home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume16 / pcomm2 / part03 / curses.c < prev    next >
C/C++ Source or Header  |  1988-09-14  |  8KB  |  483 lines

  1. /*
  2.  * Miscellaneous curses(3) routines.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <curses.h>
  7. #include <signal.h>
  8. #include "config.h"
  9. #ifdef OLDCURSES
  10. #include <fcntl.h>
  11. #else /* OLDCURSES */
  12. #include <term.h>
  13. #endif /* OLDCURSES */
  14. #include "misc.h"
  15.  
  16. /*
  17.  * Get a string from a window.  Similar to wgetstr(), except we limit
  18.  * the length, return a NULL (not pointer to NULL) on <ESC> key, beep
  19.  * at any character in "disallow" string, and beep at any character not
  20.  * in "allow". (It doesn't make sense to use both "allow" and "disallow"
  21.  * at the same time)
  22.  */
  23.  
  24. char *
  25. get_str(win, num, allow, disallow)
  26. WINDOW *win;
  27. int num;
  28. char *allow, *disallow;
  29. {
  30.     int count, x, y;
  31.     char ans, *strchr();
  32.     static char buf[80];
  33.  
  34.     count = 0;
  35.     while ((ans = wgetch(win)) != '\r') {
  36.                     /* do our own backspace */
  37.         if (ans == BS) {
  38.             if (!count) {
  39.                 beep();
  40.                 continue;
  41.             }
  42.             count--;
  43.             buf[count] = NULL;
  44.             getyx(win, y, x);
  45.             x--;
  46.             wmove(win, y, x);
  47.             waddch(win, (chtype) ' ');
  48.             wmove(win, y, x);
  49.             wrefresh(win);
  50.             continue;
  51.         }
  52.                     /* an <ESC> anywhere in the string */
  53.         if (ans == ESC)
  54.             return(NULL);
  55.  
  56.                     /* illegal character? */
  57.         if (*disallow != NULL && strchr(disallow, ans)) {
  58.             beep();
  59.             continue;
  60.         }
  61.         if (*allow != NULL && !strchr(allow, ans)) {
  62.             beep();
  63.             continue;
  64.         }
  65.                     /* exceeded the max? */
  66.         if (count == num) {
  67.             beep();
  68.             continue;
  69.         }
  70.  
  71.         buf[count] = ans;
  72.         waddch(win, (chtype) ans);
  73.         wrefresh(win);
  74.         count++;
  75.     }
  76.     buf[count] = NULL;
  77.     return(buf);
  78. }
  79.  
  80. /*
  81.  * Get a number from a window.  We limit the length and return a -1
  82.  * on <ESC> key.
  83.  */
  84.  
  85. int
  86. get_num(win, num)
  87. WINDOW *win;
  88. int num;
  89. {
  90.     int count, x, y, number;
  91.     char ans, buf[80];
  92.  
  93.     count = 0;
  94.     while ((ans = wgetch(win)) != '\r') {
  95.                     /* do our own backspace */
  96.         if (ans == BS) {
  97.             if (!count) {
  98.                 beep();
  99.                 continue;
  100.             }
  101.             count--;
  102.             buf[count] = NULL;
  103.             getyx(win, y, x);
  104.             x--;
  105.             wmove(win, y, x);
  106.             waddch(win, (chtype) ' ');
  107.             wmove(win, y, x);
  108.             wrefresh(win);
  109.             continue;
  110.         }
  111.                     /* an <ESC> anywhere in the string */
  112.         if (ans == ESC)
  113.             return(-1);
  114.                     /* only digits are allowed */
  115.         if (ans < '0' || ans > '9') {
  116.             beep();
  117.             continue;
  118.         }
  119.                     /* exceeded the max? */
  120.         if (count == num) {
  121.             beep();
  122.             continue;
  123.         }
  124.  
  125.         buf[count] = ans;
  126.         waddch(win, (chtype) ans);
  127.         wrefresh(win);
  128.         count++;
  129.     }
  130.     buf[count] = NULL;
  131.     number = atoi(buf);
  132.     return(number);
  133. }
  134.  
  135. /*
  136.  * Change video attributes while printing a string.  The use of the
  137.  * pre-processor definition NOPROMOTE (located in config.h) means that
  138.  * strings will be printed without any special video attribute if the
  139.  * requested capability doesn't exist.
  140.  */
  141.  
  142. wattrstr(win, attr, str)
  143. WINDOW *win;
  144. chtype attr;
  145. char *str;
  146. {
  147.     int do_it;
  148.                     /* if nothing, do nothing */
  149.     if (str == NULL || *str == NULL)
  150.         return(0);
  151.  
  152. #ifdef OLDCURSES
  153.     if (attr)
  154.         wstandout(win);
  155.     waddstr(win, str);
  156.     if (attr)
  157.         wstandend(win);
  158. #else /* OLDCURSES */
  159. #ifdef NOPROMOTE
  160.                     /* does the capability exist? */
  161.     do_it = 0;
  162.     if ((attr & A_STANDOUT) && enter_standout_mode)
  163.         do_it++;
  164.     if ((attr & A_UNDERLINE) && enter_underline_mode)
  165.         do_it++;
  166.     if ((attr & A_REVERSE) && (enter_reverse_mode || enter_standout_mode))
  167.         do_it++;
  168.     if ((attr & A_BLINK) && enter_blink_mode)
  169.         do_it++;
  170.     if ((attr & A_BOLD) && enter_bold_mode)
  171.         do_it++;
  172.     if ((attr & A_DIM) && enter_dim_mode)
  173.         do_it++;
  174. #else /* NOPROMOTE */
  175.     do_it = 1;
  176. #endif /* NOPROMOTE */
  177.  
  178.     if (do_it)
  179.         wattron(win, attr);
  180.                     /* print the string */
  181.     waddstr(win, str);
  182.     if (do_it)
  183.         wattroff(win, attr);
  184. #endif /* OLDCURSES */
  185.     return(0);
  186. }
  187.  
  188. /*
  189.  * Change video attributes while printing a character.
  190.  */
  191.  
  192. wattrch(win, attr, c)
  193. WINDOW *win;
  194. chtype attr;
  195. char c;
  196. {
  197.     int do_it;
  198.  
  199.     if (c == NULL)
  200.         return(0);
  201. #ifdef OLDCURSES
  202.     if (attr)
  203.         wstandout(win);
  204.     waddch(win, (chtype) c);
  205.     if (attr)
  206.         wstandend(win);
  207. #else /* OLDCURSES */
  208. #ifdef NOPROMOTE
  209.                     /* does the capability exist? */
  210.     do_it = 0;
  211.     if ((attr & A_STANDOUT) && enter_standout_mode)
  212.         do_it++;
  213.     if ((attr & A_UNDERLINE) && enter_underline_mode)
  214.         do_it++;
  215.     if ((attr & A_REVERSE) && (enter_reverse_mode || enter_standout_mode))
  216.         do_it++;
  217.     if ((attr & A_BLINK) && enter_blink_mode)
  218.         do_it++;
  219.     if ((attr & A_BOLD) && enter_bold_mode)
  220.         do_it++;
  221.     if ((attr & A_DIM) && enter_dim_mode)
  222.         do_it++;
  223. #else /* NOPROMOTE */
  224.     do_it = 1;
  225. #endif /* NOPROMOTE */
  226.  
  227.     if (do_it)
  228.         wattron(win, attr);
  229.                     /* print the character */
  230.     waddch(win, (chtype) c);
  231.     if (do_it)
  232.         wattroff(win, attr);
  233. #endif /* OLDCURSES */
  234.     return(0);
  235. }
  236.  
  237.  
  238. /*
  239.  * Change video attributes while printing a number.
  240.  */
  241.  
  242. wattrnum(win, attr, num)
  243. WINDOW *win;
  244. chtype attr;
  245. int num;
  246. {
  247.     int do_it;
  248.     char buf[20];
  249.  
  250.     sprintf(buf, "%d", num);
  251.  
  252. #ifdef OLDCURSES
  253.     if (attr)
  254.         wstandout(win);
  255.     waddstr(win, buf);
  256.     if (attr)
  257.         wstandend(win);
  258. #else /* OLDCURSES */
  259. #ifdef NOPROMOTE
  260.                     /* does the capability exist? */
  261.     do_it = 0;
  262.     if ((attr & A_STANDOUT) && enter_standout_mode)
  263.         do_it++;
  264.     if ((attr & A_UNDERLINE) && enter_underline_mode)
  265.         do_it++;
  266.     if ((attr & A_REVERSE) && (enter_reverse_mode || enter_standout_mode))
  267.         do_it++;
  268.     if ((attr & A_BLINK) && enter_blink_mode)
  269.         do_it++;
  270.     if ((attr & A_BOLD) && enter_bold_mode)
  271.         do_it++;
  272.     if ((attr & A_DIM) && enter_dim_mode)
  273.         do_it++;
  274. #else /* NOPROMOTE */
  275.     do_it = 1;
  276. #endif /* NOPROMOTE */
  277.  
  278.     if (do_it)
  279.         wattron(win, attr);
  280.                     /* print the character */
  281.     waddstr(win, buf);
  282.     if (do_it)
  283.         wattroff(win, attr);
  284. #endif /* OLDCURSES */
  285.     return(0);
  286. }
  287.  
  288. /*
  289.  * Prompt for a Yes or No answer.  Echo the single key input as words.
  290.  * Handle the funny cursor movement problems with magic cookie terminals.
  291.  * Returns a 1 on yes.
  292.  */
  293.  
  294. int
  295. yes_prompt(win, y, x, attr, str)
  296. WINDOW *win;
  297. int y, x;
  298. chtype attr;
  299. char *str;
  300. {
  301.     int save, ret_code;
  302.     char new_str[80], *strcpy(), *strcat();
  303.                     /* build and display the prompt */
  304.     strcpy(new_str, str);
  305.     strcat(new_str, "? (y/n):");
  306.     mvwattrstr(win, y, x, attr, new_str);
  307.     wmove(win, y, strlen(new_str)+x+2);
  308.     wrefresh(win);
  309.  
  310.     ret_code = -1;
  311.     while (ret_code == -1) {
  312.         save = wgetch(win);
  313.         switch (save) {
  314.             case 'y':
  315.             case 'Y':
  316.                 waddstr(win, "Yes");
  317.                 ret_code = 1;
  318.                 break;
  319.             case 'n':
  320.             case 'N':
  321.             case ESC:
  322.                 waddstr(win, "No");
  323.                 ret_code = 0;
  324.                 break;
  325.             default:
  326.                 beep();
  327.  
  328.         }
  329.     }
  330.     wrefresh(win);
  331.     return(ret_code);
  332. }
  333.  
  334. /*
  335.  * Handy routine for clear-to-end-of-line.  Fixes up the box if requested.
  336.  */
  337.  
  338. int
  339. clear_line(win, y, x, re_box)
  340. WINDOW *win;
  341. int y, x, re_box;
  342. {
  343.     if (wmove(win, y, x) == ERR)
  344.         return(ERR);
  345.  
  346.     wclrtoeol(win);
  347.  
  348.     if (re_box) {
  349.         mvwaddch(win, y, win->_maxx-1, (chtype) ACS_VLINE);
  350.         wmove(win, y, x);
  351.     }
  352.     return(0);
  353. }
  354.  
  355. /*
  356.  * Routine to make a horizontal line.  Does NOT do a wrefresh().
  357.  */
  358.  
  359. int
  360. horizontal(win, x, y, len)
  361. WINDOW *win;
  362. int x, y, len;
  363. {
  364.     wmove(win, x, y);
  365.  
  366.     while (len--)
  367.         waddch(win, ACS_HLINE);
  368.  
  369.     return(0);
  370. }
  371.  
  372. /*
  373.  * Wait for a key or time out.  Returns a -1 on timeout.  This is similar
  374.  * to the half-delay mode in the newer versions of curses(3).
  375.  */
  376.  
  377. static int wk_flag;
  378.  
  379. int
  380. wait_key(win, sec)
  381. WINDOW *win;
  382. unsigned int sec;
  383. {
  384.     int key, wk_force();
  385.     unsigned int alarm();
  386. #ifdef WGETCH_BROKE
  387.     char c;
  388. #endif /* WGETCH_BROKE */
  389.  
  390.     signal(SIGALRM, wk_force);
  391.     wk_flag = 0;
  392.  
  393.     alarm(sec);
  394. #ifdef WGETCH_BROKE
  395.     read(0, &c, 1);
  396.     key = c;
  397. #else /* WGETCH_BROKE */
  398.     key = wgetch(win);
  399. #endif /* WGETCH_BROKE */
  400.     if (wk_flag)
  401.         return(-1);
  402.     alarm(0);
  403.     return(key);
  404. }
  405. /*ARGSUSED*/
  406. static int
  407. wk_force(dummy)
  408. int dummy;
  409. {
  410.     wk_flag = 1;
  411. }
  412.  
  413. /*
  414.  * Here are some routines that are probably missing from the older
  415.  * flavors of curses(3).
  416.  */
  417.  
  418. #ifdef OLDCURSES
  419. /*
  420.  * Make the terminal bell go off
  421.  */
  422.  
  423. int
  424. beep()
  425. {
  426.     fputc(BEL, stderr);
  427.     return(0);
  428. }
  429.  
  430. /*
  431.  * Fix the stdin so that a read is satisfied immediately.  When read()
  432.  * is called it returns the character in the queue, or an error if no
  433.  * key was pressed.  The window argument is not used!
  434.  */
  435.  
  436. int
  437. nodelay(win, flag)
  438. WINDOW *win;
  439. int flag;
  440. {
  441.     if (flag)
  442.         fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) | O_NDELAY);
  443.     else
  444.         fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~O_NDELAY);
  445.     return(0);
  446. }
  447.  
  448. /*
  449.  * Take the terminal out of the "curses mode"
  450.  */
  451.  
  452. int
  453. resetterm()
  454. {
  455.     resetty();
  456.     return(0);
  457. }
  458.  
  459. /*
  460.  * Put the terminal back into the "curses mode"
  461.  */
  462.  
  463. int
  464. myputchar(c)
  465. char c;
  466. {
  467.     return(putchar(c));
  468. }
  469. int
  470. fixterm()
  471. {
  472.     int myputchar();
  473.     extern char *TI, *VS;
  474.  
  475.     tputs(TI, 1, myputchar);
  476.     tputs(VS, 1, myputchar);
  477.     nonl();
  478.     crmode();
  479.     noecho();
  480.     return(0);
  481. }
  482. #endif /* OLDCURSES */
  483.