Skip to content

Commit

Permalink
Remove Qt D-Bus, switch to sdbus-c++
Browse files Browse the repository at this point in the history
  • Loading branch information
awawa-dev committed May 24, 2024
1 parent aa20079 commit c469c6d
Show file tree
Hide file tree
Showing 10 changed files with 677 additions and 18 deletions.
3 changes: 2 additions & 1 deletion .github/actions/codeql/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ runs:
python3-minimal \
qtbase5-dev \
qdbus-qt5 \
rpm
rpm \
libsystemd-dev
- name: Checkout repository
uses: actions/checkout@v4
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@
[submodule "external/lunasvg"]
path = external/lunasvg
url = https://github.com/sammycage/lunasvg.git
[submodule "external/sdbus-cpp"]
path = external/sdbus-cpp
url = https://github.com/Kistler-Group/sdbus-cpp
509 changes: 509 additions & 0 deletions 3RD_PARTY_LICENSES

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -493,11 +493,10 @@ if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
endif()
if(COMPILER_SUPPORTS_CXX17 AND Qt_VERSION EQUAL 6)
message(STATUS "Enabling support for C++17 for QT6")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(CMAKE_CXX_STANDARD 17)
elseif(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
message(STATUS "Enabling support for C++11")
set(CMAKE_CXX_STANDARD 11)
else()
message(STATUS "No support for C++11 detected. Compilation will most likely fail on your compiler")
endif()
Expand Down
14 changes: 14 additions & 0 deletions external/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ if ( ENABLE_MQTT )
endif()
endif()

#=============================================================================
# XZ
#=============================================================================

if ( ENABLE_XZ )
option(BUILD_TESTING "" OFF)
if (NOT LIBLZMA_FOUND)
Expand All @@ -200,3 +204,13 @@ if ( ENABLE_XZ )
endif()
endif()
ENDIF()

#=============================================================================
# sdbus-cpp
#=============================================================================

if (UNIX AND NOT APPLE AND (ENABLE_POWER_MANAGEMENT OR ENABLE_PIPEWIRE))
set(SDBUSCPP_BUILD_DOCS OFF CACHE BOOL "No doc")
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/sdbus-cpp)
set_target_properties(sdbus-c++-objlib PROPERTIES POSITION_INDEPENDENT_CODE ON)
endif()
1 change: 1 addition & 0 deletions external/sdbus-cpp
Submodule sdbus-cpp added at b7d85f
9 changes: 9 additions & 0 deletions include/grabber/pipewire/PipewireHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <grabber/pipewire/smartPipewire.h>
#include <linux/types.h>
#include <HyperhdrConfig.h>
#include <memory>

#if !PW_CHECK_VERSION(0, 3, 29)
#define SPA_POD_PROP_FLAG_MANDATORY (1u << 3)
Expand Down Expand Up @@ -64,6 +65,11 @@ typedef void (*glTexParameteriFun)(GLenum target, GLenum pname, GLint param);
#define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4')
#endif

namespace sdbus{
class IConnection;
}
class ScreenCastProxy;

