From e9f4a40262232e5687711c6325421cfd4c69065f Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Mon, 19 Dec 2011 09:00:01 +0100 Subject: Implement "down" for both sink and source list --- src/command.c | 34 ++++++++++++++++++++++------------ src/interface.c | 51 +++++++++++++++++++++++++++++++++++++++++---------- src/pa-sink-ctl.c | 2 ++ src/sink.h | 15 +++++++++++++++ 4 files changed, 80 insertions(+), 22 deletions(-) diff --git a/src/command.c b/src/command.c index eb671ca..a883685 100644 --- a/src/command.c +++ b/src/command.c @@ -25,13 +25,13 @@ #include "command.h" static int -sink_input_len(struct context *ctx, struct sink *sink) +main_ctl_childs_len(struct context *ctx, struct main_ctl *ctl) { - struct sink_input *input; + struct slave_ctl *sctl; int len = 0; - list_foreach(ctx->input_list, input) - if (input->sink == sink->base.index) + list_foreach(*ctl->childs_list, sctl) + if (sctl->parent_index == ctl->base.index) len++; return len; @@ -50,7 +50,7 @@ up(struct context *ctx, int key) ifc->chooser_sink > 0) { sink = g_list_nth_data(ctx->sink_list, --ifc->chooser_sink); /* autoassigment to SELECTED_SINK (=-1) if length = 0 */ - ifc->chooser_input = sink_input_len(ctx, sink) - 1; + ifc->chooser_input = main_ctl_childs_len(ctx, (struct main_ctl *) sink) - 1; } else if (ifc->chooser_input >= 0) --ifc->chooser_input; @@ -61,17 +61,27 @@ static void down(struct context *ctx, int key) { struct interface *ifc = &ctx->interface; - struct sink *sink; + int max_input; + struct vol_ctl *ctl, *parent; + int max_len; if (!ctx->context_ready) return; - sink = g_list_nth_data(ctx->sink_list, ifc->chooser_sink); - if (ifc->chooser_input == (sink_input_len(ctx, sink) - 1) && - ifc->chooser_sink < (gint) g_list_length(ctx->sink_list)-1) { - ++ifc->chooser_sink; - ifc->chooser_input = SELECTED_SINK; - } else if (ifc->chooser_input < (sink_input_len(ctx, sink) - 1)) + max_len = g_list_length(ctx->sink_list) + g_list_length(ctx->source_list); + + ctl = interface_get_current_ctl(&ctx->interface, &parent); + if (parent) + ctl = parent; + + max_input = main_ctl_childs_len(ctx, (struct main_ctl *) ctl) -1; + + if (ifc->chooser_input == max_input) { + if (ifc->chooser_sink < max_len -1) { + ++ifc->chooser_sink; + ifc->chooser_input = SELECTED_SINK; + } + } else if (ifc->chooser_input < max_input) ++ifc->chooser_input; interface_redraw(ifc); diff --git a/src/interface.c b/src/interface.c index f6fdc8a..3247aaa 100644 --- a/src/interface.c +++ b/src/interface.c @@ -54,29 +54,60 @@ sink_get_nth_input(struct context *ctx, struct sink *sink, int n) return NULL; } +static struct source_output * +source_get_nth_output(struct context *ctx, struct source *source, int n) +{ + struct source_output *output; + int i = 0; + + list_foreach(ctx->output_list, output) { + if (output->source != source->base.index) + continue; + if (i++ == n) + return output; + } + + return NULL; +} + struct vol_ctl * interface_get_current_ctl(struct interface *ifc, struct vol_ctl **parent) { struct context *ctx = container_of(ifc, struct context, interface); - struct sink *sink; + struct vol_ctl *main_ctl, *ctl; struct sink_input *input; + struct source_output *output; + int is_sink = 1; if (parent) *parent = NULL; - sink = g_list_nth_data(ctx->sink_list, ifc->chooser_sink); - if (sink == NULL) - return NULL; + main_ctl = g_list_nth_data(ctx->sink_list, ifc->chooser_sink); + if (main_ctl == NULL) { + main_ctl = g_list_nth_data(ctx->source_list, + ifc->chooser_sink - g_list_length(ctx->sink_list)); + is_sink = 0; + if (main_ctl == NULL) + return NULL; + } if (ifc->chooser_input == SELECTED_SINK) - return &sink->base; + return main_ctl; else if (ifc->chooser_input >= 0) { - input = sink_get_nth_input(ctx, sink, ifc->chooser_input); - if (input == NULL) - return NULL; + if (is_sink) { + input = sink_get_nth_input(ctx, (struct sink *) main_ctl, ifc->chooser_input); + if (input == NULL) + return NULL; + ctl = &input->base; + } else { + output = source_get_nth_output(ctx, (struct source *) main_ctl, ifc->chooser_input); + if (output == NULL) + return NULL; + ctl = &output->base; + } if (parent) - *parent = &sink->base; - return &input->base; + *parent = main_ctl; + return ctl; } g_assert(0); diff --git a/src/pa-sink-ctl.c b/src/pa-sink-ctl.c index 690368e..38a5913 100644 --- a/src/pa-sink-ctl.c +++ b/src/pa-sink-ctl.c @@ -113,6 +113,7 @@ sink_info_cb(pa_context *c, const pa_sink_info *i, sink->base.volume_set = pa_context_set_sink_volume_by_index; sink->base.childs_foreach = sink_childs_foreach; sink->ctx = ctx; + sink->childs_list = &ctx->input_list; sink->priority = get_priority(ctx, i->proplist); ctx->sink_list = g_list_insert_sorted(ctx->sink_list, sink, @@ -172,6 +173,7 @@ source_info_cb(pa_context *c, const pa_source_info *i, source->base.volume_set = pa_context_set_source_volume_by_index; source->base.childs_foreach = source_childs_foreach; source->ctx = ctx; + source->childs_list = &ctx->output_list; source->priority = get_priority(ctx, i->proplist); ctx->source_list = g_list_insert_sorted(ctx->source_list, diff --git a/src/sink.h b/src/sink.h index d3a9362..15c51c9 100644 --- a/src/sink.h +++ b/src/sink.h @@ -44,10 +44,19 @@ struct vol_ctl { void (*childs_foreach)(struct vol_ctl *ctx, GFunc func, gpointer udata); }; +struct main_ctl { + struct vol_ctl base; + gint priority; + struct context *ctx; + + GList **childs_list; +}; + struct sink { struct vol_ctl base; gint priority; struct context *ctx; + GList **childs_list; }; struct sink_input { @@ -55,6 +64,11 @@ struct sink_input { guint32 sink; }; +struct slave_ctl { + struct vol_ctl base; + guint32 parent_index; +}; + struct source_output { struct vol_ctl base; guint32 source; @@ -64,6 +78,7 @@ struct source { struct vol_ctl base; gint priority; struct context *ctx; + GList **childs_list; }; #endif -- cgit