Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qeglfsintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtCore/qtextstream.h>
5#include <QtGui/private/qguiapplication_p.h>
6
7#include <qpa/qplatformwindow.h>
8#include <QtGui/QSurfaceFormat>
9#include <QtGui/QScreen>
10#ifndef QT_NO_OPENGL
11# include <QtGui/QOpenGLContext>
12# include <QtGui/QOffscreenSurface>
13#endif
14#include <QtGui/QWindow>
15#include <QtCore/QLoggingCategory>
16#include <qpa/qwindowsysteminterface.h>
17#include <qpa/qplatforminputcontextfactory_p.h>
18
19#include "qeglfsintegration_p.h"
20#include "qeglfswindow_p.h"
21#include "qeglfshooks_p.h"
22#ifndef QT_NO_OPENGL
23# include "qeglfscontext_p.h"
24# include "qeglfscursor_p.h"
25#endif
27
28#include <QtGui/private/qeglconvenience_p.h>
29#ifndef QT_NO_OPENGL
30# include <QtGui/private/qeglplatformcontext_p.h>
31# include <QtGui/private/qeglpbuffer_p.h>
32#endif
33
34#include <QtGui/private/qgenericunixfontdatabase_p.h>
35#include <QtGui/private/qgenericunixservices_p.h>
36#include <QtGui/private/qgenericunixthemes_p.h>
37#include <QtGui/private/qgenericunixeventdispatcher_p.h>
38#include <QtFbSupport/private/qfbvthandler_p.h>
39#ifndef QT_NO_OPENGL
40# include <QtOpenGL/private/qopenglcompositorbackingstore_p.h>
41#endif
42
43#if QT_CONFIG(libinput)
44#include <QtInputSupport/private/qlibinputhandler_p.h>
45#endif
46
47#if QT_CONFIG(evdev)
48#include <QtInputSupport/private/qevdevmousemanager_p.h>
49#include <QtInputSupport/private/qevdevkeyboardmanager_p.h>
50#include <QtInputSupport/private/qevdevtouchmanager_p.h>
51#endif
52
53#if QT_CONFIG(tslib)
54#include <QtInputSupport/private/qtslib_p.h>
55#endif
56
57#if QT_CONFIG(integrityhid)
58#include <QtInputSupport/qintegrityhidmanager.h>
59#endif
60
61static void initResources()
62{
63#ifndef QT_NO_CURSOR
65#endif
66}
67
69
70using namespace Qt::StringLiterals;
71
73 : m_kbdMgr(nullptr),
74 m_display(EGL_NO_DISPLAY),
75 m_inputContext(nullptr),
76 m_fontDb(new QGenericUnixFontDatabase),
77 m_services(new QGenericUnixServices),
78 m_disableInputHandlers(false)
79{
80 m_disableInputHandlers = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISABLE_INPUT");
81
83}
84
86{
88
89 m_display = qt_egl_device_integration()->createDisplay(nativeDisplay());
90 if (Q_UNLIKELY(m_display == EGL_NO_DISPLAY))
91 qFatal("Could not open egl display");
92
93 EGLint major, minor;
94 if (Q_UNLIKELY(!eglInitialize(m_display, &major, &minor)))
95 qFatal("Could not initialize egl display");
96
97 m_inputContext = QPlatformInputContextFactory::create();
98
99 m_vtHandler.reset(new QFbVtHandler);
100
101 if (qt_egl_device_integration()->usesDefaultScreen())
103 else
105
106 // Input code may rely on the screens, so do it only after the screen init.
107 if (!m_disableInputHandlers)
109}
110
112{
113 foreach (QWindow *w, qGuiApp->topLevelWindows())
114 w->destroy();
115
117
118 if (m_display != EGL_NO_DISPLAY)
119 eglTerminate(m_display);
120
122}
123
125{
126 return createUnixEventDispatcher();
127}
128
130{
131 return m_services.data();
132}
133
135{
136 return m_fontDb.data();
137}
138
140{
142}
143
145{
146#ifndef QT_NO_OPENGL
148 if (!window->handle())
149 window->create();
150 static_cast<QEglFSWindow *>(window->handle())->setBackingStore(bs);
151 return bs;
152#else
154 return nullptr;
155#endif
156}
157
159{
162 w->create();
163
164 const auto showWithoutActivating = window->property("_q_showWithoutActivating");
165 if (showWithoutActivating.isValid() && showWithoutActivating.toBool())
166 return w;
167
168 // Activate only the window for the primary screen to make input work
169 if (window->type() != Qt::ToolTip && window->screen() == QGuiApplication::primaryScreen())
170 w->requestActivateWindow();
171
172 return w;
173}
174
175#ifndef QT_NO_OPENGL
177{
178 EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display();
179 QPlatformOpenGLContext *share = context->shareHandle();
180
183 EGLConfig config = QEglFSDeviceIntegration::chooseConfig(dpy, adjustedFormat);
184 ctx = new QEglFSContext(adjustedFormat, share, dpy, &config);
185
186 return ctx;
187}
188
190{
191 return QEGLPlatformContext::createFrom<QEglFSContext>(context, contextDisplay, display(), shareContext);
192}
193
195{
196 EGLDisplay dpy = surface->screen() ? static_cast<QEglFSScreen *>(surface->screen()->handle())->display() : display();
198 if (qt_egl_device_integration()->supportsPBuffers()) {
199 QEGLPlatformContext::Flags flags;
200 if (!qt_egl_device_integration()->supportsSurfacelessContexts())
202 return new QEGLPbuffer(dpy, fmt, surface, flags);
203 } else {
204 return new QEglFSOffscreenWindow(dpy, fmt, surface);
205 }
206 // Never return null. Multiple QWindows are not supported by this plugin.
207}
208#endif // QT_NO_OPENGL
209
211{
212 // We assume that devices will have more and not less capabilities
214 return true;
215
216 switch (cap) {
217 case ThreadedPixmaps: return true;
218#ifndef QT_NO_OPENGL
219 case OpenGL: return true;
220 case ThreadedOpenGL: return true;
221 case RasterGLSurface: return true;
222#else
223 case OpenGL: return false;
224 case ThreadedOpenGL: return false;
225 case RasterGLSurface: return false;
226#endif
227 case WindowManagement: return false;
228 case OpenGLOnRasterSurface: return true;
230 }
231}
232
234{
235 return const_cast<QEglFSIntegration *>(this);
236}
237
249
250static int resourceType(const QByteArray &key)
251{
252 static const QByteArray names[] = { // match ResourceType
253 QByteArrayLiteral("egldisplay"),
254 QByteArrayLiteral("eglwindow"),
255 QByteArrayLiteral("eglcontext"),
256 QByteArrayLiteral("eglconfig"),
257 QByteArrayLiteral("nativedisplay"),
258 QByteArrayLiteral("display"),
259 QByteArrayLiteral("server_wl_display"),
260 QByteArrayLiteral("eglsurface"),
261 QByteArrayLiteral("vksurface")
262 };
263 const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
264 const QByteArray *result = std::find(names, end, key);
265 if (result == end)
266 result = std::find(names, end, key.toLower());
267 return int(result - names);
268}
269
271{
272 void *result = nullptr;
273
274 switch (resourceType(resource)) {
275 case EglDisplay:
276 result = display();
277 break;
278 case NativeDisplay:
279 result = reinterpret_cast<void*>(nativeDisplay());
280 break;
281 case WaylandDisplay:
283 break;
284 default:
286 break;
287 }
288
289 return result;
290}
291
293{
294 void *result = nullptr;
295
296 switch (resourceType(resource)) {
297 case XlibDisplay:
298 // Play nice when using the x11 hooks: Be compatible with xcb that allows querying
299 // the X Display pointer, which is nothing but our native display.
300 result = reinterpret_cast<void*>(nativeDisplay());
301 break;
302 default:
304 break;
305 }
306
307 return result;
308}
309
311{
312 void *result = nullptr;
313
314 switch (resourceType(resource)) {
315 case EglDisplay:
316 if (window && window->handle())
317 result = static_cast<QEglFSScreen *>(window->handle()->screen())->display();
318 else
319 result = display();
320 break;
321 case EglWindow:
322 if (window && window->handle())
323 result = reinterpret_cast<void*>(static_cast<QEglFSWindow *>(window->handle())->eglWindow());
324 break;
325 case EglSurface:
326 if (window && window->handle())
327 result = reinterpret_cast<void*>(static_cast<QEglFSWindow *>(window->handle())->surface());
328 break;
329 default:
330 break;
331 }
332
333 return result;
334}
335
336#ifndef QT_NO_OPENGL
338{
339 void *result = nullptr;
340
341 switch (resourceType(resource)) {
342 case EglContext:
343 if (context->handle())
344 result = static_cast<QEglFSContext *>(context->handle())->eglContext();
345 break;
346 case EglConfig:
347 if (context->handle())
348 result = static_cast<QEglFSContext *>(context->handle())->eglConfig();
349 break;
350 case EglDisplay:
351 if (context->handle())
352 result = static_cast<QEglFSContext *>(context->handle())->eglDisplay();
353 break;
354 default:
355 break;
356 }
357
358 return result;
359}
360
362{
364
365 QEglFSContext *handle = static_cast<QEglFSContext *>(context->handle());
366 if (!handle)
367 return nullptr;
368
369 return handle->eglContext();
370}
371#endif
372
374{
375#ifndef QT_NO_OPENGL
376 if (resource.compare("get_egl_context", Qt::CaseInsensitive) == 0)
378#else
379 Q_UNUSED(resource);
380#endif
381 return nullptr;
382}
383
384QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function) const
385{
387}
388
389#if QT_CONFIG(evdev)
390void QEglFSIntegration::loadKeymap(const QString &filename)
391{
392 if (m_kbdMgr)
393 m_kbdMgr->loadKeymap(filename);
394 else
395 qWarning("QEglFSIntegration: Cannot load keymap, no keyboard handler found");
396}
397
398void QEglFSIntegration::switchLang()
399{
400 if (m_kbdMgr)
402 else
403 qWarning("QEglFSIntegration: Cannot switch language, no keyboard handler found");
404}
405#endif
406
408{
409#if QT_CONFIG(libinput)
410 if (!qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT")) {
411 new QLibInputHandler("libinput"_L1, QString());
412 return;
413 }
414#endif
415
416#if QT_CONFIG(tslib)
417 bool useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB");
418 if (useTslib)
419 new QTsLibMouseHandler("TsLib"_L1, QString() /* spec */);
420#endif
421
422#if QT_CONFIG(evdev)
423 m_kbdMgr = new QEvdevKeyboardManager("EvdevKeyboard"_L1, QString() /* spec */, this);
424 new QEvdevMouseManager("EvdevMouse"_L1, QString() /* spec */, this);
425#if QT_CONFIG(tslib)
426 if (!useTslib)
427#endif
428 new QEvdevTouchManager("EvdevTouch"_L1, QString() /* spec */, this);
429#endif
430
431#if QT_CONFIG(integrityhid)
432 new QIntegrityHIDManager("HID", "", this);
433#endif
434}
435
436EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const
437{
439}
440
\inmodule QtCore
Definition qbytearray.h:57
int compare(QByteArrayView a, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qbytearray.h:587
A pbuffer-based implementation of QPlatformOffscreenSurface for EGL.
EGLContext eglContext() const
virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const
virtual void * nativeResourceForIntegration(const QByteArray &name)
static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
virtual QFunctionPointer platformFunction(const QByteArray &function) const
virtual QEglFSWindow * createWindow(QWindow *window) const
virtual EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay)
virtual EGLNativeDisplayType platformDisplay() const
virtual void * nativeResourceForScreen(const QByteArray &resource, QScreen *screen)
bool hasCapability(QPlatformIntegration::Capability cap) const override
QAbstractEventDispatcher * createEventDispatcher() const override
Factory function for the GUI event dispatcher.
QPlatformTheme * createPlatformTheme(const QString &name) const override
QFunctionPointer platformFunction(const QByteArray &function) const override
void initialize() override
Performs initialization steps that depend on having an event dispatcher available.
void * nativeResourceForWindow(const QByteArray &resource, QWindow *window) override
virtual void createInputHandlers()
void * nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override
void * nativeResourceForIntegration(const QByteArray &resource) override
QPlatformNativeInterface * nativeInterface() const override
QPlatformOffscreenSurface * createPlatformOffscreenSurface(QOffscreenSurface *surface) const override
Factory function for QOffscreenSurface.
QOpenGLContext * createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const override
QPlatformFontDatabase * fontDatabase() const override
Accessor for the platform integration's fontdatabase.
EGLDisplay display() const
QEvdevKeyboardManager * m_kbdMgr
QPlatformWindow * createPlatformWindow(QWindow *window) const override
Factory function for QPlatformWindow.
void destroy() override
Called before the platform integration is deleted.
NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) override
void * nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override
QPlatformServices * services() const override
QPlatformBackingStore * createPlatformBackingStore(QWindow *window) const override
Factory function for QPlatformBackingStore.
QPlatformOpenGLContext * createPlatformOpenGLContext(QOpenGLContext *context) const override
Factory function for QPlatformOpenGLContext.
void loadKeymap(const QString &file)
@ ExcludeUserInputEvents
Definition qeventloop.h:27
static QPlatformTheme * createUnixTheme(const QString &name)
Creates a UNIX theme according to the detected desktop environment.
QScreen * primaryScreen
the primary (or default) screen of the application.
\inmodule QtGui
QScreen * screen() const
Returns the screen to which the offscreen surface is connected.
QSurfaceFormat requestedFormat() const
Returns the requested surfaceformat of this offscreen surface.
A backing store implementation for OpenGL.
\inmodule QtGui
The QPlatformBackingStore class provides the drawing area for top-level windows.
The QPlatformFontDatabase class makes it possible to customize how fonts are discovered and how they ...
static QPlatformInputContext * create()
virtual bool hasCapability(Capability cap) const
Capability
Capabilities are used to determine specific features of a platform integration.
The QPlatformNativeInterface class provides an abstraction for retrieving native resource handles.
void *(* NativeResourceForContextFunction)(QOpenGLContext *context)
The QPlatformOpenGLContext class provides an abstraction for native GL contexts.
The QPlatformServices provides the backend for desktop-related functionality.
The QPlatformTheme class allows customizing the UI based on themes.
The QPlatformWindow class provides an abstraction for top-level windows.
T * data() const noexcept
Returns the value of the pointer referenced by this object.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
QPlatformScreen * handle() const
Get the platform screen handle.
Definition qscreen.cpp:83
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
static bool flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
Make Qt Gui process all events on the event queue immediately.
static void handleScreenAdded(QPlatformScreen *screen, bool isPrimary=false)
Should be called by the implementation whenever a new screen is added.
\inmodule QtGui
Definition qwindow.h:63
EGLContext ctx
QCursor cursor
Combined button and popup list for selecting options.
@ CaseInsensitive
@ ToolTip
Definition qnamespace.h:212
static void * context
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
#define Q_UNLIKELY(x)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
QEglFSDeviceIntegration * qt_egl_device_integration()
static void initResources()
@ NativeDisplay
@ WaylandDisplay
@ XlibDisplay
static int resourceType(const QByteArray &key)
static void * eglContextForContext(QOpenGLContext *context)
EGLConfig config
typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform
#define qGuiApp
#define qWarning
Definition qlogging.h:162
#define qFatal
Definition qlogging.h:164
GLuint64 GLenum void * handle
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLuint GLuint end
GLbitfield flags
GLuint name
GLuint GLuint * names
GLuint64EXT * result
[6]
GLenum cap
static void initResources()
Definition qpdf.cpp:38
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QScreen * screen
[1]
Definition main.cpp:29
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
#define Q_UNUSED(x)
#define Q_INIT_RESOURCE(name)
Definition qtresource.h:14
QVideoFrameFormat::PixelFormat fmt
QObject::connect nullptr
aWidget window() -> setWindowTitle("New Window Title")
[2]