12777ee89Sespie /* -*-C-*- */
22777ee89Sespie
3*99fd0875Safresh1 #define PERL_NO_GET_CONTEXT /* we want efficiency */
42777ee89Sespie #include "EXTERN.h"
52777ee89Sespie #include "perl.h"
62777ee89Sespie #include "XSUB.h"
72777ee89Sespie #include "ppport.h"
82777ee89Sespie
92777ee89Sespie #define InputStream PerlIO *
102777ee89Sespie
112777ee89Sespie /*******************************************************************
122777ee89Sespie
132777ee89Sespie Copyright (C) 1994,1995,1996,1997 Kenneth Albanowski. Unlimited
142777ee89Sespie distribution and/or modification is allowed as long as this copyright
152777ee89Sespie notice remains intact.
162777ee89Sespie
172777ee89Sespie Written by Kenneth Albanowski on Thu Oct 6 11:42:20 EDT 1994
182777ee89Sespie Contact at kjahds@kjahds.com or CIS:70705,126
192777ee89Sespie
20*99fd0875Safresh1 Maintained by Jonathan Stowe <jns@gellyfish.co.uk>
212777ee89Sespie
22*99fd0875Safresh1 The below captures the history prior to it being in full time version
23*99fd0875Safresh1 control:
24*99fd0875Safresh1
25*99fd0875Safresh1 $Id: ReadKey.xs,v 2.22 2005/01/11 21:15:17 jonathan Exp $
262777ee89Sespie
272777ee89Sespie Version 2.21, Sun Jul 28 12:57:56 BST 2002
282777ee89Sespie Fix to improve the chances of automated testing succeeding
292777ee89Sespie
302777ee89Sespie Version 2.20, Tue May 21 07:52:47 BST 2002
312777ee89Sespie Patch from Autrijus Tang fixing Win32 Breakage with bleadperl
322777ee89Sespie
332777ee89Sespie Version 2.19, Thu Mar 21 07:25:31 GMT 2002
342777ee89Sespie Added check for definedness of $_[0] in comparisons in ReadKey, ReadLine
352777ee89Sespie after reports of warnings.
362777ee89Sespie
372777ee89Sespie Version 2.18, Sun Feb 10 13:06:57 GMT 2002
382777ee89Sespie Altered prototyping style after reports of compile failures on
392777ee89Sespie Windows.
402777ee89Sespie
412777ee89Sespie Version 2.17, Fri Jan 25 06:58:47 GMT 2002
422777ee89Sespie The '_' macro for non-ANSI compatibility was removed in 5.7.2
432777ee89Sespie
442777ee89Sespie Version 2.16, Thu Nov 29 21:19:03 GMT 2001
452777ee89Sespie It appears that the genchars.pl bit of the patch didnt apply
462777ee89Sespie Applied the new ppport.h from Devel::PPPort
472777ee89Sespie
482777ee89Sespie Version 2.15, Sun Nov 4 15:02:37 GMT 2001 (jns)
492777ee89Sespie Applied the patch in
502777ee89Sespie http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2001-01/msg01588.html
512777ee89Sespie for PerlIO compatibility.
522777ee89Sespie
532777ee89Sespie Version 2.14, Sun Mar 28 23:26:13 EST 1999
542777ee89Sespie ppport.h 1.007 fixed for 5.005_55.
552777ee89Sespie
562777ee89Sespie Version 2.13, Wed Mar 24 20:46:06 EST 1999
572777ee89Sespie Adapted to ppport.h 1.006.
582777ee89Sespie
592777ee89Sespie Version 2.12, Wed Jan 7 10:33:11 EST 1998
602777ee89Sespie Slightly modified test and error reporting for Win32.
612777ee89Sespie
622777ee89Sespie Version 2.11, Sun Dec 14 00:39:12 EST 1997
632777ee89Sespie First attempt at Win32 support.
642777ee89Sespie
652777ee89Sespie Version 2.10, skipped
662777ee89Sespie
672777ee89Sespie Version 2.09, Tue Oct 7 13:07:43 EDT 1997
682777ee89Sespie Grr. Added explicit detection of sys/poll.h and poll.h.
692777ee89Sespie
702777ee89Sespie Version 2.08, Mon Oct 6 16:07:44 EDT 1997
712777ee89Sespie Changed poll.h to sys/poll.h.
722777ee89Sespie
732777ee89Sespie Version 2.07, Sun Jan 26 19:11:56 EST 1997
742777ee89Sespie Added $VERSION to .pm.
752777ee89Sespie
762777ee89Sespie Version 2.06, Tue Nov 26 01:47:09 EST 1996
772777ee89Sespie Added PERLIO support and removed duplicate declaration in .pm.
782777ee89Sespie
792777ee89Sespie Version 2.05, Tue Mar 12 19:08:33 EST 1996
802777ee89Sespie Changed poll support so it works. Cleaned up .pm a little.
812777ee89Sespie
822777ee89Sespie Version 2.04, Tue Oct 10 05:35:48 EDT 1995
832777ee89Sespie Whoops. Changed GetTermSize back so that GSIZE code won't be
842777ee89Sespie compiled if GWINSZ is being used. Also took ts_xxx and ts_yyy
852777ee89Sespie out of GSIZE.
862777ee89Sespie
872777ee89Sespie Version 2.03, Thu Sep 21 21:53:16 EDT 1995
882777ee89Sespie Fixed up debugging info in Readkey.pm, and changed TermSizeVIO
892777ee89Sespie to use _scrsize(). Hopefully this is GO for both Solaris and OS/2.
902777ee89Sespie
912777ee89Sespie Version 2.02, Mon Sep 18 22:17:57 EDT 1995
922777ee89Sespie Workaround for Solaris bug wasn't sufficient. Modularlized
932777ee89Sespie GetTermSize into perl code, and added support for the
942777ee89Sespie `resize` executable. Hard coded path for Solaris machines.
952777ee89Sespie
962777ee89Sespie Version 2.01, Wed Sep 13 22:22:23 EDT 1995
972777ee89Sespie Change error reporting around in getscreensize so that if
982777ee89Sespie an ioctl fails but getenv succeeds, no warning will be
992777ee89Sespie printed. This is an attempt to work around a Solaris bug where
1002777ee89Sespie TIOCGWINSZ fails in telnet sessions.
1012777ee89Sespie
1022777ee89Sespie Version 2.00, Mon Sep 4 06:37:24 EDT 1995
1032777ee89Sespie Added timeouts to select/poll, added USE_STDIO_PTR support
1042777ee89Sespie (required for recent perl revisions), and fixed up compilation
1052777ee89Sespie under OS/2.
1062777ee89Sespie
1072777ee89Sespie Version 1.99, Fri Aug 11 20:18:11 EDT 1995
1082777ee89Sespie Add file handles to ReadMode.
1092777ee89Sespie
1102777ee89Sespie Version 1.97, Mon Apr 10 21:41:52 EDT 1995
1112777ee89Sespie Changed mode 5 to disable UC & delays. Added more ECHO flags.
1122777ee89Sespie Tested termio[s] & sgtty.
1132777ee89Sespie Added termoptions so test.pl can give more info.
1142777ee89Sespie
1152777ee89Sespie Version 1.96,
1162777ee89Sespie Mucked with filehandle selection in ReadKey.pm.
1172777ee89Sespie
1182777ee89Sespie Version 1.95,
1192777ee89Sespie Cleaning up for distribution.
1202777ee89Sespie
1212777ee89Sespie Version 1.94,
1222777ee89Sespie Dealt with get/settermsize sillyness.
1232777ee89Sespie
1242777ee89Sespie Version 1.91, Sat Mar 11 23:47:04 EST 1995:
1252777ee89Sespie Andy's patches, and a bit of termsize finesse.
1262777ee89Sespie
1272777ee89Sespie Version 1.9, Thu Mar 9 14:11:49 EST 1995:
1282777ee89Sespie Modifying for portability. Prototypes, singed chars, etc.
1292777ee89Sespie
1302777ee89Sespie Version 1.8, Mon Jan 9 23:18:14 EST 1995:
1312777ee89Sespie Added use of Configure.pm. No changes to ReadKey.
1322777ee89Sespie
1332777ee89Sespie Version 1.7, Fri Dec 16 13:48:14 EST 1994:
1342777ee89Sespie Getting closer to release. Added new readmode 2. Had to bump up other
1352777ee89Sespie modes, unfortunately. This is the _last_ time I do that. If I have to
1362777ee89Sespie bump up the modes again, I'm switching to a different scheme.
1372777ee89Sespie
1382777ee89Sespie Version 1.6, Wed Dec 14 17:36:59 EST 1994:
1392777ee89Sespie Completly reorganized the control-char support (twice!) so that
1402777ee89Sespie it is automatically ported by the preproccessor for termio[s], or
1412777ee89Sespie by an included script for sgtty. Logical defaults for sgtty are included
1422777ee89Sespie too. Added Sun TermSize support. (Hope I got it right.)
1432777ee89Sespie
1442777ee89Sespie Version 1.5, Fri Dec 9 16:07:49 EST 1994:
1452777ee89Sespie Added SetTermSize, GetSpeeds, Get/SetControlChars, PerlIO support.
1462777ee89Sespie
1472777ee89Sespie Version 1.01, Thu Oct 20 23:32:39 EDT 1994:
1482777ee89Sespie Added Select_fd_set_t casts to select() call.
1492777ee89Sespie
1502777ee89Sespie Version 1.0: First "real" release. Everything seems cool.
1512777ee89Sespie
1522777ee89Sespie
1532777ee89Sespie *******************************************************************/
1542777ee89Sespie
1552777ee89Sespie /***
1562777ee89Sespie
1572777ee89Sespie Things to do:
1582777ee89Sespie
1592777ee89Sespie Make sure the GetSpeed function is doing it's best to separate ispeed
1602777ee89Sespie from ospeed.
1612777ee89Sespie
1622777ee89Sespie Separate the stty stuff from ReadMode, so that stty -a can be easily
1632777ee89Sespie used, among other things.
1642777ee89Sespie
1652777ee89Sespie ***/
1662777ee89Sespie
1672777ee89Sespie
1682777ee89Sespie
1692777ee89Sespie /* Using these defines, you can elide anything you know
1702777ee89Sespie won't work properly */
1712777ee89Sespie
1722777ee89Sespie /* Methods of doing non-blocking reads */
1732777ee89Sespie
1742777ee89Sespie /*#define DONT_USE_SELECT*/
1752777ee89Sespie /*#define DONT_USE_POLL*/
1762777ee89Sespie /*#define DONT_USE_NODELAY*/
1772777ee89Sespie
1782777ee89Sespie
1792777ee89Sespie /* Terminal I/O packages */
1802777ee89Sespie
1812777ee89Sespie /*#define DONT_USE_TERMIOS*/
1822777ee89Sespie /*#define DONT_USE_TERMIO*/
1832777ee89Sespie /*#define DONT_USE_SGTTY*/
1842777ee89Sespie
1852777ee89Sespie /* IOCTLs that can be used for GetTerminalSize */
1862777ee89Sespie
1872777ee89Sespie /*#define DONT_USE_GWINSZ*/
1882777ee89Sespie /*#define DONT_USE_GSIZE*/
1892777ee89Sespie
1902777ee89Sespie /* IOCTLs that can be used for SetTerminalSize */
1912777ee89Sespie
1922777ee89Sespie /*#define DONT_USE_SWINSZ*/
1932777ee89Sespie /*#define DONT_USE_SSIZE*/
1942777ee89Sespie
1952777ee89Sespie
1962777ee89Sespie /* This bit is for OS/2 */
1972777ee89Sespie
1982777ee89Sespie #ifdef OS2
1992777ee89Sespie # define I_FCNTL
2002777ee89Sespie # define HAS_FCNTL
2012777ee89Sespie
2022777ee89Sespie # define O_NODELAY O_NDELAY
2032777ee89Sespie
2042777ee89Sespie # define DONT_USE_SELECT
2052777ee89Sespie # define DONT_USE_POLL
2062777ee89Sespie
2072777ee89Sespie # define DONT_USE_TERMIOS
2082777ee89Sespie # define DONT_USE_SGTTY
2092777ee89Sespie # define I_TERMIO
2102777ee89Sespie # define CC_TERMIO
2112777ee89Sespie
2122777ee89Sespie /* This flag should be off in the lflags when we enable termio mode */
2132777ee89Sespie # define TRK_IDEFAULT IDEFAULT
2142777ee89Sespie
2152777ee89Sespie # define INCL_SUB
2162777ee89Sespie # define INCL_DOS
2172777ee89Sespie
2182777ee89Sespie # include <os2.h>
2192777ee89Sespie # include <stdlib.h>
2202777ee89Sespie
2212777ee89Sespie # define VIOMODE
2222777ee89Sespie #else
2232777ee89Sespie /* no os2 */
2242777ee89Sespie #endif
2252777ee89Sespie
2262777ee89Sespie /* This bit is for Windows 95/NT */
2272777ee89Sespie
2282777ee89Sespie #ifdef WIN32
2292777ee89Sespie # define DONT_USE_TERMIO
2302777ee89Sespie # define DONT_USE_TERMIOS
2312777ee89Sespie # define DONT_USE_SGTTY
2322777ee89Sespie # define DONT_USE_POLL
2332777ee89Sespie # define DONT_USE_SELECT
2342777ee89Sespie # define DONT_USE_NODELAY
2352777ee89Sespie # define USE_WIN32
2362777ee89Sespie # include <io.h>
2372777ee89Sespie # if defined(_get_osfhandle) && (PERL_VERSION == 4) && (PERL_SUBVERSION < 5)
2382777ee89Sespie # undef _get_osfhandle
2392777ee89Sespie # if defined(_MSC_VER)
2402777ee89Sespie # define level _cnt
2412777ee89Sespie # endif
2422777ee89Sespie # endif
2432777ee89Sespie #endif
2442777ee89Sespie
2452777ee89Sespie /* This bit for NeXT */
2462777ee89Sespie
2472777ee89Sespie #ifdef _NEXT_SOURCE
2482777ee89Sespie /* fcntl with O_NDELAY (FNDELAY, actually) is broken on NeXT */
2492777ee89Sespie # define DONT_USE_NODELAY
2502777ee89Sespie #endif
2512777ee89Sespie
2522777ee89Sespie #if !defined(DONT_USE_NODELAY)
2532777ee89Sespie # ifdef HAS_FCNTL
2542777ee89Sespie # define Have_nodelay
2552777ee89Sespie # ifdef I_FCNTL
2562777ee89Sespie # include <fcntl.h>
2572777ee89Sespie # endif
2582777ee89Sespie # ifdef I_SYS_FILE
2592777ee89Sespie # include <sys/file.h>
2602777ee89Sespie # endif
2612777ee89Sespie # ifdef I_UNISTD
2622777ee89Sespie # include <unistd.h>
2632777ee89Sespie # endif
2642777ee89Sespie
2652777ee89Sespie /* If any other headers are needed for fcntl or O_NODELAY, they need to get
2662777ee89Sespie included right here */
2672777ee89Sespie
2682777ee89Sespie # if !defined(O_NODELAY)
2692777ee89Sespie # if !defined(FNDELAY)
2702777ee89Sespie # undef Have_nodelay
2712777ee89Sespie # else
2722777ee89Sespie # define O_NODELAY FNDELAY
2732777ee89Sespie # endif
2742777ee89Sespie # else
2752777ee89Sespie # define O_NODELAY O_NDELAY
2762777ee89Sespie # endif
2772777ee89Sespie # endif
2782777ee89Sespie #endif
2792777ee89Sespie
2802777ee89Sespie #if !defined(DONT_USE_SELECT)
2812777ee89Sespie # ifdef HAS_SELECT
2822777ee89Sespie # ifdef I_SYS_SELECT
2832777ee89Sespie # include <sys/select.h>
2842777ee89Sespie # endif
2852777ee89Sespie
2862777ee89Sespie /* If any other headers are likely to be needed for select, they need to be
2872777ee89Sespie included right here */
2882777ee89Sespie
2892777ee89Sespie # define Have_select
2902777ee89Sespie # endif
2912777ee89Sespie #endif
2922777ee89Sespie
2932777ee89Sespie #if !defined(DONT_USE_POLL)
2942777ee89Sespie # ifdef HAS_POLL
2952777ee89Sespie # ifdef HAVE_POLL_H
2962777ee89Sespie # include <poll.h>
2972777ee89Sespie # define Have_poll
2982777ee89Sespie # endif
2992777ee89Sespie # ifdef HAVE_SYS_POLL_H
3002777ee89Sespie # include <sys/poll.h>
3012777ee89Sespie # define Have_poll
3022777ee89Sespie # endif
3032777ee89Sespie # endif
3042777ee89Sespie #endif
3052777ee89Sespie
3062777ee89Sespie #ifdef DONT_USE_TERMIOS
3072777ee89Sespie # ifdef I_TERMIOS
3082777ee89Sespie # undef I_TERMIOS
3092777ee89Sespie # endif
3102777ee89Sespie #endif
3112777ee89Sespie #ifdef DONT_USE_TERMIO
3122777ee89Sespie # ifdef I_TERMIO
3132777ee89Sespie # undef I_TERMIO
3142777ee89Sespie # endif
3152777ee89Sespie #endif
3162777ee89Sespie #ifdef DONT_USE_SGTTY
3172777ee89Sespie # ifdef I_SGTTY
3182777ee89Sespie # undef I_SGTTY
3192777ee89Sespie # endif
3202777ee89Sespie #endif
3212777ee89Sespie
3222777ee89Sespie /* Pre-POSIX SVR3 systems sometimes define struct winsize in
3232777ee89Sespie sys/ptem.h. However, sys/ptem.h needs a type mblk_t (?) which
3242777ee89Sespie is defined in <sys/stream.h>.
3252777ee89Sespie No, Configure (dist3.051) doesn't know how to check for this.
3262777ee89Sespie */
3272777ee89Sespie #ifdef I_SYS_STREAM
3282777ee89Sespie # include <sys/stream.h>
3292777ee89Sespie #endif
3302777ee89Sespie #ifdef I_SYS_PTEM
3312777ee89Sespie # include <sys/ptem.h>
3322777ee89Sespie #endif
3332777ee89Sespie
3342777ee89Sespie #ifdef I_TERMIOS
3352777ee89Sespie # include <termios.h>
3362777ee89Sespie #else
3372777ee89Sespie # ifdef I_TERMIO
3382777ee89Sespie # include <termio.h>
3392777ee89Sespie # else
3402777ee89Sespie # ifdef I_SGTTY
3412777ee89Sespie # include <sgtty.h>
3422777ee89Sespie # endif
3432777ee89Sespie # endif
3442777ee89Sespie #endif
3452777ee89Sespie
3462777ee89Sespie #ifdef I_TERMIOS
3472777ee89Sespie # define CC_TERMIOS
3482777ee89Sespie #else
3492777ee89Sespie # ifdef I_TERMIO
3502777ee89Sespie # define CC_TERMIO
3512777ee89Sespie # else
3522777ee89Sespie # ifdef I_SGTTY
3532777ee89Sespie # define CC_SGTTY
3542777ee89Sespie # endif
3552777ee89Sespie # endif
3562777ee89Sespie #endif
3572777ee89Sespie
3582777ee89Sespie #ifndef TRK_IDEFAULT
3592777ee89Sespie /* This flag should be off in the lflags when we enable termio mode */
3602777ee89Sespie # define TRK_IDEFAULT 0
3612777ee89Sespie #endif
3622777ee89Sespie
3632777ee89Sespie /* Fix up the disappearance of the '_' macro in Perl 5.7.2 */
3642777ee89Sespie
3652777ee89Sespie #ifndef _
3662777ee89Sespie # ifdef CAN_PROTOTYPE
3672777ee89Sespie # define _(args) args
3682777ee89Sespie # else
3692777ee89Sespie # define _(args) ()
3702777ee89Sespie # endif
3712777ee89Sespie #endif
3722777ee89Sespie
3732777ee89Sespie #define DisableFlush (1) /* Should flushing mode changes be enabled?
3742777ee89Sespie I think not for now. */
3752777ee89Sespie
3762777ee89Sespie
3772777ee89Sespie #define STDIN PerlIO_stdin()
3782777ee89Sespie
3792777ee89Sespie #include "cchars.h"
3802777ee89Sespie
3812777ee89Sespie
382*99fd0875Safresh1 STATIC int GetTermSizeVIO _((pTHX_ PerlIO * file,
3832777ee89Sespie int * retwidth, int * retheight,
3842777ee89Sespie int * xpix, int * ypix));
3852777ee89Sespie
386*99fd0875Safresh1 STATIC int GetTermSizeGWINSZ _((pTHX_ PerlIO * file,
3872777ee89Sespie int * retwidth, int * retheight,
3882777ee89Sespie int * xpix, int * ypix));
3892777ee89Sespie
390*99fd0875Safresh1 STATIC int GetTermSizeGSIZE _((pTHX_ PerlIO * file,
3912777ee89Sespie int * retwidth, int * retheight,
3922777ee89Sespie int * xpix, int * ypix));
3932777ee89Sespie
394*99fd0875Safresh1 STATIC int GetTermSizeWin32 _((pTHX_ PerlIO * file,
3952777ee89Sespie int * retwidth, int * retheight,
3962777ee89Sespie int * xpix, int * ypix));
3972777ee89Sespie
398*99fd0875Safresh1 STATIC int SetTerminalSize _((pTHX_ PerlIO * file,
3992777ee89Sespie int width, int height,
4002777ee89Sespie int xpix, int ypix));
4012777ee89Sespie
402*99fd0875Safresh1 STATIC void ReadMode _((pTHX_ PerlIO * file,int mode));
4032777ee89Sespie
404*99fd0875Safresh1 STATIC int pollfile _((pTHX_ PerlIO * file, double delay));
4052777ee89Sespie
406*99fd0875Safresh1 STATIC int setnodelay _((pTHX_ PerlIO * file, int mode));
4072777ee89Sespie
408*99fd0875Safresh1 STATIC int selectfile _((pTHX_ PerlIO * file, double delay));
4092777ee89Sespie
410*99fd0875Safresh1 STATIC int Win32PeekChar _((pTHX_ PerlIO * file, double delay, char * key));
4112777ee89Sespie
412*99fd0875Safresh1 STATIC int getspeed _((pTHX_ PerlIO * file, I32 *in, I32 * out ));
4132777ee89Sespie
4142777ee89Sespie
4152777ee89Sespie #ifdef VIOMODE
GetTermSizeVIO(pTHX_ PerlIO * file,int * retwidth,int * retheight,int * xpix,int * ypix)416*99fd0875Safresh1 int GetTermSizeVIO(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
4172777ee89Sespie {
4182777ee89Sespie /*int handle=PerlIO_fileno(file);
4192777ee89Sespie
4202777ee89Sespie static VIOMODEINFO *modeinfo = NULL;
4212777ee89Sespie
4222777ee89Sespie if (modeinfo == NULL)
4232777ee89Sespie modeinfo = (VIOMODEINFO *)malloc(sizeof(VIOMODEINFO));
4242777ee89Sespie
4252777ee89Sespie VioGetMode(modeinfo,0);
4262777ee89Sespie *retheight = modeinfo->row ?: 25;
4272777ee89Sespie *retwidth = modeinfo->col ?: 80;*/
4282777ee89Sespie int buf[2];
4292777ee89Sespie
4302777ee89Sespie _scrsize(&buf[0]);
4312777ee89Sespie
4322777ee89Sespie *retwidth = buf[0]; *retheight = buf[1];
4332777ee89Sespie
4342777ee89Sespie *xpix = *ypix = 0;
4352777ee89Sespie return 0;
4362777ee89Sespie }
4372777ee89Sespie #else
GetTermSizeVIO(pTHX_ PerlIO * file,int * retwidth,int * retheight,int * xpix,int * ypix)438*99fd0875Safresh1 int GetTermSizeVIO(pTHX_ PerlIO *file,int * retwidth,int *retheight, int *xpix,int *ypix)
4392777ee89Sespie {
4402777ee89Sespie croak("TermSizeVIO is not implemented on this architecture");
4412777ee89Sespie return 0;
4422777ee89Sespie }
4432777ee89Sespie #endif
4442777ee89Sespie
4452777ee89Sespie
4462777ee89Sespie #if defined(TIOCGWINSZ) && !defined(DONT_USE_GWINSZ)
GetTermSizeGWINSZ(pTHX_ PerlIO * file,int * retwidth,int * retheight,int * xpix,int * ypix)447*99fd0875Safresh1 int GetTermSizeGWINSZ(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
4482777ee89Sespie {
4492777ee89Sespie int handle=PerlIO_fileno(file);
4502777ee89Sespie struct winsize w;
4512777ee89Sespie
4522777ee89Sespie if (ioctl (handle, TIOCGWINSZ, &w) == 0) {
4532777ee89Sespie *retwidth=w.ws_col; *retheight=w.ws_row;
4542777ee89Sespie *xpix=w.ws_xpixel; *ypix=w.ws_ypixel; return 0;
4552777ee89Sespie }
4562777ee89Sespie else {
4572777ee89Sespie return -1; /* failure */
4582777ee89Sespie }
4592777ee89Sespie
4602777ee89Sespie }
4612777ee89Sespie #else
GetTermSizeGWINSZ(pTHX_ PerlIO * file,int * retwidth,int * retheight,int * xpix,int * ypix)462*99fd0875Safresh1 int GetTermSizeGWINSZ(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
4632777ee89Sespie {
4642777ee89Sespie croak("TermSizeGWINSZ is not implemented on this architecture");
4652777ee89Sespie return 0;
4662777ee89Sespie }
4672777ee89Sespie #endif
4682777ee89Sespie
4692777ee89Sespie #if (!defined(TIOCGWINSZ) || defined(DONT_USE_GWINSZ)) && (defined(TIOCGSIZE) && !defined(DONT_USE_GSIZE))
GetTermSizeGSIZE(pTHX_ PerlIO * file,int * retwidth,int * retheight,int * xpix,int * ypix)470*99fd0875Safresh1 int GetTermSizeGSIZE(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
4712777ee89Sespie {
4722777ee89Sespie int handle=PerlIO_fileno(file);
4732777ee89Sespie
4742777ee89Sespie struct ttysize w;
4752777ee89Sespie
4762777ee89Sespie if (ioctl (handle, TIOCGSIZE, &w) == 0) {
4772777ee89Sespie *retwidth=w.ts_cols; *retheight=w.ts_lines;
4782777ee89Sespie *xpix=0/*w.ts_xxx*/; *ypix=0/*w.ts_yyy*/; return 0;
4792777ee89Sespie }
4802777ee89Sespie else {
4812777ee89Sespie return -1; /* failure */
4822777ee89Sespie }
4832777ee89Sespie }
4842777ee89Sespie #else
GetTermSizeGSIZE(pTHX_ PerlIO * file,int * retwidth,int * retheight,int * xpix,int * ypix)485*99fd0875Safresh1 int GetTermSizeGSIZE(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
4862777ee89Sespie {
4872777ee89Sespie croak("TermSizeGSIZE is not implemented on this architecture");
4882777ee89Sespie return 0;
4892777ee89Sespie }
4902777ee89Sespie #endif
4912777ee89Sespie
4922777ee89Sespie #ifdef USE_WIN32
GetTermSizeWin32(pTHX_ PerlIO * file,int * retwidth,int * retheight,int * xpix,int * ypix)493*99fd0875Safresh1 int GetTermSizeWin32(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
4942777ee89Sespie {
4952777ee89Sespie int handle=PerlIO_fileno(file);
4962777ee89Sespie HANDLE whnd = (HANDLE)_get_osfhandle(handle);
4972777ee89Sespie CONSOLE_SCREEN_BUFFER_INFO info;
4982777ee89Sespie
4992777ee89Sespie if (GetConsoleScreenBufferInfo(whnd, &info)) {
5002777ee89Sespie /* Logic: return maximum possible screen width, but return
5012777ee89Sespie only currently selected height */
5022777ee89Sespie if (retwidth)
5032777ee89Sespie *retwidth = info.dwMaximumWindowSize.X;
5042777ee89Sespie /*info.srWindow.Right - info.srWindow.Left;*/
5052777ee89Sespie if (retheight)
5062777ee89Sespie *retheight = info.srWindow.Bottom - info.srWindow.Top;
5072777ee89Sespie if (xpix)
5082777ee89Sespie *xpix = 0;
5092777ee89Sespie if (ypix)
5102777ee89Sespie *ypix = 0;
5112777ee89Sespie return 0;
5122777ee89Sespie } else
5132777ee89Sespie return -1;
5142777ee89Sespie }
5152777ee89Sespie #else
GetTermSizeWin32(pTHX_ PerlIO * file,int * retwidth,int * retheight,int * xpix,int * ypix)516*99fd0875Safresh1 int GetTermSizeWin32(pTHX_ PerlIO *file,int *retwidth,int *retheight,int *xpix,int *ypix)
5172777ee89Sespie {
5182777ee89Sespie croak("TermSizeWin32 is not implemented on this architecture");
5192777ee89Sespie return 0;
5202777ee89Sespie }
5212777ee89Sespie #endif /* USE_WIN32 */
5222777ee89Sespie
5232777ee89Sespie
termsizeoptions()524*99fd0875Safresh1 STATIC int termsizeoptions() {
5252777ee89Sespie return 0
5262777ee89Sespie #ifdef VIOMODE
5272777ee89Sespie | 1
5282777ee89Sespie #endif
5292777ee89Sespie #if defined(TIOCGWINSZ) && !defined(DONT_USE_GWINSZ)
5302777ee89Sespie | 2
5312777ee89Sespie #endif
5322777ee89Sespie #if defined(TIOCGSIZE) && !defined(DONT_USE_GSIZE)
5332777ee89Sespie | 4
5342777ee89Sespie #endif
5352777ee89Sespie #if defined(USE_WIN32)
5362777ee89Sespie | 8
5372777ee89Sespie #endif
5382777ee89Sespie ;
5392777ee89Sespie }
5402777ee89Sespie
5412777ee89Sespie
SetTerminalSize(pTHX_ PerlIO * file,int width,int height,int xpix,int ypix)542*99fd0875Safresh1 int SetTerminalSize(pTHX_ PerlIO *file,int width,int height,int xpix,int ypix)
5432777ee89Sespie {
5442777ee89Sespie int handle=PerlIO_fileno(file);
5452777ee89Sespie
5462777ee89Sespie #ifdef VIOMODE
5472777ee89Sespie return -1;
5482777ee89Sespie #else
5492777ee89Sespie
5502777ee89Sespie #if defined(TIOCSWINSZ) && !defined(DONT_USE_SWINSZ)
551*99fd0875Safresh1 char buffer[10];
5522777ee89Sespie struct winsize w;
5532777ee89Sespie
5542777ee89Sespie w.ws_col=width;
5552777ee89Sespie w.ws_row=height;
5562777ee89Sespie w.ws_xpixel=xpix;
5572777ee89Sespie w.ws_ypixel=ypix;
5582777ee89Sespie if (ioctl (handle, TIOCSWINSZ, &w) == 0) {
5592777ee89Sespie sprintf(buffer,"%d",width); /* Be polite to our children */
5602777ee89Sespie my_setenv("COLUMNS",buffer);
5612777ee89Sespie sprintf(buffer,"%d",height);
5622777ee89Sespie my_setenv("LINES",buffer);
5632777ee89Sespie return 0;
5642777ee89Sespie }
5652777ee89Sespie else {
5662777ee89Sespie croak("TIOCSWINSZ ioctl call to set terminal size failed: %s",Strerror(errno));
5672777ee89Sespie return -1;
5682777ee89Sespie }
5692777ee89Sespie #else
5702777ee89Sespie # if defined(TIOCSSIZE) && !defined(DONT_USE_SSIZE)
571*99fd0875Safresh1 char buffer[10];
5722777ee89Sespie struct ttysize w;
5732777ee89Sespie
5742777ee89Sespie w.ts_lines=height;
5752777ee89Sespie w.ts_cols=width;
5762777ee89Sespie w.ts_xxx=xpix;
5772777ee89Sespie w.ts_yyy=ypix;
5782777ee89Sespie if (ioctl (handle, TIOCSSIZE, &w) == 0) {
5792777ee89Sespie sprintf(buffer,"%d",width);
5802777ee89Sespie my_setenv("COLUMNS",buffer);
5812777ee89Sespie sprintf(buffer,"%d",height);
5822777ee89Sespie my_setenv("LINES",buffer);
5832777ee89Sespie return 0;
5842777ee89Sespie }
5852777ee89Sespie else {
5862777ee89Sespie croak("TIOCSSIZE ioctl call to set terminal size failed: %s",Strerror(errno));
5872777ee89Sespie return -1;
5882777ee89Sespie }
5892777ee89Sespie # else
5902777ee89Sespie /*sprintf(buffer,"%d",width) * Should we could do this and then *
5912777ee89Sespie my_setenv("COLUMNS",buffer) * said we succeeded? *
5922777ee89Sespie sprintf(buffer,"%d",height);
5932777ee89Sespie my_setenv("LINES",buffer)*/
5942777ee89Sespie
5952777ee89Sespie return -1; /* Fail */
5962777ee89Sespie # endif
5972777ee89Sespie #endif
5982777ee89Sespie #endif
5992777ee89Sespie
6002777ee89Sespie }
6012777ee89Sespie
602*99fd0875Safresh1 STATIC const I32 terminal_speeds[] = {
6032777ee89Sespie #ifdef B50
6042777ee89Sespie 50, B50,
6052777ee89Sespie #endif
6062777ee89Sespie #ifdef B75
6072777ee89Sespie 75, B75,
6082777ee89Sespie #endif
6092777ee89Sespie #ifdef B110
6102777ee89Sespie 110, B110,
6112777ee89Sespie #endif
6122777ee89Sespie #ifdef B134
6132777ee89Sespie 134, B134,
6142777ee89Sespie #endif
6152777ee89Sespie #ifdef B150
6162777ee89Sespie 150, B150,
6172777ee89Sespie #endif
6182777ee89Sespie #ifdef B200
6192777ee89Sespie 200, B200,
6202777ee89Sespie #endif
6212777ee89Sespie #ifdef B300
6222777ee89Sespie 300, B300,
6232777ee89Sespie #endif
6242777ee89Sespie #ifdef B600
6252777ee89Sespie 600, B600,
6262777ee89Sespie #endif
6272777ee89Sespie #ifdef B1200
6282777ee89Sespie 1200, B1200,
6292777ee89Sespie #endif
6302777ee89Sespie #ifdef B1800
6312777ee89Sespie 1800, B1800,
6322777ee89Sespie #endif
6332777ee89Sespie #ifdef B2400
6342777ee89Sespie 2400, B2400,
6352777ee89Sespie #endif
6362777ee89Sespie #ifdef B4800
6372777ee89Sespie 4800, B4800,
6382777ee89Sespie #endif
6392777ee89Sespie #ifdef B9600
6402777ee89Sespie 9600, B9600,
6412777ee89Sespie #endif
6422777ee89Sespie #ifdef B19200
6432777ee89Sespie 19200, B19200,
6442777ee89Sespie #endif
6452777ee89Sespie #ifdef B38400
6462777ee89Sespie 38400, B38400,
6472777ee89Sespie #endif
6482777ee89Sespie #ifdef B57600
6492777ee89Sespie 57600, B57600,
6502777ee89Sespie #endif
6512777ee89Sespie #ifdef B115200
6522777ee89Sespie 115200, B115200,
6532777ee89Sespie #endif
6542777ee89Sespie #ifdef EXTA
6552777ee89Sespie 19200, EXTA,
6562777ee89Sespie #endif
6572777ee89Sespie #ifdef EXTB
6582777ee89Sespie 38400, EXTB,
6592777ee89Sespie #endif
6602777ee89Sespie #ifdef B0
6612777ee89Sespie 0, B0,
6622777ee89Sespie #endif
6632777ee89Sespie -1,-1
6642777ee89Sespie };
6652777ee89Sespie
getspeed(pTHX_ PerlIO * file,I32 * in,I32 * out)666*99fd0875Safresh1 int getspeed(pTHX_ PerlIO *file,I32 *in, I32 *out)
6672777ee89Sespie {
6682777ee89Sespie int handle=PerlIO_fileno(file);
669*99fd0875Safresh1 #if defined(I_TERMIOS) || defined(I_TERMIO) || defined(I_SGTTY)
6702777ee89Sespie int i;
671*99fd0875Safresh1 #endif
6722777ee89Sespie # ifdef I_TERMIOS
6732777ee89Sespie /* Posixy stuff */
6742777ee89Sespie
6752777ee89Sespie struct termios buf;
6762777ee89Sespie tcgetattr(handle,&buf);
6772777ee89Sespie
6782777ee89Sespie *in = *out = -1;
6792777ee89Sespie *in = cfgetispeed(&buf);
6802777ee89Sespie *out = cfgetospeed(&buf);
6812777ee89Sespie for(i=0;terminal_speeds[i]!=-1;i+=2) {
6822777ee89Sespie if(*in == terminal_speeds[i+1])
6832777ee89Sespie { *in = terminal_speeds[i]; break; }
6842777ee89Sespie }
6852777ee89Sespie for(i=0;terminal_speeds[i]!=-1;i+=2) {
6862777ee89Sespie if(*out == terminal_speeds[i+1])
6872777ee89Sespie { *out = terminal_speeds[i]; break; }
6882777ee89Sespie }
6892777ee89Sespie return 0;
6902777ee89Sespie
6912777ee89Sespie # else
6922777ee89Sespie # ifdef I_TERMIO
6932777ee89Sespie /* SysV stuff */
6942777ee89Sespie struct termio buf;
6952777ee89Sespie
6962777ee89Sespie ioctl(handle,TCGETA,&buf);
6972777ee89Sespie
6982777ee89Sespie *in=*out=-1;
6992777ee89Sespie for(i=0;terminal_speeds[i]!=-1;i+=2) {
7002777ee89Sespie if((buf.c_cflag & CBAUD) == terminal_speeds[i+1])
7012777ee89Sespie { *in=*out=terminal_speeds[i]; break; }
7022777ee89Sespie }
7032777ee89Sespie return 0;
7042777ee89Sespie
7052777ee89Sespie # else
7062777ee89Sespie # ifdef I_SGTTY
7072777ee89Sespie /* BSD stuff */
7082777ee89Sespie struct sgttyb buf;
7092777ee89Sespie
7102777ee89Sespie ioctl(handle,TIOCGETP,&buf);
7112777ee89Sespie
7122777ee89Sespie *in=*out=-1;
7132777ee89Sespie
7142777ee89Sespie for(i=0;terminal_speeds[i]!=-1;i+=2)
7152777ee89Sespie if(buf.sg_ospeed == terminal_speeds[i+1])
7162777ee89Sespie { *out = terminal_speeds[i]; break; }
7172777ee89Sespie
7182777ee89Sespie for(i=0;terminal_speeds[i]!=-1;i+=2)
7192777ee89Sespie if(buf.sg_ispeed == terminal_speeds[i+1])
7202777ee89Sespie { *in = terminal_speeds[i]; break; }
7212777ee89Sespie
7222777ee89Sespie return 0;
7232777ee89Sespie
7242777ee89Sespie
7252777ee89Sespie # else
7262777ee89Sespie
7272777ee89Sespie /* No termio, termios or sgtty. I suppose we can try stty,
7282777ee89Sespie but it would be nice if you could get a better OS */
7292777ee89Sespie
7302777ee89Sespie return -1;
7312777ee89Sespie
7322777ee89Sespie # endif
7332777ee89Sespie # endif
7342777ee89Sespie # endif
7352777ee89Sespie }
7362777ee89Sespie
7372777ee89Sespie #ifdef WIN32
7382777ee89Sespie struct tbuffer { DWORD Mode; };
7392777ee89Sespie #else
7402777ee89Sespie #ifdef I_TERMIOS
7412777ee89Sespie #define USE_TERMIOS
7422777ee89Sespie #define tbuffer termios
7432777ee89Sespie #else
7442777ee89Sespie #ifdef I_TERMIO
7452777ee89Sespie #define USE_TERMIO
7462777ee89Sespie #define tbuffer termio
7472777ee89Sespie #else
7482777ee89Sespie #ifdef I_SGTTY
7492777ee89Sespie #define USE_SGTTY
7502777ee89Sespie struct tbuffer {
7512777ee89Sespie struct sgttyb buf;
7522777ee89Sespie #if defined(TIOCGETC)
7532777ee89Sespie struct tchars tchar;
7542777ee89Sespie #endif
7552777ee89Sespie #if defined(TIOCGLTC)
7562777ee89Sespie struct ltchars ltchar;
7572777ee89Sespie #endif
7582777ee89Sespie #if defined(TIOCLGET)
7592777ee89Sespie int local;
7602777ee89Sespie #endif
7612777ee89Sespie };
7622777ee89Sespie #else
7632777ee89Sespie #define USE_STTY
7642777ee89Sespie struct tbuffer {
7652777ee89Sespie int dummy;
7662777ee89Sespie };
7672777ee89Sespie #endif
7682777ee89Sespie #endif
7692777ee89Sespie #endif
7702777ee89Sespie #endif
7712777ee89Sespie
772*99fd0875Safresh1 static HV * filehash; /* Used to store the original terminal settings for each handle*/
773*99fd0875Safresh1 static HV * modehash; /* Used to record the current terminal "mode" for each handle*/
7742777ee89Sespie
ReadMode(pTHX_ PerlIO * file,int mode)775*99fd0875Safresh1 void ReadMode(pTHX_ PerlIO *file,int mode)
7762777ee89Sespie {
7772777ee89Sespie dTHR;
7782777ee89Sespie int handle;
7792777ee89Sespie int firsttime;
7802777ee89Sespie int oldmode;
7812777ee89Sespie struct tbuffer work;
7822777ee89Sespie struct tbuffer savebuf;
7832777ee89Sespie
7842777ee89Sespie
7852777ee89Sespie handle=PerlIO_fileno(file);
7862777ee89Sespie
7872777ee89Sespie firsttime=!hv_exists(filehash, (char*)&handle, sizeof(int));
7882777ee89Sespie
7892777ee89Sespie
7902777ee89Sespie # ifdef WIN32
7912777ee89Sespie
7922777ee89Sespie if (!GetConsoleMode((HANDLE)_get_osfhandle(handle), &work.Mode))
7932777ee89Sespie croak("GetConsoleMode failed, LastError=|%d|",GetLastError());
7942777ee89Sespie
7952777ee89Sespie # endif /* WIN32 */
7962777ee89Sespie
7972777ee89Sespie # ifdef USE_TERMIOS
7982777ee89Sespie /* Posixy stuff */
7992777ee89Sespie
8002777ee89Sespie tcgetattr(handle,&work);
8012777ee89Sespie
8022777ee89Sespie
8032777ee89Sespie
8042777ee89Sespie #endif
8052777ee89Sespie #ifdef USE_TERMIO
8062777ee89Sespie /* SysV stuff */
8072777ee89Sespie
8082777ee89Sespie ioctl(handle,TCGETA,&work);
8092777ee89Sespie
8102777ee89Sespie
8112777ee89Sespie #endif
8122777ee89Sespie #ifdef USE_SGTTY
8132777ee89Sespie /* BSD stuff */
8142777ee89Sespie
8152777ee89Sespie ioctl(handle,TIOCGETP,&work.buf);
8162777ee89Sespie # if defined(TIOCGETC)
8172777ee89Sespie ioctl(handle,TIOCGETC,&work.tchar);
8182777ee89Sespie # endif
8192777ee89Sespie # if defined(TIOCLGET)
8202777ee89Sespie ioctl(handle,TIOCLGET,&work.local);
8212777ee89Sespie # endif
8222777ee89Sespie # if defined(TIOCGLTC)
8232777ee89Sespie ioctl(handle,TIOCGLTC,&work.ltchar);
8242777ee89Sespie # endif
8252777ee89Sespie
8262777ee89Sespie
8272777ee89Sespie #endif
8282777ee89Sespie
8292777ee89Sespie
8302777ee89Sespie if(firsttime) {
8312777ee89Sespie firsttime=0;
8322777ee89Sespie memcpy((void*)&savebuf,(void*)&work,sizeof(struct tbuffer));
8332777ee89Sespie if(!hv_store(filehash,(char*)&handle,sizeof(int),
8342777ee89Sespie newSVpv((char*)&savebuf,sizeof(struct tbuffer)),0))
8352777ee89Sespie croak("Unable to stash terminal settings.\n");
8362777ee89Sespie if(!hv_store(modehash,(char*)&handle,sizeof(int),newSViv(0),0))
8372777ee89Sespie croak("Unable to stash terminal settings.\n");
8382777ee89Sespie } else {
8392777ee89Sespie SV ** temp;
8402777ee89Sespie if(!(temp=hv_fetch(filehash,(char*)&handle,sizeof(int),0)))
8412777ee89Sespie croak("Unable to retrieve stashed terminal settings.\n");
8422777ee89Sespie memcpy(&savebuf,SvPV(*temp,PL_na),sizeof(struct tbuffer));
8432777ee89Sespie if(!(temp=hv_fetch(modehash,(char*)&handle,sizeof(int),0)))
8442777ee89Sespie croak("Unable to retrieve stashed terminal mode.\n");
8452777ee89Sespie oldmode=SvIV(*temp);
8462777ee89Sespie }
8472777ee89Sespie
8482777ee89Sespie #ifdef WIN32
8492777ee89Sespie
8502777ee89Sespie switch (mode) {
8512777ee89Sespie case 5:
8522777ee89Sespie /* Should 5 disable ENABLE_WRAP_AT_EOL_OUTPUT? */
8532777ee89Sespie case 4:
8542777ee89Sespie work.Mode &= ~(ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT|ENABLE_LINE_INPUT|ENABLE_PROCESSED_OUTPUT);
8552777ee89Sespie work.Mode |= 0;
8562777ee89Sespie break;
8572777ee89Sespie case 3:
8582777ee89Sespie work.Mode &= ~(ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT);
8592777ee89Sespie work.Mode |= ENABLE_PROCESSED_INPUT|ENABLE_PROCESSED_OUTPUT;
8602777ee89Sespie break;
8612777ee89Sespie case 2:
8622777ee89Sespie work.Mode &= ~(ENABLE_ECHO_INPUT);
8632777ee89Sespie work.Mode |= ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT|ENABLE_PROCESSED_OUTPUT;
8642777ee89Sespie break;
8652777ee89Sespie case 1:
8662777ee89Sespie work.Mode &= ~(0);
8672777ee89Sespie work.Mode |= ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT|ENABLE_PROCESSED_OUTPUT;
8682777ee89Sespie break;
8692777ee89Sespie case 0:
8702777ee89Sespie work = savebuf;
8712777ee89Sespie firsttime = 1;
8722777ee89Sespie break;
8732777ee89Sespie }
8742777ee89Sespie
8752777ee89Sespie if (!SetConsoleMode((HANDLE)_get_osfhandle(handle), work.Mode))
8762777ee89Sespie croak("SetConsoleMode failed, LastError=|%d|",GetLastError());
8772777ee89Sespie
8782777ee89Sespie #endif /* WIN32 */
8792777ee89Sespie
8802777ee89Sespie
8812777ee89Sespie #ifdef USE_TERMIOS
8822777ee89Sespie
8832777ee89Sespie
8842777ee89Sespie /* What, me worry about standards? */
8852777ee89Sespie
8862777ee89Sespie # if !defined (VMIN)
8872777ee89Sespie # define VMIN VEOF
8882777ee89Sespie # endif
8892777ee89Sespie
8902777ee89Sespie # if !defined (VTIME)
8912777ee89Sespie # define VTIME VEOL
8922777ee89Sespie # endif
8932777ee89Sespie
8942777ee89Sespie # if !defined (IXANY)
8952777ee89Sespie # define IXANY (0)
8962777ee89Sespie # endif
8972777ee89Sespie
8982777ee89Sespie #ifndef IEXTEN
8992777ee89Sespie #ifdef IDEFAULT
9002777ee89Sespie #define IEXTEN IDEFAULT
9012777ee89Sespie #endif
9022777ee89Sespie #endif
9032777ee89Sespie
9042777ee89Sespie /* XXX Is ONLCR in POSIX?. The value of '4' seems to be the same for
9052777ee89Sespie both SysV and Sun, so it's probably rather general, and I'm not
9062777ee89Sespie aware of a POSIX way to do this otherwise.
9072777ee89Sespie */
9082777ee89Sespie #ifndef ONLCR
9092777ee89Sespie # define ONLCR 4
9102777ee89Sespie #endif
9112777ee89Sespie
9122777ee89Sespie #ifndef IMAXBEL
9132777ee89Sespie #define IMAXBEL 0
9142777ee89Sespie #endif
9152777ee89Sespie #ifndef ECHOE
9162777ee89Sespie #define ECHOE 0
9172777ee89Sespie #endif
9182777ee89Sespie #ifndef ECHOK
9192777ee89Sespie #define ECHOK 0
9202777ee89Sespie #endif
9212777ee89Sespie #ifndef ECHONL
9222777ee89Sespie #define ECHONL 0
9232777ee89Sespie #endif
9242777ee89Sespie #ifndef ECHOPRT
9252777ee89Sespie #define ECHOPRT 0
9262777ee89Sespie #endif
9272777ee89Sespie #ifndef FLUSHO
9282777ee89Sespie #define FLUSHO 0
9292777ee89Sespie #endif
9302777ee89Sespie #ifndef PENDIN
9312777ee89Sespie #define PENDIN 0
9322777ee89Sespie #endif
9332777ee89Sespie #ifndef ECHOKE
9342777ee89Sespie #define ECHOKE 0
9352777ee89Sespie #endif
9362777ee89Sespie #ifndef ONLCR
9372777ee89Sespie #define ONLCR 0
9382777ee89Sespie #endif
9392777ee89Sespie #ifndef OCRNL
9402777ee89Sespie #define OCRNL 0
9412777ee89Sespie #endif
9422777ee89Sespie #ifndef ONLRET
9432777ee89Sespie #define ONLRET 0
9442777ee89Sespie #endif
9452777ee89Sespie #ifndef IUCLC
9462777ee89Sespie #define IUCLC 0
9472777ee89Sespie #endif
9482777ee89Sespie #ifndef OPOST
9492777ee89Sespie #define OPOST 0
9502777ee89Sespie #endif
9512777ee89Sespie #ifndef OLCUC
9522777ee89Sespie #define OLCUC 0
9532777ee89Sespie #endif
9542777ee89Sespie #ifndef ECHOCTL
9552777ee89Sespie #define ECHOCTL 0
9562777ee89Sespie #endif
9572777ee89Sespie #ifndef XCASE
9582777ee89Sespie #define XCASE 0
9592777ee89Sespie #endif
9602777ee89Sespie #ifndef BRKINT
9612777ee89Sespie #define BRKINT 0
9622777ee89Sespie #endif
9632777ee89Sespie
9642777ee89Sespie
9652777ee89Sespie if(mode==5) {
9662777ee89Sespie /*\
9672777ee89Sespie * Disable everything except parity if needed.
9682777ee89Sespie \*/
9692777ee89Sespie
9702777ee89Sespie /* Hopefully, this should put the tty into unbuffered mode
9712777ee89Sespie with signals and control characters (both posixy and normal)
9722777ee89Sespie disabled, along with flow control. Echo should be off.
9732777ee89Sespie CR/LF is not translated, along with 8-bit/parity */
9742777ee89Sespie
9752777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
9762777ee89Sespie
9772777ee89Sespie work.c_lflag &= ~(ICANON|ISIG|IEXTEN );
9782777ee89Sespie work.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ECHOCTL);
9792777ee89Sespie work.c_lflag &= ~(ECHOPRT|ECHOKE|FLUSHO|PENDIN|XCASE);
9802777ee89Sespie work.c_lflag |= NOFLSH;
9812777ee89Sespie work.c_iflag &= ~(IXOFF|IXON|IXANY|ICRNL|IMAXBEL|BRKINT);
9822777ee89Sespie
9832777ee89Sespie if(((work.c_iflag & INPCK) != INPCK) ||
9842777ee89Sespie ((work.c_cflag & PARENB) != PARENB)) {
9852777ee89Sespie work.c_iflag &= ~ISTRIP;
9862777ee89Sespie work.c_iflag |= IGNPAR;
9872777ee89Sespie work.c_iflag &= ~PARMRK;
9882777ee89Sespie }
9892777ee89Sespie work.c_oflag &= ~(OPOST |ONLCR|OCRNL|ONLRET);
9902777ee89Sespie
9912777ee89Sespie work.c_cc[VTIME] = 0;
9922777ee89Sespie work.c_cc[VMIN] = 1;
9932777ee89Sespie }
9942777ee89Sespie else if(mode==4) {
9952777ee89Sespie /* Hopefully, this should put the tty into unbuffered mode
9962777ee89Sespie with signals and control characters (both posixy and normal)
9972777ee89Sespie disabled, along with flow control. Echo should be off.
9982777ee89Sespie About the only thing left unchanged is 8-bit/parity */
9992777ee89Sespie
10002777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
10012777ee89Sespie
10022777ee89Sespie /*work.c_iflag = savebuf.c_iflag;*/
10032777ee89Sespie work.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO);
10042777ee89Sespie work.c_lflag &= ~(ECHOE | ECHOK | ECHONL|ECHOCTL|ECHOPRT|ECHOKE);
10052777ee89Sespie work.c_iflag &= ~(IXON | IXANY | BRKINT);
10062777ee89Sespie work.c_oflag = savebuf.c_oflag;
10072777ee89Sespie work.c_cc[VTIME] = 0;
10082777ee89Sespie work.c_cc[VMIN] = 1;
10092777ee89Sespie }
10102777ee89Sespie else if(mode==3)
10112777ee89Sespie {
10122777ee89Sespie /* This should be an unbuffered mode with signals and control
10132777ee89Sespie characters enabled, as should be flow control. Echo should
10142777ee89Sespie still be off */
10152777ee89Sespie
10162777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
10172777ee89Sespie
10182777ee89Sespie work.c_iflag = savebuf.c_iflag;
10192777ee89Sespie work.c_lflag &= ~(ICANON | ECHO);
10202777ee89Sespie work.c_lflag &= ~(ECHOE | ECHOK | ECHONL|ECHOCTL|ECHOPRT|ECHOKE);
10212777ee89Sespie work.c_lflag |= ISIG | IEXTEN;
10222777ee89Sespie /*work.c_iflag &= ~(IXON | IXOFF | IXANY);
10232777ee89Sespie work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
10242777ee89Sespie work.c_oflag = savebuf.c_oflag;*/
10252777ee89Sespie work.c_cc[VTIME] = 0;
10262777ee89Sespie work.c_cc[VMIN] = 1;
10272777ee89Sespie }
10282777ee89Sespie else if(mode==2)
10292777ee89Sespie {
10302777ee89Sespie /* This should be an unbuffered mode with signals and control
10312777ee89Sespie characters enabled, as should be flow control. Echo should
10322777ee89Sespie still be off */
10332777ee89Sespie
10342777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
10352777ee89Sespie
10362777ee89Sespie work.c_iflag = savebuf.c_iflag;
10372777ee89Sespie work.c_lflag |= ICANON|ISIG|IEXTEN;
10382777ee89Sespie work.c_lflag &= ~ECHO;
10392777ee89Sespie work.c_lflag &= ~(ECHOE | ECHOK | ECHONL|ECHOCTL|ECHOPRT|ECHOKE);
10402777ee89Sespie /*work.c_iflag &= ~(IXON |IXOFF|IXANY);
10412777ee89Sespie work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
10422777ee89Sespie work.c_oflag = savebuf.c_oflag;
10432777ee89Sespie work.c_cc[VTIME] = savebuf.c_cc[VTIME];
10442777ee89Sespie work.c_cc[VMIN] = savebuf.c_cc[VMIN];*/
10452777ee89Sespie }
10462777ee89Sespie else if(mode==1)
10472777ee89Sespie {
10482777ee89Sespie /* This should be an unbuffered mode with signals and control
10492777ee89Sespie characters enabled, as should be flow control. Echo should
10502777ee89Sespie still be off */
10512777ee89Sespie
10522777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
10532777ee89Sespie
10542777ee89Sespie work.c_iflag = savebuf.c_iflag;
10552777ee89Sespie work.c_lflag |= ICANON|ECHO|ISIG|IEXTEN;
10562777ee89Sespie /*work.c_iflag &= ~(IXON |IXOFF|IXANY);
10572777ee89Sespie work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
10582777ee89Sespie work.c_oflag = savebuf.c_oflag;
10592777ee89Sespie work.c_cc[VTIME] = savebuf.c_cc[VTIME];
10602777ee89Sespie work.c_cc[VMIN] = savebuf.c_cc[VMIN];*/
10612777ee89Sespie }
10622777ee89Sespie else if(mode==0){
10632777ee89Sespie /*work.c_lflag &= ~BITMASK;
10642777ee89Sespie work.c_lflag |= savebuf.c_lflag & BITMASK;
10652777ee89Sespie work.c_oflag = savebuf.c_oflag;
10662777ee89Sespie work.c_cc[VTIME] = savebuf.c_cc[VTIME];
10672777ee89Sespie work.c_cc[VMIN] = savebuf.c_cc[VMIN];
10682777ee89Sespie work.c_iflag = savebuf.c_iflag;
10692777ee89Sespie work.c_iflag &= ~(IXON|IXOFF|IXANY);
10702777ee89Sespie work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);*/
10712777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
10722777ee89Sespie /*Copy(&work,&savebuf,1,sizeof(struct tbuffer));*/
10732777ee89Sespie
10742777ee89Sespie firsttime=1;
10752777ee89Sespie }
10762777ee89Sespie else
10772777ee89Sespie {
10782777ee89Sespie croak("ReadMode %d is not implemented on this architecture.",mode);
10792777ee89Sespie return;
10802777ee89Sespie }
10812777ee89Sespie
10822777ee89Sespie
10832777ee89Sespie /* If switching from a "lower power" mode to a higher one, keep the
10842777ee89Sespie data that may be in the queue, as it can easily be type-ahead. On
10852777ee89Sespie switching to a lower mode from a higher one, however, flush the queue
10862777ee89Sespie so that raw keystrokes won't hit an unexpecting program */
10872777ee89Sespie
10882777ee89Sespie if(DisableFlush || oldmode<=mode)
10892777ee89Sespie tcsetattr(handle,TCSANOW,&work);
10902777ee89Sespie else
10912777ee89Sespie tcsetattr(handle,TCSAFLUSH,&work);
10922777ee89Sespie
10932777ee89Sespie /*tcsetattr(handle,TCSANOW,&work);*/ /* It might be better to FLUSH
10942777ee89Sespie when changing gears to a lower mode,
10952777ee89Sespie and only use NOW for higher modes.
10962777ee89Sespie */
10972777ee89Sespie
10982777ee89Sespie
10992777ee89Sespie #endif
11002777ee89Sespie #ifdef USE_TERMIO
11012777ee89Sespie
11022777ee89Sespie /* What, me worry about standards? */
11032777ee89Sespie
11042777ee89Sespie # if !defined (IXANY)
11052777ee89Sespie # define IXANY (0)
11062777ee89Sespie # endif
11072777ee89Sespie
11082777ee89Sespie #ifndef ECHOE
11092777ee89Sespie #define ECHOE 0
11102777ee89Sespie #endif
11112777ee89Sespie #ifndef ECHOK
11122777ee89Sespie #define ECHOK 0
11132777ee89Sespie #endif
11142777ee89Sespie #ifndef ECHONL
11152777ee89Sespie #define ECHONL 0
11162777ee89Sespie #endif
11172777ee89Sespie #ifndef XCASE
11182777ee89Sespie #define XCASE 0
11192777ee89Sespie #endif
11202777ee89Sespie #ifndef BRKINT
11212777ee89Sespie #define BRKINT 0
11222777ee89Sespie #endif
11232777ee89Sespie
11242777ee89Sespie
11252777ee89Sespie
11262777ee89Sespie if(mode==5) {
11272777ee89Sespie /* This mode should be echo disabled, signals disabled,
11282777ee89Sespie flow control disabled, and unbuffered. CR/LF translation
11292777ee89Sespie is off, and 8 bits if possible */
11302777ee89Sespie
11312777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
11322777ee89Sespie
11332777ee89Sespie work.c_lflag &= ~(ECHO | ISIG | ICANON | XCASE);
11342777ee89Sespie work.c_lflag &= ~(ECHOE | ECHOK | ECHONL | TRK_IDEFAULT);
11352777ee89Sespie work.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | BRKINT);
11362777ee89Sespie if((work.c_cflag | PARENB)!=PARENB ) {
11372777ee89Sespie work.c_iflag &= ~(ISTRIP|INPCK);
11382777ee89Sespie work.c_iflag |= IGNPAR;
11392777ee89Sespie }
11402777ee89Sespie work.c_oflag &= ~(OPOST|ONLCR);
11412777ee89Sespie work.c_cc[VMIN] = 1;
11422777ee89Sespie work.c_cc[VTIME] = 1;
11432777ee89Sespie }
11442777ee89Sespie else if(mode==4) {
11452777ee89Sespie /* This mode should be echo disabled, signals disabled,
11462777ee89Sespie flow control disabled, and unbuffered. Parity is not
11472777ee89Sespie touched. */
11482777ee89Sespie
11492777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
11502777ee89Sespie
11512777ee89Sespie work.c_lflag &= ~(ECHO | ISIG | ICANON);
11522777ee89Sespie work.c_lflag &= ~(ECHOE | ECHOK | ECHONL TRK_IDEFAULT);
11532777ee89Sespie work.c_iflag = savebuf.c_iflag;
11542777ee89Sespie work.c_iflag &= ~(IXON | IXOFF | IXANY | BRKINT);
11552777ee89Sespie work.c_oflag = savebuf.c_oflag;
11562777ee89Sespie work.c_cc[VMIN] = 1;
11572777ee89Sespie work.c_cc[VTIME] = 1;
11582777ee89Sespie }
11592777ee89Sespie else if(mode==3) {
11602777ee89Sespie /* This mode tries to have echo off, signals enabled,
11612777ee89Sespie flow control as per the original setting, and unbuffered. */
11622777ee89Sespie
11632777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
11642777ee89Sespie
11652777ee89Sespie work.c_lflag &= ~(ECHO | ICANON);
11662777ee89Sespie work.c_lflag &= ~(ECHOE | ECHOK | ECHONL | TRK_IDEFAULT);
11672777ee89Sespie work.c_lflag |= ISIG;
11682777ee89Sespie work.c_iflag = savebuf.c_iflag;
11692777ee89Sespie work.c_iflag &= ~(IXON | IXOFF | IXANY);
11702777ee89Sespie work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
11712777ee89Sespie work.c_oflag = savebuf.c_oflag;
11722777ee89Sespie work.c_cc[VMIN] = 1;
11732777ee89Sespie work.c_cc[VTIME] = 1;
11742777ee89Sespie }
11752777ee89Sespie else if(mode==2) {
11762777ee89Sespie /* This mode tries to set echo on, signals on, and buffering
11772777ee89Sespie on, with flow control set to whatever it was originally. */
11782777ee89Sespie
11792777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
11802777ee89Sespie
11812777ee89Sespie work.c_lflag |= (ISIG | ICANON);
11822777ee89Sespie work.c_lflag &= ~ECHO;
11832777ee89Sespie work.c_lflag &= ~(ECHOE | ECHOK | ECHONL | TRK_IDEFAULT);
11842777ee89Sespie work.c_iflag = savebuf.c_iflag;
11852777ee89Sespie work.c_iflag &= ~(IXON | IXOFF | IXANY);
11862777ee89Sespie work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
11872777ee89Sespie work.c_oflag = savebuf.c_oflag;
11882777ee89Sespie work.c_cc[VMIN] = savebuf.c_cc[VMIN];
11892777ee89Sespie work.c_cc[VTIME] = savebuf.c_cc[VTIME];
11902777ee89Sespie
11912777ee89Sespie /* This assumes turning ECHO and ICANON back on is
11922777ee89Sespie sufficient to re-enable cooked mode. If this is a
11932777ee89Sespie problem, complain to me */
11942777ee89Sespie
11952777ee89Sespie /* What the heck. We're already saving the entire buf, so
11962777ee89Sespie I'm now going to reset VMIN and VTIME too. Hope this works
11972777ee89Sespie properly */
11982777ee89Sespie
11992777ee89Sespie }
12002777ee89Sespie else if(mode==1) {
12012777ee89Sespie /* This mode tries to set echo on, signals on, and buffering
12022777ee89Sespie on, with flow control set to whatever it was originally. */
12032777ee89Sespie
12042777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
12052777ee89Sespie
12062777ee89Sespie work.c_lflag |= (ECHO | ISIG | ICANON);
12072777ee89Sespie work.c_iflag &= ~TRK_IDEFAULT;
12082777ee89Sespie work.c_iflag = savebuf.c_iflag;
12092777ee89Sespie work.c_iflag &= ~(IXON | IXOFF | IXANY);
12102777ee89Sespie work.c_iflag |= savebuf.c_iflag & (IXON|IXOFF|IXANY);
12112777ee89Sespie work.c_oflag = savebuf.c_oflag;
12122777ee89Sespie work.c_cc[VMIN] = savebuf.c_cc[VMIN];
12132777ee89Sespie work.c_cc[VTIME] = savebuf.c_cc[VTIME];
12142777ee89Sespie
12152777ee89Sespie /* This assumes turning ECHO and ICANON back on is
12162777ee89Sespie sufficient to re-enable cooked mode. If this is a
12172777ee89Sespie problem, complain to me */
12182777ee89Sespie
12192777ee89Sespie /* What the heck. We're already saving the entire buf, so
12202777ee89Sespie I'm now going to reset VMIN and VTIME too. Hope this works
12212777ee89Sespie properly */
12222777ee89Sespie }
12232777ee89Sespie else if(mode==0) {
12242777ee89Sespie /* Put things back the way they were */
12252777ee89Sespie
12262777ee89Sespie /*work.c_lflag = savebuf.c_lflag;
12272777ee89Sespie work.c_iflag = savebuf.c_iflag;
12282777ee89Sespie work.c_oflag = savebuf.c_oflag;
12292777ee89Sespie work.c_cc[VMIN] = savebuf.c_cc[VMIN];
12302777ee89Sespie work.c_cc[VTIME] = savebuf.c_cc[VTIME];*/
12312777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
12322777ee89Sespie firsttime=1;
12332777ee89Sespie }
12342777ee89Sespie else
12352777ee89Sespie {
12362777ee89Sespie croak("ReadMode %d is not implemented on this architecture.",mode);
12372777ee89Sespie return;
12382777ee89Sespie }
12392777ee89Sespie
12402777ee89Sespie
12412777ee89Sespie if(DisableFlush || oldmode<=mode)
12422777ee89Sespie ioctl(handle,TCSETA,&work);
12432777ee89Sespie else
12442777ee89Sespie ioctl(handle,TCSETAF,&work);
12452777ee89Sespie
12462777ee89Sespie #endif
12472777ee89Sespie #ifdef USE_SGTTY
12482777ee89Sespie
12492777ee89Sespie
12502777ee89Sespie if(mode==5) {
12512777ee89Sespie /* Unbuffered, echo off, signals off, flow control off */
12522777ee89Sespie /* CR-CR/LF mode off too, and 8-bit path enabled. */
12532777ee89Sespie # if defined(TIOCLGET) && defined(LPASS8)
12542777ee89Sespie if((work.buf.sg_flags & (EVENP|ODDP))==0 ||
12552777ee89Sespie (work.buf.sg_flags & (EVENP|ODDP))==(EVENP|ODDP))
12562777ee89Sespie work.local |= LPASS8; /* If parity isn't being used, use 8 bits */
12572777ee89Sespie # endif
12582777ee89Sespie work.buf.sg_flags &= ~(ECHO|CRMOD);
12592777ee89Sespie work.buf.sg_flags |= (RAW|CBREAK);
12602777ee89Sespie # if defined(TIOCGETC)
12612777ee89Sespie work.tchar.t_intrc = -1;
12622777ee89Sespie work.tchar.t_quitc = -1;
12632777ee89Sespie work.tchar.t_startc= -1;
12642777ee89Sespie work.tchar.t_stopc = -1;
12652777ee89Sespie work.tchar.t_eofc = -1;
12662777ee89Sespie work.tchar.t_brkc = -1;
12672777ee89Sespie # endif
12682777ee89Sespie # if defined(TIOCGLTC)
12692777ee89Sespie work.ltchar.t_suspc= -1;
12702777ee89Sespie work.ltchar.t_dsuspc= -1;
12712777ee89Sespie work.ltchar.t_rprntc= -1;
12722777ee89Sespie work.ltchar.t_flushc= -1;
12732777ee89Sespie work.ltchar.t_werasc= -1;
12742777ee89Sespie work.ltchar.t_lnextc= -1;
12752777ee89Sespie # endif
12762777ee89Sespie }
12772777ee89Sespie else if(mode==4) {
12782777ee89Sespie /* Unbuffered, echo off, signals off, flow control off */
12792777ee89Sespie work.buf.sg_flags &= ~(ECHO|RAW);
12802777ee89Sespie work.buf.sg_flags |= (CBREAK|CRMOD);
12812777ee89Sespie # if defined(TIOCLGET)
12822777ee89Sespie work.local=savebuf.local;
12832777ee89Sespie # endif
12842777ee89Sespie # if defined(TIOCGETC)
12852777ee89Sespie work.tchar.t_intrc = -1;
12862777ee89Sespie work.tchar.t_quitc = -1;
12872777ee89Sespie work.tchar.t_startc= -1;
12882777ee89Sespie work.tchar.t_stopc = -1;
12892777ee89Sespie work.tchar.t_eofc = -1;
12902777ee89Sespie work.tchar.t_brkc = -1;
12912777ee89Sespie # endif
12922777ee89Sespie # if defined(TIOCGLTC)
12932777ee89Sespie work.ltchar.t_suspc= -1;
12942777ee89Sespie work.ltchar.t_dsuspc= -1;
12952777ee89Sespie work.ltchar.t_rprntc= -1;
12962777ee89Sespie work.ltchar.t_flushc= -1;
12972777ee89Sespie work.ltchar.t_werasc= -1;
12982777ee89Sespie work.ltchar.t_lnextc= -1;
12992777ee89Sespie # endif
13002777ee89Sespie }
13012777ee89Sespie else if(mode==3) {
13022777ee89Sespie /* Unbuffered, echo off, signals on, flow control on */
13032777ee89Sespie work.buf.sg_flags &= ~(RAW|ECHO);
13042777ee89Sespie work.buf.sg_flags |= CBREAK|CRMOD;
13052777ee89Sespie # if defined(TIOCLGET)
13062777ee89Sespie work.local=savebuf.local;
13072777ee89Sespie # endif
13082777ee89Sespie # if defined(TIOCGLTC)
13092777ee89Sespie work.tchar = savebuf.tchar;
13102777ee89Sespie # endif
13112777ee89Sespie # if defined(TIOCGLTC)
13122777ee89Sespie work.ltchar = savebuf.ltchar;
13132777ee89Sespie # endif
13142777ee89Sespie }
13152777ee89Sespie else if(mode==2) {
13162777ee89Sespie /* Buffered, echo on, signals on, flow control on */
13172777ee89Sespie work.buf.sg_flags &= ~(RAW|CBREAK);
13182777ee89Sespie work.buf.sg_flags |= CRMOD;
13192777ee89Sespie work.buf.sg_flags &= ~ECHO;
13202777ee89Sespie # if defined(TIOCLGET)
13212777ee89Sespie work.local=savebuf.local;
13222777ee89Sespie # endif
13232777ee89Sespie # if defined(TIOCGLTC)
13242777ee89Sespie work.tchar = savebuf.tchar;
13252777ee89Sespie # endif
13262777ee89Sespie # if defined(TIOCGLTC)
13272777ee89Sespie work.ltchar = savebuf.ltchar;
13282777ee89Sespie # endif
13292777ee89Sespie }
13302777ee89Sespie else if(mode==1) {
13312777ee89Sespie /* Buffered, echo on, signals on, flow control on */
13322777ee89Sespie work.buf.sg_flags &= ~(RAW|CBREAK);
13332777ee89Sespie work.buf.sg_flags |= ECHO|CRMOD;
13342777ee89Sespie # if defined(TIOCLGET)
13352777ee89Sespie work.local=savebuf.local;
13362777ee89Sespie # endif
13372777ee89Sespie # if defined(TIOCGLTC)
13382777ee89Sespie work.tchar = savebuf.tchar;
13392777ee89Sespie # endif
13402777ee89Sespie # if defined(TIOCGLTC)
13412777ee89Sespie work.ltchar = savebuf.ltchar;
13422777ee89Sespie # endif
13432777ee89Sespie }
13442777ee89Sespie else if(mode==0){
13452777ee89Sespie /* Original settings */
13462777ee89Sespie #if 0
13472777ee89Sespie work.buf.sg_flags &= ~(RAW|CBREAK|ECHO|CRMOD);
13482777ee89Sespie work.buf.sg_flags |= savebuf.sg_flags & (RAW|CBREAK|ECHO|CRMOD);
13492777ee89Sespie # if defined(TIOCLGET)
13502777ee89Sespie work.local=savebuf.local;
13512777ee89Sespie # endif
13522777ee89Sespie # if defined(TIOCGLTC)
13532777ee89Sespie work.tchar = savebuf.tchar;
13542777ee89Sespie # endif
13552777ee89Sespie # if defined(TIOCGLTC)
13562777ee89Sespie work.ltchar = savebuf.ltchar;
13572777ee89Sespie # endif
13582777ee89Sespie #endif
13592777ee89Sespie memcpy((void*)&work,(void*)&savebuf,sizeof(struct tbuffer));
13602777ee89Sespie firsttime=1;
13612777ee89Sespie }
13622777ee89Sespie else
13632777ee89Sespie {
13642777ee89Sespie croak("ReadMode %d is not implemented on this architecture.",mode);
13652777ee89Sespie return;
13662777ee89Sespie }
13672777ee89Sespie #if defined(TIOCLSET)
13682777ee89Sespie ioctl(handle,TIOCLSET,&work.local);
13692777ee89Sespie #endif
13702777ee89Sespie #if defined(TIOCSETC)
13712777ee89Sespie ioctl(handle,TIOCSETC,&work.tchar);
13722777ee89Sespie #endif
13732777ee89Sespie # if defined(TIOCGLTC)
13742777ee89Sespie ioctl(handle,TIOCSLTC,&work.ltchar);
13752777ee89Sespie # endif
13762777ee89Sespie if(DisableFlush || oldmode<=mode)
13772777ee89Sespie ioctl(handle,TIOCSETN,&work.buf);
13782777ee89Sespie else
13792777ee89Sespie ioctl(handle,TIOCSETP,&work.buf);
13802777ee89Sespie #endif
13812777ee89Sespie #ifdef USE_STTY
13822777ee89Sespie
13832777ee89Sespie /* No termio, termios or sgtty. I suppose we can try stty,
13842777ee89Sespie but it would be nice if you could get a better OS */
13852777ee89Sespie
13862777ee89Sespie if(mode==5)
13872777ee89Sespie system("/bin/stty raw -cbreak -isig -echo -ixon -onlcr -icrnl -brkint");
13882777ee89Sespie else if(mode==4)
13892777ee89Sespie system("/bin/stty -raw cbreak -isig -echo -ixon onlcr icrnl -brkint");
13902777ee89Sespie else if(mode==3)
13912777ee89Sespie system("/bin/stty -raw cbreak isig -echo ixon onlcr icrnl brkint");
13922777ee89Sespie else if(mode==2)
13932777ee89Sespie system("/bin/stty -raw -cbreak isig echo ixon onlcr icrnl brkint");
13942777ee89Sespie else if(mode==1)
13952777ee89Sespie system("/bin/stty -raw -cbreak isig -echo ixon onlcr icrnl brkint");
13962777ee89Sespie else if(mode==0)
13972777ee89Sespie system("/bin/stty -raw -cbreak isig echo ixon onlcr icrnl brkint");
13982777ee89Sespie
13992777ee89Sespie /* Those probably won't work, but they couldn't hurt
14002777ee89Sespie at this point */
14012777ee89Sespie
14022777ee89Sespie #endif
14032777ee89Sespie
14042777ee89Sespie /*warn("Mode set to %d.\n",mode);*/
14052777ee89Sespie
14062777ee89Sespie if( firsttime ) {
14072777ee89Sespie (void)hv_delete(filehash,(char*)&handle,sizeof(int),0);
14082777ee89Sespie (void)hv_delete(modehash,(char*)&handle,sizeof(int),0);
14092777ee89Sespie } else {
14102777ee89Sespie if(!hv_store(modehash,(char*)&handle,sizeof(int),
14112777ee89Sespie newSViv(mode),0))
14122777ee89Sespie croak("Unable to stash terminal settings.\n");
14132777ee89Sespie }
14142777ee89Sespie
14152777ee89Sespie }
14162777ee89Sespie
14172777ee89Sespie #ifdef USE_PERLIO
14182777ee89Sespie
14192777ee89Sespie /* Make use of a recent addition to Perl, if possible */
14202777ee89Sespie # define FCOUNT(f) PerlIO_get_cnt(f)
14212777ee89Sespie #else
14222777ee89Sespie
14232777ee89Sespie /* Make use of a recent addition to Configure, if possible */
14242777ee89Sespie # ifdef USE_STDIO_PTR
14252777ee89Sespie # define FCOUNT(f) PerlIO_get_cnt(f)
14262777ee89Sespie # else
14272777ee89Sespie /* This bit borrowed from pp_sys.c. Complain to Larry if it's broken. */
14282777ee89Sespie /* If any of this works PerlIO_get_cnt() will too ... NI-S */
14292777ee89Sespie # if defined(USE_STD_STDIO) || defined(atarist) /* this will work with atariST */
14302777ee89Sespie # define FBASE(f) ((f)->_base)
14312777ee89Sespie # define FSIZE(f) ((f)->_cnt + ((f)->_ptr - (f)->_base))
14322777ee89Sespie # define FPTR(f) ((f)->_ptr)
14332777ee89Sespie # define FCOUNT(f) ((f)->_cnt)
14342777ee89Sespie # else
14352777ee89Sespie # if defined(USE_LINUX_STDIO)
14362777ee89Sespie # define FBASE(f) ((f)->_IO_read_base)
14372777ee89Sespie # define FSIZE(f) ((f)->_IO_read_end - FBASE(f))
14382777ee89Sespie # define FPTR(f) ((f)->_IO_read_ptr)
14392777ee89Sespie # define FCOUNT(f) ((f)->_IO_read_end - FPTR(f))
14402777ee89Sespie # endif
14412777ee89Sespie # endif
14422777ee89Sespie # endif
14432777ee89Sespie #endif
14442777ee89Sespie
14452777ee89Sespie /* This is for the best, I'm afraid. */
14462777ee89Sespie #if !defined(FCOUNT)
14472777ee89Sespie # ifdef Have_select
14482777ee89Sespie # undef Have_select
14492777ee89Sespie # endif
14502777ee89Sespie # ifdef Have_poll
14512777ee89Sespie # undef Have_poll
14522777ee89Sespie # endif
14532777ee89Sespie #endif
14542777ee89Sespie
14552777ee89Sespie /* Note! If your machine has a bolixed up select() call that doesn't
14562777ee89Sespie understand this syntax, either fix the checkwaiting call below, or define
14572777ee89Sespie DONT_USE_SELECT. */
14582777ee89Sespie
14592777ee89Sespie #ifdef Have_select
selectfile(pTHX_ PerlIO * file,double delay)1460*99fd0875Safresh1 int selectfile(pTHX_ PerlIO *file,double delay)
14612777ee89Sespie {
14622777ee89Sespie struct timeval t;
14632777ee89Sespie int handle=PerlIO_fileno(file);
14642777ee89Sespie
14652777ee89Sespie /*char buf[32];
14662777ee89Sespie Select_fd_set_t fd=(Select_fd_set_t)&buf[0];*/
14672777ee89Sespie
14682777ee89Sespie fd_set fd;
14692777ee89Sespie if (PerlIO_fast_gets(file) && PerlIO_get_cnt(file) > 0)
14702777ee89Sespie return 1;
14712777ee89Sespie
14722777ee89Sespie /*t.tv_sec=t.tv_usec=0;*/
14732777ee89Sespie
14742777ee89Sespie if (delay < 0.0)
14752777ee89Sespie delay = 0.0;
14762777ee89Sespie t.tv_sec = (long)delay;
14772777ee89Sespie delay -= (double)t.tv_sec;
14782777ee89Sespie t.tv_usec = (long)(delay * 1000000.0);
14792777ee89Sespie
14802777ee89Sespie FD_ZERO(&fd);
14812777ee89Sespie FD_SET(handle,&fd);
14822777ee89Sespie if(select(handle+1,(Select_fd_set_t)&fd,
14832777ee89Sespie (Select_fd_set_t)0,
14842777ee89Sespie (Select_fd_set_t)&fd, &t)) return -1;
14852777ee89Sespie else return 0;
14862777ee89Sespie }
14872777ee89Sespie
14882777ee89Sespie #else
selectfile(pTHX_ PerlIO * file,double delay)1489*99fd0875Safresh1 int selectfile(pTHX_ PerlIO *file, double delay)
14902777ee89Sespie {
14912777ee89Sespie croak("select is not supported on this architecture");
14922777ee89Sespie return 0;
14932777ee89Sespie }
14942777ee89Sespie #endif
14952777ee89Sespie
14962777ee89Sespie #ifdef Have_nodelay
setnodelay(pTHX_ PerlIO * file,int mode)1497*99fd0875Safresh1 int setnodelay(pTHX_ PerlIO *file, int mode)
14982777ee89Sespie {
14992777ee89Sespie int handle=PerlIO_fileno(file);
15002777ee89Sespie int flags;
15012777ee89Sespie flags=fcntl(handle,F_GETFL,0);
15022777ee89Sespie if(mode)
15032777ee89Sespie flags|=O_NODELAY;
15042777ee89Sespie else
15052777ee89Sespie flags&=~O_NODELAY;
15062777ee89Sespie fcntl(handle,F_SETFL,flags);
15072777ee89Sespie return 0;
15082777ee89Sespie }
15092777ee89Sespie
15102777ee89Sespie #else
setnodelay(pTHX_ PerlIO * file,int mode)1511*99fd0875Safresh1 int setnodelay(pTHX_ PerlIO *file, int mode)
15122777ee89Sespie {
15132777ee89Sespie croak("setnodelay is not supported on this architecture");
15142777ee89Sespie return 0;
15152777ee89Sespie }
15162777ee89Sespie #endif
15172777ee89Sespie
15182777ee89Sespie #ifdef Have_poll
pollfile(pTHX_ pTHX_ PerlIO * file,double delay)1519*99fd0875Safresh1 int pollfile(pTHX_ pTHX_ PerlIO *file,double delay)
15202777ee89Sespie {
15212777ee89Sespie int handle=PerlIO_fileno(file);
15222777ee89Sespie struct pollfd fds;
15232777ee89Sespie if (PerlIO_fast_gets(f) && PerlIO_get_cnt(f) > 0)
15242777ee89Sespie return 1;
15252777ee89Sespie if(delay<0.0) delay = 0.0;
15262777ee89Sespie fds.fd=handle;
15272777ee89Sespie fds.events=POLLIN;
15282777ee89Sespie fds.revents=0;
15292777ee89Sespie return (poll(&fds,1,(long)(delay * 1000.0))>0);
15302777ee89Sespie }
15312777ee89Sespie #else
pollfile(pTHX_ PerlIO * file,double delay)1532*99fd0875Safresh1 int pollfile(pTHX_ PerlIO *file,double delay)
15332777ee89Sespie {
15342777ee89Sespie croak("pollfile is not supported on this architecture");
15352777ee89Sespie return 0;
15362777ee89Sespie }
15372777ee89Sespie #endif
15382777ee89Sespie
15392777ee89Sespie #ifdef WIN32
15402777ee89Sespie
15412777ee89Sespie /*
15422777ee89Sespie
15432777ee89Sespie This portion of the Win32 code is partially borrowed from a version of PDCurses.
15442777ee89Sespie
15452777ee89Sespie */
15462777ee89Sespie
15472777ee89Sespie typedef struct {
15482777ee89Sespie int repeatCount;
15492777ee89Sespie int vKey;
15502777ee89Sespie int vScan;
15512777ee89Sespie int ascii;
15522777ee89Sespie int control;
15532777ee89Sespie } win32_key_event_t;
15542777ee89Sespie
15552777ee89Sespie #define KEY_PUSH(I, K) { events[I].repeatCount = 1; events[I].ascii = K; }
15562777ee89Sespie #define KEY_PUSH3(K1, K2, K3) \
15572777ee89Sespie do { \
15582777ee89Sespie eventCount = 0; \
15592777ee89Sespie KEY_PUSH(2, K1); \
15602777ee89Sespie KEY_PUSH(1, K2); \
15612777ee89Sespie KEY_PUSH(0, K3); \
15622777ee89Sespie eventCount = 3; \
15632777ee89Sespie goto again; \
15642777ee89Sespie } while (0)
15652777ee89Sespie
15662777ee89Sespie #define KEY_PUSH4(K1, K2, K3, K4) \
15672777ee89Sespie do { \
15682777ee89Sespie eventCount = 0; \
15692777ee89Sespie KEY_PUSH(3, K1); \
15702777ee89Sespie KEY_PUSH(2, K2); \
15712777ee89Sespie KEY_PUSH(1, K3); \
15722777ee89Sespie KEY_PUSH(0, K4); \
15732777ee89Sespie eventCount = 4; \
15742777ee89Sespie goto again; \
15752777ee89Sespie } while (0)
15762777ee89Sespie
Win32PeekChar(pTHX_ PerlIO * file,double delay,char * key)1577*99fd0875Safresh1 int Win32PeekChar(pTHX_ PerlIO *file,double delay,char *key)
15782777ee89Sespie {
15792777ee89Sespie int handle;
15802777ee89Sespie HANDLE whnd;
15812777ee89Sespie INPUT_RECORD record;
15822777ee89Sespie DWORD readRecords;
15832777ee89Sespie
15842777ee89Sespie #if 0
15852777ee89Sespie static int keyCount = 0;
15862777ee89Sespie static char lastKey = 0;
15872777ee89Sespie #endif
15882777ee89Sespie
15892777ee89Sespie #define MAX_EVENTS 4
15902777ee89Sespie static int eventCount = 0;
15912777ee89Sespie static win32_key_event_t events[MAX_EVENTS];
15922777ee89Sespie int keyCount;
15932777ee89Sespie
15942777ee89Sespie file = STDIN;
15952777ee89Sespie
15962777ee89Sespie handle = PerlIO_fileno(file);
15972777ee89Sespie whnd = /*GetStdHandle(STD_INPUT_HANDLE)*/(HANDLE)_get_osfhandle(handle);
15982777ee89Sespie
15992777ee89Sespie
16002777ee89Sespie again:
16012777ee89Sespie #if 0
16022777ee89Sespie if (keyCount > 0) {
16032777ee89Sespie keyCount--;
16042777ee89Sespie *key = lastKey;
16052777ee89Sespie return TRUE;
16062777ee89Sespie }
16072777ee89Sespie #endif
16082777ee89Sespie
16092777ee89Sespie /* printf("eventCount: %d\n", eventCount); */
16102777ee89Sespie if (eventCount) {
16112777ee89Sespie /* printf("key %d; repeatCount %d\n", *key, events[eventCount - 1].repeatCount); */
16122777ee89Sespie *key = events[eventCount - 1].ascii;
16132777ee89Sespie events[eventCount - 1].repeatCount--;
16142777ee89Sespie if (events[eventCount - 1].repeatCount <= 0) {
16152777ee89Sespie eventCount--;
16162777ee89Sespie }
16172777ee89Sespie return TRUE;
16182777ee89Sespie }
16192777ee89Sespie
16202777ee89Sespie if (delay > 0) {
1621*99fd0875Safresh1 if (WaitForSingleObject(whnd, delay * 1000) != WAIT_OBJECT_0)
16222777ee89Sespie {
16232777ee89Sespie return FALSE;
16242777ee89Sespie }
16252777ee89Sespie }
16262777ee89Sespie
16272777ee89Sespie if (delay != 0) {
16282777ee89Sespie PeekConsoleInput(whnd, &record, 1, &readRecords);
16292777ee89Sespie if (readRecords == 0) {
16302777ee89Sespie return(FALSE);
16312777ee89Sespie }
16322777ee89Sespie }
16332777ee89Sespie
16342777ee89Sespie ReadConsoleInput(whnd, &record, 1, &readRecords);
16352777ee89Sespie switch(record.EventType)
16362777ee89Sespie {
16372777ee89Sespie case KEY_EVENT:
16382777ee89Sespie /* printf("\nkeyDown = %d, repeat = %d, vKey = %d, vScan = %d, ASCII = %d, Control = %d\n",
16392777ee89Sespie record.Event.KeyEvent.bKeyDown,
16402777ee89Sespie record.Event.KeyEvent.wRepeatCount,
16412777ee89Sespie record.Event.KeyEvent.wVirtualKeyCode,
16422777ee89Sespie record.Event.KeyEvent.wVirtualScanCode,
16432777ee89Sespie record.Event.KeyEvent.uChar.AsciiChar,
16442777ee89Sespie record.Event.KeyEvent.dwControlKeyState); */
16452777ee89Sespie
16462777ee89Sespie if (record.Event.KeyEvent.bKeyDown == FALSE)
16472777ee89Sespie goto again; /* throw away KeyUp events */
16482777ee89Sespie
16492777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 38) { /* up */
16502777ee89Sespie KEY_PUSH3(27, 91, 65);
16512777ee89Sespie }
16522777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 40) { /* down */
16532777ee89Sespie KEY_PUSH3(27, 91, 66);
16542777ee89Sespie }
16552777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 39) { /* right */
16562777ee89Sespie KEY_PUSH3(27, 91, 67);
16572777ee89Sespie }
16582777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 37) { /* left */
16592777ee89Sespie KEY_PUSH3(27, 91, 68);
16602777ee89Sespie }
16612777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 33) { /* page up */
16622777ee89Sespie KEY_PUSH3(27, 79, 121);
16632777ee89Sespie }
16642777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 34) { /* page down */
16652777ee89Sespie KEY_PUSH3(27, 79, 115);
16662777ee89Sespie }
16672777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 36) { /* home */
16682777ee89Sespie KEY_PUSH4(27, 91, 49, 126);
16692777ee89Sespie }
16702777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 35) { /* end */
16712777ee89Sespie KEY_PUSH4(27, 91, 52, 126);
16722777ee89Sespie }
16732777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 45) { /* insert */
16742777ee89Sespie KEY_PUSH4(27, 91, 50, 126);
16752777ee89Sespie }
16762777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 46) { /* delete */
16772777ee89Sespie KEY_PUSH4(27, 91, 51, 126);
16782777ee89Sespie }
16792777ee89Sespie
16802777ee89Sespie if (record.Event.KeyEvent.wVirtualKeyCode == 16
16812777ee89Sespie || record.Event.KeyEvent.wVirtualKeyCode == 17
16822777ee89Sespie || record.Event.KeyEvent.wVirtualKeyCode == 18
16832777ee89Sespie || record.Event.KeyEvent.wVirtualKeyCode == 20
16842777ee89Sespie || record.Event.KeyEvent.wVirtualKeyCode == 144
16852777ee89Sespie || record.Event.KeyEvent.wVirtualKeyCode == 145)
16862777ee89Sespie goto again; /* throw away shift/alt/ctrl key only key events */
16872777ee89Sespie keyCount = record.Event.KeyEvent.wRepeatCount;
16882777ee89Sespie break;
16892777ee89Sespie default:
16902777ee89Sespie keyCount = 0;
16912777ee89Sespie goto again;
16922777ee89Sespie break;
16932777ee89Sespie }
16942777ee89Sespie
16952777ee89Sespie *key = record.Event.KeyEvent.uChar.AsciiChar;
16962777ee89Sespie keyCount--;
16972777ee89Sespie
16982777ee89Sespie if (keyCount) {
16992777ee89Sespie events[0].repeatCount = keyCount;
17002777ee89Sespie events[0].ascii = *key;
17012777ee89Sespie eventCount = 1;
17022777ee89Sespie }
17032777ee89Sespie
17042777ee89Sespie return(TRUE);
17052777ee89Sespie
17062777ee89Sespie /* again:
17072777ee89Sespie return (FALSE);
17082777ee89Sespie */
17092777ee89Sespie
17102777ee89Sespie
17112777ee89Sespie }
17122777ee89Sespie #else
Win32PeekChar(pTHX_ PerlIO * file,double delay,char * key)1713*99fd0875Safresh1 int Win32PeekChar(pTHX_ PerlIO *file, double delay,char *key)
17142777ee89Sespie {
17152777ee89Sespie croak("Win32PeekChar is not supported on this architecture");
17162777ee89Sespie return 0;
17172777ee89Sespie }
17182777ee89Sespie #endif
17192777ee89Sespie
17202777ee89Sespie
blockoptions()1721*99fd0875Safresh1 STATIC int blockoptions() {
17222777ee89Sespie return 0
17232777ee89Sespie #ifdef Have_nodelay
17242777ee89Sespie | 1
17252777ee89Sespie #endif
17262777ee89Sespie #ifdef Have_poll
17272777ee89Sespie | 2
17282777ee89Sespie #endif
17292777ee89Sespie #ifdef Have_select
17302777ee89Sespie | 4
17312777ee89Sespie #endif
17322777ee89Sespie #ifdef USE_WIN32
17332777ee89Sespie | 8
17342777ee89Sespie #endif
17352777ee89Sespie ;
17362777ee89Sespie }
17372777ee89Sespie
termoptions()1738*99fd0875Safresh1 STATIC int termoptions() {
17392777ee89Sespie int i=0;
17402777ee89Sespie #ifdef USE_TERMIOS
17412777ee89Sespie i=1;
17422777ee89Sespie #endif
17432777ee89Sespie #ifdef USE_TERMIO
17442777ee89Sespie i=2;
17452777ee89Sespie #endif
17462777ee89Sespie #ifdef USE_SGTTY
17472777ee89Sespie i=3;
17482777ee89Sespie #endif
17492777ee89Sespie #ifdef USE_STTY
17502777ee89Sespie i=4;
17512777ee89Sespie #endif
17522777ee89Sespie #ifdef USE_WIN32
17532777ee89Sespie i=5;
17542777ee89Sespie #endif
17552777ee89Sespie return i;
17562777ee89Sespie }
17572777ee89Sespie
17582777ee89Sespie
17592777ee89Sespie
17602777ee89Sespie MODULE = Term::ReadKey PACKAGE = Term::ReadKey
17612777ee89Sespie
17622777ee89Sespie int
17632777ee89Sespie selectfile(file,delay)
17642777ee89Sespie InputStream file
17652777ee89Sespie double delay
1766*99fd0875Safresh1 CODE:
1767*99fd0875Safresh1 RETVAL = selectfile(aTHX_ file, delay);
1768*99fd0875Safresh1 OUTPUT:
1769*99fd0875Safresh1 RETVAL
17702777ee89Sespie
17712777ee89Sespie # Clever, eh?
17722777ee89Sespie void
17732777ee89Sespie SetReadMode(mode,file=STDIN)
17742777ee89Sespie int mode
17752777ee89Sespie InputStream file
17762777ee89Sespie CODE:
17772777ee89Sespie {
1778*99fd0875Safresh1 ReadMode(aTHX_ file,mode);
17792777ee89Sespie }
17802777ee89Sespie
17812777ee89Sespie int
17822777ee89Sespie setnodelay(file,mode)
17832777ee89Sespie InputStream file
17842777ee89Sespie int mode
1785*99fd0875Safresh1 CODE:
1786*99fd0875Safresh1 RETVAL = setnodelay(aTHX_ file, mode);
1787*99fd0875Safresh1 OUTPUT:
1788*99fd0875Safresh1 RETVAL
17892777ee89Sespie
17902777ee89Sespie int
17912777ee89Sespie pollfile(file,delay)
17922777ee89Sespie InputStream file
17932777ee89Sespie double delay
1794*99fd0875Safresh1 CODE:
1795*99fd0875Safresh1 RETVAL = pollfile(aTHX_ file, delay);
1796*99fd0875Safresh1 OUTPUT:
1797*99fd0875Safresh1 RETVAL
17982777ee89Sespie
17992777ee89Sespie SV *
Win32PeekChar(file,delay)18002777ee89Sespie Win32PeekChar(file, delay)
18012777ee89Sespie InputStream file
18022777ee89Sespie double delay
18032777ee89Sespie CODE:
18042777ee89Sespie {
18052777ee89Sespie char key;
1806*99fd0875Safresh1 if (Win32PeekChar(aTHX_ file, delay, &key))
18072777ee89Sespie RETVAL = newSVpv(&key, 1);
18082777ee89Sespie else
18092777ee89Sespie RETVAL = newSVsv(&PL_sv_undef);
18102777ee89Sespie }
18112777ee89Sespie OUTPUT:
18122777ee89Sespie RETVAL
18132777ee89Sespie
18142777ee89Sespie int
blockoptions()18152777ee89Sespie blockoptions()
18162777ee89Sespie
18172777ee89Sespie int
18182777ee89Sespie termoptions()
18192777ee89Sespie
18202777ee89Sespie int
18212777ee89Sespie termsizeoptions()
18222777ee89Sespie
18232777ee89Sespie void
18242777ee89Sespie GetTermSizeWin32(file=STDIN)
18252777ee89Sespie InputStream file
18262777ee89Sespie PPCODE:
18272777ee89Sespie {
18282777ee89Sespie int x,y,xpix,ypix;
1829*99fd0875Safresh1 if( GetTermSizeWin32(aTHX_ file,&x,&y,&xpix,&ypix)==0)
18302777ee89Sespie {
18312777ee89Sespie EXTEND(sp, 4);
18322777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)x)));
18332777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)y)));
18342777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)xpix)));
18352777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)ypix)));
18362777ee89Sespie }
18372777ee89Sespie else
18382777ee89Sespie {
18392777ee89Sespie ST(0) = sv_newmortal();
18402777ee89Sespie }
18412777ee89Sespie }
18422777ee89Sespie
18432777ee89Sespie void
18442777ee89Sespie GetTermSizeVIO(file=STDIN)
18452777ee89Sespie InputStream file
18462777ee89Sespie PPCODE:
18472777ee89Sespie {
18482777ee89Sespie int x,y,xpix,ypix;
1849*99fd0875Safresh1 if( GetTermSizeVIO(aTHX_ file,&x,&y,&xpix,&ypix)==0)
18502777ee89Sespie {
18512777ee89Sespie EXTEND(sp, 4);
18522777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)x)));
18532777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)y)));
18542777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)xpix)));
18552777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)ypix)));
18562777ee89Sespie }
18572777ee89Sespie else
18582777ee89Sespie {
18592777ee89Sespie ST(0) = sv_newmortal();
18602777ee89Sespie }
18612777ee89Sespie }
18622777ee89Sespie
18632777ee89Sespie void
18642777ee89Sespie GetTermSizeGWINSZ(file=STDIN)
18652777ee89Sespie InputStream file
18662777ee89Sespie PPCODE:
18672777ee89Sespie {
18682777ee89Sespie int x,y,xpix,ypix;
1869*99fd0875Safresh1 if( GetTermSizeGWINSZ(aTHX_ file,&x,&y,&xpix,&ypix)==0)
18702777ee89Sespie {
18712777ee89Sespie EXTEND(sp, 4);
18722777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)x)));
18732777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)y)));
18742777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)xpix)));
18752777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)ypix)));
18762777ee89Sespie }
18772777ee89Sespie else
18782777ee89Sespie {
18792777ee89Sespie ST(0) = sv_newmortal();
18802777ee89Sespie }
18812777ee89Sespie }
18822777ee89Sespie
18832777ee89Sespie void
18842777ee89Sespie GetTermSizeGSIZE(file=STDIN)
18852777ee89Sespie InputStream file
18862777ee89Sespie PPCODE:
18872777ee89Sespie {
18882777ee89Sespie int x,y,xpix,ypix;
1889*99fd0875Safresh1 if( GetTermSizeGSIZE(aTHX_ file,&x,&y,&xpix,&ypix)==0)
18902777ee89Sespie {
18912777ee89Sespie EXTEND(sp, 4);
18922777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)x)));
18932777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)y)));
18942777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)xpix)));
18952777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)ypix)));
18962777ee89Sespie }
18972777ee89Sespie else
18982777ee89Sespie {
18992777ee89Sespie ST(0) = sv_newmortal();
19002777ee89Sespie }
19012777ee89Sespie }
19022777ee89Sespie
19032777ee89Sespie int
19042777ee89Sespie SetTerminalSize(width,height,xpix,ypix,file=STDIN)
19052777ee89Sespie int width
19062777ee89Sespie int height
19072777ee89Sespie int xpix
19082777ee89Sespie int ypix
19092777ee89Sespie InputStream file
19102777ee89Sespie CODE:
19112777ee89Sespie {
1912*99fd0875Safresh1 RETVAL=SetTerminalSize(aTHX_ file,width,height,xpix,ypix);
19132777ee89Sespie }
19142777ee89Sespie OUTPUT:
19152777ee89Sespie RETVAL
19162777ee89Sespie
19172777ee89Sespie void
19182777ee89Sespie GetSpeed(file=STDIN)
19192777ee89Sespie InputStream file
19202777ee89Sespie PPCODE:
19212777ee89Sespie {
19222777ee89Sespie I32 in,out;
1923*99fd0875Safresh1 /*
1924*99fd0875Safresh1 * experimentally relaxed for
1925*99fd0875Safresh1 * https://rt.cpan.org/Ticket/Display.html?id=88050
19262777ee89Sespie if(items!=0) {
19272777ee89Sespie croak("Usage: Term::ReadKey::GetSpeed()");
19282777ee89Sespie }
1929*99fd0875Safresh1 */
1930*99fd0875Safresh1 if(getspeed(aTHX_ file,&in,&out)) {
19312777ee89Sespie /* Failure */
19322777ee89Sespie ST( 0) = sv_newmortal();
19332777ee89Sespie } else {
19342777ee89Sespie EXTEND(sp, 2);
19352777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)in)));
19362777ee89Sespie PUSHs(sv_2mortal(newSViv((IV)out)));
19372777ee89Sespie }
19382777ee89Sespie }
19392777ee89Sespie
19402777ee89Sespie
19412777ee89Sespie
19422777ee89Sespie BOOT:
19432777ee89Sespie newXS("Term::ReadKey::GetControlChars", XS_Term__ReadKey_GetControlChars, file);
19442777ee89Sespie newXS("Term::ReadKey::SetControlChars", XS_Term__ReadKey_SetControlChars, file);
19452777ee89Sespie filehash=newHV();
19462777ee89Sespie modehash=newHV();
1947