home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / curses / xconsole.c < prev   
Encoding:
C/C++ Source or Header  |  1993-07-23  |  5.4 KB  |  306 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. #define IN_BUF(dev) (&in_buf[(dev) > 2 ? _console_dev : (dev)])
  75.  
  76. /*
  77.  * what handle means:: 0-2: BIOS handle, 3: stdout, 4: stderr
  78.  */
  79.  
  80. static short
  81. LOOKUP(handle)
  82. short handle;
  83. {
  84.     switch(handle) {
  85.     case -3:
  86.     case -2:
  87.     case -1:
  88.     case 0:
  89.         return handle + 3;
  90.     case 2:
  91.         return 4;
  92.     case 1:
  93.         if (isatty(0)) return 3;
  94.         if (isatty(2)) return 4;
  95.         /* else fall through */
  96.     default:
  97.         return _console_dev;
  98.     }
  99. }
  100.  
  101. /*
  102.  * raw i/o routines
  103.  */
  104.  
  105. static long
  106. raw_in(dev)
  107. int dev;
  108. {
  109.     if (dev < 3)
  110.         return Bconin(dev);
  111.     else if (dev == 3)
  112.         return Crawcin();
  113.     else
  114.         return Cauxin();
  115. }
  116.  
  117. #if 0
  118. static void
  119. raw_out(dev, c)
  120. int dev, c;
  121. {
  122.     if (dev < 3)
  123.         Bconout(dev, c);
  124.     else if (dev == 3)
  125.         Crawio(c);
  126.     else
  127.         Cauxout(c);
  128. }
  129. #endif
  130.  
  131. static long
  132. raw_instat(dev)
  133. int dev;
  134. {
  135.     if (dev < 3)
  136.         return Bconstat(dev);
  137.     else if (dev == 3)
  138.         return Cconis();
  139.     else
  140.         return Cauxis();
  141. }
  142.  
  143. /*
  144.  * somewhat less raw i/o routines. The main difference is that these ones
  145.  * will check for pending input before doing output, to see if a signal
  146.  * needs to be raised. This is only done if __check_signals is non-zero;
  147.  * signal() should set __check_signals when the user attempts to catch
  148.  * SIGINT or SIGQUIT. We don't do this checking all the time because
  149.  * the user may be typing ahead input for another program (e.g. if this
  150.  * is a little utility of some sort) and we shouldn't steal keystrokes
  151.  * unless necessary.
  152.  */
  153.  
  154. unsigned int console_read_byte(handle)
  155. int handle;
  156. {
  157.     k_buf *p;
  158.     short i, j, dev;
  159.     unsigned scan, key, shft;
  160.     long r;
  161.  
  162.     dev = LOOKUP(handle);
  163.  
  164.     if (_str) {
  165.         if (*_str)
  166.             return *(unsigned char *)_str++;
  167.         else
  168.             _str = 0;
  169.     }
  170.  
  171.     p = IN_BUF(dev);
  172.     if ( p->head != (i = p->tail)) {
  173.         j = p->tail + 1;
  174.         if (j >= KBUFSIZ)
  175.             j = 0;
  176.         p->tail = j;
  177.         r = p->buffer[i];
  178.     }
  179.     else
  180.         r = raw_in(dev);
  181.  
  182.     scan = (r & 0x00ff0000) >> 16;
  183.     key = r & 0x00ff;
  184.     if (scan > 0 && scan < N_KEYCODES) {
  185.         shft = Kbshift(-1);
  186.         if (shft & S_ALT)
  187.             _str = kb_alt[scan];
  188.         else if (shft & S_SHIFT)
  189.             _str = kb_shft[scan];
  190.         else if (!(shft & S_CNTRL))
  191.             _str = kb_unshft[scan];
  192.         if (_str) return *(unsigned char *)_str++;
  193.     }
  194.     return key;
  195. }
  196.  
  197. int console_input_status(handle)
  198. int handle;
  199. {
  200.     short dev;
  201.     k_buf *p;
  202.  
  203.     if (_str && *_str) return 1;
  204.     dev = LOOKUP(handle);
  205.     p = IN_BUF(dev);
  206.     return (p->head != p->tail) || raw_instat(dev);
  207. }
  208.  
  209. void
  210. console_write_byte(handle, n)
  211. int handle;
  212. int n;
  213. {
  214.     long c;
  215.     short i, j, waiting = 0;
  216.     unsigned char ch;
  217.     k_buf *p;
  218.     short dev;
  219.  
  220.     dev = LOOKUP(handle);
  221.     p = IN_BUF(dev);
  222.  
  223.     while (__check_signals && (raw_instat(dev) || waiting)) {
  224.         c = raw_in(dev);
  225.         if (!(__ttymode & RAW)) {
  226.             ch = c & 0xff;
  227.             if (ch == ('S'-'@')) {
  228.                 waiting = 1;
  229.             }
  230.             else if (ch == ('Q'-'@')) {
  231.                 waiting = 0;
  232.             }
  233.             else if (ch == __tchars[TC_INTRC]) {
  234.                 p->head = p->tail;
  235.                 raise(SIGINT);
  236.             }
  237.             else if (ch == __tchars[TC_QUITC]) {
  238.                 p->head = p->tail;
  239.                 raise(SIGQUIT);
  240.             }
  241.             else if (!waiting) {
  242.                 i = p->head;
  243.                 j = i + 1;
  244.                 if (j >= KBUFSIZ) j = 0;
  245.                 if (j != p->tail) {
  246.                     p->buffer[i] = c;
  247.                     p->head = j;
  248.                 }
  249.             }
  250.         }
  251.     }
  252. #if 0
  253.     raw_out(dev, n);
  254. #endif
  255.     ch = n;
  256.     (void)Fwrite(handle, 1L, &ch);
  257. }
  258.  
  259. void flush_key_buff(fd)  
  260. int fd;
  261.     long c;
  262.     short i, j, waiting = 0;
  263.     unsigned char ch;
  264.     k_buf *p;
  265.     short dev;
  266.     short handle;
  267.     
  268.     handle = fd;
  269.     
  270.     dev = LOOKUP(handle);
  271.     p = IN_BUF(dev);
  272.     
  273.     while (raw_instat(dev) || waiting) 
  274.     { 
  275.     c = raw_in(dev);
  276.     if (!(__ttymode & RAW)) 
  277.     {
  278.         ch = c & 0xff;
  279.         if (ch == ('S'-'@')) { waiting = 1; }
  280.         else if (ch == ('Q'-'@')) { waiting = 0; }
  281.         else if (ch == __tchars[TC_INTRC]) 
  282.         { 
  283.         p->head = p->tail;
  284.         raise(SIGINT);
  285.         }
  286.         else if (ch == __tchars[TC_QUITC]) 
  287.         { 
  288.         p->head = p->tail;
  289.         raise(SIGQUIT);
  290.         }
  291.         else if (!waiting) 
  292.         { 
  293.         i = p->head;
  294.         j = i + 1;
  295.         if (j >= KBUFSIZ) j = 0;
  296.         if (j != p->tail) 
  297.         { 
  298.             p->buffer[i] = c;
  299.             p->head = j;
  300.         }
  301.         }
  302.     }
  303.     }
  304. }
  305.