|
@@ -179,99 +179,12 @@ static int load_pipewire_syms(void)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/* When in a container, the library version can differ from the underlying core version,
|
|
|
- * so make sure the underlying Pipewire implementation meets the version requirement.
|
|
|
- */
|
|
|
-struct version_data
|
|
|
-{
|
|
|
- struct pw_main_loop *loop;
|
|
|
- int major, minor, patch;
|
|
|
- int seq;
|
|
|
-};
|
|
|
-
|
|
|
-void version_check_core_info_callback(void *data, const struct pw_core_info *info)
|
|
|
-{
|
|
|
- struct version_data *v = data;
|
|
|
-
|
|
|
- if (SDL_sscanf(info->version, "%d.%d.%d", &v->major, &v->minor, &v->patch) < 3) {
|
|
|
- v->major = 0;
|
|
|
- v->minor = 0;
|
|
|
- v->patch = 0;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void version_check_core_done_callback(void *data, uint32_t id, int seq)
|
|
|
-{
|
|
|
- struct version_data *v = data;
|
|
|
-
|
|
|
- if (id == PW_ID_CORE && v->seq == seq) {
|
|
|
- PIPEWIRE_pw_main_loop_quit(v->loop);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static const struct pw_core_events version_check_core_events = { PW_VERSION_CORE_EVENTS, .info = version_check_core_info_callback, .done = version_check_core_done_callback };
|
|
|
-
|
|
|
-SDL_bool pipewire_core_version_at_least(int major, int minor, int patch)
|
|
|
-{
|
|
|
- struct pw_main_loop *loop = NULL;
|
|
|
- struct pw_context *context = NULL;
|
|
|
- struct pw_core *core = NULL;
|
|
|
- struct version_data version_data;
|
|
|
- struct spa_hook core_listener;
|
|
|
- SDL_bool ret = SDL_FALSE;
|
|
|
-
|
|
|
- loop = PIPEWIRE_pw_main_loop_new(NULL);
|
|
|
- if (!loop) {
|
|
|
- goto done;
|
|
|
- }
|
|
|
-
|
|
|
- context = PIPEWIRE_pw_context_new(PIPEWIRE_pw_main_loop_get_loop(loop), NULL, 0);
|
|
|
- if (!context) {
|
|
|
- goto done;
|
|
|
- }
|
|
|
-
|
|
|
- core = PIPEWIRE_pw_context_connect(context, NULL, 0);
|
|
|
- if (!core) {
|
|
|
- goto done;
|
|
|
- }
|
|
|
-
|
|
|
- /* Attach a core listener and get the version. */
|
|
|
- spa_zero(version_data);
|
|
|
- version_data.loop = loop;
|
|
|
- pw_core_add_listener(core, &core_listener, &version_check_core_events, &version_data);
|
|
|
- version_data.seq = pw_core_sync(core, PW_ID_CORE, 0);
|
|
|
-
|
|
|
- PIPEWIRE_pw_main_loop_run(loop);
|
|
|
-
|
|
|
- spa_hook_remove(&core_listener);
|
|
|
-
|
|
|
- ret = (version_data.major >= major) &&
|
|
|
- (version_data.major > major || version_data.minor >= minor) &&
|
|
|
- (version_data.major > major || version_data.minor > minor || version_data.patch >= patch);
|
|
|
-
|
|
|
-done:
|
|
|
- if (core) {
|
|
|
- PIPEWIRE_pw_core_disconnect(core);
|
|
|
- }
|
|
|
- if (context) {
|
|
|
- PIPEWIRE_pw_context_destroy(context);
|
|
|
- }
|
|
|
- if (loop) {
|
|
|
- PIPEWIRE_pw_main_loop_destroy(loop);
|
|
|
- }
|
|
|
-
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-static int init_pipewire_library(SDL_bool check_preferred_version)
|
|
|
+static int init_pipewire_library()
|
|
|
{
|
|
|
if (!load_pipewire_library()) {
|
|
|
if (!load_pipewire_syms()) {
|
|
|
PIPEWIRE_pw_init(NULL, NULL);
|
|
|
-
|
|
|
- if (!check_preferred_version || pipewire_core_version_at_least(1, 0, 0)) {
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ return 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -335,9 +248,19 @@ static int hotplug_init_seq_val;
|
|
|
static SDL_bool hotplug_init_complete;
|
|
|
static SDL_bool hotplug_events_enabled;
|
|
|
|
|
|
+static int pipewire_version_major;
|
|
|
+static int pipewire_version_minor;
|
|
|
+static int pipewire_version_patch;
|
|
|
static char *pipewire_default_sink_id = NULL;
|
|
|
static char *pipewire_default_source_id = NULL;
|
|
|
|
|
|
+static SDL_bool pipewire_core_version_at_least(int major, int minor, int patch)
|
|
|
+{
|
|
|
+ return (pipewire_version_major >= major) &&
|
|
|
+ (pipewire_version_major > major || pipewire_version_minor >= minor) &&
|
|
|
+ (pipewire_version_major > major || pipewire_version_minor > minor || pipewire_version_patch >= patch);
|
|
|
+}
|
|
|
+
|
|
|
// The active node list
|
|
|
static SDL_bool io_list_check_add(struct io_node *node)
|
|
|
{
|
|
@@ -484,6 +407,15 @@ static void core_events_hotplug_init_callback(void *object, uint32_t id, int seq
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void core_events_hotplug_info_callback(void *data, const struct pw_core_info *info)
|
|
|
+{
|
|
|
+ if (SDL_sscanf(info->version, "%d.%d.%d", &pipewire_version_major, &pipewire_version_minor, &pipewire_version_patch) < 3) {
|
|
|
+ pipewire_version_major = 0;
|
|
|
+ pipewire_version_minor = 0;
|
|
|
+ pipewire_version_patch = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void core_events_interface_callback(void *object, uint32_t id, int seq)
|
|
|
{
|
|
|
struct node_object *node = object;
|
|
@@ -511,7 +443,7 @@ static void core_events_metadata_callback(void *object, uint32_t id, int seq)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static const struct pw_core_events hotplug_init_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_hotplug_init_callback };
|
|
|
+static const struct pw_core_events hotplug_init_core_events = { PW_VERSION_CORE_EVENTS, .info = core_events_hotplug_info_callback, .done = core_events_hotplug_init_callback };
|
|
|
static const struct pw_core_events interface_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_interface_callback };
|
|
|
static const struct pw_core_events metadata_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_metadata_callback };
|
|
|
|
|
@@ -1292,11 +1224,11 @@ static void PIPEWIRE_Deinitialize(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static SDL_bool PipewireInitialize(SDL_AudioDriverImpl *impl, SDL_bool check_preferred_version)
|
|
|
+static SDL_bool PipewireInitialize(SDL_AudioDriverImpl *impl)
|
|
|
{
|
|
|
if (!pipewire_initialized) {
|
|
|
|
|
|
- if (init_pipewire_library(check_preferred_version) < 0) {
|
|
|
+ if (init_pipewire_library() < 0) {
|
|
|
return SDL_FALSE;
|
|
|
}
|
|
|
|
|
@@ -1326,7 +1258,7 @@ static SDL_bool PipewireInitialize(SDL_AudioDriverImpl *impl, SDL_bool check_pre
|
|
|
|
|
|
static SDL_bool PIPEWIRE_PREFERRED_Init(SDL_AudioDriverImpl *impl)
|
|
|
{
|
|
|
- if (!PipewireInitialize(impl, SDL_TRUE)) {
|
|
|
+ if (!PipewireInitialize(impl)) {
|
|
|
return SDL_FALSE;
|
|
|
}
|
|
|
|
|
@@ -1342,7 +1274,7 @@ static SDL_bool PIPEWIRE_PREFERRED_Init(SDL_AudioDriverImpl *impl)
|
|
|
|
|
|
PIPEWIRE_pw_thread_loop_unlock(hotplug_loop);
|
|
|
|
|
|
- if (no_devices) {
|
|
|
+ if (no_devices || !pipewire_core_version_at_least(1, 0, 0)) {
|
|
|
PIPEWIRE_Deinitialize();
|
|
|
return SDL_FALSE;
|
|
|
}
|
|
@@ -1352,7 +1284,7 @@ static SDL_bool PIPEWIRE_PREFERRED_Init(SDL_AudioDriverImpl *impl)
|
|
|
|
|
|
static SDL_bool PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
|
|
|
{
|
|
|
- return PipewireInitialize(impl, SDL_FALSE);
|
|
|
+ return PipewireInitialize(impl);
|
|
|
}
|
|
|
|
|
|
AudioBootStrap PIPEWIRE_PREFERRED_bootstrap = {
|