Subject: v06i081: MicroEmacs, Version 3.7 (uEmacs3.7), Part11/12 Newsgroups: mod.sources Approved: rs@mirror.UUCP Submitted by: ihnp4!pur-ee!pur-phy!duncan!lawrence Mod.sources: Volume 6, Issue 81 Archive-name: uEmacs/Part11 [ This is the latest revision of one of two programs named "MicroEmacs"; when discussing these on the net, or in contacting the authors, make sure to mention the version number -- in this case 3.7 -- as that is the easiest way to distinguish between them. Daniel will be posting uuencoded executables in net.micro.pc and net.micro.amiga; the file 'readme' contains information on how to also get these from him directly. --r$ ] echo extracting - tcap.c sed 's/^X//' > tcap.c << 'FRIDAY_NIGHT' X/* tcap: Unix V5, V7 and BS4.2 Termcap video driver X for MicroEMACS 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 TERMCAP X X#define MARGIN 8 X#define SCRSIZ 64 X#define NPAUSE 10 /* # times thru update to pause */ X#define BEL 0x07 X#define ESC 0x1B X Xextern int ttopen(); Xextern int ttgetc(); Xextern int ttputc(); Xextern int tgetnum(); Xextern int ttflush(); Xextern int ttclose(); Xextern int tcapmove(); Xextern int tcapeeol(); Xextern int tcapeeop(); Xextern int tcapbeep(); Xextern int tcaprev(); Xextern int tcapopen(); Xextern int tput(); Xextern char *tgoto(); X#if COLOR Xextern int tcapfcol(); Xextern int tcapbcol(); X#endif X X#define TCAPSLEN 315 Xchar tcapbuf[TCAPSLEN]; Xchar *UP, PC, *CM, *CE, *CL, *SO, *SE; X XTERM term = { X NULL, /* these two values are set dynamically at open time */ X NULL, X MARGIN, X SCRSIZ, X NPAUSE, X tcapopen, X ttclose, X ttgetc, X ttputc, X ttflush, X tcapmove, X tcapeeol, X tcapeeop, X tcapbeep, X tcaprev X#if COLOR X , tcapfcol, X tcapbcol X#endif X}; X Xtcapopen() X X{ X char *getenv(); X char *t, *p, *tgetstr(); X char tcbuf[1024]; X char *tv_stype; X char err_str[72]; X X if ((tv_stype = getenv("TERM")) == NULL) X { X puts("Environment variable TERM not defined!"); X exit(1); X } X X if ((tgetent(tcbuf, tv_stype)) != 1) X { X sprintf(err_str, "Unknown terminal type %s!", tv_stype); X puts(err_str); X exit(1); X } X X X if ((term.t_nrow=(short)tgetnum("li")-1) == -1){ X puts("termcap entry incomplete (lines)"); X exit(1); X } X X if ((term.t_ncol=(short)tgetnum("co")) == -1){ X puts("Termcap entry incomplete (columns)"); X exit(1); X } X X p = tcapbuf; X t = tgetstr("pc", &p); X if(t) X PC = *t; X X CL = tgetstr("cl", &p); X CM = tgetstr("cm", &p); X CE = tgetstr("ce", &p); X UP = tgetstr("up", &p); X SE = tgetstr("se", &p); X SO = tgetstr("so", &p); X if (SO != NULL) X revexist = TRUE; X X if(CL == NULL || CM == NULL || UP == NULL) X { X puts("Incomplete termcap entry\n"); X exit(1); X } X X if (CE == NULL) /* will we be able to use clear to EOL? */ X eolexist = FALSE; X X if (p >= &tcapbuf[TCAPSLEN]) X { X puts("Terminal description too big!\n"); X exit(1); X } X ttopen(); X} X Xtcapmove(row, col) Xregister int row, col; X{ X putpad(tgoto(CM, col, row)); X} X Xtcapeeol() X{ X putpad(CE); X} X Xtcapeeop() X{ X putpad(CL); X} X Xtcaprev(state) /* change reverse video status */ X Xint state; /* FALSE = normal video, TRUE = reverse video */ X X{ X static int revstate = FALSE; X /* mustn't send SE unless SO already sent, and vice versa */ X X#if 0 X if (state) { X if ((SO != NULL) && (revstate == FALSE)) X putpad(SO); X } else X if ((SE != NULL) && (revstate == TRUE)) X putpad(SE); X X revstate = state; X#endif X if (state) { X if (SO != NULL) X putpad(SO); X } else X if (SE != NULL) X putpad(SE); X} X X#if COLOR Xtcapfcol() /* no colors here, ignore this */ X{ X} X Xtcapbcol() /* no colors here, ignore this */ X{ X} X#endif X Xtcapbeep() X{ X ttputc(BEL); X} X Xputpad(str) Xchar *str; X{ X tputs(str, 1, ttputc); X} X Xputnpad(str, n) Xchar *str; X{ X tputs(str, n, ttputc); X} X X#else X Xhello() X{ X} X X#endif TERMCAP FRIDAY_NIGHT echo extracting - termio.c sed 's/^X//' > termio.c << 'FRIDAY_NIGHT' X/* X * The functions in this file negotiate with the operating system for X * characters, and write characters in a barely buffered fashion on the display. X * All operating systems. X */ X#include X#include "estruct.h" X#include "edef.h" X X#if AMIGA X#define NEW 1006 X#define AMG_MAXBUF 1024 Xstatic long terminal; Xstatic char scrn_tmp[AMG_MAXBUF+1]; Xstatic int scrn_tmp_p = 0; X#endif X X#if VMS X#include X#include X#include X#include X#include X#include X X#define NIBUF 128 /* Input buffer size */ X#define NOBUF 1024 /* MM says bug buffers win! */ X#define EFN 0 /* Event flag */ X Xchar obuf[NOBUF]; /* Output buffer */ Xint nobuf; /* # of bytes in above */ Xchar ibuf[NIBUF]; /* Input buffer */ Xint nibuf; /* # of bytes in above */ Xint ibufi; /* Read index */ Xint oldmode[3]; /* Old TTY mode bits */ Xint newmode[3]; /* New TTY mode bits */ Xshort iochan; /* TTY I/O channel */ X#endif X X#if CPM X#include X#endif X X#if MSDOS & (LATTICE | MSDOS) Xunion REGS rg; /* cpu register for use of DOS calls */ Xint nxtchar = -1; /* character held from type ahead */ X#endif X X#if RAINBOW X#include "rainbow.h" X#endif X X#if USG /* System V */ X#include X#include Xstruct termio otermio; /* original terminal characteristics */ Xstruct termio ntermio; /* charactoristics to use inside */ X#endif X X#if V7 | BSD X#undef CTRL X#include /* for stty/gtty functions */ X#include Xstruct sgttyb ostate; /* saved tty state */ Xstruct sgttyb nstate; /* values for editor mode */ Xstruct tchars otchars; /* Saved terminal special character set */ Xstruct tchars ntchars = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; X /* A lot of nothing */ X#if BSD X#include /* to get at the typeahead */ Xextern int rtfrmshell(); /* return from suspended shell */ X#define TBUFSIZ 128 Xchar tobuf[TBUFSIZ]; /* terminal output buffer */ X#endif X#endif X X/* X * This function is called once to set up the terminal device streams. X * On VMS, it translates TT until it finds the terminal, then assigns X * a channel to it and sets it raw. On CPM it is a no-op. X */ Xttopen() X{ X /* on all screens we are not sure of the initial position X of the cursor */ X ttrow = 999; X ttcol = 999; X X#if AMIGA X terminal = Open("RAW:1/1/639/199/MicroEMACS 3.7/Amiga", NEW); X#endif X#if VMS X struct dsc$descriptor idsc; X struct dsc$descriptor odsc; X char oname[40]; X int iosb[2]; X int status; X X odsc.dsc$a_pointer = "TT"; X odsc.dsc$w_length = strlen(odsc.dsc$a_pointer); X odsc.dsc$b_dtype = DSC$K_DTYPE_T; X odsc.dsc$b_class = DSC$K_CLASS_S; X idsc.dsc$b_dtype = DSC$K_DTYPE_T; X idsc.dsc$b_class = DSC$K_CLASS_S; X do { X idsc.dsc$a_pointer = odsc.dsc$a_pointer; X idsc.dsc$w_length = odsc.dsc$w_length; X odsc.dsc$a_pointer = &oname[0]; X odsc.dsc$w_length = sizeof(oname); X status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc); X if (status!=SS$_NORMAL && status!=SS$_NOTRAN) X exit(status); X if (oname[0] == 0x1B) { X odsc.dsc$a_pointer += 4; X odsc.dsc$w_length -= 4; X } X } while (status == SS$_NORMAL); X status = SYS$ASSIGN(&odsc, &iochan, 0, 0); X if (status != SS$_NORMAL) X exit(status); X status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0, X oldmode, sizeof(oldmode), 0, 0, 0, 0); X if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) X exit(status); X newmode[0] = oldmode[0]; X newmode[1] = oldmode[1] | TT$M_NOECHO; X newmode[1] &= ~(TT$M_TTSYNC|TT$M_HOSTSYNC); X newmode[2] = oldmode[2] | TT2$M_PASTHRU; 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 exit(status); X term.t_nrow = (newmode[1]>>24) - 1; X term.t_ncol = newmode[0]>>16; X X#endif X#if CPM X#endif X X#if MSDOS & (HP150 == 0) & LATTICE X /* kill the ctrl-break interupt */ X rg.h.ah = 0x33; /* control-break check dos call */ X rg.h.al = 1; /* set the current state */ X rg.h.dl = 0; /* set it OFF */ X intdos(&rg, &rg); /* go for it! */ X#endif X X#if USG X ioctl(o, TCGETA, &otermio); /* save old settings */ X ntermio.c_iflag = 0; /* setup new settings */ X ntermio.c_oflag = 0; X ntermio.c_cflag = otermio.c_cflag; X ntermio.c_lflag = 0; X ntermio.c_line = otermio.c_line; X ntermio.c_cc[VMIN] = 1; X ntermio.c_cc[VTIME] = 0; X ioctl(0, TCSETA, &ntermio); /* and activate them */ X#endif X X#if V7 | BSD X gtty(0, &ostate); /* save old state */ X gtty(0, &nstate); /* get base of new state */ X nstate.sg_flags |= RAW; X nstate.sg_flags &= ~(ECHO|CRMOD); /* no echo for now... */ X stty(0, &nstate); /* set mode */ X ioctl(0, TIOCGETC, &otchars); /* Save old characters */ X ioctl(0, TIOCSETC, &ntchars); /* Place new character into K */ X#if BSD X /* provide a smaller terminal output buffer so that X the type ahead detection works better (more often) */ X setbuffer(stdout, &tobuf[0], TBUFSIZ); X signal(SIGTSTP,SIG_DFL); /* set signals so that we can */ X signal(SIGCONT,rtfrmshell); /* suspend & restart emacs */ X#endif X#endif X} X X/* X * This function gets called just before we go back home to the command X * interpreter. On VMS it puts the terminal back in a reasonable state. X * Another no-operation on CPM. X */ Xttclose() X{ X#if AMIGA X amg_flush(); X Close(terminal); X#endif X#if VMS X int status; X int iosb[1]; X X ttflush(); 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 exit(status); X status = SYS$DASSGN(iochan); X if (status != SS$_NORMAL) X exit(status); X#endif X#if CPM X#endif X#if MSDOS & (HP150 == 0) & LATTICE X /* restore the ctrl-break interupt */ X rg.h.ah = 0x33; /* control-break check dos call */ X rg.h.al = 1; /* set the current state */ X rg.h.dl = 1; /* set it ON */ X intdos(&rg, &rg); /* go for it! */ X#endif X X#if USG X ioctl(0, TCSETA, &otermio); /* restore terminal settings */ X#endif X X#if V7 | BSD X stty(0, &ostate); X ioctl(0, TIOCSETC, &otchars); /* Place old character into K */ X#endif X} X X/* X * Write a character to the display. On VMS, terminal output is buffered, and X * we just put the characters in the big array, after checking for overflow. X * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on X * MS-DOS (use the very very raw console output routine). X */ Xttputc(c) X#if AMIGA X char c; X#endif X{ X#if AMIGA X scrn_tmp[scrn_tmp_p++] = c; X if(scrn_tmp_p>=AMG_MAXBUF) X amg_flush(); X#endif X#if VMS X if (nobuf >= NOBUF) X ttflush(); X obuf[nobuf++] = c; X#endif X X#if CPM X bios(BCONOUT, c, 0); X#endif X X#if MSDOS & MWC86 X dosb(CONDIO, c, 0); X#endif X X#if MSDOS & (LATTICE | AZTEC) & ~IBMPC X bdos(6, c, 0); X#endif X X#if RAINBOW X Put_Char(c); /* fast video */ X#endif X X X#if V7 | USG | BSD X fputc(c, stdout); X#endif X} X X#if AMIGA Xamg_flush() X{ X if(scrn_tmp_p) X Write(terminal,scrn_tmp,scrn_tmp_p); X scrn_tmp_p = 0; X} X#endif X X/* X * Flush terminal buffer. Does real work where the terminal output is buffered X * up. A no-operation on systems where byte at a time terminal I/O is done. X */ Xttflush() X{ X#if AMIGA X amg_flush(); X#endif X#if VMS X int status; X int iosb[2]; X X status = SS$_NORMAL; X if (nobuf != 0) { X status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT, X iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0); X if (status == SS$_NORMAL) X status = iosb[0] & 0xFFFF; X nobuf = 0; X } X return (status); X#endif X X#if CPM X#endif X X#if MSDOS X#endif X X#if V7 | USG | BSD X fflush(stdout); X#endif X} X X/* X * Read a character from the terminal, performing no editing and doing no echo X * at all. More complex in VMS that almost anyplace else, which figures. Very X * simple on CPM, because the system can do exactly what you want. X */ Xttgetc() X{ X#if AMIGA X char ch; X amg_flush(); X Read(terminal, &ch, 1); X return(255 & (int)ch); X#endif X#if VMS X int status; X int iosb[2]; X int term[2]; X X while (ibufi >= nibuf) { X ibufi = 0; X term[0] = 0; X term[1] = 0; X status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED, X iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0); X if (status != SS$_NORMAL) X exit(status); X status = iosb[0] & 0xFFFF; X if (status!=SS$_NORMAL && status!=SS$_TIMEOUT) X exit(status); X nibuf = (iosb[0]>>16) + (iosb[1]>>16); X if (nibuf == 0) { X status = SYS$QIOW(EFN, iochan, IO$_READLBLK, X iosb, 0, 0, ibuf, 1, 0, term, 0, 0); X if (status != SS$_NORMAL X || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL) X exit(status); X nibuf = (iosb[0]>>16) + (iosb[1]>>16); X } X } X return (ibuf[ibufi++] & 0xFF); /* Allow multinational */ X#endif X X#if CPM X return (biosb(BCONIN, 0, 0)); X#endif X X#if RAINBOW X int Ch; X X while ((Ch = Read_Keyboard()) < 0); X X if ((Ch & Function_Key) == 0) X if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177)) X Ch &= 0xFF; X X return Ch; X#endif X X#if MSDOS & MWC86 X return (dosb(CONRAW, 0, 0)); X#endif X X#if MSDOS & (LATTICE | MSC) X int c; /* character read */ X X /* if a char already is ready, return it */ X if (nxtchar >= 0) { X c = nxtchar; X nxtchar = -1; X return(c); X } X X /* call the dos to get a char */ X rg.h.ah = 7; /* dos Direct Console Input call */ X intdos(&rg, &rg); X c = rg.h.al; /* grab the char */ X return(c & 255); X#endif X X#if MSDOS & AZTEC X int c; /* character read */ X X /* if a char already is ready, return it */ X if (nxtchar >= 0) { X c = nxtchar; X nxtchar = -1; X return(c); X } X X /* call the dos to get a char */ X rg.h.ah = 7; /* dos Direct Console I/O call */ X sysint(33, &rg, &rg); X c = rg.h.al; /* grab the char */ X return(c & 255); X#endif X X#if V7 | USG | BSD X return(127 & fgetc(stdin)); X#endif X} X X#if TYPEAH X/* typahead: Check to see if any characters are already in the X keyboard buffer X*/ X Xtypahead() X X{ X#if MSDOS & (LATTICE | AZTEC) X int c; /* character read */ X int flags; /* cpu flags from dos call */ X X#if MSC X if (kbhit() != 0) X return(TRUE); X else X return(FALSE); X#endif X X if (nxtchar >= 0) X return(TRUE); X X rg.h.ah = 6; /* Direct Console I/O call */ X rg.h.dl = 255; /* does console input */ X#if LATTICE X flags = intdos(&rg, &rg); X#else X flags = sysint(33, &rg, &rg); X#endif X c = rg.h.al; /* grab the character */ X X /* no character pending */ X if ((flags & 64) != 0) X return(FALSE); X X /* save the character and return true */ X nxtchar = c; X return(TRUE); X#endif X X#if BSD X int x; /* holds # of pending chars */ X X return((ioctl(0,FIONREAD,&x) < 0) ? 0 : x); X#endif X return(FALSE); X} X#endif X FRIDAY_NIGHT echo extracting - vmsvt.c sed 's/^X//' > vmsvt.c << 'FRIDAY_NIGHT' X/* X * VMS terminal handling routines X * X * Known types are: X * VT52, VT100, and UNKNOWN (which is defined to be an ADM3a) X * written by Curtis Smith X */ X X#include X#include "estruct.h" X#include "edef.h" X X#if VMSVT X X#define termdef 1 /* don't define "term" external */ X X#include /* Status code definitions */ X#include /* Descriptor structures */ X#include /* IO commands */ X#include /* tty commands */ X Xextern int ttopen(); /* Forward references. */ Xextern int ttgetc(); Xextern int ttputc(); Xextern int ttflush(); Xextern int ttclose(); Xextern int vmsopen(); Xextern int vmseeol(); Xextern int vmseeop(); Xextern int vmsbeep(); Xextern int vmsmove(); Xextern int vmsrev(); Xextern int eolexist; X#if COLOR Xextern int vmsfcol(); Xextern int vmsbcol(); X#endif X X#define NROWS 24 /* # of screen rolls */ X#define NCOLS 80 /* # of screen columns */ X#define MARGIN 8 /* size of minimim margin and */ X#define SCRSIZ 64 /* scroll size for extended lines */ X#define NPAUSE 100 /* # times thru update to pause */ X X/* X * Dispatch table. All the X * hard fields just point into the X * terminal I/O code. X */ XTERM term = { X NROWS - 1, X NCOLS, X MARGIN, X SCRSIZ, X NPAUSE, X &vmsopen, X &ttclose, X &ttgetc, X &ttputc, X &ttflush, X &vmsmove, X &vmseeol, X &vmseeop, X &vmsbeep, X &vmsrev X#if COLOR X , &vmsfcol, X &vmsbcol X#endif X}; X Xchar * termeop; /* Erase to end of page string */ Xint eoppad; /* Number of pad characters after eop */ Xchar * termeol; /* Erase to end of line string */ Xint eolpad; /* Number of pad characters after eol */ Xchar termtype; /* Terminal type identifier */ X X X/******* X * ttputs - Send a string to ttputc X *******/ X Xttputs(string) Xchar * string; X{ X while (*string != '\0') X ttputc(*string++); X} X X X/******* X * vmspad - Pad the output after an escape sequence X *******/ X Xvmspad(count) Xint count; X{ X while (count-- > 0) X ttputc('\0'); X} X X X/******* X * vmsmove - Move the cursor X *******/ X Xvmsmove(row, col) X{ X switch (termtype) { X case TT$_UNKNOWN: X ttputc('\033'); X ttputc('='); X ttputc(row+' '); X ttputc(col+' '); X break; X case TT$_VT52: X ttputc('\033'); X ttputc('Y'); X ttputc(row+' '); X ttputc(col+' '); X break; X case TT$_VT100: /* I'm assuming that all these */ X case TT$_VT101: /* are a super set of the VT100 */ X case TT$_VT102: /* If I'm wrong, just remove */ X case TT$_VT105: /* those entries that aren't. */ X case TT$_VT125: X case TT$_VT131: X case TT$_VT132: X case TT$_VT200_SERIES: X { X char buffer[24]; X X sprintf(buffer, "\033[%d;%dH", row+1, col+1); X ttputs(buffer); X vmspad(50); X } X } X} X X/******* X * vmsrev - set the reverse video status X *******/ X Xvmsrev(status) X Xint status; /* TRUE = reverse video, FALSE = normal video */ X{ X switch (termtype) { X case TT$_UNKNOWN: X break; X case TT$_VT52: X break; X case TT$_VT100: X if (status) { X ttputc('\033'); X ttputc('['); X ttputc('7'); X ttputc('m'); X } else { X ttputc('\033'); X ttputc('['); X ttputc('m'); X } X break; X } X} X X#if COLOR X/******* X * vmsfcol - Set the forground color (not implimented) X *******/ X Xvmsfcol() X{ X} X X/******* X * vmsbcol - Set the background color (not implimented) X *******/ X Xvmsbcol() X{ X} X#endif X X/******* X * vmseeol - Erase to end of line X *******/ X Xvmseeol() X{ X ttputs(termeol); X vmspad(eolpad); X} X X X/******* X * vmseeop - Erase to end of page (clear screen) X *******/ X Xvmseeop() X{ X ttputs(termeop); X vmspad(eoppad); X} X X X/******* X * vmsbeep - Ring the bell X *******/ X Xvmsbeep() X{ X ttputc('\007'); X} X X X/******* X * vmsopen - Get terminal type and open terminal X *******/ X Xvmsopen() X{ X termtype = vmsgtty(); X switch (termtype) { X case TT$_UNKNOWN: /* Assume ADM3a */ X eolexist = FALSE; X termeop = "\032"; X eoppad = 0; X break; X case TT$_VT52: X termeol = "\033K"; X eolpad = 0; X termeop = "\033H\033J"; X eoppad = 0; X break; X case TT$_VT100: X revexist = TRUE; X termeol = "\033[K"; X eolpad = 3; X termeop = "\033[;H\033[2J"; X eoppad = 50; X break; X default: X puts("Terminal type not supported"); X exit (SS$_NORMAL); X } X ttopen(); X} X X Xstruct iosb { /* I/O status block */ X short i_cond; /* Condition value */ X short i_xfer; /* Transfer count */ X long i_info; /* Device information */ X}; X Xstruct termchar { /* Terminal characteristics */ X char t_class; /* Terminal class */ X char t_type; /* Terminal type */ X short t_width; /* Terminal width in characters */ X long t_mandl; /* Terminal's mode and length */ X long t_extend; /* Extended terminal characteristics */ X}; X X/******* X * vmsgtty - Get terminal type from system control block X *******/ X Xvmsgtty() X{ X short fd; X int status; X struct iosb iostatus; X struct termchar tc; X $DESCRIPTOR(devnam, "SYS$INPUT"); X X status = sys$assign(&devnam, &fd, 0, 0); X if (status != SS$_NORMAL) X exit (status); X X status = sys$qiow( /* Queue and wait */ X 0, /* Wait on event flag zero */ X fd, /* Channel to input terminal */ X IO$_SENSEMODE, /* Get current characteristic */ X &iostatus, /* Status after operation */ X 0, 0, /* No AST service */ X &tc, /* Terminal characteristics buf */ X sizeof(tc), /* Size of the buffer */ X 0, 0, 0, 0); /* P3-P6 unused */ X X /* De-assign the input device */ X if (sys$dassgn(fd) != SS$_NORMAL) X exit(status); X X if (status != SS$_NORMAL) /* Jump out if bad status */ X exit(status); X if (iostatus.i_cond != SS$_NORMAL) X exit(iostatus.i_cond); X X return tc.t_type; /* Return terminal type */ X} X X#else X Xhellovms() X X{ X} X X#endif VMSVT FRIDAY_NIGHT echo extracting - vt52.c sed 's/^X//' > vt52.c << 'FRIDAY_NIGHT' X/* X * The routines in this file X * provide support for VT52 style terminals X * over a serial line. The serial I/O services are X * provided by routines in "termio.c". It compiles X * into nothing if not a VT52 style device. The X * bell on the VT52 is terrible, so the "beep" X * routine is conditionalized on defining BEL. X */ X#define termdef 1 /* don't define "term" external */ X X#include X#include "estruct.h" X#include "edef.h" X X#if VT52 X X#define NROW 24 /* 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 100 /* # times thru update to pause */ X#define BIAS 0x20 /* Origin 0 coordinate bias. */ X#define ESC 0x1B /* ESC character. */ X#define BEL 0x07 /* ascii bell character */ X Xextern int ttopen(); /* Forward references. */ Xextern int ttgetc(); Xextern int ttputc(); Xextern int ttflush(); Xextern int ttclose(); Xextern int vt52move(); Xextern int vt52eeol(); Xextern int vt52eeop(); Xextern int vt52beep(); Xextern int vt52open(); Xextern int vt52rev(); X#if COLOR Xextern int vt52fcol(); Xextern int vt52bcol(); 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 NCOL, X MARGIN, X SCRSIZ, X NPAUSE, X &vt52open, X &ttclose, X &ttgetc, X &ttputc, X &ttflush, X &vt52move, X &vt52eeol, X &vt52eeop, X &vt52beep, X &vt52rev X#if COLOR X , &vt52fcol, X &vt52bcol X#endif X}; X Xvt52move(row, col) X{ X ttputc(ESC); X ttputc('Y'); X ttputc(row+BIAS); X ttputc(col+BIAS); X} X Xvt52eeol() X{ X ttputc(ESC); X ttputc('K'); X} X Xvt52eeop() X{ X ttputc(ESC); X ttputc('J'); X} X Xvt52rev(status) /* set the reverse video state */ X Xint status; /* TRUE = reverse video, FALSE = normal video */ X X{ X /* can't do this here, so we won't */ X} X X#if COLOR Xvt52fcol() /* set the forground color [NOT IMPLIMENTED] */ X{ X} X Xvt52bcol() /* set the background color [NOT IMPLIMENTED] */ X{ X} X#endif X Xvt52beep() X{ X#ifdef BEL X ttputc(BEL); X ttflush(); X#endif X} X X#endif X Xvt52open() X{ X#if V7 | BSD X register char *cp; X char *getenv(); X X if ((cp = getenv("TERM")) == NULL) { X puts("Shell variable TERM not defined!"); X exit(1); X } X if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) { X puts("Terminal type not 'vt52'or 'z19' !"); X exit(1); X } X#endif X ttopen(); X} FRIDAY_NIGHT echo extracting - window.c sed 's/^X//' > window.c << 'FRIDAY_NIGHT' X/* X * Window management. Some of the functions are internal, and some are X * attached to keys that the user actually types. X */ X X#include X#include "estruct.h" X#include "edef.h" X X/* X * Reposition dot in the current window to line "n". If the argument is X * positive, it is that line. If it is negative it is that line from the X * bottom. If it is 0 the window is centered (this is what the standard X * redisplay code does). With no argument it defaults to 0. Bound to M-!. X */ Xreposition(f, n) X { X if (f == FALSE) /* default to 0 to center screen */ X n = 0; X curwp->w_force = n; X curwp->w_flag |= WFFORCE; X return (TRUE); X } X X/* X * Refresh the screen. With no argument, it just does the refresh. With an X * argument it recenters "." in the current window. Bound to "C-L". X */ Xrefresh(f, n) X { X if (f == FALSE) X sgarbf = TRUE; X else X { X curwp->w_force = 0; /* Center dot. */ X curwp->w_flag |= WFFORCE; X } X X return (TRUE); X } X X/* X * The command make the next window (next => down the screen) the current X * window. There are no real errors, although the command does nothing if X * there is only 1 window on the screen. Bound to "C-X C-N". X * X * with an argument this command finds the th window from the top X * X */ Xnextwind(f, n) X Xint f, n; /* default flag and numeric argument */ X X{ X register WINDOW *wp; X register int nwindows; /* total number of windows */ X X if (f) { X X /* first count the # of windows */ X wp = wheadp; X nwindows = 1; X while (wp->w_wndp != NULL) { X nwindows++; X wp = wp->w_wndp; X } X X /* if the argument is negative, it is the nth window X from the bottom of the screen */ X if (n < 0) X n = nwindows + n + 1; X X /* if an argument, give them that window from the top */ X if (n > 0 && n <= nwindows) { X wp = wheadp; X while (--n) X wp = wp->w_wndp; X } else { X mlwrite("Window number out of range"); X return(FALSE); X } X } else X if ((wp = curwp->w_wndp) == NULL) X wp = wheadp; X curwp = wp; X curbp = wp->w_bufp; X upmode(); X return (TRUE); X} X X/* X * This command makes the previous window (previous => up the screen) the X * current window. There arn't any errors, although the command does not do a X * lot if there is 1 window. X */ Xprevwind(f, n) X{ X register WINDOW *wp1; X register WINDOW *wp2; X register int nwindows; /* total # of windows */ X X /* if we have an argument, we mean the nth window from the bottom */ X if (f) X return(nextwind(f, -n)); X X wp1 = wheadp; X wp2 = curwp; X X if (wp1 == wp2) X wp2 = NULL; X X while (wp1->w_wndp != wp2) X wp1 = wp1->w_wndp; X X curwp = wp1; X curbp = wp1->w_bufp; X upmode(); X return (TRUE); X} X X/* X * This command moves the current window down by "arg" lines. Recompute the X * top line in the window. The move up and move down code is almost completely X * the same; most of the work has to do with reframing the window, and picking X * a new dot. We share the code by having "move down" just be an interface to X * "move up". Magic. Bound to "C-X C-N". X */ Xmvdnwind(f, n) X int n; X { X return (mvupwind(f, -n)); X } X X/* X * Move the current window up by "arg" lines. Recompute the new top line of X * the window. Look to see if "." is still on the screen. If it is, you win. X * If it isn't, then move "." to center it in the new framing of the window X * (this command does not really move "."; it moves the frame). Bound to X * "C-X C-P". X */ Xmvupwind(f, n) X int n; X { X register LINE *lp; X register int i; X X lp = curwp->w_linep; X X if (n < 0) X { X while (n++ && lp!=curbp->b_linep) X lp = lforw(lp); X } X else X { X while (n-- && lback(lp)!=curbp->b_linep) X lp = lback(lp); X } X X curwp->w_linep = lp; X curwp->w_flag |= WFHARD; /* Mode line is OK. */ X X for (i = 0; i < curwp->w_ntrows; ++i) X { X if (lp == curwp->w_dotp) X return (TRUE); X if (lp == curbp->b_linep) X break; X lp = lforw(lp); X } X X lp = curwp->w_linep; X i = curwp->w_ntrows/2; X X while (i-- && lp != curbp->b_linep) X lp = lforw(lp); X X curwp->w_dotp = lp; X curwp->w_doto = 0; X return (TRUE); X } X X/* X * This command makes the current window the only window on the screen. Bound X * to "C-X 1". Try to set the framing so that "." does not have to move on the X * display. Some care has to be taken to keep the values of dot and mark in X * the buffer structures right if the distruction of a window makes a buffer X * become undisplayed. X */ Xonlywind(f, n) X{ X register WINDOW *wp; X register LINE *lp; X register int i; X X while (wheadp != curwp) { X wp = wheadp; X wheadp = wp->w_wndp; X if (--wp->w_bufp->b_nwnd == 0) { X wp->w_bufp->b_dotp = wp->w_dotp; X wp->w_bufp->b_doto = wp->w_doto; X wp->w_bufp->b_markp = wp->w_markp; X wp->w_bufp->b_marko = wp->w_marko; X } X free((char *) wp); X } X while (curwp->w_wndp != NULL) { X wp = curwp->w_wndp; X curwp->w_wndp = wp->w_wndp; X if (--wp->w_bufp->b_nwnd == 0) { X wp->w_bufp->b_dotp = wp->w_dotp; X wp->w_bufp->b_doto = wp->w_doto; X wp->w_bufp->b_markp = wp->w_markp; X wp->w_bufp->b_marko = wp->w_marko; X } X free((char *) wp); X } X lp = curwp->w_linep; X i = curwp->w_toprow; X while (i!=0 && lback(lp)!=curbp->b_linep) { X --i; X lp = lback(lp); X } X curwp->w_toprow = 0; X curwp->w_ntrows = term.t_nrow-1; X curwp->w_linep = lp; X curwp->w_flag |= WFMODE|WFHARD; X return (TRUE); X} X X/* X * Delete the current window, placing its space in the window above, X * or, if it is the top window, the window below. Bound to C-X 0. X */ X Xdelwind(f,n) X Xint f, n; /* arguments are ignored for this command */ X X{ X register WINDOW *wp; /* window to recieve deleted space */ X register WINDOW *lwp; /* ptr window before curwp */ X register int target; /* target line to search for */ X X /* if there is only one window, don't delete it */ X if (wheadp->w_wndp == NULL) { X mlwrite("Can not delete this window"); X return(FALSE); X } X X /* find window before curwp in linked list */ X wp = wheadp; X lwp = NULL; X while (wp != NULL) { X if (wp == curwp) X break; X lwp = wp; X wp = wp->w_wndp; X } X X /* find recieving window and give up our space */ X wp = wheadp; X if (curwp->w_toprow == 0) { X /* find the next window down */ X target = curwp->w_ntrows + 1; X while (wp != NULL) { X if (wp->w_toprow == target) X break; X wp = wp->w_wndp; X } X if (wp == NULL) X return(FALSE); X wp->w_toprow = 0; X wp->w_ntrows += target; X } else { X /* find the next window up */ X target = curwp->w_toprow - 1; X while (wp != NULL) { X if ((wp->w_toprow + wp->w_ntrows) == target) X break; X wp = wp->w_wndp; X } X if (wp == NULL) X return(FALSE); X wp->w_ntrows += 1 + curwp->w_ntrows; X } X X /* get rid of the current window */ X if (--curwp->w_bufp->b_nwnd == 0) { X curwp->w_bufp->b_dotp = curwp->w_dotp; X curwp->w_bufp->b_doto = curwp->w_doto; X curwp->w_bufp->b_markp = curwp->w_markp; X curwp->w_bufp->b_marko = curwp->w_marko; X } X if (lwp == NULL) X wheadp = curwp->w_wndp; X else X lwp->w_wndp = curwp->w_wndp; X free((char *)curwp); X curwp = wp; X wp->w_flag |= WFHARD; X curbp = wp->w_bufp; X upmode(); X return(TRUE); X} X X/* X XSplit the current window. A window smaller than 3 lines cannot be Xsplit. An argument of 1 forces the cursor into the upper window, an Xargument of two forces the cursor to the lower window. The only other Xerror that is possible is a "malloc" failure allocating the structure Xfor the new window. Bound to "C-X 2". X X */ Xsplitwind(f, n) X Xint f, n; /* default flag and numeric argument */ X X{ X register WINDOW *wp; X register LINE *lp; X register int ntru; X register int ntrl; X register int ntrd; X register WINDOW *wp1; X register WINDOW *wp2; X char *malloc(); X X if (curwp->w_ntrows < 3) { X mlwrite("Cannot split a %d line window", curwp->w_ntrows); X return (FALSE); X } X if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) { X mlwrite("Cannot allocate WINDOW block"); X return (FALSE); X } X ++curbp->b_nwnd; /* Displayed twice. */ X wp->w_bufp = curbp; X wp->w_dotp = curwp->w_dotp; X wp->w_doto = curwp->w_doto; X wp->w_markp = curwp->w_markp; X wp->w_marko = curwp->w_marko; X wp->w_flag = 0; X wp->w_force = 0; X#if COLOR X /* set the colors of the new window */ X wp->w_fcolor = gfcolor; X wp->w_bcolor = gbcolor; X#endif X ntru = (curwp->w_ntrows-1) / 2; /* Upper size */ X ntrl = (curwp->w_ntrows-1) - ntru; /* Lower size */ X lp = curwp->w_linep; X ntrd = 0; X while (lp != curwp->w_dotp) { X ++ntrd; X lp = lforw(lp); X } X lp = curwp->w_linep; X if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) { X /* Old is upper window. */ X if (ntrd == ntru) /* Hit mode line. */ X lp = lforw(lp); X curwp->w_ntrows = ntru; X wp->w_wndp = curwp->w_wndp; X curwp->w_wndp = wp; X wp->w_toprow = curwp->w_toprow+ntru+1; X wp->w_ntrows = ntrl; X } else { /* Old is lower window */ X wp1 = NULL; X wp2 = wheadp; X while (wp2 != curwp) { X wp1 = wp2; X wp2 = wp2->w_wndp; X } X if (wp1 == NULL) X wheadp = wp; X else X wp1->w_wndp = wp; X wp->w_wndp = curwp; X wp->w_toprow = curwp->w_toprow; X wp->w_ntrows = ntru; X ++ntru; /* Mode line. */ X curwp->w_toprow += ntru; X curwp->w_ntrows = ntrl; X while (ntru--) X lp = lforw(lp); X } X curwp->w_linep = lp; /* Adjust the top lines */ X wp->w_linep = lp; /* if necessary. */ X curwp->w_flag |= WFMODE|WFHARD; X wp->w_flag |= WFMODE|WFHARD; X return (TRUE); X} X X/* X * Enlarge the current window. Find the window that loses space. Make sure it X * is big enough. If so, hack the window descriptions, and ask redisplay to do X * all the hard work. You don't just set "force reframe" because dot would X * move. Bound to "C-X Z". X */ Xenlargewind(f, n) X{ X register WINDOW *adjwp; X register LINE *lp; X register int i; X X if (n < 0) X return (shrinkwind(f, -n)); X if (wheadp->w_wndp == NULL) { X mlwrite("Only one window"); X return (FALSE); X } X if ((adjwp=curwp->w_wndp) == NULL) { X adjwp = wheadp; X while (adjwp->w_wndp != curwp) X adjwp = adjwp->w_wndp; X } X if (adjwp->w_ntrows <= n) { X mlwrite("Impossible change"); X return (FALSE); X } X if (curwp->w_wndp == adjwp) { /* Shrink below. */ X lp = adjwp->w_linep; X for (i=0; iw_bufp->b_linep; ++i) X lp = lforw(lp); X adjwp->w_linep = lp; X adjwp->w_toprow += n; X } else { /* Shrink above. */ X lp = curwp->w_linep; X for (i=0; ib_linep; ++i) X lp = lback(lp); X curwp->w_linep = lp; X curwp->w_toprow -= n; X } X curwp->w_ntrows += n; X adjwp->w_ntrows -= n; X curwp->w_flag |= WFMODE|WFHARD; X adjwp->w_flag |= WFMODE|WFHARD; X return (TRUE); X} X X/* X * Shrink the current window. Find the window that gains space. Hack at the X * window descriptions. Ask the redisplay to do all the hard work. Bound to X * "C-X C-Z". X */ Xshrinkwind(f, n) X{ X register WINDOW *adjwp; X register LINE *lp; X register int i; X X if (n < 0) X return (enlargewind(f, -n)); X if (wheadp->w_wndp == NULL) { X mlwrite("Only one window"); X return (FALSE); X } X if ((adjwp=curwp->w_wndp) == NULL) { X adjwp = wheadp; X while (adjwp->w_wndp != curwp) X adjwp = adjwp->w_wndp; X } X if (curwp->w_ntrows <= n) { X mlwrite("Impossible change"); X return (FALSE); X } X if (curwp->w_wndp == adjwp) { /* Grow below. */ X lp = adjwp->w_linep; X for (i=0; iw_bufp->b_linep; ++i) X lp = lback(lp); X adjwp->w_linep = lp; X adjwp->w_toprow -= n; X } else { /* Grow above. */ X lp = curwp->w_linep; X for (i=0; ib_linep; ++i) X lp = lforw(lp); X curwp->w_linep = lp; X curwp->w_toprow += n; X } X curwp->w_ntrows -= n; X adjwp->w_ntrows += n; X curwp->w_flag |= WFMODE|WFHARD; X adjwp->w_flag |= WFMODE|WFHARD; X return (TRUE); X} X X/* Resize the current window to the requested size */ X Xresize(f, n) X Xint f, n; /* default flag and numeric argument */ X X{ X int clines; /* current # of lines in window */ X X /* must have a non-default argument, else ignore call */ X if (f == FALSE) X return(TRUE); X X /* find out what to do */ X clines = curwp->w_ntrows; X X /* already the right size? */ X if (clines == n) X return(TRUE); X X return(enlargewind(TRUE, n - clines)); X} X X/* X * Pick a window for a pop-up. Split the screen if there is only one window. X * Pick the uppermost window that isn't the current window. An LRU algorithm X * might be better. Return a pointer, or NULL on error. X */ XWINDOW * Xwpopup() X{ X register WINDOW *wp; X X if (wheadp->w_wndp == NULL /* Only 1 window */ X && splitwind(FALSE, 0) == FALSE) /* and it won't split */ X return (NULL); X wp = wheadp; /* Find window to use */ X while (wp!=NULL && wp==curwp) X wp = wp->w_wndp; X return (wp); X} X Xscrnextup(f, n) /* scroll the next window up (back) a page */ X X{ X nextwind(FALSE, 1); X backpage(f, n); X prevwind(FALSE, 1); X} X Xscrnextdw(f, n) /* scroll the next window down (forward) a page */ X X{ X nextwind(FALSE, 1); X forwpage(f, n); X prevwind(FALSE, 1); X} X Xsavewnd(f, n) /* save ptr to current window */ X X{ X swindow = curwp; X return(TRUE); X} X Xrestwnd(f, n) /* restore the saved screen */ X X{ X register WINDOW *wp; X X /* find the window */ X wp = wheadp; X while (wp != NULL) { X if (wp == swindow) { X curwp = wp; X curbp = wp->w_bufp; X upmode(); X return (TRUE); X } X wp = wp->w_wndp; X } X X mlwrite("[No such window exists]"); X return(FALSE); X} FRIDAY_NIGHT echo es.11 completed! : That's all folks!