class PipewireHandler : public QObject
{
Q_OBJECT
Expand Down Expand Up @@ -155,6 +161,9 @@ public Q_SLOTS:

MemoryBuffer<uint8_t> _memoryCache;

std::unique_ptr<sdbus::IConnection> _dbusConnection;
std::unique_ptr<ScreenCastProxy> _screenCastProxy;

#ifdef ENABLE_PIPEWIRE_EGL
eglGetProcAddressFun eglGetProcAddress = nullptr;
eglInitializeFun eglInitialize = nullptr;
Expand Down
90 changes: 90 additions & 0 deletions include/grabber/pipewire/ScreenCastProxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@

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

#ifndef __sdbuscpp__ScreenCastProxy_h__proxy__H__
#define __sdbuscpp__ScreenCastProxy_h__proxy__H__

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

namespace org {
namespace freedesktop {
namespace portal {

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

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

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

~ScreenCast_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 SelectSources(const sdbus::ObjectPath& session_handle, const std::map<std::string, sdbus::Variant>& options)
{
sdbus::ObjectPath result;
m_proxy.callMethod("SelectSources").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;
}

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

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

uint32_t AvailableCursorModes()
{
return m_proxy.getProperty("AvailableCursorModes").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
5 changes: 3 additions & 2 deletions sources/grabber/pipewire/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber/pipewire)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/sources/grabber/pipewire)

FILE ( GLOB SMARTPIPEWIRE_SOURCES "${CURRENT_HEADER_DIR}/smartPipewire.h" "${CURRENT_HEADER_DIR}/PipewireHandler.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_SOURCE_DIR}/smartPipewire.cpp" "${CURRENT_SOURCE_DIR}/PipewireHandler.cpp" )

add_library(smartPipewire SHARED ${SMARTPIPEWIRE_SOURCES} )

# Pipewire
target_include_directories(smartPipewire PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${PIPEWIRE_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${OPENGL_EGL_INCLUDE_DIRS} )
target_link_libraries(smartPipewire PUBLIC ${PIPEWIRE_LIBRARIES} Qt${Qt_VERSION}::Core Qt${Qt_VERSION}::DBus )
target_link_libraries(smartPipewire PUBLIC ${PIPEWIRE_LIBRARIES} Qt${Qt_VERSION}::Core Qt${Qt_VERSION}::DBus sdbus-c++)
set_property(TARGET smartPipewire PROPERTY CXX_STANDARD 17)

# Grabber
FILE ( GLOB PIPEWIRE_SOURCES "${CURRENT_HEADER_DIR}/smartPipewire.h" "${CURRENT_HEADER_DIR}/PipewireGrabber.h" "${CURRENT_HEADER_DIR}/PipewireWrapper.h"
Expand Down
54 changes: 43 additions & 11 deletions sources/grabber/pipewire/PipewireHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,25 @@

#include <grabber/pipewire/smartPipewire.h>
#include <grabber/pipewire/PipewireHandler.h>
#include <grabber/pipewire/ScreenCastProxy.h>

using namespace sdbus;
using namespace org::freedesktop::portal;

class ScreenCastProxy final : public sdbus::ProxyInterfaces<org::freedesktop::portal::ScreenCast_proxy>
{
public:
ScreenCastProxy(sdbus::IConnection& connection, sdbus::ServiceName destination, sdbus::ObjectPath path)
: ProxyInterfaces(connection, std::move(destination), std::move(path))
{
registerProxy();
}

~ScreenCastProxy()
{
unregisterProxy();
}
};

// Pipewire screen grabber using Portal access interface

Expand All @@ -82,7 +101,7 @@ const QString REQUEST_TEMPLATE = QStringLiteral("/org/freedesktop/portal/desktop

PipewireHandler::PipewireHandler() :
_sessionHandle(""), _restorationToken(""), _errorMessage(""), _portalStatus(false),
_isError(false), _version(0), _streamNodeId(0),
_isError(false), _version(-1), _streamNodeId(0),
_sender(""), _replySessionPath(""), _sourceReplyPath(""), _startReplyPath(""),
_pwMainThreadLoop(nullptr), _pwNewContext(nullptr), _pwContextConnection(nullptr), _pwStream(nullptr),
_frameWidth(0),_frameHeight(0),_frameOrderRgb(false), _framePaused(false), _requestedFPS(10), _hasFrame(false),
Expand All @@ -95,6 +114,19 @@ PipewireHandler::PipewireHandler() :
qRegisterMetaType<uint32_t>();
qRegisterMetaType<pw_stream_state>();

try
{
_dbusConnection = sdbus::createSessionBusConnection();
_screenCastProxy = std::make_unique<ScreenCastProxy>(*_dbusConnection, ServiceName{ "org.freedesktop.portal.Desktop" }, ObjectPath{ "/org/freedesktop/portal/desktop" });

_version = _screenCastProxy->version();
}
catch(std::exception& e)
{
std::cout << "Pipewire: could not read Portal ScreenCast version" << std::endl;
_version = -1;
}

connect(this, &PipewireHandler::onParamsChangedSignal, this, &PipewireHandler::onParamsChanged);
connect(this, &PipewireHandler::onStateChangedSignal, this, &PipewireHandler::onStateChanged);
connect(this, &PipewireHandler::onProcessFrameSignal, this, &PipewireHandler::onProcessFrame);
Expand Down Expand Up @@ -241,11 +273,7 @@ void PipewireHandler::closeSession()

createMemory(0);

if (_version > 0)
{
std::cout << "Pipewire: driver is closed now" << std::endl;
_version = 0;
}
std::cout << "Pipewire: driver is closed now" << std::endl;
}

void PipewireHandler::releaseWorkingFrame()
Expand Down Expand Up @@ -283,12 +311,17 @@ int PipewireHandler::readVersion()
{
int version = -1;

QDBusInterface iface(DESKTOP_SERVICE, DESKTOP_PATH, DESKTOP_SCREENCAST);
try
{
auto bus = sdbus::createSessionBusConnection();
auto proxy = std::make_unique<ScreenCastProxy>(*bus, ServiceName{ "org.freedesktop.portal.Desktop" }, ObjectPath{ "/org/freedesktop/portal/desktop" });

if (iface.property("version").isValid())
version = proxy->version();
}
catch (std::exception& e)
{
version = iface.property("version").toInt();
std::cout << "PipewireHandler: ScreenCast protocol version: " << qPrintable(QString("%1").arg(version)) << std::endl;
std::cout << "Pipewire: could not read Portal ScreenCast version" << std::endl;
version = -1;
}

return version;
Expand All @@ -308,7 +341,6 @@ void PipewireHandler::startSession(QString restorationToken, uint32_t requestedF

_restorationToken = QString("%1").arg(restorationToken);

_version = PipewireHandler::readVersion();
_image.version = _version;

if (_version < 0)
Expand Down

0 comments on commit c469c6d

Please sign in to comment.