diff options
Diffstat (limited to 'screen.c')
-rw-r--r-- | screen.c | 375 |
1 files changed, 236 insertions, 139 deletions
@@ -1,12 +1,38 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * 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. @@ -21,20 +47,52 @@ #include "os.h" #include "top.h" +#if HAVE_CURSES_H && HAVE_TERM_H +#include <curses.h> +#include <term.h> +#else +#if HAVE_TERMCAP_H +#include <termcap.h> +#else +#if HAVE_CURSES_H +#include <curses.h> +#endif +#endif +#endif + +#if !HAVE_DECL_TPUTS +int tputs(const char *, int, int (*)(int)); +#endif +#if !HAVE_DECL_TGOTO +char *tgoto(const char *, int, int); +#endif +#if !HAVE_DECL_TGETENT +int tgetent(const char *, char *); +#endif +#if !HAVE_DECL_TGETFLAG +int tgetflag(const char *); +#endif +#if !HAVE_DECL_TGETNUM +int tgetnum(const char *); +#endif +#if !HAVE_DECL_TGETSTR +char *tgetstr(const char *, char **); +#endif + #include <sys/ioctl.h> #ifdef CBREAK # include <sgtty.h> -# define SGTTY +# define USE_SGTTY #else # ifdef TCGETA -# define TERMIO +# define USE_TERMIO # include <termio.h> # else -# define TERMIOS +# define USE_TERMIOS # include <termios.h> # endif #endif -#if defined(TERMIO) || defined(TERMIOS) +#if defined(USE_TERMIO) || defined(USE_TERMIOS) # ifndef TAB3 # ifdef OXTABS # define TAB3 OXTABS @@ -43,45 +101,46 @@ # endif # endif #endif + #include "screen.h" #include "boolean.h" -extern char *myname; +#define putcap(str) (void)((str) != NULL ? tputs(str, 1, putstdout) : 0) -int putstdout(); +extern char *myname; -int overstrike; -int screen_length; -int screen_width; char ch_erase; char ch_kill; +char ch_werase; char smart_terminal; +int screen_length; +int screen_width; + 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 int tc_overstrike; +static char termcap_buf[1024]; +static char string_buffer[1024]; +static char home[15]; +static char lower_left[15]; +static char *tc_clear_line; +static char *tc_clear_screen; +static char *tc_clear_to_end; +static char *tc_cursor_motion; +static char *tc_start_standout; +static char *tc_end_standout; +static char *terminal_init; +static char *terminal_end; + +#ifdef USE_SGTTY static struct sgttyb old_settings; static struct sgttyb new_settings; #endif -#ifdef TERMIO +#ifdef USE_TERMIO static struct termio old_settings; static struct termio new_settings; #endif -#ifdef TERMIOS +#ifdef USE_TERMIOS static struct termios old_settings; static struct termios new_settings; #endif @@ -95,9 +154,61 @@ static int new_lword; #define STDOUT 1 #define STDERR 2 -init_termcap(interactive) +/* This has to be defined as a subroutine for tputs (instead of a macro) */ + +static int +putstdout(TPUTS_PUTC_ARGTYPE ch) -int interactive; +{ + return putchar((int)ch); +} + +void +screen_getsize() + +{ + +#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(tc_cursor_motion, 0, screen_length - 1)); +} + +int +screen_readtermcap(int interactive) { char *bufptr; @@ -110,11 +221,11 @@ int interactive; screen_width = MAX_COLS; screen_length = 0; - if (!interactive) + if (interactive == No) { /* pretend we have a dumb terminal */ smart_terminal = No; - return; + return No; } /* assume we have a smart terminal until proven otherwise */ @@ -128,7 +239,7 @@ int interactive; if (term_name == NULL) { smart_terminal = No; - return; + return No; } /* now get the termcap entry */ @@ -146,21 +257,21 @@ int interactive; /* pretend it's dumb and proceed */ smart_terminal = No; - return; + return No; } /* "hardcopy" immediately indicates a very stupid terminal */ if (tgetflag("hc")) { smart_terminal = No; - return; + return No; } /* set up common terminal capabilities */ if ((screen_length = tgetnum("li")) <= 0) { screen_length = smart_terminal = 0; - return; + return No; } /* screen_width is a little different */ @@ -174,70 +285,73 @@ int interactive; } /* terminals that overstrike need special attention */ - overstrike = tgetflag("os"); + tc_overstrike = tgetflag("os"); /* initialize the pointer into the termcap string buffer */ bufptr = string_buffer; /* get "ce", clear to end */ - if (!overstrike) + if (!tc_overstrike) { - clear_line = tgetstr("ce", &bufptr); + tc_clear_line = tgetstr("ce", &bufptr); } /* get necessary capabilities */ - if ((clear_screen = tgetstr("cl", &bufptr)) == NULL || - (cursor_motion = tgetstr("cm", &bufptr)) == NULL) + if ((tc_clear_screen = tgetstr("cl", &bufptr)) == NULL || + (tc_cursor_motion = tgetstr("cm", &bufptr)) == NULL) { smart_terminal = No; - return; + return No; } /* get some more sophisticated stuff -- these are optional */ - clear_to_end = tgetstr("cd", &bufptr); + tc_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); + tc_start_standout = tgetstr("so", &bufptr); + tc_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) */ + (void) strcpy(home, tgoto(tc_cursor_motion, 0, 0)); + /* (lower_left is set in screen_getsize) */ /* 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(); + screen_getsize(); /* if stdout is not a terminal, pretend we are a dumb terminal */ -#ifdef SGTTY +#ifdef USE_SGTTY if (ioctl(STDOUT, TIOCGETP, &old_settings) == -1) { smart_terminal = No; } #endif -#ifdef TERMIO +#ifdef USE_TERMIO if (ioctl(STDOUT, TCGETA, &old_settings) == -1) { smart_terminal = No; } #endif -#ifdef TERMIOS +#ifdef USE_TERMIOS if (tcgetattr(STDOUT, &old_settings) == -1) { smart_terminal = No; } #endif + + return smart_terminal; } -init_screen() +void +screen_init() { /* get the old settings for safe keeping */ -#ifdef SGTTY +#ifdef USE_SGTTY if (ioctl(STDOUT, TIOCGETP, &old_settings) != -1) { /* copy the settings so we can modify them */ @@ -251,6 +365,7 @@ init_screen() /* remember the erase and kill characters */ ch_erase = old_settings.sg_erase; ch_kill = old_settings.sg_kill; + ch_werase = old_settings.sg_werase; #ifdef TOStop /* get the local mode word */ @@ -267,7 +382,7 @@ init_screen() putcap(terminal_init); } #endif -#ifdef TERMIO +#ifdef USE_TERMIO if (ioctl(STDOUT, TCGETA, &old_settings) != -1) { /* copy the settings so we can modify them */ @@ -281,8 +396,9 @@ init_screen() (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]; + ch_erase = old_settings.c_cc[VERASE]; + ch_kill = old_settings.c_cc[VKILL]; + ch_werase = old_settings.c_cc[VWERASE]; /* remember that it really is a terminal */ is_a_terminal = Yes; @@ -291,7 +407,7 @@ init_screen() putcap(terminal_init); } #endif -#ifdef TERMIOS +#ifdef USE_TERMIOS if (tcgetattr(STDOUT, &old_settings) != -1) { /* copy the settings so we can modify them */ @@ -305,8 +421,9 @@ init_screen() (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]; + ch_erase = old_settings.c_cc[VERASE]; + ch_kill = old_settings.c_cc[VKILL]; + ch_werase = old_settings.c_cc[VWERASE]; /* remember that it really is a terminal */ is_a_terminal = Yes; @@ -323,14 +440,15 @@ init_screen() } } -end_screen() +void +screen_end() { /* move to the lower left, clear the line and send "te" */ if (smart_terminal) { putcap(lower_left); - putcap(clear_line); + putcap(tc_clear_line); fflush(stdout); putcap(terminal_end); } @@ -338,37 +456,38 @@ end_screen() /* if we have settings to reset, then do so */ if (is_a_terminal) { -#ifdef SGTTY +#ifdef USE_SGTTY (void) ioctl(STDOUT, TIOCSETP, &old_settings); #ifdef TOStop (void) ioctl(STDOUT, TIOCLSET, &old_lword); #endif #endif -#ifdef TERMIO +#ifdef USE_TERMIO (void) ioctl(STDOUT, TCSETA, &old_settings); #endif -#ifdef TERMIOS +#ifdef USE_TERMIOS (void) tcsetattr(STDOUT, TCSADRAIN, &old_settings); #endif } } -reinit_screen() +void +screen_reinit() { /* install our settings if it is a terminal */ if (is_a_terminal) { -#ifdef SGTTY +#ifdef USE_SGTTY (void) ioctl(STDOUT, TIOCSETP, &new_settings); #ifdef TOStop (void) ioctl(STDOUT, TIOCLSET, &new_lword); #endif #endif -#ifdef TERMIO +#ifdef USE_TERMIO (void) ioctl(STDOUT, TCSETA, &new_settings); #endif -#ifdef TERMIOS +#ifdef USE_TERMIOS (void) tcsetattr(STDOUT, TCSADRAIN, &new_settings); #endif } @@ -380,59 +499,22 @@ reinit_screen() } } -get_screensize() +void +screen_move(int x, int y) { - -#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)); + tputs(tgoto(tc_cursor_motion, x, y), 1, putstdout); } -standout(msg) - -char *msg; +void +screen_standout(char *msg) { if (smart_terminal) { - putcap(start_standout); + putcap(tc_start_standout); fputs(msg, stdout); - putcap(end_standout); + putcap(tc_end_standout); } else { @@ -440,40 +522,64 @@ char *msg; } } -clear() +void +screen_clear() { if (smart_terminal) { - putcap(clear_screen); + putcap(tc_clear_screen); } } -clear_eol(len) +int +screen_cte() + +{ + if (smart_terminal) + { + if (tc_clear_to_end) + { + putcap(tc_clear_to_end); + return(Yes); + } + } + return(No); +} -int len; +void +screen_cleareol(int len) { - if (smart_terminal && !overstrike && len > 0) + int i; + + if (smart_terminal && !tc_overstrike && len > 0) { - if (clear_line) + if (tc_clear_line) { - putcap(clear_line); - return(0); + putcap(tc_clear_line); + return; } else { - while (len-- > 0) + i = 0; + while (i++ < 0) { putchar(' '); } - return(1); + i = 0; + while (i++ < 0) + { + putchar('\b'); + } + return; } } - return(-1); + return; } -go_home() +void +screen_home() { if (smart_terminal) @@ -482,13 +588,4 @@ go_home() } } -/* This has to be defined as a subroutine for tputs (instead of a macro) */ - -putstdout(ch) - -char ch; - -{ - putchar(ch); -} |