home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / Resources / System / BoingBag1 / Contributions / Workbench / RexxArpLib3p6 / src / createhost.c < prev    next >
C/C++ Source or Header  |  1998-06-21  |  22KB  |  1,091 lines

  1. /**    CreatHost.c
  2.   *
  3.   *    Implement the basic Create Host Port and dispatch window functions
  4.   * for rexxarplib.library.
  5.   *
  6.   *   AUTHOR/DATE:  W.G.J. Langeveld, November 1987.
  7.   *   ============
  8.   *
  9.   *    CURRENT VERSION:
  10.   *
  11.   *    This version has been converted to SAS C 6.5 format. It has been modified
  12.   *    for modern definition sequences for ANSI compilation. This no longer works
  13.   *    with OS versions prior to 2.04.e
  14.   *
  15.   *   AUTHOR/DATE:  Joanne Dow, jdow@bix.com, June 1998.
  16.   *   ============
  17.   *
  18.   **/
  19. #include <functions.h>
  20. #include "ralprotos.h"
  21. #include <exec/types.h>
  22. #include <exec/exec.h>
  23. #include <intuition/intuitionbase.h>
  24. #include <libraries/MyARP.h>
  25. #include <proto/rexxsyslib.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29. #include <time.h>
  30. #include "rexxarplib.h"
  31. #include <simpmenu.h>
  32. #include <simpreq.h>
  33.  
  34. /*
  35.  *   The window host function table
  36.  */
  37. static struct WHfunc whfs[] = 
  38. {
  39.     {
  40.         whf_openwindow,     "OPENWINDOW"     , 7 , 0       
  41.     }
  42.     ,
  43.     {
  44.         whf_closewindow,    "CLOSEWINDOW"    , 1 , 0       
  45.     }
  46.     ,
  47.     {
  48.         whf_closewindow,    "STOP"           , 0 , 0       
  49.     }
  50.     ,
  51.     {
  52.         whf_closewindow,    "QUIT"           , 0 , 0       
  53.     }
  54.     ,
  55.     {
  56.         whf_closewindow,    "EXIT"           , 0 , 0       
  57.     }
  58.     ,
  59.     {
  60.         whf_draw,           "DRAW"           , 2 , 2       
  61.     }
  62.     ,
  63.     {
  64.         whf_move,           "MOVE"           , 2 , 2       
  65.     }
  66.     ,
  67.     {
  68.         whf_text,           "TEXT"           , 1 , 1       
  69.     }
  70.     ,
  71.     {
  72.         whf_writepixel,     "WRITEPIXEL"     , 2 , 2       
  73.     }
  74.     ,
  75.     {
  76.         whf_drawellipse,    "DRAWELLIPSE"    , 4 , 4       
  77.     }
  78.     ,
  79.     {
  80.         whf_drawcircle,     "DRAWCIRCLE"     , 3 , 3       
  81.     }
  82.     ,
  83.     {
  84.         whf_flood,          "FLOOD"          , 3 , 3       
  85.     }
  86.     ,
  87.     {
  88.         whf_rectfill,       "RECTFILL"       , 4 , 4       
  89.     }
  90.     ,
  91.     {
  92.         whf_setrgb4,        "SETRGB4"        , 4 , 4       
  93.     }
  94.     ,
  95.     {
  96.         whf_setapen,        "SETAPEN"        , 1 , 1       
  97.     }
  98.     ,
  99.     {
  100.         whf_setbpen,        "SETBPEN"        , 1 , 1       
  101.     }
  102.     ,
  103.     {
  104.         whf_setopen,        "SETOPEN"        , 1 , 1       
  105.     }
  106.     ,
  107.     {
  108.         whf_setdrmd,        "SETDRMD"        , 1 , 1       
  109.     }
  110.     ,
  111.     {
  112.         whf_setdrpt,        "SETDRPT"        , 1 , 1       
  113.     }
  114.     ,
  115.     {
  116.         whf_areamove,       "AREAMOVE"       , 2 , 2       
  117.     }
  118.     ,
  119.     {
  120.         whf_areadraw,       "AREADRAW"       , 2 , 2       
  121.     }
  122.     ,
  123.     {
  124.         whf_areaend,        "AREAEND"        , 1 , 0       
  125.     }
  126.     ,
  127.     {
  128.         whf_areaellipse,    "AREAELLIPSE"    , 4 , 4       
  129.     }
  130.     ,
  131.     {
  132.         whf_areacircle,     "AREACIRCLE"     , 3 , 3       
  133.     }
  134.     ,
  135.     {
  136.         whf_addgadget,      "ADDGADGET"      , 7 , 5       
  137.     }
  138.     ,
  139.     {
  140.         whf_removegadget,   "REMOVEGADGET"   , 1 , 1       
  141.     }
  142.     ,
  143.     {
  144.         whf_refreshgadgets, "REFRESHGADGETS" , 0 , 0       
  145.     }
  146.     ,
  147.     {
  148.         whf_windowtext,     "WINDOWTEXT"     , 1 , 1       
  149.     }
  150.     ,
  151.     {
  152.         whf_backfill,       "BACKFILL"       , 0 , 0       
  153.     }
  154.     ,
  155.     {
  156.         whf_activategadget, "ACTIVATEGADGET" , 1 , 1       
  157.     }
  158.     ,
  159.     {
  160.         whf_activatewindow, "ACTIVATEWINDOW" , 0 , 0       
  161.     }
  162.     ,
  163.     {
  164.         whf_windowtofront,  "WINDOWTOFRONT"  , 0 , 0       
  165.     }
  166.     ,
  167.     {
  168.         whf_windowtoback,   "WINDOWTOBACK"   , 0 , 0       
  169.     }
  170.     ,
  171.     {
  172.         whf_setfont,        "SETFONT"        , 5 , 2       
  173.     }
  174.     ,
  175.     {
  176.         whf_modifyhost,     "MODIFYHOST"     , 2 , 2       
  177.     }
  178.     ,
  179.     {
  180.         whf_readgadget,     "READGADGET"     , 1 , 1       
  181.     }
  182.     ,
  183.     {
  184.         whf_setnotify,      "SETNOTIFY"      , 2 , 2       
  185.     }
  186.     ,
  187.     {
  188.         whf_addmenu,        "ADDMENU"        , 1 , 1       
  189.     }
  190.     ,
  191.     {
  192.         whf_additem,        "ADDITEM"        , 5 , 2       
  193.     }
  194.     ,
  195.     {
  196.         whf_addsubitem,     "ADDSUBITEM"     , 5 , 2       
  197.     }
  198.     ,
  199.     {
  200.         whf_remmenu,        "REMOVEMENU"     , 0 , 0       
  201.     }
  202.     ,
  203.     {
  204.         whf_setreqcolor,    "SETREQCOLOR"    , 2 , 2       
  205.     }
  206.     ,
  207.     {
  208.         whf_setitem,        "SETITEM"        , 4 , 4       
  209.     }
  210.     ,
  211.     {
  212.         whf_readhost,       "READHOST"       , 2 , 2       
  213.     }
  214.     ,
  215.     {
  216.         whf_setgadget,      "SETGADGET"      , 2 , 2       
  217.     }
  218.     ,
  219.     {
  220.         whf_drawiff,        "IFFIMAGE"       , 6 , 1       
  221.     }
  222.     ,
  223.     {
  224.         whf_null,            NULL            , 0 , 0       
  225.     }
  226. };
  227.  
  228. /**
  229.  *
  230.  *   This function finds a window host functions and checks the arguments
  231.  *
  232. **/
  233. whf_find( long *err, int nargs, char *function )
  234. {
  235.     int ival;
  236.     
  237.     *err = 1L;
  238.     /*
  239.      *   Get the function index
  240.      */
  241.     ival = whhtable_index(function);
  242.     if (ival < 0)
  243.         return(-1);
  244.     
  245.     if (strcmpu(function, whfs[ival].rexxname) != 0)
  246.         return(-1);
  247.     
  248.     *err = 17L;
  249.     /*
  250.      *   Check number of arguments
  251.      */
  252.     if (nargs > whfs[ival].nargs)
  253.         return(-1);
  254.     if (nargs < whfs[ival].nargs_req)
  255.         return(-1);
  256.     
  257.     *err = 0L;
  258.     return(ival);
  259. }
  260.  
  261. /**
  262.  *
  263.  *   This function sets up a host that handles the function calls in the
  264.  *   table above.
  265.  *
  266. **/
  267. #define CHARWIDTH 8
  268. #define CHARHEIGHT 9
  269.  
  270. char *rxf_createhost( long *err, int n, char *args[] )
  271. {
  272.     int ival = 0, nargs = 0, i, num = 0, na;
  273.     int mouse_outstanding = 0;
  274.     char *retval = NULL, *sg = NULL;
  275.     struct Gadget *object = NULL;
  276.     ULONG    class;
  277.     USHORT   code, qual;
  278.     long waitflags = 0L;
  279.     struct IntuiMessage *message = NULL;
  280.     struct RexxMsg *rexxmsg = NULL;
  281.     struct HostParams hp;
  282.     struct ReqPens reqp;
  283.     struct GUData *gud;
  284.     struct MenuItem *mi;
  285.     
  286.     *err = 3L;
  287.     /*
  288.      *   Initialize the HostParams structure
  289.      */
  290.     setmem(&hp, sizeof(struct HostParams), 0);
  291.     
  292.     /*
  293.      *   Under V36, defer the numbers till we open the window. This is because
  294.      *   we want to get the defaults from the Screen, there is one.
  295.      *   We can't assume the screen is open yet, and also the user may
  296.      *   already have set his colors by the time we do that though!
  297.      *   If he did, the number won't be -1, so use that now.
  298.      */
  299.     reqp.reqp_BlockPen  = (unsigned char) -1;
  300.     reqp.reqp_DetailPen = (unsigned char) -1;
  301.     reqp.reqp_BackPen   = (unsigned char) -1;
  302.     reqp.reqp_PromptPen = (unsigned char) -1;
  303.     reqp.reqp_BoxPen    = (unsigned char) -1;
  304.     reqp.reqp_ShadowPen = (unsigned char) -1;
  305.     reqp.reqp_OkayPen   = (unsigned char) -1;
  306.     reqp.reqp_CancelPen = (unsigned char) -1;
  307.  
  308.     hp.ReqPens      = &reqp;
  309.     
  310.     hp.Continue     = TRUE;
  311.     /*
  312.      *   Check arguments
  313.      */
  314.     *err = 18L;
  315.     if (!args[0])
  316.         goto cleanup;
  317.     if (!args[1])
  318.         goto cleanup;
  319.     
  320.     if (n >= 3)
  321.         hp.PublicScreen = args[2];
  322.     /*
  323.      *   Allocate some stuff
  324.      */
  325.     for (i = 0; i < MAXCLASSES; i++) 
  326.     {
  327.         hp.ClassText[i] = mymalloc(3);
  328.         if (!hp.ClassText[i])
  329.             goto cleanup;
  330.         strcpy(hp.ClassText[i], "%l");
  331.         
  332.         hp.NotifyPortName[i] = mymalloc(strlen(args[1]) + 1);
  333.         if (!hp.NotifyPortName[i])
  334.             goto cleanup;
  335.         strcpy(hp.NotifyPortName[i], args[1]);
  336.     }
  337.     
  338.     for (i = 0; i < 16; i++) 
  339.     {
  340.         hp.MsgPtr[i] = mymalloc(MAXIDCMPSIZE);
  341.         if (!hp.MsgPtr[i])
  342.             goto cleanup;
  343.     }
  344.     /*
  345.      *   Allocate a Vertex structure
  346.      */
  347.     hp.Vertex = AddVertex(NULL);
  348.     /*
  349.      *   Set up the Host's control master port.
  350.      */
  351.     *err = 12L;
  352.     hp.MasterPort = FindPort(args[0]);
  353.     if (hp.MasterPort)
  354.         goto cleanup;
  355.     
  356.     hp.MasterPort = CreatePort(args[0], 0L);
  357.     if (hp.MasterPort == NULL)
  358.         goto cleanup;
  359.     hp.WaitMask = 1L << hp.MasterPort->mp_SigBit;
  360.     /*
  361.      *   Main loop.
  362.      */
  363.     while (hp.Continue || hp.MsgCount) 
  364.     {
  365.         waitflags = Wait(hp.WaitMask);
  366.         /*
  367.          *   Handle messages from the MasterPort
  368.          */
  369.         if (waitflags & 1L << hp.MasterPort->mp_SigBit) 
  370.         {
  371.             while(( rexxmsg = (struct RexxMsg *) GetMsg(hp.MasterPort)) != NULL) 
  372.             {
  373.                 /*
  374.                  *   See if this is a reply to a message we sent out.
  375.                  *   reset the mouse flag when we get a reply.
  376.                  */
  377.                 if (rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) 
  378.                 {
  379.                     HandlePortReply(rexxmsg);
  380.                     mouse_outstanding = 0;
  381.                     hp.MsgCount--;
  382.                 }
  383.                 else
  384.                 {
  385.                     if (hp.Continue) 
  386.                     {
  387.                         /*
  388.                          *   Find the function
  389.                          */
  390.                         nargs = rexxmsg->rm_Action & 0xFF;
  391.                         ival = whf_find(&(hp.Result), nargs, rexxmsg->rm_Args[0]);
  392.                         /*
  393.                          *   Call the function with the arguments.
  394.                          */
  395.                         if (ival >= 0) 
  396.                         {
  397.                             retval = (*whfs[ival].rexxfunc)(&hp, nargs,
  398.                             &(rexxmsg->rm_Args[1]) );
  399.                         }
  400.                         rexxmsg->rm_Result1 = hp.Result;
  401.                     }
  402.                     else
  403.                     {
  404.                         rexxmsg->rm_Result1 = 12L;
  405.                     }
  406.                     /*
  407.                      *   Set the return values
  408.                      */
  409.                     rexxmsg->rm_Result2 = 0L;
  410.                     ReplyMsg( (struct Message *) rexxmsg);
  411.                 }
  412.             }
  413.         }
  414.         /*
  415.          *   Handle messages from the window if it exists
  416.          */
  417.         if (hp.Window && hp.Window->UserPort) 
  418.         {
  419.             if (waitflags & 1L << hp.Window->UserPort->mp_SigBit) 
  420.             {
  421.                 while((message = (struct IntuiMessage *)
  422.                 GetMsg(hp.Window->UserPort)) != NULL) 
  423.                 {
  424.                     code   = message->Code;
  425.                     qual   = message->Qualifier;
  426.                     object = (struct Gadget *) message->IAddress;
  427.                     class  = message->Class;
  428.                     
  429.                     ReplyMsg( (struct Message *) message);
  430.                     /*
  431.                      *   If we've really quit, don't do anything
  432.                      */
  433.                     if (hp.Continue == 0L)
  434.                         continue;
  435.                     /*
  436.                      *   Don't do mousemoves if no reply to previous message yet.
  437.                      */
  438.                     if (class == MOUSEMOVE) 
  439.                     {
  440.                         if (mouse_outstanding)
  441.                             continue;
  442.                         mouse_outstanding = 1;
  443.                     }
  444.                     /*
  445.                      *   Handle gadgets and menus separately.
  446.                      */
  447.                     num = ch_classtoindex(class);
  448.                     na = 0;
  449.                     
  450.                     if (class == GADGETUP || class == GADGETDOWN ) 
  451.                     {
  452.                         sg = NULL;
  453.                         if ((object->GadgetID & 0x0F) == 0x02)
  454.                             sg = (char *)
  455.                         ((struct StringInfo*) (object->SpecialInfo))->Buffer;
  456.                         
  457.                         if (gud = (struct GUData *) object->UserData) 
  458.                         {
  459.                             na = ch_makestr(&hp, gud->MsgText, class, code, qual,
  460.                             gud->GadgetID, sg);
  461.                             if (na) 
  462.                             {
  463.                                 if (SendPortMsg(hp.NotifyPortName[num], na, hp.MsgPtr,
  464.                                     hp.MasterPort) == 0) hp.MsgCount++;
  465.                             }
  466.                         }
  467.                     }
  468.                     else
  469.                     if (class == MENUPICK) 
  470.                     {
  471.                         if (hp.Window->MenuStrip) 
  472.                         {
  473.                             while (code != MENUNULL) 
  474.                             {
  475.                                 mi = ItemAddress(hp.Window->MenuStrip, (long) code);
  476.                                 if (sg = ((struct XMenuItem *) mi)->UserData) 
  477.                                 {
  478.                                     na = ch_makestr(&hp, sg, class, code, qual,
  479.                                     NULL, NULL);
  480.                                     if (na) 
  481.                                     {
  482.                                         if (SendPortMsg(hp.NotifyPortName[num], na,
  483.                                             hp.MsgPtr, hp.MasterPort) == 0) hp.MsgCount++;
  484.                                     }
  485.                                 }
  486.                                 code = mi->NextSelect;
  487.                             }
  488.                         }
  489.                     }
  490.                     else
  491.                     {
  492.                         if (num >= 0) 
  493.                         {
  494.                             na = ch_makestr(&hp, hp.ClassText[num], class, code, qual,
  495.                             NULL, NULL);
  496.                             if (na) 
  497.                             {
  498.                                 if (SendPortMsg(hp.NotifyPortName[num], na, hp.MsgPtr,
  499.                                     hp.MasterPort) == 0) hp.MsgCount++;
  500.                             }
  501.                         }
  502.                     }
  503.                 }
  504.             }
  505.         }
  506.     }
  507.     
  508.     *err = 0L;
  509.     
  510.     cleanup:
  511.     if (hp.Vertex)
  512.         hp.Vertex = KillVertex(hp.Vertex);
  513.     
  514.     if (hp.Font)
  515.         CloseFont(hp.Font);
  516.     
  517.     if (hp.Window)
  518.         whf_closewindow(&hp, 0, NULL);
  519.     
  520.     for (i = 0; i < MAXCLASSES; i++) 
  521.     {
  522.         if (hp.ClassText[i])
  523.             myfree(hp.ClassText[i]);
  524.         if (hp.NotifyPortName[i])
  525.             myfree(hp.NotifyPortName[i]);
  526.     }
  527.     
  528.     for (i = 0; i < 16; i++) 
  529.     {
  530.         if (hp.MsgPtr[i])
  531.             myfree(hp.MsgPtr[i]);
  532.     }
  533.     
  534.     if (hp.MasterPort && hp.WaitMask) 
  535.     {
  536.         while((rexxmsg = (struct RexxMsg *) GetMsg(hp.MasterPort)) != NULL) 
  537.         {
  538.             rexxmsg->rm_Result1 = 0L;
  539.             rexxmsg->rm_Result2 = 0L;
  540.             ReplyMsg( (struct Message *) rexxmsg);
  541.         }
  542.         DeletePort(hp.MasterPort);
  543.     }
  544.     
  545.     return(CAS("0"));
  546. }
  547.  
  548.  
  549.  
  550.  
  551. /**
  552.  *
  553.  *   The NULL function
  554.  *
  555. **/
  556. char *whf_null( struct HostParams *a, int b, char **c )
  557. {
  558.     return(NULL);
  559. }
  560.  
  561.  
  562. /**
  563.  *
  564.  *   Openwindow function
  565.  *
  566. **/
  567. #define NWSIZE ((long) sizeof(struct NewWindow))
  568.     
  569. char *whf_openwindow( struct HostParams *hp, int n, char *args[] )
  570. {
  571.     struct NewWindow *nw = NULL;
  572.     char *wt = NULL;
  573.     struct DrawInfo *dri;
  574.     int i;
  575.     struct ReqPens *reqp;
  576.  
  577.     hp->ScreenPtr = NULL;
  578.  
  579.     hp->Result = 12L;
  580.     if (hp->Window)
  581.         return(NULL);
  582.  
  583.     hp->Result = 17L;
  584.     if (args == NULL)
  585.         goto cleanup;
  586.     /*
  587.      *   If we can't find the public screen, open on the Workbench.
  588.      */
  589.     hp->ScreenPtr = LockScreen(hp->PublicScreen);
  590.     if (hp->ScreenPtr == NULL)
  591.         hp->PublicScreen = NULL;
  592.     
  593.     reqp = hp->ReqPens;
  594.  
  595.     /*
  596.      *   If we have a screen, then get its DrawInfo to obtain the pens it uses.
  597.      *   Only use its pens if the program hasn't changed the pens yet (i.e.
  598.      *   the pen isn't set to -1).
  599.      *   If the screen won't open or there is no screen, use our usual defaults.
  600.      */
  601.     if (hp->ScreenPtr) 
  602.     {
  603.         dri = GetScreenDrawInfo(hp->ScreenPtr);
  604.         
  605.         if (reqp->reqp_BlockPen  == -1)
  606.             reqp->reqp_BlockPen  = dri->dri_Pens[BLOCKPEN];
  607.         if (reqp->reqp_DetailPen == -1)
  608.             reqp->reqp_DetailPen = dri->dri_Pens[DETAILPEN];
  609.         if (reqp->reqp_BackPen   == -1)
  610.             reqp->reqp_BackPen   = dri->dri_Pens[BACKGROUNDPEN];
  611.         if (reqp->reqp_PromptPen == -1)
  612.             reqp->reqp_PromptPen = dri->dri_Pens[TEXTPEN];
  613.         if (reqp->reqp_BoxPen    == -1)
  614.             reqp->reqp_BoxPen    = dri->dri_Pens[SHINEPEN];
  615.         if (reqp->reqp_ShadowPen == -1)
  616.             reqp->reqp_ShadowPen = dri->dri_Pens[SHADOWPEN];
  617.         if (reqp->reqp_OkayPen   == -1)
  618.             reqp->reqp_OkayPen   = dri->dri_Pens[TEXTPEN];
  619.         if (reqp->reqp_CancelPen == -1)
  620.             reqp->reqp_CancelPen = dri->dri_Pens[HIGHLIGHTTEXTPEN];
  621.         
  622.         FreeScreenDrawInfo(hp->ScreenPtr, dri);
  623.     }
  624.     else
  625.     {
  626.         if (reqp->reqp_BlockPen  == -1)
  627.             reqp->reqp_BlockPen  = 3;
  628.         if (reqp->reqp_DetailPen == -1)
  629.             reqp->reqp_DetailPen = 2;
  630.         if (reqp->reqp_BackPen   == -1)
  631.             reqp->reqp_BackPen   = 0;
  632.         if (reqp->reqp_PromptPen == -1)
  633.             reqp->reqp_PromptPen = 1;
  634.         if (reqp->reqp_BoxPen    == -1)
  635.             reqp->reqp_BoxPen    = 2;
  636.         if (reqp->reqp_ShadowPen == -1)
  637.             reqp->reqp_ShadowPen = 1;
  638.         if (reqp->reqp_OkayPen   == -1)
  639.             reqp->reqp_OkayPen   = 1;
  640.         if (reqp->reqp_CancelPen == -1)
  641.             reqp->reqp_CancelPen = 3;
  642.     }
  643.     
  644.     hp->Result = 3L;
  645.     nw = (struct NewWindow *) AllocMem(NWSIZE, MEMF_CLEAR);
  646.     if (nw == NULL)
  647.         goto cleanup;
  648.     
  649.     if (n >= 1 && args[0])
  650.         nw->LeftEdge = atoi(args[0]);
  651.     if (n >= 2 && args[1])
  652.         nw->TopEdge  = atoi(args[1]);
  653.     
  654.     if (hp->ScreenPtr) 
  655.     {
  656.         nw->Width  = hp->ScreenPtr->Width;
  657.         nw->Height = hp->ScreenPtr->Height;
  658.     }
  659.     else
  660.     {
  661.         nw->Width  = GetWBCols();
  662.         nw->Height = GetWBRows();
  663.         if (GetWBLace() > 0)
  664.             nw->Height <<= 1;
  665.     }
  666.     
  667.     nw->MinWidth = 40;
  668.     nw->MaxWidth = nw->Width;
  669.     if (n >= 3 && args[2]) 
  670.     {
  671.         if (i = atoi(args[2])) 
  672.         {
  673.             nw->Width  = i;
  674.             if (nw->Width < nw->MinWidth)
  675.                 nw->MinWidth = nw->Width;
  676.         }
  677.     }
  678.     
  679.     nw->MinHeight = 10;
  680.     nw->MaxHeight = nw->Height;
  681.     if (n >= 4 && args[3]) 
  682.     {
  683.         if (i = atoi(args[3])) 
  684.         {
  685.             nw->Height = i;
  686.             if (nw->Height < nw->MinHeight)
  687.                 nw->MinHeight = nw->Height;
  688.         }
  689.     }
  690.     
  691.     if (n >= 5 && args[4]) 
  692.     {
  693.         for (i = 0; i < MAXCLASSES; i++) 
  694.         {
  695.             if ( strstr(args[4], ch_classtext(i)) )
  696.                 nw->IDCMPFlags |= ch_indextoclass(i);
  697.         }
  698.     }
  699.     
  700.     nw->Flags = SMART_REFRESH;
  701.     if (n >= 6 && args[5]) 
  702.     {
  703.         if (strstr(args[5], "WINDOWCLOSE"))
  704.             nw->Flags |= WINDOWCLOSE;
  705.         if (strstr(args[5], "SIZEBRIGHT"))
  706.             nw->Flags |= SIZEBRIGHT;
  707.         if (strstr(args[5], "SIZEBBOTTOM"))
  708.             nw->Flags |= SIZEBBOTTOM;
  709.         if (strstr(args[5], "WINDOWSIZING"))
  710.             nw->Flags |= WINDOWSIZING;
  711.         if (strstr(args[5], "WINDOWDEPTH"))
  712.             nw->Flags |= WINDOWDEPTH;
  713.         if (strstr(args[5], "WINDOWDRAG"))
  714.             nw->Flags |= WINDOWDRAG;
  715.         if (strstr(args[5], "BORDERLESS"))
  716.             nw->Flags |= BORDERLESS;
  717.         if (strstr(args[5], "ACTIVATE"))
  718.             nw->Flags |= ACTIVATE;
  719.         if (strstr(args[5], "NOCAREREFRESH"))
  720.             nw->Flags |= NOCAREREFRESH;
  721.         if (strstr(args[5], "REPORTMOUSE"))
  722.             nw->Flags |= REPORTMOUSE;
  723.         if (strstr(args[5], "BACKDROP"))
  724.             nw->Flags |= BACKDROP;
  725.     }
  726.     
  727.     if (n >= 7 && args[6]) 
  728.     {
  729.         wt = mymalloc(strlen(args[6]) + 1);
  730.         if (wt == NULL)
  731.             goto cleanup;
  732.         strcpy(wt, args[6]);
  733.         nw->Title = (UBYTE *) wt;
  734.     }
  735.     
  736.     nw->BlockPen  = reqp->reqp_BlockPen;
  737.     nw->DetailPen = reqp->reqp_DetailPen;
  738.     
  739.     nw->Screen = hp->ScreenPtr;
  740.     if (hp->ScreenPtr) 
  741.     {
  742.         nw->Type = hp->ScreenPtr->Flags & SCREENTYPE;
  743.     }
  744.     else
  745.     {
  746.         nw->Type = WBENCHSCREEN;
  747.     }
  748.     
  749.     hp->Result = 18L;
  750.     hp->Window = OpenWindow(nw);
  751.     if (hp->Window == NULL)
  752.         goto cleanup;
  753.     
  754.     if (hp->Window->UserPort)
  755.         hp->WaitMask |= 1L << hp->Window->UserPort->mp_SigBit;
  756.     
  757.     hp->Result = 0L;
  758.     
  759.     FreeMem(nw, NWSIZE);
  760.     nw = NULL;
  761.     
  762.     if (strstr(args[5], "BACKFILL"))
  763.         BlankSReqWin(hp->Window, (ULONG) reqp->reqp_BackPen);
  764.     
  765.     if (hp->ScreenPtr)
  766.         UnlockScreen(hp->PublicScreen, hp->ScreenPtr);
  767.     
  768.     return(NULL);
  769.     
  770.     cleanup:
  771.     if (hp->Window) 
  772.     {
  773.         CloseWindow(hp->Window);
  774.         hp->Window = NULL;
  775.     }
  776.     if (nw)
  777.         FreeMem(nw, NWSIZE);
  778.     if (wt)
  779.         myfree(wt);
  780.  
  781.     if (hp->ScreenPtr)
  782.         UnlockScreen(hp->PublicScreen, hp->ScreenPtr);
  783.     
  784.     return(NULL);
  785. }
  786.  
  787.  
  788. /**
  789.  *
  790.  *   Closewindow function
  791.  *
  792. **/
  793. char *whf_closewindow( struct HostParams *hp, int n, char *args[] )
  794. {
  795.     struct IntuiMessage *msg = NULL;
  796.     STRPTR wt = NULL;
  797.     struct Gadget *gadget = NULL, *nextgadget = NULL;
  798.     struct Menu *menu = NULL;
  799.     
  800.     if (hp->Window) 
  801.     {
  802.         if (hp->Window->UserPort) 
  803.         {
  804.             while (msg = (struct IntuiMessage *) GetMsg(hp->Window->UserPort))
  805.                 ReplyMsg( (struct Message *) msg);
  806.             hp->WaitMask &= ~(1L << hp->Window->UserPort->mp_SigBit);
  807.         }
  808.         
  809.         gadget = hp->Window->FirstGadget;
  810.         while (gadget) 
  811.         {
  812.             nextgadget = gadget->NextGadget;
  813.             if ((gadget->GadgetID & 0xF0) == 0x70) 
  814.             {
  815.                 RemoveGadget(hp->Window, gadget);
  816.                 if (gadget->UserData)
  817.                     gadget->UserData = FreeGUData(gadget->UserData);
  818.                 FreeSimpGad(gadget);
  819.             }
  820.             gadget = nextgadget;
  821.         }
  822.         
  823.         if (menu = hp->Window->MenuStrip)
  824.             freesmenu(menu);
  825.         
  826.         wt = hp->Window->Title;
  827.         CloseWindow(hp->Window);
  828.         hp->Window = NULL;
  829.         if (wt)
  830.             myfree(wt);
  831.     }
  832.     
  833.     hp->Result = 0L;
  834.     /*
  835.      *   This implements the single argument of CLOSEWINDOW which allows the
  836.      *   host to stay around.
  837.      */
  838.     if (args[0]) 
  839.     {
  840.         if (strcmpu(args[0], "CONTINUE") == 0)
  841.             return(NULL);
  842.     }
  843.     
  844.     hp->Continue = FALSE;
  845.     
  846.     return(NULL);
  847. }
  848.  
  849. /**
  850.  *
  851.  *   Parse a string and assemble another. Return highest argument number.
  852.  *
  853. **/
  854. int ch_makestr( struct HostParams *hp, char *t, ULONG class, USHORT code, USHORT qualifier, char *id, char *sg)
  855. {
  856.     int c, d, i, n = 0, m = 0, mn = 1;
  857.     long time();
  858.     char *s, bf[11];
  859.     
  860.     if (t == NULL)
  861.         return(0);
  862.     
  863.     for (i = 0; i < 16; i++)
  864.         hp->MsgPtr[i][0] = '\0';
  865.     
  866.     s = hp->MsgPtr[0];
  867.     
  868.     i = 0;
  869.     while (c = *t++) 
  870.     {
  871.         if (c != '%') 
  872.         {
  873.             s[i++] = c;
  874.             s[i] = '\0';
  875.         }
  876.         else
  877.         {
  878.             c = *t++;
  879.             switch (c) 
  880.             {
  881.             case '\0' :
  882.                 return(0);
  883.             case '%' :
  884.                 s[i++] = '%';
  885.                 s[i] = '\0';
  886.                 break;
  887.             case 'a' :
  888.                 s[i++] = code;
  889.                 s[i] = '\0';
  890.                 break;
  891.             case 'b' :
  892.                 switch (code) 
  893.                 {
  894.                 case SELECTDOWN :
  895.                     strcat(s, "SELECTDOWN");
  896.                     break;
  897.                 case SELECTUP   :
  898.                     strcat(s, "SELECTUP");
  899.                     break;
  900.                 case MENUDOWN   :
  901.                     strcat(s, "MENUDOWN");
  902.                     break;
  903.                 case MENUUP     :
  904.                     strcat(s, "MENUUP");
  905.                     break;
  906.                 }
  907.                 break;
  908.             case 'c' :
  909.                 strcat(s, ltoa(bf, (long) code));
  910.                 break;
  911.             case 'd' :
  912.                 if (id)
  913.                     strcat(s, id);
  914.                 break;
  915.             case 'e' :
  916.                 strcat(s, ltoa(bf, (long) hp->Window->TopEdge));
  917.                 break;
  918.             case 'f' :
  919.                 strcat(s, ltoa(bf, (long) hp->Window->LeftEdge));
  920.                 break;
  921.             case 'g' :
  922.                 if (sg)
  923.                     strcat(s, sg);
  924.                 break;
  925.             case 'h' :
  926.                 strcat(s, ltoa(bf, (long) hp->Window->Height));
  927.                 break;
  928.             case 'i' :
  929.                 strcat(s, ltoa(bf, (long) ITEMNUM(code)));
  930.                 break;
  931.             case 'l' :
  932.                 strcat(s, ch_classtoascii(class));
  933.                 break;
  934.             case 'm' :
  935.                 strcat(s, ltoa(bf, (long) MENUNUM(code)));
  936.                 break;
  937.             case 'q' :
  938.                 strcat(s, ltoa(bf, (long) qualifier));
  939.                 break;
  940.             case 's' :
  941.                 strcat(s, ltoa(bf, (long) SUBNUM(code)));
  942.                 break;
  943.             case 't' :
  944.                 strcat(s, ltoa(bf, time(NULL)));
  945.                 break;
  946.             case 'w' :
  947.                 strcat(s, ltoa(bf, (long) hp->Window->Width));
  948.                 break;
  949.             case 'x' :
  950.                 strcat(s, ltoa(bf, (long) hp->Window->MouseX));
  951.                 break;
  952.             case 'y' :
  953.                 strcat(s, ltoa(bf, (long) hp->Window->MouseY));
  954.                 break;
  955.             default  :
  956.                 if (isdigit(c)) 
  957.                 {
  958.                     n = c - '0';
  959.                     d = *t;
  960.                     if (isdigit(d)) 
  961.                     {
  962.                         m = c - '0';
  963.                         if (n == 1 && m < 6) 
  964.                         {
  965.                             n = 10 + m;
  966.                             t++;
  967.                         }
  968.                     }
  969.                     s = hp->MsgPtr[n];
  970.                     if (n > (mn - 1))
  971.                         mn = n + 1;
  972.                 }
  973.                 break;
  974.             }
  975.             i = strlen(s);
  976.             if (i >= MAXIDCMPSIZE)
  977.                 return(0);
  978.         }
  979.     }
  980.     
  981.     return(mn);
  982. }
  983.  
  984.  
  985. /**
  986.  *
  987.  *   This function translates a class into its name
  988.  *
  989. **/
  990. char *ch_classtoascii( ULONG class )
  991. {
  992.     return(ch_classtext(ch_classtoindex(class)));
  993. }
  994.  
  995. /**
  996.  *
  997.  *   Function that given an index, will return the class text with that index
  998.  *
  999. **/
  1000. char *ch_classtext( int ind )
  1001. {
  1002.     static char *cltxt[] = 
  1003.     {
  1004.         "CLOSEWINDOW",
  1005.         "MOUSEBUTTONS",
  1006.         "MOUSEMOVE",
  1007.         "DELTAMOVE",
  1008.         "GADGETUP",
  1009.         "GADGETDOWN",
  1010.         "MENUPICK",
  1011.         "NEWSIZE",
  1012.         "VANILLAKEY",
  1013.         "RAWKEY",
  1014.         "NEWPREFS",
  1015.         "DISKINSERTED",
  1016.         "DISKREMOVED",
  1017.         "ACTIVEWINDOW",
  1018.         "INACTIVEWINDOW",
  1019.         "REFRESHWINDOW",
  1020.         "UNKNOWN",
  1021.     };
  1022.     
  1023.     if (ind >= 0 && ind < MAXCLASSES)
  1024.         return(cltxt[ind]);
  1025.     else
  1026.         return(NULL);
  1027. }
  1028.  
  1029. /**
  1030.  *
  1031.  *   This function retrieves a unique number for each class of IDCMP message
  1032.  *   suitable for indexing arrays.
  1033.  *
  1034. **/
  1035. int ch_classtoindex( ULONG class )
  1036. {
  1037.     switch (class) 
  1038.     {
  1039.     case CLOSEWINDOW    : return(0);
  1040.     case MOUSEBUTTONS   : return(1);
  1041.     case MOUSEMOVE      : return(2);
  1042.     case DELTAMOVE      : return(3);
  1043.     case GADGETUP       : return(4);
  1044.     case GADGETDOWN     : return(5);
  1045.     case MENUPICK       : return(6);
  1046.     case NEWSIZE        : return(7);
  1047.     case VANILLAKEY     : return(8);
  1048.     case RAWKEY         : return(9);
  1049.     case NEWPREFS       : return(10);
  1050.     case DISKINSERTED   : return(11);
  1051.     case DISKREMOVED    : return(12);
  1052.     case ACTIVEWINDOW   : return(13);
  1053.     case INACTIVEWINDOW : return(14);
  1054.     case REFRESHWINDOW  : return(15);
  1055.     default             : return(-1);
  1056.     }
  1057. }
  1058.  
  1059. /**
  1060.  *
  1061.  *   This function retrieves the class given an index;
  1062.  *
  1063. **/
  1064. ULONG ch_indextoclass( int ind )
  1065. {
  1066.     static ULONG clnums[] = 
  1067.     {
  1068.         CLOSEWINDOW    ,
  1069.         MOUSEBUTTONS   ,
  1070.         MOUSEMOVE      ,
  1071.         DELTAMOVE      ,
  1072.         GADGETUP       ,
  1073.         GADGETDOWN     ,
  1074.         MENUPICK       ,
  1075.         NEWSIZE        ,
  1076.         VANILLAKEY     ,
  1077.         RAWKEY         ,
  1078.         NEWPREFS       ,
  1079.         DISKINSERTED   ,
  1080.         DISKREMOVED    ,
  1081.         ACTIVEWINDOW   ,
  1082.         INACTIVEWINDOW ,
  1083.         REFRESHWINDOW
  1084.     };
  1085.     
  1086.     if (ind >= 0 && ind < MAXCLASSES)
  1087.         return(clnums[ind]);
  1088.     else
  1089.         return(0L);
  1090. }
  1091.