home *** CD-ROM | disk | FTP | other *** search
- /* tty.c -- the tty management file. This includes termcap / terminfo
- initialization, colors, keys and functions to switch terminals
- between canonical and noncanonical modes. */
-
- /* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Written by Tudor Hulubei and Andrei Pitis. */
-
-
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
-
- #include <stdio.h>
-
- #ifdef HAVE_STDLIB_H
- #include <stdlib.h>
- #else /* !HAVE_STDLIB_H */
- #include "ansi_stdlib.h"
- #endif /* !HAVE_STDLIB_H */
-
- #include <sys/types.h>
- #include <ctype.h>
- #include "file.h"
- #include <fcntl.h>
- #include <sys/ioctl.h>
-
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif /* HAVE_UNISTD_H */
-
- #include "stdc.h"
- #include "xstring.h"
- #include "xmalloc.h"
- #include "xtimer.h"
- #include "xio.h"
- #include "tty.h"
- #include "misc.h"
-
-
- /* We want to avoid including curses.h or any other header file that defines
- these. It's safer because I couldn't find 2 similar curses.h files in the
- entire world... */
-
- int tgetent __P((void *__buffer, const char *__termtype));
- int tputs __P((const char *__string, int __nlines, int (*outfun)()));
- char *tgetstr __P((const char *__name, char **__area));
- char *tgoto __P((const char *__cstring, int __hpos, int __vpos));
-
-
- #define TTY_INPUT 0
- #define TTY_OUTPUT 1
-
-
- /* If tty_kbdmode == 1, single characters are inserted in the linked list.
- This feature is used by gitps (it has no command line). */
- static int tty_kbdmode = 0;
-
- #ifdef HAVE_POSIXTTY
- static struct termios old_term;
- static struct termios new_term;
- #else
- #ifdef HAVE_SYSTEMVTTY
- static struct termio old_term;
- static struct termio new_term;
- #else
- static struct sgttyb old_arg;
- static struct tchars old_targ;
- static struct ltchars old_ltarg;
- static struct sgttyb new_arg;
- static struct tchars new_targ;
- static struct ltchars new_ltarg;
-
- /* NextStep doesn't define TILDE. */
- #ifndef TILDE
- #define TILDE 0
- #endif
-
- #endif /* HAVE_SYSTEMVTTY */
- #endif /* HAVE_POSIXTTY */
-
-
- #ifdef HAVE_LINUX
- static int vcs_read_ok;
- #endif /* HAVE_LINUX */
-
- static int tty_cursor_x;
- static int tty_cursor_y;
- static int rows, columns;
- static int tty_cursormove_notified;
- static int fg_color, bg_color, br_status, rv_status, cursor_status;
-
- static unsigned char tty_current_attribute;
-
- /* tty_screen will always contain a copy of the screen, while tty_attributes
- will be used to keep track of screen attributes. */
- static unsigned char *tty_screen = NULL;
- static unsigned char *tty_attributes = NULL;
-
-
- /* The ANSI color sequences are hard coded here because I figured out that
- the Linux console, the Linux color_xterm and the Ultrix xterm use them.
- If you find a terminal (or terminal emulator) that use different color
- sequences, please mail me (tudor@chang.pub.ro) and I'll try to fix this
- Meanwhile, you're out of luck... */
- static char ansi_foreground[] = { 0x1b, '[', '3', '0', 'm' };
- static char ansi_background[] = { 0x1b, '[', '4', '0', 'm' };
-
- #ifdef HAVE_LINUX
- /* Linux also has these... */
- static char lc_attr_off[] = { 0x1b, '[', 'm' };
- static char lc_defaults[] = { 0x1b, '[', '0', 'm' };
- #endif /* HAVE_LINUX */
-
-
- /* These variable tells us if we should use standard ANSI color sequences.
- Its value is taken from the configuration file. */
- extern int AnsiColorSequences;
-
-
- #ifdef HAVE_LINUX
- /* These variable tells us if we are using a Linux console. */
- int LinuxConsole;
- #endif /* HAVE_LINUX */
-
-
- /* Structures for keys management. */
- tty_key_t *key_list_head = NULL;
- tty_key_t *current_key;
- tty_key_t default_key;
-
- static char tty_buf[MAX_CAPABILITY_LEN];
- static unsigned int tty_index = 0;
-
- static char term_buf[2048];
- static char vt100[] = "vt100";
-
- /* The terminal mode. TTY_CANONIC at the begining. */
- int tty_mode = TTY_CANONIC;
-
- /* The curses-like optimization level. See the tty_write() comment. */
- int tty_optimization_level = 0;
-
- char *tty_type;
-
- char PC; /* for tputs */
- char *BC; /* for tgoto */
- char *UP;
-
- #ifdef HAVE_LINUX
- speed_t ospeed;
- #else /* !HAVE_LINUX */
- short ospeed;
- #endif /* !HAVE_LINUX */
-
-
- /* A structure describing some attributes we need to know about each
- capability. See below for greater detail. */
- typedef struct
- {
- char *capability;
- char *name;
- int indispensable;
- char *symbol;
- } TTY_CAPABILITY;
-
-
- #define TTY_USED_CAPABILITIES 31
- #define TTY_FIRST_SYMBOL_KEY 10
-
- static TTY_CAPABILITY tty_capability[TTY_USED_CAPABILITIES] =
- {
- { NULL, "me", 0, NULL }, /* turn off all attributes */
- { NULL, "mr", 0, NULL }, /* turn on reverse video mode */
- { NULL, "md", 0, NULL }, /* turn on bold */
- { NULL, "vi", 0, NULL }, /* make the cursor invisible */
- { NULL, "ve", 0, NULL }, /* make the cursor appear normal */
- { NULL, "cl", 1, NULL }, /* clear screen and home the cursor */
- { NULL, "cm", 1, NULL }, /* move the cursor */
- { NULL, "pc", 0, NULL }, /* padding character */
- { NULL, "up", 0, NULL }, /* up one line */
- { NULL, "le", 0, NULL }, /* move left one space */
- { NULL, "ku", 0, "UP" }, /* (UP) */
- { NULL, "kd", 0, "DOWN" }, /* (DOWN) */
- { NULL, "kr", 0, "RIGHT" }, /* (RIGHT) */
- { NULL, "kl", 0, "LEFT" }, /* (LEFT) */
- { NULL, "kI", 0, "INS" }, /* (INS) */
- { NULL, "kD", 0, "DEL" }, /* (DEL) */
- { NULL, "kh", 0, "HOME" }, /* (HOME) */
- { NULL, "kH", 0, "END" }, /* (END) */
- { NULL, "kP", 0, "PGUP" }, /* (PGUP) */
- { NULL, "kN", 0, "PGDOWN" }, /* (PGDOWN) */
- { NULL, "k0", 0, "F0" }, /* (F0) */
- { NULL, "k1", 0, "F1" }, /* (F1) */
- { NULL, "k2", 0, "F2" }, /* (F2) */
- { NULL, "k3", 0, "F3" }, /* (F3) */
- { NULL, "k4", 0, "F4" }, /* (F4) */
- { NULL, "k5", 0, "F5" }, /* (F5) */
- { NULL, "k6", 0, "F6" }, /* (F6) */
- { NULL, "k7", 0, "F7" }, /* (F7) */
- { NULL, "k8", 0, "F8" }, /* (F8) */
- { NULL, "k9", 0, "F9" }, /* (F9) */
- { NULL, "k;", 0, "F10" }, /* (F10) */
- };
-
-
- /* Some nice aliases... */
- #define TTY_ATTRIBUTES_OFF (tty_capability[0].capability)
- #define TTY_REVERSE_ON (tty_capability[1].capability)
- #define TTY_BRIGHT_ON (tty_capability[2].capability)
- #define TTY_CURSOR_OFF (tty_capability[3].capability)
- #define TTY_CURSOR_ON (tty_capability[4].capability)
- #define TTY_CLEAR_SCREEN (tty_capability[5].capability)
- #define TTY_CURSOR_MOVE (tty_capability[6].capability)
- #define TTY_PAD_CHAR (tty_capability[7].capability)
- #define TTY_UP_ONE_LINE (tty_capability[8].capability)
- #define TTY_LEFT_ONE_SPACE (tty_capability[9].capability)
-
-
- /* Some more nice aliases. */
- #define TTY_ATTRIBUTES_OFF_NAME (tty_capability[0].name)
- #define TTY_REVERSE_ON_NAME (tty_capability[1].name)
- #define TTY_BRIGHT_ON_NAME (tty_capability[2].name)
- #define TTY_CURSOR_OFF_NAME (tty_capability[3].name)
- #define TTY_CURSOR_ON_NAME (tty_capability[4].name)
- #define TTY_CLEAR_SCREEN_NAME (tty_capability[5].name)
- #define TTY_CURSOR_MOVE_NAME (tty_capability[6].name)
- #define TTY_PAD_CHAR_NAME (tty_capability[7].name)
- #define TTY_UP_ONE_LINE_NAME (tty_capability[8].name)
- #define TTY_LEFT_ONE_SPACE_NAME (tty_capability[9].name)
-
-
- #ifdef HAVE_LIBTERMCAP
-
- static char term_database[] = "termcap";
- static char term_env[] = "TERMCAP";
-
- #else /* !HAVE_LIBTERMCAP */
-
- static char term_database[] = "terminfo";
- static char term_env[] = "TERMINFO";
-
- #endif /* !HAVE_LIBTERMCAP */
-
-
- void fatal __P((char *));
-
-
- /* ANSI colors. OFF & ON are here because we need them when we read the
- configuration file. Don't bother... */
- static char *colors[10] =
- {
- "BLACK",
- "RED",
- "GREEN",
- "YELLOW",
- "BLUE",
- "MAGENTA",
- "CYAN",
- "WHITE",
- "OFF",
- "ON"
- };
-
-
- /* I don't know any method to find out the current terminal colors. This is
- why we need to specify the colors to be restored at exit. We can't always
- use a white/black default because the xterm terminal emulator use reverse
- video as a default (black/white). */
- static int ForegroundAtExit; /* foreground to be restored at exit. */
- static int BackgroundAtExit; /* background to be restored at exit. */
-
-
- /* Control keys description. C-a, C-b, C-c and so on... */
- unsigned char key_ctrl_table[0x5f] =
- {
- 0x20, /* 0x20 ( ) */
- 0x21, /* 0x21 (!) */
- 0x22, /* 0x22 (") */
- 0x23, /* 0x23 (#) */
- 0xff, /* 0x24 ($) */
- 0x25, /* 0x25 (%) */
- 0x26, /* 0x26 (&) */
- 0x07, /* 0x27 (') */
- 0x28, /* 0x28 (() */
- 0x29, /* 0x29 ()) */
- 0x2a, /* 0x2a (*) */
- 0x2b, /* 0x2b (+) */
- 0x2c, /* 0x2c (,) */
- 0x2d, /* 0x2d (-) */
- 0x2e, /* 0x2e (.) */
- 0x2f, /* 0x2f (/) */
- 0x20, /* 0x30 (0) */
- 0x20, /* 0x31 (1) */
- 0xff, /* 0x32 (2) */
- 0x1b, /* 0x33 (3) */
- 0x1c, /* 0x34 (4) */
- 0x1d, /* 0x35 (5) */
- 0x1e, /* 0x36 (6) */
- 0x1f, /* 0x37 (7) */
- 0x7f, /* 0x38 (8) */
- 0x39, /* 0x39 (9) */
- 0x3a, /* 0x3a (:) */
- 0x3b, /* 0x3b (;) */
- 0x3c, /* 0x3c (<) */
- 0x20, /* 0x3d (=) */
- 0x3e, /* 0x3e (>) */
- 0x20, /* 0x3f (?) */
- 0x20, /* 0x40 (@) */
- 0x01, /* 0x41 (A) */
- 0x02, /* 0x42 (B) */
- 0x03, /* 0x43 (C) */
- 0x04, /* 0x44 (D) */
- 0x05, /* 0x45 (E) */
- 0x06, /* 0x46 (F) */
- 0x07, /* 0x47 (G) */
- 0x08, /* 0x48 (H) */
- 0x09, /* 0x49 (I) */
- 0x0a, /* 0x4a (J) */
- 0x0b, /* 0x4b (K) */
- 0x0c, /* 0x4c (L) */
- 0x0d, /* 0x4d (M) */
- 0x0e, /* 0x4e (N) */
- 0x0f, /* 0x4f (O) */
- 0x10, /* 0x50 (P) */
- 0x11, /* 0x51 (Q) */
- 0x12, /* 0x52 (R) */
- 0x13, /* 0x53 (S) */
- 0x14, /* 0x54 (T) */
- 0x15, /* 0x55 (U) */
- 0x16, /* 0x56 (V) */
- 0x17, /* 0x57 (W) */
- 0x18, /* 0x58 (X) */
- 0x19, /* 0x59 (Y) */
- 0x1a, /* 0x5a (Z) */
- 0x1b, /* 0x5b ([) */
- 0x1c, /* 0x5c (\) */
- 0x1d, /* 0x5d (]) */
- 0x5e, /* 0x5e (^) */
- 0x7f, /* 0x5f (_) */
- 0x20, /* 0x60 (`) */
- 0x01, /* 0x61 (a) */
- 0x02, /* 0x62 (b) */
- 0x03, /* 0x63 (c) */
- 0x04, /* 0x64 (d) */
- 0x05, /* 0x65 (e) */
- 0x06, /* 0x66 (f) */
- 0x07, /* 0x67 (g) */
- 0x08, /* 0x68 (h) */
- 0x09, /* 0x69 (i) */
- 0x0a, /* 0x6a (j) */
- 0x0b, /* 0x6b (k) */
- 0x0c, /* 0x6c (l) */
- 0x0d, /* 0x6d (m) */
- 0x0e, /* 0x6e (n) */
- 0x0f, /* 0x6f (o) */
- 0x10, /* 0x70 (p) */
- 0x11, /* 0x71 (q) */
- 0x12, /* 0x72 (r) */
- 0x13, /* 0x73 (s) */
- 0x14, /* 0x74 (t) */
- 0x15, /* 0x75 (u) */
- 0x16, /* 0x76 (v) */
- 0x17, /* 0x77 (w) */
- 0x18, /* 0x78 (x) */
- 0x19, /* 0x79 (y) */
- 0x1a, /* 0x7a (z) */
- 0x20, /* 0x7b ({) */
- 0x20, /* 0x7c (|) */
- 0x20, /* 0x7d (}) */
- 0x20, /* 0x7e (~) */
- };
-
-
- #define NO 0
- #define YES 1
-
- #define MAX_KEY_LENGTH 15
-
-
- #define LINUX_VC_MAJOR 4
-
- static int keyno = 0;
- static int keyindex = 0;
- static char keybuf[1024];
-
-
- /* Hooks that get called when we are going idle and when we stop
- being idle. */
- void (* tty_enter_idle_hook)() = NULL;
- void (* tty_exit_idle_hook)() = NULL;
-
-
- void
- tty_startup()
- {
- /* Fail if stdin or stdout are not real terminals. */
- if (!isatty(TTY_INPUT) || !isatty(TTY_OUTPUT))
- fatal("only standard error can be redirected");
-
- /* Get calloc-ed memory for tty_screen & tty_attributes. */
- tty_screen = (unsigned char *)xcalloc(columns * rows,
- sizeof(unsigned char));
- tty_attributes = (unsigned char *)xcalloc(columns * rows,
- sizeof(unsigned char));
-
- tty_current_attribute = 0;
-
- /* Store the terminal settings in old_term. it will be used to restore
- them later. */
- #ifdef HAVE_POSIXTTY
- tcgetattr(TTY_OUTPUT, &old_term);
- #else
- #ifdef HAVE_SYSTEMVTTY
- ioctl(TTY_OUTPUT, TCGETA, &old_term);
- #else
- ioctl(TTY_OUTPUT, TIOCGETP, &old_arg);
- ioctl(TTY_OUTPUT, TIOCGETC, &old_targ);
- ioctl(TTY_OUTPUT, TIOCGLTC, &old_ltarg);
- #endif /* HAVE_SYSTEMVTTY */
- #endif /* HAVE_POSIXTTY */
- }
-
-
- /* Initialize some keybord stuff. */
-
- void
- tty_kbdinit(kbd_mode)
- int kbd_mode;
- {
- default_key.key_seq = (unsigned char *)xmalloc(16);
- default_key.aux_data = NULL;
- default_key.next = NULL;
- tty_kbdmode = kbd_mode;
- }
-
-
- /* This function is used to switch between canonical and noncanonical
- terminal modes. */
-
- void
- tty_set_mode(mode)
- int mode;
- {
- if (mode == TTY_NONCANONIC)
- {
- #ifdef HAVE_POSIXTTY
- new_term = old_term;
- new_term.c_iflag &= ~(ICRNL | IGNCR | INLCR | IGNBRK | BRKINT);
- new_term.c_oflag &= ~OPOST;
- new_term.c_lflag |= ISIG | NOFLSH;
- new_term.c_lflag &= ~(ICANON | ECHO);
-
- /* I think we will always have these: */
-
- new_term.c_cc[VINTR] = key_INTERRUPT; /* Ctrl-G */
- new_term.c_cc[VQUIT] = key_INTERRUPT; /* Ctrl-G */
- new_term.c_cc[VSTART] = _POSIX_VDISABLE; /* START (^Q) */
- new_term.c_cc[VSTOP] = _POSIX_VDISABLE; /* STOP (^S) */
- new_term.c_cc[VMIN] = 1;
- new_term.c_cc[VTIME] = 0;
-
- /* ... but not always these: (in fact I am not sure if I really
- need to overwrite all these, but just in case... */
-
- #ifdef VERASE
- new_term.c_cc[VERASE] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VKILL
- new_term.c_cc[VKILL] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VEOL
- new_term.c_cc[VEOL] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VEOL2
- new_term.c_cc[VEOL2] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VSWTCH
- new_term.c_cc[VSWTCH] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VSUSP
- new_term.c_cc[VSUSP] = key_SUSPEND; /* Ctrl-Z */
- #endif
-
- #ifdef VDSUSP
- new_term.c_cc[VDSUSP] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VREPRINT
- new_term.c_cc[VREPRINT] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VDISCARD
- new_term.c_cc[VDISCARD] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VWERASE
- new_term.c_cc[VWERASE] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VLNEXT
- new_term.c_cc[VLNEXT] = _POSIX_VDISABLE;
- #endif
-
- tcsetattr(TTY_OUTPUT, TCSADRAIN, &new_term);
- ospeed = cfgetospeed(&new_term);
- #else
- #ifdef HAVE_SYSTEMVTTY
- new_term = old_term;
- new_term.c_iflag &= ~(ICRNL | IGNCR | INLCR);
- new_term.c_oflag = 0;
- new_term.c_lflag = 0;
-
- /* I think we will always have these: */
-
- new_term.c_cc[VINTR] = key_INTERRUPT; /* Ctrl-G */
- new_term.c_cc[VQUIT] = key_INTERRUPT; /* Ctrl-G */
- new_term.c_cc[VSTART] = -1; /* START (^Q) */
- new_term.c_cc[VSTOP] = -1; /* STOP (^S) */
- new_term.c_cc[VMIN] = 1;
- new_term.c_cc[VTIME] = 0;
-
- /* ... but not always these: (in fact I am not sure if I really
- need to overwrite all these, but just in case... */
-
- #ifdef VERASE
- new_term.c_cc[VERASE] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VKILL
- new_term.c_cc[VKILL] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VEOL
- new_term.c_cc[VEOL] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VEOL2
- new_term.c_cc[VEOL2] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VSWTCH
- new_term.c_cc[VSWTCH] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VSUSP
- new_term.c_cc[VSUSP] = key_SUSPEND; /* Ctrl-Z */
- #endif
-
- #ifdef VDSUSP
- new_term.c_cc[VDSUSP] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VREPRINT
- new_term.c_cc[VREPRINT] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VDISCARD
- new_term.c_cc[VDISCARD] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VWERASE
- new_term.c_cc[VWERASE] = _POSIX_VDISABLE;
- #endif
-
- #ifdef VLNEXT
- new_term.c_cc[VLNEXT] = _POSIX_VDISABLE;
- #endif
-
- ioctl(TTY_OUTPUT, TCSETAW, &new_term);
- ospeed = new_term.c_cflag & CBAUD;
- #else
- new_arg = old_arg;
- new_targ = old_targ;
- new_ltarg = old_ltarg;
- new_arg.sg_flags = ((old_arg.sg_flags &
- ~(ECHO | CRMOD | XTABS | ALLDELAY | TILDE)) | CBREAK);
- new_targ.t_intrc = key_INTERRUPT; /* Ctrl-G */
- new_targ.t_quitc = key_INTERRUPT; /* Ctrl-G */
- new_targ.t_eofc = _POSIX_VDISABLE;
- new_targ.t_brkc = _POSIX_VDISABLE;
- new_ltarg.t_lnextc = _POSIX_VDISABLE;
- new_ltarg.t_flushc = _POSIX_VDISABLE;
- new_ltarg.t_werasc = _POSIX_VDISABLE;
- new_ltarg.t_rprntc = _POSIX_VDISABLE;
- new_ltarg.t_dsuspc = _POSIX_VDISABLE; /* DSUSPC (delayed SUSPC,^Y) */
- new_ltarg.t_suspc = key_SUSPEND;
-
- ioctl(TTY_OUTPUT, TIOCSETN, &new_arg);
- ioctl(TTY_OUTPUT, TIOCSETC, &new_targ);
- ioctl(TTY_OUTPUT, TIOCSLTC, &new_ltarg);
- ospeed = new_arg.sg_ospeed;
- #endif /* HAVE_SYSTEMVTTY */
- #endif /* HAVE_POSIXTTY */
- }
- else
- #ifdef HAVE_POSIXTTY
- tcsetattr(TTY_OUTPUT, TCSADRAIN, &old_term);
- #else
- #ifdef HAVE_SYSTEMVTTY
- ioctl(TTY_OUTPUT, TCSETAW, &old_term);
- #else
- ioctl(TTY_OUTPUT, TIOCSETN, &old_arg);
- ioctl(TTY_OUTPUT, TIOCSETC, &old_targ);
- ioctl(TTY_OUTPUT, TIOCSLTC, &old_ltarg);
- #endif /* HAVE_SYSTEMVTTY */
- #endif /* HAVE_POSIXTTY */
-
- tty_mode = mode;
- tty_defaults();
- }
-
-
- /* Set the interrupt character. */
-
- void
- tty_set_interrupt_char(c)
- unsigned char c;
- {
- #ifdef HAVE_POSIXTTY
- struct termios current_term;
-
- tcgetattr(TTY_OUTPUT, ¤t_term);
- current_term.c_cc[VINTR] = c;
- current_term.c_cc[VQUIT] = c;
- tcsetattr(TTY_OUTPUT, TCSADRAIN, ¤t_term);
- #else
- #ifdef HAVE_SYSTEMVTTY
- struct termio current_term;
-
- ioctl(TTY_OUTPUT, TCGETA, ¤t_term);
- current_term.c_cc[VINTR] = c;
- current_term.c_cc[VQUIT] = c;
- ioctl(TTY_OUTPUT, TCSETAW, ¤t_term);
- #else
- struct tchars current_targ;
-
- ioctl(TTY_OUTPUT, TIOCGETC, ¤t_targ);
- current_targ.t_intrc = c;
- current_targ.t_quitc = c;
- ioctl(TTY_OUTPUT, TIOCSETC, ¤t_targ);
- #endif /* HAVE_SYSTEMVTTY */
- #endif /* HAVE_POSIXTTY */
- }
-
-
- /* This function is called to restore the canonic mode at exit. */
-
- void
- tty_exit()
- {
- if (tty_mode == TTY_NONCANONIC)
- {
- tty_set_mode(TTY_CANONIC);
- tty_clear();
- }
- else
- tty_defaults();
- }
-
-
- /* Converts a key sequence from the human readable, '^' based form into a
- computer usable form. */
-
- char *
- tty_key_convert(key_seq)
- unsigned char *key_seq;
- {
- unsigned char *first;
- unsigned char *second;
-
-
- first = second = key_seq;
-
- if (tty_kbdmode == 0 && *key_seq != '^')
- return NULL;
-
- while (*second)
- {
- if (*second == '^')
- {
- if (*++second)
- *first++ = key_ctrl_table[(*second++ & 0x7F) - ' '];
- else
- return NULL;
- }
- else
- *first++ = *second++;
- }
-
- *first = 0;
- return (char *)key_seq;
- }
-
-
- /* Set the curses-like optimization level. Returns the previous level.
- See the tty_write comment for more detail. */
-
- int
- tty_set_optimization_level(level)
- int level;
- {
- int old_tty_optimization_level = tty_optimization_level;
-
- tty_optimization_level = level;
-
- return old_tty_optimization_level;
- }
-
-
- /* Used by tputs() to output characters. Actually we are only storing them in
- a buffer (tty_buf[]) flushing them later with tty_flush(). */
-
- int
- tty_out_char(c)
- int c;
- {
- return tty_buf[tty_index++] = (char)c;
- }
-
-
- /* Flush the tty_buf buffer. */
-
- void
- tty_flush()
- {
- xwrite(TTY_OUTPUT, tty_buf, tty_index);
- tty_index = 0;
- }
-
-
- /* Clear the screen using the current color attributes. */
-
- void
- tty_clear()
- {
- memset(tty_screen, ' ', rows * columns * sizeof(unsigned char));
- memset(tty_attributes, tty_current_attribute,
- rows * columns * sizeof(unsigned char));
- tputs(TTY_CLEAR_SCREEN, rows, tty_out_char);
- tty_flush();
- }
-
-
- /* Touch the tty, getting rid of any possible optimization. */
-
- void
- tty_touch()
- {
- memset(tty_screen, 0, rows * columns * sizeof(unsigned char));
- }
-
-
- /* Move the cursor. */
-
- void
- tty_cursormove(y, x)
- int y, x;
- {
- char *str;
-
- str = tgoto(TTY_CURSOR_MOVE, x, y);
- tputs(str, 1, tty_out_char);
- tty_flush();
-
- tty_cursor_x = x;
- tty_cursor_y = y;
- }
-
-
- /* Notify the cursor change. Used in the output optimization code. */
-
- void
- tty_cursormove_notify(y, x)
- int y, x;
- {
- tty_cursormove_notified = 1;
- tty_cursor_x = x;
- tty_cursor_y = y;
- }
-
-
- /* Setup the reverse video status. This is only used internally by the code in
- this file so it is declared 'static'. */
-
- static void
- tty_reverse(status)
- int status;
- {
- if (status == ON)
- {
- if (TTY_REVERSE_ON)
- {
- tputs(TTY_REVERSE_ON, 1, tty_out_char);
- tty_flush();
- }
- }
- else
- {
- if (TTY_ATTRIBUTES_OFF)
- {
- tputs(TTY_ATTRIBUTES_OFF, 1, tty_out_char);
- tty_flush();
- }
- rv_status = OFF;
- /* same comment as in tty_brightness() */
- if (br_status == ON) tty_brightness(ON);
- }
-
- rv_status = status;
- }
-
-
- /* Setup the foreground color. Use the ANSI color sequence where possible or
- tty_reverse() for monochrome terminals. */
-
- void
- tty_foreground(color)
- int color;
- {
- char str[16];
-
- memcpy(str, ansi_foreground, sizeof(ansi_foreground));
-
- if (AnsiColorSequences == ON)
- {
- str[3] += (fg_color = color);
- xwrite(TTY_OUTPUT, str, sizeof(ansi_foreground));
- }
- else
- tty_reverse((fg_color = color) != WHITE);
-
- tty_current_attribute = (tty_current_attribute & 0xF8) | fg_color;
- }
-
-
- /* Setup the background color. Use the ANSI color sequence where possible or
- tty_reverse() for monochrome terminals. */
-
- void
- tty_background(color)
- int color;
- {
- char str[16];
-
- memcpy(str, ansi_background, sizeof(ansi_background));
-
- if (AnsiColorSequences == ON)
- {
- str[3] += (bg_color = color);
- xwrite(TTY_OUTPUT, str, sizeof(ansi_background));
- }
- else
- tty_reverse((bg_color = color) != BLACK);
-
- tty_current_attribute = (tty_current_attribute & 0xC7) | (bg_color << 3);
- }
-
-
- /* Setup the brightness status. See the comment below. */
-
- void
- tty_brightness(status)
- int status;
- {
- if (status == ON)
- {
- if (TTY_BRIGHT_ON)
- {
- tputs(TTY_BRIGHT_ON, 1, tty_out_char);
- tty_flush();
- }
- }
- else
- {
- if (TTY_ATTRIBUTES_OFF)
- {
- tputs(TTY_ATTRIBUTES_OFF, 1, tty_out_char);
- tty_flush();
- }
-
- br_status = OFF;
- /* There is no terminal capability for brightness off (or bold off).
- We are using the 'me' capability (where available) which turns
- off all attributes so we must restore the reverse status after
- that. There is no need to restore the foreground & background
- colors because we've always put tty_brightness(status) *BEFORE*
- tty_foreground(color) or tty_background(color). */
- if (rv_status == ON)
- tty_reverse(ON);
- }
-
- br_status = status;
-
- tty_current_attribute = (tty_current_attribute & 0xBF) | (br_status << 6);
- }
-
-
- /* Set the brightness, foreground and background together. */
-
- void
- tty_colors(brightness, foreground, background)
- int brightness, foreground, background;
- {
- tty_brightness(brightness);
- tty_foreground(foreground);
- tty_background(background);
- }
-
-
- /* Pavarotti is better, but we are doing our best... */
-
- void
- tty_beep()
- {
- char c = 7;
-
- xwrite(TTY_OUTPUT, &c, 1);
- }
-
-
- /* Setup the cursor status (where possible). Make it invisible during screen
- refreshes and restore it afterward. */
-
- void
- tty_cursor(status)
- int status;
- {
- if ((cursor_status = status))
- {
- if (TTY_CURSOR_ON)
- {
- tputs(TTY_CURSOR_ON, 1, tty_out_char);
- tty_flush();
- }
- }
- else
- {
- if (TTY_CURSOR_OFF)
- {
- tputs(TTY_CURSOR_OFF, 1, tty_out_char);
- tty_flush();
- }
- }
- }
-
-
- /* Store the soft terminal status in a tty_status_t structure. */
-
- void
- tty_save(status)
- tty_status_t *status;
- {
- status->fg_color = fg_color;
- status->bg_color = bg_color;
- status->br_status = br_status;
- status->rv_status = rv_status;
- status->cursor_status = cursor_status;
- status->attribute = tty_current_attribute;
- }
-
-
- /* Restore the soft terminal status from a tty_status_t structure. */
-
- void
- tty_restore(status)
- tty_status_t *status;
- {
- tty_colors(status->br_status, status->fg_color, status->bg_color);
- tty_reverse(status->rv_status);
- tty_cursor(status->cursor_status);
- tty_current_attribute = status->attribute;
- }
-
-
- /* Restore the terminal to its default state. Use Linux specific sequences
- on Linux consoles. */
-
- void
- tty_defaults()
- {
- #ifdef HAVE_LINUX
- if (LinuxConsole == ON)
- xwrite(TTY_OUTPUT, lc_defaults, sizeof(lc_defaults));
- else
- #endif /* HAVE_LINUX */
- if (TTY_ATTRIBUTES_OFF)
- {
- tputs(TTY_ATTRIBUTES_OFF, 1, tty_out_char);
- tty_flush();
- }
-
- tty_foreground(ForegroundAtExit);
- tty_background(BackgroundAtExit);
- br_status = rv_status = OFF;
-
- tty_cursor(ON);
-
- tty_current_attribute = (br_status << 6) | (bg_color << 3) | fg_color;
- }
-
-
- /* Write data to the terminal, performing optimizations according to the
- optimization level (tty_optimization_level). Actually there are two
- optimization methods:
- - (tty_optimization_level == 0)
- If the string we want to write on the screen is already there,
- don't perform the write() system call, but even if one character
- or attribute is different that the one on the screen, write the
- entire string. This method is suitable for panel entries because
- these entries are usually completely different so the first
- difference found leads us to the conclusion that we have to update
- the entire area.
- - (tty_optimization_level == 1)
- All the characters and attributes are checked. Only those characters
- that cannot be found on the screen are updated. Suitable for
- updating the command line. */
-
- size_t
- tty_write(buf, length)
- char *buf;
- size_t length;
- {
- size_t bytes;
- int i, j = 0, x = tty_cursor_x;
- int tty_offset = (tty_cursor_y * columns) + tty_cursor_x;
- unsigned char *tty_sptr = tty_screen + tty_offset;
- unsigned char *tty_aptr = tty_attributes + tty_offset;
-
-
- if (tty_optimization_level == 1)
- {
- while (1)
- {
- for (i = j; i < length; i++)
- if (tty_sptr[i] != (unsigned char)(buf[i]) ||
- tty_aptr[i] != tty_current_attribute)
- break;
-
- for (j = i; j < length; j++)
- if (tty_sptr[j] == (unsigned char)(buf[j]) &&
- tty_aptr[j] == tty_current_attribute)
- break;
-
- bytes = j - i;
-
- if (bytes != 0)
- {
- memcpy(tty_sptr + i, buf + i, bytes);
- memset(tty_aptr + i, tty_current_attribute, bytes);
- tty_cursormove(tty_cursor_y, x + i);
- xwrite(TTY_OUTPUT, (char *)tty_sptr + i, bytes);
- }
- else
- {
- tty_cursormove_notified = 0;
- tty_cursor_x = x + length;
- return length;
- }
- }
- }
-
- if (memcmp(tty_sptr, buf, length) == 0)
- {
- for (i = 0; i < length; i++)
- if (tty_aptr[i] != tty_current_attribute)
- {
- buf += i;
- length -= i;
- tty_cursor_x += i;
- tty_cursormove_notified = 1;
- goto write_needed;
- }
-
- tty_cursor_x += length;
- tty_cursormove_notified = 1;
- return length;
- }
-
- write_needed:
-
- memcpy(tty_sptr, buf, length);
- memset(tty_aptr, tty_current_attribute, length);
-
- if (tty_cursormove_notified)
- tty_cursormove(tty_cursor_y, tty_cursor_x);
-
- tty_cursor_x += length;
- tty_cursormove_notified = 0;
- return xwrite(TTY_OUTPUT, buf, length);
- }
-
-
- /* Read data from terminal. */
-
- size_t
- tty_read(buf, length)
- char *buf;
- size_t length;
- {
- size_t bytes;
-
- if (tty_enter_idle_hook)
- (*tty_enter_idle_hook)();
-
- bytes = xread(TTY_INPUT, buf, length);
-
- if (tty_exit_idle_hook)
- (*tty_exit_idle_hook)();
-
- return bytes;
- }
-
-
- /* Get a character from the terminal. For better performance on high loaded
- systems, read as many data as available. */
-
- int
- tty_get_char()
- {
- if (keyno)
- return keybuf[keyno--, keyindex++];
-
- /* No interrupt/quit character. */
- tty_set_interrupt_char(-1);
-
- for (keyindex = 0; (keyno = tty_read(keybuf, 1024)) < 0;);
-
- /* Restore ^G as the interrupt/quit character. */
- tty_set_interrupt_char(key_INTERRUPT);
-
- return keyno ? keybuf[keyno--, keyindex++] : -1;
- }
-
-
- /* Write a character to the screen. */
-
- size_t
- tty_put_char(c)
- char c;
- {
- return tty_write(&c, 1);
- }
-
-
- /* Insert a key sequence into the list. */
-
- void
- tty_key_list_insert_sequence(key, key_seq, aux_data)
- tty_key_t **key;
- unsigned char *key_seq;
- void *aux_data;
- {
- tty_key_t *new_key;
-
- new_key = (tty_key_t *)xmalloc(sizeof(tty_key_t));
- new_key->key_seq = (unsigned char *)xstrdup(key_seq);
- new_key->aux_data = aux_data;
- new_key->next = *key;
- *key = new_key;
- }
-
-
- /* Parse the key list, inserting the new key sequence in the proper
- position. */
-
- void
- tty_key_list_insert(key_seq, aux_data)
- unsigned char *key_seq;
- void *aux_data;
- {
- static tty_key_t **key = NULL;
-
- if (*key_seq == 0)
- return; /* bad key sequence ! */
-
- /* Try to optimize by checking if the current entry should be added
- after the current position. Avoid re-parsing the entire list if
- so. */
- if (key == NULL || strcmp((char *)key_seq, (*key)->key_seq) <= 0)
- key = &key_list_head;
-
- for (; *key; key = &(*key)->next)
- if (strcmp((char *)key_seq, (*key)->key_seq) <= 0)
- {
- tty_key_list_insert_sequence(key, key_seq, aux_data);
- return;
- }
-
- tty_key_list_insert_sequence(key, key_seq, aux_data);
- }
-
-
- /* Incremental searches a key in the list. Returns a pointer to the first
- sequence that matches. */
-
- tty_key_t *
- tty_key_search(key_seq)
- char *key_seq;
- {
- int cmp;
-
- if (current_key == NULL)
- return NULL;
-
- for (; current_key; current_key = current_key->next)
- {
- cmp = strcmp(key_seq, (char *)current_key->key_seq);
-
- if (cmp == 0)
- return current_key;
-
- if (cmp < 0)
- break;
- }
-
- if (current_key == NULL ||
- strncmp(key_seq, (char *)current_key->key_seq, strlen(key_seq)))
- return (tty_key_t *)-1;
- else
- return NULL;
- }
-
-
- /* Force the next key search to start from the begining of the list. */
-
- void
- tty_key_search_restart()
- {
- current_key = key_list_head;
- }
-
-
- #if 0
- /* Delete a key from the list. Don't remove this function, God only knows
- when I'll gonna need it... */
-
- void
- tty_key_list_delete()
- {
- tty_key_t *key, *next_key;
-
- for (key = key_list_head; key; key = next_key)
- {
- next_key = key->next;
- xfree(key->key_seq);
- xfree(key);
- }
- }
- #endif
-
-
- /* Get the first key available, returning also the repeat count, that is,
- the number of times the key has been pressed. These feature is mainly
- used by the calling routines to perform optimizations. For example, if
- you press the down arrow several times, the caller can display only
- the final position, saving a lot of time. If you have ever worked with
- this program on high loaded systems, I'm sure you know what I mean. */
-
- tty_key_t *
- tty_get_key(repeat_count)
- int *repeat_count;
- {
- int i, c;
- tty_key_t *key;
- unsigned char key_seq[64];
-
-
- restart:
-
- while ((c = tty_get_char()) == -1);
-
- if (repeat_count)
- *repeat_count = 1;
-
- /* Handle ^SPC. */
- if (c == 0)
- c = 0xff;
-
- if (!tty_kbdmode)
- {
- if (c == '\n' || c == '\r')
- c = key_ENTER;
-
- if (is_print(c) || c == key_INTERRUPT)
- {
- default_key.key_seq[0] = c;
- default_key.key_seq[1] = 0;
- return &default_key;
- }
- }
-
- tty_key_search_restart();
-
- for (i = 0; i < MAX_KEY_LENGTH; i++)
- {
- /* Handle brain-damaged key sequences correctly. If a 0 is
- found, transform it in a 0xff. I don't know how smart this
- is, but right know I don't feel like doing it otherwise. */
- if (c == 0)
- c = 0xff;
-
- key_seq[i ] = c;
- key_seq[i + 1] = 0;
-
- key = tty_key_search(key_seq);
-
- if (key == (tty_key_t *)-1)
- goto restart;
-
- if (key)
- break;
-
- while ((c = tty_get_char()) == -1);
- }
-
- if (i == MAX_KEY_LENGTH)
- goto restart;
-
- if (repeat_count)
- while (keyno > i && (memcmp(key_seq, &keybuf[keyindex], i + 1) == 0))
- {
- keyindex += i + 1;
- keyno -= i + 1;
- (*repeat_count)++;
- }
-
- return key;
- }
-
-
- /* Retreive the screen size. Try ioctl(TIOCGWINSZ, ...) and, if it fails
- or it is not supported, use the environment variables LINES & COLUMNS
- (if possible). If both methods fail, use the default 80x24. */
-
- void
- tty_get_size(_columns, _rows)
- int *_columns, *_rows;
- {
- char *env;
-
- #ifdef HAVE_WINSZ
- struct winsize winsz;
- #endif /* HAVE_WINSZ */
-
- int temp_rows, temp_columns;
-
- columns = rows = temp_columns = temp_rows = 0;
-
- #ifdef HAVE_WINSZ
-
- #if defined TIOCGSIZE && !defined TIOCGWINSZ
- #define TIOCGWINSZ TIOCGSIZE
- #endif
-
- ioctl(TTY_OUTPUT, TIOCGWINSZ, &winsz);
-
- if (winsz.ws_col && winsz.ws_row)
- {
- temp_columns = winsz.ws_col;
- temp_rows = winsz.ws_row;
- }
- #endif /* HAVE_WINSZ */
-
- if ((env = getenv("COLUMNS"))) sscanf(env, "%d", &columns);
- if ((env = getenv("LINES" ))) sscanf(env, "%d", &rows);
-
- #ifdef HAVE_WINSZ
- if (columns < 80) columns = temp_columns;
- if (rows < 10) rows = temp_rows;
- #endif /* HAVE_WINSZ */
-
- if (columns < 80 || columns > MAX_TTY_COLUMNS) columns = 80;
- if (rows < 10 || rows > MAX_TTY_ROWS) rows = 24;
-
- *_columns = columns;
- *_rows = rows;
- }
-
-
- /* Dump the screen. Only used in Linux if the terminal is a virtual
- console. */
-
- void
- tty_get_screen(buf)
- char *buf;
- {
- #ifdef HAVE_LINUX
- if (LinuxConsole == ON)
- {
- int vcs, bytes_read;
- char vcsname[16] = "/dev/vcsaX";
-
- vcsname[9] = tty_name[tty_name_len - 1];
- vcs = open(vcsname, O_RDONLY);
- bytes_read = read(vcs, buf, 4 + rows * columns * 2);
- close(vcs);
-
- vcs_read_ok = (bytes_read != -1);
- }
- #endif /* HAVE_LINUX */
- }
-
-
- /* Restore the screen. If the terminal is not a Linux virtual console, just
- restore it to the default state. */
-
- void
- tty_put_screen(buf)
- char *buf;
- {
- tty_defaults();
- tty_cursormove(0, 0);
-
- #ifdef HAVE_LINUX
- if (LinuxConsole == ON)
- {
- if (vcs_read_ok)
- {
- int vcs, bytes_written;
- char vcsname[16] = "/dev/vcsaX";
-
- tty_touch();
- vcsname[9] = tty_name[tty_name_len - 1];
- vcs = open(vcsname, O_WRONLY);
- bytes_written = write(vcs, buf, 4 + rows * columns * 2);
- close(vcs);
-
- /* We might have the permission to read the contents of the
- virtual console, but not the permission to read it. */
- if (bytes_written != -1)
- tty_cursormove(buf[3], buf[2]);
- else
- {
- tty_defaults();
- tty_clear();
- }
- }
- else
- {
- tty_defaults();
- tty_clear();
- }
- }
- else
- {
- tty_defaults();
- tty_clear();
- }
- #else /* !HAVE_LINUX */
- tty_defaults();
- tty_clear();
- #endif /* !HAVE_LINUX */
- }
-
-
- /* Get the color index from the colors[] index table. */
-
- int
- tty_get_color_index(colorname)
- char *colorname;
- {
- int i;
-
- for (i = 0; i < 10; i++)
- if (strcmp(colors[i], colorname) == 0)
- return (i < 8) ? i : (i - 8);
- return -1;
- }
-
-
- /* Return the capability of a given termcap symbol. */
-
- char *
- tty_get_symbol_key_seq(symbol)
- char *symbol;
- {
- int i;
-
- for (i = TTY_FIRST_SYMBOL_KEY; i < TTY_USED_CAPABILITIES; i++)
- if (strcmp(tty_capability[i].symbol, symbol) == 0)
- return tty_capability[i].capability;
-
- return NULL;
- }
-
-
- void
- tty_get_exit_colors()
- {
- use_section("[Setup]");
-
- /* Try to read the foreground and background colors that we should restore
- at exit. The default are white/black. */
- ForegroundAtExit = get_const_var("ForegroundAtExit", colors, 8, 7);
- BackgroundAtExit = get_const_var("BackgroundAtExit", colors, 8, 0);
- }
-
- /* Get the entire set of requiresd termcap/terminfo capabilities. It performs
- consistency checkings trying to recover as well as possible. */
-
- void
- tty_get_capabilities()
- {
- #ifdef HAVE_LINUX
- struct stat statbuf;
- #endif /* HAVE_LINUX */
- char *capability_buf, *tmp;
- int err, i, term_errors = 0;
- char *termtype = getenv("TERM");
-
- #ifdef HAVE_LINUX
- fstat(TTY_OUTPUT, &statbuf);
- if ((statbuf.st_rdev >> 8) == LINUX_VC_MAJOR &&
- ((unsigned)(statbuf.st_rdev & 0xFF)) <= 8)
- LinuxConsole = ON;
- else
- LinuxConsole = OFF;
- #endif /* HAVE_LINUX */
-
- if (termtype == NULL)
- {
- fprintf(stderr, "%s: can't find the TERM environment variable, ",
- program);
- goto switch_to_vt100;
- }
-
- if (strlen(termtype) > 63)
- {
- fprintf(stderr, "%s: the TERM environment variable is too long, ",
- program);
- switch_to_vt100:
- fprintf(stderr, "trying vt100 ...\n");
- termtype = vt100;
- }
-
- err = tgetent(term_buf, termtype);
-
- if (err == -1)
- {
- fprintf(stderr, "%s: can't find the %s database.\n",
- program, term_database);
- fprintf(stderr, "%s: check your %s environment variable ...\n",
- program, term_env);
- exit(1);
- }
-
- if (err == 0)
- {
- fprintf(stderr,
- "%s: can't find the terminal type %s in the %s database.\n",
- program, termtype, term_database);
- exit(1);
- }
- tty_type = xstrdup(termtype);
-
- capability_buf = xmalloc(2048);
-
- tmp = tgetstr(TTY_PAD_CHAR_NAME, &capability_buf);
- PC = tmp ? *tmp : 0;
-
- BC = tgetstr(TTY_LEFT_ONE_SPACE_NAME, &capability_buf);
- UP = tgetstr(TTY_UP_ONE_LINE_NAME, &capability_buf);
-
- if (BC == NULL || UP == NULL)
- BC = UP = NULL;
-
- TTY_ATTRIBUTES_OFF = tgetstr(TTY_ATTRIBUTES_OFF_NAME, &capability_buf);
- TTY_REVERSE_ON = tgetstr(TTY_REVERSE_ON_NAME, &capability_buf);
- TTY_BRIGHT_ON = tgetstr(TTY_BRIGHT_ON_NAME, &capability_buf);
-
- if (TTY_ATTRIBUTES_OFF == NULL)
- {
- #ifdef HAVE_LINUX
- if (LinuxConsole)
- TTY_ATTRIBUTES_OFF = lc_attr_off; /* I *really* hate this ! */
- else
- #endif /* HAVE_LINUX */
- TTY_REVERSE_ON = TTY_BRIGHT_ON = NULL;
- }
-
-
- /* I have problems using (and understanding) hpterm, so I've used a
- small hack to get it work. I hope I will be able to change this
- someday... */
-
- if (strcmp(termtype, "hpterm") == 0)
- TTY_ATTRIBUTES_OFF = TTY_REVERSE_ON = TTY_BRIGHT_ON = NULL;
-
- TTY_CURSOR_OFF = tgetstr(TTY_CURSOR_OFF_NAME, &capability_buf);
- TTY_CURSOR_ON = tgetstr(TTY_CURSOR_ON_NAME, &capability_buf);
-
- if (TTY_CURSOR_OFF == NULL || TTY_CURSOR_ON == NULL)
- TTY_CURSOR_ON = TTY_CURSOR_OFF = NULL;
-
- TTY_CLEAR_SCREEN = tgetstr(TTY_CLEAR_SCREEN_NAME, &capability_buf);
- TTY_CURSOR_MOVE = tgetstr(TTY_CURSOR_MOVE_NAME, &capability_buf);
-
- for (i = TTY_FIRST_SYMBOL_KEY; i < TTY_USED_CAPABILITIES; i++)
- tty_capability[i].capability = tgetstr(tty_capability[i].name,
- &capability_buf);
-
- for (i = 0; i < TTY_USED_CAPABILITIES; i++)
- if (tty_capability[i].capability == NULL)
- if (tty_capability[i].indispensable)
- {
- term_errors++;
- fprintf(stderr,
- "%s: can't find the '%s' terminal capability.\n",
- program, tty_capability[i].name);
- }
-
- if (term_errors)
- {
- fprintf(stderr, "%s: %d errors. Your terminal is too dumb :-< .\n",
- program, term_errors);
- exit(1);
- }
- }
-