-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AuroraPlatform is a platform abstraction library that glues together compositors with EGL device integration and input device managers. Compositors will use the platform abstraction layer to access input and output devices directly. Closes: #41
- Loading branch information
Showing
29 changed files
with
1,955 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
|
||
include(ECMQtDeclareLoggingCategory) | ||
ecm_qt_declare_logging_category( | ||
AuroraPlatform_SOURCES | ||
HEADER "auroracoreloggingcategories.h" | ||
IDENTIFIER "Aurora::Platform::gLcAuroraPlatform" | ||
CATEGORY_NAME "aurora.platform" | ||
DEFAULT_SEVERITY "Info" | ||
DESCRIPTION "Aurora platform abstraction" | ||
) | ||
|
||
liri_add_module(AuroraPlatform | ||
DESCRIPTION | ||
"Platform abstraction library for Wayland compositors using Aurora" | ||
SOURCES | ||
deviceintegration.cpp deviceintegration.h | ||
deviceintegrationplugin.cpp deviceintegrationplugin.h | ||
eglconfigchooser.cpp eglconfigchooser_p.h | ||
inputdevice.cpp inputdevice.h | ||
inputmanager.cpp inputmanager.h | ||
keyboarddevice.cpp keyboarddevice.h | ||
output.cpp output.h output_p.h | ||
pointerdevice.cpp pointerdevice.h | ||
session.cpp session.h | ||
session_noop.cpp session_noop_p.h | ||
touchdevice.cpp touchdevice.h | ||
window.cpp window.h window_p.h | ||
${AuroraPlatform_SOURCES} | ||
DEFINES | ||
QT_NO_CAST_FROM_ASCII | ||
PUBLIC_LIBRARIES | ||
Qt::Core | ||
Qt::Gui | ||
) | ||
|
||
liri_finalize_module(AuroraPlatform) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> | ||
// SPDX-License-Identifier: LGPL-3.0-or-later | ||
|
||
#include "deviceintegration.h" | ||
#include "deviceintegration_p.h" | ||
#include "eglconfigchooser_p.h" | ||
#include "inputmanager.h" | ||
|
||
namespace Aurora { | ||
|
||
namespace Platform { | ||
|
||
/* | ||
* DeviceIntegration | ||
*/ | ||
|
||
DeviceIntegration::DeviceIntegration(QObject *parent) | ||
: QObject(parent) | ||
, d_ptr(new DeviceIntegrationPrivate(this)) | ||
{ | ||
} | ||
|
||
DeviceIntegration::~DeviceIntegration() | ||
{ | ||
} | ||
|
||
bool DeviceIntegration::isReady() const | ||
{ | ||
Q_D(const DeviceIntegration); | ||
return d->ready; | ||
} | ||
|
||
bool DeviceIntegration::supportsPBuffers() | ||
{ | ||
return true; | ||
} | ||
|
||
bool DeviceIntegration::supportsSurfacelessContexts() | ||
{ | ||
return true; | ||
} | ||
|
||
EGLNativeDisplayType DeviceIntegration::platformDisplay() const | ||
{ | ||
return EGL_DEFAULT_DISPLAY; | ||
} | ||
|
||
EGLDisplay DeviceIntegration::createDisplay(EGLNativeDisplayType nativeDisplay) | ||
{ | ||
return eglGetDisplay(nativeDisplay); | ||
} | ||
|
||
void DeviceIntegration::destroyDisplay(EGLDisplay eglDisplay) | ||
{ | ||
if (eglDisplay != EGL_NO_DISPLAY) | ||
eglTerminate(eglDisplay); | ||
} | ||
|
||
EGLNativeWindowType DeviceIntegration::createNativeWindow(Window *window, const QSize &size, | ||
const QSurfaceFormat &format) | ||
{ | ||
Q_UNUSED(window) | ||
Q_UNUSED(size) | ||
Q_UNUSED(format) | ||
return 0; | ||
} | ||
|
||
void DeviceIntegration::destroyNativeWindow(EGLNativeWindowType nativeWindow) | ||
{ | ||
Q_UNUSED(nativeWindow) | ||
} | ||
|
||
QSurfaceFormat DeviceIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const | ||
{ | ||
return inputFormat; | ||
} | ||
|
||
EGLint DeviceIntegration::surfaceType() const | ||
{ | ||
return EGL_WINDOW_BIT; | ||
} | ||
|
||
EGLConfig DeviceIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format) | ||
{ | ||
Q_D(DeviceIntegration); | ||
|
||
QVector<EGLint> configAttribs = eglConfigAttributesFromSurfaceFormat(display, format); | ||
|
||
configAttribs.append(EGL_SURFACE_TYPE); | ||
configAttribs.append(surfaceType()); | ||
|
||
configAttribs.append(EGL_NONE); | ||
|
||
// Get the number of matching configurations for the attributes | ||
EGLConfig config = nullptr; | ||
EGLint numConfigs = 0; | ||
if (!eglChooseConfig(display, configAttribs.constData(), &config, 1, &numConfigs)) | ||
return nullptr; | ||
return config; | ||
} | ||
|
||
InputManager *Aurora::Platform::DeviceIntegration::createInputManager() | ||
{ | ||
return nullptr; | ||
} | ||
|
||
void DeviceIntegration::setReady(bool ready) | ||
{ | ||
Q_D(DeviceIntegration); | ||
|
||
if (d->ready == ready) | ||
return; | ||
|
||
d->ready = ready; | ||
emit readyChanged(ready); | ||
} | ||
|
||
/* | ||
* DeviceIntegrationPrivate | ||
*/ | ||
|
||
DeviceIntegrationPrivate::DeviceIntegrationPrivate(DeviceIntegration *self) | ||
: q_ptr(self) | ||
{ | ||
} | ||
|
||
} // namespace Platform | ||
|
||
} // namespace Aurora |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> | ||
// SPDX-License-Identifier: LGPL-3.0-or-later | ||
|
||
#pragma once | ||
|
||
#include <QSurfaceFormat> | ||
|
||
#include <LiriAuroraPlatform/Output> | ||
|
||
#include <EGL/egl.h> | ||
|
||
#include <memory> | ||
|
||
class QPlatformSurface; | ||
|
||
namespace Aurora { | ||
|
||
namespace Platform { | ||
|
||
class DeviceIntegrationPrivate; | ||
class InputManager; | ||
class Window; | ||
|
||
class LIRIAURORAPLATFORM_EXPORT DeviceIntegration : public QObject | ||
{ | ||
Q_OBJECT | ||
Q_PROPERTY(bool ready READ isReady NOTIFY readyChanged) | ||
Q_DECLARE_PRIVATE(DeviceIntegration) | ||
public: | ||
~DeviceIntegration(); | ||
|
||
bool isReady() const; | ||
|
||
virtual void initialize() = 0; | ||
virtual void destroy() = 0; | ||
|
||
virtual bool supportsPBuffers(); | ||
virtual bool supportsSurfacelessContexts(); | ||
|
||
virtual EGLNativeDisplayType platformDisplay() const; | ||
|
||
virtual EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay); | ||
virtual void destroyDisplay(EGLDisplay eglDisplay); | ||
|
||
virtual EGLNativeWindowType createNativeWindow(Window *window, const QSize &size, | ||
const QSurfaceFormat &format); | ||
virtual void destroyNativeWindow(EGLNativeWindowType nativeWindow); | ||
|
||
virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const; | ||
virtual EGLint surfaceType() const; | ||
|
||
virtual EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format); | ||
|
||
virtual Window *createWindow(Output *output, QWindow *window) = 0; | ||
|
||
virtual void waitForVSync(Window *window) const = 0; | ||
virtual void presentBuffer(Window *window) = 0; | ||
|
||
virtual InputManager *createInputManager(); | ||
|
||
virtual Outputs outputs() const = 0; | ||
|
||
signals: | ||
void readyChanged(bool ready); | ||
void outputAdded(Output *output); | ||
void outputRemoved(Output *output); | ||
|
||
protected: | ||
QScopedPointer<DeviceIntegrationPrivate> const d_ptr; | ||
|
||
explicit DeviceIntegration(QObject *parent = nullptr); | ||
|
||
void setReady(bool ready); | ||
}; | ||
|
||
} // namespace Platform | ||
|
||
} // namespace Aurora |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> | ||
// SPDX-License-Identifier: LGPL-3.0-or-later | ||
|
||
#pragma once | ||
|
||
#include <LiriAuroraPlatform/DeviceIntegration> | ||
|
||
// | ||
// W A R N I N G | ||
// ------------- | ||
// | ||
// This file is not part of the Aurora API. It exists purely as an | ||
// implementation detail. This header file may change from version to | ||
// version without notice, or even be removed. | ||
// | ||
// We mean it. | ||
// | ||
|
||
namespace Aurora { | ||
|
||
namespace Platform { | ||
|
||
class LIRIAURORAPLATFORM_EXPORT DeviceIntegrationPrivate | ||
{ | ||
Q_DECLARE_PUBLIC(DeviceIntegration) | ||
public: | ||
DeviceIntegrationPrivate(DeviceIntegration *self); | ||
|
||
bool ready = false; | ||
|
||
protected: | ||
DeviceIntegration *q_ptr = nullptr; | ||
}; | ||
|
||
} // namespace Platform | ||
|
||
} // namespace Aurora |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> | ||
// SPDX-License-Identifier: LGPL-3.0-or-later | ||
|
||
#include <QCoreApplication> | ||
#include <QDir> | ||
#include <QPluginLoader> | ||
#include <QJsonDocument> | ||
|
||
#include "auroracoreloggingcategories.h" | ||
#include "deviceintegrationplugin.h" | ||
|
||
namespace Aurora { | ||
|
||
namespace Platform { | ||
|
||
DeviceIntegrationPlugin::DeviceIntegrationPlugin(QObject *parent) | ||
: QObject(parent) | ||
{ | ||
} | ||
|
||
QStringList DeviceIntegrationFactory::keys(const QString &pluginPath) | ||
{ | ||
QStringList list; | ||
|
||
if (!pluginPath.isEmpty()) | ||
QCoreApplication::addLibraryPath(pluginPath); | ||
|
||
const auto paths = QCoreApplication::libraryPaths(); | ||
for (const auto &path : paths) { | ||
const auto absolutePath = | ||
QDir(path).absoluteFilePath(QStringLiteral("aurora/deviceintegration")); | ||
QDir dir(absolutePath); | ||
|
||
const auto fileNames = dir.entryList(QDir::Files); | ||
for (const auto &fileName : fileNames) { | ||
QPluginLoader loader(dir.absoluteFilePath(fileName)); | ||
|
||
if (loader.load()) { | ||
const auto metaData = | ||
loader.metaData().value(QLatin1String("MetaData")).toVariant().toMap(); | ||
list += metaData.value(QStringLiteral("Keys"), QStringList()).toStringList(); | ||
} | ||
|
||
loader.unload(); | ||
} | ||
} | ||
|
||
qCDebug(gLcAuroraPlatform) << "Device integration plugin keys:" << list; | ||
return list; | ||
} | ||
|
||
DeviceIntegration *DeviceIntegrationFactory::create(const QString &name, const QString &pluginPath) | ||
{ | ||
if (!pluginPath.isEmpty()) | ||
QCoreApplication::addLibraryPath(pluginPath); | ||
|
||
const auto paths = QCoreApplication::libraryPaths(); | ||
for (const auto &path : paths) { | ||
const auto absolutePath = | ||
QDir(path).absoluteFilePath(QStringLiteral("aurora/deviceintegration")); | ||
QDir dir(absolutePath); | ||
|
||
const auto fileNames = dir.entryList(QDir::Files); | ||
for (const auto &fileName : fileNames) { | ||
QPluginLoader loader(dir.absoluteFilePath(fileName)); | ||
|
||
if (loader.load()) { | ||
const auto metaData = | ||
loader.metaData().value(QLatin1String("MetaData")).toVariant().toMap(); | ||
const auto keys = | ||
metaData.value(QStringLiteral("Keys"), QStringList()).toStringList(); | ||
|
||
if (keys.contains(name)) { | ||
auto *plugin = dynamic_cast<DeviceIntegrationPlugin *>(loader.instance()); | ||
if (plugin) | ||
return plugin->create(); | ||
} | ||
} | ||
|
||
loader.unload(); | ||
} | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
} // namespace Platform | ||
|
||
} // namespace Aurora |
Oops, something went wrong.