#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<ctype.h>
#include<errno.h>
#include "connect.h"
#include "support.h"
#include "bitmap.h"



#define STEGO_VERSION "0.4"

int on_encrypt_decrypt_toggled(GtkWidget *w,gpointer data)
{
  extern GtkWidget *window;
  extern StegoState state;

  if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
    {
      state.state='D';
      stego_change_state(&state,window);

      w=lookup_widget(window,"sbar");
      gtk_statusbar_pop(GTK_STATUSBAR(w),0);
      gtk_statusbar_push(GTK_STATUSBAR(w),
			 0,"Decrypt Mode");
    }
  else
    {
      state.state='E';
      stego_change_state(&state,window);

      w=lookup_widget(window,"sbar");
      gtk_statusbar_pop(GTK_STATUSBAR(w),0);
      gtk_statusbar_push(GTK_STATUSBAR(w),
			 0,"Encrypt Mode");

    }

  return TRUE;
}

int on_encrypt_btn_clicked(GtkWidget *w,gpointer data)
{
  extern GtkWidget *window;
  extern StegoState state;
  GtkWidget *x;
  GtkTextBuffer *tb;
  GtkTextIter start,end;
  gint tempval=0;
  
  bmpheader bmph;
  FILE *fsrc,*fdest;
  gchar *fSrc,*fDest,*message;
  gchar buffer[54];


  w=lookup_widget(window,"sbar");
  gtk_statusbar_pop(GTK_STATUSBAR(w),0);

  x=lookup_widget(window,"src_file_entry");
  fSrc=(gchar *)gtk_entry_get_text(GTK_ENTRY(x));
  x=lookup_widget(window,"des_file_entry");
  fDest=(gchar *)gtk_entry_get_text(GTK_ENTRY(x));

  x=lookup_widget(window,"text");
  tb=gtk_text_view_get_buffer(GTK_TEXT_VIEW(x));
  gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(tb),&start,&end);
  message=gtk_text_buffer_get_text( GTK_TEXT_BUFFER(tb),
				    &start,&end,
				    FALSE);
  message=g_strconcat(message," ",NULL);  
  
  if(state.src_file!= TRUE && state.des_file!= TRUE)
    {
      gtk_statusbar_push(GTK_STATUSBAR(w),
		     0,"Choose Proper Files & Enter Message");
      return stego_report_dialog("Choose Files, Enter Text, Then click me");
    }

  
#ifdef DEBUG_STEGO
  g_printf("Encrypt clicked\n");  
#endif 


#ifdef DEBUG_STEGO
  g_printf("fSrc=%s fDest=%s  message=%s\n",fSrc,fDest,message);
#endif 

  fsrc=fopen(fSrc,"rb");
  fdest=fopen(fDest,"wb");



  if ((fsrc != NULL) && (fdest != NULL))
    {

#ifdef DEBUG_STEGO
      printf("File src  %s & des %s opened\n",fSrc,fDest);
#endif
    }

  else
    {
      gtk_statusbar_push(GTK_STATUSBAR(w),
		     0,"Cannot Open File.");
      stego_report_dialog("Cannot Open one/both of the files\n");
      g_free(message);
      return -2;
    }

  bmp_read_header(fsrc,&bmph);
  fseek(fsrc,0,SEEK_SET);

  fread(buffer,54,1,fsrc);
  fseek(fsrc,0,SEEK_SET);
  fwrite(buffer,54,1,fdest);


  tempval=8*strlen(message);
#ifdef DEBUG_STEGO
  g_printf("len(message)=%d pixelsize=%d\n",tempval/8,bmph.pixelsize);
#endif
  if (tempval > (3*bmph.pixelsize))
    {
      gtk_statusbar_push(GTK_STATUSBAR(w),
		     0,"Image File is too small to fit your data");
      stego_report_dialog("Image File is too small to fit your data\n");
      fclose(fsrc);
      g_free(message);
      return -1;
    }

  //encode the message.
  stego_encode_message_to_file(fdest,fsrc,message);
  stego_file_copy(fdest,fsrc);

  x=lookup_widget(window,"text");
  if(x!=NULL)
    {
      gtk_widget_set_sensitive(x,TRUE);
      gtk_text_view_set_editable(GTK_TEXT_VIEW(x),TRUE);
    }

  
  x=lookup_widget(window,"src_image_btn");
  if(x!=NULL)
    gtk_widget_set_sensitive(x,TRUE);      
  else
