diff options
author | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2011-10-21 12:52:21 +0200 |
---|---|---|
committer | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2011-10-21 23:13:39 +0200 |
commit | badb9650df460fa3999ac937958ac05f97eaad88 (patch) | |
tree | cf1e1f6c40bda9e9baa05d08ad5a032d58519422 | |
parent | b96d01ced40a2fe3df47dc4690bc50c6466e3d12 (diff) | |
download | pa-sink-ctl-badb9650df460fa3999ac937958ac05f97eaad88.tar.gz pa-sink-ctl-badb9650df460fa3999ac937958ac05f97eaad88.tar.bz2 pa-sink-ctl-badb9650df460fa3999ac937958ac05f97eaad88.zip |
Stop using global variables.
Rather store it in a context, thats used everywhere as parameter,
or as userdata.
-rw-r--r-- | src/interface.c | 246 | ||||
-rw-r--r-- | src/interface.h | 11 | ||||
-rw-r--r-- | src/pa-sink-ctl.c | 131 | ||||
-rw-r--r-- | src/pa-sink-ctl.h | 35 |
4 files changed, 219 insertions, 204 deletions
diff --git a/src/interface.c b/src/interface.c index b538c42..e4d7019 100644 --- a/src/interface.c +++ b/src/interface.c @@ -22,29 +22,11 @@ #define SELECTED_UNKNOWN -2 #define SELECTED_SINK -1 -extern pa_context* context; -extern gboolean context_ready; - -static WINDOW *menu_win; -static WINDOW *msg_win; - -static guint resize_source_id; -#ifdef HAVE_SIGNALFD -static int signal_fd; -#endif -static guint input_source_id; - -static gint chooser_sink; -static gint chooser_input; -static guint32 selected_index; - -guint max_name_len = 0; - -extern GList *sink_list; static gboolean interface_resize(gpointer data) { + struct context *ctx = data; struct winsize wsize; gint height = 80; gint width = 24; @@ -58,94 +40,94 @@ interface_resize(gpointer data) clear(); refresh(); - wresize(menu_win, height - H_MSG_BOX, width); - wresize(msg_win, H_MSG_BOX, width); - mvwin(msg_win, height - H_MSG_BOX, 0); + wresize(ctx->menu_win, height - H_MSG_BOX, width); + wresize(ctx->msg_win, H_MSG_BOX, width); + mvwin(ctx->msg_win, height - H_MSG_BOX, 0); /* NULL := display old status */ - interface_set_status(NULL); - print_sink_list(); + interface_set_status(ctx, NULL); + print_sink_list(ctx); return TRUE; } static void -print_volume(pa_volume_t volume, int mute, int y) +print_volume(struct context *ctx, pa_volume_t volume, int mute, int y) { gint x = 2 /* left */ + 2 /* index num width */ + 1 /* space */ + - 1 /* space */ + max_name_len + 1 /* space */; + 1 /* space */ + ctx->max_name_len + 1 /* space */; //gint vol = (gint) (VOLUME_BAR_LEN * volume / PA_VOLUME_NORM); - int volume_bar_len = getmaxx(menu_win) - x - 6 /* mute button + brackets + space */; + int volume_bar_len = getmaxx(ctx->menu_win) - x - 6 /* mute button + brackets + space */; gint vol = (gint) (volume_bar_len * volume / PA_VOLUME_NORM); - mvwprintw(menu_win, y, x - 1, "[%c]", mute ? 'M' : ' '); + mvwprintw(ctx->menu_win, y, x - 1, "[%c]", mute ? 'M' : ' '); x += 3; - mvwprintw(menu_win, y, x - 1 , "["); + mvwprintw(ctx->menu_win, y, x - 1 , "["); for (gint i = 0; i < vol; ++i) - mvwprintw(menu_win, y, x + i, "="); + mvwprintw(ctx->menu_win, y, x + i, "="); for (gint i = vol; i < volume_bar_len; ++i) - mvwprintw(menu_win, y, x + i, " "); - mvwprintw(menu_win, y, x + volume_bar_len, "]"); + mvwprintw(ctx->menu_win, y, x + i, " "); + mvwprintw(ctx->menu_win, y, x + volume_bar_len, "]"); } static void -print_input_list(GList *input_list, gint sink_num) +print_input_list(struct context *ctx, GList *input_list, gint sink_num) { GList *l; gint offset = sink_num + 3 /* win border + empty line + 1th sink */; gint i; - for (l = sink_list, i = 0; l && i < sink_num; l = l->next,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); for (l = input_list, i = 0; l; l = l->next,++i) { sink_input_info *input = l->data; - gboolean selected = (chooser_sink == sink_num && chooser_input == i); + gboolean selected = (ctx->chooser_sink == sink_num && ctx->chooser_input == i); if (selected) - wattron(menu_win, A_REVERSE); + wattron(ctx->menu_win, A_REVERSE); - mvwprintw(menu_win, offset + i, 2, "%*s%-*s", + mvwprintw(ctx->menu_win, offset + i, 2, "%*s%-*s", 2+1+1, "", /* space for index number + indentation*/ - max_name_len - 1, input->name); + ctx->max_name_len - 1, input->name); if (selected) - wattroff(menu_win, A_REVERSE); + wattroff(ctx->menu_win, A_REVERSE); - print_volume(input->vol, input->mute, offset + i); + print_volume(ctx, input->vol, input->mute, offset + i); } } /* looking for the longest name length of all SINK's and INPUT's */ static void -set_max_name_len(void) +set_max_name_len(struct context *ctx) { GList *l,*k; guint len = 0; - max_name_len = len; + ctx->max_name_len = len; - for (l = sink_list; l; l = l->next) { + for (l = ctx->sink_list; l; l = l->next) { sink_info *sink = l->data; len = strlen(sink->device != NULL ? sink->device : sink->name); - if (len > max_name_len) - max_name_len = len; + 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; len = strlen(input->name) + 1 /* indentation */; - if (len > max_name_len) - max_name_len = len; + if (len > ctx->max_name_len) + ctx->max_name_len = len; } } } void -print_sink_list(void) +print_sink_list(struct context *ctx) { gint i = 0; gint x = 2; @@ -154,85 +136,86 @@ print_sink_list(void) GList *l; /* looking for the longest name for right indentation */ - set_max_name_len(); + set_max_name_len(ctx); - werase(menu_win); - box(menu_win, 0, 0); + werase(ctx->menu_win); + box(ctx->menu_win, 0, 0); - /* derive chooser_input from selected_index (this is set when input is moved) */ - if (chooser_input == SELECTED_UNKNOWN) { + /* derive ctx->chooser_input from ctx->selected_index (this is set when input is moved) */ + if (ctx->chooser_input == SELECTED_UNKNOWN) { /* if index is will not be found (in the loop), select the sink itself */ - chooser_input = SELECTED_SINK; + ctx->chooser_input = SELECTED_SINK; /* step through inputs for current sink and find the selected */ - sink_info *sink = g_list_nth_data(sink_list, chooser_sink); + 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) { sink_input_info *input = l->data; - if (selected_index == input->index) { - chooser_input = i; + if (ctx->selected_index == input->index) { + ctx->chooser_input = i; break; } } } - for (l = sink_list, i = 0; l; l = l->next,++i) { + for (l = ctx->sink_list, i = 0; l; l = l->next,++i) { sink_info *sink = l->data; - gboolean selected = (i == chooser_sink && chooser_input == SELECTED_SINK); + gboolean selected = (i == ctx->chooser_sink && ctx->chooser_input == SELECTED_SINK); if (selected) - wattron(menu_win, A_REVERSE); + wattron(ctx->menu_win, A_REVERSE); - mvwprintw(menu_win, y+i+offset, x, "%2u %-*s", - sink->index, max_name_len, + mvwprintw(ctx->menu_win, y+i+offset, x, "%2u %-*s", + sink->index, ctx->max_name_len, sink->device != NULL ? sink->device : sink->name); if (selected) - wattroff(menu_win, A_REVERSE); - print_volume(sink->vol, sink->mute, y+i+offset); + wattroff(ctx->menu_win, A_REVERSE); + print_volume(ctx, sink->vol, sink->mute, y+i+offset); - print_input_list(sink->input_list, i); + print_input_list(ctx, sink->input_list, i); offset += g_list_length(sink->input_list); } - wrefresh(menu_win); + wrefresh(ctx->menu_win); } static gboolean interface_get_input(GIOChannel *source, GIOCondition condition, gpointer data) { + struct context *ctx = data; gint c; gboolean volume_increment = TRUE; sink_info *sink = NULL; - if (!context_ready) + if (!ctx->context_ready) return TRUE; - c = wgetch(menu_win); + c = wgetch(ctx->menu_win); switch (c) { case 'k': case 'w': case KEY_UP: - if (chooser_input == SELECTED_SINK && chooser_sink > 0) { - sink = g_list_nth_data(sink_list, --chooser_sink); + 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 */ - chooser_input = (gint)g_list_length(sink->input_list) - 1; + ctx->chooser_input = (gint)g_list_length(sink->input_list) - 1; } - else if (chooser_input >= 0) - --chooser_input; - print_sink_list(); + else if (ctx->chooser_input >= 0) + --ctx->chooser_input; + print_sink_list(ctx); break; case 'j': case 's': case KEY_DOWN: - sink = g_list_nth_data(sink_list, chooser_sink); - if (chooser_input == ((gint)g_list_length(sink->input_list) - 1) && chooser_sink < (gint)g_list_length(sink_list) - 1) { - ++chooser_sink; - chooser_input = SELECTED_SINK; + 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) { + ++ctx->chooser_sink; + ctx->chooser_input = SELECTED_SINK; } - else if (chooser_input < ((gint)g_list_length(sink->input_list) - 1)) - ++chooser_input; - print_sink_list(); + else if (ctx->chooser_input < ((gint)g_list_length(sink->input_list) - 1)) + ++ctx->chooser_input; + print_sink_list(ctx); break; case 'h': @@ -248,14 +231,14 @@ interface_get_input(GIOChannel *source, GIOCondition condition, gpointer data) pa_volume_t tmp_vol; pa_operation* (*volume_set) (pa_context*, guint32, const pa_cvolume*, pa_context_success_cb_t, gpointer); - sink = g_list_nth_data(sink_list, chooser_sink); - if (chooser_input >= 0) { - sink_input_info *input = g_list_nth_data(sink->input_list, chooser_input); + sink = g_list_nth_data(ctx->sink_list, ctx->chooser_sink); + if (ctx->chooser_input >= 0) { + sink_input_info *input = g_list_nth_data(sink->input_list, ctx->chooser_input); index = input->index; volume = (pa_cvolume) {.channels = input->channels}; tmp_vol = input->vol; volume_set = pa_context_set_sink_input_volume; - } else if (chooser_input == SELECTED_SINK) { + } else if (ctx->chooser_input == SELECTED_SINK) { index = sink->index; volume = (pa_cvolume) {.channels = sink->channels}; tmp_vol = sink->vol; @@ -275,7 +258,7 @@ interface_get_input(GIOChannel *source, GIOCondition condition, gpointer data) pa_cvolume_dec(&volume, inc); - pa_operation_unref(volume_set(context, index, &volume, change_callback, NULL)); + pa_operation_unref(volume_set(ctx->context, index, &volume, change_callback, ctx)); break; } @@ -287,47 +270,47 @@ interface_get_input(GIOChannel *source, GIOCondition condition, gpointer data) gint mute; pa_operation* (*mute_set) (pa_context*, guint32, int, pa_context_success_cb_t, void*); - sink = g_list_nth_data(sink_list, chooser_sink); - if (chooser_input >= 0) { - sink_input_info *input = g_list_nth_data(sink->input_list, chooser_input); + sink = g_list_nth_data(ctx->sink_list, ctx->chooser_sink); + if (ctx->chooser_input >= 0) { + sink_input_info *input = g_list_nth_data(sink->input_list, ctx->chooser_input); index = input->index; mute = !input->mute; mute_set = pa_context_set_sink_input_mute; - } else if (chooser_input == SELECTED_SINK) { + } else if (ctx->chooser_input == SELECTED_SINK) { index = sink->index; mute = !sink->mute; mute_set = pa_context_set_sink_mute_by_index; } else break; - pa_operation_unref(mute_set(context, index, mute, change_callback, NULL)); + pa_operation_unref(mute_set(ctx->context, index, mute, change_callback, ctx)); break; } case '\n': case '\t': case ' ': - if (chooser_input == SELECTED_SINK) + if (ctx->chooser_input == SELECTED_SINK) break; - sink = g_list_nth_data(sink_list, chooser_sink); - sink_input_info *input = g_list_nth_data(sink->input_list, chooser_input); - selected_index = input->index; - if (chooser_sink < (gint)g_list_length(sink_list) - 1) - chooser_sink++; + 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); + ctx->selected_index = input->index; + if (ctx->chooser_sink < (gint)g_list_length(ctx->sink_list) - 1) + ctx->chooser_sink++; else - chooser_sink = 0; + ctx->chooser_sink = 0; - sink = g_list_nth_data(sink_list, chooser_sink); - /* chooser_input needs to be derived from $selected_index */ - chooser_input = SELECTED_UNKNOWN; - pa_operation_unref(pa_context_move_sink_input_by_index(context, selected_index, + sink = g_list_nth_data(ctx->sink_list, ctx->chooser_sink); + /* ctx->chooser_input needs to be derived from $ctx->selected_index */ + ctx->chooser_input = SELECTED_UNKNOWN; + pa_operation_unref(pa_context_move_sink_input_by_index(ctx->context, ctx->selected_index, sink->index, change_callback, NULL)); break; case 'q': default: - quit(); + quit(ctx); break; } @@ -335,30 +318,28 @@ interface_get_input(GIOChannel *source, GIOCondition condition, gpointer data) } void -interface_clear(void) +interface_clear(struct context *ctx) { - g_source_remove(resize_source_id); - g_source_remove(input_source_id); - close(signal_fd); + g_source_remove(ctx->resize_source_id); + g_source_remove(ctx->input_source_id); + close(ctx->signal_fd); clear(); refresh(); endwin(); } void -interface_set_status(const gchar *msg) +interface_set_status(struct context *ctx, const gchar *msg) { - static gchar *status = NULL; - if (msg != NULL) { - g_free(status); - status = g_strdup(msg); + g_free(ctx->status); + ctx->status = g_strdup(msg); } - werase(msg_win); - box(msg_win, 0, 0); - if (status != NULL) - mvwprintw(msg_win, 1, 1, status); - wrefresh(msg_win); + werase(ctx->msg_win); + box(ctx->msg_win, 0, 0); + if (ctx->status != NULL) + mvwprintw(ctx->msg_win, 1, 1, ctx->status); + wrefresh(ctx->msg_win); refresh(); } @@ -366,26 +347,27 @@ interface_set_status(const gchar *msg) static gboolean resize_gio(GIOChannel *source, GIOCondition condition, gpointer data) { + struct context *ctx = data; struct signalfd_siginfo fdsi; ssize_t s; g_assert(condition & G_IO_IN); - s = read(signal_fd, &fdsi, sizeof fdsi); + s = read(ctx->signal_fd, &fdsi, sizeof fdsi); if (s != sizeof fdsi || fdsi.ssi_signo != SIGWINCH) return FALSE; - return interface_resize(data); + return interface_resize(ctx); } #endif void -interface_init(void) +interface_init(struct context *ctx) { GIOChannel *input_channel; - chooser_sink = 0; /* Selected sink-device. 0 is the first device */ - chooser_input = SELECTED_SINK; /* Selected input of the current sink-device. */ + ctx->chooser_sink = 0; /* Selected sink-device. 0 is the first device */ + ctx->chooser_input = SELECTED_SINK; /* Selected input of the current sink-device. */ /* SELECTED_SINK refers to sink-device itself */ initscr(); clear(); @@ -397,14 +379,14 @@ interface_init(void) curs_set(0); /* 0,0,0,0 := fullscreen */ - menu_win = newwin(0, 0, 0, 0); - msg_win = newwin(0, 0, 0, 0); + ctx->menu_win = newwin(0, 0, 0, 0); + ctx->msg_win = newwin(0, 0, 0, 0); /* multichar keys are mapped to one char */ - keypad(menu_win, TRUE); + keypad(ctx->menu_win, TRUE); /* "resizing" here is for initial box positioning and layout */ - interface_resize(NULL); + interface_resize(ctx); #ifdef HAVE_SIGNALFD { @@ -416,20 +398,20 @@ interface_init(void) if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) exit(EXIT_FAILURE); - signal_fd = signalfd(-1, &mask, 0); - channel = g_io_channel_unix_new(signal_fd); - g_io_add_watch(channel, G_IO_IN, resize_gio, NULL); + ctx->signal_fd = signalfd(-1, &mask, 0); + channel = g_io_channel_unix_new(ctx->signal_fd); + g_io_add_watch(channel, G_IO_IN, resize_gio, ctx); g_io_channel_unref(channel); } #else /* register event handler for resize and input */ - resize_source_id = unix_signal_add(SIGWINCH, interface_resize, NULL); + ctx->resize_source_id = unix_signal_add(SIGWINCH, interface_resize, ctx); #endif input_channel = g_io_channel_unix_new(STDIN_FILENO); if (!input_channel) exit(EXIT_FAILURE); - input_source_id = g_io_add_watch(input_channel, G_IO_IN, - interface_get_input, NULL); + ctx->input_source_id = g_io_add_watch(input_channel, G_IO_IN, + interface_get_input, ctx); g_io_channel_unref(input_channel); refresh(); diff --git a/src/interface.h b/src/interface.h index e251b8f..e9e47eb 100644 --- a/src/interface.h +++ b/src/interface.h @@ -4,9 +4,12 @@ #include <glib.h> #include <pulse/pulseaudio.h> -void print_sink_list(void); -void interface_init(void); -void interface_clear(void); -void interface_set_status(const gchar *); + +struct context; + +void print_sink_list(struct context *ctx); +void interface_init(struct context *ctx); +void interface_clear(struct context *ctx); +void interface_set_status(struct context *ctx, const gchar *); #endif diff --git a/src/pa-sink-ctl.c b/src/pa-sink-ctl.c index a2d8afe..32d7873 100644 --- a/src/pa-sink-ctl.c +++ b/src/pa-sink-ctl.c @@ -6,18 +6,6 @@ #include "interface.h" #include "pa-sink-ctl.h" -pa_context *context = NULL; -gboolean context_ready = FALSE; - -static gboolean info_callbacks_finished = TRUE; -static gboolean info_callbacks_blocked = FALSE; - -struct fetch_ctx { - GList *sinks; -}; - -GList *sink_list; - #define list_append_struct(list, data) \ do { \ (list) = g_list_append((list), \ @@ -27,43 +15,48 @@ GList *sink_list; int main(int argc, char** argv) { + struct context *ctx = g_new0(struct context, 1); pa_mainloop_api *mainloop_api = NULL; pa_glib_mainloop *m = NULL; - sink_list = NULL; + ctx->info_callbacks_finished = TRUE; + ctx->info_callbacks_blocked = FALSE; + ctx->sink_list = NULL; + ctx->max_name_len = 0; + ctx->context_ready = FALSE; - GMainLoop *g_loop = g_main_loop_new(NULL, FALSE); + ctx->loop = g_main_loop_new(NULL, FALSE); - interface_init(); + interface_init(ctx); if (!(m = pa_glib_mainloop_new(NULL))) { - interface_clear(); + interface_clear(ctx); g_printerr("error: pa_glib_mainloop_new() failed.\n"); return -1; } mainloop_api = pa_glib_mainloop_get_api(m); - if (!(context = pa_context_new(mainloop_api, "pa-sink-ctl"))) { - interface_clear(); + if (!(ctx->context = pa_context_new(mainloop_api, "pa-sink-ctl"))) { + interface_clear(ctx); g_printerr("error: pa_context_new() failed.\n"); return -1; } // define callback for connection init - pa_context_set_state_callback(context, context_state_callback, g_loop); - if (pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL)) { - interface_clear(); + pa_context_set_state_callback(ctx->context, context_state_callback, ctx); + if (pa_context_connect(ctx->context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL)) { + interface_clear(ctx); g_printerr("error: pa_context_connect() failed.\n"); } - g_main_loop_run(g_loop); + g_main_loop_run(ctx->loop); - interface_clear(); - g_list_free(sink_list); + interface_clear(ctx); + g_list_free(ctx->sink_list); pa_glib_mainloop_free(m); - g_main_loop_unref(g_loop); + g_main_loop_unref(ctx->loop); return 0; } @@ -71,10 +64,12 @@ main(int argc, char** argv) static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, guint32 idx, gpointer userdata) { - if (!info_callbacks_finished) - info_callbacks_blocked = TRUE; + struct context *ctx = userdata; + + if (!ctx->info_callbacks_finished) + ctx->info_callbacks_blocked = TRUE; else - collect_all_info(); + collect_all_info(ctx); } /* @@ -83,42 +78,43 @@ subscribe_cb(pa_context *c, pa_subscription_event_type_t t, guint32 idx, gpointe void context_state_callback(pa_context *c, gpointer userdata) { - static pa_operation *o = NULL; - context_ready = FALSE; + struct context *ctx = userdata; + + ctx->context_ready = FALSE; switch (pa_context_get_state(c)) { case PA_CONTEXT_CONNECTING: - interface_set_status("connecting..."); + interface_set_status(ctx, "connecting..."); break; case PA_CONTEXT_AUTHORIZING: - interface_set_status("authorizing..."); + interface_set_status(ctx, "authorizing..."); break; case PA_CONTEXT_SETTING_NAME: - interface_set_status("setting name..."); + interface_set_status(ctx, "setting name..."); break; case PA_CONTEXT_READY: - collect_all_info(); - pa_context_set_subscribe_callback(context, subscribe_cb, NULL); - g_assert((o = pa_context_subscribe(c, (pa_subscription_mask_t) ( + collect_all_info(ctx); + pa_context_set_subscribe_callback(c, subscribe_cb, ctx); + g_assert((ctx->op = pa_context_subscribe(c, (pa_subscription_mask_t) ( PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SINK_INPUT ), NULL, NULL))); - context_ready = TRUE; - interface_set_status("ready to process events."); + ctx->context_ready = TRUE; + interface_set_status(ctx, "ready to process events."); break; case PA_CONTEXT_FAILED: - interface_set_status("cannot connect!"); + interface_set_status(ctx, "cannot connect!"); break; case PA_CONTEXT_TERMINATED: - g_assert(o != NULL); - pa_operation_cancel(o); - pa_operation_unref(o); - o = NULL; - interface_set_status("connection terminated."); - g_main_loop_quit((GMainLoop *)userdata); + g_assert(ctx->op != NULL); + pa_operation_cancel(ctx->op); + pa_operation_unref(ctx->op); + ctx->op = NULL; + interface_set_status(ctx, "connection terminated."); + g_main_loop_quit(ctx->loop); break; default: - interface_set_status("unknown state"); + interface_set_status(ctx, "unknown state"); break; } } @@ -131,15 +127,15 @@ void get_sink_info_callback(pa_context *c, const pa_sink_info *i, gint is_last, gpointer userdata) { g_assert(userdata != NULL); - struct fetch_ctx *fetch_ctx = userdata; + struct context *ctx = userdata; if (is_last < 0) { g_printerr("Failed to get sink information: %s\n", pa_strerror(pa_context_errno(c))); - quit(); + quit(ctx); } if (is_last) { - pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, fetch_ctx)); + pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, ctx)); return; } @@ -154,7 +150,7 @@ get_sink_info_callback(pa_context *c, const pa_sink_info *i, gint is_last, gpoin .input_list = NULL }; - list_append_struct(fetch_ctx->sinks, sink); + list_append_struct(ctx->tmp_sinks, sink); } /* @@ -164,7 +160,7 @@ void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info *i, gint is_last, gpointer userdata) { g_assert(userdata != NULL); - struct fetch_ctx *fetch_ctx = userdata; + struct context *ctx = userdata; if (is_last < 0) { g_printerr("Failed to get sink input information: %s\n", pa_strerror(pa_context_errno(c))); @@ -172,16 +168,15 @@ get_sink_input_info_callback(pa_context *c, const pa_sink_input_info *i, gint is } if (is_last) { - info_callbacks_finished = TRUE; - g_list_free_full(sink_list, g_free); - sink_list = fetch_ctx->sinks; - g_free(fetch_ctx); + ctx->info_callbacks_finished = TRUE; + g_list_free_full(ctx->sink_list, g_free); + ctx->sink_list = ctx->tmp_sinks; - print_sink_list(); + print_sink_list(ctx); - if (info_callbacks_blocked) { - info_callbacks_blocked = FALSE; - collect_all_info(); + if (ctx->info_callbacks_blocked) { + ctx->info_callbacks_blocked = FALSE; + collect_all_info(ctx); } return; } @@ -200,14 +195,14 @@ 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(fetch_ctx->sinks, i->sink); + sink_info *sink = g_list_nth_data(ctx->tmp_sinks, i->sink); list_append_struct(sink->input_list, sink_input); } void -quit(void) +quit(struct context *ctx) { - pa_context_disconnect(context); + pa_context_disconnect(ctx->context); } /* @@ -216,14 +211,18 @@ quit(void) void change_callback(pa_context* c, gint success, gpointer userdata) { +#if 0 + struct context *ctx = userdata; +#endif return; } void -collect_all_info(void) +collect_all_info(struct context *ctx) { - if (!info_callbacks_finished) + if (!ctx->info_callbacks_finished) return; - info_callbacks_finished = FALSE; - pa_operation_unref(pa_context_get_sink_info_list(context, get_sink_info_callback, g_new0(struct fetch_ctx, 1))); + ctx->info_callbacks_finished = FALSE; + ctx->tmp_sinks = NULL; + pa_operation_unref(pa_context_get_sink_info_list(ctx->context, get_sink_info_callback, ctx)); } diff --git a/src/pa-sink-ctl.h b/src/pa-sink-ctl.h index 3175838..4358c56 100644 --- a/src/pa-sink-ctl.h +++ b/src/pa-sink-ctl.h @@ -3,9 +3,40 @@ #include <glib.h> #include <pulse/pulseaudio.h> +#include <ncurses.h> -void collect_all_info(void); -void quit(void); +struct context { + pa_context *context; + pa_operation *op; + gboolean context_ready; + + WINDOW *menu_win; + WINDOW *msg_win; + + guint resize_source_id; +#ifdef HAVE_SIGNALFD + int signal_fd; +#endif + guint input_source_id; + + gint chooser_sink; + gint chooser_input; + guint32 selected_index; + + guint max_name_len; + + gboolean info_callbacks_finished; + gboolean info_callbacks_blocked; + GMainLoop *loop; + + GList *sink_list; + GList *tmp_sinks; + + gchar *status; +}; + +void collect_all_info(struct context *ctx); +void quit(struct context *ctx); void context_state_callback(pa_context*, gpointer); void get_sink_info_callback(pa_context *, const pa_sink_info *, gint, gpointer); |