grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / filesys / SFS / SFSdefragmentGUI / SFSdefragmentGUI.c
blob5bd50c8d58e6e507d4cb40d8abd0fa8a06767fe6
1 #include <exec/memory.h>
2 #include <intuition/intuition.h>
3 #include <intuition/screens.h>
4 #include <libraries/iffparse.h>
5 #include <proto/dos.h>
6 #include <proto/exec.h>
7 #include <proto/graphics.h>
8 #include <proto/intuition.h>
9 #include <utility/tagitem.h>
10 #include "../FS/packets.h"
11 #include "../FS/query.h"
12 #include <stdio.h>
13 #include "../FS/asmsupport.c"
14 #undef SysBase
15 #undef IntuitionBase
16 #undef DOSBase
18 /* Note to people who wish to use this source:
19 -------------------------------------------
21 This code was created in just a few hours mainly to help debugging
22 the Defragmenter visually. No great effort has been made to make
23 it completely stable or OS conform, so beware.
25 There's definitely more work to be done :-) */
27 struct Window *mywindow;
28 struct RastPort *rastport;
29 UWORD dx=10;
30 UWORD dy=10;
32 UWORD uw; /* UnitWidth */
33 UWORD uh; /* UnitHeight */
34 ULONG ppu; /* Pixels per Unit */
35 UWORD uhor; /* Units horizontally */
36 UWORD uver; /* Units vertically */
37 ULONG units; /* Total number of Units */
38 ULONG bpu; /* Blocks per Unit */
39 ULONG dw=900, dh=600; /* Defrag width & height */
41 ULONG *bitmap;
43 const char version[]="\0$VER: SFSdefragmentGUI 1.2 (" ADATE ")\r\n";
45 struct DefragmentStep {
46 ULONG id; // id of the step ("MOVE", "DONE" or 0)
47 ULONG length; // length in longwords (can be 0)
48 ULONG data[0]; // size of this array is determined by length.
51 ULONG steps[200];
53 ULONG lastread[200/5];
54 ULONG lastwritten[200/5];
55 ULONG lastblocks[200/5];
57 void render(ULONG block, ULONG blocks, WORD pen);
58 void recalc(ULONG blocks_total, WORD w, WORD h);
59 void drawrect(UWORD x, UWORD y, UWORD w, UWORD h, WORD pen);
60 void initfield(ULONG blocks_total);
62 int main() {
63 struct RDArgs *readarg;
64 UBYTE template[]="DEVICE/A,DEBUG/S\n";
65 WORD exit=FALSE;
67 struct {char *name;
68 IPTR debug;} arglist={NULL};
70 DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37);
71 IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37);
72 GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37);
74 if((readarg=ReadArgs(template,(IPTR *)&arglist,0))!=0) {
75 struct MsgPort *msgport;
76 struct DosList *dl;
77 UBYTE *devname=arglist.name;
79 while(*devname!=0) {
80 if(*devname==':') {
81 *devname=0;
82 break;
84 devname++;
87 dl=LockDosList(LDF_DEVICES|LDF_READ);
88 if((dl=FindDosEntry(dl, arglist.name, LDF_DEVICES))!=0) {
89 LONG errorcode;
91 msgport=dl->dol_Task;
92 UnLockDosList(LDF_DEVICES|LDF_READ);
95 struct TagItem tags[] = {
96 {ASQ_TOTAL_BLOCKS, 0},
97 {ASQ_VERSION , 0},
98 {TAG_END , 0}
101 if((errorcode=DoPkt(msgport, ACTION_SFS_QUERY, (SIPTR)tags, 0, 0, 0, 0))!=DOSFALSE) {
102 ULONG blocks_total=tags[0].ti_Data;
104 if(tags[1].ti_Data >= (1<<16) + 83) {
105 if((errorcode=DoPkt(msgport, ACTION_SFS_DEFRAGMENT_INIT, 0, 0, 0, 0, 0))!=DOSFALSE) {
106 if((bitmap=AllocVec(blocks_total / 8 + 32, MEMF_CLEAR))!=0) {
107 if((errorcode=DoPkt(msgport, ACTION_SFS_READ_BITMAP, (SIPTR)bitmap, 0, blocks_total, 0, 0))!=DOSFALSE) {
108 if((mywindow=OpenWindowTags(0, WA_Width, dw+16,
109 WA_Height, dh+16,
110 WA_MinWidth, 100,
111 WA_MinHeight, 100,
112 WA_MaxWidth, 10000,
113 WA_MaxHeight, 10000,
114 WA_SizeGadget, TRUE,
115 WA_DepthGadget, TRUE,
116 WA_CloseGadget, TRUE,
117 WA_DragBar, TRUE,
118 WA_Title, "SFS defragmentation window",
119 WA_Activate, TRUE,
120 WA_GimmeZeroZero, TRUE,
121 WA_IDCMP, IDCMP_MOUSEBUTTONS|IDCMP_NEWSIZE|IDCMP_CLOSEWINDOW,
122 TAG_DONE))!=0) {
123 BYTE defragmented=FALSE;
125 rastport=mywindow->RPort;
127 initfield(blocks_total);
129 lastread[0]=0;
130 lastwritten[0]=0;
131 lastblocks[0]=0;
133 do {
134 struct IntuiMessage *msg;
135 UWORD class;
137 if(defragmented==FALSE) {
138 if((errorcode=DoPkt(msgport, ACTION_SFS_DEFRAGMENT_STEP, (SIPTR)steps, 190, 0, 0, 0))!=DOSFALSE) {
139 struct DefragmentStep *ds=(struct DefragmentStep *)steps;
140 WORD e;
142 e=0;
144 while(lastblocks[e]!=0) {
145 render(lastread[e], lastblocks[e], 0);
146 render(lastwritten[e], lastblocks[e], 1);
147 e++;
150 e=0;
152 while(ds->id!=0) {
153 if(ds->id==AROS_BE2LONG(MAKE_ID('M','O','V','E')) && ds->length==3) {
154 render(ds->data[1], ds->data[0], 2);
155 render(ds->data[2], ds->data[0], 3);
156 bmclr(bitmap, (blocks_total+31)/32, ds->data[2], ds->data[0]);
157 bmset(bitmap, (blocks_total+31)/32, ds->data[1], ds->data[0]);
159 if(arglist.debug!=0) {
160 printf("Moved %lu blocks from %lu to %lu\n", (unsigned long)ds->data[0], (unsigned long)ds->data[1], (unsigned long)ds->data[2]);
163 lastread[e]=ds->data[1];
164 lastwritten[e]=ds->data[2];
165 lastblocks[e]=ds->data[0];
166 e++;
168 else if(ds->id==AROS_BE2LONG(MAKE_ID('D','O','N','E'))) {
169 defragmented=TRUE;
170 break;
172 ds=(struct DefragmentStep *)((ULONG *)ds + 2 + ds->length);
175 lastblocks[e]=0;
177 if(arglist.debug!=0 && e!=0) {
178 printf("\n");
182 else {
183 WaitPort(mywindow->UserPort);
186 while((msg=(struct IntuiMessage *)GetMsg(mywindow->UserPort))!=0) {
188 class=msg->Class;
190 ReplyMsg((struct Message *)msg);
192 if(class==IDCMP_CLOSEWINDOW) {
193 // if(code==IECODE_LBUTTON) {
194 exit=TRUE;
195 // }
197 else if(class==IDCMP_NEWSIZE) {
198 initfield(blocks_total);
201 } while(exit==FALSE);
204 CloseWindow(mywindow);
208 FreeVec(bitmap);
212 else {
213 PutStr("Version of SmartFilesystem must be 1.83 or newer. You're using an older version.\n");
218 else {
219 Printf("Couldn't find device '%s:'.\n",arglist.name);
220 UnLockDosList(LDF_DEVICES|LDF_READ);
223 FreeArgs(readarg);
226 CloseLibrary((struct Library *)GfxBase);
227 CloseLibrary((struct Library *)IntuitionBase);
228 CloseLibrary((struct Library *)DOSBase);
230 return 0;
235 void recalc(ULONG blocks_total, WORD w, WORD h) {
236 UBYTE pixw[17]={ 1, 2, 3, 2, 3, 4, 3, 5, 4, 5, 4, 6, 5, 6, 5, 6, 6};
237 UBYTE pixh[17]={ 1, 1, 1, 2, 2, 2, 3, 2, 3, 3, 4, 3, 4, 4, 5, 5, 6};
238 // 1 2 3 4 6 8 9 10 12 15 16 18 20 24 25 30 36
240 WORD i;
242 for(i=16; i>=0; i--) {
243 uw = pixw[i];
244 uh = pixh[i];
245 ppu = uw * uh;
246 uhor = w/uw;
247 uver = h/uh;
248 units = uhor * uver;
249 bpu = (blocks_total+units-1) / units;
251 if(bpu<=1) {
252 break;
256 if(bpu==0) {
257 bpu=1;
263 void render(ULONG block, ULONG blocks, WORD pen) {
264 ULONG firstunit=block/bpu;
265 ULONG lastunit=(block+blocks-1)/bpu;
266 ULONG line, offset;
267 ULONG endline, endoffset;
268 UWORD i;
270 SetAPen(rastport, pen);
272 line=firstunit / uhor;
273 offset=firstunit % uhor;
275 endline=lastunit / uhor;
276 endoffset=lastunit % uhor;
278 for(;;) {
279 if(line==endline) {
280 i=uh;
282 while(i-->0) {
283 Move(rastport, dx + offset * uw, dy + line * uh + i);
284 Draw(rastport, dx + endoffset * uw + uw-1, dy + line * uh + i);
286 break;
288 else {
289 i=uh;
291 while(i-->0) {
292 Move(rastport, dx + offset * uw, dy + line * uh + i);
293 Draw(rastport, dx + (uhor * uw) - 1, dy + line * uh + i);
297 line++;
298 offset=0;
316 void drawrect(UWORD x, UWORD y, UWORD w, UWORD h, WORD pen) {
317 SetAPen(rastport, pen);
319 Move(rastport, x, y);
320 Draw(rastport, x, y+h-1);
321 Draw(rastport, x+w-1, y+h-1);
322 Draw(rastport, x+w-1, y);
323 Draw(rastport, x, y);
327 void drawbox(UWORD x, UWORD y, UWORD w, UWORD h, WORD pen) {
328 SetAPen(rastport, pen);
329 RectFill(rastport, x, y, x+w-1, y+h-1);
334 void initfield(ULONG blocks_total) {
335 ULONG start,end;
336 ULONG current=0;
337 UWORD fieldw, fieldh;
339 drawbox(0, 0, mywindow->GZZWidth, mywindow->GZZHeight, 0);
341 dw=mywindow->GZZWidth-20;
342 dh=mywindow->GZZHeight-20;
344 recalc(blocks_total, dw, dh);
346 fieldw=uhor*uw;
347 fieldh=(((blocks_total+bpu-1) / bpu + uhor-1) / uhor) * uh;
349 drawrect(dx-3, dy-3, fieldw+6, fieldh+6, -1);
350 drawrect(dx-2, dy-2, fieldw+4, fieldh+4, -1);
352 // printf("%ld pixel = %ld blocks\n", uh*uw, bpu);
354 while(current<blocks_total) {
355 start=bmffz(bitmap, (blocks_total+31)/32, current);
356 end=bmffo(bitmap, (blocks_total+31)/32, start);
358 if(end==-1) {
359 end=blocks_total;
362 render(start, end-start, 1);
363 current=end;