X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fbase%2Flib_getch.c;h=38537591afc0ab8bda04ed5ec382ba0292453584;hp=757703d8afeaebb756eda4f400257651e307c170;hb=fae162795e065e5901068152e91f2962b6b247f3;hpb=46722468f47c2b77b3987729b4bcf2321cccfd01 diff --git a/ncurses/base/lib_getch.c b/ncurses/base/lib_getch.c index 757703d8..38537591 100644 --- a/ncurses/base/lib_getch.c +++ b/ncurses/base/lib_getch.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc. * + * Copyright 2018-2019,2020 Thomas E. Dickey * + * Copyright 1998-2015,2016 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 * @@ -29,6 +30,8 @@ /**************************************************************************** * Author: Zeyd M. Ben-Halim 1992,1995 * * and: Eric S. Raymond * + * and: Thomas E. Dickey 1996-on * + * and: Juergen Pfeifer 2009 * ****************************************************************************/ /* @@ -38,170 +41,431 @@ ** */ +#define NEED_KEY_EVENT #include -MODULE_ID("$Id: lib_getch.c,v 1.67 2002/09/07 17:17:59 tom Exp $") +MODULE_ID("$Id: lib_getch.c,v 1.141 2020/09/05 22:50:47 tom Exp $") #include -NCURSES_EXPORT_VAR(int) -ESCDELAY = 1000; /* max interval betw. chars in funkeys, in millisecs */ +#if USE_REENTRANT +#define GetEscdelay(sp) *_nc_ptr_Escdelay(sp) +NCURSES_EXPORT(int) +NCURSES_PUBLIC_VAR(ESCDELAY) (void) +{ + return *(_nc_ptr_Escdelay(CURRENT_SCREEN)); +} -#ifdef NCURSES_WGETCH_EVENTS -#define TWAIT_MASK 7 +NCURSES_EXPORT(int *) +_nc_ptr_Escdelay(SCREEN *sp) +{ + return ptrEscdelay(sp); +} +#else +#define GetEscdelay(sp) ESCDELAY +NCURSES_EXPORT_VAR(int) ESCDELAY = 1000; +#endif + +#if NCURSES_EXT_FUNCS +NCURSES_EXPORT(int) +NCURSES_SP_NAME(set_escdelay) (NCURSES_SP_DCLx int value) +{ + int code = OK; + if (value < 0) { + code = ERR; + } else { +#if USE_REENTRANT + if (SP_PARM) { + SET_ESCDELAY(value); + } else { + code = ERR; + } +#else + (void) SP_PARM; + ESCDELAY = value; +#endif + } + return code; +} + +#if NCURSES_SP_FUNCS +NCURSES_EXPORT(int) +set_escdelay(int value) +{ + int code; + if (value < 0) { + code = ERR; + } else { +#if USE_REENTRANT + code = NCURSES_SP_NAME(set_escdelay) (CURRENT_SCREEN, value); #else -#define TWAIT_MASK 3 + ESCDELAY = value; + code = OK; #endif + } + return code; +} +#endif +#endif /* NCURSES_EXT_FUNCS */ -static inline int -fifo_peek(void) +#if NCURSES_EXT_FUNCS +NCURSES_EXPORT(int) +NCURSES_SP_NAME(get_escdelay) (NCURSES_SP_DCL0) { - int ch = SP->_fifo[peek]; +#if !USE_REENTRANT + (void) SP_PARM; +#endif + return GetEscdelay(SP_PARM); +} + +#if NCURSES_SP_FUNCS +NCURSES_EXPORT(int) +get_escdelay(void) +{ + return NCURSES_SP_NAME(get_escdelay) (CURRENT_SCREEN); +} +#endif +#endif /* NCURSES_EXT_FUNCS */ + +static int +_nc_use_meta(WINDOW *win) +{ + SCREEN *sp = _nc_screen_of(win); + return (sp ? sp->_use_meta : 0); +} + +#ifdef USE_TERM_DRIVER +# if defined(_NC_WINDOWS) && !defined(EXP_WIN32_DRIVER) +static HANDLE +_nc_get_handle(int fd) +{ + intptr_t value = _get_osfhandle(fd); + return (HANDLE) value; +} +# endif +#endif + +/* + * Check for mouse activity, returning nonzero if we find any. + */ +static int +check_mouse_activity(SCREEN *sp, int delay EVENTLIST_2nd(_nc_eventlist * evl)) +{ + int rc; + +#ifdef USE_TERM_DRIVER + TERMINAL_CONTROL_BLOCK *TCB = TCBOf(sp); + rc = TCBOf(sp)->drv->td_testmouse(TCBOf(sp), delay EVENTLIST_2nd(evl)); +# if defined(EXP_WIN32_DRIVER) + /* if we emulate terminfo on console, we have to use the console routine */ + if (IsTermInfoOnConsole(sp)) { + rc = _nc_console_testmouse(sp, + _nc_console_handle(sp->_ifd), + delay EVENTLIST_2nd(evl)); + } else +# elif defined(_NC_WINDOWS) + /* if we emulate terminfo on console, we have to use the console routine */ + if (IsTermInfoOnConsole(sp)) { + HANDLE fd = _nc_get_handle(sp->_ifd); + rc = _nc_mingw_testmouse(sp, fd, delay EVENTLIST_2nd(evl)); + } else +# endif + rc = TCB->drv->td_testmouse(TCB, delay EVENTLIST_2nd(evl)); +#else /* !USE_TERM_DRIVER */ +# if USE_SYSMOUSE + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail)) { + rc = TW_MOUSE; + } else +# endif + { +# if defined(EXP_WIN32_DRIVER) + rc = _nc_console_testmouse(sp, + _nc_console_handle(sp->_ifd), + delay + EVENTLIST_2nd(evl)); +# else + rc = _nc_timed_wait(sp, + TWAIT_MASK, + delay, + (int *) 0 + EVENTLIST_2nd(evl)); +# endif +# if USE_SYSMOUSE + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail) + && (rc == 0) + && (errno == EINTR)) { + rc |= TW_MOUSE; + } +# endif + } +#endif /* USE_TERM_DRIVER */ + return rc; +} + +static NCURSES_INLINE int +fifo_peek(SCREEN *sp) +{ + int ch = (peek >= 0) ? sp->_fifo[peek] : ERR; TR(TRACE_IEVENT, ("peeking at %d", peek)); p_inc(); return ch; } -static inline int -fifo_pull(void) +static NCURSES_INLINE int +fifo_pull(SCREEN *sp) { - int ch; - ch = SP->_fifo[head]; - TR(TRACE_IEVENT, ("pulling %s from %d", _tracechar(ch), head)); + int ch = (head >= 0) ? sp->_fifo[head] : ERR; + + TR(TRACE_IEVENT, ("pulling %s from %d", _nc_tracechar(sp, ch), head)); if (peek == head) { h_inc(); peek = head; - } else + } else { h_inc(); + } #ifdef TRACE - if (_nc_tracing & TRACE_IEVENT) - _nc_fifo_dump(); + if (USE_TRACEF(TRACE_IEVENT)) { + _nc_fifo_dump(sp); + _nc_unlock_global(tracef); + } #endif return ch; } -static inline int -fifo_push(EVENTLIST_0th(_nc_eventlist * evl)) +static NCURSES_INLINE int +fifo_push(SCREEN *sp EVENTLIST_2nd(_nc_eventlist * evl)) { int n; int ch = 0; - int mask; + int mask = 0; (void) mask; - if (tail == -1) + if (tail < 0) 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) +#if USE_GPM_SUPPORT || USE_EMX_MOUSE || USE_SYSMOUSE + || (sp->_mouse_fd >= 0) #endif ) { - mask = _nc_timed_wait(TWAIT_MASK, -1, (int *) 0, evl); + mask = check_mouse_activity(sp, -1 EVENTLIST_2nd(evl)); } else mask = 0; - if (mask & 4) { + if (mask & TW_EVENT) { T(("fifo_push: ungetch KEY_EVENT")); - ungetch(KEY_EVENT); + safe_ungetch(sp, 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)); +#elif USE_GPM_SUPPORT || USE_EMX_MOUSE || USE_SYSMOUSE + if (sp->_mouse_fd >= 0) { + mask = check_mouse_activity(sp, -1 EVENTLIST_2nd(evl)); + } #endif -#if USE_GPM_SUPPORT || defined(USE_EMX_MOUSE) - if ((SP->_mouse_fd >= 0) && (mask & 2)) { - SP->_mouse_event(SP); +#if USE_GPM_SUPPORT || USE_EMX_MOUSE + if ((sp->_mouse_fd >= 0) && (mask & TW_MOUSE)) { + sp->_mouse_event(sp); + ch = KEY_MOUSE; + n = 1; + } else +#endif +#if USE_SYSMOUSE + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail)) { + sp->_mouse_event(sp); ch = KEY_MOUSE; n = 1; + } else if ((sp->_mouse_type == M_SYSMOUSE) + && (mask <= 0) && errno == EINTR) { + sp->_mouse_event(sp); + ch = KEY_MOUSE; + n = 1; + } else +#endif +#ifdef USE_TERM_DRIVER + if ((sp->_mouse_type == M_TERM_DRIVER) + && (sp->_drv_mouse_head < sp->_drv_mouse_tail)) { + sp->_mouse_event(sp); + ch = KEY_MOUSE; + n = 1; + } else +#endif +#if USE_KLIBC_KBD + if (NC_ISATTY(sp->_ifd) && sp->_cbreak) { + ch = _read_kbd(0, 1, !sp->_raw); + n = (ch == -1) ? -1 : 1; + sp->_extended_key = (ch == 0); } else #endif { /* Can block... */ +#if defined(USE_TERM_DRIVER) + int buf; +# if defined(EXP_WIN32_DRIVER) + if (NC_ISATTY(sp->_ifd) && IsTermInfoOnConsole(sp) && sp->_cbreak) { +# if USE_PTHREADS_EINTR + if ((pthread_self) && (pthread_kill) && (pthread_equal)) + _nc_globals.read_thread = pthread_self(); +# endif + n = _nc_console_read(sp, + _nc_console_handle(sp->_ifd), + &buf); +# if USE_PTHREADS_EINTR + _nc_globals.read_thread = 0; +# endif + } else +# elif defined(_NC_WINDOWS) + if (NC_ISATTY(sp->_ifd) && IsTermInfoOnConsole(sp) && sp->_cbreak) + n = _nc_mingw_console_read(sp, + _nc_get_handle(sp->_ifd), + &buf); + else +# endif /* EXP_WIN32_DRIVER */ + n = CallDriver_1(sp, td_read, &buf); + ch = buf; +#else /* !USE_TERM_DRIVER */ +#if defined(EXP_WIN32_DRIVER) + int buf; +#endif unsigned char c2 = 0; - n = read(SP->_ifd, &c2, 1); +#if USE_PTHREADS_EINTR +#if USE_WEAK_SYMBOLS + if ((pthread_self) && (pthread_kill) && (pthread_equal)) +#endif + _nc_globals.read_thread = pthread_self(); +#endif +#if defined(EXP_WIN32_DRIVER) + n = _nc_console_read(sp, + _nc_console_handle(sp->_ifd), + &buf); + c2 = buf; +#else + n = (int) read(sp->_ifd, &c2, (size_t) 1); +#endif +#if USE_PTHREADS_EINTR + _nc_globals.read_thread = 0; +#endif ch = c2; +#endif /* USE_TERM_DRIVER */ } -#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)); + 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; + 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)); + TR(TRACE_IEVENT, ("pushed %s at %d", _nc_tracechar(sp, ch), tail)); #ifdef TRACE - if (_nc_tracing & TRACE_IEVENT) - _nc_fifo_dump(); + if (USE_TRACEF(TRACE_IEVENT)) { + _nc_fifo_dump(sp); + _nc_unlock_global(tracef); + } #endif return ch; } -static inline void -fifo_clear(void) +static NCURSES_INLINE void +fifo_clear(SCREEN *sp) { - memset(SP->_fifo, 0, sizeof(SP->_fifo)); + memset(sp->_fifo, 0, sizeof(sp->_fifo)); head = -1; tail = peek = 0; } -static int kgetch(EVENTLIST_0th(_nc_eventlist * evl)); +static int kgetch(SCREEN *, bool EVENTLIST_2nd(_nc_eventlist *)); + +static void +recur_wrefresh(WINDOW *win) +{ +#ifdef USE_PTHREADS + SCREEN *sp = _nc_screen_of(win); + if (_nc_use_pthreads && sp != CURRENT_SCREEN) { + SCREEN *save_SP; + + /* temporarily switch to the window's screen to check/refresh */ + _nc_lock_global(curses); + save_SP = CURRENT_SCREEN; + _nc_set_screen(sp); + recur_wrefresh(win); + _nc_set_screen(save_SP); + _nc_unlock_global(curses); + } else +#endif + if ((is_wintouched(win) || (win->_flags & _HASMOVED)) + && !(win->_flags & _ISPAD)) { + wrefresh(win); + } +} -#define wgetch_should_refresh(win) (\ - (is_wintouched(win) || (win->_flags & _HASMOVED)) \ - && !(win->_flags & _ISPAD)) +static int +recur_wgetnstr(WINDOW *win, char *buf) +{ + SCREEN *sp = _nc_screen_of(win); + int rc; + + if (sp != 0) { +#ifdef USE_PTHREADS + if (_nc_use_pthreads && sp != CURRENT_SCREEN) { + SCREEN *save_SP; + + /* temporarily switch to the window's screen to get cooked input */ + _nc_lock_global(curses); + save_SP = CURRENT_SCREEN; + _nc_set_screen(sp); + rc = recur_wgetnstr(win, buf); + _nc_set_screen(save_SP); + _nc_unlock_global(curses); + } else +#endif + { + sp->_called_wgetch = TRUE; + rc = wgetnstr(win, buf, MAXCOLUMNS); + sp->_called_wgetch = FALSE; + } + } else { + rc = ERR; + } + return rc; +} NCURSES_EXPORT(int) _nc_wgetch(WINDOW *win, - unsigned long *result, + int *result, int use_meta EVENTLIST_2nd(_nc_eventlist * evl)) { + SCREEN *sp; int ch; + int rc = 0; #ifdef NCURSES_WGETCH_EVENTS - long event_delay = -1; + int event_delay = -1; #endif - T((T_CALLED("_nc_wgetch(%p)"), win)); + T((T_CALLED("_nc_wgetch(%p)"), (void *) win)); *result = 0; - if (!win) + + sp = _nc_screen_of(win); + if (win == 0 || sp == 0) { returnCode(ERR); + } if (cooked_key_in_fifo()) { - if (wgetch_should_refresh(win)) - wrefresh(win); - - *result = fifo_pull(); - returnCode(OK); + recur_wrefresh(win); + *result = fifo_pull(sp); + returnCode(*result >= KEY_MIN ? KEY_CODE_YES : OK); } #ifdef NCURSES_WGETCH_EVENTS if (evl && (evl->count == 0)) @@ -214,70 +478,70 @@ _nc_wgetch(WINDOW *win, * 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; + if (head == -1 && + !sp->_notty && + !sp->_raw && + !sp->_cbreak && + !sp->_called_wgetch) { + char buf[MAXCOLUMNS], *bufp; 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) + rc = recur_wgetnstr(win, buf); + if (rc != KEY_EVENT && rc != ERR) + safe_ungetch(sp, '\n'); +#else + if (recur_wgetnstr(win, buf) != ERR) + safe_ungetch(sp, '\n'); #endif - ungetch('\n'); - for (sp = buf + strlen(buf); sp > buf; sp--) - ungetch(sp[-1]); + for (bufp = buf + strlen(buf); bufp > buf; bufp--) + safe_ungetch(sp, bufp[-1]); #ifdef NCURSES_WGETCH_EVENTS /* Return it first */ if (rc == KEY_EVENT) { *result = rc; - returnCode(OK); - } + } else #endif - - *result = fifo_pull(); - returnCode(OK); + *result = fifo_pull(sp); + returnCode(*result >= KEY_MIN ? KEY_CODE_YES : OK); } - if (win->_use_keypad != SP->_keypad_on) - _nc_keypad(win->_use_keypad); + if (win->_use_keypad != sp->_keypad_on) + _nc_keypad(sp, win->_use_keypad); - if (wgetch_should_refresh(win)) - wrefresh(win); + recur_wrefresh(win); - if (!win->_notimeout && (win->_delay >= 0 || SP->_cbreak > 1)) { - int delay; + if (win->_notimeout || (win->_delay >= 0) || (sp->_cbreak > 1)) { + if (head == -1) { /* fifo is empty */ + int delay; - TR(TRACE_IEVENT, ("timed delay in wgetch()")); - if (SP->_cbreak > 1) - delay = (SP->_cbreak - 1) * 100; - else - delay = win->_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; + if (event_delay >= 0 && delay > event_delay) + delay = event_delay; #endif - TR(TRACE_IEVENT, ("delay is %d milliseconds", delay)); + 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)); + rc = check_mouse_activity(sp, delay EVENTLIST_2nd(evl)); #ifdef NCURSES_WGETCH_EVENTS - if (rc & 4) { + if (rc & TW_EVENT) { *result = KEY_EVENT; - returnCode(OK); + returnCode(KEY_CODE_YES); } #endif - if (!rc) - returnCode(ERR); + if (!rc) { + goto check_sigwinch; + } } /* else go on to read data available */ } @@ -295,28 +559,25 @@ _nc_wgetch(WINDOW *win, * increase the wait with mouseinterval(). */ int runcount = 0; - int rc; do { - ch = kgetch(EVENTLIST_1st(evl)); + ch = kgetch(sp, win->_notimeout EVENTLIST_2nd(evl)); if (ch == KEY_MOUSE) { ++runcount; - if (SP->_mouse_inline(SP)) + if (sp->_mouse_inline(sp)) break; } - if (SP->_maxclick < 0) + 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))); + && (((rc = check_mouse_activity(sp, sp->_maxclick + EVENTLIST_2nd(evl))) != 0 + && !(rc & TW_EVENT)) + || !sp->_mouse_parse(sp, runcount))); #ifdef NCURSES_WGETCH_EVENTS - if ((rc & 4) && !ch == KEY_EVENT) { - ungetch(ch); + if ((rc & TW_EVENT) && !(ch == KEY_EVENT)) { + safe_ungetch(sp, ch); ch = KEY_EVENT; } #endif @@ -324,28 +585,35 @@ _nc_wgetch(WINDOW *win, #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... */ + safe_ungetch(sp, KEY_MOUSE); /* FIXME This interrupts a gesture... */ } else #endif { /* mouse event sequence ended by keystroke, store keystroke */ - ungetch(ch); + safe_ungetch(sp, ch); ch = KEY_MOUSE; } } } else { if (head == -1) - fifo_push(EVENTLIST_1st(evl)); - ch = fifo_pull(); + fifo_push(sp EVENTLIST_2nd(evl)); + ch = fifo_pull(sp); } if (ch == ERR) { + check_sigwinch: #if USE_SIZECHANGE - if (SP->_sig_winch) { - _nc_update_screensize(); + if (_nc_handle_sigwinch(sp)) { + _nc_update_screensize(sp); /* resizeterm can push KEY_RESIZE */ if (cooked_key_in_fifo()) { - *result = fifo_pull(); + *result = fifo_pull(sp); + /* + * Get the ERR from queue -- it is from WINCH, + * so we should take it out, the "error" is handled. + */ + if (fifo_peek(sp) == -1) + fifo_pull(sp); returnCode(*result >= KEY_MIN ? KEY_CODE_YES : OK); } } @@ -360,7 +628,7 @@ _nc_wgetch(WINDOW *win, * * 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. + * 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. * @@ -371,8 +639,8 @@ _nc_wgetch(WINDOW *win, * 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 (sp->_echo && !(win->_flags & _ISPAD)) { + chtype backup = (chtype) ((ch == KEY_BACKSPACE) ? '\b' : ch); if (backup < KEY_MIN) wechochar(win, backup); } @@ -380,7 +648,7 @@ _nc_wgetch(WINDOW *win, /* * Simulate ICRNL mode */ - if ((ch == '\r') && SP->_nl) + if ((ch == '\r') && sp->_nl) ch = '\n'; /* Strip 8th-bit if so desired. We do this only for characters that @@ -392,7 +660,7 @@ _nc_wgetch(WINDOW *win, if ((ch < KEY_MIN) && (ch & 0x80)) ch &= 0x7f; - T(("wgetch returning : %s", _tracechar(ch))); + T(("wgetch returning : %s", _nc_tracechar(sp, ch))); *result = ch; returnCode(ch >= KEY_MIN ? KEY_CODE_YES : OK); @@ -403,12 +671,12 @@ NCURSES_EXPORT(int) wgetch_events(WINDOW *win, _nc_eventlist * evl) { int code; - unsigned long value; + int value; - T((T_CALLED("wgetch_events(%p,%p)"), win, evl)); + T((T_CALLED("wgetch_events(%p,%p)"), (void *) win, (void *) evl)); code = _nc_wgetch(win, &value, - SP->_use_meta + _nc_use_meta(win) EVENTLIST_2nd(evl)); if (code != ERR) code = value; @@ -420,12 +688,12 @@ NCURSES_EXPORT(int) wgetch(WINDOW *win) { int code; - unsigned long value; + int value; - T((T_CALLED("wgetch(%p)"), win)); + T((T_CALLED("wgetch(%p)"), (void *) win)); code = _nc_wgetch(win, &value, - SP->_use_meta + _nc_use_meta(win) EVENTLIST_2nd((_nc_eventlist *) 0)); if (code != ERR) code = value; @@ -448,21 +716,21 @@ wgetch(WINDOW *win) */ static int -kgetch(EVENTLIST_0th(_nc_eventlist * evl)) +kgetch(SCREEN *sp, bool forever EVENTLIST_2nd(_nc_eventlist * evl)) { - struct tries *ptr; + TRIES *ptr; int ch = 0; - int timeleft = ESCDELAY; + int timeleft = forever ? 9999999 : GetEscdelay(sp); TR(TRACE_IEVENT, ("kgetch() called")); - ptr = SP->_keytry; + ptr = sp->_keytry; for (;;) { - if (cooked_key_in_fifo() && SP->_fifo[head] >= KEY_MIN) { + if (cooked_key_in_fifo() && sp->_fifo[head] >= KEY_MIN) { break; } else if (!raw_key_in_fifo()) { - ch = fifo_push(EVENTLIST_1st(evl)); + ch = fifo_push(sp EVENTLIST_2nd(evl)); if (ch == ERR) { peek = head; /* the keys stay uninterpreted */ return ERR; @@ -470,12 +738,12 @@ kgetch(EVENTLIST_0th(_nc_eventlist * evl)) #ifdef NCURSES_WGETCH_EVENTS else if (ch == KEY_EVENT) { peek = head; /* the keys stay uninterpreted */ - return fifo_pull(); /* Remove KEY_EVENT from the queue */ + return fifo_pull(sp); /* Remove KEY_EVENT from the queue */ } #endif } - ch = fifo_peek(); + ch = fifo_peek(sp); 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 @@ -487,7 +755,7 @@ kgetch(EVENTLIST_0th(_nc_eventlist * evl)) return ch; } - TR(TRACE_IEVENT, ("ch: %s", _tracechar((unsigned char) ch))); + TR(TRACE_IEVENT, ("ch: %s", _nc_tracechar(sp, (unsigned char) ch))); while ((ptr != NULL) && (ptr->ch != (unsigned char) ch)) ptr = ptr->sibling; @@ -496,14 +764,15 @@ kgetch(EVENTLIST_0th(_nc_eventlist * evl)) break; } TR(TRACE_IEVENT, ("ptr=%p, ch=%d, value=%d", - ptr, ptr->ch, ptr->value)); + (void *) ptr, ptr->ch, ptr->value)); if (ptr->value != 0) { /* sequence terminated */ TR(TRACE_IEVENT, ("end of sequence")); - if (peek == tail) - fifo_clear(); - else + if (peek == tail) { + fifo_clear(sp); + } else { head = peek; + } return (ptr->value); } @@ -513,14 +782,11 @@ kgetch(EVENTLIST_0th(_nc_eventlist * evl)) int rc; TR(TRACE_IEVENT, ("waiting for rest of sequence")); - rc = _nc_timed_wait(TWAIT_MASK, - timeleft, - &timeleft - EVENTLIST_2nd(evl)); + rc = check_mouse_activity(sp, timeleft EVENTLIST_2nd(evl)); #ifdef NCURSES_WGETCH_EVENTS - if (rc & 4) { + if (rc & TW_EVENT) { TR(TRACE_IEVENT, ("interrupted by a user event")); - /* FIXME Should have preserved timeleft for reusal... */ + /* FIXME Should have preserved remainder timeleft for reuse... */ peek = head; /* Restart interpreting later */ return KEY_EVENT; } @@ -531,7 +797,7 @@ kgetch(EVENTLIST_0th(_nc_eventlist * evl)) } } } - ch = fifo_pull(); + ch = fifo_pull(sp); peek = head; return ch; }