home *** CD-ROM | disk | FTP | other *** search
- /*
- *************
- * 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);
- }
-