1 /* @(#)ttycmds.c 1.30 21/07/07 Copyright 1984-2021 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)ttycmds.c 1.30 21/07/07 Copyright 1984-2021 J. Schilling";
6 #endif
7 /*
8 * Lower layer support routines for terminal.c
9 *
10 * Copyright (c) 1984-2021 J. Schilling
11 */
12 /*
13 * The contents of this file are subject to the terms of the
14 * Common Development and Distribution License, Version 1.0 only
15 * (the "License"). You may not use this file except in compliance
16 * with the License.
17 *
18 * See the file CDDL.Schily.txt in this distribution for details.
19 * A copy of the CDDL is also available via the Internet at
20 * http://www.opensource.org/licenses/cddl1.txt
21 *
22 * When distributing Covered Code, include this CDDL HEADER in each
23 * file and include the License file CDDL.Schily.txt from this distribution.
24 */
25
26 /*
27 * Exports:
28 * tty_start() - Parse TERMCAP entry and do set up for this package
29 * tty_entry(i) - Return pointer to decoded TERMCAP entries
30 * tty_fkey(i) - Return TERMCAP mapping for function key 'i'
31 * tty_pagesize() - Return the terminal's pagesize from TERMCAP entry
32 * tty_linelength()- Return the terminal's linelength from TERMCAP entry
33 * tty_init() - Initialize terminal (send startup sequence)
34 * tty_term() - Restore terminal to default mode (send term sequence)
35 *
36 * TTY* - Several pointers to apropriate functions
37 * implementing TERMCAP functionality.
38 * These pointers are not intended for direct use by the
39 * higher level software but for terminal.c
40 *
41 * If a specific TERMCAP functionality is not present the corresponding
42 * TTY* function pointer is a NULL pointer.
43 *
44 * If a specific function is not available in a parameterized form directly,
45 * this functionality is emulated by multiple calls to the simple function.
46 * e.g. if your terminal does not support to move the cursor 'n' lines down,
47 * this package calls the cursor-down-single function 'n' times.
48 */
49 #include "ved.h"
50 #include "ttys.h"
51 #include <schily/termcap.h>
52
53 LOCAL int (*sputchar) __PR((int c)) = 0; /* scr putc for tputs*/
54
55 EXPORT void (*TTYclrscreen) __PR((ewin_t *wp)) = 0; /* clr screen */
56 EXPORT void (*TTYclr_endscr) __PR((ewin_t *wp)) = 0; /* clr to end of scr */
57 EXPORT void (*TTYclrendln) __PR((void)) = 0; /* clr to end of line*/
58 EXPORT void (*TTYdelchars) __PR((int)) = 0; /* delete chars */
59 EXPORT void (*TTYdellines) __PR((int)) = 0; /* delete lines */
60 EXPORT void (*TTYinschars) __PR((char *)) = 0; /* insert chars */
61 EXPORT void (*TTYinslines) __PR((int)) = 0; /* insert lines */
62 EXPORT void (*TTYaltvideo) __PR((char *)) = 0; /* alternate video */
63 EXPORT void (*TTYhome) __PR((void)) = 0; /* cursor home */
64 EXPORT void (*TTYup) __PR((int)) = 0; /* cursor up */
65 EXPORT void (*TTYdown) __PR((int)) = 0; /* cursor down */
66 EXPORT void (*TTYleft) __PR((int)) = 0; /* cursor left */
67 EXPORT void (*TTYright) __PR((int)) = 0; /* cursor right */
68 EXPORT void (*TTYcursor) __PR((int y, int x)) = 0; /* move cursor abs */
69 EXPORT void (*TTYsscroll) __PR((int, int)) = 0; /* set scroll region */
70 EXPORT void (*TTYsup) __PR((int)) = 0; /* scroll up */
71 EXPORT void (*TTYsdown) __PR((int)) = 0; /* scroll down */
72
73
74 LOCAL char _stbuf[1024]; /* storage for the decoded termcap entries */
75 LOCAL char *stbp; /* export storage pointer for map.c */
76 LOCAL int pagesize; /* number of lines in a page */
77 LOCAL int linelength; /* numver of characters in a line */
78
79 /*
80 * We add kb=\b to the ansi terminal capabilities in order to be
81 * friendly to people who are using a PC type keyboard.
82 */
83 LOCAL char builtin_ansi[] =
84 "sx|ansi|any ansi terminal with pessimistic assumptions:\
85 :co#80:li#24:cl=50\\E[;H\\E[2J:bs:am:cm=\\E[%i%d;%dH:\
86 :nd=\\E[C:up=\\E[A:ce=\\E[K:ho=\\E[H:pt:kb=\b:";
87
88 #ifdef USE_DUMB
89 LOCAL char builtin_dumb[] = "xx|dumb:";
90 #endif
91
92 #undef HZ /* param.h included ??? */
93 #undef UC /* is defined (unsigned char *) in ved.h*/
94
95 char AM; /* Automatic Margins */
96 char BS; /* Backspace works */
97 char CA; /* Cursor Adressable */
98 char DA; /* Display retained above the Screen */
99 char DB; /* Display retained below the Screen */
100 char EO; /* ca Erase Overstrikes with a blank */
101 char HC; /* Hardcopy Terminal */
102 char HZ; /* Cannot print ~s (Hazeltine) */
103 char IN; /* Insert Mode distinguish nulls */
104 char MI; /* Can move in Insert Mode */
105 char MS; /* Save to move in standout Mode */
106 char NC; /* Not correctly working CR */
107 char NS; /* CRT that does not Scroll */
108 char OS; /* Overstrike works */
109 char UL; /* Underline Character overstrikes */
110 char XB; /* Beehive (f1=ESC, f2=^C) */
111 char XN; /* Newline ignored after 80 cols */
112 char XT; /* TABS destructive, so magic */
113 char XS; /* Standout not erased by overwriting */
114 char XX; /* Tektronix Insert Line */
115
116 char *AL; /* Add 1 line */
117 char *AL_PARM; /* Add n lines */
118 #ifdef OLD_TERMCAP /* 'BC' is now defined in tgoto.c */
119 char *BC; /* Back Cursor movement (Cursor left) */
120 #endif
121 char *BT; /* Back Tab */
122 char *CD; /* Clear to End of Display */
123 char *CE; /* Clear to End of Line */
124 char *CL; /* Clear Scereen */
125 char *CM; /* Cursor Motion */
126 char *CR; /* Carriage return */
127 #undef CS /* We may have included sys/regset.h */
128 char *CS; /* Change scrolling region */
129 char *DC; /* Delete 1 character */
130 char *DC_PARM; /* Delete n characters */
131 char *DL; /* Delete 1 line */
132 char *DL_PARM; /* Delete n lines */
133 char *DM; /* Delete mode enter */
134 char *DO; /* Cursor down 1 line */
135 char *DOWN_PARM; /* Cursor down n lines */
136 char *ED; /* End delete mode */
137 char *EI; /* End insert mode */
138 char *HO; /* Home cursor */
139 char *IC; /* Insert 1 character */
140 char *IC_PARM; /* Insert n characters */
141 char *IM; /* Insert mode (add im=: if has ic=) */
142 char *IP; /* Insert pad after using IM and EI */
143 char *KD; /* Keypad down arrow */
144 char *KE; /* Keypad end transmit mode */
145 char *KH; /* Keypad home key */
146 char *KEK; /* Keypad end key */
147 char *KDK; /* Keypad delete key */
148 char *KL; /* Keypad left arrow */
149 char *KR; /* Keypad right arrow */
150 char *KS; /* Keypad start transmit mode */
151 char *KU; /* Keypad up arrow */
152 char *LEFT_PARM; /* Cursor left n chars */
153 char *LL; /* Move to last line, first column */
154 char *MA; /* Arrow key map */
155 char *MD; /* Bold mode start */
156 char *ME; /* All attribute end */
157 char *ND; /* Non destructive space (Cursor right) */
158 char *NL; /* Linefeed if not NL */
159 char *RC; /* Restore cursor */
160 char *RIGHT_PARM; /* Right n chars */
161 char *SC; /* Save cursor */
162 char *SE; /* Standout end */
163 char *SF; /* Scroll forward 1 line */
164 char *SF_PARM; /* Scroll forward n lines */
165 char *SO; /* Standout begin */
166 char *SR; /* Scroll reverse 1 line */
167 char *SR_PARM; /* Scroll reverse n lines */
168 char *TA; /* Tab if not ^I or need padding */
169 char *TE; /* Terminal end sequence */
170 char *TI; /* Terminal init sequence */
171 char *UC; /* Underscore one char and move past it */
172 char *UE; /* Underscore mode end */
173 #ifdef OLD_TERMCAP /* 'UP' is now defined in tgoto.c */
174 char *UP; /* Cursor up 1 line */
175 #endif
176 char *UP_PARM; /* Cursor up n lines */
177 char *US; /* Underscore mode start */
178 char *VB; /* Visible bell */
179 char *VE; /* Visual end sequence */
180 char *VS; /* Visual start sequence */
181
182 /*
183 * Various function keys (f0 .. f19)
184 */
185 char *K0, *K1, *K2, *K3, *K4, *K5, *K6, *K7, *K8, *K9;
186 char *K10, *K11, *K12, *K13, *K14, *K15, *K16, *K17, *K18, *K19;
187
188 LOCAL char *_PC; /* Pad Character String */
189 #ifdef OLD_TERMCAP /* 'PC' is now defined in tputs.c */
190 char PC; /* Pad Character */
191 #endif
192
193 /*
194 * From the tty modes...
195 */
196 char GT; /* Gtty told us that we may use tabs */
197 char NONL; /* Terminal don't needs linefeed on CR */
198 char UPPERCASE; /* Terminal is upper case only */
199 #ifdef OLD_TERMCAP /* 'ospeed' is now defined in tputs.c */
200 short ospeed = -1; /* Needed to compute padding in tputs() */
201 #endif
202
203 LOCAL char *tflags[] = {
204 &AM, &BS, &DA, &DB, &EO, &HC, &HZ, &IN, &MI,
205 &MS, &NC, &NS, &OS, &UL, &XB, &XN, &XT, &XS,
206 &XX
207 };
208
209 LOCAL char **tstrs[] = {
210 &AL, &BC, &BT, &CD, &CE, &CL, &CM, &CR, &CS,
211 &DC, &DL, &DM, &DO, &ED, &EI, &HO, &IC,
212 &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU,
213 &LL, &MA, &MD, &ME, &ND, &NL, &_PC, &RC, &SC, &SE, &SF,
214 &SO, &SR, &TA, &TE, &TI, &UC, &UE, &UP, &US,
215 &VB, &VS, &VE, &AL_PARM, &DL_PARM, &UP_PARM,
216 &DOWN_PARM, &LEFT_PARM, &RIGHT_PARM, &DC_PARM,
217 &IC_PARM, &SF_PARM, &SR_PARM,
218 &KEK, &KDK,
219 };
220
221 LOCAL char **tfkeys[] = {
222 &K0, &K1, &K2, &K3, &K4, &K5, &K6, &K7, &K8, &K9,
223 &K10, &K11, &K12, &K13, &K14, &K15, &K16, &K17, &K18, &K19,
224 };
225
226 EXPORT char * tty_start __PR((int (*)(int c)));
227 LOCAL void tputstr __PR((char *s));
228 EXPORT char ** tty_entry __PR((void));
229 EXPORT void tty_init __PR((void));
230 EXPORT void tty_term __PR((void));
231 EXPORT char * tty_fkey __PR((int n));
232 EXPORT int tty_pagesize __PR((void));
233 EXPORT int tty_linelength __PR((void));
234 LOCAL void cur_abs __PR((int y, int x));
235 LOCAL void cl_screen __PR((ewin_t *wp));
236 LOCAL void cl_e_screen __PR((ewin_t *wp));
237 LOCAL void cl_e_line __PR((void));
238 LOCAL void home_cursor __PR((void));
239 LOCAL void up_S __PR((int n));
240 LOCAL void up_M __PR((int n));
241 LOCAL void down_S __PR((int n));
242 LOCAL void down_M __PR((int n));
243 LOCAL void left_S __PR((int n));
244 LOCAL void left_M __PR((int n));
245 LOCAL void right_S __PR((int n));
246 LOCAL void right_M __PR((int n));
247 LOCAL void del_c_S __PR((int n));
248 LOCAL void del_c_M __PR((int n));
249 LOCAL void del_l_S __PR((int n));
250 LOCAL void del_l_M __PR((int n));
251 LOCAL void ins_c_S __PR((char *str));
252 LOCAL void ins_c_M __PR((char *str));
253 LOCAL void ins_str __PR((char *str));
254 LOCAL void ins_l_S __PR((int n));
255 LOCAL void ins_l_M __PR((int n));
256 #ifdef __needed__
257 LOCAL void alt_S_Svideo __PR((char *str));
258 #endif
259 LOCAL void alt_S_video __PR((char *str));
260 LOCAL void alt_B_video __PR((char *str));
261 LOCAL void alt_U_video __PR((char *str));
262 LOCAL void sscr __PR((int b, int e));
263 LOCAL void sup_S __PR((int n));
264 LOCAL void sup_M __PR((int n));
265 LOCAL void sdown_S __PR((int n));
266 LOCAL void sdown_M __PR((int n));
267 LOCAL void gettc __PR((void));
268 LOCAL void setupttycmds __PR((void));
269
270
271 /*
272 * Initialization ot the TERMCAP package.
273 * - Read the TERMCAP data base and set pagesize & linelength.
274 * - Set up function key maps.
275 * - Set up pointers to the implementation functions.
276 *
277 * outchar() is a pointer to the function that is used to send
278 * the control sequences to the terminal.
279 *
280 * Returns:
281 * NULL - success
282 * != NULL - pointer to string with error message
283 */
284 EXPORT char *
285 tty_start(outchar)
286 int (*outchar) __PR((int c));
287 {
288 int ret;
289 static char noterm[] = "unknown";
290 char *tname;
291 char *errstr = NULL;
292
293 /*
294 * Look up the TERMCAP database for the current terminal type.
295 * Use some "smart" defaults if "TERM" is not defined or contains junk.
296 */
297 if ((tname = getenv("TERM")) == NULL)
298 tname = noterm;
299 if (tname[0] == '\0')
300 tname = "xx";
301
302 /* unknown = FALSE;*/
303 seterrno(0);
304 if ((ret = tgetent(NULL, tname)) != 1) {
305 char *bp = tcgetbuf();
306
307 /* unknown++;*/
308
309 #ifndef NO_BUILTIN_ANSI
310 if (bp) {
311 if (ret < 0) {
312 errmsgno(EX_BAD,
313 "Cannot open termcap file '%s'.\n", bp);
314 }
315 errmsgno(EX_BAD,
316 "Cannot find description for 'TERM=%s'.\n",
317 tname);
318 errmsgno(EX_BAD,
319 "Using builtin ansi terminal description.\n");
320 errmsgno(EX_BAD,
321 "Please install a termcap file in %s %s.\n",
322 "$HOME/.termcap",
323 "to avoid this message");
324 sleep(1);
325 strcpy(bp, builtin_ansi);
326 } else
327 #endif
328 if (ret == -1) {
329 js_snprintf(_stbuf, sizeof (_stbuf),
330 "Cannot open termcap file.\n");
331 return (_stbuf);
332 } else {
333 js_snprintf(_stbuf, sizeof (_stbuf),
334 "Cannot find terminal type: %s.\n",
335 tname);
336 if (geterrno() == 0)
337 seterrno(EX_BAD);
338 return (_stbuf);
339 }
340 }
341
342 if (errstr) /* XXX */
343 return (errstr);
344
345 #ifdef __never__
346 /*
347 * Do not set up default unless we invented a method to let ved
348 * work on a hardcopy terminal.
349 */
350 if ((pagesize = tgetnum("li")) <= 1)
351 pagesize = 2;
352 if ((linelength = tgetnum("co")) <= 4)
353 linelength = 80;
354 #endif
355
356 /*
357 * Now, parse the content of the TERMCAP data base buffer.
358 */
359 gettc();
360
361 /*
362 * Set up the exported implementation function pointers
363 * and a pointer to the output function.
364 */
365 init_fk_maps();
366 setupttycmds();
367 sputchar = outchar;
368 return (0);
369 }
370
371 LOCAL void
tputstr(s)372 tputstr(s)
373 register char *s;
374 {
375 while (*s) {
376 if (*s == '\n')
377 (*sputchar)('\r');
378 (*sputchar)(*s++);
379 }
380 }
381
382 /*
383 * Return space to be used by tgetstr()
384 */
385 EXPORT char **
tty_entry()386 tty_entry()
387 {
388 return (&stbp);
389 }
390
391 /*
392 * Put Terminal into a mode useful for the TERMCAP packet.
393 */
394 EXPORT void
tty_init()395 tty_init()
396 {
397 if (!XT) GT = 0; /* Do not use tabs if destructive */
398
399 if (TI)
400 tputs(TI, 0, sputchar); /* initialize terminal */
401 if (VS)
402 tputs(VS, 0, sputchar); /* make cursor visible */
403 if (KS)
404 tputs(KS, 0, sputchar); /* start keypad transmit mode */
405
406 }
407
408 /*
409 * Restore Terminal mode to general purpose mode.
410 */
411 EXPORT void
tty_term()412 tty_term()
413 {
414 if (VE && sputchar)
415 tputs(VE, 0, sputchar);
416 if (KE && sputchar)
417 tputs(KE, 0, sputchar);
418 if (TE && sputchar)
419 tputs(TE, 0, sputchar);
420
421 }
422
423 /*
424 * Return decoded strings for function keys.
425 */
426 EXPORT char *
tty_fkey(n)427 tty_fkey(n)
428 int n;
429 {
430 if (n >= 0 && n < (sizeof (tfkeys)/sizeof (tfkeys[0])))
431 return (*tfkeys[n]);
432 return ((char *)0);
433 }
434
435 /*
436 * Return pagesize from TERMCAP entry for TERM.
437 */
438 EXPORT int
tty_pagesize()439 tty_pagesize()
440 {
441 return (pagesize);
442 }
443
444 /*
445 * Return linelength from TERMCAP entry for TERM.
446 */
447 EXPORT int
tty_linelength()448 tty_linelength()
449 {
450 return (linelength);
451 }
452
453 /*
454 * move cursor absolute (Y/row/vpos, X/col/hpos)
455 */
456 LOCAL void
cur_abs(y,x)457 cur_abs(y, x)
458 int y;
459 int x;
460 {
461 tputs(tgoto(CM, x, y), 0, sputchar);
462 }
463
464 /*
465 * clear screen
466 */
467 LOCAL void
cl_screen(wp)468 cl_screen(wp)
469 ewin_t *wp;
470 {
471 tputs(CL, wp->psize, sputchar);
472 }
473
474 /*
475 * clear from cursor to end of screen
476 */
477 LOCAL void
cl_e_screen(wp)478 cl_e_screen(wp)
479 ewin_t *wp;
480 {
481 tputs(CD, wp->psize-cpos.vp, sputchar);
482 }
483
484 /*
485 * clear from cursor to end of line
486 */
487 LOCAL void
cl_e_line()488 cl_e_line()
489 {
490 tputs(CE, 1, sputchar);
491 }
492
493 /*
494 * home cursor
495 */
496 LOCAL void
home_cursor()497 home_cursor()
498 {
499 tputs(HO, 0, sputchar);
500 }
501
502 /*
503 * cursor up - using non parameter mode
504 */
505 LOCAL void
up_S(n)506 up_S(n)
507 register int n;
508 {
509 while (--n >= 0)
510 tputs(UP, 0, sputchar);
511 }
512
513 /*
514 * cursor up - parameter mode
515 */
516 LOCAL void
up_M(n)517 up_M(n)
518 int n;
519 {
520 tputs(tgoto(UP_PARM, 0, n), n, sputchar);
521 }
522
523 /*
524 * cursor down - using non parameter mode
525 */
526 LOCAL void
down_S(n)527 down_S(n)
528 register int n;
529 {
530 while (--n >= 0)
531 tputs(DO, 0, sputchar);
532 }
533
534 /*
535 * cursor down - parameter mode
536 */
537 LOCAL void
down_M(n)538 down_M(n)
539 int n;
540 {
541 tputs(tgoto(DOWN_PARM, 0, n), n, sputchar);
542 }
543
544 /*
545 * cursor left - using non parameter mode
546 */
547 LOCAL void
left_S(n)548 left_S(n)
549 register int n;
550 {
551 while (--n >= 0)
552 tputs(BC, 0, sputchar);
553 }
554
555 /*
556 * cursor left - parameter mode
557 */
558 LOCAL void
left_M(n)559 left_M(n)
560 int n;
561 {
562 tputs(tgoto(LEFT_PARM, 0, n), n, sputchar);
563 }
564
565 /*
566 * cursor right - using non parameter mode
567 */
568 LOCAL void
right_S(n)569 right_S(n)
570 register int n;
571 {
572 while (--n >= 0)
573 tputs(ND, 0, sputchar);
574 }
575
576 /*
577 * cursor right - parameter mode
578 */
579 LOCAL void
right_M(n)580 right_M(n)
581 int n;
582 {
583 tputs(tgoto(RIGHT_PARM, 0, n), n, sputchar);
584 }
585
586 /*
587 * delete chars - using non parameter mode
588 */
589 LOCAL void
del_c_S(n)590 del_c_S(n)
591 register int n;
592 {
593 while (--n >= 0)
594 tputs(DC, 0, sputchar);
595 }
596
597 /*
598 * delete chars - parameter mode
599 */
600 LOCAL void
del_c_M(n)601 del_c_M(n)
602 int n;
603 {
604 tputs(tgoto(DC_PARM, 0, n), n, sputchar);
605 }
606
607 /*
608 * delete lines - using non parameter mode
609 */
610 LOCAL void
del_l_S(n)611 del_l_S(n)
612 register int n;
613 {
614 while (--n >= 0)
615 tputs(DL, 0, sputchar);
616 }
617
618 /*
619 * delete lines - parameter mode
620 */
621 LOCAL void
del_l_M(n)622 del_l_M(n)
623 int n;
624 {
625 tputs(tgoto(DL_PARM, 0, n), n, sputchar);
626 }
627
628 /*
629 * insert chars - using non parameter mode
630 */
631 LOCAL void
ins_c_S(str)632 ins_c_S(str)
633 register char *str;
634 {
635 while (*str) {
636 tputs(IC, 0, sputchar);
637 (*sputchar)(*str++);
638 }
639 }
640
641 /*
642 * insert chars - parameter mode
643 */
644 LOCAL void
ins_c_M(str)645 ins_c_M(str)
646 char *str;
647 {
648 int n = strlen(str);
649
650 tputs(tgoto(IC_PARM, 0, n), n, sputchar);
651 tputstr(str);
652 }
653
654 /*
655 * insert string
656 */
657 LOCAL void
ins_str(str)658 ins_str(str)
659 char *str;
660 {
661 tputs(IM, 0, sputchar);
662 tputstr(str);
663 tputs(EI, 0, sputchar);
664 }
665
666 /*
667 * insert lines - using non parameter mode
668 */
669 LOCAL void
ins_l_S(n)670 ins_l_S(n)
671 register int n;
672 {
673 while (--n >= 0)
674 tputs(AL, 0, sputchar);
675 }
676
677 LOCAL void
678 /*
679 * insert lines - parameter mode
680 */
ins_l_M(n)681 ins_l_M(n)
682 int n;
683 {
684 tputs(tgoto(AL_PARM, 0, n), n, sputchar);
685 }
686
687 #ifdef __needed__
688 /*
689 * alternate video - using non parameter mode
690 * XXX is this function possible with termcap?
691 */
692 LOCAL void
alt_S_Svideo(str)693 alt_S_Svideo(str)
694 register char *str;
695 {
696 while (*str) {
697 /* tputs(SO XXX, 0, sputchar);*/
698 (*sputchar)(*str++);
699 }
700 }
701 #endif
702
703 /*
704 * alternate video - using Standout Mode
705 */
706 LOCAL void
alt_S_video(str)707 alt_S_video(str)
708 register char *str;
709 {
710 tputs(SO, 0, sputchar);
711 tputstr(str);
712 tputs(SE, 0, sputchar);
713 }
714
715 /*
716 * alternate video - using Bold Mode
717 */
718 LOCAL void
alt_B_video(str)719 alt_B_video(str)
720 register char *str;
721 {
722 tputs(MD, 0, sputchar);
723 tputstr(str);
724 tputs(ME, 0, sputchar);
725 }
726
727 /*
728 * alternate video - using Underline Mode
729 */
730 LOCAL void
alt_U_video(str)731 alt_U_video(str)
732 register char *str;
733 {
734 tputs(US, 0, sputchar);
735 tputstr(str);
736 tputs(UE, 0, sputchar);
737 }
738
739 /*
740 * set scroll region
741 */
742 LOCAL void
sscr(b,e)743 sscr(b, e)
744 int b;
745 int e;
746 {
747 tputs(tgoto(CS, e, b), 0, sputchar);
748 }
749
750 /*
751 * scroll up - using non parameter mode
752 */
753 LOCAL void
sup_S(n)754 sup_S(n)
755 register int n;
756 {
757 while (--n >= 0)
758 tputs(SF, 0, sputchar);
759 }
760
761 /*
762 * scroll up - parameter mode
763 */
764 LOCAL void
sup_M(n)765 sup_M(n)
766 int n;
767 {
768 tputs(tgoto(SF_PARM, 0, n), n, sputchar);
769 }
770
771 /*
772 * scroll down - using non parameter mode
773 */
774 LOCAL void
sdown_S(n)775 sdown_S(n)
776 register int n;
777 {
778 while (--n >= 0)
779 tputs(SR, 0, sputchar);
780 }
781
782 /*
783 * scroll down - parameter mode
784 */
785 LOCAL void
sdown_M(n)786 sdown_M(n)
787 int n;
788 {
789 tputs(tgoto(SR_PARM, 0, n), n, sputchar);
790 }
791
792 /*
793 * Get Flags and Strings from Termcap Entry
794 */
795 LOCAL void
gettc()796 gettc()
797 {
798 register char *np;
799 register char **fp;
800 register char ***sp;
801 char *sbp;
802
803 sbp = _stbuf;
804
805 /*
806 * Parse boolean flags.
807 */
808 np = "ambsdadbeohchzinmimsncnsosulxbxnxtxsxx";
809 fp = tflags;
810 do {
811 *(*fp++) = tgetflag(np);
812 np += 2;
813 } while (*np);
814
815 /*
816 * Parse string capabilities.
817 */
818 np = "albcbtcdceclcmcrcsdcdldmdoedeihoicimipkdkekhklkrkskullmamdmendnlpcrcscsesfsosrtatetiucueupusvbvsveALDLUPDOLERIDCICSFSR@7kD";
819 sp = tstrs;
820 do {
821 *(*sp++) = tgetstr(np, &sbp);
822 np += 2;
823 } while (*np);
824
825 /*
826 * Parse function key values.
827 */
828 np = "k0k1k2k3k4k5k6k7k8k9k;F1F2F3F4F5F6F7F8F9";
829 sp = tfkeys;
830 do {
831 *(*sp++) = tgetstr(np, &sbp);
832 np += 2;
833 } while (*np);
834
835 stbp = sbp;
836
837 if (XS) {
838 SO = SE = NULL;
839 } else {
840 /*
841 * Enter/Exit Standout Glitch present?
842 */
843 if (tgetnum("sg") > 0) /* # of glitch chars left by so or se*/
844 SO = NULL;
845 /*
846 * Enter/Exit Underline Glitch present?
847 */
848 if (tgetnum("ug") > 0) /* # of glitch chars left by us or ue*/
849 US = NULL;
850 if (!SO && US) {
851 SO = US;
852 SE = UE;
853 }
854 }
855
856 /*
857 * Handle funny termcap capabilities
858 */
859 if (CS && SC && RC) AL = DL = ""; /* XXX */
860 if (AL_PARM && AL == NULL) AL = "";
861 if (DL_PARM && DL == NULL) DL = "";
862 if (IC && IM == NULL) IM = "";
863 if (IC && EI == NULL) EI = "";
864 if (IM == NULL || EI == NULL) IM = EI = NULL;
865 if (!XT) GT = 0; /* Do not use tabs if destructive */
866 if (!GT) BT = NULL; /* If we can't tab, we can't backtab either */
867
868 if (tgoto(CM, 2, 2)[0] == 'O')
869 CA = FALSE, CM = 0;
870 else
871 CA = TRUE;
872
873 PC = _PC ? _PC[0] : '\0';
874
875 /* if (unknown)*/
876 /* return ERR;*/
877 /* return OK;*/
878 }
879
880 LOCAL void
setupttycmds()881 setupttycmds()
882 {
883 #ifdef CURSOR
884 char *ku;
885 char *kd;
886 char *kr;
887 char *kl;
888 char *kB;
889 char *kE;
890 #endif
891
892 #ifdef CURSOR
893 ku = tgetstr("ku", &sbp); /* Corsor up */
894 kd = tgetstr("kd", &sbp); /* Corsor down */
895 kr = tgetstr("kr", &sbp); /* Corsor forward */
896 kl = tgetstr("kl", &sbp); /* Corsor left */
897 kB = tgetstr("kB", &sbp); /* Corsor leftmost */
898 kE = tgetstr("kE", &sbp); /* Corsor rightmost */
899 if (ku) _add_map(ku, ""); /* Corsor up */
900 if (kd) _add_map(kd, ""); /* Corsor down */
901 if (kr) _add_map(kr, ""); /* Corsor forward */
902 if (kl) _add_map(kl, ""); /* Corsor left */
903 if (kB) _add_map(kB, ""); /* Corsor leftmost */
904 if (kE) _add_map(kE, ""); /* Corsor rightmost */
905 #endif
906
907 if (CA)
908 TTYcursor = cur_abs;
909 if (CL)
910 TTYclrscreen = cl_screen;
911 if (CD)
912 TTYclr_endscr = cl_e_screen;
913 if (CE)
914 TTYclrendln = cl_e_line;
915 if (HO)
916 TTYhome = home_cursor;
917
918 if (UP_PARM)
919 TTYup = up_M;
920 else if (UP)
921 TTYup = up_S;
922 if (DOWN_PARM)
923 TTYdown = down_M;
924 else if (DO)
925 TTYdown = down_S;
926 if (LEFT_PARM)
927 TTYleft = left_M;
928 else if (BC)
929 TTYleft = left_S;
930 if (RIGHT_PARM)
931 TTYright = right_M;
932 else if (ND)
933 TTYright = right_S;
934
935 if (DC_PARM)
936 TTYdelchars = del_c_M;
937 else if (DC)
938 TTYdelchars = del_c_S;
939 if (DL_PARM)
940 TTYdellines = del_l_M;
941 else if (DL && *DL)
942 TTYdellines = del_l_S;
943
944 if (IC_PARM)
945 TTYinschars = ins_c_M;
946 /*
947 * Pr�fen, wann IM und EI im vi verwendet werden !!!
948 * Es sieht so aus, als ob im vi hier der volle Pfusch abgeht.
949 * Mal nimmt er er IM und EI, mal nimmt er IC.
950 * Man mu� hier wohl sehr vorsichtig sein, was die Richtigkeit
951 * der Termcap Eintr�ge angeht, denn die sind wohl auf das Chaos
952 * im vi abgestimmt. Nach vorsichtiger Betrachtung scheint der vi
953 * auf eine sehr komplexe Art beides geschachtelt zu verwenden.
954 */
955 else if (IM && *IM)
956 TTYinschars = ins_str;
957 else if (IC)
958 TTYinschars = ins_c_S;
959 if (AL_PARM)
960 TTYinslines = ins_l_M;
961 else if (AL && *AL)
962 TTYinslines = ins_l_S;
963
964 if (SO && SE)
965 TTYaltvideo = alt_S_video;
966 else if (MD && ME)
967 TTYaltvideo = alt_B_video;
968 else if (US && UE)
969 TTYaltvideo = alt_U_video;
970
971 if (CS)
972 TTYsscroll = sscr;
973
974 if (SF_PARM)
975 TTYsup = sup_M;
976 else if (!NS) {
977 SF = "\n";
978 TTYsup = sup_S;
979 } else if (SF)
980 TTYsup = sup_S;
981
982 if (SR_PARM)
983 TTYsdown = sdown_M;
984 else if (SR)
985 TTYsdown = sdown_S;
986 }
987