mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	pulse-server: make separate index
Separate the id (the pipewire object id) from the index (what we send to the client to identify the objects).
This commit is contained in:
		
							parent
							
								
									955e4287ab
								
							
						
					
					
						commit
						0904a35ba8
					
				
					 19 changed files with 235 additions and 210 deletions
				
			
		| 
						 | 
					@ -308,8 +308,8 @@ static bool drop_from_out_queue(struct client *client, struct message *m)
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* returns true if an event with the (mask, event, id) triplet should be dropped because it is redundant */
 | 
					/* returns true if an event with the (mask, event, index) triplet should be dropped because it is redundant */
 | 
				
			||||||
static bool client_prune_subscribe_events(struct client *client, uint32_t mask, uint32_t event, uint32_t id)
 | 
					static bool client_prune_subscribe_events(struct client *client, uint32_t mask, uint32_t event, uint32_t index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct message *m, *t;
 | 
						struct message *m, *t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -322,7 +322,7 @@ static bool client_prune_subscribe_events(struct client *client, uint32_t mask,
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if ((m->extra[1] ^ event) & SUBSCRIPTION_EVENT_FACILITY_MASK)
 | 
							if ((m->extra[1] ^ event) & SUBSCRIPTION_EVENT_FACILITY_MASK)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (m->extra[2] != id)
 | 
							if (m->extra[2] != index)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((event & SUBSCRIPTION_EVENT_TYPE_MASK) == SUBSCRIPTION_EVENT_REMOVE) {
 | 
							if ((event & SUBSCRIPTION_EVENT_TYPE_MASK) == SUBSCRIPTION_EVENT_REMOVE) {
 | 
				
			||||||
| 
						 | 
					@ -334,7 +334,7 @@ static bool client_prune_subscribe_events(struct client *client, uint32_t mask,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (drop_from_out_queue(client, m)) {
 | 
								if (drop_from_out_queue(client, m)) {
 | 
				
			||||||
				pw_log_debug("client %p: dropped redundant event due to remove event for object %u",
 | 
									pw_log_debug("client %p: dropped redundant event due to remove event for object %u",
 | 
				
			||||||
					     client, id);
 | 
										     client, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				/* if the NEW event for the current object could successfully be dropped,
 | 
									/* if the NEW event for the current object could successfully be dropped,
 | 
				
			||||||
				   there is no need to deliver the REMOVE event */
 | 
									   there is no need to deliver the REMOVE event */
 | 
				
			||||||
| 
						 | 
					@ -357,12 +357,12 @@ static bool client_prune_subscribe_events(struct client *client, uint32_t mask,
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
drop:
 | 
					drop:
 | 
				
			||||||
	pw_log_debug("client %p: dropped redundant event for object %u", client, id);
 | 
						pw_log_debug("client %p: dropped redundant event for object %u", client, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int client_queue_subscribe_event(struct client *client, uint32_t mask, uint32_t event, uint32_t id)
 | 
					int client_queue_subscribe_event(struct client *client, uint32_t mask, uint32_t event, uint32_t index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (client->disconnect)
 | 
						if (client->disconnect)
 | 
				
			||||||
		return -ENOTCONN;
 | 
							return -ENOTCONN;
 | 
				
			||||||
| 
						 | 
					@ -370,21 +370,21 @@ int client_queue_subscribe_event(struct client *client, uint32_t mask, uint32_t
 | 
				
			||||||
	if (!(client->subscribed & mask))
 | 
						if (!(client->subscribed & mask))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_debug("client %p: SUBSCRIBE event:%08x id:%u", client, event, id);
 | 
						pw_log_debug("client %p: SUBSCRIBE event:%08x index:%u", client, event, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (client_prune_subscribe_events(client, mask, event, id))
 | 
						if (client_prune_subscribe_events(client, mask, event, index))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct message *reply = message_alloc(client->impl, -1, 0);
 | 
						struct message *reply = message_alloc(client->impl, -1, 0);
 | 
				
			||||||
	reply->extra[0] = COMMAND_SUBSCRIBE_EVENT;
 | 
						reply->extra[0] = COMMAND_SUBSCRIBE_EVENT;
 | 
				
			||||||
	reply->extra[1] = event;
 | 
						reply->extra[1] = event;
 | 
				
			||||||
	reply->extra[2] = id;
 | 
						reply->extra[2] = index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	message_put(reply,
 | 
						message_put(reply,
 | 
				
			||||||
		TAG_U32, COMMAND_SUBSCRIBE_EVENT,
 | 
							TAG_U32, COMMAND_SUBSCRIBE_EVENT,
 | 
				
			||||||
		TAG_U32, -1,
 | 
							TAG_U32, -1,
 | 
				
			||||||
		TAG_U32, event,
 | 
							TAG_U32, event,
 | 
				
			||||||
		TAG_U32, id,
 | 
							TAG_U32, index,
 | 
				
			||||||
		TAG_INVALID);
 | 
							TAG_INVALID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return client_queue_message(client, reply);
 | 
						return client_queue_message(client, reply);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,18 +58,25 @@ struct pw_manager_object *select_object(struct pw_manager *m, struct selector *s
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (o->id == s->id)
 | 
							if (o->id == s->id)
 | 
				
			||||||
			return o;
 | 
								return o;
 | 
				
			||||||
 | 
							if (o->index == s->index)
 | 
				
			||||||
 | 
								return o;
 | 
				
			||||||
		if (s->accumulate)
 | 
							if (s->accumulate)
 | 
				
			||||||
			s->accumulate(s, o);
 | 
								s->accumulate(s, o);
 | 
				
			||||||
		if (o->props && s->key != NULL && s->value != NULL &&
 | 
							if (o->props && s->key != NULL && s->value != NULL &&
 | 
				
			||||||
		    (str = pw_properties_get(o->props, s->key)) != NULL &&
 | 
							    (str = pw_properties_get(o->props, s->key)) != NULL &&
 | 
				
			||||||
		    spa_streq(str, s->value))
 | 
							    spa_streq(str, s->value))
 | 
				
			||||||
			return o;
 | 
								return o;
 | 
				
			||||||
		if (s->value != NULL && (uint32_t)atoi(s->value) == o->id)
 | 
							if (s->value != NULL && (uint32_t)atoi(s->value) == o->index)
 | 
				
			||||||
			return o;
 | 
								return o;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return s->best;
 | 
						return s->best;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t id_to_index(struct pw_manager *m, uint32_t id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return id;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool collect_is_linked(struct pw_manager *m, uint32_t id, enum pw_direction direction)
 | 
					bool collect_is_linked(struct pw_manager *m, uint32_t id, enum pw_direction direction)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_manager_object *o;
 | 
						struct pw_manager_object *o;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,7 @@ struct pw_manager_object;
 | 
				
			||||||
struct selector {
 | 
					struct selector {
 | 
				
			||||||
	bool (*type) (struct pw_manager_object *o);
 | 
						bool (*type) (struct pw_manager_object *o);
 | 
				
			||||||
	uint32_t id;
 | 
						uint32_t id;
 | 
				
			||||||
 | 
						uint32_t index;
 | 
				
			||||||
	const char *key;
 | 
						const char *key;
 | 
				
			||||||
	const char *value;
 | 
						const char *value;
 | 
				
			||||||
	void (*accumulate) (struct selector *sel, struct pw_manager_object *o);
 | 
						void (*accumulate) (struct selector *sel, struct pw_manager_object *o);
 | 
				
			||||||
| 
						 | 
					@ -52,6 +53,7 @@ struct selector {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pw_manager_object *select_object(struct pw_manager *m, struct selector *s);
 | 
					struct pw_manager_object *select_object(struct pw_manager *m, struct selector *s);
 | 
				
			||||||
 | 
					uint32_t id_to_index(struct pw_manager *m, uint32_t id);
 | 
				
			||||||
void select_best(struct selector *s, struct pw_manager_object *o);
 | 
					void select_best(struct selector *s, struct pw_manager_object *o);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ========================================================================== */
 | 
					/* ========================================================================== */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,12 +35,12 @@ static const struct extension extensions[] = {
 | 
				
			||||||
	{ "module-device-manager", 2 | MODULE_EXTENSION_FLAG, do_extension_device_manager, },
 | 
						{ "module-device-manager", 2 | MODULE_EXTENSION_FLAG, do_extension_device_manager, },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct extension *extension_find(uint32_t idx, const char *name)
 | 
					const struct extension *extension_find(uint32_t index, const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct extension *ext;
 | 
						const struct extension *ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SPA_FOR_EACH_ELEMENT(extensions, ext) {
 | 
						SPA_FOR_EACH_ELEMENT(extensions, ext) {
 | 
				
			||||||
		if (idx == ext->idx || spa_streq(name, ext->name))
 | 
							if (index == ext->index || spa_streq(name, ext->name))
 | 
				
			||||||
			return ext;
 | 
								return ext;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,10 +38,10 @@ struct extension_sub {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct extension {
 | 
					struct extension {
 | 
				
			||||||
	const char *name;
 | 
						const char *name;
 | 
				
			||||||
	uint32_t idx;
 | 
						uint32_t index;
 | 
				
			||||||
	int (*process)(struct client *client, uint32_t tag, struct message *m);
 | 
						int (*process)(struct client *client, uint32_t tag, struct message *m);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct extension *extension_find(uint32_t idx, const char *name);
 | 
					const struct extension *extension_find(uint32_t index, const char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* PULSE_SERVER_EXTENSION_H */
 | 
					#endif /* PULSE_SERVER_EXTENSION_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,7 +108,7 @@ static int do_sink_read_format(void *data, struct pw_manager_object *o)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	message_put(d->reply,
 | 
						message_put(d->reply,
 | 
				
			||||||
		TAG_U32, DEVICE_TYPE_SINK,
 | 
							TAG_U32, DEVICE_TYPE_SINK,
 | 
				
			||||||
		TAG_U32, o->id,
 | 
							TAG_U32, o->index,			/* sink index */
 | 
				
			||||||
		TAG_U8, n_info,				/* n_formats */
 | 
							TAG_U8, n_info,				/* n_formats */
 | 
				
			||||||
		TAG_INVALID);
 | 
							TAG_INVALID);
 | 
				
			||||||
	for (i = 0; i < n_info; i++) {
 | 
						for (i = 0; i < n_info; i++) {
 | 
				
			||||||
| 
						 | 
					@ -157,7 +157,7 @@ static int do_extension_device_restore_read_formats(struct client *client,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_zero(sel);
 | 
						spa_zero(sel);
 | 
				
			||||||
	sel.id = sink_index;
 | 
						sel.index = sink_index;
 | 
				
			||||||
	sel.type = pw_manager_object_is_sink;
 | 
						sel.type = pw_manager_object_is_sink;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o = select_object(manager, &sel);
 | 
						o = select_object(manager, &sel);
 | 
				
			||||||
| 
						 | 
					@ -173,7 +173,7 @@ static int do_extension_device_restore_read_formats(struct client *client,
 | 
				
			||||||
	return client_queue_message(client, data.reply);
 | 
						return client_queue_message(client, data.reply);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int set_card_codecs(struct pw_manager_object *o, uint32_t id,
 | 
					static int set_card_codecs(struct pw_manager_object *o, uint32_t port_index,
 | 
				
			||||||
		uint32_t device_id, uint32_t n_codecs, uint32_t *codecs)
 | 
							uint32_t device_id, uint32_t n_codecs, uint32_t *codecs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[1024];
 | 
						char buf[1024];
 | 
				
			||||||
| 
						 | 
					@ -190,7 +190,7 @@ static int set_card_codecs(struct pw_manager_object *o, uint32_t id,
 | 
				
			||||||
	spa_pod_builder_push_object(&b, &f[0],
 | 
						spa_pod_builder_push_object(&b, &f[0],
 | 
				
			||||||
			SPA_TYPE_OBJECT_ParamRoute, SPA_PARAM_Route);
 | 
								SPA_TYPE_OBJECT_ParamRoute, SPA_PARAM_Route);
 | 
				
			||||||
	spa_pod_builder_add(&b,
 | 
						spa_pod_builder_add(&b,
 | 
				
			||||||
			SPA_PARAM_ROUTE_index, SPA_POD_Int(id),
 | 
								SPA_PARAM_ROUTE_index, SPA_POD_Int(port_index),
 | 
				
			||||||
			SPA_PARAM_ROUTE_device, SPA_POD_Int(device_id),
 | 
								SPA_PARAM_ROUTE_device, SPA_POD_Int(device_id),
 | 
				
			||||||
			0);
 | 
								0);
 | 
				
			||||||
	spa_pod_builder_prop(&b, SPA_PARAM_ROUTE_props, 0);
 | 
						spa_pod_builder_prop(&b, SPA_PARAM_ROUTE_props, 0);
 | 
				
			||||||
| 
						 | 
					@ -279,7 +279,7 @@ static int do_extension_device_restore_save_formats(struct client *client,
 | 
				
			||||||
		return -ENOTSUP;
 | 
							return -ENOTSUP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_zero(sel);
 | 
						spa_zero(sel);
 | 
				
			||||||
	sel.id = sink_index;
 | 
						sel.index = sink_index;
 | 
				
			||||||
	sel.type = pw_manager_object_is_sink;
 | 
						sel.type = pw_manager_object_is_sink;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o = select_object(manager, &sel);
 | 
						o = select_object(manager, &sel);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -607,6 +607,7 @@ static void registry_event_global(void *data, uint32_t id,
 | 
				
			||||||
	o->this.permissions = permissions;
 | 
						o->this.permissions = permissions;
 | 
				
			||||||
	o->this.type = info->type;
 | 
						o->this.type = info->type;
 | 
				
			||||||
	o->this.version = version;
 | 
						o->this.version = version;
 | 
				
			||||||
 | 
						o->this.index = id;
 | 
				
			||||||
	o->this.props = props ? pw_properties_new_dict(props) : NULL;
 | 
						o->this.props = props ? pw_properties_new_dict(props) : NULL;
 | 
				
			||||||
	o->this.proxy = proxy;
 | 
						o->this.proxy = proxy;
 | 
				
			||||||
	o->this.creating = true;
 | 
						o->this.creating = true;
 | 
				
			||||||
| 
						 | 
					@ -793,7 +794,7 @@ int pw_manager_for_each_object(struct pw_manager *manager,
 | 
				
			||||||
	int res;
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_list_for_each(o, &m->this.object_list, this.link) {
 | 
						spa_list_for_each(o, &m->this.object_list, this.link) {
 | 
				
			||||||
		if (o->this.creating)
 | 
							if (o->this.creating || o->this.removing)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if ((res = callback(data, &o->this)) != 0)
 | 
							if ((res = callback(data, &o->this)) != 0)
 | 
				
			||||||
			return res;
 | 
								return res;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,6 +79,7 @@ struct pw_manager_object {
 | 
				
			||||||
	uint32_t permissions;
 | 
						uint32_t permissions;
 | 
				
			||||||
	const char *type;
 | 
						const char *type;
 | 
				
			||||||
	uint32_t version;
 | 
						uint32_t version;
 | 
				
			||||||
 | 
						uint32_t index;
 | 
				
			||||||
	struct pw_properties *props;
 | 
						struct pw_properties *props;
 | 
				
			||||||
	struct pw_proxy *proxy;
 | 
						struct pw_proxy *proxy;
 | 
				
			||||||
	char *message_object_path;
 | 
						char *message_object_path;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,7 +122,7 @@ void register_object_message_handlers(struct pw_manager_object *o)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (o->id == 0) {
 | 
						if (o->id == PW_ID_CORE) {
 | 
				
			||||||
		free(o->message_object_path);
 | 
							free(o->message_object_path);
 | 
				
			||||||
		o->message_object_path = strdup("/core");
 | 
							o->message_object_path = strdup("/core");
 | 
				
			||||||
		o->message_handler = core_object_message_handler;
 | 
							o->message_handler = core_object_message_handler;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,7 @@
 | 
				
			||||||
#include "log.h"
 | 
					#include "log.h"
 | 
				
			||||||
#include "module.h"
 | 
					#include "module.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void on_module_unload(void *obj, void *data, int res, uint32_t id)
 | 
					static void on_module_unload(void *obj, void *data, int res, uint32_t index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct module *module = obj;
 | 
						struct module *module = obj;
 | 
				
			||||||
	module_unload(NULL, module);
 | 
						module_unload(NULL, module);
 | 
				
			||||||
| 
						 | 
					@ -83,7 +83,7 @@ void module_add_listener(struct module *module,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int module_load(struct client *client, struct module *module)
 | 
					int module_load(struct client *client, struct module *module)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pw_log_info("load module id:%u name:%s", module->idx, module->name);
 | 
						pw_log_info("load module index:%u name:%s", module->index, module->name);
 | 
				
			||||||
	if (module->methods->load == NULL)
 | 
						if (module->methods->load == NULL)
 | 
				
			||||||
		return -ENOTSUP;
 | 
							return -ENOTSUP;
 | 
				
			||||||
	/* subscription event is sent when the module does a
 | 
						/* subscription event is sent when the module does a
 | 
				
			||||||
| 
						 | 
					@ -97,8 +97,8 @@ void module_free(struct module *module)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	module_emit_destroy(module);
 | 
						module_emit_destroy(module);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (module->idx != SPA_ID_INVALID)
 | 
						if (module->index != SPA_ID_INVALID)
 | 
				
			||||||
		pw_map_remove(&impl->modules, module->idx & MODULE_INDEX_MASK);
 | 
							pw_map_remove(&impl->modules, module->index & MODULE_INDEX_MASK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_hook_list_clean(&module->listener_list);
 | 
						spa_hook_list_clean(&module->listener_list);
 | 
				
			||||||
	pw_work_queue_cancel(impl->work_queue, module, SPA_ID_INVALID);
 | 
						pw_work_queue_cancel(impl->work_queue, module, SPA_ID_INVALID);
 | 
				
			||||||
| 
						 | 
					@ -118,7 +118,7 @@ int module_unload(struct client *client, struct module *module)
 | 
				
			||||||
	/* Note that client can be NULL (when the module is being unloaded
 | 
						/* Note that client can be NULL (when the module is being unloaded
 | 
				
			||||||
	 * internally and not by a client request */
 | 
						 * internally and not by a client request */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("unload module id:%u name:%s", module->idx, module->name);
 | 
						pw_log_info("unload module index:%u name:%s", module->index, module->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (module->methods->unload)
 | 
						if (module->methods->unload)
 | 
				
			||||||
		res = module->methods->unload(client, module);
 | 
							res = module->methods->unload(client, module);
 | 
				
			||||||
| 
						 | 
					@ -127,7 +127,7 @@ int module_unload(struct client *client, struct module *module)
 | 
				
			||||||
		broadcast_subscribe_event(impl,
 | 
							broadcast_subscribe_event(impl,
 | 
				
			||||||
			SUBSCRIPTION_MASK_MODULE,
 | 
								SUBSCRIPTION_MASK_MODULE,
 | 
				
			||||||
			SUBSCRIPTION_EVENT_REMOVE | SUBSCRIPTION_EVENT_MODULE,
 | 
								SUBSCRIPTION_EVENT_REMOVE | SUBSCRIPTION_EVENT_MODULE,
 | 
				
			||||||
			module->idx);
 | 
								module->index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	module_free(module);
 | 
						module_free(module);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -299,13 +299,13 @@ struct module *module_create(struct client *client, const char *name, const char
 | 
				
			||||||
	if (module == NULL)
 | 
						if (module == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	module->idx = pw_map_insert_new(&impl->modules, module);
 | 
						module->index = pw_map_insert_new(&impl->modules, module);
 | 
				
			||||||
	if (module->idx == SPA_ID_INVALID) {
 | 
						if (module->index == SPA_ID_INVALID) {
 | 
				
			||||||
		module_unload(client, module);
 | 
							module_unload(client, module);
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	module->name = strdup(name);
 | 
						module->name = strdup(name);
 | 
				
			||||||
	module->args = args ? strdup(args) : NULL;
 | 
						module->args = args ? strdup(args) : NULL;
 | 
				
			||||||
	module->idx |= MODULE_FLAG;
 | 
						module->index |= MODULE_FLAG;
 | 
				
			||||||
	return module;
 | 
						return module;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,7 @@ struct module_methods {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct module {
 | 
					struct module {
 | 
				
			||||||
	uint32_t idx;
 | 
						uint32_t index;
 | 
				
			||||||
	const char *name;
 | 
						const char *name;
 | 
				
			||||||
	const char *args;
 | 
						const char *args;
 | 
				
			||||||
	struct pw_properties *props;
 | 
						struct pw_properties *props;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -262,11 +262,11 @@ static void manager_added(void *d, struct pw_manager_object *o)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	props = pw_properties_new(NULL, NULL);
 | 
						props = pw_properties_new(NULL, NULL);
 | 
				
			||||||
	pw_properties_setf(props, PW_KEY_NODE_NAME,
 | 
						pw_properties_setf(props, PW_KEY_NODE_NAME,
 | 
				
			||||||
			"combine_output.sink-%u.%s", data->module->idx, sink_name);
 | 
								"combine_output.sink-%u.%s", data->module->index, sink_name);
 | 
				
			||||||
	pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, data->sink_name);
 | 
						pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, data->sink_name);
 | 
				
			||||||
	pw_properties_set(props, PW_KEY_NODE_TARGET, sink_name);
 | 
						pw_properties_set(props, PW_KEY_NODE_TARGET, sink_name);
 | 
				
			||||||
	pw_properties_setf(props, PW_KEY_NODE_GROUP, "combine_sink-%u", data->module->idx);
 | 
						pw_properties_setf(props, PW_KEY_NODE_GROUP, "combine_sink-%u", data->module->index);
 | 
				
			||||||
	pw_properties_setf(props, PW_KEY_NODE_LINK_GROUP, "combine_sink-%u", data->module->idx);
 | 
						pw_properties_setf(props, PW_KEY_NODE_LINK_GROUP, "combine_sink-%u", data->module->index);
 | 
				
			||||||
	pw_properties_set(props, PW_KEY_NODE_DONT_RECONNECT, "true");
 | 
						pw_properties_set(props, PW_KEY_NODE_DONT_RECONNECT, "true");
 | 
				
			||||||
	pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
 | 
						pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
 | 
				
			||||||
	pw_properties_set(props, PW_KEY_NODE_PASSIVE, "true");
 | 
						pw_properties_set(props, PW_KEY_NODE_PASSIVE, "true");
 | 
				
			||||||
| 
						 | 
					@ -351,8 +351,8 @@ static int module_combine_sink_load(struct client *client, struct module *module
 | 
				
			||||||
	pw_properties_set(props, PW_KEY_NODE_NAME, data->sink_name);
 | 
						pw_properties_set(props, PW_KEY_NODE_NAME, data->sink_name);
 | 
				
			||||||
	pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, data->sink_name);
 | 
						pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, data->sink_name);
 | 
				
			||||||
	pw_properties_set(props, PW_KEY_MEDIA_CLASS, "Audio/Sink");
 | 
						pw_properties_set(props, PW_KEY_MEDIA_CLASS, "Audio/Sink");
 | 
				
			||||||
	pw_properties_setf(props, PW_KEY_NODE_GROUP, "combine_sink-%u", data->module->idx);
 | 
						pw_properties_setf(props, PW_KEY_NODE_GROUP, "combine_sink-%u", data->module->index);
 | 
				
			||||||
	pw_properties_setf(props, PW_KEY_NODE_LINK_GROUP, "combine_sink-%u", data->module->idx);
 | 
						pw_properties_setf(props, PW_KEY_NODE_LINK_GROUP, "combine_sink-%u", data->module->index);
 | 
				
			||||||
	pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
 | 
						pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((str = pw_properties_get(module->props, "sink_properties")) != NULL)
 | 
						if ((str = pw_properties_get(module->props, "sink_properties")) != NULL)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,8 +73,8 @@ static int module_ladspa_sink_load(struct client *client, struct module *module)
 | 
				
			||||||
	if ((label = pw_properties_get(module->props, "label")) == NULL)
 | 
						if ((label = pw_properties_get(module->props, "label")) == NULL)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "ladspa-sink-%u", module->idx);
 | 
						pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "ladspa-sink-%u", module->index);
 | 
				
			||||||
	pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "ladspa-sink-%u", module->idx);
 | 
						pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "ladspa-sink-%u", module->index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f = open_memstream(&args, &size);
 | 
						f = open_memstream(&args, &size);
 | 
				
			||||||
	fprintf(f, "{");
 | 
						fprintf(f, "{");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,8 +73,8 @@ static int module_ladspa_source_load(struct client *client, struct module *modul
 | 
				
			||||||
	if ((label = pw_properties_get(module->props, "label")) == NULL)
 | 
						if ((label = pw_properties_get(module->props, "label")) == NULL)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "ladspa-source-%u", module->idx);
 | 
						pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "ladspa-source-%u", module->index);
 | 
				
			||||||
	pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "ladspa-source-%u", module->idx);
 | 
						pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "ladspa-source-%u", module->index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f = open_memstream(&args, &size);
 | 
						f = open_memstream(&args, &size);
 | 
				
			||||||
	fprintf(f, "{");
 | 
						fprintf(f, "{");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,8 +70,8 @@ static int module_loopback_load(struct client *client, struct module *module)
 | 
				
			||||||
	char *args;
 | 
						char *args;
 | 
				
			||||||
	size_t size, i;
 | 
						size_t size, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "loopback-%u", module->idx);
 | 
						pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "loopback-%u", module->index);
 | 
				
			||||||
	pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "loopback-%u", module->idx);
 | 
						pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "loopback-%u", module->index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f = open_memstream(&args, &size);
 | 
						f = open_memstream(&args, &size);
 | 
				
			||||||
	fprintf(f, "{");
 | 
						fprintf(f, "{");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,8 +67,8 @@ static int module_remap_sink_load(struct client *client, struct module *module)
 | 
				
			||||||
	char *args;
 | 
						char *args;
 | 
				
			||||||
	size_t size;
 | 
						size_t size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "remap-sink-%u", module->idx);
 | 
						pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "remap-sink-%u", module->index);
 | 
				
			||||||
	pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "remap-sink-%u", module->idx);
 | 
						pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "remap-sink-%u", module->index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f = open_memstream(&args, &size);
 | 
						f = open_memstream(&args, &size);
 | 
				
			||||||
	fprintf(f, "{");
 | 
						fprintf(f, "{");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,8 +67,8 @@ static int module_remap_source_load(struct client *client, struct module *module
 | 
				
			||||||
	char *args;
 | 
						char *args;
 | 
				
			||||||
	size_t size;
 | 
						size_t size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "remap-source-%u", module->idx);
 | 
						pw_properties_setf(data->capture_props, PW_KEY_NODE_GROUP, "remap-source-%u", module->index);
 | 
				
			||||||
	pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "remap-source-%u", module->idx);
 | 
						pw_properties_setf(data->playback_props, PW_KEY_NODE_GROUP, "remap-source-%u", module->index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f = open_memstream(&args, &size);
 | 
						f = open_memstream(&args, &size);
 | 
				
			||||||
	fprintf(f, "{");
 | 
						fprintf(f, "{");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,12 +97,12 @@ struct latency_offset_data {
 | 
				
			||||||
	unsigned int initialized:1;
 | 
						unsigned int initialized:1;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct sample *find_sample(struct impl *impl, uint32_t idx, const char *name)
 | 
					static struct sample *find_sample(struct impl *impl, uint32_t index, const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	union pw_map_item *item;
 | 
						union pw_map_item *item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (idx != SPA_ID_INVALID)
 | 
						if (index != SPA_ID_INVALID)
 | 
				
			||||||
		return pw_map_lookup(&impl->samples, idx);
 | 
							return pw_map_lookup(&impl->samples, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_array_for_each(item, &impl->samples.items) {
 | 
						pw_array_for_each(item, &impl->samples.items) {
 | 
				
			||||||
		struct sample *s = item->data;
 | 
							struct sample *s = item->data;
 | 
				
			||||||
| 
						 | 
					@ -113,13 +113,13 @@ static struct sample *find_sample(struct impl *impl, uint32_t idx, const char *n
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void broadcast_subscribe_event(struct impl *impl, uint32_t mask, uint32_t event, uint32_t id)
 | 
					void broadcast_subscribe_event(struct impl *impl, uint32_t mask, uint32_t event, uint32_t index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct server *s;
 | 
						struct server *s;
 | 
				
			||||||
	spa_list_for_each(s, &impl->servers, link) {
 | 
						spa_list_for_each(s, &impl->servers, link) {
 | 
				
			||||||
		struct client *c;
 | 
							struct client *c;
 | 
				
			||||||
		spa_list_for_each(c, &s->clients, link)
 | 
							spa_list_for_each(c, &s->clients, link)
 | 
				
			||||||
			client_queue_subscribe_event(c, mask, event, id);
 | 
								client_queue_subscribe_event(c, mask, event, index);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,23 +159,25 @@ static int do_command_auth(struct client *client, uint32_t command, uint32_t tag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int reply_set_client_name(struct client *client, uint32_t tag)
 | 
					static int reply_set_client_name(struct client *client, uint32_t tag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	struct message *reply;
 | 
						struct message *reply;
 | 
				
			||||||
	struct pw_client *c;
 | 
						struct pw_client *c;
 | 
				
			||||||
	uint32_t id;
 | 
						uint32_t id, index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c = pw_core_get_client(client->core);
 | 
						c = pw_core_get_client(client->core);
 | 
				
			||||||
	if (c == NULL)
 | 
						if (c == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	id = pw_proxy_get_bound_id((struct pw_proxy*)c);
 | 
						id = pw_proxy_get_bound_id((struct pw_proxy*)c);
 | 
				
			||||||
 | 
						index = id_to_index(manager, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] reply tag:%u id:%u", client->name, tag, id);
 | 
						pw_log_info("[%s] reply tag:%u id:%u index:%u", client->name, tag, id, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reply = reply_new(client, tag);
 | 
						reply = reply_new(client, tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (client->version >= 13) {
 | 
						if (client->version >= 13) {
 | 
				
			||||||
		message_put(reply,
 | 
							message_put(reply,
 | 
				
			||||||
			TAG_U32, id,		/* client index */
 | 
								TAG_U32, index,		/* client index */
 | 
				
			||||||
			TAG_INVALID);
 | 
								TAG_INVALID);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return client_queue_message(client, reply);
 | 
						return client_queue_message(client, reply);
 | 
				
			||||||
| 
						 | 
					@ -196,13 +198,13 @@ static void manager_sync(void *data)
 | 
				
			||||||
		operation_complete(o);
 | 
							operation_complete(o);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct stream *find_stream(struct client *client, uint32_t id)
 | 
					static struct stream *find_stream(struct client *client, uint32_t index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	union pw_map_item *item;
 | 
						union pw_map_item *item;
 | 
				
			||||||
	pw_array_for_each(item, &client->streams.items) {
 | 
						pw_array_for_each(item, &client->streams.items) {
 | 
				
			||||||
		struct stream *s = item->data;
 | 
							struct stream *s = item->data;
 | 
				
			||||||
		if (!pw_map_item_is_free(item) &&
 | 
							if (!pw_map_item_is_free(item) &&
 | 
				
			||||||
		    s->id == id)
 | 
							    s->index == index)
 | 
				
			||||||
			return s;
 | 
								return s;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
| 
						 | 
					@ -211,13 +213,13 @@ static struct stream *find_stream(struct client *client, uint32_t id)
 | 
				
			||||||
static int send_object_event(struct client *client, struct pw_manager_object *o,
 | 
					static int send_object_event(struct client *client, struct pw_manager_object *o,
 | 
				
			||||||
		uint32_t facility)
 | 
							uint32_t facility)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t event = 0, mask = 0, res_id = o->id;
 | 
						uint32_t event = 0, mask = 0, res_index = o->index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pw_manager_object_is_sink(o)) {
 | 
						if (pw_manager_object_is_sink(o)) {
 | 
				
			||||||
		client_queue_subscribe_event(client,
 | 
							client_queue_subscribe_event(client,
 | 
				
			||||||
				SUBSCRIPTION_MASK_SINK,
 | 
									SUBSCRIPTION_MASK_SINK,
 | 
				
			||||||
				SUBSCRIPTION_EVENT_SINK | facility,
 | 
									SUBSCRIPTION_EVENT_SINK | facility,
 | 
				
			||||||
				res_id);
 | 
									res_index);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (pw_manager_object_is_source_or_monitor(o)) {
 | 
						if (pw_manager_object_is_source_or_monitor(o)) {
 | 
				
			||||||
		mask = SUBSCRIPTION_MASK_SOURCE;
 | 
							mask = SUBSCRIPTION_MASK_SOURCE;
 | 
				
			||||||
| 
						 | 
					@ -249,12 +251,12 @@ static int send_object_event(struct client *client, struct pw_manager_object *o,
 | 
				
			||||||
		client_queue_subscribe_event(client,
 | 
							client_queue_subscribe_event(client,
 | 
				
			||||||
				mask,
 | 
									mask,
 | 
				
			||||||
				event | facility,
 | 
									event | facility,
 | 
				
			||||||
				res_id);
 | 
									res_index);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct pw_manager_object *find_device(struct client *client,
 | 
					static struct pw_manager_object *find_device(struct client *client,
 | 
				
			||||||
		uint32_t id, const char *name, bool sink, bool *is_monitor);
 | 
							uint32_t index, const char *name, bool sink, bool *is_monitor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int64_t get_node_latency_offset(struct pw_manager_object *o)
 | 
					static int64_t get_node_latency_offset(struct pw_manager_object *o)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -274,6 +276,7 @@ static int64_t get_node_latency_offset(struct pw_manager_object *o)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void send_latency_offset_subscribe_event(struct client *client, struct pw_manager_object *o)
 | 
					static void send_latency_offset_subscribe_event(struct client *client, struct pw_manager_object *o)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	struct latency_offset_data *d;
 | 
						struct latency_offset_data *d;
 | 
				
			||||||
	struct pw_node_info *info;
 | 
						struct pw_node_info *info;
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
| 
						 | 
					@ -308,7 +311,7 @@ static void send_latency_offset_subscribe_event(struct client *client, struct pw
 | 
				
			||||||
		client_queue_subscribe_event(client,
 | 
							client_queue_subscribe_event(client,
 | 
				
			||||||
				SUBSCRIPTION_MASK_CARD,
 | 
									SUBSCRIPTION_MASK_CARD,
 | 
				
			||||||
				SUBSCRIPTION_EVENT_CARD | SUBSCRIPTION_EVENT_CHANGE,
 | 
									SUBSCRIPTION_EVENT_CARD | SUBSCRIPTION_EVENT_CHANGE,
 | 
				
			||||||
				card_id);
 | 
									id_to_index(manager, card_id));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void send_default_change_subscribe_event(struct client *client, bool sink, bool source)
 | 
					static void send_default_change_subscribe_event(struct client *client, bool sink, bool source)
 | 
				
			||||||
| 
						 | 
					@ -444,8 +447,9 @@ static uint32_t fix_playback_buffer_attr(struct stream *s, struct buffer_attr *a
 | 
				
			||||||
static int reply_create_playback_stream(struct stream *stream, struct pw_manager_object *peer)
 | 
					static int reply_create_playback_stream(struct stream *stream, struct pw_manager_object *peer)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct client *client = stream->client;
 | 
						struct client *client = stream->client;
 | 
				
			||||||
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	struct message *reply;
 | 
						struct message *reply;
 | 
				
			||||||
	uint32_t missing, peer_id;
 | 
						uint32_t missing, peer_index;
 | 
				
			||||||
	struct spa_dict_item items[5];
 | 
						struct spa_dict_item items[5];
 | 
				
			||||||
	char latency[32];
 | 
						char latency[32];
 | 
				
			||||||
	char attr_maxlength[32];
 | 
						char attr_maxlength[32];
 | 
				
			||||||
| 
						 | 
					@ -486,22 +490,23 @@ static int reply_create_playback_stream(struct stream *stream, struct pw_manager
 | 
				
			||||||
		stream->in_prebuf = true;
 | 
							stream->in_prebuf = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	missing = stream_pop_missing(stream);
 | 
						missing = stream_pop_missing(stream);
 | 
				
			||||||
 | 
						stream->index = id_to_index(manager, stream->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] reply CREATE_PLAYBACK_STREAM tag:%u missing:%u latency:%s",
 | 
						pw_log_info("[%s] reply CREATE_PLAYBACK_STREAM tag:%u index:%u missing:%u latency:%s",
 | 
				
			||||||
			client->name, stream->create_tag, missing, latency);
 | 
								client->name, stream->create_tag, stream->index, missing, latency);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reply = reply_new(client, stream->create_tag);
 | 
						reply = reply_new(client, stream->create_tag);
 | 
				
			||||||
	message_put(reply,
 | 
						message_put(reply,
 | 
				
			||||||
		TAG_U32, stream->channel,		/* stream index/channel */
 | 
							TAG_U32, stream->channel,		/* stream index/channel */
 | 
				
			||||||
		TAG_U32, stream->id,			/* sink_input/stream index */
 | 
							TAG_U32, stream->index,			/* sink_input/stream index */
 | 
				
			||||||
		TAG_U32, missing,			/* missing/requested bytes */
 | 
							TAG_U32, missing,			/* missing/requested bytes */
 | 
				
			||||||
		TAG_INVALID);
 | 
							TAG_INVALID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (peer && pw_manager_object_is_sink(peer)) {
 | 
						if (peer && pw_manager_object_is_sink(peer)) {
 | 
				
			||||||
		peer_id = peer->id;
 | 
							peer_index = peer->index;
 | 
				
			||||||
		peer_name = pw_properties_get(peer->props, PW_KEY_NODE_NAME);
 | 
							peer_name = pw_properties_get(peer->props, PW_KEY_NODE_NAME);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		peer_id = SPA_ID_INVALID;
 | 
							peer_index = SPA_ID_INVALID;
 | 
				
			||||||
		peer_name = NULL;
 | 
							peer_name = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -517,7 +522,7 @@ static int reply_create_playback_stream(struct stream *stream, struct pw_manager
 | 
				
			||||||
		message_put(reply,
 | 
							message_put(reply,
 | 
				
			||||||
			TAG_SAMPLE_SPEC, &stream->ss,
 | 
								TAG_SAMPLE_SPEC, &stream->ss,
 | 
				
			||||||
			TAG_CHANNEL_MAP, &stream->map,
 | 
								TAG_CHANNEL_MAP, &stream->map,
 | 
				
			||||||
			TAG_U32, peer_id,		/* sink index */
 | 
								TAG_U32, peer_index,		/* sink index */
 | 
				
			||||||
			TAG_STRING, peer_name,		/* sink name */
 | 
								TAG_STRING, peer_name,		/* sink name */
 | 
				
			||||||
			TAG_BOOLEAN, false,		/* sink suspended state */
 | 
								TAG_BOOLEAN, false,		/* sink suspended state */
 | 
				
			||||||
			TAG_INVALID);
 | 
								TAG_INVALID);
 | 
				
			||||||
| 
						 | 
					@ -591,7 +596,7 @@ static int reply_create_record_stream(struct stream *stream, struct pw_manager_o
 | 
				
			||||||
	char attr_maxlength[32];
 | 
						char attr_maxlength[32];
 | 
				
			||||||
	char attr_fragsize[32];
 | 
						char attr_fragsize[32];
 | 
				
			||||||
	const char *peer_name, *name;
 | 
						const char *peer_name, *name;
 | 
				
			||||||
	uint32_t peer_id;
 | 
						uint32_t peer_index;
 | 
				
			||||||
	struct spa_fraction lat;
 | 
						struct spa_fraction lat;
 | 
				
			||||||
	uint64_t lat_usec;
 | 
						uint64_t lat_usec;
 | 
				
			||||||
	struct defs *defs = &stream->impl->defs;
 | 
						struct defs *defs = &stream->impl->defs;
 | 
				
			||||||
| 
						 | 
					@ -619,13 +624,15 @@ static int reply_create_record_stream(struct stream *stream, struct pw_manager_o
 | 
				
			||||||
	pw_stream_update_properties(stream->stream,
 | 
						pw_stream_update_properties(stream->stream,
 | 
				
			||||||
			&SPA_DICT_INIT(items, 3));
 | 
								&SPA_DICT_INIT(items, 3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] reply CREATE_RECORD_STREAM tag:%u latency:%s",
 | 
						stream->index = id_to_index(manager, stream->id);
 | 
				
			||||||
			client->name, stream->create_tag, latency);
 | 
					
 | 
				
			||||||
 | 
						pw_log_info("[%s] reply CREATE_RECORD_STREAM tag:%u index:%u latency:%s",
 | 
				
			||||||
 | 
								client->name, stream->create_tag, stream->index, latency);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reply = reply_new(client, stream->create_tag);
 | 
						reply = reply_new(client, stream->create_tag);
 | 
				
			||||||
	message_put(reply,
 | 
						message_put(reply,
 | 
				
			||||||
		TAG_U32, stream->channel,	/* stream index/channel */
 | 
							TAG_U32, stream->channel,	/* stream index/channel */
 | 
				
			||||||
		TAG_U32, stream->id,		/* source_output/stream index */
 | 
							TAG_U32, stream->index,		/* source_output/stream index */
 | 
				
			||||||
		TAG_INVALID);
 | 
							TAG_INVALID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (peer && pw_manager_object_is_sink_input(peer))
 | 
						if (peer && pw_manager_object_is_sink_input(peer))
 | 
				
			||||||
| 
						 | 
					@ -634,15 +641,15 @@ static int reply_create_record_stream(struct stream *stream, struct pw_manager_o
 | 
				
			||||||
		name = pw_properties_get(peer->props, PW_KEY_NODE_NAME);
 | 
							name = pw_properties_get(peer->props, PW_KEY_NODE_NAME);
 | 
				
			||||||
		if (!pw_manager_object_is_source(peer)) {
 | 
							if (!pw_manager_object_is_source(peer)) {
 | 
				
			||||||
			size_t len = (name ? strlen(name) : 5) + 10;
 | 
								size_t len = (name ? strlen(name) : 5) + 10;
 | 
				
			||||||
			peer_id = peer->id;
 | 
								peer_index = peer->index;
 | 
				
			||||||
			peer_name = tmp = alloca(len);
 | 
								peer_name = tmp = alloca(len);
 | 
				
			||||||
			snprintf(tmp, len, "%s.monitor", name ? name : "sink");
 | 
								snprintf(tmp, len, "%s.monitor", name ? name : "sink");
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			peer_id = peer->id;
 | 
								peer_index = peer->index;
 | 
				
			||||||
			peer_name = name;
 | 
								peer_name = name;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		peer_id = SPA_ID_INVALID;
 | 
							peer_index = SPA_ID_INVALID;
 | 
				
			||||||
		peer_name = NULL;
 | 
							peer_name = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -656,7 +663,7 @@ static int reply_create_record_stream(struct stream *stream, struct pw_manager_o
 | 
				
			||||||
		message_put(reply,
 | 
							message_put(reply,
 | 
				
			||||||
			TAG_SAMPLE_SPEC, &stream->ss,
 | 
								TAG_SAMPLE_SPEC, &stream->ss,
 | 
				
			||||||
			TAG_CHANNEL_MAP, &stream->map,
 | 
								TAG_CHANNEL_MAP, &stream->map,
 | 
				
			||||||
			TAG_U32, peer_id,		/* source index */
 | 
								TAG_U32, peer_index,		/* source index */
 | 
				
			||||||
			TAG_STRING, peer_name,		/* source name */
 | 
								TAG_STRING, peer_name,		/* source name */
 | 
				
			||||||
			TAG_BOOLEAN, false,		/* source suspended state */
 | 
								TAG_BOOLEAN, false,		/* source suspended state */
 | 
				
			||||||
			TAG_INVALID);
 | 
								TAG_INVALID);
 | 
				
			||||||
| 
						 | 
					@ -1429,7 +1436,7 @@ static int do_create_playback_stream(struct client *client, uint32_t command, ui
 | 
				
			||||||
			TAG_INVALID) < 0)
 | 
								TAG_INVALID) < 0)
 | 
				
			||||||
		goto error_protocol;
 | 
							goto error_protocol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] CREATE_PLAYBACK_STREAM tag:%u corked:%u sink-name:%s sink-idx:%u",
 | 
						pw_log_info("[%s] CREATE_PLAYBACK_STREAM tag:%u corked:%u sink-name:%s sink-index:%u",
 | 
				
			||||||
			client->name, tag, corked, sink_name, sink_index);
 | 
								client->name, tag, corked, sink_name, sink_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sink_index != SPA_ID_INVALID && sink_name != NULL)
 | 
						if (sink_index != SPA_ID_INVALID && sink_name != NULL)
 | 
				
			||||||
| 
						 | 
					@ -2224,7 +2231,7 @@ static const char *get_default(struct client *client, bool sink)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct pw_manager_object *find_device(struct client *client,
 | 
					static struct pw_manager_object *find_device(struct client *client,
 | 
				
			||||||
		uint32_t id, const char *name, bool sink, bool *is_monitor)
 | 
							uint32_t index, const char *name, bool sink, bool *is_monitor)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct selector sel;
 | 
						struct selector sel;
 | 
				
			||||||
	bool monitor = false, find_default = false;
 | 
						bool monitor = false, find_default = false;
 | 
				
			||||||
| 
						 | 
					@ -2244,16 +2251,16 @@ static struct pw_manager_object *find_device(struct client *client,
 | 
				
			||||||
			if (!sink)
 | 
								if (!sink)
 | 
				
			||||||
				return NULL;
 | 
									return NULL;
 | 
				
			||||||
			find_default = true;
 | 
								find_default = true;
 | 
				
			||||||
		} else if (spa_atou32(name, &id, 0)) {
 | 
							} else if (spa_atou32(name, &index, 0)) {
 | 
				
			||||||
			name = NULL;
 | 
								name = NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (name == NULL && (id == SPA_ID_INVALID || id == 0))
 | 
						if (name == NULL && (index == SPA_ID_INVALID || index == 0))
 | 
				
			||||||
		find_default = true;
 | 
							find_default = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (find_default) {
 | 
						if (find_default) {
 | 
				
			||||||
		name = get_default(client, sink);
 | 
							name = get_default(client, sink);
 | 
				
			||||||
		id = SPA_ID_INVALID;
 | 
							index = SPA_ID_INVALID;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (name != NULL) {
 | 
						if (name != NULL) {
 | 
				
			||||||
| 
						 | 
					@ -2261,7 +2268,7 @@ static struct pw_manager_object *find_device(struct client *client,
 | 
				
			||||||
			name = strndupa(name, strlen(name)-8);
 | 
								name = strndupa(name, strlen(name)-8);
 | 
				
			||||||
			monitor = true;
 | 
								monitor = true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (id == SPA_ID_INVALID)
 | 
						} else if (index == SPA_ID_INVALID)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2269,7 +2276,7 @@ static struct pw_manager_object *find_device(struct client *client,
 | 
				
			||||||
	sel.type = sink ?
 | 
						sel.type = sink ?
 | 
				
			||||||
		pw_manager_object_is_sink :
 | 
							pw_manager_object_is_sink :
 | 
				
			||||||
		pw_manager_object_is_source_or_monitor;
 | 
							pw_manager_object_is_source_or_monitor;
 | 
				
			||||||
	sel.id = id;
 | 
						sel.index = index;
 | 
				
			||||||
	sel.key = PW_KEY_NODE_NAME;
 | 
						sel.key = PW_KEY_NODE_NAME;
 | 
				
			||||||
	sel.value = name;
 | 
						sel.value = name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2555,7 +2562,7 @@ static int set_node_volume_mute(struct pw_manager_object *o,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int set_card_volume_mute_delay(struct pw_manager_object *o, uint32_t id,
 | 
					static int set_card_volume_mute_delay(struct pw_manager_object *o, uint32_t port_index,
 | 
				
			||||||
		uint32_t device_id, struct volume *vol, bool *mute, int64_t *latency_offset)
 | 
							uint32_t device_id, struct volume *vol, bool *mute, int64_t *latency_offset)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[1024];
 | 
						char buf[1024];
 | 
				
			||||||
| 
						 | 
					@ -2572,7 +2579,7 @@ static int set_card_volume_mute_delay(struct pw_manager_object *o, uint32_t id,
 | 
				
			||||||
	spa_pod_builder_push_object(&b, &f[0],
 | 
						spa_pod_builder_push_object(&b, &f[0],
 | 
				
			||||||
			SPA_TYPE_OBJECT_ParamRoute, SPA_PARAM_Route);
 | 
								SPA_TYPE_OBJECT_ParamRoute, SPA_PARAM_Route);
 | 
				
			||||||
	spa_pod_builder_add(&b,
 | 
						spa_pod_builder_add(&b,
 | 
				
			||||||
			SPA_PARAM_ROUTE_index, SPA_POD_Int(id),
 | 
								SPA_PARAM_ROUTE_index, SPA_POD_Int(port_index),
 | 
				
			||||||
			SPA_PARAM_ROUTE_device, SPA_POD_Int(device_id),
 | 
								SPA_PARAM_ROUTE_device, SPA_POD_Int(device_id),
 | 
				
			||||||
			0);
 | 
								0);
 | 
				
			||||||
	spa_pod_builder_prop(&b, SPA_PARAM_ROUTE_props, 0);
 | 
						spa_pod_builder_prop(&b, SPA_PARAM_ROUTE_props, 0);
 | 
				
			||||||
| 
						 | 
					@ -2601,7 +2608,7 @@ static int set_card_volume_mute_delay(struct pw_manager_object *o, uint32_t id,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int set_card_port(struct pw_manager_object *o, uint32_t device_id,
 | 
					static int set_card_port(struct pw_manager_object *o, uint32_t device_id,
 | 
				
			||||||
		uint32_t port_id)
 | 
							uint32_t port_index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[1024];
 | 
						char buf[1024];
 | 
				
			||||||
	struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
 | 
						struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
 | 
				
			||||||
| 
						 | 
					@ -2616,7 +2623,7 @@ static int set_card_port(struct pw_manager_object *o, uint32_t device_id,
 | 
				
			||||||
			SPA_PARAM_Route, 0,
 | 
								SPA_PARAM_Route, 0,
 | 
				
			||||||
			spa_pod_builder_add_object(&b,
 | 
								spa_pod_builder_add_object(&b,
 | 
				
			||||||
				SPA_TYPE_OBJECT_ParamRoute, SPA_PARAM_Route,
 | 
									SPA_TYPE_OBJECT_ParamRoute, SPA_PARAM_Route,
 | 
				
			||||||
				SPA_PARAM_ROUTE_index, SPA_POD_Int(port_id),
 | 
									SPA_PARAM_ROUTE_index, SPA_POD_Int(port_index),
 | 
				
			||||||
				SPA_PARAM_ROUTE_device, SPA_POD_Int(device_id),
 | 
									SPA_PARAM_ROUTE_device, SPA_POD_Int(device_id),
 | 
				
			||||||
				SPA_PARAM_ROUTE_save, SPA_POD_Bool(true)));
 | 
									SPA_PARAM_ROUTE_save, SPA_POD_Bool(true)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2626,21 +2633,21 @@ static int set_card_port(struct pw_manager_object *o, uint32_t device_id,
 | 
				
			||||||
static int do_set_stream_volume(struct client *client, uint32_t command, uint32_t tag, struct message *m)
 | 
					static int do_set_stream_volume(struct client *client, uint32_t command, uint32_t tag, struct message *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_manager *manager = client->manager;
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	uint32_t id;
 | 
						uint32_t index;
 | 
				
			||||||
	struct stream *stream;
 | 
						struct stream *stream;
 | 
				
			||||||
	struct volume volume;
 | 
						struct volume volume;
 | 
				
			||||||
	int res;
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((res = message_get(m,
 | 
						if ((res = message_get(m,
 | 
				
			||||||
			TAG_U32, &id,
 | 
								TAG_U32, &index,
 | 
				
			||||||
			TAG_CVOLUME, &volume,
 | 
								TAG_CVOLUME, &volume,
 | 
				
			||||||
			TAG_INVALID)) < 0)
 | 
								TAG_INVALID)) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u index:%u",
 | 
						pw_log_info("[%s] %s tag:%u index:%u",
 | 
				
			||||||
			client->name, commands[command].name, tag, id);
 | 
								client->name, commands[command].name, tag, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stream = find_stream(client, id);
 | 
						stream = find_stream(client, index);
 | 
				
			||||||
	if (stream != NULL) {
 | 
						if (stream != NULL) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (volume_compare(&stream->volume, &volume) == 0)
 | 
							if (volume_compare(&stream->volume, &volume) == 0)
 | 
				
			||||||
| 
						 | 
					@ -2654,7 +2661,7 @@ static int do_set_stream_volume(struct client *client, uint32_t command, uint32_
 | 
				
			||||||
		struct pw_manager_object *o;
 | 
							struct pw_manager_object *o;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		spa_zero(sel);
 | 
							spa_zero(sel);
 | 
				
			||||||
		sel.id = id;
 | 
							sel.index = index;
 | 
				
			||||||
		if (command == COMMAND_SET_SINK_INPUT_VOLUME)
 | 
							if (command == COMMAND_SET_SINK_INPUT_VOLUME)
 | 
				
			||||||
			sel.type = pw_manager_object_is_sink_input;
 | 
								sel.type = pw_manager_object_is_sink_input;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
| 
						 | 
					@ -2674,21 +2681,21 @@ done:
 | 
				
			||||||
static int do_set_stream_mute(struct client *client, uint32_t command, uint32_t tag, struct message *m)
 | 
					static int do_set_stream_mute(struct client *client, uint32_t command, uint32_t tag, struct message *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_manager *manager = client->manager;
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	uint32_t id;
 | 
						uint32_t index;
 | 
				
			||||||
	struct stream *stream;
 | 
						struct stream *stream;
 | 
				
			||||||
	int res;
 | 
						int res;
 | 
				
			||||||
	bool mute;
 | 
						bool mute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((res = message_get(m,
 | 
						if ((res = message_get(m,
 | 
				
			||||||
			TAG_U32, &id,
 | 
								TAG_U32, &index,
 | 
				
			||||||
			TAG_BOOLEAN, &mute,
 | 
								TAG_BOOLEAN, &mute,
 | 
				
			||||||
			TAG_INVALID)) < 0)
 | 
								TAG_INVALID)) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] DO_SET_STREAM_MUTE tag:%u id:%u mute:%u",
 | 
						pw_log_info("[%s] DO_SET_STREAM_MUTE tag:%u index:%u mute:%u",
 | 
				
			||||||
			client->name, tag, id, mute);
 | 
								client->name, tag, index, mute);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stream = find_stream(client, id);
 | 
						stream = find_stream(client, index);
 | 
				
			||||||
	if (stream != NULL) {
 | 
						if (stream != NULL) {
 | 
				
			||||||
		float val;
 | 
							float val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2704,7 +2711,7 @@ static int do_set_stream_mute(struct client *client, uint32_t command, uint32_t
 | 
				
			||||||
		struct pw_manager_object *o;
 | 
							struct pw_manager_object *o;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		spa_zero(sel);
 | 
							spa_zero(sel);
 | 
				
			||||||
		sel.id = id;
 | 
							sel.index = index;
 | 
				
			||||||
		if (command == COMMAND_SET_SINK_INPUT_MUTE)
 | 
							if (command == COMMAND_SET_SINK_INPUT_MUTE)
 | 
				
			||||||
			sel.type = pw_manager_object_is_sink_input;
 | 
								sel.type = pw_manager_object_is_sink_input;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
| 
						 | 
					@ -2726,7 +2733,7 @@ static int do_set_volume(struct client *client, uint32_t command, uint32_t tag,
 | 
				
			||||||
	struct impl *impl = client->impl;
 | 
						struct impl *impl = client->impl;
 | 
				
			||||||
	struct pw_manager *manager = client->manager;
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	struct pw_node_info *info;
 | 
						struct pw_node_info *info;
 | 
				
			||||||
	uint32_t id, card_id = SPA_ID_INVALID;
 | 
						uint32_t index, card_id = SPA_ID_INVALID;
 | 
				
			||||||
	const char *name, *str;
 | 
						const char *name, *str;
 | 
				
			||||||
	struct volume volume;
 | 
						struct volume volume;
 | 
				
			||||||
	struct pw_manager_object *o, *card = NULL;
 | 
						struct pw_manager_object *o, *card = NULL;
 | 
				
			||||||
| 
						 | 
					@ -2736,17 +2743,17 @@ static int do_set_volume(struct client *client, uint32_t command, uint32_t tag,
 | 
				
			||||||
	bool is_monitor;
 | 
						bool is_monitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((res = message_get(m,
 | 
						if ((res = message_get(m,
 | 
				
			||||||
			TAG_U32, &id,
 | 
								TAG_U32, &index,
 | 
				
			||||||
			TAG_STRING, &name,
 | 
								TAG_STRING, &name,
 | 
				
			||||||
			TAG_CVOLUME, &volume,
 | 
								TAG_CVOLUME, &volume,
 | 
				
			||||||
			TAG_INVALID)) < 0)
 | 
								TAG_INVALID)) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u index:%u name:%s",
 | 
						pw_log_info("[%s] %s tag:%u index:%u name:%s",
 | 
				
			||||||
			client->name, commands[command].name, tag, id, name);
 | 
								client->name, commands[command].name, tag, index, name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((id == SPA_ID_INVALID && name == NULL) ||
 | 
						if ((index == SPA_ID_INVALID && name == NULL) ||
 | 
				
			||||||
	    (id != SPA_ID_INVALID && name != NULL))
 | 
						    (index != SPA_ID_INVALID && name != NULL))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (command == COMMAND_SET_SINK_VOLUME)
 | 
						if (command == COMMAND_SET_SINK_VOLUME)
 | 
				
			||||||
| 
						 | 
					@ -2754,7 +2761,7 @@ static int do_set_volume(struct client *client, uint32_t command, uint32_t tag,
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		direction = PW_DIRECTION_INPUT;
 | 
							direction = PW_DIRECTION_INPUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o = find_device(client, id, name, direction == PW_DIRECTION_OUTPUT, &is_monitor);
 | 
						o = find_device(client, index, name, direction == PW_DIRECTION_OUTPUT, &is_monitor);
 | 
				
			||||||
	if (o == NULL || (info = o->info) == NULL || info->props == NULL)
 | 
						if (o == NULL || (info = o->info) == NULL || info->props == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2792,7 +2799,7 @@ static int do_set_mute(struct client *client, uint32_t command, uint32_t tag, st
 | 
				
			||||||
	struct impl *impl = client->impl;
 | 
						struct impl *impl = client->impl;
 | 
				
			||||||
	struct pw_manager *manager = client->manager;
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	struct pw_node_info *info;
 | 
						struct pw_node_info *info;
 | 
				
			||||||
	uint32_t id, card_id = SPA_ID_INVALID;
 | 
						uint32_t index, card_id = SPA_ID_INVALID;
 | 
				
			||||||
	const char *name, *str;
 | 
						const char *name, *str;
 | 
				
			||||||
	bool mute;
 | 
						bool mute;
 | 
				
			||||||
	struct pw_manager_object *o, *card = NULL;
 | 
						struct pw_manager_object *o, *card = NULL;
 | 
				
			||||||
| 
						 | 
					@ -2802,17 +2809,17 @@ static int do_set_mute(struct client *client, uint32_t command, uint32_t tag, st
 | 
				
			||||||
	bool is_monitor;
 | 
						bool is_monitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((res = message_get(m,
 | 
						if ((res = message_get(m,
 | 
				
			||||||
			TAG_U32, &id,
 | 
								TAG_U32, &index,
 | 
				
			||||||
			TAG_STRING, &name,
 | 
								TAG_STRING, &name,
 | 
				
			||||||
			TAG_BOOLEAN, &mute,
 | 
								TAG_BOOLEAN, &mute,
 | 
				
			||||||
			TAG_INVALID)) < 0)
 | 
								TAG_INVALID)) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u index:%u name:%s mute:%d",
 | 
						pw_log_info("[%s] %s tag:%u index:%u name:%s mute:%d",
 | 
				
			||||||
			client->name, commands[command].name, tag, id, name, mute);
 | 
								client->name, commands[command].name, tag, index, name, mute);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((id == SPA_ID_INVALID && name == NULL) ||
 | 
						if ((index == SPA_ID_INVALID && name == NULL) ||
 | 
				
			||||||
	    (id != SPA_ID_INVALID && name != NULL))
 | 
						    (index != SPA_ID_INVALID && name != NULL))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (command == COMMAND_SET_SINK_MUTE)
 | 
						if (command == COMMAND_SET_SINK_MUTE)
 | 
				
			||||||
| 
						 | 
					@ -2820,7 +2827,7 @@ static int do_set_mute(struct client *client, uint32_t command, uint32_t tag, st
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		direction = PW_DIRECTION_INPUT;
 | 
							direction = PW_DIRECTION_INPUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o = find_device(client, id, name, direction == PW_DIRECTION_OUTPUT, &is_monitor);
 | 
						o = find_device(client, index, name, direction == PW_DIRECTION_OUTPUT, &is_monitor);
 | 
				
			||||||
	if (o == NULL || (info = o->info) == NULL || info->props == NULL)
 | 
						if (o == NULL || (info = o->info) == NULL || info->props == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2856,7 +2863,7 @@ static int do_set_port(struct client *client, uint32_t command, uint32_t tag, st
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_manager *manager = client->manager;
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	struct pw_node_info *info;
 | 
						struct pw_node_info *info;
 | 
				
			||||||
	uint32_t id, card_id = SPA_ID_INVALID, device_id = SPA_ID_INVALID;
 | 
						uint32_t index, card_id = SPA_ID_INVALID, device_id = SPA_ID_INVALID;
 | 
				
			||||||
	uint32_t port_index = SPA_ID_INVALID;
 | 
						uint32_t port_index = SPA_ID_INVALID;
 | 
				
			||||||
	const char *name, *str, *port_name;
 | 
						const char *name, *str, *port_name;
 | 
				
			||||||
	struct pw_manager_object *o, *card = NULL;
 | 
						struct pw_manager_object *o, *card = NULL;
 | 
				
			||||||
| 
						 | 
					@ -2864,17 +2871,17 @@ static int do_set_port(struct client *client, uint32_t command, uint32_t tag, st
 | 
				
			||||||
	enum pw_direction direction;
 | 
						enum pw_direction direction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((res = message_get(m,
 | 
						if ((res = message_get(m,
 | 
				
			||||||
			TAG_U32, &id,
 | 
								TAG_U32, &index,
 | 
				
			||||||
			TAG_STRING, &name,
 | 
								TAG_STRING, &name,
 | 
				
			||||||
			TAG_STRING, &port_name,
 | 
								TAG_STRING, &port_name,
 | 
				
			||||||
			TAG_INVALID)) < 0)
 | 
								TAG_INVALID)) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u index:%u name:%s port:%s",
 | 
						pw_log_info("[%s] %s tag:%u index:%u name:%s port:%s",
 | 
				
			||||||
			client->name, commands[command].name, tag, id, name, port_name);
 | 
								client->name, commands[command].name, tag, index, name, port_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((id == SPA_ID_INVALID && name == NULL) ||
 | 
						if ((index == SPA_ID_INVALID && name == NULL) ||
 | 
				
			||||||
	    (id != SPA_ID_INVALID && name != NULL))
 | 
						    (index != SPA_ID_INVALID && name != NULL))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (command == COMMAND_SET_SINK_PORT)
 | 
						if (command == COMMAND_SET_SINK_PORT)
 | 
				
			||||||
| 
						 | 
					@ -2882,7 +2889,7 @@ static int do_set_port(struct client *client, uint32_t command, uint32_t tag, st
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		direction = PW_DIRECTION_INPUT;
 | 
							direction = PW_DIRECTION_INPUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o = find_device(client, id, name, direction == PW_DIRECTION_OUTPUT, NULL);
 | 
						o = find_device(client, index, name, direction == PW_DIRECTION_OUTPUT, NULL);
 | 
				
			||||||
	if (o == NULL || (info = o->info) == NULL || info->props == NULL)
 | 
						if (o == NULL || (info = o->info) == NULL || info->props == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2926,7 +2933,7 @@ static int do_set_port_latency_offset(struct client *client, uint32_t command, u
 | 
				
			||||||
	sel.type = pw_manager_object_is_card;
 | 
						sel.type = pw_manager_object_is_card;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((res = message_get(m,
 | 
						if ((res = message_get(m,
 | 
				
			||||||
			TAG_U32, &sel.id,
 | 
								TAG_U32, &sel.index,
 | 
				
			||||||
			TAG_STRING, &sel.value,
 | 
								TAG_STRING, &sel.value,
 | 
				
			||||||
			TAG_STRING, &port_name,
 | 
								TAG_STRING, &port_name,
 | 
				
			||||||
			TAG_S64, &offset,
 | 
								TAG_S64, &offset,
 | 
				
			||||||
| 
						 | 
					@ -2934,10 +2941,10 @@ static int do_set_port_latency_offset(struct client *client, uint32_t command, u
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u index:%u card_name:%s port_name:%s offset:%"PRIi64,
 | 
						pw_log_info("[%s] %s tag:%u index:%u card_name:%s port_name:%s offset:%"PRIi64,
 | 
				
			||||||
			client->name, commands[command].name, tag, sel.id, sel.value, port_name, offset);
 | 
								client->name, commands[command].name, tag, sel.index, sel.value, port_name, offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((sel.id == SPA_ID_INVALID && sel.value == NULL) ||
 | 
						if ((sel.index == SPA_ID_INVALID && sel.value == NULL) ||
 | 
				
			||||||
	    (sel.id != SPA_ID_INVALID && sel.value != NULL))
 | 
						    (sel.index != SPA_ID_INVALID && sel.value != NULL))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	if (port_name == NULL)
 | 
						if (port_name == NULL)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -3200,7 +3207,7 @@ static int do_lookup(struct client *client, uint32_t command, uint32_t tag, stru
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reply = reply_new(client, tag);
 | 
						reply = reply_new(client, tag);
 | 
				
			||||||
	message_put(reply,
 | 
						message_put(reply,
 | 
				
			||||||
		TAG_U32, o->id,
 | 
							TAG_U32, o->index,
 | 
				
			||||||
		TAG_INVALID);
 | 
							TAG_INVALID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return client_queue_message(client, reply);
 | 
						return client_queue_message(client, reply);
 | 
				
			||||||
| 
						 | 
					@ -3232,6 +3239,7 @@ static int fill_client_info(struct client *client, struct message *m,
 | 
				
			||||||
		struct pw_manager_object *o)
 | 
							struct pw_manager_object *o)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_client_info *info = o->info;
 | 
						struct pw_client_info *info = o->info;
 | 
				
			||||||
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
	uint32_t module_id = SPA_ID_INVALID;
 | 
						uint32_t module_id = SPA_ID_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3242,9 +3250,9 @@ static int fill_client_info(struct client *client, struct message *m,
 | 
				
			||||||
		module_id = (uint32_t)atoi(str);
 | 
							module_id = (uint32_t)atoi(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	message_put(m,
 | 
						message_put(m,
 | 
				
			||||||
		TAG_U32, o->id,				/* client index */
 | 
							TAG_U32, o->index,				/* client index */
 | 
				
			||||||
		TAG_STRING, pw_properties_get(o->props, PW_KEY_APP_NAME),
 | 
							TAG_STRING, pw_properties_get(o->props, PW_KEY_APP_NAME),
 | 
				
			||||||
		TAG_U32, module_id,			/* module */
 | 
							TAG_U32, id_to_index(manager, module_id),	/* module index */
 | 
				
			||||||
		TAG_STRING, "PipeWire",				/* driver */
 | 
							TAG_STRING, "PipeWire",				/* driver */
 | 
				
			||||||
		TAG_INVALID);
 | 
							TAG_INVALID);
 | 
				
			||||||
	if (client->version >= 13) {
 | 
						if (client->version >= 13) {
 | 
				
			||||||
| 
						 | 
					@ -3264,7 +3272,7 @@ static int fill_module_info(struct client *client, struct message *m,
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	message_put(m,
 | 
						message_put(m,
 | 
				
			||||||
		TAG_U32, o->id,				/* module index */
 | 
							TAG_U32, o->index,			/* module index */
 | 
				
			||||||
		TAG_STRING, info->name,
 | 
							TAG_STRING, info->name,
 | 
				
			||||||
		TAG_STRING, info->args,
 | 
							TAG_STRING, info->args,
 | 
				
			||||||
		TAG_U32, -1,				/* n_used */
 | 
							TAG_U32, -1,				/* n_used */
 | 
				
			||||||
| 
						 | 
					@ -3287,7 +3295,7 @@ static int fill_ext_module_info(struct client *client, struct message *m,
 | 
				
			||||||
		struct module *module)
 | 
							struct module *module)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	message_put(m,
 | 
						message_put(m,
 | 
				
			||||||
		TAG_U32, module->idx,			/* module index */
 | 
							TAG_U32, module->index,			/* module index */
 | 
				
			||||||
		TAG_STRING, module->name,
 | 
							TAG_STRING, module->name,
 | 
				
			||||||
		TAG_STRING, module->args,
 | 
							TAG_STRING, module->args,
 | 
				
			||||||
		TAG_U32, -1,				/* n_used */
 | 
							TAG_U32, -1,				/* n_used */
 | 
				
			||||||
| 
						 | 
					@ -3352,6 +3360,7 @@ static int64_t get_port_latency_offset(struct client *client, struct pw_manager_
 | 
				
			||||||
static int fill_card_info(struct client *client, struct message *m,
 | 
					static int fill_card_info(struct client *client, struct message *m,
 | 
				
			||||||
		struct pw_manager_object *o)
 | 
							struct pw_manager_object *o)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	struct pw_device_info *info = o->info;
 | 
						struct pw_device_info *info = o->info;
 | 
				
			||||||
	const char *str, *drv_name;
 | 
						const char *str, *drv_name;
 | 
				
			||||||
	uint32_t module_id = SPA_ID_INVALID, n_profiles, n;
 | 
						uint32_t module_id = SPA_ID_INVALID, n_profiles, n;
 | 
				
			||||||
| 
						 | 
					@ -3369,9 +3378,9 @@ static int fill_card_info(struct client *client, struct message *m,
 | 
				
			||||||
		drv_name = "module-bluez5-device.c"; /* blueman needs this */
 | 
							drv_name = "module-bluez5-device.c"; /* blueman needs this */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	message_put(m,
 | 
						message_put(m,
 | 
				
			||||||
		TAG_U32, o->id,				/* card index */
 | 
							TAG_U32, o->index,			/* card index */
 | 
				
			||||||
		TAG_STRING, spa_dict_lookup(info->props, PW_KEY_DEVICE_NAME),
 | 
							TAG_STRING, spa_dict_lookup(info->props, PW_KEY_DEVICE_NAME),
 | 
				
			||||||
		TAG_U32, module_id,
 | 
							TAG_U32, id_to_index(manager, module_id),
 | 
				
			||||||
		TAG_STRING, drv_name,
 | 
							TAG_STRING, drv_name,
 | 
				
			||||||
		TAG_INVALID);
 | 
							TAG_INVALID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3556,15 +3565,15 @@ static int fill_sink_info(struct client *client, struct message *m,
 | 
				
			||||||
		dev_info.ss.format = SPA_AUDIO_FORMAT_S16;
 | 
							dev_info.ss.format = SPA_AUDIO_FORMAT_S16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	message_put(m,
 | 
						message_put(m,
 | 
				
			||||||
		TAG_U32, o->id,				/* sink index */
 | 
							TAG_U32, o->index,			/* sink index */
 | 
				
			||||||
		TAG_STRING, name,
 | 
							TAG_STRING, name,
 | 
				
			||||||
		TAG_STRING, desc,
 | 
							TAG_STRING, desc,
 | 
				
			||||||
		TAG_SAMPLE_SPEC, &dev_info.ss,
 | 
							TAG_SAMPLE_SPEC, &dev_info.ss,
 | 
				
			||||||
		TAG_CHANNEL_MAP, &dev_info.map,
 | 
							TAG_CHANNEL_MAP, &dev_info.map,
 | 
				
			||||||
		TAG_U32, module_id,			/* module index */
 | 
							TAG_U32, id_to_index(manager, module_id),	/* module index */
 | 
				
			||||||
		TAG_CVOLUME, &dev_info.volume_info.volume,
 | 
							TAG_CVOLUME, &dev_info.volume_info.volume,
 | 
				
			||||||
		TAG_BOOLEAN, dev_info.volume_info.mute,
 | 
							TAG_BOOLEAN, dev_info.volume_info.mute,
 | 
				
			||||||
		TAG_U32, o->id,				/* monitor source index */
 | 
							TAG_U32, o->index,			/* monitor source index */
 | 
				
			||||||
		TAG_STRING, monitor_name,		/* monitor source name */
 | 
							TAG_STRING, monitor_name,		/* monitor source name */
 | 
				
			||||||
		TAG_USEC, 0LL,				/* latency */
 | 
							TAG_USEC, 0LL,				/* latency */
 | 
				
			||||||
		TAG_STRING, "PipeWire",			/* driver */
 | 
							TAG_STRING, "PipeWire",			/* driver */
 | 
				
			||||||
| 
						 | 
					@ -3590,7 +3599,7 @@ static int fill_sink_info(struct client *client, struct message *m,
 | 
				
			||||||
			TAG_VOLUME, dev_info.volume_info.base,	/* base volume */
 | 
								TAG_VOLUME, dev_info.volume_info.base,	/* base volume */
 | 
				
			||||||
			TAG_U32, state,				/* state */
 | 
								TAG_U32, state,				/* state */
 | 
				
			||||||
			TAG_U32, dev_info.volume_info.steps,	/* n_volume_steps */
 | 
								TAG_U32, dev_info.volume_info.steps,	/* n_volume_steps */
 | 
				
			||||||
			TAG_U32, card_id,			/* card index */
 | 
								TAG_U32, card ? card->index : SPA_ID_INVALID,	/* card index */
 | 
				
			||||||
			TAG_INVALID);
 | 
								TAG_INVALID);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (client->version >= 16) {
 | 
						if (client->version >= 16) {
 | 
				
			||||||
| 
						 | 
					@ -3759,15 +3768,15 @@ static int fill_source_info(struct client *client, struct message *m,
 | 
				
			||||||
		dev_info.ss.format = SPA_AUDIO_FORMAT_S16;
 | 
							dev_info.ss.format = SPA_AUDIO_FORMAT_S16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	message_put(m,
 | 
						message_put(m,
 | 
				
			||||||
		TAG_U32, o->id,					/* source index */
 | 
							TAG_U32, o->index,				/* source index */
 | 
				
			||||||
		TAG_STRING, is_monitor ? monitor_name : name,
 | 
							TAG_STRING, is_monitor ? monitor_name : name,
 | 
				
			||||||
		TAG_STRING, is_monitor ? monitor_desc : desc,
 | 
							TAG_STRING, is_monitor ? monitor_desc : desc,
 | 
				
			||||||
		TAG_SAMPLE_SPEC, &dev_info.ss,
 | 
							TAG_SAMPLE_SPEC, &dev_info.ss,
 | 
				
			||||||
		TAG_CHANNEL_MAP, &dev_info.map,
 | 
							TAG_CHANNEL_MAP, &dev_info.map,
 | 
				
			||||||
		TAG_U32, module_id,				/* module index */
 | 
							TAG_U32, id_to_index(manager, module_id),	/* module index */
 | 
				
			||||||
		TAG_CVOLUME, &dev_info.volume_info.volume,
 | 
							TAG_CVOLUME, &dev_info.volume_info.volume,
 | 
				
			||||||
		TAG_BOOLEAN, dev_info.volume_info.mute,
 | 
							TAG_BOOLEAN, dev_info.volume_info.mute,
 | 
				
			||||||
		TAG_U32, is_monitor ? o->id : SPA_ID_INVALID,	/* monitor of sink */
 | 
							TAG_U32, is_monitor ? o->index : SPA_ID_INVALID,/* monitor of sink */
 | 
				
			||||||
		TAG_STRING, is_monitor ? name : NULL,		/* monitor of sink name */
 | 
							TAG_STRING, is_monitor ? name : NULL,		/* monitor of sink name */
 | 
				
			||||||
		TAG_USEC, 0LL,					/* latency */
 | 
							TAG_USEC, 0LL,					/* latency */
 | 
				
			||||||
		TAG_STRING, "PipeWire",				/* driver */
 | 
							TAG_STRING, "PipeWire",				/* driver */
 | 
				
			||||||
| 
						 | 
					@ -3795,7 +3804,7 @@ static int fill_source_info(struct client *client, struct message *m,
 | 
				
			||||||
			TAG_VOLUME, dev_info.volume_info.base,	/* base volume */
 | 
								TAG_VOLUME, dev_info.volume_info.base,	/* base volume */
 | 
				
			||||||
			TAG_U32, state,				/* state */
 | 
								TAG_U32, state,				/* state */
 | 
				
			||||||
			TAG_U32, dev_info.volume_info.steps,	/* n_volume_steps */
 | 
								TAG_U32, dev_info.volume_info.steps,	/* n_volume_steps */
 | 
				
			||||||
			TAG_U32, card_id,			/* card index */
 | 
								TAG_U32, card ? card->index : SPA_ID_INVALID,	/* card index */
 | 
				
			||||||
			TAG_INVALID);
 | 
								TAG_INVALID);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (client->version >= 16) {
 | 
						if (client->version >= 16) {
 | 
				
			||||||
| 
						 | 
					@ -3861,6 +3870,7 @@ static int fill_sink_input_info(struct client *client, struct message *m,
 | 
				
			||||||
	struct pw_manager_object *peer;
 | 
						struct pw_manager_object *peer;
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
	uint32_t module_id = SPA_ID_INVALID, client_id = SPA_ID_INVALID;
 | 
						uint32_t module_id = SPA_ID_INVALID, client_id = SPA_ID_INVALID;
 | 
				
			||||||
 | 
						uint32_t peer_index;
 | 
				
			||||||
	struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT);
 | 
						struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!pw_manager_object_is_sink_input(o) || info == NULL || info->props == NULL)
 | 
						if (!pw_manager_object_is_sink_input(o) || info == NULL || info->props == NULL)
 | 
				
			||||||
| 
						 | 
					@ -3880,13 +3890,17 @@ static int fill_sink_input_info(struct client *client, struct message *m,
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	peer = find_linked(manager, o->id, PW_DIRECTION_OUTPUT);
 | 
						peer = find_linked(manager, o->id, PW_DIRECTION_OUTPUT);
 | 
				
			||||||
 | 
						if (peer && pw_manager_object_is_sink(peer))
 | 
				
			||||||
 | 
							peer_index = peer->index;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							peer_index = SPA_ID_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	message_put(m,
 | 
						message_put(m,
 | 
				
			||||||
		TAG_U32, o->id,					/* sink_input index */
 | 
							TAG_U32, o->index,				/* sink_input index */
 | 
				
			||||||
		TAG_STRING, get_media_name(info),
 | 
							TAG_STRING, get_media_name(info),
 | 
				
			||||||
		TAG_U32, module_id,				/* module index */
 | 
							TAG_U32, id_to_index(manager, module_id),	/* module index */
 | 
				
			||||||
		TAG_U32, client_id,				/* client index */
 | 
							TAG_U32, id_to_index(manager, client_id),	/* client index */
 | 
				
			||||||
		TAG_U32, peer ? peer->id : SPA_ID_INVALID,	/* sink index */
 | 
							TAG_U32, peer_index,				/* sink index */
 | 
				
			||||||
		TAG_SAMPLE_SPEC, &dev_info.ss,
 | 
							TAG_SAMPLE_SPEC, &dev_info.ss,
 | 
				
			||||||
		TAG_CHANNEL_MAP, &dev_info.map,
 | 
							TAG_CHANNEL_MAP, &dev_info.map,
 | 
				
			||||||
		TAG_CVOLUME, &dev_info.volume_info.volume,
 | 
							TAG_CVOLUME, &dev_info.volume_info.volume,
 | 
				
			||||||
| 
						 | 
					@ -3932,7 +3946,7 @@ static int fill_source_output_info(struct client *client, struct message *m,
 | 
				
			||||||
	struct pw_manager_object *peer;
 | 
						struct pw_manager_object *peer;
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
	uint32_t module_id = SPA_ID_INVALID, client_id = SPA_ID_INVALID;
 | 
						uint32_t module_id = SPA_ID_INVALID, client_id = SPA_ID_INVALID;
 | 
				
			||||||
	uint32_t peer_id;
 | 
						uint32_t peer_index;
 | 
				
			||||||
	struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_INPUT);
 | 
						struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_INPUT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!pw_manager_object_is_source_output(o) || info == NULL || info->props == NULL)
 | 
						if (!pw_manager_object_is_source_output(o) || info == NULL || info->props == NULL)
 | 
				
			||||||
| 
						 | 
					@ -3952,18 +3966,17 @@ static int fill_source_output_info(struct client *client, struct message *m,
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	peer = find_linked(manager, o->id, PW_DIRECTION_INPUT);
 | 
						peer = find_linked(manager, o->id, PW_DIRECTION_INPUT);
 | 
				
			||||||
	if (peer && pw_manager_object_is_source_or_monitor(peer)) {
 | 
						if (peer && pw_manager_object_is_source_or_monitor(peer))
 | 
				
			||||||
		peer_id = peer->id;
 | 
							peer_index = peer->index;
 | 
				
			||||||
	} else {
 | 
						else
 | 
				
			||||||
		peer_id = SPA_ID_INVALID;
 | 
							peer_index = SPA_ID_INVALID;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	message_put(m,
 | 
						message_put(m,
 | 
				
			||||||
		TAG_U32, o->id,					/* source_output index */
 | 
							TAG_U32, o->index,				/* source_output index */
 | 
				
			||||||
		TAG_STRING, get_media_name(info),
 | 
							TAG_STRING, get_media_name(info),
 | 
				
			||||||
		TAG_U32, module_id,				/* module index */
 | 
							TAG_U32, id_to_index(manager, module_id),	/* module index */
 | 
				
			||||||
		TAG_U32, client_id,				/* client index */
 | 
							TAG_U32, id_to_index(manager, client_id),	/* client index */
 | 
				
			||||||
		TAG_U32, peer_id,				/* source index */
 | 
							TAG_U32, peer_index,				/* source index */
 | 
				
			||||||
		TAG_SAMPLE_SPEC, &dev_info.ss,
 | 
							TAG_SAMPLE_SPEC, &dev_info.ss,
 | 
				
			||||||
		TAG_CHANNEL_MAP, &dev_info.map,
 | 
							TAG_CHANNEL_MAP, &dev_info.map,
 | 
				
			||||||
		TAG_USEC, 0LL,				/* latency */
 | 
							TAG_USEC, 0LL,				/* latency */
 | 
				
			||||||
| 
						 | 
					@ -4007,15 +4020,15 @@ static int do_get_info(struct client *client, uint32_t command, uint32_t tag, st
 | 
				
			||||||
	spa_zero(sel);
 | 
						spa_zero(sel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (message_get(m,
 | 
						if (message_get(m,
 | 
				
			||||||
			TAG_U32, &sel.id,
 | 
								TAG_U32, &sel.index,
 | 
				
			||||||
			TAG_INVALID) < 0)
 | 
								TAG_INVALID) < 0)
 | 
				
			||||||
		goto error_protocol;
 | 
							goto error_protocol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reply = reply_new(client, tag);
 | 
						reply = reply_new(client, tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (command == COMMAND_GET_MODULE_INFO && (sel.id & MODULE_FLAG) != 0) {
 | 
						if (command == COMMAND_GET_MODULE_INFO && (sel.index & MODULE_FLAG) != 0) {
 | 
				
			||||||
		struct module *module;
 | 
							struct module *module;
 | 
				
			||||||
		module = pw_map_lookup(&impl->modules, sel.id & MODULE_INDEX_MASK);
 | 
							module = pw_map_lookup(&impl->modules, sel.index & MODULE_INDEX_MASK);
 | 
				
			||||||
		if (module == NULL)
 | 
							if (module == NULL)
 | 
				
			||||||
			goto error_noentity;
 | 
								goto error_noentity;
 | 
				
			||||||
		fill_ext_module_info(client, reply, module);
 | 
							fill_ext_module_info(client, reply, module);
 | 
				
			||||||
| 
						 | 
					@ -4064,17 +4077,17 @@ static int do_get_info(struct client *client, uint32_t command, uint32_t tag, st
 | 
				
			||||||
	if (fill_func == NULL)
 | 
						if (fill_func == NULL)
 | 
				
			||||||
		goto error_invalid;
 | 
							goto error_invalid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sel.id != SPA_ID_INVALID && sel.value != NULL)
 | 
						if (sel.index != SPA_ID_INVALID && sel.value != NULL)
 | 
				
			||||||
		goto error_invalid;
 | 
							goto error_invalid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u idx:%u name:%s", client->name,
 | 
						pw_log_info("[%s] %s tag:%u index:%u name:%s", client->name,
 | 
				
			||||||
			commands[command].name, tag, sel.id, sel.value);
 | 
								commands[command].name, tag, sel.index, sel.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (command == COMMAND_GET_SINK_INFO || command == COMMAND_GET_SOURCE_INFO) {
 | 
						if (command == COMMAND_GET_SINK_INFO || command == COMMAND_GET_SOURCE_INFO) {
 | 
				
			||||||
		o = find_device(client, sel.id, sel.value,
 | 
							o = find_device(client, sel.index, sel.value,
 | 
				
			||||||
				command == COMMAND_GET_SINK_INFO, NULL);
 | 
									command == COMMAND_GET_SINK_INFO, NULL);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (sel.value == NULL && sel.id == SPA_ID_INVALID)
 | 
							if (sel.value == NULL && sel.index == SPA_ID_INVALID)
 | 
				
			||||||
			goto error_invalid;
 | 
								goto error_invalid;
 | 
				
			||||||
		o = select_object(manager, &sel);
 | 
							o = select_object(manager, &sel);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -4144,25 +4157,25 @@ static int do_get_sample_info(struct client *client, uint32_t command, uint32_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl = client->impl;
 | 
						struct impl *impl = client->impl;
 | 
				
			||||||
	struct message *reply = NULL;
 | 
						struct message *reply = NULL;
 | 
				
			||||||
	uint32_t id;
 | 
						uint32_t index;
 | 
				
			||||||
	const char *name;
 | 
						const char *name;
 | 
				
			||||||
	struct sample *sample;
 | 
						struct sample *sample;
 | 
				
			||||||
	int res;
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (message_get(m,
 | 
						if (message_get(m,
 | 
				
			||||||
			TAG_U32, &id,
 | 
								TAG_U32, &index,
 | 
				
			||||||
			TAG_STRING, &name,
 | 
								TAG_STRING, &name,
 | 
				
			||||||
			TAG_INVALID) < 0)
 | 
								TAG_INVALID) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((id == SPA_ID_INVALID && name == NULL) ||
 | 
						if ((index == SPA_ID_INVALID && name == NULL) ||
 | 
				
			||||||
	    (id != SPA_ID_INVALID && name != NULL))
 | 
						    (index != SPA_ID_INVALID && name != NULL))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u idx:%u name:%s", client->name,
 | 
						pw_log_info("[%s] %s tag:%u index:%u name:%s", client->name,
 | 
				
			||||||
			commands[command].name, tag, id, name);
 | 
								commands[command].name, tag, index, name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((sample = find_sample(impl, id, name)) == NULL)
 | 
						if ((sample = find_sample(impl, index, name)) == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reply = reply_new(client, tag);
 | 
						reply = reply_new(client, tag);
 | 
				
			||||||
| 
						 | 
					@ -4381,24 +4394,24 @@ static int do_update_stream_sample_rate(struct client *client, uint32_t command,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int do_extension(struct client *client, uint32_t command, uint32_t tag, struct message *m)
 | 
					static int do_extension(struct client *client, uint32_t command, uint32_t tag, struct message *m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t idx;
 | 
						uint32_t index;
 | 
				
			||||||
	const char *name;
 | 
						const char *name;
 | 
				
			||||||
	const struct extension *ext;
 | 
						const struct extension *ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (message_get(m,
 | 
						if (message_get(m,
 | 
				
			||||||
			TAG_U32, &idx,
 | 
								TAG_U32, &index,
 | 
				
			||||||
			TAG_STRING, &name,
 | 
								TAG_STRING, &name,
 | 
				
			||||||
			TAG_INVALID) < 0)
 | 
								TAG_INVALID) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u id:%u name:%s", client->name,
 | 
						pw_log_info("[%s] %s tag:%u index:%u name:%s", client->name,
 | 
				
			||||||
			commands[command].name, tag, idx, name);
 | 
								commands[command].name, tag, index, name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((idx == SPA_ID_INVALID && name == NULL) ||
 | 
						if ((index == SPA_ID_INVALID && name == NULL) ||
 | 
				
			||||||
	    (idx != SPA_ID_INVALID && name != NULL))
 | 
						    (index != SPA_ID_INVALID && name != NULL))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ext = extension_find(idx, name);
 | 
						ext = extension_find(index, name);
 | 
				
			||||||
	if (ext == NULL)
 | 
						if (ext == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4420,17 +4433,17 @@ static int do_set_profile(struct client *client, uint32_t command, uint32_t tag,
 | 
				
			||||||
	sel.type = pw_manager_object_is_card;
 | 
						sel.type = pw_manager_object_is_card;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (message_get(m,
 | 
						if (message_get(m,
 | 
				
			||||||
			TAG_U32, &sel.id,
 | 
								TAG_U32, &sel.index,
 | 
				
			||||||
			TAG_STRING, &sel.value,
 | 
								TAG_STRING, &sel.value,
 | 
				
			||||||
			TAG_STRING, &profile_name,
 | 
								TAG_STRING, &profile_name,
 | 
				
			||||||
			TAG_INVALID) < 0)
 | 
								TAG_INVALID) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u id:%u name:%s profile:%s", client->name,
 | 
						pw_log_info("[%s] %s tag:%u index:%u name:%s profile:%s", client->name,
 | 
				
			||||||
			commands[command].name, tag, sel.id, sel.value, profile_name);
 | 
								commands[command].name, tag, sel.index, sel.value, profile_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((sel.id == SPA_ID_INVALID && sel.value == NULL) ||
 | 
						if ((sel.index == SPA_ID_INVALID && sel.value == NULL) ||
 | 
				
			||||||
	    (sel.id != SPA_ID_INVALID && sel.value != NULL))
 | 
						    (sel.index != SPA_ID_INVALID && sel.value != NULL))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	if (profile_name == NULL)
 | 
						if (profile_name == NULL)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -4502,20 +4515,20 @@ static int do_suspend(struct client *client, uint32_t command, uint32_t tag, str
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_manager_object *o;
 | 
						struct pw_manager_object *o;
 | 
				
			||||||
	const char *name;
 | 
						const char *name;
 | 
				
			||||||
	uint32_t id, cmd;
 | 
						uint32_t index, cmd;
 | 
				
			||||||
	bool sink = command == COMMAND_SUSPEND_SINK, suspend;
 | 
						bool sink = command == COMMAND_SUSPEND_SINK, suspend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (message_get(m,
 | 
						if (message_get(m,
 | 
				
			||||||
			TAG_U32, &id,
 | 
								TAG_U32, &index,
 | 
				
			||||||
			TAG_STRING, &name,
 | 
								TAG_STRING, &name,
 | 
				
			||||||
			TAG_BOOLEAN, &suspend,
 | 
								TAG_BOOLEAN, &suspend,
 | 
				
			||||||
			TAG_INVALID) < 0)
 | 
								TAG_INVALID) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u id:%u name:%s", client->name,
 | 
						pw_log_info("[%s] %s tag:%u index:%u name:%s", client->name,
 | 
				
			||||||
			commands[command].name, tag, id, name);
 | 
								commands[command].name, tag, index, name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((o = find_device(client, id, name, sink, NULL)) == NULL)
 | 
						if ((o = find_device(client, index, name, sink, NULL)) == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (o->proxy == NULL)
 | 
						if (o->proxy == NULL)
 | 
				
			||||||
| 
						 | 
					@ -4532,7 +4545,7 @@ static int do_move_stream(struct client *client, uint32_t command, uint32_t tag,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_manager *manager = client->manager;
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	struct pw_manager_object *o, *dev, *dev_default;
 | 
						struct pw_manager_object *o, *dev, *dev_default;
 | 
				
			||||||
	uint32_t id, id_device;
 | 
						uint32_t index, index_device;
 | 
				
			||||||
	int target_id;
 | 
						int target_id;
 | 
				
			||||||
	const char *name_device;
 | 
						const char *name_device;
 | 
				
			||||||
	struct selector sel;
 | 
						struct selector sel;
 | 
				
			||||||
| 
						 | 
					@ -4540,28 +4553,28 @@ static int do_move_stream(struct client *client, uint32_t command, uint32_t tag,
 | 
				
			||||||
	bool sink = command == COMMAND_MOVE_SINK_INPUT;
 | 
						bool sink = command == COMMAND_MOVE_SINK_INPUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (message_get(m,
 | 
						if (message_get(m,
 | 
				
			||||||
			TAG_U32, &id,
 | 
								TAG_U32, &index,
 | 
				
			||||||
			TAG_U32, &id_device,
 | 
								TAG_U32, &index_device,
 | 
				
			||||||
			TAG_STRING, &name_device,
 | 
								TAG_STRING, &name_device,
 | 
				
			||||||
			TAG_INVALID) < 0)
 | 
								TAG_INVALID) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((id_device == SPA_ID_INVALID && name_device == NULL) ||
 | 
						if ((index_device == SPA_ID_INVALID && name_device == NULL) ||
 | 
				
			||||||
	    (id_device != SPA_ID_INVALID && name_device != NULL))
 | 
						    (index_device != SPA_ID_INVALID && name_device != NULL))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u idx:%u device:%d name:%s", client->name,
 | 
						pw_log_info("[%s] %s tag:%u index:%u device:%d name:%s", client->name,
 | 
				
			||||||
			commands[command].name, tag, id, id_device, name_device);
 | 
								commands[command].name, tag, index, index_device, name_device);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_zero(sel);
 | 
						spa_zero(sel);
 | 
				
			||||||
	sel.id = id;
 | 
						sel.index = index;
 | 
				
			||||||
	sel.type = sink ? pw_manager_object_is_sink_input: pw_manager_object_is_source_output;
 | 
						sel.type = sink ? pw_manager_object_is_sink_input: pw_manager_object_is_source_output;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o = select_object(manager, &sel);
 | 
						o = select_object(manager, &sel);
 | 
				
			||||||
	if (o == NULL)
 | 
						if (o == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((dev = find_device(client, id_device, name_device, sink, NULL)) == NULL)
 | 
						if ((dev = find_device(client, index_device, name_device, sink, NULL)) == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_default = find_device(client, SPA_ID_INVALID, NULL, sink, NULL);
 | 
						dev_default = find_device(client, SPA_ID_INVALID, NULL, sink, NULL);
 | 
				
			||||||
| 
						 | 
					@ -4589,19 +4602,19 @@ static int do_kill(struct client *client, uint32_t command, uint32_t tag, struct
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_manager *manager = client->manager;
 | 
						struct pw_manager *manager = client->manager;
 | 
				
			||||||
	struct pw_manager_object *o;
 | 
						struct pw_manager_object *o;
 | 
				
			||||||
	uint32_t id;
 | 
						uint32_t index;
 | 
				
			||||||
	struct selector sel;
 | 
						struct selector sel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (message_get(m,
 | 
						if (message_get(m,
 | 
				
			||||||
			TAG_U32, &id,
 | 
								TAG_U32, &index,
 | 
				
			||||||
			TAG_INVALID) < 0)
 | 
								TAG_INVALID) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u id:%u", client->name,
 | 
						pw_log_info("[%s] %s tag:%u index:%u", client->name,
 | 
				
			||||||
			commands[command].name, tag, id);
 | 
								commands[command].name, tag, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_zero(sel);
 | 
						spa_zero(sel);
 | 
				
			||||||
	sel.id = id;
 | 
						sel.index = index;
 | 
				
			||||||
	switch (command) {
 | 
						switch (command) {
 | 
				
			||||||
	case COMMAND_KILL_CLIENT:
 | 
						case COMMAND_KILL_CLIENT:
 | 
				
			||||||
		sel.type = pw_manager_object_is_client;
 | 
							sel.type = pw_manager_object_is_client;
 | 
				
			||||||
| 
						 | 
					@ -4632,29 +4645,29 @@ static void handle_module_loaded(struct module *module, struct client *client, u
 | 
				
			||||||
	spa_assert(!SPA_RESULT_IS_ASYNC(result));
 | 
						spa_assert(!SPA_RESULT_IS_ASYNC(result));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (SPA_RESULT_IS_OK(result)) {
 | 
						if (SPA_RESULT_IS_OK(result)) {
 | 
				
			||||||
		pw_log_info("[%s] loaded module id:%u name:%s",
 | 
							pw_log_info("[%s] loaded module index:%u name:%s",
 | 
				
			||||||
				client_name, module->idx, module->name);
 | 
									client_name, module->index, module->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		module->loaded = true;
 | 
							module->loaded = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		broadcast_subscribe_event(impl,
 | 
							broadcast_subscribe_event(impl,
 | 
				
			||||||
			SUBSCRIPTION_MASK_MODULE,
 | 
								SUBSCRIPTION_MASK_MODULE,
 | 
				
			||||||
			SUBSCRIPTION_EVENT_NEW | SUBSCRIPTION_EVENT_MODULE,
 | 
								SUBSCRIPTION_EVENT_NEW | SUBSCRIPTION_EVENT_MODULE,
 | 
				
			||||||
			module->idx);
 | 
								module->index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (client != NULL) {
 | 
							if (client != NULL) {
 | 
				
			||||||
			struct message *reply = reply_new(client, tag);
 | 
								struct message *reply = reply_new(client, tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			message_put(reply,
 | 
								message_put(reply,
 | 
				
			||||||
				TAG_U32, module->idx,
 | 
									TAG_U32, module->index,
 | 
				
			||||||
				TAG_INVALID);
 | 
									TAG_INVALID);
 | 
				
			||||||
			client_queue_message(client, reply);
 | 
								client_queue_message(client, reply);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		pw_log_warn("%p: [%s] failed to load module id:%u name:%s result:%d (%s)",
 | 
							pw_log_warn("%p: [%s] failed to load module index:%u name:%s result:%d (%s)",
 | 
				
			||||||
				impl, client_name,
 | 
									impl, client_name,
 | 
				
			||||||
				module->idx, module->name,
 | 
									module->index, module->name,
 | 
				
			||||||
				result, spa_strerror(result));
 | 
									result, spa_strerror(result));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		module_schedule_unload(module);
 | 
							module_schedule_unload(module);
 | 
				
			||||||
| 
						 | 
					@ -4757,22 +4770,22 @@ static int do_unload_module(struct client *client, uint32_t command, uint32_t ta
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl = client->impl;
 | 
						struct impl *impl = client->impl;
 | 
				
			||||||
	struct module *module;
 | 
						struct module *module;
 | 
				
			||||||
	uint32_t module_idx;
 | 
						uint32_t module_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (message_get(m,
 | 
						if (message_get(m,
 | 
				
			||||||
			TAG_U32, &module_idx,
 | 
								TAG_U32, &module_index,
 | 
				
			||||||
			TAG_INVALID) < 0)
 | 
								TAG_INVALID) < 0)
 | 
				
			||||||
		return -EPROTO;
 | 
							return -EPROTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_info("[%s] %s tag:%u id:%u", client->name,
 | 
						pw_log_info("[%s] %s tag:%u index:%u", client->name,
 | 
				
			||||||
			commands[command].name, tag, module_idx);
 | 
								commands[command].name, tag, module_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (module_idx == SPA_ID_INVALID)
 | 
						if (module_index == SPA_ID_INVALID)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	if ((module_idx & MODULE_FLAG) == 0)
 | 
						if ((module_index & MODULE_FLAG) == 0)
 | 
				
			||||||
		return -EPERM;
 | 
							return -EPERM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	module = pw_map_lookup(&impl->modules, module_idx & MODULE_INDEX_MASK);
 | 
						module = pw_map_lookup(&impl->modules, module_index & MODULE_INDEX_MASK);
 | 
				
			||||||
	if (module == NULL)
 | 
						if (module == NULL)
 | 
				
			||||||
		return -ENOENT;
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,7 @@ struct stream {
 | 
				
			||||||
	uint32_t create_tag;
 | 
						uint32_t create_tag;
 | 
				
			||||||
	uint32_t channel;	/* index in map */
 | 
						uint32_t channel;	/* index in map */
 | 
				
			||||||
	uint32_t id;		/* id of global */
 | 
						uint32_t id;		/* id of global */
 | 
				
			||||||
 | 
						uint32_t index;		/* index */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct impl *impl;
 | 
						struct impl *impl;
 | 
				
			||||||
	struct client *client;
 | 
						struct client *client;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue