
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by tralfaz!ove on Mon Nov 14 21:38:40 EST 1988
# Contents:  region.c spawn.c spawn.c,v st520.c
 
echo x - region.c
sed 's/^@//' > "region.c" <<'@//E*O*F region.c//'
/*
 * The routines in this file
 * deal with the region, that magic space
 * between "." and mark. Some functions are
 * commands. Some functions are just for
 * internal use.
 */
#include        <stdio.h>
#include	"estruct.h"
#include        "edef.h"

#if	MEGAMAX & ST520
overlay	"region"
#endif

/*
 * Kill the region. Ask "getregion"
 * to figure out the bounds of the region.
 * Move "." to the start, and kill the characters.
 * Bound to "C-W".
 */
killregion(f, n)
{
        register int    s;
        REGION          region;

	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
		return(rdonly());	/* we are in read only mode	*/
        if ((s=getregion(&region)) != TRUE)
                return (s);
        if ((lastflag&CFKILL) == 0)             /* This is a kill type  */
                kdelete();                      /* command, so do magic */
        thisflag |= CFKILL;                     /* kill buffer stuff.   */
        curwp->w_dotp = region.r_linep;
        curwp->w_doto = region.r_offset;
        return (ldelete(region.r_size, TRUE));
}

/*
 * Copy all of the characters in the
 * region to the kill buffer. Don't move dot
 * at all. This is a bit like a kill region followed
 * by a yank. Bound to "M-W".
 */
copyregion(f, n)
{
        register LINE   *linep;
        register int    loffs;
        register int    s;
        REGION          region;

        if ((s=getregion(&region)) != TRUE)
                return (s);
        if ((lastflag&CFKILL) == 0)             /* Kill type command.   */
                kdelete();
        thisflag |= CFKILL;
        linep = region.r_linep;                 /* Current line.        */
        loffs = region.r_offset;                /* Current offset.      */
        while (region.r_size--) {
                if (loffs == llength(linep)) {  /* End of line.         */
                        if ((s=kinsert('\n')) != TRUE)
                                return (s);
                        linep = lforw(linep);
                        loffs = 0;
                } else {                        /* Middle of line.      */
                        if ((s=kinsert(lgetc(linep, loffs))) != TRUE)
                                return (s);
                        ++loffs;
                }
        }
	mlwrite("[region copied]");
        return (TRUE);
}

/*
 * Lower case region. Zap all of the upper
 * case characters in the region to lower case. Use
 * the region code to set the limits. Scan the buffer,
 * doing the changes. Call "lchange" to ensure that
 * redisplay is done in all buffers. Bound to
 * "C-X C-L".
 */
lowerregion(f, n)
{
        register LINE   *linep;
        register int    loffs;
        register int    c;
        register int    s;
        REGION          region;

	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
		return(rdonly());	/* we are in read only mode	*/
        if ((s=getregion(&region)) != TRUE)
                return (s);
        lchange(WFHARD);
        linep = region.r_linep;
        loffs = region.r_offset;
        while (region.r_size--) {
                if (loffs == llength(linep)) {
                        linep = lforw(linep);
                        loffs = 0;
                } else {
                        c = lgetc(linep, loffs);
                        if (c>='A' && c<='Z')
                                lputc(linep, loffs, c+'a'-'A');
                        ++loffs;
                }
        }
        return (TRUE);
}

/*
 * Upper case region. Zap all of the lower
 * case characters in the region to upper case. Use
 * the region code to set the limits. Scan the buffer,
 * doing the changes. Call "lchange" to ensure that
 * redisplay is done in all buffers. Bound to
 * "C-X C-L".
 */
upperregion(f, n)
{
        register LINE   *linep;
        register int    loffs;
        register int    c;
        register int    s;
        REGION          region;

	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
		return(rdonly());	/* we are in read only mode	*/
        if ((s=getregion(&region)) != TRUE)
                return (s);
        lchange(WFHARD);
        linep = region.r_linep;
        loffs = region.r_offset;
        while (region.r_size--) {
                if (loffs == llength(linep)) {
                        linep = lforw(linep);
                        loffs = 0;
                } else {
                        c = lgetc(linep, loffs);
                        if (c>='a' && c<='z')
                                lputc(linep, loffs, c-'a'+'A');
                        ++loffs;
                }
        }
        return (TRUE);
}

/*
 * This routine figures out the
 * bounds of the region in the current window, and
 * fills in the fields of the "REGION" structure pointed
 * to by "rp". Because the dot and mark are usually very
 * close together, we scan outward from dot looking for
 * mark. This should save time. Return a standard code.
 * Callers of this routine should be prepared to get
 * an "ABORT" status; we might make this have the
 * conform thing later.
 */
getregion(rp)
register REGION *rp;
{
        register LINE   *flp;
        register LINE   *blp;
        long fsize;
        long bsize;

        if (curwp->w_markp == NULL) {
                mlwrite("No mark set in this window");
                return (FALSE);
        }
        if (curwp->w_dotp == curwp->w_markp) {
                rp->r_linep = curwp->w_dotp;
                if (curwp->w_doto < curwp->w_marko) {
                        rp->r_offset = curwp->w_doto;
                        rp->r_size = (long)(curwp->w_marko-curwp->w_doto);
                } else {
                        rp->r_offset = curwp->w_marko;
                        rp->r_size = (long)(curwp->w_doto-curwp->w_marko);
                }
                return (TRUE);
        }
        blp = curwp->w_dotp;
        bsize = (long)curwp->w_doto;
        flp = curwp->w_dotp;
        fsize = (long)(llength(flp)-curwp->w_doto+1);
        while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
                if (flp != curbp->b_linep) {
                        flp = lforw(flp);
                        if (flp == curwp->w_markp) {
                                rp->r_linep = curwp->w_dotp;
                                rp->r_offset = curwp->w_doto;
                                rp->r_size = fsize+curwp->w_marko;
                                return (TRUE);
                        }
                        fsize += llength(flp)+1;
                }
                if (lback(blp) != curbp->b_linep) {
                        blp = lback(blp);
                        bsize += llength(blp)+1;
                        if (blp == curwp->w_markp) {
                                rp->r_linep = blp;
                                rp->r_offset = curwp->w_marko;
                                rp->r_size = bsize - curwp->w_marko;
                                return (TRUE);
                        }
                }
        }
        mlwrite("Bug: lost mark");
        return (FALSE);
}

@//E*O*F region.c//
chmod u=rw,g=r,o=r region.c
 
echo x - spawn.c
sed 's/^@//' > "spawn.c" <<'@//E*O*F spawn.c//'
/*	Spawn:	various DOS access commands
		for MicroEMACS
*/

#include        <stdio.h>
#include	"estruct.h"
#include        "edef.h"

#if     AMIGA
#define  NEW   1006L
#endif

#if		ST520 & MEGAMAX
#include <osbind.h>
#include <string.h>
#define LOAD_EXEC 0 	/* load and execute the program */
char	*STcmd,		/* the command filename & path  */
	*STargs,	/* command args (if any)        */
	*STenv,		/* environment                  */
	*STwork;	/* work area			*/
#endif

#if     VMS
#define EFN     0                               /* Event flag.          */

#include        <ssdef.h>                       /* Random headers.      */
#include        <stsdef.h>
#include        <descrip.h>
#include        <iodef.h>

extern  int     oldmode[3];                     /* In "termio.c"        */
extern  int     newmode[3];                     /* In "termio.c"        */
extern  short   iochan;                         /* In "termio.c"        */
#endif

#if     V7 | USG | BSD
#include        <signal.h>
extern int vttidy();
#endif

#if	MSDOS & (MSC | TURBO)
#include	<process.h>
#endif

/*
 * Create a subjob with a copy of the command intrepreter in it. When the
 * command interpreter exits, mark the screen as garbage so that you do a full
 * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
 * Under some (unknown) condition, you don't get one free when DCL starts up.
 */
