diff --git a/src/extensions/session-manager/impl-interfaces.h b/src/extensions/session-manager/impl-interfaces.h index 66daa0b99..fd1e1e039 100644 --- a/src/extensions/session-manager/impl-interfaces.h +++ b/src/extensions/session-manager/impl-interfaces.h @@ -65,7 +65,7 @@ struct pw_client_endpoint_proxy_events { * -EINVAL when the id has already been set * -ENOTSUP on the server-side endpoint implementation */ - int (*set_id) (void *endpoint, uint32_t id); + int (*set_id) (void *object, uint32_t id); /** * Sets the session id of the \a endpoint. @@ -82,7 +82,7 @@ struct pw_client_endpoint_proxy_events { * -EINVAL when the session id has already been set * -ENOTSUP when the endpoint is a session master */ - int (*set_session_id) (void *endpoint, uint32_t session_id); + int (*set_session_id) (void *object, uint32_t session_id); /** * Set the configurable parameter in \a endpoint. @@ -105,7 +105,7 @@ struct pw_client_endpoint_proxy_events { * -ENOTSUP when there are no parameters implemented on \a endpoint * -ENOENT the parameter is unknown */ - int (*set_param) (void *endpoint, + int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); @@ -129,7 +129,7 @@ struct pw_client_endpoint_proxy_events { * -ESRCH when the type or size of a property is not correct. * -ENOENT when the param id is not found */ - int (*stream_set_param) (void *endpoint, uint32_t stream_id, + int (*stream_set_param) (void *object, uint32_t stream_id, uint32_t id, uint32_t flags, const struct spa_pod *param); }; @@ -215,7 +215,7 @@ struct pw_client_session_proxy_events { * -EINVAL when the id has already been set * -ENOTSUP on the server-side session implementation */ - int (*set_id) (void *session, uint32_t id); + int (*set_id) (void *object, uint32_t id); /** * Set the configurable parameter in \a session. @@ -238,7 +238,7 @@ struct pw_client_session_proxy_events { * -ENOTSUP when there are no parameters implemented on \a session * -ENOENT the parameter is unknown */ - int (*set_param) (void *session, + int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); @@ -262,15 +262,15 @@ struct pw_client_session_proxy_events { * -ESRCH when the type or size of a property is not correct. * -ENOENT when the param id is not found */ - int (*link_set_param) (void *session, uint32_t link_id, + int (*link_set_param) (void *object, uint32_t link_id, uint32_t id, uint32_t flags, const struct spa_pod *param); - int (*create_link) (void *session, const struct spa_dict *props); + int (*create_link) (void *object, const struct spa_dict *props); - int (*destroy_link) (void *session, uint32_t link_id); + int (*destroy_link) (void *object, uint32_t link_id); - int (*link_request_state) (void *session, uint32_t link_id, uint32_t state); + int (*link_request_state) (void *object, uint32_t link_id, uint32_t state); }; #define PW_CLIENT_SESSION_PROXY_METHOD_ADD_LISTENER 0 diff --git a/src/modules/module-session-manager/client-endpoint.c b/src/modules/module-session-manager/client-endpoint.c index 2e092518b..0e501c9fd 100644 --- a/src/modules/module-session-manager/client-endpoint.c +++ b/src/modules/module-session-manager/client-endpoint.c @@ -251,7 +251,7 @@ int client_endpoint_factory_init(struct pw_module *module) factory = pw_factory_new(core, "client-endpoint", - PW_TYPE_INTERFACE_Endpoint, + PW_TYPE_INTERFACE_ClientEndpoint, PW_VERSION_CLIENT_ENDPOINT_PROXY, NULL, sizeof(*data)); diff --git a/src/modules/module-session-manager/client-session.c b/src/modules/module-session-manager/client-session.c index 91e56fc06..9b20d8335 100644 --- a/src/modules/module-session-manager/client-session.c +++ b/src/modules/module-session-manager/client-session.c @@ -251,7 +251,7 @@ int client_session_factory_init(struct pw_module *module) factory = pw_factory_new(core, "client-session", - PW_TYPE_INTERFACE_Session, + PW_TYPE_INTERFACE_ClientSession, PW_VERSION_CLIENT_SESSION_PROXY, NULL, sizeof(*data)); diff --git a/src/modules/module-session-manager/endpoint-stream.c b/src/modules/module-session-manager/endpoint-stream.c index 47d2a4ea0..15995827e 100644 --- a/src/modules/module-session-manager/endpoint-stream.c +++ b/src/modules/module-session-manager/endpoint-stream.c @@ -208,7 +208,7 @@ int endpoint_stream_update(struct endpoint_stream *this, } if (!this->info.name) - this->info.name = strdup(info->name); + this->info.name = info->name ? strdup(info->name) : NULL; this->info.change_mask = info->change_mask; spa_list_for_each(resource, &this->global->resource_list, link) { diff --git a/src/modules/module-session-manager/endpoint.c b/src/modules/module-session-manager/endpoint.c index 0866e71d2..8f53429d0 100644 --- a/src/modules/module-session-manager/endpoint.c +++ b/src/modules/module-session-manager/endpoint.c @@ -286,6 +286,7 @@ int endpoint_init(struct endpoint *this, const char *keys[] = { PW_KEY_FACTORY_ID, PW_KEY_CLIENT_ID, + PW_KEY_DEVICE_ID, NULL }; diff --git a/src/modules/module-session-manager/protocol-native.c b/src/modules/module-session-manager/protocol-native.c index c0b14ca9c..f34f87244 100644 --- a/src/modules/module-session-manager/protocol-native.c +++ b/src/modules/module-session-manager/protocol-native.c @@ -144,8 +144,6 @@ do { \ SPA_POD_Int(&version), \ SPA_POD_Int(&(info)->id), \ SPA_POD_Int(&(info)->change_mask), \ - SPA_POD_Int(&(info)->n_params), \ - SPA_POD_Int(&(info)->props->n_items), \ NULL) < 0) \ return -EINVAL; \ \ @@ -314,7 +312,8 @@ static int client_endpoint_marshal_set_id (void *object, uint32_t id) b = pw_protocol_native_begin_resource(resource, PW_CLIENT_ENDPOINT_PROXY_EVENT_SET_ID, NULL); - spa_pod_builder_add (b, SPA_POD_Int(id), NULL); + spa_pod_builder_add_struct(b, + SPA_POD_Int(id)); return pw_protocol_native_end_resource(resource, b); } @@ -327,7 +326,8 @@ static int client_endpoint_marshal_set_session_id (void *object, uint32_t id) b = pw_protocol_native_begin_resource(resource, PW_CLIENT_ENDPOINT_PROXY_EVENT_SET_SESSION_ID, NULL); - spa_pod_builder_add (b, SPA_POD_Int(id), NULL); + spa_pod_builder_add_struct(b, + SPA_POD_Int(id)); return pw_protocol_native_end_resource(resource, b); } @@ -573,7 +573,7 @@ static int client_endpoint_demarshal_stream_update(void *object, spa_pod_parser_init(&prs[0], msg->data, msg->size); if (spa_pod_parser_push_struct(&prs[0], &f[0]) < 0 || spa_pod_parser_get(&prs[0], - SPA_POD_Int(&stream_id), + SPA_POD_Int(&stream_id), SPA_POD_Int(&change_mask), SPA_POD_Int(&n_params), NULL) < 0) return -EINVAL; @@ -630,9 +630,9 @@ pw_protocol_native_client_endpoint_method_demarshal[PW_CLIENT_ENDPOINT_PROXY_MET }; static const struct pw_protocol_marshal pw_protocol_native_client_endpoint_marshal = { - PW_TYPE_INTERFACE_Endpoint, + PW_TYPE_INTERFACE_ClientEndpoint, PW_VERSION_CLIENT_ENDPOINT_PROXY, - PW_PROTOCOL_MARSHAL_FLAG_IMPL, + 0, PW_CLIENT_ENDPOINT_PROXY_METHOD_NUM, PW_CLIENT_ENDPOINT_PROXY_EVENT_NUM, &pw_protocol_native_client_endpoint_method_marshal, @@ -653,7 +653,8 @@ static int client_session_marshal_set_id (void *object, uint32_t id) b = pw_protocol_native_begin_resource(resource, PW_CLIENT_SESSION_PROXY_EVENT_SET_ID, NULL); - spa_pod_builder_add (b, SPA_POD_Int(id), NULL); + spa_pod_builder_add_struct(b, + SPA_POD_Int(id)); return pw_protocol_native_end_resource(resource, b); } @@ -719,7 +720,8 @@ static int client_session_marshal_destroy_link (void *object, uint32_t link_id) b = pw_protocol_native_begin_resource(resource, PW_CLIENT_SESSION_PROXY_EVENT_DESTROY_LINK, NULL); - spa_pod_builder_add(b, SPA_POD_Int(link_id), NULL); + spa_pod_builder_add_struct(b, + SPA_POD_Int(link_id)); return pw_protocol_native_end_resource(resource, b); } @@ -1037,9 +1039,9 @@ pw_protocol_native_client_session_method_demarshal[PW_CLIENT_SESSION_PROXY_METHO }; static const struct pw_protocol_marshal pw_protocol_native_client_session_marshal = { - PW_TYPE_INTERFACE_Session, + PW_TYPE_INTERFACE_ClientSession, PW_VERSION_CLIENT_SESSION_PROXY, - PW_PROTOCOL_MARSHAL_FLAG_IMPL, + 0, PW_CLIENT_SESSION_PROXY_METHOD_NUM, PW_CLIENT_SESSION_PROXY_EVENT_NUM, &pw_protocol_native_client_session_method_marshal, diff --git a/src/pipewire/pipewire.c b/src/pipewire/pipewire.c index d36132b0c..79cd6a0a1 100644 --- a/src/pipewire/pipewire.c +++ b/src/pipewire/pipewire.c @@ -579,7 +579,9 @@ static const struct spa_type_info type_info[] = { { PW_TYPE_INTERFACE_ClientNode, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "ClientNode", NULL }, { PW_TYPE_INTERFACE_Metadata, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "Metadata", NULL }, { PW_TYPE_INTERFACE_Session, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "Session", NULL}, + { PW_TYPE_INTERFACE_ClientSession, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "ClientSession", NULL}, { PW_TYPE_INTERFACE_Endpoint, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "Endpoint", NULL}, + { PW_TYPE_INTERFACE_ClientEndpoint, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "ClientEndpoint", NULL}, { PW_TYPE_INTERFACE_EndpointStream, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "EndpointStream", NULL}, { PW_TYPE_INTERFACE_EndpointLink, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "EndpointLink", NULL}, { SPA_ID_INVALID, SPA_ID_INVALID, "spa_types", spa_types }, diff --git a/src/pipewire/type.h b/src/pipewire/type.h index 641332d56..a6c7a912d 100644 --- a/src/pipewire/type.h +++ b/src/pipewire/type.h @@ -50,7 +50,9 @@ enum { PW_TYPE_INTERFACE_ClientNode, PW_TYPE_INTERFACE_Metadata, PW_TYPE_INTERFACE_Session, + PW_TYPE_INTERFACE_ClientSession, PW_TYPE_INTERFACE_Endpoint, + PW_TYPE_INTERFACE_ClientEndpoint, PW_TYPE_INTERFACE_EndpointStream, PW_TYPE_INTERFACE_EndpointLink, }; diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c index 5f57dbd79..5a1bb5d10 100644 --- a/src/tools/pipewire-cli.c +++ b/src/tools/pipewire-cli.c @@ -269,7 +269,7 @@ static void on_core_info(void *_data, const struct pw_core_info *info) { struct remote_data *rd = _data; free(rd->name); - rd->name = strdup(info->name); + rd->name = info->name ? strdup(info->name) : NULL; fprintf(stdout, "remote %d is named '%s'\n", rd->id, rd->name); } @@ -659,6 +659,16 @@ static void info_device(struct proxy_data *pd) info->change_mask = 0; } +static void info_session(struct proxy_data *pd) +{ + struct pw_session_info *info = pd->info; + + info_global(pd); + print_properties(info->props, MARK_CHANGE(0), true); + print_params(info->params, info->n_params, MARK_CHANGE(1), true); + info->change_mask = 0; +} + static void info_endpoint(struct proxy_data *pd) { struct pw_endpoint_info *info = pd->info; @@ -693,6 +703,19 @@ static void info_endpoint(struct proxy_data *pd) info->change_mask = 0; } +static void info_endpoint_stream(struct proxy_data *pd) +{ + struct pw_endpoint_stream_info *info = pd->info; + + info_global(pd); + fprintf(stdout, "\tid: %u\n", info->id); + fprintf(stdout, "\tendpoint-id: %u\n", info->endpoint_id); + fprintf(stdout, "\tname: %s\n", info->name); + print_properties(info->props, MARK_CHANGE(1), true); + print_params(info->params, info->n_params, MARK_CHANGE(2), true); + info->change_mask = 0; +} + static void core_event_info(void *object, const struct pw_core_info *info) { struct proxy_data *pd = object; @@ -894,6 +917,53 @@ static const struct pw_device_proxy_events device_events = { .param = event_param }; +static void session_info_free(struct pw_session_info *info) +{ + free(info->params); + if (info->props) + pw_properties_free ((struct pw_properties *)info->props); + free(info); +} + +static void session_event_info(void *object, + const struct pw_session_info *update) +{ + struct proxy_data *pd = object; + struct remote_data *rd = pd->rd; + struct pw_session_info *info = pd->info; + + if (!info) { + info = pd->info = calloc(1, sizeof(*info)); + info->id = update->id; + } + if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PARAMS) { + info->n_params = update->n_params; + free(info->params); + info->params = malloc(info->n_params * sizeof(struct spa_param_info)); + memcpy(info->params, update->params, + info->n_params * sizeof(struct spa_param_info)); + } + if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PROPS) { + if (info->props) + pw_properties_free ((struct pw_properties *)info->props); + info->props = + (struct spa_dict *) pw_properties_new_dict (update->props); + } + + if (pd->global == NULL) + pd->global = pw_map_lookup(&rd->globals, info->id); + if (pd->global && pd->global->info_pending) { + info_session(pd); + pd->global->info_pending = false; + } +} + +static const struct pw_session_proxy_events session_events = { + PW_VERSION_SESSION_PROXY_EVENTS, + .info = session_event_info, + .param = event_param +}; + static void endpoint_info_free(struct pw_endpoint_info *info) { free(info->name); @@ -914,8 +984,8 @@ static void endpoint_event_info(void *object, if (!info) { info = pd->info = calloc(1, sizeof(*info)); info->id = update->id; - info->name = strdup(update->name); - info->media_class = strdup(update->media_class); + info->name = update->name ? strdup(update->name) : NULL; + info->media_class = update->media_class ? strdup(update->media_class) : NULL; info->direction = update->direction; info->flags = update->flags; } @@ -951,6 +1021,56 @@ static const struct pw_endpoint_proxy_events endpoint_events = { .param = event_param }; +static void endpoint_stream_info_free(struct pw_endpoint_stream_info *info) +{ + free(info->name); + free(info->params); + if (info->props) + pw_properties_free ((struct pw_properties *)info->props); + free(info); +} + +static void endpoint_stream_event_info(void *object, + const struct pw_endpoint_stream_info *update) +{ + struct proxy_data *pd = object; + struct remote_data *rd = pd->rd; + struct pw_endpoint_stream_info *info = pd->info; + + if (!info) { + info = pd->info = calloc(1, sizeof(*info)); + info->id = update->id; + info->endpoint_id = update->endpoint_id; + info->name = update->name ? strdup(update->name) : NULL; + } + if (update->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PARAMS) { + info->n_params = update->n_params; + free(info->params); + info->params = malloc(info->n_params * sizeof(struct spa_param_info)); + memcpy(info->params, update->params, + info->n_params * sizeof(struct spa_param_info)); + } + if (update->change_mask & PW_ENDPOINT_STREAM_CHANGE_MASK_PROPS) { + if (info->props) + pw_properties_free ((struct pw_properties *)info->props); + info->props = + (struct spa_dict *) pw_properties_new_dict (update->props); + } + + if (pd->global == NULL) + pd->global = pw_map_lookup(&rd->globals, info->id); + if (pd->global && pd->global->info_pending) { + info_endpoint_stream(pd); + pd->global->info_pending = false; + } +} + +static const struct pw_endpoint_stream_proxy_events endpoint_stream_events = { + PW_VERSION_ENDPOINT_STREAM_PROXY_EVENTS, + .info = endpoint_stream_event_info, + .param = event_param +}; + static void destroy_proxy (void *data) { @@ -1037,12 +1157,24 @@ static bool bind_global(struct remote_data *rd, struct global *global, char **er destroy = (pw_destroy_t) pw_link_info_free; info_func = info_link; break; + case PW_TYPE_INTERFACE_Session: + events = &session_events; + client_version = PW_VERSION_SESSION_PROXY; + destroy = (pw_destroy_t) session_info_free; + info_func = info_session; + break; case PW_TYPE_INTERFACE_Endpoint: events = &endpoint_events; client_version = PW_VERSION_ENDPOINT_PROXY; destroy = (pw_destroy_t) endpoint_info_free; info_func = info_endpoint; break; + case PW_TYPE_INTERFACE_EndpointStream: + events = &endpoint_stream_events; + client_version = PW_VERSION_ENDPOINT_STREAM_PROXY; + destroy = (pw_destroy_t) endpoint_stream_info_free; + info_func = info_endpoint_stream; + break; default: asprintf(error, "unsupported type %s", spa_debug_type_find_name(pw_type_info(), global->type)); return false;