|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 8314 (0x207a)
Types: TextFile
Names: »screenio.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
└─⟦883b7f77d⟧ »dvi2vdu.tar.Z«
└─⟦f158c222e⟧
└─⟦this⟧ »dvi2vdu/dvi2vdu-1.1J/src/screenio.c«
/* Original Author: Andrew Trevorrow
Implementation: Modula-2 under VAX/UNIX 4.2 BSD
Date Started: June, 1986
Description:
Implements terminal i/o routines used by DVItoVDU. Highly SYSDEP!
This version converted to C and ported to BSD and System V UNIX by
some chaps at Kernel Technology up to September 1989. Contact
mjh@uk.co.kernel (Mark J. Hewitt) with bug fixes etc.
Involved were: Mark J. Hewitt
Dave Dixon
Marc Hadley
*/
/* SYSDEP: we need to write a block of characters (including NULLs) */
#include "def.h"
#include <math.h>
#include "screenio.h"
#include "dvitovdu.h"
static char *sccsid[] = "@(#)screenio.c 1.1";
/* SYSDEP: C routines written by Alex Dickinson */
/* WARNING: To handle ^Z suspension properly, screenio needs to use some of
the vduinterface routines. But vduinterface imports screenio, so there
is a circular dependency.
Everything should be ok as long as the vduinterface routines
are only called in the reading routines. DVItoVDU calls
the first ReadString()only AFTER calling InitVDUInterface()
*/
extern void singlecharon(),
singlecharoff(),
echoon(),
echooff(),
restoretty(),
savetty();
extern int getcharnowait();
void Abort ();
#define MAXBUFSIZE 1024 /* size of output buffer */
#define NULLCHAR '\0' /* SYSDEP: used to terminate a string */
#define EOL '\012' /* SYSDEP: char read upon hitting RETURN */
#define LF '\012'
#define CR '\015'
#define CTRLC '\0' /* SYSDEP: interrupt, see unixio */
#define CTRLZ '\01' /* SYSDEP: suspend, see unixio */
/* SYSDEP: unixio puts CTRLC and CTRLZ into input buffer (along with CR) upon
getting a ^C or ^Z interrupt. (It can't put '\3' and '\32' into buffer
because tty will detect another interrupt and we'll loop forever!) */
char buffer[MAXBUFSIZE]; /* output buffer */
int buflen; /* number of characters in output buffer */
/******************************************************************************/
void Read (ch)
char *ch;
{
int dummy;
/* SYSDEP: Readc assumes singlecharon has been called */
if ((dummy = getchar ()) == EOF)
{
#ifdef DEBUG
(void) printf("Readc failed in Read()\n");
#endif /* DEBUG */
Abort ();
}
else
{
*ch = (char) dummy;
/* check for CTRLC or CTRLZ */
if (*ch == CTRLC)
{
/* interrupt */
(void) getchar (); /* remove terminator */
*ch = EOL; /* return to Command: level */
}
else
if (*ch == CTRLZ)
{
/* suspend */
(void) getchar (); /* remove terminator */
StartText ();
ClearScreen ();
WriteLn ();
ResetVDU ();
RestoreTerminal ();
suspend ();
savetty ();
singlecharon ();
echooff ();
InitVDUInterface ();
StartText ();
ClearScreen ();
*ch = EOL; /* return to Command: level */
}
else
{
dummy = (int) * ch;
(void) putchar (dummy); /* echo ch since echooff has been called */
}
}
}
/******************************************************************************/
void ReadString (s, maxlength)
unsigned int maxlength;
char *s;
{
/* Read()a string of characters.
The routine is terminated upon carriage return.
DEL can be used to erase the last character entered.
If s is not full then NULLCHAR will terminate the string.
*/
unsigned int i;
singlecharoff (); /* read string in cooked mode */
echoon (); /* echo characters */
s[0] = NULLCHAR; /* we seem to need this in case user just hits
return */
/* (void) printf ("%%"); */
if (fgets (s, (int)maxlength, stdin) == NULL)
{
/* SYSDEP: ^D will cause end of input file; no more reads are possible! */
Abort ();
}
if(strlen(s) > 0)
s[strlen (s) - 1] = '\0'; /* remove \n from string */
i = 0;
for (;;)
{
if ((i > maxlength - 1) || (s[i] == NULLCHAR))
break;
if (s[i] == CTRLC)
{
/* interrupt */
s[0] = NULLCHAR; /* simply return an empty string */
break;
}
else
if (s[i] == CTRLZ)
{
/* suspend */
StartText ();
ClearScreen ();
WriteLn ();
ResetVDU ();
RestoreTerminal ();
suspend ();
savetty ();
/* singlecharon and echooff are called below */
InitVDUInterface ();
StartText ();
ClearScreen ();
s[0] = NULLCHAR; /* return an empty string */
break;
}
i++;
}
singlecharon (); /* return to cbreak mode */
echooff (); /* and no echo */
}
/******************************************************************************/
short BusyRead (ch)
char *ch;
{
/* Return TRUE if ch is waiting in input buffer, and read it with no echo.
If nothing in input buffer then ch is undefined and we return FALSE.
*/
int dummy;
/* SYSDEP: getcharnowait assumes singlecharon and echooff have been called */
if ((dummy = getcharnowait ()) == EOF)
{
return (FALSE);
}
else
{
*ch = (char) dummy;
if (*ch == CTRLC)
{
/* interrupt */
*ch = EOL; /* main module will return to Command: level */
}
else
if (*ch == CTRLZ)
{
/* suspend */
#ifndef USG
StartText ();
ClearScreen ();
WriteLn ();
ResetVDU ();
RestoreTerminal ();
suspend ();
savetty ();
singlecharon ();
echooff ();
InitVDUInterface ();
StartText ();
ClearScreen ();
#endif /* USG */
*ch = EOL; /* after suspend, return to Command: level */
}
return (TRUE);
}
}
/******************************************************************************/
void Abort ()
{
/* HALT after restoring terminal to a nice clean state. */
StartText ();
ClearScreen ();
WriteLn ();
ResetVDU ();
RestoreTerminal ();
exitprog (1);
}
/******************************************************************************/
void Write (ch)
char ch;
{
/* This is the only place where a character is put into the output buffer.*/
if (buflen == MAXBUFSIZE)
{
(void) write (1, buffer, (unsigned) buflen);/* write entire buffer */
buflen = 0;
}
buffer[buflen] = ch;
buflen++;
}
/******************************************************************************/
void WriteString (s)
char *s;
{
/* SYSDEP: we assume end of string is first NULLCHAR, or string is full */
while(*s != NULLCHAR)
Write(*s++);
}
/******************************************************************************/
void WriteInt (i)
int i;
{
/* We call WriteCard()after writing any '-' sign. */
if (i < 0)
{
Write ('-');
i = ABS (i);
}
WriteCard ((unsigned) i);
}
/******************************************************************************/
void WriteCard (c)
unsigned int c;
{
/* Since the vast majority of given values will be small numbers, we avoid
recursion until c >= 100.
*/
if (c < 10)
{
Write ((char) ('0' + c));
}
else
if (c < 100)
{
Write ((char) ('0' + (c / 10)));
Write ((char) ('0' + (c % 10)));
}
else
{
WriteCard (c / 100); /* recursive if c >= 100 */
c = c % 100;
Write ((char) ('0' + (c / 10)));
Write ((char) ('0' + (c % 10)));
}
}
/******************************************************************************/
void WriteLn ()
{
Write (CR);
Write (LF);
WriteBuffer (); /* WriteLn()also updates terminal */
}
/******************************************************************************/
void WriteBuffer ()
{
/* Output the buffer; either buffer is full or client has explicitly
requested the terminal to be updated.
*/
if (buflen > 0)
{
(void) write (1, buffer, (unsigned) buflen);
buflen = 0;
}
}
/******************************************************************************/
void RestoreTerminal ()
{
/* RestoreTerminal()should be called before any client module terminates. */
WriteBuffer (); /* make sure terminal is up-to-date */
restoretty (); /* SYSDEP: reset terminal characteristics saved
below */
}
/******************************************************************************/
void Initscreenio ()
{
buflen = 0;
/* SYSDEP: we first save the current terminal characteristics.
savetty also sets up ^C/^Z interrupt handlers; see unixio.c.
*/
savetty ();
singlecharon (); /* cbreak mode for Read()and BusyRead() */
echooff (); /* no echo for BusyRead() */
}