347 lines
8.0 KiB
C
Executable File
347 lines
8.0 KiB
C
Executable File
/*
|
|
* AmigaGuide Class
|
|
* A BOOPSI class for displaying AmigaGuide files.
|
|
* by Daniel "Trixie" Jedlicka
|
|
*/
|
|
|
|
#undef __USE_INLINE__
|
|
|
|
#include "amigaguide_class.h"
|
|
|
|
struct localObjectData
|
|
{
|
|
struct NewAmigaGuide nag;
|
|
struct AmigaGuideMsg *agm;
|
|
AMIGAGUIDECONTEXT agHandle;
|
|
uint32 agContextID;
|
|
uint32 agSignal;
|
|
BOOL agActive;
|
|
};
|
|
|
|
struct Library *AmigaGuideBase = NULL;
|
|
struct AmigaGuideIFace *IAmigaGuide = NULL;
|
|
|
|
|
|
/* ********************************** function prototypes ************************************ */
|
|
|
|
static uint32 dispatchAGClass(Class *, Object *, Msg);
|
|
BOOL freeAGClass(Class *);
|
|
|
|
// 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);
|
|
|
|
|
|
/* *************************** class initialization and disposal ***************************** */
|
|
|
|
|
|
Class *initAGClass(void)
|
|
{
|
|
Class *cl = NULL;
|
|
|
|
|
|
// Open amigaguide.library and its interface.
|
|
if ( (AmigaGuideBase = IExec->OpenLibrary("amigaguide.library", 52)) )
|
|
{
|
|
if ( (IAmigaGuide = (struct AmigaGuideIFace *)IExec->GetInterface(AmigaGuideBase, "main", 1L, NULL)) )
|
|
{
|
|
if ( (cl = IIntuition->MakeClass(NULL, "rootclass", NULL, sizeof(struct localObjectData), 0)) )
|
|
{
|
|
cl->cl_Dispatcher.h_Entry = (HOOKFUNC)dispatchAGClass;
|
|
IIntuition->AddClass(cl);
|
|
}
|
|
else freeAGClass(NULL);
|
|
}
|
|
else freeAGClass(NULL);
|
|
}
|
|
|
|
return cl;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL freeAGClass(Class *cl)
|
|
{
|
|
BOOL retVal = FALSE;
|
|
|
|
|
|
// Close amigaguide.library and free the class.
|
|
if (IAmigaGuide) IExec->DropInterface((struct Interface *)IAmigaGuide);
|
|
if (AmigaGuideBase) IExec->CloseLibrary(AmigaGuideBase);
|
|
if (cl) retVal = IIntuition->FreeClass(cl);
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
|
|
/* ************************************** class dispatcher ************************************ */
|
|
|
|
|
|
static uint32 dispatchAGClass(Class *cl, Object *o, Msg msg)
|
|
{
|
|
|
|
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);
|
|
|
|
default:
|
|
return IIntuition->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 = IIntuition->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->agActive = FALSE;
|
|
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 IIntuition->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 *tags, *ti;
|
|
|
|
|
|
tags = msg->ops_AttrList;
|
|
|
|
while ((ti = IUtility->NextTagItem (&tags)))
|
|
{
|
|
switch (ti->ti_Tag)
|
|
{
|
|
case AMIGAGUIDE_Name:
|
|
lod->nag.nag_Name = (STRPTR)ti->ti_Data;
|
|
lod->agActive = FALSE; // Database name has changed, we must setup the help system again.
|
|
break;
|
|
|
|
case AMIGAGUIDE_Screen:
|
|
lod->nag.nag_Screen = (struct Screen *)ti->ti_Data;
|
|
lod->agActive = FALSE; // Screen pointer has changed, we must setup the help system again.
|
|
break;
|
|
|
|
case AMIGAGUIDE_PubScreen:
|
|
lod->nag.nag_PubScreen = (STRPTR)ti->ti_Data;
|
|
lod->agActive = FALSE; // Pubscreen name has changed, we must setup the help system again.
|
|
break;
|
|
|
|
case AMIGAGUIDE_BaseName:
|
|
lod->nag.nag_BaseName = (STRPTR)ti->ti_Data;
|
|
lod->agActive = FALSE; // Application basename has changed, we must setup the help system again.
|
|
break;
|
|
|
|
case AMIGAGUIDE_ContextArray:
|
|
lod->nag.nag_Context = (STRPTR *)ti->ti_Data;
|
|
lod->agActive = FALSE; // Context array has changed, we must setup the help system again.
|
|
break;
|
|
|
|
case AMIGAGUIDE_ContextID:
|
|
lod->agContextID = (uint32)ti->ti_Data;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// Setup the help system, if not ready yet or needs changing.
|
|
if ( lod->agActive == FALSE )
|
|
{
|
|
// Shut down help system should it already be running.
|
|
if ( lod->agHandle ) agm_close(cl, o, (Msg)msg);
|
|
|
|
// (Re)establish the AmigaGuide context and open the database asynchronously.
|
|
if ( (lod->agHandle = IAmigaGuide->OpenAmigaGuideAsync(&(lod->nag), NULL)) )
|
|
{
|
|
if ( (lod->agSignal = IAmigaGuide->AmigaGuideSignal(lod->agHandle)) )
|
|
{
|
|
// Wait until the help system is up and running.
|
|
IExec->Wait(lod->agSignal);
|
|
while ( !(lod->agActive) )
|
|
{
|
|
while ( (lod->agm = IAmigaGuide->GetAmigaGuideMsg(lod->agHandle)) )
|
|
{
|
|
// The AmigaGuide process started OK.
|
|
if ( lod->agm->agm_Type == ActiveToolID ) lod->agActive = TRUE;
|
|
|
|
// Opening the guide file failed for some reason, continue as usual.
|
|
if ( lod->agm->agm_Type == ToolStatusID && lod->agm->agm_Pri_Ret ) lod->agActive = TRUE;
|
|
|
|
IAmigaGuide->ReplyAmigaGuideMsg(lod->agm);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return (uint32)lod->agHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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 = 1;
|
|
break;
|
|
|
|
case AMIGAGUIDE_Screen:
|
|
*(msg->opg_Storage) = (uint32)lod->nag.nag_Screen;
|
|
retVal = 1;
|
|
break;
|
|
|
|
case AMIGAGUIDE_PubScreen:
|
|
*(msg->opg_Storage) = (uint32)lod->nag.nag_PubScreen;
|
|
retVal = 1;
|
|
break;
|
|
|
|
case AMIGAGUIDE_BaseName:
|
|
*(msg->opg_Storage) = (uint32)lod->nag.nag_BaseName;
|
|
retVal = 1;
|
|
break;
|
|
|
|
case AMIGAGUIDE_ContextArray:
|
|
*(msg->opg_Storage) = (uint32)lod->nag.nag_Context;
|
|
retVal = 1;
|
|
break;
|
|
|
|
case AMIGAGUIDE_ContextID:
|
|
*(msg->opg_Storage) = (uint32)lod->agContextID;
|
|
retVal = 1;
|
|
break;
|
|
|
|
default:
|
|
retVal = IIntuition->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);
|
|
uint32 retVal = 0;
|
|
|
|
|
|
if ( (lod->agHandle) && (lod->agActive) )
|
|
{
|
|
if ( lod->nag.nag_Context )
|
|
{
|
|
// A context node array is provided = open the current context node.
|
|
IAmigaGuide->SetAmigaGuideContext(lod->agHandle, lod->agContextID, NULL);
|
|
retVal = IAmigaGuide->SendAmigaGuideContext(lod->agHandle, NULL);
|
|
}
|
|
else
|
|
{
|
|
// No context array is provided = open the main node.
|
|
retVal = IAmigaGuide->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);
|
|
|
|
|
|
if ( lod->agHandle )
|
|
{
|
|
IAmigaGuide->CloseAmigaGuide(lod->agHandle);
|
|
lod->agHandle = NULL;
|
|
lod->agActive = FALSE;
|
|
}
|
|
|
|
return (uint32)lod->agHandle;
|
|
|
|
}
|