summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-08-08 11:37:43 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2016-08-10 09:04:47 +0000
commitb305702d1e38d72765325dd7b1f2a7fde14e5529 (patch)
tree701309886d8d34a74b025a2b8de2633fc36e0f7b /src
parente93042522817003f35402adea83b8a537dba7c87 (diff)
eglfs: Support virtual desktops in the OpenGL cursor
The GBM-based hardware cursor already has this. Let's implement it in the commonly used OpenGL cursor too. The main user will be the EGLDevice backend which does not currently have a hardware cursor but supports multiple screens. This also means QEglFSCursor must be capable of operating on different contexts (and what's more, non-sharing contexts). Task-number: QTBUG-55161 Change-Id: Ie23bba1e6aab34b04d689f26a84c19a2bde518da Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor.cpp163
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor_p.h27
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp3
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp33
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h12
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h1
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp22
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h7
9 files changed, 198 insertions, 76 deletions
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
index 7c1f11372a..0040ecd59d 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
@@ -59,12 +59,11 @@
QT_BEGIN_NAMESPACE
QEglFSCursor::QEglFSCursor(QPlatformScreen *screen)
- : m_visible(true),
- m_screen(static_cast<QEglFSScreen *>(screen)),
- m_program(0),
- m_textureEntry(0),
- m_deviceListener(0),
- m_updateRequested(false)
+ : m_visible(true),
+ m_screen(static_cast<QEglFSScreen *>(screen)),
+ m_activeScreen(nullptr),
+ m_deviceListener(0),
+ m_updateRequested(false)
{
QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
if (!hideCursorVal.isEmpty())
@@ -116,15 +115,14 @@ void QEglFSCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::Device
void QEglFSCursor::resetResources()
{
- if (QOpenGLContext::currentContext()) {
- delete m_program;
- glDeleteTextures(1, &m_cursor.customCursorTexture);
- glDeleteTextures(1, &m_cursorAtlas.texture);
+ if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) {
+ GraphicsContextData &gfx(m_gfx[ctx]);
+ delete gfx.program;
+ glDeleteTextures(1, &gfx.customCursorTexture);
+ glDeleteTextures(1, &gfx.atlasTexture);
+ gfx = GraphicsContextData();
}
- m_program = 0;
- m_cursor.customCursorTexture = 0;
m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull();
- m_cursorAtlas.texture = 0;
}
void QEglFSCursor::createShaderPrograms()
@@ -146,15 +144,16 @@ void QEglFSCursor::createShaderPrograms()
" gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
"}\n";
- m_program = new QOpenGLShaderProgram;
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
- m_program->bindAttributeLocation("vertexCoordEntry", 0);
- m_program->bindAttributeLocation("textureCoordEntry", 1);
- m_program->link();
+ GraphicsContextData &gfx(m_gfx[QOpenGLContext::currentContext()]);
+ gfx.program = new QOpenGLShaderProgram;
+ gfx.program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ gfx.program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ gfx.program->bindAttributeLocation("vertexCoordEntry", 0);
+ gfx.program->bindAttributeLocation("textureCoordEntry", 1);
+ gfx.program->link();
- m_textureEntry = m_program->uniformLocation("texture");
- m_matEntry = m_program->uniformLocation("mat");
+ gfx.textureEntry = gfx.program->uniformLocation("texture");
+ gfx.matEntry = gfx.program->uniformLocation("mat");
}
void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image)
@@ -214,7 +213,7 @@ void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window)
Q_UNUSED(window);
const QRect oldCursorRect = cursorRect();
if (setCurrentCursor(cursor))
- update(oldCursorRect | cursorRect());
+ update(oldCursorRect | cursorRect(), false);
}
bool QEglFSCursor::setCurrentCursor(QCursor *cursor)
@@ -238,16 +237,17 @@ bool QEglFSCursor::setCurrentCursor(QCursor *cursor)
hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow),
ws, hs);
m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape];
- m_cursor.texture = m_cursorAtlas.texture;
+ m_cursor.useCustomCursor = false;
m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight);
} else {
QImage image = cursor->pixmap().toImage();
m_cursor.textureRect = QRectF(0, 0, 1, 1);
m_cursor.hotSpot = cursor->hotSpot();
- m_cursor.texture = 0; // will get updated in the next render()
+ m_cursor.useCustomCursor = false; // will get updated in the next render()
m_cursor.size = image.size();
m_cursor.customCursorImage = image;
m_cursor.customCursorPending = true;
+ m_cursor.customCursorKey = m_cursor.customCursorImage.cacheKey();
}
return true;
@@ -257,17 +257,20 @@ bool QEglFSCursor::setCurrentCursor(QCursor *cursor)
class CursorUpdateEvent : public QEvent
{
public:
- CursorUpdateEvent(const QPoint &pos, const QRegion &rgn)
+ CursorUpdateEvent(const QPoint &pos, const QRect &rect, bool allScreens)
: QEvent(QEvent::Type(QEvent::User + 1)),
m_pos(pos),
- m_region(rgn)
+ m_rect(rect),
+ m_allScreens(allScreens)
{ }
QPoint pos() const { return m_pos; }
- QRegion region() const { return m_region; }
+ QRegion rect() const { return m_rect; }
+ bool allScreens() const { return m_allScreens; }
private:
QPoint m_pos;
- QRegion m_region;
+ QRect m_rect;
+ bool m_allScreens;
};
bool QEglFSCursor::event(QEvent *e)
@@ -275,21 +278,30 @@ bool QEglFSCursor::event(QEvent *e)
if (e->type() == QEvent::User + 1) {
CursorUpdateEvent *ev = static_cast<CursorUpdateEvent *>(e);
m_updateRequested = false;
- QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(ev->pos()), ev->region());
- QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
+ if (!ev->allScreens()) {
+ QWindow *w = m_screen->topLevelAt(ev->pos()); // works for the entire virtual desktop, no need to loop
+ if (w) {
+ QWindowSystemInterface::handleExposeEvent(w, ev->rect());
+ QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
+ }
+ } else {
+ for (QWindow *w : qGuiApp->topLevelWindows())
+ QWindowSystemInterface::handleExposeEvent(w, w->geometry());
+ QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
+ }
return true;
}
return QPlatformCursor::event(e);
}
-void QEglFSCursor::update(const QRegion &rgn)
+void QEglFSCursor::update(const QRect &rect, bool allScreens)
{
if (!m_updateRequested) {
// Must not flush the window system events directly from here since we are likely to
// be a called directly from QGuiApplication's processMouseEvents. Flushing events
// could cause reentering by dispatching more queued mouse events.
m_updateRequested = true;
- QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rgn));
+ QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rect, allScreens));
}
}
@@ -308,8 +320,9 @@ void QEglFSCursor::setPos(const QPoint &pos)
QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos);
const QRect oldCursorRect = cursorRect();
m_cursor.pos = pos;
- update(oldCursorRect | cursorRect());
- m_screen->handleCursorMove(m_cursor.pos);
+ update(oldCursorRect | cursorRect(), false);
+ for (QPlatformScreen *screen : m_screen->virtualSiblings())
+ static_cast<QEglFSScreen *>(screen)->handleCursorMove(m_cursor.pos);
}
void QEglFSCursor::pointerEvent(const QMouseEvent &event)
@@ -318,8 +331,9 @@ void QEglFSCursor::pointerEvent(const QMouseEvent &event)
return;
const QRect oldCursorRect = cursorRect();
m_cursor.pos = event.screenPos().toPoint();
- update(oldCursorRect | cursorRect());
- m_screen->handleCursorMove(m_cursor.pos);
+ update(oldCursorRect | cursorRect(), false);
+ for (QPlatformScreen *screen : m_screen->virtualSiblings())
+ static_cast<QEglFSScreen *>(screen)->handleCursorMove(m_cursor.pos);
}
void QEglFSCursor::paintOnScreen()
@@ -327,15 +341,35 @@ void QEglFSCursor::paintOnScreen()
if (!m_visible)
return;
- const QRectF cr = cursorRect();
- const QRect screenRect(m_screen->geometry());
- const GLfloat x1 = 2 * (cr.left() / screenRect.width()) - 1;
- const GLfloat x2 = 2 * (cr.right() / screenRect.width()) - 1;
- const GLfloat y1 = 1 - (cr.top() / screenRect.height()) * 2;
- const GLfloat y2 = 1 - (cr.bottom() / screenRect.height()) * 2;
- QRectF r(QPointF(x1, y1), QPointF(x2, y2));
+ QRect cr = cursorRect(); // hotspot included
+
+ // Support virtual desktop too. Backends with multi-screen support (e.g. all
+ // variants of KMS/DRM) will enable this by default. In this case all
+ // screens are siblings of each other. When not enabled, the sibling list
+ // only contains m_screen itself.
+ for (QPlatformScreen *screen : m_screen->virtualSiblings()) {
+ if (screen->geometry().contains(cr.topLeft() + m_cursor.hotSpot)
+ && QOpenGLContext::currentContext()->screen() == screen->screen())
+ {
+ cr.translate(-screen->geometry().topLeft());
+ const QSize screenSize = screen->geometry().size();
+ const GLfloat x1 = 2 * (cr.left() / GLfloat(screenSize.width())) - 1;
+ const GLfloat x2 = 2 * (cr.right() / GLfloat(screenSize.width())) - 1;
+ const GLfloat y1 = 1 - (cr.top() / GLfloat(screenSize.height())) * 2;
+ const GLfloat y2 = 1 - (cr.bottom() / GLfloat(screenSize.height())) * 2;
+ QRectF r(QPointF(x1, y1), QPointF(x2, y2));
+
+ draw(r);
+
+ if (screen != m_activeScreen) {
+ m_activeScreen = screen;
+ // Do not want a leftover cursor on the screen the cursor just left.
+ update(cursorRect(), true);
+ }
- draw(r);
+ break;
+ }
+ }
}
// In order to prevent breaking code doing custom OpenGL rendering while
@@ -437,30 +471,33 @@ void QEglFSCursor::draw(const QRectF &r)
{
StateSaver stateSaver;
- if (!m_program) {
+ GraphicsContextData &gfx(m_gfx[QOpenGLContext::currentContext()]);
+ if (!gfx.program) {
// one time initialization
initializeOpenGLFunctions();
createShaderPrograms();
- if (!m_cursorAtlas.texture) {
- createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image);
+ if (!gfx.atlasTexture) {
+ createCursorTexture(&gfx.atlasTexture, m_cursorAtlas.image);
if (m_cursor.shape != Qt::BitmapCursor)
- m_cursor.texture = m_cursorAtlas.texture;
+ m_cursor.useCustomCursor = false;
}
}
- if (m_cursor.shape == Qt::BitmapCursor && m_cursor.customCursorPending) {
+ if (m_cursor.shape == Qt::BitmapCursor && (m_cursor.customCursorPending || m_cursor.customCursorKey != gfx.customCursorKey)) {
// upload the custom cursor
- createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage);
- m_cursor.texture = m_cursor.customCursorTexture;
+ createCursorTexture(&gfx.customCursorTexture, m_cursor.customCursorImage);
+ m_cursor.useCustomCursor = true;
m_cursor.customCursorPending = false;
+ gfx.customCursorKey = m_cursor.customCursorKey;
}
- Q_ASSERT(m_cursor.texture);
+ GLuint cursorTexture = !m_cursor.useCustomCursor ? gfx.atlasTexture : gfx.customCursorTexture;
+ Q_ASSERT(cursorTexture);
- m_program->bind();
+ gfx.program->bind();
const GLfloat x1 = r.left();
const GLfloat x2 = r.right();
@@ -485,20 +522,20 @@ void QEglFSCursor::draw(const QRectF &r)
};
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, m_cursor.texture);
+ glBindTexture(GL_TEXTURE_2D, cursorTexture);
if (stateSaver.vaoHelper->isValid())
stateSaver.vaoHelper->glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
- m_program->enableAttributeArray(0);
- m_program->enableAttributeArray(1);
- m_program->setAttributeArray(0, cursorCoordinates, 2);
- m_program->setAttributeArray(1, textureCoordinates, 2);
+ gfx.program->enableAttributeArray(0);
+ gfx.program->enableAttributeArray(1);
+ gfx.program->setAttributeArray(0, cursorCoordinates, 2);
+ gfx.program->setAttributeArray(1, textureCoordinates, 2);
- m_program->setUniformValue(m_textureEntry, 0);
- m_program->setUniformValue(m_matEntry, m_rotationMatrix);
+ gfx.program->setUniformValue(gfx.textureEntry, 0);
+ gfx.program->setUniformValue(gfx.matEntry, m_rotationMatrix);
glDisable(GL_CULL_FACE);
glFrontFace(GL_CCW);
@@ -508,9 +545,9 @@ void QEglFSCursor::draw(const QRectF &r)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- m_program->disableAttributeArray(0);
- m_program->disableAttributeArray(1);
- m_program->release();
+ gfx.program->disableAttributeArray(0);
+ gfx.program->disableAttributeArray(1);
+ gfx.program->release();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
index f72e4c0374..8ccbe4493c 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
@@ -105,30 +105,29 @@ private:
bool setCurrentCursor(QCursor *cursor);
#endif
void draw(const QRectF &rect);
- void update(const QRegion &region);
+ void update(const QRect &rect, bool allScreens);
void createShaderPrograms();
void createCursorTexture(uint *texture, const QImage &image);
void initCursorAtlas();
// current cursor information
struct Cursor {
- Cursor() : texture(0), shape(Qt::BlankCursor), customCursorTexture(0), customCursorPending(false) { }
- uint texture; // a texture from 'image' or the atlas
+ Cursor() : shape(Qt::BlankCursor), customCursorPending(false), customCursorKey(0), useCustomCursor(false) { }
Qt::CursorShape shape;
QRectF textureRect; // normalized rect inside texture
QSize size; // size of the cursor
QPoint hotSpot;
QImage customCursorImage;
QPoint pos; // current cursor position
- uint customCursorTexture;
bool customCursorPending;
+ qint64 customCursorKey;
+ bool useCustomCursor;
} m_cursor;
// cursor atlas information
struct CursorAtlas {
- CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { }
+ CursorAtlas() : cursorsPerRow(0), cursorWidth(0), cursorHeight(0) { }
int cursorsPerRow;
- uint texture;
int width, height; // width and height of the atlas
int cursorWidth, cursorHeight; // width and height of cursors inside the atlas
QList<QPoint> hotSpots;
@@ -137,12 +136,22 @@ private:
bool m_visible;
QEglFSScreen *m_screen;
- QOpenGLShaderProgram *m_program;
- int m_textureEntry;
- int m_matEntry;
+ QPlatformScreen *m_activeScreen;
QEglFSCursorDeviceListener *m_deviceListener;
bool m_updateRequested;
QMatrix4x4 m_rotationMatrix;
+
+ struct GraphicsContextData {
+ GraphicsContextData() : program(nullptr), textureEntry(0), matEntry(0),
+ customCursorTexture(0), atlasTexture(0), customCursorKey(0) { }
+ QOpenGLShaderProgram *program;
+ int textureEntry;
+ int matEntry;
+ uint customCursorTexture;
+ uint atlasTexture;
+ qint64 customCursorKey;
+ };
+ QHash<QOpenGLContext *, GraphicsContextData> m_gfx;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
index 3848e99221..6f65929913 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
@@ -41,6 +41,7 @@
#include "qeglfsintegration.h"
#include "qeglfscursor_p.h"
#include "qeglfswindow_p.h"
+#include "qeglfsscreen_p.h"
#include "qeglfshooks_p.h"
#include <QtPlatformSupport/private/qeglconvenience_p.h>
@@ -311,7 +312,7 @@ bool QEglFSDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap
QPlatformCursor *QEglFSDeviceIntegration::createCursor(QPlatformScreen *screen) const
{
- return new QEglFSCursor(screen);
+ return new QEglFSCursor(static_cast<QEglFSScreen *>(screen));
}
void QEglFSDeviceIntegration::waitForVSync(QPlatformSurface *surface) const
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp
index 743f714cf0..f45b947fa6 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp
@@ -40,11 +40,15 @@
#include "qeglfskmsegldevice.h"
#include "qeglfskmsegldevicescreen.h"
#include "qeglfskmsegldeviceintegration.h"
+#include "private/qeglfscursor_p.h"
#include <QtCore/private/qcore_unix_p.h>
+QT_BEGIN_NAMESPACE
+
QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path)
- : QEglFSKmsDevice(integration, path)
+ : QEglFSKmsDevice(integration, path),
+ m_globalCursor(nullptr)
{
}
@@ -52,6 +56,8 @@ bool QEglFSKmsEglDevice::open()
{
Q_ASSERT(fd() == -1);
+ qCDebug(qLcEglfsKmsDebug, "Opening DRM device %s", qPrintable(devicePath()));
+
int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR);
if (Q_UNLIKELY(fd < 0))
qFatal("Could not open DRM device");
@@ -63,6 +69,8 @@ bool QEglFSKmsEglDevice::open()
void QEglFSKmsEglDevice::close()
{
+ qCDebug(qLcEglfsKmsDebug, "Closing DRM device");
+
if (qt_safe_close(fd()) == -1)
qErrnoWarning("Could not close DRM device");
@@ -74,7 +82,26 @@ EGLNativeDisplayType QEglFSKmsEglDevice::nativeDisplay() const
return static_cast<QEglFSKmsEglDeviceIntegration *>(m_integration)->eglDevice();
}
-QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position)
+QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device,
+ QEglFSKmsOutput output, QPoint position)
{
- return new QEglFSKmsEglDeviceScreen(integration, device, output, position);
+ QEglFSKmsScreen *screen = new QEglFSKmsEglDeviceScreen(integration, device, output, position);
+
+ if (!m_globalCursor && !integration->separateScreens()) {
+ qCDebug(qLcEglfsKmsDebug, "Creating new global mouse cursor");
+ m_globalCursor = new QEglFSCursor(screen);
+ }
+
+ return screen;
}
+
+void QEglFSKmsEglDevice::destroyGlobalCursor()
+{
+ if (m_globalCursor) {
+ qCDebug(qLcEglfsKmsDebug, "Destroying global mouse cursor");
+ delete m_globalCursor;
+ m_globalCursor = nullptr;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h
index b1c98f3fe6..a27112fb4f 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h
@@ -42,6 +42,10 @@
#include <qeglfskmsdevice.h>
+QT_BEGIN_NAMESPACE
+
+class QPlatformCursor;
+
class QEglFSKmsEglDevice: public QEglFSKmsDevice
{
public:
@@ -56,6 +60,14 @@ public:
QEglFSKmsDevice *device,
QEglFSKmsOutput output,
QPoint position) Q_DECL_OVERRIDE;
+
+ QPlatformCursor *globalCursor() { return m_globalCursor; }
+ void destroyGlobalCursor();
+
+private:
+ QPlatformCursor *m_globalCursor;
};
+QT_END_NAMESPACE
+
#endif // QEGLFSKMSEGLDEVICE_H
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
index cbf7cfe7d0..0120c0726d 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
@@ -41,6 +41,7 @@
#include "qeglfskmsegldeviceintegration.h"
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include "private/qeglfswindow_p.h"
+#include "private/qeglfscursor_p.h"
#include "qeglfskmsegldevice.h"
#include "qeglfskmsscreen.h"
#include <QLoggingCategory>
@@ -258,4 +259,9 @@ bool QEglFSKmsEglDeviceIntegration::query_egl_device()
return true;
}
+QPlatformCursor *QEglFSKmsEglDeviceIntegration::createCursor(QPlatformScreen *screen) const
+{
+ return separateScreens() ? new QEglFSCursor(screen) : nullptr;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
index af6b3f81ce..375c388548 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
@@ -65,6 +65,7 @@ public:
protected:
QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE;
+ QPlatformCursor *createCursor(QPlatformScreen *screen) const Q_DECL_OVERRIDE;
private:
bool setup_kms();
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
index da1b577801..b0deabe834 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
@@ -39,12 +39,32 @@
#include "qeglfskmsegldevicescreen.h"
#include "qeglfskmsegldevice.h"
+#include <QGuiApplication>
+
+QT_BEGIN_NAMESPACE
QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position)
: QEglFSKmsScreen(integration, device, output, position)
{
}
+QEglFSKmsEglDeviceScreen::~QEglFSKmsEglDeviceScreen()
+{
+ const int remainingScreenCount = qGuiApp->screens().count();
+ qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount);
+ if (!remainingScreenCount && !m_integration->separateScreens())
+ static_cast<QEglFSKmsEglDevice *>(device())->destroyGlobalCursor();
+}
+
+QPlatformCursor *QEglFSKmsEglDeviceScreen::cursor() const
+{
+ // The base class creates a cursor via integration->createCursor()
+ // in its ctor. With separateScreens just use that. Otherwise
+ // there's a virtual desktop and the device has a global cursor
+ // and the base class has no dedicated cursor at all.
+ return m_integration->separateScreens() ? QEglFSScreen::cursor() : static_cast<QEglFSKmsEglDevice *>(device())->globalCursor();
+}
+
void QEglFSKmsEglDeviceScreen::waitForFlip()
{
if (!output().mode_set) {
@@ -76,3 +96,5 @@ void QEglFSKmsEglDeviceScreen::waitForFlip()
}
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
index 0cd46e9f9d..7fceae4978 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
@@ -42,6 +42,8 @@
#include <qeglfskmsscreen.h>
+QT_BEGIN_NAMESPACE
+
class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen
{
public:
@@ -49,8 +51,13 @@ public:
QEglFSKmsDevice *device,
QEglFSKmsOutput output,
QPoint position);
+ ~QEglFSKmsEglDeviceScreen();
+
+ QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
void waitForFlip() Q_DECL_OVERRIDE;
};
+QT_END_NAMESPACE
+
#endif // QEGLFSKMSEGLDEVICESCREEN_H