home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / CURSES.LZH / CHARGET.C < prev    next >
C/C++ Source or Header  |  1980-01-01  |  9KB  |  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();        /* get raw char via BIOS */
  31. static    int    sysgetch();        /* get char via system */
  32. static    int    validchar();        /* 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.