irf@kuling.UUCP (Stellan Bergman) (09/23/87)
The following file was included in a distribution of uemacs I got hold of through EUUG. Claims to work notwithstanding, this file does not compile on a Sys V.2 (HP-UX 5.11) system who says it's V7 backward compatible. As always, the problems are caused by cryptic BSD-isms. Does there exist such a thing as a Sys V.2 acceptable version of this file. If so, please mail it to me or post it to the net. In order to facilitate easy editing for those who know how, here follows a listing of 'termio.c' from the 'uemacs' I have with my comments included within /*====== type comment blocks: * ======*/ ------------------------------------------------------------------------ /* * The functions in this file negotiate with the operating system for * characters, and write characters in a barely buffered fashion on the display. * All operating systems. */ #include <stdio.h> #include "ed.h" #if AMIGA #define NEW 1006 #define LEN 1 static long terminal; #endif #if VMS #include <stsdef.h> #include <ssdef.h> #include <descrip.h> #include <iodef.h> #include <ttdef.h> #define NIBUF 128 /* Input buffer size */ #define NOBUF 1024 /* MM says bug buffers win! */ #define EFN 0 /* Event flag */ char obuf[NOBUF]; /* Output buffer */ int nobuf; /* # of bytes in above */ char ibuf[NIBUF]; /* Input buffer */ int nibuf; /* # of bytes in above */ int ibufi; /* Read index */ int oldmode[2]; /* Old TTY mode bits */ int newmode[2]; /* New TTY mode bits */ short iochan; /* TTY I/O channel */ #endif #if CPM #include <bdos.h> #endif #if MSDOS #undef LATTICE #include <dos.h> #endif #if RAINBOW #include "rainbow.h" #endif #if V7 #include <sgtty.h> /* for stty/gtty functions */ struct sgttyb ostate; /* saved tty state */ struct sgttyb nstate; /* values for editor mode */ struct tchars otchars; struct tchars ntchars; struct ltchars oltchars; struct ltchars nltchars; int olmode; int nlmode; #endif /* * This function is called once to set up the terminal device streams. * On VMS, it translates SYS$INPUT until it finds the terminal, then assigns * a channel to it and sets it raw. On CPM it is a no-op. */ ttopen() { #if AMIGA terminal = Open("RAW:1/1/639/199/MicroEmacs", NEW); #endif #if VMS struct dsc$descriptor idsc; struct dsc$descriptor odsc; char oname[40]; int iosb[2]; int status; odsc.dsc$a_pointer = "SYS$INPUT"; odsc.dsc$w_length = strlen(odsc.dsc$a_pointer); odsc.dsc$b_dtype = DSC$K_DTYPE_T; odsc.dsc$b_class = DSC$K_CLASS_S; idsc.dsc$b_dtype = DSC$K_DTYPE_T; idsc.dsc$b_class = DSC$K_CLASS_S; do { idsc.dsc$a_pointer = odsc.dsc$a_pointer; idsc.dsc$w_length = odsc.dsc$w_length; odsc.dsc$a_pointer = &oname[0]; odsc.dsc$w_length = sizeof(oname); status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc); if (status!=SS$_NORMAL && status!=SS$_NOTRAN) exit(status); if (oname[0] == 0x1B) { odsc.dsc$a_pointer += 4; odsc.dsc$w_length -= 4; } } while (status == SS$_NORMAL); status = SYS$ASSIGN(&odsc, &iochan, 0, 0); if (status != SS$_NORMAL) exit(status); status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0, oldmode, sizeof(oldmode), 0, 0, 0, 0); if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) exit(status); newmode[0] = oldmode[0]; newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO; 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) exit(status); #endif #if CPM #endif #if MSDOS #endif #if V7 gtty(0, &ostate); /* save old state */ nstate = ostate; /* get base of new state */ nstate.sg_flags |= CBREAK; nstate.sg_flags &= ~(ECHO | CRMOD | XTABS); ioctl (0, TIOCGETC, &otchars); ntchars = otchars; ioctl (0, TIOCGLTC, &oltchars); nltchars = oltchars; ioctl (0, TIOCLGET, &olmode); nlmode = olmode; ntchars.t_intrc = -1; ntchars.t_quitc = -1; ntchars.t_startc = 021; ntchars.t_stopc = 023; ntchars.t_eofc = -1; ntchars.t_brkc = -1; nltchars.t_suspc = -1; nltchars.t_dsuspc = -1; nltchars.t_rprntc = -1; nltchars.t_flushc = -1; nltchars.t_werasc = -1; nltchars.t_lnextc = -1; stty(0, &nstate); /* set mode */ ioctl (0, TIOCSETC, &ntchars); ioctl (0, TIOCSLTC, &nltchars); ioctl (0, TIOCLSET, &nlmode); #endif } /* * This function gets called just before we go back home to the command * interpreter. On VMS it puts the terminal back in a reasonable state. * Another no-operation on CPM. */ ttclose() { #if AMIGA Close(terminal); #endif #if VMS int status; int iosb[1]; ttflush(); 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) exit(status); status = SYS$DASSGN(iochan); if (status != SS$_NORMAL) exit(status); #endif #if CPM #endif #if MSDOS #endif #if V7 stty(0, &ostate); /* set mode */ ioctl (0, TIOCSETC, &otchars); ioctl (0, TIOCSLTC, &oltchars); ioctl (0, TIOCLSET, &olmode); fflush(stdout); #endif } /* * Write a character to the display. On VMS, terminal output is buffered, and * we just put the characters in the big array, after checking for overflow. * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on * MS-DOS (use the very very raw console output routine). */ ttputc(c) #if AMIGA char c; #endif { #if AMIGA Write(terminal, &c, LEN); #endif #if VMS if (nobuf >= NOBUF) ttflush(); obuf[nobuf++] = c; #endif #if CPM bios(BCONOUT, c, 0); #endif #if MSDOS & CWC86 dosb(CONDIO, c, 0); #endif #if RAINBOW Put_Char(c); /* fast video */ #endif #if V7 fputc(c, stdout); #endif } /* * Flush terminal buffer. Does real work where the terminal output is buffered * up. A no-operation on systems where byte at a time terminal I/O is done. */ ttflush() { #if AMIGA #endif #if VMS int status; int iosb[2]; status = SS$_NORMAL; if (nobuf != 0) { status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT, iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0); if (status == SS$_NORMAL) status = iosb[0] & 0xFFFF; nobuf = 0; } return (status); #endif #if CPM #endif #if MSDOS #endif #if V7 fflush(stdout); #endif } /* * Read a character from the terminal, performing no editing and doing no echo * at all. More complex in VMS that almost anyplace else, which figures. Very * simple on CPM, because the system can do exactly what you want. */ ttgetc() { #if AMIGA char ch; Read(terminal, &ch, LEN); return (int) ch; #endif #if VMS int status; int iosb[2]; int term[2]; while (ibufi >= nibuf) { ibufi = 0; term[0] = 0; term[1] = 0; status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED, iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0); if (status != SS$_NORMAL) exit(status); status = iosb[0] & 0xFFFF; if (status!=SS$_NORMAL && status!=SS$_TIMEOUT) exit(status); nibuf = (iosb[0]>>16) + (iosb[1]>>16); if (nibuf == 0) { status = SYS$QIOW(EFN, iochan, IO$_READLBLK, iosb, 0, 0, ibuf, 1, 0, term, 0, 0); if (status != SS$_NORMAL || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL) exit(status); nibuf = (iosb[0]>>16) + (iosb[1]>>16); } } return (ibuf[ibufi++] & 0xFF); /* Allow multinational */ #endif #if CPM return (biosb(BCONIN, 0, 0)); #endif #if RAINBOW int Ch; while ((Ch = Read_Keyboard()) < 0); if ((Ch & Function_Key) == 0) if (!((Ch & 0xFF) == 015 || (Ch & 0xFF) == 0177)) Ch &= 0xFF; return Ch; #endif #if MSDOS & MWC86 return (dosb(CONRAW, 0, 0)); #endif #if V7 return(fgetc(stdin)); #endif }