/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * |_o_o|\\ Copyright (c) 1989 The Software Distillery. * * |. o.| || All Rights Reserved * * | . | || Written by John Toebes and Doug Walker * * | o | || The Software Distillery * * | . |// 235 Trillingham Lane * * ====== Cary, NC 27513 * * BBS:(919)-471-6436 * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include #include #include #include #include "pickpack.h" #include "struct.h" static struct STGLOB stg; #define ROUND(len) ((len) + 4 - ((len)%4)) int stsize[ST_NUM] = { sizeof(struct BUFDATA), sizeof(struct VIEWDATA), sizeof(struct FileInfoBlock), sizeof(struct FileHandle), sizeof(struct FileLock), sizeof(struct InfoData), }; char *wnames[ST_NUM] = { "Data Buffer %d", "Help Window", "FileInfoBlock %d", "FileHandle %d", "FileLock %d", "InfoData %d", }; int InitST(port) struct MsgPort *port; { BUG(1, ("InitST: Enter, port 0x%08.9x\n", port)) memset((char *)&stg, 0, sizeof(struct STGLOB)); stg.Port = port; BUG(1, ("InitST: Exit\n")) return(RC_OK); } int TermST() { int rc; struct STNODE *tmpnode; struct Message *msg; BUG(1, ("TermST: Enter\n")) while(stg.stlist) { if(RC_OK != (rc=UnlinkST(stg.stlist->w))) { BUG(1, ("TermST: Can't UnLink %08lx, rc %d\n", stg.stlist, rc)) tmpnode = stg.stlist; if(stg.stlist = stg.stlist->next) stg.stlist->prev = NULL; FreeMem(tmpnode, tmpnode->len); } } /* Make sure the port is clear */ while(msg=GetMsg(stg.Port)) ReplyMsg(msg); PurgeST(); BUG(1, ("TermST: Exit\n")) return(RC_OK); } struct Window *AllocST(type, data, olen) int type; APTR data; int olen; { struct STNODE *stnode; int len, dlen, rc; char *tmpchar; struct NewWindow *nw; struct IntuiText *it; BUG(1, ("AllocST: Enter, type %d data 0x%08x len %d\n", type, data, olen)) if(data == NULL) len = olen + stsize[type]; else len = 0; dlen = len; len += ROUND(sizeof(struct STNODE)); BUG(5, ("AllocST: dlen %d len %d\n")) if(!(tmpchar=(char *)AllocMem(len, MEMF_CLEAR))) return(NULL); stnode = (struct STNODE *)tmpchar; if(dlen > 0) data = (APTR)(tmpchar+ROUND(sizeof(struct STNODE))); sprintf(stnode->wname, wnames[type], ++stg.count[type]); stnode->d.data = data; if(type == ST_DATA || type == ST_VIEW) stnode->d.bdata->size = olen; stnode->len = len; stnode->type = type; stnode->num = stg.count[type]; /* Now open the window */ switch(type) { case ST_HANDLE: stfhnew( &nw, &it, stnode); break; case ST_LOCK: stlocknew(&nw, &it, stnode); break; case ST_FIB: stfibnew( &nw, &it, stnode); break; case ST_INFO: stinfnew( &nw, &it, stnode); break; case ST_DATA: stbufnew( &nw, &it, stnode); break; case ST_VIEW: stnode->d.vdata->lines = CountLines(stnode->d.vdata->buf, olen-sizeof(struct VIEWDATA)); stviewnew( &nw, &it, stnode); break; default: BUG(1, ("AllocST: Unknown type code %d\n", type)) FreeMem((char *)stnode, len); return(NULL); } if(nw) { nw->IDCMPFlags = NULL; /* Just 'cause PW keeps insisting... */ nw->Title = stnode->wname; if(!(stnode->w = OpenWindow(nw))) { BUG(2, ("AllocST: Couldn't open window\n")) goto ERRSPOT; } if(it) PrintIText(stnode->w->RPort, it, 0, 0); } else { BUG(2, ("AllocST: No new window\n")) goto ERRSPOT; } BUG(2, ("AllocST: Opened window 0x%08x\n", stnode->w)) /* Set up the UserData pointer to point to the STNode structure so */ /* we can find stnode from the window pointer later on */ stnode->w->UserData = (BYTE *)stnode; /**********************************************************************/ /* We want to use the same UserPort for all our windows; to do this, */ /* we allocated the window above with NULL for its IDCMPFlags. */ /* Intuition sees the NULL and doesn't initialize the IDCMP. We can */ /* then set up the UserPort field to point to our own port; after */ /* doing so, a call to ModifyIDCMP will set up the rest of the */ /* required fields. */ /**********************************************************************/ stnode->w->UserPort = stg.Port; ModifyIDCMP(stnode->w, MENUPICK|ACTIVEWINDOW|INACTIVEWINDOW|CLOSEWINDOW| GADGETUP|NEWSIZE|RAWKEY); SetMenuStrip(stnode->w, &Menu1); if(rc = DisplayST(stnode->w)) { BUG(1, ("AllocST: Bad RC from DisplayST = %d\n", rc)) goto ERRSPOT; } if(stg.stlist) stg.stlist->prev = stnode; stnode->next = stg.stlist; stg.stlist = stnode; BUG(1, ("AllocST: Exit, returning %08lx\n", stnode->w)) return(stnode->w); ERRSPOT: if(type == ST_VIEW) { FreeMem((char *)data, olen); stnode->d.data = NULL; } stnode->type = ST_UNLINKED; if(stg.unlist) stg.unlist->prev = stnode; stnode->next = stg.unlist; stg.unlist = stnode; BUG(1, ("AllocST: ERROR EXIT, returning NULL\n")) return(NULL); } int WindSize(window) struct Window *window; { struct STNODE *n; n = (struct STNODE *)window->UserData; if (n->type == ST_DATA) return(n->d.bdata->size); return(0); } void MoveWind(window, dir) struct Window *window; int dir; { struct STNODE *n; if(!window) return; n = (struct STNODE *)window->UserData; switch(n->type) { case ST_DATA: stbufmove(n, dir); break; case ST_VIEW: stviewmove(n, dir); break; default: DisplayST(window); break; } } #define NAMELEN 50 int NameST(window, name, pid) struct Window *window; char *name; struct MsgPort *pid; { struct STNODE *n; int rc; BUG(1, ("NameST: Entry, window 0x%08x name %s\n", window, name == NULL ? "NULL" : name)) if(!window) return(RC_ERRNOWIND); n = (struct STNODE *)window->UserData; n->pid = pid; if(!name) { if(n->oname) FreeMem(n->oname, NAMELEN); n->oname = NULL; } else { if(!n->oname) { if(!(n->oname = AllocMem(NAMELEN, 0))) return(RC_ERRNOMEM); } memset(n->oname, ' ', NAMELEN-1); memcpy(n->oname, name, min(strlen(name), NAMELEN-1)); n->oname[NAMELEN-1] = '\0'; } rc = DisplayST(window); BUG(1, ("NameST: Exit, returning %d\n", rc)) return(rc); } APTR FindST(name, type) char *name; int type; { struct STNODE *n; BUG(1, ("FindST: Entry, name '%s'\n", name)) for(n=stg.stlist; n; n=n->next) { if(!stricmp(name, n->wname) && n->type == type) { if(type == ST_DATA) { BUG(1, ("FindST: Exit, returning 0x%08x\n", n->d.bdata->buf)) return((APTR)n->d.bdata->buf); } BUG(1, ("FindST: Exit, returning 0x%08x\n", n->d.data)) return(n->d.data); } } BUG(1, ("FindST: Exit, no match\n")) return(NULL); } APTR WindToST(window) struct Window *window; { BUG(1, ("WindToST: Entry, Exit, returning 0x%08x\n", ((struct STNODE *)window->UserData)->d.data)) if(!window) return(NULL); return((((struct STNODE *)window->UserData)->d.data)); } struct Window *STToWind(data) APTR data; { struct STNODE *n; BUG(1, ("STToWind: Entry, looking for 0x%08x\n", data)) for(n=stg.stlist; n; n=n->next) { if(n->d.data == data || (n->type == ST_HANDLE && n->d.fh->fh_Arg1 == (BPTR)data) || (n->type == ST_DATA && n->d.bdata->buf == (char *)data) ) { BUG(1, ("STToWind: returning 0x%08x\n", n->w)) return(n->w); } } BUG(1, ("STToWind: returning NULL\n")) return(NULL); } int DisplayST(window) struct Window *window; { struct STNODE *n; int rc; BUG(1, ("DisplayST: Enter, window 0x%08x\n", window)) if(!window) return(RC_ERRNOWIND); n = (struct STNODE *)window->UserData; if(n->type == ST_UNLINKED) return(RC_UNLINKED); switch(n->type) { case ST_HANDLE: rc = stfhdisp(n); break; case ST_LOCK: rc = stlockdisp(n); break; case ST_FIB: rc = stfibdisp(n); break; case ST_INFO: rc = stinfdisp(n); break; case ST_DATA: rc = stbufdisp(n); break; case ST_VIEW: rc = stviewdisp(n); break; default: BUG(1, ("DisplayST: Bad type %d\n", n->type)) rc = RC_ERRBADTYPE; break; } BUG(1, ("DisplayST: Exit, returning %d\n", rc)) return(rc); } int UnlinkST(window) struct Window *window; { struct STNODE *n; char msg[100]; BUG(1, ("UnlinkST: Enter, window 0x%08x\n", window)) if(!window) return(RC_ERRNOWIND); n = (struct STNODE *)window->UserData; /* We don't want the user generating any more IDCMP messages for this */ /* window, so clear its menus and modify the IDCMP flags to only give */ /* menu selections. We can't send 0 for the flags or it would free */ /* the IDCMP port stuff, which would crash us. */ ClearMenuStrip(window); ModifyIDCMP(window, MENUPICK); window->UserPort = NULL; if(n->type == ST_LOCK && n->oname && n->oname[0] != ' ') { long arg; arg = (long)MKBADDR(n->d.lock); sendpkt(n->pid, ACTION_FREE_LOCK, &arg, 1, NULL); sprintf(msg, "%s was unlocked on your behalf", n->wname); n->d.lock = NULL; status(msg); } else if(n->type == ST_HANDLE && n->oname && n->oname[0] != ' ') { sendpkt(n->pid, ACTION_END, &n->d.fh->fh_Arg1, 1, NULL); n->oname[0] = ' '; sprintf(msg, "%s was closed on your behalf", n->wname); status(msg); } else if(n->type == ST_VIEW) { FreeMem((char *)n->d.vdata, n->d.vdata->size); n->d.vdata = NULL; } n->type = ST_UNLINKED; if(n->next) n->next->prev = n->prev; if(n->prev) n->prev->next = n->next; else stg.stlist = n->next; if(stg.unlist) stg.unlist->prev = n; n->next = stg.unlist; stg.unlist = n; BUG(1, ("UnlinkST: Exit\n")) return(RC_OK); } int PurgeST() { struct STNODE *n, *p; BUG(1, ("PurgeST: Enter\n")) p=stg.unlist; stg.unlist = NULL; while(p) { BUG(5, ("PurgeST: Closing window 0x%08x\n")) n = p->next; CloseWindow(p->w); BUG(8, ("PurgeST: Freeing STNODE type %d, %d bytes\n", p->type, p->len)) if(p->oname) FreeMem(p->oname, NAMELEN); FreeMem((char *)p, p->len); p=n; } BUG(1, ("PurgeST: Exit\n")) return(RC_OK); }