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