diff options
author | Wim Taymans <wtaymans@redhat.com> | 2020-04-20 11:50:37 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2020-04-20 11:51:20 +0200 |
commit | 16ca53e5925e01fb0635731d52af776a315d2cb7 (patch) | |
tree | d52cd5f3c6251e8efde2013a554679bb89f4159c /pipewire-jack | |
parent | 0b68d65ebffce86372dee8468b1d2a3a01419a3a (diff) |
jack: implement get_property
Diffstat (limited to 'pipewire-jack')
-rw-r--r-- | pipewire-jack/src/metadata.c | 188 | ||||
-rw-r--r-- | pipewire-jack/src/pipewire-jack.c | 29 |
2 files changed, 180 insertions, 37 deletions
diff --git a/pipewire-jack/src/metadata.c b/pipewire-jack/src/metadata.c index 2cbe6bf6..dafe00e7 100644 --- a/pipewire-jack/src/metadata.c +++ b/pipewire-jack/src/metadata.c @@ -47,12 +47,43 @@ static struct pw_properties * get_properties(void) static void make_key(char *dst, jack_uuid_t subject, const char *key, int keylen) { int len; - jack_uuid_unparse (subject, dst); + jack_uuid_unparse(subject, dst); len = strlen(dst); dst[len] = '@'; memcpy(&dst[len+1], key, keylen+1); } +static int update_property(struct client *c, + jack_uuid_t subject, + const char* key, + const char* value, + const char* type) +{ + int keylen = strlen(key); + char *dst = alloca(JACK_UUID_STRING_SIZE + keylen); + struct pw_properties * props = get_properties(); + jack_property_change_t change; + + make_key(dst, subject, key, keylen); + + if (value == NULL || type == NULL) { + pw_properties_setf(props, dst, NULL); + change = PropertyDeleted; + } else { + change = PropertyCreated; + if (pw_properties_get(props, dst) != NULL) + change = PropertyChanged; + + pw_properties_setf(props, dst, "%s@%s", value, type); + } + + if (c->property_callback) + c->property_callback(subject, key, change, c->property_arg); + + return 0; +} + + SPA_EXPORT int jack_set_property(jack_client_t*client, jack_uuid_t subject, @@ -66,13 +97,19 @@ int jack_set_property(jack_client_t*client, spa_return_val_if_fail(c != NULL, -EINVAL); spa_return_val_if_fail(key != NULL, -EINVAL); spa_return_val_if_fail(value != NULL, -EINVAL); - spa_return_val_if_fail(type != NULL, -EINVAL); + + if (c->metadata == NULL) + return -1; id = jack_uuid_to_index(subject); - pw_log_debug("set id:%u (%lu) '%s' to '%s@%s'", id, subject, key, value, type); + if (type == NULL) + type = ""; + + pw_log_info("set id:%u (%lu) '%s' to '%s@%s'", id, subject, key, value, type); pw_metadata_set_property(c->metadata->proxy, id, key, type, value); + return 0; } @@ -87,6 +124,7 @@ int jack_get_property(jack_uuid_t subject, struct pw_properties * props = get_properties(); const char *str, *at; + spa_return_val_if_fail(props != NULL, -EIO); spa_return_val_if_fail(key != NULL, -EINVAL); spa_return_val_if_fail(value != NULL, -EINVAL); spa_return_val_if_fail(type != NULL, -EINVAL); @@ -109,7 +147,7 @@ int jack_get_property(jack_uuid_t subject, *value = strndup(str, at - str); *type = strdup(at + 1); - pw_log_debug("got '%s' with value:'%s' type:'%s'", dst, *value, *type); + pw_log_info("got '%s' with value:'%s' type:'%s'", dst, *value, *type); return 0; } @@ -117,22 +155,135 @@ int jack_get_property(jack_uuid_t subject, SPA_EXPORT void jack_free_description (jack_description_t* desc, int free_description_itself) { - pw_log_warn("not implemented"); + uint32_t n; + + for (n = 0; n < desc->property_cnt; ++n) { + free((char*)desc->properties[n].key); + free((char*)desc->properties[n].data); + if (desc->properties[n].type) + free((char*)desc->properties[n].type); + } + + free(desc->properties); + + if (free_description_itself) + free(desc); } SPA_EXPORT int jack_get_properties (jack_uuid_t subject, jack_description_t* desc) { - pw_log_warn("not implemented"); - return -1; + const struct spa_dict_item *item; + struct pw_properties * props = get_properties(); + char dst[JACK_UUID_STRING_SIZE+2], *at; + uint32_t props_size, cnt; + int len; + + spa_return_val_if_fail(props != NULL, -EIO); + spa_return_val_if_fail(desc != NULL, -EINVAL); + + jack_uuid_copy(&desc->subject, subject); + desc->properties = NULL; + cnt = props_size = 0; + + jack_uuid_unparse(subject, dst); + len = strlen(dst); + dst[len] = '@'; + dst[len+1] = 0; + + pw_log_debug("keys for: %s", dst); + + spa_dict_for_each(item, &props->dict) { + jack_property_t* prop; + + pw_log_debug("keys %s <-> %s", item->key, dst); + + if (strstr(item->key, dst) != item->key) + continue; + + if (cnt == props_size) { + props_size = props_size > 0 ? props_size * 2 : 8; + desc->properties = realloc(desc->properties, sizeof(jack_property_t) * props_size); + } + prop = &desc->properties[cnt]; + + pw_log_debug("match %s", item->value); + at = strrchr(item->value, '@'); + if (at == NULL) + continue; + + prop->key = strdup(item->key + len + 1); + prop->data = strndup(item->value, at - item->value); + prop->type = strdup(at + 1); + cnt++; + } + desc->property_cnt = cnt; + return cnt; } SPA_EXPORT -int jack_get_all_properties (jack_description_t** descs) +int jack_get_all_properties (jack_description_t** descriptions) { - pw_log_warn("not implemented"); - return -1; + const struct spa_dict_item *item; + struct pw_properties * props = get_properties(); + char *at; + jack_description_t *desc, *cdesc; + uint32_t dsize, dcnt, n, len; + jack_uuid_t uuid; + + spa_return_val_if_fail(props != NULL, -EIO); + spa_return_val_if_fail(descriptions != NULL, -EINVAL); + + dsize = dcnt = 0; + desc = NULL; + + spa_dict_for_each(item, &props->dict) { + jack_property_t* prop; + + at = strrchr(item->key, '@'); + if (at == NULL) + continue; + + len = at - item->key; + + jack_uuid_parse(item->key, &uuid); + + at = strrchr(item->value, '@'); + if (at == NULL) + continue; + + for (n = 0; n < dcnt; n++) { + if (jack_uuid_compare(uuid, desc[n].subject) == 0) + break; + } + if (n == dcnt) { + if (dcnt == dsize) { + dsize = dsize > 0 ? dsize * 2 : 8; + desc = realloc (desc, sizeof(jack_description_t) * dsize); + } + desc[n].property_size = 0; + desc[n].property_cnt = 0; + desc[n].properties = NULL; + + jack_uuid_copy (&desc[n].subject, uuid); + dcnt++; + } + cdesc = &desc[n]; + + if (cdesc->property_cnt == cdesc->property_size) { + cdesc->property_size = cdesc->property_size > 0 ? cdesc->property_size * 2 : 8; + cdesc->properties = realloc (cdesc->properties, + sizeof(jack_property_t) * cdesc->property_size); + } + + prop = &cdesc->properties[cdesc->property_cnt++]; + prop->key = strdup(item->key + len + 1); + prop->data = strndup(item->value, at - item->value); + prop->type = strdup(at + 1); + } + *descriptions = desc; + return dcnt; } SPA_EXPORT @@ -165,8 +316,12 @@ int jack_remove_properties (jack_client_t* client, jack_uuid_t subject) SPA_EXPORT int jack_remove_all_properties (jack_client_t* client) { - pw_log_warn("not implemented"); - return -1; + struct client *c = (struct client *) client; + + spa_return_val_if_fail(c != NULL, -EINVAL); + + pw_metadata_clear(c->metadata->proxy); + return 0; } SPA_EXPORT @@ -174,8 +329,13 @@ int jack_set_property_change_callback (jack_client_t* client, JackPropertyChangeCallback callback, void* arg) { - pw_log_warn("not implemented"); - return -1; + struct client *c = (struct client *) client; + + spa_return_val_if_fail(c != NULL, -EINVAL); + + c->property_callback = callback; + c->property_arg = arg; + return 0; } SPA_EXPORT diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 854d7cbd..ab8b1731 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -333,6 +333,8 @@ struct client { jack_transport_state_t jack_state; }; +static int do_sync(struct client *client); + #include "metadata.c" static void init_port_pool(struct client *c, enum spa_direction direction) @@ -1894,31 +1896,12 @@ static int metadata_property(void *object, uint32_t id, const char *key, const char *type, const char *value) { struct client *c = (struct client *) object; - int keylen = strlen(key); - char *dst = alloca(JACK_UUID_STRING_SIZE + keylen); - struct pw_properties * props = get_properties(); - jack_property_change_t change; jack_uuid_t uuid; - uuid = jack_port_uuid_generate(id); - - make_key(dst, uuid, key, keylen); - - if (value == NULL || type == NULL) { - pw_properties_setf(props, dst, NULL); - change = PropertyDeleted; - } else { - change = PropertyCreated; - if (pw_properties_get(props, dst) != NULL) - change = PropertyChanged; + pw_log_info("set id:%u '%s' to '%s@%s'", id, key, value, type); - pw_properties_setf(props, dst, "%s@%s", value, type); - } - - pw_log_debug("set id:%u '%s' to '%s@%s'", id, dst, value, type); - - if (c->property_callback) - c->property_callback(uuid, key, change, c->property_arg); + uuid = jack_port_uuid_generate(id); + update_property(c, uuid, key, type, value); return 0; } @@ -2081,7 +2064,7 @@ static void registry_event_global(void *data, uint32_t id, c->metadata = pw_proxy_get_user_data(proxy); c->metadata->proxy = (struct pw_metadata*)proxy; - pw_proxy_add_object_listener(proxy, + pw_metadata_add_listener(proxy, &c->metadata->listener, &metadata_events, c); goto exit; |