Commit f923bd2b96ac3f312b413cfbcbe8b4b4e956fa28

Thomas de Grivel 2020-05-14T17:36:11

async cli events in rtbuf-gtk

diff --git a/cli/cli.c b/cli/cli.c
index e098940..a8690cb 100644
--- a/cli/cli.c
+++ b/cli/cli.c
@@ -14,10 +14,12 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <err.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/select.h>
 #include <readline/readline.h>
 #include <readline/history.h>
 
@@ -140,6 +142,25 @@ int cli_read (s_cli *cli)
   return cli->argc;
 }
 
+int cli_read_nonblocking (s_cli *cli)
+{
+  fd_set fds;
+  struct timeval timeout;
+  int s;
+  FD_ZERO(&fds);
+  FD_SET(STDIN_FILENO, &fds);
+  timeout.tv_sec = 0;
+  timeout.tv_usec = 0;
+  s = select(1, &fds, NULL, NULL, &timeout);
+  if (s < 0) {
+    warn("cli_read_nonblocking: select");
+    return -1;
+  }
+  if (s == 1)
+    return cli_read(cli);
+  return -2;
+}
+
 f_cli cli_find_function (s_cli *cli, const char *name, int arity)
 {
   const s_cli_function *function = cli->functions;
diff --git a/cli/cli.h b/cli/cli.h
index 0125d75..2ddc943 100644
--- a/cli/cli.h
+++ b/cli/cli.h
@@ -50,6 +50,7 @@ f_cli cli_find_function (s_cli *cli, const char *name, int arity);
 
 int cli_scan (s_cli *cli);
 int cli_read (s_cli *cli);
+int cli_read_nonblocking (s_cli *cli);
 int cli_read_file (s_cli *cli, FILE *fp);
 int cli_eval (s_cli *cli);
 
diff --git a/cli/include/rtbuf/cli.h b/cli/include/rtbuf/cli.h
index 0cc8b28..6f02ffe 100644
--- a/cli/include/rtbuf/cli.h
+++ b/cli/include/rtbuf/cli.h
@@ -26,4 +26,6 @@ void rtbuf_cli_args (int argc, char *argv[]);
 int rtbuf_cli_start ();
 int rtbuf_cli_stop ();
 
+int rtbuf_cli_do_event ();
+
 #endif /* RTBUF_CLI_H */
diff --git a/cli/rtbuf_cli.c b/cli/rtbuf_cli.c
index dc106ee..d6e9b10 100644
--- a/cli/rtbuf_cli.c
+++ b/cli/rtbuf_cli.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 Thomas de Grivel <thoxdg@gmail.com> +33614550127
+ * Copyright 2018,2020 Thomas de Grivel <thoxdg@gmail.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -367,6 +367,16 @@ int repl ()
   return 0;
 }
 
+int rtbuf_cli_do_event ()
+{
+  if (cli_read_nonblocking(&g_cli) >= 0) {
+    /* debug_read(cli.argc, cli.argv, cli.f); */
+    cli_eval(&g_cli);
+    return 1;
+  }
+  return 0;
+}
+
 void rtbuf_cli_args (int argc, char *argv[])
 {
   while (--argc) {
diff --git a/gtk/rtbuf_gtk.c b/gtk/rtbuf_gtk.c
index a208c45..69eca6e 100644
--- a/gtk/rtbuf_gtk.c
+++ b/gtk/rtbuf_gtk.c
@@ -16,6 +16,7 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <time.h>
 #include <pthread.h>
 #include <gtk/gtk.h>
 #include <rtbuf/rtbuf.h>
@@ -554,6 +555,24 @@ void rtbuf_gtk_unbind_cb (s_rtbuf *src, unsigned int out,
   gtk_widget_queue_draw(GTK_WIDGET(modular_layout));
 }
 
+void main_loop (void)
+{
+  struct timespec timeout;
+  timeout.tv_sec = 0;
+  timeout.tv_nsec = 1000000;
+  while (1) {
+    int sleep = 1;
+    if (rtbuf_cli_do_event())
+      sleep = 0;
+    if (gtk_events_pending()) {
+      gtk_main_iteration();
+      sleep = 0;
+    }
+    if (sleep)
+      nanosleep(&timeout, NULL);
+  }
+}
+
 int main (int argc, char *argv[])
 {
   symbols_init();
@@ -570,7 +589,9 @@ int main (int argc, char *argv[])
   if (rtbuf_gtk_builder())
     return 1;
   rtbuf_gtk_modular();
-  gtk_main();
+  repl_init();
+  rtbuf_cli_args(argc, argv);
+  main_loop();
   return 0;
 }
 
diff --git a/gtk/rtbuf_gtk_cli.c b/gtk/rtbuf_gtk_cli.c
new file mode 100644
index 0000000..8332025
--- /dev/null
+++ b/gtk/rtbuf_gtk_cli.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020 Thomas de Grivel <thoxdg@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <assert.h>
+#include <pthread.h>
+#include <rtbuf/rtbuf.h>
+#include <rtbuf/cli.h>
+#include "rtbuf_gtk.h"
+
+pthread_t g_rtbuf_gtk_cli_thread = 0;
+
+void * rtbuf_gtk_cli_thread_proc (void *arg)
+{
+  (void) arg;
+  assert(g_rtbuf);
+  assert(g_argc);
+  assert(g_argv);
+  repl();
+  return 0;
+}
+
+void rtbuf_gtk_cli_start ()
+{
+  if (pthread_create(&g_rtbuf_gtk_cli_thread, 0,
+                     &rtbuf_gtk_cli_thread_proc, 0))
+    rtbuf_err("rtbuf_gtk_cli_start: pthread_create failed");
+}