diff options
author | Wim Taymans <wtaymans@redhat.com> | 2019-12-05 10:28:19 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2019-12-05 10:28:19 +0100 |
commit | f1c7ebc79160b45578c3393060a006fc62e930d6 (patch) | |
tree | 93448ef00c4228fa144b12ee4f34638f5f04fda6 | |
parent | 4314fba7c4e245c1089b8937dbddfa9f227463d4 (diff) |
More API experimentsAPI2
Try to hide the pw_remote, we don't really need it
50 files changed, 793 insertions, 755 deletions
diff --git a/doc/pulseaudio.md b/doc/pulseaudio.md index 51f49260..4a0226c9 100644 --- a/doc/pulseaudio.md +++ b/doc/pulseaudio.md @@ -12,6 +12,7 @@ An ALSA card is exposed as a PipeWire device Each alsa PCM is opened and a Node is created for each PCM stream. + # Session Manager ## ALSA UCM @@ -65,4 +66,9 @@ only one profile is selected on the device, only 1 stream is visible on the endpoint. This clashes with the notion that multiple streams can be active at the same time but is a pulseaudio limitation. + + + + + Each Endpoint destination becomes a port on the sink/source. diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c index a55d1029..e66fc20d 100644 --- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c +++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c @@ -40,6 +40,8 @@ #include <pipewire/pipewire.h> +#define NAME "alsa-plugin" + #define MIN_BUFFERS 3u #define MAX_BUFFERS 64u @@ -68,8 +70,8 @@ typedef struct { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; uint32_t flags; struct pw_stream *stream; @@ -193,7 +195,7 @@ snd_pcm_pipewire_process_playback(snd_pcm_pipewire_t *pw, struct pw_buffer *b) ptr = SPA_MEMBER(d[0].data, offset, void); nframes = nbytes / bpf; - pw_log_trace("%d %d %lu %d %d %p %d", nbytes, avail, nframes, filled, offset, ptr, io->state); + pw_log_trace(NAME" %p: %d %d %lu %d %d %p %d", pw, nbytes, avail, nframes, filled, offset, ptr, io->state); for (channel = 0; channel < io->channels; channel++) { pwareas[channel].addr = ptr; @@ -202,7 +204,7 @@ snd_pcm_pipewire_process_playback(snd_pcm_pipewire_t *pw, struct pw_buffer *b) } if (io->state != SND_PCM_STATE_RUNNING && io->state != SND_PCM_STATE_DRAINING) { - pw_log_trace("silence %lu frames %d", nframes, io->state); + pw_log_trace(NAME" %p: silence %lu frames %d", pw, nframes, io->state); for (channel = 0; channel < io->channels; channel++) snd_pcm_area_silence(&pwareas[channel], 0, nframes, io->format); goto done; @@ -272,7 +274,7 @@ snd_pcm_pipewire_process_record(snd_pcm_pipewire_t *pw, struct pw_buffer *b) nbytes = SPA_MIN(avail, maxsize - offset); ptr = SPA_MEMBER(d[0].data, offset, void); - pw_log_trace("%d %d %d %p", nbytes, avail, offset, ptr); + pw_log_trace(NAME" %p: %d %d %d %p", pw, nbytes, avail, offset, ptr); nframes = nbytes / bpf; for (channel = 0; channel < io->channels; channel++) { @@ -329,8 +331,8 @@ static void on_stream_param_changed(void *data, uint32_t id, const struct spa_po buffers = SPA_CLAMP(io->buffer_size / io->period_size, MIN_BUFFERS, MAX_BUFFERS); size = io->period_size * stride; - pw_log_info("buffer_size:%lu period_size:%lu buffers:%u stride:%u size:%u min_avail:%lu", - io->buffer_size, io->period_size, buffers, stride, size, pw->min_avail); + pw_log_info(NAME" %p: buffer_size:%lu period_size:%lu buffers:%u stride:%u size:%u min_avail:%lu", + pw, io->buffer_size, io->period_size, buffers, stride, size, pw->min_avail); params[n_params++] = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, @@ -389,7 +391,7 @@ static int snd_pcm_pipewire_prepare(snd_pcm_ioplug_t *io) min_period = (MIN_PERIOD * io->rate / 48000); pw->min_avail = SPA_MAX(pw->min_avail, min_period); - pw_log_debug("prepare %d %p %lu %ld", pw->error, pw->stream, io->period_size, pw->min_avail); + pw_log_debug(NAME" %p: prepare %d %p %lu %ld", pw, pw->error, pw->stream, io->period_size, pw->min_avail); if (!pw->error && pw->stream != NULL) goto done; @@ -407,7 +409,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_proxy, pw->node_name, props); if (pw->stream == NULL) goto error; @@ -519,7 +521,7 @@ static int snd_pcm_pipewire_hw_params(snd_pcm_ioplug_t * io, snd_pcm_pipewire_t *pw = io->private_data; bool planar; - pw_log_debug("hw_params %lu %lu", io->buffer_size, io->period_size); + pw_log_debug(NAME" %p: hw_params %lu %lu", pw, io->buffer_size, io->period_size); switch(io->access) { case SND_PCM_ACCESS_MMAP_INTERLEAVED: @@ -747,66 +749,26 @@ 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 *data, uint32_t id, int seq, int res, const char *message) { snd_pcm_pipewire_t *pw = data; - switch (state) { - case PW_REMOTE_STATE_ERROR: - pw_log_error("error %s", error); - /* fallthrough */ - case PW_REMOTE_STATE_UNCONNECTED: + pw_log_error(NAME" %p: error id:%u seq:%d res:%d (%s): %s", pw, + 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_proxy_events core_proxy_events = { + PW_VERSION_CORE_PROXY_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, @@ -827,7 +789,7 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, str = getenv("PIPEWIRE_NODE"); - pw_log_debug("open %s %d %d %08x '%s'", name, stream, mode, flags, str); + pw_log_debug(NAME" %p: open %s %d %d %08x '%s'", pw, name, stream, mode, flags, str); pw->fd = -1; pw->io.poll_fd = -1; @@ -860,14 +822,18 @@ 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) + pw_thread_loop_lock(pw->main_loop); + pw->core_proxy = pw_core_connect(pw->core, props, 0); + if (pw->core_proxy == NULL) { + pw_thread_loop_unlock(pw->main_loop); + err = -errno; goto error; + } + pw_core_proxy_add_listener(pw->core_proxy, &pw->core_listener, &core_proxy_events, pw); + pw_thread_loop_unlock(pw->main_loop); pw->fd = spa_system_eventfd_create(pw->loop->system, SPA_FD_CLOEXEC | SPA_FD_NONBLOCK); @@ -882,7 +848,7 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, if ((err = snd_pcm_ioplug_create(&pw->io, name, stream, mode)) < 0) goto error; - pw_log_debug("open %s %d %d", name, pw->io.stream, mode); + pw_log_debug(NAME" %p: open %s %d %d", pw, name, pw->io.stream, mode); if ((err = pipewire_set_hw_constraint(pw)) < 0) goto error; diff --git a/pipewire-pulseaudio/src/context.c b/pipewire-pulseaudio/src/context.c index 0ebea4ef..f374d3a2 100644 --- a/pipewire-pulseaudio/src/context.c +++ b/pipewire-pulseaudio/src/context.c @@ -22,6 +22,7 @@ #include <spa/param/props.h> #include <pipewire/pipewire.h> +#include <pipewire/remote.h> #include <pulse/context.h> #include <pulse/timeval.h> @@ -29,12 +30,12 @@ #include "internal.h" -int pa_context_set_error(pa_context *c, int error) { +int pa_context_set_error(PA_CONST pa_context *c, int error) { pa_assert(error >= 0); pa_assert(error < PA_ERR_MAX); if (c && c->error != error) { pw_log_debug("context %p: error %d %s", c, error, pa_strerror(error)); - c->error = error; + ((pa_context*)c)->error = error; } return error; } diff --git a/pipewire-pulseaudio/src/internal.h b/pipewire-pulseaudio/src/internal.h index fd80d8b8..c9feb26a 100644 --- a/pipewire-pulseaudio/src/internal.h +++ b/pipewire-pulseaudio/src/internal.h @@ -127,7 +127,7 @@ static inline const char *pa_strnull(const char *x) { return x ? x : "(null)"; } -int pa_context_set_error(pa_context *c, int error); +int pa_context_set_error(PA_CONST pa_context *c, int error); #define PA_CHECK_VALIDITY(context, expression, error) \ do { \ diff --git a/pipewire-pulseaudio/src/stream.c b/pipewire-pulseaudio/src/stream.c index f5207fc5..4ea40964 100644 --- a/pipewire-pulseaudio/src/stream.c +++ b/pipewire-pulseaudio/src/stream.c @@ -28,7 +28,9 @@ #include <pulse/timeval.h> #include <pulse/xmalloc.h> +#include <pipewire/introspect.h> #include <pipewire/stream.h> +#include <pipewire/remote.h> #include <pipewire/keys.h> #include "core-format.h" #include "internal.h" @@ -554,7 +556,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_proxy, name, props); s->refcount = 1; s->context = c; spa_list_init(&s->pending); diff --git a/src/examples/bluez-session.c b/src/examples/bluez-session.c index aafef325..b4f5ef78 100644 --- a/src/examples/bluez-session.c +++ b/src/examples/bluez-session.c @@ -75,8 +75,8 @@ struct impl { struct pw_main_loop *loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; struct spa_handle *handle; struct spa_device *device; @@ -140,7 +140,7 @@ static struct node *create_node(struct object *obj, uint32_t id, node->id = id; node->handle = handle; node->node = iface; - node->proxy = pw_remote_export(impl->remote, + node->proxy = pw_core_proxy_export(impl->core_proxy, info->type, pw_properties_new_dict(info->props), node->node, 0); if (node->proxy == NULL) goto clean_node; @@ -248,7 +248,7 @@ static struct object *create_object(struct impl *impl, uint32_t id, obj->id = id; obj->handle = handle; obj->device = iface; - obj->proxy = pw_remote_export(impl->remote, + obj->proxy = pw_core_proxy_export(impl->core_proxy, info->type, pw_properties_new_dict(info->props), obj->device, 0); if (obj->proxy == NULL) goto clean_object; @@ -338,50 +338,37 @@ static int start_monitor(struct impl *impl) return res; } -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 impl *impl = _data; - int res; - - switch (state) { - case PW_REMOTE_STATE_ERROR: - pw_log_error(NAME" %p: remote error: %s", impl, error); - pw_main_loop_quit(impl->loop); - break; - case PW_REMOTE_STATE_CONNECTED: - pw_log_info(NAME" %p: connected", impl); - if ((res = start_monitor(impl)) < 0) { - pw_log_debug("error starting monitor: %s", spa_strerror(res)); - pw_main_loop_quit(impl->loop); - } - break; + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); - case PW_REMOTE_STATE_UNCONNECTED: - pw_log_info(NAME" %p: disconnected", impl); + if (id == 0) { pw_main_loop_quit(impl->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_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; int main(int argc, char *argv[]) { struct impl impl = { 0, }; + int res; pw_init(&argc, &argv); impl.loop = pw_main_loop_new(NULL); impl.core = pw_core_new(pw_main_loop_get_loop(impl.loop), NULL, 0); - impl.remote = pw_remote_new(impl.core, NULL, 0); + impl.core_proxy = pw_core_connect(impl.core, NULL, 0); + if (impl.core_proxy == NULL) + return -1; + + spa_list_init(&impl.device_list); pw_core_add_spa_lib(impl.core, "api.bluez5.*", "bluez5/libspa-bluez5"); @@ -389,15 +376,14 @@ int main(int argc, char *argv[]) clock_gettime(CLOCK_MONOTONIC, &impl.now); - spa_list_init(&impl.device_list); - - pw_remote_add_listener(impl.remote, - &impl.remote_listener, - &remote_events, &impl); + pw_core_proxy_add_listener(impl.core_proxy, + &impl.core_listener, + &core_events, &impl); - if (pw_remote_connect(impl.remote) < 0) + if ((res = start_monitor(&impl)) < 0) { + pw_log_debug("error starting monitor: %s", spa_strerror(res)); return -1; - + } pw_main_loop_run(impl.loop); pw_core_destroy(impl.core); diff --git a/src/examples/export-sink.c b/src/examples/export-sink.c index d2e626d6..d617efec 100644 --- a/src/examples/export-sink.c +++ b/src/examples/export-sink.c @@ -26,6 +26,7 @@ #include <stdio.h> #include <sys/mman.h> +#include <spa/utils/result.h> #include <spa/param/video/format-utils.h> #include <spa/param/props.h> #include <spa/node/utils.h> @@ -70,8 +71,8 @@ struct data { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; struct spa_node impl_node; struct spa_hook_list hooks; @@ -473,47 +474,41 @@ 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_proxy_export(data->core_proxy, SPA_TYPE_INTERFACE_Node, props, &data->impl_node, 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]; + 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_proxy_update_permissions( + pw_core_proxy_get_client_proxy(data->core_proxy), + 2, permissions); +} - /* 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; +static void on_core_error(void *_data, uint32_t id, int seq, int res, const char *message) +{ + struct data *data = _data; - pw_client_proxy_update_permissions( - pw_remote_get_client_proxy(data->remote), - 2, permissions); + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); - make_node(data); - break; - } - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; + 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_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; int main(int argc, char *argv[]) @@ -524,7 +519,12 @@ int main(int argc, char *argv[]) data.loop = pw_main_loop_new(NULL); data.core = pw_core_new(pw_main_loop_get_loop(data.loop), NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); + data.core_proxy = pw_core_connect(data.core, NULL, 0); + if (data.core_proxy == NULL) + return -1; + + pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data); + data.path = argc > 1 ? argv[1] : NULL; spa_hook_list_init(&data.hooks); @@ -554,10 +554,9 @@ int main(int argc, char *argv[]) return -1; } - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + set_permissions(&data); - if (pw_remote_connect(data.remote) < 0) - return -1; + make_node(&data); pw_main_loop_run(data.loop); diff --git a/src/examples/export-source.c b/src/examples/export-source.c index e4c426b0..270e8a06 100644 --- a/src/examples/export-source.c +++ b/src/examples/export-source.c @@ -27,6 +27,7 @@ #include <math.h> #include <sys/mman.h> +#include <spa/utils/result.h> #include <spa/param/audio/format-utils.h> #include <spa/param/props.h> #include <spa/node/io.h> @@ -55,8 +56,8 @@ struct data { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; uint64_t info_all; struct spa_port_info info; @@ -481,33 +482,24 @@ 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_proxy_export(data->core_proxy, SPA_TYPE_INTERFACE_Node, props, &data->impl_node, 0); } -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; + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); - case PW_REMOTE_STATE_CONNECTED: - make_node(data); - break; - - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; + 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_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; int main(int argc, char *argv[]) @@ -518,7 +510,12 @@ int main(int argc, char *argv[]) data.loop = pw_main_loop_new(NULL); data.core = pw_core_new(pw_main_loop_get_loop(data.loop), NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); + data.core_proxy = pw_core_connect(data.core, NULL, 0); + if (data.core_proxy == NULL) + return -1; + + pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data); + data.path = argc > 1 ? argv[1] : NULL; data.info_all = SPA_PORT_CHANGE_MASK_FLAGS | @@ -540,9 +537,7 @@ 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_remote_connect(data.remote); + make_node(&data); pw_main_loop_run(data.loop); diff --git a/src/examples/export-spa-device.c b/src/examples/export-spa-device.c index cc14a318..280577ef 100644 --- a/src/examples/export-spa-device.c +++ b/src/examples/export-spa-device.c @@ -26,6 +26,7 @@ #include <sys/mman.h> #include <signal.h> +#include <spa/utils/result.h> #include <spa/param/video/format-utils.h> #include <spa/param/props.h> @@ -36,8 +37,8 @@ struct data { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; struct pw_device *device; const char *library; @@ -63,39 +64,27 @@ static int make_device(struct data *data) PW_VERSION_DEVICE_PROXY, props, SPA_ID_INVALID); - pw_remote_export(data->remote, SPA_TYPE_INTERFACE_Device, NULL, + pw_core_proxy_export(data->core_proxy, SPA_TYPE_INTERFACE_Device, NULL, pw_device_get_implementation(data->device), 0); 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_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: - 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; + struct data *d = _data; + + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, 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_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; static void do_quit(void *data, int signal_number) @@ -123,16 +112,19 @@ 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 = pw_core_new(l, NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); + data.core_proxy = pw_core_connect(data.core, NULL, 0); data.library = argv[1]; data.factory = argv[2]; pw_module_load(data.core, "libpipewire-module-spa-device-factory", NULL, NULL); pw_module_load(data.core, "libpipewire-module-client-device", NULL, NULL); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + pw_core_proxy_add_listener(data.core_proxy, &data.core_listener, &core_events, &data); - pw_remote_connect(data.remote); + if (make_device(&data) < 0) { + pw_log_error("can't make device"); + return -1; + } pw_main_loop_run(data.loop); diff --git a/src/examples/export-spa.c b/src/examples/export-spa.c index 7aef757f..77abff23 100644 --- a/src/examples/export-spa.c +++ b/src/examples/export-spa.c @@ -26,6 +26,7 @@ #include <sys/mman.h> #include <signal.h> +#include <spa/utils/result.h> #include <spa/param/video/format-utils.h> #include <spa/param/props.h> @@ -36,8 +37,8 @@ struct data { struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; + struct spa_hook core_listener; struct pw_node *node; const char *library; @@ -91,7 +92,7 @@ static int make_node(struct data *data) pw_node_set_active(data->node, true); - data->proxy = pw_remote_export(data->remote, PW_TYPE_INTERFACE_Node, NULL, data->node, 0); + data->proxy = pw_core_proxy_export(data->core_proxy, PW_TYPE_INTERFACE_Node, NULL, data->node, 0); if (data->proxy == NULL) return -errno; @@ -101,33 +102,21 @@ static int make_node(struct data *data) 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_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: - 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; + struct data *d = _data; + + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, 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_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .error = on_core_error, }; static void do_quit(void *data, int signal_number) @@ -155,7 +144,7 @@ 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 = pw_core_new(l, NULL, 0); - data.remote = pw_remote_new(data.core, NULL, 0); + data.core_proxy = pw_core_connect(data.core, NULL, 0); data.library = argv[1]; data.factory = argv[2]; if (argc > 3) @@ -163,9 +152,12 @@ int main(int argc, char *argv[]) pw_module_load(data.core, "libpipewire-module-spa-node-factory", NULL, NULL); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); + pw_core_proxy_add_listener(data.core_proxy, &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); diff --git a/src/examples/media-session/media-session.c b/src/examples/media-session/media-session.c index c4a0de3e..b98e8a37 100644 --- a/src/examples/media-session/media-session.c +++ b/src/examples/media-session/media-session.c @@ -1216,7 +1216,7 @@ struct pw_proxy *sm_media_session_export(struct sm_media_session *sess, void *object, size_t user_data_size) { struct impl *impl = SPA_CONTAINER_OF(sess, struct impl, this); - return pw_remote_export(impl->monitor_remote, type, + return pw_core_proxy_export(impl->monitor_remote->core_proxy, type, properties, object, user_data_size); } @@ -1229,7 +1229,7 @@ struct sm_device *sm_media_session_export_device(struct sm_media_session *sess, pw_log_debug(NAME " %p: device %p", impl, object); - proxy = pw_remote_export(impl->monitor_remote, SPA_TYPE_INTERFACE_Device, + proxy = pw_core_proxy_export(impl->monitor_remote->core_proxy, SPA_TYPE_INTERFACE_Device, properties, object, sizeof(struct sm_device)); device = (struct sm_device *) create_object(impl, proxy, &properties->dict); diff --git a/src/examples/video-src.c b/src/examples/video-src.c index 35a81854..f76eb064 100644 --- a/src/examples/video-src.c +++ b/src/examples/video-src.c @@ -47,8 +47,7 @@ struct data { struct spa_source *timer; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; struct pw_stream *stream; struct spa_hook stream_listener; @@ -186,9 +185,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 +210,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,81 +271,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_core_new(pw_main_loop_get_loop(data.loop), NULL, 0); - data.remote = pw_remote_new(data.core, 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.core_proxy = pw_core_connect(data.core, NULL, 0); + if (data.core_proxy == NULL) + return -1; + + data.stream = pw_stream_new(data.core_proxy, "video-src", + pw_properties_new( + PW_KEY_MEDIA_CLASS, "Video/Source", + NULL)); - 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_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); pw_main_loop_run(data.loop); diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index 8283a805..4efefe29 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -28,6 +28,8 @@ #include <string.h> +#include <pipewire/remote.h> + #include <gst/gst.h> #include "gstpipewireformat.h" diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index fa77fe3a..ae63cbb7 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -665,7 +665,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_proxy, pwsink->client_name, props); pwsink->pool->stream = pwsink->stream; pw_stream_add_listener(pwsink->stream, @@ -697,62 +697,22 @@ 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) -{ - 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_ELEMENT_ERROR (pwsink, RESOURCE, FAILED, - ("remote error: %s", error), (NULL)); - break; - } - 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 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_proxy = pw_core_connect (pwsink->core, NULL, 0); else - pw_remote_connect_fd (pwsink->remote, dup(pwsink->fd)); + pwsink->core_proxy = pw_core_connect_fd (pwsink->core, dup(pwsink->fd), NULL, 0); - while (TRUE) { - enum pw_remote_state state = pw_remote_get_state (pwsink->remote, &error); + if (pwsink->core_proxy == NULL) + goto connect_error; - if (state == PW_REMOTE_STATE_CONNECTED) - break; - - if (state == PW_REMOTE_STATE_ERROR) - goto connect_error; - - pw_thread_loop_wait (pwsink->main_loop); - } pw_thread_loop_unlock (pwsink->main_loop); return TRUE; @@ -766,6 +726,8 @@ mainloop_error: } connect_error: { + GST_ELEMENT_ERROR (pwsink, RESOURCE, FAILED, + ("Failed to connect"), (NULL)); pw_thread_loop_unlock (pwsink->main_loop); return FALSE; } @@ -774,26 +736,13 @@ connect_error: 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); - } + if (pwsink->core_proxy) { + pw_core_proxy_disconnect (pwsink->core_proxy); + pwsink->core_proxy = NULL; } pw_thread_loop_unlock (pwsink->main_loop); @@ -804,11 +753,6 @@ gst_pipewire_sink_close (GstPipeWireSink * pwsink) pwsink->stream = NULL; } - if (pwsink->remote) { - pw_remote_destroy (pwsink->remote); - pwsink->remote = NULL; - } - return TRUE; } diff --git a/src/gst/gstpipewiresink.h b/src/gst/gstpipewiresink.h index 90866aba..75f6cf3a 100644 --- a/src/gst/gstpipewiresink.h +++ b/src/gst/gstpipewiresink.h @@ -87,8 +87,7 @@ struct _GstPipeWireSink { struct pw_thread_loop *main_loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; struct pw_stream *stream; struct spa_hook stream_listener; diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index cc27445d..08fce6ba 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -493,6 +493,7 @@ gst_pipewire_src_stream_start (GstPipeWireSrc *pwsrc) { const char *error = NULL; pw_thread_loop_lock (pwsrc->main_loop); + GST_DEBUG_OBJECT (pwsrc, "doing stream start"); while (TRUE) { enum pw_stream_state state = pw_stream_get_state (pwsrc->stream, &error); @@ -504,9 +505,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 +540,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 +633,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 +907,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,11 +921,6 @@ 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 const struct pw_stream_events stream_events = { PW_VERSION_STREAM_EVENTS, .state_changed = on_state_changed, @@ -967,36 +934,19 @@ 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_proxy = pw_core_connect (pwsrc->core, NULL, 0); else - pw_remote_connect_fd (pwsrc->remote, dup(pwsrc->fd)); + pwsrc->core_proxy = pw_core_connect_fd (pwsrc->core, dup(pwsrc->fd), NULL, 0); - while (TRUE) { - enum pw_remote_state state = pw_remote_get_state(pwsrc->remote, &error); - - GST_DEBUG ("waiting for CONNECTED, now %s", pw_remote_state_as_string (state)); - if (state == PW_REMOTE_STATE_CONNECTED) - break; - - if (state == PW_REMOTE_STATE_ERROR) - goto connect_error; - - pw_thread_loop_wait (pwsrc->main_loop); - } + if (pwsrc->core_proxy == NULL) + goto connect_error; if (pwsrc->properties) { props = pw_properties_new (NULL, NULL); @@ -1005,16 +955,14 @@ 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_proxy, pwsrc->client_name, props)) == NULL) goto no_stream; - pw_stream_add_listener(pwsrc->stream, &pwsrc->stream_listener, &stream_events, pwsrc); - pwsrc->clock = gst_pipewire_clock_new (pwsrc->stream, pwsrc->last_time); pw_thread_loop_unlock (pwsrc->main_loop); @@ -1026,14 +974,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: { + GST_ELEMENT_ERROR (pwsrc, RESOURCE, FAILED, ("can't connect"), (NULL)); pw_thread_loop_unlock (pwsrc->main_loop); return FALSE; } @@ -1065,8 +1008,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_proxy_disconnect (pwsrc->core_proxy); + pwsrc->core_proxy = NULL; } static GstStateChangeReturn diff --git a/src/gst/gstpipewiresrc.h b/src/gst/gstpipewiresrc.h index 14dc4261..af61ad9e 100644 --- a/src/gst/gstpipewiresrc.h +++ b/src/gst/gstpipewiresrc.h @@ -75,8 +75,7 @@ struct _GstPipeWireSrc { struct pw_thread_loop *main_loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; + struct pw_core_proxy *core_proxy; 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 64091971..869c6325 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/pipewire.h> +#include <pipewire/remote.h> #include "module-client-device/client-device.h" @@ -43,7 +44,7 @@ static const struct spa_dict_item module_props[] = { { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, }; -struct pw_proxy *pw_remote_spa_device_export(struct pw_remote *remote, +struct pw_proxy *pw_core_proxy_spa_device_export(struct pw_core_proxy *core, uint32_t type, struct pw_properties *props, void *object, size_t user_data_size); @@ -188,7 +189,7 @@ int pipewire__module_init(struct pw_module *module, const char *args) pw_protocol_native_ext_client_device_init(core); data->export_spadevice.type = SPA_TYPE_INTERFACE_Device; - data->export_spadevice.func = pw_remote_spa_device_export; + data->export_spadevice.func = pw_core_proxy_spa_device_export; pw_core_register_export_type(core, &data->export_spadevice); pw_module_add_listener(module, &data->module_listener, &module_events, data); diff --git a/src/modules/module-client-device/proxy-device.c b/src/modules/module-client-device/proxy-device.c index ac30c602..6b4fc7dc 100644 --- a/src/modules/module-client-device/proxy-device.c +++ b/src/modules/module-client-device/proxy-device.c @@ -33,9 +33,6 @@ #include "pipewire/private.h" struct device_data { - struct pw_remote *remote; - struct pw_core *core; - struct spa_device *device; struct spa_hook device_listener; struct spa_hook device_methods; @@ -55,7 +52,7 @@ static const struct pw_proxy_events proxy_events = { .destroy = device_proxy_destroy, }; -struct pw_proxy *pw_remote_spa_device_export(struct pw_remote *remote, +struct pw_proxy *pw_core_proxy_spa_device_export(struct pw_core_proxy *core_proxy, uint32_t type, struct pw_properties *props, void *object, size_t user_data_size) { @@ -64,7 +61,7 @@ struct pw_proxy *pw_remote_spa_device_export(struct pw_remote *remote, struct pw_proxy *proxy; struct device_data *data; - proxy = pw_core_proxy_create_object(remote->core_proxy, + proxy = pw_core_proxy_create_object(core_proxy, "client-device", SPA_TYPE_INTERFACE_Device, SPA_VERSION_DEVICE, @@ -77,9 +74,7 @@ struct pw_proxy *pw_remote_spa_device_export(struct pw_remote *remote, data = pw_proxy_get_user_data(proxy); data = SPA_MEMBER(data, user_data_size, struct device_data); - data->remote = remote; data->device = device; - data->core = pw_remote_get_core(remote); 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 5b470ab0..e7a8d697 100644 --- a/src/modules/module-client-node.c +++ b/src/modules/module-client-node.c @@ -44,9 +44,9 @@ static const struct spa_dict_item module_props[] = { { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, }; -struct pw_proxy *pw_remote_node_export(struct pw_remote *remote, +struct pw_proxy *pw_core_proxy_node_export(struct pw_core_proxy *core_proxy, uint32_t type, struct pw_properties *props, void *object, size_t user_data_size); -struct pw_proxy *pw_remote_spa_node_export(struct pw_remote *remote, +struct pw_proxy *pw_core_proxy_spa_node_export(struct pw_core_proxy *core_proxy, uint32_t type, struct pw_properties *props, void *object, size_t user_data_size); struct pw_protocol *pw_protocol_native_ext_client_node_init(struct pw_core *core); @@ -178,11 +178,11 @@ int pipewire__module_init(struct pw_module *module, const char *args) pw_protocol_native_ext_client_node0_init(core); data->export_node.type = PW_TYPE_INTERFACE_Node; - data->export_node.func = pw_remote_node_export; + data->export_node.func = pw_core_proxy_node_export; pw_core_register_export_type(core, &data->export_node); data->export_spanode.type = SPA_TYPE_INTERFACE_Node; - data->export_spanode.func = pw_remote_spa_node_export; + data->export_spanode.func = pw_core_proxy_spa_node_export; pw_core_register_export_type(core, &data->export_spanode); pw_module_add_listener(module, &data->module_listener, &module_events, data); diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index a5ffcba4..3e1d7331 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -1104,7 +1104,7 @@ static const struct spa_node_callbacks node_callbacks = { .xrun = node_xrun }; -static struct pw_proxy *node_export(struct pw_remote *remote, void *object, bool do_free, +static struct pw_proxy *node_export(struct pw_core_proxy *core_proxy, void *object, bool do_free, size_t user_data_size) { struct pw_node *node = object; @@ -1112,7 +1112,7 @@ static struct pw_proxy *node_export(struct pw_remote *remote, void *object, bool struct node_data *data; int i; - client_node = pw_core_proxy_create_object(remote->core_proxy, + client_node = pw_core_proxy_create_object(core_proxy, "client-node", PW_TYPE_INTERFACE_ClientNode, PW_VERSION_CLIENT_NODE, @@ -1122,7 +1122,7 @@ static struct pw_proxy *node_export(struct pw_remote *remote, void *object, bool return NULL; data = pw_proxy_get_user_data(client_node); - data->remote = remote; + data->remote = ((struct pw_proxy *)core_proxy)->remote; data->node = node; data->do_free = do_free; data->core = pw_node_get_core(node); @@ -1161,7 +1161,7 @@ static struct pw_proxy *node_export(struct pw_remote *remote, void *object, bool return data->proxy; } -struct pw_proxy *pw_remote_node_export(struct pw_remote *remote, +struct pw_proxy *pw_core_proxy_node_export(struct pw_core_proxy *core_proxy, uint32_t type, struct pw_properties *props, void *object, size_t user_data_size) { @@ -1171,16 +1171,16 @@ struct pw_proxy *pw_remote_node_export(struct pw_remote *remote, pw_node_update_properties(node, &props->dict); pw_properties_free(props); } - return node_export(remote, object, false, user_data_size); + return node_export(core_proxy, object, false, user_data_size); } -struct pw_proxy *pw_remote_spa_node_export(struct pw_remote *remote, +struct pw_proxy *pw_core_proxy_spa_node_export(struct pw_core_proxy *core_proxy, uint32_t type, struct pw_properties *props, void *object, size_t user_data_size) { struct pw_node *node; - node = pw_node_new(pw_remote_get_core(remote), props, 0); + node = pw_node_new(pw_core_proxy_get_core(core_proxy), props, 0); if (node == NULL) return NULL; @@ -1188,5 +1188,5 @@ struct pw_proxy *pw_remote_spa_node_export(struct pw_remote *remote, pw_node_register(node, NULL); pw_node_set_active(node, true); - return node_export(remote, node, true, user_data_size); + return node_export(core_proxy, node, true, user_data_size); } diff --git a/src/modules/module-metadata.c b/src/modules/module-metadata.c index 1aaf1585..f475f694 100644 --- a/src/modules/module-metadata.c +++ b/src/modules/module-metadata.c @@ -46,7 +46,7 @@ static const struct spa_dict_item module_props[] = { void * pw_metadata_new(struct pw_core *core, struct pw_resource *resource, struct pw_properties *properties); -struct pw_proxy *pw_remote_metadata_export(struct pw_remote *remote, +struct pw_proxy *pw_core_proxy_metadata_export(struct pw_core_proxy *core_proxy, uint32_t type, struct pw_properties *props, void *object, size_t user_data_size); int pw_protocol_native_ext_metadata_init(struct pw_core *core); @@ -174,7 +174,7 @@ int pipewire__module_init(struct pw_module *module, const char *args) data); data->export_metadata.type = PW_TYPE_INTERFACE_Metadata; - data->export_metadata.func = pw_remote_metadata_export; + data->export_metadata.func = pw_core_proxy_metadata_export; pw_core_register_export_type(core, &data->export_metadata); pw_module_add_listener(module, &data->module_listener, &module_events, data); diff --git a/src/modules/module-metadata/proxy-metadata.c b/src/modules/module-metadata/proxy-metadata.c index ce224796..45989260 100644 --- a/src/modules/module-metadata/proxy-metadata.c +++ b/src/modules/module-metadata/proxy-metadata.c @@ -33,7 +33,6 @@ #include "extensions/metadata.h" struct object_data { - struct pw_remote *remote; struct pw_core *core; struct pw_metadata *object; @@ -55,7 +54,7 @@ static const struct pw_proxy_events proxy_events = { .destroy = object_proxy_destroy, }; -struct pw_proxy *pw_remote_metadata_export(struct pw_remote *remote, +struct pw_proxy *pw_core_proxy_metadata_export(struct pw_core_proxy *core_proxy, uint32_t type, struct pw_properties *props, void *object, size_t user_data_size) { @@ -64,7 +63,7 @@ struct pw_proxy *pw_remote_metadata_export(struct pw_remote *remote, struct pw_proxy *proxy; struct object_data *data; - proxy = pw_core_proxy_create_object(remote->core_proxy, + proxy = pw_core_proxy_create_object(core_proxy, "metadata", PW_TYPE_INTERFACE_Metadata, PW_VERSION_METADATA, @@ -77,9 +76,8 @@ struct pw_proxy *pw_remote_metadata_export(struct pw_remote *remote, data = pw_proxy_get_user_data(proxy); data = SPA_MEMBER(data, user_data_size, struct object_data); - data->remote = remote; data->object = object; - data->core = pw_remote_get_core(remote); + data->core = pw_core_proxy_get_core(core_proxy); 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 6c54e26d..62817a31 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -80,6 +80,7 @@ struct protocol_data { struct client { struct pw_protocol_client this; + struct pw_remote *remote; struct spa_source *source; struct pw_protocol_native_connection *connection; @@ -579,7 +580,7 @@ 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_remote *this = impl->remote; struct pw_protocol_native_connection *conn = impl->connection; struct pw_core *core = pw_remote_get_core(this); int res; @@ -667,6 +668,8 @@ 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_proxy_notify((struct pw_proxy*)this->core_proxy, + struct pw_core_proxy_events, error, 0, 0, this->recv_seq, res, "connection error"); pw_loop_destroy_source(pw_core_get_main_loop(core), impl->source); impl->source = NULL; pw_remote_disconnect(this); @@ -676,7 +679,7 @@ error: static void on_need_flush(void *data) { struct client *impl = data; - struct pw_remote *remote = impl->this.remote; + struct pw_remote *remote = impl->remote; if (!impl->flushing && impl->source) { int mask = impl->source->mask; @@ -695,17 +698,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; + struct pw_remote *remote = impl->remote; int res; impl->disconnecting = false; - impl->connection = pw_protocol_native_connection_new(remote->core, fd); - if (impl->connection == NULL) { - res = -errno; - goto error_cleanup; - } - + pw_protocol_native_connection_set_fd(impl->connection, fd); impl->source = pw_loop_add_io(remote->core->main_loop, fd, SPA_IO_IN | SPA_IO_HUP | SPA_IO_ERR, @@ -732,7 +730,7 @@ 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_remote *remote = impl->remote; impl->disconnecting = true; @@ -763,13 +761,14 @@ impl_new_client(struct pw_protocol *protocol, struct client *impl; 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; + impl->remote = remote; if (properties) str = pw_properties_get(properties, PW_KEY_REMOTE_INTENTION); @@ -786,9 +785,20 @@ impl_new_client(struct pw_protocol *protocol, this->disconnect = impl_disconnect; this->destroy = impl_destroy; + impl->connection = pw_protocol_native_connection_new(remote->core, -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) diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c index c3260fd5..2b26dbfc 100644 --- a/src/modules/module-protocol-native/connection.c +++ b/src/modules/module-protocol-native/connection.c @@ -266,6 +266,12 @@ no_mem: return NULL; } +int pw_protocol_native_connection_set_fd(struct pw_protocol_native_connection *conn, int fd) +{ + conn->fd = fd; + return 0; +} + /** Destroy a connection * * \param conn the connection to destroy diff --git a/src/modules/module-protocol-native/connection.h b/src/modules/module-protocol-native/connection.h index c4eb476b..4e37af4d 100644 --- a/src/modules/module-protocol-native/connection.h +++ b/src/modules/module-protocol-native/connection.h @@ -72,6 +72,8 @@ pw_protocol_native_connection_add_listener(struct pw_protocol_native_connection struct pw_protocol_native_connection * pw_protocol_native_connection_new(struct pw_core *core, int fd); +int 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..451c940d 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, - void (*done_callback) (void *data, int res), - void *data); + 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, - void (*done_callback) (void *data, int res), - void *data); + 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..8a85d30b 100644 --- a/src/modules/module-protocol-native/local-socket.c +++ b/src/modules/module-protocol-native/local-socket.c @@ -35,14 +35,15 @@ #include <sys/file.h> #include <pipewire/pipewire.h> +#include <pipewire/remote.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 +52,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 +67,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/pipewire/core-proxy.c b/src/pipewire/core-proxy.c new file mode 100644 index 00000000..1064af01 --- /dev/null +++ b/src/pipewire/core-proxy.c @@ -0,0 +1,179 @@ +/* PipeWire + * + * Copyright © 2018 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/pipewire.h" +#include "pipewire/private.h" + +#include "extensions/protocol-native.h" + +#define NAME "core-proxy" + +/** \cond */ +SPA_EXPORT +struct pw_core_proxy *pw_core_connect(struct pw_core *core, + struct pw_properties *props, size_t user_data_size) +{ + struct pw_remote *remote; + int res; + + remote = pw_remote_new(core, props, user_data_size); + if (remote == NULL) + return NULL; + + if ((res = pw_remote_connect(remote)) < 0) + goto error_free; + + return remote->core_proxy; + +error_free: + pw_remote_destroy(remote); + errno = -res; + return NULL; +} + +SPA_EXPORT +struct pw_core_proxy *pw_core_connect_fd(struct pw_core *core, int fd, + struct pw_properties *props, size_t user_data_size) +{ + struct pw_remote *remote; + int res; + + remote = pw_remote_new(core, props, user_data_size); + if (remote == NULL) + return NULL; + + if ((res = pw_remote_connect_fd(remote, fd)) < 0) + goto error_free; + + return remote->core_proxy; + +error_free: + pw_remote_destroy(remote); + errno = -res; + return NULL; +} + +SPA_EXPORT +int pw_core_proxy_steal_fd(struct pw_core_proxy *proxy) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return pw_remote_steal_fd(remote); +} + +SPA_EXPORT +int pw_core_proxy_disconnect(struct pw_core_proxy *proxy) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + pw_remote_destroy(remote); + return 0; +} + +SPA_EXPORT +struct pw_core *pw_core_proxy_get_core(struct pw_core_proxy *proxy) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return remote->core; +} + +SPA_EXPORT +struct pw_client_proxy *pw_core_proxy_get_client_proxy(struct pw_core_proxy *proxy) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return remote->client_proxy; +} + +const struct pw_properties *pw_core_proxy_get_properties(struct pw_core_proxy *proxy) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return pw_remote_get_properties(remote); +} + +SPA_EXPORT +int pw_core_proxy_update_properties(struct pw_core_proxy *proxy, const struct spa_dict *dict) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return pw_remote_update_properties(remote, dict); +} + +SPA_EXPORT +void *pw_core_proxy_get_user_data(struct pw_core_proxy *proxy) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return pw_remote_get_user_data(remote); +} + +SPA_EXPORT +struct pw_proxy *pw_core_proxy_find_proxy(struct pw_core_proxy *proxy, uint32_t id) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + return pw_remote_find_proxy(remote, id); +} + +SPA_EXPORT +struct pw_proxy *pw_core_proxy_export(struct pw_core_proxy *proxy, + uint32_t type, struct pw_properties *props, void *object, + size_t user_data_size) +{ + struct pw_remote *remote = ((struct pw_proxy*)proxy)->remote; + struct pw_core *core = remote->core; + struct pw_proxy *p; + const struct pw_export_type *t; + int res; + + t = pw_core_find_export_type(core, type); + if (t == NULL) { + res = -EPROTO; + goto error_export_type; + } + + p = t->func(proxy, type, props, object, user_data_size); + if (p == NULL) { + res = -errno; + goto error_proxy_failed; + } + return p; + +error_export_type: + pw_log_error(NAME" %p: can't export type %d: %s", core, type, spa_strerror(res)); + goto exit_free; +error_proxy_failed: + pw_log_error(NAME" %p: failed to create proxy: %s", core, spa_strerror(res)); + goto exit; +exit_free: + if (props) + pw_properties_free(props); +exit: + errno = -res; + return NULL; +} diff --git a/src/pipewire/core-proxy.h b/src/pipewire/core-proxy.h new file mode 100644 index 00000000..c256b06c --- /dev/null +++ b/src/pipewire/core-proxy.h @@ -0,0 +1,103 @@ +/* PipeWire + * + * Copyright © 2018 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_CORE_PROXY_H +#define PIPEWIRE_CORE_PROXY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <spa/utils/hook.h> + +/** \class pw_core_proxy + * + * \brief Represents a connection with a PipeWire instance + * + * a \ref pw_core_proxy is created when connecting to a PipeWire + * instance. + * + * See also \ref page_core_api + */ +#include <pipewire/core.h> +#include <pipewire/properties.h> +#include <pipewire/node.h> +#include <pipewire/proxy.h> + +/** Create a new connected core_proxy + * \return a new connected core_proxy */ +struct pw_core_proxy * +pw_core_connect(struct pw_core *core, /**< a \ref pw_core */ + struct pw_properties *properties, /**< optional properties, ownership of + * the properties is taken.*/ + size_t user_data_size /**< extra user data size */); + +/** Connect to a PipeWire instance on the given socket \memberof pw_core_proxy + * \param fd the connected socket to use, the socket will be closed + * automatically on disconnect or error. + * \return 0 on success, < 0 on error */ +struct pw_core_proxy * +pw_core_connect_fd(struct pw_core *core, /**< a \ref pw_core */ + int fd, /**< an fd to connect to */ + struct pw_properties *properties, /**< optional properties, ownership of + * the properties is taken.*/ + size_t user_data_size /**< extra user data size */); + +/** Steal the fd of the core_proxy connection or < 0 on error. The core_proxy + * will be disconnected after this call. */ +int pw_core_proxy_steal_fd(struct pw_core_proxy *core_proxy); + +/** disconnect and destroy a core_proxy \memberof pw_core_proxy */ +int pw_core_proxy_disconnect(struct pw_core_proxy *core_proxy); + +/** Get the core used to construct this core_proxy */ +struct pw_core *pw_core_proxy_get_core(struct pw_core_proxy *core_proxy); + +/** Get the core_proxy properties */ +const struct pw_properties *pw_core_proxy_get_properties(struct pw_core_proxy *core_proxy); + +/** Update properties */ +int pw_core_proxy_update_properties(struct pw_core_proxy *core_proxy, const struct spa_dict *dict); + +/** Get the user_data. The size was given in \ref pw_core_connect */ +void *pw_core_proxy_get_user_data(struct pw_core_proxy *core_proxy); + +/** Get the client proxy */ +struct pw_client_proxy * pw_core_proxy_get_client_proxy(struct pw_core_proxy *core_proxy); + +/** Get the proxy with the given id */ +struct pw_proxy *pw_core_proxy_find_proxy(struct pw_core_proxy *core_proxy, uint32_t id); + +/** run a local object in the given PipeWire instance */ +struct pw_proxy *pw_core_proxy_export(struct pw_core_proxy *proxy, /**< a core proxy */ + uint32_t type, /**< the type of object */ + struct pw_properties *properties, /**< extra properties */ + void *object, /**< object to export */ + size_t user_data_size /**< extra user data */); + +#ifdef __cplusplus +} +#endif + +#endif /* PIPEWIRE_CORE_PROXY_H */ diff --git a/src/pipewire/core.c b/src/pipewire/core.c index 3459237d..1719817e 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -731,6 +731,26 @@ struct pw_loop *pw_core_get_main_loop(struct pw_core *core) } SPA_EXPORT +int pw_core_register_export_type(struct pw_core *core, struct pw_export_type *type) +{ + pw_log_debug("core %p: Add export type %d/%s to core", core, type->type, + spa_debug_type_find_name(pw_type_info(), type->type)); + spa_list_append(&core->export_list, &type->link); + return 0; +} + +SPA_EXPORT +const struct pw_export_type *pw_core_find_export_type(struct pw_core *core, uint32_t type) +{ + const struct pw_export_type *t; + spa_list_for_each(t, &core->export_list, link) { + if (t->type == type) + return t; + } + return NULL; +} + +SPA_EXPORT const struct pw_properties *pw_core_get_properties(struct pw_core *core) { return core->properties; diff --git a/src/pipewire/core.h b/src/pipewire/core.h index 7fdce82e..0ba45cc9 100644 --- a/src/pipewire/core.h +++ b/src/pipewire/core.h @@ -44,6 +44,7 @@ struct pw_core; #include <pipewire/client.h> #include <pipewire/introspect.h> +#include <pipewire/interfaces.h> #include <pipewire/global.h> #include <pipewire/loop.h> #include <pipewire/factory.h> @@ -157,6 +158,22 @@ struct spa_handle *pw_core_load_spa_handle(struct pw_core *core, const char *factory_name, const struct spa_dict *info); + +/** data for registering export functions */ +struct pw_export_type { + struct spa_list link; + uint32_t type; + struct pw_proxy * (*func) (struct pw_core_proxy *proxy, + uint32_t type, struct pw_properties *properties, void *object, + size_t user_data_size); +}; + +/** register a type that can be exported on a core_proxy. This is usually used by + * extension modules */ +int pw_core_register_export_type(struct pw_core *core, struct pw_export_type *type); +/** find information about registered export type */ +const struct pw_export_type *pw_core_find_export_type(struct pw_core *core, uint32_t type); + #ifdef __cplusplus } #endif diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c index 2124bed1..fe7a4a00 100644 --- a/src/pipewire/filter.c +++ b/src/pipewire/filter.c @@ -902,7 +902,7 @@ static int handle_connect(struct pw_filter *filter) pw_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, + filter->proxy = pw_core_proxy_export(filter->remote->core_proxy, PW_TYPE_INTERFACE_Node, NULL, impl->node, 0); if (filter->proxy == NULL) { res = -errno; diff --git a/src/pipewire/interfaces.h b/src/pipewire/interfaces.h index 40e826e6..1b222b2b 100644 --- a/src/pipewire/interfaces.h +++ b/src/pipewire/interfaces.h @@ -37,10 +37,6 @@ extern "C" { #include <spa/node/command.h> #include <spa/param/param.h> -#include <pipewire/introspect.h> -#include <pipewire/proxy.h> -#include <pipewire/permission.h> - #define PW_VERSION_CORE_PROXY 3 struct pw_core_proxy { struct spa_interface iface; }; #define PW_VERSION_REGISTRY_PROXY 3 @@ -60,6 +56,10 @@ struct pw_client_proxy { struct spa_interface iface; }; #define PW_VERSION_LINK_PROXY 3 struct pw_link_proxy { struct spa_interface iface; }; +#include <pipewire/introspect.h> +#include <pipewire/proxy.h> +#include <pipewire/permission.h> + /** * \page page_pipewire_protocol The PipeWire protocol * \section page_ifaces_pipewire Interfaces diff --git a/src/pipewire/introspect.c b/src/pipewire/introspect.c index d8f6442b..9164751d 100644 --- a/src/pipewire/introspect.c +++ b/src/pipewire/introspect.c @@ -28,8 +28,6 @@ #include "pipewire/pipewire.h" -#include "pipewire/remote.h" - SPA_EXPORT const char *pw_node_state_as_string(enum pw_node_state state) { diff --git a/src/pipewire/meson.build b/src/pipewire/meson.build index 357531b2..c22ef73a 100644 --- a/src/pipewire/meson.build +++ b/src/pipewire/meson.build @@ -4,6 +4,7 @@ pipewire_headers = [ 'client.h', 'control.h', 'core.h', + 'core-proxy.h', 'data-loop.h', 'device.h', 'filter.h', @@ -40,6 +41,7 @@ pipewire_sources = [ 'client.c', 'control.c', 'core.c', + 'core-proxy.c', 'data-loop.c', 'device.c', 'filter.c', diff --git a/src/pipewire/pipewire.h b/src/pipewire/pipewire.h index 3a0a1441..9aeb85d5 100644 --- a/src/pipewire/pipewire.h +++ b/src/pipewire/pipewire.h @@ -33,6 +33,7 @@ extern "C" { #include <pipewire/client.h> #include <pipewire/core.h> +#include <pipewire/core-proxy.h> #include <pipewire/device.h> #include <pipewire/interfaces.h> #include <pipewire/introspect.h> @@ -47,7 +48,6 @@ extern "C" { #include <pipewire/port.h> #include <pipewire/properties.h> #include <pipewire/proxy.h> -#include <pipewire/remote.h> #include <pipewire/resource.h> #include <pipewire/stream.h> #include <pipewire/thread-loop.h> diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 1f939def..1a630a74 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -898,8 +898,6 @@ pw_core_find_port(struct pw_core *core, struct spa_pod **format_filters, char **error); -const struct pw_export_type *pw_core_find_export_type(struct pw_core *core, 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 c7776c75..5d27a1e1 100644 --- a/src/pipewire/protocol.c +++ b/src/pipewire/protocol.c @@ -79,6 +79,12 @@ void *pw_protocol_get_user_data(struct pw_protocol *protocol) } SPA_EXPORT +struct pw_core *pw_protocol_get_core(struct pw_protocol *protocol) +{ + return protocol->core; +} + +SPA_EXPORT const struct pw_protocol_implementaton * pw_protocol_get_implementation(struct pw_protocol *protocol) { diff --git a/src/pipewire/protocol.h b/src/pipewire/protocol.h index b35e02af..0ac0012b 100644 --- a/src/pipewire/protocol.h +++ b/src/pipewire/protocol.h @@ -34,6 +34,7 @@ extern "C" { struct pw_protocol; #include <pipewire/core.h> +#include <pipewire/remote.h> #include <pipewire/properties.h> #include <pipewire/utils.h> @@ -44,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); @@ -55,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)) @@ -112,6 +112,8 @@ struct pw_protocol *pw_protocol_new(struct pw_core *core, const char *name, size void pw_protocol_destroy(struct pw_protocol *protocol); +struct pw_core *pw_protocol_get_core(struct pw_protocol *protocol); + void *pw_protocol_get_user_data(struct pw_protocol *protocol); const struct pw_protocol_implementaton * diff --git a/src/pipewire/proxy.c b/src/pipewire/proxy.c index ddcecba1..18f07c8d 100644 --- a/src/pipewire/proxy.c +++ b/src/pipewire/proxy.c @@ -153,6 +153,12 @@ struct pw_protocol *pw_proxy_get_protocol(struct pw_proxy *proxy) } SPA_EXPORT +struct pw_remote *pw_proxy_get_remote(struct pw_proxy *proxy) +{ + return proxy->remote; +} + +SPA_EXPORT void pw_proxy_add_listener(struct pw_proxy *proxy, struct spa_hook *listener, const struct pw_proxy_events *events, diff --git a/src/pipewire/proxy.h b/src/pipewire/proxy.h index 6abea884..d32ec737 100644 --- a/src/pipewire/proxy.h +++ b/src/pipewire/proxy.h @@ -154,6 +154,9 @@ uint32_t pw_proxy_get_id(struct pw_proxy *proxy); /** Get the type and version of the proxy */ uint32_t pw_proxy_get_type(struct pw_proxy *proxy, uint32_t *version); +/** Get the remote managing this proxy */ +struct pw_remote *pw_proxy_get_remote(struct pw_proxy *proxy); + /** Get the protocol used for the proxy */ struct pw_protocol *pw_proxy_get_protocol(struct pw_proxy *proxy); diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index 99d82aaa..5fee398a 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -45,6 +45,7 @@ struct remote { struct pw_remote this; struct spa_hook core_listener; struct spa_hook core_proxy_listener; + size_t user_data_size; }; /** \endcond */ @@ -210,6 +211,7 @@ struct pw_remote *pw_remote_new(struct pw_core *core, pw_log_debug(NAME" %p: new", impl); this->core = core; + impl->user_data_size = user_data_size; if (user_data_size > 0) this->user_data = SPA_MEMBER(impl, sizeof(struct remote), void); @@ -388,11 +390,8 @@ static const struct pw_proxy_events core_proxy_events = { .destroy = core_proxy_destroy, }; -static int -do_connect(struct spa_loop *loop, - bool async, uint32_t seq, const void *data, size_t size, void *user_data) +static int 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_proxy; int res; @@ -400,10 +399,10 @@ do_connect(struct spa_loop *loop, spa_zero(dummy); dummy.remote = remote; - core_proxy = pw_proxy_new(&dummy, PW_TYPE_INTERFACE_Core, PW_VERSION_CORE_PROXY, 0); + core_proxy = pw_proxy_new(&dummy, PW_TYPE_INTERFACE_Core, PW_VERSION_CORE_PROXY, impl->user_data_size); if (core_proxy == NULL) { res = -errno; - goto error_disconnect; + goto error; } remote->core_proxy = (struct pw_core_proxy*)core_proxy; @@ -420,19 +419,27 @@ do_connect(struct spa_loop *loop, pw_core_proxy_hello(remote->core_proxy, PW_VERSION_CORE_PROXY); pw_client_proxy_update_properties(remote->client_proxy, &remote->properties->dict); - pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTED, NULL); return 0; error_clean_core_proxy: ((struct pw_proxy*)remote->core_proxy)->removed = true; pw_proxy_destroy((struct pw_proxy*)remote->core_proxy); -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_proxy * pw_remote_get_core_proxy(struct pw_remote *remote) { @@ -470,12 +477,19 @@ 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) { - pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR, - "connect failed %s", spa_strerror(res)); - return res; - } + if ((res = init_connect(remote)) < 0) + goto error; + + if ((res = pw_protocol_client_connect(remote->conn, + &remote->properties->dict, + done_connect, remote)) < 0) + goto error; + return remote->state == PW_REMOTE_STATE_ERROR ? -EIO : 0; +error: + pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR, + "connect failed %s", spa_strerror(res)); + return res; } SPA_EXPORT @@ -485,15 +499,20 @@ int pw_remote_connect_fd(struct pw_remote *remote, int fd) pw_remote_update_state(remote, PW_REMOTE_STATE_CONNECTING, NULL); - 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; - } + if ((res = init_connect(remote)) < 0) + goto error; + + if ((res = pw_protocol_client_connect_fd(remote->conn, fd, true)) < 0) + goto error; + pw_loop_invoke(remote->core->main_loop, do_connect, 0, NULL, 0, false, remote); return remote->state == PW_REMOTE_STATE_ERROR ? -EIO : 0; +error: + pw_remote_update_state(remote, PW_REMOTE_STATE_ERROR, + "connect_fd failed %s", spa_strerror(res)); + return res; } SPA_EXPORT @@ -537,66 +556,3 @@ int pw_remote_disconnect(struct pw_remote *remote) return 0; } - -SPA_EXPORT -struct pw_proxy *pw_remote_export(struct pw_remote *remote, - uint32_t type, struct pw_properties *props, void *object, - size_t user_data_size) -{ - struct pw_proxy *proxy; - const struct pw_export_type *t; - int res; - - if (remote->core_proxy == NULL) { - res = -ENETDOWN; - goto error_core_proxy; - } - - t = pw_core_find_export_type(remote->core, type); - if (t == NULL) { - res = -EPROTO; - goto error_export_type; - } - - proxy = t->func(remote, type, props, object, user_data_size); - if (proxy == NULL) { - res = -errno; - goto error_proxy_failed; - } - return proxy; - -error_core_proxy: - pw_log_error(NAME" %p: no core proxy: %s", remote, spa_strerror(res)); - goto exit_free; -error_export_type: - pw_log_error(NAME" %p: can't export type %d: %s", remote, type, spa_strerror(res)); - goto exit_free; -error_proxy_failed: - pw_log_error(NAME" %p: failed to create proxy: %s", remote, spa_strerror(res)); - goto exit; -exit_free: - if (props) - pw_properties_free(props); -exit: - errno = -res; - return NULL; -} - -SPA_EXPORT -int pw_core_register_export_type(struct pw_core *core, struct pw_export_type *type) -{ - pw_log_debug("core %p: Add export type %d/%s to core", core, type->type, - spa_debug_type_find_name(pw_type_info(), type->type)); - spa_list_append(&core->export_list, &type->link); - return 0; -} - -const struct pw_export_type *pw_core_find_export_type(struct pw_core *core, uint32_t type) -{ - const struct pw_export_type *t; - spa_list_for_each(t, &core->export_list, link) { - if (t->type == type) - return t; - } - return NULL; -} diff --git a/src/pipewire/remote.h b/src/pipewire/remote.h index d35bb0bd..873f25fc 100644 --- a/src/pipewire/remote.h +++ b/src/pipewire/remote.h @@ -196,26 +196,6 @@ struct pw_proxy *pw_remote_find_proxy(struct pw_remote *remote, uint32_t id); /** Disconnect from the remote PipeWire. \memberof pw_remote */ int pw_remote_disconnect(struct pw_remote *remote); -/** run a local node in a remote graph */ -struct pw_proxy *pw_remote_export(struct pw_remote *remote, /**< the remote */ - uint32_t type, /**< the type of object */ - struct pw_properties *properties, /**< extra properties */ - void *object, /**< object to export */ - size_t user_data_size /**< extra user data */); - -/** data for registering export functions */ -struct pw_export_type { - struct spa_list link; - uint32_t type; - struct pw_proxy * (*func) (struct pw_remote *remote, - uint32_t type, struct pw_properties *properties, void *object, - size_t user_data_size); -}; - -/** register a type that can be exported on a remote. This is usually used by - * extension modules */ -int pw_core_register_export_type(struct pw_core *core, struct pw_export_type *type); - #ifdef __cplusplus } #endif diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index b5a2caf3..6b06f154 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -1052,7 +1052,7 @@ static int handle_connect(struct pw_stream *stream) } pw_log_debug(NAME" %p: export node %p", stream, impl->node); - stream->proxy = pw_remote_export(stream->remote, + stream->proxy = pw_core_proxy_export(stream->remote->core_proxy, PW_TYPE_INTERFACE_Node, NULL, impl->node, 0); if (stream->proxy == NULL) { res = -errno; @@ -1105,8 +1105,8 @@ static const struct pw_remote_events remote_events = { .state_changed = on_remote_state_changed, }; -SPA_EXPORT -struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name, +static struct pw_stream * +stream_new(struct pw_remote *remote, const char *name, struct pw_properties *props) { struct stream *impl; @@ -1178,6 +1178,14 @@ error_cleanup: } SPA_EXPORT +struct pw_stream * pw_stream_new(struct pw_core_proxy *core, const char *name, + struct pw_properties *props) +{ + struct pw_remote *remote = ((struct pw_proxy*)core)->remote; + return stream_new(remote, name, props); +} + +SPA_EXPORT struct pw_stream * pw_stream_new_simple(struct pw_loop *loop, const char *name, @@ -1194,7 +1202,7 @@ pw_stream_new_simple(struct pw_loop *loop, core = pw_core_new(loop, NULL, 0); remote = pw_remote_new(core, NULL, 0); - stream = pw_stream_new(remote, name, props); + stream = stream_new(remote, name, props); if (stream == NULL) { res = -errno; goto error_cleanup; @@ -1316,9 +1324,9 @@ 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_proxy *pw_stream_get_core_proxy(struct pw_stream *stream) { - return stream->remote; + return stream->remote->core_proxy; } static void add_params(struct stream *impl) diff --git a/src/pipewire/stream.h b/src/pipewire/stream.h index 75ab4f58..88e46573 100644 --- a/src/pipewire/stream.h +++ b/src/pipewire/stream.h @@ -48,7 +48,7 @@ extern "C" { * * For more complicated nodes such as filters or ports with multiple * inputs and/or outputs you will need to use the pw_filter or make - * a pw_node yourself and export it with \ref pw_remote_export. + * a pw_node yourself and export it with \ref pw_core_proxy_export. * * \section sec_create Create * @@ -152,7 +152,7 @@ struct pw_stream; #include <spa/buffer/buffer.h> #include <spa/param/param.h> -#include <pipewire/remote.h> +#include <pipewire/pipewire.h> /** \enum pw_stream_state The state of a stream \memberof pw_stream */ enum pw_stream_state { @@ -247,10 +247,11 @@ 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_proxy *core, /**< a \ref pw_core_proxy */ const char *name, /**< a stream media name */ struct pw_properties *props /**< stream properties, ownership is taken */); + struct pw_stream * pw_stream_new_simple(struct pw_loop *loop, /**< a \ref pw_loop to use */ const char *name, /**< a stream media name */ @@ -270,7 +271,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_proxy *pw_stream_get_core_proxy(struct pw_stream *stream); const struct pw_properties *pw_stream_get_properties(struct pw_stream *stream); diff --git a/src/tests/test-stream.c b/src/tests/test-stream.c index bc73d75b..4ba025bf 100644 --- a/src/tests/test-stream.c +++ b/src/tests/test-stream.c @@ -134,7 +134,7 @@ static void test_create(void) { struct pw_main_loop *loop; struct pw_core *core; - struct pw_remote *remote; + struct pw_core_proxy *proxy; struct pw_stream *stream; struct pw_stream_events stream_events = stream_events_error; struct spa_hook listener = { 0, }; @@ -143,8 +143,8 @@ static void test_create(void) loop = pw_main_loop_new(NULL); core = pw_core_new(pw_main_loop_get_loop(loop), NULL, 12); - remote = pw_remote_new(core, NULL, 12); - stream = pw_stream_new(remote, "test", NULL); + proxy = pw_core_connect(core, NULL, 0); + stream = pw_stream_new(proxy, "test", NULL); spa_assert(stream != NULL); pw_stream_add_listener(stream, &listener, &stream_events, stream); @@ -154,7 +154,7 @@ static void test_create(void) /* check name */ spa_assert(!strcmp(pw_stream_get_name(stream), "test")); /* check remote */ - spa_assert(pw_stream_get_remote(stream) == remote); + spa_assert(pw_stream_get_core_proxy(stream) == proxy); /* check id, only when connected */ spa_assert(pw_stream_get_node_id(stream) == SPA_ID_INVALID); @@ -183,8 +183,8 @@ static void test_properties(void) { struct pw_main_loop *loop; struct pw_core *core; + struct pw_core_proxy *proxy; 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, }; @@ -192,8 +192,8 @@ static void test_properties(void) loop = pw_main_loop_new(NULL); core = pw_core_new(pw_main_loop_get_loop(loop), NULL, 0); - remote = pw_remote_new(core, NULL, 0); - stream = pw_stream_new(remote, "test", + proxy = pw_core_connect(core, NULL, 0); + stream = pw_stream_new(proxy, "test", pw_properties_new("foo", "bar", "biz", "fuzz", NULL)); diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c index 4b880f2c..9c360c9e 100644 --- a/src/tools/pipewire-cli.c +++ b/src/tools/pipewire-cli.c @@ -28,6 +28,7 @@ #include <signal.h> #include <string.h> +#include <spa/utils/result.h> #include <spa/debug/pod.h> #include <spa/debug/format.h> @@ -71,12 +72,11 @@ struct remote_data { char *name; uint32_t id; - struct pw_remote *remote; - struct spa_hook remote_listener; int prompt_pending; struct pw_core_proxy *core_proxy; struct spa_hook core_listener; + struct spa_hook core_proxy_listener; struct pw_registry_proxy *registry_proxy; struct spa_hook registry_listener; @@ -370,71 +370,51 @@ static const struct pw_registry_proxy_events registry_events = { .global_remove = registry_event_global_remove, }; -static void on_remote_destroy(void *_data) +static void on_core_error(void *_data, uint32_t id, int seq, int res, const char *message) { 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); + pw_log_error("remote %p: error id:%u seq:%d res:%d (%s): %s", rd, + id, seq, res, spa_strerror(res), message); - if (data->current == rd) - data->current = NULL; - free(rd->name); + if (id == 0) { + pw_main_loop_quit(data->loop); + } } static const struct pw_core_proxy_events remote_core_events = { - PW_VERSION_CORE_EVENTS, + PW_VERSION_CORE_PROXY_EVENTS, .info = on_core_info, .done = on_core_done, + .error = on_core_error, }; -static void on_state_changed(void *_data, enum pw_remote_state old, - enum pw_remote_state state, const char *error) +static void on_core_destroy(void *_data) { 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; + spa_list_remove(&rd->link); - case PW_REMOTE_STATE_CONNECTED: - fprintf(stdout, "remote %d state: \"%s\"\n", rd->id, pw_remote_state_as_string(state)); - rd->core_proxy = pw_remote_get_core_proxy(rd->remote); - pw_core_proxy_add_listener(rd->core_proxy, - &rd->core_listener, - &remote_core_events, rd); - rd->registry_proxy = pw_core_proxy_get_registry(rd->core_proxy, - PW_VERSION_REGISTRY_PROXY, 0); - pw_registry_proxy_add_listener(rd->registry_proxy, - &rd->registry_listener, - ®istry_events, rd); - rd->prompt_pending = pw_core_proxy_sync(rd->core_proxy, 0, 0); - break; + pw_map_remove(&data->vars, rd->id); + pw_map_for_each(&rd->globals, destroy_global, rd); - default: - fprintf(stdout, "remote %d state: \"%s\"\n", rd->id, pw_remote_state_as_string(state)); - break; - } + if (data->current == rd) + data->current = NULL; + free(rd->name); } -static const struct pw_remote_events remote_events = { - PW_VERSION_REMOTE_EVENTS, - .destroy = on_remote_destroy, - .state_changed = on_state_changed, +static const struct pw_proxy_events core_proxy_events = { + PW_VERSION_PROXY_EVENTS, + .destroy = on_core_destroy, }; - 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_core_proxy *core; struct pw_properties *props = NULL; struct remote_data *rd; @@ -442,21 +422,30 @@ static bool do_connect(struct data *data, const char *cmd, char *args, char **er 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)); + core = pw_core_connect(data->core, props, sizeof(struct remote_data)); - rd = pw_remote_get_user_data(remote); - rd->remote = remote; + rd = pw_proxy_get_user_data((struct pw_proxy*)core); + rd->core_proxy = 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 = @remote:%p\n", rd->id, remote); + fprintf(stdout, "%d = @core_proxy:%p\n", rd->id, core); data->current = rd; - pw_remote_add_listener(remote, &rd->remote_listener, &remote_events, rd); - if (pw_remote_connect(remote) < 0) - return false; + pw_core_proxy_add_listener(rd->core_proxy, + &rd->core_listener, + &remote_core_events, rd); + pw_proxy_add_listener((struct pw_proxy*)rd->core_proxy, + &rd->core_proxy_listener, + &core_proxy_events, rd); + rd->registry_proxy = pw_core_proxy_get_registry(rd->core_proxy, + PW_VERSION_REGISTRY_PROXY, 0); + pw_registry_proxy_add_listener(rd->registry_proxy, + &rd->registry_listener, + ®istry_events, rd); + rd->prompt_pending = pw_core_proxy_sync(rd->core_proxy, 0, 0); return true; } @@ -476,8 +465,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_proxy_disconnect(rd->core_proxy); if (data->current == NULL) { if (spa_list_is_empty(&data->remotes)) { @@ -498,7 +486,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_proxy:%p '%s'\n", rd->id, rd->core_proxy, rd->name); return true; } @@ -1428,7 +1416,7 @@ static bool do_export_node(struct data *data, const char *cmd, char *args, char return false; } node = pw_global_get_object(global); - proxy = pw_remote_export(rd->remote, PW_TYPE_INTERFACE_Node, NULL, node, 0); + proxy = pw_core_proxy_export(rd->core_proxy, PW_TYPE_INTERFACE_Node, NULL, node, 0); id = pw_map_insert_new(&data->vars, proxy); fprintf(stdout, "%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy)); diff --git a/src/tools/pipewire-dot.c b/src/tools/pipewire-dot.c index ebd121d2..2d1568a8 100644 --- a/src/tools/pipewire-dot.c +++ b/src/tools/pipewire-dot.c @@ -26,13 +26,13 @@ #include <signal.h> #include <getopt.h> +#include <spa/utils/result.h> #include <spa/debug/pod.h> #include <spa/debug/format.h> #include <spa/debug/types.h> #include <pipewire/interfaces.h> #include <pipewire/type.h> -#include <pipewire/remote.h> #include <pipewire/main-loop.h> #include <pipewire/pipewire.h> @@ -48,9 +48,6 @@ struct data { struct pw_main_loop *loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; - struct pw_core_proxy *core_proxy; struct spa_hook core_listener; @@ -711,42 +708,21 @@ static void on_core_done(void *data, uint32_t id, int seq) pw_main_loop_quit(d->loop); } -static const struct pw_core_proxy_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_proxy = pw_remote_get_core_proxy(data->remote); - pw_core_proxy_add_listener(data->core_proxy, - &data->core_listener, - &core_events, data); - data->registry_proxy = pw_core_proxy_get_registry(data->core_proxy, - PW_VERSION_REGISTRY_PROXY, 0); - pw_registry_proxy_add_listener(data->registry_proxy, - &data->registry_listener, - ®istry_events, data); - break; + struct data *d = data; - default: - break; + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, 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_proxy_events core_events = { + PW_VERSION_CORE_PROXY_EVENTS, + .done = on_core_done, + .error = on_core_error, }; static void do_quit(void *data, int signal_number) @@ -843,26 +819,27 @@ int main(int argc, char *argv[]) if (remote_name) props = pw_properties_new(PW_KEY_REMOTE_NAME, remote_name, NULL); - data.remote = pw_remote_new(data.core, 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) + spa_list_init(&data.globals); + + data.core_proxy = pw_core_connect(data.core, props, 0); + if (data.core_proxy == NULL) return -1; - spa_list_init(&data.globals); + pw_core_proxy_add_listener(data.core_proxy, + &data.core_listener, + &core_events, &data); + data.registry_proxy = pw_core_proxy_get_registry(data.core_proxy, + PW_VERSION_REGISTRY_PROXY, 0); + pw_registry_proxy_add_listener(data.registry_proxy, + &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_core_destroy(data.core); pw_main_loop_destroy(data.loop); diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c index 822dae0d..39dc2a99 100644 --- a/src/tools/pipewire-monitor.c +++ b/src/tools/pipewire-monitor.c @@ -25,13 +25,13 @@ #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> #include <pipewire/interfaces.h> #include <pipewire/type.h> -#include <pipewire/remote.h> #include <pipewire/main-loop.h> #include <pipewire/pipewire.h> @@ -50,9 +50,6 @@ struct data { struct pw_main_loop *loop; struct pw_core *core; - struct pw_remote *remote; - struct spa_hook remote_listener; - struct pw_core_proxy *core_proxy; struct spa_hook core_listener; @@ -670,46 +667,23 @@ static const struct pw_registry_proxy_events registry_events = { .global_remove = registry_event_global_remove, }; -static const struct pw_core_proxy_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) +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; + struct data *d = data; - case PW_REMOTE_STATE_CONNECTED: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - - data->core_proxy = pw_remote_get_core_proxy(data->remote); - pw_core_proxy_add_listener(data->core_proxy, - &data->core_listener, - &core_events, data); - data->registry_proxy = pw_core_proxy_get_registry(data->core_proxy, - PW_VERSION_REGISTRY_PROXY, 0); - pw_registry_proxy_add_listener(data->registry_proxy, - &data->registry_listener, - ®istry_events, data); - break; + pw_log_error("error id:%u seq:%d res:%d (%s): %s", + id, seq, res, spa_strerror(res), message); - default: - printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); - break; + 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_proxy_events core_events = { + PW_VERSION_CORE_EVENTS, + .info = on_core_info, + .done = on_core_done, + .error = on_core_error, }; static void do_quit(void *data, int signal_number) @@ -741,19 +715,23 @@ int main(int argc, char *argv[]) if (argc > 1) props = pw_properties_new(PW_KEY_REMOTE_NAME, argv[1], NULL); - data.remote = pw_remote_new(data.core, props, 0); - if (data.remote == NULL) - return -1; + spa_list_init(&data.pending_list); - pw_remote_add_listener(data.remote, &data.remote_listener, &remote_events, &data); - if (pw_remote_connect(data.remote) < 0) + data.core_proxy = pw_core_connect(data.core, props, 0); + if (data.core_proxy == NULL) return -1; - spa_list_init(&data.pending_list); + pw_core_proxy_add_listener(data.core_proxy, + &data.core_listener, + &core_events, &data); + data.registry_proxy = pw_core_proxy_get_registry(data.core_proxy, + PW_VERSION_REGISTRY_PROXY, 0); + pw_registry_proxy_add_listener(data.registry_proxy, + &data.registry_listener, + ®istry_events, &data); pw_main_loop_run(data.loop); - pw_remote_destroy(data.remote); pw_core_destroy(data.core); pw_main_loop_destroy(data.loop); |