added support for a virtual terminal emulator widget
git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@22 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
2a18ec4879
commit
a60d6a20bf
@ -1,4 +1,5 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
# $Id$
|
||||
|
||||
INCLUDES = \
|
||||
-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
|
||||
@ -29,6 +30,7 @@ geany_SOURCES = \
|
||||
sciwrappers.c sciwrappers.h \
|
||||
document.c document.h \
|
||||
utils.c utils.h \
|
||||
vte.c vte.h \
|
||||
support.c support.h \
|
||||
interface.c interface.h \
|
||||
callbacks.c callbacks.h
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
@ -47,6 +48,15 @@
|
||||
# include "win32.h"
|
||||
#endif
|
||||
|
||||
// include vte.h on non-Win32 systems, else define fake vte_init
|
||||
#if defined(GEANY_WIN32) || ! defined(HAVE_VTE)
|
||||
# define vte_close() ;
|
||||
#else
|
||||
# include "vte.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// represents the word under the mouse pointer when right button(no. 3) is pressed
|
||||
static gchar current_word[128];
|
||||
|
||||
@ -126,6 +136,7 @@ gint destroyapp(GtkWidget *widget, gpointer gdata)
|
||||
if (GTK_IS_WIDGET(app->open_fontsel)) gtk_widget_destroy(app->open_fontsel);
|
||||
if (GTK_IS_WIDGET(app->open_colorsel)) gtk_widget_destroy(app->open_colorsel);
|
||||
gtk_widget_destroy(app->window);
|
||||
if (app->have_vte) vte_close();
|
||||
|
||||
g_free(app);
|
||||
|
||||
@ -184,7 +195,7 @@ on_exit_clicked (GtkWidget *widget, gpointer gdata)
|
||||
|
||||
|
||||
// signal handler (for SIGINT and SIGTERM)
|
||||
void signal_cb(gint sig)
|
||||
RETSIGTYPE signal_cb(gint sig)
|
||||
{
|
||||
on_exit_clicked(NULL, NULL);
|
||||
}
|
||||
@ -827,6 +838,7 @@ on_file_save_save_button_clicked (GtkButton *button,
|
||||
|
||||
if (doc_list[idx].file_name) g_free(doc_list[idx].file_name);
|
||||
doc_list[idx].file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(app->save_filesel));
|
||||
utils_replace_filename(idx);
|
||||
document_save_file(idx);
|
||||
|
||||
utils_build_show_hide(idx);
|
||||
@ -945,8 +957,8 @@ on_window_configure_event (GtkWidget *widget,
|
||||
GdkEventConfigure *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *vpaned1 = lookup_widget(app->window, "vpaned1");
|
||||
gtk_paned_set_position(GTK_PANED(vpaned1), event->height - GEANY_MSGWIN_HEIGHT);
|
||||
//GtkWidget *vpaned1 = lookup_widget(app->window, "vpaned1");
|
||||
//gtk_paned_set_position(GTK_PANED(vpaned1), event->height - GEANY_MSGWIN_HEIGHT);
|
||||
app->geometry[0] = event->x;
|
||||
app->geometry[1] = event->y;
|
||||
app->geometry[2] = event->width;
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -61,7 +62,7 @@
|
||||
#define GEANY_MAX_TAGS_COUNT 1000
|
||||
#define GEANY_WORDCHARS "_#&abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
#define GEANY_MAX_AUTOCOMPLETE_WORDS 30
|
||||
#define GEANY_MSGWIN_HEIGHT 210
|
||||
#define GEANY_MSGWIN_HEIGHT 240
|
||||
#define GEANY_STRING_UNTITLED _("untitled")
|
||||
|
||||
|
||||
@ -104,6 +105,7 @@ typedef struct MyApp
|
||||
gint long_line_color;
|
||||
gint geometry[4];
|
||||
gboolean debug_mode;
|
||||
gboolean have_vte;
|
||||
gboolean ignore_global_tags;
|
||||
gboolean toolbar_visible;
|
||||
gboolean treeview_nb_visible;
|
||||
|
||||
16
src/main.c
16
src/main.c
@ -23,6 +23,7 @@
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "geany.h"
|
||||
|
||||
#include "interface.h"
|
||||
@ -38,10 +39,17 @@
|
||||
#include "templates.h"
|
||||
#include "encodings.h"
|
||||
#include "treeviews.h"
|
||||
// include vte.h on non-Win32 systems, else define fake vte_init
|
||||
#if defined(GEANY_WIN32) || ! defined(HAVE_VTE)
|
||||
# define vte_init() ;
|
||||
#else
|
||||
# include "vte.h"
|
||||
#endif
|
||||
|
||||
|
||||
static gboolean debug_mode = FALSE;
|
||||
static gboolean ignore_global_tags = FALSE;
|
||||
static gboolean no_vte = FALSE;
|
||||
static gboolean show_version = FALSE;
|
||||
static gchar *alternate_config = NULL;
|
||||
static GOptionEntry entries[] =
|
||||
@ -49,6 +57,7 @@ static GOptionEntry entries[] =
|
||||
{ "debug", 'd', 0, G_OPTION_ARG_NONE, &debug_mode, "runs in debug mode (means being verbose)", NULL },
|
||||
{ "no-ctags", 'n', 0, G_OPTION_ARG_NONE, &ignore_global_tags, "don't load auto completion data (see documentation)", NULL },
|
||||
{ "config", 'c', 0, G_OPTION_ARG_FILENAME, &alternate_config, "use an alternate configuration directory", NULL },
|
||||
{ "no-terminal", 't', 0, G_OPTION_ARG_NONE, &no_vte, "don't load terminal support", NULL },
|
||||
{ "version", 'v', 0, G_OPTION_ARG_NONE, &show_version, "show version and exit", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
@ -255,6 +264,11 @@ gint main(gint argc, gchar **argv)
|
||||
app->prefs_dialog = NULL;
|
||||
app->find_dialog = NULL;
|
||||
app->main_window_realized= FALSE;
|
||||
#ifdef HAVE_VTE
|
||||
app->have_vte = ! no_vte;
|
||||
#else
|
||||
app->have_vte = FALSE;
|
||||
#endif
|
||||
app->ignore_global_tags = ignore_global_tags;
|
||||
app->tm_workspace = tm_get_workspace();
|
||||
app->recent_queue = g_queue_new();
|
||||
@ -337,6 +351,7 @@ gint main(gint argc, gchar **argv)
|
||||
msgwindow.popup_status_menu = msgwin_create_message_popup_menu(3);
|
||||
msgwindow.popup_msg_menu = msgwin_create_message_popup_menu(4);
|
||||
msgwindow.popup_compiler_menu = msgwin_create_message_popup_menu(5);
|
||||
vte_init();
|
||||
dialogs_create_build_menu();
|
||||
dialogs_create_recent_menu();
|
||||
utils_create_insert_menu_items();
|
||||
@ -390,6 +405,7 @@ gint main(gint argc, gchar **argv)
|
||||
|
||||
app->main_window_realized = TRUE;
|
||||
|
||||
//g_timeout_add(0, (GSourceFunc)destroyapp, NULL); // useful for start time tests
|
||||
gtk_main();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -36,11 +36,13 @@ enum
|
||||
MSG_STATUS = 0,
|
||||
MSG_COMPILER,
|
||||
MSG_MESSAGE,
|
||||
MSG_SCRATCH
|
||||
MSG_SCRATCH,
|
||||
MSG_VTE
|
||||
};
|
||||
|
||||
|
||||
typedef struct msgwin {
|
||||
typedef struct msgwin
|
||||
{
|
||||
GtkListStore *store_status;
|
||||
GtkListStore *store_msg;
|
||||
GtkListStore *store_compiler;
|
||||
|
||||
212
src/vte.c
Normal file
212
src/vte.c
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* vte.c - this file is part of Geany, a fast and lightweight IDE
|
||||
*
|
||||
* Copyright 2005 Enrico Troeger <enrico.troeger@uvena.de>
|
||||
*
|
||||
* This program 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "geany.h"
|
||||
|
||||
#ifdef HAVE_VTE
|
||||
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "vte.h"
|
||||
#include "msgwindow.h"
|
||||
#include "support.h"
|
||||
|
||||
|
||||
extern gchar **environ;
|
||||
static pid_t pid;
|
||||
static GModule *module = NULL;
|
||||
static struct vte_funcs *vf;
|
||||
|
||||
#define VTE_TERMINAL(obj) (GTK_CHECK_CAST((obj), VTE_TYPE_TERMINAL, VteTerminal))
|
||||
#define VTE_TYPE_TERMINAL (vf->vte_terminal_get_type())
|
||||
|
||||
|
||||
/* taken from anjuta, thanks */
|
||||
gchar **vte_get_child_environment(GtkWidget *term)
|
||||
{
|
||||
/* code from gnome-terminal, sort of. */
|
||||
gchar **p;
|
||||
gint i;
|
||||
gchar **retval;
|
||||
#define EXTRA_ENV_VARS 5
|
||||
|
||||
/* count env vars that are set */
|
||||
for (p = environ; *p; p++);
|
||||
|
||||
i = p - environ;
|
||||
retval = g_new(gchar *, i + 1 + EXTRA_ENV_VARS);
|
||||
|
||||
for (i = 0, p = environ; *p; p++)
|
||||
{
|
||||
/* Strip all these out, we'll replace some of them */
|
||||
if ((strncmp(*p, "COLUMNS=", 8) == 0) ||
|
||||
(strncmp(*p, "LINES=", 6) == 0) ||
|
||||
(strncmp(*p, "TERM=", 5) == 0))
|
||||
{
|
||||
/* nothing: do not copy */
|
||||
}
|
||||
else
|
||||
{
|
||||
retval[i] = g_strdup(*p);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
retval[i] = g_strdup ("TERM=xterm");
|
||||
++i;
|
||||
|
||||
retval[i] = NULL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void vte_init(void)
|
||||
{
|
||||
|
||||
GtkWidget *vte, *scrollbar, *hbox, *frame;
|
||||
module = g_module_open("libvte.so.4", G_MODULE_BIND_LAZY);
|
||||
|
||||
if (module == NULL || app->have_vte == FALSE)
|
||||
{
|
||||
app->have_vte = FALSE;
|
||||
geany_debug("Could not load libvte.so.4, terminal support disabled");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
app->have_vte = TRUE;
|
||||
vf = g_new(struct vte_funcs, 1);
|
||||
vte_register_symbols(module);
|
||||
}
|
||||
|
||||
vte = vf->vte_terminal_new();
|
||||
scrollbar = gtk_vscrollbar_new(GTK_ADJUSTMENT(VTE_TERMINAL(vte)->adjustment));
|
||||
GTK_WIDGET_UNSET_FLAGS(scrollbar, GTK_CAN_FOCUS);
|
||||
|
||||
frame = gtk_frame_new(NULL);
|
||||
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(frame), hbox);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), vte, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), scrollbar, FALSE, TRUE, 0);
|
||||
|
||||
vf->vte_terminal_set_mouse_autohide(VTE_TERMINAL(vte), TRUE);
|
||||
vf->vte_terminal_set_scrollback_lines(VTE_TERMINAL(vte), 20);
|
||||
vf->vte_terminal_set_scroll_on_keystroke(VTE_TERMINAL(vte), TRUE);
|
||||
vf->vte_terminal_set_scroll_on_output(VTE_TERMINAL(vte), TRUE);
|
||||
vf->vte_terminal_set_word_chars(VTE_TERMINAL(vte), GEANY_WORDCHARS);
|
||||
vf->vte_terminal_set_size(VTE_TERMINAL(vte), 50, 1);
|
||||
vf->vte_terminal_set_encoding(VTE_TERMINAL(vte), "UTF-8");
|
||||
vf->vte_terminal_set_font_from_string(VTE_TERMINAL(vte), "Monospace 10");
|
||||
|
||||
g_signal_connect(G_OBJECT(vte), "child-exited", G_CALLBACK(vte_start), NULL);
|
||||
g_signal_connect(G_OBJECT(vte), "event", G_CALLBACK(vte_keypress), NULL);
|
||||
|
||||
vte_start(vte, NULL);
|
||||
|
||||
gtk_widget_show_all(frame);
|
||||
gtk_notebook_insert_page(GTK_NOTEBOOK(msgwindow.notebook), frame, gtk_label_new(_("Terminal")), MSG_VTE);
|
||||
}
|
||||
|
||||
|
||||
void vte_close(void)
|
||||
{
|
||||
g_module_close(module);
|
||||
g_free(vf);
|
||||
}
|
||||
|
||||
|
||||
gboolean vte_keypress(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
||||
{
|
||||
/* Fixme: GDK_KEY_PRESS doesn't seem to be called for our keys */
|
||||
if (event->type != GDK_KEY_RELEASE)
|
||||
return FALSE;
|
||||
|
||||
/* ctrl-c or ctrl-d */
|
||||
if (event->keyval == GDK_c ||
|
||||
event->keyval == GDK_d ||
|
||||
event->keyval == GDK_C ||
|
||||
event->keyval == GDK_D)
|
||||
{
|
||||
/* Ctrl pressed */
|
||||
if (event->state & GDK_CONTROL_MASK)
|
||||
{
|
||||
kill(pid, SIGINT);
|
||||
pid = 0;
|
||||
vte_start(widget, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void vte_start(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
VteTerminal *vte = VTE_TERMINAL(widget);
|
||||
struct passwd *pw;
|
||||
const gchar *shell;
|
||||
const gchar *dir;
|
||||
gchar **env;
|
||||
|
||||
pw = getpwuid(getuid());
|
||||
if (pw)
|
||||
{
|
||||
shell = pw->pw_shell;
|
||||
dir = pw->pw_dir;
|
||||
}
|
||||
else
|
||||
{
|
||||
shell = "/bin/sh";
|
||||
dir = "/";
|
||||
}
|
||||
|
||||
env = vte_get_child_environment(app->window);
|
||||
pid = vf->vte_terminal_fork_command(VTE_TERMINAL(vte), shell, NULL, env, dir, TRUE, TRUE, TRUE);
|
||||
g_strfreev(env);
|
||||
}
|
||||
|
||||
|
||||
void vte_register_symbols(GModule *mod)
|
||||
{
|
||||
g_module_symbol(mod, "vte_terminal_new", (void*)&vf->vte_terminal_new);
|
||||
g_module_symbol(mod, "vte_terminal_set_size", (void*)&vf->vte_terminal_set_size);
|
||||
g_module_symbol(mod, "vte_terminal_fork_command", (void*)&vf->vte_terminal_fork_command);
|
||||
g_module_symbol(mod, "vte_terminal_set_word_chars", (void*)&vf->vte_terminal_set_word_chars);
|
||||
g_module_symbol(mod, "vte_terminal_set_mouse_autohide", (void*)&vf->vte_terminal_set_mouse_autohide);
|
||||
g_module_symbol(mod, "vte_terminal_set_encoding", (void*)&vf->vte_terminal_set_encoding);
|
||||
g_module_symbol(mod, "vte_terminal_reset", (void*)&vf->vte_terminal_reset);
|
||||
g_module_symbol(mod, "vte_terminal_set_cursor_blinks", (void*)&vf->vte_terminal_set_cursor_blinks);
|
||||
g_module_symbol(mod, "vte_terminal_get_type", (void*)&vf->vte_terminal_get_type);
|
||||
g_module_symbol(mod, "vte_terminal_set_scroll_on_output", (void*)&vf->vte_terminal_set_scroll_on_output);
|
||||
g_module_symbol(mod, "vte_terminal_set_scroll_on_keystroke", (void*)&vf->vte_terminal_set_scroll_on_keystroke);
|
||||
g_module_symbol(mod, "vte_terminal_set_font_from_string", (void*)&vf->vte_terminal_set_font_from_string);
|
||||
g_module_symbol(mod, "vte_terminal_set_scrollback_lines", (void*)&vf->vte_terminal_set_scrollback_lines);
|
||||
g_module_symbol(mod, "vte_terminal_get_has_selection", (void*)&vf->vte_terminal_get_has_selection);
|
||||
}
|
||||
|
||||
#endif
|
||||
84
src/vte.h
Normal file
84
src/vte.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* vte.h - this file is part of Geany, a fast and lightweight IDE
|
||||
*
|
||||
* Copyright 2005 Enrico Troeger <enrico.troeger@uvena.de>
|
||||
*
|
||||
* This program 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 2 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, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GEANY_VTE_H
|
||||
#define GEANY_VTE_H 1
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
void vte_init(void);
|
||||
|
||||
gboolean vte_keypress(GtkWidget *widget, GdkEventKey *event, gpointer data);
|
||||
|
||||
void vte_start(GtkWidget *widget, gpointer data);
|
||||
|
||||
void vte_register_symbols(GModule *module);
|
||||
|
||||
void vte_close(void);
|
||||
|
||||
|
||||
|
||||
/* taken from original vte.h to make my life easier ;-) */
|
||||
|
||||
typedef struct _VteTerminalPrivate VteTerminalPrivate;
|
||||
|
||||
typedef struct _VteTerminal VteTerminal;
|
||||
struct _VteTerminal
|
||||
{
|
||||
GtkWidget widget;
|
||||
GtkAdjustment *adjustment;
|
||||
glong char_width, char_height;
|
||||
glong char_ascent, char_descent;
|
||||
glong row_count, column_count;
|
||||
char *window_title;
|
||||
char *icon_title;
|
||||
VteTerminalPrivate *pvt;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* store function pointers in a struct to avoid a strange segfault if they are stored directly
|
||||
* if accessed directly, gdb says the segfault arrives at old_tab_width(prefs.c), don't ask me */
|
||||
struct vte_funcs
|
||||
{
|
||||
GtkWidget* (*vte_terminal_new) (void);
|
||||
pid_t (*vte_terminal_fork_command) (VteTerminal *terminal, const char *command, char **argv,
|
||||
char **envv, const char *directory, gboolean lastlog,
|
||||
gboolean utmp, gboolean wtmp);
|
||||
void (*vte_terminal_set_size) (VteTerminal *terminal, glong columns, glong rows);
|
||||
void (*vte_terminal_set_word_chars) (VteTerminal *terminal, const char *spec);
|
||||
void (*vte_terminal_set_mouse_autohide) (VteTerminal *terminal, gboolean setting);
|
||||
void (*vte_terminal_reset) (VteTerminal *terminal, gboolean full, gboolean clear_history);
|
||||
void (*vte_terminal_set_encoding) (VteTerminal *terminal, const char *codeset);
|
||||
void (*vte_terminal_set_cursor_blinks) (VteTerminal *terminal, gboolean blink);
|
||||
GtkType (*vte_terminal_get_type) (void);
|
||||
void (*vte_terminal_set_scroll_on_output) (VteTerminal *terminal, gboolean scroll);
|
||||
void (*vte_terminal_set_scroll_on_keystroke) (VteTerminal *terminal, gboolean scroll);
|
||||
void (*vte_terminal_set_font_from_string) (VteTerminal *terminal, const char *name);
|
||||
void (*vte_terminal_set_scrollback_lines) (VteTerminal *terminal, glong lines);
|
||||
gboolean (*vte_terminal_get_has_selection) (VteTerminal *terminal);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user