1 // IconWindow_MouseMove.c
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>
18 #include <proto/dos.h>
19 #include <proto/exec.h>
20 #include <proto/layers.h>
21 #include <proto/intuition.h>
23 #include <proto/scalos.h>
25 #include <clib/alib_protos.h>
28 #include <datatypes/iconobject.h>
29 #include <scalos/scalos.h>
30 #include <scalos/scalosprefs.h>
38 #include "scalos_structures.h"
39 #include "functions.h"
40 #include "Variables.h"
42 //-----------------------------------------------------------------------
44 // local data definitions
46 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
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
75 dX
= msg
->MouseX
- iwt
->iwt_StartDragMouseX
;
79 dY
= msg
->MouseY
- iwt
->iwt_StartDragMouseY
;
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
));
103 // Pointer is inside a Scalos Window
104 struct ScaIconNode
*inOrig
= in
;
106 BOOL IconOverlap
= FALSE
;
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
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
,
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
,
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
,
156 // signal pointer entering new window
157 DoMethod(swit
->iwt_WindowTask
.mt_MainObject
,
158 SCCM_IconWin_DragEnter
,
159 iwt
->iwt_WindowTask
.mt_WindowStruct
,
163 iwt
->iwt_WinUnderPtr
= swit
;
164 iwt
->iwt_IconOuterUBUnderPtr
= NULL
;
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
);
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
));
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
)
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
));
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
,
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
,
248 d1(kprintf("%s/%s/%ld: DragMayDrop=%ld\n", __FILE__
, __FUNC__
, __LINE__
, iwt
->iwt_DragMayDrop
));
253 DoMethod(iwt
->iwt_WinUnderPtr
->iwt_WindowTask
.mt_MainObject
,
254 SCCM_IconWin_DragEnter
,
255 iwt
->iwt_WindowTask
.mt_WindowStruct
,
259 iwt
->iwt_ObjectUnderMouse
= OUM_Icon
;
262 iwt
->iwt_IconUnderPtr
= in
;
266 ScalosUnLockIconList(swit
);
268 SCA_UnLockWindowList();
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
,
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
,
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
);
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
;
349 TranspFlags
= DRAGTRANSPF_AppWindows
;
352 if (iwt
->iwt_DragMayDrop
&& iwt
->iwt_IconUnderPtr
)
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
));
362 TranspFlags
= DRAGTRANSPF_DiskIcons
;
365 case WB_TEXTICON_DRAWER
:
366 TranspFlags
= DRAGTRANSPF_DrawerIcons
;
369 case WB_TEXTICON_TOOL
:
370 TranspFlags
= DRAGTRANSPF_ToolIcons
;
373 TranspFlags
= DRAGTRANSPF_ProjectIcons
;
376 TranspFlags
= DRAGTRANSPF_TrashcanIcons
;
379 TranspFlags
= DRAGTRANSPF_KickIcons
;
382 if (IsIconifiedScalosWindow(iwt
, iwt
->iwt_IconUnderPtr
))
383 TranspFlags
= DRAGTRANSPF_IconifiedWinIcons
;
385 TranspFlags
= DRAGTRANSPF_AppIcons
;
390 d1(KPrintF("%s/%s/%ld: pref_DragTranspObjects=%08lx TranspFlags=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, CurrentPrefs
.pref_DragTranspObjects
, TranspFlags
));
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
;
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
,
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
,
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
)
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
));
482 d1(kprintf("%s/%s/%ld: Icon=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, iwt
->iwt_IconUnderPtr
));
484 if (iwt
->iwt_IconUnderPtr
)
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
));
497 case WB_TEXTICON_DRAWER
:
499 destLock
= IconLock
= GetIconLock(iwt
->iwt_WinUnderPtr
, iwt
->iwt_IconUnderPtr
);
511 Result
= ScaSameLock(destLock
, srcLock
);
522 // get a Lock to an icon
523 static BPTR
GetIconLock(struct internalScaWindowTask
*iwt
, struct ScaIconNode
*in
)
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
);
539 BPTR oldDir
= CurrentDir(iwt
->iwt_WindowTask
.mt_WindowStruct
->ws_Lock
);
540 iLock
= Lock(in
->in_Name
, ACCESS_READ
);
548 // Mouse moved, MMB pressed
549 void IDCMPMMBMouseMove(struct internalScaWindowTask
*iwt
)
551 WORD oldXOffset
, oldYOffset
;
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
)
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
)
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
)
589 ULONG DrawDragFlags
= 0l;
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
;
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
;
643 GetAttr(IDTA_Type
, iwt
->iwt_IconUnderPtr
->in_Icon
, &IconType
);
645 // only copy to drawer, device, disk icons
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
;
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
)
701 ScalosReleaseSemaphore(iwt
->iwt_AppListSemaphore
);
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
)
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
))
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
);
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
)
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
))
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
);
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
;
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
;
818 EraseWindowDropMark(iwtDest
);
821 DeltaMoveFlags
|= SETVIRTF_AdjustRightSlider
;
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
);
831 DisplayWindowDropMark(iwtDest
);
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
));
857 // Pointer is inside a Scalos Window
858 DoDragScroll(iwt
, iwtUnderPointer
);
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
);