0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 04:42:18 +02:00

linux-pipewire: Move portal signal subcription to portal.c

The D-Bus signal subscription is a very boring aspect of the
portals infrastructure that shouldn't really matter when reading
the code of pipewire.c.

Move it out to its natural place, portal.c.
This commit is contained in:
Georges Basile Stavracas Neto 2022-07-01 21:53:48 -03:00 committed by Georges Basile Stavracas Neto
parent 15b8c5b743
commit 549c0f5850
3 changed files with 106 additions and 120 deletions

View File

@ -23,6 +23,15 @@
#include <util/dstr.h> #include <util/dstr.h>
struct portal_signal_call {
GCancellable *cancellable;
portal_signal_callback callback;
gpointer user_data;
char *request_path;
guint signal_id;
gulong cancelled_id;
};
#define REQUEST_PATH "/org/freedesktop/portal/desktop/request/%s/obs%u" #define REQUEST_PATH "/org/freedesktop/portal/desktop/request/%s/obs%u"
#define SESSION_PATH "/org/freedesktop/portal/desktop/session/%s/obs%u" #define SESSION_PATH "/org/freedesktop/portal/desktop/session/%s/obs%u"
@ -121,3 +130,77 @@ void portal_create_session_path(char **out_path, char **out_token)
bfree(sender_name); bfree(sender_name);
} }
} }
static void portal_signal_call_free(struct portal_signal_call *call)
{
if (call->signal_id)
g_dbus_connection_signal_unsubscribe(
portal_get_dbus_connection(), call->signal_id);
if (call->cancelled_id > 0)
g_signal_handler_disconnect(call->cancellable,
call->cancelled_id);
g_clear_pointer(&call->request_path, bfree);
bfree(call);
}
static void on_cancelled_cb(GCancellable *cancellable, void *data)
{
UNUSED_PARAMETER(cancellable);
struct portal_signal_call *call = data;
blog(LOG_INFO, "[portals] Request cancelled");
g_dbus_connection_call(
portal_get_dbus_connection(), "org.freedesktop.portal.Desktop",
call->request_path, "org.freedesktop.portal.Request", "Close",
NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
portal_signal_call_free(call);
}
static void on_response_received_cb(GDBusConnection *connection,
const char *sender_name,
const char *object_path,
const char *interface_name,
const char *signal_name,
GVariant *parameters, void *user_data)
{
UNUSED_PARAMETER(connection);
UNUSED_PARAMETER(sender_name);
UNUSED_PARAMETER(object_path);
UNUSED_PARAMETER(interface_name);
UNUSED_PARAMETER(signal_name);
struct portal_signal_call *call = user_data;
if (call->callback)
call->callback(parameters, call->user_data);
portal_signal_call_free(call);
}
void portal_signal_subscribe(const char *path, GCancellable *cancellable,
portal_signal_callback callback,
gpointer user_data)
{
struct portal_signal_call *call;
call = bzalloc(sizeof(struct portal_signal_call));
call->request_path = bstrdup(path);
call->callback = callback;
call->user_data = user_data;
call->cancellable = cancellable ? g_object_ref(cancellable) : NULL;
call->cancelled_id =
cancellable
? g_signal_connect(cancellable, "cancelled",
G_CALLBACK(on_cancelled_cb), call)
: 0;
call->signal_id = g_dbus_connection_signal_subscribe(
portal_get_dbus_connection(), "org.freedesktop.portal.Desktop",
"org.freedesktop.portal.Request", "Response",
call->request_path, NULL, G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
on_response_received_cb, call, NULL);
}

View File

@ -23,7 +23,12 @@
#include <stdint.h> #include <stdint.h>
#include <gio/gio.h> #include <gio/gio.h>
typedef void (*portal_signal_callback)(GVariant *parameters, void *user_data);
GDBusConnection *portal_get_dbus_connection(void); GDBusConnection *portal_get_dbus_connection(void);
void portal_create_request_path(char **out_path, char **out_token); void portal_create_request_path(char **out_path, char **out_token);
void portal_create_session_path(char **out_path, char **out_token); void portal_create_session_path(char **out_path, char **out_token);
void portal_signal_subscribe(const char *path, GCancellable *cancellable,
portal_signal_callback callback, void *user_data);

View File

@ -139,13 +139,6 @@ static uint32_t get_screencast_version(void)
/* ------------------------------------------------- */ /* ------------------------------------------------- */
struct dbus_call_data {
struct screencast_portal_capture *capture;
char *request_path;
guint signal_id;
gulong cancelled_id;
};
static const char *capture_type_to_string(enum portal_capture_type capture_type) static const char *capture_type_to_string(enum portal_capture_type capture_type)
{ {
switch (capture_type) { switch (capture_type) {
@ -160,58 +153,6 @@ static const char *capture_type_to_string(enum portal_capture_type capture_type)
return "unknown"; return "unknown";
} }
static void on_cancelled_cb(GCancellable *cancellable, void *data)
{
UNUSED_PARAMETER(cancellable);
struct dbus_call_data *call = data;
blog(LOG_INFO, "[pipewire] Screencast session cancelled");
g_dbus_connection_call(
portal_get_dbus_connection(), "org.freedesktop.portal.Desktop",
call->request_path, "org.freedesktop.portal.Request", "Close",
NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
}
static struct dbus_call_data *
subscribe_to_signal(struct screencast_portal_capture *capture, const char *path,
GDBusSignalCallback callback)
{
struct dbus_call_data *call;
call = bzalloc(sizeof(struct dbus_call_data));
call->capture = capture;
call->request_path = bstrdup(path);
call->cancelled_id = g_signal_connect(capture->cancellable, "cancelled",
G_CALLBACK(on_cancelled_cb),
call);
call->signal_id = g_dbus_connection_signal_subscribe(
portal_get_dbus_connection(), "org.freedesktop.portal.Desktop",
"org.freedesktop.portal.Request", "Response",
call->request_path, NULL, G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
callback, call, NULL);
return call;
}
static void dbus_call_data_free(struct dbus_call_data *call)
{
if (!call)
return;
if (call->signal_id)
g_dbus_connection_signal_unsubscribe(
portal_get_dbus_connection(), call->signal_id);
if (call->cancelled_id > 0)
g_signal_handler_disconnect(call->capture->cancellable,
call->cancelled_id);
g_clear_pointer(&call->request_path, bfree);
bfree(call);
}
/* ------------------------------------------------- */ /* ------------------------------------------------- */
static void on_pipewire_remote_opened_cb(GObject *source, GAsyncResult *res, static void on_pipewire_remote_opened_cb(GObject *source, GAsyncResult *res,
@ -276,31 +217,16 @@ static void open_pipewire_remote(struct screencast_portal_capture *capture)
/* ------------------------------------------------- */ /* ------------------------------------------------- */
static void on_start_response_received_cb(GDBusConnection *connection, static void on_start_response_received_cb(GVariant *parameters, void *user_data)
const char *sender_name,
const char *object_path,
const char *interface_name,
const char *signal_name,
GVariant *parameters, void *user_data)
{ {
UNUSED_PARAMETER(connection); struct screencast_portal_capture *capture = user_data;
UNUSED_PARAMETER(sender_name);
UNUSED_PARAMETER(object_path);
UNUSED_PARAMETER(interface_name);
UNUSED_PARAMETER(signal_name);
struct screencast_portal_capture *capture;
g_autoptr(GVariant) stream_properties = NULL; g_autoptr(GVariant) stream_properties = NULL;
g_autoptr(GVariant) streams = NULL; g_autoptr(GVariant) streams = NULL;
g_autoptr(GVariant) result = NULL; g_autoptr(GVariant) result = NULL;
struct dbus_call_data *call = user_data;
GVariantIter iter; GVariantIter iter;
uint32_t response; uint32_t response;
size_t n_streams; size_t n_streams;
capture = call->capture;
g_clear_pointer(&call, dbus_call_data_free);
g_variant_get(parameters, "(u@a{sv})", &response, &result); g_variant_get(parameters, "(u@a{sv})", &response, &result);
if (response != 0) { if (response != 0) {
@ -378,7 +304,6 @@ static void on_started_cb(GObject *source, GAsyncResult *res, void *user_data)
static void start(struct screencast_portal_capture *capture) static void start(struct screencast_portal_capture *capture)
{ {
GVariantBuilder builder; GVariantBuilder builder;
struct dbus_call_data *call;
char *request_token; char *request_token;
char *request_path; char *request_path;
@ -387,8 +312,8 @@ static void start(struct screencast_portal_capture *capture)
blog(LOG_INFO, "[pipewire] Asking for %s", blog(LOG_INFO, "[pipewire] Asking for %s",
capture_type_to_string(capture->capture_type)); capture_type_to_string(capture->capture_type));
call = subscribe_to_signal(capture, request_path, portal_signal_subscribe(request_path, capture->cancellable,
on_start_response_received_cb); on_start_response_received_cb, capture);
g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add(&builder, "{sv}", "handle_token", g_variant_builder_add(&builder, "{sv}", "handle_token",
@ -398,7 +323,7 @@ static void start(struct screencast_portal_capture *capture)
g_variant_new("(osa{sv})", capture->session_handle, g_variant_new("(osa{sv})", capture->session_handle,
"", &builder), "", &builder),
G_DBUS_CALL_FLAGS_NONE, -1, capture->cancellable, G_DBUS_CALL_FLAGS_NONE, -1, capture->cancellable,
on_started_cb, call); on_started_cb, NULL);
bfree(request_token); bfree(request_token);
bfree(request_path); bfree(request_path);
@ -406,28 +331,15 @@ static void start(struct screencast_portal_capture *capture)
/* ------------------------------------------------- */ /* ------------------------------------------------- */
static void on_select_source_response_received_cb( static void on_select_source_response_received_cb(GVariant *parameters,
GDBusConnection *connection, const char *sender_name, void *user_data)
const char *object_path, const char *interface_name,
const char *signal_name, GVariant *parameters, void *user_data)
{ {
UNUSED_PARAMETER(connection); struct screencast_portal_capture *capture = user_data;
UNUSED_PARAMETER(sender_name);
UNUSED_PARAMETER(object_path);
UNUSED_PARAMETER(interface_name);
UNUSED_PARAMETER(signal_name);
struct screencast_portal_capture *capture;
g_autoptr(GVariant) ret = NULL; g_autoptr(GVariant) ret = NULL;
struct dbus_call_data *call = user_data;
uint32_t response; uint32_t response;
capture = call->capture;
blog(LOG_DEBUG, "[pipewire] Response to select source received"); blog(LOG_DEBUG, "[pipewire] Response to select source received");
g_clear_pointer(&call, dbus_call_data_free);
g_variant_get(parameters, "(u@a{sv})", &response, &ret); g_variant_get(parameters, "(u@a{sv})", &response, &ret);
if (response != 0) { if (response != 0) {
@ -459,7 +371,6 @@ static void on_source_selected_cb(GObject *source, GAsyncResult *res,
static void select_source(struct screencast_portal_capture *capture) static void select_source(struct screencast_portal_capture *capture)
{ {
struct dbus_call_data *call;
GVariantBuilder builder; GVariantBuilder builder;
uint32_t available_cursor_modes; uint32_t available_cursor_modes;
char *request_token; char *request_token;
@ -467,8 +378,8 @@ static void select_source(struct screencast_portal_capture *capture)
portal_create_request_path(&request_path, &request_token); portal_create_request_path(&request_path, &request_token);
call = subscribe_to_signal(capture, request_path, portal_signal_subscribe(request_path, capture->cancellable,
on_select_source_response_received_cb); on_select_source_response_received_cb, capture);
g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add(&builder, "{sv}", "types", g_variant_builder_add(&builder, "{sv}", "types",
@ -508,7 +419,7 @@ static void select_source(struct screencast_portal_capture *capture)
g_variant_new("(oa{sv})", capture->session_handle, g_variant_new("(oa{sv})", capture->session_handle,
&builder), &builder),
G_DBUS_CALL_FLAGS_NONE, -1, capture->cancellable, G_DBUS_CALL_FLAGS_NONE, -1, capture->cancellable,
on_source_selected_cb, call); on_source_selected_cb, NULL);
bfree(request_token); bfree(request_token);
bfree(request_path); bfree(request_path);
@ -516,27 +427,14 @@ static void select_source(struct screencast_portal_capture *capture)
/* ------------------------------------------------- */ /* ------------------------------------------------- */
static void on_create_session_response_received_cb( static void on_create_session_response_received_cb(GVariant *parameters,
GDBusConnection *connection, const char *sender_name, void *user_data)
const char *object_path, const char *interface_name,
const char *signal_name, GVariant *parameters, void *user_data)
{ {
UNUSED_PARAMETER(connection); struct screencast_portal_capture *capture = user_data;
UNUSED_PARAMETER(sender_name);
UNUSED_PARAMETER(object_path);
UNUSED_PARAMETER(interface_name);
UNUSED_PARAMETER(signal_name);
struct screencast_portal_capture *capture;
g_autoptr(GVariant) session_handle_variant = NULL; g_autoptr(GVariant) session_handle_variant = NULL;
g_autoptr(GVariant) result = NULL; g_autoptr(GVariant) result = NULL;
struct dbus_call_data *call = user_data;
uint32_t response; uint32_t response;
capture = call->capture;
g_clear_pointer(&call, dbus_call_data_free);
g_variant_get(parameters, "(u@a{sv})", &response, &result); g_variant_get(parameters, "(u@a{sv})", &response, &result);
if (response != 0) { if (response != 0) {
@ -575,7 +473,6 @@ static void on_session_created_cb(GObject *source, GAsyncResult *res,
static void create_session(struct screencast_portal_capture *capture) static void create_session(struct screencast_portal_capture *capture)
{ {
struct dbus_call_data *call;
GVariantBuilder builder; GVariantBuilder builder;
char *session_token; char *session_token;
char *request_token; char *request_token;
@ -584,8 +481,9 @@ static void create_session(struct screencast_portal_capture *capture)
portal_create_request_path(&request_path, &request_token); portal_create_request_path(&request_path, &request_token);
portal_create_session_path(NULL, &session_token); portal_create_session_path(NULL, &session_token);
call = subscribe_to_signal(capture, request_path, portal_signal_subscribe(request_path, capture->cancellable,
on_create_session_response_received_cb); on_create_session_response_received_cb,
capture);
g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add(&builder, "{sv}", "handle_token", g_variant_builder_add(&builder, "{sv}", "handle_token",
@ -596,7 +494,7 @@ static void create_session(struct screencast_portal_capture *capture)
g_dbus_proxy_call(get_screencast_portal_proxy(), "CreateSession", g_dbus_proxy_call(get_screencast_portal_proxy(), "CreateSession",
g_variant_new("(a{sv})", &builder), g_variant_new("(a{sv})", &builder),
G_DBUS_CALL_FLAGS_NONE, -1, capture->cancellable, G_DBUS_CALL_FLAGS_NONE, -1, capture->cancellable,
on_session_created_cb, call); on_session_created_cb, NULL);
bfree(session_token); bfree(session_token);
bfree(request_token); bfree(request_token);