Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion include/grabber/linux/pipewire/PipewireHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ namespace sdbus{
class IProxy;
}
class ScreenCastProxy;
class RemoteDesktopProxy;

class PipewireHandler : public QObject
{
Expand All @@ -93,7 +94,7 @@ class PipewireHandler : public QObject
PipewireHandler();
~PipewireHandler();

void startSession(QString restorationToken, uint32_t requestedFPS, bool enableEGL, int targetMaxSize);
void startSession(QString restorationToken, uint32_t requestedFPS, bool enableEGL, int targetMaxSize, int selectedDisplay);
void closeSession();
bool hasError();
bool isRestartNeeded();
Expand Down Expand Up @@ -148,7 +149,9 @@ public Q_SLOTS:
QString _errorMessage;
bool _portalStatus;
bool _isError;
bool _useRemoteDesktopPortal;
int _version;
int _remoteDesktopVersion;
uint _streamNodeId;

QString _sender;
Expand All @@ -166,6 +169,7 @@ public Q_SLOTS:
struct pw_buffer* _workingFrame;

int _targetMaxSize;
int _selectedDisplay;
int _frameWidth;
int _frameHeight;
bool _frameOrderRgb;
Expand All @@ -184,6 +188,7 @@ public Q_SLOTS:

std::unique_ptr<sdbus::IConnection> _dbusConnection;
std::unique_ptr<ScreenCastProxy> _screenCastProxy;
std::unique_ptr<RemoteDesktopProxy> _remoteDesktopProxy;
std::unique_ptr<sdbus::IProxy> _createSessionProxy;
std::unique_ptr<sdbus::IProxy> _selectSourceProxy;
std::unique_ptr<sdbus::IProxy> _startProxy;
Expand Down
135 changes: 135 additions & 0 deletions include/grabber/linux/pipewire/RemoteDesktopProxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@

/*
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/

#ifndef __sdbuscpp__include_grabber_linux_pipewire_RemoteDesktopProxy_h__proxy__H__
#define __sdbuscpp__include_grabber_linux_pipewire_RemoteDesktopProxy_h__proxy__H__

#include <sdbus-c++/sdbus-c++.h>
#include <string>
#include <tuple>

namespace org {
namespace freedesktop {
namespace portal {

class RemoteDesktop_proxy
{
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.portal.RemoteDesktop";

protected:
RemoteDesktop_proxy(sdbus::IProxy& proxy)
: m_proxy(proxy)
{
}

RemoteDesktop_proxy(const RemoteDesktop_proxy&) = delete;
RemoteDesktop_proxy& operator=(const RemoteDesktop_proxy&) = delete;
RemoteDesktop_proxy(RemoteDesktop_proxy&&) = delete;
RemoteDesktop_proxy& operator=(RemoteDesktop_proxy&&) = delete;

~RemoteDesktop_proxy() = default;

void registerProxy()
{
}

public:
sdbus::ObjectPath CreateSession(const std::map<std::string, sdbus::Variant>& options)
{
sdbus::ObjectPath result;
m_proxy.callMethod("CreateSession").onInterface(INTERFACE_NAME).withArguments(options).storeResultsTo(result);
return result;
}

sdbus::ObjectPath SelectDevices(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options)
{
sdbus::ObjectPath result;
m_proxy.callMethod("SelectDevices").onInterface(INTERFACE_NAME).withArguments(session_handle, options).storeResultsTo(result);
return result;
}

sdbus::ObjectPath Start(const sdbus::ObjectPath& session_handle, const std::string& parent_window, const std::map<std::string, sdbus::Variant>& options)
{
sdbus::ObjectPath result;
m_proxy.callMethod("Start").onInterface(INTERFACE_NAME).withArguments(session_handle, parent_window, options).storeResultsTo(result);
return result;
}

void NotifyPointerMotion(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options, const double& dx, const double& dy)
{
m_proxy.callMethod("NotifyPointerMotion").onInterface(INTERFACE_NAME).withArguments(session_handle, options, dx, dy);
}

void NotifyPointerMotionAbsolute(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options, const uint32_t& stream, const double& x, const double& y)
{
m_proxy.callMethod("NotifyPointerMotionAbsolute").onInterface(INTERFACE_NAME).withArguments(session_handle, options, stream, x, y);
}

void NotifyPointerButton(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options, const int32_t& button, const uint32_t& state)
{
m_proxy.callMethod("NotifyPointerButton").onInterface(INTERFACE_NAME).withArguments(session_handle, options, button, state);
}

void NotifyPointerAxis(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options, const double& dx, const double& dy)
{
m_proxy.callMethod("NotifyPointerAxis").onInterface(INTERFACE_NAME).withArguments(session_handle, options, dx, dy);
}

void NotifyPointerAxisDiscrete(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options, const uint32_t& axis, const int32_t& steps)
{
m_proxy.callMethod("NotifyPointerAxisDiscrete").onInterface(INTERFACE_NAME).withArguments(session_handle, options, axis, steps);
}

void NotifyKeyboardKeycode(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options, const int32_t& keycode, const uint32_t& state)
{
m_proxy.callMethod("NotifyKeyboardKeycode").onInterface(INTERFACE_NAME).withArguments(session_handle, options, keycode, state);
}

void NotifyKeyboardKeysym(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options, const int32_t& keysym, const uint32_t& state)
{
m_proxy.callMethod("NotifyKeyboardKeysym").onInterface(INTERFACE_NAME).withArguments(session_handle, options, keysym, state);
}

void NotifyTouchDown(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options, const uint32_t& stream, const uint32_t& slot, const double& x, const double& y)
{
m_proxy.callMethod("NotifyTouchDown").onInterface(INTERFACE_NAME).withArguments(session_handle, options, stream, slot, x, y);
}

void NotifyTouchMotion(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options, const uint32_t& stream, const uint32_t& slot, const double& x, const double& y)
{
m_proxy.callMethod("NotifyTouchMotion").onInterface(INTERFACE_NAME).withArguments(session_handle, options, stream, slot, x, y);
}

void NotifyTouchUp(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options, const uint32_t& slot)
{
m_proxy.callMethod("NotifyTouchUp").onInterface(INTERFACE_NAME).withArguments(session_handle, options, slot);
}

sdbus::UnixFd ConnectToEIS(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options)
{
sdbus::UnixFd result;
m_proxy.callMethod("ConnectToEIS").onInterface(INTERFACE_NAME).withArguments(session_handle, options).storeResultsTo(result);
return result;
}

public:
uint32_t AvailableDeviceTypes()
{
return m_proxy.getProperty("AvailableDeviceTypes").onInterface(INTERFACE_NAME).get<uint32_t>();
}

uint32_t version()
{
return m_proxy.getProperty("version").onInterface(INTERFACE_NAME).get<uint32_t>();
}

private:
sdbus::IProxy& m_proxy;
};

}}} // namespaces

#endif
12 changes: 10 additions & 2 deletions include/grabber/linux/pipewire/smartPipewire.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@ struct PipewireImage
bool isOrderRgb;
uint8_t* data;
};

namespace PipewirePortal
{
constexpr int ScreenID_ScreenCast = 1;
constexpr int ScreenID_RemoteDesktop = 2;
constexpr int MinRemoteDesktopPortalVersion = 2;
}

extern "C" const char* getPipewireToken();
extern "C" const char* getPipewireError();
extern "C" bool hasPipewire();
extern "C" void initPipewireDisplay(const char* restorationToken, uint32_t requestedFPS, bool enableEGL, int targetMaxSize);
extern "C" bool hasPipewireRemoteDesktop();
extern "C" void initPipewireDisplay(const char* restorationToken, uint32_t requestedFPS, bool enableEGL, int targetMaxSize, int selectedDisplay);
extern "C" void uninitPipewireDisplay();
extern "C" PipewireImage getFramePipewire();
extern "C" void releaseFramePipewire();
extern "C" bool isRestartNeeded();

2 changes: 1 addition & 1 deletion sources/grabber/linux/pipewire/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber/linux/pipewire)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/sources/grabber/linux/pipewire)

FILE ( GLOB SMARTPIPEWIRE_SOURCES "${CURRENT_HEADER_DIR}/smartPipewire.h" "${CURRENT_HEADER_DIR}/PipewireHandler.h" "${CURRENT_HEADER_DIR}/ScreenCastProxy.h" "${CURRENT_SOURCE_DIR}/smartPipewire.cpp" "${CURRENT_SOURCE_DIR}/PipewireHandler.cpp" )
FILE ( GLOB SMARTPIPEWIRE_SOURCES "${CURRENT_HEADER_DIR}/smartPipewire.h" "${CURRENT_HEADER_DIR}/PipewireHandler.h" "${CURRENT_HEADER_DIR}/ScreenCastProxy.h" "${CURRENT_HEADER_DIR}/RemoteDesktopProxy.h" "${CURRENT_SOURCE_DIR}/smartPipewire.cpp" "${CURRENT_SOURCE_DIR}/PipewireHandler.cpp" )

add_library(smart-pipewire SHARED ${SMARTPIPEWIRE_SOURCES} )

Expand Down
28 changes: 21 additions & 7 deletions sources/grabber/linux/pipewire/PipewireGrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ namespace
{
bool (*_hasPipewire)() = nullptr;
const char* (*_getPipewireError)() = nullptr;
void (*_initPipewireDisplay)(const char* restorationToken, uint32_t requestedFPS, bool enableEGL, int targetMaxSize) = nullptr;
void (*_initPipewireDisplay)(const char* restorationToken, uint32_t requestedFPS, bool enableEGL, int targetMaxSize, int selectedDisplay) = nullptr;
void (*_uninitPipewireDisplay)() = nullptr;
PipewireImage(*_getFramePipewire)() = nullptr;
void (*_releaseFramePipewire)() = nullptr;
const char* (*_getPipewireToken)() = nullptr;
bool (*_isRestartNeeded)() = nullptr;
bool (*_hasPipewireRemoteDesktop)() = nullptr;
}

PipewireGrabber::PipewireGrabber(const QString& device, const QString& configurationPath)
Expand Down Expand Up @@ -88,17 +89,19 @@ PipewireGrabber::PipewireGrabber(const QString& device, const QString& configura
_getPipewireToken = (const char* (*)()) dlsym(_library, "getPipewireToken");
_getPipewireError = (const char* (*)()) dlsym(_library, "getPipewireError");
_hasPipewire = (bool (*)()) dlsym(_library, "hasPipewire");
_initPipewireDisplay = (void (*)(const char*, uint32_t, bool, int)) dlsym(_library, "initPipewireDisplay");
_initPipewireDisplay = (void (*)(const char*, uint32_t, bool, int, int)) dlsym(_library, "initPipewireDisplay");
_uninitPipewireDisplay = (void (*)()) dlsym(_library, "uninitPipewireDisplay");
_getFramePipewire = (PipewireImage (*)()) dlsym(_library, "getFramePipewire");
_releaseFramePipewire = (void (*)()) dlsym(_library, "releaseFramePipewire");
_isRestartNeeded = (bool (*)()) dlsym(_library, "isRestartNeeded");
_hasPipewireRemoteDesktop = (bool (*)()) dlsym(_library, "hasPipewireRemoteDesktop");
}
else
Warning(_log, "Could not load Pipewire proxy library. Error: {:s}", dlerror());

if (_library && (_getPipewireToken == nullptr || _hasPipewire == nullptr || _releaseFramePipewire == nullptr ||
_initPipewireDisplay == nullptr || _uninitPipewireDisplay == nullptr || _getFramePipewire == nullptr || _isRestartNeeded == nullptr))
_initPipewireDisplay == nullptr || _uninitPipewireDisplay == nullptr || _getFramePipewire == nullptr || _isRestartNeeded == nullptr ||
_hasPipewireRemoteDesktop == nullptr))
{
Error(_log, "Could not load Pipewire proxy library definition. Error: {:s}", dlerror());

Expand Down Expand Up @@ -264,11 +267,22 @@ void PipewireGrabber::enumerateDevices(bool silent)
DeviceProperties properties;
DevicePropertiesItem dpi;

QString id = "Pipewire System Dialog selection";
dpi.input = 1;
QString id = "Pipewire System Dialog selection (ScreenCast API)";
dpi.input = PipewirePortal::ScreenID_ScreenCast;
properties.valid.append(dpi);

_deviceProperties.insert(id, properties);
_deviceProperties.insert(id, properties);

if (_hasPipewireRemoteDesktop())
{
DeviceProperties remoteProperties;
DevicePropertiesItem remoteDpi;

remoteDpi.input = PipewirePortal::ScreenID_RemoteDesktop;
remoteProperties.valid.append(remoteDpi);

_deviceProperties.insert("Pipewire All Screens (RemoteDesktop API)", remoteProperties);
}
}
}

Expand Down Expand Up @@ -322,7 +336,7 @@ bool PipewireGrabber::init_device(int _display)
token = "";
else
Info(_log, "Loading restoration token: {:s}", (maskToken(token)));
_initPipewireDisplay(token.toLatin1().constData(), _fps, _hardware, _width);
_initPipewireDisplay(token.toLatin1().constData(), _fps, _hardware, _width, _actualDisplay);

return true;
}
Expand Down
Loading