DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T c

⟦0ec32b68a⟧ TextFile

    Length: 11058 (0x2b32)
    Types: TextFile
    Names: »curses.c«

Derivation

└─⟦87ddcff64⟧ Bits:30001253 CPHDIST85 Tape, 1985 Autumn Conference Copenhagen
    └─ ⟦this⟧ »cph85dist/wm/curses.c« 

TextFile

/*
 *************
 * DISTRIBUTION NOTICE  July 30 1985
 * A Revised Edition of WM, by Matt Lennon and Tom Truscott,
 *		Research Triangle Institute, (919) 541-7005.
 * Based on the original by Robert Jacob (decvax!nrl-css!jacob),
 *		Naval Research Laboratory, (202) 767-3365.
 * No claims or warranties of any sort are made for this distribution.
 * General permission is granted to copy, but not for profit,
 * any of this distribution, provided that this notice
 * is always included in the copies.
 *************
 */
/*
 * curses.c  R. Jacob
 */

#include "wm.h"

static WINDOW *mw=NULL;		/* message window */
static WINDOW *cmw=NULL;	/* blank message window */
time_t msgbirth = 0;


/*
 * Set up win structure and associated junk for new window w.
 * Returns 0 if sucessful, else -1.
 */
NewWindow(w, lines, cols, begline, begcol)

register int w;
int lines, cols, begline, begcol;
{
    register WINDOW *wp, *owp;


    if ((wp=newwin(lines,cols,begline,begcol)) == NULL) {
	showmsg("\007Cannot %sconstruct window #%d!.",
	    ((win[w].flags&INUSE)? "re": ""), w);
	FreeWindow(w);
	return(-1);
    }
    leaveok(wp, TRUE);

    /* If the window is already in use, copy old window to new one
     * anchored at bottom left of the windows.
     * We move the bottom left of both windows to the bottom left
     * of the screen, overwrite, then move the windows back.
     * (Actually, we do not bother to move the old window back.)
     */
    if (win[w].flags&INUSE) {
	owp = win[w].wptr;
	mvwin(owp, LINES-wlines(owp), 0);
	mvwin(wp, LINES-wlines(wp), 0);
	overwrite(owp, wp);
	mvwin(wp, begline, begcol);
	wmove(wp, wcury(owp) + (wlines(wp)-wlines(owp)), wcurx(owp));
	FreeWindow(w);
    }

    win[w].wptr = wp;

    if (MakeBorders(w) != 0)
    {
	showmsg("\007Cannot construct borders for window #%d!.", w);
	FreeWindow(w);
	return(-1);
    }

    win[w].flags |= INUSE;
    if (has_scroll_window
     || (cols == COLS
      && (has_scroll_region || has_insdel_line || lines == LINES-1)))
	win[w].flags |= FAST;

    return(0);
}

/*
 * Deallocate win structure and associated junk.
 */
FreeWindow(w)

register int w;
{
    win[w].flags = 0;

    if (win[w].wptr)	 {delwin(win[w].wptr);     win[w].wptr = 0;}
    if (win[w].boxbot)	 {delwin(win[w].boxbot);   win[w].boxbot = 0;}
    if (win[w].boxtop)	 {delwin(win[w].boxtop);   win[w].boxtop = 0;}
    if (win[w].boxright) {delwin(win[w].boxright); win[w].boxright = 0;}
    if (win[w].boxleft)	 {delwin(win[w].boxleft);  win[w].boxleft = 0;}
}

#ifdef notdef
/*
 * Redraw window w.
 */
RedrawWindow(w)

register int w;
{
    register WINDOW *wp;

    if (!iswindow(w))
	return;
    if (wp=win[w].wptr)     { touchwin(wp); wrefresh(wp); }
    if (wp=win[w].boxbot)   { touchwin(wp); wrefresh(wp); }
    if (wp=win[w].boxtop)   { touchwin(wp); wrefresh(wp); }
    if (wp=win[w].boxright) { touchwin(wp); wrefresh(wp); }
    if (wp=win[w].boxleft)  { touchwin(wp); wrefresh(wp); }
}
#endif

/*
 * Redraw the entire screen.
 * Uses Curses' standard screen, stdscr.
 */
RedrawScreen()
{
    register int w, base;
    register WINDOW *wp;

    /* speed hack: start with the topmost full-screen window.
     * (Smarter hacks come to mind, but this one is easy.)
     */
    base = botw;
    for (w=base; w>=0; w=win[w].next)
	if ((wp = win[w].wptr) && wcols(wp) == COLS && wlines(wp) >= LINES-1)
	    base = w;

    werase(stdscr);

     /* Write contents of all windows into stdscr, then refresh.
      */
    for (w=base; w>=0; w=win[w].next)
    {
	if (wp=win[w].wptr)     overwrite(wp, stdscr);
	if (wp=win[w].boxtop)   overwrite(wp, stdscr);
	if (wp=win[w].boxbot)   overwrite(wp, stdscr);
	if (wp=win[w].boxright) overwrite(wp, stdscr);
	if (wp=win[w].boxleft)  overwrite(wp, stdscr);
    }

    if (msgbirth)
	overwrite(mw, stdscr);
    touchwin(stdscr);
    wrefresh(stdscr);
    RestoreCursor();
}

