eglfs_kms: Virtual desktop
Now we can choose to use separate screens or virtual desktop. With virtual desktop the geometry of all screens is taken into account so that the input plugin do not clamp global pointer coordinates to the first screen anymore, we also create only one hardware cursor that can now freely move on all the screens. Virtual desktop is enabled by default, but the old default behavior can be restored by setting separateScreens to true. Change-Id: I78dbf9e8d3dd44f68d33350dc8fc3727bf8a26fe Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
This commit is contained in:
parent
f7047d52da
commit
11512d6a2c
@ -1,5 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
|
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
** Contact: http://www.qt.io/licensing/
|
** Contact: http://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -87,8 +88,11 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen)
|
|||||||
|
|
||||||
QEglFSKmsCursor::~QEglFSKmsCursor()
|
QEglFSKmsCursor::~QEglFSKmsCursor()
|
||||||
{
|
{
|
||||||
drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0, 0);
|
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||||
drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0);
|
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
|
||||||
|
drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0);
|
||||||
|
drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
gbm_bo_destroy(m_bo);
|
gbm_bo_destroy(m_bo);
|
||||||
m_bo = Q_NULLPTR;
|
m_bo = Q_NULLPTR;
|
||||||
@ -143,10 +147,15 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window)
|
|||||||
gbm_bo_write(m_bo, cursorImage.constBits(), cursorImage.byteCount());
|
gbm_bo_write(m_bo, cursorImage.constBits(), cursorImage.byteCount());
|
||||||
|
|
||||||
uint32_t handle = gbm_bo_get_handle(m_bo).u32;
|
uint32_t handle = gbm_bo_get_handle(m_bo).u32;
|
||||||
int status = drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, handle,
|
|
||||||
m_cursorSize.width(), m_cursorSize.height());
|
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||||
if (status != 0)
|
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
|
||||||
qWarning("Could not set cursor: %d", status);
|
|
||||||
|
int status = drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, handle,
|
||||||
|
m_cursorSize.width(), m_cursorSize.height());
|
||||||
|
if (status != 0)
|
||||||
|
qWarning("Could not set cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // QT_NO_CURSOR
|
#endif // QT_NO_CURSOR
|
||||||
|
|
||||||
@ -157,12 +166,17 @@ QPoint QEglFSKmsCursor::pos() const
|
|||||||
|
|
||||||
void QEglFSKmsCursor::setPos(const QPoint &pos)
|
void QEglFSKmsCursor::setPos(const QPoint &pos)
|
||||||
{
|
{
|
||||||
QPoint adjustedPos = pos - m_cursorImage.hotspot();
|
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||||
int ret = drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, adjustedPos.x(), adjustedPos.y());
|
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
|
||||||
if (ret == 0) {
|
QPoint origin = kmsScreen->geometry().topLeft();
|
||||||
m_pos = pos;
|
QPoint localPos = pos - origin;
|
||||||
} else {
|
QPoint adjustedPos = localPos - m_cursorImage.hotspot();
|
||||||
qWarning("Failed to move cursor: %d", ret);
|
|
||||||
|
int ret = drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, adjustedPos.x(), adjustedPos.y());
|
||||||
|
if (ret == 0)
|
||||||
|
m_pos = pos;
|
||||||
|
else
|
||||||
|
qWarning("Failed to move cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,8 +190,11 @@ void QEglFSKmsCursor::initCursorAtlas()
|
|||||||
|
|
||||||
QFile file(QString::fromUtf8(json));
|
QFile file(QString::fromUtf8(json));
|
||||||
if (!file.open(QFile::ReadOnly)) {
|
if (!file.open(QFile::ReadOnly)) {
|
||||||
drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0, 0);
|
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||||
drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0);
|
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
|
||||||
|
drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0);
|
||||||
|
drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0);
|
||||||
|
}
|
||||||
m_visible = false;
|
m_visible = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
|
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
** Contact: http://www.qt.io/licensing/
|
** Contact: http://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -308,6 +309,7 @@ QEglFSKmsDevice::QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QStrin
|
|||||||
, m_gbm_device(Q_NULLPTR)
|
, m_gbm_device(Q_NULLPTR)
|
||||||
, m_crtc_allocator(0)
|
, m_crtc_allocator(0)
|
||||||
, m_connector_allocator(0)
|
, m_connector_allocator(0)
|
||||||
|
, m_globalCursor(Q_NULLPTR)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,6 +349,10 @@ void QEglFSKmsDevice::close()
|
|||||||
qt_safe_close(m_dri_fd);
|
qt_safe_close(m_dri_fd);
|
||||||
m_dri_fd = -1;
|
m_dri_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_globalCursor)
|
||||||
|
m_globalCursor->deleteLater();
|
||||||
|
m_globalCursor = Q_NULLPTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QEglFSKmsDevice::createScreens()
|
void QEglFSKmsDevice::createScreens()
|
||||||
@ -357,6 +363,8 @@ void QEglFSKmsDevice::createScreens()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QEglFSKmsScreen *primaryScreen = Q_NULLPTR;
|
||||||
|
QList<QPlatformScreen *> siblings;
|
||||||
QPoint pos(0, 0);
|
QPoint pos(0, 0);
|
||||||
QEglFSIntegration *integration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
QEglFSIntegration *integration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
||||||
|
|
||||||
@ -369,12 +377,24 @@ void QEglFSKmsDevice::createScreens()
|
|||||||
if (screen) {
|
if (screen) {
|
||||||
integration->addScreen(screen);
|
integration->addScreen(screen);
|
||||||
pos.rx() += screen->geometry().width();
|
pos.rx() += screen->geometry().width();
|
||||||
|
siblings << screen;
|
||||||
|
|
||||||
|
if (!primaryScreen)
|
||||||
|
primaryScreen = screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
drmModeFreeConnector(connector);
|
drmModeFreeConnector(connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
drmModeFreeResources(resources);
|
drmModeFreeResources(resources);
|
||||||
|
|
||||||
|
if (!m_integration->separateScreens()) {
|
||||||
|
Q_FOREACH (QPlatformScreen *screen, siblings)
|
||||||
|
static_cast<QEglFSKmsScreen *>(screen)->setVirtualSiblings(siblings);
|
||||||
|
|
||||||
|
if (primaryScreen)
|
||||||
|
m_globalCursor = new QEglFSKmsCursor(primaryScreen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gbm_device *QEglFSKmsDevice::device() const
|
gbm_device *QEglFSKmsDevice::device() const
|
||||||
@ -387,6 +407,11 @@ int QEglFSKmsDevice::fd() const
|
|||||||
return m_dri_fd;
|
return m_dri_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPlatformCursor *QEglFSKmsDevice::globalCursor() const
|
||||||
|
{
|
||||||
|
return m_globalCursor;
|
||||||
|
}
|
||||||
|
|
||||||
void QEglFSKmsDevice::handleDrmEvent()
|
void QEglFSKmsDevice::handleDrmEvent()
|
||||||
{
|
{
|
||||||
drmEventContext drmEvent = {
|
drmEventContext drmEvent = {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
|
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
** Contact: http://www.qt.io/licensing/
|
** Contact: http://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -34,6 +35,7 @@
|
|||||||
#ifndef QEGLFSKMSDEVICE_H
|
#ifndef QEGLFSKMSDEVICE_H
|
||||||
#define QEGLFSKMSDEVICE_H
|
#define QEGLFSKMSDEVICE_H
|
||||||
|
|
||||||
|
#include "qeglfskmscursor.h"
|
||||||
#include "qeglfskmsintegration.h"
|
#include "qeglfskmsintegration.h"
|
||||||
|
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
@ -57,6 +59,8 @@ public:
|
|||||||
gbm_device *device() const;
|
gbm_device *device() const;
|
||||||
int fd() const;
|
int fd() const;
|
||||||
|
|
||||||
|
QPlatformCursor *globalCursor() const;
|
||||||
|
|
||||||
void handleDrmEvent();
|
void handleDrmEvent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -70,6 +74,8 @@ private:
|
|||||||
quint32 m_crtc_allocator;
|
quint32 m_crtc_allocator;
|
||||||
quint32 m_connector_allocator;
|
quint32 m_connector_allocator;
|
||||||
|
|
||||||
|
QEglFSKmsCursor *m_globalCursor;
|
||||||
|
|
||||||
int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector);
|
int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector);
|
||||||
QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos);
|
QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos);
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
|
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
** Contact: http://www.qt.io/licensing/
|
** Contact: http://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -60,6 +61,7 @@ QEglFSKmsIntegration::QEglFSKmsIntegration()
|
|||||||
: m_device(Q_NULLPTR)
|
: m_device(Q_NULLPTR)
|
||||||
, m_hwCursor(true)
|
, m_hwCursor(true)
|
||||||
, m_pbuffers(false)
|
, m_pbuffers(false)
|
||||||
|
, m_separateScreens(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void QEglFSKmsIntegration::platformInit()
|
void QEglFSKmsIntegration::platformInit()
|
||||||
@ -203,6 +205,11 @@ bool QEglFSKmsIntegration::hwCursor() const
|
|||||||
return m_hwCursor;
|
return m_hwCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QEglFSKmsIntegration::separateScreens() const
|
||||||
|
{
|
||||||
|
return m_separateScreens;
|
||||||
|
}
|
||||||
|
|
||||||
QMap<QString, QVariantMap> QEglFSKmsIntegration::outputSettings() const
|
QMap<QString, QVariantMap> QEglFSKmsIntegration::outputSettings() const
|
||||||
{
|
{
|
||||||
return m_outputSettings;
|
return m_outputSettings;
|
||||||
@ -235,6 +242,7 @@ void QEglFSKmsIntegration::loadConfig()
|
|||||||
m_hwCursor = object.value(QStringLiteral("hwcursor")).toBool(m_hwCursor);
|
m_hwCursor = object.value(QStringLiteral("hwcursor")).toBool(m_hwCursor);
|
||||||
m_pbuffers = object.value(QStringLiteral("pbuffers")).toBool(m_pbuffers);
|
m_pbuffers = object.value(QStringLiteral("pbuffers")).toBool(m_pbuffers);
|
||||||
m_devicePath = object.value(QStringLiteral("device")).toString();
|
m_devicePath = object.value(QStringLiteral("device")).toString();
|
||||||
|
m_separateScreens = object.value(QStringLiteral("separateScreens")).toBool(m_separateScreens);
|
||||||
|
|
||||||
const QJsonArray outputs = object.value(QStringLiteral("outputs")).toArray();
|
const QJsonArray outputs = object.value(QStringLiteral("outputs")).toArray();
|
||||||
for (int i = 0; i < outputs.size(); i++) {
|
for (int i = 0; i < outputs.size(); i++) {
|
||||||
@ -254,6 +262,7 @@ void QEglFSKmsIntegration::loadConfig()
|
|||||||
qCDebug(qLcEglfsKmsDebug) << "Configuration:\n"
|
qCDebug(qLcEglfsKmsDebug) << "Configuration:\n"
|
||||||
<< "\thwcursor:" << m_hwCursor << "\n"
|
<< "\thwcursor:" << m_hwCursor << "\n"
|
||||||
<< "\tpbuffers:" << m_pbuffers << "\n"
|
<< "\tpbuffers:" << m_pbuffers << "\n"
|
||||||
|
<< "\tseparateScreens:" << m_separateScreens << "\n"
|
||||||
<< "\toutputs:" << m_outputSettings;
|
<< "\toutputs:" << m_outputSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
|
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
** Contact: http://www.qt.io/licensing/
|
** Contact: http://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -65,6 +66,7 @@ public:
|
|||||||
bool supportsPBuffers() const Q_DECL_OVERRIDE;
|
bool supportsPBuffers() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
bool hwCursor() const;
|
bool hwCursor() const;
|
||||||
|
bool separateScreens() const;
|
||||||
QMap<QString, QVariantMap> outputSettings() const;
|
QMap<QString, QVariantMap> outputSettings() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -73,6 +75,7 @@ private:
|
|||||||
QEglFSKmsDevice *m_device;
|
QEglFSKmsDevice *m_device;
|
||||||
bool m_hwCursor;
|
bool m_hwCursor;
|
||||||
bool m_pbuffers;
|
bool m_pbuffers;
|
||||||
|
bool m_separateScreens;
|
||||||
QString m_devicePath;
|
QString m_devicePath;
|
||||||
QMap<QString, QVariantMap> m_outputSettings;
|
QMap<QString, QVariantMap> m_outputSettings;
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
|
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
** Contact: http://www.qt.io/licensing/
|
** Contact: http://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -120,6 +121,7 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration,
|
|||||||
, m_cursor(Q_NULLPTR)
|
, m_cursor(Q_NULLPTR)
|
||||||
, m_interruptHandler(new QEglFSKmsInterruptHandler(this))
|
, m_interruptHandler(new QEglFSKmsInterruptHandler(this))
|
||||||
{
|
{
|
||||||
|
m_siblings << this;
|
||||||
}
|
}
|
||||||
|
|
||||||
QEglFSKmsScreen::~QEglFSKmsScreen()
|
QEglFSKmsScreen::~QEglFSKmsScreen()
|
||||||
@ -185,6 +187,9 @@ QString QEglFSKmsScreen::name() const
|
|||||||
QPlatformCursor *QEglFSKmsScreen::cursor() const
|
QPlatformCursor *QEglFSKmsScreen::cursor() const
|
||||||
{
|
{
|
||||||
if (m_integration->hwCursor()) {
|
if (m_integration->hwCursor()) {
|
||||||
|
if (!m_integration->separateScreens())
|
||||||
|
return m_device->globalCursor();
|
||||||
|
|
||||||
if (m_cursor.isNull()) {
|
if (m_cursor.isNull()) {
|
||||||
QEglFSKmsScreen *that = const_cast<QEglFSKmsScreen *>(this);
|
QEglFSKmsScreen *that = const_cast<QEglFSKmsScreen *>(this);
|
||||||
that->m_cursor.reset(new QEglFSKmsCursor(that));
|
that->m_cursor.reset(new QEglFSKmsCursor(that));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
|
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
** Contact: http://www.qt.io/licensing/
|
** Contact: http://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -85,6 +86,10 @@ public:
|
|||||||
|
|
||||||
qreal refreshRate() const Q_DECL_OVERRIDE;
|
qreal refreshRate() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; }
|
||||||
|
void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; }
|
||||||
|
|
||||||
|
QEglFSKmsIntegration *integration() const { return m_integration; }
|
||||||
QEglFSKmsDevice *device() const { return m_device; }
|
QEglFSKmsDevice *device() const { return m_device; }
|
||||||
|
|
||||||
gbm_surface *surface() const { return m_gbm_surface; }
|
gbm_surface *surface() const { return m_gbm_surface; }
|
||||||
@ -110,6 +115,8 @@ private:
|
|||||||
QPoint m_pos;
|
QPoint m_pos;
|
||||||
QScopedPointer<QEglFSKmsCursor> m_cursor;
|
QScopedPointer<QEglFSKmsCursor> m_cursor;
|
||||||
|
|
||||||
|
QList<QPlatformScreen *> m_siblings;
|
||||||
|
|
||||||
struct FrameBuffer {
|
struct FrameBuffer {
|
||||||
FrameBuffer() : fb(0) {}
|
FrameBuffer() : fb(0) {}
|
||||||
uint32_t fb;
|
uint32_t fb;
|
||||||
|
Loading…
Reference in New Issue
Block a user