/*<html><pre>*/
#include <../source/TAL/objbase.h>
#include <../source/PAL/dataman.h>
#include <../source/PAL/oshead.h>

/*
 *	Defined in "PAL/dataman.h"
 */
global_data_t		libv_global_data=
{
	LIBV_GLOBAL_MAGIC,	/* magic */
	0,					/* number of successful calls to threadCreate() */
	NULL,				/* log_file */
	LOG_ERROR,			/* log_upper_level */
#ifdef	MALLOC_DEBUG
	0,					/* Total number of pointers and handles */
	NULL,				/* Pointer hash table */
	NULL,				/* Handle hash table */
#endif	/* MALLOC_DEBUG */
#ifdef	NT_CONSOLE
	INVALID_HANDLE_VALUE,	/* input handle */
	INVALID_HANDLE_VALUE,	/* output handle */
	FALSE,					/* console was AllocConsole()'d */
#endif	/* NT_CONSOLE */
	TYPED_STACK_EMPTY_INITIALIZER	/* log callbacks */
};

thread_data_t		libv_thread_data=
{
	LIBV_TSD_MAGIC,		/* magic */
	0xFF,				/* constant_alpha - opaque */
	/* input state */
	{
		input_locale_english,
	    false,
    	false,
	    false,
    	false
	},
	1000,1000,			/* metafile extents */
#ifndef		RIGHT_SLASHED
	&unix_file_apis		/* file IO & FS-processing routines */
#endif		/* RIGHT_SLASHED */
	/* All other members must be 0/NULL */
};

#ifdef	MALLOC_DEBUG

/*
**	Memory management support routines
*/
V_LOCAL global_data_p AllocateHashes(void);

V_LOCAL mem_list_entry_p V_CALL LockMemHash(void)
{
	/* Note: we leave global data locked */
	return libvLockGlobal()->memory_hash;
}

V_LOCAL mem_list_entry_p V_CALL LockObjHash(void)
{
	/* Note: we leave global data locked */
	return libvLockGlobal()->object_hash;
}

V_LOCAL mem_list_entry_p V_CALL LockMemHashStub(void)
{
	/* Note: we leave global data locked */
	return AllocateHashes()->memory_hash;
}

V_LOCAL mem_list_entry_p V_CALL LockObjHashStub(void)
{
	/* Note: we leave global data locked */
	return AllocateHashes()->object_hash;
}

mem_list_entry_p (V_CALL *libvLockMemoryHash)(void) = LockMemHashStub;
mem_list_entry_p (V_CALL *libvLockObjectHash)(void) = LockObjHashStub;

V_LOCAL global_data_p AllocateHashes(void)
{
	global_data_t *gd=libvLockGlobal();
	gd->memory_hash=(mem_list_entry_p)
		calloc(MEMORY_HASH_LIMIT+1,sizeof(mem_list_entry_t));
	gd->object_hash=(mem_list_entry_p)
		calloc(OBJECT_HASH_LIMIT+1,sizeof(mem_list_entry_t));
	libvLockMemoryHash=LockMemHash;
	libvLockObjectHash=LockObjHash;
	gd->hash_ref_count=0;
	/* Note: we leave global data locked */
	return gd;
}

/*	Note: we assume that global data is locked ! */
void	V_CALL libvHashRef(void)
{
	libv_global_data.hash_ref_count++;
}

/*	Note: we assume that global data is locked ! */
void	V_CALL libvHashUnref(void)
{
	if(--libv_global_data.hash_ref_count <= 0)
	{
		if(libv_global_data.memory_hash != NULL)
		{
			free(libv_global_data.memory_hash);
			libv_global_data.memory_hash=NULL;
		}
		if(libv_global_data.object_hash != NULL)
		{
			free(libv_global_data.object_hash);
			libv_global_data.object_hash=NULL;
		}
		libvLockMemoryHash=LockMemHashStub;
		libvLockObjectHash=LockObjHashStub;
	}
}

#endif	/* MALLOC_DEBUG */

/*
**	Locks / inlocks implemented in PAL/sched.c
*/

#ifdef		__WIN32__

void	V_CALL
libvError(char *msg)
{
	MessageBoxA(NULL,msg,"LibV",MB_OK|MB_ICONHAND);
}

V_LOCAL		int	nt_version = -2;

int	V_CALL
ntGetVersion(void)
{
	if(nt_version==-2)
	{
    	/* First call */
		OSVERSIONINFO vi;
		memZero(&vi,sizeof(OSVERSIONINFO));
		vi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
		GetVersionEx(&vi);
		if(vi.dwPlatformId == VER_PLATFORM_WIN32_NT)
        	nt_version=(int)vi.dwMajorVersion;
		else
        	nt_version=-1;
	}
	return nt_version;
}

#elif		defined(__UNIX__) /* !__WIN32__ */

void		V_CALL
libvError(char *msg)
{
	fprintf(stderr,"LibV error: %s.\n",msg);
}

#endif		/* __WIN32__ */

#if		defined(BUILD_DLL) && defined(__WIN32__)

#include <../source/PAL/argsused.h>
BOOL WINAPI
DllMain(HINSTANCE hInstance,DWORD fdwReason,LPVOID lpvReserved)
{
	/* Nothing to do */
	switch(fdwReason)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
	}
	return TRUE;
}

#endif	/* BUILD_DLL && __WIN32__ */

/*</pre></html>*/
/*EOF*/
