home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
240.lha
/
PickPacket_v1.0
/
Sources
/
struct.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-05-04
|
11KB
|
465 lines
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* |_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 <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfxmacros.h>
#include <graphics/rastport.h>
#include <libraries/dos.h>
#include <proto/intuition.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <string.h>
#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);
}