spawncli(f, n)
{
#if     AMIGA
        long newcli;

#endif

#if     V7 | USG | BSD
        register char *cp;
        char    *getenv();
#endif

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

#if	AMIGA
        mlwrite("[Starting new CLI]");
        sgarbf = TRUE;
        Execute("NEWCLI \"CON:0/0/640/200/MicroEMACS Subprocess\"", 0L, 0L);
        return(TRUE);
#endif

#if     VMS
        movecursor(term.t_nrow, 0);             /* In last line.        */
        mlputs("[Starting DCL]\r\n");
        TTflush(); 	                     /* Ignore "ttcol".      */
        sgarbf = TRUE;
        return (sys(NULL));                     /* NULL => DCL.         */
#endif
#if     CPM
        mlwrite("Not in CP/M-86");
#endif
#if	ST520
	mlwrite("Not in TOS");
#endif
#if     MSDOS & (AZTEC | MSC | TURBO)
        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
        TTflush();
	TTkclose();
	system("command.com");
	TTkopen();
        sgarbf = TRUE;
        return(TRUE);
#endif
#if     MSDOS & LATTICE
        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
        TTflush();
	TTkclose();
        sys("\\command.com", "");               /* Run CLI.             */
	TTkopen();
        sgarbf = TRUE;
        return(TRUE);
#endif
#if     (V7 | USG | BSD)
#if     NeWS
	mlwrite("Not availible under NeWS");
	return(FALSE);
#else
        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
        TTflush();
        TTclose();                              /* stty to old settings */
        if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
                system(cp);
        else
#if	BSD
                system("exec /bin/csh");
#else
                system("exec /bin/sh");
#endif
        sgarbf = TRUE;
        sleep(2);
        TTopen();
        return(TRUE);
#endif
#endif
}

#if	BSD

bktoshell()		/* suspend MicroEMACS and wait to wake up */
{
#if     NeWS
	mlwrite("Not availible under NeWS");
	return(FALSE);
#else
	int pid;

	vttidy();
	pid = getpid();
	kill(pid,SIGTSTP);
#endif
}

rtfrmshell()
{
#if     NeWS
	mlwrite("Not availible under NeWS");
	return(FALSE);
#else
	TTopen();
	curwp->w_flag = WFHARD;
	sgarbf = TRUE;
#endif
}
#endif

/*
 * Run a one-liner in a subjob. When the command returns, wait for a single
 * character to be typed, then mark the screen as garbage so a full repaint is
 * done. Bound to "C-X !".
 */
spawn(f, n)
{
        register int    s;
        char            line[NLINE];
	register char	*cp;
	char		line2[NLINE];

#if	ST520 & MEGAMAX
	int i,j,k;
	char *sptr,*tptr;
#endif

#if     AMIGA
        long newcli;
#endif

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

#if	AMIGA
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return (s);
        newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
        Execute(line, 0L, newcli);
        Close(newcli);
        tgetc();     /* Pause.               */
        sgarbf = TRUE;
        return(TRUE);
#endif
#if     ST520 & MEGAMAX
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return(s);
	movecursor(term.t_nrow - 1, 0);
	TTclose();
/*
 * break the line into the command and its args
 * be cute about it, if there is no '.' in the filename, try
 * to find .prg, .tos or .ttp in that order
 * in any case check to see that the file exists before we run 
 * amok
 */
	STenv = NULL;
	if((tptr = index(&line[0],' ')) == NULL) { /* no args */
		STcmd = (char *)malloc(strlen(line) + 1);
		strcpy(STcmd,line);
		STargs = NULL;
	}
	else {  /* seperate out the args from the command */
		/* resist the temptation to do ptr arithmetic */
		STcmd = (char *)malloc(strlen(line) + 1);
		for(i = 0,sptr = &line[0]; sptr != tptr; sptr++,i++)
			STcmd[i] = *sptr;
		STcmd[i] = '\0';
		for(; *tptr == ' ' || *tptr == '\t'; tptr++);
		if(*tptr == '\0')
			STargs = NULL;
		else {
			STargs = (char *)malloc(strlen(tptr) + 2);
/* first byte of STargs is the length of the string */
			STargs[0] = strlen(tptr);
			STargs[1] = NULL; /* fake it for strcat */
			strcat(STargs,tptr);
		}
	}
/*
 * before we issue the command look for the '.', if it's not there
 * try adding .prg, .tos and .ttp to see if they exist, if not
 * issue the command as is
 */
	if((tptr = index(STcmd,'.')) == NULL) {
 		STwork = (char *)malloc(strlen(STcmd) + 4);
 		strcpy(STwork,STcmd);
 		strcat(STwork,".prg");
 		tptr = index(STwork,'.');
 		if(Fsfirst(1,STwork) != 0) { /* try .tos */
 			strcpy(tptr,".tos");
 			if(Fsfirst(1,STwork) != 0) { /* try .ttp */
 				strcpy(tptr,".ttp");
 				if(Fsfirst(1,STwork) != 0) /* never mind */
 					*STwork = NULL;
 				}
 			}
 	}
 	if(*STwork != NULL)
	        Pexec(LOAD_EXEC,STwork,STargs,STenv); 		
	else
	        Pexec(LOAD_EXEC,STcmd,STargs,STenv);
	TTopen();
        mlputs("\r\n\n[End]");                  /* Pause.               */
        TTgetc();			     /* Pause.               */
        sgarbf = TRUE;
        return (TRUE);
#endif
#if     VMS
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return (s);
        TTputc('\n');                /* Already have '\r'    */
        TTflush();
        s = sys(line);                          /* Run the command.     */
        mlputs("\r\n\n[End]");                  /* Pause.               */
        TTflush();
        tgetc();
        sgarbf = TRUE;
        return (s);
#endif
#if     CPM
        mlwrite("Not in CP/M-86");
        return (FALSE);
#endif
#if     MSDOS | (ST520 & LATTICE)
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return(s);
	movecursor(term.t_nrow - 1, 0);
	TTkclose();
        system(line);
	TTkopen();
	/* if we are interactive, pause here */
	if (clexec == FALSE) {
	        mlputs("\r\n\n[End]");
        	tgetc();
        }
        sgarbf = TRUE;
        return (TRUE);
#endif
#if     (V7 | USG | BSD)
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return (s);
#if	! NeWS
        TTputc('\n');                /* Already have '\r'    */
        TTflush();
        TTclose();                              /* stty to old modes    */
#endif
        if ((cp = getenv("SHELL")) == NULL || *cp == '\0')
#if	BSD
                cp = "/bin/csh";
#else
                cp = "/bin/sh";
#endif
	sprintf(line2, "%s -c \"%s\"", cp, line);
	system(line2);
#if	! NeWS
        TTopen();
        mlputs("[End]");                        /* Pause.               */
        TTflush();

        while ((s = tgetc()) != '\r' && s != ' ')
                ;
        sgarbf = TRUE;
#endif
        return (TRUE);
#endif
}

/*
 * Pipe a one line command into a window
 * Bound to ^X @
 */
pipecmd(f, n)
{
        register int    s;	/* return status from CLI */
	register WINDOW *wp;	/* pointer to new window */
	register BUFFER *bp;	/* pointer to buffer to zot */
        char	line[NLINE];	/* command line send to shell */
	static char bname[] = "command";

#if	AMIGA
	static char filnam[] = "ram:command";
        long newcli;
#else
	static char filnam[NSTRING] = "command";
#endif

#if	MSDOS
	char *tmp;
	char *getenv();
	FILE *fp;
	FILE *fopen();
#endif

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

#if	MSDOS
	if ((tmp = getenv("TMP")) == NULL)
		strcpy(filnam, "command");
	else {
		strcpy(filnam, tmp);
                strcat(filnam,"\\command");
        }
#endif

#if     VMS
	mlwrite("Not availible under VMS");
	return(FALSE);
#endif
#if     CPM
        mlwrite("Not availible under CP/M-86");
        return(FALSE);
#endif

	/* get the command to pipe in */
        if ((s=mlreply("@", line, NLINE)) != TRUE)
                return(s);

	/* get rid of the command output buffer if it exists */
        if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
		/* try to make sure we are off screen */
		wp = wheadp;
		while (wp != NULL) {
			if (wp->w_bufp == bp) {
				onlywind(FALSE, 1);
				break;
			}
			wp = wp->w_wndp;
		}
		if (zotbuf(bp) != TRUE)

			return(FALSE);
	}

#if     AMIGA
        newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
	strcat(line, " >");
	strcat(line, filnam);
        Execute(line, 0L, newcli);
	s = TRUE;
        Close(newcli);
        sgarbf = TRUE;
#endif
#if     MSDOS
	strcat(line," >>");
	strcat(line,filnam);
	movecursor(term.t_nrow - 1, 0);
	TTkclose();
        system(line);
	TTkopen();
        sgarbf = TRUE;
	if ((fp = fopen(filnam, "r")) == NULL) {
		s = FALSE;
	} else {
		fclose(fp);
		s = TRUE;
	}
#endif
#if     V7 | USG | BSD
#if	! NeWS
fprintf(stderr, "closing\n") ;
        TTputc('\n');                /* Already have '\r'    */
        TTflush();
        TTclose();                              /* stty to old modes    */
