|
Packit |
910689 |
/* -*-C-*- */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#define PERL_NO_GET_CONTEXT /* we want efficiency */
|
|
Packit |
910689 |
#include "EXTERN.h"
|
|
Packit |
910689 |
#include "perl.h"
|
|
Packit |
910689 |
#include "XSUB.h"
|
|
Packit |
910689 |
#include "ppport.h"
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#define InputStream PerlIO *
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*******************************************************************
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Copyright (C) 1994,1995,1996,1997 Kenneth Albanowski. Unlimited
|
|
Packit |
910689 |
distribution and/or modification is allowed as long as this copyright
|
|
Packit |
910689 |
notice remains intact.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Written by Kenneth Albanowski on Thu Oct 6 11:42:20 EDT 1994
|
|
Packit |
910689 |
Contact at kjahds@kjahds.com or CIS:70705,126
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Maintained by Jonathan Stowe <jns@gellyfish.co.uk>
|
|
Packit |
910689 |
|
|
Packit |
910689 |
The below captures the history prior to it being in full time version
|
|
Packit |
910689 |
control:
|
|
Packit |
910689 |
|
|
Packit |
910689 |
$Id: ReadKey.xs,v 2.22 2005/01/11 21:15:17 jonathan Exp $
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.21, Sun Jul 28 12:57:56 BST 2002
|
|
Packit |
910689 |
Fix to improve the chances of automated testing succeeding
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.20, Tue May 21 07:52:47 BST 2002
|
|
Packit |
910689 |
Patch from Autrijus Tang fixing Win32 Breakage with bleadperl
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.19, Thu Mar 21 07:25:31 GMT 2002
|
|
Packit |
910689 |
Added check for definedness of $_[0] in comparisons in ReadKey, ReadLine
|
|
Packit |
910689 |
after reports of warnings.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.18, Sun Feb 10 13:06:57 GMT 2002
|
|
Packit |
910689 |
Altered prototyping style after reports of compile failures on
|
|
Packit |
910689 |
Windows.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.17, Fri Jan 25 06:58:47 GMT 2002
|
|
Packit |
910689 |
The '_' macro for non-ANSI compatibility was removed in 5.7.2
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.16, Thu Nov 29 21:19:03 GMT 2001
|
|
Packit |
910689 |
It appears that the genchars.pl bit of the patch didnt apply
|
|
Packit |
910689 |
Applied the new ppport.h from Devel::PPPort
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.15, Sun Nov 4 15:02:37 GMT 2001 (jns)
|
|
Packit |
910689 |
Applied the patch in
|
|
Packit |
910689 |
http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2001-01/msg01588.html
|
|
Packit |
910689 |
for PerlIO compatibility.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.14, Sun Mar 28 23:26:13 EST 1999
|
|
Packit |
910689 |
ppport.h 1.007 fixed for 5.005_55.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.13, Wed Mar 24 20:46:06 EST 1999
|
|
Packit |
910689 |
Adapted to ppport.h 1.006.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.12, Wed Jan 7 10:33:11 EST 1998
|
|
Packit |
910689 |
Slightly modified test and error reporting for Win32.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.11, Sun Dec 14 00:39:12 EST 1997
|
|
Packit |
910689 |
First attempt at Win32 support.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.10, skipped
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.09, Tue Oct 7 13:07:43 EDT 1997
|
|
Packit |
910689 |
Grr. Added explicit detection of sys/poll.h and poll.h.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.08, Mon Oct 6 16:07:44 EDT 1997
|
|
Packit |
910689 |
Changed poll.h to sys/poll.h.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.07, Sun Jan 26 19:11:56 EST 1997
|
|
Packit |
910689 |
Added $VERSION to .pm.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.06, Tue Nov 26 01:47:09 EST 1996
|
|
Packit |
910689 |
Added PERLIO support and removed duplicate declaration in .pm.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.05, Tue Mar 12 19:08:33 EST 1996
|
|
Packit |
910689 |
Changed poll support so it works. Cleaned up .pm a little.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.04, Tue Oct 10 05:35:48 EDT 1995
|
|
Packit |
910689 |
Whoops. Changed GetTermSize back so that GSIZE code won't be
|
|
Packit |
910689 |
compiled if GWINSZ is being used. Also took ts_xxx and ts_yyy
|
|
Packit |
910689 |
out of GSIZE.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.03, Thu Sep 21 21:53:16 EDT 1995
|
|
Packit |
910689 |
Fixed up debugging info in Readkey.pm, and changed TermSizeVIO
|
|
Packit |
910689 |
to use _scrsize(). Hopefully this is GO for both Solaris and OS/2.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.02, Mon Sep 18 22:17:57 EDT 1995
|
|
Packit |
910689 |
Workaround for Solaris bug wasn't sufficient. Modularlized
|
|
Packit |
910689 |
GetTermSize into perl code, and added support for the
|
|
Packit |
910689 |
`resize` executable. Hard coded path for Solaris machines.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.01, Wed Sep 13 22:22:23 EDT 1995
|
|
Packit |
910689 |
Change error reporting around in getscreensize so that if
|
|
Packit |
910689 |
an ioctl fails but getenv succeeds, no warning will be
|
|
Packit |
910689 |
printed. This is an attempt to work around a Solaris bug where
|
|
Packit |
910689 |
TIOCGWINSZ fails in telnet sessions.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 2.00, Mon Sep 4 06:37:24 EDT 1995
|
|
Packit |
910689 |
Added timeouts to select/poll, added USE_STDIO_PTR support
|
|
Packit |
910689 |
(required for recent perl revisions), and fixed up compilation
|
|
Packit |
910689 |
under OS/2.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.99, Fri Aug 11 20:18:11 EDT 1995
|
|
Packit |
910689 |
Add file handles to ReadMode.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.97, Mon Apr 10 21:41:52 EDT 1995
|
|
Packit |
910689 |
Changed mode 5 to disable UC & delays. Added more ECHO flags.
|
|
Packit |
910689 |
Tested termio[s] & sgtty.
|
|
Packit |
910689 |
Added termoptions so test.pl can give more info.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.96,
|
|
Packit |
910689 |
Mucked with filehandle selection in ReadKey.pm.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.95,
|
|
Packit |
910689 |
Cleaning up for distribution.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.94,
|
|
Packit |
910689 |
Dealt with get/settermsize sillyness.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.91, Sat Mar 11 23:47:04 EST 1995:
|
|
Packit |
910689 |
Andy's patches, and a bit of termsize finesse.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.9, Thu Mar 9 14:11:49 EST 1995:
|
|
Packit |
910689 |
Modifying for portability. Prototypes, singed chars, etc.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.8, Mon Jan 9 23:18:14 EST 1995:
|
|
Packit |
910689 |
Added use of Configure.pm. No changes to ReadKey.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.7, Fri Dec 16 13:48:14 EST 1994:
|
|
Packit |
910689 |
Getting closer to release. Added new readmode 2. Had to bump up other
|
|
Packit |
910689 |
modes, unfortunately. This is the _last_ time I do that. If I have to
|
|
Packit |
910689 |
bump up the modes again, I'm switching to a different scheme.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.6, Wed Dec 14 17:36:59 EST 1994:
|
|
Packit |
910689 |
Completly reorganized the control-char support (twice!) so that
|
|
Packit |
910689 |
it is automatically ported by the preproccessor for termio[s], or
|
|
Packit |
910689 |
by an included script for sgtty. Logical defaults for sgtty are included
|
|
Packit |
910689 |
too. Added Sun TermSize support. (Hope I got it right.)
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.5, Fri Dec 9 16:07:49 EST 1994:
|
|
Packit |
910689 |
Added SetTermSize, GetSpeeds, Get/SetControlChars, PerlIO support.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.01, Thu Oct 20 23:32:39 EDT 1994:
|
|
Packit |
910689 |
Added Select_fd_set_t casts to select() call.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Version 1.0: First "real" release. Everything seems cool.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
*******************************************************************/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/***
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Things to do:
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Make sure the GetSpeed function is doing it's best to separate ispeed
|
|
Packit |
910689 |
from ospeed.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
Separate the stty stuff from ReadMode, so that stty -a can be easily
|
|
Packit |
910689 |
used, among other things.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
***/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* Using these defines, you can elide anything you know
|
|
Packit |
910689 |
won't work properly */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* Methods of doing non-blocking reads */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*#define DONT_USE_SELECT*/
|
|
Packit |
910689 |
/*#define DONT_USE_POLL*/
|
|
Packit |
910689 |
/*#define DONT_USE_NODELAY*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* Terminal I/O packages */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*#define DONT_USE_TERMIOS*/
|
|
Packit |
910689 |
/*#define DONT_USE_TERMIO*/
|
|
Packit |
910689 |
/*#define DONT_USE_SGTTY*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* IOCTLs that can be used for GetTerminalSize */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*#define DONT_USE_GWINSZ*/
|
|
Packit |
910689 |
/*#define DONT_USE_GSIZE*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* IOCTLs that can be used for SetTerminalSize */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*#define DONT_USE_SWINSZ*/
|
|
Packit |
910689 |
/*#define DONT_USE_SSIZE*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* This bit is for OS/2 */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef OS2
|
|
Packit |
910689 |
# define I_FCNTL
|
|
Packit |
910689 |
# define HAS_FCNTL
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# define O_NODELAY O_NDELAY
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# define DONT_USE_SELECT
|
|
Packit |
910689 |
# define DONT_USE_POLL
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# define DONT_USE_TERMIOS
|
|
Packit |
910689 |
# define DONT_USE_SGTTY
|
|
Packit |
910689 |
# define I_TERMIO
|
|
Packit |
910689 |
# define CC_TERMIO
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* This flag should be off in the lflags when we enable termio mode */
|
|
Packit |
910689 |
# define TRK_IDEFAULT IDEFAULT
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# define INCL_SUB
|
|
Packit |
910689 |
# define INCL_DOS
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# include <os2.h>
|
|
Packit |
910689 |
# include <stdlib.h>
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# define VIOMODE
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
/* no os2 */
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* This bit is for Windows 95/NT */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef WIN32
|
|
Packit |
910689 |
# define DONT_USE_TERMIO
|
|
Packit |
910689 |
# define DONT_USE_TERMIOS
|
|
Packit |
910689 |
# define DONT_USE_SGTTY
|
|
Packit |
910689 |
# define DONT_USE_POLL
|
|
Packit |
910689 |
# define DONT_USE_SELECT
|
|
Packit |
910689 |
# define DONT_USE_NODELAY
|
|
Packit |
910689 |
# define USE_WIN32
|
|
Packit |
910689 |
# include <io.h>
|
|
Packit |
910689 |
# if defined(_get_osfhandle) && (PERL_VERSION == 4) && (PERL_SUBVERSION < 5)
|
|
Packit |
910689 |
# undef _get_osfhandle
|
|
Packit |
910689 |
# if defined(_MSC_VER)
|
|
Packit |
910689 |
# define level _cnt
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* This bit for NeXT */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef _NEXT_SOURCE
|
|
Packit |
910689 |
/* fcntl with O_NDELAY (FNDELAY, actually) is broken on NeXT */
|
|
Packit |
910689 |
# define DONT_USE_NODELAY
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#if !defined(DONT_USE_NODELAY)
|
|
Packit |
910689 |
# ifdef HAS_FCNTL
|
|
Packit |
910689 |
# define Have_nodelay
|
|
Packit |
910689 |
# ifdef I_FCNTL
|
|
Packit |
910689 |
# include <fcntl.h>
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# ifdef I_SYS_FILE
|
|
Packit |
910689 |
# include <sys/file.h>
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# ifdef I_UNISTD
|
|
Packit |
910689 |
# include <unistd.h>
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* If any other headers are needed for fcntl or O_NODELAY, they need to get
|
|
Packit |
910689 |
included right here */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# if !defined(O_NODELAY)
|
|
Packit |
910689 |
# if !defined(FNDELAY)
|
|
Packit |
910689 |
# undef Have_nodelay
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
# define O_NODELAY FNDELAY
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
# define O_NODELAY O_NDELAY
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#if !defined(DONT_USE_SELECT)
|
|
Packit |
910689 |
# ifdef HAS_SELECT
|
|
Packit |
910689 |
# ifdef I_SYS_SELECT
|
|
Packit |
910689 |
# include <sys/select.h>
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* If any other headers are likely to be needed for select, they need to be
|
|
Packit |
910689 |
included right here */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# define Have_select
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#if !defined(DONT_USE_POLL)
|
|
Packit |
910689 |
# ifdef HAS_POLL
|
|
Packit |
910689 |
# ifdef HAVE_POLL_H
|
|
Packit |
910689 |
# include <poll.h>
|
|
Packit |
910689 |
# define Have_poll
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# ifdef HAVE_SYS_POLL_H
|
|
Packit |
910689 |
# include <sys/poll.h>
|
|
Packit |
910689 |
# define Have_poll
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef DONT_USE_TERMIOS
|
|
Packit |
910689 |
# ifdef I_TERMIOS
|
|
Packit |
910689 |
# undef I_TERMIOS
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef DONT_USE_TERMIO
|
|
Packit |
910689 |
# ifdef I_TERMIO
|
|
Packit |
910689 |
# undef I_TERMIO
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef DONT_USE_SGTTY
|
|
Packit |
910689 |
# ifdef I_SGTTY
|
|
Packit |
910689 |
# undef I_SGTTY
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* Pre-POSIX SVR3 systems sometimes define struct winsize in
|
|
Packit |
910689 |
sys/ptem.h. However, sys/ptem.h needs a type mblk_t (?) which
|
|
Packit |
910689 |
is defined in <sys/stream.h>.
|
|
Packit |
910689 |
No, Configure (dist3.051) doesn't know how to check for this.
|
|
Packit |
910689 |
*/
|
|
Packit |
910689 |
#ifdef I_SYS_STREAM
|
|
Packit |
910689 |
# include <sys/stream.h>
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef I_SYS_PTEM
|
|
Packit |
910689 |
# include <sys/ptem.h>
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef I_TERMIOS
|
|
Packit |
910689 |
# include <termios.h>
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
# ifdef I_TERMIO
|
|
Packit |
910689 |
# include <termio.h>
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
# ifdef I_SGTTY
|
|
Packit |
910689 |
# include <sgtty.h>
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef I_TERMIOS
|
|
Packit |
910689 |
# define CC_TERMIOS
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
# ifdef I_TERMIO
|
|
Packit |
910689 |
# define CC_TERMIO
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
# ifdef I_SGTTY
|
|
Packit |
910689 |
# define CC_SGTTY
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifndef TRK_IDEFAULT
|
|
Packit |
910689 |
/* This flag should be off in the lflags when we enable termio mode */
|
|
Packit |
910689 |
# define TRK_IDEFAULT 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* Fix up the disappearance of the '_' macro in Perl 5.7.2 */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifndef _
|
|
Packit |
910689 |
# ifdef CAN_PROTOTYPE
|
|
Packit |
910689 |
# define _(args) args
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
# define _(args) ()
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#define DisableFlush (1) /* Should flushing mode changes be enabled?
|
|
Packit |
910689 |
I think not for now. */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#define STDIN PerlIO_stdin()
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#include "cchars.h"
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int GetTermSizeVIO _((pTHX_ PerlIO * file,
|
|
Packit |
910689 |
int * retwidth, int * retheight,
|
|
Packit |
910689 |
int * xpix, int * ypix));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int GetTermSizeGWINSZ _((pTHX_ PerlIO * file,
|
|
Packit |
910689 |
int * retwidth, int * retheight,
|
|
Packit |
910689 |
int * xpix, int * ypix));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int GetTermSizeGSIZE _((pTHX_ PerlIO * file,
|
|
Packit |
910689 |
int * retwidth, int * retheight,
|
|
Packit |
910689 |
int * xpix, int * ypix));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int GetTermSizeWin32 _((pTHX_ PerlIO * file,
|
|
Packit |
910689 |
int * retwidth, int * retheight,
|
|
Packit |
910689 |
int * xpix, int * ypix));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int SetTerminalSize _((pTHX_ PerlIO * file,
|
|
Packit |
910689 |
int width, int height,
|
|
Packit |
910689 |
int xpix, int ypix));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC void ReadMode _((pTHX_ PerlIO * file,int mode));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int pollfile _((pTHX_ PerlIO * file, double delay));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int setnodelay _((pTHX_ PerlIO * file, int mode));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int selectfile _((pTHX_ PerlIO * file, double delay));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int Win32PeekChar _((pTHX_ PerlIO * file, U32 delay, char * key));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int getspeed _((pTHX_ PerlIO * file, I32 *in, I32 * out ));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef VIOMODE
|
|
Packit |
910689 |
int GetTermSizeVIO(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
/*int handle=PerlIO_fileno(file);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
static VIOMODEINFO *modeinfo = NULL;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (modeinfo == NULL)
|
|
Packit |
910689 |
modeinfo = (VIOMODEINFO *)malloc(sizeof(VIOMODEINFO));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
VioGetMode(modeinfo,0);
|
|
Packit |
910689 |
*retheight = modeinfo->row ?: 25;
|
|
Packit |
910689 |
*retwidth = modeinfo->col ?: 80;*/
|
|
Packit |
910689 |
int buf[2];
|
|
Packit |
910689 |
|
|
Packit |
910689 |
_scrsize(&buf[0]);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
*retwidth = buf[0]; *retheight = buf[1];
|
|
Packit |
910689 |
|
|
Packit |
910689 |
*xpix = *ypix = 0;
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
int GetTermSizeVIO(pTHX_ PerlIO *file,int * retwidth,int *retheight, int *xpix,int *ypix)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("TermSizeVIO is not implemented on this architecture");
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#if defined(TIOCGWINSZ) && !defined(DONT_USE_GWINSZ)
|
|
Packit |
910689 |
int GetTermSizeGWINSZ(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int handle=PerlIO_fileno(file);
|
|
Packit |
910689 |
struct winsize w;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (ioctl (handle, TIOCGWINSZ, &w) == 0) {
|
|
Packit |
910689 |
*retwidth=w.ws_col; *retheight=w.ws_row;
|
|
Packit |
910689 |
*xpix=w.ws_xpixel; *ypix=w.ws_ypixel; return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else {
|
|
Packit |
910689 |
return -1; /* failure */
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
int GetTermSizeGWINSZ(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("TermSizeGWINSZ is not implemented on this architecture");
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#if (!defined(TIOCGWINSZ) || defined(DONT_USE_GWINSZ)) && (defined(TIOCGSIZE) && !defined(DONT_USE_GSIZE))
|
|
Packit |
910689 |
int GetTermSizeGSIZE(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int handle=PerlIO_fileno(file);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
struct ttysize w;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (ioctl (handle, TIOCGSIZE, &w) == 0) {
|
|
Packit |
910689 |
*retwidth=w.ts_cols; *retheight=w.ts_lines;
|
|
Packit |
910689 |
*xpix=0/*w.ts_xxx*/; *ypix=0/*w.ts_yyy*/; return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else {
|
|
Packit |
910689 |
return -1; /* failure */
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
int GetTermSizeGSIZE(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("TermSizeGSIZE is not implemented on this architecture");
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef USE_WIN32
|
|
Packit |
910689 |
int GetTermSizeWin32(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int handle=PerlIO_fileno(file);
|
|
Packit |
910689 |
HANDLE whnd = (HANDLE)_get_osfhandle(handle);
|
|
Packit |
910689 |
CONSOLE_SCREEN_BUFFER_INFO info;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (GetConsoleScreenBufferInfo(whnd, &info)) {
|
|
Packit |
910689 |
/* Logic: return maximum possible screen width, but return
|
|
Packit |
910689 |
only currently selected height */
|
|
Packit |
910689 |
if (retwidth)
|
|
Packit |
910689 |
*retwidth = info.dwMaximumWindowSize.X;
|
|
Packit |
910689 |
/*info.srWindow.Right - info.srWindow.Left;*/
|
|
Packit |
910689 |
if (retheight)
|
|
Packit |
910689 |
*retheight = info.srWindow.Bottom - info.srWindow.Top;
|
|
Packit |
910689 |
if (xpix)
|
|
Packit |
910689 |
*xpix = 0;
|
|
Packit |
910689 |
if (ypix)
|
|
Packit |
910689 |
*ypix = 0;
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
} else
|
|
Packit |
910689 |
return -1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
int GetTermSizeWin32(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("TermSizeWin32 is not implemented on this architecture");
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#endif /* USE_WIN32 */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int termsizeoptions() {
|
|
Packit |
910689 |
return 0
|
|
Packit |
910689 |
#ifdef VIOMODE
|
|
Packit |
910689 |
| 1
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#if defined(TIOCGWINSZ) && !defined(DONT_USE_GWINSZ)
|
|
Packit |
910689 |
| 2
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#if defined(TIOCGSIZE) && !defined(DONT_USE_GSIZE)
|
|
Packit |
910689 |
| 4
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#if defined(USE_WIN32)
|
|
Packit |
910689 |
| 8
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
int SetTerminalSize(pTHX_ PerlIO *file,int width,int height,int xpix,int ypix)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int handle=PerlIO_fileno(file);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef VIOMODE
|
|
Packit |
910689 |
return -1;
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#if defined(TIOCSWINSZ) && !defined(DONT_USE_SWINSZ)
|
|
Packit |
910689 |
char buffer[10];
|
|
Packit |
910689 |
struct winsize w;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
w.ws_col=width;
|
|
Packit |
910689 |
w.ws_row=height;
|
|
Packit |
910689 |
w.ws_xpixel=xpix;
|
|
Packit |
910689 |
w.ws_ypixel=ypix;
|
|
Packit |
910689 |
if (ioctl (handle, TIOCSWINSZ, &w) == 0) {
|
|
Packit |
910689 |
sprintf(buffer,"%d",width); /* Be polite to our children */
|
|
Packit |
910689 |
my_setenv("COLUMNS",buffer);
|
|
Packit |
910689 |
sprintf(buffer,"%d",height);
|
|
Packit |
910689 |
my_setenv("LINES",buffer);
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else {
|
|
Packit |
910689 |
croak("TIOCSWINSZ ioctl call to set terminal size failed: %s",Strerror(errno));
|
|
Packit |
910689 |
return -1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
# if defined(TIOCSSIZE) && !defined(DONT_USE_SSIZE)
|
|
Packit |
910689 |
char buffer[10];
|
|
Packit |
910689 |
struct ttysize w;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
w.ts_lines=height;
|
|
Packit |
910689 |
w.ts_cols=width;
|
|
Packit |
910689 |
w.ts_xxx=xpix;
|
|
Packit |
910689 |
w.ts_yyy=ypix;
|
|
Packit |
910689 |
if (ioctl (handle, TIOCSSIZE, &w) == 0) {
|
|
Packit |
910689 |
sprintf(buffer,"%d",width);
|
|
Packit |
910689 |
my_setenv("COLUMNS",buffer);
|
|
Packit |
910689 |
sprintf(buffer,"%d",height);
|
|
Packit |
910689 |
my_setenv("LINES",buffer);
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else {
|
|
Packit |
910689 |
croak("TIOCSSIZE ioctl call to set terminal size failed: %s",Strerror(errno));
|
|
Packit |
910689 |
return -1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
/*sprintf(buffer,"%d",width) * Should we could do this and then *
|
|
Packit |
910689 |
my_setenv("COLUMNS",buffer) * said we succeeded? *
|
|
Packit |
910689 |
sprintf(buffer,"%d",height);
|
|
Packit |
910689 |
my_setenv("LINES",buffer)*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
return -1; /* Fail */
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC const I32 terminal_speeds[] = {
|
|
Packit |
910689 |
#ifdef B50
|
|
Packit |
910689 |
50, B50,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B75
|
|
Packit |
910689 |
75, B75,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B110
|
|
Packit |
910689 |
110, B110,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B134
|
|
Packit |
910689 |
134, B134,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B150
|
|
Packit |
910689 |
150, B150,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B200
|
|
Packit |
910689 |
200, B200,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B300
|
|
Packit |
910689 |
300, B300,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B600
|
|
Packit |
910689 |
600, B600,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B1200
|
|
Packit |
910689 |
1200, B1200,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B1800
|
|
Packit |
910689 |
1800, B1800,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B2400
|
|
Packit |
910689 |
2400, B2400,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B4800
|
|
Packit |
910689 |
4800, B4800,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B9600
|
|
Packit |
910689 |
9600, B9600,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B19200
|
|
Packit |
910689 |
19200, B19200,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B38400
|
|
Packit |
910689 |
38400, B38400,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B57600
|
|
Packit |
910689 |
57600, B57600,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B115200
|
|
Packit |
910689 |
115200, B115200,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef EXTA
|
|
Packit |
910689 |
19200, EXTA,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef EXTB
|
|
Packit |
910689 |
38400, EXTB,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef B0
|
|
Packit |
910689 |
0, B0,
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
-1,-1
|
|
Packit |
910689 |
};
|
|
Packit |
910689 |
|
|
Packit |
910689 |
int getspeed(pTHX_ PerlIO *file,I32 *in, I32 *out)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int handle=PerlIO_fileno(file);
|
|
Packit |
910689 |
#if defined(I_TERMIOS) || defined(I_TERMIO) || defined(I_SGTTY)
|
|
Packit |
910689 |
int i;
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
# ifdef I_TERMIOS
|
|
Packit |
910689 |
/* Posixy stuff */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
struct termios buf;
|
|
Packit |
910689 |
tcgetattr(handle,&buf;;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
*in = *out = -1;
|
|
Packit |
910689 |
*in = cfgetispeed(&buf;;
|
|
Packit |
910689 |
*out = cfgetospeed(&buf;;
|
|
Packit |
910689 |
for(i=0;terminal_speeds[i]!=-1;i+=2) {
|
|
Packit |
910689 |
if(*in == terminal_speeds[i+1])
|
|
Packit |
910689 |
{ *in = terminal_speeds[i]; break; }
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
for(i=0;terminal_speeds[i]!=-1;i+=2) {
|
|
Packit |
910689 |
if(*out == terminal_speeds[i+1])
|
|
Packit |
910689 |
{ *out = terminal_speeds[i]; break; }
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
# ifdef I_TERMIO
|
|
Packit |
910689 |
/* SysV stuff */
|
|
Packit |
910689 |
struct termio buf;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
ioctl(handle,TCGETA,&buf;;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
*in=*out=-1;
|
|
Packit |
910689 |
for(i=0;terminal_speeds[i]!=-1;i+=2) {
|
|
Packit |
910689 |
if((buf.c_cflag & CBAUD) == terminal_speeds[i+1])
|
|
Packit |
910689 |
{ *in=*out=terminal_speeds[i]; break; }
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
# ifdef I_SGTTY
|
|
Packit |
910689 |
/* BSD stuff */
|
|
Packit |
910689 |
struct sgttyb buf;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
ioctl(handle,TIOCGETP,&buf;;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
*in=*out=-1;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
for(i=0;terminal_speeds[i]!=-1;i+=2)
|
|
Packit |
910689 |
if(buf.sg_ospeed == terminal_speeds[i+1])
|
|
Packit |
910689 |
{ *out = terminal_speeds[i]; break; }
|
|
Packit |
910689 |
|
|
Packit |
910689 |
for(i=0;terminal_speeds[i]!=-1;i+=2)
|
|
Packit |
910689 |
if(buf.sg_ispeed == terminal_speeds[i+1])
|
|
Packit |
910689 |
{ *in = terminal_speeds[i]; break; }
|
|
Packit |
910689 |
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* No termio, termios or sgtty. I suppose we can try stty,
|
|
Packit |
910689 |
but it would be nice if you could get a better OS */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
return -1;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef WIN32
|
|
Packit |
910689 |
struct tbuffer { DWORD Mode; };
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
#ifdef I_TERMIOS
|
|
Packit |
910689 |
#define USE_TERMIOS
|
|
Packit |
910689 |
#define tbuffer termios
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
#ifdef I_TERMIO
|
|
Packit |
910689 |
#define USE_TERMIO
|
|
Packit |
910689 |
#define tbuffer termio
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
#ifdef I_SGTTY
|
|
Packit |
910689 |
#define USE_SGTTY
|
|
Packit |
910689 |
struct tbuffer {
|
|
Packit |
910689 |
struct sgttyb buf;
|
|
Packit |
910689 |
#if defined(TIOCGETC)
|
|
Packit |
910689 |
struct tchars tchar;
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#if defined(TIOCGLTC)
|
|
Packit |
910689 |
struct ltchars ltchar;
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#if defined(TIOCLGET)
|
|
Packit |
910689 |
int local;
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
};
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
#define USE_STTY
|
|
Packit |
910689 |
struct tbuffer {
|
|
Packit |
910689 |
int dummy;
|
|
Packit |
910689 |
};
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
static HV * filehash; /* Used to store the original terminal settings for each handle*/
|
|
Packit |
910689 |
static HV * modehash; /* Used to record the current terminal "mode" for each handle*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
void ReadMode(pTHX_ PerlIO *file,int mode)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
dTHR;
|
|
Packit |
910689 |
int handle;
|
|
Packit |
910689 |
int firsttime;
|
|
Packit |
910689 |
int oldmode;
|
|
Packit |
910689 |
struct tbuffer work;
|
|
Packit |
910689 |
struct tbuffer savebuf;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
handle=PerlIO_fileno(file);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
firsttime=!hv_exists(filehash, (char*)&handle, sizeof(int));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# ifdef WIN32
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (!GetConsoleMode((HANDLE)_get_osfhandle(handle), &work.Mode))
|
|
Packit |
910689 |
croak("GetConsoleMode failed, LastError=|%d|",GetLastError());
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# endif /* WIN32 */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# ifdef USE_TERMIOS
|
|
Packit |
910689 |
/* Posixy stuff */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
tcgetattr(handle,&work);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef USE_TERMIO
|
|
Packit |
910689 |
/* SysV stuff */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
ioctl(handle,TCGETA,&work);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef USE_SGTTY
|
|
Packit |
910689 |
/* BSD stuff */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
ioctl(handle,TIOCGETP,&work.buf);
|
|
Packit |
910689 |
# if defined(TIOCGETC)
|
|
Packit |
910689 |
ioctl(handle,TIOCGETC,&work.tchar);
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCLGET)
|
|
Packit |
910689 |
ioctl(handle,TIOCLGET,&work.local);
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
ioctl(handle,TIOCGLTC,&work.ltchar);
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if(firsttime) {
|
|
Packit |
910689 |
firsttime=0;
|
|
Packit |
910689 |
memcpy((void*)&savebuf,(void*)&work,sizeof(struct tbuffer));
|
|
Packit |
910689 |
if(!hv_store(filehash,(char*)&handle,sizeof(int),
|
|
Packit |
910689 |
newSVpv((char*)&savebuf,sizeof(struct tbuffer)),0))
|
|
Packit |
910689 |
croak("Unable to stash terminal settings.\n");
|
|
Packit |
910689 |
if(!hv_store(modehash,(char*)&handle,sizeof(int),newSViv(0),0))
|
|
Packit |
910689 |
croak("Unable to stash terminal settings.\n");
|
|
Packit |
910689 |
} else {
|
|
Packit |
910689 |
SV ** temp;
|
|
Packit |
910689 |
if(!(temp=hv_fetch(filehash,(char*)&handle,sizeof(int),0)))
|
|
Packit |
910689 |
croak("Unable to retrieve stashed terminal settings.\n");
|
|
Packit |
910689 |
memcpy(&savebuf,SvPV(*temp,PL_na),sizeof(struct tbuffer));
|
|
Packit |
910689 |
if(!(temp=hv_fetch(modehash,(char*)&handle,sizeof(int),0)))
|
|
Packit |
910689 |
croak("Unable to retrieve stashed terminal mode.\n");
|
|
Packit |
910689 |
oldmode=SvIV(*temp);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef WIN32
|
|
Packit |
910689 |
|
|
Packit |
910689 |
switch (mode) {
|
|
Packit |
910689 |
case 5:
|
|
Packit |
910689 |
/* Should 5 disable ENABLE_WRAP_AT_EOL_OUTPUT? */
|
|
Packit |
910689 |
case 4:
|
|
Packit |
910689 |
work.Mode &= ~(ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT|ENABLE_LINE_INPUT|ENABLE_PROCESSED_OUTPUT);
|
|
Packit |
910689 |
work.Mode |= 0;
|
|
Packit |
910689 |
break;
|
|
Packit |
910689 |
case 3:
|
|
Packit |
910689 |
work.Mode &= ~(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT);
|
|
Packit |
910689 |
work.Mode |= ENABLE_PROCESSED_INPUT|ENABLE_PROCESSED_OUTPUT;
|
|
Packit |
910689 |
break;
|
|
Packit |
910689 |
case 2:
|
|
Packit |
910689 |
work.Mode &= ~(ENABLE_ECHO_INPUT);
|
|
Packit |
910689 |
work.Mode |= ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT|ENABLE_PROCESSED_OUTPUT;
|
|
Packit |
910689 |
break;
|
|
Packit |
910689 |
case 1:
|
|
Packit |
910689 |
work.Mode &= ~(0);
|
|
Packit |
910689 |
work.Mode |= ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT|ENABLE_PROCESSED_OUTPUT;
|
|
Packit |
910689 |
break;
|
|
Packit |
910689 |
case 0:
|
|
Packit |
910689 |
work = savebuf;
|
|
Packit |
910689 |
firsttime = 1;
|
|
Packit |
910689 |
break;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (!SetConsoleMode((HANDLE)_get_osfhandle(handle), work.Mode))
|
|
Packit |
910689 |
croak("SetConsoleMode failed, LastError=|%d|",GetLastError());
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#endif /* WIN32 */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef USE_TERMIOS
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* What, me worry about standards? */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# if !defined (VMIN)
|
|
Packit |
910689 |
# define VMIN VEOF
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# if !defined (VTIME)
|
|
Packit |
910689 |
# define VTIME VEOL
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# if !defined (IXANY)
|
|
Packit |
910689 |
# define IXANY (0)
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifndef IEXTEN
|
|
Packit |
910689 |
#ifdef IDEFAULT
|
|
Packit |
910689 |
#define IEXTEN IDEFAULT
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* XXX Is ONLCR in POSIX?. The value of '4' seems to be the same for
|
|
Packit |
910689 |
both SysV and Sun, so it's probably rather general, and I'm not
|
|
Packit |
910689 |
aware of a POSIX way to do this otherwise.
|
|
Packit |
910689 |
*/
|
|
Packit |
910689 |
#ifndef ONLCR
|
|
Packit |
910689 |
# define ONLCR 4
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifndef IMAXBEL
|
|
Packit |
910689 |
#define IMAXBEL 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef ECHOE
|
|
Packit |
910689 |
#define ECHOE 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef ECHOK
|
|
Packit |
910689 |
#define ECHOK 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef ECHONL
|
|
Packit |
910689 |
#define ECHONL 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef ECHOPRT
|
|
Packit |
910689 |
#define ECHOPRT 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef FLUSHO
|
|
Packit |
910689 |
#define FLUSHO 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef PENDIN
|
|
Packit |
910689 |
#define PENDIN 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef ECHOKE
|
|
Packit |
910689 |
#define ECHOKE 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef ONLCR
|
|
Packit |
910689 |
#define ONLCR 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef OCRNL
|
|
Packit |
910689 |
#define OCRNL 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef ONLRET
|
|
Packit |
910689 |
#define ONLRET 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef IUCLC
|
|
Packit |
910689 |
#define IUCLC 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef OPOST
|
|
Packit |
910689 |
#define OPOST 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef OLCUC
|
|
Packit |
910689 |
#define OLCUC 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef ECHOCTL
|
|
Packit |
910689 |
#define ECHOCTL 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef XCASE
|
|
Packit |
910689 |
#define XCASE 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef BRKINT
|
|
Packit |
910689 |
#define BRKINT 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if(mode==5) {
|
|
Packit |
910689 |
/*\
|
|
Packit |
910689 |
* Disable everything except parity if needed.
|
|
Packit |
910689 |
\*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* Hopefully, this should put the tty into unbuffered mode
|
|
Packit |
910689 |
with signals and control characters (both posixy and normal)
|
|
Packit |
910689 |
disabled, along with flow control. Echo should be off.
|
|
Packit |
910689 |
CR/LF is not translated, along with 8-bit/parity */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
work.c_lflag &= ~(ICANON|ISIG|IEXTEN );
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ECHOCTL);
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHOPRT|ECHOKE|FLUSHO|PENDIN|XCASE);
|
|
Packit |
910689 |
work.c_lflag |= NOFLSH;
|
|
Packit |
910689 |
work.c_iflag &= ~(IXOFF|IXON|IXANY|ICRNL|IMAXBEL|BRKINT);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if(((work.c_iflag & INPCK) != INPCK) ||
|
|
Packit |
910689 |
((work.c_cflag & PARENB) != PARENB)) {
|
|
Packit |
910689 |
work.c_iflag &= ~ISTRIP;
|
|
Packit |
910689 |
work.c_iflag |= IGNPAR;
|
|
Packit |
910689 |
work.c_iflag &= ~PARMRK;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
work.c_oflag &= ~(OPOST |ONLCR|OCRNL|ONLRET);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
work.c_cc[VTIME] = 0;
|
|
Packit |
910689 |
work.c_cc[VMIN] = 1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==4) {
|
|
Packit |
910689 |
/* Hopefully, this should put the tty into unbuffered mode
|
|
Packit |
910689 |
with signals and control characters (both posixy and normal)
|
|
Packit |
910689 |
disabled, along with flow control. Echo should be off.
|
|
Packit |
910689 |
About the only thing left unchanged is 8-bit/parity */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*work.c_iflag = savebuf.c_iflag;*/
|
|
Packit |
910689 |
work.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO);
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHOE | ECHOK | ECHONL|ECHOCTL|ECHOPRT|ECHOKE);
|
|
Packit |
910689 |
work.c_iflag &= ~(IXON | IXANY | BRKINT);
|
|
Packit |
910689 |
work.c_oflag = savebuf.c_oflag;
|
|
Packit |
910689 |
work.c_cc[VTIME] = 0;
|
|
Packit |
910689 |
work.c_cc[VMIN] = 1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==3)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
/* This should be an unbuffered mode with signals and control
|
|
Packit |
910689 |
characters enabled, as should be flow control. Echo should
|
|
Packit |
910689 |
still be off */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
work.c_iflag = savebuf.c_iflag;
|
|
Packit |
910689 |
work.c_lflag &= ~(ICANON | ECHO);
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHOE | ECHOK | ECHONL|ECHOCTL|ECHOPRT|ECHOKE);
|
|
Packit |
910689 |
work.c_lflag |= ISIG | IEXTEN;
|
|
Packit |
910689 |
/*work.c_iflag &= ~(IXON | IXOFF | IXANY);
|
|
Packit |
910689 |
work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
|
|
Packit |
910689 |
work.c_oflag = savebuf.c_oflag;*/
|
|
Packit |
910689 |
work.c_cc[VTIME] = 0;
|
|
Packit |
910689 |
work.c_cc[VMIN] = 1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==2)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
/* This should be an unbuffered mode with signals and control
|
|
Packit |
910689 |
characters enabled, as should be flow control. Echo should
|
|
Packit |
910689 |
still be off */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
work.c_iflag = savebuf.c_iflag;
|
|
Packit |
910689 |
work.c_lflag |= ICANON|ISIG|IEXTEN;
|
|
Packit |
910689 |
work.c_lflag &= ~ECHO;
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHOE | ECHOK | ECHONL|ECHOCTL|ECHOPRT|ECHOKE);
|
|
Packit |
910689 |
/*work.c_iflag &= ~(IXON |IXOFF|IXANY);
|
|
Packit |
910689 |
work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
|
|
Packit |
910689 |
work.c_oflag = savebuf.c_oflag;
|
|
Packit |
910689 |
work.c_cc[VTIME] = savebuf.c_cc[VTIME];
|
|
Packit |
910689 |
work.c_cc[VMIN] = savebuf.c_cc[VMIN];*/
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==1)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
/* This should be an unbuffered mode with signals and control
|
|
Packit |
910689 |
characters enabled, as should be flow control. Echo should
|
|
Packit |
910689 |
still be off */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
work.c_iflag = savebuf.c_iflag;
|
|
Packit |
910689 |
work.c_lflag |= ICANON|ECHO|ISIG|IEXTEN;
|
|
Packit |
910689 |
/*work.c_iflag &= ~(IXON |IXOFF|IXANY);
|
|
Packit |
910689 |
work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
|
|
Packit |
910689 |
work.c_oflag = savebuf.c_oflag;
|
|
Packit |
910689 |
work.c_cc[VTIME] = savebuf.c_cc[VTIME];
|
|
Packit |
910689 |
work.c_cc[VMIN] = savebuf.c_cc[VMIN];*/
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==0){
|
|
Packit |
910689 |
/*work.c_lflag &= ~BITMASK;
|
|
Packit |
910689 |
work.c_lflag |= savebuf.c_lflag & BITMASK;
|
|
Packit |
910689 |
work.c_oflag = savebuf.c_oflag;
|
|
Packit |
910689 |
work.c_cc[VTIME] = savebuf.c_cc[VTIME];
|
|
Packit |
910689 |
work.c_cc[VMIN] = savebuf.c_cc[VMIN];
|
|
Packit |
910689 |
work.c_iflag = savebuf.c_iflag;
|
|
Packit |
910689 |
work.c_iflag &= ~(IXON|IXOFF|IXANY);
|
|
Packit |
910689 |
work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);*/
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
/*Copy(&work,&savebuf,1,sizeof(struct tbuffer));*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
firsttime=1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("ReadMode %d is not implemented on this architecture.",mode);
|
|
Packit |
910689 |
return;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* If switching from a "lower power" mode to a higher one, keep the
|
|
Packit |
910689 |
data that may be in the queue, as it can easily be type-ahead. On
|
|
Packit |
910689 |
switching to a lower mode from a higher one, however, flush the queue
|
|
Packit |
910689 |
so that raw keystrokes won't hit an unexpecting program */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if(DisableFlush || oldmode<=mode)
|
|
Packit |
910689 |
tcsetattr(handle,TCSANOW,&work);
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
tcsetattr(handle,TCSAFLUSH,&work);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*tcsetattr(handle,TCSANOW,&work);*/ /* It might be better to FLUSH
|
|
Packit |
910689 |
when changing gears to a lower mode,
|
|
Packit |
910689 |
and only use NOW for higher modes.
|
|
Packit |
910689 |
*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef USE_TERMIO
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* What, me worry about standards? */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# if !defined (IXANY)
|
|
Packit |
910689 |
# define IXANY (0)
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifndef ECHOE
|
|
Packit |
910689 |
#define ECHOE 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef ECHOK
|
|
Packit |
910689 |
#define ECHOK 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef ECHONL
|
|
Packit |
910689 |
#define ECHONL 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef XCASE
|
|
Packit |
910689 |
#define XCASE 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifndef BRKINT
|
|
Packit |
910689 |
#define BRKINT 0
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if(mode==5) {
|
|
Packit |
910689 |
/* This mode should be echo disabled, signals disabled,
|
|
Packit |
910689 |
flow control disabled, and unbuffered. CR/LF translation
|
|
Packit |
910689 |
is off, and 8 bits if possible */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHO | ISIG | ICANON | XCASE);
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHOE | ECHOK | ECHONL | TRK_IDEFAULT);
|
|
Packit |
910689 |
work.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | BRKINT);
|
|
Packit |
910689 |
if((work.c_cflag | PARENB)!=PARENB ) {
|
|
Packit |
910689 |
work.c_iflag &= ~(ISTRIP|INPCK);
|
|
Packit |
910689 |
work.c_iflag |= IGNPAR;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
work.c_oflag &= ~(OPOST|ONLCR);
|
|
Packit |
910689 |
work.c_cc[VMIN] = 1;
|
|
Packit |
910689 |
work.c_cc[VTIME] = 1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==4) {
|
|
Packit |
910689 |
/* This mode should be echo disabled, signals disabled,
|
|
Packit |
910689 |
flow control disabled, and unbuffered. Parity is not
|
|
Packit |
910689 |
touched. */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHO | ISIG | ICANON);
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHOE | ECHOK | ECHONL TRK_IDEFAULT);
|
|
Packit |
910689 |
work.c_iflag = savebuf.c_iflag;
|
|
Packit |
910689 |
work.c_iflag &= ~(IXON | IXOFF | IXANY | BRKINT);
|
|
Packit |
910689 |
work.c_oflag = savebuf.c_oflag;
|
|
Packit |
910689 |
work.c_cc[VMIN] = 1;
|
|
Packit |
910689 |
work.c_cc[VTIME] = 1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==3) {
|
|
Packit |
910689 |
/* This mode tries to have echo off, signals enabled,
|
|
Packit |
910689 |
flow control as per the original setting, and unbuffered. */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHO | ICANON);
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHOE | ECHOK | ECHONL | TRK_IDEFAULT);
|
|
Packit |
910689 |
work.c_lflag |= ISIG;
|
|
Packit |
910689 |
work.c_iflag = savebuf.c_iflag;
|
|
Packit |
910689 |
work.c_iflag &= ~(IXON | IXOFF | IXANY);
|
|
Packit |
910689 |
work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
|
|
Packit |
910689 |
work.c_oflag = savebuf.c_oflag;
|
|
Packit |
910689 |
work.c_cc[VMIN] = 1;
|
|
Packit |
910689 |
work.c_cc[VTIME] = 1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==2) {
|
|
Packit |
910689 |
/* This mode tries to set echo on, signals on, and buffering
|
|
Packit |
910689 |
on, with flow control set to whatever it was originally. */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
work.c_lflag |= (ISIG | ICANON);
|
|
Packit |
910689 |
work.c_lflag &= ~ECHO;
|
|
Packit |
910689 |
work.c_lflag &= ~(ECHOE | ECHOK | ECHONL | TRK_IDEFAULT);
|
|
Packit |
910689 |
work.c_iflag = savebuf.c_iflag;
|
|
Packit |
910689 |
work.c_iflag &= ~(IXON | IXOFF | IXANY);
|
|
Packit |
910689 |
work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
|
|
Packit |
910689 |
work.c_oflag = savebuf.c_oflag;
|
|
Packit |
910689 |
work.c_cc[VMIN] = savebuf.c_cc[VMIN];
|
|
Packit |
910689 |
work.c_cc[VTIME] = savebuf.c_cc[VTIME];
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* This assumes turning ECHO and ICANON back on is
|
|
Packit |
910689 |
sufficient to re-enable cooked mode. If this is a
|
|
Packit |
910689 |
problem, complain to me */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* What the heck. We're already saving the entire buf, so
|
|
Packit |
910689 |
I'm now going to reset VMIN and VTIME too. Hope this works
|
|
Packit |
910689 |
properly */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==1) {
|
|
Packit |
910689 |
/* This mode tries to set echo on, signals on, and buffering
|
|
Packit |
910689 |
on, with flow control set to whatever it was originally. */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
|
|
Packit |
910689 |
work.c_lflag |= (ECHO | ISIG | ICANON);
|
|
Packit |
910689 |
work.c_iflag &= ~TRK_IDEFAULT;
|
|
Packit |
910689 |
work.c_iflag = savebuf.c_iflag;
|
|
Packit |
910689 |
work.c_iflag &= ~(IXON | IXOFF | IXANY);
|
|
Packit |
910689 |
work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
|
|
Packit |
910689 |
work.c_oflag = savebuf.c_oflag;
|
|
Packit |
910689 |
work.c_cc[VMIN] = savebuf.c_cc[VMIN];
|
|
Packit |
910689 |
work.c_cc[VTIME] = savebuf.c_cc[VTIME];
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* This assumes turning ECHO and ICANON back on is
|
|
Packit |
910689 |
sufficient to re-enable cooked mode. If this is a
|
|
Packit |
910689 |
problem, complain to me */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* What the heck. We're already saving the entire buf, so
|
|
Packit |
910689 |
I'm now going to reset VMIN and VTIME too. Hope this works
|
|
Packit |
910689 |
properly */
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==0) {
|
|
Packit |
910689 |
/* Put things back the way they were */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*work.c_lflag = savebuf.c_lflag;
|
|
Packit |
910689 |
work.c_iflag = savebuf.c_iflag;
|
|
Packit |
910689 |
work.c_oflag = savebuf.c_oflag;
|
|
Packit |
910689 |
work.c_cc[VMIN] = savebuf.c_cc[VMIN];
|
|
Packit |
910689 |
work.c_cc[VTIME] = savebuf.c_cc[VTIME];*/
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
firsttime=1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("ReadMode %d is not implemented on this architecture.",mode);
|
|
Packit |
910689 |
return;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if(DisableFlush || oldmode<=mode)
|
|
Packit |
910689 |
ioctl(handle,TCSETA,&work);
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
ioctl(handle,TCSETAF,&work);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef USE_SGTTY
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if(mode==5) {
|
|
Packit |
910689 |
/* Unbuffered, echo off, signals off, flow control off */
|
|
Packit |
910689 |
/* CR-CR/LF mode off too, and 8-bit path enabled. */
|
|
Packit |
910689 |
# if defined(TIOCLGET) && defined(LPASS8)
|
|
Packit |
910689 |
if((work.buf.sg_flags & (EVENP|ODDP))==0 ||
|
|
Packit |
910689 |
(work.buf.sg_flags & (EVENP|ODDP))==(EVENP|ODDP))
|
|
Packit |
910689 |
work.local |= LPASS8; /* If parity isn't being used, use 8 bits */
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
work.buf.sg_flags &= ~(ECHO|CRMOD);
|
|
Packit |
910689 |
work.buf.sg_flags |= (RAW|CBREAK);
|
|
Packit |
910689 |
# if defined(TIOCGETC)
|
|
Packit |
910689 |
work.tchar.t_intrc = -1;
|
|
Packit |
910689 |
work.tchar.t_quitc = -1;
|
|
Packit |
910689 |
work.tchar.t_startc= -1;
|
|
Packit |
910689 |
work.tchar.t_stopc = -1;
|
|
Packit |
910689 |
work.tchar.t_eofc = -1;
|
|
Packit |
910689 |
work.tchar.t_brkc = -1;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
work.ltchar.t_suspc= -1;
|
|
Packit |
910689 |
work.ltchar.t_dsuspc= -1;
|
|
Packit |
910689 |
work.ltchar.t_rprntc= -1;
|
|
Packit |
910689 |
work.ltchar.t_flushc= -1;
|
|
Packit |
910689 |
work.ltchar.t_werasc= -1;
|
|
Packit |
910689 |
work.ltchar.t_lnextc= -1;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==4) {
|
|
Packit |
910689 |
/* Unbuffered, echo off, signals off, flow control off */
|
|
Packit |
910689 |
work.buf.sg_flags &= ~(ECHO|RAW);
|
|
Packit |
910689 |
work.buf.sg_flags |= (CBREAK|CRMOD);
|
|
Packit |
910689 |
# if defined(TIOCLGET)
|
|
Packit |
910689 |
work.local=savebuf.local;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGETC)
|
|
Packit |
910689 |
work.tchar.t_intrc = -1;
|
|
Packit |
910689 |
work.tchar.t_quitc = -1;
|
|
Packit |
910689 |
work.tchar.t_startc= -1;
|
|
Packit |
910689 |
work.tchar.t_stopc = -1;
|
|
Packit |
910689 |
work.tchar.t_eofc = -1;
|
|
Packit |
910689 |
work.tchar.t_brkc = -1;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
work.ltchar.t_suspc= -1;
|
|
Packit |
910689 |
work.ltchar.t_dsuspc= -1;
|
|
Packit |
910689 |
work.ltchar.t_rprntc= -1;
|
|
Packit |
910689 |
work.ltchar.t_flushc= -1;
|
|
Packit |
910689 |
work.ltchar.t_werasc= -1;
|
|
Packit |
910689 |
work.ltchar.t_lnextc= -1;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==3) {
|
|
Packit |
910689 |
/* Unbuffered, echo off, signals on, flow control on */
|
|
Packit |
910689 |
work.buf.sg_flags &= ~(RAW|ECHO);
|
|
Packit |
910689 |
work.buf.sg_flags |= CBREAK|CRMOD;
|
|
Packit |
910689 |
# if defined(TIOCLGET)
|
|
Packit |
910689 |
work.local=savebuf.local;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
work.tchar = savebuf.tchar;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
work.ltchar = savebuf.ltchar;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==2) {
|
|
Packit |
910689 |
/* Buffered, echo on, signals on, flow control on */
|
|
Packit |
910689 |
work.buf.sg_flags &= ~(RAW|CBREAK);
|
|
Packit |
910689 |
work.buf.sg_flags |= CRMOD;
|
|
Packit |
910689 |
work.buf.sg_flags &= ~ECHO;
|
|
Packit |
910689 |
# if defined(TIOCLGET)
|
|
Packit |
910689 |
work.local=savebuf.local;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
work.tchar = savebuf.tchar;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
work.ltchar = savebuf.ltchar;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==1) {
|
|
Packit |
910689 |
/* Buffered, echo on, signals on, flow control on */
|
|
Packit |
910689 |
work.buf.sg_flags &= ~(RAW|CBREAK);
|
|
Packit |
910689 |
work.buf.sg_flags |= ECHO|CRMOD;
|
|
Packit |
910689 |
# if defined(TIOCLGET)
|
|
Packit |
910689 |
work.local=savebuf.local;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
work.tchar = savebuf.tchar;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
work.ltchar = savebuf.ltchar;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else if(mode==0){
|
|
Packit |
910689 |
/* Original settings */
|
|
Packit |
910689 |
#if 0
|
|
Packit |
910689 |
work.buf.sg_flags &= ~(RAW|CBREAK|ECHO|CRMOD);
|
|
Packit |
910689 |
work.buf.sg_flags |= savebuf.sg_flags & (RAW|CBREAK|ECHO|CRMOD);
|
|
Packit |
910689 |
# if defined(TIOCLGET)
|
|
Packit |
910689 |
work.local=savebuf.local;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
work.tchar = savebuf.tchar;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
work.ltchar = savebuf.ltchar;
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
|
|
Packit |
910689 |
firsttime=1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("ReadMode %d is not implemented on this architecture.",mode);
|
|
Packit |
910689 |
return;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#if defined(TIOCLSET)
|
|
Packit |
910689 |
ioctl(handle,TIOCLSET,&work.local);
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#if defined(TIOCSETC)
|
|
Packit |
910689 |
ioctl(handle,TIOCSETC,&work.tchar);
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
# if defined(TIOCGLTC)
|
|
Packit |
910689 |
ioctl(handle,TIOCSLTC,&work.ltchar);
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
if(DisableFlush || oldmode<=mode)
|
|
Packit |
910689 |
ioctl(handle,TIOCSETN,&work.buf);
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
ioctl(handle,TIOCSETP,&work.buf);
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef USE_STTY
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* No termio, termios or sgtty. I suppose we can try stty,
|
|
Packit |
910689 |
but it would be nice if you could get a better OS */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if(mode==5)
|
|
Packit |
910689 |
system("/bin/stty raw -cbreak -isig -echo -ixon -onlcr -icrnl -brkint");
|
|
Packit |
910689 |
else if(mode==4)
|
|
Packit |
910689 |
system("/bin/stty -raw cbreak -isig -echo -ixon onlcr icrnl -brkint");
|
|
Packit |
910689 |
else if(mode==3)
|
|
Packit |
910689 |
system("/bin/stty -raw cbreak isig -echo ixon onlcr icrnl brkint");
|
|
Packit |
910689 |
else if(mode==2)
|
|
Packit |
910689 |
system("/bin/stty -raw -cbreak isig echo ixon onlcr icrnl brkint");
|
|
Packit |
910689 |
else if(mode==1)
|
|
Packit |
910689 |
system("/bin/stty -raw -cbreak isig -echo ixon onlcr icrnl brkint");
|
|
Packit |
910689 |
else if(mode==0)
|
|
Packit |
910689 |
system("/bin/stty -raw -cbreak isig echo ixon onlcr icrnl brkint");
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* Those probably won't work, but they couldn't hurt
|
|
Packit |
910689 |
at this point */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*warn("Mode set to %d.\n",mode);*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if( firsttime ) {
|
|
Packit |
910689 |
(void)hv_delete(filehash,(char*)&handle,sizeof(int),0);
|
|
Packit |
910689 |
(void)hv_delete(modehash,(char*)&handle,sizeof(int),0);
|
|
Packit |
910689 |
} else {
|
|
Packit |
910689 |
if(!hv_store(modehash,(char*)&handle,sizeof(int),
|
|
Packit |
910689 |
newSViv(mode),0))
|
|
Packit |
910689 |
croak("Unable to stash terminal settings.\n");
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef USE_PERLIO
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* Make use of a recent addition to Perl, if possible */
|
|
Packit |
910689 |
# define FCOUNT(f) PerlIO_get_cnt(f)
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* Make use of a recent addition to Configure, if possible */
|
|
Packit |
910689 |
# ifdef USE_STDIO_PTR
|
|
Packit |
910689 |
# define FCOUNT(f) PerlIO_get_cnt(f)
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
/* This bit borrowed from pp_sys.c. Complain to Larry if it's broken. */
|
|
Packit |
910689 |
/* If any of this works PerlIO_get_cnt() will too ... NI-S */
|
|
Packit |
910689 |
# if defined(USE_STD_STDIO) || defined(atarist) /* this will work with atariST */
|
|
Packit |
910689 |
# define FBASE(f) ((f)->_base)
|
|
Packit |
910689 |
# define FSIZE(f) ((f)->_cnt + ((f)->_ptr - (f)->_base))
|
|
Packit |
910689 |
# define FPTR(f) ((f)->_ptr)
|
|
Packit |
910689 |
# define FCOUNT(f) ((f)->_cnt)
|
|
Packit |
910689 |
# else
|
|
Packit |
910689 |
# if defined(USE_LINUX_STDIO)
|
|
Packit |
910689 |
# define FBASE(f) ((f)->_IO_read_base)
|
|
Packit |
910689 |
# define FSIZE(f) ((f)->_IO_read_end - FBASE(f))
|
|
Packit |
910689 |
# define FPTR(f) ((f)->_IO_read_ptr)
|
|
Packit |
910689 |
# define FCOUNT(f) ((f)->_IO_read_end - FPTR(f))
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* This is for the best, I'm afraid. */
|
|
Packit |
910689 |
#if !defined(FCOUNT)
|
|
Packit |
910689 |
# ifdef Have_select
|
|
Packit |
910689 |
# undef Have_select
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
# ifdef Have_poll
|
|
Packit |
910689 |
# undef Have_poll
|
|
Packit |
910689 |
# endif
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* Note! If your machine has a bolixed up select() call that doesn't
|
|
Packit |
910689 |
understand this syntax, either fix the checkwaiting call below, or define
|
|
Packit |
910689 |
DONT_USE_SELECT. */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef Have_select
|
|
Packit |
910689 |
int selectfile(pTHX_ PerlIO *file,double delay)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
struct timeval t;
|
|
Packit |
910689 |
int handle=PerlIO_fileno(file);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*char buf[32];
|
|
Packit |
910689 |
Select_fd_set_t fd=(Select_fd_set_t)&buf[0];*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
fd_set fd;
|
|
Packit |
910689 |
if (PerlIO_fast_gets(file) && PerlIO_get_cnt(file) > 0)
|
|
Packit |
910689 |
return 1;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*t.tv_sec=t.tv_usec=0;*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (delay < 0.0)
|
|
Packit |
910689 |
delay = 0.0;
|
|
Packit |
910689 |
t.tv_sec = (long)delay;
|
|
Packit |
910689 |
delay -= (double)t.tv_sec;
|
|
Packit |
910689 |
t.tv_usec = (long)(delay * 1000000.0);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
FD_ZERO(&fd;;
|
|
Packit |
910689 |
FD_SET(handle,&fd;;
|
|
Packit |
910689 |
if(select(handle+1,(Select_fd_set_t)&fd,
|
|
Packit |
910689 |
(Select_fd_set_t)0,
|
|
Packit |
910689 |
(Select_fd_set_t)&fd, &t)) return -1;
|
|
Packit |
910689 |
else return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
int selectfile(pTHX_ PerlIO *file, double delay)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("select is not supported on this architecture");
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef Have_nodelay
|
|
Packit |
910689 |
int setnodelay(pTHX_ PerlIO *file, int mode)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int handle=PerlIO_fileno(file);
|
|
Packit |
910689 |
int flags;
|
|
Packit |
910689 |
flags=fcntl(handle,F_GETFL,0);
|
|
Packit |
910689 |
if(mode)
|
|
Packit |
910689 |
flags|=O_NODELAY;
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
flags&=~O_NODELAY;
|
|
Packit |
910689 |
fcntl(handle,F_SETFL,flags);
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
int setnodelay(pTHX_ PerlIO *file, int mode)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("setnodelay is not supported on this architecture");
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef Have_poll
|
|
Packit |
910689 |
int pollfile(pTHX_ pTHX_ PerlIO *file,double delay)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int handle=PerlIO_fileno(file);
|
|
Packit |
910689 |
struct pollfd fds;
|
|
Packit |
910689 |
if (PerlIO_fast_gets(f) && PerlIO_get_cnt(f) > 0)
|
|
Packit |
910689 |
return 1;
|
|
Packit |
910689 |
if(delay<0.0) delay = 0.0;
|
|
Packit |
910689 |
fds.fd=handle;
|
|
Packit |
910689 |
fds.events=POLLIN;
|
|
Packit |
910689 |
fds.revents=0;
|
|
Packit |
910689 |
return (poll(&fds,1,(long)(delay * 1000.0))>0);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
int pollfile(pTHX_ PerlIO *file,double delay)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("pollfile is not supported on this architecture");
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#ifdef WIN32
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/*
|
|
Packit |
910689 |
|
|
Packit |
910689 |
This portion of the Win32 code is partially borrowed from a version of PDCurses.
|
|
Packit |
910689 |
|
|
Packit |
910689 |
*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
typedef struct {
|
|
Packit |
910689 |
int repeatCount;
|
|
Packit |
910689 |
int vKey;
|
|
Packit |
910689 |
int vScan;
|
|
Packit |
910689 |
int ascii;
|
|
Packit |
910689 |
int control;
|
|
Packit |
910689 |
} win32_key_event_t;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#define KEY_PUSH(I, K) { events[I].repeatCount = 1; events[I].ascii = K; }
|
|
Packit |
910689 |
#define KEY_PUSH3(K1, K2, K3) \
|
|
Packit |
910689 |
do { \
|
|
Packit |
910689 |
eventCount = 0; \
|
|
Packit |
910689 |
KEY_PUSH(2, K1); \
|
|
Packit |
910689 |
KEY_PUSH(1, K2); \
|
|
Packit |
910689 |
KEY_PUSH(0, K3); \
|
|
Packit |
910689 |
eventCount = 3; \
|
|
Packit |
910689 |
goto again; \
|
|
Packit |
910689 |
} while (0)
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#define KEY_PUSH4(K1, K2, K3, K4) \
|
|
Packit |
910689 |
do { \
|
|
Packit |
910689 |
eventCount = 0; \
|
|
Packit |
910689 |
KEY_PUSH(3, K1); \
|
|
Packit |
910689 |
KEY_PUSH(2, K2); \
|
|
Packit |
910689 |
KEY_PUSH(1, K3); \
|
|
Packit |
910689 |
KEY_PUSH(0, K4); \
|
|
Packit |
910689 |
eventCount = 4; \
|
|
Packit |
910689 |
goto again; \
|
|
Packit |
910689 |
} while (0)
|
|
Packit |
910689 |
|
|
Packit |
910689 |
int Win32PeekChar(pTHX_ PerlIO *file,U32 delay,char *key)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int handle;
|
|
Packit |
910689 |
HANDLE whnd;
|
|
Packit |
910689 |
INPUT_RECORD record;
|
|
Packit |
910689 |
DWORD readRecords;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#if 0
|
|
Packit |
910689 |
static int keyCount = 0;
|
|
Packit |
910689 |
static char lastKey = 0;
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
#define MAX_EVENTS 4
|
|
Packit |
910689 |
static int eventCount = 0;
|
|
Packit |
910689 |
static win32_key_event_t events[MAX_EVENTS];
|
|
Packit |
910689 |
int keyCount;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
file = STDIN;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
handle = PerlIO_fileno(file);
|
|
Packit |
910689 |
whnd = /*GetStdHandle(STD_INPUT_HANDLE)*/(HANDLE)_get_osfhandle(handle);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
again:
|
|
Packit |
910689 |
#if 0
|
|
Packit |
910689 |
if (keyCount > 0) {
|
|
Packit |
910689 |
keyCount--;
|
|
Packit |
910689 |
*key = lastKey;
|
|
Packit |
910689 |
return TRUE;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* printf("eventCount: %d\n", eventCount); */
|
|
Packit |
910689 |
if (eventCount) {
|
|
Packit |
910689 |
/* printf("key %d; repeatCount %d\n", *key, events[eventCount - 1].repeatCount); */
|
|
Packit |
910689 |
*key = events[eventCount - 1].ascii;
|
|
Packit |
910689 |
events[eventCount - 1].repeatCount--;
|
|
Packit |
910689 |
if (events[eventCount - 1].repeatCount <= 0) {
|
|
Packit |
910689 |
eventCount--;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
return TRUE;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (delay > 0) {
|
|
Packit |
910689 |
if (WaitForSingleObject(whnd, delay * 1000) != WAIT_OBJECT_0)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
return FALSE;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (delay != 0) {
|
|
Packit |
910689 |
PeekConsoleInput(whnd, &record, 1, &readRecords);
|
|
Packit |
910689 |
if (readRecords == 0) {
|
|
Packit |
910689 |
return(FALSE);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
ReadConsoleInput(whnd, &record, 1, &readRecords);
|
|
Packit |
910689 |
switch(record.EventType)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
case KEY_EVENT:
|
|
Packit |
910689 |
/* printf("\nkeyDown = %d, repeat = %d, vKey = %d, vScan = %d, ASCII = %d, Control = %d\n",
|
|
Packit |
910689 |
record.Event.KeyEvent.bKeyDown,
|
|
Packit |
910689 |
record.Event.KeyEvent.wRepeatCount,
|
|
Packit |
910689 |
record.Event.KeyEvent.wVirtualKeyCode,
|
|
Packit |
910689 |
record.Event.KeyEvent.wVirtualScanCode,
|
|
Packit |
910689 |
record.Event.KeyEvent.uChar.AsciiChar,
|
|
Packit |
910689 |
record.Event.KeyEvent.dwControlKeyState); */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (record.Event.KeyEvent.bKeyDown == FALSE)
|
|
Packit |
910689 |
goto again; /* throw away KeyUp events */
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 38) { /* up */
|
|
Packit |
910689 |
KEY_PUSH3(27, 91, 65);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 40) { /* down */
|
|
Packit |
910689 |
KEY_PUSH3(27, 91, 66);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 39) { /* right */
|
|
Packit |
910689 |
KEY_PUSH3(27, 91, 67);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 37) { /* left */
|
|
Packit |
910689 |
KEY_PUSH3(27, 91, 68);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 33) { /* page up */
|
|
Packit |
910689 |
KEY_PUSH3(27, 79, 121);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 34) { /* page down */
|
|
Packit |
910689 |
KEY_PUSH3(27, 79, 115);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 36) { /* home */
|
|
Packit |
910689 |
KEY_PUSH4(27, 91, 49, 126);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 35) { /* end */
|
|
Packit |
910689 |
KEY_PUSH4(27, 91, 52, 126);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 45) { /* insert */
|
|
Packit |
910689 |
KEY_PUSH4(27, 91, 50, 126);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 46) { /* delete */
|
|
Packit |
910689 |
KEY_PUSH4(27, 91, 51, 126);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (record.Event.KeyEvent.wVirtualKeyCode == 16
|
|
Packit |
910689 |
|| record.Event.KeyEvent.wVirtualKeyCode == 17
|
|
Packit |
910689 |
|| record.Event.KeyEvent.wVirtualKeyCode == 18
|
|
Packit |
910689 |
|| record.Event.KeyEvent.wVirtualKeyCode == 20
|
|
Packit |
910689 |
|| record.Event.KeyEvent.wVirtualKeyCode == 144
|
|
Packit |
910689 |
|| record.Event.KeyEvent.wVirtualKeyCode == 145)
|
|
Packit |
910689 |
goto again; /* throw away shift/alt/ctrl key only key events */
|
|
Packit |
910689 |
keyCount = record.Event.KeyEvent.wRepeatCount;
|
|
Packit |
910689 |
break;
|
|
Packit |
910689 |
default:
|
|
Packit |
910689 |
keyCount = 0;
|
|
Packit |
910689 |
goto again;
|
|
Packit |
910689 |
break;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
*key = record.Event.KeyEvent.uChar.AsciiChar;
|
|
Packit |
910689 |
keyCount--;
|
|
Packit |
910689 |
|
|
Packit |
910689 |
if (keyCount) {
|
|
Packit |
910689 |
events[0].repeatCount = keyCount;
|
|
Packit |
910689 |
events[0].ascii = *key;
|
|
Packit |
910689 |
eventCount = 1;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
return(TRUE);
|
|
Packit |
910689 |
|
|
Packit |
910689 |
/* again:
|
|
Packit |
910689 |
return (FALSE);
|
|
Packit |
910689 |
*/
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#else
|
|
Packit |
910689 |
int Win32PeekChar(pTHX_ PerlIO *file, U32 delay,char *key)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
croak("Win32PeekChar is not supported on this architecture");
|
|
Packit |
910689 |
return 0;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int blockoptions() {
|
|
Packit |
910689 |
return 0
|
|
Packit |
910689 |
#ifdef Have_nodelay
|
|
Packit |
910689 |
| 1
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef Have_poll
|
|
Packit |
910689 |
| 2
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef Have_select
|
|
Packit |
910689 |
| 4
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef USE_WIN32
|
|
Packit |
910689 |
| 8
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
STATIC int termoptions() {
|
|
Packit |
910689 |
int i=0;
|
|
Packit |
910689 |
#ifdef USE_TERMIOS
|
|
Packit |
910689 |
i=1;
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef USE_TERMIO
|
|
Packit |
910689 |
i=2;
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef USE_SGTTY
|
|
Packit |
910689 |
i=3;
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef USE_STTY
|
|
Packit |
910689 |
i=4;
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
#ifdef USE_WIN32
|
|
Packit |
910689 |
i=5;
|
|
Packit |
910689 |
#endif
|
|
Packit |
910689 |
return i;
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
MODULE = Term::ReadKey PACKAGE = Term::ReadKey
|
|
Packit |
910689 |
|
|
Packit |
910689 |
int
|
|
Packit |
910689 |
selectfile(file,delay)
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
double delay
|
|
Packit |
910689 |
CODE:
|
|
Packit |
910689 |
RETVAL = selectfile(aTHX_ file, delay);
|
|
Packit |
910689 |
OUTPUT:
|
|
Packit |
910689 |
RETVAL
|
|
Packit |
910689 |
|
|
Packit |
910689 |
# Clever, eh?
|
|
Packit |
910689 |
void
|
|
Packit |
910689 |
SetReadMode(mode,file=STDIN)
|
|
Packit |
910689 |
int mode
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
CODE:
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
ReadMode(aTHX_ file,mode);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
int
|
|
Packit |
910689 |
setnodelay(file,mode)
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
int mode
|
|
Packit |
910689 |
CODE:
|
|
Packit |
910689 |
RETVAL = setnodelay(aTHX_ file, mode);
|
|
Packit |
910689 |
OUTPUT:
|
|
Packit |
910689 |
RETVAL
|
|
Packit |
910689 |
|
|
Packit |
910689 |
int
|
|
Packit |
910689 |
pollfile(file,delay)
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
double delay
|
|
Packit |
910689 |
CODE:
|
|
Packit |
910689 |
RETVAL = pollfile(aTHX_ file, delay);
|
|
Packit |
910689 |
OUTPUT:
|
|
Packit |
910689 |
RETVAL
|
|
Packit |
910689 |
|
|
Packit |
910689 |
SV *
|
|
Packit |
910689 |
Win32PeekChar(file, delay)
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
U32 delay
|
|
Packit |
910689 |
CODE:
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
char key;
|
|
Packit |
910689 |
if (Win32PeekChar(aTHX_ file, delay, &key))
|
|
Packit |
910689 |
RETVAL = newSVpv(&key, 1);
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
RETVAL = newSVsv(&PL_sv_undef);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
OUTPUT:
|
|
Packit |
910689 |
RETVAL
|
|
Packit |
910689 |
|
|
Packit |
910689 |
int
|
|
Packit |
910689 |
blockoptions()
|
|
Packit |
910689 |
|
|
Packit |
910689 |
int
|
|
Packit |
910689 |
termoptions()
|
|
Packit |
910689 |
|
|
Packit |
910689 |
int
|
|
Packit |
910689 |
termsizeoptions()
|
|
Packit |
910689 |
|
|
Packit |
910689 |
void
|
|
Packit |
910689 |
GetTermSizeWin32(file=STDIN)
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
PPCODE:
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int x,y,xpix,ypix;
|
|
Packit |
910689 |
if( GetTermSizeWin32(aTHX_ file,&x,&y,&xpix,&ypix)==0)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
EXTEND(sp, 4);
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)x)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)y)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)xpix)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)ypix)));
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
ST(0) = sv_newmortal();
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
void
|
|
Packit |
910689 |
GetTermSizeVIO(file=STDIN)
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
PPCODE:
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int x,y,xpix,ypix;
|
|
Packit |
910689 |
if( GetTermSizeVIO(aTHX_ file,&x,&y,&xpix,&ypix)==0)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
EXTEND(sp, 4);
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)x)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)y)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)xpix)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)ypix)));
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
ST(0) = sv_newmortal();
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
void
|
|
Packit |
910689 |
GetTermSizeGWINSZ(file=STDIN)
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
PPCODE:
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int x,y,xpix,ypix;
|
|
Packit |
910689 |
if( GetTermSizeGWINSZ(aTHX_ file,&x,&y,&xpix,&ypix)==0)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
EXTEND(sp, 4);
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)x)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)y)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)xpix)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)ypix)));
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
ST(0) = sv_newmortal();
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
void
|
|
Packit |
910689 |
GetTermSizeGSIZE(file=STDIN)
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
PPCODE:
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
int x,y,xpix,ypix;
|
|
Packit |
910689 |
if( GetTermSizeGSIZE(aTHX_ file,&x,&y,&xpix,&ypix)==0)
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
EXTEND(sp, 4);
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)x)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)y)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)xpix)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)ypix)));
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
else
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
ST(0) = sv_newmortal();
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
int
|
|
Packit |
910689 |
SetTerminalSize(width,height,xpix,ypix,file=STDIN)
|
|
Packit |
910689 |
int width
|
|
Packit |
910689 |
int height
|
|
Packit |
910689 |
int xpix
|
|
Packit |
910689 |
int ypix
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
CODE:
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
RETVAL=SetTerminalSize(aTHX_ file,width,height,xpix,ypix);
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
OUTPUT:
|
|
Packit |
910689 |
RETVAL
|
|
Packit |
910689 |
|
|
Packit |
910689 |
void
|
|
Packit |
910689 |
GetSpeed(file=STDIN)
|
|
Packit |
910689 |
InputStream file
|
|
Packit |
910689 |
PPCODE:
|
|
Packit |
910689 |
{
|
|
Packit |
910689 |
I32 in,out;
|
|
Packit |
910689 |
/*
|
|
Packit |
910689 |
* experimentally relaxed for
|
|
Packit |
910689 |
* https://rt.cpan.org/Ticket/Display.html?id=88050
|
|
Packit |
910689 |
if(items!=0) {
|
|
Packit |
910689 |
croak("Usage: Term::ReadKey::GetSpeed()");
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
*/
|
|
Packit |
910689 |
if(getspeed(aTHX_ file,&in,&out)) {
|
|
Packit |
910689 |
/* Failure */
|
|
Packit |
910689 |
ST( 0) = sv_newmortal();
|
|
Packit |
910689 |
} else {
|
|
Packit |
910689 |
EXTEND(sp, 2);
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)in)));
|
|
Packit |
910689 |
PUSHs(sv_2mortal(newSViv((IV)out)));
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
}
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
|
|
Packit |
910689 |
BOOT:
|
|
Packit |
910689 |
newXS("Term::ReadKey::GetControlChars", XS_Term__ReadKey_GetControlChars, file);
|
|
Packit |
910689 |
newXS("Term::ReadKey::SetControlChars", XS_Term__ReadKey_SetControlChars, file);
|
|
Packit |
910689 |
filehash=newHV();
|
|
Packit |
910689 |
modehash=newHV();
|