
/*
**  $VER: personal_datatypes_io.c 5.1 (21.10.96)
**
**  C source for personal_datatypes_io.library.
**  SAS/C source code.
**
**  Copyright © 1996 Cloanto Italia srl
**	    All Rights Reserved
*/

#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/displayinfo.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <datatypes/datatypes.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/pictureclass.h>
#include <libraries/personal_io.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/datatypes.h>
#include <string.h>
#include <stdlib.h>

/*
 *  pragma aliases
 */
#define DOSBase picinfo->DOSBase
#define GfxBase picinfo->GfxBase
#define IntuitionBase picinfo->IntuitionBase
#define IconBase picinfo->IconBase

#define GOT_ALL(p) (((p)->ProcessData & (p)->ProcessedData) == (p)->ProcessData)

static UBYTE VersionStr[] = "$VER:Personal DataTypes IO Library 5.1 (21.10.96)";

/*
 *  The datatypes library just supports one picture type
 */
#define DATA_DTYPE	0
#define DATA_NUM		1
static struct DataInfoEntry DInfo[DATA_NUM] =
{
   {
	DATA_DTYPE,	/* Datatypes picture type code */
	DIF_LOAD	/* attr: planar images images can be loaded */
	| DIF_LOAD_24	/* attr: 24-bit chunky images can be loaded (V43 picture.datatype) */
	| DIF_LOADFILE	/* attr: the data is read from file */
	| DIF_RECOGNIZE	/* attr: datatype files can be recognized */
	| DIF_CONVERTED,/* attr: data provided by foreign picture libraries */
	PCDT_FORMAT	/* data: image format */
	| PCDT_IMAGE	/* data: image bitmap */
	| PCDT_PALETTE	/* data: color palette */
	| PCDT_PRJINFO	/* data: project information */
	| PCDT_DPI	/* data: dots per inch */
	| PCDT_EDGES	/* data: image origin */
	| PCDT_SRCDIM	/* data: source image format */
	| PCDT_TRANSPT	/* data: transparency type */
	| PCDT_TRANSPC,	/* data: transparent color */
	10000,		/* sort priority */
	"DataType",	/* full name */
	"DType",	/* short name */
	{ NULL, NULL, NULL }	/* file name suffixes */
   }
};
static LONG DataCount;	/* counter used by query functions */

/*
 *  library interface protos
 */
__asm BOOL __saveds GetFirstDataInfo(register __a0 struct DataInfo *);
__asm BOOL __saveds GetNextDataInfo(register __a0 struct DataInfo *);
__asm WORD __saveds GetPictureInfo(register __a0 struct PictureInfo *);
__asm LONG __saveds GetProgressBumps(register __a0 struct PictureInfo *);
__asm WORD __saveds ReadPicture(register __a0 struct PictureInfo *);
__asm WORD __saveds WritePicture(register __a0 struct PictureInfo *);
__asm void __saveds IOLibCleanup(register __a0 struct PictureInfo *);
__asm BOOL __saveds GetFirstOption(register __a0 struct DataInfo *, register __a1  struct DataOption *);
__asm BOOL __saveds GetNextOption(register __a0 struct DataInfo *, register __a1  struct DataOption *);
__asm void __saveds SetOption(register __a0 struct DataInfo *, register __a1  struct DataOption *);
__asm void __saveds ResetOptions(register __a0 struct DataInfo *);
__asm WORD __saveds PersonalIOPrivate1(void);
__asm WORD __saveds PersonalIOPrivate2(void);
__asm WORD __saveds PersonalIOPrivate3(void);

/*
 *  library's standard static protos
 */
static void CloseDTypeLib(void);
static BOOL CopyBitMap8(struct BitMap *, struct BitMap *, SHORT, SHORT, struct PictureInfo *);
static BOOL CopyBitMap24(Object *, struct BitMap *, SHORT, SHORT, struct PictureInfo *);
static WORD DoGetPictureInfo(struct PictureInfo *);
static WORD DoReadPicture(struct PictureInfo *);
static void GetDataInfo(struct DataInfo *, LONG);
static BOOL Handshake(struct DataInfo *);
static BOOL NewPictureClass(Object *);
static BOOL OpenDTypeLib(struct PictureInfo *);

/*
 * Picture datatype V43
 */
