From 971aa19546d72ba5e6dc78216a57aa6de0fc1c66 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Sun, 18 Dec 2011 22:14:59 +0100 Subject: Initial support for printing available sources --- src/interface.c | 8 ++++++ src/pa-sink-ctl.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++------- src/pa-sink-ctl.h | 1 + src/sink.h | 6 +++++ 4 files changed, 83 insertions(+), 9 deletions(-) diff --git a/src/interface.c b/src/interface.c index ddd1bb6..c6ec5a1 100644 --- a/src/interface.c +++ b/src/interface.c @@ -157,6 +157,7 @@ void interface_redraw(struct interface *ifc) { struct context *ctx = container_of(ifc, struct context, interface); + gint x, y; werase(ifc->menu_win); box(ifc->menu_win, 0, 0); @@ -169,7 +170,14 @@ interface_redraw(struct interface *ifc) } g_list_foreach(ctx->sink_list, max_name_len_helper, ifc); + g_list_foreach(ctx->source_list, max_name_len_helper, ifc); + g_list_foreach(ctx->sink_list, print_vol_ctl, ifc); + getmaxyx(ifc->menu_win, y, x); + whline(ifc->menu_win, 0, x - 4); + getyx(ifc->menu_win, y, x); + wmove(ifc->menu_win, y + 1, x); + g_list_foreach(ctx->source_list, print_vol_ctl, ifc); wrefresh(ifc->menu_win); } diff --git a/src/pa-sink-ctl.c b/src/pa-sink-ctl.c index 7537e60..1092c38 100644 --- a/src/pa-sink-ctl.c +++ b/src/pa-sink-ctl.c @@ -35,30 +35,29 @@ compare_idx_pntr(gconstpointer i1, gconstpointer i2) } static int -get_sink_priority(struct context *ctx, const pa_sink_info *sink_info) +get_priority(struct context *ctx, pa_proplist *props) { struct priority *p; list_foreach(ctx->config.priorities, p) - if (g_strcmp0(pa_proplist_gets(sink_info->proplist, p->match), - p->value) == 0) + if (g_strcmp0(pa_proplist_gets(props, p->match), p->value) == 0) return p->priority; return 0; } static gchar * -get_sink_name(struct context *ctx, const pa_sink_info *sink) +get_name(struct context *ctx, pa_proplist *props, const char * const fallback) { struct config *cfg = &ctx->config; int i; for (i = 0; cfg->name_props && cfg->name_props[i]; ++i) - if (pa_proplist_contains(sink->proplist, cfg->name_props[i])) - return g_strdup(pa_proplist_gets(sink->proplist, + if (pa_proplist_contains(props, cfg->name_props[i])) + return g_strdup(pa_proplist_gets(props, cfg->name_props[i])); - return g_strdup(sink->name); + return g_strdup(fallback); } static gint @@ -115,7 +114,7 @@ sink_info_cb(pa_context *c, const pa_sink_info *i, sink->base.childs_foreach = sink_childs_foreach; sink->ctx = ctx; - sink->priority = get_sink_priority(ctx, i); + sink->priority = get_priority(ctx, i->proplist); ctx->sink_list = g_list_insert_sorted(ctx->sink_list, sink, compare_sink_priority); } else { @@ -126,7 +125,55 @@ sink_info_cb(pa_context *c, const pa_sink_info *i, sink->base.mute = i->mute; sink->base.vol = pa_cvolume_avg(&i->volume); sink->base.channels = i->volume.channels; - sink->base.name = get_sink_name(ctx, i); + sink->base.name = get_name(ctx, i->proplist, i->name); +} + +static void +source_info_cb(pa_context *c, const pa_source_info *i, + gint is_last, gpointer userdata) +{ + struct context *ctx = userdata; + struct source *source; + GList *el; + + if (is_last < 0) { + if (pa_context_errno(c) == PA_ERR_NOENTITY) + return; + interface_set_status(&ctx->interface, + "Failed to get source information: %s\n", + pa_strerror(pa_context_errno(c))); + return; + } + + if (is_last) { + interface_redraw(&ctx->interface); + return; + } + + el = g_list_find_custom(ctx->source_list, &i->index, compare_idx_pntr); + if (el == NULL) { + source = g_new0(struct source, 1); + if (source == NULL) + return; + source->base.index = i->index; + source->base.mute_set = pa_context_set_source_mute_by_index; + source->base.volume_set = pa_context_set_source_volume_by_index; + //source->base.childs_foreach = source_childs_foreach; + source->ctx = ctx; + + source->priority = get_priority(ctx, i->proplist); + ctx->source_list = g_list_insert_sorted(ctx->source_list, + source, + /*FIXME*/compare_sink_priority); + } else { + source = el->data; + g_free(source->base.name); + } + + source->base.mute = i->mute; + source->base.vol = pa_cvolume_avg(&i->volume); + source->base.channels = i->volume.channels; + source->base.name = get_name(ctx, i->proplist, i->name); } static void @@ -220,6 +267,12 @@ subscribe_cb(pa_context *c, pa_subscription_event_type_t t, ctx); pa_operation_unref(op); break; + case PA_SUBSCRIPTION_EVENT_SOURCE: + op = pa_context_get_source_info_by_index(c, idx, + source_info_cb, + ctx); + pa_operation_unref(op); + break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: op = pa_context_get_sink_input_info(c, idx, sink_input_info_cb, @@ -233,6 +286,9 @@ subscribe_cb(pa_context *c, pa_subscription_event_type_t t, case PA_SUBSCRIPTION_EVENT_SINK: list = &ctx->sink_list; break; + case PA_SUBSCRIPTION_EVENT_SOURCE: + list = &ctx->source_list; + break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: list = &ctx->input_list; break; @@ -271,6 +327,8 @@ context_state_callback(pa_context *c, gpointer userdata) case PA_CONTEXT_READY: op = pa_context_get_sink_info_list(c, sink_info_cb, ctx); pa_operation_unref(op); + op = pa_context_get_source_info_list(c, source_info_cb, ctx); + pa_operation_unref(op); op = pa_context_get_sink_input_info_list(c, sink_input_info_cb, ctx); pa_operation_unref(op); @@ -279,6 +337,7 @@ context_state_callback(pa_context *c, gpointer userdata) { pa_subscription_mask_t mask = PA_SUBSCRIPTION_MASK_SINK | + PA_SUBSCRIPTION_MASK_SOURCE | PA_SUBSCRIPTION_MASK_SINK_INPUT; g_assert((ctx->op = pa_context_subscribe(c, mask, NULL, NULL))); diff --git a/src/pa-sink-ctl.h b/src/pa-sink-ctl.h index e3eebdd..5a58a8a 100644 --- a/src/pa-sink-ctl.h +++ b/src/pa-sink-ctl.h @@ -35,6 +35,7 @@ struct context { GMainLoop *loop; GList *sink_list; + GList *source_list; GList *input_list; struct interface interface; diff --git a/src/sink.h b/src/sink.h index 3a21f6d..e5bfaaa 100644 --- a/src/sink.h +++ b/src/sink.h @@ -55,4 +55,10 @@ struct sink_input { guint32 sink; }; +struct source { + struct vol_ctl base; + gint priority; + struct context *ctx; +}; + #endif -- cgit