summaryrefslogtreecommitdiff
path: root/src/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/command.c')
-rw-r--r--src/command.c142
1 files changed, 70 insertions, 72 deletions
diff --git a/src/command.c b/src/command.c
index 3b399dc..1b90c60 100644
--- a/src/command.c
+++ b/src/command.c
@@ -24,26 +24,43 @@
#include "ctl.h"
#include "command.h"
+static struct vol_ctl *
+ctl_last_child_or_ctl(struct vol_ctl *ctl)
+{
+ int len;
+
+ if (ctl->childs_len && (len = ctl->childs_len(ctl)) > 0)
+ return ctl->get_nth_child(ctl, len-1);
+
+ return ctl;
+}
+
static void
up(struct context *ctx, int key)
{
struct interface *ifc = &ctx->interface;
- struct main_ctl *ctl = NULL;
+ struct vol_ctl *ctl, *prev;
+ GList *last;
if (!ctx->context_ready)
return;
- if (ifc->chooser_child == SELECTED_MAIN_CTL &&
- ifc->chooser_main_ctl > 0) {
+ ctl = ifc->current_ctl;
+ if (ctl == NULL)
+ return;
- --ifc->chooser_main_ctl;
- /* Always a main_ctl since chooser_child = SELECTED_MAIN_CTL */
- ctl = (struct main_ctl *) interface_get_current_ctl(ifc, NULL);
+ prev = ctl->prev_ctl(ctl);
+ if (prev) {
+ ifc->current_ctl = ctl_last_child_or_ctl(prev);
+ } else if (ctl->get_parent) {
+ ifc->current_ctl = ctl->get_parent(ctl);
+ } else {
+ struct main_ctl *mctl = (struct main_ctl *) ctl;
- /* autoassigment to SELECTED_MAIN_CTL (=-1) if length = 0 */
- ifc->chooser_child = ctl->base.childs_len(&ctl->base) - 1;
- } else if (ifc->chooser_child >= 0)
- --ifc->chooser_child;
+ if (*mctl->list == ctx->source_list &&
+ (last = g_list_last(ctx->sink_list)) != NULL)
+ ifc->current_ctl = ctl_last_child_or_ctl(last->data);
+ }
interface_redraw(ifc);
}
@@ -52,33 +69,38 @@ static void
down(struct context *ctx, int key)
{
struct interface *ifc = &ctx->interface;
- int max_ctl_childs;
- struct vol_ctl *ctl, *parent;
+ struct vol_ctl *ctl, *next = NULL, *tmp, *parent;
if (!ctx->context_ready)
return;
- ctl = interface_get_current_ctl(&ctx->interface, &parent);
- if (ctl == NULL) {
- ifc->chooser_child = SELECTED_MAIN_CTL;
- ctl = interface_get_current_ctl(&ctx->interface, &parent);
- if (ctl == NULL)
- return;
+ ctl = ifc->current_ctl;
+ if (ctl == NULL)
+ return;
+
+ if (ctl->childs_len && ctl->childs_len(ctl) > 0) {
+ next = ctl->get_nth_child(ctl, 0);
+ } else if ((tmp = ctl->next_ctl(ctl)) != NULL) {
+ next = tmp;
+ } else if (ctl->get_parent) {
+ parent = ctl->get_parent(ctl);
+ next = parent->next_ctl(parent);
+ if (!next)
+ ctl = parent; /* parent for end-of-sink list lookup */
}
- if (parent)
- ctl = parent;
-
- max_ctl_childs = ctl->childs_len(ctl) -1;
- if (ifc->chooser_child == max_ctl_childs) {
- if (ifc->chooser_main_ctl <
- interface_get_main_ctl_length(ifc) -1) {
- ++ifc->chooser_main_ctl;
- ifc->chooser_child = SELECTED_MAIN_CTL;
- }
- } else if (ifc->chooser_child < max_ctl_childs)
- ++ifc->chooser_child;
- interface_redraw(ifc);
+ if (!next) {
+ struct main_ctl *mctl = (struct main_ctl *) ctl;
+
+ if (*mctl->list == ctx->sink_list &&
+ g_list_first(ctx->source_list) != NULL)
+ next = g_list_first(ctx->source_list)->data;
+ }
+
+ if (next) {
+ ifc->current_ctl = next;
+ interface_redraw(ifc);
+ }
}
static void
@@ -92,7 +114,7 @@ volume_change(struct context *ctx, gboolean volume_increment)
if (!ctx->context_ready)
return;
- ctl = interface_get_current_ctl(&ctx->interface, NULL);
+ ctl = ctx->interface.current_ctl;
if (!ctl || !ctl->volume_set)
return;
@@ -135,7 +157,7 @@ toggle_mute(struct context *ctx, int key)
if (!ctx->context_ready)
return;
- ctl = interface_get_current_ctl(&ctx->interface, NULL);
+ ctl = ctx->interface.current_ctl;
if (!ctl && !ctl->mute_set)
return;
@@ -146,57 +168,33 @@ toggle_mute(struct context *ctx, int key)
static void
switch_sink(struct context *ctx, int key)
{
- struct interface *ifc = &ctx->interface;
- struct slave_ctl *t;
- struct vol_ctl *cslave, *cparent;
- struct main_ctl *mcparent;
+ struct vol_ctl *cslave;
+ struct main_ctl *mcparent, *ctl;
pa_operation *o;
- gint i;
- GList **list;
- int offset;
+ GList *el;
if (!ctx->context_ready)
return;
- cslave = interface_get_current_ctl(&ctx->interface, &cparent);
- if (!cslave || !cparent)
+ cslave = ctx->interface.current_ctl;
+ if (!cslave || !cslave->get_parent)
return;
- mcparent = (struct main_ctl *) cparent;
- if (*mcparent->childs_list == ctx->input_list) {
- list = &ctx->sink_list;
- offset = 0;
- } else {
- list = &ctx->source_list;
- offset = g_list_length(ctx->sink_list);
- }
-
- if (g_list_length(*list) <= 1)
+ mcparent = (struct main_ctl *) cslave->get_parent(cslave);
+ if (g_list_length(*mcparent->list) <= 1)
return;
- if (ifc->chooser_main_ctl < (gint) (offset + g_list_length(*list) - 1))
- ifc->chooser_main_ctl++;
+ el = g_list_find(*mcparent->list, mcparent);
+ g_assert(el != NULL);
+ if (el->next)
+ el = el->next;
else
- ifc->chooser_main_ctl = offset;
+ el = g_list_first(*mcparent->list);
- mcparent = g_list_nth_data(*list, ifc->chooser_main_ctl - offset);
- /* chooser_child needs to be derived from $selected_index */
- o = mcparent->move_child(ctx->context,
- cslave->index, mcparent->base.index,
- NULL, NULL);
+ ctl = el->data;
+ o = ctl->move_child(ctx->context,
+ cslave->index, ctl->base.index, NULL, NULL);
pa_operation_unref(o);
-
- /* get new chooser_child, if non, select sink as fallback */
- ifc->chooser_child = SELECTED_MAIN_CTL;
- i = -1;
- list_foreach(*mcparent->childs_list, t) {
- if (t->base.index == cslave->index) {
- ifc->chooser_child = ++i;
- break;
- }
- if (t->parent_index == mcparent->base.index)
- ++i;
- }
}
static void