Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 7u83 1
/*
2
 * This code contains changes by
3
 *      Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved.
4
 *
5
 * Conditions 1, 2, and 4 and the no-warranty notice below apply
6
 * to these changes.
7
 *
8
 *
9
 * Copyright (c) 1980, 1993
10
 * 	The Regents of the University of California.  All rights reserved.
11
 *
12
 * Redistribution and use in source and binary forms, with or without
13
 * modification, are permitted provided that the following conditions
14
 * are met:
15
 * 1. Redistributions of source code must retain the above copyright
16
 *    notice, this list of conditions and the following disclaimer.
17
 * 2. Redistributions in binary form must reproduce the above copyright
18
 *    notice, this list of conditions and the following disclaimer in the
19
 *    documentation and/or other materials provided with the distribution.
20
 * 3. All advertising materials mentioning features or use of this software
21
 *    must display the following acknowledgement:
22
 * 	This product includes software developed by the University of
23
 * 	California, Berkeley and its contributors.
24
 * 4. Neither the name of the University nor the names of its contributors
25
 *    may be used to endorse or promote products derived from this software
26
 *    without specific prior written permission.
27
 *
28
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38
 * SUCH DAMAGE.
39
 *
40
 *
41
 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
42
 *
43
 * Redistribution and use in source and binary forms, with or without
44
 * modification, are permitted provided that the following conditions
45
 * are met:
46
 *   Redistributions of source code and documentation must retain the
47
 *    above copyright notice, this list of conditions and the following
48
 *    disclaimer.
49
 *   Redistributions in binary form must reproduce the above copyright
50
 *    notice, this list of conditions and the following disclaimer in the
51
 *    documentation and/or other materials provided with the distribution.
52
 *   All advertising materials mentioning features or use of this software
53
 *    must display the following acknowledgement:
54
 *      This product includes software developed or owned by Caldera
55
 *      International, Inc.
56
 *   Neither the name of Caldera International, Inc. nor the names of
57
 *    other contributors may be used to endorse or promote products
58
 *    derived from this software without specific prior written permission.
59
 *
60
 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
61
 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
62
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64
 * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
65
 * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
66
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
67
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
68
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
69
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
70
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
71
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72
 */
73
 
74
#ifndef	lint
75
#ifdef	DOSCCS
76
static char sccsid[] = "@(#)ex_tty.c	1.29 (gritter) 2/17/05";
77
#endif
78
#endif
79
 
80
/* from ex_tty.c	7.10.1 (2.11BSD GTE) 12/9/94 */
81
 
82
#include "ex.h"
83
#include "ex_tty.h"
84
 
85
int ATTN = DELETE;
86
 
87
/*
88
 * Terminal type initialization routines,
89
 * and calculation of flags at entry or after
90
 * a shell escape which may change them.
91
 */
92
/* short	ospeed = -1;	mjm: def also in tputs.c of termcap.a  */
93
 
94
void 
95
gettmode(void)
96
{
97
	speed_t pospeed;
98
 
99
	if (tcgetattr(1, &tty) < 0) {
100
		ospeed = B0;
101
		return;
102
	}
103
	pospeed = cfgetospeed(&tty);
104
	if (ospeed != pospeed)
105
		value(SLOWOPEN) = pospeed < B1200;
106
	ospeed = pospeed;
107
	normf = tty;
108
#if defined (UCVISUAL) && defined (IUCLC)
109
	UPPERCASE = (tty.c_iflag & IUCLC) != 0;
110
#endif
111
#if defined (TAB3)
112
	GT = (tty.c_oflag & TABDLY) != TAB3 && !XT;
113
#elif defined (XTABS)
114
	GT = (tty.c_oflag & TABDLY) != XTABS && !XT;
115
#else
116
	GT = !XT;
117
#endif	/* !TAB3, XTABS */
118
	/*
119
	 * Tabs and multi-column characters do not combine properly
120
	 * unless vi performs a look-ahead on the current line. Just
121
	 * do not use them for now.
122
	 */
123
	if (mb_cur_max > 1)
124
		GT = 0;
125
	NONL = (tty.c_oflag & ONLCR) == 0;
126
	ATTN = tty.c_cc[VINTR];
127
}
128
 
