├── .gitignore ├── LICENSE ├── Makefile ├── PKGBUILD ├── README.md ├── config.h └── tinyterm.c /.gitignore: -------------------------------------------------------------------------------- 1 | tinyterm 2 | *.o 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT/X Consortium License 2 | 3 | © 2013 Jakub Klinkovský 4 | © 2009 Sebastian Linke 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a 7 | copy of this software and associated documentation files (the "Software"), 8 | to deal in the Software without restriction, including without limitation 9 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | and/or sell copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | V=1 2 | VDEVEL=$(shell test -d .git && git describe 2>/dev/null) 3 | 4 | ifneq "$(VDEVEL)" "" 5 | V=$(VDEVEL) 6 | endif 7 | 8 | CC := $(CC) -std=c99 9 | 10 | base_CFLAGS = -Wall -Wextra -pedantic -O2 -g 11 | base_LIBS = -lm 12 | 13 | pkgs = vte-2.91 14 | pkgs_CFLAGS = $(shell pkg-config --cflags $(pkgs)) 15 | pkgs_LIBS = $(shell pkg-config --libs $(pkgs)) 16 | 17 | CPPFLAGS += -DTINYTERM_VERSION=\"$(V)\" 18 | CFLAGS := $(base_CFLAGS) $(pkgs_CFLAGS) $(CFLAGS) 19 | LDLIBS := $(base_LIBS) $(pkgs_LIBS) 20 | 21 | all: tinyterm 22 | 23 | tinyterm: tinyterm.c config.h 24 | 25 | clean: 26 | $(RM) tinyterm tinyterm.o 27 | 28 | install: tinyterm 29 | install -Dm755 tinyterm $(DESTDIR)/usr/bin/tinyterm 30 | -------------------------------------------------------------------------------- /PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Jakub Klinkovský 2 | 3 | pkgname=tinyterm-git 4 | _pkgname=tinyterm 5 | pkgver=0.2.6.ga28969d 6 | pkgrel=1 7 | pkgdesc="Very lightweight terminal emulator based on VTE (fork of tinyterm-svn package)" 8 | arch=('i686' 'x86_64') 9 | url="https://github.com/lahwaacz/tinyterm" 10 | license=('MIT') 11 | depends=('vte') 12 | makedepends=('git') 13 | source=('git://github.com/lahwaacz/tinyterm.git') 14 | md5sums=('SKIP') 15 | 16 | pkgver() { 17 | cd "$_pkgname" 18 | git describe --long --tags | sed 's|^v||;s|-|.|g' 19 | } 20 | 21 | build() { 22 | cd "$_pkgname" 23 | make 24 | } 25 | 26 | package() { 27 | cd "$_pkgname" 28 | make DESTDIR="$pkgdir" install 29 | install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE" 30 | } 31 | 32 | # vim:set ts=2 sw=2 et: 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | tinyterm 2 | ======== 3 | 4 | Fork of https://github.com/lahwaacz/tinyterm, which is a fork of https://code.google.com/p/tinyterm/ 5 | 6 | - shortcuts for increasing/decreasing font size 7 | - runs against vte3 for true color support 8 | - runs a single instance to save memory, like urxvtd/urxvtc. 9 | 10 | Dependencies 11 | ------------ 12 | 13 | - glib2 14 | - gtk3 15 | - vte3 (2.91+) 16 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT/X Consortium License 3 | * 4 | * © 2015 Nathan Hoad 5 | * © 2013 Jakub Klinkovský 6 | * © 2009 Sebastian Linke 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a 9 | * copy of this software and associated documentation files (the "Software"), 10 | * to deal in the Software without restriction, including without limitation 11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 | * and/or sell copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | * DEALINGS IN THE SOFTWARE. 25 | * 26 | */ 27 | 28 | /* Terminal emulation (value of $TERM) (default: xterm) */ 29 | #define TINYTERM_TERMINFO "xterm-256color" 30 | 31 | #define TINYTERM_DYNAMIC_WINDOW_TITLE // uncomment to enable window_title_cb 32 | #define TINYTERM_URGENT_ON_BELL // uncomment to enable window_urgency_hint_cb 33 | #define TINYTERM_SCROLLBACK_LINES 10000 34 | #define TINYTERM_SEARCH_WRAP_AROUND TRUE 35 | #define TINYTERM_AUDIBLE_BELL FALSE 36 | #define TINYTERM_VISIBLE_BELL FALSE 37 | #define TINYTERM_FONT "Anonymous Pro 9" 38 | #define TINYTERM_STYLE "GtkWindow { background: black; }" 39 | 40 | 41 | #define base00 "#000000" 42 | #define base01 "#3a3432" 43 | #define base02 "#4a4543" 44 | #define base03 "#5c5855" 45 | #define base04 "#807d7c" 46 | #define base05 "#a5a2a2" 47 | #define base06 "#d6d5d4" 48 | #define base07 "#f7f7f7" 49 | #define base08 "#db2d20" 50 | #define base09 "#e8bbd0" 51 | #define base0A "#fded02" 52 | #define base0B "#01a252" 53 | #define base0C "#b5e4f4" 54 | #define base0D "#01a0e4" 55 | #define base0E "#a16a94" 56 | #define base0F "#cdab53" 57 | 58 | #define TINYTERM_COLOR_FOREGROUND "#fff" 59 | #define TINYTERM_COLOR_BACKGROUND base00 60 | #define TINYTERM_COLOR00 base00 61 | #define TINYTERM_COLOR01 base08 62 | #define TINYTERM_COLOR02 base0B 63 | #define TINYTERM_COLOR03 base0A 64 | #define TINYTERM_COLOR04 base0D 65 | #define TINYTERM_COLOR05 base0E 66 | #define TINYTERM_COLOR06 base0A 67 | #define TINYTERM_COLOR07 base05 68 | 69 | #define TINYTERM_COLOR08 base00 70 | #define TINYTERM_COLOR09 base08 71 | #define TINYTERM_COLOR0A base0B 72 | #define TINYTERM_COLOR0B base0A 73 | #define TINYTERM_COLOR0C base0D 74 | #define TINYTERM_COLOR0D base0E 75 | #define TINYTERM_COLOR0E base0A 76 | #define TINYTERM_COLOR0F base05 77 | 78 | /* One of VTE_CURSOR_SHAPE_BLOCK, VTE_CURSOR_SHAPE_IBEAM, VTE_CURSOR_SHAPE_UNDERLINE */ 79 | #define TINYTERM_CURSOR_SHAPE VTE_CURSOR_SHAPE_BLOCK 80 | 81 | /* One of VTE_CURSOR_BLINK_SYSTEM, VTE_CURSOR_BLINK_ON, VTE_CURSOR_BLINK_OFF */ 82 | #define TINYTERM_CURSOR_BLINK VTE_CURSOR_BLINK_OFF 83 | 84 | /* Selection behavior for double-clicks */ 85 | #define TINYTERM_WORD_CHARS "-A-Za-z0-9:./?%&#_=+@~" 86 | 87 | /* Keyboard shortcuts */ 88 | #define TINYTERM_MODIFIER GDK_CONTROL_MASK 89 | #define TINYTERM_KEY_FONTSIZE_INCREASE GDK_KEY_Up 90 | #define TINYTERM_KEY_FONTSIZE_DECREASE GDK_KEY_Down 91 | 92 | /* Regular expression matching urls */ 93 | #define SPECIAL_CHARS "[[:alnum:]\\Q+-_,?;.:/!%$^*&~#=()\\E]" 94 | #define SCHEME "(?:[[:alpha:]][+-.[:alpha:]]*://)" 95 | #define USERINFO "(?:[[:alnum:]]+(?:" SPECIAL_CHARS "+)?\\@)?" 96 | #define HOST "(?:(?:[[:alnum:]-]+\\.)*[[:alpha:]]{2,})" 97 | #define PORT "(?:\\:[[:digit:]]{1,5})?" 98 | #define URLPATH "(?:/" SPECIAL_CHARS "*)?" 99 | 100 | const char * const url_regex = SCHEME USERINFO HOST PORT URLPATH "(? 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include "config.h" 36 | 37 | static GApplication *_application = NULL; // needs to be global for signal_handler to work 38 | 39 | /* callback to set window urgency hint on beep events */ 40 | static void 41 | window_urgency_hint_cb(VteTerminal* vte, gpointer user_data) 42 | { 43 | gtk_window_set_urgency_hint(GTK_WINDOW (gtk_widget_get_toplevel(GTK_WIDGET (vte))), TRUE); 44 | } 45 | 46 | /* callback to unset window urgency hint on focus */ 47 | gboolean 48 | window_focus_cb(GtkWindow* window) 49 | { 50 | gtk_window_set_urgency_hint(window, FALSE); 51 | return FALSE; 52 | } 53 | 54 | /* callback to dynamically change window title */ 55 | static void 56 | window_title_cb(VteTerminal* vte) 57 | { 58 | gtk_window_set_title(GTK_WINDOW (gtk_widget_get_toplevel(GTK_WIDGET (vte))), vte_terminal_get_window_title(vte)); 59 | } 60 | 61 | /* callback to react to key press events */ 62 | static gboolean 63 | key_press_cb(VteTerminal* vte, GdkEventKey* event) 64 | { 65 | if ((event->state & (TINYTERM_MODIFIER)) == (TINYTERM_MODIFIER)) { 66 | switch (gdk_keyval_to_upper(event->keyval)) { 67 | case TINYTERM_KEY_FONTSIZE_INCREASE: 68 | { 69 | const PangoFontDescription *font = vte_terminal_get_font(vte); 70 | pango_font_description_set_size(font, (pango_font_description_get_size(font) / PANGO_SCALE + 1) * PANGO_SCALE); 71 | vte_terminal_set_font(vte, font); 72 | return TRUE; 73 | } 74 | case TINYTERM_KEY_FONTSIZE_DECREASE: 75 | { 76 | const PangoFontDescription *font = vte_terminal_get_font(vte); 77 | const gint size = pango_font_description_get_size(font) / PANGO_SCALE - 1; 78 | if (size > 0) { 79 | pango_font_description_set_size(font, size * PANGO_SCALE); 80 | vte_terminal_set_font(vte, font); 81 | } 82 | return TRUE; 83 | } 84 | } 85 | } 86 | return FALSE; 87 | } 88 | 89 | static void 90 | vte_config(VteTerminal* vte) 91 | { 92 | GRegex* regex = g_regex_new(url_regex, G_REGEX_CASELESS, G_REGEX_MATCH_NOTEMPTY, NULL); 93 | 94 | vte_terminal_search_set_gregex(vte, regex, G_REGEX_MATCH_NOTEMPTY); 95 | vte_terminal_search_set_wrap_around (vte, TINYTERM_SEARCH_WRAP_AROUND); 96 | vte_terminal_set_audible_bell (vte, TINYTERM_AUDIBLE_BELL); 97 | vte_terminal_set_cursor_shape (vte, TINYTERM_CURSOR_SHAPE); 98 | vte_terminal_set_cursor_blink_mode (vte, TINYTERM_CURSOR_BLINK); 99 | vte_terminal_set_word_char_exceptions (vte, TINYTERM_WORD_CHARS); 100 | vte_terminal_set_scrollback_lines (vte, TINYTERM_SCROLLBACK_LINES); 101 | PangoFontDescription *font = pango_font_description_from_string(TINYTERM_FONT); 102 | vte_terminal_set_font(vte, font); 103 | 104 | GdkRGBA color_fg, color_bg; 105 | GdkRGBA color_palette[16]; 106 | gdk_rgba_parse(&color_fg, TINYTERM_COLOR_FOREGROUND); 107 | gdk_rgba_parse(&color_bg, TINYTERM_COLOR_BACKGROUND); 108 | gdk_rgba_parse(&color_palette[0], TINYTERM_COLOR00); 109 | gdk_rgba_parse(&color_palette[1], TINYTERM_COLOR01); 110 | gdk_rgba_parse(&color_palette[2], TINYTERM_COLOR02); 111 | gdk_rgba_parse(&color_palette[3], TINYTERM_COLOR03); 112 | gdk_rgba_parse(&color_palette[4], TINYTERM_COLOR04); 113 | gdk_rgba_parse(&color_palette[5], TINYTERM_COLOR05); 114 | gdk_rgba_parse(&color_palette[6], TINYTERM_COLOR06); 115 | gdk_rgba_parse(&color_palette[7], TINYTERM_COLOR07); 116 | gdk_rgba_parse(&color_palette[8], TINYTERM_COLOR08); 117 | gdk_rgba_parse(&color_palette[9], TINYTERM_COLOR09); 118 | gdk_rgba_parse(&color_palette[10], TINYTERM_COLOR0A); 119 | gdk_rgba_parse(&color_palette[11], TINYTERM_COLOR0B); 120 | gdk_rgba_parse(&color_palette[12], TINYTERM_COLOR0C); 121 | gdk_rgba_parse(&color_palette[13], TINYTERM_COLOR0D); 122 | gdk_rgba_parse(&color_palette[14], TINYTERM_COLOR0E); 123 | gdk_rgba_parse(&color_palette[15], TINYTERM_COLOR0F); 124 | 125 | vte_terminal_set_colors(vte, &color_fg, &color_bg, &color_palette, 16); 126 | } 127 | 128 | static void 129 | vte_spawn(VteTerminal* vte, char* working_directory, char* command, char** environment) 130 | { 131 | GError* error = NULL; 132 | char** command_argv = NULL; 133 | 134 | /* Parse command into array */ 135 | if (!command) 136 | command = vte_get_user_shell(); 137 | g_shell_parse_argv(command, NULL, &command_argv, &error); 138 | if (error) { 139 | g_printerr("Failed to parse command: %s\n", error->message); 140 | g_error_free(error); 141 | exit(EXIT_FAILURE); 142 | } 143 | 144 | /* Create pty object */ 145 | VtePty* pty = vte_terminal_pty_new_sync(vte, VTE_PTY_NO_HELPER, NULL, &error); 146 | if (error) { 147 | g_printerr("Failed to create pty: %s\n", error->message); 148 | g_error_free(error); 149 | exit(EXIT_FAILURE); 150 | } 151 | vte_terminal_set_pty(vte, pty); 152 | 153 | int child_pid; 154 | 155 | /* Spawn default shell (or specified command) */ 156 | g_spawn_async(working_directory, command_argv, environment, 157 | (G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN), // flags from GSpawnFlags 158 | (GSpawnChildSetupFunc)vte_pty_child_setup, // an extra child setup function to run in the child just before exec() 159 | pty, // user data for child_setup 160 | &child_pid, // a location to store the child PID 161 | &error); // return location for a GError 162 | if (error) { 163 | g_printerr("%s\n", error->message); 164 | g_error_free(error); 165 | exit(EXIT_FAILURE); 166 | } 167 | vte_terminal_watch_child(vte, child_pid); 168 | g_strfreev(command_argv); 169 | } 170 | 171 | /* callback to exit TinyTerm with exit status of child process */ 172 | static void 173 | window_close(GtkWindow* window, gint status, gpointer user_data) 174 | { 175 | GtkApplication *app = (GtkApplication*)user_data; 176 | 177 | int count = 0; 178 | GList *windows = gtk_application_get_windows(app); 179 | 180 | while (windows != NULL) { 181 | windows = windows->next; 182 | count++; 183 | } 184 | 185 | if (count == 1) { 186 | g_application_quit(G_APPLICATION(app)); 187 | } 188 | } 189 | 190 | static void 191 | vte_exit_cb(VteTerminal *vte, gint status, gpointer user_data) 192 | { 193 | GtkWindow *window = (GtkWindow*)user_data; 194 | 195 | gtk_widget_destroy(GTK_WIDGET(window)); 196 | } 197 | 198 | static void 199 | parse_arguments(int argc, char* argv[], char** command, char** directory, gboolean* keep, char** name, char** title) 200 | { 201 | gboolean version = FALSE; // show version? 202 | const GOptionEntry entries[] = { 203 | {"version", 'v', 0, G_OPTION_ARG_NONE, &version, "Display program version and exit.", 0}, 204 | {"execute", 'e', 0, G_OPTION_ARG_STRING, command, "Execute command instead of default shell.", "COMMAND"}, 205 | {"directory", 'd', 0, G_OPTION_ARG_STRING, directory, "Sets the working directory for the shell (or the command specified via -e).", "PATH"}, 206 | {"keep", 'k', 0, G_OPTION_ARG_NONE, keep, "Don't exit the terminal after child process exits.", 0}, 207 | {"name", 'n', 0, G_OPTION_ARG_STRING, name, "Set first value of WM_CLASS property; second value is always 'TinyTerm' (default: 'tinyterm')", "NAME"}, 208 | {"title", 't', 0, G_OPTION_ARG_STRING, title, "Set value of WM_NAME property; disables window_title_cb (default: 'TinyTerm')", "TITLE"}, 209 | { NULL } 210 | }; 211 | 212 | GError* error = NULL; 213 | GOptionContext* context = g_option_context_new(NULL); 214 | g_option_context_set_help_enabled(context, TRUE); 215 | g_option_context_add_main_entries(context, entries, NULL); 216 | g_option_context_parse(context, &argc, &argv, &error); 217 | g_option_context_free(context); 218 | 219 | if (error) { 220 | g_printerr("option parsing failed: %s\n", error->message); 221 | g_error_free(error); 222 | exit(EXIT_FAILURE); 223 | } 224 | 225 | if (version) { 226 | g_print("tinyterm " TINYTERM_VERSION "\n"); 227 | exit(EXIT_SUCCESS); 228 | } 229 | } 230 | 231 | static void 232 | signal_handler(int signal) 233 | { 234 | g_application_quit(_application); 235 | } 236 | 237 | void new_window(GtkApplication *app, gchar **argv, gint argc) 238 | { 239 | GtkWidget* window; 240 | GtkWidget* box; 241 | GdkPixbuf* icon; 242 | GdkGeometry geo_hints; 243 | GtkIconTheme* icon_theme; 244 | GError* error = NULL; 245 | 246 | /* Variables for parsed command-line arguments */ 247 | char* command = NULL; 248 | char* directory = NULL; 249 | gboolean keep = FALSE; 250 | char* name = NULL; 251 | char* title = NULL; 252 | 253 | parse_arguments(argc, argv, &command, &directory, &keep, &name, &title); 254 | 255 | /* Create window */ 256 | window = gtk_application_window_new(GTK_APPLICATION(app)); 257 | g_signal_connect(window, "delete-event", G_CALLBACK(window_close), app); 258 | 259 | gtk_window_set_wmclass(GTK_WINDOW (window), name ? name : "tinyterm", "TinyTerm"); 260 | gtk_window_set_title(GTK_WINDOW (window), title ? title : "TinyTerm"); 261 | 262 | /* Set window icon supplied by an icon theme */ 263 | icon_theme = gtk_icon_theme_get_default(); 264 | icon = gtk_icon_theme_load_icon(icon_theme, "terminal", 48, 0, &error); 265 | if (error) 266 | g_error_free(error); 267 | if (icon) 268 | gtk_window_set_icon(GTK_WINDOW (window), icon); 269 | 270 | /* Create main box */ 271 | box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); 272 | gtk_container_add(GTK_CONTAINER (window), box); 273 | 274 | /* Create vte terminal widget */ 275 | GtkWidget* vte_widget = vte_terminal_new(); 276 | gtk_box_pack_start(GTK_BOX (box), vte_widget, TRUE, TRUE, 0); 277 | VteTerminal* vte = VTE_TERMINAL (vte_widget); 278 | if (!keep) 279 | g_signal_connect(vte, "child-exited", G_CALLBACK (vte_exit_cb), window); 280 | g_signal_connect(vte, "key-press-event", G_CALLBACK (key_press_cb), NULL); 281 | #ifdef TINYTERM_URGENT_ON_BELL 282 | g_signal_connect(vte, "bell", G_CALLBACK (window_urgency_hint_cb), NULL); 283 | g_signal_connect(window, "focus-in-event", G_CALLBACK (window_focus_cb), NULL); 284 | g_signal_connect(window, "focus-out-event", G_CALLBACK (window_focus_cb), NULL); 285 | #endif // TINYTERM_URGENT_ON_BELL 286 | #ifdef TINYTERM_DYNAMIC_WINDOW_TITLE 287 | if (!title) 288 | g_signal_connect(vte, "window-title-changed", G_CALLBACK (window_title_cb), NULL); 289 | #endif // TINYTERM_DYNAMIC_WINDOW_TITLE 290 | 291 | /* Apply geometry hints to handle terminal resizing */ 292 | geo_hints.base_width = vte_terminal_get_char_width(vte); 293 | geo_hints.base_height = vte_terminal_get_char_height(vte); 294 | geo_hints.min_width = vte_terminal_get_char_width(vte); 295 | geo_hints.min_height = vte_terminal_get_char_height(vte); 296 | geo_hints.width_inc = vte_terminal_get_char_width(vte); 297 | geo_hints.height_inc = vte_terminal_get_char_height(vte); 298 | gtk_window_set_geometry_hints(GTK_WINDOW (window), vte_widget, &geo_hints, 299 | GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); 300 | 301 | vte_config(vte); 302 | vte_spawn(vte, directory, command, NULL); 303 | 304 | /* cleanup */ 305 | g_free(command); 306 | g_free(directory); 307 | g_free(name); 308 | g_free(title); 309 | 310 | /* Show widgets and run main loop */ 311 | gtk_widget_show_all(window); 312 | } 313 | 314 | static void 315 | activate(GApplication *app, gpointer user_data) 316 | { 317 | new_window(GTK_APPLICATION(app), NULL, 0); 318 | } 319 | 320 | static void 321 | command_line(GApplication *app, GApplicationCommandLine *command_line, gpointer user_data) 322 | { 323 | gchar **argc; 324 | gint argv; 325 | argc = g_application_command_line_get_arguments(command_line, &argv); 326 | new_window(GTK_APPLICATION(app), argc, argv); 327 | } 328 | 329 | int 330 | main (int argc, char* argv[]) 331 | { 332 | gtk_init(&argc, &argv); 333 | /* register signal handler */ 334 | signal(SIGHUP, signal_handler); 335 | signal(SIGINT, signal_handler); 336 | signal(SIGTERM, signal_handler); 337 | 338 | GtkCssProvider *provider = gtk_css_provider_new(); 339 | 340 | gtk_css_provider_load_from_data(provider, TINYTERM_STYLE, strlen(TINYTERM_STYLE), NULL); 341 | 342 | gtk_style_context_add_provider_for_screen( 343 | gdk_screen_get_default(), provider, 344 | GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); 345 | 346 | GtkApplication *app; 347 | int status; 348 | app = gtk_application_new("org.nhoad.tinyterm", G_APPLICATION_HANDLES_COMMAND_LINE); 349 | _application = G_APPLICATION(app); 350 | g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); 351 | g_signal_connect(app, "command-line", G_CALLBACK(command_line), NULL); 352 | status = g_application_run(G_APPLICATION(app), argc, argv); 353 | g_object_unref(app); 354 | return status; 355 | } 356 | 357 | --------------------------------------------------------------------------------