[vte] vteapp: Add back C test application
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] vteapp: Add back C test application
- Date: Thu, 22 May 2014 18:28:35 +0000 (UTC)
commit 3e211284104be539a951976ec6f62d203e8a60f5
Author: Christian Persch <chpe gnome org>
Date: Thu May 22 20:26:59 2014 +0200
vteapp: Add back C test application
So you can test vte when building with vala fails.
src/Makefile.am | 25 ++-
src/vteapp.c | 1161 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 1184 insertions(+), 2 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 8918016..a36ac21 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,5 +1,5 @@
bin_PROGRAMS =
-noinst_PROGRAMS =
+noinst_PROGRAMS = testvte
CLEANFILES =
DISTCLEANFILES =
@@ -231,7 +231,28 @@ endif # ENABLE_VAPIGEN
endif # HAVE_INTROSPECTION
-# Test application
+# C Test application
+
+testvte_SOURCES = \
+ vteapp.c \
+ debug.c \
+ debug.h \
+ $(NULL)
+
+testvte_CPPFLAGS = \
+ -DGLIB_DISABLE_DEPRECATION_WARNINGS \
+ -DGDK_DISABLE_DEPRECATION_WARNINGS \
+ $(AM_CPPFLAGS)
+
+testvte_CFLAGS = \
+ $(VTE_CFLAGS) \
+ $(AM_CFLAGS)
+
+testvte_LDADD = \
+ libvte-$(VTE_API_VERSION).la \
+ $(VTE_LIBS)
+
+# VALA Test application
if ENABLE_TEST_APPLICATION
diff --git a/src/vteapp.c b/src/vteapp.c
new file mode 100644
index 0000000..0883b60
--- /dev/null
+++ b/src/vteapp.c
@@ -0,0 +1,1161 @@
+/*
+ * Copyright (C) 2001,2002 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <gtk/gtk.h>
+#include <glib-object.h>
+#include "debug.h"
+
+#undef VTE_DISABLE_DEPRECATED
+#include "vte.h"
+
+#include <glib/gi18n.h>
+
+#define DINGUS1
"(((gopher|news|telnet|nntp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+(:[0-9]*)?"
+#define DINGUS2 DINGUS1 "/[-A-Za-z0-9_\\$\\.\\+\\!\\*\\(\\),;:@&=\\?/~\\#\\%]*[^]'\\.}>\\) ,\\\"]"
+
+static const char *builtin_dingus[] = {
+ DINGUS1,
+ DINGUS2,
+ NULL
+};
+
+static void
+window_title_changed(GtkWidget *widget, gpointer win)
+{
+ GtkWindow *window;
+
+ g_assert(VTE_TERMINAL(widget));
+ g_assert(GTK_IS_WINDOW(win));
+ window = GTK_WINDOW(win);
+
+ gtk_window_set_title(window, vte_terminal_get_window_title(VTE_TERMINAL(widget)));
+}
+
+static void
+icon_title_changed(GtkWidget *widget, gpointer win)
+{
+ g_assert(VTE_TERMINAL(widget));
+ g_assert(GTK_IS_WINDOW(win));
+
+ g_message("Icon title changed to \"%s\".\n",
+ vte_terminal_get_icon_title(VTE_TERMINAL(widget)));
+}
+
+static void
+char_size_changed(GtkWidget *widget, guint width, guint height, gpointer data)
+{
+ VteTerminal *terminal = VTE_TERMINAL(widget);
+ GtkWindow *window = GTK_WINDOW(data);
+
+ if (!gtk_widget_get_realized (widget))
+ return;
+
+ vte_terminal_set_geometry_hints_for_window(terminal, window);
+}
+
+static void
+char_size_realized(GtkWidget *widget, gpointer data)
+{
+ VteTerminal *terminal = VTE_TERMINAL(widget);
+ GtkWindow *window = GTK_WINDOW(data);
+
+ if (!gtk_widget_get_realized (widget))
+ return;
+
+ vte_terminal_set_geometry_hints_for_window(terminal, window);
+}
+
+
+static void
+destroy_and_quit(VteTerminal *terminal, GtkWidget *window)
+{
+ const char *output_file = g_object_get_data (G_OBJECT (terminal), "output_file");
+
+ if (output_file) {
+ GFile *file;
+ GOutputStream *stream;
+ GError *error = NULL;
+
+ file = g_file_new_for_commandline_arg (output_file);
+ stream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL,
&error));
+
+ if (stream) {
+ vte_terminal_write_contents (terminal, stream,
+ VTE_WRITE_DEFAULT,
+ NULL, &error);
+ g_object_unref (stream);
+ }
+
+ if (error) {
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ }
+
+ g_object_unref (file);
+ }
+
+ gtk_widget_destroy (window);
+ gtk_main_quit ();
+}
+static void
+delete_event(GtkWidget *window, GdkEvent *event, gpointer terminal)
+{
+ destroy_and_quit(VTE_TERMINAL (terminal), window);
+}
+static void
+child_exited(GtkWidget *terminal, int status, gpointer window)
+{
+ _vte_debug_print(VTE_DEBUG_MISC, "Child exited with status %x\n", status);
+ destroy_and_quit(VTE_TERMINAL (terminal), GTK_WIDGET (window));
+}
+
+static int
+button_pressed(GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+ VteTerminal *terminal;
+ char *match;
+ int tag;
+ GtkBorder padding;
+ int char_width, char_height;
+
+ switch (event->button) {
+ case 3:
+ terminal = VTE_TERMINAL(widget);
+
+ gtk_style_context_get_padding(gtk_widget_get_style_context(widget),
+ gtk_widget_get_state_flags(widget),
+ &padding);
+ char_width = vte_terminal_get_char_width (terminal);
+ char_height = vte_terminal_get_char_height (terminal);
+ match = vte_terminal_match_check(terminal,
+ (event->x - padding.left) / char_width,
+ (event->y - padding.top) / char_height,
+ &tag);
+ if (match != NULL) {
+ g_print("Matched `%s' (%d).\n", match, tag);
+ g_free(match);
+ if (GPOINTER_TO_INT(data) != 0) {
+ vte_terminal_match_remove(terminal, tag);
+ }
+ }
+ break;
+ case 1:
+ case 2:
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static void
+iconify_window(GtkWidget *widget, gpointer data)
+{
+ gtk_window_iconify(data);
+}
+
+static void
+deiconify_window(GtkWidget *widget, gpointer data)
+{
+ gtk_window_deiconify(data);
+}
+
+static void
+raise_window(GtkWidget *widget, gpointer data)
+{
+ GdkWindow *window;
+
+ if (GTK_IS_WIDGET(data)) {
+ window = gtk_widget_get_window(GTK_WIDGET(data));
+ if (window) {
+ gdk_window_raise(window);
+ }
+ }
+}
+
+static void
+lower_window(GtkWidget *widget, gpointer data)
+{
+ GdkWindow *window;
+
+ if (GTK_IS_WIDGET(data)) {
+ window = gtk_widget_get_window(GTK_WIDGET(data));
+ if (window) {
+ gdk_window_lower(window);
+ }
+ }
+}
+
+static void
+maximize_window(GtkWidget *widget, gpointer data)
+{
+ GdkWindow *window;
+
+ if (GTK_IS_WIDGET(data)) {
+ window = gtk_widget_get_window(GTK_WIDGET(data));
+ if (window) {
+ gdk_window_maximize(window);
+ }
+ }
+}
+
+static void
+restore_window(GtkWidget *widget, gpointer data)
+{
+ GdkWindow *window;
+
+ if (GTK_IS_WIDGET(data)) {
+ window = gtk_widget_get_window(GTK_WIDGET(data));
+ if (window) {
+ gdk_window_unmaximize(window);
+ }
+ }
+}
+
+static void
+refresh_window(GtkWidget *widget, gpointer data)
+{
+ GdkWindow *window;
+ GtkAllocation allocation;
+ GdkRectangle rect;
+
+ if (GTK_IS_WIDGET(data)) {
+ window = gtk_widget_get_window(widget);
+ if (window) {
+ gtk_widget_get_allocation(widget, &allocation);
+ rect.x = rect.y = 0;
+ rect.width = allocation.width;
+ rect.height = allocation.height;
+ gdk_window_invalidate_rect(window, &rect, TRUE);
+ }
+ }
+}
+
+static void
+resize_window(GtkWidget *widget, guint width, guint height, gpointer data)
+{
+ VteTerminal *terminal;
+
+ if ((GTK_IS_WINDOW(data)) && (width >= 2) && (height >= 2)) {
+ gint owidth, oheight, char_width, char_height, column_count, row_count;
+ GtkBorder padding;
+
+ terminal = VTE_TERMINAL(widget);
+
+ gtk_window_get_size(GTK_WINDOW(data), &owidth, &oheight);
+
+ /* Take into account border overhead. */
+ char_width = vte_terminal_get_char_width (terminal);
+ char_height = vte_terminal_get_char_height (terminal);
+ column_count = vte_terminal_get_column_count (terminal);
+ row_count = vte_terminal_get_row_count (terminal);
+ gtk_style_context_get_padding(gtk_widget_get_style_context(widget),
+ gtk_widget_get_state_flags(widget),
+ &padding);
+
+ owidth -= char_width * column_count + padding.left + padding.right;
+ oheight -= char_height * row_count + padding.top + padding.bottom;
+ gtk_window_resize(GTK_WINDOW(data),
+ width + owidth, height + oheight);
+ }
+}
+
+static void
+move_window(GtkWidget *widget, guint x, guint y, gpointer data)
+{
+ GdkWindow *window;
+
+ if (GTK_IS_WIDGET(data)) {
+ window = gtk_widget_get_window(GTK_WIDGET(data));
+ if (window) {
+ gdk_window_move(window, x, y);
+ }
+ }
+}
+
+static void
+adjust_font_size(GtkWidget *widget, gpointer data, gdouble factor)
+{
+ VteTerminal *terminal;
+ gdouble scale;
+ glong char_width, char_height;
+ gint columns, rows, owidth, oheight;
+
+ /* Read the screen dimensions in cells. */
+ terminal = VTE_TERMINAL(widget);
+ columns = vte_terminal_get_column_count(terminal);
+ rows = vte_terminal_get_row_count(terminal);
+
+ /* Take into account padding and border overhead. */
+ gtk_window_get_size(GTK_WINDOW(data), &owidth, &oheight);
+ char_width = vte_terminal_get_char_width (terminal);
+ char_height = vte_terminal_get_char_height (terminal);
+ owidth -= char_width * columns;
+ oheight -= char_height * rows;
+
+ scale = vte_terminal_get_font_scale(terminal);
+ vte_terminal_set_font_scale(terminal, scale * factor);
+
+ /* This above call will have changed the char size! */
+ char_width = vte_terminal_get_char_width (terminal);
+ char_height = vte_terminal_get_char_height (terminal);
+
+ gtk_window_resize(GTK_WINDOW(data),
+ columns * char_width + owidth,
+ rows * char_height + oheight);
+}
+
+static void
+increase_font_size(GtkWidget *widget, gpointer data)
+{
+ adjust_font_size(widget, data, 1.2);
+}
+
+static void
+decrease_font_size(GtkWidget *widget, gpointer data)
+{
+ adjust_font_size(widget, data, 1. / 1.2);
+}
+
+static gboolean
+read_and_feed(GIOChannel *source, GIOCondition condition, gpointer data)
+{
+ char buf[2048];
+ gsize size;
+ GIOStatus status;
+ g_assert(VTE_IS_TERMINAL(data));
+ status = g_io_channel_read_chars(source, buf, sizeof(buf),
+ &size, NULL);
+ if ((status == G_IO_STATUS_NORMAL) && (size > 0)) {
+ vte_terminal_feed(VTE_TERMINAL(data), buf, size);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+disconnect_watch(gpointer data)
+{
+ g_source_remove(GPOINTER_TO_INT(data));
+}
+
+static void
+clipboard_get(GtkClipboard *clipboard, GtkSelectionData *selection_data,
+ guint info, gpointer owner)
+{
+ /* No-op. */
+ return;
+}
+
+static void
+take_xconsole_ownership(GtkWidget *widget, gpointer data)
+{
+ char *name, hostname[255];
+ GdkAtom atom;
+ GtkClipboard *clipboard;
+ GtkTargetList *target_list;
+ GtkTargetEntry *targets;
+ int n_targets;
+
+ target_list = gtk_target_list_new(NULL, 0);
+ gtk_target_list_add_text_targets(target_list, 0);
+ targets = gtk_target_table_new_from_list (target_list, &n_targets);
+ gtk_target_list_unref(target_list);
+
+ memset(hostname, '\0', sizeof(hostname));
+ gethostname(hostname, sizeof(hostname) - 1);
+
+ name = g_strdup_printf("MIT_CONSOLE_%s", hostname);
+ atom = gdk_atom_intern(name, FALSE);
+ clipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(widget),
+ atom);
+ g_free(name);
+
+ gtk_clipboard_set_with_owner(clipboard,
+ targets,
+ n_targets,
+ clipboard_get,
+ (GtkClipboardClearFunc)gtk_main_quit,
+ G_OBJECT(widget));
+}
+
+static void
+add_weak_pointer(GObject *object, GtkWidget **target)
+{
+ g_object_add_weak_pointer(object, (gpointer*)target);
+}
+
+static void
+terminal_notify_cb(GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GValue value = { 0, };
+ char *value_string;
+
+ if (!pspec ||
+ pspec->owner_type != VTE_TYPE_TERMINAL)
+ return;
+
+
+ g_value_init(&value, pspec->value_type);
+ g_object_get_property(object, pspec->name, &value);
+ value_string = g_strdup_value_contents(&value);
+ g_print("NOTIFY property \"%s\" value '%s'\n", pspec->name, value_string);
+ g_free(value_string);
+ g_value_unset(&value);
+}
+
+/* Derived terminal class */
+
+typedef struct _VteappTerminal VteappTerminal;
+typedef struct _VteappTerminalClass VteappTerminalClass;
+
+struct _VteappTerminalClass {
+ VteTerminalClass parent_class;
+};
+struct _VteappTerminal {
+ VteTerminal parent_instance;
+};
+
+static GType vteapp_terminal_get_type(void);
+
+G_DEFINE_TYPE(VteappTerminal, vteapp_terminal, VTE_TYPE_TERMINAL)
+
+static void
+vteapp_terminal_class_init(VteappTerminalClass *klass)
+{
+}
+
+static void
+vteapp_terminal_init(VteappTerminal *terminal)
+{
+}
+
+static GtkWidget *
+vteapp_terminal_new(void)
+{
+ return g_object_new(vteapp_terminal_get_type(), NULL);
+}
+
+/* Command line options */
+
+static int
+parse_enum(GType type,
+ const char *string)
+{
+ GEnumClass *enum_klass;
+ const GEnumValue *enum_value;
+ int value = 0;
+
+ enum_klass = (GEnumClass*)g_type_class_ref(type);
+ enum_value = g_enum_get_value_by_nick(enum_klass, string);
+ if (enum_value)
+ value = enum_value->value;
+ else
+ g_warning("Unknown enum '%s'\n", string);
+ g_type_class_unref(enum_klass);
+
+ return value;
+}
+
+static guint
+parse_flags(GType type,
+ const char *string)
+{
+ GFlagsClass *flags_klass;
+ guint value = 0;
+ char **flags;
+ guint i;
+
+ flags = g_strsplit_set(string, ",|", -1);
+ if (flags == NULL)
+ return 0;
+
+ flags_klass = (GFlagsClass*)g_type_class_ref(type);
+ for (i = 0; flags[i] != NULL; ++i) {
+ const GFlagsValue *flags_value;
+
+ flags_value = g_flags_get_value_by_nick(flags_klass, flags[i]);
+ if (flags_value)
+ value |= flags_value->value;
+ else
+ g_warning("Unknown flag '%s'\n", flags[i]);
+ }
+ g_type_class_unref(flags_klass);
+
+ return value;
+}
+
+static gboolean
+parse_color (const gchar *value,
+ GdkRGBA *color)
+{
+ if (!gdk_rgba_parse(color, value)) {
+ g_printerr("Failed to parse value \"%s\" as color", value);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+add_dingus (VteTerminal *terminal,
+ char **dingus)
+{
+ const GdkCursorType cursors[] = { GDK_GUMBY, GDK_HAND1 };
+ GRegex *regex;
+ GError *error;
+ int id, i;
+
+ for (i = 0; dingus[i]; ++i) {
+ error = NULL;
+ if (!(regex = g_regex_new(dingus[i], G_REGEX_OPTIMIZE, 0, &error))) {
+ g_warning("Failed to compile regex '%s': %s\n",
+ dingus[i], error->message);
+ g_error_free(error);
+ continue;
+ }
+
+ id = vte_terminal_match_add_gregex(terminal, regex, 0);
+ g_regex_unref (regex);
+ vte_terminal_match_set_cursor_type(terminal, id,
+ cursors[i % G_N_ELEMENTS(cursors)]);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ GdkScreen *screen;
+ GdkVisual *visual;
+ GtkWidget *window, *widget,*hbox = NULL, *scrollbar, *scrolled_window = NULL;
+ VteTerminal *terminal;
+ char *env_add[] = {
+#ifdef VTE_DEBUG
+ (char *) "FOO=BAR", (char *) "BOO=BIZ",
+#endif
+ NULL};
+ char *transparent = NULL;
+ char *encoding = NULL;
+ char *cjk_ambiguous_width = NULL;
+ gboolean audible = TRUE,
+ debug = FALSE, no_builtin_dingus = FALSE, dbuffer = TRUE,
+ console = FALSE, keep = FALSE,
+ icon_title = FALSE, shell = TRUE,
+ reverse = FALSE, use_geometry_hints = TRUE,
+ use_scrolled_window = FALSE,
+ show_object_notifications = FALSE, rewrap = TRUE;
+ char *geometry = NULL;
+ gint lines = -1;
+ const char *message = "Launching interactive shell...\r\n";
+ const char *font = NULL;
+ const char *command = NULL;
+ const char *working_directory = NULL;
+ const char *output_file = NULL;
+ char *pty_flags_string = NULL;
+ char *cursor_blink_mode_string = NULL;
+ char *cursor_shape_string = NULL;
+ char *scrollbar_policy_string = NULL;
+ char *border_width_string = NULL;
+ char *cursor_color_string = NULL;
+ char *highlight_foreground_color_string = NULL;
+ char *highlight_background_color_string = NULL;
+ char **dingus = NULL;
+ GdkRGBA fore, back;
+ const GOptionEntry options[]={
+ {
+ "console", 'C', 0,
+ G_OPTION_ARG_NONE, &console,
+ "Watch /dev/console", NULL
+ },
+ {
+ "no-builtin-dingus", 0, G_OPTION_FLAG_REVERSE,
+ G_OPTION_ARG_NONE, &no_builtin_dingus,
+ "Highlight URLs inside the terminal", NULL
+ },
+ {
+ "dingu", 'D', 0,
+ G_OPTION_ARG_STRING_ARRAY, &dingus,
+ "Add regex highlight", NULL
+ },
+ {
+ "no-rewrap", 'R', G_OPTION_FLAG_REVERSE,
+ G_OPTION_ARG_NONE, &rewrap,
+ "Disable rewrapping on resize", NULL
+ },
+ {
+ "shell", 'S', G_OPTION_FLAG_REVERSE,
+ G_OPTION_ARG_NONE, &shell,
+ "Disable spawning a shell inside the terminal", NULL
+ },
+ {
+ "transparent", 'T', 0,
+ G_OPTION_ARG_STRING, &transparent,
+ "Enable the use of a transparent background", "ALPHA"
+ },
+ {
+ "double-buffer", '2', G_OPTION_FLAG_REVERSE,
+ G_OPTION_ARG_NONE, &dbuffer,
+ "Disable double-buffering", NULL
+ },
+ {
+ "audible", 'a', G_OPTION_FLAG_REVERSE,
+ G_OPTION_ARG_NONE, &audible,
+ "Use visible, instead of audible, terminal bell",
+ NULL
+ },
+ {
+ "command", 'c', 0,
+ G_OPTION_ARG_STRING, &command,
+ "Execute a command in the terminal", NULL
+ },
+ {
+ "debug", 'd', 0,
+ G_OPTION_ARG_NONE, &debug,
+ "Enable various debugging checks", NULL
+ },
+ {
+ "font", 'f', 0,
+ G_OPTION_ARG_STRING, &font,
+ "Specify a font to use", NULL
+ },
+ {
+ "geometry", 'g', 0,
+ G_OPTION_ARG_STRING, &geometry,
+ "Set the size (in characters) and position", "GEOMETRY"
+ },
+ {
+ "highlight-foreground-color", 0, 0,
+ G_OPTION_ARG_STRING, &highlight_foreground_color_string,
+ "Enable distinct highlight foreground color for selection", NULL
+ },
+ {
+ "highlight-background-color", 0, 0,
+ G_OPTION_ARG_STRING, &highlight_background_color_string,
+ "Enable distinct highlight background color for selection", NULL
+ },
+ {
+ "icon-title", 'i', 0,
+ G_OPTION_ARG_NONE, &icon_title,
+ "Enable the setting of the icon title", NULL
+ },
+ {
+ "keep", 'k', 0,
+ G_OPTION_ARG_NONE, &keep,
+ "Live on after the window closes", NULL
+ },
+ {
+ "scrollback-lines", 'n', 0,
+ G_OPTION_ARG_INT, &lines,
+ "Specify the number of scrollback-lines", NULL
+ },
+ {
+ "cursor-blink", 0, 0,
+ G_OPTION_ARG_STRING, &cursor_blink_mode_string,
+ "Cursor blink mode (system|on|off)", "MODE"
+ },
+ {
+ "cursor-color", 0, 0,
+ G_OPTION_ARG_STRING, &cursor_color_string,
+ "Enable a colored cursor", NULL
+ },
+ {
+ "cursor-shape", 0, 0,
+ G_OPTION_ARG_STRING, &cursor_shape_string,
+ "Set cursor shape (block|underline|ibeam)", NULL
+ },
+ {
+ "encoding", 0, 0,
+ G_OPTION_ARG_STRING, &encoding,
+ "Specify the terminal encoding to use", NULL
+ },
+ {
+ "cjk-width", 0, 0,
+ G_OPTION_ARG_STRING, &cjk_ambiguous_width,
+ "Specify the cjk ambiguous width to use for UTF-8 encoding", "NARROW|WIDE"
+ },
+ {
+ "working-directory", 'w', 0,
+ G_OPTION_ARG_FILENAME, &working_directory,
+ "Specify the initial working directory of the terminal",
+ NULL
+ },
+ {
+ "reverse", 0, 0,
+ G_OPTION_ARG_NONE, &reverse,
+ "Reverse foreground/background colors", NULL
+ },
+ {
+ "no-geometry-hints", 'G', G_OPTION_FLAG_REVERSE,
+ G_OPTION_ARG_NONE, &use_geometry_hints,
+ "Allow the terminal to be resized to any dimension, not constrained to fit to an
integer multiple of characters",
+ NULL
+ },
+ {
+ "scrolled-window", 'W', 0,
+ G_OPTION_ARG_NONE, &use_scrolled_window,
+ "Use a GtkScrolledWindow as terminal container",
+ NULL
+ },
+ {
+ "scrollbar-policy", 'P', 0,
+ G_OPTION_ARG_STRING, &scrollbar_policy_string,
+ "Set the policy for the vertical scroolbar in the scrolled window (always|auto|never;
default:always)",
+ NULL
+ },
+ {
+ "object-notifications", 'N', 0,
+ G_OPTION_ARG_NONE, &show_object_notifications,
+ "Print VteTerminal object notifications",
+ NULL
+ },
+ {
+ "output-file", 0, 0,
+ G_OPTION_ARG_STRING, &output_file,
+ "Save terminal contents to file at exit", NULL
+ },
+ {
+ "pty-flags", 0, 0,
+ G_OPTION_ARG_STRING, &pty_flags_string,
+ "PTY flags set from default|no-utmp|no-wtmp|no-lastlog|no-helper|no-fallback", NULL
+ },
+ {
+ "border-width", 0, 0,
+ G_OPTION_ARG_STRING, &border_width_string,
+ "Border with", "WIDTH"
+ },
+ { NULL }
+ };
+ GOptionContext *context;
+ GError *error = NULL;
+ VteCursorBlinkMode cursor_blink_mode = VTE_CURSOR_BLINK_SYSTEM;
+ VteCursorShape cursor_shape = VTE_CURSOR_SHAPE_BLOCK;
+ GtkPolicyType scrollbar_policy = GTK_POLICY_ALWAYS;
+ VtePtyFlags pty_flags = VTE_PTY_DEFAULT;
+
+ _vte_debug_init();
+
+ /* Have to do this early. */
+ if (getenv("VTE_PROFILE_MEMORY")) {
+ if (atol(getenv("VTE_PROFILE_MEMORY")) != 0) {
+ g_mem_set_vtable(glib_mem_profiler_table);
+ }
+ }
+ if (g_getenv("VTE_CJK_WIDTH")) {
+ g_printerr("VTE_CJK_WIDTH is not supported anymore, use --cjk-width instead\n");
+ }
+
+ context = g_option_context_new (" - test VTE terminal emulation");
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_add_group (context, gtk_get_option_group (TRUE));
+ g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+ if (error != NULL) {
+ g_printerr ("Failed to parse command line arguments: %s\n",
+ error->message);
+ g_error_free (error);
+ return 1;
+ }
+
+ if (cursor_blink_mode_string) {
+ cursor_blink_mode = parse_enum(VTE_TYPE_CURSOR_BLINK_MODE, cursor_blink_mode_string);
+ g_free(cursor_blink_mode_string);
+ }
+ if (cursor_shape_string) {
+ cursor_shape = parse_enum(VTE_TYPE_CURSOR_SHAPE, cursor_shape_string);
+ g_free(cursor_shape_string);
+ }
+ if (scrollbar_policy_string) {
+ scrollbar_policy = parse_enum(GTK_TYPE_POLICY_TYPE, scrollbar_policy_string);
+ g_free(scrollbar_policy_string);
+ }
+ if (pty_flags_string) {
+ pty_flags |= parse_flags(VTE_TYPE_PTY_FLAGS, pty_flags_string);
+ g_free(pty_flags_string);
+ }
+
+ if (!reverse) {
+ back.red = back.green = back.blue = 1.0; back.alpha = 1.0;
+ fore.red = fore.green = fore.blue = 0.0; fore.alpha = 1.0;
+ } else {
+ back.red = back.green = back.blue = 0.0; back.alpha = 1.0;
+ fore.red = fore.green = fore.blue = 1.0; fore.alpha = 1.0;
+ }
+
+ gdk_window_set_debug_updates(debug);
+
+ /* Create a window to hold the scrolling shell, and hook its
+ * delete event to the quit function.. */
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_container_set_resize_mode(GTK_CONTAINER(window),
+ GTK_RESIZE_IMMEDIATE);
+ if (border_width_string) {
+ guint w;
+
+ w = g_ascii_strtoull (border_width_string, NULL, 10);
+ gtk_container_set_border_width(GTK_CONTAINER(window), w);
+ g_free (border_width_string);
+ }
+
+ /* Set ARGB visual */
+ screen = gtk_widget_get_screen (window);
+ visual = gdk_screen_get_rgba_visual(screen);
+ if (visual)
+ gtk_widget_set_visual(GTK_WIDGET(window), visual);
+
+ if (use_scrolled_window) {
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_NEVER, scrollbar_policy);
+ gtk_container_add(GTK_CONTAINER(window), scrolled_window);
+ } else {
+ /* Create a box to hold everything. */
+ hbox = gtk_hbox_new(0, FALSE);
+ gtk_container_add(GTK_CONTAINER(window), hbox);
+ }
+
+ /* Create the terminal widget and add it to the scrolling shell. */
+ widget = vteapp_terminal_new();
+ terminal = VTE_TERMINAL (widget);
+ if (!dbuffer) {
+ gtk_widget_set_double_buffered(widget, dbuffer);
+ }
+ if (show_object_notifications)
+ g_signal_connect(terminal, "notify", G_CALLBACK(terminal_notify_cb), NULL);
+ if (use_scrolled_window) {
+ gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(terminal));
+ } else {
+ gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
+ }
+
+ /* Connect to the "char_size_changed" signal to set geometry hints
+ * whenever the font used by the terminal is changed. */
+ if (use_geometry_hints) {
+ char_size_changed(widget, 0, 0, window);
+ g_signal_connect(widget, "char-size-changed",
+ G_CALLBACK(char_size_changed), window);
+ g_signal_connect(widget, "realize",
+ G_CALLBACK(char_size_realized), window);
+ }
+
+ /* Connect to the "window_title_changed" signal to set the main
+ * window's title. */
+ g_signal_connect(widget, "window-title-changed",
+ G_CALLBACK(window_title_changed), window);
+ if (icon_title) {
+ g_signal_connect(widget, "icon-title-changed",
+ G_CALLBACK(icon_title_changed), window);
+ }
+
+ /* Connect to the "button-press" event. */
+ g_signal_connect(widget, "button-press-event",
+ G_CALLBACK(button_pressed), widget);
+
+ /* Connect to application request signals. */
+ g_signal_connect(widget, "iconify-window",
+ G_CALLBACK(iconify_window), window);
+ g_signal_connect(widget, "deiconify-window",
+ G_CALLBACK(deiconify_window), window);
+ g_signal_connect(widget, "raise-window",
+ G_CALLBACK(raise_window), window);
+ g_signal_connect(widget, "lower-window",
+ G_CALLBACK(lower_window), window);
+ g_signal_connect(widget, "maximize-window",
+ G_CALLBACK(maximize_window), window);
+ g_signal_connect(widget, "restore-window",
+ G_CALLBACK(restore_window), window);
+ g_signal_connect(widget, "refresh-window",
+ G_CALLBACK(refresh_window), window);
+ g_signal_connect(widget, "resize-window",
+ G_CALLBACK(resize_window), window);
+ g_signal_connect(widget, "move-window",
+ G_CALLBACK(move_window), window);
+
+ /* Connect to font tweakage. */
+ g_signal_connect(widget, "increase-font-size",
+ G_CALLBACK(increase_font_size), window);
+ g_signal_connect(widget, "decrease-font-size",
+ G_CALLBACK(decrease_font_size), window);
+
+ if (!use_scrolled_window) {
+ /* Create the scrollbar for the widget. */
+ scrollbar = gtk_vscrollbar_new(gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(terminal)));
+ gtk_box_pack_start(GTK_BOX(hbox), scrollbar, FALSE, FALSE, 0);
+ }
+
+ /* Set some defaults. */
+ vte_terminal_set_audible_bell(terminal, audible);
+ vte_terminal_set_visible_bell(terminal, !audible);
+ vte_terminal_set_cursor_blink_mode(terminal, cursor_blink_mode);
+ vte_terminal_set_scroll_on_output(terminal, FALSE);
+ vte_terminal_set_scroll_on_keystroke(terminal, TRUE);
+ vte_terminal_set_scrollback_lines(terminal, lines);
+ vte_terminal_set_mouse_autohide(terminal, TRUE);
+
+ if (transparent != NULL) {
+ back.alpha = g_ascii_strtod (transparent, NULL);
+ g_free (transparent);
+ }
+
+ vte_terminal_set_colors(terminal, &fore, &back, NULL, 0);
+
+ if (cursor_color_string) {
+ GdkRGBA rgba;
+ if (parse_color (cursor_color_string, &rgba))
+ vte_terminal_set_color_cursor(terminal, &rgba);
+ g_free(cursor_color_string);
+ }
+ if (highlight_foreground_color_string) {
+ GdkRGBA rgba;
+ if (parse_color (highlight_foreground_color_string, &rgba))
+ vte_terminal_set_color_highlight_foreground(terminal, &rgba);
+ g_free(highlight_foreground_color_string);
+ }
+ if (highlight_background_color_string) {
+ GdkRGBA rgba;
+ if (parse_color (highlight_background_color_string, &rgba))
+ vte_terminal_set_color_highlight(terminal, &rgba);
+ g_free(highlight_background_color_string);
+ }
+
+ if (encoding != NULL) {
+ vte_terminal_set_encoding(terminal, encoding);
+ g_free(encoding);
+ }
+ if (cjk_ambiguous_width != NULL) {
+ int width = 1;
+
+ if (g_ascii_strcasecmp(cjk_ambiguous_width, "narrow") == 0)
+ width = 1;
+ else if (g_ascii_strcasecmp(cjk_ambiguous_width, "wide") == 0)
+ width = 2;
+ else
+ g_printerr("Unrecognised value \"%s\" for --cjk-width\n",
+ cjk_ambiguous_width);
+ g_free(cjk_ambiguous_width);
+
+ vte_terminal_set_cjk_ambiguous_width(terminal, width);
+ }
+
+ vte_terminal_set_cursor_shape(terminal, cursor_shape);
+
+ vte_terminal_set_rewrap_on_resize(terminal, rewrap);
+
+ /* Set the default font. */
+ if (font) {
+ PangoFontDescription *desc;
+
+ desc = pango_font_description_from_string(font);
+ vte_terminal_set_font(terminal, desc);
+ pango_font_description_free(desc);
+ }
+
+ /* Match "abcdefg". */
+ if (!no_builtin_dingus) {
+ add_dingus (terminal, (char **) builtin_dingus);
+ }
+ if (dingus) {
+ add_dingus (terminal, dingus);
+ g_strfreev (dingus);
+ }
+
+ if (console) {
+ /* Open a "console" connection. */
+ int consolefd = -1, yes = 1, watch;
+ GIOChannel *channel;
+ consolefd = open("/dev/console", O_RDONLY | O_NOCTTY);
+ if (consolefd != -1) {
+ /* Assume failure. */
+ console = FALSE;
+#ifdef TIOCCONS
+ if (ioctl(consolefd, TIOCCONS, &yes) != -1) {
+ /* Set up a listener. */
+ channel = g_io_channel_unix_new(consolefd);
+ watch = g_io_add_watch(channel,
+ G_IO_IN,
+ read_and_feed,
+ widget);
+ g_signal_connect_swapped(widget,
+ "eof",
+ G_CALLBACK(disconnect_watch),
+ GINT_TO_POINTER(watch));
+ g_signal_connect_swapped(widget,
+ "child-exited",
+ G_CALLBACK(disconnect_watch),
+ GINT_TO_POINTER(watch));
+ g_signal_connect(widget,
+ "realize",
+ G_CALLBACK(take_xconsole_ownership),
+ NULL);
+#ifdef VTE_DEBUG
+ vte_terminal_feed(terminal,
+ "Console log for ...\r\n",
+ -1);
+#endif
+ /* Record success. */
+ console = TRUE;
+ }
+#endif
+ } else {
+ /* Bail back to normal mode. */
+ g_warning(_("Could not open console.\n"));
+ close(consolefd);
+ console = FALSE;
+ }
+ }
+
+ if (!console) {
+ if (shell) {
+ GError *err = NULL;
+ char **command_argv = NULL;
+ int command_argc;
+ GPid pid = -1;
+ char *free_me = NULL;
+
+ _VTE_DEBUG_IF(VTE_DEBUG_MISC)
+ vte_terminal_feed(terminal, message, -1);
+
+ if (command == NULL || *command == '\0')
+ command = free_me = vte_get_user_shell ();
+
+ if (command == NULL || *command == '\0')
+ command = g_getenv ("SHELL");
+
+ if (command == NULL || *command == '\0')
+ command = "/bin/sh";
+
+ if (!g_shell_parse_argv(command, &command_argc, &command_argv, &err) ||
+ !vte_terminal_spawn_sync(terminal,
+ pty_flags,
+ NULL,
+ command_argv,
+ env_add,
+ G_SPAWN_SEARCH_PATH,
+ NULL, NULL,
+ &pid,
+ NULL /* cancellable */,
+ &err)) {
+ g_warning("Failed to fork: %s\n", err->message);
+ g_error_free(err);
+ } else {
+ g_print("Fork succeeded, PID %d\n", pid);
+ }
+
+ g_free (free_me);
+ g_strfreev(command_argv);
+ } else {
+ #ifdef HAVE_FORK
+ GError *err = NULL;
+ VtePty *pty;
+ pid_t pid;
+ int i;
+
+ pty = vte_pty_new_sync(VTE_PTY_DEFAULT, NULL, &err);
+ if (pty == NULL) {
+ g_printerr ("Failed to create PTY: %s\n", err->message);
+ g_error_free(err);
+ return 1;
+ }
+
+ pid = fork();
+ switch (pid) {
+ case -1:
+ /* abnormal */
+ g_warning("Error forking: %s",
+ g_strerror(errno));
+ g_object_unref(pty);
+ break;
+ case 0:
+ /* child */
+ vte_pty_child_setup(pty);
+
+ for (i = 0; ; i++) {
+ switch (i % 3) {
+ case 0:
+ case 1:
+ g_print("%d\n", i);
+ break;
+ case 2:
+ g_printerr("%d\n", i);
+ break;
+ }
+ sleep(1);
+ }
+ _exit(0);
+ break;
+ default:
+ vte_terminal_set_pty(terminal, pty);
+ g_object_unref(pty);
+ vte_terminal_watch_child(terminal, pid);
+ g_print("Child PID is %d (mine is %d).\n",
+ (int) pid, (int) getpid());
+ /* normal */
+ break;
+ }
+ #endif /* HAVE_FORK */
+ }
+ }
+
+ g_object_set_data (G_OBJECT (widget), "output_file", (gpointer) output_file);
+
+ /* Go for it! */
+ g_signal_connect(widget, "child-exited", G_CALLBACK(child_exited), window);
+ g_signal_connect(window, "delete-event", G_CALLBACK(delete_event), widget);
+
+ add_weak_pointer(G_OBJECT(widget), &widget);
+ add_weak_pointer(G_OBJECT(window), &window);
+
+ gtk_widget_realize(widget);
+ if (geometry) {
+ if (!gtk_window_parse_geometry (GTK_WINDOW(window), geometry)) {
+ g_warning (_("Could not parse the geometry spec passed to --geometry"));
+ }
+ } else {
+ /* As of GTK+ 2.91.0, the default size of a window comes from its minimum
+ * size not its natural size, so we need to set the right default size
+ * explicitly */
+ gtk_window_set_default_geometry (GTK_WINDOW (window),
+ vte_terminal_get_column_count (terminal),
+ vte_terminal_get_row_count (terminal));
+ }
+
+ gtk_widget_show_all(window);
+
+ gtk_main();
+
+ g_assert(widget == NULL);
+ g_assert(window == NULL);
+
+ if (keep) {
+ while (TRUE) {
+ sleep(60);
+ }
+ }
+
+ return 0;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]