1 /* Copyright (c) 2008, 2009
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Micah Cowan (micah@cowan.name)
5 * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
6 * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007
7 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
8 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
9 * Copyright (c) 1987 Oliver Laumann
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3, or (at your option)
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program (see the file COPYING); if not, see
23 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 ****************************************************************
29 #include <sys/types.h>
36 extern struct display
*display
, *displays
;
37 extern int real_uid
, real_gid
, eff_uid
, eff_gid
;
38 extern struct term term
[]; /* terminal capabilities */
39 extern struct NewWindow nwin_undef
, nwin_default
, nwin_options
;
41 extern int Z0width
, Z1width
;
42 extern int hardstatusemu
;
44 extern struct action umtab
[];
45 extern struct action mmtab
[];
46 extern struct action dmtab
[];
47 extern struct action ktab
[];
48 extern struct kmap_ext
*kmap_exts
;
50 extern int DefaultEsc
;
54 static void AddCap
__P((char *));
55 static void MakeString
__P((char *, char *, int, char *));
56 static char *findcap
__P((char *, char **, int));
57 static int copyarg
__P((char **, char *));
58 static int e_tgetent
__P((char *, char *));
59 static char *e_tgetstr
__P((char *, char **));
60 static int e_tgetflag
__P((char *));
61 static int e_tgetnum
__P((char *));
63 static int findseq_ge
__P((char *, int, unsigned char **));
64 static void setseqoff
__P((unsigned char *, int, int));
65 static int addmapseq
__P((char *, int, int));
66 static int remmapseq
__P((char *, int));
68 static void dumpmap
__P((void));
73 char Termcap
[TERMCAP_BUFSIZE
+ 8]; /* new termcap +8:"TERMCAP=" */
74 static int Termcaplen
;
76 char Term
[MAXSTR
+5]; /* +5: "TERM=" */
77 char screenterm
[20]; /* new $TERM, usually "screen" */
79 char *extra_incap
, *extra_outcap
;
81 static const char TermcapConst
[] = "\\\n\
82 \t:DO=\\E[%dB:LE=\\E[%dD:RI=\\E[%dC:UP=\\E[%dA:bs:bt=\\E[Z:\\\n\
83 \t:cd=\\E[J:ce=\\E[K:cl=\\E[H\\E[J:cm=\\E[%i%d;%dH:ct=\\E[3g:\\\n\
84 \t:do=^J:nd=\\E[C:pt:rc=\\E8:rs=\\Ec:sc=\\E7:st=\\EH:up=\\EM:\\\n\
85 \t:le=^H:bl=^G:cr=^M:it#8:ho=\\E[H:nw=\\EE:ta=^I:is=\\E)0:";
93 if (display
== 0 || s
== 0)
95 for (i
= 0; i
< T_N
; i
++)
97 if (term
[i
].type
!= T_STR
)
99 if (strcmp(term
[i
].tcname
, s
) == 0)
106 * Compile the terminal capabilities for a display.
107 * Input: tgetent(, D_termname) extra_incap, extra_outcap.
108 * Effect: display initialisation.
117 char tbuf
[TERMCAP_BUFSIZE
], *tp
;
118 int t
, xue
, xse
, xme
;
121 bzero(tbuf
, sizeof(tbuf
));
122 debug1("InitTermcap: looking for tgetent('%s')\n", D_termname
);
123 if (*D_termname
== 0 || e_tgetent(tbuf
, D_termname
) != 1)
126 Msg(0, "Cannot find terminfo entry for '%s'.", D_termname
);
128 Msg(0, "Cannot find termcap entry for '%s'.", D_termname
);
132 debug1("got it:\n%s\n", tbuf
);
135 debug1("Extra incap: %s\n", extra_incap
);
137 debug1("Extra outcap: %s\n", extra_outcap
);
140 if ((D_tentry
= (char *)malloc(TERMCAP_BUFSIZE
+ (extra_incap
? strlen(extra_incap
) + 1 : 0))) == 0)
147 * loop through all needed capabilities, record their values in the display
150 for (i
= 0; i
< T_N
; i
++)
155 D_tcs
[i
].flg
= e_tgetflag(term
[i
].tcname
);
158 D_tcs
[i
].num
= e_tgetnum(term
[i
].tcname
);
161 D_tcs
[i
].str
= e_tgetstr(term
[i
].tcname
, &tp
);
162 /* no empty strings, please */
163 if (D_tcs
[i
].str
&& *D_tcs
[i
].str
== 0)
167 Panic(0, "Illegal tc type in entry #%d", i
);
173 * Now a good deal of sanity checks on the retrieved capabilities.
177 Msg(0, "You can't run screen on a hardcopy terminal.");
182 Msg(0, "You can't run screen on a terminal that overstrikes.");
187 Msg(0, "Clear screen capability required.");
192 Msg(0, "Addressable cursor capability required.");
195 if ((s
= getenv("COLUMNS")) && (i
= atoi(s
)) > 0)
197 if ((s
= getenv("LINES")) && (i
= atoi(s
)) > 0)
210 /* standard fixes for xterms etc */
211 /* assume color for everything that looks ansi-compatible */
212 if (!D_CAF
&& D_ME
&& (InStr(D_ME
, "\033[m") || InStr(D_ME
, "\033[0m")))
215 D_CAF
= "\033[3%p1%dm";
216 D_CAB
= "\033[4%p1%dm";
222 if (D_OP
&& InStr(D_OP
, "\033[39;49m"))
224 if (D_OP
&& (InStr(D_OP
, "\033[m") || InStr(D_OP
, "\033[0m")))
227 if ((D_EA
&& InStr(D_EA
, "\033(B")) || (D_AS
&& InStr(D_AS
, "\033(0")))
229 if (InStr(D_termname
, "xterm") || InStr(D_termname
, "rxvt"))
231 /* "be" seems to be standard for xterms... */
235 if (nwin_options
.flowflag
== nwin_undef
.flowflag
)
236 nwin_default
.flowflag
= D_CNF
? FLOW_NOW
* 0 :
237 D_NX
? FLOW_NOW
* 1 :
239 D_CLP
|= (!D_AM
|| D_XV
|| D_XN
);
255 * Set up attribute handling.
256 * This is rather complicated because termcap has different
264 /* Unfortunatelly there is no 'mg' capability.
265 * For now we think that mg > 0 if sg and ug > 0.
267 if (D_UG
> 0 && D_SG
> 0)
268 D_MH
= D_MD
= D_MR
= D_MB
= D_ME
= 0;
274 if (D_SO
&& D_SE
== 0)
276 Msg(0, "Warning: 'so' but no 'se' capability.");
282 if (D_US
&& D_UE
== 0)
284 Msg(0, "Warning: 'us' but no 'ue' capability.");
290 if ((D_MH
|| D_MD
|| D_MR
|| D_MB
) && D_ME
== 0)
292 Msg(0, "Warning: 'm?' but no 'me' capability.");
293 D_MH
= D_MD
= D_MR
= D_MB
= 0;
296 * Does ME also reverse the effect of SO and/or US? This is not
297 * clearly specified by the termcap manual. Anyway, we should at
298 * least look whether ME and SE/UE are equal:
300 if (D_UE
&& D_SE
&& strcmp(D_SE
, D_UE
) == 0)
302 if (D_SE
&& D_ME
&& strcmp(D_ME
, D_SE
) == 0)
304 if (D_UE
&& D_ME
&& strcmp(D_ME
, D_UE
) == 0)
307 for (i
= 0; i
< NATTR
; i
++)
309 D_attrtab
[i
] = D_tcs
[T_ATTR
+ i
].str
;
310 D_attrtyp
[i
] = i
== ATTR_SO
? xse
: (i
== ATTR_US
? xue
: xme
);
313 /* Set up missing entries (attributes are priority ordered) */
316 for (i
= 0; i
< NATTR
; i
++)
317 if ((s
= D_attrtab
[i
]))
322 for (i
= 0; i
< NATTR
; i
++)
324 if (D_attrtab
[i
] == 0)
335 if (D_CAF
|| D_CAB
|| D_CSF
|| D_CSB
)
338 D_BE
= 1; /* screen erased with background color */
348 /* some strange termcap entries have IC == IM */
349 if (D_IC
&& D_IM
&& strcmp(D_IC
, D_IM
) == 0)
365 D_CS0
= "\033(%p1%c";
374 else if (D_AC
|| (D_AS
&& D_AE
)) /* some kind of graphics */
376 D_CS0
= (D_AS
&& D_AE
) ? D_AS
: "";
377 D_CE0
= (D_AS
&& D_AE
) ? D_AE
: "";
384 D_AC
= ""; /* enable default string */
387 for (i
= 0; i
< 256; i
++)
391 /* init with default string first */
392 s
= "l+m+k+j+u+t+v+w+q-x|n+o~s_p\"r#`+a:f'g#~o.v-^+<,>h#I#0#y<z>";
393 for (i
= strlen(s
) & ~1; i
>= 0; i
-= 2)
394 D_c0_tab
[(int)(unsigned char)s
[i
]] = s
[i
+ 1];
397 for (i
= strlen(D_CC0
) & ~1; i
>= 0; i
-= 2)
398 D_c0_tab
[(int)(unsigned char)D_CC0
[i
]] = D_CC0
[i
+ 1];
399 debug1("ISO2022 = %d\n", D_CG0
);
403 debug2("terminal size is %d, %d (says TERMCAP)\n", D_CO
, D_LI
);
407 if (CreateTransTable(D_CXC
))
411 /* Termcap fields Z0 & Z1 contain width-changing sequences. */
419 if (D_TS
== 0 || D_FS
== 0 || D_DS
== 0)
423 debug("oy! we have a hardware status line, says termcap\n");
427 D_has_hstatus
= hardstatusemu
& ~HSTATUS_ALWAYS
;
428 if (D_HS
&& !(hardstatusemu
& HSTATUS_ALWAYS
))
429 D_has_hstatus
= HSTATUS_HS
;
434 int enc
= FindEncoding(D_CKJ
);
439 if (!D_tcs
[T_NAVIGATE
].str
&& D_tcs
[T_NAVIGATE
+ 1].str
)
440 D_tcs
[T_NAVIGATE
].str
= D_tcs
[T_NAVIGATE
+ 1].str
; /* kh = @1 */
441 if (!D_tcs
[T_NAVIGATE
+ 2].str
&& D_tcs
[T_NAVIGATE
+ 3].str
)
442 D_tcs
[T_NAVIGATE
+ 2].str
= D_tcs
[T_NAVIGATE
+ 3].str
; /* kH = @7 */
444 D_UPcost
= CalcCost(D_UP
);
445 D_DOcost
= CalcCost(D_DO
);
446 D_NLcost
= CalcCost(D_NL
);
447 D_LEcost
= CalcCost(D_BC
);
448 D_NDcost
= CalcCost(D_ND
);
449 D_CRcost
= CalcCost(D_CR
);
450 D_IMcost
= CalcCost(D_IM
);
451 D_EIcost
= CalcCost(D_EI
);
456 debug("termcap has AN, setting autonuke\n");
462 debug1("termcap has OL (%d), setting limit\n", D_COL
);
464 D_obuflenmax
= D_obuflen
- D_obufmax
;
467 /* Some xterm entries set F0 and F10 to the same string. Nuke F0. */
468 if (D_tcs
[T_CAPS
].str
&& D_tcs
[T_CAPS
+ 10].str
&& !strcmp(D_tcs
[T_CAPS
].str
, D_tcs
[T_CAPS
+ 10].str
))
469 D_tcs
[T_CAPS
].str
= 0;
470 /* Some xterm entries set kD to ^?. Nuke it. */
471 if (D_tcs
[T_NAVIGATE_DELETE
].str
&& !strcmp(D_tcs
[T_NAVIGATE_DELETE
].str
, "\0177"))
472 D_tcs
[T_NAVIGATE_DELETE
].str
= 0;
473 /* wyse52 entries have kcub1 == kb == ^H. Nuke... */
474 if (D_tcs
[T_CURSOR
+ 3].str
&& !strcmp(D_tcs
[T_CURSOR
+ 3].str
, "\008"))
475 D_tcs
[T_CURSOR
+ 3].str
= 0;
479 for (i
= 0; i
< T_OCAPS
- T_CAPS
; i
++)
481 for (i
= 0; i
< kmap_extn
; i
++)
482 remap(i
+ (KMAP_KEYS
+KMAP_AKEYS
), 1);
483 D_seqp
= D_kmaps
+ 3;
504 int fl
= 0, domap
= 0;
505 struct action
*a1
, *a2
, *tab
;
507 struct kmap_ext
*kme
= 0;
510 if (n
>= KMAP_KEYS
+KMAP_AKEYS
)
512 kme
= kmap_exts
+ (n
- (KMAP_KEYS
+KMAP_AKEYS
));
514 l
= kme
->fl
& ~KMAP_NOTIMEOUT
;
515 fl
= kme
->fl
& KMAP_NOTIMEOUT
;
522 if (n
< KMAP_KEYS
+KMAP_AKEYS
)
526 n
-= T_OCAPS
-T_CURSOR
;
527 s
= D_tcs
[n
+ T_CAPS
].str
;
528 l
= s
? strlen(s
) : 0;
529 if (n
>= T_CURSOR
-T_CAPS
)
530 a2
= &tab
[n
+ (T_OCAPS
-T_CURSOR
)];
532 if (s
== 0 || l
== 0)
534 if (a1
&& a1
->nr
== RC_ILLEGAL
)
536 if (a2
&& a2
->nr
== RC_ILLEGAL
)
538 if (a1
&& a1
->nr
== RC_STUFF
&& a1
->args
[0] && strcmp(a1
->args
[0], s
) == 0)
540 if (a2
&& a2
->nr
== RC_STUFF
&& a2
->args
[0] && strcmp(a2
->args
[0], s
) == 0)
546 a1
= kme
? &kme
->dm
: 0;
548 else if (tab
== dmtab
)
551 a1
= kme
? &kme
->mm
: 0;
558 if (map
== 0 && domap
)
562 debug3("%smapping %s %#x\n", map
? "" :"un",s
,n
);
564 return addmapseq(s
, l
, n
| fl
);
566 return remmapseq(s
, l
);
572 struct display
*odisplay
;
579 for (display
= displays
; display
; display
= display
->d_next
)
581 for (i
= 0; i
< D_nseqs
; i
+= D_kmaps
[i
+ 2] * 2 + 4)
583 nr
= (D_kmaps
[i
] << 8 | D_kmaps
[i
+ 1]) & ~KMAP_NOTIMEOUT
;
584 if (nr
< KMAP_KEYS
+KMAP_AKEYS
)
586 if (umtab
[nr
].nr
== RC_COMMAND
)
588 if (umtab
[nr
].nr
== RC_ILLEGAL
&& dmtab
[nr
].nr
== RC_COMMAND
)
593 struct kmap_ext
*kme
= kmap_exts
+ nr
- (KMAP_KEYS
+KMAP_AKEYS
);
594 if (kme
->um
.nr
== RC_COMMAND
)
596 if (kme
->um
.nr
== RC_ILLEGAL
&& kme
->dm
.nr
== RC_COMMAND
)
606 SetEscape((struct acluser
*)0, Ctrl('a'), 'a');
607 if (odisplay
->d_user
->u_Esc
== -1)
608 odisplay
->d_user
->u_Esc
= DefaultEsc
;
609 if (odisplay
->d_user
->u_MetaEsc
== -1)
610 odisplay
->d_user
->u_MetaEsc
= DefaultMetaEsc
;
612 Msg(0, "Warning: escape char set back to ^A");
617 findseq_ge(seq
, k
, sp
)
626 while (p
- D_kmaps
< D_nseqs
)
632 if (j
== k
|| j
== l
)
634 else if (p
[j
] != ((unsigned char *)seq
)[j
])
635 j
= p
[j
] - ((unsigned char *)seq
)[j
];
666 /* go for the biggest offset */
667 for (q
= p
+ k
* 2 + 4; ; q
+= l
* 2 + 4)
670 if ((q
+ l
* 2 - p
) / 2 >= 256)
672 p
[k
+ 4 + i
] = (q
- p
- 4) / 2;
679 addmapseq(seq
, k
, nr
)
685 unsigned char *p
, *q
;
689 j
= findseq_ge(seq
, k
, &p
);
697 if (D_nseqs
+ 2 * k
+ 4 >= D_aseqs
)
699 D_kmaps
= (unsigned char *)xrealloc((char *)D_kmaps
, D_aseqs
+ 256);
703 D_seqp
= D_kmaps
+ 3;
708 bcopy((char *)p
, (char *)p
+ 2 * k
+ 4, D_nseqs
- i
);
712 bcopy(seq
, (char *)p
+ 3, k
);
713 bzero(p
+ k
+ 3, k
+ 1);
714 D_nseqs
+= 2 * k
+ 4;
719 for (i
= 0; i
< k
; i
++)
721 if (p
[3 + i
] != q
[3 + i
])
726 setseqoff(p
, i
, q
[l
+ 4 + i
] ? q
[l
+ 4 + i
] + k
+ 2: 0);
729 for (q
= D_kmaps
; q
< p
; q
+= 2 * l
+ 4)
732 for (m
= j
= 0; j
< l
; j
++)
735 if (!m
&& q
[3 + j
] != seq
[j
])
737 if (q
[l
+ 4 + j
] == 0)
740 setseqoff(q
, j
, (p
- q
- 4) / 2);
742 else if (q
+ q
[l
+ 4 + j
] * 2 + 4 > p
|| (q
+ q
[l
+ 4 + j
] * 2 + 4 == p
&& !m
))
743 setseqoff(q
, j
, q
[l
+ 4 + j
] + k
+ 2);
758 unsigned char *p
, *q
;
760 if (k
>= 254 || (j
= findseq_ge(seq
, k
, &p
)) != 0)
762 for (q
= D_kmaps
; q
< p
; q
+= 2 * l
+ 4)
765 for (j
= 0; j
< l
; j
++)
767 if (q
+ q
[l
+ 4 + j
] * 2 + 4 == p
)
768 setseqoff(q
, j
, p
[k
+ 4 + j
] ? q
[l
+ 4 + j
] + p
[k
+ 4 + j
] - k
: 0);
769 else if (q
+ q
[l
+ 4 + j
] * 2 + 4 > p
)
770 q
[l
+ 4 + j
] -= k
+ 2;
773 if (D_kmaps
+ D_nseqs
> p
+ 2 * k
+ 4)
774 bcopy((char *)p
+ 2 * k
+ 4, (char *)p
, (D_kmaps
+ D_nseqs
) - (p
+ 2 * k
+ 4));
775 D_nseqs
-= 2 * k
+ 4;
776 D_seqp
= D_kmaps
+ 3;
792 debug("Mappings:\n");
796 while (p
< D_kmaps
+ D_nseqs
)
799 debug1("%d: ", p
- D_kmaps
+ 3);
800 for (j
= 0; j
< l
; j
++)
802 o
= oo
= p
[l
+ 4 + j
];
804 o
= 2 * o
+ 4 + (p
+ 3 + j
- D_kmaps
);
805 if (p
[j
+ 3] > ' ' && p
[j
+ 3] < 0177)
807 debug3("%c[%d:%d] ", p
[j
+ 3], oo
, o
);
810 debug3("\\%03o[%d:%d] ", p
[j
+ 3], oo
, o
);
812 n
= p
[0] << 8 | p
[1];
813 debug2(" ==> %d%s\n", n
& ~KMAP_NOTIMEOUT
, (n
& KMAP_NOTIMEOUT
) ? " (no timeout)" : "");
822 * Appends to the static variable Termcap
830 if (tcLineLen
+ (n
= strlen(s
)) > 55 && Termcaplen
< TERMCAP_BUFSIZE
- 4 - 1)
832 strcpy(Termcap
+ Termcaplen
, "\\\n\t:");
836 if (Termcaplen
+ n
< TERMCAP_BUFSIZE
- 1)
838 strcpy(Termcap
+ Termcaplen
, s
);
843 Panic(0, "TERMCAP overflow - sorry.");
847 * Reads a displays capabilities and reconstructs a termcap entry in the
848 * global buffer "Termcap". A pointer to this buffer is returned.
854 char buf
[TERMCAP_BUFSIZE
];
855 register char *p
, *cp
, *s
, ch
, *tname
;
873 debug1("MakeTermcap(%d)\n", aflag
);
874 if ((s
= getenv("SCREENCAP")) && strlen(s
) < TERMCAP_BUFSIZE
)
876 sprintf(Termcap
, "TERMCAP=%s", s
);
877 strcpy(Term
, "TERM=screen");
878 debug("getenvSCREENCAP o.k.\n");
882 debug1("MakeTermcap screenterm='%s'\n", screenterm
);
883 debug1("MakeTermcap termname='%s'\n", tname
);
884 if (*screenterm
== '\0' || strlen(screenterm
) > MAXSTR
- 3)
886 debug("MakeTermcap sets screenterm=screen\n");
887 strcpy(screenterm
, "screen");
894 strcpy(Term
, "TERM=");
896 if (!aflag
&& strlen(screenterm
) + strlen(tname
) < MAXSTR
-1)
898 sprintf(p
, "%s.%s", screenterm
, tname
);
899 if (e_tgetent(buf
, p
) == 1)
903 if (nwin_default
.bce
)
905 sprintf(p
, "%s-bce", screenterm
);
906 if (e_tgetent(buf
, p
) == 1)
910 #ifdef CHECK_SCREEN_W
913 sprintf(p
, "%s-w", screenterm
);
914 if (e_tgetent(buf
, p
) == 1)
918 strcpy(p
, screenterm
);
919 if (e_tgetent(buf
, p
) == 1)
926 while (0); /* Goto free programming... */
930 /* check for compatibility problems, displays == 0 after fork */
933 char xbuf
[TERMCAP_BUFSIZE
], *xbp
= xbuf
;
934 if (tgetstr("im", &xbp
) && tgetstr("ic", &xbp
) && displays
)
936 Msg(0, "Warning: im and ic set in %s termcap entry", p
);
942 tcLineLen
= 100; /* Force NL */
943 if (strlen(Term
) > TERMCAP_BUFSIZE
- 40)
944 strcpy(Term
, "too_long");
945 sprintf(Termcap
, "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal:", Term
+ 5);
946 Termcaplen
= strlen(Termcap
);
947 debug1("MakeTermcap decided '%s'\n", p
);
948 if (extra_outcap
&& *extra_outcap
)
950 for (cp
= extra_outcap
; (p
= index(cp
, ':')); cp
= p
)
957 tcLineLen
= 100; /* Force NL */
959 debug1("MakeTermcap after outcap '%s'\n", (char *)TermcapConst
);
960 if (Termcaplen
+ strlen(TermcapConst
) < TERMCAP_BUFSIZE
)
962 strcpy(Termcap
+ Termcaplen
, (char *)TermcapConst
);
963 Termcaplen
+= strlen(TermcapConst
);
965 sprintf(buf
, "li#%d:co#%d:", he
, wi
);
968 if (aflag
|| (force_vt
&& !D_COP
) || D_CLP
|| !D_AM
)
974 if (aflag
|| (D_CS
&& D_SR
) || D_AL
|| D_CAL
)
978 AddCap("AL=\\E[%dL:");
983 AddCap("cs=\\E[%i%d;%dr:");
984 if (aflag
|| D_CS
|| D_DL
|| D_CDL
)
987 AddCap("DL=\\E[%dM:");
989 if (aflag
|| D_DC
|| D_CDC
)
992 AddCap("DC=\\E[%dP:");
994 if (aflag
|| D_CIC
|| D_IC
|| D_IM
)
996 AddCap("im=\\E[4h:");
997 AddCap("ei=\\E[4l:");
999 AddCap("IC=\\E[%d@:");
1002 AddCap("ks=\\E[?1h\\E=:");
1003 AddCap("ke=\\E[?1l\\E>:");
1005 AddCap("vi=\\E[?25l:");
1006 AddCap("ve=\\E[34h\\E[?25h:");
1007 AddCap("vs=\\E[34l:");
1008 AddCap("ti=\\E[?1049h:");
1009 AddCap("te=\\E[?1049l:");
1014 AddCap("us=\\E[4m:");
1015 AddCap("ue=\\E[24m:");
1019 AddCap("so=\\E[3m:");
1020 AddCap("se=\\E[23m:");
1023 AddCap("mb=\\E[5m:");
1025 AddCap("md=\\E[1m:");
1027 AddCap("mh=\\E[2m:");
1029 AddCap("mr=\\E[7m:");
1030 if (D_MB
|| D_MD
|| D_MH
|| D_MR
)
1031 AddCap("me=\\E[m:ms:");
1033 AddCap("Co#8:pa#64:AF=\\E[3%dm:AB=\\E[4%dm:op=\\E[39;49m:AX:");
1044 AddCap("CS=\\E[?1h:");
1045 AddCap("CE=\\E[?1l:");
1050 if (D_CC0
|| (D_CS0
&& *D_CS0
))
1052 AddCap("as=\\E(0:");
1053 AddCap("ae=\\E(B:");
1054 /* avoid `` because some shells dump core... */
1055 AddCap("ac=\\140\\140aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++,,hhII00:");
1059 AddCap("po=\\E[5i:");
1060 AddCap("pf=\\E[4i:");
1064 AddCap("Z0=\\E[?3h:");
1065 AddCap("Z1=\\E[?3l:");
1068 AddCap("WS=\\E[8;%d;%dt:");
1070 for (i
= T_CAPS
; i
< T_ECAPS
; i
++)
1076 if (i
>= T_KEYPAD
) /* don't put keypad codes in TERMCAP */
1077 continue; /* - makes it too big */
1078 if (i
>= T_CURSOR
&& i
< T_OCAPS
)
1080 act
= &umtab
[i
- (T_CURSOR
- T_OCAPS
+ T_CAPS
)];
1081 if (act
->nr
== RC_ILLEGAL
)
1082 act
= &dmtab
[i
- (T_CURSOR
- T_OCAPS
+ T_CAPS
)];
1086 act
= &umtab
[i
- T_CAPS
];
1087 if (act
->nr
== RC_ILLEGAL
)
1088 act
= &dmtab
[i
- T_CAPS
];
1090 if (act
->nr
== RC_ILLEGAL
&& (i
== T_NAVIGATE
+ 1 || i
== T_NAVIGATE
+ 3))
1092 /* kh -> @1, kH -> @7 */
1093 act
= &umtab
[i
- T_CAPS
- 1];
1094 if (act
->nr
== RC_ILLEGAL
)
1095 act
= &dmtab
[i
- T_CAPS
- 1];
1097 if (act
->nr
!= RC_ILLEGAL
)
1099 if (act
->nr
== RC_STUFF
)
1101 MakeString(term
[i
].tcname
, buf
, sizeof(buf
), act
->args
[0]);
1110 switch(term
[i
].type
)
1113 if (D_tcs
[i
].str
== 0)
1115 MakeString(term
[i
].tcname
, buf
, sizeof(buf
), D_tcs
[i
].str
);
1119 if (D_tcs
[i
].flg
== 0)
1121 sprintf(buf
, "%s:", term
[i
].tcname
);
1128 debug("MakeTermcap: end\n");
1133 MakeString(cap
, buf
, buflen
, s
)
1138 register char *p
, *pmax
;
1139 register unsigned int c
;
1142 pmax
= p
+ buflen
- (3+4+2);
1146 while ((c
= *s
++) && (p
< pmax
))
1166 sprintf(p
, "\\%03o", c
& 0377);
1185 (*p == '\\' && (p[1] == '\\' || p[1] == ',' || p[1] == '%'))
1200 if ((D_xtable
= (char ***)calloc(256, sizeof(char **))) == 0)
1210 curchar
= (unsigned char)*s
++;
1212 curchar
= 0; /* ASCII */
1216 if (D_xtable
[curchar
] == 0)
1218 if ((D_xtable
[curchar
] = (char **)calloc(257, sizeof(char *))) == 0)
1225 ctable
= D_xtable
[curchar
];
1226 for(; *s
&& *s
!= ','; s
++)
1239 while (*s
&& *s
!= ',')
1241 c
= (unsigned char)*s
++;
1242 if (QUOTES((s
- 1)))
1243 c
= (unsigned char)*s
++;
1249 l
= copyarg(&s
, (char *)0);
1251 l
= l
* templnsub
+ templlen
;
1252 if ((ctable
[c
] = (char *)malloc(l
+ 1)) == 0)
1259 for (p
= ((c
== 256) ? "%" : templ
); *p
&& *p
!= ','; p
++)
1266 sx
+= copyarg(&s
, sx
);
1272 ASSERT(ctable
[c
] + l
* templnsub
+ templlen
== sx
);
1273 debug3("XC: %c %c->%s\n", curchar
, c
, ctable
[c
]);
1287 if ((p
= D_xtable
) == 0)
1289 for (i
= 0; i
< 256; i
++, p
++)
1294 for (j
= 0; j
< 257; j
++, q
++)
1310 for (l
= 0, p
= *pp
; *p
&& *p
!= ','; p
++)
1327 ** Termcap routines that use our extra_incap
1341 r
= tgetent(bp
, name
);
1351 * cap = capability we are looking for
1352 * tepp = pointer to bufferpointer
1353 * n = size of buffer (0 = infinity)
1357 findcap(cap
, tepp
, n
)
1364 int mode
; /* mode: 0=LIT 1=^ 2=\x 3,4,5=\nnn */
1373 for (p
= extra_incap
; *p
; )
1375 if (strncmp(p
, cap
, capl
) == 0)
1379 if (c
&& c
!= ':' && c
!= '@')
1381 if (c
== 0 || c
== '@' || c
== '=' || c
== ':' || c
== '#')
1441 num
= num
* 8 + (c
- '0');
1442 if (mode
++ == 5 || (*p
< '0' || *p
> '9'))
1461 debug2("'%s' found in extra_incap -> %s\n", cap
, tep
);
1469 e_tgetstr(cap
, tepp
)
1474 if ((tep
= findcap(cap
, tepp
, 0)))
1475 return (*tep
== '@') ? 0 : tep
;
1476 return tgetstr(cap
, tepp
);
1486 if ((tep
= findcap(cap
, &bufp
, 2)))
1487 return (*tep
== '@') ? 0 : 1;
1488 return tgetflag(cap
) > 0;
1495 char buf
[20], *bufp
;
1500 if ((tep
= findcap(cap
, &bufp
, 20)))
1508 while ((c
= *tep
++) >= '0' && c
<= '9')
1509 res
= res
* base
+ (c
- '0');
1512 return tgetnum(cap
);