home *** CD-ROM | disk | FTP | other *** search
/ Computer Club Elmshorn Atari PD / CCE_PD.iso / pc / 0600 / CCE_0638.ZIP / CCE_0638 / GNULIB / LIBSRC93.ZOO / console.c < prev    next >
C/C++ Source or Header  |  1992-06-03  |  4KB  |  222 lines

  1. /* 
  2.  * console input/output routines.
  3.  * written by Eric R. Smith and placed in the public domain
  4.  */
  5.  
  6. /*
  7.  * BUGS: assumes that all tty handles >= 0 are console handles.
  8.  * If we have some handles >= 0 not attached to the console,
  9.  * and some other handles attached to a different device, we might
  10.  * get characters mixed up. This will generally not be a problem,
  11.  * since earlier versions of the library forbid any non-console
  12.  * devices entirely.
  13.  */
  14.  
  15. #include <osbind.h>
  16. #include <support.h>
  17. #include <stdlib.h>
  18. #include <ioctl.h>
  19. #include <tchars.h>
  20. #include <signal.h>
  21. #include <unistd.h>
  22. #ifndef _COMPILER_H
  23. #include <compiler.h>
  24. #endif
  25.  
  26. extern int _console_dev;    /* in main.c */
  27. int __check_signals = 0;
  28.  
  29. #define KBUFSIZ 80
  30. #define NUMDEV    3
  31.     /* 0 == prn:, 1 == aux:, 2 == con: */
  32.  
  33. typedef struct _buffer {
  34.     short head, tail;
  35.     long  buffer[KBUFSIZ];
  36. } k_buf;
  37.  
  38. k_buf in_buf[NUMDEV];
  39.  
  40. #define in_dev(dev) ((dev)>2 ? _console_dev : (dev))
  41.  
  42. #define IN_BUF(dev) (&in_buf[in_dev(dev)])
  43.  
  44. /*
  45.  * what handle means:: 0-2: BIOS handle, 3: stdout, 4: stderr
  46.  */
  47. static short LOOKUP __PROTO((short handle));
  48. static long raw_in __PROTO((int dev));
  49. static long raw_instat __PROTO((int dev));
  50. void flush_key_buff __PROTO((int dev));
  51. #if 0
  52. static void raw_out __PROTO((int dev, int c));
  53. #endif
  54.  
  55. static short
  56. #ifdef __STDC__
  57. LOOKUP(short handle)
  58. #else
  59. LOOKUP(handle)
  60. short handle;
  61. #endif
  62. {
  63.     switch(handle) {
  64.     case -3:
  65.     case -2:
  66.     case -1:
  67.     case 0:
  68.         return handle + 3;
  69.     case 2:
  70.         return 4;
  71.     case 1:
  72.         if (isatty(0)) return 3;
  73.         if (isatty(2)) return 4;
  74.         /* else fall through */
  75.     default:
  76.         return _console_dev;
  77.     }
  78. }
  79.  
  80. /*
  81.  * raw i/o routines
  82.  */
  83.  
  84. static long
  85. raw_in(dev)
  86. int dev;
  87. {
  88.   if (dev < 3)
  89.     return Bconin (dev);
  90.   else if (dev == 3)
  91.     return Crawcin ();
  92.   else
  93.     return Cauxin ();
  94. }
  95.  
  96. #if 0
  97. static void
  98. raw_out(dev, c)
  99. int dev, c;
  100. {
  101.     if (dev < 3)
  102.         Bconout(dev, c);
  103.     else if (dev == 3)
  104.         (void)Crawio(c);
  105.     else
  106.         Cauxout(c);
  107. }
  108. #endif
  109.  
  110. static long
  111. raw_instat(dev)
  112. int dev;
  113. {
  114.     return Bconstat(in_dev(dev));
  115. }
  116.  
  117. /*
  118.  * somewhat less raw i/o routines. The main difference is that these ones
  119.  * will check for pending input before doing output, to see if a signal
  120.  * needs to be raised. This is only done if __check_signals is non-zero;
  121.  * signal() should set __check_signals when the user attempts to catch
  122.  * SIGINT or SIGQUIT. We don't do this checking all the time because
  123.  * the user may be typing ahead input for another program (e.g. if this
  124.  * is a little utility of some sort) and we shouldn't steal keystrokes
  125.  * unless necessary.
  126.  */
  127.  
  128. unsigned int console_read_byte(handle)
  129. int handle;
  130. {
  131.     k_buf *p;
  132.     short i, j, dev;
  133.     long r;
  134.  
  135.     dev = LOOKUP(handle);
  136.  
  137.     p = IN_BUF(dev);
  138.     if ( p->head != (i = p->tail)) {
  139.         j = p->tail + 1;
  140.         if (j >= KBUFSIZ)
  141.             j = 0;
  142.         p->tail = j;
  143.         r = p->buffer[i];
  144.     }
  145.     else
  146.         r = raw_in(dev);
  147.  
  148.     return r;
  149. }
  150.  
  151. int console_input_status(handle)
  152. int handle;
  153. {
  154.     short dev;
  155.     k_buf *p;
  156.  
  157.     dev = LOOKUP(handle);
  158.     p = IN_BUF(dev);
  159.     return (p->head != p->tail) || raw_instat(dev);
  160. }
  161.  
  162. void
  163. console_write_byte(handle, n)
  164. int handle;
  165. int n;
  166. {
  167.     char ch;
  168.  
  169.     if (__check_signals)
  170.         flush_key_buff(handle);
  171.     ch = n;
  172.     (void)Fwrite(handle, 1L, &ch);
  173. }
  174.  
  175. void flush_key_buff(fd)  
  176. int fd;
  177.     long c;
  178.     short i, j, waiting = 0;
  179.     unsigned char ch;
  180.     k_buf *p;
  181.     short dev;
  182.     short handle;
  183.     
  184.     handle = fd;
  185.     
  186.     dev = LOOKUP(handle);
  187.     p = IN_BUF(dev);
  188.     
  189.     while (raw_instat(dev) || waiting) 
  190.     { 
  191.     c = raw_in(dev);
  192.     if (!(__ttymode & RAW)) 
  193.     {
  194.         ch = c & 0xff;
  195.         if (ch == ('S'-'@')) { waiting = 1; }
  196.         else if (ch == ('Q'-'@')) { waiting = 0; }
  197.         else if (ch == (unsigned char)__tchars[TC_INTRC]) 
  198.         { 
  199.         p->head = p->tail;
  200.         raise(SIGINT);
  201.         }
  202.         else if (ch == (unsigned char)__tchars[TC_QUITC]) 
  203.         { 
  204.         p->head = p->tail;
  205.         raise(SIGQUIT);
  206.         }
  207.         else if (!waiting) 
  208.         { 
  209.         i = p->head;
  210.         j = i + 1;
  211.         if (j >= KBUFSIZ) j = 0;
  212.         if (j != p->tail) 
  213.         { 
  214.             p->buffer[i] = c;
  215.             p->head = j;
  216.         }
  217.         }
  218.     }
  219.     }
  220. }
  221.