diff options
author | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-08-22 11:30:00 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-08-22 11:30:01 +0200 |
commit | d314819fc02139e05e16c56657898c704f7fb48f (patch) | |
tree | a61ba968233634948401c8339f9613844de1c2b5 /src/plugins/platforms | |
parent | 9f888d2fde9c5413e5519e0914e9b13638760985 (diff) | |
parent | e0e9e196a72ffe5457034894eaaadc90ed0d34ef (diff) |
Merge dev into 5.8
Change-Id: I41ee7b50534b01cf042bed8bb8824ba2e5026a29
Diffstat (limited to 'src/plugins/platforms')
84 files changed, 887 insertions, 448 deletions
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp index 5be128a0c5..5f05ab395e 100644 --- a/src/plugins/platforms/android/androidjniinput.cpp +++ b/src/plugins/platforms/android/androidjniinput.cpp @@ -1,7 +1,8 @@ /**************************************************************************** ** ** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org> -** Contact: https://www.qt.io/licensing/ +** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com> +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** @@ -120,6 +121,12 @@ namespace QtAndroidInput return m_softwareKeyboardRect; } + void updateHandles(int mode, QPoint cursor, QPoint anchor) + { + QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "updateHandles", "(IIIII)V", + mode, cursor.x(), cursor.y(), anchor.x(), + anchor.y()); + } static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y) { @@ -168,6 +175,10 @@ namespace QtAndroidInput static void longPress(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y) { + QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext(); + if (inputContext && qGuiApp) + QMetaObject::invokeMethod(inputContext, "longPress", Q_ARG(int, x), Q_ARG(int, y)); + //### TODO: add proper API for Qt 5.2 static bool rightMouseFromLongPress = qEnvironmentVariableIntValue("QT_NECESSITAS_COMPATIBILITY_LONG_PRESS"); if (!rightMouseFromLongPress) @@ -225,6 +236,12 @@ namespace QtAndroidInput double(dw*size), double(dh*size)); m_touchPoints.push_back(touchPoint); + + if (state == Qt::TouchPointPressed) { + QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext(); + if (inputContext && qGuiApp) + QMetaObject::invokeMethod(inputContext, "touchDown", Q_ARG(int, x), Q_ARG(int, y)); + } } static void touchEnd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint /*action*/) @@ -786,6 +803,18 @@ namespace QtAndroidInput #endif } + static void handleLocationChanged(JNIEnv */*env*/, jobject /*thiz*/, int id, int x, int y) + { +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL + qDebug() << "@@@ handleLocationChanged" << id << x << y; +#endif + QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext(); + if (inputContext && qGuiApp) + QMetaObject::invokeMethod(inputContext, "handleLocationChanged", + Q_ARG(int, id), Q_ARG(int, x), Q_ARG(int, y)); + + } + static JNINativeMethod methods[] = { {"touchBegin","(I)V",(void*)touchBegin}, {"touchAdd","(IIIZIIFF)V",(void*)touchAdd}, @@ -799,7 +828,8 @@ namespace QtAndroidInput {"keyDown", "(IIIZ)V", (void *)keyDown}, {"keyUp", "(IIIZ)V", (void *)keyUp}, {"keyboardVisibilityChanged", "(Z)V", (void *)keyboardVisibilityChanged}, - {"keyboardGeometryChanged", "(IIII)V", (void *)keyboardGeometryChanged} + {"keyboardGeometryChanged", "(IIII)V", (void *)keyboardGeometryChanged}, + {"handleLocationChanged", "(III)V", (void *)handleLocationChanged} }; bool registerNatives(JNIEnv *env) diff --git a/src/plugins/platforms/android/androidjniinput.h b/src/plugins/platforms/android/androidjniinput.h index 682abde098..af18a96dc1 100644 --- a/src/plugins/platforms/android/androidjniinput.h +++ b/src/plugins/platforms/android/androidjniinput.h @@ -39,6 +39,7 @@ #ifndef ANDROIDJNIINPUT_H #define ANDROIDJNIINPUT_H + #include <jni.h> #include <QtCore/qglobal.h> #include <QtCore/QRect> @@ -56,6 +57,9 @@ namespace QtAndroidInput void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd); // Software keyboard support + // cursor/selection handles + void updateHandles(int handleCount, QPoint cursor = QPoint(), QPoint anchor = QPoint()); + bool registerNatives(JNIEnv *env); } diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 6419ba2c51..677a2e2626 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -550,8 +550,11 @@ static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/) static void terminateQt(JNIEnv *env, jclass /*clazz*/) { - sem_wait(&m_terminateSemaphore); - sem_destroy(&m_terminateSemaphore); + // QAndroidEventDispatcherStopper is stopped when the user uses the task manager to kill the application + if (!QAndroidEventDispatcherStopper::instance()->stopped()) { + sem_wait(&m_terminateSemaphore); + sem_destroy(&m_terminateSemaphore); + } env->DeleteGlobalRef(m_applicationClass); env->DeleteGlobalRef(m_classLoaderObject); if (m_resourcesObj) @@ -571,8 +574,11 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/) m_androidPlatformIntegration = nullptr; delete m_androidAssetsFileEngineHandler; m_androidAssetsFileEngineHandler = nullptr; - sem_post(&m_exitSemaphore); - pthread_join(m_qtAppThread, nullptr); + + if (!QAndroidEventDispatcherStopper::instance()->stopped()) { + sem_post(&m_exitSemaphore); + pthread_join(m_qtAppThread, nullptr); + } } static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, jint w, jint h) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 125a03469f..06a9c8c488 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -2,6 +2,7 @@ ** ** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org> +** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -342,9 +343,28 @@ static JNINativeMethod methods[] = { {"updateCursorPosition", "()Z", (void *)updateCursorPosition} }; +static QRect inputItemRectangle() +{ + QRectF itemRect = qGuiApp->inputMethod()->inputItemRectangle(); + QRect rect = qGuiApp->inputMethod()->inputItemTransform().mapRect(itemRect).toRect(); + QWindow *window = qGuiApp->focusWindow(); + if (window) + rect = QRect(window->mapToGlobal(rect.topLeft()), rect.size()); + double pixelDensity = window + ? QHighDpiScaling::factor(window) + : QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen()); + if (pixelDensity != 1.0) { + rect.setX(rect.x() * pixelDensity); + rect.setY(rect.y() * pixelDensity); + rect.setWidth(rect.width() * pixelDensity); + rect.setHeight(rect.height() * pixelDensity); + } + return rect; +} QAndroidInputContext::QAndroidInputContext() - : QPlatformInputContext(), m_composingTextStart(-1), m_blockUpdateSelection(false), m_batchEditNestingLevel(0), m_focusObject(0) + : QPlatformInputContext(), m_composingTextStart(-1), m_blockUpdateSelection(false), + m_cursorHandleShown(CursorHandleNotShown), m_batchEditNestingLevel(0), m_focusObject(0) { jclass clazz = QJNIEnvironmentPrivate::findClass(QtNativeInputConnectionClassName); if (Q_UNLIKELY(!clazz)) { @@ -415,6 +435,9 @@ QAndroidInputContext::QAndroidInputContext() qRegisterMetaType<QInputMethodEvent *>("QInputMethodEvent*"); qRegisterMetaType<QInputMethodQueryEvent *>("QInputMethodQueryEvent*"); m_androidInputContext = this; + + QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged, + this, &QAndroidInputContext::updateSelectionHandles); } QAndroidInputContext::~QAndroidInputContext() @@ -452,6 +475,7 @@ void QAndroidInputContext::reset() { clear(); m_batchEditNestingLevel = 0; + m_cursorHandleShown = QAndroidInputContext::CursorHandleNotShown; if (qGuiApp->focusObject()) { QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe(Qt::ImEnabled); if (!query.isNull() && query->value(Qt::ImEnabled).toBool()) { @@ -500,6 +524,119 @@ void QAndroidInputContext::updateCursorPosition() } } +void QAndroidInputContext::updateSelectionHandles() +{ + auto im = qGuiApp->inputMethod(); + if (!m_focusObject || (m_cursorHandleShown == CursorHandleNotShown)) { + // Hide the handles + QtAndroidInput::updateHandles(0); + return; + } + QWindow *window = qGuiApp->focusWindow(); + double pixelDensity = window + ? QHighDpiScaling::factor(window) + : QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen()); + + QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition | Qt::ImEnabled); + QCoreApplication::sendEvent(m_focusObject, &query); + int cpos = query.value(Qt::ImCursorPosition).toInt(); + int anchor = query.value(Qt::ImAnchorPosition).toInt(); + + if (cpos == anchor || im->anchorRectangle().isNull()) { + if (!query.value(Qt::ImEnabled).toBool()) { + QtAndroidInput::updateHandles(0); + return; + } + + auto curRect = im->cursorRectangle(); + QPoint cursorPoint(curRect.center().x(), curRect.bottom()); + QPoint editMenuPoint(curRect.center().x(), curRect.top()); + QtAndroidInput::updateHandles(m_cursorHandleShown, cursorPoint * pixelDensity, + editMenuPoint * pixelDensity); + return; + } + + auto leftRect = im->cursorRectangle(); + auto rightRect = im->anchorRectangle(); + if (cpos > anchor) + std::swap(leftRect, rightRect); + + QPoint leftPoint(leftRect.bottomLeft().toPoint() * pixelDensity); + QPoint righPoint(rightRect.bottomRight().toPoint() * pixelDensity); + QtAndroidInput::updateHandles(CursorHandleShowSelection, leftPoint, righPoint); + + if (m_cursorHandleShown == CursorHandleShowPopup) { + // make sure the popup does not reappear when the selection menu closes + m_cursorHandleShown = QAndroidInputContext::CursorHandleNotShown; + } +} + +/* + Called from Java when a cursor/selection handle was dragged to a new position + + handleId of 1 means the cursor handle, 2 means the left handle, 3 means the right handle + */ +void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y) +{ + auto im = qGuiApp->inputMethod(); + auto leftRect = im->cursorRectangle(); + // The handle is down of the cursor, but we want the position in the middle. + QWindow *window = qGuiApp->focusWindow(); + double pixelDensity = window + ? QHighDpiScaling::factor(window) + : QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen()); + QPoint point(x / pixelDensity, y / pixelDensity); + y -= leftRect.width() / 2; + if (handleId == 1) { + setSelectionOnFocusObject(point, point); + return; + } + + QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition); + QCoreApplication::sendEvent(m_focusObject, &query); + int cpos = query.value(Qt::ImCursorPosition).toInt(); + int anchor = query.value(Qt::ImAnchorPosition).toInt(); + + auto rightRect = im->anchorRectangle(); + if (cpos > anchor) + std::swap(leftRect, rightRect); + + if (handleId == 2) { + QPoint rightPoint(rightRect.center().toPoint()); + setSelectionOnFocusObject(point, rightPoint); + } else if (handleId == 3) { + QPoint leftPoint(leftRect.center().toPoint()); + setSelectionOnFocusObject(leftPoint, point); + } +} + +void QAndroidInputContext::touchDown(int x, int y) +{ + if (m_focusObject && inputItemRectangle().contains(x, y) && !m_cursorHandleShown) { + // If the user touch the input rectangle, we can show the cursor handle + m_cursorHandleShown = QAndroidInputContext::CursorHandleShowNormal; + updateSelectionHandles(); + } +} + +void QAndroidInputContext::longPress(int x, int y) +{ + if (m_focusObject && inputItemRectangle().contains(x, y)) { + // Show the paste menu if there is something to paste. + m_cursorHandleShown = QAndroidInputContext::CursorHandleShowPopup; + updateSelectionHandles(); + } +} + +void QAndroidInputContext::keyDown() +{ + if (m_cursorHandleShown) { + // When the user enter text on the keyboard, we hide the cursor handle + m_cursorHandleShown = QAndroidInputContext::CursorHandleNotShown; + updateSelectionHandles(); + } +} + void QAndroidInputContext::update(Qt::InputMethodQueries queries) { QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQueryThreadSafe(queries); @@ -543,22 +680,11 @@ void QAndroidInputContext::showInputPanel() m_updateCursorPosConnection = connect(qGuiApp->focusObject(), SIGNAL(cursorPositionChanged(int,int)), this, SLOT(updateCursorPosition())); else m_updateCursorPosConnection = connect(qGuiApp->focusObject(), SIGNAL(cursorPositionChanged()), this, SLOT(updateCursorPosition())); - QRectF itemRect = qGuiApp->inputMethod()->inputItemRectangle(); - QRect rect = qGuiApp->inputMethod()->inputItemTransform().mapRect(itemRect).toRect(); - QWindow *window = qGuiApp->focusWindow(); - if (window) - rect = QRect(window->mapToGlobal(rect.topLeft()), rect.size()); - double pixelDensity = window ? QHighDpiScaling::factor(window) - : QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen()); - - QtAndroidInput::showSoftwareKeyboard(rect.left() * pixelDensity, - rect.top() * pixelDensity, - rect.width() * pixelDensity, - rect.height() * pixelDensity, + QRect rect = inputItemRectangle(); + QtAndroidInput::showSoftwareKeyboard(rect.left(), rect.top(), rect.width(), rect.height(), query->value(Qt::ImHints).toUInt(), - query->value(Qt::ImEnterKeyType).toUInt() - ); + query->value(Qt::ImEnterKeyType).toUInt()); } void QAndroidInputContext::showInputPanelLater(Qt::ApplicationState state) @@ -601,6 +727,7 @@ void QAndroidInputContext::setFocusObject(QObject *object) reset(); } QPlatformInputContext::setFocusObject(object); + updateSelectionHandles(); } jboolean QAndroidInputContext::beginBatchEdit() @@ -858,6 +985,8 @@ jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCur QInputMethodEvent event(m_composingText, attributes); sendInputMethodEventThreadSafe(&event); + QMetaObject::invokeMethod(this, "keyDown"); + updateCursorPosition(); return JNI_TRUE; @@ -979,20 +1108,21 @@ jboolean QAndroidInputContext::setSelection(jint start, jint end) jboolean QAndroidInputContext::selectAll() { -#warning TODO - return JNI_FALSE; + sendShortcut(QKeySequence::SelectAll); + return JNI_TRUE; } jboolean QAndroidInputContext::cut() { -#warning TODO - return JNI_FALSE; + m_cursorHandleShown = CursorHandleNotShown; + sendShortcut(QKeySequence::Cut); + return JNI_TRUE; } jboolean QAndroidInputContext::copy() { -#warning TODO - return JNI_FALSE; + sendShortcut(QKeySequence::Copy); + return JNI_TRUE; } jboolean QAndroidInputContext::copyURL() @@ -1003,10 +1133,21 @@ jboolean QAndroidInputContext::copyURL() jboolean QAndroidInputContext::paste() { -#warning TODO - return JNI_FALSE; + m_cursorHandleShown = CursorHandleNotShown; + sendShortcut(QKeySequence::Paste); + return JNI_TRUE; } +void QAndroidInputContext::sendShortcut(const QKeySequence &sequence) +{ + for (int i = 0; i < sequence.count(); ++i) { + const int keys = sequence[i]; + Qt::Key key = Qt::Key(keys & ~Qt::KeyboardModifierMask); + Qt::KeyboardModifiers mod = Qt::KeyboardModifiers(keys & Qt::KeyboardModifierMask); + QGuiApplication::postEvent(m_focusObject, new QKeyEvent(QEvent::KeyPress, key, mod)); + QGuiApplication::postEvent(m_focusObject, new QKeyEvent(QEvent::KeyRelease, key, mod)); + } +} Q_INVOKABLE QVariant QAndroidInputContext::queryFocusObjectUnsafe(Qt::InputMethodQuery query, QVariant argument) { diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h index 5ab85dcab0..8a33ff71cc 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.h +++ b/src/plugins/platforms/android/qandroidinputcontext.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org> +** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -94,6 +95,7 @@ public: bool isComposing() const; void clear(); void setFocusObject(QObject *object); + void sendShortcut(const QKeySequence &); //---------------// jboolean beginBatchEdit(); @@ -117,6 +119,11 @@ public: public slots: void updateCursorPosition(); + void updateSelectionHandles(); + void handleLocationChanged(int handleId, int x, int y); + void touchDown(int x, int y); + void longPress(int x, int y); + void keyDown(); private slots: void showInputPanelLater(Qt::ApplicationState); @@ -138,6 +145,13 @@ private: int m_composingCursor; QMetaObject::Connection m_updateCursorPosConnection; bool m_blockUpdateSelection; + enum CursorHandleShowMode { + CursorHandleNotShown, + CursorHandleShowNormal = 1, + CursorHandleShowSelection = 2, + CursorHandleShowPopup = 3 + }; + CursorHandleShowMode m_cursorHandleShown; int m_batchEditNestingLevel; QObject *m_focusObject; }; diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp index 0667a9073f..a14271c8f5 100644 --- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp +++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp @@ -60,7 +60,8 @@ void QAndroidPlatformFontDatabase::populateFontDatabase() QStringList nameFilters; nameFilters << QLatin1String("*.ttf") - << QLatin1String("*.otf"); + << QLatin1String("*.otf") + << QLatin1String("*.ttc"); const auto entries = dir.entryInfoList(nameFilters, QDir::Files); for (const QFileInfo &fi : entries) { diff --git a/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp b/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp index edb4f4e660..e935d89c9f 100644 --- a/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp +++ b/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp @@ -48,7 +48,7 @@ #include <qpa/qplatforminputcontext.h> #include <qpa/qplatforminputcontextfactory_p.h> -#if !defined(QT_NO_TSLIB) +#if QT_CONFIG(tslib) #include <QtPlatformSupport/private/qtslib_p.h> #endif @@ -127,7 +127,7 @@ QPlatformServices *QBsdFbIntegration::services() const void QBsdFbIntegration::createInputHandlers() { -#ifndef QT_NO_TSLIB +#if QT_CONFIG(tslib) const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_FB_TSLIB"); if (useTslib) new QTsLibMouseHandler(QLatin1String("TsLib"), QString()); diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 02d8b16110..d9d3cb1627 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -71,7 +71,7 @@ HEADERS += qcocoaintegration.h \ messages.h \ qcocoamimetypes.h -contains(QT_CONFIG, opengl.*) { +qtConfig(opengl.*) { OBJECTIVE_SOURCES += qcocoaglcontext.mm HEADERS += qcocoaglcontext.h diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm index 1ebcde0584..13ae0382ab 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -40,6 +40,9 @@ #include "qcocoadrag.h" #include "qmacclipboard.h" #include "qcocoahelpers.h" +#ifndef QT_NO_WIDGETS +#include <QtWidgets/qwidget.h> +#endif QT_BEGIN_NAMESPACE @@ -187,7 +190,18 @@ QPixmap QCocoaDrag::dragPixmap(QDrag *drag, QPoint &hotSpot) const const int width = fm.width(s); const int height = fm.height(); if (width > 0 && height > 0) { - pm = QPixmap(width, height); + qreal dpr = 1.0; + if (const QWindow *sourceWindow = qobject_cast<QWindow *>(drag->source())) { + dpr = sourceWindow->devicePixelRatio(); + } +#ifndef QT_NO_WIDGETS + else if (const QWidget *sourceWidget = qobject_cast<QWidget *>(drag->source())) { + if (const QWindow *sourceWindow = sourceWidget->window()->windowHandle()) + dpr = sourceWindow->devicePixelRatio(); + } +#endif + pm = QPixmap(width * dpr, height * dpr); + pm.setDevicePixelRatio(dpr); QPainter p(&pm); p.fillRect(0, 0, pm.width(), pm.height(), Qt::color0); p.setPen(Qt::color1); diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 0375dd85f2..31a0a3d600 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -589,6 +589,15 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted) QCocoaMenuBar::resetKnownMenuItemsToQt(); if (accepted) { emit accept(); + + QString filter = selectedNameFilter(); + if (filter.isEmpty()) + emit filterSelected(filter); + + QList<QUrl> files = selectedFiles(); + emit filesSelected(files); + if (files.count() == 1) + emit fileSelected(files.first()); } else { emit reject(); } diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index dc7dfb788f..dfda22d376 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -365,6 +365,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate); emit mHelper->reject(); } else { emit mHelper->accept(); + emit mHelper->fontSelected(mHelper->currentFont()); } } } diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 9b4055d92d..6920f75887 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -101,65 +101,23 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list) return result; } -static void qt_mac_deleteImage(void *image, const void *, size_t) -{ - delete static_cast<QImage *>(image); -} - -// Creates a CGDataProvider with the data from the given image. -// The data provider retains a copy of the image. -CGDataProviderRef qt_mac_CGDataProvider(const QImage &image) -{ - return CGDataProviderCreateWithData(new QImage(image), image.bits(), - image.byteCount(), qt_mac_deleteImage); -} - CGImageRef qt_mac_toCGImage(const QImage &inImage) { - if (inImage.isNull()) - return 0; + CGImageRef cgImage = inImage.toCGImage(); + if (cgImage) + return cgImage; - QImage image = inImage; - - uint cgflags = kCGImageAlphaNone; - switch (image.format()) { - case QImage::Format_ARGB32: - cgflags = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; - break; - case QImage::Format_RGB32: - cgflags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; - break; - case QImage::Format_RGB888: - cgflags = kCGImageAlphaNone | kCGBitmapByteOrder32Big; - break; - case QImage::Format_RGBA8888_Premultiplied: - cgflags = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big; - break; - case QImage::Format_RGBA8888: - cgflags = kCGImageAlphaLast | kCGBitmapByteOrder32Big; - break; - case QImage::Format_RGBX8888: - cgflags = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big; - break; - default: - // Everything not recognized explicitly is converted to ARGB32_Premultiplied. - image = inImage.convertToFormat(QImage::Format_ARGB32_Premultiplied); - // no break; - case QImage::Format_ARGB32_Premultiplied: - cgflags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; - break; - } - - QCFType<CGDataProviderRef> dataProvider = qt_mac_CGDataProvider(image); - return CGImageCreate(image.width(), image.height(), 8, 32, - image.bytesPerLine(), - qt_mac_genericColorSpace(), - cgflags, dataProvider, 0, false, kCGRenderingIntentDefault); + // Convert image data to a known-good format if the fast conversion fails. + return inImage.convertToFormat(QImage::Format_ARGB32_Premultiplied).toCGImage(); } CGImageRef qt_mac_toCGImageMask(const QImage &image) { - QCFType<CGDataProviderRef> dataProvider = qt_mac_CGDataProvider(image); + static const auto deleter = [](void *image, const void *, size_t) { delete static_cast<QImage *>(image); }; + QCFType<CGDataProviderRef> dataProvider = + CGDataProviderCreateWithData(new QImage(image), image.bits(), + image.byteCount(), deleter); + return CGImageMaskCreate(image.width(), image.height(), 8, image.depth(), image.bytesPerLine(), dataProvider, NULL, false); } @@ -647,7 +605,7 @@ QString qt_mac_removeAmpersandEscapes(QString s) returned if it can't be obtained. It is the caller's responsibility to CGContextRelease the context when finished using it. - \warning This function is only available on OS X. + \warning This function is only available on \macos. \warning This function is duplicated in qmacstyle_mac.mm */ CGContextRef qt_mac_cg_context(QPaintDevice *pdev) diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 3a3d634f5a..cb8ffee556 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -287,7 +287,8 @@ public: const qreal devicePixelRatio = qGuiApp->devicePixelRatio(); const int sizes[] = { qRound(16 * devicePixelRatio), qRound(32 * devicePixelRatio), - qRound(64 * devicePixelRatio), qRound(128 * devicePixelRatio) + qRound(64 * devicePixelRatio), qRound(128 * devicePixelRatio), + qRound(256 * devicePixelRatio) }; return QAbstractFileIconEngine::toSizeList(sizes, sizes + sizeof(sizes) / sizeof(sizes[0])); } diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 500049a504..af324c07ff 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1999,16 +1999,27 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin return target->mapFromGlobal(source->mapToGlobal(point)); } -- (NSDragOperation) draggingSourceOperationMaskForLocal:(BOOL)isLocal +- (NSDragOperation)draggingSession:(NSDraggingSession *)session + sourceOperationMaskForDraggingContext:(NSDraggingContext)context { - Q_UNUSED(isLocal); + Q_UNUSED(session); + Q_UNUSED(context); QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); return qt_mac_mapDropActions(nativeDrag->currentDrag()->supportedActions()); } -- (BOOL) ignoreModifierKeysWhileDragging +- (BOOL)ignoreModifierKeysForDraggingSession:(NSDraggingSession *)session { - return NO; + Q_UNUSED(session); + // According to the "Dragging Sources" chapter on Cocoa DnD Programming + // (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DragandDrop/Concepts/dragsource.html), + // if the control, option, or command key is pressed, the source’s + // operation mask is filtered to only contain a reduced set of operations. + // + // Since Qt already takes care of tracking the keyboard modifiers, we + // don't need (or want) Cocoa to filter anything. Instead, we'll let + // the application do the actual filtering. + return YES; } - (BOOL)wantsPeriodicDraggingUpdates @@ -2165,27 +2176,27 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin return response.isAccepted(); } -- (void)draggedImage:(NSImage*) img endedAt:(NSPoint) point operation:(NSDragOperation) operation +- (void)draggingSession:(NSDraggingSession *)session + endedAtPoint:(NSPoint)screenPoint + operation:(NSDragOperation)operation { - Q_UNUSED(img); + Q_UNUSED(session); Q_UNUSED(operation); QWindow *target = findEventTargetWindow(m_window); if (!target) return; -// keep our state, and QGuiApplication state (buttons member) in-sync, -// or future mouse events will be processed incorrectly + // keep our state, and QGuiApplication state (buttons member) in-sync, + // or future mouse events will be processed incorrectly NSUInteger pmb = [NSEvent pressedMouseButtons]; for (int buttonNumber = 0; buttonNumber < 32; buttonNumber++) { // see cocoaButton2QtButton() for the 32 value if (!(pmb & (1 << buttonNumber))) m_buttons &= ~cocoaButton2QtButton(buttonNumber); } - NSPoint windowPoint = [self convertPoint: point fromView: nil]; + NSPoint windowPoint = [self.window convertRectFromScreen:NSMakeRect(screenPoint.x, screenPoint.y, 1, 1)].origin; QPoint qtWindowPoint(windowPoint.x, windowPoint.y); - NSWindow *window = [self window]; - NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(point.x, point.y, 0, 0)].origin; QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y)); QWindowSystemInterface::handleMouseEvent(target, mapWindowCoordinates(m_window, target, qtWindowPoint), qtScreenPoint, m_buttons); diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro index 5c81e0283a..de0344ff5c 100644 --- a/src/plugins/platforms/directfb/directfb.pro +++ b/src/plugins/platforms/directfb/directfb.pro @@ -2,8 +2,7 @@ TARGET = qdirectfb QT += core-private gui-private platformsupport-private -LIBS += $$QMAKE_LIBS_DIRECTFB -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_DIRECTFB +QMAKE_USE += directfb SOURCES = main.cpp \ qdirectfbintegration.cpp \ @@ -25,7 +24,7 @@ HEADERS = qdirectfbintegration.h \ qdirectfbeglhooks.h # ### port the GL context -contains(QT_CONFIG, directfb_egl) { +qtConfig(directfb_egl) { HEADERS += qdirectfb_egl.h SOURCES += qdirectfb_egl.cpp DEFINES += DIRECTFB_GL_EGL diff --git a/src/plugins/platforms/directfb/qdirectfb_egl.cpp b/src/plugins/platforms/directfb/qdirectfb_egl.cpp index 0e706d789a..2a04c0bba3 100644 --- a/src/plugins/platforms/directfb/qdirectfb_egl.cpp +++ b/src/plugins/platforms/directfb/qdirectfb_egl.cpp @@ -49,7 +49,7 @@ #include <QtPlatformSupport/private/qeglplatformcontext_p.h> #include <QtPlatformSupport/private/qeglconvenience_p.h> -#include <EGL/egl.h> +#include <QtPlatformSupport/private/qt_egl_p.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp index 7c1f11372a..0040ecd59d 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp @@ -59,12 +59,11 @@ QT_BEGIN_NAMESPACE QEglFSCursor::QEglFSCursor(QPlatformScreen *screen) - : m_visible(true), - m_screen(static_cast<QEglFSScreen *>(screen)), - m_program(0), - m_textureEntry(0), - m_deviceListener(0), - m_updateRequested(false) + : m_visible(true), + m_screen(static_cast<QEglFSScreen *>(screen)), + m_activeScreen(nullptr), + m_deviceListener(0), + m_updateRequested(false) { QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); if (!hideCursorVal.isEmpty()) @@ -116,15 +115,14 @@ void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::Device void QEglFSCursor::resetResources() { - if (QOpenGLContext::currentContext()) { - delete m_program; - glDeleteTextures(1, &m_cursor.customCursorTexture); - glDeleteTextures(1, &m_cursorAtlas.texture); + if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) { + GraphicsContextData &gfx(m_gfx[ctx]); + delete gfx.program; + glDeleteTextures(1, &gfx.customCursorTexture); + glDeleteTextures(1, &gfx.atlasTexture); + gfx = GraphicsContextData(); } - m_program = 0; - m_cursor.customCursorTexture = 0; m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull(); - m_cursorAtlas.texture = 0; } void QEglFSCursor::createShaderPrograms() @@ -146,15 +144,16 @@ void QEglFSCursor::createShaderPrograms() " gl_FragColor = texture2D(texture, textureCoord).bgra;\n" "}\n"; - m_program = new QOpenGLShaderProgram; - m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); - m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram); - m_program->bindAttributeLocation("vertexCoordEntry", 0); - m_program->bindAttributeLocation("textureCoordEntry", 1); - m_program->link(); + GraphicsContextData &gfx(m_gfx[QOpenGLContext::currentContext()]); + gfx.program = new QOpenGLShaderProgram; + gfx.program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); + gfx.program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram); + gfx.program->bindAttributeLocation("vertexCoordEntry", 0); + gfx.program->bindAttributeLocation("textureCoordEntry", 1); + gfx.program->link(); - m_textureEntry = m_program->uniformLocation("texture"); - m_matEntry = m_program->uniformLocation("mat"); + gfx.textureEntry = gfx.program->uniformLocation("texture"); + gfx.matEntry = gfx.program->uniformLocation("mat"); } void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image) @@ -214,7 +213,7 @@ void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window) Q_UNUSED(window); const QRect oldCursorRect = cursorRect(); if (setCurrentCursor(cursor)) - update(oldCursorRect | cursorRect()); + update(oldCursorRect | cursorRect(), false); } bool QEglFSCursor::setCurrentCursor(QCursor *cursor) @@ -238,16 +237,17 @@ bool QEglFSCursor::setCurrentCursor(QCursor *cursor) hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow), ws, hs); m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape]; - m_cursor.texture = m_cursorAtlas.texture; + m_cursor.useCustomCursor = false; m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight); } else { QImage image = cursor->pixmap().toImage(); m_cursor.textureRect = QRectF(0, 0, 1, 1); m_cursor.hotSpot = cursor->hotSpot(); - m_cursor.texture = 0; // will get updated in the next render() + m_cursor.useCustomCursor = false; // will get updated in the next render() m_cursor.size = image.size(); m_cursor.customCursorImage = image; m_cursor.customCursorPending = true; + m_cursor.customCursorKey = m_cursor.customCursorImage.cacheKey(); } return true; @@ -257,17 +257,20 @@ bool QEglFSCursor::setCurrentCursor(QCursor *cursor) class CursorUpdateEvent : public QEvent { public: - CursorUpdateEvent(const QPoint &pos, const QRegion &rgn) + CursorUpdateEvent(const QPoint &pos, const QRect &rect, bool allScreens) : QEvent(QEvent::Type(QEvent::User + 1)), m_pos(pos), - m_region(rgn) + m_rect(rect), + m_allScreens(allScreens) { } QPoint pos() const { return m_pos; } - QRegion region() const { return m_region; } + QRegion rect() const { return m_rect; } + bool allScreens() const { return m_allScreens; } private: QPoint m_pos; - QRegion m_region; + QRect m_rect; + bool m_allScreens; }; bool QEglFSCursor::event(QEvent *e) @@ -275,21 +278,30 @@ bool QEglFSCursor::event(QEvent *e) if (e->type() == QEvent::User + 1) { CursorUpdateEvent *ev = static_cast<CursorUpdateEvent *>(e); m_updateRequested = false; - QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(ev->pos()), ev->region()); - QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); + if (!ev->allScreens()) { + QWindow *w = m_screen->topLevelAt(ev->pos()); // works for the entire virtual desktop, no need to loop + if (w) { + QWindowSystemInterface::handleExposeEvent(w, ev->rect()); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); + } + } else { + for (QWindow *w : qGuiApp->topLevelWindows()) + QWindowSystemInterface::handleExposeEvent(w, w->geometry()); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); + } return true; } return QPlatformCursor::event(e); } -void QEglFSCursor::update(const QRegion &rgn) +void QEglFSCursor::update(const QRect &rect, bool allScreens) { if (!m_updateRequested) { // Must not flush the window system events directly from here since we are likely to // be a called directly from QGuiApplication's processMouseEvents. Flushing events // could cause reentering by dispatching more queued mouse events. m_updateRequested = true; - QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rgn)); + QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rect, allScreens)); } } @@ -308,8 +320,9 @@ void QEglFSCursor::setPos(const QPoint &pos) QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos); const QRect oldCursorRect = cursorRect(); m_cursor.pos = pos; - update(oldCursorRect | cursorRect()); - m_screen->handleCursorMove(m_cursor.pos); + update(oldCursorRect | cursorRect(), false); + for (QPlatformScreen *screen : m_screen->virtualSiblings()) + static_cast<QEglFSScreen *>(screen)->handleCursorMove(m_cursor.pos); } void QEglFSCursor::pointerEvent(const QMouseEvent &event) @@ -318,8 +331,9 @@ void QEglFSCursor::pointerEvent(const QMouseEvent &event) return; const QRect oldCursorRect = cursorRect(); m_cursor.pos = event.screenPos().toPoint(); - update(oldCursorRect | cursorRect()); - m_screen->handleCursorMove(m_cursor.pos); + update(oldCursorRect | cursorRect(), false); + for (QPlatformScreen *screen : m_screen->virtualSiblings()) + static_cast<QEglFSScreen *>(screen)->handleCursorMove(m_cursor.pos); } void QEglFSCursor::paintOnScreen() @@ -327,15 +341,35 @@ void QEglFSCursor::paintOnScreen() if (!m_visible) return; - const QRectF cr = cursorRect(); - const QRect screenRect(m_screen->geometry()); - const GLfloat x1 = 2 * (cr.left() / screenRect.width()) - 1; - const GLfloat x2 = 2 * (cr.right() / screenRect.width()) - 1; - const GLfloat y1 = 1 - (cr.top() / screenRect.height()) * 2; - const GLfloat y2 = 1 - (cr.bottom() / screenRect.height()) * 2; - QRectF r(QPointF(x1, y1), QPointF(x2, y2)); + QRect cr = cursorRect(); // hotspot included + + // Support virtual desktop too. Backends with multi-screen support (e.g. all + // variants of KMS/DRM) will enable this by default. In this case all + // screens are siblings of each other. When not enabled, the sibling list + // only contains m_screen itself. + for (QPlatformScreen *screen : m_screen->virtualSiblings()) { + if (screen->geometry().contains(cr.topLeft() + m_cursor.hotSpot) + && QOpenGLContext::currentContext()->screen() == screen->screen()) + { + cr.translate(-screen->geometry().topLeft()); + const QSize screenSize = screen->geometry().size(); + const GLfloat x1 = 2 * (cr.left() / GLfloat(screenSize.width())) - 1; + const GLfloat x2 = 2 * (cr.right() / GLfloat(screenSize.width())) - 1; + const GLfloat y1 = 1 - (cr.top() / GLfloat(screenSize.height())) * 2; + const GLfloat y2 = 1 - (cr.bottom() / GLfloat(screenSize.height())) * 2; + QRectF r(QPointF(x1, y1), QPointF(x2, y2)); + + draw(r); + + if (screen != m_activeScreen) { + m_activeScreen = screen; + // Do not want a leftover cursor on the screen the cursor just left. + update(cursorRect(), true); + } - draw(r); + break; + } + } } // In order to prevent breaking code doing custom OpenGL rendering while @@ -437,30 +471,33 @@ void QEglFSCursor::draw(const QRectF &r) { StateSaver stateSaver; - if (!m_program) { + GraphicsContextData &gfx(m_gfx[QOpenGLContext::currentContext()]); + if (!gfx.program) { // one time initialization initializeOpenGLFunctions(); createShaderPrograms(); - if (!m_cursorAtlas.texture) { - createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image); + if (!gfx.atlasTexture) { + createCursorTexture(&gfx.atlasTexture, m_cursorAtlas.image); if (m_cursor.shape != Qt::BitmapCursor) - m_cursor.texture = m_cursorAtlas.texture; + m_cursor.useCustomCursor = false; } } - if (m_cursor.shape == Qt::BitmapCursor && m_cursor.customCursorPending) { + if (m_cursor.shape == Qt::BitmapCursor && (m_cursor.customCursorPending || m_cursor.customCursorKey != gfx.customCursorKey)) { // upload the custom cursor - createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage); - m_cursor.texture = m_cursor.customCursorTexture; + createCursorTexture(&gfx.customCursorTexture, m_cursor.customCursorImage); + m_cursor.useCustomCursor = true; m_cursor.customCursorPending = false; + gfx.customCursorKey = m_cursor.customCursorKey; } - Q_ASSERT(m_cursor.texture); + GLuint cursorTexture = !m_cursor.useCustomCursor ? gfx.atlasTexture : gfx.customCursorTexture; + Q_ASSERT(cursorTexture); - m_program->bind(); + gfx.program->bind(); const GLfloat x1 = r.left(); const GLfloat x2 = r.right(); @@ -485,20 +522,20 @@ void QEglFSCursor::draw(const QRectF &r) }; glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_cursor.texture); + glBindTexture(GL_TEXTURE_2D, cursorTexture); if (stateSaver.vaoHelper->isValid()) stateSaver.vaoHelper->glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); - m_program->enableAttributeArray(0); - m_program->enableAttributeArray(1); - m_program->setAttributeArray(0, cursorCoordinates, 2); - m_program->setAttributeArray(1, textureCoordinates, 2); + gfx.program->enableAttributeArray(0); + gfx.program->enableAttributeArray(1); + gfx.program->setAttributeArray(0, cursorCoordinates, 2); + gfx.program->setAttributeArray(1, textureCoordinates, 2); - m_program->setUniformValue(m_textureEntry, 0); - m_program->setUniformValue(m_matEntry, m_rotationMatrix); + gfx.program->setUniformValue(gfx.textureEntry, 0); + gfx.program->setUniformValue(gfx.matEntry, m_rotationMatrix); glDisable(GL_CULL_FACE); glFrontFace(GL_CCW); @@ -508,9 +545,9 @@ void QEglFSCursor::draw(const QRectF &r) glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - m_program->disableAttributeArray(0); - m_program->disableAttributeArray(1); - m_program->release(); + gfx.program->disableAttributeArray(0); + gfx.program->disableAttributeArray(1); + gfx.program->release(); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h index f72e4c0374..8ccbe4493c 100644 --- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h @@ -105,30 +105,29 @@ private: bool setCurrentCursor(QCursor *cursor); #endif void draw(const QRectF &rect); - void update(const QRegion ®ion); + void update(const QRect &rect, bool allScreens); void createShaderPrograms(); void createCursorTexture(uint *texture, const QImage &image); void initCursorAtlas(); // current cursor information struct Cursor { - Cursor() : texture(0), shape(Qt::BlankCursor), customCursorTexture(0), customCursorPending(false) { } - uint texture; // a texture from 'image' or the atlas + Cursor() : shape(Qt::BlankCursor), customCursorPending(false), customCursorKey(0), useCustomCursor(false) { } Qt::CursorShape shape; QRectF textureRect; // normalized rect inside texture QSize size; // size of the cursor QPoint hotSpot; QImage customCursorImage; QPoint pos; // current cursor position - uint customCursorTexture; bool customCursorPending; + qint64 customCursorKey; + bool useCustomCursor; } m_cursor; // cursor atlas information struct CursorAtlas { - CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { } + CursorAtlas() : cursorsPerRow(0), cursorWidth(0), cursorHeight(0) { } int cursorsPerRow; - uint texture; int width, height; // width and height of the atlas int cursorWidth, cursorHeight; // width and height of cursors inside the atlas QList<QPoint> hotSpots; @@ -137,12 +136,22 @@ private: bool m_visible; QEglFSScreen *m_screen; - QOpenGLShaderProgram *m_program; - int m_textureEntry; - int m_matEntry; + QPlatformScreen *m_activeScreen; QEglFSCursorDeviceListener *m_deviceListener; bool m_updateRequested; QMatrix4x4 m_rotationMatrix; + + struct GraphicsContextData { + GraphicsContextData() : program(nullptr), textureEntry(0), matEntry(0), + customCursorTexture(0), atlasTexture(0), customCursorKey(0) { } + QOpenGLShaderProgram *program; + int textureEntry; + int matEntry; + uint customCursorTexture; + uint atlasTexture; + qint64 customCursorKey; + }; + QHash<QOpenGLContext *, GraphicsContextData> m_gfx; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp index 3848e99221..6f65929913 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp @@ -41,6 +41,7 @@ #include "qeglfsintegration.h" #include "qeglfscursor_p.h" #include "qeglfswindow_p.h" +#include "qeglfsscreen_p.h" #include "qeglfshooks_p.h" #include <QtPlatformSupport/private/qeglconvenience_p.h> @@ -311,7 +312,7 @@ bool QEglFSDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap QPlatformCursor *QEglFSDeviceIntegration::createCursor(QPlatformScreen *screen) const { - return new QEglFSCursor(screen); + return new QEglFSCursor(static_cast<QEglFSScreen *>(screen)); } void QEglFSDeviceIntegration::waitForVSync(QPlatformSurface *surface) const diff --git a/src/plugins/platforms/eglfs/api/qeglfsglobal.h b/src/plugins/platforms/eglfs/api/qeglfsglobal.h index 2b5effc2f1..655ab7eaef 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsglobal.h +++ b/src/plugins/platforms/eglfs/api/qeglfsglobal.h @@ -42,7 +42,7 @@ #include <QtCore/qglobal.h> -#include <EGL/egl.h> +#include <QtPlatformSupport/private/qt_egl_p.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp index 47ef2f64e7..b0c32e5176 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp @@ -65,7 +65,7 @@ QEglFSScreen::~QEglFSScreen() QRect QEglFSScreen::geometry() const { - QRect r = geometryForSurface(); + QRect r = rawGeometry(); static int rotation = qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION"); switch (rotation) { @@ -88,7 +88,7 @@ QRect QEglFSScreen::geometry() const return r; } -QRect QEglFSScreen::geometryForSurface() const +QRect QEglFSScreen::rawGeometry() const { return QRect(QPoint(0, 0), qt_egl_device_integration()->screenSize()); } diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h index 232525fae3..daba9fc591 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h @@ -68,7 +68,7 @@ public: ~QEglFSScreen(); QRect geometry() const Q_DECL_OVERRIDE; - QRect geometryForSurface() const; + virtual QRect rawGeometry() const; int depth() const Q_DECL_OVERRIDE; QImage::Format format() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp index 74723955c6..5ce88e6bd8 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp @@ -142,7 +142,7 @@ void QEglFSWindow::create() context->setScreen(window()->screen()); if (Q_UNLIKELY(!context->create())) qFatal("EGLFS: Failed to create compositing context"); - compositor->setTarget(context, window(), screen->geometryForSurface()); + compositor->setTarget(context, window(), screen->rawGeometry()); compositor->setRotation(qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION")); // If there is a "root" window into which raster and QOpenGLWidget content is // composited, all other contexts must share with its context. @@ -190,7 +190,7 @@ void QEglFSWindow::resetSurface() m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat); m_format = q_glFormatFromConfig(display, m_config, platformFormat); - const QSize surfaceSize = screen()->geometryForSurface().size(); + const QSize surfaceSize = screen()->rawGeometry().size(); m_window = qt_egl_device_integration()->createNativeWindow(this, surfaceSize, m_format); m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL); } diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index 769c248d0d..b46b04d149 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -1,12 +1,12 @@ TEMPLATE = subdirs -contains(QT_CONFIG, egl_x11): SUBDIRS += eglfs_x11 -contains(QT_CONFIG, eglfs_gbm): SUBDIRS += eglfs_kms_support eglfs_kms -contains(QT_CONFIG, eglfs_egldevice): SUBDIRS += eglfs_kms_support eglfs_kms_egldevice -contains(QT_CONFIG, eglfs_brcm): SUBDIRS += eglfs_brcm -contains(QT_CONFIG, eglfs_mali): SUBDIRS += eglfs_mali -contains(QT_CONFIG, eglfs_viv): SUBDIRS += eglfs_viv -contains(QT_CONFIG, eglfs_viv_wl): SUBDIRS += eglfs_viv_wl +qtConfig(egl_x11): SUBDIRS += eglfs_x11 +qtConfig(eglfs_gbm): SUBDIRS += eglfs_kms_support eglfs_kms +qtConfig(eglfs_egldevice): SUBDIRS += eglfs_kms_support eglfs_kms_egldevice +qtConfig(eglfs_brcm): SUBDIRS += eglfs_brcm +qtConfig(eglfs_mali): SUBDIRS += eglfs_mali +qtConfig(eglfs_viv): SUBDIRS += eglfs_viv +qtConfig(eglfs_viv_wl): SUBDIRS += eglfs_viv_wl eglfs_kms_egldevice.depends = eglfs_kms_support eglfs_kms.depends = eglfs_kms_support diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro index cd97c2c5a3..d65e136a96 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro @@ -8,8 +8,8 @@ CONFIG += egl LIBS += -lbcm_host QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 SOURCES += $$PWD/qeglfsbrcmmain.cpp \ $$PWD/qeglfsbrcmintegration.cpp diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp index 363fce2214..4e811a1dfe 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp @@ -93,9 +93,23 @@ void QEglFSBrcmIntegration::platformInit() bcm_host_init(); } +static int getDisplayId() +{ + // As defined in vc_dispmanx_types.h + // DISPMANX_ID_MAIN_LCD 0 + // DISPMANX_ID_AUX_LCD 1 + // DISPMANX_ID_HDMI 2 + // DISPMANX_ID_SDTV 3 + // DISPMANX_ID_FORCE_LCD 4 + // DISPMANX_ID_FORCE_TV 5 + // DISPMANX_ID_FORCE_OTHER 6 /* non-default display */ + static const int dispmanxId = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISPMANX_ID"); + return (dispmanxId >= 0 && dispmanxId <= 6) ? dispmanxId : 0; +} + EGLNativeDisplayType QEglFSBrcmIntegration::platformDisplay() const { - dispman_display = vc_dispmanx_display_open(0/* LCD */); + dispman_display = vc_dispmanx_display_open(getDisplayId()); return EGL_DEFAULT_DISPLAY; } @@ -107,7 +121,7 @@ void QEglFSBrcmIntegration::platformDestroy() QSize QEglFSBrcmIntegration::screenSize() const { uint32_t width, height; - graphics_get_display_size(0 /* LCD */, &width, &height); + graphics_get_display_size(getDisplayId(), &width, &height); return QSize(width, height); } 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 b0d631a9d1..70ff054172 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro @@ -8,16 +8,10 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS - -CONFIG += link_pkgconfig -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += libdrm gbm -} else { - LIBS += -ldrm -lgbm -} +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 +QMAKE_USE += gbm drm CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp index 278752bddf..99f6cfb0ca 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp @@ -142,10 +142,10 @@ void QEglFSKmsGbmDevice::handleDrmEvent() drmHandleEvent(fd(), &drmEvent); } -QEglFSKmsScreen *QEglFSKmsGbmDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) +QEglFSKmsScreen *QEglFSKmsGbmDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output) { static bool firstScreen = true; - QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(integration, device, output, position); + QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(integration, device, output); if (firstScreen && integration->hwCursor()) { m_globalCursor = new QEglFSKmsGbmCursor(screen); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h index 6a45f9ffa0..7c0af84422 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h @@ -68,8 +68,7 @@ public: virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position) Q_DECL_OVERRIDE; + QEglFSKmsOutput output) Q_DECL_OVERRIDE; private: Q_DISABLE_COPY(QEglFSKmsGbmDevice) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 7a17b60a5e..dde386fc57 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -93,10 +93,9 @@ QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject( } QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position) - : QEglFSKmsScreen(integration, device, output, position) + QEglFSKmsDevice *device, + QEglFSKmsOutput output) + : QEglFSKmsScreen(integration, device, output) , m_gbm_surface(Q_NULLPTR) , m_gbm_bo_current(Q_NULLPTR) , m_gbm_bo_next(Q_NULLPTR) @@ -130,8 +129,8 @@ gbm_surface *QEglFSKmsGbmScreen::createSurface() if (!m_gbm_surface) { qCDebug(qLcEglfsKmsDebug) << "Creating window for screen" << name(); m_gbm_surface = gbm_surface_create(static_cast<QEglFSKmsGbmDevice *>(device())->gbmDevice(), - geometry().width(), - geometry().height(), + rawGeometry().width(), + rawGeometry().height(), GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h index 3381bbfdbb..d7ad348291 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h @@ -55,9 +55,8 @@ class QEglFSKmsGbmScreen : public QEglFSKmsScreen { public: QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position); + QEglFSKmsDevice *device, + QEglFSKmsOutput output); ~QEglFSKmsGbmScreen(); QPlatformCursor *cursor() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro index 8eabd2d4b7..5f47b98369 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro @@ -4,15 +4,10 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support -DEFINES += MESA_EGL_NO_X11_HEADERS - -CONFIG += link_pkgconfig -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += libdrm -} else { - LIBS += -ldrm -} +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 +QMAKE_USE += drm CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF 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 743f714cf0..d30963ff96 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp @@ -40,11 +40,15 @@ #include "qeglfskmsegldevice.h" #include "qeglfskmsegldevicescreen.h" #include "qeglfskmsegldeviceintegration.h" +#include "private/qeglfscursor_p.h" #include <QtCore/private/qcore_unix_p.h> +QT_BEGIN_NAMESPACE + QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path) - : QEglFSKmsDevice(integration, path) + : QEglFSKmsDevice(integration, path), + m_globalCursor(nullptr) { } @@ -52,6 +56,8 @@ bool QEglFSKmsEglDevice::open() { Q_ASSERT(fd() == -1); + qCDebug(qLcEglfsKmsDebug, "Opening DRM device %s", qPrintable(devicePath())); + int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR); if (Q_UNLIKELY(fd < 0)) qFatal("Could not open DRM device"); @@ -63,6 +69,8 @@ bool QEglFSKmsEglDevice::open() void QEglFSKmsEglDevice::close() { + qCDebug(qLcEglfsKmsDebug, "Closing DRM device"); + if (qt_safe_close(fd()) == -1) qErrnoWarning("Could not close DRM device"); @@ -74,7 +82,26 @@ EGLNativeDisplayType QEglFSKmsEglDevice::nativeDisplay() const return static_cast<QEglFSKmsEglDeviceIntegration *>(m_integration)->eglDevice(); } -QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) +QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, + QEglFSKmsOutput output) { - return new QEglFSKmsEglDeviceScreen(integration, device, output, position); + QEglFSKmsScreen *screen = new QEglFSKmsEglDeviceScreen(integration, device, output); + + if (!m_globalCursor && !integration->separateScreens()) { + qCDebug(qLcEglfsKmsDebug, "Creating new global mouse cursor"); + m_globalCursor = new QEglFSCursor(screen); + } + + return screen; } + +void QEglFSKmsEglDevice::destroyGlobalCursor() +{ + if (m_globalCursor) { + qCDebug(qLcEglfsKmsDebug, "Destroying global mouse cursor"); + delete m_globalCursor; + m_globalCursor = nullptr; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h index b1c98f3fe6..8c8f79f70c 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h @@ -42,6 +42,10 @@ #include <qeglfskmsdevice.h> +QT_BEGIN_NAMESPACE + +class QPlatformCursor; + class QEglFSKmsEglDevice: public QEglFSKmsDevice { public: @@ -54,8 +58,15 @@ public: virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position) Q_DECL_OVERRIDE; + QEglFSKmsOutput output) Q_DECL_OVERRIDE; + + QPlatformCursor *globalCursor() { return m_globalCursor; } + void destroyGlobalCursor(); + +private: + QPlatformCursor *m_globalCursor; }; +QT_END_NAMESPACE + #endif // QEGLFSKMSEGLDEVICE_H 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 28967d71ff..ddb2499751 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -41,6 +41,7 @@ #include "qeglfskmsegldeviceintegration.h" #include <QtPlatformSupport/private/qeglconvenience_p.h> #include "private/qeglfswindow_p.h" +#include "private/qeglfscursor_p.h" #include "qeglfskmsegldevice.h" #include "qeglfskmsscreen.h" #include <QLoggingCategory> @@ -193,8 +194,8 @@ void QEglJetsonTK1Window::resetSurface() m_format = q_glFormatFromConfig(display, m_config); qCDebug(qLcEglfsKmsDebug) << "Stream producer format is" << m_format; - const int w = cur_screen->geometry().width(); - const int h = cur_screen->geometry().height(); + const int w = cur_screen->rawGeometry().width(); + const int h = cur_screen->rawGeometry().height(); qCDebug(qLcEglfsKmsDebug, "Creating stream producer surface of size %dx%d", w, h); const EGLint stream_producer_attribs[] = { @@ -222,11 +223,6 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const return eglWindow; } -bool QEglFSKmsEglDeviceIntegration::separateScreens() const -{ - return true; -} - QEglFSKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice(const QString &devicePath) { Q_UNUSED(devicePath) @@ -263,4 +259,9 @@ bool QEglFSKmsEglDeviceIntegration::query_egl_device() return true; } +QPlatformCursor *QEglFSKmsEglDeviceIntegration::createCursor(QPlatformScreen *screen) const +{ + return separateScreens() ? new QEglFSCursor(screen) : nullptr; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h index f04c42267a..375c388548 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h @@ -61,12 +61,11 @@ public: bool supportsPBuffers() const Q_DECL_OVERRIDE; QEglFSWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE; - virtual bool separateScreens() const Q_DECL_OVERRIDE; - EGLDeviceEXT eglDevice() const { return m_egl_device; } protected: QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE; + QPlatformCursor *createCursor(QPlatformScreen *screen) const Q_DECL_OVERRIDE; private: bool setup_kms(); 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 da1b577801..55d5941e5f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp @@ -39,10 +39,30 @@ #include "qeglfskmsegldevicescreen.h" #include "qeglfskmsegldevice.h" +#include <QGuiApplication> -QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) - : QEglFSKmsScreen(integration, device, output, position) +QT_BEGIN_NAMESPACE + +QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output) + : QEglFSKmsScreen(integration, device, output) +{ +} + +QEglFSKmsEglDeviceScreen::~QEglFSKmsEglDeviceScreen() { + const int remainingScreenCount = qGuiApp->screens().count(); + qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount); + if (!remainingScreenCount && !m_integration->separateScreens()) + static_cast<QEglFSKmsEglDevice *>(device())->destroyGlobalCursor(); +} + +QPlatformCursor *QEglFSKmsEglDeviceScreen::cursor() const +{ + // The base class creates a cursor via integration->createCursor() + // in its ctor. With separateScreens just use that. Otherwise + // there's a virtual desktop and the device has a global cursor + // and the base class has no dedicated cursor at all. + return m_integration->separateScreens() ? QEglFSScreen::cursor() : static_cast<QEglFSKmsEglDevice *>(device())->globalCursor(); } void QEglFSKmsEglDeviceScreen::waitForFlip() @@ -76,3 +96,5 @@ void QEglFSKmsEglDeviceScreen::waitForFlip() } } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h index 0cd46e9f9d..c57f52c6b7 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h @@ -42,15 +42,21 @@ #include <qeglfskmsscreen.h> +QT_BEGIN_NAMESPACE + class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen { public: QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position); + QEglFSKmsOutput output); + ~QEglFSKmsEglDeviceScreen(); + + QPlatformCursor *cursor() const Q_DECL_OVERRIDE; void waitForFlip() Q_DECL_OVERRIDE; }; +QT_END_NAMESPACE + #endif // QEGLFSKMSEGLDEVICESCREEN_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro index 6dd857a4e4..464c64539f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro @@ -6,16 +6,10 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr INCLUDEPATH += $$PWD/../.. -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS - -CONFIG += link_pkgconfig -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += libdrm -} else { - LIBS += -ldrm -} +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 +QMAKE_USE += drm CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp index f4ffee569d..5944e8d51f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp @@ -159,7 +159,7 @@ static bool parseModeline(const QByteArray &text, drmModeModeInfoPtr mode) return true; } -QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos) +QEglFSKmsScreen *QEglFSKmsDevice::createScreenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, int *virtualIndex) { const QByteArray connectorName = nameForConnector(connector); @@ -173,8 +173,11 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr QSize configurationSize; drmModeModeInfo configurationModeline; - const QByteArray mode = m_integration->outputSettings().value(QString::fromUtf8(connectorName)) - .value(QStringLiteral("mode"), QStringLiteral("preferred")).toByteArray().toLower(); + auto userConfig = m_integration->outputSettings(); + auto userConnectorConfig = userConfig.value(QString::fromUtf8(connectorName)); + // default to the preferred mode unless overridden in the config + const QByteArray mode = userConnectorConfig.value(QStringLiteral("mode"), QStringLiteral("preferred")) + .toByteArray().toLower(); if (mode == "off") { configuration = OutputConfigOff; } else if (mode == "preferred") { @@ -189,6 +192,8 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr qWarning("Invalid mode \"%s\" for output %s", mode.constData(), connectorName.constData()); configuration = OutputConfigPreferred; } + if (virtualIndex) + *virtualIndex = userConnectorConfig.value(QStringLiteral("virtualIndex"), INT_MAX).toInt(); const uint32_t crtc_id = resources->crtcs[crtc]; @@ -287,18 +292,26 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr qCDebug(qLcEglfsKmsDebug) << "Selected mode" << selected_mode << ":" << width << "x" << height << '@' << refresh << "hz for output" << connectorName; } + + // physical size from connector < config values < env vars static const int width = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH"); static const int height = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT"); - QSizeF size(width, height); - if (size.isEmpty()) { - size.setWidth(connector->mmWidth); - size.setHeight(connector->mmHeight); + QSizeF physSize(width, height); + if (physSize.isEmpty()) { + physSize = QSize(userConnectorConfig.value(QStringLiteral("physicalWidth")).toInt(), + userConnectorConfig.value(QStringLiteral("physicalHeight")).toInt()); + if (physSize.isEmpty()) { + physSize.setWidth(connector->mmWidth); + physSize.setHeight(connector->mmHeight); + } } + qCDebug(qLcEglfsKmsDebug) << "Physical size is" << physSize << "mm" << "for output" << connectorName; + QEglFSKmsOutput output = { QString::fromUtf8(connectorName), connector->connector_id, crtc_id, - size, + physSize, selected_mode, false, drmModeGetCrtc(m_dri_fd, crtc_id), @@ -310,7 +323,7 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr m_crtc_allocator |= (1 << output.crtc_id); m_connector_allocator |= (1 << output.connector_id); - return createScreen(m_integration, this, output, pos); + return createScreen(m_integration, this, output); } drmModePropertyPtr QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name) @@ -342,6 +355,26 @@ QEglFSKmsDevice::~QEglFSKmsDevice() { } +struct OrderedScreen +{ + OrderedScreen() : screen(nullptr), index(-1) { } + OrderedScreen(QEglFSKmsScreen *screen, int index) : screen(screen), index(index) { } + QEglFSKmsScreen *screen; + int index; +}; + +QDebug operator<<(QDebug dbg, const OrderedScreen &s) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "OrderedScreen(" << s.screen << " : " << s.index << ")"; + return dbg; +} + +static bool orderedScreenLessThan(const OrderedScreen &a, const OrderedScreen &b) +{ + return a.index < b.index; +} + void QEglFSKmsDevice::createScreens() { drmModeResPtr resources = drmModeGetResources(m_dri_fd); @@ -350,32 +383,49 @@ void QEglFSKmsDevice::createScreens() return; } - QEglFSKmsScreen *primaryScreen = Q_NULLPTR; - QList<QPlatformScreen *> siblings; - QPoint pos(0, 0); - QEglFSIntegration *integration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QVector<OrderedScreen> screens; for (int i = 0; i < resources->count_connectors; i++) { drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]); if (!connector) continue; - QEglFSKmsScreen *screen = screenForConnector(resources, connector, pos); - if (screen) { - integration->addScreen(screen); - pos.rx() += screen->geometry().width(); - siblings << screen; - - if (!primaryScreen) - primaryScreen = screen; - } + int virtualIndex; + QEglFSKmsScreen *screen = createScreenForConnector(resources, connector, &virtualIndex); + if (screen) + screens.append(OrderedScreen(screen, virtualIndex)); drmModeFreeConnector(connector); } drmModeFreeResources(resources); + // Use stable sort to preserve the original order for outputs with unspecified indices. + std::stable_sort(screens.begin(), screens.end(), orderedScreenLessThan); + qCDebug(qLcEglfsKmsDebug) << "Sorted screen list:" << screens; + + QPoint pos(0, 0); + QList<QPlatformScreen *> siblings; + QEglFSIntegration *qpaIntegration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration()); + + for (const OrderedScreen &orderedScreen : screens) { + QEglFSKmsScreen *s = orderedScreen.screen; + // set up a horizontal or vertical virtual desktop + s->setVirtualPosition(pos); + if (m_integration->virtualDesktopLayout() == QEglFSKmsIntegration::VirtualDesktopLayoutVertical) + pos.ry() += s->geometry().height(); + else + pos.rx() += s->geometry().width(); + qCDebug(qLcEglfsKmsDebug) << "Adding screen" << s << "to QPA with geometry" << s->geometry(); + // The order in qguiapp's screens list will match the order set by + // virtualIndex. This is not only handy but also required since for instance + // evdevtouch relies on it when performing touch device - screen mapping. + qpaIntegration->addScreen(s); + siblings << s; + } + if (!m_integration->separateScreens()) { + // enable the virtual desktop Q_FOREACH (QPlatformScreen *screen, siblings) static_cast<QEglFSKmsScreen *>(screen)->setVirtualSiblings(siblings); } @@ -391,9 +441,9 @@ QString QEglFSKmsDevice::devicePath() const return m_path; } -QEglFSKmsScreen *QEglFSKmsDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) +QEglFSKmsScreen *QEglFSKmsDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output) { - return new QEglFSKmsScreen(integration, device, output, position); + return new QEglFSKmsScreen(integration, device, output); } void QEglFSKmsDevice::setFd(int fd) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h index 041c063695..4aad2e0143 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h @@ -68,8 +68,7 @@ public: protected: virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position); + QEglFSKmsOutput output); void setFd(int fd); QEglFSKmsIntegration *m_integration; @@ -80,7 +79,7 @@ protected: quint32 m_connector_allocator; int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); - QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos); + QEglFSKmsScreen *createScreenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, int *virtualIndex); drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name); static void pageFlipHandler(int fd, 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 7389050efc..6c30e8f930 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp @@ -65,6 +65,7 @@ QEglFSKmsIntegration::QEglFSKmsIntegration() , m_hwCursor(false) , m_pbuffers(false) , m_separateScreens(false) + , m_virtualDesktopLayout(VirtualDesktopLayoutHorizontal) {} void QEglFSKmsIntegration::platformInit() @@ -149,6 +150,11 @@ bool QEglFSKmsIntegration::separateScreens() const return m_separateScreens; } +QEglFSKmsIntegration::VirtualDesktopLayout QEglFSKmsIntegration::virtualDesktopLayout() const +{ + return m_virtualDesktopLayout; +} + QMap<QString, QVariantMap> QEglFSKmsIntegration::outputSettings() const { return m_outputSettings; @@ -169,15 +175,15 @@ void QEglFSKmsIntegration::loadConfig() QFile file(QString::fromUtf8(json)); if (!file.open(QFile::ReadOnly)) { - qCDebug(qLcEglfsKmsDebug) << "Could not open config file" - << json << "for reading"; + qCWarning(qLcEglfsKmsDebug) << "Could not open config file" + << json << "for reading"; return; } const QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); if (!doc.isObject()) { - qCDebug(qLcEglfsKmsDebug) << "Invalid config file" << json - << "- no top-level JSON object"; + qCWarning(qLcEglfsKmsDebug) << "Invalid config file" << json + << "- no top-level JSON object"; return; } @@ -188,6 +194,16 @@ void QEglFSKmsIntegration::loadConfig() m_devicePath = object.value(QLatin1String("device")).toString(); m_separateScreens = object.value(QLatin1String("separateScreens")).toBool(m_separateScreens); + const QString vdOriString = object.value(QLatin1String("virtualDesktopLayout")).toString(); + if (!vdOriString.isEmpty()) { + if (vdOriString == QLatin1String("horizontal")) + m_virtualDesktopLayout = VirtualDesktopLayoutHorizontal; + else if (vdOriString == QLatin1String("vertical")) + m_virtualDesktopLayout = VirtualDesktopLayoutVertical; + else + qCWarning(qLcEglfsKmsDebug) << "Unknown virtualDesktopOrientation value" << vdOriString; + } + const QJsonArray outputs = object.value(QLatin1String("outputs")).toArray(); for (int i = 0; i < outputs.size(); i++) { const QVariantMap outputSettings = outputs.at(i).toObject().toVariantMap(); @@ -207,6 +223,7 @@ void QEglFSKmsIntegration::loadConfig() << "\thwcursor:" << m_hwCursor << "\n" << "\tpbuffers:" << m_pbuffers << "\n" << "\tseparateScreens:" << m_separateScreens << "\n" + << "\tvirtualDesktopLayout:" << m_virtualDesktopLayout << "\n" << "\toutputs:" << m_outputSettings; } 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 81386881ff..ba49945715 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h @@ -56,6 +56,11 @@ Q_EGLFS_EXPORT Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) class Q_EGLFS_EXPORT QEglFSKmsIntegration : public QEglFSDeviceIntegration { public: + enum VirtualDesktopLayout { + VirtualDesktopLayoutHorizontal, + VirtualDesktopLayoutVertical + }; + QEglFSKmsIntegration(); void platformInit() Q_DECL_OVERRIDE; @@ -70,6 +75,7 @@ public: virtual bool hwCursor() const; virtual bool separateScreens() const; + virtual VirtualDesktopLayout virtualDesktopLayout() const; QMap<QString, QVariantMap> outputSettings() const; QEglFSKmsDevice *device() const; @@ -83,6 +89,7 @@ protected: bool m_hwCursor; bool m_pbuffers; bool m_separateScreens; + VirtualDesktopLayout m_virtualDesktopLayout; QString m_devicePath; QMap<QString, QVariantMap> m_outputSettings; }; 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 e6b256f6b2..f690cd668e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp @@ -71,17 +71,15 @@ private: QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position) + QEglFSKmsOutput output) : QEglFSScreen(eglGetDisplay(device->nativeDisplay())) , m_integration(integration) , m_device(device) , m_output(output) - , m_pos(position) , m_powerState(PowerStateOn) , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) { - m_siblings << this; + m_siblings << this; // gets overridden by QEglFSKmsDevice later if !separateScreens } QEglFSKmsScreen::~QEglFSKmsScreen() @@ -98,7 +96,14 @@ QEglFSKmsScreen::~QEglFSKmsScreen() delete m_interruptHandler; } -QRect QEglFSKmsScreen::geometry() const +void QEglFSKmsScreen::setVirtualPosition(const QPoint &pos) +{ + m_pos = pos; +} + +// Reimplement rawGeometry(), not geometry(). The base class implementation of +// geometry() calls rawGeometry() and may apply additional transforms. +QRect QEglFSKmsScreen::rawGeometry() const { const int mode = m_output.mode; return QRect(m_pos.x(), m_pos.y(), 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 9679f70260..2b6a0ffe6c 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h @@ -74,11 +74,13 @@ class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen public: QEglFSKmsScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position); + QEglFSKmsOutput output); ~QEglFSKmsScreen(); - QRect geometry() const Q_DECL_OVERRIDE; + void setVirtualPosition(const QPoint &pos); + + QRect rawGeometry() const Q_DECL_OVERRIDE; + int depth() const Q_DECL_OVERRIDE; QImage::Format format() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro index 1e58b5fdcd..6e32ca26d0 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro @@ -2,8 +2,8 @@ TARGET = qeglfs-mali-integration QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 INCLUDEPATH += $$PWD/../.. CONFIG += egl diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro index a53aac2041..16880535e3 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro @@ -5,7 +5,6 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr INCLUDEPATH += $$PWD/../.. CONFIG += egl DEFINES += LINUX=1 EGL_API_FB=1 -LIBS += -lGAL QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF SOURCES += $$PWD/qeglfsvivmain.cpp \ diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro index 38259f4a5d..374c5bba6b 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro @@ -5,7 +5,6 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr INCLUDEPATH += $$PWD/../.. CONFIG += egl DEFINES += LINUX=1 EGL_API_FB=1 -LIBS += -lGAL QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF SOURCES += $$PWD/qeglfsvivwlmain.cpp \ diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro index 21af6eb736..10af57e487 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro @@ -2,13 +2,13 @@ TARGET = qeglfs-x11-integration QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 INCLUDEPATH += $$PWD/../.. CONFIG += egl -LIBS += -lX11 -lX11-xcb -lxcb +QMAKE_USE += xcb_xlib QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF SOURCES += $$PWD/qeglfsx11main.cpp \ diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp index 74a687b382..f9924fe5ce 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp @@ -281,12 +281,12 @@ EGLNativeWindowType QEglFSX11Integration::createNativeWindow(QPlatformWindow *pl xcb_flush(m_connection); - return m_window; + return qt_egl_cast<EGLNativeWindowType>(m_window); } void QEglFSX11Integration::destroyNativeWindow(EGLNativeWindowType window) { - xcb_destroy_window(m_connection, window); + xcb_destroy_window(m_connection, qt_egl_cast<xcb_window_t>(window)); } bool QEglFSX11Integration::hasCapability(QPlatformIntegration::Capability cap) const diff --git a/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro b/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro index 05f4196728..eb0ce73118 100644 --- a/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro +++ b/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro @@ -10,8 +10,8 @@ MODULE = eglfsdeviceintegration QT += core-private gui-private platformsupport-private LIBS += $$QMAKE_LIBS_DYNLOAD -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 DEFINES += QT_BUILD_EGL_DEVICE_LIB diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 8c8ef99bc2..418ff6119b 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -70,17 +70,17 @@ #include <QtPlatformHeaders/QEGLNativeContext> -#ifndef QT_NO_LIBINPUT +#if QT_CONFIG(libinput) #include <QtPlatformSupport/private/qlibinputhandler_p.h> #endif -#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(evdev) #include <QtPlatformSupport/private/qevdevmousemanager_p.h> #include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h> #include <QtPlatformSupport/private/qevdevtouchmanager_p.h> #endif -#if !defined(QT_NO_TSLIB) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(tslib) #include <QtPlatformSupport/private/qtslib_p.h> #endif @@ -386,7 +386,7 @@ QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::na QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function) const { -#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(evdev) if (function == QEglFSFunctions::loadKeymapTypeIdentifier()) return QFunctionPointer(loadKeymapStatic); #else @@ -398,7 +398,7 @@ QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function) void QEglFSIntegration::loadKeymapStatic(const QString &filename) { -#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(evdev) QEglFSIntegration *self = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration()); if (self->m_kbdMgr) self->m_kbdMgr->loadKeymap(filename); @@ -411,22 +411,22 @@ void QEglFSIntegration::loadKeymapStatic(const QString &filename) void QEglFSIntegration::createInputHandlers() { -#ifndef QT_NO_LIBINPUT +#if QT_CONFIG(libinput) if (!qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT")) { new QLibInputHandler(QLatin1String("libinput"), QString()); return; } #endif -#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(evdev) m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); -#ifndef QT_NO_TSLIB +#if QT_CONFIG(tslib) const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB"); if (useTslib) new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */); else -#endif // QT_NO_TSLIB +#endif new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); #endif } diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp index 685f231756..707301487d 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp @@ -52,17 +52,17 @@ #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatforminputcontextfactory_p.h> -#ifndef QT_NO_LIBINPUT +#if QT_CONFIG(libinput) #include <QtPlatformSupport/private/qlibinputhandler_p.h> #endif -#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(evdev) && !defined(Q_OS_ANDROID) #include <QtPlatformSupport/private/qevdevmousemanager_p.h> #include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h> #include <QtPlatformSupport/private/qevdevtouchmanager_p.h> #endif -#if !defined(QT_NO_TSLIB) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(tslib) && !defined(Q_OS_ANDROID) #include <QtPlatformSupport/private/qtslib_p.h> #endif @@ -140,22 +140,22 @@ QPlatformServices *QLinuxFbIntegration::services() const void QLinuxFbIntegration::createInputHandlers() { -#ifndef QT_NO_LIBINPUT +#if QT_CONFIG(libinput) if (!qEnvironmentVariableIntValue("QT_QPA_FB_NO_LIBINPUT")) { new QLibInputHandler(QLatin1String("libinput"), QString()); return; } #endif -#if !defined(QT_NO_EVDEV) && !defined(Q_OS_ANDROID) +#if QT_CONFIG(evdev) && !defined(Q_OS_ANDROID) new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this); new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString(), this); -#ifndef QT_NO_TSLIB +#if QT_CONFIG(tslib) const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_FB_TSLIB"); if (useTslib) new QTsLibMouseHandler(QLatin1String("TsLib"), QString()); else -#endif // QT_NO_TSLIB +#endif new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); #endif } diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro index 3aca27b555..0d31d6605b 100644 --- a/src/plugins/platforms/minimal/minimal.pro +++ b/src/plugins/platforms/minimal/minimal.pro @@ -11,7 +11,6 @@ HEADERS = qminimalintegration.h \ OTHER_FILES += minimal.json CONFIG += qpa/genericunixfontdatabase -win32|darwin: DEFINES += QT_NO_FONTCONFIG PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QMinimalIntegrationPlugin diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp index 7224f4114c..984d4456a0 100644 --- a/src/plugins/platforms/minimal/qminimalintegration.cpp +++ b/src/plugins/platforms/minimal/qminimalintegration.cpp @@ -46,10 +46,10 @@ #if defined(Q_OS_WIN) #include <QtPlatformSupport/private/qbasicfontdatabase_p.h> -#elif defined(QT_NO_FONTCONFIG) -#include <qpa/qplatformfontdatabase.h> -#else +#elif QT_CONFIG(fontconfig) #include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h> +#else +#include <qpa/qplatformfontdatabase.h> #endif #if !defined(Q_OS_WIN) @@ -118,7 +118,7 @@ public: QPlatformFontDatabase *QMinimalIntegration::fontDatabase() const { if (m_options & EnableFonts) { -#ifndef QT_NO_FONTCONFIG +#if QT_CONFIG(fontconfig) if (!m_fontDatabase) m_fontDatabase = new QGenericUnixFontDatabase; #else diff --git a/src/plugins/platforms/minimalegl/minimalegl.pro b/src/plugins/platforms/minimalegl/minimalegl.pro index ac67249591..b8a91729fd 100644 --- a/src/plugins/platforms/minimalegl/minimalegl.pro +++ b/src/plugins/platforms/minimalegl/minimalegl.pro @@ -6,8 +6,8 @@ QT += core-private gui-private platformsupport-private #DEFINES += Q_OPENKODE -#Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 SOURCES = main.cpp \ qminimaleglintegration.cpp \ diff --git a/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp b/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp index cf31eec75f..b1d3691a10 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp +++ b/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp @@ -58,7 +58,7 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QScreen> -#include <EGL/egl.h> +#include <QtPlatformSupport/private/qt_egl_p.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/minimalegl/qminimaleglscreen.h b/src/plugins/platforms/minimalegl/qminimaleglscreen.h index 825d5e8541..4b53bbd39a 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglscreen.h +++ b/src/plugins/platforms/minimalegl/qminimaleglscreen.h @@ -44,7 +44,7 @@ #include <QtCore/QTextStream> -#include <EGL/egl.h> +#include <QtPlatformSupport/private/qt_egl_p.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/offscreen/offscreen.pro b/src/plugins/platforms/offscreen/offscreen.pro index 999550a7e1..cc65449b04 100644 --- a/src/plugins/platforms/offscreen/offscreen.pro +++ b/src/plugins/platforms/offscreen/offscreen.pro @@ -13,7 +13,7 @@ HEADERS = qoffscreenintegration.h \ OTHER_FILES += offscreen.json -contains(QT_CONFIG, xlib):contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2) { +qtConfig(xlib):qtConfig(opengl):!qtConfig(opengles2) { SOURCES += qoffscreenintegration_x11.cpp HEADERS += qoffscreenintegration_x11.h system(echo "Using X11 offscreen integration with GLX") diff --git a/src/plugins/platforms/openwfd/openwf.pro b/src/plugins/platforms/openwfd/openwf.pro index 152e4f57d7..79f349f472 100644 --- a/src/plugins/platforms/openwfd/openwf.pro +++ b/src/plugins/platforms/openwfd/openwf.pro @@ -31,7 +31,8 @@ SOURCES += \ qopenwfdportmode.cpp \ qopenwfdwindow.cpp -LIBS += -lWFD -lgbm -lGLESv2 -lEGL +LIBS += -lWFD +QMAKE_USE += gbm opengl_es2 egl PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QOpenWFDIntegrationPlugin diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 4bed5312ec..fcfebf6e94 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -4,19 +4,19 @@ android: SUBDIRS += android !android: SUBDIRS += minimal -!android:if(!win32|contains(QT_CONFIG, freetype)): SUBDIRS += offscreen +!android:if(!win32|qtConfig(freetype)): SUBDIRS += offscreen -contains(QT_CONFIG, xcb) { +qtConfig(xcb) { SUBDIRS += xcb } -uikit: SUBDIRS += ios +uikit:!watchos: SUBDIRS += ios osx: SUBDIRS += cocoa win32:!winrt: SUBDIRS += windows winrt: SUBDIRS += winrt -contains(QT_CONFIG, direct2d) { +qtConfig(direct2d) { SUBDIRS += direct2d } @@ -24,16 +24,16 @@ qnx { SUBDIRS += qnx } -contains(QT_CONFIG, eglfs) { +qtConfig(eglfs) { SUBDIRS += eglfs SUBDIRS += minimalegl } -contains(QT_CONFIG, directfb) { +qtConfig(directfb) { SUBDIRS += directfb } -contains(QT_CONFIG, linuxfb): SUBDIRS += linuxfb +qtConfig(linuxfb): SUBDIRS += linuxfb unix:!android:!darwin: SUBDIRS += vnc @@ -45,6 +45,6 @@ haiku { SUBDIRS += haiku } -contains(QT_CONFIG, mirclient): SUBDIRS += mirclient +qtConfig(mirclient): SUBDIRS += mirclient -contains(QT_CONFIG, integrityfb): SUBDIRS += integrity +qtConfig(integrityfb): SUBDIRS += integrity diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 5a0f4f5c98..e47731476f 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -75,14 +75,14 @@ CONFIG(qqnx_screeneventthread) { LIBS += -lscreen -contains(QT_CONFIG, opengles2) { +qtConfig(opengles2) { SOURCES += qqnxglcontext.cpp \ qqnxeglwindow.cpp HEADERS += qqnxglcontext.h \ qqnxeglwindow.h - LIBS += -lEGL + QMAKE_USE += egl } CONFIG(qqnx_pps) { @@ -100,7 +100,7 @@ CONFIG(qqnx_pps) { qqnxnavigatoreventnotifier.h \ qqnxvirtualkeyboardpps.h - LIBS += -lpps + QMAKE_USE += pps !contains(DEFINES, QT_NO_CLIPBOARD): LIBS += -lclipboard CONFIG(qqnx_imf) { @@ -116,7 +116,7 @@ CONFIG(qqnx_pps) { lgmon { DEFINES += QQNX_LGMON SOURCES += qqnxlgmon.cpp - LIBS += -llgmon + QMAKE_USE += lgmon } OTHER_FILES += qnx.json diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index 678e83cd57..f8ae5121d1 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -385,10 +385,8 @@ Qt::ScreenOrientation QQnxScreen::orientation() const QWindow *QQnxScreen::topLevelAt(const QPoint &point) const { - QListIterator<QQnxWindow*> it(m_childWindows); - it.toBack(); - while (it.hasPrevious()) { - QWindow *win = it.previous()->window(); + for (auto it = m_childWindows.rbegin(), end = m_childWindows.rend(); it != end; ++it) { + QWindow *win = (*it)->window(); if (win->geometry().contains(point)) return win; } diff --git a/src/plugins/platforms/vnc/qvncintegration.cpp b/src/plugins/platforms/vnc/qvncintegration.cpp index 810c5d2a90..3227478ebe 100644 --- a/src/plugins/platforms/vnc/qvncintegration.cpp +++ b/src/plugins/platforms/vnc/qvncintegration.cpp @@ -49,7 +49,7 @@ #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatforminputcontextfactory_p.h> #include <private/qinputdevicemanager_p_p.h> -#ifndef QT_NO_LIBINPUT +#if QT_CONFIG(libinput) #include <QtPlatformSupport/private/qlibinputhandler_p.h> #endif diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 6f236aa588..e87064e385 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -40,6 +40,7 @@ #include "qwindowsfontdatabase.h" #include "qwindowsfontdatabase_ft.h" // for default font #include "qwindowscontext.h" +#include "qwindowsintegration.h" #include "qwindowsfontengine.h" #include "qwindowsfontenginedirectwrite.h" #include <QtCore/qt_windows.h> @@ -108,6 +109,18 @@ static void createDirectWriteFactory(IDWriteFactory **factory) *factory = static_cast<IDWriteFactory *>(result); } + +static inline bool useDirectWrite(QFont::HintingPreference hintingPreference, bool isColorFont = false) +{ + const unsigned options = QWindowsIntegration::instance()->options(); + if (Q_UNLIKELY(options & QWindowsIntegration::DontUseDirectWriteFonts)) + return false; + if (isColorFont) + return (options & QWindowsIntegration::DontUseColorFonts) == 0; + return hintingPreference == QFont::PreferNoHinting + || hintingPreference == QFont::PreferVerticalHinting + || (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting); +} #endif // !QT_NO_DIRECTWRITE // Helper classes for creating font engines directly from font data @@ -1200,11 +1213,7 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal QFontEngine *fontEngine = 0; #if !defined(QT_NO_DIRECTWRITE) - bool useDirectWrite = (hintingPreference == QFont::PreferNoHinting) - || (hintingPreference == QFont::PreferVerticalHinting) - || (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting); - - if (!useDirectWrite) + if (!useDirectWrite(hintingPreference)) #endif { GUID guid; @@ -1840,15 +1849,16 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, if (SUCCEEDED(directWriteFontFace->QueryInterface(__uuidof(IDWriteFontFace2), reinterpret_cast<void **>(&directWriteFontFace2)))) { if (directWriteFontFace2->IsColorFont()) - isColorFont = true; + isColorFont = directWriteFontFace2->GetPaletteEntryCount() > 0; } #endif - - bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting) - || (request.hintingPreference == QFont::PreferVerticalHinting) - || (QHighDpiScaling::isActive() && request.hintingPreference == QFont::PreferDefaultHinting) - || isColorFont; - if (useDirectWrite) { + const QFont::HintingPreference hintingPreference = + static_cast<QFont::HintingPreference>(request.hintingPreference); + const bool useDw = useDirectWrite(hintingPreference, isColorFont); + qCDebug(lcQpaFonts) << __FUNCTION__ << request.family << request.pointSize + << "pt" << "hintingPreference=" << hintingPreference << "color=" << isColorFont + << dpi << "dpi" << "useDirectWrite=" << useDw; + if (useDw) { QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace, request.pixelSize, data); diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 90aa3fef16..b9a63c7a89 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -192,6 +192,10 @@ static inline unsigned parseOptions(const QStringList ¶mList, } } else if (param == QLatin1String("gl=gdi")) { options |= QWindowsIntegration::DisableArb; + } else if (param == QLatin1String("nodirectwrite")) { + options |= QWindowsIntegration::DontUseDirectWriteFonts; + } else if (param == QLatin1String("nocolorfonts")) { + options |= QWindowsIntegration::DontUseColorFonts; } else if (param == QLatin1String("nomousefromtouch")) { options |= QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch; } else if (parseIntOption(param, QLatin1String("verbose"), 0, INT_MAX, &QWindowsContext::verbose) @@ -304,7 +308,7 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons if (window->type() == Qt::ForeignWindow) { const HWND hwnd = reinterpret_cast<HWND>(window->winId()); if (!IsWindow(hwnd)) { - qWarning("Windows QPA: Invalid foreign window ID %p."); + qWarning("Windows QPA: Invalid foreign window ID %p.", hwnd); return nullptr; } QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd); diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index 437253cedc..4258f908e7 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -60,7 +60,9 @@ public: DisableArb = 0x4, NoNativeDialogs = 0x8, XpNativeDialogs = 0x10, - DontPassOsMouseEventsSynthesizedFromTouch = 0x20 // Do not pass OS-generated mouse events from touch. + DontPassOsMouseEventsSynthesizedFromTouch = 0x20, // Do not pass OS-generated mouse events from touch. + DontUseDirectWriteFonts = 0x40, + DontUseColorFonts = 0x80 }; explicit QWindowsIntegration(const QStringList ¶mList); diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 8d6e83298e..79b5bbae41 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -43,6 +43,7 @@ #include "qwindowswindow.h" #include "qwindowsinputcontext.h" +#include <QtGui/QGuiApplication> #include <QtGui/QWindow> #include <qpa/qwindowsysteminterface.h> #include <private/qguiapplication_p.h> @@ -1048,6 +1049,21 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) { // Found a ?_CHAR uch = QChar(ushort(wm_char.wParam)); + if (uch.isHighSurrogate()) { + m_lastHighSurrogate = uch; + return true; + } else if (uch.isLowSurrogate() && !m_lastHighSurrogate.isNull()) { + if (QObject *focusObject = QGuiApplication::focusObject()) { + const QChar chars[2] = {m_lastHighSurrogate, uch}; + QInputMethodEvent event; + event.setCommitString(QString(chars, 2)); + QCoreApplication::sendEvent(focusObject, &event); + } + m_lastHighSurrogate = QChar(); + return true; + } else { + m_lastHighSurrogate = QChar(); + } if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN)) uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter if (!code && !uch.row()) diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h index 069f78197e..2657644780 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.h +++ b/src/plugins/platforms/windows/qwindowskeymapper.h @@ -103,6 +103,7 @@ private: void deleteLayouts(); QWindow *m_keyGrabber; + QChar m_lastHighSurrogate; static const size_t NumKeyboardLayoutItems = 256; KeyboardLayoutItem keyLayout[NumKeyboardLayoutItems]; }; diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 1cadcd1954..6929f7365f 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -1,7 +1,7 @@ # Note: OpenGL32 must precede Gdi32 as it overwrites some functions. LIBS += -lole32 -luser32 -lwinspool -limm32 -lwinmm -loleaut32 -contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):!contains(QT_CONFIG, dynamicgl): LIBS *= -lopengl32 +qtConfig(opengl):!qtConfig(opengles2):!qtConfig(dynamicgl): LIBS *= -lopengl32 mingw: LIBS *= -luuid # For the dialog helpers: @@ -9,8 +9,8 @@ LIBS += -lshlwapi -lshell32 -ladvapi32 DEFINES *= QT_NO_CAST_FROM_ASCII -contains(QT_CONFIG, directwrite) { - contains(QT_CONFIG, directwrite2): \ +qtConfig(directwrite) { + qtConfig(directwrite2): \ DEFINES *= QT_USE_DIRECTWRITE2 SOURCES += $$PWD/qwindowsfontenginedirectwrite.cpp @@ -65,18 +65,18 @@ HEADERS += \ INCLUDEPATH += $$PWD -contains(QT_CONFIG,opengl): HEADERS += $$PWD/qwindowsopenglcontext.h +qtConfig(opengl): HEADERS += $$PWD/qwindowsopenglcontext.h -contains(QT_CONFIG, opengles2) { +qtConfig(opengles2) { SOURCES += $$PWD/qwindowseglcontext.cpp HEADERS += $$PWD/qwindowseglcontext.h -} else: contains(QT_CONFIG,opengl) { +} else: qtConfig(opengl) { SOURCES += $$PWD/qwindowsglcontext.cpp HEADERS += $$PWD/qwindowsglcontext.h } # Dynamic GL needs both WGL and EGL -contains(QT_CONFIG,dynamicgl) { +qtConfig(dynamicgl) { SOURCES += $$PWD/qwindowseglcontext.cpp HEADERS += $$PWD/qwindowseglcontext.h } @@ -111,18 +111,17 @@ contains(QT_CONFIG,dynamicgl) { RESOURCES += $$PWD/openglblacklists.qrc -contains(QT_CONFIG, freetype) { +qtConfig(freetype) { HEADERS += $$PWD/qwindowsfontdatabase_ft.h SOURCES += $$PWD/qwindowsfontdatabase_ft.cpp - contains(QT_CONFIG, system-freetype) { + qtConfig(system-freetype) { include($$QT_SOURCE_TREE/src/platformsupport/fontdatabases/basic/basic.pri) } else { - DEFINES *= QT_NO_FONTCONFIG include($$QT_SOURCE_TREE/src/3rdparty/freetype_dependency.pri) } } -contains(QT_CONFIG, accessibility):include($$PWD/accessible/accessible.pri) +qtConfig(accessibility): include($$PWD/accessible/accessible.pri) DEFINES *= LIBEGL_NAME=$${LIBEGL_NAME} DEFINES *= LIBGLESV2_NAME=$${LIBGLESV2_NAME} diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index a910967f87..606ca22bcd 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -322,10 +322,59 @@ void QWinRTWindow::setWindowState(Qt::WindowState state) if (d->state == state) return; +#if _MSC_VER >= 1900 + if (state == Qt::WindowFullScreen) { + HRESULT hr; + boolean success; + hr = QEventDispatcherWinRT::runOnXamlThread([&hr, &success]() { + ComPtr<IApplicationViewStatics2> applicationViewStatics; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(), + IID_PPV_ARGS(&applicationViewStatics)); + RETURN_HR_IF_FAILED("Could not access application view statics."); + ComPtr<IApplicationView> view; + hr = applicationViewStatics->GetForCurrentView(&view); + RETURN_HR_IF_FAILED("Could not access application view."); + ComPtr<IApplicationView3> view3; + hr = view.As(&view3); + Q_ASSERT_SUCCEEDED(hr); + hr = view3->TryEnterFullScreenMode(&success); + return hr; + }); + if (FAILED(hr) || !success) { + qCDebug(lcQpaWindows) << "Failed to enter full screen mode."; + return; + } + d->state = state; + return; + } + + if (d->state == Qt::WindowFullScreen) { + HRESULT hr; + hr = QEventDispatcherWinRT::runOnXamlThread([&hr]() { + ComPtr<IApplicationViewStatics2> applicationViewStatics; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(), + IID_PPV_ARGS(&applicationViewStatics)); + RETURN_HR_IF_FAILED("Could not access application view statics."); + ComPtr<IApplicationView> view; + hr = applicationViewStatics->GetForCurrentView(&view); + RETURN_HR_IF_FAILED("Could not access application view."); + ComPtr<IApplicationView3> view3; + hr = view.As(&view3); + Q_ASSERT_SUCCEEDED(hr); + hr = view3->ExitFullScreenMode(); + return hr; + }); + if (FAILED(hr)) { + qCDebug(lcQpaWindows) << "Failed to exit full screen mode."; + return; + } + } +#endif // _MSC_VER >= 1900 + if (state == Qt::WindowMinimized) setUIElementVisibility(d->uiElement.Get(), false); - if (d->state == Qt::WindowMinimized) + if (d->state == Qt::WindowMinimized || state == Qt::WindowNoState || state == Qt::WindowActive) setUIElementVisibility(d->uiElement.Get(), true); d->state = state; diff --git a/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro b/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro index 9de0476810..0cdee03f62 100644 --- a/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro +++ b/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro @@ -1,9 +1,9 @@ TEMPLATE = subdirs -contains(QT_CONFIG, egl): contains(QT_CONFIG, egl_x11): contains(QT_CONFIG, opengl) { +qtConfig(egl):qtConfig(egl_x11):qtConfig(opengl) { SUBDIRS += xcb_egl } -contains(QT_CONFIG, xcb-xlib): contains(QT_CONFIG, opengl): !contains(QT_CONFIG, opengles2) { +qtConfig(xcb-xlib):qtConfig(opengl):!qtConfig(opengles2) { SUBDIRS += xcb_glx } diff --git a/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri b/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri index c2d3849d8e..57c8f27d9c 100644 --- a/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri +++ b/src/plugins/platforms/xcb/gl_integrations/gl_integrations_plugin_base.pri @@ -4,35 +4,31 @@ INCLUDEPATH += $$PWD INCLUDEPATH += $$PWD/../ # needed by Xcursor ... -contains(QT_CONFIG, xcb-xlib) { +qtConfig(xcb-xlib) { DEFINES += XCB_USE_XLIB - contains(QT_CONFIG, xinput2) { + qtConfig(xinput2) { DEFINES += XCB_USE_XINPUT2 } } -# to support custom cursors with depth > 1 -contains(QT_CONFIG, xcb-render) { - DEFINES += XCB_USE_RENDER -} - # build with session management support -contains(QT_CONFIG, xcb-sm) { +qtConfig(xcb-sm) { DEFINES += XCB_USE_SM } -DEFINES += $$QMAKE_DEFINES_XCB -LIBS += $$QMAKE_LIBS_XCB -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB - CONFIG += qpa/genericunixfontdatabase -contains(QT_CONFIG, xcb-qt) { +!qtConfig(system-xcb) { DEFINES += XCB_USE_RENDER XCB_DIR = $$clean_path($$PWD/../../../../3rdparty/xcb) INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude - LIBS += -lxcb -L$$MODULE_BASE_OUTDIR/lib -lxcb-static$$qtPlatformTargetSuffix() + LIBS += -L$$MODULE_BASE_OUTDIR/lib -lxcb-static$$qtPlatformTargetSuffix() + QMAKE_USE += xcb } else { - LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms - !contains(DEFINES, QT_NO_XKB):LIBS += -lxcb-xkb + qtConfig(xkb): QMAKE_USE += xcb_xkb + # to support custom cursors with depth > 1 + qtConfig(xcb-render) { + DEFINES += XCB_USE_RENDER + } + QMAKE_USE += xcb_syslibs } diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h index 9729f610b6..7c6524c8ee 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/qxcbeglinclude.h @@ -46,7 +46,7 @@ #include <QtGui/private/qcssparser_p.h> #include <QtGui/private/qtextengine_p.h> -#include <EGL/egl.h> +#include <QtPlatformSupport/private/qt_egl_p.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/xcb_egl.pro b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/xcb_egl.pro index 6d52332bad..92e6c18fbe 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_egl/xcb_egl.pro +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_egl/xcb_egl.pro @@ -4,7 +4,7 @@ include(../gl_integrations_plugin_base.pri) CONFIG += egl -contains(QT_CONFIG, xcb-xlib): DEFINES += XCB_USE_XLIB +qtConfig(xcb-xlib): DEFINES += XCB_USE_XLIB HEADERS += \ qxcbeglcontext.h \ diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro index 67fd68765a..88c4144fd9 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro @@ -5,12 +5,11 @@ include(../gl_integrations_plugin_base.pri) #should be removed from the sources DEFINES += XCB_USE_GLX XCB_USE_XLIB -LIBS += -lxcb - -contains(QT_CONFIG, xcb-glx) { +qtConfig(xcb-glx) { DEFINES += XCB_HAS_XCB_GLX - LIBS += -lxcb-glx + QMAKE_USE += xcb_glx } +QMAKE_USE += xcb LIBS += $$QMAKE_LIBS_DYNLOAD diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 7065bb0ffb..2d959688b3 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -599,7 +599,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra xcb_extension_t *extensions[] = { &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id, -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) &xcb_xkb_id, #endif #ifdef XCB_USE_RENDER @@ -1069,7 +1069,7 @@ Qt::MouseButton QXcbConnection::translateMouseButton(xcb_button_t s) } } -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) namespace { typedef union { /* All XKB events share these fields. */ @@ -1252,7 +1252,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) s->handleScreenChange(change_event); } handled = true; -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) } else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295 _xkb_event *xkb_event = reinterpret_cast<_xkb_event *>(event); if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) { @@ -2174,7 +2174,7 @@ void QXcbConnection::initializeXShape() void QXcbConnection::initializeXKB() { -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xkb_id); if (!reply || !reply->present) { qWarning("Qt: XKEYBOARD extension not present on the X server."); diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 34866e5c89..4d903ec8d3 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -53,10 +53,11 @@ #include <QVarLengthArray> #include <qpa/qwindowsysteminterface.h> #include <QtCore/QLoggingCategory> +#include <QtCore/private/qglobal_p.h> // This is needed to make Qt compile together with XKB. xkb.h is using a variable // which is called 'explicit', this is a reserved keyword in c++ -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) #define explicit dont_use_cxx_explicit #include <xcb/xkb.h> #undef explicit diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 5b7f45fb6c..bda167bce9 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -697,7 +697,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo if (m_xiGrab) { // XIAllowTouchEvents deadlocks with libXi < 1.7.4 (this has nothing to do with the XI2 versions like 2.2) // http://lists.x.org/archives/xorg-devel/2014-July/043059.html -#ifndef LIBXI_MAJOR +#ifndef XCB_USE_XINPUT2 static bool allowTouchWarningShown = false; if (!allowTouchWarningShown) { allowTouchWarningShown = true; @@ -705,13 +705,16 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo " Minimum libXi version required is 1.7.4." " Expect issues with touch behavior."); } -#elif LIBXI_MAJOR == 1 && (LIBXI_MINOR < 7 || (LIBXI_MINOR == 7 && LIBXI_PATCH < 4)) +#elif QT_LIBRARY_VERSION(xinput2) < QT_VERSION_CHECK(1, 7, 4) static bool allowTouchWarningShown = false; if (!allowTouchWarningShown) { allowTouchWarningShown = true; qWarning("Skipping XIAllowTouchEvents() due to not having libXi >= 1.7.4." " libXi version at build time was %d.%d.%d." - " Expect issues with touch behavior.", LIBXI_MAJOR, LIBXI_MINOR, LIBXI_PATCH); + " Expect issues with touch behavior.", + QT_LIBRARY_VERSION_MAJOR(xinput2), + QT_LIBRARY_VERSION_MINOR(xinput2), + QT_LIBRARY_VERSION_PATCH(xinput2)); } #else XIAllowTouchEvents(static_cast<Display *>(m_xlib_display), xiDeviceEvent->deviceid, diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index cdbf9b295e..5a89113a4f 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -65,7 +65,7 @@ #include <QtGui/private/qguiapplication_p.h> #ifdef XCB_USE_EGL -#include <EGL/egl.h> +# include <QtPlatformSupport/private/qt_egl_p.h> #endif #ifdef XCB_USE_XLIB diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 811ef4251a..07932ceeb8 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -711,7 +711,7 @@ void QXcbKeyboard::updateKeymap() xkb_keymap = 0; struct xkb_state *new_state = 0; -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) if (connection()->hasXKB()) { xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, xcb_connection(), core_device_id, (xkb_keymap_compile_flags)0); if (xkb_keymap) { @@ -754,7 +754,7 @@ void QXcbKeyboard::updateKeymap() checkForLatinLayout(); } -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state) { if (m_config && connection()->hasXKB()) { @@ -1140,7 +1140,7 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection) , m_hasLatinLayout(false) { memset(&xkb_names, 0, sizeof(xkb_names)); -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) core_device_id = 0; if (connection->hasXKB()) { updateVModMapping(); @@ -1154,7 +1154,7 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection) #endif m_key_symbols = xcb_key_symbols_alloc(xcb_connection()); updateModifiers(); -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) } #endif updateKeymap(); @@ -1173,7 +1173,7 @@ QXcbKeyboard::~QXcbKeyboard() void QXcbKeyboard::updateVModMapping() { -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) xcb_xkb_get_names_cookie_t names_cookie; xcb_xkb_get_names_reply_t *name_reply; xcb_xkb_get_names_value_list_t names_list; @@ -1242,7 +1242,7 @@ void QXcbKeyboard::updateVModMapping() void QXcbKeyboard::updateVModToRModMapping() { -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) xcb_xkb_get_map_cookie_t map_cookie; xcb_xkb_get_map_reply_t *map_reply; xcb_xkb_get_map_map_t map; diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 75e6d2ec82..817b57ff5b 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -45,7 +45,7 @@ #include <xcb/xcb_keysyms.h> #include <xkbcommon/xkbcommon.h> -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) #include <xkbcommon/xkbcommon-x11.h> #endif @@ -77,7 +77,7 @@ public: #ifdef XCB_USE_XINPUT22 void updateXKBStateFromXI(void *modInfo, void *groupInfo); #endif -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) // when XKEYBOARD is present on the X server int coreDeviceId() const { return core_device_id; } void updateXKBState(xcb_xkb_state_notify_event_t *state); @@ -136,7 +136,7 @@ private: xkb_mod_index_t mod5; }; _xkb_mods xkb_mods; -#ifndef QT_NO_XKB +#if QT_CONFIG(xkb) // when XKEYBOARD is present on the X server _mod_masks vmod_masks; int core_device_id; diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro index 5915a59c0b..7840a4583f 100644 --- a/src/plugins/platforms/xcb/xcb.pro +++ b/src/plugins/platforms/xcb/xcb.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs CONFIG += ordered -contains(QT_CONFIG, xcb-qt):SUBDIRS+=xcb-static +!qtConfig(system-xcb): SUBDIRS += xcb-static SUBDIRS += xcb_qpa_lib.pro SUBDIRS += xcb-plugin.pro diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index 7967aee3ab..942183877d 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -41,67 +41,54 @@ HEADERS = \ DEFINES += QT_BUILD_XCB_PLUGIN # needed by Xcursor ... -contains(QT_CONFIG, xcb-xlib) { +qtConfig(xcb-xlib) { DEFINES += XCB_USE_XLIB - LIBS += -lX11 -lX11-xcb + QMAKE_USE += xcb_xlib - contains(QT_CONFIG, xinput2) { + qtConfig(xinput2) { DEFINES += XCB_USE_XINPUT2 SOURCES += qxcbconnection_xi2.cpp - LIBS += -lXi - !isEmpty(QMAKE_XINPUT2_VERSION_MAJOR) { - DEFINES += LIBXI_MAJOR=$$QMAKE_XINPUT2_VERSION_MAJOR \ - LIBXI_MINOR=$$QMAKE_XINPUT2_VERSION_MINOR \ - LIBXI_PATCH=$$QMAKE_XINPUT2_VERSION_PATCH - } + QMAKE_USE += xinput2 } } -# to support custom cursors with depth > 1 -contains(QT_CONFIG, xcb-render) { - DEFINES += XCB_USE_RENDER - LIBS += -lxcb-render -lxcb-render-util -} - # build with session management support -contains(QT_CONFIG, xcb-sm) { +qtConfig(xcb-sm) { DEFINES += XCB_USE_SM - LIBS += -lSM -lICE + QMAKE_USE += x11sm SOURCES += qxcbsessionmanager.cpp HEADERS += qxcbsessionmanager.h } include(gl_integrations/gl_integrations.pri) -DEFINES += $$QMAKE_DEFINES_XCB -LIBS += $$QMAKE_LIBS_XCB -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB -QMAKE_CFLAGS += $$QMAKE_CFLAGS_XCB - CONFIG += qpa/genericunixfontdatabase -contains(QT_CONFIG, dbus-linked) { +qtConfig(dbus-linked): \ QT += dbus - LIBS += $$QMAKE_LIBS_DBUS -} -contains(QT_CONFIG, xcb-qt) { +!qtConfig(system-xcb) { DEFINES += XCB_USE_RENDER XCB_DIR = ../../../3rdparty/xcb INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude - LIBS += -lxcb -L$$MODULE_BASE_OUTDIR/lib -lxcb-static$$qtPlatformTargetSuffix() + LIBS += -L$$MODULE_BASE_OUTDIR/lib -lxcb-static$$qtPlatformTargetSuffix() + QMAKE_USE += xcb } else { - LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms -lxcb-xinerama - !contains(DEFINES, QT_NO_XKB):LIBS += -lxcb-xkb + LIBS += -lxcb-xinerama ### there is no configure test for this! + qtConfig(xkb): QMAKE_USE += xcb_xkb + # to support custom cursors with depth > 1 + qtConfig(xcb-render) { + DEFINES += XCB_USE_RENDER + QMAKE_USE += xcb_render + } + QMAKE_USE += xcb_syslibs } # libxkbcommon -contains(QT_CONFIG, xkbcommon-qt) { - QT_CONFIG += use-xkbcommon-x11support - include(../../../3rdparty/xkbcommon.pri) +!qtConfig(xkbcommon-system) { + include(../../../3rdparty/xkbcommon-x11.pri) } else { - LIBS += $$QMAKE_LIBS_XKBCOMMON - QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON + QMAKE_USE += xkbcommon } load(qt_module) |