diff options
Diffstat (limited to 'src')
79 files changed, 1744 insertions, 561 deletions
diff --git a/src/client/global/qwaylandclientextension.h b/src/client/global/qwaylandclientextension.h index 37debc513..98272e571 100644 --- a/src/client/global/qwaylandclientextension.h +++ b/src/client/global/qwaylandclientextension.h @@ -95,7 +95,7 @@ public: return T::interface(); } - void bind(struct ::wl_registry *registry, int id, int ver) + void bind(struct ::wl_registry *registry, int id, int ver) override { T* instance = static_cast<T *>(this); // Make sure lowest version is used of the supplied version from the diff --git a/src/client/hardwareintegration/qwaylandclientbufferintegration_p.h b/src/client/hardwareintegration/qwaylandclientbufferintegration_p.h index f1f0cf932..7776c6158 100644 --- a/src/client/hardwareintegration/qwaylandclientbufferintegration_p.h +++ b/src/client/hardwareintegration/qwaylandclientbufferintegration_p.h @@ -86,8 +86,8 @@ public: EglConfig, EglContext }; - virtual void *nativeResource(NativeResource /*resource*/) { return Q_NULLPTR; } - virtual void *nativeResourceForContext(NativeResource /*resource*/, QPlatformOpenGLContext */*context*/) { return Q_NULLPTR; } + virtual void *nativeResource(NativeResource /*resource*/) { return nullptr; } + virtual void *nativeResourceForContext(NativeResource /*resource*/, QPlatformOpenGLContext */*context*/) { return nullptr; } }; } diff --git a/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory.cpp b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory.cpp index 94eca3262..8f573064e 100644 --- a/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory.cpp +++ b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory.cpp @@ -90,7 +90,7 @@ QWaylandInputDeviceIntegration *QWaylandInputDeviceIntegrationFactory::create(co if (QWaylandInputDeviceIntegration *ret = qLoadPlugin<QWaylandInputDeviceIntegration, QWaylandInputDeviceIntegrationPlugin>(loader(), name, args)) return ret; #endif - return Q_NULLPTR; + return nullptr; } } diff --git a/src/client/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp index 7caa247e5..bd820e28e 100644 --- a/src/client/qwaylandcursor.cpp +++ b/src/client/qwaylandcursor.cpp @@ -92,7 +92,7 @@ struct wl_cursor_image *QWaylandCursor::cursorImage(Qt::CursorShape newShape) waylandCursor = requestCursor((WaylandCursor)newShape); } else if (newShape == Qt::BitmapCursor) { // cannot create a wl_cursor_image for a CursorShape - return Q_NULLPTR; + return nullptr; } else { //TODO: Custom cursor logic (for resize arrows) } @@ -119,7 +119,7 @@ QSharedPointer<QWaylandBuffer> QWaylandCursor::cursorBitmapImage(const QCursor * const QImage &img = cursor->pixmap().toImage(); QSharedPointer<QWaylandShmBuffer> buffer(new QWaylandShmBuffer(mDisplay, img.size(), img.format())); - memcpy(buffer->image()->bits(), img.bits(), img.byteCount()); + memcpy(buffer->image()->bits(), img.bits(), img.sizeInBytes()); return buffer; } diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp index 33068c5e9..66f36f75b 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/qwaylanddatadevice.cpp @@ -97,7 +97,7 @@ void QWaylandDataDevice::setSelectionSource(QWaylandDataSource *source) { if (source) connect(source, &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::selectionSourceCancelled); - set_selection(source ? source->object() : Q_NULLPTR, m_inputDevice->serial()); + set_selection(source ? source->object() : nullptr, m_inputDevice->serial()); m_selectionSource.reset(source); } @@ -160,7 +160,7 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface, m_dragWindow = QWaylandWindow::fromWlSurface(surface)->window(); m_dragPoint = calculateDragPosition(x, y, m_dragWindow); - QMimeData *dragData = Q_NULLPTR; + QMimeData *dragData = nullptr; Qt::DropActions supportedActions; m_dragOffer.reset(static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id))); diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index 86cfe1a0d..02b1fd9a9 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -97,7 +97,7 @@ struct ::wl_region *QWaylandDisplay::createRegion(const QRegion &qregion) { struct ::wl_region *region = mCompositor.create_region(); - Q_FOREACH (const QRect &rect, qregion.rects()) + for (const QRect &rect : qregion) wl_region_add(region, rect.x(), rect.y(), rect.width(), rect.height()); return region; @@ -136,8 +136,8 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) , mLastInputSerial(0) , mLastInputDevice(0) , mLastInputWindow(0) - , mLastKeyboardFocus(Q_NULLPTR) - , mSyncCallback(Q_NULLPTR) + , mLastKeyboardFocus(nullptr) + , mSyncCallback(nullptr) { qRegisterMetaType<uint32_t>("uint32_t"); @@ -157,6 +157,9 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) QWaylandDisplay::~QWaylandDisplay(void) { + if (mSyncCallback) + wl_callback_destroy(mSyncCallback); + qDeleteAll(mInputDevices); mInputDevices.clear(); @@ -343,6 +346,15 @@ sync_callback(void *data, struct wl_callback *callback, uint32_t serial) bool *done = static_cast<bool *>(data); *done = true; + + // If the wl_callback done event is received after the condition check in the while loop in + // forceRoundTrip(), but before the call to processEvents, the call to processEvents may block + // forever if no more events are posted (eventhough the callback is handled in response to the + // aboutToBlock signal). Hence, we wake up the event dispatcher so forceRoundTrip may return. + // (QTBUG-64696) + if (auto *dispatcher = QThread::currentThread()->eventDispatcher()) + dispatcher->wakeUp(); + wl_callback_destroy(callback); } @@ -446,7 +458,7 @@ void QWaylandDisplay::handleWaylandSync() // This callback is used to set the window activation because we may get an activate/deactivate // pair, and the latter one would be lost in the QWindowSystemInterface queue, if we issue the // handleWindowActivated() calls immediately. - QWindow *activeWindow = mActiveWindows.empty() ? Q_NULLPTR : mActiveWindows.last()->window(); + QWindow *activeWindow = mActiveWindows.empty() ? nullptr : mActiveWindows.last()->window(); if (activeWindow != QGuiApplication::focusWindow()) QWindowSystemInterface::handleWindowActivated(activeWindow); } @@ -456,7 +468,7 @@ const wl_callback_listener QWaylandDisplay::syncCallbackListener = { Q_UNUSED(time); wl_callback_destroy(callback); QWaylandDisplay *display = static_cast<QWaylandDisplay *>(data); - display->mSyncCallback = Q_NULLPTR; + display->mSyncCallback = nullptr; display->handleWaylandSync(); } }; diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index 4def0de8f..b34504a1f 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -70,19 +70,16 @@ #include <QtGui/QGuiApplication> +#if QT_CONFIG(xkbcommon_evdev) +#include <xkbcommon/xkbcommon-compose.h> +#endif + QT_BEGIN_NAMESPACE namespace QtWaylandClient { QWaylandInputDevice::Keyboard::Keyboard(QWaylandInputDevice *p) : mParent(p) - , mFocus(0) -#if QT_CONFIG(xkbcommon_evdev) - , mXkbContext(0) - , mXkbMap(0) - , mXkbState(0) -#endif - , mNativeModifiers(0) { connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey())); } @@ -113,6 +110,7 @@ bool QWaylandInputDevice::Keyboard::createDefaultKeyMap() qWarning() << "xkb_map_new_from_names failed, no key input"; return false; } + createComposeState(); return true; } @@ -125,15 +123,45 @@ void QWaylandInputDevice::Keyboard::releaseKeyMap() if (mXkbContext) xkb_context_unref(mXkbContext); } + +void QWaylandInputDevice::Keyboard::createComposeState() +{ + static const char *locale = nullptr; + if (!locale) { + locale = getenv("LC_ALL"); + if (!locale) + locale = getenv("LC_CTYPE"); + if (!locale) + locale = getenv("LANG"); + if (!locale) + locale = "C"; + } + + mXkbComposeTable = xkb_compose_table_new_from_locale(mXkbContext, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); + if (mXkbComposeTable) + mXkbComposeState = xkb_compose_state_new(mXkbComposeTable, XKB_COMPOSE_STATE_NO_FLAGS); +} + +void QWaylandInputDevice::Keyboard::releaseComposeState() +{ + if (mXkbComposeState) + xkb_compose_state_unref(mXkbComposeState); + if (mXkbComposeTable) + xkb_compose_table_unref(mXkbComposeTable); + mXkbComposeState = nullptr; + mXkbComposeTable = nullptr; +} + #endif QWaylandInputDevice::Keyboard::~Keyboard() { #if QT_CONFIG(xkbcommon_evdev) + releaseComposeState(); releaseKeyMap(); #endif if (mFocus) - QWindowSystemInterface::handleWindowActivated(0); + QWindowSystemInterface::handleWindowActivated(nullptr); if (mParent->mVersion >= 3) wl_keyboard_release(object()); else @@ -147,16 +175,6 @@ void QWaylandInputDevice::Keyboard::stopRepeat() QWaylandInputDevice::Pointer::Pointer(QWaylandInputDevice *p) : mParent(p) - , mFocus(0) - , mEnterSerial(0) -#if QT_CONFIG(cursor) - , mCursorSerial(0) -#endif - , mButtons(0) -#if QT_CONFIG(cursor) - , mCursorBuffer(nullptr) - , mCursorShape(Qt::BitmapCursor) -#endif { } @@ -170,7 +188,6 @@ QWaylandInputDevice::Pointer::~Pointer() QWaylandInputDevice::Touch::Touch(QWaylandInputDevice *p) : mParent(p) - , mFocus(0) { } @@ -188,17 +205,6 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, int version, , mQDisplay(display) , mDisplay(display->wl_display()) , mVersion(qMin(version, 4)) - , mCaps(0) -#if QT_CONFIG(wayland_datadevice) - , mDataDevice(0) -#endif - , mKeyboard(0) - , mPointer(0) - , mTouch(0) - , mTextInput(0) - , mTime(0) - , mSerial(0) - , mTouchDevice(0) { #if QT_CONFIG(wayland_datadevice) if (mQDisplay->dndSelectionHandler()) { @@ -227,7 +233,7 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps) mKeyboard->init(get_keyboard()); } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && mKeyboard) { delete mKeyboard; - mKeyboard = 0; + mKeyboard = nullptr; } if (caps & WL_SEAT_CAPABILITY_POINTER && !mPointer) { @@ -236,7 +242,7 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps) pointerSurface = mQDisplay->createSurface(this); } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && mPointer) { delete mPointer; - mPointer = 0; + mPointer = nullptr; } if (caps & WL_SEAT_CAPABILITY_TOUCH && !mTouch) { @@ -251,7 +257,7 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps) } } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && mTouch) { delete mTouch; - mTouch = 0; + mTouch = nullptr; } } @@ -272,14 +278,8 @@ QWaylandInputDevice::Touch *QWaylandInputDevice::createTouch(QWaylandInputDevice void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window) { - if (mPointer && window == mPointer->mFocus) - mPointer->mFocus = 0; - if (mKeyboard && window == mKeyboard->mFocus) { - mKeyboard->mFocus = 0; + if (mKeyboard && window == mKeyboard->mFocus) mKeyboard->stopRepeat(); - } - if (mTouch && window == mTouch->mFocus) - mTouch->mFocus = 0; } void QWaylandInputDevice::handleEndDrag() @@ -321,17 +321,17 @@ void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) QWaylandWindow *QWaylandInputDevice::pointerFocus() const { - return mPointer ? mPointer->mFocus : 0; + return mPointer ? mPointer->mFocus : nullptr; } QWaylandWindow *QWaylandInputDevice::keyboardFocus() const { - return mKeyboard ? mKeyboard->mFocus : 0; + return mKeyboard ? mKeyboard->mFocus : nullptr; } QWaylandWindow *QWaylandInputDevice::touchFocus() const { - return mTouch ? mTouch->mFocus : 0; + return mTouch ? mTouch->mFocus : nullptr; } Qt::KeyboardModifiers QWaylandInputDevice::modifiers() const @@ -411,7 +411,7 @@ void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, const QPoint &hotS /* Hide cursor */ if (!buffer) { - mPointer->set_cursor(mPointer->mEnterSerial, NULL, 0, 0); + mPointer->set_cursor(mPointer->mEnterSerial, nullptr, 0, 0); return; } @@ -434,7 +434,7 @@ class EnterEvent : public QWaylandPointerEvent { public: EnterEvent(const QPointF &l, const QPointF &g) - : QWaylandPointerEvent(QWaylandPointerEvent::Enter, 0, l, g, 0, Qt::NoModifier) + : QWaylandPointerEvent(QWaylandPointerEvent::Enter, 0, l, g, nullptr, Qt::NoModifier) {} }; @@ -474,7 +474,7 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); window->handleMouseLeave(mParent); } - mFocus = 0; + mFocus = nullptr; mButtons = Qt::NoButton; mParent->mTime = time; @@ -493,7 +493,7 @@ void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surf { QWaylandWindow *window = mFocus; - if (window == NULL) { + if (!window) { // We destroyed the pointer focus surface, but the server // didn't get the message yet. return; @@ -595,7 +595,7 @@ void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, in QPoint pixelDelta; QPoint angleDelta; - if (window == NULL) { + if (!window) { // We destroyed the pointer focus surface, but the server // didn't get the message yet. return; @@ -624,7 +624,7 @@ void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, return; } - char *map_str = (char *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + char *map_str = static_cast<char *>(mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0)); if (map_str == MAP_FAILED) { close(fd); return; @@ -632,14 +632,17 @@ void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, // Release the old keymap resources in the case they were already created in // the key event or when the compositor issues a new map + releaseComposeState(); releaseKeyMap(); - mXkbContext = xkb_context_new(xkb_context_flags(0)); - mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, (xkb_keymap_compile_flags)0); + mXkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); munmap(map_str, size); close(fd); mXkbState = xkb_state_new(mXkbMap); + createComposeState(); + #else Q_UNUSED(format); Q_UNUSED(fd); @@ -672,7 +675,7 @@ void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surf window->unfocus(); } - mFocus = NULL; + mFocus = nullptr; mParent->mQDisplay->handleKeyboardFocusChanged(mParent); @@ -703,7 +706,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, { QWaylandWindow *window = mFocus; uint32_t code = key + 8; - bool isDown = state != 0; + bool isDown = state != WL_KEYBOARD_KEY_STATE_RELEASED; QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; QString text; int qtkey = key + 8; // qt-compositor substracts 8 for some reason @@ -723,12 +726,37 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, return; } - const xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState, code); + QString composedText; + xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState, code); + if (mXkbComposeState) { + if (isDown) + xkb_compose_state_feed(mXkbComposeState, sym); + xkb_compose_status status = xkb_compose_state_get_status(mXkbComposeState); + + switch (status) { + case XKB_COMPOSE_COMPOSED: { + int size = xkb_compose_state_get_utf8(mXkbComposeState, nullptr, 0); + QVarLengthArray<char, 32> buffer(size + 1); + xkb_compose_state_get_utf8(mXkbComposeState, buffer.data(), buffer.size()); + composedText = QString::fromUtf8(buffer.constData()); + sym = xkb_compose_state_get_one_sym(mXkbComposeState); + xkb_compose_state_reset(mXkbComposeState); + } break; + case XKB_COMPOSE_COMPOSING: + case XKB_COMPOSE_CANCELLED: + return; + case XKB_COMPOSE_NOTHING: + break; + } + } Qt::KeyboardModifiers modifiers = mParent->modifiers(); std::tie(qtkey, text) = QWaylandXkb::keysymToQtKey(sym, modifiers); + if (!composedText.isNull()) + text = composedText; + sendKey(window->window(), time, type, qtkey, modifiers, code, sym, mNativeModifiers, text); #else // Generic fallback for single hard keys: Assume 'key' is a Qt key code. @@ -817,7 +845,7 @@ void QWaylandInputDevice::Touch::touch_up(uint32_t serial, uint32_t time, int32_ { Q_UNUSED(serial); Q_UNUSED(time); - mFocus = 0; + mFocus = nullptr; mParent->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); // As of Weston 1.5.90 there is no touch_frame after the last touch_up @@ -843,7 +871,7 @@ void QWaylandInputDevice::Touch::touch_cancel() if (touchExt) touchExt->touchCanceled(); - QWindowSystemInterface::handleTouchCancelEvent(0, mParent->mTouchDevice); + QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice); } void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state) @@ -928,7 +956,7 @@ void QWaylandInputDevice::Touch::touch_frame() return; } - QWindow *window = mFocus ? mFocus->window() : 0; + QWindow *window = mFocus ? mFocus->window() : nullptr; if (mFocus) { const QWindowSystemInterface::TouchPoint &tp = mTouchPoints.last(); diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h index 9e3d1d1f4..8a02769e3 100644 --- a/src/client/qwaylandinputdevice_p.h +++ b/src/client/qwaylandinputdevice_p.h @@ -71,11 +71,17 @@ #endif #include <QtCore/QDebug> +#include <QPointer> #if QT_CONFIG(cursor) struct wl_cursor_image; #endif +#if QT_CONFIG(xkbcommon_evdev) +struct xkb_compose_state; +struct xkb_compose_table; +#endif + QT_BEGIN_NAMESPACE namespace QtWaylandClient { @@ -141,27 +147,27 @@ private: struct wl_display *mDisplay; int mVersion; - uint32_t mCaps; + uint32_t mCaps = 0; struct wl_surface *pointerSurface; #if QT_CONFIG(wayland_datadevice) - QWaylandDataDevice *mDataDevice; + QWaylandDataDevice *mDataDevice = nullptr; #endif - Keyboard *mKeyboard; - Pointer *mPointer; - Touch *mTouch; + Keyboard *mKeyboard = nullptr; + Pointer *mPointer = nullptr; + Touch *mTouch = nullptr; - QWaylandTextInput *mTextInput; + QWaylandTextInput *mTextInput = nullptr; - uint32_t mTime; - uint32_t mSerial; + uint32_t mTime = 0; + uint32_t mSerial = 0; void seat_capabilities(uint32_t caps) override; void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state); - QTouchDevice *mTouchDevice; + QTouchDevice *mTouchDevice = nullptr; QSharedPointer<QWaylandBuffer> mPixmapCursor; @@ -202,13 +208,15 @@ public: uint32_t group) override; QWaylandInputDevice *mParent; - QWaylandWindow *mFocus; + QPointer<QWaylandWindow> mFocus; #if QT_CONFIG(xkbcommon_evdev) - xkb_context *mXkbContext; - xkb_keymap *mXkbMap; - xkb_state *mXkbState; + xkb_context *mXkbContext = nullptr; + xkb_keymap *mXkbMap = nullptr; + xkb_state *mXkbState = nullptr; + xkb_compose_table *mXkbComposeTable = nullptr; + xkb_compose_state *mXkbComposeState = nullptr; #endif - uint32_t mNativeModifiers; + uint32_t mNativeModifiers = 0; int mRepeatKey; uint32_t mRepeatCode; @@ -228,6 +236,8 @@ private: #if QT_CONFIG(xkbcommon_evdev) bool createDefaultKeyMap(); void releaseKeyMap(); + void createComposeState(); + void releaseComposeState(); #endif }; @@ -253,17 +263,17 @@ public: void releaseButtons(); QWaylandInputDevice *mParent; - QWaylandWindow *mFocus; - uint32_t mEnterSerial; + QPointer<QWaylandWindow> mFocus; + uint32_t mEnterSerial = 0; #if QT_CONFIG(cursor) - uint32_t mCursorSerial; + uint32_t mCursorSerial = 0; #endif QPointF mSurfacePos; QPointF mGlobalPos; - Qt::MouseButtons mButtons; + Qt::MouseButtons mButtons = Qt::NoButton; #if QT_CONFIG(cursor) - wl_buffer *mCursorBuffer; - Qt::CursorShape mCursorShape; + wl_buffer *mCursorBuffer = nullptr; + Qt::CursorShape mCursorShape = Qt::BitmapCursor; #endif }; @@ -293,7 +303,7 @@ public: void releasePoints(); QWaylandInputDevice *mParent; - QWaylandWindow *mFocus; + QPointer<QWaylandWindow> mFocus; QList<QWindowSystemInterface::TouchPoint> mTouchPoints; QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints; }; diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index bffadf29a..f0182218f 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -122,7 +122,7 @@ public: QWaylandIntegration::QWaylandIntegration() : mClientBufferIntegration(0) - , mInputDeviceIntegration(Q_NULLPTR) + , mInputDeviceIntegration(nullptr) , mFontDb(new QGenericUnixFontDatabase()) , mNativeInterface(new QWaylandNativeInterface(this)) #if QT_CONFIG(accessibility) @@ -397,7 +397,7 @@ void QWaylandIntegration::initializeShellIntegration() "please specify the shell using QT_WAYLAND_SHELL_INTEGRATION instead"; preferredShells << QLatin1String("xdg-shell-v5"); } - preferredShells << QLatin1String("wl-shell"); + preferredShells << QLatin1String("wl-shell") << QLatin1String("ivi-shell"); } Q_FOREACH (QString preferredShell, preferredShells) { diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp index 5b43428d9..b6336f2e6 100644 --- a/src/client/qwaylandscreen.cpp +++ b/src/client/qwaylandscreen.cpp @@ -147,7 +147,7 @@ void QWaylandScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) { foreach (QWindow *window, QGuiApplication::allWindows()) { QWaylandWindow *w = static_cast<QWaylandWindow *>(window->handle()); - if (w && w->screen() == this) + if (w && w->waylandScreen() == this) w->setOrientationMask(mask); } } diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp index 2085bc597..a13a5f764 100644 --- a/src/client/qwaylandshmbackingstore.cpp +++ b/src/client/qwaylandshmbackingstore.cpp @@ -125,7 +125,7 @@ QWaylandShmBuffer::~QWaylandShmBuffer(void) { delete mMarginsImage; if (mImage.constBits()) - munmap((void *) mImage.constBits(), mImage.byteCount()); + munmap((void *) mImage.constBits(), mImage.sizeInBytes()); if (mShmPool) wl_shm_pool_destroy(mShmPool); } @@ -171,7 +171,7 @@ QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window) QWaylandShmBackingStore::~QWaylandShmBackingStore() { if (QWaylandWindow *w = waylandWindow()) - w->setBackingStore(Q_NULLPTR); + w->setBackingStore(nullptr); // if (mFrontBuffer == waylandWindow()->attached()) // waylandWindow()->attach(0); @@ -287,10 +287,10 @@ void QWaylandShmBackingStore::resize(const QSize &size) buffer = getBuffer(sizeWithMargins); } - int oldSize = mBackBuffer ? mBackBuffer->image()->byteCount() : 0; + qsizetype oldSize = mBackBuffer ? mBackBuffer->image()->sizeInBytes() : 0; // mBackBuffer may have been deleted here but if so it means its size was different so we wouldn't copy it anyway - if (mBackBuffer != buffer && oldSize == buffer->image()->byteCount()) { - memcpy(buffer->image()->bits(), mBackBuffer->image()->constBits(), buffer->image()->byteCount()); + if (mBackBuffer != buffer && oldSize == buffer->image()->sizeInBytes()) { + memcpy(buffer->image()->bits(), mBackBuffer->image()->constBits(), buffer->image()->sizeInBytes()); } mBackBuffer = buffer; // ensure the new buffer is at the beginning of the list so next time getBuffer() will pick diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 6661d8e7e..2e709440f 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -80,7 +80,7 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = 0; QWaylandWindow::QWaylandWindow(QWindow *window) : QObject() , QPlatformWindow(window) - , mDisplay(screen()->display()) + , mDisplay(waylandScreen()->display()) , mShellSurface(0) , mSubSurfaceWindow(0) , mWindowDecoration(0) @@ -95,7 +95,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mScale(1) , mState(Qt::WindowNoState) , mMask() - , mBackingStore(Q_NULLPTR) + , mBackingStore(nullptr) , mUpdateRequested(false) { static WId id = 1; @@ -128,6 +128,12 @@ QWaylandWindow::~QWaylandWindow() } } +void QWaylandWindow::ensureSize() +{ + if (mBackingStore) + mBackingStore->ensureSize(); +} + void QWaylandWindow::initWindow() { if (window()->type() == Qt::Desktop) @@ -194,12 +200,11 @@ void QWaylandWindow::initWindow() } } - mScale = screen()->scale(); + mScale = waylandScreen()->scale(); // Enable high-dpi rendering. Scale() returns the screen scale factor and will // typically be integer 1 (normal-dpi) or 2 (high-dpi). Call set_buffer_scale() // to inform the compositor that high-resolution buffers will be provided. - //FIXME this needs to be changed when the screen changes along with a resized backing store if (mDisplay->compositorVersion() >= 3) set_buffer_scale(scale()); @@ -241,7 +246,7 @@ bool QWaylandWindow::shouldCreateShellSurface() const bool QWaylandWindow::shouldCreateSubSurface() const { - return QPlatformWindow::parent() != Q_NULLPTR; + return QPlatformWindow::parent() != nullptr; } void QWaylandWindow::reset(bool sendDestroyEvent) @@ -369,7 +374,7 @@ void QWaylandWindow::closePopups(QWaylandWindow *parent) QWaylandScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const { - return mScreens.isEmpty() ? screen() : mScreens.first(); + return mScreens.isEmpty() ? waylandScreen() : mScreens.first(); } void QWaylandWindow::setVisible(bool visible) @@ -523,7 +528,7 @@ void QWaylandWindow::surface_enter(wl_output *output) QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); if (oldScreen != newScreen) //currently this will only happen if the first wl_surface.enter is for a non-primary screen - QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); + handleScreenChanged(); } void QWaylandWindow::surface_leave(wl_output *output) @@ -540,7 +545,7 @@ void QWaylandWindow::surface_leave(wl_output *output) QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); if (oldScreen != newScreen) - QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); + handleScreenChanged(); } void QWaylandWindow::handleScreenRemoved(QScreen *qScreen) @@ -550,7 +555,7 @@ void QWaylandWindow::handleScreenRemoved(QScreen *qScreen) if (wasRemoved) { QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); if (oldScreen != newScreen) - QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); + handleScreenChanged(); } } @@ -590,8 +595,7 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage) return; attachOffset(buffer); - const QVector<QRect> rects = damage.rects(); - for (const QRect &rect: rects) + for (const QRect &rect: damage) wl_surface::damage(rect.x(), rect.y(), rect.width(), rect.height()); wl_surface::commit(); } @@ -603,6 +607,7 @@ const wl_callback_listener QWaylandWindow::callbackListener = { void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uint32_t time) { Q_UNUSED(time); + Q_UNUSED(callback); QWaylandWindow *self = static_cast<QWaylandWindow*>(data); self->mWaitingForFrameSync = false; @@ -642,7 +647,7 @@ QWaylandSubSurface *QWaylandWindow::subSurfaceWindow() const return mSubSurfaceWindow; } -QWaylandScreen *QWaylandWindow::screen() const +QWaylandScreen *QWaylandWindow::waylandScreen() const { return static_cast<QWaylandScreen *>(QPlatformWindow::screen()); } @@ -913,10 +918,24 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe } } +void QWaylandWindow::handleScreenChanged() +{ + QWaylandScreen *newScreen = calculateScreenFromSurfaceEvents(); + QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen()); + + int scale = newScreen->scale(); + if (scale != mScale) { + mScale = scale; + if (isInitialized() && mDisplay->compositorVersion() >= 3) + set_buffer_scale(mScale); + ensureSize(); + } +} + #if QT_CONFIG(cursor) void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor) { - device->setCursor(cursor, screen()); + device->setCursor(cursor, waylandScreen()); } void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device) diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 961b7881d..fca96f30d 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -110,6 +110,7 @@ public: ~QWaylandWindow(); virtual WindowType windowType() const = 0; + virtual void ensureSize(); WId winId() const override; void setVisible(bool visible) override; void setParent(const QPlatformWindow *parent) override; @@ -142,7 +143,7 @@ public: QWaylandDisplay *display() const { return mDisplay; } QWaylandShellSurface *shellSurface() const; QWaylandSubSurface *subSurfaceWindow() const; - QWaylandScreen *screen() const; + QWaylandScreen *waylandScreen() const; void handleContentOrientationChange(Qt::ScreenOrientation orientation) override; void setOrientationMask(Qt::ScreenOrientations mask); @@ -263,6 +264,7 @@ private: QWaylandScreen *calculateScreenFromSurfaceEvents() const; void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e); + void handleScreenChanged(); bool mUpdateRequested; @@ -285,8 +287,8 @@ inline QPoint QWaylandWindow::attachOffset() const return mOffset; } -QT_END_NAMESPACE - } +QT_END_NAMESPACE + #endif // QWAYLANDWINDOW_H diff --git a/src/client/qwaylandwlshellintegration.cpp b/src/client/qwaylandwlshellintegration.cpp index e945745e2..e51637108 100644 --- a/src/client/qwaylandwlshellintegration.cpp +++ b/src/client/qwaylandwlshellintegration.cpp @@ -55,7 +55,7 @@ QWaylandWlShellIntegration *QWaylandWlShellIntegration::create(QWaylandDisplay * } QWaylandWlShellIntegration::QWaylandWlShellIntegration(QWaylandDisplay *display) - : m_wlShell(Q_NULLPTR) + : m_wlShell(nullptr) { Q_FOREACH (QWaylandDisplay::RegistryGlobal global, display->globals()) { if (global.interface == QLatin1String("wl_shell")) { diff --git a/src/client/qwaylandwlshellsurface.cpp b/src/client/qwaylandwlshellsurface.cpp index 92223f45e..185cfc4a9 100644 --- a/src/client/qwaylandwlshellsurface.cpp +++ b/src/client/qwaylandwlshellsurface.cpp @@ -58,7 +58,7 @@ QWaylandWlShellSurface::QWaylandWlShellSurface(struct ::wl_shell_surface *shell_ , m_window(window) , m_maximized(false) , m_fullscreen(false) - , m_extendedWindow(Q_NULLPTR) + , m_extendedWindow(nullptr) { if (window->display()->windowExtension()) m_extendedWindow = new QWaylandExtendedSurface(window); @@ -192,7 +192,7 @@ void QWaylandWlShellSurface::updateTransientParent(QWindow *parent) flags); } -void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial) +void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, uint serial) { QWaylandWindow *parent_wayland_window = parent; if (!parent_wayland_window) { diff --git a/src/client/qwaylandwlshellsurface_p.h b/src/client/qwaylandwlshellsurface_p.h index 94e3417a4..62583949b 100644 --- a/src/client/qwaylandwlshellsurface_p.h +++ b/src/client/qwaylandwlshellsurface_p.h @@ -102,7 +102,7 @@ private: void setTopLevel(); void updateTransientParent(QWindow *parent); - void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial); + void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, uint serial); QWaylandWindow *m_window; bool m_maximized; diff --git a/src/client/qwaylandxdgshellintegration.cpp b/src/client/qwaylandxdgshellintegration.cpp index 04b8e8048..7c40d2dd7 100644 --- a/src/client/qwaylandxdgshellintegration.cpp +++ b/src/client/qwaylandxdgshellintegration.cpp @@ -57,7 +57,7 @@ QWaylandXdgShellIntegration *QWaylandXdgShellIntegration::create(QWaylandDisplay } QWaylandXdgShellIntegration::QWaylandXdgShellIntegration(QWaylandDisplay *display) - : m_xdgShell(Q_NULLPTR) + : m_xdgShell(nullptr) { Q_FOREACH (QWaylandDisplay::RegistryGlobal global, display->globals()) { if (global.interface == QLatin1String("xdg_shell")) { diff --git a/src/client/qwaylandxdgsurface.cpp b/src/client/qwaylandxdgsurface.cpp index fe8761e5b..60266af68 100644 --- a/src/client/qwaylandxdgsurface.cpp +++ b/src/client/qwaylandxdgsurface.cpp @@ -61,7 +61,7 @@ QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *shell, QWaylandWindow * , m_minimized(false) , m_fullscreen(false) , m_active(false) - , m_extendedWindow(Q_NULLPTR) + , m_extendedWindow(nullptr) { if (window->display()->windowExtension()) m_extendedWindow = new QWaylandExtendedSurface(window); @@ -105,7 +105,7 @@ void QWaylandXdgSurface::setMaximized() void QWaylandXdgSurface::setFullscreen() { if (!m_fullscreen) - set_fullscreen(Q_NULLPTR); + set_fullscreen(nullptr); } void QWaylandXdgSurface::setNormal() diff --git a/src/client/shellintegration/qwaylandshellintegrationfactory.cpp b/src/client/shellintegration/qwaylandshellintegrationfactory.cpp index 09c62339b..c5a505bbe 100644 --- a/src/client/shellintegration/qwaylandshellintegrationfactory.cpp +++ b/src/client/shellintegration/qwaylandshellintegrationfactory.cpp @@ -90,7 +90,7 @@ QWaylandShellIntegration *QWaylandShellIntegrationFactory::create(const QString if (QWaylandShellIntegration *ret = qLoadPlugin<QWaylandShellIntegration, QWaylandShellIntegrationPlugin>(loader(), name, args)) return ret; #endif - return Q_NULLPTR; + return nullptr; } } diff --git a/src/compositor/compositor.pro b/src/compositor/compositor.pro index dc9000d90..47be591d7 100644 --- a/src/compositor/compositor.pro +++ b/src/compositor/compositor.pro @@ -30,5 +30,7 @@ include ($$PWD/compositor_api/compositor_api.pri) include ($$PWD/extensions/extensions.pri) MODULE_PLUGIN_TYPES = \ - wayland-graphics-integration-server + wayland-graphics-integration-server \ + wayland-hardware-layer-integration \ + load(qt_module) diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri index 35f57f808..e5df0f1ff 100644 --- a/src/compositor/compositor_api/compositor_api.pri +++ b/src/compositor/compositor_api/compositor_api.pri @@ -26,7 +26,8 @@ HEADERS += \ compositor_api/qwaylandview_p.h \ compositor_api/qwaylandresource.h \ compositor_api/qwaylandsurfacegrabber.h \ - compositor_api/qwaylandoutputmode_p.h + compositor_api/qwaylandoutputmode_p.h \ + compositor_api/qwaylandquickhardwarelayer_p.h \ SOURCES += \ compositor_api/qwaylandcompositor.cpp \ @@ -43,7 +44,8 @@ SOURCES += \ compositor_api/qwaylanddestroylistener.cpp \ compositor_api/qwaylandview.cpp \ compositor_api/qwaylandresource.cpp \ - compositor_api/qwaylandsurfacegrabber.cpp + compositor_api/qwaylandsurfacegrabber.cpp \ + compositor_api/qwaylandquickhardwarelayer.cpp qtConfig(im) { HEADERS += \ diff --git a/src/compositor/compositor_api/qwaylandbufferref.cpp b/src/compositor/compositor_api/qwaylandbufferref.cpp index 57a120e48..8ceeeea56 100644 --- a/src/compositor/compositor_api/qwaylandbufferref.cpp +++ b/src/compositor/compositor_api/qwaylandbufferref.cpp @@ -185,7 +185,7 @@ bool QWaylandBufferRef::isDestroyed() const */ struct ::wl_resource *QWaylandBufferRef::wl_buffer() const { - return d->buffer ? d->buffer->waylandBufferHandle() : Q_NULLPTR; + return d->buffer ? d->buffer->waylandBufferHandle() : nullptr; } /*! diff --git a/src/compositor/compositor_api/qwaylandclient.cpp b/src/compositor/compositor_api/qwaylandclient.cpp index 2b73c06ca..122fd41c3 100644 --- a/src/compositor/compositor_api/qwaylandclient.cpp +++ b/src/compositor/compositor_api/qwaylandclient.cpp @@ -146,7 +146,7 @@ QWaylandClient *QWaylandClient::fromWlClient(QWaylandCompositor *compositor, wl_ if (!wlClient) return 0; - QWaylandClient *client = Q_NULLPTR; + QWaylandClient *client = nullptr; wl_listener *l = wl_client_get_destroy_listener(wlClient, QWaylandClientPrivate::client_destroy_callback); diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 4e7040889..4c662a34a 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -656,7 +656,7 @@ QWaylandOutput *QWaylandCompositor::outputFor(QWindow *window) const return output; } - return Q_NULLPTR; + return nullptr; } /*! @@ -822,7 +822,7 @@ QWaylandSeat *QWaylandCompositor::defaultSeat() const Q_D(const QWaylandCompositor); if (d->seats.size()) return d->seats.first(); - return Q_NULLPTR; + return nullptr; } /*! diff --git a/src/compositor/compositor_api/qwaylandcompositor_p.h b/src/compositor/compositor_api/qwaylandcompositor_p.h index 3970ff152..18595a806 100644 --- a/src/compositor/compositor_api/qwaylandcompositor_p.h +++ b/src/compositor/compositor_api/qwaylandcompositor_p.h @@ -87,7 +87,7 @@ public: void destroySurface(QWaylandSurface *surface); void unregisterSurface(QWaylandSurface *surface); - QWaylandOutput *defaultOutput() const { return outputs.size() ? outputs.first() : Q_NULLPTR; } + QWaylandOutput *defaultOutput() const { return outputs.size() ? outputs.first() : nullptr; } inline QtWayland::ClientBufferIntegration *clientBufferIntegration() const; inline QtWayland::ServerBufferIntegration *serverBufferIntegration() const; diff --git a/src/compositor/compositor_api/qwaylandkeyboard.cpp b/src/compositor/compositor_api/qwaylandkeyboard.cpp index c30f7b18d..930eae1ae 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard.cpp +++ b/src/compositor/compositor_api/qwaylandkeyboard.cpp @@ -122,7 +122,7 @@ void QWaylandKeyboardPrivate::sendEnter(QWaylandSurface *surface, Resource *keyb void QWaylandKeyboardPrivate::focused(QWaylandSurface *surface) { if (surface && surface->isCursorSurface()) - surface = Q_NULLPTR; + surface = nullptr; if (focus != surface) { if (focusResource) { uint32_t serial = compositor()->nextSerial(); @@ -466,7 +466,7 @@ QWaylandClient *QWaylandKeyboard::focusClient() const { Q_D(const QWaylandKeyboard); if (!d->focusResource) - return Q_NULLPTR; + return nullptr; return QWaylandClient::fromWlClient(compositor(), d->focusResource->client()); } diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp index c369bb26c..7627195da 100644 --- a/src/compositor/compositor_api/qwaylandoutput.cpp +++ b/src/compositor/compositor_api/qwaylandoutput.cpp @@ -46,6 +46,7 @@ #include <QtWaylandCompositor/private/qwaylandsurface_p.h> #include <QtWaylandCompositor/private/qwaylandcompositor_p.h> +#include <QtWaylandCompositor/private/qwaylandview_p.h> #include <QtCore/QCoreApplication> #include <QtCore/QtMath> @@ -104,8 +105,8 @@ static QtWaylandServer::wl_output::transform toWlTransform(const QWaylandOutput: QWaylandOutputPrivate::QWaylandOutputPrivate() : QtWaylandServer::wl_output() - , compositor(Q_NULLPTR) - , window(Q_NULLPTR) + , compositor(nullptr) + , window(nullptr) , currentMode(-1) , preferredMode(-1) , subpixel(QWaylandOutput::SubpixelUnknown) @@ -319,7 +320,7 @@ struct ::wl_resource *QWaylandOutput::resourceForClient(QWaylandClient *client) if (r) return r->handle; - return Q_NULLPTR; + return nullptr; } /*! @@ -895,8 +896,10 @@ void QWaylandOutput::sendFrameCallbacks() surfaceEnter(surfacemapper.surface); d->surfaceViews[i].has_entered = true; } - if (surfacemapper.maybePrimaryView()) - surfacemapper.surface->sendFrameCallbacks(); + if (auto primaryView = surfacemapper.maybePrimaryView()) { + if (!QWaylandViewPrivate::get(primaryView)->independentFrameCallback) + surfacemapper.surface->sendFrameCallbacks(); + } } } wl_display_flush_clients(d->compositor->display()); @@ -997,7 +1000,7 @@ void QWaylandOutput::handleSetHeight(int newHeight) void QWaylandOutput::handleWindowDestroyed() { Q_D(QWaylandOutput); - d->window = Q_NULLPTR; + d->window = nullptr; emit windowChanged(); emit windowDestroyed(); } diff --git a/src/compositor/compositor_api/qwaylandoutput_p.h b/src/compositor/compositor_api/qwaylandoutput_p.h index 594fe1291..dab6daf73 100644 --- a/src/compositor/compositor_api/qwaylandoutput_p.h +++ b/src/compositor/compositor_api/qwaylandoutput_p.h @@ -87,7 +87,7 @@ struct QWaylandSurfaceViewMapper if (surface && surface->primaryView() == views.at(i)) return views.at(i); } - return Q_NULLPTR; + return nullptr; } QWaylandSurface *surface; diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp index bf4bf547d..4bdee9be2 100644 --- a/src/compositor/compositor_api/qwaylandpointer.cpp +++ b/src/compositor/compositor_api/qwaylandpointer.cpp @@ -133,7 +133,7 @@ void QWaylandPointerPrivate::pointer_set_cursor(wl_pointer::Resource *resource, Q_UNUSED(serial); if (!surface) { - seat->cursorSurfaceRequest(Q_NULLPTR, 0, 0); + seat->cursorSurfaceRequest(nullptr, 0, 0); return; } @@ -250,7 +250,7 @@ void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &loca { Q_D(QWaylandPointer); if (view && (!view->surface() || view->surface()->isCursorSurface())) - view = Q_NULLPTR; + view = nullptr; d->seat->setMouseFocus(view); d->localPosition = localPos; d->spacePosition = outputSpacePos; diff --git a/src/compositor/compositor_api/qwaylandquickhardwarelayer.cpp b/src/compositor/compositor_api/qwaylandquickhardwarelayer.cpp new file mode 100644 index 000000000..f82de0014 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandquickhardwarelayer.cpp @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandquickhardwarelayer_p.h" + +#include <QtWaylandCompositor/private/qwlhardwarelayerintegration_p.h> +#include <QtWaylandCompositor/private/qwlhardwarelayerintegrationfactory_p.h> + +#include <QtCore/private/qobject_p.h> +#include <QMatrix4x4> + +QT_BEGIN_NAMESPACE + +class QWaylandQuickHardwareLayerPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QWaylandQuickHardwareLayer) +public: + QtWayland::HardwareLayerIntegration *layerIntegration(); + QWaylandQuickItem *m_waylandItem = nullptr; + int m_stackingLevel = 0; + QMatrix4x4 m_matrixFromRenderThread; + static QtWayland::HardwareLayerIntegration *s_hardwareLayerIntegration; +}; + +QtWayland::HardwareLayerIntegration *QWaylandQuickHardwareLayerPrivate::s_hardwareLayerIntegration = nullptr; + +QtWayland::HardwareLayerIntegration *QWaylandQuickHardwareLayerPrivate::layerIntegration() +{ + if (!s_hardwareLayerIntegration) { + QStringList keys = QtWayland::HardwareLayerIntegrationFactory::keys(); + + QString environmentKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_HARDWARE_LAYER_INTEGRATION").constData()); + if (!environmentKey.isEmpty()) { + if (keys.contains(environmentKey)) { + s_hardwareLayerIntegration = QtWayland::HardwareLayerIntegrationFactory::create(environmentKey, QStringList()); + } else { + qWarning() << "Unknown hardware layer integration:" << environmentKey + << "Valid layer integrations are" << keys; + } + } else if (!keys.isEmpty()) { + s_hardwareLayerIntegration = QtWayland::HardwareLayerIntegrationFactory::create(keys.first(), QStringList()); + } else { + qWarning() << "No wayland hardware layer integrations found"; + } + } + + return s_hardwareLayerIntegration; +} + +/*! + * \qmltype WaylandHardwareLayer + * \inqmlmodule QtWayland.Compositor + * \preliminary + * \brief Makes a parent WaylandQuickItem use hardware layers for rendering + * + * This item needs to be a descendant of a WaylandQuickItem or a derivative, + * (i.e. ShellSurfaceItem or similar) + * + * The Surface of the parent WaylandQuickItem will be drawn in a hardware specific way instead + * of the regular way using the QtQuick scene graph. On some platforms, the WaylandQuickItem's + * current buffer and the scene graph can be blended in a separate step. This makes it possible for + * clients to update continuously without triggering a full redraw of the compositor scene graph for + * each frame. + * + * The preferred hardware layer integration may be overridden by setting the + * QT_WAYLAND_HARDWARE_LAYER_INTEGRATION environment variable. + */ + +QWaylandQuickHardwareLayer::QWaylandQuickHardwareLayer(QObject *parent) + : QObject(*new QWaylandQuickHardwareLayerPrivate(), parent) +{ +} + +QWaylandQuickHardwareLayer::~QWaylandQuickHardwareLayer() +{ + Q_D(QWaylandQuickHardwareLayer); + if (d->layerIntegration()) + d->layerIntegration()->remove(this); +} + +/*! + * \qmlproperty int QtWaylandCompositor::WaylandHardwareLayer::stackingLevel + * + * This property holds the stacking level of this hardware layer relative to other hardware layers, + * and can be used to sort hardware layers. I.e. a layer with a higher level is rendered on top of + * one with a lower level. + * + * Layers with level 0 will be drawn in an implementation defined order on top of the compositor + * scene graph. + * + * Layers with a level below 0 are drawn beneath the compositor scene graph, if supported by the + * hardware layer integration. + */ +int QWaylandQuickHardwareLayer::stackingLevel() const +{ + Q_D(const QWaylandQuickHardwareLayer); + return d->m_stackingLevel; +} + +void QWaylandQuickHardwareLayer::setStackingLevel(int level) +{ + Q_D(QWaylandQuickHardwareLayer); + if (level == d->m_stackingLevel) + return; + + d->m_stackingLevel = level; + emit stackingLevelChanged(); +} + +QWaylandQuickItem *QWaylandQuickHardwareLayer::waylandItem() const +{ + Q_D(const QWaylandQuickHardwareLayer); + return d->m_waylandItem; +} + +void QWaylandQuickHardwareLayer::classBegin() +{ + Q_D(QWaylandQuickHardwareLayer); + for (QObject *p = parent(); p != nullptr; p = p->parent()) { + if (auto *waylandItem = qobject_cast<QWaylandQuickItem *>(p)) { + d->m_waylandItem = waylandItem; + break; + } + } +} + +void QWaylandQuickHardwareLayer::componentComplete() +{ + Q_D(QWaylandQuickHardwareLayer); + Q_ASSERT(d->m_waylandItem); + if (auto integration = d->layerIntegration()) + integration->add(this); + else + qWarning() << "No hardware layer integration. WaylandHarwareLayer has no effect."; +} + +void QWaylandQuickHardwareLayer::disableSceneGraphPainting() +{ + waylandItem()->setPaintEnabled(false); +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquickhardwarelayer_p.h b/src/compositor/compositor_api/qwaylandquickhardwarelayer_p.h new file mode 100644 index 000000000..24cb709f4 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandquickhardwarelayer_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDQUICKHARDWARELAYER_P_H +#define QWAYLANDQUICKHARDWARELAYER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/QWaylandQuickItem> + +QT_BEGIN_NAMESPACE + +class QWaylandQuickHardwareLayerPrivate; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickHardwareLayer : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + Q_DECLARE_PRIVATE(QWaylandQuickHardwareLayer) + Q_PROPERTY(int stackingLevel READ stackingLevel WRITE setStackingLevel NOTIFY stackingLevelChanged) +public: + explicit QWaylandQuickHardwareLayer(QObject *parent = nullptr); + ~QWaylandQuickHardwareLayer() override; + + int stackingLevel() const; + void setStackingLevel(int level); + + QWaylandQuickItem *waylandItem() const; + + void classBegin() override; + void componentComplete() override; + + void disableSceneGraphPainting(); + +Q_SIGNALS: + void stackingLevelChanged(); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDQUICKHARDWARELAYER_P_H diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index 5414d06ae..74ce326e5 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -384,7 +384,7 @@ QWaylandQuickItem::~QWaylandQuickItem() QWaylandCompositor *QWaylandQuickItem::compositor() const { Q_D(const QWaylandQuickItem); - return d->view->surface() ? d->view->surface()->compositor() : Q_NULLPTR; + return d->view->surface() ? d->view->surface()->compositor() : nullptr; } /*! @@ -587,7 +587,7 @@ void QWaylandQuickItem::hoverLeaveEvent(QHoverEvent *event) Q_D(QWaylandQuickItem); if (d->shouldSendInputEvents()) { QWaylandSeat *seat = compositor()->seatFor(event); - seat->setMouseFocus(Q_NULLPTR); + seat->setMouseFocus(nullptr); } else { event->ignore(); } @@ -949,9 +949,14 @@ void QWaylandQuickItem::parentChanged(QWaylandSurface *newParent, QWaylandSurfac void QWaylandQuickItem::updateSize() { Q_D(QWaylandQuickItem); - if (d->sizeFollowsSurface && surface()) { - setSize(surface()->size() * (d->scaleFactor() / surface()->bufferScale())); - } + + QSize size(0, 0); + if (surface()) + size = surface()->size() * (d->scaleFactor() / surface()->bufferScale()); + + setImplicitSize(size.width(), size.height()); + if (d->sizeFollowsSurface) + setSize(size); } /*! @@ -1006,7 +1011,13 @@ bool QWaylandQuickItem::inputRegionContains(const QPointF &localPosition) QPointF QWaylandQuickItem::mapToSurface(const QPointF &point) const { Q_D(const QWaylandQuickItem); - return point / d->scaleFactor(); + if (!surface() || surface()->size().isEmpty()) + return point / d->scaleFactor(); + + qreal xScale = width() / surface()->size().width(); + qreal yScale = height() / surface()->size().height(); + + return QPointF(point.x() / xScale, point.y() / yScale); } /*! @@ -1032,6 +1043,9 @@ bool QWaylandQuickItem::sizeFollowsSurface() const return d->sizeFollowsSurface; } +//TODO: sizeFollowsSurface became obsolete when we added an implementation for +//implicit size. The property is here for compatibility reasons only and should +//be removed or at least default to false in Qt 6. void QWaylandQuickItem::setSizeFollowsSurface(bool sizeFollowsSurface) { Q_D(QWaylandQuickItem); @@ -1066,14 +1080,14 @@ QVariant QWaylandQuickItem::inputMethodQuery(Qt::InputMethodQuery query, QVarian Returns true if the item is hidden, though the texture is still updated. As opposed to hiding the item by - setting \l{Item::visible}{visible} to \c false, setting this property to \c true + setting \l{Item::visible}{visible} to \c false, setting this property to \c false will not prevent mouse or keyboard input from reaching item. */ /*! Returns true if the item is hidden, though the texture is still updated. As opposed to hiding the item by - setting \l{Item::visible}{visible} to \c false, setting this property to \c true + setting \l{Item::visible}{visible} to \c false, setting this property to \c false will not prevent mouse or keyboard input from reaching item. */ bool QWaylandQuickItem::paintEnabled() const @@ -1176,9 +1190,10 @@ void QWaylandQuickItem::updateInputMethod(Qt::InputMethodQueries queries) * \sa QWaylandQuickkItem::bufferLocked */ -QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) { Q_D(QWaylandQuickItem); + d->lastMatrix = data->transformNode->combinedMatrix(); const bool bufferHasContent = d->view->currentBuffer().hasContent(); if (d->view->isBufferLocked() && !bufferHasContent && d->paintEnabled) @@ -1186,7 +1201,7 @@ QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat if (!bufferHasContent || !d->paintEnabled) { delete oldNode; - return 0; + return nullptr; } QWaylandBufferRef ref = d->view->currentBuffer(); diff --git a/src/compositor/compositor_api/qwaylandquickitem.h b/src/compositor/compositor_api/qwaylandquickitem.h index cd44a4fbc..11457fa6e 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.h +++ b/src/compositor/compositor_api/qwaylandquickitem.h @@ -184,7 +184,7 @@ Q_SIGNALS: void bufferLockedChanged(); void allowDiscardFrontBufferChanged(); protected: - QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override; + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) override; QWaylandQuickItem(QWaylandQuickItemPrivate &dd, QQuickItem *parent = nullptr); }; diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h index 30b96c4f6..400cda742 100644 --- a/src/compositor/compositor_api/qwaylandquickitem_p.h +++ b/src/compositor/compositor_api/qwaylandquickitem_p.h @@ -109,9 +109,9 @@ class QWaylandQuickItemPrivate : public QQuickItemPrivate public: QWaylandQuickItemPrivate() : QQuickItemPrivate() - , view(Q_NULLPTR) - , oldSurface(Q_NULLPTR) - , provider(Q_NULLPTR) + , view(nullptr) + , oldSurface(nullptr) + , provider(nullptr) , paintEnabled(true) , touchEventsEnabled(true) , inputEventsEnabled(true) @@ -119,7 +119,7 @@ public: , newTexture(false) , focusOnClick(true) , sizeFollowsSurface(true) - , connectedWindow(Q_NULLPTR) + , connectedWindow(nullptr) , origin(QWaylandSurface::OriginTopLeft) { } @@ -149,6 +149,8 @@ public: q->updateWindow(); } + static const QWaylandQuickItemPrivate* get(const QWaylandQuickItem *item) { return item->d_func(); } + void setInputEventsEnabled(bool enable) { Q_Q(QWaylandQuickItem); @@ -177,6 +179,7 @@ public: bool focusOnClick; bool sizeFollowsSurface; QPoint hoverPos; + QMatrix4x4 lastMatrix; QQuickWindow *connectedWindow; QWaylandSurface::Origin origin; diff --git a/src/compositor/compositor_api/qwaylandquicksurface.cpp b/src/compositor/compositor_api/qwaylandquicksurface.cpp index ec68ee6a1..1197e9e43 100644 --- a/src/compositor/compositor_api/qwaylandquicksurface.cpp +++ b/src/compositor/compositor_api/qwaylandquicksurface.cpp @@ -49,9 +49,6 @@ #include <QtWaylandCompositor/QWaylandView> #include <QtWaylandCompositor/private/qwaylandsurface_p.h> -#include <QtWaylandCompositor/private/qwayland-server-surface-extension.h> -#include <QtWaylandCompositor/private/qwlextendedsurface_p.h> - QT_BEGIN_NAMESPACE class QWaylandQuickSurfacePrivate : public QWaylandSurfacePrivate @@ -112,8 +109,11 @@ void QWaylandQuickSurface::setUseTextureAlpha(bool useTextureAlpha) /*! * \qmlproperty bool QtWaylandCompositor::WaylandSurface::clientRenderingEnabled + * \deprecated * - * This property specifies whether client rendering is enabled for the surface. + * This property used to specify whether client rendering was enabled for the surface. + * It depended on a Wayland extension that was part of the private API. The surface extension + * is not used anymore, so this property does nothing. */ bool QWaylandQuickSurface::clientRenderingEnabled() const { @@ -124,12 +124,9 @@ bool QWaylandQuickSurface::clientRenderingEnabled() const void QWaylandQuickSurface::setClientRenderingEnabled(bool enabled) { Q_D(QWaylandQuickSurface); + qWarning() << Q_FUNC_INFO << "doesn't do anything"; if (d->clientRenderingEnabled != enabled) { d->clientRenderingEnabled = enabled; - - if (QtWayland::ExtendedSurface *extSurface = QtWayland::ExtendedSurface::findIn(this)) - extSurface->setVisibility(enabled ? QWindow::AutomaticVisibility : QWindow::Hidden); - emit clientRenderingEnabledChanged(); } } diff --git a/src/compositor/compositor_api/qwaylandquicksurface.h b/src/compositor/compositor_api/qwaylandquicksurface.h index 7ec08e123..273fb25f4 100644 --- a/src/compositor/compositor_api/qwaylandquicksurface.h +++ b/src/compositor/compositor_api/qwaylandquicksurface.h @@ -63,12 +63,12 @@ public: bool useTextureAlpha() const; void setUseTextureAlpha(bool useTextureAlpha); - bool clientRenderingEnabled() const; - void setClientRenderingEnabled(bool enabled); + Q_DECL_DEPRECATED bool clientRenderingEnabled() const; + Q_DECL_DEPRECATED void setClientRenderingEnabled(bool enabled); Q_SIGNALS: void useTextureAlphaChanged(); - void clientRenderingEnabledChanged(); + void clientRenderingEnabledChanged(); //deprecated }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandseat.cpp b/src/compositor/compositor_api/qwaylandseat.cpp index b4b45392c..4b506bcda 100644 --- a/src/compositor/compositor_api/qwaylandseat.cpp +++ b/src/compositor/compositor_api/qwaylandseat.cpp @@ -65,7 +65,7 @@ QWaylandSeatPrivate::QWaylandSeatPrivate(QWaylandSeat *seat) , QtWaylandServer::wl_seat() , isInitialized(false) , compositor(nullptr) - , mouseFocus(Q_NULLPTR) + , mouseFocus(nullptr) , keyboardFocus(nullptr) , capabilities() #if QT_CONFIG(wayland_datadevice) @@ -298,7 +298,93 @@ uint QWaylandSeat::sendTouchPointEvent(QWaylandSurface *surface, int id, const Q } /*! - * Sends a frame event to the touch device of a \a client. + * \qmlmethod uint QtWaylandCompositor::WaylandSeat::sendTouchPointPressed(WaylandSurface surface, int id, point position) + * + * Sends a touch pressed event for the touch point \a id on \a surface with + * position \a position. + * + * \note You need to send a touch frame event when you are done sending touch + * events. + * + * Returns the serial for the touch down event. + */ + +/*! + * Sends a touch pressed event for the touch point \a id on \a surface with + * position \a position. + * + * \note You need to send a touch frame event when you are done sending touch + * events. + * + * Returns the serial for the touch down event. + */ +uint QWaylandSeat::sendTouchPointPressed(QWaylandSurface *surface, int id, const QPointF &position) +{ + return sendTouchPointEvent(surface, id, position, Qt::TouchPointPressed); +} + +/*! + * \qmlmethod void QtWaylandCompositor::WaylandSeat::sendTouchPointReleased(WaylandSurface surface, int id, point position) + * + * Sends a touch released event for the touch point \a id on \a surface with + * position \a position. + * + * \note You need to send a touch frame event when you are done sending touch + * events. + * + * Returns the serial for the touch up event. + */ + +/*! + * Sends a touch released event for the touch point \a id on \a surface with + * position \a position. + * + * \note You need to send a touch frame event when you are done sending touch + * events. + * + * Returns the serial for the touch up event. + */ +uint QWaylandSeat::sendTouchPointReleased(QWaylandSurface *surface, int id, const QPointF &position) +{ + return sendTouchPointEvent(surface, id, position, Qt::TouchPointReleased); +} + +/*! + * \qmlmethod void QtWaylandCompositor::WaylandSeat::sendTouchPointMoved(WaylandSurface surface, int id, point position) + * + * Sends a touch moved event for the touch point \a id on \a surface with + * position \a position. + * + * \note You need to send a touch frame event when you are done sending touch + * events. + * + * Returns the serial for the touch motion event. + */ + +/*! + * Sends a touch moved event for the touch point \a id on \a surface with + * position \a position. + * + * \note You need to send a touch frame event when you are done sending touch + * events. + * + * Returns the serial for the touch motion event. + */ +uint QWaylandSeat::sendTouchPointMoved(QWaylandSurface *surface, int id, const QPointF &position) +{ + return sendTouchPointEvent(surface, id, position, Qt::TouchPointMoved); +} + +/*! + * \qmlmethod void QtWaylandCompositor::WaylandSeat::sendTouchFrameEvent(WaylandClient client) + * + * Sends a frame event to the touch device of a \a client to indicate the end + * of a series of touch up, down, and motion events. + */ + +/*! + * Sends a frame event to the touch device of a \a client to indicate the end + * of a series of touch up, down, and motion events. */ void QWaylandSeat::sendTouchFrameEvent(QWaylandClient *client) { @@ -308,6 +394,12 @@ void QWaylandSeat::sendTouchFrameEvent(QWaylandClient *client) } /*! + * \qmlmethod void QtWaylandCompositor::WaylandSeat::sendTouchCancelEvent(WaylandClient client) + * + * Sends a cancel event to the touch device of a \a client. + */ + +/*! * Sends a cancel event to the touch device of a \a client. */ void QWaylandSeat::sendTouchCancelEvent(QWaylandClient *client) @@ -381,7 +473,7 @@ QWaylandSurface *QWaylandSeat::keyboardFocus() const { Q_D(const QWaylandSeat); if (d->keyboard.isNull() || !d->keyboard->focus()) - return Q_NULLPTR; + return nullptr; return d->keyboard->focus(); } diff --git a/src/compositor/compositor_api/qwaylandseat.h b/src/compositor/compositor_api/qwaylandseat.h index e5ef46dc6..d22e05a5b 100644 --- a/src/compositor/compositor_api/qwaylandseat.h +++ b/src/compositor/compositor_api/qwaylandseat.h @@ -99,8 +99,11 @@ public: void sendFullKeyEvent(QKeyEvent *event); uint sendTouchPointEvent(QWaylandSurface *surface, int id, const QPointF &point, Qt::TouchPointState state); - void sendTouchFrameEvent(QWaylandClient *client); - void sendTouchCancelEvent(QWaylandClient *client); + Q_INVOKABLE uint sendTouchPointPressed(QWaylandSurface *surface, int id, const QPointF &position); + Q_INVOKABLE uint sendTouchPointReleased(QWaylandSurface *surface, int id, const QPointF &position); + Q_INVOKABLE uint sendTouchPointMoved(QWaylandSurface *surface, int id, const QPointF &position); + Q_INVOKABLE void sendTouchFrameEvent(QWaylandClient *client); + Q_INVOKABLE void sendTouchCancelEvent(QWaylandClient *client); void sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event); diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 05113c41c..37b6876ac 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -49,7 +49,6 @@ #include "wayland_wrapper/qwldatadevicemanager_p.h" #endif -#include "extensions/qwlextendedsurface_p.h" #include "qwaylandinputmethodcontrol_p.h" #include <QtWaylandCompositor/QWaylandCompositor> @@ -127,9 +126,9 @@ QList<QWaylandSurfacePrivate *> QWaylandSurfacePrivate::uninitializedSurfaces; QWaylandSurfacePrivate::QWaylandSurfacePrivate() : QtWaylandServer::wl_surface() - , compositor(Q_NULLPTR) + , compositor(nullptr) , refCount(1) - , client(Q_NULLPTR) + , client(nullptr) , role(0) , inputRegion(infiniteRegion()) , bufferScale(1) @@ -139,7 +138,7 @@ QWaylandSurfacePrivate::QWaylandSurfacePrivate() , isInitialized(false) , contentOrientation(Qt::PrimaryOrientation) #if QT_CONFIG(im) - , inputMethodControl(Q_NULLPTR) + , inputMethodControl(nullptr) #endif , subsurface(0) { @@ -459,7 +458,7 @@ QWaylandClient *QWaylandSurface::client() const { Q_D(const QWaylandSurface); if (isDestroyed() || !compositor() || !compositor()->clients().contains(d->client)) - return Q_NULLPTR; + return nullptr; return d->client; } @@ -603,7 +602,7 @@ void QWaylandSurface::sendFrameCallbacks() int i = 0; while (i < d->frameCallbacks.size()) { if (d->frameCallbacks.at(i)->canSend) { - d->frameCallbacks.at(i)->surface = Q_NULLPTR; + d->frameCallbacks.at(i)->surface = nullptr; d->frameCallbacks.at(i)->send(time); d->frameCallbacks.removeAt(i); } else { @@ -716,7 +715,7 @@ QWaylandView *QWaylandSurface::primaryView() const { Q_D(const QWaylandSurface); if (d->views.isEmpty()) - return Q_NULLPTR; + return nullptr; return d->views.first(); } @@ -808,7 +807,7 @@ QWaylandSurfaceRole *QWaylandSurface::role() const QWaylandSurfacePrivate *QWaylandSurfacePrivate::get(QWaylandSurface *surface) { - return surface ? surface->d_func() : Q_NULLPTR; + return surface ? surface->d_func() : nullptr; } void QWaylandSurfacePrivate::ref() diff --git a/src/compositor/compositor_api/qwaylandsurfacegrabber.h b/src/compositor/compositor_api/qwaylandsurfacegrabber.h index ce1e397e5..c28614f37 100644 --- a/src/compositor/compositor_api/qwaylandsurfacegrabber.h +++ b/src/compositor/compositor_api/qwaylandsurfacegrabber.h @@ -60,7 +60,7 @@ public: RendererNotReady, }; Q_ENUM(Error) - explicit QWaylandSurfaceGrabber(QWaylandSurface *surface, QObject *parent = Q_NULLPTR); + explicit QWaylandSurfaceGrabber(QWaylandSurface *surface, QObject *parent = nullptr); QWaylandSurface *surface() const; void grab(); diff --git a/src/compositor/compositor_api/qwaylandview.cpp b/src/compositor/compositor_api/qwaylandview.cpp index 9e8297574..4d6f392e1 100644 --- a/src/compositor/compositor_api/qwaylandview.cpp +++ b/src/compositor/compositor_api/qwaylandview.cpp @@ -55,7 +55,7 @@ void QWaylandViewPrivate::markSurfaceAsDestroyed(QWaylandSurface *surface) Q_Q(QWaylandView); Q_ASSERT(surface == this->surface); - q->setSurface(Q_NULLPTR); + q->setSurface(nullptr); emit q->surfaceDestroyed(); } @@ -376,7 +376,7 @@ struct wl_resource *QWaylandView::surfaceResource() const { Q_D(const QWaylandView); if (!d->surface) - return Q_NULLPTR; + return nullptr; return d->surface->resource(); } diff --git a/src/compositor/compositor_api/qwaylandview_p.h b/src/compositor/compositor_api/qwaylandview_p.h index 326e0b297..1cc55954c 100644 --- a/src/compositor/compositor_api/qwaylandview_p.h +++ b/src/compositor/compositor_api/qwaylandview_p.h @@ -40,6 +40,8 @@ #ifndef QWAYLANDSURFACEVIEW_P_H #define QWAYLANDSURFACEVIEW_P_H +#include "qwaylandview.h" + #include <QtCore/QPoint> #include <QtCore/QMutex> #include <QtCore/private/qobject_p.h> @@ -69,9 +71,9 @@ public: static QWaylandViewPrivate *get(QWaylandView *view) { return view->d_func(); } QWaylandViewPrivate() - : renderObject(Q_NULLPTR) - , surface(Q_NULLPTR) - , output(Q_NULLPTR) + : renderObject(nullptr) + , surface(nullptr) + , output(nullptr) , nextBufferCommitted(false) , bufferLocked(false) , broadcastRequestedPositionChanged(false) @@ -95,6 +97,7 @@ public: bool broadcastRequestedPositionChanged; bool forceAdvanceSucceed; bool allowDiscardFrontBuffer; + bool independentFrameCallback = false; //If frame callbacks are independent of the main quick scene graph }; QT_END_NAMESPACE diff --git a/src/compositor/configure.json b/src/compositor/configure.json index a95c4eb01..21f486d78 100644 --- a/src/compositor/configure.json +++ b/src/compositor/configure.json @@ -22,6 +22,26 @@ "-lEGL" ] }, + "wayland-kms": { + "label": "wayland-kms", + "test": { + "tail": [ + "extern \"C\" {", + "#define private priv", + "#include <wayland-kms.h>", + "#undef private", + "}" + ], + "main": [ + "struct wl_resource *buffer = nullptr;", + "struct wl_kms_buffer *kmsBuffer = wayland_kms_buffer_get(buffer);" + ] + }, + "sources": [ + { "type": "pkgConfig", "args": "wayland-kms" }, + "-lwayland-kms" + ] + }, "xcomposite": { "test": "xcomposite", "sources": [ @@ -95,10 +115,22 @@ "label": "libhybris EGL", "condition": "features.wayland-server && features.opengl && features.egl && tests.libhybris-egl-server", "output": [ "privateFeature" ] + }, + "wayland-layer-integration-vsp2": { + "label": "VSP2 hardware layer integration", + "condition": "features.wayland-server && features.eglfs_vsp2 && libs.wayland-kms", + "output": [ "privateFeature" ] } }, "summary": [ - "wayland-server" + "wayland-server", + { + "section": "Qt Wayland Compositor Layer Plugins", + "condition": "features.wayland-server", + "entries": [ + "wayland-layer-integration-vsp2" + ] + } ] } diff --git a/src/compositor/doc/qtwaylandcompositor.qdocconf b/src/compositor/doc/qtwaylandcompositor.qdocconf index 73331aa09..f520c98ba 100644 --- a/src/compositor/doc/qtwaylandcompositor.qdocconf +++ b/src/compositor/doc/qtwaylandcompositor.qdocconf @@ -29,7 +29,7 @@ qhp.QtWaylandCompositor.subprojects.examples.indexTitle = Qt Wayland Composi qhp.QtWaylandCompositor.subprojects.examples.selectors = fake:example qhp.QtWaylandCompositor.subprojects.examples.sortPages = true -depends += qtqml qtquick qtdoc qtquickcontrols qmake qtgui +depends += qtcore qtqml qtquick qtdoc qtquickcontrols qmake qtgui exampledirs += ../../../examples/wayland headerdirs += .. diff --git a/src/compositor/extensions/extensions.pri b/src/compositor/extensions/extensions.pri index 9cb0bcfa1..68e473e14 100644 --- a/src/compositor/extensions/extensions.pri +++ b/src/compositor/extensions/extensions.pri @@ -2,7 +2,6 @@ CONFIG += wayland-scanner CONFIG += generated_privates WAYLANDSERVERSOURCES += \ - ../extensions/surface-extension.xml \ ../extensions/touch-extension.xml \ ../extensions/qtkey-extension.xml \ ../extensions/qt-windowmanager.xml \ @@ -12,7 +11,6 @@ WAYLANDSERVERSOURCES += \ ../3rdparty/protocol/ivi-application.xml \ HEADERS += \ - extensions/qwlextendedsurface_p.h \ extensions/qwlqttouch_p.h \ extensions/qwlqtkey_p.h \ extensions/qwaylandshell.h \ @@ -36,7 +34,6 @@ HEADERS += \ extensions/qwaylandivisurface_p.h \ SOURCES += \ - extensions/qwlextendedsurface.cpp \ extensions/qwlqttouch.cpp \ extensions/qwlqtkey.cpp \ extensions/qwaylandshell.cpp \ @@ -46,6 +43,7 @@ SOURCES += \ extensions/qwaylandqtwindowmanager.cpp \ extensions/qwaylandxdgshellv5.cpp \ extensions/qwaylandxdgshellv6.cpp \ + extensions/qwaylandshellsurface.cpp \ extensions/qwaylandiviapplication.cpp \ extensions/qwaylandivisurface.cpp \ diff --git a/src/compositor/extensions/qwaylandshellsurface.cpp b/src/compositor/extensions/qwaylandshellsurface.cpp new file mode 100644 index 000000000..c1cd5272e --- /dev/null +++ b/src/compositor/extensions/qwaylandshellsurface.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWaylandCompositor/QWaylandShellSurface> + +/*! + * \qmltype ShellSurface + * \inqmlmodule QtWayland.Compositor + * \since 5.8 + * \brief Provides a common interface for surface roles specified by shell extensions + * + * This interface represents a Wayland surface role given by a Wayland protocol extension that + * defines how the WaylandSurface should map onto the screen. + * + * Note: Even though this type contains a very limited API, the properties and signals of the + * implementations are named consistently. For example, if you're only using desktop shell + * extensions in your compositor, it's safe to access properties such as title, maximized, etc. + * directly on the ShellSurface. See the various implementations for additional properties and + * signals. + * + * \sa WaylandSurface, ShellSurfaceItem, WlShellSurface, XdgSurfaceV5, IviSurface + */ + +/*! + * \class QWaylandShellSurface + * \inmodule QtWaylandCompositor + * \since 5.8 + * \brief The QWaylandShellSurface class is a common interface for surface roles specified by shell extensions + * + * This interface represents a Wayland surface role given by a Wayland protocol extension that + * defines how the QWaylandSurface should map onto the screen. + * + * \sa QWaylandSurface, QWaylandWlShellSurface, QWaylandXdgSurfaceV5, QWaylandIviSurface + */ + +#ifdef QT_WAYLAND_COMPOSITOR_QUICK +/*! + * \fn QWaylandQuickShellIntegration *QWaylandShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) + * + * Creates a QWaylandQuickShellIntegration for this QWaylandQuickShellSurface. It's called + * automatically when QWaylandQuickShellSurfaceItem::shellSurface is assigned. + * + * \sa QWaylandQuickShellSurfaceItem + */ +#endif + +/*! + * \qmlproperty enum QtWaylandCompositor::ShellSurface::windowType + * + * This property holds the window type of the ShellSurface. + */ + +/*! + * \property QWaylandWlShellSurface::windowType + * + * This property holds the window type of the QWaylandShellSurface. + */ diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp index 4cdbb0a3a..c588c1063 100644 --- a/src/compositor/extensions/qwaylandwlshell.cpp +++ b/src/compositor/extensions/qwaylandwlshell.cpp @@ -104,8 +104,8 @@ void QWaylandWlShellPrivate::unregisterShellSurface(QWaylandWlShellSurface *shel QWaylandWlShellSurfacePrivate::QWaylandWlShellSurfacePrivate() : QWaylandCompositorExtensionPrivate() , wl_shell_surface() - , m_shell(Q_NULLPTR) - , m_surface(Q_NULLPTR) + , m_shell(nullptr) + , m_surface(nullptr) , m_windowType(Qt::WindowType::Window) { } @@ -195,7 +195,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_fullscreen(Resource *resou Q_Q(QWaylandWlShellSurface); QWaylandOutput *output = output_resource ? QWaylandOutput::fromResource(output_resource) - : Q_NULLPTR; + : nullptr; setWindowType(Qt::WindowType::Window); emit q->setFullScreen(QWaylandWlShellSurface::FullScreenMethod(method), framerate, output); } @@ -220,7 +220,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_maximized(Resource *resour Q_Q(QWaylandWlShellSurface); QWaylandOutput *output = output_resource ? QWaylandOutput::fromResource(output_resource) - : Q_NULLPTR; + : nullptr; setWindowType(Qt::WindowType::Window); emit q->setMaximized(output); } diff --git a/src/compositor/extensions/qwlextendedsurface.cpp b/src/compositor/extensions/qwlextendedsurface.cpp deleted file mode 100644 index b0850f0e2..000000000 --- a/src/compositor/extensions/qwlextendedsurface.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlextendedsurface_p.h" - -#include <QtWaylandCompositor/QWaylandCompositor> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -SurfaceExtensionGlobal::SurfaceExtensionGlobal(QWaylandCompositor *compositor) - : QWaylandCompositorExtensionTemplate(compositor) - , QtWaylandServer::qt_surface_extension(compositor->display(), 1) -{ -} - -void SurfaceExtensionGlobal::surface_extension_get_extended_surface(Resource *resource, - uint32_t id, - struct wl_resource *surface_resource) -{ - QWaylandSurface *surface = QWaylandSurface::fromResource(surface_resource); - ExtendedSurface *extSurface = new ExtendedSurface(resource->client(),id, wl_resource_get_version(resource->handle), surface); - emit extendedSurfaceReady(extSurface, surface); -} - -ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, int version, QWaylandSurface *surface) - : QWaylandCompositorExtensionTemplate(surface) - , QtWaylandServer::qt_extended_surface(client, id, version) - , m_surface(surface) - , m_windowFlags(0) -{ -} - -ExtendedSurface::~ExtendedSurface() -{ -} - -void ExtendedSurface::sendGenericProperty(const QString &name, const QVariant &variant) -{ - QByteArray byteValue; - QDataStream ds(&byteValue, QIODevice::WriteOnly); - ds << variant; - send_set_generic_property(name, byteValue); - -} - -void ExtendedSurface::sendOnScreenVisibilityChange(bool onScreen) -{ - setVisibility(onScreen ? QWindow::AutomaticVisibility : QWindow::Hidden); -} - -void ExtendedSurface::setVisibility(QWindow::Visibility visibility) -{ - send_onscreen_visibility(visibility); -} - -void ExtendedSurface::setParentSurface(QWaylandSurface *surface) -{ - m_surface = surface; -} - -void ExtendedSurface::extended_surface_update_generic_property(Resource *resource, - const QString &name, - struct wl_array *value) -{ - Q_UNUSED(resource); - QVariant variantValue; - QByteArray byteValue((const char*)value->data, value->size); - QDataStream ds(&byteValue, QIODevice::ReadOnly); - ds >> variantValue; - setWindowPropertyImpl(name,variantValue); -} - -Qt::ScreenOrientations ExtendedSurface::contentOrientationMask() const -{ - return m_contentOrientationMask; -} - -void ExtendedSurface::extended_surface_set_content_orientation_mask(Resource *resource, int32_t orientation) -{ - Q_UNUSED(resource); - Qt::ScreenOrientations mask = 0; - if (orientation & QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION) - mask |= Qt::PortraitOrientation; - if (orientation & QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION) - mask |= Qt::LandscapeOrientation; - if (orientation & QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION) - mask |= Qt::InvertedPortraitOrientation; - if (orientation & QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION) - mask |= Qt::InvertedLandscapeOrientation; - if (orientation & QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION) - mask |= Qt::PrimaryOrientation; - - Qt::ScreenOrientations oldMask = m_contentOrientationMask; - m_contentOrientationMask = mask; - - if (mask != oldMask) - emit contentOrientationMaskChanged(); -} - -QVariantMap ExtendedSurface::windowProperties() const -{ - return m_windowProperties; -} - -QVariant ExtendedSurface::windowProperty(const QString &propertyName) const -{ - QVariantMap props = m_windowProperties; - return props.value(propertyName); -} - -void ExtendedSurface::setWindowProperty(const QString &name, const QVariant &value) -{ - setWindowPropertyImpl(name,value); - sendGenericProperty(name, value); -} - -void ExtendedSurface::setWindowPropertyImpl(const QString &name, const QVariant &value) -{ - m_windowProperties.insert(name, value); - emit windowPropertyChanged(name,value); -} - -void ExtendedSurface::extended_surface_set_window_flags(Resource *resource, int32_t flags) -{ - Q_UNUSED(resource); - WindowFlags windowFlags(flags); - if (windowFlags == m_windowFlags) - return; - m_windowFlags = windowFlags; - emit windowFlagsChanged(); -} - -void ExtendedSurface::extended_surface_destroy_resource(Resource *) -{ - delete this; -} - -void ExtendedSurface::extended_surface_raise(Resource *) -{ - emit raiseRequested(); -} - -void ExtendedSurface::extended_surface_lower(Resource *) -{ - emit lowerRequested(); -} - -} - -QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwlextendedsurface_p.h b/src/compositor/extensions/qwlextendedsurface_p.h deleted file mode 100644 index 8ad89619a..000000000 --- a/src/compositor/extensions/qwlextendedsurface_p.h +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WLEXTENDEDSURFACE_H -#define WLEXTENDEDSURFACE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <wayland-server.h> - -#include <QtWaylandCompositor/private/qwayland-server-surface-extension.h> -#include <QtWaylandCompositor/qwaylandsurface.h> -#include <QtWaylandCompositor/qwaylandcompositorextension.h> - -#include <QtCore/QVariant> -#include <QtCore/QLinkedList> -#include <QtGui/QWindow> - -QT_BEGIN_NAMESPACE - -class QWaylandCompositor; -class QWaylandSurface; - -namespace QtWayland { - -class ExtendedSurface; - -class Q_WAYLAND_COMPOSITOR_EXPORT SurfaceExtensionGlobal : public QWaylandCompositorExtensionTemplate<SurfaceExtensionGlobal>, public QtWaylandServer::qt_surface_extension -{ - Q_OBJECT -public: - SurfaceExtensionGlobal(QWaylandCompositor *compositor); - -Q_SIGNALS: - void extendedSurfaceReady(ExtendedSurface *extSurface, QWaylandSurface *surface); - -private: - void surface_extension_get_extended_surface(Resource *resource, - uint32_t id, - struct wl_resource *surface); - -}; - -class Q_WAYLAND_COMPOSITOR_EXPORT ExtendedSurface : public QWaylandCompositorExtensionTemplate<ExtendedSurface>, public QtWaylandServer::qt_extended_surface -{ - Q_OBJECT - Q_PROPERTY(Qt::ScreenOrientations contentOrientationMask READ contentOrientationMask NOTIFY contentOrientationMaskChanged) - Q_PROPERTY(WindowFlags windowFlags READ windowFlags NOTIFY windowFlagsChanged) - Q_FLAGS(WindowFlag WindowFlags) -public: - enum WindowFlag { - OverridesSystemGestures = 0x0001, - StaysOnTop = 0x0002, - BypassWindowManager = 0x0004 - }; - Q_DECLARE_FLAGS(WindowFlags, WindowFlag) - - ExtendedSurface(struct wl_client *client, uint32_t id, int version, QWaylandSurface *surface); - ~ExtendedSurface(); - - void sendGenericProperty(const QString &name, const QVariant &variant); - - void sendOnScreenVisibilityChange(bool onScreen); - void setVisibility(QWindow::Visibility visibility); - - void setParentSurface(QWaylandSurface *s); - - Qt::ScreenOrientations contentOrientationMask() const; - - WindowFlags windowFlags() const { return m_windowFlags; } - - QVariantMap windowProperties() const; - QVariant windowProperty(const QString &propertyName) const; - void setWindowProperty(const QString &name, const QVariant &value); - -Q_SIGNALS: - void contentOrientationMaskChanged(); - void windowFlagsChanged(); - void windowPropertyChanged(const QString &name, const QVariant &value); - void raiseRequested(); - void lowerRequested(); - -private: - void setWindowPropertyImpl(const QString &name, const QVariant &value); - - QWaylandSurface *m_surface; - - Qt::ScreenOrientations m_contentOrientationMask; - - WindowFlags m_windowFlags; - - QByteArray m_authenticationToken; - QVariantMap m_windowProperties; - - void extended_surface_update_generic_property(Resource *resource, - const QString &name, - struct wl_array *value) override; - - void extended_surface_set_content_orientation_mask(Resource *resource, - int32_t orientation) override; - - void extended_surface_set_window_flags(Resource *resource, - int32_t flags) override; - - void extended_surface_destroy_resource(Resource *) override; - void extended_surface_raise(Resource *) override; - void extended_surface_lower(Resource *) override; -}; - -} - -QT_END_NAMESPACE - -#endif // WLEXTENDEDSURFACE_H diff --git a/src/compositor/global/qwaylandcompositorextension.cpp b/src/compositor/global/qwaylandcompositorextension.cpp index 7b44dbde6..ee117bbae 100644 --- a/src/compositor/global/qwaylandcompositorextension.cpp +++ b/src/compositor/global/qwaylandcompositorextension.cpp @@ -146,7 +146,7 @@ QWaylandObject::QWaylandObject(QObjectPrivate &d, QObject *parent) QWaylandObject::~QWaylandObject() { foreach (QWaylandCompositorExtension *extension, extension_vector) - QWaylandCompositorExtensionPrivate::get(extension)->extension_container = Q_NULLPTR; + QWaylandCompositorExtensionPrivate::get(extension)->extension_container = nullptr; } QWaylandCompositorExtension *QWaylandObject::extension(const QByteArray &name) @@ -155,7 +155,7 @@ QWaylandCompositorExtension *QWaylandObject::extension(const QByteArray &name) if (extension_vector.at(i)->extensionInterface()->name == name) return extension_vector.at(i); } - return Q_NULLPTR; + return nullptr; } QWaylandCompositorExtension *QWaylandObject::extension(const wl_interface *interface) @@ -164,7 +164,7 @@ QWaylandCompositorExtension *QWaylandObject::extension(const wl_interface *inter if (extension_vector.at(i)->extensionInterface() == interface) return extension_vector.at(i); } - return Q_NULLPTR; + return nullptr; } QList<QWaylandCompositorExtension *> QWaylandObject::extensions() const diff --git a/src/compositor/global/qwaylandcompositorextension.h b/src/compositor/global/qwaylandcompositorextension.h index 73f8aab36..48fce0c96 100644 --- a/src/compositor/global/qwaylandcompositorextension.h +++ b/src/compositor/global/qwaylandcompositorextension.h @@ -114,7 +114,7 @@ public: static T *findIn(QWaylandObject *container) { - if (!container) return Q_NULLPTR; + if (!container) return nullptr; return qobject_cast<T *>(container->extension(T::interfaceName())); } diff --git a/src/compositor/global/qwaylandcompositorextension_p.h b/src/compositor/global/qwaylandcompositorextension_p.h index 56889cfab..68f817aa6 100644 --- a/src/compositor/global/qwaylandcompositorextension_p.h +++ b/src/compositor/global/qwaylandcompositorextension_p.h @@ -64,7 +64,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandCompositorExtensionPrivate : public QO public: QWaylandCompositorExtensionPrivate() : QObjectPrivate() - , extension_container(Q_NULLPTR) + , extension_container(nullptr) , initialized(false) { } diff --git a/src/compositor/hardware_integration/hardware_integration.pri b/src/compositor/hardware_integration/hardware_integration.pri index dd892e07a..6bf7a75b5 100644 --- a/src/compositor/hardware_integration/hardware_integration.pri +++ b/src/compositor/hardware_integration/hardware_integration.pri @@ -12,6 +12,9 @@ qtConfig(opengl) { hardware_integration/qwlserverbufferintegrationfactory_p.h \ hardware_integration/qwlserverbufferintegrationplugin_p.h \ hardware_integration/qwlhwintegration_p.h \ + hardware_integration/qwlhardwarelayerintegration_p.h \ + hardware_integration/qwlhardwarelayerintegrationfactory_p.h \ + hardware_integration/qwlhardwarelayerintegrationplugin_p.h \ SOURCES += \ hardware_integration/qwlclientbufferintegration.cpp \ @@ -21,6 +24,9 @@ qtConfig(opengl) { hardware_integration/qwlserverbufferintegrationfactory.cpp \ hardware_integration/qwlserverbufferintegrationplugin.cpp \ hardware_integration/qwlhwintegration.cpp \ + hardware_integration/qwlhardwarelayerintegration.cpp \ + hardware_integration/qwlhardwarelayerintegrationfactory.cpp \ + hardware_integration/qwlhardwarelayerintegrationplugin.cpp \ } else { system(echo "Qt-Compositor configured as raster only compositor") } diff --git a/src/compositor/hardware_integration/qwlhardwarelayerintegration.cpp b/src/compositor/hardware_integration/qwlhardwarelayerintegration.cpp new file mode 100644 index 000000000..76cf0990a --- /dev/null +++ b/src/compositor/hardware_integration/qwlhardwarelayerintegration.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwlhardwarelayerintegration_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +} + +QT_END_NAMESPACE diff --git a/src/compositor/hardware_integration/qwlhardwarelayerintegration_p.h b/src/compositor/hardware_integration/qwlhardwarelayerintegration_p.h new file mode 100644 index 000000000..02de8e8be --- /dev/null +++ b/src/compositor/hardware_integration/qwlhardwarelayerintegration_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDHARDWARELAYERINTEGRATION_H +#define QWAYLANDHARDWARELAYERINTEGRATION_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/qtwaylandcompositorglobal.h> + +#include <QObject> +#include <QQmlParserStatus> + +QT_BEGIN_NAMESPACE + +class QPoint; + +class QWaylandQuickHardwareLayer; + +namespace QtWayland { + +class Q_WAYLAND_COMPOSITOR_EXPORT HardwareLayerIntegration : public QObject +{ + Q_OBJECT +public: + HardwareLayerIntegration(QObject *parent = nullptr) + : QObject(parent) + {} + ~HardwareLayerIntegration() override {} + virtual void add(QWaylandQuickHardwareLayer *) {} + virtual void remove(QWaylandQuickHardwareLayer *) {} +}; + +} // namespace QtWayland + +QT_END_NAMESPACE + +#endif // QWAYLANDHARDWARELAYERINTEGRATION_H diff --git a/src/compositor/hardware_integration/qwlhardwarelayerintegrationfactory.cpp b/src/compositor/hardware_integration/qwlhardwarelayerintegrationfactory.cpp new file mode 100644 index 000000000..4b85be820 --- /dev/null +++ b/src/compositor/hardware_integration/qwlhardwarelayerintegrationfactory.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwlhardwarelayerintegrationfactory_p.h" +#include "qwlhardwarelayerintegrationplugin_p.h" +#include "qwlhardwarelayerintegration_p.h" + +#include <QtCore/private/qfactoryloader_p.h> +#include <QtCore/QCoreApplication> +#include <QtCore/QDir> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +#if QT_CONFIG(library) +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, + (QtWaylandHardwareLayerIntegrationFactoryInterface_iid, QLatin1String("/wayland-hardware-layer-integration"), Qt::CaseInsensitive)) +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, + (QtWaylandHardwareLayerIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) +#endif + +QStringList HardwareLayerIntegrationFactory::keys(const QString &pluginPath) +{ +#if QT_CONFIG(library) + QStringList list; + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + list = directLoader()->keyMap().values(); + if (!list.isEmpty()) { + const QString postFix = QStringLiteral(" (from ") + + QDir::toNativeSeparators(pluginPath) + + QLatin1Char(')'); + const QStringList::iterator end = list.end(); + for (QStringList::iterator it = list.begin(); it != end; ++it) + (*it).append(postFix); + } + } + list.append(loader()->keyMap().values()); + return list; +#else + return QStringList(); +#endif +} + +HardwareLayerIntegration *HardwareLayerIntegrationFactory::create(const QString &name, const QStringList &args, const QString &pluginPath) +{ +#if QT_CONFIG(library) + // Try loading the plugin from platformPluginPath first: + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + if (HardwareLayerIntegration *ret = qLoadPlugin<HardwareLayerIntegration, HardwareLayerIntegrationPlugin>(directLoader(), name, args)) + return ret; + } + if (HardwareLayerIntegration *ret = qLoadPlugin<HardwareLayerIntegration, HardwareLayerIntegrationPlugin>(loader(), name, args)) + return ret; +#endif + return nullptr; +} + +} + +QT_END_NAMESPACE diff --git a/src/compositor/hardware_integration/qwlhardwarelayerintegrationfactory_p.h b/src/compositor/hardware_integration/qwlhardwarelayerintegrationfactory_p.h new file mode 100644 index 000000000..83c9c523b --- /dev/null +++ b/src/compositor/hardware_integration/qwlhardwarelayerintegrationfactory_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDHARDWARELAYERINTEGRATIONFACTORY_H +#define QWAYLANDHARDWARELAYERINTEGRATIONFACTORY_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/qtwaylandcompositorglobal.h> +#include <QtCore/QStringList> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +class HardwareLayerIntegration; + +class Q_WAYLAND_COMPOSITOR_EXPORT HardwareLayerIntegrationFactory +{ +public: + static QStringList keys(const QString &pluginPath = QString()); + static HardwareLayerIntegration *create(const QString &name, const QStringList &args, const QString &pluginPath = QString()); +}; + +} + +QT_END_NAMESPACE + +#endif // QWAYLANDHARDWARELAYERINTEGRATIONFACTORY_H diff --git a/src/compositor/hardware_integration/qwlhardwarelayerintegrationplugin.cpp b/src/compositor/hardware_integration/qwlhardwarelayerintegrationplugin.cpp new file mode 100644 index 000000000..0ae3a0b6a --- /dev/null +++ b/src/compositor/hardware_integration/qwlhardwarelayerintegrationplugin.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwlhardwarelayerintegrationplugin_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +HardwareLayerIntegrationPlugin::HardwareLayerIntegrationPlugin(QObject *parent) : + QObject(parent) +{ +} + +HardwareLayerIntegrationPlugin::~HardwareLayerIntegrationPlugin() +{ +} + +} + +QT_END_NAMESPACE diff --git a/src/compositor/hardware_integration/qwlhardwarelayerintegrationplugin_p.h b/src/compositor/hardware_integration/qwlhardwarelayerintegrationplugin_p.h new file mode 100644 index 000000000..acf80fe33 --- /dev/null +++ b/src/compositor/hardware_integration/qwlhardwarelayerintegrationplugin_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDHARDWARELAYERINTEGRATIONPLUGIN_H +#define QWAYLANDHARDWARELAYERINTEGRATIONPLUGIN_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/qtwaylandcompositorglobal.h> + +#include <QtCore/qplugin.h> +#include <QtCore/qfactoryinterface.h> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +class HardwareLayerIntegration; + +#define QtWaylandHardwareLayerIntegrationFactoryInterface_iid "org.qt-project.Qt.Compositor.QtWaylandHardwareLayerIntegrationFactoryInterface.5.11" + +class Q_WAYLAND_COMPOSITOR_EXPORT HardwareLayerIntegrationPlugin : public QObject +{ + Q_OBJECT +public: + explicit HardwareLayerIntegrationPlugin(QObject *parent = nullptr); + ~HardwareLayerIntegrationPlugin() override; + + virtual HardwareLayerIntegration *create(const QString &key, const QStringList ¶mList) = 0; +}; + +} + +QT_END_NAMESPACE + +#endif // QWAYLANDHARDWARELAYERINTEGRATIONPLUGIN_H diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp index 771b4b2e4..8a1009fa8 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp @@ -162,7 +162,7 @@ void *QWaylandEglClientBufferIntegration::nativeResource(NativeResource resource default: break; } - return Q_NULLPTR; + return nullptr; } void *QWaylandEglClientBufferIntegration::nativeResourceForContext(NativeResource resource, QPlatformOpenGLContext *context) @@ -178,7 +178,7 @@ void *QWaylandEglClientBufferIntegration::nativeResourceForContext(NativeResourc default: break; } - return Q_NULLPTR; + return nullptr; } EGLDisplay QWaylandEglClientBufferIntegration::eglDisplay() const diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp index 6b5c53263..87f3e2d4e 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp @@ -92,6 +92,11 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const return QWaylandWindow::Egl; } +void QWaylandEglWindow::ensureSize() +{ + updateSurface(false); +} + void QWaylandEglWindow::setGeometry(const QRect &rect) { QWaylandWindow::setGeometry(rect); diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h index e471a8f7c..77aee56dc 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h @@ -59,6 +59,7 @@ public: QWaylandEglWindow(QWindow *window); ~QWaylandEglWindow(); WindowType windowType() const override; + void ensureSize() override; void updateSurface(bool create); virtual void setGeometry(const QRect &rect) override; diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp index f4dd6f492..967028861 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp @@ -327,7 +327,7 @@ void QWaylandGLContext::updateGLFormat() EGLSurface prevSurfaceDraw = eglGetCurrentSurface(EGL_DRAW); EGLSurface prevSurfaceRead = eglGetCurrentSurface(EGL_READ); - wl_surface *wlSurface = m_display->createSurface(Q_NULLPTR); + wl_surface *wlSurface = m_display->createSurface(nullptr); wl_egl_window *eglWindow = wl_egl_window_create(wlSurface, 1, 1); EGLSurface eglSurface = eglCreateWindowSurface(m_eglDisplay, m_config, eglWindow, 0); diff --git a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp index 431cb14c1..9c3dee3fc 100644 --- a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp @@ -121,7 +121,7 @@ void QWaylandXCompositeEGLWindow::createEglSurface() XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual); XMapWindow(m_glxIntegration->xDisplay(), m_xWindow); - m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), m_config, m_xWindow,0); + m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), m_config, reinterpret_cast<EGLNativeWindowType>(m_xWindow), nullptr); if (m_surface == EGL_NO_SURFACE) { qFatal("Could not make eglsurface"); } diff --git a/src/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2.pri b/src/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2.pri new file mode 100644 index 000000000..9d68775b3 --- /dev/null +++ b/src/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2.pri @@ -0,0 +1,9 @@ +INCLUDEPATH += $$PWD + +QMAKE_USE_PRIVATE += wayland-server + +SOURCES += \ + $$PWD/vsp2hardwarelayerintegration.cpp + +HEADERS += \ + $$PWD/vsp2hardwarelayerintegration.h diff --git a/src/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2hardwarelayerintegration.cpp b/src/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2hardwarelayerintegration.cpp new file mode 100644 index 000000000..a02226a52 --- /dev/null +++ b/src/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2hardwarelayerintegration.cpp @@ -0,0 +1,262 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "vsp2hardwarelayerintegration.h" + +extern "C" { +#define private priv +#include <wayland-kms.h> +#undef private +} + +#include <private/qwaylandquickhardwarelayer_p.h> +#include <private/qwaylandquickitem_p.h> +#include <private/qwaylandview_p.h> +#include <QWaylandQuickOutput> +#include <QQuickWindow> + +#include <QtPlatformHeaders/qeglfsfunctions.h> + +QT_BEGIN_NAMESPACE + +Vsp2Buffer::Vsp2Buffer(wl_kms_buffer *kmsBuffer) + : dmabufFd(kmsBuffer->fd) + , bytesPerLine(kmsBuffer->stride) + , drmPixelFormat(kmsBuffer->format) + , size(kmsBuffer->width, kmsBuffer->height) +{ +} + +Vsp2Layer::Vsp2Layer(QWaylandQuickHardwareLayer *hwLayer, Vsp2HardwareLayerIntegration *integration) + : m_hwLayer(hwLayer) +{ + connect(hwLayer, &QWaylandQuickHardwareLayer::stackingLevelChanged, this, [integration](){ + integration->recreateVspLayers(); + }); + connect(hwLayer->waylandItem(), &QWaylandQuickItem::surfaceChanged, this, &Vsp2Layer::handleSurfaceChanged); + connect(hwLayer->waylandItem(), &QQuickItem::opacityChanged, this, &Vsp2Layer::updateOpacity); + connect(hwLayer->waylandItem()->window(), &QQuickWindow::afterSynchronizing, this, &Vsp2Layer::updatePosition); + hwLayer->disableSceneGraphPainting(); + QWaylandViewPrivate::get(hwLayer->waylandItem()->view())->independentFrameCallback = true; + handleSurfaceChanged(); +} + +void Vsp2Layer::enableVspLayer() +{ + auto *kmsBuffer = nextKmsBuffer(); + + if (!kmsBuffer) + return; + + m_buffer = Vsp2Buffer(kmsBuffer); + updatePosition(); + auto *wlItem = m_hwLayer->waylandItem(); + m_screen = wlItem->window()->screen(); + m_layerIndex = QEglFSFunctions::vsp2AddLayer(m_screen, m_buffer.dmabufFd, m_buffer.size, m_position, m_buffer.drmPixelFormat, m_buffer.bytesPerLine); + wlItem->surface()->frameStarted(); + updateOpacity(); +} + +void Vsp2Layer::disableVspLayer() +{ + QEglFSFunctions::vsp2RemoveLayer(m_screen, m_layerIndex); + m_layerIndex = -1; + m_screen = nullptr; +} + +void Vsp2Layer::handleBufferCommitted() +{ + if (!isEnabled()) { + enableVspLayer(); + return; + } + + auto *kmsBuffer = nextKmsBuffer(); + + Vsp2Buffer newBuffer(kmsBuffer); + if (m_buffer.dmabufFd != -1) { + bool formatChanged = false; + formatChanged |= newBuffer.bytesPerLine != m_buffer.bytesPerLine; + formatChanged |= newBuffer.size != m_buffer.size; + formatChanged |= newBuffer.drmPixelFormat != m_buffer.drmPixelFormat; + if (formatChanged) { + qWarning() << "The VSP2 Wayland hardware layer integration doesn't support changing" + << "surface formats, this will most likely fail"; + } + } + + m_buffer = newBuffer; + auto *wlItem = m_hwLayer->waylandItem(); + m_screen = wlItem->window()->screen(); + QEglFSFunctions::vsp2SetLayerBuffer(m_screen, m_layerIndex, m_buffer.dmabufFd); + wlItem->surface()->frameStarted(); +} + +void Vsp2Layer::handleSurfaceChanged() +{ + auto newSurface = m_hwLayer->waylandItem()->surface(); + + if (Q_UNLIKELY(newSurface == m_surface)) + return; + + if (this->m_surface) + disconnect(this->m_surface, &QWaylandSurface::redraw, this, &Vsp2Layer::handleBufferCommitted); + if (newSurface) + connect(newSurface, &QWaylandSurface::redraw, this, &Vsp2Layer::handleBufferCommitted, Qt::DirectConnection); + + this->m_surface = newSurface; +} + +void Vsp2Layer::updatePosition() +{ + QWaylandQuickItem *wlItem = m_hwLayer->waylandItem(); + QRectF localGeometry(0, 0, wlItem->width(), wlItem->height()); + auto lastMatrix = QWaylandQuickItemPrivate::get(wlItem)->lastMatrix; + auto globalGeometry = lastMatrix.mapRect(localGeometry); + + if (m_buffer.size != globalGeometry.size().toSize()) { + qWarning() << "wl_buffer size != WaylandQuickItem size and scaling has not been" + << "implemented for the vsp2 hardware layer integration"; + } + + m_position = globalGeometry.topLeft().toPoint(); + if (isEnabled()) + QEglFSFunctions::vsp2SetLayerPosition(m_screen, m_layerIndex, m_position); +} + +void Vsp2Layer::updateOpacity() +{ + if (isEnabled()) { + qreal opacity = m_hwLayer->waylandItem()->opacity(); + QEglFSFunctions::vsp2SetLayerAlpha(m_screen, m_layerIndex, opacity); + } +} + +wl_kms_buffer *Vsp2Layer::nextKmsBuffer() +{ + Q_ASSERT(m_hwLayer && m_hwLayer->waylandItem()); + QWaylandQuickItem *wlItem = m_hwLayer->waylandItem(); + auto view = wlItem->view(); + Q_ASSERT(view); + + view->advance(); + auto wlBuffer = view->currentBuffer().wl_buffer(); + + if (!wlBuffer) + return nullptr; + + struct wl_kms_buffer *kmsBuffer = wayland_kms_buffer_get(wlBuffer); + + if (!kmsBuffer) + qWarning() << "Failed to get wl_kms_buffer for wl_buffer:" << wlBuffer->object.id; + + return kmsBuffer; +} + +void Vsp2HardwareLayerIntegration::enableVspLayers() +{ + for (auto &layer : qAsConst(m_layers)) { + Q_ASSERT(!layer->isEnabled()); + layer->enableVspLayer(); + } +} + +void Vsp2HardwareLayerIntegration::disableVspLayers() +{ + for (auto it = m_layers.rbegin(); it != m_layers.rend(); ++it) { + if ((*it)->isEnabled()) + (*it)->disableVspLayer(); + } +} + +void Vsp2HardwareLayerIntegration::sortLayersByDepth() +{ + std::sort(m_layers.begin(), m_layers.end(), [](auto &l1, auto &l2){ + return l1->hwLayer()->stackingLevel() < l2->hwLayer()->stackingLevel(); + }); +} + +void Vsp2HardwareLayerIntegration::recreateVspLayers() { + disableVspLayers(); + sortLayersByDepth(); + enableVspLayers(); +} + +Vsp2HardwareLayerIntegration::Vsp2HardwareLayerIntegration() +{ + if (QGuiApplication::platformName() != "eglfs") { + qWarning() << "Vsp2 layers are currently only supported on the eglfs platform plugin" + << "with the eglfs_kms_vsp2 device integration.\n" + << "You need to set QT_QPA_PLATFORM=eglfs and QT_QPA_EGLFS_INTEGRATION=eglfs_kms_vsp2"; + } + static Vsp2HardwareLayerIntegration *s_instance = this; + QEglFSFunctions::vsp2AddBlendListener(QGuiApplication::primaryScreen(), [](){ + s_instance->sendFrameCallbacks(); + }); +} + +void Vsp2HardwareLayerIntegration::add(QWaylandQuickHardwareLayer *hwLayer) +{ + disableVspLayers(); + m_layers.append(QSharedPointer<Vsp2Layer>(new Vsp2Layer(hwLayer, this))); + sortLayersByDepth(); + enableVspLayers(); +} + +void Vsp2HardwareLayerIntegration::remove(QWaylandQuickHardwareLayer *hwLayer) +{ + disableVspLayers(); + for (auto it = m_layers.begin(); it != m_layers.end(); ++it) { + if ((*it)->hwLayer() == hwLayer) { + m_layers.erase(it); + break; + } + } + enableVspLayers(); +} + +void Vsp2HardwareLayerIntegration::sendFrameCallbacks() +{ + for (auto &layer : qAsConst(m_layers)) { + if (auto *surface = layer->hwLayer()->waylandItem()->surface()) + surface->sendFrameCallbacks(); + } +} + +QT_END_NAMESPACE diff --git a/src/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2hardwarelayerintegration.h b/src/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2hardwarelayerintegration.h new file mode 100644 index 000000000..c9b69b7bc --- /dev/null +++ b/src/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2hardwarelayerintegration.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VSP2HARDWARELAYERINTEGRATION_H +#define VSP2HARDWARELAYERINTEGRATION_H + +#include <QtWaylandCompositor/private/qwlhardwarelayerintegration_p.h> +#include <private/qobject_p.h> + +#include <QPoint> +#include <QSize> + +struct wl_kms_buffer; + +QT_BEGIN_NAMESPACE + +class QScreen; +class QWaylandSurface; +class QWaylandQuickHardwareLayer; + +class Vsp2Layer; + +class Vsp2HardwareLayerIntegration : public QtWayland::HardwareLayerIntegration +{ + Q_OBJECT +public: + explicit Vsp2HardwareLayerIntegration(); + + void add(QWaylandQuickHardwareLayer *layer) override; + void remove(QWaylandQuickHardwareLayer *layer) override; + + void sendFrameCallbacks(); + QVector<QSharedPointer<Vsp2Layer>> m_layers; +private: + void enableVspLayers(); + void disableVspLayers(); + void sortLayersByDepth(); + void recreateVspLayers(); + friend class Vsp2Layer; +}; + +struct Vsp2Buffer +{ + explicit Vsp2Buffer() = default; + explicit Vsp2Buffer(wl_kms_buffer *kmsBuffer); + + int dmabufFd = -1; + uint bytesPerLine = 0; + uint drmPixelFormat = 0; + QSize size; +}; + +class Vsp2Layer : public QObject +{ + Q_OBJECT +public: + explicit Vsp2Layer(QWaylandQuickHardwareLayer *m_hwLayer, Vsp2HardwareLayerIntegration *integration); + void enableVspLayer(); + void disableVspLayer(); + bool isEnabled() { return m_layerIndex != -1; } + QWaylandQuickHardwareLayer *hwLayer() const { return m_hwLayer; } + +public slots: + void handleBufferCommitted(); + void handleSurfaceChanged(); + void updatePosition(); + void updateOpacity(); + +private: + wl_kms_buffer *nextKmsBuffer(); + int m_layerIndex = -1; + QScreen *m_screen = nullptr; + QPoint m_position; + QWaylandQuickHardwareLayer *m_hwLayer = nullptr; + QWaylandSurface *m_surface = nullptr; + Vsp2Buffer m_buffer; +}; + +QT_END_NAMESPACE + +#endif // VSP2HARDWARELAYERINTEGRATION_H diff --git a/src/hardwareintegration/compositor/shm-emulation-server/shmserverbufferintegration.cpp b/src/hardwareintegration/compositor/shm-emulation-server/shmserverbufferintegration.cpp index 7a86785b0..1dd037adc 100644 --- a/src/hardwareintegration/compositor/shm-emulation-server/shmserverbufferintegration.cpp +++ b/src/hardwareintegration/compositor/shm-emulation-server/shmserverbufferintegration.cpp @@ -70,7 +70,7 @@ ShmServerBuffer::ShmServerBuffer(ShmServerBufferIntegration *integration, const QString key = "qt_shm_emulation_" + QString::number(qimage.cacheKey()); m_shm = new QSharedMemory(key); - int shm_size = qimage.byteCount(); + qsizetype shm_size = qimage.sizeInBytes(); bool ok = m_shm->create(shm_size) && m_shm->lock(); if (ok) { memcpy(m_shm->data(), qimage.constBits(), shm_size); diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp index f5e63aec5..fdaddb6ab 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp @@ -223,7 +223,7 @@ WaylandEglClientBufferIntegrationPrivate::WaylandEglClientBufferIntegrationPriva , egl_create_image(0) , egl_destroy_image(0) , gl_egl_image_target_texture_2d(0) - , funcs(Q_NULLPTR) + , funcs(nullptr) { } diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp index 3cc0ba0a9..071b08827 100644 --- a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp +++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp @@ -129,7 +129,7 @@ QOpenGLTexture *XCompositeEglClientBuffer::toOpenGlTexture(int plane) attribList.append(EGL_TEXTURE_2D); attribList.append(EGL_NONE); - EGLSurface surface = eglCreatePixmapSurface(m_integration->eglDisplay(),config,pixmap,attribList.constData()); + EGLSurface surface = eglCreatePixmapSurface(m_integration->eglDisplay(), config, reinterpret_cast<EGLNativePixmapType>(pixmap), attribList.constData()); if (surface == EGL_NO_SURFACE) { qDebug() << "Failed to create eglsurface" << pixmap << compositorBuffer->window(); } diff --git a/src/imports/compositor/qwaylandquickcompositorplugin.cpp b/src/imports/compositor/qwaylandquickcompositorplugin.cpp index 0d6dbf782..44413414f 100644 --- a/src/imports/compositor/qwaylandquickcompositorplugin.cpp +++ b/src/imports/compositor/qwaylandquickcompositorplugin.cpp @@ -44,6 +44,7 @@ #include <QtWaylandCompositor/QWaylandQuickCompositor> #include <QtWaylandCompositor/QWaylandQuickItem> +#include <QtWaylandCompositor/private/qwaylandquickhardwarelayer_p.h> #include <QtWaylandCompositor/QWaylandQuickSurface> #include <QtWaylandCompositor/QWaylandClient> #include <QtWaylandCompositor/QWaylandQuickOutput> @@ -125,6 +126,7 @@ public: { qmlRegisterType<QWaylandQuickCompositorQuickExtensionContainer>(uri, 1, 0, "WaylandCompositor"); qmlRegisterType<QWaylandQuickItem>(uri, 1, 0, "WaylandQuickItem"); + qmlRegisterType<QWaylandQuickHardwareLayer>(uri, 1, 2, "WaylandHardwareLayer"); qmlRegisterType<QWaylandMouseTracker>(uri, 1, 0, "WaylandMouseTracker"); qmlRegisterType<QWaylandQuickOutput>(uri, 1, 0, "WaylandOutput"); qmlRegisterType<QWaylandQuickSurface>(uri, 1, 0, "WaylandSurface"); diff --git a/src/plugins/hardwareintegration/compositor/compositor.pro b/src/plugins/hardwareintegration/compositor/compositor.pro index 0b2a4292c..22301d07e 100644 --- a/src/plugins/hardwareintegration/compositor/compositor.pro +++ b/src/plugins/hardwareintegration/compositor/compositor.pro @@ -16,3 +16,5 @@ qtConfig(libhybris-egl-server): \ ### TODO: make shm-emulation configurable SUBDIRS += shm-emulation-server + +SUBDIRS += hardwarelayer diff --git a/src/plugins/hardwareintegration/compositor/hardwarelayer/hardwarelayer.pro b/src/plugins/hardwareintegration/compositor/hardwarelayer/hardwarelayer.pro new file mode 100644 index 000000000..634447af7 --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/hardwarelayer/hardwarelayer.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs +QT_FOR_CONFIG += waylandcompositor-private + +qtConfig(wayland-layer-integration-vsp2): \ + SUBDIRS += vsp2 diff --git a/src/plugins/hardwareintegration/compositor/hardwarelayer/vsp2/main.cpp b/src/plugins/hardwareintegration/compositor/hardwarelayer/vsp2/main.cpp new file mode 100644 index 000000000..865637c57 --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/hardwarelayer/vsp2/main.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWaylandCompositor/private/qwlhardwarelayerintegrationplugin_p.h> +#include "vsp2hardwarelayerintegration.h" + +QT_BEGIN_NAMESPACE + +class Vsp2HardwareLayerIntegrationPlugin : public QtWayland::HardwareLayerIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QtWaylandHardwareLayerIntegrationFactoryInterface_iid FILE "vsp2.json") +public: + QtWayland::HardwareLayerIntegration *create(const QString&, const QStringList&) override; +}; + +QtWayland::HardwareLayerIntegration *Vsp2HardwareLayerIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + Q_UNUSED(system); + return new Vsp2HardwareLayerIntegration(); +} + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2.json b/src/plugins/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2.json new file mode 100644 index 000000000..1fc35bc5a --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "vsp2" ] +} diff --git a/src/plugins/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2.pro b/src/plugins/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2.pro new file mode 100644 index 000000000..ff16b20bf --- /dev/null +++ b/src/plugins/hardwareintegration/compositor/hardwarelayer/vsp2/vsp2.pro @@ -0,0 +1,14 @@ +QT = waylandcompositor waylandcompositor-private core-private gui-private + +QMAKE_USE_PRIVATE += wayland-kms + +OTHER_FILES += vsp2.json + +SOURCES += \ + main.cpp + +include($PWD/../../../../../../hardwareintegration/compositor/hardwarelayer/vsp2/vsp2.pri) + +PLUGIN_TYPE = wayland-hardware-layer-integration +PLUGIN_CLASS_NAME = Vsp2HardwareLayerIntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp b/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp index 502b17c0d..fee812501 100644 --- a/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp +++ b/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp @@ -55,8 +55,8 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { QWaylandIviShellIntegration::QWaylandIviShellIntegration() - : m_iviApplication(Q_NULLPTR) - , m_iviController(Q_NULLPTR) + : m_iviApplication(nullptr) + , m_iviController(nullptr) , m_lastSurfaceId(0) , m_surfaceNumber(0) , m_useEnvSurfaceId(false) @@ -129,11 +129,11 @@ uint32_t QWaylandIviShellIntegration::getNextUniqueSurfaceId() QWaylandShellSurface *QWaylandIviShellIntegration::createShellSurface(QWaylandWindow *window) { if (!m_iviApplication) - return Q_NULLPTR; + return nullptr; uint32_t surfaceId = getNextUniqueSurfaceId(); if (surfaceId == 0) - return Q_NULLPTR; + return nullptr; struct ivi_surface *surface = m_iviApplication->surface_create(surfaceId, window->object()); if (!m_iviController) diff --git a/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp b/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp index a16518cc3..335aa852c 100644 --- a/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp +++ b/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp @@ -52,7 +52,7 @@ QWaylandIviSurface::QWaylandIviSurface(struct ::ivi_surface *ivi_surface, QWayla : QtWayland::ivi_surface(ivi_surface) , QWaylandShellSurface(window) , m_window(window) - , m_extendedWindow(Q_NULLPTR) + , m_extendedWindow(nullptr) { createExtendedSurface(window); } @@ -63,7 +63,7 @@ QWaylandIviSurface::QWaylandIviSurface(struct ::ivi_surface *ivi_surface, QWayla , QWaylandShellSurface(window) , QtWayland::ivi_controller_surface(iviControllerSurface) , m_window(window) - , m_extendedWindow(Q_NULLPTR) + , m_extendedWindow(nullptr) { createExtendedSurface(window); } diff --git a/src/qtwaylandscanner/qtwaylandscanner.cpp b/src/qtwaylandscanner/qtwaylandscanner.cpp index ed36a1386..d6a83dbbc 100644 --- a/src/qtwaylandscanner/qtwaylandscanner.cpp +++ b/src/qtwaylandscanner/qtwaylandscanner.cpp @@ -504,6 +504,7 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr printf(" private:\n"); printf(" static void bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id);\n"); printf(" static void destroy_func(struct ::wl_resource *client_resource);\n"); + printf(" static void display_destroy_func(struct ::wl_listener *listener, void *data);\n"); printf("\n"); printf(" Resource *bind(struct ::wl_client *client, uint32_t id, int version);\n"); printf(" Resource *bind(struct ::wl_resource *handle);\n"); @@ -527,6 +528,10 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr printf(" Resource *m_resource;\n"); printf(" struct ::wl_global *m_global;\n"); printf(" uint32_t m_globalVersion;\n"); + printf(" struct DisplayDestroyedListener : ::wl_listener {\n"); + printf(" %s *parent;\n", interfaceName); + printf(" };\n"); + printf(" DisplayDestroyedListener m_displayDestroyedListener;\n"); printf(" };\n"); if (j < interfaces.size() - 1) @@ -607,6 +612,13 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr printf(" %s::~%s()\n", interfaceName, interfaceName); printf(" {\n"); + printf(" for (auto resource : qAsConst(m_resource_map))\n"); + printf(" wl_resource_set_implementation(resource->handle, nullptr, nullptr, nullptr);\n"); + printf("\n"); + printf(" if (m_global) {\n"); + printf(" wl_global_destroy(m_global);\n"); + printf(" wl_list_remove(&m_displayDestroyedListener.link);\n"); + printf(" }\n"); printf(" }\n"); printf("\n"); @@ -642,6 +654,9 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr printf(" {\n"); printf(" m_global = wl_global_create(display, &::%s_interface, version, this, bind_func);\n", interfaceName); printf(" m_globalVersion = version;\n"); + printf(" m_displayDestroyedListener.notify = %s::display_destroy_func;\n", interfaceName); + printf(" m_displayDestroyedListener.parent = this;\n"); + printf(" wl_display_add_destroy_listener(display, &m_displayDestroyedListener);\n"); printf(" }\n"); printf("\n"); @@ -674,6 +689,14 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr printf(" }\n"); printf("\n"); + printf(" void %s::display_destroy_func(struct ::wl_listener *listener, void *data)\n", interfaceName); + printf(" {\n"); + printf(" Q_UNUSED(data);\n"); + printf(" %s *that = static_cast<%s::DisplayDestroyedListener *>(listener)->parent;\n", interfaceName, interfaceName); + printf(" that->m_global = nullptr;\n"); + printf(" }\n"); + printf("\n"); + printf(" void %s::destroy_func(struct ::wl_resource *client_resource)\n", interfaceName); printf(" {\n"); printf(" Resource *resource = Resource::fromResource(client_resource);\n"); |