Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qeglfskmsgbmdevice.cpp
Go to the documentation of this file.
1
// Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2
// Copyright (C) 2016 The Qt Company Ltd.
3
// Copyright (C) 2016 Pelagicore AG
4
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
// Qt-Security score:significant reason:default
6
7
#
include
"qeglfskmsgbmdevice_p.h"
8
#
include
"qeglfskmsgbmscreen_p.h"
9
10
#
include
<
private
/
qeglfsintegration_p
.
h
>
11
#
include
<
private
/
qeglfskmsintegration_p
.
h
>
12
13
#
include
<
QtCore
/
QLoggingCategory
>
14
#
include
<
QtCore
/
qtimer
.
h
>
15
#
include
<
QtCore
/
private
/
qcore_unix_p
.
h
>
16
17
#
define
ARRAY_LENGTH
(
a
)
(
sizeof
(
a
)
/
sizeof
(
a
)
[
0
]
)
18
19
QT_BEGIN_NAMESPACE
20
21
QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig,
const
QString &path)
22
: QEglFSKmsDevice(screenConfig, path)
23
, m_gbm_device(
nullptr
)
24
, m_globalCursor(
nullptr
)
25
{
26
}
27
28
bool
QEglFSKmsGbmDevice::open()
29
{
30
Q_ASSERT(fd() == -1);
31
Q_ASSERT(m_gbm_device ==
nullptr
);
32
33
int
fd = qt_safe_open(devicePath().toLocal8Bit().constData(), O_RDWR | O_CLOEXEC);
34
if
(fd == -1) {
35
qErrnoWarning(
"Could not open DRM device %s"
, qPrintable(devicePath()));
36
return
false
;
37
}
38
39
qCDebug(qLcEglfsKmsDebug) <<
"Creating GBM device for file descriptor"
<< fd
40
<<
"obtained from"
<< devicePath();
41
m_gbm_device = gbm_create_device(fd);
42
if
(!m_gbm_device) {
43
qErrnoWarning(
"Could not create GBM device"
);
44
qt_safe_close(fd);
45
fd = -1;
46
return
false
;
47
}
48
49
setFd(fd);
50
51
if
(usesEventReader()) {
52
qCDebug(qLcEglfsKmsDebug,
"Using dedicated drm event reading thread"
);
53
m_eventReader.create(
this
);
54
}
else
{
55
qCDebug(qLcEglfsKmsDebug,
"Not using dedicated drm event reading thread; "
56
"threaded multi-screen setups may experience problems"
);
57
}
58
59
return
true
;
60
}
61
62
void
QEglFSKmsGbmDevice::close()
63
{
64
// Note: screens are gone at this stage.
65
66
if
(usesEventReader())
67
m_eventReader.destroy();
68
69
if
(m_gbm_device) {
70
gbm_device_destroy(m_gbm_device);
71
m_gbm_device =
nullptr
;
72
}
73
74
if
(fd() != -1) {
75
qt_safe_close(fd());
76
setFd(-1);
77
}
78
}
79
80
void
*QEglFSKmsGbmDevice::nativeDisplay()
const
81
{
82
return
m_gbm_device;
83
}
84
85
gbm_device * QEglFSKmsGbmDevice::gbmDevice()
const
86
{
87
return
m_gbm_device;
88
}
89
90
QPlatformCursor *QEglFSKmsGbmDevice::globalCursor()
const
91
{
92
return
m_globalCursor;
93
}
94
95
// Cannot do this from close(), it may be too late.
96
// Call this from the last screen dtor instead.
97
void
QEglFSKmsGbmDevice::destroyGlobalCursor()
98
{
99
if
(m_globalCursor) {
100
qCDebug(qLcEglfsKmsDebug,
"Destroying global GBM mouse cursor"
);
101
delete
m_globalCursor;
102
m_globalCursor =
nullptr
;
103
}
104
}
105
106
void
QEglFSKmsGbmDevice::createGlobalCursor(QEglFSKmsGbmScreen *screen)
107
{
108
if
(!m_globalCursor && screenConfig()->hwCursor()) {
109
qCDebug(qLcEglfsKmsDebug,
"Creating new global GBM mouse cursor"
);
110
m_globalCursor =
new
QEglFSKmsGbmCursor(screen);
111
}
112
}
113
114
QPlatformScreen *QEglFSKmsGbmDevice::createScreen(
const
QKmsOutput &output)
115
{
116
QEglFSKmsGbmScreen *screen =
new
QEglFSKmsGbmScreen(
this
, output,
false
);
117
118
119
// On some platforms (e.g. rpi4), you'll get a kernel warning/error
120
// if the cursor is created 'at the same time' as the screen is created.
121
// (drmModeMoveCursor is the specific call that causes the issue)
122
// When this issue is triggered, the screen's connector is unusable until reboot
123
//
124
// Below is a work-around (without negative implications for other platforms).
125
//
126
// interval of 0 and QMetaObject::invokeMethod (w/o Qt::QueuedConnection)
127
// do no help / will still trigger issue
128
QTimer::singleShot(1, [screen,
this
](){
129
createGlobalCursor(screen);
130
});
131
132
return
screen;
133
}
134
135
QPlatformScreen *QEglFSKmsGbmDevice::createHeadlessScreen()
136
{
137
destroyGlobalCursor();
138
139
return
new
QEglFSKmsGbmScreen(
this
, QKmsOutput(),
true
);
140
}
141
142
void
QEglFSKmsGbmDevice::registerScreenCloning(QPlatformScreen *screen,
143
QPlatformScreen *screenThisScreenClones,
144
const
QList<QPlatformScreen *> &screensCloningThisScreen)
145
{
146
QEglFSKmsGbmScreen *gbmScreen =
static_cast
<QEglFSKmsGbmScreen *>(screen);
147
gbmScreen->initCloning(screenThisScreenClones, screensCloningThisScreen);
148
}
149
150
void
QEglFSKmsGbmDevice::registerScreen(QPlatformScreen *screen,
151
bool
isPrimary,
152
const
QPoint &virtualPos,
153
const
QList<QPlatformScreen *> &virtualSiblings)
154
{
155
QEglFSKmsDevice::registerScreen(screen, isPrimary, virtualPos, virtualSiblings);
156
if
(screenConfig()->hwCursor() && m_globalCursor)
157
m_globalCursor->reevaluateVisibilityForScreens();
158
}
159
160
void
QEglFSKmsGbmDevice::unregisterScreen(QPlatformScreen *screen)
161
{
162
// The global cursor holds a pointer to a QEglFSKmsGbmScreen.
163
// If that screen is being unregistered,
164
// this will recreate the global cursor with the first sibling screen.
165
if
(m_globalCursor && screen == m_globalCursor->screen()) {
166
qCDebug(qLcEglfsKmsDebug) <<
"Destroying global GBM mouse cursor due to unregistering"
167
<<
"it's screen - will probably be recreated right away"
;
168
delete
m_globalCursor;
169
m_globalCursor =
nullptr
;
170
171
QList<QPlatformScreen *> siblings = screen->virtualSiblings();
172
siblings.removeOne(screen);
173
if
(siblings.count() > 0) {
174
QEglFSKmsGbmScreen *kmsScreen =
static_cast
<QEglFSKmsGbmScreen *>(siblings.first());
175
m_globalCursor =
new
QEglFSKmsGbmCursor(kmsScreen);
176
qCDebug(qLcEglfsKmsDebug) <<
"Creating new global GBM mouse cursor on sibling screen"
;
177
}
else
{
178
qCWarning(qLcEglfsKmsDebug) <<
"Couldn't find a sibling to recreate"
179
<<
"the GBM mouse cursor - it might vanish"
;
180
}
181
}
182
183
QEglFSKmsDevice::unregisterScreen(screen);
184
}
185
186
bool
QEglFSKmsGbmDevice::usesEventReader()
const
187
{
188
static
const
bool
eventReaderThreadDisabled = qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_KMS_NO_EVENT_READER_THREAD"
);
189
return
!eventReaderThreadDisabled;
190
}
191
192
QT_END_NAMESPACE
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qtbase
src
plugins
platforms
eglfs
deviceintegration
eglfs_kms
qeglfskmsgbmdevice.cpp
Generated on
for Qt by
1.18.0