#endif
	strcat(line,">");
	strcat(line,filnam);
        system(line);
#if	! NeWS
        TTopen();
        TTflush();
        sgarbf = TRUE;
#endif
        s = TRUE;
#endif

	if (s != TRUE)
		return(s);

	/* split the current window to make room for the command output */
	if (splitwind(FALSE, 1) == FALSE)
			return(FALSE);

	/* and read the stuff in */
	if (getfile(filnam, FALSE) == FALSE)
		return(FALSE);

	/* make this window in VIEW mode, update all mode lines */
	curwp->w_bufp->b_mode |= MDVIEW;
	wp = wheadp;
	while (wp != NULL) {
		wp->w_flag |= WFMODE;
		wp = wp->w_wndp;
	}

	/* and get rid of the temporary file */
	unlink(filnam);
	return(TRUE);
}

/*
 * filter a buffer through an external DOS program
 * Bound to ^X #
 */
filter(f, n)

{
        register int    s;	/* return status from CLI */
	register BUFFER *bp;	/* pointer to buffer to zot */
        char line[NLINE];	/* command line send to shell */
	char tmpnam[NFILEN];	/* place to store real file name */
	static char bname1[] = "fltinp";

#if	AMIGA
	static char filnam1[] = "ram:fltinp";
	static char filnam2[] = "ram:fltout";
        long newcli;
#else
	static char filnam1[] = "fltinp";
	static char filnam2[] = "fltout";
#endif

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
		return(rdonly());	/* we are in read only mode	*/

#if     VMS
	mlwrite("Not availible under VMS");
	return(FALSE);
#endif
#if     CPM
        mlwrite("Not availible under CP/M-86");
        return(FALSE);
#endif

	/* get the filter name and its args */
        if ((s=mlreply("#", line, NLINE)) != TRUE)
                return(s);

	/* setup the proper file names */
	bp = curbp;
	strcpy(tmpnam, bp->b_fname);	/* save the original name */
	strcpy(bp->b_fname, bname1);	/* set it to our new one */

	/* write it out, checking for errors */
	if (writeout(filnam1) != TRUE) {
		mlwrite("[Cannot write filter file]");
		strcpy(bp->b_fname, tmpnam);
		return(FALSE);
	}

#if     AMIGA
        newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
	strcat(line, " <ram:fltinp >ram:fltout");
        Execute(line,0L,newcli);
	s = TRUE;
        Close(newcli);
        sgarbf = TRUE;
#endif
#if     MSDOS
	strcat(line," <fltinp >fltout");
	movecursor(term.t_nrow - 1, 0);
	TTkclose();
        system(line);
	TTkopen();
        sgarbf = TRUE;
	s = TRUE;
#endif
#if     V7 | USG | BSD
#if	! NeWS
        TTputc('\n');                /* Already have '\r'    */
        TTflush();
        TTclose();                              /* stty to old modes    */
#endif
	strcat(line," <fltinp >fltout");
        system(line);
#if	! NeWS
        TTopen();
        TTflush();
        sgarbf = TRUE;
#endif
       s = TRUE;
#endif

	/* on failure, escape gracefully */
	if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
		mlwrite("[Execution failed]");
		strcpy(bp->b_fname, tmpnam);
		unlink(filnam1);
		unlink(filnam2);
		return(s);
	}

	/* reset file name */
	strcpy(bp->b_fname, tmpnam);	/* restore name */
	bp->b_flag |= BFCHG;		/* flag it as changed */

	/* and get rid of the temporary file */
	unlink(filnam1);
	unlink(filnam2);
	return(TRUE);
}

#if     VMS
/*
 * Run a command. The "cmd" is a pointer to a command string, or NULL if you
 * want to run a copy of DCL in the subjob (this is how the standard routine
 * LIB$SPAWN works. You have to do wierd stuff with the terminal on the way in
 * and the way out, because DCL does not want the channel to be in raw mode.
 */
sys(cmd)
register char   *cmd;
{
        struct  dsc$descriptor  cdsc;
        struct  dsc$descriptor  *cdscp;
        long    status;
        long    substatus;
        long    iosb[2];

        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
                          oldmode, sizeof(oldmode), 0, 0, 0, 0);
        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
                return (FALSE);
        cdscp = NULL;                           /* Assume DCL.          */
        if (cmd != NULL) {                      /* Build descriptor.    */
                cdsc.dsc$a_pointer = cmd;
                cdsc.dsc$w_length  = strlen(cmd);
                cdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
                cdsc.dsc$b_class   = DSC$K_CLASS_S;
                cdscp = &cdsc;
        }
        status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0);
        if (status != SS$_NORMAL)
                substatus = status;
        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
                          newmode, sizeof(newmode), 0, 0, 0, 0);
        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
                return (FALSE);
        if ((substatus&STS$M_SUCCESS) == 0)     /* Command failed.      */
                return (FALSE);
        return (TRUE);
}
#endif

#if	~AZTEC & ~MSC & ~TURBO & MSDOS

/*
 * This routine, once again by Bob McNamara, is a C translation of the "system"
 * routine in the MWC-86 run time library. It differs from the "system" routine
 * in that it does not unconditionally append the string ".exe" to the end of
 * the command name. We needed to do this because we want to be able to spawn
 * off "command.com". We really do not understand what it does, but if you don't
 * do it exactly "malloc" starts doing very very strange things.
 */
sys(cmd, tail)
char    *cmd;
char    *tail;
{
#if MWC86
        register unsigned n;
        extern   char     *__end;

        n = __end + 15;
        n >>= 4;
        n = ((n + dsreg() + 16) & 0xFFF0) + 16;
        return(execall(cmd, tail, n));
#endif

#if LATTICE
        return(forklp(cmd, tail, (char *)NULL));
#endif
}
#endif

#if	MSDOS & LATTICE
/*	System: a modified version of lattice's system() function
		that detects the proper switchar and uses it
		written by Dana Hogget				*/

system(cmd)

char *cmd;	/*  Incoming command line to execute  */

{
	char *getenv();
	static char *swchar = "/C";	/*  Execution switch  */
	union REGS inregs;	/*  parameters for dos call  */
	union REGS outregs;	/*  Return results from dos call  */
	char *shell;		/*  Name of system command processor  */
	char *p;		/*  Temporary pointer  */
	int ferr;		/*  Error condition if any  */

	/*  get name of system shell  */
	if ((shell = getenv("COMSPEC")) == NULL) {
		return (-1);		/*  No shell located  */
	}

	p = cmd;
	while (isspace(*p)) {		/*  find out if null command */
		p++;
	}

	/**  If the command line is not empty, bring up the shell  **/
	/**  and execute the command.  Otherwise, bring up the     **/
	/**  shell in interactive mode.   **/

	if (p && *p) {
		/**  detect current switch character and us it  **/
		inregs.h.ah = 0x37;	/*  get setting data  */
		inregs.h.al = 0x00;	/*  get switch character  */
		intdos(&inregs, &outregs);
		*swchar = outregs.h.dl;
		ferr = forkl(shell, "command", swchar, cmd, (char *)NULL);
	} else {
		ferr = forkl(shell, "command", (char *)NULL);
	}

	return (ferr ? ferr : wait());
}
#endif
@//E*O*F spawn.c//
chmod u=rw,g=r,o=r spawn.c
 
echo x - spawn.c,v
sed 's/^@//' > "spawn.c,v" <<'@//E*O*F spawn.c,v//'
head     1.2;
access   ;
symbols  ;
locks    root:1.2; strict;
comment  @ * @;


1.2
date     87.10.22.12.33.48;  author root;  state Exp;
branches ;
next     1.1;

1.1
date     87.10.22.12.14.51;  author root;  state Exp;
branches ;
next     ;


desc
@@@


1.2
log
@@Change spawn to use shell specified in SHELL variable, or /bin/csh if BSD
@@
text
@@/*	Spawn:	various DOS access commands
		for MicroEMACS
*/

#include        <stdio.h>
#include	"estruct.h"
#include        "edef.h"

#if     AMIGA
#define  NEW   1006L
#endif

#if		ST520 & MEGAMAX
#include <osbind.h>
#include <string.h>
#define LOAD_EXEC 0 	/* load and execute the program */
char	*STcmd,		/* the command filename & path  */
	*STargs,	/* command args (if any)        */
	*STenv,		/* environment                  */
	*STwork;	/* work area			*/
#endif

#if     VMS
#define EFN     0                               /* Event flag.          */

#include        <ssdef.h>                       /* Random headers.      */
#include        <stsdef.h>
#include        <descrip.h>
#include        <iodef.h>

