diff options
Diffstat (limited to 'src/plugins')
279 files changed, 7011 insertions, 5838 deletions
diff --git a/src/plugins/bearer/android/jar/bundledjar.pro b/src/plugins/bearer/android/jar/bundledjar.pro deleted file mode 100644 index 6037f813f2..0000000000 --- a/src/plugins/bearer/android/jar/bundledjar.pro +++ /dev/null @@ -1,3 +0,0 @@ -TARGET = QtAndroidBearer-bundled -CONFIG += bundled_jar_file -include(jar.pri) diff --git a/src/plugins/bearer/android/jar/distributedjar.pro b/src/plugins/bearer/android/jar/distributedjar.pro deleted file mode 100644 index c769a113d5..0000000000 --- a/src/plugins/bearer/android/jar/distributedjar.pro +++ /dev/null @@ -1,2 +0,0 @@ -TARGET = QtAndroidBearer -include(jar.pri) diff --git a/src/plugins/bearer/android/jar/jar.pri b/src/plugins/bearer/android/jar/jar.pri deleted file mode 100644 index e43dbf0711..0000000000 --- a/src/plugins/bearer/android/jar/jar.pri +++ /dev/null @@ -1,11 +0,0 @@ -load(qt_build_paths) -CONFIG += java -DESTDIR = $$MODULE_BASE_OUTDIR/jar - -JAVACLASSPATH += $$PWD/src - -JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java - -# install -target.path = $$[QT_INSTALL_PREFIX]/jar -INSTALLS += target diff --git a/src/plugins/bearer/android/jar/jar.pro b/src/plugins/bearer/android/jar/jar.pro index 923e757d9b..f988019dac 100644 --- a/src/plugins/bearer/android/jar/jar.pro +++ b/src/plugins/bearer/android/jar/jar.pro @@ -1,2 +1,13 @@ -TEMPLATE=subdirs -SUBDIRS += distributedjar.pro bundledjar.pro +TARGET = QtAndroidBearer + +load(qt_build_paths) +CONFIG += java +DESTDIR = $$MODULE_BASE_OUTDIR/jar + +JAVACLASSPATH += $$PWD/src + +JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java + +# install +target.path = $$[QT_INSTALL_PREFIX]/jar +INSTALLS += target diff --git a/src/plugins/bearer/android/src/main.cpp b/src/plugins/bearer/android/src/main.cpp index 3892766b89..f3a5074e5d 100644 --- a/src/plugins/bearer/android/src/main.cpp +++ b/src/plugins/bearer/android/src/main.cpp @@ -50,7 +50,7 @@ class QAndroidBearerEnginePlugin : public QBearerEnginePlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QBearerEngineFactoryInterface" FILE "android.json") public: - QBearerEngine *create(const QString &key) const Q_DECL_OVERRIDE + QBearerEngine *create(const QString &key) const override { return (key == QLatin1String("android")) ? new QAndroidBearerEngine() : 0; } diff --git a/src/plugins/bearer/android/src/qandroidbearerengine.h b/src/plugins/bearer/android/src/qandroidbearerengine.h index f404ca65eb..837b02232d 100644 --- a/src/plugins/bearer/android/src/qandroidbearerengine.h +++ b/src/plugins/bearer/android/src/qandroidbearerengine.h @@ -60,20 +60,20 @@ class QAndroidBearerEngine : public QBearerEngineImpl public: explicit QAndroidBearerEngine(QObject *parent = 0); - ~QAndroidBearerEngine() Q_DECL_OVERRIDE; - - QString getInterfaceFromId(const QString &id) Q_DECL_OVERRIDE; - bool hasIdentifier(const QString &id) Q_DECL_OVERRIDE; - void connectToId(const QString &id) Q_DECL_OVERRIDE; - void disconnectFromId(const QString &id) Q_DECL_OVERRIDE; - QNetworkSession::State sessionStateForId(const QString &id) Q_DECL_OVERRIDE; - QNetworkConfigurationManager::Capabilities capabilities() const Q_DECL_OVERRIDE; - QNetworkSessionPrivate *createSessionBackend() Q_DECL_OVERRIDE; - QNetworkConfigurationPrivatePointer defaultConfiguration() Q_DECL_OVERRIDE; - bool requiresPolling() const Q_DECL_OVERRIDE; - quint64 bytesWritten(const QString &id) Q_DECL_OVERRIDE; - quint64 bytesReceived(const QString &id) Q_DECL_OVERRIDE; - quint64 startTime(const QString &id) Q_DECL_OVERRIDE; + ~QAndroidBearerEngine() override; + + QString getInterfaceFromId(const QString &id) override; + bool hasIdentifier(const QString &id) override; + void connectToId(const QString &id) override; + void disconnectFromId(const QString &id) override; + QNetworkSession::State sessionStateForId(const QString &id) override; + QNetworkConfigurationManager::Capabilities capabilities() const override; + QNetworkSessionPrivate *createSessionBackend() override; + QNetworkConfigurationPrivatePointer defaultConfiguration() override; + bool requiresPolling() const override; + quint64 bytesWritten(const QString &id) override; + quint64 bytesReceived(const QString &id) override; + quint64 startTime(const QString &id) override; Q_INVOKABLE void initialize(); Q_INVOKABLE void requestUpdate(); diff --git a/src/plugins/bearer/generic/main.cpp b/src/plugins/bearer/generic/main.cpp index 80e7b7d9aa..82a9ce97f4 100644 --- a/src/plugins/bearer/generic/main.cpp +++ b/src/plugins/bearer/generic/main.cpp @@ -54,7 +54,7 @@ public: QGenericEnginePlugin(); ~QGenericEnginePlugin(); - QBearerEngine *create(const QString &key) const Q_DECL_OVERRIDE; + QBearerEngine *create(const QString &key) const override; }; QGenericEnginePlugin::QGenericEnginePlugin() diff --git a/src/plugins/bearer/generic/qgenericengine.h b/src/plugins/bearer/generic/qgenericengine.h index e680eb9cc0..08960d66f6 100644 --- a/src/plugins/bearer/generic/qgenericengine.h +++ b/src/plugins/bearer/generic/qgenericengine.h @@ -58,24 +58,24 @@ public: QGenericEngine(QObject *parent = 0); ~QGenericEngine(); - QString getInterfaceFromId(const QString &id) Q_DECL_OVERRIDE; - bool hasIdentifier(const QString &id) Q_DECL_OVERRIDE; + QString getInterfaceFromId(const QString &id) override; + bool hasIdentifier(const QString &id) override; - void connectToId(const QString &id) Q_DECL_OVERRIDE; - void disconnectFromId(const QString &id) Q_DECL_OVERRIDE; + void connectToId(const QString &id) override; + void disconnectFromId(const QString &id) override; Q_INVOKABLE void initialize(); Q_INVOKABLE void requestUpdate(); - QNetworkSession::State sessionStateForId(const QString &id) Q_DECL_OVERRIDE; + QNetworkSession::State sessionStateForId(const QString &id) override; - QNetworkConfigurationManager::Capabilities capabilities() const Q_DECL_OVERRIDE; + QNetworkConfigurationManager::Capabilities capabilities() const override; - QNetworkSessionPrivate *createSessionBackend() Q_DECL_OVERRIDE; + QNetworkSessionPrivate *createSessionBackend() override; - QNetworkConfigurationPrivatePointer defaultConfiguration() Q_DECL_OVERRIDE; + QNetworkConfigurationPrivatePointer defaultConfiguration() override; - bool requiresPolling() const Q_DECL_OVERRIDE; + bool requiresPolling() const override; private Q_SLOTS: void doRequestUpdate(); diff --git a/src/plugins/bearer/qnetworksession_impl.h b/src/plugins/bearer/qnetworksession_impl.h index e9c0e383fc..d9aa6ca8fb 100644 --- a/src/plugins/bearer/qnetworksession_impl.h +++ b/src/plugins/bearer/qnetworksession_impl.h @@ -75,31 +75,31 @@ public: //that the state is immediately updated (w/o actually opening //a session). Also this function should take care of //notification hooks to discover future state changes. - void syncStateWithInterface() Q_DECL_OVERRIDE; + void syncStateWithInterface() override; #ifndef QT_NO_NETWORKINTERFACE - QNetworkInterface currentInterface() const Q_DECL_OVERRIDE; + QNetworkInterface currentInterface() const override; #endif - QVariant sessionProperty(const QString& key) const Q_DECL_OVERRIDE; - void setSessionProperty(const QString& key, const QVariant& value) Q_DECL_OVERRIDE; - - void open() Q_DECL_OVERRIDE; - void close() Q_DECL_OVERRIDE; - void stop() Q_DECL_OVERRIDE; - void migrate() Q_DECL_OVERRIDE; - void accept() Q_DECL_OVERRIDE; - void ignore() Q_DECL_OVERRIDE; - void reject() Q_DECL_OVERRIDE; - - QString errorString() const Q_DECL_OVERRIDE; //must return translated string - QNetworkSession::SessionError error() const Q_DECL_OVERRIDE; - - quint64 bytesWritten() const Q_DECL_OVERRIDE; - quint64 bytesReceived() const Q_DECL_OVERRIDE; - quint64 activeTime() const Q_DECL_OVERRIDE; - - QNetworkSession::UsagePolicies usagePolicies() const Q_DECL_OVERRIDE; - void setUsagePolicies(QNetworkSession::UsagePolicies) Q_DECL_OVERRIDE; + QVariant sessionProperty(const QString& key) const override; + void setSessionProperty(const QString& key, const QVariant& value) override; + + void open() override; + void close() override; + void stop() override; + void migrate() override; + void accept() override; + void ignore() override; + void reject() override; + + QString errorString() const override; //must return translated string + QNetworkSession::SessionError error() const override; + + quint64 bytesWritten() const override; + quint64 bytesReceived() const override; + quint64 activeTime() const override; + + QNetworkSession::UsagePolicies usagePolicies() const override; + void setUsagePolicies(QNetworkSession::UsagePolicies) override; private Q_SLOTS: void networkConfigurationsChanged(); diff --git a/src/plugins/generic/evdevkeyboard/main.cpp b/src/plugins/generic/evdevkeyboard/main.cpp index ef08cd56ab..5c170e1a06 100644 --- a/src/plugins/generic/evdevkeyboard/main.cpp +++ b/src/plugins/generic/evdevkeyboard/main.cpp @@ -50,7 +50,7 @@ class QEvdevKeyboardPlugin : public QGenericPlugin public: QEvdevKeyboardPlugin(); - QObject* create(const QString &key, const QString &specification) Q_DECL_OVERRIDE; + QObject* create(const QString &key, const QString &specification) override; }; QEvdevKeyboardPlugin::QEvdevKeyboardPlugin() diff --git a/src/plugins/generic/evdevmouse/main.cpp b/src/plugins/generic/evdevmouse/main.cpp index 86ec7cb575..1b8517f4c4 100644 --- a/src/plugins/generic/evdevmouse/main.cpp +++ b/src/plugins/generic/evdevmouse/main.cpp @@ -50,7 +50,7 @@ class QEvdevMousePlugin : public QGenericPlugin public: QEvdevMousePlugin(); - QObject* create(const QString &key, const QString &specification) Q_DECL_OVERRIDE; + QObject* create(const QString &key, const QString &specification) override; }; QEvdevMousePlugin::QEvdevMousePlugin() diff --git a/src/plugins/generic/evdevtablet/main.cpp b/src/plugins/generic/evdevtablet/main.cpp index 0646d71146..f43a32910d 100644 --- a/src/plugins/generic/evdevtablet/main.cpp +++ b/src/plugins/generic/evdevtablet/main.cpp @@ -50,7 +50,7 @@ class QEvdevTabletPlugin : public QGenericPlugin public: QEvdevTabletPlugin(); - QObject* create(const QString &key, const QString &specification) Q_DECL_OVERRIDE; + QObject* create(const QString &key, const QString &specification) override; }; QEvdevTabletPlugin::QEvdevTabletPlugin() diff --git a/src/plugins/generic/evdevtouch/main.cpp b/src/plugins/generic/evdevtouch/main.cpp index aa60614936..f1a0ad53ab 100644 --- a/src/plugins/generic/evdevtouch/main.cpp +++ b/src/plugins/generic/evdevtouch/main.cpp @@ -50,7 +50,7 @@ class QEvdevTouchScreenPlugin : public QGenericPlugin public: QEvdevTouchScreenPlugin(); - QObject* create(const QString &key, const QString &specification) Q_DECL_OVERRIDE; + QObject* create(const QString &key, const QString &specification) override; }; QEvdevTouchScreenPlugin::QEvdevTouchScreenPlugin() diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index 68619928d3..1cdc28c077 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -65,9 +65,6 @@ extern "C" { #endif #define XMD_H // shut JPEGlib up -#if defined(Q_OS_UNIXWARE) -# define HAVE_BOOLEAN // libjpeg under Unixware seems to need this -#endif #include <jpeglib.h> #ifdef const # undef const // remove crazy C hackery in jconfig.h diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h index f82280903d..4830959665 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h @@ -58,11 +58,11 @@ public: QComposeInputContext(); ~QComposeInputContext(); - bool isValid() const Q_DECL_OVERRIDE; - void setFocusObject(QObject *object) Q_DECL_OVERRIDE; - void reset() Q_DECL_OVERRIDE; - void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; - bool filterEvent(const QEvent *event) Q_DECL_OVERRIDE; + bool isValid() const override; + void setFocusObject(QObject *object) override; + void reset() override; + void update(Qt::InputMethodQueries) override; + bool filterEvent(const QEvent *event) override; protected: void clearComposeBuffer(); diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp index 97a7242ca6..6b33df65b9 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp @@ -51,7 +51,7 @@ class QComposePlatformInputContextPlugin : public QPlatformInputContextPlugin Q_PLUGIN_METADATA(IID QPlatformInputContextFactoryInterface_iid FILE "compose.json") public: - QComposeInputContext *create(const QString &, const QStringList &) Q_DECL_OVERRIDE; + QComposeInputContext *create(const QString &, const QStringList &) override; }; QComposeInputContext *QComposePlatformInputContextPlugin::create(const QString &system, const QStringList ¶mList) diff --git a/src/plugins/platforminputcontexts/ibus/main.cpp b/src/plugins/platforminputcontexts/ibus/main.cpp index 2846f52c8c..0a7da3b14c 100644 --- a/src/plugins/platforminputcontexts/ibus/main.cpp +++ b/src/plugins/platforminputcontexts/ibus/main.cpp @@ -51,7 +51,7 @@ class QIbusPlatformInputContextPlugin : public QPlatformInputContextPlugin Q_PLUGIN_METADATA(IID QPlatformInputContextFactoryInterface_iid FILE "ibus.json") public: - QIBusPlatformInputContext *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; + QIBusPlatformInputContext *create(const QString&, const QStringList&) override; }; QIBusPlatformInputContext *QIbusPlatformInputContextPlugin::create(const QString& system, const QStringList& paramList) diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index 9675d828e7..379e428cb0 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -90,6 +90,7 @@ public: bool valid; bool busConnected; QString predit; + QList<QInputMethodEvent::Attribute> attributes; bool needsSurroundingText; QLocale locale; }; @@ -165,6 +166,7 @@ void QIBusPlatformInputContext::reset() d->context->Reset(); d->predit = QString(); + d->attributes.clear(); } void QIBusPlatformInputContext::commit() @@ -177,6 +179,7 @@ void QIBusPlatformInputContext::commit() QObject *input = qApp->focusObject(); if (!input) { d->predit = QString(); + d->attributes.clear(); return; } @@ -188,6 +191,7 @@ void QIBusPlatformInputContext::commit() d->context->Reset(); d->predit = QString(); + d->attributes.clear(); } @@ -274,6 +278,7 @@ void QIBusPlatformInputContext::commitText(const QDBusVariant &text) QCoreApplication::sendEvent(input, &event); d->predit = QString(); + d->attributes.clear(); } void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint cursorPos, bool visible) @@ -292,11 +297,11 @@ void QIBusPlatformInputContext::updatePreeditText(const QDBusVariant &text, uint if (debug) qDebug() << "preedit text:" << t.text; - QList<QInputMethodEvent::Attribute> attributes = t.attributes.imAttributes(); + d->attributes = t.attributes.imAttributes(); if (!t.text.isEmpty()) - attributes += QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, visible ? 1 : 0); + d->attributes += QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursorPos, visible ? 1 : 0, QVariant()); - QInputMethodEvent event(t.text, attributes); + QInputMethodEvent event(t.text, d->attributes); QCoreApplication::sendEvent(input, &event); d->predit = t.text; @@ -324,6 +329,27 @@ void QIBusPlatformInputContext::deleteSurroundingText(int offset, uint n_chars) QCoreApplication::sendEvent(input, &event); } +void QIBusPlatformInputContext::hidePreeditText() +{ + QObject *input = QGuiApplication::focusObject(); + if (!input) + return; + + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event(QString(), attributes); + QCoreApplication::sendEvent(input, &event); +} + +void QIBusPlatformInputContext::showPreeditText() +{ + QObject *input = QGuiApplication::focusObject(); + if (!input) + return; + + QInputMethodEvent event(d->predit, d->attributes); + QCoreApplication::sendEvent(input, &event); +} + bool QIBusPlatformInputContext::filterEvent(const QEvent *event) { if (!d->busConnected) @@ -498,6 +524,8 @@ void QIBusPlatformInputContext::connectToContextSignals() connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool))); connect(d->context, SIGNAL(DeleteSurroundingText(int,uint)), this, SLOT(deleteSurroundingText(int,uint))); connect(d->context, SIGNAL(RequireSurroundingText()), this, SLOT(surroundingTextRequired())); + connect(d->context, SIGNAL(HidePreeditText()), this, SLOT(hidePreeditText())); + connect(d->context, SIGNAL(ShowPreeditText()), this, SLOT(showPreeditText())); } } diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h index 7baa9ad1da..f78c99e2bd 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h @@ -86,16 +86,16 @@ public: QIBusPlatformInputContext(); ~QIBusPlatformInputContext(); - bool isValid() const Q_DECL_OVERRIDE; - void setFocusObject(QObject *object) Q_DECL_OVERRIDE; + bool isValid() const override; + void setFocusObject(QObject *object) override; - void invokeAction(QInputMethod::Action a, int x) Q_DECL_OVERRIDE; - void reset() Q_DECL_OVERRIDE; - void commit() Q_DECL_OVERRIDE; - void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; - bool filterEvent(const QEvent *event) Q_DECL_OVERRIDE; - QLocale locale() const Q_DECL_OVERRIDE; - bool hasCapability(Capability capability) const Q_DECL_OVERRIDE; + void invokeAction(QInputMethod::Action a, int x) override; + void reset() override; + void commit() override; + void update(Qt::InputMethodQueries) override; + bool filterEvent(const QEvent *event) override; + QLocale locale() const override; + bool hasCapability(Capability capability) const override; public Q_SLOTS: void commitText(const QDBusVariant &text); @@ -103,6 +103,8 @@ public Q_SLOTS: void cursorRectChanged(); void deleteSurroundingText(int offset, uint n_chars); void surroundingTextRequired(); + void hidePreeditText(); + void showPreeditText(); void filterEventFinished(QDBusPendingCallWatcher *call); void socketChanged(const QString &str); void connectToBus(); diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h index e7957276c2..e456364555 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h @@ -53,10 +53,10 @@ class QCocoaAccessibility : public QPlatformAccessibility public: QCocoaAccessibility(); ~QCocoaAccessibility(); - void notifyAccessibilityUpdate(QAccessibleEvent *event) Q_DECL_OVERRIDE; - void setRootObject(QObject *o) Q_DECL_OVERRIDE; - void initialize() Q_DECL_OVERRIDE; - void cleanup() Q_DECL_OVERRIDE; + void notifyAccessibilityUpdate(QAccessibleEvent *event) override; + void setRootObject(QObject *o) override; + void initialize() override; + void cleanup() override; }; namespace QCocoaAccessible { diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 7e6bae127c..df2336d08b 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -40,6 +40,7 @@ #include "qcocoaaccessibility.h" #include "qcocoahelpers.h" #include "qcocoawindow.h" +#include "qcocoascreen.h" #include "private/qaccessiblecache_p.h" #include <QtAccessibilitySupport/private/qaccessiblebridgeutils_p.h> #include <QtGui/qaccessible.h> @@ -298,9 +299,9 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of // We're in the same top level element as our parent. return [[self parentElement] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; } else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) { - QPoint qtPosition = iface->rect().topLeft(); - QSize qtSize = iface->rect().size(); - return [NSValue valueWithPoint: NSMakePoint(qtPosition.x(), qt_mac_flipYCoordinate(qtPosition.y() + qtSize.height()))]; + // The position in points of the element's lower-left corner in screen-relative coordinates + QPointF qtPosition = QRectF(iface->rect()).bottomLeft(); + return [NSValue valueWithPoint:QCocoaScreen::mapToNative(qtPosition)]; } else if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) { QSize qtSize = iface->rect().size(); return [NSValue valueWithSize: NSMakeSize(qtSize.width(), qtSize.height())]; @@ -430,7 +431,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if ([attribute isEqualToString: NSAccessibilityBoundsForRangeParameterizedAttribute]) { NSRange range = [parameter rangeValue]; QRect firstRect = iface->textInterface()->characterRect(range.location); - QRect rect; + QRectF rect; if (range.length > 0) { NSUInteger position = range.location + range.length - 1; if (position > range.location && iface->textInterface()->text(position, position + 1) == QStringLiteral("\n")) @@ -441,15 +442,14 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of rect = firstRect; rect.setWidth(1); } - return [NSValue valueWithRect: NSMakeRect((CGFloat) rect.x(),(CGFloat) qt_mac_flipYCoordinate(rect.y() + rect.height()), rect.width(), rect.height())]; + return [NSValue valueWithRect:QCocoaScreen::mapToNative(rect)]; } if ([attribute isEqualToString: NSAccessibilityAttributedStringForRangeParameterizedAttribute]) { NSRange range = [parameter rangeValue]; QString text = iface->textInterface()->text(range.location, range.location + range.length); return [[NSAttributedString alloc] initWithString:text.toNSString()]; } else if ([attribute isEqualToString: NSAccessibilityRangeForPositionParameterizedAttribute]) { - NSPoint nsPoint = [parameter pointValue]; - QPoint point(static_cast<int>(nsPoint.x), static_cast<int>(qt_mac_flipYCoordinate(nsPoint.y))); + QPoint point = QCocoaScreen::mapFromNative([parameter pointValue]).toPoint(); int offset = iface->textInterface()->offsetAtPoint(point); return [NSValue valueWithRange:NSMakeRange(static_cast<NSUInteger>(offset), 1)]; } else if ([attribute isEqualToString: NSAccessibilityStyleRangeForIndexParameterizedAttribute]) { @@ -566,8 +566,8 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return NSAccessibilityUnignoredAncestor(self); } - int y = qt_mac_flipYCoordinate(point.y); - QAccessibleInterface *childInterface = iface->childAt(point.x, y); + QPointF screenPoint = QCocoaScreen::mapFromNative(point); + QAccessibleInterface *childInterface = iface->childAt(screenPoint.x(), screenPoint.y()); // No child found, meaning we hit this element. if (!childInterface || !childInterface->isValid()) return NSAccessibilityUnignoredAncestor(self); @@ -575,7 +575,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of // find the deepest child at the point QAccessibleInterface *childOfChildInterface = 0; do { - childOfChildInterface = childInterface->childAt(point.x, y); + childOfChildInterface = childInterface->childAt(screenPoint.x(), screenPoint.y()); if (childOfChildInterface && childOfChildInterface->isValid()) childInterface = childOfChildInterface; } while (childOfChildInterface && childOfChildInterface->isValid()); diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index a0bc204013..b4cd506513 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -52,11 +52,11 @@ public: QCocoaBackingStore(QWindow *window); ~QCocoaBackingStore(); - void flush(QWindow *, const QRegion &, const QPoint &) Q_DECL_OVERRIDE; + void flush(QWindow *, const QRegion &, const QPoint &) override; private: bool windowHasUnifiedToolbar() const; - QImage::Format format() const Q_DECL_OVERRIDE; + QImage::Format format() const override; void redrawRoundedBottomCorners(CGRect) const; }; diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.h b/src/plugins/platforms/cocoa/qcocoaclipboard.h index cab2cfaa91..a78d8f4187 100644 --- a/src/plugins/platforms/cocoa/qcocoaclipboard.h +++ b/src/plugins/platforms/cocoa/qcocoaclipboard.h @@ -56,10 +56,10 @@ class QCocoaClipboard : public QObject, public QPlatformClipboard public: QCocoaClipboard(); - QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; - void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; - bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; - bool ownsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override; + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) override; + bool supportsMode(QClipboard::Mode mode) const override; + bool ownsMode(QClipboard::Mode mode) const override; private Q_SLOTS: void handleApplicationStateChanged(Qt::ApplicationState state); diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h index 133efd6db8..01ac7e181d 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.h @@ -55,12 +55,12 @@ public: QCocoaColorDialogHelper(); ~QCocoaColorDialogHelper(); - void exec() Q_DECL_OVERRIDE; - bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE; - void hide() Q_DECL_OVERRIDE; + void exec() override; + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override; + void hide() override; - void setCurrentColor(const QColor&) Q_DECL_OVERRIDE; - QColor currentColor() const Q_DECL_OVERRIDE; + void setCurrentColor(const QColor&) override; + QColor currentColor() const override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoacursor.h b/src/plugins/platforms/cocoa/qcocoacursor.h index d1586660a4..58b9ef2151 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.h +++ b/src/plugins/platforms/cocoa/qcocoacursor.h @@ -53,9 +53,9 @@ public: QCocoaCursor(); ~QCocoaCursor(); - void changeCursor(QCursor *cursor, QWindow *window) Q_DECL_OVERRIDE; - QPoint pos() const Q_DECL_OVERRIDE; - void setPos(const QPoint &position) Q_DECL_OVERRIDE; + void changeCursor(QCursor *cursor, QWindow *window) override; + QPoint pos() const override; + void setPos(const QPoint &position) override; private: QHash<Qt::CursorShape, NSCursor *> m_cursors; NSCursor *convertCursor(QCursor *cursor); diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index 99a136d384..c021128e4c 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -39,6 +39,7 @@ #include "qcocoacursor.h" #include "qcocoawindow.h" +#include "qcocoascreen.h" #include "qcocoahelpers.h" #include <QtGui/private/qcoregraphics_p.h> @@ -70,7 +71,7 @@ void QCocoaCursor::changeCursor(QCursor *cursor, QWindow *window) QPoint QCocoaCursor::pos() const { - return qt_mac_flipPoint([NSEvent mouseLocation]).toPoint(); + return QCocoaScreen::mapFromNative([NSEvent mouseLocation]).toPoint(); } void QCocoaCursor::setPos(const QPoint &position) @@ -86,7 +87,7 @@ void QCocoaCursor::setPos(const QPoint &position) NSCursor *QCocoaCursor::convertCursor(QCursor *cursor) { - if (cursor == Q_NULLPTR) + if (cursor == nullptr) return 0; const Qt::CursorShape newShape = cursor->shape(); diff --git a/src/plugins/platforms/cocoa/qcocoadrag.h b/src/plugins/platforms/cocoa/qcocoadrag.h index c7277a47bf..dc0cc17dfb 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.h +++ b/src/plugins/platforms/cocoa/qcocoadrag.h @@ -56,10 +56,10 @@ public: ~QCocoaDrag(); QMimeData *dragMimeData(); - Qt::DropAction drag(QDrag *m_drag) Q_DECL_OVERRIDE; + Qt::DropAction drag(QDrag *m_drag) override; Qt::DropAction defaultAction(Qt::DropActions possibleActions, - Qt::KeyboardModifiers modifiers) const Q_DECL_OVERRIDE; + Qt::KeyboardModifiers modifiers) const override; /** * to meet NSView dragImage:at guarantees, we need to record the original diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h index f5ba1dc22e..2ddda14289 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h @@ -59,19 +59,19 @@ public: QCocoaFileDialogHelper(); virtual ~QCocoaFileDialogHelper(); - void exec() Q_DECL_OVERRIDE; + void exec() override; - bool defaultNameFilterDisables() const Q_DECL_OVERRIDE; + bool defaultNameFilterDisables() const override; - bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE; - void hide() Q_DECL_OVERRIDE; - void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE; - QUrl directory() const Q_DECL_OVERRIDE; - void selectFile(const QUrl &filename) Q_DECL_OVERRIDE; - QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE; - void setFilter() Q_DECL_OVERRIDE; - void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE; - QString selectedNameFilter() const Q_DECL_OVERRIDE; + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override; + void hide() override; + void setDirectory(const QUrl &directory) override; + QUrl directory() const override; + void selectFile(const QUrl &filename) override; + QList<QUrl> selectedFiles() const override; + void setFilter() override; + void selectNameFilter(const QString &filter) override; + QString selectedNameFilter() const override; public: bool showCocoaFilePanel(Qt::WindowModality windowModality, QWindow *parent); diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h index c3fad7cfd6..14f12f2d76 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.h @@ -54,13 +54,13 @@ public: QCocoaFontDialogHelper(); ~QCocoaFontDialogHelper(); - void exec() Q_DECL_OVERRIDE; + void exec() override; - bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE; - void hide() Q_DECL_OVERRIDE; + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override; + void hide() override; - void setCurrentFont(const QFont &) Q_DECL_OVERRIDE; - QFont currentFont() const Q_DECL_OVERRIDE; + void setCurrentFont(const QFont &) override; + QFont currentFont() const override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h index 1a66cec0e3..129307acf4 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.h +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -55,22 +55,22 @@ public: QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, const QVariant &nativeHandle); ~QCocoaGLContext(); - QSurfaceFormat format() const Q_DECL_OVERRIDE; + QSurfaceFormat format() const override; - void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; + void swapBuffers(QPlatformSurface *surface) override; - bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE; - void doneCurrent() Q_DECL_OVERRIDE; + bool makeCurrent(QPlatformSurface *surface) override; + void doneCurrent() override; - QFunctionPointer getProcAddress(const char *procName) Q_DECL_OVERRIDE; + QFunctionPointer getProcAddress(const char *procName) override; void update(); static NSOpenGLPixelFormat *createNSOpenGLPixelFormat(const QSurfaceFormat &format); NSOpenGLContext *nsOpenGLContext() const; - bool isSharing() const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; + bool isSharing() const override; + bool isValid() const override; void windowWasHidden(); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 7810733255..6c75db9bdb 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -85,13 +85,8 @@ QT_MANGLE_NAMESPACE(QNSView) *qnsview_cast(NSView *view); void qt_mac_transformProccessToForegroundApplication(); QString qt_mac_applicationName(); -int qt_mac_flipYCoordinate(int y); -qreal qt_mac_flipYCoordinate(qreal y); -QPointF qt_mac_flipPoint(const NSPoint &p); -NSPoint qt_mac_flipPoint(const QPoint &p); -NSPoint qt_mac_flipPoint(const QPointF &p); - -NSRect qt_mac_flipRect(const QRect &rect); +QPointF qt_mac_flip(const QPointF &pos, const QRectF &reference); +QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference); Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); @@ -193,6 +188,19 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSPanelContentsWrapper); // ------------------------------------------------------------------------- +// QAppleRefCounted expects the retain function to return the object +io_object_t q_IOObjectRetain(io_object_t obj); +// QAppleRefCounted expects the release function to return void +void q_IOObjectRelease(io_object_t obj); + +template <typename T> +class QIOType : public QAppleRefCounted<T, io_object_t, q_IOObjectRetain, q_IOObjectRelease> +{ + using QAppleRefCounted<T, io_object_t, q_IOObjectRetain, q_IOObjectRelease>::QAppleRefCounted; +}; + +// ------------------------------------------------------------------------- + // Depending on the ABI of the platform, we may need to use objc_msgSendSuper_stret: // - http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html // - https://lists.apple.com/archives/cocoa-dev/2008/Feb/msg02338.html diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 9f9618177d..85d12040de 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -232,50 +232,37 @@ QString qt_mac_applicationName() return appName; } -int qt_mac_primaryScreenHeight() -{ - QMacAutoReleasePool pool; - NSArray *screens = [NSScreen screens]; - if ([screens count] > 0) { - // The first screen in the screens array is documented to - // have the (0,0) origin and is designated the primary screen. - NSRect screenFrame = [[screens objectAtIndex: 0] frame]; - return screenFrame.size.height; - } - return 0; -} +// ------------------------------------------------------------------------- -int qt_mac_flipYCoordinate(int y) -{ - return qt_mac_primaryScreenHeight() - y; -} +/*! + \fn QPointF qt_mac_flip(const QPointF &pos, const QRectF &reference) + \fn QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference) -qreal qt_mac_flipYCoordinate(qreal y) -{ - return qt_mac_primaryScreenHeight() - y; -} + Flips the Y coordinate of the point/rect between quadrant I and IV. -QPointF qt_mac_flipPoint(const NSPoint &p) -{ - return QPointF(p.x, qt_mac_flipYCoordinate(p.y)); -} + The native coordinate system on macOS uses quadrant I, with origin + in bottom left, and Qt uses quadrant IV, with origin in top left. -NSPoint qt_mac_flipPoint(const QPoint &p) -{ - return NSMakePoint(p.x(), qt_mac_flipYCoordinate(p.y())); -} + By flipping the Y coordinate, we can map the point/rect between + the two coordinate systems. -NSPoint qt_mac_flipPoint(const QPointF &p) + The flip is always in relation to a reference rectangle, e.g. + the frame of the parent view, or the screen geometry. In the + latter case the specialized QCocoaScreen::mapFrom/To functions + should be used instead. +*/ +QPointF qt_mac_flip(const QPointF &pos, const QRectF &reference) { - return NSMakePoint(p.x(), qt_mac_flipYCoordinate(p.y())); + return QPointF(pos.x(), reference.height() - pos.y()); } -NSRect qt_mac_flipRect(const QRect &rect) +QRectF qt_mac_flip(const QRectF &rect, const QRectF &reference) { - int flippedY = qt_mac_flipYCoordinate(rect.y() + rect.height()); - return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height()); + return QRectF(qt_mac_flip(rect.bottomLeft(), reference), rect.size()); } +// ------------------------------------------------------------------------- + Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) { if (buttonNum >= 0 && buttonNum <= 31) @@ -408,4 +395,19 @@ QT_END_NAMESPACE [super layout]; } +// ------------------------------------------------------------------------- + +io_object_t q_IOObjectRetain(io_object_t obj) +{ + kern_return_t ret = IOObjectRetain(obj); + Q_ASSERT(!ret); + return obj; +} + +void q_IOObjectRelease(io_object_t obj) +{ + kern_return_t ret = IOObjectRelease(obj); + Q_ASSERT(!ret); +} + @end diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.h b/src/plugins/platforms/cocoa/qcocoainputcontext.h index a248ca0d8d..7190ba0de8 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.h +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.h @@ -53,11 +53,11 @@ public: explicit QCocoaInputContext(); ~QCocoaInputContext(); - bool isValid() const Q_DECL_OVERRIDE { return true; } + bool isValid() const override { return true; } - void reset() Q_DECL_OVERRIDE; + void reset() override; - QLocale locale() const Q_DECL_OVERRIDE { return m_locale; } + QLocale locale() const override { return m_locale; } void updateLocale(); private Q_SLOTS: diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 2fc5156d24..301771fd53 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -75,35 +75,35 @@ public: static QCocoaIntegration *instance(); Options options() const; - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const override; + QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override; QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; #ifndef QT_NO_OPENGL - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; #endif - QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const Q_DECL_OVERRIDE; + QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const override; - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const override; - QCoreTextFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; - QCocoaNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; - QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE; + QCoreTextFontDatabase *fontDatabase() const override; + QCocoaNativeInterface *nativeInterface() const override; + QPlatformInputContext *inputContext() const override; #ifndef QT_NO_ACCESSIBILITY - QCocoaAccessibility *accessibility() const Q_DECL_OVERRIDE; + QCocoaAccessibility *accessibility() const override; #endif #ifndef QT_NO_CLIPBOARD - QCocoaClipboard *clipboard() const Q_DECL_OVERRIDE; + QCocoaClipboard *clipboard() const override; #endif - QCocoaDrag *drag() const Q_DECL_OVERRIDE; + QCocoaDrag *drag() const override; - QStringList themeNames() const Q_DECL_OVERRIDE; - QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE; - QCocoaServices *services() const Q_DECL_OVERRIDE; - QVariant styleHint(StyleHint hint) const Q_DECL_OVERRIDE; + QStringList themeNames() const override; + QPlatformTheme *createPlatformTheme(const QString &name) const override; + QCocoaServices *services() const override; + QVariant styleHint(StyleHint hint) const override; - Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE; - QList<int> possibleKeys(const QKeyEvent *event) const Q_DECL_OVERRIDE; + Qt::KeyboardModifiers queryKeyboardModifiers() const override; + QList<int> possibleKeys(const QKeyEvent *event) const override; void updateScreens(); QCocoaScreen *screenForNSScreen(NSScreen *nsScreen); @@ -117,9 +117,9 @@ public: QCocoaWindow *activePopupWindow() const; QList<QCocoaWindow *> *popupWindowStack(); - void setApplicationIcon(const QIcon &icon) const Q_DECL_OVERRIDE; + void setApplicationIcon(const QIcon &icon) const override; - void beep() const Q_DECL_OVERRIDE; + void beep() const override; private Q_SLOTS: void focusWindowChanged(QWindow *); diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 5081fc78c6..f5fa93cbb5 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -55,32 +55,32 @@ public: QCocoaMenu(); ~QCocoaMenu(); - void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) Q_DECL_OVERRIDE; - void removeMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; - void syncMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; - void setEnabled(bool enabled) Q_DECL_OVERRIDE; - bool isEnabled() const Q_DECL_OVERRIDE; - void setVisible(bool visible) Q_DECL_OVERRIDE; - void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE; - void dismiss() Q_DECL_OVERRIDE; + void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) override; + void removeMenuItem(QPlatformMenuItem *menuItem) override; + void syncMenuItem(QPlatformMenuItem *menuItem) override; + void setEnabled(bool enabled) override; + bool isEnabled() const override; + void setVisible(bool visible) override; + void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) override; + void dismiss() override; - void syncSeparatorsCollapsible(bool enable) Q_DECL_OVERRIDE; + void syncSeparatorsCollapsible(bool enable) override; void propagateEnabledState(bool enabled); - void setIcon(const QIcon &icon) Q_DECL_OVERRIDE { Q_UNUSED(icon) } + void setIcon(const QIcon &icon) override { Q_UNUSED(icon) } - void setText(const QString &text) Q_DECL_OVERRIDE; - void setMinimumWidth(int width) Q_DECL_OVERRIDE; - void setFont(const QFont &font) Q_DECL_OVERRIDE; + void setText(const QString &text) override; + void setMinimumWidth(int width) override; + void setFont(const QFont &font) override; inline NSMenu *nsMenu() const { return m_nativeMenu; } inline bool isVisible() const { return m_visible; } - QPlatformMenuItem *menuItemAt(int position) const Q_DECL_OVERRIDE; - QPlatformMenuItem *menuItemForTag(quintptr tag) const Q_DECL_OVERRIDE; + QPlatformMenuItem *menuItemAt(int position) const override; + QPlatformMenuItem *menuItemForTag(quintptr tag) const override; QList<QCocoaMenuItem *> items() const; QList<QCocoaMenuItem *> merged() const; @@ -91,7 +91,7 @@ public: bool isOpen() const; void setIsOpen(bool isOpen); - void timerEvent(QTimerEvent *e) Q_DECL_OVERRIDE; + void timerEvent(QTimerEvent *e) override; void syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUpdate); diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index a4ee531e91..32a8fd89b4 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -56,11 +56,11 @@ public: QCocoaMenuBar(); ~QCocoaMenuBar(); - void insertMenu(QPlatformMenu *menu, QPlatformMenu* before) Q_DECL_OVERRIDE; - void removeMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; - void syncMenu(QPlatformMenu *menuItem) Q_DECL_OVERRIDE; - void handleReparent(QWindow *newParentWindow) Q_DECL_OVERRIDE; - QPlatformMenu *menuForTag(quintptr tag) const Q_DECL_OVERRIDE; + void insertMenu(QPlatformMenu *menu, QPlatformMenu* before) override; + void removeMenu(QPlatformMenu *menu) override; + void syncMenu(QPlatformMenu *menuItem) override; + void handleReparent(QWindow *newParentWindow) override; + QPlatformMenu *menuForTag(quintptr tag) const override; inline NSMenu *nsMenu() const { return m_nativeMenu; } diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index a4cd465dae..fd28a4d7da 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -449,7 +449,7 @@ NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole r) foreach (QCocoaMenuItem *i, m->items()) if (i->effectiveRole() == r) return i->nsItem(); - return Q_NULLPTR; + return nullptr; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index 53862d0484..2b598ee3a0 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -78,22 +78,22 @@ public: QCocoaMenuItem(); ~QCocoaMenuItem(); - void setText(const QString &text) Q_DECL_OVERRIDE; - void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; - void setMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; - void setVisible(bool isVisible) Q_DECL_OVERRIDE; - void setIsSeparator(bool isSeparator) Q_DECL_OVERRIDE; - void setFont(const QFont &font) Q_DECL_OVERRIDE; - void setRole(MenuRole role) Q_DECL_OVERRIDE; + void setText(const QString &text) override; + void setIcon(const QIcon &icon) override; + void setMenu(QPlatformMenu *menu) override; + void setVisible(bool isVisible) override; + void setIsSeparator(bool isSeparator) override; + void setFont(const QFont &font) override; + void setRole(MenuRole role) override; #ifndef QT_NO_SHORTCUT - void setShortcut(const QKeySequence& shortcut) Q_DECL_OVERRIDE; + void setShortcut(const QKeySequence& shortcut) override; #endif - void setCheckable(bool checkable) Q_DECL_OVERRIDE { Q_UNUSED(checkable) } - void setChecked(bool isChecked) Q_DECL_OVERRIDE; - void setEnabled(bool isEnabled) Q_DECL_OVERRIDE; - void setIconSize(int size) Q_DECL_OVERRIDE; + void setCheckable(bool checkable) override { Q_UNUSED(checkable) } + void setChecked(bool isChecked) override; + void setEnabled(bool isEnabled) override; + void setIconSize(int size) override; - void setNativeContents(WId item) Q_DECL_OVERRIDE; + void setNativeContents(WId item) override; inline QString text() const { return m_text; } inline NSMenuItem * nsItem() { return m_native; } diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index 26fbe3e4bc..c78f1d5a7f 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -60,18 +60,18 @@ public: QCocoaNativeInterface(); #ifndef QT_NO_OPENGL - void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context) Q_DECL_OVERRIDE; + void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context) override; #endif - void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) Q_DECL_OVERRIDE; + void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) override; - NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; + NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) override; #ifndef QT_NO_OPENGL static void *cglContextForContext(QOpenGLContext *context); static void *nsOpenGLContextForContext(QOpenGLContext* context); #endif - QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE; + QFunctionPointer platformFunction(const QByteArray &function) const override; public Q_SLOTS: void onAppFocusWindowChanged(QWindow *window); diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index 8943cb6cd5..1422aebd65 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -233,7 +233,7 @@ QFunctionPointer QCocoaNativeInterface::platformFunction(const QByteArray &funct if (function == QCocoaWindowFunctions::bottomLeftClippedByNSWindowOffsetIdentifier()) return QFunctionPointer(QCocoaWindowFunctions::BottomLeftClippedByNSWindowOffset(QCocoaWindow::bottomLeftClippedByNSWindowOffsetStatic)); - return Q_NULLPTR; + return nullptr; } void QCocoaNativeInterface::addToMimeList(void *macPasteboardMime) diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.h b/src/plugins/platforms/cocoa/qcocoaprintdevice.h index c726cca4e5..20b27f3286 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.h +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.h @@ -68,37 +68,37 @@ public: explicit QCocoaPrintDevice(const QString &id); virtual ~QCocoaPrintDevice(); - bool isValid() const Q_DECL_OVERRIDE; - bool isDefault() const Q_DECL_OVERRIDE; + bool isValid() const override; + bool isDefault() const override; - QPrint::DeviceState state() const Q_DECL_OVERRIDE; + QPrint::DeviceState state() const override; - QPageSize defaultPageSize() const Q_DECL_OVERRIDE; + QPageSize defaultPageSize() const override; QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation, - int resolution) const Q_DECL_OVERRIDE; + int resolution) const override; - int defaultResolution() const Q_DECL_OVERRIDE; + int defaultResolution() const override; - QPrint::InputSlot defaultInputSlot() const Q_DECL_OVERRIDE; + QPrint::InputSlot defaultInputSlot() const override; - QPrint::OutputBin defaultOutputBin() const Q_DECL_OVERRIDE; + QPrint::OutputBin defaultOutputBin() const override; - QPrint::DuplexMode defaultDuplexMode() const Q_DECL_OVERRIDE; + QPrint::DuplexMode defaultDuplexMode() const override; - QPrint::ColorMode defaultColorMode() const Q_DECL_OVERRIDE; + QPrint::ColorMode defaultColorMode() const override; PMPrinter macPrinter() const; PMPaper macPaper(const QPageSize &pageSize) const; protected: - void loadPageSizes() const Q_DECL_OVERRIDE; - void loadResolutions() const Q_DECL_OVERRIDE; - void loadInputSlots() const Q_DECL_OVERRIDE; - void loadOutputBins() const Q_DECL_OVERRIDE; - void loadDuplexModes() const Q_DECL_OVERRIDE; - void loadColorModes() const Q_DECL_OVERRIDE; - void loadMimeTypes() const Q_DECL_OVERRIDE; + void loadPageSizes() const override; + void loadResolutions() const override; + void loadInputSlots() const override; + void loadOutputBins() const override; + void loadDuplexModes() const override; + void loadColorModes() const override; + void loadMimeTypes() const override; private: QPageSize createPageSize(const PMPaper &paper) const; diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm index 39fcf285ed..bfe6cd09b6 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm @@ -46,6 +46,15 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_PRINTER +// The CUPS PPD APIs were deprecated in CUPS 1.6/macOS 10.8, but +// as long as we're supporting RHEL 6, which still ships CUPS 1.4 +// we're not going to rewrite this, as we want to share the code +// between macOS and Linux for the CUPS-bits. See discussion in +// https://bugreports.qt.io/browse/QTBUG-56545 +#pragma message "Disabling CUPS PPD deprecation warnings. This should be fixed once we drop support for RHEL6 (QTBUG-56545)" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + static QPrint::DuplexMode macToDuplexMode(const PMDuplexMode &mode) { if (mode == kPMDuplexTumble) @@ -474,6 +483,8 @@ PMPaper QCocoaPrintDevice::macPaper(const QPageSize &pageSize) const return paper; } +#pragma clang diagnostic pop + #endif // QT_NO_PRINTER QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoaprintersupport.h b/src/plugins/platforms/cocoa/qcocoaprintersupport.h index a07bf0ec1b..40a638207a 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintersupport.h +++ b/src/plugins/platforms/cocoa/qcocoaprintersupport.h @@ -53,12 +53,12 @@ public: QCocoaPrinterSupport(); ~QCocoaPrinterSupport(); - QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode, const QString &deviceId = QString()) Q_DECL_OVERRIDE; - QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode) Q_DECL_OVERRIDE; + QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode, const QString &deviceId = QString()) override; + QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode) override; - QPrintDevice createPrintDevice(const QString &id) Q_DECL_OVERRIDE; - QStringList availablePrintDeviceIds() const Q_DECL_OVERRIDE; - QString defaultPrintDeviceId() const Q_DECL_OVERRIDE; + QPrintDevice createPrintDevice(const QString &id) override; + QStringList availablePrintDeviceIds() const override; + QString defaultPrintDeviceId() const override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h index 937002f493..3d59c3de79 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.h +++ b/src/plugins/platforms/cocoa/qcocoascreen.h @@ -56,20 +56,20 @@ public: // ---------------------------------------------------- // Virtual methods overridden from QPlatformScreen - QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE { return m_geometry; } - QRect availableGeometry() const Q_DECL_OVERRIDE { return m_availableGeometry; } - int depth() const Q_DECL_OVERRIDE { return m_depth; } - QImage::Format format() const Q_DECL_OVERRIDE { return m_format; } - qreal devicePixelRatio() const Q_DECL_OVERRIDE; - QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_physicalSize; } - QDpi logicalDpi() const Q_DECL_OVERRIDE { return m_logicalDpi; } - qreal refreshRate() const Q_DECL_OVERRIDE { return m_refreshRate; } - QString name() const Q_DECL_OVERRIDE { return m_name; } - QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return m_cursor; } - QWindow *topLevelAt(const QPoint &point) const Q_DECL_OVERRIDE; - QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; } - QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE; + QPixmap grabWindow(WId window, int x, int y, int width, int height) const override; + QRect geometry() const override { return m_geometry; } + QRect availableGeometry() const override { return m_availableGeometry; } + int depth() const override { return m_depth; } + QImage::Format format() const override { return m_format; } + qreal devicePixelRatio() const override; + QSizeF physicalSize() const override { return m_physicalSize; } + QDpi logicalDpi() const override { return m_logicalDpi; } + qreal refreshRate() const override { return m_refreshRate; } + QString name() const override { return m_name; } + QPlatformCursor *cursor() const override { return m_cursor; } + QWindow *topLevelAt(const QPoint &point) const override; + QList<QPlatformScreen *> virtualSiblings() const override { return m_siblings; } + QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const override; // ---------------------------------------------------- // Additional methods @@ -77,16 +77,12 @@ public: NSScreen *nativeScreen() const; void updateGeometry(); - QPointF mapToNative(const QPointF &pos) const { return flipCoordinate(pos); } - QRectF mapToNative(const QRectF &rect) const { return flipCoordinate(rect); } - QPointF mapFromNative(const QPointF &pos) const { return flipCoordinate(pos); } - QRectF mapFromNative(const QRectF &rect) const { return flipCoordinate(rect); } - static QCocoaScreen *primaryScreen(); -private: - QPointF flipCoordinate(const QPointF &pos) const; - QRectF flipCoordinate(const QRectF &rect) const; + static CGPoint mapToNative(const QPointF &pos, QCocoaScreen *screen = QCocoaScreen::primaryScreen()); + static CGRect mapToNative(const QRectF &rect, QCocoaScreen *screen = QCocoaScreen::primaryScreen()); + static QPointF mapFromNative(CGPoint pos, QCocoaScreen *screen = QCocoaScreen::primaryScreen()); + static QRectF mapFromNative(CGRect rect, QCocoaScreen *screen = QCocoaScreen::primaryScreen()); public: int m_screenIndex; diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index f523873bde..ed1b19cd53 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -75,32 +75,36 @@ NSScreen *QCocoaScreen::nativeScreen() const return [screens objectAtIndex:m_screenIndex]; } -/*! - Flips the Y coordinate of the point between quadrant I and IV. +static QString displayName(CGDirectDisplayID displayID) +{ + QIOType<io_iterator_t> iterator; + if (IOServiceGetMatchingServices(kIOMasterPortDefault, + IOServiceMatching("IODisplayConnect"), &iterator)) + return QString(); + + QIOType<io_service_t> display; + while ((display = IOIteratorNext(iterator)) != 0) + { + NSDictionary *info = [(__bridge NSDictionary*)IODisplayCreateInfoDictionary( + display, kIODisplayOnlyPreferredName) autorelease]; + + if ([[info objectForKey:@kDisplayVendorID] longValue] != CGDisplayVendorNumber(displayID)) + continue; - The native coordinate system on macOS uses quadrant I, with origin - in bottom left, and Qt uses quadrant IV, with origin in top left. + if ([[info objectForKey:@kDisplayProductID] longValue] != CGDisplayModelNumber(displayID)) + continue; - By flippig the Y coordinate, we can map the position between the - two coordinate systems. -*/ -QPointF QCocoaScreen::flipCoordinate(const QPointF &pos) const -{ - return QPointF(pos.x(), m_geometry.height() - pos.y()); -} + if ([[info objectForKey:@kDisplaySerialNumber] longValue] != CGDisplaySerialNumber(displayID)) + continue; -/*! - Flips the Y coordinate of the rectangle between quadrant I and IV. + NSDictionary *localizedNames = [info objectForKey:@kDisplayProductName]; + if (![localizedNames count]) + break; // Correct screen, but no name in dictionary - The native coordinate system on macOS uses quadrant I, with origin - in bottom left, and Qt uses quadrant IV, with origin in top left. + return QString::fromNSString([localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]]); + } - By flippig the Y coordinate, we can map the rectangle between the - two coordinate systems. -*/ -QRectF QCocoaScreen::flipCoordinate(const QRectF &rect) const -{ - return QRectF(flipCoordinate(rect.topLeft() + QPoint(0, rect.height())), rect.size()); + return QString(); } void QCocoaScreen::updateGeometry() @@ -109,20 +113,10 @@ void QCocoaScreen::updateGeometry() if (!nsScreen) return; - // At this point the geometry is in native coordinates, but the size - // is correct, which we take advantage of next when we map the native - // coordinates to the Qt coordinate system. - m_geometry = QRectF::fromCGRect(NSRectToCGRect(nsScreen.frame)).toRect(); - m_availableGeometry = QRectF::fromCGRect(NSRectToCGRect(nsScreen.visibleFrame)).toRect(); - - // The reference screen for the geometry is always the primary screen, but since - // we may be in the process of creating and registering the primary screen, we - // must special-case that and assign it direcly. - QCocoaScreen *primaryScreen = (nsScreen == [[NSScreen screens] firstObject]) ? - this : QCocoaScreen::primaryScreen(); - - m_geometry = primaryScreen->mapFromNative(m_geometry).toRect(); - m_availableGeometry = primaryScreen->mapFromNative(m_availableGeometry).toRect(); + // The reference screen for the geometry is always the primary screen + QRectF primaryScreenGeometry = QRectF::fromCGRect([[NSScreen screens] firstObject].frame); + m_geometry = qt_mac_flip(QRectF::fromCGRect(nsScreen.frame), primaryScreenGeometry).toRect(); + m_availableGeometry = qt_mac_flip(QRectF::fromCGRect(nsScreen.visibleFrame), primaryScreenGeometry).toRect(); m_format = QImage::Format_RGB32; m_depth = NSBitsPerPixelFromDepth([nsScreen depth]); @@ -139,12 +133,7 @@ void QCocoaScreen::updateGeometry() if (refresh > 0) m_refreshRate = refresh; - // Get m_name (brand/model of the monitor) - NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(dpy), kIODisplayOnlyPreferredName); - NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]]; - if ([localizedNames count] > 0) - m_name = QString::fromUtf8([[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] UTF8String]); - [deviceInfo release]; + m_name = displayName(dpy); QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), m_logicalDpi.first, m_logicalDpi.second); @@ -170,7 +159,7 @@ QPlatformScreen::SubpixelAntialiasingType QCocoaScreen::subpixelAntialiasingType QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const { - NSPoint screenPoint = qt_mac_flipPoint(point); + NSPoint screenPoint = mapToNative(point); // Search (hit test) for the top-level window. [NSWidow windowNumberAtPoint: // belowWindowWithWindowNumber] may return windows that are not interesting @@ -275,6 +264,30 @@ QCocoaScreen *QCocoaScreen::primaryScreen() return static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle()); } +CGPoint QCocoaScreen::mapToNative(const QPointF &pos, QCocoaScreen *screen) +{ + Q_ASSERT(screen); + return qt_mac_flip(pos, screen->geometry()).toCGPoint(); +} + +CGRect QCocoaScreen::mapToNative(const QRectF &rect, QCocoaScreen *screen) +{ + Q_ASSERT(screen); + return qt_mac_flip(rect, screen->geometry()).toCGRect(); +} + +QPointF QCocoaScreen::mapFromNative(CGPoint pos, QCocoaScreen *screen) +{ + Q_ASSERT(screen); + return qt_mac_flip(QPointF::fromCGPoint(pos), screen->geometry()); +} + +QRectF QCocoaScreen::mapFromNative(CGRect rect, QCocoaScreen *screen) +{ + Q_ASSERT(screen); + return qt_mac_flip(QRectF::fromCGRect(rect), screen->geometry()); +} + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug debug, const QCocoaScreen *screen) { diff --git a/src/plugins/platforms/cocoa/qcocoaservices.h b/src/plugins/platforms/cocoa/qcocoaservices.h index c2ceede0f0..62a8891f96 100644 --- a/src/plugins/platforms/cocoa/qcocoaservices.h +++ b/src/plugins/platforms/cocoa/qcocoaservices.h @@ -47,8 +47,8 @@ QT_BEGIN_NAMESPACE class QCocoaServices : public QPlatformServices { public: - bool openUrl(const QUrl &url) Q_DECL_OVERRIDE; - bool openDocument(const QUrl &url) Q_DECL_OVERRIDE; + bool openUrl(const QUrl &url) override; + bool openDocument(const QUrl &url) override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h index d542a3cb8f..2f1a1e42a9 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h @@ -57,17 +57,17 @@ class Q_GUI_EXPORT QCocoaSystemTrayIcon : public QPlatformSystemTrayIcon public: QCocoaSystemTrayIcon() : m_sys(0) {} - void init() Q_DECL_OVERRIDE; - void cleanup() Q_DECL_OVERRIDE; - void updateIcon(const QIcon &icon) Q_DECL_OVERRIDE; - void updateToolTip(const QString &toolTip) Q_DECL_OVERRIDE; - void updateMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE; + void init() override; + void cleanup() override; + void updateIcon(const QIcon &icon) override; + void updateToolTip(const QString &toolTip) override; + void updateMenu(QPlatformMenu *menu) override; + QRect geometry() const override; void showMessage(const QString &title, const QString &msg, - const QIcon& icon, MessageIcon iconType, int secs) Q_DECL_OVERRIDE; + const QIcon& icon, MessageIcon iconType, int secs) override; - bool isSystemTrayAvailable() const Q_DECL_OVERRIDE; - bool supportsMessages() const Q_DECL_OVERRIDE; + bool isSystemTrayAvailable() const override; + bool supportsMessages() const override; private: QSystemTrayIconSys *m_sys; diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h index 27c071a8cd..69eaf8db56 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.h +++ b/src/plugins/platforms/cocoa/qcocoatheme.h @@ -56,25 +56,25 @@ public: void reset(); - QPlatformMenuItem* createPlatformMenuItem() const Q_DECL_OVERRIDE; - QPlatformMenu* createPlatformMenu() const Q_DECL_OVERRIDE; - QPlatformMenuBar* createPlatformMenuBar() const Q_DECL_OVERRIDE; + QPlatformMenuItem* createPlatformMenuItem() const override; + QPlatformMenu* createPlatformMenu() const override; + QPlatformMenuBar* createPlatformMenuBar() const override; #ifndef QT_NO_SYSTEMTRAYICON - QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const Q_DECL_OVERRIDE; + QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override; #endif - bool usePlatformNativeDialog(DialogType dialogType) const Q_DECL_OVERRIDE; - QPlatformDialogHelper *createPlatformDialogHelper(DialogType dialogType) const Q_DECL_OVERRIDE; + bool usePlatformNativeDialog(DialogType dialogType) const override; + QPlatformDialogHelper *createPlatformDialogHelper(DialogType dialogType) const override; - const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE; - const QFont *font(Font type = SystemFont) const Q_DECL_OVERRIDE; - QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const Q_DECL_OVERRIDE; + const QPalette *palette(Palette type = SystemPalette) const override; + const QFont *font(Font type = SystemFont) const override; + QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override; QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions options = 0) const override; - QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE; - QString standardButtonText(int button) const Q_DECL_OVERRIDE; - QKeySequence standardButtonShortcut(int button) const Q_DECL_OVERRIDE; + QVariant themeHint(ThemeHint hint) const override; + QString standardButtonText(int button) const override; + QKeySequence standardButtonShortcut(int button) const override; static const char *name; diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 5239864ad8..2aab5fd545 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -98,7 +98,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaThemeNotificationReceiver); { Q_UNUSED(notification); mPrivate->reset(); - QWindowSystemInterface::handleThemeChange(Q_NULLPTR); + QWindowSystemInterface::handleThemeChange(nullptr); } @end @@ -127,7 +127,7 @@ QCocoaTheme::~QCocoaTheme() void QCocoaTheme::reset() { delete m_systemPalette; - m_systemPalette = Q_NULLPTR; + m_systemPalette = nullptr; qDeleteAll(m_palettes); m_palettes.clear(); } @@ -275,7 +275,7 @@ QPixmap QCocoaTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const } if (iconType != 0) { QPixmap pixmap; - IconRef icon = Q_NULLPTR; + IconRef icon = nullptr; GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon); if (icon) { diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 6fbe29f683..fb91c53a7a 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -97,37 +97,37 @@ public: void initialize() override; - void setGeometry(const QRect &rect) Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE; + void setGeometry(const QRect &rect) override; + QRect geometry() const override; void setCocoaGeometry(const QRect &rect); - void setVisible(bool visible) Q_DECL_OVERRIDE; - void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE; - void setWindowState(Qt::WindowStates state) Q_DECL_OVERRIDE; - void setWindowTitle(const QString &title) Q_DECL_OVERRIDE; - void setWindowFilePath(const QString &filePath) Q_DECL_OVERRIDE; - void setWindowIcon(const QIcon &icon) Q_DECL_OVERRIDE; - void setAlertState(bool enabled) Q_DECL_OVERRIDE; - bool isAlertState() const Q_DECL_OVERRIDE; - void raise() Q_DECL_OVERRIDE; - void lower() Q_DECL_OVERRIDE; - bool isExposed() const Q_DECL_OVERRIDE; + void setVisible(bool visible) override; + void setWindowFlags(Qt::WindowFlags flags) override; + void setWindowState(Qt::WindowStates state) override; + void setWindowTitle(const QString &title) override; + void setWindowFilePath(const QString &filePath) override; + void setWindowIcon(const QIcon &icon) override; + void setAlertState(bool enabled) override; + bool isAlertState() const override; + void raise() override; + void lower() override; + bool isExposed() const override; bool isOpaque() const; - void propagateSizeHints() Q_DECL_OVERRIDE; - void setOpacity(qreal level) Q_DECL_OVERRIDE; - void setMask(const QRegion ®ion) Q_DECL_OVERRIDE; - bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE; - bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE; - QMargins frameMargins() const Q_DECL_OVERRIDE; - QSurfaceFormat format() const Q_DECL_OVERRIDE; + void propagateSizeHints() override; + void setOpacity(qreal level) override; + void setMask(const QRegion ®ion) override; + bool setKeyboardGrabEnabled(bool grab) override; + bool setMouseGrabEnabled(bool grab) override; + QMargins frameMargins() const override; + QSurfaceFormat format() const override; - bool isForeignWindow() const Q_DECL_OVERRIDE; + bool isForeignWindow() const override; void requestUpdate() override; - void requestActivateWindow() Q_DECL_OVERRIDE; + void requestActivateWindow() override; - WId winId() const Q_DECL_OVERRIDE; - void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE; + WId winId() const override; + void setParent(const QPlatformWindow *window) override; NSView *view() const; NSWindow *nativeWindow() const; @@ -167,10 +167,10 @@ public: QCocoaGLContext *currentContext() const; #endif - bool setWindowModified(bool modified) Q_DECL_OVERRIDE; + bool setWindowModified(bool modified) override; - void setFrameStrutEventsEnabled(bool enabled) Q_DECL_OVERRIDE; - bool frameStrutEventsEnabled() const Q_DECL_OVERRIDE + void setFrameStrutEventsEnabled(bool enabled) override; + bool frameStrutEventsEnabled() const override { return m_frameStrutEventsEnabled; } void setMenubar(QCocoaMenuBar *mb); @@ -187,7 +187,7 @@ public: void applyContentBorderThickness(NSWindow *window = nullptr); void updateNSToolbar(); - qreal devicePixelRatio() const Q_DECL_OVERRIDE; + qreal devicePixelRatio() const override; QWindow *childWindowAt(QPoint windowPoint); bool shouldRefuseKeyWindowAndFirstResponder(); @@ -209,8 +209,6 @@ protected: void recreateWindowIfNeeded(); QCocoaNSWindow *createNSWindow(bool shouldBePanel); - QRect nativeWindowGeometry() const; - Qt::WindowState windowState() const; void applyWindowState(Qt::WindowStates newState); void toggleMaximized(); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index d1f19f2de9..c3160e32c2 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -286,7 +286,7 @@ QRect QCocoaWindow::geometry() const NSPoint windowPoint = [m_view convertPoint:NSMakePoint(0, 0) toView:nil]; NSRect screenRect = [[m_view window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)]; NSPoint screenPoint = screenRect.origin; - QPoint position = qt_mac_flipPoint(screenPoint).toPoint(); + QPoint position = QCocoaScreen::mapFromNative(screenPoint).toPoint(); QSize size = QRectF::fromCGRect(NSRectToCGRect([m_view bounds])).toRect().size(); return QRect(position, size); } @@ -309,7 +309,7 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect) } if (isContentView()) { - NSRect bounds = qt_mac_flipRect(rect); + NSRect bounds = QCocoaScreen::mapToNative(rect); [m_view.window setFrame:[m_view.window frameRectForContentRect:bounds] display:YES animate:NO]; } else { [m_view setFrame:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; @@ -402,7 +402,7 @@ void QCocoaWindow::setVisible(bool visible) if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) { removeMonitor(); monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDownMask|NSMouseMovedMask handler:^(NSEvent *e) { - QPointF localPoint = qt_mac_flipPoint([NSEvent mouseLocation]); + QPointF localPoint = QCocoaScreen::mapFromNative([NSEvent mouseLocation]); QWindowSystemInterface::handleMouseEvent(window(), window()->mapFromGlobal(localPoint.toPoint()), localPoint, cocoaButton2QtButton([e buttonNumber])); }]; @@ -1115,7 +1115,7 @@ void QCocoaWindow::handleGeometryChange() CGRect contentRect = [m_view.window contentRectForFrameRect:m_view.window.frame]; // The result above is in native screen coordinates, so remap to the Qt coordinate system - newGeometry = QCocoaScreen::primaryScreen()->mapFromNative(QRectF::fromCGRect(contentRect)).toRect(); + newGeometry = QCocoaScreen::mapFromNative(contentRect).toRect(); } else { // QNSView has isFlipped set, so no need to remap the geometry newGeometry = QRectF::fromCGRect(m_view.frame).toRect(); @@ -1377,7 +1377,7 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel) rect.translate(-targetScreen->geometry().topLeft()); QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(targetScreen->handle()); - NSRect frame = NSRectFromCGRect(cocoaScreen->mapToNative(rect).toCGRect()); + NSRect frame = QCocoaScreen::mapToNative(rect, cocoaScreen); // Note: The macOS window manager has a bug, where if a screen is rotated, it will not allow // a window to be created within the area of the screen that has a Y coordinate (I quadrant) @@ -1473,19 +1473,6 @@ void QCocoaWindow::removeMonitor() monitor = nil; } -// Returns the current global screen geometry for the nswindow associated with this window. -QRect QCocoaWindow::nativeWindowGeometry() const -{ - if (!isContentView()) - return geometry(); - - NSRect rect = m_view.window.frame; - QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window()); - int flippedY = onScreen->geometry().height() - rect.origin.y - rect.size.height; // account for nswindow inverted y. - QRect qRect = QRect(rect.origin.x, flippedY, rect.size.width, rect.size.height); - return qRect; -} - /*! Applies the given state to the NSWindow, going in/out of minimize/zoomed/fullscreen diff --git a/src/plugins/platforms/cocoa/qmultitouch_mac.mm b/src/plugins/platforms/cocoa/qmultitouch_mac.mm index 79f8af7783..9eca4d2d43 100644 --- a/src/plugins/platforms/cocoa/qmultitouch_mac.mm +++ b/src/plugins/platforms/cocoa/qmultitouch_mac.mm @@ -39,6 +39,7 @@ #include "qmultitouch_mac_p.h" #include "qcocoahelpers.h" +#include "qcocoascreen.h" #include <private/qtouchdevice_p.h> QT_BEGIN_NAMESPACE @@ -83,7 +84,7 @@ void QCocoaTouch::updateTouchData(NSTouch *nstouch, NSTouchPhase phase) if (_touchPoint.id == 0 && phase == NSTouchPhaseBegan) { _trackpadReferencePos = qnpos; - _screenReferencePos = qt_mac_flipPoint([NSEvent mouseLocation]); + _screenReferencePos = QCocoaScreen::mapFromNative([NSEvent mouseLocation]); } QPointF screenPos = _screenReferencePos; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 28ffcf8718..90a6f936e2 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -42,6 +42,7 @@ #include "qnsview.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" +#include "qcocoascreen.h" #include "qmultitouch_mac_p.h" #include "qcocoadrag.h" #include "qcocoainputcontext.h" @@ -436,8 +437,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") nsWindowPoint = windowRect.origin; // NSWindow coordinates NSPoint nsViewPoint = [self convertPoint: nsWindowPoint fromView: nil]; // NSView/QWindow coordinates *qtWindowPoint = QPointF(nsViewPoint.x, nsViewPoint.y); // NSView/QWindow coordinates - - *qtScreenPoint = QPointF(mouseLocation.x, qt_mac_flipYCoordinate(mouseLocation.y)); // Qt screen coordinates + *qtScreenPoint = QCocoaScreen::mapFromNative(mouseLocation); } - (void)resetMouseButtons @@ -548,7 +548,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil]; QPoint qtWindowPoint = QPoint(nsViewPoint.x, titleBarHeight + nsViewPoint.y); NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 0, 0)].origin; - QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y)); + QPoint qtScreenPoint = QCocoaScreen::mapFromNative(screenPoint).toPoint(); ulong timestamp = [theEvent timestamp] * 1000; QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons); @@ -640,7 +640,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") if (!popups->isEmpty()) { // Check if the click is outside all popups. bool inside = false; - QPointF qtScreenPoint = qt_mac_flipPoint([self screenMousePoint:theEvent]); + QPointF qtScreenPoint = QCocoaScreen::mapFromNative([self screenMousePoint:theEvent]); for (QList<QCocoaWindow *>::const_iterator it = popups->begin(); it != popups->end(); ++it) { if ((*it)->geometry().contains(qtScreenPoint.toPoint())) { inside = true; @@ -1730,14 +1730,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) // The returned rect is always based on the internal cursor. QRect mr = qApp->inputMethod()->cursorRectangle().toRect(); - QPoint mp = m_platformWindow->window()->mapToGlobal(mr.bottomLeft()); - - NSRect rect; - rect.origin.x = mp.x(); - rect.origin.y = qt_mac_flipYCoordinate(mp.y()); - rect.size.width = mr.width(); - rect.size.height = mr.height(); - return rect; + mr.moveBottomLeft(m_platformWindow->window()->mapToGlobal(mr.bottomLeft())); + return QCocoaScreen::mapToNative(mr); } - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint @@ -2023,8 +2017,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin NSPoint windowPoint = [self.window convertRectFromScreen:NSMakeRect(screenPoint.x, screenPoint.y, 1, 1)].origin; NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil]; // NSView/QWindow coordinates QPoint qtWindowPoint(nsViewPoint.x, nsViewPoint.y); - - QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y)); + QPoint qtScreenPoint = QCocoaScreen::mapFromNative(screenPoint).toPoint(); QWindowSystemInterface::handleMouseEvent(target, mapWindowCoordinates(m_platformWindow->window(), target, qtWindowPoint), qtScreenPoint, m_buttons); } diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index c39af870d4..b3d48c1ec3 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -247,7 +247,7 @@ void QMacPrintEnginePrivate::initialize() QList<int> resolutions = m_printDevice->supportedResolutions(); if (!resolutions.isEmpty() && mode != QPrinter::ScreenResolution) { - qSort(resolutions); + std::sort(resolutions.begin(), resolutions.end()); if (resolutions.count() > 1 && mode == QPrinter::HighResolution) resolution.hRes = resolution.vRes = resolutions.last(); else diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h index 2d46a250d5..9514f3e691 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h +++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h @@ -150,8 +150,8 @@ public: PMPrintSession session() const { return static_cast<PMPrintSession>([printInfo PMPrintSession]); } PMPrintSettings settings() const { return static_cast<PMPrintSettings>([printInfo PMPrintSettings]); } - QPaintEngine *aggregateEngine() Q_DECL_OVERRIDE { return paintEngine; } - Qt::HANDLE nativeHandle() Q_DECL_OVERRIDE { return q_func()->handle(); } + QPaintEngine *aggregateEngine() override { return paintEngine; } + Qt::HANDLE nativeHandle() override { return q_func()->handle(); } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h index 670c4e9840..f72ea2b038 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h @@ -54,12 +54,12 @@ public: QWindowsDirect2DBackingStore(QWindow *window); ~QWindowsDirect2DBackingStore(); - void beginPaint(const QRegion &) Q_DECL_OVERRIDE; - void endPaint() Q_DECL_OVERRIDE; + void beginPaint(const QRegion &) override; + void endPaint() override; - QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - void flush(QWindow *targetWindow, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; - void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE; + QPaintDevice *paintDevice() override; + void flush(QWindow *targetWindow, const QRegion ®ion, const QPoint &offset) override; + void resize(const QSize &size, const QRegion &staticContents) override; QImage toImage() const override; }; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp index 643ae877d0..d578a58982 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp @@ -161,7 +161,7 @@ void QWindowsDirect2DDeviceContextSuspender::resume() { if (m_dc) { m_dc->resume(); - m_dc = Q_NULLPTR; + m_dc = nullptr; } } diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp index ea51135583..97e3a25b86 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp @@ -203,7 +203,7 @@ QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringLi caption.toStdWString().c_str(), MB_OK | MB_ICONERROR); - return Q_NULLPTR; + return nullptr; } QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h index 43f2a08745..39ca1d0dbf 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h @@ -58,15 +58,15 @@ public: static QWindowsDirect2DIntegration *instance(); - QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; - QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QPlatformNativeInterface *nativeInterface() const override; + QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const override; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; + QAbstractEventDispatcher *createEventDispatcher() const override; QWindowsDirect2DContext *direct2DContext() const; protected: - QWindowsWindow *createPlatformWindowHelper(QWindow *window, const QWindowsWindowData &) const Q_DECL_OVERRIDE; + QWindowsWindow *createPlatformWindowHelper(QWindow *window, const QWindowsWindowData &) const override; private: explicit QWindowsDirect2DIntegration(const QStringList ¶mList); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h index d57136129b..fce6ff9969 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h @@ -48,7 +48,7 @@ class QWindowsDirect2DNativeInterface : public QWindowsNativeInterface { Q_OBJECT public: - void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) Q_DECL_OVERRIDE; + void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h index f434ef993c..1f23d604f5 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h @@ -58,11 +58,11 @@ public: QWindowsDirect2DPaintEngine::Flags paintFlags = QWindowsDirect2DPaintEngine::NoFlag); ~QWindowsDirect2DPaintDevice(); - QPaintEngine *paintEngine() const Q_DECL_OVERRIDE; - int devType() const Q_DECL_OVERRIDE; + QPaintEngine *paintEngine() const override; + int devType() const override; protected: - int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE; + int metric(PaintDeviceMetric metric) const override; private: QScopedPointer<QWindowsDirect2DPaintDevicePrivate> d_ptr; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 164429ba30..95fbd37247 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -804,7 +804,7 @@ public: const bool alias = !q->antiAliasingEnabled(); QVectorPath::CacheEntry *cacheEntry = path.isCacheable() ? path.lookupCacheData(q) - : Q_NULLPTR; + : nullptr; if (cacheEntry) { D2DVectorPathCache *e = static_cast<D2DVectorPathCache *>(cacheEntry->data); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index a8f63af5d5..b9616acd6a 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -65,45 +65,45 @@ public: QWindowsDirect2DPaintEngine(QWindowsDirect2DBitmap *bitmap, Flags flags); - bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE; - bool end() Q_DECL_OVERRIDE; + bool begin(QPaintDevice *pdev) override; + bool end() override; - Type type() const Q_DECL_OVERRIDE; + Type type() const override; - void setState(QPainterState *s) Q_DECL_OVERRIDE; + void setState(QPainterState *s) override; - void draw(const QVectorPath &path) Q_DECL_OVERRIDE; + void draw(const QVectorPath &path) override; - void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE; + void fill(const QVectorPath &path, const QBrush &brush) override; void fill(ID2D1Geometry *geometry, const QBrush &brush); - void stroke(const QVectorPath &path, const QPen &pen) Q_DECL_OVERRIDE; + void stroke(const QVectorPath &path, const QPen &pen) override; void stroke(ID2D1Geometry *geometry, const QPen &pen); - void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE; + void clip(const QVectorPath &path, Qt::ClipOperation op) override; - void clipEnabledChanged() Q_DECL_OVERRIDE; - void penChanged() Q_DECL_OVERRIDE; - void brushChanged() Q_DECL_OVERRIDE; - void brushOriginChanged() Q_DECL_OVERRIDE; - void opacityChanged() Q_DECL_OVERRIDE; - void compositionModeChanged() Q_DECL_OVERRIDE; - void renderHintsChanged() Q_DECL_OVERRIDE; - void transformChanged() Q_DECL_OVERRIDE; + void clipEnabledChanged() override; + void penChanged() override; + void brushChanged() override; + void brushOriginChanged() override; + void opacityChanged() override; + void compositionModeChanged() override; + void renderHintsChanged() override; + void transformChanged() override; - void fillRect(const QRectF &rect, const QBrush &brush) Q_DECL_OVERRIDE; + void fillRect(const QRectF &rect, const QBrush &brush) override; - void drawRects(const QRect *rects, int rectCount) Q_DECL_OVERRIDE; - void drawRects(const QRectF *rects, int rectCount) Q_DECL_OVERRIDE; + void drawRects(const QRect *rects, int rectCount) override; + void drawRects(const QRectF *rects, int rectCount) override; - void drawEllipse(const QRectF &r) Q_DECL_OVERRIDE; - void drawEllipse(const QRect &r) Q_DECL_OVERRIDE; + void drawEllipse(const QRectF &r) override; + void drawEllipse(const QRect &r) override; - void drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE; - void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE; + void drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor) override; + void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override; - void drawStaticTextItem(QStaticTextItem *staticTextItem) Q_DECL_OVERRIDE; - void drawTextItem(const QPointF &p, const QTextItem &textItem) Q_DECL_OVERRIDE; + void drawStaticTextItem(QStaticTextItem *staticTextItem) override; + void drawTextItem(const QPointF &p, const QTextItem &textItem) override; private: void ensureBrush(); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h index 5f65a2313a..0448613a95 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h @@ -59,21 +59,21 @@ public: QWindowsDirect2DPlatformPixmap(PixelType pixelType, QWindowsDirect2DPaintEngine::Flags flags, QWindowsDirect2DBitmap *bitmap); ~QWindowsDirect2DPlatformPixmap(); - void resize(int width, int height) Q_DECL_OVERRIDE; - void fromImage(const QImage &image, Qt::ImageConversionFlags flags) Q_DECL_OVERRIDE; + void resize(int width, int height) override; + void fromImage(const QImage &image, Qt::ImageConversionFlags flags) override; - int metric(QPaintDevice::PaintDeviceMetric metric) const Q_DECL_OVERRIDE; - void fill(const QColor &color) Q_DECL_OVERRIDE; + int metric(QPaintDevice::PaintDeviceMetric metric) const override; + void fill(const QColor &color) override; - bool hasAlphaChannel() const Q_DECL_OVERRIDE; + bool hasAlphaChannel() const override; - QImage toImage() const Q_DECL_OVERRIDE; - QImage toImage(const QRect &rect) const Q_DECL_OVERRIDE; + QImage toImage() const override; + QImage toImage(const QRect &rect) const override; - QPaintEngine* paintEngine() const Q_DECL_OVERRIDE; + QPaintEngine* paintEngine() const override; - qreal devicePixelRatio() const Q_DECL_OVERRIDE; - void setDevicePixelRatio(qreal scaleFactor) Q_DECL_OVERRIDE; + qreal devicePixelRatio() const override; + void setDevicePixelRatio(qreal scaleFactor) override; QWindowsDirect2DBitmap *bitmap() const; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp index 21294cfb15..f81182e0b1 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp @@ -209,7 +209,7 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size) { m_pixmap.reset(); m_bitmap.reset(); - m_deviceContext->SetTarget(Q_NULLPTR); + m_deviceContext->SetTarget(nullptr); m_needsFullFlush = true; if (!m_swapChain) @@ -241,7 +241,7 @@ QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer() dpiX, // FLOAT dpiX; dpiY, // FLOAT dpiY; D2D1_BITMAP_OPTIONS_TARGET, // D2D1_BITMAP_OPTIONS bitmapOptions; - Q_NULLPTR // _Field_size_opt_(1) ID2D1ColorContext *colorContext; + nullptr // _Field_size_opt_(1) ID2D1ColorContext *colorContext; }; ComPtr<ID2D1Bitmap1> copy; HRESULT hr = m_deviceContext.Get()->CreateBitmap(size, NULL, 0, properties, ©); @@ -257,7 +257,7 @@ QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer() return null_result; } - return QSharedPointer<QWindowsDirect2DBitmap>(new QWindowsDirect2DBitmap(copy.Get(), Q_NULLPTR)); + return QSharedPointer<QWindowsDirect2DBitmap>(new QWindowsDirect2DBitmap(copy.Get(), nullptr)); } void QWindowsDirect2DWindow::setupBitmap() diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h index 156d4660d1..3ac532d938 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h @@ -56,7 +56,7 @@ public: QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data); ~QWindowsDirect2DWindow(); - void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE; + void setWindowFlags(Qt::WindowFlags flags) override; QPixmap *pixmap(); void flush(QWindowsDirect2DBitmap *bitmap, const QRegion ®ion, const QPoint &offset); diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp index e411ea55e9..0fc4cc54e0 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp @@ -103,7 +103,7 @@ QStringList QEglFSDeviceIntegrationFactory::keys(const QString &pluginPath) QEglFSDeviceIntegration *QEglFSDeviceIntegrationFactory::create(const QString &key, const QString &pluginPath) { - QEglFSDeviceIntegration *integration = Q_NULLPTR; + QEglFSDeviceIntegration *integration = nullptr; #if QT_CONFIG(library) if (!pluginPath.isEmpty()) { QCoreApplication::addLibraryPath(pluginPath); @@ -351,9 +351,21 @@ bool QEglFSDeviceIntegration::supportsSurfacelessContexts() const return true; } +QFunctionPointer QEglFSDeviceIntegration::platformFunction(const QByteArray &function) const +{ + Q_UNUSED(function); + return nullptr; +} + +void *QEglFSDeviceIntegration::nativeResourceForIntegration(const QByteArray &name) +{ + Q_UNUSED(name); + return nullptr; +} + void *QEglFSDeviceIntegration::wlDisplay() const { - return Q_NULLPTR; + return nullptr; } EGLConfig QEglFSDeviceIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format) diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h index 4335554912..d927bc9bc6 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h @@ -103,6 +103,8 @@ public: virtual int framebufferIndex() const; virtual bool supportsPBuffers() const; virtual bool supportsSurfacelessContexts() const; + virtual QFunctionPointer platformFunction(const QByteArray &function) const; + virtual void *nativeResourceForIntegration(const QByteArray &name); virtual void *wlDisplay() const; diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp index 9a0be489a8..c0ecfd235f 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp @@ -324,6 +324,7 @@ void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource result = qt_egl_device_integration()->wlDisplay(); break; default: + result = qt_egl_device_integration()->nativeResourceForIntegration(resource); break; } @@ -427,11 +428,9 @@ QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function) #if QT_CONFIG(evdev) if (function == QEglFSFunctions::loadKeymapTypeIdentifier()) return QFunctionPointer(loadKeymapStatic); -#else - Q_UNUSED(function) #endif - return 0; + return qt_egl_device_integration()->platformFunction(function); } void QEglFSIntegration::loadKeymapStatic(const QString &filename) diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h index 6bda262523..c61f04f569 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h @@ -95,7 +95,7 @@ public: EGLNativeWindowType eglWindow() const; EGLSurface surface() const; - QEglFSScreen *screen() const; + QEglFSScreen *screen() const override; bool hasNativeWindow() const { return m_flags.testFlag(HasNativeWindow); } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro index 27c0af1f08..43170a3875 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro @@ -19,11 +19,13 @@ SOURCES += $$PWD/qeglfskmsgbmmain.cpp \ $$PWD/qeglfskmsgbmintegration.cpp \ $$PWD/qeglfskmsgbmdevice.cpp \ $$PWD/qeglfskmsgbmscreen.cpp \ - $$PWD/qeglfskmsgbmcursor.cpp + $$PWD/qeglfskmsgbmcursor.cpp \ + $$PWD/qeglfskmsgbmwindow.cpp HEADERS += $$PWD/qeglfskmsgbmintegration.h \ $$PWD/qeglfskmsgbmdevice.h \ $$PWD/qeglfskmsgbmscreen.h \ - $$PWD/qeglfskmsgbmcursor.h + $$PWD/qeglfskmsgbmcursor.h \ + $$PWD/qeglfskmsgbmwindow.h OTHER_FILES += $$PWD/eglfs_kms.json diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp index 800118362d..9bd7fee1fb 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp @@ -68,7 +68,7 @@ Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen) : m_screen(screen) , m_cursorSize(64, 64) // 64x64 is the old standard size, we now try to query the real size below - , m_bo(Q_NULLPTR) + , m_bo(nullptr) , m_cursorImage(0, 0, 0, 0, 0, 0) , m_state(CursorPendingVisible) { @@ -118,7 +118,7 @@ QEglFSKmsGbmCursor::~QEglFSKmsGbmCursor() if (m_bo) { gbm_bo_destroy(m_bo); - m_bo = Q_NULLPTR; + m_bo = nullptr; } } @@ -132,7 +132,7 @@ void QEglFSKmsGbmCursor::updateMouseStatus() m_state = visible ? CursorPendingVisible : CursorPendingHidden; #ifndef QT_NO_CURSOR - changeCursor(Q_NULLPTR, m_screen->topLevelAt(pos())); + changeCursor(nullptr, m_screen->topLevelAt(pos())); #endif } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp index e218d580a2..20127ae7f7 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp @@ -53,28 +53,17 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) -void QEglFSKmsGbmDevice::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) -{ - Q_UNUSED(fd); - Q_UNUSED(sequence); - Q_UNUSED(tv_sec); - Q_UNUSED(tv_usec); - - QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(user_data); - screen->flipFinished(); -} - QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig, const QString &path) : QEglFSKmsDevice(screenConfig, path) - , m_gbm_device(Q_NULLPTR) - , m_globalCursor(Q_NULLPTR) + , m_gbm_device(nullptr) + , m_globalCursor(nullptr) { } bool QEglFSKmsGbmDevice::open() { Q_ASSERT(fd() == -1); - Q_ASSERT(m_gbm_device == Q_NULLPTR); + Q_ASSERT(m_gbm_device == nullptr); int fd = qt_safe_open(devicePath().toLocal8Bit().constData(), O_RDWR | O_CLOEXEC); if (fd == -1) { @@ -103,7 +92,7 @@ void QEglFSKmsGbmDevice::close() if (m_gbm_device) { gbm_device_destroy(m_gbm_device); - m_gbm_device = Q_NULLPTR; + m_gbm_device = nullptr; } if (fd() != -1) { @@ -134,24 +123,13 @@ void QEglFSKmsGbmDevice::destroyGlobalCursor() if (m_globalCursor) { qCDebug(qLcEglfsKmsDebug, "Destroying global GBM mouse cursor"); delete m_globalCursor; - m_globalCursor = Q_NULLPTR; + m_globalCursor = nullptr; } } -void QEglFSKmsGbmDevice::handleDrmEvent() -{ - drmEventContext drmEvent; - memset(&drmEvent, 0, sizeof(drmEvent)); - drmEvent.version = 2; - drmEvent.vblank_handler = nullptr; - drmEvent.page_flip_handler = pageFlipHandler; - - drmHandleEvent(fd(), &drmEvent); -} - QPlatformScreen *QEglFSKmsGbmDevice::createScreen(const QKmsOutput &output) { - QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(this, output); + QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(this, output, false); if (!m_globalCursor && screenConfig()->hwCursor()) { qCDebug(qLcEglfsKmsDebug, "Creating new global GBM mouse cursor"); @@ -161,4 +139,20 @@ QPlatformScreen *QEglFSKmsGbmDevice::createScreen(const QKmsOutput &output) return screen; } +QPlatformScreen *QEglFSKmsGbmDevice::createHeadlessScreen() +{ + return new QEglFSKmsGbmScreen(this, QKmsOutput(), true); +} + +void QEglFSKmsGbmDevice::registerScreenCloning(QPlatformScreen *screen, + QPlatformScreen *screenThisScreenClones, + const QVector<QPlatformScreen *> &screensCloningThisScreen) +{ + if (!screenThisScreenClones && screensCloningThisScreen.isEmpty()) + return; + + QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen *>(screen); + gbmScreen->initCloning(screenThisScreenClones, screensCloningThisScreen); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h index 08ca28d48e..518e2ce58b 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h @@ -65,9 +65,11 @@ public: QPlatformCursor *globalCursor() const; void destroyGlobalCursor(); - void handleDrmEvent(); - QPlatformScreen *createScreen(const QKmsOutput &output) override; + QPlatformScreen *createHeadlessScreen() override; + void registerScreenCloning(QPlatformScreen *screen, + QPlatformScreen *screenThisScreenClones, + const QVector<QPlatformScreen *> &screensCloningThisScreen) override; private: Q_DISABLE_COPY(QEglFSKmsGbmDevice) @@ -75,12 +77,6 @@ private: gbm_device *m_gbm_device; QEglFSKmsGbmCursor *m_globalCursor; - - static void pageFlipHandler(int fd, - unsigned int sequence, - unsigned int tv_sec, - unsigned int tv_usec, - void *user_data); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp index 058791e473..402338197d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp @@ -43,21 +43,13 @@ #include "qeglfskmsgbmdevice.h" #include "qeglfskmsgbmscreen.h" #include "qeglfskmsgbmcursor.h" -#include "private/qeglfswindow_p.h" +#include "qeglfskmsgbmwindow.h" #include "private/qeglfscursor_p.h" -#include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h> -#include <QtEglSupport/private/qeglconvenience_p.h> #include <QtCore/QLoggingCategory> -#include <QtCore/QJsonDocument> -#include <QtCore/QJsonObject> -#include <QtCore/QJsonArray> -#include <QtGui/qpa/qplatformwindow.h> -#include <QtGui/qpa/qplatformcursor.h> #include <QtGui/QScreen> +#include <QtDeviceDiscoverySupport/private/qdevicediscovery_p.h> -#include <xf86drm.h> -#include <xf86drmMode.h> #include <gbm.h> QT_BEGIN_NAMESPACE @@ -105,7 +97,6 @@ EGLNativeWindowType QEglFSKmsGbmIntegration::createNativeOffscreenWindow(const Q Q_UNUSED(format); Q_ASSERT(device()); - qCDebug(qLcEglfsKmsDebug) << "Creating native off screen window"; gbm_surface *surface = gbm_surface_create(static_cast<QEglFSKmsGbmDevice *>(device())->gbmDevice(), 1, 1, GBM_FORMAT_XRGB8888, @@ -134,8 +125,7 @@ QPlatformCursor *QEglFSKmsGbmIntegration::createCursor(QPlatformScreen *screen) void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface) { QWindow *window = static_cast<QWindow *>(surface->surface()); - QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(window->screen()->handle()); - + QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(window->screen()->handle()); screen->flip(); } @@ -160,46 +150,6 @@ QKmsDevice *QEglFSKmsGbmIntegration::createDevice() return new QEglFSKmsGbmDevice(screenConfig(), path); } -class QEglFSKmsGbmWindow : public QEglFSWindow -{ -public: - QEglFSKmsGbmWindow(QWindow *w, const QEglFSKmsGbmIntegration *integration) - : QEglFSWindow(w) - , m_integration(integration) - {} - void resetSurface() override; - const QEglFSKmsGbmIntegration *m_integration; -}; - -void QEglFSKmsGbmWindow::resetSurface() -{ - QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen *>(screen()); - if (gbmScreen->surface()) { - qWarning("Only single window per screen supported!"); - return; - } - - EGLDisplay display = gbmScreen->display(); - QSurfaceFormat platformFormat = m_integration->surfaceFormatFor(window()->requestedFormat()); - m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat); - m_format = q_glFormatFromConfig(display, m_config, platformFormat); - m_window = reinterpret_cast<EGLNativeWindowType>(gbmScreen->createSurface()); - - PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC createPlatformWindowSurface = nullptr; - const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - if (extensions && (strstr(extensions, "EGL_KHR_platform_gbm") || strstr(extensions, "EGL_MESA_platform_gbm"))) { - createPlatformWindowSurface = reinterpret_cast<PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC>( - eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT")); - } - - if (createPlatformWindowSurface) { - m_surface = createPlatformWindowSurface(display, m_config, reinterpret_cast<void *>(m_window), nullptr); - } else { - qCDebug(qLcEglfsKmsDebug, "No eglCreatePlatformWindowSurface for GBM, falling back to eglCreateWindowSurface"); - m_surface = eglCreateWindowSurface(display, m_config, m_window, nullptr); - } -} - QEglFSWindow *QEglFSKmsGbmIntegration::createWindow(QWindow *window) const { return new QEglFSKmsGbmWindow(window, this); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 87fb3146c7..4742143121 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** +** Copyright (C) 2017 The Qt Company Ltd. ** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** @@ -55,6 +55,18 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) +static inline uint32_t drmFormatToGbmFormat(uint32_t drmFormat) +{ + Q_ASSERT(DRM_FORMAT_XRGB8888 == GBM_FORMAT_XRGB8888); + return drmFormat; +} + +static inline uint32_t gbmFormatToDrmFormat(uint32_t gbmFormat) +{ + Q_ASSERT(DRM_FORMAT_XRGB8888 == GBM_FORMAT_XRGB8888); + return gbmFormat; +} + void QEglFSKmsGbmScreen::bufferDestroyedHandler(gbm_bo *bo, void *data) { FrameBuffer *fb = static_cast<FrameBuffer *>(data); @@ -77,29 +89,34 @@ QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject( uint32_t width = gbm_bo_get_width(bo); uint32_t height = gbm_bo_get_height(bo); - uint32_t stride = gbm_bo_get_stride(bo); - uint32_t handle = gbm_bo_get_handle(bo).u32; + uint32_t handles[4] = { gbm_bo_get_handle(bo).u32 }; + uint32_t strides[4] = { gbm_bo_get_stride(bo) }; + uint32_t offsets[4] = { 0 }; + uint32_t pixelFormat = gbmFormatToDrmFormat(gbm_bo_get_format(bo)); QScopedPointer<FrameBuffer> fb(new FrameBuffer); + qCDebug(qLcEglfsKmsDebug, "Adding FB, size %ux%u, DRM format 0x%x", width, height, pixelFormat); - int ret = drmModeAddFB(device()->fd(), width, height, 24, 32, - stride, handle, &fb->fb); + int ret = drmModeAddFB2(device()->fd(), width, height, pixelFormat, + handles, strides, offsets, &fb->fb, 0); if (ret) { qWarning("Failed to create KMS FB!"); - return Q_NULLPTR; + return nullptr; } gbm_bo_set_user_data(bo, fb.data(), bufferDestroyedHandler); return fb.take(); } -QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output) - : QEglFSKmsScreen(device, output) - , m_gbm_surface(Q_NULLPTR) - , m_gbm_bo_current(Q_NULLPTR) - , m_gbm_bo_next(Q_NULLPTR) - , m_cursor(Q_NULLPTR) +QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output, bool headless) + : QEglFSKmsScreen(device, output, headless) + , m_gbm_surface(nullptr) + , m_gbm_bo_current(nullptr) + , m_gbm_bo_next(nullptr) + , m_flipPending(false) + , m_cursor(nullptr) + , m_cloneSource(nullptr) { } @@ -114,6 +131,8 @@ QEglFSKmsGbmScreen::~QEglFSKmsGbmScreen() QPlatformCursor *QEglFSKmsGbmScreen::cursor() const { QKmsScreenConfig *config = device()->screenConfig(); + if (config->headless()) + return nullptr; if (config->hwCursor()) { if (!config->separateScreens()) return static_cast<QEglFSKmsGbmDevice *>(device())->globalCursor(); @@ -132,47 +151,112 @@ QPlatformCursor *QEglFSKmsGbmScreen::cursor() const gbm_surface *QEglFSKmsGbmScreen::createSurface() { if (!m_gbm_surface) { - qCDebug(qLcEglfsKmsDebug) << "Creating window for screen" << name(); + uint32_t gbmFormat = drmFormatToGbmFormat(m_output.drm_format); + qCDebug(qLcEglfsKmsDebug, "Creating gbm_surface for screen %s with format 0x%x", qPrintable(name()), gbmFormat); m_gbm_surface = gbm_surface_create(static_cast<QEglFSKmsGbmDevice *>(device())->gbmDevice(), rawGeometry().width(), rawGeometry().height(), - GBM_FORMAT_XRGB8888, + gbmFormat, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); } - return m_gbm_surface; + return m_gbm_surface; // not owned, gets destroyed in QEglFSKmsGbmIntegration::destroyNativeWindow() via QEglFSKmsGbmWindow::invalidateSurface() } -void QEglFSKmsGbmScreen::destroySurface() +void QEglFSKmsGbmScreen::resetSurface() { - if (m_gbm_bo_current) { - gbm_bo_destroy(m_gbm_bo_current); - m_gbm_bo_current = Q_NULLPTR; - } + m_gbm_surface = nullptr; +} - if (m_gbm_bo_next) { - gbm_bo_destroy(m_gbm_bo_next); - m_gbm_bo_next = Q_NULLPTR; +void QEglFSKmsGbmScreen::initCloning(QPlatformScreen *screenThisScreenClones, + const QVector<QPlatformScreen *> &screensCloningThisScreen) +{ + // clone destinations need to know the clone source + const bool clonesAnother = screenThisScreenClones != nullptr; + if (clonesAnother && !screensCloningThisScreen.isEmpty()) { + qWarning("QEglFSKmsGbmScreen %s cannot be clone source and destination at the same time", qPrintable(name())); + return; } + if (clonesAnother) + m_cloneSource = static_cast<QEglFSKmsGbmScreen *>(screenThisScreenClones); + + // clone sources need to know their additional destinations + for (QPlatformScreen *s : screensCloningThisScreen) { + CloneDestination d; + d.screen = static_cast<QEglFSKmsGbmScreen *>(s); + m_cloneDests.append(d); + } +} + +void QEglFSKmsGbmScreen::ensureModeSet(uint32_t fb) +{ + QKmsOutput &op(output()); + const int fd = device()->fd(); + + if (!op.mode_set) { + op.mode_set = true; + + bool doModeSet = true; + drmModeCrtcPtr currentMode = drmModeGetCrtc(fd, op.crtc_id); + const bool alreadySet = currentMode && !memcmp(¤tMode->mode, &op.modes[op.mode], sizeof(drmModeModeInfo)); + if (currentMode) + drmModeFreeCrtc(currentMode); + if (alreadySet) { + static bool alwaysDoSet = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ALWAYS_SET_MODE"); + if (!alwaysDoSet) { + qCDebug(qLcEglfsKmsDebug, "Mode already set, skipping modesetting for screen %s", qPrintable(name())); + doModeSet = false; + } + } - if (m_gbm_surface) { - gbm_surface_destroy(m_gbm_surface); - m_gbm_surface = Q_NULLPTR; + if (doModeSet) { + qCDebug(qLcEglfsKmsDebug, "Setting mode for screen %s", qPrintable(name())); + int ret = drmModeSetCrtc(fd, + op.crtc_id, + fb, + 0, 0, + &op.connector_id, 1, + &op.modes[op.mode]); + + if (ret == 0) + setPowerState(PowerStateOn); + else + qErrnoWarning(errno, "Could not set DRM mode for screen %s", qPrintable(name())); + } } } void QEglFSKmsGbmScreen::waitForFlip() { + if (m_headless || m_cloneSource) + return; + // Don't lock the mutex unless we actually need to if (!m_gbm_bo_next) return; QMutexLocker lock(&m_waitForFlipMutex); - while (m_gbm_bo_next) - static_cast<QEglFSKmsGbmDevice *>(device())->handleDrmEvent(); + while (m_gbm_bo_next) { + drmEventContext drmEvent; + memset(&drmEvent, 0, sizeof(drmEvent)); + drmEvent.version = 2; + drmEvent.vblank_handler = nullptr; + drmEvent.page_flip_handler = pageFlipHandler; + drmHandleEvent(device()->fd(), &drmEvent); + } } void QEglFSKmsGbmScreen::flip() { + // For headless screen just return silently. It is not necessarily an error + // to end up here, so show no warnings. + if (m_headless) + return; + + if (m_cloneSource) { + qWarning("Screen %s clones another screen. swapBuffers() not allowed.", qPrintable(name())); + return; + } + if (!m_gbm_surface) { qWarning("Cannot sync before platform init!"); return; @@ -185,60 +269,92 @@ void QEglFSKmsGbmScreen::flip() } FrameBuffer *fb = framebufferForBufferObject(m_gbm_bo_next); + ensureModeSet(fb->fb); QKmsOutput &op(output()); const int fd = device()->fd(); - const uint32_t w = op.modes[op.mode].hdisplay; - const uint32_t h = op.modes[op.mode].vdisplay; - - if (!op.mode_set) { - int ret = drmModeSetCrtc(fd, - op.crtc_id, - fb->fb, - 0, 0, - &op.connector_id, 1, - &op.modes[op.mode]); - - if (ret == -1) { - qErrnoWarning(errno, "Could not set DRM mode!"); - } else { - op.mode_set = true; - setPowerState(PowerStateOn); - - if (!op.plane_set) { - op.plane_set = true; - if (op.wants_plane) { - int ret = drmModeSetPlane(fd, op.plane_id, op.crtc_id, - uint32_t(-1), 0, - 0, 0, w, h, - 0 << 16, 0 << 16, w << 16, h << 16); - if (ret == -1) - qErrnoWarning(errno, "drmModeSetPlane failed"); - } - } - } - } - + m_flipPending = true; int ret = drmModePageFlip(fd, op.crtc_id, fb->fb, DRM_MODE_PAGE_FLIP_EVENT, this); if (ret) { - qErrnoWarning("Could not queue DRM page flip!"); + qErrnoWarning("Could not queue DRM page flip on screen %s", qPrintable(name())); + m_flipPending = false; gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next); - m_gbm_bo_next = Q_NULLPTR; + m_gbm_bo_next = nullptr; + return; + } + + for (CloneDestination &d : m_cloneDests) { + if (d.screen != this) { + d.screen->ensureModeSet(fb->fb); + d.cloneFlipPending = true; + int ret = drmModePageFlip(fd, + d.screen->output().crtc_id, + fb->fb, + DRM_MODE_PAGE_FLIP_EVENT, + d.screen); + if (ret) { + qErrnoWarning("Could not queue DRM page flip for clone screen %s", qPrintable(name())); + d.cloneFlipPending = false; + } + } } } +void QEglFSKmsGbmScreen::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + Q_UNUSED(fd); + Q_UNUSED(sequence); + Q_UNUSED(tv_sec); + Q_UNUSED(tv_usec); + + QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(user_data); + screen->flipFinished(); +} + void QEglFSKmsGbmScreen::flipFinished() { + if (m_cloneSource) { + m_cloneSource->cloneDestFlipFinished(this); + return; + } + + m_flipPending = false; + updateFlipStatus(); +} + +void QEglFSKmsGbmScreen::cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScreen) +{ + for (CloneDestination &d : m_cloneDests) { + if (d.screen == cloneDestScreen) { + d.cloneFlipPending = false; + break; + } + } + updateFlipStatus(); +} + +void QEglFSKmsGbmScreen::updateFlipStatus() +{ + Q_ASSERT(!m_cloneSource); + + if (m_flipPending) + return; + + for (const CloneDestination &d : m_cloneDests) { + if (d.cloneFlipPending) + return; + } + if (m_gbm_bo_current) gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_current); m_gbm_bo_current = m_gbm_bo_next; - m_gbm_bo_next = Q_NULLPTR; + m_gbm_bo_next = nullptr; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h index 341cc95bbe..f5a2122723 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h @@ -54,34 +54,54 @@ class QEglFSKmsGbmCursor; class QEglFSKmsGbmScreen : public QEglFSKmsScreen { public: - QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output); + QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output, bool headless); ~QEglFSKmsGbmScreen(); QPlatformCursor *cursor() const override; - gbm_surface *surface() const { return m_gbm_surface; } gbm_surface *createSurface(); - void destroySurface(); + void resetSurface(); + + void initCloning(QPlatformScreen *screenThisScreenClones, + const QVector<QPlatformScreen *> &screensCloningThisScreen); void waitForFlip() override; - void flip() override; - void flipFinished() override; + + void flip(); private: + void flipFinished(); + void ensureModeSet(uint32_t fb); + void cloneDestFlipFinished(QEglFSKmsGbmScreen *cloneDestScreen); + void updateFlipStatus(); + + static void pageFlipHandler(int fd, + unsigned int sequence, + unsigned int tv_sec, + unsigned int tv_usec, + void *user_data); + gbm_surface *m_gbm_surface; gbm_bo *m_gbm_bo_current; gbm_bo *m_gbm_bo_next; + bool m_flipPending; QScopedPointer<QEglFSKmsGbmCursor> m_cursor; struct FrameBuffer { - FrameBuffer() : fb(0) {} - uint32_t fb; + uint32_t fb = 0; }; static void bufferDestroyedHandler(gbm_bo *bo, void *data); FrameBuffer *framebufferForBufferObject(gbm_bo *bo); + QEglFSKmsGbmScreen *m_cloneSource; + struct CloneDestination { + QEglFSKmsGbmScreen *screen = nullptr; + bool cloneFlipPending = false; + }; + QVector<CloneDestination> m_cloneDests; + static QMutex m_waitForFlipMutex; }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp new file mode 100644 index 0000000000..110a592dec --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfskmsgbmwindow.h" +#include "qeglfskmsgbmintegration.h" +#include "qeglfskmsgbmscreen.h" + +#include <QtEglSupport/private/qeglconvenience_p.h> + +QT_BEGIN_NAMESPACE + +void QEglFSKmsGbmWindow::resetSurface() +{ + QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen *>(screen()); + EGLDisplay display = gbmScreen->display(); + QSurfaceFormat platformFormat = m_integration->surfaceFormatFor(window()->requestedFormat()); + m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat); + m_format = q_glFormatFromConfig(display, m_config, platformFormat); + // One fullscreen window per screen -> the native window is simply the gbm_surface the screen created. + m_window = reinterpret_cast<EGLNativeWindowType>(gbmScreen->createSurface()); + + PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC createPlatformWindowSurface = nullptr; + const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + if (extensions && (strstr(extensions, "EGL_KHR_platform_gbm") || strstr(extensions, "EGL_MESA_platform_gbm"))) { + createPlatformWindowSurface = reinterpret_cast<PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC>( + eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT")); + } + + if (createPlatformWindowSurface) { + m_surface = createPlatformWindowSurface(display, m_config, reinterpret_cast<void *>(m_window), nullptr); + } else { + qCDebug(qLcEglfsKmsDebug, "No eglCreatePlatformWindowSurface for GBM, falling back to eglCreateWindowSurface"); + m_surface = eglCreateWindowSurface(display, m_config, m_window, nullptr); + } +} + +void QEglFSKmsGbmWindow::invalidateSurface() +{ + QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen *>(screen()); + QEglFSWindow::invalidateSurface(); + gbmScreen->resetSurface(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/accessible/comutils.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h index b1e6183a0f..a19cf7e8bc 100644 --- a/src/plugins/platforms/windows/accessible/comutils.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.h @@ -1,6 +1,8 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -36,29 +38,30 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef COMUTILS_H -#define COMUTILS_H -#if !defined(_WINDOWS_) && !defined(_WINDOWS_H) && !defined(__WINDOWS__) -#error Must include windows.h first! -#endif +#ifndef QEGLFSKMSGBMWINDOW_H +#define QEGLFSKMSGBMWINDOW_H -#include <ocidl.h> -#include <QtCore/qstring.h> +#include "private/qeglfswindow_p.h" QT_BEGIN_NAMESPACE -class QVariant; +class QEglFSKmsGbmIntegration; -// Originally QVariantToVARIANT copied from ActiveQt - renamed to avoid conflicts in static builds. -bool QVariant2VARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out); - -inline BSTR QStringToBSTR(const QString &str) +class QEglFSKmsGbmWindow : public QEglFSWindow { - return SysAllocStringLen(reinterpret_cast<const OLECHAR *>(str.unicode()), UINT(str.length())); -} +public: + QEglFSKmsGbmWindow(QWindow *w, const QEglFSKmsGbmIntegration *integration) + : QEglFSWindow(w), + m_integration(integration) + { } + void resetSurface() override; + void invalidateSurface() override; -QT_END_NAMESPACE +private: + const QEglFSKmsGbmIntegration *m_integration; +}; -#endif // COMUTILS_H +QT_END_NAMESPACE +#endif // QEGLFSKMSGBMWINDOW_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp index cca413ff2d..8c8e6260f1 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp @@ -58,7 +58,7 @@ bool QEglFSKmsEglDevice::open() { Q_ASSERT(fd() == -1); - int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR); + int fd = drmOpen(devicePath().toLocal8Bit().constData(), nullptr); if (Q_UNLIKELY(fd < 0)) qFatal("Could not open DRM (NV) device"); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index 3af21d768e..a67457a6a5 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration() : m_egl_device(EGL_NO_DEVICE_EXT) - , m_funcs(Q_NULLPTR) + , m_funcs(nullptr) { qCDebug(qLcEglfsKmsDebug, "New DRM/KMS on EGLDevice integration created"); } @@ -75,7 +75,7 @@ EGLDisplay QEglFSKmsEglDeviceIntegration::createDisplay(EGLNativeDisplayType nat EGLDisplay display; if (m_funcs->has_egl_platform_device) { - display = m_funcs->get_platform_display(EGL_PLATFORM_DEVICE_EXT, nativeDisplay, Q_NULLPTR); + display = m_funcs->get_platform_display(EGL_PLATFORM_DEVICE_EXT, nativeDisplay, nullptr); } else { qWarning("EGL_EXT_platform_device not available, falling back to legacy path!"); display = eglGetDisplay(nativeDisplay); @@ -162,7 +162,7 @@ void QEglFSKmsEglDeviceWindow::resetSurface() qCDebug(qLcEglfsKmsDebug, "Could not query number of EGLStream FIFO frames"); } - if (!m_integration->m_funcs->get_output_layers(display, Q_NULLPTR, Q_NULLPTR, 0, &count) || count == 0) { + if (!m_integration->m_funcs->get_output_layers(display, nullptr, nullptr, 0, &count) || count == 0) { qWarning("No output layers found"); return; } @@ -172,7 +172,7 @@ void QEglFSKmsEglDeviceWindow::resetSurface() QVector<EGLOutputLayerEXT> layers; layers.resize(count); EGLint actualCount; - if (!m_integration->m_funcs->get_output_layers(display, Q_NULLPTR, layers.data(), count, &actualCount)) { + if (!m_integration->m_funcs->get_output_layers(display, nullptr, layers.data(), count, &actualCount)) { qWarning("Failed to get layers"); return; } @@ -180,7 +180,7 @@ void QEglFSKmsEglDeviceWindow::resetSurface() QEglFSKmsEglDeviceScreen *cur_screen = static_cast<QEglFSKmsEglDeviceScreen *>(screen()); Q_ASSERT(cur_screen); QKmsOutput &output(cur_screen->output()); - const uint32_t wantedId = !output.wants_plane ? output.crtc_id : output.plane_id; + const uint32_t wantedId = !output.wants_forced_plane ? output.crtc_id : output.forced_plane_id; qCDebug(qLcEglfsKmsDebug, "Searching for id: %d", wantedId); EGLOutputLayerEXT layer = EGL_NO_OUTPUT_LAYER_EXT; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp index a27c89faab..531b73d1dc 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp @@ -105,12 +105,12 @@ void QEglFSKmsEglDeviceScreen::waitForFlip() qErrnoWarning(errno, "drmModeSetCrtc failed"); } - if (!op.plane_set) { - op.plane_set = true; + if (!op.forced_plane_set) { + op.forced_plane_set = true; - if (op.wants_plane) { - qCDebug(qLcEglfsKmsDebug, "Setting plane %u", op.plane_id); - int ret = drmModeSetPlane(fd, op.plane_id, op.crtc_id, uint32_t(-1), 0, + if (op.wants_forced_plane) { + qCDebug(qLcEglfsKmsDebug, "Setting plane %u", op.forced_plane_id); + int ret = drmModeSetPlane(fd, op.forced_plane_id, op.crtc_id, uint32_t(-1), 0, 0, 0, w, h, 0 << 16, 0 << 16, w << 16, h << 16); if (ret == -1) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp index c77151181e..975b1947bf 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(qLcEglfsKmsDebug, "qt.qpa.eglfs.kms") QEglFSKmsIntegration::QEglFSKmsIntegration() - : m_device(Q_NULLPTR), + : m_device(nullptr), m_screenConfig(new QKmsScreenConfig) { } @@ -78,7 +78,7 @@ void QEglFSKmsIntegration::platformDestroy() qCDebug(qLcEglfsKmsDebug, "platformDestroy: Closing DRM device"); m_device->close(); delete m_device; - m_device = Q_NULLPTR; + m_device = nullptr; } EGLNativeDisplayType QEglFSKmsIntegration::platformDisplay() const @@ -133,6 +133,14 @@ bool QEglFSKmsIntegration::supportsPBuffers() const return m_screenConfig->supportsPBuffers(); } +void *QEglFSKmsIntegration::nativeResourceForIntegration(const QByteArray &name) +{ + if (name == QByteArrayLiteral("dri_fd") && m_device) + return (void *) (qintptr) m_device->fd(); + + return nullptr; +} + QKmsDevice *QEglFSKmsIntegration::device() const { return m_device; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h index 9955616919..26ba2fdaec 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h @@ -69,6 +69,7 @@ public: bool hasCapability(QPlatformIntegration::Capability cap) const override; void waitForVSync(QPlatformSurface *surface) const override; bool supportsPBuffers() const override; + void *nativeResourceForIntegration(const QByteArray &name) override; QKmsDevice *device() const; QKmsScreenConfig *screenConfig() const; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp index 734f5cd611..5e45b42abe 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** +** Copyright (C) 2017 The Qt Company Ltd. ** Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** @@ -68,12 +68,13 @@ private: QEglFSKmsScreen *m_screen; }; -QEglFSKmsScreen::QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output) +QEglFSKmsScreen::QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output, bool headless) : QEglFSScreen(static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->display()) , m_device(device) , m_output(output) , m_powerState(PowerStateOn) , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) + , m_headless(headless) { m_siblings << this; // gets overridden later @@ -109,6 +110,9 @@ void QEglFSKmsScreen::setVirtualPosition(const QPoint &pos) // geometry() calls rawGeometry() and may apply additional transforms. QRect QEglFSKmsScreen::rawGeometry() const { + if (m_headless) + return QRect(QPoint(0, 0), m_device->screenConfig()->headlessSize()); + const int mode = m_output.mode; return QRect(m_pos.x(), m_pos.y(), m_output.modes[mode].hdisplay, @@ -117,12 +121,30 @@ QRect QEglFSKmsScreen::rawGeometry() const int QEglFSKmsScreen::depth() const { - return 32; + return format() == QImage::Format_RGB16 ? 16 : 32; } QImage::Format QEglFSKmsScreen::format() const { - return QImage::Format_RGB32; + // the result can be slightly incorrect, it won't matter in practice + switch (m_output.drm_format) { + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: + return QImage::Format_ARGB32; + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + return QImage::Format_RGB16; + case DRM_FORMAT_XRGB2101010: + return QImage::Format_RGB30; + case DRM_FORMAT_XBGR2101010: + return QImage::Format_BGR30; + case DRM_FORMAT_ARGB2101010: + return QImage::Format_A2RGB30_Premultiplied; + case DRM_FORMAT_ABGR2101010: + return QImage::Format_A2BGR30_Premultiplied; + default: + return QImage::Format_RGB32; + } } QSizeF QEglFSKmsScreen::physicalSize() const @@ -159,7 +181,7 @@ Qt::ScreenOrientation QEglFSKmsScreen::orientation() const QString QEglFSKmsScreen::name() const { - return m_output.name; + return !m_headless ? m_output.name : QStringLiteral("qt_Headless"); } QString QEglFSKmsScreen::manufacturer() const @@ -177,22 +199,10 @@ QString QEglFSKmsScreen::serialNumber() const return m_edid.serialNumber; } -void QEglFSKmsScreen::destroySurface() -{ -} - void QEglFSKmsScreen::waitForFlip() { } -void QEglFSKmsScreen::flip() -{ -} - -void QEglFSKmsScreen::flipFinished() -{ -} - void QEglFSKmsScreen::restoreMode() { m_output.restoreMode(m_device); @@ -200,6 +210,9 @@ void QEglFSKmsScreen::restoreMode() qreal QEglFSKmsScreen::refreshRate() const { + if (m_headless) + return 60; + quint32 refresh = m_output.modes[m_output.mode].vrefresh; return refresh > 0 ? refresh : 60; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h index 4e09929189..7f395aacb7 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h @@ -56,7 +56,7 @@ class QEglFSKmsInterruptHandler; class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen { public: - QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output); + QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output, bool headless = false); ~QEglFSKmsScreen(); void setVirtualPosition(const QPoint &pos); @@ -89,11 +89,7 @@ public: QKmsDevice *device() const { return m_device; } - void destroySurface(); - virtual void waitForFlip(); - virtual void flip(); - virtual void flipFinished(); QKmsOutput &output() { return m_output; } void restoreMode(); @@ -115,6 +111,8 @@ protected: PowerState m_powerState; QEglFSKmsInterruptHandler *m_interruptHandler; + + bool m_headless; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/haiku/main.cpp b/src/plugins/platforms/haiku/main.cpp index 02168d0165..841891970d 100644 --- a/src/plugins/platforms/haiku/main.cpp +++ b/src/plugins/platforms/haiku/main.cpp @@ -47,7 +47,7 @@ QPlatformIntegration *QHaikuIntegrationPlugin::create(const QString& system, con if (!system.compare(QLatin1String("haiku"), Qt::CaseInsensitive)) return new QHaikuIntegration(paramList); - return Q_NULLPTR; + return nullptr; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/haiku/main.h b/src/plugins/platforms/haiku/main.h index 82f3313652..e316b79d7c 100644 --- a/src/plugins/platforms/haiku/main.h +++ b/src/plugins/platforms/haiku/main.h @@ -47,7 +47,7 @@ class QHaikuIntegrationPlugin : public QPlatformIntegrationPlugin Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "haiku.json") public: - QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; + QPlatformIntegration *create(const QString&, const QStringList&) override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/haiku/qhaikuapplication.h b/src/plugins/platforms/haiku/qhaikuapplication.h index 0696df8109..a9ea442691 100644 --- a/src/plugins/platforms/haiku/qhaikuapplication.h +++ b/src/plugins/platforms/haiku/qhaikuapplication.h @@ -49,8 +49,8 @@ class QHaikuApplication : public BApplication public: explicit QHaikuApplication(const char *signature); - bool QuitRequested() Q_DECL_OVERRIDE; - void RefsReceived(BMessage* message) Q_DECL_OVERRIDE; + bool QuitRequested() override; + void RefsReceived(BMessage* message) override; }; #endif diff --git a/src/plugins/platforms/haiku/qhaikubuffer.cpp b/src/plugins/platforms/haiku/qhaikubuffer.cpp index c6f6ffe6bc..f25ddef86b 100644 --- a/src/plugins/platforms/haiku/qhaikubuffer.cpp +++ b/src/plugins/platforms/haiku/qhaikubuffer.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE QHaikuBuffer::QHaikuBuffer() - : m_buffer(Q_NULLPTR) + : m_buffer(nullptr) { } @@ -63,12 +63,12 @@ BBitmap* QHaikuBuffer::nativeBuffer() const const QImage *QHaikuBuffer::image() const { - return (m_buffer != Q_NULLPTR) ? &m_image : Q_NULLPTR; + return (m_buffer != nullptr) ? &m_image : nullptr; } QImage *QHaikuBuffer::image() { - return (m_buffer != Q_NULLPTR) ? &m_image : Q_NULLPTR; + return (m_buffer != nullptr) ? &m_image : nullptr; } QRect QHaikuBuffer::rect() const diff --git a/src/plugins/platforms/haiku/qhaikuclipboard.cpp b/src/plugins/platforms/haiku/qhaikuclipboard.cpp index 774da4432a..20519e21d0 100644 --- a/src/plugins/platforms/haiku/qhaikuclipboard.cpp +++ b/src/plugins/platforms/haiku/qhaikuclipboard.cpp @@ -47,8 +47,8 @@ #include <Clipboard.h> QHaikuClipboard::QHaikuClipboard() - : m_systemMimeData(Q_NULLPTR) - , m_userMimeData(Q_NULLPTR) + : m_systemMimeData(nullptr) + , m_userMimeData(nullptr) { if (be_clipboard) be_clipboard->StartWatching(BMessenger(this)); @@ -81,12 +81,12 @@ QMimeData *QHaikuClipboard::mimeData(QClipboard::Mode mode) const BMessage *clipboard = be_clipboard->Data(); if (clipboard) { - char *name = Q_NULLPTR; + char *name = nullptr; uint32 type = 0; int32 count = 0; for (int i = 0; clipboard->GetInfo(B_MIME_TYPE, i, &name, &type, &count) == B_OK; i++) { - const void *data = Q_NULLPTR; + const void *data = nullptr; int32 dataLen = 0; const status_t status = clipboard->FindData(name, B_MIME_TYPE, &data, &dataLen); @@ -162,7 +162,7 @@ void QHaikuClipboard::MessageReceived(BMessage* message) { if (message->what == B_CLIPBOARD_CHANGED) { delete m_userMimeData; - m_userMimeData = Q_NULLPTR; + m_userMimeData = nullptr; emitChanged(QClipboard::Clipboard); } diff --git a/src/plugins/platforms/haiku/qhaikuclipboard.h b/src/plugins/platforms/haiku/qhaikuclipboard.h index 3dd4496e8d..b6eb3f591f 100644 --- a/src/plugins/platforms/haiku/qhaikuclipboard.h +++ b/src/plugins/platforms/haiku/qhaikuclipboard.h @@ -54,13 +54,13 @@ public: QHaikuClipboard(); ~QHaikuClipboard(); - QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; - void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; - bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; - bool ownsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override; + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) override; + bool supportsMode(QClipboard::Mode mode) const override; + bool ownsMode(QClipboard::Mode mode) const override; // override from BHandler to catch change notifications from Haiku clipboard - void MessageReceived(BMessage* message) Q_DECL_OVERRIDE; + void MessageReceived(BMessage* message) override; private: QMimeData *m_systemMimeData; diff --git a/src/plugins/platforms/haiku/qhaikucursor.h b/src/plugins/platforms/haiku/qhaikucursor.h index 5d70c97d9e..73a1d2c492 100644 --- a/src/plugins/platforms/haiku/qhaikucursor.h +++ b/src/plugins/platforms/haiku/qhaikucursor.h @@ -52,7 +52,7 @@ public: QHaikuCursor(); #ifndef QT_NO_CURSOR - void changeCursor(QCursor *windowCursor, QWindow *window) Q_DECL_OVERRIDE; + void changeCursor(QCursor *windowCursor, QWindow *window) override; #endif private: diff --git a/src/plugins/platforms/haiku/qhaikuintegration.cpp b/src/plugins/platforms/haiku/qhaikuintegration.cpp index d46d77ff18..8bd2171794 100644 --- a/src/plugins/platforms/haiku/qhaikuintegration.cpp +++ b/src/plugins/platforms/haiku/qhaikuintegration.cpp @@ -87,13 +87,13 @@ QHaikuIntegration::QHaikuIntegration(const QStringList ¶meters) QHaikuIntegration::~QHaikuIntegration() { destroyScreen(m_screen); - m_screen = Q_NULLPTR; + m_screen = nullptr; delete m_services; - m_services = Q_NULLPTR; + m_services = nullptr; delete m_clipboard; - m_clipboard = Q_NULLPTR; + m_clipboard = nullptr; be_app->LockLooper(); be_app->Quit(); diff --git a/src/plugins/platforms/haiku/qhaikuintegration.h b/src/plugins/platforms/haiku/qhaikuintegration.h index 1b938acb82..5c7a173c91 100644 --- a/src/plugins/platforms/haiku/qhaikuintegration.h +++ b/src/plugins/platforms/haiku/qhaikuintegration.h @@ -54,17 +54,17 @@ public: explicit QHaikuIntegration(const QStringList ¶mList); ~QHaikuIntegration(); - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const override; - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; + QAbstractEventDispatcher *createEventDispatcher() const override; - QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; - QPlatformServices *services() const Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const override; + QPlatformServices *services() const override; #ifndef QT_NO_CLIPBOARD - QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE; + QPlatformClipboard *clipboard() const override; #endif private: diff --git a/src/plugins/platforms/haiku/qhaikurasterbackingstore.cpp b/src/plugins/platforms/haiku/qhaikurasterbackingstore.cpp index ee53f693cd..613ae471cb 100644 --- a/src/plugins/platforms/haiku/qhaikurasterbackingstore.cpp +++ b/src/plugins/platforms/haiku/qhaikurasterbackingstore.cpp @@ -47,14 +47,14 @@ QT_BEGIN_NAMESPACE QHaikuRasterBackingStore::QHaikuRasterBackingStore(QWindow *window) : QPlatformBackingStore(window) - , m_bitmap(Q_NULLPTR) + , m_bitmap(nullptr) { } QHaikuRasterBackingStore::~QHaikuRasterBackingStore() { delete m_bitmap; - m_bitmap = Q_NULLPTR; + m_bitmap = nullptr; } QPaintDevice *QHaikuRasterBackingStore::paintDevice() @@ -62,7 +62,7 @@ QPaintDevice *QHaikuRasterBackingStore::paintDevice() if (!m_bufferSize.isEmpty() && m_bitmap) return m_buffer.image(); - return Q_NULLPTR; + return nullptr; } void QHaikuRasterBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) diff --git a/src/plugins/platforms/haiku/qhaikurasterbackingstore.h b/src/plugins/platforms/haiku/qhaikurasterbackingstore.h index 06a46e7eb3..060ab27126 100644 --- a/src/plugins/platforms/haiku/qhaikurasterbackingstore.h +++ b/src/plugins/platforms/haiku/qhaikurasterbackingstore.h @@ -55,9 +55,9 @@ public: explicit QHaikuRasterBackingStore(QWindow *window); ~QHaikuRasterBackingStore(); - QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; - void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE; + QPaintDevice *paintDevice() override; + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) override; + void resize(const QSize &size, const QRegion &staticContents) override; private: BBitmap *m_bitmap; diff --git a/src/plugins/platforms/haiku/qhaikurasterwindow.cpp b/src/plugins/platforms/haiku/qhaikurasterwindow.cpp index 9834b7cbc7..7e57e67bab 100644 --- a/src/plugins/platforms/haiku/qhaikurasterwindow.cpp +++ b/src/plugins/platforms/haiku/qhaikurasterwindow.cpp @@ -211,7 +211,7 @@ void HaikuViewProxy::handleKeyEvent(QEvent::Type type, BMessage *message) { int32 key = 0; uint32 code = 0; - const char *bytes = Q_NULLPTR; + const char *bytes = nullptr; QString text; if (message) { @@ -265,7 +265,7 @@ QHaikuRasterWindow::~QHaikuRasterWindow() m_window->UnlockLooper(); delete m_view; - m_view = Q_NULLPTR; + m_view = nullptr; } BView* QHaikuRasterWindow::nativeViewHandle() const diff --git a/src/plugins/platforms/haiku/qhaikurasterwindow.h b/src/plugins/platforms/haiku/qhaikurasterwindow.h index ae57e0f0e4..24b13aa122 100644 --- a/src/plugins/platforms/haiku/qhaikurasterwindow.h +++ b/src/plugins/platforms/haiku/qhaikurasterwindow.h @@ -51,15 +51,15 @@ class HaikuViewProxy : public QObject, public BView Q_OBJECT public: - explicit HaikuViewProxy(BWindow *window, QObject *parent = Q_NULLPTR); + explicit HaikuViewProxy(BWindow *window, QObject *parent = nullptr); - void MessageReceived(BMessage *message) Q_DECL_OVERRIDE; - void Draw(BRect updateRect) Q_DECL_OVERRIDE; - void MouseDown(BPoint pos) Q_DECL_OVERRIDE; - void MouseUp(BPoint pos) Q_DECL_OVERRIDE; - void MouseMoved(BPoint pos, uint32 code, const BMessage *dragMessage) Q_DECL_OVERRIDE; - void KeyDown(const char *bytes, int32 numBytes) Q_DECL_OVERRIDE; - void KeyUp(const char *bytes, int32 numBytes) Q_DECL_OVERRIDE; + void MessageReceived(BMessage *message) override; + void Draw(BRect updateRect) override; + void MouseDown(BPoint pos) override; + void MouseUp(BPoint pos) override; + void MouseMoved(BPoint pos, uint32 code, const BMessage *dragMessage) override; + void KeyDown(const char *bytes, int32 numBytes) override; + void KeyUp(const char *bytes, int32 numBytes) override; Q_SIGNALS: void mouseEvent(const QPoint &localPosition, const QPoint &globalPosition, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source); diff --git a/src/plugins/platforms/haiku/qhaikuscreen.cpp b/src/plugins/platforms/haiku/qhaikuscreen.cpp index 54951a0af5..2c8abba8aa 100644 --- a/src/plugins/platforms/haiku/qhaikuscreen.cpp +++ b/src/plugins/platforms/haiku/qhaikuscreen.cpp @@ -58,10 +58,10 @@ QHaikuScreen::QHaikuScreen() QHaikuScreen::~QHaikuScreen() { delete m_cursor; - m_cursor = Q_NULLPTR; + m_cursor = nullptr; delete m_screen; - m_screen = Q_NULLPTR; + m_screen = nullptr; } QPixmap QHaikuScreen::grabWindow(WId winId, int x, int y, int width, int height) const @@ -69,8 +69,8 @@ QPixmap QHaikuScreen::grabWindow(WId winId, int x, int y, int width, int height) if (width == 0 || height == 0) return QPixmap(); - BScreen screen(Q_NULLPTR); - BBitmap *bitmap = Q_NULLPTR; + BScreen screen(nullptr); + BBitmap *bitmap = nullptr; screen.GetBitmap(&bitmap); const BRect frame = (winId ? ((BWindow*)winId)->Frame() : screen.Frame()); diff --git a/src/plugins/platforms/haiku/qhaikuscreen.h b/src/plugins/platforms/haiku/qhaikuscreen.h index 49fa3f0a60..98de6fdd03 100644 --- a/src/plugins/platforms/haiku/qhaikuscreen.h +++ b/src/plugins/platforms/haiku/qhaikuscreen.h @@ -53,13 +53,13 @@ public: QHaikuScreen(); ~QHaikuScreen(); - QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + QPixmap grabWindow(WId window, int x, int y, int width, int height) const override; - QRect geometry() const Q_DECL_OVERRIDE; - int depth() const Q_DECL_OVERRIDE; - QImage::Format format() const Q_DECL_OVERRIDE; + QRect geometry() const override; + int depth() const override; + QImage::Format format() const override; - QPlatformCursor *cursor() const Q_DECL_OVERRIDE; + QPlatformCursor *cursor() const override; private: BScreen *m_screen; diff --git a/src/plugins/platforms/haiku/qhaikuservices.h b/src/plugins/platforms/haiku/qhaikuservices.h index a210eb8b61..59ff6395fb 100644 --- a/src/plugins/platforms/haiku/qhaikuservices.h +++ b/src/plugins/platforms/haiku/qhaikuservices.h @@ -47,10 +47,10 @@ QT_BEGIN_NAMESPACE class QHaikuServices : public QPlatformServices { public: - bool openUrl(const QUrl &url) Q_DECL_OVERRIDE; - bool openDocument(const QUrl &url) Q_DECL_OVERRIDE; + bool openUrl(const QUrl &url) override; + bool openDocument(const QUrl &url) override; - QByteArray desktopEnvironment() const Q_DECL_OVERRIDE; + QByteArray desktopEnvironment() const override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/haiku/qhaikuwindow.cpp b/src/plugins/platforms/haiku/qhaikuwindow.cpp index 4bea7f7ff6..f8fdf3f92d 100644 --- a/src/plugins/platforms/haiku/qhaikuwindow.cpp +++ b/src/plugins/platforms/haiku/qhaikuwindow.cpp @@ -118,12 +118,12 @@ void HaikuWindowProxy::zoomByQt() QHaikuWindow::QHaikuWindow(QWindow *window) : QPlatformWindow(window) - , m_window(Q_NULLPTR) + , m_window(nullptr) , m_windowState(Qt::WindowNoState) { const QRect rect = initialGeometry(window, window->geometry(), DefaultWindowWidth, DefaultWindowHeight); - HaikuWindowProxy *haikuWindow = new HaikuWindowProxy(window, rect, Q_NULLPTR); + HaikuWindowProxy *haikuWindow = new HaikuWindowProxy(window, rect, nullptr); connect(haikuWindow, SIGNAL(moved(QPoint)), SLOT(haikuWindowMoved(QPoint))); connect(haikuWindow, SIGNAL(resized(QSize,bool)), SLOT(haikuWindowResized(QSize,bool))); connect(haikuWindow, SIGNAL(windowActivated(bool)), SLOT(haikuWindowActivated(bool))); @@ -145,7 +145,7 @@ QHaikuWindow::~QHaikuWindow() m_window->LockLooper(); m_window->Quit(); - m_window = Q_NULLPTR; + m_window = nullptr; } void QHaikuWindow::setGeometry(const QRect &rect) @@ -330,7 +330,7 @@ void QHaikuWindow::haikuWindowResized(const QSize &size, bool zoomInProgress) void QHaikuWindow::haikuWindowActivated(bool activated) { - QWindowSystemInterface::handleWindowActivated(activated ? window() : Q_NULLPTR); + QWindowSystemInterface::handleWindowActivated(activated ? window() : nullptr); } void QHaikuWindow::haikuWindowMinimized(bool minimize) diff --git a/src/plugins/platforms/haiku/qhaikuwindow.h b/src/plugins/platforms/haiku/qhaikuwindow.h index 5bfb99e532..bb57742087 100644 --- a/src/plugins/platforms/haiku/qhaikuwindow.h +++ b/src/plugins/platforms/haiku/qhaikuwindow.h @@ -51,14 +51,14 @@ class HaikuWindowProxy : public QObject, public BWindow Q_OBJECT public: - explicit HaikuWindowProxy(QWindow *window, const QRect &rect, QObject *parent = Q_NULLPTR); + explicit HaikuWindowProxy(QWindow *window, const QRect &rect, QObject *parent = nullptr); - void FrameMoved(BPoint pos) Q_DECL_OVERRIDE; - void FrameResized(float width, float height) Q_DECL_OVERRIDE; - void WindowActivated(bool activated) Q_DECL_OVERRIDE; - void Minimize(bool minimize) Q_DECL_OVERRIDE; - void Zoom(BPoint pos, float width, float height) Q_DECL_OVERRIDE; - bool QuitRequested() Q_DECL_OVERRIDE; + void FrameMoved(BPoint pos) override; + void FrameResized(float width, float height) override; + void WindowActivated(bool activated) override; + void Minimize(bool minimize) override; + void Zoom(BPoint pos, float width, float height) override; + bool QuitRequested() override; void zoomByQt(); @@ -83,23 +83,23 @@ public: explicit QHaikuWindow(QWindow *window); virtual ~QHaikuWindow(); - void setGeometry(const QRect &rect) Q_DECL_OVERRIDE; - QMargins frameMargins() const Q_DECL_OVERRIDE; - void setVisible(bool visible) Q_DECL_OVERRIDE; + void setGeometry(const QRect &rect) override; + QMargins frameMargins() const override; + void setVisible(bool visible) override; - bool isExposed() const Q_DECL_OVERRIDE; - bool isActive() const Q_DECL_OVERRIDE; + bool isExposed() const override; + bool isActive() const override; - WId winId() const Q_DECL_OVERRIDE; + WId winId() const override; BWindow* nativeHandle() const; - void requestActivateWindow() Q_DECL_OVERRIDE; - void setWindowState(Qt::WindowStates state) Q_DECL_OVERRIDE; - void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE; + void requestActivateWindow() override; + void setWindowState(Qt::WindowStates state) override; + void setWindowFlags(Qt::WindowFlags flags) override; - void setWindowTitle(const QString &title) Q_DECL_OVERRIDE; + void setWindowTitle(const QString &title) override; - void propagateSizeHints() Q_DECL_OVERRIDE; + void propagateSizeHints() override; protected: HaikuWindowProxy *m_window; diff --git a/src/plugins/platforms/integrity/main.cpp b/src/plugins/platforms/integrity/main.cpp index f75e227335..6313aa47e5 100644 --- a/src/plugins/platforms/integrity/main.cpp +++ b/src/plugins/platforms/integrity/main.cpp @@ -47,7 +47,7 @@ class QIntegrityFbIntegrationPlugin : public QPlatformIntegrationPlugin Q_OBJECT Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "integrity.json") public: - QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; + QPlatformIntegration *create(const QString&, const QStringList&) override; }; QPlatformIntegration* QIntegrityFbIntegrationPlugin::create(const QString& system, const QStringList& paramList) diff --git a/src/plugins/platforms/integrity/qintegrityfbintegration.h b/src/plugins/platforms/integrity/qintegrityfbintegration.h index a954dc2356..d0cd5417ab 100644 --- a/src/plugins/platforms/integrity/qintegrityfbintegration.h +++ b/src/plugins/platforms/integrity/qintegrityfbintegration.h @@ -54,19 +54,19 @@ public: QIntegrityFbIntegration(const QStringList ¶mList); ~QIntegrityFbIntegration(); - void initialize() Q_DECL_OVERRIDE; - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + void initialize() override; + bool hasCapability(QPlatformIntegration::Capability cap) const override; - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const override; - QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; - QPlatformServices *services() const Q_DECL_OVERRIDE; - QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; } + QPlatformFontDatabase *fontDatabase() const override; + QPlatformServices *services() const override; + QPlatformInputContext *inputContext() const override { return m_inputContext; } - QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; + QPlatformNativeInterface *nativeInterface() const override; QList<QPlatformScreen *> screens() const; diff --git a/src/plugins/platforms/integrity/qintegrityfbscreen.h b/src/plugins/platforms/integrity/qintegrityfbscreen.h index 6bc78913c9..c38b4f073d 100644 --- a/src/plugins/platforms/integrity/qintegrityfbscreen.h +++ b/src/plugins/platforms/integrity/qintegrityfbscreen.h @@ -57,9 +57,9 @@ public: bool initialize(); - QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override; - QRegion doRedraw() Q_DECL_OVERRIDE; + QRegion doRedraw() override; private: QStringList mArgs; diff --git a/src/plugins/platforms/integrity/qintegrityhidmanager.cpp b/src/plugins/platforms/integrity/qintegrityhidmanager.cpp index 49583735f5..3570b90134 100644 --- a/src/plugins/platforms/integrity/qintegrityhidmanager.cpp +++ b/src/plugins/platforms/integrity/qintegrityhidmanager.cpp @@ -73,8 +73,8 @@ public: { CheckSuccess(gh_hid_close(handle)); }; - void process_event(void) Q_DECL_OVERRIDE; - void async_wait(void) Q_DECL_OVERRIDE; + void process_event(void) override; + void async_wait(void) override; HIDDriver *get_driver(void) { return driver; }; HIDHandle get_handle(void) { return handle; }; private: @@ -92,8 +92,8 @@ public: { qDeleteAll(devices); }; - void process_event(void) Q_DECL_OVERRIDE; - void async_wait(void) Q_DECL_OVERRIDE; + void process_event(void) override; + void async_wait(void) override; void find_devices(void); private: QHash<Value, HIDDeviceHandler *> devices; diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm index bea2897240..54152aebf7 100644 --- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm @@ -302,7 +302,7 @@ public: g_iteratorCurrentUrl.setLocalData(QString()); } - QString next() Q_DECL_OVERRIDE + QString next() override { // Cache the URL that we are about to return, since QDir will immediately create a // new file engine on the file and ask if it exists. Unless we do this, we end up @@ -314,17 +314,17 @@ public: return url; } - bool hasNext() const Q_DECL_OVERRIDE + bool hasNext() const override { return m_enumerator->hasNext(); } - QString currentFileName() const Q_DECL_OVERRIDE + QString currentFileName() const override { return g_iteratorCurrentUrl.localData(); } - QFileInfo currentFileInfo() const Q_DECL_OVERRIDE + QFileInfo currentFileInfo() const override { return QFileInfo(currentFileName()); } diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h index e6b890251a..38006ba90b 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.h +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -54,7 +54,7 @@ public: QIOSBackingStore(QWindow *window); ~QIOSBackingStore(); - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosclipboard.h b/src/plugins/platforms/ios/qiosclipboard.h index f3ccfcace0..3fe9b29b71 100644 --- a/src/plugins/platforms/ios/qiosclipboard.h +++ b/src/plugins/platforms/ios/qiosclipboard.h @@ -58,10 +58,10 @@ public: QIOSClipboard(); ~QIOSClipboard(); - QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; - void setMimeData(QMimeData *mimeData, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; - bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; - bool ownsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override; + void setMimeData(QMimeData *mimeData, QClipboard::Mode mode = QClipboard::Clipboard) override; + bool supportsMode(QClipboard::Mode mode) const override; + bool ownsMode(QClipboard::Mode mode) const override; private: QUIClipboard *m_clipboard; diff --git a/src/plugins/platforms/ios/qiosclipboard.mm b/src/plugins/platforms/ios/qiosclipboard.mm index 15deb3332e..9a975eadc9 100644 --- a/src/plugins/platforms/ios/qiosclipboard.mm +++ b/src/plugins/platforms/ios/qiosclipboard.mm @@ -138,8 +138,8 @@ public: QIOSMimeData(QClipboard::Mode mode) : QMimeData(), m_mode(mode) { } ~QIOSMimeData() { } - QStringList formats() const Q_DECL_OVERRIDE; - QVariant retrieveData(const QString &mimeType, QVariant::Type type) const Q_DECL_OVERRIDE; + QStringList formats() const override; + QVariant retrieveData(const QString &mimeType, QVariant::Type type) const override; private: const QClipboard::Mode m_mode; diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index 5b7917f7b4..7539e981c0 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -57,18 +57,18 @@ public: QIOSContext(QOpenGLContext *context); ~QIOSContext(); - QSurfaceFormat format() const Q_DECL_OVERRIDE; + QSurfaceFormat format() const override; - void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; + void swapBuffers(QPlatformSurface *surface) override; - bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE; - void doneCurrent() Q_DECL_OVERRIDE; + bool makeCurrent(QPlatformSurface *surface) override; + void doneCurrent() override; - GLuint defaultFramebufferObject(QPlatformSurface *) const Q_DECL_OVERRIDE; - QFunctionPointer getProcAddress(const char *procName) Q_DECL_OVERRIDE; + GLuint defaultFramebufferObject(QPlatformSurface *) const override; + QFunctionPointer getProcAddress(const char *procName) override; - bool isSharing() const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; + bool isSharing() const override; + bool isValid() const override; private Q_SLOTS: void windowDestroyed(QObject *object); diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index c1442ed1e8..62133b9510 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -51,8 +51,8 @@ class QIOSEventDispatcher : public QEventDispatcherCoreFoundation public: explicit QIOSEventDispatcher(QObject *parent = 0); - bool processEvents(QEventLoop::ProcessEventsFlags flags) Q_DECL_OVERRIDE; - bool processPostedEvents() Q_DECL_OVERRIDE; + bool processEvents(QEventLoop::ProcessEventsFlags flags) override; + bool processPostedEvents() override; void handleRunLoopExit(CFRunLoopActivity activity); diff --git a/src/plugins/platforms/ios/qiosfiledialog.h b/src/plugins/platforms/ios/qiosfiledialog.h index 0b56bd20bf..5cb1b45e20 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.h +++ b/src/plugins/platforms/ios/qiosfiledialog.h @@ -53,17 +53,17 @@ public: QIOSFileDialog(); ~QIOSFileDialog(); - void exec() Q_DECL_OVERRIDE; - bool defaultNameFilterDisables() const Q_DECL_OVERRIDE { return false; } - bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE; - void hide() Q_DECL_OVERRIDE; - void setDirectory(const QUrl &) Q_DECL_OVERRIDE {} - QUrl directory() const Q_DECL_OVERRIDE { return QUrl(); } - void selectFile(const QUrl &) Q_DECL_OVERRIDE {} - QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE; - void setFilter() Q_DECL_OVERRIDE {} - void selectNameFilter(const QString &) Q_DECL_OVERRIDE {} - QString selectedNameFilter() const Q_DECL_OVERRIDE { return QString(); } + void exec() override; + bool defaultNameFilterDisables() const override { return false; } + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override; + void hide() override; + void setDirectory(const QUrl &) override {} + QUrl directory() const override { return QUrl(); } + void selectFile(const QUrl &) override {} + QList<QUrl> selectedFiles() const override; + void setFilter() override {} + void selectNameFilter(const QString &) override {} + QString selectedNameFilter() const override { return QString(); } void selectedFilesChanged(QList<QUrl> selection); diff --git a/src/plugins/platforms/ios/qiosfiledialog.mm b/src/plugins/platforms/ios/qiosfiledialog.mm index c5722d33f8..5987bc1540 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.mm +++ b/src/plugins/platforms/ios/qiosfiledialog.mm @@ -48,7 +48,7 @@ #include "qiosoptionalplugininterface.h" QIOSFileDialog::QIOSFileDialog() - : m_viewController(Q_NULLPTR) + : m_viewController(nullptr) { } @@ -112,7 +112,7 @@ void QIOSFileDialog::hide() [m_viewController dismissViewControllerAnimated:YES completion:nil]; [m_viewController release]; - m_viewController = Q_NULLPTR; + m_viewController = nullptr; m_eventLoop.exit(); } diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 966d1a7e80..255cf8bca9 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -88,24 +88,24 @@ public: QIOSInputContext(); ~QIOSInputContext(); - bool isValid() const Q_DECL_OVERRIDE { return true; } + bool isValid() const override { return true; } - void showInputPanel() Q_DECL_OVERRIDE; - void hideInputPanel() Q_DECL_OVERRIDE; + void showInputPanel() override; + void hideInputPanel() override; - bool isInputPanelVisible() const Q_DECL_OVERRIDE; - bool isAnimating() const Q_DECL_OVERRIDE; - QRectF keyboardRect() const Q_DECL_OVERRIDE; + bool isInputPanelVisible() const override; + bool isAnimating() const override; + QRectF keyboardRect() const override; - void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; - void reset() Q_DECL_OVERRIDE; - void commit() Q_DECL_OVERRIDE; + void update(Qt::InputMethodQueries) override; + void reset() override; + void commit() override; - QLocale locale() const Q_DECL_OVERRIDE; + QLocale locale() const override; void clearCurrentFocusObject(); - void setFocusObject(QObject *object) Q_DECL_OVERRIDE; + void setFocusObject(QObject *object) override; void focusWindowChanged(QWindow *focusWindow); void scrollToCursor(); diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 54c1a1dcb7..19fe93da30 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -64,45 +64,45 @@ public: QIOSIntegration(); ~QIOSIntegration(); - bool hasCapability(Capability cap) const Q_DECL_OVERRIDE; + bool hasCapability(Capability cap) const override; - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; - QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; + QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; - QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const override; #ifndef QT_NO_CLIPBOARD - QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE; + QPlatformClipboard *clipboard() const override; #endif - QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE; - QPlatformServices *services() const Q_DECL_OVERRIDE; + QPlatformInputContext *inputContext() const override; + QPlatformServices *services() const override; - QVariant styleHint(StyleHint hint) const Q_DECL_OVERRIDE; + QVariant styleHint(StyleHint hint) const override; - QStringList themeNames() const Q_DECL_OVERRIDE; - QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE; + QStringList themeNames() const override; + QPlatformTheme *createPlatformTheme(const QString &name) const override; - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; - QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const override; + QPlatformNativeInterface *nativeInterface() const override; QTouchDevice *touchDevice(); #ifndef QT_NO_ACCESSIBILITY - QPlatformAccessibility *accessibility() const Q_DECL_OVERRIDE; + QPlatformAccessibility *accessibility() const override; #endif // Called from Objective-C class QIOSScreenTracker, which can't be friended void addScreen(QPlatformScreen *screen) { screenAdded(screen); } void destroyScreen(QPlatformScreen *screen) { QPlatformIntegration::destroyScreen(screen); } - void beep() const Q_DECL_OVERRIDE; + void beep() const override; static QIOSIntegration *instance(); // -- QPlatformNativeInterface -- - void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE; + void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override; void setDebugWindowManagement(bool); bool debugWindowManagement() const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 5f114d4762..0e4bc62227 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -123,6 +123,9 @@ QIOSIntegration::QIOSIntegration() } m_touchDevice->setCapabilities(touchCapabilities); QWindowSystemInterface::registerTouchDevice(m_touchDevice); +#if QT_CONFIG(tabletevent) + QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); +#endif QMacInternalPasteboardMime::initializeMimeTypes(); for (int i = 0; i < m_optionalPlugins->metaData().size(); ++i) @@ -201,12 +204,12 @@ class QIOSOffscreenSurface : public QPlatformOffscreenSurface public: QIOSOffscreenSurface(QOffscreenSurface *offscreenSurface) : QPlatformOffscreenSurface(offscreenSurface) {} - QSurfaceFormat format() const Q_DECL_OVERRIDE + QSurfaceFormat format() const override { Q_ASSERT(offscreenSurface()); return offscreenSurface()->requestedFormat(); } - bool isValid() const Q_DECL_OVERRIDE { return true; } + bool isValid() const override { return true; } }; QPlatformOffscreenSurface *QIOSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const diff --git a/src/plugins/platforms/ios/qiosmenu.h b/src/plugins/platforms/ios/qiosmenu.h index 61cadab56d..32022a3bb8 100644 --- a/src/plugins/platforms/ios/qiosmenu.h +++ b/src/plugins/platforms/ios/qiosmenu.h @@ -56,20 +56,20 @@ class QIOSMenuItem : public QPlatformMenuItem public: QIOSMenuItem(); - void setText(const QString &text) Q_DECL_OVERRIDE; - void setIcon(const QIcon &) Q_DECL_OVERRIDE {} - void setMenu(QPlatformMenu *) Q_DECL_OVERRIDE; - void setVisible(bool isVisible) Q_DECL_OVERRIDE; - void setIsSeparator(bool) Q_DECL_OVERRIDE; - void setFont(const QFont &) Q_DECL_OVERRIDE {} - void setRole(MenuRole role) Q_DECL_OVERRIDE; - void setCheckable(bool) Q_DECL_OVERRIDE {} - void setChecked(bool) Q_DECL_OVERRIDE {} + void setText(const QString &text) override; + void setIcon(const QIcon &) override {} + void setMenu(QPlatformMenu *) override; + void setVisible(bool isVisible) override; + void setIsSeparator(bool) override; + void setFont(const QFont &) override {} + void setRole(MenuRole role) override; + void setCheckable(bool) override {} + void setChecked(bool) override {} #ifndef QT_NO_SHORTCUT - void setShortcut(const QKeySequence&) Q_DECL_OVERRIDE; + void setShortcut(const QKeySequence&) override; #endif - void setEnabled(bool enabled) Q_DECL_OVERRIDE; - void setIconSize(int) Q_DECL_OVERRIDE {} + void setEnabled(bool enabled) override; + void setIconSize(int) override {} bool m_visible; QString m_text; @@ -88,22 +88,22 @@ public: QIOSMenu(); ~QIOSMenu(); - void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) Q_DECL_OVERRIDE; - void removeMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; - void syncMenuItem(QPlatformMenuItem *) Q_DECL_OVERRIDE; - void syncSeparatorsCollapsible(bool) Q_DECL_OVERRIDE {} + void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) override; + void removeMenuItem(QPlatformMenuItem *menuItem) override; + void syncMenuItem(QPlatformMenuItem *) override; + void syncSeparatorsCollapsible(bool) override {} - void setText(const QString &) Q_DECL_OVERRIDE; - void setIcon(const QIcon &) Q_DECL_OVERRIDE {} - void setEnabled(bool enabled) Q_DECL_OVERRIDE; - void setVisible(bool visible) Q_DECL_OVERRIDE; - void setMenuType(MenuType type) Q_DECL_OVERRIDE; + void setText(const QString &) override; + void setIcon(const QIcon &) override {} + void setEnabled(bool enabled) override; + void setVisible(bool visible) override; + void setMenuType(MenuType type) override; - void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE; - void dismiss() Q_DECL_OVERRIDE; + void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) override; + void dismiss() override; - QPlatformMenuItem *menuItemAt(int position) const Q_DECL_OVERRIDE; - QPlatformMenuItem *menuItemForTag(quintptr tag) const Q_DECL_OVERRIDE; + QPlatformMenuItem *menuItemAt(int position) const override; + QPlatformMenuItem *menuItemForTag(quintptr tag) const override; void handleItemSelected(QIOSMenuItem *menuItem); @@ -111,7 +111,7 @@ public: static id menuActionTarget() { return m_currentMenu ? m_currentMenu->m_menuController : 0; } protected: - bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; + bool eventFilter(QObject *obj, QEvent *event) override; private: bool m_enabled; diff --git a/src/plugins/platforms/ios/qiosmessagedialog.h b/src/plugins/platforms/ios/qiosmessagedialog.h index e67e10a5e1..92a4db8319 100644 --- a/src/plugins/platforms/ios/qiosmessagedialog.h +++ b/src/plugins/platforms/ios/qiosmessagedialog.h @@ -54,9 +54,9 @@ public: QIOSMessageDialog(); ~QIOSMessageDialog(); - void exec() Q_DECL_OVERRIDE; - bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE; - void hide() Q_DECL_OVERRIDE; + void exec() override; + bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override; + void hide() override; private: QEventLoop m_eventLoop; diff --git a/src/plugins/platforms/ios/qiosmessagedialog.mm b/src/plugins/platforms/ios/qiosmessagedialog.mm index 5507f13de7..9d05b792c2 100644 --- a/src/plugins/platforms/ios/qiosmessagedialog.mm +++ b/src/plugins/platforms/ios/qiosmessagedialog.mm @@ -48,7 +48,7 @@ #include "qiosmessagedialog.h" QIOSMessageDialog::QIOSMessageDialog() - : m_alertController(Q_NULLPTR) + : m_alertController(nullptr) { } @@ -136,5 +136,5 @@ void QIOSMessageDialog::hide() m_eventLoop.exit(); [m_alertController dismissViewControllerAnimated:YES completion:nil]; [m_alertController release]; - m_alertController = Q_NULLPTR; + m_alertController = nullptr; } diff --git a/src/plugins/platforms/ios/qiosoptionalplugininterface.h b/src/plugins/platforms/ios/qiosoptionalplugininterface.h index 3f74e41c83..660c74e856 100644 --- a/src/plugins/platforms/ios/qiosoptionalplugininterface.h +++ b/src/plugins/platforms/ios/qiosoptionalplugininterface.h @@ -55,7 +55,7 @@ class QIosOptionalPluginInterface public: virtual ~QIosOptionalPluginInterface() {} virtual void initPlugin() const {}; - virtual UIViewController* createImagePickerController(QIOSFileDialog *) const { return Q_NULLPTR; }; + virtual UIViewController* createImagePickerController(QIOSFileDialog *) const { return nullptr; }; }; Q_DECLARE_INTERFACE(QIosOptionalPluginInterface, QIosOptionalPluginInterface_iid) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 9fcce42825..329fb1f9e2 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -56,17 +56,17 @@ public: QIOSScreen(UIScreen *screen); ~QIOSScreen(); - QRect geometry() const Q_DECL_OVERRIDE; - QRect availableGeometry() const Q_DECL_OVERRIDE; - int depth() const Q_DECL_OVERRIDE; - QImage::Format format() const Q_DECL_OVERRIDE; - QSizeF physicalSize() const Q_DECL_OVERRIDE; - QDpi logicalDpi() const Q_DECL_OVERRIDE; - qreal devicePixelRatio() const Q_DECL_OVERRIDE; - - Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE; - Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE; - void setOrientationUpdateMask(Qt::ScreenOrientations mask) Q_DECL_OVERRIDE; + QRect geometry() const override; + QRect availableGeometry() const override; + int depth() const override; + QImage::Format format() const override; + QSizeF physicalSize() const override; + QDpi logicalDpi() const override; + qreal devicePixelRatio() const override; + + Qt::ScreenOrientation nativeOrientation() const override; + Qt::ScreenOrientation orientation() const override; + void setOrientationUpdateMask(Qt::ScreenOrientations mask) override; QPixmap grabWindow(WId window, int x, int y, int width, int height) const override; diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.mm b/src/plugins/platforms/ios/qiostextinputoverlay.mm index bb9fe4d58f..fe3c29d037 100644 --- a/src/plugins/platforms/ios/qiostextinputoverlay.mm +++ b/src/plugins/platforms/ios/qiostextinputoverlay.mm @@ -608,7 +608,7 @@ static void executeBlockWithoutAnimation(Block block) - (QIOSLoupeLayer *)createLoupeLayer { Q_UNREACHABLE(); - return Q_NULLPTR; + return nullptr; } - (void)updateFocalPoint:(QPointF)touchPoint @@ -984,12 +984,12 @@ static void executeBlockWithoutAnimation(Block block) QT_BEGIN_NAMESPACE -QIOSEditMenu *QIOSTextInputOverlay::s_editMenu = Q_NULLPTR; +QIOSEditMenu *QIOSTextInputOverlay::s_editMenu = nullptr; QIOSTextInputOverlay::QIOSTextInputOverlay() - : m_cursorRecognizer(Q_NULLPTR) - , m_selectionRecognizer(Q_NULLPTR) - , m_openMenuOnTapRecognizer(Q_NULLPTR) + : m_cursorRecognizer(nullptr) + , m_selectionRecognizer(nullptr) + , m_openMenuOnTapRecognizer(nullptr) { connect(qApp, &QGuiApplication::focusObjectChanged, this, &QIOSTextInputOverlay::updateFocusObject); } @@ -1012,10 +1012,10 @@ void QIOSTextInputOverlay::updateFocusObject() [m_selectionRecognizer release]; [m_openMenuOnTapRecognizer release]; [s_editMenu release]; - m_cursorRecognizer = Q_NULLPTR; - m_selectionRecognizer = Q_NULLPTR; - m_openMenuOnTapRecognizer = Q_NULLPTR; - s_editMenu = Q_NULLPTR; + m_cursorRecognizer = nullptr; + m_selectionRecognizer = nullptr; + m_openMenuOnTapRecognizer = nullptr; + s_editMenu = nullptr; } if (platformInputContext()->inputMethodAccepted()) { diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h index fc6b58178a..c917679a91 100644 --- a/src/plugins/platforms/ios/qiostheme.h +++ b/src/plugins/platforms/ios/qiostheme.h @@ -52,16 +52,16 @@ public: QIOSTheme(); ~QIOSTheme(); - const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE; - QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE; + const QPalette *palette(Palette type = SystemPalette) const override; + QVariant themeHint(ThemeHint hint) const override; - QPlatformMenuItem* createPlatformMenuItem() const Q_DECL_OVERRIDE; - QPlatformMenu* createPlatformMenu() const Q_DECL_OVERRIDE; + QPlatformMenuItem* createPlatformMenuItem() const override; + QPlatformMenu* createPlatformMenu() const override; - bool usePlatformNativeDialog(DialogType type) const Q_DECL_OVERRIDE; - QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const Q_DECL_OVERRIDE; + bool usePlatformNativeDialog(DialogType type) const override; + QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override; - const QFont *font(Font type = SystemFont) const Q_DECL_OVERRIDE; + const QFont *font(Font type = SystemFont) const override; static const char *name; diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index da8a6aabdc..1342d66201 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -60,35 +60,35 @@ public: explicit QIOSWindow(QWindow *window); ~QIOSWindow(); - void setGeometry(const QRect &rect) Q_DECL_OVERRIDE; + void setGeometry(const QRect &rect) override; - void setWindowState(Qt::WindowStates state) Q_DECL_OVERRIDE; - void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE; - void handleContentOrientationChange(Qt::ScreenOrientation orientation) Q_DECL_OVERRIDE; - void setVisible(bool visible) Q_DECL_OVERRIDE; - void setOpacity(qreal level) Q_DECL_OVERRIDE; + void setWindowState(Qt::WindowStates state) override; + void setParent(const QPlatformWindow *window) override; + void handleContentOrientationChange(Qt::ScreenOrientation orientation) override; + void setVisible(bool visible) override; + void setOpacity(qreal level) override; - bool isExposed() const Q_DECL_OVERRIDE; - void propagateSizeHints() Q_DECL_OVERRIDE {} + bool isExposed() const override; + void propagateSizeHints() override {} - void raise() Q_DECL_OVERRIDE{ raiseOrLower(true); } - void lower() Q_DECL_OVERRIDE { raiseOrLower(false); } + void raise() override{ raiseOrLower(true); } + void lower() override { raiseOrLower(false); } bool shouldAutoActivateWindow() const; - void requestActivateWindow() Q_DECL_OVERRIDE; + void requestActivateWindow() override; - qreal devicePixelRatio() const Q_DECL_OVERRIDE; + qreal devicePixelRatio() const override; - bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE { return grab; } - bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE { return grab; } + bool setMouseGrabEnabled(bool grab) override { return grab; } + bool setKeyboardGrabEnabled(bool grab) override { return grab; } - WId winId() const Q_DECL_OVERRIDE { return WId(m_view); } + WId winId() const override { return WId(m_view); } void clearAccessibleCache(); - QSurfaceFormat format() const Q_DECL_OVERRIDE; + QSurfaceFormat format() const override; - void requestUpdate() Q_DECL_OVERRIDE; + void requestUpdate() override; CAEAGLLayer *eaglLayer() const; diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h index 1500f0b41c..2224ee336a 100644 --- a/src/plugins/platforms/ios/quiview.h +++ b/src/plugins/platforms/ios/quiview.h @@ -58,6 +58,7 @@ QT_END_NAMESPACE QT_PREPEND_NAMESPACE(QIOSWindow) *m_qioswindow; @private QHash<UITouch *, QWindowSystemInterface::TouchPoint> m_activeTouches; + UITouch *m_activePencilTouch; int m_nextTouchId; @private diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 1507ff37f7..ddfd2c46fd 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -52,6 +52,8 @@ #include <QtGui/private/qwindow_p.h> #include <qpa/qwindowsysteminterface_p.h> +Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") + @implementation QUIView + (Class)layerClass @@ -310,11 +312,44 @@ return [super pointInside:point withEvent:event]; } -- (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state +- (void)handleTouches:(NSSet *)touches withEvent:(UIEvent *)event withState:(Qt::TouchPointState)state withTimestamp:(ulong)timeStamp { + QIOSIntegration *iosIntegration = QIOSIntegration::instance(); bool supportsPressure = QIOSIntegration::instance()->touchDevice()->capabilities() & QTouchDevice::Pressure; - foreach (UITouch *uiTouch, m_activeTouches.keys()) { +#if QT_CONFIG(tabletevent) + if (m_activePencilTouch && [touches containsObject:m_activePencilTouch]) { + NSArray<UITouch *> *cTouches = [event coalescedTouchesForTouch:m_activePencilTouch]; + int i = 0; + for (UITouch *cTouch in cTouches) { + QPointF localViewPosition = QPointF::fromCGPoint([cTouch preciseLocationInView:self]); + QPoint localViewPositionI = localViewPosition.toPoint(); + QPointF globalScreenPosition = m_qioswindow->mapToGlobal(localViewPositionI) + + (localViewPosition - localViewPositionI); + qreal pressure = cTouch.force / cTouch.maximumPossibleForce; + // azimuth unit vector: +x to the right, +y going downwards + CGVector azimuth = [cTouch azimuthUnitVectorInView: self]; + // azimuthAngle given in radians, zero when the stylus points towards +x axis; converted to degrees with 0 pointing straight up + qreal azimuthAngle = [cTouch azimuthAngleInView: self] * 180 / M_PI + 90; + // altitudeAngle given in radians, pi / 2 is with the stylus perpendicular to the iPad, smaller values mean more tilted, but never negative. + // Convert to degrees with zero being perpendicular. + qreal altitudeAngle = 90 - cTouch.altitudeAngle * 180 / M_PI; + qCDebug(lcQpaTablet) << i << ":" << timeStamp << localViewPosition << pressure << state << "azimuth" << azimuth.dx << azimuth.dy + << "angle" << azimuthAngle << "altitude" << cTouch.altitudeAngle + << "xTilt" << qBound(-60.0, altitudeAngle * azimuth.dx, 60.0) << "yTilt" << qBound(-60.0, altitudeAngle * azimuth.dy, 60.0); + QWindowSystemInterface::handleTabletEvent(m_qioswindow->window(), timeStamp, localViewPosition, globalScreenPosition, + // device, pointerType, buttons + QTabletEvent::RotationStylus, QTabletEvent::Pen, state == Qt::TouchPointReleased ? Qt::NoButton : Qt::LeftButton, + // pressure, xTilt, yTilt + pressure, qBound(-60.0, altitudeAngle * azimuth.dx, 60.0), qBound(-60.0, altitudeAngle * azimuth.dy, 60.0), + // tangentialPressure, rotation, z, uid, modifiers + 0, azimuthAngle, 0, 0, Qt::NoModifier); + ++i; + } + } +#endif + + for (UITouch *uiTouch : m_activeTouches.keys()) { QWindowSystemInterface::TouchPoint &touchPoint = m_activeTouches[uiTouch]; if (![touches containsObject:uiTouch]) { touchPoint.state = Qt::TouchPointStationary; @@ -343,17 +378,13 @@ touchPoint.pressure = uiTouch.force / uiTouch.maximumPossibleForce; } else { // We don't claim that our touch device supports QTouchDevice::Pressure, - // but fill in a meaningfull value in case clients use it anyways. + // but fill in a meaningful value in case clients use it anyway. touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0; } } } -} - -- (void)sendTouchEventWithTimestamp:(ulong)timeStamp -{ - QIOSIntegration *iosIntegration = QIOSIntegration::instance(); - QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); + if (!m_activeTouches.isEmpty()) + QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values()); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -363,8 +394,21 @@ // points to QWindowSystemInterface::TouchPoints, and assigns each TouchPoint // an id for use by Qt. for (UITouch *touch in touches) { - Q_ASSERT(!m_activeTouches.contains(touch)); - m_activeTouches[touch].id = m_nextTouchId++; +#if QT_CONFIG(tabletevent) + if (touch.type == UITouchTypeStylus) { + if (Q_UNLIKELY(m_activePencilTouch)) { + qWarning("ignoring additional Pencil while first is still active"); + continue; + } + m_activePencilTouch = touch; + } else + { + Q_ASSERT(!m_activeTouches.contains(touch)); +#endif + m_activeTouches[touch].id = m_nextTouchId++; +#if QT_CONFIG(tabletevent) + } +#endif } if (m_qioswindow->shouldAutoActivateWindow() && m_activeTouches.size() == 1) { @@ -375,31 +419,36 @@ topLevel->requestActivateWindow(); } - [self updateTouchList:touches withState:Qt::TouchPointPressed]; - [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; + [self handleTouches:touches withEvent:event withState:Qt::TouchPointPressed withTimestamp:ulong(event.timestamp * 1000)]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - [self updateTouchList:touches withState:Qt::TouchPointMoved]; - [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; + [self handleTouches:touches withEvent:event withState:Qt::TouchPointMoved withTimestamp:ulong(event.timestamp * 1000)]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - [self updateTouchList:touches withState:Qt::TouchPointReleased]; - [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; + [self handleTouches:touches withEvent:event withState:Qt::TouchPointReleased withTimestamp:ulong(event.timestamp * 1000)]; // Remove ended touch points from the active set: - for (UITouch *touch in touches) - m_activeTouches.remove(touch); - if (m_activeTouches.isEmpty()) + for (UITouch *touch in touches) { +#if QT_CONFIG(tabletevent) + if (touch.type == UITouchTypeStylus) { + m_activePencilTouch = nil; + } else +#endif + { + m_activeTouches.remove(touch); + } + } + if (m_activeTouches.isEmpty() && !m_activePencilTouch) m_nextTouchId = 0; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - if (m_activeTouches.isEmpty()) + if (m_activeTouches.isEmpty() && !m_activePencilTouch) return; // When four-finger swiping, we get a touchesCancelled callback @@ -423,11 +472,12 @@ // sub-set of the active touch events are intentionally cancelled. NSInteger count = static_cast<NSInteger>([touches count]); - if (count != 0 && count != m_activeTouches.count()) + if (count != 0 && count != m_activeTouches.count() && !m_activePencilTouch) qWarning("Subset of active touches cancelled by UIKit"); m_activeTouches.clear(); m_nextTouchId = 0; + m_activePencilTouch = nil; NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime]; diff --git a/src/plugins/platforms/linuxfb/main.cpp b/src/plugins/platforms/linuxfb/main.cpp index 82b916b9a9..24156b68e8 100644 --- a/src/plugins/platforms/linuxfb/main.cpp +++ b/src/plugins/platforms/linuxfb/main.cpp @@ -47,7 +47,7 @@ class QLinuxFbIntegrationPlugin : public QPlatformIntegrationPlugin Q_OBJECT Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "linuxfb.json") public: - QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; + QPlatformIntegration *create(const QString&, const QStringList&) override; }; QPlatformIntegration* QLinuxFbIntegrationPlugin::create(const QString& system, const QStringList& paramList) diff --git a/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp index e15d6fee24..dcc1ef2790 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp @@ -43,7 +43,6 @@ // Multiscreen: QWindow-QScreen(-output) association. Needs some reorg (device cannot be owned by screen) // Find card via devicediscovery like in eglfs_kms. // Mode restore like QEglFSKmsInterruptHandler. -// Formats other then 32 bpp? // grabWindow #include "qlinuxfbdrmscreen.h" @@ -187,15 +186,67 @@ void QLinuxFbDevice::registerScreen(QPlatformScreen *screen, Q_UNREACHABLE(); } +static uint32_t bppForDrmFormat(uint32_t drmFormat) +{ + switch (drmFormat) { + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + return 16; + default: + return 32; + } +} + +static int depthForDrmFormat(uint32_t drmFormat) +{ + switch (drmFormat) { + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + return 16; + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: + return 24; + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return 30; + default: + return 32; + } +} + +static QImage::Format formatForDrmFormat(uint32_t drmFormat) +{ + switch (drmFormat) { + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: + return QImage::Format_RGB32; + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: + return QImage::Format_ARGB32; + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + return QImage::Format_RGB16; + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + return QImage::Format_RGB30; + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_ABGR2101010: + return QImage::Format_A2RGB30_Premultiplied; + default: + return QImage::Format_ARGB32; + } +} + bool QLinuxFbDevice::createFramebuffer(QLinuxFbDevice::Output *output, int bufferIdx) { const QSize size = output->currentRes(); const uint32_t w = size.width(); const uint32_t h = size.height(); + const uint32_t bpp = bppForDrmFormat(output->kmsOutput.drm_format); drm_mode_create_dumb creq = { h, w, - 32, + bpp, 0, 0, 0, 0 }; if (drmIoctl(fd(), DRM_IOCTL_MODE_CREATE_DUMB, &creq) == -1) { @@ -207,10 +258,15 @@ bool QLinuxFbDevice::createFramebuffer(QLinuxFbDevice::Output *output, int buffe fb.handle = creq.handle; fb.pitch = creq.pitch; fb.size = creq.size; - qCDebug(qLcFbDrm, "Got a dumb buffer for size %dx%d, handle %u, pitch %u, size %u", - w, h, fb.handle, fb.pitch, (uint) fb.size); + qCDebug(qLcFbDrm, "Got a dumb buffer for size %dx%d and bpp %u: handle %u, pitch %u, size %u", + w, h, bpp, fb.handle, fb.pitch, (uint) fb.size); + + uint32_t handles[4] = { fb.handle }; + uint32_t strides[4] = { fb.pitch }; + uint32_t offsets[4] = { 0 }; - if (drmModeAddFB(fd(), w, h, 24, 32, fb.pitch, fb.handle, &fb.fb) == -1) { + if (drmModeAddFB2(fd(), w, h, output->kmsOutput.drm_format, + handles, strides, offsets, &fb.fb, 0) == -1) { qErrnoWarning(errno, "Failed to add FB"); return false; } @@ -229,10 +285,10 @@ bool QLinuxFbDevice::createFramebuffer(QLinuxFbDevice::Output *output, int buffe return false; } - qCDebug(qLcFbDrm, "FB is %u, mapped at %p", fb.fb, fb.p); + qCDebug(qLcFbDrm, "FB is %u (DRM format 0x%x), mapped at %p", fb.fb, output->kmsOutput.drm_format, fb.p); memset(fb.p, 0, fb.size); - fb.wrapper = QImage(static_cast<uchar *>(fb.p), w, h, fb.pitch, QImage::Format_ARGB32); + fb.wrapper = QImage(static_cast<uchar *>(fb.p), w, h, fb.pitch, formatForDrmFormat(output->kmsOutput.drm_format)); return true; } @@ -357,10 +413,10 @@ bool QLinuxFbDrmScreen::initialize() QLinuxFbDevice::Output *output(m_device->output(0)); mGeometry = QRect(QPoint(0, 0), output->currentRes()); - mDepth = 32; - mFormat = QImage::Format_ARGB32; + mDepth = depthForDrmFormat(output->kmsOutput.drm_format); + mFormat = formatForDrmFormat(output->kmsOutput.drm_format); mPhysicalSize = output->kmsOutput.physical_size; - qCDebug(qLcFbDrm) << mGeometry << mPhysicalSize; + qCDebug(qLcFbDrm) << mGeometry << mPhysicalSize << mDepth << mFormat; QFbScreen::initializeCompositor(); diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h index 9934a8cd54..22578bf980 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h @@ -55,19 +55,19 @@ public: QLinuxFbIntegration(const QStringList ¶mList); ~QLinuxFbIntegration(); - void initialize() Q_DECL_OVERRIDE; - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + void initialize() override; + bool hasCapability(QPlatformIntegration::Capability cap) const override; - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const override; - QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; - QPlatformServices *services() const Q_DECL_OVERRIDE; - QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; } + QPlatformFontDatabase *fontDatabase() const override; + QPlatformServices *services() const override; + QPlatformInputContext *inputContext() const override { return m_inputContext; } - QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; + QPlatformNativeInterface *nativeInterface() const override; QList<QPlatformScreen *> screens() const; diff --git a/src/plugins/platforms/minimal/main.cpp b/src/plugins/platforms/minimal/main.cpp index 29809c1843..f9a0c17509 100644 --- a/src/plugins/platforms/minimal/main.cpp +++ b/src/plugins/platforms/minimal/main.cpp @@ -48,7 +48,7 @@ class QMinimalIntegrationPlugin : public QPlatformIntegrationPlugin Q_OBJECT Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "minimal.json") public: - QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; + QPlatformIntegration *create(const QString&, const QStringList&) override; }; QPlatformIntegration *QMinimalIntegrationPlugin::create(const QString& system, const QStringList& paramList) diff --git a/src/plugins/platforms/minimal/qminimalbackingstore.h b/src/plugins/platforms/minimal/qminimalbackingstore.h index 3d7aaf2b99..2119894809 100644 --- a/src/plugins/platforms/minimal/qminimalbackingstore.h +++ b/src/plugins/platforms/minimal/qminimalbackingstore.h @@ -52,9 +52,9 @@ public: QMinimalBackingStore(QWindow *window); ~QMinimalBackingStore(); - QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; - void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE; + QPaintDevice *paintDevice() override; + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) override; + void resize(const QSize &size, const QRegion &staticContents) override; private: QImage mImage; diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp index ca33689cd7..9fc7671feb 100644 --- a/src/plugins/platforms/minimal/qminimalintegration.cpp +++ b/src/plugins/platforms/minimal/qminimalintegration.cpp @@ -123,7 +123,7 @@ bool QMinimalIntegration::hasCapability(QPlatformIntegration::Capability cap) co class DummyFontDatabase : public QPlatformFontDatabase { public: - virtual void populateFontDatabase() Q_DECL_OVERRIDE {} + virtual void populateFontDatabase() override {} }; QPlatformFontDatabase *QMinimalIntegration::fontDatabase() const diff --git a/src/plugins/platforms/minimal/qminimalintegration.h b/src/plugins/platforms/minimal/qminimalintegration.h index eaa2f228c5..bc7b23c83c 100644 --- a/src/plugins/platforms/minimal/qminimalintegration.h +++ b/src/plugins/platforms/minimal/qminimalintegration.h @@ -51,9 +51,9 @@ public: QMinimalScreen() : mDepth(32), mFormat(QImage::Format_ARGB32_Premultiplied) {} - QRect geometry() const Q_DECL_OVERRIDE { return mGeometry; } - int depth() const Q_DECL_OVERRIDE { return mDepth; } - QImage::Format format() const Q_DECL_OVERRIDE { return mFormat; } + QRect geometry() const override { return mGeometry; } + int depth() const override { return mDepth; } + QImage::Format format() const override { return mFormat; } public: QRect mGeometry; @@ -74,12 +74,12 @@ public: explicit QMinimalIntegration(const QStringList ¶meters); ~QMinimalIntegration(); - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; - QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const override; + QPlatformFontDatabase *fontDatabase() const override; - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; + QAbstractEventDispatcher *createEventDispatcher() const override; unsigned options() const { return m_options; } diff --git a/src/plugins/platforms/minimalegl/main.cpp b/src/plugins/platforms/minimalegl/main.cpp index a010ed76e2..5aac71e140 100644 --- a/src/plugins/platforms/minimalegl/main.cpp +++ b/src/plugins/platforms/minimalegl/main.cpp @@ -47,7 +47,7 @@ class QMinimalEglIntegrationPlugin : public QPlatformIntegrationPlugin Q_OBJECT Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "minimalegl.json") public: - QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; + QPlatformIntegration *create(const QString&, const QStringList&) override; }; QPlatformIntegration* QMinimalEglIntegrationPlugin::create(const QString& system, const QStringList& paramList) diff --git a/src/plugins/platforms/minimalegl/qminimaleglbackingstore.h b/src/plugins/platforms/minimalegl/qminimaleglbackingstore.h index 0e22298891..382f2d1404 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglbackingstore.h +++ b/src/plugins/platforms/minimalegl/qminimaleglbackingstore.h @@ -53,13 +53,13 @@ public: QMinimalEglBackingStore(QWindow *window); ~QMinimalEglBackingStore(); - QPaintDevice *paintDevice() Q_DECL_OVERRIDE; + QPaintDevice *paintDevice() override; - void beginPaint(const QRegion &) Q_DECL_OVERRIDE; - void endPaint() Q_DECL_OVERRIDE; + void beginPaint(const QRegion &) override; + void endPaint() override; - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; - void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE; + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) override; + void resize(const QSize &size, const QRegion &staticContents) override; private: QOpenGLContext *m_context; diff --git a/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp b/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp index a716a6092a..5d31af53d5 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp +++ b/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp @@ -71,7 +71,7 @@ public: QWinRTEventDispatcher() {} protected: - bool hasPendingEvents() Q_DECL_OVERRIDE + bool hasPendingEvents() override { return QEventDispatcherWinRT::hasPendingEvents() || QWindowSystemInterface::windowSystemEventsQueued(); } @@ -156,7 +156,7 @@ QAbstractEventDispatcher *QMinimalEglIntegration::createEventDispatcher() const #elif defined(Q_OS_WIN) return new QWindowsGuiEventDispatcher; #else - return Q_NULLPTR; + return nullptr; #endif } diff --git a/src/plugins/platforms/minimalegl/qminimaleglintegration.h b/src/plugins/platforms/minimalegl/qminimaleglintegration.h index d0ab75bd3c..70a51004a6 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglintegration.h +++ b/src/plugins/platforms/minimalegl/qminimaleglintegration.h @@ -51,18 +51,18 @@ public: QMinimalEglIntegration(); ~QMinimalEglIntegration(); - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const override; - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; #ifndef QT_NO_OPENGL - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; #endif - QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const override; - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const override; - QVariant styleHint(QPlatformIntegration::StyleHint hint) const Q_DECL_OVERRIDE; + QVariant styleHint(QPlatformIntegration::StyleHint hint) const override; private: QPlatformFontDatabase *mFontDb; diff --git a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp index 0175d2dbdd..6e122e28ce 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp +++ b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp @@ -64,7 +64,7 @@ public: { } - EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) Q_DECL_OVERRIDE + EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override { QMinimalEglWindow *window = static_cast<QMinimalEglWindow *>(surface); QMinimalEglScreen *screen = static_cast<QMinimalEglScreen *>(window->screen()); diff --git a/src/plugins/platforms/minimalegl/qminimaleglscreen.h b/src/plugins/platforms/minimalegl/qminimaleglscreen.h index 24098b8127..926936ae32 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglscreen.h +++ b/src/plugins/platforms/minimalegl/qminimaleglscreen.h @@ -56,9 +56,9 @@ public: QMinimalEglScreen(EGLNativeDisplayType display); ~QMinimalEglScreen(); - QRect geometry() const Q_DECL_OVERRIDE; - int depth() const Q_DECL_OVERRIDE; - QImage::Format format() const Q_DECL_OVERRIDE; + QRect geometry() const override; + int depth() const override; + QImage::Format format() const override; #ifndef QT_NO_OPENGL QPlatformOpenGLContext *platformContext() const; #endif diff --git a/src/plugins/platforms/minimalegl/qminimaleglwindow.h b/src/plugins/platforms/minimalegl/qminimaleglwindow.h index b8bfd6c8d2..098ec05e6b 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglwindow.h +++ b/src/plugins/platforms/minimalegl/qminimaleglwindow.h @@ -51,8 +51,8 @@ class QMinimalEglWindow : public QPlatformWindow public: QMinimalEglWindow(QWindow *w); - void setGeometry(const QRect &) Q_DECL_OVERRIDE; - WId winId() const Q_DECL_OVERRIDE; + void setGeometry(const QRect &) override; + WId winId() const override; private: WId m_winid; diff --git a/src/plugins/platforms/offscreen/main.cpp b/src/plugins/platforms/offscreen/main.cpp index 9750c4f7ca..207db60f3a 100644 --- a/src/plugins/platforms/offscreen/main.cpp +++ b/src/plugins/platforms/offscreen/main.cpp @@ -48,7 +48,7 @@ class QOffscreenIntegrationPlugin : public QPlatformIntegrationPlugin Q_OBJECT Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "offscreen.json") public: - QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; + QPlatformIntegration *create(const QString&, const QStringList&) override; }; QPlatformIntegration *QOffscreenIntegrationPlugin::create(const QString& system, const QStringList& paramList) diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.cpp b/src/plugins/platforms/offscreen/qoffscreencommon.cpp index 85422071aa..f0eb69718a 100644 --- a/src/plugins/platforms/offscreen/qoffscreencommon.cpp +++ b/src/plugins/platforms/offscreen/qoffscreencommon.cpp @@ -55,8 +55,8 @@ class QOffscreenCursor : public QPlatformCursor public: QOffscreenCursor() : m_pos(10, 10) {} - QPoint pos() const Q_DECL_OVERRIDE { return m_pos; } - void setPos(const QPoint &pos) Q_DECL_OVERRIDE + QPoint pos() const override { return m_pos; } + void setPos(const QPoint &pos) override { m_pos = pos; const QWindowList wl = QGuiApplication::topLevelWindows(); @@ -82,7 +82,7 @@ public: QOffscreenScreen::windowContainingCursor = containing ? containing->handle() : 0; } #ifndef QT_NO_CURSOR - void changeCursor(QCursor *windowCursor, QWindow *window) Q_DECL_OVERRIDE + void changeCursor(QCursor *windowCursor, QWindow *window) override { Q_UNUSED(windowCursor); Q_UNUSED(window); diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.h b/src/plugins/platforms/offscreen/qoffscreencommon.h index 1a9d65972d..541c07384c 100644 --- a/src/plugins/platforms/offscreen/qoffscreencommon.h +++ b/src/plugins/platforms/offscreen/qoffscreencommon.h @@ -57,12 +57,12 @@ class QOffscreenScreen : public QPlatformScreen public: QOffscreenScreen(); - QRect geometry() const Q_DECL_OVERRIDE { return m_geometry; } - int depth() const Q_DECL_OVERRIDE { return 32; } - QImage::Format format() const Q_DECL_OVERRIDE { return QImage::Format_RGB32; } - QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return m_cursor.data(); } + QRect geometry() const override { return m_geometry; } + int depth() const override { return 32; } + QImage::Format format() const override { return QImage::Format_RGB32; } + QPlatformCursor *cursor() const override { return m_cursor.data(); } - QPixmap grabWindow(WId window, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + QPixmap grabWindow(WId window, int x, int y, int width, int height) const override; static QPlatformWindow *windowContainingCursor; @@ -75,7 +75,7 @@ public: class QOffscreenDrag : public QPlatformDrag { public: - Qt::DropAction drag(QDrag *) Q_DECL_OVERRIDE { return Qt::IgnoreAction; } + Qt::DropAction drag(QDrag *) override { return Qt::IgnoreAction; } }; #endif @@ -85,10 +85,10 @@ public: QOffscreenBackingStore(QWindow *window); ~QOffscreenBackingStore(); - QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; - void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE; - bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; + QPaintDevice *paintDevice() override; + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) override; + void resize(const QSize &size, const QRegion &staticContents) override; + bool scroll(const QRegion &area, int dx, int dy) override; QPixmap grabWindow(WId window, const QRect &rect) const; diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h index f72587d11a..c84c1f7c50 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h @@ -54,20 +54,20 @@ public: QOffscreenIntegration(); ~QOffscreenIntegration(); - void initialize() Q_DECL_OVERRIDE; - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + void initialize() override; + bool hasCapability(QPlatformIntegration::Capability cap) const override; - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; #ifndef QT_NO_DRAGANDDROP - QPlatformDrag *drag() const Q_DECL_OVERRIDE; + QPlatformDrag *drag() const override; #endif - QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE; - QPlatformServices *services() const Q_DECL_OVERRIDE; + QPlatformInputContext *inputContext() const override; + QPlatformServices *services() const override; - QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const override; + QAbstractEventDispatcher *createEventDispatcher() const override; QStringList themeNames() const; QPlatformTheme *createPlatformTheme(const QString &name) const; diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h index aaca74d2fb..5e1c6b799b 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h @@ -55,9 +55,9 @@ class QOffscreenX11Info; class QOffscreenX11Integration : public QOffscreenIntegration { public: - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const override; - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; private: mutable QScopedPointer<QOffscreenX11Connection> m_connection; @@ -88,14 +88,14 @@ public: QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGLContext *context); ~QOffscreenX11GLXContext(); - bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE; - void doneCurrent() Q_DECL_OVERRIDE; - void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; - QFunctionPointer getProcAddress(const char *procName) Q_DECL_OVERRIDE; + bool makeCurrent(QPlatformSurface *surface) override; + void doneCurrent() override; + void swapBuffers(QPlatformSurface *surface) override; + QFunctionPointer getProcAddress(const char *procName) override; - QSurfaceFormat format() const Q_DECL_OVERRIDE; - bool isSharing() const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; + QSurfaceFormat format() const override; + bool isSharing() const override; + bool isValid() const override; private: QScopedPointer<QOffscreenX11GLXContextData> d; diff --git a/src/plugins/platforms/offscreen/qoffscreenwindow.h b/src/plugins/platforms/offscreen/qoffscreenwindow.h index 0dced9680a..e1f37bb034 100644 --- a/src/plugins/platforms/offscreen/qoffscreenwindow.h +++ b/src/plugins/platforms/offscreen/qoffscreenwindow.h @@ -53,15 +53,15 @@ public: QOffscreenWindow(QWindow *window); ~QOffscreenWindow(); - void setGeometry(const QRect &rect) Q_DECL_OVERRIDE; - void setWindowState(Qt::WindowStates states) Q_DECL_OVERRIDE; + void setGeometry(const QRect &rect) override; + void setWindowState(Qt::WindowStates states) override; - QMargins frameMargins() const Q_DECL_OVERRIDE; + QMargins frameMargins() const override; - void setVisible(bool visible) Q_DECL_OVERRIDE; - void requestActivateWindow() Q_DECL_OVERRIDE; + void setVisible(bool visible) override; + void requestActivateWindow() override; - WId winId() const Q_DECL_OVERRIDE; + WId winId() const override; static QOffscreenWindow *windowForWinId(WId id); diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp index a758bdf7f4..dd7f907ee0 100644 --- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp +++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp @@ -139,6 +139,7 @@ void QQnxRasterBackingStore::beginPaint(const QRegion ®ion) platformWindow()->adjustBufferSize(); if (window()->requestedFormat().alphaBufferSize() > 0) { + auto platformScreen = static_cast<QQnxScreen *>(platformWindow()->screen()); for (const QRect &r : region) { // Clear transparent regions const int bg[] = { @@ -149,11 +150,11 @@ void QQnxRasterBackingStore::beginPaint(const QRegion ®ion) SCREEN_BLIT_DESTINATION_HEIGHT, r.height(), SCREEN_BLIT_END }; - Q_SCREEN_CHECKERROR(screen_fill(platformWindow()->screen()->nativeContext(), + Q_SCREEN_CHECKERROR(screen_fill(platformScreen->nativeContext(), platformWindow()->renderBuffer().nativeBuffer(), bg), "failed to clear transparent regions"); } - Q_SCREEN_CHECKERROR(screen_flush_blits(platformWindow()->screen()->nativeContext(), + Q_SCREEN_CHECKERROR(screen_flush_blits(platformScreen->nativeContext(), SCREEN_WAIT_IDLE), "failed to flush blits"); } } diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp index 7f11de228e..dc844189d1 100644 --- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp @@ -141,6 +141,7 @@ QQnxBuffer &QQnxRasterWindow::renderBuffer() // Check if render buffer is invalid if (m_currentBufferIndex == -1) { + auto platformScreen = static_cast<QQnxScreen *>(screen()); // Get all buffers available for rendering screen_buffer_t buffers[MAX_BUFFER_COUNT]; const int result = screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_RENDER_BUFFERS, @@ -153,11 +154,11 @@ QQnxBuffer &QQnxRasterWindow::renderBuffer() // Clear Buffer int bg[] = { SCREEN_BLIT_COLOR, 0x00000000, SCREEN_BLIT_END }; - Q_SCREEN_CHECKERROR(screen_fill(screen()->nativeContext(), buffers[i], bg), + Q_SCREEN_CHECKERROR(screen_fill(platformScreen->nativeContext(), buffers[i], bg), "Failed to clear window buffer"); } - Q_SCREEN_CHECKERROR(screen_flush_blits(screen()->nativeContext(), 0), + Q_SCREEN_CHECKERROR(screen_flush_blits(platformScreen->nativeContext(), 0), "Failed to flush blits"); // Use the first available render buffer @@ -185,7 +186,7 @@ void QQnxRasterWindow::adjustBufferSize() int QQnxRasterWindow::pixelFormat() const { - return screen()->nativeFormat(); + return static_cast<QQnxScreen *>(screen())->nativeFormat(); } void QQnxRasterWindow::resetBuffers() diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 2253e3b23d..38b61fd782 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -479,7 +479,7 @@ void QQnxWindow::setParent(const QPlatformWindow *window) if (newParent == m_parentWindow) return; - if (screen()->rootWindow() == this) { + if (static_cast<QQnxScreen *>(screen())->rootWindow() == this) { qWarning("Application window cannot be reparented"); return; } @@ -539,7 +539,7 @@ void QQnxWindow::requestActivateWindow() if (focusWindow == this) return; - if (screen()->rootWindow() == this || + if (static_cast<QQnxScreen *>(screen())->rootWindow() == this || (focusWindow && findWindow(focusWindow->nativeHandle()))) { // If the focus window is a child, we can just set the focus of our own window // group to our window handle @@ -550,6 +550,7 @@ void QQnxWindow::requestActivateWindow() QQnxWindow *currentWindow = this; QList<QQnxWindow*> windowList; while (currentWindow) { + auto platformScreen = static_cast<QQnxScreen *>(screen()); windowList.prepend(currentWindow); // If we find the focus window, we don't have to go further if (currentWindow == focusWindow) @@ -557,9 +558,9 @@ void QQnxWindow::requestActivateWindow() if (currentWindow->parent()){ currentWindow = static_cast<QQnxWindow*>(currentWindow->parent()); - } else if (screen()->rootWindow() && - screen()->rootWindow()->m_windowGroupName == currentWindow->m_parentGroupName) { - currentWindow = screen()->rootWindow(); + } else if (platformScreen->rootWindow() && + platformScreen->rootWindow()->m_windowGroupName == currentWindow->m_parentGroupName) { + currentWindow = platformScreen->rootWindow(); } else { currentWindow = 0; } @@ -622,6 +623,11 @@ void QQnxWindow::clearMMRendererWindow() m_mmRendererWindow = 0; } +QPlatformScreen *QQnxWindow::screen() const +{ + return m_screen; +} + QQnxWindow *QQnxWindow::findWindow(screen_window_t windowHandle) { if (m_window == windowHandle) @@ -775,7 +781,8 @@ void QQnxWindow::windowPosted() bool QQnxWindow::shouldMakeFullScreen() const { - return ((screen()->rootWindow() == this) && (QQnxIntegration::options() & QQnxIntegration::FullScreenApplication)); + return ((static_cast<QQnxScreen *>(screen())->rootWindow() == this) + && (QQnxIntegration::options() & QQnxIntegration::FullScreenApplication)); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h index f96edc49e4..dfcca78f80 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -94,7 +94,7 @@ public: void setMMRendererWindow(screen_window_t handle); void clearMMRendererWindow(); - QQnxScreen *screen() const { return m_screen; } + QPlatformScreen *screen() const override; const QList<QQnxWindow*>& children() const { return m_childWindows; } QQnxWindow *findWindow(screen_window_t windowHandle); diff --git a/src/plugins/platforms/windows/accessible/accessible.pri b/src/plugins/platforms/windows/accessible/accessible.pri deleted file mode 100644 index 557bdfe307..0000000000 --- a/src/plugins/platforms/windows/accessible/accessible.pri +++ /dev/null @@ -1,19 +0,0 @@ -SOURCES += \ - $$PWD/qwindowsaccessibility.cpp \ - $$PWD/comutils.cpp - -HEADERS += \ - $$PWD/qwindowsaccessibility.h \ - $$PWD/comutils.h - -SOURCES += \ - $$PWD/qwindowsmsaaaccessible.cpp \ - $$PWD/iaccessible2.cpp - -HEADERS += \ - $$PWD/qwindowsmsaaaccessible.h \ - $$PWD/iaccessible2.h - -include(../../../../3rdparty/iaccessible2/iaccessible2.pri) - -mingw: LIBS *= -luuid diff --git a/src/plugins/platforms/windows/accessible/comutils.cpp b/src/plugins/platforms/windows/accessible/comutils.cpp deleted file mode 100644 index 1c072c5e2c..0000000000 --- a/src/plugins/platforms/windows/accessible/comutils.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qt_windows.h> - -#include <ocidl.h> -#include <olectl.h> - -#include "comutils.h" -#include <QtCore/qdatetime.h> -#include <QtGui/qpixmap.h> -#include <QtGui/qfont.h> - - -#include <QtCore/qvariant.h> -#include <QtCore/qbytearray.h> -#include <QtGui/qcolor.h> - -QT_BEGIN_NAMESPACE - -static DATE QDateTimeToDATE(const QDateTime &dt) -{ - if (!dt.isValid() || dt.isNull()) - return 949998; // Special value for no date (01/01/4501) - - SYSTEMTIME stime; - memset(&stime, 0, sizeof(stime)); - QDate date = dt.date(); - QTime time = dt.time(); - if (date.isValid() && !date.isNull()) { - stime.wDay = WORD(date.day()); - stime.wMonth = WORD(date.month()); - stime.wYear = WORD(date.year()); - } - if (time.isValid() && !time.isNull()) { - stime.wMilliseconds = WORD(time.msec()); - stime.wSecond = WORD(time.second()); - stime.wMinute = WORD(time.minute()); - stime.wHour = WORD(time.hour()); - } - - double vtime; - SystemTimeToVariantTime(&stime, &vtime); - - return vtime; -} - -inline uint QColorToOLEColor(const QColor &col) -{ - return qRgba(col.blue(), col.green(), col.red(), 0x00); -} - -bool QVariant2VARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out) -{ - QVariant qvar = var; - // "type" is the expected type, so coerce if necessary - QVariant::Type proptype = typeName.isEmpty() ? QVariant::Invalid : QVariant::nameToType(typeName); - if (proptype == QVariant::UserType && !typeName.isEmpty()) { - if (typeName == "short" || typeName == "char") - proptype = QVariant::Int; - else if (typeName == "float") - proptype = QVariant::Double; - } - if (proptype != QVariant::Invalid && proptype != QVariant::UserType && proptype != qvar.type()) { - if (qvar.canConvert(int(proptype))) - qvar.convert(int(proptype)); - else - qvar = QVariant(proptype); - } - - if (out && arg.vt == (VT_VARIANT|VT_BYREF) && arg.pvarVal) { - return QVariant2VARIANT(var, *arg.pvarVal, typeName, false); - } - - if (out && proptype == QVariant::UserType && typeName == "QVariant") { - VARIANT *pVariant = new VARIANT; - QVariant2VARIANT(var, *pVariant, QByteArray(), false); - arg.vt = VT_VARIANT|VT_BYREF; - arg.pvarVal = pVariant; - return true; - } - - switch ((int)qvar.type()) { - case QVariant::String: - if (out && arg.vt == (VT_BSTR|VT_BYREF)) { - if (*arg.pbstrVal) - SysFreeString(*arg.pbstrVal); - *arg.pbstrVal = QStringToBSTR(qvar.toString()); - arg.vt = VT_BSTR|VT_BYREF; - } else { - arg.vt = VT_BSTR; - arg.bstrVal = QStringToBSTR(qvar.toString()); - if (out) { - arg.pbstrVal = new BSTR(arg.bstrVal); - arg.vt |= VT_BYREF; - } - } - break; - - case QVariant::Int: - if (out && arg.vt == (VT_I4|VT_BYREF)) { - *arg.plVal = qvar.toInt(); - } else { - arg.vt = VT_I4; - arg.lVal = qvar.toInt(); - if (out) { - if (typeName == "short") { - arg.vt = VT_I2; - arg.piVal = new short(arg.lVal); - } else if (typeName == "char") { - arg.vt = VT_I1; - arg.pcVal= new char(arg.lVal); - } else { - arg.plVal = new long(arg.lVal); - } - arg.vt |= VT_BYREF; - } - } - break; - - case QVariant::UInt: - if (out && (arg.vt == (VT_UINT|VT_BYREF) || arg.vt == (VT_I4|VT_BYREF))) { - *arg.puintVal = qvar.toUInt(); - } else { - arg.vt = VT_UINT; - arg.uintVal = qvar.toUInt(); - if (out) { - arg.puintVal = new uint(arg.uintVal); - arg.vt |= VT_BYREF; - } - } - break; - - case QVariant::LongLong: - if (out && arg.vt == (VT_CY|VT_BYREF)) { - arg.pcyVal->int64 = qvar.toLongLong(); - } else if (out && arg.vt == (VT_I8|VT_BYREF)) { - *arg.pllVal = qvar.toLongLong(); - } else { - arg.vt = VT_I8; - arg.llVal = qvar.toLongLong(); - if (out) { - arg.pllVal = new LONGLONG(arg.llVal); - arg.vt |= VT_BYREF; - } - } - break; - - case QVariant::ULongLong: - if (out && arg.vt == (VT_CY|VT_BYREF)) { - arg.pcyVal->int64 = qvar.toULongLong(); - } else if (out && arg.vt == (VT_UI8|VT_BYREF)) { - *arg.pullVal = qvar.toULongLong(); - } else { - arg.vt = VT_UI8; - arg.ullVal = qvar.toULongLong(); - if (out) { - arg.pullVal = new ULONGLONG(arg.ullVal); - arg.vt |= VT_BYREF; - } - } - break; - - case QVariant::Bool: - if (out && arg.vt == (VT_BOOL|VT_BYREF)) { - *arg.pboolVal = qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE; - } else { - arg.vt = VT_BOOL; - arg.boolVal = qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE; - if (out) { - arg.pboolVal = new short(arg.boolVal); - arg.vt |= VT_BYREF; - } - } - break; - case QVariant::Double: - if (out && arg.vt == (VT_R8|VT_BYREF)) { - *arg.pdblVal = qvar.toDouble(); - } else { - arg.vt = VT_R8; - arg.dblVal = qvar.toDouble(); - if (out) { - if (typeName == "float") { - arg.vt = VT_R4; - arg.pfltVal = new float(arg.dblVal); - } else { - arg.pdblVal = new double(arg.dblVal); - } - arg.vt |= VT_BYREF; - } - } - break; - case QVariant::Color: - if (out && arg.vt == (VT_COLOR|VT_BYREF)) { - - *arg.plVal = QColorToOLEColor(qvariant_cast<QColor>(qvar)); - } else { - arg.vt = VT_COLOR; - arg.lVal = QColorToOLEColor(qvariant_cast<QColor>(qvar)); - if (out) { - arg.plVal = new long(arg.lVal); - arg.vt |= VT_BYREF; - } - } - break; - - case QVariant::Date: - case QVariant::Time: - case QVariant::DateTime: - if (out && arg.vt == (VT_DATE|VT_BYREF)) { - *arg.pdate = QDateTimeToDATE(qvar.toDateTime()); - } else { - arg.vt = VT_DATE; - arg.date = QDateTimeToDATE(qvar.toDateTime()); - if (out) { - arg.pdate = new DATE(arg.date); - arg.vt |= VT_BYREF; - } - } - break; - - case QVariant::Invalid: // default-parameters not set - if (out && arg.vt == (VT_ERROR|VT_BYREF)) { - *arg.plVal = DISP_E_PARAMNOTFOUND; - } else { - arg.vt = VT_ERROR; - arg.lVal = DISP_E_PARAMNOTFOUND; - if (out) { - arg.plVal = new long(arg.lVal); - arg.vt |= VT_BYREF; - } - } - break; - - default: - return false; - } - - Q_ASSERT(!out || (arg.vt & VT_BYREF)); - return true; -} - -QT_END_NAMESPACE - diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp deleted file mode 100644 index 75af65b5ab..0000000000 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ /dev/null @@ -1,1640 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <QtCore/qglobal.h> -#ifndef QT_NO_ACCESSIBILITY - -#include "iaccessible2.h" -#include "qwindowsaccessibility.h" -#include <QtAccessibilitySupport/private/qaccessiblebridgeutils_p.h> -#include <QtGui/qaccessible.h> -#include <QtGui/qclipboard.h> -#include <QtGui/qguiapplication.h> -#include <QtGui/private/qhighdpiscaling_p.h> -#include <QtCore/qdebug.h> - -#include <algorithm> - -QT_BEGIN_NAMESPACE - -template <class T> -static inline T *coTaskMemAllocArray(int size) -{ - return static_cast<T *>(::CoTaskMemAlloc(sizeof(T) * size_t(size))); -} - -/**************************************************************\ - * AccessibleApplication * - **************************************************************/ - -HRESULT STDMETHODCALLTYPE AccessibleApplication::get_appName(/* [retval][out] */ BSTR *name) -{ - const QString appName = QGuiApplication::applicationName(); - *name = QStringToBSTR(appName); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE AccessibleApplication::get_appVersion(/* [retval][out] */ BSTR *version) -{ - const QString appName = QGuiApplication::applicationVersion(); - *version = QStringToBSTR(appName); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitName(/* [retval][out] */ BSTR *name) -{ - *name = ::SysAllocString(L"Qt"); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitVersion(/* [retval][out] */ BSTR *version) -{ - *version = ::SysAllocString(TEXT(QT_VERSION_STR)); - return S_OK; -} - - -/**************************************************************\ - * AccessibleRelation * - **************************************************************/ -AccessibleRelation::AccessibleRelation(const QList<QAccessibleInterface *> &targets, - QAccessible::Relation relation) - : m_targets(targets), m_relation(relation) -{ - Q_ASSERT(m_targets.count()); -} - -/* IAccessibleRelation */ -HRESULT STDMETHODCALLTYPE AccessibleRelation::get_relationType( - /* [retval][out] */ BSTR *relationType) -{ - *relationType = relationToBSTR(m_relation); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE AccessibleRelation::get_localizedRelationType( - /* [retval][out] */ BSTR *localizedRelationType) -{ - // Who ever needs this??? - *localizedRelationType = relationToBSTR(m_relation); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE AccessibleRelation::get_nTargets( - /* [retval][out] */ long *nTargets) -{ - // ### always one target - *nTargets = m_targets.count(); - return S_OK; -} - -/*! - \internal - Client allocates and deallocates array - (see "Special Consideration when using Arrays", in Accessible2.idl) - */ -HRESULT STDMETHODCALLTYPE AccessibleRelation::get_target( - /* [in] */ long targetIndex, - /* [retval][out] */ IUnknown **target) -{ - if (targetIndex >= 0 && targetIndex < m_targets.count()) { - QAccessibleInterface *iface = m_targets.at(targetIndex); - *target = QWindowsAccessibility::wrap(iface); - if (*target) - return S_OK; - return E_FAIL; - } - return E_INVALIDARG; -} - -/*! - \internal - Client allocates and deallocates \a targets array - (see "Special Consideration when using Arrays", in Accessible2.idl) - */ -HRESULT STDMETHODCALLTYPE AccessibleRelation::get_targets( - /* [in] */ long maxTargets, - /* [length_is][size_is][out] */ IUnknown **targets, - /* [retval][out] */ long *nTargets) -{ - - const int numTargets = qMin(int(maxTargets), m_targets.count()); - for (int i = 0; i < numTargets; ++i) { - QAccessibleInterface *iface = m_targets.at(i); - IAccessible *iacc = QWindowsAccessibility::wrap(iface); - if (!iacc) - return E_FAIL; - *targets = iacc; - ++targets; - } - *nTargets = numTargets; - // \a targets array is allocated by client. - return numTargets > 0 ? S_OK : S_FALSE; -} - - -/**************************************************************\ - * * - * IUnknown * - * * - **************************************************************/ -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryInterface(REFIID id, LPVOID *iface) -{ - *iface = nullptr; - QAccessibleInterface *accessible = accessibleInterface(); - if (!accessible) - return E_NOINTERFACE; - - if (SUCCEEDED(QWindowsMsaaAccessible::QueryInterface(id, iface)) - || qWindowsComQueryInterface<IServiceProvider>(this, id, iface) - || qWindowsComQueryInterface<IAccessible2>(this, id, iface) - || qWindowsComQueryInterface<IAccessibleComponent>(this, id, iface)) { - return S_OK; - } - - if (id == IID_IAccessibleAction) { - if (accessible->actionInterface()) - *iface = static_cast<IAccessibleAction *>(this); - } else if (id == IID_IAccessibleEditableText) { - if (accessible->editableTextInterface() || - accessible->role() == QAccessible::EditableText) - { - *iface = static_cast<IAccessibleEditableText *>(this); - } - } else if (id == IID_IAccessibleHyperlink) { - //*iface = static_cast<IAccessibleHyperlink *>(this); - } else if (id == IID_IAccessibleHypertext) { - //*iface = static_cast<IAccessibleHypertext *>(this); - } else if (id == IID_IAccessibleImage) { - //*iface = static_cast<IAccessibleImage *>(this); - } else if (id == IID_IAccessibleTable) { - //*iface = static_cast<IAccessibleTable *>(this); // not supported - } else if (id == IID_IAccessibleTable2) { - if (accessible->tableInterface()) - *iface = static_cast<IAccessibleTable2 *>(this); - } else if (id == IID_IAccessibleTableCell) { - if (accessible->tableCellInterface()) - *iface = static_cast<IAccessibleTableCell *>(this); - } else if (id == IID_IAccessibleText) { - if (accessible->textInterface()) - *iface = static_cast<IAccessibleText *>(this); - } else if (id == IID_IAccessibleValue) { - if (accessible->valueInterface()) - *iface = static_cast<IAccessibleValue *>(this); - } - if (*iface) { - AddRef(); - return S_OK; - } - return E_NOINTERFACE; -} - - -/* Note that IUnknown is inherited from several interfaces. Therefore we must reimplement all its - functions in the concrete class to avoid ambiguity. -*/ -ULONG STDMETHODCALLTYPE QWindowsIA2Accessible::AddRef() -{ - return QWindowsMsaaAccessible::AddRef(); -} - -ULONG STDMETHODCALLTYPE QWindowsIA2Accessible::Release() -{ - return QWindowsMsaaAccessible::Release(); -} - -/**************************************************************\ - * * - * IAccessible2 * - * * - **************************************************************/ -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nRelations(long *nRelations) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!nRelations) - return E_INVALIDARG; - if (!accessible) - return E_FAIL; - - return getRelationsHelper(0, 0, 0, nRelations); -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_relation(long relationIndex, IAccessibleRelation **relation) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!relation) - return E_INVALIDARG; - if (!accessible) - return E_FAIL; - - return getRelationsHelper(relation, relationIndex, 1); -} - -/*! - \internal - Client allocates and deallocates array - (see "Special Consideration when using Arrays", in Accessible2.idl) - */ -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_relations(long maxRelations, - IAccessibleRelation **relations, - long *nRelations) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - return getRelationsHelper(relations, 0, maxRelations, nRelations); -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::role(long *ia2role) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - long r = accessible->role(); - - switch (r) { - case QAccessible::LayeredPane: r = IA2_ROLE_LAYERED_PANE; break; - case QAccessible::Terminal: r = IA2_ROLE_TERMINAL; break; - case QAccessible::Desktop: r = IA2_ROLE_DESKTOP_PANE; break; - case QAccessible::Paragraph: r = IA2_ROLE_PARAGRAPH; break; - case QAccessible::Section: r = IA2_ROLE_SECTION; break; - default: break; - } - - *ia2role = r; - return S_OK; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::scrollTo(enum IA2ScrollType /*scrollType*/) -{ - //### Ignore for now - return E_NOTIMPL; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::scrollToPoint(enum IA2CoordinateType /*coordinateType*/, long /*x*/, long /*y*/) -{ - //### Ignore for now - return E_NOTIMPL; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_groupPosition(long *groupLevel, - long *similarItemsInGroup, - long *positionInGroup) -{ - // ### Ignore for now. Not sure what this is used for..... - *groupLevel = 0; // Not applicable - *similarItemsInGroup = 0; // Not applicable - *positionInGroup = 0; // Not applicable - return S_FALSE; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_states(AccessibleStates *states) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - if (!states) - return E_POINTER; - QAccessible::State st = accessible->state(); - AccessibleStates ia2states = 0; - if (st.active) - ia2states |= IA2_STATE_ACTIVE; - if (st.invalid) - ia2states |= IA2_STATE_DEFUNCT; - if (st.editable) - ia2states |= IA2_STATE_EDITABLE; - if (st.multiLine) - ia2states |= IA2_STATE_MULTI_LINE; - if (st.selectableText) - ia2states |= IA2_STATE_SELECTABLE_TEXT; - if (st.supportsAutoCompletion) - ia2states |= IA2_STATE_SUPPORTS_AUTOCOMPLETION; - - *states = ia2states; - return S_OK; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_extendedRole(BSTR *extendedRole) -{ - //### - *extendedRole = 0; - return E_NOTIMPL; // mozilla does this - //return S_FALSE; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_localizedExtendedRole(BSTR *localizedExtendedRole) -{ - //### - *localizedExtendedRole = 0; - return E_NOTIMPL; // mozilla does this - //return S_FALSE; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nExtendedStates(long *nExtendedStates) -{ - // Who will ever intepret these values into something meaningful?? - *nExtendedStates = 0; - return E_NOTIMPL; // mozilla does this - //return S_FALSE; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_extendedStates(long /*maxExtendedStates*/, - BSTR **extendedStates, - long *nExtendedStates) -{ - *extendedStates = 0; - *nExtendedStates = 0; - return E_NOTIMPL; // mozilla does this - //return S_FALSE; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_localizedExtendedStates(long /*maxLocalizedExtendedStates*/, - BSTR **localizedExtendedStates, - long *nLocalizedExtendedStates) -{ - *localizedExtendedStates = 0; - *nLocalizedExtendedStates = 0; - return E_NOTIMPL; // mozilla does this - //return S_FALSE; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_uniqueID(long *outUniqueID) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - qCDebug(lcQpaAccessibility) << "uniqueID: " << showbase << hex << id; - - *outUniqueID = (long)id; - return int(id) < 0 ? S_OK : S_FALSE; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_windowHandle(HWND *windowHandle) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - return GetWindow(windowHandle); -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_indexInParent(long *indexInParent) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - if (!indexInParent) - return E_INVALIDARG; - QAccessibleInterface *par = accessible->parent(); - *indexInParent = par ? par->indexOfChild(accessible) : -1; - if (*indexInParent < 0) { - qCWarning(lcQpaAccessibility) << "index in parent invalid:" << accessible << "parent:" << par; - return S_FALSE; - } - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locale(IA2Locale *locale) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - IA2Locale res; - QLocale l; - res.country = QStringToBSTR(QLocale::countryToString(l.country())); - res.language = QStringToBSTR(QLocale::languageToString(l.language())); - res.variant = QStringToBSTR(QString()); - *locale = res; - return S_OK; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_attributes(BSTR *attributes) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - *attributes = 0;//QStringToBSTR(QString()); - return S_FALSE; -} - -/**************************************************************\ - * IAccessibleAction * - **************************************************************/ -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::nActions(long *nActions) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - *nActions = QAccessibleBridgeUtils::effectiveActionNames(accessible).count(); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::doAction(long actionIndex) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(accessible); - if (actionIndex < 0 || actionIndex >= actionNames.count()) - return E_INVALIDARG; - const QString actionName = actionNames.at(actionIndex); - return QAccessibleBridgeUtils::performEffectiveAction(accessible, actionName) ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_description(long actionIndex, BSTR *description) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - *description = 0; - const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(accessible); - if (actionIndex < 0 || actionIndex >= actionNames.count()) - return E_INVALIDARG; - const QString actionName = actionNames.at(actionIndex); - if (QAccessibleActionInterface *actionIface = actionInterface()) - *description = QStringToBSTR(actionIface->localizedActionDescription(actionName)); - else - *description = QStringToBSTR(qAccessibleLocalizedActionDescription(actionName)); - - return *description ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_keyBinding(long actionIndex, long nMaxBindings, BSTR **keyBindings, long *nBindings) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - Q_UNUSED(nMaxBindings); - BSTR *arrayOfBindingsToReturn = 0; - int numBindings = 0; - if (QAccessibleActionInterface *actionIface = actionInterface()) { - const QStringList actionNames = actionIface->actionNames(); - if (actionIndex < 0 || actionIndex >= actionNames.count()) - return E_INVALIDARG; - const QString actionName = actionNames.at(actionIndex); - const QStringList keyBindings = actionIface->keyBindingsForAction(actionName); - numBindings = keyBindings.count(); - if (numBindings > 0) { - // The IDL documents that the client must free with CoTaskMemFree - arrayOfBindingsToReturn = coTaskMemAllocArray<BSTR>(numBindings); - std::transform(keyBindings.constBegin(), keyBindings.constEnd(), - QT_MAKE_CHECKED_ARRAY_ITERATOR(arrayOfBindingsToReturn, numBindings), - QStringToBSTR); - } - } - *keyBindings = arrayOfBindingsToReturn; - *nBindings = numBindings; - - return numBindings ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_name(long actionIndex, BSTR *name) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - *name = 0; - const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(accessible); - if (actionIndex < 0 || actionIndex >= actionNames.count()) - return E_INVALIDARG; - const QString actionName = actionNames.at(actionIndex); - *name = QStringToBSTR(actionName); - return *name ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_localizedName(long actionIndex, BSTR *localizedName) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - *localizedName = 0; - const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(accessible); - if (actionIndex < 0 || actionIndex >= actionNames.count()) - return E_INVALIDARG; - - const QString actionName = actionNames.at(actionIndex); - if (QAccessibleActionInterface *actionIface = actionInterface()) - *localizedName = QStringToBSTR(actionIface->localizedActionName(actionName)); - else - *localizedName = QStringToBSTR(QAccessibleActionInterface::tr(qPrintable(actionName))); - - return *localizedName ? S_OK : S_FALSE; -} - -/**************************************************************\ - * IAccessibleComponent * - **************************************************************/ -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locationInParent(long *x, long *y) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - QPoint topLeft = accessible->rect().topLeft(); - - QAccessibleInterface *parentIface = accessible->parent(); - if (parentIface && parentIface->isValid()) - topLeft -= parentIface->rect().topLeft(); - const QPoint nativeTopLeft = QHighDpi::toNativeLocalPosition(topLeft, accessible->window()); - - - *x = nativeTopLeft.x(); - *y = nativeTopLeft.y(); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_foreground(IA2Color *foreground) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - // IA2Color is a typedef for long - *foreground = static_cast<IA2Color>(accessible->foregroundColor().rgb()); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_background(IA2Color *background) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - // IA2Color is a typedef for long - *background = static_cast<IA2Color>(accessible->backgroundColor().rgb()); - return S_OK; -} - -/**************************************************************\ - * IAccessibleEditableText * - **************************************************************/ -#if QT_CONFIG(clipboard) -/*! - \internal - - if \a endOffset == -1 it means end of the text -*/ -QString QWindowsIA2Accessible::textForRange(int startOffset, int endOffset) const -{ - QAccessibleInterface *accessible = accessibleInterface(); - - if (QAccessibleTextInterface *textIface = accessible->textInterface()) { - if (endOffset == IA2_TEXT_OFFSET_LENGTH) - endOffset = textIface->characterCount(); - return textIface->text(startOffset, endOffset); - } - QString txt = accessible->text(QAccessible::Value); - if (endOffset == IA2_TEXT_OFFSET_LENGTH) - endOffset = txt.length(); - return txt.mid(startOffset, endOffset - startOffset); -} -#endif - -/*! - \internal -*/ -void QWindowsIA2Accessible::replaceTextFallback(long startOffset, long endOffset, const QString &txt) -{ - QAccessibleInterface *accessible = accessibleInterface(); - QString t = textForRange(0, -1); - if (endOffset == IA2_TEXT_OFFSET_LENGTH) - endOffset = t.length(); - if (endOffset - startOffset == 0) { - t.insert(startOffset, txt); - } else { - t.replace(startOffset, endOffset - startOffset, txt); - } - accessible->setText(QAccessible::Value, t); -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::copyText(long startOffset, long endOffset) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); -#if QT_CONFIG(clipboard) - const QString t = textForRange(startOffset, endOffset); - QGuiApplication::clipboard()->setText(t); - return S_OK; -#else - return E_NOTIMPL; -#endif -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::deleteText(long startOffset, long endOffset) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface()) - editableTextIface->deleteText(startOffset, endOffset); - else - replaceTextFallback(startOffset, endOffset, QString()); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::insertText(long offset, BSTR *text) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - const QString txt = QString::fromWCharArray(*text); - if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface()) - editableTextIface->insertText(offset, txt); - else - replaceTextFallback(offset, offset, txt); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::cutText(long startOffset, long endOffset) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); -#if QT_CONFIG(clipboard) - const QString t = textForRange(startOffset, endOffset); - if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface()) - editableTextIface->deleteText(startOffset, endOffset); - else - replaceTextFallback(startOffset, endOffset, QString()); - QGuiApplication::clipboard()->setText(t); - return S_OK; -#else - return E_NOTIMPL; -#endif -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::pasteText(long offset) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); -#if QT_CONFIG(clipboard) - const QString txt = QGuiApplication::clipboard()->text(); - if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface()) - editableTextIface->insertText(offset, txt); - else - replaceTextFallback(offset, offset, txt); - return S_OK; -#else - return E_NOTIMPL; -#endif -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::replaceText(long startOffset, long endOffset, BSTR *text) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - const QString txt = QString::fromWCharArray(*text); - if (QAccessibleEditableTextInterface *editableTextIface = accessible->editableTextInterface()) - editableTextIface->replaceText(startOffset, endOffset, txt); - else - replaceTextFallback(startOffset, endOffset, txt); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::setAttributes(long /*startOffset*/, long /*endOffset*/, BSTR * /*attributes*/) -{ - return E_NOTIMPL; -} - - -/**************************************************************\ - * IAccessibleTable2 * - **************************************************************/ -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_cellAt( long row, long column, IUnknown **cell) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - *cell = 0; - if (QAccessibleTableInterface *tableIface = tableInterface()) { - if (QAccessibleInterface *qtCell = tableIface->cellAt(row, column)) { - *cell = QWindowsAccessibility::wrap(qtCell); - } - } - qCDebug(lcQpaAccessibility) << "found cell? " << *cell; - return *cell ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_caption( IUnknown **captionInterface) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - *captionInterface = 0; - if (QAccessibleTableInterface *tableIface = tableInterface()) { - if (QAccessibleInterface *iface = tableIface->caption()) - *captionInterface = QWindowsAccessibility::wrap(iface); - } - return *captionInterface ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_columnDescription( long column, BSTR *description) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - *description = 0; - if (QAccessibleTableInterface *tableIface = tableInterface()) { - const QString qtDesc = tableIface->columnDescription(column); - if (!qtDesc.isEmpty()) - *description = QStringToBSTR(qtDesc); - } - return *description ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nColumns( long *columnCount) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - *columnCount = tableIface->columnCount(); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nRows(long *rowCount) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - *rowCount = tableIface->rowCount(); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nSelectedCells(long *cellCount) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - *cellCount = tableIface->selectedCellCount(); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nSelectedColumns(long *columnCount) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - *columnCount = tableIface->selectedColumnCount(); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nSelectedRows(long *rowCount) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - *rowCount = tableIface->selectedRowCount(); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowDescription(long row, BSTR *description) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - *description = 0; - if (QAccessibleTableInterface *tableIface = tableInterface()) { - const QString qtDesc = tableIface->rowDescription(row); - if (!qtDesc.isEmpty()) - *description = QStringToBSTR(qtDesc); - } - return *description ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedCells(IUnknown ***cells, long *nSelectedCells) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - Q_UNUSED(cells); - Q_UNUSED(nSelectedCells); - if (!accessible) - return E_FAIL; - - QList<QAccessibleInterface*> selectedCells = tableInterface()->selectedCells(); - return wrapListOfCells(selectedCells, cells, nSelectedCells); -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedColumns(long **selectedColumns, long *nColumns) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - const QList<int> selectedIndices = tableIface->selectedColumns(); - const int count = selectedIndices.count(); - *nColumns = count; - *selectedColumns = Q_NULLPTR; - if (count) { - *selectedColumns = coTaskMemAllocArray<long>(count); - std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), - QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedColumns, count)); - } - return count ? S_OK : S_FALSE; - } - return E_FAIL; - -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedRows(long **selectedRows, long *nRows) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - const QList<int> selectedIndices = tableIface->selectedRows(); - const int count = selectedIndices.count(); - *nRows = count; - *selectedRows = Q_NULLPTR; - if (count) { - *selectedRows = coTaskMemAllocArray<long>(count); - std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), - QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedRows, count)); - } - return count ? S_OK : S_FALSE; - } - return E_FAIL; - -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_summary(IUnknown **summaryInterface) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - *summaryInterface = 0; - if (QAccessibleTableInterface *tableIface = tableInterface()) { - if (QAccessibleInterface *iface = tableIface->summary()) - *summaryInterface = QWindowsAccessibility::wrap(iface); - } - return *summaryInterface ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_isColumnSelected(long column, boolean *isSelected) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - *isSelected = tableIface->isColumnSelected(column); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_isRowSelected(long row, boolean *isSelected) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - *isSelected = tableIface->isRowSelected(row); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::selectRow(long row) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - bool ok = tableIface->selectRow(row); - return ok ? S_OK : E_INVALIDARG; //### Not sure of the return value if it fails??? - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::selectColumn(long column) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - bool ok = tableIface->selectColumn(column); - return ok ? S_OK : E_INVALIDARG; //### Not sure of the return value if it fails??? - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::unselectRow(long row) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - bool ok = tableIface->unselectRow(row); - return ok ? S_OK : E_INVALIDARG; //### Not sure of the return value if it fails??? - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::unselectColumn(long column) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleTableInterface *tableIface = tableInterface()) { - bool ok = tableIface->unselectColumn(column); - return ok ? S_OK : E_INVALIDARG; //### Not sure of the return value if it fails??? - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_modelChange( IA2TableModelChange * /*modelChange*/) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - return E_NOTIMPL; -} - -/**************************************************************\ - * IAccessibleTableCell * -\**************************************************************/ -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_columnExtent(long *nColumnsSpanned) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - *nColumnsSpanned = tableCellInterface()->columnExtent(); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_columnHeaderCells(IUnknown ***cellAccessibles, - long *nColumnHeaderCells) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - const QList<QAccessibleInterface*> headerCells = tableCellInterface()->columnHeaderCells(); - return wrapListOfCells(headerCells, cellAccessibles, nColumnHeaderCells); -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_columnIndex(long *columnIndex) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - *columnIndex = tableCellInterface()->columnIndex(); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowExtent(long *nRowsSpanned) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - *nRowsSpanned = tableCellInterface()->rowExtent(); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowHeaderCells(IUnknown ***cellAccessibles, - long *nRowHeaderCells) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - const QList<QAccessibleInterface*> headerCells = tableCellInterface()->rowHeaderCells(); - return wrapListOfCells(headerCells, cellAccessibles, nRowHeaderCells); -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowIndex(long *rowIndex) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - *rowIndex = tableCellInterface()->rowIndex(); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_isSelected( boolean *isSelected) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - *isSelected = tableCellInterface()->isSelected(); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowColumnExtents(long *row, long *column, - long *rowExtents, long *columnExtents, - boolean *isSelected) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible || !tableCellInterface()) - return E_FAIL; - - *row = tableCellInterface()->rowIndex(); - *column = tableCellInterface()->columnIndex(); - *rowExtents = tableCellInterface()->rowExtent(); - *columnExtents = tableCellInterface()->columnExtent(); - *isSelected = tableCellInterface()->isSelected(); - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_table(IUnknown **table) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - QAccessibleInterface *tableIface = tableCellInterface()->table(); - - *table = QWindowsAccessibility::wrap(tableIface); - return S_OK; -} - -/**************************************************************\ - * IAccessibleText * -\**************************************************************/ -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::addSelection(long startOffset, - long endOffset) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *text = textInterface()) { - text->addSelection(startOffset, endOffset); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_attributes(long offset, - long *startOffset, - long *endOffset, - BSTR *textAttributes) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *text = textInterface()) { - const QString attrs = text->attributes(offset, reinterpret_cast<int *>(startOffset), - reinterpret_cast<int *>(endOffset)); - *textAttributes = QStringToBSTR(attrs); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_caretOffset(long *offset) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *text = textInterface()) { - *offset = text->cursorPosition(); - return S_OK; - } - return E_FAIL; -} - - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_characterExtents(long offset, - enum IA2CoordinateType coordType, - long *x, - long *y, - long *width, - long *height) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *text = textInterface()) { - QRect rect = text->characterRect(offset); - mapFromScreenPos(coordType, rect.topLeft(), x, y); - *width = rect.width(); - *height = rect.height(); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nSelections(long *nSelections) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *text = textInterface()) { - *nSelections = text->selectionCount(); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_offsetAtPoint(long x, - long y, - enum IA2CoordinateType coordType, - long *offset) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *text = textInterface()) { - QPoint screenPos = mapToScreenPos(coordType, x, y); - *offset = text->offsetAtPoint(screenPos); - return (*offset >=0 ? S_OK : S_FALSE); - } - return E_FAIL; - -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selection(long selectionIndex, - long *startOffset, - long *endOffset) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *text = textInterface()) { - text->selection(selectionIndex, reinterpret_cast<int *>(startOffset), - reinterpret_cast<int *>(endOffset)); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_text(long startOffset, - long endOffset, - BSTR *text) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *textif = textInterface()) { - const QString t = textif->text(startOffset, endOffset); - if (!t.isEmpty()) { - *text = QStringToBSTR(t); - return S_OK; - } - return E_INVALIDARG; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textBeforeOffset(long offset, - enum IA2TextBoundaryType boundaryType, - long *startOffset, - long *endOffset, - BSTR *text) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *textIface = textInterface()) { - const QString txt = - textIface->textBeforeOffset(offset, static_cast<QAccessible::TextBoundaryType>(boundaryType), - reinterpret_cast<int *>(startOffset), - reinterpret_cast<int *>(endOffset)); - if (!txt.isEmpty()) { - *text = QStringToBSTR(txt); - return S_OK; - } - return S_FALSE; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textAfterOffset( - long offset, - enum IA2TextBoundaryType boundaryType, - long *startOffset, - long *endOffset, - BSTR *text) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *textIface = textInterface()) { - const QString txt = - textIface->textAfterOffset(offset, static_cast<QAccessible::TextBoundaryType>(boundaryType), - reinterpret_cast<int *>(startOffset), - reinterpret_cast<int *>(endOffset)); - if (!txt.isEmpty()) { - *text = QStringToBSTR(txt); - return S_OK; - } - return S_FALSE; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textAtOffset(long offset, - enum IA2TextBoundaryType boundaryType, - long *startOffset, - long *endOffset, - BSTR *text) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *textIface = textInterface()) { - const QString txt = - textIface->textAtOffset(offset, static_cast<QAccessible::TextBoundaryType>(boundaryType), - reinterpret_cast<int *>(startOffset), - reinterpret_cast<int *>(endOffset)); - if (!txt.isEmpty()) { - *text = QStringToBSTR(txt); - return S_OK; - } - return S_FALSE; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::removeSelection(long selectionIndex) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *textIface = textInterface()) { - textIface->removeSelection(selectionIndex); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::setCaretOffset(long offset) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *textIface = textInterface()) { - textIface->setCursorPosition(offset); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::setSelection(long selectionIndex, - long startOffset, - long endOffset) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *textIface = textInterface()) { - textIface->setSelection(selectionIndex, startOffset, endOffset); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nCharacters(long *nCharacters) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *textIface = textInterface()) { - *nCharacters = textIface->characterCount(); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::scrollSubstringTo(long startIndex, - long endIndex, - enum IA2ScrollType scrollType) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (QAccessibleTextInterface *textIface = textInterface()) { - Q_UNUSED(scrollType); //### - textIface->scrollToSubstring(startIndex, endIndex); - return S_OK; - } - return E_FAIL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::scrollSubstringToPoint(long startIndex, - long endIndex, - enum IA2CoordinateType coordinateType, - long x, - long y) -{ - Q_UNUSED(startIndex); - Q_UNUSED(endIndex); - Q_UNUSED(coordinateType); - Q_UNUSED(x); - Q_UNUSED(y); - - return E_NOTIMPL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_newText(IA2TextSegment *newText) -{ - Q_UNUSED(newText); - return E_NOTIMPL; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_oldText(IA2TextSegment *oldText) -{ - Q_UNUSED(oldText); - return E_NOTIMPL; -} - -/**************************************************************\ - * IAccessibleValue * - **************************************************************/ -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_currentValue(VARIANT *currentValue) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - if (QAccessibleValueInterface *valueIface = valueInterface()) { - const QVariant var = valueIface->currentValue(); - if (QVariant2VARIANT(var, *currentValue, QByteArray(), false)) - return S_OK; - - } - currentValue->vt = VT_EMPTY; - return S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::setCurrentValue(VARIANT value) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - HRESULT hr = S_FALSE; - if (QAccessibleValueInterface *valueIface = valueInterface()) { - hr = VariantChangeType(&value, &value, 0, VT_R8); - if (SUCCEEDED(hr)) { - // ### works only for numbers (not date, strings, etc) - valueIface->setCurrentValue(QVariant(value.dblVal)); - } - } - return hr; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_maximumValue(VARIANT *maximumValue) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - if (QAccessibleValueInterface *valueIface = valueInterface()) { - const QVariant var = valueIface->maximumValue(); - if (QVariant2VARIANT(var, *maximumValue, QByteArray(), false)) - return S_OK; - } - maximumValue->vt = VT_EMPTY; - return S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_minimumValue(VARIANT *minimumValue) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - if (QAccessibleValueInterface *valueIface = valueInterface()) { - const QVariant var = valueIface->minimumValue(); - if (QVariant2VARIANT(var, *minimumValue, QByteArray(), false)) - return S_OK; - } - minimumValue->vt = VT_EMPTY; - return S_FALSE; -} - - -/**************************************************************\ - * IServiceProvider * - **************************************************************/ -/*! - \internal - Reimplemented from IServiceProvider -*/ -HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryService(REFGUID guidService, REFIID riid, void **iface) -{ - if (!iface) - return E_POINTER; - Q_UNUSED(guidService); - *iface = 0; - qCDebug(lcQpaAccessibility) << "QWindowsIA2Accessible::QS(): " << QWindowsAccessibleGuid(riid); - - - if (guidService == IID_IAccessible) { - if (riid == IID_IServiceProvider) { - // do not end up calling QueryInterface for IID_IServiceProvider - *iface = 0; - } else if (riid == IID_IAccessible || riid == IID_IUnknown || riid == IID_IDispatch) { - // The above conditions works with AccProbe and NVDA. - *iface = static_cast<IAccessible*>(this); - } else { - // According to _dicoveringInterfaces Discovery of Interfaces, we should really only - // enter here if riid == IID_IAccessible2, but some screen readers does not like that, - // and other servers seems to have realized that. (Chrome and Mozilla for instance, - // calls QueryInterface more or less in the same way) - - // For instance, accProbe discovers IID_IAccessibleTable2 by a QueryService only. - return QueryInterface(riid, iface); - } - } - - if (riid == IID_IAccessibleApplication) { - *iface = new AccessibleApplication; - return S_OK; - } - if (*iface) { - AddRef(); - return S_OK; - } - - return E_NOINTERFACE; -} - - -/*! - \internal - private function.. - \a maxRelations max number of relations to return in \a relations - \a relations the array of relations matching - \a startIndex Index to start to return from, - it will return only that specific relation in \a relations - - If \a relations is null, \a startIndex and \a maxRelations are ignored, causing - it to return the number of relations in \a nRelations -*/ -HRESULT QWindowsIA2Accessible::getRelationsHelper(IAccessibleRelation **relations, int startIndex, long maxRelations, long *nRelations /* = 0*/) -{ - QAccessibleInterface *accessible = accessibleInterface(); - if (nRelations) - *nRelations = 0; - typedef QPair<QAccessibleInterface *, QAccessible::Relation> RelationEntry; - QVector<RelationEntry> rels = accessible->relations(); - QMap<QAccessible::Relation, QAccessibleInterface *> relationMap; - for (QVector<RelationEntry>::const_iterator it = rels.constBegin(); it != rels.constEnd(); ++it) - { - RelationEntry e = *it; - relationMap.insertMulti(e.second, e.first); - } - - QList<QAccessible::Relation> keys = relationMap.keys(); - const int numRelations = keys.count(); - if (relations) { - for (int i = startIndex; i < qMin(startIndex + int(maxRelations), numRelations); ++i) { - QAccessible::Relation relation = keys.at(i); - QList<QAccessibleInterface*> targets = relationMap.values(relation); - AccessibleRelation *rel = new AccessibleRelation(targets, relation); - *relations = rel; - ++relations; - } - } - if (nRelations) - *nRelations = numRelations; - - return numRelations > 0 ? S_OK : S_FALSE; -} - - - - -/*! - \internal - helper to wrap a QList<QAccessibleInterface*> inside an array of IAccessible* - The IAccessible* array is returned as a IUnknown* -*/ -HRESULT QWindowsIA2Accessible::wrapListOfCells(const QList<QAccessibleInterface*> &inputCells, IUnknown ***outputAccessibles, long *nCellCount) -{ - const int count = inputCells.count(); - // Server allocates array - *nCellCount = count; - *outputAccessibles = Q_NULLPTR; - if (count) { - *outputAccessibles = coTaskMemAllocArray<IUnknown *>(count); - std::transform(inputCells.constBegin(), inputCells.constEnd(), - QT_MAKE_CHECKED_ARRAY_ITERATOR(*outputAccessibles, count), - QWindowsAccessibility::wrap); - } - return count > 0 ? S_OK : S_FALSE; -} - -// Q_STATIC_ASSERT(IA2_ROLE_CANVAS == QAccessible::Canvas); // ### Qt 6: make them the same -Q_STATIC_ASSERT(IA2_ROLE_COLOR_CHOOSER == static_cast<IA2Role>(QAccessible::ColorChooser)); -Q_STATIC_ASSERT(IA2_ROLE_FOOTER == static_cast<IA2Role>(QAccessible::Footer)); -Q_STATIC_ASSERT(IA2_ROLE_FORM == static_cast<IA2Role>(QAccessible::Form)); -Q_STATIC_ASSERT(IA2_ROLE_HEADING == static_cast<IA2Role>(QAccessible::Heading)); -Q_STATIC_ASSERT(IA2_ROLE_NOTE == static_cast<IA2Role>(QAccessible::Note)); -Q_STATIC_ASSERT(IA2_ROLE_COMPLEMENTARY_CONTENT == static_cast<IA2Role>(QAccessible::ComplementaryContent)); - -QT_END_NAMESPACE - -#endif //QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.h b/src/plugins/platforms/windows/accessible/iaccessible2.h deleted file mode 100644 index d987016e15..0000000000 --- a/src/plugins/platforms/windows/accessible/iaccessible2.h +++ /dev/null @@ -1,358 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef IACCESSIBLE2_H -#define IACCESSIBLE2_H - -#include <QtCore/qglobal.h> -#ifndef QT_NO_ACCESSIBILITY - -#include "qwindowscombase.h" -#include "qwindowsmsaaaccessible.h" -#include "comutils.h" - -#include "ia2_api_all.h" - -#include <servprov.h> - -QT_BEGIN_NAMESPACE - -#ifdef Q_CC_MINGW -QT_WARNING_DISABLE_GCC("-Wunused-function") // MinGW 7.X claims it is unused -// MinGW's __uuidof operator does not work for the Accessible2 interfaces -template <> -IID qUuidOf<IAccessibleComponent>() { return IID_IAccessibleComponent; } -#endif // Q_CC_MINGW - -class QWindowsIA2Accessible : public QWindowsMsaaAccessible, - public IAccessibleAction, - public IAccessibleComponent, - public IAccessibleEditableText, - public IAccessibleTable2, - public IAccessibleTableCell, - public IAccessibleText, - public IAccessibleValue, - public IServiceProvider -{ -public: - QWindowsIA2Accessible(QAccessibleInterface *a) : QWindowsMsaaAccessible(a) {} - - /* IUnknown */ - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - - /* IAccessible2 */ - HRESULT STDMETHODCALLTYPE get_nRelations(long *nRelations); - HRESULT STDMETHODCALLTYPE get_relation(long relationIndex, IAccessibleRelation **relation); - HRESULT STDMETHODCALLTYPE get_relations(long maxRelations, IAccessibleRelation **relations, long *nRelations); - HRESULT STDMETHODCALLTYPE role(long *role); - HRESULT STDMETHODCALLTYPE scrollTo(enum IA2ScrollType scrollType); - HRESULT STDMETHODCALLTYPE scrollToPoint(enum IA2CoordinateType coordinateType, long x, long y); - HRESULT STDMETHODCALLTYPE get_groupPosition(long *groupLevel, long *similarItemsInGroup, long *positionInGroup); - HRESULT STDMETHODCALLTYPE get_states(AccessibleStates *states); - HRESULT STDMETHODCALLTYPE get_extendedRole(BSTR *extendedRole); - HRESULT STDMETHODCALLTYPE get_localizedExtendedRole(BSTR *localizedExtendedRole); - HRESULT STDMETHODCALLTYPE get_nExtendedStates(long *nExtendedStates); - HRESULT STDMETHODCALLTYPE get_extendedStates(long maxExtendedStates, BSTR **extendedStates, long *nExtendedStates); - HRESULT STDMETHODCALLTYPE get_localizedExtendedStates(long maxLocalizedExtendedStates, BSTR **localizedExtendedStates, long *nLocalizedExtendedStates); - HRESULT STDMETHODCALLTYPE get_uniqueID(long *uniqueID); - HRESULT STDMETHODCALLTYPE get_windowHandle(HWND *windowHandle); - HRESULT STDMETHODCALLTYPE get_indexInParent(long *indexInParent); - HRESULT STDMETHODCALLTYPE get_locale(IA2Locale *locale); - HRESULT STDMETHODCALLTYPE get_attributes(BSTR *attributes); - - /* IAccessibleAction */ - HRESULT STDMETHODCALLTYPE nActions(long *nActions); - HRESULT STDMETHODCALLTYPE doAction(long actionIndex); - HRESULT STDMETHODCALLTYPE get_description(long actionIndex, BSTR *description); - HRESULT STDMETHODCALLTYPE get_keyBinding(long actionIndex, long nMaxBindings, BSTR **keyBindings, long *nBindings); - HRESULT STDMETHODCALLTYPE get_name(long actionIndex, BSTR *name); - HRESULT STDMETHODCALLTYPE get_localizedName(long actionIndex, BSTR *localizedName); - - /* IAccessibleComponent */ - HRESULT STDMETHODCALLTYPE get_locationInParent(long *x,long *y); - HRESULT STDMETHODCALLTYPE get_foreground(IA2Color *foreground); - HRESULT STDMETHODCALLTYPE get_background(IA2Color *background); - - /* IAccessibleEditableText */ - HRESULT STDMETHODCALLTYPE copyText(long startOffset, long endOffset); - HRESULT STDMETHODCALLTYPE deleteText(long startOffset, long endOffset); - HRESULT STDMETHODCALLTYPE insertText(long offset, BSTR *text); - HRESULT STDMETHODCALLTYPE cutText(long startOffset, long endOffset); - HRESULT STDMETHODCALLTYPE pasteText(long offset); - HRESULT STDMETHODCALLTYPE replaceText(long startOffset, long endOffset, BSTR *text); - HRESULT STDMETHODCALLTYPE setAttributes(long startOffset, long endOffset, BSTR *attributes); - - /* IAccessibleTable2 */ - HRESULT STDMETHODCALLTYPE get_cellAt( long row, long column, IUnknown **cell); - HRESULT STDMETHODCALLTYPE get_caption( IUnknown **accessibleInterface); - HRESULT STDMETHODCALLTYPE get_columnDescription( long column, BSTR *description); - HRESULT STDMETHODCALLTYPE get_nColumns( long *columnCount); - HRESULT STDMETHODCALLTYPE get_nRows( long *rowCount); - HRESULT STDMETHODCALLTYPE get_nSelectedCells( long *cellCount); - HRESULT STDMETHODCALLTYPE get_nSelectedColumns( long *columnCount); - HRESULT STDMETHODCALLTYPE get_nSelectedRows( long *rowCount); - HRESULT STDMETHODCALLTYPE get_rowDescription( long row, BSTR *description); - HRESULT STDMETHODCALLTYPE get_selectedCells( IUnknown ***cells, long *nSelectedCells); - HRESULT STDMETHODCALLTYPE get_selectedColumns( long **selectedColumns, long *nColumns); - HRESULT STDMETHODCALLTYPE get_selectedRows( long **selectedRows, long *nRows); - HRESULT STDMETHODCALLTYPE get_summary( IUnknown **accessibleInterface); - HRESULT STDMETHODCALLTYPE get_isColumnSelected( long column, boolean *isSelected); - HRESULT STDMETHODCALLTYPE get_isRowSelected( long row, boolean *isSelected); - HRESULT STDMETHODCALLTYPE selectRow( long row); - HRESULT STDMETHODCALLTYPE selectColumn( long column); - HRESULT STDMETHODCALLTYPE unselectRow( long row); - HRESULT STDMETHODCALLTYPE unselectColumn( long column); - HRESULT STDMETHODCALLTYPE get_modelChange( IA2TableModelChange *modelChange); - - /* IAccessibleTableCell */ - HRESULT STDMETHODCALLTYPE get_columnExtent(long *nColumnsSpanned); - HRESULT STDMETHODCALLTYPE get_columnHeaderCells(IUnknown ***cellAccessibles, long *nColumnHeaderCells); - HRESULT STDMETHODCALLTYPE get_columnIndex(long *columnIndex); - HRESULT STDMETHODCALLTYPE get_rowExtent(long *nRowsSpanned); - HRESULT STDMETHODCALLTYPE get_rowHeaderCells(IUnknown ***cellAccessibles, long *nRowHeaderCells); - HRESULT STDMETHODCALLTYPE get_rowIndex(long *rowIndex); - HRESULT STDMETHODCALLTYPE get_isSelected( boolean *isSelected); - HRESULT STDMETHODCALLTYPE get_rowColumnExtents(long *row, long *column, - long *rowExtents, long *columnExtents, - boolean *isSelected); - HRESULT STDMETHODCALLTYPE get_table(IUnknown **table); - - - /* IAccessibleText */ - HRESULT STDMETHODCALLTYPE addSelection(long startOffset, long endOffset); - HRESULT STDMETHODCALLTYPE get_attributes(long offset, long *startOffset, - long *endOffset, BSTR *textAttributes); - HRESULT STDMETHODCALLTYPE get_caretOffset(long *offset); - HRESULT STDMETHODCALLTYPE get_characterExtents(long offset, enum IA2CoordinateType coordType, - long *x, long *y, - long *width, long *height); - HRESULT STDMETHODCALLTYPE get_nSelections(long *nSelections); - HRESULT STDMETHODCALLTYPE get_offsetAtPoint(long x, long y, enum IA2CoordinateType coordType, long *offset); - HRESULT STDMETHODCALLTYPE get_selection(long selectionIndex, long *startOffset, long *endOffset); - HRESULT STDMETHODCALLTYPE get_text(long startOffset, long endOffset, BSTR *text); - HRESULT STDMETHODCALLTYPE get_textBeforeOffset(long offset, enum IA2TextBoundaryType boundaryType, - long *startOffset, long *endOffset, BSTR *text); - HRESULT STDMETHODCALLTYPE get_textAfterOffset(long offset, enum IA2TextBoundaryType boundaryType, - long *startOffset, long *endOffset, BSTR *text); - HRESULT STDMETHODCALLTYPE get_textAtOffset(long offset, enum IA2TextBoundaryType boundaryType, - long *startOffset, long *endOffset, BSTR *text); - HRESULT STDMETHODCALLTYPE removeSelection(long selectionIndex); - HRESULT STDMETHODCALLTYPE setCaretOffset(long offset); - HRESULT STDMETHODCALLTYPE setSelection(long selectionIndex, long startOffset, long endOffset); - HRESULT STDMETHODCALLTYPE get_nCharacters(long *nCharacters); - HRESULT STDMETHODCALLTYPE scrollSubstringTo(long startIndex, long endIndex, enum IA2ScrollType scrollType); - HRESULT STDMETHODCALLTYPE scrollSubstringToPoint(long startIndex, long endIndex, - enum IA2CoordinateType coordinateType, long x, long y); - HRESULT STDMETHODCALLTYPE get_newText(IA2TextSegment *newText); - HRESULT STDMETHODCALLTYPE get_oldText(IA2TextSegment *oldText); - - /* IAccessibleValue */ - HRESULT STDMETHODCALLTYPE get_currentValue(VARIANT *currentValue); - HRESULT STDMETHODCALLTYPE setCurrentValue(VARIANT value); - HRESULT STDMETHODCALLTYPE get_maximumValue(VARIANT *maximumValue); - HRESULT STDMETHODCALLTYPE get_minimumValue(VARIANT *minimumValue); - - /* IServiceProvider */ - HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppv); - - /* private helper functions */ -private: - inline QAccessibleTextInterface *textInterface() const { - QAccessibleInterface *accessible = accessibleInterface(); - return accessible ? accessible->textInterface() : static_cast<QAccessibleTextInterface *>(0); - } - - inline QAccessibleActionInterface *actionInterface() const { - QAccessibleInterface *accessible = accessibleInterface(); - return accessible->actionInterface(); - } - - inline QAccessibleValueInterface *valueInterface() const { - QAccessibleInterface *accessible = accessibleInterface(); - return accessible->valueInterface(); - } - - inline QAccessibleTableInterface *tableInterface() const { - QAccessibleInterface *accessible = accessibleInterface(); - return accessible->tableInterface(); - } - - inline QAccessibleTableCellInterface *tableCellInterface() const { - QAccessibleInterface *accessible = accessibleInterface(); - return accessible->tableCellInterface(); - } - - /*! - \internal - \a screenPos is in screen relative position - \a x and \y (out) is in parent relative position if coordType == IA2_COORDTYPE_PARENT_RELATIVE - */ - void mapFromScreenPos(enum IA2CoordinateType coordType, const QPoint &screenPos, long *x, long *y) const { - QAccessibleInterface *accessible = accessibleInterface(); - if (coordType == IA2_COORDTYPE_PARENT_RELATIVE) { - // caller wants relative to parent - if (QAccessibleInterface *parent = accessible->parent()) { - const QRect parentScreenRect = parent->rect(); - *x = parentScreenRect.x() - screenPos.x(); - *y = parentScreenRect.y() - screenPos.y(); - return; - } - } - *x = screenPos.x(); - *y = screenPos.y(); - } - - /*! - \internal - \a x and \y is in parent relative position if coordType == IA2_COORDTYPE_PARENT_RELATIVE - \return a screen relative position - */ - QPoint mapToScreenPos(enum IA2CoordinateType coordType, long x, long y) const { - QAccessibleInterface *accessible = accessibleInterface(); - if (coordType == IA2_COORDTYPE_PARENT_RELATIVE) { - if (QAccessibleInterface *parent = accessible->parent()) { - const QRect parentScreenRect = parent->rect(); - return QPoint(parentScreenRect.x() + x, parentScreenRect.y() + y); - } - } - return QPoint(x,y); - } - - HRESULT getRelationsHelper(IAccessibleRelation **relations, int startIndex, long maxRelations, long *nRelations = 0); - HRESULT wrapListOfCells(const QList<QAccessibleInterface*> &inputCells, IUnknown ***outputAccessibles, long *nCellCount); - QString textForRange(int startOffset, int endOffset) const; - void replaceTextFallback(long startOffset, long endOffset, const QString &txt); - -}; - -/**************************************************************\ - * AccessibleApplication * - **************************************************************/ - -#ifdef Q_CC_MINGW -// MinGW's __uuidof operator does not work for the IAccessible2 interfaces -template <> -IID qUuidOf<IAccessibleApplication>() { return IID_IAccessibleApplication; } - -template <> -IID qUuidOf<IAccessible2>() { return IID_IAccessible2; } - -template <> -IID qUuidOf<IAccessibleRelation>() { return IID_IAccessibleRelation; } -#endif // Q_CC_MINGW - -class AccessibleApplication : public QWindowsComBase<IAccessibleApplication> -{ -public: - AccessibleApplication() {} - - virtual ~AccessibleApplication() {} - - /* IAccessibleApplication */ - HRESULT STDMETHODCALLTYPE get_appName(/* [retval][out] */ BSTR *name); - HRESULT STDMETHODCALLTYPE get_appVersion(/* [retval][out] */ BSTR *version); - HRESULT STDMETHODCALLTYPE get_toolkitName(/* [retval][out] */ BSTR *name); - HRESULT STDMETHODCALLTYPE get_toolkitVersion(/* [retval][out] */ BSTR *version); -}; - - - -/**************************************************************\ - * AccessibleRelation * - **************************************************************/ - - - -class AccessibleRelation : public QWindowsComBase<IAccessibleRelation> -{ -public: - AccessibleRelation(const QList<QAccessibleInterface *> &targets, - QAccessible::Relation relation); - - virtual ~AccessibleRelation() {} - - /* IAccessibleRelation */ - HRESULT STDMETHODCALLTYPE get_relationType(BSTR *relationType); - HRESULT STDMETHODCALLTYPE get_localizedRelationType(BSTR *localizedRelationType); - HRESULT STDMETHODCALLTYPE get_nTargets(long *nTargets); - HRESULT STDMETHODCALLTYPE get_target(long targetIndex, IUnknown **target); - HRESULT STDMETHODCALLTYPE get_targets(long maxTargets, IUnknown **targets, long *nTargets); - -private: - static BSTR relationToBSTR(QAccessible::Relation relation) - { - const wchar_t *constRelationString = 0; - switch (relation) { - case QAccessible::Label: - constRelationString = IA2_RELATION_LABEL_FOR; - break; - case QAccessible::Labelled: - constRelationString = IA2_RELATION_LABELLED_BY; - break; - case QAccessible::Controller: - constRelationString = IA2_RELATION_CONTROLLER_FOR; - break; - case QAccessible::Controlled: - constRelationString = IA2_RELATION_CONTROLLED_BY; - break; - case QAccessible::AllRelations: - constRelationString = ( L"AllRelations" ); - break; - } - - if (constRelationString) { - BSTR bstrVal; - const UINT wlen = (UINT)wcslen(constRelationString); - bstrVal = ::SysAllocStringLen(constRelationString, wlen); - return bstrVal; - } - return 0; - } - - - QList<QAccessibleInterface *> m_targets; - QAccessible::Relation m_relation; -}; - -QT_END_NAMESPACE - -#endif //QT_NO_ACCESSIBILITY - -#endif // IACCESSIBLE2_H diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp deleted file mode 100644 index d48cb9674f..0000000000 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qglobal.h> -#ifndef QT_NO_ACCESSIBILITY - - -#include <private/qsystemlibrary_p.h> - -#include <QtCore/qlocale.h> -#include <QtCore/qmap.h> -#include <QtCore/qpair.h> -#include <QtCore/qpointer.h> -#include <QtGui/qaccessible.h> -#include <QtGui/private/qguiapplication_p.h> -#include <qpa/qplatformnativeinterface.h> -#include <qpa/qplatformintegration.h> -#include <QtGui/qwindow.h> -#include <QtGui/qguiapplication.h> -#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h> // registry helper - -#include "qwindowsaccessibility.h" -#include "iaccessible2.h" -#include "comutils.h" - -#include <oleacc.h> - -//#include <uiautomationcoreapi.h> -#ifndef UiaRootObjectId -#define UiaRootObjectId -25 -#endif - -#include <winuser.h> -#if !defined(WINABLEAPI) -# include <winable.h> -#endif - -#include <servprov.h> -#if !defined(Q_CC_BOR) && !defined (Q_CC_GNU) -#include <comdef.h> -#endif - -#include <QtCore/qt_windows.h> - -QT_BEGIN_NAMESPACE - -/*! - \!internal - \class QWindowsAccessibility - - Implements QPlatformAccessibility - -*/ -QWindowsAccessibility::QWindowsAccessibility() -{ -} - -// Retrieve sound name by checking the icon property of a message box -static inline QString messageBoxAlertSound(const QObject *messageBox) -{ - enum MessageBoxIcon { // Keep in sync with QMessageBox::Icon - Information = 1, - Warning = 2, - Critical = 3 - }; - switch (messageBox->property("icon").toInt()) { - case Information: - return QStringLiteral("SystemAsterisk"); - case Warning: - return QStringLiteral("SystemExclamation"); - case Critical: - return QStringLiteral("SystemHand"); - } - return QString(); -} - -static QString soundFileName(const QString &soundName) -{ - const QString key = QStringLiteral("AppEvents\\Schemes\\Apps\\.Default\\") - + soundName + QStringLiteral("\\.Current"); - return QWindowsFontDatabase::readRegistryString(HKEY_CURRENT_USER, - reinterpret_cast<const wchar_t *>(key.utf16()), L""); -} - -void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) -{ - QString soundName; - switch (event->type()) { - case QAccessible::PopupMenuStart: - soundName = QLatin1String("MenuPopup"); - break; - - case QAccessible::MenuCommand: - soundName = QLatin1String("MenuCommand"); - break; - - case QAccessible::Alert: - soundName = event->object()->inherits("QMessageBox") ? - messageBoxAlertSound(event->object()) : QStringLiteral("SystemAsterisk"); - break; - default: - break; - } - - if (!soundName.isEmpty() && !soundFileName(soundName).isEmpty()) { - PlaySound(reinterpret_cast<const wchar_t *>(soundName.utf16()), 0, - SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT); - } - - // An event has to be associated with a window, - // so find the first parent that is a widget and that has a WId - QAccessibleInterface *iface = event->accessibleInterface(); - if (!isActive() || !iface || !iface->isValid()) - return; - QWindow *window = QWindowsAccessibility::windowHelper(iface); - - if (!window) { - window = QGuiApplication::focusWindow(); - if (!window) - return; - } - - QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface(); - if (!window->handle()) // Called before show(), no native window yet. - return; - const HWND hWnd = reinterpret_cast<HWND>(platform->nativeResourceForWindow("handle", window)); - - if (event->type() != QAccessible::MenuCommand && // MenuCommand is faked - event->type() != QAccessible::ObjectDestroyed) { - ::NotifyWinEvent(event->type(), hWnd, OBJID_CLIENT, QAccessible::uniqueId(iface)); - } -} - -QWindow *QWindowsAccessibility::windowHelper(const QAccessibleInterface *iface) -{ - QWindow *window = iface->window(); - if (!window) { - QAccessibleInterface *acc = iface->parent(); - while (acc && acc->isValid() && !window) { - window = acc->window(); - QAccessibleInterface *par = acc->parent(); - acc = par; - } - } - return window; -} - -/*! - \internal - helper to wrap a QAccessibleInterface inside a IAccessible* -*/ -IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc) -{ - if (!acc) - return 0; - - // ### FIXME: maybe we should accept double insertions into the cache - if (!QAccessible::uniqueId(acc)) - QAccessible::registerAccessibleInterface(acc); - - QWindowsIA2Accessible *wacc = new QWindowsIA2Accessible(acc); - IAccessible *iacc = 0; - wacc->QueryInterface(IID_IAccessible, reinterpret_cast<void **>(&iacc)); - return iacc; -} - -bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult) -{ - if (static_cast<long>(lParam) == static_cast<long>(UiaRootObjectId)) { - /* For UI Automation */ - } else if (DWORD(lParam) == DWORD(OBJID_CLIENT)) { - // Start handling accessibility internally - QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true); - // Ignoring all requests while starting up - // ### Maybe QPA takes care of this??? - if (QCoreApplication::startingUp() || QCoreApplication::closingDown()) - return false; - - typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN); - static PtrLresultFromObject ptrLresultFromObject = 0; - static bool oleaccChecked = false; - - if (!oleaccChecked) { - oleaccChecked = true; - ptrLresultFromObject = reinterpret_cast<PtrLresultFromObject>(QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject")); - } - - if (ptrLresultFromObject) { - QWindow *window = QWindowsContext::instance()->findWindow(hwnd); - if (window) { - QAccessibleInterface *acc = window->accessibleRoot(); - if (acc) { - if (IAccessible *iface = wrap(acc)) { - *lResult = ptrLresultFromObject(IID_IAccessible, wParam, iface); // ref == 2 - if (*lResult) { - iface->Release(); // the client will release the object again, and then it will destroy itself - } - return true; - } - } - } - } - } - return false; -} - -QT_END_NAMESPACE - -#endif //QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp deleted file mode 100644 index fe2b9335cb..0000000000 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ /dev/null @@ -1,1223 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qglobal.h> -#ifndef QT_NO_ACCESSIBILITY - -#include "qwindowsmsaaaccessible.h" -#include "qwindowsaccessibility.h" -#include "qwindowscombase.h" -#include <oleacc.h> -#include <servprov.h> -#include <winuser.h> -#include "comutils.h" - -#include <QtCore/qdebug.h> -#include <QtCore/qmap.h> -#include <QtCore/qpair.h> -#include <QtGui/qaccessible.h> -#include <QtGui/qguiapplication.h> -#include <qpa/qplatformnativeinterface.h> -#include <QtGui/qwindow.h> -#include <QtGui/private/qhighdpiscaling_p.h> - -//#include <uiautomationcoreapi.h> -#ifndef UiaRootObjectId -#define UiaRootObjectId -25 -#endif - -#if !defined(Q_CC_BOR) && !defined (Q_CC_GNU) -#include <comdef.h> -#endif - - -#include <QtCore/qt_windows.h> - - -QT_BEGIN_NAMESPACE - -class QWindowsEnumerate : public QWindowsComBase<IEnumVARIANT> -{ -public: - QWindowsEnumerate(const QVector<int> &a) : QWindowsComBase<IEnumVARIANT>(0), current(0),array(a) {} - virtual ~QWindowsEnumerate() {} - - HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT **ppEnum); - HRESULT STDMETHODCALLTYPE Next(unsigned long celt, VARIANT FAR* rgVar, unsigned long FAR* pCeltFetched); - HRESULT STDMETHODCALLTYPE Reset(); - HRESULT STDMETHODCALLTYPE Skip(unsigned long celt); - -private: - ULONG current; - QVector<int> array; -}; - -HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Clone(IEnumVARIANT **ppEnum) -{ - QWindowsEnumerate *penum = 0; - *ppEnum = 0; - - penum = new QWindowsEnumerate(array); - if (!penum) - return E_OUTOFMEMORY; - penum->current = current; - penum->array = array; - penum->AddRef(); - *ppEnum = penum; - - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Next(unsigned long celt, VARIANT FAR* rgVar, unsigned long FAR* pCeltFetched) -{ - if (pCeltFetched) - *pCeltFetched = 0; - - ULONG l; - for (l = 0; l < celt; l++) { - VariantInit(&rgVar[l]); - if (current + 1 > ULONG(array.size())) { - *pCeltFetched = l; - return S_FALSE; - } - - rgVar[l].vt = VT_I4; - rgVar[l].lVal = array[int(current)]; - ++current; - } - *pCeltFetched = l; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Reset() -{ - current = 0; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Skip(unsigned long celt) -{ - current += celt; - if (current > ULONG(array.size())) { - current = ULONG(array.size()); - return S_FALSE; - } - return S_OK; -} - -#if defined(DEBUG_SHOW_ATCLIENT_COMMANDS) -void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleInterface *iface) -{ - qCDebug(lcQpaAccessibility) << iface << funcName; -} -#endif - -/**************************************************************\ - * * - * IUnknown * - * * - **************************************************************/ -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::QueryInterface(REFIID id, LPVOID *iface) -{ - *iface = nullptr; - const bool result = qWindowsComQueryUnknownInterfaceMulti<IAccessible2>(this, id, iface) - || qWindowsComQueryInterface<IDispatch>(this, id, iface) - || qWindowsComQueryInterface<IAccessible>(this, id, iface) - || qWindowsComQueryInterface<IOleWindow>(this, id, iface); - - if (result) { - qCDebug(lcQpaAccessibility) << "QWindowsIA2Accessible::QI() - " - << QWindowsAccessibleGuid(id) << ", iface:" << accessibleInterface(); - } - return result ? S_OK : E_NOINTERFACE; -} - -ULONG STDMETHODCALLTYPE QWindowsMsaaAccessible::AddRef() -{ - return ++ref; -} - -ULONG STDMETHODCALLTYPE QWindowsMsaaAccessible::Release() -{ - if (!--ref) { - delete this; - return 0; - } - return ref; -} - - -/* - IDispatch -*/ - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::GetTypeInfoCount(unsigned int * pctinfo) -{ - // We don't use a type library - *pctinfo = 0; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::GetTypeInfo(unsigned int, unsigned long, ITypeInfo **pptinfo) -{ - // We don't use a type library - *pptinfo = 0; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::GetIDsOfNames(const _GUID &, wchar_t **rgszNames, unsigned int, unsigned long, long *rgdispid) -{ -#if !defined(Q_CC_BOR) && !defined(Q_CC_GNU) - // PROPERTIES: Hierarchical - if (_bstr_t(rgszNames[0]) == _bstr_t(L"accParent")) - rgdispid[0] = DISPID_ACC_PARENT; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accChildCount")) - rgdispid[0] = DISPID_ACC_CHILDCOUNT; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accChild")) - rgdispid[0] = DISPID_ACC_CHILD; - - // PROPERTIES: Descriptional - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accName(")) - rgdispid[0] = DISPID_ACC_NAME; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accValue")) - rgdispid[0] = DISPID_ACC_VALUE; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accDescription")) - rgdispid[0] = DISPID_ACC_DESCRIPTION; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accRole")) - rgdispid[0] = DISPID_ACC_ROLE; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accState")) - rgdispid[0] = DISPID_ACC_STATE; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accHelp")) - rgdispid[0] = DISPID_ACC_HELP; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accHelpTopic")) - rgdispid[0] = DISPID_ACC_HELPTOPIC; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accKeyboardShortcut")) - rgdispid[0] = DISPID_ACC_KEYBOARDSHORTCUT; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accFocus")) - rgdispid[0] = DISPID_ACC_FOCUS; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accSelection")) - rgdispid[0] = DISPID_ACC_SELECTION; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accDefaultAction")) - rgdispid[0] = DISPID_ACC_DEFAULTACTION; - - // METHODS - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accSelect")) - rgdispid[0] = DISPID_ACC_SELECT; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accLocation")) - rgdispid[0] = DISPID_ACC_LOCATION; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accNavigate")) - rgdispid[0] = DISPID_ACC_NAVIGATE; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accHitTest")) - rgdispid[0] = DISPID_ACC_HITTEST; - else if (_bstr_t(rgszNames[0]) == _bstr_t(L"accDoDefaultAction")) - rgdispid[0] = DISPID_ACC_DODEFAULTACTION; - else - return DISP_E_UNKNOWNINTERFACE; - - return S_OK; -#else - Q_UNUSED(rgszNames); - Q_UNUSED(rgdispid); - - return DISP_E_MEMBERNOTFOUND; -#endif -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::Invoke(long dispIdMember, - const _GUID &, - unsigned long, - unsigned short wFlags, - tagDISPPARAMS *pDispParams, - tagVARIANT *pVarResult, - tagEXCEPINFO *, unsigned int *) -{ - HRESULT hr = DISP_E_MEMBERNOTFOUND; - - switch (dispIdMember) - { - case DISPID_ACC_PARENT: - if (wFlags == DISPATCH_PROPERTYGET) { - if (!pVarResult) - return E_INVALIDARG; - hr = get_accParent(&pVarResult->pdispVal); - } else { - hr = DISP_E_MEMBERNOTFOUND; - } - break; - - case DISPID_ACC_CHILDCOUNT: - if (wFlags == DISPATCH_PROPERTYGET) { - if (!pVarResult) - return E_INVALIDARG; - hr = get_accChildCount(&pVarResult->lVal); - } else { - hr = DISP_E_MEMBERNOTFOUND; - } - break; - - case DISPID_ACC_CHILD: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accChild(pDispParams->rgvarg[0], &pVarResult->pdispVal); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_NAME: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accName(pDispParams->rgvarg[0], &pVarResult->bstrVal); - else if (wFlags == DISPATCH_PROPERTYPUT) - hr = put_accName(pDispParams->rgvarg[0], pVarResult->bstrVal); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_VALUE: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accValue(pDispParams->rgvarg[0], &pVarResult->bstrVal); - else if (wFlags == DISPATCH_PROPERTYPUT) - hr = put_accValue(pDispParams->rgvarg[0], pVarResult->bstrVal); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_DESCRIPTION: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accDescription(pDispParams->rgvarg[0], &pVarResult->bstrVal); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_ROLE: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accRole(pDispParams->rgvarg[0], pVarResult); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_STATE: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accState(pDispParams->rgvarg[0], pVarResult); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_HELP: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accHelp(pDispParams->rgvarg[0], &pVarResult->bstrVal); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_HELPTOPIC: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accHelpTopic(&pDispParams->rgvarg[2].bstrVal, pDispParams->rgvarg[1], &pDispParams->rgvarg[0].lVal); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_KEYBOARDSHORTCUT: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accKeyboardShortcut(pDispParams->rgvarg[0], &pVarResult->bstrVal); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_FOCUS: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accFocus(pVarResult); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_SELECTION: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accSelection(pVarResult); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_DEFAULTACTION: - if (wFlags == DISPATCH_PROPERTYGET) - hr = get_accDefaultAction(pDispParams->rgvarg[0], &pVarResult->bstrVal); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_SELECT: - if (wFlags == DISPATCH_METHOD) - hr = accSelect(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0]); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_LOCATION: - if (wFlags == DISPATCH_METHOD) - hr = accLocation(&pDispParams->rgvarg[4].lVal, &pDispParams->rgvarg[3].lVal, &pDispParams->rgvarg[2].lVal, &pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0]); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_NAVIGATE: - if (wFlags == DISPATCH_METHOD) - hr = accNavigate(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0], pVarResult); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_HITTEST: - if (wFlags == DISPATCH_METHOD) - hr = accHitTest(pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0].lVal, pVarResult); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - case DISPID_ACC_DODEFAULTACTION: - if (wFlags == DISPATCH_METHOD) - hr = accDoDefaultAction(pDispParams->rgvarg[0]); - else - hr = DISP_E_MEMBERNOTFOUND; - break; - - default: - hr = DISP_E_MEMBERNOTFOUND; - break; - } - - if (!SUCCEEDED(hr)) { - return hr; - } - return hr; -} - -/* - IAccessible - -IAccessible::accHitTest documents the value returned in pvarID like this: - -| *Point location* | *vt member* | *Value member* | -+========================================================+=============+=========================+ -| Outside of the object's boundaries, and either inside | VT_EMPTY | None. | -| or outside of the object's bounding rectangle. | | | -+--------------------------------------------------------+-------------+-------------------------+ -| Within the object but not within a child element or a | VT_I4 | lVal is CHILDID_SELF | -| child object. | | | -+--------------------------------------------------------+-------------+-------------------------+ -| Within a child element. | VT_I4 | lVal contains | -| | | the child ID. | -+--------------------------------------------------------+-------------+-------------------------+ -| Within a child object. | VT_DISPATCH | pdispVal is set to the | -| | | child object's IDispatch| -| | | interface pointer | -+--------------------------------------------------------+-------------+-------------------------+ -*/ -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarID) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - const QPoint pos = QHighDpi::fromNativeLocalPosition(QPoint(xLeft, yTop), - QWindowsAccessibility::windowHelper(accessible)); - QAccessibleInterface *child = accessible->childAt(pos.x(), pos.y()); - if (child == 0) { - // no child found, return this item if it contains the coordinates - if (accessible->rect().contains(xLeft, yTop)) { - (*pvarID).vt = VT_I4; - (*pvarID).lVal = CHILDID_SELF; - return S_OK; - } - } else { - IAccessible *iface = QWindowsAccessibility::wrap(child); - if (iface) { - (*pvarID).vt = VT_DISPATCH; - (*pvarID).pdispVal = iface; - return S_OK; - } - } - - // Did not find anything - (*pvarID).vt = VT_EMPTY; - return S_FALSE; -} - -/* - It is recommended to read - "Implementing a Microsoft Active Accessibility (MSAA) Server. - Practical Tips for Developers and How Mozilla Does It" - (https://developer.mozilla.org/En/Accessibility/Implementing_an_MSAA_Server) - - to get an overview of what's important to implement and what parts of MSAA - can be ignored. All stuff prefixed with "moz" are information from that page. -*/ -// moz: [important] -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - QAccessibleInterface *acc = childPointer(accessible, varID); - if (!acc || !acc->isValid()) - return E_FAIL; - const QRect rect = QHighDpi::toNativePixels(acc->rect(), - QWindowsAccessibility::windowHelper(accessible)); - - *pxLeft = rect.x(); - *pyTop = rect.y(); - *pcxWidth = rect.width(); - *pcyHeight = rect.height(); - - return S_OK; -} - -// moz: [important, but no need to implement up/down/left/right] -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - QAccessibleInterface *acc = 0; - switch (navDir) { - case NAVDIR_FIRSTCHILD: - acc = accessible->child(0); - break; - case NAVDIR_LASTCHILD: - acc = accessible->child(accessible->childCount() - 1); - break; - case NAVDIR_NEXT: - case NAVDIR_PREVIOUS: - if (!varStart.lVal){ - QAccessibleInterface *parent = accessible->parent(); - if (parent && parent->isValid()) { - int index = parent->indexOfChild(accessible); - index += (navDir == NAVDIR_NEXT) ? 1 : -1; - if (index >= 0 && index < parent->childCount()) - acc = parent->child(index); - } - } else { - int index = varStart.lVal; - index += (navDir == NAVDIR_NEXT) ? 1 : -1; - if (index > 0 && index <= accessible->childCount()) - acc = accessible->child(index - 1); - } - break; - - // Geometrical - case NAVDIR_UP: - case NAVDIR_DOWN: - case NAVDIR_LEFT: - case NAVDIR_RIGHT: { - QAccessibleInterface *pIface = accessible->parent(); - if (pIface && pIface->isValid()) { - const int indexOfOurself = pIface->indexOfChild(accessible); - QRect startg = accessible->rect(); - QPoint startc = startg.center(); - QAccessibleInterface *candidate = 0; - unsigned mindist = UINT_MAX; // will work on screen sizes at least up to 46340x46340 - const int sibCount = pIface->childCount(); - for (int i = 0; i < sibCount; ++i) { - QAccessibleInterface *sibling = 0; - sibling = pIface->child(i); - Q_ASSERT(sibling); - if (i == indexOfOurself || sibling->state().invisible) { - //ignore ourself and invisible siblings - continue; - } - - QRect sibg = sibling->rect(); - QPoint sibc = sibg.center(); - QPoint sibp; - QPoint startp; - QPoint distp; - switch (navDir) { - case NAVDIR_LEFT: - startp = QPoint(startg.left(), startg.top() + startg.height() / 2); - sibp = QPoint(sibg.right(), sibg.top() + sibg.height() / 2); - if (QPoint(sibc - startc).x() >= 0) { - continue; - } - distp = sibp - startp; - break; - case NAVDIR_RIGHT: - startp = QPoint(startg.right(), startg.top() + startg.height() / 2); - sibp = QPoint(sibg.left(), sibg.top() + sibg.height() / 2); - if (QPoint(sibc - startc).x() <= 0) { - continue; - } - distp = sibp - startp; - break; - case NAVDIR_UP: - startp = QPoint(startg.left() + startg.width() / 2, startg.top()); - sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.bottom()); - if (QPoint(sibc - startc).y() >= 0) { - continue; - } - distp = sibp - startp; - break; - case NAVDIR_DOWN: - startp = QPoint(startg.left() + startg.width() / 2, startg.bottom()); - sibp = QPoint(sibg.left() + sibg.width() / 2, sibg.top()); - if (QPoint(sibc - startc).y() <= 0) { - continue; - } - distp = sibp - startp; - break; - default: - break; - } - - // Since we're *comparing* (and not measuring) distances, we can compare the - // squared distance, (thus, no need to take the sqrt()). - unsigned dist = distp.x() * distp.x() + distp.y() * distp.y(); - if (dist < mindist) { - candidate = sibling; - mindist = dist; - } - } - acc = candidate; - } - } - break; - default: - break; - } - if (!acc) { - (*pvarEnd).vt = VT_EMPTY; - return S_FALSE; - } - - if (IAccessible *iface = QWindowsAccessibility::wrap(acc)) { - (*pvarEnd).vt = VT_DISPATCH; - (*pvarEnd).pdispVal = iface; - return S_OK; - } - - (*pvarEnd).vt = VT_EMPTY; - return S_FALSE; -} - -// moz: [important] -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accChild(VARIANT varChildID, IDispatch** ppdispChild) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (varChildID.vt != VT_I4) - return E_INVALIDARG; - - QAccessibleInterface *acc = childPointer(accessible, varChildID); - if (acc && acc->isValid()) { - *ppdispChild = QWindowsAccessibility::wrap(acc); - return S_OK; - } - - return E_FAIL; -} - -// moz: [important] -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accChildCount(long* pcountChildren) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - *pcountChildren = accessible->childCount(); - return S_OK; -} - -// moz: [important] -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accParent(IDispatch** ppdispParent) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - QAccessibleInterface *acc = accessible->parent(); - if (acc) { - if (IAccessible *iface = QWindowsAccessibility::wrap(acc)) { - *ppdispParent = iface; - return S_OK; - } - } - - *ppdispParent = 0; - return S_FALSE; -} - -/* - Properties and methods -*/ -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accDoDefaultAction(VARIANT varID) -{ - Q_UNUSED(varID); - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleActionInterface *actionIface = accessible->actionInterface()) { - const QString def = actionIface->actionNames().value(0); - if (!def.isEmpty()) { - actionIface->doAction(def); - return S_OK; - } - } - return S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction) -{ - Q_UNUSED(varID); - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - *pszDefaultAction = 0; - if (QAccessibleActionInterface *actionIface = accessible->actionInterface()) { - const QString def = actionIface->actionNames().value(0); - if (!def.isEmpty()) - *pszDefaultAction = QStringToBSTR(def); - } - return *pszDefaultAction ? S_OK : S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accDescription(VARIANT varID, BSTR* pszDescription) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - - QString descr; - if (varID.lVal) { - QAccessibleInterface *child = childPointer(accessible, varID); - if (!child || !child->isValid()) - return E_FAIL; - descr = child->text(QAccessible::Description); - } else { - descr = accessible->text(QAccessible::Description); - } - if (descr.size()) { - *pszDescription = QStringToBSTR(descr); - return S_OK; - } - - *pszDescription = 0; - return S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accHelp(VARIANT varID, BSTR *pszHelp) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - QString help; - if (varID.lVal) { - QAccessibleInterface *child = childPointer(accessible, varID); - if (!child || !child->isValid()) - return E_FAIL; - help = child->text(QAccessible::Help); - } else { - help = accessible->text(QAccessible::Help); - } - if (help.size()) { - *pszHelp = QStringToBSTR(help); - return S_OK; - } - - *pszHelp = 0; - return S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accHelpTopic(BSTR *, VARIANT, long *) -{ - return DISP_E_MEMBERNOTFOUND; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut) -{ - Q_UNUSED(varID); - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - *pszKeyboardShortcut = 0; - if (QAccessibleActionInterface *actionIface = accessible->actionInterface()) { - const QString def = actionIface->actionNames().value(0); - if (!def.isEmpty()) { - const QString keyBoardShortCut = actionIface->keyBindingsForAction(def).value(0); - if (!keyBoardShortCut.isEmpty()) - *pszKeyboardShortcut = QStringToBSTR(keyBoardShortCut); - } - } - return *pszKeyboardShortcut ? S_OK : S_FALSE; -} - -static QAccessibleInterface *relatedInterface(QAccessibleInterface *iface, QAccessible::RelationFlag flag) -{ - typedef QPair<QAccessibleInterface *, QAccessible::Relation> RelationPair; - QVector<RelationPair> rels = iface->relations(flag); - - return rels.value(0).first; -} - -// moz: [important] -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accName(VARIANT varID, BSTR* pszName) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - QString name; - if (varID.lVal) { - QAccessibleInterface *child = childPointer(accessible, varID); - if (!child || !child->isValid()) - return E_FAIL; - name = child->text(QAccessible::Name); - if (name.isEmpty()) { - if (QAccessibleInterface *labelInterface = relatedInterface(child, QAccessible::Label)) { - name = labelInterface->text(QAccessible::Name); - } - } - } else { - name = accessible->text(QAccessible::Name); - if (name.isEmpty()) { - if (QAccessibleInterface *labelInterface = relatedInterface(accessible, QAccessible::Label)) { - name = labelInterface->text(QAccessible::Name); - } - } - } - - QString shortcut = accessible->text(QAccessible::Accelerator); - if (!shortcut.isEmpty()) - name += QLatin1Char(' ') + shortcut; - - if (name.size()) { - *pszName = QStringToBSTR(name); - return S_OK; - } - - *pszName = 0; - return S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::put_accName(VARIANT, BSTR) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - return DISP_E_MEMBERNOTFOUND; -} - -// moz: [important] -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accRole(VARIANT varID, VARIANT *pvarRole) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - QAccessible::Role role; - if (varID.lVal) { - QAccessibleInterface *child = childPointer(accessible, varID); - if (!child || !child->isValid()) - return E_FAIL; - role = child->role(); - } else { - role = accessible->role(); - } - - if (role != QAccessible::NoRole) { - if (role >= QAccessible::LayeredPane) { - // This block should hopefully only be entered if the AT client - // does not support IAccessible2, since it should prefer IA2::role() then. - if (role == QAccessible::LayeredPane) - role = QAccessible::Pane; - else if (role == QAccessible::WebDocument) - role = QAccessible::Document; - else - role = QAccessible::Client; - } - (*pvarRole).vt = VT_I4; - (*pvarRole).lVal = role; - } else { - (*pvarRole).vt = VT_EMPTY; - } - return S_OK; -} - -// moz: [important] -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accState(VARIANT varID, VARIANT *pvarState) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - QAccessible::State state; - if (varID.lVal) { - QAccessibleInterface *child = childPointer(accessible, varID); - if (!child || !child->isValid()) - return E_FAIL; - state = child->state(); - } else { - state = accessible->state(); - } - - LONG st = 0; - if (state.animated) - st |= STATE_SYSTEM_ANIMATED; - if (state.busy) - st |= STATE_SYSTEM_BUSY; - if (state.checked) - st |= STATE_SYSTEM_CHECKED; - if (state.collapsed) - st |= STATE_SYSTEM_COLLAPSED; - if (state.defaultButton) - st |= STATE_SYSTEM_DEFAULT; - if (state.expanded) - st |= STATE_SYSTEM_EXPANDED; - if (state.extSelectable) - st |= STATE_SYSTEM_EXTSELECTABLE; - if (state.focusable) - st |= STATE_SYSTEM_FOCUSABLE; - if (state.focused) - st |= STATE_SYSTEM_FOCUSED; - if (state.hasPopup) - st |= STATE_SYSTEM_HASPOPUP; - if (state.hotTracked) - st |= STATE_SYSTEM_HOTTRACKED; - if (state.invisible) - st |= STATE_SYSTEM_INVISIBLE; - if (state.linked) - st |= STATE_SYSTEM_LINKED; - if (state.marqueed) - st |= STATE_SYSTEM_MARQUEED; - if (state.checkStateMixed) - st |= STATE_SYSTEM_MIXED; - if (state.movable) - st |= STATE_SYSTEM_MOVEABLE; - if (state.multiSelectable) - st |= STATE_SYSTEM_MULTISELECTABLE; - if (state.offscreen) - st |= STATE_SYSTEM_OFFSCREEN; - if (state.pressed) - st |= STATE_SYSTEM_PRESSED; - if (state.passwordEdit) - st |= STATE_SYSTEM_PROTECTED; - if (state.readOnly) - st |= STATE_SYSTEM_READONLY; - if (state.selectable) - st |= STATE_SYSTEM_SELECTABLE; - if (state.selected) - st |= STATE_SYSTEM_SELECTED; - if (state.selfVoicing) - st |= STATE_SYSTEM_SELFVOICING; - if (state.sizeable) - st |= STATE_SYSTEM_SIZEABLE; - if (state.traversed) - st |= STATE_SYSTEM_TRAVERSED; - if (state.disabled) - st |= STATE_SYSTEM_UNAVAILABLE; - - (*pvarState).vt = VT_I4; - (*pvarState).lVal = st; - return S_OK; -} - -// moz: [important] -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accValue(VARIANT varID, BSTR* pszValue) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (varID.vt != VT_I4) - return E_INVALIDARG; - - if (!accessible || !accessible->isValid() || varID.lVal) { - return E_FAIL; - } - - QString value; - if (accessible->valueInterface()) { - value = accessible->valueInterface()->currentValue().toString(); - } else { - value = accessible->text(QAccessible::Value); - } - if (!value.isNull()) { - *pszValue = QStringToBSTR(value); - return S_OK; - } - - *pszValue = 0; - qCDebug(lcQpaAccessibility) << "return S_FALSE"; - return S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::put_accValue(VARIANT, BSTR value) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - - if (!accessible || !accessible->isValid()) { - return E_FAIL; - } - - QString qstrValue = QString::fromWCharArray(value); - - if (accessible->valueInterface()) { - accessible->valueInterface()->setCurrentValue(qstrValue); - } else { - accessible->setText(QAccessible::Value, qstrValue); - } - - return S_OK; -} - -// moz: [important] -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accSelect(long flagsSelect, VARIANT varID) -{ - Q_UNUSED(flagsSelect); - Q_UNUSED(varID); - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - bool res = false; - -/* - ### Check for accessibleTableInterface() or accessibleTextInterface() - - ### and if there are no ia2 interfaces we should do nothing?? - if (flagsSelect & SELFLAG_TAKEFOCUS) - res = accessible()->doAction(SetFocus, varID.lVal, QVariantList()); - if (flagsSelect & SELFLAG_TAKESELECTION) { - accessible()->doAction(ClearSelection, 0, QVariantList()); - res = accessible()->doAction(AddToSelection, varID.lVal, QVariantList()); - } - if (flagsSelect & SELFLAG_EXTENDSELECTION) - res = accessible()->doAction(ExtendSelection, varID.lVal, QVariantList()); - if (flagsSelect & SELFLAG_ADDSELECTION) - res = accessible()->doAction(AddToSelection, varID.lVal, QVariantList()); - if (flagsSelect & SELFLAG_REMOVESELECTION) - res = accessible()->doAction(RemoveSelection, varID.lVal, QVariantList()); -*/ - return res ? S_OK : S_FALSE; -} - -/*! - \internal - Can return: - - +-------------+------------------------------------------------------------------------------+ - | VT_EMPTY | None. Neither this object nor any of its children has the keyboard focus. | - +-------------+------------------------------------------------------------------------------+ - | VT_I4 | lVal is CHILDID_SELF. The object itself has the keyboard focus. | - +-------------+------------------------------------------------------------------------------+ - | VT_I4 | lVal contains the child ID of the child element that has the keyboard focus. | - +-------------+------------------------------------------------------------------------------+ - | VT_DISPATCH | pdispVal member is the address of the IDispatch interface for the child | - | | object that has the keyboard focus. | - +-------------+------------------------------------------------------------------------------+ - moz: [important] -*/ -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accFocus(VARIANT *pvarID) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - if (QAccessibleInterface *acc = accessible->focusChild()) { - if (acc == accessible) { - (*pvarID).vt = VT_I4; - (*pvarID).lVal = CHILDID_SELF; - return S_OK; - } else { - if (IAccessible *iface = QWindowsAccessibility::wrap(acc)) { - (*pvarID).vt = VT_DISPATCH; - (*pvarID).pdispVal = iface; - return S_OK; - } - } - } - (*pvarID).vt = VT_EMPTY; - return S_FALSE; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accSelection(VARIANT *pvarChildren) -{ - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - int cc = accessible->childCount(); - QVector<int> sel(cc); - int selIndex = 0; - for (int i = 0; i < cc; ++i) { - bool isSelected = false; - QAccessibleInterface *child = accessible->child(i); - if (child) { - isSelected = child->state().selected; - } - if (isSelected) - sel[selIndex++] = i+1; - } - sel.resize(selIndex); - if (sel.isEmpty()) { - (*pvarChildren).vt = VT_EMPTY; - return S_FALSE; - } - if (sel.size() == 1) { - (*pvarChildren).vt = VT_I4; - (*pvarChildren).lVal = sel[0]; - return S_OK; - } - IEnumVARIANT *iface = new QWindowsEnumerate(sel); - IUnknown *uiface; - iface->QueryInterface(IID_IUnknown, (void**)&uiface); - (*pvarChildren).vt = VT_UNKNOWN; - (*pvarChildren).punkVal = uiface; - - return S_OK; -} - -/**************************************************************\ - * IOleWindow * - **************************************************************/ -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::GetWindow(HWND *phwnd) -{ - *phwnd = 0; - QAccessibleInterface *accessible = accessibleInterface(); - accessibleDebugClientCalls(accessible); - if (!accessible) - return E_FAIL; - - QWindow *window = QWindowsAccessibility::windowHelper(accessible); - if (!window) - return E_FAIL; - - QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface(); - Q_ASSERT(platform); - *phwnd = (HWND)platform->nativeResourceForWindow("handle", window); - qCDebug(lcQpaAccessibility) << "QWindowsAccessible::GetWindow(): " << *phwnd; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::ContextSensitiveHelp(BOOL) -{ - return S_OK; -} - -const char *QWindowsAccessibleGuid::iidToString(const GUID &id) -{ - const char *result = nullptr; - if (id == IID_IUnknown) - result = "IID_IUnknown"; - else if (id == IID_IDispatch) - result = "IID_IDispatch"; - else if (id == IID_IAccessible) - result = "IID_IAccessible"; - else if (id == IID_IOleWindow) - result = "IID_IOleWindow"; - else if (id == IID_IServiceProvider) - result = "IID_IServiceProvider"; - else if (id == IID_IAccessible2) - result = "IID_IAccessible2"; - else if (id == IID_IAccessibleAction) - result = "IID_IAccessibleAction"; - else if (id == IID_IAccessibleApplication) - result = "IID_IAccessibleApplication"; - else if (id == IID_IAccessibleComponent) - result = "IID_IAccessibleComponent"; - else if (id == IID_IAccessibleEditableText) - result = "IID_IAccessibleEditableText"; - else if (id == IID_IAccessibleHyperlink) - result = "IID_IAccessibleHyperlink"; - else if (id == IID_IAccessibleHypertext) - result = "IID_IAccessibleHypertext"; - else if (id == IID_IAccessibleImage) - result = "IID_IAccessibleImage"; - else if (id == IID_IAccessibleRelation) - result = "IID_IAccessibleRelation"; - else if (id == IID_IAccessibleTable) - result = "IID_IAccessibleTable"; - else if (id == IID_IAccessibleTable2) - result = "IID_IAccessibleTable2"; - else if (id == IID_IAccessibleTableCell) - result = "IID_IAccessibleTableCell"; - else if (id == IID_IAccessibleText) - result = "IID_IAccessibleText"; - else if (id == IID_IAccessibleValue) - result = "IID_IAccessibleValue"; - return result; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug, const GUID &); - -QDebug operator<<(QDebug d, const QWindowsAccessibleGuid &aguid) -{ - QDebugStateSaver saver(d); - d.nospace(); - if (const char *ids = QWindowsAccessibleGuid::iidToString(aguid.guid())) - d << ids; - else - d << aguid.guid(); - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -QT_END_NAMESPACE - -#endif //QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h deleted file mode 100644 index 5380fc2411..0000000000 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QWINDOWSMSAAACCESSIBLE_H -#define QWINDOWSMSAAACCESSIBLE_H - -#include <QtCore/qglobal.h> -#ifndef QT_NO_ACCESSIBILITY - -#include <QtCore/qt_windows.h> -#include <QtCore/qsharedpointer.h> -#include <QtGui/qaccessible.h> -#include <oleacc.h> -#include "ia2_api_all.h" // IAccessible2 inherits from IAccessible - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_DEBUG_OUTPUT -#define DEBUG_SHOW_ATCLIENT_COMMANDS -#endif -#if defined(DEBUG_SHOW_ATCLIENT_COMMANDS) -void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleInterface *iface); -# define accessibleDebugClientCalls(iface) accessibleDebugClientCalls_helper(Q_FUNC_INFO, iface) -#else -# define accessibleDebugClientCalls(iface) -#endif - -QWindow *window_helper(const QAccessibleInterface *iface); - -class QWindowsAccessibleGuid // Helper for QDebug, outputs known ids by name. -{ -public: - explicit QWindowsAccessibleGuid(const GUID &g) : m_guid(g) {} - GUID guid () const { return m_guid; } - static const char *iidToString(const GUID &id); - -private: - GUID m_guid; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const QWindowsAccessibleGuid &aguid); -#endif - -/**************************************************************\ - * QWindowsAccessible * - **************************************************************/ - -class QWindowsMsaaAccessible : public IAccessible2, public IOleWindow -{ -public: - QWindowsMsaaAccessible(QAccessibleInterface *a) - : ref(0) - { - id = QAccessible::uniqueId(a); - } - - virtual ~QWindowsMsaaAccessible() - { - } - - /* IUnknown */ - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - - /* IDispatch */ - HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *); - HRESULT STDMETHODCALLTYPE GetTypeInfo(unsigned int, unsigned long, ITypeInfo **); - HRESULT STDMETHODCALLTYPE GetIDsOfNames(const _GUID &, wchar_t **, unsigned int, unsigned long, long *); - HRESULT STDMETHODCALLTYPE Invoke(long, const _GUID &, unsigned long, unsigned short, tagDISPPARAMS *, tagVARIANT *, tagEXCEPINFO *, unsigned int *); - - /* IAccessible */ - HRESULT STDMETHODCALLTYPE accHitTest(long xLeft, long yTop, VARIANT *pvarID); - HRESULT STDMETHODCALLTYPE accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID); - HRESULT STDMETHODCALLTYPE accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd); - HRESULT STDMETHODCALLTYPE get_accChild(VARIANT varChildID, IDispatch** ppdispChild); - HRESULT STDMETHODCALLTYPE get_accChildCount(long* pcountChildren); - HRESULT STDMETHODCALLTYPE get_accParent(IDispatch** ppdispParent); - - HRESULT STDMETHODCALLTYPE accDoDefaultAction(VARIANT varID); - HRESULT STDMETHODCALLTYPE get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction); - HRESULT STDMETHODCALLTYPE get_accDescription(VARIANT varID, BSTR* pszDescription); - HRESULT STDMETHODCALLTYPE get_accHelp(VARIANT varID, BSTR *pszHelp); - HRESULT STDMETHODCALLTYPE get_accHelpTopic(BSTR *pszHelpFile, VARIANT varChild, long *pidTopic); - HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut); - HRESULT STDMETHODCALLTYPE get_accName(VARIANT varID, BSTR* pszName); - HRESULT STDMETHODCALLTYPE put_accName(VARIANT varChild, BSTR szName); - HRESULT STDMETHODCALLTYPE get_accRole(VARIANT varID, VARIANT *pvarRole); - HRESULT STDMETHODCALLTYPE get_accState(VARIANT varID, VARIANT *pvarState); - HRESULT STDMETHODCALLTYPE get_accValue(VARIANT varID, BSTR* pszValue); - HRESULT STDMETHODCALLTYPE put_accValue(VARIANT varChild, BSTR szValue); - - HRESULT STDMETHODCALLTYPE accSelect(long flagsSelect, VARIANT varID); - HRESULT STDMETHODCALLTYPE get_accFocus(VARIANT *pvarID); - HRESULT STDMETHODCALLTYPE get_accSelection(VARIANT *pvarChildren); - - /* IOleWindow */ - HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd); - HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode); - -protected: - QAccessible::Id id; - - QAccessibleInterface *accessibleInterface() const - { - QAccessibleInterface *iface = QAccessible::accessibleInterface(id); - if (iface && iface->isValid()) - return iface; - return 0; - } - - static QAccessibleInterface *childPointer(QAccessibleInterface *parent, VARIANT varID) - { - // -1 since windows API always uses 1 for the first child - Q_ASSERT(parent); - - QAccessibleInterface *acc = 0; - int childIndex = varID.lVal; - if (childIndex == 0) { - // Yes, some AT clients (Active Accessibility Object Inspector) - // actually ask for the same object. As a consequence, we need to clone ourselves: - acc = parent; - } else if (childIndex < 0) { - acc = QAccessible::accessibleInterface((QAccessible::Id)childIndex); - } else { - acc = parent->child(childIndex - 1); - } - return acc; - } - -private: - ULONG ref; - -}; - -QT_END_NAMESPACE - -#endif //QT_NO_ACCESSIBILITY - -#endif // QWINDOWSMSAAACCESSIBLE_H diff --git a/src/plugins/platforms/windows/qwin10helpers.cpp b/src/plugins/platforms/windows/qwin10helpers.cpp index 12cccd124b..ac6a34d7c2 100644 --- a/src/plugins/platforms/windows/qwin10helpers.cpp +++ b/src/plugins/platforms/windows/qwin10helpers.cpp @@ -40,6 +40,7 @@ #include "qwin10helpers.h" #include <QtCore/QDebug> +#include <QtCore/QOperatingSystemVersion> #include <QtCore/private/qsystemlibrary_p.h> #if defined(Q_CC_MINGW) @@ -115,7 +116,7 @@ static QWindowsComBaseDLL baseComDll; bool QWindowsComBaseDLL::init() { - if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10 && !isValid()) { + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10 && !isValid()) { QSystemLibrary library(QStringLiteral("combase")); roGetActivationFactory = reinterpret_cast<RoGetActivationFactory>(library.resolve("RoGetActivationFactory")); diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index 49c7144221..80872c3ea3 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -93,7 +93,7 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion ®ion, // Windows with alpha: Use blend function to update. QRect r = QHighDpi::toNativePixels(window->frameGeometry(), window); QPoint frameOffset(QHighDpi::toNativePixels(QPoint(window->frameMargins().left(), window->frameMargins().top()), - static_cast<const QWindow *>(Q_NULLPTR))); + static_cast<const QWindow *>(nullptr))); QRect dirtyRect = br.translated(offset + frameOffset); SIZE size = {r.width(), r.height()}; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 9912e03cb9..c146f8ec25 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -53,7 +53,7 @@ #include "qwindowstheme.h" #include <private/qguiapplication_p.h> #ifndef QT_NO_ACCESSIBILITY -# include "accessible/qwindowsaccessibility.h" +# include "uiautomation/qwindowsuiaaccessibility.h" #endif #if QT_CONFIG(sessionmanager) # include <private/qsessionmanager_p.h> @@ -98,6 +98,7 @@ Q_LOGGING_CATEGORY(lcQpaDialogs, "qt.qpa.dialogs") Q_LOGGING_CATEGORY(lcQpaMenus, "qt.qpa.menus") Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") Q_LOGGING_CATEGORY(lcQpaAccessibility, "qt.qpa.accessibility") +Q_LOGGING_CATEGORY(lcQpaUiAutomation, "qt.qpa.uiautomation") Q_LOGGING_CATEGORY(lcQpaTrayIcon, "qt.qpa.trayicon") int QWindowsContext::verbose = 0; @@ -193,26 +194,14 @@ void QWindowsUser32DLL::init() getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences"); setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences"); - if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10) { // Appears in 10.0.14393, October 2016 + if (QOperatingSystemVersion::current() + >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 14393)) { enableNonClientDpiScaling = (EnableNonClientDpiScaling)library.resolve("EnableNonClientDpiScaling"); getWindowDpiAwarenessContext = (GetWindowDpiAwarenessContext)library.resolve("GetWindowDpiAwarenessContext"); getAwarenessFromDpiAwarenessContext = (GetAwarenessFromDpiAwarenessContext)library.resolve("GetAwarenessFromDpiAwarenessContext"); } } -bool QWindowsUser32DLL::initTouch() -{ - if (!isTouchWindow && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) { - QSystemLibrary library(QStringLiteral("user32")); - isTouchWindow = (IsTouchWindow)(library.resolve("IsTouchWindow")); - registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow")); - unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow")); - getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo")); - closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); - } - return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; -} - void QWindowsShcoreDLL::init() { if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1) @@ -269,7 +258,7 @@ QWindowsContextPrivate::QWindowsContextPrivate() QWindowsContext::user32dll.init(); QWindowsContext::shcoredll.init(); - if (m_mouseHandler.touchDevice() && QWindowsContext::user32dll.initTouch()) + if (m_mouseHandler.touchDevice()) m_systemInfo |= QWindowsContext::SI_SupportsTouch; m_displayContext = GetDC(0); m_defaultDPI = GetDeviceCaps(m_displayContext, LOGPIXELSY); @@ -327,11 +316,6 @@ bool QWindowsContext::initTouch(unsigned integrationOptions) if (!touchDevice) return false; - if (!QWindowsContext::user32dll.initTouch()) { - delete touchDevice; - return false; - } - if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); @@ -454,7 +438,7 @@ QString QWindowsContext::registerWindowClass(const QWindow *w) // QOpenGLWidget or QQuickWidget later on. That cannot be detected at this stage. if (w->surfaceType() == QSurface::OpenGLSurface || (flags & Qt::MSWindowsOwnDC)) style |= CS_OWNDC; - if (!(flags & Qt::NoDropShadowWindowHint) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) + if (!(flags & Qt::NoDropShadowWindowHint) && (type == Qt::Popup || w->property("_q_windowsDropShadow").toBool())) { style |= CS_DROPSHADOW; } @@ -757,7 +741,7 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn, // present in the MSVCRT.DLL found on Windows XP (QTBUG-35617). static inline QString errorMessageFromComError(const _com_error &comError) { - TCHAR *message = Q_NULLPTR; + TCHAR *message = nullptr; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, DWORD(comError.Error()), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), message, 0, NULL); @@ -872,7 +856,7 @@ static inline bool resizeOnDpiChanged(const QWindow *w) static bool shouldHaveNonClientDpiScaling(const QWindow *window) { - return QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10 + return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10 && window->isTopLevel() && !window->property(QWindowsWindow::embeddedNativeParentHandleProperty).isValid() #if QT_CONFIG(opengl) // /QTBUG-62901, EnableNonClientDpiScaling has problems with GL @@ -974,7 +958,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return false; case QtWindows::AccessibleObjectFromWindowRequest: #ifndef QT_NO_ACCESSIBILITY - return QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(hwnd, wParam, lParam, result); + return QWindowsUiaAccessibility::handleWmGetObject(hwnd, wParam, lParam, result); #else return false; #endif diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 5c39b6068b..f2ec307be2 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -66,6 +66,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaDialogs) Q_DECLARE_LOGGING_CATEGORY(lcQpaMenus) Q_DECLARE_LOGGING_CATEGORY(lcQpaTablet) Q_DECLARE_LOGGING_CATEGORY(lcQpaAccessibility) +Q_DECLARE_LOGGING_CATEGORY(lcQpaUiAutomation) Q_DECLARE_LOGGING_CATEGORY(lcQpaTrayIcon) class QWindow; @@ -84,13 +85,7 @@ class QTouchDevice; struct QWindowsUser32DLL { inline void init(); - inline bool initTouch(); - typedef BOOL (WINAPI *IsTouchWindow)(HWND, PULONG); // Windows 7 - typedef BOOL (WINAPI *RegisterTouchWindow)(HWND, ULONG); - typedef BOOL (WINAPI *UnregisterTouchWindow)(HWND); - typedef BOOL (WINAPI *GetTouchInputInfo)(HANDLE, UINT, PVOID, int); - typedef BOOL (WINAPI *CloseTouchInputHandle)(HANDLE); typedef BOOL (WINAPI *SetProcessDPIAware)(); typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND); typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND); @@ -100,13 +95,6 @@ struct QWindowsUser32DLL typedef int (WINAPI *GetWindowDpiAwarenessContext)(HWND); typedef int (WINAPI *GetAwarenessFromDpiAwarenessContext)(int); - // Touch functions from Windows 7 onwards (also for use with Q_CC_MSVC). - IsTouchWindow isTouchWindow = nullptr; - RegisterTouchWindow registerTouchWindow = nullptr; - UnregisterTouchWindow unregisterTouchWindow = nullptr; - GetTouchInputInfo getTouchInputInfo = nullptr; - CloseTouchInputHandle closeTouchInputHandle = nullptr; - // Windows Vista onwards SetProcessDPIAware setProcessDPIAware = nullptr; diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index e7ba08b719..a325b9d1d7 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -184,7 +184,7 @@ static HCURSOR createBitmapCursor(const QCursor &cursor, qreal scaleFactor = 1) return createBitmapCursor(bbits, mbits, cursor.hotSpot(), invb, invm); } -static QSize systemCursorSize(const QPlatformScreen *screen = Q_NULLPTR) +static QSize systemCursorSize(const QPlatformScreen *screen = nullptr) { const QSize primaryScreenCursorSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); if (screen) { diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 9aa9523ac8..8af56e4e0c 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -70,7 +70,7 @@ class CursorHandle { Q_DISABLE_COPY(CursorHandle) public: - explicit CursorHandle(HCURSOR hcursor = Q_NULLPTR) : m_hcursor(hcursor) {} + explicit CursorHandle(HCURSOR hcursor = nullptr) : m_hcursor(hcursor) {} ~CursorHandle() { if (m_hcursor) @@ -113,9 +113,9 @@ public: static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1); static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); } - static PixmapCursor customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR); + static PixmapCursor customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen = nullptr); - static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR); + static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen = nullptr); static QPoint mousePosition(); static CursorState cursorState(); diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index e713debf5b..1efb01d52e 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -601,8 +601,8 @@ QString QWindowsShellItem::path() const { if (isFileSystem()) return QDir::cleanPath(QWindowsShellItem::displayName(m_item, SIGDN_FILESYSPATH)); - // Check for a "Library" item (Windows 7) - if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7 && isDir()) + // Check for a "Library" item + if (isDir()) return QWindowsShellItem::libraryItemDefaultSaveFolder(m_item); return QString(); } @@ -713,7 +713,7 @@ QString QWindowsShellItem::libraryItemDefaultSaveFolder(IShellItem *item) { QString result; if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) { - IShellItem *item = Q_NULLPTR; + IShellItem *item = nullptr; if (SUCCEEDED(library->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem, reinterpret_cast<void **>(&item)))) { result = QDir::cleanPath(QWindowsShellItem::displayName(item, SIGDN_FILESYSPATH)); item->Release(); @@ -895,7 +895,7 @@ void QWindowsNativeFileDialogBase::setWindowTitle(const QString &title) IShellItem *QWindowsNativeFileDialogBase::shellItem(const QUrl &url) { if (url.isLocalFile()) { - IShellItem *result = Q_NULLPTR; + IShellItem *result = nullptr; const QString native = QDir::toNativeSeparators(url.toLocalFile()); const HRESULT hr = SHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()), @@ -903,30 +903,30 @@ IShellItem *QWindowsNativeFileDialogBase::shellItem(const QUrl &url) reinterpret_cast<void **>(&result)); if (FAILED(hr)) { qErrnoWarning("%s: SHCreateItemFromParsingName(%s)) failed", __FUNCTION__, qPrintable(url.toString())); - return Q_NULLPTR; + return nullptr; } return result; } else if (url.scheme() == QLatin1String("clsid")) { // Support for virtual folders via GUID // (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx) // specified as "clsid:<GUID>" (without '{', '}'). - IShellItem *result = Q_NULLPTR; + IShellItem *result = nullptr; const auto uuid = QUuid::fromString(url.path()); if (uuid.isNull()) { qWarning() << __FUNCTION__ << ": Invalid CLSID: " << url.path(); - return Q_NULLPTR; + return nullptr; } PIDLIST_ABSOLUTE idList; HRESULT hr = SHGetKnownFolderIDList(uuid, 0, 0, &idList); if (FAILED(hr)) { qErrnoWarning("%s: SHGetKnownFolderIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString())); - return Q_NULLPTR; + return nullptr; } hr = SHCreateItemFromIDList(idList, IID_IShellItem, reinterpret_cast<void **>(&result)); CoTaskMemFree(idList); if (FAILED(hr)) { qErrnoWarning("%s: SHCreateItemFromIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString())); - return Q_NULLPTR; + return nullptr; } return result; } else { @@ -2047,7 +2047,7 @@ bool useHelper(QPlatformTheme::DialogType type) return false; switch (type) { case QPlatformTheme::FileDialog: - return QSysInfo::windowsVersion() >= QSysInfo::WV_XP; + return true; case QPlatformTheme::ColorDialog: #ifdef USE_NATIVE_COLOR_DIALOG return true; @@ -2068,13 +2068,10 @@ QPlatformDialogHelper *createHelper(QPlatformTheme::DialogType type) if (QWindowsIntegration::instance()->options() & QWindowsIntegration::NoNativeDialogs) return 0; switch (type) { - case QPlatformTheme::FileDialog: // Note: "Windows XP Professional x64 Edition has version number WV_5_2 (WV_2003). - if (QWindowsIntegration::instance()->options() & QWindowsIntegration::XpNativeDialogs - || QSysInfo::windowsVersion() <= QSysInfo::WV_2003) { + case QPlatformTheme::FileDialog: + if (QWindowsIntegration::instance()->options() & QWindowsIntegration::XpNativeDialogs) return new QWindowsXpFileDialogHelper(); - } - if (QSysInfo::windowsVersion() > QSysInfo::WV_2003) - return new QWindowsFileDialogHelper(); + return new QWindowsFileDialogHelper; case QPlatformTheme::ColorDialog: #ifdef USE_NATIVE_COLOR_DIALOG return new QWindowsColorDialogHelper(); diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 47878a7169..3e5f2c81d5 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -95,7 +95,7 @@ struct QWindowsLibGLESv2 #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) void *moduleHandle() const { return m_lib; } #else - void *moduleHandle() const { return Q_NULLPTR; } + void *moduleHandle() const { return nullptr; } #endif const GLubyte * (APIENTRY * glGetString)(GLenum name); diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 78368d87de..4bdf3167e4 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -379,9 +379,7 @@ static PIXELFORMATDESCRIPTOR initPixelFormatDescriptor(&pfd); pfd.iPixelType = PFD_TYPE_RGBA; pfd.iLayerType = PFD_MAIN_PLANE; - pfd.dwFlags = PFD_SUPPORT_OPENGL; - if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA) - pfd.dwFlags = PFD_SUPPORT_COMPOSITION; + pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_SUPPORT_COMPOSITION; const bool isPixmap = (additional.formatFlags & QWindowsGLRenderToPixmap) != 0; pfd.dwFlags |= isPixmap ? PFD_DRAW_TO_BITMAP : PFD_DRAW_TO_WINDOW; if (!(additional.formatFlags & QWindowsGLDirectRendering)) diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 8c228f588e..b9dd2c557e 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -221,6 +221,28 @@ void QWindowsInputContext::setFocusObject(QObject *) updateEnabled(); } +HWND QWindowsInputContext::getVirtualKeyboardWindowHandle() const +{ + return ::FindWindowA("IPTip_Main_Window", nullptr); +} + +QRectF QWindowsInputContext::keyboardRect() const +{ + if (HWND hwnd = getVirtualKeyboardWindowHandle()) { + RECT rect; + if (::GetWindowRect(hwnd, &rect)) { + return QRectF(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); + } + } + return QRectF(); +} + +bool QWindowsInputContext::isInputPanelVisible() const +{ + HWND hwnd = getVirtualKeyboardWindowHandle(); + return hwnd && ::IsWindowEnabled(hwnd) && ::IsWindowVisible(hwnd); +} + void QWindowsInputContext::updateEnabled() { if (!QGuiApplication::focusObject()) diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h index 617ef30cef..ada1fc0d29 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.h +++ b/src/plugins/platforms/windows/qwindowsinputcontext.h @@ -79,6 +79,9 @@ public: void invokeAction(QInputMethod::Action, int cursorPosition) override; void setFocusObject(QObject *object) override; + QRectF keyboardRect() const override; + bool isInputPanelVisible() const override; + bool startComposition(HWND hwnd); bool composition(HWND hwnd, LPARAM lParam); bool endComposition(HWND hwnd); @@ -98,6 +101,7 @@ private: void startContextComposition(); void endContextComposition(); void updateEnabled(); + HWND getVirtualKeyboardWindowHandle() const; const DWORD m_WM_MSIME_MOUSE; static HIMC m_defaultContext; diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index f9bac3920b..287b65cd5d 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -60,7 +60,7 @@ #include "qwindowsinputcontext.h" #include "qwindowskeymapper.h" #ifndef QT_NO_ACCESSIBILITY -# include "accessible/qwindowsaccessibility.h" +# include "uiautomation/qwindowsuiaaccessibility.h" #endif #include <qpa/qplatformnativeinterface.h> @@ -151,7 +151,7 @@ struct QWindowsIntegrationPrivate #endif // QT_NO_OPENGL QScopedPointer<QPlatformInputContext> m_inputContext; #ifndef QT_NO_ACCESSIBILITY - QWindowsAccessibility m_accessibility; + QWindowsUiaAccessibility m_accessibility; #endif QWindowsServices m_services; }; @@ -252,7 +252,7 @@ QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() delete m_fontDatabase; } -QWindowsIntegration *QWindowsIntegration::m_instance = Q_NULLPTR; +QWindowsIntegration *QWindowsIntegration::m_instance = nullptr; QWindowsIntegration::QWindowsIntegration(const QStringList ¶mList) : d(new QWindowsIntegrationPrivate(paramList)) @@ -266,7 +266,7 @@ QWindowsIntegration::QWindowsIntegration(const QStringList ¶mList) : QWindowsIntegration::~QWindowsIntegration() { - m_instance = Q_NULLPTR; + m_instance = nullptr; } void QWindowsIntegration::initialize() @@ -336,7 +336,7 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons << " handle=" << obtained.hwnd << ' ' << obtained.flags << '\n'; if (Q_UNLIKELY(!obtained.hwnd)) - return Q_NULLPTR; + return nullptr; QWindowsWindow *result = createPlatformWindowHelper(window, obtained); Q_ASSERT(result); @@ -356,7 +356,7 @@ QPlatformWindow *QWindowsIntegration::createForeignWindow(QWindow *window, WId n } QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd); const QRect obtainedGeometry = result->geometry(); - QScreen *screen = Q_NULLPTR; + QScreen *screen = nullptr; if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry)) screen = pScreen->screen(); if (screen && screen != window->screen()) @@ -402,7 +402,7 @@ QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate() qCWarning(lcQpaGl, "Software OpenGL failed. Falling back to system OpenGL."); if (QWindowsOpenGLTester::supportedRenderers() & QWindowsOpenGLTester::DesktopGl) return QOpenGLStaticContext::create(); - return Q_NULLPTR; + return nullptr; default: break; } diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 9544fb81f7..814291c54a 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -56,37 +56,6 @@ #include <windowsx.h> -/* Touch is supported from Windows 7 onwards and data structures - * are present in the Windows SDK's, but not in older MSVC Express - * versions. */ - -#if !defined(TOUCHEVENTF_MOVE) - -typedef struct tagTOUCHINPUT { - LONG x; - LONG y; - HANDLE hSource; - DWORD dwID; - DWORD dwFlags; - DWORD dwMask; - DWORD dwTime; - ULONG_PTR dwExtraInfo; - DWORD cxContact; - DWORD cyContact; -} TOUCHINPUT, *PTOUCHINPUT; -typedef TOUCHINPUT const * PCTOUCHINPUT; - -# define TOUCHEVENTF_MOVE 0x0001 -# define TOUCHEVENTF_DOWN 0x0002 -# define TOUCHEVENTF_UP 0x0004 -# define TOUCHEVENTF_INRANGE 0x0008 -# define TOUCHEVENTF_PRIMARY 0x0010 -# define TOUCHEVENTF_NOCOALESCE 0x0020 -# define TOUCHEVENTF_PALM 0x0080 -# define TOUCHINPUTMASKF_CONTACTAREA 0x0004 -# define TOUCHINPUTMASKF_EXTRAINFO 0x0002 -#endif // if !defined(TOUCHEVENTF_MOVE) - QT_BEGIN_NAMESPACE static inline void compressMouseMove(MSG *msg) @@ -154,8 +123,6 @@ static inline QTouchDevice *createTouchDevice() QT_NID_INTEGRATED_TOUCH = 0x1, QT_NID_EXTERNAL_TOUCH = 0x02, QT_NID_MULTI_INPUT = 0x40, QT_NID_READY = 0x80 }; - if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS7) - return 0; const int digitizers = GetSystemMetrics(QT_SM_DIGITIZER); if (!(digitizers & (QT_NID_INTEGRATED_TOUCH | QT_NID_EXTERNAL_TOUCH))) return 0; @@ -523,9 +490,8 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, touchPoints.reserve(winTouchPointCount); Qt::TouchPointStates allStates = 0; - QWindowsContext::user32dll.getTouchInputInfo(reinterpret_cast<HANDLE>(msg.lParam), - UINT(msg.wParam), - winTouchInputs.data(), sizeof(TOUCHINPUT)); + GetTouchInputInfo(reinterpret_cast<HTOUCHINPUT>(msg.lParam), + UINT(msg.wParam), winTouchInputs.data(), sizeof(TOUCHINPUT)); for (int i = 0; i < winTouchPointCount; ++i) { const TOUCHINPUT &winTouchInput = winTouchInputs[i]; int id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1); @@ -566,7 +532,7 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, touchPoints.append(touchPoint); } - QWindowsContext::user32dll.closeTouchInputHandle(reinterpret_cast<HANDLE>(msg.lParam)); + CloseTouchInputHandle(reinterpret_cast<HTOUCHINPUT>(msg.lParam)); // all touch points released, forget the ids we've seen, they may not be reused if (allStates == Qt::TouchPointReleased) diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index dc8e97c886..324b00144e 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -134,7 +134,7 @@ void *QWindowsNativeInterface::nativeResourceForCursor(const QByteArray &resourc return static_cast<const QWindowsCursor *>(pCursor)->hCursor(cursor); } } - return Q_NULLPTR; + return nullptr; } #endif // !QT_NO_CURSOR @@ -280,7 +280,7 @@ QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &fun return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic); else if (function == QWindowsWindowFunctions::isTabletModeIdentifier()) return QFunctionPointer(QWindowsNativeInterface::isTabletMode); - return Q_NULLPTR; + return nullptr; } QVariant QWindowsNativeInterface::gpu() const diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index cfddb3cc71..c0781df973 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -563,7 +563,7 @@ const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const if (scr->geometry().contains(p)) return scr; } - return Q_NULLPTR; + return nullptr; } const QWindowsScreen *QWindowsScreenManager::screenForHwnd(HWND hwnd) const diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 1d81fa9cd5..33815eeb54 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -37,6 +37,13 @@ ** ****************************************************************************/ +#if defined(WINVER) && WINVER < 0x0601 +# undef WINVER +#endif +#if !defined(WINVER) +# define WINVER 0x0601 // Enable touch functions for MinGW +#endif + #include "qwindowswindow.h" #include "qwindowscontext.h" #if QT_CONFIG(draganddrop) @@ -858,7 +865,7 @@ QWindowsBaseWindow *QWindowsBaseWindow::baseWindowOf(const QWindow *w) if (QPlatformWindow *pw = w->handle()) return static_cast<QWindowsBaseWindow *>(pw); } - return Q_NULLPTR; + return nullptr; } HWND QWindowsBaseWindow::handleOf(const QWindow *w) @@ -1113,7 +1120,7 @@ QWindowsWindow::~QWindowsWindow() { setFlag(WithinDestroy); if (testFlag(TouchRegistered)) - QWindowsContext::user32dll.unregisterTouchWindow(m_data.hwnd); + UnregisterTouchWindow(m_data.hwnd); destroyWindow(); destroyIcon(); } @@ -2600,12 +2607,12 @@ void QWindowsWindow::registerTouchWindow(QWindowsWindowFunctions::TouchWindowTou if ((QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch) && !testFlag(TouchRegistered)) { ULONG touchFlags = 0; - const bool ret = QWindowsContext::user32dll.isTouchWindow(m_data.hwnd, &touchFlags); + const bool ret = IsTouchWindow(m_data.hwnd, &touchFlags); // Return if it is not a touch window or the flags are already set by a hook // such as HCBT_CREATEWND if (ret || touchFlags != 0) return; - if (QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, ULONG(touchTypes))) + if (RegisterTouchWindow(m_data.hwnd, ULONG(touchTypes))) setFlag(TouchRegistered); else qErrnoWarning("RegisterTouchWindow() failed for window '%s'.", qPrintable(window()->objectName())); diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp new file mode 100644 index 0000000000..907883bf5b --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiaaccessibility.h" +#include "qwindowsuiamainprovider.h" +#include "qwindowsuiautils.h" + +#include <QtGui/QAccessible> +#include <QtGui/QWindow> +#include <QtGui/QGuiApplication> +#include <QtGui/private/qguiapplication_p.h> +#include <QtCore/qt_windows.h> +#include <qpa/qplatformintegration.h> +#include <QtWindowsUIAutomationSupport/private/qwindowsuiawrapper_p.h> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaAccessibility::QWindowsUiaAccessibility() +{ +} + +QWindowsUiaAccessibility::~QWindowsUiaAccessibility() +{ +} + +// Handles UI Automation window messages. +bool QWindowsUiaAccessibility::handleWmGetObject(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult) +{ + if (lParam == LPARAM(UiaRootObjectId)) { + + // Start handling accessibility internally + QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true); + + // Ignoring all requests while starting up / shutting down + if (QCoreApplication::startingUp() || QCoreApplication::closingDown()) + return false; + + if (QWindow *window = QWindowsContext::instance()->findWindow(hwnd)) { + if (QAccessibleInterface *accessible = window->accessibleRoot()) { + QWindowsUiaMainProvider *provider = QWindowsUiaMainProvider::providerForAccessible(accessible); + *lResult = QWindowsUiaWrapper::instance()->returnRawElementProvider(hwnd, wParam, lParam, provider); + return true; + } + } + } + return false; +} + +// Handles accessibility update notifications. +void QWindowsUiaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) +{ + if (!event) + return; + + QAccessibleInterface *accessible = event->accessibleInterface(); + if (!isActive() || !accessible || !accessible->isValid()) + return; + + // Ensures QWindowsUiaWrapper is properly initialized. + if (!QWindowsUiaWrapper::instance()->ready()) + return; + + // No need to do anything when nobody is listening. + if (!QWindowsUiaWrapper::instance()->clientsAreListening()) + return; + + switch (event->type()) { + + case QAccessible::Focus: + QWindowsUiaMainProvider::notifyFocusChange(event); + break; + + case QAccessible::StateChanged: + QWindowsUiaMainProvider::notifyStateChange(static_cast<QAccessibleStateChangeEvent *>(event)); + break; + + case QAccessible::ValueChanged: + QWindowsUiaMainProvider::notifyValueChange(static_cast<QAccessibleValueChangeEvent *>(event)); + break; + + case QAccessible::TextAttributeChanged: + case QAccessible::TextColumnChanged: + case QAccessible::TextInserted: + case QAccessible::TextRemoved: + case QAccessible::TextUpdated: + case QAccessible::TextSelectionChanged: + case QAccessible::TextCaretMoved: + QWindowsUiaMainProvider::notifyTextChange(event); + break; + + default: + break; + } +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.h index 8621e93120..bbb81d596b 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaaccessibility.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -37,27 +37,29 @@ ** ****************************************************************************/ -#ifndef QWINDOWSACCESSIBILITY_H -#define QWINDOWSACCESSIBILITY_H +#ifndef QWINDOWSUIAACCESSIBILITY_H +#define QWINDOWSUIAACCESSIBILITY_H -#include "../qtwindowsglobal.h" -#include "../qwindowscontext.h" -#include <qpa/qplatformaccessibility.h> +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY -#include <oleacc.h> +#include "qwindowscontext.h" +#include <qpa/qplatformaccessibility.h> QT_BEGIN_NAMESPACE -class QWindowsAccessibility : public QPlatformAccessibility +// Windows plataform accessibility implemented over UI Automation. +class QWindowsUiaAccessibility : public QPlatformAccessibility { public: - QWindowsAccessibility(); - static bool handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult); + explicit QWindowsUiaAccessibility(); + virtual ~QWindowsUiaAccessibility(); + static bool handleWmGetObject(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult); void notifyAccessibilityUpdate(QAccessibleEvent *event) override; - static IAccessible *wrap(QAccessibleInterface *acc); - static QWindow *windowHelper(const QAccessibleInterface *iface); }; QT_END_NAMESPACE -#endif // QWINDOWSACCESSIBILITY_H +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIAACCESSIBILITY_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.cpp new file mode 100644 index 0000000000..1e1fc49c0f --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaBaseProvider::QWindowsUiaBaseProvider(QAccessible::Id id) : + m_id(id) +{ +} + +QWindowsUiaBaseProvider::~QWindowsUiaBaseProvider() +{ +} + +QAccessibleInterface *QWindowsUiaBaseProvider::accessibleInterface() const +{ + QAccessibleInterface *accessible = QAccessible::accessibleInterface(m_id); + if (accessible && accessible->isValid()) + return accessible; + return nullptr; +} + +QAccessible::Id QWindowsUiaBaseProvider::id() const +{ + return m_id; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h new file mode 100644 index 0000000000..3ae403e8c5 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiabaseprovider.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIABASEPROVIDER_H +#define QWINDOWSUIABASEPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QPointer> + +#include <qwindowscombase.h> +#include <QtWindowsUIAutomationSupport/private/qwindowsuiawrapper_p.h> + +QT_BEGIN_NAMESPACE + +class QAccessibleInterface; +class QDebug; + +// Base class for UI Automation providers. +class QWindowsUiaBaseProvider : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(QWindowsUiaBaseProvider) +public: + explicit QWindowsUiaBaseProvider(QAccessible::Id id); + virtual ~QWindowsUiaBaseProvider(); + + QAccessibleInterface *accessibleInterface() const; + QAccessible::Id id() const; + +private: + QAccessible::Id m_id; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIABASEPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.cpp new file mode 100644 index 0000000000..e0502c00f3 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.cpp @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiagriditemprovider.h" +#include "qwindowsuiamainprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaGridItemProvider::QWindowsUiaGridItemProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaGridItemProvider::~QWindowsUiaGridItemProvider() +{ +} + +// Returns the row index of the item. +HRESULT STDMETHODCALLTYPE QWindowsUiaGridItemProvider::get_Row(int *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = 0; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface(); + if (!tableCellInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = tableCellInterface->rowIndex(); + return S_OK; +} + +// Returns the column index of the item. +HRESULT STDMETHODCALLTYPE QWindowsUiaGridItemProvider::get_Column(int *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = 0; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface(); + if (!tableCellInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = tableCellInterface->columnIndex(); + return S_OK; +} + +// Returns the number of rows occupied by the item. +HRESULT STDMETHODCALLTYPE QWindowsUiaGridItemProvider::get_RowSpan(int *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = 0; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface(); + if (!tableCellInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = tableCellInterface->rowExtent(); + return S_OK; +} + +// Returns the number of columns occupied by the item. +HRESULT STDMETHODCALLTYPE QWindowsUiaGridItemProvider::get_ColumnSpan(int *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = 0; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface(); + if (!tableCellInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = tableCellInterface->columnExtent(); + return S_OK; +} + +// Returns the provider for the cointaining table/tree. +HRESULT STDMETHODCALLTYPE QWindowsUiaGridItemProvider::get_ContainingGrid(IRawElementProviderSimple **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface(); + if (!tableCellInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + if (QAccessibleInterface *table = tableCellInterface->table()) { + *pRetVal = QWindowsUiaMainProvider::providerForAccessible(table); + } + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h new file mode 100644 index 0000000000..a93b50ef97 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiagriditemprovider.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIAGRIDITEMPROVIDER_H +#define QWINDOWSUIAGRIDITEMPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Grid Item control pattern provider. Used by items within a table/tree. +class QWindowsUiaGridItemProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<IGridItemProvider> +{ + Q_DISABLE_COPY(QWindowsUiaGridItemProvider) +public: + explicit QWindowsUiaGridItemProvider(QAccessible::Id id); + virtual ~QWindowsUiaGridItemProvider(); + + // IGridItemProvider + HRESULT STDMETHODCALLTYPE get_Row(int *pRetVal); + HRESULT STDMETHODCALLTYPE get_Column(int *pRetVal); + HRESULT STDMETHODCALLTYPE get_RowSpan(int *pRetVal); + HRESULT STDMETHODCALLTYPE get_ColumnSpan(int *pRetVal); + HRESULT STDMETHODCALLTYPE get_ContainingGrid(IRawElementProviderSimple **pRetVal); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIAGRIDITEMPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.cpp new file mode 100644 index 0000000000..65c2df703b --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiagridprovider.h" +#include "qwindowsuiamainprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaGridProvider::QWindowsUiaGridProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaGridProvider::~QWindowsUiaGridProvider() +{ +} + +// Returns the provider for an item within a table/tree. +HRESULT STDMETHODCALLTYPE QWindowsUiaGridProvider::GetItem(int row, int column, IRawElementProviderSimple **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableInterface *tableInterface = accessible->tableInterface(); + if (!tableInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + if ((row >= 0) && (row < tableInterface->rowCount()) && (column >= 0) && (column < tableInterface->columnCount())) { + if (QAccessibleInterface *cell = tableInterface->cellAt(row, column)) { + *pRetVal = QWindowsUiaMainProvider::providerForAccessible(cell); + } + } + return S_OK; +} + +// Returns the number of rows. +HRESULT STDMETHODCALLTYPE QWindowsUiaGridProvider::get_RowCount(int *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = 0; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableInterface *tableInterface = accessible->tableInterface(); + if (!tableInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = tableInterface->rowCount(); + return S_OK; +} + +// Returns the number of columns. +HRESULT STDMETHODCALLTYPE QWindowsUiaGridProvider::get_ColumnCount(int *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = 0; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableInterface *tableInterface = accessible->tableInterface(); + if (!tableInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = tableInterface->columnCount(); + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h new file mode 100644 index 0000000000..15521f98b3 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiagridprovider.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIAGRIDPROVIDER_H +#define QWINDOWSUIAGRIDPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Grid control pattern provider. Used by tables/trees. +class QWindowsUiaGridProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<IGridProvider> +{ + Q_DISABLE_COPY(QWindowsUiaGridProvider) +public: + explicit QWindowsUiaGridProvider(QAccessible::Id id); + virtual ~QWindowsUiaGridProvider(); + + // IGridProvider + HRESULT STDMETHODCALLTYPE GetItem(int row, int column, IRawElementProviderSimple **pRetVal); + HRESULT STDMETHODCALLTYPE get_RowCount(int *pRetVal); + HRESULT STDMETHODCALLTYPE get_ColumnCount(int *pRetVal); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIAGRIDPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.cpp new file mode 100644 index 0000000000..2af883c4f6 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiainvokeprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaInvokeProvider::QWindowsUiaInvokeProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaInvokeProvider::~QWindowsUiaInvokeProvider() +{ +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaInvokeProvider::Invoke() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleActionInterface *actionInterface = accessible->actionInterface(); + if (!actionInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + actionInterface->doAction(QAccessibleActionInterface::pressAction()); + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h new file mode 100644 index 0000000000..2b8a646983 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiainvokeprovider.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIAINVOKEPROVIDER_H +#define QWINDOWSUIAINVOKEPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Invoke control pattern provider. +class QWindowsUiaInvokeProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<IInvokeProvider> +{ + Q_DISABLE_COPY(QWindowsUiaInvokeProvider) +public: + explicit QWindowsUiaInvokeProvider(QAccessible::Id id); + virtual ~QWindowsUiaInvokeProvider(); + + // IInvokeProvider + HRESULT STDMETHODCALLTYPE Invoke(); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIAINVOKEPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp new file mode 100644 index 0000000000..46f73f81a0 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp @@ -0,0 +1,638 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiamainprovider.h" +#include "qwindowsuiavalueprovider.h" +#include "qwindowsuiarangevalueprovider.h" +#include "qwindowsuiatextprovider.h" +#include "qwindowsuiatoggleprovider.h" +#include "qwindowsuiainvokeprovider.h" +#include "qwindowsuiaselectionprovider.h" +#include "qwindowsuiaselectionitemprovider.h" +#include "qwindowsuiatableprovider.h" +#include "qwindowsuiatableitemprovider.h" +#include "qwindowsuiagridprovider.h" +#include "qwindowsuiagriditemprovider.h" +#include "qwindowscombase.h" +#include "qwindowscontext.h" +#include "qwindowsuiautils.h" +#include "qwindowsuiaprovidercache.h" + +#include <QtCore/QDebug> +#include <QtGui/QAccessible> +#include <QtGui/QGuiApplication> +#include <QtGui/QWindow> + +#if !defined(Q_CC_BOR) && !defined (Q_CC_GNU) +#include <comdef.h> +#endif + +#include <QtCore/qt_windows.h> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +// Returns a cached instance of the provider for a specific acessible interface. +QWindowsUiaMainProvider *QWindowsUiaMainProvider::providerForAccessible(QAccessibleInterface *accessible) +{ + if (!accessible) + return nullptr; + + QAccessible::Id id = QAccessible::uniqueId(accessible); + QWindowsUiaProviderCache *providerCache = QWindowsUiaProviderCache::instance(); + QWindowsUiaMainProvider *provider = qobject_cast<QWindowsUiaMainProvider *>(providerCache->providerForId(id)); + + if (provider) { + provider->AddRef(); + } else { + provider = new QWindowsUiaMainProvider(accessible); + providerCache->insert(id, provider); + } + return provider; +} + +QWindowsUiaMainProvider::QWindowsUiaMainProvider(QAccessibleInterface *a, int initialRefCount) + : QWindowsUiaBaseProvider(QAccessible::uniqueId(a)), + m_ref(initialRefCount) +{ +} + +QWindowsUiaMainProvider::~QWindowsUiaMainProvider() +{ +} + +void QWindowsUiaMainProvider::notifyFocusChange(QAccessibleEvent *event) +{ + if (QAccessibleInterface *accessible = event->accessibleInterface()) { + if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) { + QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_AutomationFocusChangedEventId); + } + } +} + +void QWindowsUiaMainProvider::notifyStateChange(QAccessibleStateChangeEvent *event) +{ + if (QAccessibleInterface *accessible = event->accessibleInterface()) { + if (event->changedStates().checked || event->changedStates().checkStateMixed) { + // Notifies states changes in checkboxes. + if (accessible->role() == QAccessible::CheckBox) { + if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) { + VARIANT oldVal, newVal; + clearVariant(&oldVal); + int toggleState = ToggleState_Off; + if (accessible->state().checked) + toggleState = accessible->state().checkStateMixed ? ToggleState_Indeterminate : ToggleState_On; + setVariantI4(toggleState, &newVal); + QWindowsUiaWrapper::instance()->raiseAutomationPropertyChangedEvent(provider, UIA_ToggleToggleStatePropertyId, oldVal, newVal); + } + } + } + if (event->changedStates().active) { + if (accessible->role() == QAccessible::Window) { + // Notifies window opened/closed. + if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) { + if (accessible->state().active) { + QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_Window_WindowOpenedEventId); + } else { + QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_Window_WindowClosedEventId); + } + } + } + } + } +} + +void QWindowsUiaMainProvider::notifyValueChange(QAccessibleValueChangeEvent *event) +{ + if (QAccessibleInterface *accessible = event->accessibleInterface()) { + if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) { + // Notifies changes in values of controls supporting the value interface. + if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) { + VARIANT oldVal, newVal; + clearVariant(&oldVal); + setVariantDouble(valueInterface->currentValue().toDouble(), &newVal); + QWindowsUiaWrapper::instance()->raiseAutomationPropertyChangedEvent(provider, UIA_RangeValueValuePropertyId, oldVal, newVal); + } + } + } +} + +// Notifies changes in text content and selection state of text controls. +void QWindowsUiaMainProvider::notifyTextChange(QAccessibleEvent *event) +{ + if (QAccessibleInterface *accessible = event->accessibleInterface()) { + if (accessible->textInterface()) { + if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) { + if (event->type() == QAccessible::TextSelectionChanged) { + QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_Text_TextSelectionChangedEventId); + } else if (event->type() == QAccessible::TextCaretMoved) { + if (!accessible->state().readOnly) { + QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_Text_TextSelectionChangedEventId); + } + } else { + QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_Text_TextChangedEventId); + } + } + } + } +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaMainProvider::QueryInterface(REFIID iid, LPVOID *iface) +{ + if (!iface) + return E_INVALIDARG; + *iface = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + + const bool result = qWindowsComQueryUnknownInterfaceMulti<IRawElementProviderSimple>(this, iid, iface) + || qWindowsComQueryInterface<IRawElementProviderSimple>(this, iid, iface) + || qWindowsComQueryInterface<IRawElementProviderFragment>(this, iid, iface) + || (accessible && hwndForAccessible(accessible) && qWindowsComQueryInterface<IRawElementProviderFragmentRoot>(this, iid, iface)); + return result ? S_OK : E_NOINTERFACE; +} + +ULONG QWindowsUiaMainProvider::AddRef() +{ + return ++m_ref; +} + +ULONG STDMETHODCALLTYPE QWindowsUiaMainProvider::Release() +{ + if (!--m_ref) { + delete this; + return 0; + } + return m_ref; +} + +HRESULT QWindowsUiaMainProvider::get_ProviderOptions(ProviderOptions *pRetVal) +{ + if (!pRetVal) + return E_INVALIDARG; + // We are STA, (OleInitialize()). + *pRetVal = static_cast<ProviderOptions>(ProviderOptions_ServerSideProvider | ProviderOptions_UseComThreading); + return S_OK; +} + +// Return providers for specific control patterns +HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknown **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << idPattern; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + switch (idPattern) { + case UIA_TextPatternId: + case UIA_TextPattern2Id: + // All text controls. + if (accessible->textInterface()) { + *pRetVal = new QWindowsUiaTextProvider(id()); + } + break; + case UIA_ValuePatternId: + // All accessible controls return text(QAccessible::Value) (which may be empty). + *pRetVal = new QWindowsUiaValueProvider(id()); + break; + case UIA_RangeValuePatternId: + // Controls providing a numeric value within a range (e.g., sliders, scroll bars, dials). + if (accessible->valueInterface()) { + *pRetVal = new QWindowsUiaRangeValueProvider(id()); + } + break; + case UIA_TogglePatternId: + // Checkbox controls. + if (accessible->role() == QAccessible::CheckBox) { + *pRetVal = new QWindowsUiaToggleProvider(id()); + } + break; + case UIA_SelectionPatternId: + // Lists of items. + if (accessible->role() == QAccessible::List) { + *pRetVal = new QWindowsUiaSelectionProvider(id()); + } + break; + case UIA_SelectionItemPatternId: + // Items within a list and radio buttons. + if ((accessible->role() == QAccessible::RadioButton) + || (accessible->role() == QAccessible::ListItem)) { + *pRetVal = new QWindowsUiaSelectionItemProvider(id()); + } + break; + case UIA_TablePatternId: + // Table/tree. + if (accessible->tableInterface() + && ((accessible->role() == QAccessible::Table) || (accessible->role() == QAccessible::Tree))) { + *pRetVal = new QWindowsUiaTableProvider(id()); + } + break; + case UIA_TableItemPatternId: + // Item within a table/tree. + if (accessible->tableCellInterface() + && ((accessible->role() == QAccessible::Cell) || (accessible->role() == QAccessible::TreeItem))) { + *pRetVal = new QWindowsUiaTableItemProvider(id()); + } + break; + case UIA_GridPatternId: + // Table/tree. + if (accessible->tableInterface() + && ((accessible->role() == QAccessible::Table) || (accessible->role() == QAccessible::Tree))) { + *pRetVal = new QWindowsUiaGridProvider(id()); + } + break; + case UIA_GridItemPatternId: + // Item within a table/tree. + if (accessible->tableCellInterface() + && ((accessible->role() == QAccessible::Cell) || (accessible->role() == QAccessible::TreeItem))) { + *pRetVal = new QWindowsUiaGridItemProvider(id()); + } + break; + case UIA_InvokePatternId: + // Things that have an invokable action (e.g., simple buttons). + if (accessible->actionInterface()) { + *pRetVal = new QWindowsUiaInvokeProvider(id()); + } + break; + default: + break; + } + + return S_OK; +} + +HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << idProp; + + if (!pRetVal) + return E_INVALIDARG; + clearVariant(pRetVal); + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + bool clientTopLevel = (accessible->role() == QAccessible::Client) + && accessible->parent() && (accessible->parent()->role() == QAccessible::Application); + + switch (idProp) { + case UIA_ProcessIdPropertyId: + // PID + setVariantI4(int(GetCurrentProcessId()), pRetVal); + break; + case UIA_AccessKeyPropertyId: + // Accelerator key. + setVariantString(accessible->text(QAccessible::Accelerator), pRetVal); + break; + case UIA_AutomationIdPropertyId: + // Automation ID, which can be used by tools to select a specific control in the UI. + setVariantString(automationIdForAccessible(accessible), pRetVal); + break; + case UIA_ClassNamePropertyId: + // Class name. + if (QObject *o = accessible->object()) { + QString className = QLatin1String(o->metaObject()->className()); + setVariantString(className, pRetVal); + } + break; + case UIA_FrameworkIdPropertyId: + setVariantString(QStringLiteral("Qt"), pRetVal); + break; + case UIA_ControlTypePropertyId: + if (clientTopLevel) { + // Reports a top-level widget as a window, instead of "custom". + setVariantI4(UIA_WindowControlTypeId, pRetVal); + } else { + // Control type converted from role. + setVariantI4(roleToControlTypeId(accessible->role()), pRetVal); + } + break; + case UIA_HelpTextPropertyId: + setVariantString(accessible->text(QAccessible::Help), pRetVal); + break; + case UIA_HasKeyboardFocusPropertyId: + setVariantBool(accessible->state().focused, pRetVal); + break; + case UIA_IsKeyboardFocusablePropertyId: + setVariantBool(accessible->state().focusable, pRetVal); + break; + case UIA_IsOffscreenPropertyId: + setVariantBool(false, pRetVal); + break; + case UIA_IsContentElementPropertyId: + setVariantBool(true, pRetVal); + break; + case UIA_IsControlElementPropertyId: + setVariantBool(true, pRetVal); + break; + case UIA_IsEnabledPropertyId: + setVariantBool(!accessible->state().disabled, pRetVal); + break; + case UIA_IsPasswordPropertyId: + setVariantBool(accessible->role() == QAccessible::EditableText + && accessible->state().passwordEdit, pRetVal); + break; + case UIA_IsPeripheralPropertyId: + // True for peripheral UIs. + if (QWindow *window = windowForAccessible(accessible)) { + const Qt::WindowType wt = window->type(); + setVariantBool(wt == Qt::Popup || wt == Qt::ToolTip || wt == Qt::SplashScreen, pRetVal); + } + break; + case UIA_FullDescriptionPropertyId: + setVariantString(accessible->text(QAccessible::Description), pRetVal); + break; + case UIA_NamePropertyId: { + QString name = accessible->text(QAccessible::Name); + if (name.isEmpty() && clientTopLevel) { + name = QCoreApplication::applicationName(); + } + setVariantString(name, pRetVal); + break; + } + default: + break; + } + return S_OK; +} + +// Generates an ID based on the name of the controls and their parents. +QString QWindowsUiaMainProvider::automationIdForAccessible(const QAccessibleInterface *accessible) +{ + QString result; + if (accessible) { + QObject *obj = accessible->object(); + while (obj) { + QString name = obj->objectName(); + if (name.isEmpty()) + return QString(); + if (!result.isEmpty()) + result.prepend(QLatin1Char('.')); + result.prepend(name); + obj = obj->parent(); + } + } + return result; +} + +HRESULT QWindowsUiaMainProvider::get_HostRawElementProvider(IRawElementProviderSimple **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + // Returns a host provider only for controls associated with a native window handle. Others should return NULL. + if (QAccessibleInterface *accessible = accessibleInterface()) { + if (HWND hwnd = hwndForAccessible(accessible)) { + return QWindowsUiaWrapper::instance()->hostProviderFromHwnd(hwnd, pRetVal); + } + } + return S_OK; +} + +// Navigates within the tree of accessible controls. +HRESULT QWindowsUiaMainProvider::Navigate(NavigateDirection direction, IRawElementProviderFragment **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << direction << " this: " << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleInterface *targetacc = nullptr; + + switch (direction) { + case NavigateDirection_Parent: + targetacc = accessible->parent(); + if (targetacc && (targetacc->role() == QAccessible::Application)) { + targetacc = nullptr; // The app's children are considered top level objects. + } + break; + case NavigateDirection_FirstChild: + targetacc = accessible->child(0); + break; + case NavigateDirection_LastChild: + targetacc = accessible->child(accessible->childCount() - 1); + break; + case NavigateDirection_NextSibling: + case NavigateDirection_PreviousSibling: + if (QAccessibleInterface *parent = accessible->parent()) { + if (parent->isValid()) { + int index = parent->indexOfChild(accessible); + index += (direction == NavigateDirection_NextSibling) ? 1 : -1; + if (index >= 0 && index < parent->childCount()) + targetacc = parent->child(index); + } + } + break; + } + + if (targetacc) + *pRetVal = providerForAccessible(targetacc); + return S_OK; +} + +// Returns a unique id assigned to the UI element, used as key by the UI Automation framework. +HRESULT QWindowsUiaMainProvider::GetRuntimeId(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + // The UiaAppendRuntimeId constant is used to make then ID unique + // among multiple instances running on the system. + int rtId[] = { UiaAppendRuntimeId, int(id()) }; + + if ((*pRetVal = SafeArrayCreateVector(VT_I4, 0, 2))) { + for (LONG i = 0; i < 2; ++i) + SafeArrayPutElement(*pRetVal, &i, &rtId[i]); + } + return S_OK; +} + +// Returns the bounding rectangle for the accessible control. +HRESULT QWindowsUiaMainProvider::get_BoundingRectangle(UiaRect *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QWindow *window = windowForAccessible(accessible); + if (!window) + return UIA_E_ELEMENTNOTAVAILABLE; + + rectToNativeUiaRect(accessible->rect(), window, pRetVal); + return S_OK; +} + +HRESULT QWindowsUiaMainProvider::GetEmbeddedFragmentRoots(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + // No embedded roots. + return S_OK; +} + +// Sets focus to the control. +HRESULT QWindowsUiaMainProvider::SetFocus() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleActionInterface *actionInterface = accessible->actionInterface(); + if (!actionInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + actionInterface->doAction(QAccessibleActionInterface::setFocusAction()); + return S_OK; +} + +HRESULT QWindowsUiaMainProvider::get_FragmentRoot(IRawElementProviderFragmentRoot **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + // Our UI Automation implementation considers the window as the root for + // non-native controls/fragments. + if (QAccessibleInterface *accessible = accessibleInterface()) { + if (QWindow *window = windowForAccessible(accessible)) { + if (QAccessibleInterface *rootacc = window->accessibleRoot()) { + *pRetVal = providerForAccessible(rootacc); + } + } + } + return S_OK; +} + +// Returns a provider for the UI element present at the specified screen coordinates. +HRESULT QWindowsUiaMainProvider::ElementProviderFromPoint(double x, double y, IRawElementProviderFragment **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << x << y; + + if (!pRetVal) { + return E_INVALIDARG; + } + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QWindow *window = windowForAccessible(accessible); + if (!window) + return UIA_E_ELEMENTNOTAVAILABLE; + + // Scales coordinates from High DPI screens. + UiaPoint uiaPoint = {x, y}; + QPoint point; + nativeUiaPointToPoint(uiaPoint, window, &point); + + QAccessibleInterface *targetacc = accessible->childAt(point.x(), point.y()); + + if (targetacc) { + QAccessibleInterface *acc = targetacc; + // Controls can be embedded within grouping elements. By default returns the innermost control. + while (acc) { + targetacc = acc; + // For accessibility tools it may be better to return the text element instead of its subcomponents. + if (targetacc->textInterface()) break; + acc = acc->childAt(point.x(), point.y()); + } + *pRetVal = providerForAccessible(targetacc); + } + return S_OK; +} + +// Returns the fragment with focus. +HRESULT QWindowsUiaMainProvider::GetFocus(IRawElementProviderFragment **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + if (QAccessibleInterface *accessible = accessibleInterface()) { + if (QAccessibleInterface *focusacc = accessible->focusChild()) { + *pRetVal = providerForAccessible(focusacc); + } + } + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h new file mode 100644 index 0000000000..893cbf7f8a --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIAMAINPROVIDER_H +#define QWINDOWSUIAMAINPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +#include <QtCore/QPointer> +#include <QtCore/QSharedPointer> +#include <QtCore/qt_windows.h> +#include <QtGui/QAccessible> + +QT_BEGIN_NAMESPACE + +// The main UI Automation class. +class QWindowsUiaMainProvider : + public QWindowsUiaBaseProvider, + public IRawElementProviderSimple, + public IRawElementProviderFragment, + public IRawElementProviderFragmentRoot +{ + Q_OBJECT + Q_DISABLE_COPY(QWindowsUiaMainProvider) +public: + static QWindowsUiaMainProvider *providerForAccessible(QAccessibleInterface *accessible); + explicit QWindowsUiaMainProvider(QAccessibleInterface *a, int initialRefCount = 1); + virtual ~QWindowsUiaMainProvider(); + static void notifyFocusChange(QAccessibleEvent *event); + static void notifyStateChange(QAccessibleStateChangeEvent *event); + static void notifyValueChange(QAccessibleValueChangeEvent *event); + static void notifyTextChange(QAccessibleEvent *event); + + // IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + // IRawElementProviderSimple methods + HRESULT STDMETHODCALLTYPE get_ProviderOptions(ProviderOptions *pRetVal); + HRESULT STDMETHODCALLTYPE GetPatternProvider(PATTERNID idPattern, IUnknown **pRetVal); + HRESULT STDMETHODCALLTYPE GetPropertyValue(PROPERTYID idProp, VARIANT *pRetVal); + HRESULT STDMETHODCALLTYPE get_HostRawElementProvider(IRawElementProviderSimple **pRetVal); + + // IRawElementProviderFragment methods + HRESULT STDMETHODCALLTYPE Navigate(NavigateDirection direction, IRawElementProviderFragment **pRetVal); + HRESULT STDMETHODCALLTYPE GetRuntimeId(SAFEARRAY **pRetVal); + HRESULT STDMETHODCALLTYPE get_BoundingRectangle(UiaRect *pRetVal); + HRESULT STDMETHODCALLTYPE GetEmbeddedFragmentRoots(SAFEARRAY **pRetVal); + HRESULT STDMETHODCALLTYPE SetFocus(); + HRESULT STDMETHODCALLTYPE get_FragmentRoot(IRawElementProviderFragmentRoot **pRetVal); + + // IRawElementProviderFragmentRoot methods + HRESULT STDMETHODCALLTYPE ElementProviderFromPoint(double x, double y, IRawElementProviderFragment **pRetVal); + HRESULT STDMETHODCALLTYPE GetFocus(IRawElementProviderFragment **pRetVal); + +private: + QString automationIdForAccessible(const QAccessibleInterface *accessible); + ULONG m_ref; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIAMAINPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.cpp new file mode 100644 index 0000000000..9f0a1e126f --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiaprovidercache.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +// Private constructor +QWindowsUiaProviderCache::QWindowsUiaProviderCache() +{ +} + +// shared instance +QWindowsUiaProviderCache *QWindowsUiaProviderCache::instance() +{ + static QWindowsUiaProviderCache providerCache; + return &providerCache; +} + +// Returns the provider instance associated with the ID, or nullptr. +QWindowsUiaBaseProvider *QWindowsUiaProviderCache::providerForId(QAccessible::Id id) const +{ + return providerTable.value(id); +} + +// Inserts a provider in the cache and associates it with an accessibility ID. +void QWindowsUiaProviderCache::insert(QAccessible::Id id, QWindowsUiaBaseProvider *provider) +{ + remove(id); + if (provider) { + providerTable[id] = provider; + inverseTable[provider] = id; + // Connects the destroyed signal to our slot, to remove deleted objects from the cache. + QObject::connect(provider, &QObject::destroyed, this, &QWindowsUiaProviderCache::objectDestroyed); + } +} + +// Removes deleted provider objects from the cache. +void QWindowsUiaProviderCache::objectDestroyed(QObject *obj) +{ + // We have to use the inverse table to map the object address back to its ID, + // since at this point (called from QObject destructor), it has already been + // partially destroyed and we cannot treat it as a provider. + auto it = inverseTable.find(obj); + if (it != inverseTable.end()) { + providerTable.remove(*it); + inverseTable.remove(obj); + } +} + +// Removes a provider with a given id from the cache. +void QWindowsUiaProviderCache::remove(QAccessible::Id id) +{ + inverseTable.remove(providerTable.value(id)); + providerTable.remove(id); +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.h new file mode 100644 index 0000000000..7ad30ac39c --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIAPROVIDERCACHE_H +#define QWINDOWSUIAPROVIDERCACHE_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +#include <QtCore/QHash> +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> + +QT_BEGIN_NAMESPACE + +// Singleton used to cache provider instances using the accessibility ID as the key. +class QWindowsUiaProviderCache : public QObject +{ + QWindowsUiaProviderCache(); + Q_OBJECT +public: + static QWindowsUiaProviderCache *instance(); + QWindowsUiaBaseProvider *providerForId(QAccessible::Id id) const; + void insert(QAccessible::Id id, QWindowsUiaBaseProvider *provider); + void remove(QAccessible::Id id); + +private Q_SLOTS: + void objectDestroyed(QObject *obj); + +private: + QHash<QAccessible::Id, QWindowsUiaBaseProvider *> providerTable; + QHash<QObject *, QAccessible::Id> inverseTable; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIAPROVIDERCACHE_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.cpp new file mode 100644 index 0000000000..0cd09c3f0a --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.cpp @@ -0,0 +1,190 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiarangevalueprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaRangeValueProvider::QWindowsUiaRangeValueProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaRangeValueProvider::~QWindowsUiaRangeValueProvider() +{ +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaRangeValueProvider::SetValue(double val) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleValueInterface *valueInterface = accessible->valueInterface(); + if (!valueInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + double minimum = valueInterface->minimumValue().toDouble(); + double maximum = valueInterface->maximumValue().toDouble(); + if ((val < minimum) || (val > maximum)) + return E_INVALIDARG; + + valueInterface->setCurrentValue(QVariant(val)); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaRangeValueProvider::get_Value(double *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleValueInterface *valueInterface = accessible->valueInterface(); + if (!valueInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + QVariant varValue = valueInterface->currentValue(); + *pRetVal = varValue.toDouble(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaRangeValueProvider::get_IsReadOnly(BOOL *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = accessible->state().readOnly; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaRangeValueProvider::get_Maximum(double *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleValueInterface *valueInterface = accessible->valueInterface(); + if (!valueInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + QVariant varValue = valueInterface->maximumValue(); + *pRetVal = varValue.toDouble(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaRangeValueProvider::get_Minimum(double *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleValueInterface *valueInterface = accessible->valueInterface(); + if (!valueInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + QVariant varValue = valueInterface->minimumValue(); + *pRetVal = varValue.toDouble(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaRangeValueProvider::get_LargeChange(double *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + return get_SmallChange(pRetVal); +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaRangeValueProvider::get_SmallChange(double *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleValueInterface *valueInterface = accessible->valueInterface(); + if (!valueInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + QVariant varValue = valueInterface->minimumStepSize(); + *pRetVal = varValue.toDouble(); + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h new file mode 100644 index 0000000000..f742ef99c2 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiarangevalueprovider.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIARANGEVALUEPROVIDER_H +#define QWINDOWSUIARANGEVALUEPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Range Value control pattern provider. +class QWindowsUiaRangeValueProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<IRangeValueProvider> +{ + Q_DISABLE_COPY(QWindowsUiaRangeValueProvider) +public: + explicit QWindowsUiaRangeValueProvider(QAccessible::Id id); + virtual ~QWindowsUiaRangeValueProvider(); + + // IRangeValueProvider + HRESULT STDMETHODCALLTYPE SetValue(double val); + HRESULT STDMETHODCALLTYPE get_Value(double *pRetVal); + HRESULT STDMETHODCALLTYPE get_IsReadOnly(BOOL *pRetVal); + HRESULT STDMETHODCALLTYPE get_Maximum(double *pRetVal); + HRESULT STDMETHODCALLTYPE get_Minimum(double *pRetVal); + HRESULT STDMETHODCALLTYPE get_LargeChange(double *pRetVal); + HRESULT STDMETHODCALLTYPE get_SmallChange(double *pRetVal); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIARANGEVALUEPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp new file mode 100644 index 0000000000..45216a6d1c --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.cpp @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiaselectionitemprovider.h" +#include "qwindowsuiamainprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaSelectionItemProvider::QWindowsUiaSelectionItemProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaSelectionItemProvider::~QWindowsUiaSelectionItemProvider() +{ +} + +// Selects the element (deselecting all others). +HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::Select() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleActionInterface *actionInterface = accessible->actionInterface(); + if (!actionInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + if (accessible->role() == QAccessible::RadioButton) { + // For radio buttons we just invoke the selection action; others are automatically deselected. + actionInterface->doAction(QAccessibleActionInterface::pressAction()); + } else { + // Toggle list item if not already selected. It must be done first to support all selection modes. + if (!accessible->state().selected) { + actionInterface->doAction(QAccessibleActionInterface::toggleAction()); + } + // Toggle selected siblings. + if (QAccessibleInterface *parent = accessible->parent()) { + for (int i = 0; i < parent->childCount(); ++i) { + if (QAccessibleInterface *sibling = parent->child(i)) { + if ((sibling != accessible) && (sibling->state().selected)) { + if (QAccessibleActionInterface *siblingAction = sibling->actionInterface()) { + siblingAction->doAction(QAccessibleActionInterface::toggleAction()); + } + } + } + } + } + } + return S_OK; +} + +// Adds the element to the list of selected elements. +HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::AddToSelection() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleActionInterface *actionInterface = accessible->actionInterface(); + if (!actionInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + if (accessible->role() == QAccessible::RadioButton) { + // For radio buttons we invoke the selection action. + actionInterface->doAction(QAccessibleActionInterface::pressAction()); + } else { + // Toggle list item if not already selected. + if (!accessible->state().selected) { + actionInterface->doAction(QAccessibleActionInterface::toggleAction()); + } + } + return S_OK; +} + +// Removes a list item from selection. +HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::RemoveFromSelection() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleActionInterface *actionInterface = accessible->actionInterface(); + if (!actionInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + if (accessible->role() != QAccessible::RadioButton) { + if (accessible->state().selected) { + actionInterface->doAction(QAccessibleActionInterface::toggleAction()); + } + } + + return S_OK; +} + +// Returns true if element is currently selected. +HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::get_IsSelected(BOOL *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = FALSE; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + if (accessible->role() == QAccessible::RadioButton) + *pRetVal = accessible->state().checked; + else + *pRetVal = accessible->state().selected; + return S_OK; +} + +// Returns the provider for the container element (e.g., the list for the list item). +HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionItemProvider::get_SelectionContainer(IRawElementProviderSimple **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleActionInterface *actionInterface = accessible->actionInterface(); + if (!actionInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + // Radio buttons do not require a container. + if (accessible->role() == QAccessible::ListItem) { + if (QAccessibleInterface *parent = accessible->parent()) { + if (parent->role() == QAccessible::List) { + *pRetVal = QWindowsUiaMainProvider::providerForAccessible(parent); + } + } + } + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h new file mode 100644 index 0000000000..6a9b5b1e4b --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionitemprovider.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIASELECTIONITEMPROVIDER_H +#define QWINDOWSUIASELECTIONITEMPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Selection Item control pattern provider. Used for List items and radio buttons. +class QWindowsUiaSelectionItemProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<ISelectionItemProvider> +{ + Q_DISABLE_COPY(QWindowsUiaSelectionItemProvider) +public: + explicit QWindowsUiaSelectionItemProvider(QAccessible::Id id); + virtual ~QWindowsUiaSelectionItemProvider(); + + // ISelectionItemProvider + HRESULT STDMETHODCALLTYPE Select(); + HRESULT STDMETHODCALLTYPE AddToSelection(); + HRESULT STDMETHODCALLTYPE RemoveFromSelection(); + HRESULT STDMETHODCALLTYPE get_IsSelected(BOOL *pRetVal); + HRESULT STDMETHODCALLTYPE get_SelectionContainer(IRawElementProviderSimple **pRetVal); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIASELECTIONITEMPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp new file mode 100644 index 0000000000..1c06503bfc --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.cpp @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiaselectionprovider.h" +#include "qwindowsuiamainprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> +#include <QList> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaSelectionProvider::QWindowsUiaSelectionProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaSelectionProvider::~QWindowsUiaSelectionProvider() +{ +} + +// Returns an array of providers with the selected items. +HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::GetSelection(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + // First put selected items in a list, then build a safe array with the right size. + QList<QAccessibleInterface *> selectedList; + for (int i = 0; i < accessible->childCount(); ++i) { + if (QAccessibleInterface *child = accessible->child(i)) { + if (child->state().selected) { + selectedList.append(child); + } + } + } + + if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, selectedList.size()))) { + for (LONG i = 0; i < selectedList.size(); ++i) { + if (QWindowsUiaMainProvider *childProvider = QWindowsUiaMainProvider::providerForAccessible(selectedList.at(i))) { + SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(childProvider)); + childProvider->Release(); + } + } + } + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_CanSelectMultiple(BOOL *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = FALSE; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = accessible->state().multiSelectable; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaSelectionProvider::get_IsSelectionRequired(BOOL *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = FALSE; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + // Initially returns false if none are selected. After the first selection, it may be required. + bool anySelected = false; + for (int i = 0; i < accessible->childCount(); ++i) { + if (QAccessibleInterface *child = accessible->child(i)) { + if (child->state().selected) { + anySelected = true; + break; + } + } + } + + *pRetVal = anySelected && !accessible->state().multiSelectable && !accessible->state().extSelectable; + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h new file mode 100644 index 0000000000..5a07a82ac8 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaselectionprovider.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIASELECTIONPROVIDER_H +#define QWINDOWSUIASELECTIONPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Selection control pattern provider. Used for Lists. +class QWindowsUiaSelectionProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<ISelectionProvider> +{ + Q_DISABLE_COPY(QWindowsUiaSelectionProvider) +public: + explicit QWindowsUiaSelectionProvider(QAccessible::Id id); + virtual ~QWindowsUiaSelectionProvider(); + + // ISelectionProvider + HRESULT STDMETHODCALLTYPE GetSelection(SAFEARRAY **pRetVal); + HRESULT STDMETHODCALLTYPE get_CanSelectMultiple(BOOL *pRetVal); + HRESULT STDMETHODCALLTYPE get_IsSelectionRequired(BOOL *pRetVal); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIASELECTIONPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp new file mode 100644 index 0000000000..3ea29fc86c --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiatableitemprovider.h" +#include "qwindowsuiamainprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaTableItemProvider::QWindowsUiaTableItemProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaTableItemProvider::~QWindowsUiaTableItemProvider() +{ +} + +// Returns the providers for the row headers associated with the item. +HRESULT STDMETHODCALLTYPE QWindowsUiaTableItemProvider::GetRowHeaderItems(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface(); + if (!tableCellInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + QList<QAccessibleInterface *> headers = tableCellInterface->rowHeaderCells(); + + if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) { + for (LONG i = 0; i < headers.size(); ++i) { + if (QWindowsUiaMainProvider *headerProvider = QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) { + SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(headerProvider)); + headerProvider->Release(); + } + } + } + return S_OK; +} + +// Returns the providers for the column headers associated with the item. +HRESULT STDMETHODCALLTYPE QWindowsUiaTableItemProvider::GetColumnHeaderItems(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableCellInterface *tableCellInterface = accessible->tableCellInterface(); + if (!tableCellInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + QList<QAccessibleInterface *> headers = tableCellInterface->columnHeaderCells(); + + if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) { + for (LONG i = 0; i < headers.size(); ++i) { + if (QWindowsUiaMainProvider *headerProvider = QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) { + SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(headerProvider)); + headerProvider->Release(); + } + } + } + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h new file mode 100644 index 0000000000..277884c980 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableitemprovider.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIATABLEITEMPROVIDER_H +#define QWINDOWSUIATABLEITEMPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Table Item control pattern provider. Used by items within a table/tree. +class QWindowsUiaTableItemProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<ITableItemProvider> +{ + Q_DISABLE_COPY(QWindowsUiaTableItemProvider) +public: + explicit QWindowsUiaTableItemProvider(QAccessible::Id id); + virtual ~QWindowsUiaTableItemProvider(); + + // ITableItemProvider + HRESULT STDMETHODCALLTYPE GetRowHeaderItems(SAFEARRAY **pRetVal); + HRESULT STDMETHODCALLTYPE GetColumnHeaderItems(SAFEARRAY **pRetVal); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIATABLEITEMPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.cpp new file mode 100644 index 0000000000..f79a24536b --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiatableprovider.h" +#include "qwindowsuiamainprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaTableProvider::QWindowsUiaTableProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaTableProvider::~QWindowsUiaTableProvider() +{ +} + +// Gets the providers for all the row headers in the table. +HRESULT STDMETHODCALLTYPE QWindowsUiaTableProvider::GetRowHeaders(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableInterface *tableInterface = accessible->tableInterface(); + if (!tableInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + QList<QAccessibleInterface *> headers; + + for (int i = 0; i < tableInterface->rowCount(); ++i) { + if (QAccessibleInterface *cell = tableInterface->cellAt(i, 0)) { + if (QAccessibleTableCellInterface *tableCellInterface = cell->tableCellInterface()) { + headers.append(tableCellInterface->rowHeaderCells()); + } + } + } + if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) { + for (LONG i = 0; i < headers.size(); ++i) { + if (QWindowsUiaMainProvider *headerProvider = QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) { + SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(headerProvider)); + headerProvider->Release(); + } + } + } + return S_OK; +} + +// Gets the providers for all the column headers in the table. +HRESULT STDMETHODCALLTYPE QWindowsUiaTableProvider::GetColumnHeaders(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTableInterface *tableInterface = accessible->tableInterface(); + if (!tableInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + QList<QAccessibleInterface *> headers; + + for (int i = 0; i < tableInterface->columnCount(); ++i) { + if (QAccessibleInterface *cell = tableInterface->cellAt(0, i)) { + if (QAccessibleTableCellInterface *tableCellInterface = cell->tableCellInterface()) { + headers.append(tableCellInterface->columnHeaderCells()); + } + } + } + if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, headers.size()))) { + for (LONG i = 0; i < headers.size(); ++i) { + if (QWindowsUiaMainProvider *headerProvider = QWindowsUiaMainProvider::providerForAccessible(headers.at(i))) { + SafeArrayPutElement(*pRetVal, &i, static_cast<IRawElementProviderSimple *>(headerProvider)); + headerProvider->Release(); + } + } + } + return S_OK; +} + +// Returns the primary direction of traversal for the table. +HRESULT STDMETHODCALLTYPE QWindowsUiaTableProvider::get_RowOrColumnMajor(enum RowOrColumnMajor *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = RowOrColumnMajor_Indeterminate; + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h new file mode 100644 index 0000000000..8cd0acda03 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatableprovider.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIATABLEPROVIDER_H +#define QWINDOWSUIATABLEPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Table control pattern provider. Used by tables/trees. +class QWindowsUiaTableProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<ITableProvider> +{ + Q_DISABLE_COPY(QWindowsUiaTableProvider) +public: + explicit QWindowsUiaTableProvider(QAccessible::Id id); + virtual ~QWindowsUiaTableProvider(); + + // ITableProvider + HRESULT STDMETHODCALLTYPE GetRowHeaders(SAFEARRAY **pRetVal); + HRESULT STDMETHODCALLTYPE GetColumnHeaders(SAFEARRAY **pRetVal); + HRESULT STDMETHODCALLTYPE get_RowOrColumnMajor(enum RowOrColumnMajor *pRetVal); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIATABLEPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp new file mode 100644 index 0000000000..e1622933af --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.cpp @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiatextprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaTextProvider::QWindowsUiaTextProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaTextProvider::~QWindowsUiaTextProvider() +{ +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::QueryInterface(REFIID iid, LPVOID *iface) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!iface) + return E_INVALIDARG; + *iface = nullptr; + + const bool result = qWindowsComQueryUnknownInterfaceMulti<ITextProvider>(this, iid, iface) + || qWindowsComQueryInterface<ITextProvider>(this, iid, iface) + || qWindowsComQueryInterface<ITextProvider2>(this, iid, iface); + return result ? S_OK : E_NOINTERFACE; +} + +// Returns an array of providers for the selected text ranges. +HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetSelection(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + int selCount = textInterface->selectionCount(); + if (selCount > 0) { + // Build a safe array with the text range providers. + if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, selCount))) { + for (LONG i = 0; i < selCount; ++i) { + int startOffset = 0, endOffset = 0; + textInterface->selection((int)i, &startOffset, &endOffset); + QWindowsUiaTextRangeProvider *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), startOffset, endOffset); + SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider)); + textRangeProvider->Release(); + } + } + } else { + // If there is no selection, we return an array with a single degenerate (empty) text range at the cursor position. + if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1))) { + LONG i = 0; + int cursorPosition = textInterface->cursorPosition(); + QWindowsUiaTextRangeProvider *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), cursorPosition, cursorPosition); + SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider)); + textRangeProvider->Release(); + } + } + return S_OK; +} + +// Returns an array of providers for the visible text ranges. +HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetVisibleRanges(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + // Considering the entire text as visible. + if ((*pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 1))) { + LONG i = 0; + QWindowsUiaTextRangeProvider *textRangeProvider = new QWindowsUiaTextRangeProvider(id(), 0, textInterface->characterCount()); + SafeArrayPutElement(*pRetVal, &i, static_cast<IUnknown *>(textRangeProvider)); + textRangeProvider->Release(); + } + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::RangeFromChild(IRawElementProviderSimple * /*childElement*/, + ITextRangeProvider **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + // No children supported. + return S_OK; +} + +// Returns a degenerate text range at the specified point. +HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + QWindow *window = windowForAccessible(accessible); + if (!window) + return UIA_E_ELEMENTNOTAVAILABLE; + + QPoint pt; + nativeUiaPointToPoint(point, window, &pt); + + int offset = textInterface->offsetAtPoint(pt); + if ((offset >= 0) && (offset < textInterface->characterCount())) { + *pRetVal = new QWindowsUiaTextRangeProvider(id(), offset, offset); + } + return S_OK; +} + +// Returns a text range provider for the entire text. +HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::get_DocumentRange(ITextRangeProvider **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = new QWindowsUiaTextRangeProvider(id(), 0, textInterface->characterCount()); + return S_OK; +} + +// Currently supporting single selection. +HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::get_SupportedTextSelection(SupportedTextSelection *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = SupportedTextSelection_Single; + return S_OK; +} + +// Not supporting annotations. +HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::RangeFromAnnotation(IRawElementProviderSimple * /*annotationElement*/, ITextRangeProvider **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QWindowsUiaTextProvider::GetCaretRange(BOOL *isActive, ITextRangeProvider **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!isActive || !pRetVal) + return E_INVALIDARG; + *isActive = FALSE; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + *isActive = accessible->state().focused; + + int cursorPosition = textInterface->cursorPosition(); + *pRetVal = new QWindowsUiaTextRangeProvider(id(), cursorPosition, cursorPosition); + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h new file mode 100644 index 0000000000..a6d10027fa --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextprovider.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIATEXTPROVIDER_H +#define QWINDOWSUIATEXTPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" +#include "qwindowsuiatextrangeprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Text control pattern provider. Used for text controls. +class QWindowsUiaTextProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<ITextProvider2> +{ + Q_DISABLE_COPY(QWindowsUiaTextProvider) +public: + explicit QWindowsUiaTextProvider(QAccessible::Id id); + ~QWindowsUiaTextProvider(); + + // IUnknown overrides + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface); + + // ITextProvider + HRESULT STDMETHODCALLTYPE GetSelection(SAFEARRAY **pRetVal); + HRESULT STDMETHODCALLTYPE GetVisibleRanges(SAFEARRAY **pRetVal); + HRESULT STDMETHODCALLTYPE RangeFromChild(IRawElementProviderSimple *childElement, ITextRangeProvider **pRetVal); + HRESULT STDMETHODCALLTYPE RangeFromPoint(UiaPoint point, ITextRangeProvider **pRetVal); + HRESULT STDMETHODCALLTYPE get_DocumentRange(ITextRangeProvider **pRetVal); + HRESULT STDMETHODCALLTYPE get_SupportedTextSelection(SupportedTextSelection *pRetVal); + + // ITextProvider2 + HRESULT STDMETHODCALLTYPE RangeFromAnnotation(IRawElementProviderSimple *annotationElement, ITextRangeProvider **pRetVal); + HRESULT STDMETHODCALLTYPE GetCaretRange(BOOL *isActive, ITextRangeProvider **pRetVal); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIATEXTPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp new file mode 100644 index 0000000000..dae7cbdd5f --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp @@ -0,0 +1,554 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiatextrangeprovider.h" +#include "qwindowsuiamainprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaTextRangeProvider::QWindowsUiaTextRangeProvider(QAccessible::Id id, int startOffset, int endOffset) : + QWindowsUiaBaseProvider(id), + m_startOffset(startOffset), + m_endOffset(endOffset) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this << startOffset << endOffset; +} + +QWindowsUiaTextRangeProvider::~QWindowsUiaTextRangeProvider() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; +} + +HRESULT QWindowsUiaTextRangeProvider::AddToSelection() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + return Select(); +} + +HRESULT QWindowsUiaTextRangeProvider::Clone(ITextRangeProvider **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + + *pRetVal = new QWindowsUiaTextRangeProvider(id(), m_startOffset, m_endOffset); + return S_OK; +} + +// Two ranges are considered equal if their start/end points are the same. +HRESULT QWindowsUiaTextRangeProvider::Compare(ITextRangeProvider *range, BOOL *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!range || !pRetVal) + return E_INVALIDARG; + + QWindowsUiaTextRangeProvider *targetProvider = static_cast<QWindowsUiaTextRangeProvider *>(range); + *pRetVal = ((targetProvider->m_startOffset == m_startOffset) && (targetProvider->m_endOffset == m_endOffset)); + return S_OK; +} + +// Compare different endpoinds between two providers. +HRESULT QWindowsUiaTextRangeProvider::CompareEndpoints(TextPatternRangeEndpoint endpoint, + ITextRangeProvider *targetRange, + TextPatternRangeEndpoint targetEndpoint, + int *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ + << "endpoint=" << endpoint << "targetRange=" << targetRange + << "targetEndpoint=" << targetEndpoint << "this: " << this; + + if (!targetRange || !pRetVal) + return E_INVALIDARG; + + QWindowsUiaTextRangeProvider *targetProvider = static_cast<QWindowsUiaTextRangeProvider *>(targetRange); + + int point = (endpoint == TextPatternRangeEndpoint_Start) ? m_startOffset : m_endOffset; + int targetPoint = (targetEndpoint == TextPatternRangeEndpoint_Start) ? + targetProvider->m_startOffset : targetProvider->m_endOffset; + *pRetVal = point - targetPoint; + return S_OK; +} + +// Expands/normalizes the range for a given text unit. +HRESULT QWindowsUiaTextRangeProvider::ExpandToEnclosingUnit(TextUnit unit) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << "unit=" << unit << "this: " << this; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + int len = textInterface->characterCount(); + if (len < 1) { + m_startOffset = 0; + m_endOffset = 0; + } else { + if (unit == TextUnit_Character) { + m_startOffset = qBound(0, m_startOffset, len - 1); + m_endOffset = m_startOffset + 1; + } else { + QString text = textInterface->text(0, len); + for (int t = m_startOffset; t >= 0; --t) { + if (!isTextUnitSeparator(unit, text[t]) && ((t == 0) || isTextUnitSeparator(unit, text[t - 1]))) { + m_startOffset = t; + break; + } + } + for (int t = m_startOffset; t < len; ++t) { + if ((t == len - 1) || (isTextUnitSeparator(unit, text[t]) && ((unit == TextUnit_Word) || !isTextUnitSeparator(unit, text[t + 1])))) { + m_endOffset = t + 1; + break; + } + } + } + } + return S_OK; +} + +// Not supported. +HRESULT QWindowsUiaTextRangeProvider::FindAttribute(TEXTATTRIBUTEID /* attributeId */, + VARIANT /* val */, BOOL /* backward */, + ITextRangeProvider **pRetVal) +{ + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + return S_OK; +} + +// Returns the value of a given attribute. +HRESULT STDMETHODCALLTYPE QWindowsUiaTextRangeProvider::GetAttributeValue(TEXTATTRIBUTEID attributeId, + VARIANT *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << "attributeId=" << attributeId << "this: " << this; + + if (!pRetVal) + return E_INVALIDARG; + clearVariant(pRetVal); + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + switch (attributeId) { + case UIA_IsReadOnlyAttributeId: + setVariantBool(accessible->state().readOnly, pRetVal); + break; + case UIA_CaretPositionAttributeId: + if (textInterface->cursorPosition() == 0) + setVariantI4(CaretPosition_BeginningOfLine, pRetVal); + else if (textInterface->cursorPosition() == textInterface->characterCount()) + setVariantI4(CaretPosition_EndOfLine, pRetVal); + else + setVariantI4(CaretPosition_Unknown, pRetVal); + break; + default: + break; + } + return S_OK; +} + +// Returns an array of bounding rectangles for text lines within the range. +HRESULT QWindowsUiaTextRangeProvider::GetBoundingRectangles(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + QWindow *window = windowForAccessible(accessible); + if (!window) + return UIA_E_ELEMENTNOTAVAILABLE; + + int len = textInterface->characterCount(); + QList<QRect> rectList; + + if ((m_startOffset >= 0) && (m_endOffset <= len) && (m_startOffset < m_endOffset)) { + int start, end; + textInterface->textAtOffset(m_startOffset, QAccessible::LineBoundary, &start, &end); + while ((start >= 0) && (end >= 0)) { + int startRange = qMax(start, m_startOffset); + int endRange = qMin(end, m_endOffset); + if (startRange < endRange) { + // Calculates a bounding rectangle for the line and adds it to the list. + QRect startRect = textInterface->characterRect(startRange); + QRect endRect = textInterface->characterRect(endRange - 1); + QRect lineRect(qMin(startRect.x(), endRect.x()), + qMin(startRect.y(), endRect.y()), + qMax(startRect.x() + startRect.width(), endRect.x() + endRect.width()) - qMin(startRect.x(), endRect.x()), + qMax(startRect.y() + startRect.height(), endRect.y() + endRect.height()) - qMin(startRect.y(), endRect.y())); + rectList.append(lineRect); + } + if (end >= len) break; + textInterface->textAfterOffset(end + 1, QAccessible::LineBoundary, &start, &end); + } + } + + if ((*pRetVal = SafeArrayCreateVector(VT_R8, 0, 4 * rectList.size()))) { + for (int i = 0; i < rectList.size(); ++i) { + // Scale rect for high DPI screens. + UiaRect uiaRect; + rectToNativeUiaRect(rectList[i], window, &uiaRect); + double coords[4] = { uiaRect.left, uiaRect.top, uiaRect.width, uiaRect.height }; + for (int j = 0; j < 4; ++j) { + LONG idx = 4 * i + j; + SafeArrayPutElement(*pRetVal, &idx, &coords[j]); + } + } + } + return S_OK; +} + +// Returns an array of children elements embedded within the range. +HRESULT QWindowsUiaTextRangeProvider::GetChildren(SAFEARRAY **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + // Not supporting any children. + *pRetVal = SafeArrayCreateVector(VT_UNKNOWN, 0, 0); + return S_OK; +} + +// Returns a provider for the enclosing element (text to which the range belongs). +HRESULT QWindowsUiaTextRangeProvider::GetEnclosingElement(IRawElementProviderSimple **pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + if (!pRetVal) + return E_INVALIDARG; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = QWindowsUiaMainProvider::providerForAccessible(accessible); + return S_OK; +} + +// Gets the text within the range. +HRESULT QWindowsUiaTextRangeProvider::GetText(int maxLength, BSTR *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << maxLength << "this: " << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + int len = textInterface->characterCount(); + QString rangeText; + if ((m_startOffset >= 0) && (m_endOffset <= len) && (m_startOffset < m_endOffset)) + rangeText = textInterface->text(m_startOffset, m_endOffset); + + if ((maxLength > -1) && (rangeText.size() > maxLength)) + rangeText.truncate(maxLength); + *pRetVal = bStrFromQString(rangeText); + return S_OK; +} + +// Moves the range a specified number of units (and normalizes it). +HRESULT QWindowsUiaTextRangeProvider::Move(TextUnit unit, int count, int *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << "unit=" << unit << "count=" << count << "this: " << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = 0; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + int len = textInterface->characterCount(); + + if (len < 1) + return S_OK; + + if (unit == TextUnit_Character) { + // Moves the start point, ensuring it lies within the bounds. + int start = qBound(0, m_startOffset + count, len - 1); + // If range was initially empty, leaves it as is; otherwise, normalizes it to one char. + m_endOffset = (m_endOffset > m_startOffset) ? start + 1 : start; + *pRetVal = start - m_startOffset; // Returns the actually moved distance. + m_startOffset = start; + } else { + if (count > 0) { + MoveEndpointByUnit(TextPatternRangeEndpoint_End, unit, count, pRetVal); + MoveEndpointByUnit(TextPatternRangeEndpoint_Start, unit, count, pRetVal); + } else { + MoveEndpointByUnit(TextPatternRangeEndpoint_Start, unit, count, pRetVal); + MoveEndpointByUnit(TextPatternRangeEndpoint_End, unit, count, pRetVal); + } + } + return S_OK; +} + +// Copies the value of an end point from one range to another. +HRESULT QWindowsUiaTextRangeProvider::MoveEndpointByRange(TextPatternRangeEndpoint endpoint, + ITextRangeProvider *targetRange, + TextPatternRangeEndpoint targetEndpoint) +{ + if (!targetRange) + return E_INVALIDARG; + + qCDebug(lcQpaUiAutomation) << __FUNCTION__ + << "endpoint=" << endpoint << "targetRange=" << targetRange << "targetEndpoint=" << targetEndpoint << "this: " << this; + + QWindowsUiaTextRangeProvider *targetProvider = static_cast<QWindowsUiaTextRangeProvider *>(targetRange); + + int targetPoint = (targetEndpoint == TextPatternRangeEndpoint_Start) ? + targetProvider->m_startOffset : targetProvider->m_endOffset; + + // If the moved endpoint crosses the other endpoint, that one is moved too. + if (endpoint == TextPatternRangeEndpoint_Start) { + m_startOffset = targetPoint; + if (m_endOffset < m_startOffset) + m_endOffset = m_startOffset; + } else { + m_endOffset = targetPoint; + if (m_endOffset < m_startOffset) + m_startOffset = m_endOffset; + } + return S_OK; +} + +// Moves an endpoint an specific number of units. +HRESULT QWindowsUiaTextRangeProvider::MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, + TextUnit unit, int count, + int *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ + << "endpoint=" << endpoint << "unit=" << unit << "count=" << count << "this: " << this; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = 0; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + int len = textInterface->characterCount(); + + if (len < 1) + return S_OK; + + if (unit == TextUnit_Character) { + if (endpoint == TextPatternRangeEndpoint_Start) { + int boundedValue = qBound(0, m_startOffset + count, len - 1); + *pRetVal = boundedValue - m_startOffset; + m_startOffset = boundedValue; + m_endOffset = qBound(m_startOffset, m_endOffset, len); + } else { + int boundedValue = qBound(0, m_endOffset + count, len); + *pRetVal = boundedValue - m_endOffset; + m_endOffset = boundedValue; + m_startOffset = qBound(0, m_startOffset, m_endOffset); + } + } else { + QString text = textInterface->text(0, len); + int moved = 0; + + if (endpoint == TextPatternRangeEndpoint_Start) { + if (count > 0) { + for (int t = m_startOffset; (t < len - 1) && (moved < count); ++t) { + if (isTextUnitSeparator(unit, text[t]) && !isTextUnitSeparator(unit, text[t + 1])) { + m_startOffset = t + 1; + ++moved; + } + } + m_endOffset = qBound(m_startOffset, m_endOffset, len); + } else { + for (int t = m_startOffset - 1; (t >= 0) && (moved > count); --t) { + if (!isTextUnitSeparator(unit, text[t]) && ((t == 0) || isTextUnitSeparator(unit, text[t - 1]))) { + m_startOffset = t; + --moved; + } + } + } + } else { + if (count > 0) { + for (int t = m_endOffset; (t < len) && (moved < count); ++t) { + if ((t == len - 1) || (isTextUnitSeparator(unit, text[t]) && ((unit == TextUnit_Word) || !isTextUnitSeparator(unit, text[t + 1])))) { + m_endOffset = t + 1; + ++moved; + } + } + } else { + int end = 0; + for (int t = m_endOffset - 2; (t > 0) && (moved > count); --t) { + if (isTextUnitSeparator(unit, text[t]) && ((unit == TextUnit_Word) || !isTextUnitSeparator(unit, text[t + 1]))) { + end = t + 1; + --moved; + } + } + m_endOffset = end; + m_startOffset = qBound(0, m_startOffset, m_endOffset); + } + } + *pRetVal = moved; + } + return S_OK; +} + +HRESULT QWindowsUiaTextRangeProvider::RemoveFromSelection() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + // unselects all + return unselect(); +} + +// Scrolls the range into view. +HRESULT QWindowsUiaTextRangeProvider::ScrollIntoView(BOOL alignToTop) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << "alignToTop=" << alignToTop << "this: " << this; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + textInterface->scrollToSubstring(m_startOffset, m_endOffset); + return S_OK; +} + +// Selects the range. +HRESULT QWindowsUiaTextRangeProvider::Select() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + // unselects all and adds a new selection + unselect(); + textInterface->addSelection(m_startOffset, m_endOffset); + return S_OK; +} + +// Not supported. +HRESULT QWindowsUiaTextRangeProvider::FindTextW(BSTR /* text */, BOOL /* backward */, + BOOL /* ignoreCase */, + ITextRangeProvider **pRetVal) +{ + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + return S_OK; +} + +// Removes all selected ranges from the text element. +HRESULT QWindowsUiaTextRangeProvider::unselect() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__ << this; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleTextInterface *textInterface = accessible->textInterface(); + if (!textInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + int selCount = textInterface->selectionCount(); + + for (int i = selCount - 1; i >= 0; --i) + textInterface->removeSelection(i); + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h new file mode 100644 index 0000000000..6fe6502c41 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIATEXTRANGEPROVIDER_H +#define QWINDOWSUIATEXTRANGEPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Text Range control pattern provider. Used for text controls. +class QWindowsUiaTextRangeProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<ITextRangeProvider> +{ + Q_DISABLE_COPY(QWindowsUiaTextRangeProvider) +public: + explicit QWindowsUiaTextRangeProvider(QAccessible::Id id, int startOffset, int endOffset); + virtual ~QWindowsUiaTextRangeProvider(); + + HRESULT STDMETHODCALLTYPE AddToSelection(); + HRESULT STDMETHODCALLTYPE Clone(ITextRangeProvider **pRetVal); + HRESULT STDMETHODCALLTYPE Compare(ITextRangeProvider *range, BOOL *pRetVal); + HRESULT STDMETHODCALLTYPE CompareEndpoints(TextPatternRangeEndpoint endpoint, ITextRangeProvider *targetRange, TextPatternRangeEndpoint targetEndpoint, int *pRetVal); + HRESULT STDMETHODCALLTYPE ExpandToEnclosingUnit(TextUnit unit); + HRESULT STDMETHODCALLTYPE FindAttribute(TEXTATTRIBUTEID attributeId, VARIANT val, BOOL backward, ITextRangeProvider **pRetVal); + HRESULT STDMETHODCALLTYPE FindText(BSTR text, BOOL backward, BOOL ignoreCase, ITextRangeProvider **pRetVal); + HRESULT STDMETHODCALLTYPE GetAttributeValue(TEXTATTRIBUTEID attributeId, VARIANT *pRetVal); + HRESULT STDMETHODCALLTYPE GetBoundingRectangles(SAFEARRAY **pRetVal); + HRESULT STDMETHODCALLTYPE GetChildren(SAFEARRAY **pRetVal); + HRESULT STDMETHODCALLTYPE GetEnclosingElement(IRawElementProviderSimple **pRetVal); + HRESULT STDMETHODCALLTYPE GetText(int maxLength, BSTR *pRetVal); + HRESULT STDMETHODCALLTYPE Move(TextUnit unit, int count, int *pRetVal); + HRESULT STDMETHODCALLTYPE MoveEndpointByRange(TextPatternRangeEndpoint endpoint, ITextRangeProvider *targetRange, TextPatternRangeEndpoint targetEndpoint); + HRESULT STDMETHODCALLTYPE MoveEndpointByUnit(TextPatternRangeEndpoint endpoint, TextUnit unit, int count, int *pRetVal); + HRESULT STDMETHODCALLTYPE RemoveFromSelection(); + HRESULT STDMETHODCALLTYPE ScrollIntoView(BOOL alignToTop); + HRESULT STDMETHODCALLTYPE Select(); + +private: + HRESULT unselect(); + int m_startOffset; + int m_endOffset; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIATEXTRANGEPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.cpp new file mode 100644 index 0000000000..01cdfd7e91 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiatoggleprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaToggleProvider::QWindowsUiaToggleProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaToggleProvider::~QWindowsUiaToggleProvider() +{ +} + +// toggles the state by invoking the toggle action +HRESULT STDMETHODCALLTYPE QWindowsUiaToggleProvider::Toggle() +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + QAccessibleActionInterface *actionInterface = accessible->actionInterface(); + if (!actionInterface) + return UIA_E_ELEMENTNOTAVAILABLE; + + actionInterface->doAction(QAccessibleActionInterface::toggleAction()); + return S_OK; +} + +// Gets the current toggle state. +HRESULT STDMETHODCALLTYPE QWindowsUiaToggleProvider::get_ToggleState(ToggleState *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = ToggleState_Off; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + if (accessible->state().checked) + *pRetVal = accessible->state().checkStateMixed ? ToggleState_Indeterminate : ToggleState_On; + else + *pRetVal = ToggleState_Off; + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h new file mode 100644 index 0000000000..a0df983e40 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatoggleprovider.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIATOGGLEPROVIDER_H +#define QWINDOWSUIATOGGLEPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Toggle control pattern provider. Used for checkboxes. +class QWindowsUiaToggleProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<IToggleProvider> +{ + Q_DISABLE_COPY(QWindowsUiaToggleProvider) +public: + explicit QWindowsUiaToggleProvider(QAccessible::Id id); + virtual ~QWindowsUiaToggleProvider(); + + // IToggleProvider + HRESULT STDMETHODCALLTYPE Toggle(); + HRESULT STDMETHODCALLTYPE get_ToggleState(ToggleState *pRetVal); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIATOGGLEPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp new file mode 100644 index 0000000000..89e5075dcb --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp @@ -0,0 +1,221 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" +#include "qwindowswindow.h" + +#include <QtGui/QWindow> +#include <QtGui/private/qhighdpiscaling_p.h> +#include <cmath> + +QT_BEGIN_NAMESPACE + +namespace QWindowsUiAutomation { + +// Returns the window containing the element (usually the top window), +QWindow *windowForAccessible(const QAccessibleInterface *accessible) +{ + QWindow *window = accessible->window(); + if (!window) { + QAccessibleInterface *acc = accessible->parent(); + while (acc && acc->isValid() && !window) { + window = acc->window(); + QAccessibleInterface *par = acc->parent(); + acc = par; + } + } + return window; +} + +// Returns the native window handle associated with the element, if any. +// Usually it will be NULL, as Qt5 by default uses alien widgets with no native windows. +HWND hwndForAccessible(const QAccessibleInterface *accessible) +{ + if (QWindow *window = accessible->window()) { + if (!accessible->parent() || (accessible->parent()->window() != window)) { + return QWindowsBaseWindow::handleOf(window); + } + } + return NULL; +} + +void clearVariant(VARIANT *variant) +{ + variant->vt = VT_EMPTY; + variant->punkVal = nullptr; +} + +void setVariantI4(int value, VARIANT *variant) +{ + variant->vt = VT_I4; + variant->lVal = value; +} + +void setVariantBool(bool value, VARIANT *variant) +{ + variant->vt = VT_BOOL; + variant->boolVal = value ? -1 : 0; +} + +void setVariantDouble(double value, VARIANT *variant) +{ + variant->vt = VT_R8; + variant->boolVal = value; +} + +BSTR bStrFromQString(const QString &value) +{ + return SysAllocString(reinterpret_cast<const wchar_t *>(value.utf16())); +} + +void setVariantString(const QString &value, VARIANT *variant) +{ + variant->vt = VT_BSTR; + variant->bstrVal = bStrFromQString(value); +} + +// Scales a rect to native coordinates, according to high dpi settings. +void rectToNativeUiaRect(const QRect &rect, const QWindow *w, UiaRect *uiaRect) +{ + if (w && uiaRect) { + const qreal factor = QHighDpiScaling::factor(w); + uiaRect->left = qreal(rect.x()) * factor; + uiaRect->top = qreal(rect.y()) * factor; + uiaRect->width = qreal(rect.width()) * factor; + uiaRect->height = qreal(rect.height()) * factor; + } +} + +// Scales a point from native coordinates, according to high dpi settings. +void nativeUiaPointToPoint(const UiaPoint &uiaPoint, const QWindow *w, QPoint *point) +{ + if (w && point) { + const qreal factor = QHighDpiScaling::factor(w); + point->setX(int(std::lround(uiaPoint.x / factor))); + point->setY(int(std::lround(uiaPoint.y / factor))); + } +} + +// Maps an accessibility role ID to an UI Automation control type ID. +long roleToControlTypeId(QAccessible::Role role) +{ + static const QHash<QAccessible::Role, long> mapping { + {QAccessible::TitleBar, UIA_TitleBarControlTypeId}, + {QAccessible::MenuBar, UIA_MenuBarControlTypeId}, + {QAccessible::ScrollBar, UIA_ScrollBarControlTypeId}, + {QAccessible::Grip, UIA_ThumbControlTypeId}, + {QAccessible::Sound, UIA_CustomControlTypeId}, + {QAccessible::Cursor, UIA_CustomControlTypeId}, + {QAccessible::Caret, UIA_CustomControlTypeId}, + {QAccessible::AlertMessage, UIA_CustomControlTypeId}, + {QAccessible::Window, UIA_WindowControlTypeId}, + {QAccessible::Client, UIA_CustomControlTypeId}, + {QAccessible::PopupMenu, UIA_MenuControlTypeId}, + {QAccessible::MenuItem, UIA_MenuItemControlTypeId}, + {QAccessible::ToolTip, UIA_ToolTipControlTypeId}, + {QAccessible::Application, UIA_CustomControlTypeId}, + {QAccessible::Document, UIA_DocumentControlTypeId}, + {QAccessible::Pane, UIA_PaneControlTypeId}, + {QAccessible::Chart, UIA_CustomControlTypeId}, + {QAccessible::Dialog, UIA_WindowControlTypeId}, + {QAccessible::Border, UIA_CustomControlTypeId}, + {QAccessible::Grouping, UIA_GroupControlTypeId}, + {QAccessible::Separator, UIA_SeparatorControlTypeId}, + {QAccessible::ToolBar, UIA_ToolBarControlTypeId}, + {QAccessible::StatusBar, UIA_StatusBarControlTypeId}, + {QAccessible::Table, UIA_TableControlTypeId}, + {QAccessible::ColumnHeader, UIA_HeaderControlTypeId}, + {QAccessible::RowHeader, UIA_HeaderControlTypeId}, + {QAccessible::Column, UIA_HeaderItemControlTypeId}, + {QAccessible::Row, UIA_HeaderItemControlTypeId}, + {QAccessible::Cell, UIA_DataItemControlTypeId}, + {QAccessible::Link, UIA_HyperlinkControlTypeId}, + {QAccessible::HelpBalloon, UIA_ToolTipControlTypeId}, + {QAccessible::Assistant, UIA_CustomControlTypeId}, + {QAccessible::List, UIA_ListControlTypeId}, + {QAccessible::ListItem, UIA_ListItemControlTypeId}, + {QAccessible::Tree, UIA_TreeControlTypeId}, + {QAccessible::TreeItem, UIA_TreeItemControlTypeId}, + {QAccessible::PageTab, UIA_TabItemControlTypeId}, + {QAccessible::PropertyPage, UIA_CustomControlTypeId}, + {QAccessible::Indicator, UIA_CustomControlTypeId}, + {QAccessible::Graphic, UIA_ImageControlTypeId}, + {QAccessible::StaticText, UIA_EditControlTypeId}, + {QAccessible::EditableText, UIA_EditControlTypeId}, + {QAccessible::Button, UIA_ButtonControlTypeId}, + {QAccessible::CheckBox, UIA_CheckBoxControlTypeId}, + {QAccessible::RadioButton, UIA_RadioButtonControlTypeId}, + {QAccessible::ComboBox, UIA_ComboBoxControlTypeId}, + {QAccessible::ProgressBar, UIA_ProgressBarControlTypeId}, + {QAccessible::Dial, UIA_CustomControlTypeId}, + {QAccessible::HotkeyField, UIA_CustomControlTypeId}, + {QAccessible::Slider, UIA_SliderControlTypeId}, + {QAccessible::SpinBox, UIA_SpinnerControlTypeId}, + {QAccessible::Canvas, UIA_CustomControlTypeId}, + {QAccessible::Animation, UIA_CustomControlTypeId}, + {QAccessible::Equation, UIA_CustomControlTypeId}, + {QAccessible::ButtonDropDown, UIA_ButtonControlTypeId}, + {QAccessible::ButtonMenu, UIA_ButtonControlTypeId}, + {QAccessible::ButtonDropGrid, UIA_ButtonControlTypeId}, + {QAccessible::Whitespace, UIA_CustomControlTypeId}, + {QAccessible::PageTabList, UIA_TabControlTypeId}, + {QAccessible::Clock, UIA_CustomControlTypeId}, + {QAccessible::Splitter, UIA_CustomControlTypeId}, + }; + + return mapping.value(role, UIA_CustomControlTypeId); +} + +// True if a character can be a separator for a text unit. +bool isTextUnitSeparator(TextUnit unit, const QChar &ch) +{ + return (((unit == TextUnit_Word) || (unit == TextUnit_Format)) && ch.isSpace()) + || ((unit == TextUnit_Line) && (ch.toLatin1() == '\n')); +} + +} // namespace QWindowsUiAutomation + + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.h new file mode 100644 index 0000000000..15f4d6e8ba --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIAUTILS_H +#define QWINDOWSUIAUTILS_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include <QtCore/QString> +#include <QtCore/qt_windows.h> +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtGui/QWindow> +#include <QtCore/QDebug> +#include <QtCore/QRect> +#include <QtWindowsUIAutomationSupport/private/qwindowsuiawrapper_p.h> + +QT_BEGIN_NAMESPACE + +namespace QWindowsUiAutomation { + +QWindow *windowForAccessible(const QAccessibleInterface *accessible); + +HWND hwndForAccessible(const QAccessibleInterface *accessible); + +void rectToNativeUiaRect(const QRect &rect, const QWindow *w, UiaRect *uiaRect); + +void nativeUiaPointToPoint(const UiaPoint &uiaPoint, const QWindow *w, QPoint *point); + +long roleToControlTypeId(QAccessible::Role role); + +bool isTextUnitSeparator(TextUnit unit, const QChar &ch); + +void clearVariant(VARIANT *variant); + +void setVariantI4(int value, VARIANT *variant); + +void setVariantBool(bool value, VARIANT *variant); + +void setVariantDouble(double value, VARIANT *variant); + +BSTR bStrFromQString(const QString &value); + +void setVariantString(const QString &value, VARIANT *variant); + +} // namespace QWindowsUiAutomation + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIAUTILS_H diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.cpp new file mode 100644 index 0000000000..ef7d564e22 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiavalueprovider.h" +#include "qwindowsuiautils.h" +#include "qwindowscontext.h" + +#include <QtGui/QAccessible> +#include <QtGui/QAccessibleInterface> +#include <QtCore/QDebug> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +using namespace QWindowsUiAutomation; + + +QWindowsUiaValueProvider::QWindowsUiaValueProvider(QAccessible::Id id) : + QWindowsUiaBaseProvider(id) +{ +} + +QWindowsUiaValueProvider::~QWindowsUiaValueProvider() +{ +} + +// Sets the value associated with the control. +HRESULT STDMETHODCALLTYPE QWindowsUiaValueProvider::SetValue(LPCWSTR val) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + // First sets the value as a text. + QString strVal = QString::fromUtf16(reinterpret_cast<const ushort *>(val)); + accessible->setText(QAccessible::Value, strVal); + + // Then, if the control supports the value interface (range value) + // and the supplied text can be converted to a number, and that number + // lies within the min/max limits, sets it as the control's current (numeric) value. + if (QAccessibleValueInterface *valueInterface = accessible->valueInterface()) { + bool ok = false; + double numval = strVal.toDouble(&ok); + if (ok) { + double minimum = valueInterface->minimumValue().toDouble(); + double maximum = valueInterface->maximumValue().toDouble(); + if ((numval >= minimum) && (numval <= maximum)) { + valueInterface->setCurrentValue(QVariant(numval)); + } + } + } + return S_OK; +} + +// True for read-only controls. +HRESULT STDMETHODCALLTYPE QWindowsUiaValueProvider::get_IsReadOnly(BOOL *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = FALSE; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = accessible->state().readOnly; + return S_OK; +} + +// Returns the value in text form. +HRESULT STDMETHODCALLTYPE QWindowsUiaValueProvider::get_Value(BSTR *pRetVal) +{ + qCDebug(lcQpaUiAutomation) << __FUNCTION__; + + if (!pRetVal) + return E_INVALIDARG; + *pRetVal = nullptr; + + QAccessibleInterface *accessible = accessibleInterface(); + if (!accessible) + return UIA_E_ELEMENTNOTAVAILABLE; + + *pRetVal = bStrFromQString(accessible->text(QAccessible::Value)); + return S_OK; +} + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h new file mode 100644 index 0000000000..db54fc0a46 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiavalueprovider.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSUIAVALUEPROVIDER_H +#define QWINDOWSUIAVALUEPROVIDER_H + +#include <QtCore/QtConfig> +#ifndef QT_NO_ACCESSIBILITY + +#include "qwindowsuiabaseprovider.h" + +QT_BEGIN_NAMESPACE + +// Implements the Value control pattern provider. +// Supported for all controls that can return text(QAccessible::Value). +class QWindowsUiaValueProvider : public QWindowsUiaBaseProvider, + public QWindowsComBase<IValueProvider> +{ + Q_DISABLE_COPY(QWindowsUiaValueProvider) +public: + explicit QWindowsUiaValueProvider(QAccessible::Id id); + virtual ~QWindowsUiaValueProvider(); + + // IValueProvider + HRESULT STDMETHODCALLTYPE SetValue(LPCWSTR val); + HRESULT STDMETHODCALLTYPE get_IsReadOnly(BOOL *pRetVal); + HRESULT STDMETHODCALLTYPE get_Value(BSTR *pRetVal); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY + +#endif // QWINDOWSUIAVALUEPROVIDER_H diff --git a/src/plugins/platforms/windows/uiautomation/uiautomation.pri b/src/plugins/platforms/windows/uiautomation/uiautomation.pri new file mode 100644 index 0000000000..e3071766d9 --- /dev/null +++ b/src/plugins/platforms/windows/uiautomation/uiautomation.pri @@ -0,0 +1,43 @@ +qtHaveModule(windowsuiautomation_support-private): \ + QT += windowsuiautomation_support-private + +SOURCES += \ + $$PWD/qwindowsuiaaccessibility.cpp \ + $$PWD/qwindowsuiaprovidercache.cpp \ + $$PWD/qwindowsuiamainprovider.cpp \ + $$PWD/qwindowsuiabaseprovider.cpp \ + $$PWD/qwindowsuiavalueprovider.cpp \ + $$PWD/qwindowsuiatextprovider.cpp \ + $$PWD/qwindowsuiatextrangeprovider.cpp \ + $$PWD/qwindowsuiatoggleprovider.cpp \ + $$PWD/qwindowsuiaselectionprovider.cpp \ + $$PWD/qwindowsuiaselectionitemprovider.cpp \ + $$PWD/qwindowsuiainvokeprovider.cpp \ + $$PWD/qwindowsuiarangevalueprovider.cpp \ + $$PWD/qwindowsuiatableprovider.cpp \ + $$PWD/qwindowsuiatableitemprovider.cpp \ + $$PWD/qwindowsuiagridprovider.cpp \ + $$PWD/qwindowsuiagriditemprovider.cpp \ + $$PWD/qwindowsuiautils.cpp + +HEADERS += \ + $$PWD/qwindowsuiaaccessibility.h \ + $$PWD/qwindowsuiaprovidercache.h \ + $$PWD/qwindowsuiamainprovider.h \ + $$PWD/qwindowsuiabaseprovider.h \ + $$PWD/qwindowsuiavalueprovider.h \ + $$PWD/qwindowsuiatextprovider.h \ + $$PWD/qwindowsuiatextrangeprovider.h \ + $$PWD/qwindowsuiatoggleprovider.h \ + $$PWD/qwindowsuiaselectionprovider.h \ + $$PWD/qwindowsuiaselectionitemprovider.h \ + $$PWD/qwindowsuiainvokeprovider.h \ + $$PWD/qwindowsuiarangevalueprovider.h \ + $$PWD/qwindowsuiatableprovider.h \ + $$PWD/qwindowsuiatableitemprovider.h \ + $$PWD/qwindowsuiagridprovider.h \ + $$PWD/qwindowsuiagriditemprovider.h \ + $$PWD/qwindowsuiautils.h + +mingw: LIBS *= -luuid + diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index b7790a66e3..f4c396f7c5 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -53,7 +53,7 @@ HEADERS += \ $$PWD/qwindowsservices.h \ $$PWD/qwindowsnativeinterface.h \ $$PWD/qwindowsopengltester.h \ - $$PWD/qwindowsthreadpoolrunner.h + $$PWD/qwindowsthreadpoolrunner.h \ $$PWD/qwin10helpers.h INCLUDEPATH += $$PWD @@ -109,7 +109,7 @@ qtConfig(imageformat_png):RESOURCES += $$PWD/cursors.qrc RESOURCES += $$PWD/openglblacklists.qrc -qtConfig(accessibility): include($$PWD/accessible/accessible.pri) +qtConfig(accessibility): include($$PWD/uiautomation/uiautomation.pri) qtConfig(combined-angle-lib) { DEFINES *= LIBEGL_NAME=$${LIBQTANGLE_NAME} diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp index 117cb515df..05c34b82f8 100644 --- a/src/plugins/platforms/winrt/qwinrtclipboard.cpp +++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp @@ -59,7 +59,7 @@ typedef IEventHandler<IInspectable *> ContentChangedHandler; QT_BEGIN_NAMESPACE QWinRTClipboard::QWinRTClipboard() - : m_mimeData(Q_NULLPTR) + : m_mimeData(nullptr) { QEventDispatcherWinRT::runOnXamlThread([this]() { HRESULT hr; diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp index 28a5f73e6e..3c918df935 100644 --- a/src/plugins/platforms/winrt/qwinrtcursor.cpp +++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp @@ -89,7 +89,7 @@ void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *window) switch (windowCursor ? windowCursor->shape() : Qt::ArrowCursor) { case Qt::BlankCursor: hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow]() { - coreWindow->put_PointerCursor(Q_NULLPTR); + coreWindow->put_PointerCursor(nullptr); return S_OK; }); RETURN_VOID_IF_FAILED("Failed to set blank native cursor"); diff --git a/src/plugins/platforms/winrt/qwinrtdrag.cpp b/src/plugins/platforms/winrt/qwinrtdrag.cpp index 43c406e1fb..0c918230b3 100644 --- a/src/plugins/platforms/winrt/qwinrtdrag.cpp +++ b/src/plugins/platforms/winrt/qwinrtdrag.cpp @@ -104,7 +104,7 @@ class DragThreadTransferData : public QObject public slots: void handleDrag(); public: - explicit DragThreadTransferData(QObject *parent = Q_NULLPTR); + explicit DragThreadTransferData(QObject *parent = nullptr); QWindow *window; QWinRTInternalMimeData *mime; QPoint point; diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp index 62eacba89b..3c90334c8c 100644 --- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp +++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp @@ -83,7 +83,7 @@ public: } HRESULT __stdcall GetView(IVectorView<HSTRING> **view) { - *view = Q_NULLPTR; + *view = nullptr; return E_NOTIMPL; } HRESULT __stdcall IndexOf(HSTRING value, quint32 *index, boolean *found) diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp index f037c516b5..76efdf6cc8 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp +++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp @@ -144,7 +144,7 @@ QAbstractFileEngine *QWinRTFileEngineHandler::create(const QString &fileName) co if (file != d->files.end()) return new QWinRTFileEngine(fileName, file.value().Get()); - return Q_NULLPTR; + return nullptr; } static HRESULT getDestinationFolder(const QString &fileName, const QString &newFileName, diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index c370c2ec50..7b9502f9ab 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -497,7 +497,7 @@ QWinRTScreen::QWinRTScreen() Q_D(QWinRTScreen); qCDebug(lcQpaWindows) << __FUNCTION__; d->orientation = Qt::PrimaryOrientation; - d->touchDevice = Q_NULLPTR; + d->touchDevice = nullptr; HRESULT hr; ComPtr<Xaml::IWindowStatics> windowStatics; @@ -540,7 +540,7 @@ QWinRTScreen::QWinRTScreen() Q_ASSERT_SUCCEEDED(hr); d->nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation))); // Set initial pixel density - onDpiChanged(Q_NULLPTR, Q_NULLPTR); + onDpiChanged(nullptr, nullptr); d->orientation = d->nativeOrientation; ComPtr<IApplicationViewStatics2> applicationViewStatics; @@ -764,7 +764,7 @@ void QWinRTScreen::initialize() Q_ASSERT_SUCCEEDED(hr); hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]); Q_ASSERT_SUCCEEDED(hr); - onOrientationChanged(Q_NULLPTR, Q_NULLPTR); + onOrientationChanged(nullptr, nullptr); onVisibilityChanged(nullptr, nullptr); hr = d->redirect->add_PointerRoutedReleased(Callback<RedirectHandler>(this, &QWinRTScreen::onRedirectReleased).Get(), &d->redirectTokens[&ICorePointerRedirector::remove_PointerRoutedReleased]); @@ -864,7 +864,7 @@ void QWinRTScreen::removeWindow(QWindow *window) const Qt::WindowType type = window->type(); if (wasTopWindow && type != Qt::Popup && type != Qt::ToolTip && type != Qt::Tool) - QWindowSystemInterface::handleWindowActivated(Q_NULLPTR, Qt::OtherFocusReason); + QWindowSystemInterface::handleWindowActivated(nullptr, Qt::OtherFocusReason); handleExpose(); QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); #ifndef QT_NO_DRAGANDDROP diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h index a8992450b9..9604b4bbaa 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.h +++ b/src/plugins/platforms/winrt/qwinrtwindow.h @@ -70,8 +70,8 @@ public: qreal devicePixelRatio() const override; void setWindowState(Qt::WindowStates state) override; - bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE; - bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE; + bool setMouseGrabEnabled(bool grab) override; + bool setKeyboardGrabEnabled(bool grab) override; EGLSurface eglSurface() const; void createEglSurface(EGLDisplay display, EGLConfig config); diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h index 926e5e22df..07e983a499 100644 --- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h +++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h @@ -69,7 +69,7 @@ public: #endif virtual QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const = 0; - virtual QXcbNativeInterfaceHandler *nativeInterfaceHandler() const { return Q_NULLPTR; } + virtual QXcbNativeInterfaceHandler *nativeInterfaceHandler() const { return nullptr; } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbnativeinterfacehandler.cpp b/src/plugins/platforms/xcb/gl_integrations/qxcbnativeinterfacehandler.cpp index ac992b859d..e18656c6ec 100644 --- a/src/plugins/platforms/xcb/gl_integrations/qxcbnativeinterfacehandler.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/qxcbnativeinterfacehandler.cpp @@ -56,37 +56,37 @@ QXcbNativeInterfaceHandler::~QXcbNativeInterfaceHandler() QPlatformNativeInterface::NativeResourceForIntegrationFunction QXcbNativeInterfaceHandler::nativeResourceFunctionForIntegration(const QByteArray &resource) const { Q_UNUSED(resource); - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterfaceHandler::nativeResourceFunctionForContext(const QByteArray &resource) const { Q_UNUSED(resource); - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterfaceHandler::nativeResourceFunctionForScreen(const QByteArray &resource) const { Q_UNUSED(resource); - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForWindowFunction QXcbNativeInterfaceHandler::nativeResourceFunctionForWindow(const QByteArray &resource) const { Q_UNUSED(resource); - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForBackingStoreFunction QXcbNativeInterfaceHandler::nativeResourceFunctionForBackingStore(const QByteArray &resource) const { Q_UNUSED(resource); - return Q_NULLPTR; + return nullptr; } QFunctionPointer QXcbNativeInterfaceHandler::platformFunction(const QByteArray &function) const { Q_UNUSED(function); - return Q_NULLPTR; + return nullptr; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp index 7aa1d631df..fe18bc24db 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglintegration.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE QXcbEglIntegration::QXcbEglIntegration() - : m_connection(Q_NULLPTR) + : m_connection(nullptr) , m_egl_display(EGL_NO_DISPLAY) { qCDebug(lcQpaGl) << "Xcb EGL gl-integration created"; diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglnativeinterfacehandler.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglnativeinterfacehandler.cpp index 30f5e3a00d..c0e3f820fe 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglnativeinterfacehandler.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglnativeinterfacehandler.cpp @@ -77,7 +77,7 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QXcbEglNativeInte default: break; } - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForContextFunction QXcbEglNativeInterfaceHandler::nativeResourceFunctionForContext(const QByteArray &resource) const @@ -90,7 +90,7 @@ QPlatformNativeInterface::NativeResourceForContextFunction QXcbEglNativeInterfac default: break; } - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForWindowFunction QXcbEglNativeInterfaceHandler::nativeResourceFunctionForWindow(const QByteArray &resource) const @@ -101,7 +101,7 @@ QPlatformNativeInterface::NativeResourceForWindowFunction QXcbEglNativeInterface default: break; } - return Q_NULLPTR; + return nullptr; } void *QXcbEglNativeInterfaceHandler::eglDisplay() @@ -114,11 +114,11 @@ void *QXcbEglNativeInterfaceHandler::eglDisplay() void *QXcbEglNativeInterfaceHandler::eglDisplayForWindow(QWindow *window) { Q_ASSERT(window); - if (window->supportsOpenGL() && window->handle() == Q_NULLPTR) + if (window->supportsOpenGL() && window->handle() == nullptr) return eglDisplay(); else if (window->supportsOpenGL()) return static_cast<QXcbEglWindow *>(window->handle())->glIntegration()->eglDisplay(); - return Q_NULLPTR; + return nullptr; } void *QXcbEglNativeInterfaceHandler::eglContextForContext(QOpenGLContext *context) diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp index 9c3fd26d49..65beac227c 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglwindow.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE QXcbEglWindow::QXcbEglWindow(QWindow *window, QXcbEglIntegration *glIntegration) : QXcbWindow(window) , m_glIntegration(glIntegration) - , m_config(Q_NULLPTR) + , m_config(nullptr) , m_surface(EGL_NO_SURFACE) { } diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 3bc8590d36..56a737e882 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -321,7 +321,7 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share) if (!m_context && m_shareContext) { // re-try without a shared glx context m_shareContext = 0; - m_context = glXCreateContext(m_display, visualInfo, Q_NULLPTR, true); + m_context = glXCreateContext(m_display, visualInfo, nullptr, true); } // Create a temporary window so that we can make the new context current @@ -470,7 +470,7 @@ static QXcbScreen *screenForPlatformSurface(QPlatformSurface *surface) } else if (surfaceClass == QSurface::Offscreen) { return static_cast<QXcbScreen *>(static_cast<QGLXPbuffer *>(surface)->screen()); } - return Q_NULLPTR; + return nullptr; } QVariant QGLXContext::nativeHandle() const diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp index 377066df61..13f03f8bf3 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxintegration.cpp @@ -87,7 +87,7 @@ QT_BEGIN_NAMESPACE #endif QXcbGlxIntegration::QXcbGlxIntegration() - : m_connection(Q_NULLPTR) + : m_connection(nullptr) , m_glx_first_event(0) { qCDebug(lcQpaGl) << "Xcb GLX gl-integration created"; diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxnativeinterfacehandler.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxnativeinterfacehandler.cpp index 638fdd46b5..e9bb4460ff 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxnativeinterfacehandler.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxnativeinterfacehandler.cpp @@ -72,7 +72,7 @@ QPlatformNativeInterface::NativeResourceForContextFunction QXcbGlxNativeInterfac default: break; } - return Q_NULLPTR; + return nullptr; } void *QXcbGlxNativeInterfaceHandler::glxContextForContext(QOpenGLContext *context) diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp index 145a11a5e3..d682ea87fb 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp @@ -58,7 +58,7 @@ const xcb_visualtype_t *QXcbGlxWindow::createVisual() { QXcbScreen *scr = xcbScreen(); if (!scr) - return Q_NULLPTR; + return nullptr; qDebug(lcQpaGl) << "Requested format before FBConfig/Visual selection:" << m_format; @@ -74,7 +74,7 @@ const xcb_visualtype_t *QXcbGlxWindow::createVisual() XVisualInfo *visualInfo = qglx_findVisualInfo(dpy, scr->screenNumber(), &m_format, GLX_WINDOW_BIT, flags); if (!visualInfo) { qWarning() << "No XVisualInfo for format" << m_format; - return Q_NULLPTR; + return nullptr; } const xcb_visualtype_t *xcb_visualtype = scr->visualForId(visualInfo->visualid); XFree(visualInfo); diff --git a/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp index 2dd2cdd9e3..cb2bbafee1 100644 --- a/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp +++ b/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp @@ -115,7 +115,7 @@ void QXcbNativeBackingStore::flush(QWindow *window, const QRegion ®ion, const else #endif { - GC gc = XCreateGC(display(), wid, 0, Q_NULLPTR); + GC gc = XCreateGC(display(), wid, 0, nullptr); if (clipRects.size() != 1) XSetClipRectangles(display(), gc, 0, 0, clipRects.data(), clipRects.size(), YXBanded); @@ -155,7 +155,7 @@ void QXcbNativeBackingStore::resize(const QSize &size, const QRegion &staticCont QRect br = staticContents.boundingRect().intersected(QRect(QPoint(0, 0), size)); if (!br.isEmpty()) { - GC gc = XCreateGC(display(), to, 0, Q_NULLPTR); + GC gc = XCreateGC(display(), to, 0, nullptr); XCopyArea(display(), from, to, gc, br.x(), br.y(), br.width(), br.height(), br.x(), br.y()); XFreeGC(display(), gc); } @@ -172,7 +172,7 @@ bool QXcbNativeBackingStore::scroll(const QRegion &area, int dx, int dy) QRect rect = area.boundingRect(); Pixmap pix = qt_x11PixmapHandle(m_pixmap); - GC gc = XCreateGC(display(), pix, 0, Q_NULLPTR); + GC gc = XCreateGC(display(), pix, 0, nullptr); XCopyArea(display(), pix, pix, gc, rect.x(), rect.y(), rect.width(), rect.height(), rect.x()+dx, rect.y()+dy); diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h index 34b5d929d5..a0dd6cdf74 100644 --- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h +++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h @@ -56,10 +56,10 @@ public: QX11PaintEngine(); ~QX11PaintEngine(); - bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE; - bool end() Q_DECL_OVERRIDE; + bool begin(QPaintDevice *pdev) override; + bool end() override; - void updateState(const QPaintEngineState &state) Q_DECL_OVERRIDE; + void updateState(const QPaintEngineState &state) override; void updatePen(const QPen &pen); void updateBrush(const QBrush &brush, const QPointF &pt); @@ -68,31 +68,31 @@ public: void updateMatrix(const QTransform &matrix); void updateClipRegion_dev(const QRegion ®ion, Qt::ClipOperation op); - void drawLines(const QLine *lines, int lineCount) Q_DECL_OVERRIDE; - void drawLines(const QLineF *lines, int lineCount) Q_DECL_OVERRIDE; + void drawLines(const QLine *lines, int lineCount) override; + void drawLines(const QLineF *lines, int lineCount) override; - void drawRects(const QRect *rects, int rectCount) Q_DECL_OVERRIDE; - void drawRects(const QRectF *rects, int rectCount) Q_DECL_OVERRIDE; + void drawRects(const QRect *rects, int rectCount) override; + void drawRects(const QRectF *rects, int rectCount) override; - void drawPoints(const QPoint *points, int pointCount) Q_DECL_OVERRIDE; - void drawPoints(const QPointF *points, int pointCount) Q_DECL_OVERRIDE; + void drawPoints(const QPoint *points, int pointCount) override; + void drawPoints(const QPointF *points, int pointCount) override; - void drawEllipse(const QRect &r) Q_DECL_OVERRIDE; - void drawEllipse(const QRectF &r) Q_DECL_OVERRIDE; + void drawEllipse(const QRect &r) override; + void drawEllipse(const QRectF &r) override; - virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE; - inline void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE + virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override; + inline void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) override { QPaintEngine::drawPolygon(points, pointCount, mode); } - void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE; - void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) Q_DECL_OVERRIDE; - void drawPath(const QPainterPath &path) Q_DECL_OVERRIDE; - void drawTextItem(const QPointF &p, const QTextItem &textItem) Q_DECL_OVERRIDE; + void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override; + void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) override; + void drawPath(const QPainterPath &path) override; + void drawTextItem(const QPointF &p, const QTextItem &textItem) override; void drawImage(const QRectF &r, const QImage &img, const QRectF &sr, - Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE; + Qt::ImageConversionFlags flags = Qt::AutoColor) override; virtual Drawable handle() const; - inline Type type() const Q_DECL_OVERRIDE { return QPaintEngine::X11; } + inline Type type() const override { return QPaintEngine::X11; } QPainter::RenderHints supportedRenderHints() const; diff --git a/src/plugins/platforms/xcb/nativepainting/qpixmap_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qpixmap_x11_p.h index 2cbd1fe3d0..79e607c6f8 100644 --- a/src/plugins/platforms/xcb/nativepainting/qpixmap_x11_p.h +++ b/src/plugins/platforms/xcb/nativepainting/qpixmap_x11_p.h @@ -56,22 +56,22 @@ public: QX11PlatformPixmap(PixelType pixelType); ~QX11PlatformPixmap(); - QPlatformPixmap *createCompatiblePlatformPixmap() const Q_DECL_OVERRIDE; - void resize(int width, int height) Q_DECL_OVERRIDE; - void fromImage(const QImage &img, Qt::ImageConversionFlags flags) Q_DECL_OVERRIDE; - void copy(const QPlatformPixmap *data, const QRect &rect) Q_DECL_OVERRIDE; - bool scroll(int dx, int dy, const QRect &rect) Q_DECL_OVERRIDE; - int metric(QPaintDevice::PaintDeviceMetric metric) const Q_DECL_OVERRIDE; - void fill(const QColor &fillColor) Q_DECL_OVERRIDE; - QBitmap mask() const Q_DECL_OVERRIDE; - void setMask(const QBitmap &mask) Q_DECL_OVERRIDE; - bool hasAlphaChannel() const Q_DECL_OVERRIDE; - QPixmap transformed(const QTransform &matrix, Qt::TransformationMode mode) const Q_DECL_OVERRIDE; - QImage toImage() const Q_DECL_OVERRIDE; - QImage toImage(const QRect &rect) const Q_DECL_OVERRIDE; - QPaintEngine *paintEngine() const Q_DECL_OVERRIDE; - qreal devicePixelRatio() const Q_DECL_OVERRIDE; - void setDevicePixelRatio(qreal scaleFactor) Q_DECL_OVERRIDE; + QPlatformPixmap *createCompatiblePlatformPixmap() const override; + void resize(int width, int height) override; + void fromImage(const QImage &img, Qt::ImageConversionFlags flags) override; + void copy(const QPlatformPixmap *data, const QRect &rect) override; + bool scroll(int dx, int dy, const QRect &rect) override; + int metric(QPaintDevice::PaintDeviceMetric metric) const override; + void fill(const QColor &fillColor) override; + QBitmap mask() const override; + void setMask(const QBitmap &mask) override; + bool hasAlphaChannel() const override; + QPixmap transformed(const QTransform &matrix, Qt::TransformationMode mode) const override; + QImage toImage() const override; + QImage toImage(const QRect &rect) const override; + QPaintEngine *paintEngine() const override; + qreal devicePixelRatio() const override; + void setDevicePixelRatio(qreal scaleFactor) override; inline Drawable handle() const { return hd; } inline Picture x11PictureHandle() const { return picture; } @@ -123,7 +123,7 @@ inline QX11PlatformPixmap *qt_x11Pixmap(const QPixmap &pixmap) { return (pixmap.handle() && pixmap.handle()->classId() == QPlatformPixmap::X11Class) ? static_cast<QX11PlatformPixmap *>(pixmap.handle()) - : Q_NULLPTR; + : nullptr; } inline Picture qt_x11PictureHandle(const QPixmap &pixmap) diff --git a/src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.cpp b/src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.cpp index ccb421d868..7731f6c806 100644 --- a/src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.cpp +++ b/src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.cpp @@ -38,7 +38,7 @@ QT_BEGIN_NAMESPACE -QXcbX11Data *qt_x11Data = Q_NULLPTR; +QXcbX11Data *qt_x11Data = nullptr; void qt_xcb_native_x11_info_init(QXcbConnection *conn) { @@ -122,7 +122,7 @@ class QXcbX11InfoData : public QSharedData, public QX11InfoData {}; QXcbX11Info::QXcbX11Info() - : d(Q_NULLPTR) + : d(nullptr) {} QXcbX11Info::~QXcbX11Info() diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 420d1ac7c5..32a381bc4f 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -145,7 +145,7 @@ private: QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format) : QXcbObject(screen->connection()) - , m_graphics_buffer(Q_NULLPTR) + , m_graphics_buffer(nullptr) , m_gc(0) , m_gc_drawable(0) , m_xcb_pixmap(0) @@ -265,7 +265,7 @@ void QXcbShmImage::destroy() if (m_gc) xcb_free_gc(xcb_connection(), m_gc); delete m_graphics_buffer; - m_graphics_buffer = Q_NULLPTR; + m_graphics_buffer = nullptr; if (m_xcb_pixmap) { xcb_free_pixmap(xcb_connection(), m_xcb_pixmap); @@ -565,7 +565,7 @@ QImage QXcbBackingStore::toImage() const QPlatformGraphicsBuffer *QXcbBackingStore::graphicsBuffer() const { - return m_image ? m_image->graphicsBuffer() : Q_NULLPTR; + return m_image ? m_image->graphicsBuffer() : nullptr; } void QXcbBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 536c709dbe..c5eae20266 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -369,7 +369,7 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen) // If there are no other screens on the same virtual desktop, // then transform the physical screen into a fake screen. const QString nameWas = screen->name(); - screen->setOutput(XCB_NONE, Q_NULLPTR); + screen->setOutput(XCB_NONE, nullptr); qCDebug(lcQpaScreen) << "transformed" << nameWas << "to fake" << screen; } else { // There is more than one screen on the same virtual desktop, remove the screen @@ -395,7 +395,7 @@ void QXcbConnection::initializeScreens() { xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); int xcbScreenNumber = 0; // screen number in the xcb sense - QXcbScreen *primaryScreen = Q_NULLPTR; + QXcbScreen *primaryScreen = nullptr; while (it.rem) { // Each "screen" in xcb terminology is a virtual desktop, // potentially a collection of separate juxtaposed monitors. @@ -415,7 +415,7 @@ void QXcbConnection::initializeScreens() qWarning("failed to get the current screen resources"); } else { xcb_timestamp_t timestamp = 0; - xcb_randr_output_t *outputs = Q_NULLPTR; + xcb_randr_output_t *outputs = nullptr; int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.get()); if (outputCount) { timestamp = resources_current->config_timestamp; @@ -487,7 +487,7 @@ void QXcbConnection::initializeScreens() while (it.rem) { xcb_xinerama_screen_info_t *screen_info = it.data; QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, - XCB_NONE, Q_NULLPTR, + XCB_NONE, nullptr, screen_info, it.index); siblings << screen; m_screens << screen; @@ -498,7 +498,7 @@ void QXcbConnection::initializeScreens() if (siblings.isEmpty()) { // If there are no XRandR outputs or XRandR extension is missing, // then create a fake/legacy screen. - QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, XCB_NONE, Q_NULLPTR); + QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, XCB_NONE, nullptr); qCDebug(lcQpaScreen) << "created fake screen" << screen; m_screens << screen; if (m_primaryScreenNumber == xcbScreenNumber) { @@ -631,7 +631,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra if (m_glIntegration && !m_glIntegration->initialize(this)) { qCDebug(lcQpaGl) << "Failed to initialize xcb gl-integration" << glIntegrationNames.at(i); delete m_glIntegration; - m_glIntegration = Q_NULLPTR; + m_glIntegration = nullptr; } } if (!m_glIntegration) @@ -689,7 +689,7 @@ QXcbScreen *QXcbConnection::primaryScreen() const return m_screens.first(); } - return Q_NULLPTR; + return nullptr; } void QXcbConnection::addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener) @@ -983,6 +983,12 @@ static Qt::MouseButtons translateMouseButtons(int s) return ret; } +void QXcbConnection::setButtonState(Qt::MouseButton button, bool down) +{ + m_buttonState.setFlag(button, down); + m_button = button; +} + Qt::MouseButton QXcbConnection::translateMouseButton(xcb_button_t s) { switch (s) { @@ -1055,7 +1061,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) // the event explicitly contains the state of the three first buttons, // the rest we need to manage ourselves m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state); - m_buttonState |= translateMouseButton(ev->detail); + setButtonState(translateMouseButton(ev->detail), true); if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "legacy mouse press, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttonState)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent); @@ -1064,7 +1070,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) xcb_button_release_event_t *ev = (xcb_button_release_event_t *)event; m_keyboard->updateXKBStateFromCore(ev->state); m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state); - m_buttonState &= ~translateMouseButton(ev->detail); + setButtonState(translateMouseButton(ev->detail), false); if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "legacy mouse release, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttonState)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); @@ -1413,7 +1419,7 @@ void QXcbConnection::setFocusWindow(QWindow *w) void QXcbConnection::setMouseGrabber(QXcbWindow *w) { m_mouseGrabber = w; - m_mousePressWindow = Q_NULLPTR; + m_mousePressWindow = nullptr; } void QXcbConnection::setMousePressWindow(QXcbWindow *w) { @@ -2070,7 +2076,8 @@ const xcb_format_t *QXcbConnection::formatForDepth(uint8_t depth) const xcb_format_next(&iterator); } - return 0; + qWarning() << "XCB failed to find an xcb_format_t for depth:" << depth; + return nullptr; } void QXcbConnection::sync() diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 999dc0630c..725c01f77d 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -409,6 +409,15 @@ public: const xcb_setup_t *setup() const { return m_setup; } const xcb_format_t *formatForDepth(uint8_t depth) const; + bool imageNeedsEndianSwap() const + { +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + return m_setup->image_byte_order != XCB_IMAGE_ORDER_MSB_FIRST; +#else + return m_setup->image_byte_order != XCB_IMAGE_ORDER_LSB_FIRST; +#endif + } + QXcbKeyboard *keyboard() const { return m_keyboard; } #ifndef QT_NO_CLIPBOARD @@ -476,8 +485,9 @@ public: xcb_window_t getSelectionOwner(xcb_atom_t atom) const; xcb_window_t getQtSelectionOwner(); - void setButtonState(Qt::MouseButton button, bool down) { m_buttonState.setFlag(button, down); } + void setButtonState(Qt::MouseButton button, bool down); Qt::MouseButtons buttonState() const { return m_buttonState; } + Qt::MouseButton button() const { return m_button; } Qt::MouseButton translateMouseButton(xcb_button_t s); QXcbWindow *focusWindow() const { return m_focusWindow; } @@ -691,6 +701,7 @@ private: bool has_render_extension = false; Qt::MouseButtons m_buttonState = 0; + Qt::MouseButton m_button = Qt::NoButton; QXcbWindow *m_focusWindow = nullptr; QXcbWindow *m_mouseGrabber = nullptr; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index f90f189146..e60b5213ff 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -1333,7 +1333,7 @@ QXcbConnection::TabletData *QXcbConnection::tabletDataForDevice(int id) if (m_tabletData.at(i).deviceId == id) return &m_tabletData[i]; } - return Q_NULLPTR; + return nullptr; } #endif // QT_CONFIG(tabletevent) diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index da63360333..bfa3eccdf8 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -660,7 +660,7 @@ QPoint QXcbCursor::pos() const void QXcbCursor::setPos(const QPoint &pos) { - QXcbVirtualDesktop *virtualDesktop = Q_NULLPTR; + QXcbVirtualDesktop *virtualDesktop = nullptr; queryPointer(connection(), &virtualDesktop, 0); xcb_warp_pointer(xcb_connection(), XCB_NONE, virtualDesktop->root(), 0, 0, 0, 0, pos.x(), pos.y()); xcb_flush(xcb_connection()); diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index d4521de8e0..18f5ff4f0d 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -208,7 +208,7 @@ void QXcbDrag::startDrag() setScreen(current_virtual_desktop->screens().constFirst()->screen()); initiatorWindow = QGuiApplicationPrivate::currentMouseWindow; QBasicDrag::startDrag(); - if (connection()->mouseGrabber() == Q_NULLPTR) + if (connection()->mouseGrabber() == nullptr) shapedPixmapWindow()->setMouseGrabEnabled(true); } @@ -308,7 +308,7 @@ void QXcbDrag::move(const QPoint &globalPos) if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid()) return; - QXcbVirtualDesktop *virtualDesktop = Q_NULLPTR; + QXcbVirtualDesktop *virtualDesktop = nullptr; QPoint cursorPos; QXcbCursor::queryPointer(connection(), &virtualDesktop, &cursorPos); QXcbScreen *screen = virtualDesktop->screenAt(cursorPos); @@ -317,7 +317,7 @@ void QXcbDrag::move(const QPoint &globalPos) if (virtualDesktop != current_virtual_desktop) { setUseCompositing(virtualDesktop->compositingActive()); recreateShapedPixmapWindow(static_cast<QPlatformScreen*>(screen)->screen(), deviceIndependentPos); - if (connection()->mouseGrabber() == Q_NULLPTR) + if (connection()->mouseGrabber() == nullptr) shapedPixmapWindow()->setMouseGrabEnabled(true); current_virtual_desktop = virtualDesktop; diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp index 36536e0602..e18a08755b 100644 --- a/src/plugins/platforms/xcb/qxcbimage.cpp +++ b/src/plugins/platforms/xcb/qxcbimage.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qxcbimage.h" +#include <QtCore/QtEndian> #include <QtGui/QColor> #include <QtGui/private/qimage_p.h> #include <QtGui/private/qdrawhelper_p.h> @@ -52,47 +53,108 @@ extern "C" { #undef template #endif +#include "qxcbconnection.h" +#include "qxcbintegration.h" + +namespace { + +QImage::Format imageFormatForMasks(int depth, int bits_per_pixel, int red_mask, int blue_mask) +{ + if (bits_per_pixel == 32) { + switch (depth) { + case 32: + if (red_mask == 0xff0000 && blue_mask == 0xff) + return QImage::Format_ARGB32_Premultiplied; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + if (red_mask == 0xff && blue_mask == 0xff0000) + return QImage::Format_RGBA8888_Premultiplied; +#else + if (red_mask == 0xff000000 && blue_mask == 0xff00) + return QImage::Format_RGBA8888_Premultiplied; +#endif + if (red_mask == 0x3ff && blue_mask == 0x3ff00000) + return QImage::Format_A2BGR30_Premultiplied; + if (red_mask == 0x3ff00000 && blue_mask == 0x3ff) + return QImage::Format_A2RGB30_Premultiplied; + break; + case 30: + if (red_mask == 0x3ff && blue_mask == 0x3ff00000) + return QImage::Format_BGR30; + if (blue_mask == 0x3ff && red_mask == 0x3ff00000) + return QImage::Format_RGB30; + break; + case 24: + if (red_mask == 0xff0000 && blue_mask == 0xff) + return QImage::Format_RGB32; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + if (red_mask == 0xff && blue_mask == 0xff0000) + return QImage::Format_RGBX8888; +#else + if (red_mask == 0xff000000 && blue_mask == 0xff00) + return QImage::Format_RGBX8888; +#endif + break; + } + } else if (bits_per_pixel == 16) { + if (depth == 16 && red_mask == 0xf800 && blue_mask == 0x1f) + return QImage::Format_RGB16; + if (depth == 15 && red_mask == 0x7c00 && blue_mask == 0x1f) + return QImage::Format_RGB555; + } + return QImage::Format_Invalid; +} + +} // namespace + QT_BEGIN_NAMESPACE -QImage::Format qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t depth, - const xcb_visualtype_t *visual) +bool qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t depth, const xcb_visualtype_t *visual, + QImage::Format *imageFormat, bool *needsRgbSwap) { + Q_ASSERT(connection && visual && imageFormat); + + if (needsRgbSwap) + *needsRgbSwap = false; + *imageFormat = QImage::Format_Invalid; + + if (depth == 8) { + if (visual->_class == XCB_VISUAL_CLASS_GRAY_SCALE) { + *imageFormat = QImage::Format_Grayscale8; + return true; + } +#if QT_CONFIG(xcb_native_painting) + if (QXcbIntegration::instance() && QXcbIntegration::instance()->nativePaintingEnabled()) { + *imageFormat = QImage::Format_Indexed8; + return true; + } +#endif + return false; + } + const xcb_format_t *format = connection->formatForDepth(depth); + if (!format) + return false; + + const bool connectionEndianSwap = connection->imageNeedsEndianSwap(); + // We swap the masks and see if we can recognize it as a host format + const quint32 red_mask = connectionEndianSwap ? qbswap(visual->red_mask) : visual->red_mask; + const quint32 blue_mask = connectionEndianSwap ? qbswap(visual->blue_mask) : visual->blue_mask; - if (!visual || !format) - return QImage::Format_Invalid; - - if (depth == 32 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000 - && visual->green_mask == 0xff00 && visual->blue_mask == 0xff) - return QImage::Format_ARGB32_Premultiplied; - - if (depth == 30 && format->bits_per_pixel == 32 && visual->red_mask == 0x3ff - && visual->green_mask == 0x0ffc00 && visual->blue_mask == 0x3ff00000) - return QImage::Format_BGR30; - - if (depth == 30 && format->bits_per_pixel == 32 && visual->blue_mask == 0x3ff - && visual->green_mask == 0x0ffc00 && visual->red_mask == 0x3ff00000) - return QImage::Format_RGB30; - - if (depth == 24 && format->bits_per_pixel == 32 && visual->red_mask == 0xff0000 - && visual->green_mask == 0xff00 && visual->blue_mask == 0xff) - return QImage::Format_RGB32; - - if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { - if (depth == 24 && format->bits_per_pixel == 32 && visual->blue_mask == 0xff0000 - && visual->green_mask == 0xff00 && visual->red_mask == 0xff) - return QImage::Format_RGBX8888; - } else { - if (depth == 24 && format->bits_per_pixel == 32 && visual->blue_mask == 0xff00 - && visual->green_mask == 0xff0000 && visual->red_mask == 0xff000000) - return QImage::Format_RGBX8888; + *imageFormat = imageFormatForMasks(depth, format->bits_per_pixel, red_mask, blue_mask); + if (*imageFormat != QImage::Format_Invalid) + return true; + + if (needsRgbSwap) { + *imageFormat = imageFormatForMasks(depth, format->bits_per_pixel, blue_mask, red_mask); + if (*imageFormat != QImage::Format_Invalid) { + *needsRgbSwap = true; + return true; + } } - if (depth == 16 && format->bits_per_pixel == 16 && visual->red_mask == 0xf800 - && visual->green_mask == 0x7e0 && visual->blue_mask == 0x1f) - return QImage::Format_RGB16; + qWarning("Unsupported screen format: depth: %d, bits_per_pixel: %d, red_mask: %x, blue_mask: %x", depth, format->bits_per_pixel, red_mask, blue_mask); - return QImage::Format_Invalid; + return false; } QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap, @@ -112,44 +174,14 @@ QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap QPixmap result; - QImage::Format format = qt_xcb_imageFormatForVisual(connection, depth, visual); - if (format != QImage::Format_Invalid) { + QImage::Format format; + bool needsRgbSwap; + if (qt_xcb_imageFormatForVisual(connection, depth, visual, &format, &needsRgbSwap)) { uint32_t bytes_per_line = length / height; QImage image(const_cast<uint8_t *>(data), width, height, bytes_per_line, format); - uint8_t image_byte_order = connection->setup()->image_byte_order; - - // we may have to swap the byte order - if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST) - || (QSysInfo::ByteOrder == QSysInfo::BigEndian && image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST)) - { - for (int i=0; i < image.height(); i++) { - switch (format) { - case QImage::Format_RGB16: { - ushort *p = (ushort*)image.scanLine(i); - ushort *end = p + image.width(); - while (p < end) { - *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff); - p++; - } - break; - } - case QImage::Format_RGB32: - case QImage::Format_ARGB32_Premultiplied: - case QImage::Format_RGBX8888: { - uint *p = (uint*)image.scanLine(i); - uint *end = p + image.width(); - while (p < end) { - *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000) - | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff); - p++; - } - break; - } - default: - Q_ASSERT(false); - } - } - } + + if (needsRgbSwap) + image = std::move(image).rgbSwapped(); // fix-up alpha channel if (format == QImage::Format_RGB32 || format == QImage::Format_RGBX8888) { diff --git a/src/plugins/platforms/xcb/qxcbimage.h b/src/plugins/platforms/xcb/qxcbimage.h index a9071a45de..d718089ec2 100644 --- a/src/plugins/platforms/xcb/qxcbimage.h +++ b/src/plugins/platforms/xcb/qxcbimage.h @@ -48,8 +48,8 @@ QT_BEGIN_NAMESPACE -QImage::Format qt_xcb_imageFormatForVisual(QXcbConnection *connection, - uint8_t depth, const xcb_visualtype_t *visual); +bool qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t depth, const xcb_visualtype_t *visual, + QImage::Format *imageFormat, bool *needsRgbSwap = nullptr); QPixmap qt_xcb_pixmapFromXPixmap(QXcbConnection *connection, xcb_pixmap_t pixmap, int width, int height, int depth, const xcb_visualtype_t *visual); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 72d31060db..6afa7bc934 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -121,7 +121,7 @@ static bool runningUnderDebugger() #endif } -QXcbIntegration *QXcbIntegration::m_instance = Q_NULLPTR; +QXcbIntegration *QXcbIntegration::m_instance = nullptr; QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char **argv) : m_services(new QGenericUnixServices) @@ -222,7 +222,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char QXcbIntegration::~QXcbIntegration() { qDeleteAll(m_connections); - m_instance = Q_NULLPTR; + m_instance = nullptr; } QPlatformPixmap *QXcbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const @@ -274,7 +274,7 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont QXcbGlIntegration *glIntegration = screen->connection()->glIntegration(); if (!glIntegration) { qWarning("QXcbIntegration: Cannot create platform OpenGL context, neither GLX nor EGL are enabled"); - return Q_NULLPTR; + return nullptr; } return glIntegration->createPlatformOpenGLContext(context); } @@ -296,7 +296,7 @@ QPlatformOffscreenSurface *QXcbIntegration::createPlatformOffscreenSurface(QOffs QXcbGlIntegration *glIntegration = screen->connection()->glIntegration(); if (!glIntegration) { qWarning("QXcbIntegration: Cannot create platform offscreen surface, neither GLX nor EGL are enabled"); - return Q_NULLPTR; + return nullptr; } return glIntegration->createPlatformOffscreenSurface(surface); } diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index caa9499c45..d989761297 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -101,7 +101,7 @@ QXcbNativeInterface::QXcbNativeInterface() : static inline QXcbSystemTrayTracker *systemTrayTracker(const QScreen *s) { if (!s) - return Q_NULLPTR; + return nullptr; return static_cast<const QXcbScreen *>(s->handle())->connection()->systemTrayTracker(); } @@ -194,7 +194,7 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resourceStr { if (!screen) { qWarning("nativeResourceForScreen: null screen"); - return Q_NULLPTR; + return nullptr; } QByteArray lowerCaseResource = resourceString.toLower(); @@ -236,7 +236,7 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resourceStr break; case CompositingEnabled: if (QXcbVirtualDesktop *vd = xcbScreen->virtualDesktop()) - result = vd->compositingActive() ? this : Q_NULLPTR; + result = vd->compositingActive() ? this : nullptr; break; default: break; @@ -294,7 +294,7 @@ void *QXcbNativeInterface::nativeResourceForCursor(const QByteArray &resource, c } } } - return Q_NULLPTR; + return nullptr; } #endif // !QT_NO_CURSOR @@ -323,7 +323,7 @@ QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface:: QPlatformNativeInterface::NativeResourceForContextFunction func = handlerNativeResourceFunctionForContext(lowerCaseResource); if (func) return func; - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::nativeResourceFunctionForScreen(const QByteArray &resource) @@ -390,13 +390,13 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio if (function == QXcbScreenFunctions::virtualDesktopNumberIdentifier()) return QFunctionPointer(QXcbScreenFunctions::VirtualDesktopNumber(QXcbScreen::virtualDesktopNumberStatic)); - return Q_NULLPTR; + return nullptr; } void *QXcbNativeInterface::appTime(const QXcbScreen *screen) { if (!screen) - return Q_NULLPTR; + return nullptr; return reinterpret_cast<void *>(quintptr(screen->connection()->time())); } @@ -404,7 +404,7 @@ void *QXcbNativeInterface::appTime(const QXcbScreen *screen) void *QXcbNativeInterface::appUserTime(const QXcbScreen *screen) { if (!screen) - return Q_NULLPTR; + return nullptr; return reinterpret_cast<void *>(quintptr(screen->connection()->netWmUserTime())); } @@ -412,7 +412,7 @@ void *QXcbNativeInterface::appUserTime(const QXcbScreen *screen) void *QXcbNativeInterface::getTimestamp(const QXcbScreen *screen) { if (!screen) - return Q_NULLPTR; + return nullptr; return reinterpret_cast<void *>(quintptr(screen->connection()->getTimestamp())); } @@ -452,7 +452,7 @@ void *QXcbNativeInterface::display() if (defaultConnection) return defaultConnection->xlib_display(); #endif - return Q_NULLPTR; + return nullptr; } void *QXcbNativeInterface::connection() @@ -525,10 +525,10 @@ QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window) QXcbScreen *screen; if (window) { QScreen *qs = window->screen(); - screen = static_cast<QXcbScreen *>(qs ? qs->handle() : Q_NULLPTR); + screen = static_cast<QXcbScreen *>(qs ? qs->handle() : nullptr); } else { QScreen *qs = QGuiApplication::primaryScreen(); - screen = static_cast<QXcbScreen *>(qs ? qs->handle() : Q_NULLPTR); + screen = static_cast<QXcbScreen *>(qs ? qs->handle() : nullptr); } return screen; } @@ -537,23 +537,23 @@ void *QXcbNativeInterface::displayForWindow(QWindow *window) { #if QT_CONFIG(xcb_xlib) QXcbScreen *screen = qPlatformScreenForWindow(window); - return screen ? screen->connection()->xlib_display() : Q_NULLPTR; + return screen ? screen->connection()->xlib_display() : nullptr; #else Q_UNUSED(window); - return Q_NULLPTR; + return nullptr; #endif } void *QXcbNativeInterface::connectionForWindow(QWindow *window) { QXcbScreen *screen = qPlatformScreenForWindow(window); - return screen ? screen->xcb_connection() : Q_NULLPTR; + return screen ? screen->xcb_connection() : nullptr; } void *QXcbNativeInterface::screenForWindow(QWindow *window) { QXcbScreen *screen = qPlatformScreenForWindow(window); - return screen ? screen->screen() : Q_NULLPTR; + return screen ? screen->screen() : nullptr; } void QXcbNativeInterface::addHandler(QXcbNativeInterfaceHandler *handler) @@ -575,7 +575,7 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QXcbNativeInterfa if (result) return result; } - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface::handlerNativeResourceFunctionForContext(const QByteArray &resource) const @@ -586,7 +586,7 @@ QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface:: if (result) return result; } - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::handlerNativeResourceFunctionForScreen(const QByteArray &resource) const @@ -597,7 +597,7 @@ QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::h if (result) return result; } - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForWindowFunction QXcbNativeInterface::handlerNativeResourceFunctionForWindow(const QByteArray &resource) const @@ -608,7 +608,7 @@ QPlatformNativeInterface::NativeResourceForWindowFunction QXcbNativeInterface::h if (result) return result; } - return Q_NULLPTR; + return nullptr; } QPlatformNativeInterface::NativeResourceForBackingStoreFunction QXcbNativeInterface::handlerNativeResourceFunctionForBackingStore(const QByteArray &resource) const @@ -619,7 +619,7 @@ QPlatformNativeInterface::NativeResourceForBackingStoreFunction QXcbNativeInterf if (result) return result; } - return Q_NULLPTR; + return nullptr; } QFunctionPointer QXcbNativeInterface::handlerPlatformFunction(const QByteArray &function) const @@ -630,7 +630,7 @@ QFunctionPointer QXcbNativeInterface::handlerPlatformFunction(const QByteArray & if (func) return func; } - return Q_NULLPTR; + return nullptr; } void *QXcbNativeInterface::handlerNativeResourceForIntegration(const QByteArray &resource) const @@ -638,7 +638,7 @@ void *QXcbNativeInterface::handlerNativeResourceForIntegration(const QByteArray NativeResourceForIntegrationFunction func = handlerNativeResourceFunctionForIntegration(resource); if (func) return func(); - return Q_NULLPTR; + return nullptr; } void *QXcbNativeInterface::handlerNativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) const @@ -646,7 +646,7 @@ void *QXcbNativeInterface::handlerNativeResourceForContext(const QByteArray &res NativeResourceForContextFunction func = handlerNativeResourceFunctionForContext(resource); if (func) return func(context); - return Q_NULLPTR; + return nullptr; } void *QXcbNativeInterface::handlerNativeResourceForScreen(const QByteArray &resource, QScreen *screen) const @@ -654,7 +654,7 @@ void *QXcbNativeInterface::handlerNativeResourceForScreen(const QByteArray &reso NativeResourceForScreenFunction func = handlerNativeResourceFunctionForScreen(resource); if (func) return func(screen); - return Q_NULLPTR; + return nullptr; } void *QXcbNativeInterface::handlerNativeResourceForWindow(const QByteArray &resource, QWindow *window) const @@ -662,7 +662,7 @@ void *QXcbNativeInterface::handlerNativeResourceForWindow(const QByteArray &reso NativeResourceForWindowFunction func = handlerNativeResourceFunctionForWindow(resource); if (func) return func(window); - return Q_NULLPTR; + return nullptr; } void *QXcbNativeInterface::handlerNativeResourceForBackingStore(const QByteArray &resource, QBackingStore *backingStore) const @@ -670,7 +670,7 @@ void *QXcbNativeInterface::handlerNativeResourceForBackingStore(const QByteArray NativeResourceForBackingStoreFunction func = handlerNativeResourceFunctionForBackingStore(resource); if (func) return func(backingStore); - return Q_NULLPTR; + return nullptr; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index ec0f9ba561..cdeafa8cba 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -140,7 +140,7 @@ QXcbScreen *QXcbVirtualDesktop::screenAt(const QPoint &pos) const if (screen->virtualDesktop() == this && screen->geometry().contains(pos)) return screen; } - return Q_NULLPTR; + return nullptr; } void QXcbVirtualDesktop::addScreen(QPlatformScreen *s) @@ -583,7 +583,9 @@ QRect QXcbScreen::availableGeometry() const QImage::Format QXcbScreen::format() const { - return qt_xcb_imageFormatForVisual(connection(), screen()->root_depth, visualForId(screen()->root_visual)); + QImage::Format format; + qt_xcb_imageFormatForVisual(connection(), screen()->root_depth, visualForId(screen()->root_visual), &format); + return format; } QDpi QXcbScreen::virtualDpi() const diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 842738b622..4a9b1bd209 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -140,7 +140,7 @@ class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen public: QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop, xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *outputInfo, - const xcb_xinerama_screen_info_t *xineramaScreenInfo = Q_NULLPTR, int xineramaScreenIdx = -1); + const xcb_xinerama_screen_info_t *xineramaScreenInfo = nullptr, int xineramaScreenIdx = -1); ~QXcbScreen(); QString getOutputName(xcb_randr_get_output_info_reply_t *outputInfo); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index c8a668b72c..9c34fccd48 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -51,6 +51,7 @@ #include "qxcbscreen.h" #include "qxcbdrag.h" #include "qxcbkeyboard.h" +#include "qxcbimage.h" #include "qxcbwmsupport.h" #include "qxcbimage.h" #include "qxcbnativeinterface.h" @@ -176,80 +177,23 @@ static inline bool isTransient(const QWindow *w) || w->type() == Qt::Popup; } -static inline QImage::Format imageFormatForVisual(int depth, quint32 red_mask, quint32 blue_mask, bool *rgbSwap) +void QXcbWindow::setImageFormatForVisual(const xcb_visualtype_t *visual) { - if (rgbSwap) - *rgbSwap = false; - switch (depth) { - case 32: - if (blue_mask == 0xff) - return QImage::Format_ARGB32_Premultiplied; - if (red_mask == 0x3ff) - return QImage::Format_A2BGR30_Premultiplied; - if (blue_mask == 0x3ff) - return QImage::Format_A2RGB30_Premultiplied; - if (red_mask == 0xff) { - if (rgbSwap) - *rgbSwap = true; - return QImage::Format_ARGB32_Premultiplied; - } - break; - case 30: - if (red_mask == 0x3ff) - return QImage::Format_BGR30; - if (blue_mask == 0x3ff) - return QImage::Format_RGB30; - break; - case 24: - if (blue_mask == 0xff) - return QImage::Format_RGB32; - if (red_mask == 0xff) { - if (rgbSwap) - *rgbSwap = true; - return QImage::Format_RGB32; - } - break; - case 16: - if (blue_mask == 0x1f) - return QImage::Format_RGB16; - if (red_mask == 0x1f) { - if (rgbSwap) - *rgbSwap = true; - return QImage::Format_RGB16; - } - break; - case 15: - if (blue_mask == 0x1f) - return QImage::Format_RGB555; - if (red_mask == 0x1f) { - if (rgbSwap) - *rgbSwap = true; - return QImage::Format_RGB555; - } - break; -#if QT_CONFIG(xcb_native_painting) - case 8: - if (QXcbIntegration::instance() && QXcbIntegration::instance()->nativePaintingEnabled()) - return QImage::Format_Indexed8; - break; -#endif - default: - break; - } - qWarning("Unsupported screen format: depth: %d, red_mask: %x, blue_mask: %x", depth, red_mask, blue_mask); + if (qt_xcb_imageFormatForVisual(connection(), m_depth, visual, &m_imageFormat, &m_imageRgbSwap)) + return; - switch (depth) { + switch (m_depth) { + case 32: case 24: qWarning("Using RGB32 fallback, if this works your X11 server is reporting a bad screen format."); - return QImage::Format_RGB32; + m_imageFormat = QImage::Format_RGB32; + break; case 16: qWarning("Using RGB16 fallback, if this works your X11 server is reporting a bad screen format."); - return QImage::Format_RGB16; + m_imageFormat = QImage::Format_RGB16; default: break; } - - return QImage::Format_Invalid; } static inline bool positionIncludesFrame(QWindow *w) @@ -287,7 +231,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s) if (!mapper || errCode < 0) { mapper = QTextCodec::codecForName("latin1"); if (!mapper || !mapper->canEncode(s)) - return Q_NULLPTR; + return nullptr; #endif static QByteArray qcs; qcs = s.toLatin1(); @@ -322,7 +266,7 @@ static QWindow *childWindowAt(QWindow *win, const QPoint &p) && win->geometry().contains(win->parent()->mapFromGlobal(p))) { return win; } - return Q_NULLPTR; + return nullptr; } static const char *wm_window_type_property_id = "_q_xcb_wm_window_type"; @@ -381,7 +325,7 @@ void QXcbWindow::create() } if (!visual) visual = platformScreen->visualForId(m_visualId); - m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap); + setImageFormatForVisual(visual); connection()->addWindowEventListener(m_window, this); return; } @@ -418,7 +362,7 @@ void QXcbWindow::create() resolveFormat(platformScreen->surfaceFormatFor(window()->requestedFormat())); - const xcb_visualtype_t *visual = Q_NULLPTR; + const xcb_visualtype_t *visual = nullptr; if (connection()->hasDefaultVisualId()) { visual = platformScreen->visualForId(connection()->defaultVisualId()); @@ -451,7 +395,7 @@ void QXcbWindow::create() m_visualId = visual->visual_id; m_depth = platformScreen->depthOfVisual(m_visualId); - m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap); + setImageFormatForVisual(visual); quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL @@ -641,7 +585,7 @@ void QXcbWindow::destroy() if (connection()->focusWindow() == this) doFocusOut(); if (connection()->mouseGrabber() == this) - connection()->setMouseGrabber(Q_NULLPTR); + connection()->setMouseGrabber(nullptr); if (m_syncCounter && m_usingSyncProtocol) xcb_sync_destroy_counter(xcb_connection(), m_syncCounter); @@ -877,12 +821,12 @@ void QXcbWindow::hide() xcb_flush(xcb_connection()); if (connection()->mouseGrabber() == this) - connection()->setMouseGrabber(Q_NULLPTR); + connection()->setMouseGrabber(nullptr); if (QPlatformWindow *w = connection()->mousePressWindow()) { // Unset mousePressWindow when it (or one of its parents) is unmapped while (w) { if (w == this) { - connection()->setMousePressWindow(Q_NULLPTR); + connection()->setMousePressWindow(nullptr); break; } w = w->parent(); @@ -900,7 +844,7 @@ void QXcbWindow::hide() // Find the top level window at cursor position. // Don't use QGuiApplication::topLevelAt(): search only the virtual siblings of this window's screen - QWindow *enterWindow = Q_NULLPTR; + QWindow *enterWindow = nullptr; const auto screens = xcbScreen()->virtualSiblings(); for (QPlatformScreen *screen : screens) { if (screen->geometry().contains(cursorPos)) { @@ -2000,13 +1944,14 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even return; if (event->type == atom(QXcbAtom::WM_PROTOCOLS)) { - if (event->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) { + xcb_atom_t protocolAtom = event->data.data32[0]; + if (protocolAtom == atom(QXcbAtom::WM_DELETE_WINDOW)) { QWindowSystemInterface::handleCloseEvent(window()); - } else if (event->data.data32[0] == atom(QXcbAtom::WM_TAKE_FOCUS)) { + } else if (protocolAtom == atom(QXcbAtom::WM_TAKE_FOCUS)) { connection()->setTime(event->data.data32[1]); relayFocusToModalWindow(); return; - } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) { + } else if (protocolAtom == atom(QXcbAtom::_NET_WM_PING)) { if (event->window == xcbScreen()->root()) return; @@ -2015,20 +1960,23 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even reply.response_type = XCB_CLIENT_MESSAGE; reply.window = xcbScreen()->root(); - xcb_send_event(xcb_connection(), 0, xcbScreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply); + xcb_send_event(xcb_connection(), 0, xcbScreen()->root(), + XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, + (const char *)&reply); xcb_flush(xcb_connection()); - } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) { + } else if (protocolAtom == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) { connection()->setTime(event->data.data32[1]); m_syncValue.lo = event->data.data32[2]; m_syncValue.hi = event->data.data32[3]; if (m_usingSyncProtocol) m_syncState = SyncReceived; #ifndef QT_NO_WHATSTHIS - } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) { + } else if (protocolAtom == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) { QWindowSystemInterface::handleEnterWhatsThisEvent(); #endif } else { - qWarning() << "QXcbWindow: Unhandled WM_PROTOCOLS message:" << connection()->atomName(event->data.data32[0]); + qCWarning(lcQpaXcb, "Unhandled WM_PROTOCOLS (%s)", + connection()->atomName(protocolAtom).constData()); } #ifndef QT_NO_DRAGANDDROP } else if (event->type == atom(QXcbAtom::XdndEnter)) { @@ -2056,7 +2004,7 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even || event->type == atom(QXcbAtom::_GTK_LOAD_ICONTHEMES)) { //silence the _COMPIZ and _GTK messages for now } else { - qWarning() << "QXcbWindow: Unhandled client message:" << connection()->atomName(event->type); + qCWarning(lcQpaXcb) << "Unhandled client message: " << connection()->atomName(event->type); } } @@ -2165,7 +2113,8 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) } void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, - int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source) + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, + QEvent::Type type, Qt::MouseEventSource source) { const bool isWheel = detail >= 4 && detail <= 7; if (!isWheel && window() != QGuiApplication::focusWindow()) { @@ -2214,11 +2163,12 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in connection()->setMousePressWindow(this); - handleMouseEvent(timestamp, local, global, modifiers, source); + handleMouseEvent(timestamp, local, global, modifiers, type, source); } void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, - int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source) + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, + QEvent::Type type, Qt::MouseEventSource source) { QPoint local(event_x, event_y); QPoint global(root_x, root_y); @@ -2229,9 +2179,9 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, } if (connection()->buttonState() == Qt::NoButton) - connection()->setMousePressWindow(Q_NULLPTR); + connection()->setMousePressWindow(nullptr); - handleMouseEvent(timestamp, local, global, modifiers, source); + handleMouseEvent(timestamp, local, global, modifiers, type, source); } static inline bool doCheckUnGrabAncestor(QXcbConnection *conn) @@ -2254,7 +2204,7 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn) return true; } -static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn = Q_NULLPTR) +static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn = nullptr) { return ((doCheckUnGrabAncestor(conn) && mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) @@ -2263,7 +2213,7 @@ static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn = || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); } -static bool ignoreEnterEvent(quint8 mode, quint8 detail, QXcbConnection *conn = Q_NULLPTR) +static bool ignoreEnterEvent(quint8 mode, quint8 detail, QXcbConnection *conn = nullptr) { return ((doCheckUnGrabAncestor(conn) && mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) @@ -2332,7 +2282,8 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, } void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, - Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source) + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, + QEvent::Type type, Qt::MouseEventSource source) { QPoint local(event_x, event_y); QPoint global(root_x, root_y); @@ -2340,33 +2291,34 @@ void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, i // "mousePressWindow" can be NULL i.e. if a window will be grabbed or unmapped, so set it again here. // Unset "mousePressWindow" when mouse button isn't pressed - in some cases the release event won't arrive. const bool isMouseButtonPressed = (connection()->buttonState() != Qt::NoButton); - const bool hasMousePressWindow = (connection()->mousePressWindow() != Q_NULLPTR); + const bool hasMousePressWindow = (connection()->mousePressWindow() != nullptr); if (isMouseButtonPressed && !hasMousePressWindow) connection()->setMousePressWindow(this); else if (hasMousePressWindow && !isMouseButtonPressed) - connection()->setMousePressWindow(Q_NULLPTR); + connection()->setMousePressWindow(nullptr); - handleMouseEvent(timestamp, local, global, modifiers, source); + handleMouseEvent(timestamp, local, global, modifiers, type, source); } void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) { Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); handleButtonPressEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail, - modifiers, event->time); + modifiers, event->time, QEvent::MouseButtonPress); } void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event) { Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); handleButtonReleaseEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail, - modifiers, event->time); + modifiers, event->time, QEvent::MouseButtonRelease); } void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) { Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); - handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers, event->time); + handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers, + event->time, QEvent::MouseMove); } #if QT_CONFIG(xinput2) @@ -2417,18 +2369,18 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName); conn->setButtonState(button, true); - handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); + handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonPress, source); break; case XI_ButtonRelease: if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName); conn->setButtonState(button, false); - handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); + handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonRelease, source); break; case XI_Motion: if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName); - handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, source); + handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, QEvent::MouseMove, source); break; default: qWarning() << "Unrecognized XI2 mouse event" << ev->evtype; @@ -2473,10 +2425,13 @@ void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event) QXcbWindow *QXcbWindow::toWindow() { return this; } void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, - Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source) + Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source) { connection()->setTime(time); - QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttonState(), modifiers, source); + Qt::MouseButton button = type == QEvent::MouseMove ? Qt::NoButton : connection()->button(); + QWindowSystemInterface::handleMouseEvent(window(), time, local, global, + connection()->buttonState(), button, + type, modifiers, source); } void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) @@ -2526,7 +2481,7 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev m_lastWindowStateEvent = newState; m_windowState = newState; if ((m_windowState & Qt::WindowMinimized) && connection()->mouseGrabber() == this) - connection()->setMouseGrabber(Q_NULLPTR); + connection()->setMouseGrabber(nullptr); } return; } else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) { @@ -2594,7 +2549,7 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab) bool QXcbWindow::setMouseGrabEnabled(bool grab) { if (!grab && connection()->mouseGrabber() == this) - connection()->setMouseGrabber(Q_NULLPTR); + connection()->setMouseGrabber(nullptr); #if QT_CONFIG(xinput2) if (connection()->hasXInput2() && !connection()->xi2MouseEventsDisabled()) { diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 1ce9b0a42f..b89dddf72f 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -146,7 +146,7 @@ public: QXcbWindow *toWindow() override; void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, - Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source); + Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source); void updateNetWmUserTime(xcb_timestamp_t timestamp); @@ -188,6 +188,7 @@ public Q_SLOTS: protected: virtual void resolveFormat(const QSurfaceFormat &format) { m_format = format; } virtual const xcb_visualtype_t *createVisual(); + void setImageFormatForVisual(const xcb_visualtype_t *visual); QXcbScreen *parentScreen(); @@ -220,13 +221,16 @@ protected: bool compressExposeEvent(QRegion &exposeRegion); void handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, - int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, + QEvent::Type type, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); void handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, - int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, + QEvent::Type type, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, - Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, + QEvent::Type type, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); void handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y, quint8 mode, quint8 detail, xcb_timestamp_t timestamp); diff --git a/src/plugins/platformthemes/gtk3/main.cpp b/src/plugins/platformthemes/gtk3/main.cpp index c4cd66c33b..fb1c425d8e 100644 --- a/src/plugins/platformthemes/gtk3/main.cpp +++ b/src/plugins/platformthemes/gtk3/main.cpp @@ -48,7 +48,7 @@ class QGtk3ThemePlugin : public QPlatformThemePlugin Q_PLUGIN_METADATA(IID QPlatformThemeFactoryInterface_iid FILE "gtk3.json") public: - QPlatformTheme *create(const QString &key, const QStringList ¶ms) Q_DECL_OVERRIDE; + QPlatformTheme *create(const QString &key, const QStringList ¶ms) override; }; QPlatformTheme *QGtk3ThemePlugin::create(const QString &key, const QStringList ¶ms) diff --git a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h index ba43046e04..e78a7fc6d1 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h +++ b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h @@ -63,12 +63,12 @@ public: QGtk3ColorDialogHelper(); ~QGtk3ColorDialogHelper(); - bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) Q_DECL_OVERRIDE; - void exec() Q_DECL_OVERRIDE; - void hide() Q_DECL_OVERRIDE; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void exec() override; + void hide() override; - void setCurrentColor(const QColor &color) Q_DECL_OVERRIDE; - QColor currentColor() const Q_DECL_OVERRIDE; + void setCurrentColor(const QColor &color) override; + QColor currentColor() const override; private Q_SLOTS: void onAccepted(); @@ -88,18 +88,18 @@ public: QGtk3FileDialogHelper(); ~QGtk3FileDialogHelper(); - bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) Q_DECL_OVERRIDE; - void exec() Q_DECL_OVERRIDE; - void hide() Q_DECL_OVERRIDE; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void exec() override; + void hide() override; - bool defaultNameFilterDisables() const Q_DECL_OVERRIDE; - void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE; - QUrl directory() const Q_DECL_OVERRIDE; - void selectFile(const QUrl &filename) Q_DECL_OVERRIDE; - QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE; - void setFilter() Q_DECL_OVERRIDE; - void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE; - QString selectedNameFilter() const Q_DECL_OVERRIDE; + bool defaultNameFilterDisables() const override; + void setDirectory(const QUrl &directory) override; + QUrl directory() const override; + void selectFile(const QUrl &filename) override; + QList<QUrl> selectedFiles() const override; + void setFilter() override; + void selectNameFilter(const QString &filter) override; + QString selectedNameFilter() const override; private Q_SLOTS: void onAccepted(); @@ -128,12 +128,12 @@ public: QGtk3FontDialogHelper(); ~QGtk3FontDialogHelper(); - bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) Q_DECL_OVERRIDE; - void exec() Q_DECL_OVERRIDE; - void hide() Q_DECL_OVERRIDE; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void exec() override; + void hide() override; - void setCurrentFont(const QFont &font) Q_DECL_OVERRIDE; - QFont currentFont() const Q_DECL_OVERRIDE; + void setCurrentFont(const QFont &font) override; + QFont currentFont() const override; private Q_SLOTS: void onAccepted(); diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.h b/src/plugins/platformthemes/gtk3/qgtk3theme.h index 52036680c6..8f03b84bb6 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3theme.h +++ b/src/plugins/platformthemes/gtk3/qgtk3theme.h @@ -49,14 +49,14 @@ class QGtk3Theme : public QGnomeTheme public: QGtk3Theme(); - virtual QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE; - virtual QString gtkFontName() const Q_DECL_OVERRIDE; + virtual QVariant themeHint(ThemeHint hint) const override; + virtual QString gtkFontName() const override; - bool usePlatformNativeDialog(DialogType type) const Q_DECL_OVERRIDE; - QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const Q_DECL_OVERRIDE; + bool usePlatformNativeDialog(DialogType type) const override; + QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override; - QPlatformMenu* createPlatformMenu() const Q_DECL_OVERRIDE; - QPlatformMenuItem* createPlatformMenuItem() const Q_DECL_OVERRIDE; + QPlatformMenu* createPlatformMenu() const override; + QPlatformMenuItem* createPlatformMenuItem() const override; static const char *name; }; diff --git a/src/plugins/printsupport/cups/main.cpp b/src/plugins/printsupport/cups/main.cpp index 39309a0031..cf263a7f52 100644 --- a/src/plugins/printsupport/cups/main.cpp +++ b/src/plugins/printsupport/cups/main.cpp @@ -52,7 +52,7 @@ class QCupsPrinterSupportPlugin : public QPlatformPrinterSupportPlugin public: QStringList keys() const; - QPlatformPrinterSupport *create(const QString &) Q_DECL_OVERRIDE; + QPlatformPrinterSupport *create(const QString &) override; }; QStringList QCupsPrinterSupportPlugin::keys() const diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h index 0ebf6e7a0f..c99c48c7ea 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine_p.h +++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h @@ -72,8 +72,8 @@ public: virtual ~QCupsPrintEngine(); // reimplementations QPdfPrintEngine - void setProperty(PrintEnginePropertyKey key, const QVariant &value) Q_DECL_OVERRIDE; - QVariant property(PrintEnginePropertyKey key) const Q_DECL_OVERRIDE; + void setProperty(PrintEnginePropertyKey key, const QVariant &value) override; + QVariant property(PrintEnginePropertyKey key) const override; // end reimplementations QPdfPrintEngine private: @@ -87,8 +87,8 @@ public: QCupsPrintEnginePrivate(QPrinter::PrinterMode m); ~QCupsPrintEnginePrivate(); - bool openPrintDevice() Q_DECL_OVERRIDE; - void closePrintDevice() Q_DECL_OVERRIDE; + bool openPrintDevice() override; + void closePrintDevice() override; private: Q_DISABLE_COPY(QCupsPrintEnginePrivate) diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h index df6507d324..42de28aec0 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h +++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h @@ -64,12 +64,12 @@ public: QCupsPrinterSupport(); ~QCupsPrinterSupport(); - QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode, const QString &deviceId = QString()) Q_DECL_OVERRIDE; - QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode) Q_DECL_OVERRIDE; + QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode, const QString &deviceId = QString()) override; + QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode) override; - QPrintDevice createPrintDevice(const QString &id) Q_DECL_OVERRIDE; - QStringList availablePrintDeviceIds() const Q_DECL_OVERRIDE; - QString defaultPrintDeviceId() const Q_DECL_OVERRIDE; + QPrintDevice createPrintDevice(const QString &id) override; + QStringList availablePrintDeviceIds() const override; + QString defaultPrintDeviceId() const override; private: QString cupsOption(int i, const QString &key) const; diff --git a/src/plugins/printsupport/cups/qppdprintdevice.h b/src/plugins/printsupport/cups/qppdprintdevice.h index fab7077ce4..3cd7518b14 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.h +++ b/src/plugins/printsupport/cups/qppdprintdevice.h @@ -69,35 +69,35 @@ public: explicit QPpdPrintDevice(const QString &id); virtual ~QPpdPrintDevice(); - bool isValid() const Q_DECL_OVERRIDE; - bool isDefault() const Q_DECL_OVERRIDE; + bool isValid() const override; + bool isDefault() const override; - QPrint::DeviceState state() const Q_DECL_OVERRIDE; + QPrint::DeviceState state() const override; - QPageSize defaultPageSize() const Q_DECL_OVERRIDE; + QPageSize defaultPageSize() const override; QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation, - int resolution) const Q_DECL_OVERRIDE; + int resolution) const override; - int defaultResolution() const Q_DECL_OVERRIDE; + int defaultResolution() const override; - QPrint::InputSlot defaultInputSlot() const Q_DECL_OVERRIDE; + QPrint::InputSlot defaultInputSlot() const override; - QPrint::OutputBin defaultOutputBin() const Q_DECL_OVERRIDE; + QPrint::OutputBin defaultOutputBin() const override; - QPrint::DuplexMode defaultDuplexMode() const Q_DECL_OVERRIDE; + QPrint::DuplexMode defaultDuplexMode() const override; - QPrint::ColorMode defaultColorMode() const Q_DECL_OVERRIDE; + QPrint::ColorMode defaultColorMode() const override; protected: - void loadPageSizes() const Q_DECL_OVERRIDE; - void loadResolutions() const Q_DECL_OVERRIDE; - void loadInputSlots() const Q_DECL_OVERRIDE; - void loadOutputBins() const Q_DECL_OVERRIDE; - void loadDuplexModes() const Q_DECL_OVERRIDE; - void loadColorModes() const Q_DECL_OVERRIDE; + void loadPageSizes() const override; + void loadResolutions() const override; + void loadInputSlots() const override; + void loadOutputBins() const override; + void loadDuplexModes() const override; + void loadColorModes() const override; #ifndef QT_NO_MIMETYPE - void loadMimeTypes() const Q_DECL_OVERRIDE; + void loadMimeTypes() const override; #endif private: diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp index 1cb14514ee..b1589c0738 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp @@ -87,13 +87,13 @@ static LPDEVMODE getDevmode(HANDLE hPrinter, const QString &printerId) // Allocate the required DEVMODE buffer LONG dmSize = DocumentProperties(NULL, hPrinter, printerIdUtf16, NULL, NULL, 0); if (dmSize <= 0) - return Q_NULLPTR; + return nullptr; LPDEVMODE pDevMode = reinterpret_cast<LPDEVMODE>(malloc(dmSize)); // Get the default DevMode LONG result = DocumentProperties(NULL, hPrinter, printerIdUtf16, pDevMode, NULL, DM_OUT_BUFFER); if (result != IDOK) { free(pDevMode); - pDevMode = Q_NULLPTR; + pDevMode = nullptr; } return pDevMode; } diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.h b/src/plugins/printsupport/windows/qwindowsprintdevice.h index d95a4316cc..6b51ee8785 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.h +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.h @@ -64,34 +64,34 @@ public: explicit QWindowsPrintDevice(const QString &id); virtual ~QWindowsPrintDevice(); - bool isValid() const Q_DECL_OVERRIDE; - bool isDefault() const Q_DECL_OVERRIDE; + bool isValid() const override; + bool isDefault() const override; - QPrint::DeviceState state() const Q_DECL_OVERRIDE; + QPrint::DeviceState state() const override; - QPageSize defaultPageSize() const Q_DECL_OVERRIDE; + QPageSize defaultPageSize() const override; QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation, - int resolution) const Q_DECL_OVERRIDE; + int resolution) const override; - int defaultResolution() const Q_DECL_OVERRIDE; + int defaultResolution() const override; - QPrint::InputSlot defaultInputSlot() const Q_DECL_OVERRIDE; + QPrint::InputSlot defaultInputSlot() const override; - QPrint::DuplexMode defaultDuplexMode() const Q_DECL_OVERRIDE; + QPrint::DuplexMode defaultDuplexMode() const override; - QPrint::ColorMode defaultColorMode() const Q_DECL_OVERRIDE; + QPrint::ColorMode defaultColorMode() const override; static QStringList availablePrintDeviceIds(); static QString defaultPrintDeviceId(); protected: - void loadPageSizes() const Q_DECL_OVERRIDE; - void loadResolutions() const Q_DECL_OVERRIDE; - void loadInputSlots() const Q_DECL_OVERRIDE; - void loadOutputBins() const Q_DECL_OVERRIDE; - void loadDuplexModes() const Q_DECL_OVERRIDE; - void loadColorModes() const Q_DECL_OVERRIDE; + void loadPageSizes() const override; + void loadResolutions() const override; + void loadInputSlots() const override; + void loadOutputBins() const override; + void loadDuplexModes() const override; + void loadColorModes() const override; private: HANDLE m_hPrinter; diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h index 84b60a8207..c42e7aa551 100644 --- a/src/plugins/printsupport/windows/qwindowsprintersupport.h +++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h @@ -50,12 +50,12 @@ public: QWindowsPrinterSupport(); ~QWindowsPrinterSupport(); - QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode, const QString &deviceId = QString()) Q_DECL_OVERRIDE; - QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode) Q_DECL_OVERRIDE; + QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode, const QString &deviceId = QString()) override; + QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode) override; - QPrintDevice createPrintDevice(const QString &id) Q_DECL_OVERRIDE; - QStringList availablePrintDeviceIds() const Q_DECL_OVERRIDE; - QString defaultPrintDeviceId() const Q_DECL_OVERRIDE; + QPrintDevice createPrintDevice(const QString &id) override; + QStringList availablePrintDeviceIds() const override; + QString defaultPrintDeviceId() const override; }; QT_END_NAMESPACE diff --git a/src/plugins/sqldrivers/db2/qsql_db2.cpp b/src/plugins/sqldrivers/db2/qsql_db2.cpp index 1a9631f1eb..b457ced538 100644 --- a/src/plugins/sqldrivers/db2/qsql_db2.cpp +++ b/src/plugins/sqldrivers/db2/qsql_db2.cpp @@ -92,24 +92,24 @@ class QDB2Result: public QSqlResult public: QDB2Result(const QDB2Driver *drv); ~QDB2Result(); - bool prepare(const QString &query) Q_DECL_OVERRIDE; - bool exec() Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; + bool prepare(const QString &query) override; + bool exec() override; + QVariant handle() const override; protected: - QVariant data(int field) Q_DECL_OVERRIDE; - bool reset(const QString &query) Q_DECL_OVERRIDE; - bool fetch(int i) Q_DECL_OVERRIDE; - bool fetchNext() Q_DECL_OVERRIDE; - bool fetchFirst() Q_DECL_OVERRIDE; - bool fetchLast() Q_DECL_OVERRIDE; - bool isNull(int i) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; - void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; - void detachFromResultSet() Q_DECL_OVERRIDE; - bool nextResult() Q_DECL_OVERRIDE; + QVariant data(int field) override; + bool reset(const QString &query) override; + bool fetch(int i) override; + bool fetchNext() override; + bool fetchFirst() override; + bool fetchLast() override; + bool isNull(int i) override; + int size() override; + int numRowsAffected() override; + QSqlRecord record() const override; + void virtual_hook(int id, void *data) override; + void detachFromResultSet() override; + bool nextResult() override; }; class QDB2ResultPrivate: public QSqlResultPrivate diff --git a/src/plugins/sqldrivers/db2/qsql_db2_p.h b/src/plugins/sqldrivers/db2/qsql_db2_p.h index fa6d739479..79ae54ab2d 100644 --- a/src/plugins/sqldrivers/db2/qsql_db2_p.h +++ b/src/plugins/sqldrivers/db2/qsql_db2_p.h @@ -75,24 +75,24 @@ public: explicit QDB2Driver(QObject* parent = 0); QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent = 0); ~QDB2Driver(); - bool hasFeature(DriverFeature) const Q_DECL_OVERRIDE; - void close() Q_DECL_OVERRIDE; - QSqlRecord record(const QString &tableName) const Q_DECL_OVERRIDE; - QStringList tables(QSql::TableType type) const Q_DECL_OVERRIDE; - QSqlResult *createResult() const Q_DECL_OVERRIDE; - QSqlIndex primaryIndex(const QString &tablename) const Q_DECL_OVERRIDE; - bool beginTransaction() Q_DECL_OVERRIDE; - bool commitTransaction() Q_DECL_OVERRIDE; - bool rollbackTransaction() Q_DECL_OVERRIDE; - QString formatValue(const QSqlField &field, bool trimStrings) const Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; + bool hasFeature(DriverFeature) const override; + void close() override; + QSqlRecord record(const QString &tableName) const override; + QStringList tables(QSql::TableType type) const override; + QSqlResult *createResult() const override; + QSqlIndex primaryIndex(const QString &tablename) const override; + bool beginTransaction() override; + bool commitTransaction() override; + bool rollbackTransaction() override; + QString formatValue(const QSqlField &field, bool trimStrings) const override; + QVariant handle() const override; bool open(const QString &db, const QString &user, const QString &password, const QString &host, int port, - const QString& connOpts) Q_DECL_OVERRIDE; - QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; + const QString& connOpts) override; + QString escapeIdentifier(const QString &identifier, IdentifierType type) const override; private: bool setAutoCommit(bool autoCommit); diff --git a/src/plugins/sqldrivers/ibase/qsql_ibase.cpp b/src/plugins/sqldrivers/ibase/qsql_ibase.cpp index c50fc7916a..218cd75c69 100644 --- a/src/plugins/sqldrivers/ibase/qsql_ibase.cpp +++ b/src/plugins/sqldrivers/ibase/qsql_ibase.cpp @@ -356,16 +356,16 @@ class QIBaseResult : public QSqlCachedResult public: explicit QIBaseResult(const QIBaseDriver* db); - bool prepare(const QString &query) Q_DECL_OVERRIDE; - bool exec() Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; + bool prepare(const QString &query) override; + bool exec() override; + QVariant handle() const override; protected: - bool gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx) Q_DECL_OVERRIDE; - bool reset (const QString &query) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; + bool gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx) override; + bool reset (const QString &query) override; + int size() override; + int numRowsAffected() override; + QSqlRecord record() const override; }; class QIBaseResultPrivate: public QSqlCachedResultPrivate diff --git a/src/plugins/sqldrivers/ibase/qsql_ibase_p.h b/src/plugins/sqldrivers/ibase/qsql_ibase_p.h index c7cee41462..295f6c0cec 100644 --- a/src/plugins/sqldrivers/ibase/qsql_ibase_p.h +++ b/src/plugins/sqldrivers/ibase/qsql_ibase_p.h @@ -74,36 +74,36 @@ public: explicit QIBaseDriver(QObject *parent = 0); explicit QIBaseDriver(isc_db_handle connection, QObject *parent = 0); virtual ~QIBaseDriver(); - bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; + bool hasFeature(DriverFeature f) const override; bool open(const QString &db, const QString &user, const QString &password, const QString &host, int port, - const QString &connOpts) Q_DECL_OVERRIDE; + const QString &connOpts) override; bool open(const QString &db, const QString &user, const QString &password, const QString &host, int port) { return open(db, user, password, host, port, QString()); } - void close() Q_DECL_OVERRIDE; - QSqlResult *createResult() const Q_DECL_OVERRIDE; - bool beginTransaction() Q_DECL_OVERRIDE; - bool commitTransaction() Q_DECL_OVERRIDE; - bool rollbackTransaction() Q_DECL_OVERRIDE; - QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; + void close() override; + QSqlResult *createResult() const override; + bool beginTransaction() override; + bool commitTransaction() override; + bool rollbackTransaction() override; + QStringList tables(QSql::TableType) const override; - QSqlRecord record(const QString& tablename) const Q_DECL_OVERRIDE; - QSqlIndex primaryIndex(const QString &table) const Q_DECL_OVERRIDE; + QSqlRecord record(const QString& tablename) const override; + QSqlIndex primaryIndex(const QString &table) const override; - QString formatValue(const QSqlField &field, bool trimStrings) const Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; + QString formatValue(const QSqlField &field, bool trimStrings) const override; + QVariant handle() const override; - QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; + QString escapeIdentifier(const QString &identifier, IdentifierType type) const override; - bool subscribeToNotification(const QString &name) Q_DECL_OVERRIDE; - bool unsubscribeFromNotification(const QString &name) Q_DECL_OVERRIDE; - QStringList subscribedToNotifications() const Q_DECL_OVERRIDE; + bool subscribeToNotification(const QString &name) override; + bool unsubscribeFromNotification(const QString &name) override; + QStringList subscribedToNotifications() const override; private Q_SLOTS: void qHandleEventNotification(void* updatedResultBuffer); diff --git a/src/plugins/sqldrivers/mysql/main.cpp b/src/plugins/sqldrivers/mysql/main.cpp index 00d9c5bb34..d8d70483ef 100644 --- a/src/plugins/sqldrivers/mysql/main.cpp +++ b/src/plugins/sqldrivers/mysql/main.cpp @@ -51,7 +51,7 @@ class QMYSQLDriverPlugin : public QSqlDriverPlugin public: QMYSQLDriverPlugin(); - QSqlDriver* create(const QString &) Q_DECL_OVERRIDE; + QSqlDriver* create(const QString &) override; }; QMYSQLDriverPlugin::QMYSQLDriverPlugin() diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp index d9aebff700..f84a0081df 100644 --- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp +++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp @@ -175,26 +175,26 @@ public: explicit QMYSQLResult(const QMYSQLDriver *db); ~QMYSQLResult(); - QVariant handle() const Q_DECL_OVERRIDE; + QVariant handle() const override; protected: void cleanup(); - bool fetch(int i) Q_DECL_OVERRIDE; - bool fetchNext() Q_DECL_OVERRIDE; - bool fetchLast() Q_DECL_OVERRIDE; - bool fetchFirst() Q_DECL_OVERRIDE; - QVariant data(int field) Q_DECL_OVERRIDE; - bool isNull(int field) Q_DECL_OVERRIDE; - bool reset (const QString& query) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QVariant lastInsertId() const Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; - void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; - bool nextResult() Q_DECL_OVERRIDE; + bool fetch(int i) override; + bool fetchNext() override; + bool fetchLast() override; + bool fetchFirst() override; + QVariant data(int field) override; + bool isNull(int field) override; + bool reset (const QString& query) override; + int size() override; + int numRowsAffected() override; + QVariant lastInsertId() const override; + QSqlRecord record() const override; + void virtual_hook(int id, void *data) override; + bool nextResult() override; #if MYSQL_VERSION_ID >= 40108 - bool prepare(const QString &stmt) Q_DECL_OVERRIDE; - bool exec() Q_DECL_OVERRIDE; + bool prepare(const QString &stmt) override; + bool exec() override; #endif }; diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql_p.h b/src/plugins/sqldrivers/mysql/qsql_mysql_p.h index 7641f9aa34..48b04fb1f5 100644 --- a/src/plugins/sqldrivers/mysql/qsql_mysql_p.h +++ b/src/plugins/sqldrivers/mysql/qsql_mysql_p.h @@ -78,29 +78,29 @@ public: explicit QMYSQLDriver(QObject *parent=0); explicit QMYSQLDriver(MYSQL *con, QObject * parent=0); ~QMYSQLDriver(); - bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; + bool hasFeature(DriverFeature f) const override; bool open(const QString & db, const QString & user, const QString & password, const QString & host, int port, - const QString& connOpts) Q_DECL_OVERRIDE; - void close() Q_DECL_OVERRIDE; - QSqlResult *createResult() const Q_DECL_OVERRIDE; - QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; - QSqlIndex primaryIndex(const QString& tablename) const Q_DECL_OVERRIDE; - QSqlRecord record(const QString& tablename) const Q_DECL_OVERRIDE; + const QString& connOpts) override; + void close() override; + QSqlResult *createResult() const override; + QStringList tables(QSql::TableType) const override; + QSqlIndex primaryIndex(const QString& tablename) const override; + QSqlRecord record(const QString& tablename) const override; QString formatValue(const QSqlField &field, - bool trimStrings) const Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; - QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; + bool trimStrings) const override; + QVariant handle() const override; + QString escapeIdentifier(const QString &identifier, IdentifierType type) const override; - bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; + bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const override; protected: - bool beginTransaction() Q_DECL_OVERRIDE; - bool commitTransaction() Q_DECL_OVERRIDE; - bool rollbackTransaction() Q_DECL_OVERRIDE; + bool beginTransaction() override; + bool commitTransaction() override; + bool rollbackTransaction() override; private: void init(); }; diff --git a/src/plugins/sqldrivers/oci/qsql_oci.cpp b/src/plugins/sqldrivers/oci/qsql_oci.cpp index 9ce2fc1b55..2d16c3d60c 100644 --- a/src/plugins/sqldrivers/oci/qsql_oci.cpp +++ b/src/plugins/sqldrivers/oci/qsql_oci.cpp @@ -55,6 +55,7 @@ #include <qvarlengtharray.h> #include <qvector.h> #include <qdebug.h> +#include <qtimezone.h> // This is needed for oracle oci when compiling with mingw-w64 headers #if defined(__MINGW64_VERSION_MAJOR) && defined(_WIN64) @@ -112,9 +113,6 @@ static const ub2 qOraCharset = OCI_UCS2ID; typedef QVarLengthArray<sb2, 32> IndicatorArray; typedef QVarLengthArray<ub2, 32> SizeArray; -static QByteArray qMakeOraDate(const QDateTime& dt); -static QDateTime qMakeDate(const char* oraDate); - static QByteArray qMakeOCINumber(const qlonglong &ll, OCIError *err); static QByteArray qMakeOCINumber(const qulonglong& ull, OCIError* err); @@ -156,6 +154,60 @@ QOCIRowId::~QOCIRowId() OCIDescriptorFree(id, OCI_DTYPE_ROWID); } +class QOCIDateTime +{ +public: + QOCIDateTime(OCIEnv *env, OCIError *err, const QDateTime &dt = QDateTime()); + ~QOCIDateTime(); + OCIDateTime *dateTime; + static QDateTime fromOCIDateTime(OCIEnv *env, OCIError *err, OCIDateTime *dt); +}; + +QOCIDateTime::QOCIDateTime(OCIEnv *env, OCIError *err, const QDateTime &dt) + : dateTime(nullptr) +{ + OCIDescriptorAlloc(env, reinterpret_cast<void**>(&dateTime), OCI_DTYPE_TIMESTAMP_TZ, 0, 0); + if (dt.isValid()) { + const QDate date = dt.date(); + const QTime time = dt.time(); + // Zone in +hh:mm format (stripping UTC prefix from OffsetName) + QString timeZone = dt.timeZone().displayName(dt, QTimeZone::OffsetName).mid(3); + const OraText *tz = reinterpret_cast<const OraText *>(timeZone.utf16()); + OCIDateTimeConstruct(env, err, dateTime, date.year(), date.month(), date.day(), time.hour(), + time.minute(), time.second(), time.msec() * 1000000, + const_cast<OraText *>(tz), timeZone.length() * sizeof(QChar)); + } +} + +QOCIDateTime::~QOCIDateTime() +{ + if (dateTime != nullptr) + OCIDescriptorFree(dateTime, OCI_DTYPE_TIMESTAMP_TZ); +} + +QDateTime QOCIDateTime::fromOCIDateTime(OCIEnv *env, OCIError *err, OCIDateTime *dateTime) +{ + sb2 year; + ub1 month, day, hour, minute, second; + ub4 nsec; + sb1 tzHour, tzMinute; + + OCIDateTimeGetDate(env, err, dateTime, &year, &month, &day); + OCIDateTimeGetTime(env, err, dateTime, &hour, &minute, &second, &nsec); + OCIDateTimeGetTimeZoneOffset(env, err, dateTime, &tzHour, &tzMinute); + int secondsOffset = (qAbs(tzHour) * 60 + tzMinute) * 60; + if (tzHour < 0) + secondsOffset = -secondsOffset; + // OCIDateTimeGetTime gives "fractions of second" as nanoseconds + return QDateTime(QDate(year, month, day), QTime(hour, minute, second, nsec / 1000000), + Qt::OffsetFromUTC, secondsOffset); +} + +struct TempStorage { + QList<QByteArray> rawData; + QList<QOCIDateTime *> dateTimes; +}; + typedef QSharedDataPointer<QOCIRowId> QOCIRowIdPointer; QT_BEGIN_INCLUDE_NAMESPACE Q_DECLARE_METATYPE(QOCIRowIdPointer) @@ -193,19 +245,19 @@ class QOCIResult: public QSqlCachedResult public: QOCIResult(const QOCIDriver *db); ~QOCIResult(); - bool prepare(const QString &query) Q_DECL_OVERRIDE; - bool exec() Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; + bool prepare(const QString &query) override; + bool exec() override; + QVariant handle() const override; protected: - bool gotoNext(ValueCache &values, int index) Q_DECL_OVERRIDE; - bool reset(const QString &query) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; - QVariant lastInsertId() const Q_DECL_OVERRIDE; - bool execBatch(bool arrayBind = false) Q_DECL_OVERRIDE; - void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; + bool gotoNext(ValueCache &values, int index) override; + bool reset(const QString &query) override; + int size() override; + int numRowsAffected() override; + QSqlRecord record() const override; + QVariant lastInsertId() const override; + bool execBatch(bool arrayBind = false) override; + void virtual_hook(int id, void *data) override; bool fetchNext() override; }; @@ -228,11 +280,11 @@ public: void setStatementAttributes(); int bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, int pos, - const QVariant &val, dvoid *indPtr, ub2 *tmpSize, QList<QByteArray> &tmpStorage); + const QVariant &val, dvoid *indPtr, ub2 *tmpSize, TempStorage &tmpStorage); int bindValues(QVector<QVariant> &values, IndicatorArray &indicators, SizeArray &tmpSizes, - QList<QByteArray> &tmpStorage); + TempStorage &tmpStorage); void outValues(QVector<QVariant> &values, IndicatorArray &indicators, - QList<QByteArray> &tmpStorage); + TempStorage &tmpStorage); inline bool isOutValue(int i) const { Q_Q(const QOCIResult); return q->bindValueType(i) & QSql::Out; } inline bool isBinaryValue(int i) const @@ -305,7 +357,7 @@ void QOCIResultPrivate::setStatementAttributes() } int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, int pos, - const QVariant &val, dvoid *indPtr, ub2 *tmpSize, QList<QByteArray> &tmpStorage) + const QVariant &val, dvoid *indPtr, ub2 *tmpSize, TempStorage &tmpStorage) { int r = OCI_SUCCESS; void *data = const_cast<void *>(val.constData()); @@ -323,14 +375,15 @@ int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, in case QVariant::Time: case QVariant::Date: case QVariant::DateTime: { - QByteArray ba = qMakeOraDate(val.toDateTime()); + QOCIDateTime *ptr = new QOCIDateTime(env, err, val.toDateTime()); r = OCIBindByPos(sql, hbnd, err, pos + 1, - ba.data(), - ba.size(), - SQLT_DAT, indPtr, 0, 0, 0, 0, OCI_DEFAULT); - tmpStorage.append(ba); - break; } + &ptr->dateTime, + sizeof(OCIDateTime *), + SQLT_TIMESTAMP_TZ, indPtr, 0, 0, 0, 0, OCI_DEFAULT); + tmpStorage.dateTimes.append(ptr); + break; + } case QVariant::Int: r = OCIBindByPos(sql, hbnd, err, pos + 1, @@ -357,7 +410,7 @@ int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, in ba.data(), ba.size(), SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT); - tmpStorage.append(ba); + tmpStorage.rawData.append(ba); break; } case QVariant::ULongLong: @@ -368,7 +421,7 @@ int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, in ba.data(), ba.size(), SQLT_VNU, indPtr, 0, 0, 0, 0, OCI_DEFAULT); - tmpStorage.append(ba); + tmpStorage.rawData.append(ba); break; } case QVariant::Double: @@ -438,7 +491,7 @@ int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, in } if (r == OCI_SUCCESS) setCharset(*hbnd, OCI_HTYPE_BIND); - tmpStorage.append(ba); + tmpStorage.rawData.append(ba); break; } // default case } // switch @@ -448,7 +501,7 @@ int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, in } int QOCIResultPrivate::bindValues(QVector<QVariant> &values, IndicatorArray &indicators, - SizeArray &tmpSizes, QList<QByteArray> &tmpStorage) + SizeArray &tmpSizes, TempStorage &tmpStorage) { int r = OCI_SUCCESS; for (int i = 0; i < values.count(); ++i) { @@ -466,27 +519,30 @@ int QOCIResultPrivate::bindValues(QVector<QVariant> &values, IndicatorArray &ind } // will assign out value and remove its temp storage. -static void qOraOutValue(QVariant &value, QList<QByteArray> &storage, OCIError* err) +static void qOraOutValue(QVariant &value, TempStorage &tmpStorage, OCIEnv *env, OCIError* err) { switch (value.type()) { case QVariant::Time: - value = qMakeDate(storage.takeFirst()).time(); + value = QOCIDateTime::fromOCIDateTime(env, err, + tmpStorage.dateTimes.takeFirst()->dateTime).time(); break; case QVariant::Date: - value = qMakeDate(storage.takeFirst()).date(); + value = QOCIDateTime::fromOCIDateTime(env, err, + tmpStorage.dateTimes.takeFirst()->dateTime).date(); break; case QVariant::DateTime: - value = qMakeDate(storage.takeFirst()); + value = QOCIDateTime::fromOCIDateTime(env, err, + tmpStorage.dateTimes.takeFirst()->dateTime); break; case QVariant::LongLong: - value = qMakeLongLong(storage.takeFirst(), err); + value = qMakeLongLong(tmpStorage.rawData.takeFirst(), err); break; case QVariant::ULongLong: - value = qMakeULongLong(storage.takeFirst(), err); + value = qMakeULongLong(tmpStorage.rawData.takeFirst(), err); break; case QVariant::String: value = QString( - reinterpret_cast<const QChar *>(storage.takeFirst().constData())); + reinterpret_cast<const QChar *>(tmpStorage.rawData.takeFirst().constData())); break; default: break; //nothing @@ -494,14 +550,14 @@ static void qOraOutValue(QVariant &value, QList<QByteArray> &storage, OCIError* } void QOCIResultPrivate::outValues(QVector<QVariant> &values, IndicatorArray &indicators, - QList<QByteArray> &tmpStorage) + TempStorage &tmpStorage) { for (int i = 0; i < values.count(); ++i) { if (!isOutValue(i)) continue; - qOraOutValue(values[i], tmpStorage, err); + qOraOutValue(values[i], tmpStorage, env, err); QVariant::Type typ = values.at(i).type(); if (indicators[i] == -1) // NULL @@ -693,11 +749,9 @@ QVariant::Type qDecodeOCIType(int ocitype, QSql::NumericalPrecisionPolicy precis break; case SQLT_DAT: case SQLT_ODT: -#ifdef SQLT_TIMESTAMP case SQLT_TIMESTAMP: case SQLT_TIMESTAMP_TZ: case SQLT_TIMESTAMP_LTZ: -#endif type = QVariant::DateTime; break; default: @@ -724,27 +778,6 @@ static QSqlField qFromOraInf(const OraFieldInfo &ofi) } /*! - \internal - - Convert QDateTime to the internal Oracle DATE format NB! - It does not handle BCE dates. -*/ -QByteArray qMakeOraDate(const QDateTime& dt) -{ - QByteArray ba; - ba.resize(7); - int year = dt.date().year(); - ba[0]= (year / 100) + 100; // century - ba[1]= (year % 100) + 100; // year - ba[2]= dt.date().month(); - ba[3]= dt.date().day(); - ba[4]= dt.time().hour() + 1; - ba[5]= dt.time().minute() + 1; - ba[6]= dt.time().second() + 1; - return ba; -} - -/*! \internal Convert qlonglong to the internal Oracle OCINumber format. @@ -794,22 +827,6 @@ qulonglong qMakeULongLong(const char* ociNumber, OCIError* err) return qull; } -QDateTime qMakeDate(const char* oraDate) -{ - int century = uchar(oraDate[0]); - if(century >= 100){ - int year = uchar(oraDate[1]); - year = ((century-100)*100) + (year-100); - int month = oraDate[2]; - int day = oraDate[3]; - int hour = oraDate[4] - 1; - int min = oraDate[5] - 1; - int sec = oraDate[6] - 1; - return QDateTime(QDate(year,month,day), QTime(hour,min,sec)); - } - return QDateTime(); -} - class QOCICols { public: @@ -832,7 +849,7 @@ private: class OraFieldInf { public: - OraFieldInf(): data(0), len(0), ind(0), typ(QVariant::Invalid), oraType(0), def(0), lob(0) + OraFieldInf() : data(0), len(0), ind(0), typ(QVariant::Invalid), oraType(0), def(0), lob(0), dataPtr(nullptr) {} ~OraFieldInf(); char *data; @@ -842,6 +859,7 @@ private: ub4 oraType; OCIDefine *def; OCILobLocator *lob; + void *dataPtr; }; QVector<OraFieldInf> fieldInf; @@ -856,6 +874,20 @@ QOCICols::OraFieldInf::~OraFieldInf() if (r != 0) qWarning("QOCICols: Cannot free LOB descriptor"); } + if (dataPtr) { + switch (typ) { + case QVariant::Date: + case QVariant::Time: + case QVariant::DateTime: { + int r = OCIDescriptorFree(dataPtr, OCI_DTYPE_TIMESTAMP_TZ); + if (r != OCI_SUCCESS) + qWarning("QOCICols: Cannot free OCIDateTime descriptor"); + break; + } + default: + break; + } + } } QOCICols::QOCICols(int size, QOCIResultPrivate* dp) @@ -902,13 +934,18 @@ QOCICols::QOCICols(int size, QOCIResultPrivate* dp) switch (ofi.type) { case QVariant::DateTime: + r = OCIDescriptorAlloc(d->env, (void **)&fieldInf[idx].dataPtr, OCI_DTYPE_TIMESTAMP_TZ, 0, 0); + if (r != OCI_SUCCESS) { + qWarning("QOCICols: Unable to allocate the OCIDateTime descriptor"); + break; + } r = OCIDefineByPos(d->sql, &dfn, d->err, count, - create(idx, dataSize+1), - dataSize+1, - SQLT_DAT, + &fieldInf[idx].dataPtr, + sizeof(OCIDateTime *), + SQLT_TIMESTAMP_TZ, &(fieldInf[idx].ind), 0, 0, OCI_DEFAULT); break; @@ -1323,11 +1360,10 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b fieldTypes.append(tp == QVariant::List ? boundValues.at(i).toList().value(0).type() : tp); } - - QList<QByteArray> tmpStorage; SizeArray tmpSizes(columnCount); QVector<QOCIBatchColumn> columns(columnCount); QOCIBatchCleanupHandler cleaner(columns); + TempStorage tmpStorage; // figuring out buffer sizes for (i = 0; i < columnCount; ++i) { @@ -1364,8 +1400,8 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b case QVariant::Time: case QVariant::Date: case QVariant::DateTime: - col.bindAs = SQLT_DAT; - col.maxLen = 7; + col.bindAs = SQLT_TIMESTAMP_TZ; + col.maxLen = sizeof(OCIDateTime *); break; case QVariant::Int: @@ -1433,7 +1469,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b for (uint row = 0; row < col.recordCount; ++row) { const QVariant &val = boundValues.at(i).toList().at(row); - if (val.isNull()){ + if (val.isNull() && !d->isOutValue(i)) { columns[i].indicators[row] = -1; columns[i].lengths[row] = 0; } else { @@ -1444,9 +1480,8 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b case QVariant::Date: case QVariant::DateTime:{ columns[i].lengths[row] = columns[i].maxLen; - const QByteArray ba = qMakeOraDate(val.toDateTime()); - Q_ASSERT(ba.size() == int(columns[i].maxLen)); - memcpy(dataPtr, ba.constData(), columns[i].maxLen); + QOCIDateTime *date = new QOCIDateTime(d->env, d->err, val.toDateTime()); + *reinterpret_cast<OCIDateTime**>(dataPtr) = date->dateTime; break; } case QVariant::Int: @@ -1582,7 +1617,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b QVariant::Type tp = boundValues.at(i).type(); if (tp != QVariant::List) { - qOraOutValue(boundValues[i], tmpStorage, d->err); + qOraOutValue(boundValues[i], tmpStorage, d->env, d->err); if (*columns[i].indicators == -1) boundValues[i] = QVariant(tp); continue; @@ -1594,16 +1629,16 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b for (uint r = 0; r < columns[i].recordCount; ++r){ if (columns[i].indicators[r] == -1) { - (*list)[r] = QVariant(); + (*list)[r] = QVariant(fieldTypes[i]); continue; } switch(columns[i].bindAs) { - case SQLT_DAT: - (*list)[r] = qMakeDate(data + r * columns[i].maxLen); + case SQLT_TIMESTAMP_TZ: + (*list)[r] = QOCIDateTime::fromOCIDateTime(d->env, d->err, + *reinterpret_cast<OCIDateTime **>(data + r * columns[i].maxLen)); break; - case SQLT_INT: (*list)[r] = *reinterpret_cast<int*>(data + r * columns[i].maxLen); break; @@ -1647,6 +1682,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b d->q_func()->setAt(QSql::BeforeFirstRow); d->q_func()->setActive(true); + qDeleteAll(tmpStorage.dateTimes); return true; } @@ -1755,7 +1791,8 @@ void QOCICols::getValues(QVector<QVariant> &v, int index) switch (fld.typ) { case QVariant::DateTime: - v[index + i] = QVariant(qMakeDate(fld.data)); + v[index + i] = QVariant(QOCIDateTime::fromOCIDateTime(d->env, d->err, + reinterpret_cast<OCIDateTime *>(fld.dataPtr))); break; case QVariant::Double: case QVariant::Int: @@ -1985,7 +2022,7 @@ bool QOCIResult::exec() ub2 stmtType=0; ub4 iters; ub4 mode; - QList<QByteArray> tmpStorage; + TempStorage tmpStorage; IndicatorArray indicators(boundValueCount()); SizeArray tmpSizes(boundValueCount()); @@ -2056,7 +2093,7 @@ bool QOCIResult::exec() if (hasOutValues()) d->outValues(boundValues(), indicators, tmpStorage); - + qDeleteAll(tmpStorage.dateTimes); return true; } diff --git a/src/plugins/sqldrivers/oci/qsql_oci_p.h b/src/plugins/sqldrivers/oci/qsql_oci_p.h index 69911f4bee..295c131f1a 100644 --- a/src/plugins/sqldrivers/oci/qsql_oci_p.h +++ b/src/plugins/sqldrivers/oci/qsql_oci_p.h @@ -84,21 +84,21 @@ public: const QString &password, const QString &host, int port, - const QString &connOpts) Q_DECL_OVERRIDE; - void close() Q_DECL_OVERRIDE; - QSqlResult *createResult() const Q_DECL_OVERRIDE; - QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; - QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE; - QSqlIndex primaryIndex(const QString& tablename) const Q_DECL_OVERRIDE; + const QString &connOpts) override; + void close() override; + QSqlResult *createResult() const override; + QStringList tables(QSql::TableType) const override; + QSqlRecord record(const QString &tablename) const override; + QSqlIndex primaryIndex(const QString& tablename) const override; QString formatValue(const QSqlField &field, - bool trimStrings) const Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; - QString escapeIdentifier(const QString &identifier, IdentifierType) const Q_DECL_OVERRIDE; + bool trimStrings) const override; + QVariant handle() const override; + QString escapeIdentifier(const QString &identifier, IdentifierType) const override; protected: - bool beginTransaction() Q_DECL_OVERRIDE; - bool commitTransaction() Q_DECL_OVERRIDE; - bool rollbackTransaction() Q_DECL_OVERRIDE; + bool beginTransaction() override; + bool commitTransaction() override; + bool rollbackTransaction() override; }; QT_END_NAMESPACE diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp index c32a29c5e7..4a4183c7a3 100644 --- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp +++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp @@ -163,27 +163,27 @@ public: QODBCResult(const QODBCDriver *db); virtual ~QODBCResult(); - bool prepare(const QString &query) Q_DECL_OVERRIDE; - bool exec() Q_DECL_OVERRIDE; + bool prepare(const QString &query) override; + bool exec() override; - QVariant lastInsertId() const Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; + QVariant lastInsertId() const override; + QVariant handle() const override; protected: - bool fetchNext() Q_DECL_OVERRIDE; - bool fetchFirst() Q_DECL_OVERRIDE; - bool fetchLast() Q_DECL_OVERRIDE; - bool fetchPrevious() Q_DECL_OVERRIDE; - bool fetch(int i) Q_DECL_OVERRIDE; - bool reset(const QString &query) Q_DECL_OVERRIDE; - QVariant data(int field) Q_DECL_OVERRIDE; - bool isNull(int field) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; - void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; - void detachFromResultSet() Q_DECL_OVERRIDE; - bool nextResult() Q_DECL_OVERRIDE; + bool fetchNext() override; + bool fetchFirst() override; + bool fetchLast() override; + bool fetchPrevious() override; + bool fetch(int i) override; + bool reset(const QString &query) override; + QVariant data(int field) override; + bool isNull(int field) override; + int size() override; + int numRowsAffected() override; + QSqlRecord record() const override; + void virtual_hook(int id, void *data) override; + void detachFromResultSet() override; + bool nextResult() override; }; class QODBCResultPrivate: public QSqlResultPrivate diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc_p.h b/src/plugins/sqldrivers/odbc/qsql_odbc_p.h index f4ce8bc243..ea0aa6fc8b 100644 --- a/src/plugins/sqldrivers/odbc/qsql_odbc_p.h +++ b/src/plugins/sqldrivers/odbc/qsql_odbc_p.h @@ -92,30 +92,30 @@ public: explicit QODBCDriver(QObject *parent=0); QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent=0); virtual ~QODBCDriver(); - bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; - void close() Q_DECL_OVERRIDE; - QSqlResult *createResult() const Q_DECL_OVERRIDE; - QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; - QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE; - QSqlIndex primaryIndex(const QString &tablename) const Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; + bool hasFeature(DriverFeature f) const override; + void close() override; + QSqlResult *createResult() const override; + QStringList tables(QSql::TableType) const override; + QSqlRecord record(const QString &tablename) const override; + QSqlIndex primaryIndex(const QString &tablename) const override; + QVariant handle() const override; QString formatValue(const QSqlField &field, - bool trimStrings) const Q_DECL_OVERRIDE; + bool trimStrings) const override; bool open(const QString &db, const QString &user, const QString &password, const QString &host, int port, - const QString &connOpts) Q_DECL_OVERRIDE; + const QString &connOpts) override; - QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; + QString escapeIdentifier(const QString &identifier, IdentifierType type) const override; - bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; + bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const override; protected: - bool beginTransaction() Q_DECL_OVERRIDE; - bool commitTransaction() Q_DECL_OVERRIDE; - bool rollbackTransaction() Q_DECL_OVERRIDE; + bool beginTransaction() override; + bool commitTransaction() override; + bool rollbackTransaction() override; private: bool endTrans(); diff --git a/src/plugins/sqldrivers/psql/main.cpp b/src/plugins/sqldrivers/psql/main.cpp index 7657fcbfdf..c5d546f6ff 100644 --- a/src/plugins/sqldrivers/psql/main.cpp +++ b/src/plugins/sqldrivers/psql/main.cpp @@ -51,7 +51,7 @@ class QPSQLDriverPlugin : public QSqlDriverPlugin public: QPSQLDriverPlugin(); - QSqlDriver* create(const QString &) Q_DECL_OVERRIDE; + QSqlDriver* create(const QString &) override; }; QPSQLDriverPlugin::QPSQLDriverPlugin() diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index 0f4b7a80af..1dce2f28c1 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -135,23 +135,23 @@ public: QPSQLResult(const QPSQLDriver *db); ~QPSQLResult(); - QVariant handle() const Q_DECL_OVERRIDE; - void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; + QVariant handle() const override; + void virtual_hook(int id, void *data) override; protected: void cleanup(); - bool fetch(int i) Q_DECL_OVERRIDE; - bool fetchFirst() Q_DECL_OVERRIDE; - bool fetchLast() Q_DECL_OVERRIDE; - QVariant data(int i) Q_DECL_OVERRIDE; - bool isNull(int field) Q_DECL_OVERRIDE; - bool reset (const QString &query) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; - QVariant lastInsertId() const Q_DECL_OVERRIDE; - bool prepare(const QString &query) Q_DECL_OVERRIDE; - bool exec() Q_DECL_OVERRIDE; + bool fetch(int i) override; + bool fetchFirst() override; + bool fetchLast() override; + QVariant data(int i) override; + bool isNull(int field) override; + bool reset (const QString &query) override; + int size() override; + int numRowsAffected() override; + QSqlRecord record() const override; + QVariant lastInsertId() const override; + bool prepare(const QString &query) override; + bool exec() override; }; class QPSQLDriverPrivate : public QSqlDriverPrivate @@ -237,7 +237,7 @@ public: preparedQueriesEnabled(false) { } - QString fieldSerial(int i) const Q_DECL_OVERRIDE { return QLatin1Char('$') + QString::number(i + 1); } + QString fieldSerial(int i) const override { return QLatin1Char('$') + QString::number(i + 1); } void deallocatePreparedStmt(); PGresult *result; diff --git a/src/plugins/sqldrivers/psql/qsql_psql_p.h b/src/plugins/sqldrivers/psql/qsql_psql_p.h index f5cb2e9bd0..2873a9f851 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql_p.h +++ b/src/plugins/sqldrivers/psql/qsql_psql_p.h @@ -98,34 +98,34 @@ public: explicit QPSQLDriver(QObject *parent=0); explicit QPSQLDriver(PGconn *conn, QObject *parent=0); ~QPSQLDriver(); - bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; + bool hasFeature(DriverFeature f) const override; bool open(const QString & db, const QString & user, const QString & password, const QString & host, int port, - const QString& connOpts) Q_DECL_OVERRIDE; - bool isOpen() const Q_DECL_OVERRIDE; - void close() Q_DECL_OVERRIDE; - QSqlResult *createResult() const Q_DECL_OVERRIDE; - QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; - QSqlIndex primaryIndex(const QString& tablename) const Q_DECL_OVERRIDE; - QSqlRecord record(const QString& tablename) const Q_DECL_OVERRIDE; + const QString& connOpts) override; + bool isOpen() const override; + void close() override; + QSqlResult *createResult() const override; + QStringList tables(QSql::TableType) const override; + QSqlIndex primaryIndex(const QString& tablename) const override; + QSqlRecord record(const QString& tablename) const override; Protocol protocol() const; - QVariant handle() const Q_DECL_OVERRIDE; + QVariant handle() const override; - QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; - QString formatValue(const QSqlField &field, bool trimStrings) const Q_DECL_OVERRIDE; + QString escapeIdentifier(const QString &identifier, IdentifierType type) const override; + QString formatValue(const QSqlField &field, bool trimStrings) const override; - bool subscribeToNotification(const QString &name) Q_DECL_OVERRIDE; - bool unsubscribeFromNotification(const QString &name) Q_DECL_OVERRIDE; - QStringList subscribedToNotifications() const Q_DECL_OVERRIDE; + bool subscribeToNotification(const QString &name) override; + bool unsubscribeFromNotification(const QString &name) override; + QStringList subscribedToNotifications() const override; protected: - bool beginTransaction() Q_DECL_OVERRIDE; - bool commitTransaction() Q_DECL_OVERRIDE; - bool rollbackTransaction() Q_DECL_OVERRIDE; + bool beginTransaction() override; + bool commitTransaction() override; + bool rollbackTransaction() override; private Q_SLOTS: void _q_handleNotification(int); diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp index e9f5ee9508..e1ddd4b25e 100644 --- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp +++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp @@ -123,19 +123,19 @@ class QSQLiteResult : public QSqlCachedResult public: explicit QSQLiteResult(const QSQLiteDriver* db); ~QSQLiteResult(); - QVariant handle() const Q_DECL_OVERRIDE; + QVariant handle() const override; protected: - bool gotoNext(QSqlCachedResult::ValueCache& row, int idx) Q_DECL_OVERRIDE; - bool reset(const QString &query) Q_DECL_OVERRIDE; - bool prepare(const QString &query) Q_DECL_OVERRIDE; - bool exec() Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QVariant lastInsertId() const Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; - void detachFromResultSet() Q_DECL_OVERRIDE; - void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; + bool gotoNext(QSqlCachedResult::ValueCache& row, int idx) override; + bool reset(const QString &query) override; + bool prepare(const QString &query) override; + bool exec() override; + int size() override; + int numRowsAffected() override; + QVariant lastInsertId() const override; + QSqlRecord record() const override; + void detachFromResultSet() override; + void virtual_hook(int id, void *data) override; }; class QSQLiteDriverPrivate : public QSqlDriverPrivate diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite_p.h b/src/plugins/sqldrivers/sqlite/qsql_sqlite_p.h index ca969a4b53..61be4c937f 100644 --- a/src/plugins/sqldrivers/sqlite/qsql_sqlite_p.h +++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite_p.h @@ -75,28 +75,28 @@ public: explicit QSQLiteDriver(QObject *parent = 0); explicit QSQLiteDriver(sqlite3 *connection, QObject *parent = 0); ~QSQLiteDriver(); - bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; + bool hasFeature(DriverFeature f) const override; bool open(const QString & db, const QString & user, const QString & password, const QString & host, int port, - const QString & connOpts) Q_DECL_OVERRIDE; - void close() Q_DECL_OVERRIDE; - QSqlResult *createResult() const Q_DECL_OVERRIDE; - bool beginTransaction() Q_DECL_OVERRIDE; - bool commitTransaction() Q_DECL_OVERRIDE; - bool rollbackTransaction() Q_DECL_OVERRIDE; - QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; + const QString & connOpts) override; + void close() override; + QSqlResult *createResult() const override; + bool beginTransaction() override; + bool commitTransaction() override; + bool rollbackTransaction() override; + QStringList tables(QSql::TableType) const override; - QSqlRecord record(const QString& tablename) const Q_DECL_OVERRIDE; - QSqlIndex primaryIndex(const QString &table) const Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; - QString escapeIdentifier(const QString &identifier, IdentifierType) const Q_DECL_OVERRIDE; + QSqlRecord record(const QString& tablename) const override; + QSqlIndex primaryIndex(const QString &table) const override; + QVariant handle() const override; + QString escapeIdentifier(const QString &identifier, IdentifierType) const override; - bool subscribeToNotification(const QString &name) Q_DECL_OVERRIDE; - bool unsubscribeFromNotification(const QString &name) Q_DECL_OVERRIDE; - QStringList subscribedToNotifications() const Q_DECL_OVERRIDE; + bool subscribeToNotification(const QString &name) override; + bool unsubscribeFromNotification(const QString &name) override; + QStringList subscribedToNotifications() const override; private Q_SLOTS: void handleNotification(const QString &tableName, qint64 rowid); }; diff --git a/src/plugins/sqldrivers/sqlite/smain.cpp b/src/plugins/sqldrivers/sqlite/smain.cpp index 2ad466a61e..092813990c 100644 --- a/src/plugins/sqldrivers/sqlite/smain.cpp +++ b/src/plugins/sqldrivers/sqlite/smain.cpp @@ -51,7 +51,7 @@ class QSQLiteDriverPlugin : public QSqlDriverPlugin public: QSQLiteDriverPlugin(); - QSqlDriver* create(const QString &) Q_DECL_OVERRIDE; + QSqlDriver* create(const QString &) override; }; QSQLiteDriverPlugin::QSQLiteDriverPlugin() diff --git a/src/plugins/sqldrivers/sqlite2/qsql_sqlite2.cpp b/src/plugins/sqldrivers/sqlite2/qsql_sqlite2.cpp index 93f47e3f13..9745c5ebc6 100644 --- a/src/plugins/sqldrivers/sqlite2/qsql_sqlite2.cpp +++ b/src/plugins/sqldrivers/sqlite2/qsql_sqlite2.cpp @@ -107,16 +107,16 @@ class QSQLite2Result : public QSqlCachedResult public: explicit QSQLite2Result(const QSQLite2Driver* db); ~QSQLite2Result(); - QVariant handle() const Q_DECL_OVERRIDE; + QVariant handle() const override; protected: - bool gotoNext(QSqlCachedResult::ValueCache &row, int idx) Q_DECL_OVERRIDE; - bool reset(const QString &query) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; - void detachFromResultSet() Q_DECL_OVERRIDE; - void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; + bool gotoNext(QSqlCachedResult::ValueCache &row, int idx) override; + bool reset(const QString &query) override; + int size() override; + int numRowsAffected() override; + QSqlRecord record() const override; + void detachFromResultSet() override; + void virtual_hook(int id, void *data) override; }; class QSQLite2ResultPrivate: public QSqlCachedResultPrivate diff --git a/src/plugins/sqldrivers/sqlite2/qsql_sqlite2_p.h b/src/plugins/sqldrivers/sqlite2/qsql_sqlite2_p.h index 83b248ec6a..48c64536f1 100644 --- a/src/plugins/sqldrivers/sqlite2/qsql_sqlite2_p.h +++ b/src/plugins/sqldrivers/sqlite2/qsql_sqlite2_p.h @@ -79,29 +79,29 @@ public: explicit QSQLite2Driver(QObject *parent = 0); explicit QSQLite2Driver(sqlite *connection, QObject *parent = 0); ~QSQLite2Driver(); - bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; + bool hasFeature(DriverFeature f) const override; bool open(const QString &db, const QString &user, const QString &password, const QString &host, int port, - const QString &connOpts) Q_DECL_OVERRIDE; + const QString &connOpts) override; bool open(const QString &db, const QString &user, const QString &password, const QString &host, int port) { return open(db, user, password, host, port, QString()); } - void close() Q_DECL_OVERRIDE; - QSqlResult *createResult() const Q_DECL_OVERRIDE; - bool beginTransaction() Q_DECL_OVERRIDE; - bool commitTransaction() Q_DECL_OVERRIDE; - bool rollbackTransaction() Q_DECL_OVERRIDE; - QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; + void close() override; + QSqlResult *createResult() const override; + bool beginTransaction() override; + bool commitTransaction() override; + bool rollbackTransaction() override; + QStringList tables(QSql::TableType) const override; - QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE; - QSqlIndex primaryIndex(const QString &table) const Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; - QString escapeIdentifier(const QString &identifier, IdentifierType) const Q_DECL_OVERRIDE; + QSqlRecord record(const QString &tablename) const override; + QSqlIndex primaryIndex(const QString &table) const override; + QVariant handle() const override; + QString escapeIdentifier(const QString &identifier, IdentifierType) const override; }; QT_END_NAMESPACE diff --git a/src/plugins/sqldrivers/tds/qsql_tds.cpp b/src/plugins/sqldrivers/tds/qsql_tds.cpp index 670198af81..5fc34da407 100644 --- a/src/plugins/sqldrivers/tds/qsql_tds.cpp +++ b/src/plugins/sqldrivers/tds/qsql_tds.cpp @@ -163,15 +163,15 @@ class QTDSResult : public QSqlCachedResult public: explicit QTDSResult(const QTDSDriver* db); ~QTDSResult(); - QVariant handle() const Q_DECL_OVERRIDE; + QVariant handle() const override; protected: void cleanup(); - bool reset(const QString &query) Q_DECL_OVERRIDE; - int size() Q_DECL_OVERRIDE; - int numRowsAffected() Q_DECL_OVERRIDE; - bool gotoNext(QSqlCachedResult::ValueCache &values, int index) Q_DECL_OVERRIDE; - QSqlRecord record() const Q_DECL_OVERRIDE; + bool reset(const QString &query) override; + int size() override; + int numRowsAffected() override; + bool gotoNext(QSqlCachedResult::ValueCache &values, int index) override; + QSqlRecord record() const override; }; class QTDSResultPrivate: public QSqlCachedResultPrivate diff --git a/src/plugins/sqldrivers/tds/qsql_tds_p.h b/src/plugins/sqldrivers/tds/qsql_tds_p.h index d0914455a2..948e3c7024 100644 --- a/src/plugins/sqldrivers/tds/qsql_tds_p.h +++ b/src/plugins/sqldrivers/tds/qsql_tds_p.h @@ -88,29 +88,29 @@ public: explicit QTDSDriver(QObject* parent = 0); QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QObject* parent = 0); ~QTDSDriver(); - bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE; + bool hasFeature(DriverFeature f) const override; bool open(const QString &db, const QString &user, const QString &password, const QString &host, int port, - const QString &connOpts) Q_DECL_OVERRIDE; - void close() Q_DECL_OVERRIDE; - QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE; - QSqlResult *createResult() const Q_DECL_OVERRIDE; - QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE; - QSqlIndex primaryIndex(const QString &tablename) const Q_DECL_OVERRIDE; + const QString &connOpts) override; + void close() override; + QStringList tables(QSql::TableType) const override; + QSqlResult *createResult() const override; + QSqlRecord record(const QString &tablename) const override; + QSqlIndex primaryIndex(const QString &tablename) const override; QString formatValue(const QSqlField &field, - bool trimStrings) const Q_DECL_OVERRIDE; - QVariant handle() const Q_DECL_OVERRIDE; + bool trimStrings) const override; + QVariant handle() const override; - QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE; + QString escapeIdentifier(const QString &identifier, IdentifierType type) const override; protected: - bool beginTransaction() Q_DECL_OVERRIDE; - bool commitTransaction() Q_DECL_OVERRIDE; - bool rollbackTransaction() Q_DECL_OVERRIDE; + bool beginTransaction() override; + bool commitTransaction() override; + bool rollbackTransaction() override; private: void init(); }; diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp index 0a47ccf68a..ba993e55f2 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp @@ -3963,6 +3963,40 @@ QWindowsXPStyle::QWindowsXPStyle(QWindowsXPStylePrivate &dd) : QWindowsStyle(dd) { } +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const XPThemeData &t) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "XPThemeData(" << t.widget << ", theme=#" << t.theme << ", " << t.htheme + << ", partId=" << t.partId << ", stateId=" << t.stateId << ", rect=" << t.rect + << ", mirrorHorizontally=" << t.mirrorHorizontally << ", mirrorVertically=" + << t.mirrorVertically << ", noBorder=" << t.noBorder << ", noContent=" << t.noContent + << ", rotate=" << t.rotate << ')'; + return d; +} + +QDebug operator<<(QDebug d, const ThemeMapKey &k) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "ThemeMapKey(theme=#" << k.theme + << ", partId=" << k.partId << ", stateId=" << k.stateId + << ", noBorder=" << k.noBorder << ", noContent=" << k.noContent << ')'; + return d; +} + +QDebug operator<<(QDebug d, const ThemeMapData &td) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "ThemeMapData(alphaType=" << td.alphaType + << ", dataValid=" << td.dataValid << ", partIsTransparent=" << td.partIsTransparent + << ", hasAlphaChannel=" << td.hasAlphaChannel << ", wasAlphaSwapped=" << td.wasAlphaSwapped + << ", hadInvalidAlpha=" << td.hadInvalidAlpha << ')'; + return d; +} +#endif // QT_NO_DEBUG_STREAM // Debugging code ---------------------------------------------------------------------[ START ]--- // The code for this point on is not compiled by default, but only used as assisting diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h b/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h index 721a734829..4f3fd9c48d 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle_p_p.h @@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE +class QDebug; + // TMT_TEXTSHADOWCOLOR is wrongly defined in mingw #if TMT_TEXTSHADOWCOLOR != 3818 #undef TMT_TEXTSHADOWCOLOR @@ -181,6 +183,12 @@ struct ThemeMapData { hasAlphaChannel(false), wasAlphaSwapped(false), hadInvalidAlpha(false) {} }; +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, const XPThemeData &t); +QDebug operator<<(QDebug d, const ThemeMapKey &k); +QDebug operator<<(QDebug d, const ThemeMapData &td); +#endif + class QWindowsXPStylePrivate : public QWindowsStylePrivate { Q_DECLARE_PUBLIC(QWindowsXPStyle) |