/******************************************************************************
*		       							      *
* gnome/main.c (part of rcalc)					       	      *
* Copyright (C) 2001 Free Software Foundation, Inc.			      *
*								       	      *
* 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.	       	      *
*								       	      *
******************************************************************************/

/* This file acts as a wrapper to hide the IPC stuff from the GNOME UI stuff
*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include "main.h"		/* This file's header	     		*/
#include "app.h"		/* The main process (GUI and engine)	*/
#include "reader.h"		/* The reader process (readline)	*/
#include <engine/debug.h>	/* Debugging functions			*/

#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>

/*****************************************************************************/

/* Safe replacements for pipe() and fdopen() respectively.
*/
static void rc_pipe( int filedes[2] )
{
	gint error;

	errno = 0;
	error = pipe( filedes );
	error = error < 0 ? errno : error;

	if( error )
		g_error( "pipe(): failed due to: %s.", g_strerror( error ) );
}
static FILE *rc_fdopen( int filedes, const char *mode )
{
	FILE *file;
	
	errno = 0;
	file = fdopen( filedes, mode );

	if( !file )
		g_error( "fdopen(): failed due to: %s.", g_strerror( errno ) );

	return file;
}

/*****************************************************************************/

/* Run rcalc's GNOME user interface.
*/
void rc_gnome_main( int argc, char **argv, const struct poptOption *options )
{
	int main_to_reader[2];
	int reader_to_main[2];
	ZvtTerm *terminal;
	pid_t child_pid;

	rc_debug( RC_DBG_TOPLEVEL, "executing GNOME user interface." );

	/* Create the pipes
	*/
	rc_pipe( main_to_reader );
	rc_pipe( reader_to_main );

	/* Create the terminal and fork
	*/
	terminal  = ZVT_TERM( zvt_term_new_with_size( 10, 10 ) );
	errno     = 0;
	child_pid = zvt_term_forkpty( terminal, FALSE );
	if( child_pid == -1 )
	{
		g_error( "fork(): failed due to: %s.", g_strerror( errno ) );
	}
	if( child_pid )
	{
		FILE *to_reader, *from_reader;
		
		/* Set the process name */
		g_set_prgname( PACKAGE );

		/* Close the pipe ends that don't concern us. */
		close( main_to_reader[0] );
		close( reader_to_main[1] );

		/* Associate stdio streams to the other pipe ends */
		to_reader   = rc_fdopen( main_to_reader[1], "w" );
		from_reader = rc_fdopen( reader_to_main[0], "r" );
		
		/* Run the main process */
		rcg_main_process( to_reader, from_reader, terminal );

		/* Kill the reader process:
		**  SIGUSR1 tells it to write ~/.rcalc_history, then
		**  SIGTERM kills it dead.
		*/
		kill( child_pid, SIGUSR1 );
		kill( child_pid, SIGTERM );
		waitpid( child_pid, NULL, 0 );
	}
	else
	{
		FILE *to_main, *from_main;

		/* Set the process name */
		g_set_prgname( PACKAGE "-reader" );

		/* Close the pipe ends that don't concern us. */
		close( main_to_reader[1] );
		close( reader_to_main[0] );

		/* Associate stdio streams to the other pipe ends */
		to_main   = rc_fdopen( reader_to_main[1], "w" );
		from_main = rc_fdopen( main_to_reader[0], "r" );

		/* Run the reader process */
		rcg_reader_process( to_main, from_main );
	}
}

/*** end of gnome/main.c *****************************************************/
