summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Persch <chpe@src.gnome.org>2020-03-24 19:10:32 +0100
committerChristian Persch <chpe@src.gnome.org>2020-03-24 19:10:32 +0100
commitfd91213485aff9304403f34f1bdaf9f67bca646c (patch)
treec7590b220092ebe3a1c09ab9482c5ef50e54d09f /src
parent070085ea5d7e7dab48b0b8780add3e782948d025 (diff)
downloadvte-fd91213485aff9304403f34f1bdaf9f67bca646c.tar.gz
app: Add test for vte_terminal_feed_child
When passed --feed-stdin, read data from stdin and write it to the terminal with vte_terminal_feed_child().
Diffstat (limited to 'src')
-rw-r--r--src/app/app.cc79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/app/app.cc b/src/app/app.cc
index 0c7eed5d..5cb08f57 100644
--- a/src/app/app.cc
+++ b/src/app/app.cc
@@ -23,10 +23,12 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <termios.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gi18n.h>
+#include <glib-unix.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
#include <cairo/cairo-gobject.h>
@@ -46,6 +48,7 @@ public:
gboolean bold_is_bright{false};
gboolean console{false};
gboolean debug{false};
+ gboolean feed_stdin{false};
gboolean icon_title{false};
gboolean keep{false};
gboolean no_argb_visual{false};
@@ -370,6 +373,8 @@ public:
"Add environment variable to the child\'s environment", "VAR=VALUE" },
{ "extra-margin", 0, 0, G_OPTION_ARG_INT, &extra_margin,
"Add extra margin around the terminal widget", "MARGIN" },
+ { "feed-stdin", 'B', 0, G_OPTION_ARG_NONE, &feed_stdin,
+ "Feed input to the terminal", nullptr },
{ "font", 'f', 0, G_OPTION_ARG_STRING, &font_string,
"Specify a font to use", nullptr },
{ "foreground-color", 0, 0, G_OPTION_ARG_CALLBACK, (void*)parse_fg_color,
@@ -2063,6 +2068,8 @@ typedef struct _VteappApplicationClass VteappApplicationClass;
struct _VteappApplication {
GtkApplication parent;
+
+ guint input_source;
};
struct _VteappApplicationClass {
@@ -2094,6 +2101,37 @@ app_action_close_cb(GSimpleAction* action,
gtk_widget_destroy(GTK_WIDGET(window));
}
+static gboolean
+app_stdin_readable_cb(int fd,
+ GIOCondition condition,
+ VteappApplication* application)
+{
+ auto eos = bool{false};
+ if (condition & G_IO_IN) {
+ auto window = gtk_application_get_active_window(GTK_APPLICATION(application));
+ auto terminal = VTEAPP_IS_WINDOW(window) ? VTEAPP_WINDOW(window)->terminal : nullptr;
+
+ char buf[4096];
+ auto r = int{0};
+ do {
+ errno = 0;
+ r = read(fd, buf, sizeof(buf));
+ if (r > 0 && terminal != nullptr)
+ vte_terminal_feed_child(terminal, buf, r);
+ } while (r > 0 || errno == EINTR);
+
+ if (r == 0)
+ eos = true;
+ }
+
+ if (eos) {
+ application->input_source = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
G_DEFINE_TYPE(VteappApplication, vteapp_application, GTK_TYPE_APPLICATION)
static void
@@ -2105,6 +2143,27 @@ vteapp_application_init(VteappApplication* application)
/* Make gtk+ CSD not steal F10 from the terminal */
"gtk-menu-bar-accel", nullptr,
nullptr);
+
+ if (options.feed_stdin) {
+ g_unix_set_fd_nonblocking(STDIN_FILENO, true, nullptr);
+ application->input_source = g_unix_fd_add(STDIN_FILENO,
+ GIOCondition(G_IO_IN | G_IO_HUP | G_IO_ERR),
+ (GUnixFDSourceFunc)app_stdin_readable_cb,
+ application);
+ }
+}
+
+static void
+vteapp_application_dispose(GObject* object)
+{
+ VteappApplication* application = VTEAPP_APPLICATION(object);
+
+ if (application->input_source != 0) {
+ g_source_remove(application->input_source);
+ application->input_source = 0;
+ }
+
+ G_OBJECT_CLASS(vteapp_application_parent_class)->dispose(object);
}
static void
@@ -2134,6 +2193,9 @@ vteapp_application_activate(GApplication* application)
static void
vteapp_application_class_init(VteappApplicationClass* klass)
{
+ GObjectClass* object_class = G_OBJECT_CLASS(klass);
+ object_class->dispose = vteapp_application_dispose;
+
GApplicationClass* application_class = G_APPLICATION_CLASS(klass);
application_class->startup = vteapp_application_startup;
application_class->activate = vteapp_application_activate;
@@ -2189,9 +2251,26 @@ main(int argc,
}
#endif
+ auto reset_termios = bool{false};
+ struct termios saved_tcattr;
+ if (options.feed_stdin && isatty(STDIN_FILENO)) {
+ /* Put terminal in raw mode */
+
+ struct termios tcattr;
+ if (tcgetattr(STDIN_FILENO, &tcattr) == 0) {
+ saved_tcattr = tcattr;
+ cfmakeraw(&tcattr);
+ if (tcsetattr(STDIN_FILENO, TCSANOW, &tcattr) == 0)
+ reset_termios = true;
+ }
+ }
+
auto app = vteapp_application_new();
auto rv = g_application_run(app, 0, nullptr);
g_object_unref(app);
+ if (reset_termios)
+ tcsetattr(STDIN_FILENO, TCSANOW, &saved_tcattr);
+
return rv;
}