static inline int fifo_push(void) { int n; unsigned int ch; if (tail == -1) return ERR; #ifdef HIDE_EINTR again: errno = 0; #endif #if USE_GPM_SUPPORT || defined(USE_EMX_MOUSE) if ((SP->_mouse_fd >= 0) && (_nc_timed_wait(3, -1, (int *) 0) & 2)) { SP->_mouse_event(SP); ch = KEY_MOUSE; n = 1; } else #endif { unsigned char c2 = 0; n = read(SP->_ifd, &c2, 1); ch = c2 & 0xff; } #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 %#x at %d", ch, tail)); #ifdef TRACE if (_nc_tracing & TRACE_IEVENT) _nc_fifo_dump(); #endif return ch; }
/* * 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 rc = TCBOf(sp)->drv->testmouse(TCBOf(sp), delay EVENTLIST_2nd(evl)); #else #if USE_SYSMOUSE if ((sp->_mouse_type == M_SYSMOUSE) && (sp->_sysmouse_head < sp->_sysmouse_tail)) { rc = TW_MOUSE; } else #endif { rc = _nc_timed_wait(sp, TWAIT_MASK, delay, (int *) 0 EVENTLIST_2nd(evl)); #if USE_SYSMOUSE if ((sp->_mouse_type == M_SYSMOUSE) && (sp->_sysmouse_head < sp->_sysmouse_tail) && (rc == 0) && (errno == EINTR)) { rc |= TW_MOUSE; } #endif } #endif return rc; }
int delay_output(int ms) { T((T_CALLED("delay_output(%d)"), ms)); if (cur_term == 0 || cur_term->_baudrate <= 0) { (void) fflush(OUTPUT); _nc_timed_wait(0, ms, (int *)0); } #ifdef no_pad_char else if (no_pad_char) napms(ms); #endif /* no_pad_char */ else { register int nullcount; char null = '\0'; #ifdef pad_char if (pad_char) null = pad_char[0]; #endif /* pad_char */ nullcount = ms * cur_term->_baudrate / 10000; for (_nc_nulls_sent += nullcount; nullcount > 0; nullcount--) my_outch(null); if (my_outch == _nc_outch) (void) fflush(OUTPUT); } returnCode(OK); }
NCURSES_SP_NAME(napms) (NCURSES_SP_DCLx int ms) { (void) SP_PARM; T((T_CALLED("napms(%d)"), ms)); #ifdef USE_TERM_DRIVER CallDriver_1(SP_PARM, nap, ms); #else /* !USE_TERM_DRIVER */ #if HAVE_NANOSLEEP { struct timespec request, remaining; request.tv_sec = ms / 1000; request.tv_nsec = (ms % 1000) * 1000000; while (nanosleep(&request, &remaining) == -1 && errno == EINTR) { request = remaining; } } #else _nc_timed_wait(0, 0, ms, (int *) 0 EVENTLIST_2nd(0)); #endif #endif /* !USE_TERM_DRIVER */ returnCode(OK); }
napms(int ms) { T((T_CALLED("napms(%d)"), ms)); #if HAVE_NANOSLEEP { struct timespec request, remaining; request.tv_sec = ms / 1000; request.tv_nsec = (ms % 1000) * 1000000; while (nanosleep(&request, &remaining) == -1 && errno == EINTR) { request = remaining; } } #else _nc_timed_wait(0, 0, ms, (int *) 0 EVENTLIST_2nd(0)); #endif returnCode(OK); }
/* * 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)); # ifdef __MINGW32__ /* 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 #if USE_SYSMOUSE if ((sp->_mouse_type == M_SYSMOUSE) && (sp->_sysmouse_head < sp->_sysmouse_tail)) { rc = TW_MOUSE; } else #endif { rc = _nc_timed_wait(sp, TWAIT_MASK, delay, (int *) 0 EVENTLIST_2nd(evl)); #if USE_SYSMOUSE if ((sp->_mouse_type == M_SYSMOUSE) && (sp->_sysmouse_head < sp->_sysmouse_tail) && (rc == 0) && (errno == EINTR)) { rc |= TW_MOUSE; } #endif } #endif return rc; }
/* * Check for mouse activity, returning nonzero if we find any. */ static int check_mouse_activity(int delay EVENTLIST_2nd(_nc_eventlist * evl)) { int rc; #if USE_SYSMOUSE if ((SP->_mouse_type == M_SYSMOUSE) && (SP->_sysmouse_head < SP->_sysmouse_tail)) { return 2; } #endif rc = _nc_timed_wait(TWAIT_MASK, delay, (int *) 0 EVENTLIST_2nd(evl)); #if USE_SYSMOUSE if ((SP->_mouse_type == M_SYSMOUSE) && (SP->_sysmouse_head < SP->_sysmouse_tail) && (rc == 0) && (errno == EINTR)) { rc |= 2; } #endif return rc; }
int wgetch(WINDOW *win) { int ch; T((T_CALLED("wgetch(%p)"), win)); if (!win) returnCode(ERR); if (cooked_key_in_fifo()) { if (wgetch_should_refresh(win)) wrefresh(win); ch = fifo_pull(); T(("wgetch returning (pre-cooked): %#x = %s", ch, _trace_key(ch))); returnCode(ch); } /* * 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; TR(TRACE_IEVENT, ("filling queue in cooked mode")); wgetnstr(win, buf, MAXCOLUMNS); /* ungetch in reverse order */ ungetch('\n'); for (sp = buf + strlen(buf); sp > buf; sp--) ungetch(sp[-1]); returnCode(fifo_pull()); } 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; TR(TRACE_IEVENT, ("delay is %d milliseconds", delay)); if (head == -1) /* fifo is empty */ if (!_nc_timed_wait(3, delay, (int *) 0)) 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; do { ch = kgetch(win); if (ch == KEY_MOUSE) { ++runcount; if (SP->_mouse_inline(SP)) break; } } while (ch == KEY_MOUSE && (_nc_timed_wait(3, SP->_maxclick, (int *) 0) || !SP->_mouse_parse(runcount))); if (runcount > 0 && ch != KEY_MOUSE) { /* mouse event sequence ended by keystroke, push it */ ungetch(ch); ch = KEY_MOUSE; } } else { if (head == -1) fifo_push(); 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()) { ch = fifo_pull(); T(("wgetch returning (pre-cooked): %#x = %s", ch, _trace_key(ch))); returnCode(ch); } } #endif T(("wgetch returning ERR")); 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 ((ch < KEY_MIN) && (ch & 0x80)) if (!SP->_use_meta) ch &= 0x7f; T(("wgetch returning : %#x = %s", ch, _trace_key(ch))); returnCode(ch); }