#ifndef PDTA_DestMode
 #define PDTA_DestMode       (DTA_Dummy + 251)
 #define DTM_READPIXELARRAY  (DTM_Dummy + 0x61)
 #define MODE_V42		0
 #define MODE_V43		1
#endif

/*
 * CyberGraphics stuff
 */
#ifndef RECTFMT_RGB
 #define RECTFMT_RGB 0
 #pragma libcall CyberGfxBase ReadPixelArray 78 76543921080a
 ULONG ReadPixelArray(APTR, UWORD, UWORD, UWORD, struct RastPort *, UWORD, UWORD, UWORD, UWORD, UBYTE);
#endif

/*
 * Masking types
 */
#define MSK_NONE		0  /* No masking */
#define MSK_HAS_MASK		1  /* A masking row followes each graphic row */
#define MSK_HAS_TRANSPCOL	2  /* Set each "transparentColor" pixel to color 0 */
#define MSK_LASSO		3  /* Draw a "transparentColor" rectangle
					around the picture, then fill with color 0
					(like Workbench "BACKFILL" icons) */
/*
 *  static data
 */
struct Library *DataTypesBase;
struct ExecBase *SysBase;

static BOOL Inspected;
static Object *DataObject;
static struct BitMapHeader DataBmHeader;
static ULONG DataDisplayID;





/*
 *  Standard query dispatcher:
 *  the n'th DataInfoEntry is copied to 'dinfo'.
 *
 *  This function does not usually need to be changed,
 *  unless the library supports run-time defined picture types.
 */
static void GetDataInfo(struct DataInfo *dinfo, LONG n)
{
	struct DataInfoEntry *de = &DInfo[n];
	LONG s;

	dinfo->Code = de->Code;
	dinfo->Flags = de->Flags;
	dinfo->ProcessData = de->ProcessData;
	dinfo->Priority = de->Priority;
	strcpy(dinfo->Name, de->Name);
	strcpy(dinfo->ShortName, de->ShortName);

	for (s = 3; --s >= 0; )
	{
		if (de->FileSuffix[s])
			strcpy(&dinfo->FileSuffix[s][0], de->FileSuffix[s]);
		else
			dinfo->FileSuffix[s][0] = 0;
	}
	memset(dinfo->pad, 0, sizeof(dinfo->pad));
}

/*
 *  Standard handshake function:
 *  FALSE is returned if handshaking fails,
 *  TRUE if it succeeds.
 */
static BOOL Handshake(struct DataInfo *dinfo)
{
	/*
	 * Cloanto is a registered trademark of Cloanto Italia srl;
	 * use of the following handshaking protocol requires a license,
	 * which is normally available at no charge for non-commercial use.
         */
	static UBYTE hs_text[] = "Cloanto®";

	if (dinfo->Version >= 5)  /* V5 of client interface feature */
	{
		if (dinfo->HandshakeText == NULL)
			return(FALSE);
		if (strcmp(dinfo->HandshakeText, hs_text) != 0)
			return(FALSE);
		/*
		 * the library internal string is passed
		 */
		dinfo->HandshakeText = hs_text;
	}
	return(TRUE);
}

/*
 *  Standard query function
 *  (support for multiple picture types is included)
 */
__asm BOOL __saveds GetFirstDataInfo(register __a0 struct DataInfo *dinfo)
{
	if (Handshake(dinfo))
	{
		DataCount = 0;
		if (DataCount < DATA_NUM)
		{
			GetDataInfo(dinfo, DataCount++);
			return(TRUE);
		}
	}
	return(FALSE);
}

/*
 *  Standard query function
 *  (support for multiple picture types is included)
 */
__asm BOOL __saveds GetNextDataInfo(register __a0 struct DataInfo *dinfo)
{
	if (Handshake(dinfo))
	{
		if (DataCount < DATA_NUM)
		{
			GetDataInfo(dinfo, DataCount++);
			return(TRUE);
		}
	}
	return(FALSE);
}

/*
 *  This function opens the datatypes library
 *  and initializes the DataTypesBase global pointer
 */
static BOOL OpenDTypeLib(struct PictureInfo *picinfo)
{
	SysBase = picinfo->SysBase;

	if (DataTypesBase == NULL)
		DataTypesBase = OpenLibrary("datatypes.library", 0);

	return((BOOL)(DataTypesBase != NULL));
}

/*
 *  This function close the datatypes library
 */
static void CloseDTypeLib()
{
	if (DataTypesBase)
	{
		CloseLibrary(DataTypesBase);
		DataTypesBase = NULL;
	}
}

