|
|
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 p
Length: 7540 (0x1d74)
Types: TextFile
Names: »pager.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦e7f64e0c0⟧ »EurOpenD3/mail/vmh.tar.Z«
└─⟦dcb95597f⟧
└─⟦this⟧ »pager.c«
#ifndef lint
static char rcsid[] =
"$Header: pager.c,v 1.10 88/01/13 19:14:52 deboor Exp $";
static char notice[] =
"This program is in the public domain and is available for unlimited \
distribution as long as this notice is enclosed.";
#endif lint
/*
* support routines for paging things in the bottom display window.
*
* $Source: /c/support/deboor/usr/src/old/vmh/RCS/pager.c,v $
* $Revision: 1.10 $
* $Author: deboor $
*
* FUNCTIONS:
* end_pager finish out pager session
* init_pager initialize pager variables
* newline do a newline in a window. returns ERR if at end of page
* nextpage prompt for another page
* putstr print a string worrying about word wrap.
*/
#include "vmh.h"
#include <sys/file.h>
typedef struct _blist { /* structure to implement 'b' in nextpage() */
off_t bl_off; /* offset where last page was */
struct _blist *bl_next, /* pointer to structure for previous page */
*bl_prev;
} BLIST;
static int lines; /* the number of lines printed */
static int fLines; /* the number of lines in the file so far */
static int lastpage; /* the last page number (set in nextpage()) */
static BLIST bL0 = { 0, 0, 0 };
static struct {
BLIST *head,
*tail,
*cur;
int pageno;
} backList;
static FILE *curFile;
static WINDOW *curWin;
/*
* init_pager(fl, win) FILE *fl; WINDOW *win;
* Initializes pager-related variables. Must be called before using pager
* routines.
*/
init_pager(fl, win)
FILE *fl;
WINDOW *win;
{
curWin = win;
curFile = fl;
lines = win->_maxy - 1;
fLines = 0;
backList.head = backList.tail = backList.cur = &bL0;
bL0.bl_next = (BLIST *) 0;
lastpage = backList.pageno = 0;
}
/*
* end_pager()
* frees up any backList remaining. Should be called when done using pager
* routines.
*/
end_pager()
{
register BLIST *bL;
for (bL = backList.head->bl_next; bL; bL = bL->bl_next)
Free ((char *) bL);
curFile = (FILE *) 0;
curWin = (WINDOW *) 0;
}
/*
** newline ()
** simulates a '\n' being printed to window curWin.
** if we're on the bottom line already, then calls
** scrollup() to scroll the window, else it just
** increments the y coordinate. In either case
** curx is set back to 0. If the newly-incremented
** global variable 'lines' is equal to maxy, ERR
** is returned, else OK is returned.
*/
newline (godown)
int godown;
{
BLIST *bL;
wclrtoeol(curWin);
curWin->_curx = 0;
fLines++;
if ((fLines % curWin->_maxy == 0) && curFile) {
backList.cur = backList.cur->bl_next;
if (! backList.cur) {
bL = AllocST(BLIST);
bL->bl_off = ftell (curFile);
bL->bl_prev = backList.tail;
backList.tail->bl_next = bL;
backList.cur = backList.tail = bL;
bL->bl_next = (BLIST *) 0;
}
backList.pageno++;
}
if (! lines--) {
lines = (curWin->_maxy - 1) - LEFTOVER;
return ERR;
} else {
if (godown) {
if (curWin->_cury >= curWin->_maxy - 1)
scrollup(curWin);
else
curWin->_cury++;
wclrtoeol(curWin);
}
return OK;
}
}
/*
* nextpage ()
* Prompt for next page? Returns 1 if done, 0 to continue...
* win is the window in which the file was being displayed.
* if curFile is set, backpaging is enabled and all that goes with it.
* the --More-- prompt is always displayed in the cmdWin.
*/
nextpage()
{
register int c; /* input character */
struct stat sb;
int pct; /* the percent seen and a general
* flag telling if curFile is valid */
if (!curFile) {
pct = -1;
} else if (fstat (fileno(curFile), &sb) < 0) {
pct = -1;
} else {
/*
* if ftell returns an error, pct will be
* negative so it won't be used
*/
pct = ftell (curFile) * 100 / sb.st_size;
}
wrefresh(curWin);
waitforit:
for ( ; ; ) /* Loop till non-^L key pushed */
{
wmove(cmdWin, 0, 0);
wstandout(cmdWin);
waddstr (cmdWin, "--More--");
if (pct >= 0)
wprintw (cmdWin,"(%d%%)", pct);
if (! terse)
waddstr (cmdWin, "[Press space to continue, 'q' to quit]");
wclrtoeol (cmdWin);
wstandend(cmdWin);
wrefresh(cmdWin);
_puts (SE); /* turn the damn thing OFF */
curscr->_flags &= ~_STANDOUT;
c = mygetch(cmdWin) & 0177;
werase(cmdWin);
wrefresh(cmdWin); /* This is pretty weird logic */
if (c == '\014' || c == '\022') /*^L or ^R redraws the screen */
cmdRedraw(); /* I think it must be time to go */
else
break; /* home and get some sleep */
/* beware of standout curses bug! */
}
if (c == 'b') {
if (pct < 0) {
beep();
goto waitforit;
}
backList.cur = (backList.cur->bl_prev) ?
backList.cur->bl_prev :
backList.cur;
backList.pageno--;
if (lastpage == backList.pageno) {
backList.cur = (backList.cur->bl_prev) ?
backList.cur->bl_prev :
backList.cur;
backList.pageno--;
}
Fseek (curFile, backList.cur->bl_off, L_SET);
fLines -= curWin->_maxy-1;
lines = curWin->_maxy-1;
lastpage = backList.pageno;
wmove (curWin, 0, 0);
return (0);
}
lastpage = backList.pageno; /* ???? */
if (c == '\n' || c == '\r') {
scrollup (curWin);
wmove (curWin, curWin->_maxy - 1, 0);
wclrtobot(curWin);
lines = 0;
return (0);
}
if( c == ' ' ) {
if (do_page) {
wmove(curWin, 0, 0);
lines += LEFTOVER;
} else {
scrollup (curWin);
}
return( 0 );
}
else if( c >= '0' && c <= '9') { /* scroll n lines */
lines = c - '0';
scrollup (curWin);
return( 0 );
}
else if (c != 'q') {
/*
* put character back in buffer as first chr$ of command
*/
ungetc (c, stdin);
}
return( 1 );
}
/*
** putstr (str) register char *str;
** prints the specified string str to the specified window win
** performing margin-wraping and changing any non-printable characters
** besides ' ', '\t' '\n' and '\f' into printable ones using unctrl().
** If the printing of a character returns ERR, nextpage() is called to
** prompt for input. If this returns 1, output is stopped with a 1 return
** code, else the printing of str continues.
** WrapMargin is the offset from the right side of the window at which to
** start looking for spaces which can be changed to '\n's.
*/
putstr (str)
Reg4 char *str;
{
Reg2 int i;
Reg3 int j;
Reg1 char *cp;
Reg5 int gotSpace;
/*
* first we try to stick in extra newlines to do wordwrap nicely.
*/
for (gotSpace = 0, cp = str, i = curWin->_curx; *cp; cp++) {
switch (*cp) {
case '\t':
i = (i + 8) & ~7;
gotSpace = 1;
break;
case ' ':
gotSpace = 1;
i++;
break;
case '\n':
i = 0;
break;
default:
i++;
}
if (i >= curWin->_maxx) {
if (gotSpace) {
while (!isspace (*cp))
cp--;
*cp = '\n';
gotSpace = i = 0;
} else {
/*
* there's nothing to do if there's no space
* in the preceeding line. We just break it
* unnaturally and hope for the best
*/
i = 0;
gotSpace = 0;
}
}
}
for (i = curWin->_curx; *str; str++) {
if (*str == '\n') {
i = 0;
if (newline(1) == ERR && nextpage())
return 1;
} else if ( ! isspace (*str) && ! isprint (*str)) {
wstandout (curWin);
waddch (curWin, (*str & 037) + '@');
wstandend (curWin);
i++;
} else {
waddch (curWin, *str);
i++;
}
/*
* if we've hit the end of the line without a newline,
* we have to do one anyway to keep the number of lines
* we've printed up to date. We do the same sort of processing
* as for an existing newline, including calling newline() and
* nextpage().
*/
if (i >= curWin->_maxx) {
i = 0;
if (newline(0) == ERR && nextpage()) {
return (1);
}
}
}
return 0;
}