eglfs: Support dynamic mouse cursor show/hide with DRM HW cursor
Task-number: QTBUG-52743 Change-Id: I0bea1451dfe7b049c129b11716d593115e3d8374 Reviewed-by: Louai Al-Khanji <louai.al-khanji@qt.io>
This commit is contained in:
parent
edc4f02410
commit
c46f74d325
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
@ -41,6 +41,7 @@
|
||||
#include <QtCore/QJsonArray>
|
||||
#include <QtCore/QLoggingCategory>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
@ -62,13 +63,13 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen)
|
||||
, m_cursorSize(64, 64) // 64x64 is the old standard size, we now try to query the real size below
|
||||
, m_bo(Q_NULLPTR)
|
||||
, m_cursorImage(0, 0, 0, 0, 0, 0)
|
||||
, m_visible(true)
|
||||
, m_state(CursorPendingVisible)
|
||||
{
|
||||
QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
|
||||
if (!hideCursorVal.isEmpty())
|
||||
m_visible = hideCursorVal.toInt() == 0;
|
||||
if (!m_visible)
|
||||
if (!hideCursorVal.isEmpty() && hideCursorVal.toInt()) {
|
||||
m_state = CursorDisabled;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t width, height;
|
||||
if ((drmGetCap(m_screen->device()->fd(), DRM_CAP_CURSOR_WIDTH, &width) == 0)
|
||||
@ -85,6 +86,12 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen)
|
||||
initCursorAtlas();
|
||||
}
|
||||
|
||||
m_deviceListener = new QEglFSKmsCursorDeviceListener(this);
|
||||
connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged,
|
||||
m_deviceListener, &QEglFSKmsCursorDeviceListener::onDeviceListChanged);
|
||||
if (!m_deviceListener->hasMouse())
|
||||
m_state = CursorPendingHidden;
|
||||
|
||||
#ifndef QT_NO_CURSOR
|
||||
QCursor cursor(Qt::ArrowCursor);
|
||||
changeCursor(&cursor, 0);
|
||||
@ -94,6 +101,8 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen)
|
||||
|
||||
QEglFSKmsCursor::~QEglFSKmsCursor()
|
||||
{
|
||||
delete m_deviceListener;
|
||||
|
||||
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
|
||||
drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0);
|
||||
@ -106,6 +115,31 @@ QEglFSKmsCursor::~QEglFSKmsCursor()
|
||||
}
|
||||
}
|
||||
|
||||
void QEglFSKmsCursor::updateMouseStatus()
|
||||
{
|
||||
const bool wasVisible = m_state == CursorVisible;
|
||||
const bool visible = m_deviceListener->hasMouse();
|
||||
if (visible == wasVisible)
|
||||
return;
|
||||
|
||||
m_state = visible ? CursorPendingVisible : CursorPendingHidden;
|
||||
|
||||
#ifndef QT_NO_CURSOR
|
||||
changeCursor(nullptr, m_screen->topLevelAt(pos()));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool QEglFSKmsCursorDeviceListener::hasMouse() const
|
||||
{
|
||||
return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0;
|
||||
}
|
||||
|
||||
void QEglFSKmsCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type)
|
||||
{
|
||||
if (type == QInputDeviceManager::DeviceTypePointer)
|
||||
m_cursor->updateMouseStatus();
|
||||
}
|
||||
|
||||
void QEglFSKmsCursor::pointerEvent(const QMouseEvent &event)
|
||||
{
|
||||
setPos(event.screenPos().toPoint());
|
||||
@ -119,7 +153,15 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window)
|
||||
if (!m_bo)
|
||||
return;
|
||||
|
||||
if (!m_visible)
|
||||
if (m_state == CursorPendingHidden) {
|
||||
m_state = CursorHidden;
|
||||
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
|
||||
drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_state == CursorHidden || m_state == CursorDisabled)
|
||||
return;
|
||||
|
||||
const Qt::CursorShape newShape = windowCursor ? windowCursor->shape() : Qt::ArrowCursor;
|
||||
@ -159,6 +201,9 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window)
|
||||
|
||||
uint32_t handle = gbm_bo_get_handle(m_bo).u32;
|
||||
|
||||
if (m_state == CursorPendingVisible)
|
||||
m_state = CursorVisible;
|
||||
|
||||
Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) {
|
||||
QEglFSKmsScreen *kmsScreen = static_cast<QEglFSKmsScreen *>(screen);
|
||||
|
||||
@ -206,7 +251,7 @@ void QEglFSKmsCursor::initCursorAtlas()
|
||||
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_state = CursorDisabled;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -37,12 +37,29 @@
|
||||
#include <qpa/qplatformcursor.h>
|
||||
#include <QtCore/QList>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtGui/private/qinputdevicemanager_p.h>
|
||||
|
||||
#include <gbm.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QEglFSKmsScreen;
|
||||
class QEglFSKmsCursor;
|
||||
|
||||
class QEglFSKmsCursorDeviceListener : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QEglFSKmsCursorDeviceListener(QEglFSKmsCursor *cursor) : m_cursor(cursor) { }
|
||||
bool hasMouse() const;
|
||||
|
||||
public slots:
|
||||
void onDeviceListChanged(QInputDeviceManager::DeviceType type);
|
||||
|
||||
private:
|
||||
QEglFSKmsCursor *m_cursor;
|
||||
};
|
||||
|
||||
class QEglFSKmsCursor : public QPlatformCursor
|
||||
{
|
||||
@ -60,15 +77,26 @@ public:
|
||||
QPoint pos() const Q_DECL_OVERRIDE;
|
||||
void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
|
||||
|
||||
void updateMouseStatus();
|
||||
|
||||
private:
|
||||
void initCursorAtlas();
|
||||
|
||||
enum CursorState {
|
||||
CursorDisabled,
|
||||
CursorPendingHidden,
|
||||
CursorHidden,
|
||||
CursorPendingVisible,
|
||||
CursorVisible
|
||||
};
|
||||
|
||||
QEglFSKmsScreen *m_screen;
|
||||
QSize m_cursorSize;
|
||||
gbm_bo *m_bo;
|
||||
QPoint m_pos;
|
||||
QPlatformCursorImage m_cursorImage;
|
||||
bool m_visible;
|
||||
CursorState m_state;
|
||||
QEglFSKmsCursorDeviceListener *m_deviceListener;
|
||||
|
||||
// cursor atlas information
|
||||
struct CursorAtlas {
|
||||
|
Loading…
x
Reference in New Issue
Block a user