From ec4eb4db61094179bc6a9ec26ec68fb710177053 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Fri, 27 May 2016 11:04:03 +0300 Subject: Install some eglfsdeviceintegration headers, as a private module This allows external integrations to be developed against it. Also uniforms all class names as QEglFSFoo. Change-Id: I72ff37c0fcdf1ccd37110b4c36874d6c99b2e743 Reviewed-by: Laszlo Agocs --- .../qeglfshooks_8726m.cpp | 2 +- src/plugins/platforms/eglfs/api/api.pri | 15 + src/plugins/platforms/eglfs/api/qeglfscursor.cpp | 509 +++++++++++++++++++++ src/plugins/platforms/eglfs/api/qeglfscursor_p.h | 147 ++++++ .../eglfs/api/qeglfsdeviceintegration.cpp | 382 ++++++++++++++++ .../eglfs/api/qeglfsdeviceintegration_p.h | 133 ++++++ src/plugins/platforms/eglfs/api/qeglfsglobal.h | 69 +++ src/plugins/platforms/eglfs/api/qeglfshooks.cpp | 136 ++++++ src/plugins/platforms/eglfs/api/qeglfshooks_p.h | 67 +++ src/plugins/platforms/eglfs/api/qeglfsscreen.cpp | 206 +++++++++ src/plugins/platforms/eglfs/api/qeglfsscreen_p.h | 105 +++++ src/plugins/platforms/eglfs/api/qeglfswindow.cpp | 336 ++++++++++++++ src/plugins/platforms/eglfs/api/qeglfswindow_p.h | 129 ++++++ .../deviceintegration/eglfs_brcm/eglfs_brcm.pro | 2 +- .../eglfs_brcm/qeglfsbrcmintegration.h | 4 +- .../eglfs_brcm/qeglfsbrcmmain.cpp | 8 +- .../deviceintegration/eglfs_kms/eglfs_kms.pro | 2 +- .../eglfs_kms/qeglfskmsgbmintegration.cpp | 2 +- .../eglfs_kms/qeglfskmsgbmmain.cpp | 8 +- .../eglfs_kms_egldevice/eglfs_kms_egldevice.pro | 2 +- .../qeglfskmsegldeviceintegration.cpp | 4 +- .../eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp | 6 +- .../eglfs_kms_support/eglfs_kms_support.pro | 2 +- .../eglfs_kms_support/qeglfskmsintegration.cpp | 4 +- .../eglfs_kms_support/qeglfskmsintegration.h | 4 +- .../eglfs_kms_support/qeglfskmsscreen.h | 2 +- .../deviceintegration/eglfs_mali/eglfs_mali.pro | 2 +- .../eglfs_mali/qeglfsmaliintegration.cpp | 2 +- .../eglfs_mali/qeglfsmaliintegration.h | 4 +- .../eglfs_mali/qeglfsmalimain.cpp | 8 +- .../deviceintegration/eglfs_viv/eglfs_viv.pro | 2 +- .../eglfs_viv/qeglfsvivintegration.cpp | 2 +- .../eglfs_viv/qeglfsvivintegration.h | 4 +- .../deviceintegration/eglfs_viv/qeglfsvivmain.cpp | 8 +- .../eglfs_viv_wl/eglfs_viv_wl.pro | 2 +- .../eglfs_viv_wl/qeglfsvivwlintegration.cpp | 2 +- .../eglfs_viv_wl/qeglfsvivwlintegration.h | 4 +- .../eglfs_viv_wl/qeglfsvivwlmain.cpp | 8 +- .../deviceintegration/eglfs_x11/eglfs_x11.pro | 2 +- .../eglfs_x11/qeglfsx11integration.h | 4 +- .../deviceintegration/eglfs_x11/qeglfsx11main.cpp | 8 +- src/plugins/platforms/eglfs/eglfs-plugin.pro | 2 +- src/plugins/platforms/eglfs/eglfs.pro | 2 +- src/plugins/platforms/eglfs/eglfs_device_lib.pro | 54 --- .../platforms/eglfs/eglfsdeviceintegration.pro | 47 ++ src/plugins/platforms/eglfs/qeglfscontext.cpp | 6 +- src/plugins/platforms/eglfs/qeglfscursor.cpp | 509 --------------------- src/plugins/platforms/eglfs/qeglfscursor.h | 147 ------ .../platforms/eglfs/qeglfsdeviceintegration.cpp | 348 -------------- .../platforms/eglfs/qeglfsdeviceintegration.h | 131 ------ src/plugins/platforms/eglfs/qeglfsglobal.h | 64 --- src/plugins/platforms/eglfs/qeglfshooks.cpp | 136 ------ src/plugins/platforms/eglfs/qeglfshooks.h | 56 --- src/plugins/platforms/eglfs/qeglfsintegration.cpp | 26 +- src/plugins/platforms/eglfs/qeglfsintegration.h | 2 - .../platforms/eglfs/qeglfsoffscreenwindow.cpp | 2 +- src/plugins/platforms/eglfs/qeglfsscreen.cpp | 206 --------- src/plugins/platforms/eglfs/qeglfsscreen.h | 92 ---- src/plugins/platforms/eglfs/qeglfswindow.cpp | 335 -------------- src/plugins/platforms/eglfs/qeglfswindow.h | 118 ----- sync.profile | 2 + 61 files changed, 2350 insertions(+), 2283 deletions(-) create mode 100644 src/plugins/platforms/eglfs/api/api.pri create mode 100644 src/plugins/platforms/eglfs/api/qeglfscursor.cpp create mode 100644 src/plugins/platforms/eglfs/api/qeglfscursor_p.h create mode 100644 src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp create mode 100644 src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h create mode 100644 src/plugins/platforms/eglfs/api/qeglfsglobal.h create mode 100644 src/plugins/platforms/eglfs/api/qeglfshooks.cpp create mode 100644 src/plugins/platforms/eglfs/api/qeglfshooks_p.h create mode 100644 src/plugins/platforms/eglfs/api/qeglfsscreen.cpp create mode 100644 src/plugins/platforms/eglfs/api/qeglfsscreen_p.h create mode 100644 src/plugins/platforms/eglfs/api/qeglfswindow.cpp create mode 100644 src/plugins/platforms/eglfs/api/qeglfswindow_p.h delete mode 100644 src/plugins/platforms/eglfs/eglfs_device_lib.pro create mode 100644 src/plugins/platforms/eglfs/eglfsdeviceintegration.pro delete mode 100644 src/plugins/platforms/eglfs/qeglfscursor.cpp delete mode 100644 src/plugins/platforms/eglfs/qeglfscursor.h delete mode 100644 src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp delete mode 100644 src/plugins/platforms/eglfs/qeglfsdeviceintegration.h delete mode 100644 src/plugins/platforms/eglfs/qeglfsglobal.h delete mode 100644 src/plugins/platforms/eglfs/qeglfshooks.cpp delete mode 100644 src/plugins/platforms/eglfs/qeglfshooks.h delete mode 100644 src/plugins/platforms/eglfs/qeglfsscreen.cpp delete mode 100644 src/plugins/platforms/eglfs/qeglfsscreen.h delete mode 100644 src/plugins/platforms/eglfs/qeglfswindow.cpp delete mode 100644 src/plugins/platforms/eglfs/qeglfswindow.h diff --git a/mkspecs/devices/linux-arm-amlogic-8726M-g++/qeglfshooks_8726m.cpp b/mkspecs/devices/linux-arm-amlogic-8726M-g++/qeglfshooks_8726m.cpp index 4dac018810..184a47b683 100644 --- a/mkspecs/devices/linux-arm-amlogic-8726M-g++/qeglfshooks_8726m.cpp +++ b/mkspecs/devices/linux-arm-amlogic-8726M-g++/qeglfshooks_8726m.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include "qeglfshooks.h" +#include "private/qeglfshooks_p.h" #include #include #include diff --git a/src/plugins/platforms/eglfs/api/api.pri b/src/plugins/platforms/eglfs/api/api.pri new file mode 100644 index 0000000000..957dee554c --- /dev/null +++ b/src/plugins/platforms/eglfs/api/api.pri @@ -0,0 +1,15 @@ + +SOURCES += $$PWD/qeglfswindow.cpp \ + $$PWD/qeglfsscreen.cpp \ + $$PWD/qeglfscursor.cpp \ + $$PWD/qeglfshooks.cpp \ + $$PWD/qeglfsdeviceintegration.cpp + +HEADERS += $$PWD/qeglfswindow_p.h \ + $$PWD/qeglfsscreen_p.h \ + $$PWD/qeglfscursor_p.h \ + $$PWD/qeglfshooks_p.h \ + $$PWD/qeglfsdeviceintegration_p.h \ + $$PWD/qeglfsglobal.h + +INCLUDEPATH += $$PWD diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp new file mode 100644 index 0000000000..ffee21a9b0 --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp @@ -0,0 +1,509 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfscursor_p.h" +#include "qeglfsintegration.h" +#include "qeglfsscreen_p.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifndef GL_VERTEX_ARRAY_BINDING +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#endif + +QT_BEGIN_NAMESPACE + +QEglFSCursor::QEglFSCursor(QPlatformScreen *screen) + : m_visible(true), + m_screen(static_cast(screen)), + m_program(0), + m_textureEntry(0), + m_deviceListener(0), + m_updateRequested(false) +{ + QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); + if (!hideCursorVal.isEmpty()) + m_visible = hideCursorVal.toInt() == 0; + if (!m_visible) + return; + + // Try to load the cursor atlas. If this fails, m_visible is set to false and + // paintOnScreen() and setCurrentCursor() become no-ops. + initCursorAtlas(); + + // initialize the cursor +#ifndef QT_NO_CURSOR + QCursor cursor(Qt::ArrowCursor); + setCurrentCursor(&cursor); +#endif + + m_deviceListener = new QEglFSCursorDeviceListener(this); + connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, + m_deviceListener, &QEglFSCursorDeviceListener::onDeviceListChanged); + updateMouseStatus(); +} + +QEglFSCursor::~QEglFSCursor() +{ + resetResources(); + delete m_deviceListener; +} + +void QEglFSCursor::updateMouseStatus() +{ + m_visible = m_deviceListener->hasMouse(); +} + +bool QEglFSCursorDeviceListener::hasMouse() const +{ + return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; +} + +void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) +{ + if (type == QInputDeviceManager::DeviceTypePointer) + m_cursor->updateMouseStatus(); +} + +void QEglFSCursor::resetResources() +{ + if (QOpenGLContext::currentContext()) { + delete m_program; + glDeleteTextures(1, &m_cursor.customCursorTexture); + glDeleteTextures(1, &m_cursorAtlas.texture); + } + m_program = 0; + m_cursor.customCursorTexture = 0; + m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull(); + m_cursorAtlas.texture = 0; +} + +void QEglFSCursor::createShaderPrograms() +{ + static const char *textureVertexProgram = + "attribute highp vec2 vertexCoordEntry;\n" + "attribute highp vec2 textureCoordEntry;\n" + "varying highp vec2 textureCoord;\n" + "void main() {\n" + " textureCoord = textureCoordEntry;\n" + " gl_Position = vec4(vertexCoordEntry, 1.0, 1.0);\n" + "}\n"; + + static const char *textureFragmentProgram = + "uniform sampler2D texture;\n" + "varying highp vec2 textureCoord;\n" + "void main() {\n" + " gl_FragColor = texture2D(texture, textureCoord).bgra;\n" + "}\n"; + + m_program = new QOpenGLShaderProgram; + m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); + m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram); + m_program->bindAttributeLocation("vertexCoordEntry", 0); + m_program->bindAttributeLocation("textureCoordEntry", 1); + m_program->link(); + + m_textureEntry = m_program->uniformLocation("texture"); +} + +void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image) +{ + if (!*texture) + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D, *texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, image.width(), image.height(), 0 /* border */, + GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); +} + +void QEglFSCursor::initCursorAtlas() +{ + static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR"); + if (json.isEmpty()) + json = ":/cursor.json"; + + QFile file(QString::fromUtf8(json)); + if (!file.open(QFile::ReadOnly)) { + m_visible = false; + return; + } + + QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); + QJsonObject object = doc.object(); + + QString atlas = object.value(QLatin1String("image")).toString(); + Q_ASSERT(!atlas.isEmpty()); + + const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble(); + Q_ASSERT(cursorsPerRow); + m_cursorAtlas.cursorsPerRow = cursorsPerRow; + + const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray(); + Q_ASSERT(hotSpots.count() == Qt::LastCursor + 1); + for (int i = 0; i < hotSpots.count(); i++) { + QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble()); + m_cursorAtlas.hotSpots << hotSpot; + } + + QImage image = QImage(atlas).convertToFormat(QImage::Format_ARGB32_Premultiplied); + m_cursorAtlas.cursorWidth = image.width() / m_cursorAtlas.cursorsPerRow; + m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + cursorsPerRow) / cursorsPerRow); + m_cursorAtlas.width = image.width(); + m_cursorAtlas.height = image.height(); + m_cursorAtlas.image = image; +} + +#ifndef QT_NO_CURSOR +void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window) +{ + Q_UNUSED(window); + const QRect oldCursorRect = cursorRect(); + if (setCurrentCursor(cursor)) + update(oldCursorRect | cursorRect()); +} + +bool QEglFSCursor::setCurrentCursor(QCursor *cursor) +{ + if (!m_visible) + return false; + + const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor) + return false; + + if (m_cursor.shape == Qt::BitmapCursor) { + m_cursor.customCursorImage = QImage(); + m_cursor.customCursorPending = false; + } + m_cursor.shape = newShape; + if (newShape != Qt::BitmapCursor) { // standard cursor + const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width, + hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height; + m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow), + hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow), + ws, hs); + m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape]; + m_cursor.texture = m_cursorAtlas.texture; + m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight); + } else { + QImage image = cursor->pixmap().toImage(); + m_cursor.textureRect = QRectF(0, 0, 1, 1); + m_cursor.hotSpot = cursor->hotSpot(); + m_cursor.texture = 0; // will get updated in the next render() + m_cursor.size = image.size(); + m_cursor.customCursorImage = image; + m_cursor.customCursorPending = true; + } + + return true; +} +#endif + +class CursorUpdateEvent : public QEvent +{ +public: + CursorUpdateEvent(const QPoint &pos, const QRegion &rgn) + : QEvent(QEvent::Type(QEvent::User + 1)), + m_pos(pos), + m_region(rgn) + { } + QPoint pos() const { return m_pos; } + QRegion region() const { return m_region; } + +private: + QPoint m_pos; + QRegion m_region; +}; + +bool QEglFSCursor::event(QEvent *e) +{ + if (e->type() == QEvent::User + 1) { + CursorUpdateEvent *ev = static_cast(e); + m_updateRequested = false; + QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(ev->pos()), ev->region()); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); + return true; + } + return QPlatformCursor::event(e); +} + +void QEglFSCursor::update(const QRegion &rgn) +{ + if (!m_updateRequested) { + // Must not flush the window system events directly from here since we are likely to + // be a called directly from QGuiApplication's processMouseEvents. Flushing events + // could cause reentering by dispatching more queued mouse events. + m_updateRequested = true; + QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rgn)); + } +} + +QRect QEglFSCursor::cursorRect() const +{ + return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size); +} + +QPoint QEglFSCursor::pos() const +{ + return m_cursor.pos; +} + +void QEglFSCursor::setPos(const QPoint &pos) +{ + QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos); + const QRect oldCursorRect = cursorRect(); + m_cursor.pos = pos; + update(oldCursorRect | cursorRect()); + m_screen->handleCursorMove(m_cursor.pos); +} + +void QEglFSCursor::pointerEvent(const QMouseEvent &event) +{ + if (event.type() != QEvent::MouseMove) + return; + const QRect oldCursorRect = cursorRect(); + m_cursor.pos = event.screenPos().toPoint(); + update(oldCursorRect | cursorRect()); + m_screen->handleCursorMove(m_cursor.pos); +} + +void QEglFSCursor::paintOnScreen() +{ + if (!m_visible) + return; + + const QRectF cr = cursorRect(); + const QRect screenRect(m_screen->geometry()); + const GLfloat x1 = 2 * (cr.left() / screenRect.width()) - 1; + const GLfloat x2 = 2 * (cr.right() / screenRect.width()) - 1; + const GLfloat y1 = 1 - (cr.top() / screenRect.height()) * 2; + const GLfloat y2 = 1 - (cr.bottom() / screenRect.height()) * 2; + QRectF r(QPointF(x1, y1), QPointF(x2, y2)); + + draw(r); +} + +// In order to prevent breaking code doing custom OpenGL rendering while +// expecting the state in the context unchanged, save and restore all the state +// we touch. The exception is Qt Quick where the scenegraph is known to be able +// to deal with the changes we make. +struct StateSaver +{ + StateSaver() { + f = QOpenGLContext::currentContext()->functions(); + vaoHelper = new QOpenGLVertexArrayObjectHelper(QOpenGLContext::currentContext()); + + static bool windowsChecked = false; + static bool shouldSave = true; + if (!windowsChecked) { + windowsChecked = true; + QWindowList windows = QGuiApplication::allWindows(); + if (!windows.isEmpty() && windows[0]->inherits("QQuickWindow")) + shouldSave = false; + } + saved = shouldSave; + if (!shouldSave) + return; + + f->glGetIntegerv(GL_CURRENT_PROGRAM, &program); + f->glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture); + f->glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); + f->glGetIntegerv(GL_FRONT_FACE, &frontFace); + cull = f->glIsEnabled(GL_CULL_FACE); + depthTest = f->glIsEnabled(GL_DEPTH_TEST); + blend = f->glIsEnabled(GL_BLEND); + f->glGetIntegerv(GL_BLEND_SRC_RGB, blendFunc); + f->glGetIntegerv(GL_BLEND_SRC_ALPHA, blendFunc + 1); + f->glGetIntegerv(GL_BLEND_DST_RGB, blendFunc + 2); + f->glGetIntegerv(GL_BLEND_DST_ALPHA, blendFunc + 3); + f->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &arrayBuf); + if (vaoHelper->isValid()) + f->glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vao); + for (int i = 0; i < 2; ++i) { + f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &va[i].enabled); + f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &va[i].size); + f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &va[i].type); + f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &va[i].normalized); + f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &va[i].stride); + f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &va[i].buffer); + f->glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &va[i].pointer); + } + } + ~StateSaver() { + if (saved) { + f->glUseProgram(program); + f->glBindTexture(GL_TEXTURE_2D, texture); + f->glActiveTexture(activeTexture); + f->glFrontFace(frontFace); + if (cull) + f->glEnable(GL_CULL_FACE); + else + f->glDisable(GL_CULL_FACE); + if (depthTest) + f->glEnable(GL_DEPTH_TEST); + else + f->glDisable(GL_DEPTH_TEST); + if (blend) + f->glEnable(GL_BLEND); + else + f->glDisable(GL_BLEND); + f->glBlendFuncSeparate(blendFunc[0], blendFunc[1], blendFunc[2], blendFunc[3]); + f->glBindBuffer(GL_ARRAY_BUFFER, arrayBuf); + if (vaoHelper->isValid()) + vaoHelper->glBindVertexArray(vao); + for (int i = 0; i < 2; ++i) { + if (va[i].enabled) + f->glEnableVertexAttribArray(i); + else + f->glDisableVertexAttribArray(i); + f->glBindBuffer(GL_ARRAY_BUFFER, va[i].buffer); + f->glVertexAttribPointer(i, va[i].size, va[i].type, va[i].normalized, va[i].stride, va[i].pointer); + } + } + delete vaoHelper; + } + QOpenGLFunctions *f; + QOpenGLVertexArrayObjectHelper *vaoHelper; + bool saved; + GLint program; + GLint texture; + GLint activeTexture; + GLint frontFace; + bool cull; + bool depthTest; + bool blend; + GLint blendFunc[4]; + GLint vao; + GLint arrayBuf; + struct { GLint enabled, type, size, normalized, stride, buffer; GLvoid *pointer; } va[2]; +}; + +void QEglFSCursor::draw(const QRectF &r) +{ + StateSaver stateSaver; + + if (!m_program) { + // one time initialization + initializeOpenGLFunctions(); + + createShaderPrograms(); + + if (!m_cursorAtlas.texture) { + createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image); + + if (m_cursor.shape != Qt::BitmapCursor) + m_cursor.texture = m_cursorAtlas.texture; + } + } + + if (m_cursor.shape == Qt::BitmapCursor && m_cursor.customCursorPending) { + // upload the custom cursor + createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage); + m_cursor.texture = m_cursor.customCursorTexture; + m_cursor.customCursorPending = false; + } + + Q_ASSERT(m_cursor.texture); + + m_program->bind(); + + const GLfloat x1 = r.left(); + const GLfloat x2 = r.right(); + const GLfloat y1 = r.top(); + const GLfloat y2 = r.bottom(); + const GLfloat cursorCoordinates[] = { + x1, y2, + x2, y2, + x1, y1, + x2, y1 + }; + + const GLfloat s1 = m_cursor.textureRect.left(); + const GLfloat s2 = m_cursor.textureRect.right(); + const GLfloat t1 = m_cursor.textureRect.top(); + const GLfloat t2 = m_cursor.textureRect.bottom(); + const GLfloat textureCoordinates[] = { + s1, t2, + s2, t2, + s1, t1, + s2, t1 + }; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_cursor.texture); + + if (stateSaver.vaoHelper->isValid()) + stateSaver.vaoHelper->glBindVertexArray(0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + m_program->enableAttributeArray(0); + m_program->enableAttributeArray(1); + m_program->setAttributeArray(0, cursorCoordinates, 2); + m_program->setAttributeArray(1, textureCoordinates, 2); + + m_program->setUniformValue(m_textureEntry, 0); + + glDisable(GL_CULL_FACE); + glFrontFace(GL_CCW); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + m_program->disableAttributeArray(0); + m_program->disableAttributeArray(1); + m_program->release(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h new file mode 100644 index 0000000000..bb30d53d6c --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSCURSOR_H +#define QEGLFSCURSOR_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 "qeglfsglobal.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QOpenGLShaderProgram; +class QEglFSCursor; +class QEglFSScreen; + +class QEglFSCursorDeviceListener : public QObject +{ + Q_OBJECT + +public: + QEglFSCursorDeviceListener(QEglFSCursor *cursor) : m_cursor(cursor) { } + bool hasMouse() const; + +public slots: + void onDeviceListChanged(QInputDeviceManager::DeviceType type); + +private: + QEglFSCursor *m_cursor; +}; + +class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor, protected QOpenGLFunctions +{ + Q_OBJECT +public: + QEglFSCursor(QPlatformScreen *screen); + ~QEglFSCursor(); + +#ifndef QT_NO_CURSOR + void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE; +#endif + void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE; + QPoint pos() const Q_DECL_OVERRIDE; + void setPos(const QPoint &pos) Q_DECL_OVERRIDE; + + QRect cursorRect() const; + void paintOnScreen(); + void resetResources(); + + void updateMouseStatus(); + +private: + bool event(QEvent *e) Q_DECL_OVERRIDE; +#ifndef QT_NO_CURSOR + bool setCurrentCursor(QCursor *cursor); +#endif + void draw(const QRectF &rect); + void update(const QRegion ®ion); + void createShaderPrograms(); + void createCursorTexture(uint *texture, const QImage &image); + void initCursorAtlas(); + + // current cursor information + struct Cursor { + Cursor() : texture(0), shape(Qt::BlankCursor), customCursorTexture(0), customCursorPending(false) { } + uint texture; // a texture from 'image' or the atlas + Qt::CursorShape shape; + QRectF textureRect; // normalized rect inside texture + QSize size; // size of the cursor + QPoint hotSpot; + QImage customCursorImage; + QPoint pos; // current cursor position + uint customCursorTexture; + bool customCursorPending; + } m_cursor; + + // cursor atlas information + struct CursorAtlas { + CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { } + int cursorsPerRow; + uint texture; + int width, height; // width and height of the atlas + int cursorWidth, cursorHeight; // width and height of cursors inside the atlas + QList hotSpots; + QImage image; // valid until it's uploaded + } m_cursorAtlas; + + bool m_visible; + QEglFSScreen *m_screen; + QOpenGLShaderProgram *m_program; + int m_textureEntry; + QEglFSCursorDeviceListener *m_deviceListener; + bool m_updateRequested; +}; + +QT_END_NAMESPACE + +#endif // QEGLFSCURSOR_H diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp new file mode 100644 index 0000000000..a735f4dba4 --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp @@ -0,0 +1,382 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qeglfsdeviceintegration_p.h" +#include "qeglfsintegration.h" +#include "qeglfscursor_p.h" +#include "qeglfswindow_p.h" +#include "qeglfshooks_p.h" + +#include +#include +#include +#include +#include +#include +#include + +#if defined(Q_OS_LINUX) +#include +#include +#include +#include +#endif + +#include +#include + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(qLcEglDevDebug, "qt.qpa.egldeviceintegration") + +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, + (QEglFSDeviceIntegrationFactoryInterface_iid, QLatin1String("/egldeviceintegrations"), Qt::CaseInsensitive)) + +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, + (QEglFSDeviceIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) + +static inline QEglFSDeviceIntegration *loadIntegration(QFactoryLoader *loader, const QString &key) +{ + const int index = loader->indexOf(key); + if (index != -1) { + QObject *plugin = loader->instance(index); + if (QEglFSDeviceIntegrationPlugin *factory = qobject_cast(plugin)) { + if (QEglFSDeviceIntegration *result = factory->create()) + return result; + } + } + return Q_NULLPTR; +} + +#endif // QT_NO_LIBRARY + +QStringList QEglFSDeviceIntegrationFactory::keys(const QString &pluginPath) +{ + QStringList list; +#ifndef QT_NO_LIBRARY + 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); + } + } +#else + Q_UNUSED(pluginPath); +#endif + list.append(loader()->keyMap().values()); + qCDebug(qLcEglDevDebug) << "EGL device integration plugin keys:" << list; + return list; +} + +QEglFSDeviceIntegration *QEglFSDeviceIntegrationFactory::create(const QString &key, const QString &pluginPath) +{ + QEglFSDeviceIntegration *integration = Q_NULLPTR; +#ifndef QT_NO_LIBRARY + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + integration = qLoadPlugin(directLoader(), key); + } +#else + Q_UNUSED(pluginPath); +#endif + if (!integration) + integration = qLoadPlugin(loader(), key); + if (integration) + qCDebug(qLcEglDevDebug) << "Using EGL device integration" << key; + else + qCWarning(qLcEglDevDebug) << "Failed to load EGL device integration" << key; + + return integration; +} + +static int framebuffer = -1; + +QByteArray QEglFSDeviceIntegration::fbDeviceName() const +{ +#ifdef Q_OS_LINUX + QByteArray fbDev = qgetenv("QT_QPA_EGLFS_FB"); + if (fbDev.isEmpty()) + fbDev = QByteArrayLiteral("/dev/fb0"); + + return fbDev; +#else + return QByteArray(); +#endif +} + +int QEglFSDeviceIntegration::framebufferIndex() const +{ + int fbIndex = 0; +#ifndef QT_NO_REGULAREXPRESSION + QRegularExpression fbIndexRx(QLatin1String("fb(\\d+)")); + QRegularExpressionMatch match = fbIndexRx.match(QString::fromLocal8Bit(fbDeviceName())); + if (match.hasMatch()) + fbIndex = match.captured(1).toInt(); +#endif + return fbIndex; +} + +void QEglFSDeviceIntegration::platformInit() +{ +#ifdef Q_OS_LINUX + QByteArray fbDev = fbDeviceName(); + + framebuffer = qt_safe_open(fbDev, O_RDONLY); + + if (Q_UNLIKELY(framebuffer == -1)) { + qWarning("EGLFS: Failed to open %s", fbDev.constData()); + qFatal("EGLFS: Can't continue without a display"); + } + +#ifdef FBIOBLANK + ioctl(framebuffer, FBIOBLANK, VESA_NO_BLANKING); +#endif +#endif +} + +void QEglFSDeviceIntegration::platformDestroy() +{ +#ifdef Q_OS_LINUX + if (framebuffer != -1) + close(framebuffer); +#endif +} + +EGLNativeDisplayType QEglFSDeviceIntegration::platformDisplay() const +{ + return EGL_DEFAULT_DISPLAY; +} + +EGLDisplay QEglFSDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) +{ + return eglGetDisplay(nativeDisplay); +} + +bool QEglFSDeviceIntegration::usesDefaultScreen() +{ + return true; +} + +void QEglFSDeviceIntegration::screenInit() +{ + // Nothing to do here. Called only when usesDefaultScreen is false. +} + +void QEglFSDeviceIntegration::screenDestroy() +{ + QGuiApplication *app = qGuiApp; + QEglFSIntegration *platformIntegration = static_cast( + QGuiApplicationPrivate::platformIntegration()); + while (!app->screens().isEmpty()) + platformIntegration->removeScreen(app->screens().last()->handle()); +} + +QSizeF QEglFSDeviceIntegration::physicalScreenSize() const +{ + return q_physicalScreenSizeFromFb(framebuffer, screenSize()); +} + +QSize QEglFSDeviceIntegration::screenSize() const +{ + return q_screenSizeFromFb(framebuffer); +} + +QDpi QEglFSDeviceIntegration::logicalDpi() const +{ + const QSizeF ps = physicalScreenSize(); + const QSize s = screenSize(); + + if (!ps.isEmpty() && !s.isEmpty()) + return QDpi(25.4 * s.width() / ps.width(), + 25.4 * s.height() / ps.height()); + else + return QDpi(100, 100); +} + +qreal QEglFSDeviceIntegration::pixelDensity() const +{ + return qRound(logicalDpi().first / qreal(100)); +} + +Qt::ScreenOrientation QEglFSDeviceIntegration::nativeOrientation() const +{ + return Qt::PrimaryOrientation; +} + +Qt::ScreenOrientation QEglFSDeviceIntegration::orientation() const +{ + return Qt::PrimaryOrientation; +} + +int QEglFSDeviceIntegration::screenDepth() const +{ + return q_screenDepthFromFb(framebuffer); +} + +QImage::Format QEglFSDeviceIntegration::screenFormat() const +{ + return screenDepth() == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32; +} + +qreal QEglFSDeviceIntegration::refreshRate() const +{ + return q_refreshRateFromFb(framebuffer); +} + +EGLint QEglFSDeviceIntegration::surfaceType() const +{ + return EGL_WINDOW_BIT; +} + +QSurfaceFormat QEglFSDeviceIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const +{ + QSurfaceFormat format = inputFormat; + + static const bool force888 = qEnvironmentVariableIntValue("QT_QPA_EGLFS_FORCE888"); + if (force888) { + format.setRedBufferSize(8); + format.setGreenBufferSize(8); + format.setBlueBufferSize(8); + } + + return format; +} + +bool QEglFSDeviceIntegration::filterConfig(EGLDisplay, EGLConfig) const +{ + return true; +} + +QEglFSWindow *QEglFSDeviceIntegration::createWindow(QWindow *window) const +{ + return new QEglFSWindow(window); +} + +EGLNativeWindowType QEglFSDeviceIntegration::createNativeWindow(QPlatformWindow *platformWindow, + const QSize &size, + const QSurfaceFormat &format) +{ + Q_UNUSED(platformWindow); + Q_UNUSED(size); + Q_UNUSED(format); + return 0; +} + +EGLNativeWindowType QEglFSDeviceIntegration::createNativeOffscreenWindow(const QSurfaceFormat &format) +{ + Q_UNUSED(format); + return 0; +} + +void QEglFSDeviceIntegration::destroyNativeWindow(EGLNativeWindowType window) +{ + Q_UNUSED(window); +} + +bool QEglFSDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap) const +{ + Q_UNUSED(cap); + return false; +} + +QPlatformCursor *QEglFSDeviceIntegration::createCursor(QPlatformScreen *screen) const +{ + return new QEglFSCursor(screen); +} + +void QEglFSDeviceIntegration::waitForVSync(QPlatformSurface *surface) const +{ + Q_UNUSED(surface); + +#if defined(Q_OS_LINUX) && defined(FBIO_WAITFORVSYNC) + static const bool forceSync = qEnvironmentVariableIntValue("QT_QPA_EGLFS_FORCEVSYNC"); + if (forceSync && framebuffer != -1) { + int arg = 0; + if (ioctl(framebuffer, FBIO_WAITFORVSYNC, &arg) == -1) + qWarning("Could not wait for vsync."); + } +#endif +} + +void QEglFSDeviceIntegration::presentBuffer(QPlatformSurface *surface) +{ + Q_UNUSED(surface); +} + +bool QEglFSDeviceIntegration::supportsPBuffers() const +{ + return true; +} + +bool QEglFSDeviceIntegration::supportsSurfacelessContexts() const +{ + return true; +} + +void *QEglFSDeviceIntegration::wlDisplay() const +{ + return Q_NULLPTR; +} + +EGLConfig QEglFSDeviceIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format) +{ + class Chooser : public QEglConfigChooser { + public: + Chooser(EGLDisplay display) + : QEglConfigChooser(display) { } + bool filterConfig(EGLConfig config) const Q_DECL_OVERRIDE { + return qt_egl_device_integration()->filterConfig(display(), config) + && QEglConfigChooser::filterConfig(config); + } + }; + + Chooser chooser(display); + chooser.setSurfaceType(qt_egl_device_integration()->surfaceType()); + chooser.setSurfaceFormat(format); + return chooser.chooseConfig(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h new file mode 100644 index 0000000000..819e4818ab --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration_p.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSDEVICEINTEGRATION_H +#define QEGLFSDEVICEINTEGRATION_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 "qeglfsglobal.h" +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QPlatformSurface; +class QEglFSWindow; + +#define QEglFSDeviceIntegrationFactoryInterface_iid "org.qt-project.qt.qpa.egl.QEglFSDeviceIntegrationFactoryInterface.5.5" + +class Q_EGLFS_EXPORT QEglFSDeviceIntegration +{ +public: + virtual ~QEglFSDeviceIntegration() { } + + virtual void platformInit(); + virtual void platformDestroy(); + virtual EGLNativeDisplayType platformDisplay() const; + virtual EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay); + virtual bool usesDefaultScreen(); + virtual void screenInit(); + virtual void screenDestroy(); + virtual QSizeF physicalScreenSize() const; + virtual QSize screenSize() const; + virtual QDpi logicalDpi() const; + virtual qreal pixelDensity() const; + virtual Qt::ScreenOrientation nativeOrientation() const; + virtual Qt::ScreenOrientation orientation() const; + virtual int screenDepth() const; + virtual QImage::Format screenFormat() const; + virtual qreal refreshRate() const; + virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; + virtual EGLint surfaceType() const; + virtual QEglFSWindow *createWindow(QWindow *window) const; + virtual EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, + const QSize &size, + const QSurfaceFormat &format); + virtual EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format); + virtual void destroyNativeWindow(EGLNativeWindowType window); + virtual bool hasCapability(QPlatformIntegration::Capability cap) const; + virtual QPlatformCursor *createCursor(QPlatformScreen *screen) const; + virtual bool filterConfig(EGLDisplay display, EGLConfig config) const; + virtual void waitForVSync(QPlatformSurface *surface) const; + virtual void presentBuffer(QPlatformSurface *surface); + virtual QByteArray fbDeviceName() const; + virtual int framebufferIndex() const; + virtual bool supportsPBuffers() const; + virtual bool supportsSurfacelessContexts() const; + + virtual void *wlDisplay() const; + + static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format); +}; + +class Q_EGLFS_EXPORT QEglFSDeviceIntegrationPlugin : public QObject +{ + Q_OBJECT + +public: + virtual QEglFSDeviceIntegration *create() = 0; + + // the pattern expected by qLoadPlugin calls for a QString argument. + // we don't need it, so don't bother subclasses with it: + QEglFSDeviceIntegration *create(const QString &) { return create(); } +}; + +class Q_EGLFS_EXPORT QEglFSDeviceIntegrationFactory +{ +public: + static QStringList keys(const QString &pluginPath = QString()); + static QEglFSDeviceIntegration *create(const QString &name, const QString &platformPluginPath = QString()); +}; + +QT_END_NAMESPACE + +#endif // QEGLDEVICEINTEGRATION_H diff --git a/src/plugins/platforms/eglfs/api/qeglfsglobal.h b/src/plugins/platforms/eglfs/api/qeglfsglobal.h new file mode 100644 index 0000000000..2b5effc2f1 --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfsglobal.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSGLOBAL_H +#define QEGLFSGLOBAL_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +#ifdef QT_BUILD_EGL_DEVICE_LIB +#define Q_EGLFS_EXPORT Q_DECL_EXPORT +#else +#define Q_EGLFS_EXPORT Q_DECL_IMPORT +#endif + +#undef Status +#undef None +#undef Bool +#undef CursorShape +#undef KeyPress +#undef KeyRelease +#undef FocusIn +#undef FocusOut +#undef FontChange +#undef Expose +#undef Unsorted + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/eglfs/api/qeglfshooks.cpp b/src/plugins/platforms/eglfs/api/qeglfshooks.cpp new file mode 100644 index 0000000000..b67d8fab54 --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfshooks.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec 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 "qeglfshooks_p.h" +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(qLcEglDevDebug) + +#ifdef EGLFS_PLATFORM_HOOKS + +QEglFSDeviceIntegration *qt_egl_device_integration() +{ + extern QEglFSHooks *platformHooks; + return platformHooks; +} + +#else + +class DeviceIntegration +{ +public: + DeviceIntegration(); + ~DeviceIntegration() { delete m_integration; } + QEglFSDeviceIntegration *integration() { return m_integration; } +private: + QEglFSDeviceIntegration *m_integration; +}; + +Q_GLOBAL_STATIC(DeviceIntegration, deviceIntegration) + +DeviceIntegration::DeviceIntegration() : m_integration(0) +{ + QStringList pluginKeys = QEglFSDeviceIntegrationFactory::keys(); + if (!pluginKeys.isEmpty()) { + // Some built-in logic: Prioritize either X11 or KMS/DRM. + if (qEnvironmentVariableIsSet("DISPLAY")) { + const QString x11key = QStringLiteral("eglfs_x11"); + if (pluginKeys.contains(x11key)) { + pluginKeys.removeOne(x11key); + pluginKeys.prepend(x11key); + } + } else { + const QString kmskey = QStringLiteral("eglfs_kms"); + if (pluginKeys.contains(kmskey)) { + pluginKeys.removeOne(kmskey); + pluginKeys.prepend(kmskey); + } + } + + QByteArray requested; + + // The environment variable can override everything. + if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_INTEGRATION")) { + requested = qgetenv("QT_QPA_EGLFS_INTEGRATION"); + } else { + // Device-specific makespecs may define a preferred plugin. +#ifdef EGLFS_PREFERRED_PLUGIN +#define DEFAULT_PLUGIN EGLFS_PREFERRED_PLUGIN +#define STR(s) #s +#define STRQ(s) STR(s) + requested = STRQ(DEFAULT_PLUGIN); +#endif + } + + // Treat "none" as special. There has to be a way to indicate + // that plugins must be ignored when the device is known to be + // functional with the default, non-specialized integration. + if (requested != QByteArrayLiteral("none")) { + if (!requested.isEmpty()) { + QString reqStr = QString::fromLocal8Bit(requested); + pluginKeys.removeOne(reqStr); + pluginKeys.prepend(reqStr); + } + qCDebug(qLcEglDevDebug) << "EGL device integration plugin keys (sorted):" << pluginKeys; + while (!m_integration && !pluginKeys.isEmpty()) { + QString key = pluginKeys.takeFirst(); + qCDebug(qLcEglDevDebug) << "Trying to load device EGL integration" << key; + m_integration = QEglFSDeviceIntegrationFactory::create(key); + } + } + } + + if (!m_integration) { + // Use a default, non-specialized device integration when no plugin is available. + // For some systems this is sufficient. + qCDebug(qLcEglDevDebug) << "Using base device integration"; + m_integration = new QEglFSDeviceIntegration; + } +} + +QEglFSDeviceIntegration *qt_egl_device_integration() +{ + return deviceIntegration()->integration(); +} + +#endif // EGLFS_PLATFORM_HOOKS + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/api/qeglfshooks_p.h b/src/plugins/platforms/eglfs/api/qeglfshooks_p.h new file mode 100644 index 0000000000..e379f7a76d --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfshooks_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSHOOKS_H +#define QEGLFSHOOKS_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 "qeglfsglobal.h" +#include "qeglfsdeviceintegration_p.h" + +QT_BEGIN_NAMESPACE + +class QEglFSHooks : public QEglFSDeviceIntegration +{ +}; + +Q_EGLFS_EXPORT QEglFSDeviceIntegration *qt_egl_device_integration(); + +QT_END_NAMESPACE + +#endif // QEGLFSHOOKS_H diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp new file mode 100644 index 0000000000..d636a783ec --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp @@ -0,0 +1,206 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "qeglfsscreen_p.h" +#include "qeglfswindow_p.h" +#include "qeglfshooks_p.h" + +QT_BEGIN_NAMESPACE + +QEglFSScreen::QEglFSScreen(EGLDisplay dpy) + : m_dpy(dpy), + m_surface(EGL_NO_SURFACE), + m_cursor(0) +{ + m_cursor = qt_egl_device_integration()->createCursor(this); +} + +QEglFSScreen::~QEglFSScreen() +{ + delete m_cursor; + QOpenGLCompositor::destroy(); +} + +QRect QEglFSScreen::geometry() const +{ + return QRect(QPoint(0, 0), qt_egl_device_integration()->screenSize()); +} + +int QEglFSScreen::depth() const +{ + return qt_egl_device_integration()->screenDepth(); +} + +QImage::Format QEglFSScreen::format() const +{ + return qt_egl_device_integration()->screenFormat(); +} + +QSizeF QEglFSScreen::physicalSize() const +{ + return qt_egl_device_integration()->physicalScreenSize(); +} + +QDpi QEglFSScreen::logicalDpi() const +{ + return qt_egl_device_integration()->logicalDpi(); +} + +qreal QEglFSScreen::pixelDensity() const +{ + return qt_egl_device_integration()->pixelDensity(); +} + +Qt::ScreenOrientation QEglFSScreen::nativeOrientation() const +{ + return qt_egl_device_integration()->nativeOrientation(); +} + +Qt::ScreenOrientation QEglFSScreen::orientation() const +{ + return qt_egl_device_integration()->orientation(); +} + +QPlatformCursor *QEglFSScreen::cursor() const +{ + return m_cursor; +} + +qreal QEglFSScreen::refreshRate() const +{ + return qt_egl_device_integration()->refreshRate(); +} + +void QEglFSScreen::setPrimarySurface(EGLSurface surface) +{ + m_surface = surface; +} + +void QEglFSScreen::handleCursorMove(const QPoint &pos) +{ + const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + const QList 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 windows = compositor->windows(); + Q_ASSERT(!windows.isEmpty()); + + QImage img; + + if (static_cast(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/api/qeglfsscreen_p.h b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h new file mode 100644 index 0000000000..092d853ffd --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSSCREEN_H +#define QEGLFSSCREEN_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 "qeglfsglobal.h" +#include + +#include + +QT_BEGIN_NAMESPACE + +class QEglFSWindow; +class QOpenGLContext; + +class Q_EGLFS_EXPORT QEglFSScreen : public QPlatformScreen +{ +public: + QEglFSScreen(EGLDisplay display); + ~QEglFSScreen(); + + QRect geometry() const Q_DECL_OVERRIDE; + int depth() const Q_DECL_OVERRIDE; + QImage::Format format() const Q_DECL_OVERRIDE; + + QSizeF physicalSize() const Q_DECL_OVERRIDE; + QDpi logicalDpi() const Q_DECL_OVERRIDE; + qreal pixelDensity() const Q_DECL_OVERRIDE; + Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE; + Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE; + + QPlatformCursor *cursor() const Q_DECL_OVERRIDE; + + 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; } + + EGLDisplay display() const { return m_dpy; } + + void handleCursorMove(const QPoint &pos); + +private: + void setPrimarySurface(EGLSurface surface); + + EGLDisplay m_dpy; + QPointer m_pointerWindow; + EGLSurface m_surface; + QPlatformCursor *m_cursor; + + friend class QEglFSWindow; +}; + +QT_END_NAMESPACE + +#endif // QEGLFSSCREEN_H diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp new file mode 100644 index 0000000000..f602c1b976 --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp @@ -0,0 +1,336 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qeglfswindow_p.h" +#include "qeglfscursor_p.h" +#include "qeglfshooks_p.h" +#include "qeglfsdeviceintegration_p.h" + +QT_BEGIN_NAMESPACE + +QEglFSWindow::QEglFSWindow(QWindow *w) + : QPlatformWindow(w), + m_backingStore(0), + m_raster(false), + m_winId(0), + m_surface(EGL_NO_SURFACE), + m_window(0), + m_flags(0) +{ +} + +QEglFSWindow::~QEglFSWindow() +{ + destroy(); +} + +static WId newWId() +{ + static WId id = 0; + + if (id == std::numeric_limits::max()) + qWarning("QEGLPlatformWindow: Out of window IDs"); + + return ++id; +} + +void QEglFSWindow::create() +{ + if (m_flags.testFlag(Created)) + return; + + 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; + + if (window()->type() == Qt::Desktop) + return; + + // Stop if there is already a window backed by a native window and surface. Additional + // raster windows will not have their own native window, surface and context. Instead, + // they will be composited onto the root window's surface. + QEglFSScreen *screen = this->screen(); + QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + if (screen->primarySurface() != EGL_NO_SURFACE) { + if (Q_UNLIKELY(!isRaster() || !compositor->targetWindow())) { +#if !defined(Q_OS_ANDROID) + // We can have either a single OpenGL window or multiple raster windows. + // Other combinations cannot work. + qFatal("EGLFS: OpenGL windows cannot be mixed with others."); +#endif + return; + } + m_format = compositor->targetWindow()->format(); + return; + } + + m_flags |= HasNativeWindow; + setGeometry(QRect()); // will become fullscreen + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size())); + + resetSurface(); + + if (Q_UNLIKELY(m_surface == EGL_NO_SURFACE)) { + EGLint error = eglGetError(); + eglTerminate(screen->display()); + qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error); + } + + screen->setPrimarySurface(m_surface); + + if (isRaster()) { + QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance()); + context->setShareContext(qt_gl_global_share_context()); + context->setFormat(m_format); + context->setScreen(window()->screen()); + if (Q_UNLIKELY(!context->create())) + qFatal("EGLFS: Failed to create compositing context"); + compositor->setTarget(context, window()); + // If there is a "root" window into which raster and QOpenGLWidget content is + // composited, all other contexts must share with its context. + if (!qt_gl_global_share_context()) { + qt_gl_set_global_share_context(context); + // What we set up here is in effect equivalent to the application setting + // AA_ShareOpenGLContexts. Set the attribute to be fully consistent. + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + } + } +} + +void QEglFSWindow::destroy() +{ + QEglFSScreen *screen = this->screen(); + if (m_flags.testFlag(HasNativeWindow)) { + QEglFSCursor *cursor = qobject_cast(screen->cursor()); + if (cursor) + cursor->resetResources(); + + if (screen->primarySurface() == m_surface) + screen->setPrimarySurface(EGL_NO_SURFACE); + + invalidateSurface(); + } + + m_flags = 0; + QOpenGLCompositor::instance()->removeWindow(this); +} + +void QEglFSWindow::invalidateSurface() +{ + if (m_surface != EGL_NO_SURFACE) { + eglDestroySurface(screen()->display(), m_surface); + m_surface = EGL_NO_SURFACE; + } + qt_egl_device_integration()->destroyNativeWindow(m_window); + m_window = 0; +} + +void QEglFSWindow::resetSurface() +{ + EGLDisplay display = screen()->display(); + QSurfaceFormat platformFormat = qt_egl_device_integration()->surfaceFormatFor(window()->requestedFormat()); + + m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat); + m_format = q_glFormatFromConfig(display, m_config, platformFormat); + m_window = qt_egl_device_integration()->createNativeWindow(this, screen()->geometry().size(), m_format); + m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL); +} + +void QEglFSWindow::setVisible(bool visible) +{ + QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + QList windows = compositor->windows(); + QWindow *wnd = window(); + + if (wnd->type() != Qt::Desktop) { + if (visible) { + compositor->addWindow(this); + } else { + compositor->removeWindow(this); + windows = compositor->windows(); + if (windows.size()) + windows.last()->sourceWindow()->requestActivate(); + } + } + + QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); + + if (visible) + QWindowSystemInterface::flushWindowSystemEvents(); +} + +void QEglFSWindow::setGeometry(const QRect &r) +{ + QRect rect; + bool forceFullscreen = m_flags.testFlag(HasNativeWindow); + if (forceFullscreen) + rect = screen()->availableGeometry(); + else + rect = r; + + QPlatformWindow::setGeometry(rect); + + // if we corrected the size, trigger a resize event + if (rect != r) + QWindowSystemInterface::handleGeometryChange(window(), rect, r); +} + +QRect QEglFSWindow::geometry() const +{ + // For yet-to-become-fullscreen windows report the geometry covering the entire + // screen. This is particularly important for Quick where the root object may get + // sized to some geometry queried before calling create(). + if (!m_flags.testFlag(Created) && screen()->primarySurface() == EGL_NO_SURFACE) + return screen()->availableGeometry(); + + return QPlatformWindow::geometry(); +} + +void QEglFSWindow::requestActivateWindow() +{ + if (window()->type() != Qt::Desktop) + QOpenGLCompositor::instance()->moveToTop(this); + + QWindow *wnd = window(); + QWindowSystemInterface::handleWindowActivated(wnd); + QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); +} + +void QEglFSWindow::raise() +{ + QWindow *wnd = window(); + if (wnd->type() != Qt::Desktop) { + QOpenGLCompositor::instance()->moveToTop(this); + QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); + } +} + +void QEglFSWindow::lower() +{ + QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); + QList windows = compositor->windows(); + if (window()->type() != Qt::Desktop && windows.count() > 1) { + int idx = windows.indexOf(this); + if (idx > 0) { + compositor->changeWindowIndex(this, idx - 1); + QWindowSystemInterface::handleExposeEvent(windows.last()->sourceWindow(), + QRect(QPoint(0, 0), windows.last()->sourceWindow()->geometry().size())); + } + } +} + +EGLSurface QEglFSWindow::surface() const +{ + return m_surface != EGL_NO_SURFACE ? m_surface : screen()->primarySurface(); +} + +QSurfaceFormat QEglFSWindow::format() const +{ + return m_format; +} + +EGLNativeWindowType QEglFSWindow::eglWindow() const +{ + return m_window; +} + +QEglFSScreen *QEglFSWindow::screen() const +{ + return static_cast(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/api/qeglfswindow_p.h b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h new file mode 100644 index 0000000000..aea4ed4806 --- /dev/null +++ b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLFSWINDOW_H +#define QEGLFSWINDOW_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 "qeglfsglobal.h" +#include "qeglfsintegration.h" +#include "qeglfsscreen_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +class QOpenGLCompositorBackingStore; +class QPlatformTextureList; + +class Q_EGLFS_EXPORT QEglFSWindow : public QPlatformWindow, public QOpenGLCompositorWindow +{ +public: + QEglFSWindow(QWindow *w); + ~QEglFSWindow(); + + void create(); + void destroy(); + + void setGeometry(const QRect &) Q_DECL_OVERRIDE; + QRect geometry() const Q_DECL_OVERRIDE; + void setVisible(bool visible) Q_DECL_OVERRIDE; + void requestActivateWindow() Q_DECL_OVERRIDE; + void raise() Q_DECL_OVERRIDE; + void lower() Q_DECL_OVERRIDE; + + void propagateSizeHints() 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; + EGLSurface surface() const; + QEglFSScreen *screen() const; + + bool hasNativeWindow() const { return m_flags.testFlag(HasNativeWindow); } + + virtual void invalidateSurface() Q_DECL_OVERRIDE; + virtual void resetSurface(); + + 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; + +protected: + QOpenGLCompositorBackingStore *m_backingStore; + bool m_raster; + WId m_winId; + + EGLSurface m_surface; + EGLNativeWindowType m_window; + + EGLConfig m_config; + QSurfaceFormat m_format; + + enum Flag { + Created = 0x01, + HasNativeWindow = 0x02 + }; + Q_DECLARE_FLAGS(Flags, Flag) + Flags m_flags; +}; + +QT_END_NAMESPACE + +#endif // QEGLFSWINDOW_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro index e2ebf9f7ee..cd97c2c5a3 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro @@ -1,6 +1,6 @@ TARGET = qeglfs-brcm-integration -QT += core-private gui-private platformsupport-private eglfs_device_lib-private +QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private INCLUDEPATH += $$PWD/../.. CONFIG += egl diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h index 8f78b51190..5af628dedd 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h @@ -40,11 +40,11 @@ #ifndef QEGLFSBRCMINTEGRATION_H #define QEGLFSBRCMINTEGRATION_H -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" QT_BEGIN_NAMESPACE -class QEglFSBrcmIntegration : public QEGLDeviceIntegration +class QEglFSBrcmIntegration : public QEglFSDeviceIntegration { public: void platformInit() Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp index 0bd54ba239..80d7631931 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp @@ -37,18 +37,18 @@ ** ****************************************************************************/ -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" #include "qeglfsbrcmintegration.h" QT_BEGIN_NAMESPACE -class QEglFSBrcmIntegrationPlugin : public QEGLDeviceIntegrationPlugin +class QEglFSBrcmIntegrationPlugin : public QEglFSDeviceIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_brcm.json") + Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_brcm.json") public: - QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSBrcmIntegration; } + QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSBrcmIntegration; } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro index 979bfe3ea9..b0d631a9d1 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro @@ -4,7 +4,7 @@ PLUGIN_TYPE = egldeviceintegrations PLUGIN_CLASS_NAME = QEglFSKmsGbmIntegrationPlugin load(qt_plugin) -QT += core-private gui-private platformsupport-private eglfs_device_lib-private eglfs_kms_support-private +QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private eglfs_kms_support-private INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp index 1c0a8e1b5f..a5ab73cca4 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp @@ -43,7 +43,7 @@ #include "qeglfskmsgbmdevice.h" #include "qeglfskmsgbmscreen.h" #include "qeglfskmsgbmcursor.h" -#include "qeglfscursor.h" +#include "private/qeglfscursor_p.h" #include #include diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp index 8e8779ca10..f34e4859c6 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp @@ -38,18 +38,18 @@ ** ****************************************************************************/ -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" #include "qeglfskmsgbmintegration.h" QT_BEGIN_NAMESPACE -class QEglFSKmsGbmIntegrationPlugin : public QEGLDeviceIntegrationPlugin +class QEglFSKmsGbmIntegrationPlugin : public QEglFSDeviceIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms.json") + Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms.json") public: - QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsGbmIntegration; } + QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsGbmIntegration; } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro index 3a380b7525..b7c1b8f764 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro @@ -1,6 +1,6 @@ TARGET = qeglfs-kms-egldevice-integration -QT += core-private gui-private platformsupport-private eglfs_device_lib-private eglfs_kms_support-private +QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private_kms_support-private INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index 838569d5c6..28967d71ff 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -40,7 +40,7 @@ #include "qeglfskmsegldeviceintegration.h" #include -#include "qeglfswindow.h" +#include "private/qeglfswindow_p.h" #include "qeglfskmsegldevice.h" #include "qeglfskmsscreen.h" #include @@ -189,7 +189,7 @@ void QEglJetsonTK1Window::resetSurface() if (!m_integration->m_funcs->stream_consumer_output(display, m_egl_stream, layer)) qWarning("resetSurface: Unable to connect stream"); - m_config = QEglFSIntegration::chooseConfig(display, m_integration->surfaceFormatFor(window()->requestedFormat())); + m_config = QEglFSDeviceIntegration::chooseConfig(display, m_integration->surfaceFormatFor(window()->requestedFormat())); m_format = q_glFormatFromConfig(display, m_config); qCDebug(qLcEglfsKmsDebug) << "Stream producer format is" << m_format; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp index 63571f796f..42fec073f1 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp @@ -41,13 +41,13 @@ QT_BEGIN_NAMESPACE -class QEglFSKmsEglDeviceIntegrationPlugin : public QEGLDeviceIntegrationPlugin +class QEglFSKmsEglDeviceIntegrationPlugin : public QEglFSDeviceIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms_egldevice.json") + Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms_egldevice.json") public: - QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsEglDeviceIntegration; } + QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsEglDeviceIntegration; } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro index 6355fe6abd..6dd857a4e4 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro @@ -2,7 +2,7 @@ TARGET = QtEglFsKmsSupport CONFIG += no_module_headers internal_module load(qt_module) -QT += core-private gui-private platformsupport-private eglfs_device_lib-private +QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private INCLUDEPATH += $$PWD/../.. diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp index 07ea7d4439..7389050efc 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp @@ -42,8 +42,8 @@ #include "qeglfskmsintegration.h" #include "qeglfskmsdevice.h" #include "qeglfskmsscreen.h" -#include "qeglfswindow.h" -#include "qeglfscursor.h" +#include "private/qeglfswindow_p.h" +#include "private/qeglfscursor_p.h" #include #include diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h index 34ac5385a5..81386881ff 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h @@ -42,7 +42,7 @@ #ifndef QEGLFSKMSINTEGRATION_H #define QEGLFSKMSINTEGRATION_H -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" #include #include #include @@ -53,7 +53,7 @@ class QEglFSKmsDevice; Q_EGLFS_EXPORT Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) -class Q_EGLFS_EXPORT QEglFSKmsIntegration : public QEGLDeviceIntegration +class Q_EGLFS_EXPORT QEglFSKmsIntegration : public QEglFSDeviceIntegration { public: QEglFSKmsIntegration(); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h index aa698e1b5d..9679f70260 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h @@ -43,7 +43,7 @@ #define QEGLFSKMSSCREEN_H #include "qeglfskmsintegration.h" -#include "qeglfsscreen.h" +#include "private/qeglfsscreen_p.h" #include #include diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro index 7fc4568ae3..1e58b5fdcd 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro @@ -1,6 +1,6 @@ TARGET = qeglfs-mali-integration -QT += core-private gui-private platformsupport-private eglfs_device_lib-private +QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private # Avoid X11 header collision DEFINES += MESA_EGL_NO_X11_HEADERS diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp index ffdb7a686b..cd468c989f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp @@ -56,7 +56,7 @@ struct fbdev_window { void QEglFSMaliIntegration::platformInit() { // Keep the non-overridden base class functions based on fb0 working. - QEGLDeviceIntegration::platformInit(); + QEglFSDeviceIntegration::platformInit(); int fd = qt_safe_open("/dev/fb0", O_RDWR, 0); if (fd == -1) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h index 35a2c64951..56883a3676 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h @@ -40,11 +40,11 @@ #ifndef QEGLFSMALIINTEGRATION_H #define QEGLFSMALIINTEGRATION_H -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" QT_BEGIN_NAMESPACE -class QEglFSMaliIntegration : public QEGLDeviceIntegration +class QEglFSMaliIntegration : public QEglFSDeviceIntegration { public: void platformInit() Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp index 0754e1af5b..a3c804f54d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp @@ -37,18 +37,18 @@ ** ****************************************************************************/ -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" #include "qeglfsmaliintegration.h" QT_BEGIN_NAMESPACE -class QEglFSMaliIntegrationPlugin : public QEGLDeviceIntegrationPlugin +class QEglFSMaliIntegrationPlugin : public QEglFSDeviceIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_mali.json") + Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_mali.json") public: - QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSMaliIntegration; } + QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSMaliIntegration; } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro index 6fac2f529a..a53aac2041 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro @@ -1,6 +1,6 @@ TARGET = qeglfs-viv-integration -QT += core-private gui-private platformsupport-private eglfs_device_lib-private +QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private INCLUDEPATH += $$PWD/../.. CONFIG += egl diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp index ca97f6c8f9..f2fcc0d3ff 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE void QEglFSVivIntegration::platformInit() { - QEGLDeviceIntegration::platformInit(); + QEglFSDeviceIntegration::platformInit(); int width, height; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h index 4a8cd5c385..2e98c2b4b1 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h @@ -40,11 +40,11 @@ #ifndef QEGLFSVIVINTEGRATION_H #define QEGLFSVIVINTEGRATION_H -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" QT_BEGIN_NAMESPACE -class QEglFSVivIntegration : public QEGLDeviceIntegration +class QEglFSVivIntegration : public QEglFSDeviceIntegration { public: void platformInit() Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp index d1c9fb4086..ebe2091b1e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp @@ -37,18 +37,18 @@ ** ****************************************************************************/ -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" #include "qeglfsvivintegration.h" QT_BEGIN_NAMESPACE -class QEglFSVivIntegrationPlugin : public QEGLDeviceIntegrationPlugin +class QEglFSVivIntegrationPlugin : public QEglFSDeviceIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_viv.json") + Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_viv.json") public: - QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSVivIntegration; } + QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSVivIntegration; } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro index 44f75c40e0..38259f4a5d 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro @@ -1,6 +1,6 @@ TARGET = qeglfs-viv-wl-integration -QT += core-private gui-private platformsupport-private eglfs_device_lib-private +QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private INCLUDEPATH += $$PWD/../.. CONFIG += egl diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp index 5c113456e4..61e2f17766 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE void QEglFSVivWaylandIntegration::platformInit() { - QEGLDeviceIntegration::platformInit(); + QEglFSDeviceIntegration::platformInit(); int width, height; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h index 40eacc8f2f..9abbe817a6 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h @@ -40,12 +40,12 @@ #ifndef QEGLFSVIVINTEGRATION_H #define QEGLFSVIVINTEGRATION_H -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" struct wl_display; QT_BEGIN_NAMESPACE -class QEglFSVivWaylandIntegration : public QEGLDeviceIntegration +class QEglFSVivWaylandIntegration : public QEglFSDeviceIntegration { public: void platformInit() Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp index 02ef9c566c..3b26feda07 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp @@ -37,18 +37,18 @@ ** ****************************************************************************/ -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" #include "qeglfsvivwlintegration.h" QT_BEGIN_NAMESPACE -class QEglFSVivWaylandIntegrationPlugin : public QEGLDeviceIntegrationPlugin +class QEglFSVivWaylandIntegrationPlugin : public QEglFSDeviceIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_viv_wl.json") + Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_viv_wl.json") public: - QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSVivWaylandIntegration; } + QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSVivWaylandIntegration; } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro index 83f0c74910..21af6eb736 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro @@ -1,6 +1,6 @@ TARGET = qeglfs-x11-integration -QT += core-private gui-private platformsupport-private eglfs_device_lib-private +QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private # Avoid X11 header collision DEFINES += MESA_EGL_NO_X11_HEADERS diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h index a3d0b01baf..c0f0ee5f22 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h @@ -40,7 +40,7 @@ #ifndef QEGLFSX11INTEGRATION_H #define QEGLFSX11INTEGRATION_H -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" #include #include @@ -64,7 +64,7 @@ namespace Atoms { class EventReader; -class QEglFSX11Integration : public QEGLDeviceIntegration +class QEglFSX11Integration : public QEglFSDeviceIntegration { public: QEglFSX11Integration() : m_connection(0), m_window(0), m_eventReader(0) {} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp index 314a85694b..c15e05b657 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp @@ -37,18 +37,18 @@ ** ****************************************************************************/ -#include "qeglfsdeviceintegration.h" +#include "private/qeglfsdeviceintegration_p.h" #include "qeglfsx11integration.h" QT_BEGIN_NAMESPACE -class QEglFSX11IntegrationPlugin : public QEGLDeviceIntegrationPlugin +class QEglFSX11IntegrationPlugin : public QEglFSDeviceIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_x11.json") + Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_x11.json") public: - QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSX11Integration; } + QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSX11Integration; } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/eglfs-plugin.pro b/src/plugins/platforms/eglfs/eglfs-plugin.pro index a628cdccd9..90b8a9fb32 100644 --- a/src/plugins/platforms/eglfs/eglfs-plugin.pro +++ b/src/plugins/platforms/eglfs/eglfs-plugin.pro @@ -1,6 +1,6 @@ TARGET = qeglfs -QT += platformsupport-private eglfs_device_lib-private +QT += platformsupport-private eglfsdeviceintegration-private SOURCES += $$PWD/qeglfsmain.cpp diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro index 03c96ca1d9..d91ffd60a1 100644 --- a/src/plugins/platforms/eglfs/eglfs.pro +++ b/src/plugins/platforms/eglfs/eglfs.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs CONFIG += ordered -SUBDIRS += eglfs_device_lib.pro +SUBDIRS += eglfsdeviceintegration.pro SUBDIRS += eglfs-plugin.pro SUBDIRS += deviceintegration diff --git a/src/plugins/platforms/eglfs/eglfs_device_lib.pro b/src/plugins/platforms/eglfs/eglfs_device_lib.pro deleted file mode 100644 index f784020fb6..0000000000 --- a/src/plugins/platforms/eglfs/eglfs_device_lib.pro +++ /dev/null @@ -1,54 +0,0 @@ -# The device integration plugin base class has to live in a shared library, -# placing it into a static lib like platformsupport is not sufficient since we -# have to keep the QObject magic like qobject_cast working. -# Hence this header-less, private-only module. - -TARGET = QtEglDeviceIntegration -CONFIG += no_module_headers internal_module - -QT += core-private gui-private platformsupport-private -LIBS += $$QMAKE_LIBS_DYNLOAD - -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS - -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 \ - $$PWD/qeglfsdeviceintegration.cpp - -HEADERS += $$PWD/qeglfsintegration.h \ - $$PWD/qeglfswindow.h \ - $$PWD/qeglfsscreen.h \ - $$PWD/qeglfscursor.h \ - $$PWD/qeglfshooks.h \ - $$PWD/qeglfscontext.h \ - $$PWD/qeglfsoffscreenwindow.h \ - $$PWD/qeglfsdeviceintegration.h - -QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF - -INCLUDEPATH += $$PWD - -!isEmpty(EGLFS_PLATFORM_HOOKS_SOURCES) { - HEADERS += $$EGLFS_PLATFORM_HOOKS_HEADERS - SOURCES += $$EGLFS_PLATFORM_HOOKS_SOURCES - LIBS += $$EGLFS_PLATFORM_HOOKS_LIBS - DEFINES += EGLFS_PLATFORM_HOOKS -} - -!isEmpty(EGLFS_DEVICE_INTEGRATION) { - DEFINES += EGLFS_PREFERRED_PLUGIN=$$EGLFS_DEVICE_INTEGRATION -} - -CONFIG += egl qpa/genericunixfontdatabase - -!contains(DEFINES, QT_NO_CURSOR): RESOURCES += $$PWD/cursor.qrc - -load(qt_module) diff --git a/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro b/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro new file mode 100644 index 0000000000..05f4196728 --- /dev/null +++ b/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro @@ -0,0 +1,47 @@ +# The device integration plugin base class has to live in a shared library, +# placing it into a static lib like platformsupport is not sufficient since we +# have to keep the QObject magic like qobject_cast working. +# Hence this header-less, private-only module. + +TARGET = QtEglFSDeviceIntegration +CONFIG += internal_module +MODULE = eglfsdeviceintegration + +QT += core-private gui-private platformsupport-private +LIBS += $$QMAKE_LIBS_DYNLOAD + +# Avoid X11 header collision +DEFINES += MESA_EGL_NO_X11_HEADERS + +DEFINES += QT_BUILD_EGL_DEVICE_LIB + +SOURCES += $$PWD/qeglfsintegration.cpp \ + $$PWD/qeglfscontext.cpp \ + $$PWD/qeglfsoffscreenwindow.cpp \ + +HEADERS += $$PWD/qeglfsintegration.h \ + $$PWD/qeglfscontext.h \ + $$PWD/qeglfsoffscreenwindow.h \ + +include($$PWD/api/api.pri) + +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +INCLUDEPATH += $$PWD + +!isEmpty(EGLFS_PLATFORM_HOOKS_SOURCES) { + HEADERS += $$EGLFS_PLATFORM_HOOKS_HEADERS + SOURCES += $$EGLFS_PLATFORM_HOOKS_SOURCES + LIBS += $$EGLFS_PLATFORM_HOOKS_LIBS + DEFINES += EGLFS_PLATFORM_HOOKS +} + +!isEmpty(EGLFS_DEVICE_INTEGRATION) { + DEFINES += EGLFS_PREFERRED_PLUGIN=$$EGLFS_DEVICE_INTEGRATION +} + +CONFIG += egl qpa/genericunixfontdatabase + +!contains(DEFINES, QT_NO_CURSOR): RESOURCES += $$PWD/cursor.qrc + +load(qt_module) diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp index 6acb362bf0..8d479873cf 100644 --- a/src/plugins/platforms/eglfs/qeglfscontext.cpp +++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp @@ -43,9 +43,9 @@ #include #include "qeglfscontext.h" -#include "qeglfswindow.h" -#include "qeglfshooks.h" -#include "qeglfscursor.h" +#include "qeglfswindow_p.h" +#include "qeglfshooks_p.h" +#include "qeglfscursor_p.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp deleted file mode 100644 index 6c8c35b1dc..0000000000 --- a/src/plugins/platforms/eglfs/qeglfscursor.cpp +++ /dev/null @@ -1,509 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfscursor.h" -#include "qeglfsintegration.h" -#include "qeglfsscreen.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifndef GL_VERTEX_ARRAY_BINDING -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#endif - -QT_BEGIN_NAMESPACE - -QEglFSCursor::QEglFSCursor(QPlatformScreen *screen) - : m_visible(true), - m_screen(static_cast(screen)), - m_program(0), - m_textureEntry(0), - m_deviceListener(0), - m_updateRequested(false) -{ - QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); - if (!hideCursorVal.isEmpty()) - m_visible = hideCursorVal.toInt() == 0; - if (!m_visible) - return; - - // Try to load the cursor atlas. If this fails, m_visible is set to false and - // paintOnScreen() and setCurrentCursor() become no-ops. - initCursorAtlas(); - - // initialize the cursor -#ifndef QT_NO_CURSOR - QCursor cursor(Qt::ArrowCursor); - setCurrentCursor(&cursor); -#endif - - m_deviceListener = new QEglFSCursorDeviceListener(this); - connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged, - m_deviceListener, &QEglFSCursorDeviceListener::onDeviceListChanged); - updateMouseStatus(); -} - -QEglFSCursor::~QEglFSCursor() -{ - resetResources(); - delete m_deviceListener; -} - -void QEglFSCursor::updateMouseStatus() -{ - m_visible = m_deviceListener->hasMouse(); -} - -bool QEglFSCursorDeviceListener::hasMouse() const -{ - return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0; -} - -void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type) -{ - if (type == QInputDeviceManager::DeviceTypePointer) - m_cursor->updateMouseStatus(); -} - -void QEglFSCursor::resetResources() -{ - if (QOpenGLContext::currentContext()) { - delete m_program; - glDeleteTextures(1, &m_cursor.customCursorTexture); - glDeleteTextures(1, &m_cursorAtlas.texture); - } - m_program = 0; - m_cursor.customCursorTexture = 0; - m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull(); - m_cursorAtlas.texture = 0; -} - -void QEglFSCursor::createShaderPrograms() -{ - static const char *textureVertexProgram = - "attribute highp vec2 vertexCoordEntry;\n" - "attribute highp vec2 textureCoordEntry;\n" - "varying highp vec2 textureCoord;\n" - "void main() {\n" - " textureCoord = textureCoordEntry;\n" - " gl_Position = vec4(vertexCoordEntry, 1.0, 1.0);\n" - "}\n"; - - static const char *textureFragmentProgram = - "uniform sampler2D texture;\n" - "varying highp vec2 textureCoord;\n" - "void main() {\n" - " gl_FragColor = texture2D(texture, textureCoord).bgra;\n" - "}\n"; - - m_program = new QOpenGLShaderProgram; - m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram); - m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram); - m_program->bindAttributeLocation("vertexCoordEntry", 0); - m_program->bindAttributeLocation("textureCoordEntry", 1); - m_program->link(); - - m_textureEntry = m_program->uniformLocation("texture"); -} - -void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image) -{ - if (!*texture) - glGenTextures(1, texture); - glBindTexture(GL_TEXTURE_2D, *texture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, image.width(), image.height(), 0 /* border */, - GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); -} - -void QEglFSCursor::initCursorAtlas() -{ - static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR"); - if (json.isEmpty()) - json = ":/cursor.json"; - - QFile file(QString::fromUtf8(json)); - if (!file.open(QFile::ReadOnly)) { - m_visible = false; - return; - } - - QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); - QJsonObject object = doc.object(); - - QString atlas = object.value(QLatin1String("image")).toString(); - Q_ASSERT(!atlas.isEmpty()); - - const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble(); - Q_ASSERT(cursorsPerRow); - m_cursorAtlas.cursorsPerRow = cursorsPerRow; - - const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray(); - Q_ASSERT(hotSpots.count() == Qt::LastCursor + 1); - for (int i = 0; i < hotSpots.count(); i++) { - QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble()); - m_cursorAtlas.hotSpots << hotSpot; - } - - QImage image = QImage(atlas).convertToFormat(QImage::Format_ARGB32_Premultiplied); - m_cursorAtlas.cursorWidth = image.width() / m_cursorAtlas.cursorsPerRow; - m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + cursorsPerRow) / cursorsPerRow); - m_cursorAtlas.width = image.width(); - m_cursorAtlas.height = image.height(); - m_cursorAtlas.image = image; -} - -#ifndef QT_NO_CURSOR -void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window) -{ - Q_UNUSED(window); - const QRect oldCursorRect = cursorRect(); - if (setCurrentCursor(cursor)) - update(oldCursorRect | cursorRect()); -} - -bool QEglFSCursor::setCurrentCursor(QCursor *cursor) -{ - if (!m_visible) - return false; - - const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; - if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor) - return false; - - if (m_cursor.shape == Qt::BitmapCursor) { - m_cursor.customCursorImage = QImage(); - m_cursor.customCursorPending = false; - } - m_cursor.shape = newShape; - if (newShape != Qt::BitmapCursor) { // standard cursor - const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width, - hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height; - m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow), - hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow), - ws, hs); - m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape]; - m_cursor.texture = m_cursorAtlas.texture; - m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight); - } else { - QImage image = cursor->pixmap().toImage(); - m_cursor.textureRect = QRectF(0, 0, 1, 1); - m_cursor.hotSpot = cursor->hotSpot(); - m_cursor.texture = 0; // will get updated in the next render() - m_cursor.size = image.size(); - m_cursor.customCursorImage = image; - m_cursor.customCursorPending = true; - } - - return true; -} -#endif - -class CursorUpdateEvent : public QEvent -{ -public: - CursorUpdateEvent(const QPoint &pos, const QRegion &rgn) - : QEvent(QEvent::Type(QEvent::User + 1)), - m_pos(pos), - m_region(rgn) - { } - QPoint pos() const { return m_pos; } - QRegion region() const { return m_region; } - -private: - QPoint m_pos; - QRegion m_region; -}; - -bool QEglFSCursor::event(QEvent *e) -{ - if (e->type() == QEvent::User + 1) { - CursorUpdateEvent *ev = static_cast(e); - m_updateRequested = false; - QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(ev->pos()), ev->region()); - QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); - return true; - } - return QPlatformCursor::event(e); -} - -void QEglFSCursor::update(const QRegion &rgn) -{ - if (!m_updateRequested) { - // Must not flush the window system events directly from here since we are likely to - // be a called directly from QGuiApplication's processMouseEvents. Flushing events - // could cause reentering by dispatching more queued mouse events. - m_updateRequested = true; - QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rgn)); - } -} - -QRect QEglFSCursor::cursorRect() const -{ - return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size); -} - -QPoint QEglFSCursor::pos() const -{ - return m_cursor.pos; -} - -void QEglFSCursor::setPos(const QPoint &pos) -{ - QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos); - const QRect oldCursorRect = cursorRect(); - m_cursor.pos = pos; - update(oldCursorRect | cursorRect()); - m_screen->handleCursorMove(m_cursor.pos); -} - -void QEglFSCursor::pointerEvent(const QMouseEvent &event) -{ - if (event.type() != QEvent::MouseMove) - return; - const QRect oldCursorRect = cursorRect(); - m_cursor.pos = event.screenPos().toPoint(); - update(oldCursorRect | cursorRect()); - m_screen->handleCursorMove(m_cursor.pos); -} - -void QEglFSCursor::paintOnScreen() -{ - if (!m_visible) - return; - - const QRectF cr = cursorRect(); - const QRect screenRect(m_screen->geometry()); - const GLfloat x1 = 2 * (cr.left() / screenRect.width()) - 1; - const GLfloat x2 = 2 * (cr.right() / screenRect.width()) - 1; - const GLfloat y1 = 1 - (cr.top() / screenRect.height()) * 2; - const GLfloat y2 = 1 - (cr.bottom() / screenRect.height()) * 2; - QRectF r(QPointF(x1, y1), QPointF(x2, y2)); - - draw(r); -} - -// In order to prevent breaking code doing custom OpenGL rendering while -// expecting the state in the context unchanged, save and restore all the state -// we touch. The exception is Qt Quick where the scenegraph is known to be able -// to deal with the changes we make. -struct StateSaver -{ - StateSaver() { - f = QOpenGLContext::currentContext()->functions(); - vaoHelper = new QOpenGLVertexArrayObjectHelper(QOpenGLContext::currentContext()); - - static bool windowsChecked = false; - static bool shouldSave = true; - if (!windowsChecked) { - windowsChecked = true; - QWindowList windows = QGuiApplication::allWindows(); - if (!windows.isEmpty() && windows[0]->inherits("QQuickWindow")) - shouldSave = false; - } - saved = shouldSave; - if (!shouldSave) - return; - - f->glGetIntegerv(GL_CURRENT_PROGRAM, &program); - f->glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture); - f->glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); - f->glGetIntegerv(GL_FRONT_FACE, &frontFace); - cull = f->glIsEnabled(GL_CULL_FACE); - depthTest = f->glIsEnabled(GL_DEPTH_TEST); - blend = f->glIsEnabled(GL_BLEND); - f->glGetIntegerv(GL_BLEND_SRC_RGB, blendFunc); - f->glGetIntegerv(GL_BLEND_SRC_ALPHA, blendFunc + 1); - f->glGetIntegerv(GL_BLEND_DST_RGB, blendFunc + 2); - f->glGetIntegerv(GL_BLEND_DST_ALPHA, blendFunc + 3); - f->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &arrayBuf); - if (vaoHelper->isValid()) - f->glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vao); - for (int i = 0; i < 2; ++i) { - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &va[i].enabled); - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &va[i].size); - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &va[i].type); - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &va[i].normalized); - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &va[i].stride); - f->glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &va[i].buffer); - f->glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &va[i].pointer); - } - } - ~StateSaver() { - if (saved) { - f->glUseProgram(program); - f->glBindTexture(GL_TEXTURE_2D, texture); - f->glActiveTexture(activeTexture); - f->glFrontFace(frontFace); - if (cull) - f->glEnable(GL_CULL_FACE); - else - f->glDisable(GL_CULL_FACE); - if (depthTest) - f->glEnable(GL_DEPTH_TEST); - else - f->glDisable(GL_DEPTH_TEST); - if (blend) - f->glEnable(GL_BLEND); - else - f->glDisable(GL_BLEND); - f->glBlendFuncSeparate(blendFunc[0], blendFunc[1], blendFunc[2], blendFunc[3]); - f->glBindBuffer(GL_ARRAY_BUFFER, arrayBuf); - if (vaoHelper->isValid()) - vaoHelper->glBindVertexArray(vao); - for (int i = 0; i < 2; ++i) { - if (va[i].enabled) - f->glEnableVertexAttribArray(i); - else - f->glDisableVertexAttribArray(i); - f->glBindBuffer(GL_ARRAY_BUFFER, va[i].buffer); - f->glVertexAttribPointer(i, va[i].size, va[i].type, va[i].normalized, va[i].stride, va[i].pointer); - } - } - delete vaoHelper; - } - QOpenGLFunctions *f; - QOpenGLVertexArrayObjectHelper *vaoHelper; - bool saved; - GLint program; - GLint texture; - GLint activeTexture; - GLint frontFace; - bool cull; - bool depthTest; - bool blend; - GLint blendFunc[4]; - GLint vao; - GLint arrayBuf; - struct { GLint enabled, type, size, normalized, stride, buffer; GLvoid *pointer; } va[2]; -}; - -void QEglFSCursor::draw(const QRectF &r) -{ - StateSaver stateSaver; - - if (!m_program) { - // one time initialization - initializeOpenGLFunctions(); - - createShaderPrograms(); - - if (!m_cursorAtlas.texture) { - createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image); - - if (m_cursor.shape != Qt::BitmapCursor) - m_cursor.texture = m_cursorAtlas.texture; - } - } - - if (m_cursor.shape == Qt::BitmapCursor && m_cursor.customCursorPending) { - // upload the custom cursor - createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage); - m_cursor.texture = m_cursor.customCursorTexture; - m_cursor.customCursorPending = false; - } - - Q_ASSERT(m_cursor.texture); - - m_program->bind(); - - const GLfloat x1 = r.left(); - const GLfloat x2 = r.right(); - const GLfloat y1 = r.top(); - const GLfloat y2 = r.bottom(); - const GLfloat cursorCoordinates[] = { - x1, y2, - x2, y2, - x1, y1, - x2, y1 - }; - - const GLfloat s1 = m_cursor.textureRect.left(); - const GLfloat s2 = m_cursor.textureRect.right(); - const GLfloat t1 = m_cursor.textureRect.top(); - const GLfloat t2 = m_cursor.textureRect.bottom(); - const GLfloat textureCoordinates[] = { - s1, t2, - s2, t2, - s1, t1, - s2, t1 - }; - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_cursor.texture); - - if (stateSaver.vaoHelper->isValid()) - stateSaver.vaoHelper->glBindVertexArray(0); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - - m_program->enableAttributeArray(0); - m_program->enableAttributeArray(1); - m_program->setAttributeArray(0, cursorCoordinates, 2); - m_program->setAttributeArray(1, textureCoordinates, 2); - - m_program->setUniformValue(m_textureEntry, 0); - - glDisable(GL_CULL_FACE); - glFrontFace(GL_CCW); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - m_program->disableAttributeArray(0); - m_program->disableAttributeArray(1); - m_program->release(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfscursor.h b/src/plugins/platforms/eglfs/qeglfscursor.h deleted file mode 100644 index bb30d53d6c..0000000000 --- a/src/plugins/platforms/eglfs/qeglfscursor.h +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLFSCURSOR_H -#define QEGLFSCURSOR_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 "qeglfsglobal.h" -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QOpenGLShaderProgram; -class QEglFSCursor; -class QEglFSScreen; - -class QEglFSCursorDeviceListener : public QObject -{ - Q_OBJECT - -public: - QEglFSCursorDeviceListener(QEglFSCursor *cursor) : m_cursor(cursor) { } - bool hasMouse() const; - -public slots: - void onDeviceListChanged(QInputDeviceManager::DeviceType type); - -private: - QEglFSCursor *m_cursor; -}; - -class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor, protected QOpenGLFunctions -{ - Q_OBJECT -public: - QEglFSCursor(QPlatformScreen *screen); - ~QEglFSCursor(); - -#ifndef QT_NO_CURSOR - void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE; -#endif - void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE; - QPoint pos() const Q_DECL_OVERRIDE; - void setPos(const QPoint &pos) Q_DECL_OVERRIDE; - - QRect cursorRect() const; - void paintOnScreen(); - void resetResources(); - - void updateMouseStatus(); - -private: - bool event(QEvent *e) Q_DECL_OVERRIDE; -#ifndef QT_NO_CURSOR - bool setCurrentCursor(QCursor *cursor); -#endif - void draw(const QRectF &rect); - void update(const QRegion ®ion); - void createShaderPrograms(); - void createCursorTexture(uint *texture, const QImage &image); - void initCursorAtlas(); - - // current cursor information - struct Cursor { - Cursor() : texture(0), shape(Qt::BlankCursor), customCursorTexture(0), customCursorPending(false) { } - uint texture; // a texture from 'image' or the atlas - Qt::CursorShape shape; - QRectF textureRect; // normalized rect inside texture - QSize size; // size of the cursor - QPoint hotSpot; - QImage customCursorImage; - QPoint pos; // current cursor position - uint customCursorTexture; - bool customCursorPending; - } m_cursor; - - // cursor atlas information - struct CursorAtlas { - CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { } - int cursorsPerRow; - uint texture; - int width, height; // width and height of the atlas - int cursorWidth, cursorHeight; // width and height of cursors inside the atlas - QList hotSpots; - QImage image; // valid until it's uploaded - } m_cursorAtlas; - - bool m_visible; - QEglFSScreen *m_screen; - QOpenGLShaderProgram *m_program; - int m_textureEntry; - QEglFSCursorDeviceListener *m_deviceListener; - bool m_updateRequested; -}; - -QT_END_NAMESPACE - -#endif // QEGLFSCURSOR_H diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp deleted file mode 100644 index 5cbc5dbdb0..0000000000 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qeglfsdeviceintegration.h" -#include "qeglfsintegration.h" -#include "qeglfscursor.h" -#include "qeglfswindow.h" -#include -#include -#include -#include -#include -#include -#include - -#if defined(Q_OS_LINUX) -#include -#include -#include -#include -#endif - -#include -#include - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(qLcEglDevDebug, "qt.qpa.egldeviceintegration") - -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, - (QEGLDeviceIntegrationFactoryInterface_iid, QLatin1String("/egldeviceintegrations"), Qt::CaseInsensitive)) - -#ifndef QT_NO_LIBRARY -Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, - (QEGLDeviceIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) -#endif // QT_NO_LIBRARY - -QStringList QEGLDeviceIntegrationFactory::keys(const QString &pluginPath) -{ - QStringList list; -#ifndef QT_NO_LIBRARY - 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); - } - } -#else - Q_UNUSED(pluginPath); -#endif - list.append(loader()->keyMap().values()); - qCDebug(qLcEglDevDebug) << "EGL device integration plugin keys:" << list; - return list; -} - -QEGLDeviceIntegration *QEGLDeviceIntegrationFactory::create(const QString &key, const QString &pluginPath) -{ - QEGLDeviceIntegration *integration = Q_NULLPTR; -#ifndef QT_NO_LIBRARY - if (!pluginPath.isEmpty()) { - QCoreApplication::addLibraryPath(pluginPath); - integration = qLoadPlugin(directLoader(), key); - } -#else - Q_UNUSED(pluginPath); -#endif - if (!integration) - integration = qLoadPlugin(loader(), key); - if (integration) - qCDebug(qLcEglDevDebug) << "Using EGL device integration" << key; - else - qCWarning(qLcEglDevDebug) << "Failed to load EGL device integration" << key; - - return integration; -} - -static int framebuffer = -1; - -QByteArray QEGLDeviceIntegration::fbDeviceName() const -{ -#ifdef Q_OS_LINUX - QByteArray fbDev = qgetenv("QT_QPA_EGLFS_FB"); - if (fbDev.isEmpty()) - fbDev = QByteArrayLiteral("/dev/fb0"); - - return fbDev; -#else - return QByteArray(); -#endif -} - -int QEGLDeviceIntegration::framebufferIndex() const -{ - int fbIndex = 0; -#ifndef QT_NO_REGULAREXPRESSION - QRegularExpression fbIndexRx(QLatin1String("fb(\\d+)")); - QRegularExpressionMatch match = fbIndexRx.match(QString::fromLocal8Bit(fbDeviceName())); - if (match.hasMatch()) - fbIndex = match.captured(1).toInt(); -#endif - return fbIndex; -} - -void QEGLDeviceIntegration::platformInit() -{ -#ifdef Q_OS_LINUX - QByteArray fbDev = fbDeviceName(); - - framebuffer = qt_safe_open(fbDev, O_RDONLY); - - if (Q_UNLIKELY(framebuffer == -1)) { - qWarning("EGLFS: Failed to open %s", fbDev.constData()); - qFatal("EGLFS: Can't continue without a display"); - } - -#ifdef FBIOBLANK - ioctl(framebuffer, FBIOBLANK, VESA_NO_BLANKING); -#endif -#endif -} - -void QEGLDeviceIntegration::platformDestroy() -{ -#ifdef Q_OS_LINUX - if (framebuffer != -1) - close(framebuffer); -#endif -} - -EGLNativeDisplayType QEGLDeviceIntegration::platformDisplay() const -{ - return EGL_DEFAULT_DISPLAY; -} - -EGLDisplay QEGLDeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) -{ - return eglGetDisplay(nativeDisplay); -} - -bool QEGLDeviceIntegration::usesDefaultScreen() -{ - return true; -} - -void QEGLDeviceIntegration::screenInit() -{ - // Nothing to do here. Called only when usesDefaultScreen is false. -} - -void QEGLDeviceIntegration::screenDestroy() -{ - QGuiApplication *app = qGuiApp; - QEglFSIntegration *platformIntegration = static_cast( - QGuiApplicationPrivate::platformIntegration()); - while (!app->screens().isEmpty()) - platformIntegration->removeScreen(app->screens().last()->handle()); -} - -QSizeF QEGLDeviceIntegration::physicalScreenSize() const -{ - return q_physicalScreenSizeFromFb(framebuffer, screenSize()); -} - -QSize QEGLDeviceIntegration::screenSize() const -{ - return q_screenSizeFromFb(framebuffer); -} - -QDpi QEGLDeviceIntegration::logicalDpi() const -{ - const QSizeF ps = physicalScreenSize(); - const QSize s = screenSize(); - - if (!ps.isEmpty() && !s.isEmpty()) - return QDpi(25.4 * s.width() / ps.width(), - 25.4 * s.height() / ps.height()); - else - return QDpi(100, 100); -} - -qreal QEGLDeviceIntegration::pixelDensity() const -{ - return qRound(logicalDpi().first / qreal(100)); -} - -Qt::ScreenOrientation QEGLDeviceIntegration::nativeOrientation() const -{ - return Qt::PrimaryOrientation; -} - -Qt::ScreenOrientation QEGLDeviceIntegration::orientation() const -{ - return Qt::PrimaryOrientation; -} - -int QEGLDeviceIntegration::screenDepth() const -{ - return q_screenDepthFromFb(framebuffer); -} - -QImage::Format QEGLDeviceIntegration::screenFormat() const -{ - return screenDepth() == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32; -} - -qreal QEGLDeviceIntegration::refreshRate() const -{ - return q_refreshRateFromFb(framebuffer); -} - -EGLint QEGLDeviceIntegration::surfaceType() const -{ - return EGL_WINDOW_BIT; -} - -QSurfaceFormat QEGLDeviceIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const -{ - QSurfaceFormat format = inputFormat; - - static const bool force888 = qEnvironmentVariableIntValue("QT_QPA_EGLFS_FORCE888"); - if (force888) { - format.setRedBufferSize(8); - format.setGreenBufferSize(8); - format.setBlueBufferSize(8); - } - - return format; -} - -bool QEGLDeviceIntegration::filterConfig(EGLDisplay, EGLConfig) const -{ - return true; -} - -QEglFSWindow *QEGLDeviceIntegration::createWindow(QWindow *window) const -{ - return new QEglFSWindow(window); -} - -EGLNativeWindowType QEGLDeviceIntegration::createNativeWindow(QPlatformWindow *platformWindow, - const QSize &size, - const QSurfaceFormat &format) -{ - Q_UNUSED(platformWindow); - Q_UNUSED(size); - Q_UNUSED(format); - return 0; -} - -EGLNativeWindowType QEGLDeviceIntegration::createNativeOffscreenWindow(const QSurfaceFormat &format) -{ - Q_UNUSED(format); - return 0; -} - -void QEGLDeviceIntegration::destroyNativeWindow(EGLNativeWindowType window) -{ - Q_UNUSED(window); -} - -bool QEGLDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - Q_UNUSED(cap); - return false; -} - -QPlatformCursor *QEGLDeviceIntegration::createCursor(QPlatformScreen *screen) const -{ - return new QEglFSCursor(screen); -} - -void QEGLDeviceIntegration::waitForVSync(QPlatformSurface *surface) const -{ - Q_UNUSED(surface); - -#if defined(Q_OS_LINUX) && defined(FBIO_WAITFORVSYNC) - static const bool forceSync = qEnvironmentVariableIntValue("QT_QPA_EGLFS_FORCEVSYNC"); - if (forceSync && framebuffer != -1) { - int arg = 0; - if (ioctl(framebuffer, FBIO_WAITFORVSYNC, &arg) == -1) - qWarning("Could not wait for vsync."); - } -#endif -} - -void QEGLDeviceIntegration::presentBuffer(QPlatformSurface *surface) -{ - Q_UNUSED(surface); -} - -bool QEGLDeviceIntegration::supportsPBuffers() const -{ - return true; -} - -bool QEGLDeviceIntegration::supportsSurfacelessContexts() const -{ - return true; -} - -void *QEGLDeviceIntegration::wlDisplay() const -{ - return Q_NULLPTR; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h deleted file mode 100644 index f1a5bde331..0000000000 --- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLFSDEVICEINTEGRATION_H -#define QEGLFSDEVICEINTEGRATION_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 "qeglfsglobal.h" -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QPlatformSurface; -class QEglFSWindow; - -#define QEGLDeviceIntegrationFactoryInterface_iid "org.qt-project.qt.qpa.egl.QEGLDeviceIntegrationFactoryInterface.5.5" - -class Q_EGLFS_EXPORT QEGLDeviceIntegration -{ -public: - virtual ~QEGLDeviceIntegration() { } - - virtual void platformInit(); - virtual void platformDestroy(); - virtual EGLNativeDisplayType platformDisplay() const; - virtual EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay); - virtual bool usesDefaultScreen(); - virtual void screenInit(); - virtual void screenDestroy(); - virtual QSizeF physicalScreenSize() const; - virtual QSize screenSize() const; - virtual QDpi logicalDpi() const; - virtual qreal pixelDensity() const; - virtual Qt::ScreenOrientation nativeOrientation() const; - virtual Qt::ScreenOrientation orientation() const; - virtual int screenDepth() const; - virtual QImage::Format screenFormat() const; - virtual qreal refreshRate() const; - virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; - virtual EGLint surfaceType() const; - virtual QEglFSWindow *createWindow(QWindow *window) const; - virtual EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, - const QSize &size, - const QSurfaceFormat &format); - virtual EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format); - virtual void destroyNativeWindow(EGLNativeWindowType window); - virtual bool hasCapability(QPlatformIntegration::Capability cap) const; - virtual QPlatformCursor *createCursor(QPlatformScreen *screen) const; - virtual bool filterConfig(EGLDisplay display, EGLConfig config) const; - virtual void waitForVSync(QPlatformSurface *surface) const; - virtual void presentBuffer(QPlatformSurface *surface); - virtual QByteArray fbDeviceName() const; - virtual int framebufferIndex() const; - virtual bool supportsPBuffers() const; - virtual bool supportsSurfacelessContexts() const; - - virtual void *wlDisplay() const; -}; - -class Q_EGLFS_EXPORT QEGLDeviceIntegrationPlugin : public QObject -{ - Q_OBJECT - -public: - virtual QEGLDeviceIntegration *create() = 0; - - // the pattern expected by qLoadPlugin calls for a QString argument. - // we don't need it, so don't bother subclasses with it: - QEGLDeviceIntegration *create(const QString &) { return create(); } -}; - -class Q_EGLFS_EXPORT QEGLDeviceIntegrationFactory -{ -public: - static QStringList keys(const QString &pluginPath = QString()); - static QEGLDeviceIntegration *create(const QString &name, const QString &platformPluginPath = QString()); -}; - -QT_END_NAMESPACE - -#endif // QEGLDEVICEINTEGRATION_H diff --git a/src/plugins/platforms/eglfs/qeglfsglobal.h b/src/plugins/platforms/eglfs/qeglfsglobal.h deleted file mode 100644 index d6aba565ce..0000000000 --- a/src/plugins/platforms/eglfs/qeglfsglobal.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLFSGLOBAL_H -#define QEGLFSGLOBAL_H - -#include - -#ifdef QT_BUILD_EGL_DEVICE_LIB -#define Q_EGLFS_EXPORT Q_DECL_EXPORT -#else -#define Q_EGLFS_EXPORT Q_DECL_IMPORT -#endif - -#include -#undef Status -#undef None -#undef Bool -#undef CursorShape -#undef KeyPress -#undef KeyRelease -#undef FocusIn -#undef FocusOut -#undef FontChange -#undef Expose -#undef Unsorted - -#endif diff --git a/src/plugins/platforms/eglfs/qeglfshooks.cpp b/src/plugins/platforms/eglfs/qeglfshooks.cpp deleted file mode 100644 index 87285428df..0000000000 --- a/src/plugins/platforms/eglfs/qeglfshooks.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake spec 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 "qeglfshooks.h" -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qLcEglDevDebug) - -#ifdef EGLFS_PLATFORM_HOOKS - -QEGLDeviceIntegration *qt_egl_device_integration() -{ - extern QEglFSHooks *platformHooks; - return platformHooks; -} - -#else - -class DeviceIntegration -{ -public: - DeviceIntegration(); - ~DeviceIntegration() { delete m_integration; } - QEGLDeviceIntegration *integration() { return m_integration; } -private: - QEGLDeviceIntegration *m_integration; -}; - -Q_GLOBAL_STATIC(DeviceIntegration, deviceIntegration) - -DeviceIntegration::DeviceIntegration() : m_integration(0) -{ - QStringList pluginKeys = QEGLDeviceIntegrationFactory::keys(); - if (!pluginKeys.isEmpty()) { - // Some built-in logic: Prioritize either X11 or KMS/DRM. - if (qEnvironmentVariableIsSet("DISPLAY")) { - const QString x11key = QStringLiteral("eglfs_x11"); - if (pluginKeys.contains(x11key)) { - pluginKeys.removeOne(x11key); - pluginKeys.prepend(x11key); - } - } else { - const QString kmskey = QStringLiteral("eglfs_kms"); - if (pluginKeys.contains(kmskey)) { - pluginKeys.removeOne(kmskey); - pluginKeys.prepend(kmskey); - } - } - - QByteArray requested; - - // The environment variable can override everything. - if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_INTEGRATION")) { - requested = qgetenv("QT_QPA_EGLFS_INTEGRATION"); - } else { - // Device-specific makespecs may define a preferred plugin. -#ifdef EGLFS_PREFERRED_PLUGIN -#define DEFAULT_PLUGIN EGLFS_PREFERRED_PLUGIN -#define STR(s) #s -#define STRQ(s) STR(s) - requested = STRQ(DEFAULT_PLUGIN); -#endif - } - - // Treat "none" as special. There has to be a way to indicate - // that plugins must be ignored when the device is known to be - // functional with the default, non-specialized integration. - if (requested != QByteArrayLiteral("none")) { - if (!requested.isEmpty()) { - QString reqStr = QString::fromLocal8Bit(requested); - pluginKeys.removeOne(reqStr); - pluginKeys.prepend(reqStr); - } - qCDebug(qLcEglDevDebug) << "EGL device integration plugin keys (sorted):" << pluginKeys; - while (!m_integration && !pluginKeys.isEmpty()) { - QString key = pluginKeys.takeFirst(); - qCDebug(qLcEglDevDebug) << "Trying to load device EGL integration" << key; - m_integration = QEGLDeviceIntegrationFactory::create(key); - } - } - } - - if (!m_integration) { - // Use a default, non-specialized device integration when no plugin is available. - // For some systems this is sufficient. - qCDebug(qLcEglDevDebug) << "Using base device integration"; - m_integration = new QEGLDeviceIntegration; - } -} - -QEGLDeviceIntegration *qt_egl_device_integration() -{ - return deviceIntegration()->integration(); -} - -#endif // EGLFS_PLATFORM_HOOKS - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h deleted file mode 100644 index cc6c325b58..0000000000 --- a/src/plugins/platforms/eglfs/qeglfshooks.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLFSHOOKS_H -#define QEGLFSHOOKS_H - -#include "qeglfsglobal.h" -#include "qeglfsdeviceintegration.h" - -QT_BEGIN_NAMESPACE - -class QEglFSHooks : public QEGLDeviceIntegration -{ -}; - -Q_EGLFS_EXPORT QEGLDeviceIntegration *qt_egl_device_integration(); - -QT_END_NAMESPACE - -#endif // QEGLFSHOOKS_H diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 6f38a96f45..8c8ef99bc2 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -52,11 +52,11 @@ #include #include "qeglfsintegration.h" -#include "qeglfswindow.h" -#include "qeglfshooks.h" +#include "qeglfswindow_p.h" +#include "qeglfshooks_p.h" #include "qeglfscontext.h" #include "qeglfsoffscreenwindow.h" -#include "qeglfscursor.h" +#include "qeglfscursor_p.h" #include #include @@ -205,7 +205,7 @@ QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLCo QEglFSContext *ctx; QSurfaceFormat adjustedFormat = qt_egl_device_integration()->surfaceFormatFor(context->format()); if (nativeHandle.isNull()) { - EGLConfig config = QEglFSIntegration::chooseConfig(dpy, adjustedFormat); + EGLConfig config = QEglFSDeviceIntegration::chooseConfig(dpy, adjustedFormat); ctx = new QEglFSContext(adjustedFormat, share, dpy, &config, QVariant()); } else { ctx = new QEglFSContext(adjustedFormat, share, dpy, 0, nativeHandle); @@ -436,22 +436,4 @@ EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const return qt_egl_device_integration()->platformDisplay(); } -EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format) -{ - class Chooser : public QEglConfigChooser { - public: - Chooser(EGLDisplay display) - : QEglConfigChooser(display) { } - bool filterConfig(EGLConfig config) const Q_DECL_OVERRIDE { - return qt_egl_device_integration()->filterConfig(display(), config) - && QEglConfigChooser::filterConfig(config); - } - }; - - Chooser chooser(display); - chooser.setSurfaceType(qt_egl_device_integration()->surfaceType()); - chooser.setSurfaceFormat(format); - return chooser.chooseConfig(); -} - QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index 678452a8db..9c5439a22f 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -92,8 +92,6 @@ public: void addScreen(QPlatformScreen *screen); void removeScreen(QPlatformScreen *screen); - static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format); - private: EGLNativeDisplayType nativeDisplay() const; void createInputHandlers(); diff --git a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.cpp b/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.cpp index 11b101970b..0334ac9785 100644 --- a/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfsoffscreenwindow.cpp @@ -38,7 +38,7 @@ ****************************************************************************/ #include "qeglfsoffscreenwindow.h" -#include "qeglfshooks.h" +#include "qeglfshooks_p.h" #include #include diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp deleted file mode 100644 index a1ab854db1..0000000000 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include - -#include "qeglfsscreen.h" -#include "qeglfswindow.h" -#include "qeglfshooks.h" - -QT_BEGIN_NAMESPACE - -QEglFSScreen::QEglFSScreen(EGLDisplay dpy) - : m_dpy(dpy), - m_surface(EGL_NO_SURFACE), - m_cursor(0) -{ - m_cursor = qt_egl_device_integration()->createCursor(this); -} - -QEglFSScreen::~QEglFSScreen() -{ - delete m_cursor; - QOpenGLCompositor::destroy(); -} - -QRect QEglFSScreen::geometry() const -{ - return QRect(QPoint(0, 0), qt_egl_device_integration()->screenSize()); -} - -int QEglFSScreen::depth() const -{ - return qt_egl_device_integration()->screenDepth(); -} - -QImage::Format QEglFSScreen::format() const -{ - return qt_egl_device_integration()->screenFormat(); -} - -QSizeF QEglFSScreen::physicalSize() const -{ - return qt_egl_device_integration()->physicalScreenSize(); -} - -QDpi QEglFSScreen::logicalDpi() const -{ - return qt_egl_device_integration()->logicalDpi(); -} - -qreal QEglFSScreen::pixelDensity() const -{ - return qt_egl_device_integration()->pixelDensity(); -} - -Qt::ScreenOrientation QEglFSScreen::nativeOrientation() const -{ - return qt_egl_device_integration()->nativeOrientation(); -} - -Qt::ScreenOrientation QEglFSScreen::orientation() const -{ - return qt_egl_device_integration()->orientation(); -} - -QPlatformCursor *QEglFSScreen::cursor() const -{ - return m_cursor; -} - -qreal QEglFSScreen::refreshRate() const -{ - return qt_egl_device_integration()->refreshRate(); -} - -void QEglFSScreen::setPrimarySurface(EGLSurface surface) -{ - m_surface = surface; -} - -void QEglFSScreen::handleCursorMove(const QPoint &pos) -{ - const QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - const QList 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 windows = compositor->windows(); - Q_ASSERT(!windows.isEmpty()); - - QImage img; - - if (static_cast(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 deleted file mode 100644 index 57d68ca572..0000000000 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLFSSCREEN_H -#define QEGLFSSCREEN_H - -#include "qeglfsglobal.h" -#include - -QT_BEGIN_NAMESPACE - -class QEglFSWindow; -class QOpenGLContext; - -class Q_EGLFS_EXPORT QEglFSScreen : public QPlatformScreen -{ -public: - QEglFSScreen(EGLDisplay display); - ~QEglFSScreen(); - - QRect geometry() const Q_DECL_OVERRIDE; - int depth() const Q_DECL_OVERRIDE; - QImage::Format format() const Q_DECL_OVERRIDE; - - QSizeF physicalSize() const Q_DECL_OVERRIDE; - QDpi logicalDpi() const Q_DECL_OVERRIDE; - qreal pixelDensity() const Q_DECL_OVERRIDE; - Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE; - Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE; - - QPlatformCursor *cursor() const Q_DECL_OVERRIDE; - - 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; } - - EGLDisplay display() const { return m_dpy; } - - void handleCursorMove(const QPoint &pos); - -private: - void setPrimarySurface(EGLSurface surface); - - EGLDisplay m_dpy; - QPointer m_pointerWindow; - EGLSurface m_surface; - QPlatformCursor *m_cursor; - - friend class QEglFSWindow; -}; - -QT_END_NAMESPACE - -#endif // QEGLFSSCREEN_H diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp deleted file mode 100644 index 556d3942cd..0000000000 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qeglfswindow.h" -#include "qeglfscursor.h" -#include "qeglfshooks.h" - -QT_BEGIN_NAMESPACE - -QEglFSWindow::QEglFSWindow(QWindow *w) - : QPlatformWindow(w), - m_backingStore(0), - m_raster(false), - m_winId(0), - m_surface(EGL_NO_SURFACE), - m_window(0), - m_flags(0) -{ -} - -QEglFSWindow::~QEglFSWindow() -{ - destroy(); -} - -static WId newWId() -{ - static WId id = 0; - - if (id == std::numeric_limits::max()) - qWarning("QEGLPlatformWindow: Out of window IDs"); - - return ++id; -} - -void QEglFSWindow::create() -{ - if (m_flags.testFlag(Created)) - return; - - 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; - - if (window()->type() == Qt::Desktop) - return; - - // Stop if there is already a window backed by a native window and surface. Additional - // raster windows will not have their own native window, surface and context. Instead, - // they will be composited onto the root window's surface. - QEglFSScreen *screen = this->screen(); - QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - if (screen->primarySurface() != EGL_NO_SURFACE) { - if (Q_UNLIKELY(!isRaster() || !compositor->targetWindow())) { -#if !defined(Q_OS_ANDROID) - // We can have either a single OpenGL window or multiple raster windows. - // Other combinations cannot work. - qFatal("EGLFS: OpenGL windows cannot be mixed with others."); -#endif - return; - } - m_format = compositor->targetWindow()->format(); - return; - } - - m_flags |= HasNativeWindow; - setGeometry(QRect()); // will become fullscreen - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size())); - - resetSurface(); - - if (Q_UNLIKELY(m_surface == EGL_NO_SURFACE)) { - EGLint error = eglGetError(); - eglTerminate(screen->display()); - qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error); - } - - screen->setPrimarySurface(m_surface); - - if (isRaster()) { - QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance()); - context->setShareContext(qt_gl_global_share_context()); - context->setFormat(m_format); - context->setScreen(window()->screen()); - if (Q_UNLIKELY(!context->create())) - qFatal("EGLFS: Failed to create compositing context"); - compositor->setTarget(context, window()); - // If there is a "root" window into which raster and QOpenGLWidget content is - // composited, all other contexts must share with its context. - if (!qt_gl_global_share_context()) { - qt_gl_set_global_share_context(context); - // What we set up here is in effect equivalent to the application setting - // AA_ShareOpenGLContexts. Set the attribute to be fully consistent. - QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); - } - } -} - -void QEglFSWindow::destroy() -{ - QEglFSScreen *screen = this->screen(); - if (m_flags.testFlag(HasNativeWindow)) { - QEglFSCursor *cursor = qobject_cast(screen->cursor()); - if (cursor) - cursor->resetResources(); - - if (screen->primarySurface() == m_surface) - screen->setPrimarySurface(EGL_NO_SURFACE); - - invalidateSurface(); - } - - m_flags = 0; - QOpenGLCompositor::instance()->removeWindow(this); -} - -void QEglFSWindow::invalidateSurface() -{ - if (m_surface != EGL_NO_SURFACE) { - eglDestroySurface(screen()->display(), m_surface); - m_surface = EGL_NO_SURFACE; - } - qt_egl_device_integration()->destroyNativeWindow(m_window); - m_window = 0; -} - -void QEglFSWindow::resetSurface() -{ - EGLDisplay display = screen()->display(); - QSurfaceFormat platformFormat = qt_egl_device_integration()->surfaceFormatFor(window()->requestedFormat()); - - m_config = QEglFSIntegration::chooseConfig(display, platformFormat); - m_format = q_glFormatFromConfig(display, m_config, platformFormat); - m_window = qt_egl_device_integration()->createNativeWindow(this, screen()->geometry().size(), m_format); - m_surface = eglCreateWindowSurface(display, m_config, m_window, NULL); -} - -void QEglFSWindow::setVisible(bool visible) -{ - QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - QList windows = compositor->windows(); - QWindow *wnd = window(); - - if (wnd->type() != Qt::Desktop) { - if (visible) { - compositor->addWindow(this); - } else { - compositor->removeWindow(this); - windows = compositor->windows(); - if (windows.size()) - windows.last()->sourceWindow()->requestActivate(); - } - } - - QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); - - if (visible) - QWindowSystemInterface::flushWindowSystemEvents(); -} - -void QEglFSWindow::setGeometry(const QRect &r) -{ - QRect rect; - bool forceFullscreen = m_flags.testFlag(HasNativeWindow); - if (forceFullscreen) - rect = screen()->availableGeometry(); - else - rect = r; - - QPlatformWindow::setGeometry(rect); - - // if we corrected the size, trigger a resize event - if (rect != r) - QWindowSystemInterface::handleGeometryChange(window(), rect, r); -} - -QRect QEglFSWindow::geometry() const -{ - // For yet-to-become-fullscreen windows report the geometry covering the entire - // screen. This is particularly important for Quick where the root object may get - // sized to some geometry queried before calling create(). - if (!m_flags.testFlag(Created) && screen()->primarySurface() == EGL_NO_SURFACE) - return screen()->availableGeometry(); - - return QPlatformWindow::geometry(); -} - -void QEglFSWindow::requestActivateWindow() -{ - if (window()->type() != Qt::Desktop) - QOpenGLCompositor::instance()->moveToTop(this); - - QWindow *wnd = window(); - QWindowSystemInterface::handleWindowActivated(wnd); - QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); -} - -void QEglFSWindow::raise() -{ - QWindow *wnd = window(); - if (wnd->type() != Qt::Desktop) { - QOpenGLCompositor::instance()->moveToTop(this); - QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size())); - } -} - -void QEglFSWindow::lower() -{ - QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); - QList windows = compositor->windows(); - if (window()->type() != Qt::Desktop && windows.count() > 1) { - int idx = windows.indexOf(this); - if (idx > 0) { - compositor->changeWindowIndex(this, idx - 1); - QWindowSystemInterface::handleExposeEvent(windows.last()->sourceWindow(), - QRect(QPoint(0, 0), windows.last()->sourceWindow()->geometry().size())); - } - } -} - -EGLSurface QEglFSWindow::surface() const -{ - return m_surface != EGL_NO_SURFACE ? m_surface : screen()->primarySurface(); -} - -QSurfaceFormat QEglFSWindow::format() const -{ - return m_format; -} - -EGLNativeWindowType QEglFSWindow::eglWindow() const -{ - return m_window; -} - -QEglFSScreen *QEglFSWindow::screen() const -{ - return static_cast(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 deleted file mode 100644 index d607c8bd62..0000000000 --- a/src/plugins/platforms/eglfs/qeglfswindow.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QEGLFSWINDOW_H -#define QEGLFSWINDOW_H - -#include "qeglfsglobal.h" -#include "qeglfsintegration.h" -#include "qeglfsscreen.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -class QOpenGLCompositorBackingStore; -class QPlatformTextureList; - -class Q_EGLFS_EXPORT QEglFSWindow : public QPlatformWindow, public QOpenGLCompositorWindow -{ -public: - QEglFSWindow(QWindow *w); - ~QEglFSWindow(); - - void create(); - void destroy(); - - void setGeometry(const QRect &) Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE; - void setVisible(bool visible) Q_DECL_OVERRIDE; - void requestActivateWindow() Q_DECL_OVERRIDE; - void raise() Q_DECL_OVERRIDE; - void lower() Q_DECL_OVERRIDE; - - void propagateSizeHints() 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; - EGLSurface surface() const; - QEglFSScreen *screen() const; - - bool hasNativeWindow() const { return m_flags.testFlag(HasNativeWindow); } - - virtual void invalidateSurface() Q_DECL_OVERRIDE; - virtual void resetSurface(); - - 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; - -protected: - QOpenGLCompositorBackingStore *m_backingStore; - bool m_raster; - WId m_winId; - - EGLSurface m_surface; - EGLNativeWindowType m_window; - - EGLConfig m_config; - QSurfaceFormat m_format; - - enum Flag { - Created = 0x01, - HasNativeWindow = 0x02 - }; - Q_DECLARE_FLAGS(Flags, Flag) - Flags m_flags; -}; - -QT_END_NAMESPACE - -#endif // QEGLFSWINDOW_H diff --git a/sync.profile b/sync.profile index bba0ff2b2f..7807907420 100644 --- a/sync.profile +++ b/sync.profile @@ -18,8 +18,10 @@ "QtANGLE/EGL" => "!$basedir/src/3rdparty/angle/include/EGL", "QtZlib" => "!>$basedir/src/corelib;$basedir/src/3rdparty/zlib", "QtOpenGLExtensions" => "$basedir/src/openglextensions", + "QtEglFSDeviceIntegration" => "$basedir/src/plugins/platforms/eglfs", ); %moduleheaders = ( # restrict the module headers to those found in relative path + "QtEglFSDeviceIntegration" => "api", ); @allmoduleheadersprivate = ( ); -- cgit v1.2.3