diff --git a/src/remotedesktop.cpp b/src/remotedesktop.cpp
index deea101..28bf225 100644
--- a/src/remotedesktop.cpp
+++ b/src/remotedesktop.cpp
@@ -1,309 +1,311 @@
/*
* Copyright © 2018 Red Hat, Inc
*
* This program 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 of the License, or (at your option) any later version.
*
* 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 .
*
* Authors:
* Jan Grulich
*/
#include "remotedesktop.h"
#include "session.h"
#include "remotedesktopdialog.h"
#include "utils.h"
#include "waylandintegration.h"
#include
Q_LOGGING_CATEGORY(XdgDesktopPortalKdeRemoteDesktop, "xdp-kde-remotedesktop")
RemoteDesktopPortal::RemoteDesktopPortal(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
}
RemoteDesktopPortal::~RemoteDesktopPortal()
{
}
uint RemoteDesktopPortal::CreateSession(const QDBusObjectPath &handle,
const QDBusObjectPath &session_handle,
const QString &app_id,
const QVariantMap &options,
QVariantMap &results)
{
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << "CreateSession called with parameters:";
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " handle: " << handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " app_id: " << app_id;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " options: " << options;
Session *session = Session::createSession(this, Session::RemoteDesktop, app_id, session_handle.path());
if (!session) {
return 2;
}
connect(session, &Session::closed, [this] () {
WaylandIntegration::stopStreaming();
});
return 0;
}
uint RemoteDesktopPortal::SelectDevices(const QDBusObjectPath &handle,
const QDBusObjectPath &session_handle,
const QString &app_id,
const QVariantMap &options,
QVariantMap &results)
{
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << "SelectDevices called with parameters:";
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " handle: " << handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " app_id: " << app_id;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " options: " << options;
RemoteDesktopPortal::DeviceTypes types = RemoteDesktopPortal::None;
if (options.contains(QStringLiteral("types"))) {
types = static_cast(options.value(QStringLiteral("types")).toUInt());
}
RemoteDesktopSession *session = qobject_cast(Session::getSession(session_handle.path()));
if (!session) {
qCWarning(XdgDesktopPortalKdeRemoteDesktop) << "Tried to select sources on non-existing session " << session_handle.path();
return 2;
}
if (options.contains(QStringLiteral("types"))) {
types = (DeviceTypes)(options.value(QStringLiteral("types")).toUInt());
}
session->setDeviceTypes(types);
return 0;
}
uint RemoteDesktopPortal::Start(const QDBusObjectPath &handle,
const QDBusObjectPath &session_handle,
const QString &app_id,
const QString &parent_window,
const QVariantMap &options,
QVariantMap &results)
{
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << "Start called with parameters:";
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " handle: " << handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " app_id: " << app_id;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " parent_window: " << parent_window;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " options: " << options;
RemoteDesktopSession *session = qobject_cast(Session::getSession(session_handle.path()));
if (!session) {
qCWarning(XdgDesktopPortalKdeRemoteDesktop) << "Tried to call start on non-existing session " << session_handle.path();
return 2;
}
// TODO check whether we got some outputs?
if (WaylandIntegration::screens().isEmpty()) {
qCWarning(XdgDesktopPortalKdeRemoteDesktop) << "Failed to show dialog as there is no screen to select";
return 2;
}
QScopedPointer remoteDesktopDialog(new RemoteDesktopDialog(app_id, session->deviceTypes(), session->screenSharingEnabled(), session->multipleSources()));
Utils::setParentWindow(remoteDesktopDialog.data(), parent_window);
+ connect(session, &Session::closed, remoteDesktopDialog.data(), &RemoteDesktopDialog::reject);
+
if (remoteDesktopDialog->exec()) {
if (session->screenSharingEnabled()) {
if (!WaylandIntegration::startStreaming(remoteDesktopDialog->selectedScreens().first())) {
return 2;
}
WaylandIntegration::authenticate();
QVariant streams = WaylandIntegration::streams();
if (!streams.isValid()) {
qCWarning(XdgDesktopPortalKdeRemoteDesktop()) << "Pipewire stream is not ready to be streamed";
return 2;
}
results.insert(QStringLiteral("streams"), streams);
} else {
qCWarning(XdgDesktopPortalKdeRemoteDesktop()) << "Only stream input";
WaylandIntegration::startStreamingInput();
WaylandIntegration::authenticate();
}
results.insert(QStringLiteral("devices"), QVariant::fromValue(remoteDesktopDialog->deviceTypes()));
return 0;
}
return 1;
}
void RemoteDesktopPortal::NotifyPointerMotion(const QDBusObjectPath &session_handle,
const QVariantMap &options,
double dx,
double dy)
{
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << "NotifyPointerMotion called with parameters:";
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " options: " << options;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " dx: " << dx;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " dy: " << dy;
RemoteDesktopSession *session = qobject_cast(Session::getSession(session_handle.path()));
if (!session) {
qCWarning(XdgDesktopPortalKdeRemoteDesktop) << "Tried to call NotifyPointerMotion on non-existing session " << session_handle.path();
return;
}
WaylandIntegration::requestPointerMotion(QSizeF(dx, dy));
}
void RemoteDesktopPortal::NotifyPointerMotionAbsolute(const QDBusObjectPath &session_handle,
const QVariantMap &options,
uint stream,
double x,
double y)
{
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << "NotifyPointerMotionAbsolute called with parameters:";
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " options: " << options;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " stream: " << stream;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " x: " << x;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " y: " << y;
RemoteDesktopSession *session = qobject_cast(Session::getSession(session_handle.path()));
if (!session) {
qCWarning(XdgDesktopPortalKdeRemoteDesktop) << "Tried to call NotifyPointerMotionAbsolute on non-existing session " << session_handle.path();
return;
}
WaylandIntegration::requestPointerMotionAbsolute(QPointF(x, y));
}
void RemoteDesktopPortal::NotifyPointerButton(const QDBusObjectPath &session_handle,
const QVariantMap &options,
int button,
uint state)
{
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << "NotifyPointerButton called with parameters:";
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " options: " << options;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " button: " << button;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " state: " << state;
RemoteDesktopSession *session = qobject_cast(Session::getSession(session_handle.path()));
if (!session) {
qCWarning(XdgDesktopPortalKdeRemoteDesktop) << "Tried to call NotifyPointerButton on non-existing session " << session_handle.path();
return;
}
if (state) {
WaylandIntegration::requestPointerButtonPress(button);
} else {
WaylandIntegration::requestPointerButtonRelease(button);
}
}
void RemoteDesktopPortal::NotifyPointerAxis(const QDBusObjectPath &session_handle,
const QVariantMap &options,
double dx,
double dy)
{
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << "NotifyPointerAxis called with parameters:";
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " options: " << options;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " dx: " << dx;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " dy: " << dy;
}
void RemoteDesktopPortal::NotifyPointerAxisDiscrete(const QDBusObjectPath &session_handle,
const QVariantMap &options,
uint axis,
int steps)
{
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << "NotifyPointerAxisDiscrete called with parameters:";
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " options: " << options;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " axis: " << axis;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " steps: " << steps;
RemoteDesktopSession *session = qobject_cast(Session::getSession(session_handle.path()));
if (!session) {
qCWarning(XdgDesktopPortalKdeRemoteDesktop) << "Tried to call NotifyPointerAxisDiscrete on non-existing session " << session_handle.path();
return;
}
WaylandIntegration::requestPointerAxisDiscrete(!axis ? Qt::Vertical : Qt::Horizontal, steps);
}
void RemoteDesktopPortal::NotifyKeyboardKeysym(const QDBusObjectPath &session_handle,
const QVariantMap &options,
int keysym,
uint state)
{
}
void RemoteDesktopPortal::NotifyKeyboardKeycode(const QDBusObjectPath &session_handle,
const QVariantMap &options,
int keycode,
uint state)
{
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << "NotifyKeyboardKeycode called with parameters:";
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " options: " << options;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " keycode: " << keycode;
qCDebug(XdgDesktopPortalKdeRemoteDesktop) << " state: " << state;
RemoteDesktopSession *session = qobject_cast(Session::getSession(session_handle.path()));
if (!session) {
qCWarning(XdgDesktopPortalKdeRemoteDesktop) << "Tried to call NotifyKeyboardKeycode on non-existing session " << session_handle.path();
return;
}
WaylandIntegration::requestKeyboardKeycode(keycode, state != 0);
}
void RemoteDesktopPortal::NotifyTouchDown(const QDBusObjectPath &session_handle,
const QVariantMap &options,
uint stream,
uint slot,
int x,
int y)
{
}
void RemoteDesktopPortal::NotifyTouchMotion(const QDBusObjectPath &session_handle,
const QVariantMap &options,
uint stream,
uint slot,
int x,
int y)
{
}
void RemoteDesktopPortal::NotifyTouchUp(const QDBusObjectPath &session_handle,
const QVariantMap &options,
uint slot)
{
}
diff --git a/src/screencast.cpp b/src/screencast.cpp
index 09a564c..38b00ca 100644
--- a/src/screencast.cpp
+++ b/src/screencast.cpp
@@ -1,168 +1,170 @@
/*
* Copyright © 2018 Red Hat, Inc
*
* This program 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 of the License, or (at your option) any later version.
*
* 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 .
*
* Authors:
* Jan Grulich
*/
#include "screencast.h"
#include "screenchooserdialog.h"
#include "session.h"
#include "waylandintegration.h"
#include "utils.h"
#include
Q_LOGGING_CATEGORY(XdgDesktopPortalKdeScreenCast, "xdp-kde-screencast")
ScreenCastPortal::ScreenCastPortal(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
}
ScreenCastPortal::~ScreenCastPortal()
{
}
uint ScreenCastPortal::CreateSession(const QDBusObjectPath &handle,
const QDBusObjectPath &session_handle,
const QString &app_id,
const QVariantMap &options,
QVariantMap &results)
{
Q_UNUSED(results)
qCDebug(XdgDesktopPortalKdeScreenCast) << "CreateSession called with parameters:";
qCDebug(XdgDesktopPortalKdeScreenCast) << " handle: " << handle.path();
qCDebug(XdgDesktopPortalKdeScreenCast) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeScreenCast) << " app_id: " << app_id;
qCDebug(XdgDesktopPortalKdeScreenCast) << " options: " << options;
Session *session = Session::createSession(this, Session::ScreenCast, app_id, session_handle.path());
if (!session) {
return 2;
}
connect(session, &Session::closed, [this] () {
WaylandIntegration::stopStreaming();
});
return 0;
}
uint ScreenCastPortal::SelectSources(const QDBusObjectPath &handle,
const QDBusObjectPath &session_handle,
const QString &app_id,
const QVariantMap &options,
QVariantMap &results)
{
Q_UNUSED(results)
qCDebug(XdgDesktopPortalKdeScreenCast) << "SelectSource called with parameters:";
qCDebug(XdgDesktopPortalKdeScreenCast) << " handle: " << handle.path();
qCDebug(XdgDesktopPortalKdeScreenCast) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeScreenCast) << " app_id: " << app_id;
qCDebug(XdgDesktopPortalKdeScreenCast) << " options: " << options;
uint types = Monitor;
ScreenCastSession *session = qobject_cast(Session::getSession(session_handle.path()));
if (!session) {
qCWarning(XdgDesktopPortalKdeScreenCast) << "Tried to select sources on non-existing session " << session_handle.path();
return 2;
}
if (options.contains(QStringLiteral("multiple"))) {
session->setMultipleSources(options.value(QStringLiteral("multiple")).toBool());
}
if (options.contains(QStringLiteral("types"))) {
types = (SourceType)(options.value(QStringLiteral("types")).toUInt());
}
if (types == Window) {
qCWarning(XdgDesktopPortalKdeScreenCast) << "Screen cast of a window is not implemented";
return 2;
}
// Might be also a RemoteDesktopSession
if (session->type() == Session::RemoteDesktop) {
RemoteDesktopSession *remoteDesktopSession = qobject_cast(session);
if (remoteDesktopSession) {
remoteDesktopSession->setScreenSharingEnabled(true);
}
}
return 0;
}
uint ScreenCastPortal::Start(const QDBusObjectPath &handle,
const QDBusObjectPath &session_handle,
const QString &app_id,
const QString &parent_window,
const QVariantMap &options,
QVariantMap &results)
{
Q_UNUSED(results)
qCDebug(XdgDesktopPortalKdeScreenCast) << "Start called with parameters:";
qCDebug(XdgDesktopPortalKdeScreenCast) << " handle: " << handle.path();
qCDebug(XdgDesktopPortalKdeScreenCast) << " session_handle: " << session_handle.path();
qCDebug(XdgDesktopPortalKdeScreenCast) << " app_id: " << app_id;
qCDebug(XdgDesktopPortalKdeScreenCast) << " parent_window: " << parent_window;
qCDebug(XdgDesktopPortalKdeScreenCast) << " options: " << options;
ScreenCastSession *session = qobject_cast(Session::getSession(session_handle.path()));
if (!session) {
qCWarning(XdgDesktopPortalKdeScreenCast) << "Tried to call start on non-existing session " << session_handle.path();
return 2;
}
if (WaylandIntegration::screens().isEmpty()) {
qCWarning(XdgDesktopPortalKdeScreenCast) << "Failed to show dialog as there is no screen to select";
return 2;
}
if (!WaylandIntegration::isEGLInitialized()) {
qCWarning(XdgDesktopPortalKdeScreenCast) << "EGL is not properly initialized";
return 2;
}
QScopedPointer screenDialog(new ScreenChooserDialog(app_id, session->multipleSources()));
Utils::setParentWindow(screenDialog.data(), parent_window);
+ connect(session, &Session::closed, screenDialog.data(), &ScreenChooserDialog::reject);
+
if (screenDialog->exec()) {
if (!WaylandIntegration::startStreaming(screenDialog->selectedScreens().first())) {
return 2;
}
QVariant streams = WaylandIntegration::streams();
if (!streams.isValid()) {
qCWarning(XdgDesktopPortalKdeScreenCast) << "Pipewire stream is not ready to be streamed";
return 2;
}
results.insert(QStringLiteral("streams"), streams);
return 0;
}
return 1;
}