129
char *xPC;
130
char **sstrs[] = {
131
	&AL, &BC, &BT, &CD, &CE, &CL, &CM, &xCR, &xCS, &DC, &DL, &DM, &DO,
132
	&ED, &EI, &F0, &F1, &F2, &F3, &F4, &F5, &F6, &F7, &F8, &F9,
133
	&HO, &IC, &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU, &LL, &ND, &xNL,
134
	&xPC, &RC, &SC, &SE, &SF, &SO, &SR, &TA, &TE, &TI, &UP, &VB, &VS, &VE,
135
	&AL_PARM, &DL_PARM, &UP_PARM, &DOWN_PARM, &LEFT_PARM, &RIGHT_PARM
136
};
137
bool *sflags[] = {
138
	&AM, &BS, &DA, &DB, &EO, &HC,
139
#ifdef	UCVISUAL
140
	&xHZ,
141
#endif
142
	&IN, &MI, &NC, &NS, &OS, &UL,
143
	&XB, &XN, &XT, &XX
144
};
145
char **fkeys[10] = {
146
	&F0, &F1, &F2, &F3, &F4, &F5, &F6, &F7, &F8, &F9
147
};
148
void
149
setterm(char *type)
150
{
151
	register int unknown;
152
	char ltcbuf[TCBUFSIZE];
153
 
154
	if (type[0] == 0)
155
		type = "xx";
156
	unknown = 0;
157
	putpad(TE);
158
	if (tgetent(ltcbuf, type) != 1) {
159
		unknown++;
160
		CP(ltcbuf, "xx|dumb:");
161
	}
162
	gettmode(); /* must call gettmode() before setsize(). GR */
163
	setsize();
164
	aoftspace = tspace;
165
	zap();
166
	/*
167
	 * Initialize keypad arrow keys.
168
	 */
169
	addmac1(KU, "k", "up", arrows, 1);
170
	addmac1(KD, "j", "down", arrows, 1);
171
	addmac1(KL, "h", "left", arrows, 1);
172
	addmac1(KR, "l", "right", arrows, 1);
173
	addmac1(KH, "H", "home", arrows, 1);
174
 
175
	/*
176
	 * Handle funny termcap capabilities
177
	 */
178
	if (xCS && SC && RC) {
179
		if (AL==NULL) AL="";
180
		if (DL==NULL) DL="";
181
	}
182
	if (AL_PARM && AL==NULL) AL="";
183
	if (DL_PARM && DL==NULL) DL="";
184
	if (IC && IM==NULL) IM="";
185
	if (IC && EI==NULL) EI="";
186
	if (!GT) BT=NULL;	/* If we can't tab, we can't backtab either */
187
 
188
#ifdef	TIOCLGET
189
#define	HAS_JOB_CONTROL
190
#endif
191
#ifdef	_SC_JOB_CONTROL
192
#define	HAS_JOB_CONTROL
193
#endif
194
#ifdef	HAS_JOB_CONTROL
195
	/*
196
	 * Now map users susp char to ^Z, being careful that the susp
197
	 * overrides any arrow key, but only for hackers (=new tty driver).
198
	 */
199
	{
200
		static char sc[2];
201
		int i /* , fnd */;
202
 
203
		if (sysconf(_SC_JOB_CONTROL) != -1)
204
		{
205
			/*
206
			 * If a system supports job control but no job
207
			 * control shell is used, only one method of
208
			 * detection remains: Our session id equals our
209
			 * process group id. Any job control shell would
210
			 * have created at least one new process group.
211
			 * But as the VSUSP key may be active, we have
212
			 * to override arrow keys either.
213
			 */
214
#ifndef	_CRAY	/* getsid() is a bad syscall on UNICOS */
215
			if (getsid(0) != getpgid(0))
216
#endif	/* !_CRAY */
217
				ldisc = 2;	/* value of NTTYDISC */
218
			sc[0] = tty.c_cc[VSUSP];
219
			sc[1] = 0;
220
			if (tty.c_cc[VSUSP] == CTRL('z')) {
221
				for (i=0; i<=4; i++)
222
					if (arrows[i].cap &&
223
					    arrows[i].cap[0] == CTRL('z'))
224
						addmac(sc, NULL, NULL, arrows);
225
			} else if (sc[0]
226
#ifdef	_PC_VDISABLE
227
					&& sc[0] != fpathconf(1, _PC_VDISABLE)
228
#endif
229
					)
230
				addmac(sc, "\32", "susp", arrows);
231
		}
232
	}
233
#endif	/* HAS_JOB_CONTROL */
234
 
235
	if (CM != 0) {
236
		if (tgoto(CM, 2, 2)[0] == 'O')	/* OOPS */
237
			CA = 0, CM = 0;
238
		else
239
			CA = 1, costCM = cost(tgoto(CM, 8, 10));
240
	} else {
241
		CA = 0, CM = 0;
242
	}
243
	costSR = cost(SR);
244
	costAL = cost(AL);
245
	costDP = cost(tgoto(DOWN_PARM, 10, 10));
246
	costLP = cost(tgoto(LEFT_PARM, 10, 10));
247
	costRP = cost(tgoto(RIGHT_PARM, 10, 10));
248
	PC = xPC ? xPC[0] : 0;
249
	aoftspace = tspace;
250
	safecp(ttylongname, gettlongname(ltcbuf, type), sizeof ttylongname,
251
			"Terminal name too long");
252
	/* proper strings to change tty type */
253
	termreset();
254
	gettmode();
255
	value(REDRAW) = AL && DL;
256
	value(OPTIMIZE) = !CA && !GT;
257
	if (ospeed == B1200 && !value(REDRAW))
258
		value(SLOWOPEN) = 1;	/* see also gettmode above */
259
	if (unknown)
260
		serror(catgets(catd, 1, 191,
261
				"%s: Unknown terminal type"), type);
262
}
263
 
