+ int n;
+ int ch = 0;
+ int mask = 0;
+
+ (void) mask;
+ if (tail < 0)
+ return ERR;
+
+#ifdef NCURSES_WGETCH_EVENTS
+ if (evl
+#if USE_GPM_SUPPORT || USE_EMX_MOUSE || USE_SYSMOUSE
+ || (sp->_mouse_fd >= 0)
+#endif
+ ) {
+ mask = check_mouse_activity(sp, -1 EVENTLIST_2nd(evl));
+ } else
+ mask = 0;
+
+ if (mask & TW_EVENT) {
+ T(("fifo_push: ungetch KEY_EVENT"));
+ safe_ungetch(sp, KEY_EVENT);
+ return KEY_EVENT;
+ }
+#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 || 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... */
+#ifdef USE_TERM_DRIVER
+ int buf;
+#ifdef _WIN32
+ if (NC_ISATTY(sp->_ifd) && IsTermInfoOnConsole(sp) && sp->_cbreak)
+ n = _nc_mingw_console_read(sp,
+ _nc_get_handle(sp->_ifd),
+ &buf);
+ else
+#endif
+ n = CallDriver_1(sp, td_read, &buf);
+ ch = buf;
+#else
+ unsigned char c2 = 0;
+# if USE_PTHREADS_EINTR
+# if USE_WEAK_SYMBOLS
+ if ((pthread_self) && (pthread_kill) && (pthread_equal))
+# endif
+ _nc_globals.read_thread = pthread_self();
+# endif
+ n = (int) read(sp->_ifd, &c2, (size_t) 1);
+#if USE_PTHREADS_EINTR
+ _nc_globals.read_thread = 0;
+#endif
+ ch = c2;
+#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", _nc_tracechar(sp, ch), tail));
+#ifdef TRACE
+ if (USE_TRACEF(TRACE_IEVENT)) {
+ _nc_fifo_dump(sp);
+ _nc_unlock_global(tracef);
+ }
+#endif
+ return ch;