Skip to content

Commit

Permalink
Device integration for Wayland
Browse files Browse the repository at this point in the history
Closes: #42
  • Loading branch information
plfiorini committed Aug 23, 2023
1 parent d413d67 commit 3cb80e1
Show file tree
Hide file tree
Showing 20 changed files with 1,213 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ if(FEATURE_aurora_qpa)
add_subdirectory(src/plugins/platforms/eglfs/deviceintegration/eglfs_x11)
endif()
endif()
if(FEATURE_aurora_deviceintegration_wayland)
add_subdirectory(src/plugins/deviceintegration/wayland)
endif()
if(BUILD_TESTING)
if(TARGET AuroraCompositor)
add_subdirectory(tests/auto/compositor/compositor)
Expand Down
23 changes: 23 additions & 0 deletions features.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,29 @@ if(FEATURE_aurora_vulkan_server_buffer)
endif()
set(LIRI_FEATURE_aurora_vulkan_server_buffer "$<IF:${FEATURE_aurora_vulkan_server_buffer},1,0>")

# Device Integration: wayland
option(FEATURE_aurora_deviceintegration_wayland "Device Integration: wayland" ON)
if(FEATURE_aurora_deviceintegration_wayland)
find_package(EGL QUIET)
find_package(Wayland "${WAYLAND_MIN_VERSION}" COMPONENTS Egl QUIET)
find_package(KF5Wayland QUIET)

if(NOT TARGET EGL::EGL)
message(WARNING "You need EGL for Aurora::DeviceIntegration::Wayland")
set(FEATURE_aurora_deviceintegration_wayland OFF)
endif()
if(NOT TARGET Wayland::Egl)
message(WARNING "You need Wayland::Egl for Aurora::DeviceIntegration::Wayland")
set(FEATURE_aurora_deviceintegration_wayland OFF)
endif()
if(NOT KF5Wayland_FOUND)
message(WARNING "You need KWayland::Client for Aurora::DeviceIntegration::Wayland")
set(FEATURE_aurora_deviceintegration_wayland OFF)
endif()
endif()
add_feature_info("Aurora::DeviceIntegration::Wayland" FEATURE_aurora_deviceintegration_wayland "Build Wayland device integration")
set(LIRI_FEATURE_aurora_deviceintegration_wayland "$<IF:${FEATURE_aurora_deviceintegration_wayland},1,0>")

# xwayland
option(FEATURE_aurora_xwayland "XWayland support" ON)
if(FEATURE_aurora_xwayland)
Expand Down
38 changes: 38 additions & 0 deletions src/plugins/deviceintegration/wayland/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
include(ECMQtDeclareLoggingCategory)
ecm_qt_declare_logging_category(
AuroraDeviceIntegrationWayland_SOURCES
HEADER "waylandloggingcategories.h"
IDENTIFIER "Aurora::Core::gLcWayland"
CATEGORY_NAME "aurora.core.wayland"
DEFAULT_SEVERITY "Info"
DESCRIPTION "Aurora device integration for Wayland"
)

liri_add_plugin(AuroraDeviceIntegrationWayland
TYPE
"aurora/deviceintegration"
OUTPUT_NAME
wayland
SOURCES
eglintegration.cpp eglintegration.h
waylandinputmanager.cpp waylandinputmanager.h
waylandintegrationplugin.cpp waylandintegrationplugin.h
waylandkeyboard.cpp waylandkeyboard.h
waylandintegration.cpp waylandintegration.h
waylandoutput.cpp waylandoutput.h
waylandscreenwindow.cpp waylandscreenwindow.h
waylandwindow.cpp waylandwindow.h
wayland.json
${AuroraDeviceIntegrationWayland_SOURCES}
PUBLIC_LIBRARIES
Qt5::Core
Qt5::Gui
Liri::AuroraCore
Liri::AuroraCorePrivate
EGL::EGL
Wayland::Egl
LIBRARIES
KF5::WaylandClient
)

liri_finalize_plugin(AuroraDeviceIntegrationWayland)
86 changes: 86 additions & 0 deletions src/plugins/deviceintegration/wayland/eglintegration.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#include <QByteArray>
#include <QList>

#include "eglintegration.h"
#include "waylandloggingcategories.h"
#include "waylandintegration.h"

