/*
 * dll.h
 *
 * Definitions for DLLLib
 *
 *  1994 Straylight
 */

#ifndef __dll_h
#define __dll_h

#ifdef __cplusplus
  extern "C" {
#endif

/*----- External dependencies ---------------------------------------------*/

#ifndef __os_h
  #include "os.h"
#endif

#ifndef __kernel_h
  #include "kernel.h"
#endif

#ifndef __wimp_h
  #include "wimp.h"
#endif

/*----- Type definitions for DLLs -----------------------------------------*/

typedef void *dll;                      /* What a DLL handle looks like    */

typedef struct                          /* An external DLL table           */
{
  char *name;                           /* Name of DLL to load             */
  int version;                          /* Minimum acceptable version      */
  char *entryNames;                     /* Pointer to entry name table     */
  void *branchTable;                    /* Pointer to branch table to fill */
}
dll_table;

typedef struct                          /* A DLL information structure     */
{
  dll d;                                /* The handle of the DLL           */
  char *name;                           /* The DLL's textual name          */
  int version;                          /* The DLL's version number        */
  char *author;                         /* The name of the DLL's author    */
  unsigned instSize;                    /* Size of the DLL's instance vars */
}
dll_infostr;

/*----- Interface to DLLManager SWIs --------------------------------------*
 *
 * The sharper eyed amongst you may have noticed that DLL_Prologue doesn't
 * have an entry point here.  This is for several reasons:
 *
 * 1. It's not a very safe call to make if you don't know what you're doing.
 *    Then again, nor are any of the others.
 *
 * 2. It's not all that useful unless you're writing in assembler, in which
 *    case you can call the SWI directly.
 *
 * 3. Hopefully, the cdll program can generate all the code you'll ever need
 *    which calls DLL_Prologue, and you'll never need to mess about with it.
 *
 * Several of the calls listed here suffer badly from lack of usefulness.
 * The only ones that you're really likely to want to use are dll_nameApp,
 * dll_info and dll_findEntry.
 */

os_error *dll_find(const char */*name*/, int /*version*/, dll */*d*/);
os_error *dll_findFromTable(const dll_table */*table*/, int /*entries*/);
os_error *dll_load(void */*buffer*/, const char */*name*/);
os_error *dll_lose(dll /*d*/);
os_error *dll_appDying(void);
os_error *dll_giveCLibData(void */*data*/);
os_error *dll_findCLibData(void **/*p*/);
os_error *dll_instanceVars(void */*buffer*/, int */*size*/, int */*magic*/);
os_error *dll_setInstanceVars(dll /*d*/, void */*workspace*/);
os_error *dll_appData(void);
os_error *dll_readStackPtr(int */*sp*/);
os_error *dll_setStackPtr(int /*sp*/);
os_error *dll_nameApp(const char */*name*/);
os_error *dll_info(dll /*d*/, dll_infostr */*i*/);
os_error *dll_findEntry(dll /*d*/, const char */*name*/,
                        void (**/*entry*/)());
os_error *dll_saveHandle(int */*handle*/);
os_error *dll_restoreHandle(int */*handle*/);
os_error *dll_findInstanceVars(dll /*d*/, void **/*addr*/);
os_error *dll_registerAppEntryTable(void (**/*btable*/)(), char */*names*/);
os_error *dll_findAppEntry(char */*name*/, void (**/*func*/)());
os_error *dll_setExtensionTable(void (**/*btable*/)(), char */*names*/);

/*----- Doing nothing at all, but without warnings! -----------------------*/

#define _dll_nothing ((void)(0))

/*----- Registration with DLLManager --------------------------------------*/

#ifndef _dll_NODLL

void _dll_appspace(void);
void _dll_clibdata(void);
#define _dll_setname(name) (void)dll_nameApp(name)

#else

#define _dll_appspace(x) _dll_nothing
#define _dll_clibdata(x) _dll_nothing
#define _dll_setname(name) _dll_nothing

#endif

/*----- Handling *commands ------------------------------------------------*/

#ifndef _dll_NODLL

int _dll_system(const char */*command*/);
int _dll_ksystem(const char */*command*/, int /*chain*/);
os_error *_dll_oscli(const char */*command*/);
os_error *_dll_starttask(const char */*command*/);

#else

#define _dll_system(x) system(x)
#define _dll_ksystem(x) _kernel_system(x)
#define _dll_oscli(x) os_cli(x)
#define _dll_starttask(x) wimp_starttask(x)

#endif

/*----- Handling of extension DLLs ----------------------------------------*/

dll _dll_loadExtension(const char */*name*/);
void _dll_freeExtension(dll /*d*/);

/*----- setjmp and longjmp support ----------------------------------------*/

#ifndef _dll_NODLL

int _dll_setjmp(void);
void _dll_longjmped(int /*sp*/);

#else

#define _dll_setjmp(x) (0)
#define _dll_longjmped(x) ((x)=(x))

#endif

/*----- Other miscellaneous calls -----------------------------------------*/

#ifndef _dll_NODLL

void _dll_giveMemory(void);

#else

#define _dll_giveMemory(x) _dll_nothing

#endif

/*----- External names for extentry functions -----------------------------*/

#ifdef _DLL

#define _dllEntry(name) _dllEntry_ ## name

#else

#define _dllEntry(name) name

#endif

#ifndef _dll_NODLL

#define _extEntry(name) _extEntry_ ## name
#define _dll_static

#else

#define _extEntry(name) name
#define _dll_static static

#endif

#ifdef __cplusplus
  }
#endif

#endif
