diff options
author | joerg <joerg@FreeBSD.org> | 1997-03-23 18:51:21 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1997-03-23 18:51:21 +0000 |
commit | 1b9d0472b72177a604d3c5dd26d25eec00049bd2 (patch) | |
tree | 1409de2219944c7c90248988b70ac693cf71206d /contrib/top/screen.c | |
download | FreeBSD-src-1b9d0472b72177a604d3c5dd26d25eec00049bd2.zip FreeBSD-src-1b9d0472b72177a604d3c5dd26d25eec00049bd2.tar.gz |
This is the long-awaited import of top into the base system (actually,
the src/contrib/top part right now). This tools is simply too system-
dependant to maintain it in the ports collection.
Diffstat (limited to 'contrib/top/screen.c')
-rw-r--r-- | contrib/top/screen.c | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/contrib/top/screen.c b/contrib/top/screen.c new file mode 100644 index 0000000..b5d0388 --- /dev/null +++ b/contrib/top/screen.c @@ -0,0 +1,494 @@ +/* + * Top users/processes display for Unix + * Version 3 + * + * This program may be freely redistributed, + * but this entire comment MUST remain intact. + * + * Copyright (c) 1984, 1989, William LeFebvre, Rice University + * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University + */ + +/* This file contains the routines that interface to termcap and stty/gtty. + * + * Paul Vixie, February 1987: converted to use ioctl() instead of stty/gtty. + * + * I put in code to turn on the TOSTOP bit while top was running, but I + * didn't really like the results. If you desire it, turn on the + * preprocessor variable "TOStop". --wnl + */ + +#include "os.h" +#include "top.h" + +#include <sys/ioctl.h> +#ifdef CBREAK +# include <sgtty.h> +# define SGTTY +#else +# ifdef TCGETA +# define TERMIO +# include <termio.h> +# else +# define TERMIOS +# include <termios.h> +# endif +#endif +#if defined(TERMIO) || defined(TERMIOS) +# ifndef TAB3 +# ifdef OXTABS +# define TAB3 OXTABS +# else +# define TAB3 0 +# endif +# endif +#endif +#include "screen.h" +#include "boolean.h" + +extern char *myname; + +int putstdout(); + +int overstrike; +int screen_length; +int screen_width; +char ch_erase; +char ch_kill; +char smart_terminal; +char PC; +char *tgetstr(); +char *tgoto(); +char termcap_buf[1024]; +char string_buffer[1024]; +char home[15]; +char lower_left[15]; +char *clear_line; +char *clear_screen; +char *clear_to_end; +char *cursor_motion; +char *start_standout; +char *end_standout; +char *terminal_init; +char *terminal_end; +short ospeed; + +#ifdef SGTTY +static struct sgttyb old_settings; +static struct sgttyb new_settings; +#endif +#ifdef TERMIO +static struct termio old_settings; +static struct termio new_settings; +#endif +#ifdef TERMIOS +static struct termios old_settings; +static struct termios new_settings; +#endif +static char is_a_terminal = No; +#ifdef TOStop +static int old_lword; +static int new_lword; +#endif + +#define STDIN 0 +#define STDOUT 1 +#define STDERR 2 + +init_termcap(interactive) + +int interactive; + +{ + char *bufptr; + char *PCptr; + char *term_name; + char *getenv(); + int status; + + /* set defaults in case we aren't smart */ + screen_width = MAX_COLS; + screen_length = 0; + + if (!interactive) + { + /* pretend we have a dumb terminal */ + smart_terminal = No; + return; + } + + /* assume we have a smart terminal until proven otherwise */ + smart_terminal = Yes; + + /* get the terminal name */ + term_name = getenv("TERM"); + + /* if there is no TERM, assume it's a dumb terminal */ + /* patch courtesy of Sam Horrocks at telegraph.ics.uci.edu */ + if (term_name == NULL) + { + smart_terminal = No; + return; + } + + /* now get the termcap entry */ + if ((status = tgetent(termcap_buf, term_name)) != 1) + { + if (status == -1) + { + fprintf(stderr, "%s: can't open termcap file\n", myname); + } + else + { + fprintf(stderr, "%s: no termcap entry for a `%s' terminal\n", + myname, term_name); + } + + /* pretend it's dumb and proceed */ + smart_terminal = No; + return; + } + + /* "hardcopy" immediately indicates a very stupid terminal */ + if (tgetflag("hc")) + { + smart_terminal = No; + return; + } + + /* set up common terminal capabilities */ + if ((screen_length = tgetnum("li")) <= 0) + { + screen_length = smart_terminal = 0; + return; + } + + /* screen_width is a little different */ + if ((screen_width = tgetnum("co")) == -1) + { + screen_width = 79; + } + else + { + screen_width -= 1; + } + + /* terminals that overstrike need special attention */ + overstrike = tgetflag("os"); + + /* initialize the pointer into the termcap string buffer */ + bufptr = string_buffer; + + /* get "ce", clear to end */ + if (!overstrike) + { + clear_line = tgetstr("ce", &bufptr); + } + + /* get necessary capabilities */ + if ((clear_screen = tgetstr("cl", &bufptr)) == NULL || + (cursor_motion = tgetstr("cm", &bufptr)) == NULL) + { + smart_terminal = No; + return; + } + + /* get some more sophisticated stuff -- these are optional */ + clear_to_end = tgetstr("cd", &bufptr); + terminal_init = tgetstr("ti", &bufptr); + terminal_end = tgetstr("te", &bufptr); + start_standout = tgetstr("so", &bufptr); + end_standout = tgetstr("se", &bufptr); + + /* pad character */ + PC = (PCptr = tgetstr("pc", &bufptr)) ? *PCptr : 0; + + /* set convenience strings */ + (void) strcpy(home, tgoto(cursor_motion, 0, 0)); + /* (lower_left is set in get_screensize) */ + + /* get the actual screen size with an ioctl, if needed */ + /* This may change screen_width and screen_length, and it always + sets lower_left. */ + get_screensize(); + + /* if stdout is not a terminal, pretend we are a dumb terminal */ +#ifdef SGTTY + if (ioctl(STDOUT, TIOCGETP, &old_settings) == -1) + { + smart_terminal = No; + } +#endif +#ifdef TERMIO + if (ioctl(STDOUT, TCGETA, &old_settings) == -1) + { + smart_terminal = No; + } +#endif +#ifdef TERMIOS + if (tcgetattr(STDOUT, &old_settings) == -1) + { + smart_terminal = No; + } +#endif +} + +init_screen() + +{ + /* get the old settings for safe keeping */ +#ifdef SGTTY + if (ioctl(STDOUT, TIOCGETP, &old_settings) != -1) + { + /* copy the settings so we can modify them */ + new_settings = old_settings; + + /* turn on CBREAK and turn off character echo and tab expansion */ + new_settings.sg_flags |= CBREAK; + new_settings.sg_flags &= ~(ECHO|XTABS); + (void) ioctl(STDOUT, TIOCSETP, &new_settings); + + /* remember the erase and kill characters */ + ch_erase = old_settings.sg_erase; + ch_kill = old_settings.sg_kill; + +#ifdef TOStop + /* get the local mode word */ + (void) ioctl(STDOUT, TIOCLGET, &old_lword); + + /* modify it */ + new_lword = old_lword | LTOSTOP; + (void) ioctl(STDOUT, TIOCLSET, &new_lword); +#endif + /* remember that it really is a terminal */ + is_a_terminal = Yes; + + /* send the termcap initialization string */ + putcap(terminal_init); + } +#endif +#ifdef TERMIO + if (ioctl(STDOUT, TCGETA, &old_settings) != -1) + { + /* copy the settings so we can modify them */ + new_settings = old_settings; + + /* turn off ICANON, character echo and tab expansion */ + new_settings.c_lflag &= ~(ICANON|ECHO); + new_settings.c_oflag &= ~(TAB3); + new_settings.c_cc[VMIN] = 1; + new_settings.c_cc[VTIME] = 0; + (void) ioctl(STDOUT, TCSETA, &new_settings); + + /* remember the erase and kill characters */ + ch_erase = old_settings.c_cc[VERASE]; + ch_kill = old_settings.c_cc[VKILL]; + + /* remember that it really is a terminal */ + is_a_terminal = Yes; + + /* send the termcap initialization string */ + putcap(terminal_init); + } +#endif +#ifdef TERMIOS + if (tcgetattr(STDOUT, &old_settings) != -1) + { + /* copy the settings so we can modify them */ + new_settings = old_settings; + + /* turn off ICANON, character echo and tab expansion */ + new_settings.c_lflag &= ~(ICANON|ECHO); + new_settings.c_oflag &= ~(TAB3); + new_settings.c_cc[VMIN] = 1; + new_settings.c_cc[VTIME] = 0; + (void) tcsetattr(STDOUT, TCSADRAIN, &new_settings); + + /* remember the erase and kill characters */ + ch_erase = old_settings.c_cc[VERASE]; + ch_kill = old_settings.c_cc[VKILL]; + + /* remember that it really is a terminal */ + is_a_terminal = Yes; + + /* send the termcap initialization string */ + putcap(terminal_init); + } +#endif + + if (!is_a_terminal) + { + /* not a terminal at all---consider it dumb */ + smart_terminal = No; + } +} + +end_screen() + +{ + /* move to the lower left, clear the line and send "te" */ + if (smart_terminal) + { + putcap(lower_left); + putcap(clear_line); + fflush(stdout); + putcap(terminal_end); + } + + /* if we have settings to reset, then do so */ + if (is_a_terminal) + { +#ifdef SGTTY + (void) ioctl(STDOUT, TIOCSETP, &old_settings); +#ifdef TOStop + (void) ioctl(STDOUT, TIOCLSET, &old_lword); +#endif +#endif +#ifdef TERMIO + (void) ioctl(STDOUT, TCSETA, &old_settings); +#endif +#ifdef TERMIOS + (void) tcsetattr(STDOUT, TCSADRAIN, &old_settings); +#endif + } +} + +reinit_screen() + +{ + /* install our settings if it is a terminal */ + if (is_a_terminal) + { +#ifdef SGTTY + (void) ioctl(STDOUT, TIOCSETP, &new_settings); +#ifdef TOStop + (void) ioctl(STDOUT, TIOCLSET, &new_lword); +#endif +#endif +#ifdef TERMIO + (void) ioctl(STDOUT, TCSETA, &new_settings); +#endif +#ifdef TERMIOS + (void) tcsetattr(STDOUT, TCSADRAIN, &new_settings); +#endif + } + + /* send init string */ + if (smart_terminal) + { + putcap(terminal_init); + } +} + +get_screensize() + +{ + +#ifdef TIOCGWINSZ + + struct winsize ws; + + if (ioctl (1, TIOCGWINSZ, &ws) != -1) + { + if (ws.ws_row != 0) + { + screen_length = ws.ws_row; + } + if (ws.ws_col != 0) + { + screen_width = ws.ws_col - 1; + } + } + +#else +#ifdef TIOCGSIZE + + struct ttysize ts; + + if (ioctl (1, TIOCGSIZE, &ts) != -1) + { + if (ts.ts_lines != 0) + { + screen_length = ts.ts_lines; + } + if (ts.ts_cols != 0) + { + screen_width = ts.ts_cols - 1; + } + } + +#endif /* TIOCGSIZE */ +#endif /* TIOCGWINSZ */ + + (void) strcpy(lower_left, tgoto(cursor_motion, 0, screen_length - 1)); +} + +standout(msg) + +char *msg; + +{ + if (smart_terminal) + { + putcap(start_standout); + fputs(msg, stdout); + putcap(end_standout); + } + else + { + fputs(msg, stdout); + } +} + +clear() + +{ + if (smart_terminal) + { + putcap(clear_screen); + } +} + +clear_eol(len) + +int len; + +{ + if (smart_terminal && !overstrike && len > 0) + { + if (clear_line) + { + putcap(clear_line); + return(0); + } + else + { + while (len-- > 0) + { + putchar(' '); + } + return(1); + } + } + return(-1); +} + +go_home() + +{ + if (smart_terminal) + { + putcap(home); + } +} + +/* This has to be defined as a subroutine for tputs (instead of a macro) */ + +putstdout(ch) + +char ch; + +{ + putchar(ch); +} + |