/*
 *  V43.753 picture.datatype detection
 */
static BOOL NewPictureClass(Object *obj)
{
	ULONG	*methods, *method;

	if (GetDTAttrs(obj, DTA_Methods, &methods, TAG_DONE)) {
		method = methods;

		while (*method != 0xffffffff) {
			if (*method == DTM_READPIXELARRAY)
				return(TRUE);
			method++;
		}
	}
	return(FALSE);
}

/*
 *  Two step file recognition function (this function is called twice):
 *  1) file format is returned (fast response)
 *  2) image is loaded and its format is returned (slow response)
 */
static WORD DoGetPictureInfo(struct PictureInfo *picinfo)
{
	struct DataType *dtn;
	struct DataTypeHeader *dth;
	struct BitMapHeader *bmh;
	BPTR  lock;
	UBYTE strbuff[80];

	if (!Inspected)		/* step 1 */
	{
		strbuff[0] = 0;
		if (lock = Lock(picinfo->FileName, ACCESS_READ))
		{
			if (dtn = ObtainDataTypeA(DTST_FILE, (APTR)lock, NULL))
			{
				dth = dtn->dtn_Header;
				if (dth->dth_GroupID == GID_PICTURE)
					strcpy(strbuff, dth->dth_Name);
				ReleaseDataType(dtn);
			}
			UnLock(lock);
		}
		if (strbuff[0])  /* file format successfully identified */
		{
			GetDataInfo(&picinfo->Data, DATA_DTYPE);
			/*
			   the data names are modified
			   (the proper format name will be shown in the progress requester)
			*/
			strcpy(picinfo->Data.Name, strbuff);
			strcpy(picinfo->Data.ShortName, strbuff);
			strcat(picinfo->Data.Name, " (DataTypes)");
			strcat(picinfo->Data.ShortName, " (DT)");
			Inspected = TRUE;

			return(PIOERR_OK);
		}
		else return(PIOERR_BADTYPE);
	}
	else	/* step 2 */
	{
		Inspected = FALSE;
		GetDataInfo(&picinfo->Data, DATA_DTYPE);  /* restore original data names */

		/* get the picture object
		 */
		if (DataObject = NewDTObject(picinfo->FileName,
						DTA_SourceType, DTST_FILE,
						DTA_GroupID, GID_PICTURE,
						PDTA_Remap, FALSE,
						PDTA_DestMode, MODE_V43,  /* activates V43 mode, where available */
						TAG_DONE))
		{
			if (GetDTAttrs(DataObject,
					PDTA_ModeID, &DataDisplayID,
					PDTA_BitMapHeader, &bmh,
					TAG_DONE) == 2)   /* get the bitmap_header and mode_id */
			{
				if (DataDisplayID == INVALID_ID)
					DataDisplayID = LORES_KEY;

				if ((bmh->bmh_Depth > 8 &&
					  (bmh->bmh_Depth != 24 || !NewPictureClass(DataObject))) ||
					 (DataDisplayID & (HAM | DUALPF)) != 0)
				{
					DisposeDTObject(DataObject);
					DataObject = NULL;
					return(PIOERR_UIMGTYP);  /* unsupported image type */
				}
				picinfo->Width = bmh->bmh_Width;
				picinfo->Height = bmh->bmh_Height;
				picinfo->Depth = (bmh->bmh_Depth <= 8) ? bmh->bmh_Depth : 24;
				picinfo->PreviewDepth = (picinfo->Depth == 24) ? 24 : 0;
				/*
				 *  format information is now available
				 */
				picinfo->ProcessedData |= PCDT_FORMAT;
				DataBmHeader = *bmh;

				return(PIOERR_OK);
			}
			else
			{
				DisposeDTObject(DataObject);
				DataObject = NULL;
			}
		}
	}
	return(PIOERR_NODATA);
}

/*
 *  File recognition function
 */
__asm WORD __saveds GetPictureInfo(register __a0 struct PictureInfo *picinfo)
{
	WORD rc;

	if (picinfo->Version < 3)
		return(PIOERR_BADVER);

	if (!OpenDTypeLib(picinfo))
		return(PIOERR_BADTYPE);

	rc = DoGetPictureInfo(picinfo);

	/*
	 *  leave the library open if the DataObject holds a picture
	 *  (used later in ReadPicture())
	 */
	if (DataObject == NULL)
		CloseDTypeLib();

	return(rc);
}

