/* GNUPLOT - mtos.trm */
/*
 * Copyright (C) 1994   
 *
 * Permission to use, copy, and distribute this software and its
 * documentation for any purpose with or without fee is hereby granted, 
 * provided that the above copyright notice appear in all copies and 
 * that both that copyright notice and this permission notice appear 
 * in supporting documentation.
 *
 * Permission to modify the software is granted, but not the right to
 * distribute the modified code.  Modifications are to be distributed 
 * as patches to released version.
 *  
 * This software  is provided "as is" without express or implied warranty.
 * 
 * This file is included by ../term.c.
 *
 * This terminal driver supports:
 *   mtos : ATARI Systems MiNT/MULTITOS/MAGIC with external client
 *
 * AUTHOR
 *  Dirk Stadler (email: dirk_stadler@n.maus.de, dirk@lstm.uni-erlangen.de)
 * 
 * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
 * 
 */
 
#ifndef GOT_DRIVER_H
#include "driver.h"
#endif

#ifdef TERM_REGISTER
register_term(mtos)
#endif           

#ifdef TERM_PROTO

/* function-prototypes */
TERM_PUBLIC void MTOS_options(void);
TERM_PUBLIC void MTOS_init(void);
TERM_PUBLIC void MTOS_reset(void);
TERM_PUBLIC void MTOS_graphics(void);
TERM_PUBLIC void MTOS_text(void);
TERM_PUBLIC void MTOS_move(unsigned int x, unsigned int y);
TERM_PUBLIC void MTOS_vector(unsigned int x, unsigned int y);
TERM_PUBLIC void MTOS_linetype(int lt);
TERM_PUBLIC int MTOS_text_angle(int ta);
TERM_PUBLIC void MTOS_put_text(unsigned int x, unsigned int y, char *str);
TERM_PUBLIC int  MTOS_justify_text(enum JUSTIFY mode);
TERM_PUBLIC void MTOS_point(unsigned int x, unsigned int y, int number);

/* default to ST high resolution */
#define MTOS_XMAX  640
#define MTOS_YMAX  400
#define MTOS_VCHAR 18
#define MTOS_HCHAR 12
#define MTOS_HTIC  5
#define MTOS_VTIC  MTOS_HTIC

#define GOT_MTOS_PROTO
#endif /* TERM_PROTO */

#ifndef TERM_PROTO_ONLY
#ifdef TERM_BODY

#include <unistd.h>
#include <fcntl.h>
#include <param.h>
#include <process.h>
#include <signal.h>
#include <support.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>
#include <aesbind.h>
#include <osbind.h>
#include <mintbind.h>

int  MTOS_pause(char *str);
static void MTOS_quit(void);
void MTOS_open_pipe(void);
static void write_pid(void);
static void init_exit(void);

/* commands for GPCLIENT */
#define SET_GRAPHICS    'G'
#define SET_TEXT        'E'
#define SET_LINE        'L'
#define SET_ANGLE       'A'
#define SET_JUSTIFY     'J'
#define SET_POINTMODE   'D'
#define GR_MOVE         'M'
#define GR_DRAW         'V'
#define GR_RESET        'R'
#define GR_TEXT         'T'

#define PAUSE           'P'
#define PID             'I'
#define QUIT            'Q'

/* for creating pipes */
#define PIPE1           "u:\\pipe\\GPLT%d"
#define PIPE2           "u:\\pipe\\gpclient.tmp"
#define NAMESIZE        25
#define SIZE            ((unsigned)sizeof(short))

/* default name for client */
#define GPCLIENT1       "gpclient.prg"
#define GPCLIENT2       "gpclient"

/* environment */
#define MYENV          "GNUPLOTPATH" 
#define PATH           "PATH"

/* some global variables */
static char MTOS_mode = 0;
static int handle = -1;
static int pid = -1;

TERM_PUBLIC void MTOS_options()
{
	term_options[0] = '\0';
}