/*
 * Identify windows.
 * Draw each window in turn, from bottom to top.
 * Uses Curses' standard screen, stdscr.
 */
IdentWindows()
{
    register int w;	/* window index */
    register WINDOW *wp;
    register int canceled=FALSE; /* TRUE if user cancels this command */
    register int c;


     /* Erase the screen (and stdscr).
      */
    ClearScreen();

     /* Write contents of each window into stdscr, then refresh.
      */
    for (w=botw; w>=0; w=win[w].next)
    {
	if (wp=win[w].wptr)     overwrite(wp, stdscr);
	if (wp=win[w].boxtop)   overwrite(wp, stdscr);
	if (wp=win[w].boxbot)   overwrite(wp, stdscr);
	if (wp=win[w].boxright) overwrite(wp, stdscr);
	if (wp=win[w].boxleft)  overwrite(wp, stdscr);

	if (canceled)
	    continue;

#ifdef BUGGYTERMINFO
	/* buggyterminfo seems to require this */
	touchwin(stdscr);
#endif
	wrefresh(stdscr);

	if (w != topw)
	{
	    showmsg("Window #%d.  Hit any key to see next window.", w);
	    c = tty_getch();
	    if (c == CANCEL1  ||  c == CANCEL2)
	    {
		showmsg("Canceled.");
		canceled = TRUE;
	    }
	}

	else
	{
	    showmsg("Window #%d (top window).  Hit any key to continue.", w);
	    (void) tty_getch();
	}
    }

    if (canceled)
	wrefresh(stdscr);
    RestoreMsg();
    RestoreCursor();
}

/*
 * Show message s on bottom of screen.
 */
/*VARARGS1*/
showmsg(s, arg1, arg2)

register char *s;
{
    char buf[256];

     /* Initialize message window first time 'round.
      */
    if (mw == NULL) {
	mw=newwin(1, 0, LINES-1, 0);
	cmw=newwin(1, 0, LINES-1, 0);
	if (!mw || !cmw) {
	    fprintf(stderr, "Cannot create message window!\n\r");
	    Shutdown(1);
	}
	leaveok(cmw, TRUE);
	werase(cmw);
	/* (leaveok for mw & cursor positioning for prompts needs thought) */
	wstandout(mw);
    }

#ifdef notdef
    /* pause to let user ponder a previous message */
    if (msgbirth && *s && (t = 2-abs(msgbirth - time((time_t *)0))) > 0)
	sleep((unsigned int)t);
#endif

    /* Format the message */
    (void) sprintf(buf, s, arg1, arg2);
    s = buf;
    s[wcols(mw)-1] = '\0';		/* make sure it fits */

    /* hack to honk but once */
    if (*s == '\007') {
	flash();
	s++;
    }
    werase(mw);
    waddstr(mw, s);
    touchwin(mw);
    wrefresh(mw);

    msgbirth = s[0]? time((time_t *)0): 0;
}

ZapMsgLine()
{
    if (msgbirth) {
	touchwin(cmw);
	wrefresh(cmw);
    }
}

RestoreMsg()
{
    if (msgbirth) {
	touchwin(mw);
	wrefresh(mw);
    }
}

/*
 * Restore cursor in top window.
 */
RestoreCursor()
{
    register WINDOW *wp;	/* pointer to top window */

    wp = win[topw].wptr;
    if (movecursor(wbegy(wp)+wcury(wp), wbegx(wp)+wcurx(wp)))
	(void) fflush(stdout);
}

/*
 * Clear the whole screen
 */
ClearScreen()
{
    wclear(stdscr);
    wrefresh(stdscr);
}

/*
 * Creates windows containing
 * a border to surround window w
 * and puts pointer to the new windows
 * into proper places in global win[].
 * Borders appear in standout mode if
 * terminal has that capability.
 * Returns 0 if sucessful, else -1.
 */
MakeBorders(w)

