diff options
author | 1997-11-26 04:01:02 +0000 | |
---|---|---|
committer | 1997-11-26 04:01:02 +0000 | |
commit | 010b00ebb3f4bdd576ec41ca1d5d0a8994e8fe5b (patch) | |
tree | 5ee5e7213ad9b412a927de7effdcb7c8ce4b489e /lib/libcurses/lib_getch.c | |
parent | libform from ncurses 4.1. Post 4.1 patches to be applied in a separate commit. (diff) | |
download | wireguard-openbsd-010b00ebb3f4bdd576ec41ca1d5d0a8994e8fe5b.tar.xz wireguard-openbsd-010b00ebb3f4bdd576ec41ca1d5d0a8994e8fe5b.zip |
ncurses 4.1 + changes to work with our terminfo libs (instead of
the ncurses ones). Changes are #ifdef EXTERN_TERMINFO.
Post 4.1 patches will be applied in a separate commit.
Diffstat (limited to 'lib/libcurses/lib_getch.c')
-rw-r--r-- | lib/libcurses/lib_getch.c | 224 |
1 files changed, 138 insertions, 86 deletions
diff --git a/lib/libcurses/lib_getch.c b/lib/libcurses/lib_getch.c index 12372bc0fc0..c0d0d5af203 100644 --- a/lib/libcurses/lib_getch.c +++ b/lib/libcurses/lib_getch.c @@ -26,13 +26,9 @@ ** */ -#include "curses.priv.h" -#include <sys/types.h> -#include <string.h> -#include <errno.h> -#if !HAVE_EXTERN_ERRNO -extern int errno; -#endif +#include <curses.priv.h> + +MODULE_ID("Id: lib_getch.c,v 1.24 1997/02/15 21:12:16 tom Exp $") #define head SP->_fifohead #define tail SP->_fifotail @@ -52,24 +48,24 @@ static int fifo_peek(void) } #ifdef TRACE -static __inline void fifo_dump(void) +static inline void fifo_dump(void) { int i; T(("head = %d, tail = %d, peek = %d", head, tail, peek)); for (i = 0; i < 10; i++) - T(("char %d = %s", i, _tracechar(SP->_fifo[i]))); + T(("char %d = %s", i, _trace_key(SP->_fifo[i]))); } #endif /* TRACE */ -static __inline int fifo_pull(void) +static inline int fifo_pull(void) { int ch; - ch = SP->_fifo[head]; + ch = SP->_fifo[head]; T(("pulling %d from %d", ch, head)); h_inc(); #ifdef TRACE - if (_nc_tracing & TRACE_FIFO) fifo_dump(); + if (_nc_tracing & TRACE_IEVENT) fifo_dump(); #endif return ch; } @@ -83,26 +79,56 @@ int ungetch(int ch) t_inc() } else h_dec(); - + SP->_fifo[head] = ch; T(("ungetch ok")); #ifdef TRACE - if (_nc_tracing & TRACE_FIFO) fifo_dump(); + if (_nc_tracing & TRACE_IEVENT) fifo_dump(); #endif return OK; } -static __inline int fifo_push(void) +static inline int fifo_push(void) { int n; -unsigned char ch; +unsigned int ch; if (tail == -1) return ERR; /* FALLTHRU */ -again: - n = read(SP->_ifd, &ch, 1); - if (n == -1 && errno == EINTR) +again: + errno = 0; +#if USE_GPM_SUPPORT + if ((_nc_mouse_fd() >= 0) + && (_nc_timed_wait(3, -1, (int *)0) & 2)) + { + _nc_mouse_event(SP); + ch = KEY_MOUSE; + n = 1; + } else +#endif + { + unsigned char c2; + n = read(SP->_ifd, &c2, 1); + ch = c2; + } + + /* + * Under System V curses with non-restarting signals, getch() returns + * with value ERR when a handled signal keeps it from completing. + * If signals restart system calls, OTOH, the signal is invisible + * except to its handler. + * + * We don't want this difference to show. This piece of code + * tries to make it look like we always have restarting signals. + */ + if (n <= 0 && errno == EINTR) goto again; + + if ((n == -1) || (n == 0)) + { + T(("read(%d,&ch,1)=%d", SP->_ifd, n)); + return ERR; + } T(("read %d characters", n)); SP->_fifo[tail] = ch; @@ -110,12 +136,12 @@ again: t_inc(); T(("pushed %#x at %d", ch, tail)); #ifdef TRACE - if (_nc_tracing & TRACE_FIFO) fifo_dump(); + if (_nc_tracing & TRACE_IEVENT) fifo_dump(); #endif return ch; } -static __inline void fifo_clear(void) +static inline void fifo_clear(void) { int i; for (i = 0; i < FIFO_SIZE; i++) @@ -133,7 +159,8 @@ void _nc_backspace(WINDOW *win) return; } - mvwaddstr(curscr, win->_begy + win->_cury, win->_begx + win->_curx, "\b \b"); + mvwaddstr(curscr, win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx, "\b \b"); waddstr(win, "\b \b"); /* @@ -141,35 +168,57 @@ void _nc_backspace(WINDOW *win) * would fail on terminals with a non-backspace cursor_left * character. */ - mvcur(win->_begy + win->_cury, win->_begx + win->_curx, - win->_begy + win->_cury, win->_begx + win->_curx - 1); + mvcur(win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx, + win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx - 1); _nc_outstr(" "); - mvcur(win->_begy + win->_cury, win->_begx + win->_curx, - win->_begy + win->_cury, win->_begx + win->_curx - 1); - SP->_curscol--; + mvcur(win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx, + win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx - 1); + SP->_curscol--; } int wgetch(WINDOW *win) { -bool setHere = FALSE; /* cbreak mode was set here */ -int ch; +int ch; + + T((T_CALLED("wgetch(%p)"), win)); + + /* + * Handle cooked mode. Grab a string from the screen, + * stuff its contents in the FIFO queue, and pop off + * the first character to return it. + */ + if (head == -1 && !SP->_raw && !SP->_cbreak) + { + char buf[MAXCOLUMNS], *sp; + + T(("filling queue in cooked mode")); - T(("wgetch(%p) called", win)); + wgetnstr(win, buf, MAXCOLUMNS); + + for (sp = buf; *sp; sp++) + ungetch(*sp); + ungetch('\n'); + + return(fifo_pull()); + } /* this should be eliminated */ - if (! win->_scroll && (SP->_echo) && (win->_flags & _FULLWIN) - && win->_curx == win->_maxx && win->_cury == win->_maxy) - return(ERR); + if (!has_ic() + && !win->_scroll + && (SP->_echo) + && (win->_flags & _FULLWIN) + && win->_curx == win->_maxx + && win->_cury == win->_maxy) + returnCode(ERR); if ((is_wintouched(win) || (win->_flags & _HASMOVED)) && !(win->_flags & _ISPAD)) wrefresh(win); - if (SP->_echo && ! (SP->_raw || SP->_cbreak)) { - cbreak(); - setHere = TRUE; - } - if (!win->_notimeout && (win->_delay >= 0 || SP->_cbreak > 1)) { int delay; @@ -182,19 +231,13 @@ int ch; T(("delay is %d microseconds", delay)); if (head == -1) /* fifo is empty */ - if (_nc_timed_wait(SP->_ifd, delay, NULL) == 0) - return ERR; + if (!_nc_timed_wait(3, delay, (int *)0)) + returnCode(ERR); /* else go on to read data available */ } - /* - * Give the mouse interface a chance to pick up an event. - * If no mouse event, check for keyboard input. - */ - if (_nc_mouse_event(SP)) - ch = KEY_MOUSE; - else if (win->_use_keypad) { - /* + if (win->_use_keypad) { + /* * This is tricky. We only want to get special-key * events one at a time. But we want to accumulate * mouse events until either (a) the mouse logic tells @@ -203,9 +246,9 @@ int ch; * * Note: if the mouse code starts failing to compose * press/release events into clicks, you should probably - * increase _nc_max_click_interval. + * increase _nc_max_click_interval. */ - int runcount = 0; + int runcount = 0; do { ch = kgetch(win); @@ -217,7 +260,7 @@ int ch; } } while (ch == KEY_MOUSE - && (_nc_timed_wait(SP->_ifd, _nc_max_click_interval, NULL) + && (_nc_timed_wait(3, _nc_max_click_interval, (int *)0) || !_nc_mouse_parse(runcount))); if (runcount > 0 && ch != KEY_MOUSE) { @@ -231,6 +274,18 @@ int ch; ch = fifo_pull(); } + if (ch == ERR) + { + T(("wgetch returning ERR")); + returnCode(ERR); + } + + /* + * Simulate ICRNL mode + */ + if ((ch == '\r') && SP->_nl) + ch = '\n'; + /* Strip 8th-bit if so desired. We do this only for characters that * are in the range 128-255, to provide compatibility with terminals * that display only 7-bit characters. Note that 'ch' may be a @@ -240,28 +295,24 @@ int ch; if (!SP->_use_meta) ch &= 0x7f; - if (!(win->_flags & _ISPAD) && SP->_echo) { + if (!(win->_flags & _ISPAD) && SP->_echo) { /* there must be a simpler way of doing this */ if (ch == erasechar() || ch == KEY_BACKSPACE || ch == KEY_LEFT) _nc_backspace(win); else if (ch < KEY_MIN) { mvwaddch(curscr, - win->_begy + win->_cury, - win->_begx + win->_curx, - (chtype)(ch | win->_attrs)); - waddch(win, (chtype)(ch | win->_attrs)); + win->_begy + win->_cury + win->_yoffset, + win->_begx + win->_curx, + ch); + waddch(win, (chtype)ch); } else beep(); } - if (setHere) - nocbreak(); - T(("wgetch returning : 0x%x = %s", - ch, - (ch > KEY_MIN) ? keyname(ch) : unctrl(ch))); + T(("wgetch returning : %#x = %s", ch, _trace_key(ch));) - return(ch); + returnCode(ch); } @@ -278,52 +329,53 @@ int ch; */ static int -kgetch(WINDOW *win) +kgetch(WINDOW *win GCC_UNUSED) { -struct try *ptr; +struct tries *ptr; int ch = 0; int timeleft = ESCDELAY; - TR(TRACE_FIFO, ("kgetch(%p) called", win)); + TR(TRACE_IEVENT, ("kgetch(%p) called", win)); - ptr = SP->_keytry; + ptr = SP->_keytry; if (head == -1) { - ch = fifo_push(); + if ((ch = fifo_push()) == ERR) + return ERR; peek = 0; - while (ptr != NULL) { - TR(TRACE_FIFO, ("ch: %s", _tracechar((unsigned char)ch))); + while (ptr != NULL) { + TR(TRACE_IEVENT, ("ch: %s", _trace_key((unsigned char)ch))); while ((ptr != NULL) && (ptr->ch != (unsigned char)ch)) ptr = ptr->sibling; #ifdef TRACE if (ptr == NULL) - {TR(TRACE_FIFO, ("ptr is null"));} + {TR(TRACE_IEVENT, ("ptr is null"));} else - TR(TRACE_FIFO, ("ptr=%p, ch=%d, value=%d", + TR(TRACE_IEVENT, ("ptr=%p, ch=%d, value=%d", ptr, ptr->ch, ptr->value)); #endif /* TRACE */ if (ptr != NULL) - if (ptr->value != 0) { /* sequence terminated */ - TR(TRACE_FIFO, ("end of sequence")); - fifo_clear(); + if (ptr->value != 0) { /* sequence terminated */ + TR(TRACE_IEVENT, ("end of sequence")); + fifo_clear(); return(ptr->value); - } else { /* go back for another character */ + } else { /* go back for another character */ ptr = ptr->child; - TR(TRACE_FIFO, ("going back for more")); - } else + TR(TRACE_IEVENT, ("going back for more")); + } else break; - TR(TRACE_FIFO, ("waiting for rest of sequence")); - if (_nc_timed_wait(SP->_ifd, timeleft, &timeleft) < 1) { - TR(TRACE_FIFO, ("ran out of time")); + TR(TRACE_IEVENT, ("waiting for rest of sequence")); + if (!_nc_timed_wait(3, timeleft, &timeleft)) { + TR(TRACE_IEVENT, ("ran out of time")); return(fifo_pull()); - } else { - TR(TRACE_FIFO, ("got more!")); - fifo_push(); - ch = fifo_peek(); - } + } else { + TR(TRACE_IEVENT, ("got more!")); + fifo_push(); + ch = fifo_peek(); + } } - } + } return(fifo_pull()); } |