extern  int     oldmode[3];                     /* In "termio.c"        */
extern  int     newmode[3];                     /* In "termio.c"        */
extern  short   iochan;                         /* In "termio.c"        */
#endif

#if     V7 | USG | BSD
#include        <signal.h>
extern int vttidy();
#endif

#if	MSDOS & (MSC | TURBO)
#include	<process.h>
#endif

/*
 * Create a subjob with a copy of the command intrepreter in it. When the
 * command interpreter exits, mark the screen as garbage so that you do a full
 * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
 * Under some (unknown) condition, you don't get one free when DCL starts up.
 */
spawncli(f, n)
{
#if     AMIGA
        long newcli;

#endif

#if     V7 | USG | BSD
        register char *cp;
        char    *getenv();
#endif

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

#if	AMIGA
        mlwrite("[Starting new CLI]");
        sgarbf = TRUE;
        Execute("NEWCLI \"CON:0/0/640/200/MicroEMACS Subprocess\"", 0L, 0L);
        return(TRUE);
#endif

#if     VMS
        movecursor(term.t_nrow, 0);             /* In last line.        */
        mlputs("[Starting DCL]\r\n");
        TTflush(); 	                     /* Ignore "ttcol".      */
        sgarbf = TRUE;
        return (sys(NULL));                     /* NULL => DCL.         */
#endif
#if     CPM
        mlwrite("Not in CP/M-86");
#endif
#if	ST520
	mlwrite("Not in TOS");
#endif
#if     MSDOS & (AZTEC | MSC | TURBO)
        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
        TTflush();
	TTkclose();
	system("command.com");
	TTkopen();
        sgarbf = TRUE;
        return(TRUE);
#endif
#if     MSDOS & LATTICE
        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
        TTflush();
	TTkclose();
        sys("\\command.com", "");               /* Run CLI.             */
	TTkopen();
        sgarbf = TRUE;
        return(TRUE);
#endif
#if     V7 | USG | BSD
        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
        TTflush();
        TTclose();                              /* stty to old settings */
        if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
                system(cp);
        else
#if	BSD
                system("exec /bin/csh");
#else
                system("exec /bin/sh");
#endif
        sgarbf = TRUE;
        sleep(2);
        TTopen();
        return(TRUE);
#endif
}

#if	BSD

bktoshell()		/* suspend MicroEMACS and wait to wake up */
{
	int pid;

	vttidy();
	pid = getpid();
	kill(pid,SIGTSTP);
}

rtfrmshell()
{
	TTopen();
	curwp->w_flag = WFHARD;
	sgarbf = TRUE;
}
#endif

/*
 * Run a one-liner in a subjob. When the command returns, wait for a single
 * character to be typed, then mark the screen as garbage so a full repaint is
 * done. Bound to "C-X !".
 */
spawn(f, n)
{
        register int    s;
        char            line[NLINE];
	register char	*cp;
	char		line2[NLINE];

#if	ST520 & MEGAMAX
	int i,j,k;
	char *sptr,*tptr;
#endif

#if     AMIGA
        long newcli;
#endif

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

#if	AMIGA
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return (s);
        newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
        Execute(line, 0L, newcli);
        Close(newcli);
        tgetc();     /* Pause.               */
        sgarbf = TRUE;
        return(TRUE);
#endif
#if     ST520 & MEGAMAX
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return(s);
	movecursor(term.t_nrow - 1, 0);
	TTclose();
/*
 * break the line into the command and its args
 * be cute about it, if there is no '.' in the filename, try
 * to find .prg, .tos or .ttp in that order
 * in any case check to see that the file exists before we run 
 * amok
 */
	STenv = NULL;
	if((tptr = index(&line[0],' ')) == NULL) { /* no args */
		STcmd = (char *)malloc(strlen(line) + 1);
		strcpy(STcmd,line);
		STargs = NULL;
	}
	else {  /* seperate out the args from the command */
		/* resist the temptation to do ptr arithmetic */
		STcmd = (char *)malloc(strlen(line) + 1);
		for(i = 0,sptr = &line[0]; sptr != tptr; sptr++,i++)
			STcmd[i] = *sptr;
		STcmd[i] = '\0';
		for(; *tptr == ' ' || *tptr == '\t'; tptr++);
		if(*tptr == '\0')
			STargs = NULL;
		else {
			STargs = (char *)malloc(strlen(tptr) + 2);
/* first byte of STargs is the length of the string */
			STargs[0] = strlen(tptr);
			STargs[1] = NULL; /* fake it for strcat */
			strcat(STargs,tptr);
		}
	}
/*
 * before we issue the command look for the '.', if it's not there
 * try adding .prg, .tos and .ttp to see if they exist, if not
 * issue the command as is
 */
	if((tptr = index(STcmd,'.')) == NULL) {
 		STwork = (char *)malloc(strlen(STcmd) + 4);
 		strcpy(STwork,STcmd);
 		strcat(STwork,".prg");
 		tptr = index(STwork,'.');
 		if(Fsfirst(1,STwork) != 0) { /* try .tos */
 			strcpy(tptr,".tos");
 			if(Fsfirst(1,STwork) != 0) { /* try .ttp */
 				strcpy(tptr,".ttp");
 				if(Fsfirst(1,STwork) != 0) /* never mind */
 					*STwork = NULL;
 				}
 			}
 	}
 	if(*STwork != NULL)
	        Pexec(LOAD_EXEC,STwork,STargs,STenv); 		
	else
	        Pexec(LOAD_EXEC,STcmd,STargs,STenv);
	TTopen();
        mlputs("\r\n\n[End]");                  /* Pause.               */
        TTgetc();			     /* Pause.               */
        sgarbf = TRUE;
        return (TRUE);
#endif
#if     VMS
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return (s);
        TTputc('\n');                /* Already have '\r'    */
        TTflush();
        s = sys(line);                          /* Run the command.     */
        mlputs("\r\n\n[End]");                  /* Pause.               */
        TTflush();
        tgetc();
        sgarbf = TRUE;
        return (s);
#endif
#if     CPM
        mlwrite("Not in CP/M-86");
        return (FALSE);
#endif
#if     MSDOS | (ST520 & LATTICE)
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return(s);
	movecursor(term.t_nrow - 1, 0);
	TTkclose();
        system(line);
	TTkopen();
	/* if we are interactive, pause here */
	if (clexec == FALSE) {
	        mlputs("\r\n\n[End]");
        	tgetc();
        }
        sgarbf = TRUE;
        return (TRUE);
#endif
#if     V7 | USG | BSD
        if ((s=mlreply("!", line, NLINE)) != TRUE)
                return (s);
        TTputc('\n');                /* Already have '\r'    */
        TTflush();
        TTclose();                              /* stty to old modes    */
        if ((cp = getenv("SHELL")) == NULL || *cp == '\0')
#if	BSD
                cp = "/bin/csh";
#else
                cp = "/bin/sh";
#endif
	sprintf(line2, "%s -c %s", cp, line);
	system(line2);
        TTopen();
        mlputs("[End]");                        /* Pause.               */
        TTflush();
        while ((s = tgetc()) != '\r' && s != ' ')
                ;
        sgarbf = TRUE;
        return (TRUE);
#endif
}

/*
 * Pipe a one line command into a window
 * Bound to ^X @@
 */
pipecmd(f, n)
{
        register int    s;	/* return status from CLI */
	register WINDOW *wp;	/* pointer to new window */
	register BUFFER *bp;	/* pointer to buffer to zot */
        char	line[NLINE];	/* command line send to shell */
	static char bname[] = "command";

#if	AMIGA
	static char filnam[] = "ram:command";
        long newcli;
#else
	static char filnam[NSTRING] = "command";
#endif

#if	MSDOS
	char *tmp;
	char *getenv();
	FILE *fp;
	FILE *fopen();
#endif

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

#if	MSDOS
	if ((tmp = getenv("TMP")) == NULL)
		strcpy(filnam, "command");
	else {
		strcpy(filnam, tmp);
                strcat(filnam,"\\command");
        }
#endif

#if     VMS
	mlwrite("Not availible under VMS");
	return(FALSE);
#endif
#if     CPM
        mlwrite("Not availible under CP/M-86");
        return(FALSE);
#endif

	/* get the command to pipe in */
        if ((s=mlreply("@@", line, NLINE)) != TRUE)
                return(s);

	/* get rid of the command output buffer if it exists */
        if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
		/* try to make sure we are off screen */
		wp = wheadp;
		while (wp != NULL) {
			if (wp->w_bufp == bp) {
				onlywind(FALSE, 1);
				break;
			}
			wp = wp->w_wndp;
		}
		if (zotbuf(bp) != TRUE)

			return(FALSE);
	}

