diff --git a/src/client/protocols/wayland-eglstream-controller.xml b/src/client/protocols/wayland-eglstream-controller.xml
new file mode 100644
index 0000000..2c3a635
--- /dev/null
+++ b/src/client/protocols/wayland-eglstream-controller.xml
@@ -0,0 +1,87 @@
+
+
+
+ Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+
+
+
+
+ - dont_care: Using this enum will tell the server to make its own
+ decisions regarding present mode.
+
+ - fifo: Tells the server to use a fifo present mode. The decision to
+ use fifo synchronous is left up to the server.
+
+ - mailbox: Tells the server to use a mailbox present mode.
+
+
+
+
+
+
+
+
+ - present_mode: Must be one of wl_eglstream_controller_present_mode. Tells the
+ server the desired present mode that should be used.
+
+ - fifo_length: Only valid when the present_mode attrib is provided and its
+ value is specified as fifo. Tells the server the desired fifo
+ length to be used when the desired present_mode is fifo.
+
+
+
+
+
+
+
+ Creates the corresponding server side EGLStream from the given wl_buffer
+ and attaches a consumer to it.
+
+
+
+
+
+
+
+ Creates the corresponding server side EGLStream from the given wl_buffer
+ and attaches a consumer to it using the given attributes.
+
+
+
+
+
+ It contains key-value pairs compatible with intptr_t type. A key must
+ be one of wl_eglstream_controller_attrib enumeration values. What a value
+ represents is attribute-specific.
+
+
+
+
+
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 7566ef3..cebdbe7 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -1,355 +1,363 @@
set(SERVER_LIB_SRCS
appmenu_interface.cpp
buffer_interface.cpp
clientconnection.cpp
compositor_interface.cpp
datadevice_interface.cpp
datadevicemanager_interface.cpp
dataoffer_interface.cpp
datasource_interface.cpp
display.cpp
dpms_interface.cpp
filtered_display.cpp
global.cpp
idle_interface.cpp
idleinhibit_interface.cpp
idleinhibit_interface_v1.cpp
fakeinput_interface.cpp
keyboard_interface.cpp
remote_access_interface.cpp
outputconfiguration_interface.cpp
outputchangeset.cpp
outputmanagement_interface.cpp
outputdevice_interface.cpp
output_interface.cpp
pointer_interface.cpp
plasmashell_interface.cpp
plasmavirtualdesktop_interface.cpp
plasmawindowmanagement_interface.cpp
pointerconstraints_interface.cpp
pointerconstraints_interface_v1.cpp
pointergestures_interface.cpp
pointergestures_interface_v1.cpp
qtsurfaceextension_interface.cpp
region_interface.cpp
relativepointer_interface.cpp
relativepointer_interface_v1.cpp
resource.cpp
seat_interface.cpp
slide_interface.cpp
shadow_interface.cpp
blur_interface.cpp
contrast_interface.cpp
server_decoration_interface.cpp
server_decoration_palette_interface.cpp
shell_interface.cpp
surface_interface.cpp
subcompositor_interface.cpp
touch_interface.cpp
textinput_interface.cpp
textinput_interface_v0.cpp
textinput_interface_v2.cpp
xdgdecoration_interface.cpp
xdgshell_interface.cpp
xdgshell_v5_interface.cpp
xdgforeign_v2_interface.cpp
xdgforeign_interface.cpp
xdgshell_v5_interface.cpp
xdgshell_v6_interface.cpp
xdgshell_stable_interface.cpp
xdgoutput_interface.cpp
+ eglstream_controller_interface.cpp
../compat/wayland-xdg-shell-v5-protocol.c
)
ecm_qt_declare_logging_category(SERVER_LIB_SRCS HEADER logging.h IDENTIFIER KWAYLAND_SERVER CATEGORY_NAME kwayland-server DEFAULT_SEVERITY Critical)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/output-management.xml
BASENAME output-management
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/outputdevice.xml
BASENAME org_kde_kwin_outputdevice
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/plasma-shell.xml
BASENAME plasma-shell
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/plasma-virtual-desktop.xml
BASENAME plasma-virtual-desktop
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/plasma-window-management.xml
BASENAME plasma-window-management
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/surface-extension.xml
BASENAME qt-surface-extension
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/idle.xml
BASENAME idle
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/fake-input.xml
BASENAME fake-input
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/shadow.xml
BASENAME shadow
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/dpms.xml
BASENAME dpms
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/blur.xml
BASENAME blur
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/contrast.xml
BASENAME contrast
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/relative-pointer-unstable-v1.xml
BASENAME relativepointer-unstable-v1
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/slide.xml
BASENAME slide
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/server-decoration.xml
BASENAME server_decoration
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/text-input.xml
BASENAME text
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/text-input-unstable-v2.xml
BASENAME text-input-unstable-v2
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/xdg-shell-unstable-v6.xml
BASENAME xdg-shell-v6
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/pointer-gestures-unstable-v1.xml
BASENAME pointer-gestures-unstable-v1
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/pointer-constraints-unstable-v1.xml
BASENAME pointer-constraints-unstable-v1
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/xdg-foreign-unstable-v2.xml
BASENAME xdg-foreign-unstable-v2
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/idle-inhibit-unstable-v1.xml
BASENAME idle-inhibit-unstable-v1
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/appmenu.xml
BASENAME appmenu
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/server-decoration-palette.xml
BASENAME server_decoration_palette
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/remote-access.xml
BASENAME remote-access
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/xdg-output-unstable-v1.xml
BASENAME xdg-output
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/xdg-shell.xml
BASENAME xdg-shell
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/xdg-decoration-unstable-v1.xml
BASENAME xdg-decoration
)
+ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
+ PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/wayland-eglstream-controller.xml
+ BASENAME eglstream-controller
+)
+
set(SERVER_GENERATED_SRCS
${CMAKE_CURRENT_BINARY_DIR}/wayland-output-management-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-output-management-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-org_kde_kwin_outputdevice-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-org_kde_kwin_outputdevice-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-plasma-shell-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-plasma-shell-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-plasma-shell-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-plasma-virtual-desktop-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-plasma-virtual-desktop-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-plasma-window-management-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-plasma-window-management-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-qt-surface-extension-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-qt-surface-extension-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-idle-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-idle-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-fake-input-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-fake-input-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-shadow-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-shadow-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-dpms-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-dpms-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-blur-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-blur-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-contrast-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-contrast-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-relativepointer-unstable-v1-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-relativepointer-unstable-v1-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-slide-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-slide-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-server_decoration-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-server_decoration-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-server_decoration_palette-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-server_decoration_palette-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-text-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-text-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-text-input-unstable-v2-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-text-input-unstable-v2-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-xdg-shell-v6-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-xdg-shell-v6-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-xdg-shell-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-xdg-shell-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-pointer-gestures-unstable-v1-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-pointer-gestures-unstable-v1-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-pointer-constraints-unstable-v1-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-pointer-constraints-unstable-v1-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-xdg-foreign-unstable-v2-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-xdg-foreign-unstable-v2-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-idle-inhibit-unstable-v1-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-idle-inhibit-unstable-v1-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-output-unstable-v1-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-output-unstable-v1-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-output-unstable-v1-client-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-xdg-decoration-server-protocol.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-xdg-decoration-client-protocol.h
+ ${CMAKE_CURRENT_BINARY_DIR}/wayland-eglstream-controller-server-protocol.h
)
set_source_files_properties(${SERVER_GENERATED_SRCS} PROPERTIES SKIP_AUTOMOC ON)
add_library(KF5WaylandServer ${SERVER_LIB_SRCS})
generate_export_header(KF5WaylandServer
BASE_NAME
KWaylandServer
EXPORT_FILE_NAME
KWayland/Server/kwaylandserver_export.h
)
add_library(KF5::WaylandServer ALIAS KF5WaylandServer)
target_include_directories(KF5WaylandServer INTERFACE "$")
target_link_libraries(KF5WaylandServer
PUBLIC Qt5::Gui
PRIVATE
Wayland::Server
EGL::EGL
Qt5::Concurrent
)
set_target_properties(KF5WaylandServer PROPERTIES VERSION ${KWAYLAND_VERSION_STRING}
SOVERSION ${KWAYLAND_SOVERSION}
EXPORT_NAME WaylandServer
)
install(TARGETS KF5WaylandServer EXPORT KF5WaylandTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS})
set(SERVER_LIB_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/KWayland/Server/kwaylandserver_export.h
appmenu_interface.h
blur_interface.h
contrast_interface.h
buffer_interface.h
clientconnection.h
compositor_interface.h
datadevice_interface.h
datadevicemanager_interface.h
dataoffer_interface.h
datasource_interface.h
display.h
dpms_interface.h
+ eglstream_controller_interface.h
filtered_display.h
fakeinput_interface.h
global.h
idle_interface.h
idleinhibit_interface.h
keyboard_interface.h
remote_access_interface.h
outputdevice_interface.h
outputchangeset.h
outputconfiguration_interface.h
outputmanagement_interface.h
output_interface.h
pointer_interface.h
pointerconstraints_interface.h
pointergestures_interface.h
plasmashell_interface.h
plasmavirtualdesktop_interface.h
plasmawindowmanagement_interface.h
qtsurfaceextension_interface.h
region_interface.h
relativepointer_interface.h
resource.h
seat_interface.h
server_decoration_interface.h
server_decoration_palette_interface.h
shadow_interface.h
shell_interface.h
slide_interface.h
subcompositor_interface.h
surface_interface.h
textinput_interface.h
touch_interface.h
xdgdecoration_interface.h
xdgshell_interface.h
xdgforeign_interface.h
xdgoutput_interface.h
)
install(FILES
${SERVER_LIB_HEADERS}
DESTINATION ${KF5_INCLUDE_INSTALL_DIR}/KWayland/Server COMPONENT Devel
)
# make available to ecm_add_qch in parent folder
set(KWaylandServer_APIDOX_SRCS ${SERVER_LIB_HEADERS} PARENT_SCOPE)
include(ECMGeneratePriFile)
ecm_generate_pri_file(BASE_NAME KWaylandServer LIB_NAME KF5WaylandServer DEPS "core" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5})
install(FILES ${PRI_FILENAME}
DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
diff --git a/src/server/display.cpp b/src/server/display.cpp
index 693f08b..6862645 100644
--- a/src/server/display.cpp
+++ b/src/server/display.cpp
@@ -1,633 +1,641 @@
/********************************************************************
Copyright 2014 Martin Gräßlin
Copyright 2018 David Edmundson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see .
*********************************************************************/
#include "display.h"
#include "compositor_interface.h"
#include "datadevicemanager_interface.h"
#include "dpms_interface.h"
#include "outputconfiguration_interface.h"
#include "outputmanagement_interface.h"
#include "outputdevice_interface.h"
#include "idle_interface.h"
#include "idleinhibit_interface_p.h"
#include "remote_access_interface.h"
#include "fakeinput_interface.h"
#include "logging.h"
#include "output_interface.h"
#include "plasmashell_interface.h"
#include "plasmawindowmanagement_interface.h"
#include "pointerconstraints_interface_p.h"
#include "pointergestures_interface_p.h"
#include "qtsurfaceextension_interface.h"
#include "seat_interface.h"
#include "shadow_interface.h"
#include "blur_interface.h"
#include "contrast_interface.h"
#include "relativepointer_interface_p.h"
#include "server_decoration_interface.h"
#include "slide_interface.h"
#include "shell_interface.h"
#include "subcompositor_interface.h"
#include "textinput_interface_p.h"
#include "xdgshell_v5_interface_p.h"
#include "xdgforeign_interface.h"
#include "xdgshell_v6_interface_p.h"
#include "xdgshell_stable_interface_p.h"
#include "appmenu_interface.h"
#include "server_decoration_palette_interface.h"
#include "plasmavirtualdesktop_interface.h"
#include "xdgoutput_interface.h"
#include "xdgdecoration_interface.h"
+#include "eglstream_controller_interface.h"
#include
#include
#include
#include
#include
#include
#include
namespace KWayland
{
namespace Server
{
class Display::Private
{
public:
Private(Display *q);
void flush();
void dispatch();
void setRunning(bool running);
void installSocketNotifier();
wl_display *display = nullptr;
wl_event_loop *loop = nullptr;
QString socketName = QStringLiteral("wayland-0");
bool running = false;
bool automaticSocketNaming = false;
QList outputs;
QList outputdevices;
QVector seats;
QVector clients;
EGLDisplay eglDisplay = EGL_NO_DISPLAY;
private:
Display *q;
};
Display::Private::Private(Display *q)
: q(q)
{
}
void Display::Private::installSocketNotifier()
{
if (!QThread::currentThread()) {
return;
}
int fd = wl_event_loop_get_fd(loop);
if (fd == -1) {
qCWarning(KWAYLAND_SERVER) << "Did not get the file descriptor for the event loop";
return;
}
QSocketNotifier *m_notifier = new QSocketNotifier(fd, QSocketNotifier::Read, q);
QObject::connect(m_notifier, &QSocketNotifier::activated, q, [this] { dispatch(); } );
QObject::connect(QThread::currentThread()->eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, q, [this] { flush(); });
setRunning(true);
}
Display::Display(QObject *parent)
: QObject(parent)
, d(new Private(this))
{
}
Display::~Display()
{
terminate();
if (d->display) {
wl_display_destroy(d->display);
}
}
void Display::Private::flush()
{
if (!display || !loop) {
return;
}
wl_display_flush_clients(display);
}
void Display::Private::dispatch()
{
if (!display || !loop) {
return;
}
if (wl_event_loop_dispatch(loop, 0) != 0) {
qCWarning(KWAYLAND_SERVER) << "Error on dispatching Wayland event loop";
}
}
void Display::setSocketName(const QString &name)
{
if (d->socketName == name) {
return;
}
d->socketName = name;
emit socketNameChanged(d->socketName);
}
QString Display::socketName() const
{
return d->socketName;
}
void Display::setAutomaticSocketNaming(bool automaticSocketNaming)
{
if (d->automaticSocketNaming == automaticSocketNaming) {
return;
}
d->automaticSocketNaming = automaticSocketNaming;
emit automaticSocketNamingChanged(automaticSocketNaming);
}
bool Display::automaticSocketNaming() const
{
return d->automaticSocketNaming;
}
void Display::start(StartMode mode)
{
Q_ASSERT(!d->running);
Q_ASSERT(!d->display);
d->display = wl_display_create();
if (mode == StartMode::ConnectToSocket) {
if (d->automaticSocketNaming) {
const char *socket = wl_display_add_socket_auto(d->display);
if (socket == nullptr) {
qCWarning(KWAYLAND_SERVER) << "Failed to create Wayland socket";
return;
}
const QString newEffectiveSocketName = QString::fromUtf8(socket);
if (d->socketName != newEffectiveSocketName) {
d->socketName = newEffectiveSocketName;
emit socketNameChanged(d->socketName);
}
} else if (wl_display_add_socket(d->display, qPrintable(d->socketName)) != 0) {
qCWarning(KWAYLAND_SERVER) << "Failed to create Wayland socket";
return;
}
}
d->loop = wl_display_get_event_loop(d->display);
d->installSocketNotifier();
}
void Display::startLoop()
{
Q_ASSERT(!d->running);
Q_ASSERT(d->display);
d->installSocketNotifier();
}
void Display::dispatchEvents(int msecTimeout)
{
Q_ASSERT(d->display);
if (d->running) {
d->dispatch();
} else if (d->loop) {
wl_event_loop_dispatch(d->loop, msecTimeout);
wl_display_flush_clients(d->display);
}
}
void Display::terminate()
{
if (!d->running) {
return;
}
emit aboutToTerminate();
wl_display_terminate(d->display);
wl_display_destroy(d->display);
d->display = nullptr;
d->loop = nullptr;
d->setRunning(false);
}
void Display::Private::setRunning(bool r)
{
Q_ASSERT(running != r);
running = r;
emit q->runningChanged(running);
}
OutputInterface *Display::createOutput(QObject *parent)
{
OutputInterface *output = new OutputInterface(this, parent);
connect(output, &QObject::destroyed, this, [this,output] { d->outputs.removeAll(output); });
connect(this, &Display::aboutToTerminate, output, [this,output] { removeOutput(output); });
d->outputs << output;
return output;
}
CompositorInterface *Display::createCompositor(QObject *parent)
{
CompositorInterface *compositor = new CompositorInterface(this, parent);
connect(this, &Display::aboutToTerminate, compositor, [this,compositor] { delete compositor; });
return compositor;
}
ShellInterface *Display::createShell(QObject *parent)
{
ShellInterface *shell = new ShellInterface(this, parent);
connect(this, &Display::aboutToTerminate, shell, [this,shell] { delete shell; });
return shell;
}
OutputDeviceInterface *Display::createOutputDevice(QObject *parent)
{
OutputDeviceInterface *output = new OutputDeviceInterface(this, parent);
connect(output, &QObject::destroyed, this, [this,output] { d->outputdevices.removeAll(output); });
connect(this, &Display::aboutToTerminate, output, [this,output] { removeOutputDevice(output); });
d->outputdevices << output;
return output;
}
OutputManagementInterface *Display::createOutputManagement(QObject *parent)
{
OutputManagementInterface *om = new OutputManagementInterface(this, parent);
connect(this, &Display::aboutToTerminate, om, [this,om] { delete om; });
return om;
}
SeatInterface *Display::createSeat(QObject *parent)
{
SeatInterface *seat = new SeatInterface(this, parent);
connect(seat, &QObject::destroyed, this, [this, seat] { d->seats.removeAll(seat); });
connect(this, &Display::aboutToTerminate, seat, [this,seat] { delete seat; });
d->seats << seat;
return seat;
}
SubCompositorInterface *Display::createSubCompositor(QObject *parent)
{
auto c = new SubCompositorInterface(this, parent);
connect(this, &Display::aboutToTerminate, c, [this,c] { delete c; });
return c;
}
DataDeviceManagerInterface *Display::createDataDeviceManager(QObject *parent)
{
auto m = new DataDeviceManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, m, [this,m] { delete m; });
return m;
}
PlasmaShellInterface *Display::createPlasmaShell(QObject* parent)
{
auto s = new PlasmaShellInterface(this, parent);
connect(this, &Display::aboutToTerminate, s, [this, s] { delete s; });
return s;
}
PlasmaWindowManagementInterface *Display::createPlasmaWindowManagement(QObject *parent)
{
auto wm = new PlasmaWindowManagementInterface(this, parent);
connect(this, &Display::aboutToTerminate, wm, [this, wm] { delete wm; });
return wm;
}
QtSurfaceExtensionInterface *Display::createQtSurfaceExtension(QObject *parent)
{
auto s = new QtSurfaceExtensionInterface(this, parent);
connect(this, &Display::aboutToTerminate, s, [this, s] { delete s; });
return s;
}
RemoteAccessManagerInterface *Display::createRemoteAccessManager(QObject *parent)
{
auto i = new RemoteAccessManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, i, [this, i] { delete i; });
return i;
}
IdleInterface *Display::createIdle(QObject *parent)
{
auto i = new IdleInterface(this, parent);
connect(this, &Display::aboutToTerminate, i, [this, i] { delete i; });
return i;
}
FakeInputInterface *Display::createFakeInput(QObject *parent)
{
auto i = new FakeInputInterface(this, parent);
connect(this, &Display::aboutToTerminate, i, [this, i] { delete i; });
return i;
}
ShadowManagerInterface *Display::createShadowManager(QObject *parent)
{
auto s = new ShadowManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, s, [this, s] { delete s; });
return s;
}
BlurManagerInterface *Display::createBlurManager(QObject *parent)
{
auto b = new BlurManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, b, [this, b] { delete b; });
return b;
}
ContrastManagerInterface *Display::createContrastManager(QObject *parent)
{
auto b = new ContrastManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, b, [this, b] { delete b; });
return b;
}
SlideManagerInterface *Display::createSlideManager(QObject *parent)
{
auto b = new SlideManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, b, [this, b] { delete b; });
return b;
}
DpmsManagerInterface *Display::createDpmsManager(QObject *parent)
{
auto d = new DpmsManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, d, [this, d] { delete d; });
return d;
}
ServerSideDecorationManagerInterface *Display::createServerSideDecorationManager(QObject *parent)
{
auto d = new ServerSideDecorationManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, d, [d] { delete d; });
return d;
}
TextInputManagerInterface *Display::createTextInputManager(const TextInputInterfaceVersion &version, QObject *parent)
{
TextInputManagerInterface *t = nullptr;
switch (version) {
case TextInputInterfaceVersion::UnstableV0:
t = new TextInputManagerUnstableV0Interface(this, parent);
break;
case TextInputInterfaceVersion::UnstableV1:
// unsupported
return nullptr;
case TextInputInterfaceVersion::UnstableV2:
t = new TextInputManagerUnstableV2Interface(this, parent);
}
connect(this, &Display::aboutToTerminate, t, [t] { delete t; });
return t;
}
XdgShellInterface *Display::createXdgShell(const XdgShellInterfaceVersion &version, QObject *parent)
{
XdgShellInterface *x = nullptr;
switch (version) {
case XdgShellInterfaceVersion::UnstableV5:
x = new XdgShellV5Interface(this, parent);
break;
case XdgShellInterfaceVersion::UnstableV6:
x = new XdgShellV6Interface(this, parent);
break;
case XdgShellInterfaceVersion::Stable:
x = new XdgShellStableInterface(this, parent);
break;
}
connect(this, &Display::aboutToTerminate, x, [x] { delete x; });
return x;
}
RelativePointerManagerInterface *Display::createRelativePointerManager(const RelativePointerInterfaceVersion &version, QObject *parent)
{
RelativePointerManagerInterface *r = nullptr;
switch (version) {
case RelativePointerInterfaceVersion::UnstableV1:
r = new RelativePointerManagerUnstableV1Interface(this, parent);
break;
}
connect(this, &Display::aboutToTerminate, r, [r] { delete r; });
return r;
}
PointerGesturesInterface *Display::createPointerGestures(const PointerGesturesInterfaceVersion &version, QObject *parent)
{
PointerGesturesInterface *p = nullptr;
switch (version) {
case PointerGesturesInterfaceVersion::UnstableV1:
p = new PointerGesturesUnstableV1Interface(this, parent);
break;
}
connect(this, &Display::aboutToTerminate, p, [p] { delete p; });
return p;
}
PointerConstraintsInterface *Display::createPointerConstraints(const PointerConstraintsInterfaceVersion &version, QObject *parent)
{
PointerConstraintsInterface *p = nullptr;
switch (version) {
case PointerConstraintsInterfaceVersion::UnstableV1:
p = new PointerConstraintsUnstableV1Interface(this, parent);
break;
}
connect(this, &Display::aboutToTerminate, p, [p] { delete p; });
return p;
}
XdgForeignInterface *Display::createXdgForeignInterface(QObject *parent)
{
XdgForeignInterface *foreign = new XdgForeignInterface(this, parent);
connect(this, &Display::aboutToTerminate, foreign, [this,foreign] { delete foreign; });
return foreign;
}
IdleInhibitManagerInterface *Display::createIdleInhibitManager(const IdleInhibitManagerInterfaceVersion &version, QObject *parent)
{
IdleInhibitManagerInterface *i = nullptr;
switch (version) {
case IdleInhibitManagerInterfaceVersion::UnstableV1:
i = new IdleInhibitManagerUnstableV1Interface(this, parent);
break;
}
connect(this, &Display::aboutToTerminate, i, [this,i] { delete i; });
return i;
}
AppMenuManagerInterface *Display::createAppMenuManagerInterface(QObject *parent)
{
auto b = new AppMenuManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, b, [this, b] { delete b; });
return b;
}
ServerSideDecorationPaletteManagerInterface *Display::createServerSideDecorationPaletteManager(QObject *parent)
{
auto b = new ServerSideDecorationPaletteManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, b, [this, b] { delete b; });
return b;
}
PlasmaVirtualDesktopManagementInterface *Display::createPlasmaVirtualDesktopManagement(QObject *parent)
{
auto b = new PlasmaVirtualDesktopManagementInterface(this, parent);
connect(this, &Display::aboutToTerminate, b, [this, b] { delete b; });
return b;
}
XdgOutputManagerInterface *Display::createXdgOutputManager(QObject *parent)
{
auto b = new XdgOutputManagerInterface(this, parent);
connect(this, &Display::aboutToTerminate, b, [this, b] { delete b; });
return b;
}
XdgDecorationManagerInterface *Display::createXdgDecorationManager(XdgShellInterface *shellInterface, QObject *parent)
{
auto d = new XdgDecorationManagerInterface(this, shellInterface, parent);
connect(this, &Display::aboutToTerminate, d, [d] { delete d; });
return d;
}
+EglStreamControllerInterface *Display::createEglStreamControllerInterface(QObject *parent)
+{
+ EglStreamControllerInterface *e = new EglStreamControllerInterface(this, parent);
+ connect(this, &Display::aboutToTerminate, e, [e] { delete e; });
+ return e;
+}
+
void Display::createShm()
{
Q_ASSERT(d->display);
wl_display_init_shm(d->display);
}
void Display::removeOutput(OutputInterface *output)
{
d->outputs.removeAll(output);
delete output;
}
void Display::removeOutputDevice(OutputDeviceInterface *output)
{
d->outputdevices.removeAll(output);
delete output;
}
quint32 Display::nextSerial()
{
return wl_display_next_serial(d->display);
}
quint32 Display::serial()
{
return wl_display_get_serial(d->display);
}
bool Display::isRunning() const
{
return d->running;
}
Display::operator wl_display*()
{
return d->display;
}
Display::operator wl_display*() const
{
return d->display;
}
QList< OutputInterface* > Display::outputs() const
{
return d->outputs;
}
QList< OutputDeviceInterface* > Display::outputDevices() const
{
return d->outputdevices;
}
QVector Display::seats() const
{
return d->seats;
}
ClientConnection *Display::getConnection(wl_client *client)
{
Q_ASSERT(client);
auto it = std::find_if(d->clients.constBegin(), d->clients.constEnd(),
[client](ClientConnection *c) {
return c->client() == client;
}
);
if (it != d->clients.constEnd()) {
return *it;
}
// no ConnectionData yet, create it
auto c = new ClientConnection(client, this);
d->clients << c;
connect(c, &ClientConnection::disconnected, this,
[this] (ClientConnection *c) {
const int index = d->clients.indexOf(c);
Q_ASSERT(index != -1);
d->clients.remove(index);
Q_ASSERT(d->clients.indexOf(c) == -1);
emit clientDisconnected(c);
}
);
emit clientConnected(c);
return c;
}
QVector< ClientConnection* > Display::connections() const
{
return d->clients;
}
ClientConnection *Display::createClient(int fd)
{
Q_ASSERT(fd != -1);
Q_ASSERT(d->display);
wl_client *c = wl_client_create(d->display, fd);
if (!c) {
return nullptr;
}
return getConnection(c);
}
void Display::setEglDisplay(void *display)
{
if (d->eglDisplay != EGL_NO_DISPLAY) {
qCWarning(KWAYLAND_SERVER) << "EGLDisplay cannot be changed";
return;
}
d->eglDisplay = (EGLDisplay)display;
}
void *Display::eglDisplay() const
{
return d->eglDisplay;
}
}
}
diff --git a/src/server/display.h b/src/server/display.h
index a375357..d6a5f47 100644
--- a/src/server/display.h
+++ b/src/server/display.h
@@ -1,347 +1,356 @@
/********************************************************************
Copyright 2014 Martin Gräßlin
Copyright 2018 David Edmundson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) version 3, or any
later version accepted by the membership of KDE e.V. (or its
successor approved by the membership of KDE e.V.), which shall
act as a proxy defined in Section 6 of version 3 of the license.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see .
*********************************************************************/
#ifndef WAYLAND_SERVER_DISPLAY_H
#define WAYLAND_SERVER_DISPLAY_H
#include
#include
#include
#include "clientconnection.h"
struct wl_client;
struct wl_display;
struct wl_event_loop;
namespace KWayland
{
/**
* @short KWayland Server.
*
* This namespace groups all classes related to the Server module.
*
* The main entry point into the KWayland::Server API is the Display class.
* It allows to create a Wayland server and create various global objects on it.
*
* KWayland::Server is an API to easily create a head-less Wayland server with a
* Qt style API.
*
* @see Display
**/
namespace Server
{
class CompositorInterface;
class DataDeviceManagerInterface;
class DpmsManagerInterface;
class IdleInterface;
enum class IdleInhibitManagerInterfaceVersion;
class RemoteAccessManagerInterface;
class IdleInhibitManagerInterface;
class FakeInputInterface;
class OutputInterface;
class OutputDeviceInterface;
class OutputConfigurationInterface;
class OutputManagementInterface;
class PlasmaShellInterface;
class PlasmaWindowManagementInterface;
class QtSurfaceExtensionInterface;
class SeatInterface;
class ShadowManagerInterface;
class BlurManagerInterface;
class ContrastManagerInterface;
class ServerSideDecorationManagerInterface;
class SlideManagerInterface;
class ShellInterface;
class SubCompositorInterface;
enum class TextInputInterfaceVersion;
class TextInputManagerInterface;
class XdgShellV5Interface;
enum class XdgShellInterfaceVersion;
class XdgShellInterface;
enum class RelativePointerInterfaceVersion;
class RelativePointerManagerInterface;
enum class PointerGesturesInterfaceVersion;
class PointerGesturesInterface;
enum class PointerConstraintsInterfaceVersion;
class PointerConstraintsInterface;
class XdgForeignInterface;
class AppMenuManagerInterface;
class ServerSideDecorationPaletteManagerInterface;
class PlasmaVirtualDesktopManagementInterface;
class XdgOutputManagerInterface;
class XdgDecorationManagerInterface;
+class EglStreamControllerInterface;
/**
* @brief Class holding the Wayland server display loop.
*
* @todo Improve documentation
**/
class KWAYLANDSERVER_EXPORT Display : public QObject
{
Q_OBJECT
Q_PROPERTY(QString socketName READ socketName WRITE setSocketName NOTIFY socketNameChanged)
Q_PROPERTY(bool automaticSocketNaming READ automaticSocketNaming WRITE setAutomaticSocketNaming NOTIFY automaticSocketNamingChanged)
Q_PROPERTY(bool running READ isRunning NOTIFY runningChanged)
public:
explicit Display(QObject *parent = nullptr);
virtual ~Display();
/**
* Sets the basename of the socket to @p name. If @p name is empty, it will use
* wl_display_add_socket_auto to get a free socket with a filename "wayland-%d".
**/
void setSocketName(const QString &name);
QString socketName() const;
/**
* If automaticSocketNaming is true, the manually set socketName is ignored
* and it will use wl_display_add_socket_auto on start to get a free socket with
* a filename "wayland-%d" instead. The effective socket is written into socketName.
* @since 5.55
**/
void setAutomaticSocketNaming(bool automaticSocketNaming);
bool automaticSocketNaming() const;
quint32 serial();
quint32 nextSerial();
/**
* How to setup the server connection.
* @li ConnectToSocket: the server will open the socket identified by the socket name
* @li ConnectClientsOnly: only connections through createClient are possible
**/
enum class StartMode {
ConnectToSocket,
ConnectClientsOnly
};
void start(StartMode mode = StartMode::ConnectToSocket);
void terminate();
/**
* Starts the event loop for the server socket.
* This method should only be used if start() is used before creating the
* QCoreApplication. In that case start() cannot fully setup the event processing
* and the loop needs to be started after the QCoreApplication got created.
* @see start
* @see dispatchEvents
**/
void startLoop();
/**
* Dispatches pending events in a blocking way. May only be used if the Display is
* created and started before the QCoreApplication is created. Once the QCoreApplication
* is created and the event loop is started this method delegates to the normal dispatch
* handling.
* @see startLoop
**/
void dispatchEvents(int msecTimeout = -1);
/**
* Create a client for the given file descriptor.
*
* The client is created as if it connected through the normal server
* socket. This method can be used to create a connection bypassing the
* normal socket connection. It's recommended to use together with
* socketpair and pass the other side of the socket to the client.
*
* @param fd The file descriptor for the socket to the client
* @returns The new ClientConnection or @c null on failure.
**/
ClientConnection *createClient(int fd);
operator wl_display*();
operator wl_display*() const;
bool isRunning() const;
OutputInterface *createOutput(QObject *parent = nullptr);
void removeOutput(OutputInterface *output);
QList outputs() const;
OutputDeviceInterface *createOutputDevice(QObject *parent = nullptr);
void removeOutputDevice(OutputDeviceInterface *output);
QList outputDevices() const;
CompositorInterface *createCompositor(QObject *parent = nullptr);
void createShm();
ShellInterface *createShell(QObject *parent = nullptr);
SeatInterface *createSeat(QObject *parent = nullptr);
/**
* @returns All SeatInterface currently managed on the Display.
* @since 5.6
**/
QVector seats() const;
SubCompositorInterface *createSubCompositor(QObject *parent = nullptr);
DataDeviceManagerInterface *createDataDeviceManager(QObject *parent = nullptr);
OutputManagementInterface *createOutputManagement(QObject *parent = nullptr);
PlasmaShellInterface *createPlasmaShell(QObject *parent = nullptr);
PlasmaWindowManagementInterface *createPlasmaWindowManagement(QObject *parent = nullptr);
QtSurfaceExtensionInterface *createQtSurfaceExtension(QObject *parent = nullptr);
IdleInterface *createIdle(QObject *parent = nullptr);
RemoteAccessManagerInterface *createRemoteAccessManager(QObject *parent = nullptr);
FakeInputInterface *createFakeInput(QObject *parent = nullptr);
ShadowManagerInterface *createShadowManager(QObject *parent = nullptr);
BlurManagerInterface *createBlurManager(QObject *parent = nullptr);
ContrastManagerInterface *createContrastManager(QObject *parent = nullptr);
SlideManagerInterface *createSlideManager(QObject *parent = nullptr);
DpmsManagerInterface *createDpmsManager(QObject *parent = nullptr);
/**
* @since 5.6
**/
ServerSideDecorationManagerInterface *createServerSideDecorationManager(QObject *parent = nullptr);
/**
* Create the text input manager in interface @p version.
* @returns The created manager object
* @since 5.23
**/
TextInputManagerInterface *createTextInputManager(const TextInputInterfaceVersion &version, QObject *parent = nullptr);
/**
* Creates the XdgShell in interface @p version.
*
* @since 5.25
**/
XdgShellInterface *createXdgShell(const XdgShellInterfaceVersion &version, QObject *parent = nullptr);
/**
* Creates the RelativePointerManagerInterface in interface @p version
*
* @returns The created manager object
* @since 5.28
**/
RelativePointerManagerInterface *createRelativePointerManager(const RelativePointerInterfaceVersion &version, QObject *parent = nullptr);
/**
* Creates the PointerGesturesInterface in interface @p version
*
* @returns The created manager object
* @since 5.29
**/
PointerGesturesInterface *createPointerGestures(const PointerGesturesInterfaceVersion &version, QObject *parent = nullptr);
/**
* Creates the PointerConstraintsInterface in interface @p version
*
* @returns The created manager object
* @since 5.29
**/
PointerConstraintsInterface *createPointerConstraints(const PointerConstraintsInterfaceVersion &version, QObject *parent = nullptr);
/**
* Creates the XdgForeignInterface in interface @p version
*
* @returns The created manager object
* @since 5.40
**/
XdgForeignInterface *createXdgForeignInterface(QObject *parent = nullptr);
/**
* Creates the IdleInhibitManagerInterface in interface @p version.
*
* @returns The created manager object
* @since 5.41
**/
IdleInhibitManagerInterface *createIdleInhibitManager(const IdleInhibitManagerInterfaceVersion &version, QObject *parent = nullptr);
/**
* Creates the AppMenuManagerInterface in interface @p version.
*
* @returns The created manager object
* @since 5.42
**/
AppMenuManagerInterface *createAppMenuManagerInterface(QObject *parent = nullptr);
/**
* Creates the ServerSideDecorationPaletteManagerInterface in interface @p version.
*
* @returns The created manager object
* @since 5.42
**/
ServerSideDecorationPaletteManagerInterface *createServerSideDecorationPaletteManager(QObject *parent = nullptr);
/**
* Creates the XdgOutputManagerInterface
*
* @return the created manager
* @since 5.47
*/
XdgOutputManagerInterface *createXdgOutputManager(QObject *parent = nullptr);
/**
* Creates the PlasmaVirtualDesktopManagementInterface in interface @p version.
*
* @returns The created manager object
* @since 5.52
**/
PlasmaVirtualDesktopManagementInterface *createPlasmaVirtualDesktopManagement(QObject *parent = nullptr);
/**
* Creates the XdgDecorationManagerInterface
* @arg shellInterface A created XdgShellInterface based on XDG_WM_BASE
*
* @return the created manager
* @since 5.54
*/
XdgDecorationManagerInterface *createXdgDecorationManager(XdgShellInterface *shellInterface, QObject *parent = nullptr);
+ /**
+ * Creates the EglStreamControllerInterface
+ *
+ * @return the created EGL Stream controller
+ * @since 5.58
+ */
+ EglStreamControllerInterface *createEglStreamControllerInterface(QObject *parent = nullptr);
+
/**
* Gets the ClientConnection for the given @p client.
* If there is no ClientConnection yet for the given @p client, it will be created.
* @param client The native client for which the ClientConnection is retrieved
* @return The ClientConnection for the given native client
**/
ClientConnection *getConnection(wl_client *client);
QVector connections() const;
/**
* Set the EGL @p display for this Wayland display.
* The EGLDisplay can only be set once and must be alive as long as the Wayland display
* is alive. The user should have set up the binding between the EGLDisplay and the
* Wayland display prior to calling this method.
*
* @see eglDisplay
* @since 5.3
**/
void setEglDisplay(void *display);
/**
* @returns the EGLDisplay used for this Wayland display or EGL_NO_DISPLAY if not set.
* @see setEglDisplay
* @since 5.3
**/
void *eglDisplay() const;
Q_SIGNALS:
void socketNameChanged(const QString&);
void automaticSocketNamingChanged(bool);
void runningChanged(bool);
void aboutToTerminate();
void clientConnected(KWayland::Server::ClientConnection*);
void clientDisconnected(KWayland::Server::ClientConnection*);
private:
class Private;
QScopedPointer d;
};
}
}
#endif
diff --git a/src/server/eglstream_controller_interface.cpp b/src/server/eglstream_controller_interface.cpp
new file mode 100644
index 0000000..0196454
--- /dev/null
+++ b/src/server/eglstream_controller_interface.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+Copyright 2019 NVIDIA Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) version 3, or any
+later version accepted by the membership of KDE e.V. (or its
+successor approved by the membership of KDE e.V.), which shall
+act as a proxy defined in Section 6 of version 3 of the license.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library. If not, see .
+****************************************************************************/
+#include "eglstream_controller_interface_p.h"
+#include "clientconnection.h"
+#include "display.h"
+#include "logging.h"
+
+#include
+#include
+
+namespace KWayland
+{
+namespace Server
+{
+
+const quint32 EglStreamControllerInterface::Private::s_version = 1;
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+const struct wl_eglstream_controller_interface EglStreamControllerInterface::Private::s_interface = {
+ attachStreamConsumer,
+ attachStreamConsumerAttribs
+};
+#endif
+
+void EglStreamControllerInterface::Private::attachStreamConsumer(wl_client *client,
+ wl_resource *resource,
+ wl_resource *surface,
+ wl_resource *eglStream)
+{
+ wl_array noAttribs = { 0, 0, nullptr };
+ attachStreamConsumerAttribs(client, resource, surface, eglStream, &noAttribs);
+}
+
+void EglStreamControllerInterface::Private::attachStreamConsumerAttribs(wl_client *client,
+ wl_resource *resource,
+ wl_resource *surface,
+ wl_resource *eglStream,
+ wl_array *attribs)
+{
+ Q_UNUSED(client);
+ Private *p = reinterpret_cast(wl_resource_get_user_data(resource));
+ emit p->q->streamConsumerAttached(SurfaceInterface::get(surface), eglStream, attribs);
+}
+
+EglStreamControllerInterface::Private::Private(EglStreamControllerInterface *q, Display *display)
+ // libnvidia-egl-wayland.so.1 may not be present on all systems, so we load it dynamically
+ : Global::Private(display,
+ (wl_interface *)QLibrary::resolve(QLatin1String("libnvidia-egl-wayland.so.1"),
+ "wl_eglstream_controller_interface"),
+ s_version)
+ , q(q)
+{
+}
+
+void EglStreamControllerInterface::Private::create()
+{
+ // bail out early if we were unable to load the interface
+ if (m_interface == nullptr) {
+ qCWarning(KWAYLAND_SERVER) << "failed to resolve wl_eglstream_controller_interface";
+ return;
+ }
+
+ Global::Private::create();
+}
+
+void EglStreamControllerInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
+{
+ wl_resource *r = display->getConnection(client)->createResource(m_interface, version, id);
+ if (r == nullptr) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ wl_resource_set_implementation(r, &s_interface, this, nullptr);
+}
+
+EglStreamControllerInterface::~EglStreamControllerInterface() = default;
+
+EglStreamControllerInterface::EglStreamControllerInterface(Display *display, QObject *parent)
+ : Global(new Private(this, display), parent)
+{
+}
+
+void EglStreamControllerInterface::create()
+{
+ static_cast(*d).create();
+}
+
+}
+}
diff --git a/src/server/eglstream_controller_interface.h b/src/server/eglstream_controller_interface.h
new file mode 100644
index 0000000..175114a
--- /dev/null
+++ b/src/server/eglstream_controller_interface.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+Copyright 2019 NVIDIA Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) version 3, or any
+later version accepted by the membership of KDE e.V. (or its
+successor approved by the membership of KDE e.V.), which shall
+act as a proxy defined in Section 6 of version 3 of the license.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library. If not, see .
+****************************************************************************/
+#ifndef WAYLAND_SERVER_EGLSTREAM_CONTROLLER_INTERFACE_H
+#define WAYLAND_SERVER_EGLSTREAM_CONTROLLER_INTERFACE_H
+
+#include "global.h"
+#include "surface_interface.h"
+
+#include
+#include
+#include
+
+namespace KWayland
+{
+namespace Server
+{
+
+class Display;
+
+/**
+ * @brief Represents the Global for the wl_eglstream_controller interface.
+ *
+ * This class handles requests (typically from the NVIDIA EGL driver) to attach
+ * a newly created EGL Stream to a Wayland surface, facilitating the sharing
+ * of buffer contents between client and compositor.
+ *
+ */
+class KWAYLANDSERVER_EXPORT EglStreamControllerInterface : public Global
+{
+ Q_OBJECT
+public:
+ ~EglStreamControllerInterface() override;
+ void create();
+
+Q_SIGNALS:
+ /**
+ * Emitted when a new stream attach request is received.
+ */
+ void streamConsumerAttached(SurfaceInterface *surface, void *eglStream, wl_array *attribs);
+private:
+ explicit EglStreamControllerInterface(Display *display, QObject *parent = nullptr);
+
+ class Private;
+ friend class Display;
+};
+
+}
+}
+
+#endif
diff --git a/src/server/eglstream_controller_interface_p.h b/src/server/eglstream_controller_interface_p.h
new file mode 100644
index 0000000..386f55d
--- /dev/null
+++ b/src/server/eglstream_controller_interface_p.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+Copyright 2019 NVIDIA Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) version 3, or any
+later version accepted by the membership of KDE e.V. (or its
+successor approved by the membership of KDE e.V.), which shall
+act as a proxy defined in Section 6 of version 3 of the license.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library. If not, see .
+****************************************************************************/
+#ifndef WAYLAND_SERVER_EGLSTREAM_CONTROLLER_INTERFACE_P_H
+#define WAYLAND_SERVER_EGLSTREAM_CONTROLLER_INTERFACE_P_H
+
+#include "eglstream_controller_interface.h"
+#include "global_p.h"
+
+#include
+
+namespace KWayland
+{
+namespace Server
+{
+
+class Q_DECL_HIDDEN EglStreamControllerInterface::Private : public Global::Private
+{
+public:
+ Private(EglStreamControllerInterface *controller, Display *display);
+ void create();
+
+private:
+ static void attachStreamConsumer(wl_client *client,
+ wl_resource *resource,
+ wl_resource *surface,
+ wl_resource *eglStream);
+ static void attachStreamConsumerAttribs(wl_client *client,
+ wl_resource *resource,
+ wl_resource *surface,
+ wl_resource *eglStream,
+ wl_array *attribs);
+ static const struct wl_eglstream_controller_interface s_interface;
+ static const quint32 s_version;
+ void bind(wl_client *client, uint32_t version, uint32_t id) override;
+ EglStreamControllerInterface *q;
+};
+
+}
+}
+
+#endif