Initial import of Scalos. To decrease size I have
[AROS-Contrib.git] / scalos / main / DragDropBobs.c
blobf833834e399c9d5a00aa93780847313a37aae62f
1 // DragDropBobs.c
2 // $Date$
3 // $Revision$
6 #include <exec/types.h>
7 #include <graphics/gels.h>
8 #include <graphics/rastport.h>
9 #include <graphics/gfxmacros.h>
10 #include <hardware/blit.h>
11 #include <intuition/classes.h>
12 #include <intuition/classusr.h>
13 #include <utility/hooks.h>
14 #include <intuition/gadgetclass.h>
15 #include <workbench/workbench.h>
16 #include <workbench/startup.h>
17 #include <cybergraphx/cybergraphics.h>
18 #include <dos/dostags.h>
20 #define __USE_SYSBASE
22 #include <proto/dos.h>
23 #include <proto/exec.h>
24 #include <proto/layers.h>
25 #include <proto/graphics.h>
26 #include <proto/intuition.h>
27 #include <proto/cybergraphics.h>
28 #include <proto/iconobject.h>
29 #include "debug.h"
30 #include <proto/scalos.h>
32 #include <clib/alib_protos.h>
34 #include <defs.h>
35 #include <datatypes/iconobject.h>
36 #include <scalos/scalos.h>
37 #include <scalos/scalosprefs.h>
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <string.h>
43 #include "scalos_structures.h"
44 #include "locale.h"
45 #include "functions.h"
46 #include "Variables.h"
49 //----------------------------------------------------------------------------
51 #define NO_BOB_POSITION 0x8000
53 #define PATH_POINTER_ICONS "THEME:PointerIcons/"
54 #define PATH_POINTER_ICONS_FALLBACK "ENV:Scalos/"
56 #define NAME_FORBIDDEN PATH_POINTER_ICONS "forbidden"
57 #define NAME_COPYING PATH_POINTER_ICONS "copying"
58 #define NAME_MAKELINK PATH_POINTER_ICONS "makelink"
59 #define NAME_MOVING PATH_POINTER_ICONS "moving"
61 #define NAME_FORBIDDEN_FALLBACK PATH_POINTER_ICONS_FALLBACK "forbidden"
62 #define NAME_COPYING_FALLBACK PATH_POINTER_ICONS_FALLBACK "copying"
63 #define NAME_MAKELINK_FALLBACK PATH_POINTER_ICONS_FALLBACK "makelink"
64 #define NAME_MOVING_FALLBACK PATH_POINTER_ICONS_FALLBACK "moving"
66 //----------------------------------------------------------------------------
68 // local functions
70 static void AppendDragNode(struct internalScaWindowTask *iwt, struct RastPort *rp,
71 struct ScaIconNode *in, LONG n, LONG x, LONG y, LONG x0, LONG y0);
72 static struct ScaBob *InitDrag_ImageOnly(struct DragNode *dgn,
73 struct ScaBob **BobList,
74 struct RastPort *rp, struct internalScaWindowTask *iwt,
75 LONG x0, LONG y0);
76 static void InitDrag_ImageAndText(struct DragNode *dgn,
77 struct ScaBob **BobList,
78 struct RastPort *rp, struct internalScaWindowTask *iwt,
79 LONG x0, LONG y0);
80 static struct ScaBob *internalAddBob(struct DragHandle *dh,
81 struct ScaBob **BobList,
82 struct BitMap *bm, APTR Mask, const UBYTE *AlphaChannel,
83 ULONG Width, ULONG Height,
84 ULONG BoundsWidth, ULONG BoundsHeight,
85 WORD LeftBorder,
86 LONG XOffset, LONG YOffset);
87 static void DrawIconListShadows(struct internalScaWindowTask *iwt, struct ScaIconNode **IconList);
88 static void FreeBobNode(struct ScalosNodeList *nodeList, struct ScaBob *bob);
89 static void RemoveCustomBobsFromScreen(struct ScaBob **BobList);
90 static void FreeCustomBobNode(struct ScalosNodeList *nodeList, struct ScaBob *bob);
91 static struct ScaBob *sca_AddBobCustom(struct DragHandle *dh,
92 struct ScaBob **BobList,
93 struct BitMap *bm, APTR Mask, const UBYTE *AlphaChannel,
94 ULONG Width, ULONG Height,
95 ULONG BoundsWidth, ULONG BoundsHeight,
96 WORD LeftBorder,
97 LONG XOffset, LONG YOffset);
98 static void BlitBob(struct ScaBob *bob, struct BitMap *bmSrc, struct BitMap *bmDest);
99 static LONG CompareLeftUpFunc(const struct ScaBob *bob1, const struct ScaBob *bob2);
100 static void sca_DrawDragCustom(struct DragHandle *dh, LONG x, LONG y, ULONG Flags);
101 static void RestoreBuffer(struct DragHandle *dh,
102 struct BitMap *DestBM,
103 LONG x, LONG y, LONG Width, LONG Height);
104 static void RestoreBuffer2(struct DragHandle *dh,
105 struct BitMap *DestBM,
106 LONG x, LONG y, LONG Width, LONG Height);
107 static BOOL ClipBlitIn(struct Screen *Scr, struct BitMap *DestBM,
108 LONG SrcX, LONG SrcY, LONG Width, LONG Height);
109 static BOOL ClipBlitOut(struct Screen *Scr, struct BitMap *SrcBM,
110 LONG DstX, LONG DstY, LONG Width, LONG Height);
111 static void BlitBob2(struct DragHandle *dh,
112 struct ScaBob *bob, struct BitMap *bm,
113 LONG SrcX, LONG SrcY, LONG DestX, LONG DestY,
114 LONG Width, LONG Height);
115 static void BlitTrans(struct DragHandle *dh,
116 const struct ScaBob *bob, struct BitMap *SrcBM,
117 LONG SrcX, LONG SrcY, LONG DestX, LONG DestY,
118 LONG Width, LONG Height, const struct BitMap *MaskBM);
119 static void OptimizeBobs(struct DragHandle *dh);
120 static void MergeBobs(struct RastPort *TempRp, struct DragHandle *dh,
121 struct ScaBob **NewBobList, struct ScaBob *NewBob);
122 static void MergeBobsAlpha(struct RastPort *TempRp, struct DragHandle *dh,
123 struct ScaBob **NewBobList, struct ScaBob *NewBob);
124 static void SwapLong(LONG *x1, LONG *x2);
125 static void FreeBobList(struct DragHandle *dh);
126 static void FreeCustomBobList(struct ScaBob **BobList);
127 static struct ScaBob *AllocBob2(struct DragHandle *dh, struct ScalosNodeList *BobList,
128 LONG x, LONG y, LONG Width, LONG Height, LONG BoundsWidth, LONG BoundsHeight);
129 static BOOL IsBobPosition(WORD x);
130 static void FreeSpeedBitMapAlloc(struct DragHandle *dh);
131 static BOOL AddSpecialIcon(struct internalScaWindowTask *iwt, struct RastPort *rp,
132 CONST_STRPTR IconFileName, struct ScaBob **BobPtr);
133 static BOOL AppendSpecialDragNode(struct DragHandle *dh,
134 struct internalScaWindowTask *iwt, struct RastPort *rp,
135 struct ScaIconNode *in, struct ScaBob **BobPtr);
136 static void CheckSpecialBobCustom(struct DragHandle *dh, ULONG Flags,
137 ULONG MaskBit, struct ScaBob **bob, CONST_STRPTR FirstName, CONST_STRPTR FallbackName);
138 static void CheckSpecialBob(struct DragHandle *dh, ULONG Flags,
139 ULONG MaskBit, struct ScaBob **bob, CONST_STRPTR FirstName, CONST_STRPTR FallbackName);
140 static BOOL AddInfoTextBob(struct internalScaWindowTask *iwt);
141 static void CountDragObjects(struct DragHandle *drgh, const struct ScaIconNode *in);
142 static void BlitARGBMaskAlpha(ULONG SrcWidth, ULONG SrcHeight,
143 const struct ARGB *Src, LONG SrcLeft, LONG SrcTop,
144 ULONG DestWidth, struct ARGB *Dest, LONG DestLeft, LONG DestTop,
145 const struct BitMap *MaskBM, ULONG Trans,
146 const UBYTE *Alpha, LONG AlphaLeft, ULONG AlphaWidth);
147 //static void DumpBitMap(struct BitMap *bm);
149 //----------------------------------------------------------------------------
151 // local data
153 static struct Hook CompareLeftUpHook =
155 { NULL, NULL },
156 HOOKFUNC_DEF(CompareLeftUpFunc), // h_Entry + h_SubEntry
157 NULL, // h_Data
160 //----------------------------------------------------------------------------
163 void InitDrag(struct IntuiMessage *iMsg, struct internalScaWindowTask *iwt)
165 struct ExtGadget *mgg = (struct ExtGadget *) iwt->iwt_LastIcon; // Icon directly under mouse
166 struct ScaIconNode *in;
167 struct RastPort rp;
168 LONG x, y;
169 LONG x0 = 0, y0 = 0; // Left/Top Edge of icon directly under mouse
170 LONG n;
172 iwt->iwt_WinUnderPtr = NULL; // +jl+ 20010405
173 iwt->iwt_IconUnderPtr = NULL;
174 iwt->iwt_ObjectUnderMouse = OUM_nothing;
176 iwt->iwt_RemIconsFlag = FALSE;
178 iwt->iwt_StartDragMouseX = iMsg->MouseX;
179 iwt->iwt_StartDragMouseY = iMsg->MouseY;
181 x = iwt->iwt_InnerLeft - iwt->iwt_WindowTask.wt_XOffset - iMsg->MouseX;
182 y = iwt->iwt_InnerTop - iwt->iwt_WindowTask.wt_YOffset - iMsg->MouseY;
184 switch (CurrentPrefs.pref_DragType)
186 case DRAGTYPE_ImageOnly:
187 x0 = x + mgg->LeftEdge;
188 y0 = y + mgg->TopEdge;
189 break;
191 case DRAGTYPE_ImageAndText:
192 x0 = x + mgg->BoundsLeftEdge;
193 y0 = y + mgg->BoundsTopEdge;
194 break;
197 d1(KPrintF("%s/%s/%ld: x=%ld y=%ld MouseX=%ld MouseY=%ld\n", __FILE__, __FUNC__, __LINE__, x, y, iMsg->MouseX, iMsg->MouseY));
199 Scalos_InitRastPort(&rp);
200 Scalos_SetFont(&rp, iwt->iwt_IconFont, &iwt->iwt_IconTTFont);
201 SetABPenDrMd(&rp, FontPrefs.fprf_FontFrontPen, FontPrefs.fprf_FontBackPen, FontPrefs.fprf_TextDrawModeSel);
203 SCA_FreeAllNodes((struct ScalosNodeList *) &iwt->iwt_DragNodeList);
205 iwt->iwt_myDragHandle = SCA_InitDrag(iwt->iwt_WinScreen);
206 if (NULL == iwt->iwt_myDragHandle)
207 return;
209 iwt->iwt_myDragHandle->drgh_iwt = iwt;
211 iwt->iwt_IconListDDLocked = TRUE;
212 ScalosLockIconListExclusive(iwt);
214 iwt->iwt_myDragHandle->drgh_FileCount = 0;
215 iwt->iwt_myDragHandle->drgh_DrawerCount = 0;
216 iwt->iwt_myDragHandle->drgh_DeviceCount = 0;
218 ScalosObtainSemaphore(&iwt->iwt_myDragHandle->drgh_BobListSemaphore);
220 if (CurrentPrefs.pref_UseOldDragIcons)
222 for (in=iwt->iwt_WindowTask.wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
224 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
226 if (gg->Flags & GFLG_SELECTED)
228 // count devices, drawers and files
229 CountDragObjects(iwt->iwt_myDragHandle, in);
231 switch (CurrentPrefs.pref_DragType)
233 case DRAGTYPE_ImageOnly:
234 x0 = x + gg->LeftEdge;
235 y0 = y + gg->TopEdge;
236 break;
238 case DRAGTYPE_ImageAndText:
239 x0 = x + gg->BoundsLeftEdge;
240 y0 = y + gg->BoundsTopEdge;
241 break;
244 AppendDragNode(iwt, &rp, in, 0, x, y, x0, y0);
245 ClassSelectIcon(iwt->iwt_WindowTask.mt_WindowStruct, in, FALSE);
249 else
251 // add every selected icon except icon under mouse
252 for (n=1, in=iwt->iwt_WindowTask.wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
254 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
256 if (gg != mgg && (gg->Flags & GFLG_SELECTED))
258 // count devices, drawers and files
259 CountDragObjects(iwt->iwt_myDragHandle, in);
261 AppendDragNode(iwt, &rp, in, n, x, y, x0 + 5 * n, y0 - 5 * n);
262 ClassSelectIcon(iwt->iwt_WindowTask.mt_WindowStruct, in, FALSE);
263 n++;
267 // Finally, add icon under mouse
268 // so that it is being drawn on top of the bob stack
269 for (in=iwt->iwt_WindowTask.wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
271 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
273 if (gg == mgg)
275 // count devices, drawers and files
276 CountDragObjects(iwt->iwt_myDragHandle, in);
278 AppendDragNode(iwt, &rp, in, 0, x, y, x0, y0);
279 ClassSelectIcon(iwt->iwt_WindowTask.mt_WindowStruct, in, FALSE);
280 break;
285 ScalosUnLockIconList(iwt);
287 if (CurrentPrefs.pref_ShowDDCountText)
288 AddInfoTextBob(iwt);
290 ScalosReleaseSemaphore(&iwt->iwt_myDragHandle->drgh_BobListSemaphore);
292 if (NULL == iwt->iwt_DragNodeList)
294 SCA_EndDrag(iwt->iwt_myDragHandle);
295 iwt->iwt_myDragHandle = NULL;
297 EndDragUnlock(iwt);
300 UpdateIconCount(iwt);
302 Scalos_DoneRastPort(&rp);
306 static void AppendDragNode(struct internalScaWindowTask *iwt, struct RastPort *rp,
307 struct ScaIconNode *in, LONG n, LONG x, LONG y, LONG x0, LONG y0)
309 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
310 struct DragNode *dgn = (struct DragNode *) SCA_AllocStdNode((struct ScalosNodeList *) &iwt->iwt_DragNodeList, NTYP_DragNode);
312 d1(KPrintF("%s/%s/%ld: DragNode=%08lx\n", __FILE__, __FUNC__, __LINE__, dgn));
313 d1(KPrintF("%s/%s/%ld: x=%ld y=%ld x0=%ld y0=%ld\n", __FILE__, __FUNC__, __LINE__, x, y, x0, y0));
315 if (dgn)
317 dgn->drgn_iconnode = in;
318 dgn->drgn_icon = in->in_Icon;
320 dgn->drgn_x = x + gg->LeftEdge;
321 dgn->drgn_y = y + gg->TopEdge;
323 dgn->drgn_DeltaX = -x0;
324 dgn->drgn_DeltaY = -y0;
326 if (n < 3)
328 if (in->in_Flags & INF_TextIcon)
330 InitDrag_ImageOnly(dgn, &iwt->iwt_myDragHandle->drgh_boblist, rp, iwt, x0, y0);
332 else
334 switch (CurrentPrefs.pref_DragType)
336 case DRAGTYPE_ImageOnly:
337 InitDrag_ImageOnly(dgn, &iwt->iwt_myDragHandle->drgh_boblist, rp, iwt, x0, y0);
338 break;
339 case DRAGTYPE_ImageAndText:
340 InitDrag_ImageAndText(dgn, &iwt->iwt_myDragHandle->drgh_boblist, rp, iwt, x0, y0);
341 break;
349 static struct ScaBob *InitDrag_ImageOnly(struct DragNode *dgn,
350 struct ScaBob **BobList,
351 struct RastPort *rp, struct internalScaWindowTask *iwt,
352 LONG x0, LONG y0)
354 struct ScaIconNode *in = dgn->drgn_iconnode;
355 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
356 struct ScaBob *bob;
357 WORD Width, Height;
358 WORD ggWidth;
359 struct BitMap *MaskBMSelected = NULL;
360 struct BitMap *MaskBM = NULL;
361 PLANEPTR MaskPlane = NULL;
362 const UBYTE *AlphaChannel = NULL;
363 LONG LeftSpace, TopSpace, RightSpace, BottomSpace;
365 LeftSpace = TopSpace = RightSpace = BottomSpace = 0;
367 if (in->in_Flags & INF_TextIcon)
369 Width = ggWidth = iwt->iwt_WidthArray[WIDTHARRAY_NAME];
370 d1(KPrintF("%s/%s/%ld: Width=%0ld\n", __FILE__, __FUNC__, __LINE__, Width));
372 else
374 ggWidth = gg->Width;
375 Width = gg->Width - LeftSpace - RightSpace;
378 Height = gg->Height - TopSpace - BottomSpace;
380 rp->BitMap = AllocBitMap(ggWidth, gg->Height,
381 GetBitMapAttr(iwt->iwt_WinScreen->RastPort.BitMap, BMA_DEPTH),
382 BMF_CLEAR | BMF_DISPLAYABLE | BMF_MINPLANES,
383 iwt->iwt_WinScreen->RastPort.BitMap);
384 if (NULL == rp->BitMap)
385 return NULL;
387 DoMethod(in->in_Icon, IDTM_Draw, iwt->iwt_WinScreen,
388 NULL, rp, iwt->iwt_WinDrawInfo,
389 0, 0,
390 IODRAWF_AbsolutePos | IODRAWF_NoText | IODRAWF_NoAlpha);
392 GetAttr((gg->Flags & GFLG_SELECTED) ? IDTA_MaskBM_Selected : IDTA_MaskBM_Normal,
393 in->in_Icon, (APTR) &MaskBMSelected);
395 d1(KPrintF("%s/%s/%ld: MaskBMSelected=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskBMSelected));
396 d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, gg->Width, gg->Height));
398 if (MaskBMSelected)
400 // adapt size of mask plane (Width,Height) to icon size (ggWidth,gg->Height)
402 MaskBM = AllocBitMap(ggWidth, gg->Height, 1, BMF_MINPLANES | BMF_CLEAR, NULL);
404 if (MaskBM)
406 d1(KPrintF("%s/%s/%ld: Mask=%08lx x=%ld y=%ld xb=%ld yb=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, MaskBMSelected, \
407 gg->LeftEdge, gg->TopEdge, \
408 gg->BoundsLeftEdge, gg->BoundsTopEdge,
409 Width, Height));
411 d1(DumpBitMap(MaskBMSelected));
413 BltBitMap(MaskBMSelected,
414 0, 0,
415 MaskBM,
416 LeftSpace, TopSpace,
417 Width, Height,
418 ABC | ABNC, ~0, NULL);
420 d1(DumpBitMap(MaskBM));
421 #if 0
423 struct RastPort rp;
425 InitRastPort(&rp);
426 rp.BitMap = MaskBM;
427 SetRast(&rp, 1);
429 #endif
430 MaskPlane = MaskBM->Planes[0];
432 d1(KPrintF("%s/%s/%ld: MaskPlane: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
433 __FILE__, __FUNC__, __LINE__, MaskPlane[0], MaskPlane[1], MaskPlane[2], MaskPlane[3],\
434 MaskPlane[4], MaskPlane[5], MaskPlane[6], MaskPlane[7]); \
435 kprintf("%s/%s/%ld: MaskPlane: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
436 __FILE__, __FUNC__, __LINE__, MaskPlane[8], MaskPlane[9], MaskPlane[10], MaskPlane[11], \
437 MaskPlane[12], MaskPlane[13], MaskPlane[14], MaskPlane[15]));
441 GetAttr(IDTA_AlphaChannel, in->in_Icon, (APTR) &AlphaChannel);
443 d1(if (AlphaChannel)\
445 kprintf("%s/%s/%ld: AlphaChannel: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
446 __FILE__, __FUNC__, __LINE__, AlphaChannel[0], AlphaChannel[1], AlphaChannel[2], AlphaChannel[3],\
447 AlphaChannel[4], AlphaChannel[5], AlphaChannel[6], AlphaChannel[7]);\
448 kprintf("%s/%s/%ld: AlphaChannel: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
449 __FILE__, __FUNC__, __LINE__, AlphaChannel[8], AlphaChannel[9], AlphaChannel[10], AlphaChannel[11],\
450 AlphaChannel[12], AlphaChannel[13], AlphaChannel[14], AlphaChannel[15]);\
451 kprintf("%s/%s/%ld: AlphaChannel: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
452 __FILE__, __FUNC__, __LINE__, AlphaChannel[16], AlphaChannel[17], AlphaChannel[18], AlphaChannel[19],\
453 AlphaChannel[20], AlphaChannel[21], AlphaChannel[22], AlphaChannel[23]);\
454 kprintf("%s/%s/%ld: AlphaChannel: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
455 __FILE__, __FUNC__, __LINE__, AlphaChannel[24], AlphaChannel[25], AlphaChannel[26], AlphaChannel[27],\
456 AlphaChannel[28], AlphaChannel[29], AlphaChannel[30], AlphaChannel[31]);\
459 bob = internalAddBob(iwt->iwt_myDragHandle,
460 BobList,
461 rp->BitMap, MaskPlane, AlphaChannel,
462 ggWidth, gg->Height,
463 gg->BoundsWidth, gg->BoundsHeight,
464 gg->LeftEdge - gg->BoundsLeftEdge,
465 x0, y0
468 if (MaskBM)
469 FreeBitMap(MaskBM);
471 FreeBitMap(rp->BitMap);
473 return bob;
477 static void InitDrag_ImageAndText(struct DragNode *dgn,
478 struct ScaBob **BobList,
479 struct RastPort *rp, struct internalScaWindowTask *iwt,
480 LONG x0, LONG y0)
482 struct ScaIconNode *in = dgn->drgn_iconnode;
483 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
484 const UBYTE *AlphaChannel = NULL;
485 struct BitMap *allocBM;
486 struct BitMap *MaskBM;
488 rp->BitMap = allocBM = AllocBitMap(gg->BoundsWidth, gg->BoundsHeight,
489 GetBitMapAttr(iwt->iwt_WinScreen->RastPort.BitMap, BMA_DEPTH),
490 BMF_CLEAR | BMF_DISPLAYABLE | BMF_MINPLANES,
491 iwt->iwt_WinScreen->RastPort.BitMap);
492 if (NULL == rp->BitMap)
493 return;
495 DoMethod(in->in_Icon, IDTM_Draw, iwt->iwt_WinScreen,
496 NULL, rp, iwt->iwt_WinDrawInfo,
497 0, 0, IODRAWF_AbsolutePos | IODRAWF_NoAlpha);
499 GetAttr(IDTA_AlphaChannel, in->in_Icon, (APTR) &AlphaChannel);
501 MaskBM = AllocBitMap(gg->BoundsWidth, gg->BoundsHeight, 1, BMF_CLEAR, NULL);
502 rp->BitMap = MaskBM;
503 if (MaskBM)
505 struct BitMap *MaskBMSelected = NULL;
507 SetAPen(rp, 1);
508 SetBPen(rp, 1);
510 GetAttr((gg->Flags & GFLG_SELECTED) ? IDTA_MaskBM_Selected : IDTA_MaskBM_Normal,
511 in->in_Icon, (APTR) &MaskBMSelected);
513 d1(kprintf("%s/%s/%ld: Mask=%08lx x=%ld y=%ld xb=%ld yb=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, MaskBMSelected, \
514 gg->LeftEdge, gg->TopEdge, \
515 gg->BoundsLeftEdge, gg->BoundsTopEdge,
516 gg->Width, gg->Height));
518 if (MaskBMSelected)
520 LONG LeftSpace, TopSpace, RightSpace, BottomSpace;
521 WORD Width, Height;
523 LeftSpace = TopSpace = RightSpace = BottomSpace = 0;
525 Width = gg->Width - LeftSpace - RightSpace;
526 Height = gg->Height - TopSpace - BottomSpace;
528 BltBitMap(MaskBMSelected, 0, 0, MaskBM,
529 gg->LeftEdge - gg->BoundsLeftEdge + LeftSpace,
530 gg->TopEdge - gg->BoundsTopEdge + TopSpace,
531 Width, Height,
532 ABC | ABNC, ~0, NULL);
534 else
536 d1(kprintf("%s/%s/%ld: x1=%ld y1=%ld x2=%ld y2=%ld\n", __FILE__, __FUNC__, __LINE__, \
537 gg->LeftEdge - gg->BoundsLeftEdge,\
538 gg->TopEdge - gg->BoundsTopEdge,\
539 gg->Width - 1, gg->Height - 1));
541 RectFill(rp, gg->LeftEdge - gg->BoundsLeftEdge,
542 gg->TopEdge - gg->BoundsTopEdge,
543 gg->LeftEdge - gg->BoundsLeftEdge + gg->Width - 1,
544 gg->TopEdge - gg->BoundsTopEdge + gg->Height - 1);
546 // .maskok2:
547 SetAttrs(in->in_Icon,
548 IDTA_TextPen, 1,
549 IDTA_TextPenSel, 1,
550 IDTA_TextPenShadow, 1,
551 IDTA_TextPenOutline, 1,
552 IDTA_TextDrawMode, JAM1,
553 TAG_END);
555 // add icon text to mask
556 DoMethod(in->in_Icon, IDTM_Draw, iwt->iwt_WinScreen,
557 NULL, rp, iwt->iwt_WinDrawInfo, 0, 0,
558 IODRAWF_NoImage | IODRAWF_AbsolutePos | IODRAWF_NoAlpha);
560 // restore original settings
561 SetAttrs(in->in_Icon,
562 IDTA_TextPen, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPEN],
563 IDTA_TextPenSel, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPENSEL],
564 IDTA_TextPenShadow, PalettePrefs.pal_PensList[PENIDX_ICONTEXTSHADOWPEN],
565 IDTA_TextPenOutline, PalettePrefs.pal_PensList[PENIDX_ICONTEXTOUTLINEPEN],
566 IDTA_TextDrawMode, FontPrefs.fprf_TextDrawMode,
567 TAG_END);
569 SetABPenDrMd(rp, FontPrefs.fprf_FontFrontPen, FontPrefs.fprf_FontBackPen, FontPrefs.fprf_TextDrawModeSel);
572 // .maskok:
573 internalAddBob(iwt->iwt_myDragHandle, BobList,
574 allocBM, rp->BitMap->Planes[0], AlphaChannel,
575 gg->BoundsWidth, gg->BoundsHeight,
576 gg->BoundsWidth, gg->BoundsHeight,
578 x0, y0
581 if (MaskBM)
582 FreeBitMap(MaskBM);
583 FreeBitMap(allocBM);
587 void RestoreDragIcons(struct internalScaWindowTask *iwt)
589 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
591 if (IsIwtViewByIcon(iwt) && CurrentPrefs.pref_AutoRemoveFlag && iwt->iwt_RemIconsFlag && iwt->iwt_DragIconList)
593 struct ScaIconNode *FirstIcon = iwt->iwt_DragIconList;
595 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
597 while (iwt->iwt_DragIconList)
599 d1(kprintf("%s/%s/%ld: Icon=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_DragIconList, GetIconName(iwt->iwt_DragIconList)));
601 SCA_MoveIconNode(&iwt->iwt_DragIconList, &iwt->iwt_WindowTask.wt_IconList, iwt->iwt_DragIconList);
604 RefreshIconList(iwt, FirstIcon, NULL);
606 iwt->iwt_RemIconsFlag = FALSE;
610 void DrawDrag(ULONG DrawFlags, struct internalScaWindowTask *iwt)
612 d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
614 if (IsIwtViewByIcon(iwt) && CurrentPrefs.pref_AutoRemoveFlag && !iwt->iwt_RemIconsFlag)
616 struct DragNode *dn;
618 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
620 for (dn = iwt->iwt_DragNodeList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
622 d1(kprintf("%s/%s/%ld: Icon=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, dn->drgn_iconnode, GetIconName(dn->drgn_iconnode)));
624 SCA_MoveIconNode(&iwt->iwt_WindowTask.wt_IconList, &iwt->iwt_DragIconList, dn->drgn_iconnode);
627 ScalosObtainSemaphore(&iwt->iwt_UpdateSemaphore);
629 RemoveIcons(iwt, &iwt->iwt_DragIconList);
630 DrawIconListShadows(iwt, &iwt->iwt_DragIconList);
632 ScalosReleaseSemaphore(&iwt->iwt_UpdateSemaphore);
634 iwt->iwt_RemIconsFlag = TRUE;
637 if (!(DrawFlags & SCAF_Drag_NoDrawDrag))
639 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
640 SCA_DrawDrag(iwt->iwt_myDragHandle, iwt->iwt_WinScreen->MouseX,
641 iwt->iwt_WinScreen->MouseY, DrawFlags & ~SCAF_Drag_NoDrawDrag);
644 d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
648 static void DrawIconListShadows(struct internalScaWindowTask *iwt, struct ScaIconNode **IconList)
650 struct ScaIconNode *in;
651 ULONG ScreenDepth;
652 struct RastPort rpMask;
653 struct RastPort rp;
655 d1(kprintf("\n" "%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
657 Scalos_InitRastPort(&rp);
658 Scalos_SetFont(&rp, iwt->iwt_IconFont, &iwt->iwt_IconTTFont);
660 Scalos_InitRastPort(&rpMask);
661 Scalos_SetFont(&rpMask, iwt->iwt_IconFont, &iwt->iwt_IconTTFont);
663 ScreenDepth = GetBitMapAttr(iInfos.xii_iinfos.ii_Screen->RastPort.BitMap, BMA_DEPTH);
665 iwt->iwt_IconShadowVisible = TRUE;
667 for (in = *IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
669 d1(kprintf("%s/%s/%ld: in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, in, GetIconName(in)));
670 DrawIconObjectTransparent(iwt, in->in_Icon, ScreenDepth, &rp, &rpMask,
671 CurrentPrefs.pref_IconShadowTransparency, CurrentPrefs.pref_RealTransFlag);
674 Scalos_DoneRastPort(&rpMask);
675 Scalos_DoneRastPort(&rp);
679 void DragRefreshIcons(struct internalScaWindowTask *iwt)
681 struct RastPort *rp = iwt->iwt_WindowTask.wt_Window->RPort;
682 struct DragNode *dn;
684 SetABPenDrMd(rp, FontPrefs.fprf_FontFrontPen, FontPrefs.fprf_FontBackPen, FontPrefs.fprf_TextDrawMode);
686 for (dn = iwt->iwt_DragNodeList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
688 if (dn->drgn_icon)
690 DoMethod((Object *) dn->drgn_icon,
691 IDTM_Draw, iwt->iwt_WinScreen,
692 iwt->iwt_WindowTask.wt_Window, rp,
693 iwt->iwt_WinDrawInfo,
694 iwt->iwt_InnerLeft - iwt->iwt_WindowTask.wt_XOffset,
695 iwt->iwt_InnerTop - iwt->iwt_WindowTask.wt_YOffset,
703 LIBFUNC_P8(BOOL, sca_AddBob,
704 A0, struct DragHandle *, dh,
705 A1, struct BitMap *, bm,
706 A2, APTR, Mask,
707 D0, ULONG, Width,
708 D1, ULONG, Height,
709 D2, LONG, XOffset,
710 D3, LONG, YOffset,
711 A6, struct ScalosBase *, ScalosBase)
713 (void) ScalosBase;
715 return (BOOL) (internalAddBob(dh,
716 &dh->drgh_boblist,
717 bm, Mask, NULL,
718 Width, Height,
719 Width, Height,
721 XOffset, YOffset) != NULL);
723 LIBFUNC_END
726 static struct ScaBob *internalAddBob(struct DragHandle *dh,
727 struct ScaBob **BobList,
728 struct BitMap *bm, APTR Mask, const UBYTE *AlphaChannel,
729 ULONG Width, ULONG Height,
730 ULONG BoundsWidth, ULONG BoundsHeight,
731 WORD LeftBorder,
732 LONG XOffset, LONG YOffset)
734 struct ScaBob *Result = NULL;
735 struct ScaBob *bob;
737 if (dh->drgh_flags & DRGHF_CustomBob)
739 return sca_AddBobCustom((struct DragHandle *) dh, BobList, bm,
740 Mask, AlphaChannel,
741 Width, Height,
742 BoundsWidth, BoundsHeight,
743 LeftBorder,
744 XOffset, YOffset);
747 d1(kprintf("%s/%s/%ld: x=%ld y=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, XOffset, YOffset, Width, Height));
749 do {
750 struct BitMap tempBM;
751 ULONG n, PlaneSize;
752 ULONG AllocLen;
753 UBYTE *bp;
754 UWORD Pattern, EndMask;
755 UWORD *pw1, *pw2, *pwm;
756 UWORD y, xMax;
758 bob = (struct ScaBob *) SCA_AllocNode((struct ScalosNodeList *) BobList,
759 sizeof(struct ScaBob) - sizeof(struct MinNode));
760 if (NULL == bob)
761 break;
763 bob->scbob_draghandle = dh;
764 bob->scbob_width = Width;
765 bob->scbob_height = Height;
766 bob->scbob_BoundsWidth = BoundsWidth;
767 bob->scbob_BoundsHeight = BoundsHeight;
768 bob->scbob_LeftBorder = LeftBorder;
769 bob->scbob_x = XOffset;
770 bob->scbob_y = YOffset;
771 bob->scbob_Bob.scbob_Bob1.scbob1_bob.BobVSprite = &bob->scbob_Bob.scbob_Bob1.scbob1_vsprite;
772 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.VSBob = &bob->scbob_Bob.scbob_Bob1.scbob1_bob;
774 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Width = ((Width + 15) & ~15) / 16;
775 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Height = Height;
776 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Depth = bm->Depth;
778 tempBM.BytesPerRow = ((Width + 15) & ~15) / 8;
779 tempBM.Rows = Height;
780 tempBM.Flags = 0;
781 tempBM.pad = 0;
782 tempBM.Depth = bm->Depth;
784 PlaneSize = tempBM.BytesPerRow * tempBM.Rows;
785 AllocLen = PlaneSize * bm->Depth;
787 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData = AllocVec(AllocLen,
788 MEMF_PUBLIC | ChipMemAttr() | MEMF_CLEAR);
789 if (NULL == bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData)
790 break;
792 bp = (UBYTE *) bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData;
793 for (n=0; n<8; n++)
795 if (n < bm->Depth)
797 tempBM.Planes[n] = bp;
798 bp += PlaneSize;
800 else
801 tempBM.Planes[n] = NULL;
804 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.PlanePick = ~(~0 << bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Depth);
806 BltBitMap(bm, 0, 0, &tempBM, 0, 0,
807 bob->scbob_width, bob->scbob_height,
808 ABC | ABNC, ~0, NULL);
810 bob->scbob_Bob.scbob_Bob1.scbob1_bob.SaveBuffer = AllocVec(AllocLen, MEMF_PUBLIC | ChipMemAttr());
811 if (NULL == bob->scbob_Bob.scbob_Bob1.scbob1_bob.SaveBuffer)
812 break;
814 bob->scbob_Bob.scbob_Bob1.scbob1_shadow1 = AllocVec(PlaneSize, MEMF_PUBLIC | ChipMemAttr());
815 if (NULL == bob->scbob_Bob.scbob_Bob1.scbob1_shadow1)
816 break;
818 bob->scbob_Bob.scbob_Bob1.scbob1_shadow2 = AllocVec(PlaneSize, MEMF_PUBLIC | ChipMemAttr());
819 if (NULL == bob->scbob_Bob.scbob_Bob1.scbob1_shadow2)
820 break;
822 xMax = ((bob->scbob_width + 15) & ~15) / 16;
823 Pattern = 0xaaaa;
825 pw1 = (UWORD *) bob->scbob_Bob.scbob_Bob1.scbob1_shadow1;
826 pw2 = (UWORD *) bob->scbob_Bob.scbob_Bob1.scbob1_shadow2;
827 pwm = (UWORD *) Mask;
829 d1(kprintf("%s/%s/%ld: PlaneSize=%ld Width=%ld xMax=%ld\n", __FILE__, __FUNC__, __LINE__, PlaneSize, Width, xMax));
831 EndMask = ~0 << (((bob->scbob_width + 15) & ~15) - bob->scbob_width);
833 for (y=0; y<bob->scbob_height; y++)
835 UWORD x;
837 for (x=0; x < xMax - 1; x++)
839 *pw1++ = 0xffff;
840 *pw2++ = Pattern;
842 if (Mask)
844 pw1[-1] &= *pwm;
845 pw2[-1] &= *pwm;
846 pwm++;
849 *pw1++ = EndMask;
850 *pw2 = EndMask;
851 *pw2++ &= Pattern;
853 if (Mask)
855 pw1[-1] &= *pwm;
856 pw2[-1] &= *pwm;
857 pwm++;
860 Pattern ^= 0xffff;
863 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Flags = SAVEBACK | OVERLAY;
864 bob->scbob_Bob.scbob_Bob1.scbob1_bob.ImageShadow = bob->scbob_Bob.scbob_Bob1.scbob1_shadow1;
866 // only add bobs which are to be added to drgh_boblist
867 // (e.g. do not add special bobs !!)
868 if (BobList == &dh->drgh_boblist)
869 AddBob(&bob->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort);
871 Result = bob;
872 bob = NULL;
873 } while (0);
875 if (bob)
876 FreeBobNode((struct ScalosNodeList *) BobList, bob);
878 return Result;
882 static void FreeBobNode(struct ScalosNodeList *nodeList, struct ScaBob *bob)
884 if (NULL == bob)
885 return;
887 if (bob->scbob_Bob.scbob_Bob1.scbob1_shadow1)
889 FreeVec(bob->scbob_Bob.scbob_Bob1.scbob1_shadow1);
890 bob->scbob_Bob.scbob_Bob1.scbob1_shadow1 = NULL;
892 if (bob->scbob_Bob.scbob_Bob1.scbob1_shadow2)
894 FreeVec(bob->scbob_Bob.scbob_Bob1.scbob1_shadow2);
895 bob->scbob_Bob.scbob_Bob1.scbob1_shadow2 = NULL;
897 if (bob->scbob_Bob.scbob_Bob1.scbob1_bob.SaveBuffer)
899 FreeVec(bob->scbob_Bob.scbob_Bob1.scbob1_bob.SaveBuffer);
900 bob->scbob_Bob.scbob_Bob1.scbob1_bob.SaveBuffer = NULL;
902 if (bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData)
904 FreeVec(bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData);
905 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData = NULL;
907 if (bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel
908 && (bob->scbob_Flags & BOBFLAGF_FreeAlphaChannel))
910 ScalosFree((UBYTE *) bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel);
911 bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel = NULL;
912 bob->scbob_Flags &= ~BOBFLAGF_FreeAlphaChannel;
915 SCA_FreeNode(nodeList, &bob->scbob_Node);
919 static void FreeCustomBobNode(struct ScalosNodeList *nodeList, struct ScaBob *bob)
921 if (NULL == bob)
922 return;
924 if (bob->scbob_Bob.scbob_Bob2.scbob2_bitmap)
926 FreeBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_bitmap);
927 bob->scbob_Bob.scbob_Bob2.scbob2_bitmap = NULL;
929 if (bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap)
931 FreeBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap);
932 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap = NULL;
934 if (bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2)
936 FreeBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2);
937 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2 = NULL;
939 if (bob->scbob_Bob.scbob_Bob2.scbob2_shadow1)
941 FreeBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_shadow1);
942 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1 = NULL;
944 if (bob->scbob_Bob.scbob_Bob2.scbob2_shadow2)
946 FreeBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_shadow2);
947 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2 = NULL;
950 SCA_FreeNode(nodeList, &bob->scbob_Node);
954 static struct ScaBob *sca_AddBobCustom(struct DragHandle *dh,
955 struct ScaBob **BobList,
956 struct BitMap *bm, APTR Mask, const UBYTE *AlphaChannel,
957 ULONG Width, ULONG Height,
958 ULONG BoundsWidth, ULONG BoundsHeight,
959 WORD LeftBorder,
960 LONG XOffset, LONG YOffset)
962 struct ScaBob *bob;
963 struct ScaBob *Result = NULL;
964 struct BitMap *tempBM = NULL;
966 d1(KPrintF("%s/%s/%ld: x=%ld y=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, XOffset, YOffset, Width, Height));
968 do {
969 static UWORD Pattern[] = { 0xaaaa, 0x5555 };
970 struct RastPort rpMask;
972 bob = AllocBob2(dh, (struct ScalosNodeList *) BobList,
973 XOffset, YOffset, Width, Height, BoundsWidth, BoundsHeight);
974 if (NULL == bob)
975 break;
977 bob->scbob_LeftBorder = LeftBorder;
978 bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel = AlphaChannel;
980 tempBM = AllocBitMap(bob->scbob_width, bob->scbob_height, 1, BMF_MINPLANES | BMF_CLEAR, NULL);
981 if (NULL == tempBM)
982 break;
984 InitRastPort(&rpMask);
985 rpMask.BitMap = tempBM;
987 d1(KPrintF("%s/%s/%ld: Mask=%08lx BytesPerRow=%ld Rows=%ld\n", __FILE__, __FUNC__, __LINE__, Mask, tempBM->BytesPerRow, tempBM->Rows));
989 if (Mask)
991 SetABPenDrMd(&rpMask, 1, 0, JAM2);
992 BltTemplate((const PLANEPTR) Mask,
994 2 * ((bob->scbob_width + 15) / 16),
995 &rpMask,
996 0, 0,
997 bob->scbob_width,
998 bob->scbob_height );
1000 else
1002 SetRast(&rpMask, 1);
1005 d1(DumpBitMap(tempBM));
1006 d1(KPrintF("%s/%s/%ld: Mask=%04lx %04lx %04lx %04lx %04lx %04lx %04lx %04lx \n", __FILE__, __FUNC__, __LINE__, \
1007 ((UWORD *) Mask)[0], ((UWORD *) Mask)[1], ((UWORD *) Mask)[2], ((UWORD *) Mask)[3], \
1008 ((UWORD *) Mask)[4], ((UWORD *) Mask)[5], ((UWORD *) Mask)[6], ((UWORD *) Mask)[7]));
1010 d1(KPrintF("%s/%s/%ld: Planes[0]=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
1011 tempBM->Planes[0][0], tempBM->Planes[0][1], \
1012 tempBM->Planes[0][2], tempBM->Planes[0][3], \
1013 tempBM->Planes[0][4], tempBM->Planes[0][5], \
1014 tempBM->Planes[0][6], tempBM->Planes[0][7]));
1016 BlitBob(bob, tempBM, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1);
1018 SetABPenDrMd(&rpMask, 0, 1, JAM1);
1019 SetAfPt(&rpMask, Pattern, 2);
1020 RectFill(&rpMask,
1021 0, 0,
1022 bob->scbob_width - 1, bob->scbob_height - 1);
1024 d1(DumpBitMap(tempBM));
1025 d1(KPrintF("%s/%s/%ld: Planes[0]=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
1026 tempBM->Planes[0][0], tempBM->Planes[0][1], \
1027 tempBM->Planes[0][2], tempBM->Planes[0][3], \
1028 tempBM->Planes[0][4], tempBM->Planes[0][5], \
1029 tempBM->Planes[0][6], tempBM->Planes[0][7]));
1031 BlitBob(bob, tempBM, bob->scbob_Bob.scbob_Bob2.scbob2_shadow2);
1033 d1(kprintf("%s/%s/%ld: Shadow1=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
1034 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][0], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][1], \
1035 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][2], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][3], \
1036 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][4], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][5], \
1037 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][6], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][7]));
1038 d1(kprintf("%s/%s/%ld: Shadow2=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
1039 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][0], bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][1], \
1040 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][2], bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][3], \
1041 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][4], bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][5], \
1042 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][6], bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][7]));
1044 BlitBob(bob, bm, bob->scbob_Bob.scbob_Bob2.scbob2_bitmap);
1046 SCA_SortNodes((struct ScalosNodeList *) BobList, &CompareLeftUpHook, SCA_SortType_Best);
1048 Result = bob;
1049 bob = NULL;
1050 } while (0);
1052 if (bob)
1053 FreeCustomBobNode((struct ScalosNodeList *) BobList, bob);
1054 if (tempBM)
1055 FreeBitMap(tempBM);
1057 return Result;
1061 static void BlitBob(struct ScaBob *bob, struct BitMap *bmSrc, struct BitMap *bmDest)
1063 BltBitMap(bmSrc, 0, 0,
1064 bmDest, 0, 0,
1065 bob->scbob_width, bob->scbob_height,
1066 ABC | ABNC, ~0, NULL);
1067 WaitBlit();
1071 static LONG CompareLeftUpFunc(const struct ScaBob *bob1, const struct ScaBob *bob2)
1073 d1(kprintf("%s/%s/%ld: bob2=%08lx bob2=%08lx\n", __FILE__, __FUNC__, __LINE__, bob1, bob2));
1075 if (bob2->scbob_x < bob1->scbob_x)
1076 return 1;
1077 else if (bob2->scbob_x > bob1->scbob_x)
1078 return -1;
1080 if (bob2->scbob_y < bob1->scbob_y)
1081 return 1;
1082 else if (bob2->scbob_y > bob1->scbob_y)
1083 return -1;
1085 return 0;
1089 BOOL SuspendDrag(struct DragHandle *dh, struct internalScaWindowTask *iwt)
1091 BOOL WasLocked = FALSE;
1093 d1(kprintf("%s/%s/%ld: START dh=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, dh, iwt->iwt_WinTitle));
1095 if (dh)
1097 if (!(dh->drgh_flags & DRGHF_LockSuspended))
1099 ClassHideDragBobs(iwt, dh);
1100 SetWindowPointer(iwt->iwt_WindowTask.wt_Window,
1101 WA_BusyPointer, TRUE,
1102 WA_PointerDelay, 0,
1103 TAG_END);
1104 WasLocked = SCA_UnlockDrag(dh);
1105 dh->drgh_flags |= DRGHF_LockSuspended;
1109 d1(kprintf("%s/%s/%ld: END dh=%08lx WasLocked=%ld\n", __FILE__, __FUNC__, __LINE__, dh, WasLocked));
1111 return WasLocked;
1115 void ResumeDrag(struct DragHandle *dh, struct internalScaWindowTask *iwt, BOOL wasLocked)
1117 d1(kprintf("%s/%s/%ld: START dh=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, dh, iwt->iwt_WinTitle));
1119 if (dh)
1121 if (dh->drgh_flags & DRGHF_LockSuspended)
1123 SetWindowPointer(iwt->iwt_WindowTask.wt_Window,
1124 WA_Pointer, NULL,
1125 TAG_END);
1126 dh->drgh_flags &= ~DRGHF_LockSuspended;
1127 ReLockDrag(dh, iwt, wasLocked);
1130 else
1132 SetWindowPointer(iwt->iwt_WindowTask.wt_Window,
1133 WA_Pointer, NULL,
1134 TAG_END);
1136 d1(kprintf("%s/%s/%ld: END dh=%08lx\n", __FILE__, __FUNC__, __LINE__, dh));
1140 void ReLockDrag(struct DragHandle *dh, struct internalScaWindowTask *iwt, BOOL wasLocked)
1142 d1(kprintf("%s/%s/%ld: START dh=%08lx\n", __FILE__, __FUNC__, __LINE__, dh));
1144 if (wasLocked && (iInfos.xii_GlobalDragHandle == dh) && dh)
1146 BOOL Locked2;
1147 BOOL Locked1 = dh->drgh_flags & DRGHF_LayersLocked;
1149 d1(kprintf("%s/%s/%ld: dh=%08lx drgh_flags=%08lx\n", __FILE__, __FUNC__, __LINE__, dh, dh->drgh_flags));
1151 #if defined(__MORPHOS__)
1152 if (DOSBase->dl_lib.lib_Version >= 51)
1154 WaitTOF();
1155 if (iwt)
1156 WaitBOVP(&iwt->iwt_WinScreen->ViewPort);
1158 #endif //defined(__MORPHOS__)
1159 SCA_LockDrag(dh);
1161 Locked2 = dh->drgh_flags & DRGHF_LayersLocked;
1163 if (iwt && Locked2 && !Locked1)
1165 SCA_DrawDrag(iwt->iwt_myDragHandle,
1166 iwt->iwt_WinScreen->MouseX,
1167 iwt->iwt_WinScreen->MouseY,
1171 d1(kprintf("%s/%s/%ld: dh=%08lx drgh_flags=%08lx\n", __FILE__, __FUNC__, __LINE__, dh, dh->drgh_flags));
1173 d1(kprintf("%s/%s/%ld: END dh=%08lx\n", __FILE__, __FUNC__, __LINE__, dh));
1177 LIBFUNC_P2(void, sca_LockDrag,
1178 A0, struct DragHandle *, dh,
1179 A6, struct ScalosBase *, ScalosBase)
1181 (void) ScalosBase;
1183 if (dh)
1185 d1(kprintf("%s/%s/%ld: dh=%08lx drgh_flags=%08lx Task=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, \
1186 dh, dh->drgh_flags, FindTask(NULL), FindTask(NULL)->tc_Node.ln_Name));
1188 if (!(dh->drgh_flags & DRGHF_LockSuspended) && !(dh->drgh_flags & DRGHF_LayersLocked))
1190 d1(kprintf("%s/%s/%ld: dh=%08lx ScaLockScreenLayers\n", __FILE__, __FUNC__, __LINE__, dh));
1191 ScalosObtainSemaphore(&LayersSema);
1192 ScaLockScreenLayers();
1193 dh->drgh_flags |= DRGHF_LayersLocked;
1194 d1(kprintf("%s/%s/%ld: dh=%08lx ScaLockScreenLayers\n", __FILE__, __FUNC__, __LINE__, dh));
1198 LIBFUNC_END
1201 LIBFUNC_P2(ULONG, sca_UnlockDrag,
1202 A0, struct DragHandle *, dh,
1203 A6, struct ScalosBase *, ScalosBase)
1205 ULONG WasLocked = FALSE;
1207 (void) ScalosBase;
1209 if (dh)
1211 d1(kprintf("%s/%s/%ld: dh=%08lx drgh_flags=%08lx Task=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, \
1212 dh, dh->drgh_flags, FindTask(NULL), FindTask(NULL)->tc_Node.ln_Name));
1213 WasLocked = TRUE;
1215 if (dh->drgh_flags & DRGHF_LayersLocked)
1217 d1(kprintf("%s/%s/%ld: dh=%08lx ScaUnlockScreenLayers\n", __FILE__, __FUNC__, __LINE__, dh));
1218 dh->drgh_flags &= ~DRGHF_LayersLocked;
1219 ScaUnlockScreenLayers();
1220 ScalosReleaseSemaphore(&LayersSema);
1221 d1(kprintf("%s/%s/%ld: dh=%08lx ScaUnlockScreenLayers\n", __FILE__, __FUNC__, __LINE__, dh));
1225 d1(kprintf("%s/%s/%ld: END WasLocked=%ld\n", __FILE__, __FUNC__, __LINE__, WasLocked));
1227 return WasLocked;
1229 LIBFUNC_END
1232 LIBFUNC_P5(void, sca_DrawDrag,
1233 A0, struct DragHandle *, dh,
1234 D0, LONG, XOffset,
1235 D1, LONG, YOffset,
1236 D2, ULONG, Flags,
1237 A6, struct ScalosBase *, ScalosBase)
1239 (void) ScalosBase;
1241 d1(KPrintF("%s/%s/%ld: dh=%08lx x=%ld y=%ld Flags=%08lx\n", \
1242 __FILE__, __FUNC__, __FUNC__, __LINE__, dh, XOffset, YOffset, Flags));
1244 if (NULL == dh)
1245 return;
1247 if (dh->drgh_flags & DRGHF_LockSuspended)
1248 return;
1250 ScalosObtainSemaphore(&dh->drgh_BobListSemaphore);
1252 switch (CurrentPrefs.pref_DragTranspMode)
1254 case DRAGTRANSPMODE_SolidAndTransp:
1255 Flags ^= SCAF_Drag_Transparent;
1256 break;
1257 case DRAGTRANSPMODE_Solid:
1258 Flags &= ~SCAF_Drag_Transparent;
1259 break;
1260 case DRAGTRANSPMODE_Transp:
1261 Flags |= SCAF_Drag_Transparent;
1262 break;
1265 d1(KPrintF("%s/%s/%ld: dh=%08lx x=%ld y=%ld Flags=%08lx\n", \
1266 __FILE__, __FUNC__, __FUNC__, __LINE__, dh, XOffset, YOffset, Flags));
1268 if ((dh->drgh_flags & DRGHF_CustomBob) && !(dh->drgh_flags & DRGHF_BobsOptimized))
1270 OptimizeBobs((struct DragHandle *) dh);
1271 dh->drgh_flags |= DRGHF_BobsOptimized;
1274 if (!(dh->drgh_flags & DRGHF_LayersLocked))
1276 SCA_LockDrag(dh);
1279 if (dh->drgh_flags & DRGHF_CustomBob)
1281 sca_DrawDragCustom((struct DragHandle *) dh, XOffset, YOffset, Flags);
1283 else
1285 struct ScaBob *bob;
1287 CheckSpecialBob(dh, Flags & SCAF_Drag_NoDropHere, DRGHF_NoDropIndicatorVisible,
1288 &dh->drgh_Bob_NoDropIndicator, NAME_FORBIDDEN, NAME_FORBIDDEN_FALLBACK);
1289 CheckSpecialBob(dh, Flags & SCAF_Drag_IndicateCopy, DRGHF_CopyIndicatorVisible,
1290 &dh->drgh_Bob_CopyIndicator, NAME_COPYING, NAME_COPYING_FALLBACK);
1291 CheckSpecialBob(dh, Flags & SCAF_Drag_IndicateMakeLink, DRGHF_MakeLinkIndicatorVisible,
1292 &dh->drgh_Bob_MakeLinkIndicator, NAME_MAKELINK, NAME_MAKELINK_FALLBACK);
1293 CheckSpecialBob(dh, Flags & SCAF_Drag_ForceMove, DRGHF_ForceMoveIndicatorVisible,
1294 &dh->drgh_Bob_ForceMoveIndicator, NAME_MOVING, NAME_MOVING_FALLBACK);
1296 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1298 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.X = XOffset + bob->scbob_x;
1299 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Y = YOffset + bob->scbob_y;
1301 if ((Flags & SCAF_Drag_Transparent) && !(bob->scbob_Flags & BOBFLAGF_NeverTransparent))
1302 bob->scbob_Bob.scbob_Bob1.scbob1_bob.ImageShadow = bob->scbob_Bob.scbob_Bob1.scbob1_shadow2;
1303 else
1304 bob->scbob_Bob.scbob_Bob1.scbob1_bob.ImageShadow = bob->scbob_Bob.scbob_Bob1.scbob1_shadow1;
1307 if ((Flags & SCAF_Drag_Hide) && !(dh->drgh_flags & DRGF_BobsHidden))
1309 // Hide all bobs
1310 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1312 RemIBob(&bob->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort, &dh->drgh_screen->ViewPort);
1314 dh->drgh_flags |= DRGF_BobsHidden;
1316 if (!(Flags & SCAF_Drag_Hide) && (dh->drgh_flags & DRGF_BobsHidden))
1318 // Show hidden bobs
1319 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1321 AddBob(&bob->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort);
1323 dh->drgh_flags &= ~DRGF_BobsHidden;
1326 SortGList(&dh->drgh_screen->RastPort);
1327 DrawGList(&dh->drgh_screen->RastPort, &dh->drgh_screen->ViewPort);
1330 ScalosReleaseSemaphore(&dh->drgh_BobListSemaphore);
1332 LIBFUNC_END
1335 static void sca_DrawDragCustom(struct DragHandle *dh, LONG x, LONG y, ULONG Flags)
1337 struct ScaBob *bob;
1339 d1(KPrintF("%s/%s/%ld: x=%ld y=%ld drgh_flags=%08lx Flags=%08lx\n", \
1340 __FILE__, __FUNC__, __LINE__, x, y, dh->drgh_flags, Flags));
1342 dh->drgh_flags &= ~DRGHF_BlitRealTransp;
1344 if (Flags & SCAF_Drag_Hide)
1346 x = NO_BOB_POSITION;
1347 y = NO_BOB_POSITION;
1348 dh->drgh_flags |= DRGF_BobsHidden;
1351 if (dh->drgh_flags & DRGHF_RealTranspPossible
1352 && (Flags & SCAF_Drag_Transparent))
1354 dh->drgh_flags |= DRGHF_BlitRealTransp;
1355 d1(KPrintF("%s/%s/%ld: DRGHF_BlitRealTransp\n", __FILE__, __FUNC__, __LINE__));
1358 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1360 CheckSpecialBobCustom(dh, Flags & SCAF_Drag_NoDropHere, DRGHF_NoDropIndicatorVisible,
1361 &dh->drgh_Bob_NoDropIndicator, NAME_FORBIDDEN, NAME_FORBIDDEN_FALLBACK);
1362 CheckSpecialBobCustom(dh, Flags & SCAF_Drag_IndicateCopy, DRGHF_CopyIndicatorVisible,
1363 &dh->drgh_Bob_CopyIndicator, NAME_COPYING, NAME_COPYING_FALLBACK);
1364 CheckSpecialBobCustom(dh, Flags & SCAF_Drag_IndicateMakeLink, DRGHF_MakeLinkIndicatorVisible,
1365 &dh->drgh_Bob_MakeLinkIndicator, NAME_MAKELINK, NAME_MAKELINK_FALLBACK);
1366 CheckSpecialBobCustom(dh, Flags & SCAF_Drag_ForceMove, DRGHF_ForceMoveIndicatorVisible,
1367 &dh->drgh_Bob_ForceMoveIndicator, NAME_MOVING, NAME_MOVING_FALLBACK);
1369 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1371 for (bob = dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1373 bob->scbob_Bob.scbob_Bob2.scbob2_xpos = x + bob->scbob_x;
1374 bob->scbob_Bob.scbob_Bob2.scbob2_ypos = y + bob->scbob_y;
1376 if ((Flags & SCAF_Drag_Transparent)
1377 && !(dh->drgh_flags & DRGHF_BlitRealTransp)
1378 && !(bob->scbob_Flags & BOBFLAGF_NeverTransparent))
1379 bob->scbob_Bob.scbob_Bob2.scbob2_shadow = bob->scbob_Bob.scbob_Bob2.scbob2_shadow2;
1380 else
1381 bob->scbob_Bob.scbob_Bob2.scbob2_shadow = bob->scbob_Bob.scbob_Bob2.scbob2_shadow1;
1384 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1386 if (!(dh->drgh_flags & DRGHF_SpeedBitMapAlloc))
1388 LONG MaxWidth = 0, MaxHeight = 0;
1390 for (bob = dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1392 if (bob->scbob_width > MaxWidth)
1393 MaxWidth = bob->scbob_width;
1394 if (bob->scbob_height > MaxHeight)
1395 MaxHeight = bob->scbob_height;
1397 if (0 == MaxWidth)
1398 return;
1400 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap = AllocBitMap(MaxWidth, MaxHeight,
1401 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap->Depth,
1402 BMF_MINPLANES | BMF_DISPLAYABLE,
1403 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap);
1404 if (NULL == dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap)
1405 return;
1407 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2 = AllocBitMap(MaxWidth, MaxHeight,
1408 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap->Depth,
1409 BMF_MINPLANES | BMF_DISPLAYABLE,
1410 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap);
1411 if (NULL == dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2)
1412 return;
1414 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer = AllocVec(MaxWidth * MaxHeight * sizeof(struct ARGB), MEMF_PUBLIC);
1415 if (NULL == dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer)
1416 return;
1418 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2 = AllocVec(MaxWidth * MaxHeight * sizeof(struct ARGB), MEMF_PUBLIC);
1419 if (NULL == dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2)
1420 return;
1422 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap = AllocBitMap(MaxWidth * 2, MaxHeight * 2,
1423 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap->Depth,
1424 BMF_MINPLANES | BMF_DISPLAYABLE,
1425 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap);
1426 if (NULL == dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap)
1427 return;
1429 dh->drgh_flags |= DRGHF_SpeedBitMapAlloc;
1432 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1434 if (dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_lastxpos == dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_xpos &&
1435 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_lastypos == dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_ypos &&
1436 dh->drgh_LastDragFlags == Flags)
1437 return;
1439 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1441 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1443 if (ClipBlitIn(dh->drgh_screen,
1444 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2,
1445 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1446 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1447 bob->scbob_width,
1448 bob->scbob_height))
1450 RestoreBuffer(dh,
1451 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2,
1452 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1453 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1454 bob->scbob_width,
1455 bob->scbob_height);
1457 else
1459 // .nobackup:
1460 bob->scbob_Bob.scbob_Bob2.scbob2_xpos = (WORD) NO_BOB_POSITION;
1461 bob->scbob_Bob.scbob_Bob2.scbob2_ypos = (WORD) NO_BOB_POSITION;
1465 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1467 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1469 d1(kprintf("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, bob->scbob_Bob.scbob_Bob2.scbob2_xpos, bob->scbob_Bob.scbob_Bob2.scbob2_ypos));
1470 d1(kprintf("%s/%s/%ld: lastx=%ld lasty=%ld\n", __FILE__, __FUNC__, __LINE__, bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos, bob->scbob_Bob.scbob_Bob2.scbob2_lastypos));
1471 d1(kprintf("%s/%s/%ld: lastx=%ld isBobPos=%ld\n", __FILE__, __FUNC__, __LINE__, bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos, IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos)));
1473 if (IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos))
1475 LONG dx = bob->scbob_Bob.scbob_Bob2.scbob2_xpos - bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos;
1476 LONG dy = bob->scbob_Bob.scbob_Bob2.scbob2_ypos - bob->scbob_Bob.scbob_Bob2.scbob2_lastypos;
1478 if (dx < 0)
1479 dx = -dx;
1480 if (dy < 0)
1481 dy = -dy;
1483 d1(kprintf("%s/%s/%ld: dx=%ld dy=%ld\n", __FILE__, __FUNC__, __LINE__, dx, dy));
1485 if (dx >= bob->scbob_width || dy >= bob->scbob_height || !IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_xpos))
1487 // .restore:
1489 // icons have been moved more than bob->scbob_width or bob->scbob_height
1491 d1(kprintf("%s/%s/%ld: x=%ld y=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1492 bob->scbob_Bob.scbob_Bob2.scbob2_xpos, bob->scbob_Bob.scbob_Bob2.scbob2_ypos, bob->scbob_width, bob->scbob_height));
1494 // get background at new position
1495 ClipBlitIn(dh->drgh_screen,
1496 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1497 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1498 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1499 bob->scbob_width,
1500 bob->scbob_height);
1502 RestoreBuffer(dh,
1503 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1504 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1505 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1506 bob->scbob_width,
1507 bob->scbob_height);
1509 RestoreBuffer2(dh,
1510 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1511 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1512 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1513 bob->scbob_width,
1514 bob->scbob_height);
1516 BltBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap, 0, 0,
1517 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2, 0, 0,
1518 bob->scbob_width,
1519 bob->scbob_height,
1520 ABC | ABNC, ~0, NULL);
1522 RestoreBuffer2(dh,
1523 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2,
1524 bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos,
1525 bob->scbob_Bob.scbob_Bob2.scbob2_lastypos,
1526 bob->scbob_width,
1527 bob->scbob_height);
1529 // erase bob at old position
1530 ClipBlitOut(dh->drgh_screen,
1531 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2,
1532 bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos,
1533 bob->scbob_Bob.scbob_Bob2.scbob2_lastypos,
1534 bob->scbob_width,
1535 bob->scbob_height);
1537 if (IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_xpos))
1539 d1(kprintf("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, bob->scbob_Bob.scbob_Bob2.scbob2_xpos, bob->scbob_Bob.scbob_Bob2.scbob2_ypos));
1541 // draw bob at new position
1542 ClipBlitOut(dh->drgh_screen,
1543 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1544 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1545 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1546 bob->scbob_width,
1547 bob->scbob_height);
1550 else
1552 // .oldyislower:
1553 LONG xStart, yStart;
1555 dx += bob->scbob_width;
1556 dy += bob->scbob_height;
1558 xStart = min(bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos, bob->scbob_Bob.scbob_Bob2.scbob2_xpos);
1559 yStart = min(bob->scbob_Bob.scbob_Bob2.scbob2_lastypos, bob->scbob_Bob.scbob_Bob2.scbob2_ypos);
1561 d1(kprintf("%s/%s/%ld: x=%ld y=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, xStart, yStart, dx, dy));
1563 // Copy from Screen to speedbitmap
1564 ClipBlitIn(dh->drgh_screen,
1565 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1566 xStart, yStart,
1567 dx, dy);
1569 RestoreBuffer(dh,
1570 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1571 xStart, yStart,
1572 dx, dy);
1574 RestoreBuffer2(dh,
1575 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1576 xStart, yStart,
1577 dx, dy);
1579 d1(kprintf("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, xStart, yStart));
1581 // Copy from speedbitmap to Screen
1582 ClipBlitOut(dh->drgh_screen,
1583 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1584 xStart, yStart,
1585 dx, dy);
1588 else
1590 // .norestore:
1591 ClipBlitIn(dh->drgh_screen,
1592 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1593 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1594 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1595 bob->scbob_width,
1596 bob->scbob_height);
1598 BlitBob2(dh, bob, bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, 0, 0, 0, 0,
1599 bob->scbob_width, bob->scbob_height);
1601 d1(kprintf("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, bob->scbob_Bob.scbob_Bob2.scbob2_xpos, bob->scbob_Bob.scbob_Bob2.scbob2_ypos));
1603 ClipBlitOut(dh->drgh_screen,
1604 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1605 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1606 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1607 bob->scbob_width,
1608 bob->scbob_height);
1612 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1614 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1616 struct BitMap *temp;
1618 bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos = bob->scbob_Bob.scbob_Bob2.scbob2_xpos;
1619 bob->scbob_Bob.scbob_Bob2.scbob2_lastypos = bob->scbob_Bob.scbob_Bob2.scbob2_ypos;
1621 temp = bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap;
1622 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap = bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2;
1623 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2 = temp;
1626 dh->drgh_LastDragFlags = Flags;
1630 static void RestoreBuffer(struct DragHandle *dh,
1631 struct BitMap *DestBM,
1632 LONG x, LONG y, LONG Width, LONG Height)
1634 LONG xMax, yMax;
1635 struct ScaBob *bob;
1637 d1(kprintf("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, x, y));
1639 xMax = x + Width - 1;
1640 yMax = y + Height - 1;
1642 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1644 d1(kprintf("%s/%s/%ld: bob=%08lx xpos=%ld ypos=%ld xMax=%ld yMax=%ld\n", \
1645 __FILE__, __FUNC__, __LINE__, bob, bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos, bob->scbob_Bob.scbob_Bob2.scbob2_lastypos, xMax, yMax));
1647 if (IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos)
1648 && bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos <= xMax
1649 && bob->scbob_Bob.scbob_Bob2.scbob2_lastypos <= yMax
1650 && (bob->scbob_width + bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos - 1) >= x
1651 && (bob->scbob_height + bob->scbob_Bob.scbob_Bob2.scbob2_lastypos - 1) >= y)
1653 LONG SrcX, SrcY, DstX, DstY, SizeX, SizeY;
1655 DstX = 0;
1656 SizeX = bob->scbob_width;
1657 SrcX = x - bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos;
1659 if (SrcX < 0)
1661 SrcX = -SrcX;
1663 SwapLong(&SrcX, &DstX);
1665 SizeX = Width - DstX;
1667 if (SizeX > bob->scbob_width)
1668 SizeX = bob->scbob_width;
1670 else
1672 SizeX -= SrcX;
1673 if (SizeX > Width)
1674 SizeX = Width;
1677 DstY = 0;
1678 SizeY = bob->scbob_height;
1679 SrcY = y - bob->scbob_Bob.scbob_Bob2.scbob2_lastypos;
1681 if (SrcY < 0)
1683 SrcY = -SrcY;
1685 SwapLong(&SrcY, &DstY);
1687 SizeY = Height - DstY;
1689 if (SizeY > bob->scbob_height)
1690 SizeY = bob->scbob_height;
1692 else
1694 SizeY -= SrcY;
1695 if (SizeY > Height)
1696 SizeY = Height;
1699 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1700 SrcX, SrcY, DstX, DstY, SizeX, SizeY));
1702 BltBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap, SrcX, SrcY,
1703 DestBM, DstX, DstY,
1704 SizeX, SizeY,
1705 ABC | ABNC, ~0, NULL);
1711 static void RestoreBuffer2(struct DragHandle *dh,
1712 struct BitMap *DestBM,
1713 LONG x, LONG y, LONG Width, LONG Height)
1715 struct ScaBob *bob;
1716 LONG xMax = x + Width - 1;
1717 LONG yMax = y + Height - 1;
1719 d1(kprintf("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, x, y));
1721 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1723 d1(kprintf("%s/%s/%ld: bob=%08lx xpos=%ld ypos=%ld xMax=%ld yMax=%ld\n", \
1724 __FILE__, __FUNC__, __LINE__, bob, bob->scbob_Bob.scbob_Bob2.scbob2_xpos, bob->scbob_Bob.scbob_Bob2.scbob2_ypos, xMax, yMax));
1726 if (IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_xpos)
1727 && bob->scbob_Bob.scbob_Bob2.scbob2_xpos <= xMax
1728 && bob->scbob_Bob.scbob_Bob2.scbob2_ypos <= yMax
1729 && (bob->scbob_Bob.scbob_Bob2.scbob2_xpos + bob->scbob_width - 1) >= x
1730 && (bob->scbob_Bob.scbob_Bob2.scbob2_ypos + bob->scbob_height - 1) >= y)
1732 LONG SrcX, SrcY, DstX, DstY, SizeX, SizeY;
1734 DstX = 0;
1735 SizeX = bob->scbob_width;
1736 SrcX = x - bob->scbob_Bob.scbob_Bob2.scbob2_xpos;
1738 if (SrcX < 0)
1740 SrcX = -SrcX;
1742 SwapLong(&DstX, &SrcX);
1744 SizeX = Width - DstX;
1746 if (SizeX > bob->scbob_width)
1747 SizeX = bob->scbob_width;
1749 else
1751 SizeX -= SrcX;
1752 if (SizeX > Width)
1753 SizeX = Width;
1756 DstY = 0;
1757 SizeY = bob->scbob_height;
1758 SrcY = y - bob->scbob_Bob.scbob_Bob2.scbob2_ypos;
1760 if (SrcY < 0)
1762 SrcY = -SrcY;
1764 SwapLong(&DstY, &SrcY);
1766 SizeY = Height - DstY;
1768 if (SizeY > bob->scbob_height)
1769 SizeY = bob->scbob_height;
1771 else
1773 SizeY -= SrcY;
1774 if (SizeY > Height)
1775 SizeY = Height;
1778 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1779 SrcX, SrcY, DstX, DstY, SizeX, SizeY));
1781 if (SizeX < bob->scbob_width || SizeY < bob->scbob_height)
1783 // .doubleblit:
1784 d1(kprintf("%s/%s/%ld: .doubleblit\n", __FILE__, __FUNC__, __LINE__));
1786 BltBitMap(DestBM, DstX, DstY,
1787 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap, SrcX, SrcY,
1788 SizeX, SizeY,
1789 ABC | ABNC, ~0, NULL);
1791 dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap = dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap;
1793 BlitTrans(dh, bob, bob->scbob_Bob.scbob_Bob2.scbob2_bitmap,
1794 0, 0,
1795 0, 0,
1796 bob->scbob_width, bob->scbob_height,
1797 bob->scbob_Bob.scbob_Bob2.scbob2_shadow
1800 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1801 SrcX, SrcY, DstX, DstY, SizeX, SizeY));
1803 BltBitMap(dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap, SrcX, SrcY,
1804 DestBM, DstX, DstY,
1805 SizeX, SizeY,
1806 ABC | ABNC, ~0, NULL);
1808 else
1810 dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap = DestBM;
1812 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1813 SrcX, SrcY, DstX, DstY, SizeX, SizeY));
1814 d1(kprintf("%s/%s/%ld: SrcBM=%08lx DestBM=%08lx Mask=%08lx\n", __FILE__, __FUNC__, __LINE__, \
1815 bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, DestBM, bob->scbob_Bob.scbob_Bob2.scbob2_shadow->Planes[0]));
1817 BlitTrans(dh, bob, bob->scbob_Bob.scbob_Bob2.scbob2_bitmap,
1818 SrcX, SrcY,
1819 DstX, DstY,
1820 SizeX, SizeY,
1821 bob->scbob_Bob.scbob_Bob2.scbob2_shadow
1829 // Blit from Screen to an internal Bitmap
1830 static BOOL ClipBlitIn(struct Screen *Scr, struct BitMap *DestBM,
1831 LONG SrcX, LONG SrcY, LONG Width, LONG Height)
1833 LONG DstX, DstY;
1834 struct RastPort rp;
1836 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1837 SrcX, SrcY, Width, Height));
1839 Scalos_InitRastPort(&rp);
1840 rp.BitMap = DestBM;
1842 DstX = -SrcX;
1843 if (DstX < 0)
1845 LONG Right = (SrcX + Width - 1) - (Scr->Width - 1);
1847 if (Right >= 0)
1849 Width -= Right;
1851 if (Width < 0)
1852 return FALSE;
1855 DstX = 0;
1857 else
1859 Width -= DstX;
1861 if (Width < 0)
1862 return FALSE;
1864 SrcX = 0;
1867 DstY = -SrcY;
1868 if (DstY < 0)
1870 LONG Bottom = (SrcY + Height - 1) - (Scr->Height - 1);
1872 if (Bottom >= 0)
1874 Height -= Bottom;
1876 if (Height < 0)
1877 return FALSE;
1880 DstY = 0;
1882 else
1884 Height -= DstY;
1886 if (Height < 0)
1887 return FALSE;
1889 SrcY = 0;
1892 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1893 SrcX, SrcY, DstX, DstY, Width, Height));
1895 ClipBlit(&Scr->RastPort, SrcX, SrcY,
1896 &rp, DstX, DstY,
1897 Width, Height,
1898 ABC | ABNC);
1900 Scalos_DoneRastPort(&rp);
1902 return TRUE;
1906 // Blit from an internal Bitmap to the Screen
1907 static BOOL ClipBlitOut(struct Screen *Scr, struct BitMap *SrcBM,
1908 LONG DstX, LONG DstY, LONG Width, LONG Height)
1910 LONG SrcX, SrcY;
1911 struct RastPort rp;
1913 d1(kprintf("%s/%s/%ld: DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1914 DstX, DstY, Width, Height));
1916 Scalos_InitRastPort(&rp);
1917 rp.BitMap = SrcBM;
1919 SrcX = -DstX;
1920 if (SrcX < 0)
1922 LONG Right = (DstX + Width - 1) - (Scr->Width - 1);
1924 if (Right >= 0)
1926 Width -= Right;
1928 if (Width < 0)
1929 return FALSE;
1932 SrcX = 0;
1934 else
1936 Width -= SrcX;
1938 if (Width < 0)
1939 return FALSE;
1941 DstX = 0;
1944 SrcY = -DstY;
1945 if (SrcY < 0)
1947 LONG Bottom = (DstY + Height - 1) - (Scr->Height - 1);
1949 if (Bottom >= 0)
1951 Height -= Bottom;
1953 if (Height < 0)
1954 return FALSE;
1957 SrcY = 0;
1959 else
1961 Height -= SrcY;
1963 if (Height < 0)
1964 return FALSE;
1966 DstY = 0;
1969 d1(kprintf("%s/%s/%ld: DestRp=%08lx SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1970 &Scr->RastPort, SrcX, SrcY, DstX, DstY, Width, Height));
1972 ClipBlit(&rp, SrcX, SrcY,
1973 &Scr->RastPort, DstX, DstY,
1974 Width, Height,
1975 ABC | ABNC);
1977 Scalos_DoneRastPort(&rp);
1979 return TRUE;
1983 static void BlitBob2(struct DragHandle *dh,
1984 struct ScaBob *bob, struct BitMap *bm,
1985 LONG SrcX, LONG SrcY, LONG DestX, LONG DestY,
1986 LONG Width, LONG Height)
1988 dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap = dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap;
1990 BlitTrans(dh, bob, bm,
1991 SrcX, SrcY, DestX, DestY,
1992 Width, Height,
1993 bob->scbob_Bob.scbob_Bob2.scbob2_shadow);
1997 // DestX, DestY : Offsets into RastPort->BitMap
1999 static void BlitTrans(struct DragHandle *dh,
2000 const struct ScaBob *bob, struct BitMap *SrcBM,
2001 LONG SrcX, LONG SrcY, LONG DestX, LONG DestY,
2002 LONG Width, LONG Height,
2003 const struct BitMap *MaskBM)
2005 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, \
2006 SrcX, SrcY, Width, Height));
2008 if (dh->drgh_flags & DRGHF_RealTranspPossible)
2010 ULONG Transp;
2011 ULONG DestMod = Width * sizeof(struct ARGB);
2012 struct BitMap *oldBitMap;
2014 if ((dh->drgh_flags & DRGHF_BlitRealTransp) && !(bob->scbob_Flags & BOBFLAGF_NeverTransparent))
2015 Transp = (CurrentPrefs.pref_DragTransparency * 255) / 100;
2016 else
2017 Transp = ALPHA_OPAQUE; // opaque
2019 oldBitMap = dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap;
2020 dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap = SrcBM;
2022 // read background from SrcBM into drgh_Specific.drghs_DragHandle2.drgh2_transbuffer
2023 ScalosReadPixelArray(dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer, DestMod,
2024 &dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport, SrcX, SrcY,
2025 Width, Height);
2027 dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap = oldBitMap;
2029 // read icon image into drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2
2030 ScalosReadPixelArray(dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2, DestMod,
2031 &dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport, DestX, DestY,
2032 Width, Height);
2034 d1(kprintf("%s/%s/%ld: AlphaChannel=%08lx\n", \
2035 __FILE__, __FUNC__, __LINE__, bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel));
2037 if (bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel)
2039 BlitARGBMaskAlpha(Width, Height,
2040 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer,
2041 0, 0,
2042 Width,
2043 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2, 0, 0,
2044 MaskBM,
2045 Transp,
2046 bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel,
2047 bob->scbob_LeftBorder, bob->scbob_BoundsWidth);
2049 else
2051 BlitARGBMask(Width, Height,
2052 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer,
2053 0, 0,
2054 Width,
2055 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2, 0, 0,
2056 MaskBM,
2057 Transp);
2060 // write back to icon image
2061 ScalosWritePixelArray(dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2, DestMod,
2062 &dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport, DestX, DestY,
2063 Width, Height);
2065 else
2067 BltMaskBitMapRastPort(SrcBM, SrcX, SrcY,
2068 &dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport, DestX, DestY,
2069 Width, Height,
2070 ABC|ABNC|ANBC, MaskBM->Planes[0]);
2075 static void OptimizeBobs(struct DragHandle *dh)
2077 LONG xMin, yMin, xMax, yMax;
2078 struct ScaBob *bob;
2080 d1(kprintf("%s/%s/%ld: OptimizeBobs START\n", __FILE__, __FUNC__, __LINE__));
2082 xMin = yMin = SHRT_MAX;
2083 xMax = yMax = SHRT_MIN;
2085 bob = dh->drgh_boblist;
2086 if (bob && bob->scbob_Node.mln_Succ)
2088 LONG Width, Height;
2089 struct ScaBob *newBob;
2090 struct ScaBob *nbList = NULL;
2091 BOOL NeedAlpha = FALSE;
2093 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2095 d1(kprintf("%s/%s/%ld: bob=%08lx NoOptimize=%ld\n", __FILE__, __FUNC__, __LINE__, \
2096 bob, bob->scbob_Flags & BOBFLAGF_NoOptimize ));
2097 if (!(bob->scbob_Flags & BOBFLAGF_NoOptimize))
2099 if (bob->scbob_x < xMin)
2100 xMin = bob->scbob_x;
2101 if (bob->scbob_y < yMin)
2102 yMin = bob->scbob_y;
2103 if (bob->scbob_x + bob->scbob_width > xMax)
2104 xMax = bob->scbob_x + bob->scbob_width;
2105 if (bob->scbob_y + bob->scbob_height > yMax)
2106 yMax = bob->scbob_y + bob->scbob_height;
2108 if (bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel)
2109 NeedAlpha = TRUE;
2113 d1(kprintf("%s/%s/%ld: xMin=%ld xMax=%ld yMin=%ld yMax=%ld\n", __FILE__, __FUNC__, __LINE__, \
2114 xMin, xMax, yMin, yMax));
2116 Width = 1 + xMax - xMin;
2117 Height = 1 + yMax - yMin;
2119 newBob = AllocBob2(dh, (struct ScalosNodeList *)(APTR) &nbList, xMin, yMin, Width, Height, Width, Height);
2120 if (newBob)
2122 struct RastPort rp;
2124 Scalos_InitRastPort(&rp);
2126 if (NeedAlpha)
2127 MergeBobsAlpha(&rp, dh, &nbList, newBob);
2128 else
2129 MergeBobs(&rp, dh, &nbList, newBob);
2131 FreeCustomBobList(&dh->drgh_boblist);
2132 dh->drgh_boblist = nbList;
2134 Scalos_DoneRastPort(&rp);
2138 d1(kprintf("%s/%s/%ld: OptimizeBobs END\n", __FILE__, __FUNC__, __LINE__));
2140 dh->drgh_flags |= DRGHF_BobsOptimized;
2144 static void MergeBobs(struct RastPort *TempRp, struct DragHandle *dh,
2145 struct ScaBob **NewBobList, struct ScaBob *NewBob)
2147 struct ScaBob *bob;
2149 for (bob=dh->drgh_boblist; bob; )
2151 struct ScaBob *NextBob = (struct ScaBob *) bob->scbob_Node.mln_Succ;
2153 d1(kprintf("%s/%s/%ld: bob=%08lx NoOptimize=%ld\n", __FILE__, __FUNC__, __LINE__, \
2154 bob, bob->scbob_Flags & BOBFLAGF_NoOptimize ));
2156 if (bob->scbob_Flags & BOBFLAGF_NoOptimize)
2158 SCA_MoveBobNode(&dh->drgh_boblist, NewBobList, bob);
2160 else
2162 LONG DstX = bob->scbob_x - NewBob->scbob_x;
2163 LONG DstY = bob->scbob_y - NewBob->scbob_y;
2165 d1(kprintf("%s/%s/%ld: bob=%08lx DstX=%ld DstY=%ld\n", __FILE__, __FUNC__, __LINE__, \
2166 bob, DstX, DstY));
2168 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_bitmap;
2169 BltMaskBitMapRastPort(bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, 0, 0,
2170 TempRp, DstX, DstY,
2171 bob->scbob_width, bob->scbob_height,
2172 ABC | ABNC | ANBC, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0]
2175 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_shadow1;
2176 BltMaskBitMapRastPort(bob->scbob_Bob.scbob_Bob2.scbob2_shadow1, 0, 0,
2177 TempRp, DstX, DstY,
2178 bob->scbob_width, bob->scbob_height,
2179 ABC | ABNC | ANBC, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0]
2182 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_shadow2;
2183 BltMaskBitMapRastPort(bob->scbob_Bob.scbob_Bob2.scbob2_shadow2, 0, 0,
2184 TempRp, DstX, DstY,
2185 bob->scbob_width, bob->scbob_height,
2186 ABC | ABNC | ANBC, bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0]
2190 bob = NextBob;
2196 static void MergeBobsAlpha(struct RastPort *TempRp, struct DragHandle *dh,
2197 struct ScaBob **NewBobList, struct ScaBob *NewBob)
2199 struct ARGB *OldBobBuffer;
2200 struct ARGB *NewBobBuffer = NULL;
2202 do {
2203 struct ScaBob *bob;
2204 size_t AllocSize;
2205 UBYTE *NewAlphaChannel;
2206 UWORD NewBobDestMod = NewBob->scbob_width * sizeof(struct ARGB);
2208 d1(kprintf("%s/%s/%ld: NewBob Width=%ld Height=%ld\n", \
2209 __FILE__, __FUNC__, __LINE__, NewBob->scbob_width, NewBob->scbob_height));
2211 // First, move all bobs away that are not to be merged
2212 for (bob=dh->drgh_boblist; bob; )
2214 struct ScaBob *NextBob = (struct ScaBob *) bob->scbob_Node.mln_Succ;
2216 d1(kprintf("%s/%s/%ld: bob=%08lx NoOptimize=%ld\n", __FILE__, __FUNC__, __LINE__, \
2217 bob, bob->scbob_Flags & BOBFLAGF_NoOptimize ));
2219 if (bob->scbob_Flags & BOBFLAGF_NoOptimize)
2221 SCA_MoveBobNode(&dh->drgh_boblist, NewBobList, bob);
2223 bob = NextBob;
2226 AllocSize = NewBob->scbob_width * NewBob->scbob_height * sizeof(struct ARGB);
2227 OldBobBuffer = ScalosAlloc(AllocSize);
2228 d1(kprintf("%s/%s/%ld: OldBobBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, OldBobBuffer));
2229 if (NULL == OldBobBuffer)
2230 break;
2232 NewBobBuffer = ScalosAlloc(AllocSize);
2233 d1(kprintf("%s/%s/%ld: NewBobBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, NewBobBuffer));
2234 if (NULL == NewBobBuffer)
2235 break;
2237 // Allocate Alpha channel for new bob
2238 NewBob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel = NewAlphaChannel = ScalosAlloc(NewBob->scbob_width * NewBob->scbob_height);
2239 if (NULL == NewBob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel)
2240 break;
2241 NewBob->scbob_Flags |= BOBFLAGF_FreeAlphaChannel;
2243 d1(kprintf("%s/%s/%ld: AlphaChannel=%08lx\n", __FILE__, __FUNC__, __LINE__, \
2244 NewBob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel));
2246 memset(NewAlphaChannel, 0, NewBob->scbob_width * NewBob->scbob_height);
2249 // Merge <scbob2_bitmap>
2251 memset(NewBobBuffer, 0, AllocSize);
2252 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2254 LONG DstX = bob->scbob_x - NewBob->scbob_x;
2255 LONG DstY = bob->scbob_y - NewBob->scbob_y;
2256 UWORD DestMod = bob->scbob_width * sizeof(struct ARGB);
2257 ULONG y;
2258 const UBYTE *AlphaSrcPtr = bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel;
2259 UBYTE *AlphaDestPtr = NewAlphaChannel + DstY * NewBob->scbob_width;
2260 const UBYTE *Mask = bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0];
2261 ULONG MaskBytesPerRow = ((bob->scbob_width + 15) & ~0x0f) / 8;
2263 d1(kprintf("%s/%s/%ld: bob=%08lx AlphaSrcPtr=%08lx\n", __FILE__, __FUNC__, __LINE__, bob, AlphaSrcPtr));
2264 d1(kprintf("%s/%s/%ld: bob=%08lx width=%ld height=%ld\n", \
2265 __FILE__, __FUNC__, __LINE__, bob, bob->scbob_width, bob->scbob_height));
2267 d1(kprintf("%s/%s/%ld: bob=%08lx DstX=%ld DstY=%ld OldBobBuffer=%08lx\n", \
2268 __FILE__, __FUNC__, __LINE__, bob, DstX, DstY, OldBobBuffer));
2270 TempRp->BitMap = bob->scbob_Bob.scbob_Bob2.scbob2_bitmap;
2272 ScalosReadPixelArray(OldBobBuffer, DestMod, TempRp,
2273 0, 0, bob->scbob_width, bob->scbob_height);
2275 if (AlphaSrcPtr)
2277 BlitARGBMaskAlpha(bob->scbob_width, bob->scbob_height,
2278 OldBobBuffer, 0, 0,
2279 NewBob->scbob_width,
2280 NewBobBuffer, DstX, DstY,
2281 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1,
2282 ALPHA_OPAQUE,
2283 AlphaSrcPtr,
2284 bob->scbob_LeftBorder, bob->scbob_BoundsWidth);
2286 else
2288 BlitARGBMask(bob->scbob_width, bob->scbob_height,
2289 OldBobBuffer, 0, 0,
2290 NewBob->scbob_width,
2291 NewBobBuffer, DstX, DstY,
2292 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1,
2293 ALPHA_OPAQUE);
2296 // calculate combined Alpha for merged bob
2297 for (y = 0; y < bob->scbob_height; y++)
2299 UBYTE *AlphaLineDestPtr = AlphaDestPtr + DstX;
2300 ULONG x;
2302 if (AlphaSrcPtr)
2304 const UBYTE *AlphaLineSrcPtr = AlphaSrcPtr + bob->scbob_LeftBorder;
2306 for (x = 0; x < bob->scbob_width; x++, AlphaLineSrcPtr++, AlphaLineDestPtr++)
2308 ULONG OldBobTransparency = ALPHA_OPAQUE - *AlphaLineSrcPtr;
2309 ULONG NewBobTransparency = ALPHA_OPAQUE - *AlphaLineDestPtr;
2311 NewBobTransparency = ALPHA_OPAQUE - ((OldBobTransparency * NewBobTransparency) >> 8);
2312 if (NewBobTransparency > UCHAR_MAX)
2313 NewBobTransparency = UCHAR_MAX;
2315 *AlphaLineDestPtr = NewBobTransparency;
2318 AlphaSrcPtr += bob->scbob_BoundsWidth;
2320 else
2322 // <bob> has no Alpha channel
2323 UWORD BitMask = 0x0080;
2324 const UBYTE *MaskPtr2 = Mask;
2326 for (x = 0; x < bob->scbob_width; x++, AlphaLineDestPtr++)
2328 if (*MaskPtr2 & BitMask)
2329 *AlphaLineDestPtr = ALPHA_OPAQUE;
2331 BitMask >>= 1;
2332 if (0 == BitMask)
2334 BitMask = 0x0080;
2335 MaskPtr2++;
2339 Mask += MaskBytesPerRow;
2342 AlphaDestPtr += NewBob->scbob_width;
2344 d1(kprintf("%s/%s/%ld: AlphaDestPtr=%08lx Offset=%lu\n", \
2345 __FILE__, __FUNC__, __LINE__, AlphaDestPtr, AlphaDestPtr - NewAlphaChannel));
2348 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_bitmap;
2349 ScalosWritePixelArray(NewBobBuffer, NewBobDestMod, TempRp,
2350 0, 0, NewBob->scbob_width, NewBob->scbob_height);
2354 // Now merge <scbob2_shadow1> and <scbob2_shadow2>
2356 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2358 LONG DstX = bob->scbob_x - NewBob->scbob_x;
2359 LONG DstY = bob->scbob_y - NewBob->scbob_y;
2361 d1(kprintf("%s/%s/%ld: bob=%08lx DstX=%ld DstY=%ld\n", __FILE__, __FUNC__, __LINE__, \
2362 bob, DstX, DstY));
2364 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_shadow1;
2365 BltMaskBitMapRastPort(bob->scbob_Bob.scbob_Bob2.scbob2_shadow1, 0, 0,
2366 TempRp, DstX, DstY,
2367 bob->scbob_width, bob->scbob_height,
2368 ABC | ABNC | ANBC, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0]
2371 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_shadow2;
2372 BltMaskBitMapRastPort(bob->scbob_Bob.scbob_Bob2.scbob2_shadow2, 0, 0,
2373 TempRp, DstX, DstY,
2374 bob->scbob_width, bob->scbob_height,
2375 ABC | ABNC | ANBC, bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0]
2378 } while (0);
2380 if (NewBobBuffer)
2381 ScalosFree(NewBobBuffer);
2382 if (OldBobBuffer)
2383 ScalosFree(OldBobBuffer);
2387 static void SwapLong(LONG *x1, LONG *x2)
2389 LONG temp = *x1;
2391 *x1 = *x2;
2392 *x2 = temp;
2396 // Free all bobs in BobList
2397 static void FreeBobList(struct DragHandle *dh)
2399 struct ScaBob *bob;
2401 if (!(dh->drgh_flags & DRGF_BobsHidden))
2403 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2405 RemIBob(&bob->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort, &dh->drgh_screen->ViewPort);
2408 WaitBOVP(&dh->drgh_screen->ViewPort);
2411 while (dh->drgh_SpecialBobList)
2412 FreeBobNode((struct ScalosNodeList *) &dh->drgh_SpecialBobList, dh->drgh_SpecialBobList);
2414 while (dh->drgh_boblist)
2415 FreeBobNode((struct ScalosNodeList *) &dh->drgh_boblist, dh->drgh_boblist);
2419 static void RemoveCustomBobsFromScreen(struct ScaBob **BobList)
2421 struct ScaBob *bob;
2423 for (bob=*BobList; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2425 if (bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap && IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos))
2427 // bob needs to be removed from screen
2428 ClipBlitOut(bob->scbob_draghandle->drgh_screen,
2429 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap,
2430 bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos, bob->scbob_Bob.scbob_Bob2.scbob2_lastypos,
2431 bob->scbob_width, bob->scbob_height);
2435 WaitBlit();
2439 // Free all custom bobs in BobList
2440 static void FreeCustomBobList(struct ScaBob **BobList)
2442 RemoveCustomBobsFromScreen(BobList);
2444 while (*BobList)
2445 FreeCustomBobNode((struct ScalosNodeList *) BobList, *BobList);
2449 static struct ScaBob *AllocBob2(struct DragHandle *dh, struct ScalosNodeList *BobList,
2450 LONG x, LONG y, LONG Width, LONG Height, LONG BoundsWidth, LONG BoundsHeight)
2452 ULONG Depth, ScreenWidth, Flags;
2453 BOOL Success = FALSE;
2454 struct ScaBob *bob;
2456 do {
2457 bob = (struct ScaBob *) SCA_AllocNode(BobList, sizeof(struct ScaBob) - sizeof(struct MinNode));
2458 if (NULL == bob)
2459 break;
2461 bob->scbob_draghandle = (struct DragHandle *) dh;
2462 bob->scbob_width = Width;
2463 bob->scbob_height = Height;
2464 bob->scbob_BoundsWidth = BoundsWidth;
2465 bob->scbob_BoundsHeight = BoundsHeight;
2466 bob->scbob_x = x;
2467 bob->scbob_y = y;
2468 bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel = NULL;
2469 bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos = (WORD) NO_BOB_POSITION;
2470 bob->scbob_Bob.scbob_Bob2.scbob2_lastypos = (WORD) NO_BOB_POSITION;
2472 Depth = GetBitMapAttr(dh->drgh_screen->RastPort.BitMap, BMA_DEPTH);
2473 if (0 == Depth)
2474 break;
2476 bob->scbob_Bob.scbob_Bob2.scbob2_bitmap = AllocBitMap(bob->scbob_width, bob->scbob_height,
2477 Depth, BMF_MINPLANES | BMF_DISPLAYABLE, dh->drgh_screen->RastPort.BitMap);
2478 if (NULL == bob->scbob_Bob.scbob_Bob2.scbob2_bitmap)
2479 break;
2481 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap = AllocBitMap(bob->scbob_width, bob->scbob_height,
2482 Depth, BMF_MINPLANES | BMF_DISPLAYABLE, dh->drgh_screen->RastPort.BitMap);
2483 if (NULL == bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap)
2484 break;
2486 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2 = AllocBitMap(bob->scbob_width, bob->scbob_height,
2487 Depth, BMF_MINPLANES | BMF_DISPLAYABLE, dh->drgh_screen->RastPort.BitMap);
2488 if (NULL == bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2)
2489 break;
2491 ScreenWidth = GetBitMapAttr(bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, BMA_WIDTH);
2492 Flags = GetBitMapAttr(bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, BMA_FLAGS);
2493 if (Flags & BMF_INTERLEAVED)
2495 Depth = GetBitMapAttr(bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, BMA_DEPTH);
2496 ScreenWidth *= Depth;
2499 d1(kprintf("%s/%s/%ld: ScreenWidth=%ld\n", __FILE__, __FUNC__, __LINE__, ScreenWidth));
2501 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1 = AllocBitMap(ScreenWidth, bob->scbob_height, 1, BMF_CLEAR, NULL);
2502 if (NULL == bob->scbob_Bob.scbob_Bob2.scbob2_shadow1)
2503 break;
2505 d1(kprintf("%s/%s/%ld: Shadow1: BytesPerRow=%ld Rows=%ld Depth=%ld FLags=%02lx\n", __FILE__, __FUNC__, __LINE__, \
2506 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->BytesPerRow, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Rows, \
2507 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Depth, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Flags));
2508 d1(kprintf("%s/%s/%ld: Planes: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx \n", __FILE__, __FUNC__, __LINE__, \
2509 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[1],
2510 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[2], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[3],
2511 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[4], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[5],
2512 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[6], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[7]));
2514 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2 = AllocBitMap(ScreenWidth, bob->scbob_height, 1, BMF_CLEAR, NULL);
2515 if (NULL == bob->scbob_Bob.scbob_Bob2.scbob2_shadow2)
2516 break;
2518 Success= TRUE;
2519 } while (0);
2521 if (!Success && bob)
2523 FreeCustomBobNode(BobList, bob);
2524 bob = NULL;
2527 return bob;
2531 static BOOL IsBobPosition(WORD x)
2533 return (BOOL) ((UWORD) x != NO_BOB_POSITION);
2537 static void FreeSpeedBitMapAlloc(struct DragHandle *dh)
2539 if (dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap)
2541 FreeBitMap(dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap);
2542 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap = NULL;
2544 if (dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap)
2546 FreeBitMap(dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap);
2547 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap = NULL;
2549 if (dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2)
2551 FreeBitMap(dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2);
2552 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2 = NULL;
2555 if (dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer)
2557 FreeVec(dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer);
2558 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer = NULL;
2560 if (dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2)
2562 FreeVec(dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2);
2563 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2 = NULL;
2566 dh->drgh_flags &= ~DRGHF_SpeedBitMapAlloc;
2570 LIBFUNC_P2(void, sca_EndDrag,
2571 A0, struct DragHandle *, dh,
2572 A6, struct ScalosBase *, ScalosBase)
2574 (void)ScalosBase;
2576 d1(kprintf("%s/%s/%ld: START dh=%08lx\n", __FILE__, __FUNC__, __LINE__, dh));
2578 if (dh == iInfos.xii_GlobalDragHandle)
2580 iInfos.xii_GlobalDragHandle = NULL;
2582 if (dh->drgh_flags & DRGHF_CustomBob)
2584 FreeCustomBobList(&dh->drgh_boblist); // remove+free all bobs
2586 FreeCustomBobList(&dh->drgh_SpecialBobList); // free special bobs
2588 FreeSpeedBitMapAlloc(dh);
2590 Scalos_DoneRastPort(&dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport);
2592 else
2594 FreeBobList(dh); // remove+free all bobs
2596 dh->drgh_screen->RastPort.GelsInfo = dh->drgh_Specific.drghs_DragHandle1.drgh1_oldginfo;
2599 while (dh->drgh_SpecialDragList)
2601 d1(kprintf("%s/%s/%ld: Free dgn=%08lx\n", __FILE__, __FUNC__, __LINE__, dh->drgh_SpecialDragList));
2602 SCA_FreeNode((struct ScalosNodeList *) &dh->drgh_SpecialDragList, &dh->drgh_SpecialDragList->drgn_Node);
2604 while (dh->drgh_SpecialIconList)
2606 if (dh->drgh_SpecialIconList->in_Icon)
2607 DisposeIconObject(dh->drgh_SpecialIconList->in_Icon);
2609 SCA_FreeNode((struct ScalosNodeList *) &dh->drgh_SpecialIconList, &dh->drgh_SpecialIconList->in_Node);
2612 d1(kprintf("%s/%s/%ld: dh=%08lx drgh_flags=%08lx\n", __FILE__, __FUNC__, __LINE__, dh, dh->drgh_flags));
2613 if (dh->drgh_flags & DRGHF_LayersLocked)
2615 SCA_UnlockDrag(dh);
2618 ScalosFree(dh);
2620 if (!CurrentPrefs.pref_EnableDropMenu)
2621 ClosePopupWindows(FALSE);
2623 d1(kprintf("%s/%s/%ld: END dh=%08lx\n", __FILE__, __FUNC__, __LINE__, dh));
2625 LIBFUNC_END
2628 LIBFUNC_P2(struct DragHandle *, sca_InitDrag,
2629 A0, struct Screen *, Scr,
2630 A6, struct ScalosBase *, ScalosBase)
2632 ULONG Depth;
2634 (void) ScalosBase;
2636 if (NULL == iInfos.xii_GlobalDragHandle)
2638 struct DragHandle *dh;
2640 if (NULL == Scr)
2641 Scr = iInfos.xii_iinfos.ii_Screen;
2643 Depth = GetBitMapAttr(Scr->RastPort.BitMap, BMA_DEPTH);
2645 dh = ScalosAlloc(sizeof(struct DragHandle));
2646 if (NULL == dh)
2647 return NULL;
2649 memset(dh, 0, sizeof(struct DragHandle));
2651 dh->drgh_screen = Scr;
2653 if (DRAGMETHOD_Custom == CurrentPrefs.pref_DragMethod || Depth > 8)
2655 dh->drgh_flags |= DRGHF_CustomBob;
2657 Scalos_InitRastPort(&dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport);
2659 if (CyberGfxBase && CurrentPrefs.pref_RealTransFlag && Depth > 8)
2660 dh->drgh_flags |= DRGHF_RealTranspPossible;
2662 d1(KPrintF("%s/%s/%ld: CyberGfxBase=%08lx pref_RealTransFlag=%ld Depth=%ld\n", \
2663 __FILE__, __FUNC__, __LINE__, CyberGfxBase, CurrentPrefs.pref_RealTransFlag, Depth));
2665 ScalosInitSemaphore(&dh->drgh_BobListSemaphore);
2667 iInfos.xii_GlobalDragHandle = dh;
2669 else
2671 dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo.leftmost = 0;
2672 dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo.topmost = 0;
2673 dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo.rightmost = Scr->Width - 1;
2674 dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo.bottommost = Scr->Height - 1;
2676 InitGels(&dh->drgh_Specific.drghs_DragHandle1.drgh1_vshead,
2677 &dh->drgh_Specific.drghs_DragHandle1.drgh1_vstail,
2678 &dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo);
2680 dh->drgh_Specific.drghs_DragHandle1.drgh1_oldginfo = dh->drgh_screen->RastPort.GelsInfo;
2681 dh->drgh_screen->RastPort.GelsInfo = &dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo;
2683 ScalosInitSemaphore(&dh->drgh_BobListSemaphore);
2685 iInfos.xii_GlobalDragHandle = dh;
2689 return iInfos.xii_GlobalDragHandle;
2691 LIBFUNC_END
2694 static BOOL AddSpecialIcon(struct internalScaWindowTask *iwt, struct RastPort *rp,
2695 CONST_STRPTR IconFileName, struct ScaBob **BobPtr)
2697 struct ScaIconNode *in;
2698 struct DragHandle *dh = iwt->iwt_myDragHandle;
2700 in = (struct ScaIconNode *) SCA_AllocStdNode((struct ScalosNodeList *) &dh->drgh_SpecialIconList, NTYP_IconNode);
2701 if (NULL == in)
2702 return FALSE;
2704 in->in_Icon = NewIconObjectTags((STRPTR) IconFileName,
2705 IDTA_Text, (ULONG) "",
2706 TAG_END);
2708 d1(kprintf("%s/%s/%ld: in=%08lx IconObj=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, in, in->in_Icon, IconFileName));
2710 if (NULL == in->in_Icon)
2712 SCA_FreeNode((struct ScalosNodeList *) &dh->drgh_SpecialIconList, &in->in_Node);
2713 return FALSE;
2716 DoMethod(in->in_Icon, IDTM_Layout, iwt->iwt_WinScreen,
2717 iwt->iwt_WindowTask.wt_Window, iwt->iwt_WindowTask.wt_Window->RPort,
2718 iwt->iwt_WinDrawInfo, IOLAYOUTF_NormalImage);
2720 return AppendSpecialDragNode(dh, iwt, rp, in, BobPtr);
2724 static BOOL AppendSpecialDragNode(struct DragHandle *dh,
2725 struct internalScaWindowTask *iwt, struct RastPort *rp,
2726 struct ScaIconNode *in, struct ScaBob **BobPtr)
2728 BOOL Success = FALSE;
2729 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
2730 struct DragNode *dgn = (struct DragNode *) SCA_AllocStdNode((struct ScalosNodeList *) &dh->drgh_SpecialDragList, NTYP_DragNode);
2732 d1(KPrintF("%s/%s/%ld: dgn=%08lx\n", __FILE__, __FUNC__, __LINE__, dgn));
2734 if (dgn)
2736 struct ScaBob *bob;
2737 WORD bx, by;
2739 bx = - gg->Width / 2;
2740 by = - gg->Height / 2;
2742 dgn->drgn_iconnode = in;
2743 dgn->drgn_icon = in->in_Icon;
2745 dgn->drgn_x = 0;
2746 dgn->drgn_y = 0;
2748 // create new Bob at end of drgh_boblist
2749 bob = InitDrag_ImageOnly(dgn, &iwt->iwt_myDragHandle->drgh_SpecialBobList, rp, iwt, bx, by);
2751 // find bob
2752 if (bob)
2754 *BobPtr = bob;
2756 bob->scbob_Flags |= BOBFLAGF_NeverTransparent;
2758 Success = TRUE;
2762 return Success;
2766 // Add or remove special indicator bob
2767 // used with custom bob routines
2768 static void CheckSpecialBobCustom(struct DragHandle *dh, ULONG Flags,
2769 ULONG MaskBit, struct ScaBob **bob, CONST_STRPTR FirstName, CONST_STRPTR FallbackName)
2771 BOOL changed = FALSE;
2773 if (Flags && !(dh->drgh_flags & MaskBit))
2775 // Add Indicator
2776 if (NULL == *bob)
2778 struct RastPort rp;
2780 InitRastPort(&rp);
2781 if (!AddSpecialIcon(dh->drgh_iwt, &rp, FirstName, bob))
2782 AddSpecialIcon(dh->drgh_iwt, &rp, FallbackName, bob);
2785 if (*bob)
2787 RemoveCustomBobsFromScreen(&dh->drgh_boblist);
2789 SCA_MoveBobNode(&dh->drgh_SpecialBobList, &dh->drgh_boblist, *bob);
2791 dh->drgh_flags |= MaskBit;
2793 (*bob)->scbob_Bob.scbob_Bob2.scbob2_xpos = (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastxpos = (WORD) NO_BOB_POSITION;
2794 (*bob)->scbob_Bob.scbob_Bob2.scbob2_ypos = (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastypos = (WORD) NO_BOB_POSITION;
2796 changed = TRUE;
2799 if (!Flags && (dh->drgh_flags & MaskBit))
2801 // Remove Indicator
2802 d1(kprintf("%s/%s/%ld: bob=%08lx\n", __FILE__, __FUNC__, __LINE__, *bob));
2804 if ((*bob)->scbob_Bob.scbob_Bob2.scbob2_backbitmap && IsBobPosition((*bob)->scbob_Bob.scbob_Bob2.scbob2_lastxpos))
2806 // bob needs to be removed from screen
2807 ClipBlitOut((*bob)->scbob_draghandle->drgh_screen,
2808 (*bob)->scbob_Bob.scbob_Bob2.scbob2_backbitmap,
2809 (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastxpos, (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastypos,
2810 (*bob)->scbob_width, (*bob)->scbob_height);
2813 SCA_MoveBobNode(&dh->drgh_boblist, &dh->drgh_SpecialBobList, *bob);
2815 RemoveCustomBobsFromScreen(&dh->drgh_boblist);
2817 (*bob)->scbob_Bob.scbob_Bob2.scbob2_xpos = (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastxpos = (WORD) NO_BOB_POSITION;
2818 (*bob)->scbob_Bob.scbob_Bob2.scbob2_ypos = (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastypos = (WORD) NO_BOB_POSITION;
2820 dh->drgh_flags &= ~MaskBit;
2821 changed = TRUE;
2823 if (changed)
2824 FreeSpeedBitMapAlloc(dh);
2828 // Add or remove special indicator bob
2829 // used with system bob routines
2830 static void CheckSpecialBob(struct DragHandle *dh, ULONG Flags,
2831 ULONG MaskBit, struct ScaBob **bob, CONST_STRPTR FirstName, CONST_STRPTR FallbackName)
2833 if (Flags && !(dh->drgh_flags & MaskBit))
2835 // Add Indicator
2836 if (NULL == *bob)
2838 struct RastPort rp;
2840 InitRastPort(&rp);
2841 if (!AddSpecialIcon(dh->drgh_iwt, &rp, FirstName, bob))
2842 AddSpecialIcon(dh->drgh_iwt, &rp, FallbackName, bob);
2844 if (*bob)
2846 SCA_MoveBobNode(&dh->drgh_SpecialBobList, &dh->drgh_boblist, *bob);
2848 dh->drgh_flags |= MaskBit;
2850 if (!(dh->drgh_flags & DRGF_BobsHidden))
2851 AddBob(&(*bob)->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort);
2854 if (!Flags && (dh->drgh_flags & MaskBit))
2856 // Remove Indicator
2857 if (!(dh->drgh_flags & DRGF_BobsHidden))
2858 RemIBob(&(*bob)->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort, &dh->drgh_screen->ViewPort);
2860 SCA_MoveBobNode(&dh->drgh_boblist, &dh->drgh_SpecialBobList, *bob);
2862 dh->drgh_flags &= ~MaskBit;
2867 void EndDrag(struct internalScaWindowTask *iwt)
2869 d1(kprintf("%s/%s/%ld: iwt=%08lx DragFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt, iwt->iwt_DragFlags));
2870 d1(kprintf("%s/%s/%ld: WinUnderPtr=%08lx DragFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, \
2871 iwt->iwt_WinUnderPtr, iwt->iwt_WinUnderPtr ? iwt->iwt_WinUnderPtr->iwt_DragFlags : 0l));
2873 SCA_EndDrag(iwt->iwt_myDragHandle); // side effect: does UnlockLayers()
2875 iwt->iwt_myDragHandle = NULL;
2879 void EndDragUnlock(struct internalScaWindowTask *iwt)
2881 SCA_FreeAllNodes((struct ScalosNodeList *) &iwt->iwt_DragNodeList);
2883 if (iwt->iwt_IconListDDLocked)
2885 iwt->iwt_IconListDDLocked = FALSE;
2886 ScalosUnLockIconList(iwt);
2891 static BOOL AddInfoTextBob(struct internalScaWindowTask *iwt)
2893 BOOL Success = FALSE;
2894 STRPTR TextBuffer[3] = { NULL, NULL, NULL };
2895 struct BitMap *bm = NULL;
2896 APTR Mask = NULL;
2897 short n;
2899 do {
2900 struct RastPort rp;
2901 struct TextExtent tExt[3];
2902 WORD Width, Height;
2903 WORD x, y;
2904 LONG Len, yMax;
2905 struct ScaBob *bob;
2907 memset(tExt, 0, sizeof(tExt));
2909 for (n=0; n<3; n++)
2911 TextBuffer[n] = AllocPathBuffer();
2912 if (NULL == TextBuffer[n])
2913 break;
2915 strcpy(TextBuffer[n], "");
2918 if (iwt->iwt_myDragHandle->drgh_DrawerCount + iwt->iwt_myDragHandle->drgh_DeviceCount
2919 + iwt->iwt_myDragHandle->drgh_FileCount > 1)
2921 if (iwt->iwt_myDragHandle->drgh_FileCount > 0)
2923 ScaFormatStringMaxLength(TextBuffer[0], Max_PathLen,
2924 GetLocString(MSGID_MULTIDRAG),
2925 iwt->iwt_myDragHandle->drgh_FileCount,
2926 (ULONG) GetLocString(1 == iwt->iwt_myDragHandle->drgh_FileCount ? MSGID_MULTIDRAG_FILE_1 : MSGID_MULTIDRAG_FILE_2)
2929 if (iwt->iwt_myDragHandle->drgh_DrawerCount > 0)
2931 ScaFormatStringMaxLength(TextBuffer[1], Max_PathLen,
2932 GetLocString(MSGID_MULTIDRAG),
2933 iwt->iwt_myDragHandle->drgh_DrawerCount,
2934 (ULONG) GetLocString(1 == iwt->iwt_myDragHandle->drgh_DrawerCount ? MSGID_MULTIDRAG_DRAWER_1 : MSGID_MULTIDRAG_DRAWER_2)
2937 if (iwt->iwt_myDragHandle->drgh_DeviceCount > 0)
2939 ScaFormatStringMaxLength(TextBuffer[2], Max_PathLen,
2940 GetLocString(MSGID_MULTIDRAG),
2941 iwt->iwt_myDragHandle->drgh_DeviceCount,
2942 (ULONG) GetLocString(1 == iwt->iwt_myDragHandle->drgh_DeviceCount ? MSGID_MULTIDRAG_DEVICE_1 : MSGID_MULTIDRAG_DEVICE_2)
2947 for (Len=0, n=0; n<3; n++)
2949 Len += strlen(TextBuffer[n]);
2952 if (0 == Len)
2953 break;
2955 // find position for text bob (just below all othe bobs)
2956 yMax = -1;
2957 for (bob=iwt->iwt_myDragHandle->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2959 if (bob->scbob_y + bob->scbob_height > yMax)
2960 yMax = bob->scbob_y + bob->scbob_height;
2963 Scalos_InitRastPort(&rp);
2964 Scalos_SetFont(&rp, iwt->iwt_IconFont, &iwt->iwt_IconTTFont);
2965 SetABPenDrMd(&rp, PalettePrefs.pal_PensList[PENIDX_DRAGINFOTEXT_TEXT],
2966 PalettePrefs.pal_PensList[PENIDX_DRAGINFOTEXT_BG], JAM1);
2968 for (n=0; n<3; n++)
2970 if (*TextBuffer[n])
2971 Scalos_TextExtent(&rp, TextBuffer[n], strlen(TextBuffer[n]), &tExt[n]);
2974 Width = Height = 0;
2975 for (n=0; n<3; n++)
2977 if (tExt[n].te_Width > Width)
2978 Width = tExt[n].te_Width;
2980 Height += tExt[n].te_Height;
2983 bm = AllocBitMap(Width, Height,
2984 GetBitMapAttr(iwt->iwt_myDragHandle->drgh_screen->RastPort.BitMap, BMA_DEPTH),
2985 BMF_STANDARD,
2986 iwt->iwt_myDragHandle->drgh_screen->RastPort.BitMap);
2987 if (NULL == bm)
2988 break;
2990 rp.BitMap = bm;
2992 SetRast(&rp, PalettePrefs.pal_PensList[PENIDX_DRAGINFOTEXT_BG]);
2994 y = Scalos_GetFontBaseline(&rp);
2995 for (n=0; n<3; n++)
2997 x = (Width - tExt[n].te_Width) / 2 - tExt[n].te_Extent.MinX;
2999 Move(&rp, x, y);
3000 Scalos_Text(&rp, TextBuffer[n], strlen(TextBuffer[n]));
3002 y += tExt[n].te_Height;
3005 Success = SCA_AddBob(iwt->iwt_myDragHandle,
3006 bm, Mask,
3007 Width, Height,
3008 - Width / 2, yMax + 1);
3010 bob = internalAddBob(iwt->iwt_myDragHandle,
3011 &iwt->iwt_myDragHandle->drgh_boblist,
3012 bm, Mask, NULL,
3013 Width, Height,
3014 Width, Height,
3016 - Width / 2, yMax + 1);
3017 if (bob)
3019 Success = TRUE;
3020 bob->scbob_Flags |= BOBFLAGF_NeverTransparent | BOBFLAGF_NoOptimize;
3023 Scalos_DoneRastPort(&rp);
3024 } while (0);
3026 if (bm)
3027 FreeBitMap(bm);
3029 for (n=0; n<3; n++)
3031 if (TextBuffer[n])
3032 FreePathBuffer(TextBuffer[n]);
3035 return Success;
3039 static void CountDragObjects(struct DragHandle *drgh, const struct ScaIconNode *in)
3041 if (in->in_DeviceIcon)
3042 drgh->drgh_DeviceCount++;
3043 else
3045 if (in->in_Flags & INF_File)
3046 drgh->drgh_FileCount++;
3047 else
3048 drgh->drgh_DrawerCount++;
3053 void BlitARGB(ULONG SrcWidth, ULONG SrcHeight,
3054 const struct ARGB *Src, LONG SrcLeft, LONG SrcTop,
3055 ULONG DestWidth, struct ARGB *Dest, LONG DestLeft, LONG DestTop,
3056 ULONG Trans)
3058 ULONG y;
3059 ULONG a;
3060 ULONG mla;
3063 a = Trans + 1;
3064 mla = 257 - a;
3066 Src += SrcTop * SrcWidth;
3067 Dest += DestTop * DestWidth;
3069 for (y=0; y<SrcHeight; y++)
3071 ULONG x;
3072 const struct ARGB *SrcPtr = Src + SrcLeft;
3073 struct ARGB *DestPtr = Dest + DestLeft;
3075 for (x=0; x<SrcWidth; x++)
3077 d1(KPrintF("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, x, y));
3079 switch (a)
3081 case 0:
3082 case 1:
3083 break;
3084 case ALPHA_OPAQUE:
3085 *DestPtr = *SrcPtr;
3086 break;
3087 default:
3088 DestPtr->Red = (a * SrcPtr->Red + mla * DestPtr->Red) >> 8;
3089 DestPtr->Green = (a * SrcPtr->Green + mla * DestPtr->Green) >> 8;
3090 DestPtr->Blue = (a * SrcPtr->Blue + mla * DestPtr->Blue) >> 8;
3091 break;
3094 SrcPtr++;
3095 DestPtr++;
3098 Src += SrcWidth;
3099 Dest += DestWidth;
3101 d1(KPrintF("%s/%s/%ld: ny=%ld\n", __FILE__, __FUNC__, __LINE__, ny));
3106 void BlitARGBMask(ULONG SrcWidth, ULONG SrcHeight,
3107 const struct ARGB *Src, LONG SrcLeft, LONG SrcTop,
3108 ULONG DestWidth, struct ARGB *Dest, LONG DestLeft, LONG DestTop,
3109 const struct BitMap *MaskBM, ULONG Trans)
3111 UWORD MaskBytesPerRow = MaskBM->BytesPerRow;
3112 const UBYTE *Mask = MaskBM->Planes[0];
3113 ULONG y;
3114 ULONG a;
3117 d1(kprintf("%s/%s/%ld: Mask=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
3118 Mask[0], Mask[1], Mask[2], Mask[3], \
3119 Mask[4], Mask[5], Mask[6], Mask[7]));
3120 d1(kprintf("%s/%s/%ld: Mask=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
3121 Mask[8], Mask[9], Mask[10], Mask[11], \
3122 Mask[12], Mask[13], Mask[14], Mask[15]));
3124 d1(kprintf("%s/%s/%ld: Mask=%08lx MaskBytesPerRow=%ld\n", __FILE__, __FUNC__, __LINE__, Mask, MaskBytesPerRow ));
3126 a = Trans + 1;
3128 if ( a > 1)
3130 ULONG mla = 257 - a;
3132 Src += SrcTop * SrcWidth;
3133 Dest += DestTop * DestWidth;
3135 for (y=0; y<SrcHeight; y++)
3137 ULONG x;
3138 UWORD BitMask = 0x0080;
3139 const UBYTE *MaskPtr2 = Mask;
3140 const struct ARGB *SrcPtr = Src + SrcLeft;
3141 struct ARGB *DestPtr = Dest + DestLeft;
3143 for (x=0; x<SrcWidth; x++)
3145 d1(kprintf("%s/%s/%ld: x=%ld y=%ld Mask=%08lx *MaskPtr2=%02lx BitMask=%02lx\n", __FILE__, __FUNC__, __LINE__, x, y, Mask, *MaskPtr2, BitMask));
3147 if (*MaskPtr2 & BitMask)
3149 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
3150 d1(kprintf("%s/%s/%ld: x=%ld y=%ld *Mask=%02lx BitMask=%02lx\n", __FILE__, __FUNC__, __LINE__, x, y, *Mask, BitMask));
3152 switch (a)
3154 case 0:
3155 case 1:
3156 break;
3157 case ALPHA_OPAQUE:
3158 *DestPtr = *SrcPtr;
3159 break;
3160 default:
3161 DestPtr->Red = (a * SrcPtr->Red + mla * DestPtr->Red) >> 8;
3162 DestPtr->Green = (a * SrcPtr->Green + mla * DestPtr->Green) >> 8;
3163 DestPtr->Blue = (a * SrcPtr->Blue + mla * DestPtr->Blue) >> 8;
3164 break;
3168 SrcPtr++;
3169 DestPtr++;
3171 BitMask >>= 1;
3172 if (0 == BitMask)
3174 BitMask = 0x0080;
3175 MaskPtr2++;
3179 Mask += MaskBytesPerRow;
3180 Src += SrcWidth;
3181 Dest += DestWidth;
3183 d1(kprintf("%s/%s/%ld: ny=%ld Mask=%08lx\n", __FILE__, __FUNC__, __LINE__, ny, mask));
3189 static void BlitARGBMaskAlpha(ULONG SrcWidth, ULONG SrcHeight,
3190 const struct ARGB *Src, LONG SrcLeft, LONG SrcTop,
3191 ULONG DestWidth, struct ARGB *Dest, LONG DestLeft, LONG DestTop,
3192 const struct BitMap *MaskBM, ULONG Trans,
3193 const UBYTE *Alpha, LONG AlphaLeft, ULONG AlphaWidth)
3195 UWORD MaskBytesPerRow = MaskBM->BytesPerRow;
3196 const UBYTE *Mask = MaskBM->Planes[0];
3197 ULONG y;
3200 d1(kprintf("%s/%s/%ld: Mask=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
3201 Mask[0], Mask[1], Mask[2], Mask[3], \
3202 Mask[4], Mask[5], Mask[6], Mask[7]));
3203 d1(kprintf("%s/%s/%ld: Mask=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
3204 Mask[8], Mask[9], Mask[10], Mask[11], \
3205 Mask[12], Mask[13], Mask[14], Mask[15]));
3207 d1(kprintf("%s/%s/%ld: SrcWidth=%ld BoundsWidth=%ld Left=%ld\n", __FILE__, __FUNC__, __LINE__, SrcWidth, BoundsWidth, Left));
3209 Src += SrcTop * SrcWidth;
3210 Dest += DestTop * DestWidth;
3212 d1(kprintf("%s/%s/%ld: SrcLeft=%ld SrcTop=%ld DestLeft=%ld DestTop=%08ld\n", \
3213 __FILE__, __FUNC__, __LINE__, SrcLeft, SrcTop, DestLeft, DestTop));
3214 d1(kprintf("%s/%s/%ld: Src=%08lx Dest=%08lx\n", __FILE__, __FUNC__, __LINE__, Src, Dest));
3216 for (y=0; y < SrcHeight; y++)
3218 ULONG x;
3219 UWORD BitMask = 0x0080;
3220 const UBYTE *MaskPtr2 = Mask;
3221 const struct ARGB *SrcPtr = Src + SrcLeft;
3222 struct ARGB *DestPtr = Dest + DestLeft;
3223 const UBYTE *AlphaPtr = Alpha + AlphaLeft;
3225 for (x=0; x < SrcWidth; x++)
3227 d1(kprintf("%s/%s/%ld: x=%ld y=%ld MaskPtr2=%08lx *MaskPtr2=%02lx BitMask=%02lx\n", \
3228 __FILE__, __FUNC__, __LINE__, x, y, MaskPtr2, *MaskPtr2, BitMask));
3230 if (*MaskPtr2 & BitMask)
3232 ULONG a;
3233 ULONG mla;
3235 d1(kprintf("%s/%s/%ld: x=%ld y=%ld *Mask=%02lx BitMask=%02lx\n", __FILE__, __FUNC__, __LINE__, x, y, *Mask, BitMask));
3237 a = (ULONG) *AlphaPtr;
3238 a = ((Trans * a) >> 8) + 1;
3240 switch (a)
3242 case 0:
3243 case 1:
3244 break;
3245 case ALPHA_OPAQUE:
3246 *DestPtr = *SrcPtr;
3247 break;
3248 default:
3249 mla = 257 - a;
3250 DestPtr->Red = (a * SrcPtr->Red + mla * DestPtr->Red) >> 8;
3251 DestPtr->Green = (a * SrcPtr->Green + mla * DestPtr->Green) >> 8;
3252 DestPtr->Blue = (a * SrcPtr->Blue + mla * DestPtr->Blue) >> 8;
3253 break;
3257 SrcPtr++;
3258 DestPtr++;
3259 AlphaPtr++;
3261 BitMask >>= 1;
3262 if (0 == BitMask)
3264 BitMask = 0x0080;
3265 MaskPtr2++;
3269 Alpha += AlphaWidth;
3270 Mask += MaskBytesPerRow;
3271 Src += SrcWidth;
3272 Dest += DestWidth;
3274 d1(kprintf("%s/%s/%ld: ny=%ld Mask=%08lx\n", __FILE__, __FUNC__, __LINE__, ny, mask));
3278 //----------------------------------------------------------------------------
3279 #if 0
3280 static void DumpBitMap(struct BitMap *bm)
3282 struct RastPort rp;
3283 ULONG y;
3284 LONG Width, Height, Depth;
3286 Width = GetBitMapAttr(bm, BMA_WIDTH);
3287 Height = GetBitMapAttr(bm, BMA_HEIGHT);
3288 Depth = GetBitMapAttr(bm, BMA_DEPTH);
3290 KPrintF("%s/%s/%ld: START Width=%ld Height=%ld Depth=%ld\n", __FILE__, __FUNC__, __LINE__, Width, Height, Depth);
3292 InitRastPort(&rp);
3293 rp.BitMap = bm;
3295 for (y = 0; y < Height; y++)
3297 ULONG x;
3299 for (x = 0; x < Width; x++)
3301 ULONG px = ReadPixel(&rp, x, y);
3303 KPrintF("%ld ", px);
3306 KPrintF("\n");
3309 KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__);
3311 #endif
3312 //----------------------------------------------------------------------------