pulse-server: add move and default sink/source

Clean up error handling, use errno everywhere and convert when needed.
This commit is contained in:
Wim Taymans 2020-10-29 11:59:16 +01:00
parent 686128a5dd
commit c619d7851f
4 changed files with 433 additions and 404 deletions

View file

@ -81,6 +81,31 @@ enum error_code {
ERR_MAX /**< Not really an error but the first invalid error code */ ERR_MAX /**< Not really an error but the first invalid error code */
}; };
static inline int res_to_err(int res)
{
switch (res) {
case 0: return ERR_OK;
case -EACCES: return ERR_ACCESS;
case -ENOTTY: return ERR_COMMAND;
case -EINVAL: return ERR_INVALID;
case -EEXIST: return ERR_EXIST;
case -ENOENT: return ERR_NOENTITY;
case -ECONNREFUSED: return ERR_CONNECTIONREFUSED;
case -EPROTO: return ERR_PROTOCOL;
case -ETIMEDOUT: return ERR_TIMEOUT;
case -ENOKEY: return ERR_AUTHKEY;
case -ECONNRESET: return ERR_CONNECTIONTERMINATED;
case -EBADFD: return ERR_BADSTATE;
case -ENODATA: return ERR_NODATA;
case -EOVERFLOW: return ERR_TOOLARGE;
case -ENOTSUP: return ERR_NOTSUPPORTED;
case -ENOSYS: return ERR_NOTIMPLEMENTED;
case -EIO: return ERR_IO;
case -EBUSY: return ERR_BUSY;
}
return ERR_UNKNOWN;
}
enum { enum {
/* Generic commands */ /* Generic commands */
COMMAND_ERROR, COMMAND_ERROR,
@ -366,3 +391,7 @@ static uint32_t port_type_value(const char *port_type)
} }
return 0; return 0;
} }
#define METADATA_DEFAULT_SINK "default.audio.sink"
#define METADATA_DEFAULT_SOURCE "default.audio.source"
#define METADATA_TARGET_NODE "target.node"

View file

