summaryrefslogtreecommitdiff
path: root/pipewire-jack
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2020-04-20 11:50:37 +0200
committerWim Taymans <wtaymans@redhat.com>2020-04-20 11:51:20 +0200
commit16ca53e5925e01fb0635731d52af776a315d2cb7 (patch)
treed52cd5f3c6251e8efde2013a554679bb89f4159c /pipewire-jack
parent0b68d65ebffce86372dee8468b1d2a3a01419a3a (diff)
jack: implement get_property
Diffstat (limited to 'pipewire-jack')
-rw-r--r--pipewire-jack/src/metadata.c188
-rw-r--r--pipewire-jack/src/pipewire-jack.c29
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;