home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / fm2000 / config.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-04  |  39.8 KB  |  1,645 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. #include <exec/types.h>
  21. #include <exec/memory.h>
  22. #include <dos/dos.h>
  23. #include <intuition/intuition.h>
  24. #include <libraries/gadtools.h>
  25. #include <proto/all.h>
  26. #include <proto/reqtools.h>
  27. #include <strings.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <libraries/reqtools.h>
  31.  
  32. #define HELPCONFIGSIZE 500
  33.  
  34. #include "fmlocale.h"
  35. #include "fmgui.h"
  36. #include "fmnode.h"
  37. #include "fieldlist.h"
  38. #include "fmdos.h"
  39.  
  40. void *parseconfigdefault(struct CMenuConfig*);
  41. void *includeconfigdefault(struct CMenuConfig*);
  42. void *excludeconfigdefault(struct CMenuConfig*);
  43. void *ownexecuteconfigdefault(struct CMenuConfig*);
  44.  
  45. WORD quitconfig(struct GUIBase*,struct CMenuConfig*);
  46. void *quitconfigdefault(struct CMenuConfig*);
  47. WORD sleepconfig(struct GUIBase*,struct CMenuConfig*);
  48. void *sleepconfigdefault(struct CMenuConfig*);
  49. WORD parentconfig(struct GUIBase*,struct CMenuConfig*);
  50. void *parentconfigdefault(struct CMenuConfig*);
  51. WORD copyconfig(struct GUIBase*,struct CMenuConfig*);
  52. void *copyconfigdefault(struct CMenuConfig*);
  53. WORD deleteconfig(struct GUIBase*,struct CMenuConfig*);
  54. void *deleteconfigdefault(struct CMenuConfig*);
  55. WORD showtextconfig(struct GUIBase*,struct CMenuConfig*);
  56. void *showtextconfigdefault(struct CMenuConfig*);
  57. WORD executeconfig(struct GUIBase*,struct CMenuConfig*);
  58. void *executeconfigdefault(struct CMenuConfig*);
  59. WORD hearconfig(struct GUIBase*,struct CMenuConfig*);
  60. void *hearconfigdefault(struct CMenuConfig*);
  61. WORD diskeditconfig(struct GUIBase*,struct CMenuConfig*);
  62. void *diskeditconfigdefault(struct CMenuConfig*);
  63.  
  64. extern struct FMMain fmmain;
  65. extern struct FMList fmlist[];
  66. extern struct FMConfig *fmconfig;
  67. extern struct ReqToolsBase *ReqToolsBase=0;
  68. extern UBYTE reqlib[];
  69.  
  70. void* __asm rleunpack(register __a0 void*,register __a1 void*,register __d0 LONG);
  71. LONG __asm rlepack(register __a0 void*,register __a1 void*,register __d0 LONG);
  72.  
  73. ULONG power2(WORD);
  74.  
  75. struct FMConfig *newconfig(struct FMConfig *oc)
  76. {
  77. struct FMConfig *fmc;
  78.  
  79. fmc=allocmem(sizeof(struct FMConfig));
  80. if(!fmc) return(0);
  81. CopyMem(oc,fmc,sizeof(struct FMConfig));
  82. fmc->txtfontattr.ta_Name=fmc->txtfontname;
  83. fmc->listfontattr.ta_Name=fmc->listfontname;
  84. fmc->reqfontattr.ta_Name=fmc->reqfontname;
  85. fmc->txtshowfontattr.ta_Name=fmc->txtshowfontname;
  86. fmc->smallfontattr.ta_Name=fmc->smallfontname;
  87. return(fmc);
  88. }
  89. void freeconfig(struct FMConfig *sc,struct FMConfig *dc)
  90. {
  91. CopyMem(sc,dc,sizeof(struct FMConfig));
  92. dc->txtfontattr.ta_Name=dc->txtfontname;
  93. dc->listfontattr.ta_Name=dc->listfontname;
  94. dc->reqfontattr.ta_Name=dc->reqfontname;
  95. dc->txtshowfontattr.ta_Name=dc->txtshowfontname;
  96. dc->smallfontattr.ta_Name=dc->smallfontname;
  97. freemem(sc);
  98. }
  99.  
  100. WORD errorreq(WORD,UBYTE*,WORD,WORD);
  101.  
  102. WORD openreqtools(void)
  103. {
  104. UBYTE text[100];
  105.  
  106. if(!ReqToolsBase) {
  107.     ReqToolsBase=(struct ReqToolsBase*)OpenLibrary(reqlib,38);
  108.     if(!ReqToolsBase) {
  109.         sformatmsg(text,MSG_FMDOS_OPENERR,reqlib);
  110.         errorreq(MSG_REQ_ERROR,text,0,MSG_OK);
  111.         return(0);
  112.     }
  113. }
  114. return(1);
  115. }
  116.  
  117. /*
  118. WORD getfilename(UBYTE *dst,WORD len)
  119. {
  120. struct rtFileRequester *rfr;
  121. UBYTE fname[110];
  122. UBYTE path[200];
  123. UBYTE *ptr;
  124.  
  125. strcpy(path,dst);
  126. if(!openreqtools()) return(0);
  127. if(!(rfr=rtAllocRequest(RT_FILEREQ,0))) return(0);
  128. ptr=FilePart(path);
  129. strcpy(fname,ptr);
  130. *ptr=0;
  131. rtChangeReqAttr(rfr,RTFI_Dir,path,TAG_DONE);
  132. if(rtFileRequest(rfr,fname,getstring(MSG_CONFIG_COMSELECT),TAG_DONE)) {
  133.     strcpy(rfr->Dir,dst);
  134.     AddPart(dst,fname,len);
  135. }
  136. rtFreeRequest(rfr);
  137. return(1);
  138. }
  139. */
  140.  
  141. WORD askscreen(struct ScreenConfig *sc,WORD title,WORD scroll)
  142. {
  143. struct rtScreenModeRequester *req;
  144. WORD ret;
  145. ULONG flags;
  146.  
  147. ret=0;
  148. flags=0;
  149. if(scroll) flags=SCREQF_AUTOSCROLLGAD;
  150. flags|=SCREQF_OVERSCANGAD|SCREQF_SIZEGADS|SCREQF_DEPTHGAD|SCREQF_GUIMODES;
  151.  
  152. if(!openreqtools()) return(0);
  153.  
  154. req=(struct rtScreenModeRequester*)rtAllocRequestA(RT_SCREENMODEREQ,0);
  155. if(req) {
  156.     rtChangeReqAttr(req,
  157.     RTSC_DisplayID,sc->screenmode,
  158.     RTSC_DisplayWidth,sc->width,
  159.     RTSC_DisplayHeight,sc->height,
  160.     RTSC_DisplayDepth,sc->depth,
  161.     RTSC_AutoScroll,sc->autoscroll,
  162.     RTSC_OverscanType,sc->overscan,
  163.     TAG_DONE);
  164.     ret=rtScreenModeRequest(req,getstring(title), 
  165.     RTSC_Flags,flags,
  166.     RTSC_MinDepth,1,RTSC_MaxDepth,4,
  167.     TAG_DONE);
  168.     if(ret) {
  169.         sc->screenmode=req->DisplayID;
  170.         sc->width=req->DisplayWidth;
  171.         sc->height=req->DisplayHeight;
  172.         sc->depth=req->DisplayDepth;
  173.         sc->overscan=req->OverscanType;
  174.         sc->autoscroll=0;
  175.         if (scroll) sc->autoscroll=1;
  176.         ret=3;
  177.     }
  178.     rtFreeRequest(req);
  179. }
  180. return(ret);
  181. }
  182. WORD askfont(struct TextAttr *ta,WORD title,WORD type)
  183. {
  184. struct rtFontRequester *req;
  185. WORD ret=0;
  186.  
  187. if(!openreqtools()) return(0);
  188.  
  189. req=(struct rtFontRequester*)rtAllocRequestA(RT_FONTREQ,0);
  190. if(req) {
  191.     rtChangeReqAttr(req,
  192.     RTFO_FontName,ta->ta_Name,
  193.     RTFO_FontHeight,ta->ta_YSize,
  194.     RTFO_FontStyle,ta->ta_Style,
  195.     TAG_DONE);
  196.     ret=rtFontRequest(req,getstring(title),
  197.     RTFO_Flags,(type?0:FREQF_FIXEDWIDTH)|FREQF_SCALE,
  198.     TAG_DONE);
  199.     if(ret) {
  200.         strcpy(ta->ta_Name,req->Attr.ta_Name);
  201.         ta->ta_YSize=req->Attr.ta_YSize;
  202.         ta->ta_Style=req->Attr.ta_Style;
  203.         ret=3;
  204.     }
  205.     rtFreeRequest(req);
  206. }
  207. return(ret);
  208. }
  209.  
  210. // ********************************
  211. //        DATATYPES
  212. // ********************************
  213.  
  214. WORD datatypesconfig(struct FMConfig *ofmc)
  215. {
  216. struct GUIBase *gb;
  217. WORD retcode,c;
  218. struct FMConfig *fmc;
  219. WORD dt1,dt2,dt3,dt4,dt5,dt6,dt7,dt8;
  220.  
  221. retcode=0;
  222. if(!(fmc=newconfig(ofmc))) return(0);
  223.  
  224. gb=getguibase(getstring(MSG_CONFIG_NAME));
  225. setconnectgroup(gb,9,0,0);
  226.  
  227. dt1=fmc->usepicturedt;
  228. dt2=fmc->usesampledt;
  229. dt3=fmc->useascdt;
  230. dt4=fmc->usehexdt;
  231. dt5=fmc->usemoddt;
  232. dt6=fmc->useicondt;
  233. dt7=fmc->usefontdt;
  234. dt8=fmc->useexecutedt;
  235. setconnectgroup(gb,1,1,9);
  236. reqinfomsg(gb,MSG_CONFIG_USEDT_PICTURE,110,guiUC|guiLEFT);
  237. reqinfomsg(gb,MSG_CONFIG_USEDT_SAMPLE,111,guiUC|guiLEFT);
  238. reqinfomsg(gb,MSG_CONFIG_USEDT_ASC,112,guiUC|guiLEFT);
  239. reqinfomsg(gb,MSG_CONFIG_USEDT_HEX,113,guiUC|guiLEFT);
  240. reqinfomsg(gb,MSG_CONFIG_USEDT_MOD,114,guiUC|guiLEFT);
  241. reqinfomsg(gb,MSG_CONFIG_USEDT_ICON,115,guiUC|guiLEFT);
  242. reqinfomsg(gb,MSG_CONFIG_USEDT_FONT,116,guiUC|guiLEFT);
  243. reqinfomsg(gb,MSG_CONFIG_USEDT_EXECUTE,117,guiUC|guiLEFT);
  244. setconnectgroup(gb,2,1,9);
  245. reqcyclemsg(gb,110,&dt1,MSG_NON,MSG_YESN,0);
  246. reqcyclemsg(gb,111,&dt2,MSG_NON,MSG_YESN,0);
  247. reqcyclemsg(gb,112,&dt3,MSG_NON,MSG_YESN,0);
  248. reqcyclemsg(gb,113,&dt4,MSG_NON,MSG_YESN,0);
  249. reqcyclemsg(gb,114,&dt5,MSG_NON,MSG_YESN,0);
  250. reqcyclemsg(gb,115,&dt6,MSG_NON,MSG_YESN,0);
  251. reqcyclemsg(gb,116,&dt7,MSG_NON,MSG_YESN,0);
  252. reqcyclemsg(gb,117,&dt8,MSG_NON,MSG_YESN,0);
  253. buttonbarmsg(gb,MSG_OK,1,MSG_CANCEL,0,0);
  254.  
  255. c=quickreq(gb);
  256. if(c) {
  257.     fmc->usepicturedt=dt1;
  258.     fmc->usesampledt=dt2;
  259.     fmc->useascdt=dt3;
  260.     fmc->usehexdt=dt4;
  261.     fmc->usemoddt=dt5;
  262.     fmc->useicondt=dt6;
  263.     fmc->usefontdt=dt7;
  264.     fmc->useexecutedt=dt8;
  265.     freeconfig(fmc,ofmc);
  266.     fmc=0;
  267. }
  268. freemem(fmc);
  269. return(retcode);
  270. }
  271.  
  272. // ********************************
  273. //        GENERAL
  274. // ********************************
  275.  
  276. WORD generalconfig(struct FMConfig *ofmc)
  277. {
  278. struct GUIBase *gb;
  279. WORD retcode=0;
  280. LONG mpri,pril,prim,prih,dosbuf,dctime;
  281. WORD rbut,c;
  282. struct FMConfig *fmc;
  283.  
  284. if(!(fmc=newconfig(ofmc))) return(0);
  285.  
  286. gb=getguibase(getstring(MSG_CONFIG_NAME));
  287. setconnectgroup(gb,9,0,0);
  288.  
  289. mpri=fmc->mainpriority;
  290. pril=fmc->pri[0];
  291. prim=fmc->pri[1];
  292. prih=fmc->pri[2];
  293. dosbuf=fmc->dosbuffersize;
  294. dctime=fmc->doubleclick;
  295. rbut=fmc->rightmouse;
  296.  
  297. setconnectgroup(gb,1,1,9);
  298. reqinfomsg(gb,MSG_CONFIG_PRIORITYMAIN,100,guiUC|guiLEFT);
  299. reqinfomsg(gb,MSG_CONFIG_PRIORITYLOW,101,guiUC|guiLEFT);
  300. reqinfomsg(gb,MSG_CONFIG_PRIORITYMED,102,guiUC|guiLEFT);
  301. reqinfomsg(gb,MSG_CONFIG_PRIORITYHIGH,103,guiUC|guiLEFT);
  302. reqinfomsg(gb,MSG_CONFIG_DOSBUFSIZE,104,guiUC|guiLEFT);    
  303. reqinfomsg(gb,MSG_CONFIG_DOUBLECLICK,105,guiUC|guiLEFT);
  304. reqinfomsg(gb,MSG_CONFIG_RIGHTMOUSE,106,guiUC|guiLEFT);
  305. setconnectgroup(gb,2,1,9);
  306. reqinteger(gb,100,&mpri,-128,127);
  307. reqinteger(gb,101,&pril,-128,127);
  308. reqinteger(gb,102,&prim,-128,127);
  309. reqinteger(gb,103,&prih,-128,127);
  310. reqinteger(gb,104,&dosbuf,2000,99999999);
  311. reqinteger(gb,105,&dctime,1,100);
  312. reqcyclemsg(gb,106,&rbut,MSG_CONFIG_RIGHTMOUSE_DOUBLECLICK,MSG_CONFIG_RIGHTMOUSE_PARENT,0);
  313. buttonbarmsg(gb,MSG_OK,1,MSG_CANCEL,0,0);
  314.  
  315. c=quickreq(gb);
  316. if(c) {
  317.     fmc->mainpriority=mpri;
  318.     fmc->pri[0]=pril;
  319.     fmc->pri[1]=prim;
  320.     fmc->pri[2]=prih;
  321.     fmc->dosbuffersize=dosbuf;
  322.     fmc->doubleclick=dctime;
  323.     fmc->rightmouse=rbut;
  324.     freeconfig(fmc,ofmc);
  325.     fmc=0;
  326. }
  327. freemem(fmc);
  328. return(retcode);
  329. }
  330.  
  331. static WORD palette(struct FMConfig *ofmc)
  332. {
  333. struct GUIBase *gb;
  334. WORD cnt1,retcode,c;
  335. UBYTE *ptr1,*ptr2;
  336. UBYTE txt[100];
  337. UBYTE pens[FMPENS];
  338. struct FMConfig *fmc;
  339.  
  340. if(!(fmc=newconfig(ofmc))) return(0);
  341. gb=getguibase(getstring(MSG_CONFIG_PALETTE));
  342. setconnectgroup(gb,10,0,0);
  343. setconnectgroup(gb,1,1,10);
  344. setconnectgroup(gb,2,1,10);
  345. ptr1=getstring(MSG_CONFIG_PENS);
  346. ptr2=&fmc->devicepen;
  347. for(cnt1=0;cnt1<FMPENS;cnt1++) {
  348.     setguigroup(gb,1,0);
  349.     reqinfo(gb,ptr1,cnt1+100,guiUC|guiLEFT);
  350.     setguigroup(gb,2,0);
  351.     pens[cnt1]=*ptr2;
  352.     ptr1+=strlen(ptr1)+1;
  353.     reqpalette(gb,cnt1+120,ptr2);
  354.     ptr2++;
  355. }
  356. buttonbarmsg(gb,MSG_OK,2,MSG_CONFIG_EDITPALETTE,1,MSG_CANCEL,0,0);
  357.  
  358. retcode=0;
  359. if(openinitreq(gb)) {
  360.     retcode=-1;
  361.     while(retcode<0) {
  362.         c=reqmsghandler(gb);
  363.         switch(c)
  364.             {
  365.             case 2:    // OK
  366.             ptr2=&fmc->devicepen;
  367.             for(cnt1=0;cnt1<FMPENS;cnt1++) {
  368.                 if(pens[cnt1]!=*ptr2) {
  369.                     if(cnt1>=9) retcode=2; else retcode=1;
  370.                 }
  371.             }
  372.             freeconfig(fmc,ofmc);
  373.             fmc=0;
  374.             break;
  375.             case 1:
  376.             if(openreqtools()) {
  377.                 ptr1=getstring(MSG_CONFIG_EDITPALETTE);
  378.                 ptr2=txt;
  379.                 while(*ptr1) {
  380.                     if(*ptr1=='_') ptr1++; else *ptr2++=*ptr1++;
  381.                 }
  382.                 *ptr2=0;
  383.                 rtPaletteRequestA(txt,0,0);
  384.             }
  385.             break;
  386.             case 0:
  387.             retcode=0;
  388.             break;
  389.         }
  390.     }
  391. }
  392. freereq(gb);
  393. freemem(fmc);
  394. return(retcode);
  395. }
  396.  
  397. static WORD savecommands(struct FMConfig *fmc,void *moreconfigs[])
  398. {
  399. struct CMenuConfig *cmc;
  400. WORD cnt;
  401.  
  402. for(cnt=0;cnt<TOTALCOMMANDS;cnt++) {
  403.     cmc=&fmc->cmenuconfig[cnt];
  404.     moreconfigs[cnt]=0;
  405.     if(cmc->moreconfiglen) {
  406.         moreconfigs[cnt]=allocmem(cmc->moreconfiglen);
  407.         if(!moreconfigs[cnt]) return(0);
  408.         CopyMem(cmc->moreconfig,moreconfigs[cnt],cmc->moreconfiglen);
  409.     }
  410. }
  411. return(1);
  412. }
  413. static void restorecommands(struct FMConfig *fmc,void *moreconfigs[])
  414. {
  415. struct CMenuConfig *cmc;
  416. WORD cnt;
  417.  
  418. for(cnt=0;cnt<TOTALCOMMANDS;cnt++) {
  419.     if(fmc) {
  420.         cmc=&fmc->cmenuconfig[cnt];
  421.         if(moreconfigs[cnt]) {
  422.             CopyMem(moreconfigs[cnt],cmc->moreconfig,cmc->moreconfiglen);
  423.         } else if(cmc->moreconfiglen) {
  424.             freemem(cmc->moreconfig);
  425.             cmc->moreconfiglen=0;
  426.         }
  427.     } else {
  428.         freemem(moreconfigs[cnt]);
  429.     }
  430.     moreconfigs[cnt]=0;
  431. }
  432. }
  433.  
  434.  
  435. static WORD commandconfig(struct FMConfig *ofmc,struct CMenuConfig *cmc)
  436. {
  437. struct GUIBase *gb;
  438. struct OwnCommand *oc;
  439. struct FMConfig *fmc;
  440. void *moreconfigs[TOTALCOMMANDS];
  441. WORD apu1,retcode;
  442. WORD pri,sw,cd,frs,fre,res;
  443. UBYTE front,back;
  444. LONG stack,timeout;
  445. UBYTE vara1[100];
  446.  
  447. apu1=-1;
  448. retcode=0;
  449. if(!(fmc=newconfig(ofmc))) return(0);
  450. if(!savecommands(fmc,moreconfigs)) goto error;
  451.  
  452. sformat(vara1,"%s (%s)",getstring(MSG_CONFIG_NAME),findbuildstring(cmc));
  453. getconfig(cmc);
  454.  
  455. gb=getguibase(vara1);
  456. setconnectgroup(gb,10,0,0);
  457. if(cmc->cmenucount==100) oc=cmc->moreconfig; else oc=0;
  458.  
  459. setconnectgroup(gb,1,1,10);
  460. reqinfomsg(gb,MSG_CONFIG_COMKEY,100,guiUC|guiLEFT);
  461. reqinfomsg(gb,MSG_CONFIG_COMLABEL,101,guiUC|guiLEFT);
  462. reqinfomsg(gb,MSG_CONFIG_COMFRONTPEN,102,guiUC|guiLEFT);
  463. reqinfomsg(gb,MSG_CONFIG_COMBACKPEN,103,guiUC|guiLEFT);
  464. reqinfomsg(gb,MSG_CONFIG_COMPRI,104,guiUC|guiLEFT);
  465. setconnectgroup(gb,2,1,10);
  466. reqstring(gb,100,cmc->shortcut,sizeof(cmc->shortcut));
  467. reqstring(gb,101,cmc->label,sizeof(cmc->label));
  468. front=cmc->frontpen;
  469. reqpalette(gb,102,&front);
  470. back=cmc->backpen;
  471. reqpalette(gb,103,&back);
  472. pri=cmc->priority;
  473. reqcyclemsg(gb,104,&pri,MSG_CONFIG_COMLOWPRI,MSG_CONFIG_COMMEDPRI,MSG_CONFIG_COMHIGHPRI,0);
  474.  
  475. if(cmc->cmenucount==100) {
  476.     setguigroup(gb,1,0);
  477.     reqinfomsg(gb,MSG_EXE_SHELLWINDOW,110,guiUC|guiLEFT);
  478.     reqinfomsg(gb,MSG_EXE_CONFIG_CD,111,guiUC|guiLEFT);
  479.     reqinfomsg(gb,MSG_EXE_CONFIG_RESCAN,112,guiUC|guiLEFT);
  480.     reqinfomsg(gb,MSG_EXE_CONFIG_STARTSCREEN,113,guiUC|guiLEFT);
  481.     reqinfomsg(gb,MSG_EXE_CONFIG_ENDSCREEN,114,guiUC|guiLEFT);
  482.     reqinfomsg(gb,MSG_CONFIG_COMPATTERN,115,guiUC|guiLEFT);
  483.     reqinfomsg(gb,MSG_CONFIG_COMSIGNATURE,116,guiUC|guiLEFT);
  484.     reqinfomsg(gb,MSG_CONFIG_COMCOMMAND,117,guiUC|guiLEFT);
  485.     reqinfomsg(gb,MSG_CONFIG_COMSTACK,118,guiUC|guiLEFT);
  486.     reqinfomsg(gb,MSG_EXE_TIMEOUT,119,guiUC|guiLEFT);
  487.     setguigroup(gb,2,0);
  488.     sw=oc->ef.shellwindow;
  489.     reqcyclemsg(gb,110,&sw,MSG_NON,MSG_YESN,0);
  490.     cd=oc->ef.cd;
  491.     reqcyclemsg(gb,111,&cd,MSG_EXE_CONFIG_NOCHANGE,MSG_EXE_CONFIG_SOURCE,MSG_EXE_CONFIG_DESTINATION,0);
  492.     res=oc->ef.rescan;
  493.     reqcyclemsg(gb,112,&res,MSG_EXE_CONFIG_NOCHANGE,MSG_EXE_CONFIG_SOURCE,MSG_EXE_CONFIG_DESTINATION,MSG_EXE_CONFIG_SOURCEDEST,0);
  494.     frs=oc->ef.startfront;
  495.     reqcyclemsg(gb,113,&frs,MSG_EXE_CONFIG_NOCHANGE,MSG_EXE_CONFIG_FMFRONT,MSG_EXE_CONFIG_WBFRONT,0);
  496.     fre=oc->ef.endfront;
  497.     reqcyclemsg(gb,114,&fre,MSG_EXE_CONFIG_NOCHANGE,MSG_EXE_CONFIG_FMFRONT,MSG_EXE_CONFIG_WBFRONT,0);
  498.     reqstring(gb,115,oc->namematch,sizeof(oc->namematch));
  499.     reqstring(gb,116,oc->matchbytes,sizeof(oc->matchbytes));
  500.     reqstring(gb,117,oc->command,sizeof(oc->command));
  501.     stack=oc->ef.stack;
  502.     reqinteger(gb,118,&stack,4,999999999);
  503.     timeout=oc->ef.timeout;
  504.     reqinteger(gb,119,&timeout,-1,99);
  505. }
  506.  
  507. apu1=-1;
  508. switch(cmc->cmenucount)
  509.     {
  510.     case SLEEPCONFIG:
  511.     apu1=sleepconfig(gb,cmc);
  512.     break;
  513.     case QUITCONFIG:
  514.     apu1=quitconfig(gb,cmc);
  515.     break;
  516.     case PARENTCONFIG:
  517.     apu1=parentconfig(gb,cmc);
  518.     break;
  519.     case COPYCONFIG:
  520.     case COPYASCONFIG:
  521.     case MOVECONFIG:
  522.     apu1=copyconfig(gb,cmc);
  523.     break;
  524.     case DELETECONFIG:
  525.     apu1=deleteconfig(gb,cmc);
  526.     break;
  527.     case SHOWASCCONFIG:
  528.     case SHOWHEXCONFIG:
  529.     apu1=showtextconfig(gb,cmc);
  530.     break;
  531.     case EXECUTECONFIG:
  532.     apu1=executeconfig(gb,cmc);
  533.     break;
  534.     case HEARCONFIG:
  535.     apu1=hearconfig(gb,cmc);
  536.     break;
  537.     case DISKEDITCONFIG:
  538.     apu1=diskeditconfig(gb,cmc);
  539.     break;
  540. }
  541. if(apu1==-1) {
  542.     commandanswer(gb);
  543.     apu1=quickreq(gb);
  544. }
  545. if(apu1==1) {
  546.     retcode=1;
  547.     cmc->frontpen=front;
  548.     cmc->backpen=back;
  549.     cmc->priority=pri;
  550.     CopyMem(cmc,&fmc->cmenuconfig[cmc-ofmc->cmenuconfig],sizeof(struct CMenuConfig));
  551.     if(oc) {
  552.         oc->ef.shellwindow=sw;
  553.         oc->ef.cd=cd;
  554.         oc->ef.rescan=res;
  555.         oc->ef.startfront=frs;
  556.         oc->ef.endfront=fre;
  557.         oc->ef.stack=stack;
  558.         oc->ef.timeout=timeout;
  559.     }
  560. }
  561.  
  562. error:
  563. if(!retcode) {
  564.     restorecommands(fmc,moreconfigs);
  565. } else {
  566.     freeconfig(fmc,ofmc);
  567.     fmc=0;
  568. }
  569. restorecommands(0,moreconfigs);
  570. freemem(fmc);
  571. return(retcode);
  572. }
  573.  
  574. #include "oldconfig.h"
  575. static void readoldconfig(UBYTE *rletemp)
  576. {
  577. struct CMenuConfig *cmc;
  578. struct OwnCommand *oc;
  579. struct FMConfig3022 *fmcold;
  580. struct OwnCommand3022 *ocold;
  581. UBYTE *ptr;
  582. WORD cnt1;
  583.  
  584. fmcold=allocmem(sizeof(struct FMConfig3022));
  585. if(!fmcold) goto error;
  586. rleunpack(rletemp,fmcold,sizeof(struct FMConfig3022));
  587. cmc=&fmconfig->cmenuconfig[BUILDCOMMANDS];
  588. /*
  589. ptr=&fmcold->cmenuconfig[0];
  590. for(cnt1=0;cnt1<MAXCMENUS3022;cnt1++) {
  591.     if(cnt1<4) cmc->position=2; else cmc->position=1;
  592.     cmc->frontpen=ptr[3];
  593.     cmc->backpen=ptr[4];
  594.     cmc->priority=ptr[5];
  595.     ptr+=CMENUCONFIGSIZE3022;
  596.     cmc++;
  597. }
  598. cmc++;
  599. */
  600. ptr=&fmcold->cmenuownconfig[0];
  601. for(cnt1=0;cnt1<MAXCOMMANDS3022;cnt1++) {
  602.     ocold=&fmcold->owncommand[cnt1];
  603.     if(ocold->gadgetname[0]) {
  604.         cmc->moreconfig=allocmem(sizeof(struct OwnCommand));
  605.         if(cmc->moreconfig) {
  606.             oc=(struct OwnCommand*)cmc->moreconfig;
  607.             cmc->moreconfiglen=sizeof(struct OwnCommand);
  608.             cmc->cmenucount=100;
  609.             cmc->position=1;
  610.             cmc->frontpen=ptr[3];
  611.             cmc->backpen=ptr[4];
  612.             cmc->priority=ptr[5];
  613.             strcpy(cmc->label,ocold->gadgetname);
  614.             strcpy(oc->namematch,ocold->namematch);
  615.             strcpy(oc->matchbytes,ocold->matchbytes);
  616.             strcpy(oc->command,ocold->command);
  617.             oc->ef.stack=ocold->stack;
  618.             cmc++;
  619.         }
  620.     }
  621.     ptr+=CMENUCONFIGSIZE3022;
  622. }
  623. error:
  624. freemem(fmcold);
  625. }
  626.  
  627. void readconfig(void)
  628. {
  629. BPTR handle=0;
  630. UBYTE *rletemp=0;
  631. UBYTE *ptr1;
  632. UWORD apu2,apu1;
  633. WORD cnt1;
  634. struct CMenuConfig *cmc;
  635. LONG len;
  636. UBYTE *vara2;
  637.  
  638. handle=Open("ENV:fm.prefs",1005);
  639. if(!handle) handle=Open("ENVARC:fm.prefs",1005);
  640. if(!handle) handle=Open("S:fm.prefs",1005);
  641. if(!handle) goto error;
  642.  
  643. Seek(handle,0,OFFSET_END);
  644. len=Seek(handle,0,OFFSET_BEGINNING)-6;
  645. vara2=allocmem(HELPCONFIGSIZE);
  646. rletemp=allocmem(len);
  647. if(!rletemp||!vara2) goto error;
  648.  
  649. Read(handle,&apu2,2);
  650. if(apu2!='FM') goto error;
  651. Read(handle,&apu2,2);
  652. if(apu2!=OLDCONFIGVERSION&&apu2!=FMCONFIGVERSION) {
  653.     errorreq(MSG_MAIN_WARNING,getstring(MSG_CONFIG_OLDCONFIG),0,MSG_OK);
  654.     goto error;
  655. }
  656. Read(handle,&apu1,2);
  657. if(Read(handle,rletemp,len)!=len) goto error;
  658. if(apu2==OLDCONFIGVERSION) {
  659.     readoldconfig(rletemp);
  660. } else {
  661.     ptr1=rleunpack(rletemp,fmconfig,apu1);
  662.     for(cnt1=0;cnt1<TOTALCOMMANDS;cnt1++) {
  663.         cmc=&fmconfig->cmenuconfig[cnt1];
  664.         ptr1=rleunpack(ptr1,vara2,HELPCONFIGSIZE);
  665.         if(cmc->moreconfiglen) {
  666.             cmc->moreconfig=allocvec(0,cmc->moreconfiglen,MEMF_CLEAR|MEMF_PUBLIC);
  667.             if(!cmc->moreconfig) goto error;
  668.             CopyMem(vara2,cmc->moreconfig,cmc->moreconfiglen);
  669.         }
  670.     }
  671. }
  672. error:
  673. if(handle) Close(handle);
  674. freemem(rletemp);
  675. freemem(vara2);
  676. }
  677.  
  678. void writeconfig(struct FMConfig *fmc)
  679. {
  680. BPTR handle;
  681. LONG size;
  682. UBYTE *rletemp,*ptr1;
  683. UBYTE ident[6];
  684. WORD apu1,cnt1;
  685. void *moreconfigs[TOTALCOMMANDS];
  686. struct CMenuConfig *cmc;
  687. UBYTE empty[HELPCONFIGSIZE];
  688. UBYTE vara2[HELPCONFIGSIZE];
  689.  
  690. ident[0]='F';
  691. ident[1]='M';
  692. ident[2]=0;
  693. ident[3]=FMCONFIGVERSION;
  694. ident[4]=(UBYTE)((sizeof(struct FMConfig)>>8)&0xff);
  695. ident[5]=(UBYTE)((sizeof(struct FMConfig))&0xff);
  696.  
  697. memseti(empty,0,HELPCONFIGSIZE);
  698. fmmain.myproc->pr_WindowPtr=(APTR)-1;
  699. for(cnt1=0;cnt1<TOTALCOMMANDS;cnt1++) {
  700.     cmc=&fmc->cmenuconfig[cnt1];
  701.     moreconfigs[cnt1]=cmc->moreconfig;
  702.     cmc->moreconfig=0;
  703. }
  704. fmc->txtfontattr.ta_Name=0;
  705. fmc->listfontattr.ta_Name=0;
  706. fmc->reqfontattr.ta_Name=0;
  707. fmc->txtshowfontattr.ta_Name=0;
  708. fmc->smallfontattr.ta_Name=0;
  709.  
  710. rletemp=allocmem(sizeof(struct FMConfig)+TOTALCOMMANDS*HELPCONFIGSIZE);
  711. if(!rletemp) goto error;
  712. size=rlepack(fmc,rletemp,sizeof(struct FMConfig));
  713. for(cnt1=0;cnt1<TOTALCOMMANDS;cnt1++) {
  714.     cmc=&fmc->cmenuconfig[cnt1];
  715.     if(cmc->moreconfiglen) {
  716.         memseti(vara2,0,HELPCONFIGSIZE);
  717.         CopyMem(moreconfigs[cnt1],vara2,cmc->moreconfiglen);
  718.         ptr1=vara2;
  719.     } else {
  720.         ptr1=empty;
  721.     }
  722.     size+=rlepack(ptr1,rletemp+size,HELPCONFIGSIZE);
  723. }
  724. apu1=0;
  725. DeleteFile("ENV:fm.prefs");
  726. DeleteFile("ENVARC:fm.prefs");
  727. DeleteFile("S:fm.prefs");
  728. handle=Open("ENV:fm.prefs",1006);
  729. if(handle) {
  730.     Write(handle,ident,sizeof(ident));
  731.     Write(handle,rletemp,size);
  732.     Close(handle);
  733. }
  734. handle=Open("ENVARC:fm.prefs",1006);
  735. if(handle) {
  736.     Write(handle,ident,sizeof(ident));
  737.     Write(handle,rletemp,size);
  738.     Close(handle);
  739.     apu1=1;
  740. }
  741. if(!apu1) {
  742.     handle=Open("S:fm.prefs",1006);
  743.     if(handle) {
  744.         Write(handle,ident,sizeof(ident));
  745.         Write(handle,rletemp,size);
  746.         Close(handle);
  747.     }
  748. }
  749. error:
  750. for(cnt1=0;cnt1<TOTALCOMMANDS;cnt1++) {
  751.     fmc->cmenuconfig[cnt1].moreconfig=moreconfigs[cnt1];
  752. }
  753. fmc->txtfontattr.ta_Name=fmc->txtfontname;
  754. fmc->listfontattr.ta_Name=fmc->listfontname;
  755. fmc->reqfontattr.ta_Name=fmc->reqfontname;
  756. fmc->txtshowfontattr.ta_Name=fmc->txtshowfontname;
  757. fmc->smallfontattr.ta_Name=fmc->smallfontname;
  758. fmmain.myproc->pr_WindowPtr=fmmain.ikkuna;
  759. freemem(rletemp);
  760. }
  761.  
  762. void commandanswer(struct GUIBase *gb)
  763. {
  764. buttonbarmsg(gb,MSG_OK,1,MSG_CANCEL,0,0);
  765. }
  766.  
  767. WORD allocconfig(struct CMenuConfig *cmc,WORD len)
  768. {
  769. if(cmc->moreconfig) return(-1);
  770. cmc->moreconfig=allocvec(0,len,MEMF_CLEAR|MEMF_PUBLIC);
  771. if(!cmc->moreconfig) return(0);
  772. cmc->moreconfiglen=len;
  773. return(1);
  774. }
  775.  
  776. struct CMenuConfig *getconfignumber(WORD num)
  777. {
  778. WORD cnt;
  779. struct CMenuConfig *cmc;
  780.  
  781. for(cnt=0;cnt<TOTALCOMMANDS;cnt++) {
  782.     cmc=&fmconfig->cmenuconfig[cnt];
  783.     if(cmc->cmenucount==num) {
  784.         getconfig(cmc);
  785.         return(cmc);
  786.     }
  787. }
  788. return(0);
  789. }
  790.  
  791. void *getconfig(struct CMenuConfig *cmc)
  792. {
  793. if(!cmc->moreconfig) {
  794.     switch(cmc->cmenucount)
  795.     {
  796.     case 100:
  797.     ownexecuteconfigdefault(cmc);
  798.     break;
  799.     case INCLUDECONFIG:
  800.     case PARSECONFIG:
  801.     case EXCLUDECONFIG:
  802.     parseconfigdefault(cmc);
  803.     break;
  804.     case SLEEPCONFIG:
  805.     sleepconfigdefault(cmc);
  806.     break;
  807.     case QUITCONFIG:
  808.     quitconfigdefault(cmc);
  809.     break;
  810.     case PARENTCONFIG:
  811.     parentconfigdefault(cmc);
  812.     break;
  813.     case COPYCONFIG:
  814.     case COPYASCONFIG:
  815.     case MOVECONFIG:
  816.     copyconfigdefault(cmc);
  817.     break;
  818.     case DELETECONFIG:
  819.     deleteconfigdefault(cmc);
  820.     break;
  821.     case SHOWASCCONFIG:
  822.     case SHOWHEXCONFIG:
  823.     showtextconfigdefault(cmc);
  824.     break;
  825.     case EXECUTECONFIG:
  826.     executeconfigdefault(cmc);
  827.     break;
  828.     case HEARCONFIG:
  829.     hearconfigdefault(cmc);
  830.     break;
  831.     case DISKEDITCONFIG:
  832.     diskeditconfigdefault(cmc);
  833.     break;
  834.     }
  835. }
  836. return(cmc->moreconfig);
  837. }
  838.  
  839. __saveds __asm APTR dlldisplayhookfunc(register __a0 struct Hook *hook,register __a2 Object *obj,register __a1 struct lvRender *lvr)
  840. {
  841. UBYTE *str;
  842. struct DirListLayout *dll=(struct DirListLayout*)lvr->lvr_Entry;
  843. switch(dll->type)
  844. {
  845. case 0:
  846. str=getstring(MSG_PARSE_SIZEMATCH);
  847. break;
  848. case 1:
  849. str=getstring(MSG_PARSE_NAMEMATCH);
  850. break;
  851. case 2:
  852. str=getstring(MSG_PARSE_PROTMATCH);
  853. break;
  854. case 3:
  855. str=getstring(MSG_PARSE_DATEMATCH);
  856. break;
  857. case 4:
  858. str=getstring(MSG_PARSE_COMMENTMATCH);
  859. break;
  860. }
  861. return(str);
  862. }
  863.  
  864. __saveds __asm APTR dllresourcehookfunc(register __a0 struct Hook *hook,register __a2 Object *obj,register __a1 struct lvResource *lvr)
  865. {
  866. struct DirListLayout *dll=0;
  867.  
  868. switch(lvr->lvr_Command)
  869. {
  870. case LVRC_MAKE:
  871. dll=AllocVec(sizeof(struct DirListLayout),0);
  872. if(dll) {
  873.     CopyMem(lvr->lvr_Entry,dll,sizeof(struct DirListLayout));
  874. }
  875. break;
  876. case LVRC_KILL:
  877. FreeVec(lvr->lvr_Entry);
  878. break;
  879. }
  880. return(dll);
  881. }
  882.  
  883.  
  884. struct Hook dllresourcehook = { NULL, NULL, (HOOKFUNC)dllresourcehookfunc, NULL, NULL };
  885. struct Hook dlldisplayhook  = { NULL, NULL, (HOOKFUNC)dlldisplayhookfunc,  NULL, NULL };
  886.  
  887. struct DirListLayout *setdllgads(struct GUIBase *gb,struct GUISlot *gs)
  888. {
  889. ULONG data;
  890. struct DirListLayout *dll;
  891.  
  892. GetAttr(LISTV_LastClicked,gs->obj,&data);
  893. dll=(struct DirListLayout*)data;
  894. setobject(gb,10,dll->width);
  895. setobject(gb,11,dll->rightaligned);
  896. setobject(gb,12,dll->rightlock);
  897. return(dll);
  898. }
  899.  
  900. WORD dirlayoutconfig(struct FMConfig *ofmc)
  901. {
  902. struct FMConfig *fmc;
  903. struct GUIBase *gb;
  904. struct GUISlot *gs1;
  905. struct DirListLayout *dll;
  906. Class *ddlistclass;
  907. WORD cnt1;
  908. WORD lock,align;
  909. LONG fw;
  910. WORD ret;
  911.  
  912. if(!(fmc=newconfig(ofmc))) return(0);
  913.  
  914. gb=getguibase(getstring(MSG_CONFIG_NAME));
  915. setconnectgroup(gb,1,0,0);
  916.  
  917. ddlistclass=InitFLClass();
  918.  
  919. gs1=getguislot(gb,NewObject(ddlistclass,0,
  920.     GA_ID,20,
  921.     LAB_Label,getstring(MSG_CONFIG_LAYOUT_DIRLIST),
  922.     LAB_Place,PLACE_ABOVE,
  923.     LISTV_ShowDropSpot,TRUE,
  924.     LISTV_MinEntriesShown,8,
  925.     LISTV_SortEntryArray,FALSE,
  926.     LISTV_ListFont,&fmc->listfontattr,
  927.     LISTV_ResourceHook,&dllresourcehook,
  928.     LISTV_DisplayHook,&dlldisplayhook,
  929.     BT_DragObject,TRUE,
  930.     BT_DropObject,TRUE,
  931.     TAG_DONE),20,LISTVIEW_KIND,0);
  932.  
  933. setconnectgroup(gb,2,1,1);
  934. if(!gs1) goto error;
  935.  
  936. fw=0;align=0;lock=0;
  937.  
  938. reqinfomsg(gb,MSG_CONFIG_LAYOUT_WIDTH,10,guiUC|guiCENTER);
  939. reqinteger(gb,10,&fw,1,99);
  940. reqinfomsg(gb,MSG_CONFIG_LAYOUT_RIGHTALIGNMENT,11,guiUC|guiCENTER);
  941. reqcycle2msg(gb,11,&align);
  942. reqinfomsg(gb,MSG_CONFIG_LAYOUT_RIGHTLOCK,12,guiUC|guiCENTER);
  943. reqcycle2msg(gb,12,&lock);
  944.  
  945. for(cnt1=0;cnt1<5;cnt1++) {
  946.     dll=&fmc->dl[cnt1];
  947.     BGUI_DoGadgetMethod(gs1->obj,0,0,LVM_ADDSINGLE,0,dll,LVAP_TAIL,0);
  948. }
  949. SetAttrs(gs1->obj,LISTV_Select,0,TAG_DONE);
  950.  
  951. buttonbarmsg(gb,MSG_OK,1,MSG_CANCEL,0,0);
  952. if(openinitreq(gb)) {
  953.     dll=setdllgads(gb,gs1);
  954.     for(;;) {
  955.         ret=reqmsghandler(gb);
  956.         if(ret==1) {
  957.             closereq(gb);
  958.             dll=(struct DirListLayout*)DoMethod(gs1->obj,LVM_FIRSTENTRY,0,0,TAG_DONE);
  959.             cnt1=0;
  960.             do {
  961.                 CopyMem(dll,&fmc->dl[cnt1],sizeof(struct DirListLayout));
  962.                 dll=(struct DirListLayout*)DoMethod(gs1->obj,LVM_NEXTENTRY,dll,0,TAG_DONE);
  963.                 cnt1++;
  964.             } while(dll);
  965.             freeconfig(fmc,ofmc);
  966.             fmc=0;
  967.         }
  968.         if(ret<2) break;
  969.         switch(ret)
  970.         {
  971.         case 20:
  972.         dll=setdllgads(gb,gs1);
  973.         break;
  974.         case 10:
  975.         dll->width=fw;
  976.         break;
  977.         case 11:
  978.         dll->rightaligned=align;
  979.         break;
  980.         case 12:
  981.         dll->rightlock=lock;
  982.         break;
  983.         }
  984.     }
  985. }
  986. error:
  987. freereq(gb);
  988. if(ddlistclass) FreeClass(ddlistclass);
  989. freemem(fmc);
  990. return(0);
  991. }
  992.  
  993.  
  994. //***************************
  995. //    SCREEN
  996. //***************************
  997.  
  998. WORD screenconfig(struct FMConfig *ofmc)
  999. {
  1000. struct GUIBase *gb;
  1001. WORD c;
  1002. WORD apu1,apu2;
  1003. WORD refresh=0;
  1004. UBYTE *ptr1,*ptr2;
  1005. WORD stype,windowed;
  1006. LONG flags;
  1007. UBYTE *buf=0;
  1008. struct FMConfig *fmc=0;
  1009.  
  1010. if(!(fmc=newconfig(ofmc))) goto error;;
  1011. if(!(buf=allocmem(1000))) goto error;
  1012.  
  1013. for(;;) {
  1014.     ptr1=buf;
  1015.     gb=getguibase(getstring(MSG_CONFIG_NAME));
  1016.  
  1017.     sformatmsg(ptr1,MSG_CONFIG_SCRFORMAT,getstring(MSG_CONFIG_MAINSCREEN),fmc->mainscreen.width,fmc->mainscreen.height,fmc->mainscreen.depth,fmc->mainscreen.screenmode);
  1018.     reqbutton(gb,ptr1,10,guiUC|guiCENTER);
  1019.     ptr1+=strlen(ptr1)+1;
  1020.     sformatmsg(ptr1,MSG_CONFIG_SCRFORMAT,getstring(MSG_CONFIG_TEXTSCREEN),fmc->textscreen.width,fmc->textscreen.height,fmc->textscreen.depth,fmc->textscreen.screenmode);
  1021.     reqbutton(gb,ptr1,11,guiUC|guiCENTER);
  1022.     ptr1+=strlen(ptr1)+1;
  1023.  
  1024.     sformatmsg(ptr1,MSG_CONFIG_FONTFORMAT,getstring(MSG_CONFIG_TEXTFONT),fmc->txtfontattr.ta_Name,fmc->txtfontattr.ta_YSize);
  1025.     reqbutton(gb,ptr1,12,guiUC|guiCENTER);
  1026.     ptr1+=strlen(ptr1)+1;
  1027.     sformatmsg(ptr1,MSG_CONFIG_FONTFORMAT,getstring(MSG_CONFIG_LISTFONT),fmc->listfontattr.ta_Name,fmc->listfontattr.ta_YSize);
  1028.     reqbutton(gb,ptr1,13,guiUC|guiCENTER);
  1029.     ptr1+=strlen(ptr1)+1;
  1030.     sformatmsg(ptr1,MSG_CONFIG_FONTFORMAT,getstring(MSG_CONFIG_REQFONT),fmc->reqfontattr.ta_Name,fmc->reqfontattr.ta_YSize);
  1031.     reqbutton(gb,ptr1,14,guiUC|guiCENTER);
  1032.     ptr1+=strlen(ptr1)+1;
  1033.     sformatmsg(ptr1,MSG_CONFIG_FONTFORMAT,getstring(MSG_CONFIG_SHOWFONT),fmc->txtshowfontattr.ta_Name,fmc->txtshowfontattr.ta_YSize);
  1034.     reqbutton(gb,ptr1,15,guiUC|guiCENTER);
  1035.     ptr1+=strlen(ptr1)+1;
  1036.  
  1037.     ptr2=ptr1;
  1038.     ptr1=stpcpy(ptr1,getstring(MSG_CONFIG_LAYOUT));
  1039.     *ptr1++=32;
  1040.     apu1=0;
  1041.     while(fmc->listinfo[apu1][0]) {
  1042.         apu2=1;
  1043.         while(fmc->listinfo[apu1][apu2]&0x7f) apu2++;
  1044.         if(apu1) *ptr1++='/';
  1045.         *ptr1++=apu2-1+'0';
  1046.         apu1++;
  1047.     }
  1048.     *ptr1++=0;
  1049.     reqbutton(gb,ptr2,16,guiUC|guiCENTER);
  1050.  
  1051.     reqbuttonmsg(gb,MSG_CONFIG_DIRLAYOUT,17,guiUC|guiCENTER);
  1052.  
  1053.     reqbuttonmsg(gb,MSG_CONFIG_PALETTE,18,guiUC|guiCENTER);
  1054.  
  1055.     setconnectgroup(gb,9,0,0);
  1056.  
  1057.     setconnectgroup(gb,1,1,9);
  1058.     reqinfomsg(gb,MSG_CONFIG_SCREENWINDOW,90,guiUC|guiLEFT);
  1059.     stype=fmc->screentype;
  1060.     reqcyclemsg(gb,90,&stype,MSG_CONFIG_SCREENTYPE1,MSG_CONFIG_SCREENTYPE2,MSG_CONFIG_SCREENTYPE3,0);
  1061.     setconnectgroup(gb,2,1,9);
  1062.     windowed=(fmc->flags&MWINDOWED)?1:0;
  1063.     reqcycle2msg(gb,100,&windowed);
  1064.     reqstring(gb,101,fmc->pubscreen,sizeof(fmc->pubscreen));
  1065.  
  1066.     buttonbarmsg(gb,MSG_OK,1,MSG_CANCEL,0,0);
  1067.  
  1068.     c=0;
  1069.     if(openinitreq(gb)) {
  1070.         do {
  1071.             apu1=getobject(gb,90);
  1072.             if(apu1==2) denaobject(gb,101,0); else denaobject(gb,101,1);
  1073.             c=reqmsghandler(gb);
  1074.         } while(c>=90);
  1075.         closereq(gb);
  1076.     }
  1077.  
  1078.     switch(c)
  1079.     {
  1080.     case 10:
  1081.     refresh=askscreen(&fmc->mainscreen,MSG_CONFIG_MAINSCREEN,TRUE);
  1082.     break;
  1083.     case 11:
  1084.     refresh=askscreen(&fmc->textscreen,MSG_CONFIG_TEXTSCREEN,FALSE);
  1085.     break;
  1086.     case 12:
  1087.     refresh=askfont(&fmc->txtfontattr,MSG_CONFIG_TEXTFONT,TRUE);
  1088.     break;
  1089.     case 13:
  1090.     refresh=askfont(&fmc->listfontattr,MSG_CONFIG_LISTFONT,FALSE);
  1091.     break;
  1092.     case 14:
  1093.     refresh=askfont(&fmc->reqfontattr,MSG_CONFIG_REQFONT,TRUE);
  1094.     break;
  1095.     case 15:
  1096.     refresh=askfont(&fmc->txtshowfontattr,MSG_CONFIG_SHOWFONT,FALSE);
  1097.     break;
  1098.     case 16:
  1099. //    refresh=layoutconfig(fmc);
  1100.     break;
  1101.     case 17:
  1102.     refresh=dirlayoutconfig(fmc);
  1103.     break;
  1104.     case 18:
  1105.     refresh=palette(fmc);
  1106.     break;
  1107.     }
  1108.     flags=fmc->flags;
  1109.     fmc->flags&=~(MWINDOWED|MVSCROLL|MHSCROLL);
  1110.     if (windowed) fmc->flags|=MWINDOWED;
  1111.  
  1112.     if(flags!=fmc->flags) refresh=3;
  1113.     if(fmc->screentype!=stype) refresh=3;
  1114.     fmc->screentype=stype;
  1115.     if(c==1) {
  1116.         if(!refresh) refresh=1;
  1117.         freeconfig(fmc,ofmc);
  1118.         fmc=0;
  1119.     }
  1120.     if(c<10) break;
  1121. }
  1122. error:
  1123. freemem(fmc);
  1124. freemem(buf);
  1125. return(refresh);
  1126. }
  1127.  
  1128. /* COMMAND CONFIG */
  1129.  
  1130. struct cmenudata {
  1131.     UBYTE name[32];
  1132.     struct CMenuConfig *cmc;
  1133. };
  1134.  
  1135. static void rescanbuttonconfig(struct FMConfig *fmc,struct GUISlot *gs[])
  1136. {
  1137. struct cmenudata *cmd;
  1138. struct CMenuConfig *cmcbuf;
  1139. struct CMenuConfig *cmc;
  1140. WORD cnt1;
  1141. APTR entry;
  1142.  
  1143. cmcbuf=allocmem(TOTALCOMMANDS*sizeof(struct CMenuConfig));
  1144. if(!cmcbuf) return;
  1145. cnt1=0;
  1146. cmc=cmcbuf;
  1147. // CORNER
  1148. if((entry=(APTR)DoMethod(gs[2]->obj,LVM_FIRSTENTRY,NULL,0L))) {
  1149.     do {
  1150.         cmd=(struct cmenudata*)entry;
  1151.         CopyMem(cmd->cmc,cmc,sizeof(struct CMenuConfig));
  1152.         cmc->position=2;
  1153.         cmc++;
  1154.         cnt1++;
  1155.         entry=(APTR)DoMethod(gs[2]->obj,LVM_NEXTENTRY,entry,0L);
  1156.     } while(entry);
  1157. }
  1158. // BAR
  1159. if((entry=(APTR)DoMethod(gs[1]->obj,LVM_FIRSTENTRY,NULL,0L))) {
  1160.     do {
  1161.         cmd=(struct cmenudata*)entry;
  1162.         CopyMem(cmd->cmc,cmc,sizeof(struct CMenuConfig));
  1163.         cmc->position=1;
  1164.         cmc++;
  1165.         cnt1++;
  1166.         entry=(APTR)DoMethod(gs[1]->obj,LVM_NEXTENTRY,entry,0L);
  1167.     } while(entry);
  1168. }
  1169. // HIDDEN
  1170. if((entry=(APTR)DoMethod(gs[3]->obj,LVM_FIRSTENTRY,NULL,0L))) {
  1171.     do {
  1172.         cmd=(struct cmenudata*)entry;
  1173.         CopyMem(cmd->cmc,cmc,sizeof(struct CMenuConfig));
  1174.         cmc->position=9;
  1175.         cmc++;
  1176.         cnt1++;
  1177.         entry=(APTR)DoMethod(gs[3]->obj,LVM_NEXTENTRY,entry,0L);
  1178.     } while(entry);
  1179. }
  1180. while(cnt1<TOTALCOMMANDS) {
  1181.     memseti(cmc,0,sizeof(struct CMenuConfig));
  1182.     cmc->position=0xff;
  1183.     cmc++;
  1184.     cnt1++;
  1185. }
  1186. CopyMem(cmcbuf,fmc->cmenuconfig,TOTALCOMMANDS*sizeof(struct CMenuConfig));
  1187. freemem(cmcbuf);
  1188. }
  1189.  
  1190. static struct CMenuConfig *findnewcmc(struct FMConfig *fmc)
  1191. {
  1192. struct CMenuConfig *cmc;
  1193. WORD cnt1;
  1194.  
  1195. for(cnt1=0;cnt1<TOTALCOMMANDS;cnt1++) {
  1196.     cmc=&fmc->cmenuconfig[cnt1];
  1197.     if(cmc->position==0xff) break;
  1198. }
  1199. if(cnt1==TOTALCOMMANDS) {
  1200.     cmc=0;
  1201.     request(getstring(MSG_CONFIG_NAME),MSG_OK,0,getstring(MSG_CONFIG_COMSLOTSFULL));
  1202. }
  1203. if(cmc) {
  1204.     cmc->priority=1;
  1205.     cmc->frontpen=fmc->txtpen;
  1206.     cmc->backpen=fmc->backpen;
  1207. }
  1208. return(cmc);
  1209. }
  1210.  
  1211. static void newbuildin(struct FMConfig *fmc,struct CMenuConfig *cmc)
  1212. {
  1213. struct CMenuConfig *newcmc;
  1214. WORD cnt1;
  1215.  
  1216. newcmc=findnewcmc(fmc);
  1217. if(!newcmc) return;
  1218. cnt1=findbuild(cmc);
  1219. if(cnt1) {
  1220.     newcmc->position=cmc->position;
  1221.     newcmc->cmenucount=cnt1;
  1222.     memcpy(newcmc->label,cmc->label,sizeof(cmc->label));
  1223.     newcmc->label[sizeof(cmc->label)-1]=0;
  1224.     commandconfig(fmc,newcmc);
  1225. } else {
  1226.     newcmc->position=0xff;
  1227. }
  1228. }
  1229.  
  1230. WORD findbuild(struct CMenuConfig *cmc)
  1231. {
  1232. WORD cnt1;
  1233. UBYTE *ptr1;
  1234.  
  1235. ptr1=getstring(MSG_MAIN_CMENULABEL);
  1236. cnt1=1;
  1237. while(*ptr1) {
  1238.     if(!strcmp(ptr1,cmc->label)) return(cnt1);
  1239.     cnt1++;
  1240.     ptr1+=strlen(ptr1)+1;
  1241. }
  1242. return(0);
  1243. }
  1244. UBYTE *findbuildstring(struct CMenuConfig *cmc)
  1245. {
  1246. UBYTE *ptr1;
  1247. WORD cnt1;
  1248.  
  1249. ptr1=getstring(MSG_MAIN_CMENULABEL);
  1250. cnt1=cmc->cmenucount;
  1251. if(cnt1>=100) return(getstring(MSG_CONFIG_COMUSERCOMMAND));
  1252. cnt1--;
  1253. while(cnt1--) ptr1+=strlen(ptr1)+1;
  1254. return(ptr1);
  1255. }
  1256.  
  1257. static void newuser(struct FMConfig *fmc)
  1258. {
  1259. struct CMenuConfig *newcmc;
  1260.  
  1261. newcmc=findnewcmc(fmc);
  1262. if(!newcmc) return;
  1263. if(!ownexecuteconfigdefault(newcmc)) return;
  1264. newcmc->cmenucount=100;
  1265. newcmc->position=1;
  1266. commandconfig(fmc,newcmc);
  1267. }
  1268.  
  1269. static void gsdoubleclick(struct FMConfig *fmc,struct GUISlot *gs[],struct GUISlot *obj,void *data)
  1270. {
  1271. struct CMenuConfig cmc2,*cmc3,*cmc;
  1272. struct GUIBase *gb;
  1273. WORD flags,ret,buildin;
  1274. UBYTE vara[80];
  1275.  
  1276. flags=buildin=0;
  1277. if(obj==gs[0]) {
  1278.     memseti(&cmc2,0,sizeof(struct CMenuConfig));
  1279.     strcpy(cmc2.label,(UBYTE*)data);
  1280.     cmc=&cmc2;
  1281.     flags=8|16;
  1282.     buildin=1;
  1283. } else {
  1284.     cmc=((struct cmenudata*)data)->cmc;
  1285. }
  1286. if(obj==gs[1]) flags=2|4|128|32;
  1287. if(obj==gs[2]) flags=1|4|128|32;
  1288. if(obj==gs[3]) flags=1|2|128|32;
  1289.  
  1290. sformat(vara,"%s ('%s')",getstring(MSG_CONFIG_NAME),cmc->label);
  1291. gb=getguibase(vara);
  1292. setconnectgroup(gb,1,1,0);
  1293. if(!buildin) reqbuttonmsg(gb,MSG_CONFIG_COMEDITCONFIG,4,0);
  1294. if(flags&1) reqbuttonmsg(gb,MSG_CONFIG_COMMOVEGADGETBAR,5,0);
  1295. if(flags&2) reqbuttonmsg(gb,MSG_CONFIG_COMMOVECORNERMENU,6,0);
  1296. if(flags&4) reqbuttonmsg(gb,MSG_CONFIG_COMMOVEHIDDEN,7,0);
  1297. if(flags&8) reqbuttonmsg(gb,MSG_CONFIG_COMCOPYGADGETBAR,5,0);
  1298. if(flags&16) reqbuttonmsg(gb,MSG_CONFIG_COMCOPYCORNERMENU,6,0);
  1299. if(flags&32) reqbuttonmsg(gb,MSG_CONFIG_COMDUPLICATECOMMAND,3,0);
  1300. if(flags&128) reqbuttonmsg(gb,MSG_CONFIG_COMREMOVECOMMAND,8,0);
  1301. reqbuttonmsg(gb,MSG_CONFIG_COMNEWUSERCOMMAND,9,0);
  1302. buttonbarmsg(gb,MSG_OK,1,0);
  1303. ret=quickreq(gb);
  1304. switch(ret)
  1305.     {
  1306.     case 3:
  1307.     cmc3=findnewcmc(fmc);
  1308.     if(cmc3) {
  1309.         CopyMem(cmc,cmc3,sizeof(struct CMenuConfig));
  1310.         if(cmc->moreconfig) {
  1311.             cmc3->moreconfig=allocmem(cmc->moreconfiglen);
  1312.             if(cmc3->moreconfig) CopyMem(cmc->moreconfig,cmc3->moreconfig,cmc->moreconfiglen);
  1313.         }
  1314.     }
  1315.     break;
  1316.     case 4:
  1317.     commandconfig(fmc,cmc);
  1318.     break;
  1319.     case 5:
  1320.     cmc->position=1;
  1321.     if(buildin) newbuildin(fmc,cmc);
  1322.     break;
  1323.     case 6:
  1324.     cmc->position=2;
  1325.     if(buildin) newbuildin(fmc,cmc);
  1326.     break;
  1327.     case 7:
  1328.     cmc->position=9;
  1329.     break;
  1330.     case 8:
  1331.     cmc->position=0xff;
  1332.     freemem(cmc->moreconfig);
  1333.     cmc->moreconfig=0;
  1334.     cmc->moreconfiglen=0;
  1335.     break;
  1336.     case 9:
  1337.     newuser(fmc);
  1338.     break;
  1339. }
  1340. }
  1341.  
  1342. static void refreshcommands(struct FMConfig *fmc,struct GUIBase *gb,struct GUISlot *gs[])
  1343. {
  1344. struct CMenuConfig *cmc;
  1345. WORD cnt1;
  1346. UBYTE *ptr1;
  1347. UBYTE bap1;
  1348.  
  1349. BGUI_DoGadgetMethod(gs[0]->obj,0,0,LVM_CLEAR,0);
  1350. BGUI_DoGadgetMethod(gs[1]->obj,0,0,LVM_CLEAR,0);
  1351. BGUI_DoGadgetMethod(gs[2]->obj,0,0,LVM_CLEAR,0);
  1352. BGUI_DoGadgetMethod(gs[3]->obj,0,0,LVM_CLEAR,0);
  1353. ptr1=getstring(MSG_MAIN_CMENULABEL);
  1354. for(cnt1=0;cnt1<BUILDCOMMANDS;cnt1++) {
  1355.     BGUI_DoGadgetMethod(gs[0]->obj,0,0,LVM_ADDSINGLE,0,ptr1,LVAP_SORTED,0);
  1356.     ptr1+=strlen(ptr1)+1;
  1357. }
  1358. for(cnt1=0;cnt1<TOTALCOMMANDS;cnt1++) {
  1359.     cmc=&fmc->cmenuconfig[cnt1];
  1360.     bap1=cmc->position;
  1361.     if(bap1==1) {
  1362.         BGUI_DoGadgetMethod(gs[1]->obj,0,0,LVM_ADDSINGLE,0,cmc,LVAP_TAIL,0);
  1363.     } else if(bap1==2) {
  1364.         BGUI_DoGadgetMethod(gs[2]->obj,0,0,LVM_ADDSINGLE,0,cmc,LVAP_TAIL,0);
  1365.     } else if(bap1==9) {
  1366.         BGUI_DoGadgetMethod(gs[3]->obj,0,0,LVM_ADDSINGLE,0,cmc,LVAP_TAIL,0);
  1367.     }
  1368. }
  1369. BGUI_DoGadgetMethod(gs[0]->obj,gb->win,0,LVM_REFRESH,0);
  1370. BGUI_DoGadgetMethod(gs[1]->obj,gb->win,0,LVM_REFRESH,0);
  1371. BGUI_DoGadgetMethod(gs[2]->obj,gb->win,0,LVM_REFRESH,0);
  1372. BGUI_DoGadgetMethod(gs[3]->obj,gb->win,0,LVM_REFRESH,0);
  1373. }
  1374.  
  1375. __saveds __asm APTR comdisplayhookfunc(register __a0 struct Hook *hook,register __a2 Object *obj,register __a1 struct lvRender *lvr)
  1376. {
  1377. struct cmenudata *cmd=(struct cmenudata*)lvr->lvr_Entry;
  1378. return(cmd->name);
  1379. }
  1380.  
  1381. __saveds __asm APTR comresourcehookfunc(register __a0 struct Hook *hook,register __a2 Object *obj,register __a1 struct lvResource *lvr)
  1382. {
  1383. struct CMenuConfig *cmc;
  1384. struct cmenudata *cmd;
  1385. UBYTE *vara;
  1386.  
  1387. switch(lvr->lvr_Command)
  1388. {
  1389. case LVRC_MAKE:
  1390. cmd=AllocVec(sizeof(struct cmenudata),0);
  1391. if(cmd) {
  1392.     cmc=(struct CMenuConfig*)lvr->lvr_Entry;
  1393.     cmd->cmc=cmc;
  1394.     vara=cmd->name;
  1395.     vara[0]='(';
  1396.     if(cmc->cmenucount==100) {
  1397.         vara[1]=getstring(MSG_CONFIG_COMBUILDUSERKEY)[1];
  1398.     } else {
  1399.         vara[1]=getstring(MSG_CONFIG_COMBUILDUSERKEY)[0];
  1400.     }
  1401.     vara[2]=')';
  1402.     vara[3]=' ';
  1403.     strcpy(vara+4,cmc->label);
  1404. }
  1405. break;
  1406. case LVRC_KILL:
  1407. FreeVec(lvr->lvr_Entry);
  1408. break;
  1409. }
  1410. return(cmd);
  1411. }
  1412.  
  1413. struct Hook comresourcehook = { NULL, NULL, (HOOKFUNC)comresourcehookfunc, NULL, NULL };
  1414. struct Hook comdisplayhook  = { NULL, NULL, (HOOKFUNC)comdisplayhookfunc,  NULL, NULL };
  1415.  
  1416. WORD commands(struct FMConfig *ofmc)
  1417. {
  1418. struct FMConfig *fmc;
  1419. Object *obj;
  1420. ULONG ds[2],dm[2],last = 0,clicked;
  1421. Class *ddlistclass;
  1422. struct GUIBase *gb;
  1423. struct GUISlot *gs[4];
  1424. WORD ret,cnt1;
  1425. WORD cmenutype,cmenucolumns;
  1426. void *moreconfigs[TOTALCOMMANDS];
  1427. UBYTE msg[20];
  1428.  
  1429. if(!(fmc=newconfig(ofmc))) return(0);
  1430. if(!savecommands(fmc,moreconfigs)) goto error;
  1431.  
  1432. ddlistclass=InitFLClass();
  1433.  
  1434. gb=getguibase(getstring(MSG_CONFIG_NAME));
  1435.  
  1436. setconnectgroup(gb,1,0,0);
  1437.  
  1438. gs[0]=getguislot(gb,NewObject(ddlistclass,0,
  1439.     GA_ID,20,
  1440.     LAB_Label,getstring(MSG_CONFIG_COMBUILDINCOMMANDS),
  1441.     LAB_Place,PLACE_ABOVE,
  1442.     LISTV_MinEntriesShown,20,
  1443.     LISTV_SortEntryArray,TRUE,
  1444.     LISTV_ListFont,&fmc->listfontattr,
  1445.     BT_DragObject,TRUE,
  1446.     BT_DropObject,FALSE,
  1447.     TAG_DONE),0,LISTVIEW_KIND,0);
  1448. gs[1]=getguislot(gb,NewObject(ddlistclass,0,
  1449.     GA_ID,21,
  1450.     LAB_Label,getstring(MSG_CONFIG_COMBARCOMMANDS),
  1451.     LAB_Place,PLACE_ABOVE,
  1452.     LISTV_ShowDropSpot,TRUE,
  1453.     LISTV_MinEntriesShown,20,
  1454.     LISTV_SortEntryArray,FALSE,
  1455.     LISTV_ListFont,&fmc->listfontattr,
  1456.     LISTV_ResourceHook,&comresourcehook,
  1457.     LISTV_DisplayHook,&comdisplayhook,
  1458.     BT_DragObject,TRUE,
  1459.     BT_DropObject,TRUE,
  1460.     TAG_DONE),0,LISTVIEW_KIND,0);
  1461. gs[2]=getguislot(gb,NewObject(ddlistclass,0,
  1462.     GA_ID,22,
  1463.     LAB_Label,getstring(MSG_CONFIG_COMCORNERCOMMANDS),
  1464.     LAB_Place,PLACE_ABOVE,
  1465.     LISTV_ShowDropSpot,TRUE,
  1466.     LISTV_MinEntriesShown,20,
  1467.     LISTV_SortEntryArray,FALSE,
  1468.     LISTV_ListFont,&fmc->listfontattr,
  1469.     LISTV_ResourceHook,&comresourcehook,
  1470.     LISTV_DisplayHook,&comdisplayhook,
  1471.     BT_DragObject,TRUE,
  1472.     BT_DropObject,TRUE,
  1473.     TAG_DONE),0,LISTVIEW_KIND,0);
  1474. gs[3]=getguislot(gb,NewObject(ddlistclass,0,
  1475.     GA_ID,23,
  1476.     LAB_Label,getstring(MSG_CONFIG_COMHIDDENCOMMANDS),
  1477.     LAB_Place,PLACE_ABOVE,
  1478.     LISTV_ShowDropSpot,TRUE,
  1479.     LISTV_MinEntriesShown,20,
  1480.     LISTV_SortEntryArray,FALSE,
  1481.     LISTV_ListFont,&fmc->listfontattr,
  1482.     LISTV_ResourceHook,&comresourcehook,
  1483.     LISTV_DisplayHook,&comdisplayhook,
  1484.     BT_DragObject,TRUE,
  1485.     BT_DropObject,TRUE,
  1486.     FL_SortDrops,TRUE,
  1487.     TAG_DONE),0,LISTVIEW_KIND,0);
  1488.  
  1489. if(!gs[0]||!gs[1]||!gs[2]||!gs[3]) goto error;
  1490.  
  1491. setconnectgroup(gb,14,0,0);
  1492. setconnectgroup(gb,2,1,14);
  1493. reqinfomsg(gb,MSG_CONFIG_LAYOUT_CMENUALIGNMENT,110,guiUC|guiLEFT);
  1494. reqinfomsg(gb,MSG_CONFIG_LAYOUT_CMENUSIZE,111,guiUC|guiLEFT);
  1495. setconnectgroup(gb,3,1,14);
  1496. cmenutype=fmconfig->cmenutype;
  1497. reqcyclemsg(gb,110,&cmenutype,MSG_CONFIG_LAYOUTVER,MSG_CONFIG_LAYOUTHOR,0);
  1498. for(cnt1=0;cnt1<9;cnt1++) {
  1499.     msg[cnt1*2+0]=cnt1+'1';
  1500.     msg[cnt1*2+1]=0;
  1501. }
  1502. cmenucolumns=fmconfig->cmenucolumns-1;
  1503. reqcycle(gb,111,&cmenucolumns,&msg[0],&msg[2],&msg[4],&msg[6],&msg[8],&msg[10],&msg[12],&msg[14],&msg[16],0);
  1504.  
  1505. buttonbarmsg(gb,MSG_OK,1,MSG_CANCEL,0,0);
  1506. last=0xffffffff;
  1507. if(openinitreq(gb)) {
  1508.     refreshcommands(fmc,gb,gs);
  1509.     for(;;) {
  1510.         ret=reqmsghandler(gb);
  1511.         if(ret<10) break;
  1512.         if(ret>=20&&ret<=23) {
  1513.             obj=gs[ret-20]->obj;
  1514.             GetAttr(LISTV_LastClicked,obj,&clicked );
  1515.             if (clicked==last ) {
  1516.                 CurrentTime(&ds[1],&dm[1]);
  1517.                 if (DoubleClick(ds[0],dm[0],ds[1],dm[1])) {
  1518.                     sleepreq(gb);
  1519.                     rescanbuttonconfig(fmc,gs);
  1520.                     gsdoubleclick(fmc,gs,gs[ret-20],(void*)clicked);
  1521.                     refreshcommands(fmc,gb,gs);
  1522.                     wakereq(gb);
  1523.                 }
  1524.             }
  1525.             CurrentTime(&ds[0],&dm[0]);
  1526.             last = clicked;
  1527.         }
  1528.     }
  1529. }
  1530. rescanbuttonconfig(fmc,gs);
  1531. refreshcommands(fmc,gb,gs);
  1532. error:
  1533. freereq(gb);
  1534. if(ddlistclass) FreeClass(ddlistclass);
  1535. if(!ret) {
  1536.     restorecommands(fmc,moreconfigs);
  1537. } else {
  1538.     fmc->cmenutype=cmenutype;
  1539.     fmc->cmenucolumns=cmenucolumns+1;
  1540.     freeconfig(fmc,ofmc);
  1541.     fmc=0;
  1542. }
  1543. restorecommands(0,moreconfigs);
  1544. freemem(fmc);
  1545. return(ret);
  1546. }
  1547.  
  1548.  
  1549. WORD config(void)
  1550. {
  1551. struct GUIBase *gb;
  1552. struct FMConfig *fmc;
  1553. WORD c=0;
  1554. WORD apu1=0,apu2;
  1555. #ifndef V39
  1556. WORD apu3,apu4;
  1557. #endif
  1558. WORD refresh=0,retcode=0;
  1559. ULONG coltable[COLORS*3];
  1560. UBYTE *ptr1,*ptr2;
  1561.  
  1562. fmconfig->windowtop=fmmain.ikkuna->TopEdge;
  1563. fmconfig->windowleft=fmmain.ikkuna->LeftEdge;
  1564. fmconfig->windowheight=fmmain.ikkuna->Height;
  1565. fmconfig->windowwidth=fmmain.ikkuna->Width;
  1566. if(!(fmc=newconfig(fmconfig))) return(0);
  1567.  
  1568. gb=getguibase(getstring(MSG_CONFIG_NAME));
  1569. reqbuttonmsg(gb,MSG_CONFIG_SCREEN,10,guiUC|guiCENTER);
  1570. reqbuttonmsg(gb,MSG_CONFIG_COMMANDS,11,guiUC|guiCENTER);
  1571. reqbuttonmsg(gb,MSG_CONFIG_GENERAL,12,guiUC|guiCENTER);
  1572. reqbuttonmsg(gb,MSG_CONFIG_DATATYPES,13,guiUC|guiCENTER);
  1573. buttonbarmsg(gb,MSG_OK,1,MSG_SAVE,2,MSG_CANCEL,0,0);
  1574. if(openinitreq(gb)) {
  1575.     for(;;) {
  1576.         c=reqmsghandler(gb);
  1577.         if(c==2) {
  1578.             apu1=power2(fmc->mainscreen.depth);
  1579.             ptr1=fmc->colors;
  1580.             ptr2=(UBYTE*)coltable;
  1581.     #ifdef V39
  1582.             GetRGB32(fmmain.naytto->ViewPort.ColorMap,0,apu1,coltable);
  1583.             for(apu2=0;apu2<apu1;apu2++) {
  1584.                 *ptr1++=*ptr2;
  1585.                 ptr2+=4;
  1586.                 *ptr1++=*ptr2;
  1587.                 ptr2+=4;
  1588.                 *ptr1++=*ptr2;
  1589.                 ptr2+=4;
  1590.             }    
  1591.     #else
  1592.             for(apu2=0;apu2<apu1;apu2++) {
  1593.                 apu3=GetRGB4(fmmain.naytto->ViewPort.ColorMap,apu2);
  1594.                 apu4=(apu3>>8)&0x0f;
  1595.                 *ptr1++=apu4<<4|apu4;
  1596.                 apu4=(apu3>>4)&0x0f;
  1597.                 *ptr1++=apu4<<4|apu4;
  1598.                 apu4=(apu3)&0x0f;
  1599.                 *ptr1++=apu4<<4|apu4;
  1600.             }
  1601.     #endif
  1602.             writeconfig(fmc);
  1603.         }
  1604.         if(c<10) break;
  1605.         sleepreq(gb);
  1606.         switch(c)
  1607.         {
  1608.         case 10:
  1609.         refresh=screenconfig(fmc);
  1610.         break;
  1611.         case 11:
  1612.         refresh=commands(fmc);
  1613.         break;
  1614.         case 12:
  1615.         refresh=generalconfig(fmc);
  1616.         break;
  1617.         case 13:
  1618.         refresh=datatypesconfig(fmc);
  1619.         break;
  1620.         }
  1621.         wakereq(gb);
  1622.         if(refresh>retcode) retcode=refresh;
  1623.     }
  1624.     apu1=0;
  1625.     if(!c) {
  1626.         retcode=0;
  1627.     } else {
  1628.         apu2=fmconfig->screentype;
  1629.         apu1=fmc->screentype;
  1630.         freeconfig(fmc,fmconfig);
  1631.         fmc=0;
  1632.         fmconfig->screentype=apu2;
  1633.         fmmain.maxdirlistwidth=fmconfig->dl[0].width+fmconfig->dl[1].width+fmconfig->dl[2].width+fmconfig->dl[3].width+fmconfig->dl[4].width+4;
  1634.     }
  1635. }
  1636. cerr:
  1637. freereq(gb);
  1638. freemem(fmc);
  1639. fmc=0;
  1640. if(ReqToolsBase) CloseLibrary((struct Library*)ReqToolsBase);
  1641. ReqToolsBase=0;
  1642. return((WORD)(apu1<<8|retcode)); //0=no refresh,1=redraw,2=reopen window,3=screen/window reopen,bit7=recalculate all
  1643. }
  1644.  
  1645.