|
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 c
Length: 11058 (0x2b32) Types: TextFile Names: »curses.c«
└─⟦87ddcff64⟧ Bits:30001253 CPHDIST85 Tape, 1985 Autumn Conference Copenhagen └─⟦this⟧ »cph85dist/wm/curses.c«
/* ************* * 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); }