namespace Aurora {

namespace Core {

EglIntegration::EglIntegration(WaylandIntegration *integration) : m_integration(integration) { }

EglIntegration::~EglIntegration()
{
destroy();
}

bool EglIntegration::isInitialized() const
{
return m_initialized;
}

EGLDisplay EglIntegration::display() const
{
return m_eglDisplay;
}

typedef const char *(*EGLGETERRORSTRINGPROC)(EGLint error);

bool EglIntegration::initialize()
{
if (m_initialized)
return true;

m_initialized = true;

if (hasEglExtension("EGL_EXT_platform_base")) {
if (hasEglExtension("EGL_KHR_platform_wayland")
|| hasEglExtension("EGL_EXT_platform_wayland")
|| hasEglExtension("EGL_MESA_platform_wayland")) {
static PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplay = nullptr;
if (!eglGetPlatformDisplay)
eglGetPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
eglGetProcAddress("eglGetPlatformDisplayEXT"));

m_eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, m_integration->display(),
nullptr);
} else {
qCWarning(gLcWayland) << "The EGL implementation does not support the Wayland platform";
return false;
}
} else {
QByteArray eglPlatform = qgetenv("EGL_PLATFORM");
if (eglPlatform.isEmpty())
setenv("EGL_PLATFORM", "wayland", true);

m_eglDisplay =
eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(m_integration->display()));
}

return true;
}

void EglIntegration::destroy()
{
if (m_eglDisplay != EGL_NO_DISPLAY) {
eglTerminate(m_eglDisplay);
m_eglDisplay = EGL_NO_DISPLAY;
}
}

bool EglIntegration::hasEglExtension(const char *name, EGLDisplay display)
{
QList<QByteArray> extensions =
QByteArray(reinterpret_cast<const char *>(eglQueryString(display, EGL_EXTENSIONS)))
.split(' ');
return extensions.contains(name);
}

} // namespace Core

} // namespace Aurora
47 changes: 47 additions & 0 deletions src/plugins/deviceintegration/wayland/eglintegration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QPointer>

#ifndef EGL_NO_X11
# define EGL_NO_X11
#endif
#ifndef MESA_EGL_NO_X11_HEADERS
# define MESA_EGL_NO_X11_HEADERS
#endif

#include <EGL/egl.h>
#include <EGL/eglext.h>

namespace Aurora {

namespace Core {

class WaylandIntegration;

class EglIntegration
{
public:
EglIntegration(WaylandIntegration *integration);
~EglIntegration();

bool isInitialized() const;

EGLDisplay display() const;

bool initialize();
void destroy();

static bool hasEglExtension(const char *name, EGLDisplay display = EGL_NO_DISPLAY);

private:
bool m_initialized = false;
QPointer<WaylandIntegration> m_integration;
EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
};

} // namespace Core

} // namespace Aurora
3 changes: 3 additions & 0 deletions src/plugins/deviceintegration/wayland/wayland.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"Keys": [ "wayland" ]
}
29 changes: 29 additions & 0 deletions src/plugins/deviceintegration/wayland/waylandinputmanager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#include <KWayland/Client/seat.h>

#include "waylandinputmanager.h"
#include "waylandintegration.h"

namespace Aurora {

namespace Core {

WaylandInputManager::WaylandInputManager(WaylandIntegration *integration, QObject *parent)
: InputManager(parent), m_integration(integration)
{
auto *seat = m_integration->seat();
connect(seat, &KWayland::Client::Seat::hasKeyboardChanged, this,
[this, seat](bool hasKeyboard) {
if (hasKeyboard) {
auto *hostKeyboard = seat->createKeyboard(this);
m_keyboard = new WaylandKeyboard(hostKeyboard, this);
emit deviceAdded(m_keyboard);
}
});
}

} // namespace Core

} // namespace Aurora
24 changes: 24 additions & 0 deletions src/plugins/deviceintegration/wayland/waylandinputmanager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#include <LiriAuroraCore/InputManager>

namespace Aurora {

namespace Core {

class WaylandIntegration;

class WaylandInputManager : public InputManager
{
Q_OBJECT
public:
WaylandInputManager(WaylandIntegration *integration, QObject *parent = nullptr);

private:
QPointer<WaylandIntegration> m_integration;
};

} // namespace Core

} // namespace Aurora
Loading

0 comments on commit 3cb80e1

Please sign in to comment.