home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 465.lha / ParM_v2.5r / MenuAlloc.c < prev    next >
C/C++ Source or Header  |  1991-01-05  |  5KB  |  230 lines

  1. /*
  2.  *    MenuAlloc.c - Copyright © 1990 by S.R. & P.C.
  3.  *
  4.  *    Created:    16 Jun 1990
  5.  *    Modified:    20 Nov 1990  21:18:16
  6.  *
  7.  *    Make>> make
  8.  */
  9.  
  10. #include "Menu.h"
  11. #include "Tokens.h"
  12.  
  13. #define NO_MENUS 4
  14.  
  15. #define MEM_BLOCK_SIZE 1024
  16.  
  17. struct MemBlock {
  18.     struct MinNode mb_MinNode;
  19.     char mb_MemBlock[MEM_BLOCK_SIZE];
  20. };
  21.  
  22.  
  23. /*****                 global functions                    *****/
  24.  
  25. void AddMenu(char *);
  26. void AddSubMenu(char *);
  27. void AddEntry(char *, char *, char*, char*, char, char, long, short);
  28. void EndSubMenu(void);
  29. void CleanUp(void);
  30. void FreeMenus(void);
  31. void InitMenuAlloc(void);
  32.  
  33. extern void Bye(short);
  34.  
  35. /*****                 global variables                    *****/
  36.  
  37. extern struct Menu Menu1;
  38. extern UBYTE menu_pen;
  39. extern char *ReqTitle;
  40.  
  41.  
  42. /*****                 local variables                    *****/
  43.  
  44. static struct Menu *CurrentMenu;
  45. static struct MenuItem *CurrentSubMenu, **CurrentItem;
  46. static struct MinList MemList;
  47. static size_t Avail;
  48.  
  49.  
  50. void InitMenuAlloc(void)
  51. {
  52.     MemList.mlh_Head = (struct MinNode *)&MemList.mlh_Tail;
  53.     MemList.mlh_TailPred = (struct MinNode *)&MemList;
  54. }
  55.  
  56.  
  57. /* Memory allocation functions */
  58.  
  59. static void *Malloc(size_t size);
  60. #pragma regcall(Malloc(d0))
  61.  
  62.  
  63. static void *Malloc(size_t size)
  64. {
  65.     struct MemBlock *mb;
  66.     static char *mem;
  67.     void *chunck;
  68.  
  69.     size += 3;            /* make chuncks long word aligned */
  70.     size &= ~(3L);
  71.     if (size > Avail) {
  72.         if (size > MEM_BLOCK_SIZE) {
  73.             SimpleRequest(ReqTitle, "Line too long");
  74.             Bye(NO_MENUS);
  75.         }
  76.         if (!(mb = AllocMem(sizeof(struct MemBlock), MEMF_PUBLIC|MEMF_CLEAR)))
  77.             Bye(NO_MENUS);
  78.         AddTail((struct List *)&MemList, (struct Node *)mb);
  79.         mem = mb->mb_MemBlock;
  80.         Avail = MEM_BLOCK_SIZE;
  81.     }
  82.     chunck = mem;
  83.     mem += size;
  84.     Avail -= size;
  85.     return chunck;
  86. }
  87.  
  88.  
  89. /* clean up widths and other info now that menu is all built */
  90.  
  91. void CleanUp(void)
  92. {
  93.     UWORD maxw, smaxw, txtw, top, stop, left;
  94.     struct Menu *mptr;
  95.     struct MenuItem *iptr, *sptr;
  96.  
  97.     left = Menu1.Width;
  98.     for( mptr = Menu1.NextMenu ; mptr ; mptr=mptr->NextMenu ) {
  99.         mptr->LeftEdge = left;
  100.         maxw = mptr->Width = (strlen(mptr->MenuName)+2) * 8;
  101.         left += maxw;
  102.         top = 0;
  103.         /* determine max width */
  104.         for( iptr = mptr->FirstItem ; iptr ; iptr=iptr->NextItem ) {
  105.             iptr->TopEdge = top;
  106.             top += iptr->Height;
  107.             txtw = IntuiTextLength((struct IntuiText *)iptr->ItemFill)+2;
  108.             if( iptr->Flags & COMMSEQ ) txtw += 48;
  109.             if( txtw > maxw ) maxw = txtw;
  110.         }
  111.         for( iptr = mptr->FirstItem ; iptr ; iptr=iptr->NextItem ) {
  112.             iptr->Width = maxw;
  113.             stop = smaxw = 0;
  114.             for( sptr=iptr->SubItem ; sptr ; sptr=sptr->NextItem ) {
  115.                 sptr->LeftEdge = maxw;
  116.                 sptr->TopEdge = stop;
  117.                 stop += sptr->Height;
  118.                 txtw = IntuiTextLength((struct IntuiText *)sptr->ItemFill)+2;
  119.                 if( sptr->Flags & COMMSEQ ) txtw += 48;
  120.                 if( txtw > smaxw ) smaxw = txtw;
  121.             }
  122.             for( sptr=iptr->SubItem ; sptr ; sptr=sptr->NextItem )
  123.                 sptr->Width = smaxw;
  124.         }
  125.     }
  126. }
  127.  
  128.  
  129. /*****  make (and Mallocate) a copy of the passed string *****/
  130.  
  131. static char *MallocStr(char *str)
  132. {
  133.     char *newstr;
  134.     newstr = Malloc(strlen(str)+1);
  135.     strcpy(newstr, str);
  136.     return newstr;
  137. }
  138.  
  139.  
  140. /* allocate and initialize a new MenuItem */
  141.  
  142. struct Extended_MenuItem *AllocItem(char *itemstr)
  143. {
  144.     struct IntuiText *IT;
  145.     struct Extended_MenuItem *emi;
  146.  
  147.     emi = Malloc(sizeof(struct Extended_MenuItem));
  148.     IT = Malloc(sizeof(struct IntuiText));
  149.     emi->emi_MenuItem.Height = 10;
  150.     emi->emi_MenuItem.Flags = ITEMTEXT+HIGHCOMP+ITEMENABLED;
  151.     IT->FrontPen = menu_pen;
  152.     IT->LeftEdge = IT->TopEdge = 1;
  153.     IT->DrawMode = JAM1;
  154.     IT->IText = (UBYTE *)MallocStr(itemstr);
  155.     emi->emi_MenuItem.ItemFill = (APTR)IT;
  156.     return emi;
  157. }
  158.  
  159.  
  160. /* allocate and initialize a new Menu */
  161.  
  162. void AddMenu(char *str)
  163. {
  164.     struct Menu *Menu;
  165.  
  166.     Menu = Malloc(sizeof(struct Menu));
  167.     Menu->MenuName = MallocStr(str);
  168.     Menu->Flags = MENUENABLED;
  169.     CurrentMenu->NextMenu = Menu;
  170.     CurrentMenu = Menu;
  171.     CurrentItem = &Menu->FirstItem;
  172. }
  173.  
  174.  
  175. void AddSubMenu(char *substr)
  176. {
  177.     *CurrentItem = (struct MenuItem *)AllocItem(substr);
  178.     CurrentSubMenu = *CurrentItem;
  179.     CurrentItem = &CurrentSubMenu->SubItem;
  180. }
  181.  
  182.  
  183. void EndSubMenu(void)
  184. {
  185.     CurrentItem = &CurrentSubMenu->NextItem;
  186. }
  187.  
  188.  
  189. void AddEntry(    char *item,
  190.                 char *cmd,
  191.                 char *args,
  192.                 char *win,
  193.                 char shortcut,
  194.                 char mode,
  195.                 long stk,
  196.                 short pri )
  197. {
  198.     struct Extended_MenuItem *emi;
  199.  
  200.     emi = AllocItem(item);
  201.     emi->emi_Mode = mode;
  202.     emi->emi_Cmd = MallocStr(cmd);
  203.     if (args) emi->emi_Args = MallocStr(args);
  204.     if (shortcut) {
  205.         emi->emi_MenuItem.Flags |= COMMSEQ;
  206.         emi->emi_MenuItem.Command = shortcut;
  207.     }
  208.     if (win)
  209.         emi->emi_Window = MallocStr(win);
  210.     emi->emi_Pri = pri;
  211.     emi->emi_Stack = stk;
  212.     *CurrentItem = (struct MenuItem *)emi;
  213.     CurrentItem = &emi->emi_MenuItem.NextItem;
  214. }
  215.  
  216.  
  217. /* free up all space taken up by our menus */
  218.  
  219. void FreeMenus( void )
  220. {
  221.     struct MemBlock *mb;
  222.  
  223.     while( mb = (struct MemBlock *)RemTail((struct List *)&MemList) )
  224.         FreeMem(mb, sizeof(struct MemBlock));
  225.     CurrentMenu = &Menu1;
  226.     Menu1.NextMenu = NULL;
  227.     Avail = 0;
  228. }
  229.  
  230.