home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
misc
/
beav
/
beav.src.lha
/
termio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-27
|
8KB
|
376 lines
/*
* The functions in this file negotiate with the operating system for
* characters, and write characters in a barely buffered fashion on the display.
* All operating systems.
*/
#include <sys/types.h> /* 1.13 */
#ifdef UNIX /* System V */
#include <stdio.h>
#include <signal.h>
#ifdef BSD
#include <sys/ioctl.h>
#else
#ifdef OS2
#ifndef __EMX__
#define INCL_NOPM
#define INCL_DOS
#define INCL_KBD
#include <os2.h>
#endif
#include <io.h>
#else
#ifdef MINIX
#include <sgtty.h>
#define O_NDELAY O_NONBLOCK
#else
#include <termio.h>
#endif /* MINIX */
#endif /* OS2 */
#endif /* BSD */
#include <errno.h>
#include <fcntl.h>
#include "def.h"
int kbdflgs; /* saved keyboard fd flags */
int kbdpoll; /* in O_NDELAY mode */
int kbdqp; /* there is a char in kbdq */
char kbdq; /* char we've already read */
#ifdef BSD
struct sgttyb otermb;
struct sgttyb ntermb;
#else
#ifdef OS2
#ifndef __EMX__
KBDINFO kbst, kbst_std;
#endif
#else
#ifdef MINIX
struct sgttyb otermio; /* original terminal characteristics */
struct sgttyb ntermio; /* charactoristics to use inside */
struct tchars tchars, tcharsorig;
#else
struct termio otermio; /* original terminal characteristics */
struct termio ntermio; /* charactoristics to use inside */
#endif /* MINIX */
#endif /* OS2 */
#endif /* BSD */
#ifndef OS2
extern errno; /* System error number -- Necessary when compiling in BSD 1.13 */
#endif
int nrow; /* Terminal size, rows. */
int ncol; /* Terminal size, columns. */
/*
* This function is called once to set up the terminal device streams.
* On VMS, it translates TT until it finds the terminal, then assigns
* a channel to it and sets it raw. On CPM it is a no-op.
*/
void
ttopen ()
{
#ifdef BSD
#ifdef ULTRIX
struct winsize ttysize;
#else
struct ttysize ttysize;
#endif
ioctl (0, TIOCGETP, &otermb); /* save settings */
ntermb = otermb; /* setup new settings */
ntermb.sg_flags &= ~ECHO;
ntermb.sg_flags |= RAW;
ioctl (0, TIOCSETP, &ntermb); /* and activate them */
kbdpoll = FALSE;
/* on all screens we are not sure of the initial position
of the cursor */
ttrow = 999;
ttcol = 999;
#ifdef ULTRIX
if (ioctl (0, TIOCGWINSZ, &ttysize) == 0)
{
nrow = ttysize.ws_row;
ncol = ttysize.ws_col;
#else
if (ioctl (0, TIOCGSIZE, &ttysize) == 0)
{
nrow = ttysize.ts_lines;
ncol = ttysize.ts_cols;
#endif
}
else
{
nrow = NROW;
ncol = NCOL;
}
#else
#ifdef OS2
setmode (1, O_BINARY);
#else
#ifdef MINIX
ioctl (0, TIOCGETP, &otermio);
ntermio = otermio;
ntermio.sg_flags &= ~ECHO;
ntermio.sg_flags |= RAW;
ioctl (0, TIOCSETP, &ntermio);
ioctl (0, TIOCGETC, &tcharsorig);
tchars = tcharsorig;
tchars.t_intrc = tchars.t_quitc = tchars.t_startc =
tchars.t_stopc = tchars.t_eofc = tchars.t_brkc = -1;
ioctl (0, TIOCSETC, &tchars);
#else
ioctl (0, TCGETA, &otermio);/* save old settings */
ntermio.c_iflag = 0; /* setup new settings */
ntermio.c_oflag = 0;
ntermio.c_cflag = otermio.c_cflag;
ntermio.c_lflag = 0;
ntermio.c_line = otermio.c_line;
ntermio.c_cc[VMIN] = 1;
ntermio.c_cc[VTIME] = 0;
ioctl (0, TCSETAW, &ntermio); /* and activate them */
#endif /* MINIX */
kbdflgs = fcntl (0, F_GETFL, 0);
kbdpoll = FALSE;
#endif /* OS2 */
/* on all screens we are not sure of the initial position of the cursor */
ttrow = 999;
ttcol = 999;
nrow = NROW;
ncol = NCOL;
#endif /* BSD */
}
/*
* This function gets called just before we go back home to the command
* interpreter. On VMS it puts the terminal back in a reasonable state.
* Another no-operation on CPM.
*/
void
ttclose ()
{
#ifdef BSD
if (ioctl (0, TIOCSETP, &otermb) == -1) /* restore terminal settings */
printf ("closing ioctl on dev 0 failure, error = %d\n", errno);
#else
#ifdef OS2
setmode (1, O_TEXT);
#else
#ifdef MINIX
if (ioctl (0, TIOCSETP, &otermio) == -1 ||
ioctl (0, TIOCSETC, &tcharsorig) == -1)
printf ("closing ioctl on dev 0 failure, error = %d\n", errno);
#else
if (ioctl (0, TCSETAW, &otermio) == -1) /* restore terminal settings */
printf ("closing ioctl on dev 0 failure, error = %d\n", errno);
#endif /* MINIX */
if (fcntl (0, F_SETFL, kbdflgs) == -1)
printf ("closing fcntl on dev 0 failure, error = %d\n", errno);
#endif /* OS2 */
#endif /* BSD */
}
#ifdef OS2
void
ttraw (void)
{
#ifdef __32BIT__
signal (SIGINT, SIG_IGN);
signal (SIGBREAK, SIG_IGN);
#else
PFNSIGHANDLER oldhandler;
USHORT oldact;
DosSetSigHandler ((PFNSIGHANDLER) NULL, &oldhandler, &oldact,
SIGA_IGNORE, SIG_CTRLBREAK);
DosSetSigHandler ((PFNSIGHANDLER) NULL, &oldhandler, &oldact,
SIGA_IGNORE, SIG_CTRLC);
#endif
#ifndef __EMX__
kbst_std.cb = sizeof (kbst_std);
KbdGetStatus (&kbst_std, 0);
kbst = kbst_std;
kbst.fsMask &= ~(KEYBOARD_ECHO_ON | KEYBOARD_ASCII_MODE |
KEYBOARD_SHIFT_REPORT);
kbst.fsMask |= (KEYBOARD_ECHO_OFF | KEYBOARD_BINARY_MODE);
KbdSetStatus (&kbst, 0);
#endif
}
void
ttcooked (void)
{
#ifndef __EMX__
KbdSetStatus (&kbst_std, 0);
#endif
}
#endif
/*
* Write a character to the display. On VMS, terminal output is buffered, and
* we just put the characters in the big array, after checking for overflow.
* On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
* MS-DOS (use the very very raw console output routine).
*/
#ifdef OS2
int tty_io_size = 0;
char tty_io_buffer[2048];
#endif
int
ttputc (c)
{
#ifdef OS2
if (tty_io_size == sizeof (tty_io_buffer))
{
write (1, tty_io_buffer, tty_io_size);
tty_io_size = 0;
}
tty_io_buffer[tty_io_size++] = c;
#else
fputc (c, stdout);
#endif
return c;
}
/*
* Flush terminal buffer. Does real work where the terminal output is buffered
* up. A no-operation on systems where byte at a time terminal I/O is done.
*/
void
ttflush ()
{
#ifdef OS2
if (tty_io_size)
{
write (1, tty_io_buffer, tty_io_size);
tty_io_size = 0;
}
#else
fflush (stdout);
#endif
}
/*
* Read a character from the terminal, performing no editing and doing no echo
* at all. More complex in VMS that almost anyplace else, which figures. Very
* simple on CPM, because the system can do exactly what you want.
*/
#ifdef OS2
#ifdef __EMX__
static int chr = -1;
#endif
#endif
ttgetc ()
{
#ifdef OS2
#ifdef __EMX__
if (chr != -1)
{
int c = chr;
chr = -1;
return c;
}
else
return _read_kbd (0, 1, 0);
#else
static int ext, scan, chr;
KBDKEYINFO ki;
if (ext)
{
ext = 0;
return scan;
}
else
{
ttflush ();
KbdCharIn (&ki, IO_WAIT, 0);
if (ki.chChar == 0 || ki.chChar == 0xE0)
{
ext = 1;
scan = ki.chScan;
return 0xE0;
}
else
return ki.chChar;
}
#endif
#else
if (kbdqp)
kbdqp = FALSE;
else
{
#ifdef BSD
int count;
if (kbdpoll && (ioctl (0, FIONREAD, &count), count == 0))
return FALSE;
read (0, &kbdq, 1);
#else
if (kbdpoll && fcntl (0, F_SETFL, kbdflgs) < 0)
return FALSE;
kbdpoll = FALSE;
while (read (0, &kbdq, 1) != 1)
;
#endif
}
return (kbdq & 127);
#endif /* OS2 */
}
/* typahead(): Check to see if any characters are already in the
keyboard buffer
*/
ttkeyready ()
{
#ifdef OS2
#ifdef __EMX__
chr = _read_kbd (0, 0, 0);
return (chr != -1);
#else
KBDKEYINFO ki;
KbdPeek (&ki, 0);
return (ki.fbStatus != 0);
#endif
#else
if (!kbdqp)
{
#ifdef BSD
int count;
if (!kbdpoll && (ioctl (0, FIONREAD, &count), count == 0))
return FALSE;
kbdpoll = TRUE; /* fix in 1.13 */
kbdqp = TRUE;
#else
#ifdef X_MINIX
/* MINIX has non-blocking mode but it doesn't work !?!? */
return FALSE;
#else
if (!kbdpoll && fcntl (0, F_SETFL, kbdflgs | O_NDELAY) < 0)
return (FALSE);
kbdpoll = TRUE; /* fix in 1.13 */
kbdqp = (1 == read (0, &kbdq, 1));
#endif /* MINIX */
#endif /* BSD */
}
return (kbdqp);
#endif /* OS2 */
}
#endif