#ifdef DEBUG_STEGO
    g_printf("src_image==NULL");
#endif  
      
  x=lookup_widget(window,"des_image_btn");
  if(x!=NULL)
    gtk_widget_set_sensitive(x,TRUE);
  else
#ifdef DEBUG_STEGO
    g_printf("dest_image==NULL");
#endif
  gtk_statusbar_push(GTK_STATUSBAR(w),
		     0,"Encryption Over");
  stego_report_dialog("Encrypted!");

  fclose(fsrc);
  fclose(fdest);
  g_free(message);
  return TRUE;
}

int on_decrypt_btn_clicked(GtkWidget *w,gpointer data)
{
  extern GtkWidget *window;
  extern StegoState state;
  GtkTextBuffer *tb;
  GtkWidget *x;
  GtkTextIter start;

  FILE *fsrc;
  gchar *fSrc;
  gchar *message;
  guint l=0;

#ifdef DEBUG_STEGO
  g_printf("Decrypt clicked\n");
#endif

  w=lookup_widget(window,"sbar");
  gtk_statusbar_pop(GTK_STATUSBAR(w),0);//clear older values.

  if(state.src_file != TRUE)
    return stego_report_dialog("Choose Encrypted File , Then click me");
  

  x=lookup_widget(window,"src_file_entry");
  fSrc=(gchar *)gtk_entry_get_text(GTK_ENTRY(x));

#ifdef DEBUG_STEGO
  g_printf("File name: %s\n",fSrc);
#endif  
  fsrc=fopen(fSrc,"rb");

  if (fsrc == NULL)
    {
      gtk_statusbar_push(GTK_STATUSBAR(w),
		     0,"Cannot Open File");  
      stego_report_dialog("Cannot Open the files\n");
      return -2;
    }


#ifdef DEBUG_STEGO
      printf("File %s opened\n",fSrc);
#endif


  message=g_malloc(sizeof(gchar)*1024*10); //10 Kb text?

  fseek(fsrc,54,SEEK_CUR);//oops I forgot this!earlier.
  l=stego_decode_message_to_file(stdout,fsrc,message,1024*10);
#ifdef DEBUG_STEGO   
  g_printf("Message=%s\n",message);
#endif
  x=lookup_widget(window,"text");
  tb=gtk_text_view_get_buffer(GTK_TEXT_VIEW(x));

  gtk_text_buffer_set_text (GTK_TEXT_BUFFER(tb),message,l);
  gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(tb),&start);
  gtk_text_buffer_set_text(GTK_TEXT_BUFFER(tb),
			   message,l);  
  
  if(x!=NULL)
    {
      gtk_widget_set_sensitive(x,TRUE);
      gtk_text_view_set_editable(GTK_TEXT_VIEW(x),FALSE);
    }
  

#ifdef DEBUG_STEGO
  g_printf("fSrc=%s message=%s\n",fSrc,message);
#endif 

  gtk_statusbar_push(GTK_STATUSBAR(w),
		     0,"Decryption Over.");  
  stego_report_dialog("Decryption Over!");
  g_free(message);
  fclose(fsrc);
  return TRUE;
}

