home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / fm2000 / edit.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-04  |  37.8 KB  |  1,401 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 <graphics/gfxbase.h>
  23. #include <dos/dos.h>
  24. #include <dos/dosextens.h>
  25. #include <dos/filehandler.h>
  26. #include <devices/trackdisk.h>
  27. #include <proto/all.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include "fmnode.h"
  31. #include "child.h"
  32. #include "fmdos.h"
  33. #include "fmlocale.h"
  34. #include "fmgui.h"
  35.  
  36. extern struct FMConfig *fmconfig;
  37. extern struct TextFont *txtshowfont;
  38. extern struct GfxBase *GfxBase;
  39. extern struct FMMain fmmain;
  40.  
  41. struct DiskEditConfig {
  42.     unsigned lowcyl:2;
  43. };
  44.  
  45. struct fmboolgadget {
  46.     struct    Gadget gadget;
  47.     struct    Border border1;
  48.     struct    Border border2;
  49.     struct    Border border3;
  50.     struct    Border border4;
  51.     WORD    xy1[2*5];
  52.     WORD    xy2[2*5];
  53. };
  54. struct    trackgadget {
  55.     struct    Gadget gadget;
  56.     struct    StringInfo si;
  57.     struct    StringExtend se;
  58.     UBYTE    buffer[16];
  59. };
  60.  
  61. struct Edit {
  62.     WORD    type;
  63.     struct    FMList *list;
  64.     struct    FMNode *node;
  65.     struct    FMHandle *handle;
  66.     WORD    hexwidth;
  67.     WORD    ascwidth;
  68.     WORD    editheight;
  69.     WORD    infoliney;
  70.     WORD    columns;
  71.     WORD    rows;
  72.     WORD    xoffsethex;
  73.     WORD    xoffsetasc;
  74.     WORD    yoffset;
  75.     WORD    screenbytes;
  76.     LONG    offset;
  77.     UBYTE    *buffer;
  78.     UBYTE    *usebuffer;
  79.     LONG    usebufsize;
  80.     LONG    bufsize;
  81.     WORD    cursorx;
  82.     WORD    cursory;
  83.     WORD     cursoroffset;
  84.     WORD    mode;
  85.     UBYTE    searchstring[64];
  86.     UBYTE    changed;
  87.     UBYTE    pad1;
  88.     LONG    oldsearch;
  89.  
  90.     WORD    xoffsetbtsh;
  91.     WORD    xwidthbtsh;
  92.     struct    DosEnvec *dosenv;
  93.     struct    IOStdReq *ioreq;
  94.     WORD    screenoffset;
  95.     LONG    blocklen;
  96.     LONG    blocks;
  97.     LONG    tracks;
  98.     LONG    sectors;
  99.     LONG    heads;
  100.     LONG    lowoffset;
  101.     LONG    maxoffset;
  102.     LONG    rootoffset;
  103.     UBYTE    devname[32];
  104.     struct    CMenuConfig *cmc;
  105.     struct    DiskEditConfig *dec;
  106.  
  107.     struct    trackgadget blockgad;
  108.     struct    trackgadget trackgad;
  109.     struct    trackgadget secgad;
  110.     struct    trackgadget headgad;
  111.  
  112.     struct    fmboolgadget exitgadget;
  113.     struct    fmboolgadget writegadget;
  114.     struct    fmboolgadget undogadget;
  115.     struct    fmboolgadget searchgadget;
  116.     WORD    gads;
  117.     UBYTE    keyshorts[4];
  118.     UBYTE    btsh[4];
  119.     WORD    btshxw[2*4];
  120. };
  121.  
  122. void editor(struct Edit*);
  123. WORD editwindownewsize(struct Edit*);
  124. void editevent(struct Edit*);
  125. void editoutput(struct Edit*);
  126. void editcursor(struct Edit*,WORD,WORD);
  127. void convertmouse(struct Edit*,WORD*,WORD*);
  128. void editoutputline(struct Edit*);
  129. void editoutputlistline(struct Edit*,UBYTE*,LONG,WORD);
  130. WORD readfileedit(struct Edit*);
  131. WORD writefileedit(struct Edit*);
  132. WORD readoffset(struct Edit*,LONG);
  133. void calcblocks(struct Edit*);
  134. void search(struct Edit*,WORD);
  135. void blockinfo(struct Edit*);
  136. void askline(struct Edit*);
  137. WORD editprocessgadget(struct Edit*,struct IntuiMessage*,WORD);
  138. void checkblocks(struct Edit*,WORD);
  139. void freeedit(struct Edit*);
  140. void limitblocks(struct Edit*,WORD,WORD);
  141.  
  142. WORD __asm hexconvert(register __a0 UBYTE*,register __a1 UBYTE*,register __d0 WORD,register __d1 WORD);
  143. WORD windownewsize(void);
  144. void freelistgads(void);
  145. void freegadgets(struct Gadget*);
  146. void draw3dbox(struct RastPort*,WORD,WORD,WORD,WORD,WORD);
  147. WORD diskio(struct FMList*,struct IOStdReq*);
  148. WORD finddevice(BPTR,struct DosList**,struct DosList**);
  149. void doborder(WORD*,struct Border*,struct Border*,WORD*,struct Border*,struct Border*,WORD,WORD);
  150. ULONG __asm checksum(register __a0 UBYTE *,register __d0 LONG);
  151.  
  152. void fileedit(void)
  153. {
  154. struct ProcMsg *pm;
  155. struct Edit *edit;
  156. UBYTE oname[24];
  157.  
  158. pm=sinitproc();
  159. if(!(edit=allocmem(sizeof(struct Edit)))) goto endi;
  160. edit->type=0;
  161. edit->list=fmmain.sourcedir;
  162. edit->cmc=pm->cmc;
  163. strcpy(oname,edit->list->workname);
  164. strcpy(edit->list->workname,edit->cmc->label);
  165. if(sselected(edit->list,1)) {
  166.     if(edit->node=findselnode(edit->list)) {
  167.         if(edit->handle=openfile(edit->list,NDFILE(edit->node),OFNORMAL)) {
  168.             editor(edit);
  169.             closefile(edit->handle);
  170.         }
  171.         edit->node->flags&=~NSELECTED;
  172.         outputlistline(edit->list,edit->node);
  173.     }
  174. }
  175. strcpy(edit->list->workname,oname);
  176. freemem(edit);
  177. endi:
  178. deinitproc(pm);
  179. }
  180. void diskedit(void)
  181. {
  182. struct ProcMsg *pm;
  183. struct Edit *edit;
  184. struct DosList *doslist=0;
  185. struct DosList *vollist;
  186. struct FileSysStartupMsg *fssm;
  187. struct DosEnvec *de;
  188. LONG apu1;
  189. WORD dl=0,nodos=0;
  190. BPTR lock=0,rlock;
  191. UBYTE oname[24];
  192.  
  193. pm=sinitproc();
  194. if(!(edit=allocmem(sizeof(struct Edit)))) goto endi;
  195. edit->type=1;
  196. edit->cmc=pm->cmc;
  197. edit->dec=getconfig(edit->cmc);
  198. edit->list=fmmain.sourcedir;
  199. edit->node=findselnodeall(edit->list);
  200. strcpy(oname,edit->list->workname);
  201. strcpy(edit->list->workname,edit->cmc->label);
  202. if(!edit->node&&edit->list->flags&LDIRLIST) {
  203.     lock=fmlock(edit->list,edit->list->path);
  204. } else if(edit->node&&(edit->node->flags&(NDEVICE|NFILE|NDIRECTORY))) {
  205.     if(edit->list->flags&LDEVLIST) {
  206.         fmmain.myproc->pr_WindowPtr=(APTR)-1;
  207.         lock=Lock(NDFILE(edit->node),SHARED_LOCK);
  208.         fmmain.myproc->pr_WindowPtr=fmmain.ikkuna;
  209.         nodos=1;
  210.     } else {
  211.         lock=fmlock(edit->list,NDFILE(edit->node));
  212.     }
  213.     edit->node->flags&=~NSELECTED;
  214. } else {
  215.     strcpymsg(edit->list->fmmessage1,MSG_MAIN_NOSOURCEFILE);
  216.     fmmessage(edit->list);
  217.     goto dend;
  218. }
  219. if(!lock&&!nodos) goto dend;
  220.  
  221. apu1=0;
  222. memseti(edit->devname,0,32);
  223. doslist=LockDosList(LDF_VOLUMES|LDF_DEVICES|LDF_READ);
  224. dl=1;
  225. if(!lock) {
  226.     strcpy(edit->devname,NDFILE(edit->node));
  227.     edit->devname[strlen(edit->devname)-1]=0;
  228.     doslist=FindDosEntry(doslist,edit->devname,LDF_DEVICES);
  229.     if(doslist) apu1=1;
  230. } else if(finddevice(lock,&doslist,&vollist)) {
  231.     siirrabstr((UBYTE*)(doslist->dol_Name<<2),edit->devname);
  232.     apu1=1;
  233. }
  234. edit->devname[strlen(edit->devname)]=':';
  235. if(apu1) {
  236.     fssm=(struct FileSysStartupMsg*)(doslist->dol_misc.dol_handler.dol_Startup<<2);
  237.     if(fssm) {
  238.         de=edit->dosenv=(struct DosEnvec*)(fssm->fssm_Environ<<2);
  239.         edit->blocklen=edit->dosenv->de_SizeBlock<<2;
  240.         edit->ioreq=(struct IOStdReq*)opendevice(edit->list,(UBYTE*)(fssm->fssm_Device<<2)+1,fssm->fssm_Unit,fssm->fssm_Flags,sizeof(struct IOStdReq));
  241.         apu1=de->de_Surfaces*de->de_BlocksPerTrack*512L;
  242.         if(!edit->dec->lowcyl) edit->lowoffset=de->de_LowCyl*apu1;
  243.         edit->maxoffset=(de->de_HighCyl+1)*apu1;
  244.         UnLockDosList(LDF_VOLUMES|LDF_DEVICES|LDF_READ);
  245.         dl=0;
  246.         if(lock) {
  247.             edit->offset=((struct FileLock*)(lock<<2))->fl_Key*(de->de_SizeBlock<<2);
  248.             rlock=Lock(edit->devname,SHARED_LOCK);
  249.             if(rlock) {
  250.                 edit->rootoffset=((struct FileLock*)(rlock<<2))->fl_Key*(de->de_SizeBlock<<2);
  251.                 UnLock(rlock);
  252.             }
  253.         }
  254.         if(edit->ioreq) {
  255.             editor(edit);
  256.             closedevice((struct IORequest*)edit->ioreq);
  257.         }
  258.     }
  259. }
  260. dend:
  261. if(dl) UnLockDosList(LDF_VOLUMES|LDF_DEVICES|LDF_READ);
  262. if(lock) UnLock(lock);
  263. outputlist(edit->list);
  264. strcpy(edit->list->workname,oname);
  265. freemem(edit);
  266. endi:
  267. deinitproc(pm);
  268. }
  269.  
  270. void editor(struct Edit *edit)
  271. {
  272. UWORD flags;
  273.  
  274. flags=fmconfig->flags;
  275. fmconfig->flags&=~MSUBPROC;
  276. edit->list->flags|=LACTIVE;
  277. edit->oldsearch=-1;
  278. if(editwindownewsize(edit)) editevent(edit);
  279. freeedit(edit);
  280. edit->list->fmmessage1[0]=0;
  281. edit->list->fmmessage2[0]=0;
  282. fmmessage(edit->list);
  283. fmconfig->flags=flags;
  284. edit->list->flags&=~LACTIVE;
  285. windownewsize();
  286. }
  287.  
  288. void editevent(struct Edit *edit)
  289. {
  290. struct Gadget *cmgad;
  291. struct fmboolgadget *fbg;
  292. WORD apu1,apu2;
  293.  
  294. ULONG class;
  295. UWORD code;
  296. struct IntuiMessage *message=0;
  297. struct AppMessage *appiconmsg=0,*appwinmsg=0;
  298. ULONG signalmask;
  299. WORD quit=0;
  300. WORD mousex,mousey,curx,cury;
  301. LONG offset;
  302. struct InputEvent ie;
  303. UBYTE chartab[2];
  304. WORD asciicode,mode;
  305. WORD oldhex=-1;
  306. //struct DosEnvec *de;
  307.  
  308. ie.ie_Class=IECLASS_RAWKEY;
  309. ie.ie_SubClass=0;
  310. //de=edit->dosenv;
  311. signalmask=1L<<fmmain.ikkuna->UserPort->mp_SigBit;
  312. if(fmmain.appiconport) signalmask|=(1L<<fmmain.appiconport->mp_SigBit);
  313. if(fmmain.appwinport) signalmask|=(1L<<fmmain.appwinport->mp_SigBit);
  314.  
  315. while(!quit) {
  316.     for(;;) {
  317.         message=(struct IntuiMessage*)GetMsg(fmmain.ikkuna->UserPort);
  318.         if(fmmain.appiconport) appiconmsg=(struct AppMessage*)GetMsg(fmmain.appiconport);
  319.         if(fmmain.appwinport) appwinmsg=(struct AppMessage*)GetMsg(fmmain.appwinport);
  320.         if(!message&&!appiconmsg&&!appwinmsg) {
  321.             Wait(signalmask);
  322.         } else {
  323.             break;
  324.         }
  325.     }
  326.     if(appwinmsg) {
  327.         ReplyMsg((struct Message*)appwinmsg);
  328.         appwinmsg=0;
  329.     }
  330.     if(appiconmsg) {
  331.         ScreenToFront(fmmain.naytto);
  332.         WindowToFront(fmmain.ikkuna);
  333.         ReplyMsg((struct Message*)appiconmsg);
  334.         appiconmsg=0;
  335.     }
  336.     if(!message) continue;
  337.  
  338.     class=message->Class;
  339.     code=message->Code;
  340.     mousex=message->MouseX;
  341.     mousey=message->MouseY;
  342.     mousex-=fmmain.ikkuna->BorderLeft;
  343.     mousey-=fmmain.ikkuna->BorderTop;
  344.  
  345.     switch(class)
  346.     {
  347.     case IDCMP_CLOSEWINDOW:
  348.     quit=1;
  349.     break;
  350.     case IDCMP_REFRESHWINDOW:
  351.     BeginRefresh(fmmain.ikkuna);
  352.     EndRefresh(fmmain.ikkuna,1);
  353.     break;
  354.     case IDCMP_NEWSIZE:
  355.     if(!editwindownewsize(edit)) quit=1;
  356.     break;
  357.     case IDCMP_RAWKEY:
  358.     curx=edit->cursorx;
  359.     cury=edit->cursory;
  360.     offset=edit->offset;
  361.     mode=edit->mode;
  362.     if(edit->mode>=0) {
  363.         switch(code)
  364.         {
  365.         case 0x1b:    //esc
  366.         mode=-1;
  367.         editcursor(edit,-1,-1);
  368.         break;
  369.         case 0x2e:    //5
  370.         mode^=1;
  371.         break;
  372.         case 0x4c:    //up
  373.         case 0x3e:
  374.             if(cury) cury--;
  375.         break;
  376.         case 0x4d:    //down
  377.         case 0x1e:
  378.             if(cury<edit->rows-1) cury++;
  379.         break;
  380.         case 0x4f:    //left
  381.         case 0x2d:
  382.             if(curx) curx--;
  383.         break;
  384.         case 0x4e:    //right
  385.         case 0x2f:
  386.             if(curx<edit->columns-1) curx++;
  387.         break;
  388.         }
  389.         if(mode!=edit->mode||curx!=edit->cursorx||cury!=edit->cursory) {
  390.             if(edit->mode!=mode) edit->mode=mode;
  391.             editcursor(edit,curx,cury);
  392.             break;
  393.         }
  394.     } else {
  395.         switch(code)
  396.         {
  397.         case 0x3d:    //home
  398.         offset=0;
  399.         break;
  400.         case 0x1d:    //end
  401.         if(edit->type)
  402.             offset=edit->maxoffset-edit->blocklen;
  403.             else
  404.             offset=edit->handle->size;
  405.         break;
  406.         case 0x4f:    //left
  407.         case 0x3e:
  408.         if(edit->type)
  409.             offset-=edit->bufsize;
  410.             else
  411.             offset-=edit->columns;
  412.         break;
  413.         case 0x4e:    //right
  414.         case 0x1e:
  415.         if(edit->type)
  416.             offset+=edit->bufsize;
  417.             else
  418.             offset+=edit->columns;
  419.         break;
  420.         case 0x3f:    //page up
  421.         if(edit->type) {
  422.             edit->screenoffset-=edit->screenbytes-edit->columns;
  423.             editoutput(edit);
  424.             break;
  425.         }
  426.         case 0x4c:    //up
  427.         if(edit->type)
  428.             offset-=edit->bufsize;
  429.             else
  430.             offset-=edit->screenbytes-edit->columns;
  431.         break;
  432.         case 0x1f:    //page down
  433.         if(edit->type) {
  434.             edit->screenoffset+=edit->screenbytes-edit->columns;
  435.             editoutput(edit);
  436.             break;
  437.         }
  438.         case 0x4d:    //down
  439.         if(edit->type)
  440.             offset+=edit->bufsize;
  441.             else
  442.             offset+=edit->screenbytes-edit->columns;
  443.         break;
  444.         case 0x2e:    //root
  445.         if(edit->type) offset=edit->rootoffset;
  446.         break;
  447.         }
  448.         if(offset!=edit->offset) {
  449.             if(!readoffset(edit,offset)) quit=1;
  450.             break;
  451.         }
  452.     }
  453.     ie.ie_Code=code&(~0x80);
  454.     ie.ie_Qualifier=message->Qualifier&(~0x80);
  455.     ie.ie_EventAddress=(APTR*)*((ULONG*)message->IAddress);
  456.     if (MapRawKey(&ie,chartab,2,0)==1) {
  457.         asciicode=chartab[0];
  458.         switch(edit->mode)
  459.         {
  460.         case -1:    //none
  461.         asciicode=ToUpper(asciicode);
  462.         if(!(code&0x80)) {
  463.             if(asciicode==0x0d&&!edit->type) askline(edit);
  464.             apu1=(message->Qualifier&3)?-1:1;
  465.             apu2=-1;
  466.             if(asciicode==edit->btsh[0]) apu2=0;
  467.             if(asciicode==edit->btsh[3]) apu2=3;
  468.             if(asciicode==edit->btsh[2]) apu2=2;
  469.             if(asciicode==edit->btsh[1]) apu2=1;
  470.             limitblocks(edit,apu2,apu1);
  471.         }
  472.         if(asciicode) {
  473.             fbg=&edit->exitgadget;
  474.             for(apu1=0;apu1<4;apu1++) {
  475.                 cmgad=&fbg->gadget;
  476.                 if(asciicode==cmgad->GadgetID) {
  477.                     if(editprocessgadget(edit,message,cmgad->GadgetID)) quit=1;
  478.                     break;
  479.                 }
  480.                 fbg++;
  481.             }
  482.         }
  483.         break;
  484.         case 0:        //hex
  485.         case 1:        //asc
  486.             if(code&0x80) break;
  487.             if(edit->mode==0) {
  488.                 asciicode=ToUpper(asciicode);
  489.                 asciicode-='0';
  490.                 if(asciicode>9) asciicode-=7;
  491.                 if(asciicode>15||asciicode<0) break;
  492.                 if(oldhex==-1) {
  493.                     oldhex=asciicode;
  494.                     break;
  495.                 } else {
  496.                     asciicode|=oldhex<<4;
  497.                 }
  498.             }
  499.             curx=edit->cursorx;cury=edit->cursory;
  500.             editcursor(edit,-1,-1);
  501.             edit->buffer[edit->cursoroffset]=asciicode;
  502.             edit->usebuffer[edit->cursoroffset]=1;
  503.             editoutputline(edit);
  504.             if(curx<edit->columns-1) {
  505.                 curx++;
  506.             } else {
  507.                 curx=0;
  508.                 cury++;
  509.                 if(cury>=edit->rows) cury=edit->rows-1;
  510.             }
  511.             editcursor(edit,curx,cury);
  512.             oldhex=-1;
  513.         break;
  514.         }
  515.     }
  516.     break;
  517.     case IDCMP_MOUSEBUTTONS:
  518.         if(mousey<=edit->editheight+edit->yoffset) {
  519.             switch(code)
  520.             {
  521.             case MENUDOWN:
  522.             editcursor(edit,-1,-1);
  523.             edit->mode=-1;
  524.             editcursor(edit,-1,-1);
  525.             ReportMouse(0,fmmain.ikkuna);
  526.             break;
  527.             case SELECTDOWN:
  528.                 ReportMouse(1,fmmain.ikkuna);
  529.                 convertmouse(edit,&mousex,&mousey);
  530.                 editcursor(edit,mousex,mousey);
  531.             break;
  532.             case SELECTUP:
  533.                 ReportMouse(0,fmmain.ikkuna);
  534.                 convertmouse(edit,&mousex,&mousey);
  535.                 editcursor(edit,mousex,mousey);
  536.             break;
  537.             }
  538.         } else {
  539.             editcursor(edit,-1,-1);
  540.             edit->mode=-1;
  541.             editcursor(edit,-1,-1);
  542.             ReportMouse(0,fmmain.ikkuna);
  543.             if((code==SELECTDOWN||code==MENUDOWN)&&mousey>=edit->editheight+edit->yoffset+fmconfig->spaceh&&mousey<=edit->editheight+edit->yoffset+fmconfig->spaceh+fmmain.txtysize) {
  544.                 if(edit->type) {                
  545.                     if(mousex>=edit->xoffsethex&&mousex<=edit->xoffsethex+64-fmconfig->spacew) readoffset(edit,edit->rootoffset);
  546.                     for(apu1=0;apu1<4;apu1++) {
  547.                         if(mousex>=edit->btshxw[apu1*2]&&mousex<=edit->btshxw[apu1*2+1]) limitblocks(edit,apu1,code==SELECTDOWN?1:-1);
  548.                     }
  549.                 } else {
  550.                     if(code==SELECTDOWN&&mousex>=edit->xoffsetasc&&mousex<=edit->xoffsetasc+edit->ascwidth) askline(edit);
  551.                 }
  552.             }
  553.         }            
  554.     break;
  555.     case IDCMP_MOUSEMOVE:
  556.         convertmouse(edit,&mousex,&mousey);
  557.         editcursor(edit,mousex,mousey);
  558.     break;
  559.     case IDCMP_GADGETUP:
  560.     case IDCMP_GADGETDOWN:
  561.     apu1=((struct Gadget*)message->IAddress)->GadgetID;
  562.     if(apu1==1) {
  563.         edit->blocks=edit->blockgad.si.LongInt;
  564.         checkblocks(edit,1);
  565.     } else if(apu1<=4) {
  566.         edit->tracks=edit->trackgad.si.LongInt;
  567.         edit->sectors=edit->secgad.si.LongInt;
  568.         edit->heads=edit->headgad.si.LongInt;
  569.         edit->blocks=edit->tracks*edit->sectors*edit->heads;
  570.         checkblocks(edit,0);
  571.     }
  572.     if(apu1>=32) {
  573.         if(editprocessgadget(edit,message,apu1)) quit=1;
  574.     }
  575.     break;
  576.     }
  577.  
  578.  
  579.  
  580.     ReplyMsg((struct Message*)message);
  581.     message=0;
  582.  
  583. }
  584. ReportMouse(0,fmmain.ikkuna);
  585. }
  586.  
  587. WORD readoffset(struct Edit *edit,LONG offset)
  588. {
  589. edit->oldsearch=-1;
  590. switch(edit->type)
  591. {
  592. case 0:
  593. if(offset>edit->handle->size-edit->bufsize) offset=edit->handle->size-edit->bufsize;
  594. break;
  595. case 1:
  596. if(offset>=edit->maxoffset) offset=edit->maxoffset-edit->bufsize;
  597. break;
  598. }
  599. if(offset<0) offset=0;
  600. edit->offset=offset;
  601. if(!readfileedit(edit)) return(0);
  602. editoutput(edit);
  603. return(1);
  604. }
  605.  
  606. void convertmouse(struct Edit *edit,WORD *amousex,WORD *amousey)
  607. {
  608. WORD mousex,mousey;
  609.  
  610. mousex=*amousex;mousey=*amousey;
  611. mousey-=edit->yoffset;
  612. if(mousey>=0) mousey/=fmmain.listysize; else mousey=0;
  613. if(mousex>=edit->xoffsetasc) {
  614.     edit->mode=1;
  615.     mousex-=edit->xoffsetasc;
  616.     mousex/=fmmain.listxsize;
  617. } else {
  618.     edit->mode=0;
  619.     mousex-=edit->xoffsethex;
  620.     if(mousex>=0) mousex/=(fmmain.listxsize*2); else mousex=0;
  621. }
  622. if(mousey>=edit->rows) mousey=edit->rows-1;
  623. if(mousex>=edit->columns) mousex=edit->columns-1;
  624. *amousex=mousex;*amousey=mousey;
  625. }
  626.  
  627. void editoutputline(struct Edit *edit)
  628. {
  629. ObtainSemaphore(&fmmain.gfxsema);
  630. SetAPen(fmmain.rp,fmconfig->txtpen);
  631. SetDrMd(fmmain.rp,JAM2);
  632. SetFont(fmmain.rp,fmmain.listfont);
  633. editoutputlistline(edit,edit->buffer+edit->cursory*edit->columns+edit->screenoffset,edit->bufsize-edit->cursory*edit->columns-edit->screenoffset,edit->cursory);
  634. SetFont(fmmain.rp,fmmain.txtfont);
  635. ReleaseSemaphore(&fmmain.gfxsema);
  636. }
  637. void editoutput(struct Edit *edit)
  638. {
  639. WORD yy;
  640. UBYTE *memory;
  641. LONG bsize;
  642.  
  643. if(edit->type) {
  644.     if(edit->screenoffset>edit->bufsize-edit->screenbytes) edit->screenoffset=edit->bufsize-edit->screenbytes;
  645.     if(edit->screenoffset<0) edit->screenoffset=0;
  646. }
  647. memory=edit->buffer+edit->screenoffset;
  648. bsize=edit->bufsize-edit->screenoffset;
  649. ObtainSemaphore(&fmmain.gfxsema);
  650. SetAPen(fmmain.rp,fmconfig->txtpen);
  651. SetDrMd(fmmain.rp,JAM2);
  652. SetFont(fmmain.rp,fmmain.listfont);
  653. for(yy=0;yy<edit->rows;yy++) {
  654.     editoutputlistline(edit,memory,bsize,yy);
  655.     bsize-=edit->columns;
  656.     memory+=edit->columns;
  657. }
  658. SetFont(fmmain.rp,fmmain.txtfont);
  659. ReleaseSemaphore(&fmmain.gfxsema);
  660. edit->cursorx=-1;
  661. editcursor(edit,-1,-1);
  662. if(edit->type) calcblocks(edit);
  663. }
  664.  
  665. void editoutputlistline(struct Edit *edit,UBYTE *memory,LONG bsize,WORD yy)
  666. {
  667. UBYTE vara[1000];
  668. WORD yyy,yyyb;
  669. UBYTE *ptr;
  670.  
  671. yyyb=yy*fmmain.listysize+edit->yoffset;
  672. yyy=yyyb+fmmain.listbaseline;
  673. if(bsize>=edit->columns) {
  674.     hexconvert(memory,vara,edit->columns,edit->columns);
  675.     Move(fmmain.rp,edit->xoffsethex,yyy);
  676.     Text(fmmain.rp,vara,edit->columns*2);
  677.     Move(fmmain.rp,edit->xoffsetasc,yyy);
  678.     Text(fmmain.rp,vara+edit->columns*2+1,edit->columns);
  679. } else if (bsize>0) {
  680.     hexconvert(memory,vara,bsize,bsize);
  681.     Move(fmmain.rp,edit->xoffsethex,yyy);
  682.     Text(fmmain.rp,vara,bsize*2);
  683.     Move(fmmain.rp,edit->xoffsetasc,yyy);
  684.     Text(fmmain.rp,vara+bsize*2+1,bsize);
  685.     SetAPen(fmmain.rp,fmconfig->backpen);
  686.     RectFill(fmmain.rp,edit->xoffsethex+bsize*fmmain.listxsize*2,yyyb,edit->xoffsethex+(edit->columns*2)*fmmain.listxsize-1,yyyb+fmmain.listysize-1);
  687.     RectFill(fmmain.rp,edit->xoffsetasc+bsize*fmmain.listxsize,yyyb,edit->xoffsetasc+(edit->columns)*fmmain.listxsize-1,yyyb+fmmain.listysize-1);
  688.     SetAPen(fmmain.rp,fmconfig->txtpen);
  689. } else {
  690.     SetAPen(fmmain.rp,fmconfig->backpen);
  691.     RectFill(fmmain.rp,edit->xoffsethex,yyyb,edit->xoffsethex+edit->columns*fmmain.listxsize*2-1,yyyb+fmmain.listysize-1);
  692.     RectFill(fmmain.rp,edit->xoffsetasc,yyyb,edit->xoffsetasc+edit->columns*fmmain.listxsize-1,yyyb+fmmain.listysize-1);
  693.     SetAPen(fmmain.rp,fmconfig->txtpen);
  694. }        
  695. ptr=edit->usebuffer+yy*edit->columns+edit->screenoffset;
  696. SetDrMd(fmmain.rp,COMPLEMENT);
  697. for(yyy=0;yyy<edit->columns;yyy++) {
  698.     if(ptr[yyy]==1) fmmain.rp->Mask=255;
  699.     if(ptr[yyy]==2) fmmain.rp->Mask=3;
  700.     if(ptr[yyy]) {
  701.         RectFill(fmmain.rp,edit->xoffsethex+yyy*fmmain.listxsize*2,yyyb,edit->xoffsethex+((yyy+1)*fmmain.listxsize)*2-1,yyyb+fmmain.listysize-1);
  702.         RectFill(fmmain.rp,edit->xoffsetasc+yyy*fmmain.listxsize,yyyb,edit->xoffsetasc+((yyy+1)*fmmain.listxsize)-1,yyyb+fmmain.listysize-1);
  703.     }
  704.  
  705. }
  706. fmmain.rp->Mask=255;
  707. SetDrMd(fmmain.rp,JAM2);
  708. }
  709.  
  710. void editcursor(struct Edit *edit,WORD x,WORD y)
  711. {
  712. WORD yyyb,xxxb;
  713. UBYTE vara[40];
  714. LONG offset;
  715. UBYTE *aschex;
  716.  
  717. ObtainSemaphore(&fmmain.gfxsema);
  718. SetDrMd(fmmain.rp,COMPLEMENT);
  719. fmmain.rp->Mask=1;
  720. if(edit->cursorx>=0) {
  721.     yyyb=edit->cursory*fmmain.listysize+edit->yoffset;
  722.     xxxb=edit->cursorx*fmmain.listxsize;
  723.     RectFill(fmmain.rp,edit->xoffsethex+xxxb*2,yyyb,edit->xoffsethex+(xxxb+fmmain.listxsize)*2-1,yyyb+fmmain.listysize-1);
  724.     RectFill(fmmain.rp,edit->xoffsetasc+xxxb,yyyb,edit->xoffsetasc+xxxb+fmmain.listxsize-1,yyyb+fmmain.listysize-1);
  725. }
  726. if(x>=0&&y>=0) {
  727.     edit->cursorx=x;
  728.     edit->cursory=y;
  729.     if(y*edit->columns+x>=edit->bufsize) {
  730.         x=edit->cursorx=(edit->bufsize-1)%edit->columns;
  731.         y=edit->cursory=(edit->bufsize-1)/edit->columns;
  732.     }
  733.     yyyb=edit->cursory*fmmain.listysize+edit->yoffset;
  734.     xxxb=edit->cursorx*fmmain.listxsize;
  735.     RectFill(fmmain.rp,edit->xoffsethex+xxxb*2,yyyb,edit->xoffsethex+(xxxb+fmmain.listxsize)*2-1,yyyb+fmmain.listysize-1);
  736.     RectFill(fmmain.rp,edit->xoffsetasc+xxxb,yyyb,edit->xoffsetasc+xxxb+fmmain.listxsize-1,yyyb+fmmain.listysize-1);
  737.     edit->cursoroffset=y*edit->columns+x;
  738. } else {
  739.     edit->cursorx=-1;
  740. }
  741. SetDrMd(fmmain.rp,JAM2);
  742. fmmain.rp->Mask=255;
  743. ReleaseSemaphore(&fmmain.gfxsema);
  744.  
  745. switch(edit->mode)
  746. {
  747. case 0:
  748. aschex=getstring(MSG_FDEDIT_HEX);
  749. break;
  750. case 1:
  751. aschex=getstring(MSG_FDEDIT_ASC);
  752. break;
  753. default:
  754. aschex=" ";
  755. break;
  756. }
  757. switch(edit->type)
  758. {
  759. case 0:
  760. offset=edit->offset;
  761. if(edit->cursorx>=0) offset+=edit->cursory*edit->columns+edit->cursorx;
  762. sformatmsg(vara,MSG_FDEDIT_FILEINFO1,offset,edit->handle->size,aschex);
  763. fittext(fmmain.rp,vara,-1,edit->xoffsetasc-1,edit->infoliney+1,edit->ascwidth,0);
  764. break;
  765. case 1:
  766. blockinfo(edit);
  767. edit->blocks=edit->offset/edit->blocklen;
  768. break;
  769. }
  770.  
  771. }
  772.  
  773. WORD editwindownewsize(struct Edit *edit)
  774. {
  775. WORD height,width,tfh;
  776. struct Gadget *gad;
  777. struct StringInfo *si;
  778. struct fmboolgadget *fbg;
  779. struct trackgadget *tg;
  780. WORD cnt;
  781. WORD apu1,apu2,bottomx,apu3,apu4,bottomwidth;
  782. UBYTE *ptr1;
  783. UBYTE gadname[16];
  784. LONG offset;
  785.  
  786. freeedit(edit);
  787. ObtainSemaphore(&fmmain.gfxsema);
  788. SetAPen(fmmain.rp,fmconfig->backpen);
  789. RectFill(fmmain.rp,fmmain.ikkuna->BorderLeft,fmmain.ikkuna->BorderTop,fmmain.ikkuna->Width+fmmain.ikkuna->BorderLeft,fmmain.ikkuna->Height+fmmain.ikkuna->BorderTop);
  790. height=fmmain.ikkuna->Height-fmmain.ikkuna->BorderTop-fmmain.ikkuna->BorderBottom;
  791. width=fmmain.ikkuna->Width-fmmain.ikkuna->BorderLeft-fmmain.ikkuna->BorderRight;
  792. tfh=fmmain.txtysize+1;
  793.  
  794. edit->cursorx=-1;
  795. edit->mode=-1;
  796. edit->columns=((width-3*fmconfig->spacew)/(fmmain.listxsize*3))&0xfffe;
  797. edit->rows=(height-5*tfh-3*fmconfig->spaceh+1)/fmmain.listysize;
  798. edit->screenbytes=edit->columns*edit->rows;
  799. edit->ascwidth=edit->columns*fmmain.listxsize;
  800. edit->hexwidth=edit->ascwidth*2;
  801. edit->ascwidth++;
  802. edit->hexwidth++;
  803. edit->editheight=edit->rows*fmmain.listysize+1;
  804. apu1=(((width-3*fmconfig->spacew-edit->ascwidth-edit->hexwidth)+2)/3);
  805. edit->xoffsethex=fmconfig->spacew+1+apu1;
  806. edit->xoffsetasc=edit->xoffsethex+edit->hexwidth+apu1+fmconfig->spacew;
  807. edit->yoffset=fmconfig->spaceh+1;
  808. if (fmconfig->flags&MDOUBLED) {
  809.     draw3dbox(fmmain.rp,2,1,width-2*2,height-2*1,1);
  810.     SetAPen(fmmain.rp,fmconfig->mainbackfillpen);
  811.     RectFill(fmmain.rp,2,1,width-2*2+1,height-2*1);
  812. } else {
  813.     draw3dbox(fmmain.rp,1,1,width-2*1,height-2*1,1);
  814.     SetAPen(fmmain.rp,fmconfig->mainbackfillpen);
  815.     RectFill(fmmain.rp,1,1,width-2*1,height-2*1);
  816. }
  817. draw3dbox(fmmain.rp,edit->xoffsethex-1,edit->yoffset-1,edit->hexwidth,edit->editheight,0);
  818. draw3dbox(fmmain.rp,edit->xoffsetasc-1,edit->yoffset-1,edit->ascwidth,edit->editheight,0);
  819. edit->infoliney=edit->yoffset+edit->editheight+fmconfig->spaceh-1;
  820.  
  821. switch(edit->type)
  822. {
  823. case 0: //file editor
  824. draw3dbox(fmmain.rp,edit->xoffsethex-1,edit->infoliney,edit->hexwidth,tfh,0);
  825. draw3dbox(fmmain.rp,edit->xoffsetasc-1,edit->infoliney,edit->ascwidth,tfh,0);
  826. fittext(fmmain.rp,edit->handle->filename,-1,edit->xoffsethex-1,edit->infoliney+1,edit->hexwidth,0);
  827. edit->bufsize=edit->screenbytes;
  828. if(edit->handle->size<edit->bufsize) edit->bufsize=edit->handle->size;
  829. break;
  830. case 1: //disk editor
  831. draw3dbox(fmmain.rp,edit->xoffsethex-1,edit->infoliney,64,tfh,0);
  832. fittext(fmmain.rp,edit->devname,-1,edit->xoffsethex-1,edit->infoliney+1,64,0);
  833. edit->xoffsetbtsh=edit->xoffsethex+64+fmconfig->spacew-1;
  834. edit->xwidthbtsh=edit->hexwidth-64-fmconfig->spacew;
  835. draw3dbox(fmmain.rp,edit->xoffsetbtsh,edit->infoliney,edit->xwidthbtsh,tfh,0);
  836. draw3dbox(fmmain.rp,edit->xoffsetasc-1,edit->infoliney,edit->ascwidth,tfh,0);
  837. edit->bufsize=edit->blocklen;
  838. break;
  839. }
  840.  
  841. fmmain.bottomliney=height-tfh-fmconfig->spaceh+1;
  842. fmmain.messageliney1=height-3*tfh-2*fmconfig->spaceh+1;
  843. fmmain.messageliney2=fmmain.messageliney1+tfh;
  844.  
  845. SetDrMd(fmmain.rp,JAM1);
  846. bottomwidth=0;
  847. ptr1=getstring(MSG_FDEDIT_GADGETS);
  848. bottomx=fmmain.ikkuna->Width-fmmain.ikkuna->BorderLeft-fmmain.ikkuna->BorderRight-fmconfig->spacew/3*2;
  849. fbg=&edit->exitgadget;
  850. for(cnt=0;cnt<4;cnt++) {
  851.     gad=&fbg->gadget;
  852.     gad->TopEdge=fmmain.bottomliney-2;
  853.     gad->GadgetID=edit->keyshorts[cnt]=scanus(ptr1);
  854.     apu1=0;
  855.     while(*ptr1) {
  856.         if(*ptr1!='_') gadname[apu1++]=*ptr1;
  857.         ptr1++;
  858.     }
  859.     ptr1++;
  860.     gadname[apu1]=0;
  861.     textextent(fmmain.rp,gadname,&apu1,&apu2);
  862.     gad->Width=(apu1+2*fmconfig->spaceh);
  863.     bottomwidth+=gad->Width;
  864.     gad->Height=fmmain.txtysize+2+1;
  865.     bottomx-=gad->Width;
  866.     gad->LeftEdge=bottomx;
  867.     doborder(fbg->xy1,&fbg->border1,&fbg->border2,fbg->xy2,&fbg->border3,&fbg->border4,gad->Height,gad->Width);
  868.     gad->GadgetRender=&fbg->border1;
  869.     gad->SelectRender=&fbg->border3;
  870.     gad->Activation=RELVERIFY;
  871.     gad->GadgetType=BOOLGADGET;
  872.     gad->Flags=GADGHIMAGE;
  873.     fbg++;
  874.     gad->NextGadget=&fbg->gadget;
  875.     SetAPen(fmmain.rp,fmconfig->backpen);
  876.     RectFill(fmmain.rp,gad->LeftEdge+2,gad->TopEdge+1,gad->Width+gad->LeftEdge-3,gad->Height+gad->TopEdge-2);
  877.     SetAPen(fmmain.rp,fmconfig->txtpen);
  878.     Move(fmmain.rp,gad->LeftEdge+fmconfig->spaceh,gad->TopEdge+fmmain.txtbaseline+1);
  879.     Text(fmmain.rp,gadname,strlen(gadname));
  880. }
  881. gad->NextGadget=0;
  882. AddGList(fmmain.ikkuna,&edit->exitgadget.gadget,-1,-1,0);
  883. SetDrMd(fmmain.rp,JAM2);
  884. SetAPen(fmmain.rp,fmconfig->txtpen);
  885.  
  886. if(edit->type) {
  887.     apu3=0;
  888.     CopyMem(getstring(MSG_FDEDIT_DISKBTSH),edit->btsh,4);
  889.     for(cnt=0;cnt<4;cnt++) {
  890.         gadname[0]=edit->btsh[cnt];
  891.         gadname[1]=0;
  892.         textextent(fmmain.rp,gadname,&apu1,&apu2);
  893.         if(apu3<apu1) apu3=apu1;
  894.     }
  895.     apu4=edit->xwidthbtsh/4;
  896.     tg=&edit->blockgad;
  897.     apu1=edit->xoffsetbtsh+fmconfig->spacew;
  898.     for(cnt=0;cnt<4;cnt++) {
  899.         Move(fmmain.rp,apu1,edit->infoliney+fmmain.txtbaseline+1);
  900.         edit->btshxw[cnt*2]=fmmain.rp->cp_x;
  901.         Text(fmmain.rp,&edit->btsh[cnt],1);
  902.         edit->btshxw[cnt*2+1]=fmmain.rp->cp_x;
  903.         gad=&tg->gadget;
  904.         si=&tg->si;
  905.         gad->TopEdge=edit->infoliney+1;
  906.         gad->Height=tfh-1;
  907.         gad->LeftEdge=apu1+apu3+fmconfig->spacew;
  908.         gad->Width=apu4-2*fmconfig->spacew-apu3;
  909.         apu1+=apu4;
  910.         gad->Flags=GFLG_STRINGEXTEND;
  911.         gad->Activation=RELVERIFY|LONGINT;
  912.         gad->GadgetType=STRGADGET;
  913.         gad->SpecialInfo=si;
  914.         gad->GadgetID=cnt+1;
  915.         si->Buffer=tg->buffer;
  916.         tg->buffer[0]='0';
  917.         si->UndoBuffer=fmmain.undobuf;
  918.         si->Extension=&tg->se;
  919.         si->MaxChars=8;
  920.         tg->se.Font=fmmain.txtfont;
  921.         tg->se.Pens[0]=tg->se.ActivePens[0]=fmconfig->txtpen;
  922.         tg->se.Pens[1]=tg->se.ActivePens[1]=fmconfig->backpen;
  923.         tg++;
  924.         gad->NextGadget=&tg->gadget;
  925.     }
  926.     gad->NextGadget=0;
  927.     AddGList(fmmain.ikkuna,&edit->blockgad.gadget,-1,-1,0);
  928. }
  929.  
  930. draw3dbox(fmmain.rp,fmconfig->spacew,fmmain.messageliney1-1,width-2*fmconfig->spacew,2*tfh,0);
  931. fmmain.bottomlinewidth=width-bottomwidth-fmconfig->spacew-2*fmconfig->spacew/3*2;
  932. draw3dbox(fmmain.rp,fmconfig->spacew,fmmain.bottomliney-1,fmmain.bottomlinewidth,tfh,0);
  933. fmmain.bottomlinewidth-=2*fmconfig->spacew;
  934. if(fmmain.bottomlinewidth<0) fmmain.bottomlinewidth=0;
  935.  
  936. fmconfig->windowtop=fmmain.ikkuna->TopEdge;
  937. fmconfig->windowleft=fmmain.ikkuna->LeftEdge;
  938. fmconfig->windowheight=fmmain.ikkuna->Height;
  939. fmconfig->windowwidth=fmmain.ikkuna->Width;
  940. RefreshGList(&edit->exitgadget.gadget,fmmain.ikkuna,0,-1);
  941. edit->gads=1;
  942. ReleaseSemaphore(&fmmain.gfxsema);
  943.  
  944. edit->buffer=allocvec(edit->list,edit->bufsize,MEMF_CLEAR);
  945. if(!edit->buffer) goto editend;
  946. edit->usebufsize=edit->bufsize;
  947. if(edit->screenbytes>edit->usebufsize) edit->usebufsize=edit->screenbytes;
  948. edit->usebuffer=allocvec(edit->list,edit->usebufsize,MEMF_CLEAR);
  949. if(!edit->usebuffer) goto editend;
  950.  
  951. offset=edit->offset;
  952. edit->offset=-1;
  953. if(!readoffset(edit,offset)) goto editend;
  954. editoutput(edit);
  955. return(1);
  956. editend:
  957. freeedit(edit);
  958. return(0);
  959. }
  960.  
  961. void freeedit(struct Edit *edit)
  962. {
  963. freelistgads();
  964. freegadgets(fmmain.firstgadget); fmmain.firstgadget=0;
  965. freemem(edit->buffer);
  966. edit->buffer=0;
  967. freemem(edit->usebuffer);
  968. edit->usebuffer=0;
  969. if(edit->gads) RemoveGList(fmmain.ikkuna,&edit->exitgadget.gadget,-1);
  970. edit->gads=0;
  971. }
  972.  
  973. WORD readfileedit(struct Edit *edit)
  974. {
  975. WORD ret;
  976.  
  977. memseti(edit->usebuffer,0,edit->usebufsize);
  978. switch(edit->type)
  979. {
  980. case 0:
  981. if(seek(edit->handle,edit->offset,OFFSET_BEGINNING)<0) return(0);
  982. if(readbufferfile(edit->handle,edit->buffer,edit->bufsize)<0) return(0);
  983. return(1);
  984. break;
  985. case 1:
  986. edit->ioreq->io_Command=CMD_READ;
  987. edit->ioreq->io_Data=edit->buffer;
  988. edit->ioreq->io_Length=edit->blocklen;
  989. edit->ioreq->io_Offset=edit->offset+edit->lowoffset;
  990. ret=diskio(edit->list,edit->ioreq);
  991. if(!ret) memseti(edit->buffer,0,edit->blocklen);
  992. edit->ioreq->io_Command=TD_MOTOR;
  993. edit->ioreq->io_Length=0;
  994. diskio(edit->list,edit->ioreq);
  995. edit->changed=1;
  996. return(ret);
  997. break;
  998. }
  999. }
  1000.  
  1001. WORD writefileedit(struct Edit *edit)
  1002. {
  1003. if(!requestmsg(edit->list->workname,MSG_YES,MSG_NO,MSG_MAIN_AREYOUSURE)) return(1);
  1004. memseti(edit->usebuffer,0,edit->usebufsize);
  1005. switch(edit->type)
  1006. {
  1007. case 0:
  1008. if(seek(edit->handle,edit->offset,OFFSET_BEGINNING)<0) return(0);
  1009. if(writefile(edit->handle,edit->buffer,edit->bufsize)<0) return(0);
  1010. strcpymsg(edit->list->fmmessage1,MSG_MAIN_COMPLETED);
  1011. fmmessage(edit->list);
  1012. return(1);
  1013. break;
  1014. case 1:
  1015. if(checksum(edit->buffer,edit->blocklen)) {
  1016.     if(requestmsg(edit->list->workname,MSG_YES,MSG_NO,MSG_FDEDIT_CALCCHECKSUM)) {
  1017.         *((ULONG*)&edit->buffer[4*5])=0;
  1018.         *((ULONG*)&edit->buffer[4*5])=-checksum(edit->buffer,edit->blocklen);
  1019.         editoutput(edit);
  1020.     }
  1021. }
  1022. edit->ioreq->io_Command=CMD_WRITE;
  1023. edit->ioreq->io_Data=edit->buffer;
  1024. edit->ioreq->io_Length=edit->blocklen;
  1025. edit->ioreq->io_Offset=edit->offset+edit->lowoffset;
  1026. diskio(edit->list,edit->ioreq);
  1027. edit->ioreq->io_Command=CMD_UPDATE;
  1028. if(!diskio(edit->list,edit->ioreq)) {
  1029.     edit->ioreq->io_Command=CMD_CLEAR;
  1030.     diskio(edit->list,edit->ioreq);
  1031. } else {
  1032.     strcpymsg(edit->list->fmmessage1,MSG_MAIN_COMPLETED);
  1033.     fmmessage(edit->list);
  1034. }
  1035. edit->ioreq->io_Command=TD_MOTOR;
  1036. edit->ioreq->io_Length=0;
  1037. diskio(edit->list,edit->ioreq);
  1038. return(1);
  1039. break;
  1040. }
  1041. }
  1042.  
  1043. void blockinfo(struct Edit *edit)
  1044. {
  1045. ULONG type1,type2;
  1046. ULONG *ptr;
  1047. UBYTE name[40],date1[40],date2[40],vara[100],cnt[16];
  1048. WORD dtype;
  1049. struct FMList *list;
  1050. UBYTE *aschex;
  1051.  
  1052. list=edit->list;
  1053. list->fmmessage1[0]=0;list->fmmessage2[0]=0;
  1054. ptr=(ULONG*)edit->buffer;
  1055.  
  1056. switch(edit->mode)
  1057. {
  1058. case 0:
  1059. aschex=getstring(MSG_FDEDIT_HEX);
  1060. break;
  1061. case 1:
  1062. aschex=getstring(MSG_FDEDIT_ASC);
  1063. break;
  1064. default:
  1065. aschex=" ";
  1066. break;
  1067. }
  1068. type1=ptr[0];
  1069. type2=ptr[127];
  1070. dtype=MSG_FDEDIT_DISKUNKNOWN;
  1071. if(type1==2&&type2==1) {
  1072.     dtype=MSG_FDEDIT_DISKROOT3;
  1073.     if(edit->changed) {
  1074.         siirrabstr(edit->buffer+0x1b0,name);    
  1075.         longtodatestring(date1,dstolong((struct DateStamp*)(edit->buffer+0x1a4)));
  1076.         longtodatestring(date2,dstolong((struct DateStamp*)(edit->buffer+0x1e4)));
  1077.         sformatmsg(list->fmmessage1,MSG_FDEDIT_DISKROOT1,name,date2,date1);
  1078.         sformatmsg(list->fmmessage2,MSG_FDEDIT_DISKROOT2,ptr[79]);
  1079.     }
  1080. }
  1081. if(type1==2&&type2==0xfffffffd) {
  1082.     dtype=MSG_FDEDIT_DISKFILE3;
  1083.     if(edit->changed) {
  1084.         siirrabstr(edit->buffer+0x1b0,name);
  1085.         longtodatestring(date1,dstolong((struct DateStamp*)(edit->buffer+0x1a4)));
  1086.         sformatmsg(list->fmmessage1,MSG_FDEDIT_DISKFILE1,name,ptr[81],date1);
  1087.         sformatmsg(list->fmmessage2,MSG_FDEDIT_DISKFILE2,ptr[2],ptr[4],ptr[124],ptr[125],ptr[126]);
  1088.     }
  1089. }
  1090. if(type1==2&&type2==2) {
  1091.     dtype=MSG_FDEDIT_DISKDIR3;
  1092.     if(edit->changed) {
  1093.         siirrabstr(edit->buffer+0x1b0,name);
  1094.         longtodatestring(date1,dstolong((struct DateStamp*)(edit->buffer+0x1a4)));
  1095.         sformatmsg(list->fmmessage1,MSG_FDEDIT_DISKDIR1,name,date1);
  1096.         sformatmsg(list->fmmessage2,MSG_FDEDIT_DISKDIR2,ptr[124],ptr[125]);
  1097.     }
  1098. }
  1099. if(type1==16&&type2==0xfffffffd) {
  1100.     dtype=MSG_FDEDIT_DISKLIST3;
  1101.     if(edit->changed) {
  1102.         sformatmsg(list->fmmessage1,MSG_FDEDIT_DISKLIST1,ptr[2],ptr[125],ptr[126]);
  1103.     }
  1104. }
  1105. if(type1==8&&edit->dosenv->de_DosType==0x444f5300) {
  1106.     dtype=MSG_FDEDIT_DISKDATA3;
  1107.     if(edit->changed) {
  1108.         sformatmsg(list->fmmessage1,MSG_FDEDIT_DISKDATA1,ptr[1],ptr[2],ptr[3],ptr[4]);
  1109.     }
  1110. }
  1111. cnt[0]=0;
  1112. if(edit->mode>=0) sformat(cnt,"%03.3d %s",edit->cursoroffset+edit->screenoffset,aschex);
  1113. sformatmsg(vara,MSG_FDEDIT_DISKINFO1,checksum(edit->buffer,edit->blocklen)?'-':'+',getstring(dtype),edit->screenoffset,cnt);
  1114. fittext(fmmain.rp,vara,-1,edit->xoffsetasc-1,edit->infoliney+1,edit->ascwidth,0);
  1115. if(edit->changed) fmmessage(list);
  1116. edit->changed=0;
  1117. }
  1118.  
  1119. void checkblocks(struct Edit *edit,WORD mode)
  1120. {
  1121. struct DosEnvec *de;
  1122.  
  1123. de=edit->dosenv;
  1124. if(!mode) {
  1125.     if(edit->tracks<0) edit->tracks=0;
  1126.     if(edit->tracks>de->de_HighCyl) edit->tracks=de->de_HighCyl;
  1127.     if(edit->sectors<0) edit->sectors=0;
  1128.     if(edit->sectors>=de->de_BlocksPerTrack) edit->sectors=de->de_BlocksPerTrack-1;
  1129.     if(edit->heads<0) edit->heads=0;
  1130.     if(edit->heads>=de->de_Surfaces) edit->heads=de->de_Surfaces-1;
  1131.     edit->blocks=edit->tracks*edit->dosenv->de_Surfaces*edit->dosenv->de_BlocksPerTrack;
  1132.     edit->blocks+=edit->heads*edit->dosenv->de_BlocksPerTrack;
  1133.     edit->blocks+=edit->sectors;
  1134. }
  1135. calcblocks(edit);
  1136. readoffset(edit,edit->blocks*edit->blocklen);
  1137. }
  1138.  
  1139. void calcblocks(struct Edit *edit)
  1140. {
  1141. struct DosEnvec *de;
  1142.  
  1143. de=edit->dosenv;
  1144. edit->sectors=edit->blocks%de->de_BlocksPerTrack;
  1145. edit->tracks=edit->blocks/(de->de_BlocksPerTrack*de->de_Surfaces);
  1146. edit->heads=(edit->blocks/de->de_BlocksPerTrack)%de->de_Surfaces;
  1147. sformat(edit->blockgad.buffer,"%ld",edit->blocks);
  1148. edit->blockgad.si.LongInt=edit->blocks;
  1149. sformat(edit->trackgad.buffer,"%ld",edit->tracks);
  1150. edit->trackgad.si.LongInt=edit->tracks;
  1151. sformat(edit->secgad.buffer,"%ld",edit->sectors);
  1152. edit->secgad.si.LongInt=edit->sectors;
  1153. sformat(edit->headgad.buffer,"%ld",edit->heads);
  1154. edit->headgad.si.LongInt=edit->heads;
  1155. RefreshGList(&edit->blockgad.gadget,fmmain.ikkuna,0,4);
  1156. }
  1157.  
  1158. void limitblocks(struct Edit *edit,WORD mode,WORD dir)
  1159. {
  1160. LONG *ptr;
  1161. struct DosEnvec *de;
  1162.  
  1163. if(mode<0) return;
  1164. de=edit->dosenv;
  1165. ptr=&edit->blocks;
  1166. ptr[mode]+=dir;
  1167. if(edit->blocks<0) edit->blocks=0;
  1168. if(edit->blocks>=edit->maxoffset/edit->blocklen) edit->blocks=edit->maxoffset/edit->blocklen-1;
  1169.  
  1170. if(edit->sectors<0) {
  1171.     edit->sectors=de->de_BlocksPerTrack-1;
  1172.     edit->heads--;
  1173. }
  1174. if(edit->sectors>=de->de_BlocksPerTrack) {
  1175.     edit->sectors=0;
  1176.     edit->heads++;
  1177. }
  1178. if(edit->heads<0) {
  1179.     edit->heads=de->de_Surfaces-1;
  1180.     edit->tracks--;
  1181. }
  1182. if(edit->heads>=de->de_Surfaces) {
  1183.     edit->heads=0;
  1184.     edit->tracks++;
  1185. }
  1186. checkblocks(edit,!mode?1:0);
  1187. }
  1188.  
  1189. void search(struct Edit *edit,WORD mode)
  1190. {
  1191. UBYTE str[64];
  1192. WORD len,len2;
  1193. WORD cnt;
  1194. UBYTE apu1,apu2;
  1195. UBYTE *sbuf=0;
  1196. LONG size;
  1197. LONG apu3,apu4;
  1198. LONG offset;
  1199. UBYTE hexdec;
  1200. LONG bufsize;
  1201. LONG oldoffset;
  1202.  
  1203. edit->list->fmmessage1[0]=0;
  1204. edit->list->fmmessage2[0]=0;
  1205. fmmessage(edit->list);
  1206. edit->list->flags&=~LABORTREQ;
  1207.  
  1208. if(!mode||edit->searchstring[0]==0) {
  1209.     if(!askstring(0,edit->list->workname,getstring(MSG_FDEDIT_SEARCH),edit->searchstring,32)) return;
  1210. }
  1211. len=strlen(edit->searchstring);
  1212. if(edit->searchstring[0]=='$') {
  1213.     hexdec=1;
  1214.     cnt=0;
  1215.     if(!(len&1)||len<=1) goto fail;
  1216.     len2=len-1;
  1217.     len=0;
  1218.     while(len2) {
  1219.         apu1=ToUpper(edit->searchstring[cnt*2+1])-'0';
  1220.         if(apu1>9) apu1-=7;
  1221.         if(apu1>15) goto fail;
  1222.         apu2=ToUpper(edit->searchstring[cnt*2+2])-'0';
  1223.         if(apu2>9) apu2-=7;
  1224.         if(apu2>15) goto fail;
  1225.         str[cnt++]=apu1<<4|apu2;
  1226.         len2-=2;
  1227.         len++;
  1228.     }
  1229. } else {
  1230.     hexdec=0;
  1231.     for(cnt=0;cnt<len;cnt++) str[cnt]=ToUpper(edit->searchstring[cnt]);
  1232.     str[cnt]=0;
  1233.     if(cnt<=0) goto fail;
  1234. }
  1235. if(edit->type) {
  1236.     bufsize=((fmconfig->dosbuffersize&0x00ffffff)/edit->blocklen)*edit->blocklen;
  1237.     sbuf=allocvec(edit->list,bufsize,0);
  1238.     if(sbuf) {
  1239.         edit->list->flags|=LUPDATEMSG;
  1240.         if(edit->oldsearch!=-1) 
  1241.             offset=edit->oldsearch+edit->blocklen;
  1242.             else
  1243.             offset=edit->offset;
  1244.         edit->oldsearch=-1;
  1245.         sformatmsg(edit->list->fmmessage1,MSG_FDEDIT_SEARCHING,offset/edit->blocklen,edit->maxoffset/edit->blocklen);
  1246.         fmmessage(edit->list);
  1247.         while(offset<edit->maxoffset) {
  1248.             sformatmsg(edit->list->fmmessage1,MSG_FDEDIT_SEARCHING,offset/edit->blocklen,edit->maxoffset/edit->blocklen);
  1249.             if(testabort(edit->list)) break;
  1250.             size=bufsize;
  1251.             if(size>edit->maxoffset-offset) {
  1252.                 size=edit->maxoffset-offset;
  1253.                 apu4=size;
  1254.             } else {
  1255.                 apu4=size-edit->blocklen;
  1256.             }
  1257.             oldoffset=edit->offset;
  1258.             edit->offset=offset;
  1259.             calcblocks(edit);
  1260.             edit->offset=oldoffset;
  1261.             edit->ioreq->io_Command=CMD_READ;
  1262.             edit->ioreq->io_Data=sbuf;
  1263.             edit->ioreq->io_Length=size;
  1264.             edit->ioreq->io_Offset=offset+edit->lowoffset;
  1265.             if(!diskio(edit->list,edit->ioreq)) break;
  1266.             if(!hexdec) for(apu3=0;apu3<size;apu3++) sbuf[apu3]=ToUpper(sbuf[apu3]);
  1267.             for(apu3=0;apu3<apu4;apu3++) {
  1268.                 if(!memcmp(str,&sbuf[apu3],len)) {
  1269.                     apu4=apu3+offset;
  1270.                     offset+=apu3;
  1271.                     offset=(offset/edit->blocklen)*edit->blocklen;
  1272.                     readoffset(edit,offset);
  1273.                     apu3=apu4;
  1274.                     apu4-=edit->offset;
  1275.                     for(cnt=0;cnt<len;cnt++) {
  1276.                         if(apu4+cnt>=0&&apu4+cnt<=edit->blocklen) edit->usebuffer[apu4+cnt]=2;
  1277.                         }
  1278.                     editoutput(edit);
  1279.                     edit->oldsearch=apu3;
  1280.                     goto sok;
  1281.                 }
  1282.             }
  1283.             offset+=bufsize-edit->blocklen;
  1284.         }
  1285.         DisplayBeep(0);
  1286.     }
  1287. } else {
  1288.     bufsize=(fmconfig->dosbuffersize&0x00ffffff);
  1289.     sbuf=allocvec(edit->list,bufsize,0);
  1290.     if(sbuf) {
  1291.         edit->list->flags|=LUPDATEMSG;
  1292.         if(edit->oldsearch!=-1) 
  1293.             offset=edit->oldsearch+1;
  1294.             else
  1295.             offset=edit->offset;
  1296.         edit->oldsearch=-1;
  1297.         sformatmsg(edit->list->fmmessage1,MSG_FDEDIT_SEARCHING,offset,edit->handle->size);
  1298.         fmmessage(edit->list);
  1299.         while(offset<edit->handle->size) {
  1300.             sformatmsg(edit->list->fmmessage1,MSG_FDEDIT_SEARCHING,offset,edit->handle->size);
  1301.             if(testabort(edit->list)) break;
  1302.             if(seek(edit->handle,offset,OFFSET_BEGINNING)<0) break;
  1303.             size=bufsize;
  1304.             if(size>edit->handle->size-edit->handle->position) {
  1305.                 size=edit->handle->size-edit->handle->position;
  1306.                 apu4=size;
  1307.             } else {
  1308.                 apu4=size-128;
  1309.             }
  1310.             if(readbufferfile(edit->handle,sbuf,size)<0) break;
  1311.             if(!hexdec) for(apu3=0;apu3<size;apu3++) sbuf[apu3]=ToUpper(sbuf[apu3]);
  1312.             for(apu3=0;apu3<apu4;apu3++) {
  1313.                 if(!memcmp(str,&sbuf[apu3],len)) {
  1314.                     apu4=apu3+offset;
  1315.                     offset+=(apu3-edit->screenbytes/2);
  1316.                     readoffset(edit,offset);
  1317.                     apu3=apu4;
  1318.                     apu4-=edit->offset;
  1319.                     for(cnt=0;cnt<len;cnt++) {
  1320.                         if(apu4+cnt>=0&&apu4+cnt<=edit->screenbytes) edit->usebuffer[apu4+cnt]=2;
  1321.                         }
  1322.                     editoutput(edit);
  1323.                     edit->oldsearch=apu3;
  1324.                     goto sok;
  1325.                     }
  1326.             }
  1327.             offset+=bufsize-128;
  1328.         }
  1329.         DisplayBeep(0);
  1330.     }
  1331. }
  1332. sok:
  1333. if(edit->type) {
  1334.     edit->ioreq->io_Command=TD_MOTOR;
  1335.     edit->ioreq->io_Length=0;
  1336.     diskio(edit->list,edit->ioreq);
  1337. }
  1338. edit->list->flags&=~LUPDATEMSG;
  1339. edit->list->fmmessage1[0]=0;
  1340. fmmessage(edit->list);
  1341. freemem(sbuf);
  1342. return;
  1343. fail:
  1344. requestmsg(edit->list->workname,0,MSG_OK,MSG_FDEDIT_ILLEGALSEARCH);
  1345. }
  1346.  
  1347. void askline(struct Edit *edit)
  1348. {
  1349. LONG offset;
  1350.  
  1351. offset=edit->offset;
  1352. if(!asklong(0,edit->list->workname,getstring(MSG_FDEDIT_BYTENUMBER),&offset,0,edit->handle->size)) return;
  1353. readoffset(edit,offset);
  1354. }
  1355.  
  1356. WORD editprocessgadget(struct Edit *edit,struct IntuiMessage *msg,WORD id)
  1357. {
  1358. if(edit->keyshorts[3]==id) {
  1359.     search(edit,msg->Qualifier&0x80);
  1360. }
  1361. if(edit->keyshorts[0]==id) return(1);
  1362. if(edit->keyshorts[2]==id) {
  1363.     if(!readfileedit(edit)) return(1);
  1364.     editoutput(edit);
  1365. }
  1366. if(edit->keyshorts[1]==id) {
  1367.     writefileedit(edit);
  1368.     editoutput(edit);
  1369. }
  1370. return(0);
  1371. }
  1372.  
  1373. void *diskeditconfigdefault(struct CMenuConfig *cmc)
  1374. {
  1375. struct DiskEditConfig *config;
  1376. WORD ret;
  1377.  
  1378. ret=allocconfig(cmc,sizeof(struct DiskEditConfig));
  1379. if(ret<0) return(cmc->moreconfig);
  1380. if(!ret) return(0);
  1381. config=(struct DiskEditConfig*)cmc->moreconfig;
  1382. return(cmc->moreconfig);
  1383. }
  1384.  
  1385. WORD diskeditconfig(struct GUIBase *gb,struct CMenuConfig *cmc)
  1386. {
  1387. struct DiskEditConfig *config;
  1388. WORD c,lowcyl;
  1389.  
  1390. config=getconfig(cmc);
  1391. lowcyl=config->lowcyl;
  1392. setguigroup(gb,1,0);
  1393. reqinfomsg(gb,MSG_FDEDIT_CONFIG_NOLOWCYL,100,guiUC|guiLEFT);
  1394. setguigroup(gb,2,0);
  1395. reqcycle2msg(gb,100,&lowcyl);
  1396. commandanswer(gb);
  1397. c=quickreq(gb);
  1398. config->lowcyl=lowcyl;
  1399. return(c);
  1400. }
  1401.