home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / cprog / cursesp.zip / CHARGET.C < prev    next >
C/C++ Source or Header  |  1991-12-02  |  11KB  |  261 lines

  1. /****************************************************************/
  2. /* Getch() routines of the PCcurses package                     */
  3. /*                                                              */
  4. /****************************************************************/
  5. /* This version of curses is based on ncurses, a curses version */
  6. /* originally written by Pavel Curtis at Cornell University.    */
  7. /* I have made substantial changes to make it run on IBM PC's,  */
  8. /* and therefore consider myself free to make it public domain. */
  9. /*              Bjorn Larsson (...mcvax!enea!infovax!bl)        */
  10. /****************************************************************/
  11. /* 1.0: Release:                                        870515  */
  12. /* 1.1: Bug fixes: call to _curseskeytest() changed             */
  13. /*      _curseskeytst(). Test of that routine also              */
  14. /*      lacked () in one place:                         870907  */
  15. /* 1.2: #undef:ine of getch now covers all the file, to         */
  16. /*      make sure this module's getch() calls go to DOS,        */
  17. /*      not to the PCCurses 'getch()' function. Fixed           */
  18. /*      thanks to N.D. Pentcheff:                       881002  */
  19. /* 1.3: MSC -W3, Turbo'C' -w -w-pro checkes:            881005  */
  20. /****************************************************************/
  21.  
  22. #include <curses.h>
  23. #include <curspriv.h>
  24.  
  25. #undef getch                            /* We use MSC getch() below */
  26. #undef ungetch
  27.  
  28. #include <conio.h>
  29.  
  30. static  int     rawgetch(void);         /* get raw char via BIOS */
  31. static  int     sysgetch(void);         /* get char via system */
  32. static  int     validchar(int);         /* keypad xlate and char check */
  33.  
  34. char _curses_charget_rcsid[] = "@(#)charget.c v1.3 - 881005";
  35.  
  36. static  int     buffer[_INBUFSIZ];      /* character buffer */
  37. static  int     pindex = 0;             /* putter index */
  38. static  int     gindex = 1;             /* getter index */
  39. static  WINDOW *w;                      /* to reduce stack usage */
  40. static  int     ungind = 0;             /* wungetch() push index */
  41. static  int     ungch[NUNGETCH];        /* array of ungotten chars */
  42.  
  43. /* Table for key code translation of function keys in keypad mode */
  44. /* These values are for strict IBM keyboard compatibles only */
  45.  
  46. static  int     kptab[] =
  47.   {
  48.   0x3b,KEY_F(1),  0x3c,KEY_F(2),  0x3d,KEY_F(3),  0x3e,KEY_F(4),
  49.   0x3f,KEY_F(5),  0x40,KEY_F(6),  0x41,KEY_F(7),  0x42,KEY_F(8),
  50.   0x43,KEY_F(9),  0x44,KEY_F(10), 0x47,KEY_HOME,  0x48,KEY_UP,
  51.   0x49,KEY_PPAGE, 0x4b,KEY_LEFT,  0x4d,KEY_RIGHT, 0x4f,KEY_LL,
  52.   0x50,KEY_DOWN,  0x51,KEY_NPAGE, 0x52,KEY_IC,    0x53,KEY_DC,
  53.   0x54,KEY_F(11), 0x55,KEY_F(12), 0x56,KEY_F(13), 0x57,KEY_F(14),
  54.   0x58,KEY_F(15), 0x59,KEY_F(16), 0x5a,KEY_F(17), 0x5b,KEY_F(18),
  55.   0x5c,KEY_F(19), 0x5d,KEY_F(20), 0x5e,KEY_F(21), 0x5f,KEY_F(22),
  56.   0x60,KEY_F(23), 0x61,KEY_F(24), 0x62,KEY_F(25), 0x63,KEY_F(26),
  57.   0x64,KEY_F(27), 0x65,KEY_F(28), 0x66,KEY_F(29), 0x67,KEY_F(30),
  58.   0x73,KEY_LEFT,  0x74,KEY_RIGHT,  0x75,KEY_LL,   0x76,KEY_NPAGE,
  59.   0x77,KEY_HOME,  0x84,KEY_PPAGE,  0x100,        -1
  60.   };
  61.  
  62.  
  63. /****************************************************************/
  64. /* Wgetch(win) gets a character from the terminal, in normal,   */
  65. /* cbreak or raw mode, optionally echoing to window  'win'.     */
  66. /****************************************************************/
  67.  
  68. int wgetch(win)
  69.   WINDOW        *win;
  70.   {
  71.   int key;
  72.   int cbr;
  73.  
  74.   if (ungind)                                   /* if ungotten char exists */
  75.     return(ungch[--ungind]);                    /* remove and return it */
  76.  
  77.   if ((!_cursvar.raw) && (!_cursvar.cbreak))    /* if normal */
  78.     if (gindex < pindex)                        /* and data in buffer */
  79.       return(buffer[gindex++]);
  80.  
  81.   w = win;                                      /* static for speed & stack */
  82.   pindex = 0;                                   /* prepare to buffer data */
  83.   gindex = 0;
  84.   while(1)                                      /* loop for any buffering */
  85.     {
  86.     if (_cursvar.raw)                           /* get a raw character */
  87.       key = rawgetch();
  88.     else                                        /* get a system character */
  89.       {
  90.       cbr = _cursesgcb();                       /* get ^BREAK status */
  91.       _cursesscb(_cursvar.orgcbr);              /* if break return proper */
  92.       key = sysgetch();
  93.       _cursesscb(cbr);                          /* restore as it was */
  94.       }
  95.     if (w->_nodelay && (key == -1))             /* if nodelay and no char */
  96.       return(-1);
  97.     if ((key == '\r') && _cursvar.autocr && !_cursvar.raw) /* translate cr */
  98.       key = '\n';
  99.     if (_cursvar.echo && (key < 0x100))         /* check if echo */
  100.       {
  101.       waddch(w,key);
  102.       wrefresh(w);
  103.       }
  104.     if (_cursvar.raw || _cursvar.cbreak)        /* if no buffering */
  105.       return(key);
  106.     if (pindex < _INBUFSIZ-2)                   /* if no overflow, */
  107.       buffer[pindex++] = key;                   /* put data in buffer */
  108.     if ((key == '\n') || (key == '\r'))         /* if we got a line */
  109.       return(buffer[gindex++]);
  110.     } /* while */
  111.   } /* wgetch */
  112.  
  113. /****************************************************************/
  114. /* Flushinp() kills any pending input characters.               */
  115. /****************************************************************/
  116.  
  117. void flushinp()
  118.   {
  119.   while(_curseskeytst())                /* empty keyboard buffer */
  120.     _curseskey();
  121.   while(kbhit())                        /* empty system's buffers */
  122.     (void) getch();
  123.   gindex = 1;                           /* set indices to kill buffer */
  124.   pindex = 0;
  125.   ungind = 0;                           /* clear ungch array */
  126.   } /* flushinp */
  127.  
  128. /****************************************************************/
  129. /* Wungetch() pushes back its argument on the input stream. If  */
  130. /* OK, returns 1, otherwise returns 0.                          */
  131. /****************************************************************/
  132.  
  133. int     wungetch(ch)
  134.   int   ch;
  135.   {
  136.   if (ungind >= NUNGETCH)               /* pushback stack full */
  137.     return(0);
  138.   ungch[ungind++] = ch;
  139.   return(1);
  140.   } /* wungetch() */
  141.  
  142. /****************************************************************/
  143. /* Mvgetch() first moves the stdscr cursor to a new location,   */
  144. /* then does a wgetch() on stdscr.                              */
  145. /****************************************************************/
  146.  
  147. int     mvgetch(y,x)
  148.   int y;
  149.   int x;
  150.   {
  151.   wmove(stdscr,y,x);
  152.   return(wgetch(stdscr));
  153.   } /* mvgetch */
  154.  
  155. /****************************************************************/
  156. /* Mvwgetch() first moves the cursor of window 'win' to a new   */
  157. /* location, then does a wgetch() in 'win'.                     */
  158. /****************************************************************/
  159.  
  160. int mvwgetch(win,y,x)
  161.   WINDOW *win;
  162.   int y;
  163.   int x;
  164.   {
  165.   wmove(win,y,x);
  166.   return(wgetch(win));
  167.   } /* mvwgetch */
  168.  
  169. /****************************************************************/
  170. /* rawgetch() gets a character without any interpretation at    */
  171. /* all and returns it. If keypad mode is active for the desig-  */
  172. /* nated window, function key translation will be performed.    */
  173. /* Otherwise, function keys are ignored.If nodelay mode is      */
  174. /* active in the window, then rawgetch() returns -1 if no cha-  */
  175. /* racter is available.                                         */
  176. /****************************************************************/
  177.  
  178. static int rawgetch()
  179.   {
  180.   int c;
  181.  
  182.   if (w->_nodelay && !_curseskeytst())
  183.     return(-1);
  184.   while(1)                                      /* loop to get valid char */
  185.     {
  186.     if ((c = validchar(_curseskey())) >= 0)
  187.       return(c);
  188.     } /* while */
  189.   } /* rawgetch */
  190.  
  191. /****************************************************************/
  192. /* Sysgetch() gets a character with normal ^S, ^Q, ^P and ^C    */
  193. /* interpretation and returns it. If keypad mode is active for  */
  194. /* the designated window, function key translation will be per- */
  195. /* formed. Otherwise, function keys are ignored. If nodelay     */
  196. /* mode is active in the window, then sysgetch() returns -1 if  */
  197. /* no character is available.                                   */
  198. /****************************************************************/
  199.  
  200. static int sysgetch()
  201.   {
  202.   int c;
  203.  
  204.   if (w->_nodelay && !kbhit())
  205.     return(-1);
  206.   while(1)
  207.     {
  208.     c = getch();
  209.     if (c)                                      /* if not a function key */
  210.       return(c & 0xff);                         /* avoids sign-extending */
  211.     c = getch();
  212.     if ((c = validchar(c << 8)) >= 0)           /* get & check next char */
  213.       return(c);
  214.     } /* while */
  215.   } /* sysgetch */
  216.  
  217. /****************************************************************/
  218. /* Validchar(c) chacks that 'c' is a valid character, and       */
  219. /* if so returns it, with function key translation applied if   */
  220. /* 'w' has keypad mode set. If char is invalid, returns -1.     */
  221. /****************************************************************/
  222.  
  223. static int validchar(c)
  224.   int   c;
  225.   {
  226.   int *scanp;
  227.  
  228.   if (c == 0x0300)                      /* special case, ^@ = NULL */
  229.     return(0);
  230.   if (!(c & 0xff00))                    /* normal character */
  231.     return(c);
  232.   if (!(w->_keypad))                    /* skip f keys if not keypad mode */
  233.     return(-1);
  234.   c = (c >> 8) & 0xff;
  235.   scanp = kptab;
  236.   while(*scanp <= c)                    /* search for value */
  237.     {                                   /* (stops on table entry 0x100) */
  238.     if (*scanp++ == c)
  239.       return(*scanp);                   /* found, return it */
  240.     scanp++;
  241.     }
  242.   return(-1);                           /* not found, invalid */
  243.   } /* validchar */
  244.  
  245. /****************************************************************/
  246. /* _cursespendch() returns 1 if there is any character avai-    */
  247. /* lable, and 0 if there is none. This is not for programmer    */
  248. /* usage, but for the updatew routines.                         */
  249. /****************************************************************/
  250.  
  251. bool    _cursespendch()
  252.   {
  253.   if (ungind)                           /* ungotten char */
  254.     return(TRUE);
  255.   if (pindex > gindex)                  /* buffered char */
  256.     return(TRUE);
  257.   if (_cursvar.raw)                     /* raw mode test */
  258.     return(_curseskeytst());
  259.   return((bool)kbhit());                /* normal mode test */
  260.   } /* _cursespendch */
  261.