diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2019-05-23 08:03:25 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2019-05-23 08:03:25 +0200 |
commit | babcc9ea1373677401c01d16c174ea4a7593d5d8 (patch) | |
tree | aad0157f30dbd39ee9c8717bd0de56a05d6f7ae5 | |
download | gterm-babcc9ea1373677401c01d16c174ea4a7593d5d8.tar.gz |
minimal terminal implementation
-rw-r--r-- | gterm.c | 106 | ||||
-rw-r--r-- | meson.build | 17 |
2 files changed, 123 insertions, 0 deletions
@@ -0,0 +1,106 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <pwd.h> + +#include <sys/types.h> + +#include <gtk/gtk.h> +#include <vte/vte.h> + +typedef struct gterm { + GtkWidget *window; + GtkWidget *terminal; + GPid pid; + gint exit_code; +} gterm; + +static void gterm_spawn_cb(VteTerminal *terminal, GPid pid, + GError *error, gpointer user_data) +{ + gterm *gt = user_data; + + if (error) { + fprintf(stderr, "ERROR: %s\n", error->message); + gt->exit_code = 1; + gtk_main_quit(); + } else { + gt->pid = pid; + } +} + +static void gterm_spawn(gterm *gt, char *argv[]) +{ + vte_terminal_spawn_async(VTE_TERMINAL(gt->terminal), + VTE_PTY_DEFAULT, + NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + NULL, + -1, + NULL, + gterm_spawn_cb, + gt); +} + +static void gterm_spawn_shell(gterm *gt) +{ + struct passwd *pwent; + char *argv[2]; + + pwent = getpwent(); + argv[0] = strdup(pwent->pw_shell); + argv[1] = NULL; + gterm_spawn(gt, argv); +} + +static void gterm_vte_child_exited(VteTerminal *vteterminal, + gint status, + gpointer user_data) +{ + gterm *gt = user_data; + + if (WIFEXITED(status)) + gt->exit_code = WEXITSTATUS(status); + if (WIFSIGNALED(status)) + gt->exit_code = 1; + gtk_main_quit(); +} + +static void gterm_window_destroy(GtkWidget *widget, gpointer data) +{ + gtk_main_quit(); +} + +static gterm *gterm_new(void) +{ + gterm *gt = g_new0(gterm, 1); + + gt->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + g_signal_connect(G_OBJECT(gt->window), "destroy", + G_CALLBACK(gterm_window_destroy), gt); + + gt->terminal = vte_terminal_new(); + g_signal_connect(G_OBJECT(gt->terminal), "child-exited", + G_CALLBACK(gterm_vte_child_exited), gt); + + gtk_container_add(GTK_CONTAINER(gt->window), gt->terminal); + gtk_widget_show_all(gt->window); + return gt; +} + +int main(int argc, char *argv[]) +{ + gterm *gt; + + gtk_init(&argc, &argv); + + gt = gterm_new(); + gterm_spawn_shell(gt); + + gtk_main(); + return gt->exit_code; +} diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..96f19f0 --- /dev/null +++ b/meson.build @@ -0,0 +1,17 @@ +project('gterm', 'c', default_options : [ 'c_std=c99' ] ) + +# tweak warnings +add_global_arguments('-D_POSIX_SOURCE=1', language : 'c') +add_global_arguments('-D_GNU_SOURCE=1', language : 'c') + +# pkg-config deps +gtk_dep = dependency('gtk+-3.0') +vte_dep = dependency('vte-2.91') + +executable('gterm', + sources : [ 'gterm.c' ], + dependencies : [ gtk_dep, vte_dep ], + install : true) + +#install_man('gterm.1') + |