register int w;		/* make borders for this window */
{
    int left, right, top, bottom;	/* border flags */
    int begx, begy, cols, lines;	/* window dimensions */
    register WINDOW *wp;		/* window pointer */
    register int i;			/* index */


     /* Get window dimensions.
      */
    wp = win[w].wptr;
    begx =  wbegx(wp);
    begy =  wbegy(wp);
    cols =  wcols(wp);
    lines = wlines(wp);


     /* Determine which sides of the window need borders.
      */
    left   = (begx > 0);
    right  = (begx+cols < COLS);
    top    = (begy > 0);
    bottom = (begy+lines < LINES-1); /* bottom line for msgs */

    if (top)
	--begy, ++lines;
    if (bottom)
	lines++;
    

     /* Make left border using '>'.
      */
    if (left)
    {
	if ((win[w].boxleft = wp = newwin(lines,1,begy,begx-1))  == NULL)
	    return(-1);
	leaveok(wp, TRUE);
	wstandout(wp);
	for (i=0; i<lines; i++)
	    waddch(wp, '>');
    }
    

     /* Make right border using '<'.
      */
    if (right)
    {
	if ((win[w].boxright = wp = newwin(lines,1,begy,begx+cols))  == NULL)
	    return(-1);
	leaveok(wp, TRUE);
	wstandout(wp);
	for (i=0; i<lines; i++)
	    waddch(wp, '<');
    }


     /* Make top border using window number.
      */
    if (top)
    {
	if ((win[w].boxtop = wp = newwin(1,cols,begy,begx))  == NULL)
	    return(-1);
	leaveok(wp, TRUE);
	wstandout(wp);
	for (i=0; i<cols; i++)
	    waddch(wp, itoc(w));
    }


     /* Make bottom border using window number.
      */
    if (bottom)
    {
	if ((win[w].boxbot = wp = newwin(1,cols,begy+lines-1,begx))  == NULL)
	    return(-1);
	leaveok(wp, TRUE);
	wstandout(wp);
	for (i=0; i<cols; i++)
	    waddch(wp, itoc(w));
    }

    return(0);
}

/*
 * Dump.
 * Dump the contents of the current window to file 'wmdump'
 * in the current directory.
 * Returns 0 on sucessful completion, -1 otherwise.
 */
DumpWindow(w, dumpfile)

int w;		/* number of window we're to dump */
char *dumpfile;	/* file we're dumping to */
{
    register WINDOW *wp;	/* top window */
    register FILE *dfp;		/* dump file pointer */
    register int line, col;	/* current line, column of window */
    register int lastcol;	/* column of rightmost non-blank */
    int oldy, oldx;		/* saved cursor position */

    if ((dfp = fopen(dumpfile, "w"))  == NULL)
	return(-1);

    wp = win[w].wptr;
    getyx(wp, oldy, oldx);
    for (line = 0; line < wlines(wp); line++)
    {
	lastcol = wcols(wp);
	while (--lastcol >= 0)
	    if (toascii(mvwinch(wp, line, lastcol)) != ' ')
		break;
	for (col = 0; col <= lastcol; col++)
	    putc(toascii(mvwinch(wp, line, col)),  dfp);
	putc('\n', dfp);
    }
    (void) fclose(dfp);
    wmove(wp, oldy, oldx);
    return(0);
}

#define BUFLEN		80

/* Prompt user for a string.
 */
char *
WPrompt(prompt, dflt)

char *prompt;	/* prompt */
char *dflt;	/* default response */
{
    register int c;		/* character in string */
    static char buf[BUFLEN+1];	/* string buffer */
    register int i=0;		/* buffer index */
    int maxlen, x;		/* how long can string be? */

     /* Print prompt and default response
      * on bottom line of screen.
      */
    showmsg("%s? [%s] ", prompt, dflt);

     /* Determine length of longest string
      * that will fit in window.
      */
    x = wcurx(mw);
    maxlen = (BUFLEN < wcols(mw)-2-x  ?  BUFLEN  :  wcols(mw)-2-x);


     /* Read string. Process line kill & backspace chars.
      */
    while ((c = tty_getch()) != EOF && c != '\n' && c != '\r')
    {
	if (c==CANCEL1 || c==CANCEL2)	/* cancel */
	{
	    showmsg("Canceled.");
	    return(NULL);
	}
	if (c==erasechar() || c == KEY_BACKSPACE || c == KEY_LEFT)
	{
	    if (i > 0)
	    {
		i--;
		waddstr(mw, "\b \b");
	    }
	}
	else if (c == killchar())
	{
	    i = 0;
	    wmove(mw, 0, x);
	    wclrtoeol(mw);
	}
	else if (i > maxlen)		/* is string too long? */
	    flash();
	else if (isspace(c) || !isprint(c)) /* is character inappropriate? */
	    flash();
	else				/* regular char: add to string */
	{
	    waddch(mw, c);
	    buf[i++] = c;
	}

	wrefresh(mw);
    }


     /* If user didn't respond, just return default response.
      */
    if (i == 0)
	strcpy(buf, dflt);
    else
	buf[i] = '\0';


    return(buf);
}