diff options
-rw-r--r-- | src/interface.c | 74 | ||||
-rw-r--r-- | src/pa-sink-ctl.c | 43 | ||||
-rw-r--r-- | src/pa-sink-ctl.h | 4 | ||||
-rw-r--r-- | src/sink.h | 1 |
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; }; @@ -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 { |