1 /* Routines for querying termcap information on UNIX.
2    These routines are shared between the alternative screen
3    modules curses.c and ansi.c
4 */
5 
6 #include <string.h>
7 #include <ctype.h>
8 #include <stdlib.h>
9 #include "readtc.h"
10 
11 /* the pseudographic character codes */
12 #define ASCII_SPECIALS "|-****|-*****><!*^v&*"
13 char *tt_specials = ASCII_SPECIALS;
14 char *tt_alternate_start = NULL;
15 char *tt_alternate_end = NULL;
16 
17 /* cursor shape control */
18 char *tt_showcursor = NULL;
19 char *tt_hidecursor = NULL;
20 
21 #if defined(UNIX) || defined(Cygwin)
22 
23 #define DEC_SPECIALS   "xqlkmjxqlkmja>< p^V&*"
24 #define LINUX_SPECIALS   "\225\232\226\234\223\231\205\212\206\214\203\211*><!*^V&*"
25 /* "\170\161\154\153\155\152\170\161\154\153\155\152\141><\160^^V&*" */
26 
27 
28 /* No chance to guess which UNIX uses term.h and which termcap.h, so we
29    just have to use our own prototype. I know this is ugly ...
30    #include <termcap.h>
31    #include <term.h>
32 */
33 
34 int tgetent(char *, const char *);
35 char *tgetstr(char *, char **);
36 
37 static char termbuf[4096];
38 static char termresult[4096];
39 
transform_acs(char * template,char * terminfo)40 static char *transform_acs(char *template, char *terminfo)
41 {
42     int i;
43     static char buffer[22];
44     char *p;
45 
46     for (i = 0; i < sizeof(buffer) && i < strlen(template); i++)
47     {
48         p = islower(template[i]) ? strchr(terminfo, template[i]) : NULL;
49         if (p != NULL && p[0] && p[1])
50         {
51             buffer[i] = p[1];
52         }
53         else
54         {
55             buffer[i] = ASCII_SPECIALS[i];
56         }
57     }
58     return buffer;
59 }
60 
query_termcap(int what)61 void query_termcap(int what)
62 {
63     char *termname;
64     char *area;
65     char *acs;
66 
67     termname = getenv("TERM");
68 
69     /* READ INFORMATION ON PSEUDO GRAPHICS CHARACTERS */
70 
71     if ((termname != NULL) && (what & QUERY_ALTCHARSET))
72     {
73         /* The Linux people are idiots, can't even get their termcap right */
74         if (!strcmp(termname, "linux") ||
75             !strcmp(termname, "linux-lat") ||
76             !strcmp(termname, "linux console"))
77         {
78             tt_specials = LINUX_SPECIALS;
79             tt_alternate_start = "";
80             tt_alternate_end = "";
81             tt_showcursor = "\033[25h";
82             tt_hidecursor = "\033[25l";
83         }
84         else if (tgetent(termbuf, termname) != 0)
85         {
86             area = termresult;
87             tt_alternate_start = tgetstr("as", &area);
88             tt_alternate_end = tgetstr("ae", &area);
89             acs = tgetstr("ac", &area);
90             tt_showcursor = tgetstr("ve", &area);
91             tt_hidecursor = tgetstr("vi", &area);
92 
93             if (acs != NULL)
94             {
95                 tt_specials = transform_acs(DEC_SPECIALS, acs);
96                 if (tt_alternate_start == NULL)
97                 {
98                     tt_alternate_start = "";
99                 }
100                 if (tt_alternate_end == NULL)
101                 {
102                     tt_alternate_end = "";
103                 }
104             }
105             else if (tt_alternate_start != NULL && tt_alternate_end != NULL)
106             {
107                 tt_specials = DEC_SPECIALS;
108             }
109             else
110             {
111                 tt_alternate_start = NULL;
112                 tt_alternate_end = NULL;
113             }
114         }
115     } else
116     {
117         tt_specials = ASCII_SPECIALS;
118         tt_alternate_start = NULL;
119         tt_alternate_end = NULL;
120     }
121 }
122 #endif
123