Skip to content

Commit

Permalink
basic groundwork for pw
Browse files Browse the repository at this point in the history
  • Loading branch information
vaxerski committed Aug 26, 2023
1 parent 3adac24 commit b32c560
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 4 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ add_subdirectory(subprojects/sdbus-cpp)
find_package(Threads 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")
add_executable(xdg-desktop-portal-hyprland ${SRCFILES})
Expand Down
15 changes: 14 additions & 1 deletion src/core/PortalManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <protocols/wlr-foreign-toplevel-management-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) {
g_pPortalManager->onGlobal(data, registry, name, interface, version);
}
Expand All @@ -26,7 +28,7 @@ void CPortalManager::onGlobal(void* data, struct wl_registry* registry, uint32_t

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));
}

Expand Down Expand Up @@ -58,10 +60,19 @@ void CPortalManager::init() {
wl_registry* registry = wl_display_get_registry(m_sWaylandConnection.display);
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");

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) {
// dbus events
while (m_pConnection->processPendingRequest()) {
Expand All @@ -77,6 +88,8 @@ void CPortalManager::init() {
break;
}

// TODO: pipewire loop

std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/core/PortalManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include "../portals/Screencopy.hpp"

struct pw_loop;

class CPortalManager {
public:
void init();
Expand All @@ -14,6 +16,10 @@ class CPortalManager {

sdbus::IConnection* getConnection();

struct {
pw_loop* loop = nullptr;
} m_sPipewire;

private:
std::unique_ptr<sdbus::IConnection> m_pConnection;

Expand Down
35 changes: 35 additions & 0 deletions src/portals/Screencopy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "../helpers/Log.hpp"
#include "../helpers/MiscFunctions.hpp"

#include <pipewire/pipewire.h>

void onCloseRequest(sdbus::MethodCall& call, CScreencopyPortal::SSession* sess) {
if (!sess || !sess->request)
return;
Expand Down Expand Up @@ -197,6 +199,7 @@ void CScreencopyPortal::onStart(sdbus::MethodCall& call) {
case TYPE_WINDOW: type = 1 << WINDOW; break;
case TYPE_GEOMETRY:
case TYPE_WORKSPACE: type = 1 << VIRTUAL; break;
default: type = 0; break;
}
options["source_type"] = type;

Expand Down Expand Up @@ -226,5 +229,37 @@ CScreencopyPortal::CScreencopyPortal(zwlr_screencopy_manager_v1* mgr) {

m_pObject->finishRegistration();

m_sState.screencopy = mgr;
m_pPipewire = std::make_unique<CPipewireConnection>();

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);
}
25 changes: 23 additions & 2 deletions src/portals/Screencopy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ enum sourceTypes
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 {
public:
CScreencopyPortal(zwlr_screencopy_manager_v1*);
Expand Down Expand Up @@ -46,6 +61,12 @@ class CScreencopyPortal {

SSession* getSession(sdbus::ObjectPath& path);

const std::string INTERFACE_NAME = "org.freedesktop.impl.portal.ScreenCast";
const std::string OBJECT_PATH = "/org/freedesktop/portal/desktop";
std::unique_ptr<CPipewireConnection> m_pPipewire;

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";
};

0 comments on commit b32c560

Please sign in to comment.