|
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() */ }