From: Daniel Elstner Date: Fri, 9 Oct 2015 16:26:00 +0000 (+0200) Subject: anykey: Use GLib I/O channel watch X-Git-Tag: sigrok-cli-0.6.0~5 X-Git-Url: https://sigrok.org/gitweb/?p=sigrok-cli.git;a=commitdiff_plain;h=fd65ec4c9c349a9ed240fedf69946abea7afd047 anykey: Use GLib I/O channel watch Watch for input on a GLib I/O channel using the standard GLib main loop API instead of injecting an FD event source into the sigrok session loop. Also run the session in a main loop created by sigrok-cli instead of using sr_session_run(). This is mainly for demonstration; the GLib I/O watch change would work even with sr_session_run() since it is using the same main context in this case. --- diff --git a/anykey.c b/anykey.c index 7c801f1..b1ac9ef 100644 --- a/anykey.c +++ b/anykey.c @@ -23,8 +23,8 @@ #include #else #include -#endif #include +#endif #include #include #include "sigrok-cli.h" @@ -35,32 +35,38 @@ static DWORD stdin_mode; #else static struct termios term_orig; #endif +static unsigned int watch_id = 0; -static int received_anykey(int fd, int revents, void *cb_data) +static gboolean received_anykey(GIOChannel *source, + GIOCondition condition, void *data) { struct sr_session *session; - (void)fd; - (void)revents; + (void)source; + (void)condition; + session = data; - session = cb_data; - sr_session_source_remove(session, STDIN_FILENO); + watch_id = 0; sr_session_stop(session); - return TRUE; + return G_SOURCE_REMOVE; } -/* Turn off buffering on stdin. */ +/* Turn off buffering on stdin and watch for input. + */ void add_anykey(struct sr_session *session) { + GIOChannel *channel; + #ifdef _WIN32 stdin_handle = GetStdHandle(STD_INPUT_HANDLE); if (!GetConsoleMode(stdin_handle, &stdin_mode)) { /* TODO: Error handling. */ } - SetConsoleMode(stdin_handle, 0); + + channel = g_io_channel_win32_new_fd(0); #else struct termios term; @@ -68,17 +74,26 @@ void add_anykey(struct sr_session *session) memcpy(&term_orig, &term, sizeof(struct termios)); term.c_lflag &= ~(ECHO | ICANON | ISIG); tcsetattr(STDIN_FILENO, TCSADRAIN, &term); + + channel = g_io_channel_unix_new(STDIN_FILENO); #endif + g_io_channel_set_encoding(channel, NULL, NULL); + g_io_channel_set_buffered(channel, FALSE); - sr_session_source_add(session, STDIN_FILENO, G_IO_IN, -1, - received_anykey, session); + watch_id = g_io_add_watch(channel, G_IO_IN, &received_anykey, session); + g_io_channel_unref(channel); g_message("Press any key to stop acquisition."); } -/* Restore stdin attributes. */ +/* Remove the event watch and restore stdin attributes. + */ void clear_anykey(void) { + if (watch_id != 0) { + g_source_remove(watch_id); + watch_id = 0; + } #ifdef _WIN32 SetConsoleMode(stdin_handle, stdin_mode); #else diff --git a/session.c b/session.c index 6f40205..f71f999 100644 --- a/session.c +++ b/session.c @@ -531,6 +531,7 @@ void run_session(void) int is_demo_dev; struct sr_dev_driver *driver; const struct sr_transform *t; + GMainLoop *main_loop; devices = device_scan(); if (!devices) { @@ -682,8 +683,14 @@ void run_session(void) if (!(t = setup_transform_module(sdi))) g_critical("Failed to initialize transform module."); + main_loop = g_main_loop_new(NULL, FALSE); + + sr_session_stopped_callback_set(session, + (sr_session_stopped_callback)g_main_loop_quit, main_loop); + if (sr_session_start(session) != SR_OK) { g_critical("Failed to start session."); + g_main_loop_unref(main_loop); sr_session_destroy(session); return; } @@ -691,7 +698,7 @@ void run_session(void) if (opt_continuous) add_anykey(session); - sr_session_run(session); + g_main_loop_run(main_loop); if (opt_continuous) clear_anykey(); @@ -700,6 +707,6 @@ void run_session(void) sr_trigger_free(trigger); sr_session_datafeed_callback_remove_all(session); + g_main_loop_unref(main_loop); sr_session_destroy(session); - }