summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interface.c74
-rw-r--r--src/pa-sink-ctl.c43
-rw-r--r--src/pa-sink-ctl.h4
-rw-r--r--src/sink.h1
4 files changed, 85 insertions, 37 deletions
diff --git a/src/interface.c b/src/interface.c
index 804106d..1246a9f 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -22,6 +22,38 @@
#define SELECTED_UNKNOWN -2
#define SELECTED_SINK -1
+static int
+sink_input_len(struct context *ctx, sink_info *sink)
+{
+ int len = 0;
+ GList *l;
+
+ for (l = ctx->input_list; l; l = l->next) {
+ sink_input_info *input = l->data;
+
+ if (input->sink == sink->index)
+ len++;
+ }
+
+ return len;
+}
+
+static sink_input_info *
+sink_get_nth_input(struct context *ctx, sink_info *sink, int n)
+{
+ GList *l;
+ int i;
+
+ for (l = ctx->input_list; l; l = l->next) {
+ sink_input_info *input = l->data;
+ if (input->sink != sink->index)
+ continue;
+ if (i++ == n)
+ return input;
+ }
+
+ return NULL;
+}
static gboolean
interface_resize(gpointer data)
@@ -72,17 +104,19 @@ print_volume(struct context *ctx, pa_volume_t volume, int mute, int y)
}
static void
-print_input_list(struct context *ctx, GList *input_list, gint sink_num)
+print_input_list(struct context *ctx, sink_info *sink, gint sink_num)
{
GList *l;
gint offset = sink_num + 3 /* win border + empty line + 1th sink */;
gint i;
for (l = ctx->sink_list, i = 0; l && i < sink_num; l = l->next,i++)
- offset += g_list_length(((sink_info *)l->data)->input_list);
+ offset += sink_input_len(ctx, l->data);
- for (l = input_list, i = 0; l; l = l->next,++i) {
+ for (l = ctx->input_list, i = 0; l; l = l->next,++i) {
sink_input_info *input = l->data;
+ if (input->sink != sink->index)
+ continue;
gboolean selected = (ctx->chooser_sink == sink_num && ctx->chooser_input == i);
if (selected)
@@ -103,7 +137,7 @@ print_input_list(struct context *ctx, GList *input_list, gint sink_num)
static void
set_max_name_len(struct context *ctx)
{
- GList *l,*k;
+ GList *l;
guint len = 0;
ctx->max_name_len = len;
@@ -114,15 +148,15 @@ set_max_name_len(struct context *ctx)
if (len > ctx->max_name_len)
ctx->max_name_len = len;
+ }
- for (k = sink->input_list; k; k = k->next) {
- sink_input_info *input = k->data;
+ for (l = ctx->input_list; l; l = l->next) {
+ sink_input_info *input = l->data;
- len = strlen(input->name) + 1 /* indentation */;
+ len = strlen(input->name) + 1 /* indentation */;
- if (len > ctx->max_name_len)
- ctx->max_name_len = len;
- }
+ if (len > ctx->max_name_len)
+ ctx->max_name_len = len;
}
}
@@ -147,8 +181,10 @@ print_sink_list(struct context *ctx)
ctx->chooser_input = SELECTED_SINK;
/* step through inputs for current sink and find the selected */
sink_info *sink = g_list_nth_data(ctx->sink_list, ctx->chooser_sink);
- for (l = sink->input_list, i = 0; l; l = l->next,++i) {
+ for (l = ctx->input_list, i = 0; l; l = l->next,++i) {
sink_input_info *input = l->data;
+ if (input->sink != sink->index)
+ continue;
if (ctx->selected_index == input->index) {
ctx->chooser_input = i;
break;
@@ -171,9 +207,9 @@ print_sink_list(struct context *ctx)
wattroff(ctx->menu_win, A_REVERSE);
print_volume(ctx, sink->vol, sink->mute, y+i+offset);
- print_input_list(ctx, sink->input_list, i);
+ print_input_list(ctx, sink, i);
- offset += g_list_length(sink->input_list);
+ offset += sink_input_len(ctx, sink);
}
wrefresh(ctx->menu_win);
}
@@ -198,7 +234,7 @@ interface_get_input(GIOChannel *source, GIOCondition condition, gpointer data)
if (ctx->chooser_input == SELECTED_SINK && ctx->chooser_sink > 0) {
sink = g_list_nth_data(ctx->sink_list, --ctx->chooser_sink);
/* automatic SELECTED_SINK (=-1) assignment if length = 0 */
- ctx->chooser_input = (gint)g_list_length(sink->input_list) - 1;
+ ctx->chooser_input = sink_input_len(ctx, sink) - 1;
}
else if (ctx->chooser_input >= 0)
@@ -210,11 +246,11 @@ interface_get_input(GIOChannel *source, GIOCondition condition, gpointer data)
case 's':
case KEY_DOWN:
sink = g_list_nth_data(ctx->sink_list, ctx->chooser_sink);
- if (ctx->chooser_input == ((gint)g_list_length(sink->input_list) - 1) && ctx->chooser_sink < (gint)g_list_length(ctx->sink_list) - 1) {
+ if (ctx->chooser_input == (sink_input_len(ctx, sink) - 1) && ctx->chooser_sink < (gint)g_list_length(ctx->sink_list) - 1) {
++ctx->chooser_sink;
ctx->chooser_input = SELECTED_SINK;
}
- else if (ctx->chooser_input < ((gint)g_list_length(sink->input_list) - 1))
+ else if (ctx->chooser_input < (sink_input_len(ctx, sink) - 1))
++ctx->chooser_input;
print_sink_list(ctx);
break;
@@ -233,7 +269,7 @@ interface_get_input(GIOChannel *source, GIOCondition condition, gpointer data)
pa_operation* (*volume_set) (pa_context*, guint32, const pa_cvolume*, pa_context_success_cb_t, gpointer);
if (ctx->chooser_input >= 0) {
- sink_input_info *input = g_list_nth_data(sink->input_list, ctx->chooser_input);
+ sink_input_info *input = sink_get_nth_input(ctx, sink, ctx->chooser_input);
index = input->index;
volume = (pa_cvolume) {.channels = input->channels};
tmp_vol = input->vol;
@@ -268,7 +304,7 @@ interface_get_input(GIOChannel *source, GIOCondition condition, gpointer data)
pa_operation* (*mute_set) (pa_context*, guint32, int, pa_context_success_cb_t, void*);
if (ctx->chooser_input >= 0) {
- sink_input_info *input = g_list_nth_data(sink->input_list, ctx->chooser_input);
+ sink_input_info *input = sink_get_nth_input(ctx, sink, ctx->chooser_input);
index = input->index;
mute = !input->mute;
mute_set = pa_context_set_sink_input_mute;
@@ -288,7 +324,7 @@ interface_get_input(GIOChannel *source, GIOCondition condition, gpointer data)
if (ctx->chooser_input == SELECTED_SINK)
break;
sink = g_list_nth_data(ctx->sink_list, ctx->chooser_sink);
- sink_input_info *input = g_list_nth_data(sink->input_list, ctx->chooser_input);
+ sink_input_info *input = sink_get_nth_input(ctx, sink, ctx->chooser_input);
ctx->selected_index = input->index;
if (ctx->chooser_sink < (gint)g_list_length(ctx->sink_list) - 1)
ctx->chooser_sink++;
diff --git a/src/pa-sink-ctl.c b/src/pa-sink-ctl.c
index cd8fbfc..8408c3e 100644
--- a/src/pa-sink-ctl.c
+++ b/src/pa-sink-ctl.c
@@ -87,15 +87,16 @@ get_sink_input_info_callback(pa_context *c, const pa_sink_input_info *i, gint is
}
if (is_last) {
- ctx->info_callbacks_finished = TRUE;
- g_list_free_full(ctx->sink_list, g_free);
- ctx->sink_list = ctx->tmp_sinks;
+ g_list_free_full(ctx->input_list, g_free);
+ ctx->input_list = ctx->tmp_inputs;
- print_sink_list(ctx);
+ if (++ctx->info_callbacks_finished == 2) {
+ print_sink_list(ctx);
- if (ctx->info_callbacks_blocked) {
- ctx->info_callbacks_blocked = FALSE;
- collect_all_info(ctx);
+ if (ctx->info_callbacks_blocked) {
+ ctx->info_callbacks_blocked = FALSE;
+ collect_all_info(ctx);
+ }
}
return;
}
@@ -114,8 +115,7 @@ get_sink_input_info_callback(pa_context *c, const pa_sink_input_info *i, gint is
.pid = NULL /* maybe obsolete */
};
- sink_info *sink = g_list_nth_data(ctx->tmp_sinks, i->sink);
- list_append_struct(sink->input_list, sink_input);
+ list_append_struct(ctx->tmp_inputs, sink_input);
}
/*
@@ -133,7 +133,17 @@ get_sink_info_callback(pa_context *c, const pa_sink_info *i, gint is_last, gpoin
}
if (is_last) {
- pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, ctx));
+ g_list_free_full(ctx->sink_list, g_free);
+ ctx->sink_list = ctx->tmp_sinks;
+
+ if (++ctx->info_callbacks_finished == 2) {
+ print_sink_list(ctx);
+ if (ctx->info_callbacks_blocked) {
+ ctx->info_callbacks_blocked = FALSE;
+ collect_all_info(ctx);
+ }
+ }
+
return;
}
@@ -145,13 +155,11 @@ get_sink_info_callback(pa_context *c, const pa_sink_info *i, gint is_last, gpoin
.name = g_strdup(i->name),
.device = pa_proplist_contains(i->proplist, "device.product.name") ?
g_strdup(pa_proplist_gets(i->proplist, "device.product.name")) : NULL,
- .input_list = NULL
};
list_append_struct(ctx->tmp_sinks, sink);
}
-
void
quit(struct context *ctx)
{
@@ -173,11 +181,13 @@ change_callback(pa_context* c, gint success, gpointer userdata)
static void
collect_all_info(struct context *ctx)
{
- if (!ctx->info_callbacks_finished)
+ if (ctx->info_callbacks_finished < 2)
return;
- ctx->info_callbacks_finished = FALSE;
+ ctx->info_callbacks_finished = 0;
ctx->tmp_sinks = NULL;
+ ctx->tmp_inputs = NULL;
pa_operation_unref(pa_context_get_sink_info_list(ctx->context, get_sink_info_callback, ctx));
+ pa_operation_unref(pa_context_get_sink_input_info_list(ctx->context, get_sink_input_info_callback, ctx));
}
int
@@ -187,7 +197,7 @@ main(int argc, char** argv)
pa_mainloop_api *mainloop_api = NULL;
pa_glib_mainloop *m = NULL;
- ctx->info_callbacks_finished = TRUE;
+ ctx->info_callbacks_finished = 2;
ctx->info_callbacks_blocked = FALSE;
ctx->sink_list = NULL;
ctx->max_name_len = 0;
@@ -221,7 +231,8 @@ main(int argc, char** argv)
g_main_loop_run(ctx->loop);
interface_clear(ctx);
- g_list_free(ctx->sink_list);
+ g_list_free_full(ctx->sink_list, g_free);
+ g_list_free_full(ctx->input_list, g_free);
pa_glib_mainloop_free(m);
g_main_loop_unref(ctx->loop);
diff --git a/src/pa-sink-ctl.h b/src/pa-sink-ctl.h
index 2539ea3..172bfcd 100644
--- a/src/pa-sink-ctl.h
+++ b/src/pa-sink-ctl.h
@@ -25,12 +25,14 @@ struct context {
guint max_name_len;
- gboolean info_callbacks_finished;
+ int info_callbacks_finished;
gboolean info_callbacks_blocked;
GMainLoop *loop;
GList *sink_list;
+ GList *input_list;
GList *tmp_sinks;
+ GList *tmp_inputs;
gchar *status;
};
diff --git a/src/sink.h b/src/sink.h
index 14d9be2..afaf929 100644
--- a/src/sink.h
+++ b/src/sink.h
@@ -11,7 +11,6 @@ typedef struct _sink_info {
gint mute;
guint8 channels;
pa_volume_t vol;
- GList *input_list;
} sink_info;
typedef struct _sink_input_info {