#ifndef __QNX4_H
#define __QNX4_H

#ifndef __QNXNTO__

#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <semaphore.h>
#include <string.h>
#include <conio.h>
#include <i86.h>
#include <process.h>
#include <stddef.h>
#include <sys/fd.h>
#include <sys/fsys.h>
#include <sys/inline.h> 
#include <sys/io_msg.h>
#include <sys/ioctl.h>
#include <sys/irqinfo.h>
#include <sys/mman.h>
#include <sys/osinfo.h>
#include <sys/psinfo.h>
#include <sys/pci.h>
#include <sys/proxy.h>
#include <sys/prfx.h>
#include <sys/sched.h>
#include <sys/seginfo.h>
#include <sys/sendmx.h>
#include <sys/sys_msg.h>
#include <sys/dev_msg.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <time.h>
#include <unistd.h>

#define inline 				/* Doesn't exist in Watcom C*/

#define in8(a) inp(a)
#define in16(a) inpw(a)
#define in32(a) inpd(a)
#define out8(a,b) outp(a,b)
#define out16(a,b) outpw(a,b)
#define out32(a,b) outpd(a,b)

#define outb(v, p) outp(p, v)
#define inb(p) inp(p)
#define outw(v, p) outpw(p, v)
#define inw(p) inpw(p)
#define outl(v, p) outpd(p, v)
#define inl(p) inpd(p)

#define IMR1                    0x21  /* PIC1 Interrupt mask register */
#define IMR2                    0xa1  /* PIC2 Interrupt mask register */

#define MAX_DEVICES 16
#define MAX_OPEN_FILES 32


/* used to implement condition variables */

extern int WCHAN;		/* sleep channel for condvar emulation */
extern pid_t intr_thread_pids[];
extern pid_t parent;

typedef struct _sleep_entity {

        pid_t           proxy;
        char            wchan;
        timer_t         tid;
	int		timedout;	// timer expired?
        int             (*func)(void *);
} sleep_entity_t;


typedef struct _iofunc_notify_t {

	pid_t			proxy;
	struct _select_set	set;
} iofunc_notify_t;


/* dummy, does nothing */
typedef struct _iofunc_mount_t {
	short flags;
} iofunc_mount_t;


/* for stat messages */

typedef struct _iofunc_attr_t {

	/* don't need all of these fields */
	int 		major;
	int		minor;
	ino_t		ino_ino;
	dev_t		ino_dev;
	mode_t		ino_ftype;
	off_t		ino_size;
	dev_t		ino_rdev;
	short		ino_uid;
	short		ino_gid;
	time_t		ino_mtime,
			ino_atime,
			ino_ctime;
	nlink_t		ino_nlink;
	

} iofunc_attr_t;

enum {
        FNONE  = 0,
        FEXEC  = (1 << 0),
        FWRITE = (1 << 1),
        FREAD  = (1 << 2),
        FACC   = (FREAD|FWRITE|FEXEC),
        FOWNER = (1 << 3),
        FNDELAY= (1 << 4),
        FSYNC  = (1 << 5)
	};
	
#define d_owner(d)        (d->ino_uid)
#define d_group(d)        (d->ino_gid)
#define d_mode(d)         (d->ino_ftype)

typedef struct _iofunc_ocb_t {

	struct snd_stru_attr	*attr;
	

	short int		oflag;

#define _IO_FLAG_RD 		0x01
#define _IO_FLAG_WR 		0x02
#define _IO_FLAG_MASK 		0x0f	      
#define _IO_FLAG_NONBLOCK	0x10
	
	short int 		ioflag;
	off_t			offset;
} iofunc_ocb_t;


struct device {
	char 			*pfx;
	struct snd_stru_attr 	*attr;
};

typedef union {

	msg_t	 			type;
	msg_t	 			status;
	struct _sysmsg_hdr		sysmsg;
	struct _sysmsg_hdr_reply 	sysmsg_reply;
	struct _io_open			open;
	struct _io_open_reply		open_reply;
	struct _io_close		close;
	struct _io_close_reply		close_reply;
	struct _io_read			read;
	struct _io_read_reply		read_reply;
	struct _io_write		write;
	struct _io_write_reply		write_reply;
        struct _io_qioctl		ioctl;
	struct _io_qioctl_reply		ioctl_reply;
	struct _io_fstat		stat;
	struct _io_fstat_reply 		stat_reply;
	struct _io_select		select;
	struct _io_select_reply		select_reply;
	struct _io_flags		flags;
	struct _io_flags_reply		flags_reply;
	struct _io_chmod		chmod;
	struct _io_chmod_reply		chmod_reply;
	struct _io_chown		chown;
	struct _io_chown_reply		chown_reply;
	struct _io_dup			dup;
	struct _io_dup_reply		dup_reply;
} message_t;


/* version info */

#ifndef NAME
#define NAME "Audio"
#endif
#ifndef VERSION
#define VERSION 001
#endif
#ifndef RELEASE
#define RELEASE 'A'
#endif

/* fixme */
#define atomic_set_value(a,b) ((*(a)) |= (b))
#define atomic_clr(a,b) ((*(a)) &= ~(b))

/* TODO: change snd_printk to a variable args func */

#define snd_printk printf

#ifdef SNDCFG_DEBUG
#define snd_printd printf
#else
#define snd_printd snd_print_nothing 
#endif

#ifdef SNDCFG_DEBUG_DETECT
#define snd_printdd printf
#else
#define snd_printdd snd_print_nothing 
#endif

void snd_print_nothing(char *fmt,...);
void destroy_intr_thread(pid_t pid);
int proxy_callback(void *arg);
int hint_connect(int irq, struct snd_stru_irq *irqp);
int check_pid(pid_t pid);
paddr_t virt_to_bus(void *x);
void nsec_delay(unsigned usec);
void initloop(struct _osinfo *);
void setup_signal_handling(void (*handler)());

/* TO ADD */
pid_t pulse_attach(int (*func)(void *handle), int priority, void *data, int nbytes);
void intr_off(int);
void intr_on(int);


#endif
#endif /* QNX4_H */