@ -33,6 +33,8 @@
#define manager_emit_removed(m,o) spa_hook_list_call(&m->hooks, struct pw_manager_events, removed, 0, o) #define manager_emit_removed(m,o) spa_hook_list_call(&m->hooks, struct pw_manager_events, removed, 0, o)
#define manager_emit_metadata(m,s,k,t,v) spa_hook_list_call(&m->hooks, struct pw_manager_events, metadata,0,s,k,t,v) #define manager_emit_metadata(m,s,k,t,v) spa_hook_list_call(&m->hooks, struct pw_manager_events, metadata,0,s,k,t,v)
struct object;
struct manager { struct manager {
struct pw_manager this; struct pw_manager this;
@ -40,6 +42,8 @@ struct manager {
struct spa_hook registry_listener; struct spa_hook registry_listener;
int sync_seq; int sync_seq;
struct object *metadata;
struct spa_hook_list hooks; struct spa_hook_list hooks;
}; };
@ -47,7 +51,8 @@ struct object_info {
const char *type; const char *type;
uint32_t version; uint32_t version;
const void *events; const void *events;
void (*destroy) (void *object); void (*init) (struct object *object);
void (*destroy) (struct object *object);
}; };
struct object { struct object {
@ -131,6 +136,12 @@ static void object_destroy(struct object *o)
free(o); free(o);
} }
/* core */
static const struct object_info core_info = {
.type = PW_TYPE_INTERFACE_Core,
.version = PW_VERSION_CORE,
};
/* client */ /* client */
static void client_event_info(void *object, const struct pw_client_info *info) static void client_event_info(void *object, const struct pw_client_info *info)
{ {
@ -155,9 +166,8 @@ static const struct pw_client_events client_events = {
.info = client_event_info, .info = client_event_info,
}; };
static void client_destroy(void *data) static void client_destroy(struct object *o)
{ {
struct object *o = data;
if (o->this.info) if (o->this.info)
pw_client_info_free(o->this.info); pw_client_info_free(o->this.info);
} }
@ -193,9 +203,8 @@ static const struct pw_module_events module_events = {
.info = module_event_info, .info = module_event_info,
}; };
static void module_destroy(void *data) static void module_destroy(struct object *o)
{ {
struct object *o = data;
if (o->this.info) if (o->this.info)
pw_module_info_free(o->this.info); pw_module_info_free(o->this.info);
} }
@ -257,9 +266,8 @@ static const struct pw_device_events device_events = {
.param = device_event_param, .param = device_event_param,
}; };
static void device_destroy(void *data) static void device_destroy(struct object *o)
{ {
struct object *o = data;
if (o->this.info) if (o->this.info)
pw_device_info_free(o->this.info); pw_device_info_free(o->this.info);
} }
@ -324,9 +332,8 @@ static const struct pw_node_events node_events = {
.param = node_event_param, .param = node_event_param,
}; };
static void node_destroy(void *data) static void node_destroy(struct object *o)
{ {
struct object *o = data;
if (o->this.info) if (o->this.info)
pw_node_info_free(o->this.info); pw_node_info_free(o->this.info);
} }
@ -362,14 +369,31 @@ static const struct pw_metadata_events metadata_events = {
.property = metadata_property, .property = metadata_property,
}; };
static void metadata_init(struct object *o)
{
struct manager *m = o->manager;
if (m->metadata == NULL)
m->metadata = o;
}
static void metadata_destroy(struct object *o)
{
struct manager *m = o->manager;
if (m->metadata == o)
m->metadata = NULL;
}
static const struct object_info metadata_info = { static const struct object_info metadata_info = {
.type = PW_TYPE_INTERFACE_Metadata, .type = PW_TYPE_INTERFACE_Metadata,
.version = PW_VERSION_METADATA, .version = PW_VERSION_METADATA,
.events = &metadata_events, .events = &metadata_events,
.init = metadata_init,
.destroy = metadata_destroy,
}; };
static const struct object_info *objects[] = static const struct object_info *objects[] =
{ {
&core_info,
&module_info, &module_info,
&client_info, &client_info,
&device_info, &device_info,
@ -459,6 +483,9 @@ static void registry_event_global(void *data, uint32_t id,
&o->proxy_listener, &o->proxy_listener,
&proxy_events, o); &proxy_events, o);
if (info->init)
info->init(o);
core_sync(m); core_sync(m);
} }
@ -541,16 +568,32 @@ void pw_manager_add_listener(struct pw_manager *manager,
core_sync(m); core_sync(m);
} }
struct pw_manager_object *pw_manager_find_object(struct pw_manager *manager, int pw_manager_set_metadata(struct pw_manager *manager,
uint32_t id) uint32_t subject, const char *key, const char *type,
const char *format, ...)
{ {
struct manager *m = SPA_CONTAINER_OF(manager, struct manager, this); struct manager *m = SPA_CONTAINER_OF(manager, struct manager, this);
struct object *o; struct object *s;
va_list args;
char buf[1024];
o = find_object(m, id); if ((s = find_object(m, subject)) == NULL)
if (o == NULL) return -ENOENT;
return NULL; if (!SPA_FLAG_IS_SET(s->this.permissions, PW_PERM_M))
return (struct pw_manager_object*)o; return -EACCES;
if (m->metadata == NULL)
return -ENOTSUP;
if (!SPA_FLAG_IS_SET(m->metadata->this.permissions, PW_PERM_W|PW_PERM_X))
return -EACCES;
va_start(args, format);
vsnprintf(buf, sizeof(buf)-1, format, args);
va_end(args);
pw_metadata_set_property(m->metadata->this.proxy,
subject, key, type, buf);
return 0;
} }
int pw_manager_for_each_object(struct pw_manager *manager, int pw_manager_for_each_object(struct pw_manager *manager,

View file

@ -90,6 +90,10 @@ void pw_manager_add_listener(struct pw_manager *manager,
void pw_manager_destroy(struct pw_manager *manager); void pw_manager_destroy(struct pw_manager *manager);
int pw_manager_set_metadata(struct pw_manager *manager,
uint32_t subject, const char *key, const char *type,
const char *format, ...) SPA_PRINTF_FUNC(5,6);
int pw_manager_for_each_object(struct pw_manager *manager, int pw_manager_for_each_object(struct pw_manager *manager,
int (*callback) (void *data, struct pw_manager_object *object), int (*callback) (void *data, struct pw_manager_object *object),
void *data); void *data);

File diff suppressed because it is too large Load diff