From 39b32e641b34f13d54c21340246e9e10a17005b1 Mon Sep 17 00:00:00 2001 From: Vic Fryzel Date: Sun, 18 Jul 2010 02:01:11 -0400 Subject: After initial import from github, switching name to svte. Revamping README with new project information. --- .hgignore | 4 + LICENSE | 2 +- Makefile | 47 ++++++--- README | 60 ++++++----- config.mk | 19 ++++ defaults.h | 10 +- mt.c | 351 ------------------------------------------------------------- svte.c | 351 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 448 insertions(+), 396 deletions(-) create mode 100644 .hgignore delete mode 100644 mt.c create mode 100644 svte.c diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..2a9fe88 --- /dev/null +++ b/.hgignore @@ -0,0 +1,4 @@ +syntax: glob + +*.o +svte diff --git a/LICENSE b/LICENSE index 0ea79a6..bfc1c54 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -mt is under GPLv3 and also includes documents licensed under MIT/X. +svte is under GPLv3 and also includes documents licensed under MIT/X. both licenses are provided here and are also available online. diff --git a/Makefile b/Makefile index 444651c..641e0b0 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,31 @@ -# multi-terminal - a simple gtk terminal +# svte: simple virtual terminal emulator: minimal, tabbed, VTE-based terminal +# Copyright 2010 svte contributors. +# +# This file is part of svte. +# +# svte is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + include config.mk -SRC = mt.c +SRC = svte.c OBJ = ${SRC:.c=.o} -all: options mt +all: options svte options: - @echo mt build options: + @echo svte build options: @echo "CFLAGS = ${CFLAGS}" @echo "LDFLAGS = ${LDFLAGS}" @echo "CC = ${CC}" @@ -20,31 +37,31 @@ options: ${OBJ}: config.mk -mt: ${OBJ} +svte: ${OBJ} @echo CC -o $@ - @${CC} -o $@ mt.o ${LDFLAGS} + @${CC} -o $@ svte.o ${LDFLAGS} clean: @echo cleaning - @rm -f mt ${OBJ} mt-${VERSION}.tar.gz + @rm -f svte ${OBJ} mt-${VERSION}.tar.gz dist: clean @echo creating dist tarball - @mkdir -p mt-${VERSION} - @cp -R Makefile config.mk ${SRC} mt-${VERSION} - @tar -cf mt-${VERSION}.tar mt-${VERSION} - @gzip mt-${VERSION}.tar - @rm -rf mt-${VERSION} + @mkdir -p svte-${VERSION} + @cp -R Makefile config.mk ${SRC} svte-${VERSION} + @tar -cf svte-${VERSION}.tar mt-${VERSION} + @gzip svte-${VERSION}.tar + @rm -rf svte-${VERSION} install: all @echo installing executable file to ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f mt ${DESTDIR}${PREFIX}/bin - @chmod 755 ${DESTDIR}${PREFIX}/bin/mt + @cp -f svte ${DESTDIR}${PREFIX}/bin + @chmod 755 ${DESTDIR}${PREFIX}/bin/svte uninstall: @echo removing executable file from ${DESTDIR}${PREFIX}/bin - @rm -f ${DESTDIR}${PREFIX}/bin/mt + @rm -f ${DESTDIR}${PREFIX}/bin/svte .PHONY: all options clean dist install uninstall diff --git a/README b/README index 3e8b0ec..b318654 100644 --- a/README +++ b/README @@ -1,44 +1,56 @@ +svte: simple virtual terminal emulator: minimal, tabbed, VTE-based terminal -commits to mt should be small and frequent, push them as soon as possible, once something works bug free, push it. That way it is easier to track changes over a period of time +svte is a terminal that is flexible and has a small codebase. Its aim is to be +lightweight and fast, while providing nice integration with a modern Linux +environment. svte is yet another minimal GTK incarnation of VTE. svte is an +alternative to Sakura, Lilyterm, etc. -Todo/Goals: += Goals of svte = -vte callbacks -color schemes -rcfile -commenting and reworking some source. -minimal gtk or vte lib possible? +* Keep a small footprint, small codebase, and minimal implementation +* Support a large amount of the VTE interface +* Support color schemes +* Load configuration information from an rc file -mt - multi-terminal: a simple, tabbed, VTE based terminal that aims to simple, flexible, and maintain a ridiculously small codebase. while still aiming to be light and fast, i feel it provides better integration to the modern linux environment. GTK's footprint isn't light, but it has an excellent API, is easy to work with and is in development. += Help = -Basically another minimal GTK incarnation of gtk's VTE integration. +svte usage information is available at the svte project site, located at +http://code.google.com/p/svte/. -I was looking for a alternative to Sakura, Lilyterm and others. +If you have questions or comments regarding using svte, send an email to the +svte-users mailing list at svte-users@googlegroups.com. To browse the group, +see http://groups.google.com/group/svte-users/. -BUGS: += Contributing = -NONE +Contributions to svte are most welcome. Please submit patches or pull +requests to the svte-eng mailing list at svte-eng@googlegroups.com. To browse +the group, see http://groups.google.com/group/svte-eng/. +All other information contributors might need, like change histories, the bug +tracker, and documentation are available at the svte project site +http://code.google.com/p/svte/. -THANKS to: -Sakura -Suckless.org -LilyTerm -tinyterm -LICENSE: -This project is released under the GPL license. Scripts from surf are under the MIT/X license ( read the license file for MIT/X) += Thanks = -for further information visit +svte is made possible in part by the work of predecessory projects, including: -http://www.gnu.org/licenses/gpl.html -http://en.wikipedia.org/wiki/MIT_License +* Sakura +* Suckless.org +* LilyTerm +* tinyterm -CONTACT: -Swing me some electronic mail :) mutantturkey@gmail.com += License = +This project is released under the GPL license. Scripts from surf are under the +MIT/X license (read the license file for MIT/X.) Licenses are included with +svte in the LICENSE file. +For further information visit: +* http://www.gnu.org/licenses/gpl.html +* http://en.wikipedia.org/wiki/MIT_License diff --git a/config.mk b/config.mk index f05715c..c425368 100644 --- a/config.mk +++ b/config.mk @@ -1,3 +1,22 @@ +# svte: simple virtual terminal emulator: minimal, tabbed, VTE-based terminal +# Copyright 2010 svte contributors. +# +# This file is part of svte. +# +# svte is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + # mocicon version: VERSION = 0.1.4 diff --git a/defaults.h b/defaults.h index d822808..b6c6bdc 100644 --- a/defaults.h +++ b/defaults.h @@ -1,9 +1,9 @@ -/* mt: A simple, tabbed, VTE based terminal - * Copyright 2010 mutantturkey and mt contributors. +/* svte: simple virtual terminal emulator: minimal, tabbed, VTE-based terminal + * Copyright 2010 mutantturkey and svte contributors. * - * This file is part of mt. + * This file is part of svte. * - * mt is free software: you can redistribute it and/or modify + * svte is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -19,7 +19,7 @@ #ifndef DEFAULT_CONFIG_FILE -#define DEFAULT_CONFIG_FILE g_build_path("/", g_get_home_dir(), ".mtrc") +#define DEFAULT_CONFIG_FILE g_build_path("/", g_get_home_dir(), ".svterc") #endif #ifndef DEFAULT_FONT #define DEFAULT_FONT "monospace 10" diff --git a/mt.c b/mt.c deleted file mode 100644 index 54ac039..0000000 --- a/mt.c +++ /dev/null @@ -1,351 +0,0 @@ -/* mt: A simple, tabbed, VTE based terminal - * Copyright 2010 mutantturkey and mt contributors. - * - * This file is part of mt. - * - * mt is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include "defaults.h" -#include -#include -#include -#include - - -static struct { - GtkWidget *win; - GtkWidget *notebook; - gchar *title; -} mt; - - -typedef struct term { - GtkWidget *vte; - GtkWidget *label; -} term; - - -static void quit(); -gboolean key_press_cb(GtkWidget *widget, GdkEventKey *event); -gboolean button_press_cb(GtkWidget *widget, GdkEventButton *event, - struct term *t); -static void tab_close(); -static void tab_title(); -static void tab_geometry_hints(); -static void tab_new(); -static void configure_window(); -static void tab_focus(GtkNotebook *notebook, GtkNotebookPage *page, - guint page_num, gpointer user_data); - - -static GQuark term_data_id = 0; -#define get_page_term( sakura, page_idx ) (struct term*)g_object_get_qdata(G_OBJECT( gtk_notebook_get_nth_page( (GtkNotebook*)mt.notebook, page_idx ) ), term_data_id); - - -static gchar *config_file = NULL; -static gboolean show_version = FALSE; -static GOptionEntry options[] = { - { "config", 'c', 0, G_OPTION_ARG_FILENAME, &config_file, - "Path to configuration file to use.", NULL }, - { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, - "Print version information and exit", NULL }, - { NULL } -}; - - -typedef struct { - gchar *font; - gboolean fullscreen; - gboolean bold; - gint num_scrollback_lines; - gboolean transparent_bg; - gchar *url_regex; -} Settings; -static Settings *config; - - -/** - * Helper function, if i ever need to do something while closing, like query if - * more than one tab :) - */ -static void quit() { - gtk_main_quit(); -} - - -gboolean key_press_cb(GtkWidget *widget, GdkEventKey *event) { - guint(g) = event->keyval; - - if ((event->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) == - (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) { - if (g == GDK_T) { - tab_new(); - return TRUE; - } - if (g == GDK_W) { - tab_close(); - return TRUE; - } - } - if ((event->state & (GDK_MOD1_MASK) ) == (GDK_MOD1_MASK)) { - if (g == GDK_Left) { - gtk_notebook_prev_page(GTK_NOTEBOOK(mt.notebook)); - return TRUE; - } - if (g == GDK_Right) { - gtk_notebook_next_page(GTK_NOTEBOOK(mt.notebook)); - return TRUE; - } - if (g == GDK_F11) { - if(config->fullscreen) { - gtk_window_unfullscreen(GTK_WINDOW(mt.win)); - config->fullscreen = FALSE; - } else { - gtk_window_fullscreen(GTK_WINDOW(mt.win)); - config->fullscreen = TRUE; - } - return TRUE; - } - } - return FALSE; -} - - -gboolean button_press_cb(GtkWidget *widget, GdkEventButton *event, struct term *t) { - puts("LOL"); -/* - glong column, row; - gchar *match; - match = vte_terminal_match_check(VTE_TERMINAL(t->vte), column, row, NULL); - printf("%d , %d", column, row); - printf("LOL"); - puts(match); - return TRUE; -*/ -} - - -static void tab_close() { - gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(mt.notebook)); - struct term *t; - t = get_page_term(NULL, page); - gtk_notebook_remove_page(GTK_NOTEBOOK(mt.notebook), page); - g_free(t); - - if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(mt.notebook)) == 1) { - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(mt.notebook), FALSE); - gtk_widget_grab_focus( - gtk_notebook_get_nth_page(GTK_NOTEBOOK(mt.notebook), - gtk_notebook_get_current_page(GTK_NOTEBOOK(mt.notebook)))); - } - if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(mt.notebook)) == 0) { - quit(); - } -} - - -static void tab_geometry_hints(term *t) { - // borrowed from sakura, but using non deprecated code patch by me :) - // I dont need to call this every time, since the char width only changes - // once, maybe I'll make hints and border global and reuse them - GdkGeometry hints; - GtkBorder *border; - gint pad_x, pad_y; - gint char_width, char_height; - gtk_widget_style_get(GTK_WIDGET(t->vte), "inner-border", &border, NULL); - - char_width = vte_terminal_get_char_width(VTE_TERMINAL(t->vte)); - char_height = vte_terminal_get_char_height(VTE_TERMINAL(t->vte)); - - hints.min_width = char_width + border->left + border->right; - hints.min_height = char_height + border->top + border->bottom; - hints.base_width = border->left + border->right; - hints.base_height = border->top + border->bottom; - hints.width_inc = char_width; - hints.height_inc = char_height; - - gtk_window_set_geometry_hints( - GTK_WINDOW(mt.win), - GTK_WIDGET(t->vte), - &hints, - GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); -} - - -static void tab_title(GtkWidget *widget, term *t) { - gtk_label_set_text( - GTK_LABEL(t->label), - vte_terminal_get_window_title(VTE_TERMINAL(t->vte))); -} - - -static void tab_focus(GtkNotebook *notebook, GtkNotebookPage *page, - guint page_num, gpointer user_data) { - struct term *t; - t = get_page_term(NULL, page_num); - const char *title = vte_terminal_get_window_title(VTE_TERMINAL(t->vte)); - if (title == NULL) { - title = "mt"; - } - gtk_window_set_title(GTK_WINDOW(mt.win), title); -} - - -static void tab_new() { - term *t, previous; - int *tmp; - t = g_new0(term, 1); - t->label = gtk_label_new(""); - t->vte = vte_terminal_new(); - - int index = gtk_notebook_append_page(GTK_NOTEBOOK(mt.notebook), t->vte, - t->label); - gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(mt.notebook), t->vte, TRUE); - - if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(mt.notebook)) == 1) { - tab_geometry_hints(t); - } - if (index == 0) { - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(mt.notebook), FALSE); - } else { - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(mt.notebook), TRUE); - } - - vte_terminal_fork_command(VTE_TERMINAL(t->vte), NULL, NULL, NULL, NULL, - FALSE, FALSE, FALSE); - g_object_set_qdata_full(G_OBJECT(gtk_notebook_get_nth_page( - (GtkNotebook*)mt.notebook, index)), term_data_id, t, NULL); - g_signal_connect(t->vte, "child-exited", G_CALLBACK(tab_close), NULL); - g_signal_connect(t->vte, "window-title-changed", G_CALLBACK(tab_title), t); - g_signal_connect(mt.win, "button-press-event", G_CALLBACK(button_press_cb), - t); - vte_terminal_set_background_transparent(VTE_TERMINAL(t->vte), - config->transparent_bg); - vte_terminal_set_allow_bold(VTE_TERMINAL(t->vte), config->bold); - - - *tmp = vte_terminal_match_add_gregex( - VTE_TERMINAL(t->vte), - g_regex_new(config->url_regex, G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY, - NULL), - 0); - vte_terminal_match_set_cursor_type(VTE_TERMINAL(t->vte), *tmp, - GDK_HAND2); - g_free(tmp); - // borrowed from sakura - vte_terminal_set_scrollback_lines(VTE_TERMINAL(t->vte), - config->num_scrollback_lines); - vte_terminal_set_mouse_autohide(VTE_TERMINAL(t->vte), TRUE); - vte_terminal_set_font_from_string(VTE_TERMINAL(t->vte), config->font); - gtk_window_set_title(GTK_WINDOW(mt.win), - vte_terminal_get_window_title(VTE_TERMINAL(t->vte))); - gtk_widget_show_all(mt.notebook); - gtk_notebook_set_current_page(GTK_NOTEBOOK(mt.notebook), index); - gtk_widget_grab_focus(t->vte); -} - - -static void configure_window() { - term_data_id = g_quark_from_static_string("mt"); - mt.notebook = gtk_notebook_new(); - gtk_notebook_set_show_border(GTK_NOTEBOOK(mt.notebook), FALSE); - gtk_notebook_set_scrollable(GTK_NOTEBOOK(mt.notebook), TRUE); - mt.win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - if (config->fullscreen) { - gtk_window_fullscreen(GTK_WINDOW(mt.win)); - } - gtk_window_set_default_size(GTK_WINDOW(mt.win), 500, 350); - gtk_container_add(GTK_CONTAINER(mt.win), mt.notebook); - tab_new(); - gtk_widget_show_all(mt.win); - g_signal_connect(G_OBJECT(mt.win), "destroy", G_CALLBACK(quit), NULL); - g_signal_connect(mt.win, "key-press-event", G_CALLBACK(key_press_cb), NULL); - g_signal_connect(G_OBJECT(mt.notebook), "switch-page", G_CALLBACK(tab_focus), - NULL); -} - - -static gboolean parse_command_line_options(int argc, char* argv[]) { - gboolean retval = TRUE; - GError *error = NULL; - GOptionContext *context; - context = g_option_context_new("- a simple, tabbed, VTE based terminal"); - g_option_context_add_main_entries(context, options, NULL); - g_option_context_add_group(context, gtk_get_option_group(TRUE)); - if (!g_option_context_parse(context, &argc, &argv, &error)) { - g_error("Error parsing command-line options: %s\n", error->message); - retval = FALSE; - } - return retval; -} - - -static void parse_config_file(gchar *config_file) { - GKeyFile *keyfile; - GKeyFileFlags flags; - GError *error = NULL; - gsize length; - - keyfile = g_key_file_new(); - if (!g_key_file_load_from_file(keyfile, config_file, flags, &error)) { - g_warning("Error parsing config file %s: %s\n", - config_file, - error->message); - } - - config = g_slice_new(Settings); - config->font = g_key_file_get_string( - keyfile, "font", "UI", NULL); - config->bold = g_key_file_get_boolean( - keyfile, "UI", "bold", NULL); - config->fullscreen = g_key_file_get_boolean( - keyfile, "UI", "fullscreen", NULL); - config->transparent_bg = g_key_file_get_boolean( - keyfile, "UI", "transparent_bg", NULL); - config->transparent_bg = g_key_file_get_boolean( - keyfile, "UI", "num_scrollback_lines", NULL); - config->url_regex = g_key_file_get_string( - keyfile, "UI", "url_regex", NULL); - if (NULL == config->font) { - config->font = DEFAULT_FONT; - } - if (NULL == config->url_regex) { - config->url_regex = DEFAULT_URL_REGEX; - } -} - - -int main(int argc, char* argv[]) { - gtk_init(&argc, &argv); - - if(!parse_command_line_options(argc, argv)) { - return 1; - } - - if (show_version) { - printf(VERSION); - return 0; - } - - if (config_file == NULL) { - config_file = DEFAULT_CONFIG_FILE; - } - parse_config_file(config_file); - - configure_window(); - gtk_main(); - return 0; -} diff --git a/svte.c b/svte.c new file mode 100644 index 0000000..07ec60a --- /dev/null +++ b/svte.c @@ -0,0 +1,351 @@ +/* svte: simple virtual terminal emulator: minimal, tabbed, VTE-based terminal + * Copyright 2010 mutantturkey and svte contributors. + * + * This file is part of svte. + * + * svte is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "defaults.h" +#include +#include +#include +#include + + +static struct { + GtkWidget *win; + GtkWidget *notebook; + gchar *title; +} svte; + + +typedef struct term { + GtkWidget *vte; + GtkWidget *label; +} term; + + +static void quit(); +gboolean key_press_cb(GtkWidget *widget, GdkEventKey *event); +gboolean button_press_cb(GtkWidget *widget, GdkEventButton *event, + struct term *t); +static void tab_close(); +static void tab_title(); +static void tab_geometry_hints(); +static void tab_new(); +static void configure_window(); +static void tab_focus(GtkNotebook *notebook, GtkNotebookPage *page, + guint page_num, gpointer user_data); + + +static GQuark term_data_id = 0; +#define get_page_term( sakura, page_idx ) (struct term*)g_object_get_qdata(G_OBJECT( gtk_notebook_get_nth_page( (GtkNotebook*)svte.notebook, page_idx ) ), term_data_id); + + +static gchar *config_file = NULL; +static gboolean show_version = FALSE; +static GOptionEntry options[] = { + { "config", 'c', 0, G_OPTION_ARG_FILENAME, &config_file, + "Path to configuration file to use.", NULL }, + { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, + "Print version information and exit", NULL }, + { NULL } +}; + + +typedef struct { + gchar *font; + gboolean fullscreen; + gboolean bold; + gint num_scrollback_lines; + gboolean transparent_bg; + gchar *url_regex; +} Settings; +static Settings *config; + + +/** + * Helper function, if i ever need to do something while closing, like query if + * more than one tab :) + */ +static void quit() { + gtk_main_quit(); +} + + +gboolean key_press_cb(GtkWidget *widget, GdkEventKey *event) { + guint(g) = event->keyval; + + if ((event->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) == + (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) { + if (g == GDK_T) { + tab_new(); + return TRUE; + } + if (g == GDK_W) { + tab_close(); + return TRUE; + } + } + if ((event->state & (GDK_MOD1_MASK) ) == (GDK_MOD1_MASK)) { + if (g == GDK_Left) { + gtk_notebook_prev_page(GTK_NOTEBOOK(svte.notebook)); + return TRUE; + } + if (g == GDK_Right) { + gtk_notebook_next_page(GTK_NOTEBOOK(svte.notebook)); + return TRUE; + } + if (g == GDK_F11) { + if(config->fullscreen) { + gtk_window_unfullscreen(GTK_WINDOW(svte.win)); + config->fullscreen = FALSE; + } else { + gtk_window_fullscreen(GTK_WINDOW(svte.win)); + config->fullscreen = TRUE; + } + return TRUE; + } + } + return FALSE; +} + + +gboolean button_press_cb(GtkWidget *widget, GdkEventButton *event, struct term *t) { + puts("LOL"); +/* + glong column, row; + gchar *match; + match = vte_terminal_match_check(VTE_TERMINAL(t->vte), column, row, NULL); + printf("%d , %d", column, row); + printf("LOL"); + puts(match); + return TRUE; +*/ +} + + +static void tab_close() { + gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(svte.notebook)); + struct term *t; + t = get_page_term(NULL, page); + gtk_notebook_remove_page(GTK_NOTEBOOK(svte.notebook), page); + g_free(t); + + if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(svte.notebook)) == 1) { + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(svte.notebook), FALSE); + gtk_widget_grab_focus( + gtk_notebook_get_nth_page(GTK_NOTEBOOK(svte.notebook), + gtk_notebook_get_current_page(GTK_NOTEBOOK(svte.notebook)))); + } + if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(svte.notebook)) == 0) { + quit(); + } +} + + +static void tab_geometry_hints(term *t) { + // borrowed from sakura, but using non deprecated code patch by me :) + // I dont need to call this every time, since the char width only changes + // once, maybe I'll make hints and border global and reuse them + GdkGeometry hints; + GtkBorder *border; + gint pad_x, pad_y; + gint char_width, char_height; + gtk_widget_style_get(GTK_WIDGET(t->vte), "inner-border", &border, NULL); + + char_width = vte_terminal_get_char_width(VTE_TERMINAL(t->vte)); + char_height = vte_terminal_get_char_height(VTE_TERMINAL(t->vte)); + + hints.min_width = char_width + border->left + border->right; + hints.min_height = char_height + border->top + border->bottom; + hints.base_width = border->left + border->right; + hints.base_height = border->top + border->bottom; + hints.width_inc = char_width; + hints.height_inc = char_height; + + gtk_window_set_geometry_hints( + GTK_WINDOW(svte.win), + GTK_WIDGET(t->vte), + &hints, + GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); +} + + +static void tab_title(GtkWidget *widget, term *t) { + gtk_label_set_text( + GTK_LABEL(t->label), + vte_terminal_get_window_title(VTE_TERMINAL(t->vte))); +} + + +static void tab_focus(GtkNotebook *notebook, GtkNotebookPage *page, + guint page_num, gpointer user_data) { + struct term *t; + t = get_page_term(NULL, page_num); + const char *title = vte_terminal_get_window_title(VTE_TERMINAL(t->vte)); + if (title == NULL) { + title = "svte"; + } + gtk_window_set_title(GTK_WINDOW(svte.win), title); +} + + +static void tab_new() { + term *t, previous; + int *tmp; + t = g_new0(term, 1); + t->label = gtk_label_new(""); + t->vte = vte_terminal_new(); + + int index = gtk_notebook_append_page(GTK_NOTEBOOK(svte.notebook), t->vte, + t->label); + gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(svte.notebook), t->vte, TRUE); + + if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(svte.notebook)) == 1) { + tab_geometry_hints(t); + } + if (index == 0) { + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(svte.notebook), FALSE); + } else { + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(svte.notebook), TRUE); + } + + vte_terminal_fork_command(VTE_TERMINAL(t->vte), NULL, NULL, NULL, NULL, + FALSE, FALSE, FALSE); + g_object_set_qdata_full(G_OBJECT(gtk_notebook_get_nth_page( + (GtkNotebook*)svte.notebook, index)), term_data_id, t, NULL); + g_signal_connect(t->vte, "child-exited", G_CALLBACK(tab_close), NULL); + g_signal_connect(t->vte, "window-title-changed", G_CALLBACK(tab_title), t); + g_signal_connect(svte.win, "button-press-event", G_CALLBACK(button_press_cb), + t); + vte_terminal_set_background_transparent(VTE_TERMINAL(t->vte), + config->transparent_bg); + vte_terminal_set_allow_bold(VTE_TERMINAL(t->vte), config->bold); + + + *tmp = vte_terminal_match_add_gregex( + VTE_TERMINAL(t->vte), + g_regex_new(config->url_regex, G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY, + NULL), + 0); + vte_terminal_match_set_cursor_type(VTE_TERMINAL(t->vte), *tmp, + GDK_HAND2); + g_free(tmp); + // borrowed from sakura + vte_terminal_set_scrollback_lines(VTE_TERMINAL(t->vte), + config->num_scrollback_lines); + vte_terminal_set_mouse_autohide(VTE_TERMINAL(t->vte), TRUE); + vte_terminal_set_font_from_string(VTE_TERMINAL(t->vte), config->font); + gtk_window_set_title(GTK_WINDOW(svte.win), + vte_terminal_get_window_title(VTE_TERMINAL(t->vte))); + gtk_widget_show_all(svte.notebook); + gtk_notebook_set_current_page(GTK_NOTEBOOK(svte.notebook), index); + gtk_widget_grab_focus(t->vte); +} + + +static void configure_window() { + term_data_id = g_quark_from_static_string("svte"); + svte.notebook = gtk_notebook_new(); + gtk_notebook_set_show_border(GTK_NOTEBOOK(svte.notebook), FALSE); + gtk_notebook_set_scrollable(GTK_NOTEBOOK(svte.notebook), TRUE); + svte.win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + if (config->fullscreen) { + gtk_window_fullscreen(GTK_WINDOW(svte.win)); + } + gtk_window_set_default_size(GTK_WINDOW(svte.win), 500, 350); + gtk_container_add(GTK_CONTAINER(svte.win), svte.notebook); + tab_new(); + gtk_widget_show_all(svte.win); + g_signal_connect(G_OBJECT(svte.win), "destroy", G_CALLBACK(quit), NULL); + g_signal_connect(svte.win, "key-press-event", G_CALLBACK(key_press_cb), NULL); + g_signal_connect(G_OBJECT(svte.notebook), "switch-page", G_CALLBACK(tab_focus), + NULL); +} + + +static gboolean parse_command_line_options(int argc, char* argv[]) { + gboolean retval = TRUE; + GError *error = NULL; + GOptionContext *context; + context = g_option_context_new("- a simple, tabbed, VTE based terminal"); + g_option_context_add_main_entries(context, options, NULL); + g_option_context_add_group(context, gtk_get_option_group(TRUE)); + if (!g_option_context_parse(context, &argc, &argv, &error)) { + g_error("Error parsing command-line options: %s\n", error->message); + retval = FALSE; + } + return retval; +} + + +static void parse_config_file(gchar *config_file) { + GKeyFile *keyfile; + GKeyFileFlags flags; + GError *error = NULL; + gsize length; + + keyfile = g_key_file_new(); + if (!g_key_file_load_from_file(keyfile, config_file, flags, &error)) { + g_warning("Error parsing config file %s: %s\n", + config_file, + error->message); + } + + config = g_slice_new(Settings); + config->font = g_key_file_get_string( + keyfile, "font", "UI", NULL); + config->bold = g_key_file_get_boolean( + keyfile, "UI", "bold", NULL); + config->fullscreen = g_key_file_get_boolean( + keyfile, "UI", "fullscreen", NULL); + config->transparent_bg = g_key_file_get_boolean( + keyfile, "UI", "transparent_bg", NULL); + config->transparent_bg = g_key_file_get_boolean( + keyfile, "UI", "num_scrollback_lines", NULL); + config->url_regex = g_key_file_get_string( + keyfile, "UI", "url_regex", NULL); + if (NULL == config->font) { + config->font = DEFAULT_FONT; + } + if (NULL == config->url_regex) { + config->url_regex = DEFAULT_URL_REGEX; + } +} + + +int main(int argc, char* argv[]) { + gtk_init(&argc, &argv); + + if(!parse_command_line_options(argc, argv)) { + return 1; + } + + if (show_version) { + printf(VERSION); + return 0; + } + + if (config_file == NULL) { + config_file = DEFAULT_CONFIG_FILE; + } + parse_config_file(config_file); + + configure_window(); + gtk_main(); + return 0; +} -- cgit v1.2.3