diff options
Diffstat (limited to 'ncurses-5.3/ncurses/base/lib_getch.c')
-rw-r--r-- | ncurses-5.3/ncurses/base/lib_getch.c | 537 |
1 files changed, 0 insertions, 537 deletions
diff --git a/ncurses-5.3/ncurses/base/lib_getch.c b/ncurses-5.3/ncurses/base/lib_getch.c deleted file mode 100644 index 45502ab..0000000 --- a/ncurses-5.3/ncurses/base/lib_getch.c +++ /dev/null @@ -1,537 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * - ****************************************************************************/ - -/* -** lib_getch.c -** -** The routine getch(). -** -*/ - -#include <curses.priv.h> - -MODULE_ID("$Id$") - -#include <fifo_defs.h> - -NCURSES_EXPORT_VAR(int) -ESCDELAY = 1000; /* max interval betw. chars in funkeys, in millisecs */ - -#ifdef NCURSES_WGETCH_EVENTS -#define TWAIT_MASK 7 -#else -#define TWAIT_MASK 3 -#endif - -static inline int -fifo_peek(void) -{ - int ch = SP->_fifo[peek]; - TR(TRACE_IEVENT, ("peeking at %d", peek)); - - p_inc(); - return ch; -} - -static inline int -fifo_pull(void) -{ - int ch; - ch = SP->_fifo[head]; - TR(TRACE_IEVENT, ("pulling %s from %d", _tracechar(ch), head)); - - if (peek == head) { - h_inc(); - peek = head; - } else - h_inc(); - -#ifdef TRACE - if (_nc_tracing & TRACE_IEVENT) - _nc_fifo_dump(); -#endif - return ch; -} - -static inline int -fifo_push(EVENTLIST_0th(_nc_eventlist * evl)) -{ - int n; - int ch = 0; - int mask; - - (void) mask; - if (tail == -1) - return ERR; - -#ifdef HIDE_EINTR - again: - errno = 0; -#endif - -#ifdef NCURSES_WGETCH_EVENTS - if (evl -#if USE_GPM_SUPPORT || defined(USE_EMX_MOUSE) - || (SP->_mouse_fd >= 0) -#endif - ) { - mask = _nc_timed_wait(TWAIT_MASK, -1, (int *) 0, evl); - } else - mask = 0; - - if (mask & 4) { - T(("fifo_push: ungetch KEY_EVENT")); - ungetch(KEY_EVENT); - return KEY_EVENT; - } -#elif USE_GPM_SUPPORT || defined(USE_EMX_MOUSE) - if (SP->_mouse_fd >= 0) - mask = _nc_timed_wait(TWAIT_MASK, -1, (int *) 0 EVENTLIST_2nd(evl)); -#endif - -#if USE_GPM_SUPPORT || defined(USE_EMX_MOUSE) - if ((SP->_mouse_fd >= 0) && (mask & 2)) { - SP->_mouse_event(SP); - ch = KEY_MOUSE; - n = 1; - } else -#endif - { /* Can block... */ - unsigned char c2 = 0; - n = read(SP->_ifd, &c2, 1); - ch = c2; - } - -#ifdef HIDE_EINTR - /* - * 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; -#endif - - if ((n == -1) || (n == 0)) { - TR(TRACE_IEVENT, ("read(%d,&ch,1)=%d, errno=%d", SP->_ifd, n, errno)); - ch = ERR; - } - TR(TRACE_IEVENT, ("read %d characters", n)); - - SP->_fifo[tail] = ch; - SP->_fifohold = 0; - if (head == -1) - head = peek = tail; - t_inc(); - TR(TRACE_IEVENT, ("pushed %s at %d", _tracechar(ch), tail)); -#ifdef TRACE - if (_nc_tracing & TRACE_IEVENT) - _nc_fifo_dump(); -#endif - return ch; -} - -static inline void -fifo_clear(void) -{ - memset(SP->_fifo, 0, sizeof(SP->_fifo)); - head = -1; - tail = peek = 0; -} - -static int kgetch(EVENTLIST_0th(_nc_eventlist * evl)); - -#define wgetch_should_refresh(win) (\ - (is_wintouched(win) || (win->_flags & _HASMOVED)) \ - && !(win->_flags & _ISPAD)) - -NCURSES_EXPORT(int) -_nc_wgetch(WINDOW *win, - unsigned long *result, - int use_meta - EVENTLIST_2nd(_nc_eventlist * evl)) -{ - int ch; -#ifdef NCURSES_WGETCH_EVENTS - long event_delay = -1; -#endif - - T((T_CALLED("_nc_wgetch(%p)"), win)); - - *result = 0; - if (!win) - returnCode(ERR); - - if (cooked_key_in_fifo()) { - if (wgetch_should_refresh(win)) - wrefresh(win); - - *result = fifo_pull(); - returnCode(OK); - } -#ifdef NCURSES_WGETCH_EVENTS - if (evl && (evl->count == 0)) - evl = NULL; - event_delay = _nc_eventlist_timeout(evl); -#endif - - /* - * 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; - int rc; - - TR(TRACE_IEVENT, ("filling queue in cooked mode")); - - rc = wgetnstr(win, buf, MAXCOLUMNS); - - /* ungetch in reverse order */ -#ifdef NCURSES_WGETCH_EVENTS - if (rc != KEY_EVENT) -#endif - ungetch('\n'); - for (sp = buf + strlen(buf); sp > buf; sp--) - ungetch(sp[-1]); - -#ifdef NCURSES_WGETCH_EVENTS - /* Return it first */ - if (rc == KEY_EVENT) { - *result = rc; - returnCode(OK); - } -#endif - - *result = fifo_pull(); - returnCode(OK); - } - - if (win->_use_keypad != SP->_keypad_on) - _nc_keypad(win->_use_keypad); - - if (wgetch_should_refresh(win)) - wrefresh(win); - - if (!win->_notimeout && (win->_delay >= 0 || SP->_cbreak > 1)) { - int delay; - - TR(TRACE_IEVENT, ("timed delay in wgetch()")); - if (SP->_cbreak > 1) - delay = (SP->_cbreak - 1) * 100; - else - delay = win->_delay; - -#ifdef NCURSES_WGETCH_EVENTS - if (event_delay >= 0 && delay > event_delay) - delay = event_delay; -#endif - - TR(TRACE_IEVENT, ("delay is %d milliseconds", delay)); - - if (head == -1) { /* fifo is empty */ - int rc = _nc_timed_wait(TWAIT_MASK, - delay, - (int *) 0 - EVENTLIST_2nd(evl)); - -#ifdef NCURSES_WGETCH_EVENTS - if (rc & 4) { - *result = KEY_EVENT; - returnCode(OK); - } -#endif - if (!rc) - returnCode(ERR); - } - /* else go on to read data available */ - } - - 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 - * us it's picked up a complete gesture, or (b) - * there's a detectable time lapse after one. - * - * Note: if the mouse code starts failing to compose - * press/release events into clicks, you should probably - * increase the wait with mouseinterval(). - */ - int runcount = 0; - int rc; - - do { - ch = kgetch(EVENTLIST_1st(evl)); - if (ch == KEY_MOUSE) { - ++runcount; - if (SP->_mouse_inline(SP)) - break; - } - if (SP->_maxclick < 0) - break; - } while - (ch == KEY_MOUSE - && (((rc = _nc_timed_wait(TWAIT_MASK, - SP->_maxclick, - (int *) 0 - EVENTLIST_2nd(evl))) != 0 - && !(rc & 4)) - || !SP->_mouse_parse(runcount))); -#ifdef NCURSES_WGETCH_EVENTS - if ((rc & 4) && !ch == KEY_EVENT) { - ungetch(ch); - ch = KEY_EVENT; - } -#endif - if (runcount > 0 && ch != KEY_MOUSE) { -#ifdef NCURSES_WGETCH_EVENTS - /* mouse event sequence ended by an event, report event */ - if (ch == KEY_EVENT) { - ungetch(KEY_MOUSE); /* FIXME This interrupts a gesture... */ - } else -#endif - { - /* mouse event sequence ended by keystroke, store keystroke */ - ungetch(ch); - ch = KEY_MOUSE; - } - } - } else { - if (head == -1) - fifo_push(EVENTLIST_1st(evl)); - ch = fifo_pull(); - } - - if (ch == ERR) { -#if USE_SIZECHANGE - if (SP->_sig_winch) { - _nc_update_screensize(); - /* resizeterm can push KEY_RESIZE */ - if (cooked_key_in_fifo()) { - *result = fifo_pull(); - returnCode(*result >= KEY_MIN ? KEY_CODE_YES : OK); - } - } -#endif - returnCode(ERR); - } - - /* - * If echo() is in effect, display the printable version of the - * key on the screen. Carriage return and backspace are treated - * specially by Solaris curses: - * - * If carriage return is defined as a function key in the - * terminfo, e.g., kent, then Solaris may return either ^J (or ^M - * if nonl() is set) or KEY_ENTER depending on the echo() mode. - * We echo before translating carriage return based on nonl(), - * since the visual result simply moves the cursor to column 0. - * - * Backspace is a different matter. Solaris curses does not - * translate it to KEY_BACKSPACE if kbs=^H. This does not depend - * on the stty modes, but appears to be a hardcoded special case. - * This is a difference from ncurses, which uses the terminfo entry. - * However, we provide the same visual result as Solaris, moving the - * cursor to the left. - */ - if (SP->_echo && !(win->_flags & _ISPAD)) { - chtype backup = (ch == KEY_BACKSPACE) ? '\b' : ch; - if (backup < KEY_MIN) - wechochar(win, backup); - } - - /* - * 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 - * function key at this point, so we mustn't strip _those_. - */ - if (!use_meta) - if ((ch < KEY_MIN) && (ch & 0x80)) - ch &= 0x7f; - - T(("wgetch returning : %s", _tracechar(ch))); - - *result = ch; - returnCode(ch >= KEY_MIN ? KEY_CODE_YES : OK); -} - -#ifdef NCURSES_WGETCH_EVENTS -NCURSES_EXPORT(int) -wgetch_events(WINDOW *win, _nc_eventlist * evl) -{ - int code; - unsigned long value; - - T((T_CALLED("wgetch_events(%p,%p)"), win, evl)); - code = _nc_wgetch(win, - &value, - SP->_use_meta - EVENTLIST_2nd(evl)); - if (code != ERR) - code = value; - returnCode(code); -} -#endif - -NCURSES_EXPORT(int) -wgetch(WINDOW *win) -{ - int code; - unsigned long value; - - T((T_CALLED("wgetch(%p)"), win)); - code = _nc_wgetch(win, - &value, - SP->_use_meta - EVENTLIST_2nd((_nc_eventlist *) 0)); - if (code != ERR) - code = value; - returnCode(code); -} - -/* -** int -** kgetch() -** -** Get an input character, but take care of keypad sequences, returning -** an appropriate code when one matches the input. After each character -** is received, set an alarm call based on ESCDELAY. If no more of the -** sequence is received by the time the alarm goes off, pass through -** the sequence gotten so far. -** -** This function must be called when there are no cooked keys in queue. -** (that is head==-1 || peek==head) -** -*/ - -static int -kgetch(EVENTLIST_0th(_nc_eventlist * evl)) -{ - struct tries *ptr; - int ch = 0; - int timeleft = ESCDELAY; - - TR(TRACE_IEVENT, ("kgetch() called")); - - ptr = SP->_keytry; - - for (;;) { - if (cooked_key_in_fifo() && SP->_fifo[head] >= KEY_MIN) { - break; - } else if (!raw_key_in_fifo()) { - ch = fifo_push(EVENTLIST_1st(evl)); - if (ch == ERR) { - peek = head; /* the keys stay uninterpreted */ - return ERR; - } -#ifdef NCURSES_WGETCH_EVENTS - else if (ch == KEY_EVENT) { - peek = head; /* the keys stay uninterpreted */ - return fifo_pull(); /* Remove KEY_EVENT from the queue */ - } -#endif - } - - ch = fifo_peek(); - if (ch >= KEY_MIN) { - /* If not first in queue, somebody put this key there on purpose in - * emergency. Consider it higher priority than the unfinished - * keysequence we are parsing. - */ - peek = head; - /* assume the key is the last in fifo */ - t_dec(); /* remove the key */ - return ch; - } - - TR(TRACE_IEVENT, ("ch: %s", _tracechar((unsigned char) ch))); - while ((ptr != NULL) && (ptr->ch != (unsigned char) ch)) - ptr = ptr->sibling; - - if (ptr == NULL) { - TR(TRACE_IEVENT, ("ptr is null")); - break; - } - TR(TRACE_IEVENT, ("ptr=%p, ch=%d, value=%d", - ptr, ptr->ch, ptr->value)); - - if (ptr->value != 0) { /* sequence terminated */ - TR(TRACE_IEVENT, ("end of sequence")); - if (peek == tail) - fifo_clear(); - else - head = peek; - return (ptr->value); - } - - ptr = ptr->child; - - if (!raw_key_in_fifo()) { - int rc; - - TR(TRACE_IEVENT, ("waiting for rest of sequence")); - rc = _nc_timed_wait(TWAIT_MASK, - timeleft, - &timeleft - EVENTLIST_2nd(evl)); -#ifdef NCURSES_WGETCH_EVENTS - if (rc & 4) { - TR(TRACE_IEVENT, ("interrupted by a user event")); - /* FIXME Should have preserved timeleft for reusal... */ - peek = head; /* Restart interpreting later */ - return KEY_EVENT; - } -#endif - if (!rc) { - TR(TRACE_IEVENT, ("ran out of time")); - break; - } - } - } - ch = fifo_pull(); - peek = head; - return ch; -} |