home *** CD-ROM | disk | FTP | other *** search
- /* @(#)curs_io.c (c) copyright 3/18/87 (Dan Heller) */
-
- /* curs_io.c -- curses based I/O */
- #include "mush.h"
-
- #ifdef CURSES
- #include "bindings.h"
- #endif /* CURSES */
-
- char *_unctrl[] = {
- "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "^I", "^J", "^K",
- "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W",
- "^X", "^Y", "^Z", "^[", "^\\", "^]", "^~", "^_",
- " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-",
- ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
- "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I",
- "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
- "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e",
- "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
- "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "^?"
- };
-
- #ifdef Addch
- #undef Addch
- #endif /* Addch */
-
- #ifndef CURSES
-
- #define Addch(c) if (isoff(glob_flags, ECHO_FLAG)) \
- fputc(c, stdout), fflush(stdout)
-
- #else
-
- /* see end of Getstr */
- #define Addch(c) \
- if (iscurses) \
- addch(c), refresh(); \
- else if (isoff(glob_flags, ECHO_FLAG)) \
- fputc(c, stdout), fflush(stdout)
- #endif /* CURSES */
-
- /*
- * get a string of at most 'length' chars.
- * allow backspace-space-backspace, kill word and kill line
- * (options set by user in stty).
- * length is the max length this string can get. offset is from beginning
- * of string.
- * input of ^D returns -1; otherwise, return the number of chars in string.
- */
- Getstr(String, length, offset)
- char String[];
- register int length;
- {
- register int c, literal_next = FALSE;
- int count = offset;
-
- while ((c = getchar()) != '\n' && c != '\r' && c != EOF &&
- isoff(glob_flags, WAS_INTR)) {
- /* echo isn't set, so whatever the character, enter it */
- if (ison(glob_flags, ECHO_FLAG))
- if (count < length)
- String[count++] = c;
- else {
- print("Warning: string too long. Truncated at %d chars.\n",
- length);
- break;
- }
- /* ^D as the first char on a line or two ^D's in a row is EOF */
- else if (c == CTRL(D) && !count)
- break;
- else if (c == '\\') {
- literal_next = TRUE;
- Addch(String[count++] = '\\');
- } else if (literal_next) {
- literal_next = FALSE;
- if (iscntrl(c) || c == _tty.sg_kill || c == _tty.sg_erase
- #ifdef TIOCGLTC
- || c == ltchars.t_werasc
- #endif /* TIOCGLTC */
- )
- backspace(String, &count);
- String[count++] = c;
- if (iscntrl(c) || c == _tty.sg_erase) {
- if (iscntrl(c))
- Addch('^');
- Addch(_unctrl[c][1]);
- } else
- Addch(c);
- } else if (c == _tty.sg_erase || c == CTRL(H) || c == 127 /*CTRL(?)*/) {
- if (count)
- backspace(String, &count);
- /* if iscurses, then backspacing too far is cancelling a function */
- else if (!count && iscurses) {
- String[0] = '\0';
- return -1;
- }
- } else if (c == _tty.sg_kill) {
- if (count) {
- do backspace(String, &count);
- while (count);
- }
- } else
- #ifndef TIOCGLTC
- if (c == CTRL(R)) /* system doesn't have ltchars */
- #else
- if (c == ltchars.t_rprntc) /* reprint line */
- #endif /* TIOCGLTC */
- String[count] = 0, printf("\n%s", String);
- else
- #ifndef TIOCGLTC
- if (c == CTRL(W)) /* system doesn't have ltchars */
- #else
- if (c == ltchars.t_werasc) /* word erase */
- #endif /* TIOCGLTC */
- while (count) {
- backspace(String, &count);
- if (!count ||
- isspace(String[count-1]) && !isspace(String[count]) ||
- !isalnum(String[count-1]) && isalnum(String[count]))
- break;
- }
- else if (c == '\t')
- do {
- Addch(' ');
- String[count] = ' ';
- } while (++count % 8 && count < length);
- else if (count == length)
- bell();
- else {
- String[count++] = c;
- if (c != '\t' && iscntrl(c)) {
- Addch('^');
- Addch(_unctrl[c][1]);
- } else
- Addch(c);
- }
- }
- if (c == CTRL(D) || c == EOF || ison(glob_flags, WAS_INTR)) {
- if (feof(stdin))
- clearerr(stdin);
- return -1;
- }
- if (count && String[count-1] == '\\') {
- int count2;
- if (isoff(glob_flags, ECHO_FLAG))
- putchar('\n');
- if ((count2 = Getstr(&String[count-1], length - count + 1, 0)) == -1)
- return -1;
- return count + count2;
- }
- if (!iscurses && isoff(glob_flags, ECHO_FLAG))
- putchar('\n');
- while (count > 0 && isspace(String[count-1]))
- --count;
- String[count] = 0;
- return count;
- }
-
- static
- backspace(str, n)
- register char *str;
- int *n;
- {
- (*n)--;
- Addch('\b'); Addch(' '); Addch('\b');
- if (iscntrl(str[*n])) {
- Addch('\b'); Addch(' '); Addch('\b');
- }
- }
-
- #undef Addch
-
- #ifdef CURSES
- /*
- * prompt for a carriage return, but return whatever user types unless
- * it's a character which he might regret (like 'q' or 'x'). Ignore
- * interrupts (kind of) because we have nowhere to longjmp to. When we
- * return, we'll setjmp again (top of loop.c)
- */
- hit_return()
- {
- int c;
-
- turnon(glob_flags, IGN_SIGS);
- iscurses = FALSE;
- (void) check_new_mail();
- iscurses = TRUE;
- mail_status(1), addstr("...continue... "), refresh();
- c = getcmd();
- turnoff(glob_flags, IGN_SIGS);
-
- /* don't let the user type something he might regret */
- if (c == C_QUIT || c == C_EXIT)
- return C_NULL;
- return c;
- }
-
- curses_msg_list(str, list, m_list)
- register char *str, *list;
- char m_list[];
- {
- register char *p = NULL;
- int c;
-
- print(str);
- c = Getstr(list, COLS-13, 0);
- move(LINES-1, 0), refresh();
- if (c <= 0 || !(p = do_range(list, m_list)) ||
- (p == list && *p && *p != '$' && *p != '^')) {
- if (p)
- print("Invalid message list: %s", p);
- return 0;
- }
- return 1;
- }
-
- curs_vars(which)
- int which; /* really, a char */
- {
- char c, buf[128], buf2[128], *string;
- struct options **list;
-
- switch(which) {
- case C_OWN_HDR : string = "my_hdr", list = &own_hdrs;
- when C_ALIAS : string = "alias", list = &aliases;
- when C_IGNORE : string = "ignore", list = &ignore_hdr;
- when C_VAR_SET : string = "set", list = &set_options;
- otherwise : clr_bot_line(); return;
- }
-
- print("%s [? Set Unset All]: ", string);
- c = getchar();
- clr_bot_line();
- switch (Lower(c)) {
- /* if help, print help -- if "all", show all settings. */
- case '?' : case 'a' :
- if (c == '?') {
- if (!strcmp(string, "set")) {
- print("which variable? [all <var>]: ");
- if ((c = Getstr(buf+1, COLS-40, 0)) < 0)
- return;
- clr_bot_line();
- buf[0] = '?';
- if (c > 0) {
- char *argv[3];
- argv[0] = string;
- argv[1] = buf;
- argv[2] = NULL;
- Lower(buf[1]);
- if (!strcmp(buf+1, "a"))
- (void) strcpy(buf+1, "all");
- if (!strcmp(buf+1, "all"))
- turnon(glob_flags, CNTD_CMD);
- (void) set(2, argv);
- return;
- }
- }
- /* help returns next command (hit_return) */
- help(0, string, cmd_help);
- turnon(glob_flags, CNTD_CMD);
- return;
- }
- turnon(glob_flags, CNTD_CMD);
- (void) do_set(*list, NULL);
-
- /* if set, prompt for string and let user type */
- when 's' :
- print("set: ");
- c = Getstr(buf, COLS-18, 0);
- clr_bot_line();
- if (c > 0)
- (void) cmd_line(sprintf(buf2, "%s %s", string, buf), msg_list);
-
- /* if unset, just as easy as set! */
- when 'u' :
- print("unset: ", string);
- if (Getstr(buf, COLS-18, 0) > 0 && !un_set(list, buf))
- print("%s isn't set", buf);
- }
- if (ison(glob_flags, CNTD_CMD))
- putchar('\n');
- }
-
- #endif /* CURSES */
-