int on_srcimage_clicked(GtkWidget *w,gpointer data)
{
  extern GtkWidget *window;
  GtkWidget *x,*y;
  gchar *fSrc;
  
#ifdef DEBUG_STEGO
  g_printf("srcimage\n");
#endif
  x=lookup_widget(window,"src_file_entry");
  fSrc=(gchar *)gtk_entry_get_text(GTK_ENTRY(x));    

#ifdef DEBUG_STEGO
  g_printf("Opening %s",fSrc);
#endif

  if(fSrc == NULL || g_file_test(fSrc,G_FILE_TEST_EXISTS)==FALSE)
    {
      if(fSrc==NULL || strlen(fSrc) < 1)
	{
	  fSrc=g_strconcat("Please Choose File to Display.",NULL);
	}
      else
	fSrc=g_strconcat("Cannot Open file \"",fSrc,"\" ",NULL);

      stego_report_dialog(fSrc);
      g_free(fSrc);
      return -1;
    }


  y=gtk_image_new_from_file(fSrc);
  if(y==NULL)
    {
      fSrc=g_strconcat("Cannot Open Image ",fSrc,NULL);
      stego_report_dialog(fSrc);
      g_free(fSrc);
      return -2;
    }
  
  x=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(x),fSrc);
  gtk_window_set_position(GTK_WINDOW(x),GTK_WIN_POS_CENTER_ON_PARENT);

  gtk_container_add(GTK_CONTAINER(x),y);
  gtk_window_set_modal(GTK_WINDOW(x),FALSE);//need not be

  gtk_widget_set_events(x,gtk_widget_get_events(x) | GDK_KEY_PRESS | GDK_BUTTON_PRESS | GDK_2BUTTON_PRESS);

  gtk_signal_connect (GTK_OBJECT (x), "key_press_event",
                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
		      NULL);

  gtk_signal_connect (GTK_OBJECT (x), "button_press_event",
                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
		      NULL);

  gtk_signal_connect (GTK_OBJECT (x), "destroy",
                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
		      NULL);


  gtk_widget_show(y);
  gtk_widget_show(x);

  
  return TRUE;
}

int on_destimage_clicked(GtkWidget *w,gpointer data)
{
  extern GtkWidget *window;
  GtkWidget *x,*y;
  gchar *fSrc;

#ifdef DEBUG_STEGO  
  g_printf("desimage\n");
#endif

  x=lookup_widget(window,"des_file_entry");
  fSrc=(gchar *)gtk_entry_get_text(GTK_ENTRY(x));    

#ifdef DEBUG_STEGO
  g_printf("Opening %s",fSrc);
#endif

  if(fSrc == NULL || g_file_test(fSrc,G_FILE_TEST_EXISTS)==FALSE)
    {
      if(fSrc==NULL || strlen(fSrc) < 1)
	{
	  fSrc=g_strconcat("Please Choose File to Display.",NULL);
	}
      else
	fSrc=g_strconcat("Cannot Open file \"",fSrc,"\" ",NULL);

      stego_report_dialog(fSrc);
      g_free(fSrc);
      return -1;
    }

  y=gtk_image_new_from_file(fSrc);
  if(y==NULL)
    {
      fSrc=g_strconcat("Cannot Open Image ",fSrc,NULL);
      stego_report_dialog(fSrc);
      g_free(fSrc);
      return -2;
    }

  
  x=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(x),fSrc);
  gtk_window_set_position(GTK_WINDOW(x),GTK_WIN_POS_CENTER_ON_PARENT);

  gtk_container_add(GTK_CONTAINER(x),y);
  gtk_window_set_modal(GTK_WINDOW(x),FALSE);//need not be

  gtk_widget_set_events(x,gtk_widget_get_events(x) | GDK_KEY_PRESS | GDK_BUTTON_PRESS | GDK_2BUTTON_PRESS);


  gtk_signal_connect (GTK_OBJECT (x), "key_press_event",
                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
		      NULL);

  gtk_signal_connect (GTK_OBJECT (x), "button_press_event",
                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
		      NULL);


  gtk_signal_connect (GTK_OBJECT (x), "destroy",
                      GTK_SIGNAL_FUNC (gtk_widget_destroy),
		      NULL);  
  gtk_widget_show(y);
  gtk_widget_show(x);


  return TRUE;
}  



int on_srcfile_clicked(GtkWidget *w,gpointer data)
{
  extern StegoState state;
  extern GtkWidget *window;


  gchar *fname;
  GtkEntry *k;
  
  k=(GtkEntry *)data;  
  fname=stego_get_file_ensure("Source File",".bmp");
  if(fname==NULL)
    {
      GtkWidget *w=NULL;
      w=lookup_widget(window,"sbar");
      gtk_statusbar_pop(GTK_STATUSBAR(w),0);
      gtk_statusbar_push(GTK_STATUSBAR(w),
			 0,"Please Choose a BMP File!");
      /* gtk_entry_set_text(k,"Please Choose a BMP File!"); */
      state.src_file=FALSE;
    }
  else
    {
      gtk_entry_set_text(k,fname);  
      state.src_file=TRUE;
    }
  g_free(fname);
  return TRUE;
}

