fix panel_scroll_pages start page
[midnight-commander.git] / slang / sltermin.c
blob94119fd17bf39c6157da057471f0b4e422a2fd9d
1 /* This file contains enough terminfo reading capabilities sufficient for
2 * the slang SLtt interface.
3 */
5 /* Copyright (c) 1992, 1995 John E. Davis
6 * All rights reserved.
7 *
8 * You may distribute under the terms of either the GNU General Public
9 * License or the Perl Artistic License.
12 #include "config.h"
14 #include <stdio.h>
15 #ifdef HAVE_STDLIB_H
16 # include <stdlib.h>
17 #endif
19 #ifndef USE_SETUPTERM
20 #include "_slang.h"
23 * The majority of the comments found in the file were taken from the
24 * term(4) man page on an SGI.
27 /* Short integers are stored in two 8-bit bytes. The first byte contains
28 * the least significant 8 bits of the value, and the second byte contains
29 * the most significant 8 bits. (Thus, the value represented is
30 * 256*second+first.) The value -1 is represented by 0377,0377, and the
31 * value -2 is represented by 0376,0377; other negative values are illegal.
32 * The -1 generally means that a capability is missing from this terminal.
33 * The -2 means that the capability has been cancelled in the terminfo
34 * source and also is to be considered missing.
37 static int make_integer (unsigned char *buf)
39 register int lo, hi;
40 lo = (int) *buf++; hi = (int) *buf;
41 if (hi == 0377)
43 if (lo == 0377) return -1;
44 if (lo == 0376) return -2;
46 return lo + 256 * hi;
50 * The compiled file is created from the source file descriptions of the
51 * terminals (see the -I option of infocmp) by using the terminfo compiler,
52 * tic, and read by the routine setupterm [see curses(3X).] The file is
53 * divided into six parts in the following order: the header, terminal
54 * names, boolean flags, numbers, strings, and string table.
56 * The header section begins the file. This section contains six short
57 * integers in the format described below. These integers are (1) the magic
58 * number (octal 0432); (2) the size, in bytes, of the names section; (3)
59 * the number of bytes in the boolean section; (4) the number of short
60 * integers in the numbers section; (5) the number of offsets (short
61 * integers) in the strings section; (6) the size, in bytes, of the string
62 * table.
65 #define MAGIC 0432
67 /* In this structure, all char * fields are malloced EXCEPT if the
68 * structure is SLTERMCAP. In that case, only terminal_names is malloced
69 * and the other fields are pointers into it.
71 typedef struct
73 #define SLTERMINFO 1
74 #define SLTERMCAP 2
75 unsigned int flags;
77 unsigned int name_section_size;
78 char *terminal_names;
80 unsigned int boolean_section_size;
81 unsigned char *boolean_flags;
83 unsigned int num_numbers;
84 unsigned char *numbers;
86 unsigned int num_string_offsets;
87 unsigned char *string_offsets;
89 unsigned int string_table_size;
90 char *string_table;
92 } Terminfo_Type;
94 static char *tcap_getstr (char *, Terminfo_Type *);
95 static int tcap_getnum (char *, Terminfo_Type *);
96 static int tcap_getflag (char *, Terminfo_Type *);
97 static int tcap_getent (char *, Terminfo_Type *);
99 static FILE *open_terminfo (char *file, Terminfo_Type *h)
101 FILE *fp;
102 unsigned char buf[12];
104 fp = fopen (file, "rb");
105 if (fp == NULL) return NULL;
107 if ((12 == fread ((char *) buf, 1, 12, fp) && (MAGIC == make_integer (buf))))
109 h->name_section_size = make_integer (buf + 2);
110 h->boolean_section_size = make_integer (buf + 4);
111 h->num_numbers = make_integer (buf + 6);
112 h->num_string_offsets = make_integer (buf + 8);
113 h->string_table_size = make_integer (buf + 10);
115 else
117 fclose (fp);
118 fp = NULL;
120 return fp;
124 * The terminal names section comes next. It contains the first line of the
125 * terminfo description, listing the various names for the terminal,
126 * separated by the bar ( | ) character (see term(5)). The section is
127 * terminated with an ASCII NUL character.
130 /* returns pointer to malloced space */
131 static unsigned char *read_terminfo_section (FILE *fp, unsigned int size)
133 char *s;
135 if (NULL == (s = (char *) SLMALLOC (size))) return NULL;
136 if (size != fread (s, 1, size, fp))
138 SLFREE (s);
139 return NULL;
141 return (unsigned char *) s;
144 static char *read_terminal_names (FILE *fp, Terminfo_Type *t)
146 return t->terminal_names = (char *) read_terminfo_section (fp, t->name_section_size);
150 * The boolean flags have one byte for each flag. This byte is either 0 or
151 * 1 as the flag is present or absent. The value of 2 means that the flag
152 * has been cancelled. The capabilities are in the same order as the file
153 * <term.h>.
156 static unsigned char *read_boolean_flags (FILE *fp, Terminfo_Type *t)
158 /* Between the boolean section and the number section, a null byte is
159 * inserted, if necessary, to ensure that the number section begins on an
160 * even byte offset. All short integers are aligned on a short word
161 * boundary.
164 unsigned int size = (t->name_section_size + t->boolean_section_size) % 2;
165 size += t->boolean_section_size;
167 return t->boolean_flags = read_terminfo_section (fp, size);
173 * The numbers section is similar to the boolean flags section. Each
174 * capability takes up two bytes, and is stored as a short integer. If the
175 * value represented is -1 or -2, the capability is taken to be missing.
178 static unsigned char *read_numbers (FILE *fp, Terminfo_Type *t)
180 return t->numbers = read_terminfo_section (fp, 2 * t->num_numbers);
184 /* The strings section is also similar. Each capability is stored as a
185 * short integer, in the format above. A value of -1 or -2 means the
186 * capability is missing. Otherwise, the value is taken as an offset from
187 * the beginning of the string table. Special characters in ^X or \c
188 * notation are stored in their interpreted form, not the printing
189 * representation. Padding information ($<nn>) and parameter information
190 * (%x) are stored intact in uninterpreted form.
193 static unsigned char *read_string_offsets (FILE *fp, Terminfo_Type *t)
195 return t->string_offsets = (unsigned char *) read_terminfo_section (fp, 2 * t->num_string_offsets);
199 /* The final section is the string table. It contains all the values of
200 * string capabilities referenced in the string section. Each string is
201 * null terminated.
204 static char *read_string_table (FILE *fp, Terminfo_Type *t)
206 return t->string_table = (char *) read_terminfo_section (fp, t->string_table_size);
211 * Compiled terminfo(4) descriptions are placed under the directory
212 * /usr/share/lib/terminfo. In order to avoid a linear search of a huge
213 * UNIX system directory, a two-level scheme is used:
214 * /usr/share/lib/terminfo/c/name where name is the name of the terminal,
215 * and c is the first character of name. Thus, att4425 can be found in the
216 * file /usr/share/lib/terminfo/a/att4425. Synonyms for the same terminal
217 * are implemented by multiple links to the same compiled file.
220 #define MAX_TI_DIRS 7
221 static char *Terminfo_Dirs [MAX_TI_DIRS] =
223 NULL,
224 "/usr/lib/terminfo",
225 "/usr/share/lib/terminfo",
226 "/usr/local/lib/terminfo",
227 "/lib/terminfo",
228 "/usr/local/share/terminfo",
229 "/usr/share/terminfo"
232 char *SLtt_tigetent (char *term)
234 char *tidir;
235 int i;
236 FILE *fp = NULL;
237 char *file;
238 Terminfo_Type *ti;
240 if (
241 (term == NULL)
242 #ifdef SLANG_UNTIC
243 && (SLang_Untic_Terminfo_File == NULL)
244 #endif
246 return NULL;
248 if (NULL == (ti = (Terminfo_Type *) SLMALLOC (sizeof (Terminfo_Type))))
250 return NULL;
253 #ifdef SLANG_UNTIC
254 if (SLang_Untic_Terminfo_File != NULL)
256 fp = open_terminfo (SLang_Untic_Terminfo_File, ti);
257 goto fp_open_label;
259 else
260 #endif
261 /* If we are on a termcap based system, use termcap */
262 if (0 == tcap_getent (term, ti)) return (char *) ti;
264 Terminfo_Dirs[0] = getenv ("TERMINFO");
265 i = 0;
266 while (i < MAX_TI_DIRS)
268 tidir = Terminfo_Dirs[i];
269 if (tidir != NULL)
271 file = SLMALLOC (strlen (tidir) + 3 + strlen (term) + 1);
272 if (!file)
273 continue;
274 sprintf (file, "%s/%c/%s", tidir, *term, term);
275 fp = open_terminfo (file, ti);
276 SLFREE (file);
277 if (fp)
278 break;
280 i++;
282 #ifdef SLANG_UNTIC
283 fp_open_label:
284 #endif
286 if (fp != NULL)
288 if (NULL != read_terminal_names (fp, ti))
290 if (NULL != read_boolean_flags (fp, ti))
292 if (NULL != read_numbers (fp, ti))
294 if (NULL != read_string_offsets (fp, ti))
296 if (NULL != read_string_table (fp, ti))
298 /* success */
299 fclose (fp);
300 ti->flags = SLTERMINFO;
301 return (char *) ti;
303 SLFREE (ti->string_offsets);
305 SLFREE (ti->numbers);
307 SLFREE (ti->boolean_flags);
309 SLFREE (ti->terminal_names);
311 fclose (fp);
314 SLFREE (ti);
315 return NULL;
318 #ifdef SLANG_UNTIC
319 # define UNTIC_COMMENT(x) ,x
320 #else
321 # define UNTIC_COMMENT(x)
322 #endif
324 typedef const struct
326 char name[3];
327 int offset;
328 #ifdef SLANG_UNTIC
329 char *comment;
330 #endif
332 Tgetstr_Map_Type;
334 /* I need to add: K1-5, %0-5(not important), @8, &8... */
335 static Tgetstr_Map_Type Tgetstr_Map [] =
337 {"@7", 164 UNTIC_COMMENT("KEY End")},
338 {"AB", 360 UNTIC_COMMENT("set a color background")},
339 {"AF", 359 UNTIC_COMMENT("set a color foreground")},
340 {"AL", 110 UNTIC_COMMENT("parm_insert_line")},
341 {"DL", 106 UNTIC_COMMENT("parm_delete_line")},
342 {"RI", 112 UNTIC_COMMENT("parm_right_cursor")},
343 {"Sf", 302 UNTIC_COMMENT("set foreground (color)")},
344 {"Sb", 303 UNTIC_COMMENT("set background (color)")},
345 {"ac", 146 UNTIC_COMMENT("acs_chars")},
346 {"ae", 38 UNTIC_COMMENT("exit_alt_charset_mode")},
347 {"as", 25 UNTIC_COMMENT("enter_alt_charset_mode")},
348 {"ce", 6 UNTIC_COMMENT("clr_eol")},
349 {"cl", 5 UNTIC_COMMENT("clear_screen")},
350 {"cm", 10 UNTIC_COMMENT("cursor_address")},
351 {"cs", 3 UNTIC_COMMENT("change_scroll_region")},
352 {"dc", 21 UNTIC_COMMENT("delete_character")},
353 {"ds", 23 UNTIC_COMMENT("disable status line")},
354 {"eA", 155 UNTIC_COMMENT("enable alt char set")},
355 {"ei", 42 UNTIC_COMMENT("exit_insert_mode")},
356 {"fs", 47 UNTIC_COMMENT("return from status line")},
357 {"im", 31 UNTIC_COMMENT("enter_insert_mode")},
358 {"k0", 65 UNTIC_COMMENT("key_f0")},
359 {"k1", 66 UNTIC_COMMENT("key_f1")},
360 {"k2", 68 UNTIC_COMMENT("key_f2")},
361 {"k3", 69 UNTIC_COMMENT("key_f3")},
362 {"k4", 70 UNTIC_COMMENT("key_f4")},
363 {"k5", 71 UNTIC_COMMENT("key_f5")},
364 {"k6", 72 UNTIC_COMMENT("key_f6")},
365 {"k7", 73 UNTIC_COMMENT("key_f7")},
366 {"k8", 74 UNTIC_COMMENT("key_f8")},
367 {"k9", 75 UNTIC_COMMENT("key_f9")},
368 {"kA", 78 UNTIC_COMMENT("key_il")},
369 {"kC", 57 UNTIC_COMMENT("key_clear")},
370 {"kD", 59 UNTIC_COMMENT("key_dc")},
371 {"kE", 63 UNTIC_COMMENT("key_eol,")},
372 {"kF", 84 UNTIC_COMMENT("key_sf")},
373 {"kH", 80 UNTIC_COMMENT("key_ll")},
374 {"kI", 77 UNTIC_COMMENT("key_ic")},
375 {"kL", 60 UNTIC_COMMENT("key_dl")},
376 {"kM", 62 UNTIC_COMMENT("key_eic,")},
377 {"kN", 81 UNTIC_COMMENT("key_npage")},
378 {"kP", 82 UNTIC_COMMENT("key_ppage")},
379 {"kR", 85 UNTIC_COMMENT("key_sr")},
380 {"kS", 64 UNTIC_COMMENT("key_eos,")},
381 {"kT", 86 UNTIC_COMMENT("key_stab")},
382 {"ka", 56 UNTIC_COMMENT("key_catab")},
383 {"k;", 67 UNTIC_COMMENT("key_f10")},
384 {"kb", 55 UNTIC_COMMENT("key_backspace")},
385 {"kd", 61 UNTIC_COMMENT("key_down")},
386 {"ke", 88 UNTIC_COMMENT("End keypad transmit mode")},
387 {"kh", 76 UNTIC_COMMENT("key_home")},
388 {"kl", 79 UNTIC_COMMENT("key_left")},
389 {"kr", 83 UNTIC_COMMENT("key_right")},
390 {"ks", 89 UNTIC_COMMENT("Start keypad transmit mode")},
391 {"kt", 58 UNTIC_COMMENT("key_ctab")},
392 {"ku", 87 UNTIC_COMMENT("key_up")},
393 {"mb", 26 UNTIC_COMMENT("enter_blink_mode")},
394 {"md", 27 UNTIC_COMMENT("enter_bold_mode")},
395 {"me", 39 UNTIC_COMMENT("exit_attribute_mode")},
396 {"mr", 34 UNTIC_COMMENT("enter_reverse_mode")},
397 {"op", 297 UNTIC_COMMENT("orig_pair (color)")},
398 {"pf", 119 UNTIC_COMMENT("turn OFF printer")},
399 {"po", 120 UNTIC_COMMENT("turn ON printer")},
400 {"se", 43 UNTIC_COMMENT("exit_standout_mode")},
401 {"so", 35 UNTIC_COMMENT("enter_standout_mode")},
402 {"sr", 130 UNTIC_COMMENT("scroll_reverse")},
403 {"te", 40 UNTIC_COMMENT("end cursor addressing")},
404 {"ti", 28 UNTIC_COMMENT("begin cursor addressing")},
405 {"ts", 135 UNTIC_COMMENT("goto to status line")},
406 {"up", 19 UNTIC_COMMENT("cursor_up")},
407 {"us", 36 UNTIC_COMMENT("enter_underline_mode")},
408 {"vb", 45 UNTIC_COMMENT("flash_screen")},
409 {"ve", 16 UNTIC_COMMENT("make cursor very visible")},
410 {"vi", 13 UNTIC_COMMENT("make cursor invisible")},
411 {"vs", 20 UNTIC_COMMENT("make cursor very visible")},
412 {"", 0 UNTIC_COMMENT(NULL)}
415 static int compute_cap_offset (char *cap, Terminfo_Type *t, Tgetstr_Map_Type *map, unsigned int max_ofs)
417 char cha, chb;
419 (void) t;
420 cha = *cap++; chb = *cap;
422 while (*map->name != 0)
424 if ((cha == *map->name) && (chb == *(map->name + 1)))
426 if (map->offset >= (int) max_ofs) return -1;
427 return map->offset;
429 map++;
431 return -1;
435 char *SLtt_tigetstr (char *cap, char **pp)
437 int offset;
438 Terminfo_Type *t;
440 if ((pp == NULL) || (NULL == (t = (Terminfo_Type *) *pp))) return NULL;
442 if (t->flags == SLTERMCAP) return tcap_getstr (cap, t);
444 offset = compute_cap_offset (cap, t, Tgetstr_Map, t->num_string_offsets);
445 if (offset < 0) return NULL;
446 offset = make_integer (t->string_offsets + 2 * offset);
447 if (offset < 0) return NULL;
448 return t->string_table + offset;
451 static Tgetstr_Map_Type Tgetnum_Map[] =
453 {"co", 0 UNTIC_COMMENT("columns")},
454 {"li", 2 UNTIC_COMMENT("lines")},
455 {"Co", 13 UNTIC_COMMENT("max colors")},
456 {"pa", 14 UNTIC_COMMENT("max pairs")},
457 {"sg", 4 UNTIC_COMMENT("magic cookie glitch")},
458 {"ws", 7 UNTIC_COMMENT("num columns in status line")},
459 {"", -1 UNTIC_COMMENT(NULL)}
462 int SLtt_tigetnum (char *cap, char **pp)
464 int offset;
465 Terminfo_Type *t;
467 if ((pp == NULL) || (NULL == (t = (Terminfo_Type *) *pp))) return -1;
469 if (t->flags == SLTERMCAP) return tcap_getnum (cap, t);
471 offset = compute_cap_offset (cap, t, Tgetnum_Map, t->num_numbers);
472 if (offset < 0) return -1;
473 return make_integer (t->numbers + 2 * offset);
476 static Tgetstr_Map_Type Tgetflag_Map[] =
478 {"am", 1 UNTIC_COMMENT("auto right margin")},
479 {"hs", 9 UNTIC_COMMENT("has status line")},
480 {"ms", 14 UNTIC_COMMENT("move standout mode")},
481 {"xs", 3 UNTIC_COMMENT("ceol standout glitch")},
482 {"xn", 4 UNTIC_COMMENT("NEWLINE ignored after 80 columns")},
483 {"es", 16 UNTIC_COMMENT("status line esc ok")},
484 {"", -1 UNTIC_COMMENT(NULL)}
487 int SLtt_tigetflag (char *cap, char **pp)
489 int offset;
490 Terminfo_Type *t;
492 if ((pp == NULL) || (NULL == (t = (Terminfo_Type *) *pp))) return -1;
494 if (t->flags == SLTERMCAP) return tcap_getflag (cap, t);
496 offset = compute_cap_offset (cap, t, Tgetflag_Map, t->boolean_section_size);
498 if (offset < 0) return -1;
499 return (int) *(t->boolean_flags + offset);
504 /* These are my termcap routines. They only work with the TERMCAP environment
505 * variable. This variable must contain the termcap entry and NOT the file.
508 static int tcap_getflag (char *cap, Terminfo_Type *t)
510 char a, b;
511 char *f = (char *) t->boolean_flags;
512 char *fmax;
514 if (f == NULL) return 0;
515 fmax = f + t->boolean_section_size;
517 a = *cap;
518 b = *(cap + 1);
519 while (f < fmax)
521 if ((a == f[0]) && (b == f[1]))
522 return 1;
523 f += 2;
525 return 0;
528 static char *tcap_get_cap (unsigned char *cap, unsigned char *caps, unsigned int len)
530 unsigned char c0, c1;
531 unsigned char *caps_max;
533 c0 = cap[0];
534 c1 = cap[1];
536 if (caps == NULL) return NULL;
537 caps_max = caps + len;
538 while (caps < caps_max)
540 if ((c0 == caps[0]) && (c1 == caps[1]))
542 return (char *) caps + 3;
544 caps += (int) caps[2];
546 return NULL;
550 static int tcap_getnum (char *cap, Terminfo_Type *t)
552 cap = tcap_get_cap ((unsigned char *) cap, t->numbers, t->num_numbers);
553 if (cap == NULL) return -1;
554 return atoi (cap);
557 static char *tcap_getstr (char *cap, Terminfo_Type *t)
559 return tcap_get_cap ((unsigned char *) cap, (unsigned char *) t->string_table, t->string_table_size);
562 static int tcap_extract_field (unsigned char *t0)
564 register unsigned char ch, *t = t0;
565 while (((ch = *t) != 0) && (ch != ':')) t++;
566 if (ch == ':') return (int) (t - t0);
567 return -1;
570 int SLtt_Try_Termcap = 1;
571 static int tcap_getent (char *term, Terminfo_Type *ti)
573 unsigned char *termcap, ch;
574 unsigned char *buf, *b;
575 unsigned char *t;
576 int len;
578 if (SLtt_Try_Termcap == 0) return -1;
579 #if 1
580 /* XFREE86 xterm sets the TERMCAP environment variable to an invalid
581 * value. Specifically, it lacks the tc= string.
583 if (!strncmp (term, "xterm", 5))
584 return -1;
585 #endif
586 termcap = (unsigned char *) getenv ("TERMCAP");
587 if ((termcap == NULL) || (*termcap == '/')) return -1;
589 /* We have a termcap so lets use it provided it does not have a reference
590 * to another terminal via tc=. In that case, user terminfo. The alternative
591 * would be to parse the termcap file which I do not want to do right now.
592 * Besides, this is a terminfo based system and if the termcap were parsed
593 * terminfo would almost never get a chance to run. In addition, the tc=
594 * thing should not occur if tset is used to set the termcap entry.
596 t = termcap;
597 while ((len = tcap_extract_field (t)) != -1)
599 if ((len > 3) && (t[0] == 't') && (t[1] == 'c') && (t[2] == '='))
600 return -1;
601 t += (len + 1);
604 /* malloc some extra space just in case it is needed. */
605 len = strlen ((char *) termcap) + 256;
606 if (NULL == (buf = (unsigned char *) SLMALLOC ((unsigned int) len))) return -1;
608 b = buf;
610 /* The beginning of the termcap entry contains the names of the entry.
611 * It is terminated by a colon.
614 ti->terminal_names = (char *) b;
615 t = termcap;
616 len = tcap_extract_field (t);
617 if (len < 0)
619 SLFREE (buf);
620 return -1;
622 strncpy ((char *) b, (char *) t, (unsigned int) len);
623 b[len] = 0;
624 b += len + 1;
625 ti->name_section_size = len;
628 /* Now, we are really at the start of the termcap entries. Point the
629 * termcap variable here since we want to refer to this a number of times.
631 termcap = t + (len + 1);
634 /* Process strings first. */
635 ti->string_table = (char *) b;
636 t = termcap;
637 while (-1 != (len = tcap_extract_field (t)))
639 unsigned char *b1;
640 unsigned char *tmax;
642 /* We are looking for: XX=something */
643 if ((len < 4) || (t[2] != '=') || (*t == '.'))
645 t += len + 1;
646 continue;
648 tmax = t + len;
649 b1 = b;
651 while (t < tmax)
653 ch = *t++;
654 if ((ch == '\\') && (t < tmax))
656 t = (unsigned char *) SLexpand_escaped_char ((char *) t, (char *) &ch);
658 else if ((ch == '^') && (t < tmax))
660 ch = *t++;
661 if (ch == '?') ch = 127;
662 else ch = (ch | 0x20) - ('a' - 1);
664 *b++ = ch;
666 /* Null terminate it. */
667 *b++ = 0;
668 len = (int) (b - b1);
669 b1[2] = (unsigned char) len; /* replace the = by the length */
670 /* skip colon to next field. */
671 t++;
673 ti->string_table_size = (int) (b - (unsigned char *) ti->string_table);
675 /* Now process the numbers. */
677 t = termcap;
678 ti->numbers = b;
679 while (-1 != (len = tcap_extract_field (t)))
681 unsigned char *b1;
682 unsigned char *tmax;
684 /* We are looking for: XX#NUMBER */
685 if ((len < 4) || (t[2] != '#') || (*t == '.'))
687 t += len + 1;
688 continue;
690 tmax = t + len;
691 b1 = b;
693 while (t < tmax)
695 *b++ = *t++;
697 /* Null terminate it. */
698 *b++ = 0;
699 len = (int) (b - b1);
700 b1[2] = (unsigned char) len; /* replace the # by the length */
701 t++;
703 ti->num_numbers = (int) (b - ti->numbers);
705 /* Now process the flags. */
706 t = termcap;
707 ti->boolean_flags = b;
708 while (-1 != (len = tcap_extract_field (t)))
710 /* We are looking for: XX#NUMBER */
711 if ((len != 2) || (*t == '.') || (*t <= ' '))
713 t += len + 1;
714 continue;
716 b[0] = t[0];
717 b[1] = t[1];
718 t += 3;
719 b += 2;
721 ti->boolean_section_size = (int) (b - ti->boolean_flags);
722 ti->flags = SLTERMCAP;
723 return 0;
726 #else /* USE_SETUPTERM */
728 /* Ching Hui fixes so that it will work on AIX and OSF/1 */
729 #include <curses.h>
730 #include <term.h>
732 int SLtt_Try_Termcap = 1;
734 char *SLtt_tigetent (char *term)
736 int rc;
738 setupterm(term, 1, &rc);
739 if (rc != 1)
740 return NULL;
741 return (char *)cur_term;
744 #define MATCH_CHAR(c, variable) \
745 do { \
746 if (*(cap + 1) == c) \
747 return variable; \
748 } while (0)
750 char *SLtt_tigetstr (char *cap, char **pp)
752 if ((pp == NULL) || ((cur_term = (struct term *) *pp) == NULL))
753 return NULL;
755 switch(*cap) {
756 case '@':
757 MATCH_CHAR('7', key_end);
758 break;
759 case 'A':
760 MATCH_CHAR('A', parm_insert_line);
761 break;
762 case 'D':
763 MATCH_CHAR('L', parm_delete_line);
764 break;
765 case 'R':
766 MATCH_CHAR('I', parm_right_cursor);
767 break;
768 case 'a':
769 #ifdef acs_chars
770 MATCH_CHAR('c', acs_chars);
771 #elif defined (box_chars_1)
772 MATCH_CHAR('c', box_chars_1); /* AIX hack */
773 #else
774 MATCH_CHAR('c', NULL);
775 #endif
776 MATCH_CHAR('e', exit_alt_charset_mode);
777 MATCH_CHAR('s', enter_alt_charset_mode);
778 break;
779 case 'c':
780 MATCH_CHAR('e', clr_eol);
781 MATCH_CHAR('l', clear_screen);
782 MATCH_CHAR('m', cursor_address);
783 MATCH_CHAR('s', change_scroll_region);
784 break;
785 case 'd':
786 MATCH_CHAR('c', delete_character);
787 break;
788 case 'e':
789 MATCH_CHAR('i', exit_insert_mode);
790 #ifdef ena_acs
791 MATCH_CHAR('A', ena_acs); /* aix hack */
792 #else
793 MATCH_CHAR('A', NULL);
794 #endif
795 break;
796 case 'i':
797 MATCH_CHAR('m', enter_insert_mode);
798 break;
799 case 'k':
800 MATCH_CHAR('0', key_f0);
801 MATCH_CHAR('1', key_f1);
802 MATCH_CHAR('1', key_f1);
803 MATCH_CHAR('2', key_f2);
804 MATCH_CHAR('3', key_f3);
805 MATCH_CHAR('4', key_f4);
806 MATCH_CHAR('5', key_f5);
807 MATCH_CHAR('6', key_f6);
808 MATCH_CHAR('7', key_f7);
809 MATCH_CHAR('8', key_f8);
810 MATCH_CHAR('9', key_f9);
811 MATCH_CHAR('A', key_il);
812 MATCH_CHAR('C', key_clear);
813 MATCH_CHAR('D', key_dc);
814 MATCH_CHAR('E', key_eol);
815 MATCH_CHAR('F', key_sf);
816 MATCH_CHAR('H', key_ll);
817 MATCH_CHAR('I', key_ic);
818 MATCH_CHAR('L', key_dl);
819 MATCH_CHAR('M', key_eic);
820 MATCH_CHAR('N', key_npage);
821 MATCH_CHAR('P', key_ppage);
822 MATCH_CHAR('R', key_sr);
823 MATCH_CHAR('S', key_eos);
824 MATCH_CHAR('T', key_stab);
825 MATCH_CHAR('a', key_catab);
826 MATCH_CHAR(';', key_f10);
827 MATCH_CHAR('b', key_backspace);
828 MATCH_CHAR('d', key_down);
829 MATCH_CHAR('e', keypad_local);
830 MATCH_CHAR('h', key_home);
831 MATCH_CHAR('l', key_left);
832 MATCH_CHAR('r', key_right);
833 MATCH_CHAR('s', keypad_xmit);
834 MATCH_CHAR('t', key_ctab);
835 MATCH_CHAR('u', key_up);
836 break;
837 case 'm':
838 MATCH_CHAR('b', enter_blink_mode);
839 MATCH_CHAR('d', enter_bold_mode);
840 MATCH_CHAR('e', exit_attribute_mode);
841 MATCH_CHAR('r', enter_reverse_mode);
842 break;
843 case 's':
844 MATCH_CHAR('e', exit_standout_mode);
845 MATCH_CHAR('o', enter_standout_mode);
846 MATCH_CHAR('r', scroll_reverse);
847 break;
848 case 't':
849 MATCH_CHAR('e', exit_ca_mode);
850 MATCH_CHAR('i', enter_ca_mode);
851 break;
852 case 'u':
853 MATCH_CHAR('p', cursor_up);
854 MATCH_CHAR('s', enter_underline_mode);
855 break;
856 case 'v':
857 MATCH_CHAR('b', flash_screen);
858 MATCH_CHAR('i', cursor_invisible);
859 MATCH_CHAR('s', cursor_visible);
860 break;
861 case 'F':
862 MATCH_CHAR('1', key_f11);
863 MATCH_CHAR('2', key_f12);
864 MATCH_CHAR('3', key_f13);
865 MATCH_CHAR('4', key_f14);
866 MATCH_CHAR('5', key_f15);
867 MATCH_CHAR('6', key_f16);
868 MATCH_CHAR('7', key_f17);
869 MATCH_CHAR('8', key_f18);
870 MATCH_CHAR('9', key_f19);
871 MATCH_CHAR('A', key_f20);
872 break;
873 #ifdef orig_pair
874 case 'o':
875 MATCH_CHAR('p', orig_pair);
876 break;
877 #endif
879 return NULL;
882 int SLtt_tigetnum (char *cap, char **pp)
884 if ((pp == NULL) || ((cur_term = (struct term *) *pp) == NULL))
885 return (int) NULL;
886 switch(*cap) {
887 case 'c':
888 MATCH_CHAR('o', columns);
889 break;
890 case 'l':
891 MATCH_CHAR('i', lines);
892 break;
894 return -1;
897 int SLtt_tigetflag (char *cap, char **pp)
899 if ((pp == NULL) || ((cur_term = (struct term *) *pp) == NULL))
900 return (int) NULL;
901 switch(*cap) {
902 case 'a':
903 MATCH_CHAR('m', auto_right_margin);
904 break;
905 case 'm':
906 MATCH_CHAR('s', move_standout_mode);
907 break;
908 case 'x':
909 MATCH_CHAR('s', ceol_standout_glitch);
910 break;
911 case 's':
912 MATCH_CHAR('g', magic_cookie_glitch);
913 break;
915 return -1;
918 #endif /* !USE_SETUPTERM */