mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-12-26 03:19:48 +01:00
basic groundwork for pw
This commit is contained in:
parent
3adac247f2
commit
b32c560b31
5 changed files with 79 additions and 4 deletions
|
@ -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})
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -58,10 +60,19 @@ void CPortalManager::init() {
|
|||
wl_registry* registry = wl_display_get_registry(m_sWaylandConnection.display);
|
||||
wl_registry_add_listener(registry, ®istryListener, 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()) {
|
||||
|
@ -77,6 +88,8 @@ void CPortalManager::init() {
|
|||
break;
|
||||
}
|
||||
|
||||
// TODO: pipewire loop
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "../portals/Screencopy.hpp"
|
||||
|
||||
struct pw_loop;
|
||||
|
||||
class CPortalManager {
|
||||
public:
|
||||
void init();
|
||||
|
@ -14,6 +16,10 @@ class CPortalManager {
|
|||
|
||||
sdbus::IConnection* getConnection();
|
||||
|
||||
struct {
|
||||
pw_loop* loop = nullptr;
|
||||
} m_sPipewire;
|
||||
|
||||
private:
|
||||
std::unique_ptr<sdbus::IConnection> m_pConnection;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
|
@ -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*);
|
||||
|
@ -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";
|
||||
};
|
Loading…
Reference in a new issue