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