using kprintf to output debug, which may be redirected to serial, is not a good idea...
[AROS-Contrib.git] / scalos / main / IconWindow_MouseMove.c
blob61f74e2054a4335717beebb3af87a96974eb273d
1 // IconWindow_MouseMove.c
2 // $Date$
3 // $Revision$
6 #include <exec/types.h>
7 #include <graphics/gels.h>
8 #include <graphics/rastport.h>
9 #include <intuition/classes.h>
10 #include <intuition/classusr.h>
11 #include <utility/hooks.h>
12 #include <workbench/workbench.h>
13 #include <workbench/startup.h>
14 #include <dos/dostags.h>
16 #define __USE_SYSBASE
18 #include <proto/dos.h>
19 #include <proto/exec.h>
20 #include <proto/layers.h>
21 #include <proto/intuition.h>
22 #include "debug.h"
23 #include <proto/scalos.h>
25 #include <clib/alib_protos.h>
27 #include <defs.h>
28 #include <datatypes/iconobject.h>
29 #include <scalos/scalos.h>
30 #include <scalos/scalosprefs.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
36 #include <DefIcons.h>
38 #include "scalos_structures.h"
39 #include "functions.h"
40 #include "Variables.h"
42 //-----------------------------------------------------------------------
44 // local data definitions
46 //----------------------------------------------------------------------------
48 // local functions
50 static LONG GetSourceDestScaSameLock(struct internalScaWindowTask *iwt);
51 static BPTR GetIconLock(struct internalScaWindowTask *iwt, struct ScaIconNode *in);
52 static ULONG DragMayCopy(struct internalScaWindowTask *iwt, ULONG Qualifier);
53 static BOOL IsIconifiedScalosWindow(struct internalScaWindowTask *iwt, struct ScaIconNode *in);
54 static void CheckNeedScroll(struct internalScaWindowTask *iwt, WORD xw, WORD yw);
55 static void DoDragScroll(struct internalScaWindowTask *iwtSrc, struct internalScaWindowTask *iwtDest);
57 //----------------------------------------------------------------------------
59 // local data
61 static const WORD DRAG_Threshold = 4;
63 //----------------------------------------------------------------------------
65 void IDCMPDragMouseMove(struct internalScaWindowTask *iwt, struct IntuiMessage *msg)
67 struct internalScaWindowTask *swit;
68 struct ScaIconNode *in;
69 struct ScaIconNode *inOuterBounds;
70 struct Window *foreignWin;
71 ULONG DrawDragFlags = 0;
72 BOOL DestChange = FALSE; // Flag: mouse is now over different object
73 WORD dX, dY;
75 dX = msg->MouseX - iwt->iwt_StartDragMouseX;
76 if (dX < 0)
77 dX = -dX;
79 dY = msg->MouseY - iwt->iwt_StartDragMouseY;
80 if (dY < 0)
81 dY = -dY;
83 if (dX >= DRAG_Threshold || dY >= DRAG_Threshold)
85 iwt->iwt_StartDragMouseX = (WORD) 0x8000; // make sure DRAG_Threshold is always hit now
86 iwt->iwt_StartDragMouseY = (WORD) 0x8000;
88 iwt->iwt_ObjectUnderMouse = OUM_nothing;
90 DrawDrag(SCAF_Drag_NoDrawDrag, iwt); // make sure icons get removed
92 if (iwt->iwt_myDragHandle)
93 iwt->iwt_myDragHandle->drgh_flags |= DRGF_DragStarted;
95 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
97 QueryObjectUnderPointer(&swit, &in, &inOuterBounds, &foreignWin);
99 d1(kprintf("%s/%s/%ld: swit=%08lx\n", __FILE__, __FUNC__, __LINE__, swit));
101 if (swit)
103 // Pointer is inside a Scalos Window
104 struct ScaIconNode *inOrig = in;
105 struct DragNode *dn;
106 BOOL IconOverlap = FALSE;
107 WORD x, y;
109 iwt->iwt_ObjectUnderMouse = OUM_ScalosWindow;
111 d1(kprintf("%s/%s/%ld: WinUnderPtr=%08lx swit=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_WinUnderPtr, swit));
113 x = msg->MouseX + iwt->iwt_WindowTask.wt_Window->LeftEdge - swit->iwt_WindowTask.wt_Window->LeftEdge - swit->iwt_InnerLeft + swit->iwt_WindowTask.wt_XOffset;
114 y = msg->MouseY + iwt->iwt_WindowTask.wt_Window->TopEdge - swit->iwt_WindowTask.wt_Window->TopEdge - swit->iwt_InnerTop + swit->iwt_WindowTask.wt_YOffset;
116 if (swit != iwt->iwt_WinUnderPtr)
118 // pointer entered different window
120 DestChange = TRUE;
122 d1(kprintf("%s/%s/%ld: New Scalos Window swit=%08lx\n", __FILE__, __FUNC__, __LINE__, swit));
124 if (iwt->iwt_WinUnderPtr)
126 if (iwt->iwt_IconUnderPtr)
128 // signal pointer leaving old icon
129 DoMethod(iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_MainObject,
130 SCCM_IconWin_DragLeave,
131 iwt->iwt_WindowTask.mt_WindowStruct,
132 iwt->iwt_IconUnderPtr,
133 x, y);
135 iwt->iwt_IconUnderPtr = NULL;
138 // signal pointer leaving old window
139 DoMethod(iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_MainObject,
140 SCCM_IconWin_DragLeave,
141 iwt->iwt_WindowTask.mt_WindowStruct,
142 NULL,
143 x, y);
145 iwt->iwt_WinUnderPtr = NULL;
146 iwt->iwt_IconOuterUBUnderPtr = NULL;
149 // query window if icons may be dropped on it
150 iwt->iwt_DragMayDrop = DoMethod(swit->iwt_WindowTask.mt_MainObject,
151 SCCM_IconWin_DragQuery,
152 iwt->iwt_WindowTask.mt_WindowStruct,
153 NULL,
154 x, y);
156 // signal pointer entering new window
157 DoMethod(swit->iwt_WindowTask.mt_MainObject,
158 SCCM_IconWin_DragEnter,
159 iwt->iwt_WindowTask.mt_WindowStruct,
160 NULL,
161 x, y);
163 iwt->iwt_WinUnderPtr = swit;
164 iwt->iwt_IconOuterUBUnderPtr = NULL;
166 else
168 // same window as before
169 if (NULL == inOuterBounds && NULL == in)
171 WORD xw = msg->MouseX + iwt->iwt_WindowTask.wt_Window->LeftEdge - swit->iwt_WindowTask.wt_Window->LeftEdge;
172 WORD yw = msg->MouseY + iwt->iwt_WindowTask.wt_Window->TopEdge - swit->iwt_WindowTask.wt_Window->TopEdge;
174 // we are not over any icon
175 CheckNeedScroll(swit, xw, yw);
177 DoDragScroll(iwt, swit);
179 else
181 swit->iwt_DragScrollX = swit->iwt_DragScrollY = 0;
185 d1(kprintf("%s/%s/%ld: IconList=%08lx\n", __FILE__, __FUNC__, __LINE__, swit->iwt_WindowTask.wt_IconList));
187 // now check icons
189 // check if <in> is one of the icons being dragged
190 for (dn = iwt->iwt_DragNodeList; in && dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
192 if (dn->drgn_icon == in->in_Icon)
193 in = NULL;
196 d1(kprintf("%s/%s/%ld: in=%08lx IconUnderPtr=%08lx\n", __FILE__, __FUNC__, __LINE__, \
197 in, iwt->iwt_IconUnderPtr));
198 d1(kprintf("%s/%s/%ld: inOuterBounds=%08lx IconOuterUBUnderPtr=%08lx\n", \
199 __FILE__, __FUNC__, __LINE__, inOuterBounds, iwt->iwt_IconOuterUBUnderPtr));
201 if (!CurrentPrefs.pref_DDIconsMayOverlap && inOuterBounds != iwt->iwt_IconOuterUBUnderPtr)
203 d1(kprintf("%s/%s/%ld: WinUnderPtr=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_WinUnderPtr));
205 d1(kprintf("%s/%s/%ld: inOuterBounds=%08lx <%s> iwt_IconOuterUBUnderPtr=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, \
206 inOuterBounds, inOuterBounds ? inOuterBounds->in_Name : (STRPTR) "", \
207 iwt->iwt_IconOuterUBUnderPtr, \
208 iwt->iwt_IconOuterUBUnderPtr ? iwt->iwt_IconOuterUBUnderPtr->in_Name : (STRPTR) ""));
211 iwt->iwt_DragMayDrop = (NULL == inOuterBounds);
212 IconOverlap = !iwt->iwt_DragMayDrop;
214 d1(kprintf("%s/%s/%ld: DragMayDrop=%ld\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_DragMayDrop));
216 iwt->iwt_IconOuterUBUnderPtr = inOuterBounds;
219 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
221 if (in != iwt->iwt_IconUnderPtr)
223 d1(kprintf("%s/%s/%ld: WinUnderPtr=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_WinUnderPtr));
225 DestChange = TRUE;
227 d1(kprintf("%s/%s/%ld: in=%08lx <%s> IconUnderPtr=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, \
228 in, in ? in->in_Name : (STRPTR) "", \
229 iwt->iwt_IconUnderPtr, \
230 iwt->iwt_IconUnderPtr ? iwt->iwt_IconUnderPtr->in_Name : (STRPTR) ""));
232 // query icon or window if icons may be dropped on it
233 iwt->iwt_DragMayDrop = !IconOverlap && DoMethod(iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_MainObject,
234 SCCM_IconWin_DragQuery,
235 iwt->iwt_WindowTask.mt_WindowStruct,
237 x, y);
239 if (iwt->iwt_IconUnderPtr)
241 DoMethod(iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_MainObject,
242 SCCM_IconWin_DragLeave,
243 iwt->iwt_WindowTask.mt_WindowStruct,
244 iwt->iwt_IconUnderPtr,
245 x, y);
248 d1(kprintf("%s/%s/%ld: DragMayDrop=%ld\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_DragMayDrop));
250 if (in)
252 // enter new icon
253 DoMethod(iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_MainObject,
254 SCCM_IconWin_DragEnter,
255 iwt->iwt_WindowTask.mt_WindowStruct,
257 x, y);
259 iwt->iwt_ObjectUnderMouse = OUM_Icon;
262 iwt->iwt_IconUnderPtr = in;
265 if (inOrig)
266 ScalosUnLockIconList(swit);
268 SCA_UnLockWindowList();
270 else if (foreignWin)
272 // foreign (non-scalos) window found
273 struct internalScaWindowTask *iwtx = (struct internalScaWindowTask *) iInfos.xii_iinfos.ii_AppWindowStruct->ws_WindowTask;
275 iwt->iwt_ObjectUnderMouse = OUM_ForeignWindow;
277 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
279 if (iwt->iwt_WinUnderPtr)
281 if (iwt->iwt_IconUnderPtr)
283 // signal pointer leaving icon
284 DoMethod(iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_MainObject,
285 SCCM_IconWin_DragLeave,
286 iwt->iwt_WindowTask.mt_WindowStruct,
287 iwt->iwt_IconUnderPtr,
288 0, 0);
289 iwt->iwt_IconUnderPtr = NULL;
292 // signal pointer leaving window
293 DoMethod(iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_MainObject,
294 SCCM_IconWin_DragLeave,
295 iwt->iwt_WindowTask.mt_WindowStruct,
296 NULL,
297 0, 0);
299 iwt->iwt_WinUnderPtr = NULL;
300 iwt->iwt_IconOuterUBUnderPtr = NULL;
303 if (ScalosAttemptSemaphoreShared(iwtx->iwt_AppListSemaphore))
305 struct AppObject *an;
307 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
309 for (an=iwtx->iwt_AppList; an; an = (struct AppObject *) an->appo_Node.mln_Succ)
311 if (APPTYPE_AppWindow == an->appo_type &&
312 an->appo_object.appoo_Window == foreignWin)
314 // Mouse is inside AppWindow
315 iwt->iwt_DragMayDrop = TRUE;
316 iwt->iwt_ObjectUnderMouse = OUM_AppWindow;
318 d1(kprintf("%s/%s/%ld: AppWindow found AppObject=%08lx\n", __FILE__, __FUNC__, __LINE__, an));
322 ScalosReleaseSemaphore(iwtx->iwt_AppListSemaphore);
326 if (DestChange)
328 iwt->iwt_SameLock = GetSourceDestScaSameLock(iwt);
331 if (DRAGTRANSPMODE_TranspAndSolid == CurrentPrefs.pref_DragTranspMode
332 || DRAGTRANSPMODE_SolidAndTransp == CurrentPrefs.pref_DragTranspMode)
334 ULONG TranspFlags = 0;
336 d1(kprintf("%s/%s/%ld: ObjectUnderMouse=%ld\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_ObjectUnderMouse));
338 if (iwt->iwt_IconUnderPtr)
339 iwt->iwt_ObjectUnderMouse = OUM_Icon;
340 else if (iwt->iwt_WinUnderPtr)
341 iwt->iwt_ObjectUnderMouse = OUM_ScalosWindow;
343 switch (iwt->iwt_ObjectUnderMouse)
345 case OUM_ScalosWindow:
346 TranspFlags = DRAGTRANSPF_ScalosWindows;
347 break;
348 case OUM_AppWindow:
349 TranspFlags = DRAGTRANSPF_AppWindows;
350 break;
351 case OUM_Icon:
352 if (iwt->iwt_DragMayDrop && iwt->iwt_IconUnderPtr)
354 IPTR IconType;
356 GetAttr(IDTA_Type, iwt->iwt_IconUnderPtr->in_Icon, &IconType);
358 d1(KPrintF("%s/%s/%ld: <%s> IconType=%08lx\n", __FILE__, __FUNC__, __LINE__, GetIconName(iwt->iwt_IconUnderPtr), IconType));
359 switch (IconType)
361 case WBDISK:
362 TranspFlags = DRAGTRANSPF_DiskIcons;
363 break;
364 case WBDRAWER:
365 case WB_TEXTICON_DRAWER:
366 TranspFlags = DRAGTRANSPF_DrawerIcons;
367 break;
368 case WBTOOL:
369 case WB_TEXTICON_TOOL:
370 TranspFlags = DRAGTRANSPF_ToolIcons;
371 break;
372 case WBPROJECT:
373 TranspFlags = DRAGTRANSPF_ProjectIcons;
374 break;
375 case WBGARBAGE:
376 TranspFlags = DRAGTRANSPF_TrashcanIcons;
377 break;
378 case WBKICK:
379 TranspFlags = DRAGTRANSPF_KickIcons;
380 break;
381 case WBAPPICON:
382 if (IsIconifiedScalosWindow(iwt, iwt->iwt_IconUnderPtr))
383 TranspFlags = DRAGTRANSPF_IconifiedWinIcons;
384 else
385 TranspFlags = DRAGTRANSPF_AppIcons;
386 break;
387 default:
388 break;
390 d1(KPrintF("%s/%s/%ld: pref_DragTranspObjects=%08lx TranspFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, CurrentPrefs.pref_DragTranspObjects, TranspFlags));
392 break;
393 default:
394 break;
397 if (((DRAGTRANSPMODE_SolidAndTransp == CurrentPrefs.pref_DragTranspMode)
398 && (CurrentPrefs.pref_DragTranspObjects & TranspFlags)) ||
399 ((DRAGTRANSPMODE_TranspAndSolid == CurrentPrefs.pref_DragTranspMode)
400 && !(CurrentPrefs.pref_DragTranspObjects & TranspFlags)) )
401 DrawDragFlags |= SCAF_Drag_Transparent;
404 d1(kprintf("%s/%s/%ld: DrawDragFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, DrawDragFlags));
406 if (!iwt->iwt_DragMayDrop)
407 DrawDragFlags |= SCAF_Drag_NoDropHere;
408 else
409 DrawDragFlags |= DragMayCopy(iwt, msg->Qualifier);
412 d1(kprintf("%s/%s/%ld: DrawDragFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, DrawDragFlags));
414 DrawDrag(DrawDragFlags, iwt);
416 d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
420 void IconWin_EndDrag(struct internalScaWindowTask *iwt)
422 d1(kprintf("%s/%s/%ld: iwt=%08lx DragFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt, iwt->iwt_DragFlags));
423 d1(kprintf("%s/%s/%ld: WinUnderPtr=%08lx DragFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, \
424 iwt->iwt_WinUnderPtr, iwt->iwt_WinUnderPtr ? iwt->iwt_WinUnderPtr->iwt_DragFlags : 0l));
426 if (iwt->iwt_WinUnderPtr)
428 if (iwt->iwt_IconUnderPtr)
430 // signal pointer leaving old icon
431 DoMethod(iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_MainObject,
432 SCCM_IconWin_DragLeave,
433 iwt->iwt_WindowTask.mt_WindowStruct,
434 iwt->iwt_IconUnderPtr,
435 0, 0);
437 iwt->iwt_IconUnderPtr = NULL;
440 // signal pointer leaving old window
441 DoMethod(iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_MainObject,
442 SCCM_IconWin_DragLeave,
443 iwt->iwt_WindowTask.mt_WindowStruct,
444 NULL,
445 0, 0);
447 iwt->iwt_WinUnderPtr = NULL;
450 iwt->iwt_IconOuterUBUnderPtr = NULL;
451 iwt->iwt_ObjectUnderMouse = OUM_nothing;
453 // erase icon shadows
454 if (iwt->iwt_IconShadowVisible)
456 RemoveIcons(iwt, &iwt->iwt_DragIconList);
457 iwt->iwt_IconShadowVisible = FALSE;
462 static LONG GetSourceDestScaSameLock(struct internalScaWindowTask *iwt)
464 LONG Result;
465 BPTR srcLock = iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock;
466 BPTR destLock = (BPTR)NULL;
467 BPTR IconLock = (BPTR)NULL;
469 if (iwt->iwt_DragNodeList->drgn_iconnode->in_Lock)
470 srcLock = iwt->iwt_DragNodeList->drgn_iconnode->in_Lock;
472 d1(kprintf("%s/%s/%ld: iwt=%08lx ObjUnderMouse=%ld\n", __FILE__, __FUNC__, __LINE__, iwt, iwt->iwt_ObjectUnderMouse));
474 switch (iwt->iwt_ObjectUnderMouse)
476 case OUM_ScalosWindow:
477 destLock = iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_WindowStruct->ws_Lock;
478 d1(kprintf("%s/%s/%ld: ScalosWindow Lock=%08lx\n", __FILE__, __FUNC__, __LINE__, destLock));
479 break;
481 case OUM_Icon:
482 d1(kprintf("%s/%s/%ld: Icon=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_IconUnderPtr));
484 if (iwt->iwt_IconUnderPtr)
486 IPTR IconType;
488 GetAttr(IDTA_Type, iwt->iwt_IconUnderPtr->in_Icon, &IconType);
490 d1(kprintf("%s/%s/%ld: <%s> Lock=%08lx Type=%ld\n", __FILE__, __FUNC__, __LINE__, \
491 iwt->iwt_IconUnderPtr->in_Name, iwt->iwt_IconUnderPtr->in_Lock, IconType));
493 switch (IconType)
495 case WBDISK:
496 case WBDRAWER:
497 case WB_TEXTICON_DRAWER:
498 case WBGARBAGE:
499 destLock = IconLock = GetIconLock(iwt->iwt_WinUnderPtr, iwt->iwt_IconUnderPtr);
500 break;
501 default:
502 break;
505 break;
506 default:
507 break;
510 if (destLock)
511 Result = ScaSameLock(destLock, srcLock);
512 else
513 Result = LOCK_SAME;
515 if (IconLock)
516 UnLock(IconLock);
518 return Result;
522 // get a Lock to an icon
523 static BPTR GetIconLock(struct internalScaWindowTask *iwt, struct ScaIconNode *in)
525 BPTR iLock;
526 IPTR IconType;
528 GetAttr(IDTA_Type, in->in_Icon, &IconType);
530 if (WBDISK == IconType && in->in_DeviceIcon)
532 // this is a Device, i.e. RAM:, DF0:
533 iLock = Lock(in->in_DeviceIcon->di_Volume, ACCESS_READ);
535 else if (in->in_Lock)
536 iLock = DupLock(in->in_Lock);
537 else
539 BPTR oldDir = CurrentDir(iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock);
540 iLock = Lock(in->in_Name, ACCESS_READ);
541 CurrentDir(oldDir);
544 return iLock;
548 // Mouse moved, MMB pressed
549 void IDCMPMMBMouseMove(struct internalScaWindowTask *iwt)
551 WORD oldXOffset, oldYOffset;
552 LONG dx, dy;
553 ULONG Flags = 0;
554 LONG x = iwt->iwt_WindowTask.wt_Window->MouseX;
555 LONG y = iwt->iwt_WindowTask.wt_Window->MouseY;
557 if (x == iwt->iwt_OldMouse.X && y == iwt->iwt_OldMouse.Y)
558 return;
560 dx = iwt->iwt_OldMouse.X - x;
561 dy = iwt->iwt_OldMouse.Y - y;
563 iwt->iwt_OldMouse.X = x;
564 iwt->iwt_OldMouse.Y = y;
566 if (2 == CurrentPrefs.pref_MMBMoveFlag)
568 dx = -dx;
569 dy = -dy;
572 oldXOffset = iwt->iwt_WindowTask.wt_XOffset;
573 oldYOffset = iwt->iwt_WindowTask.wt_YOffset;
575 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_DeltaMove, dx, dy);
577 if (oldXOffset != iwt->iwt_WindowTask.wt_XOffset)
578 Flags |= SETVIRTF_AdjustBottomSlider;
579 if (oldYOffset != iwt->iwt_WindowTask.wt_YOffset)
580 Flags |= SETVIRTF_AdjustRightSlider;
582 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_SetVirtSize, Flags);
586 static ULONG DragMayCopy(struct internalScaWindowTask *iwt, ULONG Qualifier)
588 struct DragNode *dn;
589 ULONG DrawDragFlags = 0l;
590 IPTR IconType;
591 BOOL isBackDropIcon = FALSE;
593 DrawDragFlags &= ~(SCAF_Drag_IndicateCopy | SCAF_Drag_IndicateMakeLink | SCAF_Drag_ForceMove);
595 switch (iwt->iwt_ObjectUnderMouse)
597 case OUM_ScalosWindow:
598 for (dn = iwt->iwt_DragNodeList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
600 if (dn->drgn_iconnode->in_Lock)
601 isBackDropIcon = TRUE;
603 if (dn->drgn_iconnode->in_DeviceIcon &&
604 iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_WindowStruct->ws_WindowType != WSV_Type_DeviceWindow)
606 // dragging device icon to non-main window is allowed - always copy
607 if (isMakeLinkQualifier(Qualifier))
609 DrawDragFlags |= SCAF_Drag_IndicateMakeLink;
611 else
613 DrawDragFlags |= SCAF_Drag_IndicateCopy;
618 if ((isBackDropIcon || iwt->iwt_WindowTask.mt_WindowStruct->ws_WindowType != WSV_Type_DeviceWindow) && // no copy from main window
619 iwt->iwt_WinUnderPtr->iwt_WindowTask.mt_WindowStruct->ws_WindowType != WSV_Type_DeviceWindow) // no copy to main window
621 if (isMakeLinkQualifier(Qualifier))
623 DrawDragFlags |= SCAF_Drag_IndicateMakeLink;
625 else if (isMoveQualifier(Qualifier))
627 DrawDragFlags |= SCAF_Drag_ForceMove;
629 else if (isCopyQualifier(Qualifier))
631 DrawDragFlags |= SCAF_Drag_IndicateCopy;
633 else if (LOCK_DIFFERENT == iwt->iwt_SameLock)
635 // check if Src and Dest are on same volume
636 // if different volume then Copy
637 DrawDragFlags |= SCAF_Drag_IndicateCopy;
640 break;
642 case OUM_Icon:
643 GetAttr(IDTA_Type, iwt->iwt_IconUnderPtr->in_Icon, &IconType);
645 // only copy to drawer, device, disk icons
646 switch (IconType)
648 case WBDRAWER:
649 case WBDISK:
650 case WBDEVICE:
651 case WB_TEXTICON_DRAWER:
652 if (isMakeLinkQualifier(Qualifier))
654 DrawDragFlags |= SCAF_Drag_IndicateMakeLink;
656 else if (isMoveQualifier(Qualifier))
658 DrawDragFlags |= SCAF_Drag_ForceMove;
660 else if (isCopyQualifier(Qualifier))
662 DrawDragFlags |= SCAF_Drag_IndicateCopy;
664 else if (LOCK_DIFFERENT == iwt->iwt_SameLock)
666 // check if Src and Dest are on same volume
667 // if different volume then Copy
668 DrawDragFlags |= SCAF_Drag_IndicateCopy;
670 break;
671 default:
672 break;
674 break;
675 default:
676 break;
679 return DrawDragFlags;
683 static BOOL IsIconifiedScalosWindow(struct internalScaWindowTask *iwt, struct ScaIconNode *in)
685 struct AppObject *appo;
686 BOOL IsIconified = FALSE;
688 ScalosObtainSemaphoreShared(iwt->iwt_AppListSemaphore);
690 for (appo=iwt->iwt_AppList; appo; appo = (struct AppObject *) appo->appo_Node.mln_Succ)
692 if (APPTYPE_AppIcon == appo->appo_type
693 && in->in_Icon == appo->appo_object.appoo_IconObject
694 && MAKE_ID('I','C','F','Y') == appo->appo_id)
696 IsIconified = TRUE;
697 break;
701 ScalosReleaseSemaphore(iwt->iwt_AppListSemaphore);
703 return IsIconified;
707 static void CheckNeedScroll(struct internalScaWindowTask *iwt, WORD xw, WORD yw)
709 if (xw >= iwt->iwt_InnerLeft && xw < (iwt->iwt_InnerLeft + iwt->iwt_InnerWidth))
711 // xw is inside inner window area
713 if (yw < iwt->iwt_InnerTop)
715 // Scroll down
716 d1(KPrintF("%s/%s/%ld: iwt=%08lx xw=%ld yw=%ld scroll down\n", __FILE__, __FUNC__, __LINE__, iwt, xw, yw));
717 iwt->iwt_DragScrollY = yw - iwt->iwt_InnerTop;
719 else if (yw >= (iwt->iwt_InnerTop + iwt->iwt_InnerHeight))
721 // Scroll up
722 d1(KPrintF("%s/%s/%ld: iwt=%08lx xw=%ld yw=%ld scroll up\n", __FILE__, __FUNC__, __LINE__, iwt, xw, yw));
723 iwt->iwt_DragScrollY = yw - (iwt->iwt_InnerTop + iwt->iwt_InnerHeight);
725 else
727 iwt->iwt_DragScrollY = 0;
730 if (yw >= iwt->iwt_InnerTop && yw < (iwt->iwt_InnerTop + iwt->iwt_InnerHeight))
732 // yw is inside inner window area
734 if (xw < iwt->iwt_InnerLeft)
736 // Scroll right
737 d1(KPrintF("%s/%s/%ld: iwt=%08lx xw=%ld yw=%ld scroll right\n", __FILE__, __FUNC__, __LINE__, iwt, xw, yw));
738 iwt->iwt_DragScrollX = xw - iwt->iwt_InnerLeft;
740 else if (xw >= (iwt->iwt_InnerLeft + iwt->iwt_InnerWidth))
742 // Scroll left
743 d1(KPrintF("%s/%s/%ld: iwt=%08lx xw=%ld yw=%ld scroll left\n", __FILE__, __FUNC__, __LINE__, iwt, xw, yw));
744 iwt->iwt_DragScrollX = xw - (iwt->iwt_InnerLeft + iwt->iwt_InnerWidth);
746 else
748 iwt->iwt_DragScrollX = 0;
754 static void DoDragScroll(struct internalScaWindowTask *iwtSrc, struct internalScaWindowTask *iwtDest)
756 LONG DeltaX = 0, DeltaY = 0;
758 d1(KPrintF("%s/%s/%ld: iwtDest=%08lx iwtDest_DragScrollX=%ld iwtDest_DragScrollY=%ld\n", \
759 __FILE__, __FUNC__, __LINE__, iwtDest, iwtDest->iwt_DragScrollX, iwtDest->iwt_DragScrollY));
761 if (iwtDest->iwt_DragScrollY < 0)
763 d1(KPrintF("%s/%s/%ld: iwt_MinY=%ld iwt_InvisibleHeight=%ld iwt_InnerHeight=%ld wt_YOffset=%ld\n", \
764 __FILE__, __FUNC__, __LINE__, iwtDest->iwt_MinY, iwtDest->iwt_InvisibleHeight, \
765 iwtDest->iwt_InnerHeight, iwtDest->iwt_WindowTask.wt_YOffset));
767 if ((iwtDest->iwt_MinY + 1) < iwtDest->iwt_WindowTask.wt_YOffset)
769 DeltaY = iwtDest->iwt_DragScrollY;
772 else if (iwtDest->iwt_DragScrollY > 0)
774 d1(KPrintF("%s/%s/%ld: iwt_MinY=%ld iwt_InvisibleHeight=%ld iwt_InnerHeight=%ld wt_YOffset=%ld\n", \
775 __FILE__, __FUNC__, __LINE__, iwtDest->iwt_MinY, iwtDest->iwt_InvisibleHeight, \
776 iwtDest->iwt_InnerHeight, iwtDest->iwt_WindowTask.wt_YOffset));
778 if ((iwtDest->iwt_MinY + iwtDest->iwt_InvisibleHeight) > iwtDest->iwt_WindowTask.wt_YOffset)
780 DeltaY = iwtDest->iwt_DragScrollY;
784 if (iwtDest->iwt_DragScrollX < 0)
786 if ((iwtDest->iwt_MinX + 1) < iwtDest->iwt_WindowTask.wt_XOffset)
788 DeltaX = iwtDest->iwt_DragScrollX;
791 else if (iwtDest->iwt_DragScrollX > 0)
793 if ((iwtDest->iwt_MinX + iwtDest->iwt_InvisibleWidth) > iwtDest->iwt_WindowTask.wt_XOffset)
795 DeltaX = iwtDest->iwt_DragScrollX;
799 if (DeltaX || DeltaY)
801 UWORD DeltaMoveFlags = 0;
802 BOOL DropMark = (iwtDest->iwt_DragFlags & DRAGFLAGF_WindowMarked);
803 BOOL WindowLocked = iwtDest->iwt_DragFlags & DRAGFLAGF_WindowLocked;
804 struct DragHandle *dh = iwtSrc->iwt_myDragHandle;
805 ULONG WasLocked = FALSE;
807 if (dh)
809 ClassHideDragBobs(iwtDest, dh);
810 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
811 WasLocked = SCA_UnlockDrag(dh);
814 // clear lock flag to allow icons to be updated
815 iwtDest->iwt_DragFlags &= ~DRAGFLAGF_WindowLocked;
817 if (DropMark)
818 EraseWindowDropMark(iwtDest);
820 if (DeltaY)
821 DeltaMoveFlags |= SETVIRTF_AdjustRightSlider;
822 if (DeltaX)
823 DeltaMoveFlags |= SETVIRTF_AdjustBottomSlider;
825 DoMethod(iwtDest->iwt_WindowTask.mt_MainObject,
826 SCCM_IconWin_DeltaMove, DeltaX, DeltaY);
827 DoMethod(iwtDest->iwt_WindowTask.mt_MainObject,
828 SCCM_IconWin_SetVirtSize, DeltaMoveFlags);
830 if (DropMark)
831 DisplayWindowDropMark(iwtDest);
833 if (WindowLocked)
834 iwtDest->iwt_DragFlags |= DRAGFLAGF_WindowLocked;
836 ReLockDrag(dh, iwtSrc, WasLocked);
841 void IDCMPDragIntuiTicks(struct internalScaWindowTask *iwt, struct IntuiMessage *msg)
843 struct internalScaWindowTask *iwtUnderPointer;
844 struct ScaIconNode *in;
845 struct ScaIconNode *inOuterBounds;
846 struct Window *foreignWin;
847 struct DragHandle *dh;
849 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
851 QueryObjectUnderPointer(&iwtUnderPointer, &in, &inOuterBounds, &foreignWin);
853 d1(KPrintF("%s/%s/%ld: iwtUnderPointer=%08lx\n", __FILE__, __FUNC__, __LINE__, iwtUnderPointer));
855 if (iwtUnderPointer)
857 // Pointer is inside a Scalos Window
858 DoDragScroll(iwt, iwtUnderPointer);
860 if (in)
861 ScalosUnLockIconList(iwtUnderPointer);
862 SCA_UnLockWindowList();
865 dh = iInfos.xii_GlobalDragHandle;
867 if (dh && dh->drgh_PopOpenTickCount && dh->drgh_PopOpenDestWindow && dh->drgh_PopOpenIcon)
869 d1(KPrintF("%s/%s/%ld: drgh_PopOpenTickCount=%lu\n", __FILE__, __FUNC__, __LINE__, dh->drgh_PopOpenTickCount));
871 if (0 == --dh->drgh_PopOpenTickCount)
873 d1(KPrintF("%s/%s/%ld: Task=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, FindTask(NULL), FindTask(NULL)->tc_Node.ln_Name));
874 PopOpenWindow(iwt, dh);