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