TERM_PUBLIC void MTOS_init() 
{ 
	char pipe[NAMESIZE];
	char *file, cmd[MAXPATHLEN];
	char const *const ext[] = {"prg", "app", NULL};

	if (handle < 0) {
		if (aesid < 0) {
			if ((aesid = appl_init()) < 0)
				int_error("APPL_INIT failed !", NO_CARET);			
		}

		file = findfile(GPCLIENT2,getenv(MYENV),ext);
		if (!file)
			strcpy(cmd,GPCLIENT1);
		else if (file && !strchr(file,'\\') && !strchr(file,'/'))
			strcpy(cmd,file);
		else
			unx2dos(file,cmd);
		if (!shel_find(cmd))
			int_error("Cannot find GPCLIENT !", NO_CARET);

		sprintf(&pipe[1],PIPE1,aesid);

		if ((handle = open(&pipe[1], O_RDWR | O_CREAT)) < 0) {
			if ((handle = (int)Fcreate(&pipe[1],0)) < 0)
				int_error("Cannot open PIPE to GPCLIENT !", NO_CARET);
		}
		
		pipe[0] = (char)(strlen(&pipe[1])+1);

		if (!shel_write(1,1,100,cmd,pipe)) {
			close(handle);
			handle = -1;
			int_error("Cannot spawn GPCLIENT !", NO_CARET);
		}
       	init_exit();
	}
	if (aesid > -1) menu_register(aesid, "  Terminal: mtos");
}

TERM_PUBLIC void MTOS_reset() 
{
	short buff;

	buff = (short)GR_RESET;
	write(handle, &buff, SIZE); 
}

TERM_PUBLIC void MTOS_text() 
{
	short buff;

	buff = (short)SET_TEXT;
	if (MTOS_mode != SET_TEXT) 
   		write(handle, &buff, SIZE);
	MTOS_mode = SET_TEXT;
}

TERM_PUBLIC void MTOS_graphics()
{ 
	short buff;

	buff = (short)SET_GRAPHICS;
	write(handle, &buff, SIZE);
	MTOS_mode = SET_GRAPHICS ;
}

TERM_PUBLIC void MTOS_move(unsigned int x, unsigned int y)
{ 
	short x_1, y_1, buff;

	x_1 = (short)x;
	y_1 = (short)y;	 
	buff = (short)GR_MOVE;	
	write(handle, &buff, SIZE);
	write(handle, &x_1, SIZE);
	write(handle, &y_1, SIZE);
}

TERM_PUBLIC void MTOS_vector(unsigned int x, unsigned int y)
{ 
	short x_1, y_1, buff;

	x_1 = (short)x;
	y_1 = (short)y;	
	buff = (short)GR_DRAW;
	write(handle, &buff, SIZE);
	write(handle, &x_1, SIZE);
	write(handle, &y_1, SIZE);
}

TERM_PUBLIC void MTOS_linetype(int lt)
{ 
	short lt_1, buff;

	lt_1 = (short)lt;
	buff = (short)SET_LINE;
	write(handle, &buff, SIZE);
	write(handle, &lt_1, SIZE);
}

TERM_PUBLIC int MTOS_text_angle(int ta)
{ 
	short ta_1, buff;

	ta_1 = (short)ta;
	buff = (short)SET_ANGLE;
	write(handle, &buff, SIZE);
	write(handle, &ta_1, SIZE);
	return(TRUE);
}

TERM_PUBLIC void MTOS_put_text(unsigned int x, unsigned int y, char *str) 
{
	short x_1, y_1, len, buff;

	x_1 = (short)x;
	y_1 = (short)y;
	len = (short)strlen(str) + 1;
	buff = (short)GR_TEXT;	
	write(handle, &buff, SIZE);
	write(handle, &x_1, SIZE);
	write(handle, &y_1, SIZE);
	write(handle, &len, SIZE);
	write(handle, str, (unsigned)len);
}

