|
|
1.1 root 1: #ifndef lint
2: static char *rcsid_Xttylib_c = "$Header: Xttylib.c,v 10.6 86/02/01 15:42:48 tony 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(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(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.