/*---------------------------------------------------------------------------*
 |           PDFlib - A library for generating PDF on the fly                |
 +---------------------------------------------------------------------------+
 |          Copyright (c) 1997-2002 PDFlib GmbH. All rights reserved.        |
 *---------------------------------------------------------------------------*/

/* $Id: pdflibdl.c,v 1.1.2.7 2002/05/29 15:07:37 tm Exp $
 *
 * C wrapper code for dynamically loading the PDFlib DLL at runtime.
 *
 * Note: This module is not supported on all platforms.
 *
 */

#include <stdlib.h>

#ifdef WIN32

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winbase.h>
#undef WIN32_LEAN_AND_MEAN

#elif defined(__MVS__)

#include <dynit.h>
#include <dll.h>

#endif

#include "pdflibdl.h"

#ifdef WIN32

#ifdef _DEBUG
    #define DEBUG
#endif

#define PDF_LOADDLL(name)		LoadLibrary(name)
#define PDF_GETPFN(handle, name)	GetProcAddress(handle, name)
#define PDF_FREEDLL(handle)		FreeLibrary(handle)
#define PDF_HANDLE			HINSTANCE
#define PDF_DLLNAME			"pdflib.dll"

#elif defined(__MVS__)

#define PDF_LOADDLL(name)		dllload(name)
#define PDF_GETPFN(handle, name)	dllqueryfn(handle, name)
#define PDF_FREEDLL(handle)		dllfree(handle)
#define PDF_HANDLE			dllhandle *
#define PDF_DLLNAME			"PDFLIB"

#else

#error No DLL loading code for this platform available!

#endif


#ifdef DEBUG
#define PDF_FATAL(msg)	fprintf(stderr, msg)
#else
#define PDF_FATAL(msg)	/* */
#endif

/* Load the PDFlib DLL and fetch the API structure */

PDFLIB_API PDFlib_api * PDFLIB_CALL
PDF_boot_dll(void)
{
    PDFlib_api *PDFlib, *(PDFLIB_CALL *get_api)();
    float major, minor;
    PDF_HANDLE handle;

    /* load the PDFLIB DLL... */
    handle = (void *) PDF_LOADDLL(PDF_DLLNAME);

    if (!handle)
    {
	PDF_FATAL("Error: couldn't load PDFlib DLL\n");
	return NULL;
    }

    /* ...and fetch function pointers */
    get_api = (PDFlib_api *(PDFLIB_CALL *)()) PDF_GETPFN(handle, "PDF_get_api");

    if (get_api == NULL)
    {
	PDF_FATAL("Error: couldn't find function PDF_get_api in PDFlib DLL\n");
	PDF_FREEDLL((PDF_HANDLE) handle);
	return NULL;
    }

    PDFlib = (*get_api)();

    PDFlib->PDF_boot();

    /*
     * Check the version numbers of the loaded DLL against that of
     * the included header file to avoid version mismatch.
     */
    major = PDFlib->PDF_get_value(NULL, "major", 0);
    minor = PDFlib->PDF_get_value(NULL, "minor", 0);

    if (major != PDFLIB_MAJORVERSION || minor != PDFLIB_MINORVERSION) {
	PDF_FATAL("Error: Loaded wrong version of PDFlib DLL\n");
	PDFlib->PDF_shutdown();
	PDF_FREEDLL((PDF_HANDLE) PDFlib->handle);
	return NULL;
    }

    PDFlib->handle = handle;

    return PDFlib;
}

/* unload the previously loaded PDFlib DLL */

PDFLIB_API void PDFLIB_CALL
PDF_shutdown_dll(PDFlib_api *PDFlib)
{
    if (!PDFlib || !PDFlib->handle)
	return;

    PDFlib->PDF_shutdown();

    PDF_FREEDLL((PDF_HANDLE) PDFlib->handle);
}
