1 #include <exec/memory.h>
2 #include <intuition/intuition.h>
3 #include <intuition/screens.h>
4 #include <libraries/iffparse.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"
13 #include "../FS/asmsupport.c"
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
;
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 */
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.
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
);
63 struct RDArgs
*readarg
;
64 UBYTE
template[]="DEVICE/A,DEBUG/S\n";
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
;
77 UBYTE
*devname
=arglist
.name
;
87 dl
=LockDosList(LDF_DEVICES
|LDF_READ
);
88 if((dl
=FindDosEntry(dl
, arglist
.name
, LDF_DEVICES
))!=0) {
92 UnLockDosList(LDF_DEVICES
|LDF_READ
);
95 struct TagItem tags
[] = {
96 {ASQ_TOTAL_BLOCKS
, 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,
115 WA_DepthGadget
, TRUE
,
116 WA_CloseGadget
, TRUE
,
118 WA_Title
, "SFS defragmentation window",
120 WA_GimmeZeroZero
, TRUE
,
121 WA_IDCMP
, IDCMP_MOUSEBUTTONS
|IDCMP_NEWSIZE
|IDCMP_CLOSEWINDOW
,
123 BYTE defragmented
=FALSE
;
125 rastport
=mywindow
->RPort
;
127 initfield(blocks_total
);
134 struct IntuiMessage
*msg
;
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
;
144 while(lastblocks
[e
]!=0) {
145 render(lastread
[e
], lastblocks
[e
], 0);
146 render(lastwritten
[e
], lastblocks
[e
], 1);
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];
168 else if(ds
->id
==AROS_BE2LONG(MAKE_ID('D','O','N','E'))) {
172 ds
=(struct DefragmentStep
*)((ULONG
*)ds
+ 2 + ds
->length
);
177 if(arglist
.debug
!=0 && e
!=0) {
183 WaitPort(mywindow
->UserPort
);
186 while((msg
=(struct IntuiMessage
*)GetMsg(mywindow
->UserPort
))!=0) {
190 ReplyMsg((struct Message
*)msg
);
192 if(class==IDCMP_CLOSEWINDOW
) {
193 // if(code==IECODE_LBUTTON) {
197 else if(class==IDCMP_NEWSIZE
) {
198 initfield(blocks_total
);
201 } while(exit
==FALSE
);
204 CloseWindow(mywindow
);
213 PutStr("Version of SmartFilesystem must be 1.83 or newer. You're using an older version.\n");
219 Printf("Couldn't find device '%s:'.\n",arglist
.name
);
220 UnLockDosList(LDF_DEVICES
|LDF_READ
);
226 CloseLibrary((struct Library
*)GfxBase
);
227 CloseLibrary((struct Library
*)IntuitionBase
);
228 CloseLibrary((struct Library
*)DOSBase
);
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
242 for(i
=16; i
>=0; i
--) {
249 bpu
= (blocks_total
+units
-1) / units
;
263 void render(ULONG block
, ULONG blocks
, WORD pen
) {
264 ULONG firstunit
=block
/bpu
;
265 ULONG lastunit
=(block
+blocks
-1)/bpu
;
267 ULONG endline
, endoffset
;
270 SetAPen(rastport
, pen
);
272 line
=firstunit
/ uhor
;
273 offset
=firstunit
% uhor
;
275 endline
=lastunit
/ uhor
;
276 endoffset
=lastunit
% uhor
;
283 Move(rastport
, dx
+ offset
* uw
, dy
+ line
* uh
+ i
);
284 Draw(rastport
, dx
+ endoffset
* uw
+ uw
-1, dy
+ line
* uh
+ i
);
292 Move(rastport
, dx
+ offset
* uw
, dy
+ line
* uh
+ i
);
293 Draw(rastport
, dx
+ (uhor
* uw
) - 1, dy
+ line
* uh
+ i
);
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
) {
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
);
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
);
362 render(start
, end
-start
, 1);