/*
 *  Progress requester information function:
 *  there is no way to track datatype loading,
 *  the progress request bar will be ghosted
 */
__asm LONG __saveds GetProgressBumps(register __a0 struct PictureInfo *picinfo)
{
	return(0);
}

/*
 *  This function copies a "black box" 8-bit bitmap
 *  to a standard bitmap
 *  (V43 picture datatype only)
 */
static BOOL CopyBitMap8(struct BitMap *src,
			struct BitMap *dst,
			SHORT width,
			SHORT height,
			struct PictureInfo *picinfo)
{
	struct BitMap *temp_bm;
	struct RastPort rport, temp_rp;
	UBYTE *pixbuff, *pb;
	SHORT x, y;
	LONG rowsize, offs;
	BOOL ok = FALSE;

	if (GfxBase->LibNode.lib_Version >= 39)
	{
		if (temp_bm = AllocBitMap(width, 1, picinfo->Depth, BMF_CLEAR, NULL))	/* temp bitmap for ReadPixelLine8() */
		{
			rowsize = ((width + 15) >> 4) << 4;
			if (pixbuff = AllocMem(rowsize, 0))
			{
				ok = TRUE;
				InitRastPort(&rport);
				rport.BitMap = src;
				InitRastPort(&temp_rp);
				temp_rp.BitMap = temp_bm;

				for (y = 0; y < height; y++)
				{
					ReadPixelLine8(&rport, 0, y, width, pixbuff, &temp_rp);
					pb = pixbuff;
					if ((width & 31) == 0)	/* fast (aligned) copy */
					{
						offs = dst->BytesPerRow * y;
						for (x = width >> 5; --x >= 0; pb += 32, offs += 4)
							picinfo->ChunkyToBMap(pb, dst, offs);
					}
					else	/* normal copy */
					{
						picinfo->FastWritePix(dst, FBMP_INIT,0,0);
						for (x = 0; x < width; x++)
							picinfo->FastWritePix(dst, x, y, *pb++);

						picinfo->FastWritePix(dst, FBMP_FLUSH,0,0);
					}
				}
				FreeMem(pixbuff, rowsize);
			}
			FreeBitMap(temp_bm);
		}
	}
	return(ok);
}

/*
 *  This function copies a "black box" 24-bit object
 *  to a PersonalIO 24-bit bitmap
 *  (V43 picture datatype only)
 */
static BOOL CopyBitMap24(Object *src,
			 struct BitMap *dst,
			 SHORT width, SHORT height,
			 struct PictureInfo *picinfo)
{
	UBYTE *r_plane, *g_plane, *b_plane, *rpl, *gpl, *bpl;
	UBYTE *pixbuff, *pb;
	SHORT x, y;
	LONG rowsize, dst_mod;

	rowsize = width * 3;
	if (pixbuff = AllocMem(rowsize, 0))
	{
		r_plane = dst->Planes[0];
		g_plane = dst->Planes[1];
		b_plane = dst->Planes[2];
		dst_mod = dst->BytesPerRow;

		for (y = 0; y < height; y++)
		{
			DoMethod(src, DTM_READPIXELARRAY, pixbuff, RECTFMT_RGB, rowsize, 0, y, width, 1L);
			rpl = r_plane;
			gpl = g_plane;
			bpl = b_plane;
			pb = pixbuff;
			for (x = 0; x < width; x++)
			{
				*rpl++ = *pb++;
				*gpl++ = *pb++;
				*bpl++ = *pb++;
			}
			if (picinfo->PreviewDepth)
				picinfo->PreviewRow(dst, y);
			r_plane += dst_mod;
			g_plane += dst_mod;
			b_plane += dst_mod;
		}
		FreeMem(pixbuff, rowsize);
		return(TRUE);
	}
	else return(FALSE);
}

/*
 *  This function gets information from the image object
 *  previously loaded in the DoGetPictureInfo() function
 */
