home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / tass.lzh / curses.c < prev    next >
Text File  |  1993-01-24  |  12KB  |  453 lines

  1.  
  2. /*
  3.  *  This is a screen management library borrowed with permission from the
  4.  *  Elm mail system (a great mailer--I highly recommend it!).
  5.  *
  6.  *  I've hacked this library to only provide what Tass needs.
  7.  *
  8.  *  Original copyright follows:
  9.  */
  10.  
  11. /*******************************************************************************
  12.  *  The Elm Mail System  -  $Revision: 2.1 $   $State: Exp $
  13.  *
  14.  *                     Copyright (c) 1986 Dave Taylor
  15.  ******************************************************************************/
  16.  
  17. #include <stdio.h>
  18. #ifndef        OSK
  19. #include <curses.h>
  20. #include <sys/ioctl.h>
  21. #else  /* OSK */
  22. #include <termcap.h>
  23. #include <sgstat.h>
  24. char   PC_, *UP, *BC;
  25. short  ospeed;
  26. #endif /* OSK */
  27. #include "tass.h"
  28.  
  29. #define                BACKSPACE       '\b'
  30. #define                VERY_LONG_STRING        2500
  31.  
  32. int LINES=23;
  33. int COLS=80;
  34.  
  35. int inverse_okay = TRUE;
  36.  
  37. /*
  38. #ifdef BSD
  39. #  ifndef BSD4_1
  40. #    include <sgtty.h>
  41. #  else
  42. #    include <termio.h>
  43. #  endif
  44. # else
  45. #  include <termio.h>
  46. #endif
  47. */
  48.  
  49. #include <ctype.h>
  50.  
  51. /*
  52. #ifdef BSD
  53. #undef tolower
  54. #endif
  55. */
  56.  
  57. #define TTYIN  0
  58.  
  59. #ifdef SHORTNAMES
  60. # define _clearinverse _clrinv
  61. # define _cleartoeoln  _clrtoeoln
  62. # define _cleartoeos   _clr2eos
  63. #endif
  64.  
  65. #ifndef BSD
  66. #ifndef        OSK
  67. struct termio _raw_tty, 
  68.               _original_tty;
  69. #else  /* OSK */
  70. struct sgbuf   _raw_tty, 
  71.                _original_tty;
  72. #endif /* OSK */
  73. #else
  74. #define TCGETA TIOCGETP
  75. #define TCSETAW        TIOCSETP
  76.  
  77. struct sgttyb _raw_tty,
  78.              _original_tty;
  79. #endif
  80.  
  81. static int _inraw = 0;                  /* are we IN rawmode?    */
  82.  
  83. #define DEFAULT_LINES_ON_TERMINAL      24
  84. #define DEFAULT_COLUMNS_ON_TERMINAL    80
  85.  
  86. static int _memory_locked = 0;         /* are we IN memlock??   */
  87.  
  88. static int _intransmit;                        /* are we transmitting keys? */
  89.  
  90. static
  91. char *_clearscreen, *_moveto, *_cleartoeoln, *_cleartoeos,
  92.        *_setinverse, *_clearinverse, *_setunderline, *_clearunderline;
  93.  
  94. # define       K_UP            0
  95. # define       K_DOWN          1
  96. # define       K_LEFT          2
  97. # define       K_RIGHT         3
  98. # define       K_PUP           4
  99. # define       K_PDOWN         5
  100.  
  101. # define       K_MAX           6
  102.  
  103. static
  104. char *_spckey[K_MAX];
  105. static
  106. char *_spckeytc[K_MAX] = {
  107.        "ku", "kd", "kl", "kr", "kP", "kN"
  108. };
  109.  
  110. static
  111. int _lines,_columns;
  112.  
  113. static char _terminal[1024];              /* Storage for terminal entry */
  114. static char _capabilities[1024];           /* String for cursor motion */
  115.  
  116. static char *ptr = _capabilities;      /* for buffering         */
  117.  
  118. int    outchar();                      /* char output for tputs */
  119. char  *tgetstr(),                     /* Get termcap capability */
  120.       *tgoto();                                /* and the goto stuff    */
  121.  
  122. InitScreen()
  123. {
  124. int  tgetent(),      /* get termcap entry */
  125.      err;
  126. char termname[40];
  127. char *strcpy(), *getenv();
  128. int i;
  129.        
  130.        if (getenv("TERM") == NULL) {
  131.                fprintf(stderr,
  132.                  "TERM variable not set; Tass requires screen capabilities\n");
  133.                return(FALSE);
  134.        }
  135.        if (strcpy(termname, getenv("TERM")) == NULL) {
  136.                fprintf(stderr,"Can't get TERM variable\n");
  137.                return(FALSE);
  138.        }
  139.        if ((err = tgetent(_terminal, termname)) != 1) {
  140.                fprintf(stderr,"Can't get entry for TERM\n");
  141.                return(FALSE);
  142.        }
  143.  
  144.        /* load in all those pesky values */
  145.        _clearscreen       = tgetstr("cl", &ptr);
  146.        _moveto            = tgetstr("cm", &ptr);
  147.        _cleartoeoln       = tgetstr("ce", &ptr);
  148.        _cleartoeos        = tgetstr("cd", &ptr);
  149.        _lines             = tgetnum("li");
  150.        _columns           = tgetnum("co");
  151.        _setinverse        = tgetstr("so", &ptr);
  152.        _clearinverse      = tgetstr("se", &ptr);
  153.        _setunderline      = tgetstr("us", &ptr);
  154.        _clearunderline    = tgetstr("ue", &ptr);
  155.  
  156.        if (!_clearscreen) {
  157.                fprintf(stderr,
  158.                        "Terminal must have clearscreen (cl) capability\n");
  159.                return(FALSE);
  160.        }
  161.        if (!_moveto) {
  162.                fprintf(stderr,
  163.                        "Terminal must have cursor motion (cm)\n");
  164.                return(FALSE);
  165.        }
  166.        if (!_cleartoeoln) {
  167.                fprintf(stderr,
  168.                        "Terminal must have clear to end-of-line (ce)\n");
  169.                return(FALSE);
  170.        }
  171.        if (!_cleartoeos) {
  172.                fprintf(stderr,
  173.                        "Terminal must have clear to end-of-screen (cd)\n");
  174.                return(FALSE);
  175.        }
  176.        if (_lines == -1)
  177.                _lines = DEFAULT_LINES_ON_TERMINAL;
  178.        if (_columns == -1)
  179.                _columns = DEFAULT_COLUMNS_ON_TERMINAL;
  180.  
  181.        for (i = 0; i < K_MAX; ++i)
  182.                _spckey[i] = tgetstr (_spckeytc[i], &ptr);
  183.  
  184.        return(TRUE);
  185. }
  186.  
  187. ScreenSize(lines, columns)
  188. int *lines, *columns;
  189. {
  190.        /** returns the number of lines and columns on the display. **/
  191.  
  192.        if (_lines == 0) _lines = DEFAULT_LINES_ON_TERMINAL;
  193.        if (_columns == 0) _columns = DEFAULT_COLUMNS_ON_TERMINAL;
  194.  
  195.        *lines = _lines - 1;            /* assume index from zero*/
  196.        *columns = _columns;            /* assume index from one */
  197. }
  198.  
  199. ClearScreen()
  200. {
  201.        /* clear the screen: returns -1 if not capable */
  202.  
  203.        tputs(_clearscreen, 1, outchar);
  204.        fflush(stdout);      /* clear the output buffer */
  205. }
  206.  
  207. MoveCursor(row, col)
  208. int row, col;
  209. {
  210.        /** move cursor to the specified row column on the screen.
  211.             0,0 is the top left! **/
  212.  
  213.        char *stuff, *tgoto();
  214.  
  215.        stuff = tgoto(_moveto, col, row);
  216.        tputs(stuff, 1, outchar);
  217.        fflush(stdout);
  218. }
  219.  
  220. CleartoEOLN()
  221. {
  222.        /** clear to end of line **/
  223.  
  224.        tputs(_cleartoeoln, 1, outchar);
  225.        fflush(stdout);  /* clear the output buffer */
  226. }
  227.  
  228. CleartoEOS()
  229. {
  230.        /** clear to end of screen **/
  231.  
  232.        tputs(_cleartoeos, 1, outchar);
  233.        fflush(stdout);  /* clear the output buffer */
  234. }
  235.  
  236. StartInverse()
  237. {
  238.        /** set inverse video mode **/
  239.  
  240.        if (_setinverse && inverse_okay)
  241.                tputs(_setinverse, 1, outchar);
  242. /*     fflush(stdout); */
  243. }
  244.  
  245.  
  246. EndInverse()
  247. {
  248.        /** compliment of startinverse **/
  249.  
  250.        if (_clearinverse && inverse_okay)
  251.                tputs(_clearinverse, 1, outchar);
  252. /*     fflush(stdout); */
  253. }
  254.  
  255. #if 0
  256. StartUnderline()
  257. {
  258.        /** start underline mode **/
  259.  
  260.        if (!_setunderline)
  261.                return(-1);
  262.  
  263.        tputs(_setunderline, 1, outchar);
  264.        fflush(stdout);
  265.        return(0);
  266. }
  267.  
  268.  
  269. EndUnderline()
  270. {
  271.        /** the compliment of start underline mode **/
  272.  
  273.        if (!_clearunderline)
  274.                return(-1);
  275.  
  276.        tputs(_clearunderline, 1, outchar);
  277.        fflush(stdout);
  278.        return(0);
  279. }
  280. #endif
  281.  
  282. RawState()
  283. {
  284.        /** returns either 1 or 0, for ON or OFF **/
  285.  
  286.        return( _inraw );
  287. }
  288.  
  289. Raw(state)
  290. int state;
  291. {
  292.        /** state is either TRUE or FALSE, as indicated by call **/
  293.  
  294.        if (state == FALSE && _inraw) {
  295. #ifndef        OSK
  296.          (void) ioctl(TTYIN, TCSETAW, &_original_tty);
  297. #else  /* OSK */
  298.          (void) _ss_opt (TTYIN, &_original_tty);
  299. #endif /* OSK */
  300.          _inraw = 0;
  301.        }
  302.        else if (state == TRUE && ! _inraw) {
  303.  
  304. #ifndef        OSK
  305.          (void) ioctl(TTYIN, TCGETA, &_original_tty);  /** current setting **/
  306.  
  307.          (void) ioctl(TTYIN, TCGETA, &_raw_tty);    /** again! **/
  308. #ifdef BSD
  309.          _raw_tty.sg_flags &= ~(ECHO | CRMOD); /* echo off */
  310.          _raw_tty.sg_flags |= CBREAK;  /* raw on    */
  311. #else
  312.          _raw_tty.c_lflag &= ~(ICANON | ECHO); /* noecho raw mode        */
  313.  
  314.          _raw_tty.c_cc[VMIN] = '\01';  /* minimum # of chars to queue    */
  315.          _raw_tty.c_cc[VTIME] = '\0';  /* minimum time to wait for input */
  316.  
  317. #endif
  318.          (void) ioctl(TTYIN, TCSETAW, &_raw_tty);
  319. #else  /* OSK */
  320.          (void) _gs_opt (TTYIN, &_original_tty);
  321.          _raw_tty = _original_tty;
  322.          _raw_tty.sg_echo = 0;
  323.          _raw_tty.sg_pause = 0;
  324.          _raw_tty.sg_alf = 0;
  325.          _raw_tty.sg_psch = 0;
  326.          _raw_tty.sg_eofch = 0;
  327.          
  328.          (void) _ss_opt (TTYIN, &_raw_tty);
  329. #endif /* OSK */
  330.  
  331.          _inraw = 1;
  332.        }
  333. }
  334.  
  335. int
  336. ReadCh()
  337. {
  338.        /** read a character with Raw mode set! **/
  339.  
  340.        register int result;
  341.        char ch;
  342.        register int i, j, n;
  343.        register char *spc;
  344.  
  345.        spc = NULL;
  346.        do {
  347.                if (spc) {
  348. #ifdef OSK
  349.                        tsleep (4);
  350.                        if (_gs_rdy (0) < 1)
  351.                                tsleep (50 | (1 << 31));
  352.                        if (_gs_rdy (0) < 1)
  353. #else  /* OSK */
  354. #ifdef FIONREAD
  355. #define        CH_READ         FIONREAD
  356. #else  /* FIONREAD */
  357. #ifdef TCRDCHK
  358. #define        CH_READ         TCRDCHK
  359. #else  /* TCRDCHK */
  360.        Panic!
  361. #endif /* TCRDCHK */
  362. #endif /* FIONREAD */
  363.                        int tmp;
  364.  
  365.                        ioctl (0, CH_READ, &tmp);
  366.                        if (tmp < 1)
  367.                                nap (200);
  368.                        ioctl (0, CH_READ, &tmp);
  369.                        if (tmp < 1)
  370. #endif /* OSK */
  371.                                spc = NULL;
  372.                }
  373.                if ((result = read(0, &ch, 1)) != 1)
  374.                        break;
  375.                if (!spc) {
  376.                        for (i = 0; i < K_MAX; ++i)
  377.                                if (_spckey[i] && (_spckey[i][0] == ch)) {
  378.                                        spc = _spckey[i];
  379.                                        n = 1;
  380.                                        break;
  381.                                }
  382.                } else if (ch != spc[n]) {
  383.                        for (j = 0; j < K_MAX; ++j)
  384.                                if (!_spckey[j])
  385.                                        continue;
  386.                                else if (spc[0]) {
  387.                                        if ((!strncmp (spc, _spckey[j], n - 1)) && (_spckey[j][n] == ch))
  388.                                                break;
  389.                                } else if (spc[0] == _spckey[j][0]) {
  390.                                        if (n > 1) {
  391.                                                if ((!strncmp (spc + 1, _spckey[j] + 1, n - 2)) && (_spckey[j][n] == ch))
  392.                                                        break;
  393.                                        } else if (_spckey[j][n] == ch)
  394.                                                break;
  395.                                }
  396.                        if (j < K_MAX) {
  397.                                spc = _spckey[j];
  398.                                i = j;
  399.                                ++n;
  400.                        } else {
  401.                                spc = NULL;
  402.                                result = -1;
  403.                        }
  404.                } else
  405.                        ++n;
  406.                if (spc && (!spc[n])) {
  407.                        spc = NULL;
  408.                        switch (i) {
  409.                                case K_UP:
  410.                                        ch = ctrl('P');
  411.                                        break;
  412.                                case K_DOWN:
  413.                                        ch = ctrl('N');
  414.                                        break;
  415.                                case K_LEFT:
  416.                                        ch = ctrl('B');
  417.                                        break;
  418.                                case K_RIGHT:
  419.                                        ch = ctrl('F');
  420.                                        break;
  421.                                case K_PUP:
  422.                                        ch = ctrl('Z');
  423.                                        break;
  424.                                case K_PDOWN:
  425.                                        ch = ctrl('V');
  426.                                        break;
  427.                        }
  428.                }
  429.        } while (spc || (result < 0));
  430.         return((result <= 0 ) ? EOF : ch & 0x7F);
  431. }
  432.  
  433.  
  434. outchar(c)
  435. char c;
  436. {
  437.        /** output the given character.  From tputs... **/
  438.        /** Note: this CANNOT be a macro!              **/
  439.  
  440.        putc(c, stdout);
  441. }
  442.  
  443. #ifdef NO_NAP
  444. nap (n)
  445. int n;
  446. {
  447.        int     t;
  448.  
  449.        for (t = 100 * n; t > 0; --t)
  450.                ;
  451. }
  452. #endif /* NO_NAP */
  453.