xref: /original-bsd/usr.bin/window/ttgeneric.c (revision 79386b64)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)ttgeneric.c	3.37 (Berkeley) 10/04/88";
20 #endif /* not lint */
21 
22 #include "ww.h"
23 #include "tt.h"
24 
25 char PC, *BC, *UP;
26 short ospeed;
27 
28 	/* normal frame */
29 short gen_frame[16] = {
30 	' ', '|', '-', '+',
31 	'|', '|', '+', '+',
32 	'-', '+', '-', '+',
33 	'+', '+', '+', '+'
34 };
35 
36 	/* ANSI graphics frame */
37 #define G (WWM_GRP << WWC_MSHIFT)
38 short ansi_frame[16] = {
39 	' ',	'x'|G,	'Q'|G,	'm'|G,
40 	'x'|G,	'x'|G,	'l'|G,	't'|G,
41 	'q'|G,	'j'|G,	'q'|G,	'v'|G,
42 	'k'|G,	'u'|G,	'w'|G,	'n'|G
43 };
44 struct tt_str ansi_AS = {
45 	"\033(0", 3
46 };
47 
48 struct tt_str *gen_PC;
49 struct tt_str *gen_CM;
50 struct tt_str *gen_IM;
51 struct tt_str *gen_IC;
52 struct tt_str *gen_IP;
53 struct tt_str *gen_EI;
54 struct tt_str *gen_DC;
55 struct tt_str *gen_AL;
56 struct tt_str *gen_DL;
57 struct tt_str *gen_CE;
58 struct tt_str *gen_CD;
59 struct tt_str *gen_CL;
60 struct tt_str *gen_VS;
61 struct tt_str *gen_VE;
62 struct tt_str *gen_TI;
63 struct tt_str *gen_TE;
64 struct tt_str *gen_SO;
65 struct tt_str *gen_SE;
66 struct tt_str *gen_US;
67 struct tt_str *gen_UE;
68 struct tt_str *gen_LE;
69 struct tt_str *gen_ND;
70 struct tt_str *gen_UP;
71 struct tt_str *gen_DO;
72 struct tt_str *gen_BC;
73 struct tt_str *gen_NL;
74 struct tt_str *gen_CR;
75 struct tt_str *gen_HO;
76 struct tt_str *gen_AS;
77 struct tt_str *gen_AE;
78 struct tt_str *gen_XS;
79 struct tt_str *gen_XE;
80 struct tt_str *gen_SF;
81 struct tt_str *gen_SR;
82 struct tt_str *gen_CS;
83 char gen_MI;
84 char gen_MS;
85 char gen_AM;
86 char gen_OS;
87 char gen_BS;
88 char gen_DA;
89 char gen_DB;
90 char gen_NS;
91 char gen_XN;
92 int gen_CO;
93 int gen_LI;
94 int gen_UG;
95 int gen_SG;
96 
97 gen_setinsert(new)
98 char new;
99 {
100 	if (new) {
101 		if (gen_IM)
102 			ttxputs(gen_IM);
103 	} else
104 		if (gen_EI)
105 			ttxputs(gen_EI);
106 	tt.tt_insert = new;
107 }
108 
109 gen_setmodes(new)
110 register new;
111 {
112 	register diff;
113 
114 	diff = new ^ tt.tt_modes;
115 	if (diff & WWM_REV) {
116 		if (new & WWM_REV) {
117 			if (gen_SO)
118 				ttxputs(gen_SO);
119 		} else
120 			if (gen_SE)
121 				ttxputs(gen_SE);
122 	}
123 	if (diff & WWM_UL) {
124 		if (new & WWM_UL) {
125 			if (gen_US)
126 				ttxputs(gen_US);
127 		} else
128 			if (gen_UE)
129 				ttxputs(gen_UE);
130 	}
131 	if (diff & WWM_GRP) {
132 		if (new & WWM_GRP) {
133 			if (gen_AS)
134 				ttxputs(gen_AS);
135 		} else
136 			if (gen_AE)
137 				ttxputs(gen_AE);
138 	}
139 	if (diff & WWM_USR) {
140 		if (new & WWM_USR) {
141 			if (gen_XS)
142 				ttxputs(gen_XS);
143 		} else
144 			if (gen_XE)
145 				ttxputs(gen_XE);
146 	}
147 	tt.tt_modes = new;
148 }
149 
150 gen_insline()
151 {
152 	if (tt.tt_modes)			/* for concept 100 */
153 		gen_setmodes(0);
154 	if (gen_AL)
155 		tttputs(gen_AL, gen_LI - tt.tt_row);
156 }
157 
158 gen_delline()
159 {
160 	if (tt.tt_modes)			/* for concept 100 */
161 		gen_setmodes(0);
162 	if (gen_DL)
163 		tttputs(gen_DL, gen_LI - tt.tt_row);
164 }
165 
166 gen_putc(c)
167 register char c;
168 {
169 	if (tt.tt_ninsert != tt.tt_insert)
170 		gen_setinsert(tt.tt_ninsert);
171 	if (tt.tt_nmodes != tt.tt_modes)
172 		gen_setmodes(tt.tt_nmodes);
173 	if (tt.tt_insert) {
174 		if (gen_IC)
175 			tttputs(gen_IC, gen_CO - tt.tt_col);
176 		ttputc(c);
177 		if (gen_IP)
178 			tttputs(gen_IP, gen_CO - tt.tt_col);
179 	} else
180 		ttputc(c);
181 	if (++tt.tt_col == gen_CO)
182 		if (gen_XN)
183 			tt.tt_col = tt.tt_row = -10;
184 		else if (gen_AM)
185 			tt.tt_col = 0, tt.tt_row++;
186 		else
187 			tt.tt_col--;
188 }
189 
190 gen_write(p, n)
191 	register char *p;
192 	register n;
193 {
194 	if (tt.tt_ninsert != tt.tt_insert)
195 		gen_setinsert(tt.tt_ninsert);
196 	if (tt.tt_nmodes != tt.tt_modes)
197 		gen_setmodes(tt.tt_nmodes);
198 	if (tt.tt_insert && (gen_IC || gen_IP)) {
199 		while (--n >= 0) {
200 			if (gen_IC)
201 				tttputs(gen_IC, gen_CO - tt.tt_col);
202 			ttputc(*p++);
203 			if (gen_IP)
204 				tttputs(gen_IP, gen_CO - tt.tt_col);
205 			tt.tt_col++;
206 		}
207 	} else {
208 		tt.tt_col += n;
209 		ttwrite(p, n);
210 	}
211 	if (tt.tt_col == gen_CO)
212 		if (gen_XN)
213 			tt.tt_col = tt.tt_row = -10;
214 		else if (gen_AM)
215 			tt.tt_col = 0, tt.tt_row++;
216 		else
217 			tt.tt_col--;
218 }
219 
220 gen_move(row, col)
221 register int row, col;
222 {
223 	if (tt.tt_row == row && tt.tt_col == col)
224 		return;
225 	if (!gen_MI && tt.tt_insert)
226 		gen_setinsert(0);
227 	if (!gen_MS && tt.tt_modes)
228 		gen_setmodes(0);
229 	if (row < tt.tt_scroll_top || row > tt.tt_scroll_bot)
230 		gen_setscroll(tt.tt_nrow - 1, 0);
231 	if (tt.tt_row == row) {
232 		if (col == 0) {
233 			ttxputs(gen_CR);
234 			goto out;
235 		}
236 		if (tt.tt_col == col - 1) {
237 			if (gen_ND) {
238 				ttxputs(gen_ND);
239 				goto out;
240 			}
241 		} else if (tt.tt_col == col + 1) {
242 			if (gen_LE) {
243 				ttxputs(gen_LE);
244 				goto out;
245 			}
246 		}
247 	}
248 	if (tt.tt_col == col) {
249 		if (tt.tt_row == row + 1) {
250 			if (gen_UP) {
251 				ttxputs(gen_UP);
252 				goto out;
253 			}
254 		} else if (tt.tt_row == row - 1) {
255 			ttxputs(gen_DO);
256 			goto out;
257 		}
258 	}
259 	if (gen_HO && col == 0 && row == 0) {
260 		ttxputs(gen_HO);
261 		goto out;
262 	}
263 	tttgoto(gen_CM, col, row);
264 out:
265 	tt.tt_col = col;
266 	tt.tt_row = row;
267 }
268 
269 gen_init()
270 {
271 	if (gen_VS)
272 		ttxputs(gen_VS);
273 	if (gen_TI)
274 		ttxputs(gen_TI);
275 	ttxputs(gen_CL);
276 	tt.tt_col = tt.tt_row = 0;
277 	tt.tt_ninsert = tt.tt_insert = 0;
278 	tt.tt_nmodes = tt.tt_modes = 0;
279 }
280 
281 gen_end()
282 {
283 	if (gen_TE)
284 		ttxputs(gen_TE);
285 	if (gen_VE)
286 		ttxputs(gen_VE);
287 }
288 
289 gen_clreol()
290 {
291 	if (tt.tt_modes)			/* for concept 100 */
292 		gen_setmodes(0);
293 	tttputs(gen_CE, gen_CO - tt.tt_col);
294 }
295 
296 gen_clreos()
297 {
298 	if (tt.tt_modes)			/* for concept 100 */
299 		gen_setmodes(0);
300 	tttputs(gen_CD, gen_LI - tt.tt_row);
301 }
302 
303 gen_clear()
304 {
305 	if (tt.tt_modes)			/* for concept 100 */
306 		gen_setmodes(0);
307 	ttxputs(gen_CL);
308 }
309 
310 gen_delchar()
311 {
312 	tttputs(gen_DC, gen_CO - tt.tt_col);
313 }
314 
315 gen_scroll_down()
316 {
317 	gen_move(tt.tt_scroll_bot, 0);
318 	ttxputs(gen_SF);
319 }
320 
321 gen_scroll_up()
322 {
323 	gen_move(tt.tt_scroll_top, 0);
324 	ttxputs(gen_SR);
325 }
326 
327 gen_setscroll(top, bot)
328 {
329 	tttgoto(gen_CS, bot, top);
330 	tt.tt_scroll_top = top;
331 	tt.tt_scroll_bot = bot;
332 	tt.tt_row = tt.tt_col = -10;
333 }
334 
335 tt_generic()
336 {
337 	gen_PC = tttgetstr("pc");
338 	PC = gen_PC ? *gen_PC->ts_str : 0;
339 	ospeed = wwoldtty.ww_sgttyb.sg_ospeed;
340 
341 	gen_CM = ttxgetstr("cm");		/* may not work */
342 	gen_IM = ttxgetstr("im");
343 	gen_IC = tttgetstr("ic");
344 	gen_IP = tttgetstr("ip");
345 	gen_EI = ttxgetstr("ei");
346 	gen_DC = tttgetstr("dc");
347 	gen_AL = tttgetstr("al");
348 	gen_DL = tttgetstr("dl");
349 	gen_CE = tttgetstr("ce");
350 	gen_CD = tttgetstr("cd");
351 	gen_CL = ttxgetstr("cl");
352 	gen_VS = ttxgetstr("vs");
353 	gen_VE = ttxgetstr("ve");
354 	gen_TI = ttxgetstr("ti");
355 	gen_TE = ttxgetstr("te");
356 	gen_SO = ttxgetstr("so");
357 	gen_SE = ttxgetstr("se");
358 	gen_US = ttxgetstr("us");
359 	gen_UE = ttxgetstr("ue");
360 	gen_LE = ttxgetstr("le");
361 	gen_ND = ttxgetstr("nd");
362 	gen_UP = ttxgetstr("up");
363 	gen_DO = ttxgetstr("do");
364 	gen_BC = ttxgetstr("bc");
365 	gen_NL = ttxgetstr("nl");
366 	gen_CR = ttxgetstr("cr");
367 	gen_HO = ttxgetstr("ho");
368 	gen_AS = ttxgetstr("as");
369 	gen_AE = ttxgetstr("ae");
370 	gen_XS = ttxgetstr("XS");
371 	gen_XE = ttxgetstr("XE");
372 	gen_SF = ttxgetstr("sf");
373 	gen_SR = ttxgetstr("sr");
374 	gen_CS = ttxgetstr("cs");
375 	gen_MI = tgetflag("mi");
376 	gen_MS = tgetflag("ms");
377 	gen_AM = tgetflag("am");
378 	gen_OS = tgetflag("os");
379 	gen_BS = tgetflag("bs");
380 	gen_DA = tgetflag("da");
381 	gen_DB = tgetflag("db");
382 	gen_NS = tgetflag("ns");
383 	gen_XN = tgetflag("xn");
384 	gen_CO = tgetnum("co");
385 	gen_LI = tgetnum("li");
386 	gen_UG = tgetnum("ug");
387 	gen_SG = tgetnum("sg");
388 	if (gen_CL == 0 || gen_OS || gen_CM == 0)
389 		return -1;
390 
391 	/*
392 	 * Deal with obsolete termcap fields.
393 	 */
394 	if (gen_LE == 0)
395 		if (gen_BC)
396 			gen_LE = gen_BC;
397 		else if (gen_BS) {
398 			static struct tt_str bc = { "\b", 1 };
399 			gen_BC = &bc;
400 		}
401 	if (gen_NL == 0) {
402 		static struct tt_str nl = { "\n", 1 };
403 		gen_NL = &nl;
404 	}
405 	if (gen_DO == 0)
406 		gen_DO = gen_NL;
407 	if (gen_CR == 0) {
408 		static struct tt_str cr = { "\r", 1 };
409 		gen_CR = &cr;
410 	}
411 	/*
412 	 * Most terminal will scroll with "nl", but very few specify "sf".
413 	 * We shouldn't use "do" here.
414 	 */
415 	if (gen_SF == 0 && !gen_NS)
416 		gen_SF = gen_NL;
417 	BC = gen_LE ? gen_LE->ts_str : 0;
418 	UP = gen_UP ? gen_UP->ts_str : 0;
419 	/*
420 	 * Fix up display attributes that we can't handle, or don't
421 	 * really exist.
422 	 */
423 	if (gen_SG > 0)
424 		gen_SO = 0;
425 	if (gen_UG > 0 || gen_US && gen_SO && ttstrcmp(gen_US, gen_SO) == 0)
426 		gen_US = 0;
427 
428 	if (gen_DC)
429 		tt.tt_delchar = gen_delchar;
430 	if (gen_AL)
431 		tt.tt_insline = gen_insline;
432 	if (gen_DL)
433 		tt.tt_delline = gen_delline;
434 	if (gen_CE)
435 		tt.tt_clreol = gen_clreol;
436 	if (gen_CD)
437 		tt.tt_clreos = gen_clreos;
438 	if (gen_SF)
439 		tt.tt_scroll_down = gen_scroll_down;
440 	/*
441 	 * Don't allow scroll_up if da or db but not cs.
442 	 * See comment in wwscroll.c.
443 	 */
444 	if (gen_SR && (gen_CS || !gen_DA && !gen_DB))
445 		tt.tt_scroll_up = gen_scroll_up;
446 	if (gen_CS)
447 		tt.tt_setscroll = gen_setscroll;
448 	if (gen_SO)
449 		tt.tt_availmodes |= WWM_REV;
450 	if (gen_US)
451 		tt.tt_availmodes |= WWM_UL;
452 	if (gen_AS)
453 		tt.tt_availmodes |= WWM_GRP;
454 	if (gen_XS)
455 		tt.tt_availmodes |= WWM_USR;
456 	tt.tt_hasinsert = gen_IM || gen_IC;
457 	tt.tt_wrap = gen_AM;
458 	tt.tt_retain = gen_DB;
459 	tt.tt_ncol = gen_CO;
460 	tt.tt_nrow = gen_LI;
461 	tt.tt_init = gen_init;
462 	tt.tt_end = gen_end;
463 	tt.tt_write = gen_write;
464 	tt.tt_putc = gen_putc;
465 	tt.tt_move = gen_move;
466 	tt.tt_clear = gen_clear;
467 	tt.tt_setinsert = gen_setinsert;
468 	tt.tt_setmodes = gen_setmodes;
469 	tt.tt_frame = gen_AS && ttstrcmp(gen_AS, &ansi_AS) == 0 ?
470 		ansi_frame : gen_frame;
471 	return 0;
472 }
473