#ifndef _XLIBOS_H
#define _XLIBOS_H 1
/*
 * $XConsortium: Xlibos.h,v 1.23 89/12/18 13:44:00 rws Exp $
 *
 * Xlib networking include files for UNIX Systems.
 */

#ifndef __stdlib_h
#include <stdlib.h>
#endif
#ifndef __stdio_h
#include <stdio.h>
#endif

#ifndef _BSD_C
#ifndef __string_h
#include <string.h>
#endif
/*
 * The compiler will warn if the following causes redefinition of
 * important tokens.  If so it will be necessary to rework the source
 * code, to #undef the definitions (dangerous, as these routines are
 * used as standard in X code!) or to compile with a BSD compiler or
 * -D_NO_BSD_STRINGS
 */
#if !defined(_NO_BSD_STRINGS) && !defined(__STDC__)
#define index strchr
#define rindex strrchr
#define bcopy $bcopy
#define bzero $bzero
#define bcmp memcmp
#endif
#else	/* _BSD_C */
#ifndef __strings_h
#include "strings.h"
#endif
#endif	/* _BSD_C */

#ifndef __netinet_in_h
#include "netinet/in.h"
#endif
#ifndef __sys_ioctl_h
#include "sys/ioctl.h"
#endif
#ifndef __netdb_h
#include "netdb.h"
#endif
#ifndef __sys_uio_h
#include "sys/uio.h"	/* needed for XlibInt.c (struct iovec) */
#endif
#ifndef __sys_param_h
#include "sys/param.h"	/* needed for XConnDis.c */
#endif
#ifndef __sys_time_h
#include "sys/time.h"	/* For struct timeval */
#endif
#ifndef __unistd_h
#include "unistd.h"
#endif

#define MALLOC_0_RETURNS_NULL
#define BytesReadable(fd, ptr) ioctl ((fd), FIONREAD, (ptr))
#define MSKCNT ((NOFILE + 31) / 32)	/* size of bit array */


#if (MSKCNT==1)
#define BITMASK(i) (1 << (i))
#define MASKIDX(i) 0
#endif
#if (MSKCNT>1)
#define BITMASK(i) (1 << ((i) & 31))
#define MASKIDX(i) ((i) >> 5)
#endif

#define MASKWORD(buf, i) buf[MASKIDX(i)]
#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))

#if (MSKCNT==1)
#define COPYBITS(src, dst) (dst[0] = src[0]);
#define CLEARBITS(buf) (buf[0] = 0);
#define MASKANDSETBITS(dst, b1, b2) (dst[0] = (b1[0] & b2[0]));
#define ORBITS(dst, b1, b2) (dst[0] = (b1[0] | b2[0]));
#define UNSETBITS(dst, b1) (dst[0] &= ~b1[0]);
#define ANYSET(src) (src[0])
#endif
#if (MSKCNT==2)
#define COPYBITS(src, dst) { dst[0] = src[0]; dst[1] = src[1]; }
#define CLEARBITS(buf) { buf[0] = 0; buf[1] = 0; }
#define MASKANDSETBITS(dst, b1, b2)  {\
		      dst[0] = (b1[0] & b2[0]);\
		      dst[1] = (b1[1] & b2[1]); }
#define ORBITS(dst, b1, b2)  {\
		      dst[0] = (b1[0] | b2[0]);\
		      dst[1] = (b1[1] | b2[1]); }
#define UNSETBITS(dst, b1) {\
                      dst[0] &= ~b1[0]; \
                      dst[1] &= ~b1[1]; }
#define ANYSET(src) (src[0] || src[1])
#endif
#if (MSKCNT==3)
#define COPYBITS(src, dst) { dst[0] = src[0]; dst[1] = src[1]; \
			     dst[2] = src[2]; }
#define CLEARBITS(buf) { buf[0] = 0; buf[1] = 0; buf[2] = 0; }
#define MASKANDSETBITS(dst, b1, b2)  {\
		      dst[0] = (b1[0] & b2[0]);\
		      dst[1] = (b1[1] & b2[1]);\
		      dst[2] = (b1[2] & b2[2]); }
#define ORBITS(dst, b1, b2)  {\
		      dst[0] = (b1[0] | b2[0]);\
		      dst[1] = (b1[1] | b2[1]);\
		      dst[2] = (b1[2] | b2[2]); }
#define UNSETBITS(dst, b1) {\
                      dst[0] &= ~b1[0]; \
                      dst[1] &= ~b1[1]; \
                      dst[2] &= ~b1[2]; }
