[BACK]Return to screen.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / top

Diff for /src/usr.bin/top/screen.c between version 1.9 and 1.10

version 1.9, 2003/06/12 22:30:23 version 1.10, 2003/06/12 23:09:30
Line 1 
Line 1 
 /*      $OpenBSD$       */  /* $OpenBSD$     */
   
 /*  /*
  *  Top users/processes display for Unix   *  Top users/processes display for Unix
Line 28 
Line 28 
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */   */
   
 /*  This file contains the routines that interface to termcap and stty/gtty.  /*
  *   * This file contains the routines that interface to termcap and stty/gtty.
  *  Paul Vixie, February 1987: converted to use ioctl() instead of 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   * I put in code to turn on the TOSTOP bit while top was running, but I didn't
  *  preprocessor variable "TOStop".   --wnl   * really like the results.  If you desire it, turn on the preprocessor
    * variable "TOStop".   --wnl
  */   */
   
 #include <sys/types.h>  #include <sys/types.h>
Line 50 
Line 51 
 #include "screen.h"  #include "screen.h"
 #include "boolean.h"  #include "boolean.h"
   
 extern char *myname;  extern char    *myname;
   
 int  overstrike;  int             overstrike;
 int  screen_length;  int             screen_length;
 int  screen_width;  int             screen_width;
 char ch_erase;  char            ch_erase;
 char ch_kill;  char            ch_kill;
 char smart_terminal;  char            smart_terminal;
 char PC;  char            PC;
 char string_buffer[1024];  char            string_buffer[1024];
 char home[15];  char            home[15];
 char lower_left[15];  char            lower_left[15];
 char *clear_line;  char           *clear_line;
 char *clear_scr;  char           *clear_scr;
 char *clear_to_end;  char           *clear_to_end;
 char *cursor_motion;  char           *cursor_motion;
 char *start_standout;  char           *start_standout;
 char *end_standout;  char           *end_standout;
 char *terminal_init;  char           *terminal_init;
 char *terminal_end;  char           *terminal_end;
 short ospeed;  short           ospeed;
   
 static struct termios old_settings;  static struct termios old_settings;
 static struct termios new_settings;  static struct termios new_settings;
   
 static char is_a_terminal = No;  static char     is_a_terminal = No;
   
 void  void
 init_termcap(int interactive)  init_termcap(int interactive)
 {  {
     char *bufptr;          char *bufptr, *PCptr, *term_name;
     char *PCptr;          int status;
     char *term_name;  
     int status;  
   
     /* set defaults in case we aren't smart */          /* set defaults in case we aren't smart */
     screen_width = MAX_COLS;          screen_width = MAX_COLS;
     screen_length = 0;          screen_length = 0;
   
     if (!interactive)          if (!interactive) {
     {                  /* pretend we have a dumb terminal */
         /* pretend we have a dumb terminal */                  smart_terminal = No;
         smart_terminal = No;                  return;
         return;          }
     }          /* assume we have a smart terminal until proven otherwise */
           smart_terminal = Yes;
   
     /* assume we have a smart terminal until proven otherwise */          /* get the terminal name */
     smart_terminal = Yes;          term_name = getenv("TERM");
   
     /* get the terminal name */          /* if there is no TERM, assume it's a dumb terminal */
     term_name = getenv("TERM");          /* patch courtesy of Sam Horrocks at telegraph.ics.uci.edu */
           if (term_name == NULL) {
                   smart_terminal = No;
                   return;
           }
   
     /* if there is no TERM, assume it's a dumb terminal */          /* now get the termcap entry */
     /* patch courtesy of Sam Horrocks at telegraph.ics.uci.edu */          if ((status = tgetent(NULL, term_name)) != 1) {
     if (term_name == NULL)                  if (status == -1)
     {                          fprintf(stderr, "%s: can't open termcap file\n", myname);
         smart_terminal = No;                  else
         return;                          fprintf(stderr, "%s: no termcap entry for a `%s' terminal\n",
     }                              myname, term_name);
   
     /* now get the termcap entry */                  /* pretend it's dumb and proceed */
     if ((status = tgetent(NULL, term_name)) != 1)                  smart_terminal = No;
     {                  return;
         if (status == -1)  
         {  
             fprintf(stderr, "%s: can't open termcap file\n", myname);  
         }          }
         else  
         {          /* "hardcopy" immediately indicates a very stupid terminal */
             fprintf(stderr, "%s: no termcap entry for a `%s' terminal\n",          if (tgetflag("hc")) {
                     myname, term_name);                  smart_terminal = No;
                   return;
         }          }
           /* set up common terminal capabilities */
           if ((screen_length = tgetnum("li")) <= Header_lines) {
                   screen_length = smart_terminal = 0;
                   return;
           }
   
         /* pretend it's dumb and proceed */          /* screen_width is a little different */
         smart_terminal = No;          if ((screen_width = tgetnum("co")) == -1)
         return;                  screen_width = 79;
     }          else
                   screen_width -= 1;
   
     /* "hardcopy" immediately indicates a very stupid terminal */          /* terminals that overstrike need special attention */
     if (tgetflag("hc"))          overstrike = tgetflag("os");
     {  
         smart_terminal = No;  
         return;  
     }  
   
     /* set up common terminal capabilities */          /* initialize the pointer into the termcap string buffer */
     if ((screen_length = tgetnum("li")) <= Header_lines)          bufptr = string_buffer;
     {  
         screen_length = smart_terminal = 0;  
         return;  
     }  
   
     /* screen_width is a little different */          /* get "ce", clear to end */
     if ((screen_width = tgetnum("co")) == -1)          if (!overstrike) {
     {                  clear_line = tgetstr("ce", &bufptr);
         screen_width = 79;          }
     }          /* get necessary capabilities */
     else          if ((clear_scr = tgetstr("cl", &bufptr)) == NULL ||
     {              (cursor_motion = tgetstr("cm", &bufptr)) == NULL) {
         screen_width -= 1;                  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);
   
     /* terminals that overstrike need special attention */          /* pad character */
     overstrike = tgetflag("os");          PC = (PCptr = tgetstr("pc", &bufptr)) ? *PCptr : 0;
   
     /* initialize the pointer into the termcap string buffer */          /* set convenience strings */
     bufptr = string_buffer;          (void) strlcpy(home, tgoto(cursor_motion, 0, 0), sizeof(home));
           /* (lower_left is set in get_screensize) */
   
     /* get "ce", clear to end */          /* get the actual screen size with an ioctl, if needed */
     if (!overstrike)          /*
     {           * This may change screen_width and screen_length, and it always sets
         clear_line = tgetstr("ce", &bufptr);           * lower_left.
     }           */
           get_screensize();
   
     /* get necessary capabilities */          /* if stdout is not a terminal, pretend we are a dumb terminal */
     if ((clear_scr  = tgetstr("cl", &bufptr)) == NULL ||          if (tcgetattr(STDOUT_FILENO, &old_settings) == -1)
         (cursor_motion = tgetstr("cm", &bufptr)) == NULL)                  smart_terminal = No;
     {  
         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) strncpy(home, tgoto(cursor_motion, 0, 0), sizeof (home) -1);  
     home[sizeof (home) -1] = 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 */  
     if (tcgetattr(STDOUT_FILENO, &old_settings) == -1)  
     {  
         smart_terminal = No;  
     }  
 }  }
   
 void  void
 init_screen(void)  init_screen(void)
 {  {
     /* get the old settings for safe keeping */          /* get the old settings for safe keeping */
     if (tcgetattr(STDOUT_FILENO, &old_settings) != -1)          if (tcgetattr(STDOUT_FILENO, &old_settings) != -1) {
     {                  /* copy the settings so we can modify them */
         /* copy the settings so we can modify them */                  new_settings = old_settings;
         new_settings = old_settings;  
   
         /* turn off ICANON, character echo and tab expansion */                  /* turn off ICANON, character echo and tab expansion */
         new_settings.c_lflag &= ~(ICANON|ECHO);                  new_settings.c_lflag &= ~(ICANON | ECHO);
         new_settings.c_oflag &= ~(OXTABS);                  new_settings.c_oflag &= ~(OXTABS);
         new_settings.c_cc[VMIN] = 1;                  new_settings.c_cc[VMIN] = 1;
         new_settings.c_cc[VTIME] = 0;                  new_settings.c_cc[VTIME] = 0;
         (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);                  (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);
   
         /* remember the erase and kill characters */                  /* remember the erase and kill characters */
         ch_erase = old_settings.c_cc[VERASE];                  ch_erase = old_settings.c_cc[VERASE];
         ch_kill  = old_settings.c_cc[VKILL];                  ch_kill = old_settings.c_cc[VKILL];
   
         /* remember that it really is a terminal */                  /* remember that it really is a terminal */
         is_a_terminal = Yes;                  is_a_terminal = Yes;
   
         /* send the termcap initialization string */                  /* send the termcap initialization string */
         putcap(terminal_init);                  putcap(terminal_init);
     }          }
           if (!is_a_terminal) {
     if (!is_a_terminal)                  /* not a terminal at all---consider it dumb */
     {                  smart_terminal = No;
         /* not a terminal at all---consider it dumb */          }
         smart_terminal = No;  
     }  
 }  }
   
 void  void
 end_screen(void)  end_screen(void)
 {  {
     /* move to the lower left, clear the line and send "te" */          /* move to the lower left, clear the line and send "te" */
     if (smart_terminal)          if (smart_terminal) {
     {                  putcap(lower_left);
         putcap(lower_left);                  putcap(clear_line);
         putcap(clear_line);                  fflush(stdout);
         fflush(stdout);                  putcap(terminal_end);
         putcap(terminal_end);          }
     }  
   
     /* if we have settings to reset, then do so */          /* if we have settings to reset, then do so */
     if (is_a_terminal)          if (is_a_terminal)
     {                  (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &old_settings);
         (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &old_settings);  
     }  
 }  }
   
 void  void
 reinit_screen(void)  reinit_screen(void)
 {  {
     /* install our settings if it is a terminal */          /* install our settings if it is a terminal */
     if (is_a_terminal)          if (is_a_terminal)
     {                  (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);
         (void) tcsetattr(STDOUT_FILENO, TCSADRAIN, &new_settings);  
     }  
   
     /* send init string */          /* send init string */
     if (smart_terminal)          if (smart_terminal)
     {                  putcap(terminal_init);
         putcap(terminal_init);  
     }  
 }  }
   
 void  void
 get_screensize(void)  get_screensize(void)
 {  {
     struct winsize ws;          struct winsize ws;
   
     if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1)          if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
     {                  if (ws.ws_row != 0)
         if (ws.ws_row != 0)                          screen_length = ws.ws_row;
         {                  if (ws.ws_col != 0)
             screen_length = ws.ws_row;                          screen_width = ws.ws_col - 1;
         }          }
         if (ws.ws_col != 0)          (void) strlcpy(lower_left, tgoto(cursor_motion, 0, screen_length - 1),
         {              sizeof(lower_left));
             screen_width = ws.ws_col - 1;  
         }  
     }  
   
     (void) strncpy(lower_left, tgoto(cursor_motion, 0, screen_length - 1),  
                    sizeof (lower_left) -1);  
     lower_left[sizeof(lower_left) -1] = 0;  
 }  }
   
 void  void
 standout(char *msg)  standout(char *msg)
 {  {
     if (smart_terminal)          if (smart_terminal) {
     {                  putcap(start_standout);
         putcap(start_standout);                  if (fputs(msg, stdout) == EOF)
         if (fputs(msg, stdout) == EOF)                          exit(1);
             exit(1);                  putcap(end_standout);
         putcap(end_standout);          } else {
     }                  if (fputs(msg, stdout) == EOF)
     else                          exit(1);
     {          }
         if (fputs(msg, stdout) == EOF)  
             exit(1);  
     }  
 }  }
   
 void clear()  void
   clear()
 {  {
     if (smart_terminal)          if (smart_terminal)
     {                  putcap(clear_scr);
         putcap(clear_scr);  
     }  
 }  }
   
 int  int
 clear_eol(int len)  clear_eol(int len)
 {  {
     if (smart_terminal && !overstrike && len > 0)          if (smart_terminal && !overstrike && len > 0) {
     {                  if (clear_line) {
         if (clear_line)                          putcap(clear_line);
         {                          return (0);
             putcap(clear_line);                  } else {
             return(0);                          while (len-- > 0) {
                                   if (putchar(' ') == EOF)
                                           exit(1);
                           }
                           return (1);
                   }
         }          }
         else          return (-1);
         {  
             while (len-- > 0)  
             {  
                 if (putchar(' ') == EOF)  
                         exit(1);  
             }  
             return(1);  
         }  
     }  
     return(-1);  
 }  }
   
 void  void
 go_home(void)  go_home(void)
 {  {
     if (smart_terminal)          if (smart_terminal)
     {                  putcap(home);
         putcap(home);  
     }  
 }  }
   
 /* This has to be defined as a subroutine for tputs (instead of a macro) */  /* This has to be defined as a subroutine for tputs (instead of a macro) */
   
 int  int
 putstdout(int ch)  putstdout(int ch)
 {  {
     int ret;          int ret;
   
     ret = putchar(ch);          ret = putchar(ch);
     if (ret == EOF)          if (ret == EOF)
         exit(1);                  exit(1);
     return (ret);          return (ret);
 }  }

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10