This is curses.c in view mode; [Download] [Up]
/*
* Miscellaneous curses(3) routines.
*/
#define STR_WIDTH 256
#define NUM_WIDTH 16
#include <stdio.h>
#include <curses.h>
#include <signal.h>
#include "config.h"
#include "misc.h"
#ifdef BSD
#include <setjmp.h>
jmp_buf wk_buf;
#endif /* BSD */
#ifndef OLDCURSES
#include <term.h>
#else /* OLDCURSES */
#ifdef UNIXPC
#include <sgtty.h>
#endif /* UNIXPC */
#endif /* OLDCURSES */
/*
* Get a string from a window. Similar to wgetstr(), except we limit
* the length, return a NULL (not pointer to NULL) on <ESC> key, beep
* at any character in "disallow" string, and beep at any character not
* in "allow". (It doesn't make sense to use both "allow" and "disallow"
* at the same time). Returns a pointer to a static area.
*/
char *
get_str(win, num, allow, disallow)
WINDOW *win;
int num;
char *allow, *disallow;
{
int count, x, y;
char ans, *strchr();
static char buf[STR_WIDTH];
count = 0;
while ((ans = wgetch(win)) != '\r') {
/* do our own backspace */
if (ans == BS || ans == DEL) {
if (!count) {
beep();
continue;
}
count--;
buf[count] = '\0';
getyx(win, y, x);
x--;
wmove(win, y, x);
waddch(win, (chtype) ' ');
wmove(win, y, x);
wrefresh(win);
continue;
}
/* an <ESC> anywhere in the string */
if (ans == ESC)
return(NULL);
/* illegal character? */
if (*disallow != '\0' && strchr(disallow, ans)) {
beep();
continue;
}
if (*allow != '\0' && !strchr(allow, ans)) {
beep();
continue;
}
/* exceeded the max? */
if (count >= num || count >= STR_WIDTH) {
beep();
continue;
}
buf[count] = ans;
waddch(win, (chtype) ans);
wrefresh(win);
count++;
}
buf[count] = '\0';
return(buf);
}
/*
* Get a number from a window. We limit the length and return a -1
* on <ESC> key.
*/
int
get_num(win, num)
WINDOW *win;
int num;
{
int count, x, y, number;
char ans, buf[NUM_WIDTH];
count = 0;
while ((ans = wgetch(win)) != '\r') {
/* do our own backspace */
if (ans == BS || ans == DEL) {
if (!count) {
beep();
continue;
}
count--;
buf[count] = '\0';
getyx(win, y, x);
x--;
wmove(win, y, x);
waddch(win, (chtype) ' ');
wmove(win, y, x);
wrefresh(win);
continue;
}
/* an <ESC> anywhere in the string */
if (ans == ESC)
return(-1);
/* only digits are allowed */
if (ans < '0' || ans > '9') {
beep();
continue;
}
/* exceeded the max? */
if (count >= num || count >= NUM_WIDTH) {
beep();
continue;
}
buf[count] = ans;
waddch(win, (chtype) ans);
wrefresh(win);
count++;
}
buf[count] = '\0';
number = atoi(buf);
return(number);
}
/*
* Change video attributes while printing a string. The use of the
* pre-processor definition NOPROMOTE (located in config.h) means that
* strings will be printed without any special video attribute if the
* requested capability doesn't exist.
*/
wattrstr(win, attr, str)
WINDOW *win;
chtype attr;
char *str;
{
int do_it;
/* if nothing, do nothing */
if (str == NULL || *str == '\0')
return(0);
#ifdef OLDCURSES
if (attr)
wstandout(win);
waddstr(win, str);
if (attr)
wstandend(win);
#else /* OLDCURSES */
#ifdef NOPROMOTE
/* does the capability exist? */
do_it = 0;
if ((attr & A_STANDOUT) && enter_standout_mode)
do_it++;
if ((attr & A_UNDERLINE) && enter_underline_mode)
do_it++;
if ((attr & A_REVERSE) && (enter_reverse_mode || enter_standout_mode))
do_it++;
if ((attr & A_BLINK) && enter_blink_mode)
do_it++;
if ((attr & A_BOLD) && enter_bold_mode)
do_it++;
if ((attr & A_DIM) && enter_dim_mode)
do_it++;
#else /* NOPROMOTE */
do_it = 1;
#endif /* NOPROMOTE */
if (do_it)
wattron(win, attr);
/* print the string */
waddstr(win, str);
if (do_it)
wattroff(win, attr);
#endif /* OLDCURSES */
return(0);
}
/*
* Change video attributes while printing a character.
*/
wattrch(win, attr, c)
WINDOW *win;
chtype attr;
char c;
{
int do_it;
if (c == '\0')
return(0);
#ifdef OLDCURSES
if (attr)
wstandout(win);
waddch(win, (chtype) c);
if (attr)
wstandend(win);
#else /* OLDCURSES */
#ifdef NOPROMOTE
/* does the capability exist? */
do_it = 0;
if ((attr & A_STANDOUT) && enter_standout_mode)
do_it++;
if ((attr & A_UNDERLINE) && enter_underline_mode)
do_it++;
if ((attr & A_REVERSE) && (enter_reverse_mode || enter_standout_mode))
do_it++;
if ((attr & A_BLINK) && enter_blink_mode)
do_it++;
if ((attr & A_BOLD) && enter_bold_mode)
do_it++;
if ((attr & A_DIM) && enter_dim_mode)
do_it++;
#else /* NOPROMOTE */
do_it = 1;
#endif /* NOPROMOTE */
if (do_it)
wattron(win, attr);
/* print the character */
waddch(win, (chtype) c);
if (do_it)
wattroff(win, attr);
#endif /* OLDCURSES */
return(0);
}
/*
* Change video attributes while printing a number.
*/
wattrnum(win, attr, num)
WINDOW *win;
chtype attr;
int num;
{
int do_it;
char buf[40];
sprintf(buf, "%d", num);
#ifdef OLDCURSES
if (attr)
wstandout(win);
waddstr(win, buf);
if (attr)
wstandend(win);
#else /* OLDCURSES */
#ifdef NOPROMOTE
/* does the capability exist? */
do_it = 0;
if ((attr & A_STANDOUT) && enter_standout_mode)
do_it++;
if ((attr & A_UNDERLINE) && enter_underline_mode)
do_it++;
if ((attr & A_REVERSE) && (enter_reverse_mode || enter_standout_mode))
do_it++;
if ((attr & A_BLINK) && enter_blink_mode)
do_it++;
if ((attr & A_BOLD) && enter_bold_mode)
do_it++;
if ((attr & A_DIM) && enter_dim_mode)
do_it++;
#else /* NOPROMOTE */
do_it = 1;
#endif /* NOPROMOTE */
if (do_it)
wattron(win, attr);
/* print the character */
waddstr(win, buf);
if (do_it)
wattroff(win, attr);
#endif /* OLDCURSES */
return(0);
}
/*
* Prompt for a Yes or No answer. Echo the single key input as words.
* Handle the funny cursor movement problems with magic cookie terminals.
* Returns a 1 on yes.
*/
int
yes_prompt(win, y, x, attr, str)
WINDOW *win;
int y, x;
chtype attr;
char *str;
{
int ret_code;
char new_str[80], *strcpy(), *strcat();
/* sanity checking */
if (strlen(str) > 71)
*(str+71) = '\0';
/* build and display the prompt */
strcpy(new_str, str);
strcat(new_str, "? (y/n):");
mvwattrstr(win, y, x, attr, new_str);
wmove(win, y, strlen(new_str)+x+2);
wrefresh(win);
ret_code = -1;
while (ret_code == -1) {
switch (wgetch(win)) {
case 'y':
case 'Y':
waddstr(win, "Yes");
ret_code = 1;
break;
case 'n':
case 'N':
case ESC:
waddstr(win, "No");
ret_code = 0;
break;
default:
beep();
}
}
wrefresh(win);
return(ret_code);
}
/*
* Handy routine for clear-to-end-of-line. Fixes up the box if requested.
*/
int
clear_line(win, y, x, re_box)
WINDOW *win;
int y, x, re_box;
{
if (wmove(win, y, x) == ERR)
return(ERR);
wclrtoeol(win);
if (re_box) {
mvwaddch(win, y, win->_maxx-1, (chtype) ACS_VLINE);
wmove(win, y, x);
}
return(0);
}
/*
* Routine to make a horizontal line. Does NOT do a wrefresh().
*/
int
horizontal(win, x, y, len)
WINDOW *win;
int x, y, len;
{
wmove(win, x, y);
while (len--)
waddch(win, ACS_HLINE);
return(0);
}
/*
* Wait for a key or time out. Returns a -1 on timeout. This is similar
* to the half-delay mode in the newer versions of curses(3).
*/
static int wk_flag;
/* ARGSUSED */
int
wait_key(win, sec)
WINDOW *win;
unsigned int sec;
{
int key;
static int wk_force();
unsigned int alarm();
char c;
signal(SIGALRM, (SIG_TYPE(*) ()) wk_force);
wk_flag = 0;
alarm(sec);
#ifdef BSD
if (setjmp(wk_buf))
return(-1);
#endif /* BSD */
#ifdef WGETCH_BROKE
read(0, &c, 1);
key = c & 0x7f;
#else /* WGETCH_BROKE */
key = wgetch(win);
#endif /* WGETCH_BROKE */
if (wk_flag)
return(-1);
alarm(0);
return(key);
}
/* ARGSUSED */
static int
wk_force(dummy)
int dummy;
{
#ifdef BSD
longjmp(wk_buf, 1);
#else /* BSD */
signal(SIGALRM, (SIG_TYPE(*) ()) wk_force);
wk_flag = 1;
#endif /* BSD */
}
/*
* Here are some routines that are probably missing from the older
* flavors of curses(3).
*/
#ifdef OLDCURSES
/*
* Make the terminal bell go off
*/
int
beep()
{
fputc(BEL, stderr);
return(0);
}
/*
* Take the terminal out of the "curses mode". The t_mode structure was
* captured before we initialized the curses mode.
*/
int
resetterm()
{
extern char _putchar();
extern struct sgttyb t_mode;
ioctl(0, TIOCSETP, &t_mode);
tputs(TE, 1, _putchar);
tputs(VE, 1, _putchar);
return(0);
}
/*
* Put the terminal back into the "curses mode". The c_mode structure was
* captured after we initialized the curses mode.
*/
int
fixterm()
{
extern char _putchar();
extern struct sgttyb c_mode;
ioctl(0, TIOCSETP, &c_mode);
tputs(TI, 1, _putchar);
tputs(VS, 1, _putchar);
return(0);
}
#endif /* OLDCURSES */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.