From ce10176ea73bf6a9db11a503102d4fa9363fc587 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Sun, 18 Dec 2011 22:31:19 +0100 Subject: Initial support for displaying source outputs --- src/command.c | 4 +-- src/interface.c | 3 +++ src/pa-sink-ctl.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/pa-sink-ctl.h | 1 + src/sink.h | 13 +++++++--- 5 files changed, 89 insertions(+), 8 deletions(-) diff --git a/src/command.c b/src/command.c index 425d484..eb671ca 100644 --- a/src/command.c +++ b/src/command.c @@ -89,7 +89,7 @@ volume_change(struct context *ctx, gboolean volume_increment) return; ctl = interface_get_current_ctl(&ctx->interface, NULL); - if (!ctl) + if (!ctl || !ctl->volume_set) return; volume.channels = ctl->channels; @@ -132,7 +132,7 @@ toggle_mute(struct context *ctx, int key) return; ctl = interface_get_current_ctl(&ctx->interface, NULL); - if (!ctl) + if (!ctl && !ctl->mute_set) return; o = ctl->mute_set(ctx->context, ctl->index, !ctl->mute, NULL, NULL); diff --git a/src/interface.c b/src/interface.c index c6ec5a1..f6fdc8a 100644 --- a/src/interface.c +++ b/src/interface.c @@ -105,6 +105,9 @@ print_volume(struct interface *ifc, struct vol_ctl *ctl) { gint vol; + if (!ctl->mute_set || !ctl->volume_set) + return; + allocate_volume_bar(ifc); vol = (gint) (ifc->volume_bar_len * ctl->vol / PA_VOLUME_NORM); wprintw(ifc->menu_win, " [%c][%-*.*s]", diff --git a/src/pa-sink-ctl.c b/src/pa-sink-ctl.c index 1092c38..690368e 100644 --- a/src/pa-sink-ctl.c +++ b/src/pa-sink-ctl.c @@ -128,6 +128,18 @@ sink_info_cb(pa_context *c, const pa_sink_info *i, sink->base.name = get_name(ctx, i->proplist, i->name); } +static void +source_childs_foreach(struct vol_ctl *ctl, GFunc func, gpointer user_data) +{ + struct source *source = (struct source *) ctl; + struct source_output *output; + + list_foreach(source->ctx->output_list, output) + if (output->source == source->base.index) + func(&output->base, user_data); +} + + static void source_info_cb(pa_context *c, const pa_source_info *i, gint is_last, gpointer userdata) @@ -158,7 +170,7 @@ source_info_cb(pa_context *c, const pa_source_info *i, 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->base.childs_foreach = source_childs_foreach; source->ctx = ctx; source->priority = get_priority(ctx, i->proplist); @@ -226,6 +238,52 @@ sink_input_info_cb(pa_context *c, const pa_sink_input_info *i, sink_input->base.vol = pa_cvolume_avg(&i->volume); } +static void +source_output_info_cb(pa_context *c, const pa_source_output_info *i, + gint is_last, gpointer userdata) +{ + struct context *ctx = userdata; + struct source_output *source_output; + GList *el; + + if (is_last < 0) { + if (pa_context_errno(c) == PA_ERR_NOENTITY) + return; + interface_set_status(&ctx->interface, + "Failed to get source output info: %s\n", + pa_strerror(pa_context_errno(c))); + return; + } + + if (is_last) { + interface_redraw(&ctx->interface); + return; + } + + if (!(i->client != PA_INVALID_INDEX)) return; + + el = g_list_find_custom(ctx->output_list, &i->index, compare_idx_pntr); + if (el == NULL) { + source_output = g_new0(struct source_output, 1); + if (source_output == NULL) + return; + source_output->base.index = i->index; + source_output->base.indent = 1; + source_output->base.hide_index = TRUE; + ctx->output_list = g_list_append(ctx->output_list, + source_output); + } else { + source_output = el->data; + g_free(source_output->base.name); + } + + source_output->source = i->source; + source_output->base.name = + pa_proplist_contains(i->proplist, "application.name") ? + g_strdup(pa_proplist_gets(i->proplist, "application.name")) : + g_strdup(i->name); +} + static void vol_ctl_free(gpointer data) { @@ -279,6 +337,12 @@ subscribe_cb(pa_context *c, pa_subscription_event_type_t t, ctx); pa_operation_unref(op); break; + case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: + op = pa_context_get_source_output_info(c, idx, + source_output_info_cb, + ctx); + pa_operation_unref(op); + break; } break; case PA_SUBSCRIPTION_EVENT_REMOVE: @@ -292,6 +356,9 @@ subscribe_cb(pa_context *c, pa_subscription_event_type_t t, case PA_SUBSCRIPTION_EVENT_SINK_INPUT: list = &ctx->input_list; break; + case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: + list = &ctx->output_list; + break; default: return; } @@ -332,13 +399,18 @@ context_state_callback(pa_context *c, gpointer userdata) op = pa_context_get_sink_input_info_list(c, sink_input_info_cb, ctx); pa_operation_unref(op); + op = pa_context_get_source_output_info_list(c, + source_output_info_cb, + ctx); + pa_operation_unref(op); pa_context_set_subscribe_callback(c, subscribe_cb, ctx); { pa_subscription_mask_t mask = PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE | - PA_SUBSCRIPTION_MASK_SINK_INPUT; + PA_SUBSCRIPTION_MASK_SINK_INPUT | + PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT; 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 5a58a8a..b994a2b 100644 --- a/src/pa-sink-ctl.h +++ b/src/pa-sink-ctl.h @@ -37,6 +37,7 @@ struct context { GList *sink_list; GList *source_list; GList *input_list; + GList *output_list; struct interface interface; struct config config; diff --git a/src/sink.h b/src/sink.h index e5bfaaa..d3a9362 100644 --- a/src/sink.h +++ b/src/sink.h @@ -27,14 +27,14 @@ struct context; struct vol_ctl { guint32 index; - pa_volume_t vol; // TOTO: exchange with the channel-list - gint mute; - guint8 channels; - gchar *name; /* displayed name */ gint indent; /* indentation when displayed */ gboolean hide_index; + pa_volume_t vol; // TOTO: exchange with the channel-list + gint mute; + guint8 channels; + pa_operation *(*mute_set)(pa_context *, guint32, int, pa_context_success_cb_t, void *); @@ -55,6 +55,11 @@ struct sink_input { guint32 sink; }; +struct source_output { + struct vol_ctl base; + guint32 source; +}; + struct source { struct vol_ctl base; gint priority; -- cgit