/* zterm.c - Zed's Virtual Terminal
* Copyright (C) 1998 Michael Zucchi
*
* A simple terminal program, based on ZTerm.
*
* 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.
Adapted for use in sg by C. Steenberg 23/6/2000
*/
/* needed for getopt under 'gcc -ansi -pedantic' on Linux */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <pwd.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkprivate.h>
#include <gdk/gdkkeysyms.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <Python.h>
#include <readline/readline.h>
#include <readline/history.h>
#ifdef WITH_GNOME
#include <gnome.h>
#include <zvt/zvtterm.h>
#else
#include "zvtterm.h"
#endif
#include "../sg.h"
#include "../../config.h"
#include "python_command.h"
#include "../pixmaps/python_small.xpm"
static void sg_term_readdata (gpointer data, gint fd, GdkInputCondition condition);
static pid_t child_pid=-1,
term_pid=-1;
static gboolean child_died_locked = FALSE;
static struct sigaction *p_saved_sigchld_action = NULL;
gint stdout_pipe[2],stderr_pipe[2],line_pipe[2],com_pipe[2], life_pipe[2],
stdout_tag, stderr_tag,line_tag, com_tag, life_tag,
term_x,term_y,term_xmin=40,term_ymin=15,
sizey_busy=0,restarted=0,term_open=0;
PyObject *fo_stdout=NULL,*fo_stderr=NULL;
GtkWidget *layout, *hscrollbar, *vscrollbar, *container,*table;
GtkWidget *term, *hbox, *scrollbar;
gushort *red, *green, *blue;
gushort linux_red[] = { 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff,
0x0, 0x0 };
gushort linux_grn[] = { 0x0000, 0x0000, 0xaaaa, 0x5555, 0x0000, 0x0000, 0xaaaa, 0xaaaa,
0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff,
0x0, 0x0 };
gushort linux_blu[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff,
0x0, 0x0 };
FILE *stdout_fp,*stderr_fp;
GArray *fd_array;
extern gint py_status; /* 0=normal, 1=old line waiting */
extern PyObject *sys_dict;
extern gboolean sg_exiting;
#define FONT "-misc-fixed-medium-r-normal--12-200-75-75-c-100-iso8859-1"
extern char **environ;
static char **env;
static char **env_copy;
static int winid_pos;
static GtkWidget *window = NULL;
void child_died(int sig);
void
hide_window_event (ZvtTerm *term)
{ gtk_widget_hide(window);
}
void
child_died_event_process (GtkWidget *term,gboolean stop_emit)
{ gchar buff[10],count=0;
struct sigaction sigpipe_action,
sigchld_action,
tmp_action;
if (child_died_locked) return;
child_died_locked = TRUE;
tmp_action.sa_handler = SIG_IGN;
tmp_action.sa_flags = 0;
sigemptyset(&tmp_action.sa_mask);
sigaction(SIGPIPE, &tmp_action, &sigpipe_action);
sigaction(SIGCHLD, &tmp_action, &sigchld_action);
term_open=0;
py_status=0;
if (line_tag)
{ gdk_input_remove(line_tag);
line_tag=0;
}
if (life_tag)
{ gdk_input_remove(life_tag);
life_tag=0;
}
if (child_pid>0)
{ pid_t pid_status;
kill(child_pid,SIGKILL);
do{
pid_status=waitpid(child_pid,NULL,WNOHANG);
}
while (pid_status==0);
child_pid=-1;
}
if (term_pid>0)
{ pid_t pid_status;
kill(term_pid,SIGKILL);
do{
pid_status=waitpid(term_pid,NULL,WNOHANG);
}
while (pid_status==0);
term_pid=-1;
close(stdout_pipe[1]);
close(stderr_pipe[1]);
}
if (fo_stdout)
{ Py_XDECREF(fo_stdout);
fo_stdout=NULL;
}
if (fo_stderr)
{ Py_XDECREF(fo_stderr);
fo_stderr=NULL;
}
if (fd_array) g_array_free(fd_array,FALSE);
gtk_main_iteration_do(FALSE);
fd_array=NULL;
if (term && !stop_emit) gtk_signal_emit_stop_by_name (GTK_OBJECT (term), "destroy");
if (window && !stop_emit) gtk_signal_emit_stop_by_name (GTK_OBJECT (window), "destroy");
term_open=FALSE;
/* restore signal actions */
sigaction(SIGPIPE, &sigpipe_action, NULL);
sigaction(SIGCHLD, &sigchld_action, NULL);
}
/* Closes the terminal, to be called by outside code */
void term_kill_child (void)
{ child_died_event_process(term,TRUE);
}
void
child_died_event (GtkWidget *term)
{ child_died_event_process(term,FALSE);
}
static void
title_changed_event (ZvtTerm *term, VTTITLE_TYPE type, char *newtitle)
{
switch(type) {
case VTTITLE_WINDOW:
case VTTITLE_WINDOWICON:
gtk_window_set_title (GTK_WINDOW (window), newtitle);
break;
default:
break;
}
}
static int
button_press_event (ZvtTerm *term, GdkEventButton *e)
{
int x,y;
GdkModifierType mask;
char *data, *str;
gdk_window_get_pointer(GTK_WIDGET(term)->window, &x, &y, &mask);
str = zvt_term_match_check(term, x/term->charwidth, y/term->charheight,(void *)&data);
if (str) {
gtk_signal_emit_stop_by_name (GTK_OBJECT (term), "button_press_event");
return TRUE;
}
return FALSE;
}
static void
set_hints (GtkWidget *widget)
{
ZvtTerm *term;
GdkGeometry hints;
GtkWidget *app;
g_assert (widget != NULL);
term = ZVT_TERM (widget);
app = gtk_widget_get_toplevel(widget);
g_assert (app != NULL);
#define PADDING 2
hints.base_width = (GTK_WIDGET (term)->style->klass->xthickness * 2) + PADDING;
hints.base_height = (GTK_WIDGET (term)->style->klass->ythickness * 2);
hints.width_inc = term->charwidth;
hints.height_inc = term->charheight;
hints.min_width = hints.base_width + hints.width_inc;
hints.min_height = hints.base_height + hints.height_inc;
gtk_window_set_geometry_hints(GTK_WINDOW(app),
GTK_WIDGET(term),
&hints,
GDK_HINT_RESIZE_INC|GDK_HINT_MIN_SIZE|GDK_HINT_BASE_SIZE);
}
static void sg_term_line_typed (gpointer data, gint fd, GdkInputCondition condition)
{
gboolean update;
gchar buffer[2048],norm[]="R>>> ",cont[]="R... ";
gint count, saveerrno,res,wres;
ZvtTerm *term;
term = (ZvtTerm *) data;
saveerrno = 0;
while ( (count = read (fd, buffer, 2048)) > 0)
{ saveerrno = errno;
if (count>0 && count<2048) break;
}
res=python_simple(buffer,count);
if (res==2)
wres=write(com_pipe[1],cont,strlen(cont));
else
wres=write(com_pipe[1],norm,strlen(norm));
if (wres<0){
child_died_locked = FALSE;
fprintf(stderr,"Error writing prompt, terminal died.\n");
child_died(0);
}
return;
}
void
print_raw (GtkWidget * textwidget, unsigned char *text, gint len)
{
int dotime = FALSE;
char num[8];
int reverse = 0, under = 0, bold = 0,
comma, k, i = 0, j = 0, maxj = len+1024;
unsigned char *newtext = g_new (unsigned char, len+1024);
while (i < len)
{
if (maxj - j < 100)
{
maxj += 1024;
newtext = g_renew (unsigned char, newtext, maxj);
}
switch (text[i])
{
case '\026':
if (reverse)
{
reverse = FALSE;
strcpy (&newtext[j], "\033[27m");
} else
{
reverse = TRUE;
strcpy (&newtext[j], "\033[7m");
}
j = strlen (newtext);
break;
case '\037':
if (under)
{
under = FALSE;
strcpy (&newtext[j], "\033[24m");
} else
{
under = TRUE;
strcpy (&newtext[j], "\033[4m");
}
j = strlen (newtext);
break;
case '\002':
if (bold)
{
bold = FALSE;
strcpy (&newtext[j], "\033[22m");
} else
{
bold = TRUE;
strcpy (&newtext[j], "\033[1m");
}
j = strlen (newtext);
break;
case '\017':
strcpy (&newtext[j], "\033[0m");
j = strlen (newtext);
reverse = FALSE;
bold = FALSE;
under = FALSE;
break;
case '\n':
newtext[j++] = '\r';
default:
newtext[j] = text[i];
j++;
}
i++;
}
newtext[j] = 0;
zvt_term_feed ((ZvtTerm *) textwidget, newtext, j);
g_free (newtext);
}
static void sg_term_write (gpointer data, gint fd, GdkInputCondition condition)
{
gchar buffer[2048];
gint count, saveerrno,*fd2;
fd2=(gint *)data;
saveerrno = EAGAIN;
while (1) {
count = read (fd, buffer, 2048);
if (count<=0) break;
saveerrno = errno;
write (fd2[1], buffer, count);
}
}
static void sg_term_readdata (gpointer data, gint fd, GdkInputCondition condition)
{ fd_set read_set;
gchar buffer[4096];
gint count, saveerrno;
ZvtTerm *term;
struct timeval tv;
if (fd!=life_pipe[0]) return;
term = (ZvtTerm *) data;
saveerrno = EAGAIN;
while (1){
tv.tv_sec=0;
tv.tv_usec=100000;
FD_SET(fd,&read_set);
select(fd+1,&read_set,NULL,NULL,&tv);
if (FD_ISSET(fd,&read_set))
{ count = read (fd, buffer, 4096);
saveerrno = errno;
if (count>0)
print_raw (GTK_WIDGET(term), buffer, count);
if (count>0 && count<4096) break;
}
else break;
}
}
static void sg_term_life (gpointer data, gint fd, GdkInputCondition condition)
{
gchar buffer[10];
gint count, saveerrno;
ZvtTerm *term;
saveerrno = EAGAIN;
while ( (count = read (fd, buffer, 10)) > 0) {
saveerrno = errno;
switch (buffer[0])
{ case 'T': /* Terminal died */
waitpid(term_pid,NULL,0);
break;
default: break;
}
if (count<10) break;
}
}
static void parent_died(int sig)
{
close(stdout_pipe[0]);
close(stderr_pipe[0]);
close(life_pipe[1]);
_exit(0);
}
static void buffer_process(void)
{ fd_set read_set,write_set;
gint fd_max=0,i,fd,num,tnum;
gchar buffer[2048],*temp;
pipe(life_pipe);
fcntl(life_pipe[0],F_SETFL,O_NONBLOCK);
fcntl(life_pipe[1],F_SETFL,O_NONBLOCK);
term_pid=fork();
switch (term_pid)
{ case -1: perror("Can't fork the buffer process");
return;
case 0: /* the child */
{ GPtrArray *buffer_array;
GArray *len,*pos;
gint sel=0;
struct timeval tv;
struct sigaction action;
action.sa_flags = SA_RESTART;
sigemptyset(&action.sa_mask);
action.sa_handler = parent_died;
sigaction(SIGPIPE,&action,NULL);
sigaction(SIGHUP,&action,NULL);
action.sa_handler = SIG_IGN;
sigaction(SIGINT,&action,NULL);
close(stdout_pipe[1]);
close(stderr_pipe[1]);
close(life_pipe[0]);
buffer_array=g_ptr_array_new();
len=g_array_new(FALSE,FALSE,sizeof(gint));
pos=g_array_new(FALSE,FALSE,sizeof(gint));
while (1)
{ fd_max=-1;
FD_ZERO(&read_set);
for (i=0;i<fd_array->len;i++)
{ fd=g_array_index(fd_array,gint,i);
FD_SET(fd,&read_set);
if (fd>fd_max) fd_max=fd;
}
if (buffer_array->len)
{ tv.tv_sec=0;
tv.tv_usec=0;
sel=select(fd_max+1,&read_set,NULL,NULL,&tv);
}
else
{ tv.tv_sec=2;
tv.tv_usec=0;
sel=select(fd_max+1,&read_set,NULL,NULL,&tv);
}
if (sel>=0)
for (i=0;i<fd_array->len;i++)
{ fd=g_array_index(fd_array,gint,i);
if (FD_ISSET(fd,&read_set))
while (1)
{ num=read(fd,buffer,2048);
if (num>0)
{ buffer[num]='\0';
g_ptr_array_add(buffer_array,strdup(buffer));
g_array_append_val(len,num);
tnum=0;
g_array_append_val(pos,tnum);
}
if (num<2048) break;
}
}
else
{ for (i=0;i<fd_array->len;i++)
{ fd=g_array_index(fd_array,gint,i);
close(fd);
}
_exit(0);
}
FD_SET(life_pipe[1],&write_set);
tv.tv_sec=0;
tv.tv_usec=0;
select(life_pipe[1]+1,NULL,&write_set,NULL,&tv);
if (FD_ISSET(life_pipe[1],&write_set))
while (buffer_array->len)
{ temp=(gchar *)g_ptr_array_index(buffer_array,0);
temp+=g_array_index(pos,gint,0);
num=write(life_pipe[1],temp,g_array_index(len,gint,0)-
g_array_index(pos,gint,0));
if (num>0) {
gint ti;
ti=g_array_index(pos,gint,0)+num;
g_array_remove_index(pos,0);
g_array_prepend_val(pos,ti);
}
if (g_array_index(pos,gint,0)>=g_array_index(len,gint,0))
{ g_array_remove_index(pos,0);
g_array_remove_index(len,0);
g_free(g_ptr_array_index(buffer_array,0));
g_ptr_array_remove_index(buffer_array,0);
}
else break;
}
}
_exit(0);
}
default: /* the parent */
/* wait for child process to be forked */
while (kill(term_pid,0)<0) usleep(1000);
life_tag=gdk_input_add(life_pipe[0], GDK_INPUT_READ,
sg_term_readdata, term);
break;
}
}
/* create_child: forks off a new process and handles input via readline on
* the newly created terminal. Todo: create python command completion code.
*/
int create_child(void)
{ gchar buffer [256],buf2[2048],*line;
gint len,i,mychar;
ZvtTerm *g_term;
PyObject *fo;
g_term=ZVT_TERM(term);
/* Open some pipes */
pipe(line_pipe); /* For the child to tell the parent what line was typed */
fcntl(line_pipe[0],F_SETFL,O_NONBLOCK);
fcntl(line_pipe[1],F_SETFL,O_NONBLOCK);
pipe(com_pipe); /* For the parent to tell child what is what */
fcntl(com_pipe[1],F_SETFL,O_NONBLOCK);
pipe(stdout_pipe);
pipe(stderr_pipe);
child_pid=vt_forkpty(&g_term->vx->vt,FALSE);
switch (child_pid)
{ case -1:
perror ("Error: unable to fork");
return 0;
case 0: /* the child */
{struct sigaction action;
action.sa_flags = SA_RESTART;
sigemptyset(&action.sa_mask);
action.sa_handler = parent_died;
sigaction(SIGPIPE,&action,NULL);
sigaction(SIGHUP,&action,NULL);
action.sa_handler = SIG_IGN;
sigaction(SIGINT,&action,NULL);
close(line_pipe[0]); /* Close read end */
close(com_pipe[1]); /* Close write end */
rl_reset_terminal("vt100");
rl_initialize();
rl_filename_completion_desired=0;
rl_bind_key('\t',rl_insert);
#ifdef READLINE_4
rl_catch_signals=0;
rl_free_line_state();
#endif
close(stdout_pipe[0]);
close(stderr_pipe[0]);
close(1);
dup2(stdout_pipe[1],1);
close(2);
dup2(stderr_pipe[1],2);
for (;;)
{ len=0;
i=0;
do {
len=read(com_pipe[0],buffer,256);
if (i>10) {
write(line_pipe[1], "\n", 1);
usleep(100000);
i=0;
}
}
while (len<=0);
if (buffer[0]=='R') /* Only action defined so far */
{ buffer[len]= '\0';
line=0;
line=readline(buffer+1);
if (line) {
if (*line)
add_history(line);
len= strlen(line);
if (len) write(line_pipe[1], line, len);
else write(line_pipe[1], "\n", 1);
free(line);
}
else write(line_pipe[1], "\n", 1);
}
if (buffer[0]=='K') break;
}
_exit(0);
}
default: /* the parent */
{struct sigaction action;
if (!p_saved_sigchld_action)
p_saved_sigchld_action = g_new(struct sigaction, 1);
action.sa_handler = child_died;
action.sa_flags = SA_RESTART;
sigemptyset(&action.sa_mask);
sigaction(SIGCHLD,&action,p_saved_sigchld_action);
/* wait for child process to be forked */
while (kill(child_pid,0)<0) usleep(1000);
fd_array= g_array_new (FALSE, FALSE, sizeof (gint));
stdout_fp=fdopen(stdout_pipe[1],"w");
setvbuf(stdout_fp,NULL,_IONBF,0);
fo_stdout=PyFile_FromFile (stdout_fp, "<stdout>", "w", NULL);
PyDict_SetItemString (sys_dict, "stdout", fo_stdout);
stdout_fp=fdopen(stdout_pipe[1],"w");
setvbuf(stdout_fp,NULL,_IONBF,0);
fo_stderr=PyFile_FromFile (stdout_fp, "<stderr>", "w", NULL);
PyDict_SetItemString (sys_dict, "stderr", fo_stderr);
g_array_append_val(fd_array,stdout_pipe[0]);
line_tag=gdk_input_add(line_pipe[0], GDK_INPUT_READ,
sg_term_line_typed, term);
close(line_pipe[1]); /* Close write end */
close(com_pipe[0]); /* Close read end */
buffer_process();
write(com_pipe[1],"R>>> ",5);
close(stdout_pipe[0]);
close(stderr_pipe[0]);
break;
}
}
}
void child_died(int sig)
{
if (child_died_locked) return;
child_died_locked = TRUE;
if (life_tag)
{
gdk_input_remove(life_tag);
life_tag=0;
}
if (line_tag)
{
gdk_input_remove(line_tag);
line_tag=0;
}
close(com_pipe[1]);
close(stdout_pipe[0]);
close(stderr_pipe[0]);
close(line_pipe[0]);
if (child_pid>0)
{ pid_t pid_status;
kill(child_pid,SIGKILL);
do{
pid_status=waitpid(child_pid,NULL,WNOHANG);
}
while (pid_status==0);
child_pid=-1;
}
if (term_pid>0)
{ pid_t pid_status;
kill(term_pid,SIGKILL);
do{
pid_status=waitpid(term_pid,NULL,WNOHANG);
}
while (pid_status==0);
term_pid=-1;
}
if (fo_stdout)
{ Py_XDECREF(fo_stdout);
fo_stdout=NULL;
}
if (fo_stderr)
{ Py_XDECREF(fo_stderr);
fo_stderr=NULL;
}
if (fd_array) g_array_free(fd_array,FALSE);
fd_array=NULL;
if (GTK_IS_WIDGET(window))
{
gtk_widget_destroy(GTK_WIDGET(window));
window=NULL;
}
term_open=FALSE;
/* restore the signal handlers in case the parent has called
* then call the restored signal handler
* hope it works this way - Rob.
*/
if (sig == SIGCHLD && p_saved_sigchld_action != NULL)
{sigaction(SIGCHLD,p_saved_sigchld_action,NULL);
raise(SIGCHLD);
}
/* unlock */
child_died_locked = FALSE;
}
/*
Do setup, initialises windows, forks child.
*/
gint create_python_term(GtkWidget *widget, gpointer data)
{
int i, c, cmdindex, scrollbacklines, login_shell;
char **p, *fontname=FONT;
GdkPixmap *pixmap;
GdkBitmap *mask;
GdkGC *fg_gc,*bg_gc,*scroll_gc;
GdkColor *fg_color,*bg_color;
PyObject *fo;
int argc=1;
char *argv[]={"sga"},buf2[4096];
enum { RIGHT, LEFT } scrollpos = RIGHT;
if (term_open)
{ gtk_widget_show(window);
return TRUE;
}
else term_open=1;
login_shell = 0;
cmdindex = 0;
scrollbacklines = 2000;
/* Create widgets and set options */
#ifdef WITH_GNOME
window=gnome_app_new (PACKAGE,"Python terminal (SciGraphica)");
#else
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Python terminal (SciGraphica)");
gtk_window_set_wmclass (GTK_WINDOW (window), "zterm", "zterm");
#endif
/* create hbox */
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_set_spacing (GTK_BOX (hbox), 2);
gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
#ifdef WITH_GNOME
gnome_app_set_contents(GNOME_APP(window),hbox);
#else
gtk_container_add (GTK_CONTAINER (window), hbox);
#endif
gtk_widget_show (hbox);
/* create terminal */
term = zvt_term_new_with_size(80,24);
zvt_term_set_font_name(ZVT_TERM (term), fontname);
zvt_term_set_blink (ZVT_TERM (term), TRUE);
zvt_term_set_bell (ZVT_TERM (term), TRUE);
zvt_term_set_scrollback(ZVT_TERM (term), scrollbacklines);
zvt_term_set_scroll_on_keystroke (ZVT_TERM (term), TRUE);
zvt_term_set_scroll_on_output (ZVT_TERM (term), FALSE);
zvt_term_set_background (ZVT_TERM (term), NULL, 0, 0);
zvt_term_set_wordclass (ZVT_TERM (term), "-A-Za-z0-9/_:.,?+%=");
/* ZVT_TERM(term)->fore_gc=fg_gc;
ZVT_TERM(term)->back_gc=bg_gc;
ZVT_TERM(term)->scroll_gc=bg_gc;*/
gtk_signal_connect (
GTK_OBJECT (term),
"button_press_event",
GTK_SIGNAL_FUNC (button_press_event),
NULL);
gtk_signal_connect (
GTK_OBJECT (term),
"child_died",
GTK_SIGNAL_FUNC (child_died_event),
NULL);
gtk_signal_connect (
GTK_OBJECT (term),
"delete_event",
GTK_SIGNAL_FUNC (child_died_event),
NULL);
gtk_signal_connect (
GTK_OBJECT (window),
"destroy",
GTK_SIGNAL_FUNC (child_died_event),
NULL);
gtk_signal_connect (
GTK_OBJECT (term),
"title_changed",
GTK_SIGNAL_FUNC (title_changed_event),
NULL);
gtk_signal_connect_after (
GTK_OBJECT (term),
"realize",
GTK_SIGNAL_FUNC (set_hints),
term);
/* scrollbar */
scrollbar =
gtk_vscrollbar_new (GTK_ADJUSTMENT (ZVT_TERM (term)->adjustment));
GTK_WIDGET_UNSET_FLAGS (scrollbar, GTK_CAN_FOCUS);
if (scrollpos == LEFT) {
gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (hbox), term, 1, 1, 0);
} else {
gtk_box_pack_start (GTK_BOX (hbox), term, 1, 1, 0);
gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, TRUE, 0);
}
gtk_widget_show (scrollbar);
linux_red [16] = linux_red [9];
linux_blu [16] = linux_blu [12];
linux_grn [16] = linux_grn [10];
linux_red [17] = linux_red [0];
linux_blu [17] = linux_blu [0];
linux_grn [17] = linux_grn [0];
gtk_widget_realize (window);
/* This causes segfaults on 256 bit displays */
/* zvt_term_set_color_scheme (ZVT_TERM(term), linux_red, linux_grn, linux_blu);*/
zvt_term_set_default_color_scheme(ZVT_TERM(term));
gtk_widget_show (term);
/* show them all! */
pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL,
gdk_colormap_get_system(),
&mask, NULL, python_small_xpm);
gdk_window_set_icon(window->window, NULL, pixmap, mask);
gtk_widget_show_all (window);
create_child();
/* unlock */
child_died_locked = FALSE;
return TRUE;
}
syntax highlighted by Code2HTML, v. 0.9.1