version 1.4, 2000/02/26 22:53:16 |
version 1.5, 2000/02/27 05:52:32 |
|
|
/* |
/* |
* Name: MicroEMACS |
* POSIX terminal I/O. |
* POSIX terminal I/O. |
|
* Version: 0 |
|
* Last edit: Tue Aug 26 23:57:57 PDT 1986 |
|
* By: gonzo!daveb |
|
* {sun, amdahl, mtxinu}!rtech!gonzo!daveb |
|
* |
* |
* The functions in this file |
* The functions in this file |
* negotiate with the operating system for |
* negotiate with the operating system for |
* keyboard characters, and write characters to |
* keyboard characters, and write characters to |
* the display in a barely buffered fashion. |
* the display in a barely buffered fashion. |
* |
|
* This version goes along with the terminfo tty.c. |
|
*/ |
*/ |
#include "def.h" |
#include "def.h" |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
#include <sys/time.h> |
|
#include <sys/ioctl.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <termios.h> |
#include <termios.h> |
#include <term.h> |
#include <term.h> |
|
|
int nrow; /* Terminal size, rows. */ |
int nrow; /* Terminal size, rows. */ |
int ncol; /* Terminal size, columns. */ |
int ncol; /* Terminal size, columns. */ |
|
|
/* These are used to implement typeahead on System V */ |
|
|
|
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 */ |
|
|
|
/* |
/* |
* This function gets called once, to set up |
* This function gets called once, to set up |
* the terminal channel. This version turns off flow |
* the terminal channel. This version turns off flow |
|
|
nt.c_cflag &= ~PARENB; /* Don't check parity */ |
nt.c_cflag &= ~PARENB; /* Don't check parity */ |
nt.c_lflag &= ~( ECHO | ICANON | ISIG ); |
nt.c_lflag &= ~( ECHO | ICANON | ISIG ); |
|
|
kbdpoll = (((kbdflgs = fcntl(0, F_GETFL, 0)) & O_NDELAY) != 0); |
|
|
|
ttysavedp = TRUE; |
ttysavedp = TRUE; |
} |
} |
|
|
if (tcsetattr(0, TCSAFLUSH, &nt) < 0) |
if (tcsetattr(0, TCSAFLUSH, &nt) < 0) |
abort(); |
abort(); |
|
|
setttysize(); |
|
|
|
ttyactivep = TRUE; |
ttyactivep = TRUE; |
} |
} |
|
|
|
|
if(!ttysavedp || !ttyactivep) |
if(!ttysavedp || !ttyactivep) |
return; |
return; |
ttflush(); |
ttflush(); |
if (tcsetattr(0, TCSAFLUSH, &ot) < 0 || |
if (tcsetattr(0, TCSAFLUSH, &ot) < 0) |
fcntl( 0, F_SETFL, kbdflgs ) < 0) |
|
abort(); |
abort(); |
ttyactivep = FALSE; |
ttyactivep = FALSE; |
} |
} |
|
|
*/ |
*/ |
ttputc(c) |
ttputc(c) |
{ |
{ |
|
|
if (nobuf >= NOBUF) |
if (nobuf >= NOBUF) |
ttflush(); |
ttflush(); |
obuf[nobuf++] = c; |
obuf[nobuf++] = c; |
|
|
*/ |
*/ |
ttflush() |
ttflush() |
{ |
{ |
|
|
if (nobuf != 0) { |
if (nobuf != 0) { |
write(1, obuf, nobuf); |
write(1, obuf, nobuf); |
nobuf = 0; |
nobuf = 0; |
|
|
*/ |
*/ |
ttgetc() |
ttgetc() |
{ |
{ |
if( kbdqp ) |
int c; |
kbdqp = FALSE; |
|
else |
while (read(0, &c, 1) != 1) |
{ |
; |
if( kbdpoll && fcntl( 0, F_SETFL, kbdflgs ) < 0 ) |
return (c & 0xFF); |
abort(); |
|
kbdpoll = FALSE; |
|
while (read(0, &kbdq, 1) != 1) |
|
; |
|
} |
|
return ( kbdq & 0xff ); |
|
} |
} |
|
|
/* |
/* |
* Return non-FALSE if typeahead is pending. |
* Return TRUE if there are characters waiting to be read. |
* |
|
* If already got unread typeahead, do nothing. |
|
* Otherwise, set keyboard to O_NDELAY if not already, and try |
|
* a one character read. |
|
*/ |
*/ |
typeahead() |
typeahead() |
{ |
{ |
if( !kbdqp ) |
int x; |
{ |
|
if( !kbdpoll && fcntl( 0, F_SETFL, kbdflgs | O_NDELAY ) < 0 ) |
return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x); |
abort(); |
|
kbdpoll = TRUE; |
|
kbdqp = (1 == read( 0, &kbdq, 1 )); |
|
} |
|
return ( kbdqp ); |
|
} |
} |
|
|
|
|
|
|
panic(s) |
panic(s) |
char *s; |
char *s; |
{ |
{ |
fprintf(stderr, "%s\r\n", s); |
|
abort(); |
(void) fputs("panic: ", stderr); |
|
(void) fputs(s, stderr); |
|
(void) fputc('\n', stderr); |
|
abort(); /* To leave a core image. */ |
} |
} |
|
|
|
|
|
|
{ |
{ |
#ifdef TIOCGWINSZ |
#ifdef TIOCGWINSZ |
struct winsize winsize; |
struct winsize winsize; |
|
|
if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) { |
if (ioctl(0, TIOCGWINSZ, (char *) &winsize) == 0) { |
nrow = winsize . ws_row; |
nrow = winsize.ws_row; |
ncol = winsize . ws_col; |
ncol = winsize.ws_col; |
} else |
} else |
#endif |
#endif |
if ((nrow = lines) <= 0 || (ncol = columns) <= 0) { |
if ((nrow = lines) <= 0 || (ncol = columns) <= 0) { |
|
|
} |
} |
|
|
#ifndef NO_DPROMPT |
#ifndef NO_DPROMPT |
#include <signal.h> |
|
#include <setjmp.h> |
|
|
|
static jmp_buf tohere; |
|
|
|
static void alrm() |
|
{ |
|
longjmp(tohere, -1); |
|
} |
|
|
|
/* |
/* |
* Return TRUE if we wait without doing anything, else return FALSE. |
* Return TRUE if we wait without doing anything, else return FALSE. |
*/ |
*/ |
|
|
ttwait() |
ttwait() |
{ |
{ |
if (kbdqp) |
fd_set readfds; |
return FALSE; /* already pending input */ |
struct timeval tmout; |
if (setjmp(tohere)) |
|
return TRUE; /* timeout on read if here */ |
FD_ZERO(&readfds); |
signal(SIGALRM, alrm); alarm(2); |
FD_SET(0, &readfds); |
kbdqp = (1 == read(0, &kbdq, 1)); |
|
alarm(0); |
tmout.tv_sec = 2; |
return FALSE; /* successful read if here */ |
tmout.tv_usec = 0; |
|
|
|
if ((select(1, &readfds, NULL, NULL, &tmout)) == 0) |
|
return(TRUE); |
|
return(FALSE); |
} |
} |
#endif NO_DPROMPT |
#endif NO_DPROMPT |