Fixed a typo.
[AROS.git] / workbench / tools / HDToolBox / ptclass.c
blob6c4d533c2d2ce8c43b41cc4bf84af1298b9fce1f
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <proto/alib.h>
7 #include <proto/exec.h>
8 #include <proto/graphics.h>
9 #include <proto/intuition.h>
10 #include <proto/utility.h>
12 #include <intuition/cghooks.h>
13 #include <intuition/classes.h>
14 #include <intuition/classusr.h>
15 #include <intuition/gadgetclass.h>
16 #include <intuition/intuition.h>
17 #include <intuition/imageclass.h>
19 #include <string.h>
21 #include "ptclass.h"
22 #include "partitions.h"
23 #include "partitiontables.h"
24 #include "platform.h"
26 #define DEBUG 0
27 #include "debug.h"
29 #define G(a) ((struct Gadget *)a)
31 #define DPTYPE_EMPTY 0
32 #define DPTYPE_EMPTY_SELECTED 1
33 #define DPTYPE_USED 2
34 #define DPTYPE_USED_SELECTED 3
36 #define PARTITIONBLOCK_FRAMEWIDTH 2
38 #define END_FIX 1
40 #define EMPTY1_RED 0x99999999
41 #define EMPTY1_GREEN 0x99999999
42 #define EMPTY1_BLUE 0x99999999
44 #define EMPTY2_RED 0x65656565
45 #define EMPTY2_GREEN 0x65656565
46 #define EMPTY2_BLUE 0x65656565
48 #define EMPTY1_DARK_RED 0x66666666
49 #define EMPTY1_DARK_GREEN 0x66666666
50 #define EMPTY1_DARK_BLUE 0x66666666
52 #define EMPTY2_DARK_RED 0x42424242
53 #define EMPTY2_DARK_GREEN 0x42424242
54 #define EMPTY2_DARK_BLUE 0x42424242
56 #define EMPTY1_SEL_RED 0x40404040
57 #define EMPTY1_SEL_GREEN 0x85858585
58 #define EMPTY1_SEL_BLUE 0x99999999
60 #define EMPTY2_SEL_RED 0x29292929
61 #define EMPTY2_SEL_GREEN 0x56565656
62 #define EMPTY2_SEL_BLUE 0x63636363
64 #define USED_RED 0x02020202
65 #define USED_GREEN 0x75757575
66 #define USED_BLUE 0x02020202
68 #define USED_SEL_RED 0x66666666
69 #define USED_SEL_GREEN 0xc9c9c9c9
70 #define USED_SEL_BLUE 0x66666666
72 #define PEN_EMPTY1 0
73 #define PEN_EMPTY2 1
74 #define PEN_EMPTY1_SEL 2
75 #define PEN_EMPTY2_SEL 3
76 #define PEN_EMPTY1_DARK 4
77 #define PEN_EMPTY2_DARK 5
78 #define PEN_USED 6
79 #define PEN_USED_SEL 7
81 #define NUM_PENS 8
83 STATIC CONST ULONG rgbtable[] =
85 EMPTY1_RED , EMPTY1_GREEN , EMPTY1_BLUE ,
86 EMPTY2_RED , EMPTY2_GREEN , EMPTY2_BLUE ,
87 EMPTY1_SEL_RED , EMPTY1_SEL_GREEN , EMPTY1_SEL_BLUE ,
88 EMPTY2_SEL_RED , EMPTY2_SEL_GREEN , EMPTY2_SEL_BLUE ,
89 EMPTY1_DARK_RED , EMPTY1_DARK_GREEN , EMPTY1_DARK_BLUE ,
90 EMPTY2_DARK_RED , EMPTY2_DARK_GREEN , EMPTY2_DARK_BLUE ,
91 USED_RED , USED_GREEN , USED_BLUE ,
92 USED_SEL_RED , USED_SEL_GREEN , USED_SEL_BLUE
95 struct PTableData {
96 struct DrawInfo *dri;
97 struct Image *frame;
98 struct HDTBPartition *table;
99 struct HDTBPartition *active; /* active partition, or the DE for free space */
100 struct DosEnvec gap;
101 struct ColorMap *cm;
102 ULONG block;
103 ULONG flags;
104 WORD pens[NUM_PENS];
105 BOOL move;
106 BOOL selected;
107 BOOL multicolor;
108 BOOL firstdraw;
109 BOOL pensallocated;
112 STATIC CONST UWORD pattern[] =
114 0xAAAA, 0xAAAA,
115 0x5555, 0x5555
118 STATIC CONST UWORD pattern2[] =
120 0xFF00,
121 0xFF00,
122 0xFF00,
123 0xFF00,
124 0xFF00,
125 0xFF00,
126 0xFF00,
127 0xFF00,
128 0x00FF,
129 0x00FF,
130 0x00FF,
131 0x00FF,
132 0x00FF,
133 0x00FF,
134 0x00FF,
135 0x00FF
138 #define SetPattern(r,p,s) {r->AreaPtrn = (UWORD *)p; r->AreaPtSz = s;}
140 Class *ptcl = NULL;
142 static void PrepareRP(struct RastPort *rp, struct PTableData *data, WORD dptype)
144 D(bug("[HDToolBox] PrepareRP()\n"));
146 if (data->multicolor)
148 switch(dptype)
150 case DPTYPE_EMPTY:
151 SetPattern(rp, pattern2, 4);
152 SetABPenDrMd(rp, data->pens[PEN_EMPTY1], data->pens[PEN_EMPTY2], JAM2);
153 break;
155 case DPTYPE_EMPTY_SELECTED:
156 SetPattern(rp, pattern2, 4);
157 SetABPenDrMd(rp, data->pens[PEN_EMPTY1_SEL], data->pens[PEN_EMPTY2_SEL], JAM2);
158 break;
160 case DPTYPE_USED:
161 SetPattern(rp, NULL, 0);
162 SetABPenDrMd(rp, data->pens[PEN_USED], 0, JAM2);
163 break;
165 case DPTYPE_USED_SELECTED:
166 SetPattern(rp, NULL, 0);
167 SetABPenDrMd(rp, data->pens[PEN_USED_SEL], 0, JAM2);
168 break;
170 } /* if (data->multicolor) */
171 else
173 switch(dptype)
175 case DPTYPE_EMPTY:
176 SetPattern(rp, NULL, 0);
177 SetABPenDrMd(rp, 0, 0, JAM2);
178 break;
180 case DPTYPE_EMPTY_SELECTED:
181 SetPattern(rp, pattern, 2);
182 SetABPenDrMd(rp, 1, 0, JAM2);
183 break;
185 case DPTYPE_USED:
186 SetPattern(rp, pattern, 2);
187 SetABPenDrMd(rp, 2, 0, JAM2);
188 break;
190 case DPTYPE_USED_SELECTED:
191 SetPattern(rp, pattern, 2);
192 SetABPenDrMd(rp, 3, 0, JAM2);
193 break;
195 } /* if (data->multicolor) */
198 STATIC IPTR pt_new(Class *cl, Object *obj, struct opSet *msg)
200 struct PTableData *data;
201 struct DrawInfo *dri;
202 struct Image *frame;
203 struct HDTBPartition *table;
204 ULONG flags;
206 struct TagItem tags[] =
208 {IA_Width, 0UL },
209 {IA_Height, 0UL },
210 {IA_Resolution, 0UL },
211 {IA_FrameType, FRAME_BUTTON },
212 {TAG_DONE }
215 D(bug("[HDToolBox] pt_new()\n"));
217 dri = (struct DrawInfo *)GetTagData(GA_DrawInfo, (IPTR)NULL, msg->ops_AttrList);
218 if (!dri)
219 return (IPTR)NULL;
221 tags[0].ti_Data = GetTagData(GA_Width, 0, msg->ops_AttrList);
222 tags[1].ti_Data = GetTagData(GA_Height, 0, msg->ops_AttrList);
223 table = (struct HDTBPartition *)GetTagData(PTCT_PartitionTable, 0, msg->ops_AttrList);
224 flags = GetTagData(PTCT_Flags, 0, msg->ops_AttrList);
225 tags[2].ti_Data = (dri->dri_Resolution.X << 16) + dri->dri_Resolution.Y;
227 frame = (struct Image *) NewObjectA(NULL, FRAMEICLASS, tags);
228 if (!frame)
229 return (IPTR)NULL;
231 tags[0].ti_Tag = GA_Image;
232 tags[0].ti_Data = (IPTR) frame;
233 tags[1].ti_Tag = TAG_MORE;
234 tags[1].ti_Data = (IPTR) msg->ops_AttrList;
235 obj = (Object *) DoSuperMethodA(cl, obj, (Msg)msg);
236 if (!obj)
238 DisposeObject(frame);
239 return (IPTR)NULL;
242 data = INST_DATA(cl, obj);
244 data->dri = dri;
245 data->frame = frame;
246 data->table = table;
247 data->flags = flags;
248 data->active = NULL;
249 data->move = FALSE;
250 data->selected = FALSE;
251 data->firstdraw = TRUE;
253 return (IPTR)obj;
256 STATIC IPTR pt_set(Class *cl, Object *obj, struct opSet *msg)
258 struct PTableData *data = INST_DATA(cl, obj);
259 IPTR retval = 0UL;
260 struct TagItem *tag;
261 struct TagItem *taglist;
262 struct RastPort *rport;
264 D(bug("[HDToolBox] pt_set()\n"));
266 if (msg->MethodID != OM_NEW)
267 retval = DoSuperMethodA(cl, obj, (Msg)msg);
269 taglist = (struct TagItem *)msg->ops_AttrList;
270 while ((tag = NextTagItem(&taglist)))
272 switch (tag->ti_Tag)
274 case GA_Disabled:
275 retval = TRUE;
276 break;
277 case GA_DrawInfo:
278 if (msg->MethodID == OM_NEW)
279 data->dri = (struct DrawInfo *)tag->ti_Data;
280 break;
281 case PTCT_PartitionTable:
282 data->table = (struct HDTBPartition *)tag->ti_Data;
283 retval = TRUE;
284 break;
285 case PTCT_ActivePartition:
286 data->active = (struct HDTBPartition *)tag->ti_Data;
287 retval = TRUE;
288 break;
292 /* redraw if one attribute has changed something */
293 if ((retval) && (OCLASS(obj) == cl))
295 rport = ObtainGIRPort(msg->ops_GInfo);
296 if (rport)
298 DoMethod(obj, GM_RENDER, (IPTR) msg->ops_GInfo, (IPTR) rport, GREDRAW_UPDATE);
299 ReleaseGIRPort(rport);
300 retval = FALSE;
303 return retval;
306 STATIC IPTR pt_get(Class *cl, Object *obj, struct opGet *msg)
308 struct PTableData *data = INST_DATA(cl, obj);
309 IPTR retval = 0;
311 D(bug("[HDToolBox] pt_get()\n"));
313 switch (msg->opg_AttrID)
315 case PTCT_PartitionTable:
316 *msg->opg_Storage = (IPTR)data->table;
317 retval = 1;
318 break;
319 case PTCT_ActivePartition:
320 *msg->opg_Storage = (IPTR)data->active;
321 retval = 1;
322 break;
323 case PTCT_ActiveType:
324 if ((struct DosEnvec *)data->active == &data->gap)
325 *msg->opg_Storage = (IPTR)PTS_EMPTY_AREA;
326 else if (data->active == NULL)
327 *msg->opg_Storage = (IPTR)PTS_NOTHING;
328 else
329 *msg->opg_Storage = (IPTR)PTS_PARTITION;
330 retval = 1;
331 break;
333 case PTCT_Flags:
334 break;
336 default:
337 retval = DoSuperMethodA(cl, obj, (Msg)msg);
339 return retval;
342 struct DosEnvec *findSpace(struct HDTBPartition *table, struct DosEnvec *de, ULONG block)
344 struct HDTBPartition *pn;
345 ULONG spc;
346 ULONG first = 0;
347 ULONG last = 0xFFFFFFFF;
349 D(bug("[HDToolBox] findSpace()\n"));
351 /* inherit */
352 CopyMem(&table->de, de, sizeof(struct DosEnvec));
353 de->de_SizeBlock = table->dg.dg_SectorSize>>2;
354 de->de_Surfaces = table->dg.dg_Heads;
355 de->de_BlocksPerTrack = table->dg.dg_TrackSectors;
356 de->de_BufMemType = table->dg.dg_BufMemType;
358 pn = (struct HDTBPartition *)table->listnode.list.lh_Head;
359 while (pn->listnode.ln.ln_Succ != NULL)
361 ULONG start;
362 ULONG end;
364 if (pn->listnode.ln.ln_Type != LNT_Parent)
366 spc = pn->de.de_Surfaces*pn->de.de_BlocksPerTrack;
367 start = pn->de.de_LowCyl*spc;
368 end = ((pn->de.de_HighCyl+1)*spc)-1;
369 if (block<start)
371 if (start<last)
372 last=start-1;
374 else if (block>end)
376 if (end>first)
377 first = end+1;
380 pn = (struct HDTBPartition *)pn->listnode.ln.ln_Succ;
383 spc = table->dg.dg_Heads*table->dg.dg_TrackSectors;
384 if (first == 0)
385 first = table->table->reserved;
386 if (first != 0)
387 first = (first - 1) / spc + 1;
389 last = ((last+1)/spc)-1;
390 if (last>=table->dg.dg_Cylinders)
391 last=table->dg.dg_Cylinders-1;
393 de->de_LowCyl = first;
394 de->de_HighCyl = last;
396 return de;
400 * Find the partition containing the currently selected block, or the DE
401 * describing the empty space.
403 struct HDTBPartition *getActive(struct PTableData *data)
405 struct HDTBPartition *pn;
407 D(bug("[HDToolBox] getActive()\n"));
409 pn = (struct HDTBPartition *)data->table->listnode.list.lh_Head;
410 while (pn->listnode.ln.ln_Succ != NULL)
412 ULONG start;
413 ULONG end;
415 if (pn->listnode.ln.ln_Type != LNT_Parent)
417 start = pn->de.de_LowCyl*pn->de.de_Surfaces*pn->de.de_BlocksPerTrack;
418 end = (pn->de.de_HighCyl+1)*pn->de.de_Surfaces*pn->de.de_BlocksPerTrack;
419 if ((data->block>=start) && (data->block<end))
420 return pn;
422 pn = (struct HDTBPartition *)pn->listnode.ln.ln_Succ;
424 return (struct HDTBPartition *)findSpace(data->table,&data->gap,data->block);
427 void DrawBox(struct RastPort *rport, struct DrawInfo *dri,
428 UWORD sx, UWORD sy, UWORD ex, UWORD ey, BOOL recessed)
430 D(bug("[HDToolBox] DrawBox(rport @ %p, dri @ %p, %d,%dx%d,%d)\n", rport, dri, sx, sy, ex, ey));
432 SetAPen(rport, dri->dri_Pens[recessed ? SHINEPEN : SHADOWPEN]);
433 Move(rport, ex, sy);
434 Draw(rport, ex, ey);
435 Draw(rport, sx, ey);
436 SetAPen(rport, dri->dri_Pens[recessed ? SHADOWPEN : SHINEPEN]);
437 Draw(rport, sx, sy);
438 Draw(rport, ex, sy);
441 void DrawFilledBox(struct RastPort *rport, struct DrawInfo *dri,
442 UWORD sx, UWORD sy, UWORD ex, UWORD ey)
444 D(bug("[HDToolBox] DrawFilledBox()\n"));
446 RectFill(rport, sx+1, sy+1, ex-1, ey-1);
447 DrawBox(rport, dri, sx, sy, ex, ey, FALSE);
450 void DrawPartition(struct RastPort *rport, struct PTableData *data,
451 struct Gadget *gadget, struct HDTBPartition *table, struct DosEnvec *pn, WORD drawtype)
453 ULONG start;
454 ULONG end;
455 ULONG blocks;
456 ULONG spc;
457 ULONG cyls;
458 ULONG skipcyl;
460 D(bug("[HDToolBox] DrawPartition()\n"));
462 if (!rport) return;
464 #if 0
465 blocks =
466 (table->table->de_HighCyl+1)*
467 table->table->de_Surfaces*
468 table->table->de_BlocksPerTrack;
469 #else
470 blocks = table->dg.dg_Heads*table->dg.dg_TrackSectors;
471 skipcyl = table->table->reserved/blocks;
472 cyls = (table->dg.dg_Cylinders-1)-skipcyl;
474 #endif
475 spc = pn->de_Surfaces*pn->de_BlocksPerTrack;
476 #if 0
477 start = pn->de_LowCyl*spc*gadget->Width/blocks;
478 end = (((pn->de_HighCyl+1)*spc)-1)*gadget->Width/blocks;
479 #else
480 start = pn->de_LowCyl;
481 end = pn->de_HighCyl;
482 if (
483 (pn->de_Surfaces!=table->dg.dg_Heads) ||
484 (pn->de_BlocksPerTrack!=table->dg.dg_TrackSectors)
487 start = start*spc/blocks;
488 end = end*spc/blocks;
490 if (start!=0)
491 start -= skipcyl;
492 if (end !=0)
493 end -= skipcyl;
494 start = (start*(gadget->Width - PARTITIONBLOCK_FRAMEWIDTH)/cyls)+1;
495 #if END_FIX
496 end = ((end + 1) *(gadget->Width - PARTITIONBLOCK_FRAMEWIDTH)/cyls) + 1 - 1;
497 #else
498 end = (end*(gadget->Width - PARTITIONBLOCK_FRAMEWIDTH)/cyls);
499 #endif
500 start += gadget->LeftEdge;
501 end += gadget->LeftEdge;
502 #endif
504 PrepareRP(rport, data, drawtype);
506 if (drawtype == DPTYPE_EMPTY)
508 RectFill(rport, start, gadget->TopEdge+1+(gadget->Height/2),
509 end, gadget->TopEdge+(gadget->Height)-2);
511 else
513 DrawFilledBox
515 rport,
516 data->dri,
517 start, gadget->TopEdge+1+(gadget->Height/2),
518 end, gadget->TopEdge+(gadget->Height)-2
522 SetPattern(rport, NULL, 0);
525 ULONG getBlock(UWORD mousex, UWORD width, struct HDTBPartition *table)
527 ULONG block;
529 if ((WORD)mousex < 0) mousex = 0;
531 block = mousex*(table->dg.dg_Cylinders-1)/width;
532 block *= table->dg.dg_Heads*table->dg.dg_TrackSectors;
533 block += table->table->reserved;
534 return block;
537 STATIC VOID notify_all(Class *cl, Object *obj, struct GadgetInfo *gi, BOOL interim, BOOL userinput)
539 struct PTableData *data = INST_DATA(cl, obj);
540 struct opUpdate opu;
542 struct TagItem tags[] =
544 {GA_ID, G(obj)->GadgetID },
545 #ifndef __AMIGAOS__
546 {GA_UserInput, userinput },
547 #endif
548 {PTCT_ActivePartition,(IPTR)data->active },
549 {PTCT_PartitionTable, (IPTR)data->table },
550 {PTCT_PartitionMove, (IPTR)data->move },
551 {PTCT_Selected, (IPTR)data->selected },
552 {TAG_DONE }
555 D(bug("[HDToolBox] notify_all()\n"));
557 opu.MethodID = OM_NOTIFY;
558 opu.opu_AttrList = tags;
559 opu.opu_GInfo = gi;
560 opu.opu_Flags = interim ? OPUF_INTERIM : 0;
561 DoMethodA(obj, (Msg)&opu);
564 STATIC IPTR pt_goactive(Class *cl, Object *obj, struct gpInput *msg)
566 struct PTableData *data = INST_DATA(cl, obj);
567 IPTR retval = GMR_MEACTIVE;
568 struct DosEnvec *de;
569 struct RastPort *rport;
570 WORD drawtype;
572 D(bug("[HDToolBox] pt_goactive()\n"));
574 data->block = getBlock(msg->gpi_Mouse.X, G(obj)->Width - PARTITIONBLOCK_FRAMEWIDTH,data->table);
575 rport = ObtainGIRPort(msg->gpi_GInfo);
576 if (data->active != NULL)
578 /* draw previous active as unselected */
579 if ((struct DosEnvec *)data->active == &data->gap)
581 drawtype = DPTYPE_EMPTY;
582 de = &data->gap;
584 else
586 drawtype = DPTYPE_USED;
587 de = &data->active->de;
589 DrawPartition(rport, data, (struct Gadget *)obj, data->table, de, drawtype);
591 data->active = getActive(data);
593 if ((struct DosEnvec *)data->active == &data->gap)
595 drawtype = DPTYPE_EMPTY_SELECTED;
596 de = &data->gap;
598 else
600 drawtype = DPTYPE_USED_SELECTED;
601 de = &data->active->de;
602 if (data->flags & PTCTF_EmptySelectOnly)
603 data->active = NULL;
605 data->selected = TRUE;
606 notify_all(cl, obj, msg->gpi_GInfo, TRUE, TRUE);
607 data->selected = FALSE;
608 if (data->active && rport)
610 DrawPartition(rport, data, (struct Gadget *)obj, data->table, de, drawtype);
613 if (rport) ReleaseGIRPort(rport);
615 return retval;
618 STATIC IPTR pt_goinactive(Class *cl, Object *obj, struct gpInput *msg)
620 struct PTableData *data = INST_DATA(cl, obj);
621 IPTR retval = TRUE;
622 struct DosEnvec *de;
623 struct RastPort *rport;
624 WORD drawtype;
626 D(bug("[HDToolBox] pt_goinactive()\n"));
628 if (data->active)
630 // data->block = getBlock(msg->gpi_Mouse.X, G(obj)->Width - PARTITIONBLOCK_FRAMEWIDTH, data->table);
631 if (getActive(data) == data->active)
633 if ((rport = ObtainGIRPort(msg->gpi_GInfo)))
635 if ((struct DosEnvec *)data->active == &data->gap)
637 drawtype = DPTYPE_EMPTY_SELECTED;
638 de = &data->gap;
640 else
642 drawtype = DPTYPE_USED_SELECTED;
643 de = &data->active->de;
645 DrawPartition(rport, data, (struct Gadget *)obj, data->table, de, drawtype);
647 ReleaseGIRPort(rport);
651 return retval;
654 ULONG overflow_add(ULONG a, LONG b)
656 ULONG result;
658 result = a + b;
660 if (a > result)
661 result = (ULONG)-1;
663 return result;
666 ULONG underflow_add(ULONG a, LONG b)
668 ULONG result;
670 if (a<-b)
671 result = 0;
672 else
673 result = a+b;
675 return result;
678 BOOL overlap(ULONG a, ULONG b, ULONG c, ULONG d)
680 if (a>b)
682 ULONG e;
683 e = b;
684 b = a;
685 a = e;
687 return
689 (((a >= c) && (a < d)) || ((b >= c) && (b < d))) ||
690 (((c >= a) && (c < b)) || ((d >= a) && (d < b)))
694 LONG getBetterDiff(struct HDTBPartition *table, struct HDTBPartition *current, LONG diff)
696 struct HDTBPartition *pn;
697 ULONG spc;
698 ULONG oldblock;
699 ULONG block;
700 ULONG other;
701 ULONG start;
702 ULONG end;
703 ULONG size;
705 spc = current->de.de_Surfaces*current->de.de_BlocksPerTrack;
706 start = current->de.de_LowCyl*spc;
707 end = ((current->de.de_HighCyl+1)*spc)-1;
708 size = end-start;
709 if (diff > 0)
711 oldblock = end;
712 block = overflow_add(end, diff);
713 other = block-size;
715 else
717 oldblock = start;
718 block = underflow_add(start, diff);
719 other = block+size; /* use correct partition size */
721 if (block < table->table->reserved)
723 diff = table->table->reserved-oldblock;
724 if (diff == 0)
725 return 0;
726 return getBetterDiff(table, current, diff);
728 spc = table->dg.dg_Heads*table->dg.dg_TrackSectors;
729 if (block >= ((table->dg.dg_Cylinders)*spc))
731 diff = (((table->dg.dg_Cylinders)*spc)-1)-oldblock;
732 if (diff == 0)
733 return 0;
734 return getBetterDiff(table, current, diff);
737 for (pn = (struct HDTBPartition *)table->listnode.list.lh_Head;
738 pn->listnode.ln.ln_Succ;
739 pn = (struct HDTBPartition *)pn->listnode.ln.ln_Succ)
741 /* do NOT include anything that is NOT a partition */
742 if (pn->listnode.ln.ln_Type != LNT_Partition)
743 continue;
744 /* don't check currently processed partition */
745 if (current != pn)
747 spc = pn->de.de_Surfaces*pn->de.de_BlocksPerTrack;
748 if (
749 overlap
751 block, other,
752 pn->de.de_LowCyl*spc, ((pn->de.de_HighCyl+1)*spc)-1
756 if (diff>0)
757 diff = ((pn->de.de_LowCyl*spc)-1)-oldblock;
758 else
759 diff = ((pn->de.de_HighCyl+1)*spc)-oldblock;
760 return getBetterDiff(table, current, diff);
764 return diff;
767 STATIC IPTR pt_handleinput(Class *cl, Object *obj, struct gpInput *msg)
769 struct PTableData *data = INST_DATA(cl, obj);
770 IPTR retval = GMR_MEACTIVE;
771 struct InputEvent *ie;
772 struct RastPort *rport;
775 ie = msg->gpi_IEvent;
776 if (ie->ie_Class == IECLASS_RAWMOUSE)
778 D(bug("[HDToolBox] pt_handleinput(): %x / %x / %x\n", IECODE_NOBUTTON, IECODE_LBUTTON | IECODE_UP_PREFIX, ie->ie_Code));
779 switch (ie->ie_Code)
781 case IECODE_NOBUTTON:
782 if (
783 ((struct DosEnvec *)data->active != &data->gap) &&
784 (!(data->flags & PTCTF_NoPartitionMove))
787 ULONG block;
788 LONG diff;
789 ULONG start;
790 ULONG end;
791 ULONG spc;
792 ULONG tocheck;
794 D(bug("[HDToolBox] - attempting to obtain block\n", diff));
795 block = getBlock(msg->gpi_Mouse.X, G(obj)->Width - PARTITIONBLOCK_FRAMEWIDTH, data->table);
796 D(bug("[HDToolBox] - block location: %ld\n", diff));
797 diff = block-data->block;
798 if (diff)
800 D(bug("[HDToolBox] - odiff: %ld\n", diff));
801 diff = getBetterDiff(data->table, data->active, diff);
802 D(bug("[HDToolBox] - diff : %ld\n", diff));
803 if (diff)
805 spc=data->active->de.de_Surfaces*data->active->de.de_BlocksPerTrack;
806 D(bug("[HDToolBox] - spc : %ld\n", spc));
807 start = data->active->de.de_LowCyl*spc;
808 D(bug("[HDToolBox] - start: %ld\n", start));
809 start += diff;
810 end = ((data->active->de.de_HighCyl+1)*spc)-1;
811 D(bug("[HDToolBox] - end : %ld\n", end));
812 end += diff;
813 tocheck = (diff>0) ? end : start;
814 if (validValue(data->table, data->active, tocheck))
816 start = start/spc;
817 end = ((end+1)/spc)-1;
819 rport = ObtainGIRPort(msg->gpi_GInfo);
821 DrawPartition
823 rport,
824 data,
825 (struct Gadget *)obj,
826 data->table,
827 &data->active->de,
828 DPTYPE_EMPTY
830 data->active->de.de_LowCyl=start;
831 data->active->de.de_HighCyl=end;
832 DrawPartition
834 rport,
835 data,
836 (struct Gadget *)obj,
837 data->table,
838 &data->active->de,
839 DPTYPE_USED_SELECTED
841 if (rport) ReleaseGIRPort(rport);
843 data->block = block;
844 data->move = TRUE;
845 notify_all(cl, obj, msg->gpi_GInfo, TRUE, TRUE);
847 else
849 D(bug("[HDToolBox] pt_handleinput: !!!!!!!!!!!!!!!!!!!not valid\n"));
854 break;
855 case (IECODE_LBUTTON | IECODE_UP_PREFIX):
856 data->move = FALSE;
857 notify_all(cl, obj, msg->gpi_GInfo, FALSE, TRUE);
858 data->selected = FALSE;
859 retval = GMR_NOREUSE|GMR_VERIFY;
860 break;
863 else
865 D(bug("[HDToolBox] pt_handleinput(): Other class: %x\n", ie->ie_Class));
867 D(bug("[HDToolBox] pt_handleinput(): successful\n", ie->ie_Class));
868 return retval;
871 void DrawLegend(struct RastPort *rport, struct DrawInfo *dri, LONG sx, LONG sy, LONG ex, LONG ey, char *text)
873 D(bug("[HDToolBox] DrawLegend()\n"));
875 RectFill(rport, sx+1, sy+1, ex-1, ey-1);
876 DrawBox(rport, dri, sx, sy, ex, ey, FALSE);
878 SetAPen(rport, 1);
879 SetDrMd(rport, JAM1);
881 Move(rport, sx, ey+rport->TxHeight+1);
882 Text(rport, text, strlen(text));
885 STATIC IPTR pt_render(Class *cl, Object *obj, struct gpRender *msg)
887 struct PTableData *data = INST_DATA(cl, obj);
888 struct HDTBPartition *pn;
889 IPTR retval = 0;
891 D(bug("[HDToolBox] pt_render()\n"));
893 retval = DoSuperMethodA(cl, obj, (Msg)msg);
895 if (data->firstdraw)
897 struct TagItem obp_tags[] =
899 {OBP_Precision, PRECISION_EXACT },
900 {OBP_FailIfBad, TRUE },
901 {TAG_DONE }
904 WORD i;
906 data->firstdraw = FALSE;
908 data->cm = msg->gpr_GInfo->gi_Screen->ViewPort.ColorMap;
910 for(i = 0; i < NUM_PENS; i++)
912 data->pens[i] = ObtainBestPenA(data->cm,
913 rgbtable[i * 3],
914 rgbtable[i * 3 + 1],
915 rgbtable[i * 3 + 2],
916 obp_tags);
918 if (data->pens[i] == -1)
920 while(--i >= 0)
922 ReleasePen(data->cm, data->pens[i]);
924 break;
928 if (i == NUM_PENS)
930 data->multicolor = TRUE;
931 data->pensallocated = TRUE;
935 EraseRect
937 msg->gpr_RPort,
938 G(obj)->LeftEdge,
939 G(obj)->TopEdge,
940 G(obj)->LeftEdge+G(obj)->Width - 1,
941 G(obj)->TopEdge+(G(obj)->Height - 1)
944 PrepareRP(msg->gpr_RPort, data, DPTYPE_EMPTY);
945 DrawLegend
947 msg->gpr_RPort,
948 data->dri,
949 G(obj)->LeftEdge,
950 G(obj)->TopEdge,
951 G(obj)->LeftEdge+(G(obj)->Width/5),
952 G(obj)->TopEdge+(G(obj)->Height/2)-(G(obj)->Height/4),
953 "Unselected Empty"
956 PrepareRP(msg->gpr_RPort, data, DPTYPE_EMPTY_SELECTED);
957 DrawLegend
959 msg->gpr_RPort,
960 data->dri,
961 G(obj)->LeftEdge+(G(obj)->Width/5)+(G(obj)->Width/15),
962 G(obj)->TopEdge,
963 G(obj)->LeftEdge+(G(obj)->Width/5*2)+(G(obj)->Width/15),
964 G(obj)->TopEdge+(G(obj)->Height/2)-(G(obj)->Height/4),
965 "Selected Empty"
968 PrepareRP(msg->gpr_RPort, data, DPTYPE_USED);
969 DrawLegend
971 msg->gpr_RPort,
972 data->dri,
973 G(obj)->LeftEdge+(G(obj)->Width/5*2)+(G(obj)->Width/15*2),
974 G(obj)->TopEdge,
975 G(obj)->LeftEdge+(G(obj)->Width/5*3)+(G(obj)->Width/15*2),
976 G(obj)->TopEdge+(G(obj)->Height/2)-(G(obj)->Height/4),
977 "Unselected Used"
980 PrepareRP(msg->gpr_RPort, data, DPTYPE_USED_SELECTED);
981 DrawLegend
983 msg->gpr_RPort,
984 data->dri,
985 G(obj)->LeftEdge+(G(obj)->Width/5*3)+(G(obj)->Width/15*3),
986 G(obj)->TopEdge,
987 G(obj)->LeftEdge+(G(obj)->Width/5*4)+(G(obj)->Width/15*3),
988 G(obj)->TopEdge+(G(obj)->Height/2)-(G(obj)->Height/4),
989 "Selected Used"
992 PrepareRP(msg->gpr_RPort, data, DPTYPE_EMPTY);
994 RectFill
996 msg->gpr_RPort,
997 G(obj)->LeftEdge,
998 G(obj)->TopEdge+(G(obj)->Height/2),
999 G(obj)->LeftEdge+G(obj)->Width - 1,
1000 G(obj)->TopEdge+(G(obj)->Height - 1)
1002 SetPattern(msg->gpr_RPort, NULL, 0);
1004 DrawBox
1006 msg->gpr_RPort,
1007 data->dri,
1008 G(obj)->LeftEdge,
1009 G(obj)->TopEdge+(G(obj)->Height/2),
1010 G(obj)->LeftEdge+G(obj)->Width - 1,
1011 G(obj)->TopEdge+(G(obj)->Height - 1),
1012 TRUE
1015 if (data->table)
1017 SetPattern(msg->gpr_RPort, &pattern, 2);
1018 pn = (struct HDTBPartition *)data->table->listnode.list.lh_Head;
1019 while (pn->listnode.ln.ln_Succ)
1021 if (pn->listnode.ln.ln_Type == LNT_Partition)
1023 DrawPartition
1025 msg->gpr_RPort,
1026 data,
1027 (struct Gadget *)obj,
1028 data->table,
1029 &pn->de,
1030 (data->active == pn) ? DPTYPE_USED_SELECTED : DPTYPE_USED
1033 pn = (struct HDTBPartition *)pn->listnode.ln.ln_Succ;
1035 if ((struct DosEnvec *)data->active == &data->gap)
1037 DrawPartition
1039 msg->gpr_RPort,
1040 data,
1041 (struct Gadget *)obj,
1042 data->table,
1043 &data->gap,
1044 DPTYPE_EMPTY_SELECTED
1047 SetPattern(msg->gpr_RPort, 0, 0);
1049 return retval;
1052 STATIC IPTR pt_dispose(Class *cl, Object *obj, Msg msg)
1054 struct PTableData *data = INST_DATA(cl, obj);
1056 D(bug("[HDToolBox] pt_dispose()\n"));
1058 if (data->pensallocated)
1060 WORD i = 0;
1062 for(i = 0; i < NUM_PENS; i++)
1064 ReleasePen(data->cm, data->pens[i]);
1068 return DoSuperMethodA(cl, obj, msg);
1071 STATIC IPTR pt_hittest(Class *cl, Object *obj, struct gpHitTest *msg)
1073 D(bug("[HDToolBox] pt_hittest()\n"));
1075 return GMR_GADGETHIT;
1078 AROS_UFH3S(IPTR, dispatch_ptclass,
1079 AROS_UFHA(Class *, cl, A0),
1080 AROS_UFHA(Object *, obj, A2),
1081 AROS_UFHA(Msg, msg, A1))
1083 AROS_USERFUNC_INIT
1085 IPTR retval;
1087 D(bug("[HDToolBox] dispatch_ptclass()\n"));
1089 switch (msg->MethodID)
1091 case OM_NEW:
1092 retval = pt_new(cl, obj, (struct opSet *)msg);
1093 break;
1094 case OM_DISPOSE:
1095 retval = pt_dispose(cl, obj, msg);
1096 break;
1097 case OM_SET:
1098 case OM_UPDATE:
1099 retval = pt_set(cl, obj, (struct opSet *)msg);
1100 break;
1101 case OM_GET:
1102 retval = pt_get(cl, obj, (struct opGet *)msg);
1103 break;
1104 case GM_HITTEST:
1105 retval = pt_hittest(cl, obj, (struct gpHitTest *)msg);
1106 break;
1107 case GM_RENDER:
1108 retval = pt_render(cl, obj, (struct gpRender *)msg);
1109 break;
1110 case GM_GOACTIVE:
1111 retval = pt_goactive(cl, obj, (struct gpInput *)msg);
1112 break;
1113 case GM_GOINACTIVE:
1114 retval = pt_goinactive(cl, obj, (struct gpInput *)msg);
1115 break;
1116 case GM_HANDLEINPUT:
1117 retval = pt_handleinput(cl, obj, (struct gpInput *)msg);
1118 break;
1119 default:
1120 D(bug("[HDToolBox] dispatch_ptclass:default %ld\n", msg->MethodID));
1121 retval = DoSuperMethodA(cl, obj, msg);
1122 break;
1124 return retval;
1126 AROS_USERFUNC_EXIT
1129 Class *makePTClass(void)
1131 D(bug("[HDToolBox] makePTClass()\n"));
1133 if (!ptcl)
1135 ptcl = MakeClass(NULL, GADGETCLASS, NULL, sizeof(struct PTableData), 0);
1136 if (ptcl)
1138 ptcl->cl_Dispatcher.h_Entry = AROS_ASMSYMNAME(dispatch_ptclass);
1139 ptcl->cl_Dispatcher.h_SubEntry = NULL;
1140 ptcl->cl_UserData = (IPTR)NULL;
1143 return ptcl;