Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!mit-eddie!ll-xn!adelie!necntc!ncoast!allbery From: nwd@j.cc.purdue.edu (Daniel Lawrence) Newsgroups: comp.sources.misc Subject: MicroEmacs 3.9 (Part 11 of 16) Message-ID: <5687@ncoast.UUCP> Date: Mon, 16-Nov-87 21:34:04 EST Article-I.D.: ncoast.5687 Posted: Mon Nov 16 21:34:04 1987 Date-Received: Fri, 20-Nov-87 06:44:18 EST Sender: allbery@ncoast.UUCP Lines: 1485 Approved: allbery@ncoast.UUCP X-Archive: comp.sources.misc/microemacs-3.9/10 # This is a shar archive. # Remove everything above this line. # Run the file through sh, not csh. # (type `sh mes.11') # If you do not see the message # `mes.11 completed!' # then the file was incomplete. echo extracting - spawn.c sed 's/^X//' > spawn.c << 'FRIDAY_NIGHT' X/* Spawn: various DOS access commands X for MicroEMACS X*/ X X#include X#include "estruct.h" X#include "edef.h" X X#if AMIGA X#define NEW 1006L X#endif X X#if VMS X#define EFN 0 /* Event flag. */ X X#include /* Random headers. */ X#include X#include X#include X Xextern int oldmode[3]; /* In "termio.c" */ Xextern int newmode[3]; /* In "termio.c" */ Xextern short iochan; /* In "termio.c" */ X#endif X X#if V7 | USG | BSD X#include Xextern int vttidy(); X#endif X X#if MSDOS & (MSC | TURBO) X#include X#endif X X/* X * Create a subjob with a copy of the command intrepreter in it. When the X * command interpreter exits, mark the screen as garbage so that you do a full X * repaint. Bound to "^X C". The message at the start in VMS puts out a newline. X * Under some (unknown) condition, you don't get one free when DCL starts up. X */ Xspawncli(f, n) X{ X#if AMIGA X long newcli; X X#endif X X#if V7 | USG | BSD X register char *cp; X char *getenv(); X#endif X X /* don't allow this command if restricted */ X if (restflag) X return(resterr()); X X#if AMIGA X mlwrite("[Starting new CLI]"); X sgarbf = TRUE; X Execute("NEWCLI \"CON:0/0/640/200/MicroEMACS Subprocess\"", 0L, 0L); X return(TRUE); X#endif X X#if VMS X movecursor(term.t_nrow, 0); /* In last line. */ X mlputs("[Starting DCL]\r\n"); X TTflush(); /* Ignore "ttcol". */ X sgarbf = TRUE; X return (sys(NULL)); /* NULL => DCL. */ X#endif X#if CPM X mlwrite("Not in CP/M-86"); X#endif X#if MSDOS & (AZTEC | MSC | TURBO) X movecursor(term.t_nrow, 0); /* Seek to last line. */ X TTflush(); X TTkclose(); X shellprog(""); X TTkopen(); X sgarbf = TRUE; X return(TRUE); X#endif X#if ST520 & MWC X mlerase(); /* clear the message line */ X TTflush(); X TTkclose(); X system("msh.prg"); X TTkopen(); X sgarbf = TRUE; X return(TRUE); X#endif X#if MSDOS & LATTICE X movecursor(term.t_nrow, 0); /* Seek to last line. */ X TTflush(); X TTkclose(); X sys("\\command.com", ""); /* Run CLI. */ X TTkopen(); X sgarbf = TRUE; X return(TRUE); X#endif X#if V7 | USG | BSD X movecursor(term.t_nrow, 0); /* Seek to last line. */ X TTflush(); X TTclose(); /* stty to old settings */ X if ((cp = getenv("SHELL")) != NULL && *cp != '\0') X system(cp); X else X#if BSD X system("exec /bin/csh"); X#else X system("exec /bin/sh"); X#endif X sgarbf = TRUE; X sleep(2); X TTopen(); X return(TRUE); X#endif X} X X#if BSD X Xbktoshell() /* suspend MicroEMACS and wait to wake up */ X{ X int pid; X X vttidy(); X pid = getpid(); X kill(pid,SIGTSTP); X} X Xrtfrmshell() X{ X TTopen(); X curwp->w_flag = WFHARD; X sgarbf = TRUE; X} X#endif X X/* X * Run a one-liner in a subjob. When the command returns, wait for a single X * character to be typed, then mark the screen as garbage so a full repaint is X * done. Bound to "C-X !". X */ Xspawn(f, n) X{ X register int s; X char line[NLINE]; X X#if AMIGA X long newcli; X#endif X X /* don't allow this command if restricted */ X if (restflag) X return(resterr()); X X#if AMIGA X if ((s=mlreply("!", line, NLINE)) != TRUE) X return (s); X newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW); X Execute(line, 0L, newcli); X Close(newcli); X tgetc(); /* Pause. */ X sgarbf = TRUE; X return(TRUE); X#endif X X#if VMS X if ((s=mlreply("!", line, NLINE)) != TRUE) X return (s); X TTputc('\n'); /* Already have '\r' */ X TTflush(); X s = sys(line); /* Run the command. */ X mlputs("\r\n\n[End]"); /* Pause. */ X TTflush(); X tgetc(); X sgarbf = TRUE; X return (s); X#endif X#if CPM X mlwrite("Not in CP/M-86"); X return (FALSE); X#endif X#if MSDOS X if ((s=mlreply("!", line, NLINE)) != TRUE) X return(s); X movecursor(term.t_nrow - 1, 0); X TTkclose(); X shellprog(line); X TTkopen(); X /* if we are interactive, pause here */ X if (clexec == FALSE) { X mlputs("\r\n\n[End]"); X tgetc(); X } X sgarbf = TRUE; X return (TRUE); X#endif X#if ST520 & MWC X if ((s=mlreply("!", line, NLINE)) != TRUE) X return(s); X mlerase(); X TTkclose(); X system(line); X TTkopen(); X /* if we are interactive, pause here */ X if (clexec == FALSE) { X mlputs("\r\n\n[End]"); X tgetc(); X } X sgarbf = TRUE; X return (TRUE); X#endif X#if V7 | USG | BSD X if ((s=mlreply("!", line, NLINE)) != TRUE) X return (s); X TTputc('\n'); /* Already have '\r' */ X TTflush(); X TTclose(); /* stty to old modes */ X system(line); X TTopen(); X mlputs("[End]"); /* Pause. */ X TTflush(); X while ((s = tgetc()) != '\r' && s != ' ') X ; X sgarbf = TRUE; X return (TRUE); X#endif X} X X/* X * Run an external program with arguments. When it returns, wait for a single X * character to be typed, then mark the screen as garbage so a full repaint is X * done. Bound to "C-X $". X */ X Xexecprg(f, n) X X{ X register int s; X char line[NLINE]; X X#if AMIGA X long newcli; X#endif X X /* don't allow this command if restricted */ X if (restflag) X return(resterr()); X X#if AMIGA X if ((s=mlreply("!", line, NLINE)) != TRUE) X return (s); X newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW); X Execute(line, 0L, newcli); X Close(newcli); X tgetc(); /* Pause. */ X sgarbf = TRUE; X return(TRUE); X#endif X X#if VMS X if ((s=mlreply("!", line, NLINE)) != TRUE) X return (s); X TTputc('\n'); /* Already have '\r' */ X TTflush(); X s = sys(line); /* Run the command. */ X mlputs("\r\n\n[End]"); /* Pause. */ X TTflush(); X tgetc(); X sgarbf = TRUE; X return (s); X#endif X#if CPM X mlwrite("Not in CP/M-86"); X return (FALSE); X#endif X#if MSDOS X if ((s=mlreply("$", line, NLINE)) != TRUE) X return(s); X movecursor(term.t_nrow - 1, 0); X TTkclose(); X execprog(line); X TTkopen(); X /* if we are interactive, pause here */ X if (clexec == FALSE) { X mlputs("\r\n\n[End]"); X tgetc(); X } X sgarbf = TRUE; X return (TRUE); X#endif X#if ST520 & MWC X if ((s=mlreply("!", line, NLINE)) != TRUE) X return(s); X mlerase(); X TTkclose(); X system(line); X TTkopen(); X /* if we are interactive, pause here */ X if (clexec == FALSE) { X mlputs("\r\n\n[End]"); X tgetc(); X } X sgarbf = TRUE; X return (TRUE); X#endif X#if V7 | USG | BSD X if ((s=mlreply("!", line, NLINE)) != TRUE) X return (s); X TTputc('\n'); /* Already have '\r' */ X TTflush(); X TTclose(); /* stty to old modes */ X system(line); X TTopen(); X mlputs("[End]"); /* Pause. */ X TTflush(); X while ((s = tgetc()) != '\r' && s != ' ') X ; X sgarbf = TRUE; X return (TRUE); X#endif X} X X/* X * Pipe a one line command into a window X * Bound to ^X @ X */ Xpipecmd(f, n) X{ X register int s; /* return status from CLI */ X register WINDOW *wp; /* pointer to new window */ X register BUFFER *bp; /* pointer to buffer to zot */ X char line[NLINE]; /* command line send to shell */ X static char bname[] = "command"; X X#if AMIGA X static char filnam[] = "ram:command"; X long newcli; X#else X static char filnam[NSTRING] = "command"; X#endif X X#if MSDOS | (ST520 & MWC) X char *tmp; X char *getenv(); X FILE *fp; X FILE *fopen(); X#endif X X /* don't allow this command if restricted */ X if (restflag) X return(resterr()); X X#if MSDOS X if ((tmp = getenv("TMP")) == NULL) X strcpy(filnam, "command"); X else { X strcpy(filnam, tmp); X strcat(filnam,"\\command"); X } X#endif X X#if VMS X mlwrite("Not availible under VMS"); X return(FALSE); X#endif X#if CPM X mlwrite("Not availible under CP/M-86"); X return(FALSE); X#endif X X /* get the command to pipe in */ X if ((s=mlreply("@", line, NLINE)) != TRUE) X return(s); X X /* get rid of the command output buffer if it exists */ X if ((bp=bfind(bname, FALSE, 0)) != FALSE) { X /* try to make sure we are off screen */ X wp = wheadp; X while (wp != NULL) { X if (wp->w_bufp == bp) { X onlywind(FALSE, 1); X break; X } X wp = wp->w_wndp; X } X if (zotbuf(bp) != TRUE) X X return(FALSE); X } X X#if AMIGA X newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW); X strcat(line, " >"); X strcat(line, filnam); X Execute(line, 0L, newcli); X s = TRUE; X Close(newcli); X sgarbf = TRUE; X#endif X#if MSDOS | (ST520 & MWC) X strcat(line," >>"); X strcat(line,filnam); X movecursor(term.t_nrow - 1, 0); X TTkclose(); X#if MSDOS X shellprog(line); X#else X system(line); X#endif X TTkopen(); X sgarbf = TRUE; X if ((fp = fopen(filnam, "r")) == NULL) { X s = FALSE; X } else { X fclose(fp); X s = TRUE; X } X#endif X#if V7 | USG | BSD X TTputc('\n'); /* Already have '\r' */ X TTflush(); X TTclose(); /* stty to old modes */ X strcat(line,">"); X strcat(line,filnam); X system(line); X TTopen(); X TTflush(); X sgarbf = TRUE; X s = TRUE; X#endif X X if (s != TRUE) X return(s); X X /* split the current window to make room for the command output */ X if (splitwind(FALSE, 1) == FALSE) X return(FALSE); X X /* and read the stuff in */ X if (getfile(filnam, FALSE) == FALSE) X return(FALSE); X X /* make this window in VIEW mode, update all mode lines */ X curwp->w_bufp->b_mode |= MDVIEW; X wp = wheadp; X while (wp != NULL) { X wp->w_flag |= WFMODE; X wp = wp->w_wndp; X } X X /* and get rid of the temporary file */ X unlink(filnam); X return(TRUE); X} X X/* X * filter a buffer through an external DOS program X * Bound to ^X # X */ Xfilter(f, n) X X{ X register int s; /* return status from CLI */ X register BUFFER *bp; /* pointer to buffer to zot */ X char line[NLINE]; /* command line send to shell */ X char tmpnam[NFILEN]; /* place to store real file name */ X static char bname1[] = "fltinp"; X X#if AMIGA X static char filnam1[] = "ram:fltinp"; X static char filnam2[] = "ram:fltout"; X long newcli; X#else X static char filnam1[] = "fltinp"; X static char filnam2[] = "fltout"; X#endif X X /* don't allow this command if restricted */ X if (restflag) X return(resterr()); X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X X#if VMS X mlwrite("Not availible under VMS"); X return(FALSE); X#endif X#if CPM X mlwrite("Not availible under CP/M-86"); X return(FALSE); X#endif X X /* get the filter name and its args */ X if ((s=mlreply("#", line, NLINE)) != TRUE) X return(s); X X /* setup the proper file names */ X bp = curbp; X strcpy(tmpnam, bp->b_fname); /* save the original name */ X strcpy(bp->b_fname, bname1); /* set it to our new one */ X X /* write it out, checking for errors */ X if (writeout(filnam1) != TRUE) { X mlwrite("[Cannot write filter file]"); X strcpy(bp->b_fname, tmpnam); X return(FALSE); X } X X#if AMIGA X newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW); X strcat(line, " ram:fltout"); X Execute(line,0L,newcli); X s = TRUE; X Close(newcli); X sgarbf = TRUE; X#endif X#if MSDOS | (ST520 & MWC) X strcat(line," fltout"); X movecursor(term.t_nrow - 1, 0); X TTkclose(); X#if MSDOS X shellprog(line); X#else X system(line); X#endif X TTkopen(); X sgarbf = TRUE; X s = TRUE; X#endif X#if V7 | USG | BSD X TTputc('\n'); /* Already have '\r' */ X TTflush(); X TTclose(); /* stty to old modes */ X strcat(line," fltout"); X system(line); X TTopen(); X TTflush(); X sgarbf = TRUE; X s = TRUE; X#endif X X /* on failure, escape gracefully */ X if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) { X mlwrite("[Execution failed]"); X strcpy(bp->b_fname, tmpnam); X unlink(filnam1); X unlink(filnam2); X return(s); X } X X /* reset file name */ X strcpy(bp->b_fname, tmpnam); /* restore name */ X bp->b_flag |= BFCHG; /* flag it as changed */ X X /* and get rid of the temporary file */ X unlink(filnam1); X unlink(filnam2); X return(TRUE); X} X X#if VMS X/* X * Run a command. The "cmd" is a pointer to a command string, or NULL if you X * want to run a copy of DCL in the subjob (this is how the standard routine X * LIB$SPAWN works. You have to do wierd stuff with the terminal on the way in X * and the way out, because DCL does not want the channel to be in raw mode. X */ Xsys(cmd) Xregister char *cmd; X{ X struct dsc$descriptor cdsc; X struct dsc$descriptor *cdscp; X long status; X long substatus; X long iosb[2]; X X status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0, X oldmode, sizeof(oldmode), 0, 0, 0, 0); X if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) X return (FALSE); X cdscp = NULL; /* Assume DCL. */ X if (cmd != NULL) { /* Build descriptor. */ X cdsc.dsc$a_pointer = cmd; X cdsc.dsc$w_length = strlen(cmd); X cdsc.dsc$b_dtype = DSC$K_DTYPE_T; X cdsc.dsc$b_class = DSC$K_CLASS_S; X cdscp = &cdsc; X } X status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0); X if (status != SS$_NORMAL) X substatus = status; X status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0, X newmode, sizeof(newmode), 0, 0, 0, 0); X if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) X return (FALSE); X if ((substatus&STS$M_SUCCESS) == 0) /* Command failed. */ X return (FALSE); X return (TRUE); X} X#endif X X#if ~AZTEC & ~MSC & ~TURBO & MSDOS X X/* X * This routine, once again by Bob McNamara, is a C translation of the "system" X * routine in the MWC-86 run time library. It differs from the "system" routine X * in that it does not unconditionally append the string ".exe" to the end of X * the command name. We needed to do this because we want to be able to spawn X * off "command.com". We really do not understand what it does, but if you don't X * do it exactly "malloc" starts doing very very strange things. X */ Xsys(cmd, tail) Xchar *cmd; Xchar *tail; X{ X#if MWC X register unsigned n; X extern char *__end; X X n = __end + 15; X n >>= 4; X n = ((n + dsreg() + 16) & 0xFFF0) + 16; X return(execall(cmd, tail, n)); X#endif X X#if LATTICE X return(forklp(cmd, tail, (char *)NULL)); X#endif X} X#endif X X#if MSDOS & LATTICE X/* System: a modified version of lattice's system() function X that detects the proper switchar and uses it X written by Dana Hogget */ X Xsystem(cmd) X Xchar *cmd; /* Incoming command line to execute */ X X{ X char *getenv(); X static char *swchar = "/C"; /* Execution switch */ X union REGS inregs; /* parameters for dos call */ X union REGS outregs; /* Return results from dos call */ X char *shell; /* Name of system command processor */ X char *p; /* Temporary pointer */ X int ferr; /* Error condition if any */ X X /* get name of system shell */ X if ((shell = getenv("COMSPEC")) == NULL) { X return (-1); /* No shell located */ X } X X p = cmd; X while (isspace(*p)) { /* find out if null command */ X p++; X } X X /** If the command line is not empty, bring up the shell **/ X /** and execute the command. Otherwise, bring up the **/ X /** shell in interactive mode. **/ X X if (p && *p) { X /** detect current switch character and us it **/ X inregs.h.ah = 0x37; /* get setting data */ X inregs.h.al = 0x00; /* get switch character */ X intdos(&inregs, &outregs); X *swchar = outregs.h.dl; X ferr = forkl(shell, "command", swchar, cmd, (char *)NULL); X } else { X ferr = forkl(shell, "command", (char *)NULL); X } X X return (ferr ? ferr : wait()); X} X#endif X X#if MSDOS & LATTICE Xextern int _oserr; X#endif X X#if MSDOS & AZTEC Xextern int errno; X#endif X X#if MSDOS & (TURBO | LATTICE | AZTEC) X/* SHELLPROG: Execute a command in a subshell */ X Xshellprog(cmd) X Xchar *cmd; /* Incoming command line to execute */ X X{ X char *shell; /* Name of system command processor */ X char *p; /* Temporary pointer */ X char swchar; /* switch character to use */ X union REGS regs; /* parameters for dos call */ X char comline[NSTRING]; /* constructed command line */ X char *getenv(); X X /* detect current switch character and set us up to use it */ X regs.h.ah = 0x37; /* get setting data */ X regs.h.al = 0x00; /* get switch character */ X intdos(®s, ®s); X swchar = (char)regs.h.dl; X X /* get name of system shell */ X if ((shell = getenv("COMSPEC")) == NULL) { X return(FALSE); /* No shell located */ X } X X /* trim leading whitespace off the command */ X while (*cmd == ' ' || *cmd == '\t') /* find out if null command */ X cmd++; X X /** If the command line is not empty, bring up the shell **/ X /** and execute the command. Otherwise, bring up the **/ X /** shell in interactive mode. **/ X X if (*cmd) { X strcpy(comline, shell); X strcat(comline, " "); X comline[strlen(comline) + 1] = 0; X comline[strlen(comline)] = swchar; X strcat(comline, "c "); X strcat(comline, cmd); X return(execprog(comline)); X } else X return(execprog(shell)); X} X X/* EXECPROG: A function to execute a named program X with arguments X*/ X Xexecprog(cmd) X Xchar *cmd; /* Incoming command line to execute */ X X{ X char *sp; /* temporary string pointer */ X char f1[38]; /* FCB1 area (not initialized */ X char f2[38]; /* FCB2 area (not initialized */ X char prog[NSTRING]; /* program filespec */ X char tail[NSTRING]; /* command tail with length byte */ X union REGS regs; /* parameters for dos call */ X struct SREGS segreg; /* segment registers for dis call */ X struct pblock { /* EXEC parameter block */ X short envptr; /* 2 byte pointer to environment string */ X char *cline; /* 4 byte pointer to command line */ X char *fcb1; /* 4 byte pointer to FCB at PSP+5Ch */ X char *fcb2; /* 4 byte pointer to FCB at PSP+6Ch */ X } pblock; X char *flook(); X X /* parse the command name from the command line */ X sp = prog; X while (*cmd && (*cmd != ' ') && (*cmd != '\t')) X *sp++ = *cmd++; X *sp = 0; X X /* and parse out the command tail */ X while (*cmd && ((*cmd == ' ') || (*cmd == '\t'))) X ++cmd; X *tail = (char)(strlen(cmd)); /* record the byte length */ X strcpy(&tail[1], cmd); X strcat(&tail[1], "\r"); X X /* look up the program on the path trying various extentions */ X if ((sp = flook(prog, TRUE)) == NULL) X if ((sp = flook(strcat(prog, ".exe"), TRUE)) == NULL) { X strcpy(&prog[strlen(prog)-4], ".com"); X if ((sp = flook(prog, TRUE)) == NULL) X return(FALSE); X } X strcpy(prog, sp); X X /* get a pointer to this PSPs environment segment number */ X segread(&segreg); X X /* set up the EXEC parameter block */ X pblock.envptr = 0; /* make the child inherit the parents env */ X pblock.fcb1 = f1; /* point to a blank FCB */ X pblock.fcb2 = f2; /* point to a blank FCB */ X pblock.cline = tail; /* parameter line pointer */ X X /* and make the call */ X regs.h.ah = 0x4b; /* EXEC Load or Execute a Program */ X regs.h.al = 0x00; /* load end execute function subcode */ X#if AZTEC X regs.x.ds = ((unsigned long)(prog) >> 16); /* program name ptr */ X#else X segreg.ds = ((unsigned long)(prog) >> 16); /* program name ptr */ X#endif X regs.x.dx = (unsigned int)(prog); X#if AZTEC X regs.x.es = regs.x.ds; X /*regs.x.es = ((unsigned long)(&pblock) >> 16); * set up param block ptr */ X#else X segreg.es = ((unsigned long)(&pblock) >> 16); /* set up param block ptr */ X#endif X regs.x.bx = (unsigned int)(&pblock); X#if LATTICE X#define CFLAG 1 X if ((intdosx(®s, ®s, &segreg) & CFLAG) == 0) { X regs.h.ah = 0x4d; /* get child process return code */ X intdos(®s, ®s); /* go do it */ X rval = regs.x.ax; /* save child's return code */ X } else X rval = -_oserr; /* failed child call */ X#endif X#if AZTEC X#define CFLAG 1 X if ((sysint(0x21, ®s, ®s) & CFLAG) == 0) { X regs.h.ah = 0x4d; /* get child process return code */ X sysint(0x21, ®s, ®s); /* go do it */ X rval = regs.x.ax; /* save child's return code */ X } else X rval = -errno; /* failed child call */ X#endif X#if TURBO X intdosx(®s, ®s, &segreg); X if (regs.x.cflag == 0) { X regs.h.ah = 0x4d; /* get child process return code */ X intdos(®s, ®s); /* go do it */ X rval = regs.x.ax; /* save child's return code */ X } else X rval = -_doserrno; /* failed child call */ X#endif X return((rval < 0) ? FALSE : TRUE); X} X#endif FRIDAY_NIGHT echo extracting - st520.c sed 's/^X//' > st520.c << 'FRIDAY_NIGHT' X/* X XThe routines in this file provide support for the Atari 520 or 1040ST Xusing VT52 emulation. The I/O services are provided here as well. It Xcompiles into nothing if not a 520ST style device. The only compiler Xsupported directly is Mark Williams C X XAdditional code and ideas from: X X James Turner X Jeff Lomicka X J. C. Benoist X X*/ X X#define termdef 1 /* don't define "term" external */ X X#include X#include "estruct.h" X#include "edef.h" X X#if ATARI & ST520 X X/* X These routines provide support for the ATARI 1040ST and 520ST Xusing the virtual VT52 Emulator X X*/ X X#include X#include X#include X X#define NROW 50 /* Screen size. */ X#define NCOL 80 /* Edit if you want to. */ X#define MARGIN 8 /* size of minimim margin and */ X#define SCRSIZ 64 /* scroll size for extended lines */ X#define NPAUSE 300 /* # times thru update to pause */ X#define BIAS 0x20 /* Origin 0 coordinate bias. */ X#define ESC 0x1B /* ESC character. */ X#define SCRFONT 2 /* index of 8x16 monochrome system default font */ X#define DENSIZE 50 /* # of lines in a dense screen */ X X/**** ST Internals definitions *****/ X X/* BIOS calls */ X X#define BCONSTAT 1 /* return input device status */ X#define CONIN 2 /* read character from device */ X#define BCONOUT 3 /* write character to device */ X X/* XBIOS calls */ X X#define INITMOUS 0 /* initialize the mouse */ X#define GETREZ 4 /* get current resolution */ X#define SETSCREEN 5 /* set screen resolution */ X#define SETPALETTE 6 /* set the color pallette */ X#define SETCOLOR 7 /* set or read a color */ X#define CURSCONF 21 /* set cursor configuration */ X#define IKBDWS 25 /* intelligent keyboard send command */ X#define KBDVBASE 34 /* get keyboard table base */ X X/* GEMDOS calls */ X X#define EXEC 0x4b /* Exec off a process */ X X#define CON 2 /* CON: Keyboard and screen device */ X X/* Palette color definitions */ X X#define LOWPAL "000700070770007707077777" X#define MEDPAL "000700007777" X#define HIGHPAL "111000" X X/* ST Global definitions */ X X/* keyboard vector table */ Xstruct KVT { X long midivec; /* midi input */ X long vkbderr; /* keyboard error */ X long vmiderr; /* MIDI error */ X long statvec; /* IKBD status */ X int (*mousevec)(); /* mouse vector */ X long clockvec; /* clock vector */ X long joyvec; /* joystict vector */ X} *ktable; X Xint (*sysmint)(); /* system mouse interupt handler */ X X/* mouse parameter table */ Xstruct Param { X char topmode; X char buttons; X char xparam; X char yparam; X int xmax,ymax; X int xinitial,yinitial; X} mparam; X Xint initrez; /* initial screen resolution */ Xint currez; /* current screen resolution */ Xchar resname[][8] = { /* screen resolution names */ X "LOW", "MEDIUM", "HIGH", "DENSE" X}; Xshort spalette[16]; /* original color palette settings */ Xshort palette[16]; /* current palette settings */ X XLINEA *aline; /* Pointer to line a parameter block returned by init */ X XNLINEA *naline; /* Pointer to line a parameters at negative offsets */ X XFONT **fonts; /* Array of pointers to the three system font headers */ X /* returned by init (in register A1) */ X XWORD (**foncs)(); /* Array of pointers to the 15 line a functions */ X /* returned by init (in register A2) */ X /* only valid in ROM'ed TOS */ X XFONT *system_font; /* pointer to default system font */ XFONT *small_font; /* pointer to small font */ X Xextern int ttopen(); /* Forward references. */ Xextern int ttgetc(); Xextern int ttputc(); Xextern int ttflush(); Xextern int ttclose(); Xextern int stmove(); Xextern int steeol(); Xextern int steeop(); Xextern int stbeep(); Xextern int stopen(); Xextern int stclose(); Xextern int stgetc(); Xextern int stputc(); Xextern int strev(); Xextern int strez(); Xextern int stkopen(); Xextern int stkclose(); X X#if COLOR Xextern int stfcol(); Xextern int stbcol(); X#endif X X/* X * Dispatch table. All the X * hard fields just point into the X * terminal I/O code. X */ XTERM term = { X NROW-1, X NROW-1, X NCOL, X NCOL, X MARGIN, X SCRSIZ, X NPAUSE, X &stopen, X &stclose, X &stkopen, X &stkclose, X &stgetc, X &stputc, X &ttflush, X &stmove, X &steeol, X &steeop, X &stbeep, X &strev, X &strez X#if COLOR X , &stfcol, X &stbcol X#endif X}; X Xvoid init_aline() X{ X linea0(); X aline = (LINEA *)(la_init.li_a0); X fonts = (FONT **)(la_init.li_a1); X foncs = la_init.li_a2; X naline = ((NLINEA *)aline) - 1; X} X Xinit() X{ X init_aline(); X system_font = fonts[SCRFONT]; /* save it */ X small_font = fonts[1]; X} X X Xswitch_font(fp) X XFONT *fp; X X{ X /* See aline.h for description of fields */ X /* these definitions are temporary...too many cooks!!! */ X#undef V_CEL_HT X#undef V_CEL_WR X#undef V_CEL_MY X#undef V_CEL_MX X#undef V_FNT_ST X#undef V_FNT_ND X#undef V_FNT_AD X#undef V_FNT_WR X#undef V_OFF_AD X#undef VWRAP X#undef V_Y_MAX X#undef V_X_MAX X X naline->V_CEL_HT = fp->form_height; X naline->V_CEL_WR = aline->VWRAP * fp->form_height; X naline->V_CEL_MY = (naline->V_Y_MAX / fp->form_height) - 1; X naline->V_CEL_MX = (naline->V_X_MAX / fp->max_cell_width) - 1; X naline->V_FNT_WR = fp->form_width; X naline->V_FNT_ST = fp->first_ade; X naline->V_FNT_ND = fp->last_ade; X naline->V_OFF_AD = fp->off_table; X naline->V_FNT_AD = fp->dat_table; X} X Xstmove(row, col) X{ X stputc(ESC); X stputc('Y'); X stputc(row+BIAS); X stputc(col+BIAS); X} X Xsteeol() X{ X stputc(ESC); X stputc('K'); X} X Xsteeop() X{ X#if COLOR X stfcol(gfcolor); X stbcol(gbcolor); X#endif X stputc(ESC); X stputc('J'); X} X Xstrev(status) /* set the reverse video state */ X Xint status; /* TRUE = reverse video, FALSE = normal video */ X X{ X if (currez > 1) { X stputc(ESC); X stputc(status ? 'p' : 'q'); X } X} X X#if COLOR Xmapcol(clr) /* medium rez color translation */ X Xint clr; /* emacs color number to translate */ X X{ X static int mctable[] = {0, 1, 2, 3, 2, 1, 2, 3}; X X if (currez != 1) X return(clr); X else X return(mctable[clr]); X} X Xstfcol(color) /* set the forground color */ X Xint color; /* color to set forground to */ X X{ X if (currez < 2) { X stputc(ESC); X stputc('b'); X stputc(mapcol(color)); X } X} X Xstbcol(color) /* set the background color */ X Xint color; /* color to set background to */ X X X{ X if (currez < 2) { X stputc(ESC); X stputc('c'); X stputc(mapcol(color)); X } X} X#endif X Xstatic char beep[] = { X 0x00, 0x00, X 0x01, 0x01, X 0x02, 0x01, X 0x03, 0x01, X 0x04, 0x02, X 0x05, 0x01, X 0x07, 0x38, X 0x08, 0x10, X 0x09, 0x10, X 0x0A, 0x10, X 0x0B, 0x00, X 0x0C, 0x30, X 0x0D, 0x03, X 0xFF, 0x00 X}; X Xstbeep() X{ X Dosound(beep); X} X Xdomouse() /* mouse interupt handler */ X X{ X return((*sysmint)()); X} X Xstkopen() /* open the keyboard (and mouse) */ X X{ X /* grab the keyboard vector table */ X ktable = (struct KVT *)xbios(KBDVBASE); X sysmint = ktable->mousevec; /* save mouse vector */ X X /* initialize the mouse */ X mparam.topmode = 0; X mparam.buttons = 4; X mparam.xparam = 8; X mparam.yparam = 10; X mparam.xmax = 79; X mparam.ymax = 23; X mparam.xinitial = 0; X mparam.yinitial = 0; X xbios(INITMOUS, 4, &mparam, &domouse); X} X Xstopen() /* open the screen */ X X{ X int i; X X ttopen(); X eolexist = TRUE; X init(); X X /* switch to a steady cursor */ X xbios(CURSCONF, 3); X X /* save the current color palette */ X for (i=0; i<16; i++) X spalette[i] = xbios(SETCOLOR, i, -1); X X /* and find the current resolution */ X initrez = currez = xbios(GETREZ); X strcpy(sres, resname[currez]); X X /* set up the screen size and palette */ X switch (currez) { X case 0: term.t_mrow = 25 - 1; X term.t_nrow = 25 - 1; X term.t_ncol = 40; X strcpy(palstr, LOWPAL); X break; X X case 1: term.t_mrow = 25 - 1; X term.t_nrow = 25 - 1; X strcpy(palstr, MEDPAL); X break; X X case 2: term.t_mrow = DENSIZE - 1; X term.t_nrow = 25 - 1; X strcpy(palstr, HIGHPAL); X } X X /* and set up the default palette */ X spal(palstr); X X stputc(ESC); /* automatic overflow off */ X stputc('w'); X stputc(ESC); /* turn cursor on */ X stputc('e'); X} X Xstkclose() /* close the keyboard (and mouse) */ X X{ X static char resetcmd[] = {0x80, 0x01}; /* keyboard reset command */ X X /* restore the mouse interupt routines */ X xbios(INITMOUS, 2, &mparam, (long)sysmint); X X /* and reset the keyboard controller */ X xbios(IKBDWS, 1, &resetcmd[0]); X} X Xstclose() X X{ X stputc(ESC); /* auto overflow on */ X stputc('v'); X X /* switch to a flashing cursor */ X xbios(CURSCONF, 2); X X /* restore the original screen resolution */ X if (currez == 3) X switch_font(system_font); X strez(resname[initrez]); X X /* restore the original palette settings */ X xbios(SETPALETTE, spalette); X X ttclose(); X} X X/* spal(pstr): reset the current palette according to a X "palette string" of the form X X 000111222333444555666777 X X which contains the octal values for the palette registers X*/ X Xspal(pstr) X Xchar *pstr; /* palette string */ X X{ X int pal; /* current palette position */ X int clr; /* current color value */ X int i; X X for (pal = 0; pal < 16; pal++) { X if (*pstr== 0) X break; X X /* parse off a color */ X clr = 0; X for (i = 0; i < 3; i++) X if (*pstr) X clr = clr * 16 + (*pstr++ - '0'); X palette[pal] = clr; X }; X X /* and now set it */ X xbios(SETPALETTE, palette); X} X Xstgetc() /* get a char from the keyboard */ X X{ X register long rval; /* return value from BIOS call */ X static int funkey = 0; /* held fuction key scan code */ X static long sh; /* shift/alt key on held function? */ X long bios(); X X /* if there is a pending function key, return it */ X if (funkey) { X if (sh) { /* alt or cntrl */ X if (funkey >= 0x3B && funkey <= 0x44) { X rval = funkey + '^' - ';'; X if (sh & 0x08) /* alt */ X rval += 10; X funkey = 0; X return(rval & 255); X } X } X rval = funkey; X funkey = 0; X } else { X /* waiting... flash the cursor */ X xbios(CURSCONF, 2); X X /* get the character */ X rval = bios(CONIN, CON); X sh = Getshift(-1) & 0x0cL; /* see if alt or cntrl depressed */ X if ((rval & 255L) == 0L) { X funkey = (rval >> 16L) & 255; X rval = 0; X } X X } X X /* and switch to a steady cursor */ X xbios(CURSCONF, 3); X X return(rval & 255); X} X Xstputc(c) /* output char c to the screen */ X Xchar c; /* character to print out */ X X{ X bios(BCONOUT, CON, c); X} X Xstrez(newrez) /* change screen resolution */ X Xchar *newrez; /* requested resolution */ X X{ X int nrez; /* requested new resolution */ X X /* first, decode the resolution name */ X for (nrez = 0; nrez < 4; nrez++) X if (strcmp(newrez, resname[nrez]) == 0) X break; X if (nrez == 4) { X mlwrite("%%No such resolution"); X return(FALSE); X } X X /* next, make sure this resolution is legal for this monitor */ X if ((currez < 2 && nrez > 1) || (currez > 1 && nrez < 2)) { X mlwrite("%%Resolution illegal for this monitor"); X return(FALSE); X } X X /* eliminate non-changes */ X if (currez == nrez) X return(TRUE); X X /* finally, make the change */ X switch (nrez) { X case 0: /* low resolution - 16 colors */ X newwidth(TRUE, 40); X strcpy(palstr, LOWPAL); X xbios(SETSCREEN, -1L, -1L, 0); X break; X X case 1: /* medium resolution - 4 colors */ X newwidth(TRUE, 80); X strcpy(palstr, MEDPAL); X xbios(SETSCREEN, -1L, -1L, 1); X break; X X case 2: /* High resolution - 2 colors - 25 lines */ X newsize(TRUE, 25); X strcpy(palstr, HIGHPAL); X switch_font(system_font); X break; X X case 3: /* Dense resolution - 2 colors - 40 lines */ X newsize(TRUE, DENSIZE); X strcpy(palstr, HIGHPAL); X switch_font(small_font); X break; X } X X /* and set up the default palette */ X spal(palstr); X currez = nrez; X strcpy(sres, resname[currez]); X X stputc(ESC); /* automatic overflow off */ X stputc('w'); X stputc(ESC); /* turn cursor on */ X stputc('e'); X X return(TRUE); X} X X#if LATTICE Xsystem(cmd) /* call the system to execute a new program */ X Xchar *cmd; /* command to execute */ X X{ X char *pptr; /* pointer into program name */ X char pname[NSTRING]; /* name of program to execute */ X char tail[NSTRING]; /* command tail */ X X /* scan off program name.... */ X pptr = pname; X while (*cmd && (*cmd != ' ' && *cmd != '\t')) X *pptr++ = *cmd++; X *pptr = 0; X X /* create program name length/string */ X tail[0] = strlen(cmd); X strcpy(&tail[1], cmd); X X /* go do it! */ X return(gemdos( (int)EXEC, X (int)0, X (char *)pname, X (char *)tail, X (char *)NULL)); X} X#endif X X#if TYPEAH Xtypahead() X X{ X int rval; /* return value from BIOS call */ X X /* get the status of the console */ X rval = bios(BCONSTAT, CON); X X /* end return the results */ X if (rval == 0) X return(FALSE); X else X return(TRUE); X} X#endif X X#if FLABEL Xfnclabel(f, n) /* label a function key */ X Xint f,n; /* default flag, numeric argument [unused] */ X X{ X /* on machines with no function keys...don't bother */ X return(TRUE); X} X#endif X#else Xsthello() X{ X} X#endif FRIDAY_NIGHT echo mes.11 completed! # That's all folsca