forwarding build fix when MUIA_Scrollgroup_AutoBars is defined (NicJA).
[AROS-Contrib.git] / scalos / main / DragDropBobs.c
blob5a706eec2ec039a276eb78645d16f24dd563295c
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 #ifdef DEBUG_SCALOS
148 static void DumpBitMap(struct BitMap *bm);
149 #endif
151 //----------------------------------------------------------------------------
153 // local data
155 static struct Hook CompareLeftUpHook =
157 { NULL, NULL },
158 HOOKFUNC_DEF(CompareLeftUpFunc), // h_Entry + h_SubEntry
159 NULL, // h_Data
162 //----------------------------------------------------------------------------
165 void InitDrag(struct IntuiMessage *iMsg, struct internalScaWindowTask *iwt)
167 struct ExtGadget *mgg = (struct ExtGadget *) iwt->iwt_LastIcon; // Icon directly under mouse
168 struct ScaIconNode *in;
169 struct RastPort rp;
170 LONG x, y;
171 LONG x0 = 0, y0 = 0; // Left/Top Edge of icon directly under mouse
172 LONG n;
174 iwt->iwt_WinUnderPtr = NULL; // +jl+ 20010405
175 iwt->iwt_IconUnderPtr = NULL;
176 iwt->iwt_ObjectUnderMouse = OUM_nothing;
178 iwt->iwt_RemIconsFlag = FALSE;
180 iwt->iwt_StartDragMouseX = iMsg->MouseX;
181 iwt->iwt_StartDragMouseY = iMsg->MouseY;
183 x = iwt->iwt_InnerLeft - iwt->iwt_WindowTask.wt_XOffset - iMsg->MouseX;
184 y = iwt->iwt_InnerTop - iwt->iwt_WindowTask.wt_YOffset - iMsg->MouseY;
186 switch (CurrentPrefs.pref_DragType)
188 case DRAGTYPE_ImageOnly:
189 x0 = x + mgg->LeftEdge;
190 y0 = y + mgg->TopEdge;
191 break;
193 case DRAGTYPE_ImageAndText:
194 x0 = x + mgg->BoundsLeftEdge;
195 y0 = y + mgg->BoundsTopEdge;
196 break;
199 d1(KPrintF("%s/%s/%ld: x=%ld y=%ld MouseX=%ld MouseY=%ld\n", __FILE__, __FUNC__, __LINE__, x, y, iMsg->MouseX, iMsg->MouseY));
201 Scalos_InitRastPort(&rp);
202 Scalos_SetFont(&rp, iwt->iwt_IconFont, &iwt->iwt_IconTTFont);
203 SetABPenDrMd(&rp, FontPrefs.fprf_FontFrontPen, FontPrefs.fprf_FontBackPen, FontPrefs.fprf_TextDrawModeSel);
205 SCA_FreeAllNodes((struct ScalosNodeList *) &iwt->iwt_DragNodeList);
207 iwt->iwt_myDragHandle = SCA_InitDrag(iwt->iwt_WinScreen);
208 if (NULL == iwt->iwt_myDragHandle)
209 return;
211 iwt->iwt_myDragHandle->drgh_iwt = iwt;
213 iwt->iwt_IconListDDLocked = TRUE;
214 ScalosLockIconListExclusive(iwt);
216 iwt->iwt_myDragHandle->drgh_FileCount = 0;
217 iwt->iwt_myDragHandle->drgh_DrawerCount = 0;
218 iwt->iwt_myDragHandle->drgh_DeviceCount = 0;
220 ScalosObtainSemaphore(&iwt->iwt_myDragHandle->drgh_BobListSemaphore);
222 if (CurrentPrefs.pref_UseOldDragIcons)
224 for (in=iwt->iwt_WindowTask.wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
226 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
228 if (gg->Flags & GFLG_SELECTED)
230 // count devices, drawers and files
231 CountDragObjects(iwt->iwt_myDragHandle, in);
233 switch (CurrentPrefs.pref_DragType)
235 case DRAGTYPE_ImageOnly:
236 x0 = x + gg->LeftEdge;
237 y0 = y + gg->TopEdge;
238 break;
240 case DRAGTYPE_ImageAndText:
241 x0 = x + gg->BoundsLeftEdge;
242 y0 = y + gg->BoundsTopEdge;
243 break;
246 AppendDragNode(iwt, &rp, in, 0, x, y, x0, y0);
247 ClassSelectIcon(iwt->iwt_WindowTask.mt_WindowStruct, in, FALSE);
251 else
253 // add every selected icon except icon under mouse
254 for (n=1, in=iwt->iwt_WindowTask.wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
256 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
258 if (gg != mgg && (gg->Flags & GFLG_SELECTED))
260 // count devices, drawers and files
261 CountDragObjects(iwt->iwt_myDragHandle, in);
263 AppendDragNode(iwt, &rp, in, n, x, y, x0 + 5 * n, y0 - 5 * n);
264 ClassSelectIcon(iwt->iwt_WindowTask.mt_WindowStruct, in, FALSE);
265 n++;
269 // Finally, add icon under mouse
270 // so that it is being drawn on top of the bob stack
271 for (in=iwt->iwt_WindowTask.wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
273 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
275 if (gg == mgg)
277 // count devices, drawers and files
278 CountDragObjects(iwt->iwt_myDragHandle, in);
280 AppendDragNode(iwt, &rp, in, 0, x, y, x0, y0);
281 ClassSelectIcon(iwt->iwt_WindowTask.mt_WindowStruct, in, FALSE);
282 break;
287 ScalosUnLockIconList(iwt);
289 if (CurrentPrefs.pref_ShowDDCountText)
290 AddInfoTextBob(iwt);
292 ScalosReleaseSemaphore(&iwt->iwt_myDragHandle->drgh_BobListSemaphore);
294 if (NULL == iwt->iwt_DragNodeList)
296 SCA_EndDrag(iwt->iwt_myDragHandle);
297 iwt->iwt_myDragHandle = NULL;
299 EndDragUnlock(iwt);
302 UpdateIconCount(iwt);
304 Scalos_DoneRastPort(&rp);
308 static void AppendDragNode(struct internalScaWindowTask *iwt, struct RastPort *rp,
309 struct ScaIconNode *in, LONG n, LONG x, LONG y, LONG x0, LONG y0)
311 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
312 struct DragNode *dgn = (struct DragNode *) SCA_AllocStdNode((struct ScalosNodeList *) &iwt->iwt_DragNodeList, NTYP_DragNode);
314 d1(KPrintF("%s/%s/%ld: DragNode=%08lx\n", __FILE__, __FUNC__, __LINE__, dgn));
315 d1(KPrintF("%s/%s/%ld: x=%ld y=%ld x0=%ld y0=%ld\n", __FILE__, __FUNC__, __LINE__, x, y, x0, y0));
317 if (dgn)
319 dgn->drgn_iconnode = in;
320 dgn->drgn_icon = in->in_Icon;
322 dgn->drgn_x = x + gg->LeftEdge;
323 dgn->drgn_y = y + gg->TopEdge;
325 dgn->drgn_DeltaX = -x0;
326 dgn->drgn_DeltaY = -y0;
328 if (n < 3)
330 if (in->in_Flags & INF_TextIcon)
332 InitDrag_ImageOnly(dgn, &iwt->iwt_myDragHandle->drgh_boblist, rp, iwt, x0, y0);
334 else
336 switch (CurrentPrefs.pref_DragType)
338 case DRAGTYPE_ImageOnly:
339 InitDrag_ImageOnly(dgn, &iwt->iwt_myDragHandle->drgh_boblist, rp, iwt, x0, y0);
340 break;
341 case DRAGTYPE_ImageAndText:
342 InitDrag_ImageAndText(dgn, &iwt->iwt_myDragHandle->drgh_boblist, rp, iwt, x0, y0);
343 break;
351 static struct ScaBob *InitDrag_ImageOnly(struct DragNode *dgn,
352 struct ScaBob **BobList,
353 struct RastPort *rp, struct internalScaWindowTask *iwt,
354 LONG x0, LONG y0)
356 struct ScaIconNode *in = dgn->drgn_iconnode;
357 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
358 struct ScaBob *bob;
359 WORD Width, Height;
360 WORD ggWidth;
361 struct BitMap *MaskBMSelected = NULL;
362 struct BitMap *MaskBM = NULL;
363 PLANEPTR MaskPlane = NULL;
364 const UBYTE *AlphaChannel = NULL;
365 LONG LeftSpace, TopSpace, RightSpace, BottomSpace;
367 LeftSpace = TopSpace = RightSpace = BottomSpace = 0;
369 if (in->in_Flags & INF_TextIcon)
371 Width = ggWidth = iwt->iwt_WidthArray[WIDTHARRAY_NAME];
372 d1(KPrintF("%s/%s/%ld: Width=%0ld\n", __FILE__, __FUNC__, __LINE__, Width));
374 else
376 ggWidth = gg->Width;
377 Width = gg->Width - LeftSpace - RightSpace;
380 Height = gg->Height - TopSpace - BottomSpace;
382 rp->BitMap = AllocBitMap(ggWidth, gg->Height,
383 GetBitMapAttr(iwt->iwt_WinScreen->RastPort.BitMap, BMA_DEPTH),
384 BMF_CLEAR | BMF_DISPLAYABLE | BMF_MINPLANES,
385 iwt->iwt_WinScreen->RastPort.BitMap);
386 if (NULL == rp->BitMap)
387 return NULL;
389 DoMethod(in->in_Icon, IDTM_Draw, iwt->iwt_WinScreen,
390 NULL, rp, iwt->iwt_WinDrawInfo,
391 0, 0,
392 IODRAWF_AbsolutePos | IODRAWF_NoText | IODRAWF_NoAlpha);
394 GetAttr((gg->Flags & GFLG_SELECTED) ? IDTA_MaskBM_Selected : IDTA_MaskBM_Normal,
395 in->in_Icon, (APTR) &MaskBMSelected);
397 d1(KPrintF("%s/%s/%ld: MaskBMSelected=%08lx\n", __FILE__, __FUNC__, __LINE__, MaskBMSelected));
398 d1(KPrintF("%s/%s/%ld: Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, gg->Width, gg->Height));
400 if (MaskBMSelected)
402 // adapt size of mask plane (Width,Height) to icon size (ggWidth,gg->Height)
404 MaskBM = AllocBitMap(ggWidth, gg->Height, 1, BMF_MINPLANES | BMF_CLEAR, NULL);
406 if (MaskBM)
408 d1(KPrintF("%s/%s/%ld: Mask=%08lx x=%ld y=%ld xb=%ld yb=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, MaskBMSelected, \
409 gg->LeftEdge, gg->TopEdge, \
410 gg->BoundsLeftEdge, gg->BoundsTopEdge,
411 Width, Height));
413 d1(DumpBitMap(MaskBMSelected));
415 BltBitMap(MaskBMSelected,
416 0, 0,
417 MaskBM,
418 LeftSpace, TopSpace,
419 Width, Height,
420 ABC | ABNC, ~0, NULL);
422 d1(DumpBitMap(MaskBM));
423 #if 0
425 struct RastPort rp;
427 InitRastPort(&rp);
428 rp.BitMap = MaskBM;
429 SetRast(&rp, 1);
431 #endif
432 MaskPlane = MaskBM->Planes[0];
434 d1(KPrintF("%s/%s/%ld: MaskPlane: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
435 __FILE__, __FUNC__, __LINE__, MaskPlane[0], MaskPlane[1], MaskPlane[2], MaskPlane[3],\
436 MaskPlane[4], MaskPlane[5], MaskPlane[6], MaskPlane[7]); \
437 kprintf("%s/%s/%ld: MaskPlane: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
438 __FILE__, __FUNC__, __LINE__, MaskPlane[8], MaskPlane[9], MaskPlane[10], MaskPlane[11], \
439 MaskPlane[12], MaskPlane[13], MaskPlane[14], MaskPlane[15]));
443 GetAttr(IDTA_AlphaChannel, in->in_Icon, (APTR) &AlphaChannel);
445 d1(if (AlphaChannel)\
447 kprintf("%s/%s/%ld: AlphaChannel: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
448 __FILE__, __FUNC__, __LINE__, AlphaChannel[0], AlphaChannel[1], AlphaChannel[2], AlphaChannel[3],\
449 AlphaChannel[4], AlphaChannel[5], AlphaChannel[6], AlphaChannel[7]);\
450 kprintf("%s/%s/%ld: AlphaChannel: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
451 __FILE__, __FUNC__, __LINE__, AlphaChannel[8], AlphaChannel[9], AlphaChannel[10], AlphaChannel[11],\
452 AlphaChannel[12], AlphaChannel[13], AlphaChannel[14], AlphaChannel[15]);\
453 kprintf("%s/%s/%ld: AlphaChannel: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
454 __FILE__, __FUNC__, __LINE__, AlphaChannel[16], AlphaChannel[17], AlphaChannel[18], AlphaChannel[19],\
455 AlphaChannel[20], AlphaChannel[21], AlphaChannel[22], AlphaChannel[23]);\
456 kprintf("%s/%s/%ld: AlphaChannel: %02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", \
457 __FILE__, __FUNC__, __LINE__, AlphaChannel[24], AlphaChannel[25], AlphaChannel[26], AlphaChannel[27],\
458 AlphaChannel[28], AlphaChannel[29], AlphaChannel[30], AlphaChannel[31]);\
461 bob = internalAddBob(iwt->iwt_myDragHandle,
462 BobList,
463 rp->BitMap, MaskPlane, AlphaChannel,
464 ggWidth, gg->Height,
465 gg->BoundsWidth, gg->BoundsHeight,
466 gg->LeftEdge - gg->BoundsLeftEdge,
467 x0, y0
470 if (MaskBM)
471 FreeBitMap(MaskBM);
473 FreeBitMap(rp->BitMap);
475 return bob;
479 static void InitDrag_ImageAndText(struct DragNode *dgn,
480 struct ScaBob **BobList,
481 struct RastPort *rp, struct internalScaWindowTask *iwt,
482 LONG x0, LONG y0)
484 struct ScaIconNode *in = dgn->drgn_iconnode;
485 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
486 const UBYTE *AlphaChannel = NULL;
487 struct BitMap *allocBM;
488 struct BitMap *MaskBM;
490 rp->BitMap = allocBM = AllocBitMap(gg->BoundsWidth, gg->BoundsHeight,
491 GetBitMapAttr(iwt->iwt_WinScreen->RastPort.BitMap, BMA_DEPTH),
492 BMF_CLEAR | BMF_DISPLAYABLE | BMF_MINPLANES,
493 iwt->iwt_WinScreen->RastPort.BitMap);
494 if (NULL == rp->BitMap)
495 return;
497 DoMethod(in->in_Icon, IDTM_Draw, iwt->iwt_WinScreen,
498 NULL, rp, iwt->iwt_WinDrawInfo,
499 0, 0, IODRAWF_AbsolutePos | IODRAWF_NoAlpha);
501 GetAttr(IDTA_AlphaChannel, in->in_Icon, (APTR) &AlphaChannel);
503 MaskBM = AllocBitMap(gg->BoundsWidth, gg->BoundsHeight, 1, BMF_CLEAR, NULL);
504 rp->BitMap = MaskBM;
505 if (MaskBM)
507 struct BitMap *MaskBMSelected = NULL;
509 SetAPen(rp, 1);
510 SetBPen(rp, 1);
512 GetAttr((gg->Flags & GFLG_SELECTED) ? IDTA_MaskBM_Selected : IDTA_MaskBM_Normal,
513 in->in_Icon, (APTR) &MaskBMSelected);
515 d1(kprintf("%s/%s/%ld: Mask=%08lx x=%ld y=%ld xb=%ld yb=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, MaskBMSelected, \
516 gg->LeftEdge, gg->TopEdge, \
517 gg->BoundsLeftEdge, gg->BoundsTopEdge,
518 gg->Width, gg->Height));
520 if (MaskBMSelected)
522 LONG LeftSpace, TopSpace, RightSpace, BottomSpace;
523 WORD Width, Height;
525 LeftSpace = TopSpace = RightSpace = BottomSpace = 0;
527 Width = gg->Width - LeftSpace - RightSpace;
528 Height = gg->Height - TopSpace - BottomSpace;
530 BltBitMap(MaskBMSelected, 0, 0, MaskBM,
531 gg->LeftEdge - gg->BoundsLeftEdge + LeftSpace,
532 gg->TopEdge - gg->BoundsTopEdge + TopSpace,
533 Width, Height,
534 ABC | ABNC, ~0, NULL);
536 else
538 d1(kprintf("%s/%s/%ld: x1=%ld y1=%ld x2=%ld y2=%ld\n", __FILE__, __FUNC__, __LINE__, \
539 gg->LeftEdge - gg->BoundsLeftEdge,\
540 gg->TopEdge - gg->BoundsTopEdge,\
541 gg->Width - 1, gg->Height - 1));
543 RectFill(rp, gg->LeftEdge - gg->BoundsLeftEdge,
544 gg->TopEdge - gg->BoundsTopEdge,
545 gg->LeftEdge - gg->BoundsLeftEdge + gg->Width - 1,
546 gg->TopEdge - gg->BoundsTopEdge + gg->Height - 1);
548 // .maskok2:
549 SetAttrs(in->in_Icon,
550 IDTA_TextPen, 1,
551 IDTA_TextPenSel, 1,
552 IDTA_TextPenShadow, 1,
553 IDTA_TextPenOutline, 1,
554 IDTA_TextDrawMode, JAM1,
555 TAG_END);
557 // add icon text to mask
558 DoMethod(in->in_Icon, IDTM_Draw, iwt->iwt_WinScreen,
559 NULL, rp, iwt->iwt_WinDrawInfo, 0, 0,
560 IODRAWF_NoImage | IODRAWF_AbsolutePos | IODRAWF_NoAlpha);
562 // restore original settings
563 SetAttrs(in->in_Icon,
564 IDTA_TextPen, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPEN],
565 IDTA_TextPenSel, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPENSEL],
566 IDTA_TextPenShadow, PalettePrefs.pal_PensList[PENIDX_ICONTEXTSHADOWPEN],
567 IDTA_TextPenOutline, PalettePrefs.pal_PensList[PENIDX_ICONTEXTOUTLINEPEN],
568 IDTA_TextDrawMode, FontPrefs.fprf_TextDrawMode,
569 TAG_END);
571 SetABPenDrMd(rp, FontPrefs.fprf_FontFrontPen, FontPrefs.fprf_FontBackPen, FontPrefs.fprf_TextDrawModeSel);
574 // .maskok:
575 internalAddBob(iwt->iwt_myDragHandle, BobList,
576 allocBM, rp->BitMap->Planes[0], AlphaChannel,
577 gg->BoundsWidth, gg->BoundsHeight,
578 gg->BoundsWidth, gg->BoundsHeight,
580 x0, y0
583 if (MaskBM)
584 FreeBitMap(MaskBM);
585 FreeBitMap(allocBM);
589 void RestoreDragIcons(struct internalScaWindowTask *iwt)
591 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
593 if (IsIwtViewByIcon(iwt) && CurrentPrefs.pref_AutoRemoveFlag && iwt->iwt_RemIconsFlag && iwt->iwt_DragIconList)
595 struct ScaIconNode *FirstIcon = iwt->iwt_DragIconList;
597 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
599 while (iwt->iwt_DragIconList)
601 d1(kprintf("%s/%s/%ld: Icon=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_DragIconList, GetIconName(iwt->iwt_DragIconList)));
603 SCA_MoveIconNode(&iwt->iwt_DragIconList, &iwt->iwt_WindowTask.wt_IconList, iwt->iwt_DragIconList);
606 RefreshIconList(iwt, FirstIcon, NULL);
608 iwt->iwt_RemIconsFlag = FALSE;
612 void DrawDrag(ULONG DrawFlags, struct internalScaWindowTask *iwt)
614 d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
616 if (IsIwtViewByIcon(iwt) && CurrentPrefs.pref_AutoRemoveFlag && !iwt->iwt_RemIconsFlag)
618 struct DragNode *dn;
620 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
622 for (dn = iwt->iwt_DragNodeList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
624 d1(kprintf("%s/%s/%ld: Icon=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, dn->drgn_iconnode, GetIconName(dn->drgn_iconnode)));
626 SCA_MoveIconNode(&iwt->iwt_WindowTask.wt_IconList, &iwt->iwt_DragIconList, dn->drgn_iconnode);
629 ScalosObtainSemaphore(&iwt->iwt_UpdateSemaphore);
631 RemoveIcons(iwt, &iwt->iwt_DragIconList);
632 DrawIconListShadows(iwt, &iwt->iwt_DragIconList);
634 ScalosReleaseSemaphore(&iwt->iwt_UpdateSemaphore);
636 iwt->iwt_RemIconsFlag = TRUE;
639 if (!(DrawFlags & SCAF_Drag_NoDrawDrag))
641 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
642 SCA_DrawDrag(iwt->iwt_myDragHandle, iwt->iwt_WinScreen->MouseX,
643 iwt->iwt_WinScreen->MouseY, DrawFlags & ~SCAF_Drag_NoDrawDrag);
646 d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
650 static void DrawIconListShadows(struct internalScaWindowTask *iwt, struct ScaIconNode **IconList)
652 struct ScaIconNode *in;
653 ULONG ScreenDepth;
654 struct RastPort rpMask;
655 struct RastPort rp;
657 d1(kprintf("\n" "%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
659 Scalos_InitRastPort(&rp);
660 Scalos_SetFont(&rp, iwt->iwt_IconFont, &iwt->iwt_IconTTFont);
662 Scalos_InitRastPort(&rpMask);
663 Scalos_SetFont(&rpMask, iwt->iwt_IconFont, &iwt->iwt_IconTTFont);
665 ScreenDepth = GetBitMapAttr(iInfos.xii_iinfos.ii_Screen->RastPort.BitMap, BMA_DEPTH);
667 iwt->iwt_IconShadowVisible = TRUE;
669 for (in = *IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
671 d1(kprintf("%s/%s/%ld: in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, in, GetIconName(in)));
672 DrawIconObjectTransparent(iwt, in->in_Icon, ScreenDepth, &rp, &rpMask,
673 CurrentPrefs.pref_IconShadowTransparency, CurrentPrefs.pref_RealTransFlag);
676 Scalos_DoneRastPort(&rpMask);
677 Scalos_DoneRastPort(&rp);
681 void DragRefreshIcons(struct internalScaWindowTask *iwt)
683 struct RastPort *rp = iwt->iwt_WindowTask.wt_Window->RPort;
684 struct DragNode *dn;
686 SetABPenDrMd(rp, FontPrefs.fprf_FontFrontPen, FontPrefs.fprf_FontBackPen, FontPrefs.fprf_TextDrawMode);
688 for (dn = iwt->iwt_DragNodeList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
690 if (dn->drgn_icon)
692 DoMethod((Object *) dn->drgn_icon,
693 IDTM_Draw, iwt->iwt_WinScreen,
694 iwt->iwt_WindowTask.wt_Window, rp,
695 iwt->iwt_WinDrawInfo,
696 iwt->iwt_InnerLeft - iwt->iwt_WindowTask.wt_XOffset,
697 iwt->iwt_InnerTop - iwt->iwt_WindowTask.wt_YOffset,
705 LIBFUNC_P8(BOOL, sca_AddBob,
706 A0, struct DragHandle *, dh,
707 A1, struct BitMap *, bm,
708 A2, APTR, Mask,
709 D0, ULONG, Width,
710 D1, ULONG, Height,
711 D2, LONG, XOffset,
712 D3, LONG, YOffset,
713 A6, struct ScalosBase *, ScalosBase, 0)
715 (void) ScalosBase;
717 return (BOOL) (internalAddBob(dh,
718 &dh->drgh_boblist,
719 bm, Mask, NULL,
720 Width, Height,
721 Width, Height,
723 XOffset, YOffset) != NULL);
725 LIBFUNC_END
728 static struct ScaBob *internalAddBob(struct DragHandle *dh,
729 struct ScaBob **BobList,
730 struct BitMap *bm, APTR Mask, const UBYTE *AlphaChannel,
731 ULONG Width, ULONG Height,
732 ULONG BoundsWidth, ULONG BoundsHeight,
733 WORD LeftBorder,
734 LONG XOffset, LONG YOffset)
736 struct ScaBob *Result = NULL;
737 struct ScaBob *bob;
739 if (dh->drgh_flags & DRGHF_CustomBob)
741 return sca_AddBobCustom((struct DragHandle *) dh, BobList, bm,
742 Mask, AlphaChannel,
743 Width, Height,
744 BoundsWidth, BoundsHeight,
745 LeftBorder,
746 XOffset, YOffset);
749 d1(kprintf("%s/%s/%ld: x=%ld y=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, XOffset, YOffset, Width, Height));
751 do {
752 struct BitMap tempBM;
753 ULONG n, PlaneSize;
754 ULONG AllocLen;
755 UBYTE *bp;
756 UWORD Pattern, EndMask;
757 UWORD *pw1, *pw2, *pwm;
758 UWORD y, xMax;
760 bob = (struct ScaBob *) SCA_AllocNode((struct ScalosNodeList *) BobList,
761 sizeof(struct ScaBob) - sizeof(struct MinNode));
762 if (NULL == bob)
763 break;
765 bob->scbob_draghandle = dh;
766 bob->scbob_width = Width;
767 bob->scbob_height = Height;
768 bob->scbob_BoundsWidth = BoundsWidth;
769 bob->scbob_BoundsHeight = BoundsHeight;
770 bob->scbob_LeftBorder = LeftBorder;
771 bob->scbob_x = XOffset;
772 bob->scbob_y = YOffset;
773 bob->scbob_Bob.scbob_Bob1.scbob1_bob.BobVSprite = &bob->scbob_Bob.scbob_Bob1.scbob1_vsprite;
774 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.VSBob = &bob->scbob_Bob.scbob_Bob1.scbob1_bob;
776 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Width = ((Width + 15) & ~15) / 16;
777 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Height = Height;
778 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Depth = bm->Depth;
780 tempBM.BytesPerRow = ((Width + 15) & ~15) / 8;
781 tempBM.Rows = Height;
782 tempBM.Flags = 0;
783 tempBM.pad = 0;
784 tempBM.Depth = bm->Depth;
786 PlaneSize = tempBM.BytesPerRow * tempBM.Rows;
787 AllocLen = PlaneSize * bm->Depth;
789 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData = AllocVec(AllocLen,
790 MEMF_PUBLIC | ChipMemAttr() | MEMF_CLEAR);
791 if (NULL == bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData)
792 break;
794 bp = (UBYTE *) bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData;
795 for (n=0; n<8; n++)
797 if (n < bm->Depth)
799 tempBM.Planes[n] = bp;
800 bp += PlaneSize;
802 else
803 tempBM.Planes[n] = NULL;
806 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.PlanePick = ~(~0 << bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Depth);
808 BltBitMap(bm, 0, 0, &tempBM, 0, 0,
809 bob->scbob_width, bob->scbob_height,
810 ABC | ABNC, ~0, NULL);
812 bob->scbob_Bob.scbob_Bob1.scbob1_bob.SaveBuffer = AllocVec(AllocLen, MEMF_PUBLIC | ChipMemAttr());
813 if (NULL == bob->scbob_Bob.scbob_Bob1.scbob1_bob.SaveBuffer)
814 break;
816 bob->scbob_Bob.scbob_Bob1.scbob1_shadow1 = AllocVec(PlaneSize, MEMF_PUBLIC | ChipMemAttr());
817 if (NULL == bob->scbob_Bob.scbob_Bob1.scbob1_shadow1)
818 break;
820 bob->scbob_Bob.scbob_Bob1.scbob1_shadow2 = AllocVec(PlaneSize, MEMF_PUBLIC | ChipMemAttr());
821 if (NULL == bob->scbob_Bob.scbob_Bob1.scbob1_shadow2)
822 break;
824 xMax = ((bob->scbob_width + 15) & ~15) / 16;
825 Pattern = 0xaaaa;
827 pw1 = (UWORD *) bob->scbob_Bob.scbob_Bob1.scbob1_shadow1;
828 pw2 = (UWORD *) bob->scbob_Bob.scbob_Bob1.scbob1_shadow2;
829 pwm = (UWORD *) Mask;
831 d1(kprintf("%s/%s/%ld: PlaneSize=%ld Width=%ld xMax=%ld\n", __FILE__, __FUNC__, __LINE__, PlaneSize, Width, xMax));
833 EndMask = ~0 << (((bob->scbob_width + 15) & ~15) - bob->scbob_width);
835 for (y=0; y<bob->scbob_height; y++)
837 UWORD x;
839 for (x=0; x < xMax - 1; x++)
841 *pw1++ = 0xffff;
842 *pw2++ = Pattern;
844 if (Mask)
846 pw1[-1] &= *pwm;
847 pw2[-1] &= *pwm;
848 pwm++;
851 *pw1++ = EndMask;
852 *pw2 = EndMask;
853 *pw2++ &= Pattern;
855 if (Mask)
857 pw1[-1] &= *pwm;
858 pw2[-1] &= *pwm;
859 pwm++;
862 Pattern ^= 0xffff;
865 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Flags = SAVEBACK | OVERLAY;
866 bob->scbob_Bob.scbob_Bob1.scbob1_bob.ImageShadow = bob->scbob_Bob.scbob_Bob1.scbob1_shadow1;
868 // only add bobs which are to be added to drgh_boblist
869 // (e.g. do not add special bobs !!)
870 if (BobList == &dh->drgh_boblist)
871 AddBob(&bob->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort);
873 Result = bob;
874 bob = NULL;
875 } while (0);
877 if (bob)
878 FreeBobNode((struct ScalosNodeList *) BobList, bob);
880 return Result;
884 static void FreeBobNode(struct ScalosNodeList *nodeList, struct ScaBob *bob)
886 if (NULL == bob)
887 return;
889 if (bob->scbob_Bob.scbob_Bob1.scbob1_shadow1)
891 FreeVec(bob->scbob_Bob.scbob_Bob1.scbob1_shadow1);
892 bob->scbob_Bob.scbob_Bob1.scbob1_shadow1 = NULL;
894 if (bob->scbob_Bob.scbob_Bob1.scbob1_shadow2)
896 FreeVec(bob->scbob_Bob.scbob_Bob1.scbob1_shadow2);
897 bob->scbob_Bob.scbob_Bob1.scbob1_shadow2 = NULL;
899 if (bob->scbob_Bob.scbob_Bob1.scbob1_bob.SaveBuffer)
901 FreeVec(bob->scbob_Bob.scbob_Bob1.scbob1_bob.SaveBuffer);
902 bob->scbob_Bob.scbob_Bob1.scbob1_bob.SaveBuffer = NULL;
904 if (bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData)
906 FreeVec(bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData);
907 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.ImageData = NULL;
909 if (bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel
910 && (bob->scbob_Flags & BOBFLAGF_FreeAlphaChannel))
912 ScalosFree((UBYTE *) bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel);
913 bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel = NULL;
914 bob->scbob_Flags &= ~BOBFLAGF_FreeAlphaChannel;
917 SCA_FreeNode(nodeList, &bob->scbob_Node);
921 static void FreeCustomBobNode(struct ScalosNodeList *nodeList, struct ScaBob *bob)
923 if (NULL == bob)
924 return;
926 if (bob->scbob_Bob.scbob_Bob2.scbob2_bitmap)
928 FreeBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_bitmap);
929 bob->scbob_Bob.scbob_Bob2.scbob2_bitmap = NULL;
931 if (bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap)
933 FreeBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap);
934 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap = NULL;
936 if (bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2)
938 FreeBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2);
939 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2 = NULL;
941 if (bob->scbob_Bob.scbob_Bob2.scbob2_shadow1)
943 FreeBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_shadow1);
944 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1 = NULL;
946 if (bob->scbob_Bob.scbob_Bob2.scbob2_shadow2)
948 FreeBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_shadow2);
949 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2 = NULL;
952 SCA_FreeNode(nodeList, &bob->scbob_Node);
956 static struct ScaBob *sca_AddBobCustom(struct DragHandle *dh,
957 struct ScaBob **BobList,
958 struct BitMap *bm, APTR Mask, const UBYTE *AlphaChannel,
959 ULONG Width, ULONG Height,
960 ULONG BoundsWidth, ULONG BoundsHeight,
961 WORD LeftBorder,
962 LONG XOffset, LONG YOffset)
964 struct ScaBob *bob;
965 struct ScaBob *Result = NULL;
966 struct BitMap *tempBM = NULL;
968 d1(KPrintF("%s/%s/%ld: x=%ld y=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, XOffset, YOffset, Width, Height));
970 do {
971 static UWORD Pattern[] = { 0xaaaa, 0x5555 };
972 struct RastPort rpMask;
974 bob = AllocBob2(dh, (struct ScalosNodeList *) BobList,
975 XOffset, YOffset, Width, Height, BoundsWidth, BoundsHeight);
976 if (NULL == bob)
977 break;
979 bob->scbob_LeftBorder = LeftBorder;
980 bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel = AlphaChannel;
982 tempBM = AllocBitMap(bob->scbob_width, bob->scbob_height, 1, BMF_MINPLANES | BMF_CLEAR, NULL);
983 if (NULL == tempBM)
984 break;
986 InitRastPort(&rpMask);
987 rpMask.BitMap = tempBM;
989 d1(KPrintF("%s/%s/%ld: Mask=%08lx BytesPerRow=%ld Rows=%ld\n", __FILE__, __FUNC__, __LINE__, Mask, tempBM->BytesPerRow, tempBM->Rows));
991 if (Mask)
993 SetABPenDrMd(&rpMask, 1, 0, JAM2);
994 BltTemplate((const PLANEPTR) Mask,
996 2 * ((bob->scbob_width + 15) / 16),
997 &rpMask,
998 0, 0,
999 bob->scbob_width,
1000 bob->scbob_height );
1002 else
1004 SetRast(&rpMask, 1);
1007 d1(DumpBitMap(tempBM));
1008 d1(KPrintF("%s/%s/%ld: Mask=%04lx %04lx %04lx %04lx %04lx %04lx %04lx %04lx \n", __FILE__, __FUNC__, __LINE__, \
1009 ((UWORD *) Mask)[0], ((UWORD *) Mask)[1], ((UWORD *) Mask)[2], ((UWORD *) Mask)[3], \
1010 ((UWORD *) Mask)[4], ((UWORD *) Mask)[5], ((UWORD *) Mask)[6], ((UWORD *) Mask)[7]));
1012 d1(KPrintF("%s/%s/%ld: Planes[0]=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
1013 tempBM->Planes[0][0], tempBM->Planes[0][1], \
1014 tempBM->Planes[0][2], tempBM->Planes[0][3], \
1015 tempBM->Planes[0][4], tempBM->Planes[0][5], \
1016 tempBM->Planes[0][6], tempBM->Planes[0][7]));
1018 BlitBob(bob, tempBM, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1);
1020 SetABPenDrMd(&rpMask, 0, 1, JAM1);
1021 SetAfPt(&rpMask, Pattern, 2);
1022 RectFill(&rpMask,
1023 0, 0,
1024 bob->scbob_width - 1, bob->scbob_height - 1);
1026 d1(DumpBitMap(tempBM));
1027 d1(KPrintF("%s/%s/%ld: Planes[0]=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
1028 tempBM->Planes[0][0], tempBM->Planes[0][1], \
1029 tempBM->Planes[0][2], tempBM->Planes[0][3], \
1030 tempBM->Planes[0][4], tempBM->Planes[0][5], \
1031 tempBM->Planes[0][6], tempBM->Planes[0][7]));
1033 BlitBob(bob, tempBM, bob->scbob_Bob.scbob_Bob2.scbob2_shadow2);
1035 d1(kprintf("%s/%s/%ld: Shadow1=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
1036 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][0], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][1], \
1037 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][2], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][3], \
1038 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][4], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][5], \
1039 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][6], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0][7]));
1040 d1(kprintf("%s/%s/%ld: Shadow2=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
1041 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][0], bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][1], \
1042 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][2], bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][3], \
1043 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][4], bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][5], \
1044 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][6], bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0][7]));
1046 BlitBob(bob, bm, bob->scbob_Bob.scbob_Bob2.scbob2_bitmap);
1048 SCA_SortNodes((struct ScalosNodeList *) BobList, &CompareLeftUpHook, SCA_SortType_Best);
1050 Result = bob;
1051 bob = NULL;
1052 } while (0);
1054 if (bob)
1055 FreeCustomBobNode((struct ScalosNodeList *) BobList, bob);
1056 if (tempBM)
1057 FreeBitMap(tempBM);
1059 return Result;
1063 static void BlitBob(struct ScaBob *bob, struct BitMap *bmSrc, struct BitMap *bmDest)
1065 BltBitMap(bmSrc, 0, 0,
1066 bmDest, 0, 0,
1067 bob->scbob_width, bob->scbob_height,
1068 ABC | ABNC, ~0, NULL);
1069 WaitBlit();
1073 static LONG CompareLeftUpFunc(const struct ScaBob *bob1, const struct ScaBob *bob2)
1075 d1(kprintf("%s/%s/%ld: bob2=%08lx bob2=%08lx\n", __FILE__, __FUNC__, __LINE__, bob1, bob2));
1077 if (bob2->scbob_x < bob1->scbob_x)
1078 return 1;
1079 else if (bob2->scbob_x > bob1->scbob_x)
1080 return -1;
1082 if (bob2->scbob_y < bob1->scbob_y)
1083 return 1;
1084 else if (bob2->scbob_y > bob1->scbob_y)
1085 return -1;
1087 return 0;
1091 BOOL SuspendDrag(struct DragHandle *dh, struct internalScaWindowTask *iwt)
1093 BOOL WasLocked = FALSE;
1095 d1(kprintf("%s/%s/%ld: START dh=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, dh, iwt->iwt_WinTitle));
1097 if (dh)
1099 if (!(dh->drgh_flags & DRGHF_LockSuspended))
1101 ClassHideDragBobs(iwt, dh);
1102 SetWindowPointer(iwt->iwt_WindowTask.wt_Window,
1103 WA_BusyPointer, TRUE,
1104 WA_PointerDelay, 0,
1105 TAG_END);
1106 WasLocked = SCA_UnlockDrag(dh);
1107 dh->drgh_flags |= DRGHF_LockSuspended;
1111 d1(kprintf("%s/%s/%ld: END dh=%08lx WasLocked=%ld\n", __FILE__, __FUNC__, __LINE__, dh, WasLocked));
1113 return WasLocked;
1117 void ResumeDrag(struct DragHandle *dh, struct internalScaWindowTask *iwt, BOOL wasLocked)
1119 d1(kprintf("%s/%s/%ld: START dh=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, dh, iwt->iwt_WinTitle));
1121 if (dh)
1123 if (dh->drgh_flags & DRGHF_LockSuspended)
1125 SetWindowPointer(iwt->iwt_WindowTask.wt_Window,
1126 WA_Pointer, NULL,
1127 TAG_END);
1128 dh->drgh_flags &= ~DRGHF_LockSuspended;
1129 ReLockDrag(dh, iwt, wasLocked);
1132 else
1134 SetWindowPointer(iwt->iwt_WindowTask.wt_Window,
1135 WA_Pointer, NULL,
1136 TAG_END);
1138 d1(kprintf("%s/%s/%ld: END dh=%08lx\n", __FILE__, __FUNC__, __LINE__, dh));
1142 void ReLockDrag(struct DragHandle *dh, struct internalScaWindowTask *iwt, BOOL wasLocked)
1144 d1(kprintf("%s/%s/%ld: START dh=%08lx\n", __FILE__, __FUNC__, __LINE__, dh));
1146 if (wasLocked && (iInfos.xii_GlobalDragHandle == dh) && dh)
1148 BOOL Locked2;
1149 BOOL Locked1 = dh->drgh_flags & DRGHF_LayersLocked;
1151 d1(kprintf("%s/%s/%ld: dh=%08lx drgh_flags=%08lx\n", __FILE__, __FUNC__, __LINE__, dh, dh->drgh_flags));
1153 #if defined(__MORPHOS__)
1154 if (DOSBase->dl_lib.lib_Version >= 51)
1156 WaitTOF();
1157 if (iwt)
1158 WaitBOVP(&iwt->iwt_WinScreen->ViewPort);
1160 #endif //defined(__MORPHOS__)
1161 SCA_LockDrag(dh);
1163 Locked2 = dh->drgh_flags & DRGHF_LayersLocked;
1165 if (iwt && Locked2 && !Locked1)
1167 SCA_DrawDrag(iwt->iwt_myDragHandle,
1168 iwt->iwt_WinScreen->MouseX,
1169 iwt->iwt_WinScreen->MouseY,
1173 d1(kprintf("%s/%s/%ld: dh=%08lx drgh_flags=%08lx\n", __FILE__, __FUNC__, __LINE__, dh, dh->drgh_flags));
1175 d1(kprintf("%s/%s/%ld: END dh=%08lx\n", __FILE__, __FUNC__, __LINE__, dh));
1179 LIBFUNC_P2(void, sca_LockDrag,
1180 A0, struct DragHandle *, dh,
1181 A6, struct ScalosBase *, ScalosBase, 0)
1183 (void) ScalosBase;
1185 if (dh)
1187 d1(kprintf("%s/%s/%ld: dh=%08lx drgh_flags=%08lx Task=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, \
1188 dh, dh->drgh_flags, FindTask(NULL), FindTask(NULL)->tc_Node.ln_Name));
1190 if (!(dh->drgh_flags & DRGHF_LockSuspended) && !(dh->drgh_flags & DRGHF_LayersLocked))
1192 d1(kprintf("%s/%s/%ld: dh=%08lx ScaLockScreenLayers\n", __FILE__, __FUNC__, __LINE__, dh));
1193 ScalosObtainSemaphore(&LayersSema);
1194 ScaLockScreenLayers();
1195 dh->drgh_flags |= DRGHF_LayersLocked;
1196 d1(kprintf("%s/%s/%ld: dh=%08lx ScaLockScreenLayers\n", __FILE__, __FUNC__, __LINE__, dh));
1200 LIBFUNC_END
1203 LIBFUNC_P2(ULONG, sca_UnlockDrag,
1204 A0, struct DragHandle *, dh,
1205 A6, struct ScalosBase *, ScalosBase, 0)
1207 ULONG WasLocked = FALSE;
1209 (void) ScalosBase;
1211 if (dh)
1213 d1(kprintf("%s/%s/%ld: dh=%08lx drgh_flags=%08lx Task=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, \
1214 dh, dh->drgh_flags, FindTask(NULL), FindTask(NULL)->tc_Node.ln_Name));
1215 WasLocked = TRUE;
1217 if (dh->drgh_flags & DRGHF_LayersLocked)
1219 d1(kprintf("%s/%s/%ld: dh=%08lx ScaUnlockScreenLayers\n", __FILE__, __FUNC__, __LINE__, dh));
1220 dh->drgh_flags &= ~DRGHF_LayersLocked;
1221 ScaUnlockScreenLayers();
1222 ScalosReleaseSemaphore(&LayersSema);
1223 d1(kprintf("%s/%s/%ld: dh=%08lx ScaUnlockScreenLayers\n", __FILE__, __FUNC__, __LINE__, dh));
1227 d1(kprintf("%s/%s/%ld: END WasLocked=%ld\n", __FILE__, __FUNC__, __LINE__, WasLocked));
1229 return WasLocked;
1231 LIBFUNC_END
1234 LIBFUNC_P5(void, sca_DrawDrag,
1235 A0, struct DragHandle *, dh,
1236 D0, LONG, XOffset,
1237 D1, LONG, YOffset,
1238 D2, ULONG, Flags,
1239 A6, struct ScalosBase *, ScalosBase, 0)
1241 (void) ScalosBase;
1243 d1(KPrintF("%s/%s/%ld: dh=%08lx x=%ld y=%ld Flags=%08lx\n", \
1244 __FILE__, __FUNC__, __FUNC__, __LINE__, dh, XOffset, YOffset, Flags));
1246 if (NULL == dh)
1247 return;
1249 if (dh->drgh_flags & DRGHF_LockSuspended)
1250 return;
1252 ScalosObtainSemaphore(&dh->drgh_BobListSemaphore);
1254 switch (CurrentPrefs.pref_DragTranspMode)
1256 case DRAGTRANSPMODE_SolidAndTransp:
1257 Flags ^= SCAF_Drag_Transparent;
1258 break;
1259 case DRAGTRANSPMODE_Solid:
1260 Flags &= ~SCAF_Drag_Transparent;
1261 break;
1262 case DRAGTRANSPMODE_Transp:
1263 Flags |= SCAF_Drag_Transparent;
1264 break;
1267 d1(KPrintF("%s/%s/%ld: dh=%08lx x=%ld y=%ld Flags=%08lx\n", \
1268 __FILE__, __FUNC__, __FUNC__, __LINE__, dh, XOffset, YOffset, Flags));
1270 if ((dh->drgh_flags & DRGHF_CustomBob) && !(dh->drgh_flags & DRGHF_BobsOptimized))
1272 OptimizeBobs((struct DragHandle *) dh);
1273 dh->drgh_flags |= DRGHF_BobsOptimized;
1276 if (!(dh->drgh_flags & DRGHF_LayersLocked))
1278 SCA_LockDrag(dh);
1281 if (dh->drgh_flags & DRGHF_CustomBob)
1283 sca_DrawDragCustom((struct DragHandle *) dh, XOffset, YOffset, Flags);
1285 else
1287 struct ScaBob *bob;
1289 CheckSpecialBob(dh, Flags & SCAF_Drag_NoDropHere, DRGHF_NoDropIndicatorVisible,
1290 &dh->drgh_Bob_NoDropIndicator, NAME_FORBIDDEN, NAME_FORBIDDEN_FALLBACK);
1291 CheckSpecialBob(dh, Flags & SCAF_Drag_IndicateCopy, DRGHF_CopyIndicatorVisible,
1292 &dh->drgh_Bob_CopyIndicator, NAME_COPYING, NAME_COPYING_FALLBACK);
1293 CheckSpecialBob(dh, Flags & SCAF_Drag_IndicateMakeLink, DRGHF_MakeLinkIndicatorVisible,
1294 &dh->drgh_Bob_MakeLinkIndicator, NAME_MAKELINK, NAME_MAKELINK_FALLBACK);
1295 CheckSpecialBob(dh, Flags & SCAF_Drag_ForceMove, DRGHF_ForceMoveIndicatorVisible,
1296 &dh->drgh_Bob_ForceMoveIndicator, NAME_MOVING, NAME_MOVING_FALLBACK);
1298 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1300 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.X = XOffset + bob->scbob_x;
1301 bob->scbob_Bob.scbob_Bob1.scbob1_vsprite.Y = YOffset + bob->scbob_y;
1303 if ((Flags & SCAF_Drag_Transparent) && !(bob->scbob_Flags & BOBFLAGF_NeverTransparent))
1304 bob->scbob_Bob.scbob_Bob1.scbob1_bob.ImageShadow = bob->scbob_Bob.scbob_Bob1.scbob1_shadow2;
1305 else
1306 bob->scbob_Bob.scbob_Bob1.scbob1_bob.ImageShadow = bob->scbob_Bob.scbob_Bob1.scbob1_shadow1;
1309 if ((Flags & SCAF_Drag_Hide) && !(dh->drgh_flags & DRGF_BobsHidden))
1311 // Hide all bobs
1312 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1314 RemIBob(&bob->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort, &dh->drgh_screen->ViewPort);
1316 dh->drgh_flags |= DRGF_BobsHidden;
1318 if (!(Flags & SCAF_Drag_Hide) && (dh->drgh_flags & DRGF_BobsHidden))
1320 // Show hidden bobs
1321 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1323 AddBob(&bob->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort);
1325 dh->drgh_flags &= ~DRGF_BobsHidden;
1328 SortGList(&dh->drgh_screen->RastPort);
1329 DrawGList(&dh->drgh_screen->RastPort, &dh->drgh_screen->ViewPort);
1332 ScalosReleaseSemaphore(&dh->drgh_BobListSemaphore);
1334 LIBFUNC_END
1337 static void sca_DrawDragCustom(struct DragHandle *dh, LONG x, LONG y, ULONG Flags)
1339 struct ScaBob *bob;
1341 d1(KPrintF("%s/%s/%ld: x=%ld y=%ld drgh_flags=%08lx Flags=%08lx\n", \
1342 __FILE__, __FUNC__, __LINE__, x, y, dh->drgh_flags, Flags));
1344 dh->drgh_flags &= ~DRGHF_BlitRealTransp;
1346 if (Flags & SCAF_Drag_Hide)
1348 x = NO_BOB_POSITION;
1349 y = NO_BOB_POSITION;
1350 dh->drgh_flags |= DRGF_BobsHidden;
1353 if (dh->drgh_flags & DRGHF_RealTranspPossible
1354 && (Flags & SCAF_Drag_Transparent))
1356 dh->drgh_flags |= DRGHF_BlitRealTransp;
1357 d1(KPrintF("%s/%s/%ld: DRGHF_BlitRealTransp\n", __FILE__, __FUNC__, __LINE__));
1360 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1362 CheckSpecialBobCustom(dh, Flags & SCAF_Drag_NoDropHere, DRGHF_NoDropIndicatorVisible,
1363 &dh->drgh_Bob_NoDropIndicator, NAME_FORBIDDEN, NAME_FORBIDDEN_FALLBACK);
1364 CheckSpecialBobCustom(dh, Flags & SCAF_Drag_IndicateCopy, DRGHF_CopyIndicatorVisible,
1365 &dh->drgh_Bob_CopyIndicator, NAME_COPYING, NAME_COPYING_FALLBACK);
1366 CheckSpecialBobCustom(dh, Flags & SCAF_Drag_IndicateMakeLink, DRGHF_MakeLinkIndicatorVisible,
1367 &dh->drgh_Bob_MakeLinkIndicator, NAME_MAKELINK, NAME_MAKELINK_FALLBACK);
1368 CheckSpecialBobCustom(dh, Flags & SCAF_Drag_ForceMove, DRGHF_ForceMoveIndicatorVisible,
1369 &dh->drgh_Bob_ForceMoveIndicator, NAME_MOVING, NAME_MOVING_FALLBACK);
1371 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1373 for (bob = dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1375 bob->scbob_Bob.scbob_Bob2.scbob2_xpos = x + bob->scbob_x;
1376 bob->scbob_Bob.scbob_Bob2.scbob2_ypos = y + bob->scbob_y;
1378 if ((Flags & SCAF_Drag_Transparent)
1379 && !(dh->drgh_flags & DRGHF_BlitRealTransp)
1380 && !(bob->scbob_Flags & BOBFLAGF_NeverTransparent))
1381 bob->scbob_Bob.scbob_Bob2.scbob2_shadow = bob->scbob_Bob.scbob_Bob2.scbob2_shadow2;
1382 else
1383 bob->scbob_Bob.scbob_Bob2.scbob2_shadow = bob->scbob_Bob.scbob_Bob2.scbob2_shadow1;
1386 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1388 if (!(dh->drgh_flags & DRGHF_SpeedBitMapAlloc))
1390 LONG MaxWidth = 0, MaxHeight = 0;
1392 for (bob = dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1394 if (bob->scbob_width > MaxWidth)
1395 MaxWidth = bob->scbob_width;
1396 if (bob->scbob_height > MaxHeight)
1397 MaxHeight = bob->scbob_height;
1399 if (0 == MaxWidth)
1400 return;
1402 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap = AllocBitMap(MaxWidth, MaxHeight,
1403 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap->Depth,
1404 BMF_MINPLANES | BMF_DISPLAYABLE,
1405 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap);
1406 if (NULL == dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap)
1407 return;
1409 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2 = AllocBitMap(MaxWidth, MaxHeight,
1410 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap->Depth,
1411 BMF_MINPLANES | BMF_DISPLAYABLE,
1412 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap);
1413 if (NULL == dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2)
1414 return;
1416 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer = AllocVec(MaxWidth * MaxHeight * sizeof(struct ARGB), MEMF_PUBLIC);
1417 if (NULL == dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer)
1418 return;
1420 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2 = AllocVec(MaxWidth * MaxHeight * sizeof(struct ARGB), MEMF_PUBLIC);
1421 if (NULL == dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2)
1422 return;
1424 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap = AllocBitMap(MaxWidth * 2, MaxHeight * 2,
1425 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap->Depth,
1426 BMF_MINPLANES | BMF_DISPLAYABLE,
1427 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_bitmap);
1428 if (NULL == dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap)
1429 return;
1431 dh->drgh_flags |= DRGHF_SpeedBitMapAlloc;
1434 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1436 if (dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_lastxpos == dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_xpos &&
1437 dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_lastypos == dh->drgh_boblist->scbob_Bob.scbob_Bob2.scbob2_ypos &&
1438 dh->drgh_LastDragFlags == Flags)
1439 return;
1441 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1443 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1445 if (ClipBlitIn(dh->drgh_screen,
1446 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2,
1447 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1448 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1449 bob->scbob_width,
1450 bob->scbob_height))
1452 RestoreBuffer(dh,
1453 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2,
1454 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1455 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1456 bob->scbob_width,
1457 bob->scbob_height);
1459 else
1461 // .nobackup:
1462 bob->scbob_Bob.scbob_Bob2.scbob2_xpos = (WORD) NO_BOB_POSITION;
1463 bob->scbob_Bob.scbob_Bob2.scbob2_ypos = (WORD) NO_BOB_POSITION;
1467 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1469 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1471 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));
1472 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));
1473 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)));
1475 if (IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos))
1477 LONG dx = bob->scbob_Bob.scbob_Bob2.scbob2_xpos - bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos;
1478 LONG dy = bob->scbob_Bob.scbob_Bob2.scbob2_ypos - bob->scbob_Bob.scbob_Bob2.scbob2_lastypos;
1480 if (dx < 0)
1481 dx = -dx;
1482 if (dy < 0)
1483 dy = -dy;
1485 d1(kprintf("%s/%s/%ld: dx=%ld dy=%ld\n", __FILE__, __FUNC__, __LINE__, dx, dy));
1487 if (dx >= bob->scbob_width || dy >= bob->scbob_height || !IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_xpos))
1489 // .restore:
1491 // icons have been moved more than bob->scbob_width or bob->scbob_height
1493 d1(kprintf("%s/%s/%ld: x=%ld y=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1494 bob->scbob_Bob.scbob_Bob2.scbob2_xpos, bob->scbob_Bob.scbob_Bob2.scbob2_ypos, bob->scbob_width, bob->scbob_height));
1496 // get background at new position
1497 ClipBlitIn(dh->drgh_screen,
1498 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1499 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1500 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1501 bob->scbob_width,
1502 bob->scbob_height);
1504 RestoreBuffer(dh,
1505 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1506 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1507 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1508 bob->scbob_width,
1509 bob->scbob_height);
1511 RestoreBuffer2(dh,
1512 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1513 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1514 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1515 bob->scbob_width,
1516 bob->scbob_height);
1518 BltBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap, 0, 0,
1519 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2, 0, 0,
1520 bob->scbob_width,
1521 bob->scbob_height,
1522 ABC | ABNC, ~0, NULL);
1524 RestoreBuffer2(dh,
1525 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2,
1526 bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos,
1527 bob->scbob_Bob.scbob_Bob2.scbob2_lastypos,
1528 bob->scbob_width,
1529 bob->scbob_height);
1531 // erase bob at old position
1532 ClipBlitOut(dh->drgh_screen,
1533 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2,
1534 bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos,
1535 bob->scbob_Bob.scbob_Bob2.scbob2_lastypos,
1536 bob->scbob_width,
1537 bob->scbob_height);
1539 if (IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_xpos))
1541 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));
1543 // draw bob at new position
1544 ClipBlitOut(dh->drgh_screen,
1545 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1546 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1547 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1548 bob->scbob_width,
1549 bob->scbob_height);
1552 else
1554 // .oldyislower:
1555 LONG xStart, yStart;
1557 dx += bob->scbob_width;
1558 dy += bob->scbob_height;
1560 xStart = min(bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos, bob->scbob_Bob.scbob_Bob2.scbob2_xpos);
1561 yStart = min(bob->scbob_Bob.scbob_Bob2.scbob2_lastypos, bob->scbob_Bob.scbob_Bob2.scbob2_ypos);
1563 d1(kprintf("%s/%s/%ld: x=%ld y=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, xStart, yStart, dx, dy));
1565 // Copy from Screen to speedbitmap
1566 ClipBlitIn(dh->drgh_screen,
1567 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1568 xStart, yStart,
1569 dx, dy);
1571 RestoreBuffer(dh,
1572 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1573 xStart, yStart,
1574 dx, dy);
1576 RestoreBuffer2(dh,
1577 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1578 xStart, yStart,
1579 dx, dy);
1581 d1(kprintf("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, xStart, yStart));
1583 // Copy from speedbitmap to Screen
1584 ClipBlitOut(dh->drgh_screen,
1585 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1586 xStart, yStart,
1587 dx, dy);
1590 else
1592 // .norestore:
1593 ClipBlitIn(dh->drgh_screen,
1594 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1595 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1596 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1597 bob->scbob_width,
1598 bob->scbob_height);
1600 BlitBob2(dh, bob, bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, 0, 0, 0, 0,
1601 bob->scbob_width, bob->scbob_height);
1603 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));
1605 ClipBlitOut(dh->drgh_screen,
1606 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap,
1607 bob->scbob_Bob.scbob_Bob2.scbob2_xpos,
1608 bob->scbob_Bob.scbob_Bob2.scbob2_ypos,
1609 bob->scbob_width,
1610 bob->scbob_height);
1614 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1616 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1618 struct BitMap *temp;
1620 bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos = bob->scbob_Bob.scbob_Bob2.scbob2_xpos;
1621 bob->scbob_Bob.scbob_Bob2.scbob2_lastypos = bob->scbob_Bob.scbob_Bob2.scbob2_ypos;
1623 temp = bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap;
1624 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap = bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2;
1625 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2 = temp;
1628 dh->drgh_LastDragFlags = Flags;
1632 static void RestoreBuffer(struct DragHandle *dh,
1633 struct BitMap *DestBM,
1634 LONG x, LONG y, LONG Width, LONG Height)
1636 LONG xMax, yMax;
1637 struct ScaBob *bob;
1639 d1(kprintf("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, x, y));
1641 xMax = x + Width - 1;
1642 yMax = y + Height - 1;
1644 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1646 d1(kprintf("%s/%s/%ld: bob=%08lx xpos=%ld ypos=%ld xMax=%ld yMax=%ld\n", \
1647 __FILE__, __FUNC__, __LINE__, bob, bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos, bob->scbob_Bob.scbob_Bob2.scbob2_lastypos, xMax, yMax));
1649 if (IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos)
1650 && bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos <= xMax
1651 && bob->scbob_Bob.scbob_Bob2.scbob2_lastypos <= yMax
1652 && (bob->scbob_width + bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos - 1) >= x
1653 && (bob->scbob_height + bob->scbob_Bob.scbob_Bob2.scbob2_lastypos - 1) >= y)
1655 LONG SrcX, SrcY, DstX, DstY, SizeX, SizeY;
1657 DstX = 0;
1658 SizeX = bob->scbob_width;
1659 SrcX = x - bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos;
1661 if (SrcX < 0)
1663 SrcX = -SrcX;
1665 SwapLong(&SrcX, &DstX);
1667 SizeX = Width - DstX;
1669 if (SizeX > bob->scbob_width)
1670 SizeX = bob->scbob_width;
1672 else
1674 SizeX -= SrcX;
1675 if (SizeX > Width)
1676 SizeX = Width;
1679 DstY = 0;
1680 SizeY = bob->scbob_height;
1681 SrcY = y - bob->scbob_Bob.scbob_Bob2.scbob2_lastypos;
1683 if (SrcY < 0)
1685 SrcY = -SrcY;
1687 SwapLong(&SrcY, &DstY);
1689 SizeY = Height - DstY;
1691 if (SizeY > bob->scbob_height)
1692 SizeY = bob->scbob_height;
1694 else
1696 SizeY -= SrcY;
1697 if (SizeY > Height)
1698 SizeY = Height;
1701 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1702 SrcX, SrcY, DstX, DstY, SizeX, SizeY));
1704 BltBitMap(bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap, SrcX, SrcY,
1705 DestBM, DstX, DstY,
1706 SizeX, SizeY,
1707 ABC | ABNC, ~0, NULL);
1713 static void RestoreBuffer2(struct DragHandle *dh,
1714 struct BitMap *DestBM,
1715 LONG x, LONG y, LONG Width, LONG Height)
1717 struct ScaBob *bob;
1718 LONG xMax = x + Width - 1;
1719 LONG yMax = y + Height - 1;
1721 d1(kprintf("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, x, y));
1723 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
1725 d1(kprintf("%s/%s/%ld: bob=%08lx xpos=%ld ypos=%ld xMax=%ld yMax=%ld\n", \
1726 __FILE__, __FUNC__, __LINE__, bob, bob->scbob_Bob.scbob_Bob2.scbob2_xpos, bob->scbob_Bob.scbob_Bob2.scbob2_ypos, xMax, yMax));
1728 if (IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_xpos)
1729 && bob->scbob_Bob.scbob_Bob2.scbob2_xpos <= xMax
1730 && bob->scbob_Bob.scbob_Bob2.scbob2_ypos <= yMax
1731 && (bob->scbob_Bob.scbob_Bob2.scbob2_xpos + bob->scbob_width - 1) >= x
1732 && (bob->scbob_Bob.scbob_Bob2.scbob2_ypos + bob->scbob_height - 1) >= y)
1734 LONG SrcX, SrcY, DstX, DstY, SizeX, SizeY;
1736 DstX = 0;
1737 SizeX = bob->scbob_width;
1738 SrcX = x - bob->scbob_Bob.scbob_Bob2.scbob2_xpos;
1740 if (SrcX < 0)
1742 SrcX = -SrcX;
1744 SwapLong(&DstX, &SrcX);
1746 SizeX = Width - DstX;
1748 if (SizeX > bob->scbob_width)
1749 SizeX = bob->scbob_width;
1751 else
1753 SizeX -= SrcX;
1754 if (SizeX > Width)
1755 SizeX = Width;
1758 DstY = 0;
1759 SizeY = bob->scbob_height;
1760 SrcY = y - bob->scbob_Bob.scbob_Bob2.scbob2_ypos;
1762 if (SrcY < 0)
1764 SrcY = -SrcY;
1766 SwapLong(&DstY, &SrcY);
1768 SizeY = Height - DstY;
1770 if (SizeY > bob->scbob_height)
1771 SizeY = bob->scbob_height;
1773 else
1775 SizeY -= SrcY;
1776 if (SizeY > Height)
1777 SizeY = Height;
1780 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1781 SrcX, SrcY, DstX, DstY, SizeX, SizeY));
1783 if (SizeX < bob->scbob_width || SizeY < bob->scbob_height)
1785 // .doubleblit:
1786 d1(kprintf("%s/%s/%ld: .doubleblit\n", __FILE__, __FUNC__, __LINE__));
1788 BltBitMap(DestBM, DstX, DstY,
1789 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap, SrcX, SrcY,
1790 SizeX, SizeY,
1791 ABC | ABNC, ~0, NULL);
1793 dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap = dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap;
1795 BlitTrans(dh, bob, bob->scbob_Bob.scbob_Bob2.scbob2_bitmap,
1796 0, 0,
1797 0, 0,
1798 bob->scbob_width, bob->scbob_height,
1799 bob->scbob_Bob.scbob_Bob2.scbob2_shadow
1802 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1803 SrcX, SrcY, DstX, DstY, SizeX, SizeY));
1805 BltBitMap(dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap, SrcX, SrcY,
1806 DestBM, DstX, DstY,
1807 SizeX, SizeY,
1808 ABC | ABNC, ~0, NULL);
1810 else
1812 dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap = DestBM;
1814 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1815 SrcX, SrcY, DstX, DstY, SizeX, SizeY));
1816 d1(kprintf("%s/%s/%ld: SrcBM=%08lx DestBM=%08lx Mask=%08lx\n", __FILE__, __FUNC__, __LINE__, \
1817 bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, DestBM, bob->scbob_Bob.scbob_Bob2.scbob2_shadow->Planes[0]));
1819 BlitTrans(dh, bob, bob->scbob_Bob.scbob_Bob2.scbob2_bitmap,
1820 SrcX, SrcY,
1821 DstX, DstY,
1822 SizeX, SizeY,
1823 bob->scbob_Bob.scbob_Bob2.scbob2_shadow
1831 // Blit from Screen to an internal Bitmap
1832 static BOOL ClipBlitIn(struct Screen *Scr, struct BitMap *DestBM,
1833 LONG SrcX, LONG SrcY, LONG Width, LONG Height)
1835 LONG DstX, DstY;
1836 struct RastPort rp;
1838 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1839 SrcX, SrcY, Width, Height));
1841 Scalos_InitRastPort(&rp);
1842 rp.BitMap = DestBM;
1844 DstX = -SrcX;
1845 if (DstX < 0)
1847 LONG Right = (SrcX + Width - 1) - (Scr->Width - 1);
1849 if (Right >= 0)
1851 Width -= Right;
1853 if (Width < 0)
1854 return FALSE;
1857 DstX = 0;
1859 else
1861 Width -= DstX;
1863 if (Width < 0)
1864 return FALSE;
1866 SrcX = 0;
1869 DstY = -SrcY;
1870 if (DstY < 0)
1872 LONG Bottom = (SrcY + Height - 1) - (Scr->Height - 1);
1874 if (Bottom >= 0)
1876 Height -= Bottom;
1878 if (Height < 0)
1879 return FALSE;
1882 DstY = 0;
1884 else
1886 Height -= DstY;
1888 if (Height < 0)
1889 return FALSE;
1891 SrcY = 0;
1894 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1895 SrcX, SrcY, DstX, DstY, Width, Height));
1897 ClipBlit(&Scr->RastPort, SrcX, SrcY,
1898 &rp, DstX, DstY,
1899 Width, Height,
1900 ABC | ABNC);
1902 Scalos_DoneRastPort(&rp);
1904 return TRUE;
1908 // Blit from an internal Bitmap to the Screen
1909 static BOOL ClipBlitOut(struct Screen *Scr, struct BitMap *SrcBM,
1910 LONG DstX, LONG DstY, LONG Width, LONG Height)
1912 LONG SrcX, SrcY;
1913 struct RastPort rp;
1915 d1(kprintf("%s/%s/%ld: DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1916 DstX, DstY, Width, Height));
1918 Scalos_InitRastPort(&rp);
1919 rp.BitMap = SrcBM;
1921 SrcX = -DstX;
1922 if (SrcX < 0)
1924 LONG Right = (DstX + Width - 1) - (Scr->Width - 1);
1926 if (Right >= 0)
1928 Width -= Right;
1930 if (Width < 0)
1931 return FALSE;
1934 SrcX = 0;
1936 else
1938 Width -= SrcX;
1940 if (Width < 0)
1941 return FALSE;
1943 DstX = 0;
1946 SrcY = -DstY;
1947 if (SrcY < 0)
1949 LONG Bottom = (DstY + Height - 1) - (Scr->Height - 1);
1951 if (Bottom >= 0)
1953 Height -= Bottom;
1955 if (Height < 0)
1956 return FALSE;
1959 SrcY = 0;
1961 else
1963 Height -= SrcY;
1965 if (Height < 0)
1966 return FALSE;
1968 DstY = 0;
1971 d1(kprintf("%s/%s/%ld: DestRp=%08lx SrcX=%ld SrcY=%ld DstX=%ld DstY=%ld w=%ld h=%ld\n", __FILE__, __FUNC__, __LINE__, \
1972 &Scr->RastPort, SrcX, SrcY, DstX, DstY, Width, Height));
1974 ClipBlit(&rp, SrcX, SrcY,
1975 &Scr->RastPort, DstX, DstY,
1976 Width, Height,
1977 ABC | ABNC);
1979 Scalos_DoneRastPort(&rp);
1981 return TRUE;
1985 static void BlitBob2(struct DragHandle *dh,
1986 struct ScaBob *bob, struct BitMap *bm,
1987 LONG SrcX, LONG SrcY, LONG DestX, LONG DestY,
1988 LONG Width, LONG Height)
1990 dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap = dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap;
1992 BlitTrans(dh, bob, bm,
1993 SrcX, SrcY, DestX, DestY,
1994 Width, Height,
1995 bob->scbob_Bob.scbob_Bob2.scbob2_shadow);
1999 // DestX, DestY : Offsets into RastPort->BitMap
2001 static void BlitTrans(struct DragHandle *dh,
2002 const struct ScaBob *bob, struct BitMap *SrcBM,
2003 LONG SrcX, LONG SrcY, LONG DestX, LONG DestY,
2004 LONG Width, LONG Height,
2005 const struct BitMap *MaskBM)
2007 d1(kprintf("%s/%s/%ld: SrcX=%ld SrcY=%ld Width=%ld Height=%ld\n", __FILE__, __FUNC__, __LINE__, \
2008 SrcX, SrcY, Width, Height));
2010 if (dh->drgh_flags & DRGHF_RealTranspPossible)
2012 ULONG Transp;
2013 ULONG DestMod = Width * sizeof(struct ARGB);
2014 struct BitMap *oldBitMap;
2016 if ((dh->drgh_flags & DRGHF_BlitRealTransp) && !(bob->scbob_Flags & BOBFLAGF_NeverTransparent))
2017 Transp = (CurrentPrefs.pref_DragTransparency * 255) / 100;
2018 else
2019 Transp = ALPHA_OPAQUE; // opaque
2021 oldBitMap = dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap;
2022 dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap = SrcBM;
2024 // read background from SrcBM into drgh_Specific.drghs_DragHandle2.drgh2_transbuffer
2025 ScalosReadPixelArray(dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer, DestMod,
2026 &dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport, SrcX, SrcY,
2027 Width, Height);
2029 dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport.BitMap = oldBitMap;
2031 // read icon image into drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2
2032 ScalosReadPixelArray(dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2, DestMod,
2033 &dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport, DestX, DestY,
2034 Width, Height);
2036 d1(kprintf("%s/%s/%ld: AlphaChannel=%08lx\n", \
2037 __FILE__, __FUNC__, __LINE__, bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel));
2039 if (bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel)
2041 BlitARGBMaskAlpha(Width, Height,
2042 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer,
2043 0, 0,
2044 Width,
2045 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2, 0, 0,
2046 MaskBM,
2047 Transp,
2048 bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel,
2049 bob->scbob_LeftBorder, bob->scbob_BoundsWidth);
2051 else
2053 BlitARGBMask(Width, Height,
2054 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer,
2055 0, 0,
2056 Width,
2057 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2, 0, 0,
2058 MaskBM,
2059 Transp);
2062 // write back to icon image
2063 ScalosWritePixelArray(dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2, DestMod,
2064 &dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport, DestX, DestY,
2065 Width, Height);
2067 else
2069 BltMaskBitMapRastPort(SrcBM, SrcX, SrcY,
2070 &dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport, DestX, DestY,
2071 Width, Height,
2072 ABC|ABNC|ANBC, MaskBM->Planes[0]);
2077 static void OptimizeBobs(struct DragHandle *dh)
2079 LONG xMin, yMin, xMax, yMax;
2080 struct ScaBob *bob;
2082 d1(kprintf("%s/%s/%ld: OptimizeBobs START\n", __FILE__, __FUNC__, __LINE__));
2084 xMin = yMin = SHRT_MAX;
2085 xMax = yMax = SHRT_MIN;
2087 bob = dh->drgh_boblist;
2088 if (bob && bob->scbob_Node.mln_Succ)
2090 LONG Width, Height;
2091 struct ScaBob *newBob;
2092 struct ScaBob *nbList = NULL;
2093 BOOL NeedAlpha = FALSE;
2095 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2097 d1(kprintf("%s/%s/%ld: bob=%08lx NoOptimize=%ld\n", __FILE__, __FUNC__, __LINE__, \
2098 bob, bob->scbob_Flags & BOBFLAGF_NoOptimize ));
2099 if (!(bob->scbob_Flags & BOBFLAGF_NoOptimize))
2101 if (bob->scbob_x < xMin)
2102 xMin = bob->scbob_x;
2103 if (bob->scbob_y < yMin)
2104 yMin = bob->scbob_y;
2105 if (bob->scbob_x + bob->scbob_width > xMax)
2106 xMax = bob->scbob_x + bob->scbob_width;
2107 if (bob->scbob_y + bob->scbob_height > yMax)
2108 yMax = bob->scbob_y + bob->scbob_height;
2110 if (bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel)
2111 NeedAlpha = TRUE;
2115 d1(kprintf("%s/%s/%ld: xMin=%ld xMax=%ld yMin=%ld yMax=%ld\n", __FILE__, __FUNC__, __LINE__, \
2116 xMin, xMax, yMin, yMax));
2118 Width = 1 + xMax - xMin;
2119 Height = 1 + yMax - yMin;
2121 newBob = AllocBob2(dh, (struct ScalosNodeList *)(APTR) &nbList, xMin, yMin, Width, Height, Width, Height);
2122 if (newBob)
2124 struct RastPort rp;
2126 Scalos_InitRastPort(&rp);
2128 if (NeedAlpha)
2129 MergeBobsAlpha(&rp, dh, &nbList, newBob);
2130 else
2131 MergeBobs(&rp, dh, &nbList, newBob);
2133 FreeCustomBobList(&dh->drgh_boblist);
2134 dh->drgh_boblist = nbList;
2136 Scalos_DoneRastPort(&rp);
2140 d1(kprintf("%s/%s/%ld: OptimizeBobs END\n", __FILE__, __FUNC__, __LINE__));
2142 dh->drgh_flags |= DRGHF_BobsOptimized;
2146 static void MergeBobs(struct RastPort *TempRp, struct DragHandle *dh,
2147 struct ScaBob **NewBobList, struct ScaBob *NewBob)
2149 struct ScaBob *bob;
2151 for (bob=dh->drgh_boblist; bob; )
2153 struct ScaBob *NextBob = (struct ScaBob *) bob->scbob_Node.mln_Succ;
2155 d1(kprintf("%s/%s/%ld: bob=%08lx NoOptimize=%ld\n", __FILE__, __FUNC__, __LINE__, \
2156 bob, bob->scbob_Flags & BOBFLAGF_NoOptimize ));
2158 if (bob->scbob_Flags & BOBFLAGF_NoOptimize)
2160 SCA_MoveBobNode(&dh->drgh_boblist, NewBobList, bob);
2162 else
2164 LONG DstX = bob->scbob_x - NewBob->scbob_x;
2165 LONG DstY = bob->scbob_y - NewBob->scbob_y;
2167 d1(kprintf("%s/%s/%ld: bob=%08lx DstX=%ld DstY=%ld\n", __FILE__, __FUNC__, __LINE__, \
2168 bob, DstX, DstY));
2170 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_bitmap;
2171 BltMaskBitMapRastPort(bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, 0, 0,
2172 TempRp, DstX, DstY,
2173 bob->scbob_width, bob->scbob_height,
2174 ABC | ABNC | ANBC, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0]
2177 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_shadow1;
2178 BltMaskBitMapRastPort(bob->scbob_Bob.scbob_Bob2.scbob2_shadow1, 0, 0,
2179 TempRp, DstX, DstY,
2180 bob->scbob_width, bob->scbob_height,
2181 ABC | ABNC | ANBC, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0]
2184 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_shadow2;
2185 BltMaskBitMapRastPort(bob->scbob_Bob.scbob_Bob2.scbob2_shadow2, 0, 0,
2186 TempRp, DstX, DstY,
2187 bob->scbob_width, bob->scbob_height,
2188 ABC | ABNC | ANBC, bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0]
2192 bob = NextBob;
2198 static void MergeBobsAlpha(struct RastPort *TempRp, struct DragHandle *dh,
2199 struct ScaBob **NewBobList, struct ScaBob *NewBob)
2201 struct ARGB *OldBobBuffer;
2202 struct ARGB *NewBobBuffer = NULL;
2204 do {
2205 struct ScaBob *bob;
2206 size_t AllocSize;
2207 UBYTE *NewAlphaChannel;
2208 UWORD NewBobDestMod = NewBob->scbob_width * sizeof(struct ARGB);
2210 d1(kprintf("%s/%s/%ld: NewBob Width=%ld Height=%ld\n", \
2211 __FILE__, __FUNC__, __LINE__, NewBob->scbob_width, NewBob->scbob_height));
2213 // First, move all bobs away that are not to be merged
2214 for (bob=dh->drgh_boblist; bob; )
2216 struct ScaBob *NextBob = (struct ScaBob *) bob->scbob_Node.mln_Succ;
2218 d1(kprintf("%s/%s/%ld: bob=%08lx NoOptimize=%ld\n", __FILE__, __FUNC__, __LINE__, \
2219 bob, bob->scbob_Flags & BOBFLAGF_NoOptimize ));
2221 if (bob->scbob_Flags & BOBFLAGF_NoOptimize)
2223 SCA_MoveBobNode(&dh->drgh_boblist, NewBobList, bob);
2225 bob = NextBob;
2228 AllocSize = NewBob->scbob_width * NewBob->scbob_height * sizeof(struct ARGB);
2229 OldBobBuffer = ScalosAlloc(AllocSize);
2230 d1(kprintf("%s/%s/%ld: OldBobBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, OldBobBuffer));
2231 if (NULL == OldBobBuffer)
2232 break;
2234 NewBobBuffer = ScalosAlloc(AllocSize);
2235 d1(kprintf("%s/%s/%ld: NewBobBuffer=%08lx\n", __FILE__, __FUNC__, __LINE__, NewBobBuffer));
2236 if (NULL == NewBobBuffer)
2237 break;
2239 // Allocate Alpha channel for new bob
2240 NewBob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel = NewAlphaChannel = ScalosAlloc(NewBob->scbob_width * NewBob->scbob_height);
2241 if (NULL == NewBob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel)
2242 break;
2243 NewBob->scbob_Flags |= BOBFLAGF_FreeAlphaChannel;
2245 d1(kprintf("%s/%s/%ld: AlphaChannel=%08lx\n", __FILE__, __FUNC__, __LINE__, \
2246 NewBob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel));
2248 memset(NewAlphaChannel, 0, NewBob->scbob_width * NewBob->scbob_height);
2251 // Merge <scbob2_bitmap>
2253 memset(NewBobBuffer, 0, AllocSize);
2254 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2256 LONG DstX = bob->scbob_x - NewBob->scbob_x;
2257 LONG DstY = bob->scbob_y - NewBob->scbob_y;
2258 UWORD DestMod = bob->scbob_width * sizeof(struct ARGB);
2259 ULONG y;
2260 const UBYTE *AlphaSrcPtr = bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel;
2261 UBYTE *AlphaDestPtr = NewAlphaChannel + DstY * NewBob->scbob_width;
2262 const UBYTE *Mask = bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0];
2263 ULONG MaskBytesPerRow = ((bob->scbob_width + 15) & ~0x0f) / 8;
2265 d1(kprintf("%s/%s/%ld: bob=%08lx AlphaSrcPtr=%08lx\n", __FILE__, __FUNC__, __LINE__, bob, AlphaSrcPtr));
2266 d1(kprintf("%s/%s/%ld: bob=%08lx width=%ld height=%ld\n", \
2267 __FILE__, __FUNC__, __LINE__, bob, bob->scbob_width, bob->scbob_height));
2269 d1(kprintf("%s/%s/%ld: bob=%08lx DstX=%ld DstY=%ld OldBobBuffer=%08lx\n", \
2270 __FILE__, __FUNC__, __LINE__, bob, DstX, DstY, OldBobBuffer));
2272 TempRp->BitMap = bob->scbob_Bob.scbob_Bob2.scbob2_bitmap;
2274 ScalosReadPixelArray(OldBobBuffer, DestMod, TempRp,
2275 0, 0, bob->scbob_width, bob->scbob_height);
2277 if (AlphaSrcPtr)
2279 BlitARGBMaskAlpha(bob->scbob_width, bob->scbob_height,
2280 OldBobBuffer, 0, 0,
2281 NewBob->scbob_width,
2282 NewBobBuffer, DstX, DstY,
2283 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1,
2284 ALPHA_OPAQUE,
2285 AlphaSrcPtr,
2286 bob->scbob_LeftBorder, bob->scbob_BoundsWidth);
2288 else
2290 BlitARGBMask(bob->scbob_width, bob->scbob_height,
2291 OldBobBuffer, 0, 0,
2292 NewBob->scbob_width,
2293 NewBobBuffer, DstX, DstY,
2294 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1,
2295 ALPHA_OPAQUE);
2298 // calculate combined Alpha for merged bob
2299 for (y = 0; y < bob->scbob_height; y++)
2301 UBYTE *AlphaLineDestPtr = AlphaDestPtr + DstX;
2302 ULONG x;
2304 if (AlphaSrcPtr)
2306 const UBYTE *AlphaLineSrcPtr = AlphaSrcPtr + bob->scbob_LeftBorder;
2308 for (x = 0; x < bob->scbob_width; x++, AlphaLineSrcPtr++, AlphaLineDestPtr++)
2310 ULONG OldBobTransparency = ALPHA_OPAQUE - *AlphaLineSrcPtr;
2311 ULONG NewBobTransparency = ALPHA_OPAQUE - *AlphaLineDestPtr;
2313 NewBobTransparency = ALPHA_OPAQUE - ((OldBobTransparency * NewBobTransparency) >> 8);
2314 if (NewBobTransparency > UCHAR_MAX)
2315 NewBobTransparency = UCHAR_MAX;
2317 *AlphaLineDestPtr = NewBobTransparency;
2320 AlphaSrcPtr += bob->scbob_BoundsWidth;
2322 else
2324 // <bob> has no Alpha channel
2325 UWORD BitMask = 0x0080;
2326 const UBYTE *MaskPtr2 = Mask;
2328 for (x = 0; x < bob->scbob_width; x++, AlphaLineDestPtr++)
2330 if (*MaskPtr2 & BitMask)
2331 *AlphaLineDestPtr = ALPHA_OPAQUE;
2333 BitMask >>= 1;
2334 if (0 == BitMask)
2336 BitMask = 0x0080;
2337 MaskPtr2++;
2341 Mask += MaskBytesPerRow;
2344 AlphaDestPtr += NewBob->scbob_width;
2346 d1(kprintf("%s/%s/%ld: AlphaDestPtr=%08lx Offset=%lu\n", \
2347 __FILE__, __FUNC__, __LINE__, AlphaDestPtr, AlphaDestPtr - NewAlphaChannel));
2350 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_bitmap;
2351 ScalosWritePixelArray(NewBobBuffer, NewBobDestMod, TempRp,
2352 0, 0, NewBob->scbob_width, NewBob->scbob_height);
2356 // Now merge <scbob2_shadow1> and <scbob2_shadow2>
2358 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2360 LONG DstX = bob->scbob_x - NewBob->scbob_x;
2361 LONG DstY = bob->scbob_y - NewBob->scbob_y;
2363 d1(kprintf("%s/%s/%ld: bob=%08lx DstX=%ld DstY=%ld\n", __FILE__, __FUNC__, __LINE__, \
2364 bob, DstX, DstY));
2366 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_shadow1;
2367 BltMaskBitMapRastPort(bob->scbob_Bob.scbob_Bob2.scbob2_shadow1, 0, 0,
2368 TempRp, DstX, DstY,
2369 bob->scbob_width, bob->scbob_height,
2370 ABC | ABNC | ANBC, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0]
2373 TempRp->BitMap = NewBob->scbob_Bob.scbob_Bob2.scbob2_shadow2;
2374 BltMaskBitMapRastPort(bob->scbob_Bob.scbob_Bob2.scbob2_shadow2, 0, 0,
2375 TempRp, DstX, DstY,
2376 bob->scbob_width, bob->scbob_height,
2377 ABC | ABNC | ANBC, bob->scbob_Bob.scbob_Bob2.scbob2_shadow2->Planes[0]
2380 } while (0);
2382 if (NewBobBuffer)
2383 ScalosFree(NewBobBuffer);
2384 if (OldBobBuffer)
2385 ScalosFree(OldBobBuffer);
2389 static void SwapLong(LONG *x1, LONG *x2)
2391 LONG temp = *x1;
2393 *x1 = *x2;
2394 *x2 = temp;
2398 // Free all bobs in BobList
2399 static void FreeBobList(struct DragHandle *dh)
2401 struct ScaBob *bob;
2403 if (!(dh->drgh_flags & DRGF_BobsHidden))
2405 for (bob=dh->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2407 RemIBob(&bob->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort, &dh->drgh_screen->ViewPort);
2410 WaitBOVP(&dh->drgh_screen->ViewPort);
2413 while (dh->drgh_SpecialBobList)
2414 FreeBobNode((struct ScalosNodeList *) &dh->drgh_SpecialBobList, dh->drgh_SpecialBobList);
2416 while (dh->drgh_boblist)
2417 FreeBobNode((struct ScalosNodeList *) &dh->drgh_boblist, dh->drgh_boblist);
2421 static void RemoveCustomBobsFromScreen(struct ScaBob **BobList)
2423 struct ScaBob *bob;
2425 for (bob=*BobList; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2427 if (bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap && IsBobPosition(bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos))
2429 // bob needs to be removed from screen
2430 ClipBlitOut(bob->scbob_draghandle->drgh_screen,
2431 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap,
2432 bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos, bob->scbob_Bob.scbob_Bob2.scbob2_lastypos,
2433 bob->scbob_width, bob->scbob_height);
2437 WaitBlit();
2441 // Free all custom bobs in BobList
2442 static void FreeCustomBobList(struct ScaBob **BobList)
2444 RemoveCustomBobsFromScreen(BobList);
2446 while (*BobList)
2447 FreeCustomBobNode((struct ScalosNodeList *) BobList, *BobList);
2451 static struct ScaBob *AllocBob2(struct DragHandle *dh, struct ScalosNodeList *BobList,
2452 LONG x, LONG y, LONG Width, LONG Height, LONG BoundsWidth, LONG BoundsHeight)
2454 ULONG Depth, ScreenWidth, Flags;
2455 BOOL Success = FALSE;
2456 struct ScaBob *bob;
2458 do {
2459 bob = (struct ScaBob *) SCA_AllocNode(BobList, sizeof(struct ScaBob) - sizeof(struct MinNode));
2460 if (NULL == bob)
2461 break;
2463 bob->scbob_draghandle = (struct DragHandle *) dh;
2464 bob->scbob_width = Width;
2465 bob->scbob_height = Height;
2466 bob->scbob_BoundsWidth = BoundsWidth;
2467 bob->scbob_BoundsHeight = BoundsHeight;
2468 bob->scbob_x = x;
2469 bob->scbob_y = y;
2470 bob->scbob_Bob.scbob_Bob2.scbob2_AlphaChannel = NULL;
2471 bob->scbob_Bob.scbob_Bob2.scbob2_lastxpos = (WORD) NO_BOB_POSITION;
2472 bob->scbob_Bob.scbob_Bob2.scbob2_lastypos = (WORD) NO_BOB_POSITION;
2474 Depth = GetBitMapAttr(dh->drgh_screen->RastPort.BitMap, BMA_DEPTH);
2475 if (0 == Depth)
2476 break;
2478 bob->scbob_Bob.scbob_Bob2.scbob2_bitmap = AllocBitMap(bob->scbob_width, bob->scbob_height,
2479 Depth, BMF_MINPLANES | BMF_DISPLAYABLE, dh->drgh_screen->RastPort.BitMap);
2480 if (NULL == bob->scbob_Bob.scbob_Bob2.scbob2_bitmap)
2481 break;
2483 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap = AllocBitMap(bob->scbob_width, bob->scbob_height,
2484 Depth, BMF_MINPLANES | BMF_DISPLAYABLE, dh->drgh_screen->RastPort.BitMap);
2485 if (NULL == bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap)
2486 break;
2488 bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2 = AllocBitMap(bob->scbob_width, bob->scbob_height,
2489 Depth, BMF_MINPLANES | BMF_DISPLAYABLE, dh->drgh_screen->RastPort.BitMap);
2490 if (NULL == bob->scbob_Bob.scbob_Bob2.scbob2_backbitmap2)
2491 break;
2493 ScreenWidth = GetBitMapAttr(bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, BMA_WIDTH);
2494 Flags = GetBitMapAttr(bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, BMA_FLAGS);
2495 if (Flags & BMF_INTERLEAVED)
2497 Depth = GetBitMapAttr(bob->scbob_Bob.scbob_Bob2.scbob2_bitmap, BMA_DEPTH);
2498 ScreenWidth *= Depth;
2501 d1(kprintf("%s/%s/%ld: ScreenWidth=%ld\n", __FILE__, __FUNC__, __LINE__, ScreenWidth));
2503 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1 = AllocBitMap(ScreenWidth, bob->scbob_height, 1, BMF_CLEAR, NULL);
2504 if (NULL == bob->scbob_Bob.scbob_Bob2.scbob2_shadow1)
2505 break;
2507 d1(kprintf("%s/%s/%ld: Shadow1: BytesPerRow=%ld Rows=%ld Depth=%ld FLags=%02lx\n", __FILE__, __FUNC__, __LINE__, \
2508 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->BytesPerRow, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Rows, \
2509 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Depth, bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Flags));
2510 d1(kprintf("%s/%s/%ld: Planes: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx \n", __FILE__, __FUNC__, __LINE__, \
2511 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[0], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[1],
2512 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[2], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[3],
2513 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[4], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[5],
2514 bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[6], bob->scbob_Bob.scbob_Bob2.scbob2_shadow1->Planes[7]));
2516 bob->scbob_Bob.scbob_Bob2.scbob2_shadow2 = AllocBitMap(ScreenWidth, bob->scbob_height, 1, BMF_CLEAR, NULL);
2517 if (NULL == bob->scbob_Bob.scbob_Bob2.scbob2_shadow2)
2518 break;
2520 Success= TRUE;
2521 } while (0);
2523 if (!Success && bob)
2525 FreeCustomBobNode(BobList, bob);
2526 bob = NULL;
2529 return bob;
2533 static BOOL IsBobPosition(WORD x)
2535 return (BOOL) ((UWORD) x != NO_BOB_POSITION);
2539 static void FreeSpeedBitMapAlloc(struct DragHandle *dh)
2541 if (dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap)
2543 FreeBitMap(dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap);
2544 dh->drgh_Specific.drghs_DragHandle2.drgh2_speedbitmap = NULL;
2546 if (dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap)
2548 FreeBitMap(dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap);
2549 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap = NULL;
2551 if (dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2)
2553 FreeBitMap(dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2);
2554 dh->drgh_Specific.drghs_DragHandle2.drgh2_bufferbitmap2 = NULL;
2557 if (dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer)
2559 FreeVec(dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer);
2560 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer = NULL;
2562 if (dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2)
2564 FreeVec(dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2);
2565 dh->drgh_Specific.drghs_DragHandle2.drgh2_transbuffer2 = NULL;
2568 dh->drgh_flags &= ~DRGHF_SpeedBitMapAlloc;
2572 LIBFUNC_P2(void, sca_EndDrag,
2573 A0, struct DragHandle *, dh,
2574 A6, struct ScalosBase *, ScalosBase, 0)
2576 (void)ScalosBase;
2578 d1(kprintf("%s/%s/%ld: START dh=%08lx\n", __FILE__, __FUNC__, __LINE__, dh));
2580 if (dh == iInfos.xii_GlobalDragHandle)
2582 iInfos.xii_GlobalDragHandle = NULL;
2584 if (dh->drgh_flags & DRGHF_CustomBob)
2586 FreeCustomBobList(&dh->drgh_boblist); // remove+free all bobs
2588 FreeCustomBobList(&dh->drgh_SpecialBobList); // free special bobs
2590 FreeSpeedBitMapAlloc(dh);
2592 Scalos_DoneRastPort(&dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport);
2594 else
2596 FreeBobList(dh); // remove+free all bobs
2598 dh->drgh_screen->RastPort.GelsInfo = dh->drgh_Specific.drghs_DragHandle1.drgh1_oldginfo;
2601 while (dh->drgh_SpecialDragList)
2603 d1(kprintf("%s/%s/%ld: Free dgn=%08lx\n", __FILE__, __FUNC__, __LINE__, dh->drgh_SpecialDragList));
2604 SCA_FreeNode((struct ScalosNodeList *) &dh->drgh_SpecialDragList, &dh->drgh_SpecialDragList->drgn_Node);
2606 while (dh->drgh_SpecialIconList)
2608 if (dh->drgh_SpecialIconList->in_Icon)
2609 DisposeIconObject(dh->drgh_SpecialIconList->in_Icon);
2611 SCA_FreeNode((struct ScalosNodeList *) &dh->drgh_SpecialIconList, &dh->drgh_SpecialIconList->in_Node);
2614 d1(kprintf("%s/%s/%ld: dh=%08lx drgh_flags=%08lx\n", __FILE__, __FUNC__, __LINE__, dh, dh->drgh_flags));
2615 if (dh->drgh_flags & DRGHF_LayersLocked)
2617 SCA_UnlockDrag(dh);
2620 ScalosFree(dh);
2622 if (!CurrentPrefs.pref_EnableDropMenu)
2623 ClosePopupWindows(FALSE);
2625 d1(kprintf("%s/%s/%ld: END dh=%08lx\n", __FILE__, __FUNC__, __LINE__, dh));
2627 LIBFUNC_END
2630 LIBFUNC_P2(struct DragHandle *, sca_InitDrag,
2631 A0, struct Screen *, Scr,
2632 A6, struct ScalosBase *, ScalosBase, 0)
2634 ULONG Depth;
2636 (void) ScalosBase;
2638 if (NULL == iInfos.xii_GlobalDragHandle)
2640 struct DragHandle *dh;
2642 if (NULL == Scr)
2643 Scr = iInfos.xii_iinfos.ii_Screen;
2645 Depth = GetBitMapAttr(Scr->RastPort.BitMap, BMA_DEPTH);
2647 dh = ScalosAlloc(sizeof(struct DragHandle));
2648 if (NULL == dh)
2649 return NULL;
2651 memset(dh, 0, sizeof(struct DragHandle));
2653 dh->drgh_screen = Scr;
2655 if (DRAGMETHOD_Custom == CurrentPrefs.pref_DragMethod || Depth > 8)
2657 dh->drgh_flags |= DRGHF_CustomBob;
2659 Scalos_InitRastPort(&dh->drgh_Specific.drghs_DragHandle2.drgh2_rastport);
2661 if (CyberGfxBase && CurrentPrefs.pref_RealTransFlag && Depth > 8)
2662 dh->drgh_flags |= DRGHF_RealTranspPossible;
2664 d1(KPrintF("%s/%s/%ld: CyberGfxBase=%08lx pref_RealTransFlag=%ld Depth=%ld\n", \
2665 __FILE__, __FUNC__, __LINE__, CyberGfxBase, CurrentPrefs.pref_RealTransFlag, Depth));
2667 ScalosInitSemaphore(&dh->drgh_BobListSemaphore);
2669 iInfos.xii_GlobalDragHandle = dh;
2671 else
2673 dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo.leftmost = 0;
2674 dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo.topmost = 0;
2675 dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo.rightmost = Scr->Width - 1;
2676 dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo.bottommost = Scr->Height - 1;
2678 InitGels(&dh->drgh_Specific.drghs_DragHandle1.drgh1_vshead,
2679 &dh->drgh_Specific.drghs_DragHandle1.drgh1_vstail,
2680 &dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo);
2682 dh->drgh_Specific.drghs_DragHandle1.drgh1_oldginfo = dh->drgh_screen->RastPort.GelsInfo;
2683 dh->drgh_screen->RastPort.GelsInfo = &dh->drgh_Specific.drghs_DragHandle1.drgh1_gelsinfo;
2685 ScalosInitSemaphore(&dh->drgh_BobListSemaphore);
2687 iInfos.xii_GlobalDragHandle = dh;
2691 return iInfos.xii_GlobalDragHandle;
2693 LIBFUNC_END
2696 static BOOL AddSpecialIcon(struct internalScaWindowTask *iwt, struct RastPort *rp,
2697 CONST_STRPTR IconFileName, struct ScaBob **BobPtr)
2699 struct ScaIconNode *in;
2700 struct DragHandle *dh = iwt->iwt_myDragHandle;
2702 in = (struct ScaIconNode *) SCA_AllocStdNode((struct ScalosNodeList *) &dh->drgh_SpecialIconList, NTYP_IconNode);
2703 if (NULL == in)
2704 return FALSE;
2706 in->in_Icon = NewIconObjectTags((STRPTR) IconFileName,
2707 IDTA_Text, (IPTR) "",
2708 TAG_END);
2710 d1(kprintf("%s/%s/%ld: in=%08lx IconObj=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, in, in->in_Icon, IconFileName));
2712 if (NULL == in->in_Icon)
2714 SCA_FreeNode((struct ScalosNodeList *) &dh->drgh_SpecialIconList, &in->in_Node);
2715 return FALSE;
2718 DoMethod(in->in_Icon, IDTM_Layout, iwt->iwt_WinScreen,
2719 iwt->iwt_WindowTask.wt_Window, iwt->iwt_WindowTask.wt_Window->RPort,
2720 iwt->iwt_WinDrawInfo, IOLAYOUTF_NormalImage);
2722 return AppendSpecialDragNode(dh, iwt, rp, in, BobPtr);
2726 static BOOL AppendSpecialDragNode(struct DragHandle *dh,
2727 struct internalScaWindowTask *iwt, struct RastPort *rp,
2728 struct ScaIconNode *in, struct ScaBob **BobPtr)
2730 BOOL Success = FALSE;
2731 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
2732 struct DragNode *dgn = (struct DragNode *) SCA_AllocStdNode((struct ScalosNodeList *) &dh->drgh_SpecialDragList, NTYP_DragNode);
2734 d1(KPrintF("%s/%s/%ld: dgn=%08lx\n", __FILE__, __FUNC__, __LINE__, dgn));
2736 if (dgn)
2738 struct ScaBob *bob;
2739 WORD bx, by;
2741 bx = - gg->Width / 2;
2742 by = - gg->Height / 2;
2744 dgn->drgn_iconnode = in;
2745 dgn->drgn_icon = in->in_Icon;
2747 dgn->drgn_x = 0;
2748 dgn->drgn_y = 0;
2750 // create new Bob at end of drgh_boblist
2751 bob = InitDrag_ImageOnly(dgn, &iwt->iwt_myDragHandle->drgh_SpecialBobList, rp, iwt, bx, by);
2753 // find bob
2754 if (bob)
2756 *BobPtr = bob;
2758 bob->scbob_Flags |= BOBFLAGF_NeverTransparent;
2760 Success = TRUE;
2764 return Success;
2768 // Add or remove special indicator bob
2769 // used with custom bob routines
2770 static void CheckSpecialBobCustom(struct DragHandle *dh, ULONG Flags,
2771 ULONG MaskBit, struct ScaBob **bob, CONST_STRPTR FirstName, CONST_STRPTR FallbackName)
2773 BOOL changed = FALSE;
2775 if (Flags && !(dh->drgh_flags & MaskBit))
2777 // Add Indicator
2778 if (NULL == *bob)
2780 struct RastPort rp;
2782 InitRastPort(&rp);
2783 if (!AddSpecialIcon(dh->drgh_iwt, &rp, FirstName, bob))
2784 AddSpecialIcon(dh->drgh_iwt, &rp, FallbackName, bob);
2787 if (*bob)
2789 RemoveCustomBobsFromScreen(&dh->drgh_boblist);
2791 SCA_MoveBobNode(&dh->drgh_SpecialBobList, &dh->drgh_boblist, *bob);
2793 dh->drgh_flags |= MaskBit;
2795 (*bob)->scbob_Bob.scbob_Bob2.scbob2_xpos = (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastxpos = (WORD) NO_BOB_POSITION;
2796 (*bob)->scbob_Bob.scbob_Bob2.scbob2_ypos = (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastypos = (WORD) NO_BOB_POSITION;
2798 changed = TRUE;
2801 if (!Flags && (dh->drgh_flags & MaskBit))
2803 // Remove Indicator
2804 d1(kprintf("%s/%s/%ld: bob=%08lx\n", __FILE__, __FUNC__, __LINE__, *bob));
2806 if ((*bob)->scbob_Bob.scbob_Bob2.scbob2_backbitmap && IsBobPosition((*bob)->scbob_Bob.scbob_Bob2.scbob2_lastxpos))
2808 // bob needs to be removed from screen
2809 ClipBlitOut((*bob)->scbob_draghandle->drgh_screen,
2810 (*bob)->scbob_Bob.scbob_Bob2.scbob2_backbitmap,
2811 (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastxpos, (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastypos,
2812 (*bob)->scbob_width, (*bob)->scbob_height);
2815 SCA_MoveBobNode(&dh->drgh_boblist, &dh->drgh_SpecialBobList, *bob);
2817 RemoveCustomBobsFromScreen(&dh->drgh_boblist);
2819 (*bob)->scbob_Bob.scbob_Bob2.scbob2_xpos = (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastxpos = (WORD) NO_BOB_POSITION;
2820 (*bob)->scbob_Bob.scbob_Bob2.scbob2_ypos = (*bob)->scbob_Bob.scbob_Bob2.scbob2_lastypos = (WORD) NO_BOB_POSITION;
2822 dh->drgh_flags &= ~MaskBit;
2823 changed = TRUE;
2825 if (changed)
2826 FreeSpeedBitMapAlloc(dh);
2830 // Add or remove special indicator bob
2831 // used with system bob routines
2832 static void CheckSpecialBob(struct DragHandle *dh, ULONG Flags,
2833 ULONG MaskBit, struct ScaBob **bob, CONST_STRPTR FirstName, CONST_STRPTR FallbackName)
2835 if (Flags && !(dh->drgh_flags & MaskBit))
2837 // Add Indicator
2838 if (NULL == *bob)
2840 struct RastPort rp;
2842 InitRastPort(&rp);
2843 if (!AddSpecialIcon(dh->drgh_iwt, &rp, FirstName, bob))
2844 AddSpecialIcon(dh->drgh_iwt, &rp, FallbackName, bob);
2846 if (*bob)
2848 SCA_MoveBobNode(&dh->drgh_SpecialBobList, &dh->drgh_boblist, *bob);
2850 dh->drgh_flags |= MaskBit;
2852 if (!(dh->drgh_flags & DRGF_BobsHidden))
2853 AddBob(&(*bob)->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort);
2856 if (!Flags && (dh->drgh_flags & MaskBit))
2858 // Remove Indicator
2859 if (!(dh->drgh_flags & DRGF_BobsHidden))
2860 RemIBob(&(*bob)->scbob_Bob.scbob_Bob1.scbob1_bob, &dh->drgh_screen->RastPort, &dh->drgh_screen->ViewPort);
2862 SCA_MoveBobNode(&dh->drgh_boblist, &dh->drgh_SpecialBobList, *bob);
2864 dh->drgh_flags &= ~MaskBit;
2869 void EndDrag(struct internalScaWindowTask *iwt)
2871 d1(kprintf("%s/%s/%ld: iwt=%08lx DragFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt, iwt->iwt_DragFlags));
2872 d1(kprintf("%s/%s/%ld: WinUnderPtr=%08lx DragFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, \
2873 iwt->iwt_WinUnderPtr, iwt->iwt_WinUnderPtr ? iwt->iwt_WinUnderPtr->iwt_DragFlags : 0l));
2875 SCA_EndDrag(iwt->iwt_myDragHandle); // side effect: does UnlockLayers()
2877 iwt->iwt_myDragHandle = NULL;
2881 void EndDragUnlock(struct internalScaWindowTask *iwt)
2883 SCA_FreeAllNodes((struct ScalosNodeList *) &iwt->iwt_DragNodeList);
2885 if (iwt->iwt_IconListDDLocked)
2887 iwt->iwt_IconListDDLocked = FALSE;
2888 ScalosUnLockIconList(iwt);
2893 static BOOL AddInfoTextBob(struct internalScaWindowTask *iwt)
2895 BOOL Success = FALSE;
2896 STRPTR TextBuffer[3] = { NULL, NULL, NULL };
2897 struct BitMap *bm = NULL;
2898 APTR Mask = NULL;
2899 short n;
2901 do {
2902 struct RastPort rp;
2903 struct TextExtent tExt[3];
2904 WORD Width, Height;
2905 WORD x, y;
2906 LONG Len, yMax;
2907 struct ScaBob *bob;
2909 memset(tExt, 0, sizeof(tExt));
2911 for (n=0; n<3; n++)
2913 TextBuffer[n] = AllocPathBuffer();
2914 if (NULL == TextBuffer[n])
2915 break;
2917 strcpy(TextBuffer[n], "");
2920 if (iwt->iwt_myDragHandle->drgh_DrawerCount + iwt->iwt_myDragHandle->drgh_DeviceCount
2921 + iwt->iwt_myDragHandle->drgh_FileCount > 1)
2923 if (iwt->iwt_myDragHandle->drgh_FileCount > 0)
2925 ScaFormatStringMaxLength(TextBuffer[0], Max_PathLen,
2926 GetLocString(MSGID_MULTIDRAG),
2927 iwt->iwt_myDragHandle->drgh_FileCount,
2928 (IPTR) GetLocString(1 == iwt->iwt_myDragHandle->drgh_FileCount ? MSGID_MULTIDRAG_FILE_1 : MSGID_MULTIDRAG_FILE_2)
2931 if (iwt->iwt_myDragHandle->drgh_DrawerCount > 0)
2933 ScaFormatStringMaxLength(TextBuffer[1], Max_PathLen,
2934 GetLocString(MSGID_MULTIDRAG),
2935 iwt->iwt_myDragHandle->drgh_DrawerCount,
2936 (IPTR) GetLocString(1 == iwt->iwt_myDragHandle->drgh_DrawerCount ? MSGID_MULTIDRAG_DRAWER_1 : MSGID_MULTIDRAG_DRAWER_2)
2939 if (iwt->iwt_myDragHandle->drgh_DeviceCount > 0)
2941 ScaFormatStringMaxLength(TextBuffer[2], Max_PathLen,
2942 GetLocString(MSGID_MULTIDRAG),
2943 iwt->iwt_myDragHandle->drgh_DeviceCount,
2944 (IPTR) GetLocString(1 == iwt->iwt_myDragHandle->drgh_DeviceCount ? MSGID_MULTIDRAG_DEVICE_1 : MSGID_MULTIDRAG_DEVICE_2)
2949 for (Len=0, n=0; n<3; n++)
2951 Len += strlen(TextBuffer[n]);
2954 if (0 == Len)
2955 break;
2957 // find position for text bob (just below all othe bobs)
2958 yMax = -1;
2959 for (bob=iwt->iwt_myDragHandle->drgh_boblist; bob; bob = (struct ScaBob *) bob->scbob_Node.mln_Succ)
2961 if (bob->scbob_y + bob->scbob_height > yMax)
2962 yMax = bob->scbob_y + bob->scbob_height;
2965 Scalos_InitRastPort(&rp);
2966 Scalos_SetFont(&rp, iwt->iwt_IconFont, &iwt->iwt_IconTTFont);
2967 SetABPenDrMd(&rp, PalettePrefs.pal_PensList[PENIDX_DRAGINFOTEXT_TEXT],
2968 PalettePrefs.pal_PensList[PENIDX_DRAGINFOTEXT_BG], JAM1);
2970 for (n=0; n<3; n++)
2972 if (*TextBuffer[n])
2973 Scalos_TextExtent(&rp, TextBuffer[n], strlen(TextBuffer[n]), &tExt[n]);
2976 Width = Height = 0;
2977 for (n=0; n<3; n++)
2979 if (tExt[n].te_Width > Width)
2980 Width = tExt[n].te_Width;
2982 Height += tExt[n].te_Height;
2985 bm = AllocBitMap(Width, Height,
2986 GetBitMapAttr(iwt->iwt_myDragHandle->drgh_screen->RastPort.BitMap, BMA_DEPTH),
2987 BMF_STANDARD,
2988 iwt->iwt_myDragHandle->drgh_screen->RastPort.BitMap);
2989 if (NULL == bm)
2990 break;
2992 rp.BitMap = bm;
2994 SetRast(&rp, PalettePrefs.pal_PensList[PENIDX_DRAGINFOTEXT_BG]);
2996 y = Scalos_GetFontBaseline(&rp);
2997 for (n=0; n<3; n++)
2999 x = (Width - tExt[n].te_Width) / 2 - tExt[n].te_Extent.MinX;
3001 Move(&rp, x, y);
3002 Scalos_Text(&rp, TextBuffer[n], strlen(TextBuffer[n]));
3004 y += tExt[n].te_Height;
3007 Success = SCA_AddBob(iwt->iwt_myDragHandle,
3008 bm, Mask,
3009 Width, Height,
3010 - Width / 2, yMax + 1);
3012 bob = internalAddBob(iwt->iwt_myDragHandle,
3013 &iwt->iwt_myDragHandle->drgh_boblist,
3014 bm, Mask, NULL,
3015 Width, Height,
3016 Width, Height,
3018 - Width / 2, yMax + 1);
3019 if (bob)
3021 Success = TRUE;
3022 bob->scbob_Flags |= BOBFLAGF_NeverTransparent | BOBFLAGF_NoOptimize;
3025 Scalos_DoneRastPort(&rp);
3026 } while (0);
3028 if (bm)
3029 FreeBitMap(bm);
3031 for (n=0; n<3; n++)
3033 if (TextBuffer[n])
3034 FreePathBuffer(TextBuffer[n]);
3037 return Success;
3041 static void CountDragObjects(struct DragHandle *drgh, const struct ScaIconNode *in)
3043 if (in->in_DeviceIcon)
3044 drgh->drgh_DeviceCount++;
3045 else
3047 if (in->in_Flags & INF_File)
3048 drgh->drgh_FileCount++;
3049 else
3050 drgh->drgh_DrawerCount++;
3055 void BlitARGB(ULONG SrcWidth, ULONG SrcHeight,
3056 const struct ARGB *Src, LONG SrcLeft, LONG SrcTop,
3057 ULONG DestWidth, struct ARGB *Dest, LONG DestLeft, LONG DestTop,
3058 ULONG Trans)
3060 ULONG y;
3061 ULONG a;
3062 ULONG mla;
3065 a = Trans + 1;
3066 mla = 257 - a;
3068 Src += SrcTop * SrcWidth;
3069 Dest += DestTop * DestWidth;
3071 for (y=0; y<SrcHeight; y++)
3073 ULONG x;
3074 const struct ARGB *SrcPtr = Src + SrcLeft;
3075 struct ARGB *DestPtr = Dest + DestLeft;
3077 for (x=0; x<SrcWidth; x++)
3079 d1(KPrintF("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, x, y));
3081 switch (a)
3083 case 0:
3084 case 1:
3085 break;
3086 case ALPHA_OPAQUE:
3087 *DestPtr = *SrcPtr;
3088 break;
3089 default:
3090 DestPtr->Red = (a * SrcPtr->Red + mla * DestPtr->Red) >> 8;
3091 DestPtr->Green = (a * SrcPtr->Green + mla * DestPtr->Green) >> 8;
3092 DestPtr->Blue = (a * SrcPtr->Blue + mla * DestPtr->Blue) >> 8;
3093 break;
3096 SrcPtr++;
3097 DestPtr++;
3100 Src += SrcWidth;
3101 Dest += DestWidth;
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;
3187 static void BlitARGBMaskAlpha(ULONG SrcWidth, ULONG SrcHeight,
3188 const struct ARGB *Src, LONG SrcLeft, LONG SrcTop,
3189 ULONG DestWidth, struct ARGB *Dest, LONG DestLeft, LONG DestTop,
3190 const struct BitMap *MaskBM, ULONG Trans,
3191 const UBYTE *Alpha, LONG AlphaLeft, ULONG AlphaWidth)
3193 UWORD MaskBytesPerRow = MaskBM->BytesPerRow;
3194 const UBYTE *Mask = MaskBM->Planes[0];
3195 ULONG y;
3198 d1(kprintf("%s/%s/%ld: Mask=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
3199 Mask[0], Mask[1], Mask[2], Mask[3], \
3200 Mask[4], Mask[5], Mask[6], Mask[7]));
3201 d1(kprintf("%s/%s/%ld: Mask=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx \n", __FILE__, __FUNC__, __LINE__, \
3202 Mask[8], Mask[9], Mask[10], Mask[11], \
3203 Mask[12], Mask[13], Mask[14], Mask[15]));
3205 d1(kprintf("%s/%s/%ld: SrcWidth=%ld\n", __FILE__, __FUNC__, __LINE__, SrcWidth));
3207 Src += SrcTop * SrcWidth;
3208 Dest += DestTop * DestWidth;
3210 d1(kprintf("%s/%s/%ld: SrcLeft=%ld SrcTop=%ld DestLeft=%ld DestTop=%08ld\n", \
3211 __FILE__, __FUNC__, __LINE__, SrcLeft, SrcTop, DestLeft, DestTop));
3212 d1(kprintf("%s/%s/%ld: Src=%08lx Dest=%08lx\n", __FILE__, __FUNC__, __LINE__, Src, Dest));
3214 for (y=0; y < SrcHeight; y++)
3216 ULONG x;
3217 UWORD BitMask = 0x0080;
3218 const UBYTE *MaskPtr2 = Mask;
3219 const struct ARGB *SrcPtr = Src + SrcLeft;
3220 struct ARGB *DestPtr = Dest + DestLeft;
3221 const UBYTE *AlphaPtr = Alpha + AlphaLeft;
3223 for (x=0; x < SrcWidth; x++)
3225 d1(kprintf("%s/%s/%ld: x=%ld y=%ld MaskPtr2=%08lx *MaskPtr2=%02lx BitMask=%02lx\n", \
3226 __FILE__, __FUNC__, __LINE__, x, y, MaskPtr2, *MaskPtr2, BitMask));
3228 if (*MaskPtr2 & BitMask)
3230 ULONG a;
3231 ULONG mla;
3233 d1(kprintf("%s/%s/%ld: x=%ld y=%ld *Mask=%02lx BitMask=%02lx\n", __FILE__, __FUNC__, __LINE__, x, y, *Mask, BitMask));
3235 a = (ULONG) *AlphaPtr;
3236 a = ((Trans * a) >> 8) + 1;
3238 switch (a)
3240 case 0:
3241 case 1:
3242 break;
3243 case ALPHA_OPAQUE:
3244 *DestPtr = *SrcPtr;
3245 break;
3246 default:
3247 mla = 257 - a;
3248 DestPtr->Red = (a * SrcPtr->Red + mla * DestPtr->Red) >> 8;
3249 DestPtr->Green = (a * SrcPtr->Green + mla * DestPtr->Green) >> 8;
3250 DestPtr->Blue = (a * SrcPtr->Blue + mla * DestPtr->Blue) >> 8;
3251 break;
3255 SrcPtr++;
3256 DestPtr++;
3257 AlphaPtr++;
3259 BitMask >>= 1;
3260 if (0 == BitMask)
3262 BitMask = 0x0080;
3263 MaskPtr2++;
3267 Alpha += AlphaWidth;
3268 Mask += MaskBytesPerRow;
3269 Src += SrcWidth;
3270 Dest += DestWidth;
3274 //----------------------------------------------------------------------------
3275 #ifdef DEBUG_SCALOS
3276 static void DumpBitMap(struct BitMap *bm)
3278 struct RastPort rp;
3279 ULONG y;
3280 LONG Width, Height, Depth;
3282 Width = GetBitMapAttr(bm, BMA_WIDTH);
3283 Height = GetBitMapAttr(bm, BMA_HEIGHT);
3284 Depth = GetBitMapAttr(bm, BMA_DEPTH);
3286 KPrintF("%s/%s/%ld: START Width=%ld Height=%ld Depth=%ld\n", __FILE__, __FUNC__, __LINE__, Width, Height, Depth);
3288 InitRastPort(&rp);
3289 rp.BitMap = bm;
3291 for (y = 0; y < Height; y++)
3293 ULONG x;
3295 for (x = 0; x < Width; x++)
3297 ULONG px = ReadPixel(&rp, x, y);
3299 KPrintF("%ld ", px);
3302 KPrintF("\n");
3305 KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__);
3307 #endif
3308 //----------------------------------------------------------------------------