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