home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / mush6.0 / part03 / curs_io.c next >
Encoding:
C/C++ Source or Header  |  1988-04-12  |  7.2 KB  |  285 lines

  1. /* @(#)curs_io.c    (c) copyright 3/18/87 (Dan Heller) */
  2.  
  3. /* curs_io.c -- curses based I/O */
  4. #include "mush.h"
  5.  
  6. #ifdef CURSES
  7. #include "bindings.h"
  8. #endif /* CURSES */
  9.  
  10. char *_unctrl[] = {
  11.     "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "^I", "^J", "^K",
  12.     "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W",
  13.     "^X", "^Y", "^Z", "^[", "^\\", "^]", "^~", "^_",
  14.     " ", "!", "\"", "#", "$",  "%", "&", "'", "(", ")", "*", "+", ",", "-",
  15.     ".", "/", "0",  "1", "2",  "3", "4", "5", "6", "7", "8", "9", ":", ";",
  16.     "<", "=", ">",  "?", "@",  "A", "B", "C", "D", "E", "F", "G", "H", "I",
  17.     "J", "K", "L",  "M", "N",  "O", "P", "Q", "R", "S", "T", "U", "V", "W",
  18.     "X", "Y", "Z",  "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e",
  19.     "f", "g", "h",  "i", "j",  "k", "l", "m", "n", "o", "p", "q", "r", "s",
  20.     "t", "u", "v",  "w", "x",  "y", "z", "{", "|", "}", "~", "^?"
  21. };
  22.  
  23. #ifdef Addch
  24. #undef Addch
  25. #endif /* Addch */
  26.  
  27. #ifndef CURSES
  28.  
  29. #define Addch(c) if (isoff(glob_flags, ECHO_FLAG)) \
  30.               fputc(c, stdout), fflush(stdout)
  31.  
  32. #else
  33.  
  34. /* see end of Getstr */
  35. #define Addch(c)  \
  36.     if (iscurses) \
  37.     addch(c), refresh(); \
  38.     else if (isoff(glob_flags, ECHO_FLAG)) \
  39.     fputc(c, stdout), fflush(stdout)
  40. #endif /* CURSES */
  41.  
  42. /*
  43.  * get a string of at most 'length' chars.
  44.  * allow backspace-space-backspace, kill word and kill line
  45.  * (options set by user in stty).
  46.  * length is the max length this string can get. offset is from beginning
  47.  * of string.
  48.  * input of ^D returns -1; otherwise, return the number of chars in string.
  49.  */
  50. Getstr(String, length, offset)
  51. char String[];
  52. register int length;
  53. {
  54.     register int c, literal_next = FALSE;
  55.     int count = offset;
  56.  
  57.     while ((c = getchar()) != '\n' && c != '\r' && c != EOF &&
  58.     isoff(glob_flags, WAS_INTR)) {
  59.     /* echo isn't set, so whatever the character, enter it */
  60.     if (ison(glob_flags, ECHO_FLAG))
  61.         if (count < length)
  62.         String[count++] = c;
  63.         else {
  64.         print("Warning: string too long. Truncated at %d chars.\n",
  65.             length);
  66.         break;
  67.         }
  68.     /* ^D as the first char on a line or two ^D's in a row is EOF */
  69.     else if (c == CTRL(D) && !count)
  70.         break;
  71.     else if (c == '\\') {
  72.         literal_next = TRUE;
  73.         Addch(String[count++] = '\\');
  74.     } else if (literal_next) {
  75.         literal_next = FALSE;
  76.         if (iscntrl(c) || c == _tty.sg_kill || c == _tty.sg_erase
  77. #ifdef TIOCGLTC
  78.             || c == ltchars.t_werasc
  79. #endif /* TIOCGLTC */
  80.                      )
  81.         backspace(String, &count);
  82.         String[count++] = c;
  83.         if (iscntrl(c) || c == _tty.sg_erase) {
  84.         if (iscntrl(c))
  85.             Addch('^');
  86.         Addch(_unctrl[c][1]);
  87.         } else
  88.         Addch(c);
  89.     } else if (c == _tty.sg_erase || c == CTRL(H) || c == 127 /*CTRL(?)*/) {
  90.         if (count)
  91.         backspace(String, &count);
  92.         /* if iscurses, then backspacing too far is cancelling a function */
  93.         else if (!count && iscurses) {
  94.         String[0] = '\0';
  95.         return -1;
  96.         }
  97.     } else if (c == _tty.sg_kill) {
  98.         if (count) {
  99.         do backspace(String, &count);
  100.         while (count);
  101.         }
  102.     } else
  103. #ifndef TIOCGLTC
  104.     if (c == CTRL(R)) /* system doesn't have ltchars */
  105. #else
  106.     if (c == ltchars.t_rprntc) /* reprint line */
  107. #endif /* TIOCGLTC */
  108.         String[count] = 0, printf("\n%s", String);
  109.         else
  110. #ifndef TIOCGLTC
  111.     if (c == CTRL(W)) /* system doesn't have ltchars */
  112. #else
  113.     if (c == ltchars.t_werasc) /* word erase */
  114. #endif /* TIOCGLTC */
  115.         while (count) {
  116.         backspace(String, &count);
  117.         if (!count ||
  118.             isspace(String[count-1]) && !isspace(String[count]) ||
  119.             !isalnum(String[count-1]) && isalnum(String[count]))
  120.             break;
  121.         }
  122.     else if (c == '\t')
  123.         do  {
  124.         Addch(' ');
  125.         String[count] = ' ';
  126.         } while (++count % 8 && count < length);
  127.     else if (count == length)
  128.         bell();
  129.     else {
  130.         String[count++] = c;
  131.         if (c != '\t' && iscntrl(c)) {
  132.         Addch('^');
  133.         Addch(_unctrl[c][1]);
  134.         } else
  135.         Addch(c);
  136.     }
  137.     }
  138.     if (c == CTRL(D) || c == EOF || ison(glob_flags, WAS_INTR)) {
  139.     if (feof(stdin))
  140.         clearerr(stdin);
  141.     return -1;
  142.     }
  143.     if (count && String[count-1] == '\\') {
  144.     int count2;
  145.     if (isoff(glob_flags, ECHO_FLAG))
  146.         putchar('\n');
  147.     if ((count2 = Getstr(&String[count-1], length - count + 1, 0)) == -1)
  148.         return -1;
  149.     return count + count2;
  150.     }
  151.     if (!iscurses && isoff(glob_flags, ECHO_FLAG))
  152.     putchar('\n');
  153.     while (count > 0 && isspace(String[count-1]))
  154.     --count;
  155.     String[count] = 0;
  156.     return count;
  157. }
  158.  
  159. static
  160. backspace(str, n)
  161. register char *str;
  162. int *n;
  163. {
  164.     (*n)--;
  165.     Addch('\b'); Addch(' '); Addch('\b');
  166.     if (iscntrl(str[*n])) {
  167.     Addch('\b'); Addch(' '); Addch('\b');
  168.     }
  169. }
  170.  
  171. #undef Addch
  172.  
  173. #ifdef CURSES
  174. /*
  175.  * prompt for a carriage return, but return whatever user types unless
  176.  * it's a character which he might regret (like 'q' or 'x'). Ignore
  177.  * interrupts (kind of) because we have nowhere to longjmp to.  When we
  178.  * return, we'll setjmp again (top of loop.c)
  179.  */
  180. hit_return()
  181. {
  182.     int c;
  183.  
  184.     turnon(glob_flags, IGN_SIGS);
  185.     iscurses = FALSE;
  186.     (void) check_new_mail();
  187.     iscurses = TRUE;
  188.     mail_status(1), addstr("...continue... "), refresh();
  189.     c = getcmd();
  190.     turnoff(glob_flags, IGN_SIGS);
  191.  
  192.     /* don't let the user type something he might regret */
  193.     if (c == C_QUIT || c == C_EXIT)
  194.     return C_NULL;
  195.     return c;
  196. }
  197.  
  198. curses_msg_list(str, list, m_list)
  199. register char *str, *list;
  200. char m_list[];
  201. {
  202.     register char *p = NULL;
  203.     int c;
  204.  
  205.     print(str);
  206.     c = Getstr(list, COLS-13, 0);
  207.     move(LINES-1, 0), refresh();
  208.     if (c <= 0 || !(p = do_range(list, m_list)) ||
  209.     (p == list && *p && *p != '$' && *p != '^')) {
  210.     if (p)
  211.         print("Invalid message list: %s", p);
  212.     return 0;
  213.     }
  214.     return 1;
  215. }
  216.  
  217. curs_vars(which)
  218. int which;  /* really, a char */
  219. {
  220.     char c, buf[128], buf2[128], *string;
  221.     struct options **list;
  222.  
  223.     switch(which) {
  224.     case C_OWN_HDR : string = "my_hdr", list = &own_hdrs;
  225.     when C_ALIAS : string = "alias", list = &aliases;
  226.     when C_IGNORE : string = "ignore", list = &ignore_hdr;
  227.     when C_VAR_SET : string = "set", list = &set_options;
  228.     otherwise : clr_bot_line(); return;
  229.     }
  230.  
  231.     print("%s [? Set Unset All]: ", string);
  232.     c = getchar();
  233.     clr_bot_line();
  234.     switch (Lower(c)) {
  235.     /* if help, print help -- if "all", show all settings. */
  236.     case '?' : case 'a' :
  237.         if (c == '?') {
  238.         if (!strcmp(string, "set")) {
  239.             print("which variable? [all <var>]: ");
  240.             if ((c = Getstr(buf+1, COLS-40, 0)) < 0)
  241.             return;
  242.             clr_bot_line();
  243.             buf[0] = '?';
  244.             if (c > 0) {
  245.             char *argv[3];
  246.             argv[0] = string;
  247.             argv[1] = buf;
  248.             argv[2] = NULL;
  249.             Lower(buf[1]);
  250.             if (!strcmp(buf+1, "a"))
  251.                 (void) strcpy(buf+1, "all");
  252.             if (!strcmp(buf+1, "all"))
  253.                 turnon(glob_flags, CNTD_CMD);
  254.             (void) set(2, argv);
  255.             return;
  256.             }
  257.         }
  258.         /* help returns next command (hit_return) */
  259.         help(0, string, cmd_help);
  260.         turnon(glob_flags, CNTD_CMD);
  261.         return;
  262.         }
  263.         turnon(glob_flags, CNTD_CMD);
  264.         (void) do_set(*list, NULL);
  265.  
  266.     /* if set, prompt for string and let user type */
  267.     when 's' :
  268.         print("set: ");
  269.         c = Getstr(buf, COLS-18, 0);
  270.         clr_bot_line();
  271.         if (c > 0)
  272.         (void) cmd_line(sprintf(buf2, "%s %s", string, buf), msg_list);
  273.  
  274.     /* if unset, just as easy as set! */
  275.     when 'u' :
  276.         print("unset: ", string);
  277.         if (Getstr(buf, COLS-18, 0) > 0 && !un_set(list, buf))
  278.         print("%s isn't set", buf);
  279.     }
  280.     if (ison(glob_flags, CNTD_CMD))
  281.     putchar('\n');
  282. }
  283.  
  284. #endif /* CURSES */
  285.