|
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; }