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>
34 extern struct display
*display
, *displays
;
35 extern int real_uid
, real_gid
, eff_uid
, eff_gid
;
36 extern struct term term
[]; /* terminal capabilities */
37 extern struct NewWindow nwin_undef
, nwin_default
, nwin_options
;
39 extern int Z0width
, Z1width
;
40 extern int hardstatusemu
;
42 extern struct action umtab
[];
43 extern struct action mmtab
[];
44 extern struct action dmtab
[];
45 extern struct action ktab
[];
46 extern struct kmap_ext
*kmap_exts
;
48 extern int DefaultEsc
;
52 static void AddCap
__P((char *));
53 static void MakeString
__P((char *, char *, int, char *));
54 static char *findcap
__P((char *, char **, int));
55 static int copyarg
__P((char **, char *));
56 static int e_tgetent
__P((char *, char *));
57 static char *e_tgetstr
__P((char *, char **));
58 static int e_tgetflag
__P((char *));
59 static int e_tgetnum
__P((char *));
61 static int findseq_ge
__P((char *, int, unsigned char **));
62 static void setseqoff
__P((unsigned char *, int, int));
63 static int addmapseq
__P((char *, int, int));
64 static int remmapseq
__P((char *, int));
66 static void dumpmap
__P((void));
71 char Termcap
[TERMCAP_BUFSIZE
+ 8]; /* new termcap +8:"TERMCAP=" */
72 static int Termcaplen
;
74 char Term
[MAXSTR
+5]; /* +5: "TERM=" */
75 char screenterm
[20]; /* new $TERM, usually "screen" */
77 char *extra_incap
, *extra_outcap
;
79 static const char TermcapConst
[] = "\\\n\
80 \t:DO=\\E[%dB:LE=\\E[%dD:RI=\\E[%dC:UP=\\E[%dA:bs:bt=\\E[Z:\\\n\
81 \t:cd=\\E[J:ce=\\E[K:cl=\\E[H\\E[J:cm=\\E[%i%d;%dH:ct=\\E[3g:\\\n\
82 \t:do=^J:nd=\\E[C:pt:rc=\\E8:rs=\\Ec:sc=\\E7:st=\\EH:up=\\EM:\\\n\
83 \t:le=^H:bl=^G:cr=^M:it#8:ho=\\E[H:nw=\\EE:ta=^I:is=\\E)0:";
91 if (display
== 0 || s
== 0)
93 for (i
= 0; i
< T_N
; i
++)
95 if (term
[i
].type
!= T_STR
)
97 if (strcmp(term
[i
].tcname
, s
) == 0)
104 * Compile the terminal capabilities for a display.
105 * Input: tgetent(, D_termname) extra_incap, extra_outcap.
106 * Effect: display initialisation.
115 char tbuf
[TERMCAP_BUFSIZE
], *tp
;
116 int t
, xue
, xse
, xme
;
119 bzero(tbuf
, sizeof(tbuf
));
120 debug1("InitTermcap: looking for tgetent('%s')\n", D_termname
);
121 if (*D_termname
== 0 || e_tgetent(tbuf
, D_termname
) != 1)
124 Msg(0, "Cannot find terminfo entry for '%s'.", D_termname
);
126 Msg(0, "Cannot find termcap entry for '%s'.", D_termname
);
130 debug1("got it:\n%s\n", tbuf
);
133 debug1("Extra incap: %s\n", extra_incap
);
135 debug1("Extra outcap: %s\n", extra_outcap
);
138 if ((D_tentry
= (char *)malloc(TERMCAP_BUFSIZE
+ (extra_incap
? strlen(extra_incap
) + 1 : 0))) == 0)
145 * loop through all needed capabilities, record their values in the display
148 for (i
= 0; i
< T_N
; i
++)
153 D_tcs
[i
].flg
= e_tgetflag(term
[i
].tcname
);
156 D_tcs
[i
].num
= e_tgetnum(term
[i
].tcname
);
159 D_tcs
[i
].str
= e_tgetstr(term
[i
].tcname
, &tp
);
160 /* no empty strings, please */
161 if (D_tcs
[i
].str
&& *D_tcs
[i
].str
== 0)
165 Panic(0, "Illegal tc type in entry #%d", i
);
171 * Now a good deal of sanity checks on the retrieved capabilities.
175 Msg(0, "You can't run screen on a hardcopy terminal.");
180 Msg(0, "You can't run screen on a terminal that overstrikes.");
185 Msg(0, "Clear screen capability required.");
190 Msg(0, "Addressable cursor capability required.");
193 if ((s
= getenv("COLUMNS")) && (i
= atoi(s
)) > 0)
195 if ((s
= getenv("LINES")) && (i
= atoi(s
)) > 0)
208 /* standard fixes for xterms etc */
209 /* assume color for everything that looks ansi-compatible */
210 if (!D_CAF
&& D_ME
&& (InStr(D_ME
, "\033[m") || InStr(D_ME
, "\033[0m")))
213 D_CAF
= "\033[3%p1%dm";
214 D_CAB
= "\033[4%p1%dm";
220 if (D_OP
&& InStr(D_OP
, "\033[39;49m"))
222 if (D_OP
&& (InStr(D_OP
, "\033[m") || InStr(D_OP
, "\033[0m")))
225 if ((D_EA
&& InStr(D_EA
, "\033(B")) || (D_AS
&& InStr(D_AS
, "\033(0")))
227 if (InStr(D_termname
, "xterm") || InStr(D_termname
, "rxvt") ||
228 (D_CKM
&& InStr(D_CKM
, "\033[M")))
230 /* "be" seems to be standard for xterms... */
234 if (nwin_options
.flowflag
== nwin_undef
.flowflag
)
235 nwin_default
.flowflag
= D_CNF
? FLOW_NOW
* 0 :
236 D_NX
? FLOW_NOW
* 1 :
238 D_CLP
|= (!D_AM
|| D_XV
|| D_XN
);
254 * Set up attribute handling.
255 * This is rather complicated because termcap has different
263 /* Unfortunately there is no 'mg' capability.
264 * For now we think that mg > 0 if sg and ug > 0.
266 if (D_UG
> 0 && D_SG
> 0)
267 D_MH
= D_MD
= D_MR
= D_MB
= D_ME
= 0;
273 if (D_SO
&& D_SE
== 0)
275 Msg(0, "Warning: 'so' but no 'se' capability.");
281 if (D_US
&& D_UE
== 0)
283 Msg(0, "Warning: 'us' but no 'ue' capability.");
289 if ((D_MH
|| D_MD
|| D_MR
|| D_MB
) && D_ME
== 0)
291 Msg(0, "Warning: 'm?' but no 'me' capability.");
292 D_MH
= D_MD
= D_MR
= D_MB
= 0;
295 * Does ME also reverse the effect of SO and/or US? This is not
296 * clearly specified by the termcap manual. Anyway, we should at
297 * least look whether ME and SE/UE are equal:
299 if (D_UE
&& D_SE
&& strcmp(D_SE
, D_UE
) == 0)
301 if (D_SE
&& D_ME
&& strcmp(D_ME
, D_SE
) == 0)
303 if (D_UE
&& D_ME
&& strcmp(D_ME
, D_UE
) == 0)
306 for (i
= 0; i
< NATTR
; i
++)
308 D_attrtab
[i
] = D_tcs
[T_ATTR
+ i
].str
;
309 D_attrtyp
[i
] = i
== ATTR_SO
? xse
: (i
== ATTR_US
? xue
: xme
);
312 /* Set up missing entries (attributes are priority ordered) */
315 for (i
= 0; i
< NATTR
; i
++)
316 if ((s
= D_attrtab
[i
]))
321 for (i
= 0; i
< NATTR
; i
++)
323 if (D_attrtab
[i
] == 0)
334 if (D_CAF
|| D_CAB
|| D_CSF
|| D_CSB
)
337 D_BE
= 1; /* screen erased with background color */
347 /* some strange termcap entries have IC == IM */
348 if (D_IC
&& D_IM
&& strcmp(D_IC
, D_IM
) == 0)
364 D_CS0
= "\033(%p1%c";
373 else if (D_AC
|| (D_AS
&& D_AE
)) /* some kind of graphics */
375 D_CS0
= (D_AS
&& D_AE
) ? D_AS
: "";
376 D_CE0
= (D_AS
&& D_AE
) ? D_AE
: "";
383 D_AC
= ""; /* enable default string */
386 for (i
= 0; i
< 256; i
++)
390 /* init with default string first */
391 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>";
392 for (i
= strlen(s
) & ~1; i
>= 0; i
-= 2)
393 D_c0_tab
[(int)(unsigned char)s
[i
]] = s
[i
+ 1];
396 for (i
= strlen(D_CC0
) & ~1; i
>= 0; i
-= 2)
397 D_c0_tab
[(int)(unsigned char)D_CC0
[i
]] = D_CC0
[i
+ 1];
398 debug1("ISO2022 = %d\n", D_CG0
);
402 debug2("terminal size is %d, %d (says TERMCAP)\n", D_CO
, D_LI
);
406 if (CreateTransTable(D_CXC
))
410 /* Termcap fields Z0 & Z1 contain width-changing sequences. */
418 if (D_TS
== 0 || D_FS
== 0 || D_DS
== 0)
422 debug("oy! we have a hardware status line, says termcap\n");
426 D_has_hstatus
= hardstatusemu
& ~HSTATUS_ALWAYS
;
427 if (D_HS
&& !(hardstatusemu
& HSTATUS_ALWAYS
))
428 D_has_hstatus
= HSTATUS_HS
;
433 int enc
= FindEncoding(D_CKJ
);
438 if (!D_tcs
[T_NAVIGATE
].str
&& D_tcs
[T_NAVIGATE
+ 1].str
)
439 D_tcs
[T_NAVIGATE
].str
= D_tcs
[T_NAVIGATE
+ 1].str
; /* kh = @1 */
440 if (!D_tcs
[T_NAVIGATE
+ 2].str
&& D_tcs
[T_NAVIGATE
+ 3].str
)
441 D_tcs
[T_NAVIGATE
+ 2].str
= D_tcs
[T_NAVIGATE
+ 3].str
; /* kH = @7 */
443 D_UPcost
= CalcCost(D_UP
);
444 D_DOcost
= CalcCost(D_DO
);
445 D_NLcost
= CalcCost(D_NL
);
446 D_LEcost
= CalcCost(D_BC
);
447 D_NDcost
= CalcCost(D_ND
);
448 D_CRcost
= CalcCost(D_CR
);
449 D_IMcost
= CalcCost(D_IM
);
450 D_EIcost
= CalcCost(D_EI
);
455 debug("termcap has AN, setting autonuke\n");
461 debug1("termcap has OL (%d), setting limit\n", D_COL
);
463 D_obuflenmax
= D_obuflen
- D_obufmax
;
466 /* Some xterm entries set F0 and F10 to the same string. Nuke F0. */
467 if (D_tcs
[T_CAPS
].str
&& D_tcs
[T_CAPS
+ 10].str
&& !strcmp(D_tcs
[T_CAPS
].str
, D_tcs
[T_CAPS
+ 10].str
))
468 D_tcs
[T_CAPS
].str
= 0;
469 /* Some xterm entries set kD to ^?. Nuke it. */
470 if (D_tcs
[T_NAVIGATE_DELETE
].str
&& !strcmp(D_tcs
[T_NAVIGATE_DELETE
].str
, "\0177"))
471 D_tcs
[T_NAVIGATE_DELETE
].str
= 0;
472 /* wyse52 entries have kcub1 == kb == ^H. Nuke... */
473 if (D_tcs
[T_CURSOR
+ 3].str
&& !strcmp(D_tcs
[T_CURSOR
+ 3].str
, "\008"))
474 D_tcs
[T_CURSOR
+ 3].str
= 0;
478 for (i
= 0; i
< T_OCAPS
- T_CAPS
; i
++)
480 for (i
= 0; i
< kmap_extn
; i
++)
481 remap(i
+ (KMAP_KEYS
+KMAP_AKEYS
), 1);
482 D_seqp
= D_kmaps
+ 3;
503 int fl
= 0, domap
= 0;
504 struct action
*a1
, *a2
, *tab
;
506 struct kmap_ext
*kme
= 0;
509 if (n
>= KMAP_KEYS
+KMAP_AKEYS
)
511 kme
= kmap_exts
+ (n
- (KMAP_KEYS
+KMAP_AKEYS
));
513 l
= kme
->fl
& ~KMAP_NOTIMEOUT
;
514 fl
= kme
->fl
& KMAP_NOTIMEOUT
;
521 if (n
< KMAP_KEYS
+KMAP_AKEYS
)
525 n
-= T_OCAPS
-T_CURSOR
;
526 s
= D_tcs
[n
+ T_CAPS
].str
;
527 l
= s
? strlen(s
) : 0;
528 if (n
>= T_CURSOR
-T_CAPS
)
529 a2
= &tab
[n
+ (T_OCAPS
-T_CURSOR
)];
531 if (s
== 0 || l
== 0)
533 if (a1
&& a1
->nr
== RC_ILLEGAL
)
535 if (a2
&& a2
->nr
== RC_ILLEGAL
)
537 if (a1
&& a1
->nr
== RC_STUFF
&& a1
->args
[0] && strcmp(a1
->args
[0], s
) == 0)
539 if (a2
&& a2
->nr
== RC_STUFF
&& a2
->args
[0] && strcmp(a2
->args
[0], s
) == 0)
545 a1
= kme
? &kme
->dm
: 0;
547 else if (tab
== dmtab
)
550 a1
= kme
? &kme
->mm
: 0;
557 if (map
== 0 && domap
)
561 debug3("%smapping %s %#x\n", map
? "" :"un",s
,n
);
563 return addmapseq(s
, l
, n
| fl
);
565 return remmapseq(s
, l
);
571 struct display
*odisplay
;
578 for (display
= displays
; display
; display
= display
->d_next
)
580 for (i
= 0; i
< D_nseqs
; i
+= D_kmaps
[i
+ 2] * 2 + 4)
582 nr
= (D_kmaps
[i
] << 8 | D_kmaps
[i
+ 1]) & ~KMAP_NOTIMEOUT
;
583 if (nr
< KMAP_KEYS
+KMAP_AKEYS
)
585 if (umtab
[nr
].nr
== RC_COMMAND
)
587 if (umtab
[nr
].nr
== RC_ILLEGAL
&& dmtab
[nr
].nr
== RC_COMMAND
)
592 struct kmap_ext
*kme
= kmap_exts
+ nr
- (KMAP_KEYS
+KMAP_AKEYS
);
593 if (kme
->um
.nr
== RC_COMMAND
)
595 if (kme
->um
.nr
== RC_ILLEGAL
&& kme
->dm
.nr
== RC_COMMAND
)
605 SetEscape((struct acluser
*)0, Ctrl('a'), 'a');
606 if (odisplay
->d_user
->u_Esc
== -1)
607 odisplay
->d_user
->u_Esc
= DefaultEsc
;
608 if (odisplay
->d_user
->u_MetaEsc
== -1)
609 odisplay
->d_user
->u_MetaEsc
= DefaultMetaEsc
;
611 Msg(0, "Warning: escape char set back to ^A");
616 findseq_ge(seq
, k
, sp
)
625 while (p
- D_kmaps
< D_nseqs
)
631 if (j
== k
|| j
== l
)
633 else if (p
[j
] != ((unsigned char *)seq
)[j
])
634 j
= p
[j
] - ((unsigned char *)seq
)[j
];
665 /* go for the biggest offset */
666 for (q
= p
+ k
* 2 + 4; ; q
+= l
* 2 + 4)
669 if ((q
+ l
* 2 - p
) / 2 >= 256)
671 p
[k
+ 4 + i
] = (q
- p
- 4) / 2;
678 addmapseq(seq
, k
, nr
)
684 unsigned char *p
, *q
;
688 j
= findseq_ge(seq
, k
, &p
);
696 if (D_nseqs
+ 2 * k
+ 4 >= D_aseqs
)
698 D_kmaps
= (unsigned char *)xrealloc((char *)D_kmaps
, D_aseqs
+ 256);
702 D_seqp
= D_kmaps
+ 3;
707 bcopy((char *)p
, (char *)p
+ 2 * k
+ 4, D_nseqs
- i
);
711 bcopy(seq
, (char *)p
+ 3, k
);
712 bzero(p
+ k
+ 3, k
+ 1);
713 D_nseqs
+= 2 * k
+ 4;
718 for (i
= 0; i
< k
; i
++)
720 if (p
[3 + i
] != q
[3 + i
])
725 setseqoff(p
, i
, q
[l
+ 4 + i
] ? q
[l
+ 4 + i
] + k
+ 2: 0);
728 for (q
= D_kmaps
; q
< p
; q
+= 2 * l
+ 4)
731 for (m
= j
= 0; j
< l
; j
++)
734 if (!m
&& q
[3 + j
] != seq
[j
])
736 if (q
[l
+ 4 + j
] == 0)
739 setseqoff(q
, j
, (p
- q
- 4) / 2);
741 else if (q
+ q
[l
+ 4 + j
] * 2 + 4 > p
|| (q
+ q
[l
+ 4 + j
] * 2 + 4 == p
&& !m
))
742 setseqoff(q
, j
, q
[l
+ 4 + j
] + k
+ 2);
757 unsigned char *p
, *q
;
759 if (k
>= 254 || (j
= findseq_ge(seq
, k
, &p
)) != 0)
761 for (q
= D_kmaps
; q
< p
; q
+= 2 * l
+ 4)
764 for (j
= 0; j
< l
; j
++)
766 if (q
+ q
[l
+ 4 + j
] * 2 + 4 == p
)
767 setseqoff(q
, j
, p
[k
+ 4 + j
] ? q
[l
+ 4 + j
] + p
[k
+ 4 + j
] - k
: 0);
768 else if (q
+ q
[l
+ 4 + j
] * 2 + 4 > p
)
769 q
[l
+ 4 + j
] -= k
+ 2;
772 if (D_kmaps
+ D_nseqs
> p
+ 2 * k
+ 4)
773 bcopy((char *)p
+ 2 * k
+ 4, (char *)p
, (D_kmaps
+ D_nseqs
) - (p
+ 2 * k
+ 4));
774 D_nseqs
-= 2 * k
+ 4;
775 D_seqp
= D_kmaps
+ 3;
791 debug("Mappings:\n");
795 while (p
< D_kmaps
+ D_nseqs
)
798 debug1("%d: ", p
- D_kmaps
+ 3);
799 for (j
= 0; j
< l
; j
++)
801 o
= oo
= p
[l
+ 4 + j
];
803 o
= 2 * o
+ 4 + (p
+ 3 + j
- D_kmaps
);
804 if (p
[j
+ 3] > ' ' && p
[j
+ 3] < 0177)
806 debug3("%c[%d:%d] ", p
[j
+ 3], oo
, o
);
809 debug3("\\%03o[%d:%d] ", p
[j
+ 3], oo
, o
);
811 n
= p
[0] << 8 | p
[1];
812 debug2(" ==> %d%s\n", n
& ~KMAP_NOTIMEOUT
, (n
& KMAP_NOTIMEOUT
) ? " (no timeout)" : "");
821 * Appends to the static variable Termcap
829 if (tcLineLen
+ (n
= strlen(s
)) > 55 && Termcaplen
< TERMCAP_BUFSIZE
- 4 - 1)
831 strcpy(Termcap
+ Termcaplen
, "\\\n\t:");
835 if (Termcaplen
+ n
< TERMCAP_BUFSIZE
- 1)
837 strcpy(Termcap
+ Termcaplen
, s
);
842 Panic(0, "TERMCAP overflow - sorry.");
846 * Reads a displays capabilities and reconstructs a termcap entry in the
847 * global buffer "Termcap". A pointer to this buffer is returned.
853 char buf
[TERMCAP_BUFSIZE
];
854 register char *p
, *cp
, *s
, ch
, *tname
;
872 debug1("MakeTermcap(%d)\n", aflag
);
873 if ((s
= getenv("SCREENCAP")) && strlen(s
) < TERMCAP_BUFSIZE
)
875 sprintf(Termcap
, "TERMCAP=%s", s
);
876 strcpy(Term
, "TERM=screen");
877 debug("getenvSCREENCAP o.k.\n");
881 debug1("MakeTermcap screenterm='%s'\n", screenterm
);
882 debug1("MakeTermcap termname='%s'\n", tname
);
883 if (*screenterm
== '\0' || strlen(screenterm
) > MAXSTR
- 3)
885 debug("MakeTermcap sets screenterm=screen\n");
886 strcpy(screenterm
, "screen");
893 strcpy(Term
, "TERM=");
895 if (!aflag
&& strlen(screenterm
) + strlen(tname
) < MAXSTR
-1)
897 sprintf(p
, "%s.%s", screenterm
, tname
);
898 if (e_tgetent(buf
, p
) == 1)
902 if (nwin_default
.bce
)
904 sprintf(p
, "%s-bce", screenterm
);
905 if (e_tgetent(buf
, p
) == 1)
909 #ifdef CHECK_SCREEN_W
912 sprintf(p
, "%s-w", screenterm
);
913 if (e_tgetent(buf
, p
) == 1)
917 strcpy(p
, screenterm
);
918 if (e_tgetent(buf
, p
) == 1)
925 while (0); /* Goto free programming... */
929 /* check for compatibility problems, displays == 0 after fork */
932 char xbuf
[TERMCAP_BUFSIZE
], *xbp
= xbuf
;
933 if (tgetstr("im", &xbp
) && tgetstr("ic", &xbp
) && displays
)
935 Msg(0, "Warning: im and ic set in %s termcap entry", p
);
941 tcLineLen
= 100; /* Force NL */
942 if (strlen(Term
) > TERMCAP_BUFSIZE
- 40)
943 strcpy(Term
, "too_long");
944 sprintf(Termcap
, "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal:", Term
+ 5);
945 Termcaplen
= strlen(Termcap
);
946 debug1("MakeTermcap decided '%s'\n", p
);
947 if (extra_outcap
&& *extra_outcap
)
949 for (cp
= extra_outcap
; (p
= index(cp
, ':')); cp
= p
)
956 tcLineLen
= 100; /* Force NL */
958 debug1("MakeTermcap after outcap '%s'\n", (char *)TermcapConst
);
959 if (Termcaplen
+ strlen(TermcapConst
) < TERMCAP_BUFSIZE
)
961 strcpy(Termcap
+ Termcaplen
, (char *)TermcapConst
);
962 Termcaplen
+= strlen(TermcapConst
);
964 sprintf(buf
, "li#%d:co#%d:", he
, wi
);
967 if (aflag
|| (force_vt
&& !D_COP
) || D_CLP
|| !D_AM
)
973 if (aflag
|| (D_CS
&& D_SR
) || D_AL
|| D_CAL
)
977 AddCap("AL=\\E[%dL:");
982 AddCap("cs=\\E[%i%d;%dr:");
983 if (aflag
|| D_CS
|| D_DL
|| D_CDL
)
986 AddCap("DL=\\E[%dM:");
988 if (aflag
|| D_DC
|| D_CDC
)
991 AddCap("DC=\\E[%dP:");
993 if (aflag
|| D_CIC
|| D_IC
|| D_IM
)
995 AddCap("im=\\E[4h:");
996 AddCap("ei=\\E[4l:");
998 AddCap("IC=\\E[%d@:");
1001 AddCap("ks=\\E[?1h\\E=:");
1002 AddCap("ke=\\E[?1l\\E>:");
1004 AddCap("vi=\\E[?25l:");
1005 AddCap("ve=\\E[34h\\E[?25h:");
1006 AddCap("vs=\\E[34l:");
1007 AddCap("ti=\\E[?1049h:");
1008 AddCap("te=\\E[?1049l:");
1013 AddCap("us=\\E[4m:");
1014 AddCap("ue=\\E[24m:");
1018 AddCap("so=\\E[3m:");
1019 AddCap("se=\\E[23m:");
1022 AddCap("mb=\\E[5m:");
1024 AddCap("md=\\E[1m:");
1026 AddCap("mh=\\E[2m:");
1028 AddCap("mr=\\E[7m:");
1029 if (D_MB
|| D_MD
|| D_MH
|| D_MR
)
1030 AddCap("me=\\E[m:ms:");
1032 AddCap("Co#8:pa#64:AF=\\E[3%dm:AB=\\E[4%dm:op=\\E[39;49m:AX:");
1043 AddCap("CS=\\E[?1h:");
1044 AddCap("CE=\\E[?1l:");
1049 if (D_CC0
|| (D_CS0
&& *D_CS0
))
1051 AddCap("as=\\E(0:");
1052 AddCap("ae=\\E(B:");
1053 /* avoid `` because some shells dump core... */
1054 AddCap("ac=\\140\\140aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++,,hhII00:");
1058 AddCap("po=\\E[5i:");
1059 AddCap("pf=\\E[4i:");
1063 AddCap("Z0=\\E[?3h:");
1064 AddCap("Z1=\\E[?3l:");
1067 AddCap("WS=\\E[8;%d;%dt:");
1069 for (i
= T_CAPS
; i
< T_ECAPS
; i
++)
1075 if (i
>= T_KEYPAD
) /* don't put keypad codes in TERMCAP */
1076 continue; /* - makes it too big */
1077 if (i
>= T_CURSOR
&& i
< T_OCAPS
)
1079 act
= &umtab
[i
- (T_CURSOR
- T_OCAPS
+ T_CAPS
)];
1080 if (act
->nr
== RC_ILLEGAL
)
1081 act
= &dmtab
[i
- (T_CURSOR
- T_OCAPS
+ T_CAPS
)];
1085 act
= &umtab
[i
- T_CAPS
];
1086 if (act
->nr
== RC_ILLEGAL
)
1087 act
= &dmtab
[i
- T_CAPS
];
1089 if (act
->nr
== RC_ILLEGAL
&& (i
== T_NAVIGATE
+ 1 || i
== T_NAVIGATE
+ 3))
1091 /* kh -> @1, kH -> @7 */
1092 act
= &umtab
[i
- T_CAPS
- 1];
1093 if (act
->nr
== RC_ILLEGAL
)
1094 act
= &dmtab
[i
- T_CAPS
- 1];
1096 if (act
->nr
!= RC_ILLEGAL
)
1098 if (act
->nr
== RC_STUFF
)
1100 MakeString(term
[i
].tcname
, buf
, sizeof(buf
), act
->args
[0]);
1109 switch(term
[i
].type
)
1112 if (D_tcs
[i
].str
== 0)
1114 MakeString(term
[i
].tcname
, buf
, sizeof(buf
), D_tcs
[i
].str
);
1118 if (D_tcs
[i
].flg
== 0)
1120 sprintf(buf
, "%s:", term
[i
].tcname
);
1127 debug("MakeTermcap: end\n");
1132 MakeString(cap
, buf
, buflen
, s
)
1137 register char *p
, *pmax
;
1138 register unsigned int c
;
1141 pmax
= p
+ buflen
- (3+4+2);
1145 while ((c
= *s
++) && (p
< pmax
))
1165 sprintf(p
, "\\%03o", c
& 0377);
1184 (*p == '\\' && (p[1] == '\\' || p[1] == ',' || p[1] == '%'))
1199 if ((D_xtable
= (char ***)calloc(256, sizeof(char **))) == 0)
1209 curchar
= (unsigned char)*s
++;
1211 curchar
= 0; /* ASCII */
1215 if (D_xtable
[curchar
] == 0)
1217 if ((D_xtable
[curchar
] = (char **)calloc(257, sizeof(char *))) == 0)
1224 ctable
= D_xtable
[curchar
];
1225 for(; *s
&& *s
!= ','; s
++)
1238 while (*s
&& *s
!= ',')
1240 c
= (unsigned char)*s
++;
1241 if (QUOTES((s
- 1)))
1242 c
= (unsigned char)*s
++;
1248 l
= copyarg(&s
, (char *)0);
1250 l
= l
* templnsub
+ templlen
;
1251 if ((ctable
[c
] = (char *)malloc(l
+ 1)) == 0)
1258 for (p
= ((c
== 256) ? "%" : templ
); *p
&& *p
!= ','; p
++)
1265 sx
+= copyarg(&s
, sx
);
1271 ASSERT(ctable
[c
] + l
* templnsub
+ templlen
== sx
);
1272 debug3("XC: %c %c->%s\n", curchar
, c
, ctable
[c
]);
1286 if ((p
= D_xtable
) == 0)
1288 for (i
= 0; i
< 256; i
++, p
++)
1293 for (j
= 0; j
< 257; j
++, q
++)
1309 for (l
= 0, p
= *pp
; *p
&& *p
!= ','; p
++)
1326 ** Termcap routines that use our extra_incap
1340 r
= tgetent(bp
, name
);
1350 * cap = capability we are looking for
1351 * tepp = pointer to bufferpointer
1352 * n = size of buffer (0 = infinity)
1356 findcap(cap
, tepp
, n
)
1363 int mode
; /* mode: 0=LIT 1=^ 2=\x 3,4,5=\nnn */
1372 for (p
= extra_incap
; *p
; )
1374 if (strncmp(p
, cap
, capl
) == 0)
1378 if (c
&& c
!= ':' && c
!= '@')
1380 if (c
== 0 || c
== '@' || c
== '=' || c
== ':' || c
== '#')
1440 num
= num
* 8 + (c
- '0');
1441 if (mode
++ == 5 || (*p
< '0' || *p
> '9'))
1460 debug2("'%s' found in extra_incap -> %s\n", cap
, tep
);
1468 e_tgetstr(cap
, tepp
)
1473 if ((tep
= findcap(cap
, tepp
, 0)))
1474 return (*tep
== '@') ? 0 : tep
;
1475 return tgetstr(cap
, tepp
);
1485 if ((tep
= findcap(cap
, &bufp
, 2)))
1486 return (*tep
== '@') ? 0 : 1;
1487 return tgetflag(cap
) > 0;
1494 char buf
[20], *bufp
;
1499 if ((tep
= findcap(cap
, &bufp
, 20)))
1507 while ((c
= *tep
++) >= '0' && c
<= '9')
1508 res
= res
* base
+ (c
- '0');
1511 return tgetnum(cap
);