home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / curses / crssrc12.zoo / src / xconsole.c < prev   
Encoding:
C/C++ Source or Header  |  1992-04-27  |  5.0 KB  |  283 lines

  1. /* Replacement console read/write routines that allow for key
  2.    remappings */
  3. /* 
  4.  * console input/output routines.
  5.  * written by Eric R. Smith and placed in the public domain
  6.  */
  7.  
  8. /*
  9.  * BUGS: assumes all input is coming from the same place;
  10.  * this bug shows up only when keys are remapped, though.
  11.  */
  12.  
  13. #include <osbind.h>
  14. #include <support.h>
  15. #include <stdlib.h>
  16. #include <ioctl.h>
  17. #include <tchars.h>
  18. #include <signal.h>
  19. #include <unixlib.h>
  20. #include <keycodes.h>
  21. #include <string.h>
  22.  
  23. #define STRDUP(x,y) if (x) free(x); x = strdup(y);
  24.  
  25. #define S_SHIFT 0x03
  26. #define S_CNTRL    0x04
  27. #define S_ALT    0x08
  28.  
  29. extern int _console_dev;    /* in main.c */
  30. int __check_signals = 0;
  31.  
  32. /* arrays to hold keyboard strings */
  33.  
  34. static char *kb_unshft[N_KEYCODES], *kb_shft[N_KEYCODES], *kb_alt[N_KEYCODES];
  35. static char *_str = NULL;
  36.  
  37. void console_set_key(keycode, regular, shifted, alted)
  38. int keycode;
  39. char *regular, *shifted, *alted;
  40. {
  41.     if (keycode < 1 || keycode >= N_KEYCODES)
  42.         return;
  43.  
  44.     if (regular) {
  45.         if (!*regular) regular = 0;
  46.         STRDUP(kb_unshft[keycode],regular);
  47.     }
  48.     if (shifted) {
  49.         if (!*shifted) shifted = 0;
  50. /* shifted function keys are a bit screwy */
  51.         if (keycode >= F_1 && keycode <= F_10) {
  52.             STRDUP(kb_shft[keycode - F_1 + 0x54],shifted);
  53.         }
  54.         else {
  55.             STRDUP(kb_shft[keycode],shifted);
  56.         }
  57.     }
  58.     if (alted) {
  59.         if (!*alted) alted = 0;
  60.         STRDUP(kb_alt[keycode],alted);
  61.     }
  62. }
  63.  
  64. #define KBUFSIZ 80
  65. #define NUMDEV    3
  66.     /* 0 == prn:, 1 == aux:, 2 == con: */
  67.  
  68. typedef struct _buffer {
  69.     short head, tail;
  70.     long  buffer[KBUFSIZ];
  71. } k_buf;
  72.  
  73. static k_buf in_buf[NUMDEV];
  74.  
  75. #define in_dev(dev) ((dev)>2 ? _console_dev : (dev))
  76.  
  77. #define IN_BUF(dev) (&in_buf[in_dev(dev)])
  78.  
  79.  
  80. /*
  81.  * what handle means:: 0-2: BIOS handle, 3: stdout, 4: stderr
  82.  */
  83. static short LOOKUP __PROTO((short handle));
  84. static long raw_in __PROTO((int dev));
  85. static long raw_instat __PROTO((int dev));
  86. void flush_key_buff __PROTO((int dev));
  87. #if 0
  88. static void raw_out __PROTO((int dev, int c));
  89. #endif
  90.  
  91. static short
  92. #ifdef __STDC__
  93. LOOKUP(short handle)
  94. #else
  95. LOOKUP(handle)
  96. short handle;
  97. #endif
  98. {
  99.     switch(handle) {
  100.     case -3:
  101.     case -2:
  102.     case -1:
  103.     case 0:
  104.         return handle + 3;
  105.     case 2:
  106.         return 4;
  107.     case 1:
  108.         if (isatty(0)) return 3;
  109.         if (isatty(2)) return 4;
  110.         /* else fall through */
  111.     default:
  112.         return _console_dev;
  113.     }
  114. }
  115.  
  116. /*
  117.  * raw i/o routines
  118.  */
  119.  
  120. static long
  121. raw_in(dev)
  122. int dev;
  123. {
  124.   if (dev < 3)
  125.     return Bconin (dev);
  126.   else if (dev == 3)
  127.     return Crawcin ();
  128.   else
  129.     return Cauxin ();
  130. }
  131.  
  132. #if 0
  133. static void
  134. raw_out(dev, c)
  135. int dev, c;
  136. {
  137.     if (dev < 3)
  138.         Bconout(dev, c);
  139.     else if (dev == 3)
  140.         Crawio(c);
  141.     else
  142.         Cauxout(c);
  143. }
  144. #endif
  145.  
  146. static long
  147. raw_instat(dev)
  148. int dev;
  149. {
  150.     return Bconstat(in_dev(dev));
  151. }
  152.  
  153. /*
  154.  * somewhat less raw i/o routines. The main difference is that these ones
  155.  * will check for pending input before doing output, to see if a signal
  156.  * needs to be raised. This is only done if __check_signals is non-zero;
  157.  * signal() should set __check_signals when the user attempts to catch
  158.  * SIGINT or SIGQUIT. We don't do this checking all the time because
  159.  * the user may be typing ahead input for another program (e.g. if this
  160.  * is a little utility of some sort) and we shouldn't steal keystrokes
  161.  * unless necessary.
  162.  */
  163.  
  164. unsigned int console_read_byte(handle)
  165. int handle;
  166. {
  167.     k_buf *p;
  168.     short i, j, dev;
  169.     unsigned scan, key, shft;
  170.     long r;
  171.  
  172.     dev = LOOKUP(handle);
  173.  
  174.     if (_str) {
  175.         if (*_str)
  176.             return *(unsigned char *)_str++;
  177.         else
  178.             _str = 0;
  179.     }
  180.  
  181.     p = IN_BUF(dev);
  182.     if ( p->head != (i = p->tail)) {
  183.         j = p->tail + 1;
  184.         if (j >= KBUFSIZ)
  185.             j = 0;
  186.         p->tail = j;
  187.         r = p->buffer[i];
  188.     }
  189.     else
  190.         r = raw_in(dev);
  191.  
  192.     scan = (r & 0x00ff0000) >> 16;
  193.     key = r & 0x00ff;
  194.     if (scan > 0 && scan < N_KEYCODES) {
  195.         shft = Kbshift(-1);
  196.         if (shft & S_ALT)
  197.             _str = kb_alt[scan];
  198.         else if (shft & S_SHIFT)
  199.             _str = kb_shft[scan];
  200.         else if (!(shft & S_CNTRL))
  201.             _str = kb_unshft[scan];
  202.         if (_str) return *(unsigned char *)_str++;
  203.     }
  204.     return key;
  205. }
  206.  
  207. int console_input_status(handle)
  208. int handle;
  209. {
  210.     short dev;
  211.     k_buf *p;
  212.  
  213.     if (_str && *_str) return 1;
  214.     dev = LOOKUP(handle);
  215.     p = IN_BUF(dev);
  216.     return (p->head != p->tail) || raw_instat(dev);
  217. }
  218.  
  219. void
  220. console_write_byte(handle, n)
  221. int handle;
  222. int n;
  223. {
  224.     char ch;
  225.     short dev;
  226.  
  227.     dev = LOOKUP(handle);
  228.  
  229.     if (__check_signals)
  230.         flush_key_buff(dev);
  231. /*    raw_out(dev, n); */
  232.     ch = n;
  233.     (void)Fwrite(handle, 1L, &ch);
  234. }
  235.  
  236. void flush_key_buff(fd)  
  237. int fd;
  238.     long c;
  239.     short i, j, waiting = 0;
  240.     unsigned char ch;
  241.     k_buf *p;
  242.     short dev;
  243.     short handle;
  244.     
  245.     handle = fd;
  246.     
  247.     dev = LOOKUP(handle);
  248.     p = IN_BUF(dev);
  249.     
  250.     while (raw_instat(dev) || waiting) 
  251.     { 
  252.     c = raw_in(dev);
  253.     if (!(__ttymode & RAW)) 
  254.     {
  255.         ch = c & 0xff;
  256.         if (ch == ('S'-'@')) { waiting = 1; }
  257.         else if (ch == ('Q'-'@')) { waiting = 0; }
  258.         else if (ch == __tchars[TC_INTRC]) 
  259.         { 
  260.         p->head = p->tail;
  261.         raise(SIGINT);
  262.         }
  263.         else if (ch == __tchars[TC_QUITC]) 
  264.         { 
  265.         p->head = p->tail;
  266.         raise(SIGQUIT);
  267.         }
  268.         else if (!waiting) 
  269.         { 
  270.         i = p->head;
  271.         j = i + 1;
  272.         if (j >= KBUFSIZ) j = 0;
  273.         if (j != p->tail) 
  274.         { 
  275.             p->buffer[i] = c;
  276.             p->head = j;
  277.         }
  278.         }
  279.     }
  280.     }
  281. }
  282.