home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume29 / parseargs / part03 / winsize.c < prev   
Encoding:
C/C++ Source or Header  |  1992-05-19  |  7.0 KB  |  280 lines

  1. /*************************************************************************
  2. ** ^FILE: winsize.c - implement the routine get_winsize()
  3. **
  4. ** ^DESCRIPTION:
  5. **    Implement the get_winsize() function for various windowing and
  6. **    operating systems.
  7. **
  8. ** ^HISTORY:
  9. **    10/01/90     Brad Appleton     <brad@ssd.csd.harris.com>     Created
  10. ***^^**********************************************************************/
  11.  
  12.  
  13. /***************************************************************************
  14. ** ^FUNCTION: get_winsize - get the current window size
  15. **
  16. ** ^SYNOPSIS:
  17. **    void get_winsize( fd, nrows, ncols )
  18. **
  19. ** ^PARAMETERS:
  20. **    int fd;
  21. **    -- file-descriptor associated with the "output-window"
  22. **
  23. **    int *nrows;
  24. **    -- pointer to number of rows in window
  25. **
  26. **    int *ncols;
  27. **    -- pointer to number of columns in window
  28. **
  29. ** ^DESCRIPTION:
  30. **    Get_winsize will attempt to determine the maximum number of
  31. **    rows and colums that will fit on one screen-full of the associated
  32. **    output device. If it fails to do this, it will assume the "window"
  33. **    is a 24x80 (rows by columns) display.
  34. **
  35. ** ^REQUIREMENTS:
  36. **    fd must correspond to a valid output device.
  37. **
  38. ** ^SIDE-EFFECTS:
  39. **    The memory addressed by nrows and ncols is assigned the corresponding
  40. **    appropriate value(s).
  41. **
  42. ** ^RETURN-VALUE:
  43. **    None.
  44. **
  45. ** ^ALGORITHM:
  46. **     System dependent.
  47. ***^^**********************************************************************/
  48.  
  49. #include <stdio.h>
  50.  
  51. #ifdef __ANSI_C__
  52. # define  GET_WINSIZE(fd,nrows,ncols)  \
  53.     void get_winsize( int fd, int *nrows, int *ncols )
  54. #else
  55. # define  GET_WINSIZE(fd,nrows,ncols)  \
  56.     void get_winsize( fd, nrows, ncols ) \
  57.     int fd, *nrows, *ncols;   /* nrows and ncols are passed by reference */
  58. #endif
  59.  
  60. #define  DEFAULT_ROWS  24
  61. #define  DEFAULT_COLS  80
  62.  
  63. #ifdef vms
  64.  
  65. #include <stdio.h>
  66. #include <iodef.h>
  67. #include <ssdef.h>
  68. #include <descrip.h>
  69. #include <useful.h>
  70.  
  71.    /* structure to contain terminal characteristics */
  72. typedef  struct {
  73.       short garb1, cols;
  74.       char   garb2, garb3, garb4, rows;
  75. } termchar_t;
  76.  
  77. int sys$assign();
  78. int sys$qiow();
  79. int sys$dassgn();
  80.  
  81. GET_WINSIZE( fd, nrows, ncols )
  82. {
  83.    int c, charlen = 8;
  84.    termchar_t   termchar;
  85.    int chan;
  86.    $DESCRIPTOR( devnam,"SYS$COMMAND" );
  87.  
  88.    sys$assign( &devnam, &chan, 0, 0 );
  89.    sys$qiow( 0, chan, IO$_SENSEMODE, 0, 0, 0, &termchar, &charlen, 0, 0, 0, 0 );
  90.    sys$dassgn( chan );
  91.  
  92.    *nrows = ( termchar.rows > 0 ) ? (int) termchar.rows : DEFAULT_ROWS;
  93.    *ncols = ( termchar.cols > 0 ) ? (int) termchar.cols : DEFAULT_COLS;
  94. }
  95.  
  96. #else
  97. #ifdef unix
  98.  
  99.    /*
  100.    ** we will either try to access terminfo through the termcap-interface
  101.    ** in the curses library (which would require linking with -lcurses)
  102.    ** or use termcap directly (which would require linking with -ltermcap)
  103.    */
  104. #ifndef USE_TERMCAP
  105. #if ( defined(USE_TERMINFO) || defined(USE_CURSES) )
  106. #define USE_TERMCAP
  107. #endif
  108. #endif
  109.  
  110.  
  111. #ifdef USE_TERMCAP
  112. # define TERMBUFSIZ    1024
  113. # define UNKNOWN_TERM  "unknown"
  114. # define DUMB_TERMBUF  "dumb:co#80:hc:"
  115. extern int  tgetent();
  116. extern int  tgetnum();
  117. #endif
  118.  
  119.  
  120.    /* try to get TIOCGWINSZ from termios.h, then from sys/ioctl.h */
  121. #include <termios.h>
  122. #if ( !defined(TIOCGWINSZ)  &&  !defined(TIOCGSIZE)  &&  !defined(WIOCGETD) )
  123. #include <sys/ioctl.h>
  124. #endif
  125.  
  126.    /* if still dont have TIOCGWINSZ (or TIOCGSIZE) try for WIOCGETD */
  127. #if ( !defined(TIOCGWINSZ)  &&  !defined(TIOCGSIZE)  &&  !defined(WIOCGETD) )
  128. #include <sgtty.h>
  129. #endif
  130.  
  131. #include <useful.h>
  132.  
  133. /*
  134. ** get_winsize() -- determine # of rows/columns that will fit on the screen.
  135. **
  136. **     The environment variables $LINES and $COLUMNS will be used if they exist.
  137. **     If not, then the TIOCGWINSZ call to ioctl() is used (if it is defined).
  138. **     If not, then the TIOCGSIZE call to ioctl() is used (if it is defined).
  139. **     If not, then the WIOCGETD call to ioctl() is used (if it is defined).
  140. **     If not, then get the info from terminfo/termcap (if it is there)
  141. **     Otherwise, assume we have a 24x80 screen.
  142. */
  143.  
  144. extern  int   ioctl();
  145. extern  int   isatty();
  146. extern  long  atol();
  147. extern  char *getenv();
  148.  
  149. GET_WINSIZE( fd, nrows, ncols )
  150. {
  151.    char  *lines_env, *cols_env;
  152.    long  lrow = 0, lcol = 0;
  153.    int   lines = 0, cols = 0;
  154. #ifdef USE_TERMCAP
  155.    char  term_buf[ TERMBUFSIZ ], *term_env;
  156. #endif
  157. #ifdef TIOCGWINSZ
  158.    struct winsize  win;
  159. #else
  160. #ifdef TIOCGSIZE
  161.    struct ttysize  win;
  162. #else
  163. #ifdef WIOCGETD
  164.    struct uwdata  win;
  165. #endif
  166. #endif
  167. #endif
  168.  
  169.       /* make sure that fd corresponds to a terminal */
  170.    if ( !isatty( fd ) ) {
  171.       *nrows = DEFAULT_ROWS;
  172.       *ncols = DEFAULT_COLS;
  173.       return;
  174.    }
  175.  
  176.       /* LINES & COLUMNS environment variables override everything else */
  177.    lines_env = getenv( "LINES" );
  178.    if ( lines_env  &&  (lrow = atol(lines_env)) > 0 ) {
  179.       *nrows = lines = (int) lrow;
  180.    }
  181.  
  182.    cols_env = getenv( "COLUMNS" );
  183.    if ( cols_env  &&  (lcol = atol(cols_env)) > 0 ) {
  184.       *ncols = cols = (int) lcol;
  185.    }
  186.  
  187. #ifdef TIOCGWINSZ
  188.       /* see what ioctl() has to say (overrides terminfo & termcap) */
  189.    if ( (!lines || !cols)  &&  ioctl(fd, TIOCGWINSZ, &win) != -1 ) {
  190.       if ( !lines  &&  win.ws_row > 0 ) {
  191.          *nrows = lines = (int) win.ws_row;
  192.       }
  193.  
  194.       if ( !cols  &&  win.ws_col > 0 ) {
  195.          *ncols = cols = (int) win.ws_col;
  196.       }
  197.    }/*if*/
  198. #else
  199. #ifdef TIOCGSIZE
  200.       /* see what ioctl() has to say (overrides terminfo & termcap) */
  201.    if ( (!lines || !cols)  &&  ioctl(fd, TIOCGSIZE, &win) != -1 ) {
  202.       if ( !lines  &&  win.ts_lines > 0 )
  203.          *nrows = lines = (int) win.ts_lines;
  204.  
  205.       if ( !cols  &&  win.ts_cols > 0 )
  206.          *ncols = cols = (int) win.ts_cols;
  207.    }/*if*/
  208. #else
  209. #ifdef WIOCGETD
  210.       /* see what ioctl() has to say (overrides terminfo & termcap) */
  211.    if ( (!lines || !cols)  &&  ioctl(fd, WIOCGETD, &win) != -1 ) {
  212.       if ( !lines  &&  win.uw_height > 0 )
  213.          *nrows = lines = (int) (win.uw_height / win.uw_vs);
  214.  
  215.       if ( !cols  &&  win.uw_width > 0 )
  216.          *ncols = cols = (int) (win.uw_width / win.uw_hs);
  217.    }/*if*/
  218. #endif
  219. #endif
  220. #endif
  221.  
  222. #ifdef USE_TERMCAP
  223.       /* see what terminfo/termcap has to say */
  224.    if ( !lines || !cols ) {
  225.       if ( !(term_env = getenv("TERM")) )
  226.          term_env = UNKNOWN_TERM;
  227.  
  228.       if ( (tgetent(term_buf, term_env) <= 0) )
  229.          strcpy( term_buf, DUMB_TERMBUF );
  230.  
  231.           if ( !lines   &&   (lrow = tgetnum("li")) > 0 )
  232.             *nrows = lines = (int) lrow;
  233.  
  234.           if ( !cols   &&   (lcol = tgetnum("co")) > 0 )
  235.             *ncols = cols = (int) lcol;
  236.    }
  237. #endif
  238.  
  239.       /* use 80x24 if all else fails */
  240.    if ( !lines )  *nrows = DEFAULT_ROWS;
  241.    if ( !cols )   *ncols = DEFAULT_COLS;
  242.  
  243. }/*get_winsize()*/
  244.  
  245. #else
  246.  
  247. GET_WINSIZE( fd, nrows, ncols )
  248. {
  249.       /* just use 80x24 */
  250.    *nrows = DEFAULT_ROWS;
  251.    *ncols = DEFAULT_COLS;
  252. }
  253.  
  254. #endif  /* not a vms system */
  255. #endif  /* not a unix-system */
  256.  
  257. #ifdef WINSIZE_TEST
  258.  
  259. #ifdef vms
  260. # include <ssdef.h>
  261. #endif
  262.  
  263.    /* test get_winsize to see if it works */
  264. main()
  265. {
  266.    int rows, cols;
  267.  
  268.    get_winsize( fileno(stderr), &rows, &cols );
  269.    printf( "Output will be %d rows by %d columns\n", rows, cols );
  270.  
  271. #ifdef vms
  272.    exit( SS$_NORMAL );
  273. #else
  274.    exit( 0 );
  275. #endif
  276.  
  277. }
  278.  
  279. #endif
  280.