|
|
1.1 root 1: /* @(#) setupterm.c: 1.2 10/31/83 (1.36 3/18/83) */
2: #include "curses.ext"
3: #include "../local/uparm.h"
4:
5: extern struct term _first_term;
6: extern struct term *cur_term;
7:
8: static char firststrtab[2048];
9: static int called_before = 0; /* To check for first time. */
10: char *getenv();
11: char *malloc();
12: char ttytype[128];
13: #ifndef termpath
14: #define termpath(file) "/usr/lib/terminfo/file"
15: #endif
16: #define MAGNUM 0432
17:
18: #define getshi() getsh(ip) ; ip += 2
19:
20: /*
21: * "function" to get a short from a pointer. The short is in a standard
22: * format: two bytes, the first is the low order byte, the second is
23: * the high order byte (base 256). The only negative number allowed is
24: * -1, which is represented as 255, 255. This format happens to be the
25: * same as the hardware on the pdp-11 and vax, making it fast and
26: * convenient and small to do this on a pdp-11.
27: */
28:
29: #ifdef vax
30: #define getsh(ip) (* (short *) ip)
31: #endif
32: #ifdef pdp11
33: #define getsh(ip) (* (short *) ip)
34: #endif
35:
36: #ifndef getsh
37: /*
38: * Here is a more portable version, which does not assume byte ordering
39: * in shorts, sign extension, etc.
40: */
41: getsh(p)
42: register char *p;
43: {
44: register int rv;
45: if (*p == 0377)
46: return -1;
47: rv = *p++;
48: rv += *p * 256;
49: return rv;
50: }
51: #endif
52:
53: /*
54: * setupterm: low level routine to dig up terminfo from database
55: * and read it in. Parms are terminal type (0 means use getenv("TERM"),
56: * file descriptor all output will go to (for ioctls), and a pointer
57: * to an int into which the error return code goes (0 means to bomb
58: * out with an error message if there's an error). Thus, setupterm(0, 1, 0)
59: * is a reasonable way for a simple program to set up.
60: */
61: setupterm(term, filenum, errret)
62: char *term;
63: int filenum; /* This is a UNIX file descriptor, not a stdio ptr. */
64: int *errret;
65: {
66: char tiebuf[4096];
67: char fname[128];
68: register char *ip;
69: register char *cp;
70: int n, tfd;
71: char *lcp, *ccp;
72: int snames, nbools, nints, nstrs, sstrtab;
73: char *strtab;
74:
75: if (term == NULL)
76: term = getenv("TERM");
77: if (term == NULL || *term == '\0')
78: term = "unknown";
79: tfd = -1;
80: if (cp=getenv("TERMINFO")) {
81: strcpy(fname, cp);
82: cp = fname + strlen(fname);
83: *cp++ = '/';
84: *cp++ = *term;
85: *cp++ = '/';
86: strcpy(cp, term);
87: tfd = open(fname, 0);
88: }
89: if (tfd < 0) {
90: strcpy(fname, termpath(a/));
91: cp = fname + strlen(fname);
92: cp[-2] = *term;
93: strcpy(cp, term);
94: tfd = open(fname, 0);
95: }
96:
97: if( tfd < 0 )
98: {
99: if( access( termpath( . ), 0 ) )
100: {
101: if( errret == 0 )
102: perror( termpath( . ) );
103: else
104: *errret = -1;
105: }
106: else
107: {
108: if( errret == 0 )
109: {
110: write(2, "No such terminal: ", 18);
111: write(2, term, strlen(term));
112: write(2, "\r\n", 2);
113: }
114: else
115: {
116: *errret = 0;
117: }
118: }
119: if( errret == 0 )
120: exit( -2 );
121: else
122: return -1;
123: }
124:
125: if( called_before && cur_term ) /* 2nd or more times through */
126: {
127: cur_term = (struct term *) malloc(sizeof (struct term));
128: strtab = NULL;
129: }
130: else /* First time through */
131: {
132: cur_term = &_first_term;
133: called_before = TRUE;
134: strtab = firststrtab;
135: }
136:
137: if( filenum == 1 && !isatty(filenum) ) /* Allow output redirect */
138: {
139: filenum = 2;
140: }
141: cur_term -> Filedes = filenum;
142: def_shell_mode();
143:
144: if (errret)
145: *errret = 1;
146: n = read(tfd, tiebuf, sizeof tiebuf);
147: close(tfd);
148: if (n <= 0) {
149: corrupt:
150: write(2, "corrupted term entry\r\n", 22);
151: if (errret == 0)
152: exit(-3);
153: else
154: return -1;
155: }
156: if (n == sizeof tiebuf) {
157: write(2, "term entry too long\r\n", 21);
158: if (errret == 0)
159: exit(-4);
160: else
161: return -1;
162: }
163: cp = ttytype;
164: ip = tiebuf;
165:
166: /* Pick up header */
167: snames = getshi();
168: if (snames != MAGNUM) {
169: goto corrupt;
170: }
171: snames = getshi();
172: nbools = getshi();
173: nints = getshi();
174: nstrs = getshi();
175: sstrtab = getshi();
176: if (strtab == NULL) {
177: strtab = (char *) malloc(sstrtab);
178: }
179:
180: while (snames--)
181: *cp++ = *ip++; /* Skip names of terminals */
182:
183: /*
184: * Inner blocks to share this register among two variables.
185: */
186: {
187: register char *sp;
188: char *fp = (char *)&cur_term->Columns;
189: register char s;
190: for (cp= &cur_term->Auto_left_margin; nbools--; ) {
191: s = *ip++;
192: if (cp < fp)
193: *cp++ = s;
194: }
195: }
196:
197: /* Force proper alignment */
198: if (((unsigned int) ip) & 1)
199: ip++;
200:
201: {
202: register short *sp;
203: short *fp = (short *)&cur_term->strs;
204: register int s;
205:
206: for (sp= &cur_term->Columns; nints--; ) {
207: s = getshi();
208: if (sp < fp)
209: *sp++ = s;
210: }
211: }
212:
213: #ifdef JWINSIZE
214: /*
215: * ioctls for Blit - you may need to #include <jioctl.h>
216: * This ioctl defines the window size and overrides what
217: * it says in terminfo.
218: */
219: {
220: struct winsize w;
221:
222: if (ioctl(2, JWINSIZE, &w) != -1) {
223: lines = w.bytesy;
224: columns = w.bytesx;
225: }
226: }
227: #endif
228: lcp = getenv("LINES");
229: ccp = getenv("COLUMNS");
230: if (lcp)
231: lines = atoi(lcp);
232: if (ccp)
233: columns = atoi(ccp);
234:
235: {
236: register char **pp;
237: char **fp = (char **)&cur_term->Filedes;
238:
239: for (pp= &cur_term->strs.Back_tab; nstrs--; ) {
240: n = getshi();
241: if (pp < fp) {
242: if (n == -1)
243: *pp++ = NULL;
244: else
245: *pp++ = strtab+n;
246: }
247: }
248: }
249:
250: for (cp=strtab; sstrtab--; ) {
251: *cp++ = *ip++;
252: }
253:
254: /*
255: * If tabs are being expanded in software, turn this off
256: * so output won't get messed up. Also, don't use tab
257: * or backtab, even if the terminal has them, since the
258: * user might not have hardware tabs set right.
259: */
260: #ifdef USG
261: if ((cur_term -> Nttyb.c_oflag & TABDLY) == TAB3) {
262: cur_term->Nttyb.c_oflag &= ~TABDLY;
263: tab = NULL;
264: back_tab = NULL;
265: reset_prog_mode();
266: return 0;
267: }
268: #else
269: if ((cur_term -> Nttyb.sg_flags & XTABS) == XTABS) {
270: cur_term->Nttyb.sg_flags &= ~XTABS;
271: tab = NULL;
272: back_tab = NULL;
273: reset_prog_mode();
274: return 0;
275: }
276: #endif
277: #ifdef DIOCSETT
278: reset_prog_mode();
279: #endif
280: #ifdef LTILDE
281: ioctl(cur_term -> Filedes, TIOCLGET, &n);
282: if (n & LTILDE);
283: reset_prog_mode();
284: #endif
285: return 0;
286: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.