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