1 /* Copyright (c) 1993-2002
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Copyright (c) 1987 Oliver Laumann
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file COPYING); if not, write to the
18 * Free Software Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 ****************************************************************
24 #include <sys/types.h>
31 extern struct display
*display
, *displays
;
32 extern int real_uid
, real_gid
, eff_uid
, eff_gid
;
33 extern struct term term
[]; /* terminal capabilities */
34 extern struct NewWindow nwin_undef
, nwin_default
, nwin_options
;
36 extern int Z0width
, Z1width
;
37 extern int hardstatusemu
;
39 extern struct action umtab
[];
40 extern struct action mmtab
[];
41 extern struct action dmtab
[];
42 extern struct action ktab
[];
43 extern struct kmap_ext
*kmap_exts
;
45 extern int DefaultEsc
;
49 static void AddCap
__P((char *));
50 static void MakeString
__P((char *, char *, int, char *));
51 static char *findcap
__P((char *, char **, int));
52 static int copyarg
__P((char **, char *));
53 static int e_tgetent
__P((char *, char *));
54 static char *e_tgetstr
__P((char *, char **));
55 static int e_tgetflag
__P((char *));
56 static int e_tgetnum
__P((char *));
58 static int findseq_ge
__P((char *, int, unsigned char **));
59 static void setseqoff
__P((unsigned char *, int, int));
60 static int addmapseq
__P((char *, int, int));
61 static int remmapseq
__P((char *, int));
63 static void dumpmap
__P((void));
68 char Termcap
[TERMCAP_BUFSIZE
+ 8]; /* new termcap +8:"TERMCAP=" */
69 static int Termcaplen
;
71 char Term
[MAXSTR
+5]; /* +5: "TERM=" */
72 char screenterm
[20]; /* new $TERM, usually "screen" */
74 char *extra_incap
, *extra_outcap
;
76 static const char TermcapConst
[] = "\\\n\
77 \t:DO=\\E[%dB:LE=\\E[%dD:RI=\\E[%dC:UP=\\E[%dA:bs:bt=\\E[Z:\\\n\
78 \t:cd=\\E[J:ce=\\E[K:cl=\\E[H\\E[J:cm=\\E[%i%d;%dH:ct=\\E[3g:\\\n\
79 \t:do=^J:nd=\\E[C:pt:rc=\\E8:rs=\\Ec:sc=\\E7:st=\\EH:up=\\EM:\\\n\
80 \t:le=^H:bl=^G:cr=^M:it#8:ho=\\E[H:nw=\\EE:ta=^I:is=\\E)0:";
88 if (display
== 0 || s
== 0)
90 for (i
= 0; i
< T_N
; i
++)
92 if (term
[i
].type
!= T_STR
)
94 if (strcmp(term
[i
].tcname
, s
) == 0)
101 * Compile the terminal capabilities for a display.
102 * Input: tgetent(, D_termname) extra_incap, extra_outcap.
103 * Effect: display initialisation.
112 char tbuf
[TERMCAP_BUFSIZE
], *tp
;
113 int t
, xue
, xse
, xme
;
116 bzero(tbuf
, sizeof(tbuf
));
117 debug1("InitTermcap: looking for tgetent('%s')\n", D_termname
);
118 if (*D_termname
== 0 || e_tgetent(tbuf
, D_termname
) != 1)
121 Msg(0, "Cannot find terminfo entry for '%s'.", D_termname
);
123 Msg(0, "Cannot find termcap entry for '%s'.", D_termname
);
127 debug1("got it:\n%s\n", tbuf
);
130 debug1("Extra incap: %s\n", extra_incap
);
132 debug1("Extra outcap: %s\n", extra_outcap
);
135 if ((D_tentry
= (char *)malloc(TERMCAP_BUFSIZE
+ (extra_incap
? strlen(extra_incap
) + 1 : 0))) == 0)
142 * loop through all needed capabilities, record their values in the display
145 for (i
= 0; i
< T_N
; i
++)
150 D_tcs
[i
].flg
= e_tgetflag(term
[i
].tcname
);
153 D_tcs
[i
].num
= e_tgetnum(term
[i
].tcname
);
156 D_tcs
[i
].str
= e_tgetstr(term
[i
].tcname
, &tp
);
157 /* no empty strings, please */
158 if (D_tcs
[i
].str
&& *D_tcs
[i
].str
== 0)
162 Panic(0, "Illegal tc type in entry #%d", i
);
168 * Now a good deal of sanity checks on the retrieved capabilities.
172 Msg(0, "You can't run screen on a hardcopy terminal.");
177 Msg(0, "You can't run screen on a terminal that overstrikes.");
182 Msg(0, "Clear screen capability required.");
187 Msg(0, "Addressable cursor capability required.");
190 if ((s
= getenv("COLUMNS")) && (i
= atoi(s
)) > 0)
192 if ((s
= getenv("LINES")) && (i
= atoi(s
)) > 0)
205 /* standard fixes for xterms etc */
206 /* assume color for everything that looks ansi-compatible */
207 if (!D_CAF
&& D_ME
&& (InStr(D_ME
, "\033[m") || InStr(D_ME
, "\033[0m")))
210 D_CAF
= "\033[3%p1%dm";
211 D_CAB
= "\033[4%p1%dm";
217 if (D_OP
&& InStr(D_OP
, "\033[39;49m"))
219 if (D_OP
&& (InStr(D_OP
, "\033[m") || InStr(D_OP
, "\033[0m")))
222 if ((D_EA
&& InStr(D_EA
, "\033(B")) || (D_AS
&& InStr(D_AS
, "\033(0")))
224 if (InStr(D_termname
, "xterm") || InStr(D_termname
, "rxvt"))
226 /* "be" seems to be standard for xterms... */
230 if (nwin_options
.flowflag
== nwin_undef
.flowflag
)
231 nwin_default
.flowflag
= D_CNF
? FLOW_NOW
* 0 :
232 D_NX
? FLOW_NOW
* 1 :
234 D_CLP
|= (!D_AM
|| D_XV
|| D_XN
);
250 * Set up attribute handling.
251 * This is rather complicated because termcap has different
259 /* Unfortunatelly there is no 'mg' capability.
260 * For now we think that mg > 0 if sg and ug > 0.
262 if (D_UG
> 0 && D_SG
> 0)
263 D_MH
= D_MD
= D_MR
= D_MB
= D_ME
= 0;
269 if (D_SO
&& D_SE
== 0)
271 Msg(0, "Warning: 'so' but no 'se' capability.");
277 if (D_US
&& D_UE
== 0)
279 Msg(0, "Warning: 'us' but no 'ue' capability.");
285 if ((D_MH
|| D_MD
|| D_MR
|| D_MB
) && D_ME
== 0)
287 Msg(0, "Warning: 'm?' but no 'me' capability.");
288 D_MH
= D_MD
= D_MR
= D_MB
= 0;
291 * Does ME also reverse the effect of SO and/or US? This is not
292 * clearly specified by the termcap manual. Anyway, we should at
293 * least look whether ME and SE/UE are equal:
295 if (D_UE
&& D_SE
&& strcmp(D_SE
, D_UE
) == 0)
297 if (D_SE
&& D_ME
&& strcmp(D_ME
, D_SE
) == 0)
299 if (D_UE
&& D_ME
&& strcmp(D_ME
, D_UE
) == 0)
302 for (i
= 0; i
< NATTR
; i
++)
304 D_attrtab
[i
] = D_tcs
[T_ATTR
+ i
].str
;
305 D_attrtyp
[i
] = i
== ATTR_SO
? xse
: (i
== ATTR_US
? xue
: xme
);
308 /* Set up missing entries (attributes are priority ordered) */
311 for (i
= 0; i
< NATTR
; i
++)
312 if ((s
= D_attrtab
[i
]))
317 for (i
= 0; i
< NATTR
; i
++)
319 if (D_attrtab
[i
] == 0)
330 if (D_CAF
|| D_CAB
|| D_CSF
|| D_CSB
)
333 D_BE
= 1; /* screen erased with background color */
343 /* some strange termcap entries have IC == IM */
344 if (D_IC
&& D_IM
&& strcmp(D_IC
, D_IM
) == 0)
360 D_CS0
= "\033(%p1%c";
369 else if (D_AC
|| (D_AS
&& D_AE
)) /* some kind of graphics */
371 D_CS0
= (D_AS
&& D_AE
) ? D_AS
: "";
372 D_CE0
= (D_AS
&& D_AE
) ? D_AE
: "";
379 D_AC
= ""; /* enable default string */
382 for (i
= 0; i
< 256; i
++)
386 /* init with default string first */
387 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>";
388 for (i
= strlen(s
) & ~1; i
>= 0; i
-= 2)
389 D_c0_tab
[(int)(unsigned char)s
[i
]] = s
[i
+ 1];
392 for (i
= strlen(D_CC0
) & ~1; i
>= 0; i
-= 2)
393 D_c0_tab
[(int)(unsigned char)D_CC0
[i
]] = D_CC0
[i
+ 1];
394 debug1("ISO2022 = %d\n", D_CG0
);
398 debug2("terminal size is %d, %d (says TERMCAP)\n", D_CO
, D_LI
);
402 if (CreateTransTable(D_CXC
))
406 /* Termcap fields Z0 & Z1 contain width-changing sequences. */
414 if (D_TS
== 0 || D_FS
== 0 || D_DS
== 0)
418 debug("oy! we have a hardware status line, says termcap\n");
422 D_has_hstatus
= hardstatusemu
& ~HSTATUS_ALWAYS
;
423 if (D_HS
&& !(hardstatusemu
& HSTATUS_ALWAYS
))
424 D_has_hstatus
= HSTATUS_HS
;
429 int enc
= FindEncoding(D_CKJ
);
434 if (!D_tcs
[T_NAVIGATE
].str
&& D_tcs
[T_NAVIGATE
+ 1].str
)
435 D_tcs
[T_NAVIGATE
].str
= D_tcs
[T_NAVIGATE
+ 1].str
; /* kh = @1 */
436 if (!D_tcs
[T_NAVIGATE
+ 2].str
&& D_tcs
[T_NAVIGATE
+ 3].str
)
437 D_tcs
[T_NAVIGATE
+ 2].str
= D_tcs
[T_NAVIGATE
+ 3].str
; /* kH = @7 */
439 D_UPcost
= CalcCost(D_UP
);
440 D_DOcost
= CalcCost(D_DO
);
441 D_NLcost
= CalcCost(D_NL
);
442 D_LEcost
= CalcCost(D_BC
);
443 D_NDcost
= CalcCost(D_ND
);
444 D_CRcost
= CalcCost(D_CR
);
445 D_IMcost
= CalcCost(D_IM
);
446 D_EIcost
= CalcCost(D_EI
);
451 debug("termcap has AN, setting autonuke\n");
457 debug1("termcap has OL (%d), setting limit\n", D_COL
);
459 D_obuflenmax
= D_obuflen
- D_obufmax
;
462 /* Some xterm entries set F0 and F10 to the same string. Nuke F0. */
463 if (D_tcs
[T_CAPS
].str
&& D_tcs
[T_CAPS
+ 10].str
&& !strcmp(D_tcs
[T_CAPS
].str
, D_tcs
[T_CAPS
+ 10].str
))
464 D_tcs
[T_CAPS
].str
= 0;
465 /* Some xterm entries set kD to ^?. Nuke it. */
466 if (D_tcs
[T_NAVIGATE_DELETE
].str
&& !strcmp(D_tcs
[T_NAVIGATE_DELETE
].str
, "\0177"))
467 D_tcs
[T_NAVIGATE_DELETE
].str
= 0;
468 /* wyse52 entries have kcub1 == kb == ^H. Nuke... */
469 if (D_tcs
[T_CURSOR
+ 3].str
&& !strcmp(D_tcs
[T_CURSOR
+ 3].str
, "\008"))
470 D_tcs
[T_CURSOR
+ 3].str
= 0;
474 for (i
= 0; i
< T_OCAPS
- T_CAPS
; i
++)
476 for (i
= 0; i
< kmap_extn
; i
++)
477 remap(i
+ (KMAP_KEYS
+KMAP_AKEYS
), 1);
478 D_seqp
= D_kmaps
+ 3;
499 int fl
= 0, domap
= 0;
500 struct action
*a1
, *a2
, *tab
;
502 struct kmap_ext
*kme
= 0;
505 if (n
>= KMAP_KEYS
+KMAP_AKEYS
)
507 kme
= kmap_exts
+ (n
- (KMAP_KEYS
+KMAP_AKEYS
));
509 l
= kme
->fl
& ~KMAP_NOTIMEOUT
;
510 fl
= kme
->fl
& KMAP_NOTIMEOUT
;
517 if (n
< KMAP_KEYS
+KMAP_AKEYS
)
521 n
-= T_OCAPS
-T_CURSOR
;
522 s
= D_tcs
[n
+ T_CAPS
].str
;
523 l
= s
? strlen(s
) : 0;
524 if (n
>= T_CURSOR
-T_CAPS
)
525 a2
= &tab
[n
+ (T_OCAPS
-T_CURSOR
)];
527 if (s
== 0 || l
== 0)
529 if (a1
&& a1
->nr
== RC_ILLEGAL
)
531 if (a2
&& a2
->nr
== RC_ILLEGAL
)
533 if (a1
&& a1
->nr
== RC_STUFF
&& strcmp(a1
->args
[0], s
) == 0)
535 if (a2
&& a2
->nr
== RC_STUFF
&& strcmp(a2
->args
[0], s
) == 0)
541 a1
= kme
? &kme
->dm
: 0;
543 else if (tab
== dmtab
)
546 a1
= kme
? &kme
->mm
: 0;
553 if (map
== 0 && domap
)
557 debug3("%smapping %s %#x\n", map
? "" :"un",s
,n
);
559 return addmapseq(s
, l
, n
| fl
);
561 return remmapseq(s
, l
);
567 struct display
*odisplay
;
574 for (display
= displays
; display
; display
= display
->d_next
)
576 for (i
= 0; i
< D_nseqs
; i
+= D_kmaps
[i
+ 2] * 2 + 4)
578 nr
= (D_kmaps
[i
] << 8 | D_kmaps
[i
+ 1]) & ~KMAP_NOTIMEOUT
;
579 if (nr
< KMAP_KEYS
+KMAP_AKEYS
)
581 if (umtab
[nr
].nr
== RC_COMMAND
)
583 if (umtab
[nr
].nr
== RC_ILLEGAL
&& dmtab
[nr
].nr
== RC_COMMAND
)
588 struct kmap_ext
*kme
= kmap_exts
+ nr
- (KMAP_KEYS
+KMAP_AKEYS
);
589 if (kme
->um
.nr
== RC_COMMAND
)
591 if (kme
->um
.nr
== RC_ILLEGAL
&& kme
->dm
.nr
== RC_COMMAND
)
601 SetEscape((struct acluser
*)0, Ctrl('a'), 'a');
602 if (odisplay
->d_user
->u_Esc
== -1)
603 odisplay
->d_user
->u_Esc
= DefaultEsc
;
604 if (odisplay
->d_user
->u_MetaEsc
== -1)
605 odisplay
->d_user
->u_MetaEsc
= DefaultMetaEsc
;
607 Msg(0, "Warning: escape char set back to ^A");
612 findseq_ge(seq
, k
, sp
)
621 while (p
- D_kmaps
< D_nseqs
)
627 if (j
== k
|| j
== l
)
629 else if (p
[j
] != ((unsigned char *)seq
)[j
])
630 j
= p
[j
] - ((unsigned char *)seq
)[j
];
661 /* go for the biggest offset */
662 for (q
= p
+ k
* 2 + 4; ; q
+= l
* 2 + 4)
665 if ((q
+ l
* 2 - p
) / 2 >= 256)
667 p
[k
+ 4 + i
] = (q
- p
- 4) / 2;
674 addmapseq(seq
, k
, nr
)
680 unsigned char *p
, *q
;
684 j
= findseq_ge(seq
, k
, &p
);
692 if (D_nseqs
+ 2 * k
+ 4 >= D_aseqs
)
694 D_kmaps
= (unsigned char *)xrealloc((char *)D_kmaps
, D_aseqs
+ 256);
698 D_seqp
= D_kmaps
+ 3;
703 bcopy((char *)p
, (char *)p
+ 2 * k
+ 4, D_nseqs
- i
);
707 bcopy(seq
, (char *)p
+ 3, k
);
708 bzero(p
+ k
+ 3, k
+ 1);
709 D_nseqs
+= 2 * k
+ 4;
714 for (i
= 0; i
< k
; i
++)
716 if (p
[3 + i
] != q
[3 + i
])
721 setseqoff(p
, i
, q
[l
+ 4 + i
] ? q
[l
+ 4 + i
] + k
+ 2: 0);
724 for (q
= D_kmaps
; q
< p
; q
+= 2 * l
+ 4)
727 for (m
= j
= 0; j
< l
; j
++)
730 if (!m
&& q
[3 + j
] != seq
[j
])
732 if (q
[l
+ 4 + j
] == 0)
735 setseqoff(q
, j
, (p
- q
- 4) / 2);
737 else if (q
+ q
[l
+ 4 + j
] * 2 + 4 > p
|| (q
+ q
[l
+ 4 + j
] * 2 + 4 == p
&& !m
))
738 setseqoff(q
, j
, q
[l
+ 4 + j
] + k
+ 2);
753 unsigned char *p
, *q
;
755 if (k
>= 254 || (j
= findseq_ge(seq
, k
, &p
)) != 0)
757 for (q
= D_kmaps
; q
< p
; q
+= 2 * l
+ 4)
760 for (j
= 0; j
< l
; j
++)
762 if (q
+ q
[l
+ 4 + j
] * 2 + 4 == p
)
763 setseqoff(q
, j
, p
[k
+ 4 + j
] ? q
[l
+ 4 + j
] + p
[k
+ 4 + j
] - k
: 0);
764 else if (q
+ q
[l
+ 4 + j
] * 2 + 4 > p
)
765 q
[l
+ 4 + j
] -= k
+ 2;
768 if (D_kmaps
+ D_nseqs
> p
+ 2 * k
+ 4)
769 bcopy((char *)p
+ 2 * k
+ 4, (char *)p
, (D_kmaps
+ D_nseqs
) - (p
+ 2 * k
+ 4));
770 D_nseqs
-= 2 * k
+ 4;
771 D_seqp
= D_kmaps
+ 3;
787 debug("Mappings:\n");
791 while (p
< D_kmaps
+ D_nseqs
)
794 debug1("%d: ", p
- D_kmaps
+ 3);
795 for (j
= 0; j
< l
; j
++)
797 o
= oo
= p
[l
+ 4 + j
];
799 o
= 2 * o
+ 4 + (p
+ 3 + j
- D_kmaps
);
800 if (p
[j
+ 3] > ' ' && p
[j
+ 3] < 0177)
802 debug3("%c[%d:%d] ", p
[j
+ 3], oo
, o
);
805 debug3("\\%03o[%d:%d] ", p
[j
+ 3], oo
, o
);
807 n
= p
[0] << 8 | p
[1];
808 debug2(" ==> %d%s\n", n
& ~KMAP_NOTIMEOUT
, (n
& KMAP_NOTIMEOUT
) ? " (no timeout)" : "");
817 * Appends to the static variable Termcap
825 if (tcLineLen
+ (n
= strlen(s
)) > 55 && Termcaplen
< TERMCAP_BUFSIZE
- 4 - 1)
827 strcpy(Termcap
+ Termcaplen
, "\\\n\t:");
831 if (Termcaplen
+ n
< TERMCAP_BUFSIZE
- 1)
833 strcpy(Termcap
+ Termcaplen
, s
);
838 Panic(0, "TERMCAP overflow - sorry.");
842 * Reads a displays capabilities and reconstructs a termcap entry in the
843 * global buffer "Termcap". A pointer to this buffer is returned.
849 char buf
[TERMCAP_BUFSIZE
];
850 register char *p
, *cp
, *s
, ch
, *tname
;
868 debug1("MakeTermcap(%d)\n", aflag
);
869 if ((s
= getenv("SCREENCAP")) && strlen(s
) < TERMCAP_BUFSIZE
)
871 sprintf(Termcap
, "TERMCAP=%s", s
);
872 strcpy(Term
, "TERM=screen");
873 debug("getenvSCREENCAP o.k.\n");
877 debug1("MakeTermcap screenterm='%s'\n", screenterm
);
878 debug1("MakeTermcap termname='%s'\n", tname
);
879 if (*screenterm
== '\0' || strlen(screenterm
) > MAXSTR
- 3)
881 debug("MakeTermcap sets screenterm=screen\n");
882 strcpy(screenterm
, "screen");
889 strcpy(Term
, "TERM=");
891 if (!aflag
&& strlen(screenterm
) + strlen(tname
) < MAXSTR
-1)
893 sprintf(p
, "%s.%s", screenterm
, tname
);
894 if (e_tgetent(buf
, p
) == 1)
898 if (nwin_default
.bce
)
900 sprintf(p
, "%s-bce", screenterm
);
901 if (e_tgetent(buf
, p
) == 1)
905 #ifdef CHECK_SCREEN_W
908 sprintf(p
, "%s-w", screenterm
);
909 if (e_tgetent(buf
, p
) == 1)
913 strcpy(p
, screenterm
);
914 if (e_tgetent(buf
, p
) == 1)
921 while (0); /* Goto free programming... */
925 /* check for compatibility problems, displays == 0 after fork */
928 char xbuf
[TERMCAP_BUFSIZE
], *xbp
= xbuf
;
929 if (tgetstr("im", &xbp
) && tgetstr("ic", &xbp
) && displays
)
931 Msg(0, "Warning: im and ic set in %s termcap entry", p
);
937 tcLineLen
= 100; /* Force NL */
938 if (strlen(Term
) > TERMCAP_BUFSIZE
- 40)
939 strcpy(Term
, "too_long");
940 sprintf(Termcap
, "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal:", Term
+ 5);
941 Termcaplen
= strlen(Termcap
);
942 debug1("MakeTermcap decided '%s'\n", p
);
943 if (extra_outcap
&& *extra_outcap
)
945 for (cp
= extra_outcap
; (p
= index(cp
, ':')); cp
= p
)
952 tcLineLen
= 100; /* Force NL */
954 debug1("MakeTermcap after outcap '%s'\n", (char *)TermcapConst
);
955 if (Termcaplen
+ strlen(TermcapConst
) < TERMCAP_BUFSIZE
)
957 strcpy(Termcap
+ Termcaplen
, (char *)TermcapConst
);
958 Termcaplen
+= strlen(TermcapConst
);
960 sprintf(buf
, "li#%d:co#%d:", he
, wi
);
963 if (aflag
|| (force_vt
&& !D_COP
) || D_CLP
|| !D_AM
)
969 if (aflag
|| (D_CS
&& D_SR
) || D_AL
|| D_CAL
)
973 AddCap("AL=\\E[%dL:");
978 AddCap("cs=\\E[%i%d;%dr:");
979 if (aflag
|| D_CS
|| D_DL
|| D_CDL
)
982 AddCap("DL=\\E[%dM:");
984 if (aflag
|| D_DC
|| D_CDC
)
987 AddCap("DC=\\E[%dP:");
989 if (aflag
|| D_CIC
|| D_IC
|| D_IM
)
991 AddCap("im=\\E[4h:");
992 AddCap("ei=\\E[4l:");
994 AddCap("IC=\\E[%d@:");
997 AddCap("ks=\\E[?1h\\E=:");
998 AddCap("ke=\\E[?1l\\E>:");
1000 AddCap("vi=\\E[?25l:");
1001 AddCap("ve=\\E[34h\\E[?25h:");
1002 AddCap("vs=\\E[34l:");
1003 AddCap("ti=\\E[?1049h:");
1004 AddCap("te=\\E[?1049l:");
1009 AddCap("us=\\E[4m:");
1010 AddCap("ue=\\E[24m:");
1014 AddCap("so=\\E[3m:");
1015 AddCap("se=\\E[23m:");
1018 AddCap("mb=\\E[5m:");
1020 AddCap("md=\\E[1m:");
1022 AddCap("mh=\\E[2m:");
1024 AddCap("mr=\\E[7m:");
1025 if (D_MB
|| D_MD
|| D_MH
|| D_MR
)
1026 AddCap("me=\\E[m:ms:");
1028 AddCap("Co#8:pa#64:AF=\\E[3%dm:AB=\\E[4%dm:op=\\E[39;49m:AX:");
1039 AddCap("CS=\\E[?1h:");
1040 AddCap("CE=\\E[?1l:");
1045 if (D_CC0
|| (D_CS0
&& *D_CS0
))
1047 AddCap("as=\\E(0:");
1048 AddCap("ae=\\E(B:");
1049 /* avoid `` because some shells dump core... */
1050 AddCap("ac=\\140\\140aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++,,hhII00:");
1054 AddCap("po=\\E[5i:");
1055 AddCap("pf=\\E[4i:");
1059 AddCap("Z0=\\E[?3h:");
1060 AddCap("Z1=\\E[?3l:");
1063 AddCap("WS=\\E[8;%d;%dt:");
1065 for (i
= T_CAPS
; i
< T_ECAPS
; i
++)
1071 if (i
>= T_KEYPAD
) /* don't put keypad codes in TERMCAP */
1072 continue; /* - makes it too big */
1073 if (i
>= T_CURSOR
&& i
< T_OCAPS
)
1075 act
= &umtab
[i
- (T_CURSOR
- T_OCAPS
+ T_CAPS
)];
1076 if (act
->nr
== RC_ILLEGAL
)
1077 act
= &dmtab
[i
- (T_CURSOR
- T_OCAPS
+ T_CAPS
)];
1081 act
= &umtab
[i
- T_CAPS
];
1082 if (act
->nr
== RC_ILLEGAL
)
1083 act
= &dmtab
[i
- T_CAPS
];
1085 if (act
->nr
== RC_ILLEGAL
&& (i
== T_NAVIGATE
+ 1 || i
== T_NAVIGATE
+ 3))
1087 /* kh -> @1, kH -> @7 */
1088 act
= &umtab
[i
- T_CAPS
- 1];
1089 if (act
->nr
== RC_ILLEGAL
)
1090 act
= &dmtab
[i
- T_CAPS
- 1];
1092 if (act
->nr
!= RC_ILLEGAL
)
1094 if (act
->nr
== RC_STUFF
)
1096 MakeString(term
[i
].tcname
, buf
, sizeof(buf
), act
->args
[0]);
1105 switch(term
[i
].type
)
1108 if (D_tcs
[i
].str
== 0)
1110 MakeString(term
[i
].tcname
, buf
, sizeof(buf
), D_tcs
[i
].str
);
1114 if (D_tcs
[i
].flg
== 0)
1116 sprintf(buf
, "%s:", term
[i
].tcname
);
1123 debug("MakeTermcap: end\n");
1128 MakeString(cap
, buf
, buflen
, s
)
1133 register char *p
, *pmax
;
1134 register unsigned int c
;
1137 pmax
= p
+ buflen
- (3+4+2);
1141 while ((c
= *s
++) && (p
< pmax
))
1161 sprintf(p
, "\\%03o", c
& 0377);
1180 (*p == '\\' && (p[1] == '\\' || p[1] == ',' || p[1] == '%'))
1195 if ((D_xtable
= (char ***)malloc(256 * sizeof(char **))) == 0)
1200 bzero((char *)D_xtable
, 256 * sizeof(char **));
1206 curchar
= (unsigned char)*s
++;
1208 curchar
= 0; /* ASCII */
1212 if (D_xtable
[curchar
] == 0)
1214 if ((D_xtable
[curchar
] = (char **)malloc(257 * sizeof(char *))) == 0)
1220 bzero((char *)D_xtable
[curchar
], 257 * sizeof(char *));
1222 ctable
= D_xtable
[curchar
];
1223 for(; *s
&& *s
!= ','; s
++)
1236 while (*s
&& *s
!= ',')
1238 c
= (unsigned char)*s
++;
1239 if (QUOTES((s
- 1)))
1240 c
= (unsigned char)*s
++;
1246 l
= copyarg(&s
, (char *)0);
1248 l
= l
* templnsub
+ templlen
;
1249 if ((ctable
[c
] = (char *)malloc(l
+ 1)) == 0)
1256 for (p
= ((c
== 256) ? "%" : templ
); *p
&& *p
!= ','; p
++)
1263 sx
+= copyarg(&s
, sx
);
1269 ASSERT(ctable
[c
] + l
* templnsub
+ templlen
== sx
);
1270 debug3("XC: %c %c->%s\n", curchar
, c
, ctable
[c
]);
1284 if ((p
= D_xtable
) == 0)
1286 for (i
= 0; i
< 256; i
++, p
++)
1291 for (j
= 0; j
< 257; j
++, q
++)
1307 for (l
= 0, p
= *pp
; *p
&& *p
!= ','; p
++)
1324 ** Termcap routines that use our extra_incap
1338 r
= tgetent(bp
, name
);
1348 * cap = capability we are looking for
1349 * tepp = pointer to bufferpointer
1350 * n = size of buffer (0 = infinity)
1354 findcap(cap
, tepp
, n
)
1361 int mode
; /* mode: 0=LIT 1=^ 2=\x 3,4,5=\nnn */
1370 for (p
= extra_incap
; *p
; )
1372 if (strncmp(p
, cap
, capl
) == 0)
1376 if (c
&& c
!= ':' && c
!= '@')
1378 if (c
== 0 || c
== '@' || c
== '=' || c
== ':' || c
== '#')
1438 num
= num
* 8 + (c
- '0');
1439 if (mode
++ == 5 || (*p
< '0' || *p
> '9'))
1458 debug2("'%s' found in extra_incap -> %s\n", cap
, tep
);
1466 e_tgetstr(cap
, tepp
)
1471 if ((tep
= findcap(cap
, tepp
, 0)))
1472 return (*tep
== '@') ? 0 : tep
;
1473 return tgetstr(cap
, tepp
);
1483 if ((tep
= findcap(cap
, &bufp
, 2)))
1484 return (*tep
== '@') ? 0 : 1;
1485 return tgetflag(cap
) > 0;
1492 char buf
[20], *bufp
;
1497 if ((tep
= findcap(cap
, &bufp
, 20)))
1505 while ((c
= *tep
++) >= '0' && c
<= '9')
1506 res
= res
* base
+ (c
- '0');
1509 return tgetnum(cap
);