264
void
265
setsize(void)
266
{
267
	register int l, i;
268
#ifdef	TIOCGWINSZ
269
	struct winsize win;
270
#endif
271
 
272
	char *e;
273
 
274
#ifdef	TIOCGWINSZ
275
	i = ioctl(0, TIOCGWINSZ, &win);
276
#endif
277
	TLINES = TCOLUMNS = 0;
278
	e = getenv("COLUMNS");
279
	if (e != NULL && *e != '\0')
280
		TCOLUMNS = atoi(e);
281
	if (TCOLUMNS <= 0) {
282
#ifdef	TIOCGWINSZ
283
		if (i >= 0 && win.ws_col != 0)
284
			TCOLUMNS = winsz.ws_col = win.ws_col;
285
		else
286
#endif
287
			TCOLUMNS = tgetnum("co");
288
	}
289
	e = getenv("LINES");
290
	if (e != NULL && *e != '\0')
291
		TLINES = atoi(e);
292
	if (TLINES <= 0) {
293
#ifdef	TIOCGWINSZ
294
		if (i >= 0 && win.ws_row != 0)
295
			TLINES = winsz.ws_row = win.ws_row;
296
		else
297
#endif
298
			TLINES = tgetnum("li");
299
	}
300
	i = TLINES;
301
	if (TLINES <= 5)
302
		TLINES = 24;
303
	if (TLINES > TUBELINES)
304
		TLINES = TUBELINES;
305
	l = TLINES;
306
	if (ospeed < B1200)
307
		l = 9;	/* including the message line at the bottom */
308
	else if (ospeed < B2400)
309
		l = 17;
310
	if (l > TLINES)
311
		l = TLINES;
312
	if (TCOLUMNS <= 4)
313
		TCOLUMNS = 1000;
314
	options[WINDOW].ovalue = options[WINDOW].odefault = l - 1;
315
	if (defwind) {
316
		options[WINDOW].ovalue = defwind;
317
		l = defwind + 1;
318
	}
319
	options[SCROLL].ovalue = options[SCROLL].odefault = HC ? 11 : ((l-1) / 2);
320
	if (i <= 0)
321
		TLINES = 2;
322
}
323
 
324
void
325
zap(void)
326
{
327
	register char *namp;
328
	register bool **fp;
329
	register char ***sp;
330
	int flag;
331
	char *string;
332
 
333
#ifndef	UCVISUAL
334
	namp = "ambsdadbeohcinmincnsosulxbxnxtxx";
335
#else
336
	namp = "ambsdadbeohchzinmincnsosulxbxnxtxx";
337
#endif
338
	fp = sflags;
339
	do {
340
		flag = tgetflag(namp);
341
		*(*fp++) = flag;
342
		namp += 2;
343
	} while (*namp);
344
	namp = "albcbtcdceclcmcrcsdcdldmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullndnlpcrcscsesfsosrtatetiupvbvsveALDLUPDOLERI";
345
	sp = sstrs;
346
	do {
347
		string = tgetstr(namp, &aoftspace);
348
		*(*sp++) = string;
349
		namp += 2;
350
	} while (*namp);
351
}
352
 
353
char *
354
gettlongname(register char *bp, char *def)
355
{
356
	register char *cp;
357
 
358
	while (*bp && *bp != ':' && *bp != '|')
359
		bp++;
360
	if (*bp == '|') {
361
		bp++;
362
		cp = bp;
363
		while (*cp && *cp != ':' && *cp != '|')
364
			cp++;
365
		*cp = 0;
366
		return (bp);
367
	}
368
	return (def);
369
}
370
 
371
char *
372
fkey(int i)
373
{
374
	if (0 <= i && i <= 9)
375
		return(*fkeys[i]);
376
	else
377
		return(NOSTR);
378
}
379
 
380
/*
381
 * cost figures out how much (in characters) it costs to send the string
382
 * str to the terminal.  It takes into account padding information, as
383
 * much as it can, for a typical case.  (Right now the typical case assumes
384
 * the number of lines affected is the size of the screen, since this is
385
 * mainly used to decide if AL or SR is better, and this always happens
386
 * at the top of the screen.  We assume cursor motion (CM) has little
387
 * padding, if any, required, so that case, which is really more important
388
 * than AL vs SR, won't be really affected.)
389
 */
390
static int costnum;
391
int
392
cost(char *str)
393
{
394
	if (str == NULL || *str=='O')	/* OOPS */
395
		return 10000;	/* infinity */
396
	costnum = 0;
397
	tputs(str, TLINES, countnum);
398
	return costnum;
399
}
400
 
401
/*ARGSUSED*/
402
int
403
countnum(int ch)
404
{
405
	costnum++;
406
	return ch;
407
}