int on_desfile_clicked(GtkWidget *w,gpointer data)
{
  extern StegoState state;
  extern GtkWidget *window;

  gchar *fname;
  GtkEntry *k;
  
  k=(GtkEntry *)data;  
  
  if(state.state=='E')    
    stego_report_dialog("The destination File Will Be Over Written!\n");
  else
    {
      //Decryption doesnot overwrite the files!
    }

  fname=stego_get_file_ensure("Destination File",".bmp");
  if(fname==NULL)
    {
      GtkWidget *w=NULL;
      w=lookup_widget(window,"sbar");
      gtk_statusbar_pop(GTK_STATUSBAR(w),0);
      gtk_statusbar_push(GTK_STATUSBAR(w),
			 0,"Please Choose a BMP File!");
      /* gtk_entry_set_text(k,"Please Choose a BMP File!"); */
      state.des_file=FALSE;
    }
  else
    {
      gtk_entry_set_text(k,fname);  
      state.des_file=TRUE;
    }
  g_free(fname);
  return TRUE;
}


int on_destfile_changed(GtkEntry *e,gpointer data)
{
  extern StegoState state;
  
  if(GTK_IS_ENTRY(e))
    {
      if(strlen(gtk_entry_get_text(e))>0)
	{
	  state.des_file=TRUE;
#ifdef DEBUG_STEGO
	  g_printf("State: des_file TRUE\n");
#endif
	}
      else
	{
	  state.des_file=FALSE;
#ifdef DEBUG_STEGO
	  g_printf("State: des_file FALSE\n");
#endif
	}
    }
  return TRUE;
}

int on_srcfile_changed(GtkEntry *e,gpointer data)
{
 extern StegoState state;
  
  if(GTK_IS_ENTRY(e))
    {
      if(strlen(gtk_entry_get_text(e))>0)
	{
	  state.src_file=TRUE;
#ifdef DEBUG_STEGO
	  g_printf("State: src_file TRUE\n");
#endif
	}
      else
	{
	  state.src_file=FALSE;
#ifdef DEBUG_STEGO
	  g_printf("State: src_file FALSE\n");
#endif
	}
	
    }
  return TRUE;
}

gboolean on_srcfile_drag(GtkWidget *w,GdkDragContext     *context,
			 gint x,gint y,guint time)
{
#ifdef STEGO_DEBUG
  g_printf("Droppings: Im Called\n");
#endif
  return TRUE;
}

void on_text_changed(GtkTextBuffer *buffer,gpointer data)
{
  GtkTextView *view;
  GtkTextIter lineiter,enditer;
 
  view=(GtkTextView *)data;

#ifdef DEBUG_STEGO
  g_printf("Text buffer changed.\n");
#endif

  gtk_text_buffer_get_bounds(buffer,&lineiter,&enditer);
  gtk_text_buffer_apply_tag_by_name     (buffer,
					 "ThemeFgBg",
					 &lineiter,
 					 &enditer);
  return;
}  

