Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save saivert/c940cad1745d53f53d2c4f5857d3fb4e to your computer and use it in GitHub Desktop.

Select an option

Save saivert/c940cad1745d53f53d2c4f5857d3fb4e to your computer and use it in GitHub Desktop.
#include <pipewire/pipewire.h>
#include <strings.h>
static int roundtrip(struct pw_core *core, struct pw_main_loop *loop)
{
struct spa_hook core_listener;
int pending, done = 0;
void core_event_done(void *object, uint32_t id, int seq) {
if (id == PW_ID_CORE && seq == pending) {
done = 1;
pw_main_loop_quit(loop);
}
}
const struct pw_core_events core_events = {
PW_VERSION_CORE_EVENTS,
.done = core_event_done,
};
spa_zero(core_listener);
pw_core_add_listener(core, &core_listener,
&core_events, NULL);
pending = pw_core_sync(core, PW_ID_CORE, 0);
while (!done) {
pw_main_loop_run(loop);
}
spa_hook_remove(&core_listener);
return 0;
}
struct proxy_data;
typedef void (*info_func_t) (struct proxy_data *pd);
struct proxy_data {
struct remote_data *rd;
struct global *global;
struct pw_proxy *proxy;
void *info;
info_func_t info_func;
pw_destroy_t destroy;
struct spa_hook proxy_listener;
struct spa_hook object_listener;
};
struct pw_registry *registry;
struct pw_proxy *_proxy;
struct proxy_data *pd;
static void print_properties(struct spa_dict *props, char mark, bool header)
{
const struct spa_dict_item *item;
if (header)
fprintf(stdout, "%c\tproperties:\n", mark);
if (props == NULL || props->n_items == 0) {
if (header)
fprintf(stdout, "\t\tnone\n");
return;
}
spa_dict_for_each(item, props) {
fprintf(stdout, "%c\t\t%s = \"%s\"\n", mark, item->key, item->value);
}
}
static void node_event_info(void *object, const struct pw_node_info *info)
{
struct proxy_data *pd = object;
struct remote_data *rd = pd->rd;
if (pd->info)
fprintf(stdout, "node %d changed\n", info->id);
pd->info = pw_node_info_update(pd->info, info);
print_properties (((struct pw_node_info *)pd->info)->props, ' ', true);
}
static const struct pw_node_events node_events = {
PW_VERSION_NODE_EVENTS,
.info = node_event_info
};
static void registry_event_global(void *data, uint32_t id,
uint32_t permissions, const char *type, uint32_t version,
const struct spa_dict *props)
{
if (!strcmp(type, PW_TYPE_INTERFACE_Node) && props)
{
// const char *media_class;
// media_class = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
// if (media_class && !strcmp(media_class, "Audio/Sink"))
// {
// const char *nick, *name;
// nick = spa_dict_lookup(props, PW_KEY_NODE_NICK);
// name = spa_dict_lookup(props, PW_KEY_NODE_NAME);
// printf("%d: %s: %s\n", id, nick ? nick : "(No Nick)", name ? name : "(No Name)");
// }
const char *name;
name = spa_dict_lookup(props, PW_KEY_NODE_NAME);
if (!strcmp(name, "DeaDBeeF Music Player")) {
_proxy = pw_registry_bind(registry,
id,
type,
PW_VERSION_NODE,
sizeof(struct proxy_data));
pd = pw_proxy_get_user_data(_proxy);
pw_proxy_add_object_listener(_proxy, &pd->object_listener, &node_events, pd);
// struct spa_dict *dict = ((struct pw_node_info *)pd->info)->props;
}
}
// printf("object: id:%u type:%s/%d\n", id, type, version);
// const struct spa_dict_item *item;
// if (props)
// spa_dict_for_each(item, props)
// printf("\t\t%s: \"%s\"\n", item->key, item->value);
}
static const struct pw_registry_events registry_events = {
PW_VERSION_REGISTRY_EVENTS,
.global = registry_event_global,
};
int main(int argc, char *argv[])
{
struct pw_main_loop *loop;
struct pw_context *context;
struct pw_core *core;
struct spa_hook registry_listener;
pw_init(&argc, &argv);
loop = pw_main_loop_new(NULL /* properties */);
context = pw_context_new(pw_main_loop_get_loop(loop),
NULL /* properties */,
0 /* user_data size */);
core = pw_context_connect(context,
NULL /* properties */,
0 /* user_data size */);
registry = pw_core_get_registry(core, PW_VERSION_REGISTRY,
0 /* user_data size */);
spa_zero(registry_listener);
pw_registry_add_listener(registry, &registry_listener,
&registry_events, NULL);
// Very dirty hack to get a few roundtrips so the node events get to fire
roundtrip(core, loop);
roundtrip(core, loop);
roundtrip(core, loop);
roundtrip(core, loop);
// pw_main_loop_run(loop);
pw_proxy_destroy((struct pw_proxy*)registry);
pw_core_disconnect(core);
pw_context_destroy(context);
pw_main_loop_destroy(loop);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment