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