/* Help must be, NON Modal or its self-defeating  */
gboolean stego_help_contents(GtkWidget *w,gpointer data)
{
  GtkWidget *okb,*box; 
  GtkWidget *im;
  GtkTextBuffer *tb;
  GtkTextIter lineiter,enditer;
  GtkWidget *scrwin;
  GtkWidget *text;
  static gchar *help_text=NULL;
  gint length=0;

  w=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_modal(GTK_WINDOW(w),FALSE);

  scrwin=gtk_scrolled_window_new(NULL,NULL);

  box=gtk_vbox_new(FALSE,FALSE);
  gtk_window_set_default_size(GTK_WINDOW(w),400,500);
  okb=gtk_button_new_from_stock(GTK_STOCK_OK);  
  tb=gtk_text_buffer_new(NULL);

  if(!help_text)
    {
      g_file_get_contents(STEGO_DOC_DIR "/stego.help",
			  &help_text,&length,NULL);
      if(length<= 0)
	help_text=g_strdup("Cannot Find Help file: " STEGO_DOC_DIR "/stego.help");
    }
  
  gtk_text_buffer_set_text(tb,help_text, -1);

  gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(tb),
			     "ThemeFgBg",
			     "foreground","purple",//
			     "background","white",//
			     "wrap_mode",TRUE,
			     "justification",GTK_JUSTIFY_LEFT,
			     "underline",TRUE,
			     "editable",FALSE,
			     //"background_stipple",NULL //add it in future
			     NULL);

  gtk_text_buffer_get_bounds(tb,&lineiter,&enditer);
  gtk_text_buffer_apply_tag_by_name     (tb,
					 "ThemeFgBg",
					 &lineiter,
 					 &enditer);

  im=gtk_image_new_from_file(STEGO_IMAGE_DIR "/gnome-emacs.png");
  gtk_text_buffer_insert_pixbuf(tb,&enditer,
				gtk_image_get_pixbuf(GTK_IMAGE(im)));

  text=gtk_text_view_new_with_buffer(tb);
  gtk_text_view_set_editable(GTK_TEXT_VIEW(text),FALSE);
  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrwin),text);
  gtk_box_pack_start_defaults(GTK_BOX(box),scrwin);
  gtk_box_pack_start(GTK_BOX(box),
		     gtk_label_new("Free Software is a"
				   " matter of freedom, Not Price -RMS")
		     ,FALSE,FALSE,0);

  gtk_box_pack_start(GTK_BOX(box),
		     okb,FALSE,FALSE,0);

  gtk_container_add(GTK_CONTAINER(w),box);

  gtk_window_set_position(GTK_WINDOW(w),GTK_WIN_POS_CENTER_ON_PARENT);
  gtk_widget_grab_focus(okb);
  gtk_widget_grab_focus(w);
  gtk_widget_show_all(w);

  g_signal_connect(G_OBJECT(w),"destroy",G_CALLBACK(gtk_widget_destroy),NULL);
  g_signal_connect_swapped(G_OBJECT(okb),"clicked",
			   G_CALLBACK(gtk_widget_destroy),w);
  
  /*gtk_dialog_run(GTK_DIALOG(w));
    gtk_widget_destroy(w);*/
  /* g_free(help_text); */
  
  return TRUE;
}

/*
  Modal and blocks.
*/
gboolean stego_about(GtkWidget *widget,gpointer data)
{
  GtkWidget *w; 
  GtkWidget *okb; 
  GtkWidget *im;
  GtkTextBuffer *tb;
  GtkTextIter lineiter,enditer;
  GtkWidget *text;

  w=gtk_dialog_new();
  gtk_window_set_default_size(GTK_WINDOW(w),200,200);
  okb=gtk_button_new_from_stock(GTK_STOCK_OK);      
  tb=gtk_text_buffer_new(NULL);
  gtk_text_buffer_set_text(tb,"Stego: Its a small Image Encryption Program.\n"
			   "Stego aims to demonstrate steganography as it,\n"
			   "applies to image hiding, within pictures\n"
			   "\n\n"
			   "Author: Muthiah Annamalai\n"
			   "Contact: <gnumuthu@users.sf.net>",
			   -1);

  gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(tb),
			     "ThemeFgBg",
			     "foreground","#f07eda",//
			     "background","#ffffff",//
			     "wrap_mode",TRUE,
			     "justification",GTK_JUSTIFY_LEFT,
			     "underline",TRUE,
			     "editable",FALSE,
			                       //"background_stipple",NULL //add it in future
			     NULL);

  gtk_text_buffer_get_bounds(tb,&lineiter,&enditer);
  gtk_text_buffer_apply_tag_by_name     (tb,
					 "ThemeFgBg",
					 &lineiter,
 					 &enditer);


  im=gtk_image_new_from_file(STEGO_IMAGE_DIR "/gnome-emacs.png");
  gtk_text_buffer_insert_pixbuf(tb,&enditer,
				gtk_image_get_pixbuf(GTK_IMAGE(im)));

  text=gtk_text_view_new_with_buffer(tb);
  gtk_text_view_set_editable(GTK_TEXT_VIEW(text),FALSE);

  gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(w)->vbox),text);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(w)->vbox),
		     gtk_label_new("Free Software is a"
				   " matter of freedom, Not Price -RMS")
		     ,FALSE,FALSE,0);
  gtk_dialog_add_action_widget(GTK_DIALOG(w),okb,GTK_RESPONSE_OK);
  gtk_window_set_position(&GTK_DIALOG(w)->window,GTK_WIN_POS_CENTER_ON_PARENT);
  gtk_widget_grab_focus(okb);
  gtk_widget_show_all(w);
  gtk_dialog_run(GTK_DIALOG(w));
  gtk_widget_destroy(w);
  return 0;
}
 
