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
);
549 /* This operation is insanely expensive on slow m68k
550 * machines in planar modes.
552 IPTR depth
= GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
);
553 if (depth
> 8 && src_bmn
->bmn_BitMapBuffer
)
555 if (src_bmn
->bmn_BitMapBuffer
)
558 /* This should be done using BltBitMapRastPortAlpha with
559 * direct video card alpha blit, but this function is not
560 * available on AROS yet. Current implementation is that
561 * src_bmn->bmn_BitMapBuffer contains 32bit ARGB buffer
562 * acquired from src_bmn->bmn_BitMap */
563 WritePixelArrayAlpha(src_bmn
->bmn_BitMapBuffer
, offx
, offy
,
564 src_bmn
->bmn_Width
* sizeof(ULONG
), rp
, x
, y
, width
,
569 BltBitMapRastPort(src_bmn
->bmn_BitMap
, offx
, offy
,
570 rp
, x
, y
, width
, height
, 0xc0);
575 //-------------------------------------
576 STATIC VOID
BltNearBitMaps(struct BitMapNode
*src_bmn
, struct RastPort
*rp
,
577 LONG x
, LONG y
, LONG width
, LONG height
)
579 struct DragNDrop
*dnd
= src_bmn
->bmn_DnD
;
580 struct BitMapNode
*bmn
= List_First(&dnd
->dnd_List
);
581 struct Rectangle rect
;
585 rect
.MaxX
= x
+ width
- 1;
586 rect
.MaxY
= y
+ height
- 1;
590 if (bmn
!= src_bmn
&& bmn
->bmn_Drawed
)
592 struct Rectangle bmn_rect
, result_rect
;
593 bmn_rect
.MinX
= bmn
->bmn_SaveX
;
594 bmn_rect
.MinY
= bmn
->bmn_SaveY
;
595 bmn_rect
.MaxX
= bmn_rect
.MinX
+ bmn
->bmn_SaveWidth
- 1;
596 bmn_rect
.MaxY
= bmn_rect
.MinY
+ bmn
->bmn_SaveHeight
- 1;
598 if (AndRectangle(&rect
, &bmn_rect
, &result_rect
))
600 LONG bmn_x
= result_rect
.MinX
- bmn_rect
.MinX
;
601 LONG bmn_y
= result_rect
.MinY
- bmn_rect
.MinY
;
602 LONG bmn_width
= result_rect
.MaxX
- result_rect
.MinX
+ 1;
603 LONG bmn_height
= result_rect
.MaxY
- result_rect
.MinY
+ 1;
604 LONG xDest
= result_rect
.MinX
- rect
.MinX
;
605 LONG yDest
= result_rect
.MinY
- rect
.MinY
;
607 BltBitMapNode(bmn
, bmn_x
, bmn_y
,
608 rp
, xDest
, yDest
, bmn_width
, bmn_height
);
612 bmn
= Node_Next(bmn
);
615 //-------------------------------------
616 STATIC VOID
RestoreBackground(struct BitMapNode
*src_bmn
,
619 LONG save_x
= src_bmn
->bmn_SaveX
;
620 LONG save_y
= src_bmn
->bmn_SaveY
;
621 LONG save_width
= src_bmn
->bmn_SaveWidth
;
622 LONG save_height
= src_bmn
->bmn_SaveHeight
;
624 struct DragNDrop
*dnd
= src_bmn
->bmn_DnD
;
625 struct BitMapNode
*bmn
= List_First(&dnd
->dnd_List
);
626 struct Rectangle last_rect
;
628 last_rect
.MinX
= save_x
;
629 last_rect
.MinY
= save_y
;
630 last_rect
.MaxX
= save_x
+ save_width
- 1;
631 last_rect
.MaxY
= save_y
+ save_height
- 1;
633 SafeBltBitMapRastPort(src_bmn
->bmn_SaveBitMap
, 0, 0,
634 rp
, save_x
, save_y
, save_width
, save_height
, 0xc0);
639 if (bmn
!= src_bmn
&& bmn
->bmn_Drawed
)
641 struct Rectangle bmn_rect
, result_rect
;
642 bmn_rect
.MinX
= bmn
->bmn_SaveX
;
643 bmn_rect
.MinY
= bmn
->bmn_SaveY
;
644 bmn_rect
.MaxX
= bmn_rect
.MinX
+ bmn
->bmn_SaveWidth
- 1;
645 bmn_rect
.MaxY
= bmn_rect
.MinY
+ bmn
->bmn_SaveHeight
- 1;
647 if (AndRectangle(&last_rect
, &bmn_rect
, &result_rect
))
649 LONG bmn_x
= result_rect
.MinX
- bmn_rect
.MinX
;
650 LONG bmn_y
= result_rect
.MinY
- bmn_rect
.MinY
;
651 LONG bmn_width
= result_rect
.MaxX
- result_rect
.MinX
+ 1;
652 LONG bmn_height
= result_rect
.MaxY
- result_rect
.MinY
+ 1;
653 /* LONG xDest = result_rect.MinX - last_rect.MinX; */
654 /* LONG yDest = result_rect.MinY - last_rect.MinY; */
656 BltBitMapNode(bmn
, bmn_x
, bmn_y
,
657 rp
, result_rect
.MinX
, result_rect
.MinY
, bmn_width
,
660 // SafeBltBitMapRastPort(bmn->bmn_SaveBitMap, bmn_x, bmn_y,
661 // rp, xDest, yDest, bmn_width, bmn_height,0xc0);
665 bmn
= Node_Next(bmn
);
668 //-------------------------------------
669 struct BitMapNode
*CreateBitMapNodeA(struct TagItem
*tagList
)
671 struct BitMapNode
*bmn
=
672 (struct BitMapNode
*)AllocMem(sizeof(struct BitMapNode
),
676 BOOL sourcealpha
= FALSE
;
677 struct TagItem
*tl
= tagList
;
680 while ((tag
= NextTagItem(&tl
)))
682 ULONG id
= tag
->ti_Tag
;
683 IPTR data
= tag
->ti_Data
;
688 bmn
->bmn_BitMap
= (struct BitMap
*)data
;
692 bmn
->bmn_Mask
= (APTR
) data
;
696 bmn
->bmn_Left
= data
;
704 bmn
->bmn_Width
= data
;
708 bmn
->bmn_Height
= data
;
711 case GUI_SourceAlpha
:
717 if (!bmn
->bmn_BitMap
)
719 FreeMem(bmn
, sizeof(struct BitMapNode
));
723 if (bmn
&& sourcealpha
)
725 /* See notes in BltBitMapNode */
726 struct RastPort temp_rp
;
727 InitRastPort(&temp_rp
);
728 temp_rp
.BitMap
= bmn
->bmn_BitMap
;
729 bmn
->bmn_BitMapBuffer
=
730 AllocVec(bmn
->bmn_Width
* bmn
->bmn_Height
* sizeof(ULONG
),
732 ReadPixelArray(bmn
->bmn_BitMapBuffer
, 0, 0,
733 bmn
->bmn_Width
* sizeof(ULONG
), &temp_rp
, 0, 0,
734 bmn
->bmn_Width
, bmn
->bmn_Height
, RECTFMT_ARGB
);
735 DeinitRastPort(&temp_rp
);
740 //-------------------------------------
741 VOID
DeleteBitMapNode(struct BitMapNode
*bmn
)
743 if (bmn
->bmn_SaveBitMap
)
744 FreeBitMap(bmn
->bmn_SaveBitMap
);
745 FreeVec(bmn
->bmn_BitMapBuffer
);
746 FreeMem(bmn
, sizeof(struct BitMapNode
));
748 //-------------------------------------
749 struct BitMap
*GetBitMap(struct BitMapNode
*bmn
)
752 return bmn
->bmn_BitMap
;
755 //-------------------------------------
756 VOID
AttachBitMapNode(struct DragNDrop
*dnd
, struct BitMapNode
*bmn
)
758 AddTail((struct List
*)&dnd
->dnd_List
, (struct Node
*)&bmn
->bmn_Node
);
761 //-------------------------------------
762 VOID
DetachBitMapNode(struct BitMapNode
*bmn
)
764 if (bmn
->bmn_Succ
&& bmn
->bmn_Pred
)
766 Remove((struct Node
*)&bmn
->bmn_Node
);
767 bmn
->bmn_Succ
= bmn
->bmn_Pred
= NULL
;
771 //-------------------------------------
772 VOID
DrawBitMapNode(struct BitMapNode
*bmn
, LONG x
, LONG y
)
774 LONG width
= bmn
->bmn_Width
;
775 LONG height
= bmn
->bmn_Height
;
776 LONG save_x
= bmn
->bmn_SaveX
;
777 LONG save_y
= bmn
->bmn_SaveY
;
778 LONG save_width
= bmn
->bmn_SaveWidth
;
779 LONG save_height
= bmn
->bmn_SaveHeight
;
781 struct BitMap
*temp_bmap
;
782 BOOL draw
= TRUE
; //FALSE;
784 if (!bmn
|| !bmn
->bmn_DnD
|| !bmn
->bmn_DnD
->dnd_Screen
)
786 rp
= &bmn
->bmn_DnD
->dnd_Screen
->RastPort
;
787 temp_bmap
= bmn
->bmn_DnD
->dnd_TempBitMap
;
789 if (!bmn
->bmn_SaveBitMap
)
792 /* if( bmn->bmn_SaveWidth > 0 && bmn->bmn_SaveHeight > 0 )
796 RestoreBackground(bmn,rp);
802 maxHeight
/* , offx=0, offy=0, save_offx=0, save_offy=0 */ ;
803 LONG real_width
= width
, real_height
= height
;
804 LONG real_save_width
= save_width
, real_save_height
= save_height
;
806 maxWidth
= GetBitMapAttr(rp
->BitMap
, BMA_WIDTH
);
807 maxHeight
= GetBitMapAttr(rp
->BitMap
, BMA_HEIGHT
);
814 real_save_width
+= save_x
;
816 real_save_height
+= save_y
;
818 if (real_width
+ x
> maxWidth
)
819 real_width
= maxWidth
- x
;
820 if (real_height
+ y
> maxHeight
)
821 real_height
= maxHeight
- y
;
822 if (real_save_width
+ x
> maxWidth
)
823 real_save_width
= maxWidth
- x
;
824 if (real_save_height
+ y
> maxHeight
)
825 real_save_height
= maxHeight
- y
;
827 if ((real_width
> 0 && real_height
> 0) || (real_save_width
> 0
828 && real_save_height
> 0))
836 // SafeBltBitMap(rp->BitMap, x,y,
837 // bmn->bmn_SaveBitMap, 0,0, width, height, 0xc0, -1, NULL);
839 // bmn->bmn_SaveWidth = 0;
840 // bmn->bmn_SaveHeight = 0;
842 // BltBackgroundBitMap(bmn->bmn_DnD, x, y,
843 // bmn->bmn_SaveBitMap, 0,0, width, height);
845 if (bmn
->bmn_SaveWidth
> 0 && bmn
->bmn_SaveHeight
> 0)
846 RestoreBackground(bmn
, rp
);
848 BltBackgroundBitMap(bmn
, x
, y
, width
, height
, FALSE
);
850 // BltBitMapRastPort(bmn->bmn_SaveBitMap,0,0,
851 // rp, 20+bmn->bmn_Left*2,20+bmn->bmn_Top,width,height,0xc0);
854 BltBitMapNode(bmn
, 0, 0, rp
, x
, y
, width
, height
);
858 struct RastPort temp_rp
;
859 struct Rectangle save_rect
, rect
, result_rect
;
860 InitRastPort(&temp_rp
);
861 temp_rp
.BitMap
= temp_bmap
;
863 save_rect
.MinX
= save_x
;
864 save_rect
.MinY
= save_y
;
865 save_rect
.MaxX
= save_x
+ save_width
- 1;
866 save_rect
.MaxY
= save_y
+ save_height
- 1;
870 rect
.MaxX
= x
+ width
- 1;
871 rect
.MaxY
= y
+ height
- 1;
873 if (AndRectangle(&rect
, &save_rect
, &result_rect
))
875 LONG result_width
= result_rect
.MaxX
- result_rect
.MinX
+ 1;
877 result_rect
.MaxY
- result_rect
.MinY
+ 1;
878 LONG result_x
= result_rect
.MinX
- save_rect
.MinX
;
879 LONG result_y
= result_rect
.MinY
- save_rect
.MinY
;
880 // cout << rect.MinX << " " << rect.MaxX << " " << rect.MinY << " " << rect.MaxY << endl;
881 // cout << save_rect.MinX << " " << save_rect.MaxX << " " << save_rect.MinY << " " << save_rect.MaxY << endl;
882 // cout << result_rect.MinX << " " << result_rect.MaxX << " " << result_rect.MinY << " " << result_rect.MaxY << endl;
883 // cout << "soffx:" << save_offx << " offx:" << offx << " rx:" << result_x << " " << result_y << " " << " w: " << width << " " << result_width << " " << result_height << endl;
885 // SetRast(&temp_rp,0);
887 // Neuen Hintergrund in temporäre Bitmap
888 // SafeBltBitMapRastPort( rp->BitMap, x, y,
889 // &temp_rp, 0, 0, width, height,0xc0);
891 BltBackgroundBitMap(bmn
, x
, y
, width
, height
, TRUE
);
894 // BltBitMapRastPort(temp_bmap,0,0,rp,100+bmn->bmn_Left,
895 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
897 // Teile des alten Hintergrundes, die neu verdeckt werden in temporäre Bitmap
898 BltBitMapRastPort(bmn
->bmn_SaveBitMap
, result_x
, result_y
,
899 &temp_rp
, (result_x
? 0 : (save_width
- result_width
)),
900 result_y
? 0 : (save_height
- result_height
),
901 result_width
, result_height
, 0xc0);
904 // BltBitMapRastPort(temp_bmap,0,0,rp,180+bmn->bmn_Left,
905 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
908 // Teile des alten Hintergrundes, die nicht mehr verdeckt werden auf Screen
909 if ((save_width
- result_width
) > 0)
911 SafeBltBitMapRastPort(bmn
->bmn_SaveBitMap
,
912 (result_x
? 0 : (result_width
)), 0, rp
,
913 save_x
+ (result_x
? 0 : (result_width
)), save_y
,
914 save_width
- result_width
, save_height
, 0xc0);
917 if ((save_height
- result_height
) > 0)
919 SafeBltBitMapRastPort(bmn
->bmn_SaveBitMap
, 0,
920 result_y
? 0 : (result_height
), rp
, save_x
,
921 save_y
+ (result_y
? 0 : (result_height
)),
922 save_width
, save_height
- result_height
, 0xc0);
925 // temporäre BitMap ist neuer Hintergrund
926 BltBitMap(temp_bmap
, 0, 0,
927 bmn
->bmn_SaveBitMap
, 0, 0, width
, height
, 0xc0, -1,
930 /* Blit drag image bitmap to temporary bitmap */
931 BltBitMapNode(bmn
, 0, 0, &temp_rp
, 0, 0, width
, height
);
933 // Angenzende BitMaps in temporäre BitMap
934 BltNearBitMaps(bmn
, &temp_rp
, x
, y
, width
, height
);
937 // BltBitMapRastPort(temp_bmap,0,0,rp,240+bmn->bmn_Left,
938 // 20+bmn->bmn_Top,width,height,0xc0);
941 /* Blit prepared temporaty bitmap to screen */
942 SafeBltBitMapRastPort(temp_bmap
, 0, 0,
943 rp
, x
, y
, width
, height
, 0xc0);
946 // BltBitMapRastPort(bmn->bmn_SaveBitMap,0,0,rp,40+bmn->bmn_Left,
947 // 20+bmn->bmn_Top,bmn->bmn_Width,bmn->bmn_Height,0xc0);
952 if (bmn
->bmn_SaveWidth
> 0 && bmn
->bmn_SaveHeight
> 0)
953 RestoreBackground(bmn
, rp
);
955 BltBackgroundBitMap(bmn
, x
, y
, width
, height
, FALSE
);
957 /* BltBitMapRastPort( bmn->bmn_SaveBitMap,0,0,
958 rp, bmn->bmn_SaveX, bmn->bmn_SaveY, bmn->bmn_SaveWidth, bmn->bmn_SaveHeight, 0xc0 );
960 SafeBltBitMap(rp->BitMap, x,y,
961 bmn->bmn_SaveBitMap, 0,0, width, height, 0xc0, -1, NULL);
963 BltBitMapNode(bmn
, 0, 0, rp
, x
, y
, width
, height
);
968 bmn
->bmn_Drawed
= TRUE
;
971 bmn
->bmn_SaveWidth
= width
;
972 bmn
->bmn_SaveHeight
= height
;
973 // bmn->bmn_SaveOffX = offx;
974 // bmn->bmn_SaveOffY = offy;
976 //-------------------------------------
977 VOID
UndrawBitMapNode(struct BitMapNode
*bmn
)
979 struct RastPort
*rp
= &bmn
->bmn_DnD
->dnd_Screen
->RastPort
;
981 if (!bmn
->bmn_SaveBitMap
)
984 if (bmn
->bmn_SaveWidth
> 0 && bmn
->bmn_SaveHeight
> 0)
986 SafeBltBitMapRastPort(bmn
->bmn_SaveBitMap
, 0, 0,
987 rp
, bmn
->bmn_SaveX
, bmn
->bmn_SaveY
, bmn
->bmn_SaveWidth
,
988 bmn
->bmn_SaveHeight
, 0xc0);
990 bmn
->bmn_SaveWidth
= 0;
991 bmn
->bmn_SaveHeight
= 0;
993 //-------------------------------------
995 //-------------------------------------
996 struct DragNDrop
*CreateDragNDropA(struct TagItem
*tlist
)
998 struct DragNDrop
*dnd
=
999 (struct DragNDrop
*)AllocMem(sizeof(struct DragNDrop
), MEMF_CLEAR
);
1002 NewList((struct List
*)&dnd
->dnd_List
);
1004 /* if(dnd->dnd_LayerInfo = NewLayerInfo()))
1006 dnd->dnd_Screen = NULL
1007 dnd->dnd_TempBitMap = NULL;
1010 struct RastPort *rp = &dnd->dnd_RastPort;
1015 if(dnd->dnd_Layer = CreateBehindLayer(dnd->dnd_LayerInfo,
1019 FreeMem( dnd, sizeof(struct DragNDrop ));*/
1024 //-------------------------------------
1025 VOID
DeleteDragNDrop(struct DragNDrop
*dnd
)
1027 struct BitMapNode
*node
;
1029 FinishDragNDrop(dnd
);
1032 (struct BitMapNode
*)RemTail((struct List
*)&dnd
->dnd_List
)))
1033 DeleteBitMapNode(node
);
1035 FreeMem(dnd
, sizeof(struct DragNDrop
));
1037 //-------------------------------------
1038 VOID
DrawDragNDrop(struct DragNDrop
*dnd
, LONG x
, LONG y
)
1042 // static LONG first=TRUE;
1044 struct BitMapNode
*node
;
1046 LONG diffx
= x
- lastx
;
1047 LONG diffy
= y
- lasty
;
1049 if (!dnd
|| !dnd
->dnd_Screen
)
1054 if (abs(diffy
) < abs(diffx
)) //y==lasty)
1058 List_Sort_Mode_3(&dnd
->dnd_List
);
1064 List_Sort_Mode_1(&dnd
->dnd_List
);
1068 /* if(first) reverse = FALSE;
1071 if( x<lastx) reverse = FALSE;
1074 if(x==lastx && y < lasty) reverse=FALSE;
1075 else reverse = TRUE;
1078 if(x>lastx && y < lasty)
1080 List_Sort_Mode_2(&dnd->dnd_List);
1084 if(x<lastx && y > lasty)
1086 List_Sort_Mode_2(&dnd->dnd_List);
1092 // cout << x << " " << lastx << " " << y << " " << lasty << " " << reverse << endl;
1095 node
= List_First(&dnd
->dnd_List
);
1098 node
->bmn_Drawed
= FALSE
;
1099 node
= Node_Next(node
);
1104 node
= List_First(&dnd
->dnd_List
);
1107 DrawBitMapNode(node
, x
+ node
->bmn_Left
, y
+ node
->bmn_Top
);
1108 node
= Node_Next(node
);
1113 node
= (struct BitMapNode
*)List_Last(&dnd
->dnd_List
);
1116 DrawBitMapNode(node
, x
+ node
->bmn_Left
, y
+ node
->bmn_Top
);
1117 node
= (struct BitMapNode
*)Node_Prev(node
);
1124 //-------------------------------------
1125 VOID
UndrawDragNDrop(struct DragNDrop
*dnd
)
1127 struct BitMapNode
*node
;
1128 node
= (struct BitMapNode
*)List_Last(&dnd
->dnd_List
);
1131 UndrawBitMapNode(node
);
1132 node
= (struct BitMapNode
*)Node_Prev(node
);
1135 //-------------------------------------
1136 BOOL
PrepareDragNDrop(struct DragNDrop
*dnd
, struct Screen
*scr
)
1138 struct BitMapNode
*bmn
;
1139 struct RastPort
*rp
;
1141 LONG maxwidth
= 0, maxheight
= 0;
1146 dnd
->dnd_Screen
= scr
;
1148 rp
= &scr
->RastPort
;
1149 depth
= GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
);
1151 bmn
= List_First(&dnd
->dnd_List
);
1154 bmn
->bmn_SaveWidth
= bmn
->bmn_SaveHeight
= 0;
1155 if (bmn
->bmn_Width
> maxwidth
)
1156 maxwidth
= bmn
->bmn_Width
;
1157 if (bmn
->bmn_Height
> maxheight
)
1158 maxheight
= bmn
->bmn_Height
;
1160 if (!(bmn
->bmn_SaveBitMap
=
1161 AllocBitMap(bmn
->bmn_Width
, bmn
->bmn_Height
, depth
,
1162 BMF_MINPLANES
, rp
->BitMap
)))
1167 bmn
= Node_Next(bmn
);
1170 if (ok
&& maxwidth
&& maxheight
)
1172 dnd
->dnd_TempBitMap
=
1173 /*NULL;// */ AllocBitMap(maxwidth
, maxheight
, depth
,
1174 BMF_MINPLANES
, rp
->BitMap
);
1178 bmn
= List_First(&dnd
->dnd_List
);
1181 if (bmn
->bmn_SaveBitMap
)
1183 FreeBitMap(bmn
->bmn_SaveBitMap
);
1184 bmn
->bmn_SaveBitMap
= NULL
;
1186 bmn
= Node_Next(bmn
);
1191 //-------------------------------------
1192 VOID
FinishDragNDrop(struct DragNDrop
*dnd
)
1194 struct BitMapNode
*bmn
;
1195 if (dnd
->dnd_TempBitMap
)
1196 FreeBitMap(dnd
->dnd_TempBitMap
);
1198 bmn
= List_First(&dnd
->dnd_List
);
1201 if (bmn
->bmn_SaveBitMap
)
1203 FreeBitMap(bmn
->bmn_SaveBitMap
);
1204 bmn
->bmn_SaveBitMap
= NULL
;
1206 bmn
= Node_Next(bmn
);
1210 //-------------------------------------
1212 /**********************************************************************
1213 Varargs function of CreateBitMapNode(). Note that we need a dummy
1214 because we need at least one parameter
1215 **********************************************************************/
1216 struct BitMapNode
*VARARGS68K
CreateBitMapNode(void *dummy
, ...)
1218 #ifndef __amigaos4__
1219 return CreateBitMapNodeA((struct TagItem
*)(((ULONG
*) & dummy
) + 1));
1222 struct TagItem
*tagList
;
1223 struct BitMapNode
*res
;
1225 va_startlinear(argptr
, dummy
);
1226 tagList
= va_getlinearva(argptr
, struct TagItem
*);
1227 res
= CreateBitMapNodeA(tagList
);
1233 /******************************************************************************/
1252 struct Library
*TimerBase
;
1255 struct MsgPort
*msgport
;
1256 struct timerequest
*iorequest
;
1257 struct Library
*timerbase
;
1261 //-------------------------------------
1262 ASM VOID
TIMER_DeleteTimer(register __a0 APTR t
)
1266 struct TimerStruct
*timer
= (struct TimerStruct
*)t
;
1269 if (timer
->timerbase
)
1273 // printf("Test1\n");
1274 AbortIO((struct IORequest
*)timer
->iorequest
);
1275 // printf("Test2\n");
1276 WaitIO((struct IORequest
*)timer
->iorequest
);
1279 CloseDevice((struct IORequest
*)timer
->iorequest
);
1281 if (timer
->iorequest
)
1282 DeleteIORequest(timer
->iorequest
);
1284 DeleteMsgPort(timer
->msgport
);
1289 //-------------------------------------
1290 ASM APTR
TIMER_CreateTimer()
1292 struct TimerStruct
*timer
=
1293 (struct TimerStruct
*)AllocVec(sizeof(struct TimerStruct
), 0x10000);
1296 if ((timer
->msgport
= CreateMsgPort()))
1298 if ((timer
->iorequest
=
1299 (struct timerequest
*)CreateIORequest(timer
->msgport
,
1300 sizeof(struct timerequest
))))
1302 if (!OpenDevice(TIMERNAME
, UNIT_VBLANK
,
1303 (struct IORequest
*)timer
->iorequest
, NULL
))
1306 /*TimerBase = */ timer
->timerbase
=
1307 (struct Library
*)timer
->iorequest
->tr_node
.
1311 (struct Library
*)timer
->iorequest
->tr_node
.
1318 TIMER_DeleteTimer(timer
);
1322 //-------------------------------------
1323 ASM
struct MsgPort
*TIMER_GetMsgPort(register __a0 APTR t
)
1327 return ((struct TimerStruct
*)t
)->msgport
;
1329 //-------------------------------------
1330 ASM ULONG
TIMER_GetSigMask(register __a0 APTR t
)
1334 return (1UL << (((struct TimerStruct
*)t
)->msgport
->mp_SigBit
));
1336 //-------------------------------------
1337 ASM APTR
TIMER_StartTimer(register __a0 APTR t
, register __d0 ULONG secs
,
1338 register __d1 ULONG mics
)
1340 struct TimerStruct
*timer
;
1341 struct timerequest
*req
;
1346 timer
= (struct TimerStruct
*)t
;
1350 req
= timer
->iorequest
;
1351 req
->tr_node
.io_Command
= TR_ADDREQUEST
;
1352 req
->tr_time
.tv_secs
= secs
;
1353 req
->tr_time
.tv_micro
= mics
;
1355 SendIO((struct IORequest
*)req
);
1358 //-------------------------------------
1359 ASM VOID
TIMER_StopTimer(register __a0 APTR t
)
1361 struct TimerStruct
*timer
;
1365 timer
= (struct TimerStruct
*)t
;
1368 AbortIO((struct IORequest
*)timer
->iorequest
);
1369 WaitIO((struct IORequest
*)timer
->iorequest
);
1373 //-------------------------------------
1375 //-------------------------------------
1376 struct BitMap
*CreateBitmapFromIcon(struct Screen
*scr
,
1377 struct DiskObject
*dobj
, LONG
*width
, LONG
*height
)
1379 struct Rectangle rect
;
1380 static struct TagItem rect_tags
[] = {
1381 ICONDRAWA_Borderless
, TRUE
,
1385 static struct TagItem draw_tags
[] = {
1386 ICONDRAWA_Borderless
, TRUE
,
1387 ICONDRAWA_EraseBackground
, TRUE
,
1394 if (GetIconRectangleA(NULL
, dobj
, NULL
, &rect
, rect_tags
))
1397 struct BitMap
*bmap
;
1398 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_FLAGS
) & BMF_STANDARD
)
1403 *width
= rect
.MaxX
- rect
.MinX
+ 1;
1404 *height
= rect
.MaxY
- rect
.MinY
+ 1;
1406 // cout << rect.MinY << " " << rect.MaxY << endl;
1409 AllocBitMap(*width
, *height
, 8, /*NULL,NULL);// */
1410 BMF_MINPLANES
, standard
? NULL
: scr
->RastPort
.BitMap
);
1417 DrawIconStateA(&rp
, dobj
, NULL
, 0, 0, IDS_SELECTED
, draw_tags
);
1425 //-------------------------------------
1428 struct DragNDrop
*drag
;
1430 //-------------------------------------
1434 static LONG lmx
, lmy
;
1436 WaitPort(wnd
->UserPort
);
1437 while (ready
== FALSE
)
1439 struct IntuiMessage
*imsg
;
1440 while ((imsg
= (struct IntuiMessage
*)GetMsg(wnd
->UserPort
)))
1442 ULONG cl
= imsg
->Class
;
1443 UWORD code
= imsg
->Code
;
1444 // LONG mx = imsg->MouseX;
1445 // LONG my = imsg->MouseY;
1447 ReplyMsg((struct Message
*)imsg
);
1451 case IDCMP_CLOSEWINDOW
:
1455 case IDCMP_VANILLAKEY
:
1457 DrawDragNDrop(drag
, wnd
->WScreen
->MouseX
,
1458 wnd
->WScreen
->MouseY
);
1459 lmx
= wnd
->WScreen
->MouseX
;
1460 lmy
= wnd
->WScreen
->MouseY
;
1464 case IDCMP_MOUSEBUTTONS
:
1465 if (code
== SELECTDOWN
)
1467 DrawDragNDrop(drag
, wnd
->WScreen
->MouseX
,
1468 wnd
->WScreen
->MouseY
);
1469 lmx
= wnd
->WScreen
->MouseX
;
1470 lmy
= wnd
->WScreen
->MouseY
;
1474 case IDCMP_MOUSEMOVE
:
1475 // cout << wnd->WScreen->MouseX - lmx << " " << wnd->WScreen->MouseY - lmy << endl;
1476 // WaitBOVP(&wnd->WScreen->ViewPort);
1477 DrawDragNDrop(drag
, wnd
->WScreen
->MouseX
,
1478 wnd
->WScreen
->MouseY
);
1484 //-------------------------------------
1486 UBYTE fullmask
[8192];
1491 for (i
= 0; i
< 8192; i
++)
1494 wnd
= OpenWindowTags(NULL
,
1496 WA_InnerHeight
, 200,
1498 IDCMP_CLOSEWINDOW
| IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
|
1499 IDCMP_MOUSEBUTTONS
| IDCMP_VANILLAKEY
, WA_DragBar
, TRUE
,
1500 WA_DepthGadget
, TRUE
, WA_CloseGadget
, TRUE
, WA_ReportMouse
, TRUE
,
1501 WA_Activate
, TRUE
, WA_GimmeZeroZero
, TRUE
, WA_MouseQueue
, 2,
1506 struct DiskObject
*obj1
= GetIconTags("SYS:Prefs",
1507 ICONGETA_GenerateImageMasks
, TRUE
,
1509 struct DiskObject
*obj2
= GetIconTags("SYS:Picasso96",
1510 ICONGETA_GenerateImageMasks
, TRUE
,
1512 struct DiskObject
*obj3
= GetIconTags("SYS:Tools",
1513 ICONGETA_GenerateImageMasks
, TRUE
,
1516 struct BitMap
*bmap1
=
1517 CreateBitmapFromIcon(wnd
->WScreen
, obj1
, &width
, &height
);
1518 struct BitMap
*bmap2
=
1519 CreateBitmapFromIcon(wnd
->WScreen
, obj2
, &width
, &height
);
1520 struct BitMap
*bmap3
=
1521 CreateBitmapFromIcon(wnd
->WScreen
, obj3
, &width
, &height
);
1522 if (bmap1
&& bmap2
&& bmap3
)
1524 APTR mask1
, mask2
, mask3
;
1525 IconControl(obj1
, ICONCTRLA_GetImageMask1
, &mask1
, TAG_DONE
);
1526 IconControl(obj2
, ICONCTRLA_GetImageMask1
, &mask2
, TAG_DONE
);
1527 IconControl(obj3
, ICONCTRLA_GetImageMask1
, &mask3
, TAG_DONE
);
1528 if ((drag
= CreateDragNDropA(NULL
)))
1530 struct BitMapNode
*bmn1
=
1531 CreateBitMapNode(GUI_BitMap
, bmap1
,
1536 GUI_LeftOffset
, -35,
1539 struct BitMapNode
*bmn2
=
1540 CreateBitMapNode(GUI_BitMap
, bmap2
,
1547 struct BitMapNode
*bmn3
=
1548 CreateBitMapNode(GUI_BitMap
, bmap3
,
1556 struct BitMapNode
*bmn4
=
1557 CreateBitMapNode(GUI_BitMap
, bmap1
,
1564 struct BitMapNode
*bmn5
=
1565 CreateBitMapNode(GUI_BitMap
, bmap2
,
1573 struct BitMapNode
*bmn6
=
1574 CreateBitMapNode(GUI_BitMap
, bmap3
,
1578 GUI_LeftOffset
, 100,
1582 if (bmn1
&& bmn2
&& bmn3
&& bmn4
&& bmn5
&& bmn6
)
1584 AttachBitMapNode(drag
, bmn1
);
1585 AttachBitMapNode(drag
, bmn2
);
1586 AttachBitMapNode(drag
, bmn3
);
1587 AttachBitMapNode(drag
, bmn4
);
1588 AttachBitMapNode(drag
, bmn5
);
1589 AttachBitMapNode(drag
, bmn6
);
1590 PrepareDragNDrop(drag
, wnd
->WScreen
);
1592 FinishDragNDrop(drag
);
1593 DetachBitMapNode(bmn6
);
1594 DetachBitMapNode(bmn5
);
1595 DetachBitMapNode(bmn4
);
1596 DetachBitMapNode(bmn3
);
1597 DetachBitMapNode(bmn2
);
1598 DetachBitMapNode(bmn1
);
1601 DeleteBitMapNode(bmn6
);
1603 DeleteBitMapNode(bmn5
);
1605 DeleteBitMapNode(bmn4
);
1607 DeleteBitMapNode(bmn3
);
1609 DeleteBitMapNode(bmn2
);
1611 DeleteBitMapNode(bmn1
);
1612 DeleteDragNDrop(drag
);
1624 FreeDiskObject(obj3
);
1626 FreeDiskObject(obj2
);
1628 FreeDiskObject(obj1
);
1633 //-------------------------------------