#if     AMIGA
        newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
	strcat(line, " >");
	strcat(line, filnam);
        Execute(line, 0L, newcli);
	s = TRUE;
        Close(newcli);
        sgarbf = TRUE;
#endif
#if     MSDOS
	strcat(line," >>");
	strcat(line,filnam);
	movecursor(term.t_nrow - 1, 0);
	TTkclose();
        system(line);
	TTkopen();
        sgarbf = TRUE;
	if ((fp = fopen(filnam, "r")) == NULL) {
		s = FALSE;
	} else {
		fclose(fp);
		s = TRUE;
	}
#endif
#if     V7 | USG | BSD
        TTputc('\n');                /* Already have '\r'    */
        TTflush();
        TTclose();                              /* stty to old modes    */
	strcat(line,">");
	strcat(line,filnam);
        system(line);
        TTopen();
        TTflush();
        sgarbf = TRUE;
        s = TRUE;
#endif

	if (s != TRUE)
		return(s);

	/* split the current window to make room for the command output */
	if (splitwind(FALSE, 1) == FALSE)
			return(FALSE);

	/* and read the stuff in */
	if (getfile(filnam, FALSE) == FALSE)
		return(FALSE);

	/* make this window in VIEW mode, update all mode lines */
	curwp->w_bufp->b_mode |= MDVIEW;
	wp = wheadp;
	while (wp != NULL) {
		wp->w_flag |= WFMODE;
		wp = wp->w_wndp;
	}

	/* and get rid of the temporary file */
	unlink(filnam);
	return(TRUE);
}

/*
 * filter a buffer through an external DOS program
 * Bound to ^X #
 */
filter(f, n)

{
        register int    s;	/* return status from CLI */
	register BUFFER *bp;	/* pointer to buffer to zot */
        char line[NLINE];	/* command line send to shell */
	char tmpnam[NFILEN];	/* place to store real file name */
	static char bname1[] = "fltinp";

#if	AMIGA
	static char filnam1[] = "ram:fltinp";
	static char filnam2[] = "ram:fltout";
        long newcli;
#else
	static char filnam1[] = "fltinp";
	static char filnam2[] = "fltout";
#endif

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
		return(rdonly());	/* we are in read only mode	*/

#if     VMS
	mlwrite("Not availible under VMS");
	return(FALSE);
#endif
#if     CPM
        mlwrite("Not availible under CP/M-86");
        return(FALSE);
#endif

	/* get the filter name and its args */
        if ((s=mlreply("#", line, NLINE)) != TRUE)
                return(s);

	/* setup the proper file names */
	bp = curbp;
	strcpy(tmpnam, bp->b_fname);	/* save the original name */
	strcpy(bp->b_fname, bname1);	/* set it to our new one */

	/* write it out, checking for errors */
	if (writeout(filnam1) != TRUE) {
		mlwrite("[Cannot write filter file]");
		strcpy(bp->b_fname, tmpnam);
		return(FALSE);
	}

#if     AMIGA
        newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
	strcat(line, " <ram:fltinp >ram:fltout");
        Execute(line,0L,newcli);
	s = TRUE;
        Close(newcli);
        sgarbf = TRUE;
#endif
#if     MSDOS
	strcat(line," <fltinp >fltout");
	movecursor(term.t_nrow - 1, 0);
	TTkclose();
        system(line);
	TTkopen();
        sgarbf = TRUE;
	s = TRUE;
#endif
#if     V7 | USG | BSD
        TTputc('\n');                /* Already have '\r'    */
        TTflush();
        TTclose();                              /* stty to old modes    */
	strcat(line," <fltinp >fltout");
        system(line);
        TTopen();
        TTflush();
        sgarbf = TRUE;
        s = TRUE;
#endif

	/* on failure, escape gracefully */
	if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
		mlwrite("[Execution failed]");
		strcpy(bp->b_fname, tmpnam);
		unlink(filnam1);
		unlink(filnam2);
		return(s);
	}

	/* reset file name */
	strcpy(bp->b_fname, tmpnam);	/* restore name */
	bp->b_flag |= BFCHG;		/* flag it as changed */

	/* and get rid of the temporary file */
	unlink(filnam1);
	unlink(filnam2);
	return(TRUE);
}

#if     VMS
/*
 * Run a command. The "cmd" is a pointer to a command string, or NULL if you
 * want to run a copy of DCL in the subjob (this is how the standard routine
 * LIB$SPAWN works. You have to do wierd stuff with the terminal on the way in
 * and the way out, because DCL does not want the channel to be in raw mode.
 */
sys(cmd)
register char   *cmd;
{
        struct  dsc$descriptor  cdsc;
        struct  dsc$descriptor  *cdscp;
        long    status;
        long    substatus;
        long    iosb[2];

        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
                          oldmode, sizeof(oldmode), 0, 0, 0, 0);
        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
                return (FALSE);
        cdscp = NULL;                           /* Assume DCL.          */
        if (cmd != NULL) {                      /* Build descriptor.    */
                cdsc.dsc$a_pointer = cmd;
                cdsc.dsc$w_length  = strlen(cmd);
                cdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
                cdsc.dsc$b_class   = DSC$K_CLASS_S;
                cdscp = &cdsc;
        }
        status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0);
        if (status != SS$_NORMAL)
                substatus = status;
        status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
                          newmode, sizeof(newmode), 0, 0, 0, 0);
        if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
                return (FALSE);
        if ((substatus&STS$M_SUCCESS) == 0)     /* Command failed.      */
                return (FALSE);
        return (TRUE);
}
#endif

#if	~AZTEC & ~MSC & ~TURBO & MSDOS

/*
 * This routine, once again by Bob McNamara, is a C translation of the "system"
 * routine in the MWC-86 run time library. It differs from the "system" routine
 * in that it does not unconditionally append the string ".exe" to the end of
 * the command name. We needed to do this because we want to be able to spawn
 * off "command.com". We really do not understand what it does, but if you don't
 * do it exactly "malloc" starts doing very very strange things.
 */
sys(cmd, tail)
char    *cmd;
char    *tail;
{
#if MWC86
        register unsigned n;
        extern   char     *__end;

        n = __end + 15;
        n >>= 4;
        n = ((n + dsreg() + 16) & 0xFFF0) + 16;
        return(execall(cmd, tail, n));
#endif

#if LATTICE
        return(forklp(cmd, tail, (char *)NULL));
#endif
}
#endif

#if	MSDOS & LATTICE
/*	System: a modified version of lattice's system() function
		that detects the proper switchar and uses it
		written by Dana Hogget				*/

system(cmd)

char *cmd;	/*  Incoming command line to execute  */

{
	char *getenv();
	static char *swchar = "/C";	/*  Execution switch  */
	union REGS inregs;	/*  parameters for dos call  */
	union REGS outregs;	/*  Return results from dos call  */
	char *shell;		/*  Name of system command processor  */
	char *p;		/*  Temporary pointer  */
	int ferr;		/*  Error condition if any  */

	/*  get name of system shell  */
	if ((shell = getenv("COMSPEC")) == NULL) {
		return (-1);		/*  No shell located  */
	}

	p = cmd;
	while (isspace(*p)) {		/*  find out if null command */
		p++;
	}

	/**  If the command line is not empty, bring up the shell  **/
	/**  and execute the command.  Otherwise, bring up the     **/
	/**  shell in interactive mode.   **/

	if (p && *p) {
		/**  detect current switch character and us it  **/
		inregs.h.ah = 0x37;	/*  get setting data  */
		inregs.h.al = 0x00;	/*  get switch character  */
		intdos(&inregs, &outregs);
		*swchar = outregs.h.dl;
		ferr = forkl(shell, "command", swchar, cmd, (char *)NULL);
	} else {
		ferr = forkl(shell, "command", (char *)NULL);
	}

	return (ferr ? ferr : wait());
}
#endif
@@


1.1
log
@@Initial revision
@@
text
@@d152 2
d279 8
a286 1
        system(line);
@@
@//E*O*F spawn.c,v//
chmod u=rw,g=r,o=r spawn.c,v
 
echo x - st520.c
sed 's/^@//' > "st520.c" <<'@//E*O*F st520.c//'
/*

The routines in this file provide support for the Atari 520 or 1040ST
using VT52 emulation.  The I/O services are provided here as well.  It
compiles into nothing if not a 520ST style device.

*/

