mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-10-29 05:40:27 -04:00 
			
		
		
		
	pw-cli: add type info to variables
Add type info to variables. This way we can avoid doing things on variables of the wrong type. Add a list-vars command to list the currently registered variables and their type. Fixes #4746
This commit is contained in:
		
							parent
							
								
									b51755bc8b
								
							
						
					
					
						commit
						343509abdf
					
				
					 1 changed files with 101 additions and 20 deletions
				
			
		|  | @ -80,6 +80,16 @@ struct global { | ||||||
| 	struct pw_properties *properties; | 	struct pw_properties *properties; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct var { | ||||||
|  | 	int type; | ||||||
|  | #define TYPE_UNKNOWN	0 | ||||||
|  | #define TYPE_REMOTE	1 | ||||||
|  | #define TYPE_PROXY	2 | ||||||
|  | #define TYPE_MODULE	3 | ||||||
|  | 	uint32_t id; | ||||||
|  | 	void *object; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| struct remote_data { | struct remote_data { | ||||||
| 	struct spa_list link; | 	struct spa_list link; | ||||||
| 	struct data *data; | 	struct data *data; | ||||||
|  | @ -107,6 +117,7 @@ struct proxy_data { | ||||||
| 	const struct class *class; | 	const struct class *class; | ||||||
| 	struct spa_hook proxy_listener; | 	struct spa_hook proxy_listener; | ||||||
| 	struct spa_hook object_listener; | 	struct spa_hook object_listener; | ||||||
|  | 	uint32_t id; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct command { | struct command { | ||||||
|  | @ -116,6 +127,70 @@ struct command { | ||||||
| 	bool (*func) (struct data *data, const char *cmd, char *args, char **error); | 	bool (*func) (struct data *data, const char *cmd, char *args, char **error); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | static uint32_t add_var(struct data *data, void *object, int type) | ||||||
|  | { | ||||||
|  | 	struct var *var; | ||||||
|  | 	if ((var = calloc(1, sizeof(*var))) == NULL) | ||||||
|  | 		return SPA_ID_INVALID; | ||||||
|  | 	var->type = type; | ||||||
|  | 	var->object = object; | ||||||
|  | 	var->id = pw_map_insert_new(&data->vars, var); | ||||||
|  | 	return var->id; | ||||||
|  | } | ||||||
|  | static void *find_var(struct data *data, uint32_t id, int type) | ||||||
|  | { | ||||||
|  | 	struct var *var; | ||||||
|  | 	var = pw_map_lookup(&data->vars, id); | ||||||
|  | 	if (var == NULL || var->type != type) | ||||||
|  | 		return NULL; | ||||||
|  | 	return var->object; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void remove_var(struct data *data, uint32_t id, int type) | ||||||
|  | { | ||||||
|  | 	struct var *var; | ||||||
|  | 	var = pw_map_lookup(&data->vars, id); | ||||||
|  | 	if (var == NULL || var->type != type) | ||||||
|  | 		return; | ||||||
|  | 	pw_map_remove(&data->vars, var->id); | ||||||
|  | 	free(var); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int list_var(void *item_data, void *data) | ||||||
|  | { | ||||||
|  | 	struct var *var = item_data; | ||||||
|  | 	switch (var->type) { | ||||||
|  | 	case TYPE_MODULE: | ||||||
|  | 		printf("%d = @module:%d\n", var->id, pw_global_get_id(pw_impl_module_get_global(var->object))); | ||||||
|  | 		break; | ||||||
|  | 	case TYPE_PROXY: | ||||||
|  | 		printf("%d = @proxy:%d\n", var->id, pw_proxy_get_id(var->object)); | ||||||
|  | 		break; | ||||||
|  | 	case TYPE_REMOTE: | ||||||
|  | 	{ | ||||||
|  | 		struct remote_data *rd = var->object; | ||||||
|  | 		printf("%d = @remote:%p\n", var->id, rd->core); | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void print_var(struct data *data, uint32_t id) | ||||||
|  | { | ||||||
|  | 	struct var *var; | ||||||
|  | 	var = pw_map_lookup(&data->vars, id); | ||||||
|  | 	if (var == NULL) | ||||||
|  | 		return; | ||||||
|  | 	list_var(var, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void list_vars(struct data *data) | ||||||
|  | { | ||||||
|  | 	pw_map_for_each(&data->vars, list_var, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static struct spa_dict * global_props(struct global *global); | static struct spa_dict * global_props(struct global *global); | ||||||
| static struct global * obj_global(struct remote_data *rd, uint32_t id); | static struct global * obj_global(struct remote_data *rd, uint32_t id); | ||||||
| static int children_of(struct remote_data *rd, uint32_t parent_id, | static int children_of(struct remote_data *rd, uint32_t parent_id, | ||||||
|  | @ -170,6 +245,7 @@ static bool do_not_implemented(struct data *data, const char *cmd, char *args, c | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| static bool do_help(struct data *data, const char *cmd, char *args, char **error); | static bool do_help(struct data *data, const char *cmd, char *args, char **error); | ||||||
|  | static bool do_list_vars(struct data *data, const char *cmd, char *args, char **error); | ||||||
| static bool do_load_module(struct data *data, const char *cmd, char *args, char **error); | static bool do_load_module(struct data *data, const char *cmd, char *args, char **error); | ||||||
| static bool do_unload_module(struct data *data, const char *cmd, char *args, char **error); | static bool do_unload_module(struct data *data, const char *cmd, char *args, char **error); | ||||||
| static bool do_list_objects(struct data *data, const char *cmd, char *args, char **error); | static bool do_list_objects(struct data *data, const char *cmd, char *args, char **error); | ||||||
|  | @ -194,6 +270,7 @@ static bool do_quit(struct data *data, const char *cmd, char *args, char **error | ||||||
| 
 | 
 | ||||||
| static const struct command command_list[] = { | static const struct command command_list[] = { | ||||||
| 	{ "help", "h", "Show this help", do_help }, | 	{ "help", "h", "Show this help", do_help }, | ||||||
|  | 	{ "list-vars", "lv", "List all variables", do_list_vars }, | ||||||
| 	{ "load-module", "lm", "Load a module. <module-name> [<module-arguments>]", do_load_module }, | 	{ "load-module", "lm", "Load a module. <module-name> [<module-arguments>]", do_load_module }, | ||||||
| 	{ "unload-module", "um", "Unload a module. <module-var>", do_unload_module }, | 	{ "unload-module", "um", "Unload a module. <module-var>", do_unload_module }, | ||||||
| 	{ "connect", "con", "Connect to a remote. [<remote-name>]", do_connect }, | 	{ "connect", "con", "Connect to a remote. [<remote-name>]", do_connect }, | ||||||
|  | @ -238,6 +315,13 @@ static bool do_help(struct data *data, const char *cmd, char *args, char **error | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static bool do_list_vars(struct data *data, const char *cmd, char *args, char **error) | ||||||
|  | { | ||||||
|  | 	printf("Known variables:\n"); | ||||||
|  | 	list_vars(data); | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static bool do_load_module(struct data *data, const char *cmd, char *args, char **error) | static bool do_load_module(struct data *data, const char *cmd, char *args, char **error) | ||||||
| { | { | ||||||
| 	struct pw_impl_module *module; | 	struct pw_impl_module *module; | ||||||
|  | @ -257,9 +341,9 @@ static bool do_load_module(struct data *data, const char *cmd, char *args, char | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	id = pw_map_insert_new(&data->vars, module); | 	id = add_var(data, module, TYPE_MODULE); | ||||||
| 	if (data->interactive) | 	if (data->interactive) | ||||||
| 		printf("%d = @module:%d\n", id, pw_global_get_id(pw_impl_module_get_global(module))); | 		print_var(data, id); | ||||||
| 
 | 
 | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  | @ -277,12 +361,12 @@ static bool do_unload_module(struct data *data, const char *cmd, char *args, cha | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 	idx = atoi(a[0]); | 	idx = atoi(a[0]); | ||||||
| 	module = pw_map_lookup(&data->vars, idx); | 	module = find_var(data, idx, TYPE_MODULE); | ||||||
| 	if (module == NULL) { | 	if (module == NULL) { | ||||||
| 		*error = spa_aprintf("%s: unknown module '%s'", cmd, a[0]); | 		*error = spa_aprintf("%s: unknown module '%s'", cmd, a[0]); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 	pw_map_remove(&data->vars, idx); | 	remove_var(data, idx, TYPE_MODULE); | ||||||
| 	pw_impl_module_destroy(module); | 	pw_impl_module_destroy(module); | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  | @ -496,7 +580,7 @@ static void on_core_destroy(void *_data) | ||||||
| 	spa_hook_remove(&rd->core_listener); | 	spa_hook_remove(&rd->core_listener); | ||||||
| 	spa_hook_remove(&rd->proxy_core_listener); | 	spa_hook_remove(&rd->proxy_core_listener); | ||||||
| 
 | 
 | ||||||
| 	pw_map_remove(&data->vars, rd->id); | 	remove_var(data, rd->id, TYPE_REMOTE); | ||||||
| 	pw_map_for_each(&rd->globals, destroy_global, rd); | 	pw_map_for_each(&rd->globals, destroy_global, rd); | ||||||
| 	pw_map_clear(&rd->globals); | 	pw_map_clear(&rd->globals); | ||||||
| 
 | 
 | ||||||
|  | @ -539,11 +623,11 @@ static bool do_connect(struct data *data, const char *cmd, char *args, char **er | ||||||
| 	rd->core = core; | 	rd->core = core; | ||||||
| 	rd->data = data; | 	rd->data = data; | ||||||
| 	pw_map_init(&rd->globals, 64, 16); | 	pw_map_init(&rd->globals, 64, 16); | ||||||
| 	rd->id = pw_map_insert_new(&data->vars, rd); | 	rd->id = add_var(data, rd, TYPE_REMOTE); | ||||||
| 	spa_list_append(&data->remotes, &rd->link); | 	spa_list_append(&data->remotes, &rd->link); | ||||||
| 
 | 
 | ||||||
| 	if (rd->data->interactive) | 	if (rd->data->interactive) | ||||||
| 		printf("%d = @remote:%p\n", rd->id, rd->core); | 		print_var(data, rd->id); | ||||||
| 
 | 
 | ||||||
| 	data->current = rd; | 	data->current = rd; | ||||||
| 
 | 
 | ||||||
|  | @ -572,7 +656,7 @@ static bool do_disconnect(struct data *data, const char *cmd, char *args, char * | ||||||
| 	n = pw_split_ip(args, WHITESPACE, 1, a); | 	n = pw_split_ip(args, WHITESPACE, 1, a); | ||||||
| 	if (n >= 1) { | 	if (n >= 1) { | ||||||
| 		idx = atoi(a[0]); | 		idx = atoi(a[0]); | ||||||
| 		rd = pw_map_lookup(&data->vars, idx); | 		rd = find_var(data, idx, TYPE_REMOTE); | ||||||
| 		if (rd == NULL) | 		if (rd == NULL) | ||||||
| 			goto no_remote; | 			goto no_remote; | ||||||
| 
 | 
 | ||||||
|  | @ -614,7 +698,7 @@ static bool do_switch_remote(struct data *data, const char *cmd, char *args, cha | ||||||
| 	if (n == 1) | 	if (n == 1) | ||||||
| 		idx = atoi(a[0]); | 		idx = atoi(a[0]); | ||||||
| 
 | 
 | ||||||
| 	rd = pw_map_lookup(&data->vars, idx); | 	rd = find_var(data, idx, TYPE_REMOTE); | ||||||
| 	if (rd == NULL) | 	if (rd == NULL) | ||||||
| 		goto no_remote; | 		goto no_remote; | ||||||
| 
 | 
 | ||||||
|  | @ -1454,7 +1538,6 @@ static bool do_create_device(struct data *data, const char *cmd, char *args, cha | ||||||
| 	struct remote_data *rd = data->current; | 	struct remote_data *rd = data->current; | ||||||
| 	char *a[2]; | 	char *a[2]; | ||||||
| 	int n; | 	int n; | ||||||
| 	uint32_t id; |  | ||||||
| 	struct pw_proxy *proxy; | 	struct pw_proxy *proxy; | ||||||
| 	struct pw_properties *props = NULL; | 	struct pw_properties *props = NULL; | ||||||
| 	struct proxy_data *pd; | 	struct proxy_data *pd; | ||||||
|  | @ -1484,9 +1567,9 @@ static bool do_create_device(struct data *data, const char *cmd, char *args, cha | ||||||
| 	pw_proxy_add_object_listener(proxy, &pd->object_listener, &device_events, pd); | 	pw_proxy_add_object_listener(proxy, &pd->object_listener, &device_events, pd); | ||||||
| 	pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd); | 	pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd); | ||||||
| 
 | 
 | ||||||
| 	id = pw_map_insert_new(&data->vars, proxy); | 	pd->id = add_var(data, proxy, TYPE_PROXY); | ||||||
| 	if (rd->data->interactive) | 	if (rd->data->interactive) | ||||||
| 		printf("%d = @proxy:%d\n", id, pw_proxy_get_id(proxy)); | 		print_var(data, pd->id); | ||||||
| 
 | 
 | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  | @ -1496,7 +1579,6 @@ static bool do_create_node(struct data *data, const char *cmd, char *args, char | ||||||
| 	struct remote_data *rd = data->current; | 	struct remote_data *rd = data->current; | ||||||
| 	char *a[2]; | 	char *a[2]; | ||||||
| 	int n; | 	int n; | ||||||
| 	uint32_t id; |  | ||||||
| 	struct pw_proxy *proxy; | 	struct pw_proxy *proxy; | ||||||
| 	struct pw_properties *props = NULL; | 	struct pw_properties *props = NULL; | ||||||
| 	struct proxy_data *pd; | 	struct proxy_data *pd; | ||||||
|  | @ -1526,9 +1608,9 @@ static bool do_create_node(struct data *data, const char *cmd, char *args, char | ||||||
| 	pw_proxy_add_object_listener(proxy, &pd->object_listener, &node_events, pd); | 	pw_proxy_add_object_listener(proxy, &pd->object_listener, &node_events, pd); | ||||||
| 	pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd); | 	pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd); | ||||||
| 
 | 
 | ||||||
| 	id = pw_map_insert_new(&data->vars, proxy); | 	pd->id = add_var(data, proxy, TYPE_PROXY); | ||||||
| 	if (rd->data->interactive) | 	if (rd->data->interactive) | ||||||
| 		printf("%d = @proxy:%d\n", id, pw_proxy_get_id(proxy)); | 		printf("%d = @proxy:%d\n", pd->id, pw_proxy_get_id(proxy)); | ||||||
| 
 | 
 | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  | @ -1588,7 +1670,6 @@ obj_global_port(struct remote_data *rd, struct global *global, const char *port_ | ||||||
| static void create_link_with_properties(struct data *data, const struct pw_properties *props) | static void create_link_with_properties(struct data *data, const struct pw_properties *props) | ||||||
| { | { | ||||||
| 	struct remote_data *rd = data->current; | 	struct remote_data *rd = data->current; | ||||||
| 	uint32_t id; |  | ||||||
| 	struct pw_proxy *proxy; | 	struct pw_proxy *proxy; | ||||||
| 	struct proxy_data *pd; | 	struct proxy_data *pd; | ||||||
| 
 | 
 | ||||||
|  | @ -1606,9 +1687,9 @@ static void create_link_with_properties(struct data *data, const struct pw_prope | ||||||
| 	pw_proxy_add_object_listener(proxy, &pd->object_listener, &link_events, pd); | 	pw_proxy_add_object_listener(proxy, &pd->object_listener, &link_events, pd); | ||||||
| 	pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd); | 	pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd); | ||||||
| 
 | 
 | ||||||
| 	id = pw_map_insert_new(&data->vars, proxy); | 	pd->id = add_var(data, proxy, TYPE_PROXY); | ||||||
| 	if (rd->data->interactive) | 	if (rd->data->interactive) | ||||||
| 		printf("%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy)); | 		printf("%d = @proxy:%d\n", pd->id, pw_proxy_get_id((struct pw_proxy*)proxy)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool do_create_link(struct data *data, const char *cmd, char *args, char **error) | static bool do_create_link(struct data *data, const char *cmd, char *args, char **error) | ||||||
|  | @ -1712,7 +1793,7 @@ static bool do_export_node(struct data *data, const char *cmd, char *args, char | ||||||
| 	} | 	} | ||||||
| 	if (n == 2) { | 	if (n == 2) { | ||||||
| 		idx = atoi(a[1]); | 		idx = atoi(a[1]); | ||||||
| 		rd = pw_map_lookup(&data->vars, idx); | 		rd = find_var(data, idx, TYPE_REMOTE); | ||||||
| 		if (rd == NULL) | 		if (rd == NULL) | ||||||
| 			goto no_remote; | 			goto no_remote; | ||||||
| 	} | 	} | ||||||
|  | @ -1729,7 +1810,7 @@ static bool do_export_node(struct data *data, const char *cmd, char *args, char | ||||||
| 	node = pw_global_get_object(global); | 	node = pw_global_get_object(global); | ||||||
| 	proxy = pw_core_export(rd->core, PW_TYPE_INTERFACE_Node, NULL, node, 0); | 	proxy = pw_core_export(rd->core, PW_TYPE_INTERFACE_Node, NULL, node, 0); | ||||||
| 
 | 
 | ||||||
| 	id = pw_map_insert_new(&data->vars, proxy); | 	id = add_var(data, proxy, TYPE_PROXY); | ||||||
| 	if (rd->data->interactive) | 	if (rd->data->interactive) | ||||||
| 		printf("%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy)); | 		printf("%d = @proxy:%d\n", id, pw_proxy_get_id((struct pw_proxy*)proxy)); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Wim Taymans
						Wim Taymans