From cecfaca55f24f6628beb9a918b10b7ffab266535 Mon Sep 17 00:00:00 2001 From: ben Date: Fri, 23 Jul 2010 18:25:13 +0200 Subject: glib curses input-event added (replacement for g_timeout) --- src/Makefile.am | 2 +- src/g_curses_input.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/g_curses_input.h | 12 ++++++++++ src/interface.c | 17 +++++++------- src/interface.h | 2 +- src/pa-sink-ctl.c | 7 ------ 6 files changed, 88 insertions(+), 17 deletions(-) create mode 100644 src/g_curses_input.c create mode 100644 src/g_curses_input.h 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 +#include +#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 +#include + +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 -- cgit