/* crtdll.h */

/*
 *	All redefinitions in this header are controlled by #ifdefs -
 *	most changes affect headers that are already included - so make
 *	sure this is included after all other standard headers.
 *
 *	If you use the 286|Dos Extender's ability to multi-task amongst
 *	several .EXEs, and each wishes to use the CRT DLL, you should
 *	#define _CRTDLL_MULTIPROC to guarantee that each process gets
 *	the proper access to the runtime's internal variables.  If
 *	you do _not_, then direct access is only given to process #1's
 *	variables, and child processes will not be given proper information.
 */

/*
 *	$Id: crtdll.h 1.14 1995/03/24 11:24:19 clark Exp $
 */

#ifndef _INC_CRTDLL
#define _INC_CRTDLL

#ifdef __cplusplus
	extern "C" {
#endif

/*
 *	Various typedefs if included without any of the other headers
 */

#if ! (defined(OS2DEF_INCLUDED) || defined(PHAPI_H_INCLUDED))
typedef short SHORT;
typedef long LONG;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned char UCHAR;
typedef unsigned int UINT;
typedef unsigned short USHORT;
typedef unsigned long ULONG;
typedef	ULONG	*PULONG;
#define APIENTRY _pascal _far
#endif

/*
 *	OS/2 specific typedefs for DosCreateThread/beginthread, from bsedev.h
 */
typedef BYTE   _far  *PBYTE;
typedef USHORT	  TID;		/* tid	*/
typedef TID _far *PTID;
typedef void (_far *PFNTHREAD)(void);

/*
 *	begin- & endthread take care of some internal house keeping
 *	for threads in the C Runtime DLL, in particular the errno and
 *	_doserrno variables, enabling thread-specific error codes.
 *
 */
    
USHORT	APIENTRY DosBeginThread(PFNTHREAD threadFunc, PTID pTid, PBYTE pbStack);
void	APIENTRY DosEndThread(USHORT fTerminate, USHORT usExitCode,
			      PULONG semToClear);
/*
 *	_CRT_DLLinit() initiallizes some basic run-time services to allow
 *	calls to some run-time functions from DLL initialization routines
 *	or "stand-alone", loading the CRT DLL via DosLoadModule.
 *
 *	This is mostly useful for the printf() and malloc() families.
 *
 *	Note that this function only needs to be called in the startup
 *	function of a DLL if that DLL uses these calls _in_ the startup
 *	function, as that is called prior to loading the application's .EXE
 *	file.  Normal DLL functions called by your application do not
 *	need this support, as the CRT DLL is fully initialized by the
 *	application's .EXE startup code.
 *
 */

void		 _CRT_DLLinit(void);


#ifdef __BORLANDC__		// BIG ifdef, Borland Or Microsoft

#define BCVER4MAGIC	0x452			// __BORLANDC__ value at 4.0

//
//	provide access to _maxfarrealloc, to allow >1M malloc/realloc
//
int _far * _cdecl _CRT__maxfarMP(void);

#ifdef _CRTDLL_MULTIPROC

#define _maxfarrealloc	(*_CRT__maxfarMP())

#else	// _CRTDLL_MULTIPROC

extern  USHORT   _far _cdecl	_CRT__maxfar;
#define	_maxfarrealloc	_CRT__maxfar

#endif	// _CRTDLL_MULTIPROC

/*
 *	stdio.h replacment declarations
 */
#ifdef __STDIO_H

#undef stdin
#undef stdout
#undef stderr
#undef stdaux
#undef stdprn

extern FILE _far * _cdecl _CRT__streamsMP(void);
extern FILE _far * _cdecl _CRT__getstream(int index);

#ifdef _CRTDLL_MULTIPROC

#define _streams	(_CRT__streamsMP())

#define	stdin _CRT__getstream(0)
#define	stdout _CRT__getstream(1)
#define	stderr _CRT__getstream(2)
#define	stdaux _CRT__getstream(3)
#define	stdprn _CRT__getstream(4)

#else	// _CRTDLL_MULTIPROC

extern	FILE	_far _cdecl _CRT__streams[];

#define stdin   (&_CRT__streams[0])
#define stdout  (&_CRT__streams[1])
#define stderr  (&_CRT__streams[2])
#define stdaux  (&_CRT__streams[3])
#define stdprn  (&_CRT__streams[4])

#endif	// _CRTDLL_MULTIPROC

#endif	// __STDIO_H

/*
 *	stdio.h/io.h replacment declarations
 */
#if defined(__STDIO_H) || defined(__IO_H)
#ifdef _CRTDLL_MULTIPROC

extern int _far * _cdecl _CRT__openfdMP(void);
#define _openfd	(_CRT__openfdMP())

#else	// _CRTDLL_MULTIPROC

extern	int _far *	_cdecl	_CRT__openfd;
#define		_openfd		_CRT__openfd

#endif	// _CRTDLL_MULTIPROC
#endif	// STDIO or IO

/*
 *	ctype.h replacment declarations
 */
#ifdef __CTYPE_H
#ifdef _CRTDLL_COMMONCTYPE

#undef isalnum
#undef isalpha
#undef iscntrl
#undef isgraph
#undef islower
#undef isprint
#undef ispunct
#undef isspace
#undef isupper
#undef isxdigit

#ifdef _CRTDLL_MULTIPROC

extern unsigned char _far * _cdecl _CRT__ctypeMP();
#define _ctype (_CRT__ctypeMP())

#else	// _CRTDLL_MULTIPROC

extern	unsigned char _far *	_cdecl	_CRT__ctype;
#define		_ctype			_CRT__ctype

#endif	// _CRTDLL_MULTIPROC

#endif	// _CRTDLL_COMMONCTYPE
#endif	// __CTYPE_H

/*
 *	fcntl.h
 */
#if defined(__FCNTL_H) || defined(__STDLIB_H)

extern	int _far * _cdecl _CRT__fmodeMP(void);

#ifdef _CRTDLL_MULTIPROC

#define _fmode		(*_CRT__fmodeMP())

#else	// _CRTDLL_MULTIPROC

extern	int _far	_cdecl _CRT__fmode;

#define _fmode		_CRT__fmode

#endif	//	_CRTDLL_MULTIPROC
#endif	// __FCNTL_H

/*
 *	time.h replacment declarations
 */
#ifdef __TIME_H

#undef timezone
#undef daylight
#undef tzname
#undef _timezone
#undef _daylight
#undef _tzname

extern	char _far * _far * _cdecl _CRT__tznameMP(void);
extern	long _far * _cdecl _CRT__timezoneMP(void);
extern	int _far * _cdecl _CRT__daylightMP(void);

#ifdef _CRTDLL_MULTIPROC

#if __BORLANDC__ >= BCVER4MAGIC

#define _tzname		(_CRT__tznameMP())
#define _timezone	(*_CRT__timezoneMP())
#define _daylight	(*_CRT__daylightMP())

#else	// bc40

#define tzname		(_CRT__tznameMP())
#define timezone	(*_CRT__timezoneMP())
#define daylight	(*_CRT__daylightMP())

#endif	// bc40

#else	// _CRTDLL_MULTIPROC

extern	char _far *		_cdecl _CRT__tzname[];
extern	long _far		_cdecl _CRT__timezone;
extern	int _far		_cdecl _CRT__daylight;

#if __BORLANDC__ >= BCVER4MAGIC

#define _tzname		_CRT__tzname
#define _timezone	_CRT__timezone
#define _daylight	_CRT__daylight

#else	// bc40

#define tzname		_CRT__tzname
#define timezone	_CRT__timezone
#define daylight	_CRT__daylight

#endif	// bc40
#endif	//	_CRTDLL_MULTIPROC
#endif // __TIME_H

// bug in dos.h, declared as getdrive(), sourced as _getdrive()
#ifdef __DOS_H
#ifndef getdrive
#define		getdrive	_getdrive
#endif
#endif

/*
 *	errno.h/stdlib.h/dos.h replacment declarations
 */
#if defined(__ERRNO_H) || defined(__STDLIB_H) || defined(__DOS_H)

#undef	sys_errlist
#undef	_sys_errlist
#undef	_sys_nerr
#undef	sys_nerr

int _far *		_cdecl _CRT_errnoMP(void);
int _far *		_cdecl _CRT__doserrnoMP(void);
char _far * _far *	_cdecl	_CRT__sys_errlistMP(void);

#ifdef _CRTDLL_MULTIPROC

/*
 *	The CRT DLL still updates the application's errno/_doserrno variables
 *	in a multi-process/multi-thread situation.  However, the value is
 *	can be over-written by an erro in another thread, so you should
 *	usually leave this functional access as is.  However, this can
 *	sometimes interfere with application code that only knows how to
 *	access a __near CRT variable, therefore not allowing the error
 *	information to get to bark to the CRT DLL.  In this case, you may
 *	need to #undef the following, to allow access to the locally defined
 *	error information.  See the CRT DLL chapter of the 286|DOS Extender
 *	manual for a more detailed explanation of this possible problem.
 */

#define _doserrno	(*_CRT__doserrnoMP())
#define errno		(*_CRT_errnoMP())

int _far *	_cdecl _CRT__sys_nerrMP(void);

#if __BORLANDC__ >= BCVER4MAGIC

#define _sys_errlist	(*_CRT__sys_errlistMP())
#define _sys_nerr	(*_CRT__sys_nerrMP())
#define sys_errlist	(*_CRT__sys_errlistMP())
#define sys_nerr	(*_CRT__sys_nerrMP())

#else	// bc40

#define sys_errlist	(*_CRT__sys_errlistMP())
#define sys_nerr	(*_CRT__sys_nerrMP())

#endif	// bc40

#else	// _CRTDLL_MULTIPROC

extern	int _far	_cdecl	_CRT_errno;
extern	int _far	_cdecl _CRT__doserrno;
extern	char _far * _far _cdecl	_CRT__sys_errlist[];
extern	int _far	_cdecl _CRT__sys_nerr;

/*
 *	The CRT DLL updates the application's local errno/_doserrno variables
 *	on any CRT DLL error.  Therefore these do not need to be exported
 *	in a single process application.  Note that they are still redefined
 *	in a multpiple process application, to provide thread-specific error
 *	support.
 *
 *	If you do need to explicitly set errno, and then have perror() work
 *	on the value you set explicitly in your application, then #define
 *	_CRTDLL_USEDLLERRNO to have the DLL copy of errno kept in sync
 *	with the local copy.  This is only necesary if your code needs
 *	to look like the following:
 *
 *		errno = EACCES;
 *		perror("I set errno myself, not the runtime library!");
 */

#ifdef _CRTDLL_USEDLLERRNO
#define _doserrno	_CRT__doserrno
#define errno		_CRT_errno
#endif

#if __BORLANDC__ >= BCVER4MAGIC

#define _sys_errlist	_CRT__sys_errlist
#define _sys_nerr	_CRT__sys_nerr
#define sys_errlist	_CRT__sys_errlist
#define sys_nerr	_CRT__sys_nerr

#else	// bc40

#define sys_errlist	_CRT__sys_errlist
#define sys_nerr	_CRT__sys_nerr

#endif	// bc40

#endif	// _CRTDLL_MULTIPROC
#endif	// STDLIB, ERRNO, or DOS_H

/*
 *	conio.h replacment declarations
 */
#ifdef __CONIO_H

#undef	directvideo
#undef	_directvideo
#undef	wscroll
#undef	_wscroll

/*
 *	If you need to access the lowlevel _video struct directly,
 *	#define CRTUSE_VIDEO in your source, or take out this #ifdef
 *	If you don't, your changes to _video will have no effect,
 *	as you will only change a local .EXE copy of the struct, not
 *	the copy that the CRT DLL uses.
 *
 *	Declare a VIDEOREC *, then assign _CRT__video() to it, i.e.
 *	VIDEOREC *v1 = _CRT__video();
 *
 *	Then use v1 to access the lowlevel video struct.
 *
 *	_video is also then defined as error
 */

#ifdef _CRTDLL_USEVIDEO
typedef unsigned char uchar;

typedef struct
{
        uchar windowx1;
        uchar windowy1;
        uchar windowx2;
        uchar windowy2;
        uchar attribute;
        uchar normattr;
        uchar currmode;
        uchar screenheight;
        uchar screenwidth;
        uchar graphicsmode;
        uchar snow;
        union {
                char far * p;
                struct { unsigned off,seg; } u;
        } displayptr;
} VIDEOREC;
#endif	// _CRTDLL_USEVIDEO

extern	int _far * _cdecl _CRT__directvideoMP(void);
extern	int _far * _cdecl _CRT__wscrollMP(void);

#ifdef _CRTDLL_MULTIPROC

#define	_wscroll	(*_CRT__wscrollMP())

#if __BORLANDC__ >= BCVER4MAGIC
#define	_directvideo	(*_CRT__directvideoMP())
#else
#define	directvideo	(*_CRT__directvideoMP())
#endif

#ifdef _CRTDLL_USEVIDEO

extern VIDEOREC _far * _cdecl _CRT__video(void);
#define _video	__CRTDLL_video_error@@@;

#endif	// _CRTDLL_USEVIDEO

#else	// _CRTDLL_MULTIPROC

extern	int _far	_cdecl	_CRT__directvideo;
extern	int _far	_cdecl	_CRT__wscroll;

#define	_wscroll	_CRT__wscroll

#if __BORLANDC__ >= BCVER4MAGIC
#define	_directvideo	_CRT__directvideo
#else
#define	directvideo	_CRT__directvideo
#endif

#ifdef _CRTDLL_USEVIDEO
extern	VIDEOREC _far	_cdecl		_CRT__video;
#define		_video			_CRT__video
#endif

#endif	// _CRTDLL_MULTIPROC

#endif	// __CONIO_H

#else		// BIG __BORLAND__ #ifdef, now doing Microsoft

#if defined(_INC_ERRNO) || defined(_INC_STDLIB)

#undef	sys_errlist
#undef	_sys_errlist
#undef	_sys_nerr
#undef	sys_nerr

#ifdef _CRTDLL_MULTIPROC

int	_far *		_cdecl	_CRT_errnoMP(void);
int	_far *		_cdecl	_CRT__doserrnoMP(void);
char	_far * _far *	_cdecl	_CRT__sys_errlistMP(void);
int	_far *		_cdecl	_CRT__sys_nerrMP(void);

/*
 *	The CRT DLL still updates the application's errno/_doserrno variables
 *	in a multi-process/multi-thread situation.  However, the value is
 *	can be over-written by an erro in another thread, so you should
 *	usually leave this functional access as is.  However, this can
 *	sometimes interfere with application code that only knows how to
 *	access a __near CRT variable, therefore not allowing the error
 *	information to get to bark to the CRT DLL.  In this case, you may
 *	need to #undef the following, to allow access to the locally defined
 *	error information.  See the CRT DLL chapter of the 286|DOS Extender
 *	manual for a more detailed explanation of this possible problem.
 */

#define _doserrno	(*_CRT__doserrnoMP())
#define errno		(*_CRT_errnoMP())
#define _sys_errlist	(*_CRT__sys_errlistMP())
#define _sys_nerr	(*_CRT__sys_nerrMP())
#define sys_errlist	(*_CRT__sys_errlistMP())
#define sys_nerr	(*_CRT__sys_nerrMP())

#else	// _CRTDLL_MULTIPROC

extern	int _far	_cdecl	_CRT_errno;
extern	int _far	_cdecl _CRT__doserrno;
extern	char _far *	_cdecl	_CRT__sys_errlist[];
extern	int _far	_cdecl _CRT__sys_nerr;

/*
 *	The CRT DLL updates the application's local errno/_doserrno variables
 *	on any CRT DLL error.  Therefore these do not need to be exported
 *	in a single process instance.  Note that they are still redefined
 *	in a multpiple process application, to provide thread-specific error
 *	support.
 *
 *	If you do need to explicitly set errno, and then have perror() work
 *	on the value you set explicitly in your application, then #define
 *	_CRTDLL_USEDLLERRNO to have the DLL copy of errno kept in sync
 *	with the local copy.  This is only necesary if your code needs
 *	to look like the following:
 *
 *		errno = EACCES;
 *		perror("I set errno myself, not the runtime library!");
 */

#ifdef _CRTDLL_USEDLLERRNO
#define _doserrno	_CRT__doserrno
#define errno		_CRT_errno
#endif

#define _sys_errlist	_CRT__sys_errlist
#define _sys_nerr	_CRT__sys_nerr
#define sys_errlist	_CRT__sys_errlist
#define sys_nerr	_CRT__sys_nerr

#endif	// _CRTDLL_MULTIPROC
#endif	// _INC_ERRNO, INC_STDLIB

#ifdef _INC_TIME

#undef timezone
#undef daylight
#undef tzname
#undef _timezone
#undef _daylight
#undef _tzname

#ifdef _CRTDLL_MULTIPROC

extern	char _far * _far * _cdecl _CRT__tznameMP(void);
extern	long _far * _cdecl _CRT__timezoneMP(void);
extern	int _far * _cdecl _CRT__daylightMP(void);

#define _tzname		(_CRT__tznameMP())
#define _timezone	(*_CRT__timezoneMP())
#define _daylight	(*_CRT__daylightMP())

#else	// _CRTDLL_MULTIPROC

extern	char _far *		_cdecl _CRT__tzname[];
extern	long _far		_cdecl _CRT__timezone;
extern	int _far		_cdecl _CRT__daylight;

#define _tzname		_CRT__tzname
#define _timezone	_CRT__timezone
#define _daylight	_CRT__daylight

#endif	//	_CRTDLL_MULTIPROC
#endif	//	_INC_TIME


#ifdef _INC_STDIO

#undef stdin
#undef stdout
#undef stderr
#undef stdaux
#undef stdprn

#ifdef _CRTDLL_MULTIPROC

extern FILE _far * _cdecl _CRT__iobMP(void);
extern FILE _far * _cdecl _CRT__getstreamMP(int index);

#define _iob		(_CRT__iobMP())

#define	stdin _CRT__getstreamMP(0)
#define	stdout _CRT__getstreamMP(1)
#define	stderr _CRT__getstreamMP(2)
#define	stdaux _CRT__getstreamMP(3)
#define	stdprn _CRT__getstreamMP(4)

#else	// _CRTDLL_MULTIPROC

extern	FILE	_far _cdecl _CRT__iob[];

#define _iob	_CRT__iob

#define stdin   (&_CRT__iob[0])
#define stdout  (&_CRT__iob[1])
#define stderr  (&_CRT__iob[2])
#define stdaux  (&_CRT__iob[3])
#define stdprn  (&_CRT__iob[4])

#endif	// _CRTDLL_MULTIPROC
#endif	// __STDIO_H

#ifdef _INC_PROCESS
#define	_p_overlay	_CRT__p_overlay
extern int __far _CRT__p_overlay;
#endif

#ifdef _INC_STDLIB
#define __mb_cur_max	_CRT___mb_cur_max
extern int __far _CRT___mb_cur_max;
#endif

#ifdef _INC_MATH
#ifndef DLL_NOFLOAT

#define acos	CRT_acos
#define asin	CRT_asin
#define atan	CRT_atan
#define atan2	CRT_atan2
#define _cabs	CRT__cabs
#define ceil	CRT_ceil
#define cos	CRT_cos
#define cosh	CRT_cosh
#define exp	CRT_exp
#define fabs	CRT_fabs
#define floor	CRT_floor
#define fmod	CRT_fmod
#define frexp	CRT_frexp
#define _hypot	CRT__hypot
#define _j0	CRT__j0
#define _j1	CRT__j1
#define _jn	CRT__jn
// #define ldexp	CRT_ldexp
#define log	CRT_log
#define log10	CRT_log10
#define modf	CRT_modf
#define pow	CRT_pow
#define sin	CRT_sin
#define sinh	CRT_sinh
#define sqrt	CRT_sqrt
#define tan	CRT_tan
#define tanh	CRT_tanh
#define _y0	CRT__y0
#define _y1	CRT__y1
#define _yn	CRT__yn

double	__cdecl CRT_acos(double);
double	__cdecl CRT_asin(double);
double	__cdecl CRT_atan(double);
double	__cdecl CRT_atan2(double, double);
double	__cdecl CRT__cabs(struct _complex);
double	__cdecl CRT_ceil(double);
double	__cdecl CRT_cos(double);
double	__cdecl CRT_cosh(double);
double	__cdecl CRT_exp(double);
double	__cdecl CRT_fabs(double);
double	__cdecl CRT_floor(double);
double	__cdecl CRT_fmod(double, double);
double	__cdecl CRT_frexp(double, int *);
double	__cdecl CRT__hypot(double, double);
double	__cdecl CRT__j0(double);
double	__cdecl CRT__j1(double);
double	__cdecl CRT__jn(int, double);
// double	__cdecl CRT_ldexp(double, int);
double	__cdecl CRT_log(double);
double	__cdecl CRT_log10(double);
double	__cdecl CRT_modf(double, double *);
double	__cdecl CRT_pow(double, double);
double	__cdecl CRT_sin(double);
double	__cdecl CRT_sinh(double);
double	__cdecl CRT_sqrt(double);
double	__cdecl CRT_tan(double);
double	__cdecl CRT_tanh(double);
double	__cdecl CRT__y0(double);
double	__cdecl CRT__y1(double);
double	__cdecl CRT__yn(int, double);

#endif		// DLL_NOFLOAT
#endif		// INC_MATH

#endif		// ! __BORLAND__, just finished MS

#ifdef __cplusplus
	}
#endif

#endif	/* _INC_CRTDLL */
