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;
556 if (map
== 0 && domap
)
560 debug3("%smapping %s %#x\n", map
? "" :"un",s
,n
);
562 return addmapseq(s
, l
, n
| fl
);
564 return remmapseq(s
, l
);
570 struct display
*odisplay
;
577 for (display
= displays
; display
; display
= display
->d_next
)
579 for (i
= 0; i
< D_nseqs
; i
+= D_kmaps
[i
+ 2] * 2 + 4)
581 nr
= (D_kmaps
[i
] << 8 | D_kmaps
[i
+ 1]) & ~KMAP_NOTIMEOUT
;
582 if (nr
< KMAP_KEYS
+KMAP_AKEYS
)
584 if (umtab
[nr
].nr
== RC_COMMAND
)
586 if (umtab
[nr
].nr
== RC_ILLEGAL
&& dmtab
[nr
].nr
== RC_COMMAND
)
591 struct kmap_ext
*kme
= kmap_exts
+ nr
- (KMAP_KEYS
+KMAP_AKEYS
);
592 if (kme
->um
.nr
== RC_COMMAND
)
594 if (kme
->um
.nr
== RC_ILLEGAL
&& kme
->dm
.nr
== RC_COMMAND
)
604 SetEscape((struct acluser
*)0, Ctrl('a'), 'a');
605 if (odisplay
->d_user
->u_Esc
== -1)
606 odisplay
->d_user
->u_Esc
= DefaultEsc
;
607 if (odisplay
->d_user
->u_MetaEsc
== -1)
608 odisplay
->d_user
->u_MetaEsc
= DefaultMetaEsc
;
610 Msg(0, "Warning: escape char set back to ^A");
615 findseq_ge(seq
, k
, sp
)
624 while (p
- D_kmaps
< D_nseqs
)
630 if (j
== k
|| j
== l
)
632 else if (p
[j
] != ((unsigned char *)seq
)[j
])
633 j
= p
[j
] - ((unsigned char *)seq
)[j
];
664 /* go for the biggest offset */
665 for (q
= p
+ k
* 2 + 4; ; q
+= l
* 2 + 4)
668 if ((q
+ l
* 2 - p
) / 2 >= 256)
670 p
[k
+ 4 + i
] = (q
- p
- 4) / 2;
677 addmapseq(seq
, k
, nr
)
683 unsigned char *p
, *q
;
687 j
= findseq_ge(seq
, k
, &p
);
695 if (D_nseqs
+ 2 * k
+ 4 >= D_aseqs
)
697 D_kmaps
= (unsigned char *)xrealloc((char *)D_kmaps
, D_aseqs
+ 256);
701 D_seqp
= D_kmaps
+ 3;
706 bcopy((char *)p
, (char *)p
+ 2 * k
+ 4, D_nseqs
- i
);
710 bcopy(seq
, (char *)p
+ 3, k
);
711 bzero(p
+ k
+ 3, k
+ 1);
712 D_nseqs
+= 2 * k
+ 4;
717 for (i
= 0; i
< k
; i
++)
719 if (p
[3 + i
] != q
[3 + i
])
724 setseqoff(p
, i
, q
[l
+ 4 + i
] ? q
[l
+ 4 + i
] + k
+ 2: 0);
727 for (q
= D_kmaps
; q
< p
; q
+= 2 * l
+ 4)
730 for (m
= j
= 0; j
< l
; j
++)
733 if (!m
&& q
[3 + j
] != seq
[j
])
735 if (q
[l
+ 4 + j
] == 0)
738 setseqoff(q
, j
, (p
- q
- 4) / 2);
740 else if (q
+ q
[l
+ 4 + j
] * 2 + 4 > p
|| (q
+ q
[l
+ 4 + j
] * 2 + 4 == p
&& !m
))
741 setseqoff(q
, j
, q
[l
+ 4 + j
] + k
+ 2);
756 unsigned char *p
, *q
;
758 if (k
>= 254 || (j
= findseq_ge(seq
, k
, &p
)) != 0)
760 for (q
= D_kmaps
; q
< p
; q
+= 2 * l
+ 4)
763 for (j
= 0; j
< l
; j
++)
765 if (q
+ q
[l
+ 4 + j
] * 2 + 4 == p
)
766 setseqoff(q
, j
, p
[k
+ 4 + j
] ? q
[l
+ 4 + j
] + p
[k
+ 4 + j
] - k
: 0);
767 else if (q
+ q
[l
+ 4 + j
] * 2 + 4 > p
)
768 q
[l
+ 4 + j
] -= k
+ 2;
771 if (D_kmaps
+ D_nseqs
> p
+ 2 * k
+ 4)
772 bcopy((char *)p
+ 2 * k
+ 4, (char *)p
, (D_kmaps
+ D_nseqs
) - (p
+ 2 * k
+ 4));
773 D_nseqs
-= 2 * k
+ 4;
774 D_seqp
= D_kmaps
+ 3;
790 debug("Mappings:\n");
794 while (p
< D_kmaps
+ D_nseqs
)
797 debug1("%d: ", p
- D_kmaps
+ 3);
798 for (j
= 0; j
< l
; j
++)
800 o
= oo
= p
[l
+ 4 + j
];
802 o
= 2 * o
+ 4 + (p
+ 3 + j
- D_kmaps
);
803 if (p
[j
+ 3] > ' ' && p
[j
+ 3] < 0177)
805 debug3("%c[%d:%d] ", p
[j
+ 3], oo
, o
);
808 debug3("\\%03o[%d:%d] ", p
[j
+ 3], oo
, o
);
810 n
= p
[0] << 8 | p
[1];
811 debug2(" ==> %d%s\n", n
& ~KMAP_NOTIMEOUT
, (n
& KMAP_NOTIMEOUT
) ? " (no timeout)" : "");
820 * Appends to the static variable Termcap
828 if (tcLineLen
+ (n
= strlen(s
)) > 55 && Termcaplen
< TERMCAP_BUFSIZE
- 4 - 1)
830 strcpy(Termcap
+ Termcaplen
, "\\\n\t:");
834 if (Termcaplen
+ n
< TERMCAP_BUFSIZE
- 1)
836 strcpy(Termcap
+ Termcaplen
, s
);
841 Panic(0, "TERMCAP overflow - sorry.");
845 * Reads a displays capabilities and reconstructs a termcap entry in the
846 * global buffer "Termcap". A pointer to this buffer is returned.
852 char buf
[TERMCAP_BUFSIZE
];
853 register char *p
, *cp
, *s
, ch
, *tname
;
871 debug1("MakeTermcap(%d)\n", aflag
);
872 if ((s
= getenv("SCREENCAP")) && strlen(s
) < TERMCAP_BUFSIZE
)
874 sprintf(Termcap
, "TERMCAP=%s", s
);
875 strcpy(Term
, "TERM=screen");
876 debug("getenvSCREENCAP o.k.\n");
880 debug1("MakeTermcap screenterm='%s'\n", screenterm
);
881 debug1("MakeTermcap termname='%s'\n", tname
);
882 if (*screenterm
== '\0' || strlen(screenterm
) > MAXSTR
- 3)
884 debug("MakeTermcap sets screenterm=screen\n");
885 strcpy(screenterm
, "screen");
892 strcpy(Term
, "TERM=");
894 if (!aflag
&& strlen(screenterm
) + strlen(tname
) < MAXSTR
-1)
896 sprintf(p
, "%s.%s", screenterm
, tname
);
897 if (e_tgetent(buf
, p
) == 1)
901 if (nwin_default
.bce
)
903 sprintf(p
, "%s-bce", screenterm
);
904 if (e_tgetent(buf
, p
) == 1)
908 #ifdef CHECK_SCREEN_W
911 sprintf(p
, "%s-w", screenterm
);
912 if (e_tgetent(buf
, p
) == 1)
916 strcpy(p
, screenterm
);
917 if (e_tgetent(buf
, p
) == 1)
924 while (0); /* Goto free programming... */
928 /* check for compatibility problems, displays == 0 after fork */
931 char xbuf
[TERMCAP_BUFSIZE
], *xbp
= xbuf
;
932 if (tgetstr("im", &xbp
) && tgetstr("ic", &xbp
) && displays
)
934 Msg(0, "Warning: im and ic set in %s termcap entry", p
);
940 tcLineLen
= 100; /* Force NL */
941 if (strlen(Term
) > TERMCAP_BUFSIZE
- 40)
942 strcpy(Term
, "too_long");
943 sprintf(Termcap
, "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal:", Term
+ 5);
944 Termcaplen
= strlen(Termcap
);
945 debug1("MakeTermcap decided '%s'\n", p
);
946 if (extra_outcap
&& *extra_outcap
)
948 for (cp
= extra_outcap
; (p
= index(cp
, ':')); cp
= p
)
955 tcLineLen
= 100; /* Force NL */
957 debug1("MakeTermcap after outcap '%s'\n", (char *)TermcapConst
);
958 if (Termcaplen
+ strlen(TermcapConst
) < TERMCAP_BUFSIZE
)
960 strcpy(Termcap
+ Termcaplen
, (char *)TermcapConst
);
961 Termcaplen
+= strlen(TermcapConst
);
963 sprintf(buf
, "li#%d:co#%d:", he
, wi
);
966 if (aflag
|| (force_vt
&& !D_COP
) || D_CLP
|| !D_AM
)
972 if (aflag
|| (D_CS
&& D_SR
) || D_AL
|| D_CAL
)
976 AddCap("AL=\\E[%dL:");
981 AddCap("cs=\\E[%i%d;%dr:");
982 if (aflag
|| D_CS
|| D_DL
|| D_CDL
)
985 AddCap("DL=\\E[%dM:");
987 if (aflag
|| D_DC
|| D_CDC
)
990 AddCap("DC=\\E[%dP:");
992 if (aflag
|| D_CIC
|| D_IC
|| D_IM
)
994 AddCap("im=\\E[4h:");
995 AddCap("ei=\\E[4l:");
997 AddCap("IC=\\E[%d@:");
1000 AddCap("ks=\\E[?1h\\E=:");
1001 AddCap("ke=\\E[?1l\\E>:");
1003 AddCap("vi=\\E[?25l:");
1004 AddCap("ve=\\E[34h\\E[?25h:");
1005 AddCap("vs=\\E[34l:");
1006 AddCap("ti=\\E[?1049h:");
1007 AddCap("te=\\E[?1049l:");
1012 AddCap("us=\\E[4m:");
1013 AddCap("ue=\\E[24m:");
1017 AddCap("so=\\E[3m:");
1018 AddCap("se=\\E[23m:");
1021 AddCap("mb=\\E[5m:");
1023 AddCap("md=\\E[1m:");
1025 AddCap("mh=\\E[2m:");
1027 AddCap("mr=\\E[7m:");
1028 if (D_MB
|| D_MD
|| D_MH
|| D_MR
)
1029 AddCap("me=\\E[m:ms:");
1031 AddCap("Co#8:pa#64:AF=\\E[3%dm:AB=\\E[4%dm:op=\\E[39;49m:AX:");
1042 AddCap("CS=\\E[?1h:");
1043 AddCap("CE=\\E[?1l:");
1048 if (D_CC0
|| (D_CS0
&& *D_CS0
))
1050 AddCap("as=\\E(0:");
1051 AddCap("ae=\\E(B:");
1052 /* avoid `` because some shells dump core... */
1053 AddCap("ac=\\140\\140aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++,,hhII00:");
1057 AddCap("po=\\E[5i:");
1058 AddCap("pf=\\E[4i:");
1062 AddCap("Z0=\\E[?3h:");
1063 AddCap("Z1=\\E[?3l:");
1066 AddCap("WS=\\E[8;%d;%dt:");
1068 for (i
= T_CAPS
; i
< T_ECAPS
; i
++)
1074 if (i
>= T_KEYPAD
) /* don't put keypad codes in TERMCAP */
1075 continue; /* - makes it too big */
1076 if (i
>= T_CURSOR
&& i
< T_OCAPS
)
1078 act
= &umtab
[i
- (T_CURSOR
- T_OCAPS
+ T_CAPS
)];
1079 if (act
->nr
== RC_ILLEGAL
)
1080 act
= &dmtab
[i
- (T_CURSOR
- T_OCAPS
+ T_CAPS
)];
1084 act
= &umtab
[i
- T_CAPS
];
1085 if (act
->nr
== RC_ILLEGAL
)
1086 act
= &dmtab
[i
- T_CAPS
];
1088 if (act
->nr
== RC_ILLEGAL
&& (i
== T_NAVIGATE
+ 1 || i
== T_NAVIGATE
+ 3))
1090 /* kh -> @1, kH -> @7 */
1091 act
= &umtab
[i
- T_CAPS
- 1];
1092 if (act
->nr
== RC_ILLEGAL
)
1093 act
= &dmtab
[i
- T_CAPS
- 1];
1095 if (act
->nr
!= RC_ILLEGAL
)
1097 if (act
->nr
== RC_STUFF
)
1099 MakeString(term
[i
].tcname
, buf
, sizeof(buf
), act
->args
[0]);
1108 switch(term
[i
].type
)
1111 if (D_tcs
[i
].str
== 0)
1113 MakeString(term
[i
].tcname
, buf
, sizeof(buf
), D_tcs
[i
].str
);
1117 if (D_tcs
[i
].flg
== 0)
1119 sprintf(buf
, "%s:", term
[i
].tcname
);
1126 debug("MakeTermcap: end\n");
1131 MakeString(cap
, buf
, buflen
, s
)
1136 register char *p
, *pmax
;
1137 register unsigned int c
;
1140 pmax
= p
+ buflen
- (3+4+2);
1144 while ((c
= *s
++) && (p
< pmax
))
1164 sprintf(p
, "\\%03o", c
& 0377);
1183 (*p == '\\' && (p[1] == '\\' || p[1] == ',' || p[1] == '%'))
1198 if ((D_xtable
= (char ***)calloc(256, sizeof(char **))) == 0)
1208 curchar
= (unsigned char)*s
++;
1210 curchar
= 0; /* ASCII */
1214 if (D_xtable
[curchar
] == 0)
1216 if ((D_xtable
[curchar
] = (char **)calloc(257, sizeof(char *))) == 0)
1223 ctable
= D_xtable
[curchar
];
1224 for(; *s
&& *s
!= ','; s
++)
1237 while (*s
&& *s
!= ',')
1239 c
= (unsigned char)*s
++;
1240 if (QUOTES((s
- 1)))
1241 c
= (unsigned char)*s
++;
1247 l
= copyarg(&s
, (char *)0);
1249 l
= l
* templnsub
+ templlen
;
1250 if ((ctable
[c
] = (char *)malloc(l
+ 1)) == 0)
1257 for (p
= ((c
== 256) ? "%" : templ
); *p
&& *p
!= ','; p
++)
1264 sx
+= copyarg(&s
, sx
);
1270 ASSERT(ctable
[c
] + l
* templnsub
+ templlen
== sx
);
1271 debug3("XC: %c %c->%s\n", curchar
, c
, ctable
[c
]);
1285 if ((p
= D_xtable
) == 0)
1287 for (i
= 0; i
< 256; i
++, p
++)
1292 for (j
= 0; j
< 257; j
++, q
++)
1308 for (l
= 0, p
= *pp
; *p
&& *p
!= ','; p
++)
1325 ** Termcap routines that use our extra_incap
1339 r
= tgetent(bp
, name
);
1349 * cap = capability we are looking for
1350 * tepp = pointer to bufferpointer
1351 * n = size of buffer (0 = infinity)
1355 findcap(cap
, tepp
, n
)
1362 int mode
; /* mode: 0=LIT 1=^ 2=\x 3,4,5=\nnn */
1371 for (p
= extra_incap
; *p
; )
1373 if (strncmp(p
, cap
, capl
) == 0)
1377 if (c
&& c
!= ':' && c
!= '@')
1379 if (c
== 0 || c
== '@' || c
== '=' || c
== ':' || c
== '#')
1439 num
= num
* 8 + (c
- '0');
1440 if (mode
++ == 5 || (*p
< '0' || *p
> '9'))
1459 debug2("'%s' found in extra_incap -> %s\n", cap
, tep
);
1467 e_tgetstr(cap
, tepp
)
1472 if ((tep
= findcap(cap
, tepp
, 0)))
1473 return (*tep
== '@') ? 0 : tep
;
1474 return tgetstr(cap
, tepp
);
1484 if ((tep
= findcap(cap
, &bufp
, 2)))
1485 return (*tep
== '@') ? 0 : 1;
1486 return tgetflag(cap
) > 0;
1493 char buf
[20], *bufp
;
1498 if ((tep
= findcap(cap
, &bufp
, 20)))
1506 while ((c
= *tep
++) >= '0' && c
<= '9')
1507 res
= res
* base
+ (c
- '0');
1510 return tgetnum(cap
);