diff --git a/plugins/linux-capture/CMakeLists.txt b/plugins/linux-capture/CMakeLists.txt index 0b27ea1718f54b..e8dd6c9b28acb5 100644 --- a/plugins/linux-capture/CMakeLists.txt +++ b/plugins/linux-capture/CMakeLists.txt @@ -72,11 +72,13 @@ if(ENABLE_PIPEWIRE) ${linux-capture_SOURCES} pipewire.c pipewire-capture.c + portal.c ) set(linux-capture_HEADERS ${linux-capture_HEADERS} pipewire.h pipewire-capture.h + portal.h ) set(linux-capture_LIBRARIES ${linux-capture_LIBRARIES} diff --git a/plugins/linux-capture/pipewire-capture.c b/plugins/linux-capture/pipewire-capture.c index deb6bfb9312588..72f0df5816fb48 100644 --- a/plugins/linux-capture/pipewire-capture.c +++ b/plugins/linux-capture/pipewire-capture.c @@ -19,6 +19,7 @@ */ #include "pipewire.h" +#include "portal.h" /* obs_source_info methods */ @@ -106,6 +107,23 @@ static void pipewire_capture_video_render(void *data, gs_effect_t *effect) void pipewire_capture_load(void) { + uint32_t available_capture_types = portal_get_available_capture_types(); + bool desktop_capture_available = + (available_capture_types & DESKTOP_CAPTURE) != 0; + bool window_capture_available = + (available_capture_types & WINDOW_CAPTURE) != 0; + + if (available_capture_types == 0) { + blog(LOG_INFO, "[pipewire] No captures available"); + return; + } + + blog(LOG_INFO, "[pipewire] Available captures:"); + if (desktop_capture_available) + blog(LOG_INFO, "[pipewire] - Desktop capture"); + if (window_capture_available) + blog(LOG_INFO, "[pipewire] - Window capture"); + // Desktop capture const struct obs_source_info pipewire_desktop_capture_info = { .id = "pipewire-desktop-capture-source", @@ -124,7 +142,8 @@ void pipewire_capture_load(void) .video_render = pipewire_capture_video_render, .icon_type = OBS_ICON_TYPE_DESKTOP_CAPTURE, }; - obs_register_source(&pipewire_desktop_capture_info); + if (desktop_capture_available) + obs_register_source(&pipewire_desktop_capture_info); // Window capture const struct obs_source_info pipewire_window_capture_info = { @@ -144,7 +163,8 @@ void pipewire_capture_load(void) .video_render = pipewire_capture_video_render, .icon_type = OBS_ICON_TYPE_WINDOW_CAPTURE, }; - obs_register_source(&pipewire_window_capture_info); + if (window_capture_available) + obs_register_source(&pipewire_window_capture_info); pw_init(NULL, NULL); } diff --git a/plugins/linux-capture/portal.c b/plugins/linux-capture/portal.c new file mode 100644 index 00000000000000..6aeb17a09fdf75 --- /dev/null +++ b/plugins/linux-capture/portal.c @@ -0,0 +1,74 @@ +/* portal.c + * + * Copyright 2021 Georges Basile Stavracas Neto + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "portal.h" +#include "pipewire.h" + +static GDBusConnection *connection = NULL; +static GDBusProxy *proxy = NULL; + +static void ensure_proxy(void) +{ + g_autoptr(GError) error = NULL; + if (!connection) { + connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); + + if (error) { + blog(LOG_WARNING, + "[portals] Error retrieving D-Bus connection: %s", + error->message); + return; + } + } + + if (!proxy) { + proxy = g_dbus_proxy_new_sync( + connection, G_DBUS_PROXY_FLAGS_NONE, NULL, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + "org.freedesktop.portal.ScreenCast", NULL, &error); + + if (error) { + blog(LOG_WARNING, + "[portals] Error retrieving D-Bus proxy: %s", + error->message); + return; + } + } +} + +uint32_t portal_get_available_capture_types(void) +{ + g_autoptr(GVariant) cached_source_types = NULL; + uint32_t available_source_types; + + ensure_proxy(); + + if (!proxy) + return 0; + + cached_source_types = + g_dbus_proxy_get_cached_property(proxy, "AvailableSourceTypes"); + available_source_types = + cached_source_types ? g_variant_get_uint32(cached_source_types) + : 0; + + return available_source_types; +} diff --git a/plugins/linux-capture/portal.h b/plugins/linux-capture/portal.h new file mode 100644 index 00000000000000..67aeb7646d2ee1 --- /dev/null +++ b/plugins/linux-capture/portal.h @@ -0,0 +1,25 @@ +/* portal.c + * + * Copyright 2021 Georges Basile Stavracas Neto + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#pragma once + +#include + +uint32_t portal_get_available_capture_types(void);