#define	termdef	1			/* don't define "term" external */

#include        <stdio.h>
#include        "estruct.h"
#include	"edef.h"

#if     ATARI & ST520 & MEGAMAX
#include	<osbind.h>
#include	<ctype.h>

#define LINEA_INIT 0xA000
#define V_CEL_WR   -0x28

#define V_CEL_MY   -0x2a
#define V_CEL_HT   -0x2e
#define V_FNT_AD   -0x16
#define V_OFF_AD   -0x0a
#define V_DISAB    -346

#define NROW    25                      /* Screen size.                 */
#define NCOL    80                      /* Edit if you want to.         */
#define	MARGIN	8			/* size of minimim margin and	*/
#define	SCRSIZ	64			/* scroll size for extended lines */
#define	NPAUSE	25			/* # times thru update to pause */
#define BIAS    0x20                    /* Origin 0 coordinate bias.    */
#define ESC     0x1B                    /* ESC character.               */
#define BEL     0x07                    /* ascii bell character         */

extern  int     ttopen();               /* Forward references.          */
extern  int     ttgetc();
extern  int     ttputc();
extern  int     ttflush();
extern  int     ttclose();
extern  int     st520move();
extern  int     st520eeol();
extern  int     st520eeop();
extern  int     st520beep();
extern  int     st520open();
extern	int	st520close();
extern	int	st520rev();
extern  int st520kopen();
extern  int st520kclose();
extern	int st520chgrez();

#if	COLOR
extern	int	st520fcol();
extern	int	st520bcol();

int		cfcolor = -1;		/* current fg (character) color */
int		cbcolor = -1;		/* current bg color */
int		oldpal[8];		/* pallette when emacs was invoked */
int		newpal[8] = {		/* default emacs pallette */
	0x000, 0x700, 0x070, 0x770, 0x007, 0x707, 0x077, 0x777};
#endif

int STncolors = 0;		/* number of colors  */
int STrez;			/* physical screen resolution */	

/*
 * Dispatch table. All the
 * hard fields just point into the
 * terminal I/O code.
 */
TERM    term    = {
        NROW-1,
        NCOL,
	MARGIN,
	MARGIN,
	SCRSIZ,
	NPAUSE,
        &st520open,
        &st520close,
	&st520kopen,
	&st520kclose,
        &ttgetc,
        &ttputc,
        &ttflush,
        &st520move,
        &st520eeol,
        &st520eeop,
        &st520beep,
        &st520rev
#if	MULTREZ
	, &st520chgrez
#endif
#if	COLOR
	, &st520fcol,
	&st520bcol
#endif
};
	struct KBDvecs {
		int (*midivec) ();
		int (*vkbderr) ();
		int (*vmiderr) ();
		int (*statvec) ();
		int (*mousevec) ();
		int (*clockvec) ();
		int (*joyvec) ();
		int (*midisys) ();
		int (*ikbdsys) ();
	};
	struct Param {
		char topmode;
		char buttons;
		char xparam;
		char yparam;
		int xmax,ymax;
		int xinitial,yinitial;
	};
	struct KBDvecs *kbdvecs;
	struct Param *paramp;
	char kbdcmds[25];

st520move(row, col)
{
        ttputc(ESC);
        ttputc('Y');
        ttputc(row+BIAS);
        ttputc(col+BIAS);
}

st520eeol()
{
        ttputc(ESC);
        ttputc('K');
}

st520eeop()
{

#if	COLOR
		st520fcol(gfcolor);
		st520bcol(gbcolor);
#endif
        ttputc(ESC);
        ttputc('J');
}

st520rev(status)	/* set the reverse video state */

int status;	/* TRUE = reverse video, FALSE = normal video */

{

	if(status) {
		ttputc(ESC);
		ttputc('p');
	}
	else {
		ttputc(ESC);
		ttputc('q');
	}
}

#if	COLOR
st520fcol(color)
int color;	
{
		if(color == cfcolor || !STncolors)
			return;
		else {

			ttputc(ESC);
			ttputc('b');
			ttputc(color & 0x0f);
			cfcolor = color;
		}
}

st520bcol(color)
int color;
{
		if(color == cbcolor || !STncolors)
			return;
		else {
			ttputc(ESC);
			ttputc('c');
			ttputc(color & 0x0f);
			cbcolor = color;
		}

}
#endif

st520beep()
{
#ifdef	BEL
        ttputc(BEL);
        ttflush();
#endif
}

st520open()
{
	int i,j,k;
	long phys, log;	/* screen bases */
	
/* IMPORTANT: it is ABSOLUTELY necessary that the default resolution be the
 *	largest possible so that display will allocate (malloc) the maximum
 *	size for the VIDEO arrray
 */
	STrez = Getrez();
	switch(STrez) {
		case 0: /* low res 25x40 16 colors */
			phys = Physbase();
			log  = Logbase();
			Setscreen(log, phys, 1);
			STrez = 1;
			/* fall thru to med res */

		case 1: /* med res 25x80 4 colors */
			term.t_nrow = 25 - 1;
			term.t_ncol  = 80;
			grez = 1;
#if	COLOR
			STncolors = 4;
			for(i=0;i<8;i++) {
				oldpal[i] = Setcolor(i,newpal[i]);
			}
#endif
			break;
		case 2: /* high res 25x80 no colors */
			term.t_nrow  = 40 - 1;
			term.t_ncol  = 80;
			grez = 2;
			make_8x10(); /* create a smaller font */
			set_40();    /* and go to 40 line mode */
#if	COLOR
			STncolors = 0;
#endif
			break;
	}

	revexist = TRUE;
	eolexist = TRUE;
	paramp = (struct Param *)malloc(sizeof(struct Param));
	kbdvecs = (struct KBDvecs *)Kbdvbase();
	paramp -> topmode = 0;
	paramp -> buttons = 4;
	paramp -> xparam = 8;
	paramp -> yparam = 10;
	paramp -> xmax = 79;
	paramp -> ymax = 23;
	paramp -> xinitial = 0;
	paramp -> yinitial = 0;
	Initmous(1,paramp,kbdvecs -> mousevec);

	i = 0;
	kbdcmds[i++] = 0x0a;	/*set mouse keycode mode */
	kbdcmds[i++] = 0x08;
	kbdcmds[i++] = 0x0a;
	Ikbdws(i-1,&kbdcmds[0]);
	Cursconf(1,0);
	Cursconf(3,0);
	Cconout(27);Cconout('E');
        ttopen();
}

st520close()

{
	int i,j,k;

	i = 0;
	kbdcmds[i++] = 0x80;	/*reset mouse keycode mode */
	kbdcmds[i++] = 0x01;
	Ikbdws(i-1,&kbdcmds[0]);
	if(grez == 2 && STrez == 2) /* b/w monitor in 40 row mode */
		restore();

#if		COLOR
	for(i=0;i<STncolors;i++)
		Setcolor(i,oldpal[i]);
#endif
	Cconout(27);Cconout('E');
	paramp -> buttons = 0;
	Initmous(2,paramp,kbdvecs -> mousevec);
	i = 0;
	kbdcmds[i++] = 0x80;	/*reset the keyboard*/
	kbdcmds[i++] = 0x01;
	Ikbdws(i-1,&kbdcmds[0]);
	Cursconf(1,0);
	ttclose();
}
st520kopen()
{

}
st520kclose()
{

}

st520chgrez(nurez)
int nurez;
{
	int ierr, i, j ,k;
	long phys, log;	/* screen bases */
	char dum[80]; /* for debugging only */
		
	if(grez == nurez)
		return(TRUE);
		
	if(STrez == 2) { /* b/w monitor-only allow hi | med rez */
		switch(nurez) {
			case 2: /* high res */
				term.t_nrow  = 40 - 1;
				term.t_ncol  = 80;
				make_8x10(); /* create a smaller font */
				set_40();    /* and go to 40 line mode */
				grez = 2;
				sgarbf = TRUE;
				onlywind(1,1);
				break;
			case 1: /* med res */
				term.t_nrow  = 25 - 1;
				term.t_ncol  = 80;
				restore();
				grez = 1;
				sgarbf = TRUE;
				onlywind(1,1);
				break;
			default:
				mlwrite("Invalid resolution");
				return(FALSE);
				break;
		}
	}
	else { /* color monitor-only allow low | medium resolution */
		phys = Physbase();
		log  = Logbase();
		switch(nurez) {
			case 1:
				term.t_nrow  = 25 - 1;
				term.t_ncol  = 80;
				Setscreen(log, phys, 1);
				STncolors = 4;
				grez = 1;
				sgarbf = TRUE;
				onlywind(1,1);
				break;
			case 0:
				term.t_nrow  = 25 - 1;
				term.t_ncol  = 40;
				Setscreen(log, phys, 0);
				STncolors = 8;
				grez = 0;
				sgarbf = TRUE;
				onlywind(1,1);
				break;
			default:
				mlwrite("%Invalid resolution");
				return(FALSE);
				break;
		}
	}
}			

