home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- *
- * NAME: basewin.cpp
- *
- * DESCRIPTION:
- *
- * copyright (c) 1990 J. Alan Eldridge
- *
- * M O D I F I C A T I O N H I S T O R Y
- *
- * when who what
- * -------------------------------------------------------------------
- * 11/??/90 J. Alan Eldridge created
- *
- *********************************************************************/
-
- #include "w.h"
-
- // local defines
-
- #define PRINTF_MAX 512 // size of string buffer for printf()
-
- // Unix Curses clears to end of line on newline ...
- // set NL_DOES_CLREOL to 0 if you do not want this behavior
- #define NL_DOES_CLREOL 1
-
- // destructor
-
- basewin::~basewin()
- {
- if (state == OK) {
- delete xdirty;
- state = ERR;
- }
- }
-
- // constructor
-
- basewin::basewin(
- int yul, int xul,
- int ylr, int xlr):
- vidbuf(yul, xul, ylr, xlr),
- viewport(0, 0, ylr - yul, xlr - xul)
- {
- if (state == OK) {
- if (!(xdirty = new int [ ylr - yul ][ 2 ]))
- state = ERR;
- }
- if (state == OK) {
- zflags();
- unmark();
- att = vid_defaultatt;
- clear();
- }
- }
-
- // clear current port
-
- basewin &
- basewin::clear(uchar ch)
- {
- setpos(0,0);
- vidbuf::clear(yUL,xUL,yLR,xLR,ch,att);
- touch();
- return *this;
- }
-
- // clear to end of line
-
- basewin &
- basewin::clreol(uchar ch)
- {
- if (xCur <= xLR) {
- mark(yCur);
- markline(yCur, xCur);
- markline(yCur, xLR);
- clrline(yCur, xCur, xLR, ch, att);
- }
- return *this;
- }
-
- // newline (implies carriage return)
-
- basewin &
- basewin::NL()
- {
- #if NL_DOES_CLREOL
- clreol();
- #endif
- CR();
- if (yCur < yLR) {
- yCur++;
- } else if (fScroll) {
- scroll();
- }
- return *this;
- }
-
- // carriage return
-
- basewin &
- basewin::CR()
- {
- xCur = xUL;
- return *this;
- }
-
- // non-destructive backspace
-
- basewin &
- basewin::BS()
- {
- if (xCur > xUL) {
- xCur--;
- } else if (yCur > yUL) {
- yCur--;
- xCur = xLR;
- }
- return *this;
- }
-
- // put a single character
-
- basewin &
- basewin::put(uchar ch)
- {
- if (ch == '\r')
- return CR();
- else if (ch == '\n')
- return NL();
- else if (ch == '\b')
- return BS();
- else if (xCur <= xLR) {
- mark(yCur);
- markline(yCur, xCur);
- putchr(yCur, xCur++, ch, att);
- if (xCur > xLR && fWrap) {
- NL();
- }
- }
- return *this;
- }
-
- // put a string
-
- basewin &
- basewin::put(uchar *s)
- {
- while (*s) {
- put(*s++);
- }
- return *this;
- }
-
- basewin &
- basewin::center(int line, uchar *s)
- {
- int skip = (cols - strlen(s))/2;
-
- if (skip < 0)
- skip = 0;
- setpos(line, 0);
- clreol();
- setpos(yCur, skip);
- return put(s);
- }
-
- // printf to current position
-
- basewin &
- basewin::printf(uchar *fmt, ...)
- {
- uchar buf[PRINTF_MAX];
- va_list ap;
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
- return put(buf);
- }
-
- // mark row as dirty (does NOT set line dirty markers)
-
- void
- basewin::mark(int row)
- {
- if (row < ydirty[0]) ydirty[0] = row;
- if (row > ydirty[1]) ydirty[1] = row;
- }
-
- // mark position on line as dirty
-
- void
- basewin::markline(int row, int col)
- {
- if (col < xdirty[row][0]) xdirty[row][0] = col;
- if (col > xdirty[row][1]) xdirty[row][1] = col;
- }
-
- // unmark everything (nothing to redraw)
-
- void
- basewin::unmark()
- {
- ydirty[0] = INT_MAX; ydirty[1] = 0;
- for (int y = 0; y < rows; y++) {
- xdirty[y][0] = INT_MAX; xdirty[y][1] = 0;
- }
- }
-
- // mark a region as dirty
-
- void
- basewin::touch(
- int yul,
- int xul,
- int ylr,
- int xlr)
- {
- mark(yul);
- mark(ylr);
- for (int y = yul; y <= ylr; y++) {
- markline(y, xul);
- markline(y, xlr);
- }
- }
-
- // update to display screen
-
- void
- basewin::refresh(int vflag)
- {
- if (state != OK)
- return;
-
- for (int y = ydirty[0], ylim = ydirty[1]; y <= ylim; y++) {
- int x = xdirty[y][0], xlim = xdirty[y][1];
-
- if (x <= xlim)
- display(y, x, xlim - x + 1, vflag);
- }
- unmark();
- setcursor(vflag);
- }
-
- // scroll a section of a window
-
- void
- basewin::scroll(
- int yul,
- int xul,
- int ylr,
- int xlr,
- int nLines)
- {
- if (nLines) {
- int absLines = abs(nLines);
-
- // 3 choices here: clear it, scroll up, or scroll down
-
- if (absLines > ylr - yul) {
- vidbuf::clear(yul, xul, ylr, xlr, ' ', att);
- } else {
- int rows = ylr - yul + 1 - absLines;
- int bytes = (xlr - xul + 1) * sizeof(vidchr);
-
- if (nLines > 0) {
- // scroll up
- for (int r = yul; rows-- > 0; r++) {
- memcpy(vidptr(r, xul), vidptr(r + nLines, xul), bytes);
- }
- vidbuf::clear(r, xul, ylr, xlr, ' ', att);
- } else {
- // scroll down
- for (int r = ylr; rows-- > 0; r--) {
- memcpy(vidptr(r, xul), vidptr(r + nLines, xul), bytes);
- }
- vidbuf::clear(yul, xul, r, xlr, ' ', att);
- }
- touch(yul, xul, ylr, xlr);
- }
- }
- }
-
-