117ca54c3Smrg/*
217ca54c3Smrg
317ca54c3SmrgCopyright 1994, 1998  The Open Group
417ca54c3Smrg
517ca54c3SmrgPermission to use, copy, modify, distribute, and sell this software and its
617ca54c3Smrgdocumentation for any purpose is hereby granted without fee, provided that
717ca54c3Smrgthe above copyright notice appear in all copies and that both that
817ca54c3Smrgcopyright notice and this permission notice appear in supporting
917ca54c3Smrgdocumentation.
1017ca54c3Smrg
1117ca54c3SmrgThe above copyright notice and this permission notice shall be included
1217ca54c3Smrgin all copies or substantial portions of the Software.
1317ca54c3Smrg
1417ca54c3SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1517ca54c3SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1617ca54c3SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1717ca54c3SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
1817ca54c3SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1917ca54c3SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2017ca54c3SmrgOTHER DEALINGS IN THE SOFTWARE.
2117ca54c3Smrg
2217ca54c3SmrgExcept as contained in this notice, the name of The Open Group shall
2317ca54c3Smrgnot be used in advertising or otherwise to promote the sale, use or
2417ca54c3Smrgother dealings in this Software without prior written authorization
2517ca54c3Smrgfrom The Open Group.
2617ca54c3Smrg
2717ca54c3Smrg*/
2817ca54c3Smrg
2917ca54c3Smrg/*
3017ca54c3Smrg * Copyright © 2005 Daniel Stone
3117ca54c3Smrg * 
3217ca54c3Smrg * Permission to use, copy, modify, distribute, and sell this software and its
3317ca54c3Smrg * documentation for any purpose is hereby granted without fee, provided that
3417ca54c3Smrg * the above copyright notice appear in all copies and that both that
3517ca54c3Smrg * copyright notice and this permission notice appear in supporting
3617ca54c3Smrg * documentation, and that the name of Daniel Stone not be used in advertising
3717ca54c3Smrg * or publicity pertaining to distribution of the software without specific,
3817ca54c3Smrg * written prior permission.  Daniel Stone makes no representations about the
3917ca54c3Smrg * suitability of this software for any purpose.  It is provided "as is"
4017ca54c3Smrg * without express or implied warranty.
4117ca54c3Smrg *
4217ca54c3Smrg * DANIEL STONE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
4317ca54c3Smrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
4417ca54c3Smrg * DANIEL STONE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
4517ca54c3Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
4617ca54c3Smrg * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
4717ca54c3Smrg * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4817ca54c3Smrg*/
4917ca54c3Smrg
5017ca54c3Smrg#ifndef _XPOLL_H_
5117ca54c3Smrg#define _XPOLL_H_
5217ca54c3Smrg
5317ca54c3Smrg#if !defined(WIN32) || defined(__CYGWIN__)
5417ca54c3Smrg
5517ca54c3Smrg#ifndef USE_POLL
5617ca54c3Smrg
57bd60773fSmrg#if defined(FD_SETSIZE) && FD_SETSIZE < 512
58bd60773fSmrg# define XFD_SETSIZE	FD_SETSIZE
59bd60773fSmrg#else
60bd60773fSmrg# define XFD_SETSIZE	512
61bd60773fSmrg# ifndef FD_SETSIZE
62bd60773fSmrg#  define FD_SETSIZE	XFD_SETSIZE
63bd60773fSmrg# endif
64bd60773fSmrg#endif
65bd60773fSmrg
6617ca54c3Smrg#include <X11/Xos.h>
6717ca54c3Smrg
6817ca54c3Smrg#include <sys/select.h>  /* Get the FD_* macros. */
6917ca54c3Smrg
7017ca54c3Smrg#include <X11/Xmd.h>
7117ca54c3Smrg
7217ca54c3Smrg#ifdef CSRG_BASED
7317ca54c3Smrg#include <sys/param.h>
7417ca54c3Smrg# if BSD < 199103
7517ca54c3Smrgtypedef long fd_mask;
7617ca54c3Smrg# endif
7717ca54c3Smrg#endif
7817ca54c3Smrg
7917ca54c3Smrg#ifndef NBBY
8017ca54c3Smrg#define NBBY	8		/* number of bits in a byte */
8117ca54c3Smrg#endif
8217ca54c3Smrg
8317ca54c3Smrg#ifndef NFDBITS
8417ca54c3Smrg#define NFDBITS (sizeof(fd_mask) * NBBY)	/* bits per mask */
8517ca54c3Smrg#endif
8617ca54c3Smrg
8717ca54c3Smrg#ifndef howmany
8817ca54c3Smrg#define howmany(x,y)	(((x)+((y)-1))/(y))
8917ca54c3Smrg#endif
9017ca54c3Smrg
9117ca54c3Smrg#if defined(BSD) && BSD < 198911 
9217ca54c3Smrgtypedef struct fd_set {
9317ca54c3Smrg	fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
9417ca54c3Smrg} fd_set;
9517ca54c3Smrg#endif
9617ca54c3Smrg
9717ca54c3Smrg# define Select(n,r,w,e,t) select(n,(fd_set*)r,(fd_set*)w,(fd_set*)e,(struct timeval*)t)
9817ca54c3Smrg
9917ca54c3Smrg#define __X_FDS_BITS @USE_FDS_BITS@
10017ca54c3Smrg
10117ca54c3Smrg#ifndef __FDS_BITS
10217ca54c3Smrg# define __FDS_BITS(p)  ((p)->__X_FDS_BITS)
10317ca54c3Smrg#endif
10417ca54c3Smrg
10517ca54c3Smrg#define __XFDS_BITS(p, n) (__FDS_BITS(p))[n]
10617ca54c3Smrg
10717ca54c3Smrg#ifndef FD_SET
10817ca54c3Smrg#define FD_SET(n, p)    (__XFDS_BITS(p, ((n)/NFDBITS)) |= ((fd_mask)1 << ((n) % NFDBITS)))
10917ca54c3Smrg#endif
11017ca54c3Smrg#ifndef FD_CLR
11117ca54c3Smrg#define FD_CLR(n, p)    (__XFDS_BITS((p), ((n)/NFDBITS)) &= ~((fd_mask)1 << ((n) % NFDBITS)))
11217ca54c3Smrg#endif
11317ca54c3Smrg#ifndef FD_ISSET
11417ca54c3Smrg#define FD_ISSET(n, p)  ((__XFDS_BITS((p), ((n)/NFDBITS))) & ((fd_mask)1 << ((n) % NFDBITS)))
11517ca54c3Smrg#endif
11617ca54c3Smrg#ifndef FD_ZERO
11717ca54c3Smrg#define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
11817ca54c3Smrg#endif
11917ca54c3Smrg
12017ca54c3Smrg/*
12117ca54c3Smrg * The howmany(FD_SETSIZE, NFDBITS) computes the number of elements in the
12217ca54c3Smrg * array. before accessing an element in the array we check it exists.
12317ca54c3Smrg * If it does not exist then the compiler discards the code to access it. 
12417ca54c3Smrg */
12517ca54c3Smrg#define XFD_ANYSET(p) \
12617ca54c3Smrg        ((howmany(FD_SETSIZE, NFDBITS) > 0 && (__XFDS_BITS(p, 0))) || \
12717ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 1 && (__XFDS_BITS(p, 1))) || \
12817ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 2 && (__XFDS_BITS(p, 2))) || \
12917ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 3 && (__XFDS_BITS(p, 3))) || \
13017ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 4 && (__XFDS_BITS(p, 4))) || \
13117ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 5 && (__XFDS_BITS(p, 5))) || \
13217ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 6 && (__XFDS_BITS(p, 6))) || \
13317ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 7 && (__XFDS_BITS(p, 7))) || \
13417ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 8 && (__XFDS_BITS(p, 8))) || \
13517ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 9 && (__XFDS_BITS(p, 9))) || \
13617ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 10 && (__XFDS_BITS(p, 10))) || \
13717ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 11 && (__XFDS_BITS(p, 11))) || \
13817ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 12 && (__XFDS_BITS(p, 12))) || \
13917ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 13 && (__XFDS_BITS(p, 13))) || \
14017ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 14 && (__XFDS_BITS(p, 14))) || \
14117ca54c3Smrg        (howmany(FD_SETSIZE, NFDBITS) > 15 && (__XFDS_BITS(p, 15))))
14217ca54c3Smrg
14317ca54c3Smrg
14417ca54c3Smrg#define XFD_COPYSET(src,dst) { \
14517ca54c3Smrg        int __i__; \
14617ca54c3Smrg		for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \
14717ca54c3Smrg            __XFDS_BITS((dst), __i__) = __XFDS_BITS((src), __i__); \
14817ca54c3Smrg        }
14917ca54c3Smrg#define XFD_ANDSET(dst,b1,b2) { \
15017ca54c3Smrg        int __i__; \
15117ca54c3Smrg        for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \
15217ca54c3Smrg            __XFDS_BITS((dst), __i__) = ((__XFDS_BITS((b1), __i__)) & (__XFDS_BITS((b2), __i__))); \
15317ca54c3Smrg        }
15417ca54c3Smrg#define XFD_ORSET(dst,b1,b2) { \
15517ca54c3Smrg        int __i__; \
15617ca54c3Smrg        for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \
15717ca54c3Smrg		__XFDS_BITS((dst), __i__) = ((__XFDS_BITS((b1), __i__)) | (__XFDS_BITS((b2), __i__))); \
15817ca54c3Smrg        }        
15917ca54c3Smrg#define XFD_UNSET(dst,b1) { \
16017ca54c3Smrg        int __i__; \
16117ca54c3Smrg        for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \
16217ca54c3Smrg    		__XFDS_BITS((dst), __i__) &= ~(__XFDS_BITS((b1), __i__)); \
16317ca54c3Smrg        }
16417ca54c3Smrg
16517ca54c3Smrg#else /* USE_POLL */
16617ca54c3Smrg#include <sys/poll.h>
16717ca54c3Smrg#endif /* USE_POLL */
16817ca54c3Smrg
16917ca54c3Smrg#else /* WIN32 */
17017ca54c3Smrg
17117ca54c3Smrg#define XFD_SETSIZE	512
17217ca54c3Smrg#ifndef FD_SETSIZE
17317ca54c3Smrg#define FD_SETSIZE	XFD_SETSIZE
17417ca54c3Smrg#endif
17517ca54c3Smrg#include <X11/Xwinsock.h>
17617ca54c3Smrg
17717ca54c3Smrg#define Select(n,r,w,e,t) select(0,(fd_set*)r,(fd_set*)w,(fd_set*)e,(struct timeval*)t)
17817ca54c3Smrg
17917ca54c3Smrg#define XFD_SETCOUNT(p)	(((fd_set FAR *)(p))->fd_count)
18017ca54c3Smrg#define XFD_FD(p,i) (((fd_set FAR *)(p))->fd_array[i])
18117ca54c3Smrg#define XFD_ANYSET(p)	XFD_SETCOUNT(p)
18217ca54c3Smrg
18317ca54c3Smrg#define XFD_COPYSET(src,dst) { \
18417ca54c3Smrg    u_int __i; \
18517ca54c3Smrg    FD_ZERO(dst); \
18617ca54c3Smrg    for (__i = 0; __i < XFD_SETCOUNT(src) ; __i++) { \
18717ca54c3Smrg        XFD_FD(dst,__i) = XFD_FD(src,__i); \
18817ca54c3Smrg    } \
18917ca54c3Smrg    XFD_SETCOUNT(dst) = XFD_SETCOUNT(src); \
19017ca54c3Smrg}
19117ca54c3Smrg
19217ca54c3Smrg#define XFD_ANDSET(dst,b1,b2) { \
19317ca54c3Smrg    u_int __i; \
19417ca54c3Smrg    FD_ZERO(dst); \
19517ca54c3Smrg    for (__i = 0; __i < XFD_SETCOUNT(b1) ; __i++) { \
19617ca54c3Smrg        if (FD_ISSET(XFD_FD(b1,__i), b2)) \
19717ca54c3Smrg	   FD_SET(XFD_FD(b1,__i), dst); \
19817ca54c3Smrg    } \
19917ca54c3Smrg}
20017ca54c3Smrg
20117ca54c3Smrg#define XFD_ORSET(dst,b1,b2) { \
20217ca54c3Smrg    u_int __i; \
20317ca54c3Smrg    if (dst != b1) XFD_COPYSET(b1,dst); \
20417ca54c3Smrg    for (__i = 0; __i < XFD_SETCOUNT(b2) ; __i++) { \
20517ca54c3Smrg        if (!FD_ISSET(XFD_FD(b2,__i), dst)) \
20617ca54c3Smrg	   FD_SET(XFD_FD(b2,__i), dst); \
20717ca54c3Smrg    } \
20817ca54c3Smrg}
20917ca54c3Smrg
21017ca54c3Smrg/* this one is really sub-optimal */
21117ca54c3Smrg#define XFD_UNSET(dst,b1) { \
21217ca54c3Smrg    u_int __i; \
21317ca54c3Smrg    for (__i = 0; __i < XFD_SETCOUNT(b1) ; __i++) { \
21417ca54c3Smrg	FD_CLR(XFD_FD(b1,__i), dst); \
21517ca54c3Smrg    } \
21617ca54c3Smrg}
21717ca54c3Smrg
21817ca54c3Smrg/* we have to pay the price of having an array here, unlike with bitmasks
21917ca54c3Smrg   calling twice FD_SET with the same fd is not transparent, so be careful */
22017ca54c3Smrg#undef FD_SET
22117ca54c3Smrg#define FD_SET(fd,set) do { \
22217ca54c3Smrg    if (XFD_SETCOUNT(set) < FD_SETSIZE && !FD_ISSET(fd,set)) \
22317ca54c3Smrg        XFD_FD(set,XFD_SETCOUNT(set)++)=(fd); \
22417ca54c3Smrg} while(0)
22517ca54c3Smrg
22617ca54c3Smrg#define getdtablesize() FD_SETSIZE 
22717ca54c3Smrg
22817ca54c3Smrg#endif /* WIN32 */
22917ca54c3Smrg
23017ca54c3Smrg#endif /* _XPOLL_H_ */
231