home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / fm2000 / screen.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-04  |  31.7 KB  |  1,132 lines

  1. /*
  2.      Filemaster - Multitasking directory utility.
  3.      Copyright (C) 2000  Toni Wilen
  4.      
  5.      This program is free software; you can redistribute it and/or
  6.      modify it under the terms of the GNU General Public License
  7.      as published by the Free Software Foundation; either version 2
  8.      of the License, or (at your option) any later version.
  9.      
  10.      This program is distributed in the hope that it will be useful,
  11.      but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.      GNU General Public License for more details.
  14.      
  15.      You should have received a copy of the GNU General Public License
  16.      along with this program; if not, write to the Free Software
  17.      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19.  
  20.  
  21. #include <proto/all.h>
  22. #include <exec/types.h>
  23. #include <exec/execbase.h>
  24. #include <exec/memory.h>
  25. #include <intuition/intuition.h>
  26. #include <intuition/sghooks.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include "fmnode.h"
  30. #include "fmlocale.h"
  31. #include "child.h"
  32. #include "fmdos.h"
  33.  
  34. WORD avaanaytto(WORD);
  35. WORD suljenaytto(WORD);
  36. void teeruutu(WORD,WORD);
  37. void draw3dbox(struct RastPort*,WORD,WORD,WORD,WORD,WORD);
  38. struct TextFont* openfont(struct TextAttr*);
  39. WORD windownewsize(void);
  40. void setcmenu(void);
  41. void docmenusize(void);
  42. void textextent(struct RastPort*,UBYTE*,WORD*,WORD*);
  43. ULONG power2(WORD);
  44. void freegadgets(struct Gadget*);
  45. void drives(struct FMList*);
  46. void updatetasknumbers(struct ListInfo*);
  47.  
  48. struct ListInfo *alloclistgads(WORD,WORD,WORD,WORD,WORD,WORD,WORD,WORD);
  49. void addlistgads(void);
  50. void freelistgads(void);
  51. void doborder(WORD*,struct Border*,struct Border*,WORD*,struct Border*,struct Border*,WORD,WORD);
  52. WORD avaanayttoa(UBYTE*,WORD);
  53. void gadgettables(void);
  54. void executeownnum(void);
  55.  
  56. WORD errorreq(WORD,UBYTE*,WORD,WORD);
  57.  
  58. extern struct FMConfig *fmconfig;
  59. extern struct FMMain fmmain;
  60. extern struct FMList fmlist[];
  61. extern struct ExecBase *SysBase;
  62. extern UBYTE dflib[];
  63. extern UBYTE topaz[];
  64. extern UBYTE workbench[];
  65.  
  66. WORD avaanaytto(WORD flag)
  67. {
  68. UBYTE emsg[100];
  69.  
  70. if(flag==2) return(avaanayttoa(emsg,2));
  71. if(avaanayttoa(emsg,flag)) return(1);
  72. strcpy(fmconfig->listfontname,topaz);
  73. fmconfig->listfontattr.ta_YSize=8;
  74. strcpy(fmconfig->txtfontname,topaz);
  75. fmconfig->txtfontattr.ta_YSize=8;
  76. strcpy(fmconfig->reqfontname,topaz);
  77. fmconfig->reqfontattr.ta_YSize=8;
  78. fmconfig->txtfontattr.ta_Name=fmconfig->txtfontname;
  79. fmconfig->listfontattr.ta_Name=fmconfig->listfontname;
  80. fmconfig->reqfontattr.ta_Name=fmconfig->reqfontname;
  81. if(avaanayttoa(emsg,flag)) return(1);
  82. fmconfig->mainscreen.width=640;
  83. fmconfig->mainscreen.height=256;
  84. fmconfig->mainscreen.depth=2;
  85. fmconfig->mainscreen.autoscroll=0;
  86. fmconfig->mainscreen.overscan=1;
  87. fmconfig->screentype=0;
  88. if(avaanayttoa(emsg,flag)) return(1);
  89. errorreq(MSG_REQ_FATALERR,emsg,0,MSG_OK);
  90. return(0);
  91. }
  92.  
  93. WORD avaanayttoa(UBYTE *emsg,WORD flag)
  94. {
  95. WORD apu1,apu2;
  96. UBYTE *ptr1,*ptr2;
  97. WORD penlist[2];
  98. ULONG coltable[COLORS*3+8];
  99. struct DrawInfo *di;
  100. struct Screen *vscr;
  101. WORD ret=1;
  102.  
  103. #define WFLAGS WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_SMART_REFRESH
  104.  
  105. struct NewWindow uusiikkuna  =
  106.     {
  107.     0,0,0,0,0,2,
  108.     IDCMP_MOUSEMOVE|IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_GADGETUP|IDCMP_GADGETDOWN|IDCMP_MOUSEMOVE|IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|IDCMP_DISKINSERTED|IDCMP_DISKREMOVED|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW,
  109.     0,
  110.     0,0,0,0,0,0,0,0xffff,0xffff,0
  111.     };
  112.  
  113.  
  114. if(flag==3) {
  115.     penlist[0]=-1; penlist[1]=-1;
  116.     if(!(fmmain.normalfont=openfont(&fmmain.tattr))) goto anaytto1;
  117.     if(!(fmmain.smallfont=openfont(&fmconfig->smallfontattr))) goto anaytto1;
  118.     if(!(fmmain.txtfont=openfont(&fmconfig->txtfontattr))) goto anaytto1;
  119.     if(!(fmmain.listfont=openfont(&fmconfig->listfontattr))) goto anaytto1;
  120.     if(!(fmmain.reqfont=openfont(&fmconfig->reqfontattr))) goto anaytto1;
  121.     if(!(fmmain.txtshowfont=openfont(&fmconfig->txtshowfontattr))) goto anaytto1;
  122.     fmmain.txtysize=fmmain.txtfont->tf_YSize;
  123.     fmmain.txtxsize=fmmain.txtfont->tf_XSize;
  124.     fmmain.txtbaseline=fmmain.txtfont->tf_Baseline;
  125.     fmmain.listysize=fmmain.listfont->tf_YSize;
  126.     fmmain.listxsize=fmmain.listfont->tf_XSize;
  127.     fmmain.listbaseline=fmmain.listfont->tf_Baseline;
  128.     fmmain.reqysize=fmmain.reqfont->tf_YSize;
  129.     fmmain.reqxsize=fmmain.reqfont->tf_XSize;
  130.     fmmain.reqbaseline=fmmain.reqfont->tf_Baseline;
  131.     fmmain.txtshowysize=fmmain.txtshowfont->tf_YSize;
  132.     fmmain.txtshowxsize=fmmain.txtshowfont->tf_XSize;
  133.     fmmain.txtshowbaseline=fmmain.txtshowfont->tf_Baseline;
  134. }
  135.  
  136. scrretry:
  137.  
  138. fmmain.myproc = (struct Process*)FindTask(0);
  139.  
  140. if (flag==3) {
  141.     if (fmconfig->screentype<=1) {
  142.         if (!(fmmain.naytto = (struct Screen *)OpenScreenTags(0,
  143.         SA_Width,fmconfig->mainscreen.width,
  144.         SA_Height,fmconfig->mainscreen.height,
  145.         SA_Type,CUSTOMSCREEN,
  146.         SA_Title,fmmain.fmtitlename,
  147.         SA_Font,&fmconfig->txtfontattr,
  148.         SA_Pens,penlist,
  149.         SA_DisplayID,fmconfig->mainscreen.screenmode,
  150.         SA_Overscan,fmconfig->mainscreen.overscan,
  151.         SA_AutoScroll,fmconfig->mainscreen.autoscroll,
  152.         SA_Depth,fmconfig->mainscreen.depth,
  153.         SA_Interleaved,TRUE,
  154.         SA_PubName,fmconfig->screentype==1?"FM":0,
  155.         TAG_DONE))) {
  156.             strcpymsg(emsg,MSG_MAIN_SCRERR1);
  157.             fmconfig->mainscreen.width=640;
  158.             fmconfig->mainscreen.height=256;
  159.             fmconfig->mainscreen.screenmode=HIRES_KEY;
  160.             fmconfig->mainscreen.overscan=1;
  161.             fmconfig->mainscreen.autoscroll=0;
  162.             fmconfig->mainscreen.depth=2;
  163.             ret=0;
  164.             goto anaytto1;
  165.         } else {
  166.             ShowTitle(fmmain.naytto,FALSE);
  167.             apu1=power2(fmconfig->mainscreen.depth);
  168.             ptr2=fmconfig->colors;
  169.             ptr1=(UBYTE*)coltable;
  170. #ifdef V39
  171.             *ptr1++=0;*ptr1++=apu1;*ptr1++=0;*ptr1++=0;
  172.             for(apu2=0;apu2<apu1;apu2++) {
  173.                 *ptr1++=*ptr2;
  174.                 *ptr1++=*ptr2;
  175.                 *ptr1++=*ptr2;
  176.                 *ptr1++=*ptr2;
  177.                 ptr2++;
  178.                 *ptr1++=*ptr2;
  179.                 *ptr1++=*ptr2;
  180.                 *ptr1++=*ptr2;
  181.                 *ptr1++=*ptr2;
  182.                 ptr2++;
  183.                 *ptr1++=*ptr2;
  184.                 *ptr1++=*ptr2;
  185.                 *ptr1++=*ptr2;
  186.                 *ptr1++=*ptr2;
  187.                 ptr2++;
  188.             }
  189.             *ptr1++=0;*ptr1++=0;*ptr1++=0;*ptr1=0;
  190.             LoadRGB32(&fmmain.naytto->ViewPort,coltable);
  191. #else
  192.             for(apu2=0;apu2<apu1;apu2++) {
  193.                 *ptr1=(*ptr2++)>>4;
  194.                 ptr1++;
  195.                 *ptr1=(*ptr2++)&0xf0;
  196.                 *ptr1|=((*ptr2++)&0xf0)>>4;
  197.                 ptr1++;
  198.             }
  199.             LoadRGB4(&fmmain.naytto->ViewPort,(UWORD*)coltable,apu1);
  200. #endif
  201.         }
  202.     } else {
  203.         fmmain.naytto=LockPubScreen(fmconfig->pubscreen);
  204.         if(!fmmain.naytto) {
  205.             strcpy(fmconfig->pubscreen,workbench);
  206.             fmmain.naytto=LockPubScreen(fmconfig->pubscreen);
  207.             if(!fmmain.naytto) {
  208.                 strcpymsg(emsg,MSG_SCR_SCRERR2);
  209.                 ret=0;
  210.                 goto anaytto1;
  211.             }
  212.         }
  213.         fmconfig->mainscreen.depth=fmmain.naytto->RastPort.BitMap->Depth<=4?fmmain.naytto->RastPort.BitMap->Depth:4;
  214.     }
  215.     if (fmmain.naytto->Width/2>fmmain.naytto->Height) {
  216.         fmconfig->flags|=MDOUBLED;
  217.         fmconfig->spacew=2*fmconfig->spaceh;
  218.         fmconfig->sliderw=2*fmconfig->sliderh;
  219.     } else {
  220.         fmconfig->flags&=~MDOUBLED;
  221.         fmconfig->spacew=fmconfig->spaceh;
  222.         fmconfig->sliderw=fmconfig->sliderh;
  223.     }
  224.     if (!(fmmain.gtvisual=GetVisualInfo(fmmain.naytto,0))) {
  225.         strcpymsg(emsg,MSG_MAIN_SCRERR1);
  226.         ret=0;
  227.         goto anaytto1;
  228.     }
  229.     if (di=GetScreenDrawInfo(fmmain.naytto)) {
  230.         fmconfig->whitepen=di->dri_Pens[SHINEPEN];
  231.         fmconfig->blackpen=di->dri_Pens[SHADOWPEN];
  232.         FreeScreenDrawInfo(fmmain.naytto,di);
  233. }
  234. }
  235.  
  236. if (fmconfig->screentype<=1) uusiikkuna.Type=CUSTOMSCREEN;
  237. if (fmconfig->screentype==2) uusiikkuna.Type=PUBLICSCREEN;
  238. if (fmconfig->flags&MWINDOWED) {
  239.     uusiikkuna.Flags=WFLAGS|WFLG_SIZEGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_SIZEBBOTTOM|WFLG_GIMMEZEROZERO;
  240.     uusiikkuna.Title=fmmain.fmtitlename;
  241.     uusiikkuna.TopEdge=fmconfig->windowtop;
  242.     uusiikkuna.LeftEdge=fmconfig->windowleft;
  243.     uusiikkuna.Height=fmconfig->windowheight;
  244.     uusiikkuna.Width=fmconfig->windowwidth;
  245. } else {
  246.     uusiikkuna.Flags=WFLAGS|WFLG_BACKDROP|WFLG_BORDERLESS;
  247.     uusiikkuna.Title=0;
  248.     uusiikkuna.TopEdge=fmmain.naytto->WBorTop+fmmain.txtysize+1;
  249.     uusiikkuna.Height=fmconfig->mainscreen.height-uusiikkuna.TopEdge;
  250.     uusiikkuna.Width=fmconfig->mainscreen.width;
  251. }
  252.  
  253. uusiikkuna.Screen = fmmain.naytto;
  254. uusiikkuna.BlockPen = fmconfig->sliderpen;
  255. uusiikkuna.DetailPen = fmconfig->backpen;
  256. if (!(fmmain.ikkuna = (struct Window *)OpenWindowTags(&uusiikkuna,WA_AutoAdjust,TRUE,TAG_DONE))) {
  257.     strcpymsg(emsg,MSG_MAIN_WINERR1);
  258.     ret=0;
  259.     fmconfig->windowtop=0;
  260.     fmconfig->windowleft=0;
  261.     fmconfig->windowheight=fmconfig->mainscreen.height;
  262.     fmconfig->windowwidth=fmconfig->mainscreen.width;
  263.     goto anaytto1;
  264. }
  265. fmmain.oldwinptr = fmmain.myproc->pr_WindowPtr;
  266. fmmain.myproc->pr_WindowPtr = fmmain.ikkuna;
  267. fmmain.rp=fmmain.ikkuna->RPort;
  268. SetFont(fmmain.rp,fmmain.txtfont);
  269. ReportMouse(0,fmmain.ikkuna);
  270.  
  271. if (!windownewsize()) {
  272.     strcpymsg(emsg,MSG_SCR_MEMERR);
  273.     ret=0;
  274.     goto anaytto1;
  275. }
  276.  
  277. vscr=LockPubScreen(workbench);
  278. if(vscr==fmmain.naytto) {
  279.     fmmain.appwinport=CreateMsgPort();
  280.     if(fmmain.appwinport) fmmain.appwin=AddAppWindow(0,0,fmmain.ikkuna,fmmain.appwinport,0);
  281.  
  282. }
  283. if(vscr) UnlockPubScreen(0,vscr);
  284.  
  285. anaytto1:
  286. if (!fmmain.naytto || !fmmain.ikkuna || !fmmain.txtfont || !fmmain.listfont || !ret) { 
  287.     suljenaytto(flag);
  288.     return(ret);
  289. }
  290. if(fmmain.naytto&&fmconfig->screentype==1) PubScreenStatus(fmmain.naytto,0);
  291. return(1);
  292. }
  293.  
  294. WORD suljenaytto(WORD flag)
  295. {
  296. struct AppMessage *appmsg;
  297.  
  298. if(flag==3) {
  299.     for(;;) {
  300.         if(fmmain.naytto&&fmconfig->screentype<=1&&fmmain.naytto->FirstWindow&&fmmain.naytto->FirstWindow->NextWindow) {
  301.             if (!requestmsg(getstring(MSG_MAIN_WARNING),MSG_RETRY,MSG_CANCEL,MSG_MAIN_WINDOWS)) return(0);
  302.         } else {
  303.             break;
  304.         }
  305.     }
  306.     if(fmmain.naytto&&fmconfig->screentype==1) {
  307.         for(;;) {
  308.             if (!((PubScreenStatus(fmmain.naytto,PSNF_PRIVATE))&1)) {
  309.                 if (!requestmsg(getstring(MSG_MAIN_WARNING),MSG_RETRY,MSG_CANCEL,MSG_MAIN_VISITORWINDOWS)) return(0);
  310.             } else {
  311.                 break;
  312.             }
  313.         }
  314.     }
  315.     ObtainSemaphore(&fmmain.gfxsema);
  316.     if (fmmain.txtfont) { CloseFont(fmmain.txtfont); fmmain.txtfont=0; }
  317.     if (fmmain.listfont) { CloseFont(fmmain.listfont); fmmain.listfont=0; }
  318.     if (fmmain.reqfont) { CloseFont(fmmain.reqfont); fmmain.reqfont=0; }
  319.     if (fmmain.txtshowfont) { CloseFont(fmmain.txtshowfont); fmmain.txtshowfont=0; }
  320.     if (fmmain.normalfont) { CloseFont(fmmain.normalfont); fmmain.normalfont=0; }
  321.     if (fmmain.smallfont) { CloseFont(fmmain.smallfont); fmmain.smallfont=0; }
  322.     freegadgets(fmmain.firstgadget); fmmain.firstgadget=0;
  323.     freelistgads();
  324.     if (fmmain.appwin) { RemoveAppWindow(fmmain.appwin); fmmain.appwin=0; }
  325.     if (fmmain.appwinport) {
  326.             while(appmsg=(struct AppMessage *)GetMsg(fmmain.appwinport)) ReplyMsg((struct Message*)appmsg);
  327.         DeleteMsgPort(fmmain.appwinport); fmmain.appwinport=0;
  328.     }
  329. }
  330.  
  331. ObtainSemaphore(&fmmain.gfxsema);
  332. if (fmmain.ikkuna) {
  333.     fmconfig->windowtop=fmmain.ikkuna->TopEdge;
  334.     fmconfig->windowleft=fmmain.ikkuna->LeftEdge;
  335.     fmconfig->windowheight=fmmain.ikkuna->Height;
  336.     fmconfig->windowwidth=fmmain.ikkuna->Width;
  337.     fmmain.myproc->pr_WindowPtr=fmmain.oldwinptr;
  338.     CloseWindow(fmmain.ikkuna);
  339.     fmmain.ikkuna=0;
  340. }
  341. ReleaseSemaphore(&fmmain.gfxsema);
  342.  
  343. if(flag==3) {
  344.     if (fmmain.gtvisual) { FreeVisualInfo(fmmain.gtvisual); fmmain.gtvisual=0; }
  345.     if (fmmain.naytto) {
  346.         if (fmconfig->screentype<=1) {
  347.             CloseScreen(fmmain.naytto);
  348.         } else {
  349.             UnlockPubScreen(0,fmmain.naytto);
  350.         }
  351.         fmmain.naytto=0;
  352.     }
  353.     ReleaseSemaphore(&fmmain.gfxsema);
  354. }
  355. return(1);
  356. }
  357.  
  358. WORD windownewsize(void)
  359. {
  360. WORD height,width,apu1;
  361. struct FMList *list;
  362.  
  363. ObtainSemaphore(&fmmain.gfxsema);
  364. freelistgads();
  365. freegadgets(fmmain.firstgadget); fmmain.firstgadget=0;
  366. SetAPen(fmmain.rp,fmconfig->backpen);
  367. RectFill(fmmain.rp,fmmain.ikkuna->BorderLeft,fmmain.ikkuna->BorderTop,fmmain.ikkuna->Width+fmmain.ikkuna->BorderLeft,fmmain.ikkuna->Height+fmmain.ikkuna->BorderTop);
  368. height=fmmain.ikkuna->Height-fmmain.ikkuna->BorderTop-fmmain.ikkuna->BorderBottom;
  369. width=fmmain.ikkuna->Width-fmmain.ikkuna->BorderLeft-fmmain.ikkuna->BorderRight;
  370. docmenusize();
  371. teeruutu(width,height);
  372. addlistgads();
  373. ReleaseSemaphore(&fmmain.gfxsema);
  374. setcmenu();
  375. for(apu1=0;apu1<WINDOWLISTS;apu1++) {
  376.     if(fmmain.li[apu1]) {
  377.         list=fmmain.li[apu1]->list;
  378.         if(list->flags==0)
  379.             drives(list);
  380.             else
  381.             outputlist(list);
  382.         if(list->flags&LALLOCATED) offgadget(&fmmain.li[apu1]->slider1,LISTGADGETS);
  383.     }
  384.     fmmain.uselist[apu1]=0;
  385. }
  386. dirmeters();
  387. fmmessage(fmmain.sourcedir);
  388. RefreshGList(fmmain.ikkuna->FirstGadget,fmmain.ikkuna,0,-1);
  389. updatetasknumbers(0);
  390. fmconfig->windowtop=fmmain.ikkuna->TopEdge;
  391. fmconfig->windowleft=fmmain.ikkuna->LeftEdge;
  392. fmconfig->windowheight=fmmain.ikkuna->Height;
  393. fmconfig->windowwidth=fmmain.ikkuna->Width;
  394. return(1);
  395. }
  396.  
  397. void freegadgets(struct Gadget *g)
  398. {
  399. struct Gadget *gg;
  400.  
  401. if(g) {
  402.     RemoveGList(fmmain.ikkuna,g,-1);
  403.     while(g) {
  404.         gg=g;
  405.         g=g->NextGadget;
  406.         freemem(gg);
  407.     }
  408. }
  409. }
  410.  
  411. void teeruutu(WORD width,WORD height)
  412. {
  413. WORD tfh,sw,sh;
  414. WORD apu1,apu2,apu3,apu4,apu5,apu6,apu7,apu8,apu9,apu10,ly,sy;
  415. WORD colums,colweight;
  416. WORD rows[COLS+1],rowweight[COLS+1];
  417. WORD newcols[COLS+1];
  418. WORD maxrows;
  419. WORD listwidth,listheight;
  420. WORD minwidth,minheight,widthi;
  421. WORD *xy;
  422.  
  423. sh=fmconfig->sliderh+2; sw=fmconfig->sliderw+2;
  424. tfh=fmmain.txtysize+1;
  425.  
  426. if(!fmconfig->cmenutype) {
  427.     fmmain.realcmenuspace=fmmain.cmenuwidth*fmconfig->cmenucolumns;
  428. } else {
  429.     fmmain.realcmenuspace=fmconfig->cmenucolumns*(tfh+1);
  430. }
  431.  
  432. textextent(fmmain.rp,"0",&apu1,&apu2);
  433. textextent(fmmain.rp,">",&apu3,&apu2);
  434. if(apu1<apu3) apu1=apu3;
  435. textextent(fmmain.rp,"<",&apu3,&apu2);
  436. if(apu1<apu3) apu1=apu3;
  437. widthi=apu1+2*fmconfig->spaceh+1;
  438.  
  439. listwidth=width-fmconfig->spacew;
  440. listheight=height-2*fmconfig->spaceh-3*tfh-fmconfig->spacew/3;
  441. if(fmconfig->cmenutype&&fmconfig->cmenuposition>0) listheight--;
  442.  
  443. if(!fmconfig->cmenutype)
  444.     listwidth-=fmmain.realcmenuspace;
  445.     else
  446.     listheight-=fmmain.realcmenuspace;
  447. apu1=0; colweight=0; maxrows=0;
  448. while(fmconfig->listinfo[apu1][0]) {
  449.     colweight+=(WORD)(fmconfig->listinfo[apu1][0]&0x7f);
  450.     apu2=1; rowweight[apu1]=0;
  451.     while(fmconfig->listinfo[apu1][apu2]&0x7f) {
  452.         rowweight[apu1]+=(WORD)(fmconfig->listinfo[apu1][apu2]&0x7f);
  453.         apu2++;
  454.     }
  455.     if(apu2>maxrows) maxrows=apu2;
  456.     rows[apu1]=apu2-1;
  457.     apu1++;
  458. }
  459. colums=apu1;
  460. maxrows--;
  461.  
  462. apu3=0;apu5=sw+2*fmconfig->spacew+fmconfig->spacew/3;
  463. for(apu1=0;apu1<colums;apu1++) {
  464.     apu2=((LONG)listwidth*(LONG)(fmconfig->listinfo[apu1][0]&0x7f))/colweight;
  465.     apu2-=apu5;
  466.     apu2=(apu2/fmmain.listxsize)*fmmain.listxsize;
  467.     apu2+=apu5;
  468.     apu3+=apu2;
  469.     newcols[apu1]=apu2;
  470. }
  471. sy=0;
  472. if(!fmconfig->cmenutype) {
  473.     fmmain.realcmenuspace=width-apu3-fmconfig->spacew-fmconfig->spacew/3;
  474.     fmmain.cmenuwidth=(fmmain.realcmenuspace)/fmconfig->cmenucolumns;
  475.     apu1=height-4*fmconfig->spaceh-3*tfh;
  476.     fmmain.cmenuy=fmconfig->spaceh;
  477.     fmmain.totalcmenuwidth=fmmain.realcmenuspace;
  478.     fmmain.cmenugadnumperline=(apu1/(tfh+1));
  479.     fmmain.totalcmenuheight=fmmain.cmenugadnumperline*(tfh+1);
  480. } else {
  481.     fmmain.cmenugadnumperline=width/fmmain.cmenuwidth;
  482.     fmmain.cmenux=0;
  483.     fmmain.totalcmenuwidth=width;
  484.     fmmain.totalcmenuheight=fmmain.realcmenuspace;
  485.     if(fmconfig->cmenutype&&!fmconfig->cmenuposition) {
  486.         sy=fmmain.realcmenuspace;
  487.         fmmain.cmenuy=0;
  488.     }
  489. }
  490.  
  491. if (fmconfig->flags&MDOUBLED) {
  492.     draw3dbox(fmmain.rp,2,sy+1,width-2*2,height-2*1-sy,1);
  493.     SetAPen(fmmain.rp,fmconfig->mainbackfillpen);
  494.     RectFill(fmmain.rp,2,sy+1,width-2*2+1,height-2*1);
  495. } else {
  496.     draw3dbox(fmmain.rp,1,sy+1,width-2*1,height-2*1-sy,1);
  497.     SetAPen(fmmain.rp,fmconfig->mainbackfillpen);
  498.     RectFill(fmmain.rp,1,sy+1,width-2*1,height-2*1);
  499. }
  500.  
  501. apu3=0; apu4=0;
  502. apu8=fmconfig->cmenuposition;
  503. minwidth=3*fmconfig->spacew+sw+3*fmmain.listxsize;
  504. if(minwidth<(4*widthi+32)) minwidth=4*widthi+32;
  505. minheight=5*fmconfig->spaceh+2*tfh+sh+3*fmmain.listysize;
  506. ly=0;
  507. for(apu1=0;apu1<colums;apu1++) {
  508.     if(!apu8&&!fmconfig->cmenutype) {
  509.         apu4+=(fmconfig->spacew/3*2);
  510.         fmmain.cmenux=apu4;
  511.         apu4+=fmmain.realcmenuspace;
  512.         apu4-=(fmconfig->spacew/3);
  513.     }
  514.     apu8--;
  515.     apu5=sy;
  516.     apu6=newcols[apu1];
  517.     if(apu6<minwidth) apu6=minwidth;
  518.     apu10=0;
  519.     for(apu2=0;apu2<rows[apu1];apu2++) {
  520.         apu7=((LONG)listheight*(LONG)(fmconfig->listinfo[apu1][apu2+1]&0x7f))/rowweight[apu1];
  521.         if(apu7<minheight) apu7=minheight;
  522.         if(fmmain.uselist[apu3]>0) {
  523.             apu9=fmmain.uselist[apu3]-1;
  524.         } else {
  525.             for(apu9=0;apu9<WINDOWLISTS;apu9++) {
  526.                 if(!fmlist[apu9].li) break;
  527.             }
  528.         }
  529.         fmmain.li[apu3]=alloclistgads(apu4,apu5,apu6,apu7,fmconfig->listinfo[apu1][apu2+1]&0x80,apu9,apu3,widthi);
  530.         if(fmmain.li[apu3]) apu10+=fmmain.li[apu3]->height;
  531.         apu5+=apu7;
  532.         apu3++;
  533.  
  534.     }
  535.     if(apu10>ly) ly=apu10;
  536.     apu4+=apu6;
  537. }
  538. ly+=fmconfig->spaceh+sy;
  539.  
  540. if(!fmconfig->cmenutype&&apu8>=0) fmmain.cmenux=apu4+fmmain.ikkuna->BorderLeft+fmconfig->spacew/3*2;
  541.  
  542. if(!fmconfig->cmenutype)
  543.     WindowLimits(fmmain.ikkuna,colums*(minwidth+2*fmconfig->spacew)+fmmain.realcmenuspace+fmmain.naytto->WBorLeft+fmmain.naytto->WBorRight,maxrows*minheight+3*fmconfig->spaceh+5*tfh+fmmain.naytto->WBorTop+fmmain.naytto->WBorBottom,-1,-1);
  544.     else
  545.     WindowLimits(fmmain.ikkuna,colums*(minwidth+2*fmconfig->spacew)+fmmain.naytto->WBorLeft+fmmain.naytto->WBorRight,maxrows*minheight+fmmain.realcmenuspace+3*fmconfig->spaceh+5*tfh+fmmain.naytto->WBorTop+fmmain.naytto->WBorBottom,-1,-1);
  546.  
  547. if(fmconfig->cmenutype&&fmconfig->cmenuposition==1) {
  548.     fmmain.cmenuy=ly-2;
  549.     ly+=fmmain.realcmenuspace+1;
  550. }
  551. fmmain.messageliney1=ly;
  552. fmmain.messageliney2=fmmain.messageliney1+tfh;
  553. ly+=2*tfh;
  554.  
  555. if(fmconfig->cmenutype&&fmconfig->cmenuposition==2) {
  556.     ly++;
  557.     fmmain.cmenuy=ly;
  558.     ly+=fmmain.realcmenuspace;
  559. }
  560.  
  561. fmmain.bottomliney=ly+fmconfig->spaceh;
  562. ly+=tfh+fmconfig->spaceh;
  563.  
  564. if(fmconfig->cmenutype&&fmconfig->cmenuposition==3) {
  565.     ly++;
  566.     fmmain.cmenuy=ly;
  567. }
  568.  
  569. draw3dbox(fmmain.rp,fmconfig->spacew,fmmain.messageliney1-1,width-2*fmconfig->spacew,2*tfh,0);
  570.  
  571. xy=fmmain.gadgetxy;apu5=0;
  572. if(!fmconfig->cmenutype) {
  573.     apu1=fmmain.cmenux+(fmmain.realcmenuspace-fmmain.cmenuwidth*fmconfig->cmenucolumns)/2;
  574.     for(apu4=0;apu4<fmconfig->cmenucolumns;apu4++) {
  575.         apu2=fmmain.cmenuy;
  576.         for(apu3=0;apu3<fmmain.cmenugadnumperline;apu3++) {
  577.             *xy++=apu1+1;*xy++=apu2;
  578.             *xy++=fmmain.cmenuwidth-1;*xy++=tfh+1;
  579.             apu2+=tfh+1;
  580.             apu5++;
  581.             if(apu5>=TOTALCOMMANDS) break;
  582.         }
  583.         if(apu5>=TOTALCOMMANDS) break;
  584.         apu1+=fmmain.cmenuwidth;
  585.     }
  586. } else {
  587.     apu6=(fmmain.totalcmenuwidth<<4)/fmmain.cmenugadnumperline;
  588.     apu2=fmmain.cmenuy;
  589.     for(apu3=0;apu3<fmconfig->cmenucolumns;apu3++) {
  590.         apu1=fmmain.cmenux<<4;
  591.         for(apu4=0;apu4<fmmain.cmenugadnumperline;apu4++) {
  592.             xy[0]=apu1>>4;xy[1]=apu2;
  593.             xy[2]=((apu1+apu6)>>4)-xy[0];xy[3]=tfh+1;
  594.             xy+=4;
  595.             apu1+=apu6;
  596.             apu5++;
  597.             if(apu5>=TOTALCOMMANDS) break;
  598.         }
  599.         if(apu5>=TOTALCOMMANDS) break;
  600.         apu2+=tfh+1;
  601.     }
  602. }
  603. *xy=-1;
  604.  
  605. apu4=0;
  606. for(apu3=0;apu3<TOTALCOMMANDS;apu3++) {
  607.     if(fmconfig->cmenuconfig[apu3].position==2) {
  608.         textextent(fmmain.rp,fmconfig->cmenuconfig[apu3].label,&apu1,&apu2);
  609.         apu4+=(apu1+2*fmconfig->spaceh);
  610.     }
  611. }
  612. fmmain.bottomlinewidth=width-apu4-fmconfig->spacew-2*fmconfig->spacew/3*2;
  613. draw3dbox(fmmain.rp,fmconfig->spacew,fmmain.bottomliney-1,fmmain.bottomlinewidth,fmmain.txtfont->tf_YSize+1,0);
  614. fmmain.bottomlinewidth-=2*fmconfig->spacew;
  615. if(fmmain.bottomlinewidth<0) fmmain.bottomlinewidth=0;
  616. }
  617.  
  618. void addlistgads(void)
  619. {
  620. WORD cnt;
  621.  
  622. for(cnt=0;cnt<WINDOWLISTS;cnt++) {
  623.     if(fmmain.li[cnt]) {
  624.         AddGList(fmmain.ikkuna,&fmmain.li[cnt]->slider1,-1,LISTGADGETS+3,0);
  625.     }
  626. }
  627. }
  628.  
  629. void freelistgads(void)
  630. {
  631. WORD cnt,cnt2;
  632.  
  633. cnt2=0;
  634. for(cnt=0;cnt<WINDOWLISTS;cnt++) {
  635.     fmlist[cnt].li=0;
  636.     if(fmmain.li[cnt]) {
  637.         RemoveGList(fmmain.ikkuna,&fmmain.li[cnt]->slider1,LISTGADGETS+3);
  638.         fmmain.uselist[cnt2++]=fmmain.li[cnt]->list->listnumber+1;
  639.         freemem(fmmain.li[cnt]->im1.ImageData);
  640.         freemem(fmmain.li[cnt]->im2.ImageData);
  641.         freemem(fmmain.li[cnt]->sim1.ImageData);
  642.         freemem(fmmain.li[cnt]->sim2.ImageData);
  643.         freemem(fmmain.li[cnt]);
  644.         fmmain.li[cnt]=0;
  645.     }
  646. }
  647. if(cnt2) while(cnt2!=WINDOWLISTS) fmmain.uselist[cnt2++]=0;
  648. }
  649.  
  650. extern void drawall(struct ReqScrollStruct*);
  651. extern void scrollndraw(LONG,LONG,LONG,LONG,struct ReqScrollStruct*);
  652.  
  653. struct ListInfo *alloclistgads(WORD x,WORD y,WORD width,WORD height,WORD mirror,WORD listnum,WORD linum,WORD widthi)
  654. {
  655. struct Gadget *slider1,*slider2,*string1;
  656. struct ReqScrollStruct *req1,*req2;
  657. struct Image *im1,*im2,*sim1,*sim2;
  658. struct ListInfo *li;
  659. struct Border *bd1,*bd2,*bd3,*bd4;
  660. WORD *xy1,*xy2;
  661. WORD tfh,sw,sh;
  662. WORD apu1,apu2,apu3,apu4,apu5;
  663.  
  664. tfh=fmmain.txtysize+1;
  665. sw=fmconfig->sliderw+2; sh=fmconfig->sliderh+2;
  666.  
  667. li=allocvec(0,sizeof(struct ListInfo),MEMF_CLEAR|MEMF_PUBLIC);
  668. if(!li) return(0);
  669. li->slider1.NextGadget=&li->slider2;
  670. li->slider2.NextGadget=&li->string;
  671. li->string.NextGadget=&li->taskgadget;
  672. li->taskgadget.NextGadget=&li->ltaskgadget;
  673. li->ltaskgadget.NextGadget=&li->rtaskgadget;
  674.  
  675. slider1=&li->slider1;
  676. slider2=&li->slider2;
  677. string1=&li->string;
  678. req1=&li->rscroll1;
  679. req2=&li->rscroll2;
  680. im1=&li->im1;
  681. im2=&li->im2;
  682. sim1=&li->sim1;
  683. sim2=&li->sim2;
  684.  
  685. slider2->Activation=slider1->Activation=GADGIMMEDIATE|RELVERIFY|FOLLOWMOUSE;
  686. slider2->GadgetType=slider1->GadgetType=PROPGADGET;
  687. slider1->SpecialInfo=&li->pinfo1;
  688. slider2->SpecialInfo=&li->pinfo2;
  689. slider1->GadgetRender=im1;
  690. slider2->GadgetRender=im2;
  691. slider1->SelectRender=sim1;
  692. slider2->SelectRender=sim2;
  693. slider1->Flags=slider2->Flags=GADGIMAGE|GADGHIMAGE;
  694. li->pinfo1.Flags=FREEHORIZ|PROPBORDERLESS;
  695. li->pinfo2.Flags=FREEVERT|PROPBORDERLESS;
  696. li->pinfo1.HorizBody=65535; li->pinfo1.HorizPot=65535;
  697. li->pinfo2.VertBody=65535; li->pinfo2.VertPot=65535;
  698. im1->Depth=im2->Depth=fmconfig->mainscreen.depth;
  699. sim1->Depth=sim2->Depth=fmconfig->mainscreen.depth;
  700. im1->PlanePick=im2->PlanePick=power2(fmconfig->mainscreen.depth)-1;
  701. sim1->PlanePick=sim2->PlanePick=power2(fmconfig->mainscreen.depth)-1;
  702. im1->Width=sim1->Width=sw-2;
  703. im2->Height=sim2->Height=sh-2;
  704.  
  705. string1->Flags=GFLG_STRINGEXTEND;
  706. string1->Activation=RELVERIFY;
  707. string1->GadgetType=STRGADGET;
  708. string1->SpecialInfo=(APTR)&li->sinfo;
  709. li->sinfo.Buffer=fmlist[listnum].path;
  710. li->sinfo.UndoBuffer=fmmain.undobuf;
  711. li->sinfo.Extension=&li->stext;
  712. li->sinfo.MaxChars=510;
  713. li->stext.Font=fmmain.txtfont;
  714. li->stext.Pens[0]=li->stext.ActivePens[0]=fmconfig->stringpen;
  715. li->stext.Pens[1]=li->stext.ActivePens[1]=fmconfig->backpen;
  716.  
  717. slider1->GadgetID=linum+101;
  718. slider2->GadgetID=linum+111;
  719. string1->GadgetID=linum+201;
  720.  
  721. req1->gfxbase=req2->gfxbase=GfxBase;
  722. req1->VersionNumber=req2->VersionNumber=2;
  723. req1->RedrawAll=req2->RedrawAll=(APTR)&drawall;
  724. req1->ScrollAndDraw=req2->ScrollAndDraw=(APTR)&scrollndraw;
  725. req1->flags=0; req2->flags=1;
  726. req1->PropGadget=slider1; req2->PropGadget=slider2;
  727. if(fmconfig->flags&MVSCROLL)
  728.     req1->LineSpacing=1;
  729.     else
  730.     req1->LineSpacing=fmmain.listysize;
  731. if(fmconfig->flags&MHSCROLL)
  732.     req2->LineSpacing=1;
  733.     else
  734.     req2->LineSpacing=fmmain.listxsize;
  735.  
  736. req1->fmlist=req2->fmlist=&fmlist[listnum];
  737.  
  738. li->list=&fmlist[listnum];
  739. li->linumber=linum;
  740. fmlist[listnum].li=li;
  741.  
  742. li->visiblelinesw=(width-2*fmconfig->spacew-sw-fmconfig->spacew/3)/fmmain.listxsize;
  743. li->visiblelines=(height-5*fmconfig->spaceh-2*tfh-sh)/fmmain.listysize;
  744. req1->NumLines=li->visiblelines;
  745. req2->NumLines=li->visiblelinesw;
  746. li->x=x;
  747. li->y=y;
  748. li->dirwidth=li->visiblelinesw*fmmain.listxsize;
  749. li->dirheight=li->visiblelines*fmmain.listysize;
  750. li->diry=2*fmconfig->spaceh+tfh+1+y;
  751. if(!mirror)
  752.     li->dirx=2*fmconfig->spacew+sw+1+x;
  753.     else
  754.     li->dirx=fmconfig->spacew+1+x;
  755. li->edirx=li->dirx+li->dirwidth;
  756. li->ediry=li->diry+li->dirheight;
  757. draw3dbox(fmmain.rp,li->dirx-1,li->diry-1,li->dirwidth+2,li->dirheight+1,0);
  758. li->topliney=fmconfig->spaceh+1+y;
  759. draw3dbox(fmmain.rp,li->dirx-1,li->topliney-1,li->dirwidth+2,tfh,0);
  760.  
  761. if(!mirror)
  762.     slider1->LeftEdge=apu1=fmconfig->spacew+1+x;
  763.     else
  764.     slider1->LeftEdge=apu1=2*fmconfig->spacew+li->dirwidth+2+1+x;
  765. slider1->TopEdge=apu2=li->diry;
  766. slider1->Width=apu3=sw-2;
  767. slider1->Height=apu4=li->dirheight-1;
  768. apu5=RASSIZE(sw,apu4+2)*im1->Depth;
  769. im1->ImageData=allocvec(0,apu5,MEMF_CLEAR|MEMF_CHIP);
  770. sim1->ImageData=allocvec(0,apu5,MEMF_CLEAR|MEMF_CHIP);
  771. draw3dbox(fmmain.rp,apu1-1,apu2-1,apu3+2,apu4+2,0);
  772. if(!mirror)
  773.     slider2->LeftEdge=apu1=fmconfig->spacew*2+sw+1+x;
  774.     else
  775.     slider2->LeftEdge=apu1=fmconfig->spacew+1+x;
  776. slider2->TopEdge=apu2=li->diry+(li->dirheight+1)+fmconfig->spaceh;
  777. slider2->Width=apu3=(li->dirwidth+2)-2;
  778. slider2->Height=apu4=sh-2;
  779. apu5=RASSIZE(apu3,sh+2)*im2->Depth;
  780. im2->ImageData=allocvec(0,apu5,MEMF_CLEAR|MEMF_CHIP);
  781. sim2->ImageData=allocvec(0,apu5,MEMF_CLEAR|MEMF_CHIP);
  782. draw3dbox(fmmain.rp,apu1-1,apu2-1,apu3+2,apu4+2,0);
  783.  
  784. bd1=&li->bord1;
  785. bd2=&li->bord2;
  786. bd3=&li->bord3;
  787. bd4=&li->bord4;
  788. xy1=li->xy1;
  789. xy2=li->xy2;
  790. string1->Height=apu4=tfh-1;
  791. string1->TopEdge=apu2=li->diry+(li->dirheight+1)+2*fmconfig->spaceh+sh;
  792. apu2-=2; apu4+=4;
  793.  
  794. li->width=width;
  795. li->height=height;
  796. li->ex=x+width;
  797. li->ey=y+height;
  798.  
  799. apu5=fmconfig->spacew*2/3+x;
  800.  
  801. li->ltaskgadget.TopEdge=li->taskgadget.TopEdge=li->rtaskgadget.TopEdge=apu2;
  802. li->ltaskgadget.Width=li->taskgadget.Width=li->rtaskgadget.Width=widthi-1;
  803. li->ltaskgadget.Height=li->taskgadget.Height=li->rtaskgadget.Height=apu4-1;
  804. li->ltaskgadget.GadgetType=li->taskgadget.GadgetType=li->rtaskgadget.GadgetType=BOOLGADGET;
  805. li->ltaskgadget.Activation=li->taskgadget.Activation=li->rtaskgadget.Activation=RELVERIFY;
  806. li->ltaskgadget.Flags=li->taskgadget.Flags=li->rtaskgadget.Flags=GADGHIMAGE;
  807. li->ltaskgadget.GadgetRender=li->taskgadget.GadgetRender=li->rtaskgadget.GadgetRender=bd1;
  808. li->ltaskgadget.SelectRender=li->taskgadget.SelectRender=li->rtaskgadget.SelectRender=bd3;
  809.  
  810. li->ltaskgadget.LeftEdge=apu5;
  811. li->ltaskgadget.GadgetID=linum+411;
  812. li->ltaskgadget.UserData=(APTR)'<';
  813. apu5+=widthi;
  814. li->taskgadget.LeftEdge=apu5;
  815. li->taskgadget.GadgetID=linum+401;
  816. li->taskgadget.UserData=(APTR)linum;
  817. apu5+=widthi;
  818. li->rtaskgadget.LeftEdge=apu5;
  819. li->rtaskgadget.GadgetID=linum+421;
  820. li->rtaskgadget.UserData=(APTR)'>';
  821. apu5+=widthi;
  822. doborder(xy1,bd1,bd2,xy2,bd3,bd4,apu4,widthi);
  823.  
  824. apu5+=fmconfig->spacew*2/3;
  825. string1->LeftEdge=apu1=apu5;
  826. apu3=(2*fmconfig->spacew+(li->dirwidth+2)+sw)-apu5+x;
  827. string1->Width=(apu3/fmmain.txtxsize)*fmmain.txtxsize;
  828. draw3dbox(fmmain.rp,apu1,apu2+1,apu3,apu4-2,0);
  829.  
  830. if(!im1->ImageData||!im2->ImageData||!sim1->ImageData||!sim2->ImageData) {
  831.     freemem(im1->ImageData);
  832.     freemem(im2->ImageData);
  833.     freemem(sim1->ImageData);
  834.     freemem(sim2->ImageData);
  835.     freemem(li);
  836.     li=0;
  837. }
  838. return(li);
  839. }
  840.  
  841. struct TextFont* openfont(struct TextAttr *ta)
  842. {
  843. struct TextFont *tf;
  844. extern struct Library *DiskfontBase;
  845. APTR winptr;
  846.  
  847. winptr=fmmain.myproc->pr_WindowPtr;
  848. fmmain.myproc->pr_WindowPtr=(APTR)-1;
  849. tf=OpenFont(ta);
  850. if (tf) goto retu;
  851. DiskfontBase=OpenLibrary(dflib,37);
  852. if (!DiskfontBase) goto normal;
  853. tf=OpenDiskFont(ta);
  854. CloseLibrary(DiskfontBase);
  855. if (tf) goto retu;
  856. normal:
  857. ta->ta_YSize=8;
  858. ta->ta_Style=0;
  859. ta->ta_Flags=0;
  860. strcpy(ta->ta_Name,topaz);
  861. tf=OpenFont(ta);
  862. retu:
  863. fmmain.myproc->pr_WindowPtr=winptr;
  864. return(tf);
  865. }
  866.  
  867. void docmenusize(void)
  868. {
  869. WORD apu1,apu2,cnt,txoffset;
  870. struct RastPort rp;
  871.  
  872. InitRastPort(&rp);
  873. SetFont(&rp,fmmain.txtfont);
  874. apu1=0;
  875. for(cnt=0;cnt<TOTALCOMMANDS;cnt++) {
  876.     textextent(&rp,fmconfig->cmenuconfig[cnt].label,&apu2,&txoffset);
  877.     if(apu1<apu2) apu1=apu2;
  878. }
  879. fmmain.cmenuwidth=apu1+6;
  880. }
  881.  
  882. void setcmenu(void)
  883. {
  884. WORD bottomx,cmenudelay;
  885. WORD cnt2,apu1,apu2;
  886. UBYTE *ptr1;
  887. struct Gadget *gad;
  888. struct Gadget *pgad=0;
  889. struct Border *bo1,*bo2,*bo3,*bo4;
  890. WORD *xy1,*xy2,*xy;
  891. struct CMenuConfig *cmc;
  892.  
  893. freegadgets(fmmain.firstgadget); fmmain.firstgadget=0;
  894. bottomx=fmmain.ikkuna->Width-fmmain.ikkuna->BorderLeft-fmmain.ikkuna->BorderRight-fmconfig->spacew/3*2;
  895. cmenudelay=fmmain.cmenu;
  896. ObtainSemaphore(&fmmain.gfxsema);
  897. SetDrMd(fmmain.rp,JAM1);
  898. cnt2=0;
  899. cmc=&fmconfig->cmenuconfig[0];
  900. xy=fmmain.gadgetxy;
  901. while(*xy>=0) {
  902.     ptr1=allocvec(0,sizeof(struct Gadget)+sizeof(struct Border)*4+4*(2*5),MEMF_CLEAR|MEMF_PUBLIC);
  903.     gad=(struct Gadget*)ptr1;
  904.  
  905.     if(fmmain.firstgadget==0) {
  906.         fmmain.firstgadget=gad;
  907.     } else {
  908.         pgad->NextGadget=gad;
  909.     }
  910.     pgad=gad;
  911.     gad->Activation=RELVERIFY;
  912.     gad->GadgetType=BOOLGADGET;
  913.     gad->Flags=GADGHIMAGE;
  914.     ptr1+=sizeof(struct Gadget);
  915.     bo1=(struct Border*)ptr1;
  916.     bo2=(struct Border*)(ptr1+sizeof(struct Border));
  917.     bo3=(struct Border*)(ptr1+2*sizeof(struct Border));
  918.     bo4=(struct Border*)(ptr1+3*sizeof(struct Border));
  919.     xy1=(WORD*)(ptr1+4*sizeof(struct Border));
  920.     xy2=(WORD*)(ptr1+4*sizeof(struct Border)+2*5*2);
  921.  
  922.     while(cnt2<TOTALCOMMANDS) {
  923.         if(cmc->position==1) {
  924.             if(cmenudelay) {
  925.                 cnt2+=cmenudelay;
  926.                 cmc+=cmenudelay;
  927.                 cmenudelay=0;
  928.                 continue;
  929.             }
  930.             gad->LeftEdge=*xy++;
  931.             gad->TopEdge=*xy++;
  932.             gad->Width=*xy++;
  933.             gad->Height=*xy++;
  934.             break;
  935.         } else if(cmc->position==2) {
  936.             gad->TopEdge=fmmain.bottomliney-2;
  937.             textextent(fmmain.rp,cmc->label,&apu1,&apu2);
  938.             gad->Width=(apu1+2*fmconfig->spaceh);
  939.             gad->Height=fmmain.txtysize+2+1;
  940.             bottomx-=gad->Width;
  941.             gad->LeftEdge=bottomx;
  942.             break;
  943.         }
  944.         cmc++;
  945.         cnt2++;
  946.     }
  947.     if(cnt2>=TOTALCOMMANDS) {
  948.         gad->LeftEdge=*xy++;
  949.         gad->TopEdge=*xy++;
  950.         gad->Width=*xy++;
  951.         gad->Height=*xy++;
  952.     }
  953.  
  954.     doborder(xy1,bo1,bo2,xy2,bo3,bo4,gad->Height,gad->Width);
  955.     gad->GadgetRender=bo1;
  956.     gad->SelectRender=bo3;
  957.  
  958.     if(cnt2<TOTALCOMMANDS)
  959.         SetAPen(fmmain.rp,cmc->backpen);
  960.         else
  961.         SetAPen(fmmain.rp,fmconfig->backpen);
  962.     if(fmconfig->flags&MDOUBLED) 
  963.         RectFill(fmmain.rp,gad->LeftEdge+2,gad->TopEdge+1,gad->Width+gad->LeftEdge-3,gad->Height+gad->TopEdge-2);
  964.         else
  965.         RectFill(fmmain.rp,gad->LeftEdge+1,gad->TopEdge+1,gad->Width+gad->LeftEdge-2,gad->Height+gad->TopEdge-2);
  966.     Move(fmmain.rp,gad->LeftEdge+fmconfig->spaceh,gad->TopEdge+fmmain.txtbaseline+1);
  967.     if(cnt2<TOTALCOMMANDS) {
  968.         if(cmc->cmenucount!=EMPTYCONFIG) {
  969.             SetAPen(fmmain.rp,cmc->frontpen);
  970.             Text(fmmain.rp,cmc->label,strlen(cmc->label));
  971.         }
  972.         cmc++;
  973.         cnt2++;
  974.     }
  975. }
  976. SetDrMd(fmmain.rp,JAM2);
  977. AddGList(fmmain.ikkuna,fmmain.firstgadget,-1,-1,0);
  978. RefreshGList(fmmain.firstgadget,fmmain.ikkuna,0,-1);
  979. ReleaseSemaphore(&fmmain.gfxsema);
  980. gadgettables();
  981. }
  982.  
  983. void gadgettables(void)
  984. {
  985. struct CMenuConfig *cmc;
  986. struct GadKeyTab *gkt;
  987. struct Gadget *g;
  988. WORD cnt1,apu2;
  989.  
  990. extern APTR launchtable[];
  991. gkt=&fmmain.gadkeytab[0];
  992. memseti(gkt,0,sizeof(struct GadKeyTab)*(WINDOWLISTS*LISTGADGETS+TOTALCOMMANDS));
  993.  
  994. for(cnt1=0;cnt1<WINDOWLISTS;cnt1++) {
  995.     if(fmmain.li[cnt1]) {
  996.         apu2=fmmain.li[cnt1]->list->listnumber;
  997.         gkt->g=&fmmain.li[cnt1]->taskgadget;
  998.         gkt->key[0]=fmmain.li[cnt1]->list->listnumber+'0';
  999.         gkt->listnum=apu2;
  1000.         gkt++;
  1001.         gkt->g=&fmmain.li[cnt1]->ltaskgadget;
  1002.         gkt->key[0]='<';
  1003.         gkt->listnum=apu2;
  1004.         gkt->onelist=1;
  1005.         gkt++;
  1006.         gkt->g=&fmmain.li[cnt1]->rtaskgadget;
  1007.         gkt->key[0]='>';
  1008.         gkt->listnum=apu2;
  1009.         gkt->onelist=1;
  1010.         gkt++;
  1011.     } else {
  1012.         gkt->unused=1;
  1013.         gkt++;
  1014.         gkt->unused=1;
  1015.         gkt++;
  1016.         gkt->unused=1;
  1017.         gkt++;
  1018.     }
  1019. }        
  1020. g=fmmain.firstgadget;
  1021. apu2=0;
  1022. for(cnt1=0;cnt1<TOTALCOMMANDS;cnt1++) {
  1023.     cmc=&fmconfig->cmenuconfig[cnt1];
  1024.     if(g&&(cmc->position==2||(cmc->position==1&&apu2>=fmmain.cmenu))) {
  1025.         gkt->g=g;
  1026.         g->GadgetID=cnt1+301;
  1027.         g=g->NextGadget;
  1028.     } else {
  1029.         gkt->g=(struct Gadget*)2L;
  1030.     }
  1031.     if(cmc->position==1) apu2++;
  1032.     gkt->listnum=-1;
  1033.     gkt->cmc=&fmconfig->cmenuconfig[cnt1];
  1034.     gkt++;
  1035. }
  1036. }
  1037.  
  1038. void doborder(WORD *xy1,struct Border *bo1,struct Border *bo2,WORD *xy2,struct Border *bo3,struct Border *bo4,WORD h,WORD w)
  1039. {
  1040. h--; w--;
  1041. if(fmconfig->flags&MDOUBLED) {
  1042.     xy1[3]=h;
  1043.     xy1[4]=1; xy1[5]=h;
  1044.     xy1[6]=1;
  1045.     xy1[8]=w;
  1046.     xy2[0]=w; xy2[1]=h;
  1047.     xy2[2]=w;
  1048.     xy2[4]=w-1; xy2[5]=1;
  1049.     xy2[6]=xy2[4]; xy2[7]=h;
  1050.     xy2[8]=1; xy2[9]=h;
  1051. } else {
  1052.     xy1[5]=xy1[7]=h;
  1053.     xy1[2]=xy1[4]=w;
  1054.     xy1[0]=xy1[1]=xy1[3]=xy1[8]=xy1[9]=0;
  1055. /*
  1056.     xy1[1]=h;
  1057.     xy1[4]=w;
  1058.     xy1[3]=xy1[5]=xy1[6]=xy1[8]=0;
  1059. */
  1060.     xy2[0]=w;
  1061.     xy2[1]=1;
  1062.     xy2[2]=w;
  1063.     xy2[3]=h;
  1064.     xy2[4]=1;
  1065.     xy2[5]=h;
  1066.     xy2[6]=xy2[8]=xy2[4];
  1067.     xy2[7]=xy2[9]=xy2[5];
  1068. }
  1069. bo1->FrontPen=bo4->FrontPen=fmconfig->whitepen;
  1070. bo1->Count=bo2->Count=bo3->Count=bo4->Count=5;
  1071. bo1->XY=xy1;
  1072. bo1->NextBorder=bo2;
  1073. bo2->FrontPen=bo3->FrontPen=fmconfig->blackpen;
  1074. bo2->XY=xy2;
  1075. bo3->XY=xy1;
  1076. bo3->NextBorder=bo4;
  1077. bo4->XY=xy2;
  1078.  
  1079. }
  1080.  
  1081.  
  1082. void textextent(struct RastPort *rp,UBYTE *ptr,WORD *width,WORD *offset)
  1083. {
  1084. struct TextExtent te;
  1085.  
  1086. TextExtent(rp,ptr,strlen(ptr),&te);
  1087. *offset=te.te_Extent.MinX;
  1088. *width=te.te_Extent.MaxX+te.te_Extent.MinX;
  1089. }
  1090. void textextentuc(struct RastPort *rp,UBYTE *ptr,WORD *width,WORD *offset)
  1091. {
  1092. struct TextExtent te;
  1093. UBYTE varaptr[100];
  1094.  
  1095. copyus(varaptr,ptr);
  1096. TextExtent(rp,varaptr,strlen(varaptr),&te);
  1097. *width=te.te_Extent.MaxX+te.te_Extent.MinX;
  1098. *offset=te.te_Extent.MinX;
  1099. }
  1100.  
  1101. void draw3dbox(struct RastPort *rp,WORD x,WORD y,WORD w,WORD h,WORD type)
  1102. {
  1103. UBYTE col1,col2;
  1104.  
  1105. //1=raised 0=lowered
  1106.  
  1107. SetAPen(rp,fmconfig->backpen);
  1108. RectFill(rp,x,y,x+w,y+h);
  1109. if (type) {
  1110.     col1=fmconfig->whitepen; col2=fmconfig->blackpen;
  1111.     } else {
  1112.     col1=fmconfig->blackpen; col2=fmconfig->whitepen;
  1113. }
  1114. x--;y--;w++;h++;
  1115. if (fmconfig->flags&MDOUBLED) { x--; w+=2; }
  1116. Move(rp,x,y);
  1117. SetAPen(rp,col1);
  1118. Draw(rp,x+w,y);
  1119. SetAPen(rp,col2);
  1120. Draw(rp,x+w,y+h);
  1121. Draw(rp,x,y+h);
  1122. SetAPen(rp,col1);
  1123. Draw(rp,x,y);
  1124. if (fmconfig->flags&MDOUBLED) {
  1125.     Move(rp,x+1,y);
  1126.     Draw(rp,x+1,y+h-1);
  1127.     SetAPen(rp,col2);
  1128.     Move(rp,x+w-1,y+1);
  1129.     Draw(rp,x+w-1,y+h);
  1130. }
  1131. }
  1132.