home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------
- *
- * alert.c
- *
- * copyright (c) 1987,88,89,90 J. Alan Eldridge
- *
- * DESCRIPTION:
- *
- * a Mac-like alert box for Curses!
- *
- * BUGS:
- *
- * maximum length of text supplied by caller is A_UROWS * A_UCOLS
- * no checking is done for overflow in alertf
- * but it has A_USLOP extra bytes just in case
- * alerts truncates the text to fit
- *
- * maximum length of a word is A_UCOLS
- * alerts doesn't check for this error
- * but it could address outside the buffer
- * and mess up the stack
- *
- *
- *----------------------------------------------------------------------
- */
-
- #include <stdarg.h>
-
- #include "curses.h"
-
- /* args to newwin */
-
- #define A_ROWS 12 /* # rows in window */
- #define A_COLS 60 /* # cols in window */
- #define A_ORGY 7 /* window has origin at ... */
- #define A_ORGX 10 /* ... row A_ORGY, col A_ORGX */
-
- /* user text area */
-
- #define A_UROWS 5 /* # rows in message area */
- #define A_UCOLS 50 /* # cols in message area */
- #define A_UORGY 2 /* message are has origin at ... */
- #define A_UORGX 5 /* ... row A_UORGY, col A_UORGX */
- #define A_USLOP 50 /* extra room in buffer so we don't overflow */
-
- /* size of local buffer for alertf() */
-
- #define A_UBUFSIZE (A_UROWS * A_UCOLS + 1 + A_USLOP)
-
- static int attrib = VID_DEFBRIGHT; /* attribute to use for alert window */
-
- int
- alertf(
- int die,
- char *title,
- char *prompt,
- int *keys,
- int sound,
- char *fmt,
- ...)
- {
- va_list ap;
- char buf[A_UBUFSIZE];
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
-
- return alerts(die, title, prompt, keys, sound, buf);
- }
-
- static char *
- getword(buf, lenp, nxtp)
- char *buf, **nxtp;
- int *lenp;
- {
- char *cp;
-
- /*
- skip leading whitespace
- except for newlines
- */
-
- while (*buf && isspace(*buf))
- if (*buf == '\n') {
- *lenp = 0;
- *nxtp = buf + 1;
- return buf;
- } else
- buf++;
-
- /*
- collect the word,
- if there is one,
- and set the length
- */
-
- cp = buf;
- while (*cp && !isspace(*cp))
- cp++;
- *lenp = cp - buf;
-
- /*
- skip trailing whitespace,
- stopping for a newline
- */
-
- while (*cp && isspace(*cp))
- if (*cp == '\n')
- break;
- else
- cp++;
-
- *nxtp = cp;
- return *lenp ? buf : 0;
- }
-
- void
- alertattr(att)
- int att;
- {
- if (iscolor())
- attrib = att != -1 ? att : __DEFBRIGHT;
- }
-
- int
- alerts(die, title, prompt, keys, sound, s)
- int die;
- char *title,
- *prompt;
- int *keys;
- int sound;
- char *s;
- {
- static int nl[] = { K_NL, K_ILLEGAL };
- static int nl_esc[] = { K_NL, K_ESC, K_ILLEGAL };
-
- int uy = 0, ux = 0, wlen, key;
- char ubuf[A_UROWS][A_UCOLS + 1], *word;
- WINDOW *awin, *asav, *newwin(), *savescr();
-
- /* allocate space */
-
- if (!(awin = newwin(A_ROWS, A_COLS, A_ORGY, A_ORGX)))
- return ERR;
- if (!(asav = savescr(A_ROWS, A_COLS, A_ORGY, A_ORGX))) {
- delwin(awin);
- return ERR;
- }
-
- /* set up the window */
-
- setattr(awin, attrib);
- werase(awin);
-
- if (sound < 0)
- wblinkon(awin);
- box(awin, 1, 1);
- if (title) {
- mvwaddch(awin, 0, 2, ' ');
- waddstr(awin, title);
- waddch(awin, ' ');
- }
- wblinkoff(awin);
-
- if (die)
- prompt = "Sorry. Press any key to end program.";
- else {
- if (!prompt) {
- prompt = "Press ENTER to continue ...";
- keys = nl;
- } else if (!keys)
- keys = nl_esc;
- }
-
- /*
- set up the user text ...
-
- this is a word wrap routine
-
- it follows the same rules as the
- word wrap routine in the Mac Toolbox
-
- a "word" is any sequence of characters
- that aren't whitespace. a newline
- causes an explicit wrap.
- */
-
- while (word = getword(s, &wlen, &s))
- if (!wlen) {
- /* got a newline */
- if (uy >= A_UROWS - 1)
- break; /* truncate */
- ubuf[uy][ux] = 0;
- ux = 0;
- uy++;
- } else {
- /* got a word */
- /* does it fit? */
- if (ux + wlen + (ux != 0) >= A_UCOLS) {
- /* nope */
- if (uy >= A_UROWS - 1)
- break; /* truncate */
- ubuf[uy][ux] = 0;
- ux = 0;
- uy++;
- }
- /* copy it into ubuf */
- if (ux != 0)
- ubuf[uy][ux++] = ' ';
- while (wlen-- > 0)
- ubuf[uy][ux++] = *word++;
- }
-
- ubuf[uy++][ux] = 0;
- while (uy < A_UROWS)
- ubuf[uy++][0] = 0;
-
- /* put user text on window */
-
- for (uy = 0; uy < A_UROWS; uy++)
- mvwaddstr(awin, uy + A_UORGY, A_UORGX, ubuf[uy]);
-
- mvwaddstr(awin, A_UORGY + A_UROWS + 2, A_UORGX, prompt);
-
- /* pop up & get a key */
-
- wrefresh(awin);
- while (sound-- > 0)
- beep();
-
- if (die) {
- wgetch(awin);
- endwin();
- exit(die);
- }
-
-
- while (kb_matchkey(keys, key = wgetch(awin)) == -1)
- ;
-
- restscr(asav);
- delwin(awin);
- delwin(asav);
- return key;
- }
-
- /*
- set up video attributes
- */
-
- void
- init_alerts(void)
- {
- attrib = __DEFBRIGHT;
- }
-