home *** CD-ROM | disk | FTP | other *** search
- /*
- * A possible replacement for curses' wgetstr(). Allows
- * line editing as in csh.
- * Recognizes the erase, kill chars, word deleting.
- *
- * By Hung Le (mott@ucscb.ucsc.edu ...!ucbvax!ucscc!ucscb!mott)
- * History:
- * 01/18/89 - Initial version
- * 03/20/89 - Add control-w to delete word
- * 05/17/89 - add option to return immediately or to bell()
- * when buffer is full.
- *
- * Release to Public Domain
- */
- #include <curses.h>
- #include <sys/ioctl.h>
- #include <sgtty.h>
-
- #define STD_INPUT 0 /* standard input */
- #define NEWLINE '\n'
- #define SPACE ' '
- /* default for erase and kill characters */
- #define ERASE '\010'
- #define KILL '\025'
- #define WORD '\027'
-
- /* You bugger !!! you did something wrong */
- #define bell() fprintf(stderr,"%c", '\007')
-
- /*
- * my_wgetstr(WINDOW *win, char *str, int size, int ret)
- * win: the concerned window
- * str: buffer holding input
- * size: (size -1) is the maximum chars to get
- * ret: flag indicating what to do when (size -1) is reached
- * 0: ring bell()
- * 1: returns
- * two macros are defined in "my_wgetstr.h" as RET=1 and NO_RET=0
- *
- * works same as wgetstr() in curses but allows editing.
- * Recognizes the erase character and the kill character and
- * WORD as the word deleting char.
- * Will try to get the erase and kill char from the terminal setting.
- * If failed, will use the default ERASE and KILL definitions.
- * Word char is set to WORD.
- *
- * DOES NOT check for illegal scrolling.
- * Returns
- * . when received a new line character
- * . if ( (strlen(str) == (size - 1)) and (ret) )
- *
- * str[size - 1] must be set to '\0' to end the string properly
- * so my_wgetstr(errwin, str, 8) will get at most 7 characters.
- *
- * Returned value is the number of chars read.
- */
-
- my_wgetstr(win, str, size, ret)
- WINDOW *win;
- char *str;
- int size;
- int ret;
- {
- struct sgttyb ttyb;
- char erase_char, kill_char;
- register int x_pos, y_pos, index, in;
-
- if (ioctl(STD_INPUT, TIOCGETP, &ttyb) == -1)
- {
- /*
- * failed to get terminal setting. Let's use the default
- * ERASE and KILL
- */
- erase_char = ERASE;
- kill_char = KILL;
- }
- else
- {
- erase_char = ttyb.sg_erase;
- kill_char = ttyb.sg_kill;
- }
-
- /*
- * since we are going to set noecho() and crmode() let's be safe and
- * save the current tty
- */
- savetty();
- noecho();
- crmode();
-
- /* get current position */
- getyx(win, y_pos, x_pos);
- /* intializing */
- index = 0;
- str[index] = '\0';
-
- /* while input char is not NEWLINE */
- while ((in = getch() & 0177) != NEWLINE)
- {
- /* if buffer is full (size -1) */
- if (index >= size - 1)
- if (ret)/* return flag set, return immediately */
- break;
- else /* allows editing chars to pass through */
- if ((in != erase_char) && (in != kill_char) && (in != WORD))
- {
- /* warns user that buffer is full */
- bell();
- continue;
- }
-
- if (in == erase_char) /* ERASING */
- {
- if (index > 0)
- {
- mvwaddch(win, y_pos, --x_pos, SPACE);
- str[--index] = SPACE;
- wmove(win, y_pos, x_pos);
- }
- else
- bell();
- }
- else
- if (in == kill_char) /* KILLING */
- {
- if (index > 0)
- while (index > 0)
- {
- mvwaddch(win, y_pos, --x_pos, SPACE);
- str[--index] = SPACE;
- wmove(win, y_pos, x_pos);
- }
- else
- bell();
- }
- else
- if (in == WORD) /* WORD DELETING */
- {
- if (index > 0)
- {
- /* throw away all spaces */
- while ((index > 0) && (str[index - 1] == SPACE))
- {
- mvwaddch(win, y_pos, --x_pos, SPACE);
- str[--index] = SPACE;
- wmove(win, y_pos, x_pos);
- }
- /* move back until see another space */
- while ((index > 0) && (str[index - 1] != SPACE))
- {
- mvwaddch(win, y_pos, --x_pos, SPACE);
- str[--index] = SPACE;
- wmove(win, y_pos, x_pos);
- }
- }
- else
- bell();
- }
- else
- {
- mvwaddch(win, y_pos, x_pos++, in);
- str[index++] = in;
- }
- /* show result */
- wrefresh(win);
- }
- /* ends the string properly */
- str[index] = '\0';
- /* restore the tty */
- resetty();
- /* returns number of chars read */
- return (index);
- }
-