home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d419
/
parm
/
menualloc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-18
|
5KB
|
230 lines
/*
* MenuAlloc.c - Copyright © 1990 by S.R. & P.C.
*
* Created: 16 Jun 1990
* Modified: 20 Nov 1990 21:18:16
*
* Make>> make
*/
#include "Menu.h"
#include "Tokens.h"
#define NO_MENUS 4
#define MEM_BLOCK_SIZE 1024
struct MemBlock {
struct MinNode mb_MinNode;
char mb_MemBlock[MEM_BLOCK_SIZE];
};
/***** global functions *****/
void AddMenu(char *);
void AddSubMenu(char *);
void AddEntry(char *, char *, char*, char*, char, char, long, short);
void EndSubMenu(void);
void CleanUp(void);
void FreeMenus(void);
void InitMenuAlloc(void);
extern void Bye(short);
/***** global variables *****/
extern struct Menu Menu1;
extern UBYTE menu_pen;
extern char *ReqTitle;
/***** local variables *****/
static struct Menu *CurrentMenu;
static struct MenuItem *CurrentSubMenu, **CurrentItem;
static struct MinList MemList;
static size_t Avail;
void InitMenuAlloc(void)
{
MemList.mlh_Head = (struct MinNode *)&MemList.mlh_Tail;
MemList.mlh_TailPred = (struct MinNode *)&MemList;
}
/* Memory allocation functions */
static void *Malloc(size_t size);
#pragma regcall(Malloc(d0))
static void *Malloc(size_t size)
{
struct MemBlock *mb;
static char *mem;
void *chunck;
size += 3; /* make chuncks long word aligned */
size &= ~(3L);
if (size > Avail) {
if (size > MEM_BLOCK_SIZE) {
SimpleRequest(ReqTitle, "Line too long");
Bye(NO_MENUS);
}
if (!(mb = AllocMem(sizeof(struct MemBlock), MEMF_PUBLIC|MEMF_CLEAR)))
Bye(NO_MENUS);
AddTail((struct List *)&MemList, (struct Node *)mb);
mem = mb->mb_MemBlock;
Avail = MEM_BLOCK_SIZE;
}
chunck = mem;
mem += size;
Avail -= size;
return chunck;
}
/* clean up widths and other info now that menu is all built */
void CleanUp(void)
{
UWORD maxw, smaxw, txtw, top, stop, left;
struct Menu *mptr;
struct MenuItem *iptr, *sptr;
left = Menu1.Width;
for( mptr = Menu1.NextMenu ; mptr ; mptr=mptr->NextMenu ) {
mptr->LeftEdge = left;
maxw = mptr->Width = (strlen(mptr->MenuName)+2) * 8;
left += maxw;
top = 0;
/* determine max width */
for( iptr = mptr->FirstItem ; iptr ; iptr=iptr->NextItem ) {
iptr->TopEdge = top;
top += iptr->Height;
txtw = IntuiTextLength((struct IntuiText *)iptr->ItemFill)+2;
if( iptr->Flags & COMMSEQ ) txtw += 48;
if( txtw > maxw ) maxw = txtw;
}
for( iptr = mptr->FirstItem ; iptr ; iptr=iptr->NextItem ) {
iptr->Width = maxw;
stop = smaxw = 0;
for( sptr=iptr->SubItem ; sptr ; sptr=sptr->NextItem ) {
sptr->LeftEdge = maxw;
sptr->TopEdge = stop;
stop += sptr->Height;
txtw = IntuiTextLength((struct IntuiText *)sptr->ItemFill)+2;
if( sptr->Flags & COMMSEQ ) txtw += 48;
if( txtw > smaxw ) smaxw = txtw;
}
for( sptr=iptr->SubItem ; sptr ; sptr=sptr->NextItem )
sptr->Width = smaxw;
}
}
}
/***** make (and Mallocate) a copy of the passed string *****/
static char *MallocStr(char *str)
{
char *newstr;
newstr = Malloc(strlen(str)+1);
strcpy(newstr, str);
return newstr;
}
/* allocate and initialize a new MenuItem */
struct Extended_MenuItem *AllocItem(char *itemstr)
{
struct IntuiText *IT;
struct Extended_MenuItem *emi;
emi = Malloc(sizeof(struct Extended_MenuItem));
IT = Malloc(sizeof(struct IntuiText));
emi->emi_MenuItem.Height = 10;
emi->emi_MenuItem.Flags = ITEMTEXT+HIGHCOMP+ITEMENABLED;
IT->FrontPen = menu_pen;
IT->LeftEdge = IT->TopEdge = 1;
IT->DrawMode = JAM1;
IT->IText = (UBYTE *)MallocStr(itemstr);
emi->emi_MenuItem.ItemFill = (APTR)IT;
return emi;
}
/* allocate and initialize a new Menu */
void AddMenu(char *str)
{
struct Menu *Menu;
Menu = Malloc(sizeof(struct Menu));
Menu->MenuName = MallocStr(str);
Menu->Flags = MENUENABLED;
CurrentMenu->NextMenu = Menu;
CurrentMenu = Menu;
CurrentItem = &Menu->FirstItem;
}
void AddSubMenu(char *substr)
{
*CurrentItem = (struct MenuItem *)AllocItem(substr);
CurrentSubMenu = *CurrentItem;
CurrentItem = &CurrentSubMenu->SubItem;
}
void EndSubMenu(void)
{
CurrentItem = &CurrentSubMenu->NextItem;
}
void AddEntry( char *item,
char *cmd,
char *args,
char *win,
char shortcut,
char mode,
long stk,
short pri )
{
struct Extended_MenuItem *emi;
emi = AllocItem(item);
emi->emi_Mode = mode;
emi->emi_Cmd = MallocStr(cmd);
if (args) emi->emi_Args = MallocStr(args);
if (shortcut) {
emi->emi_MenuItem.Flags |= COMMSEQ;
emi->emi_MenuItem.Command = shortcut;
}
if (win)
emi->emi_Window = MallocStr(win);
emi->emi_Pri = pri;
emi->emi_Stack = stk;
*CurrentItem = (struct MenuItem *)emi;
CurrentItem = &emi->emi_MenuItem.NextItem;
}
/* free up all space taken up by our menus */
void FreeMenus( void )
{
struct MemBlock *mb;
while( mb = (struct MemBlock *)RemTail((struct List *)&MemList) )
FreeMem(mb, sizeof(struct MemBlock));
CurrentMenu = &Menu1;
Menu1.NextMenu = NULL;
Avail = 0;
}