home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff227.lzh / PickPacket / src / struct.c < prev    next >
C/C++ Source or Header  |  1989-06-25  |  11KB  |  465 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
  2. * |_o_o|\\ Copyright (c) 1989 The Software Distillery.                    *
  3. * |. o.| ||          All Rights Reserved                                  *
  4. * | .  | ||          Written by John Toebes and Doug Walker               *
  5. * | o  | ||          The Software Distillery                              *
  6. * |  . |//           235 Trillingham Lane                                 *
  7. * ======             Cary, NC 27513                                       *
  8. *                    BBS:(919)-471-6436                                   *
  9. \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  10. #include <exec/types.h>
  11. #include <intuition/intuition.h>
  12. #include <graphics/gfxmacros.h>
  13. #include <graphics/rastport.h>
  14. #include <libraries/dos.h>
  15. #include <proto/intuition.h>
  16. #include <proto/dos.h>
  17. #include <proto/exec.h>
  18. #include <proto/graphics.h>
  19. #include <string.h>
  20.  
  21. #include "pickpack.h"
  22. #include "struct.h"
  23.  
  24. static struct STGLOB stg;
  25.  
  26. #define ROUND(len) ((len) + 4 - ((len)%4))
  27.  
  28. int stsize[ST_NUM] = 
  29. {
  30.    sizeof(struct BUFDATA),
  31.    sizeof(struct VIEWDATA),
  32.    sizeof(struct FileInfoBlock),
  33.    sizeof(struct FileHandle),
  34.    sizeof(struct FileLock),
  35.    sizeof(struct InfoData),
  36. };
  37.  
  38. char *wnames[ST_NUM] =
  39. {
  40.    "Data Buffer %d",
  41.    "Help Window",
  42.    "FileInfoBlock %d",
  43.    "FileHandle %d",
  44.    "FileLock %d",
  45.    "InfoData %d",
  46. };
  47.  
  48. int InitST(port)
  49. struct MsgPort *port;
  50. {
  51.    BUG(1, ("InitST: Enter, port 0x%08.9x\n", port))
  52.  
  53.    memset((char *)&stg, 0, sizeof(struct STGLOB));
  54.    stg.Port = port;
  55.  
  56.    BUG(1, ("InitST: Exit\n"))
  57.    return(RC_OK);
  58. }
  59.  
  60. int TermST()
  61. {
  62.    int rc;
  63.    struct STNODE *tmpnode;
  64.    struct Message *msg;
  65.  
  66.    BUG(1, ("TermST: Enter\n"))
  67.  
  68.    while(stg.stlist)
  69.    {
  70.       if(RC_OK != (rc=UnlinkST(stg.stlist->w)))
  71.       {
  72.          BUG(1, ("TermST: Can't UnLink %08lx, rc %d\n", stg.stlist, rc))
  73.          tmpnode = stg.stlist;
  74.          if(stg.stlist = stg.stlist->next)
  75.             stg.stlist->prev = NULL;
  76.          FreeMem(tmpnode, tmpnode->len);
  77.       }
  78.    }
  79.  
  80.    /* Make sure the port is clear */
  81.    while(msg=GetMsg(stg.Port)) ReplyMsg(msg);
  82.  
  83.    PurgeST();
  84.  
  85.    BUG(1, ("TermST: Exit\n"))
  86.  
  87.    return(RC_OK);
  88. }
  89.  
  90. struct Window *AllocST(type, data, olen)
  91. int type;
  92. APTR data;
  93. int olen;
  94. {
  95.    struct STNODE *stnode;
  96.    int len, dlen, rc;
  97.    char *tmpchar;
  98.    struct NewWindow *nw;
  99.    struct IntuiText *it;
  100.  
  101.    BUG(1, ("AllocST: Enter, type %d data 0x%08x len %d\n",
  102.       type, data, olen))
  103.  
  104.    if(data == NULL)
  105.       len = olen + stsize[type];
  106.    else 
  107.       len = 0;
  108.    dlen = len;
  109.  
  110.    len += ROUND(sizeof(struct STNODE));
  111.  
  112.    BUG(5, ("AllocST: dlen %d len %d\n"))
  113.  
  114.    if(!(tmpchar=(char *)AllocMem(len, MEMF_CLEAR)))
  115.       return(NULL);
  116.  
  117.    stnode = (struct STNODE *)tmpchar;
  118.  
  119.    if(dlen > 0)
  120.       data = (APTR)(tmpchar+ROUND(sizeof(struct STNODE)));
  121.  
  122.    sprintf(stnode->wname, wnames[type], ++stg.count[type]);
  123.  
  124.    stnode->d.data = data;
  125.  
  126.    if(type == ST_DATA || type == ST_VIEW)
  127.       stnode->d.bdata->size = olen;
  128.  
  129.    stnode->len = len;
  130.    stnode->type = type;
  131.    stnode->num = stg.count[type];
  132.  
  133.  
  134.    /* Now open the window */
  135.    switch(type)
  136.    {
  137.       case ST_HANDLE: stfhnew(  &nw, &it, stnode); break;
  138.       case ST_LOCK:   stlocknew(&nw, &it, stnode); break;
  139.       case ST_FIB:    stfibnew( &nw, &it, stnode); break;
  140.       case ST_INFO:   stinfnew( &nw, &it, stnode); break;
  141.       case ST_DATA:   stbufnew( &nw, &it, stnode); break;
  142.       case ST_VIEW:   
  143.          stnode->d.vdata->lines = CountLines(stnode->d.vdata->buf, 
  144.             olen-sizeof(struct VIEWDATA));
  145.          stviewnew( &nw, &it, stnode); 
  146.          break;
  147.       default:
  148.          BUG(1, ("AllocST: Unknown type code %d\n", type))
  149.          FreeMem((char *)stnode, len);
  150.          return(NULL);
  151.    }  
  152.  
  153.    if(nw)
  154.    {
  155.       nw->IDCMPFlags = NULL;   /* Just 'cause PW keeps insisting... */
  156.       nw->Title = stnode->wname;
  157.       if(!(stnode->w = OpenWindow(nw))) 
  158.       {
  159.          BUG(2, ("AllocST: Couldn't open window\n"))
  160.          goto ERRSPOT;
  161.       }
  162.       if(it) PrintIText(stnode->w->RPort, it, 0, 0);
  163.    }
  164.    else
  165.    {
  166.       BUG(2, ("AllocST: No new window\n"))
  167.       goto ERRSPOT;
  168.    }
  169.  
  170.  
  171.    BUG(2, ("AllocST: Opened window 0x%08x\n", stnode->w))
  172.  
  173.    /* Set up the UserData pointer to point to the STNode structure so */
  174.    /* we can find stnode from the window pointer later on             */
  175.    stnode->w->UserData = (BYTE *)stnode;
  176.  
  177.  
  178.    /**********************************************************************/
  179.    /* We want to use the same UserPort for all our windows;  to do this, */
  180.    /* we allocated the window above with NULL for its IDCMPFlags.        */
  181.    /* Intuition sees the NULL and doesn't initialize the IDCMP.  We can  */
  182.    /* then set up the UserPort field to point to our own port;  after    */
  183.    /* doing so, a call to ModifyIDCMP will set up the rest of the        */
  184.    /* required fields.                                                   */
  185.    /**********************************************************************/
  186.  
  187.    stnode->w->UserPort = stg.Port;
  188.    ModifyIDCMP(stnode->w, MENUPICK|ACTIVEWINDOW|INACTIVEWINDOW|CLOSEWINDOW|
  189.                           GADGETUP|NEWSIZE|RAWKEY);
  190.  
  191.    SetMenuStrip(stnode->w, &Menu1);
  192.  
  193.    if(rc = DisplayST(stnode->w))
  194.    {
  195.       BUG(1, ("AllocST: Bad RC from DisplayST = %d\n", rc))
  196.       goto ERRSPOT;
  197.    }
  198.  
  199.    if(stg.stlist) stg.stlist->prev = stnode;
  200.    stnode->next = stg.stlist;
  201.    stg.stlist = stnode;
  202.  
  203.    BUG(1, ("AllocST: Exit, returning %08lx\n", stnode->w))
  204.  
  205.    return(stnode->w);
  206.  
  207. ERRSPOT:
  208.    if(type == ST_VIEW) 
  209.    {
  210.       FreeMem((char *)data, olen);
  211.       stnode->d.data = NULL;
  212.    }
  213.    stnode->type = ST_UNLINKED;
  214.  
  215.    if(stg.unlist) stg.unlist->prev = stnode;
  216.    stnode->next = stg.unlist;
  217.    stg.unlist = stnode;
  218.    
  219.    BUG(1, ("AllocST: ERROR EXIT, returning NULL\n"))
  220.    return(NULL);
  221. }
  222.  
  223. int WindSize(window)
  224. struct Window *window;
  225. {
  226.    struct STNODE *n;
  227.  
  228.    n = (struct STNODE *)window->UserData;
  229.    if (n->type == ST_DATA)
  230.       return(n->d.bdata->size);
  231.    return(0);
  232. }
  233.    
  234. void MoveWind(window, dir)
  235. struct Window *window;
  236. int dir;
  237. {
  238.    struct STNODE *n;
  239.    if(!window) return;
  240.  
  241.    n = (struct STNODE *)window->UserData;
  242.    switch(n->type)
  243.       {
  244.       case ST_DATA: stbufmove(n, dir);  break;
  245.       case ST_VIEW: stviewmove(n, dir); break;
  246.       default:      DisplayST(window);  break;
  247.       }
  248. }
  249.  
  250. #define NAMELEN 50
  251.  
  252. int NameST(window, name, pid)
  253. struct Window *window;
  254. char *name;
  255. struct MsgPort *pid;
  256. {
  257.    struct STNODE *n;
  258.    int rc;
  259.  
  260.    BUG(1, ("NameST: Entry, window 0x%08x name %s\n", window,
  261.       name == NULL ? "NULL" : name))
  262.  
  263.    if(!window) return(RC_ERRNOWIND);
  264.  
  265.    n = (struct STNODE *)window->UserData;
  266.  
  267.    n->pid = pid;
  268.  
  269.    if(!name)
  270.    {
  271.       if(n->oname) FreeMem(n->oname, NAMELEN);
  272.       n->oname = NULL;
  273.    }
  274.    else
  275.    {
  276.       if(!n->oname) 
  277.       {
  278.          if(!(n->oname = AllocMem(NAMELEN, 0)))
  279.             return(RC_ERRNOMEM);
  280.       }
  281.  
  282.       memset(n->oname, ' ', NAMELEN-1);
  283.       memcpy(n->oname, name, min(strlen(name), NAMELEN-1));
  284.       n->oname[NAMELEN-1] = '\0';
  285.    }
  286.  
  287.    rc = DisplayST(window);
  288.  
  289.    BUG(1, ("NameST: Exit, returning %d\n", rc))
  290.  
  291.    return(rc);
  292. }
  293.  
  294. APTR FindST(name, type)
  295. char *name;
  296. int type;
  297. {
  298.    struct STNODE *n;
  299.    BUG(1, ("FindST: Entry, name '%s'\n", name))
  300.  
  301.    for(n=stg.stlist; n; n=n->next)
  302.    {
  303.       if(!stricmp(name, n->wname) && n->type == type)
  304.       {
  305.          if(type == ST_DATA) 
  306.          {
  307.             BUG(1, ("FindST: Exit, returning 0x%08x\n", n->d.bdata->buf))
  308.             return((APTR)n->d.bdata->buf);
  309.          }
  310.          BUG(1, ("FindST: Exit, returning 0x%08x\n", n->d.data))
  311.          return(n->d.data);
  312.       }
  313.    }
  314.    BUG(1, ("FindST: Exit, no match\n"))
  315.    return(NULL);
  316. }
  317.  
  318. APTR WindToST(window)
  319. struct Window *window;
  320. {
  321.    BUG(1, ("WindToST: Entry, Exit, returning 0x%08x\n",
  322.       ((struct STNODE *)window->UserData)->d.data))
  323.    if(!window) return(NULL);
  324.    return((((struct STNODE *)window->UserData)->d.data));
  325. }
  326.  
  327. struct Window *STToWind(data)
  328. APTR data;
  329. {
  330.    struct STNODE *n;
  331.    BUG(1, ("STToWind: Entry, looking for 0x%08x\n", data))
  332.  
  333.    for(n=stg.stlist; n; n=n->next)
  334.    {
  335.       if(n->d.data == data ||
  336.          (n->type == ST_HANDLE && n->d.fh->fh_Arg1 == (BPTR)data) ||
  337.          (n->type == ST_DATA && n->d.bdata->buf == (char *)data)
  338.         )
  339.       {
  340.          BUG(1, ("STToWind: returning 0x%08x\n", n->w))
  341.          return(n->w);
  342.       }
  343.    }
  344.    BUG(1, ("STToWind: returning NULL\n"))
  345.    return(NULL);
  346. }
  347.  
  348. int DisplayST(window)
  349. struct Window *window;
  350. {
  351.    struct STNODE *n;
  352.    int rc;
  353.  
  354.    BUG(1, ("DisplayST: Enter, window 0x%08x\n", window))
  355.  
  356.    if(!window) return(RC_ERRNOWIND);
  357.  
  358.    n = (struct STNODE *)window->UserData;
  359.    if(n->type == ST_UNLINKED) return(RC_UNLINKED);
  360.  
  361.    switch(n->type)
  362.    {
  363.       case ST_HANDLE:  rc = stfhdisp(n);      break;
  364.       case ST_LOCK:    rc = stlockdisp(n);    break;
  365.       case ST_FIB:     rc = stfibdisp(n);     break;
  366.       case ST_INFO:    rc = stinfdisp(n);     break;
  367.       case ST_DATA:    rc = stbufdisp(n);     break;
  368.       case ST_VIEW:    rc = stviewdisp(n);    break;
  369.       default:
  370.          BUG(1, ("DisplayST: Bad type %d\n", n->type))
  371.          rc = RC_ERRBADTYPE; 
  372.          break;
  373.    }
  374.  
  375.    BUG(1, ("DisplayST: Exit, returning %d\n", rc))
  376.    return(rc);
  377. }
  378.  
  379. int UnlinkST(window)
  380. struct Window *window;
  381. {
  382.    struct STNODE *n;
  383.    char msg[100];
  384.  
  385.    BUG(1, ("UnlinkST: Enter, window 0x%08x\n", window))
  386.  
  387.    if(!window) return(RC_ERRNOWIND);
  388.  
  389.    n = (struct STNODE *)window->UserData;
  390.  
  391.    /* We don't want the user generating any more IDCMP messages for this */
  392.    /* window, so clear its menus and modify the IDCMP flags to only give */
  393.    /* menu selections.  We can't send 0 for the flags or it would free   */
  394.    /* the IDCMP port stuff, which would crash us.                        */
  395.    ClearMenuStrip(window);
  396.    ModifyIDCMP(window, MENUPICK);
  397.  
  398.    window->UserPort = NULL;
  399.  
  400.    if(n->type == ST_LOCK && n->oname && n->oname[0] != ' ')
  401.    {
  402.       long arg;
  403.       arg = (long)MKBADDR(n->d.lock);
  404.       sendpkt(n->pid, ACTION_FREE_LOCK, &arg, 1, NULL);
  405.       sprintf(msg, "%s was unlocked on your behalf", n->wname);
  406.       n->d.lock = NULL;
  407.       status(msg);
  408.    }
  409.    else if(n->type == ST_HANDLE && n->oname && n->oname[0] != ' ')
  410.    {
  411.       sendpkt(n->pid, ACTION_END, &n->d.fh->fh_Arg1, 1, NULL);
  412.       n->oname[0] = ' ';
  413.       sprintf(msg, "%s was closed on your behalf", n->wname);
  414.       status(msg);
  415.    }
  416.    else if(n->type == ST_VIEW)
  417.    {
  418.       FreeMem((char *)n->d.vdata, n->d.vdata->size);
  419.       n->d.vdata = NULL;
  420.    }
  421.  
  422.    n->type = ST_UNLINKED;
  423.    if(n->next) n->next->prev = n->prev;
  424.    if(n->prev) n->prev->next = n->next;
  425.    else        stg.stlist = n->next;
  426.  
  427.    if(stg.unlist) stg.unlist->prev = n;
  428.    n->next = stg.unlist;
  429.    stg.unlist = n;
  430.  
  431.    BUG(1, ("UnlinkST: Exit\n"))
  432.  
  433.    return(RC_OK);
  434. }
  435.  
  436. int PurgeST()
  437. {
  438.    struct STNODE *n, *p;
  439.  
  440.    BUG(1, ("PurgeST: Enter\n"))
  441.  
  442.    p=stg.unlist;
  443.    stg.unlist = NULL;
  444.    while(p)
  445.    {
  446.       BUG(5, ("PurgeST: Closing window 0x%08x\n"))
  447.  
  448.       n = p->next;
  449.       CloseWindow(p->w);
  450.  
  451.       BUG(8, ("PurgeST: Freeing STNODE type %d, %d bytes\n", 
  452.          p->type, p->len))
  453.  
  454.       if(p->oname) FreeMem(p->oname, NAMELEN);
  455.  
  456.       FreeMem((char *)p, p->len);
  457.       p=n;
  458.    }
  459.  
  460.    BUG(1, ("PurgeST: Exit\n"))
  461.    
  462.    return(RC_OK);
  463. }
  464.  
  465.