STcurblink(onoff)
int onoff;
{
	if(onoff)
		Cursconf(2,0);
	else
		Cursconf(3,0);
}


char parm_save[28];
long fnt_8x10[640];

make_8x10()
{
	int i,j,k;
	long savea23[2];
	
	for(i=0;i<640;i++)
		fnt_8x10[i] = 0;
		
	asm {
	movem.l	A2-A3,savea23(A6)
	
	dc.w	LINEA_INIT		;A1 -> array of font headers

	lea	parm_save(A4),A2	;A2 -> parameters savearea
	move.l	V_OFF_AD(A0),(A2)+
	move.l	V_FNT_AD(A0),(A2)+
	move.w	V_CEL_HT(A0),(A2)+
	move.w	V_CEL_MY(A0),(A2)+
	move.w	V_CEL_WR(A0),(A2)+


	move.l	04(A1),A1		; A1 -> 8x8 font header
	move.l	76(A1),A2		; A2 -> 8x8 font data
	lea	fnt_8x10+0x100(A4),A3	; A3 -> 2nd line of font buffer
	move.w	#0x200-1,D0		; D0 <- longword counter for font xfer

fnt_loop:

	move.l	(A2)+,(A3)+
	dbf	D0,fnt_loop
		
	movem.l	savea23(A6),A2-A3
	}
	
}

set_40()
{
	long	savea23[2];
	
	asm {
	
;
;  use the 8x10 character set: 40 line mode
;

	movem.l	A2-A3,savea23(A6)
	
	dc.w	LINEA_INIT

	move.l	04(A1),A1		; A1 -> 8x8 font header
	move.l	72(A1),V_OFF_AD(A0)	; v_off_ad <- 8x8  offset table addr
	lea	fnt_8x10(A4),A2
	move.l	A2,V_FNT_AD(A0)		; v_fnt_ad <- 8x10 font data addr

	move.w	#10,V_CEL_HT(A0)	; v_cel_ht <- 10   8x10 cell height
	move.w	#39,V_CEL_MY(A0)	; v_cel_my <- 39   maximum cell "Y"
	move.w	#800,V_CEL_WR(A0)	; v_cel_wr <- 800  offset to cell Y+1

	movem.l savea23,A2-A3
	}
}

set_20()
{
	long	savea23[2];

	asm {
		
;
;  use the 8x10 character set: 20 line mode
;

	movem.l	A2-A3,savea23(A6)
	
	dc.w	LINEA_INIT		; A0 -> line A variables

	move.l	04(A1),A1		; A1 -> 8x8 font header
	move.l	72(A1),V_OFF_AD(A0)	; v_off_ad <- 8x8  offset table addr
	lea	fnt_8x10(A4),A2
	move.l	A2,V_FNT_AD(A0)		; v_fnt_ad <- 8x10 font data addr

	move.w	#10,V_CEL_HT(A0)	; v_cel_ht <- 10   8x10 cell height
	move.w	#19,V_CEL_MY(A0)	; v_cel_my <- 19   maximum cell "Y"
	move.w	#1600,V_CEL_WR(A0)	; v_cel_wr <- 800  offset to cell Y+1
	
	movem.l	savea23,A2-A3
	}
}


restore()
{
	long savea23[2];
	
	asm {
	
;  return what was saved in parameter save zone	

	movem.l	A2-A3,savea23(A6)

	dc.w	LINEA_INIT		; a0 -> line A variables

	lea	parm_save(A4),A2	; a2 -> parameter save area
	move.l	(A2)+,V_OFF_AD(A0)
	move.l	(A2)+,V_FNT_AD(A0)
	move.w	(A2)+,V_CEL_HT(A0)
	move.w	(A2)+,V_CEL_MY(A0)
	move.w	(A2)+,V_CEL_WR(A0)
	
	movem.l	savea23(A6),A2-A3
	}          
}
GetCurStat(onoff)
int	onoff;
{
	long savea23[2];

	asm {
	movem.l	A2-A3,savea23(A6)

	dc.w	LINEA_INIT		; a0 -> line A variables
	move.w	V_DISAB(A0),onoff(A6)	; 0 = cursor visible
	moveq	#0,D0
	move.w	V_DISAB(A0),D0	
	movem.l	savea23(A6),A2-A3
	}          
}
#else
#if	ATARI & ST520 & LATTICE

/*
	These routines provide support for the ATARI 1040ST using
the LATTICE compiler using the virtual VT52 Emulator

*/

#define NROW    40                      /* Screen size.                 */
#define NCOL    80                      /* Edit if you want to.         */
#define	MARGIN	8			/* size of minimim margin and	*/
#define	SCRSIZ	64			/* scroll size for extended lines */
#define	NPAUSE	300			/* # times thru update to pause */
#define BIAS    0x20                    /* Origin 0 coordinate bias.    */
#define ESC     0x1B                    /* ESC character.               */
#define BEL     0x07                    /* ASCII bell character         */

/****	ST Internals definitions		*****/

/*	BIOS calls */

#define	BCONSTAT	1	/* return input device status */
#define	CONIN		2	/* read character from device */
#define	BCONOUT		3	/* write character to device */

/*	XBIOS calls */

#define	INITMOUS	0	/* initialize the mouse */
#define	GETREZ		4	/* get current resolution */
#define	SETSCREEN	5	/* set screen resolution */
#define	SETPALETTE	6	/* set the color pallette */
#define	SETCOLOR	7	/* set or read a color */
#define	CURSCONF	21	/* set cursor configuration */
#define	IKBDWS		25	/* intelligent keyboard send command */
#define	KBDVBASE	34	/* get keyboard table base */

/*	GEMDOS calls */

#define	EXEC		0x4b	/* Exec off a process */

#define	CON		2	/* CON: Keyboard and screen device */

/*	LINE A variables	*/

#define LINEA_INIT 0xA000
#define V_CEL_WR   -0x28
#define V_CEL_MY   -0x2a
#define V_CEL_HT   -0x2e
#define V_FNT_AD   -0x16
#define V_OFF_AD   -0x0a
#define V_DISAB    -346

/*	Palette color definitions	*/

#define	LOWPAL	"000700070770007707077777"
#define	MEDPAL	"000700007777"
#define	HIGHPAL	"000111"

/*	ST Global definitions		*/

/* keyboard vector table */
struct KVT {
	long midivec;		/* midi input */
	long vkbderr;		/* keyboard error */
	long vmiderr;		/* MIDI error */
	long statvec;		/* IKBD status */
	int (*mousevec)();	/* mouse vector */
	long clockvec;		/* clock vector */
	long joyvec;		/* joystict vector */
} *ktable;

int (*sysmint)();			/* system mouse interupt handler */

/* mouse parameter table */
struct Param {
	char topmode;
	char buttons;
	char xparam;
	char yparam;
	int xmax,ymax;
	int xinitial,yinitial;
} mparam;

int initrez;			/* initial screen resolution */
int currez;			/* current screen resolution */
char resname[][8] = {		/* screen resolution names */
	"LOW", "MEDIUM", "HIGH", "DENSE"
};
short spalette[16];			/* original color palette settings */
short palette[16];			/* current palette settings */

extern  int     ttopen();               /* Forward references.          */
extern  int     ttgetc();
extern  int     ttputc();
extern  int     ttflush();
extern  int     ttclose();
extern  int     stmove();
extern  int     steeol();
extern  int     steeop();
extern  int     stbeep();
extern  int     stopen();
extern	int	stclose();
extern	int	stgetc();
extern	int	stputc();
extern	int	strev();
extern	int	strez();
extern	int	stkopen();
extern	int	stkclose();

#if	COLOR
extern	int	stfcol();
extern	int	stbcol();
#endif

/*
 * Dispatch table. All the
 * hard fields just point into the
 * terminal I/O code.
 */
TERM    term    = {
	NROW-1,
        NROW-1,
        NCOL,
        NCOL,
	MARGIN,
	SCRSIZ,
	NPAUSE,
        &stopen,
        &stclose,
	&stkopen,
	&stkclose,
        &stgetc,
	&stputc,
        &ttflush,
        &stmove,
        &steeol,
        &steeop,
        &stbeep,
        &strev,
	&strez
#if	COLOR
	, &stfcol,
	&stbcol
#endif
};

