summaryrefslogtreecommitdiffstats
path: root/lib/libcurses/lib_getch.c
diff options
context:
space:
mode:
authormillert <millert@openbsd.org>1997-11-26 04:01:02 +0000
committermillert <millert@openbsd.org>1997-11-26 04:01:02 +0000
commit010b00ebb3f4bdd576ec41ca1d5d0a8994e8fe5b (patch)
tree5ee5e7213ad9b412a927de7effdcb7c8ce4b489e /lib/libcurses/lib_getch.c
parentlibform from ncurses 4.1. Post 4.1 patches to be applied in a separate commit. (diff)
downloadwireguard-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.c224
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());
}