1 /********************************************************************/
2 /*                                                                  */
3 /*  trm_inf.c     Driver for terminfo screen access.                */
4 /*  Copyright (C) 1989 - 2005  Thomas Mertes                        */
5 /*                                                                  */
6 /*  This file is part of the Seed7 Runtime Library.                 */
7 /*                                                                  */
8 /*  The Seed7 Runtime Library is free software; you can             */
9 /*  redistribute it and/or modify it under the terms of the GNU     */
10 /*  Lesser General Public License as published by the Free Software */
11 /*  Foundation; either version 2.1 of the License, or (at your      */
12 /*  option) any later version.                                      */
13 /*                                                                  */
14 /*  The Seed7 Runtime Library is distributed in the hope that it    */
15 /*  will be useful, but WITHOUT ANY WARRANTY; without even the      */
16 /*  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
17 /*  PURPOSE.  See the GNU Lesser General Public License for more    */
18 /*  details.                                                        */
19 /*                                                                  */
20 /*  You should have received a copy of the GNU Lesser General       */
21 /*  Public License along with this program; if not, write to the    */
22 /*  Free Software Foundation, Inc., 51 Franklin Street,             */
23 /*  Fifth Floor, Boston, MA  02110-1301, USA.                       */
24 /*                                                                  */
25 /*  Module: Seed7 Runtime Library                                   */
26 /*  File: seed7/src/trm_inf.c                                       */
27 /*  Changes: 1994  Thomas Mertes                                    */
28 /*  Content: Driver for terminfo screen access.                     */
29 /*                                                                  */
30 /********************************************************************/
31 
32 #define LOG_FUNCTIONS 0
33 #define VERBOSE_EXCEPTIONS 0
34 
35 #include "version.h"
36 
37 #ifdef USE_TERMINFO
38 #include "stdlib.h"
39 #include "stdio.h"
40 #include "string.h"
41 
42 #ifdef TERM_INCLUDE
43 #include TERM_INCLUDE
44 #ifdef HAS_TERMIOS_H
45 #include "termios.h"
46 #endif
47 #else
48 #ifdef INCL_CURSES_BEFORE_TERM
49 /* The following includes are necessary for RM Machines. */
50 #include "curses.h"
51 #include "termios.h"
52 #endif
53 
54 #ifdef INCL_NCURSES_TERM
55 #include "ncurses/term.h"
56 #else
57 #include "term.h"
58 #endif
59 #endif
60 
61 #include "common.h"
62 #include "os_decls.h"
63 
64 #undef EXTERN
65 #define EXTERN
66 #define DO_INIT
67 #include "trm_drv.h"
68 
69 #define SETUPTERM_WORKS_OK
70 
71 
72 #ifdef OUT_OF_ORDER
73 #ifdef C_PLUS_PLUS
74 
75 extern "C" int tgetent (char *, char *);
76 extern "C" int tgetnum (char *);
77 extern "C" int tgetflag (char *);
78 extern "C" char *tgetstr(char *, char **);
79 extern "C" char *tgoto (char *, int, int);
80 extern "C" int tputs (char *, int, int (*) (char ch));
81 
82 #else
83 
84 int tgetent (char *, char *);
85 int tgetnum (char *);
86 int tgetflag (char *);
87 char *tgetstr(char *, char **);
88 char *tgoto (char *, int, int);
89 void tputs (char *, int, int (*) (char ch));
90 
91 #endif
92 #endif
93 
94 
95 
read_cap_name(FILE * fix_file,char * cap_name,int * term_char)96 static void read_cap_name (FILE *fix_file, char *cap_name, int *term_char)
97 
98   {
99     int ch;
100 
101   /* read_cap_name */
102     do {
103       ch = fgetc(fix_file);
104     } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
105     while (ch != ':' && ch != ',' &&
106         ch != '=' && ch != '#' && ch != '|' && ch != EOF) {
107       *cap_name++ = (char) ch;
108       ch = fgetc(fix_file);
109     } /* while */
110     *cap_name = '\0';
111     *term_char = ch;
112   } /* read_cap_name */
113 
114 
115 
read_int_cap(FILE * fix_file,char ** cap_value,int * term_char)116 static void read_int_cap (FILE *fix_file, char **cap_value, int *term_char)
117 
118   {
119     int from;
120 
121   /* read_int_cap */
122     from = fgetc(fix_file);
123     while (from != ',' && from != ':') {
124       from = fgetc(fix_file);
125     } /* while */
126     *term_char = from;
127   } /* read_int_cap */
128 
129 
130 
read_stri_cap(FILE * fix_file,char ** cap_value,int * term_char)131 static void read_stri_cap (FILE *fix_file, char **cap_value, int *term_char)
132 
133   {
134     int from;
135     char to_buf[513];
136     char *to;
137 
138   /* read_stri_cap */
139     from = fgetc(fix_file);
140     to = to_buf;
141     while (from != ',' && from != ':' && from != EOF) {
142       if (from == '\\') {
143         from = fgetc(fix_file);
144         if (from == 'E' || from == 'e') {
145           *to++ = '\033';
146         } else if (from == 'n') {
147           *to++ = '\n';
148         } else if (from == 'l') {
149           *to++ = '\n';
150         } else if (from == 'r') {
151           *to++ = '\r';
152         } else if (from == 't') {
153           *to++ = '\t';
154         } else if (from == 'b') {
155           *to++ = '\b';
156         } else if (from == 'f') {
157           *to++ = '\f';
158         } else if (from == 's') {
159           *to++ = ' ';
160         } else if (from == '0') {
161           *to++ = '\200';
162         } else if (from == EOF) {
163           *to++ = '\\';
164         } else {
165           *to++ = (char) from;
166         } /* if */
167         from = fgetc(fix_file);
168       } else if (from == '^') {
169         from = fgetc(fix_file);
170         if (from >= 'a' && from <= 'z') {
171           *to++ = (char) (from - 'a' + 1);
172         } else if (from >= 'A' && from <= 'Z') {
173           *to++ = (char) (from - 'A' + 1);
174         } else if (from == EOF) {
175           *to++ = '^';
176         } else {
177           *to++ = (char) from;
178         } /* if */
179         from = fgetc(fix_file);
180       } else {
181         *to++ = (char) from;
182         from = fgetc(fix_file);
183       } /* if */
184     } /* while */
185     if (to == to_buf) {
186       *cap_value = NULL;
187     } else {
188       *to = '\0';
189       if ((*cap_value = (char *) malloc((size_t) (to - to_buf + 1))) != NULL) {
190         strcpy(*cap_value, to_buf);
191       } /* if */
192     } /* if */
193     *term_char = from;
194   } /* read_stri_cap */
195 
196 
197 
assign_cap(char * cap_name,const_cstriType terminfo_name,const_cstriType termcap_name,char ** cap_pointer,char * cap_value)198 static int assign_cap (char *cap_name, const_cstriType terminfo_name,
199     const_cstriType termcap_name, char **cap_pointer, char *cap_value)
200 
201   { /* assign_cap */
202     if (cap_name != NULL &&
203         (strcmp(cap_name, terminfo_name) == 0 ||
204         strcmp(cap_name, termcap_name) == 0)) {
205       logMessage(fprintf(stderr, "%s=%s:\n", cap_name, cap_value););
206       *cap_pointer = cap_value;
207       return TRUE;
208     } else {
209       return FALSE;
210     } /* if */
211   } /* assign_cap */
212 
213 
214 
fix_capability(void)215 static void fix_capability (void)
216 
217   {
218     char *home_dir_path;
219     char *terminal_name;
220     char fix_file_name[256];
221     FILE *fix_file;
222     char cap_name[256];
223     char *cap_value;
224     int term_char;
225     size_t len;
226 
227   /* fix_capability */
228     logFunction(fprintf(stderr, "fix_capability\n"););
229     home_dir_path = getenv("HOME");
230     terminal_name = getenv("TERM");
231     if (home_dir_path != NULL) {
232       strcpy(fix_file_name, home_dir_path);
233       len = strlen(fix_file_name);
234     } else {
235       len = 0;
236     } /* if */
237     if (len > 0 && fix_file_name[len - 1] != '/') {
238       fix_file_name[len] = '/';
239       len++;
240     } /* if */
241     strcpy(&fix_file_name[len], ".term");
242     if (terminal_name != NULL) {
243       strcat(fix_file_name, terminal_name);
244     } /* if */
245     if ((fix_file = fopen(fix_file_name, "r")) != NULL) {
246       do {
247         read_cap_name(fix_file, cap_name, &term_char);
248       } while (term_char != ',' && term_char != ':' && term_char != EOF);
249       read_cap_name(fix_file, cap_name, &term_char);
250       logMessage(fprintf(stderr, "cap \"%s\" ", cap_name););
251       while (term_char != EOF) {
252         cap_value = NULL;
253         switch (term_char) {
254           case ',':
255           case ':':
256             break;
257           case '#':
258             read_int_cap(fix_file, &cap_value, &term_char);
259             break;
260           case '=':
261             read_stri_cap(fix_file, &cap_value, &term_char);
262             break;
263         } /* switch */
264         if (assign_cap(cap_name, "rmkx",  "ke", &keypad_local, cap_value) ||
265             assign_cap(cap_name, "smkx",  "ks", &keypad_xmit,  cap_value) ||
266             assign_cap(cap_name, "kcbt",  "kB", &key_btab,     cap_value) ||
267             assign_cap(cap_name, "kdch1", "kD", &key_dc,       cap_value) ||
268             assign_cap(cap_name, "kcud1", "kd", &key_down,     cap_value) ||
269             assign_cap(cap_name, "khome", "kh", &key_home,     cap_value) ||
270             assign_cap(cap_name, "kich1", "kI", &key_ic,       cap_value) ||
271             assign_cap(cap_name, "kcub1", "kl", &key_left,     cap_value) ||
272             assign_cap(cap_name, "knp",   "kN", &key_npage,    cap_value) ||
273             assign_cap(cap_name, "kpp",   "kP", &key_ppage,    cap_value) ||
274             assign_cap(cap_name, "kind",  "kF", &key_sf,       cap_value) ||
275             assign_cap(cap_name, "kri",   "kR", &key_sr,       cap_value) ||
276             assign_cap(cap_name, "kcuf1", "kr", &key_right,    cap_value) ||
277             assign_cap(cap_name, "kcuu1", "ku", &key_up,       cap_value) ||
278             assign_cap(cap_name, "kend",  "@7", &key_end,      cap_value) ||
279             assign_cap(cap_name, "kb2",   "K2", &key_b2,       cap_value) ||
280             assign_cap(cap_name, "kf0",   "k0", &key_f0,       cap_value) ||
281             assign_cap(cap_name, "kf1",   "k1", &key_f1,       cap_value) ||
282             assign_cap(cap_name, "kf2",   "k2", &key_f2,       cap_value) ||
283             assign_cap(cap_name, "kf3",   "k3", &key_f3,       cap_value) ||
284             assign_cap(cap_name, "kf4",   "k4", &key_f4,       cap_value) ||
285             assign_cap(cap_name, "kf5",   "k5", &key_f5,       cap_value) ||
286             assign_cap(cap_name, "kf6",   "k6", &key_f6,       cap_value) ||
287             assign_cap(cap_name, "kf7",   "k7", &key_f7,       cap_value) ||
288             assign_cap(cap_name, "kf8",   "k8", &key_f8,       cap_value) ||
289             assign_cap(cap_name, "kf9",   "k9", &key_f9,       cap_value) ||
290             assign_cap(cap_name, "kf10",  "k;", &key_f10,      cap_value) ||
291             assign_cap(cap_name, "kf11",  "F1", &key_f11,      cap_value) ||
292             assign_cap(cap_name, "kf12",  "F2", &key_f12,      cap_value) ||
293             assign_cap(cap_name, "kf13",  "F3", &key_f13,      cap_value) ||
294             assign_cap(cap_name, "kf14",  "F4", &key_f14,      cap_value) ||
295             assign_cap(cap_name, "kf15",  "F5", &key_f15,      cap_value) ||
296             assign_cap(cap_name, "kf16",  "F6", &key_f16,      cap_value) ||
297             assign_cap(cap_name, "kf17",  "F7", &key_f17,      cap_value) ||
298             assign_cap(cap_name, "kf18",  "F8", &key_f18,      cap_value) ||
299             assign_cap(cap_name, "kf19",  "F9", &key_f19,      cap_value) ||
300             assign_cap(cap_name, "kf20",  "FA", &key_f20,      cap_value) ||
301             assign_cap(cap_name, "kf21",  "FB", &key_f21,      cap_value) ||
302             assign_cap(cap_name, "kf22",  "FC", &key_f22,      cap_value) ||
303             assign_cap(cap_name, "kf23",  "FD", &key_f23,      cap_value) ||
304             assign_cap(cap_name, "kf24",  "FE", &key_f24,      cap_value) ||
305             assign_cap(cap_name, "kf25",  "FF", &key_f25,      cap_value) ||
306             assign_cap(cap_name, "kf26",  "FG", &key_f26,      cap_value) ||
307             assign_cap(cap_name, "kf27",  "FH", &key_f27,      cap_value) ||
308             assign_cap(cap_name, "kf28",  "FI", &key_f28,      cap_value) ||
309             assign_cap(cap_name, "kf29",  "FJ", &key_f29,      cap_value) ||
310             assign_cap(cap_name, "kf30",  "FK", &key_f30,      cap_value) ||
311             assign_cap(cap_name, "kf31",  "FL", &key_f31,      cap_value) ||
312             assign_cap(cap_name, "kf32",  "FM", &key_f32,      cap_value) ||
313             assign_cap(cap_name, "kf33",  "FN", &key_f33,      cap_value) ||
314             assign_cap(cap_name, "kf34",  "FO", &key_f34,      cap_value) ||
315             assign_cap(cap_name, "kf35",  "FP", &key_f35,      cap_value) ||
316             assign_cap(cap_name, "kf36",  "FQ", &key_f36,      cap_value) ||
317             assign_cap(cap_name, "kf37",  "FR", &key_f37,      cap_value) ||
318             assign_cap(cap_name, "kf38",  "FS", &key_f38,      cap_value) ||
319             assign_cap(cap_name, "kf39",  "FT", &key_f39,      cap_value) ||
320             assign_cap(cap_name, "kf40",  "FU", &key_f40,      cap_value) ||
321             assign_cap(cap_name, "kf41",  "FV", &key_f41,      cap_value) ||
322             assign_cap(cap_name, "kf42",  "FW", &key_f42,      cap_value) ||
323             assign_cap(cap_name, "kf43",  "FX", &key_f43,      cap_value) ||
324             assign_cap(cap_name, "kf44",  "FY", &key_f44,      cap_value) ||
325             assign_cap(cap_name, "kf45",  "FZ", &key_f45,      cap_value) ||
326             assign_cap(cap_name, "kf46",  "Fa", &key_f46,      cap_value) ||
327             assign_cap(cap_name, "kf47",  "Fb", &key_f47,      cap_value) ||
328             assign_cap(cap_name, "kf48",  "Fc", &key_f48,      cap_value) ||
329             assign_cap(cap_name, "kf49",  "Fd", &key_f49,      cap_value) ||
330             assign_cap(cap_name, "kf50",  "Fe", &key_f50,      cap_value) ||
331             assign_cap(cap_name, "kf51",  "Ff", &key_f51,      cap_value) ||
332             assign_cap(cap_name, "kf52",  "Fg", &key_f52,      cap_value) ||
333             assign_cap(cap_name, "kf53",  "Fh", &key_f53,      cap_value) ||
334             assign_cap(cap_name, "kf54",  "Fi", &key_f54,      cap_value) ||
335             assign_cap(cap_name, "kf55",  "Fj", &key_f55,      cap_value) ||
336             assign_cap(cap_name, "kf56",  "Fk", &key_f56,      cap_value) ||
337             assign_cap(cap_name, "kf57",  "Fl", &key_f57,      cap_value) ||
338             assign_cap(cap_name, "kf58",  "Fm", &key_f58,      cap_value) ||
339             assign_cap(cap_name, "kf59",  "Fn", &key_f59,      cap_value) ||
340             assign_cap(cap_name, "kf60",  "Fo", &key_f60,      cap_value) ||
341             assign_cap(cap_name, "kf61",  "Fp", &key_f61,      cap_value) ||
342             assign_cap(cap_name, "kf62",  "Fq", &key_f62,      cap_value) ||
343             assign_cap(cap_name, "kf63",  "Fr", &key_f63,      cap_value)) {
344         } /* if */
345         read_cap_name(fix_file, cap_name, &term_char);
346         logMessage(fprintf(stderr, "cap \"%s\" ", cap_name););
347       } /* while */
348       fclose(fix_file);
349     } /* if */
350     logFunction(fprintf(stderr, "fix_capability -->\n"););
351   } /* fix_capability */
352 
353 
354 
getcaps(void)355 int getcaps (void)
356 
357   {
358     char *terminal_name;
359     int setup_result;
360     int errret;
361 
362   /* getcaps */
363     logFunction(fprintf(stderr, "getcaps\n"););
364     if (!caps_initialized) {
365       if ((terminal_name = getenv("TERM")) != NULL) {
366         logMessage(fprintf(stderr, "TERM = \"%s\"\n", terminal_name););
367         errret = 1;
368         setup_result = setupterm(terminal_name, fileno(stdout), &errret);
369         logMessage(fprintf(stderr, "setupterm --> %d  errret = %d\n",
370                            setup_result, errret););
371 #ifdef SETUPTERM_WORKS_OK
372         if (setup_result == 0 /*OK*/  &&  errret == 1) {
373 #endif
374           fix_capability();
375           caps_initialized = TRUE;
376 #ifdef SETUPTERM_WORKS_OK
377         } /* if */
378 #endif
379       } /* if */
380     } /* if */
381     logFunction(fprintf(stderr, "getcaps --> %d\n", caps_initialized););
382     return caps_initialized;
383   } /* getcaps */
384 
385 
386 
outch(int ch)387 int outch (int ch)
388 
389   { /* outch */
390     return putchar(ch);
391   } /* outch */
392 
393 
394 
putcontrol(char * control)395 void putcontrol (char *control)
396 
397   { /* putcontrol */
398     if (control != NULL) {
399       tputs(control, 1, outch);
400     } /* if */
401   } /* putcontrol */
402 
403 #endif
404