basic groundwork for pw

This commit is contained in:
vaxerski 2023-08-27 00:32:18 +02:00
parent 3adac247f2
commit b32c560b31
5 changed files with 79 additions and 4 deletions

View file

@ -29,7 +29,7 @@ add_subdirectory(subprojects/sdbus-cpp)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-protocols cairo pango pangocairo libjpeg) pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-protocols cairo pango pangocairo libjpeg libpipewire-0.3 libspa-0.2)
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp") file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp")
add_executable(xdg-desktop-portal-hyprland ${SRCFILES}) add_executable(xdg-desktop-portal-hyprland ${SRCFILES})

View file

@ -6,6 +6,8 @@
#include <protocols/wlr-foreign-toplevel-management-unstable-v1-protocol.h> #include <protocols/wlr-foreign-toplevel-management-unstable-v1-protocol.h>
#include <protocols/wlr-screencopy-unstable-v1-protocol.h> #include <protocols/wlr-screencopy-unstable-v1-protocol.h>
#include <pipewire/pipewire.h>
void handleGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version) { void handleGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version) {
g_pPortalManager->onGlobal(data, registry, name, interface, version); g_pPortalManager->onGlobal(data, registry, name, interface, version);
} }
@ -26,7 +28,7 @@ void CPortalManager::onGlobal(void* data, struct wl_registry* registry, uint32_t
Debug::log(LOG, " | Got interface: {} (ver {})", INTERFACE, version); Debug::log(LOG, " | Got interface: {} (ver {})", INTERFACE, version);
if (INTERFACE == zwlr_screencopy_manager_v1_interface.name) if (INTERFACE == zwlr_screencopy_manager_v1_interface.name && m_sPipewire.loop)
m_sPortals.screencopy = std::make_unique<CScreencopyPortal>((zwlr_screencopy_manager_v1*)wl_registry_bind(registry, name, &zwlr_screencopy_manager_v1_interface, version)); m_sPortals.screencopy = std::make_unique<CScreencopyPortal>((zwlr_screencopy_manager_v1*)wl_registry_bind(registry, name, &zwlr_screencopy_manager_v1_interface, version));
} }
@ -58,10 +60,19 @@ void CPortalManager::init() {
wl_registry* registry = wl_display_get_registry(m_sWaylandConnection.display); wl_registry* registry = wl_display_get_registry(m_sWaylandConnection.display);
wl_registry_add_listener(registry, &registryListener, nullptr); wl_registry_add_listener(registry, &registryListener, nullptr);
pw_init(nullptr, nullptr);
m_sPipewire.loop = pw_loop_new(nullptr);
if (!m_sPipewire.loop)
Debug::log(ERR, "Pipewire: refused to create a loop. Screensharing will not work.");
Debug::log(LOG, "Gathering exported interfaces"); Debug::log(LOG, "Gathering exported interfaces");
wl_display_roundtrip(m_sWaylandConnection.display); wl_display_roundtrip(m_sWaylandConnection.display);
if (!m_sPortals.screencopy)
Debug::log(WARN, "Screencopy not started: compositor doesn't support zwlr_screencopy_v1 or pw refused a loop");
while (1) { while (1) {
// dbus events // dbus events
while (m_pConnection->processPendingRequest()) { while (m_pConnection->processPendingRequest()) {
@ -77,6 +88,8 @@ void CPortalManager::init() {
break; break;
} }
// TODO: pipewire loop
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
} }

View file

@ -6,6 +6,8 @@
#include "../portals/Screencopy.hpp" #include "../portals/Screencopy.hpp"
struct pw_loop;
class CPortalManager { class CPortalManager {
public: public:
void init(); void init();
@ -14,6 +16,10 @@ class CPortalManager {
sdbus::IConnection* getConnection(); sdbus::IConnection* getConnection();
struct {
pw_loop* loop = nullptr;
} m_sPipewire;
private: private:
std::unique_ptr<sdbus::IConnection> m_pConnection; std::unique_ptr<sdbus::IConnection> m_pConnection;

View file

@ -3,6 +3,8 @@
#include "../helpers/Log.hpp" #include "../helpers/Log.hpp"
#include "../helpers/MiscFunctions.hpp" #include "../helpers/MiscFunctions.hpp"
#include <pipewire/pipewire.h>
void onCloseRequest(sdbus::MethodCall& call, CScreencopyPortal::SSession* sess) { void onCloseRequest(sdbus::MethodCall& call, CScreencopyPortal::SSession* sess) {
if (!sess || !sess->request) if (!sess || !sess->request)
return; return;
@ -197,6 +199,7 @@ void CScreencopyPortal::onStart(sdbus::MethodCall& call) {
case TYPE_WINDOW: type = 1 << WINDOW; break; case TYPE_WINDOW: type = 1 << WINDOW; break;
case TYPE_GEOMETRY: case TYPE_GEOMETRY:
case TYPE_WORKSPACE: type = 1 << VIRTUAL; break; case TYPE_WORKSPACE: type = 1 << VIRTUAL; break;
default: type = 0; break;
} }
options["source_type"] = type; options["source_type"] = type;
@ -226,5 +229,37 @@ CScreencopyPortal::CScreencopyPortal(zwlr_screencopy_manager_v1* mgr) {
m_pObject->finishRegistration(); m_pObject->finishRegistration();
m_sState.screencopy = mgr;
m_pPipewire = std::make_unique<CPipewireConnection>();
Debug::log(LOG, "[screencopy] init successful"); Debug::log(LOG, "[screencopy] init successful");
} }
bool CPipewireConnection::good() {
return m_pContext && m_pCore;
}
CPipewireConnection::CPipewireConnection() {
m_pContext = pw_context_new(g_pPortalManager->m_sPipewire.loop, nullptr, 0);
if (!m_pContext) {
Debug::log(ERR, "[pipewire] pw didn't allow for a context");
return;
}
m_pCore = pw_context_connect(m_pContext, nullptr, 0);
if (!m_pCore) {
Debug::log(ERR, "[pipewire] pw didn't allow for a context connection");
return;
}
Debug::log(LOG, "[pipewire] connected");
}
CPipewireConnection::~CPipewireConnection() {
if (m_pCore)
pw_core_disconnect(m_pCore);
if (m_pContext)
pw_context_destroy(m_pContext);
}

View file

@ -18,6 +18,21 @@ enum sourceTypes
VIRTUAL = 4, VIRTUAL = 4,
}; };
struct pw_context;
struct pw_core;
class CPipewireConnection {
public:
CPipewireConnection();
~CPipewireConnection();
bool good();
private:
pw_context* m_pContext = nullptr;
pw_core* m_pCore = nullptr;
};
class CScreencopyPortal { class CScreencopyPortal {
public: public:
CScreencopyPortal(zwlr_screencopy_manager_v1*); CScreencopyPortal(zwlr_screencopy_manager_v1*);
@ -46,6 +61,12 @@ class CScreencopyPortal {
SSession* getSession(sdbus::ObjectPath& path); SSession* getSession(sdbus::ObjectPath& path);
const std::string INTERFACE_NAME = "org.freedesktop.impl.portal.ScreenCast"; std::unique_ptr<CPipewireConnection> m_pPipewire;
const std::string OBJECT_PATH = "/org/freedesktop/portal/desktop";
struct {
zwlr_screencopy_manager_v1* screencopy = nullptr;
} m_sState;
const std::string INTERFACE_NAME = "org.freedesktop.impl.portal.ScreenCast";
const std::string OBJECT_PATH = "/org/freedesktop/portal/desktop";
}; };