home *** CD-ROM | disk | FTP | other *** search
- /*
- * console input/output routines.
- * written by Eric R. Smith and placed in the public domain
- */
-
- /*
- * BUGS: assumes that all tty handles >= 0 are console handles.
- * If we have some handles >= 0 not attached to the console,
- * and some other handles attached to a different device, we might
- * get characters mixed up. This will generally not be a problem,
- * since earlier versions of the library forbid any non-console
- * devices entirely.
- */
-
- #include <osbind.h>
- #include <support.h>
- #include <stdlib.h>
- #include <ioctl.h>
- #include <tchars.h>
- #include <signal.h>
- #include <unistd.h>
- #ifndef _COMPILER_H
- #include <compiler.h>
- #endif
-
- extern int _console_dev; /* in main.c */
- int __check_signals = 0;
-
- #define KBUFSIZ 80
- #define NUMDEV 3
- /* 0 == prn:, 1 == aux:, 2 == con: */
-
- typedef struct _buffer {
- short head, tail;
- long buffer[KBUFSIZ];
- } k_buf;
-
- k_buf in_buf[NUMDEV];
-
- #define in_dev(dev) ((dev)>2 ? _console_dev : (dev))
-
- #define IN_BUF(dev) (&in_buf[in_dev(dev)])
-
- /*
- * what handle means:: 0-2: BIOS handle, 3: stdout, 4: stderr
- */
- static short LOOKUP __PROTO((short handle));
- static long raw_in __PROTO((int dev));
- static long raw_instat __PROTO((int dev));
- void flush_key_buff __PROTO((int dev));
- #if 0
- static void raw_out __PROTO((int dev, int c));
- #endif
-
- static short
- #ifdef __STDC__
- LOOKUP(short handle)
- #else
- LOOKUP(handle)
- short handle;
- #endif
- {
- switch(handle) {
- case -3:
- case -2:
- case -1:
- case 0:
- return handle + 3;
- case 2:
- return 4;
- case 1:
- if (isatty(0)) return 3;
- if (isatty(2)) return 4;
- /* else fall through */
- default:
- return _console_dev;
- }
- }
-
- /*
- * raw i/o routines
- */
-
- static long
- raw_in(dev)
- int dev;
- {
- if (dev < 3)
- return Bconin (dev);
- else if (dev == 3)
- return Crawcin ();
- else
- return Cauxin ();
- }
-
- #if 0
- static void
- raw_out(dev, c)
- int dev, c;
- {
- if (dev < 3)
- Bconout(dev, c);
- else if (dev == 3)
- (void)Crawio(c);
- else
- Cauxout(c);
- }
- #endif
-
- static long
- raw_instat(dev)
- int dev;
- {
- return Bconstat(in_dev(dev));
- }
-
- /*
- * somewhat less raw i/o routines. The main difference is that these ones
- * will check for pending input before doing output, to see if a signal
- * needs to be raised. This is only done if __check_signals is non-zero;
- * signal() should set __check_signals when the user attempts to catch
- * SIGINT or SIGQUIT. We don't do this checking all the time because
- * the user may be typing ahead input for another program (e.g. if this
- * is a little utility of some sort) and we shouldn't steal keystrokes
- * unless necessary.
- */
-
- unsigned int console_read_byte(handle)
- int handle;
- {
- k_buf *p;
- short i, j, dev;
- long r;
-
- dev = LOOKUP(handle);
-
- p = IN_BUF(dev);
- if ( p->head != (i = p->tail)) {
- j = p->tail + 1;
- if (j >= KBUFSIZ)
- j = 0;
- p->tail = j;
- r = p->buffer[i];
- }
- else
- r = raw_in(dev);
-
- return r;
- }
-
- int console_input_status(handle)
- int handle;
- {
- short dev;
- k_buf *p;
-
- dev = LOOKUP(handle);
- p = IN_BUF(dev);
- return (p->head != p->tail) || raw_instat(dev);
- }
-
- void
- console_write_byte(handle, n)
- int handle;
- int n;
- {
- char ch;
-
- if (__check_signals)
- flush_key_buff(handle);
- ch = n;
- (void)Fwrite(handle, 1L, &ch);
- }
-
- void flush_key_buff(fd)
- int fd;
- {
- long c;
- short i, j, waiting = 0;
- unsigned char ch;
- k_buf *p;
- short dev;
- short handle;
-
- handle = fd;
-
- dev = LOOKUP(handle);
- p = IN_BUF(dev);
-
- while (raw_instat(dev) || waiting)
- {
- c = raw_in(dev);
- if (!(__ttymode & RAW))
- {
- ch = c & 0xff;
- if (ch == ('S'-'@')) { waiting = 1; }
- else if (ch == ('Q'-'@')) { waiting = 0; }
- else if (ch == (unsigned char)__tchars[TC_INTRC])
- {
- p->head = p->tail;
- raise(SIGINT);
- }
- else if (ch == (unsigned char)__tchars[TC_QUITC])
- {
- p->head = p->tail;
- raise(SIGQUIT);
- }
- else if (!waiting)
- {
- i = p->head;
- j = i + 1;
- if (j >= KBUFSIZ) j = 0;
- if (j != p->tail)
- {
- p->buffer[i] = c;
- p->head = j;
- }
- }
- }
- }
- }
-