version 1.10, 1999/02/28 08:37:45
|
version 1.27, 2007/07/01 18:32:11
|
Line 1
|
Line 1
|
/* direct key io driver |
/* direct key io driver |
|
|
Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc. |
Copyright (C) 1995,1996,1997,1998,1999,2002,2003,2006 Free Software Foundation, Inc. |
|
|
This file is part of Gforth. |
This file is part of Gforth. |
|
|
Line 16
|
Line 16
|
|
|
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
|
|
The following is stolen from the readline library for bash |
The following is stolen from the readline library for bash |
*/ |
*/ |
Line 26
|
Line 26
|
*/ |
*/ |
|
|
#include "config.h" |
#include "config.h" |
|
#include "forth.h" |
#include <sys/time.h> |
#include <sys/time.h> |
#include <sys/types.h> |
#include <sys/types.h> |
#include <unistd.h> |
#include <unistd.h> |
Line 51 typedef unsigned int uint32_t;
|
Line 52 typedef unsigned int uint32_t;
|
#include <sys/filio.h> |
#include <sys/filio.h> |
#endif |
#endif |
#include <setjmp.h> |
#include <setjmp.h> |
#include "forth.h" |
|
#include "io.h" |
#include "io.h" |
|
|
#ifndef MSDOS |
#ifndef MSDOS |
Line 447 void deprep_terminal ()
|
Line 447 void deprep_terminal ()
|
#define VTIME VEOL |
#define VTIME VEOL |
#endif |
#endif |
|
|
|
#include <locale.h> |
|
|
void prep_terminal () |
void prep_terminal () |
{ |
{ |
int tty = fileno (stdin); |
int tty = fileno (stdin); |
Line 472 void prep_terminal ()
|
Line 474 void prep_terminal ()
|
return; /* added by MdG */ |
return; /* added by MdG */ |
} /* added by MdG */ |
} /* added by MdG */ |
|
|
|
setlocale(LC_ALL, ""); |
|
setlocale(LC_NUMERIC, "C"); |
|
|
/* Try to keep this function from being INTerrupted. We can do it |
/* Try to keep this function from being INTerrupted. We can do it |
on POSIX and systems with BSD-like signal handling. */ |
on POSIX and systems with BSD-like signal handling. */ |
#if defined (HAVE_POSIX_SIGNALS) |
#if defined (HAVE_POSIX_SIGNALS) |
Line 613 void deprep_terminal ()
|
Line 618 void deprep_terminal ()
|
} |
} |
#endif /* NEW_TTY_DRIVER */ |
#endif /* NEW_TTY_DRIVER */ |
|
|
/* If a character is available to be read, then read it |
|
and stuff it into IBUFFER. Otherwise, just return. */ |
|
|
|
long pending = -1L; |
|
|
|
long key_avail (FILE * stream) |
long key_avail (FILE * stream) |
{ |
{ |
int tty = fileno (stream); |
int tty = fileno (stream); |
int chars_avail = pending; |
fd_set selin; |
int result; |
static long int now[2] = { 0 , 0 }; |
|
int res; |
if(!terminal_prepped) prep_terminal(); |
|
|
setvbuf(stream, NULL, _IONBF, 0); |
#ifndef _WIN32 |
if(!terminal_prepped && stream == stdin) |
if(isatty (tty)) { |
prep_terminal(); |
result = ioctl (tty, FIONREAD, &chars_avail); |
|
} |
FD_ZERO(&selin); |
#else |
FD_SET(tty, &selin); |
{ |
return select(1, &selin, NULL, NULL, now); |
fd_set selin; |
|
static int now[2] = { 0 , 0 }; |
|
int res; |
|
|
|
FD_ZERO(&selin); |
|
FD_SET(tty, &selin); |
|
chars_avail=select(1, &selin, NULL, NULL, now); |
|
} |
|
#endif |
|
|
|
if(chars_avail == -1L) { |
|
unsigned char inchar; |
|
|
|
fcntl(tty, F_SETFL, O_NDELAY); |
|
result = read(tty, &inchar, sizeof(char)); |
|
if(result == sizeof(char)) { |
|
chars_avail = 1; |
|
pending = (long)inchar; |
|
} else { |
|
chars_avail = 0; |
|
} |
|
fcntl(tty, F_SETFL, 0); |
|
} |
|
|
|
return chars_avail; |
|
} |
} |
|
|
/* Get a key from the buffer of characters to be read. |
/* Get a key from the buffer of characters to be read. |
Line 666 long key_avail (FILE * stream)
|
Line 641 long key_avail (FILE * stream)
|
/* When compiling and running in the `Posix' environment, Ultrix does |
/* When compiling and running in the `Posix' environment, Ultrix does |
not restart system calls, so this needs to do it. */ |
not restart system calls, so this needs to do it. */ |
|
|
unsigned getkey(FILE * stream) |
Cell getkey(FILE * stream) |
{ |
{ |
int result; |
Cell result; |
unsigned char c; |
unsigned char c; |
|
|
if(!terminal_prepped) prep_terminal(); |
setvbuf(stream, NULL, _IONBF, 0); |
|
if(!terminal_prepped && stream == stdin) |
while (pending < 0) |
prep_terminal(); |
{ |
|
result = read (fileno (stream), &c, sizeof (char)); |
|
|
|
if (result == sizeof (char)) |
|
return /* (c == 0x7F ? 0x08 :*/ c /*)*/; |
|
|
|
/* If zero characters are returned, then the file that we are |
result = fread(&c, sizeof(c), 1, stream); |
reading from is empty! Return EOF in that case. */ |
return result==0 ? EOF : c; |
if (result == 0) |
} |
return (EOF); |
|
|
|
/* If the error that we received was SIGINT, then try again, |
|
this is simply an interrupted system call to read (). |
|
Otherwise, some error ocurred, also signifying EOF. */ |
|
if (errno != EINTR) |
|
return (EOF); |
|
} |
|
|
|
result = (int) pending; |
#ifdef STANDALONE |
pending = -1L; |
void emit_char(char x) |
|
{ |
|
putc(x, stdout); |
|
} |
|
|
return result; |
void type_chars(char *addr, unsigned int l) |
|
{ |
|
fwrite(addr, l, 1, stdout); |
} |
} |
|
#endif |
|
|
#ifdef TEST |
#ifdef TEST |
|
|