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