Logo Search packages:      
Sourcecode: scigraphica version File versions  Download package

python_term.c

/*  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;  
}

Generated by  Doxygen 1.6.0   Back to index