static WORD DoReadPicture(struct PictureInfo *picinfo)
{
	struct BitMap *bmap;
	struct Color *col;
	struct gpLayout layout;
	ULONG *creg;
	UBYTE *str;
	LONG  ncol;
	SHORT rc, c, nc;

	if (DataObject == NULL)
		return(PIOERR_NODATA);

	if (picinfo->ProcessData & PCDT_DPI)	/* get DPI information */
	{
		if (DataBmHeader.bmh_XAspect == 0 || DataBmHeader.bmh_YAspect == 0)
			picinfo->HorizDPI = picinfo->VertDPI = 1;
		else
		{
			picinfo->HorizDPI = DataBmHeader.bmh_YAspect;	/* inverted */
			picinfo->VertDPI = DataBmHeader.bmh_XAspect;
		}
		picinfo->ProcessedData |= PCDT_DPI;
	}
	if (picinfo->ProcessData & PCDT_SRCDIM)	/* get source information */
	{
		picinfo->ProcessedData |= PCDT_SRCDIM;
		/* Note: PageWidth/Height give unpredictable results */
		picinfo->SourceWidth = DataBmHeader.bmh_Width;
		picinfo->SourceHeight = DataBmHeader.bmh_Height;
	}
	if (picinfo->ProcessData & PCDT_EDGES)	/* get edge information */
	{
		picinfo->ProcessedData |= PCDT_EDGES;
		picinfo->LeftEdge = DataBmHeader.bmh_Left;
		picinfo->TopEdge = DataBmHeader.bmh_Top;
	}
	if (picinfo->ProcessData & PCDT_TRANSPC)	/* get transparent color */
	{
		picinfo->ProcessedData |= PCDT_TRANSPC;
		picinfo->TransparentColor = DataBmHeader.bmh_Transparent;
	}
	if (picinfo->ProcessData & PCDT_TRANSPT)	/* get transparency type */
	{
		picinfo->ProcessedData |= PCDT_TRANSPT;
		picinfo->TranspType = (DataBmHeader.bmh_Masking <= MSK_LASSO && DataBmHeader.bmh_Masking != MSK_HAS_MASK) ? DataBmHeader.bmh_Masking : MSK_NONE;
	}
	if ((picinfo->ProcessData & PCDT_PRJINFO) && picinfo->ProjInfo)
	{
		/*
		 *  get author, copyright and annotation
		 */
		if (GetDTAttrs(DataObject, DTA_ObjAuthor, &str, TAG_DONE) == 1) {
			if (str)
			{
				if (picinfo->Version >= 4)
				{
					if (picinfo->SetProjectInfo(picinfo->ProjInfo, AUTHOR_INFO, str))
						picinfo->ProcessedData |= PCDT_PRJINFO;
				}
				else
				{
					strncpy(picinfo->ProjInfo->Author, str, PRJINF_AUTSIZE);
					*(picinfo->ProjInfo->Author + (PRJINF_AUTSIZE - 1)) = 0;
					picinfo->ProcessedData |= PCDT_PRJINFO;
				}
			}
		}
		if (GetDTAttrs(DataObject, DTA_ObjCopyright, &str, TAG_DONE) == 1)
		{
			if (str)
			{
				if (picinfo->Version >= 4)
				{
					if (picinfo->SetProjectInfo(picinfo->ProjInfo, COPYRIGHT_INFO, str))
						picinfo->ProcessedData |= PCDT_PRJINFO;
				}
				else
				{
					strncpy(picinfo->ProjInfo->Copyright, str, PRJINF_COPYRSIZE);
					*(picinfo->ProjInfo->Copyright + (PRJINF_COPYRSIZE - 1)) = 0;
					picinfo->ProcessedData |= PCDT_PRJINFO;
				}
			}
		}
		if (GetDTAttrs(DataObject, DTA_ObjAnnotation, &str, TAG_DONE) == 1)
		{
			if (str)
			{
				if (picinfo->Version >= 4)
				{
					if (picinfo->SetProjectInfo(picinfo->ProjInfo, ANNOTATION_INFO, str))
						picinfo->ProcessedData |= PCDT_PRJINFO;
				}
				else
				{
					strncpy(picinfo->ProjInfo->Annotation, str, PRJINF_ANNOTSIZE);
					*(picinfo->ProjInfo->Annotation + (PRJINF_ANNOTSIZE - 1)) = 0;
					picinfo->ProcessedData |= PCDT_PRJINFO;
				}
			}
		}
	}

	rc = PIOERR_NODATA;

	layout.MethodID = DTM_PROCLAYOUT;	/* render the object */
	layout.gpl_GInfo = NULL;
	layout.gpl_Initial = TRUE;

	if (DoDTMethodA(DataObject, NULL, NULL, (Msg)&layout))
	{
		if ((picinfo->ProcessData & PCDT_IMAGE) && picinfo->BMap)	/* get image data */
		{
			if (GetDTAttrs(DataObject,
					PDTA_BitMap, &bmap,
					TAG_DONE) == 1 && bmap != NULL)
			{
				if (picinfo->BMap->Depth <= 8)
				{
					if (NewPictureClass(DataObject))
					{
						if (CopyBitMap8(bmap, picinfo->BMap, picinfo->Width, picinfo->Height, picinfo))
							picinfo->ProcessedData |= PCDT_IMAGE;
					}
					else	/* direct access */
					{
						BltBitMap(bmap, 0,0, picinfo->BMap, 0,0, picinfo->Width, picinfo->Height, 0xC0, 0xFF, NULL);
						picinfo->ProcessedData |= PCDT_IMAGE;
					}
				}
				else
				{
					if (CopyBitMap24(DataObject, picinfo->BMap, picinfo->Width, picinfo->Height, picinfo))
						picinfo->ProcessedData |= PCDT_IMAGE;
				}
				rc = (picinfo->ProcessedData & PCDT_IMAGE) ? PIOERR_OK : PIOERR_NOMEMORY;
			}
			else if (IoErr() == ERROR_NO_FREE_STORE)
				rc = PIOERR_NOMEMORY;
		}
		if ((picinfo->ProcessData & PCDT_PALETTE) && picinfo->Palette &&
			 picinfo->Depth <= 8)	/* get palette information */
		{
			if (GetDTAttrs(DataObject,
					PDTA_CRegs, &creg,
					PDTA_NumColors, &ncol,
					TAG_DONE) == 2 && creg != NULL && ncol > 0)
			{
				picinfo->ProcessedData |= PCDT_PALETTE;
				nc = 1 << picinfo->Depth;
				for (c = 0, col = picinfo->Palette; c < nc; c++, col++)
				{
					if (c < ncol)
					{
						col->Red = *creg++ >> 24;
						col->Green = *creg++ >> 24;
						col->Blue = *creg++ >> 24;
						col->EFlag = 0;
					}
					else	col->Red = col->Green = col->Blue = col->EFlag = 0;
				}
			}
			else if (IoErr() == ERROR_NO_FREE_STORE)
				rc = PIOERR_NOMEMORY;
		}
	}
	return(rc);
}

