home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / top / screen.c < prev    next >
C/C++ Source or Header  |  1992-02-01  |  6KB  |  303 lines

  1. /*
  2.  *  Top - a top users display for Berkeley Unix
  3.  *
  4.  *  This file contains the routines that interface to termcap and stty/gtty.
  5.  *
  6.  *  Paul Vixie, February 1987: converted to use ioctl() instead of stty/gtty.
  7.  *
  8.  *  I put in code to turn on the TOSTOP bit while top was running, but I
  9.  *  didn't really like the results.  If you desire it, turn on the
  10.  *  preprocessor variable "TOStop".   --wnl
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <sgtty.h>
  15. #include <strings.h>
  16. #include "screen.h"
  17. #include "boolean.h"
  18.  
  19. extern char *myname;
  20.  
  21. int putstdout();
  22.  
  23. int  overstrike;
  24. int  screen_length;
  25. int  screen_width;
  26. char ch_erase;
  27. char ch_kill;
  28. char smart_terminal;
  29. char PC;
  30. char *tgetstr();
  31. char *tgoto();
  32. char termcap_buf[1024];
  33. char string_buffer[1024];
  34. char home[15];
  35. char lower_left[15];
  36. char *clear_line;
  37. char *clear_screen;
  38. char *clear_to_end;
  39. char *cursor_motion;
  40. char *start_standout;
  41. char *end_standout;
  42. char *terminal_init;
  43. char *terminal_end;
  44. short ospeed;
  45.  
  46. static struct sgttyb old_settings;
  47. static struct sgttyb new_settings;
  48. static char is_a_terminal = No;
  49. #ifdef TOStop
  50. static int old_lword;
  51. static int new_lword;
  52. #endif
  53.  
  54. #define    STDIN    0
  55. #define    STDOUT    1
  56. #define    STDERR    2
  57.  
  58. init_termcap()
  59.  
  60. {
  61.     char *bufptr;
  62.     char *PCptr;
  63.     char *term_name;
  64.     char *getenv();
  65.     int status;
  66.  
  67.     /* assume we have a smart terminal until proven otherwise */
  68.     smart_terminal = Yes;
  69.  
  70.     /* now get terminal name and termcap entry */
  71.     term_name = getenv("TERM");
  72.     if ((status = tgetent(termcap_buf, term_name)) != 1)
  73.     {
  74.     if (status == -1)
  75.     {
  76.         fprintf(stderr, "%s: can't open termcap file\n", myname);
  77.     }
  78.     else
  79.     {
  80.         fprintf(stderr, "%s: no termcap entry for a `%s' terminal\n",
  81.             myname, getenv("TERM"));
  82.     }
  83.  
  84.     /* pretend it's dumb and proceed */
  85.     smart_terminal = No;
  86.     return;
  87.     }
  88.  
  89.     /* "hardcopy" immediately indicates a very stupid terminal */
  90.     if (tgetflag("hc"))
  91.     {
  92.     smart_terminal = No;
  93.     return;
  94.     }
  95.  
  96.     /* set up common terminal capabilities */
  97.     if ((screen_length = tgetnum("li")) <= 0)
  98.     {
  99.     screen_length = smart_terminal = 0;
  100.     return;
  101.     }
  102.  
  103.     /* screen_width is a little different */
  104.     if ((screen_width = tgetnum("co")) == -1)
  105.     {
  106.     screen_width = 79;
  107.     }
  108.     else
  109.     {
  110.     screen_width -= 1;
  111.     }
  112.  
  113.     /* terminals that overstrike need special attention */
  114.     overstrike = tgetflag("os");
  115.  
  116.     /* initialize the pointer into the termcap string buffer */
  117.     bufptr = string_buffer;
  118.  
  119.     /* get "ce", clear to end */
  120.     if (!overstrike)
  121.     {
  122.     clear_line = tgetstr("ce", &bufptr);
  123.     }
  124.  
  125.     /* get necessary capabilities */
  126.     if ((clear_screen  = tgetstr("cl", &bufptr)) == NULL ||
  127.     (cursor_motion = tgetstr("cm", &bufptr)) == NULL)
  128.     {
  129.     smart_terminal = No;
  130.     return;
  131.     }
  132.  
  133.     /* get some more sophisticated stuff -- these are optional */
  134.     clear_to_end   = tgetstr("cd", &bufptr);
  135.     terminal_init  = tgetstr("ti", &bufptr);
  136.     terminal_end   = tgetstr("te", &bufptr);
  137.     start_standout = tgetstr("so", &bufptr);
  138.     end_standout   = tgetstr("se", &bufptr);
  139.  
  140.     /* pad character */
  141.     PC = (PCptr = tgetstr("pc", &bufptr)) ? *PCptr : 0;
  142.  
  143.     /* set convenience strings */
  144.     (void) strcpy(home, tgoto(cursor_motion, 0, 0));
  145.     (void) strcpy(lower_left, tgoto(cursor_motion, 0, screen_length - 1));
  146.  
  147.     /* if stdout is not a terminal, pretend we are a dumb terminal */
  148.     if (ioctl(STDOUT, TIOCGETP, &old_settings) == -1)
  149.     {
  150.     smart_terminal = No;
  151.     }
  152. }
  153.  
  154. init_screen()
  155.  
  156. {
  157.     /* get the old settings for safe keeping */
  158.     if (ioctl(STDOUT, TIOCGETP, &old_settings) == 0)
  159.     {
  160.     /* copy the settings so we can modify them */
  161.     new_settings = old_settings;
  162.  
  163.     /* turn on CBREAK and turn off character echo and tab expansion */
  164.     new_settings.sg_flags |= CBREAK;
  165.     new_settings.sg_flags &= ~(ECHO|XTABS);
  166.     (void) ioctl(STDOUT, TIOCSETP, &new_settings);
  167.  
  168.     /* remember the erase and kill characters */
  169.     ch_erase = old_settings.sg_erase;
  170.     ch_kill  = old_settings.sg_kill;
  171.  
  172. #ifdef TOStop
  173.     /* get the local mode word */
  174.     (void) ioctl(STDOUT, TIOCLGET, &old_lword);
  175.  
  176.     /* modify it */
  177.     new_lword = old_lword | LTOSTOP;
  178.     (void) ioctl(STDOUT, TIOCLSET, &new_lword);
  179. #endif
  180.  
  181.     /* remember that it really is a terminal */
  182.     is_a_terminal = Yes;
  183.  
  184.     /* send the termcap initialization string */
  185.     putcap(terminal_init);
  186.     }
  187.     else
  188.     {
  189.     /* not a terminal at all---consider it dumb */
  190.     smart_terminal = No;
  191.     }
  192. }
  193.  
  194. end_screen()
  195.  
  196. {
  197.     /* move to the lower left, clear the line and send "te" */
  198.     if (smart_terminal)
  199.     {
  200.     putcap(lower_left);
  201.     putcap(clear_line);
  202.     putcap(terminal_end);
  203.     }
  204.  
  205.     /* if we have settings to reset, then do so */
  206.     if (is_a_terminal)
  207.     {
  208.     (void) ioctl(STDOUT, TIOCSETP, &old_settings);
  209. #ifdef TOStop
  210.     (void) ioctl(STDOUT, TIOCLSET, &old_lword);
  211. #endif
  212.     }
  213. }
  214.  
  215. reinit_screen()
  216.  
  217. {
  218.     /* install our settings if it is a terminal */
  219.     if (is_a_terminal)
  220.     {
  221.     (void) ioctl(STDOUT, TIOCSETP, &new_settings);
  222. #ifdef TOStop
  223.     (void) ioctl(STDOUT, TIOCLSET, &new_lword);
  224. #endif
  225.     }
  226.  
  227.     /* send init string */
  228.     if (smart_terminal)
  229.     {
  230.     putcap(terminal_init);
  231.     }
  232. }
  233.  
  234. standout(msg)
  235.  
  236. char *msg;
  237.  
  238. {
  239.     if (smart_terminal)
  240.     {
  241.     putcap(start_standout);
  242.     fputs(msg, stdout);
  243.     putcap(end_standout);
  244.     }
  245.     else
  246.     {
  247.     fputs(msg, stdout);
  248.     }
  249. }
  250.  
  251. clear()
  252.  
  253. {
  254.     if (smart_terminal)
  255.     {
  256.     putcap(clear_screen);
  257.     }
  258. }
  259.  
  260. clear_eol(len)
  261.  
  262. int len;
  263.  
  264. {
  265.     if (smart_terminal && !overstrike && len > 0)
  266.     {
  267.     if (clear_line)
  268.     {
  269.         putcap(clear_line);
  270.         return(0);
  271.     }
  272.     else
  273.     {
  274.         while (len-- > 0)
  275.         {
  276.         putchar(' ');
  277.         }
  278.         return(1);
  279.     }
  280.     }
  281.     return(-1);
  282. }
  283.  
  284. go_home()
  285.  
  286. {
  287.     if (smart_terminal)
  288.     {
  289.     putcap(home);
  290.     }
  291. }
  292.  
  293. /* This has to be defined as a subroutine for tputs (instead of a macro) */
  294.  
  295. putstdout(ch)
  296.  
  297. char ch;
  298.  
  299. {
  300.     putchar(ch);
  301. }
  302.  
  303.