stmove(row, col)
{
        stputc(ESC);
        stputc('Y');
        stputc(row+BIAS);
        stputc(col+BIAS);
}

steeol()
{
        stputc(ESC);
        stputc('K');
}

steeop()
{
#if	COLOR
	stfcol(gfcolor);
	stbcol(gbcolor);
#endif
        stputc(ESC);
        stputc('J');
}

strev(status)	/* set the reverse video state */

int status;	/* TRUE = reverse video, FALSE = normal video */

{
	if (currez > 1) {
		stputc(ESC);
		stputc(status ? 'p' : 'q');
	}
}

#if	COLOR
mapcol(clr)	/* medium rez color translation */

int clr;	/* emacs color number to translate */

{
	static int mctable[] = {0, 1, 2, 3, 2, 1, 2, 3};

	if (currez != 1)
		return(clr);
	else
		return(mctable[clr]);
}

stfcol(color)	/* set the forground color */

int color;	/* color to set forground to */

{
	if (currez < 2) {
		stputc(ESC);
		stputc('b');
		stputc(mapcol(color));
	}
}

stbcol(color)	/* set the background color */

int color;	/* color to set background to */


{
	if (currez < 2) {
		stputc(ESC);
		stputc('c');
		stputc(mapcol(color));
	}
}
#endif

stbeep()
{
        stputc(BEL);
        ttflush();
}

domouse()	/* mouse interupt handler */

{
	return((*sysmint)());
}

stkopen()	/* open the keyboard (and mouse) */

{
	/* grab the keyboard vector table */
	ktable = (struct KVT *)xbios(KBDVBASE);
	sysmint = ktable->mousevec;	/* save mouse vector */

	/* initialize the mouse */
	mparam.topmode = 0;
	mparam.buttons = 4;
	mparam.xparam = 8;
	mparam.yparam = 10;
	mparam.xmax = 79;
	mparam.ymax = 23;
	mparam.xinitial = 0;
	mparam.yinitial = 0;
	xbios(INITMOUS, 4, &mparam, &domouse);
}

stopen()	/* open the screen */

{
	int i;

        ttopen();
	eolexist = TRUE;

	/* switch to a steady cursor */
	xbios(CURSCONF, 3);

	/* save the current color palette */
	for (i=0; i<16; i++)
		spalette[i] = xbios(SETCOLOR, i, -1);

	/* and find the current resolution */
	initrez = currez = xbios(GETREZ);
	strcpy(sres, resname[currez]);

	/* set up the screen size and palette */
	switch (currez) {
		case 0:	term.t_mrow = 25 - 1;
			term.t_nrow = 25 - 1;
			term.t_ncol = 40;
			strcpy(palstr, LOWPAL);
			break;

		case 1: term.t_mrow = 25 - 1;
			term.t_nrow = 25 - 1;
			strcpy(palstr, MEDPAL);
			break;

		case 2: term.t_mrow = 40 - 1;
			term.t_nrow = 25 - 1;
			strcpy(palstr, HIGHPAL);
	}

	/* and set up the default palette */
	spal(palstr);

	stputc(ESC);	/* automatic overflow off */
	stputc('w');
	stputc(ESC);	/* turn cursor on */
	stputc('e');
}

stkclose()	/* close the keyboard (and mouse) */

{
	static char resetcmd[] = {0x80, 0x01};	/* keyboard reset command */

	/* restore the mouse interupt routines */
	xbios(INITMOUS, 2, &mparam, (long)sysmint);

	/* and reset the keyboard controller */
	xbios(IKBDWS, 1, &resetcmd[0]);
}

stclose()

{
	stputc(ESC);	/* auto overflow on */
	stputc('v');

	/* switch to a flashing cursor */
	xbios(CURSCONF, 2);

	/* restore the original screen resolution */
	strez(resname[initrez]);

	/* restore the original palette settings */
	xbios(SETPALETTE, spalette);

	ttclose();
}

/* 	spal(pstr):	reset the current palette according to a
			"palette string" of the form

	000111222333444555666777

	which contains the octal values for the palette registers
*/

spal(pstr)

char *pstr;	/* palette string */

{
	int pal;	/* current palette position */
	int clr;	/* current color value */
	int i;

	for (pal = 0; pal < 16; pal++) {
		if (*pstr== 0)
			break;

		/* parse off a color */
		clr = 0;
		for (i = 0; i < 3; i++)
			if (*pstr)
				clr = clr * 16 + (*pstr++ - '0');
		palette[pal] = clr;
	};

	/* and now set it */
	xbios(SETPALETTE, palette);
}

stgetc()	/* get a char from the keyboard */

{
	int rval;		/* return value from BIOS call */
	static int funkey = 0;	/* held fuction key scan code */

	/* if there is a pending function key, return it */
	if (funkey) {
		rval = funkey;
		funkey = 0;
	} else {
		/* waiting... flash the cursor */
		xbios(CURSCONF, 2);

		/* get the character */
		rval = bios(CONIN, CON);
		if ((rval & 255) == 0) {
			funkey = (rval >> 16) & 255;
			rval = 0;
		}

		/* and switch to a steady cursor */
		xbios(CURSCONF, 3);
	}

	return(rval & 255);
}

stputc(c)	/* output char c to the screen */

char c;		/* character to print out */

{
	bios(BCONOUT, CON, c);
}

strez(newrez)	/* change screen resolution */

char *newrez;	/* requested resolution */

{
	int nrez;	/* requested new resolution */

	/* first, decode the resolution name */
	for (nrez = 0; nrez < 4; nrez++)
		if (strcmp(newrez, resname[nrez]) == 0)
			break;
	if (nrez == 4) {
		mlwrite("%%No such resolution");
		return(FALSE);
	}

	/* next, make sure this resolution is legal for this monitor */
	if ((currez < 2 && nrez > 1) || (currez > 1 && nrez < 2)) {
		mlwrite("%%Resolution illegal for this monitor");
		return(FALSE);
	}

	/* eliminate non-changes */
	if (currez == nrez)
		return(TRUE);

	/* finally, make the change */
	switch (nrez) {
		case 0:	/* low resolution - 16 colors */
			newwidth(TRUE, 40);
			strcpy(palstr, LOWPAL);
			xbios(SETSCREEN, -1, -1, 0);
			break;

		case 1:	/* medium resolution - 4 colors */
			newwidth(TRUE, 80);
			strcpy(palstr, MEDPAL);
			xbios(SETSCREEN, -1, -1, 1);
			break;

		case 2:	/* High resolution - 2 colors - 25 lines */
			newsize(TRUE, 25);
			strcpy(palstr, HIGHPAL);
			/* change char set back to normal */
			break;

		case 3:	/* Dense resolution - 2 colors - 40 lines */
			/* newsize(TRUE, 40); */
			strcpy(palstr, HIGHPAL);
			/*change char set size */
			break;
	}

	/* and set up the default palette */
	spal(palstr);
	currez = nrez;
	strcpy(sres, resname[currez]);

	stputc(ESC);	/* automatic overflow off */
	stputc('w');
	stputc(ESC);	/* turn cursor on */
	stputc('e');

	return(TRUE);
}

system(cmd)	/* call the system to execute a new program */

char *cmd;	/* command to execute */

{
	char *pptr;			/* pointer into program name */
	char pname[NSTRING];		/* name of program to execute */
	char tail[NSTRING];		/* command tail */

	/* scan off program name.... */
	pptr = pname;
	while (*cmd && (*cmd != ' ' && *cmd != '\t'))
		*pptr++ = *cmd++;
	*pptr = 0;

	/* create program name length/string */
	tail[0] = strlen(cmd);
	strcpy(&tail[1], cmd);

	/* go do it! */
	return(gemdos(		(int)EXEC,
				(int)0,
				(char *)pname,
				(char *)tail,
				(char *)NULL));
}

#if	TYPEAH
typahead()

{
	int rval;	/* return value from BIOS call */

	/* get the status of the console */
	rval = bios(BCONSTAT, CON);

	/* end return the results */
	if (rval == 0)
		return(FALSE);
	else
		return(TRUE);
}
#endif

#if	FLABEL
fnclabel(f, n)		/* label a function key */

int f,n;	/* default flag, numeric argument [unused] */

{
	/* on machines with no function keys...don't bother */
	return(TRUE);
}
#endif
#else
sthello()
{
}
#endif
#endif

@//E*O*F st520.c//
chmod u=rw,g=r,o=r st520.c
 
exit 0
