home *** CD-ROM | disk | FTP | other *** search
- /* nodehost.c
- * Written by David N. Junod
- *
- * Example of a Dynamic Node Host. This example is useful for determining
- * what nodes an AmigaGuide database is calling when it brings up the
- * "Can't locate node" requester.
- *
- * I use it when I'm writing help files for AppShell applications...
- *
- */
-
- #include <exec/types.h>
- #include <intuition/intuition.h>
- #include <intuition/screens.h>
- #include <libraries/amigaguide.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/amigaguide_protos.h>
- #include <pragmas/exec.h>
- #include <pragmas/amigaguide_pragmas.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
-
- extern struct Library *SysBase, *DOSBase;
- struct Library *IntuitionBase, *GfxBase, *AmigaGuideBase;
-
- void kprintf (void *, ...);
- #define DB(x) ;
-
- #define ASM __asm
- #define REG(x) register __ ## x
-
- ULONG __saveds dispatchAmigaGuideHost (struct Hook *h, STRPTR db, Msg msg);
- ULONG ASM hookEntry (register __a0 struct Hook *,register __a2 VOID *,register __a1 VOID *);
-
- main (int argc, char **argv)
- {
- struct Hook hook;
- AMIGAGUIDEHOST hh;
-
- IntuitionBase = OpenLibrary ("intuition.library", 0);
- GfxBase = OpenLibrary ("graphics.library", 0);
-
- /* amigaguide.library works with 1.3 and newer versions of the OS */
- if (AmigaGuideBase = OpenLibrary ("amigaguide.library", 33))
- {
- /* Initialize the hook */
- hook.h_Entry = hookEntry;
- hook.h_SubEntry = dispatchAmigaGuideHost;
-
- /* Add the AmigaGuideHost to the system */
- if (hh = AddAmigaGuideHost (&hook, "ExampleHost", NULL))
- {
- printf ("Added AmigaGuideHost 0x%lx\n", hh);
-
- /* Wait until we're told to quit */
- Wait (SIGBREAKF_CTRL_C);
-
- printf ("Remove AmigaGuideHost 0x%lx", hh);
-
- /* Try removing the host */
- while (RemoveAmigaGuideHost (hh, NULL) > 0)
- {
- /* Wait a while */
- printf (".");
- Delay (250);
- }
- printf ("\n");
- }
- else
- {
- printf ("Couldn't add AmigaGuideHost\n");
- }
-
- /* close the library */
- CloseLibrary (AmigaGuideBase);
- }
-
- CloseLibrary (GfxBase);
- CloseLibrary (IntuitionBase);
- }
-
- /*** Common tag manipulation routines ************************************/
-
- struct TagItem *nextTagItem(struct TagItem **tp)
- {
- struct TagItem *nextti;
-
- /* 'tp' already holds "next" item in list */
- nextti = *tp;
-
- /* walk all TAG_MORE and TAG_IGNORE chaining */
- while ( nextti )
- {
- switch ( nextti->ti_Tag )
- {
- case TAG_MORE:
- nextti = (struct TagItem *) nextti->ti_Data;
- break;
- case TAG_SKIP:
- nextti+= 1 + (int) nextti->ti_Data;
- break;
- case TAG_IGNORE:
- nextti++;
- break;
- case TAG_DONE:
- return ( *tp = NULL );
- break;
- default: /* a normal tag item */
- *tp = nextti + 1;
- return ( nextti );
- }
- }
- return ( *tp = NULL );
- }
-
- struct TagItem *findTagItem(Tag tag, struct TagItem * ti)
- {
- struct TagItem *tistate;
-
- tistate = ti;
-
- while ( ti = nextTagItem( &tistate ) )
- {
- if ( ti->ti_Tag == tag ) break;
- }
- return ( ti );
- }
-
- ULONG getTagData(Tag tag, ULONG deflt, struct TagItem *ti)
- {
- if ( ti = findTagItem( tag, ti ) )
- {
- return ( ti->ti_Data );
- }
- return ( deflt );
- }
-
- #define TEMP_NODE "This AmigaGuideHost is example, that can also\nbe used as a debuggin tool.\n"
- #define LINK "Link: "
-
- struct TextAttr TOPAZ8 = {"topaz.font", 8, NULL, NULL};
- struct TextAttr TOPAZ8B = {"topaz.font", 8, FSF_BOLD, NULL};
-
- /* We really need the screen, rectangle, and pen spec. */
- VOID Display (struct opNodeIO *onm)
- {
- struct TagItem *attrs = onm->onm_Attrs;
- struct IntuiText it1 = {NULL};
- struct IntuiText it2 = {NULL};
- struct Rectangle *rect = NULL;
- struct NewWindow nw = {NULL};
- struct Screen *scr = NULL;
- struct IntuiMessage *msg;
- struct Window *win;
- UWORD *pens = NULL;
- BOOL going = TRUE;
- LONG width = 0L;
- WORD w = 640;
- WORD h = 200;
- WORD dif;
-
- /* Get attributes, could be NULL */
- if (attrs)
- {
- scr = (struct Screen *) getTagData (HTNA_Screen, NULL, attrs);
- pens = (UWORD *) getTagData (HTNA_Pens, NULL, attrs);
- rect = (struct Rectangle *) getTagData (HTNA_Rectangle, NULL, attrs);
- }
-
- /* Prepare the IntuiText */
- it1.FrontPen = it2.FrontPen = ((pens) ? pens[SHADOWPEN] : 1);
- it1.DrawMode = it2.DrawMode = JAM1;
- it1.ITextFont = &TOPAZ8;
- it2.ITextFont = &TOPAZ8B;
- it1.IText = LINK;
- it2.IText = onm->onm_Node;
-
- /* Get the width of the first string */
- width = IntuiTextLength (&it1);
- it2.LeftEdge = (SHORT) width;
-
- /* Add in the length of the node name */
- width += IntuiTextLength (&it2);
-
- /* Link the text */
- it1.NextText = &it2;
-
- /* Prepare the window */
- nw.IDCMPFlags = IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS;
- nw.Flags = WFLG_BORDERLESS | WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH \
- | WFLG_ACTIVATE;
- nw.Width = 8 + width + 8;
- nw.Height = 16;
- nw.Screen = scr;
- nw.Type = (scr) ? CUSTOMSCREEN : WBENCHSCREEN;
-
- /* Cache the screen size */
- if (scr)
- {
- w = scr->Width;
- h = scr->Height;
- }
-
- /* See if we have a open help window */
- if (rect)
- {
- /* Center the window within the help window */
- nw.LeftEdge = rect->MinX + ((rect->MaxX - nw.Width) / 2);
- nw.TopEdge = rect->MinY + ((rect->MaxY - nw.Height) / 2);
- }
- /* No help window, so go off the screen */
- else if (scr)
- {
- /* Center the window horizontally under the mouse and place it
- * vertically over the mouse position. */
- nw.LeftEdge = scr->MouseX - (nw.Width / 2);
- nw.TopEdge = scr->MouseY - (nw.Height - 2);
-
- /* Make sure the window can open */
- nw.LeftEdge = (nw.LeftEdge < 0) ? 0 : nw.LeftEdge;
- nw.TopEdge = (nw.TopEdge < 0) ? 0 : nw.TopEdge;
- }
-
- /* Make sure window is on-screen */
- dif = (nw.LeftEdge + nw.Width) - w;
- nw.LeftEdge = (dif > 0) ? nw.LeftEdge - dif : nw.LeftEdge;
- dif = (nw.TopEdge + nw.Height) - h;
- nw.TopEdge = (dif > 0) ? nw.TopEdge - dif : nw.TopEdge;
-
- /* Open the temporary window */
- if (win = OpenWindow (&nw))
- {
- /* Clear the window background */
- SetAPen (win->RPort, ((pens) ? pens[SHADOWPEN] : 1));
- RectFill (win->RPort, 0, 0, (win->Width - 1), (win->Height - 1));
- SetAPen (win->RPort, ((pens) ? pens[SHINEPEN] : 2));
- RectFill (win->RPort, 1, 1, (win->Width - 2), (win->Height - 2));
-
- /* Print the text */
- PrintIText (win->RPort, &it1, 8, 4);
-
- /* Keep on going til the going gets tough */
- while (going)
- {
- /* Wait around for something eventful */
- Wait (1L << win->UserPort->mp_SigBit);
-
- /* Pull each message and handle it */
- while (msg = (struct IntuiMessage *) GetMsg (win->UserPort))
- {
- switch (msg->Class)
- {
- case IDCMP_MOUSEBUTTONS:
- /* Stop if we were touched */
- if (msg->Code == SELECTDOWN)
- {
- going = FALSE;
- }
- break;
-
- case IDCMP_VANILLAKEY:
- /* Stop on significant keypress */
- if ((msg->Code == 27) || (msg->Code == 13))
- {
- going = FALSE;
- }
- break;
- }
-
- ReplyMsg ((struct Message *) msg);
- }
- }
-
- /* Close the window */
- CloseWindow (win);
- }
- }
-
- /* This is your AmigaGuideHost dispatch hook. It will never run on your
- * own process. */
- ULONG __saveds dispatchAmigaGuideHost (struct Hook *h, STRPTR db, Msg msg)
- {
- struct opNodeIO *onm = (struct opNodeIO *) msg;
- ULONG retval = 0;
-
- switch (msg->MethodID)
- {
- /* Does this node belong to you? */
- case HM_FindNode:
- {
- struct opFindHost *ofh = (struct opFindHost *) msg;
-
- DB (kprintf ("Find [%s] in %s\n", ofh->ofh_Node, db));
-
- /* See if they want to find our table of contents */
- if ((stricmp (ofh->ofh_Node, "main")) == 0)
- {
- /* Return TRUE to indicate that it's your node,
- * otherwise return FALSE. */
- retval = TRUE;
- }
- else
- {
- /* Display the name of the node */
- Display (onm);
-
- /* Return TRUE to indicate that it's your node,
- * otherwise return FALSE. */
- retval = FALSE;
- }
- }
- break;
-
- /* Open a node. */
- case HM_OpenNode:
- DB (kprintf ("Open [%s] in %s\n", onm->onm_Node, db));
-
- /* See if they want to display our table of contents */
- if ((stricmp (onm->onm_Node, "main")) == 0)
- {
- /* Provide the contents of the node */
- onm->onm_DocBuffer = TEMP_NODE;
- onm->onm_BuffLen = strlen (TEMP_NODE);
- }
- else
- {
- /* Display the name of the node */
- Display (onm);
-
- /* Indicate that we want the node removed from our database,
- * and that we handled the display of the node */
- onm->onm_Flags |= (HTNF_CLEAN | HTNF_DONE);
- }
-
- /* Indicate that we were able to open the node */
- retval = TRUE;
- break;
-
- /* Close a node, that has no users. */
- case HM_CloseNode:
- DB (kprintf ("Close [%s] in %s\n", onm->onm_Node, db));
-
- /* Indicate that we were able to close the node */
- retval = TRUE;
- break;
-
- /* Free any extra memory */
- case HM_Expunge:
- DB (kprintf ("Expunge [%s]\n", db));
- break;
-
- default:
- DB (kprintf ("Unknown method %ld\n", msg->MethodID));
- break;
- }
-
- return (retval);
- }
-
- /* Main entry point for your AmigaGuideHost dispatch hook */
- ULONG __asm hookEntry (
- register __a0 struct Hook *h,
- register __a2 VOID *obj,
- register __a1 VOID *msg)
- {
- /* Pass the parameters on the stack */
- return ((h->h_SubEntry)(h, obj, msg));
- }
-