/*
 *  Image loading function
 */
__asm WORD __saveds ReadPicture(register __a0 struct PictureInfo *picinfo)
{
	WORD rc;

	if (!OpenDTypeLib(picinfo))
		return(PIOERR_BADTYPE);

	rc = DoReadPicture(picinfo);

	if (DataObject == NULL)
		CloseDTypeLib();

	return(rc);
}

/*
 *  Empty image saving function (this is a load-only library)
 */
__asm WORD __saveds WritePicture(register __a0 struct PictureInfo *picinfo)
{
	return(PIOERR_CANCEL);
}

/*
 *  This function is called after ReadPicture()
 *  to dispose the image object created in DoGetPictureInfo()
 *  and to close the datatypes library
 */
__asm void __saveds IOLibCleanup(register __a0 struct PictureInfo *picinfo)
{
	if (DataObject)
	{
		if (OpenDTypeLib(picinfo))
		{
			DisposeDTObject(DataObject);
			DataObject = NULL;
			CloseDTypeLib();
		}
	}
}


/* Data Option Functions (no options supported) */

__asm BOOL __saveds GetFirstOption(register __a0 struct DataInfo *dinfo,
				   register __a1 struct DataOption *option)
{
	return(FALSE);
}

__asm BOOL __saveds GetNextOption(register __a0 struct DataInfo *dinfo,
				  register __a1 struct DataOption *option)
{
	return(FALSE);
}

__asm void __saveds SetOption(register __a0 struct DataInfo *dinfo,
			      register __a1 struct DataOption *option)
{
}

__asm void __saveds ResetOptions(register __a0 struct DataInfo *dinfo)
{
}


/*
 *  Private PersonalIO functions
 */
__asm WORD __saveds PersonalIOPrivate1()
{
	return(PIOERR_CANCEL);
}

__asm WORD __saveds PersonalIOPrivate2()
{
	return(PIOERR_CANCEL);
}

__asm WORD __saveds PersonalIOPrivate3()
{
	return(PIOERR_CANCEL);
}
