|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid_Xttylib_c = "$Header: Xttylib.c,v 10.7 86/04/22 15:18:10 jg Rel $"; ! 3: #endif ! 4: /* This version has a single reverse-video argument instead of colors. It ! 5: really only works well on monochrome displays */ ! 6: ! 7: /* Library of routines to create a terminal emulator window ! 8: * ! 9: * Routines in this library are: ! 10: * ! 11: * CreateTTYWindow Creates a new instance of a terminal window ! 12: * DestroyTTYWindow Destroys a terminal window ! 13: * TTYPutString Puts a string in a terminal window ! 14: * TTYPutChar Puts a character in a terminal window ! 15: * TTYPrintf Does a printf in a terminal window ! 16: * TTYGetString Gets s string from a terminal window ! 17: * TTYGetChar Gets a char from a terminal window ! 18: * SetStdout Flushes stdout and assigns it to a window ! 19: * ResetStdout Resets stdout to its inital value ! 20: * ! 21: * The terminal window created responds to exactly the same character ! 22: * sequences as xterm (not surprising). Creating a window automatically ! 23: * maps it ! 24: * ! 25: * These routines pass around a pointer to a TTYWindow: ! 26: * ! 27: * typedef struct _TTYWindow { ! 28: * Window w; The window id ! 29: * int pid; The pid of the subprocess xterm ! 30: * short file; The file id of the tty to read/write characters to/from ! 31: * } TTYWindow; ! 32: * ! 33: * ! 34: * The SetStdout routine is highly useful in conjunction with curses ! 35: * since curses always writes to stdout. ! 36: */ ! 37: ! 38: #include <X/Xlib.h> ! 39: #include <stdio.h> ! 40: #include <signal.h> ! 41: #include <sys/file.h> ! 42: #include <sys/ioctl.h> ! 43: #include <sgtty.h> ! 44: #include "Xtty.h" ! 45: ! 46: TTYWindow *CreateTTYWindow(cols, lines, x, y, normFont, boldFont, bwidth, ! 47: reverse) ! 48: int lines, cols, x, y, bwidth, reverse; ! 49: char *normFont, *boldFont; ! 50: { ! 51: TTYWindow *t; ! 52: ! 53: if ((t = (TTYWindow *) malloc(sizeof(TTYWindow))) == ! 54: NULL) return NULL; ! 55: ! 56: if (Start_slave_xterm(t, lines, cols, x, y, normFont, boldFont, ! 57: bwidth, reverse) == 0) { ! 58: free((char *)t); ! 59: fprintf(stderr, "Couldn't start slave xterm\n"); ! 60: return NULL; ! 61: } ! 62: ! 63: return t; ! 64: } ! 65: ! 66: int ttyMasterPty; ! 67: int keepMasterOpen = 0; ! 68: ! 69: int Start_slave_xterm(t, lines, cols, x, y, normFont, boldFont, bwidth, ! 70: reverse) ! 71: TTYWindow *t; ! 72: int lines, cols, x, y, bwidth, reverse; ! 73: char *normFont, *boldFont; ! 74: { ! 75: #define BUFSIZE 20 ! 76: ! 77: char ttyName[BUFSIZE]; ! 78: char Sbuf[BUFSIZE], sizeBuf[BUFSIZE], wdBuf[BUFSIZE], ! 79: inputBuffer[BUFSIZE]; ! 80: int bytesRead, len; ! 81: ! 82: if (boldFont == NULL) boldFont = normFont; ! 83: ! 84: ttyMasterPty = GetPty(ttyName); ! 85: if (ttyMasterPty == -1) return 0; ! 86: ! 87: if ((t->pid = vfork()) < 0) return 0; ! 88: ! 89: if (t->pid == 0) { ! 90: sprintf(Sbuf, "-S%c%c%d", ttyName[8], ttyName[9], ttyMasterPty); ! 91: sprintf(sizeBuf, "=%dx%d+%d+%d", cols, lines, x, y); ! 92: sprintf(wdBuf, "%d", bwidth); ! 93: ! 94: execlp("xterm", "xterm", Sbuf, "-fn", normFont, "-fb", boldFont, ! 95: sizeBuf, "-bw", wdBuf, reverse ? "-rv" : (char *) 0, ! 96: (char *) 0); ! 97: ! 98: } else { ! 99: if (!keepMasterOpen) close(ttyMasterPty); ! 100: ! 101: /* Open the slave end of the pty */ ! 102: ! 103: ttyName[5] = 't'; /* Change /dev/pty?? to /dev/tty?? */ ! 104: ! 105: t->file = open(ttyName, O_RDWR, 0777); ! 106: ! 107: if (t->file < 0) { ! 108: /* Couldn't open the tty--better get rid of the process */ ! 109: kill (t->pid, SIGINT); ! 110: return 0; ! 111: } ! 112: ! 113: /* Read the windowid from the pty */ ! 114: ! 115: len = 0; ! 116: while ((bytesRead = read(t->file, inputBuffer + len, ! 117: sizeof(Window) - len)) > 0) len += bytesRead; ! 118: ! 119: /* Flush the rest of the garbahge */ ! 120: ! 121: ioctl(t->file, TIOCFLUSH, (struct sgttyb *) NULL); ! 122: ! 123: /* the data consists of a binary window ID */ ! 124: ! 125: t->w = *(Window *) inputBuffer; ! 126: } ! 127: return 1; ! 128: #undef BUFSIZE ! 129: } ! 130: ! 131: int GetPty(name) ! 132: char *name; ! 133: { ! 134: register int devindex, letter; ! 135: int fd; ! 136: ! 137: strcpy(name, "/dev/ptyp0"); ! 138: ! 139: for (letter = 0; letter < 4; letter++) { ! 140: name[8] = "pqrs"[letter]; ! 141: ! 142: for (devindex = 0; devindex < 16; devindex++) { ! 143: name[9] = "0123456789abcdef"[devindex]; ! 144: if ((fd = open (name, O_RDWR)) >= 0) return fd; ! 145: } ! 146: } ! 147: ! 148: return -1; ! 149: } ! 150: ! 151: DestroyTTYWindow(t) ! 152: TTYWindow *t; ! 153: { ! 154: /* close the tty; this should cause the xterm to terminate with an I/O error */ ! 155: close(t->file); ! 156: free((char *)t); ! 157: } ! 158: ! 159: TTYPutString(t, str) ! 160: TTYWindow *t; ! 161: char *str; ! 162: { ! 163: write(t->file, str, strlen(str)); ! 164: } ! 165: ! 166: TTYPutChar(t, ch) ! 167: TTYWindow *t; ! 168: char ch; ! 169: { ! 170: write(t->file, &ch, 1); ! 171: } ! 172: ! 173: TTYPrintf(t, format, args) ! 174: TTYWindow *t; ! 175: char *format; ! 176: { ! 177: #define TTY_BUFSIZE 2048 ! 178: char buffer[TTY_BUFSIZE+1]; ! 179: struct _iobuf _strbuf; ! 180: ! 181: _strbuf._flag = _IOWRT+_IOSTRG; ! 182: _strbuf._ptr = buffer; ! 183: _strbuf._cnt = TTY_BUFSIZE; ! 184: _doprnt(format, &args, &_strbuf); ! 185: _strbuf._cnt++; /* Be sure there's room for the \0 */ ! 186: putc('\0', &_strbuf); ! 187: TTYPutString(t, buffer); ! 188: #undef TTY_BUFSIZE ! 189: } ! 190: ! 191: static initial_stdout = -1; ! 192: ! 193: SetStdout(t) ! 194: TTYWindow *t; ! 195: { ! 196: if (initial_stdout == -1) initial_stdout = stdout->_file; ! 197: fflush(stdout); ! 198: stdout->_file = t->file; ! 199: } ! 200: ! 201: ResetStdout() ! 202: { ! 203: fflush(stdout); ! 204: stdout->_file = initial_stdout; ! 205: initial_stdout = -1; ! 206: } ! 207: ! 208: #define CMASK 0377 ! 209: ! 210: int TTYGetChar(t) ! 211: TTYWindow *t; ! 212: { ! 213: char c; ! 214: ! 215: if (read(t->file, &c, 1) > 0) ! 216: return (c & CMASK); ! 217: else return (EOF); ! 218: } ! 219: ! 220: char *TTYGetString(t, str, n) ! 221: register TTYWindow *t; ! 222: char *str; ! 223: register int n; ! 224: { ! 225: register char *cs; ! 226: ! 227: cs = str; ! 228: while (--n > 0 && read(t->file, cs, 1) > 0) { ! 229: if (*cs++ == '\n') break; ! 230: } ! 231: ! 232: if (cs == str) return NULL; ! 233: ! 234: *cs = '\0'; ! 235: return str; ! 236: ! 237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.