diff --git a/src/metadata.c b/src/metadata.c index 2dac2c3e8..8ec3b212b 100644 --- a/src/metadata.c +++ b/src/metadata.c @@ -26,9 +26,29 @@ #include #include +#include #include + +static struct pw_properties * get_properties(void) +{ + static struct pw_properties *properties = NULL; + if (properties == NULL) { + properties = pw_properties_new(NULL, NULL); + } + return properties; +} + +static void make_key(char *dst, jack_uuid_t subject, const char *key, int keylen) +{ + int len; + jack_uuid_unparse (subject, dst); + len = strlen(dst); + dst[len] = '@'; + memcpy(&dst[len+1], key, keylen+1); +} + SPA_EXPORT int jack_set_property(jack_client_t*client, jack_uuid_t subject, @@ -36,8 +56,16 @@ int jack_set_property(jack_client_t*client, const char* value, const char* type) { - pw_log_warn("not implemented"); - return -1; + int keylen = strlen(key); + char *dst = alloca(JACK_UUID_STRING_SIZE + keylen); + struct pw_properties * props = get_properties(); + + make_key(dst, subject, key, keylen); + + pw_properties_setf(props, dst, "%s@%s", value, type); + pw_log_debug("set '%s' to '%s@%s'", dst, value, type); + + return 0; } SPA_EXPORT @@ -46,8 +74,30 @@ int jack_get_property(jack_uuid_t subject, char** value, char** type) { - pw_log_warn("not implemented"); - return -1; + int keylen = strlen(key); + char *dst = alloca(JACK_UUID_STRING_SIZE + keylen); + struct pw_properties * props = get_properties(); + const char *str, *at; + + make_key(dst, subject, key, keylen); + + if ((str = pw_properties_get(props, dst)) == NULL) { + pw_log_warn("no property '%s'", dst); + return -1; + } + + at = strrchr(str, '@'); + if (at == NULL) { + pw_log_warn("property '%s' invalid value '%s'", dst, str); + return -1; + } + + *value = strndup(str, at - str); + *type = strdup(at + 1); + + pw_log_debug("got '%s' with value:'%s' type:'%s'", dst, *value, *type); + + return 0; } SPA_EXPORT @@ -74,8 +124,16 @@ int jack_get_all_properties (jack_description_t** descs) SPA_EXPORT int jack_remove_property (jack_client_t* client, jack_uuid_t subject, const char* key) { - pw_log_warn("not implemented"); - return -1; + int keylen = strlen(key); + char *dst = alloca(JACK_UUID_STRING_SIZE + keylen); + struct pw_properties * props = get_properties(); + + make_key(dst, subject, key, keylen); + + pw_properties_set(props, dst, NULL); + pw_log_debug("removed %s", dst); + + return 0; } SPA_EXPORT diff --git a/src/pipewire-jack.c b/src/pipewire-jack.c index f94ea5c52..8b9312e5e 100644 --- a/src/pipewire-jack.c +++ b/src/pipewire-jack.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -89,7 +90,6 @@ struct object { uint32_t type; uint32_t id; - uint32_t parent_id; union { struct { @@ -105,6 +105,7 @@ struct object { char alias1[REAL_JACK_PORT_NAME_SIZE+1]; char alias2[REAL_JACK_PORT_NAME_SIZE+1]; uint32_t type_id; + uint32_t node_id; uint32_t port_id; } port; }; @@ -372,7 +373,7 @@ static struct port * alloc_port(struct client *c, enum spa_direction direction) o = alloc_object(c); o->type = PW_TYPE_INTERFACE_Port; o->id = SPA_ID_INVALID; - o->parent_id = c->node_id; + o->port.node_id = c->node_id; o->port.port_id = p->id; spa_list_append(&c->context.ports, &o->link); @@ -738,9 +739,10 @@ on_rtsocket_condition(void *data, int fd, uint32_t mask) &c->jack_position, c->sync_arg); } - pw_log_trace(NAME" %p: do process %"PRIu64" %d %d %d %"PRIi64" %f", c, + pw_log_trace(NAME" %p: do process %"PRIu64" %d %d %d %"PRIi64" %f %p", c, nsec, c->buffer_size, c->sample_rate, - c->jack_position.frame, delay, c->rate_diff); + c->jack_position.frame, delay, c->rate_diff, + c->position); if (c->process_callback) c->process_callback(c->buffer_size, c->process_arg); @@ -1463,7 +1465,6 @@ static void registry_event_global(void *data, uint32_t id, struct object *o, *ot; const char *str; size_t size; - uint32_t parent_id = 0; if (props == NULL) return; @@ -1488,6 +1489,7 @@ static void registry_event_global(void *data, uint32_t id, const struct spa_dict_item *item; unsigned long flags = 0; jack_port_type_id_t type_id; + uint32_t node_id; char full_name[1024]; if ((str = spa_dict_lookup(props, PW_KEY_FORMAT_DSP)) == NULL) { @@ -1500,7 +1502,7 @@ static void registry_event_global(void *data, uint32_t id, if ((str = spa_dict_lookup(props, PW_KEY_NODE_ID)) == NULL) goto exit; - parent_id = atoi(str); + node_id = atoi(str); if ((str = spa_dict_lookup(props, PW_KEY_PORT_NAME)) == NULL) goto exit; @@ -1527,7 +1529,7 @@ static void registry_event_global(void *data, uint32_t id, } o = NULL; - if (parent_id == c->node_id) { + if (node_id == c->node_id) { snprintf(full_name, sizeof(full_name), "%s:%s", c->name, str); o = find_port(c, full_name); if (o != NULL) @@ -1539,7 +1541,7 @@ static void registry_event_global(void *data, uint32_t id, goto exit; spa_list_append(&c->context.ports, &o->link); - ot = pw_map_lookup(&c->context.globals, parent_id); + ot = pw_map_lookup(&c->context.globals, node_id); if (ot == NULL || ot->type != PW_TYPE_INTERFACE_Node) goto exit_free; @@ -1559,6 +1561,7 @@ static void registry_event_global(void *data, uint32_t id, o->port.flags = flags; o->port.type_id = type_id; + o->port.node_id = node_id; pw_log_debug(NAME" %p: add port %d %s %d", c, id, o->port.name, type_id); break; @@ -1585,7 +1588,6 @@ static void registry_event_global(void *data, uint32_t id, o->type = type; o->id = id; - o->parent_id = parent_id; size = pw_map_get_size(&c->context.globals); while (id > size) @@ -1867,11 +1869,24 @@ char * jack_get_client_name (jack_client_t *client) return c->name; } +static jack_uuid_t cuuid = 0x2; + SPA_EXPORT char *jack_get_uuid_for_client_name (jack_client_t *client, const char *client_name) { - pw_log_warn(NAME" %p: not implemented %s", client, client_name); + struct client *c = (struct client *) client; + struct object *o; + + spa_list_for_each(o, &c->context.nodes, link) { + if (strcmp(o->node.name, client_name) == 0) { + char *uuid; + asprintf(&uuid, "%" PRIu64, (cuuid << 32) | o->id); + pw_log_debug(NAME" %p: name %s -> %s", + client, client_name, uuid); + return uuid; + } + } return NULL; } @@ -1879,7 +1894,21 @@ SPA_EXPORT char *jack_get_client_name_by_uuid (jack_client_t *client, const char *client_uuid ) { - pw_log_warn(NAME" %p: not implemented %s", client, client_uuid); + struct client *c = (struct client *) client; + struct object *o; + jack_uuid_t uuid; + jack_uuid_t cuuid = 0x2; + + if (jack_uuid_parse(client_uuid, &uuid) < 0) + return NULL; + + spa_list_for_each(o, &c->context.nodes, link) { + if ((cuuid << 32 | o->id) == uuid) { + pw_log_debug(NAME" %p: uuid %s (%"PRIu64")-> %s", + client, client_uuid, uuid, o->node.name); + return strdup(o->node.name); + } + } return NULL; } @@ -2436,8 +2465,8 @@ void * jack_port_get_buffer (jack_port_t *port, jack_nframes_t frames) SPA_EXPORT jack_uuid_t jack_port_uuid (const jack_port_t *port) { - pw_log_warn("not implemented %p", port); - return 0; + struct object *o = (struct object *) port; + return jack_port_uuid_generate(o->id); } SPA_EXPORT @@ -2699,9 +2728,9 @@ int jack_connect (jack_client_t *client, goto exit; } - snprintf(val[0], sizeof(val[0]), "%d", src->parent_id); + snprintf(val[0], sizeof(val[0]), "%d", src->port.node_id); snprintf(val[1], sizeof(val[1]), "%d", src->id); - snprintf(val[2], sizeof(val[2]), "%d", dst->parent_id); + snprintf(val[2], sizeof(val[2]), "%d", dst->port.node_id); snprintf(val[3], sizeof(val[3]), "%d", dst->id); props = SPA_DICT_INIT(items, 0); @@ -2897,7 +2926,7 @@ const char ** jack_get_ports (jack_client_t *client, continue; if (!SPA_FLAG_CHECK(o->port.flags, flags)) continue; - if (id != SPA_ID_INVALID && o->parent_id != id) + if (id != SPA_ID_INVALID && o->port.node_id != id) continue; if (port_name_pattern && port_name_pattern[0]) { @@ -3184,8 +3213,10 @@ void jack_session_event_free (jack_session_event_t *event) SPA_EXPORT char *jack_client_get_uuid (jack_client_t *client) { - pw_log_warn(NAME" %p: not implemented", client); - return ""; + struct client *c = (struct client *) client; + char *uuid = NULL; + asprintf(&uuid, "%d", c->node_id); + return uuid; } SPA_EXPORT diff --git a/src/uuid.c b/src/uuid.c index db2db86e7..f49e52bc6 100644 --- a/src/uuid.c +++ b/src/uuid.c @@ -32,59 +32,69 @@ SPA_EXPORT jack_uuid_t jack_client_uuid_generate () { - pw_log_warn("not implemented"); - return 0; + static uint32_t uuid_cnt = 0; + jack_uuid_t uuid = 0x2; /* JackUUIDClient */; + uuid = (uuid << 32) | ++uuid_cnt; + return uuid; } SPA_EXPORT jack_uuid_t jack_port_uuid_generate (uint32_t port_id) { - pw_log_warn("not implemented"); - return 0; + jack_uuid_t uuid = 0x1; /* JackUUIDPort */ + uuid = (uuid << 32) | (port_id + 1); + return uuid; } SPA_EXPORT uint32_t jack_uuid_to_index (jack_uuid_t id) { - pw_log_warn("not implemented"); - return 0; + return (id & 0xffff) - 1; } SPA_EXPORT int jack_uuid_compare (jack_uuid_t id1, jack_uuid_t id2) { - pw_log_warn("not implemented"); - return 0; + if (id1 == id2) + return 0; + if (id1 < id2) + return -1; + return 1; } SPA_EXPORT void jack_uuid_copy (jack_uuid_t* dst, jack_uuid_t src) { - pw_log_warn("not implemented"); + *dst = src; } SPA_EXPORT -void jack_uuid_clear (jack_uuid_t*id) +void jack_uuid_clear (jack_uuid_t *id) { - pw_log_warn("not implemented"); + *id = 0; } SPA_EXPORT -int jack_uuid_parse (const char *buf, jack_uuid_t*id) +int jack_uuid_parse (const char *buf, jack_uuid_t *id) { - pw_log_warn("not implemented"); - return 0; + if (sscanf (buf, "%" PRIu64, id) == 1) { + if (*id < (0x1LL << 32)) { + /* has not type bits set - not legal */ + return -1; + } + return 0; + } + return -1; } SPA_EXPORT void jack_uuid_unparse (jack_uuid_t id, char buf[JACK_UUID_STRING_SIZE]) { - pw_log_warn("not implemented"); + snprintf (buf, JACK_UUID_STRING_SIZE, "%" PRIu64, id); } SPA_EXPORT int jack_uuid_empty (jack_uuid_t id) { - pw_log_warn("not implemented"); - return 0; + return id == 0; }