diff options
Diffstat (limited to 'dviware/dvgtk/screenio.c')
-rw-r--r-- | dviware/dvgtk/screenio.c | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/dviware/dvgtk/screenio.c b/dviware/dvgtk/screenio.c new file mode 100644 index 0000000000..9a93a36f82 --- /dev/null +++ b/dviware/dvgtk/screenio.c @@ -0,0 +1,483 @@ +/* screenio.c - display functions + $Id: screenio.c,v 0.2 1997/03/28 03:17:23 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#include "dvgt.h" +#include "screenio.h" +#include "unixio.h" +#include "vdu.h" + +/* Variables Exported, via "screenio.h" */ + +char TeXtoASCII[XXX]; + + +/* IMPORT InitVDU, ClearScreen, StartText, ClearScreen, ResetVDU. + To handle ^Z suspension properly, ScreenIO needs to use some VDU routines. + */ + +/* SYSDEP: We need to use the Unix write routine. + In particular, using Pascal's write/writeln has some nasty side-effect + that prevents BusyRead from working! + */ + +int textlinewidth; /* text characters (columns) per line */ +int textcolumn = 0; /* column number in current text line */ + +/*--------------------------------------------------------------------*/ + +int +MesgChar (int ch) +{ + int status; + /* maxcol <= both size of a string, and width of a line */ + int maxcol = (maxstring < textlinewidth ? maxstring : textlinewidth); + + /* Keep messages within maxcol columns */ + if (textcolumn >= maxcol) + status = EOF; + else + { + status = putchar (ch); + ++textcolumn; + } + return status; +} +/* MesgChar */ + +/*--------------------------------------------------------------------*/ + +int +MesgString (const char *s) +{ + int status; + String message; + /* maxcol <= both size of a string, and width of a line */ + int maxcol = (maxstring < textlinewidth ? maxstring : textlinewidth); + + /* Keep messages within maxcol columns */ + if (textcolumn < 0 || textcolumn >= maxcol) + { + strcpy (message, ""); + } + else + { + strncpy (message, s, maxcol - textcolumn); + message[maxcol - textcolumn] = '\0'; + } + + status = fputs (message, stdout); + textcolumn += strlen (message); + return status; +} +/* MesgString */ + +/*--------------------------------------------------------------------*/ + +int +MesgFlush () +{ + int status = fflush (stdout); + textcolumn = 0; + return status; +} +/* MesgFlush */ + +/*--------------------------------------------------------------------*/ + +void +MesgLine () +{ + save_temp_tty (); + rawoutoff (); /* Enable NL to CR+LF mapping */ + /*!!! putchar (CR); *//* SYSDEP: Really an NL */ + putchar ('\r'); /* SYSDEP: Really an NL */ + putchar ('\n'); /* SYSDEP: Really an NL */ + MesgFlush (); /* MesgLine also updates terminal */ + restore_temp_tty (); +} +/* MesgLine */ + +/*--------------------------------------------------------------------*/ + +static int +MesgCard (int c) +{ + /* Since the vast majority of given values will be small numbers, we avoid + recursion until c >= 100. + */ + + int len = 0; + if (c < 10) + { + MesgChar (c + '0'); + ++len; + } + else if (c < 100) + { + MesgChar (c / 10 + '0'); + MesgChar (c % 10 + '0'); + len += 2; + } + else + { /* c >= 100 */ + len += MesgCard (c / 100); /* recursive if c >= 100 */ + c %= 100; + MesgChar (c / 10 + '0'); + MesgChar (c % 10 + '0'); + len += 2; + } + return (len); +} +/* MesgCard */ + +/*--------------------------------------------------------------------*/ + +int +MesgInt (int i) +{ + int len = 0; + if (i < 0) + { + MesgChar ('-'); + ++len; + i = abs (i); + } + len += MesgCard (i); + return (len); +} +/* MesgInt */ + +/*--------------------------------------------------------------------*/ + +void +WriteLine () +{ + WriteChar (CR); + WriteFlush (); /* WriteLine also updates terminal */ +} +/* WriteLine */ + +/*--------------------------------------------------------------------*/ + +static void +WriteCard (int c) +{ + /* Since the vast majority of given values will be small numbers, we avoid + recursion until c >= 100. + */ + + if (c < 10) + { + WriteChar (c + '0'); + return; + } + if (c < 100) + { + WriteChar (c / 10 + '0'); + WriteChar (c % 10 + '0'); + return; + } + else + { + WriteCard (c / 100); /* recursive if c >= 100 */ + c %= 100; + WriteChar (c / 10 + '0'); + WriteChar (c % 10 + '0'); + } +} +/* WriteCard */ + +/*--------------------------------------------------------------------*/ + +void +WriteInt (int i) +{ + if (i < 0) + { + WriteChar ('-'); + i = abs (i); + } + WriteCard (i); +} +/* WriteInt */ + +/*--------------------------------------------------------------------*/ + +static void +Restore_Temp_Terminal () +{ + /* Restore_Temp_Terminal is for screenio.c only. */ + + MesgFlush (); /* make sure terminal is up-to-date */ + restore_temp_tty (); /* restore terminal characteristics saved below */ +} + +/* Restore_Temp_Terminal */ + +/*--------------------------------------------------------------------*/ + +void +RestoreTerminal () +{ + /* RestoreTerminal restores the initial terminal setting. */ + /* It should be called before any client module terminates. */ + MesgFlush (); /* make sure terminal is up-to-date */ + restore_init_tty (); /* restore terminal characteristics saved below */ +} + +/* RestoreTerminal */ + +/*--------------------------------------------------------------------*/ + +void +ReadChar (char *ch) +{ + /* gt - if cbreak's off, turn it on */ + singlecharon (); + /* gt - if echo's on, turn it off */ + echooff (); + + /* gt - at this point, we need singlechar (cbreak) on and echo off. */ + /* gt - BUT WHY? */ + + /* check for CTRL-C or CTRL-Z */ + + /* Interrupted by user? (CTRL-C) */ + if (sig_flags.intr) + { /* echo ch since echooff has been called */ + /* interrupt */ + sig_flags.intr = 0; /* reset intr flag */ + *ch = CR; /* return to "Command: " prompt level */ + } + else if (sig_flags.tstop) + { /* Suspended by user? (CTRL-Z) */ + /* suspend */ + sig_flags.tstop = 0; /* reset tstop flag */ + + StartText (); + ClearScreen (); + MesgLine (); + ResetVDU (); + Restore_Temp_Terminal (); + + suspend (); + save_temp_tty (); + + singlecharon (); + rawouton (); + echooff (); + + InitVDU (); + StartText (); + ClearScreen (); + + *ch = CR; /* return to Command: level */ + } + else + { + putchar (*ch = getchar ()); + } +} +/* ReadChar */ + +/*--------------------------------------------------------------------*/ + +void +ReadString (char *s) +{ + /* Read a string of characters. + The routine is terminated upon carriage return. + */ + + char ch; + int i; + + singlecharoff (); /* read string in cooked mode */ + rawoutoff (); + echoon (); /* echo characters */ + + for (i = 0; true; i++) + { + if (sig_flags.intr) + { + /* interrupt */ + sig_flags.intr = 0; /* reset intr flag */ + s[0] = '\0'; + break; + } + if (sig_flags.tstop) + { + /* suspend */ + sig_flags.tstop = 0; /* reset tstop flag */ + + StartText (); + ClearScreen (); + MesgLine (); + ResetVDU (); + Restore_Temp_Terminal (); + + suspend (); + save_temp_tty (); + /* singlecharon and echooff are called below */ + + InitVDU (); + StartText (); + ClearScreen (); + + s[0] = '\0'; + break; + } + ch = getchar (); + if (ch == CR) + { + s[i] = '\0'; + break; + } + s[i] = ch; + if (i == maxstring) + { + s[i] = '\0'; + break; + } + } + singlecharon (); /* return to cbreak mode */ + rawouton (); + echooff (); /* and no echo */ +} +/* ReadString */ + +/*--------------------------------------------------------------------*/ + +boolean +BusyRead (char *ch) +{ + /* Return TRUE if ch is waiting in input buffer or if a ^C or ^Z has been + typed. Set ch to CR or the character read (no echo). + If nothing in input buffer, then ch is undefined and we return FALSE. + */ + + if (sig_flags.intr) + { + /* interrupt */ + sig_flags.intr = 0; + *ch = CR; /* main module will return to Command: level */ + return true; + } + if (sig_flags.tstop) + { + /* suspend */ + sig_flags.tstop = 0; + + StartText (); + ClearScreen (); + MesgLine (); + ResetVDU (); + Restore_Temp_Terminal (); + + suspend (); + save_temp_tty (); + /* singlecharon and echooff are called below */ + + InitVDU (); + StartText (); + ClearScreen (); + + *ch = CR; /* after suspend, return to Command: level */ + return true; + } + /* SYSDEP: buffercount assumes singlecharon and echooff have been called */ + + /* gt - check whether singlecharon and echooff have been called */ + + if (cmode_flags.cbreak == 0) + singlecharon (); + + if (cmode_flags.echo == 1) + echooff (); + + if (buffercount () == 0) + return false; + else + { + *ch = getchar (); + return true; + } +} +/* BusyRead */ + +/*--------------------------------------------------------------------*/ + +static void +InitTeXtoASCII () +{ + /* Initialize TeXtoASCII array used in specific ShowChar/Rectangle routines + to map a given TeX char into a similar, displayable ASCII char. + */ + + int i; + + for (i = 0; i <= 0xa; i++) /* Greek letters */ + TeXtoASCII[i] = '?'; + for (i = 0xb; i <= 0xf; i++) /* ligatures */ + TeXtoASCII[i] = '?'; + TeXtoASCII[0x10] = 'i'; /* dotless i */ + TeXtoASCII[0x11] = 'j'; /* dotless j */ + TeXtoASCII[0x12] = '`'; /* grave accent */ + TeXtoASCII[0x13] = '\''; /* acute accent */ + for (i = 0x14; i <= 0x17; i++) /* high accents */ + TeXtoASCII[i] = '~'; + TeXtoASCII[0x18] = ','; /* cedilla */ + for (i = 0x19; i <= 0x20; i++) /* foreigns */ + TeXtoASCII[i] = '?'; + for (i = 0x21; i <= 0x5b; i++) /* same */ + TeXtoASCII[i] = i; + TeXtoASCII[0x5c] = '"'; /* open dble quote */ + TeXtoASCII[0x5d] = ']'; /* same */ + for (i = 0x5e; i <= 0x5f; i++) /* more accents */ + TeXtoASCII[i] = '^'; + for (i = 0x60; i <= 0x7a; i++) /* same */ + TeXtoASCII[i] = i; + for (i = 0x7b; i <= 0x7c; i++) /* en & em dash */ + TeXtoASCII[i] = '-'; + for (i = 0x7d; i <= 0x7f; i++) /* more accents */ + TeXtoASCII[i] = '~'; + for (i = 0x80; i <= 0xff; i++) /* non-ASCII, but 8-bit: 128 to 255 */ + TeXtoASCII[i] = '?'; +} +/* InitTeXtoASCII */ + +/*--------------------------------------------------------------------*/ + +void +InitScreenIO () +{ + InitTeXtoASCII (); + /* We first save the current terminal characteristics. + save_init_tty also calls save_temp_tty, which + sets up ^C/^Z interrupt handlers; see unixio.c. + */ + save_init_tty (); + atexit (RestoreTerminal); + + singlecharon (); /* cbreak mode for ReadChar and BusyRead */ + echooff (); /* no echo for BusyRead */ + rawouton (); + /* was _IOFBF */ +#ifdef SETVBUF_REVERSED + if (setvbuf (stdout, _IONBF, NULL, BUFSIZ / 4) != 0) + { +#else + if (setvbuf (stdout, NULL, _IONBF, BUFSIZ / 4) != 0) + { +#endif + MesgString ("screenio.c: InitScreenIO: setvbuf failed!"); + MesgLine (); + } +} +/* InitScreenIO */ + +/*--------------------------------------------------------------------*/ + +/* end screenio.c */ |