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.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
@ -87,8 +88,11 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen)
|
||||
|
||||
QEglFSKmsCursor::~QEglFSKmsCursor()
|
||||
{
|
||||
drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0, 0);
|
||||
drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0);
|
||||
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||
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);
|
||||
m_bo = Q_NULLPTR;
|
||||
@ -143,10 +147,15 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window)
|
||||
gbm_bo_write(m_bo, cursorImage.constBits(), cursorImage.byteCount());
|
||||
|
||||
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());
|
||||
if (status != 0)
|
||||
qWarning("Could not set cursor: %d", status);
|
||||
|
||||
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
|
||||
|
||||
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
|
||||
|
||||
@ -157,12 +166,17 @@ QPoint QEglFSKmsCursor::pos() const
|
||||
|
||||
void QEglFSKmsCursor::setPos(const QPoint &pos)
|
||||
{
|
||||
QPoint adjustedPos = pos - m_cursorImage.hotspot();
|
||||
int ret = drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, adjustedPos.x(), adjustedPos.y());
|
||||
if (ret == 0) {
|
||||
m_pos = pos;
|
||||
} else {
|
||||
qWarning("Failed to move cursor: %d", ret);
|
||||
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
|
||||
QPoint origin = kmsScreen->geometry().topLeft();
|
||||
QPoint localPos = pos - origin;
|
||||
QPoint adjustedPos = localPos - m_cursorImage.hotspot();
|
||||
|
||||
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));
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0, 0);
|
||||
drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0);
|
||||
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
@ -308,6 +309,7 @@ QEglFSKmsDevice::QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QStrin
|
||||
, m_gbm_device(Q_NULLPTR)
|
||||
, m_crtc_allocator(0)
|
||||
, m_connector_allocator(0)
|
||||
, m_globalCursor(Q_NULLPTR)
|
||||
{
|
||||
}
|
||||
|
||||
@ -347,6 +349,10 @@ void QEglFSKmsDevice::close()
|
||||
qt_safe_close(m_dri_fd);
|
||||
m_dri_fd = -1;
|
||||
}
|
||||
|
||||
if (m_globalCursor)
|
||||
m_globalCursor->deleteLater();
|
||||
m_globalCursor = Q_NULLPTR;
|
||||
}
|
||||
|
||||
void QEglFSKmsDevice::createScreens()
|
||||
@ -357,6 +363,8 @@ void QEglFSKmsDevice::createScreens()
|
||||
return;
|
||||
}
|
||||
|
||||
QEglFSKmsScreen *primaryScreen = Q_NULLPTR;
|
||||
QList<QPlatformScreen *> siblings;
|
||||
QPoint pos(0, 0);
|
||||
QEglFSIntegration *integration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
||||
|
||||
@ -369,12 +377,24 @@ void QEglFSKmsDevice::createScreens()
|
||||
if (screen) {
|
||||
integration->addScreen(screen);
|
||||
pos.rx() += screen->geometry().width();
|
||||
siblings << screen;
|
||||
|
||||
if (!primaryScreen)
|
||||
primaryScreen = screen;
|
||||
}
|
||||
|
||||
drmModeFreeConnector(connector);
|
||||
}
|
||||
|
||||
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
|
||||
@ -387,6 +407,11 @@ int QEglFSKmsDevice::fd() const
|
||||
return m_dri_fd;
|
||||
}
|
||||
|
||||
QPlatformCursor *QEglFSKmsDevice::globalCursor() const
|
||||
{
|
||||
return m_globalCursor;
|
||||
}
|
||||
|
||||
void QEglFSKmsDevice::handleDrmEvent()
|
||||
{
|
||||
drmEventContext drmEvent = {
|
||||
|
@ -1,5 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
@ -34,6 +35,7 @@
|
||||
#ifndef QEGLFSKMSDEVICE_H
|
||||
#define QEGLFSKMSDEVICE_H
|
||||
|
||||
#include "qeglfskmscursor.h"
|
||||
#include "qeglfskmsintegration.h"
|
||||
|
||||
#include <xf86drm.h>
|
||||
@ -57,6 +59,8 @@ public:
|
||||
gbm_device *device() const;
|
||||
int fd() const;
|
||||
|
||||
QPlatformCursor *globalCursor() const;
|
||||
|
||||
void handleDrmEvent();
|
||||
|
||||
private:
|
||||
@ -70,6 +74,8 @@ private:
|
||||
quint32 m_crtc_allocator;
|
||||
quint32 m_connector_allocator;
|
||||
|
||||
QEglFSKmsCursor *m_globalCursor;
|
||||
|
||||
int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector);
|
||||
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.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
@ -60,6 +61,7 @@ QEglFSKmsIntegration::QEglFSKmsIntegration()
|
||||
: m_device(Q_NULLPTR)
|
||||
, m_hwCursor(true)
|
||||
, m_pbuffers(false)
|
||||
, m_separateScreens(false)
|
||||
{}
|
||||
|
||||
void QEglFSKmsIntegration::platformInit()
|
||||
@ -203,6 +205,11 @@ bool QEglFSKmsIntegration::hwCursor() const
|
||||
return m_hwCursor;
|
||||
}
|
||||
|
||||
bool QEglFSKmsIntegration::separateScreens() const
|
||||
{
|
||||
return m_separateScreens;
|
||||
}
|
||||
|
||||
QMap<QString, QVariantMap> QEglFSKmsIntegration::outputSettings() const
|
||||
{
|
||||
return m_outputSettings;
|
||||
@ -235,6 +242,7 @@ void QEglFSKmsIntegration::loadConfig()
|
||||
m_hwCursor = object.value(QStringLiteral("hwcursor")).toBool(m_hwCursor);
|
||||
m_pbuffers = object.value(QStringLiteral("pbuffers")).toBool(m_pbuffers);
|
||||
m_devicePath = object.value(QStringLiteral("device")).toString();
|
||||
m_separateScreens = object.value(QStringLiteral("separateScreens")).toBool(m_separateScreens);
|
||||
|
||||
const QJsonArray outputs = object.value(QStringLiteral("outputs")).toArray();
|
||||
for (int i = 0; i < outputs.size(); i++) {
|
||||
@ -254,6 +262,7 @@ void QEglFSKmsIntegration::loadConfig()
|
||||
qCDebug(qLcEglfsKmsDebug) << "Configuration:\n"
|
||||
<< "\thwcursor:" << m_hwCursor << "\n"
|
||||
<< "\tpbuffers:" << m_pbuffers << "\n"
|
||||
<< "\tseparateScreens:" << m_separateScreens << "\n"
|
||||
<< "\toutputs:" << m_outputSettings;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
@ -65,6 +66,7 @@ public:
|
||||
bool supportsPBuffers() const Q_DECL_OVERRIDE;
|
||||
|
||||
bool hwCursor() const;
|
||||
bool separateScreens() const;
|
||||
QMap<QString, QVariantMap> outputSettings() const;
|
||||
|
||||
private:
|
||||
@ -73,6 +75,7 @@ private:
|
||||
QEglFSKmsDevice *m_device;
|
||||
bool m_hwCursor;
|
||||
bool m_pbuffers;
|
||||
bool m_separateScreens;
|
||||
QString m_devicePath;
|
||||
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.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
@ -120,6 +121,7 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration,
|
||||
, m_cursor(Q_NULLPTR)
|
||||
, m_interruptHandler(new QEglFSKmsInterruptHandler(this))
|
||||
{
|
||||
m_siblings << this;
|
||||
}
|
||||
|
||||
QEglFSKmsScreen::~QEglFSKmsScreen()
|
||||
@ -185,6 +187,9 @@ QString QEglFSKmsScreen::name() const
|
||||
QPlatformCursor *QEglFSKmsScreen::cursor() const
|
||||
{
|
||||
if (m_integration->hwCursor()) {
|
||||
if (!m_integration->separateScreens())
|
||||
return m_device->globalCursor();
|
||||
|
||||
if (m_cursor.isNull()) {
|
||||
QEglFSKmsScreen *that = const_cast<QEglFSKmsScreen *>(this);
|
||||
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.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
@ -85,6 +86,10 @@ public:
|
||||
|
||||
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; }
|
||||
|
||||
gbm_surface *surface() const { return m_gbm_surface; }
|
||||
@ -110,6 +115,8 @@ private:
|
||||
QPoint m_pos;
|
||||
QScopedPointer<QEglFSKmsCursor> m_cursor;
|
||||
|
||||
QList<QPlatformScreen *> m_siblings;
|
||||
|
||||
struct FrameBuffer {
|
||||
FrameBuffer() : fb(0) {}
|
||||
uint32_t fb;
|
||||
|
Loading…
Reference in New Issue
Block a user