2 Copyright © 2002-2011, The AROS Development Team.
12 #include <exec/devices.h>
13 #include <exec/memory.h>
14 #include <workbench/icon.h>
16 #include <clib/alib_protos.h>
18 #include <cybergraphx/cybergraphics.h>
19 #include <proto/cybergraphics.h>
20 #include <proto/graphics.h>
21 #include <proto/exec.h>
22 #include <proto/intuition.h>
23 #include <proto/icon.h>
25 #include <proto/timer.h>
26 #include <proto/utility.h>
28 #include "dragndrop.h"
29 #include "muimaster_intern.h"
32 /* #define MYDEBUG 1 */
35 extern struct Library
*MUIMasterBase
;
39 ULONG
IconControl(struct DiskObject
*icon
, ...)
41 return IconControlA(icon
, (struct TagItem
*)((((ULONG
*) & icon
) + 1)));
44 struct DiskObject
*GetIconTags(CONST_STRPTR name
, ...)
46 return GetIconTagList(name
, (struct TagItem
*)(((ULONG
*) & name
) + 1));
62 //-------------------------------------
64 //-------------------------------------
65 static struct MinNode
*Node_Prev(APTR node
)
69 if (((struct MinNode
*)node
)->mln_Pred
== NULL
)
71 if (((struct MinNode
*)node
)->mln_Pred
->mln_Pred
== NULL
)
73 return ((struct MinNode
*)node
)->mln_Pred
;
75 //-------------------------------------
77 //-------------------------------------
78 static struct MinNode
*List_Last(APTR list
)
80 if (!((struct MinList
*)list
)->mlh_TailPred
)
83 if (((struct MinList
*)list
)->mlh_TailPred
->mln_Pred
== NULL
)
85 return ((struct MinList
*)list
)->mlh_TailPred
;
87 //-------------------------------------
89 static ULONG
List_Length(APTR list
)
91 struct MinNode
*node
= List_First(list
);
96 node
= Node_Next(node
);
100 //-------------------------------------
101 static struct MinNode
*List_Find(APTR list
, ULONG num
)
103 struct MinNode
*node
= List_First(list
);
106 if (!(node
= Node_Next(node
)))
112 //-------------------------------------
116 struct MinList dnd_List
;
117 struct Screen
*dnd_Screen
;
118 struct BitMap
*dnd_TempBitMap
;
121 struct RastPort dnd_RastPort;
122 struct Layer_Info *dnd_LayerInfo;
123 struct Layer *dnd_Layer;
129 struct MinNode bmn_Node
;
130 struct BitMap
*bmn_BitMap
; /* This bitmap is external and not to be modified */
145 struct BitMap
*bmn_SaveBitMap
;
147 struct DragNDrop
*bmn_DnD
;
149 /* Basic alpha-blitting implementation */
150 APTR bmn_BitMapBuffer
; /* Same data as bmn_BitMap but 32-bit ARGB */
153 #define bmn_Succ bmn_Node.mln_Succ
154 #define bmn_Pred bmn_Node.mln_Pred
156 //-------------------------------------
157 STATIC VOID
List_Sort_Mode_1(struct MinList
*list
)
159 BOOL notfinished
= TRUE
;
161 /* Sort list (quick & dirty bubble sort) */
164 struct BitMapNode
*first
;
166 /* Reset not finished flag */
170 if ((first
= List_First(list
)))
172 struct BitMapNode
*second
;
174 /* One bubble sort round */
175 while ((second
= Node_Next(first
)))
178 if (first
->bmn_Top
> second
->bmn_Top
)
180 else if (first
->bmn_Top
== second
->bmn_Top
181 && first
->bmn_Left
> second
->bmn_Left
)
188 Remove((struct Node
*)first
);
189 Insert((struct List
*)list
, (struct Node
*)first
,
190 (struct Node
*)second
);
199 //-------------------------------------
201 STATIC VOID
List_Sort_Mode_2(struct MinList
*list
)
203 BOOL notfinished
= TRUE
;
205 /* Sort list (quick & dirty bubble sort) */
208 struct BitMapNode
*first
;
210 /* Reset not finished flag */
214 if ((first
= List_First(list
)))
216 struct BitMapNode
*second
;
218 /* One bubble sort round */
219 while ((second
= Node_Next(first
)))
222 if (first
->bmn_Top
> second
->bmn_Top
)
224 else if (first
->bmn_Top
== second
->bmn_Top
225 && first
->bmn_Left
< second
->bmn_Left
)
232 Remove((struct Node
*)first
);
233 Insert((struct List
*)list
, (struct Node
*)first
,
234 (struct Node
*)second
);
244 //-------------------------------------
245 STATIC VOID
List_Sort_Mode_3(struct MinList
*list
)
247 BOOL notfinished
= TRUE
;
249 /* Sort list (quick & dirty bubble sort) */
252 struct BitMapNode
*first
;
254 /* Reset not finished flag */
258 if ((first
= List_First(list
)))
260 struct BitMapNode
*second
;
262 /* One bubble sort round */
263 while ((second
= Node_Next(first
)))
266 if (first
->bmn_Left
> second
->bmn_Left
)
268 else if (first
->bmn_Left
== second
->bmn_Left
269 && first
->bmn_Top
> second
->bmn_Top
)
276 Remove((struct Node
*)first
);
277 Insert((struct List
*)list
, (struct Node
*)first
,
278 (struct Node
*)second
);
287 //-------------------------------------
288 STATIC BOOL
AndRectangle(struct Rectangle
*a
, struct Rectangle
*b
,
291 c
->MinX
= MAX(a
->MinX
, b
->MinX
);
292 c
->MinY
= MAX(a
->MinY
, b
->MinY
);
293 c
->MaxX
= MIN(a
->MaxX
, b
->MaxX
);
294 c
->MaxY
= MIN(a
->MaxY
, b
->MaxY
);
296 if ((c
->MinX
> c
->MaxX
) || (c
->MinY
> c
->MaxY
))
301 //-------------------------------------
303 //-------------------------------------
304 STATIC VOID
SafeBltBitMapRastPort(struct BitMap
*srcBitMap
, long xSrc
,
305 long ySrc
, struct RastPort
*destRP
, long xDest
, long yDest
, long xSize
,
306 long ySize
, unsigned long minterm
)
308 struct BitMap
*destBitMap
= destRP
->BitMap
;
309 LONG srcMaxWidth
, srcMaxHeight
;
310 LONG destMaxWidth
, destMaxHeight
;
312 srcMaxWidth
= GetBitMapAttr(srcBitMap
, BMA_WIDTH
);
313 srcMaxHeight
= GetBitMapAttr(srcBitMap
, BMA_HEIGHT
);
314 destMaxWidth
= GetBitMapAttr(destBitMap
, BMA_WIDTH
);
315 destMaxHeight
= GetBitMapAttr(destBitMap
, BMA_HEIGHT
);
345 if (xSize
+ xSrc
> srcMaxWidth
)
346 xSize
= srcMaxWidth
- xSrc
;
347 if (ySize
+ ySrc
> srcMaxHeight
)
348 ySize
= srcMaxHeight
- ySrc
;
349 if (xSize
+ xDest
> destMaxWidth
)
350 xSize
= destMaxWidth
- xDest
;
351 if (ySize
+ yDest
> destMaxHeight
)
352 ySize
= destMaxHeight
- yDest
;
354 if (xSize
> 0 && ySize
> 0)
356 BltBitMapRastPort(srcBitMap
, xSrc
, ySrc
, destRP
, xDest
, yDest
,
357 xSize
, ySize
, minterm
);
360 //-------------------------------------
361 STATIC LONG
SafeBltBitMap(struct BitMap
*srcBitMap
, long xSrc
, long ySrc
,
362 struct BitMap
*destBitMap
, long xDest
, long yDest
, long xSize
,
363 long ySize
, unsigned long minterm
, unsigned long mask
, PLANEPTR tempA
)
365 LONG srcMaxWidth
, srcMaxHeight
;
366 LONG destMaxWidth
, destMaxHeight
;
368 srcMaxWidth
= GetBitMapAttr(srcBitMap
, BMA_WIDTH
);
369 srcMaxHeight
= GetBitMapAttr(srcBitMap
, BMA_HEIGHT
);
370 destMaxWidth
= GetBitMapAttr(destBitMap
, BMA_WIDTH
);
371 destMaxHeight
= GetBitMapAttr(destBitMap
, BMA_HEIGHT
);
401 if (xSize
+ xSrc
> srcMaxWidth
)
402 xSize
= srcMaxWidth
- xSrc
;
403 if (ySize
+ ySrc
> srcMaxHeight
)
404 ySize
= srcMaxHeight
- ySrc
;
405 if (xSize
+ xDest
> destMaxWidth
)
406 xSize
= destMaxWidth
- xDest
;
407 if (ySize
+ yDest
> destMaxHeight
)
408 ySize
= destMaxHeight
- yDest
;
410 if (xSize
> 0 && ySize
> 0)
412 return BltBitMap(srcBitMap
, xSrc
, ySrc
, destBitMap
, xDest
, yDest
,
413 xSize
, ySize
, minterm
, mask
, tempA
);
418 //-------------------------------------
419 STATIC VOID
BltBackgroundBitMap(struct BitMapNode
*dest_bmn
, long xSrc
,
420 long ySrc
, long xSize
, long ySize
, ULONG use_temp
)
422 struct BitMap
*srcBitMap
, *destBitMap
;
423 struct DragNDrop
*dnd
= dest_bmn
->bmn_DnD
;
424 LONG maxWidth
, maxHeight
;
425 LONG xDest
= 0, yDest
= 0;
427 struct Rectangle rect
;
430 rect
.MaxX
= xSrc
+ xSize
- 1;
431 rect
.MaxY
= ySrc
+ ySize
- 1;
433 srcBitMap
= dnd
->dnd_Screen
->RastPort
.BitMap
;
436 destBitMap
= dnd
->dnd_TempBitMap
;
438 destBitMap
= dest_bmn
->bmn_SaveBitMap
;
440 maxWidth
= GetBitMapAttr(srcBitMap
, BMA_WIDTH
);
441 maxHeight
= GetBitMapAttr(srcBitMap
, BMA_HEIGHT
);
457 if (xSize
+ xSrc
> maxWidth
)
458 xSize
= maxWidth
- xSrc
;
459 if (ySize
+ ySrc
> maxHeight
)
460 ySize
= maxHeight
- ySrc
;
462 if (xSize
> 0 && ySize
> 0)
464 struct BitMapNode
*bmn
= List_First(&dnd
->dnd_List
);
466 SafeBltBitMap(srcBitMap
, xSrc
, ySrc
, destBitMap
, xDest
, yDest
,
467 xSize
, ySize
, 0xc0, -1, NULL
);
470 // BltBitMapRastPort(destBitMap,0,0,
471 // &dnd->dnd_Screen->RastPort, 2*dest_bmn->bmn_Left+150, dest_bmn->bmn_Top+200, xSize, ySize,0xc0);
477 struct Rectangle bmn_rect
, result_rect
;
478 bmn_rect
.MinX
= bmn
->bmn_SaveX
;
479 bmn_rect
.MinY
= bmn
->bmn_SaveY
;
480 bmn_rect
.MaxX
= bmn_rect
.MinX
+ bmn
->bmn_SaveWidth
- 1;
481 bmn_rect
.MaxY
= bmn_rect
.MinY
+ bmn
->bmn_SaveHeight
- 1;
483 if (AndRectangle(&rect
, &bmn_rect
, &result_rect
))
485 LONG bmn_x
= result_rect
.MinX
- bmn_rect
.MinX
;
486 LONG bmn_y
= result_rect
.MinY
- bmn_rect
.MinY
;
488 result_rect
.MaxX
- result_rect
.MinX
+ 1;
490 result_rect
.MaxY
- result_rect
.MinY
+ 1;
491 LONG xDest
= result_rect
.MinX
- rect
.MinX
;
492 LONG yDest
= result_rect
.MinY
- rect
.MinY
;
494 SafeBltBitMap(bmn
->bmn_SaveBitMap
, bmn_x
, bmn_y
,
495 destBitMap
, xDest
, yDest
, bmn_width
, bmn_height
,
498 // BltBitMapRastPort(destBitMap,0,0,
499 // &dnd->dnd_Screen->RastPort, 100,300, xSize, ySize,0xc0);
503 bmn
= Node_Next(bmn
);
506 // BltBitMapRastPort(destBitMap,0,0,
507 // &dnd->dnd_Screen->RastPort, 2*dest_bmn->bmn_Left+150, dest_bmn->bmn_Top+200, xSize, ySize,0xc0);
511 //-------------------------------------
512 STATIC VOID
BltBitMapNode(struct BitMapNode
*src_bmn
, LONG offx
, LONG offy
,
513 struct RastPort
*rp
, LONG x
, LONG y
, LONG width
, LONG height
)
515 struct BitMap
*destBitMap
= rp
->BitMap
;
516 LONG destMaxWidth
= GetBitMapAttr(destBitMap
, BMA_WIDTH
);
517 LONG destMaxHeight
= GetBitMapAttr(destBitMap
, BMA_HEIGHT
);
533 if (width
+ x
> destMaxWidth
)
534 width
= destMaxWidth
- x
;
535 if (height
+ y
> destMaxHeight
)
536 height
= destMaxHeight
- y
;
538 if (width
> 0 && height
> 0)
540 if (src_bmn
->bmn_Mask
)
542 BltMaskBitMapRastPort(src_bmn
->bmn_BitMap
, offx
, offy
,
543 rp
, x
, y
, width
, height
, 0xe2,
544 (PLANEPTR
) src_bmn
->bmn_Mask
);
548 IPTR depth
= GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
);
549 if (depth
> 8 && src_bmn
->bmn_BitMapBuffer
)
551 /* This should be done using BltBitMapRastPortAlpha with
552 * direct video card alpha blit, but this function is not
553 * available on AROS yet. Current implementation is that
554 * src_bmn->bmn_BitMapBuffer contains 32bit ARGB buffer
555 * acquired from src_bmn->bmn_BitMap */
556 WritePixelArrayAlpha(src_bmn
->bmn_BitMapBuffer
, offx
, offy
,
557 src_bmn
->bmn_Width
* sizeof(ULONG
), rp
, x
, y
, width
,
562 BltBitMapRastPort(src_bmn
->bmn_BitMap
, offx
, offy
,
563 rp
, x
, y
, width
, height
, 0xc0);
568 //-------------------------------------
569 STATIC VOID
BltNearBitMaps(struct BitMapNode
*src_bmn
, struct RastPort
*rp
,
570 LONG x
, LONG y
, LONG width
, LONG height
)
572 struct DragNDrop
*dnd
= src_bmn
->bmn_DnD
;
573 struct BitMapNode
*bmn
= List_First(&dnd
->dnd_List
);
574 struct Rectangle rect
;
578 rect
.MaxX
= x
+ width
- 1;
579 rect
.MaxY
= y
+ height
- 1;
583 if (bmn
!= src_bmn
&& bmn
->bmn_Drawed
)
585 struct Rectangle bmn_rect
, result_rect
;
586 bmn_rect
.MinX
= bmn
->bmn_SaveX
;
587 bmn_rect
.MinY
= bmn
->bmn_SaveY
;
588 bmn_rect
.MaxX
= bmn_rect
.MinX
+ bmn
->bmn_SaveWidth
- 1;
589 bmn_rect
.MaxY
= bmn_rect
.MinY
+ bmn
->bmn_SaveHeight
- 1;
591 if (AndRectangle(&rect
, &bmn_rect
, &result_rect
))
593 LONG bmn_x
= result_rect
.MinX
- bmn_rect
.MinX
;
594 LONG bmn_y
= result_rect
.MinY
- bmn_rect
.MinY
;
595 LONG bmn_width
= result_rect
.MaxX
- result_rect
.MinX
+ 1;
596 LONG bmn_height
= result_rect
.MaxY
- result_rect
.MinY
+ 1;
597 LONG xDest
= result_rect
.MinX
- rect
.MinX
;
598 LONG yDest
= result_rect
.MinY
- rect
.MinY
;
600 BltBitMapNode(bmn
, bmn_x
, bmn_y
,
601 rp
, xDest
, yDest
, bmn_width
, bmn_height
);
605 bmn
= Node_Next(bmn
);
608 //-------------------------------------
609 STATIC VOID
RestoreBackground(struct BitMapNode
*src_bmn
,
612 LONG save_x
= src_bmn
->bmn_SaveX
;
613 LONG save_y
= src_bmn
->bmn_SaveY
;
614 LONG save_width
= src_bmn
->bmn_SaveWidth
;
615 LONG save_height
= src_bmn
->bmn_SaveHeight
;
617 struct DragNDrop
*dnd
= src_bmn
->bmn_DnD
;
618 struct BitMapNode
*bmn
= List_First(&dnd
->dnd_List
);
619 struct Rectangle last_rect
;
621 last_rect
.MinX
= save_x
;
622 last_rect
.MinY
= save_y
;
623 last_rect
.MaxX
= save_x
+ save_width
- 1;
624 last_rect
.MaxY
= save_y
+ save_height
- 1;
626 SafeBltBitMapRastPort(src_bmn
->bmn_SaveBitMap
, 0, 0,
627 rp
, save_x
, save_y
, save_width
, save_height
, 0xc0);
632 if (bmn
!= src_bmn
&& bmn
->bmn_Drawed
)
634 struct Rectangle bmn_rect
, result_rect
;
635 bmn_rect
.MinX
= bmn
->bmn_SaveX
;
636 bmn_rect
.MinY
= bmn
->bmn_SaveY
;
637 bmn_rect
.MaxX
= bmn_rect
.MinX
+ bmn
->bmn_SaveWidth
- 1;
638 bmn_rect
.MaxY
= bmn_rect
.MinY
+ bmn
->bmn_SaveHeight
- 1;
640 if (AndRectangle(&last_rect
, &bmn_rect
, &result_rect
))
642 LONG bmn_x
= result_rect
.MinX
- bmn_rect
.MinX
;
643 LONG bmn_y
= result_rect
.MinY
- bmn_rect
.MinY
;
644 LONG bmn_width
= result_rect
.MaxX
- result_rect
.MinX
+ 1;
645 LONG bmn_height
= result_rect
.MaxY
- result_rect
.MinY
+ 1;
646 /* LONG xDest = result_rect.MinX - last_rect.MinX; */
647 /* LONG yDest = result_rect.MinY - last_rect.MinY; */
649 BltBitMapNode(bmn
, bmn_x
, bmn_y
,
650 rp
, result_rect
.MinX
, result_rect
.MinY
, bmn_width
,
653 // SafeBltBitMapRastPort(bmn->bmn_SaveBitMap, bmn_x, bmn_y,
654 // rp, xDest, yDest, bmn_width, bmn_height,0xc0);
658 bmn
= Node_Next(bmn
);
661 //-------------------------------------
662 struct BitMapNode
*CreateBitMapNodeA(struct TagItem
*tagList
)
664 struct BitMapNode
*bmn
=
665 (struct BitMapNode
*)AllocMem(sizeof(struct BitMapNode
),
669 BOOL sourcealpha
= FALSE
;
670 struct TagItem
*tl
= tagList
;
673 while ((tag
= NextTagItem(&tl
)))
675 ULONG id
= tag
->ti_Tag
;
676 IPTR data
= tag
->ti_Data
;
681 bmn
->bmn_BitMap
= (struct BitMap
*)data
;
685 bmn
->bmn_Mask
= (APTR
) data
;
689 bmn
->bmn_Left
= data
;
697 bmn
->bmn_Width
= data
;
701 bmn
->bmn_Height
= data
;
704 case GUI_SourceAlpha
:
710 if (!bmn
->bmn_BitMap
)
712 FreeMem(bmn
, sizeof(struct BitMapNode
));
716 if (bmn
&& sourcealpha
)
718 /* See notes in BltBitMapNode */
719 struct RastPort temp_rp
;
720 InitRastPort(&temp_rp
);
721 temp_rp
.BitMap
= bmn
->bmn_BitMap
;
722 bmn
->bmn_BitMapBuffer
=
723 AllocVec(bmn
->bmn_Width
* bmn
->bmn_Height
* sizeof(ULONG
),
725 ReadPixelArray(bmn
->bmn_BitMapBuffer
, 0, 0,
726 bmn
->bmn_Width
* sizeof(ULONG
), &temp_rp
, 0, 0,
727 bmn
->bmn_Width
, bmn
->bmn_Height
, RECTFMT_ARGB
);
728 DeinitRastPort(&temp_rp
);
733 //-------------------------------------
734 VOID
DeleteBitMapNode(struct BitMapNode
*bmn
)
736 if (bmn
->bmn_SaveBitMap
)
737 FreeBitMap(bmn
->bmn_SaveBitMap
);
738 FreeVec(bmn
->bmn_BitMapBuffer
);
739 FreeMem(bmn
, sizeof(struct BitMapNode
));
741 //-------------------------------------
742 struct BitMap
*GetBitMap(struct BitMapNode
*bmn
)
745 return bmn
->bmn_BitMap
;
748 //-------------------------------------
749 VOID
AttachBitMapNode(struct DragNDrop
*dnd
, struct BitMapNode
*bmn
)
751 AddTail((struct List
*)&dnd
->dnd_List
, (struct Node
*)&bmn
->bmn_Node
);
754 //-------------------------------------
755 VOID
DetachBitMapNode(struct BitMapNode
*bmn
)
757 if (bmn
->bmn_Succ
&& bmn
->bmn_Pred
)
759 Remove((struct Node
*)&bmn
->bmn_Node
);
760 bmn
->bmn_Succ
= bmn
->bmn_Pred
= NULL
;
764 //-------------------------------------
765 VOID
DrawBitMapNode(struct BitMapNode
*bmn
, LONG x
, LONG y
)
767 LONG width
= bmn
->bmn_Width
;
768 LONG height
= bmn
->bmn_Height
;
769 LONG save_x
= bmn
->bmn_SaveX
;
770 LONG save_y
= bmn
->bmn_SaveY
;
771 LONG save_width
= bmn
->bmn_SaveWidth
;
772 LONG save_height
= bmn
->bmn_SaveHeight
;
774 struct BitMap
*temp_bmap
;
775 BOOL draw
= TRUE
; //FALSE;
777 if (!bmn
|| !bmn
->bmn_DnD
|| !bmn
->bmn_DnD
->dnd_Screen
)
779 rp
= &bmn
->bmn_DnD
->dnd_Screen
->RastPort
;
780 temp_bmap
= bmn
->bmn_DnD
->dnd_TempBitMap
;
782 if (!bmn
->bmn_SaveBitMap
)
785 /* if( bmn->bmn_SaveWidth > 0 && bmn->bmn_SaveHeight > 0 )
789 RestoreBackground(bmn,rp);
795 maxHeight
/* , offx=0, offy=0, save_offx=0, save_offy=0 */ ;
796 LONG real_width
= width
, real_height
= height
;
797 LONG real_save_width
= save_width
, real_save_height
= save_height
;
799 maxWidth
= GetBitMapAttr(rp
->BitMap
, BMA_WIDTH
);
800 maxHeight
= GetBitMapAttr(rp
->BitMap
, BMA_HEIGHT
);
807 real_save_width
+= save_x
;
809 real_save_height
+= save_y
;
811 if (real_width
+ x
> maxWidth
)
812 real_width
= maxWidth
- x
;
813 if (real_height
+ y
> maxHeight
)
814 real_height
= maxHeight
- y
;
815 if (real_save_width
+ x
> maxWidth
)
816 real_save_width
= maxWidth
- x
;
817 if (real_save_height
+ y
> maxHeight
)
818 real_save_height
= maxHeight
- y
;
820 if ((real_width
> 0 && real_height
> 0) || (real_save_width
> 0
821 && real_save_height
> 0))
829 // SafeBltBitMap(rp->BitMap, x,y,
830 // bmn->bmn_SaveBitMap, 0,0, width, height, 0xc0, -1, NULL);
832 // bmn->bmn_SaveWidth = 0;
833 // bmn->bmn_SaveHeight = 0;
835 // BltBackgroundBitMap(bmn->bmn_DnD, x, y,
836 // bmn->bmn_SaveBitMap, 0,0, width, height);
838 if (bmn
->bmn_SaveWidth
> 0 && bmn
->bmn_SaveHeight
> 0)
839 RestoreBackground(bmn
, rp
);
841 BltBackgroundBitMap(bmn
, x
, y
, width
, height
, FALSE
);
843 // BltBitMapRastPort(bmn->bmn_SaveBitMap,0,0,
844 // rp, 20+bmn->bmn_Left*2,20+bmn->bmn_Top,width,height,0xc0);
847 BltBitMapNode(bmn
, 0, 0, rp
, x
, y
, width
, height
);
851 struct RastPort temp_rp
;
852 struct Rectangle save_rect
, rect
, result_rect
;
853 InitRastPort(&temp_rp
);
854 temp_rp
.BitMap
= temp_bmap
;
856 save_rect
.MinX
= save_x
;
857 save_rect
.MinY
= save_y
;
858 save_rect
.MaxX
= save_x
+ save_width
- 1;
859 save_rect
.MaxY
= save_y
+ save_height
- 1;
863 rect
.MaxX
= x
+ width
- 1;
864 rect
.MaxY
= y
+ height
- 1;
866 if (AndRectangle(&rect
, &save_rect
, &result_rect
))
868 LONG result_width
= result_rect
.MaxX
- result_rect
.MinX
+ 1;
870 result_rect
.MaxY
- result_rect
.MinY
+ 1;
871 LONG result_x
= result_rect
.MinX
- save_rect
.MinX
;
872 LONG result_y
= result_rect
.MinY
- save_rect
.MinY
;
873 // cout << rect.MinX << " " << rect.MaxX << " " << rect.MinY << " " << rect.MaxY << endl;
874 // cout << save_rect.MinX << " " << save_rect.MaxX << " " << save_rect.MinY << " " << save_rect.MaxY << endl;
875 // cout << result_rect.MinX << " " << result_rect.MaxX << " " << result_rect.MinY << " " << result_rect.MaxY << endl;
876 // cout << "soffx:" << save_offx << " offx:" << offx << " rx:" << result_x << " " << result_y << " " << " w: " << width << " " << result_width << " " << result_height << endl;
878 // SetRast(&temp_rp,0);
880 // Neuen Hintergrund in temporäre Bitmap
881 // SafeBltBitMapRastPort( rp->BitMap, x, y,
882 // &temp_rp, 0, 0, width, height,0xc0);
884 BltBackgroundBitMap(bmn
, x
, y
, width
, height
, TRUE
);
887 // BltBitMapRastPort(temp_bmap,0,0,rp,100+bmn->bmn_Left,
888 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
890 // Teile des alten Hintergrundes, die neu verdeckt werden in temporäre Bitmap
891 BltBitMapRastPort(bmn
->bmn_SaveBitMap
, result_x
, result_y
,
892 &temp_rp
, (result_x
? 0 : (save_width
- result_width
)),
893 result_y
? 0 : (save_height
- result_height
),
894 result_width
, result_height
, 0xc0);
897 // BltBitMapRastPort(temp_bmap,0,0,rp,180+bmn->bmn_Left,
898 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
901 // Teile des alten Hintergrundes, die nicht mehr verdeckt werden auf Screen
902 if ((save_width
- result_width
) > 0)
904 SafeBltBitMapRastPort(bmn
->bmn_SaveBitMap
,
905 (result_x
? 0 : (result_width
)), 0, rp
,
906 save_x
+ (result_x
? 0 : (result_width
)), save_y
,
907 save_width
- result_width
, save_height
, 0xc0);
910 if ((save_height
- result_height
) > 0)
912 SafeBltBitMapRastPort(bmn
->bmn_SaveBitMap
, 0,
913 result_y
? 0 : (result_height
), rp
, save_x
,
914 save_y
+ (result_y
? 0 : (result_height
)),
915 save_width
, save_height
- result_height
, 0xc0);
918 // temporäre BitMap ist neuer Hintergrund
919 BltBitMap(temp_bmap
, 0, 0,
920 bmn
->bmn_SaveBitMap
, 0, 0, width
, height
, 0xc0, -1,
923 /* Blit drag image bitmap to temporary bitmap */
924 BltBitMapNode(bmn
, 0, 0, &temp_rp
, 0, 0, width
, height
);
926 // Angenzende BitMaps in temporäre BitMap
927 BltNearBitMaps(bmn
, &temp_rp
, x
, y
, width
, height
);
930 // BltBitMapRastPort(temp_bmap,0,0,rp,240+bmn->bmn_Left,
931 // 20+bmn->bmn_Top,width,height,0xc0);
934 /* Blit prepared temporaty bitmap to screen */
935 SafeBltBitMapRastPort(temp_bmap
, 0, 0,
936 rp
, x
, y
, width
, height
, 0xc0);
939 // BltBitMapRastPort(bmn->bmn_SaveBitMap,0,0,rp,40+bmn->bmn_Left,
940 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
945 if (bmn
->bmn_SaveWidth
> 0 && bmn
->bmn_SaveHeight
> 0)
946 RestoreBackground(bmn
, rp
);
948 BltBackgroundBitMap(bmn
, x
, y
, width
, height
, FALSE
);
950 /* BltBitMapRastPort( bmn->bmn_SaveBitMap,0,0,
951 rp, bmn->bmn_SaveX, bmn->bmn_SaveY, bmn->bmn_SaveWidth, bmn->bmn_SaveHeight, 0xc0 );
953 SafeBltBitMap(rp->BitMap, x,y,
954 bmn->bmn_SaveBitMap, 0,0, width, height, 0xc0, -1, NULL);
956 BltBitMapNode(bmn
, 0, 0, rp
, x
, y
, width
, height
);
961 bmn
->bmn_Drawed
= TRUE
;
964 bmn
->bmn_SaveWidth
= width
;
965 bmn
->bmn_SaveHeight
= height
;
966 // bmn->bmn_SaveOffX = offx;
967 // bmn->bmn_SaveOffY = offy;
969 //-------------------------------------
970 VOID
UndrawBitMapNode(struct BitMapNode
*bmn
)
972 struct RastPort
*rp
= &bmn
->bmn_DnD
->dnd_Screen
->RastPort
;
974 if (!bmn
->bmn_SaveBitMap
)
977 if (bmn
->bmn_SaveWidth
> 0 && bmn
->bmn_SaveHeight
> 0)
979 SafeBltBitMapRastPort(bmn
->bmn_SaveBitMap
, 0, 0,
980 rp
, bmn
->bmn_SaveX
, bmn
->bmn_SaveY
, bmn
->bmn_SaveWidth
,
981 bmn
->bmn_SaveHeight
, 0xc0);
983 bmn
->bmn_SaveWidth
= 0;
984 bmn
->bmn_SaveHeight
= 0;
986 //-------------------------------------
988 //-------------------------------------
989 struct DragNDrop
*CreateDragNDropA(struct TagItem
*tlist
)
991 struct DragNDrop
*dnd
=
992 (struct DragNDrop
*)AllocMem(sizeof(struct DragNDrop
), MEMF_CLEAR
);
995 NewList((struct List
*)&dnd
->dnd_List
);
997 /* if(dnd->dnd_LayerInfo = NewLayerInfo()))
999 dnd->dnd_Screen = NULL
1000 dnd->dnd_TempBitMap = NULL;
1003 struct RastPort *rp = &dnd->dnd_RastPort;
1008 if(dnd->dnd_Layer = CreateBehindLayer(dnd->dnd_LayerInfo,
1012 FreeMem( dnd, sizeof(struct DragNDrop ));*/
1017 //-------------------------------------
1018 VOID
DeleteDragNDrop(struct DragNDrop
*dnd
)
1020 struct BitMapNode
*node
;
1022 FinishDragNDrop(dnd
);
1025 (struct BitMapNode
*)RemTail((struct List
*)&dnd
->dnd_List
)))
1026 DeleteBitMapNode(node
);
1028 FreeMem(dnd
, sizeof(struct DragNDrop
));
1030 //-------------------------------------
1031 VOID
DrawDragNDrop(struct DragNDrop
*dnd
, LONG x
, LONG y
)
1035 // static LONG first=TRUE;
1037 struct BitMapNode
*node
;
1039 LONG diffx
= x
- lastx
;
1040 LONG diffy
= y
- lasty
;
1042 if (!dnd
|| !dnd
->dnd_Screen
)
1047 if (abs(diffy
) < abs(diffx
)) //y==lasty)
1051 List_Sort_Mode_3(&dnd
->dnd_List
);
1057 List_Sort_Mode_1(&dnd
->dnd_List
);
1061 /* if(first) reverse = FALSE;
1064 if( x<lastx) reverse = FALSE;
1067 if(x==lastx && y < lasty) reverse=FALSE;
1068 else reverse = TRUE;
1071 if(x>lastx && y < lasty)
1073 List_Sort_Mode_2(&dnd->dnd_List);
1077 if(x<lastx && y > lasty)
1079 List_Sort_Mode_2(&dnd->dnd_List);
1085 // cout << x << " " << lastx << " " << y << " " << lasty << " " << reverse << endl;
1088 node
= List_First(&dnd
->dnd_List
);
1091 node
->bmn_Drawed
= FALSE
;
1092 node
= Node_Next(node
);
1097 node
= List_First(&dnd
->dnd_List
);
1100 DrawBitMapNode(node
, x
+ node
->bmn_Left
, y
+ node
->bmn_Top
);
1101 node
= Node_Next(node
);
1106 node
= (struct BitMapNode
*)List_Last(&dnd
->dnd_List
);
1109 DrawBitMapNode(node
, x
+ node
->bmn_Left
, y
+ node
->bmn_Top
);
1110 node
= (struct BitMapNode
*)Node_Prev(node
);
1117 //-------------------------------------
1118 VOID
UndrawDragNDrop(struct DragNDrop
*dnd
)
1120 struct BitMapNode
*node
;
1121 node
= (struct BitMapNode
*)List_Last(&dnd
->dnd_List
);
1124 UndrawBitMapNode(node
);
1125 node
= (struct BitMapNode
*)Node_Prev(node
);
1128 //-------------------------------------
1129 BOOL
PrepareDragNDrop(struct DragNDrop
*dnd
, struct Screen
*scr
)
1131 struct BitMapNode
*bmn
;
1132 struct RastPort
*rp
;
1134 LONG maxwidth
= 0, maxheight
= 0;
1139 dnd
->dnd_Screen
= scr
;
1141 rp
= &scr
->RastPort
;
1142 depth
= GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
);
1144 bmn
= List_First(&dnd
->dnd_List
);
1147 bmn
->bmn_SaveWidth
= bmn
->bmn_SaveHeight
= 0;
1148 if (bmn
->bmn_Width
> maxwidth
)
1149 maxwidth
= bmn
->bmn_Width
;
1150 if (bmn
->bmn_Height
> maxheight
)
1151 maxheight
= bmn
->bmn_Height
;
1153 if (!(bmn
->bmn_SaveBitMap
=
1154 AllocBitMap(bmn
->bmn_Width
, bmn
->bmn_Height
, depth
,
1155 BMF_MINPLANES
, rp
->BitMap
)))
1160 bmn
= Node_Next(bmn
);
1163 if (ok
&& maxwidth
&& maxheight
)
1165 dnd
->dnd_TempBitMap
=
1166 /*NULL;// */ AllocBitMap(maxwidth
, maxheight
, depth
,
1167 BMF_MINPLANES
, rp
->BitMap
);
1171 bmn
= List_First(&dnd
->dnd_List
);
1174 if (bmn
->bmn_SaveBitMap
)
1176 FreeBitMap(bmn
->bmn_SaveBitMap
);
1177 bmn
->bmn_SaveBitMap
= NULL
;
1179 bmn
= Node_Next(bmn
);
1184 //-------------------------------------
1185 VOID
FinishDragNDrop(struct DragNDrop
*dnd
)
1187 struct BitMapNode
*bmn
;
1188 if (dnd
->dnd_TempBitMap
)
1189 FreeBitMap(dnd
->dnd_TempBitMap
);
1191 bmn
= List_First(&dnd
->dnd_List
);
1194 if (bmn
->bmn_SaveBitMap
)
1196 FreeBitMap(bmn
->bmn_SaveBitMap
);
1197 bmn
->bmn_SaveBitMap
= NULL
;
1199 bmn
= Node_Next(bmn
);
1203 //-------------------------------------
1205 /**********************************************************************
1206 Varargs function of CreateBitMapNode(). Note that we need a dummy
1207 because we need at least one parameter
1208 **********************************************************************/
1209 struct BitMapNode
*VARARGS68K
CreateBitMapNode(void *dummy
, ...)
1211 #ifndef __amigaos4__
1212 return CreateBitMapNodeA((struct TagItem
*)(((ULONG
*) & dummy
) + 1));
1215 struct TagItem
*tagList
;
1216 struct BitMapNode
*res
;
1218 va_startlinear(argptr
, dummy
);
1219 tagList
= va_getlinearva(argptr
, struct TagItem
*);
1220 res
= CreateBitMapNodeA(tagList
);
1226 /******************************************************************************/
1245 struct Library
*TimerBase
;
1248 struct MsgPort
*msgport
;
1249 struct timerequest
*iorequest
;
1250 struct Library
*timerbase
;
1254 //-------------------------------------
1255 ASM VOID
TIMER_DeleteTimer(register __a0 APTR t
)
1259 struct TimerStruct
*timer
= (struct TimerStruct
*)t
;
1262 if (timer
->timerbase
)
1266 // printf("Test1\n");
1267 AbortIO((struct IORequest
*)timer
->iorequest
);
1268 // printf("Test2\n");
1269 WaitIO((struct IORequest
*)timer
->iorequest
);
1272 CloseDevice((struct IORequest
*)timer
->iorequest
);
1274 if (timer
->iorequest
)
1275 DeleteIORequest(timer
->iorequest
);
1277 DeleteMsgPort(timer
->msgport
);
1282 //-------------------------------------
1283 ASM APTR
TIMER_CreateTimer()
1285 struct TimerStruct
*timer
=
1286 (struct TimerStruct
*)AllocVec(sizeof(struct TimerStruct
), 0x10000);
1289 if ((timer
->msgport
= CreateMsgPort()))
1291 if ((timer
->iorequest
=
1292 (struct timerequest
*)CreateIORequest(timer
->msgport
,
1293 sizeof(struct timerequest
))))
1295 if (!OpenDevice(TIMERNAME
, UNIT_VBLANK
,
1296 (struct IORequest
*)timer
->iorequest
, NULL
))
1299 /*TimerBase = */ timer
->timerbase
=
1300 (struct Library
*)timer
->iorequest
->tr_node
.
1304 (struct Library
*)timer
->iorequest
->tr_node
.
1311 TIMER_DeleteTimer(timer
);
1315 //-------------------------------------
1316 ASM
struct MsgPort
*TIMER_GetMsgPort(register __a0 APTR t
)
1320 return ((struct TimerStruct
*)t
)->msgport
;
1322 //-------------------------------------
1323 ASM ULONG
TIMER_GetSigMask(register __a0 APTR t
)
1327 return (1UL << (((struct TimerStruct
*)t
)->msgport
->mp_SigBit
));
1329 //-------------------------------------
1330 ASM APTR
TIMER_StartTimer(register __a0 APTR t
, register __d0 ULONG secs
,
1331 register __d1 ULONG mics
)
1333 struct TimerStruct
*timer
;
1334 struct timerequest
*req
;
1339 timer
= (struct TimerStruct
*)t
;
1343 req
= timer
->iorequest
;
1344 req
->tr_node
.io_Command
= TR_ADDREQUEST
;
1345 req
->tr_time
.tv_secs
= secs
;
1346 req
->tr_time
.tv_micro
= mics
;
1348 SendIO((struct IORequest
*)req
);
1351 //-------------------------------------
1352 ASM VOID
TIMER_StopTimer(register __a0 APTR t
)
1354 struct TimerStruct
*timer
;
1358 timer
= (struct TimerStruct
*)t
;
1361 AbortIO((struct IORequest
*)timer
->iorequest
);
1362 WaitIO((struct IORequest
*)timer
->iorequest
);
1366 //-------------------------------------
1368 //-------------------------------------
1369 struct BitMap
*CreateBitmapFromIcon(struct Screen
*scr
,
1370 struct DiskObject
*dobj
, LONG
*width
, LONG
*height
)
1372 struct Rectangle rect
;
1373 static struct TagItem rect_tags
[] = {
1374 ICONDRAWA_Borderless
, TRUE
,
1378 static struct TagItem draw_tags
[] = {
1379 ICONDRAWA_Borderless
, TRUE
,
1380 ICONDRAWA_EraseBackground
, TRUE
,
1387 if (GetIconRectangleA(NULL
, dobj
, NULL
, &rect
, rect_tags
))
1390 struct BitMap
*bmap
;
1391 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_FLAGS
) & BMF_STANDARD
)
1396 *width
= rect
.MaxX
- rect
.MinX
+ 1;
1397 *height
= rect
.MaxY
- rect
.MinY
+ 1;
1399 // cout << rect.MinY << " " << rect.MaxY << endl;
1402 AllocBitMap(*width
, *height
, 8, /*NULL,NULL);// */
1403 BMF_MINPLANES
, standard
? NULL
: scr
->RastPort
.BitMap
);
1410 DrawIconStateA(&rp
, dobj
, NULL
, 0, 0, IDS_SELECTED
, draw_tags
);
1418 //-------------------------------------
1421 struct DragNDrop
*drag
;
1423 //-------------------------------------
1427 static LONG lmx
, lmy
;
1429 WaitPort(wnd
->UserPort
);
1430 while (ready
== FALSE
)
1432 struct IntuiMessage
*imsg
;
1433 while ((imsg
= (struct IntuiMessage
*)GetMsg(wnd
->UserPort
)))
1435 ULONG cl
= imsg
->Class
;
1436 UWORD code
= imsg
->Code
;
1437 // LONG mx = imsg->MouseX;
1438 // LONG my = imsg->MouseY;
1440 ReplyMsg((struct Message
*)imsg
);
1444 case IDCMP_CLOSEWINDOW
:
1448 case IDCMP_VANILLAKEY
:
1450 DrawDragNDrop(drag
, wnd
->WScreen
->MouseX
,
1451 wnd
->WScreen
->MouseY
);
1452 lmx
= wnd
->WScreen
->MouseX
;
1453 lmy
= wnd
->WScreen
->MouseY
;
1457 case IDCMP_MOUSEBUTTONS
:
1458 if (code
== SELECTDOWN
)
1460 DrawDragNDrop(drag
, wnd
->WScreen
->MouseX
,
1461 wnd
->WScreen
->MouseY
);
1462 lmx
= wnd
->WScreen
->MouseX
;
1463 lmy
= wnd
->WScreen
->MouseY
;
1467 case IDCMP_MOUSEMOVE
:
1468 // cout << wnd->WScreen->MouseX - lmx << " " << wnd->WScreen->MouseY - lmy << endl;
1469 // WaitBOVP(&wnd->WScreen->ViewPort);
1470 DrawDragNDrop(drag
, wnd
->WScreen
->MouseX
,
1471 wnd
->WScreen
->MouseY
);
1477 //-------------------------------------
1479 UBYTE fullmask
[8192];
1484 for (i
= 0; i
< 8192; i
++)
1487 wnd
= OpenWindowTags(NULL
,
1489 WA_InnerHeight
, 200,
1491 IDCMP_CLOSEWINDOW
| IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
|
1492 IDCMP_MOUSEBUTTONS
| IDCMP_VANILLAKEY
, WA_DragBar
, TRUE
,
1493 WA_DepthGadget
, TRUE
, WA_CloseGadget
, TRUE
, WA_ReportMouse
, TRUE
,
1494 WA_Activate
, TRUE
, WA_GimmeZeroZero
, TRUE
, WA_MouseQueue
, 2,
1499 struct DiskObject
*obj1
= GetIconTags("SYS:Prefs",
1500 ICONGETA_GenerateImageMasks
, TRUE
,
1502 struct DiskObject
*obj2
= GetIconTags("SYS:Picasso96",
1503 ICONGETA_GenerateImageMasks
, TRUE
,
1505 struct DiskObject
*obj3
= GetIconTags("SYS:Tools",
1506 ICONGETA_GenerateImageMasks
, TRUE
,
1509 struct BitMap
*bmap1
=
1510 CreateBitmapFromIcon(wnd
->WScreen
, obj1
, &width
, &height
);
1511 struct BitMap
*bmap2
=
1512 CreateBitmapFromIcon(wnd
->WScreen
, obj2
, &width
, &height
);
1513 struct BitMap
*bmap3
=
1514 CreateBitmapFromIcon(wnd
->WScreen
, obj3
, &width
, &height
);
1515 if (bmap1
&& bmap2
&& bmap3
)
1517 APTR mask1
, mask2
, mask3
;
1518 IconControl(obj1
, ICONCTRLA_GetImageMask1
, &mask1
, TAG_DONE
);
1519 IconControl(obj2
, ICONCTRLA_GetImageMask1
, &mask2
, TAG_DONE
);
1520 IconControl(obj3
, ICONCTRLA_GetImageMask1
, &mask3
, TAG_DONE
);
1521 if ((drag
= CreateDragNDropA(NULL
)))
1523 struct BitMapNode
*bmn1
=
1524 CreateBitMapNode(GUI_BitMap
, bmap1
,
1529 GUI_LeftOffset
, -35,
1532 struct BitMapNode
*bmn2
=
1533 CreateBitMapNode(GUI_BitMap
, bmap2
,
1540 struct BitMapNode
*bmn3
=
1541 CreateBitMapNode(GUI_BitMap
, bmap3
,
1549 struct BitMapNode
*bmn4
=
1550 CreateBitMapNode(GUI_BitMap
, bmap1
,
1557 struct BitMapNode
*bmn5
=
1558 CreateBitMapNode(GUI_BitMap
, bmap2
,
1566 struct BitMapNode
*bmn6
=
1567 CreateBitMapNode(GUI_BitMap
, bmap3
,
1571 GUI_LeftOffset
, 100,
1575 if (bmn1
&& bmn2
&& bmn3
&& bmn4
&& bmn5
&& bmn6
)
1577 AttachBitMapNode(drag
, bmn1
);
1578 AttachBitMapNode(drag
, bmn2
);
1579 AttachBitMapNode(drag
, bmn3
);
1580 AttachBitMapNode(drag
, bmn4
);
1581 AttachBitMapNode(drag
, bmn5
);
1582 AttachBitMapNode(drag
, bmn6
);
1583 PrepareDragNDrop(drag
, wnd
->WScreen
);
1585 FinishDragNDrop(drag
);
1586 DetachBitMapNode(bmn6
);
1587 DetachBitMapNode(bmn5
);
1588 DetachBitMapNode(bmn4
);
1589 DetachBitMapNode(bmn3
);
1590 DetachBitMapNode(bmn2
);
1591 DetachBitMapNode(bmn1
);
1594 DeleteBitMapNode(bmn6
);
1596 DeleteBitMapNode(bmn5
);
1598 DeleteBitMapNode(bmn4
);
1600 DeleteBitMapNode(bmn3
);
1602 DeleteBitMapNode(bmn2
);
1604 DeleteBitMapNode(bmn1
);
1605 DeleteDragNDrop(drag
);
1617 FreeDiskObject(obj3
);
1619 FreeDiskObject(obj2
);
1621 FreeDiskObject(obj1
);
1626 //-------------------------------------