gboolean on_decrypt_toolbar_clicked(GtkWidget *w)
{
   on_decrypt_btn_clicked(NULL,NULL);
   return TRUE;
}

gboolean on_encrypt_toolbar_clicked(GtkWidget *w)
{
  on_encrypt_btn_clicked(NULL,NULL);
  return TRUE;
}

gboolean  entry_drop_handle (GtkWidget        *widget,
			     GdkDragContext   *context,
			     gint              x,
			     gint              y,
			     GtkSelectionData *selection_data,
			     guint             info,
			     guint             time,
			     gpointer          data)
{
  gchar *str,*p;

#ifdef STEGO_DEBUG
  g_printf("Drop Handle\n");
#endif

  str=(gchar *)selection_data->data;
  str=selection_data->data;  
  str=str+strlen("file://"); //hoping you dont drag in URL's!! ;-)
  p=str;

#ifdef STEGO_DEBUG
  g_printf("File: %s\n",str);
#endif
  while(isalnum(*str)!=0 || *str=='/' || *str=='-' || *str=='.' || *str=='_') 
    str++;

  *str='\0';
  str=p;

#ifdef STEGO_DEBUG
  g_printf("Filename: %s\n",str);
#endif

  gtk_entry_set_text(GTK_ENTRY(widget),str);

#ifdef STEGO_DEBUG
  g_printf("%s\n",str);
#endif
  return TRUE;
}


gboolean  entry_drop   (GtkWidget        *widget,
			GdkDragContext    *context,
			gint              x,
			gint              y,
			guint          time)
{
  gtk_drag_finish(context,TRUE,FALSE,time);//indicate success.
  return TRUE;
}

gboolean  text_drop_handle (GtkWidget        *widget,
			     GdkDragContext   *context,
			     gint              x,
			     gint              y,
			     GtkSelectionData *selection_data,
			     guint             info,
			     guint             time,
			     gpointer          data)
{
  gchar *str,*p;
  FILE *fp;
  GtkTextBuffer *tb;
  guint size;
  guint read;

#ifdef STEGO_DEBUG
  g_printf("Text WIdget Drop Handle\n");
#endif

  str=(gchar *)selection_data->data;
  str=selection_data->data;  
  str=str+strlen("file://"); //hoping you dont drag in URL's!! ;-)
  p=str;

#ifdef STEGO_DEBUG
  g_printf("File: %s\n",str);
#endif
  while(isalnum(*str)!=0 || *str=='/' || *str=='-' || *str=='.' || *str=='_') 
    str++;

  *str='\0';
  str=p;

#ifdef STEGO_DEBUG
  g_printf("Filename: %s\n",str);
#endif

  tb=gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));

  fp=fopen(str,"r");
  if(fp==NULL)
    {
      size=-1;
      return TRUE;
    }
  
  p=g_malloc(sizeof(char)*1024);
  while(!feof(fp))
    {
      bzero(p,1024);
      read=fread(p,1024,1,fp);

#ifdef STEGO_DEBUG
      g_printf("Read: %d\n",read);
#endif
      gtk_text_buffer_insert_at_cursor(tb,
				       p,
				       -1);
      
    }

  {
    GtkTextIter ti;
    GtkTextMark *tm;
    gtk_text_buffer_get_start_iter(tb,&ti);
    tm=gtk_text_buffer_create_mark(tb,"top",&ti,TRUE);
    gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(widget),
				       tm);
    
  }

  g_free(p);
  fclose(fp);

#ifdef STEGO_DEBUG
  g_printf("%s\n",str);
#endif
  return TRUE;
}
