summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interface.c15
-rw-r--r--src/pa-sink-ctl.c59
2 files changed, 55 insertions, 19 deletions
diff --git a/src/interface.c b/src/interface.c
index c3c8ba7..d45bff7 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -4,6 +4,7 @@
#include <ncurses.h>
#include <string.h>
#include <stdlib.h>
+#include <stdbool.h>
#include "interface.h"
#include "sink.h"
@@ -38,6 +39,7 @@ void interface_init(void)
startx = (80 - WIDTH) / 2;
starty = (24 - HEIGHT) / 2;
menu_win = newwin(HEIGHT, WIDTH, starty, startx);
+ nodelay(menu_win, TRUE); /* important! make wgetch non-blocking */
keypad(menu_win, TRUE);
curs_set(0); /* hide cursor */
mvprintw(0, 0, "Use arrow keys to go up and down, Press enter to select a choice");
@@ -130,6 +132,10 @@ void get_input(void)
c = wgetch(menu_win);
switch (c) {
+ case ERR:
+ /* nothing typed in */
+ return;
+
case 'k':
case KEY_UP:
if (chooser_input == -1 && chooser_sink > 0) {
@@ -139,6 +145,7 @@ void get_input(void)
else if (chooser_input >= 0)
--chooser_input;
+ print_sink_list();
break;
case 'j':
@@ -149,6 +156,7 @@ void get_input(void)
}
else if (chooser_input < ((gint)sink_list_get(chooser_sink)->input_list->len - 1))
++chooser_input;
+ print_sink_list();
break;
case 'h':
@@ -192,7 +200,7 @@ void get_input(void)
);
pa_operation_unref(tmp.volume_set(context, tmp.index, &tmp.volume, change_callback, NULL));
- return;
+ break;
case 'm':
case 'M': {
struct tmp_t {
@@ -218,7 +226,7 @@ void get_input(void)
break;
pa_operation_unref(tmp.mute_set(context, tmp.index, !tmp.mute, change_callback, NULL));
- return;
+ break;
}
case '\n':
case ' ':
@@ -234,7 +242,7 @@ void get_input(void)
pa_operation_unref(pa_context_move_sink_input_by_index(context, selected_index,
sink_list_get(chooser_sink)->index,
change_callback, NULL));
- return;
+ break;
case 'q':
default:
@@ -242,7 +250,6 @@ void get_input(void)
quit();
break;
}
- collect_all_info();
}
void interface_clear(void)
diff --git a/src/pa-sink-ctl.c b/src/pa-sink-ctl.c
index 2acc7df..b811edf 100644
--- a/src/pa-sink-ctl.c
+++ b/src/pa-sink-ctl.c
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdbool.h>
#include <glib.h>
@@ -20,10 +21,14 @@
#define HEIGHT 10
GArray *sink_list = NULL;
+GArray *sink_list_tmp = NULL;
pa_mainloop_api *mainloop_api = NULL;
pa_context *context = NULL;
+bool info_callbacks_finished = true;
+bool state_callback_pending = false;
+
int main(int argc, char** argv)
{
GMainContext *g_context = NULL;
@@ -34,7 +39,7 @@ int main(int argc, char** argv)
interface_init();
- g_context = g_main_context_new();
+ g_context = g_main_context_default();
g_loop = g_main_loop_new(g_context, false);
if (!(m = pa_glib_mainloop_new(g_context))) {
@@ -64,6 +69,21 @@ int main(int argc, char** argv)
return 0;
}
+
+static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata)
+{
+ if (!info_callbacks_finished)
+ state_callback_pending = true;
+ else
+ collect_all_info();
+}
+
+static int loop(gpointer data)
+{
+ get_input();
+ return true;
+}
+
/*
* is called after connection
*/
@@ -71,20 +91,18 @@ void context_state_callback(pa_context *c, void *userdata)
{
switch (pa_context_get_state(c)) {
case PA_CONTEXT_CONNECTING:
-// printf("connecting...\n");
- break;
-
case PA_CONTEXT_AUTHORIZING:
-// printf("authorizing...\n");
- break;
-
case PA_CONTEXT_SETTING_NAME:
-// printf("setting name\n");
break;
case PA_CONTEXT_READY:
-// printf("Menue\n");
collect_all_info();
+ g_timeout_add(3, loop, NULL);
+ pa_context_set_subscribe_callback(context, subscribe_cb, NULL);
+ pa_operation *o;
+ g_assert((o = pa_context_subscribe(c, (pa_subscription_mask_t) (
+ PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SINK_INPUT
+ ), NULL, NULL)));
break;
default:
@@ -108,7 +126,7 @@ void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_last, v
return;
}
- g_array_append_val(sink_list, ((sink_info) {
+ g_array_append_val(sink_list_tmp, ((sink_info) {
.index = i->index,
.mute = i->mute,
.vol = pa_cvolume_avg(&i->volume),
@@ -133,8 +151,16 @@ void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info *i, in
}
if (is_last) {
+ info_callbacks_finished = true;
+ sink_list_free(sink_list);
+ sink_list = sink_list_tmp;
+
print_sink_list();
- get_input();
+
+ if (state_callback_pending) {
+ state_callback_pending = false;
+ collect_all_info();
+ }
return;
}
@@ -143,7 +169,7 @@ void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info *i, in
snprintf(t, sizeof(t), "%u", i->owner_module);
snprintf(k, sizeof(k), "%u", i->client);
- g_array_append_val(sink_list_get(i->sink)->input_list, ((sink_input_info) {
+ g_array_append_val(g_array_index(sink_list_tmp, sink_info, i->sink).input_list, ((sink_input_info) {
.index = i->index,
.sink = i->sink,
.name = strdup(pa_proplist_gets(i->proplist, "application.name")),
@@ -166,12 +192,15 @@ void quit(void)
*/
void change_callback(pa_context* c, int success, void* userdate)
{
- collect_all_info();
+ print_sink_list();
}
void collect_all_info(void)
{
- sink_list_free(sink_list);
- sink_list = sink_list_alloc();
+ if (!info_callbacks_finished)
+ return;
+ info_callbacks_finished = false;
+
+ sink_list_tmp = sink_list_alloc();
pa_operation_unref(pa_context_get_sink_info_list(context, get_sink_info_callback, NULL));
}