TERM_PUBLIC int MTOS_justify_text(enum JUSTIFY mode)
{
	short j_mode, buff;

	j_mode = (short)mode;
	buff = (short)SET_JUSTIFY;	
	write(handle, &buff, SIZE);
	write(handle, &j_mode, SIZE);
	return(TRUE);
}

TERM_PUBLIC void MTOS_point(unsigned int x, unsigned int y, int number)
{
	short mode, buff;

	buff = (short)SET_POINTMODE;	
	mode = 1;
	write(handle, &buff, SIZE);
	write(handle, &mode, SIZE);    
	do_point(x, y, number); 
	mode = 0;
	write(handle, &buff, SIZE);
	write(handle, &mode, SIZE);
}

int MTOS_pause(char *str)
{
	short len, buff;

	len = (short)strlen(str) + 1;
	buff = (short)PAUSE;	
	write(handle, &buff, SIZE);
	write(handle, &len, SIZE);
	write(handle, str, (unsigned)len);
	read (handle, &len, SIZE);
	return((int)len);
}

static void MTOS_quit()
{
	short buff;
	
	if (pid > -1)
		kill(pid,SIGTERM);
	if (handle > -1) {
		buff = (short)QUIT;
		write(handle, &buff, SIZE);
		close(handle);
	}
}

void MTOS_open_pipe()
{
	char pipe[NAMESIZE];
	short len;
	
	if (handle < 0) {
		if ((handle = open(PIPE2, O_RDWR)) < 0)
            	return;
		read(handle, &len, SIZE);
		if (len > 0) {
        		read(handle, pipe, (unsigned)len);
        		close(handle);
        		if ((handle = open(pipe, O_RDWR)) < 0) {
					fprintf(stderr,"\n\n\33p Can't open Pipe: (%s) Error: (%s) !\33q\n\n",pipe,sys_errlist[errno]);
					fflush(stderr);
            		return;
				}
		}
		init_exit();
	}
}

static void write_pid()
{
	short buff, mypid, gpclpid;
	
	mypid = (short)getpid();
	buff = (short)PID;
	while (write(handle, &buff, SIZE) <= 0)
		Fselect(100,0L,0L,0L);
	while (read(handle, &gpclpid, SIZE) <= 0)
		Fselect(100,0L,0L,0L);
	write(handle, &mypid, SIZE);
	pid = (int)gpclpid;
}

static void init_exit()
{
	Cconout(7);
	write_pid();
	atexit(MTOS_quit);
}

#endif /* TERM_BODY */

#ifdef TERM_TABLE

TERM_TABLE_START(mtos_driver)
	"mtos", "Atari MiNT/MULTITOS/Magic Terminal",
	MTOS_XMAX, MTOS_YMAX, MTOS_VCHAR, MTOS_HCHAR, 
	MTOS_VTIC, MTOS_HTIC, MTOS_options, MTOS_init, MTOS_reset, 
	MTOS_text, null_scale, MTOS_graphics, MTOS_move, MTOS_vector, 
	MTOS_linetype, MTOS_put_text, MTOS_text_angle, 
	MTOS_justify_text, MTOS_point, do_arrow, set_font_null,
	0, TERM_CAN_MULTIPLOT, 0, 0
TERM_TABLE_END(mtos_driver)

#undef LAST_TERM
#define LAST_TERM mtos_driver

#endif /* TERM_TABLE */

#endif /* TERM_PROTO_ONLY */

#ifdef TERM_HELP
START_HELP(mtos)
"1 mtos",
"?set terminal mtos",
"?mtos",
" The `mtos` terminal has no options.  It sends data via a pipe to an external",
" program called GPCLIENT. It runs under MiNT, MULTITOS, Magic 3.x and MagicMAC.",
" If you cannot find GPCLIENT, than mail to dirk@lstm.uni-erlangen.de."
END_HELP(mtos)
#endif /* TERM_HELP */
