150276Speter/****************************************************************************
2262685Sdelphij * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc.              *
350276Speter *                                                                          *
450276Speter * Permission is hereby granted, free of charge, to any person obtaining a  *
550276Speter * copy of this software and associated documentation files (the            *
650276Speter * "Software"), to deal in the Software without restriction, including      *
750276Speter * without limitation the rights to use, copy, modify, merge, publish,      *
850276Speter * distribute, distribute with modifications, sublicense, and/or sell       *
950276Speter * copies of the Software, and to permit persons to whom the Software is    *
1050276Speter * furnished to do so, subject to the following conditions:                 *
1150276Speter *                                                                          *
1250276Speter * The above copyright notice and this permission notice shall be included  *
1350276Speter * in all copies or substantial portions of the Software.                   *
1450276Speter *                                                                          *
1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2250276Speter *                                                                          *
2350276Speter * Except as contained in this notice, the name(s) of the above copyright   *
2450276Speter * holders shall not be used in advertising or otherwise to promote the     *
2550276Speter * sale, use or other dealings in this Software without prior written       *
2650276Speter * authorization.                                                           *
2750276Speter ****************************************************************************/
2850276Speter
2950276Speter/****************************************************************************
3050276Speter *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
3150276Speter *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
32174993Srafan *     and: Thomas E. Dickey                        1996-on                 *
3350276Speter ****************************************************************************/
3450276Speter
3550276Speter/*
3650276Speter**	lib_twait.c
3750276Speter**
3850276Speter**	The routine _nc_timed_wait().
3950276Speter**
4050276Speter**	(This file was originally written by Eric Raymond; however except for
4150276Speter**	comments, none of the original code remains - T.Dickey).
4250276Speter*/
4350276Speter
4497049Speter#include <curses.priv.h>
4597049Speter
46184989Srafan#if defined __HAIKU__ && defined __BEOS__
47184989Srafan#undef __BEOS__
48184989Srafan#endif
49184989Srafan
5056639Speter#ifdef __BEOS__
5197049Speter#undef false
5297049Speter#undef true
5356639Speter#include <OS.h>
5456639Speter#endif
5556639Speter
56262685Sdelphij#if USE_KLIBC_KBD
57262685Sdelphij#define INCL_KBD
58262685Sdelphij#include <os2.h>
59262685Sdelphij#endif
60262685Sdelphij
6150276Speter#if USE_FUNC_POLL
6250276Speter# if HAVE_SYS_TIME_H
6350276Speter#  include <sys/time.h>
6450276Speter# endif
6550276Speter#elif HAVE_SELECT
6650276Speter# if HAVE_SYS_TIME_H && HAVE_SYS_TIME_SELECT
6750276Speter#  include <sys/time.h>
6850276Speter# endif
6950276Speter# if HAVE_SYS_SELECT_H
7050276Speter#  include <sys/select.h>
7150276Speter# endif
7250276Speter#endif
73262629Sdelphij#ifdef __MINGW32__
74262629Sdelphij#  include <sys/time.h>
75262629Sdelphij#endif
76184989Srafan#undef CUR
7750276Speter
78262685SdelphijMODULE_ID("$Id: lib_twait.c,v 1.67 2013/02/18 09:22:27 tom Exp $")
79184989Srafan
8066963Speterstatic long
81262685Sdelphij_nc_gettime(TimeType * t0, int first)
8250276Speter{
8366963Speter    long res;
8450276Speter
85174993Srafan#if PRECISE_GETTIME
86174993Srafan    TimeType t1;
8766963Speter    gettimeofday(&t1, (struct timezone *) 0);
8866963Speter    if (first) {
89174993Srafan	*t0 = t1;
90166124Srafan	res = 0;
91166124Srafan    } else {
92166124Srafan	/* .tv_sec and .tv_usec are unsigned, be careful when subtracting */
93174993Srafan	if (t0->tv_usec > t1.tv_usec) {
94174993Srafan	    t1.tv_usec += 1000000;	/* Convert 1s in 1e6 microsecs */
95166124Srafan	    t1.tv_sec--;
96166124Srafan	}
97174993Srafan	res = (t1.tv_sec - t0->tv_sec) * 1000
98174993Srafan	    + (t1.tv_usec - t0->tv_usec) / 1000;
9966963Speter    }
10050276Speter#else
10166963Speter    time_t t1 = time((time_t *) 0);
10266963Speter    if (first) {
103174993Srafan	*t0 = t1;
10466963Speter    }
105174993Srafan    res = (t1 - *t0) * 1000;
10650276Speter#endif
10797049Speter    TR(TRACE_IEVENT, ("%s time: %ld msec", first ? "get" : "elapsed", res));
10866963Speter    return res;
10950276Speter}
11050276Speter
111166124Srafan#ifdef NCURSES_WGETCH_EVENTS
112166124SrafanNCURSES_EXPORT(int)
113166124Srafan_nc_eventlist_timeout(_nc_eventlist * evl)
114166124Srafan{
115166124Srafan    int event_delay = -1;
116166124Srafan    int n;
117166124Srafan
118166124Srafan    if (evl != 0) {
119166124Srafan
120166124Srafan	for (n = 0; n < evl->count; ++n) {
121166124Srafan	    _nc_event *ev = evl->events[n];
122166124Srafan
123166124Srafan	    if (ev->type == _NC_EVENT_TIMEOUT_MSEC) {
124166124Srafan		event_delay = ev->data.timeout_msec;
125166124Srafan		if (event_delay < 0)
126166124Srafan		    event_delay = INT_MAX;	/* FIXME Is this defined? */
127166124Srafan	    }
128166124Srafan	}
129166124Srafan    }
130166124Srafan    return event_delay;
131166124Srafan}
132166124Srafan#endif /* NCURSES_WGETCH_EVENTS */
133166124Srafan
134262629Sdelphij#if (USE_FUNC_POLL || HAVE_SELECT)
135262629Sdelphij#  define MAYBE_UNUSED
136262629Sdelphij#else
137262629Sdelphij#  define MAYBE_UNUSED GCC_UNUSED
138262629Sdelphij#endif
139262629Sdelphij
140262629Sdelphij#if (USE_FUNC_POLL || HAVE_SELECT)
141262629Sdelphij#  define MAYBE_UNUSED
142262629Sdelphij#else
143262629Sdelphij#  define MAYBE_UNUSED GCC_UNUSED
144262629Sdelphij#endif
145262629Sdelphij
14650276Speter/*
14750276Speter * Wait a specified number of milliseconds, returning nonzero if the timer
14850276Speter * didn't expire before there is activity on the specified file descriptors.
14950276Speter * The file-descriptors are specified by the mode:
150262629Sdelphij *	TW_NONE    0 - none (absolute time)
151262629Sdelphij *	TW_INPUT   1 - ncurses' normal input-descriptor
152262629Sdelphij *	TW_MOUSE   2 - mouse descriptor, if any
153262629Sdelphij *	TW_ANY     3 - either input or mouse.
154262629Sdelphij *      TW_EVENT   4 -
155166124Srafan * Experimental:  if NCURSES_WGETCH_EVENTS is defined, (mode & 4) determines
156166124Srafan * whether to pay attention to evl argument.  If set, the smallest of
157166124Srafan * millisecond and of timeout of evl is taken.
158166124Srafan *
15950276Speter * We return a mask that corresponds to the mode (e.g., 2 for mouse activity).
16050276Speter *
16150276Speter * If the milliseconds given are -1, the wait blocks until activity on the
16250276Speter * descriptors.
16350276Speter */
16476726SpeterNCURSES_EXPORT(int)
165262629Sdelphij_nc_timed_wait(SCREEN *sp MAYBE_UNUSED,
166262629Sdelphij	       int mode MAYBE_UNUSED,
167166124Srafan	       int milliseconds,
168166124Srafan	       int *timeleft
169166124Srafan	       EVENTLIST_2nd(_nc_eventlist * evl))
17050276Speter{
17166963Speter    int count;
172262629Sdelphij    int result = TW_NONE;
173174993Srafan    TimeType t0;
174262629Sdelphij#if (USE_FUNC_POLL || HAVE_SELECT)
175262629Sdelphij    int fd;
176262629Sdelphij#endif
17750276Speter
178166124Srafan#ifdef NCURSES_WGETCH_EVENTS
179166124Srafan    int timeout_is_event = 0;
180166124Srafan    int n;
181166124Srafan#endif
182166124Srafan
18350276Speter#if USE_FUNC_POLL
184166124Srafan#define MIN_FDS 2
185166124Srafan    struct pollfd fd_list[MIN_FDS];
186166124Srafan    struct pollfd *fds = fd_list;
18756639Speter#elif defined(__BEOS__)
18850276Speter#elif HAVE_SELECT
189174993Srafan    fd_set set;
19050276Speter#endif
19150276Speter
192262685Sdelphij#if USE_KLIBC_KBD
193262685Sdelphij    fd_set saved_set;
194262685Sdelphij    KBDKEYINFO ki;
195262685Sdelphij    struct timeval tv;
196262685Sdelphij#endif
197262685Sdelphij
19866963Speter    long starttime, returntime;
19950276Speter
20097049Speter    TR(TRACE_IEVENT, ("start twait: %d milliseconds, mode: %d",
20197049Speter		      milliseconds, mode));
20250276Speter
203166124Srafan#ifdef NCURSES_WGETCH_EVENTS
204262629Sdelphij    if (mode & TW_EVENT) {
205166124Srafan	int event_delay = _nc_eventlist_timeout(evl);
206166124Srafan
207166124Srafan	if (event_delay >= 0
208166124Srafan	    && (milliseconds >= event_delay || milliseconds < 0)) {
209166124Srafan	    milliseconds = event_delay;
210166124Srafan	    timeout_is_event = 1;
211166124Srafan	}
212166124Srafan    }
213166124Srafan#endif
214166124Srafan
215174993Srafan#if PRECISE_GETTIME && HAVE_NANOSLEEP
21666963Speter  retry:
21750276Speter#endif
218174993Srafan    starttime = _nc_gettime(&t0, TRUE);
21950276Speter
22066963Speter    count = 0;
221262685Sdelphij    (void) count;
22250276Speter
223166124Srafan#ifdef NCURSES_WGETCH_EVENTS
224262629Sdelphij    if ((mode & TW_EVENT) && evl)
225166124Srafan	evl->result_flags = 0;
226166124Srafan#endif
227166124Srafan
22850276Speter#if USE_FUNC_POLL
229166124Srafan    memset(fd_list, 0, sizeof(fd_list));
230166124Srafan
231166124Srafan#ifdef NCURSES_WGETCH_EVENTS
232262685Sdelphij    if ((mode & TW_EVENT) && evl) {
233166124Srafan	fds = typeMalloc(struct pollfd, MIN_FDS + evl->count);
234262685Sdelphij	if (fds == 0)
235262685Sdelphij	    return TW_NONE;
236262685Sdelphij    }
237166124Srafan#endif
238166124Srafan
239262629Sdelphij    if (mode & TW_INPUT) {
240178866Srafan	fds[count].fd = sp->_ifd;
24166963Speter	fds[count].events = POLLIN;
24266963Speter	count++;
24366963Speter    }
244262629Sdelphij    if ((mode & TW_MOUSE)
245178866Srafan	&& (fd = sp->_mouse_fd) >= 0) {
24666963Speter	fds[count].fd = fd;
24766963Speter	fds[count].events = POLLIN;
24866963Speter	count++;
24966963Speter    }
250166124Srafan#ifdef NCURSES_WGETCH_EVENTS
251262629Sdelphij    if ((mode & TW_EVENT) && evl) {
252166124Srafan	for (n = 0; n < evl->count; ++n) {
253166124Srafan	    _nc_event *ev = evl->events[n];
25450276Speter
255166124Srafan	    if (ev->type == _NC_EVENT_FILE
256166124Srafan		&& (ev->data.fev.flags & _NC_EVENT_FILE_READABLE)) {
257166124Srafan		fds[count].fd = ev->data.fev.fd;
258166124Srafan		fds[count].events = POLLIN;
259166124Srafan		count++;
260166124Srafan	    }
261166124Srafan	}
262166124Srafan    }
263166124Srafan#endif
264166124Srafan
265262685Sdelphij    result = poll(fds, (size_t) count, milliseconds);
266166124Srafan
267166124Srafan#ifdef NCURSES_WGETCH_EVENTS
268262629Sdelphij    if ((mode & TW_EVENT) && evl) {
269166124Srafan	int c;
270166124Srafan
271166124Srafan	if (!result)
272166124Srafan	    count = 0;
273166124Srafan
274166124Srafan	for (n = 0; n < evl->count; ++n) {
275166124Srafan	    _nc_event *ev = evl->events[n];
276166124Srafan
277166124Srafan	    if (ev->type == _NC_EVENT_FILE
278166124Srafan		&& (ev->data.fev.flags & _NC_EVENT_FILE_READABLE)) {
279166124Srafan		ev->data.fev.result = 0;
280166124Srafan		for (c = 0; c < count; c++)
281166124Srafan		    if (fds[c].fd == ev->data.fev.fd
282166124Srafan			&& fds[c].revents & POLLIN) {
283166124Srafan			ev->data.fev.result |= _NC_EVENT_FILE_READABLE;
284166124Srafan			evl->result_flags |= _NC_EVENT_FILE_READABLE;
285166124Srafan		    }
286166124Srafan	    } else if (ev->type == _NC_EVENT_TIMEOUT_MSEC
287166124Srafan		       && !result && timeout_is_event) {
288166124Srafan		evl->result_flags |= _NC_EVENT_TIMEOUT_MSEC;
289166124Srafan	    }
290166124Srafan	}
291166124Srafan    }
292166124Srafan#endif
293166124Srafan
29456639Speter#elif defined(__BEOS__)
29566963Speter    /*
29666963Speter     * BeOS's select() is declared in socket.h, so the configure script does
29766963Speter     * not see it.  That's just as well, since that function works only for
29866963Speter     * sockets.  This (using snooze and ioctl) was distilled from Be's patch
29966963Speter     * for ncurses which uses a separate thread to simulate select().
30066963Speter     *
30166963Speter     * FIXME: the return values from the ioctl aren't very clear if we get
30266963Speter     * interrupted.
303166124Srafan     *
304166124Srafan     * FIXME: this assumes mode&1 if milliseconds < 0 (see lib_getch.c).
30566963Speter     */
306262629Sdelphij    result = TW_NONE;
307262629Sdelphij    if (mode & TW_INPUT) {
308166124Srafan	int step = (milliseconds < 0) ? 0 : 5000;
30966963Speter	bigtime_t d;
31066963Speter	bigtime_t useconds = milliseconds * 1000;
31166963Speter	int n, howmany;
31256639Speter
313166124Srafan	if (useconds <= 0)	/* we're here to go _through_ the loop */
31466963Speter	    useconds = 1;
31556639Speter
316166124Srafan	for (d = 0; d < useconds; d += step) {
31766963Speter	    n = 0;
31866963Speter	    howmany = ioctl(0, 'ichr', &n);
31966963Speter	    if (howmany >= 0 && n > 0) {
32066963Speter		result = 1;
32166963Speter		break;
32266963Speter	    }
323166124Srafan	    if (useconds > 1 && step > 0) {
324166124Srafan		snooze(step);
325166124Srafan		milliseconds -= (step / 1000);
326166124Srafan		if (milliseconds <= 0) {
327166124Srafan		    milliseconds = 0;
328166124Srafan		    break;
329166124Srafan		}
330166124Srafan	    }
33156639Speter	}
33266963Speter    } else if (milliseconds > 0) {
33366963Speter	snooze(milliseconds * 1000);
33466963Speter	milliseconds = 0;
33566963Speter    }
33650276Speter#elif HAVE_SELECT
33766963Speter    /*
33866963Speter     * select() modifies the fd_set arguments; do this in the
33966963Speter     * loop.
34066963Speter     */
34166963Speter    FD_ZERO(&set);
34250276Speter
343262685Sdelphij#if !USE_KLIBC_KBD
344262629Sdelphij    if (mode & TW_INPUT) {
345178866Srafan	FD_SET(sp->_ifd, &set);
346178866Srafan	count = sp->_ifd + 1;
34766963Speter    }
348262685Sdelphij#endif
349262629Sdelphij    if ((mode & TW_MOUSE)
350178866Srafan	&& (fd = sp->_mouse_fd) >= 0) {
35166963Speter	FD_SET(fd, &set);
35266963Speter	count = max(fd, count) + 1;
35366963Speter    }
354166124Srafan#ifdef NCURSES_WGETCH_EVENTS
355262629Sdelphij    if ((mode & TW_EVENT) && evl) {
356166124Srafan	for (n = 0; n < evl->count; ++n) {
357166124Srafan	    _nc_event *ev = evl->events[n];
35850276Speter
359166124Srafan	    if (ev->type == _NC_EVENT_FILE
360166124Srafan		&& (ev->data.fev.flags & _NC_EVENT_FILE_READABLE)) {
361166124Srafan		FD_SET(ev->data.fev.fd, &set);
362166124Srafan		count = max(ev->data.fev.fd + 1, count);
363166124Srafan	    }
364166124Srafan	}
365166124Srafan    }
366166124Srafan#endif
367166124Srafan
368262685Sdelphij#if USE_KLIBC_KBD
369262685Sdelphij    for (saved_set = set;; set = saved_set) {
370262685Sdelphij	if ((mode & TW_INPUT)
371262685Sdelphij	    && (sp->_extended_key
372262685Sdelphij		|| (KbdPeek(&ki, 0) == 0
373262685Sdelphij		    && (ki.fbStatus & KBDTRF_FINAL_CHAR_IN)))) {
374262685Sdelphij	    FD_ZERO(&set);
375262685Sdelphij	    FD_SET(sp->_ifd, &set);
376262685Sdelphij	    result = 1;
377262685Sdelphij	    break;
378262685Sdelphij	}
379262685Sdelphij
380262685Sdelphij	tv.tv_sec = 0;
381262685Sdelphij	tv.tv_usec = (milliseconds == 0) ? 0 : (10 * 1000);
382262685Sdelphij
383262685Sdelphij	if ((result = select(count, &set, NULL, NULL, &tv)) != 0)
384262685Sdelphij	    break;
385262685Sdelphij
386262685Sdelphij	/* Time out ? */
387262685Sdelphij	if (milliseconds >= 0 && _nc_gettime(&t0, FALSE) >= milliseconds) {
388262685Sdelphij	    result = 0;
389262685Sdelphij	    break;
390262685Sdelphij	}
391262685Sdelphij    }
392262685Sdelphij#else
39366963Speter    if (milliseconds >= 0) {
39466963Speter	struct timeval ntimeout;
39566963Speter	ntimeout.tv_sec = milliseconds / 1000;
39666963Speter	ntimeout.tv_usec = (milliseconds % 1000) * 1000;
39766963Speter	result = select(count, &set, NULL, NULL, &ntimeout);
39866963Speter    } else {
39966963Speter	result = select(count, &set, NULL, NULL, NULL);
40066963Speter    }
401262685Sdelphij#endif
402166124Srafan
403166124Srafan#ifdef NCURSES_WGETCH_EVENTS
404262629Sdelphij    if ((mode & TW_EVENT) && evl) {
405166124Srafan	evl->result_flags = 0;
406166124Srafan	for (n = 0; n < evl->count; ++n) {
407166124Srafan	    _nc_event *ev = evl->events[n];
408166124Srafan
409166124Srafan	    if (ev->type == _NC_EVENT_FILE
410166124Srafan		&& (ev->data.fev.flags & _NC_EVENT_FILE_READABLE)) {
411166124Srafan		ev->data.fev.result = 0;
412166124Srafan		if (FD_ISSET(ev->data.fev.fd, &set)) {
413166124Srafan		    ev->data.fev.result |= _NC_EVENT_FILE_READABLE;
414166124Srafan		    evl->result_flags |= _NC_EVENT_FILE_READABLE;
415166124Srafan		}
416166124Srafan	    } else if (ev->type == _NC_EVENT_TIMEOUT_MSEC
417166124Srafan		       && !result && timeout_is_event)
418166124Srafan		evl->result_flags |= _NC_EVENT_TIMEOUT_MSEC;
419166124Srafan	}
420166124Srafan    }
42150276Speter#endif
42250276Speter
423166124Srafan#endif /* USE_FUNC_POLL, etc */
424166124Srafan
425174993Srafan    returntime = _nc_gettime(&t0, FALSE);
42650276Speter
42766963Speter    if (milliseconds >= 0)
428262629Sdelphij	milliseconds -= (int) (returntime - starttime);
42950276Speter
430166124Srafan#ifdef NCURSES_WGETCH_EVENTS
431166124Srafan    if (evl) {
432166124Srafan	evl->result_flags = 0;
433166124Srafan	for (n = 0; n < evl->count; ++n) {
434166124Srafan	    _nc_event *ev = evl->events[n];
435166124Srafan
436166124Srafan	    if (ev->type == _NC_EVENT_TIMEOUT_MSEC) {
437166124Srafan		long diff = (returntime - starttime);
438166124Srafan		if (ev->data.timeout_msec <= diff)
439166124Srafan		    ev->data.timeout_msec = 0;
440166124Srafan		else
441166124Srafan		    ev->data.timeout_msec -= diff;
442166124Srafan	    }
443166124Srafan
444166124Srafan	}
445166124Srafan    }
446166124Srafan#endif
447166124Srafan
448166124Srafan#if PRECISE_GETTIME && HAVE_NANOSLEEP
44966963Speter    /*
45066963Speter     * If the timeout hasn't expired, and we've gotten no data,
45166963Speter     * this is probably a system where 'select()' needs to be left
45266963Speter     * alone so that it can complete.  Make this process sleep,
45366963Speter     * then come back for more.
45466963Speter     */
45566963Speter    if (result == 0 && milliseconds > 100) {
456166124Srafan	napms(100);		/* FIXME: this won't be right if I recur! */
45766963Speter	milliseconds -= 100;
45866963Speter	goto retry;
45966963Speter    }
46050276Speter#endif
46150276Speter
46266963Speter    /* return approximate time left in milliseconds */
46366963Speter    if (timeleft)
46466963Speter	*timeleft = milliseconds;
46550276Speter
46697049Speter    TR(TRACE_IEVENT, ("end twait: returned %d (%d), remaining time %d msec",
46797049Speter		      result, errno, milliseconds));
46850276Speter
46966963Speter    /*
47066963Speter     * Both 'poll()' and 'select()' return the number of file descriptors
47166963Speter     * that are active.  Translate this back to the mask that denotes which
47266963Speter     * file-descriptors, so that we don't need all of this system-specific
47366963Speter     * code everywhere.
47466963Speter     */
47566963Speter    if (result != 0) {
47666963Speter	if (result > 0) {
47766963Speter	    result = 0;
47850276Speter#if USE_FUNC_POLL
479166124Srafan	    for (count = 0; count < MIN_FDS; count++) {
48066963Speter		if ((mode & (1 << count))
48166963Speter		    && (fds[count].revents & POLLIN)) {
48266963Speter		    result |= (1 << count);
48366963Speter		}
48466963Speter	    }
48556639Speter#elif defined(__BEOS__)
486262629Sdelphij	    result = TW_INPUT;	/* redundant, but simple */
48750276Speter#elif HAVE_SELECT
488262629Sdelphij	    if ((mode & TW_MOUSE)
489178866Srafan		&& (fd = sp->_mouse_fd) >= 0
49066963Speter		&& FD_ISSET(fd, &set))
491262629Sdelphij		result |= TW_MOUSE;
492262629Sdelphij	    if ((mode & TW_INPUT)
493178866Srafan		&& FD_ISSET(sp->_ifd, &set))
494262629Sdelphij		result |= TW_INPUT;
49550276Speter#endif
49666963Speter	} else
49766963Speter	    result = 0;
49866963Speter    }
499166124Srafan#ifdef NCURSES_WGETCH_EVENTS
500262629Sdelphij    if ((mode & TW_EVENT) && evl && evl->result_flags)
501262629Sdelphij	result |= TW_EVENT;
502166124Srafan#endif
50350276Speter
504262685Sdelphij#if USE_FUNC_POLL
505262685Sdelphij#ifdef NCURSES_WGETCH_EVENTS
506262685Sdelphij    if (fds != fd_list)
507262685Sdelphij	free((char *) fds);
508262685Sdelphij#endif
509262685Sdelphij#endif
510262685Sdelphij
51166963Speter    return (result);
51250276Speter}
513