home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / install / amigaguide / ag_v34 / source / hyperapp.c next >
C/C++ Source or Header  |  1994-10-19  |  15KB  |  681 lines

  1. /* HyperApp.c
  2.  */
  3.  
  4. #include <exec/types.h>
  5. #include <exec/libraries.h>
  6. #include <intuition/intuition.h>
  7. #include <graphics/gfx.h>
  8. #include <graphics/text.h>
  9. #include <libraries/amigaguide.h>
  10. #include <clib/alib_protos.h>
  11. #include <clib/exec_protos.h>
  12. #include <clib/intuition_protos.h>
  13. #include <clib/graphics_protos.h>
  14. #include <clib/amigaguide_protos.h>
  15. #include <pragmas/amigaguide_pragmas.h>
  16. #include <stdio.h>
  17.  
  18. #define    DB(x)    ;
  19.  
  20. struct AppInfo
  21. {
  22.     struct Window *ai_Window;                /* Window pointer */
  23.     BOOL ai_Done;                    /* Done yet? */
  24.     AMIGAGUIDECONTEXT ai_AmigaGuide;            /* Pointer to the AmigaGuide context */
  25.     LONG ai_Region;                    /* Region that the mouse if over */
  26.     struct TextFont *ai_Font;                /* Window font */
  27. };
  28.  
  29. struct FuncTable
  30. {
  31.     VOID (*ft_Func) (struct AppInfo *);
  32. };
  33.  
  34. struct EMenuItem
  35. {
  36.     struct MenuItem em_MenuItem;            /* Embedded menu structure */
  37.     LONG em_MenuID;                    /* Menu ID */
  38. };
  39.  
  40. extern struct Library *SysBase, *DOSBase;
  41. struct Library *IntuitionBase, *GfxBase, *AmigaGuideBase;
  42.  
  43. VOID MainFunc (struct AppInfo *);
  44. VOID QuitFunc (struct AppInfo *);
  45. VOID GadgetFunc (struct AppInfo *);
  46. VOID OkayFunc (struct AppInfo *);
  47. VOID CancelFunc (struct AppInfo *);
  48.  
  49. /* Context ID's to be sent to AmigaGuide */
  50. STRPTR context[] =
  51. {
  52.     "MAIN",
  53.     "QUIT",
  54.     "GADGET",
  55.     "OKAY",
  56.     "CANCEL",
  57.     NULL
  58. };
  59.  
  60. /* Simple little prompts to display within the application window */
  61. STRPTR quickhelp[] =
  62. {
  63.     "HyperApp Main Window",
  64.     "",
  65.     "Transmogrify Objects",
  66.     "Positive Quit",
  67.     "Negative Quit",
  68.     NULL
  69. };
  70.  
  71. struct FuncTable Funcs[] =
  72. {
  73.     MainFunc,
  74.     QuitFunc,
  75.     GadgetFunc,
  76.     OkayFunc,
  77.     CancelFunc,
  78.     NULL
  79. };
  80.  
  81. struct TextAttr TOPAZ8 =
  82. {(STRPTR) "topaz.font", 8, 0, 0};
  83.  
  84. struct IntuiText IText3 =
  85. {
  86.     0, 0, JAM1, 2, 1, &TOPAZ8, "Quit", NULL
  87. };
  88.  
  89. struct EMenuItem MenuItem1 =
  90. {
  91.     NULL, 0, 0, 142, 9, ITEMTEXT | COMMSEQ | ITEMENABLED | HIGHCOMP,
  92.     0, (APTR) & IText3, NULL, 'Q', NULL, MENUNULL, 1L
  93. };
  94.  
  95. struct Menu Menu1 =
  96. {
  97.     NULL, 2, 0, 64, 0, MENUENABLED, "Project", (struct MenuItem *) & MenuItem1
  98. };
  99.  
  100. SHORT BData1[] =
  101. {0, 0, 94, 0, 94, 13, 0, 13, 0, 0};
  102. SHORT BData2[] =
  103. {0, 0, 94, 0, 94, 13, 0, 13, 0, 0};
  104.  
  105. struct Border Border1 =
  106. {0, 0, 1, 0, JAM1, 5, BData1, NULL};
  107. struct Border Border2 =
  108. {0, 0, 1, 0, JAM1, 5, BData2, NULL};
  109.  
  110. struct IntuiText IText1 =
  111. {1, 0, JAM2, 26, 3, &TOPAZ8, "Cancel", NULL};
  112. struct IntuiText IText2 =
  113. {1, 0, JAM2, 40, 3, &TOPAZ8, "OK", NULL};
  114.  
  115. struct Gadget Gadget3 =
  116. {
  117.     NULL, -120, -18, 95, 14, GRELBOTTOM | GRELRIGHT, RELVERIFY, BOOLGADGET,
  118.     (APTR) & Border1, NULL, &IText1, NULL, NULL, 4L, NULL
  119. };
  120.  
  121. struct Gadget Gadget2 =
  122. {
  123.     &Gadget3, 12, -18, 95, 14, GRELBOTTOM, RELVERIFY, BOOLGADGET,
  124.     (APTR) & Border2, NULL, &IText2, NULL, NULL, 3L, NULL
  125. };
  126.  
  127. struct Gadget Gadget1 =
  128. {
  129.     &Gadget2, 12, 27, -40, -48, GADGHCOMP | GRELWIDTH | GRELHEIGHT | SELECTED,
  130.     TOGGLESELECT | RELVERIFY, BOOLGADGET, NULL, NULL, NULL, NULL, NULL,
  131.     2L, NULL
  132. };
  133.  
  134. struct TagItem WinTags[] =
  135. {
  136.     WA_MenuHelp, TRUE,
  137.     TAG_DONE,
  138. };
  139.  
  140. /* NewWindow Structures */
  141. struct ExtNewWindow NewWindowStructure1 =
  142. {
  143.     0, 0, 640, 100, -1, -1,
  144.     IDCMP_RAWKEY | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_MENUHELP |
  145.     IDCMP_GADGETUP | IDCMP_MOUSEMOVE,
  146.     WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | WFLG_REPORTMOUSE |
  147.     SIZEBRIGHT | ACTIVATE | NOCAREREFRESH | WFLG_NW_EXTENDED,
  148.     &Gadget1, NULL, "HyperApp (Press HELP over Gadget or Menu)", NULL, NULL,
  149.     320, 50, 65535, 65535, WBENCHSCREEN, WinTags,
  150. };
  151.  
  152. /* Determine if a point is within a rectangle */
  153. ULONG PointInBox (WORD x, WORD y, struct IBox * box)
  154. {
  155.  
  156.     if ((x >= box->Left) &&
  157.     (x <= (box->Left + box->Width)) &&
  158.     (y >= box->Top) &&
  159.     (y <= (box->Top + box->Height)))
  160.     {
  161.     return (1L);
  162.     }
  163.  
  164.     return (0L);
  165. }
  166.  
  167. /* Find the rectangle of a gadget */
  168. VOID gadgetBox (struct Gadget * g, struct IBox * domain, struct IBox * box)
  169. {
  170.  
  171.     /* Set the 'normal' rectangle */
  172.     box->Left = g->LeftEdge;
  173.     box->Top = g->TopEdge;
  174.     box->Width = g->Width;
  175.     box->Height = g->Height;
  176.  
  177.     /* Check for relativity */
  178.     if (g->Flags & GRELRIGHT)
  179.     box->Left += domain->Width - 1;
  180.     if (g->Flags & GRELBOTTOM)
  181.     box->Top += domain->Height - 1;
  182.     if (g->Flags & GRELWIDTH)
  183.     box->Width += domain->Width;
  184.     if (g->Flags & GRELHEIGHT)
  185.     box->Height += domain->Height;
  186. }
  187.  
  188. /* Process menu events */
  189. VOID HandleMenuEvent (struct IntuiMessage * msg)
  190. {
  191.     struct Window *win = msg->IDCMPWindow;
  192.     struct AppInfo *ai = (struct AppInfo *) win->UserData;
  193.     UWORD selection = msg->Code;
  194.     struct EMenuItem *item;
  195.  
  196.     /* Turn off the menu button */
  197.     win->Flags |= RMBTRAP;
  198.  
  199.     /* Process all menu events */
  200.     while (selection != MENUNULL)
  201.     {
  202.     /* Get the MenuItem structure address */
  203.     if (item = (struct EMenuItem *)
  204.         ItemAddress (win->MenuStrip, (LONG) selection))
  205.     {
  206.         (*(Funcs[item->em_MenuID].ft_Func)) (ai);
  207.  
  208.         /* Get the next selection */
  209.         selection = item->em_MenuItem.NextSelect;
  210.     }
  211.     else
  212.     {
  213.         selection = MENUNULL;
  214.     }
  215.     }
  216.  
  217.     /* Turn menu events back on. */
  218.     win->Flags &= ~RMBTRAP;
  219. }
  220.  
  221. /* Process MenuHelp events */
  222. VOID HandleMenuHelp (struct IntuiMessage * msg)
  223. {
  224.     struct Window *win = msg->IDCMPWindow;
  225.     struct AppInfo *ai = (struct AppInfo *) win->UserData;
  226.     struct EMenuItem *item;
  227.     WORD mnum, inum, snum;
  228.  
  229.     mnum = MENUNUM (msg->Code);
  230.     inum = ITEMNUM (msg->Code);
  231.     snum = SUBNUM (msg->Code);
  232.  
  233.     printf ("m %d i %d s %d\n", mnum, inum, snum);
  234.  
  235.     /* Get the MenuItem structure address */
  236.     if (item = (struct EMenuItem *)
  237.     ItemAddress (win->MenuStrip, (LONG) msg->Code))
  238.     {
  239.     /* Set the AmigaGuide context */
  240.     SetAmigaGuideContext (ai->ai_AmigaGuide, item->em_MenuID, NULL);
  241.  
  242.     /* Display the node */
  243.     SendAmigaGuideContext (ai->ai_AmigaGuide, NULL);
  244.     }
  245.     else
  246.     {
  247.     /* No selectable item where help was pressed */
  248.     printf ("No item here\n");
  249.     }
  250. }
  251.  
  252. /* Process MouseMove events */
  253. VOID HandleMouseMove (struct IntuiMessage * msg)
  254. {
  255.     struct Window *win = msg->IDCMPWindow;
  256.     struct AppInfo *ai = (struct AppInfo *) win->UserData;
  257.     struct Gadget *gad = win->FirstGadget;
  258.     struct IBox box;
  259.     LONG region;
  260.  
  261.     if ((msg->MouseX < 0) || (msg->MouseX > win->Width) ||
  262.     (msg->MouseY < 0) || (msg->MouseY > win->Height))
  263.     {
  264.     region = -1L;
  265.     }
  266.     else
  267.     {
  268.     region = 0L;
  269.  
  270.     /* Step through the gadgets to see which one the pointer was over */
  271.     while (gad && (region == 0L))
  272.     {
  273.         /* Calculate the gadget rectangle */
  274.         gadgetBox (gad, (struct IBox *) & (win->LeftEdge), &box);
  275.  
  276.         /* Is the pointer within this gadget? */
  277.         if (PointInBox (msg->MouseX, msg->MouseY, &box))
  278.         {
  279.         /* Is it a system gadget? */
  280.         if (!(gad->GadgetType & GTYP_SYSGADGET))
  281.         {
  282.             /* Set the region */
  283.             region = (LONG) gad->GadgetID;
  284.         }
  285.         }
  286.  
  287.         /* Get the next gadget */
  288.         gad = gad->NextGadget;
  289.     }
  290.     }
  291.  
  292.     if (region != ai->ai_Region)
  293.     {
  294.     WORD tx, ty;
  295.     WORD bx, by;
  296.  
  297.     tx = win->BorderLeft + 8;
  298.     ty = win->BorderTop + 2;
  299.     bx = win->Width - (win->BorderRight + 8);
  300.     by = ty + win->RPort->TxHeight;
  301.  
  302.     SetDrMd (win->RPort, JAM1);
  303.  
  304.     /* Clear the quick help region */
  305.     SetAPen (win->RPort, 0);
  306.     RectFill (win->RPort, tx, ty, bx, by);
  307.  
  308.     /* Remember the region */
  309.     ai->ai_Region = region;
  310.  
  311.     /* Display the quick help if within the window */
  312.     if (region >= 0)
  313.     {
  314.         SetAPen (win->RPort, 1);
  315.         Move (win->RPort, tx, ty + win->RPort->TxBaseline);
  316.         Text (win->RPort, quickhelp[region], strlen (quickhelp[region]));
  317.     }
  318.     }
  319. }
  320.  
  321. /* Process GadgetHelp events */
  322. VOID HandleGadgetHelp (struct IntuiMessage * msg)
  323. {
  324.     struct Window *win = msg->IDCMPWindow;
  325.     struct AppInfo *ai = (struct AppInfo *) win->UserData;
  326.     struct Gadget *gad = win->FirstGadget;
  327.     struct IBox box;
  328.     LONG region;
  329.  
  330.     region = 0L;
  331.  
  332.     /* Step through the gadgets to see which one the pointer was over */
  333.     while (gad && (region == 0L))
  334.     {
  335.     /* Calculate the gadget rectangle */
  336.     gadgetBox (gad, (struct IBox *) & (win->LeftEdge), &box);
  337.  
  338.     /* Is the pointer within this gadget? */
  339.     if (PointInBox (msg->MouseX, msg->MouseY, &box))
  340.     {
  341.         /* Is it a system gadget? */
  342.         if (gad->GadgetType & GTYP_SYSGADGET)
  343.         {
  344.         ULONG sys;
  345.  
  346.         /* Which system gadget? */
  347.         sys = (ULONG) ((gad->GadgetType & 0xF0) / 16);
  348.  
  349.         /* Set the region */
  350.         region = HTFC_SYSGADS + sys;
  351.         }
  352.         else
  353.         {
  354.         /* Set the region */
  355.         region = (LONG) gad->GadgetID;
  356.         }
  357.     }
  358.  
  359.     /* Get the next gadget */
  360.     gad = gad->NextGadget;
  361.     }
  362.  
  363.     /* Set the AmigaGuide context. */
  364.     SetAmigaGuideContext (ai->ai_AmigaGuide, region, NULL);
  365.  
  366.     /* Display the current node */
  367.     SendAmigaGuideContext (ai->ai_AmigaGuide, NULL);
  368. }
  369.  
  370. /* Process Gadget events */
  371. VOID HandleGadgetEvent (struct IntuiMessage * msg)
  372. {
  373.     struct Window *win = msg->IDCMPWindow;
  374.     struct AppInfo *ai = (struct AppInfo *) win->UserData;
  375.     struct Gadget *gad = (struct Gadget *) msg->IAddress;
  376.  
  377.     if (gad)
  378.     {
  379.     (*(Funcs[gad->GadgetID].ft_Func)) (ai);
  380.     }
  381. }
  382.  
  383. /* Process Intuition messages */
  384. VOID HandleIDCMP (struct AppInfo * ai)
  385. {
  386.     struct Window *win = ai->ai_Window;
  387.     struct IntuiMessage *imsg;
  388.  
  389.     while (imsg = (struct IntuiMessage *) GetMsg (win->UserPort))
  390.     {
  391.     switch (imsg->Class)
  392.     {
  393.         case IDCMP_MOUSEMOVE:
  394.         HandleMouseMove (imsg);
  395.         break;
  396.  
  397.         case IDCMP_CLOSEWINDOW:
  398.         ai->ai_Done = TRUE;
  399.         break;
  400.  
  401.         case IDCMP_MENUPICK:
  402.         HandleMenuEvent (imsg);
  403.         break;
  404.  
  405.         case IDCMP_MENUHELP:
  406.         HandleMenuHelp (imsg);
  407.         break;
  408.  
  409.         case IDCMP_GADGETUP:
  410.         HandleGadgetEvent (imsg);
  411.         break;
  412.  
  413.         case IDCMP_RAWKEY:
  414.         if (imsg->Code == 95)
  415.         {
  416.             HandleGadgetHelp (imsg);
  417.         }
  418.  
  419.         break;
  420.     }
  421.  
  422.     /* Reply to the message */
  423.     ReplyMsg ((struct Message *) imsg);
  424.     }
  425. }
  426.  
  427. VOID DisplayError (LONG err)
  428. {
  429.  
  430.     printf ("%s\n", GetAmigaGuideString (err));
  431. }
  432.  
  433. STRPTR err_type[] =
  434. {
  435.     "NO ERROR",
  436.     "HTERR_NOT_ENOUGH_MEMORY",
  437.     "HTERR_CANT_OPEN_DATABASE",
  438.     "HTERR_CANT_FIND_NODE",
  439.     "HTERR_CANT_OPEN_NODE",
  440.     "HTERR_CANT_OPEN_WINDOW",
  441.     "HTERR_INVALID_COMMAND",
  442.     "HTERR_CANT_COMPLETE",
  443.     "HTERR_PORT_CLOSED",
  444.     "HTERR_CANT_CREATE_PORT",
  445.     NULL
  446. };
  447.  
  448. STRPTR msg_type[] =
  449. {
  450.     "<unknown>",
  451.     "StartupMsgID",
  452.     "LoginToolID",
  453.     "LogoutToolID",
  454.     "ShutdownMsgID",
  455.     "ActivateToolID",
  456.     "DeactivateToolID",
  457.     "ActiveToolID",
  458.     "InactiveToolID",
  459.     "ToolStatusID",
  460.     "ToolCmdID",
  461.     "ToolCmdReplyID",
  462.     "ShutdownToolID",
  463.     NULL
  464. };
  465.  
  466. VOID display_msg (struct AmigaGuideMsg * msg)
  467. {
  468.     LONG type, err;
  469.  
  470.     type = msg->agm_Type - StartupMsgID + 1;
  471.     err = msg->agm_Sec_Ret - HTERR_NOT_ENOUGH_MEMORY + 1;
  472.  
  473.     if (err < 0)
  474.     err = 0;
  475.  
  476.     if (type < 0)
  477.     type = 0;
  478.  
  479.     if (msg->agm_Msg.mn_Node.ln_Type == NT_REPLYMSG)
  480.     {
  481.     DB (kprintf ("Reply "));
  482.     }
  483.     else if (msg->agm_Msg.mn_Node.ln_Type == NT_MESSAGE)
  484.     {
  485.     DB (kprintf ("Message "));
  486.     }
  487.     else
  488.     {
  489.     DB (kprintf ("Unknown "));
  490.     }
  491.  
  492.     DB (kprintf ("%s : %s\n", msg_type[type], err_type[err]));
  493. }
  494.  
  495. /* Process AmigaGuide messages */
  496. VOID HandleAmigaGuide (struct AppInfo * ai)
  497. {
  498.     struct AmigaGuideMsg *agm;
  499.  
  500.     /* process amigaguide messages */
  501.     while (agm = GetAmigaGuideMsg (ai->ai_AmigaGuide))
  502.     {
  503.     DB (display_msg (agm));
  504.  
  505.     /* check message types */
  506.     switch (agm->agm_Type)
  507.     {
  508.         /* AmigaGuide is ready for us */
  509.         case ActiveToolID:
  510.         break;
  511.  
  512.         /* This is a reply to our cmd */
  513.         case ToolCmdReplyID:
  514.         if (agm->agm_Pri_Ret)
  515.         {
  516.             DisplayError (agm->agm_Sec_Ret);
  517.         }
  518.         break;
  519.  
  520.         /* This is a status message */
  521.         case ToolStatusID:
  522.         if (agm->agm_Pri_Ret)
  523.         {
  524.             DisplayError (agm->agm_Sec_Ret);
  525.         }
  526.         break;
  527.  
  528.         /* Shutdown message */
  529.         case ShutdownMsgID:
  530.         if (agm->agm_Pri_Ret)
  531.         {
  532.             DisplayError (agm->agm_Sec_Ret);
  533.         }
  534.         break;
  535.  
  536.         default:
  537.         break;
  538.     }
  539.  
  540.     /* Reply to the message */
  541.     ReplyAmigaGuideMsg (agm);
  542.     }
  543. }
  544.  
  545. main (int argc, char **argv)
  546. {
  547.     struct NewAmigaGuide nag = {NULL};
  548.     struct AppInfo ai = {NULL};
  549.  
  550.     /* Initialize the global data */
  551.     ai.ai_Region = -1;
  552.  
  553.     /* Open Intuition library */
  554.     IntuitionBase = OpenLibrary ("intuition.library", 0);
  555.  
  556.     /* Open the graphics library */
  557.     GfxBase = OpenLibrary ("graphics.library", 0);
  558.  
  559.     /* amigaguide.library works with 1.3 and newer versions of the OS */
  560.     if (AmigaGuideBase = OpenLibrary ("amigaguide.library", 33))
  561.     {
  562.     /* Open the window font */
  563.     if (ai.ai_Font = OpenFont (&TOPAZ8))
  564.     {
  565.         /* Open the window */
  566.         if (ai.ai_Window = OpenWindow (&NewWindowStructure1))
  567.         {
  568.         ULONG sigr = 0L, sigi = 0L, sigb = 0L;
  569.  
  570.         /* Set the window font */
  571.         SetFont (ai.ai_Window->RPort, ai.ai_Font);
  572.  
  573.         /* Set the menu */
  574.         SetMenuStrip (ai.ai_Window, &Menu1);
  575.  
  576.         /* Remember the AppInfo */
  577.         ai.ai_Window->UserData = (APTR) & ai;
  578.  
  579.         /* Show that we're not done running the application yet */
  580.         ai.ai_Done = FALSE;
  581.  
  582.         /* Set the application base name */
  583.         nag.nag_BaseName = "HyperApp";
  584.  
  585.         /* Set the document name */
  586.         nag.nag_Name = "hyperapp.guide";
  587.  
  588.         /* establish the base name to use for hypertext ARexx port */
  589.         nag.nag_ClientPort = "AGAPP_HELP";
  590.  
  591.         /* Set up the context table */
  592.         nag.nag_Context = context;
  593.  
  594.         /* Open the help system */
  595.         ai.ai_AmigaGuide = OpenAmigaGuideAsync (&nag, NULL);
  596.  
  597.         /* Get our signal bits */
  598.         sigb = AmigaGuideSignal (ai.ai_AmigaGuide);
  599.         sigi = (1L << ai.ai_Window->UserPort->mp_SigBit);
  600.  
  601.         /* Clear the AmigaGuide context */
  602.         SetAmigaGuideContext (ai.ai_AmigaGuide, 0L, NULL);
  603.  
  604.         /* Continue until done */
  605.         while (!(ai.ai_Done))
  606.         {
  607.             /* Wait for something to happen */
  608.             sigr = Wait (sigb | sigi);
  609.  
  610.             /* Process Intuition messages */
  611.             if (sigr & sigi)
  612.             {
  613.             HandleIDCMP (&ai);
  614.             }
  615.  
  616.             /* Process AmigaGuide messages */
  617.             if (sigr & sigb)
  618.             {
  619.             HandleAmigaGuide (&ai);
  620.             }
  621.         }
  622.  
  623.         /* Shutdown the help system */
  624.         CloseAmigaGuide (ai.ai_AmigaGuide);
  625.  
  626.         /* Do we have a menu? */
  627.         if (ai.ai_Window->MenuStrip)
  628.         {
  629.             /* Clear it */
  630.             ClearMenuStrip (ai.ai_Window);
  631.         }
  632.  
  633.         /* Close the application window */
  634.         CloseWindow (ai.ai_Window);
  635.         }
  636.  
  637.         /* Close the font */
  638.         CloseFont (ai.ai_Font);
  639.     }
  640.  
  641.     /* close the library */
  642.     CloseLibrary (AmigaGuideBase);
  643.     }
  644.  
  645.     CloseLibrary (GfxBase);
  646.     CloseLibrary (IntuitionBase);
  647. }
  648.  
  649. VOID MainFunc (struct AppInfo * ai)
  650. {
  651.  
  652.     printf ("I don't do anything...\n");
  653. }
  654.  
  655. VOID QuitFunc (struct AppInfo * ai)
  656. {
  657.  
  658.     /* All done, guys */
  659.     ai->ai_Done = TRUE;
  660. }
  661.  
  662. VOID GadgetFunc (struct AppInfo * ai)
  663. {
  664.  
  665.     printf ("Pressed the big gadget\n");
  666. }
  667.  
  668. VOID OkayFunc (struct AppInfo * ai)
  669. {
  670.  
  671.     /* All done, guys */
  672.     ai->ai_Done = TRUE;
  673. }
  674.  
  675. VOID CancelFunc (struct AppInfo * ai)
  676. {
  677.  
  678.     /* All done, guys */
  679.     ai->ai_Done = TRUE;
  680. }
  681.