This is tcaphelp.c in view mode; [Download] [Up]
/* tcaphelp.c */ char id_tcaphelp[] = "$Id: tcaphelp.c,v 2.20 1996/09/18 20:37:17 steve Exp $"; /* This file includes low-level tty control functions used by the termcap * user interface. These are: * ttyinit() - remember the initial serial line configuration * ttyraw() - switch to the mode that elvis runs it * ttynormal() - switch back to the mode saved by ttyinit() * ttyread(buf,len,timeout)- read characters, possibly with timeout * ttywrite(buf,len) - write characters * ttytermtype() - return the name of the terminal type * ttysize() - determine the terminal size * * Also, it contains a small terminal emulator to be used when TERM=bios. */ #include "elvis.h" #ifdef GUI_TERMCAP # include <fcntl.h> # include <dos.h> # include <io.h> # include <conio.h> # include <signal.h> # include "pcvideo.h" # ifndef O_TEXT # define O_TEXT _O_TEXT # define O_BINARY _O_BINARY # endif #if USE_PROTOTYPES static long dostime(void); static void catchsig(int signo); #endif /* This is defined in guitcap.c */ extern long ttycaught; /* These variables remember the configuration of the console upon startup */ static int origraw; /* was it in raw mode? */ static int origbrk; /* was it looking for ^C? */ static int origmode; /* was it in O_TEXT mode, or O_BINARY? */ /* This variable is used to indicate that the BIOS interface is being used */ static BOOLEAN usebios; /* Width & height of video display */ static int pccols, pcrows; /* IOCTL GETRAW/SETRAW bits. */ #define DEVICE 0x80 #define RAW 0x20 /* IOCTL operations */ #define GETRAW 0x4400 #define SETRAW 0x4401 #define GETBRK 0x3300 #define SETBRK 0x3301 /* A nice way to call the DOS IOCTL or function */ static int elvioctl(int handle, int mode, unsigned setvalue) { union REGS regs; regs.x.ax = mode; regs.x.bx = handle; regs.h.dl = (char) setvalue; regs.h.dh = 0; /* Zero out dh */ intdos(®s, ®s); return (regs.x.dx); } /* This function catches signals, especially SIGINT */ static void catchsig(signo) int signo; { ttycaught |= (1 << signo); } void ttyinit() { /* remember the original state */ origraw = elvioctl(1, GETRAW, 0); origbrk = elvioctl(1, GETBRK, 0); origmode = setmode(1, O_TEXT); } /* switch to the tty state that elvis runs in */ void ttyraw(erasekey) char *erasekey; /* where to store the ERASE key */ { if (!usebios) { setmode(1, O_BINARY); if (origraw & DEVICE) (void)elvioctl(1, SETRAW, origraw | RAW); } (void)elvioctl(1, SETBRK, 0); signal(SIGINT, catchsig); } /* switch back to the original tty state */ void ttynormal() { (void)elvioctl(1, SETBRK, origbrk); setmode(1, origmode); if (usebios) { v_attr((int)0xffff, (int)0x0707); v_put('\r'); v_put('\n'); v_ce(); } else { if (origraw & DEVICE) (void)elvioctl(1, SETRAW, origraw); write(1, "\r\n", 2); } } /* this function returns the DOS time, as a 32-bit long int representing * hundredths of a second since midnight. Some systems may be limited to * a resolution of whole seconds, but the values will still represent * hundredths. */ static long dostime P_((void)) { union REGS regs; regs.h.ah = 0x2c; /* MS-DOS "get time" service */ intdos(®s, ®s); return (((regs.h.ch * 60L) + regs.h.cl) * 60L + regs.h.dh) * 100L + regs.h.dl; } /* Read from keyboard, with timeout. For DOS, we poll the keyboard in a * tight loop until we have a keystroke or the system's clock advances past * our timeout time. If we don't time out, then we loop until there are no * more characters, or the buffer is about full. */ int ttyread(buf, len, timeout) char *buf; /* where to place the input characters */ int len; /* maximum number of characters to read */ int timeout;/* timeout (0 for none) */ { long stop; int got; signal(SIGINT, catchsig); /* reset the "ttycaught" variable */ ttycaught = 0; /* are we going to timeout? */ if (timeout != 0) { /* compute the time when we'll give up */ stop = dostime() + timeout * 10L; /* wait for keystroke, timeout, or signal */ while (!kbhit()) { /* signal? */ if (ttycaught) return -1; /* timeout? */ if (dostime() > stop) { /* we couldn't read any characters * before timeout */ return 0; } } } /* get at least one keystroke */ got = 0; do { /* caught a signal lately? */ if (ttycaught) return -1; buf[got] = getch(); if (buf[got] == 0) /* function key? */ { buf[got++] = '#'; buf[got] = getch(); } got++; } while (kbhit() && got + 2 < len); return got; } /* write characters out to the screen */ void ttywrite(buf, len) char *buf; /* buffer, holds characters to be written */ int len; /* number of characters in buf */ { static int arg[5]; /* arguments to an escape sequence */ static int argno = -1; /* # of args in arg[], or -1 is not in Esc */ static int x, y; /* cursor position */ static BOOLEAN rvid; /* in reverse-video mode? */ static BOOLEAN uvid; /* in false-underline mode? */ static BOOLEAN colored; /* explicit colors set? (disables uvid) */ int i, j; /* if not using the BIOS, then just write the characters to stdout */ if (!usebios) { write(1, buf, len); return; } /* handle each character separately */ for (i = 0; i < len; i++) { if (buf[i] == '\007') { v_put('\007'); } else if (buf[i] == '\r') { x = 0; v_move(x, y); } else if (buf[i] == '\n') { if (y < pcrows - 1) { y++; v_move(x, y); } else { v_put('\n'); } } else if (buf[i] == '\b') { x--; if (x < 0) { if (y > 0) { x += pccols; y--; } else x = 0; } v_move(x, y); } else if (buf[i] == '\033') { /* start an escape sequence */ for (j = 0; j < QTY(arg); j++) arg[j] = 0; argno = 0; } else if (argno < 0) { /* normal character */ v_put(buf[i]); x++; if (x >= pccols) { x = 0; y++; } } else { /* in an escape sequence... */ switch (buf[i]) { case '[': case '?': /* ignored */ break; case ';': /* advance to next argument */ argno++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* incorporate this digit into current arg */ arg[argno] = arg[argno] * 10 + buf[i] - '0'; break; case 'H': /* move the cursor */ x = (arg[1] ? arg[1] - 1 : 0); y = (arg[0] ? arg[0] - 1 : 0); v_move(x, y); argno = -1; break; case 'J': /* clear the screen */ v_cl(); argno = -1; break; case 'K': /* clear to end-of-line */ v_ce(); argno = -1; break; case 'L': /* insert n lines */ v_al(arg[0] ? arg[0] : 1); argno = -1; break; case 'M': /* delete n lines */ v_dl(arg[0] ? arg[0] : 1); argno = -1; break; case 'h': if (arg[0] == 12) v_cb(); /* cursor big */ argno = -1; break; case 'l': if (arg[0] == 12) v_cs(); /* cursor small */ argno = -1; break; case 'm': for (j = 0; j <= argno; j++) { switch (arg[j]) { case 0: /* Resetting attributes is a * little tricky for color. We * want to force blink/bright * off but leave the colors... * Unless we were in standout * mode, in which case we want * to flip colors. */ if (rvid) { v_attr(0x0000, 0x0077); rvid = False; } if (uvid && !colored) { v_attr(0x0000, 0x0040); uvid = False; } colored = False; v_attr(0xff88, 0x0700); break; case 1: v_attr(0x0000, 0x0808); break; case 4: if (colored) { v_attr(0x7700, 0x0100); } else { uvid = (BOOLEAN)!uvid; v_attr(0x7700, 0x0140); } break; case 5: v_attr(0x0000, 0x8080); break; case 7: /* Setting standout mode is a * little tricky for mono, * because we need to force * underlining off. */ rvid = (BOOLEAN)!rvid; v_attr(0x7700, rvid ? 0x7077 : 0x0777); break; case 30: v_attr(0x0007, 0x0000); break; case 31: v_attr(0x0007, 0x0004); break; case 32: v_attr(0x0007, 0x0002); break; case 33: v_attr(0x0007, 0x0006); break; case 34: v_attr(0x0007, 0x0001); break; case 35: v_attr(0x0007, 0x0005); break; case 36: v_attr(0x0007, 0x0003); break; case 37: v_attr(0x0007, 0x0007); break; case 40: v_attr(0x0070, 0x0000); colored = True; break; case 41: v_attr(0x0070, 0x0040); colored = True; break; case 42: v_attr(0x0070, 0x0020); colored = True; break; case 43: v_attr(0x0070, 0x0060); colored = True; break; case 44: v_attr(0x0070, 0x0010); colored = True; break; case 45: v_attr(0x0070, 0x0050); colored = True; break; case 46: v_attr(0x0070, 0x0030); colored = True; break; case 47: v_attr(0x0070, 0x0070); colored = uvid; break; } } argno = -1; break; default: /* does it look like the end of a command? */ if ((buf[i] & 0x40) != 0) { argno = -1; } } } } } /* determine the terminal type */ char *ttytermtype() { char *type; type = getenv("TERM"); if (!type) type = TTY_DEFAULT; if (!strcmp(type, "ansi")) type = "dosansi"; usebios = (BOOLEAN)!strcmp(type, "pcbios"); return type; } /* This function gets the window size. */ BOOLEAN ttysize(linesptr, colsptr) int *linesptr; /* where to store the number of rows */ int *colsptr; /* where to store the number of columns */ { pccols = *colsptr = v_cols(); pcrows = *linesptr = v_rows(); return True; } /* Check for signs of boredom from user, so we can abort a time-consuming * operation. Here we check to see if SIGINT has been caught recently. */ BOOLEAN ttypoll(reset) BOOLEAN reset; { return (BOOLEAN)(ttycaught != 0); } #endif /* GUI_TERMCAP */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.