#define ANYSET(src) (src[0] || src[1] || src[2])
#endif
#if (MSKCNT==4)
#define COPYBITS(src, dst) dst[0] = src[0]; dst[1] = src[1]; \
			   dst[2] = src[2]; dst[3] = src[3]
#define CLEARBITS(buf) buf[0] = 0; buf[1] = 0; buf[2] = 0; buf[3] = 0
#define MASKANDSETBITS(dst, b1, b2)  \
                      dst[0] = (b1[0] & b2[0]);\
                      dst[1] = (b1[1] & b2[1]);\
                      dst[2] = (b1[2] & b2[2]);\
                      dst[3] = (b1[3] & b2[3])
#define ORBITS(dst, b1, b2)  \
                      dst[0] = (b1[0] | b2[0]);\
                      dst[1] = (b1[1] | b2[1]);\
                      dst[2] = (b1[2] | b2[2]);\
                      dst[3] = (b1[3] | b2[3])
#define UNSETBITS(dst, b1) \
                      dst[0] &= ~b1[0]; \
                      dst[1] &= ~b1[1]; \
                      dst[2] &= ~b1[2]; \
                      dst[3] &= ~b1[3]
#define ANYSET(src) (src[0] || src[1] || src[2] || src[3])
#endif

#if (MSKCNT>4)
#define COPYBITS(src, dst) bcopy((caddr_t) src, (caddr_t) dst,\
				 MSKCNT*sizeof(long))
#define CLEARBITS(buf) bzero((caddr_t) buf, MSKCNT*sizeof(long))
#define MASKANDSETBITS(dst, b1, b2)  \
		      { int cri;			\
			for (cri=0; cri<MSKCNT; cri++)	\
		          dst[cri] = (b1[cri] & b2[cri]) }
#define ORBITS(dst, b1, b2)  \
		      { int cri;			\
		      for (cri=0; cri<MSKCNT; cri++)	\
		          dst[cri] = (b1[cri] | b2[cri]) }
#define UNSETBITS(dst, b1) \
		      { int cri;			\
		      for (cri=0; cri<MSKCNT; cri++)	\
		          dst[cri] &= ~b1[cri];  }
/*
 * If MSKCNT>4, then ANYSET is a routine defined in XlibInt.c.
 *
 * #define ANYSET(src) (src[0] || src[1] || src[2] || src[3] || src[4] ...)
 */
extern int ANYSET(long *src);
#endif

/*
 * The following definitions can be used for locking requests in multi-threaded
 * address spaces.
 */
#define LockDisplay(dis)
#define LockMutex(mutex)
#define UnlockMutex(mutex)
#define UnlockDisplay(dis)
#define Xfree(ptr) free((ptr))


/*
 * The following definitions provide an alternative storage manager
 * interface which returns a real (freeable) heap pointer if 0 bytes
 * are requested.
 */
extern void *_Xcalloc(size_t nmemb, size_t size);
extern void *_Xmalloc(size_t size);
extern void *_Xrealloc(void *ptr, size_t size);

# define Xmalloc(size) _Xmalloc((size))
# define Xrealloc(ptr, size) _Xrealloc((ptr), (size))
# define Xcalloc(nelem, elsize) _Xcalloc((nelem), (elsize))

#ifdef STREAMSCONN
#include "Xstreams.h"

extern char _XsTypeOfStream[];
extern Xstream _XsStream[];

#define ReadFromServer(dpy, data, size) \
	(*_XsStream[_XsTypeOfStream[dpy]].ReadFromStream)((dpy), (data), (size), \
						     BUFFERING)
#define WriteToServer(dpy, bufind, size) \
	(*_XsStream[_XsTypeOfStream[dpy]].WriteToStream)((dpy), (bufind), (size))

#else /* else not STREAMSCONN */

/*
 * bsd can read from sockets directly
 */
#define ReadFromServer(dpy, data, size) read((dpy), (data), (size))
#define WriteToServer(dpy, bufind, size) write((dpy), (bufind), (size))

#endif /* STREAMSCONN */


/*
 * Need typedefs for readv/writev - they should be in sys/uio.h
 * but are not at present.
 */
extern int readv(int fd, struct iovec *iov, int iovcnt);
extern int writev(int fd, struct iovec *iov, int iovcnt);
#define _XReadV readv
#define _XWriteV writev

#define ReadvFromServer(dpy, iov, iovcnt) _XReadV((dpy), (iov), (iovcnt))
#define WritevToServer(dpy, iov, iovcnt) _XWriteV((dpy), (iov), (iovcnt))

#define SearchString(string, char) index((string), (char))
#endif
