summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2011-10-21 12:52:21 +0200
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2011-10-21 23:13:39 +0200
commitbadb9650df460fa3999ac937958ac05f97eaad88 (patch)
treecf1e1f6c40bda9e9baa05d08ad5a032d58519422 /src
parentb96d01ced40a2fe3df47dc4690bc50c6466e3d12 (diff)
downloadpa-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.
Diffstat (limited to 'src')
-rw-r--r--src/interface.c246
-rw-r--r--src/interface.h11
-rw-r--r--src/pa-sink-ctl.c131
-rw-r--r--src/pa-sink-ctl.h35
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);