You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
395 lines
8.2 KiB
395 lines
8.2 KiB
/*
|
|
* AmigaGuide Class
|
|
* A BOOPSI class for displaying AmigaGuide files.
|
|
* by Daniel "Trixie" Jedlicka
|
|
*/
|
|
|
|
#include "amiga/os3support.h"
|
|
#include "amigaguide_class.h"
|
|
|
|
#ifdef __amigaos4__
|
|
#define DISPATCHHOOK(func) static uint32 func(Class *cl, Object *o, Msg msg)
|
|
#else
|
|
#define DISPATCHHOOK(func) static ASM uint32 func(REG(a0, Class *cl),REG(a2, Object *o), REG(a1, Msg msg))
|
|
#endif
|
|
|
|
struct localObjectData
|
|
{
|
|
struct NewAmigaGuide nag;
|
|
struct AmigaGuideMsg *agm;
|
|
AMIGAGUIDECONTEXT agHandle;
|
|
uint32 agContextID;
|
|
uint32 agSignal;
|
|
};
|
|
|
|
struct Library *AmigaGuideBase = NULL;
|
|
struct AmigaGuideIFace *IAmigaGuide = NULL;
|
|
|
|
|
|
/* ********************************** function prototypes ************************************ */
|
|
|
|
DISPATCHHOOK(dispatchAGClass);
|
|
|
|
|
|
// class methods
|
|
uint32 om_new(Class *, Object *, struct opSet *);
|
|
uint32 om_dispose(Class *, Object *, Msg);
|
|
uint32 om_set(Class *, Object *, struct opSet *);
|
|
uint32 om_get(Class *, Object *, struct opGet *);
|
|
uint32 agm_open(Class *, Object *, Msg);
|
|
uint32 agm_close(Class *, Object *, Msg);
|
|
uint32 agm_process(Class *, Object *, Msg);
|
|
|
|
|
|
/* *************************** class initialization and disposal ***************************** */
|
|
|
|
|
|
Class *initAGClass(void)
|
|
{
|
|
Class *cl = NULL;
|
|
|
|
|
|
// Open amigaguide.library and its interface.
|
|
if ( (AmigaGuideBase = OpenLibrary("amigaguide.library", 40)) )
|
|
{
|
|
#ifdef __amigaos4__
|
|
if ( (IAmigaGuide = (struct AmigaGuideIFace *)GetInterface(AmigaGuideBase, "main", 1L, NULL)) )
|
|
{
|
|
#endif
|
|
if ( (cl = MakeClass(NULL, "rootclass", NULL, sizeof(struct localObjectData), 0)) )
|
|
{
|
|
cl->cl_Dispatcher.h_Entry = (HOOKFUNC)dispatchAGClass;
|
|
AddClass(cl);
|
|
}
|
|
else freeAGClass(NULL);
|
|
#ifdef __amigaos4__
|
|
}
|
|
else freeAGClass(NULL);
|
|
#endif
|
|
}
|
|
|
|
return cl;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL freeAGClass(Class *cl)
|
|
{
|
|
BOOL retVal = FALSE;
|
|
|
|
|
|
// Close amigaguide.library and free the class.
|
|
#ifdef __amigaos4__
|
|
if (IAmigaGuide) DropInterface((struct Interface *)IAmigaGuide);
|
|
#endif
|
|
if (AmigaGuideBase) CloseLibrary(AmigaGuideBase);
|
|
if (cl) retVal = FreeClass(cl);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
|
|
/* ************************************** class dispatcher ************************************ */
|
|
|
|
|
|
DISPATCHHOOK(dispatchAGClass)
|
|
{
|
|
|
|
switch (msg->MethodID)
|
|
{
|
|
case OM_NEW:
|
|
return om_new(cl, o, (struct opSet *)msg);
|
|
|
|
case OM_DISPOSE:
|
|
return om_dispose(cl, o, msg);
|
|
|
|
case OM_UPDATE:
|
|
case OM_SET:
|
|
return om_set(cl, o, (struct opSet *)msg);
|
|
|
|
case OM_GET:
|
|
return om_get(cl, o, (struct opGet *)msg);
|
|
|
|
case AGM_OPEN:
|
|
return agm_open(cl, o, msg);
|
|
|
|
case AGM_CLOSE:
|
|
return agm_close(cl, o, msg);
|
|
|
|
case AGM_PROCESS:
|
|
return agm_process(cl, o, msg);
|
|
|
|
default:
|
|
return IDoSuperMethodA(cl, o, msg);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* *************************************** class methods ************************************** */
|
|
|
|
uint32 om_new(Class *cl, Object *o, struct opSet *msg)
|
|
{
|
|
struct localObjectData *lod = NULL;
|
|
uint32 retVal = 0L;
|
|
|
|
|
|
if ( (retVal = IDoSuperMethodA(cl, o, (Msg)msg)) )
|
|
{
|
|
// Obtain pointer to our object's local instance data.
|
|
if ( (lod = (struct localObjectData *)INST_DATA(cl, retVal)) )
|
|
{
|
|
// Initialize values.
|
|
lod->agHandle = NULL;
|
|
lod->agContextID = 0;
|
|
lod->nag.nag_Name = NULL;
|
|
lod->nag.nag_Screen = NULL;
|
|
lod->nag.nag_PubScreen = NULL;
|
|
lod->nag.nag_BaseName = NULL;
|
|
lod->nag.nag_Context = NULL;
|
|
lod->nag.nag_Client = NULL; // private, must be NULL!
|
|
|
|
// Set initial object attributes based on the tags from NewObject().
|
|
om_set(cl, (Object *)retVal, msg);
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32 om_dispose(Class *cl, Object *o, Msg msg)
|
|
{
|
|
|
|
// Close the document, should it still be opened.
|
|
agm_close(cl, o, msg);
|
|
|
|
// Let superclass dispose of the object.
|
|
return IDoSuperMethodA(cl, o, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32 om_set(Class *cl, Object *o, struct opSet *msg)
|
|
{
|
|
struct localObjectData *lod = (struct localObjectData *)INST_DATA(cl, o);
|
|
struct TagItem *ti = NULL, *tags = msg->ops_AttrList;
|
|
uint32 retVal = 0L;
|
|
|
|
|
|
while ((ti = NextTagItem (&tags)))
|
|
{
|
|
switch (ti->ti_Tag)
|
|
{
|
|
case AMIGAGUIDE_Name:
|
|
lod->nag.nag_Name = (STRPTR)ti->ti_Data;
|
|
retVal++;
|
|
break;
|
|
|
|
case AMIGAGUIDE_Screen:
|
|
lod->nag.nag_Screen = (struct Screen *)ti->ti_Data;
|
|
retVal++;
|
|
break;
|
|
|
|
case AMIGAGUIDE_PubScreen:
|
|
lod->nag.nag_PubScreen = (STRPTR)ti->ti_Data;
|
|
retVal++;
|
|
break;
|
|
|
|
case AMIGAGUIDE_BaseName:
|
|
lod->nag.nag_BaseName = (STRPTR)ti->ti_Data;
|
|
retVal++;
|
|
break;
|
|
|
|
case AMIGAGUIDE_ContextArray:
|
|
lod->nag.nag_Context = (STRPTR *)ti->ti_Data;
|
|
retVal++;
|
|
break;
|
|
|
|
case AMIGAGUIDE_ContextID:
|
|
lod->agContextID = (uint32)ti->ti_Data;
|
|
retVal++;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32 om_get(Class *cl, Object *o, struct opGet *msg)
|
|
{
|
|
struct localObjectData *lod = (struct localObjectData *)INST_DATA(cl, o);
|
|
uint32 retVal = 0L;
|
|
|
|
|
|
switch (msg->opg_AttrID)
|
|
{
|
|
case AMIGAGUIDE_Name:
|
|
*(msg->opg_Storage) = (uint32)lod->nag.nag_Name;
|
|
retVal = 1L;
|
|
break;
|
|
|
|
case AMIGAGUIDE_Screen:
|
|
*(msg->opg_Storage) = (uint32)lod->nag.nag_Screen;
|
|
retVal = 1L;
|
|
break;
|
|
|
|
case AMIGAGUIDE_PubScreen:
|
|
*(msg->opg_Storage) = (uint32)lod->nag.nag_PubScreen;
|
|
retVal = 1L;
|
|
break;
|
|
|
|
case AMIGAGUIDE_BaseName:
|
|
*(msg->opg_Storage) = (uint32)lod->nag.nag_BaseName;
|
|
retVal = 1L;
|
|
break;
|
|
|
|
case AMIGAGUIDE_ContextArray:
|
|
*(msg->opg_Storage) = (uint32)lod->nag.nag_Context;
|
|
retVal = 1L;
|
|
break;
|
|
|
|
case AMIGAGUIDE_ContextID:
|
|
*(msg->opg_Storage) = (uint32)lod->agContextID;
|
|
retVal = 1L;
|
|
break;
|
|
|
|
case AMIGAGUIDE_Signal:
|
|
*(msg->opg_Storage) = (uint32)lod->agSignal;
|
|
retVal = 1L;
|
|
break;
|
|
|
|
default:
|
|
retVal = IDoSuperMethodA(cl, o, (Msg)msg);
|
|
}
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32 agm_open(Class *cl, Object *o, Msg msg)
|
|
{
|
|
struct localObjectData *lod = (struct localObjectData *)INST_DATA(cl, o);
|
|
BOOL agActive = FALSE;
|
|
uint32 retVal = 0L;
|
|
|
|
|
|
// Close a previous instance.
|
|
if ( lod->agHandle ) agm_close(cl, o, msg);
|
|
|
|
// (Re)establish the AmigaGuide context and open the database asynchronously.
|
|
if ( (lod->agHandle = OpenAmigaGuideAsync(&(lod->nag), NULL)) )
|
|
{
|
|
if ( (lod->agSignal = AmigaGuideSignal(lod->agHandle)) )
|
|
{
|
|
// Wait until the database is displayed and ready.
|
|
Wait(lod->agSignal);
|
|
while ( agActive == FALSE )
|
|
{
|
|
while ( (lod->agm = GetAmigaGuideMsg(lod->agHandle)) )
|
|
{
|
|
// The AmigaGuide process started OK.
|
|
if ( lod->agm->agm_Type == ActiveToolID ) agActive = TRUE;
|
|
|
|
// Opening the guide file failed for some reason, continue as usual.
|
|
if ( lod->agm->agm_Type == ToolStatusID && lod->agm->agm_Pri_Ret ) agActive = TRUE;
|
|
|
|
ReplyAmigaGuideMsg(lod->agm);
|
|
}
|
|
}
|
|
if ( lod->nag.nag_Context )
|
|
{
|
|
// A context node array is provided = open the current context node.
|
|
SetAmigaGuideContext(lod->agHandle, lod->agContextID, NULL);
|
|
retVal = SendAmigaGuideContext(lod->agHandle, NULL);
|
|
}
|
|
else
|
|
{
|
|
// No context array is provided = open the main node.
|
|
retVal = SendAmigaGuideCmd(lod->agHandle, "LINK MAIN", TAG_DONE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32 agm_close(Class *cl, Object *o, Msg msg)
|
|
{
|
|
struct localObjectData *lod = (struct localObjectData *)INST_DATA(cl, o);
|
|
uint32 retVal = 0L;
|
|
|
|
|
|
if ( lod->agHandle )
|
|
{
|
|
CloseAmigaGuide(lod->agHandle);
|
|
lod->agHandle = NULL;
|
|
lod->agSignal = 0;
|
|
retVal = 1L;
|
|
}
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32 agm_process(Class *cl, Object *o, Msg msg)
|
|
{
|
|
struct localObjectData *lod = (struct localObjectData *)INST_DATA(cl, o);
|
|
uint32 retVal = 0L;
|
|
|
|
|
|
if (lod->agHandle)
|
|
{
|
|
while ( (lod->agm = GetAmigaGuideMsg(lod->agHandle)) )
|
|
{
|
|
switch (lod->agm->agm_Type)
|
|
{
|
|
case ShutdownMsgID:
|
|
agm_close(cl, o, msg);
|
|
retVal = 1L;
|
|
break;
|
|
|
|
default:
|
|
//printf("%d\n", lod->agm->agm_Type);
|
|
break;
|
|
}
|
|
ReplyAmigaGuideMsg(lod->agm);
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|