summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/g_curses_input.c65
-rw-r--r--src/g_curses_input.h12
-rw-r--r--src/interface.c17
-rw-r--r--src/interface.h2
-rw-r--r--src/pa-sink-ctl.c7
6 files changed, 88 insertions, 17 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 3c905b8..6f7a2ee 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
bin_PROGRAMS = pa-sink-ctl
-pa_sink_ctl_SOURCES = interface.c pa-sink-ctl.c sink.c sink_input.c g_unix_signal.c
+pa_sink_ctl_SOURCES = interface.c pa-sink-ctl.c sink.c sink_input.c g_unix_signal.c g_curses_input.c
AM_CFLAGS = -std=c99 -pedantic -Wall -Werror @PULSE_CFLAGS@ @PULSE_MAINLOOP_CFLAGS@ @GLIB_CFLAGS@
pa_sink_ctl_LDADD = @GLIB_LIBS@ @PULSE_LIBS@ @PULSE_MAINLOOP_LIBS@ @CURSES_LIBS@
diff --git a/src/g_curses_input.c b/src/g_curses_input.c
new file mode 100644
index 0000000..d84ddee
--- /dev/null
+++ b/src/g_curses_input.c
@@ -0,0 +1,65 @@
+#include <curses.h>
+#include <glib.h>
+#include "interface.h"
+
+typedef struct _GCursesInput {
+ GSource source;
+ WINDOW *win;
+} GCursesInput;
+
+static gboolean check(GSource *source)
+{
+ GCursesInput *curses_input = (GCursesInput*) source;
+ static int i = 0;
+ i++;
+ gint ch = wgetch(curses_input->win);
+ if (ch != ERR)
+ ungetch(ch);
+ return ch != ERR;
+}
+
+static gboolean prepare(GSource *source, gint *timeout_)
+{
+ *timeout_ = 2;
+ return check(source);
+}
+
+static gboolean dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
+{
+ GCursesInput *curses_input = (GCursesInput*) source;
+ return callback((gpointer)curses_input->win) ? TRUE : FALSE;
+}
+
+static GSourceFuncs SourceFuncs =
+{
+ .prepare = prepare,
+ .check = check,
+ .dispatch = dispatch,
+ .finalize = NULL,
+ .closure_callback = NULL, .closure_marshal = NULL
+};
+
+GSource *g_curses_input_source_new(WINDOW *win) {
+ GSource *source = g_source_new(&SourceFuncs, sizeof(GCursesInput));
+ GCursesInput *curses_input = (GCursesInput*) source;
+ curses_input->win = win;
+ nodelay(win, TRUE); /* important! make wgetch non-blocking */
+ return source;
+}
+
+guint g_curses_input_add_full(gint priority, WINDOW *win, GSourceFunc function, gpointer data, GDestroyNotify notify)
+{
+ g_return_val_if_fail(function != NULL, 0);
+ GSource *source = g_curses_input_source_new(win);
+ if (priority != G_PRIORITY_DEFAULT)
+ g_source_set_priority (source, priority);
+ g_source_set_callback(source, function, data, notify);
+ guint id = g_source_attach(source, NULL);
+ g_source_unref(source);
+ return id;
+}
+
+guint g_curses_input_add(WINDOW *win, GSourceFunc function, gpointer data)
+{
+ return g_curses_input_add_full(G_PRIORITY_DEFAULT, win, function, data, NULL);
+}
diff --git a/src/g_curses_input.h b/src/g_curses_input.h
new file mode 100644
index 0000000..23eb550
--- /dev/null
+++ b/src/g_curses_input.h
@@ -0,0 +1,12 @@
+#ifndef G_CURESES_INPUT_H
+#define G_CURESES_INPUT_H
+
+#include <ncurses.h>
+#include <glib.h>
+
+GSource *g_curses_input_source_new(WINDOW *screen);
+guint g_curses_input_add_full(gint priority, WINDOW *win, GSourceFunc function,
+ gpointer data, GDestroyNotify notify);
+guint g_curses_input_add(WINDOW *win, GSourceFunc function, gpointer data);
+
+#endif /* G_CURESES_INPUT_H */
diff --git a/src/interface.c b/src/interface.c
index 0b79ab4..67323e9 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -10,7 +10,9 @@
#include "interface.h"
#include "sink.h"
#include "pa-sink-ctl.h"
+
#include "g_unix_signal.h"
+#include "g_curses_input.h"
#define VOLUME_BAR_LEN 50
#define H_MSG_BOX 3
@@ -21,6 +23,7 @@ static WINDOW *menu_win;
static WINDOW *msg_win;
static guint resize_source_id;
+static guint input_source_id;
static gint chooser_sink;
static gint chooser_input;
@@ -42,13 +45,13 @@ void interface_init(void)
menu_win = newwin(0, 0, 0, 0);
msg_win = newwin(0, 0, 0, 0);
- nodelay(menu_win, TRUE); /* important! make wgetch non-blocking */
- keypad(menu_win, TRUE); /* multichar keys are mapped to one char */
+ keypad(menu_win, TRUE); /* multichar keys are mapped to one char */
/* "resizing" here is for initial box positioning and layout */
interface_resize(NULL);
- resize_source_id = g_unix_signal_add(SIGWINCH, interface_resize, NULL);
+ resize_source_id = g_unix_signal_add(SIGWINCH, interface_resize, NULL);
+ input_source_id = g_curses_input_add(menu_win, get_input, NULL);
refresh();
}
@@ -154,17 +157,13 @@ void print_volume(pa_volume_t volume, int mute, int y)
mvwprintw(menu_win, y, x + VOLUME_BAR_LEN, "]");
}
-void get_input(void)
+gboolean get_input(gpointer data)
{
gint c;
gboolean volume_increment = TRUE;
c = wgetch(menu_win);
switch (c) {
- case ERR:
- /* nothing typed in */
- return;
-
case 'k':
case 'w':
case KEY_UP:
@@ -293,11 +292,13 @@ void get_input(void)
quit();
break;
}
+ return TRUE;
}
void interface_clear(void)
{
g_source_remove(resize_source_id);
+ g_source_remove(input_source_id);
clear();
refresh();
endwin();
diff --git a/src/interface.h b/src/interface.h
index 89c038d..69483a7 100644
--- a/src/interface.h
+++ b/src/interface.h
@@ -7,7 +7,7 @@
void print_sink_list(void);
void print_input_list(gint);
void print_volume(pa_volume_t, gint, gint);
-void get_input(void);
+gboolean get_input(gpointer);
void interface_init(void);
gboolean interface_resize(gpointer);
void interface_clear(void);
diff --git a/src/pa-sink-ctl.c b/src/pa-sink-ctl.c
index 767a5a6..04d4481 100644
--- a/src/pa-sink-ctl.c
+++ b/src/pa-sink-ctl.c
@@ -63,12 +63,6 @@ static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, guint32
collect_all_info();
}
-static int loop(gpointer data)
-{
- get_input();
- return TRUE;
-}
-
/*
* is called after connection
*/
@@ -88,7 +82,6 @@ void context_state_callback(pa_context *c, gpointer userdata)
case PA_CONTEXT_READY:
collect_all_info();
- g_timeout_add(3, loop, NULL);
pa_context_set_subscribe_callback(context, subscribe_cb, NULL);
g_assert((o = pa_context_subscribe(c, (pa_subscription_mask_t) (
PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SINK_INPUT