diff options
author | Wim Taymans <wtaymans@redhat.com> | 2019-12-04 13:17:53 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2019-12-04 13:17:53 +0100 |
commit | 9efe32b45cb461fd058791a1c94e587b9ef15e1d (patch) | |
tree | 8c2d801e8c0d6a6d7dab9701fbc0e8e375946211 | |
parent | 97915b352915c1ddcac793654d37f1eef51ccc5a (diff) |
more API refactoringAPI
Try to remove the pw_remote from view and work directly with
the pw_core proxies.
66 files changed, 1346 insertions, 1061 deletions
diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c index 7c63dea7..0c026768 100644 --- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c +++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c @@ -66,10 +66,8 @@ typedef struct { struct pw_loop *loop; struct pw_thread_loop *main_loop; - struct pw_impl_core *core; - - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core *core; + struct spa_hook core_listener; uint32_t flags; struct pw_stream *stream; @@ -112,13 +110,13 @@ static void snd_pcm_pipewire_free(snd_pcm_pipewire_t *pw) if (pw->main_loop) pw_thread_loop_stop(pw->main_loop); if (pw->core) - pw_impl_core_destroy(pw->core); + pw_proxy_destroy((struct pw_proxy*)pw->core); if (pw->main_loop) pw_thread_loop_destroy(pw->main_loop); - if (pw->loop) - pw_loop_destroy(pw->loop); if (pw->fd >= 0) spa_system_close(pw->loop->system, pw->fd); + if (pw->loop) + pw_loop_destroy(pw->loop); free(pw); } } @@ -407,7 +405,7 @@ static int snd_pcm_pipewire_prepare(snd_pcm_ioplug_t *io) "Playback" : "Capture"); pw_properties_set(props, PW_KEY_MEDIA_ROLE, "Music"); - pw->stream = pw_stream_new(pw->remote, pw->node_name, props); + pw->stream = pw_stream_new(pw->core, pw->node_name, props); if (pw->stream == NULL) goto error; @@ -747,66 +745,24 @@ static int pipewire_set_hw_constraint(snd_pcm_pipewire_t *pw) return 0; } -static void on_remote_state_changed(void *data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void on_core_error(void *object, uint32_t id, int seq, int res, const char *message) { - snd_pcm_pipewire_t *pw = data; + snd_pcm_pipewire_t *pw = object; - switch (state) { - case PW_REMOTE_STATE_ERROR: - pw_log_error("error %s", error); - /* fallthrough */ - case PW_REMOTE_STATE_UNCONNECTED: + pw_log_error("error id:%d seq:%d res:%d (%s): %s", id, seq, res, spa_strerror(res), message); + if (id == 0) { pw->error = true; if (pw->fd != -1) pcm_poll_unblock_check(&pw->io); - /* fallthrough */ - case PW_REMOTE_STATE_CONNECTED: - pw_thread_loop_signal(pw->main_loop, false); - break; - default: - break; - } + } + pw_thread_loop_signal(pw->main_loop, false); } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_remote_state_changed, +static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, + .error = on_core_error, }; -static int remote_connect_sync(snd_pcm_pipewire_t *pw) -{ - const char *error = NULL; - enum pw_remote_state state; - int res; - - pw_thread_loop_lock(pw->main_loop); - - if ((res = pw_remote_connect(pw->remote)) < 0) { - error = spa_strerror(res); - goto error; - } - - while (true) { - state = pw_remote_get_state(pw->remote, &error); - if (state == PW_REMOTE_STATE_ERROR) - goto error; - - if (state == PW_REMOTE_STATE_CONNECTED) - break; - - pw_thread_loop_wait(pw->main_loop); - } - exit: - pw_thread_loop_unlock(pw->main_loop); - - return res; - - error: - SNDERR("PipeWire: Unable to connect: %s\n", error); - goto exit; -} - static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, const char *node_name, const char *playback_node, @@ -851,7 +807,6 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, pw->loop = pw_loop_new(NULL); pw->main_loop = pw_thread_loop_new(pw->loop, "alsa-pipewire"); - pw->core = pw_impl_core_new(pw->loop, NULL, 0); props = pw_properties_new(NULL, NULL); str = pw_get_prgname(); @@ -860,14 +815,12 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, else pw_properties_set(props, PW_KEY_APP_NAME, "ALSA plug-in"); - pw->remote = pw_remote_new(pw->core, props, 0); - pw_remote_add_listener(pw->remote, &pw->remote_listener, &remote_events, pw); if ((err = pw_thread_loop_start(pw->main_loop)) < 0) goto error; - if ((err = remote_connect_sync(pw)) < 0) - goto error; + pw->core = pw_core_connect(pw->loop, props, 0); + pw_core_add_listener(pw->core, &pw->core_listener, &core_events, pw); pw->fd = spa_system_eventfd_create(pw->loop->system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK); diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index cc955a09..2647fd31 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -203,7 +203,6 @@ struct port { struct context { struct pw_main_loop *main; struct pw_thread_loop *loop; - struct pw_impl_core *core; struct pw_map globals; struct spa_list free_objects; @@ -536,47 +535,37 @@ jack_get_version_string(void) return "0.0.0.0"; } -static void on_state_changed(void *data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void on_sync_reply(void *data, uint32_t id, int seq) { struct client *client = data; - - pw_log_debug(NAME" %p: state %s", client, pw_remote_state_as_string(state)); - switch (state) { - case PW_REMOTE_STATE_ERROR: - client->error = true; - /* fallthrough*/ - case PW_REMOTE_STATE_UNCONNECTED: - /* don't call shutdown when we do client_close, only - * on unexpected errors */ - if (client->shutdown_callback && !client->destroyed) - client->shutdown_callback(client->shutdown_arg); - /* fallthrough*/ - case PW_REMOTE_STATE_CONNECTED: - pw_thread_loop_signal(client->context.loop, false); - break; - default: - break; - } + if (id != 0) + return; + client->last_sync = seq; + pw_thread_loop_signal(client->context.loop, false); } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, -}; -static void on_sync_reply(void *data, uint32_t id, int seq) +static void on_error(void *data, uint32_t id, int seq, int res, const char *message) { struct client *client = data; + + pw_log_debug(NAME" %p: error %s", client, message); + if (id != 0) return; - client->last_sync = seq; + + client->error = true; + + if (client->shutdown_callback && !client->destroyed) + client->shutdown_callback(client->shutdown_arg); + pw_thread_loop_signal(client->context.loop, false); } static const struct pw_core_events core_events = { PW_VERSION_CORE_EVENTS, .done = on_sync_reply, + .error = on_error, }; static int do_sync(struct client *client) @@ -2094,7 +2083,6 @@ jack_client_t * jack_client_open (const char *client_name, jack_status_t *status, ...) { struct client *client; - bool busy = true; struct spa_dict props; struct spa_dict_item items[6]; const struct spa_support *support; @@ -2117,28 +2105,16 @@ jack_client_t * jack_client_open (const char *client_name, strncpy(client->name, client_name, JACK_CLIENT_NAME_SIZE); client->context.main = pw_main_loop_new(NULL); client->context.loop = pw_thread_loop_new(pw_main_loop_get_loop(client->context.main), client_name); - client->context.core = pw_impl_core_new(pw_thread_loop_get_loop(client->context.loop), NULL, 0); spa_list_init(&client->context.free_objects); spa_list_init(&client->context.nodes); spa_list_init(&client->context.ports); spa_list_init(&client->context.links); - support = pw_impl_core_get_support(client->context.core, &n_support); - - mix2 = mix2_c; - cpu_iface = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); - if (cpu_iface) { -#if defined (__SSE__) - uint32_t flags = spa_cpu_get_flags(cpu_iface); - if (flags & SPA_CPU_FLAG_SSE) - mix2 = mix2_sse; -#endif - } - client->loop = pw_data_loop_new(NULL); if (client->loop == NULL) goto init_failed; + pw_array_init(&client->links, 64); client->buffer_frames = (uint32_t)-1; @@ -2156,40 +2132,31 @@ jack_client_t * jack_client_open (const char *client_name, pw_thread_loop_start(client->context.loop); pw_thread_loop_lock(client->context.loop); - client->remote = pw_remote_new(client->context.core, + + client->core = pw_core_connect(pw_main_loop_get_loop(client->context.main), pw_properties_new( PW_KEY_CLIENT_NAME, client_name, PW_KEY_CLIENT_API, "jack", NULL), 0); - pw_remote_add_listener(client->remote, &client->remote_listener, &remote_events, client); - - if (pw_remote_connect(client->remote) < 0) - goto server_failed; - - while (busy) { - const char *error = NULL; + pw_core_add_listener(client->core, &client->core_listener, &core_events, client); - switch (pw_remote_get_state(client->remote, &error)) { - case PW_REMOTE_STATE_ERROR: - goto server_failed; + support = pw_context_get_support(pw_core_get_context(client->core), &n_support); - case PW_REMOTE_STATE_CONNECTED: - busy = false; - break; + mix2 = mix2_c; + cpu_iface = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU); + if (cpu_iface) { +#if defined (__SSE__) + uint32_t flags = spa_cpu_get_flags(cpu_iface); + if (flags & SPA_CPU_FLAG_SSE) + mix2 = mix2_sse; +#endif + } - default: - break; - } - if (busy) - pw_thread_loop_wait(client->context.loop); + if (do_sync(client) < 0) + goto server_failed; - } - client->core = pw_remote_get_core(client->remote); - pw_core_add_listener(client->core, - &client->core_listener, - &core_events, client); client->registry = pw_core_get_registry(client->core, PW_VERSION_REGISTRY, 0); pw_registry_add_listener(client->registry, @@ -2285,7 +2252,7 @@ int jack_client_close (jack_client_t *client) pw_thread_loop_stop(c->context.loop); c->destroyed = true; - pw_impl_core_destroy(c->context.core); + pw_core_disconnect(c->core); pw_thread_loop_destroy(c->context.loop); pw_main_loop_destroy(c->context.main); diff --git a/pipewire-pulseaudio/src/context.c b/pipewire-pulseaudio/src/context.c index d5735d84..38b38d59 100644 --- a/pipewire-pulseaudio/src/context.c +++ b/pipewire-pulseaudio/src/context.c @@ -817,12 +817,29 @@ static void core_done(void *data, uint32_t id, int seq) complete_operations(c, seq); } +static void core_error(void *data, uint32_t id, int seq, int res, const char *message) +{ + pa_context *c = data; + + pw_log_error("error: id:%u seq:%d res:%d %s\n", id, seq, res, message); + if (id == 0) { + if (c->core) { + spa_hook_remove(&c->core_listener); + c->core = NULL; + } + if (!c->disconnect) + context_fail(c, PA_ERR_CONNECTIONTERMINATED); + } +} + static const struct pw_core_events core_events = { PW_VERSION_CORE_EVENTS, .info = core_info, - .done = core_done + .done = core_done, + .error = core_error }; +#if 0 static void remote_state_changed(void *data, enum pw_remote_state old, enum pw_remote_state state, const char *error) { @@ -863,6 +880,7 @@ static const struct pw_remote_events remote_events = { PW_VERSION_REMOTE_EVENTS, .state_changed = remote_state_changed, }; +#endif struct success_data { pa_context_success_cb_t cb; @@ -913,14 +931,15 @@ pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_c SPA_EXPORT pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, PA_CONST pa_proplist *p) { - struct pw_impl_core *core; - struct pw_loop *loop; - struct pw_remote *r; struct pw_properties *props; pa_context *c; pa_assert(mainloop); + c = calloc(1, sizeof(struct pa_context)); + if (c == NULL) + return NULL; + props = pw_properties_new(NULL, NULL); if (name) pw_properties_set(props, PA_PROP_APPLICATION_NAME, name); @@ -928,20 +947,7 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char * if (p) pw_properties_update(props, &p->props->dict); - loop = mainloop->userdata; - core = pw_impl_core_new(loop, NULL, 0); - - r = pw_remote_new(core, props, sizeof(struct pa_context)); - if (r == NULL) - return NULL; - - c = pw_remote_get_user_data(r); - c->loop = loop; - c->core_impl = core; - c->remote = r; - - pw_remote_add_listener(r, &c->remote_listener, &remote_events, c); - + c->loop = mainloop->userdata; c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new(); c->refcount = 1; c->client_index = PA_INVALID_INDEX; @@ -964,7 +970,8 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char * static void do_core_destroy(pa_mainloop_api*m, void *userdata) { pa_context *c = userdata; - pw_impl_core_destroy(c->core_impl); + pw_core_disconnect(c->core); + free(c); } static void context_free(pa_context *c) @@ -1059,8 +1066,6 @@ pa_context_state_t pa_context_get_state(PA_CONST pa_context *c) SPA_EXPORT int pa_context_connect(pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api) { - int res; - pa_assert(c); pa_assert(c->refcount >= 1); @@ -1072,11 +1077,18 @@ int pa_context_connect(pa_context *c, const char *server, pa_context_flags_t fla c->no_fail = !!(flags & PA_CONTEXT_NOFAIL); - res = pw_remote_connect(c->remote); + pa_context_set_state(c, PA_CONTEXT_CONNECTING); + + c->core = pw_core_connect(c->loop, c->proplist->props, 0); + pw_core_add_listener(c->core, &c->core_listener, &core_events, c); + + pa_context_set_state(c, PA_CONTEXT_AUTHORIZING); + pa_context_set_state(c, PA_CONTEXT_SETTING_NAME); + pa_context_set_state(c, PA_CONTEXT_READY); pa_context_unref(c); - return res; + return 0; } SPA_EXPORT @@ -1086,7 +1098,7 @@ void pa_context_disconnect(pa_context *c) pa_assert(c->refcount >= 1); c->disconnect = true; - pw_remote_disconnect(c->remote); + pw_core_disconnect(c->core); if (PA_CONTEXT_IS_GOOD(c->state)) pa_context_set_state(c, PA_CONTEXT_TERMINATED); @@ -1199,7 +1211,7 @@ pa_operation* pa_context_set_name(pa_context *c, const char *name, pa_context_su items[0] = SPA_DICT_ITEM_INIT(PA_PROP_APPLICATION_NAME, name); dict = SPA_DICT_INIT(items, 1); - pw_remote_update_properties(c->remote, &dict); + pw_core_update_client_properties(c->core, &dict); o = pa_operation_new(c, NULL, on_success, sizeof(struct success_data)); d = o->userdata; diff --git a/pipewire-pulseaudio/src/internal.h b/pipewire-pulseaudio/src/internal.h index e0c67a7e..e16c482a 100644 --- a/pipewire-pulseaudio/src/internal.h +++ b/pipewire-pulseaudio/src/internal.h @@ -281,9 +281,6 @@ struct pa_context { uint32_t client_index; struct pw_loop *loop; - struct pw_impl_core *core_impl; - struct pw_remote *remote; - struct spa_hook remote_listener; struct pw_core *core; struct spa_hook core_listener; diff --git a/pipewire-pulseaudio/src/operation.c b/pipewire-pulseaudio/src/operation.c index 0a13911b..adf72aad 100644 --- a/pipewire-pulseaudio/src/operation.c +++ b/pipewire-pulseaudio/src/operation.c @@ -22,6 +22,7 @@ #include <spa/utils/list.h> #include <pipewire/log.h> +#include <pipewire/core.h> #include <pulse/operation.h> diff --git a/pipewire-pulseaudio/src/stream.c b/pipewire-pulseaudio/src/stream.c index f5207fc5..1572e30e 100644 --- a/pipewire-pulseaudio/src/stream.c +++ b/pipewire-pulseaudio/src/stream.c @@ -554,7 +554,7 @@ static pa_stream* stream_new(pa_context *c, const char *name, NULL); pw_properties_update(props, &s->proplist->props->dict); - s->stream = pw_stream_new(c->remote, name, props); + s->stream = pw_stream_new(c->core, name, props); s->refcount = 1; s->context = c; spa_list_init(&s->pending); diff --git a/src/examples/audio-dsp-filter.c b/src/examples/audio-dsp-filter.c index 3b9d0f70..dbb23899 100644 --- a/src/examples/audio-dsp-filter.c +++ b/src/examples/audio-dsp-filter.c @@ -22,15 +22,6 @@ * DEALINGS IN THE SOFTWARE. */ -#include <stdio.h> -#include <errno.h> -#include <time.h> -#include <math.h> -#include <sys/mman.h> - -#include <spa/param/audio/format-utils.h> -#include <spa/param/props.h> - #include <pipewire/pipewire.h> #include <pipewire/filter.h> diff --git a/src/examples/export-sink.c b/src/examples/export-sink.c index 5e686698..4524b254 100644 --- a/src/examples/export-sink.c +++ b/src/examples/export-sink.c @@ -68,10 +68,8 @@ struct data { struct pw_main_loop *loop; - struct pw_impl_core *core; - - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core *core; + struct spa_hook core_listener; struct spa_node impl_node; struct spa_hook_list hooks; @@ -473,47 +471,42 @@ static void make_node(struct data *data) SPA_TYPE_INTERFACE_Node, SPA_VERSION_NODE, &impl_node, data); - pw_remote_export(data->remote, SPA_TYPE_INTERFACE_Node, props, &data->impl_node, 0); + pw_core_export_object(data->core, + SPA_TYPE_INTERFACE_Node, + &props->dict, + &data->impl_node.iface, 0); } -static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) +static void set_permissions(struct data *data) { - struct data *data = _data; - - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); - pw_main_loop_quit(data->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - { - struct pw_permission permissions[2]; - - /* an example, set specific permissions on one object, this is the - * core object. */ - permissions[0].id = 0; - permissions[0].permissions = PW_PERM_R | PW_PERM_X; - /* remove WX from all other objects */ - permissions[1].id = SPA_ID_INVALID; - permissions[1].permissions = PW_PERM_R; + struct pw_permission permissions[2]; + + /* an example, set specific permissions on one object, this is the + * core object. */ + permissions[0].id = 0; + permissions[0].permissions = PW_PERM_R | PW_PERM_X; + /* remove WX from all other objects */ + permissions[1].id = SPA_ID_INVALID; + permissions[1].permissions = PW_PERM_R; + + pw_client_update_permissions( + pw_core_get_client(data->core), + 2, permissions); +} - pw_client_update_permissions( - pw_remote_get_client(data->remote), - 2, permissions); +static void on_error(void *object, uint32_t id, int seq, int res, const char *message) +{ + struct data *data = object; - make_node(data); - break; - } - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; + printf("error: %s\n", message); + if (id == 0) { + pw_main_loop_quit(data->loop); } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, +static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, + .error = on_error, }; int main(int argc, char *argv[]) @@ -523,8 +516,7 @@ int main(int argc, char *argv[]) pw_init(&argc, &argv); data.loop = pw_main_loop_new(NULL); - data.core = pw_impl_core_new(pw_main_loop_get_loop(data.loop), NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); + data.core = pw_core_connect(pw_main_loop_get_loop(data.loop), NULL, 0); data.path = argc > 1 ? argv[1] : NULL; spa_hook_list_init(&data.hooks); @@ -554,14 +546,15 @@ int main(int argc, char *argv[]) return -1; } - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + pw_core_add_listener(data.core, &data.core_listener, &core_events, &data); - if (pw_remote_connect(data.remote) < 0) - return -1; + set_permissions(&data); + + make_node(&data); pw_main_loop_run(data.loop); - pw_impl_core_destroy(data.core); + pw_core_disconnect(data.core); pw_main_loop_destroy(data.loop); return 0; diff --git a/src/examples/export-source.c b/src/examples/export-source.c index 1716da49..ff0e8c21 100644 --- a/src/examples/export-source.c +++ b/src/examples/export-source.c @@ -53,10 +53,8 @@ struct data { struct pw_main_loop *loop; - struct pw_impl_core *core; - - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core *core; + struct spa_hook core_listener; uint64_t info_all; struct spa_port_info info; @@ -481,33 +479,26 @@ static void make_node(struct data *data) SPA_TYPE_INTERFACE_Node, SPA_VERSION_NODE, &impl_node, data); - pw_remote_export(data->remote, SPA_TYPE_INTERFACE_Node, props, &data->impl_node, 0); + + pw_core_export_object(data->core, + SPA_TYPE_INTERFACE_Node, + &props->dict, + &data->impl_node.iface, 0); } -static void on_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void on_error(void *object, uint32_t id, int seq, int res, const char *message) { - struct data *data = _data; + struct data *data = object; - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); + printf("error: %s\n", message); + if (id == 0) { pw_main_loop_quit(data->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - make_node(data); - break; - - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, +static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, + .error = on_error, }; int main(int argc, char *argv[]) @@ -517,8 +508,7 @@ int main(int argc, char *argv[]) pw_init(&argc, &argv); data.loop = pw_main_loop_new(NULL); - data.core = pw_impl_core_new(pw_main_loop_get_loop(data.loop), NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); + data.core = pw_core_connect(pw_main_loop_get_loop(data.loop), NULL, 0); data.path = argc > 1 ? argv[1] : NULL; data.info_all = SPA_PORT_CHANGE_MASK_FLAGS | @@ -540,13 +530,13 @@ int main(int argc, char *argv[]) spa_list_init(&data.empty); spa_hook_list_init(&data.hooks); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + pw_core_add_listener(data.core, &data.core_listener, &core_events, &data); - pw_remote_connect(data.remote); + make_node(&data); pw_main_loop_run(data.loop); - pw_impl_core_destroy(data.core); + pw_core_disconnect(data.core); pw_main_loop_destroy(data.loop); return 0; diff --git a/src/examples/export-spa-device.c b/src/examples/export-spa-device.c index e5e4589b..fe053281 100644 --- a/src/examples/export-spa-device.c +++ b/src/examples/export-spa-device.c @@ -34,10 +34,8 @@ struct data { struct pw_main_loop *loop; - struct pw_impl_core *core; - - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core *core; + struct spa_hook core_listener; struct pw_impl_device *device; const char *library; @@ -47,6 +45,7 @@ struct data { static int make_device(struct data *data) { +#if 0 struct pw_impl_factory *factory; struct pw_properties *props; @@ -66,36 +65,22 @@ static int make_device(struct data *data) pw_remote_export(data->remote, SPA_TYPE_INTERFACE_Device, NULL, pw_impl_device_get_implementation(data->device), 0); +#endif return 0; } -static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) +static void on_error(void *object, uint32_t id, int seq, int res, const char *message) { - struct data *data = _data; - - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); + struct data *data = object; + printf("core error: id:%u seq:%d res:%d %s\n", id, seq, res, message); + if (id == 0) { pw_main_loop_quit(data->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - if (make_device(data) < 0) { - pw_log_error("can't make device"); - pw_main_loop_quit(data->loop); - } - break; - - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, +static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, + .error = on_error, }; static void do_quit(void *data, int signal_number) @@ -122,21 +107,24 @@ int main(int argc, char *argv[]) l = pw_main_loop_get_loop(data.loop); pw_loop_add_signal(l, SIGINT, do_quit, &data); pw_loop_add_signal(l, SIGTERM, do_quit, &data); - data.core = pw_impl_core_new(l, NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); - data.library = argv[1]; - data.factory = argv[2]; - pw_impl_module_load(data.core, "libpipewire-module-spa-device-factory", NULL, NULL); - pw_impl_module_load(data.core, "libpipewire-module-client-device", NULL, NULL); + pw_context_load_module(NULL, "libpipewire-module-spa-device-factory", NULL, NULL); + pw_context_load_module(NULL, "libpipewire-module-client-device", NULL, NULL); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + data.core = pw_core_connect(l, NULL, 0); + pw_core_add_listener(data.core, &data.core_listener, &core_events, &data); - pw_remote_connect(data.remote); + data.library = argv[1]; + data.factory = argv[2]; + + if (make_device(&data) < 0) { + fprintf(stderr, "can't make device"); + return -1; + } pw_main_loop_run(data.loop); - pw_impl_core_destroy(data.core); + pw_core_disconnect(data.core); pw_main_loop_destroy(data.loop); return 0; diff --git a/src/examples/export-spa.c b/src/examples/export-spa.c index 01fe2abf..1a5e45c8 100644 --- a/src/examples/export-spa.c +++ b/src/examples/export-spa.c @@ -34,10 +34,8 @@ struct data { struct pw_main_loop *loop; - struct pw_impl_core *core; - - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core *core; + struct spa_hook core_listener; struct pw_impl_node *node; const char *library; @@ -66,6 +64,7 @@ static const struct pw_node_events node_events = { static int make_node(struct data *data) { +#if 0 struct pw_impl_factory *factory; struct pw_properties *props; @@ -98,36 +97,23 @@ static int make_node(struct data *data) pw_node_add_listener((struct pw_node*)data->proxy, &data->node_listener, &node_events, data); +#endif return 0; } -static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) +static void on_error(void *object, uint32_t id, int seq, int res, const char *message) { - struct data *data = _data; + struct data *data = object; - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); + printf("error: %s\n", message); + if (id == 0) { pw_main_loop_quit(data->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - if (make_node(data) < 0) { - pw_log_error("can't make node"); - pw_main_loop_quit(data->loop); - } - break; - - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; } } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, +static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, + .error = on_error, }; static void do_quit(void *data, int signal_number) @@ -154,22 +140,26 @@ int main(int argc, char *argv[]) l = pw_main_loop_get_loop(data.loop); pw_loop_add_signal(l, SIGINT, do_quit, &data); pw_loop_add_signal(l, SIGTERM, do_quit, &data); - data.core = pw_impl_core_new(l, NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); + + data.core = pw_core_connect(l, NULL, 0); + data.library = argv[1]; data.factory = argv[2]; if (argc > 3) data.path = argv[3]; - pw_impl_module_load(data.core, "libpipewire-module-spa-node-factory", NULL, NULL); + pw_core_load_module(data.core, "libpipewire-module-spa-node-factory", NULL, NULL, 0); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + pw_core_add_listener(data.core, &data.core_listener, &core_events, &data); - pw_remote_connect(data.remote); + if (make_node(&data) < 0) { + pw_log_error("can't make node"); + return -1; + } pw_main_loop_run(data.loop); - pw_impl_core_destroy(data.core); + pw_core_disconnect(data.core); pw_main_loop_destroy(data.loop); return 0; diff --git a/src/examples/media-session/media-session.c b/src/examples/media-session/media-session.c index d3f29f3b..b39017b4 100644 --- a/src/examples/media-session/media-session.c +++ b/src/examples/media-session/media-session.c @@ -1657,6 +1657,7 @@ int main(int argc, char *argv[]) impl.loop = pw_main_loop_new(NULL); impl.this.loop = pw_main_loop_get_loop(impl.loop); + impl.this.core_impl = pw_impl_core_new(impl.this.loop, NULL, 0); pw_impl_core_add_spa_lib(impl.this.core_impl, "api.bluez5.*", "bluez5/libspa-bluez5"); diff --git a/src/examples/video-src.c b/src/examples/video-src.c index 8a76301e..3e2524f7 100644 --- a/src/examples/video-src.c +++ b/src/examples/video-src.c @@ -46,10 +46,7 @@ struct data { struct pw_main_loop *loop; struct spa_source *timer; - struct pw_impl_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; - + struct pw_core *core; struct pw_stream *stream; struct spa_hook stream_listener; @@ -186,9 +183,17 @@ static void on_stream_state_changed(void *_data, enum pw_stream_state old, enum printf("stream state: \"%s\"\n", pw_stream_state_as_string(state)); switch (state) { + case PW_STREAM_STATE_UNCONNECTED: + case PW_STREAM_STATE_ERROR: + pw_main_loop_quit(data->loop); + break; + case PW_STREAM_STATE_PAUSED: printf("node id: %d\n", pw_stream_get_node_id(data->stream)); + pw_loop_update_timer(pw_main_loop_get_loop(data->loop), + data->timer, NULL, NULL, false); break; + case PW_STREAM_STATE_STREAMING: { struct timespec timeout, interval; @@ -203,8 +208,6 @@ static void on_stream_state_changed(void *_data, enum pw_stream_state old, enum break; } default: - pw_loop_update_timer(pw_main_loop_get_loop(data->loop), - data->timer, NULL, NULL, false); break; } } @@ -266,85 +269,51 @@ static const struct pw_stream_events stream_events = { .param_changed = on_stream_param_changed, }; -static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) -{ - struct data *data = _data; - struct pw_remote *remote = data->remote; - - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); - pw_main_loop_quit(data->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - { - const struct spa_pod *params[1]; - uint8_t buffer[1024]; - struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); - - printf("remote state: \"%s\"\n", - pw_remote_state_as_string(state)); - - data->stream = pw_stream_new(remote, "video-src", - pw_properties_new( - PW_KEY_MEDIA_CLASS, "Video/Source", - NULL)); - - params[0] = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, - SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video), - SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), - SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_RGB), - SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle( - &SPA_RECTANGLE(320, 240), - &SPA_RECTANGLE(1, 1), - &SPA_RECTANGLE(4096, 4096)), - SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&SPA_FRACTION(25, 1))); - - pw_stream_add_listener(data->stream, - &data->stream_listener, - &stream_events, - data); - - pw_stream_connect(data->stream, - PW_DIRECTION_OUTPUT, - SPA_ID_INVALID, - PW_STREAM_FLAG_DRIVER | - PW_STREAM_FLAG_MAP_BUFFERS, - params, 1); - break; - } - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; - } -} - -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, -}; - int main(int argc, char *argv[]) { struct data data = { 0, }; + const struct spa_pod *params[1]; + uint8_t buffer[1024]; + struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); pw_init(&argc, &argv); data.loop = pw_main_loop_new(NULL); - data.core = pw_impl_core_new(pw_main_loop_get_loop(data.loop), NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); + data.core = pw_core_connect(pw_main_loop_get_loop(data.loop), NULL, 0); data.timer = pw_loop_add_timer(pw_main_loop_get_loop(data.loop), on_timeout, &data); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + data.stream = pw_stream_new(data.core, "video-src", + pw_properties_new( + PW_KEY_MEDIA_CLASS, "Video/Source", + NULL)); + + pw_stream_add_listener(data.stream, + &data.stream_listener, + &stream_events, + &data); - pw_remote_connect(data.remote); + params[0] = spa_pod_builder_add_object(&b, + SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, + SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video), + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), + SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_RGB), + SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle( + &SPA_RECTANGLE(320, 240), + &SPA_RECTANGLE(1, 1), + &SPA_RECTANGLE(4096, 4096)), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction(&SPA_FRACTION(25, 1))); + + pw_stream_connect(data.stream, + PW_DIRECTION_OUTPUT, + SPA_ID_INVALID, + PW_STREAM_FLAG_DRIVER | + PW_STREAM_FLAG_MAP_BUFFERS, + params, 1); pw_main_loop_run(data.loop); - pw_impl_core_destroy(data.core); + pw_core_disconnect(data.core); pw_main_loop_destroy(data.loop); return 0; diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index 295f0de7..b50544fa 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -283,7 +283,6 @@ gst_pipewire_sink_init (GstPipeWireSink * sink) sink->loop = pw_loop_new (NULL); sink->main_loop = pw_thread_loop_new (sink->loop, "pipewire-sink-loop"); - sink->core = pw_impl_core_new (sink->loop, NULL, 0); GST_DEBUG ("loop %p %p", sink->loop, sink->main_loop); } @@ -665,7 +664,7 @@ gst_pipewire_sink_start (GstBaseSink * basesink) } pw_thread_loop_lock (pwsink->main_loop); - pwsink->stream = pw_stream_new (pwsink->remote, pwsink->client_name, props); + pwsink->stream = pw_stream_new (pwsink->core, pwsink->client_name, props); pwsink->pool->stream = pwsink->stream; pw_stream_add_listener(pwsink->stream, @@ -697,60 +696,41 @@ gst_pipewire_sink_stop (GstBaseSink * basesink) return TRUE; } -static void -on_remote_state_changed (void *data, enum pw_remote_state old, enum pw_remote_state state, const char *error) +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) { GstPipeWireSink *pwsink = data; - - GST_DEBUG ("got remote state %d", state); - - switch (state) { - case PW_REMOTE_STATE_UNCONNECTED: - case PW_REMOTE_STATE_CONNECTING: - case PW_REMOTE_STATE_CONNECTED: - break; - case PW_REMOTE_STATE_ERROR: + GST_DEBUG ("got error id:%u %s", id, message); + if (id == 0) { GST_ELEMENT_ERROR (pwsink, RESOURCE, FAILED, - ("remote error: %s", error), (NULL)); - break; + ("core error: %s", message), (NULL)); } pw_thread_loop_signal (pwsink->main_loop, FALSE); } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_remote_state_changed, +static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, + .error = on_core_error, }; static gboolean gst_pipewire_sink_open (GstPipeWireSink * pwsink) { - const char *error = NULL; - if (pw_thread_loop_start (pwsink->main_loop) < 0) goto mainloop_error; pw_thread_loop_lock (pwsink->main_loop); - pwsink->remote = pw_remote_new (pwsink->core, NULL, 0); - - pw_remote_add_listener (pwsink->remote, - &pwsink->remote_listener, - &remote_events, pwsink); if (pwsink->fd == -1) - pw_remote_connect (pwsink->remote); + pwsink->core = pw_core_connect (pwsink->loop, NULL, 0); else - pw_remote_connect_fd (pwsink->remote, dup(pwsink->fd)); + pwsink->core = pw_core_connect_fd (pwsink->loop, dup(pwsink->fd), NULL, 0); - while (TRUE) { - enum pw_remote_state state = pw_remote_get_state (pwsink->remote, &error); - - if (state == PW_REMOTE_STATE_CONNECTED) - break; - - if (state == PW_REMOTE_STATE_ERROR) - goto connect_error; + pw_core_add_listener (pwsink->core, + &pwsink->core_listener, + &core_events, pwsink); + while (TRUE) { + GST_DEBUG ("waiting for CONNECTED"); pw_thread_loop_wait (pwsink->main_loop); } pw_thread_loop_unlock (pwsink->main_loop); @@ -764,39 +744,11 @@ mainloop_error: ("Failed to start mainloop"), (NULL)); return FALSE; } -connect_error: - { - pw_thread_loop_unlock (pwsink->main_loop); - return FALSE; - } } static gboolean gst_pipewire_sink_close (GstPipeWireSink * pwsink) { - const char *error = NULL; - - pw_thread_loop_lock (pwsink->main_loop); - if (pwsink->stream) { - pw_stream_disconnect (pwsink->stream); - } - if (pwsink->remote) { - pw_remote_disconnect (pwsink->remote); - - while (TRUE) { - enum pw_remote_state state = pw_remote_get_state (pwsink->remote, &error); - - if (state == PW_REMOTE_STATE_UNCONNECTED) - break; - - if (state == PW_REMOTE_STATE_ERROR) - break; - - pw_thread_loop_wait (pwsink->main_loop); - } - } - pw_thread_loop_unlock (pwsink->main_loop); - pw_thread_loop_stop (pwsink->main_loop); if (pwsink->stream) { @@ -804,9 +756,9 @@ gst_pipewire_sink_close (GstPipeWireSink * pwsink) pwsink->stream = NULL; } - if (pwsink->remote) { - pw_remote_destroy (pwsink->remote); - pwsink->remote = NULL; + if (pwsink->core) { + pw_core_disconnect (pwsink->core); + pwsink->core = NULL; } return TRUE; diff --git a/src/gst/gstpipewiresink.h b/src/gst/gstpipewiresink.h index 5c4dffdd..b57b827b 100644 --- a/src/gst/gstpipewiresink.h +++ b/src/gst/gstpipewiresink.h @@ -86,9 +86,8 @@ struct _GstPipeWireSink { struct pw_loop *loop; struct pw_thread_loop *main_loop; - struct pw_impl_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core *core; + struct spa_hook core_listener; struct pw_stream *stream; struct spa_hook stream_listener; diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index 7d148a92..b1efbeae 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -208,7 +208,7 @@ gst_pipewire_src_finalize (GObject * object) clear_queue (pwsrc); - pw_impl_core_destroy (pwsrc->core); + pw_proxy_destroy ((struct pw_proxy*)pwsrc->core); pwsrc->core = NULL; pw_thread_loop_destroy (pwsrc->main_loop); pwsrc->main_loop = NULL; @@ -331,7 +331,6 @@ gst_pipewire_src_init (GstPipeWireSrc * src) src->pool = gst_pipewire_pool_new (); src->loop = pw_loop_new (NULL); src->main_loop = pw_thread_loop_new (src->loop, "pipewire-main-loop"); - src->core = pw_impl_core_new (src->loop, NULL, 0); GST_DEBUG ("loop %p, mainloop %p", src->loop, src->main_loop); } @@ -504,9 +503,6 @@ gst_pipewire_src_stream_start (GstPipeWireSrc *pwsrc) if (state == PW_STREAM_STATE_ERROR) goto start_error; - if (pw_remote_get_state(pwsrc->remote, &error) == PW_REMOTE_STATE_ERROR) - goto start_error; - pw_thread_loop_wait (pwsrc->main_loop); } @@ -542,9 +538,6 @@ wait_negotiated (GstPipeWireSrc *this) if (state == PW_STREAM_STATE_ERROR) break; - if (pw_remote_get_state(this->remote, &error) == PW_REMOTE_STATE_ERROR) - break; - if (this->started) break; @@ -638,9 +631,6 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc) if (state == PW_STREAM_STATE_ERROR) goto connect_error; - if (pw_remote_get_state(pwsrc->remote, &error) == PW_REMOTE_STATE_ERROR) - goto connect_error; - pw_thread_loop_wait (pwsrc->main_loop); } pw_thread_loop_unlock (pwsrc->main_loop); @@ -915,26 +905,6 @@ gst_pipewire_src_stop (GstBaseSrc * basesrc) return TRUE; } -static void -on_remote_state_changed (void *data, enum pw_remote_state old, enum pw_remote_state state, const char *error) -{ - GstPipeWireSrc *pwsrc = data; - - GST_DEBUG ("got remote state %s", pw_remote_state_as_string (state)); - - switch (state) { - case PW_REMOTE_STATE_UNCONNECTED: - case PW_REMOTE_STATE_CONNECTING: - case PW_REMOTE_STATE_CONNECTED: - break; - case PW_REMOTE_STATE_ERROR: - GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, - ("remote error: %s", error), (NULL)); - break; - } - pw_thread_loop_signal (pwsrc->main_loop, FALSE); -} - static gboolean copy_properties (GQuark field_id, const GValue *value, @@ -949,9 +919,20 @@ copy_properties (GQuark field_id, return TRUE; } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_remote_state_changed, +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) +{ + GstPipeWireSrc *pwsrc = data; + GST_DEBUG ("got error id:%u %s", id, message); + if (id == 0) { + GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, + ("core error: %s", message), (NULL)); + } + pw_thread_loop_signal (pwsrc->main_loop, FALSE); +} + +static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, + .error = on_core_error, }; static const struct pw_stream_events stream_events = { @@ -967,34 +948,26 @@ static gboolean gst_pipewire_src_open (GstPipeWireSrc * pwsrc) { struct pw_properties *props; - const char *error = NULL; if (pw_thread_loop_start (pwsrc->main_loop) < 0) goto mainloop_failed; pw_thread_loop_lock (pwsrc->main_loop); - if ((pwsrc->remote = pw_remote_new (pwsrc->core, NULL, 0)) == NULL) - goto no_remote; - - pw_remote_add_listener (pwsrc->remote, - &pwsrc->remote_listener, - &remote_events, pwsrc); if (pwsrc->fd == -1) - pw_remote_connect (pwsrc->remote); + pwsrc->core = pw_core_connect (pwsrc->loop, NULL, 0); else - pw_remote_connect_fd (pwsrc->remote, dup(pwsrc->fd)); - - while (TRUE) { - enum pw_remote_state state = pw_remote_get_state(pwsrc->remote, &error); + pwsrc->core = pw_core_connect_fd (pwsrc->loop, dup(pwsrc->fd), NULL, 0); - GST_DEBUG ("waiting for CONNECTED, now %s", pw_remote_state_as_string (state)); - if (state == PW_REMOTE_STATE_CONNECTED) - break; + if (pwsrc->core == NULL) + goto no_core; - if (state == PW_REMOTE_STATE_ERROR) - goto connect_error; + pw_core_add_listener (pwsrc->core, + &pwsrc->core_listener, + &core_events, pwsrc); + while (TRUE) { + GST_DEBUG ("waiting for CONNECTED"); pw_thread_loop_wait (pwsrc->main_loop); } @@ -1005,10 +978,9 @@ gst_pipewire_src_open (GstPipeWireSrc * pwsrc) props = NULL; } - if ((pwsrc->stream = pw_stream_new (pwsrc->remote, pwsrc->client_name, props)) == NULL) + if ((pwsrc->stream = pw_stream_new (pwsrc->core, pwsrc->client_name, props)) == NULL) goto no_stream; - pw_stream_add_listener(pwsrc->stream, &pwsrc->stream_listener, &stream_events, @@ -1026,14 +998,9 @@ mainloop_failed: GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("error starting mainloop"), (NULL)); return FALSE; } -no_remote: - { - GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("can't create remote"), (NULL)); - pw_thread_loop_unlock (pwsrc->main_loop); - return FALSE; - } -connect_error: +no_core: { + GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("can't create core"), (NULL)); pw_thread_loop_unlock (pwsrc->main_loop); return FALSE; } @@ -1065,8 +1032,8 @@ gst_pipewire_src_close (GstPipeWireSrc * pwsrc) pw_stream_destroy (pwsrc->stream); pwsrc->stream = NULL; - pw_remote_destroy (pwsrc->remote); - pwsrc->remote = NULL; + pw_core_disconnect (pwsrc->core); + pwsrc->core = NULL; } static GstStateChangeReturn diff --git a/src/gst/gstpipewiresrc.h b/src/gst/gstpipewiresrc.h index 6391fb73..7c8ed791 100644 --- a/src/gst/gstpipewiresrc.h +++ b/src/gst/gstpipewiresrc.h @@ -74,9 +74,8 @@ struct _GstPipeWireSrc { struct pw_loop *loop; struct pw_thread_loop *main_loop; - struct pw_impl_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core *core; + struct spa_hook core_listener; struct pw_stream *stream; struct spa_hook stream_listener; diff --git a/src/modules/module-client-device.c b/src/modules/module-client-device.c index 24875f69..ff538dcf 100644 --- a/src/modules/module-client-device.c +++ b/src/modules/module-client-device.c @@ -32,6 +32,7 @@ #include <spa/utils/result.h> #include <pipewire/impl.h> +#include <pipewire/private.h> #include "module-client-device/client-device.h" @@ -189,7 +190,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) data->export_spadevice.type = SPA_TYPE_INTERFACE_Device; data->export_spadevice.func = pw_remote_spa_device_export; - pw_impl_core_register_export_type(core, &data->export_spadevice); + pw_context_register_export_type(core->context, &data->export_spadevice); pw_impl_module_add_listener(module, &data->module_listener, &module_events, data); diff --git a/src/modules/module-client-device/protocol-native.c b/src/modules/module-client-device/protocol-native.c index 826ec5ea..bb37380d 100644 --- a/src/modules/module-client-device/protocol-native.c +++ b/src/modules/module-client-device/protocol-native.c @@ -536,11 +536,11 @@ static const struct pw_protocol_marshal pw_protocol_native_client_device_marshal .client_demarshal = pw_protocol_native_device_method_demarshal, }; -struct pw_protocol *pw_protocol_native_ext_client_device_init(struct pw_impl_core *core) +struct pw_protocol *pw_protocol_native_ext_client_device_init(struct pw_context *context) { struct pw_protocol *protocol; - protocol = pw_impl_core_find_protocol(core, PW_TYPE_INFO_PROTOCOL_Native); + protocol = pw_context_find_protocol(context, PW_TYPE_INFO_PROTOCOL_Native); if (protocol == NULL) return NULL; diff --git a/src/modules/module-client-device/proxy-device.c b/src/modules/module-client-device/proxy-device.c index 432fa232..bf6cec75 100644 --- a/src/modules/module-client-device/proxy-device.c +++ b/src/modules/module-client-device/proxy-device.c @@ -79,7 +79,7 @@ struct pw_proxy *pw_remote_spa_device_export(struct pw_remote *remote, data = SPA_MEMBER(data, user_data_size, struct device_data); data->remote = remote; data->device = device; - data->core_impl = pw_remote_get_core_impl(remote); + data->core_impl = remote->context->core_impl; data->proxy = proxy; iface = (struct spa_interface*)proxy; diff --git a/src/modules/module-client-node.c b/src/modules/module-client-node.c index 0309c851..64afe36d 100644 --- a/src/modules/module-client-node.c +++ b/src/modules/module-client-node.c @@ -32,6 +32,7 @@ #include <spa/utils/result.h> #include <pipewire/impl.h> +#include <pipewire/private.h> #include "module-client-node/v0/client-node.h" #include "module-client-node/client-node.h" @@ -179,11 +180,11 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) data->export_node.type = PW_TYPE_INTERFACE_Node; data->export_node.func = pw_remote_node_export; - pw_impl_core_register_export_type(core, &data->export_node); + pw_context_register_export_type(core->context, &data->export_node); data->export_spanode.type = SPA_TYPE_INTERFACE_Node; data->export_spanode.func = pw_remote_spa_node_export; - pw_impl_core_register_export_type(core, &data->export_spanode); + pw_context_register_export_type(core->context, &data->export_spanode); pw_impl_module_add_listener(module, &data->module_listener, &module_events, data); diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index 5e1a3b6a..6b43fc9e 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -1157,11 +1157,11 @@ static const struct pw_protocol_marshal pw_protocol_native_client_node_marshal = .client_demarshal = pw_protocol_native_client_node_event_demarshal, }; -struct pw_protocol *pw_protocol_native_ext_client_node_init(struct pw_impl_core *core) +struct pw_protocol *pw_protocol_native_ext_client_node_init(struct pw_context *context) { struct pw_protocol *protocol; - protocol = pw_impl_core_find_protocol(core, PW_TYPE_INFO_PROTOCOL_Native); + protocol = pw_context_find_protocol(context, PW_TYPE_INFO_PROTOCOL_Native); if (protocol == NULL) return NULL; diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index 13796035..8add002a 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -1180,7 +1180,7 @@ struct pw_proxy *pw_remote_spa_node_export(struct pw_remote *remote, { struct pw_impl_node *node; - node = pw_impl_node_new(pw_remote_get_core_impl(remote), props, 0); + node = pw_impl_node_new(remote->context->core_impl, props, 0); if (node == NULL) return NULL; diff --git a/src/modules/module-client-node/v0/protocol-native.c b/src/modules/module-client-node/v0/protocol-native.c index c4242b9a..e7a962ca 100644 --- a/src/modules/module-client-node/v0/protocol-native.c +++ b/src/modules/module-client-node/v0/protocol-native.c @@ -502,11 +502,11 @@ static const struct pw_protocol_marshal pw_protocol_native_client_node_marshal = NULL, }; -struct pw_protocol *pw_protocol_native_ext_client_node0_init(struct pw_impl_core *core) +struct pw_protocol *pw_protocol_native_ext_client_node0_init(struct pw_context *context) { struct pw_protocol *protocol; - protocol = pw_impl_core_find_protocol(core, PW_TYPE_INFO_PROTOCOL_Native); + protocol = pw_context_find_protocol(context, PW_TYPE_INFO_PROTOCOL_Native); if (protocol == NULL) return NULL; diff --git a/src/modules/module-metadata.c b/src/modules/module-metadata.c index 50023fb6..d7ce1eee 100644 --- a/src/modules/module-metadata.c +++ b/src/modules/module-metadata.c @@ -32,6 +32,7 @@ #include <spa/utils/result.h> #include <pipewire/impl.h> +#include <pipewire/private.h> #include <extensions/metadata.h> #define NAME "metadata" @@ -175,7 +176,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) data->export_metadata.type = PW_TYPE_INTERFACE_Metadata; data->export_metadata.func = pw_remote_metadata_export; - pw_impl_core_register_export_type(core, &data->export_metadata); + pw_context_register_export_type(core->context, &data->export_metadata); pw_impl_module_add_listener(module, &data->module_listener, &module_events, data); diff --git a/src/modules/module-metadata/protocol-native.c b/src/modules/module-metadata/protocol-native.c index a4a1e615..fc7740ef 100644 --- a/src/modules/module-metadata/protocol-native.c +++ b/src/modules/module-metadata/protocol-native.c @@ -321,11 +321,11 @@ static const struct pw_protocol_marshal pw_protocol_native_metadata_impl_marshal .client_demarshal = pw_protocol_native_metadata_client_method_demarshal, }; -int pw_protocol_native_ext_metadata_init(struct pw_impl_core *core) +int pw_protocol_native_ext_metadata_init(struct pw_context *context) { struct pw_protocol *protocol; - protocol = pw_impl_core_find_protocol(core, PW_TYPE_INFO_PROTOCOL_Native); + protocol = pw_context_find_protocol(context, PW_TYPE_INFO_PROTOCOL_Native); if (protocol == NULL) return -EPROTO; diff --git a/src/modules/module-metadata/proxy-metadata.c b/src/modules/module-metadata/proxy-metadata.c index c7f88f4f..bb79a4a8 100644 --- a/src/modules/module-metadata/proxy-metadata.c +++ b/src/modules/module-metadata/proxy-metadata.c @@ -34,7 +34,7 @@ struct object_data { struct pw_remote *remote; - struct pw_impl_core *core; + struct pw_impl_core *core_impl; struct pw_metadata *object; struct spa_hook object_listener; @@ -79,7 +79,7 @@ struct pw_proxy *pw_remote_metadata_export(struct pw_remote *remote, data = SPA_MEMBER(data, user_data_size, struct object_data); data->remote = remote; data->object = object; - data->core = pw_remote_get_core_impl(remote); + data->core_impl = remote->context->core_impl; data->proxy = proxy; iface = (struct spa_interface*)proxy; diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index 6add3308..a5bbedf7 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -43,6 +43,7 @@ #endif #include <pipewire/impl.h> +#include <pipewire/protocol.h> #include <extensions/protocol-native.h> #include "pipewire/map.h" @@ -80,6 +81,7 @@ struct protocol_data { struct client { struct pw_protocol_client this; + struct pw_context *context; struct spa_source *source; struct pw_protocol_native_connection *connection; @@ -223,6 +225,7 @@ client_busy_changed(void *data, bool busy) { struct client_data *c = data; struct pw_impl_client *client = c->client; + struct pw_context *context = client->core->context; uint32_t mask = c->source->mask; c->busy = busy; @@ -230,7 +233,7 @@ client_busy_changed(void *data, bool busy) SPA_FLAG_UPDATE(mask, SPA_IO_IN, !busy); pw_log_debug(NAME" %p: busy changed %d", client->protocol, busy); - pw_loop_update_io(client->core->main_loop, c->source, mask); + pw_loop_update_io(context->main_loop, c->source, mask); if (!busy) process_messages(c); @@ -259,7 +262,7 @@ connection_data(void *data, int fd, uint32_t mask) if (res >= 0) { int mask = this->source->mask; SPA_FLAG_CLEAR(mask, SPA_IO_OUT); - pw_loop_update_io(client->protocol->core->main_loop, + pw_loop_update_io(client->protocol->context->main_loop, this->source, mask); } else if (res != EAGAIN) { pw_log_error("client %p: could not flush: %s", @@ -280,7 +283,7 @@ static void client_free(void *data) spa_list_remove(&client->protocol_link); if (this->source) - pw_loop_destroy_source(client->protocol->core->main_loop, this->source); + pw_loop_destroy_source(client->protocol->context->main_loop, this->source); if (this->connection) pw_protocol_native_connection_destroy(this->connection); @@ -323,7 +326,7 @@ static struct pw_impl_client *client_new(struct server *s, int fd) struct pw_protocol *protocol = s->this.protocol; socklen_t len; struct ucred ucred; - struct pw_impl_core *core = protocol->core; + struct pw_context *context = protocol->context; struct pw_properties *props; char buffer[1024]; struct protocol_data *d = pw_protocol_get_user_data(protocol); @@ -353,7 +356,7 @@ static struct pw_impl_client *client_new(struct server *s, int fd) pw_properties_setf(props, PW_KEY_MODULE_ID, "%d", d->module->global->id); - client = pw_impl_client_new(protocol->core, + client = pw_impl_client_new(context->core_impl, props, sizeof(struct client_data)); if (client == NULL) @@ -364,7 +367,7 @@ static struct pw_impl_client *client_new(struct server *s, int fd) spa_list_append(&s->this.client_list, &client->protocol_link); this->client = client; - this->source = pw_loop_add_io(pw_impl_core_get_main_loop(core), + this->source = pw_loop_add_io(context->main_loop, fd, SPA_IO_ERR | SPA_IO_HUP, true, connection_data, this); if (this->source == NULL) { @@ -372,7 +375,7 @@ static struct pw_impl_client *client_new(struct server *s, int fd) goto cleanup_client; } - this->connection = pw_protocol_native_connection_new(protocol->core, fd); + this->connection = pw_protocol_native_connection_new(protocol->context, fd); if (this->connection == NULL) { res = -errno; goto cleanup_client; @@ -481,7 +484,7 @@ socket_data(void *data, int fd, uint32_t mask) c = client->user_data; if (!client->busy) - pw_loop_update_io(client->protocol->core->main_loop, + pw_loop_update_io(client->protocol->context->main_loop, c->source, c->source->mask | SPA_IO_IN); } @@ -540,7 +543,7 @@ static int add_socket(struct pw_protocol *protocol, struct server *s) } s->activated = activated; - s->loop = pw_impl_core_get_main_loop(protocol->core); + s->loop = protocol->context->main_loop; if (s->loop == NULL) { res = -errno; goto error_close; @@ -579,9 +582,9 @@ static void on_remote_data(void *data, int fd, uint32_t mask) { struct client *impl = data; - struct pw_remote *this = impl->this.remote; + struct pw_context *context = impl->context; + struct pw_remote *this = context->remote; struct pw_protocol_native_connection *conn = impl->connection; - struct pw_impl_core *core = pw_remote_get_core_impl(this); int res; if (mask & (SPA_IO_ERR | SPA_IO_HUP)) { @@ -593,7 +596,7 @@ on_remote_data(void *data, int fd, uint32_t mask) if (res >= 0) { int mask = impl->source->mask; SPA_FLAG_CLEAR(mask, SPA_IO_OUT); - pw_loop_update_io(core->main_loop, + pw_loop_update_io(context->main_loop, impl->source, mask); impl->flushing = false; } else if (res != EAGAIN) @@ -666,8 +669,10 @@ on_remote_data(void *data, int fd, uint32_t mask) } return; error: - pw_log_error(NAME" %p: got connection error %d (%s)", impl, res, spa_strerror(res)); - pw_loop_destroy_source(pw_impl_core_get_main_loop(core), impl->source); + pw_log_error(NAME" %p: got connection error %d (%s)", this, res, spa_strerror(res)); + pw_loop_destroy_source(context->main_loop, impl->source); + pw_proxy_notify((struct pw_proxy*)this->core, + struct pw_core_events, error, 0, 0, 0, res, spa_strerror(res)); impl->source = NULL; pw_remote_disconnect(this); } @@ -676,13 +681,12 @@ error: static void on_need_flush(void *data) { struct client *impl = data; - struct pw_remote *remote = impl->this.remote; if (!impl->flushing && impl->source) { int mask = impl->source->mask; impl->flushing = true; SPA_FLAG_SET(mask, SPA_IO_OUT); - pw_loop_update_io(remote->core_impl->main_loop, + pw_loop_update_io(impl->context->main_loop, impl->source, mask); } } @@ -695,18 +699,12 @@ static const struct pw_protocol_native_connection_events client_conn_events = { static int impl_connect_fd(struct pw_protocol_client *client, int fd, bool do_close) { struct client *impl = SPA_CONTAINER_OF(client, struct client, this); - struct pw_remote *remote = client->remote; int res; impl->disconnecting = false; - impl->connection = pw_protocol_native_connection_new(remote->core_impl, fd); - if (impl->connection == NULL) { - res = -errno; - goto error_cleanup; - } - - impl->source = pw_loop_add_io(remote->core_impl->main_loop, + pw_protocol_native_connection_set_fd(impl->connection, fd); + impl->source = pw_loop_add_io(impl->context->main_loop, fd, SPA_IO_IN | SPA_IO_HUP | SPA_IO_ERR, do_close, on_remote_data, impl); @@ -732,12 +730,12 @@ error_cleanup: static void impl_disconnect(struct pw_protocol_client *client) { struct client *impl = SPA_CONTAINER_OF(client, struct client, this); - struct pw_remote *remote = client->remote; + struct pw_context *context = impl->context; impl->disconnecting = true; if (impl->source) - pw_loop_destroy_source(remote->core_impl->main_loop, impl->source); + pw_loop_destroy_source(context->main_loop, impl->source); impl->source = NULL; if (impl->connection) @@ -764,13 +762,13 @@ impl_new_client(struct pw_protocol *protocol, struct pw_remote *remote = proxy->remote; struct pw_protocol_client *this; const char *str = NULL; + int res; if ((impl = calloc(1, sizeof(struct client))) == NULL) return NULL; this = &impl->this; this->protocol = protocol; - this->remote = remote; if (properties) str = pw_properties_get(properties, PW_KEY_REMOTE_INTENTION); @@ -787,9 +785,21 @@ impl_new_client(struct pw_protocol *protocol, this->disconnect = impl_disconnect; this->destroy = impl_destroy; + impl->context = remote->context; + impl->connection = pw_protocol_native_connection_new(impl->context, -1); + if (impl->connection == NULL) { + res = -errno; + goto error_free; + } + spa_list_append(&protocol->client_list, &this->link); return this; + +error_free: + free(impl); + errno = -res; + return NULL; } static void destroy_server(struct pw_protocol_server *server) @@ -831,7 +841,7 @@ static void on_before_hook(void *_data) if (res == -EAGAIN) { int mask = data->source->mask; SPA_FLAG_SET(mask, SPA_IO_OUT); - pw_loop_update_io(client->protocol->core->main_loop, + pw_loop_update_io(client->protocol->context->main_loop, data->source, mask); } else if (res < 0) { pw_log_warn("client %p: could not flush: %s", @@ -866,7 +876,7 @@ impl_add_server(struct pw_protocol *protocol, struct pw_properties *properties) { struct pw_protocol_server *this; - struct pw_impl_core *core = protocol->core; + struct pw_context *context = protocol->context; struct server *s; const char *name; int res; @@ -883,9 +893,9 @@ impl_add_server(struct pw_protocol *protocol, spa_list_append(&protocol->server_list, &this->link); - name = get_name(core->properties); + name = get_name(context->properties); - pw_loop_add_hook(pw_impl_core_get_main_loop(core), &s->hook, &impl_hooks, s); + pw_loop_add_hook(context->main_loop, &s->hook, &impl_hooks, s); if ((res = init_socket_name(s, name)) < 0) goto error; @@ -995,15 +1005,16 @@ SPA_EXPORT int pipewire__module_init(struct pw_impl_module *module, const char *args) { struct pw_impl_core *core = pw_impl_module_get_core_impl(module); + struct pw_context *context = core->context; struct pw_protocol *this; const char *val; struct protocol_data *d; int res; - if (pw_impl_core_find_protocol(core, PW_TYPE_INFO_PROTOCOL_Native) != NULL) + if (pw_context_find_protocol(context, PW_TYPE_INFO_PROTOCOL_Native) != NULL) return 0; - this = pw_protocol_new(core, PW_TYPE_INFO_PROTOCOL_Native, sizeof(struct protocol_data)); + this = pw_protocol_new(context, PW_TYPE_INFO_PROTOCOL_Native, sizeof(struct protocol_data)); if (this == NULL) return -errno; diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c index 7684a404..cb96ee65 100644 --- a/src/modules/module-protocol-native/connection.c +++ b/src/modules/module-protocol-native/connection.c @@ -63,7 +63,7 @@ struct buffer { struct impl { struct pw_protocol_native_connection this; - struct pw_impl_core *core; + struct pw_context *context; struct buffer in, out; struct spa_pod_builder builder; @@ -225,7 +225,7 @@ static void clear_buffer(struct buffer *buf) * * \memberof pw_protocol_native_connection */ -struct pw_protocol_native_connection *pw_protocol_native_connection_new(struct pw_impl_core *core, int fd) +struct pw_protocol_native_connection *pw_protocol_native_connection_new(struct pw_context *context, int fd) { struct impl *impl; struct pw_protocol_native_connection *this; @@ -235,7 +235,7 @@ struct pw_protocol_native_connection *pw_protocol_native_connection_new(struct p return NULL; debug_messages = pw_debug_is_category_enabled("connection"); - impl->core = core; + impl->context = context; this = &impl->this; @@ -265,6 +265,10 @@ no_mem: free(impl); return NULL; } +void pw_protocol_native_connection_set_fd(struct pw_protocol_native_connection *conn, int fd) +{ + conn->fd = fd; +} /** Destroy a connection * diff --git a/src/modules/module-protocol-native/connection.h b/src/modules/module-protocol-native/connection.h index cdbbec56..8a4fd8a4 100644 --- a/src/modules/module-protocol-native/connection.h +++ b/src/modules/module-protocol-native/connection.h @@ -70,7 +70,9 @@ pw_protocol_native_connection_add_listener(struct pw_protocol_native_connection } struct pw_protocol_native_connection * -pw_protocol_native_connection_new(struct pw_impl_core *core, int fd); +pw_protocol_native_connection_new(struct pw_context *context, int fd); + +void pw_protocol_native_connection_set_fd(struct pw_protocol_native_connection *conn, int fd); void pw_protocol_native_connection_destroy(struct pw_protocol_native_connection *conn); diff --git a/src/modules/module-protocol-native/defs.h b/src/modules/module-protocol-native/defs.h index 92f155c7..a1c9ba36 100644 --- a/src/modules/module-protocol-native/defs.h +++ b/src/modules/module-protocol-native/defs.h @@ -23,8 +23,10 @@ */ int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client, + const struct spa_dict *props, void (*done_callback) (void *data, int res), void *data); int pw_protocol_native_connect_portal_screencast(struct pw_protocol_client *client, + const struct spa_dict *props, void (*done_callback) (void *data, int res), void *data); diff --git a/src/modules/module-protocol-native/local-socket.c b/src/modules/module-protocol-native/local-socket.c index 49373347..8622b326 100644 --- a/src/modules/module-protocol-native/local-socket.c +++ b/src/modules/module-protocol-native/local-socket.c @@ -37,12 +37,12 @@ #include <pipewire/pipewire.h> static const char * -get_remote(const struct pw_properties *properties) +get_remote(const struct spa_dict *props) { const char *name = NULL; - if (properties) - name = pw_properties_get(properties, PW_KEY_REMOTE_NAME); + if (props) + name = spa_dict_lookup(props, PW_KEY_REMOTE_NAME); if (name == NULL) name = getenv("PIPEWIRE_REMOTE"); if (name == NULL) @@ -51,10 +51,10 @@ get_remote(const struct pw_properties *properties) } int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client, + const struct spa_dict *props, void (*done_callback) (void *data, int res), void *data) { - struct pw_remote *remote = client->remote; struct sockaddr_un addr; socklen_t size; const char *runtime_dir, *name = NULL; @@ -66,7 +66,7 @@ int pw_protocol_native_connect_local_socket(struct pw_protocol_client *client, goto error; } - name = get_remote(pw_remote_get_properties(remote)); + name = get_remote(props); if ((fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0) { res = -errno; diff --git a/src/modules/module-protocol-native/portal-screencast.c b/src/modules/module-protocol-native/portal-screencast.c index d5f2ba59..7cb66148 100644 --- a/src/modules/module-protocol-native/portal-screencast.c +++ b/src/modules/module-protocol-native/portal-screencast.c @@ -33,6 +33,7 @@ #include <pipewire/pipewire.h> int pw_protocol_native_connect_portal_screencast(struct pw_protocol_client *client, + const struct spa_dict *props, void (*done_callback) (void *data, int res), void *data) { diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index 1f5b692f..5ca29c18 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -30,6 +30,7 @@ #include <spa/utils/result.h> #include <pipewire/pipewire.h> +#include <pipewire/protocol.h> #include <extensions/protocol-native.h> #include "connection.h" @@ -226,13 +227,13 @@ core_method_marshal_create_object(void *object, } static int -core_method_marshal_destroy(void *object, void *p) +core_method_marshal_destroy_object(void *object, void *p) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; uint32_t id = pw_proxy_get_id(p); - b = pw_protocol_native_begin_proxy(proxy, PW_CORE_METHOD_DESTROY, NULL); + b = pw_protocol_native_begin_proxy(proxy, PW_CORE_METHOD_DESTROY_OBJECT, NULL); spa_pod_builder_add_struct(b, SPA_POD_Int(id)); @@ -599,6 +600,7 @@ static int core_method_demarshal_create_object(void *object, const struct pw_pro const char *factory_name; struct spa_dict props = SPA_DICT_INIT(NULL, 0); + pw_log_debug("."); spa_pod_parser_init(&prs, msg->data, msg->size); if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 || spa_pod_parser_get(&prs, @@ -608,26 +610,30 @@ static int core_method_demarshal_create_object(void *object, const struct pw_pro NULL) < 0) return -EINVAL; + pw_log_debug("."); if (spa_pod_parser_push_struct(&prs, &f[1]) < 0 || spa_pod_parser_get(&prs, SPA_POD_Int(&props.n_items), NULL) < 0) return -EINVAL; + pw_log_debug("."); props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); if (parse_dict(&prs, &props) < 0) return -EINVAL; spa_pod_parser_pop(&prs, &f[1]); + pw_log_debug("."); if (spa_pod_parser_get(&prs, SPA_POD_Int(&new_id), NULL) < 0) return -EINVAL; + pw_log_debug("."); return pw_resource_notify(resource, struct pw_core_methods, create_object, 0, factory_name, type, version, &props, new_id); } -static int core_method_demarshal_destroy(void *object, const struct pw_protocol_native_message *msg) +static int core_method_demarshal_destroy_object(void *object, const struct pw_protocol_native_message *msg) { struct pw_resource *resource = object; struct pw_impl_client *client = pw_resource_get_client(resource); @@ -645,7 +651,7 @@ static int core_method_demarshal_destroy(void *object, const struct pw_protocol_ if ((r = pw_impl_client_find_resource(client, id)) == NULL) goto no_resource; - return pw_resource_notify(resource, struct pw_core_methods, destroy, 0, r); + return pw_resource_notify(resource, struct pw_core_methods, destroy_object, 0, r); no_resource: pw_log_error("client %p: unknown resouce %u op:%u", client, id, msg->opcode); @@ -1902,7 +1908,7 @@ static const struct pw_core_methods pw_protocol_native_core_method_marshal = { .error = &core_method_marshal_error, .get_registry = &core_method_marshal_get_registry, .create_object = &core_method_marshal_create_object, - .destroy = &core_method_marshal_destroy, + .destroy_object = &core_method_marshal_destroy_object, }; static const struct pw_protocol_native_demarshal pw_protocol_native_core_method_demarshal[PW_CORE_METHOD_NUM] = { @@ -1913,7 +1919,7 @@ static const struct pw_protocol_native_demarshal pw_protocol_native_core_method_ [PW_CORE_METHOD_ERROR] = { &core_method_demarshal_error, 0, }, [PW_CORE_METHOD_GET_REGISTRY] = { &core_method_demarshal_get_registry, 0, }, [PW_CORE_METHOD_CREATE_OBJECT] = { &core_method_demarshal_create_object, 0, }, - [PW_CORE_METHOD_DESTROY] = { &core_method_demarshal_destroy, 0, } + [PW_CORE_METHOD_DESTROY_OBJECT] = { &core_method_demarshal_destroy_object, 0, } }; static const struct pw_core_events pw_protocol_native_core_event_marshal = { diff --git a/src/modules/module-protocol-native/test-connection.c b/src/modules/module-protocol-native/test-connection.c index be188e03..f2965694 100644 --- a/src/modules/module-protocol-native/test-connection.c +++ b/src/modules/module-protocol-native/test-connection.c @@ -123,23 +123,23 @@ static void test_read_write(struct pw_protocol_native_connection *in, int main(int argc, char *argv[]) { struct pw_main_loop *loop; - struct pw_impl_core *core; + struct pw_context *context; struct pw_protocol_native_connection *in, *out; int fds[2]; pw_init(&argc, &argv); loop = pw_main_loop_new(NULL); - core = pw_impl_core_new(pw_main_loop_get_loop(loop), NULL, 0); + context = pw_context_new(pw_main_loop_get_loop(loop), NULL, 0); if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { spa_assert_not_reached(); return -1; } - in = pw_protocol_native_connection_new(core, fds[0]); + in = pw_protocol_native_connection_new(context, fds[0]); spa_assert(in != NULL); - out = pw_protocol_native_connection_new(core, fds[1]); + out = pw_protocol_native_connection_new(context, fds[1]); spa_assert(out != NULL); test_create(in); diff --git a/src/modules/module-protocol-native/v0/protocol-native.c b/src/modules/module-protocol-native/v0/protocol-native.c index 5304e9cf..b39b503d 100644 --- a/src/modules/module-protocol-native/v0/protocol-native.c +++ b/src/modules/module-protocol-native/v0/protocol-native.c @@ -644,7 +644,7 @@ static int core_demarshal_destroy(void *object, const struct pw_protocol_native_ if ((r = pw_impl_client_find_resource(client, id)) == NULL) goto no_resource; - return pw_resource_notify(resource, struct pw_core_methods, destroy, 0, r); + return pw_resource_notify(resource, struct pw_core_methods, destroy_object, 0, r); no_resource: pw_log_error("client %p: unknown resouce %u op:%u", client, id, msg->opcode); diff --git a/src/modules/module-session-manager/protocol-native.c b/src/modules/module-session-manager/protocol-native.c index 12e3deb3..e017330a 100644 --- a/src/modules/module-session-manager/protocol-native.c +++ b/src/modules/module-session-manager/protocol-native.c @@ -2001,11 +2001,11 @@ static const struct pw_protocol_marshal pw_protocol_native_session_marshal = { &pw_protocol_native_session_event_demarshal, }; -struct pw_protocol *pw_protocol_native_ext_session_manager_init(struct pw_impl_core *core) +struct pw_protocol *pw_protocol_native_ext_session_manager_init(struct pw_context *context) { struct pw_protocol *protocol; - protocol = pw_impl_core_find_protocol(core, PW_TYPE_INFO_PROTOCOL_Native); + protocol = pw_context_find_protocol(context, PW_TYPE_INFO_PROTOCOL_Native); if (protocol == NULL) return NULL; diff --git a/src/modules/spa/spa-device.h b/src/modules/spa/spa-device.h index 3f286099..c9492d06 100644 --- a/src/modules/spa/spa-device.h +++ b/src/modules/spa/spa-device.h @@ -27,7 +27,8 @@ #include <spa/monitor/device.h> -#include <pipewire/core.h> +#include <pipewire/impl-core.h> +#include <pipewire/properties.h> #include <pipewire/device.h> #ifdef __cplusplus diff --git a/src/pipewire/api.h b/src/pipewire/api.h new file mode 100644 index 00000000..ecfe471d --- /dev/null +++ b/src/pipewire/api.h @@ -0,0 +1,53 @@ +/* PipeWire + * + * Copyright © 2019 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef PIPEWIRE_API_H +#define PIPEWIRE_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <pipewire/pipewire.h> + +/** connect to a core */ +struct pw_core * +pw_core_connect(struct pw_loop *loop, struct pw_properties *props, size_t user_data_size); + +struct pw_core * +pw_core_connect_fd(struct pw_loop *loop, int fd, struct pw_properties *props, size_t user_data_size); + +struct pw_context * pw_core_get_context(struct pw_core *core); + +struct pw_client * pw_core_get_client(struct pw_core *core); + +int pw_core_update_client_properties(struct pw_core *core, const struct spa_dict *props); + +void pw_core_disconnect(struct pw_core *core); + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_API_H */ diff --git a/src/pipewire/context.c b/src/pipewire/context.c new file mode 100644 index 00000000..e1bcb575 --- /dev/null +++ b/src/pipewire/context.c @@ -0,0 +1,256 @@ +/* PipeWire + * + * Copyright © 2019 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <unistd.h> +#include <regex.h> + +#include <spa/support/cpu.h> +#include <spa/support/dbus.h> +#include <spa/node/utils.h> +#include <spa/utils/names.h> + +#include <pipewire/context.h> +#include <pipewire/private.h> +#include <pipewire/data-loop.h> + +#define NAME "context" + +struct impl { + struct pw_context this; + struct spa_handle *dbus_handle; +}; + +struct factory_entry { + regex_t regex; + char *lib; +}; + +SPA_EXPORT +struct pw_context * +pw_context_new(struct pw_loop *main_loop, struct pw_properties *properties, + size_t user_data_size) +{ + struct impl *impl; + struct pw_context *this; + const char *name, *lib, *str; + void *dbus_iface = NULL; + struct pw_properties *pr; + uint32_t n_support; + struct spa_cpu *cpu; + int res = 0; + + impl = calloc(1, sizeof(struct impl) + user_data_size); + if (impl == NULL) { + res = -errno; + goto error; + } + + this = &impl->this; + + pw_log_debug(NAME" %p: new", this); + + if (user_data_size > 0) + this->user_data = SPA_MEMBER(impl, sizeof(struct impl), void); + + if (properties == NULL) + properties = pw_properties_new(NULL, NULL); + if (properties == NULL) { + res = -errno; + goto error_free; + } + + if ((name = pw_properties_get(properties, PW_KEY_CORE_NAME)) == NULL) { + pw_properties_setf(properties, + PW_KEY_CORE_NAME, "pipewire-%s-%d", + pw_get_user_name(), getpid()); + name = pw_properties_get(properties, PW_KEY_CORE_NAME); + } + + this->properties = properties; + + pr = pw_properties_copy(properties); + if ((str = pw_properties_get(pr, "core.data-loop." PW_KEY_LIBRARY_NAME_SYSTEM))) + pw_properties_set(pr, PW_KEY_LIBRARY_NAME_SYSTEM, str); + + this->data_loop_impl = pw_data_loop_new(pr); + pr = NULL; + + if (this->data_loop_impl == NULL) { + res = -errno; + goto error_free; + } + this->data_loop = pw_data_loop_get_loop(this->data_loop_impl); + this->data_system = this->data_loop->system; + this->main_loop = main_loop; + + n_support = pw_get_support(this->support, SPA_N_ELEMENTS(this->support)); + this->support[n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_System, this->main_loop->system); + this->support[n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_Loop, this->main_loop->loop); + this->support[n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_LoopUtils, this->main_loop->utils); + this->support[n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DataSystem, this->data_system); + this->support[n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DataLoop, this->data_loop->loop); + + if ((cpu = spa_support_find(this->support, n_support, SPA_TYPE_INTERFACE_CPU)) != NULL) + pw_properties_setf(properties, PW_KEY_CPU_MAX_ALIGN, "%u", spa_cpu_get_max_align(cpu)); + + lib = pw_properties_get(properties, PW_KEY_LIBRARY_NAME_DBUS); + if (lib == NULL) + lib = "support/libspa-dbus"; + + impl->dbus_handle = pw_load_spa_handle(lib, + SPA_NAME_SUPPORT_DBUS, NULL, + n_support, this->support); + + if (impl->dbus_handle == NULL || + (res = spa_handle_get_interface(impl->dbus_handle, + SPA_TYPE_INTERFACE_DBus, &dbus_iface)) < 0) { + pw_log_warn(NAME" %p: can't load dbus interface: %s", this, spa_strerror(res)); + } else { + this->support[n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DBus, dbus_iface); + } + this->n_support = n_support; + + this->sc_pagesize = sysconf(_SC_PAGESIZE); + + pw_array_init(&this->factory_lib, 32); + spa_list_init(&this->protocol_list); + spa_list_init(&this->export_list); + + return this; + +error_free: + if (pr) + pw_properties_free(pr); + free(impl); +error: + errno = -res; + return NULL; +} + +SPA_EXPORT +void pw_context_destroy(struct pw_context *this) +{ + struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); + struct factory_entry *entry; + + pw_data_loop_destroy(this->data_loop_impl); + + pw_properties_free(this->properties); + + if (impl->dbus_handle) + pw_unload_spa_handle(impl->dbus_handle); + + pw_array_for_each(entry, &this->factory_lib) { + regfree(&entry->regex); + free(entry->lib); + } + pw_array_clear(&this->factory_lib); + free(impl); +} + +SPA_EXPORT +void *pw_context_get_user_data(struct pw_context *context) +{ + return context->user_data; +} + +SPA_EXPORT +const struct spa_support *pw_context_get_support(struct pw_context *context, uint32_t *n_support) +{ + *n_support = context->n_support; + return context->support; +} + +SPA_EXPORT +int pw_context_add_spa_lib(struct pw_context *this, const char *factory_regexp, const char *lib) +{ + struct factory_entry *entry; + int err; + + entry = pw_array_add(&this->factory_lib, sizeof(*entry)); + if (entry == NULL) + return -errno; + + if ((err = regcomp(&entry->regex, factory_regexp, REG_EXTENDED | REG_NOSUB)) != 0) { + char errbuf[1024]; + regerror(err, &entry->regex, errbuf, sizeof(errbuf)); + pw_log_error(NAME" %p: can compile regex: %s", this, errbuf); + pw_array_remove(&this->factory_lib, entry); + return -EINVAL; + } + + entry->lib = strdup(lib); + pw_log_debug(NAME" %p: map factory regex '%s' to '%s", this, + factory_regexp, lib); + return 0; +} + +SPA_EXPORT +const char * pw_context_find_spa_lib(struct pw_context *this, const char *factory_name) +{ + struct factory_entry *entry; + + pw_array_for_each(entry, &this->factory_lib) { + if (regexec(&entry->regex, factory_name, 0, NULL, 0) == 0) + return entry->lib; + } + return NULL; +} + +SPA_EXPORT +struct spa_handle *pw_context_load_spa_handle(struct pw_context *this, + const char *factory_name, + const struct spa_dict *info) +{ + const char *lib; + const struct spa_support *support; + uint32_t n_support; + struct spa_handle *handle; + + pw_log_debug(NAME" %p: load factory %s", this, factory_name); + + lib = pw_context_find_spa_lib(this, factory_name); + if (lib == NULL && info != NULL) + lib = spa_dict_lookup(info, SPA_KEY_LIBRARY_NAME); + if (lib == NULL) { + pw_log_warn(NAME" %p: no library for %s: %m", + this, factory_name); + errno = ENOENT; + return NULL; + } + + support = pw_context_get_support(this, &n_support); + + handle = pw_load_spa_handle(lib, factory_name, + info, n_support, support); + + return handle; +} + +SPA_EXPORT +int pw_context_load_module(struct pw_context *context, + const char *name, const char *args, struct pw_properties *properties) +{ + return 0; +} diff --git a/src/pipewire/context.h b/src/pipewire/context.h new file mode 100644 index 00000000..c0ddd10d --- /dev/null +++ b/src/pipewire/context.h @@ -0,0 +1,73 @@ +/* PipeWire + * + * Copyright © 2019 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef PIPEWIRE_CONTEXT_H +#define PIPEWIRE_CONTEXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct pw_context; + +#include <pipewire/pipewire.h> +#include <pipewire/loop.h> + +/** Make a new context object. */ +struct pw_context * +pw_context_new(struct pw_loop *loop, /**< a main loop */ + struct pw_properties *properties, /**< properties */ + size_t user_data_size /**< size of user data */); + +/** destroy an context */ +void pw_context_destroy(struct pw_context *context); + +/** Get the user_data. The size was given in \ref pw_context_new */ +void *pw_context_get_user_data(struct pw_context *context); + +/** Get the support objects */ +const struct spa_support *pw_context_get_support(struct pw_context *context, uint32_t *n_support); + +/** add a spa library for the given factory_name regex */ +int pw_context_add_spa_lib(struct pw_context *context, const char *factory_regex, const char *lib); + +/** find the library name for a spa factory */ +const char * pw_context_find_spa_lib(struct pw_context *context, const char *factory_name); + +/** load a spa_handle for the given factory name and info */ +struct spa_handle *pw_context_load_spa_handle(struct pw_context *context, + const char *factory_name, + const struct spa_dict *info); + +int pw_context_load_module(struct pw_context *context, + const char *name, /**< name of the module */ + const char *args /**< arguments of the module */, + struct pw_properties *properties /**< extra global properties */); + + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_CONTEXT_H */ diff --git a/src/pipewire/core.c b/src/pipewire/core.c new file mode 100644 index 00000000..903a312f --- /dev/null +++ b/src/pipewire/core.c @@ -0,0 +1,128 @@ +/* PipeWire + * + * Copyright © 2019 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <unistd.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <errno.h> +#include <sys/mman.h> + +#include <spa/pod/parser.h> +#include <spa/debug/types.h> + +#include "pipewire/api.h" +#include "pipewire/private.h" + +#include "extensions/protocol-native.h" + +#define NAME "core" + +/** \cond */ + +struct core { + struct pw_context *context; + struct pw_remote *remote; + + struct pw_properties *properties; + + struct pw_core *core; + struct pw_client *client; +}; + +SPA_EXPORT +struct pw_core *pw_core_connect(struct pw_loop *loop, + struct pw_properties *properties, + size_t user_data_size) +{ + return pw_core_connect_fd(loop, -1, properties, user_data_size); +} + +SPA_EXPORT +struct pw_core *pw_core_connect_fd(struct pw_loop *loop, int fd, + struct pw_properties *properties, + size_t user_data_size) +{ + struct core *impl; + int res; + + impl = calloc(1, sizeof(struct core) + user_data_size); + if (impl == NULL) { + res = -errno; + goto exit_cleanup; + } + pw_log_debug(NAME" %p: new", impl); + + if (properties == NULL) + properties = pw_properties_new(NULL, NULL); + if (properties == NULL) { + res = -errno; + goto exit_free; + } + + impl->context = pw_context_new(loop, pw_properties_copy(properties), 0); + impl->remote = pw_remote_new(impl->context, properties, user_data_size); + + if (fd != -1) + pw_remote_connect_fd(impl->remote, fd); + else + pw_remote_connect(impl->remote); + + impl->core = pw_remote_get_core(impl->remote); + + return impl->core; + +exit_free: + free(impl); +exit_cleanup: + if (properties) + pw_properties_free(properties); + errno = -res; + return NULL; +} + +SPA_EXPORT +struct pw_context * pw_core_get_context(struct pw_core *core) +{ + return ((struct pw_proxy*)core)->remote->context; +} + +SPA_EXPORT +struct pw_client * pw_core_get_client(struct pw_core *core) +{ + return ((struct pw_proxy*)core)->remote->client; +} + +SPA_EXPORT +int pw_core_update_client_properties(struct pw_core *core, const struct spa_dict *props) +{ + struct pw_client *client = pw_core_get_client(core); + return pw_client_update_properties(client, props); +} + +SPA_EXPORT +void pw_core_disconnect(struct pw_core *core) +{ + return pw_proxy_destroy((struct pw_proxy*)core); +} diff --git a/src/pipewire/core.h b/src/pipewire/core.h index 4991c799..54b20ae5 100644 --- a/src/pipewire/core.h +++ b/src/pipewire/core.h @@ -35,6 +35,8 @@ extern "C" { #include <spa/utils/defs.h> #include <spa/utils/hook.h> +#include <pipewire/proxy.h> + #define PW_VERSION_CORE 3 struct pw_core { struct spa_interface iface; }; @@ -182,9 +184,11 @@ struct pw_core_events { #define PW_CORE_METHOD_PONG 3 #define PW_CORE_METHOD_ERROR 4 #define PW_CORE_METHOD_GET_REGISTRY 5 -#define PW_CORE_METHOD_CREATE_OBJECT 6 -#define PW_CORE_METHOD_DESTROY 7 -#define PW_CORE_METHOD_NUM 8 +#define PW_CORE_METHOD_LOAD_MODULE 6 +#define PW_CORE_METHOD_CREATE_OBJECT 7 +#define PW_CORE_METHOD_EXPORT_OBJECT 8 +#define PW_CORE_METHOD_DESTROY_OBJECT 9 +#define PW_CORE_METHOD_NUM 10 /** * \struct pw_core_methods @@ -257,6 +261,15 @@ struct pw_core_methods { size_t user_data_size); /** + * Load a module + */ + void * (*load_module) (void *object, + const char *name, + const char *args, + const struct spa_dict *props, + size_t user_data_size); + + /** * Create a new object on the PipeWire server from a factory. * * \param factory_name the factory name to use @@ -271,6 +284,16 @@ struct pw_core_methods { uint32_t version, const struct spa_dict *props, size_t user_data_size); + + /** + * Export a local interface + */ + void * (*export_object) (void *object, + uint32_t type, + const struct spa_dict *props, + const struct spa_interface *iface, + size_t user_data_size); + /** * Destroy an resource * @@ -278,7 +301,7 @@ struct pw_core_methods { * * \param obj the proxy to destroy */ - int (*destroy) (void *object, void *proxy); + int (*destroy_object) (void *object, void *proxy); }; #define pw_core_method(o,method,version,...) \ @@ -330,6 +353,20 @@ pw_core_get_registry(struct pw_core *core, uint32_t version, size_t user_data_si } static inline void * +pw_core_load_module(struct pw_core *core, + const char *name, + const char *args, + const struct spa_dict *props, + size_t user_data_size) +{ + void *res = NULL; + spa_interface_call_res(&core->iface, + struct pw_core_methods, res, + load_module, 0, name, args, + props, user_data_size); + return res; +} +static inline void * pw_core_create_object(struct pw_core *core, const char *factory_name, uint32_t type, @@ -345,7 +382,27 @@ pw_core_create_object(struct pw_core *core, return res; } -#define pw_core_destroy(c,...) pw_core_method(c,destroy,0,__VA_ARGS__) +static inline void * +pw_core_export_object(struct pw_core *core, + uint32_t type, + const struct spa_dict *props, + const struct spa_interface *iface, + size_t user_data_size) +{ + void *res = NULL; + spa_interface_call_res(&core->iface, + struct pw_core_methods, res, + export_object, 0, type, props, iface, user_data_size); + return res; +} + +#define pw_core_destroy_object(c,...) pw_core_method(c,destroy_object,0,__VA_ARGS__) + +static inline void * +pw_core_get_user_data(struct pw_core *core) +{ + return pw_proxy_get_user_data((struct pw_proxy*)core); +} /** \page page_registry Registry * diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c index d8abc627..69b98c9d 100644 --- a/src/pipewire/filter.c +++ b/src/pipewire/filter.c @@ -69,8 +69,7 @@ struct queue { }; struct data { - struct pw_impl_core *core; - struct pw_remote *remote; + struct pw_core *core; struct spa_hook filter_listener; }; @@ -88,9 +87,8 @@ struct port { enum spa_direction direction; uint32_t id; uint32_t flags; - struct pw_impl_port *port; - struct pw_properties *props; + struct pw_properties *properties; uint32_t change_mask_all; struct spa_port_info info; @@ -116,13 +114,14 @@ struct filter { const char *path; - struct pw_impl_core *core_impl; + struct pw_context *context; enum pw_filter_flags flags; struct spa_hook remote_listener; - struct pw_impl_node *node; + uint32_t change_mask_all; + struct spa_node_info info; struct spa_node impl_node; struct spa_hook_list hooks; @@ -341,7 +340,7 @@ static int impl_send_command(void *object, const struct spa_command *command) switch (SPA_NODE_COMMAND_ID(command)) { case SPA_NODE_COMMAND_Suspend: case SPA_NODE_COMMAND_Pause: - pw_loop_invoke(impl->core_impl->main_loop, + pw_loop_invoke(impl->context->main_loop, NULL, 0, NULL, 0, false, impl); if (filter->state == PW_FILTER_STATE_STREAMING) { pw_log_debug(NAME" %p: pause", filter); @@ -362,24 +361,24 @@ static int impl_send_command(void *object, const struct spa_command *command) return 0; } -static void emit_node_info(struct filter *d) +static void emit_node_info(struct filter *d, bool full) { - struct spa_node_info info; - - info = SPA_NODE_INFO_INIT(); - info.max_input_ports = MAX_PORTS; - info.max_output_ports = MAX_PORTS; - info.change_mask |= SPA_NODE_CHANGE_MASK_FLAGS; - info.flags = SPA_NODE_FLAG_RT; - spa_node_emit_info(&d->hooks, &info); + if (full) + d->info.change_mask = d->change_mask_all; + if (d->info.change_mask != 0) { + spa_node_emit_info(&d->hooks, &d->info); + d->info.change_mask = 0; + } } static void emit_port_info(struct filter *d, struct port *p, bool full) { if (full) p->info.change_mask = p->change_mask_all; - if (p->info.change_mask != 0) + if (p->info.change_mask != 0) { spa_node_emit_port_info(&d->hooks, p->direction, p->id, &p->info); + p->info.change_mask = 0; + } } static int impl_add_listener(void *object, @@ -393,7 +392,7 @@ static int impl_add_listener(void *object, spa_hook_list_isolate(&d->hooks, &save, listener, events, data); - emit_node_info(d); + emit_node_info(d, true); spa_list_for_each(p, &d->port_list, link) emit_port_info(d, p, true); @@ -532,8 +531,9 @@ static int port_set_param(struct filter *impl, struct port *port, idx = get_param_index(id); if (idx != -1) { - impl->params[idx].flags |= SPA_PARAM_INFO_READ; - impl->params[idx].flags ^= SPA_PARAM_INFO_SERIAL; + port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS; + port->params[idx].flags |= SPA_PARAM_INFO_READ; + port->params[idx].flags ^= SPA_PARAM_INFO_SERIAL; emit_port_info(impl, port, false); } return res; @@ -561,7 +561,7 @@ static int map_data(struct filter *impl, struct spa_data *data, int prot) void *ptr; struct pw_map_range range; - pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->core_impl->sc_pagesize); + pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize); ptr = mmap(NULL, range.size, prot, MAP_SHARED, data->fd, range.offset); if (ptr == MAP_FAILED) { @@ -579,7 +579,7 @@ static int unmap_data(struct filter *impl, struct spa_data *data) { struct pw_map_range range; - pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->core_impl->sc_pagesize); + pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize); if (munmap(SPA_MEMBER(data->data, -range.start, void), range.size) < 0) pw_log_warn(NAME" %p: failed to unmap: %m", impl); @@ -736,7 +736,7 @@ static void call_process(struct filter *impl) do_call_process(NULL, false, 1, NULL, 0, impl); } else { - pw_loop_invoke(impl->core_impl->main_loop, + pw_loop_invoke(impl->context->main_loop, do_call_process, 1, NULL, 0, false, impl); } } @@ -755,7 +755,7 @@ do_call_drained(struct spa_loop *loop, static void call_drained(struct filter *impl) { - pw_loop_invoke(impl->core_impl->main_loop, + pw_loop_invoke(impl->context->main_loop, do_call_drained, 1, NULL, 0, false, impl); } @@ -891,19 +891,8 @@ static int handle_connect(struct pw_filter *filter) pw_log_debug(NAME" %p: creating node", filter); props = pw_properties_copy(filter->properties); - impl->node = pw_impl_node_new(impl->core_impl, props, 0); - if (impl->node == NULL) { - res = -errno; - goto error_node; - } - - impl->node->port_user_data_size = sizeof(struct port); - - pw_impl_node_set_implementation(impl->node, &impl->impl_node); - - pw_log_debug(NAME" %p: export node %p", filter, impl->node); filter->proxy = pw_remote_export(filter->remote, - PW_TYPE_INTERFACE_Node, NULL, impl->node, 0); + SPA_TYPE_INTERFACE_Node, props, &impl->impl_node, 0); if (filter->proxy == NULL) { res = -errno; goto error_proxy; @@ -911,14 +900,8 @@ static int handle_connect(struct pw_filter *filter) pw_proxy_add_listener(filter->proxy, &filter->proxy_listener, &proxy_events, filter); - if (!SPA_FLAG_IS_SET(impl->flags, PW_FILTER_FLAG_INACTIVE)) - pw_impl_node_set_active(impl->node, true); - return 0; -error_node: - pw_log_error(NAME" %p: can't make node: %s", filter, spa_strerror(res)); - return res; error_proxy: pw_log_error(NAME" %p: can't make proxy: %s", filter, spa_strerror(res)); return res; @@ -957,11 +940,12 @@ static const struct pw_remote_events remote_events = { }; SPA_EXPORT -struct pw_filter * pw_filter_new(struct pw_remote *remote, const char *name, +struct pw_filter * pw_filter_new(struct pw_core *core, const char *name, struct pw_properties *props) { struct filter *impl; struct pw_filter *this; + struct pw_remote *remote = ((struct pw_proxy*)core)->remote; const char *str; int res; @@ -970,6 +954,7 @@ struct pw_filter * pw_filter_new(struct pw_remote *remote, const char *name, res = -errno; goto error_cleanup; } + impl->data.core = core; this = &impl->this; pw_log_debug(NAME" %p: new", impl); @@ -998,7 +983,17 @@ struct pw_filter * pw_filter_new(struct pw_remote *remote, const char *name, spa_hook_list_init(&impl->hooks); this->properties = props; + impl->info = SPA_NODE_INFO_INIT(); + impl->info.max_input_ports = MAX_PORTS; + impl->info.max_output_ports = MAX_PORTS; + impl->change_mask_all = SPA_NODE_CHANGE_MASK_FLAGS | + SPA_NODE_CHANGE_MASK_PROPS; + impl->info.change_mask = impl->change_mask_all; + impl->info.flags = SPA_NODE_FLAG_RT; + impl->info.props = &this->properties->dict; + this->remote = remote; + impl->context = remote->context; this->name = name ? strdup(name) : NULL; this->node_id = SPA_ID_INVALID; @@ -1010,8 +1005,6 @@ struct pw_filter * pw_filter_new(struct pw_remote *remote, const char *name, this->state = PW_FILTER_STATE_UNCONNECTED; - impl->core_impl = remote->core_impl; - pw_remote_add_listener(remote, &impl->remote_listener, &remote_events, this); spa_list_append(&remote->filter_list, &this->link); @@ -1037,14 +1030,12 @@ pw_filter_new_simple(struct pw_loop *loop, { struct pw_filter *filter; struct filter *impl; - struct pw_impl_core *core; - struct pw_remote *remote; + struct pw_core *core; int res; - core = pw_impl_core_new(loop, NULL, 0); - remote = pw_remote_new(core, NULL, 0); + core = pw_core_connect(loop, props, 0); - filter = pw_filter_new(remote, name, props); + filter = pw_filter_new(core, name, props); if (filter == NULL) { res = -errno; goto error_cleanup; @@ -1054,14 +1045,13 @@ pw_filter_new_simple(struct pw_loop *loop, impl->free_data = true; impl->data.core = core; - impl->data.remote = remote; pw_filter_add_listener(filter, &impl->data.filter_listener, events, data); return filter; error_cleanup: - pw_impl_core_destroy(core); + pw_proxy_destroy((struct pw_proxy*)core); errno = -res; return NULL; } @@ -1108,7 +1098,7 @@ void pw_filter_destroy(struct pw_filter *filter) free(filter->name); if (impl->free_data) - pw_impl_core_destroy(impl->data.core); + pw_proxy_destroy((struct pw_proxy*)impl->data.core); free(impl); } @@ -1131,9 +1121,10 @@ enum pw_filter_state pw_filter_get_state(struct pw_filter *filter, const char ** } SPA_EXPORT -struct pw_remote *pw_filter_get_remote(struct pw_filter *filter) +struct pw_core *pw_filter_get_core(struct pw_filter *filter) { - return filter->remote; + struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this); + return impl->data.core; } SPA_EXPORT @@ -1145,15 +1136,12 @@ const char *pw_filter_get_name(struct pw_filter *filter) SPA_EXPORT const struct pw_properties *pw_filter_get_properties(struct pw_filter *filter, void *port_data) { - struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this); struct port *port = SPA_CONTAINER_OF(port_data, struct port, user_data); if (port_data) { - if (port->port) - return pw_impl_port_get_properties(port->port); + return port->properties; } else { - if (impl->node) - return pw_impl_node_get_properties(impl->node); + return filter->properties; } return NULL; } @@ -1166,11 +1154,19 @@ int pw_filter_update_properties(struct pw_filter *filter, void *port_data, const int changed = 0; if (port_data) { - if (port->port) - changed = pw_impl_port_update_properties(port->port, dict); + changed = pw_properties_update(port->properties, dict); + port->info.props = &port->properties->dict; + if (changed) { + port->info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS; + emit_port_info(impl, port, false); + } } else { - if (impl->node) - changed = pw_impl_node_update_properties(impl->node, dict); + changed = pw_properties_update(filter->properties, dict); + impl->info.props = &filter->properties->dict; + if (changed) { + impl->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS; + emit_node_info(impl, false); + } } return changed; } @@ -1229,17 +1225,9 @@ int pw_filter_disconnect(struct pw_filter *filter) pw_log_debug(NAME" %p: disconnect", filter); impl->disconnecting = true; - if (impl->node) - pw_impl_node_set_active(impl->node, false); - if (filter->proxy) pw_proxy_destroy(filter->proxy); - if (impl->node) { - pw_impl_node_destroy(impl->node); - impl->node = NULL; - } - return 0; } @@ -1332,7 +1320,7 @@ void *pw_filter_add_port(struct pw_filter *filter, } p->alloc_buffers = SPA_FLAG_IS_SET(flags, PW_FILTER_PORT_FLAG_ALLOC_BUFFERS); - p->props = props; + p->properties = props; p->flags = flags; /* first configure default params */ @@ -1352,7 +1340,7 @@ void *pw_filter_add_port(struct pw_filter *filter, p->info.flags = 0; if (p->alloc_buffers) p->info.flags |= SPA_PORT_FLAG_CAN_ALLOC_BUFFERS; - p->info.props = &p->props->dict; + p->info.props = &p->properties->dict; p->change_mask_all |= SPA_PORT_CHANGE_MASK_PARAMS; p->params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ); p->params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, 0); @@ -1424,9 +1412,7 @@ SPA_EXPORT int pw_filter_set_active(struct pw_filter *filter, bool active) { struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this); - pw_log_debug(NAME" %p: active:%d", filter, active); - if (impl->node) - pw_impl_node_set_active(impl->node, active); + pw_log_debug(NAME" %p: active:%d", impl, active); return 0; } @@ -1462,7 +1448,7 @@ static inline int call_trigger(struct filter *impl) { int res = 0; if (SPA_FLAG_IS_SET(impl->flags, PW_FILTER_FLAG_DRIVER)) { - res = pw_loop_invoke(impl->core_impl->data_loop, + res = pw_loop_invoke(impl->context->data_loop, do_process, 1, NULL, 0, false, impl); } return res; @@ -1561,7 +1547,7 @@ SPA_EXPORT int pw_filter_flush(struct pw_filter *filter, bool drain) { struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this); - pw_loop_invoke(impl->core_impl->data_loop, + pw_loop_invoke(impl->context->data_loop, drain ? do_drain : do_flush, 1, NULL, 0, true, impl); return 0; } diff --git a/src/pipewire/filter.h b/src/pipewire/filter.h index 4db4f575..66b325c1 100644 --- a/src/pipewire/filter.h +++ b/src/pipewire/filter.h @@ -44,7 +44,10 @@ struct pw_filter; #include <spa/node/io.h> #include <spa/param/param.h> -#include <pipewire/remote.h> +#include <pipewire/core.h> +#include <pipewire/port.h> +#include <pipewire/stream.h> +#include <pipewire/loop.h> /** \enum pw_filter_state The state of a filter \memberof pw_filter */ enum pw_filter_state { @@ -124,7 +127,7 @@ enum pw_filter_port_flags { /** Create a new unconneced \ref pw_filter \memberof pw_filter * \return a newly allocated \ref pw_filter */ struct pw_filter * -pw_filter_new(struct pw_remote *remote, /**< a \ref pw_remote */ +pw_filter_new(struct pw_core *core, /**< a \ref pw_core */ const char *name, /**< a filter media name */ struct pw_properties *props /**< filter properties, ownership is taken */); @@ -147,7 +150,7 @@ enum pw_filter_state pw_filter_get_state(struct pw_filter *filter, const char ** const char *pw_stream_get_name(struct pw_stream *stream); -struct pw_remote *pw_filter_get_remote(struct pw_filter *filter); +struct pw_core *pw_filter_get_core(struct pw_filter *filter); /** Connect a filter for processing. \memberof pw_filter * \return 0 on success < 0 on error. diff --git a/src/pipewire/impl-client.h b/src/pipewire/impl-client.h index 8f49e443..6191f0c4 100644 --- a/src/pipewire/impl-client.h +++ b/src/pipewire/impl-client.h @@ -43,7 +43,6 @@ extern "C" { */ struct pw_impl_client; -#include <pipewire/core.h> #include <pipewire/client.h> #include <pipewire/global.h> #include <pipewire/properties.h> diff --git a/src/pipewire/impl-core.c b/src/pipewire/impl-core.c index 07bfef16..5a81a977 100644 --- a/src/pipewire/impl-core.c +++ b/src/pipewire/impl-core.c @@ -366,11 +366,11 @@ error_exit: return NULL; } -static int core_destroy(void *object, void *proxy) +static int core_destroy_object(void *object, void *obj) { struct pw_resource *resource = object; struct pw_impl_client *client = resource->client; - struct pw_resource *r = proxy; + struct pw_resource *r = obj; pw_log_debug(NAME" %p: destroy resource %p from client %p", resource->core, r, client); pw_resource_destroy(r); return 0; @@ -384,7 +384,7 @@ static const struct pw_core_methods core_methods = { .error = core_error, .get_registry = core_get_registry, .create_object = core_create_object, - .destroy = core_destroy, + .destroy_object = core_destroy_object, }; static void core_unbind_func(void *data) @@ -507,6 +507,13 @@ struct pw_impl_core *pw_impl_core_new(struct pw_loop *main_loop, if ((str = pw_properties_get(pr, "core.data-loop." PW_KEY_LIBRARY_NAME_SYSTEM))) pw_properties_set(pr, PW_KEY_LIBRARY_NAME_SYSTEM, str); + if ((name = pw_properties_get(properties, PW_KEY_CORE_NAME)) == NULL) { + pw_properties_setf(properties, + PW_KEY_CORE_NAME, "pipewire-%s-%d", + pw_get_user_name(), getpid()); + name = pw_properties_get(properties, PW_KEY_CORE_NAME); + } + this->data_loop_impl = pw_data_loop_new(pr); if (this->data_loop_impl == NULL) { res = -errno; @@ -550,10 +557,11 @@ struct pw_impl_core *pw_impl_core_new(struct pw_loop *main_loop, } this->n_support = n_support; + this->sc_pagesize = sysconf(_SC_PAGESIZE); + pw_array_init(&this->factory_lib, 32); pw_map_init(&this->globals, 128, 32); - spa_list_init(&this->protocol_list); spa_list_init(&this->remote_list); spa_list_init(&this->registry_resource_list); spa_list_init(&this->global_list); @@ -565,17 +573,9 @@ struct pw_impl_core *pw_impl_core_new(struct pw_loop *main_loop, spa_list_init(&this->link_list); spa_list_init(&this->control_list[0]); spa_list_init(&this->control_list[1]); - spa_list_init(&this->export_list); spa_list_init(&this->driver_list); spa_hook_list_init(&this->listener_list); - if ((name = pw_properties_get(properties, PW_KEY_CORE_NAME)) == NULL) { - pw_properties_setf(properties, - PW_KEY_CORE_NAME, "pipewire-%s-%d", - pw_get_user_name(), getpid()); - name = pw_properties_get(properties, PW_KEY_CORE_NAME); - } - if ((res = pw_data_loop_start(this->data_loop_impl)) < 0) goto error_free_loop; @@ -587,8 +587,6 @@ struct pw_impl_core *pw_impl_core_new(struct pw_loop *main_loop, this->info.cookie = random(); this->info.name = name; - this->sc_pagesize = sysconf(_SC_PAGESIZE); - this->global = pw_global_new(this, PW_TYPE_INTERFACE_Core, PW_VERSION_CORE, diff --git a/src/pipewire/impl-core.h b/src/pipewire/impl-core.h index c2cee3b2..8375e90c 100644 --- a/src/pipewire/impl-core.h +++ b/src/pipewire/impl-core.h @@ -43,6 +43,7 @@ extern "C" { struct pw_impl_core; #include <pipewire/impl-client.h> +#include <pipewire/core.h> #include <pipewire/global.h> #include <pipewire/loop.h> #include <pipewire/factory.h> diff --git a/src/pipewire/meson.build b/src/pipewire/meson.build index 88586d20..e51f1084 100644 --- a/src/pipewire/meson.build +++ b/src/pipewire/meson.build @@ -4,6 +4,7 @@ pipewire_headers = [ 'client.h', 'impl-client.h', 'impl-control.h', + 'context.h', 'core.h', 'impl-core.h', 'data-loop.h', @@ -42,6 +43,8 @@ pipewire_headers = [ pipewire_sources = [ 'buffers.c', + 'core.c', + 'context.c', 'impl-client.c', 'impl-control.c', 'impl-core.c', diff --git a/src/pipewire/pipewire.c b/src/pipewire/pipewire.c index 93745d20..54819473 100644 --- a/src/pipewire/pipewire.c +++ b/src/pipewire/pipewire.c @@ -504,7 +504,7 @@ const char *pw_get_client_name(void) * \memberof pw_pipewire */ SPA_EXPORT -void pw_fill_remote_properties(struct pw_impl_core *core, struct pw_properties *properties) +void pw_fill_remote_properties(struct pw_context *context, struct pw_properties *properties) { const char *val; @@ -534,10 +534,10 @@ void pw_fill_remote_properties(struct pw_impl_core *core, struct pw_properties * pw_properties_set(properties, PW_KEY_WINDOW_X11_DISPLAY, getenv("DISPLAY")); } - pw_properties_set(properties, PW_KEY_CORE_VERSION, core->info.version); - pw_properties_set(properties, PW_KEY_CORE_NAME, core->info.name); + pw_properties_set(properties, PW_KEY_CORE_VERSION, context->info.version); + pw_properties_set(properties, PW_KEY_CORE_NAME, context->info.name); - if ((val = pw_properties_get(core->properties, PW_KEY_CORE_DAEMON))) + if ((val = pw_properties_get(context->properties, PW_KEY_CORE_DAEMON))) pw_properties_set(properties, PW_KEY_CORE_DAEMON, val); } @@ -549,7 +549,7 @@ void pw_fill_remote_properties(struct pw_impl_core *core, struct pw_properties * * \memberof pw_pipewire */ SPA_EXPORT -void pw_fill_stream_properties(struct pw_impl_core *core, struct pw_properties *properties) +void pw_fill_stream_properties(struct pw_context *context, struct pw_properties *properties) { } diff --git a/src/pipewire/pipewire.h b/src/pipewire/pipewire.h index 1445322d..61f722e4 100644 --- a/src/pipewire/pipewire.h +++ b/src/pipewire/pipewire.h @@ -31,6 +31,8 @@ extern "C" { #include <spa/support/plugin.h> +#include <pipewire/context.h> +#include <pipewire/proxy.h> #include <pipewire/device.h> #include <pipewire/keys.h> #include <pipewire/link.h> @@ -42,7 +44,7 @@ extern "C" { #include <pipewire/node.h> #include <pipewire/port.h> #include <pipewire/properties.h> -#include <pipewire/proxy.h> +#include <pipewire/protocol.h> #include <pipewire/remote.h> #include <pipewire/resource.h> #include <pipewire/stream.h> @@ -50,6 +52,7 @@ extern "C" { #include <pipewire/type.h> #include <pipewire/utils.h> #include <pipewire/version.h> +#include <pipewire/api.h> /** \mainpage * @@ -125,10 +128,10 @@ const char * pw_get_client_name(void); void -pw_fill_remote_properties(struct pw_impl_core *core, struct pw_properties *properties); +pw_fill_remote_properties(struct pw_context *context, struct pw_properties *properties); void -pw_fill_stream_properties(struct pw_impl_core *core, struct pw_properties *properties); +pw_fill_stream_properties(struct pw_context *context, struct pw_properties *properties); enum pw_direction pw_direction_reverse(enum pw_direction direction); diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 085954d2..2e4de574 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -64,11 +64,36 @@ struct ucred { #define MAX_PARAMS 32 +struct pw_context { + struct pw_properties *properties; /**< properties of the core */ + struct pw_core_info info; /**< info about the core */ + + struct pw_remote *remote; + struct pw_impl_core *core_impl; + + struct pw_loop *main_loop; /**< main loop for control */ + struct pw_loop *data_loop; /**< data loop for data passing */ + struct pw_data_loop *data_loop_impl; + struct spa_system *data_system; /**< data system for data passing */ + + struct spa_support support[16]; /**< support for spa plugins */ + uint32_t n_support; /**< number of support items */ + struct pw_array factory_lib; /**< mapping of factory_name regexp to library */ + + struct spa_list protocol_list; /**< list of protocols */ + struct spa_list export_list; /**< list of export types */ + + long sc_pagesize; + + void *user_data; +}; + #define pw_protocol_emit_destroy(p) spa_hook_list_call(&p->listener_list, struct pw_protocol_events, destroy, 0) struct pw_protocol { struct spa_list link; /**< link in core protocol_list */ - struct pw_impl_core *core; /**< core for this protocol */ + + struct pw_context *context; /**< context for this protocol */ char *name; /**< type name of the protocol */ @@ -223,7 +248,6 @@ struct pw_impl_core { struct pw_map globals; /**< map of globals */ - struct spa_list protocol_list; /**< list of protocols */ struct spa_list remote_list; /**< list of remote connections */ struct spa_list registry_resource_list; /**< list of registry resources */ struct spa_list module_list; /**< list of modules */ @@ -234,11 +258,12 @@ struct pw_impl_core { struct spa_list factory_list; /**< list of factories */ struct spa_list link_list; /**< list of links */ struct spa_list control_list[2]; /**< list of controls, indexed by direction */ - struct spa_list export_list; /**< list of export types */ struct spa_list driver_list; /**< list of driver nodes */ struct spa_hook_list listener_list; + struct pw_context *context; + struct pw_loop *main_loop; /**< main loop for control */ struct pw_loop *data_loop; /**< data loop for data passing */ struct pw_data_loop *data_loop_impl; @@ -248,10 +273,10 @@ struct pw_impl_core { uint32_t n_support; /**< number of support items */ struct pw_array factory_lib; /**< mapping of factory_name regexp to library */ - struct pw_impl_client *current_client; /**< client currently executing code in mainloop */ - long sc_pagesize; + struct pw_impl_client *current_client; /**< client currently executing code in mainloop */ + void *user_data; /**< extra user data */ }; @@ -738,7 +763,6 @@ struct pw_proxy { #define pw_remote_emit_state_changed(r,o,s,e) pw_remote_emit(r, state_changed, 0, o, s, e) struct pw_remote { - struct pw_impl_core *core_impl; /**< core */ struct spa_list link; /**< link in core remote_list */ struct pw_properties *properties; /**< extra properties */ @@ -760,6 +784,8 @@ struct pw_remote { struct spa_hook_list listener_list; + struct pw_context *context; + void *user_data; /**< extra user data */ }; @@ -900,7 +926,7 @@ pw_impl_core_find_port(struct pw_impl_core *core, struct spa_pod **format_filters, char **error); -const struct pw_export_type *pw_impl_core_find_export_type(struct pw_impl_core *core, uint32_t type); +const struct pw_export_type *pw_context_find_export_type(struct pw_context *context, uint32_t type); int pw_proxy_install_marshal(struct pw_proxy *proxy, bool implementor); int pw_resource_install_marshal(struct pw_resource *resource, bool implementor); diff --git a/src/pipewire/protocol.c b/src/pipewire/protocol.c index b89bafae..b6afbfe4 100644 --- a/src/pipewire/protocol.c +++ b/src/pipewire/protocol.c @@ -44,7 +44,7 @@ struct marshal { /** \endcond */ SPA_EXPORT -struct pw_protocol *pw_protocol_new(struct pw_impl_core *core, +struct pw_protocol *pw_protocol_new(struct pw_context *context, const char *name, size_t user_data_size) { @@ -54,7 +54,7 @@ struct pw_protocol *pw_protocol_new(struct pw_impl_core *core, if (protocol == NULL) return NULL; - protocol->core = core; + protocol->context = context; protocol->name = strdup(name); spa_list_init(&protocol->marshal_list); @@ -65,7 +65,7 @@ struct pw_protocol *pw_protocol_new(struct pw_impl_core *core, if (user_data_size > 0) protocol->user_data = SPA_MEMBER(protocol, sizeof(struct impl), void); - spa_list_append(&core->protocol_list, &protocol->link); + spa_list_append(&context->protocol_list, &protocol->link); pw_log_debug(NAME" %p: Created protocol %s", protocol, name); @@ -169,11 +169,11 @@ pw_protocol_get_marshal(struct pw_protocol *protocol, uint32_t type, uint32_t ve } SPA_EXPORT -struct pw_protocol *pw_impl_core_find_protocol(struct pw_impl_core *core, const char *name) +struct pw_protocol *pw_context_find_protocol(struct pw_context *context, const char *name) { struct pw_protocol *protocol; - spa_list_for_each(protocol, &core->protocol_list, link) { + spa_list_for_each(protocol, &context->protocol_list, link) { if (strcmp(protocol->name, name) == 0) return protocol; } diff --git a/src/pipewire/protocol.h b/src/pipewire/protocol.h index 9d7c03b5..8367595e 100644 --- a/src/pipewire/protocol.h +++ b/src/pipewire/protocol.h @@ -33,7 +33,7 @@ extern "C" { struct pw_protocol; -#include <pipewire/impl-core.h> +#include <pipewire/context.h> #include <pipewire/proxy.h> #include <pipewire/properties.h> #include <pipewire/utils.h> @@ -45,9 +45,8 @@ struct pw_protocol_client { struct spa_list link; /**< link in protocol client_list */ struct pw_protocol *protocol; /**< the owner protocol */ - struct pw_remote *remote; /**< the associated remote */ - int (*connect) (struct pw_protocol_client *client, + const struct spa_dict *props, void (*done_callback) (void *data, int result), void *data); int (*connect_fd) (struct pw_protocol_client *client, int fd, bool close); @@ -56,7 +55,7 @@ struct pw_protocol_client { void (*destroy) (struct pw_protocol_client *client); }; -#define pw_protocol_client_connect(c,cb,d) ((c)->connect(c,cb,d)) +#define pw_protocol_client_connect(c,p,cb,d) ((c)->connect(c,p,cb,d)) #define pw_protocol_client_connect_fd(c,fd,cl) ((c)->connect_fd(c,fd,cl)) #define pw_protocol_client_steal_fd(c) ((c)->steal_fd(c)) #define pw_protocol_client_disconnect(c) ((c)->disconnect(c)) @@ -108,7 +107,7 @@ struct pw_protocol_events { #define pw_protocol_add_server(p,...) (pw_protocol_get_implementation(p)->add_server(p,__VA_ARGS__)) #define pw_protocol_ext(p,type,method,...) (((type*)pw_protocol_get_extension(p))->method( __VA_ARGS__)) -struct pw_protocol *pw_protocol_new(struct pw_impl_core *core, const char *name, size_t user_data_size); +struct pw_protocol *pw_protocol_new(struct pw_context *context, const char *name, size_t user_data_size); void pw_protocol_destroy(struct pw_protocol *protocol); @@ -136,7 +135,7 @@ int pw_protocol_add_marshal(struct pw_protocol *protocol, const struct pw_protocol_marshal * pw_protocol_get_marshal(struct pw_protocol *protocol, uint32_t type, uint32_t version, uint32_t flags); -struct pw_protocol * pw_impl_core_find_protocol(struct pw_impl_core *core, const char *name); +struct pw_protocol * pw_context_find_protocol(struct pw_context *context, const char *name); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/pipewire/proxy.c b/src/pipewire/proxy.c index 54c7b342..4d2b0937 100644 --- a/src/pipewire/proxy.c +++ b/src/pipewire/proxy.c @@ -28,6 +28,7 @@ #include <pipewire/remote.h> #include <pipewire/private.h> #include <pipewire/type.h> +#include <pipewire/protocol.h> #include <spa/debug/types.h> @@ -191,7 +192,7 @@ void pw_proxy_destroy(struct pw_proxy *proxy) * from the proxy objects and schedule a destroy. */ if (remote->core) { proxy->zombie = true; - pw_core_destroy(remote->core, proxy); + pw_core_destroy_object(remote->core, proxy); } else { proxy->removed = true; } diff --git a/src/pipewire/proxy.h b/src/pipewire/proxy.h index 6abea884..d820e54e 100644 --- a/src/pipewire/proxy.h +++ b/src/pipewire/proxy.h @@ -101,7 +101,7 @@ extern "C" { */ struct pw_proxy; -#include <pipewire/protocol.h> +//#include <pipewire/protocol.h> /** Proxy events, use \ref pw_proxy_add_listener */ struct pw_proxy_events { diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index b351cfd0..ae3e5bd6 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -33,6 +33,7 @@ #include <spa/debug/types.h> #include "pipewire/impl.h" +#include "pipewire/protocol.h" #include "pipewire/private.h" #include "extensions/protocol-native.h" @@ -45,6 +46,7 @@ struct remote { struct pw_remote this; struct spa_hook core_proxy_listener; struct spa_hook core_listener; + size_t user_data_size; }; /** \endcond */ @@ -190,7 +192,7 @@ static const struct pw_core_events core_events = { }; SPA_EXPORT -struct pw_remote *pw_remote_new(struct pw_impl_core *core, +struct pw_remote *pw_remote_new(struct pw_context *context, struct pw_properties *properties, size_t user_data_size) { @@ -206,11 +208,13 @@ struct pw_remote *pw_remote_new(struct pw_impl_core *core, res = -errno; goto exit_cleanup; } + impl->user_data_size = user_data_size; this = &impl->this; pw_log_debug(NAME" %p: new", impl); - this->core_impl = core; + this->context = context; + context->remote = this; if (user_data_size > 0) this->user_data = SPA_MEMBER(impl, sizeof(struct remote), void); @@ -220,7 +224,7 @@ struct pw_remote *pw_remote_new(struct pw_impl_core *core, if (properties == NULL) goto error_properties; - pw_fill_remote_properties(core, properties); + pw_fill_remote_properties(context, properties); this->properties = properties; this->state = PW_REMOTE_STATE_UNCONNECTED; @@ -233,12 +237,11 @@ struct pw_remote *pw_remote_new(struct pw_impl_core *core, spa_hook_list_init(&this->listener_list); if ((protocol_name = pw_properties_get(properties, PW_KEY_PROTOCOL)) == NULL) { - if ((protocol_name = pw_properties_get(core->properties, PW_KEY_PROTOCOL)) == NULL) { + if ((protocol_name = pw_properties_get(context->properties, PW_KEY_PROTOCOL)) == NULL) { protocol_name = PW_TYPE_INFO_PROTOCOL_Native; - if ((protocol = pw_impl_core_find_protocol(core, protocol_name)) == NULL) { - if (pw_impl_module_load(core, "libpipewire-module-protocol-native", - NULL, NULL) == NULL) { - res = -errno; + if ((protocol = pw_context_find_protocol(context, protocol_name)) == NULL) { + if ((res = pw_context_load_module(context, "libpipewire-module-protocol-native", + NULL, NULL)) < 0) { goto error_protocol; } } @@ -246,7 +249,7 @@ struct pw_remote *pw_remote_new(struct pw_impl_core *core, } if (protocol == NULL) - protocol = pw_impl_core_find_protocol(core, protocol_name); + protocol = pw_context_find_protocol(context, protocol_name); if (protocol == NULL) { res = -ENOTSUP; goto error_protocol; @@ -259,13 +262,11 @@ struct pw_remote *pw_remote_new(struct pw_impl_core *core, if (this->conn == NULL) goto error_connection; - pw_impl_module_load(core, "libpipewire-module-rtkit", NULL, NULL); - pw_impl_module_load(core, "libpipewire-module-client-node", NULL, NULL); - pw_impl_module_load(core, "libpipewire-module-adapter", NULL, NULL); - pw_impl_module_load(core, "libpipewire-module-metadata", NULL, NULL); - pw_impl_module_load(core, "libpipewire-module-session-manager", NULL, NULL); - - spa_list_append(&core->remote_list, &this->link); + pw_context_load_module(context, "libpipewire-module-rtkit", NULL, NULL); + pw_context_load_module(context, "libpipewire-module-client-node", NULL, NULL); + pw_context_load_module(context, "libpipewire-module-adapter", NULL, NULL); + pw_context_load_module(context, "libpipewire-module-metadata", NULL, NULL); + pw_context_load_module(context, "libpipewire-module-session-manager", NULL, NULL); return this; @@ -321,9 +322,9 @@ void pw_remote_destroy(struct pw_remote *remote) } SPA_EXPORT -struct pw_impl_core *pw_remote_get_core_impl(struct pw_remote *remote) +struct pw_context *pw_remote_get_context(struct pw_remote *remote) { - return remote->core_impl; + return remote->context; } SPA_EXPORT @@ -393,10 +394,8 @@ static const struct pw_proxy_events core_proxy_events = { }; static int -do_connect(struct spa_loop *loop, - bool async, uint32_t seq, const void *data, size_t size, void *user_data) +init_connect(struct pw_remote *remote) { - struct pw_remote *remote = user_data; struct remote *impl = SPA_CONTAINER_OF(remote, struct remote, this); struct pw_proxy dummy, *core; int res; @@ -404,10 +403,10 @@ do_connect(struct spa_loop *loop, spa_zero(dummy); dummy.remote = remote; - core = pw_proxy_new(&dummy, PW_TYPE_INTERFACE_Core, PW_VERSION_CORE, 0); + core = pw_proxy_new(&dummy, PW_TYPE_INTERFACE_Core, PW_VERSION_CORE, impl->user_data_size); if (core == NULL) { res = -errno; - goto error_disconnect; + goto error; } remote->core = (struct pw_core*)core; @@ -424,19 +423,27 @@ do_connect(struct spa_loop *loop, pw_core_hello(remote->core, PW_VERSION_CORE); pw_client_update_properties(remote->client, &remote->properties->dict); - pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTED, NULL); return 0; error_clean_core: ((struct pw_proxy*)remote->core)->removed = true; pw_proxy_destroy((struct pw_proxy*)remote->core); -error_disconnect: - pw_protocol_client_disconnect(remote->conn); +error: pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR, "can't connect: %s", spa_strerror(res)); return res; } +static int +do_connect(struct spa_loop *loop, + bool async, uint32_t seq, const void *data, size_t size, void *user_data) +{ + struct pw_remote *remote = user_data; + + pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTED, NULL); + return 0; +} + SPA_EXPORT struct pw_core * pw_remote_get_core(struct pw_remote *remote) { @@ -463,7 +470,7 @@ static void done_connect(void *data, int result) spa_strerror(result)); return; } - pw_loop_invoke(remote->core_impl->main_loop, + pw_loop_invoke(remote->context->main_loop, do_connect, 0, NULL, 0, false, remote); } @@ -474,7 +481,11 @@ int pw_remote_connect(struct pw_remote *remote) pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTING, NULL); - if ((res = pw_protocol_client_connect(remote->conn, done_connect, remote)) < 0) { + init_connect(remote); + + if ((res = pw_protocol_client_connect(remote->conn, + &remote->properties->dict, + done_connect, remote)) < 0) { pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR, "connect failed %s", spa_strerror(res)); return res; @@ -489,12 +500,14 @@ int pw_remote_connect_fd(struct pw_remote *remote, int fd) pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTING, NULL); + init_connect(remote); + if ((res = pw_protocol_client_connect_fd(remote->conn, fd, true)) < 0) { pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR, "connect_fd failed %s", spa_strerror(res)); return res; } - pw_loop_invoke(remote->core_impl->main_loop, + pw_loop_invoke(remote->context->main_loop, do_connect, 0, NULL, 0, false, remote); return remote->state == PW_REMOTE_STATE_ERROR ? -EIO : 0; @@ -556,7 +569,7 @@ struct pw_proxy *pw_remote_export(struct pw_remote *remote, goto error_core; } - t = pw_impl_core_find_export_type(remote->core_impl, type); + t = pw_context_find_export_type(remote->context, type); if (t == NULL) { res = -EPROTO; goto error_export_type; @@ -587,18 +600,18 @@ exit: } SPA_EXPORT -int pw_impl_core_register_export_type(struct pw_impl_core *core, struct pw_export_type *type) +int pw_context_register_export_type(struct pw_context *context, struct pw_export_type *type) { - pw_log_debug("core %p: Add export type %d/%s to core", core, type->type, + pw_log_debug("context %p: Add export type %d/%s to context", context, type->type, spa_debug_type_find_name(pw_type_info(), type->type)); - spa_list_append(&core->export_list, &type->link); + spa_list_append(&context->export_list, &type->link); return 0; } -const struct pw_export_type *pw_impl_core_find_export_type(struct pw_impl_core *core, uint32_t type) +const struct pw_export_type *pw_context_find_export_type(struct pw_context *context, uint32_t type) { const struct pw_export_type *t; - spa_list_for_each(t, &core->export_list, link) { + spa_list_for_each(t, &context->export_list, link) { if (t->type == type) return t; } diff --git a/src/pipewire/remote.h b/src/pipewire/remote.h index 6a59ec70..4f499c2b 100644 --- a/src/pipewire/remote.h +++ b/src/pipewire/remote.h @@ -111,9 +111,8 @@ extern "C" { */ struct pw_remote; -#include <pipewire/impl-core.h> +#include <pipewire/context.h> #include <pipewire/properties.h> -#include <pipewire/node.h> #include <pipewire/proxy.h> /** \enum pw_remote_state The state of a \ref pw_remote \memberof pw_remote */ @@ -142,16 +141,16 @@ struct pw_remote_events { /** Create a new unconnected remote \memberof pw_remote * \return a new unconnected remote */ struct pw_remote * -pw_remote_new(struct pw_impl_core *core, /**< a \ref pw_impl_core */ - struct pw_properties *properties, /**< optional properties, ownership of +pw_remote_new(struct pw_context *context, /**< a \ref pw_context */ + struct pw_properties *properties, /**< optional properties, ownership of * the properties is taken.*/ size_t user_data_size /**< extra user data size */); /** Destroy a remote \memberof pw_remote */ void pw_remote_destroy(struct pw_remote *remote); -/** Get the core used to construct this remote */ -struct pw_impl_core *pw_remote_get_core_impl(struct pw_remote *remote); +/** Get the loop used to construct this remote */ +struct pw_context *pw_remote_get_context(struct pw_remote *remote); /** Get the remote properties */ const struct pw_properties *pw_remote_get_properties(struct pw_remote *remote); @@ -214,7 +213,7 @@ struct pw_export_type { /** register a type that can be exported on a remote. This is usually used by * extension modules */ -int pw_impl_core_register_export_type(struct pw_impl_core *core, struct pw_export_type *type); +int pw_context_register_export_type(struct pw_context *context, struct pw_export_type *type); #ifdef __cplusplus } diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 47bde96a..d05a100d 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -66,8 +66,7 @@ struct queue { }; struct data { - struct pw_impl_core *core; - struct pw_remote *remote; + struct pw_core *core; struct spa_hook stream_listener; }; @@ -94,6 +93,8 @@ struct stream { struct pw_impl_core *core_impl; + struct pw_context *context; + enum spa_direction direction; enum pw_stream_flags flags; @@ -307,7 +308,7 @@ static void call_process(struct stream *impl) do_call_process(NULL, false, 1, NULL, 0, impl); } else { - pw_loop_invoke(impl->core_impl->main_loop, + pw_loop_invoke(impl->context->main_loop, do_call_process, 1, NULL, 0, false, impl); } } @@ -326,7 +327,7 @@ do_call_drained(struct spa_loop *loop, static void call_drained(struct stream *impl) { - pw_loop_invoke(impl->core_impl->main_loop, + pw_loop_invoke(impl->context->main_loop, do_call_drained, 1, NULL, 0, false, impl); } @@ -357,7 +358,7 @@ static int impl_send_command(void *object, const struct spa_command *command) switch (SPA_NODE_COMMAND_ID(command)) { case SPA_NODE_COMMAND_Suspend: case SPA_NODE_COMMAND_Pause: - pw_loop_invoke(impl->core_impl->main_loop, + pw_loop_invoke(impl->context->main_loop, NULL, 0, NULL, 0, false, impl); if (stream->state == PW_STREAM_STATE_STREAMING) { @@ -552,7 +553,7 @@ static int map_data(struct stream *impl, struct spa_data *data, int prot) void *ptr; struct pw_map_range range; - pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->core_impl->sc_pagesize); + pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize); ptr = mmap(NULL, range.size, prot, MAP_SHARED, data->fd, range.offset); if (ptr == MAP_FAILED) { @@ -570,7 +571,7 @@ static int unmap_data(struct stream *impl, struct spa_data *data) { struct pw_map_range range; - pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->core_impl->sc_pagesize); + pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize); if (munmap(SPA_MEMBER(data->data, -range.start, void), range.size) < 0) pw_log_warn(NAME" %p: failed to unmap: %m", impl); @@ -775,10 +776,12 @@ again: } } - if (!impl->draining && !SPA_FLAG_IS_SET(impl->flags, PW_STREAM_FLAG_DRIVER)) { + if (!impl->draining && + !SPA_FLAG_IS_SET(impl->flags, PW_STREAM_FLAG_DRIVER) && + io->status == SPA_STATUS_NEED_DATA && + spa_ringbuffer_get_read_index(&impl->queued.ring, &index) < MIN_QUEUED) { call_process(impl); - if (spa_ringbuffer_get_read_index(&impl->queued.ring, &index) >= MIN_QUEUED && - io->status == SPA_STATUS_NEED_DATA) + if (spa_ringbuffer_get_read_index(&impl->queued.ring, &index) >= MIN_QUEUED) goto again; } exit: @@ -1059,7 +1062,6 @@ static int handle_connect(struct pw_stream *stream) pw_proxy_add_listener(stream->proxy, &stream->proxy_listener, &proxy_events, stream); - pw_impl_node_add_listener(impl->node, &stream->node_listener, &node_events, stream); return 0; @@ -1104,11 +1106,12 @@ static const struct pw_remote_events remote_events = { }; SPA_EXPORT -struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name, +struct pw_stream * pw_stream_new(struct pw_core *core, const char *name, struct pw_properties *props) { struct stream *impl; struct pw_stream *this; + struct pw_remote *remote = ((struct pw_proxy*)core)->remote; const char *str; int res; @@ -1117,6 +1120,7 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name, res = -errno; goto error_cleanup; } + impl->data.core = core; this = &impl->this; pw_log_debug(NAME" %p: new \"%s\"", impl, name); @@ -1145,7 +1149,6 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name, spa_hook_list_init(&impl->hooks); this->properties = props; - this->remote = remote; this->name = name ? strdup(name) : NULL; this->node_id = SPA_ID_INVALID; @@ -1158,7 +1161,8 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name, this->state = PW_STREAM_STATE_UNCONNECTED; - impl->core_impl = remote->core_impl; + this->remote = remote; + impl->context = remote->context; pw_remote_add_listener(remote, &impl->remote_listener, &remote_events, this); @@ -1185,14 +1189,12 @@ pw_stream_new_simple(struct pw_loop *loop, { struct pw_stream *stream; struct stream *impl; - struct pw_impl_core *core; - struct pw_remote *remote; + struct pw_core *core; int res; - core = pw_impl_core_new(loop, NULL, 0); - remote = pw_remote_new(core, NULL, 0); + core = pw_core_connect(loop, props, 0); - stream = pw_stream_new(remote, name, props); + stream = pw_stream_new(core, name, props); if (stream == NULL) { res = -errno; goto error_cleanup; @@ -1202,14 +1204,13 @@ pw_stream_new_simple(struct pw_loop *loop, impl->free_data = true; impl->data.core = core; - impl->data.remote = remote; pw_stream_add_listener(stream, &impl->data.stream_listener, events, data); return stream; error_cleanup: - pw_impl_core_destroy(core); + pw_proxy_destroy((struct pw_proxy*)core); errno = -res; return NULL; } @@ -1262,7 +1263,7 @@ void pw_stream_destroy(struct pw_stream *stream) } if (impl->free_data) - pw_impl_core_destroy(impl->data.core); + pw_proxy_destroy((struct pw_proxy*)impl->data.core); free(impl); } @@ -1314,9 +1315,10 @@ int pw_stream_update_properties(struct pw_stream *stream, const struct spa_dict } SPA_EXPORT -struct pw_remote *pw_stream_get_remote(struct pw_stream *stream) +struct pw_core *pw_stream_get_core(struct pw_stream *stream) { - return stream->remote; + struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); + return impl->data.core; } static void add_params(struct stream *impl) @@ -1628,7 +1630,7 @@ static inline int call_trigger(struct stream *impl) { int res = 0; if (SPA_FLAG_IS_SET(impl->flags, PW_STREAM_FLAG_DRIVER)) { - res = pw_loop_invoke(impl->core_impl->data_loop, + res = pw_loop_invoke(impl->context->data_loop, do_process, 1, NULL, 0, false, impl); } return res; @@ -1700,7 +1702,7 @@ SPA_EXPORT int pw_stream_flush(struct pw_stream *stream, bool drain) { struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); - pw_loop_invoke(impl->core_impl->data_loop, + pw_loop_invoke(impl->context->data_loop, drain ? do_drain : do_flush, 1, NULL, 0, true, impl); return 0; } diff --git a/src/pipewire/stream.h b/src/pipewire/stream.h index aadde0aa..9d7d145e 100644 --- a/src/pipewire/stream.h +++ b/src/pipewire/stream.h @@ -152,8 +152,10 @@ struct pw_stream; #include <spa/buffer/buffer.h> #include <spa/param/param.h> -#include <pipewire/remote.h> +#include <pipewire/core.h> #include <pipewire/port.h> +#include <pipewire/properties.h> +#include <pipewire/loop.h> /** \enum pw_stream_state The state of a stream \memberof pw_stream */ enum pw_stream_state { @@ -248,7 +250,7 @@ enum pw_stream_flags { /** Create a new unconneced \ref pw_stream \memberof pw_stream * \return a newly allocated \ref pw_stream */ struct pw_stream * -pw_stream_new(struct pw_remote *remote, /**< a \ref pw_remote */ +pw_stream_new(struct pw_core *core, /**< a \ref pw_core */ const char *name, /**< a stream media name */ struct pw_properties *props /**< stream properties, ownership is taken */); @@ -271,7 +273,7 @@ enum pw_stream_state pw_stream_get_state(struct pw_stream *stream, const char ** const char *pw_stream_get_name(struct pw_stream *stream); -struct pw_remote *pw_stream_get_remote(struct pw_stream *stream); +struct pw_core *pw_stream_get_core(struct pw_stream *stream); const struct pw_properties *pw_stream_get_properties(struct pw_stream *stream); diff --git a/src/tests/test-interfaces.c b/src/tests/test-interfaces.c index 1a841fa9..4b8d979d 100644 --- a/src/tests/test-interfaces.c +++ b/src/tests/test-interfaces.c @@ -46,13 +46,23 @@ static void test_core_abi(void) int (*error) (void *object, uint32_t id, int seq, int res, const char *error); struct pw_registry * (*get_registry) (void *object, uint32_t version, size_t user_data_size); + void * (*load_module) (void *object, + const char *name, + const char *args, + const struct spa_dict *props, + size_t user_data_size); void * (*create_object) (void *object, const char *factory_name, uint32_t type, uint32_t version, const struct spa_dict *props, size_t user_data_size); - int (*destroy) (void *object, void *proxy); + void * (*export_object) (void *object, + uint32_t type, + const struct spa_dict *props, + const struct spa_interface *iface, + size_t user_data_size); + int (*destroy_object) (void *object, void *proxy); } methods = { PW_VERSION_CORE_METHODS, }; struct { uint32_t version; @@ -73,8 +83,10 @@ static void test_core_abi(void) TEST_FUNC(m, methods, pong); TEST_FUNC(m, methods, error); TEST_FUNC(m, methods, get_registry); + TEST_FUNC(m, methods, load_module); TEST_FUNC(m, methods, create_object); - TEST_FUNC(m, methods, destroy); + TEST_FUNC(m, methods, export_object); + TEST_FUNC(m, methods, destroy_object); spa_assert(PW_VERSION_CORE_METHODS == 0); spa_assert(sizeof(m) == sizeof(methods)); diff --git a/src/tests/test-remote.c b/src/tests/test-remote.c index 549cdad1..d0d14569 100644 --- a/src/tests/test-remote.c +++ b/src/tests/test-remote.c @@ -84,21 +84,21 @@ static void remote_destroy_count(void *data) static void test_create(void) { struct pw_main_loop *loop; - struct pw_impl_core *core; + struct pw_context *context; struct pw_remote *remote; struct pw_remote_events remote_events = remote_events_error; struct spa_hook listener = { 0, }; const char *error = NULL; loop = pw_main_loop_new(NULL); - core = pw_impl_core_new(pw_main_loop_get_loop(loop), NULL, 12); + context = pw_context_new(pw_main_loop_get_loop(loop), NULL, 12); - remote = pw_remote_new(core, NULL, 12); + remote = pw_remote_new(context, NULL, 12); spa_assert(remote != NULL); pw_remote_add_listener(remote, &listener, &remote_events, remote); /* check core */ - spa_assert(pw_remote_get_core_impl(remote) == core); + spa_assert(pw_remote_get_context(remote) == context); /* check user data */ spa_assert(pw_remote_get_user_data(remote) != NULL); /* check state */ @@ -118,14 +118,13 @@ static void test_create(void) pw_remote_destroy(remote); spa_assert(destroy_count == 1); - pw_impl_core_destroy(core); pw_main_loop_destroy(loop); } static void test_properties(void) { struct pw_main_loop *loop; - struct pw_impl_core *core; + struct pw_context *context; const struct pw_properties *props; struct pw_remote *remote; struct pw_remote_events remote_events = remote_events_error; @@ -133,8 +132,9 @@ static void test_properties(void) struct spa_dict_item items[3]; loop = pw_main_loop_new(NULL); - core = pw_impl_core_new(pw_main_loop_get_loop(loop), NULL, 0); - remote = pw_remote_new(core, + context = pw_context_new(pw_main_loop_get_loop(loop), NULL, 12); + + remote = pw_remote_new(context, pw_properties_new("foo", "bar", "biz", "fuzz", NULL), @@ -168,7 +168,6 @@ static void test_properties(void) /* check destroy */ destroy_count = 0; remote_events.destroy = remote_destroy_count; - pw_impl_core_destroy(core); spa_assert(destroy_count == 1); pw_main_loop_destroy(loop); diff --git a/src/tests/test-stream.c b/src/tests/test-stream.c index f07e166c..01aba8cf 100644 --- a/src/tests/test-stream.c +++ b/src/tests/test-stream.c @@ -133,8 +133,7 @@ static void stream_destroy_count(void *data) static void test_create(void) { struct pw_main_loop *loop; - struct pw_impl_core *core; - struct pw_remote *remote; + struct pw_core *core; struct pw_stream *stream; struct pw_stream_events stream_events = stream_events_error; struct spa_hook listener = { 0, }; @@ -142,9 +141,8 @@ static void test_create(void) struct pw_time tm; loop = pw_main_loop_new(NULL); - core = pw_impl_core_new(pw_main_loop_get_loop(loop), NULL, 12); - remote = pw_remote_new(core, NULL, 12); - stream = pw_stream_new(remote, "test", NULL); + core = pw_core_connect(pw_main_loop_get_loop(loop), NULL, 12); + stream = pw_stream_new(core, "test", NULL); spa_assert(stream != NULL); pw_stream_add_listener(stream, &listener, &stream_events, stream); @@ -153,8 +151,8 @@ static void test_create(void) spa_assert(error == NULL); /* check name */ spa_assert(!strcmp(pw_stream_get_name(stream), "test")); - /* check remote */ - spa_assert(pw_stream_get_remote(stream) == remote); + /* check core */ + spa_assert(pw_stream_get_core(stream) == core); /* check id, only when connected */ spa_assert(pw_stream_get_node_id(stream) == SPA_ID_INVALID); @@ -175,25 +173,23 @@ static void test_create(void) pw_stream_destroy(stream); spa_assert(destroy_count == 1); - pw_impl_core_destroy(core); + pw_core_disconnect(core); pw_main_loop_destroy(loop); } static void test_properties(void) { struct pw_main_loop *loop; - struct pw_impl_core *core; + struct pw_core *core; const struct pw_properties *props; - struct pw_remote *remote; struct pw_stream *stream; struct pw_stream_events stream_events = stream_events_error; struct spa_hook listener = { NULL, }; struct spa_dict_item items[3]; loop = pw_main_loop_new(NULL); - core = pw_impl_core_new(pw_main_loop_get_loop(loop), NULL, 0); - remote = pw_remote_new(core, NULL, 0); - stream = pw_stream_new(remote, "test", + core = pw_core_connect(pw_main_loop_get_loop(loop), NULL, 0); + stream = pw_stream_new(core, "test", pw_properties_new("foo", "bar", "biz", "fuzz", NULL)); @@ -222,7 +218,7 @@ static void test_properties(void) /* check destroy */ destroy_count = 0; stream_events.destroy = stream_destroy_count; - pw_impl_core_destroy(core); + pw_core_disconnect(core); spa_assert(destroy_count == 1); pw_main_loop_destroy(loop); diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c index d623d393..56a3919b 100644 --- a/src/tools/pipewire-cli.c +++ b/src/tools/pipewire-cli.c @@ -35,7 +35,6 @@ #include <pipewire/pipewire.h> #include <pipewire/type.h> #include <pipewire/permission.h> -#include <pipewire/impl-module.h> #include <extensions/session-manager.h> @@ -44,8 +43,8 @@ static const char WHITESPACE[] = " \t"; struct remote_data; struct data { - struct pw_main_loop *loop; - struct pw_impl_core *core; + struct pw_main_loop *main_loop; + struct pw_loop *loop; struct spa_list remotes; struct remote_data *current; @@ -71,12 +70,10 @@ struct remote_data { char *name; uint32_t id; - struct pw_remote *remote; - struct spa_hook remote_listener; - int prompt_pending; - struct pw_core *core; struct spa_hook core_listener; + int prompt_pending; + struct pw_registry *registry; struct spa_hook registry_listener; @@ -242,10 +239,11 @@ static bool do_help(struct data *data, const char *cmd, char *args, char **error static bool do_load_module(struct data *data, const char *cmd, char *args, char **error) { - struct pw_impl_module *module; + struct pw_module *module; char *a[2]; int n; uint32_t id; + struct remote_data *rd = data->current; n = pw_split_ip(args, WHITESPACE, 2, a); if (n < 1) { @@ -253,40 +251,18 @@ static bool do_load_module(struct data *data, const char *cmd, char *args, char return false; } - module = pw_impl_module_load(data->core, a[0], n == 2 ? a[1] : NULL, NULL); + module = pw_core_load_module(rd->core, a[0], n == 2 ? a[1] : NULL, NULL, 0); if (module == NULL) { - asprintf(error, "Could not load module"); + asprintf(error, "Could not load module: %m"); return false; } id = pw_map_insert_new(&data->vars, module); - fprintf(stdout, "%d = @module:%d\n", id, pw_global_get_id(pw_impl_module_get_global(module))); + fprintf(stdout, "%d = @module:%d\n", id, pw_proxy_get_id((struct pw_proxy*)module)); return true; } -static void on_core_info(void *_data, const struct pw_core_info *info) -{ - struct remote_data *rd = _data; - free(rd->name); - rd->name = info->name ? strdup(info->name) : NULL; - fprintf(stdout, "remote %d is named '%s'\n", rd->id, rd->name); -} - -static void show_prompt(struct remote_data *rd) -{ - fprintf(stdout, "%s>>", rd->name); - fflush(stdout); -} - -static void on_core_done(void *_data, uint32_t id, int seq) -{ - struct remote_data *rd = _data; - - if (seq == rd->prompt_pending) - show_prompt(rd); -} - static int print_global(void *obj, void *data) { struct global *global = obj; @@ -370,96 +346,6 @@ static const struct pw_registry_events registry_events = { .global_remove = registry_event_global_remove, }; -static void on_remote_destroy(void *_data) -{ - struct remote_data *rd = _data; - struct data *data = rd->data; - - spa_list_remove(&rd->link); - - pw_map_remove(&data->vars, rd->id); - pw_map_for_each(&rd->globals, destroy_global, rd); - - if (data->current == rd) - data->current = NULL; - free(rd->name); -} - -static const struct pw_core_events remote_core_events = { - PW_VERSION_CORE_EVENTS, - .info = on_core_info, - .done = on_core_done, -}; - -static void on_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) -{ - struct remote_data *rd = _data; - struct data *data = rd->data; - - switch (state) { - case PW_REMOTE_STATE_ERROR: - fprintf(stderr, "remote %d error: %s\n", rd->id, error); - pw_main_loop_quit(data->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - fprintf(stdout, "remote %d state: \"%s\"\n", rd->id, pw_remote_state_as_string(state)); - rd->core = pw_remote_get_core(rd->remote); - pw_core_add_listener(rd->core, - &rd->core_listener, - &remote_core_events, rd); - rd->registry = pw_core_get_registry(rd->core, PW_VERSION_REGISTRY, 0); - pw_registry_add_listener(rd->registry, - &rd->registry_listener, - ®istry_events, rd); - rd->prompt_pending = pw_core_sync(rd->core, 0, 0); - break; - - default: - fprintf(stdout, "remote %d state: \"%s\"\n", rd->id, pw_remote_state_as_string(state)); - break; - } -} - -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .destroy = on_remote_destroy, - .state_changed = on_state_changed, -}; - - -static bool do_connect(struct data *data, const char *cmd, char *args, char **error) -{ - char *a[1]; - int n; - struct pw_remote *remote; - struct pw_properties *props = NULL; - struct remote_data *rd; - - n = pw_split_ip(args, WHITESPACE, 1, a); - if (n == 1) { - props = pw_properties_new(PW_KEY_REMOTE_NAME, a[0], NULL); - } - remote = pw_remote_new(data->core, props, sizeof(struct remote_data)); - - rd = pw_remote_get_user_data(remote); - rd->remote = remote; - rd->data = data; - pw_map_init(&rd->globals, 64, 16); - rd->id = pw_map_insert_new(&data->vars, rd); - spa_list_append(&data->remotes, &rd->link); - - fprintf(stdout, "%d = @remote:%p\n", rd->id, remote); - data->current = rd; - - pw_remote_add_listener(remote, &rd->remote_listener, &remote_events, rd); - if (pw_remote_connect(remote) < 0) - return false; - - return true; -} - static bool do_disconnect(struct data *data, const char *cmd, char *args, char **error) { char *a[1]; @@ -475,8 +361,7 @@ static bool do_disconnect(struct data *data, const char *cmd, char *args, char * goto no_remote; } - pw_remote_disconnect(rd->remote); - pw_remote_destroy(rd->remote); + pw_core_disconnect(rd->core); if (data->current == NULL) { if (spa_list_is_empty(&data->remotes)) { @@ -497,7 +382,7 @@ static bool do_list_remotes(struct data *data, const char *cmd, char *args, char struct remote_data *rd; spa_list_for_each(rd, &data->remotes, link) - fprintf(stdout, "\t%d = @remote:%p '%s'\n", rd->id, rd->remote, rd->name); + fprintf(stdout, "\t%d = @core:%p '%s'\n", rd->id, rd->core, rd->name); return true; } @@ -722,11 +607,26 @@ static void core_event_info(void *object, const struct pw_core_info *info) info_core(pd); pd->global->info_pending = false; } + fprintf(stdout, "remote %d is named '%s'\n", rd->id, rd->name); +} + +static void show_prompt(struct remote_data *rd) +{ + fprintf(stdout, "%s>>", rd->name); + fflush(stdout); +} + +static void core_event_done(void *_data, uint32_t id, int seq) +{ + struct remote_data *rd = _data; + if (seq == rd->prompt_pending) + show_prompt(rd); } static const struct pw_core_events core_events = { PW_VERSION_CORE_EVENTS, - .info = core_event_info + .info = core_event_info, + .done = core_event_done, }; @@ -1092,6 +992,9 @@ static bool do_list_objects(struct data *data, const char *cmd, char *args, char return true; } + + + static bool bind_global(struct remote_data *rd, struct global *global, char **error) { const void *events; @@ -1102,12 +1005,14 @@ static bool bind_global(struct remote_data *rd, struct global *global, char **er struct pw_proxy *proxy; switch (global->type) { +#if 0 case PW_TYPE_INTERFACE_Core: events = &core_events; client_version = PW_VERSION_CORE; destroy = (pw_destroy_t) pw_core_info_free; info_func = info_core; break; +#endif case PW_TYPE_INTERFACE_Module: events = &module_events; client_version = PW_VERSION_MODULE; @@ -1397,6 +1302,7 @@ static bool do_create_link(struct data *data, const char *cmd, char *args, char static bool do_export_node(struct data *data, const char *cmd, char *args, char **error) { +#if 0 struct remote_data *rd = data->current; struct pw_global *global; struct pw_node *node; @@ -1436,6 +1342,7 @@ static bool do_export_node(struct data *data, const char *cmd, char *args, char no_remote: asprintf(error, "Remote %d does not exist", idx); +#endif return false; } @@ -1563,6 +1470,42 @@ static bool do_get_permissions(struct data *data, const char *cmd, char *args, c return true; } +static bool do_connect(struct data *data, const char *cmd, char *args, char **error) +{ + char *a[1]; + int n; + struct pw_core *core; + struct pw_properties *props = NULL; + struct remote_data *rd; + + n = pw_split_ip(args, WHITESPACE, 1, a); + if (n == 1) { + props = pw_properties_new(PW_KEY_REMOTE_NAME, a[0], NULL); + } + core = pw_core_connect(data->loop, props, sizeof(struct remote_data)); + + rd = pw_core_get_user_data(core); + rd->core = core; + rd->data = data; + pw_map_init(&rd->globals, 64, 16); + rd->id = pw_map_insert_new(&data->vars, rd); + spa_list_append(&data->remotes, &rd->link); + + fprintf(stdout, "%d = @core:%p\n", rd->id, core); + data->current = rd; + + pw_core_add_listener(core, &rd->core_listener, &core_events, rd); + + rd->registry = pw_core_get_registry(rd->core, PW_VERSION_REGISTRY, 0); + pw_registry_add_listener(rd->registry, + &rd->registry_listener, + ®istry_events, rd); + + rd->prompt_pending = pw_core_sync(rd->core, 0, 0); + + return true; +} + static bool parse(struct data *data, char *buf, size_t size, char **error) { char *a[2]; @@ -1615,7 +1558,7 @@ static void do_input(void *data, int fd, uint32_t mask) } if (r == 0) { fprintf(stdout, "\n"); - pw_main_loop_quit(d->loop); + pw_main_loop_quit(d->main_loop); return; } buf[r] = '\0'; @@ -1625,7 +1568,7 @@ static void do_input(void *data, int fd, uint32_t mask) free(error); } if (d->current == NULL) - pw_main_loop_quit(d->loop); + pw_main_loop_quit(d->main_loop); else { struct remote_data *rd = d->current; if (rd->core) @@ -1637,42 +1580,32 @@ static void do_input(void *data, int fd, uint32_t mask) static void do_quit(void *data, int signal_number) { struct data *d = data; - pw_main_loop_quit(d->loop); + pw_main_loop_quit(d->main_loop); } int main(int argc, char *argv[]) { struct data data = { 0 }; - struct pw_loop *l; - const struct pw_core_info *info; char *error, args[128]; pw_init(&argc, &argv); - data.loop = pw_main_loop_new(NULL); - l = pw_main_loop_get_loop(data.loop); - pw_loop_add_signal(l, SIGINT, do_quit, &data); - pw_loop_add_signal(l, SIGTERM, do_quit, &data); + data.main_loop = pw_main_loop_new(NULL); + data.loop = pw_main_loop_get_loop(data.main_loop); + pw_loop_add_signal(data.loop, SIGINT, do_quit, &data); + pw_loop_add_signal(data.loop, SIGTERM, do_quit, &data); spa_list_init(&data.remotes); pw_map_init(&data.vars, 64, 16); - data.core = pw_impl_core_new(l, pw_properties_new(PW_KEY_CORE_DAEMON, "1", NULL), 0); - info = pw_impl_core_get_info(data.core); - - pw_impl_module_load(data.core, "libpipewire-module-link-factory", NULL, NULL); - - pw_loop_add_io(l, STDIN_FILENO, SPA_IO_IN|SPA_IO_HUP, false, do_input, &data); - - fprintf(stdout, "Welcome to PipeWire \"%s\" version %s. Type 'help' for usage.\n", info->name, info->version); + pw_loop_add_io(data.loop, STDIN_FILENO, SPA_IO_IN|SPA_IO_HUP, false, do_input, &data); - snprintf(args, sizeof(args), "%s", info->name); + args[0] = 0; do_connect(&data, "connect", args, &error); - pw_main_loop_run(data.loop); + pw_main_loop_run(data.main_loop); - pw_impl_core_destroy(data.core); - pw_main_loop_destroy(data.loop); + pw_main_loop_destroy(data.main_loop); return 0; } diff --git a/src/tools/pipewire-dot.c b/src/tools/pipewire-dot.c index ef510b40..18bf70f4 100644 --- a/src/tools/pipewire-dot.c +++ b/src/tools/pipewire-dot.c @@ -29,11 +29,10 @@ #include <spa/debug/pod.h> #include <spa/debug/format.h> #include <spa/debug/types.h> +#include <spa/utils/result.h> -#include <pipewire/type.h> -#include <pipewire/remote.h> +#include <pipewire/pipewire.h> #include <pipewire/main-loop.h> -#include <pipewire/impl.h> #define GLOBAL_ID_NONE UINT32_MAX #define DEFAULT_DOT_PATH "pw.dot" @@ -45,10 +44,6 @@ typedef void *(*info_update_t) (void *info, const void *update); struct data { struct pw_main_loop *loop; - struct pw_impl_core *core_impl; - - struct pw_remote *remote; - struct spa_hook remote_listener; struct pw_core *core; struct spa_hook core_listener; @@ -710,42 +705,18 @@ static void on_core_done(void *data, uint32_t id, int seq) pw_main_loop_quit(d->loop); } -static const struct pw_core_events core_events = { - PW_VERSION_CORE_EVENTS, - .done = on_core_done, -}; - -static void on_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) { - struct data *data = _data; - - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); - pw_main_loop_quit(data->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - data->core = pw_remote_get_core(data->remote); - pw_core_add_listener(data->core, - &data->core_listener, - &core_events, data); - data->registry = pw_core_get_registry(data->core, - PW_VERSION_REGISTRY, 0); - pw_registry_add_listener(data->registry, - &data->registry_listener, - ®istry_events, data); - break; - - default: - break; - } + struct data *d = data; + printf("error: id:%u %d (%s): \"%s\"\n", id, res, spa_strerror(res), message); + if (id == 0) + pw_main_loop_quit(d->loop); } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, +static const struct pw_core_events core_events = { + PW_VERSION_CORE_EVENTS, + .done = on_core_done, + .error = on_core_error, }; static void do_quit(void *data, int signal_number) @@ -835,34 +806,35 @@ int main(int argc, char *argv[]) pw_loop_add_signal(l, SIGINT, do_quit, &data); pw_loop_add_signal(l, SIGTERM, do_quit, &data); - data.core_impl = pw_impl_core_new(l, NULL, 0); - if (data.core_impl == NULL) - return -1; - if (remote_name) props = pw_properties_new(PW_KEY_REMOTE_NAME, remote_name, NULL); - data.remote = pw_remote_new(data.core_impl, props, 0); - if (data.remote == NULL) - return -1; - - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); - if (pw_remote_connect(data.remote) < 0) - return -1; - data.dot_str = dot_str_new(); if (data.dot_str == NULL) return -1; spa_list_init(&data.globals); + data.core = pw_core_connect(l, props, 0); + if (data.core == NULL) + return -1; + + pw_core_add_listener(data.core, + &data.core_listener, + &core_events, &data); + data.registry = pw_core_get_registry(data.core, + PW_VERSION_REGISTRY, 0); + pw_registry_add_listener(data.registry, + &data.registry_listener, + ®istry_events, &data); + + pw_main_loop_run(data.loop); draw_graph(&data, dot_path); dot_str_clear(&data.dot_str); - pw_remote_destroy(data.remote); - pw_impl_core_destroy(data.core_impl); + pw_core_disconnect(data.core); pw_main_loop_destroy(data.loop); return 0; diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c index 378dbe59..6ab2f4fa 100644 --- a/src/tools/pipewire-monitor.c +++ b/src/tools/pipewire-monitor.c @@ -25,6 +25,7 @@ #include <stdio.h> #include <signal.h> +#include <spa/utils/result.h> #include <spa/debug/pod.h> #include <spa/debug/format.h> #include <spa/debug/types.h> @@ -47,10 +48,6 @@ struct param { struct data { struct pw_main_loop *loop; - struct pw_impl_core *core_impl; - - struct pw_remote *remote; - struct spa_hook remote_listener; struct pw_core *core; struct spa_hook core_listener; @@ -669,46 +666,20 @@ static const struct pw_registry_events registry_events = { .global_remove = registry_event_global_remove, }; +static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) +{ + struct data *d = data; + printf("error: id:%u %d (%s): \"%s\"\n", id, res, spa_strerror(res), message); + if (id == 0) + pw_main_loop_quit(d->loop); +} + + static const struct pw_core_events core_events = { PW_VERSION_CORE_EVENTS, .info = on_core_info, .done = on_core_done, -}; - -static void on_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) -{ - struct data *data = _data; - - switch (state) { - case PW_REMOTE_STATE_ERROR: - printf("remote error: %s\n", error); - pw_main_loop_quit(data->loop); - break; - - case PW_REMOTE_STATE_CONNECTED: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - - data->core = pw_remote_get_core(data->remote); - pw_core_add_listener(data->core, - &data->core_listener, - &core_events, data); - data->registry = pw_core_get_registry(data->core, - PW_VERSION_REGISTRY, 0); - pw_registry_add_listener(data->registry, - &data->registry_listener, - ®istry_events, data); - break; - - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; - } -} - -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .state_changed = on_state_changed, + .error = on_core_error, }; static void do_quit(void *data, int signal_number) @@ -733,27 +704,28 @@ int main(int argc, char *argv[]) pw_loop_add_signal(l, SIGINT, do_quit, &data); pw_loop_add_signal(l, SIGTERM, do_quit, &data); - data.core_impl = pw_impl_core_new(l, NULL, 0); - if (data.core == NULL) - return -1; - if (argc > 1) props = pw_properties_new(PW_KEY_REMOTE_NAME, argv[1], NULL); - data.remote = pw_remote_new(data.core_impl, props, 0); - if (data.remote == NULL) + data.core = pw_core_connect(l, props, 0); + if (data.core == NULL) return -1; - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); - if (pw_remote_connect(data.remote) < 0) - return -1; + pw_core_add_listener(data.core, + &data.core_listener, + &core_events, &data); + + data.registry = pw_core_get_registry(data.core, + PW_VERSION_REGISTRY, 0); + pw_registry_add_listener(data.registry, + &data.registry_listener, + ®istry_events, &data); spa_list_init(&data.pending_list); pw_main_loop_run(data.loop); - pw_remote_destroy(data.remote); - pw_impl_core_destroy(data.core_impl); + pw_core_disconnect(data.core); pw_main_loop_destroy(data.loop); return 0; |