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