|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T t ┃
Length: 5151 (0x141f) Types: TextFile Names: »ttyio.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/micrognu/sys/sysv/ttyio.c«
/* * Name: MicroEMACS * System V terminal I/O. * Version: 0 * Last edit: Tue Aug 26 23:57:57 PDT 1986 * By: gonzo!daveb * {sun, amdahl, mtxinu}!rtech!gonzo!daveb * * The functions in this file * negotiate with the operating system for * keyboard characters, and write characters to * the display in a barely buffered fashion. * * This version goes along with tty/termcap/tty.c. * Terminal size is determined there, rather than here, and * this does not open the termcap file */ #include "def.h" #include <sys/types.h> #include <fcntl.h> #include <termio.h> #define NOBUF 512 /* Output buffer size. */ char obuf[NOBUF]; /* Output buffer. */ int nobuf; /* buffer count */ static struct termio ot; /* entry state of the terminal */ static struct termio nt; /* editor's terminal state */ static int ttyactivep = FALSE; /* terminal in editor mode? */ static int ttysavedp = FALSE; /* terminal state saved? */ int nrow; /* Terminal size, rows. */ int ncol; /* Terminal size, columns. */ /* These are used to implement typeahead on System V */ int kbdflgs; /* saved keyboard fd flags */ int kbdpoll; /* in O_NDELAY mode */ int kbdqp; /* there is a char in kbdq */ char kbdq; /* char we've already read */ /* * This function gets called once, to set up * the terminal channel. This version turns off flow * control. This may be wrong for your system, but no * good solution has really been found (daveb). */ ttopen() { register char *cp; extern char *getenv(); if (ttyactivep) return; if( !ttysavedp ) { if (ioctl(0, TCGETA, &ot) < 0) abort(); nt = ot; /* save entry state */ nt.c_cc[VMIN] = 1; /* one character read is OK */ nt.c_cc[VTIME] = 0; /* Never time out. */ nt.c_iflag |= IGNBRK; nt.c_iflag &= ~( ICRNL | INLCR | ISTRIP | IXON | IXOFF ); nt.c_oflag &= ~OPOST; nt.c_cflag |= CS8; /* allow 8th bit on input */ nt.c_cflag &= ~PARENB; /* Don't check parity */ nt.c_lflag &= ~( ECHO | ICANON | ISIG ); kbdflgs = fcntl( 0, F_GETFL, 0 ); kbdpoll = FALSE; ttysavedp = TRUE; } if (ioctl(0, TCSETAF, &nt) < 0) abort(); /* This really belongs in tty/termcap... */ if ((cp=getenv("TERMCAP")) == NULL || (nrow=getvalue(cp, "li")) <= 0 || (ncol=getvalue(cp, "co")) <= 0) { nrow = 24; ncol = 80; } if (nrow > NROW) /* Don't crash if the */ nrow = NROW; /* termcap entry is */ if (ncol > NCOL) /* too big. */ ncol = NCOL; ttyactivep = TRUE; } /* * This routine scans a string, which is * actually the return value of a getenv call for the TERMCAP * variable, looking for numeric parameter "name". Return the value * if found. Return -1 if not there. Assume that "name" is 2 * characters long. This limited use of the TERMCAP lets us find * out the size of a window on the X display. */ getvalue(cp, name) register char *cp; register char *name; { for (;;) { while (*cp!=0 && *cp!=':') ++cp; if (*cp++ == 0) /* Not found. */ return (-1); if (cp[0]==name[0] && cp[1]==name[1] && cp[2]=='#') return (atoi(cp+3)); /* Stops on ":". */ } } /* * This function gets called just * before we go back home to the shell. Put all of * the terminal parameters back. */ ttclose() { if(!ttysavedp || !ttyactivep) return; ttflush(); if (ioctl(0, TCSETAF, &ot) < 0 || fcntl( 0, F_SETFL, kbdflgs ) < 0) abort(); ttyactivep = FALSE; } /* * Write character to the display. * Characters are buffered up, to make things * a little bit more efficient. */ ttputc(c) { if (nobuf >= NOBUF) ttflush(); obuf[nobuf++] = c; } /* * Flush output. */ ttflush() { if (nobuf != 0) { write(1, obuf, nobuf); nobuf = 0; } } /* * Read character from terminal. * All 8 bits are returned, so that you can use * a multi-national terminal. * * If keyboard 'queue' already has typeahead from a typeahead() call, * just return it. Otherwise, make sure we are in blocking i/o mode * and read a character. */ ttgetc() { if( kbdqp ) kbdqp = FALSE; else { if( kbdpoll && fcntl( 0, F_SETFL, kbdflgs ) < 0 ) abort(); kbdpoll = FALSE; while (read(0, &kbdq, 1) != 1) ; } return ( kbdq & 0xff ); } /* * Return non-FALSE if typeahead is pending. * * If already got unread typeahead, do nothing. * Otherwise, set keyboard to O_NDELAY if not already, and try * a one character read. */ typeahead() { if( !kbdqp ) { if( !kbdpoll && fcntl( 0, F_SETFL, kbdflgs | O_NDELAY ) < 0 ) abort(); kbdqp = (1 == read( 0, &kbdq, 1 )); } return ( kbdqp ); } /* * panic: print error and die, leaving core file. * Don't know why this is needed (daveb). */ panic(s) char *s; { fprintf(stderr, "%s\r\n", s); abort(); } /* ** This should check the size of the window, and reset if needed. */ setttysize() { #ifdef TIOCGWINSZ if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) { nrow = winsize . ws_row; ncol = winsize . ws_col; } else #endif if ((nrow=tgetnum ("li")) <= 0 || (ncol=tgetnum ("co")) <= 0) { nrow = 24; ncol = 80; } if (nrow > NROW) /* Don't crash if the */ nrow = NROW; /* termcap entry is */ if (ncol > NCOL) /* too big. */ ncol = NCOL; }