home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / pcomm / part02 / curses.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-17  |  7.5 KB  |  440 lines

  1. /*
  2.  * Miscellaneous curses routines.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <curses.h>
  7. #include <signal.h>
  8. #include <setjmp.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 == 8) {
  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, ' ');
  48.             wmove(win, y, x);
  49.             wrefresh(win);
  50.             continue;
  51.         }
  52.                     /* an ESC anywhere in the string */
  53.         if (ans == 27)
  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, 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 == 8) {
  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, ' ');
  107.             wmove(win, y, x);
  108.             wrefresh(win);
  109.             continue;
  110.         }
  111.                     /* an ESC anywhere in the string */
  112.         if (ans == 27)
  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, 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 misc.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. int 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. int 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, 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, 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. int attr, num;
  245. {
  246.     int do_it;
  247.     char buf[20];
  248.  
  249.     sprintf(buf, "%d", num);
  250.  
  251. #ifdef OLDCURSES
  252.     if (attr)
  253.         wstandout(win);
  254.     waddstr(win, buf);
  255.     if (attr)
  256.         wstandend(win);
  257. #else /* OLDCURSES */
  258. #ifdef NOPROMOTE
  259.                     /* does the capability exist ? */
  260.     do_it = 0;
  261.     if ((attr & A_STANDOUT) && enter_standout_mode)
  262.         do_it++;
  263.     if ((attr & A_UNDERLINE) && enter_underline_mode)
  264.         do_it++;
  265.     if ((attr & A_REVERSE) && (enter_reverse_mode || enter_standout_mode))
  266.         do_it++;
  267.     if ((attr & A_BLINK) && enter_blink_mode)
  268.         do_it++;
  269.     if ((attr & A_BOLD) && enter_bold_mode)
  270.         do_it++;
  271.     if ((attr & A_DIM) && enter_dim_mode)
  272.         do_it++;
  273. #else /* NOPROMOTE */
  274.     do_it = 1;
  275. #endif /* NOPROMOTE */
  276.  
  277.     if (do_it)
  278.         wattron(win, attr);
  279.                     /* print the character */
  280.     waddstr(win, buf);
  281.     if (do_it)
  282.         wattroff(win, attr);
  283. #endif /* OLDCURSES */
  284.     return(0);
  285. }
  286.  
  287. /*
  288.  * Prompt for a Yes or No answer.  Echo the single key input as words.
  289.  * Handle the funny cursor movement problems with magic cookie terminals.
  290.  * Returns a 1 on yes.
  291.  */
  292.  
  293. int
  294. yes_prompt(win, y, x, attr, str)
  295. WINDOW *win;
  296. int y, x, attr;
  297. char *str;
  298. {
  299.     int save, ret_code;
  300.     char new_str[80], *strcpy(), *strcat();
  301.                     /* build and display the prompt */
  302.     strcpy(new_str, str);
  303.     strcat(new_str, "? (y/n):");
  304.     mvwattrstr(win, y, x, attr, new_str);
  305.     wmove(win, y, strlen(new_str)+x+2);
  306.     wrefresh(win);
  307.  
  308.     ret_code = 0;
  309.     save = wgetch(win);
  310.     if (save == 'y' || save == 'Y') {
  311.         waddstr(win, "Yes");
  312.         ret_code = 1;
  313.     }
  314.     else
  315.         waddstr(win, "No");
  316.  
  317.     wrefresh(win);
  318.     return(ret_code);
  319. }
  320.  
  321. /*
  322.  * Handy routine for clear-to-end-of-line.  Fixes up the box if requested.
  323.  */
  324.  
  325. int
  326. clear_line(win, y, x, re_box)
  327. WINDOW *win;
  328. int y, x, re_box;
  329. {
  330.     if (wmove(win, y, x) == ERR)
  331.         return(ERR);
  332.  
  333.     wclrtoeol(win);
  334.  
  335.     if (re_box) {
  336.         mvwaddch(win, y, win->_maxx-1, '|');
  337.         wmove(win, y, x);
  338.     }
  339.     return(0);
  340. }
  341.  
  342. /*
  343.  * Wait for a key or time out.  Returns a -1 on timeout.
  344.  */
  345.  
  346. jmp_buf wk_jmp;
  347.  
  348. int
  349. wait_key(win, sec)
  350. WINDOW *win;
  351. unsigned int sec;
  352. {
  353.     int c, force_wk();
  354.     unsigned int alarm();
  355.  
  356.     signal(SIGALRM, force_wk);
  357.     if (setjmp(wk_jmp))
  358.         return(-1);
  359.     alarm(sec);
  360.     c = wgetch(win);
  361.     alarm(0);
  362.     return(c);
  363. }
  364. int
  365. force_wk(dummy)
  366. int dummy;
  367. {
  368.     void longjmp();
  369.  
  370.     longjmp(wk_jmp, 1);
  371. }
  372.  
  373. /*
  374.  * Here are some routines that are probably missing from the older
  375.  * flavors of curses(3)
  376.  */
  377.  
  378. #ifdef OLDCURSES
  379. /*
  380.  * Make the terminal bell go off
  381.  */
  382.  
  383. int
  384. beep()
  385. {
  386.     fputc(7, stderr);
  387.     return(0);
  388. }
  389.  
  390. /*
  391.  * Fix the stdin so that a read is satisfied immediately.  When read()
  392.  * is called it returns the character in the queue, or an error if no
  393.  * key was pressed.  The window argument is not used!
  394.  */
  395.  
  396. int
  397. nodelay(win, flag)
  398. WINDOW *win;
  399. int flag;
  400. {
  401.     if (flag)
  402.         fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) | O_NDELAY);
  403.     else
  404.         fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~O_NDELAY);
  405.     return(0);
  406. }
  407.  
  408. /*
  409.  * Take the terminal out of the "curses mode"
  410.  */
  411.  
  412. int
  413. resetterm()
  414. {
  415.     resetty();
  416.     return(0);
  417. }
  418.  
  419. /*
  420.  * Put the terminal back into the "curses mode"
  421.  */
  422.  
  423. int
  424. myputchar(c)
  425. char c;
  426. {
  427.     putchar(c);
  428. }
  429. int
  430. fixterm()
  431. {
  432.     tputs(TI, 1, myputchar);
  433.     tputs(VS, 1, myputchar);
  434.     nonl();
  435.     crmode();
  436.     noecho();
  437.     return(0);
  438. }
  439. #endif /* OLDCURSES */
  440.