diff options
20 files changed, 593 insertions, 1090 deletions
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri index d102203d5e..457efd68fb 100644 --- a/src/platformsupport/eglconvenience/eglconvenience.pri +++ b/src/platformsupport/eglconvenience/eglconvenience.pri @@ -1,29 +1,16 @@ contains(QT_CONFIG,egl) { HEADERS += \ - $$PWD/qeglconvenience_p.h \ - $$PWD/qeglpbuffer_p.h + $$PWD/qeglconvenience_p.h SOURCES += \ - $$PWD/qeglconvenience.cpp \ - $$PWD/qeglpbuffer.cpp + $$PWD/qeglconvenience.cpp contains(QT_CONFIG,opengl) { - HEADERS += $$PWD/qeglplatformcontext_p.h - SOURCES += $$PWD/qeglplatformcontext.cpp + HEADERS += $$PWD/qeglplatformcontext_p.h \ + $$PWD/qeglpbuffer_p.h - unix { - HEADERS += \ - $$PWD/qeglplatformcursor_p.h \ - $$PWD/qeglplatformwindow_p.h \ - $$PWD/qeglplatformscreen_p.h \ - $$PWD/qeglplatformintegration_p.h - - SOURCES += \ - $$PWD/qeglplatformcursor.cpp \ - $$PWD/qeglplatformwindow.cpp \ - $$PWD/qeglplatformscreen.cpp \ - $$PWD/qeglplatformintegration.cpp - } + SOURCES += $$PWD/qeglplatformcontext.cpp \ + $$PWD/qeglpbuffer.cpp } # Avoid X11 header collision diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp deleted file mode 100644 index 1868ff1665..0000000000 --- a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtGui/QWindow> -#include <QtGui/QOpenGLContext> -#include <QtGui/QOffscreenSurface> -#include <QtGui/QGuiApplication> -#include <QtGui/private/qguiapplication_p.h> -#include <qpa/qwindowsysteminterface.h> -#include <qpa/qplatforminputcontextfactory_p.h> - -#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h> -#include <QtPlatformSupport/private/qgenericunixservices_p.h> -#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> -#include <QtPlatformSupport/private/qfbvthandler_p.h> -#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h> - -#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) -#include <QtPlatformSupport/private/qevdevmousemanager_p.h> -#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h> -#include <QtPlatformSupport/private/qevdevtouchmanager_p.h> -#endif - -#if !defined(QT_NO_TSLIB) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) -#include <QtPlatformSupport/private/qtslib_p.h> -#endif - -#include <QtPlatformHeaders/qeglfsfunctions.h> - -#include "qeglplatformintegration_p.h" -#include "qeglplatformcontext_p.h" -#include "qeglplatformwindow_p.h" -#include "qeglplatformscreen_p.h" -#include "qeglplatformcursor_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QEGLPlatformIntegration - \brief Base class for EGL-based QPlatformIntegration implementations. - \since 5.2 - \internal - \ingroup qpa - - This class provides most of the necessary platform integration for - an EGL-based Unix system. Platform plugins must subclass this and - reimplement the virtuals for creating platform screens and windows - since they will most likely wish to use a subclass for these. - - The backing store, native interface accessors, font database, - basic capability flags, etc. are provided out of the box, no - further customization is needed. - - \note It is critical that this class' implementation of - initialize() is called. Therefore subclasses should either avoid - to reimplement this function or call the base class - implementation. - */ - -QEGLPlatformIntegration::QEGLPlatformIntegration() - : m_display(EGL_NO_DISPLAY), - m_inputContext(0), - m_fontDb(new QGenericUnixFontDatabase), - m_services(new QGenericUnixServices), - m_kbdMgr(0) -{ -} - -QEGLPlatformIntegration::~QEGLPlatformIntegration() -{ -} - -void QEGLPlatformIntegration::initialize() -{ - m_display = eglGetDisplay(nativeDisplay()); - if (m_display == EGL_NO_DISPLAY) - qFatal("Could not open egl display"); - - EGLint major, minor; - if (!eglInitialize(m_display, &major, &minor)) - qFatal("Could not initialize egl display"); - - m_inputContext = QPlatformInputContextFactory::create(); - - m_vtHandler.reset(new QFbVtHandler); -} - -void QEGLPlatformIntegration::destroy() -{ - foreach (QWindow *w, qGuiApp->topLevelWindows()) - w->destroy(); - - if (m_display != EGL_NO_DISPLAY) - eglTerminate(m_display); -} - -QAbstractEventDispatcher *QEGLPlatformIntegration::createEventDispatcher() const -{ - return createUnixEventDispatcher(); -} - -QPlatformServices *QEGLPlatformIntegration::services() const -{ - return m_services.data(); -} - -QPlatformFontDatabase *QEGLPlatformIntegration::fontDatabase() const -{ - return m_fontDb.data(); -} - -QPlatformBackingStore *QEGLPlatformIntegration::createPlatformBackingStore(QWindow *window) const -{ - QOpenGLCompositorBackingStore *bs = new QOpenGLCompositorBackingStore(window); - if (!window->handle()) - window->create(); - static_cast<QEGLPlatformWindow *>(window->handle())->setBackingStore(bs); - return bs; -} - -QPlatformWindow *QEGLPlatformIntegration::createPlatformWindow(QWindow *window) const -{ - QWindowSystemInterface::flushWindowSystemEvents(); - QEGLPlatformWindow *w = createWindow(window); - w->create(); - if (window->type() != Qt::ToolTip) - w->requestActivateWindow(); - return w; -} - -QPlatformOpenGLContext *QEGLPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const -{ - // If there is a "root" window into which raster and QOpenGLWidget content is - // composited, all other contexts must share with its context. - QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context(); - QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle(); - QVariant nativeHandle = context->nativeHandle(); - QPlatformOpenGLContext *platformContext = createContext(context->format(), - share, - display(), - &nativeHandle); - context->setNativeHandle(nativeHandle); - return platformContext; -} - -QPlatformOffscreenSurface *QEGLPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const -{ - QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(surface->screen()->handle()); - return createOffscreenSurface(screen->display(), surface->requestedFormat(), surface); -} - -bool QEGLPlatformIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - switch (cap) { - case ThreadedPixmaps: return true; - case OpenGL: return true; - case ThreadedOpenGL: return true; - case WindowManagement: return false; - case RasterGLSurface: return true; - default: return QPlatformIntegration::hasCapability(cap); - } -} - -QPlatformNativeInterface *QEGLPlatformIntegration::nativeInterface() const -{ - return const_cast<QEGLPlatformIntegration *>(this); -} - -enum ResourceType { - EglDisplay, - EglWindow, - EglContext, - EglConfig, - NativeDisplay, - XlibDisplay -}; - -static int resourceType(const QByteArray &key) -{ - static const QByteArray names[] = { // match ResourceType - QByteArrayLiteral("egldisplay"), - QByteArrayLiteral("eglwindow"), - QByteArrayLiteral("eglcontext"), - QByteArrayLiteral("eglconfig"), - QByteArrayLiteral("nativedisplay"), - QByteArrayLiteral("display") - }; - const QByteArray *end = names + sizeof(names) / sizeof(names[0]); - const QByteArray *result = std::find(names, end, key); - if (result == end) - result = std::find(names, end, key.toLower()); - return int(result - names); -} - -void *QEGLPlatformIntegration::nativeResourceForIntegration(const QByteArray &resource) -{ - void *result = 0; - - switch (resourceType(resource)) { - case EglDisplay: - result = display(); - break; - case NativeDisplay: - result = reinterpret_cast<void*>(nativeDisplay()); - break; - default: - break; - } - - return result; -} - -void *QEGLPlatformIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *) -{ - void *result = 0; - - switch (resourceType(resource)) { - case XlibDisplay: - // Play nice when using the x11 hooks: Be compatible with xcb that allows querying - // the X Display pointer, which is nothing but our native display. - result = reinterpret_cast<void*>(nativeDisplay()); - break; - default: - break; - } - - return result; -} - -void *QEGLPlatformIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) -{ - void *result = 0; - - switch (resourceType(resource)) { - case EglDisplay: - if (window && window->handle()) - result = static_cast<QEGLPlatformScreen *>(window->handle()->screen())->display(); - else - result = display(); - break; - case EglWindow: - if (window && window->handle()) - result = reinterpret_cast<void*>(static_cast<QEGLPlatformWindow *>(window->handle())->eglWindow()); - break; - default: - break; - } - - return result; -} - -void *QEGLPlatformIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) -{ - void *result = 0; - - switch (resourceType(resource)) { - case EglContext: - if (context->handle()) - result = static_cast<QEGLPlatformContext *>(context->handle())->eglContext(); - break; - case EglConfig: - if (context->handle()) - result = static_cast<QEGLPlatformContext *>(context->handle())->eglConfig(); - break; - case EglDisplay: - if (context->handle()) - result = static_cast<QEGLPlatformContext *>(context->handle())->eglDisplay(); - break; - default: - break; - } - - return result; -} - -static void *eglContextForContext(QOpenGLContext *context) -{ - Q_ASSERT(context); - - QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(context->handle()); - if (!handle) - return 0; - - return handle->eglContext(); -} - -QPlatformNativeInterface::NativeResourceForContextFunction QEGLPlatformIntegration::nativeResourceFunctionForContext(const QByteArray &resource) -{ - QByteArray lowerCaseResource = resource.toLower(); - if (lowerCaseResource == "get_egl_context") - return NativeResourceForContextFunction(eglContextForContext); - - return 0; -} - -QFunctionPointer QEGLPlatformIntegration::platformFunction(const QByteArray &function) const -{ -#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) - if (function == QEglFSFunctions::loadKeymapTypeIdentifier()) - return QFunctionPointer(loadKeymapStatic); -#else - Q_UNUSED(function) -#endif - - return 0; -} - -void QEGLPlatformIntegration::loadKeymapStatic(const QString &filename) -{ -#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) - QEGLPlatformIntegration *self = static_cast<QEGLPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration()); - if (self->m_kbdMgr) - self->m_kbdMgr->loadKeymap(filename); - else - qWarning("QEGLPlatformIntegration: Cannot load keymap, no keyboard handler found"); -#else - Q_UNUSED(filename); -#endif -} - -void QEGLPlatformIntegration::createInputHandlers() -{ -#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) - m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); - new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); -#ifndef QT_NO_TSLIB - const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB"); - if (useTslib) - new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */); - else -#endif // QT_NO_TSLIB - new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); -#endif -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h deleted file mode 100644 index 42fbf8c8a1..0000000000 --- a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLPLATFORMINTEGRATION_H -#define QEGLPLATFORMINTEGRATION_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/QVariant> -#include <qpa/qplatformintegration.h> -#include <qpa/qplatformnativeinterface.h> -#include <EGL/egl.h> - -QT_BEGIN_NAMESPACE - -class QEGLPlatformWindow; -class QEGLPlatformContext; -class QFbVtHandler; -class QEvdevKeyboardManager; - -class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface -{ -public: - QEGLPlatformIntegration(); - ~QEGLPlatformIntegration(); - - void initialize() Q_DECL_OVERRIDE; - void destroy() Q_DECL_OVERRIDE; - - EGLDisplay display() const { return m_display; } - - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; - QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; - QPlatformServices *services() const Q_DECL_OVERRIDE; - QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; } - - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; - QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE; - - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; - - QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; - // QPlatformNativeInterface - void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; - void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) Q_DECL_OVERRIDE; - void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE; - void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE; - NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE; - - QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE; - - QFbVtHandler *vtHandler() { return m_vtHandler.data(); } - -protected: - virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0; - virtual QEGLPlatformContext *createContext(const QSurfaceFormat &format, - QPlatformOpenGLContext *shareContext, - EGLDisplay display, - QVariant *nativeHandle) const = 0; - virtual QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display, - const QSurfaceFormat &format, - QOffscreenSurface *surface) const = 0; - - virtual EGLNativeDisplayType nativeDisplay() const { return EGL_DEFAULT_DISPLAY; } - - void createInputHandlers(); - -private: - static void loadKeymapStatic(const QString &filename); - - EGLDisplay m_display; - QPlatformInputContext *m_inputContext; - QScopedPointer<QPlatformFontDatabase> m_fontDb; - QScopedPointer<QPlatformServices> m_services; - QScopedPointer<QFbVtHandler> m_vtHandler; - QEvdevKeyboardManager *m_kbdMgr; -}; - -QT_END_NAMESPACE - -#endif // QEGLPLATFORMINTEGRATION_H diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp deleted file mode 100644 index 61f8cdd9b4..0000000000 --- a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglplatformscreen_p.h" -#include "qeglplatformwindow_p.h" -#include <QtGui/qwindow.h> -#include <qpa/qwindowsysteminterface.h> -#include <QtPlatformSupport/private/qopenglcompositor_p.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QEGLPlatformScreen - \brief Base class for EGL-based platform screen implementations. - \since 5.2 - \internal - \ingroup qpa - */ - -QEGLPlatformScreen::QEGLPlatformScreen(EGLDisplay dpy) - : m_dpy(dpy), - m_pointerWindow(0) -{ -} - -QEGLPlatformScreen::~QEGLPlatformScreen() -{ - QOpenGLCompositor::destroy(); -} - -void QEGLPlatformScreen::handleCursorMove(const QPoint &pos) -{ - const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); - - // Generate enter and leave events like a real windowing system would do. - if (windows.isEmpty()) - return; - - // First window is always fullscreen. - if (windows.count() == 1) { - QWindow *window = windows[0]->sourceWindow(); - if (m_pointerWindow != window) { - m_pointerWindow = window; - QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos); - } - return; - } - - QWindow *enter = 0, *leave = 0; - for (int i = windows.count() - 1; i >= 0; --i) { - QWindow *window = windows[i]->sourceWindow(); - const QRect geom = window->geometry(); - if (geom.contains(pos)) { - if (m_pointerWindow != window) { - leave = m_pointerWindow; - m_pointerWindow = window; - enter = window; - } - break; - } - } - - if (enter && leave) - QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); -} - -QPixmap QEGLPlatformScreen::grabWindow(WId wid, int x, int y, int width, int height) const -{ - QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); - Q_ASSERT(!windows.isEmpty()); - - QImage img; - - if (static_cast<QEGLPlatformWindow *>(windows.first()->sourceWindow()->handle())->isRaster()) { - // Request the compositor to render everything into an FBO and read it back. This - // is of course slow, but it's safe and reliable. It will not include the mouse - // cursor, which is a plus. - img = compositor->grab(); - } else { - // Just a single OpenGL window without compositing. Do not support this case for now. Doing - // glReadPixels is not an option since it would read from the back buffer which may have - // undefined content when calling right after a swapBuffers (unless preserved swap is - // available and enabled, but we have no support for that). - qWarning("grabWindow: Not supported for non-composited OpenGL content. Use QQuickWindow::grabWindow() instead."); - return QPixmap(); - } - - if (!wid) { - const QSize screenSize = geometry().size(); - if (width < 0) - width = screenSize.width() - x; - if (height < 0) - height = screenSize.height() - y; - return QPixmap::fromImage(img).copy(x, y, width, height); - } - - foreach (QOpenGLCompositorWindow *w, windows) { - const QWindow *window = w->sourceWindow(); - if (window->winId() == wid) { - const QRect geom = window->geometry(); - if (width < 0) - width = geom.width() - x; - if (height < 0) - height = geom.height() - y; - QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height)); - rect &= window->geometry(); - return QPixmap::fromImage(img).copy(rect); - } - } - - return QPixmap(); -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h deleted file mode 100644 index 4a987f6860..0000000000 --- a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLPLATFORMSCREEN_H -#define QEGLPLATFORMSCREEN_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/QList> -#include <QtCore/QPoint> -#include <QtCore/qtextstream.h> -#include <qpa/qplatformscreen.h> -#include <EGL/egl.h> - -QT_BEGIN_NAMESPACE - -class QOpenGLContext; -class QWindow; -class QEGLPlatformWindow; - -class QEGLPlatformScreen : public QPlatformScreen -{ -public: - QEGLPlatformScreen(EGLDisplay dpy); - ~QEGLPlatformScreen(); - - EGLDisplay display() const { return m_dpy; } - - void handleCursorMove(const QPoint &pos); - - QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE; - -private: - EGLDisplay m_dpy; - QWindow *m_pointerWindow; -}; - -QT_END_NAMESPACE - -#endif // QEGLPLATFORMSCREEN_H diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp deleted file mode 100644 index 35f38ac29a..0000000000 --- a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qpa/qwindowsysteminterface.h> -#include <QtPlatformSupport/private/qopenglcompositor_p.h> -#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h> - -#include "qeglplatformwindow_p.h" -#include "qeglplatformscreen_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QEGLPlatformWindow - \brief Base class for EGL-based platform window implementations. - \since 5.2 - \internal - \ingroup qpa - - Lightweight class providing some basic platform window operations - and interfacing with QOpenGLCompositorBackingStore. - - Almost no QPlatformWindow functions are implemented here. This is - intentional because different platform plugins may use different - strategies for their window management (some may force fullscreen - windows, some may not, some may share the underlying native - surface, some may not, etc.) and therefore it is not sensible to - enforce anything for these functions. - - \note Subclasses are responsible for invoking this class' - implementation of create() and are expected to utilize the window - stack management functions (addWindow() etc.) in - QOpenGLCompositor. - */ - -QEGLPlatformWindow::QEGLPlatformWindow(QWindow *w) - : QPlatformWindow(w), - m_backingStore(0), - m_raster(false), - m_winId(0) -{ -} - -static WId newWId() -{ - static WId id = 0; - - if (id == std::numeric_limits<WId>::max()) - qWarning("QEGLPlatformWindow: Out of window IDs"); - - return ++id; -} - -void QEGLPlatformWindow::create() -{ - m_winId = newWId(); - - // Save the original surface type before changing to OpenGLSurface. - m_raster = (window()->surfaceType() == QSurface::RasterSurface); - if (m_raster) // change to OpenGL, but not for RasterGLSurface - window()->setSurfaceType(QSurface::OpenGLSurface); - - if (window()->type() == Qt::Desktop) { - QRect fullscreenRect(QPoint(), screen()->availableGeometry().size()); - QPlatformWindow::setGeometry(fullscreenRect); - QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect); - return; - } -} - -bool QEGLPlatformWindow::isRaster() const -{ - return m_raster || window()->surfaceType() == QSurface::RasterGLSurface; -} - -QWindow *QEGLPlatformWindow::sourceWindow() const -{ - return window(); -} - -const QPlatformTextureList *QEGLPlatformWindow::textures() const -{ - if (m_backingStore) - return m_backingStore->textures(); - - return 0; -} - -void QEGLPlatformWindow::endCompositing() -{ - if (m_backingStore) - m_backingStore->notifyComposited(); -} - -WId QEGLPlatformWindow::winId() const -{ - return m_winId; -} - -void QEGLPlatformWindow::setOpacity(qreal) -{ - if (!isRaster()) - qWarning("QEGLPlatformWindow: Cannot set opacity for non-raster windows"); - - // Nothing to do here. The opacity is stored in the QWindow. -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h deleted file mode 100644 index 852d690c92..0000000000 --- a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLPLATFORMWINDOW_H -#define QEGLPLATFORMWINDOW_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <qpa/qplatformwindow.h> -#include <QtPlatformSupport/private/qopenglcompositor_p.h> -#include <EGL/egl.h> - -QT_BEGIN_NAMESPACE - -class QOpenGLCompositorBackingStore; -class QPlatformTextureList; - -class QEGLPlatformWindow : public QPlatformWindow, public QOpenGLCompositorWindow -{ -public: - QEGLPlatformWindow(QWindow *w); - - virtual void create(); - - QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; } - void setBackingStore(QOpenGLCompositorBackingStore *backingStore) { m_backingStore = backingStore; } - bool isRaster() const; - - QWindow *sourceWindow() const Q_DECL_OVERRIDE; - const QPlatformTextureList *textures() const Q_DECL_OVERRIDE; - void endCompositing() Q_DECL_OVERRIDE; - - WId winId() const Q_DECL_OVERRIDE; - void setOpacity(qreal opacity) Q_DECL_OVERRIDE; - - virtual EGLNativeWindowType eglWindow() const = 0; - -private: - QOpenGLCompositorBackingStore *m_backingStore; - bool m_raster; - WId m_winId; -}; - -QT_END_NAMESPACE - -#endif // QEGLPLATFORMWINDOW_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp index 45224ccb87..d1814fb85d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp @@ -36,8 +36,8 @@ #include "qeglfskmsdevice.h" #include "qeglfskmsscreen.h" #include "qeglfskmscursor.h" +#include "qeglfscursor.h" -#include <QtPlatformSupport/private/qeglplatformcursor_p.h> #include <QtPlatformSupport/private/qdevicediscovery_p.h> #include <QtCore/QLoggingCategory> #include <QtCore/QJsonDocument> @@ -176,7 +176,7 @@ QPlatformCursor *QEglFSKmsIntegration::createCursor(QPlatformScreen *screen) con if (m_hwCursor) return Q_NULLPTR; else - return new QEGLPlatformCursor(screen); + return new QEglFSCursor(screen); } void QEglFSKmsIntegration::waitForVSync(QPlatformSurface *surface) const diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp index 5e49c224a0..b3e3f06f6c 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp @@ -35,11 +35,11 @@ #include "qeglfskmsscreen.h" #include "qeglfskmsdevice.h" #include "qeglfskmscursor.h" +#include "qeglfsintegration.h" #include <QtCore/QLoggingCategory> #include <QtGui/private/qguiapplication_p.h> -#include <QtPlatformSupport/private/qeglplatformintegration_p.h> #include <QtPlatformSupport/private/qfbvthandler_p.h> QT_BEGIN_NAMESPACE @@ -50,7 +50,7 @@ class QEglFSKmsInterruptHandler : public QObject { public: QEglFSKmsInterruptHandler(QEglFSKmsScreen *screen) : m_screen(screen) { - m_vtHandler = static_cast<QEGLPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration())->vtHandler(); + m_vtHandler = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->vtHandler(); connect(m_vtHandler, &QFbVtHandler::interrupted, this, &QEglFSKmsInterruptHandler::restoreVideoMode); connect(m_vtHandler, &QFbVtHandler::suspendRequested, this, &QEglFSKmsInterruptHandler::handleSuspendRequest); } diff --git a/src/plugins/platforms/eglfs/eglfs_device_lib.pro b/src/plugins/platforms/eglfs/eglfs_device_lib.pro index 729290706d..22a32663c7 100644 --- a/src/plugins/platforms/eglfs/eglfs_device_lib.pro +++ b/src/plugins/platforms/eglfs/eglfs_device_lib.pro @@ -26,6 +26,7 @@ DEFINES += QT_BUILD_EGL_DEVICE_LIB SOURCES += $$PWD/qeglfsintegration.cpp \ $$PWD/qeglfswindow.cpp \ $$PWD/qeglfsscreen.cpp \ + $$PWD/qeglfscursor.cpp \ $$PWD/qeglfshooks.cpp \ $$PWD/qeglfscontext.cpp \ $$PWD/qeglfsoffscreenwindow.cpp \ @@ -34,6 +35,7 @@ SOURCES += $$PWD/qeglfsintegration.cpp \ HEADERS += $$PWD/qeglfsintegration.h \ $$PWD/qeglfswindow.h \ $$PWD/qeglfsscreen.h \ + $$PWD/qeglfscursor.h \ $$PWD/qeglfshooks.h \ $$PWD/qeglfscontext.h \ $$PWD/qeglfsoffscreenwindow.h \ diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index 9216b7a85d..e2223aba43 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -32,15 +32,13 @@ ****************************************************************************/ #include <QtGui/QSurface> -#include <QtDebug> - -#include <QtPlatformSupport/private/qeglplatformcursor_p.h> #include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtPlatformSupport/private/qeglpbuffer_p.h> +#include "qeglfscontext.h" #include "qeglfswindow.h" #include "qeglfshooks.h" -#include "qeglfscontext.h" +#include "qeglfscursor.h" QT_BEGIN_NAMESPACE @@ -91,7 +89,7 @@ void QEglFSContext::swapBuffers(QPlatformSurface *surface) // draw the cursor if (surface->surface()->surfaceClass() == QSurface::Window) { QPlatformWindow *window = static_cast<QPlatformWindow *>(surface); - if (QEGLPlatformCursor *cursor = qobject_cast<QEGLPlatformCursor *>(window->screen()->cursor())) + if (QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(window->screen()->cursor())) cursor->paintOnScreen(); } diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp index 09243487c7..d81aa2eaf2 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp +++ b/src/plugins/platforms/eglfs/qeglfscursor.cpp @@ -31,33 +31,24 @@ ** ****************************************************************************/ +#include "qeglfscursor.h" +#include "qeglfsintegration.h" +#include "qeglfsscreen.h" + #include <qpa/qwindowsysteminterface.h> #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLShaderProgram> #include <QtCore/QJsonDocument> #include <QtCore/QJsonArray> #include <QtCore/QJsonObject> -#include <QtDebug> #include <QtGui/private/qguiapplication_p.h> -#include "qeglplatformcursor_p.h" -#include "qeglplatformintegration_p.h" -#include "qeglplatformscreen_p.h" - QT_BEGIN_NAMESPACE -/*! - \class QEGLPlatformCursor - \brief Mouse cursor implementation using OpenGL. - \since 5.2 - \internal - \ingroup qpa - */ - -QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen) +QEglFSCursor::QEglFSCursor(QPlatformScreen *screen) : m_visible(true), - m_screen(static_cast<QEGLPlatformScreen *>(screen)), + m_screen(static_cast<QEglFSScreen *>(screen)), m_program(0), m_vertexCoordEntry(0), m_textureCoordEntry(0), @@ -81,35 +72,35 @@ QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen) setCurrentCursor(&cursor); #endif - m_deviceListener = new QEGLPlatformCursorDeviceListener(this); + m_deviceListener = new QEglFSCursorDeviceListener(this); connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, - m_deviceListener, &QEGLPlatformCursorDeviceListener::onDeviceListChanged); + m_deviceListener, &QEglFSCursorDeviceListener::onDeviceListChanged); updateMouseStatus(); } -QEGLPlatformCursor::~QEGLPlatformCursor() +QEglFSCursor::~QEglFSCursor() { resetResources(); delete m_deviceListener; } -void QEGLPlatformCursor::updateMouseStatus() +void QEglFSCursor::updateMouseStatus() { m_visible = m_deviceListener->hasMouse(); } -bool QEGLPlatformCursorDeviceListener::hasMouse() const +bool QEglFSCursorDeviceListener::hasMouse() const { return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; } -void QEGLPlatformCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) +void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) { if (type == QInputDeviceManager::DeviceTypePointer) m_cursor->updateMouseStatus(); } -void QEGLPlatformCursor::resetResources() +void QEglFSCursor::resetResources() { if (QOpenGLContext::currentContext()) { delete m_program; @@ -122,7 +113,7 @@ void QEGLPlatformCursor::resetResources() m_cursorAtlas.texture = 0; } -void QEGLPlatformCursor::createShaderPrograms() +void QEglFSCursor::createShaderPrograms() { static const char *textureVertexProgram = "attribute highp vec2 vertexCoordEntry;\n" @@ -150,7 +141,7 @@ void QEGLPlatformCursor::createShaderPrograms() m_textureEntry = m_program->uniformLocation("texture"); } -void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image) +void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image) { if (!*texture) glGenTextures(1, texture); @@ -164,7 +155,7 @@ void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image) GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); } -void QEGLPlatformCursor::initCursorAtlas() +void QEglFSCursor::initCursorAtlas() { static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR"); if (json.isEmpty()) @@ -202,7 +193,7 @@ void QEGLPlatformCursor::initCursorAtlas() } #ifndef QT_NO_CURSOR -void QEGLPlatformCursor::changeCursor(QCursor *cursor, QWindow *window) +void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window) { Q_UNUSED(window); const QRect oldCursorRect = cursorRect(); @@ -210,7 +201,7 @@ void QEGLPlatformCursor::changeCursor(QCursor *cursor, QWindow *window) update(oldCursorRect | cursorRect()); } -bool QEGLPlatformCursor::setCurrentCursor(QCursor *cursor) +bool QEglFSCursor::setCurrentCursor(QCursor *cursor) { if (!m_visible) return false; @@ -263,7 +254,7 @@ private: QRegion m_region; }; -bool QEGLPlatformCursor::event(QEvent *e) +bool QEglFSCursor::event(QEvent *e) { if (e->type() == QEvent::User + 1) { CursorUpdateEvent *ev = static_cast<CursorUpdateEvent *>(e); @@ -275,7 +266,7 @@ bool QEGLPlatformCursor::event(QEvent *e) return QPlatformCursor::event(e); } -void QEGLPlatformCursor::update(const QRegion &rgn) +void QEglFSCursor::update(const QRegion &rgn) { if (!m_updateRequested) { // Must not flush the window system events directly from here since we are likely to @@ -286,17 +277,17 @@ void QEGLPlatformCursor::update(const QRegion &rgn) } } -QRect QEGLPlatformCursor::cursorRect() const +QRect QEglFSCursor::cursorRect() const { return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size); } -QPoint QEGLPlatformCursor::pos() const +QPoint QEglFSCursor::pos() const { return m_cursor.pos; } -void QEGLPlatformCursor::setPos(const QPoint &pos) +void QEglFSCursor::setPos(const QPoint &pos) { QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos); const QRect oldCursorRect = cursorRect(); @@ -305,7 +296,7 @@ void QEGLPlatformCursor::setPos(const QPoint &pos) m_screen->handleCursorMove(m_cursor.pos); } -void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event) +void QEglFSCursor::pointerEvent(const QMouseEvent &event) { if (event.type() != QEvent::MouseMove) return; @@ -315,7 +306,7 @@ void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event) m_screen->handleCursorMove(m_cursor.pos); } -void QEGLPlatformCursor::paintOnScreen() +void QEglFSCursor::paintOnScreen() { if (!m_visible) return; @@ -331,7 +322,7 @@ void QEGLPlatformCursor::paintOnScreen() draw(r); } -void QEGLPlatformCursor::draw(const QRectF &r) +void QEglFSCursor::draw(const QRectF &r) { if (!m_program) { // one time initialization diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h b/src/plugins/platforms/eglfs/qeglfscursor.h index b89dd1ca43..048f276137 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h +++ b/src/plugins/platforms/eglfs/qeglfscursor.h @@ -31,8 +31,8 @@ ** ****************************************************************************/ -#ifndef QEGLPLATFORMCURSOR_H -#define QEGLPLATFORMCURSOR_H +#ifndef QEGLFSCURSOR_H +#define QEGLFSCURSOR_H // // W A R N I N G @@ -45,6 +45,7 @@ // We mean it. // +#include "qeglfsglobal.h" #include <qpa/qplatformcursor.h> #include <qpa/qplatformscreen.h> #include <QtGui/QOpenGLFunctions> @@ -53,30 +54,30 @@ QT_BEGIN_NAMESPACE class QOpenGLShaderProgram; -class QEGLPlatformCursor; -class QEGLPlatformScreen; +class QEglFSCursor; +class QEglFSScreen; -class QEGLPlatformCursorDeviceListener : public QObject +class QEglFSCursorDeviceListener : public QObject { Q_OBJECT public: - QEGLPlatformCursorDeviceListener(QEGLPlatformCursor *cursor) : m_cursor(cursor) { } + QEglFSCursorDeviceListener(QEglFSCursor *cursor) : m_cursor(cursor) { } bool hasMouse() const; public slots: void onDeviceListChanged(QInputDeviceManager::DeviceType type); private: - QEGLPlatformCursor *m_cursor; + QEglFSCursor *m_cursor; }; -class QEGLPlatformCursor : public QPlatformCursor, protected QOpenGLFunctions +class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor, protected QOpenGLFunctions { Q_OBJECT public: - QEGLPlatformCursor(QPlatformScreen *screen); - ~QEGLPlatformCursor(); + QEglFSCursor(QPlatformScreen *screen); + ~QEglFSCursor(); #ifndef QT_NO_CURSOR void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE; @@ -128,15 +129,15 @@ private: } m_cursorAtlas; bool m_visible; - QEGLPlatformScreen *m_screen; + QEglFSScreen *m_screen; QOpenGLShaderProgram *m_program; int m_vertexCoordEntry; int m_textureCoordEntry; int m_textureEntry; - QEGLPlatformCursorDeviceListener *m_deviceListener; + QEglFSCursorDeviceListener *m_deviceListener; bool m_updateRequested; }; QT_END_NAMESPACE -#endif // QEGLPLATFORMCURSOR_H +#endif // QEGLFSCURSOR_H diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp index 7771c981dd..d27c949c8d 100644 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp @@ -33,8 +33,8 @@ #include "qeglfsdeviceintegration.h" #include "qeglfsintegration.h" +#include "qeglfscursor.h" #include <QtPlatformSupport/private/qeglconvenience_p.h> -#include <QtPlatformSupport/private/qeglplatformcursor_p.h> #include <QGuiApplication> #include <private/qguiapplication_p.h> #include <QScreen> @@ -286,7 +286,7 @@ bool QEGLDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap) QPlatformCursor *QEGLDeviceIntegration::createCursor(QPlatformScreen *screen) const { - return new QEGLPlatformCursor(screen); + return new QEglFSCursor(screen); } void QEGLDeviceIntegration::waitForVSync(QPlatformSurface *surface) const diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 5eb8485dc7..aec5a5e179 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -39,19 +39,41 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QScreen> #include <QtGui/QOffscreenSurface> -#include <qpa/qplatformcursor.h> +#include <QtGui/QWindow> +#include <qpa/qwindowsysteminterface.h> +#include <qpa/qplatforminputcontextfactory_p.h> #include "qeglfsintegration.h" #include "qeglfswindow.h" #include "qeglfshooks.h" #include "qeglfscontext.h" #include "qeglfsoffscreenwindow.h" +#include "qeglfscursor.h" #include <QtPlatformSupport/private/qeglconvenience_p.h> #include <QtPlatformSupport/private/qeglplatformcontext_p.h> #include <QtPlatformSupport/private/qeglpbuffer_p.h> + +#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h> +#include <QtPlatformSupport/private/qgenericunixservices_p.h> +#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> +#include <QtPlatformSupport/private/qfbvthandler_p.h> +#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h> + #include <QtPlatformHeaders/QEGLNativeContext> +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) +#include <QtPlatformSupport/private/qevdevmousemanager_p.h> +#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h> +#include <QtPlatformSupport/private/qevdevtouchmanager_p.h> +#endif + +#if !defined(QT_NO_TSLIB) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) +#include <QtPlatformSupport/private/qtslib_p.h> +#endif + +#include <QtPlatformHeaders/qeglfsfunctions.h> + #include <EGL/egl.h> static void initResources() @@ -64,21 +86,18 @@ static void initResources() QT_BEGIN_NAMESPACE QEglFSIntegration::QEglFSIntegration() + : m_display(EGL_NO_DISPLAY), + m_inputContext(0), + m_fontDb(new QGenericUnixFontDatabase), + m_services(new QGenericUnixServices), + m_kbdMgr(0), + m_disableInputHandlers(false) { - mDisableInputHandlers = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISABLE_INPUT"); + m_disableInputHandlers = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISABLE_INPUT"); initResources(); } -bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - // We assume that devices will have more and not less capabilities - if (qt_egl_device_integration()->hasCapability(cap)) - return true; - - return QEGLPlatformIntegration::hasCapability(cap); -} - void QEglFSIntegration::addScreen(QPlatformScreen *screen) { screenAdded(screen); @@ -93,9 +112,19 @@ void QEglFSIntegration::initialize() { qt_egl_device_integration()->platformInit(); - QEGLPlatformIntegration::initialize(); + m_display = eglGetDisplay(nativeDisplay()); + if (m_display == EGL_NO_DISPLAY) + qFatal("Could not open egl display"); + + EGLint major, minor; + if (!eglInitialize(m_display, &major, &minor)) + qFatal("Could not initialize egl display"); + + m_inputContext = QPlatformInputContextFactory::create(); + + m_vtHandler.reset(new QFbVtHandler); - if (!mDisableInputHandlers) + if (!m_disableInputHandlers) createInputHandlers(); if (qt_egl_device_integration()->usesDefaultScreen()) @@ -108,52 +137,276 @@ void QEglFSIntegration::destroy() { foreach (QWindow *w, qGuiApp->topLevelWindows()) w->destroy(); + qt_egl_device_integration()->screenDestroy(); - if (display() != EGL_NO_DISPLAY) - eglTerminate(display()); + + if (m_display != EGL_NO_DISPLAY) + eglTerminate(m_display); + qt_egl_device_integration()->platformDestroy(); } -EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const +QAbstractEventDispatcher *QEglFSIntegration::createEventDispatcher() const { - return qt_egl_device_integration()->platformDisplay(); + return createUnixEventDispatcher(); +} + +QPlatformServices *QEglFSIntegration::services() const +{ + return m_services.data(); } -QEGLPlatformWindow *QEglFSIntegration::createWindow(QWindow *window) const +QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const { - return new QEglFSWindow(window); + return m_fontDb.data(); } -QEGLPlatformContext *QEglFSIntegration::createContext(const QSurfaceFormat &format, - QPlatformOpenGLContext *shareContext, - EGLDisplay display, - QVariant *nativeHandle) const +QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const { + QOpenGLCompositorBackingStore *bs = new QOpenGLCompositorBackingStore(window); + if (!window->handle()) + window->create(); + static_cast<QEglFSWindow *>(window->handle())->setBackingStore(bs); + return bs; +} + +QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const +{ + QWindowSystemInterface::flushWindowSystemEvents(); + QEglFSWindow *w = new QEglFSWindow(window); + w->create(); + if (window->type() != Qt::ToolTip) + w->requestActivateWindow(); + return w; +} + +QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const +{ + // If there is a "root" window into which raster and QOpenGLWidget content is + // composited, all other contexts must share with its context. + QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context(); + EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display(); + QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle(); + QVariant nativeHandle = context->nativeHandle(); + QEglFSContext *ctx; - QSurfaceFormat adjustedFormat = qt_egl_device_integration()->surfaceFormatFor(format); - if (!nativeHandle || nativeHandle->isNull()) { - EGLConfig config = QEglFSIntegration::chooseConfig(display, adjustedFormat); - ctx = new QEglFSContext(adjustedFormat, shareContext, display, &config, QVariant()); + QSurfaceFormat adjustedFormat = qt_egl_device_integration()->surfaceFormatFor(context->format()); + if (nativeHandle.isNull()) { + EGLConfig config = QEglFSIntegration::chooseConfig(dpy, adjustedFormat); + ctx = new QEglFSContext(adjustedFormat, share, dpy, &config, QVariant()); } else { - ctx = new QEglFSContext(adjustedFormat, shareContext, display, 0, *nativeHandle); + ctx = new QEglFSContext(adjustedFormat, share, dpy, 0, nativeHandle); } - *nativeHandle = QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx->eglContext(), display)); + nativeHandle = QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx->eglContext(), dpy)); + + context->setNativeHandle(nativeHandle); return ctx; } -QPlatformOffscreenSurface *QEglFSIntegration::createOffscreenSurface(EGLDisplay display, - const QSurfaceFormat &format, - QOffscreenSurface *surface) const +QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const { - QSurfaceFormat fmt = qt_egl_device_integration()->surfaceFormatFor(format); + EGLDisplay dpy = surface->screen() ? static_cast<QEglFSScreen *>(surface->screen()->handle())->display() : display(); + QSurfaceFormat fmt = qt_egl_device_integration()->surfaceFormatFor(surface->requestedFormat()); if (qt_egl_device_integration()->supportsPBuffers()) - return new QEGLPbuffer(display, fmt, surface); + return new QEGLPbuffer(dpy, fmt, surface); else - return new QEglFSOffscreenWindow(display, fmt, surface); - + return new QEglFSOffscreenWindow(dpy, fmt, surface); // Never return null. Multiple QWindows are not supported by this plugin. } +bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const +{ + // We assume that devices will have more and not less capabilities + if (qt_egl_device_integration()->hasCapability(cap)) + return true; + + switch (cap) { + case ThreadedPixmaps: return true; + case OpenGL: return true; + case ThreadedOpenGL: return true; + case WindowManagement: return false; + case RasterGLSurface: return true; + default: return QPlatformIntegration::hasCapability(cap); + } +} + +QPlatformNativeInterface *QEglFSIntegration::nativeInterface() const +{ + return const_cast<QEglFSIntegration *>(this); +} + +enum ResourceType { + EglDisplay, + EglWindow, + EglContext, + EglConfig, + NativeDisplay, + XlibDisplay +}; + +static int resourceType(const QByteArray &key) +{ + static const QByteArray names[] = { // match ResourceType + QByteArrayLiteral("egldisplay"), + QByteArrayLiteral("eglwindow"), + QByteArrayLiteral("eglcontext"), + QByteArrayLiteral("eglconfig"), + QByteArrayLiteral("nativedisplay"), + QByteArrayLiteral("display") + }; + const QByteArray *end = names + sizeof(names) / sizeof(names[0]); + const QByteArray *result = std::find(names, end, key); + if (result == end) + result = std::find(names, end, key.toLower()); + return int(result - names); +} + +void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource) +{ + void *result = 0; + + switch (resourceType(resource)) { + case EglDisplay: + result = display(); + break; + case NativeDisplay: + result = reinterpret_cast<void*>(nativeDisplay()); + break; + default: + break; + } + + return result; +} + +void *QEglFSIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *) +{ + void *result = 0; + + switch (resourceType(resource)) { + case XlibDisplay: + // Play nice when using the x11 hooks: Be compatible with xcb that allows querying + // the X Display pointer, which is nothing but our native display. + result = reinterpret_cast<void*>(nativeDisplay()); + break; + default: + break; + } + + return result; +} + +void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) +{ + void *result = 0; + + switch (resourceType(resource)) { + case EglDisplay: + if (window && window->handle()) + result = static_cast<QEglFSScreen *>(window->handle()->screen())->display(); + else + result = display(); + break; + case EglWindow: + if (window && window->handle()) + result = reinterpret_cast<void*>(static_cast<QEglFSWindow *>(window->handle())->eglWindow()); + break; + default: + break; + } + + return result; +} + +void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) +{ + void *result = 0; + + switch (resourceType(resource)) { + case EglContext: + if (context->handle()) + result = static_cast<QEglFSContext *>(context->handle())->eglContext(); + break; + case EglConfig: + if (context->handle()) + result = static_cast<QEglFSContext *>(context->handle())->eglConfig(); + break; + case EglDisplay: + if (context->handle()) + result = static_cast<QEglFSContext *>(context->handle())->eglDisplay(); + break; + default: + break; + } + + return result; +} + +static void *eglContextForContext(QOpenGLContext *context) +{ + Q_ASSERT(context); + + QEglFSContext *handle = static_cast<QEglFSContext *>(context->handle()); + if (!handle) + return 0; + + return handle->eglContext(); +} + +QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource) +{ + QByteArray lowerCaseResource = resource.toLower(); + if (lowerCaseResource == "get_egl_context") + return NativeResourceForContextFunction(eglContextForContext); + + return 0; +} + +QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function) const +{ +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) + if (function == QEglFSFunctions::loadKeymapTypeIdentifier()) + return QFunctionPointer(loadKeymapStatic); +#else + Q_UNUSED(function) +#endif + + return 0; +} + +void QEglFSIntegration::loadKeymapStatic(const QString &filename) +{ +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) + QEglFSIntegration *self = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration()); + if (self->m_kbdMgr) + self->m_kbdMgr->loadKeymap(filename); + else + qWarning("QEglFSIntegration: Cannot load keymap, no keyboard handler found"); +#else + Q_UNUSED(filename); +#endif +} + +void QEglFSIntegration::createInputHandlers() +{ +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) + m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); + new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); +#ifndef QT_NO_TSLIB + const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB"); + if (useTslib) + new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */); + else +#endif // QT_NO_TSLIB + new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this); +#endif +} + +EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const +{ + return qt_egl_device_integration()->platformDisplay(); +} + EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format) { class Chooser : public QEglConfigChooser { diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index 11b643d540..98c7ee9f78 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -34,41 +34,72 @@ #ifndef QEGLFSINTEGRATION_H #define QEGLFSINTEGRATION_H -#include <QtPlatformSupport/private/qeglplatformintegration_p.h> +#include <QtCore/QVariant> +#include <qpa/qplatformintegration.h> +#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformscreen.h> #include <EGL/egl.h> #include "qeglfsglobal.h" QT_BEGIN_NAMESPACE -class Q_EGLFS_EXPORT QEglFSIntegration : public QEGLPlatformIntegration +class QEglFSWindow; +class QEglFSContext; +class QFbVtHandler; +class QEvdevKeyboardManager; + +class Q_EGLFS_EXPORT QEglFSIntegration : public QPlatformIntegration, public QPlatformNativeInterface { public: QEglFSIntegration(); - void addScreen(QPlatformScreen *screen); - void removeScreen(QPlatformScreen *screen); - void initialize() Q_DECL_OVERRIDE; void destroy() Q_DECL_OVERRIDE; + EGLDisplay display() const { return m_display; } + + QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; + QPlatformServices *services() const Q_DECL_OVERRIDE; + QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; } + + QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; + QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; - static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format); + QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; -protected: - QEGLPlatformWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE; - QEGLPlatformContext *createContext(const QSurfaceFormat &format, - QPlatformOpenGLContext *shareContext, - EGLDisplay display, - QVariant *nativeHandle) const Q_DECL_OVERRIDE; - QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display, - const QSurfaceFormat &format, - QOffscreenSurface *surface) const Q_DECL_OVERRIDE; - EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE; + // QPlatformNativeInterface + void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; + void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) Q_DECL_OVERRIDE; + void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE; + void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE; + NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE; + + QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE; + + QFbVtHandler *vtHandler() { return m_vtHandler.data(); } + + void addScreen(QPlatformScreen *screen); + void removeScreen(QPlatformScreen *screen); + + static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format); private: - bool mDisableInputHandlers; + EGLNativeDisplayType nativeDisplay() const; + void createInputHandlers(); + static void loadKeymapStatic(const QString &filename); + + EGLDisplay m_display; + QPlatformInputContext *m_inputContext; + QScopedPointer<QPlatformFontDatabase> m_fontDb; + QScopedPointer<QPlatformServices> m_services; + QScopedPointer<QFbVtHandler> m_vtHandler; + QEvdevKeyboardManager *m_kbdMgr; + bool m_disableInputHandlers; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 1b6e2307f8..22ec424451 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -32,7 +32,10 @@ ****************************************************************************/ #include <QtCore/qtextstream.h> -#include <QtGui/qpa/qplatformcursor.h> +#include <QtGui/qwindow.h> +#include <qpa/qwindowsysteminterface.h> +#include <qpa/qplatformcursor.h> +#include <QtPlatformSupport/private/qopenglcompositor_p.h> #include "qeglfsscreen.h" #include "qeglfswindow.h" @@ -41,7 +44,8 @@ QT_BEGIN_NAMESPACE QEglFSScreen::QEglFSScreen(EGLDisplay dpy) - : QEGLPlatformScreen(dpy), + : m_dpy(dpy), + m_pointerWindow(0), m_surface(EGL_NO_SURFACE), m_cursor(0) { @@ -51,6 +55,7 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy) QEglFSScreen::~QEglFSScreen() { delete m_cursor; + QOpenGLCompositor::destroy(); } QRect QEglFSScreen::geometry() const @@ -103,4 +108,89 @@ void QEglFSScreen::setPrimarySurface(EGLSurface surface) m_surface = surface; } +void QEglFSScreen::handleCursorMove(const QPoint &pos) +{ + const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); + + // Generate enter and leave events like a real windowing system would do. + if (windows.isEmpty()) + return; + + // First window is always fullscreen. + if (windows.count() == 1) { + QWindow *window = windows[0]->sourceWindow(); + if (m_pointerWindow != window) { + m_pointerWindow = window; + QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos); + } + return; + } + + QWindow *enter = 0, *leave = 0; + for (int i = windows.count() - 1; i >= 0; --i) { + QWindow *window = windows[i]->sourceWindow(); + const QRect geom = window->geometry(); + if (geom.contains(pos)) { + if (m_pointerWindow != window) { + leave = m_pointerWindow; + m_pointerWindow = window; + enter = window; + } + break; + } + } + + if (enter && leave) + QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); +} + +QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) const +{ + QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList<QOpenGLCompositorWindow *> windows = compositor->windows(); + Q_ASSERT(!windows.isEmpty()); + + QImage img; + + if (static_cast<QEglFSWindow *>(windows.first()->sourceWindow()->handle())->isRaster()) { + // Request the compositor to render everything into an FBO and read it back. This + // is of course slow, but it's safe and reliable. It will not include the mouse + // cursor, which is a plus. + img = compositor->grab(); + } else { + // Just a single OpenGL window without compositing. Do not support this case for now. Doing + // glReadPixels is not an option since it would read from the back buffer which may have + // undefined content when calling right after a swapBuffers (unless preserved swap is + // available and enabled, but we have no support for that). + qWarning("grabWindow: Not supported for non-composited OpenGL content. Use QQuickWindow::grabWindow() instead."); + return QPixmap(); + } + + if (!wid) { + const QSize screenSize = geometry().size(); + if (width < 0) + width = screenSize.width() - x; + if (height < 0) + height = screenSize.height() - y; + return QPixmap::fromImage(img).copy(x, y, width, height); + } + + foreach (QOpenGLCompositorWindow *w, windows) { + const QWindow *window = w->sourceWindow(); + if (window->winId() == wid) { + const QRect geom = window->geometry(); + if (width < 0) + width = geom.width() - x; + if (height < 0) + height = geom.height() - y; + QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height)); + rect &= window->geometry(); + return QPixmap::fromImage(img).copy(rect); + } + } + + return QPixmap(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index 07b6ff63ef..dc291285ad 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -35,7 +35,6 @@ #define QEGLFSSCREEN_H #include "qeglfsglobal.h" -#include <QtPlatformSupport/private/qeglplatformscreen_p.h> #include <EGL/egl.h> QT_BEGIN_NAMESPACE @@ -43,7 +42,7 @@ QT_BEGIN_NAMESPACE class QEglFSWindow; class QOpenGLContext; -class Q_EGLFS_EXPORT QEglFSScreen : public QEGLPlatformScreen +class Q_EGLFS_EXPORT QEglFSScreen : public QPlatformScreen { public: QEglFSScreen(EGLDisplay display); @@ -62,16 +61,23 @@ public: qreal refreshRate() const Q_DECL_OVERRIDE; + QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + EGLSurface primarySurface() const { return m_surface; } -protected: - void setPrimarySurface(EGLSurface surface); + EGLDisplay display() const { return m_dpy; } + + void handleCursorMove(const QPoint &pos); private: - friend class QEglFSWindow; + void setPrimarySurface(EGLSurface surface); + EGLDisplay m_dpy; + QWindow *m_pointerWindow; EGLSurface m_surface; QPlatformCursor *m_cursor; + + friend class QEglFSWindow; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index c0d51c94a5..c3b9dd6ef0 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -37,21 +37,23 @@ #include <private/qguiapplication_p.h> #include <QtGui/private/qopenglcontext_p.h> #include <QtGui/QOpenGLContext> -#include <QtPlatformSupport/private/qeglplatformcursor_p.h> #include <QtPlatformSupport/private/qeglconvenience_p.h> +#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h> #include "qeglfswindow.h" +#include "qeglfscursor.h" #include "qeglfshooks.h" -#include <QtDebug> - QT_BEGIN_NAMESPACE QEglFSWindow::QEglFSWindow(QWindow *w) - : QEGLPlatformWindow(w) - , m_surface(0) - , m_window(0) - , m_flags(0) + : QPlatformWindow(w), + m_backingStore(0), + m_raster(false), + m_winId(0), + m_surface(0), + m_window(0), + m_flags(0) { } @@ -60,12 +62,34 @@ QEglFSWindow::~QEglFSWindow() destroy(); } +static WId newWId() +{ + static WId id = 0; + + if (id == std::numeric_limits<WId>::max()) + qWarning("QEGLPlatformWindow: Out of window IDs"); + + return ++id; +} + void QEglFSWindow::create() { if (m_flags.testFlag(Created)) return; - QEGLPlatformWindow::create(); + m_winId = newWId(); + + // Save the original surface type before changing to OpenGLSurface. + m_raster = (window()->surfaceType() == QSurface::RasterSurface); + if (m_raster) // change to OpenGL, but not for RasterGLSurface + window()->setSurfaceType(QSurface::OpenGLSurface); + + if (window()->type() == Qt::Desktop) { + QRect fullscreenRect(QPoint(), screen()->availableGeometry().size()); + QPlatformWindow::setGeometry(fullscreenRect); + QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect); + return; + } m_flags = Created; @@ -120,7 +144,7 @@ void QEglFSWindow::destroy() { QEglFSScreen *screen = this->screen(); if (m_flags.testFlag(HasNativeWindow)) { - QEGLPlatformCursor *cursor = qobject_cast<QEGLPlatformCursor *>(screen->cursor()); + QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(screen->cursor()); if (cursor) cursor->resetResources(); @@ -265,4 +289,41 @@ QEglFSScreen *QEglFSWindow::screen() const return static_cast<QEglFSScreen *>(QPlatformWindow::screen()); } +bool QEglFSWindow::isRaster() const +{ + return m_raster || window()->surfaceType() == QSurface::RasterGLSurface; +} + +QWindow *QEglFSWindow::sourceWindow() const +{ + return window(); +} + +const QPlatformTextureList *QEglFSWindow::textures() const +{ + if (m_backingStore) + return m_backingStore->textures(); + + return 0; +} + +void QEglFSWindow::endCompositing() +{ + if (m_backingStore) + m_backingStore->notifyComposited(); +} + +WId QEglFSWindow::winId() const +{ + return m_winId; +} + +void QEglFSWindow::setOpacity(qreal) +{ + if (!isRaster()) + qWarning("QEglFSWindow: Cannot set opacity for non-raster windows"); + + // Nothing to do here. The opacity is stored in the QWindow. +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h index f9d207c153..53b9e18dc1 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ b/src/plugins/platforms/eglfs/qeglfswindow.h @@ -37,17 +37,23 @@ #include "qeglfsintegration.h" #include "qeglfsscreen.h" #include "qeglfsglobal.h" -#include <QtPlatformSupport/private/qeglplatformwindow_p.h> + +#include <qpa/qplatformwindow.h> +#include <QtPlatformSupport/private/qopenglcompositor_p.h> +#include <EGL/egl.h> QT_BEGIN_NAMESPACE -class Q_EGLFS_EXPORT QEglFSWindow : public QEGLPlatformWindow +class QOpenGLCompositorBackingStore; +class QPlatformTextureList; + +class Q_EGLFS_EXPORT QEglFSWindow : public QPlatformWindow, public QOpenGLCompositorWindow { public: QEglFSWindow(QWindow *w); ~QEglFSWindow(); - void create() Q_DECL_OVERRIDE; + void create(); void destroy(); void setGeometry(const QRect &) Q_DECL_OVERRIDE; @@ -58,13 +64,15 @@ public: void lower() Q_DECL_OVERRIDE; void propagateSizeHints() Q_DECL_OVERRIDE { } - void setOpacity(qreal) Q_DECL_OVERRIDE { } void setMask(const QRegion &) Q_DECL_OVERRIDE { } bool setKeyboardGrabEnabled(bool) Q_DECL_OVERRIDE { return false; } bool setMouseGrabEnabled(bool) Q_DECL_OVERRIDE { return false; } + void setOpacity(qreal) Q_DECL_OVERRIDE; + WId winId() const Q_DECL_OVERRIDE; QSurfaceFormat format() const Q_DECL_OVERRIDE; - EGLNativeWindowType eglWindow() const Q_DECL_OVERRIDE; + + EGLNativeWindowType eglWindow() const; EGLSurface surface() const; QEglFSScreen *screen() const; @@ -73,11 +81,22 @@ public: virtual void invalidateSurface() Q_DECL_OVERRIDE; virtual void resetSurface(); -protected: + QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; } + void setBackingStore(QOpenGLCompositorBackingStore *backingStore) { m_backingStore = backingStore; } + bool isRaster() const; + + QWindow *sourceWindow() const Q_DECL_OVERRIDE; + const QPlatformTextureList *textures() const Q_DECL_OVERRIDE; + void endCompositing() Q_DECL_OVERRIDE; + +private: + QOpenGLCompositorBackingStore *m_backingStore; + bool m_raster; + WId m_winId; + EGLSurface m_surface; EGLNativeWindowType m_window; -private: EGLConfig m_config; QSurfaceFormat m_format; |