anykey: Use GLib I/O channel watch
authorDaniel Elstner <daniel.kitta@gmail.com>
Fri, 9 Oct 2015 16:26:00 +0000 (18:26 +0200)
committerDaniel Elstner <daniel.kitta@gmail.com>
Fri, 9 Oct 2015 18:33:04 +0000 (20:33 +0200)
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.

anykey.c
session.c

index 7c801f1ce8b8bb6dbb3983346ff264330c8e1ab3..b1ac9ef430a80df681ee1442e99d8bbc6712fe11 100644 (file)
--- a/anykey.c
+++ b/anykey.c
@@ -23,8 +23,8 @@
 #include <windows.h>
 #else
 #include <termios.h>
-#endif
 #include <unistd.h>
+#endif
 #include <string.h>
 #include <glib.h>
 #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
index 6f402056c0eadfdac17b4ad829bf191aa2bdbf5e..f71f999bd10491449b191e14786d62f9edb28eb6 100644 (file)
--- 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);
-
 }