forwarding build fix when MUIA_Scrollgroup_AutoBars is defined (NicJA).
[AROS-Contrib.git] / scalos / main / DragDrop.c
blob7ea5c2c29083b8169d8b4027b1708e33eff7c1e7
1 // DragDrop.c
2 // $Date$
3 // $Revision$
4 // $Id$
7 #include <exec/types.h>
8 #include <graphics/gels.h>
9 #include <graphics/rastport.h>
10 #include <intuition/classes.h>
11 #include <intuition/classusr.h>
12 #include <intuition/intuitionbase.h>
13 #include <utility/hooks.h>
14 #include <intuition/gadgetclass.h>
15 #include <workbench/workbench.h>
16 #include <workbench/startup.h>
17 #include <dos/dostags.h>
19 #define __USE_SYSBASE
21 #include <proto/dos.h>
22 #include <proto/exec.h>
23 #include <proto/layers.h>
24 #include <proto/intuition.h>
25 #include <proto/graphics.h>
26 #include <proto/utility.h>
27 #ifdef __AROS__
28 #include <proto/popupmenu.h>
29 #else
30 #include <proto/pm.h>
31 #endif
32 #include <proto/icon.h>
33 #include <proto/iconobject.h>
34 #include <proto/rexxsyslib.h>
35 #include "debug.h"
36 #include <proto/scalos.h>
37 #include <proto/scalosmenuplugin.h>
39 #include <clib/alib_protos.h>
41 #include <defs.h>
42 #include <datatypes/iconobject.h>
43 #include <scalos/scalos.h>
44 #include <scalos/menu.h>
45 #include <scalos/GadgetBar.h>
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <stdarg.h>
51 #include <ctype.h>
53 #include <DefIcons.h>
55 #include "scalos_structures.h"
56 #include "functions.h"
57 #include "locale.h"
58 #include "Variables.h"
59 #include "DtImageClass.h"
61 //----------------------------------------------------------------------------
63 // local data definitions
65 #define DROPMENU
67 enum DropMenuImgIndex
69 DROPMENUIMAGE_Abort = 0,
70 DROPMENUIMAGE_Copy,
71 DROPMENUIMAGE_Move,
72 DROPMENUIMAGE_CreateLink,
74 DROPMENUIMAGE_MAX
77 //----------------------------------------------------------------------------
79 // local functions
80 static SAVEDS(void) ASM INTERRUPT DropTask(void);
81 static struct DragNode *FindIconInDragList(struct internalScaWindowTask *iwt, const struct ScaIconNode *in);
82 static void DragDropFinish(struct internalScaWindowTask *iwt, struct ScaWindowStruct *wsSrc,
83 struct ScaWindowStruct *wsDest, LONG x, LONG y, struct DropOps *drops);
84 static void Icon2IconDrop(struct ScalosArg **ArgList,
85 struct ScaWindowStruct *wsSrc,
86 struct ScaWindowStruct *wsDest,
87 struct DropInfo *DrInfo);
88 static void Icon2DesktopDrop(struct ScalosArg **, struct ScaWindowStruct *Src,
89 struct ScaWindowStruct *Dest,
90 struct DropInfo *DrInfo);
91 static void Desktop2DesktopDrop(struct ScalosArg **, struct ScaWindowStruct *Src,
92 struct ScaWindowStruct *Dest, struct DropInfo *DrInfo);
93 static void Desktop2IconDrop(struct ScalosArg **, struct ScaWindowStruct *Src,
94 struct ScaWindowStruct *Dest, struct DropInfo *DrInfo);
95 static void DropStart(struct internalScaWindowTask *iwt, struct internalScaWindowTask *iwtDest,
96 struct ScaIconNode *in);
97 static ULONG Icon2IconDrop_Drawer(struct internalScaWindowTask *iwtSrc, struct DropInfo *DrInfo, APTR undoStep);
98 static ULONG Icon2IconDrop_File(struct internalScaWindowTask *iwtSrc, struct DropInfo *DrInfo, APTR undoStep);
99 static ULONG Icon2Icon_MoveDir(struct internalScaWindowTask *iwtSrc, struct DropInfo *DrInfo, APTR undoStep);
100 static ULONG Icon2Icon_CopyDir(struct internalScaWindowTask *iwtSrc, struct DropInfo *DrInfo, CONST_STRPTR DestName, APTR undoStep);
101 static ULONG Icon2Icon_CreateLink(struct internalScaWindowTask *iwtSrc, struct DropInfo *DrInfo, APTR undoStep);
102 static ULONG DropAddIcon(struct MsgPort *ReplyPort, struct ScaWindowStruct *wsDest,
103 BPTR DirLock, STRPTR IconName, WORD x, WORD y);
104 static void DropRemoveIcon(struct ScaWindowStruct *wsDest, BPTR DirLock, CONST_STRPTR IconName);
105 static void DronOnAppIcon(struct internalScaWindowTask *iwt, struct internalScaWindowTask *iwtFound,
106 struct ScaIconNode *in, LONG x, LONG y);
107 static void DronOnAppObject(struct internalScaWindowTask *iwt, struct AppObject *ao, LONG x, LONG y);
108 static void SameWindow(struct internalScaWindowTask *iwt, struct internalScaWindowTask *iwtFound, LONG x, LONG y);
109 static void SameWindow2(struct internalScaWindowTask *iwt, struct internalScaWindowTask *iwtFound, LONG x, LONG y);
110 static ULONG DragQuery_IconWin(struct ScaIconNode *, ULONG IconType);
111 static void MoveIconToNewPosition(struct internalScaWindowTask *iwt,
112 struct ScaIconNode *in, WORD xNew, WORD yNew);
113 static BOOL DropPopupMenu(struct internalScaWindowTask *iwtSrc,
114 struct DropInfo *DrInfo, const struct DropOps *AllowedDrops);
116 //----------------------------------------------------------------------------
118 // local data items
120 //----------------------------------------------------------------------------
122 void DragDrop(struct Window *win, LONG MouseX, LONG MouseY, ULONG Qualifier,
123 struct internalScaWindowTask *iwt)
125 struct internalScaWindowTask *iwtDest;
126 struct ScaIconNode *inDest;
127 enum ObjTypes ObjUnderMouse;
128 LONG x = 0, y = 0;
129 struct DropOps drops;
131 d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
133 drops.drop_Copy = drops.drop_Move = drops.drop_CreateLink = drops.drop_PutAway = drops.drop_LeaveOut = FALSE;
134 if (isMakeLinkQualifier(Qualifier))
136 drops.drop_CreateLink = TRUE;
138 else if (isMoveQualifier(Qualifier))
140 drops.drop_Move = TRUE;
142 else if (isCopyQualifier(Qualifier))
144 drops.drop_Copy = TRUE;
147 SCA_LockWindowList(SCA_LockWindowList_Shared);
149 iwtDest = iwt->iwt_WinUnderPtr;
150 inDest = iwt->iwt_IconUnderPtr;
152 ObjUnderMouse = iwt->iwt_ObjectUnderMouse;
154 d1(kprintf("%s/%s/%ld: iwt=%08lx MayDrop=%ld iwtDest=<%s> inDest=%08lx ObjType=%ld\n", __FILE__, __FUNC__, __LINE__, \
155 iwt, iwt->iwt_DragMayDrop, iwt->iwt_WinTitle, inDest, ObjUnderMouse));
156 d1(kprintf("%s/%s/%ld: WinUnderPtr=%08lx IconUnderPtr=%08lx\n", __FILE__, __FUNC__, __LINE__, \
157 iwt->iwt_WinUnderPtr, iwt->iwt_IconUnderPtr));
159 IconWin_EndDrag(iwt); // Signal Mouse leaving window/icon
161 if (!iwt->iwt_DragMayDrop)
163 d1(KPrintF("%s/%s/%ld: No Drop allowed here\n", __FILE__, __FUNC__, __LINE__));
165 SCA_UnLockWindowList();
167 if (!CurrentPrefs.pref_EnableDropMenu)
168 ClosePopupWindows(TRUE);
170 if (iwt->iwt_DragIconList)
172 RestoreDragIcons(iwt);
173 DisplayBeep(iwt->iwt_WinScreen);
175 return;
178 if (iwtDest)
180 x = MouseX + iwt->iwt_WindowTask.wt_Window->LeftEdge - iwtDest->iwt_WindowTask.wt_Window->LeftEdge
181 - iwtDest->iwt_InnerLeft + iwtDest->iwt_WindowTask.wt_XOffset;
182 y = MouseY + iwt->iwt_WindowTask.wt_Window->TopEdge - iwtDest->iwt_WindowTask.wt_Window->TopEdge
183 - iwtDest->iwt_InnerTop + iwtDest->iwt_WindowTask.wt_YOffset;
186 d1(kprintf("%s/%s/%ld: MouseX=%ld MouseY=%ld x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, MouseX, MouseY, x, y));
188 switch (ObjUnderMouse)
190 case OUM_ScalosWindow:
191 if (iwtDest)
193 d1(kprintf("%s/%s/%ld: Drop on Scalos Window \n", __FILE__, __FUNC__, __LINE__));
194 if (iwt == iwtDest && !drops.drop_Copy)
195 SameWindow(iwt, iwtDest, x, y);
196 else
197 DragDropFinish(iwt, iwt->iwt_WindowTask.mt_WindowStruct, iwtDest->iwt_WindowTask.mt_WindowStruct, x, y, &drops);
199 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
200 #if 0
201 // if iwtDest was a Popup window, close it now!
202 if (iwtDest->iwt_WindowTask.mt_WindowStruct->ws_Flags & WSV_FlagF_DdPopupWindow)
204 struct SM_CloseWindow *msg;
206 msg = (struct SM_CloseWindow *) SCA_AllocMessage(MTYP_CloseWindow, 0);
207 if (msg)
209 msg->ScalosMessage.sm_Message.mn_ReplyPort = iInfos.xii_iinfos.ii_MainMsgPort;
210 PutMsg(iwtDest->iwt_WindowTask.mt_WindowStruct->ws_MessagePort, &msg->ScalosMessage.sm_Message);
213 #endif
214 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
216 break;
218 case OUM_ForeignWindow:
219 d1(kprintf("%s/%s/%ld: Drop on foreign Window\n", __FILE__, __FUNC__, __LINE__));
220 RestoreDragIcons(iwt);
221 DisplayBeep(iwt->iwt_WinScreen);
222 break;
224 case OUM_AppWindow:
225 d1(kprintf("%s/%s/%ld: Drop on AppWindow\n", __FILE__, __FUNC__, __LINE__));
226 if (iInfos.xii_iinfos.ii_AppWindowStruct)
228 struct internalScaWindowTask *iwtx = (struct internalScaWindowTask *) iInfos.xii_iinfos.ii_AppWindowStruct->ws_WindowTask;
229 struct AppObject *ao;
231 ScalosObtainSemaphoreShared(iwtx->iwt_AppListSemaphore);
233 for (ao = iwtx->iwt_AppList; ao; ao = (struct AppObject *) ao->appo_Node.mln_Succ)
235 if (APPTYPE_AppWindow == ao->appo_type &&
236 ao->appo_object.appoo_Window == win)
238 // AppWindow found
239 ScalosReleaseSemaphore(iwtx->iwt_AppListSemaphore);
241 DronOnAppObject(iwt, ao, MouseX, MouseY);
243 SCA_UnLockWindowList();
244 RestoreDragIcons(iwt);
245 return;
249 // non-AppWindow
250 ScalosReleaseSemaphore(iwtx->iwt_AppListSemaphore);
252 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
253 DisplayBeep(iwt->iwt_WinScreen);
255 break;
257 case OUM_Icon:
258 d1(KPrintF("%s/%s/%ld: Drop on Scalos Icon\n", __FILE__, __FUNC__, __LINE__));
260 if (NULL == FindIconInDragList(iwt, inDest))
262 IPTR IconType;
264 GetAttr(IDTA_Type, inDest->in_Icon, &IconType);
266 d1(kprintf("%s/%s/%ld: Icon=<%s> Type=%ld\n", __FILE__, __FUNC__, __LINE__, GetIconName(inDest), IconType));
268 switch (IconType)
270 case WBAPPICON:
271 DronOnAppIcon(iwt, iwtDest, inDest, x, y);
272 break;
273 case WBTOOL:
274 case WB_TEXTICON_TOOL:
275 if (CurrentPrefs.pref_DragStartFlag)
276 DropStart(iwt, iwtDest, inDest);
277 break;
278 default:
279 if (iwt == iwtDest)
281 if (DragQuery_IconWin(inDest, IconType))
283 RestoreDragIcons(iwt);
284 DragDropFinish(iwt, iwt->iwt_WindowTask.mt_WindowStruct, iwtDest->iwt_WindowTask.mt_WindowStruct, x, y, &drops);
286 else
288 SameWindow(iwt, iwtDest, x, y);
291 else
293 DragDropFinish(iwt, iwt->iwt_WindowTask.mt_WindowStruct, iwtDest->iwt_WindowTask.mt_WindowStruct, x, y, &drops);
295 break;
298 else
300 if (iwt == iwtDest)
301 SameWindow(iwt, iwtDest, x, y);
303 break;
304 default:
305 d1(KPrintF("%s/%s/%ld: Just moved around icon\n", __FILE__, __FUNC__, __LINE__));
306 break;
309 RestoreDragIcons(iwt);
310 SCA_UnLockWindowList();
312 d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
316 static SAVEDS(void) ASM INTERRUPT DropTask(void)
318 struct Process *myProc = (struct Process *) FindTask(NULL);
319 struct SM_DropProc *sMsg;
321 do {
322 sMsg = (struct SM_DropProc *) GetMsg(&myProc->pr_MsgPort);
324 if (NULL == sMsg)
325 WaitPort(&myProc->pr_MsgPort);
326 } while (NULL == sMsg);
328 d1(kprintf("%s/%s/%ld: sMsg=%08lx Type=%08lx\n", __FILE__, __FUNC__, __LINE__, sMsg, sMsg->sdpm_ScalosMessage.sm_MessageType));
330 if (ID_IMSG == sMsg->sdpm_ScalosMessage.sm_Signature &&
331 MTYP_DropProc == sMsg->sdpm_ScalosMessage.sm_MessageType)
333 struct ScalosArg *sarg;
334 ULONG ArgCount;
335 struct ScaWindowStruct *wsSrc, *wsDest;
336 struct ScalosArg *ArgList;
337 DROPFUNC DropFunc;
338 struct DropInfo DrInfo;
340 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
342 ScalosObtainSemaphoreShared(sMsg->sdpm_SourceWindowStruct->ws_WindowTask->wt_WindowSemaphore);
343 ScalosObtainSemaphoreShared(sMsg->sdpm_DestWindowStruct->ws_WindowTask->wt_WindowSemaphore);
345 DrInfo.drin_LastDropMenuResult = DROPMENURESULT_Unknown;
347 DrInfo.drin_x = sMsg->sdpm_MouseX;
348 DrInfo.drin_y = sMsg->sdpm_MouseY;
349 DrInfo.drin_Arg = NULL;
350 DrInfo.drin_DestLock = (BPTR)NULL;
351 wsSrc = sMsg->sdpm_SourceWindowStruct;
352 wsDest = sMsg->sdpm_DestWindowStruct;
353 DrInfo.drin_Drops = sMsg->sdpm_Drops;
354 DropFunc = sMsg->sdpm_DropFunc;
355 ArgList = sMsg->sdpm_ArgList;
357 ReplyMsg((struct Message *) sMsg);
359 for (sarg=ArgList, ArgCount=0; sarg; sarg = (struct ScalosArg *) sarg->scarg_Node.mln_Succ)
360 ArgCount++;
362 d1(kprintf("%s/%s/%ld: ArgList=%08lx ArgCount=%ld\n", __FILE__, __FUNC__, __LINE__, ArgList, ArgCount));
364 DrInfo.drin_FileTransObj = SCA_NewScalosObjectTags((STRPTR) "FileTransfer.sca",
365 SCCA_FileTrans_Screen, (IPTR) iInfos.xii_iinfos.ii_Screen,
366 SCCA_FileTrans_Number, ArgCount,
367 SCCA_FileTrans_ReplaceMode, SCCV_ReplaceMode_Ask,
368 TAG_END);
370 d1(KPrintF("%s/%s/%ld: FileTransObj=%08lx wsSrc=%08lx wsDest=%08lx\n", __FILE__, __FUNC__, __LINE__, \
371 DrInfo.drin_FileTransObj, wsSrc, wsDest));
373 if (DrInfo.drin_FileTransObj)
375 (*DropFunc)(&ArgList, wsSrc, wsDest, &DrInfo);
377 SCA_DisposeScalosObject(DrInfo.drin_FileTransObj);
380 d1(kprintf("%s/%s/%ld: ClassDragFinish_IconWin(ArgList=%08lx)\n", __FILE__, __FUNC__, __LINE__, ArgList));
381 ClassDragFinish_IconWin(&ArgList);
383 else
384 ReplyMsg((struct Message *) sMsg);
388 static struct DragNode *FindIconInDragList(struct internalScaWindowTask *iwt, const struct ScaIconNode *in)
390 struct DragNode *dn;
392 for (dn = iwt->iwt_DragNodeList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
394 if (dn->drgn_iconnode == in)
396 return dn;
400 return NULL;
404 static void DragDropFinish(struct internalScaWindowTask *iwt, struct ScaWindowStruct *wsSrc,
405 struct ScaWindowStruct *wsDest, LONG x, LONG y, struct DropOps *drops)
407 struct ScalosArg *argList;
409 d1(KPrintF("%s/%s/%ld: Started: - iwt=%08lx wsSrc=<%s> wsDest=<%s> x=%ld y=%ld Copy=%ld Move=%ld CreateLink=%ld\n", \
410 __FILE__, __FUNC__, __LINE__, iwt, wsSrc->ws_Name, wsDest->ws_Name, x, y, drops->drop_Copy, drops->drop_Move, drops->drop_CreateLink));
412 RestoreDragIcons(iwt);
414 if (NULL == wsSrc || NULL == wsDest)
415 return;
417 argList = NULL;
419 switch (wsSrc->ws_WindowType)
421 case WSV_Type_DeviceWindow:
422 d1(kprintf("%s/%s/%ld: DeviceWindow\n", __FILE__, __FUNC__, __LINE__));
423 ClassDragBegin_DeviceWin(&argList, &iwt->iwt_DragNodeList);
424 break;
425 case WSV_Type_IconWindow:
426 d1(kprintf("%s/%s/%ld: IconWindow CALL ClassDragBegin_IconWin(&argList, &iwt->iwt_DragNodeList)\n", __FILE__, __FUNC__, __LINE__));
427 ClassDragBegin_IconWin(&argList, &iwt->iwt_DragNodeList);
428 break;
431 d1(kprintf("%s/%s/%ld: Src WindowType=%ld argList=%08lx\n", __FILE__, __FUNC__, __LINE__, wsSrc->ws_WindowType, argList));
433 if (argList)
435 DROPFUNC DropProc = NULL;
437 if (WSV_Type_IconWindow == wsSrc->ws_WindowType && WSV_Type_IconWindow == wsDest->ws_WindowType)
439 d1(kprintf("%s/%s/%ld: Icon 2 Icon\n",__FILE__, __FUNC__, __LINE__));
440 DropProc = Icon2IconDrop;
442 else if (WSV_Type_IconWindow == wsSrc->ws_WindowType && WSV_Type_DeviceWindow == wsDest->ws_WindowType)
444 d1(kprintf("%s/%s/%ld: Icon 2 Device\n", __FILE__, __FUNC__, __LINE__));
445 DropProc = Icon2DesktopDrop;
447 else if (WSV_Type_DeviceWindow == wsSrc->ws_WindowType && WSV_Type_IconWindow == wsDest->ws_WindowType)
449 d1(kprintf("%s/%s/%ld: Device 2 Icon\n", __FILE__, __FUNC__, __LINE__));
450 DropProc = Desktop2IconDrop;
452 else if (WSV_Type_DeviceWindow == wsSrc->ws_WindowType && WSV_Type_DeviceWindow == wsDest->ws_WindowType)
454 d1(kprintf("%s/%s/%ld: Device 2 Device\n", __FILE__, __FUNC__, __LINE__));
455 DropProc = Desktop2DesktopDrop;
458 if (DropProc)
460 struct SM_DropProc *sMsg;
462 sMsg = (struct SM_DropProc *) SCA_AllocMessage(MTYP_DropProc, 0);
464 if (sMsg)
466 STATIC_PATCHFUNC(DropTask)
467 struct Process *proc;
469 sMsg->sdpm_ScalosMessage.sm_Message.mn_ReplyPort = iwt->iwt_WindowTask.wt_IconPort;
470 sMsg->sdpm_DropFunc = DropProc;
471 sMsg->sdpm_SourceWindowStruct = wsSrc;
472 sMsg->sdpm_DestWindowStruct = wsDest;
473 sMsg->sdpm_ArgList = argList;
474 sMsg->sdpm_MouseX = x;
475 sMsg->sdpm_MouseY = y;
476 sMsg->sdpm_Drops = *drops;
478 // CreateNewProc()
479 proc = CreateNewProcTags(NP_WindowPtr, NULL,
480 NP_StackSize, 8192,
481 NP_Cli, TRUE,
482 NP_CommandName, (IPTR) "Scalos_Drag&Drop",
483 NP_Name, (IPTR) "Scalos_Drag&Drop",
484 NP_Entry, (IPTR) PATCH_NEWFUNC(DropTask),
485 NP_Path, DupWBPathList(),
486 TAG_END);
488 d1(kprintf("%s/%s/%ld: proc=%08lx\n", __FILE__, __FUNC__, __LINE__, proc));
490 if (proc)
492 d1(kprintf("%s/%s/%ld: proc=%08lx\n", __FILE__, __FUNC__, __LINE__, proc));
494 PutMsg(&proc->pr_MsgPort, &sMsg->sdpm_ScalosMessage.sm_Message);
496 d1(kprintf("%s/%s/%ld: CALL WaitReply for: (%s)\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_WinTitle));
498 WaitReply(iwt->iwt_WindowTask.wt_IconPort, iwt, MTYP_DropProc);
501 else
503 d1(kprintf("%s/%s/%ld: CALL ClassDragFinish_IconWin(argList)\n", __FILE__, __FUNC__, __LINE__));
504 ClassDragFinish_IconWin(&argList);
508 else
510 d1(kprintf("%s/%s/%ld: DropProc = NULL - CALL ClassDragFinish_IconWin(argList)\n", __FILE__, __FUNC__, __LINE__));
511 ClassDragFinish_IconWin(&argList);
517 // .drag_error:
519 // d1(kprintf("%s/%s/%ld: CALL IconWin_EndDrag(iwt) \n", __FILE__, __FUNC__, __LINE__));
521 IconWin_EndDrag(iwt); // Signal Mouse leaving window/icon.
523 // d1(kprintf("%s/%s/%ld: Finished. \n", __FILE__, __FUNC__, __LINE__));
527 static void DropStart(struct internalScaWindowTask *iwt, struct internalScaWindowTask *iwtDest,
528 struct ScaIconNode *inDest)
530 struct WBArg *Buffer;
531 ULONG ArgCount = 0;
533 d1(KPrintF("%s/%s/%ld: Started: iwt=%08lx icon=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt, inDest, GetIconName(inDest)));
534 d1(KPrintF("%s/%s/%ld: iwt_DragIconList=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_DragIconList));
536 do {
537 struct ScaIconNode *in;
538 ULONG NumberOfWbArgs;
539 struct WBArg *wbArg;
541 for (NumberOfWbArgs = 1, in = iwt->iwt_DragIconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
543 NumberOfWbArgs++;
546 d1(KPrintF("%s/%s/%ld: NumberOfWbArgs=%lu\n", __FILE__, __FUNC__, __LINE__, NumberOfWbArgs));
548 Buffer = ScalosAlloc(NumberOfWbArgs * sizeof(struct WBArg));
549 d1(KPrintF("%s/%s/%ld: Buffer=%08lx\n", __FILE__, __FUNC__, __LINE__, Buffer));
550 if (NULL == Buffer)
551 break;
553 memset(Buffer, 0, NumberOfWbArgs * sizeof(struct WBArg));
555 // Add destination as first argument
556 if (!DoMethod(iwtDest->iwt_WindowTask.mt_MainObject, SCCM_IconWin_MakeWBArg, inDest, Buffer))
557 break;
559 // Now add all icons from iwt_DragIconList
560 for (ArgCount = 1, in = iwt->iwt_DragIconList, wbArg = Buffer + 1;
561 in; in = (struct ScaIconNode *) in->in_Node.mln_Succ, wbArg++)
563 d1(KPrintF("%s/%s/%ld: add icon=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt, in, GetIconName(in)));
564 ArgCount += DoMethod(iwt->iwt_WindowTask.mt_MainObject,
565 SCCM_IconWin_MakeWBArg, in, wbArg);
568 d1(KPrintF("%s/%s/%ld: ArgCount=%ld\n", __FILE__, __FUNC__, __LINE__, ArgCount));
570 RestoreDragIcons(iwt);
572 SCA_WBStart(Buffer, NULL, ArgCount);
573 } while (0);
575 if (Buffer)
577 SCA_FreeWBArgs(Buffer, ArgCount, SCAF_FreeNames);
578 ScalosFree(Buffer);
580 if (iwt->iwt_DragIconList)
581 RestoreDragIcons(iwt);
583 d1(KPrintF("%s/%s/%ld: Finished: iwt=%08lx icon=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt, inDest, GetIconName(inDest)));
587 static void Icon2IconDrop(struct ScalosArg **ArgList,
588 struct ScaWindowStruct *wsSrc,
589 struct ScaWindowStruct *wsDest,
590 struct DropInfo *DrInfo)
592 struct internalScaWindowTask *iwtSrc, *iwtDest;
593 BPTR SrcLock = (BPTR)NULL;
594 BPTR oldDir = NOT_A_LOCK;
595 BOOL WindowsLocked = TRUE;
597 if (NULL == wsSrc || NULL == wsDest)
598 return;
600 iwtSrc = (struct internalScaWindowTask *) wsSrc->ws_WindowTask;
601 iwtDest = (struct internalScaWindowTask *) wsDest->ws_WindowTask;
603 if (NULL == iwtSrc || NULL == iwtDest)
604 return;
606 d1(kprintf("%s/%s/%ld: ArgList=%08lx\n", __FILE__, __FUNC__, __LINE__, ArgList));
607 d1(kprintf("%s/%s/%ld: Src=%08lx <%s> Dest=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, \
608 wsSrc, wsSrc->ws_Name, wsDest, wsDest->ws_Name));
610 do {
611 APTR undoStep;
612 ULONG Result = RETURN_OK;
613 struct ScaIconNode *in;
615 if (wsSrc->ws_Lock)
617 SrcLock = DupLock(wsSrc->ws_Lock);
618 if ((BPTR)NULL == SrcLock)
619 break;
621 if (wsDest->ws_Lock)
623 DrInfo->drin_DestLock = DupLock(wsDest->ws_Lock);
624 if ((BPTR)NULL == DrInfo->drin_DestLock)
625 break;
628 oldDir = CurrentDir(DrInfo->drin_DestLock);
630 ScalosLockIconListShared(iwtDest);
632 in = CheckMouseIcon(&iwtDest->iwt_WindowTask.wt_IconList,
633 iwtDest, DrInfo->drin_x, DrInfo->drin_y);
634 if (in)
636 BPTR IconLock = (BPTR)NULL;
638 if (in->in_Lock)
640 BPTR oldDir2 = CurrentDir(in->in_Lock);
642 IconLock = Lock((STRPTR) GetIconName(in), ACCESS_READ);
643 CurrentDir(oldDir2);
645 else
647 IPTR IconType;
649 GetAttr(IDTA_Type, in->in_Icon, &IconType);
650 d1(kprintf("%s/%s/%ld: in=%08lx <%s> IconType=%ld\n", __FILE__, __FUNC__, __LINE__, in, GetIconName(in), IconType));
652 switch (IconType)
654 case WBDISK:
655 IconLock = DiskInfoLock(in);
656 break;
658 case WBDRAWER:
659 case WBGARBAGE:
660 case WB_TEXTICON_DRAWER:
661 IconLock = Lock((STRPTR) GetIconName(in), ACCESS_READ);
662 break;
666 if (IconLock)
668 UnLock(DrInfo->drin_DestLock);
669 DrInfo->drin_DestLock = IconLock;
670 DrInfo->drin_x = NO_ICON_POSITION_SHORT;
671 DrInfo->drin_y = NO_ICON_POSITION_SHORT;
675 ScalosUnLockIconList(iwtDest);
677 CurrentDir(oldDir);
678 oldDir = NOT_A_LOCK;
680 ScalosReleaseSemaphore(iwtSrc->iwt_WindowTask.wt_WindowSemaphore);
681 ScalosReleaseSemaphore(iwtDest->iwt_WindowTask.wt_WindowSemaphore);
682 WindowsLocked = FALSE;
684 undoStep = UndoBeginStep();
686 for (DrInfo->drin_Arg = *ArgList;
687 RESULT_UserAborted != Result && DrInfo->drin_Arg;
688 DrInfo->drin_Arg = (struct ScalosArg *) DrInfo->drin_Arg->scarg_Node.mln_Succ)
690 d1(kprintf("%s/%s/%ld: DrInfo->drin_Arg=%08lx <%s> IconType=%ld\n", \
691 __FILE__, __FUNC__, __LINE__, \
692 DrInfo->drin_Arg, DrInfo->drin_Arg->scarg_name, DrInfo->drin_Arg->scarg_icontype));
694 switch (DrInfo->drin_Arg->scarg_icontype)
696 case WBDRAWER:
697 case WB_TEXTICON_DRAWER:
698 case WBGARBAGE:
699 Result = Icon2IconDrop_Drawer(iwtSrc, DrInfo, undoStep);
700 break;
701 case WBTOOL:
702 case WB_TEXTICON_TOOL:
703 Result = Icon2IconDrop_File(iwtSrc, DrInfo, undoStep);
704 break;
708 UndoEndStep(iwtSrc, undoStep);
710 d1(kprintf("%s/%s/%ld: ClassDragFinish_IconWin(ArgList=%08lx)\n", __FILE__, __FUNC__, __LINE__, ArgList));
711 ClassDragFinish_IconWin(ArgList);
712 } while (0);
714 if (IS_VALID_LOCK(oldDir))
715 CurrentDir(oldDir);
716 if (SrcLock)
717 UnLock(SrcLock);
718 if (DrInfo->drin_DestLock)
720 UnLock(DrInfo->drin_DestLock);
721 DrInfo->drin_DestLock = (BPTR)NULL;
724 if (WindowsLocked)
726 ScalosReleaseSemaphore(iwtSrc->iwt_WindowTask.wt_WindowSemaphore);
727 ScalosReleaseSemaphore(iwtDest->iwt_WindowTask.wt_WindowSemaphore);
732 static ULONG Icon2IconDrop_Drawer(struct internalScaWindowTask *iwtSrc, struct DropInfo *DrInfo, APTR undoStep)
734 LONG sameLock = ScaSameLock(DrInfo->drin_Arg->scarg_lock, DrInfo->drin_DestLock);
735 STRPTR DestName = NULL;
736 ULONG Result = RETURN_OK;
737 struct DropOps AllowedDrops;
739 debugLock_d1(DrInfo->drin_Arg->scarg_lock);
740 debugLock_d1(DrInfo->drin_DestLock);
742 d1(KPrintF("%s/%s/%ld: sameLock=%ld\n", __FILE__, __FUNC__, __LINE__, sameLock));
744 AllowedDrops.drop_CreateLink = TRUE;
745 AllowedDrops.drop_Copy = TRUE;
746 AllowedDrops.drop_Move = LOCK_SAME != sameLock;
748 if (!DropPopupMenu(iwtSrc, DrInfo, &AllowedDrops))
749 return RETURN_OK;
751 if (DrInfo->drin_Drops.drop_CreateLink)
753 return Icon2Icon_CreateLink(iwtSrc, DrInfo, undoStep);
755 else if (DrInfo->drin_Drops.drop_Move)
757 // force move - do nothing if same directory
758 if (LOCK_SAME != sameLock)
759 sameLock = LOCK_SAME_VOLUME;
761 else if (DrInfo->drin_Drops.drop_Copy)
763 // source and dest are in same directory
765 if (LOCK_SAME == sameLock)
767 DestName = AllocPathBuffer();
769 BumpRevision(DestName, DrInfo->drin_Arg->scarg_name);
772 // force copy
773 sameLock = LOCK_DIFFERENT;
776 d1(kprintf("%s/%s/%ld: sameLock=%ld\n", __FILE__, __FUNC__, __LINE__, sameLock));
778 switch (sameLock)
780 case LOCK_SAME:
781 return RETURN_OK;
783 case LOCK_DIFFERENT:
784 Result = Icon2Icon_CopyDir(iwtSrc, DrInfo, DestName, undoStep);
785 break;
787 case LOCK_SAME_VOLUME:
788 Result = Icon2Icon_MoveDir(iwtSrc, DrInfo, undoStep);
789 break;
792 if (DestName)
793 FreePathBuffer(DestName);
795 d1(kprintf("%s/%s/%ld: Result=%08lx\n", __FILE__, __FUNC__, __LINE__, Result));
797 return Result;
801 static ULONG Icon2IconDrop_File(struct internalScaWindowTask *iwtSrc, struct DropInfo *DrInfo, APTR undoStep)
803 LONG sameLock = ScaSameLock(DrInfo->drin_Arg->scarg_lock, DrInfo->drin_DestLock);
804 STRPTR DestName = NULL;
805 ULONG Result = RETURN_OK;
806 LONG xi = DrInfo->drin_x, yi = DrInfo->drin_y;
807 struct DropOps AllowedDrops;
809 debugLock_d1(DrInfo->drin_Arg->scarg_lock);
810 debugLock_d1(DrInfo->drin_DestLock);
812 d1(KPrintF("%s/%s/%ld: sameLock=%ld\n", __FILE__, __FUNC__, __LINE__, sameLock));
814 if (NO_ICON_POSITION_SHORT != xi)
816 xi += DrInfo->drin_Arg->scarg_xpos;
817 yi += DrInfo->drin_Arg->scarg_ypos;
820 AllowedDrops.drop_CreateLink = TRUE;
821 AllowedDrops.drop_Copy = TRUE;
822 AllowedDrops.drop_Move = LOCK_SAME != sameLock;
824 if (!DropPopupMenu(iwtSrc, DrInfo, &AllowedDrops))
825 return RETURN_OK;
827 if (DrInfo->drin_Drops.drop_CreateLink)
829 return Icon2Icon_CreateLink(iwtSrc, DrInfo, undoStep);
831 else if (DrInfo->drin_Drops.drop_Move)
833 // force move - do nothing if same directory
834 if (LOCK_SAME != sameLock)
835 sameLock = LOCK_SAME_VOLUME;
837 else if (DrInfo->drin_Drops.drop_Copy)
839 if (LOCK_SAME == sameLock)
841 // source and dest are in same directory
842 DestName = AllocPathBuffer();
844 BumpRevision(DestName, DrInfo->drin_Arg->scarg_name);
847 // force copy
848 sameLock = LOCK_DIFFERENT;
851 d1(kprintf("%s/%s/%ld: sameLock=%ld\n", __FILE__, __FUNC__, __LINE__, sameLock));
853 switch (sameLock)
855 case LOCK_SAME:
856 return RETURN_OK;
858 case LOCK_DIFFERENT:
859 UndoAddEvent(iwtSrc, UNDO_Copy,
860 UNDOTAG_UndoMultiStep, undoStep,
861 UNDOTAG_CopySrcDirLock, DrInfo->drin_Arg->scarg_lock,
862 UNDOTAG_CopyDestDirLock, DrInfo->drin_DestLock,
863 UNDOTAG_CopySrcName, DrInfo->drin_Arg->scarg_name,
864 UNDOTAG_CopyDestName, DestName,
865 UNDOTAG_IconPosX, xi,
866 UNDOTAG_IconPosY, yi,
867 TAG_END);
868 Result = DoMethod(DrInfo->drin_FileTransObj, SCCM_FileTrans_Copy,
869 DrInfo->drin_Arg->scarg_lock, DrInfo->drin_DestLock,
870 DrInfo->drin_Arg->scarg_name,
871 DestName, xi, yi);
872 break;
874 case LOCK_SAME_VOLUME:
875 Result = Icon2Icon_MoveDir(iwtSrc, DrInfo, undoStep);
876 break;
879 if (DestName)
880 FreePathBuffer(DestName);
882 d1(kprintf("%s/%s/%ld: Result=%08lx\n", __FILE__, __FUNC__, __LINE__, Result));
884 return Result;
888 static ULONG Icon2Icon_MoveDir(struct internalScaWindowTask *iwtSrc, struct DropInfo *DrInfo, APTR undoStep)
890 ULONG Result;
891 LONG xi = DrInfo->drin_x, yi = DrInfo->drin_y;
893 d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
895 if (NO_ICON_POSITION_SHORT != xi)
897 xi += DrInfo->drin_Arg->scarg_xpos;
898 yi += DrInfo->drin_Arg->scarg_ypos;
901 UndoAddEvent(iwtSrc, UNDO_Move,
902 UNDOTAG_UndoMultiStep, undoStep,
903 UNDOTAG_CopySrcDirLock, DrInfo->drin_Arg->scarg_lock,
904 UNDOTAG_CopyDestDirLock, DrInfo->drin_DestLock,
905 UNDOTAG_CopySrcName, DrInfo->drin_Arg->scarg_name,
906 UNDOTAG_IconPosX, xi,
907 UNDOTAG_IconPosY, yi,
908 TAG_END);
910 Result = DoMethod(DrInfo->drin_FileTransObj, SCCM_FileTrans_Move,
911 DrInfo->drin_Arg->scarg_lock, DrInfo->drin_DestLock,
912 DrInfo->drin_Arg->scarg_name, xi, yi);
914 d1(kprintf("%s/%s/%ld: Result=%08lx\n", __FILE__, __FUNC__, __LINE__, Result));
916 return Result;
920 static ULONG Icon2Icon_CopyDir(struct internalScaWindowTask *iwtSrc, struct DropInfo *DrInfo, CONST_STRPTR DestName, APTR undoStep)
922 ULONG Result;
923 LONG xi = DrInfo->drin_x, yi = DrInfo->drin_y;
925 if (NO_ICON_POSITION_SHORT != xi)
927 xi += DrInfo->drin_Arg->scarg_xpos;
928 yi += DrInfo->drin_Arg->scarg_ypos;
931 UndoAddEvent(iwtSrc, UNDO_Copy,
932 UNDOTAG_UndoMultiStep, undoStep,
933 UNDOTAG_CopySrcDirLock, DrInfo->drin_Arg->scarg_lock,
934 UNDOTAG_CopyDestDirLock, DrInfo->drin_DestLock,
935 UNDOTAG_CopySrcName, DrInfo->drin_Arg->scarg_name,
936 UNDOTAG_CopyDestName, DestName,
937 UNDOTAG_IconPosX, xi,
938 UNDOTAG_IconPosY, yi,
939 TAG_END);
941 Result = DoMethod(DrInfo->drin_FileTransObj, SCCM_FileTrans_Copy,
942 DrInfo->drin_Arg->scarg_lock, DrInfo->drin_DestLock,
943 DrInfo->drin_Arg->scarg_name, DestName, xi, yi);
945 return Result;
949 static ULONG Icon2Icon_CreateLink(struct internalScaWindowTask *iwtSrc, struct DropInfo *DrInfo, APTR undoStep)
951 ULONG Result;
952 LONG xi = DrInfo->drin_x, yi = DrInfo->drin_y;
954 if (NO_ICON_POSITION_SHORT != xi)
956 xi += DrInfo->drin_Arg->scarg_xpos;
957 yi += DrInfo->drin_Arg->scarg_ypos;
960 UndoAddEvent(iwtSrc, UNDO_CreateLink,
961 UNDOTAG_UndoMultiStep, undoStep,
962 UNDOTAG_CopySrcDirLock, DrInfo->drin_Arg->scarg_lock,
963 UNDOTAG_CopyDestDirLock, DrInfo->drin_DestLock,
964 UNDOTAG_CopySrcName, DrInfo->drin_Arg->scarg_name,
965 UNDOTAG_IconPosX, xi,
966 UNDOTAG_IconPosY, yi,
967 TAG_END);
969 Result = DoMethod(DrInfo->drin_FileTransObj, SCCM_FileTrans_CreateLink,
970 DrInfo->drin_Arg->scarg_lock, DrInfo->drin_DestLock,
971 DrInfo->drin_Arg->scarg_name,
972 DrInfo->drin_Arg->scarg_name,
973 xi, yi);
975 d1(kprintf("%s/%s/%ld: Result=%08lx\n", __FILE__, __FUNC__, __LINE__, Result));
977 return Result;
981 static void Icon2DesktopDrop(struct ScalosArg **ArgList,
982 struct ScaWindowStruct *wsSrc,
983 struct ScaWindowStruct *wsDest,
984 struct DropInfo *DrInfo)
986 struct internalScaWindowTask *iwtSrc, *iwtDest;
987 struct MsgPort *replyPort;
988 struct BackDropList bdl; // +jmc+
990 d1(KPrintF("%s/%s/%ld: Src=%08lx <%s> Dest=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, \
991 wsSrc, wsSrc->ws_Name, wsDest, wsDest->ws_Name));
993 if (NULL == wsSrc || NULL == wsDest)
994 return;
996 iwtSrc = (struct internalScaWindowTask *) wsSrc->ws_WindowTask;
997 iwtDest = (struct internalScaWindowTask *) wsDest->ws_WindowTask;
999 if (NULL == iwtSrc || NULL == iwtDest)
1000 return;
1002 BackDropInitList(&bdl); // +jmc+
1004 do {
1005 APTR undoStep;
1006 struct ScaIconNode *in;
1007 struct ScalosArg *arg;
1009 ScalosLockIconListShared(iwtDest);
1011 in = CheckMouseIcon(&iwtDest->iwt_WindowTask.wt_IconList, iwtDest,
1012 DrInfo->drin_x, DrInfo->drin_y);
1013 d1(kprintf("%s/%s/%ld: in=%08lx x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, in, DrInfo->drin_x, DrInfo->drin_y));
1014 if (in)
1016 // Drop on some icon
1017 IPTR IconType;
1019 GetAttr(IDTA_Type, in->in_Icon, &IconType);
1021 d1(kprintf("%s/%s/%ld: in=%08lx <%s> Type=%ld\n", __FILE__, __FUNC__, __LINE__, in, \
1022 GetIconName(in), IconType));
1023 switch (IconType)
1025 case WBDISK:
1026 case WBDRAWER:
1027 case WB_TEXTICON_DRAWER:
1028 case WBGARBAGE:
1029 ScalosUnLockIconList(iwtDest);
1030 Icon2IconDrop(ArgList, wsSrc, wsDest, DrInfo);
1031 return;
1032 break;
1036 ScalosUnLockIconList(iwtDest);
1038 // Drop onto desktop
1039 replyPort = CreateMsgPort();
1040 if (NULL == replyPort)
1041 break;
1043 undoStep = UndoBeginStep();
1045 for (arg = *ArgList; arg; arg = (struct ScalosArg *) arg->scarg_Node.mln_Succ)
1047 ULONG Result;
1049 d1(KPrintF("%s/%s/%ld: DrInfo->drin_Arg=%08lx <%s> Type=%ld\n", __FILE__, __FUNC__, __LINE__, \
1050 arg, arg->scarg_name, arg->scarg_icontype));
1052 if (WBDISK == arg->scarg_icontype)
1053 continue;
1055 DrInfo->drin_Drops.drop_LeaveOut = TRUE;
1056 if (CurrentPrefs.pref_AutoLeaveOut)
1058 d1(KPrintF("%s/%s/%ld: drin_x=%ld drin_y=%ld\n", __FILE__, __FUNC__, __LINE__, DrInfo->drin_x, DrInfo->drin_y));
1059 d1(KPrintF("%s/%s/%ld: scarg_xpos=%ld scarg_ypos=%ld\n", __FILE__, __FUNC__, __LINE__, arg->scarg_xpos, arg->scarg_ypos));
1061 UndoAddEvent(iwtSrc, UNDO_Leaveout,
1062 UNDOTAG_UndoMultiStep, undoStep,
1063 UNDOTAG_IconDirLock, arg->scarg_lock,
1064 UNDOTAG_IconName, arg->scarg_name,
1065 UNDOTAG_IconPosX, DrInfo->drin_x + arg->scarg_xpos,
1066 UNDOTAG_IconPosY, DrInfo->drin_y + arg->scarg_ypos,
1067 TAG_END);
1069 DoLeaveOutIcon(iwtSrc,
1070 arg->scarg_lock,
1071 arg->scarg_name,
1072 DrInfo->drin_x + arg->scarg_xpos,
1073 DrInfo->drin_y + arg->scarg_ypos);
1075 d1(KPrintF("%s/%s/%ld: DoLeaveout(name=<%s>) Type=%ld\n", __FILE__, __FUNC__, __LINE__, \
1076 arg->scarg_name, arg->scarg_icontype));
1078 else
1080 // Add icon to destination window
1081 Result = DropAddIcon(replyPort, wsDest,
1082 arg->scarg_lock,
1083 arg->scarg_name,
1084 DrInfo->drin_x + arg->scarg_xpos,
1085 DrInfo->drin_y + arg->scarg_ypos);
1087 d1(KPrintF("%s/%s/%ld: DropAddIcon(name=<%s>) Type=%ld\n", __FILE__, __FUNC__, __LINE__, \
1088 arg->scarg_name, arg->scarg_icontype));
1089 // +jmc+
1090 if (IsPermanentBackDropIcon(iwtDest, &bdl, arg->scarg_lock, arg->scarg_name))
1092 ScalosLockIconListExclusive(iwtDest);
1094 for (in = iwtDest->iwt_WindowTask.wt_IconList; in; in=(struct ScaIconNode *) in->in_Node.mln_Succ)
1096 d1(KPrintF("%s/%s/%ld: in_Name=%08lx\n", __FILE__, __FUNC__, __LINE__, in->in_Name));
1098 if (in->in_Lock && (LOCK_SAME == SameLock(in->in_Lock, arg->scarg_lock))
1099 && in->in_Name && 0 == Stricmp(arg->scarg_name, in->in_Name))
1101 struct SM_RedrawIconObj *sMsg;
1103 SetAttrs(in->in_Icon,
1104 IDTA_OverlayType, ICONOVERLAYF_LeftOut,
1105 TAG_END);
1107 d1(KPrintF("%s/%s/%ld: scarg_name=<%s> in->in_Name=<%s> ICONOVERLAYF_LeftOut is SET\n", __FILE__, __FUNC__, __LINE__, \
1108 arg->scarg_name, in->in_Name));
1110 sMsg = (struct SM_RedrawIconObj *) SCA_AllocMessage(MTYP_RedrawIconObj, 0);
1112 d1(KPrintF("%s/%s/%ld: sMsg=%08lx\n", __FILE__, __FUNC__, __LINE__, sMsg));
1114 if (sMsg)
1116 sMsg->smrio_IconObject = in->in_Icon;
1117 sMsg->smrio_Flags = SMRIOFLAGF_IconListLocked;
1118 PutMsg(iwtDest->iwt_WindowTask.wt_IconPort,
1119 &sMsg->ScalosMessage.sm_Message);
1124 ScalosUnLockIconList(iwtDest);
1127 if (0 == Result)
1128 continue;
1130 // Remove icon from source window
1131 DropRemoveIcon(wsSrc, arg->scarg_lock, arg->scarg_name);
1133 // Special handling for "view all" textwindows.
1134 // here both object and icon are separate entries, which must be removed both!
1135 if (!IsIwtViewByIcon(iwtSrc) && IsShowAll(wsSrc))
1137 STRPTR IconInfoName = ScalosAlloc(1 + strlen(arg->scarg_name) + strlen(".info"));
1139 if (IconInfoName)
1141 strcpy(IconInfoName, arg->scarg_name);
1142 strcat(IconInfoName, ".info");
1144 // remove associated ".info" icon from source window
1145 DropRemoveIcon(wsSrc, arg->scarg_lock, IconInfoName);
1147 ScalosFree(IconInfoName);
1153 UndoEndStep(iwtSrc, undoStep);
1154 } while (0);
1156 if (replyPort)
1157 DeleteMsgPort(replyPort);
1159 BackdropFreeList(&bdl);
1161 ScalosReleaseSemaphore(iwtSrc->iwt_WindowTask.wt_WindowSemaphore);
1162 ScalosReleaseSemaphore(iwtDest->iwt_WindowTask.wt_WindowSemaphore);
1164 ClassDragFinish_IconWin(ArgList);
1168 static void Desktop2DesktopDrop(struct ScalosArg **ArgList, struct ScaWindowStruct *wsSrc,
1169 struct ScaWindowStruct *wsDest, struct DropInfo *DrInfo)
1171 struct internalScaWindowTask *iwtDest;
1172 struct ScaIconNode *in;
1174 d1(KPrintF("%s/%s/%ld: Src=%08lx <%s> Dest=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, \
1175 wsSrc, wsSrc->ws_Name, wsDest, wsDest->ws_Name));
1177 if (NULL == wsSrc || NULL == wsDest)
1178 return;
1180 iwtDest = (struct internalScaWindowTask *) wsDest->ws_WindowTask;
1182 if (NULL == iwtDest)
1183 return;
1185 ScalosLockIconListShared(iwtDest);
1187 in = CheckMouseIcon(&iwtDest->iwt_WindowTask.wt_IconList, iwtDest, DrInfo->drin_x, DrInfo->drin_y);
1188 if (in)
1190 IPTR IconType;
1192 GetAttr(IDTA_Type, in->in_Icon, &IconType);
1193 switch (IconType)
1195 case WBDISK:
1196 for (DrInfo->drin_Arg = *ArgList; DrInfo->drin_Arg; DrInfo->drin_Arg = (struct ScalosArg *) DrInfo->drin_Arg->scarg_Node.mln_Succ)
1198 STRPTR p;
1199 BPTR diskcopyLock;
1200 char ch;
1202 d1(kprintf("%s/%s/%ld: DrInfo->drin_Arg=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, DrInfo->drin_Arg, DrInfo->drin_Arg->scarg_name));
1204 if (WBDISK != DrInfo->drin_Arg->scarg_icontype)
1205 continue;
1207 p = PathPart((STRPTR) CurrentPrefs.pref_DefDiskCopy);
1208 ch = *p;
1209 *p = '\0';
1211 diskcopyLock = Lock((STRPTR) CurrentPrefs.pref_DefDiskCopy, ACCESS_READ);
1213 *p = ch;
1215 if (diskcopyLock)
1217 struct WBArg ArgArray[3];
1219 ArgArray[0].wa_Lock = diskcopyLock;
1220 ArgArray[0].wa_Name = FilePart((STRPTR) CurrentPrefs.pref_DefDiskCopy);
1222 ArgArray[1].wa_Lock = (BPTR)NULL;
1223 ArgArray[1].wa_Name = NULL;
1224 if (DrInfo->drin_Arg->scarg_lock)
1225 ArgArray[1].wa_Lock = DupLock(DrInfo->drin_Arg->scarg_lock);
1226 else
1227 ArgArray[1].wa_Name = DrInfo->drin_Arg->scarg_name;
1229 ArgArray[2].wa_Lock = DiskInfoLock(in);
1230 ArgArray[2].wa_Name = NULL;
1232 if ((BPTR)NULL == ArgArray[2].wa_Lock)
1233 ArgArray[2].wa_Name = in->in_DeviceIcon->di_Device;
1235 SCA_WBStart(ArgArray, NULL, 3);
1238 DrInfo->drin_Arg->scarg_icontype = 0;
1240 break;
1241 default:
1242 ScalosUnLockIconList(iwtDest);
1243 Desktop2IconDrop(ArgList, wsSrc, wsDest, DrInfo);
1244 return;
1245 break;
1249 ScalosUnLockIconList(iwtDest);
1251 Desktop2IconDrop(ArgList, wsSrc, wsDest, DrInfo);
1255 // drop icon(s) from desktop (=device window) to some icon window
1256 static void Desktop2IconDrop(struct ScalosArg **ArgList,
1257 struct ScaWindowStruct *wsSrc,
1258 struct ScaWindowStruct *wsDest,
1259 struct DropInfo *DrInfo)
1261 struct internalScaWindowTask *iwtSrc, *iwtDest;
1262 BPTR SrcLock = (BPTR)NULL;
1263 BPTR oldDir = NOT_A_LOCK;
1264 struct MsgPort *replyPort = NULL;
1265 BOOL WindowsLocked = TRUE;
1266 APTR undoStep = NULL;
1268 d1(KPrintF("%s/%s/%ld: START Src=%08lx <%s> Dest=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, \
1269 wsSrc, wsSrc->ws_Name, wsDest, wsDest->ws_Name));
1271 if (NULL == wsSrc || NULL == wsDest)
1272 return;
1274 iwtSrc = (struct internalScaWindowTask *) wsSrc->ws_WindowTask;
1275 iwtDest = (struct internalScaWindowTask *) wsDest->ws_WindowTask;
1277 if (NULL == iwtSrc || NULL == iwtDest)
1278 return;
1280 do {
1281 ULONG Result = RETURN_OK;
1282 struct ScaIconNode *in;
1284 if (wsSrc->ws_Lock)
1286 SrcLock = DupLock(wsSrc->ws_Lock);
1287 if ((BPTR)NULL == SrcLock)
1288 break;
1290 if (wsDest->ws_Lock)
1292 DrInfo->drin_DestLock = DupLock(wsDest->ws_Lock);
1293 if ((BPTR)NULL == DrInfo->drin_DestLock)
1294 break;
1297 oldDir = CurrentDir(DrInfo->drin_DestLock);
1299 ScalosLockIconListShared(iwtDest);
1301 in = CheckMouseIcon(&iwtDest->iwt_WindowTask.wt_IconList,
1302 iwtDest, DrInfo->drin_x, DrInfo->drin_y);
1303 d1(kprintf("%s/%s/%ld: in=%08lx iwtDest=%08lx\n", __FILE__, __FUNC__, __LINE__, in, iwtDest));
1304 if (in)
1306 IPTR IconType;
1307 BPTR IconLock = (BPTR)NULL;
1309 GetAttr(IDTA_Type, in->in_Icon, &IconType);
1310 switch (IconType)
1312 case WBDISK:
1313 IconLock = DiskInfoLock(in);
1314 break;
1315 case WBDRAWER:
1316 case WBGARBAGE:
1317 case WB_TEXTICON_DRAWER:
1318 if (in->in_Lock)
1320 BPTR oldDir2 = CurrentDir(in->in_Lock);
1322 IconLock = Lock((STRPTR) GetIconName(in), ACCESS_READ);
1324 CurrentDir(oldDir2);
1326 else
1327 IconLock = Lock((STRPTR) GetIconName(in), ACCESS_READ);
1328 break;
1331 if (IconLock)
1333 UnLock(DrInfo->drin_DestLock);
1334 DrInfo->drin_DestLock = IconLock;
1335 DrInfo->drin_x = NO_ICON_POSITION_SHORT;
1336 DrInfo->drin_y = NO_ICON_POSITION_SHORT;
1340 ScalosUnLockIconList(iwtDest);
1342 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1344 CurrentDir(oldDir);
1345 oldDir = NOT_A_LOCK;
1347 replyPort = CreateMsgPort();
1348 if (NULL == replyPort)
1349 break;
1351 undoStep = UndoBeginStep();
1353 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1355 for (DrInfo->drin_Arg = *ArgList; DrInfo->drin_Arg; DrInfo->drin_Arg = (struct ScalosArg *) DrInfo->drin_Arg->scarg_Node.mln_Succ)
1357 d1(kprintf("%s/%s/%ld: DrInfo->drin_Arg=%08lx <%s> IconType=%ld\n", \
1358 __FILE__, __FUNC__, __LINE__, \
1359 DrInfo->drin_Arg, DrInfo->drin_Arg->scarg_name, DrInfo->drin_Arg->scarg_icontype));
1361 if (WBDISK == DrInfo->drin_Arg->scarg_icontype)
1362 continue;
1364 debugLock_d1(DrInfo->drin_DestLock);
1365 debugLock_d1(DrInfo->drin_Arg->scarg_lock);
1367 if (LOCK_SAME == ScaSameLock(DrInfo->drin_DestLock, DrInfo->drin_Arg->scarg_lock))
1369 // drop left-out icon back into its native window
1370 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1372 DrInfo->drin_Drops.drop_PutAway = TRUE;
1374 UndoAddEvent(iwtSrc, UNDO_PutAway,
1375 UNDOTAG_UndoMultiStep, undoStep,
1376 UNDOTAG_IconDirLock, DrInfo->drin_Arg->scarg_lock,
1377 UNDOTAG_IconName, DrInfo->drin_Arg->scarg_name,
1378 TAG_END);
1380 PutAwayIcon(iwtSrc,
1381 DrInfo->drin_Arg->scarg_lock,
1382 DrInfo->drin_Arg->scarg_name,
1383 CurrentPrefs.pref_AutoLeaveOut);
1385 d1(kprintf("%s/%s/%ld: PutAwayIcon(name=<%s>) IconType=%ld\n", \
1386 __FILE__, __FUNC__, __LINE__, \
1387 DrInfo->drin_Arg->scarg_name, DrInfo->drin_Arg->scarg_icontype));
1389 if (NO_ICON_POSITION_SHORT == DrInfo->drin_x)
1391 struct ScaUpdateIcon_IW upd;
1393 upd.ui_iw_Lock = DrInfo->drin_Arg->scarg_lock;
1394 upd.ui_iw_Name = DrInfo->drin_Arg->scarg_name;
1395 upd.ui_IconType = ICONTYPE_NONE;
1397 SCA_UpdateIcon(SIV_IconWin, &upd, sizeof(upd));
1399 else
1401 ULONG Result;
1403 Result = DropAddIcon(replyPort, wsDest,
1404 DrInfo->drin_Arg->scarg_lock,
1405 DrInfo->drin_Arg->scarg_name,
1406 DrInfo->drin_x + DrInfo->drin_Arg->scarg_xpos,
1407 DrInfo->drin_y + DrInfo->drin_Arg->scarg_ypos);
1409 if (0 == Result)
1411 DropAddIcon(replyPort, wsSrc,
1412 DrInfo->drin_Arg->scarg_lock,
1413 DrInfo->drin_Arg->scarg_name,
1414 DrInfo->drin_x + DrInfo->drin_Arg->scarg_xpos,
1415 DrInfo->drin_y + DrInfo->drin_Arg->scarg_ypos);
1418 // Special handling for "view all" textwindows.
1419 // here both object and icon are separate entries, which must be added both!
1420 if (!IsIwtViewByIcon(iwtDest) && IsShowAll(wsDest))
1422 STRPTR IconInfoName = ScalosAlloc(1 + strlen(DrInfo->drin_Arg->scarg_name) + strlen(".info"));
1424 if (IconInfoName)
1426 strcpy(IconInfoName, DrInfo->drin_Arg->scarg_name);
1427 strcat(IconInfoName, ".info");
1429 // add associated ".info" icon to destination window
1430 DropAddIcon(replyPort, wsDest,
1431 DrInfo->drin_Arg->scarg_lock,
1432 IconInfoName,
1433 DrInfo->drin_x + DrInfo->drin_Arg->scarg_xpos,
1434 DrInfo->drin_y + DrInfo->drin_Arg->scarg_ypos);
1436 ScalosFree(IconInfoName);
1441 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1444 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1446 DeleteMsgPort(replyPort);
1447 replyPort = NULL;
1449 ScalosReleaseSemaphore(iwtSrc->iwt_WindowTask.wt_WindowSemaphore);
1450 ScalosReleaseSemaphore(iwtDest->iwt_WindowTask.wt_WindowSemaphore);
1451 WindowsLocked = FALSE;
1453 for (DrInfo->drin_Arg = *ArgList;
1454 RESULT_UserAborted != Result && DrInfo->drin_Arg;
1455 DrInfo->drin_Arg = (struct ScalosArg *) DrInfo->drin_Arg->scarg_Node.mln_Succ)
1457 LONG xi = DrInfo->drin_x, yi = DrInfo->drin_y;
1459 d1(kprintf("%s/%s/%ld: DrInfo->drin_Arg=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, DrInfo->drin_Arg, DrInfo->drin_Arg->scarg_name));
1461 if (NO_ICON_POSITION_SHORT != xi)
1463 xi += DrInfo->drin_Arg->scarg_xpos;
1464 yi += DrInfo->drin_Arg->scarg_ypos;
1467 switch (DrInfo->drin_Arg->scarg_icontype)
1469 case WBDRAWER:
1470 case WB_TEXTICON_DRAWER:
1471 case WBGARBAGE:
1472 Result = Icon2IconDrop_Drawer(iwtSrc, DrInfo, undoStep);
1473 break;
1474 case WBTOOL:
1475 case WB_TEXTICON_TOOL:
1476 Result = Icon2IconDrop_File(iwtSrc, DrInfo, undoStep);
1477 break;
1479 case WBDISK:
1480 if (LOCK_DIFFERENT == ScaSameLock(DrInfo->drin_DestLock, DrInfo->drin_Arg->scarg_lock) ||
1481 DrInfo->drin_Drops.drop_Copy || DrInfo->drin_Drops.drop_CreateLink)
1483 STRPTR Name = NULL;
1484 BPTR oldDir2 = BNULL;
1486 debugLock_d1(DrInfo->drin_DestLock);
1487 debugLock_d1(DrInfo->drin_Arg->scarg_lock);
1489 do {
1490 struct DropOps AllowedDrops;
1492 AllowedDrops.drop_CreateLink = TRUE;
1493 AllowedDrops.drop_Copy = TRUE;
1494 AllowedDrops.drop_Move = FALSE;
1496 if (!DropPopupMenu(iwtSrc, DrInfo, &AllowedDrops))
1497 break;
1499 oldDir2 = CurrentDir(DrInfo->drin_DestLock);
1501 Name = AllocPathBuffer();
1502 if (NULL == Name)
1503 break;
1505 if (!NameFromLock(DrInfo->drin_Arg->scarg_lock, Name, Max_PathLen-1))
1506 break;
1508 d1(kprintf("%s/%s/%ld: Name=<%s>\n", __FILE__, __FUNC__, __LINE__, Name));
1510 StripTrailingColon(Name);
1512 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1514 if (DrInfo->drin_Drops.drop_CreateLink)
1516 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1517 UndoAddEvent(iwtSrc, UNDO_CreateLink,
1518 UNDOTAG_UndoMultiStep, undoStep,
1519 UNDOTAG_CopySrcDirLock, DrInfo->drin_Arg->scarg_lock,
1520 UNDOTAG_CopyDestDirLock, DrInfo->drin_DestLock,
1521 UNDOTAG_CopySrcName, "",
1522 UNDOTAG_CopyDestName, Name,
1523 UNDOTAG_IconPosX, xi,
1524 UNDOTAG_IconPosY, yi,
1525 TAG_END);
1526 Result = DoMethod(DrInfo->drin_FileTransObj,
1527 SCCM_FileTrans_CreateLink,
1528 DrInfo->drin_Arg->scarg_lock,
1529 DrInfo->drin_DestLock,
1530 "", Name,
1531 xi, yi);
1533 else
1535 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1536 UndoAddEvent(iwtSrc, UNDO_Copy,
1537 UNDOTAG_UndoMultiStep, undoStep,
1538 UNDOTAG_CopySrcDirLock, DrInfo->drin_Arg->scarg_lock,
1539 UNDOTAG_CopyDestDirLock, DrInfo->drin_DestLock,
1540 UNDOTAG_CopySrcName, "",
1541 UNDOTAG_CopyDestName, Name,
1542 UNDOTAG_IconPosX, xi,
1543 UNDOTAG_IconPosY, yi,
1544 TAG_END);
1545 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1546 Result = DoMethod(DrInfo->drin_FileTransObj,
1547 SCCM_FileTrans_Copy,
1548 DrInfo->drin_Arg->scarg_lock,
1549 DrInfo->drin_DestLock,
1550 "", Name,
1551 xi, yi);
1552 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1555 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1556 } while (0);
1558 if (Name)
1559 FreePathBuffer(Name);
1561 CurrentDir(oldDir2);
1563 break;
1565 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1568 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1570 ClassDragFinish_IconWin(ArgList);
1571 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1572 } while (0);
1574 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1576 if (undoStep)
1577 UndoEndStep(iwtSrc, undoStep);
1578 if (replyPort)
1579 DeleteMsgPort(replyPort);
1580 if (IS_VALID_LOCK(oldDir))
1581 CurrentDir(oldDir);
1582 if (SrcLock)
1583 UnLock(SrcLock);
1584 if (DrInfo->drin_DestLock)
1586 UnLock(DrInfo->drin_DestLock);
1587 DrInfo->drin_DestLock = (BPTR)NULL;
1590 if (WindowsLocked)
1592 ScalosReleaseSemaphore(iwtSrc->iwt_WindowTask.wt_WindowSemaphore);
1593 ScalosReleaseSemaphore(iwtDest->iwt_WindowTask.wt_WindowSemaphore);
1596 d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
1600 static ULONG DropAddIcon(struct MsgPort *ReplyPort, struct ScaWindowStruct *wsDest,
1601 BPTR DirLock, STRPTR IconName, WORD x, WORD y)
1603 struct SM_AddIcon *aMsg;
1604 ULONG Result;
1605 ULONG *resPtr;
1607 aMsg = (struct SM_AddIcon *) SCA_AllocMessage(MTYP_AddIcon, 0);
1608 d1(kprintf("%s/%s/%ld: aMsg=%08lx\n", __FILE__, __FUNC__, __LINE__, aMsg));
1609 if (NULL == aMsg)
1610 return 0;
1612 aMsg->ScalosMessage.sm_Message.mn_ReplyPort = ReplyPort;
1613 aMsg->smai_x = x;
1614 aMsg->smai_y = y;
1615 aMsg->smai_DirLock = DirLock;
1616 aMsg->smai_IconName = IconName;
1618 PutMsg(wsDest->ws_MessagePort, &aMsg->ScalosMessage.sm_Message);
1620 d1(kprintf("%s/%s/%ld: before WaitPort\n", __FILE__, __FUNC__, __LINE__));
1622 WaitPort(ReplyPort);
1624 d1(kprintf("%s/%s/%ld: after WaitPort\n", __FILE__, __FUNC__, __LINE__));
1626 aMsg = (struct SM_AddIcon *) GetMsg(ReplyPort);
1627 resPtr = (ULONG *)&aMsg->smai_x;
1628 Result = *resPtr ;
1630 SCA_FreeMessage(&aMsg->ScalosMessage);
1632 return Result;
1636 static void DropRemoveIcon(struct ScaWindowStruct *wsDest, BPTR DirLock, CONST_STRPTR IconName)
1638 struct SM_RemIcon *rMsg;
1640 // allocate space for the icon name at the end of the SM_RemIcon structure
1641 rMsg = (struct SM_RemIcon *) SCA_AllocMessage(MTYP_RemIcon, 1 + strlen(IconName));
1642 d1(KPrintF("%s/%s/%ld: IconName=<%s> rMsg=%08lx\n", __FILE__, __FUNC__, __LINE__, IconName, rMsg));
1643 if (rMsg)
1645 STRPTR ClonedIconName;
1647 ClonedIconName = (STRPTR) (rMsg + 1);
1648 strcpy(ClonedIconName, IconName);
1650 rMsg->ScalosMessage.sm_Message.mn_ReplyPort = NULL;
1651 rMsg->smri_DirLock = DirLock;
1652 rMsg->smri_IconName = ClonedIconName;
1654 PutMsg(wsDest->ws_MessagePort, &rMsg->ScalosMessage.sm_Message);
1659 ULONG ScalosDropAddIcon(BPTR DirLock, CONST_STRPTR IconName, WORD x, WORD y)
1661 struct MsgPort *ReplyPort;
1662 ULONG Result = 0;
1663 struct ScaWindowStruct *ws;
1665 ReplyPort = CreateMsgPort();
1666 d1(KPrintF("%s/%s/%ld: ReplyPort=%08lx\n", __FILE__, __FUNC__, __LINE__, ReplyPort));
1667 if (NULL == ReplyPort)
1668 return (ULONG) IoErr();
1670 SCA_LockWindowList(SCA_LockWindowList_Shared);
1672 for (ws=winlist.wl_WindowStruct; ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
1674 if (ws->ws_Lock && LOCK_SAME == SameLock(DirLock, ws->ws_Lock))
1676 d1(kprintf("%s/%s/%ld: found Window\n", __FILE__, __FUNC__, __LINE__));
1678 if (&ws->ws_Task->pr_Task == FindTask(NULL))
1680 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1681 Result = DoMethod(ws->ws_WindowTask->mt_MainObject,
1682 SCCM_IconWin_AddIcon,
1683 SCCM_ADDICON_MAKEXY(x, y),
1684 DirLock,
1685 IconName);
1687 else
1689 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1690 Result = DropAddIcon(ReplyPort,
1692 DirLock,
1693 (STRPTR) IconName,
1694 x, y);
1699 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1701 SCA_UnLockWindowList();
1703 d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
1705 DeleteMsgPort(ReplyPort);
1707 return Result;
1711 void ScalosDropRemoveIcon(BPTR DirLock, CONST_STRPTR IconName)
1713 struct ScaWindowStruct *ws;
1715 d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
1717 SCA_LockWindowList(SCA_LockWindowList_Shared);
1719 for (ws=winlist.wl_WindowStruct; ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
1721 if (ws->ws_Lock && LOCK_SAME == SameLock(DirLock, ws->ws_Lock))
1723 DropRemoveIcon(ws, DirLock, (STRPTR) IconName);
1727 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1729 SCA_UnLockWindowList();
1733 static void DronOnAppIcon(struct internalScaWindowTask *iwt, struct internalScaWindowTask *iwtDest,
1734 struct ScaIconNode *in, LONG x, LONG y)
1736 d1(kprintf("%s/%s/%ld: iwt=%08lx iwtFound=%08lx Icon=%08lx <%s> x=%ld y=%ld\n", \
1737 __LINE__, iwt, iwtDest, in, GetIconName(in), x, y));
1739 RestoreDragIcons(iwt);
1741 ScalosLockIconListShared(iwtDest);
1743 if (iwtDest->iwt_AppListSemaphore)
1745 struct AppObject *ao;
1747 ScalosObtainSemaphoreShared(iwtDest->iwt_AppListSemaphore);
1749 for (ao=iwtDest->iwt_AppList; ao; ao = (struct AppObject *) ao->appo_Node.mln_Succ)
1751 if (APPTYPE_AppIcon == ao->appo_type &&
1752 in->in_Icon == ao->appo_object.appoo_IconObject)
1754 ScalosUnLockIconList(iwtDest);
1756 if (ScalosAttemptSemaphoreShared(iwtDest->iwt_WindowTask.wt_WindowSemaphore))
1758 DronOnAppObject(iwt, ao, x, y);
1760 ScalosReleaseSemaphore(iwtDest->iwt_WindowTask.wt_WindowSemaphore);
1762 ScalosLockIconListShared(iwtDest);
1763 break;
1768 ScalosReleaseSemaphore(iwtDest->iwt_AppListSemaphore);
1771 ScalosUnLockIconList(iwtDest);
1775 static void DronOnAppObject(struct internalScaWindowTask *iwt, struct AppObject *ao, LONG x, LONG y)
1777 struct DragNode *dn;
1778 struct AppMessage *am;
1779 struct WBArg *argList;
1780 size_t Len;
1781 ULONG ArgCount;
1782 ULONG NumberOfDroppedIcons;
1784 d1(kprintf("%s/%s/%ld: iwt=%08lx AppObj=%08lx x=%ld y=%ld\n", \
1785 __LINE__, iwt, ao, x, y));
1787 for (dn = iwt->iwt_DragNodeList, NumberOfDroppedIcons = 0;
1788 dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
1789 NumberOfDroppedIcons++;
1791 Len = sizeof(struct AppMessage) + sizeof(struct WBArg) * NumberOfDroppedIcons;
1793 am = AllocVec(Len, MEMF_PUBLIC | MEMF_CLEAR);
1794 if (NULL == am)
1795 return;
1797 d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
1799 argList = (struct WBArg *) &am[1];
1801 am->am_Message.mn_ReplyPort = iInfos.xii_iinfos.ii_MainMsgPort;
1802 am->am_Message.mn_Length = Len;
1804 switch (ao->appo_type)
1806 case APPTYPE_AppIcon:
1807 am->am_Type = AMTYPE_APPICON;
1808 break;
1809 case APPTYPE_AppWindow:
1810 am->am_Type = AMTYPE_APPWINDOW;
1811 break;
1812 case APPTYPE_AppMenuItem:
1813 am->am_Type = AMTYPE_APPMENUITEM;
1814 break;
1817 am->am_UserData = ao->appo_userdata;
1818 am->am_ID = ao->appo_id;
1819 am->am_Version = AM_VERSION;
1821 x += iwt->iwt_WindowTask.wt_Window->LeftEdge;
1822 y += iwt->iwt_WindowTask.wt_Window->TopEdge;
1824 if (APPTYPE_AppWindow == ao->appo_type)
1826 x -= ao->appo_object.appoo_Window->LeftEdge;
1827 y -= ao->appo_object.appoo_Window->TopEdge;
1830 am->am_MouseX = x;
1831 am->am_MouseY = y;
1833 CurrentTime(&am->am_Seconds, &am->am_Micros);
1835 am->am_Reserved[0] = ID_APPM;
1836 am->am_ArgList = argList;
1838 d1(kprintf("%s/%s/%ld: x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, x, y));
1840 ArgCount = 0;
1842 ScalosLockIconListShared(iwt);
1844 for (dn=iwt->iwt_DragNodeList; dn && ArgCount < NumberOfDroppedIcons; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
1846 struct ScaIconNode *in = dn->drgn_iconnode;
1847 IPTR IconType;
1848 BPTR oldDir;
1849 BPTR fLock;
1851 GetAttr(IDTA_Type, dn->drgn_icon, &IconType);
1853 d1(kprintf("%s/%s/%ld: dn=%08lx <%s> Type=%ld\n", __FILE__, __FUNC__, __LINE__, dn, GetIconName(in), IconType));
1855 switch (IconType)
1857 case WBTOOL:
1858 case WBPROJECT:
1859 case WB_TEXTICON_TOOL: // Text Tool
1860 //.tool:
1861 if (in->in_Name)
1863 if (in->in_Lock)
1864 fLock = DupLock(in->in_Lock);
1865 else
1867 if (iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock)
1868 fLock = DupLock(iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock);
1869 else
1870 fLock = (BPTR)NULL;
1873 argList->wa_Lock = fLock;
1874 argList->wa_Name = AllocCopyString(in->in_Name);
1876 argList++;
1877 ArgCount++;
1879 break;
1881 case WBAPPICON:
1882 break;
1884 default:
1885 oldDir = CurrentDir(in->in_Lock ? in->in_Lock : iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock);
1887 if (in->in_DeviceIcon)
1888 fLock = DiskInfoLock(in);
1889 else
1890 fLock = Lock((STRPTR) GetIconName(in), ACCESS_READ);
1892 CurrentDir(oldDir);
1894 if (fLock)
1896 argList->wa_Lock = fLock;
1897 argList->wa_Name = AllocCopyString(NULL);
1899 argList++;
1900 ArgCount++;
1902 break;
1906 ScalosUnLockIconList(iwt);
1908 d1(kprintf("%s/%s/%ld: ArgCount=%ld\n", __FILE__, __FUNC__, __LINE__, ArgCount));
1910 am->am_NumArgs = ArgCount;
1911 if (0 == am->am_NumArgs)
1912 am->am_ArgList = NULL;
1914 PutMsg(ao->appo_msgport, &am->am_Message);
1918 static void SameWindow(struct internalScaWindowTask *iwt, struct internalScaWindowTask *iwtDest, LONG x, LONG y)
1920 struct DragNode *dn;
1921 struct Region *ClipRegion;
1922 BOOL fIconsMoved = FALSE;
1923 APTR undoStep;
1924 LONG x1, y1;
1926 d1(kprintf("%s/%s/%ld: iwt=%08lx iwtFound=%08lx x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, iwt, iwtDest, x, y));
1928 if (iwt->iwt_RemIconsFlag && IsIwtViewByIcon(iwt) && CurrentPrefs.pref_AutoRemoveFlag)
1930 SameWindow2(iwt, iwtDest, x, y);
1931 return;
1934 ScalosLockIconListExclusive(iwt);
1936 x1 = iwt->iwt_InnerLeft - iwt->iwt_WindowTask.wt_XOffset;
1937 y1 = iwt->iwt_InnerTop - iwt->iwt_WindowTask.wt_YOffset;
1939 ClipRegion = NewRegion();
1941 undoStep = UndoBeginStep();
1943 for (dn=iwt->iwt_DragNodeList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
1945 struct ScaIconNode *in = dn->drgn_iconnode;
1946 const struct ExtGadget *gg = (const struct ExtGadget *) in->in_Icon;
1948 d1(kprintf("%s/%s/%ld: in=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, in, GetIconName(in)));
1950 if (!(in->in_Flags & INF_Sticky))
1952 struct Rectangle IconRect;
1954 IconRect.MinX = x1 + gg->BoundsLeftEdge;
1955 IconRect.MaxX = IconRect.MinX + gg->BoundsWidth - 1;
1956 IconRect.MinY = y1 + gg->BoundsTopEdge;
1957 IconRect.MaxY = IconRect.MinY + gg->BoundsHeight - 1;
1959 UndoAddEvent(iwt, UNDO_ChangeIconPos,
1960 UNDOTAG_UndoMultiStep, undoStep,
1961 UNDOTAG_IconDirLock, in->in_Lock ?
1962 in->in_Lock : iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock,
1963 UNDOTAG_IconNode, in,
1964 UNDOTAG_IconPosX, dn->drgn_x + x,
1965 UNDOTAG_IconPosY, y + dn->drgn_y,
1966 TAG_END);
1968 d1(kprintf("%s/%s/%ld: IconRect x=%ld %ld y=%ld %ld\n", __FILE__, __FUNC__, __LINE__, \
1969 IconRect.MinX, IconRect.MaxX, IconRect.MinY, IconRect.MaxY));
1971 OrRectRegion(ClipRegion, &IconRect);
1973 fIconsMoved = TRUE;
1975 MoveIconToNewPosition(iwt, in, dn->drgn_x + x, y + dn->drgn_y);
1979 d1(kprintf("%s/%s/%ld: IconsMoved=%ld\n", __FILE__, __FUNC__, __LINE__, fIconsMoved));
1981 UndoEndStep(iwt, undoStep);
1983 if (fIconsMoved)
1985 struct Rectangle WindowRect;
1987 WindowRect.MinX = WindowRect.MaxX = iwt->iwt_InnerLeft;
1988 WindowRect.MinY = WindowRect.MaxY = iwt->iwt_InnerTop;
1989 WindowRect.MaxX += iwt->iwt_InnerWidth - 1;
1990 WindowRect.MaxY += iwt->iwt_InnerHeight - 1;
1992 AndRectRegion(ClipRegion, &WindowRect);
1994 if (iwt->iwt_DragFlags & DRAGFLAGF_WindowLocked)
1996 iwt->iwt_DragFlags |= DRAGFLAGF_UpdatePending;
1998 else
2000 struct Region *oldClipRegion;
2002 d1(kprintf("%s/%s/%ld: DragFlags=%08lx ClipRegion=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_DragFlags, ClipRegion));
2004 oldClipRegion = InstallClipRegion(iwt->iwt_WindowTask.wt_Window->WLayer, ClipRegion);
2006 EraseRect(iwt->iwt_WindowTask.wt_Window->RPort,
2007 0, 0,
2008 iwt->iwt_WindowTask.wt_Window->Width - 1,
2009 iwt->iwt_WindowTask.wt_Window->Height - 1);
2011 RefreshIcons(iwt, NULL); // refresh icons NOT in iwt_DragNodeList
2013 InstallClipRegion(iwt->iwt_WindowTask.wt_Window->WLayer, oldClipRegion);
2014 d1(kprintf("%s/%s/%ld: oldClipRegion=%08lx\n", __FILE__, __FUNC__, __LINE__, oldClipRegion));
2017 DisposeRegion(ClipRegion);
2019 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_CleanUp);
2021 DragRefreshIcons(iwt); // refresh icons from iwt_DragNodeList
2023 ScalosUnLockIconList(iwt);
2025 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_SetVirtSize,
2026 SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider);
2028 else
2030 ScalosUnLockIconList(iwt);
2031 DisposeRegion(ClipRegion);
2036 static void SameWindow2(struct internalScaWindowTask *iwt, struct internalScaWindowTask *iwtDest, LONG x, LONG y)
2038 APTR undoStep;
2039 struct DragNode *dn;
2040 struct ScaIconNode *initialDragIconList;
2042 d1(KPrintF("%s/%s/%ld: iwt=%08lx iwtFound=%08lx x=%ld y=%ld\n", __FILE__, __FUNC__, __LINE__, iwt, iwtDest, x, y));
2044 ScalosLockIconListExclusive(iwt);
2046 initialDragIconList = iwt->iwt_DragIconList;
2048 undoStep = UndoBeginStep();
2050 for (dn=iwt->iwt_DragNodeList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
2052 SCA_MoveIconNode(&iwt->iwt_DragIconList, &iwt->iwt_WindowTask.wt_IconList, dn->drgn_iconnode);
2054 if (!(dn->drgn_iconnode->in_Flags & INF_Sticky))
2056 UndoAddEvent(iwt, UNDO_ChangeIconPos,
2057 UNDOTAG_UndoMultiStep, undoStep,
2058 UNDOTAG_IconDirLock, dn->drgn_iconnode->in_Lock ?
2059 dn->drgn_iconnode->in_Lock : iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock,
2060 UNDOTAG_IconNode, dn->drgn_iconnode,
2061 UNDOTAG_IconPosX, dn->drgn_x + x,
2062 UNDOTAG_IconPosY, y + dn->drgn_y,
2063 TAG_END);
2065 MoveIconToNewPosition(iwt, dn->drgn_iconnode, dn->drgn_x + x, y + dn->drgn_y);
2069 UndoEndStep(iwt, undoStep);
2071 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_CleanUp);
2073 RefreshIconList(iwt, initialDragIconList, NULL);
2075 ScalosUnLockIconList(iwt);
2077 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_SetVirtSize,
2078 SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider);
2082 static ULONG DragQuery_IconWin(struct ScaIconNode *in, ULONG IconType)
2084 switch (IconType)
2086 case WBDISK:
2087 case WBDRAWER:
2088 case WBGARBAGE:
2089 case WB_TEXTICON_DRAWER:
2090 return TRUE;
2091 break;
2094 return FALSE;
2098 static void MoveIconToNewPosition(struct internalScaWindowTask *iwt,
2099 struct ScaIconNode *in, WORD xNew, WORD yNew)
2101 struct ExtGadget *gg = (struct ExtGadget *) in->in_Icon;
2102 WORD x0, y0;
2103 BOOL NewPosNoGood = FALSE;
2104 WORD origLeft, origTop, origBoundsLeft, origBoundsTop;
2106 origLeft = gg->LeftEdge;
2107 origBoundsLeft = gg->BoundsLeftEdge;
2108 origTop = gg->TopEdge;
2109 origBoundsTop = gg->BoundsTopEdge;
2111 x0 = gg->LeftEdge - gg->BoundsLeftEdge;
2113 gg->LeftEdge = xNew;
2114 gg->BoundsLeftEdge = gg->LeftEdge - x0;
2116 y0 = gg->TopEdge - gg->BoundsTopEdge;
2118 gg->TopEdge = yNew;
2119 gg->BoundsTopEdge = gg->TopEdge - y0;
2121 if (iwt->iwt_BackDrop)
2122 NewPosNoGood = CheckPosition(iwt, in);
2124 if (!CurrentPrefs.pref_DDIconsMayOverlap)
2125 NewPosNoGood = NewPosNoGood || CheckOverlap(iwt, in);
2127 if (NewPosNoGood)
2129 // Put icon back to original position
2130 // and move it back to wt_IconList
2131 ScalosLockIconListExclusive(iwt);
2133 gg->LeftEdge = origLeft;
2134 gg->BoundsLeftEdge = origBoundsLeft;
2135 gg->TopEdge = origTop;
2136 gg->BoundsTopEdge = origBoundsTop;
2138 SCA_MoveIconNode(&iwt->iwt_WindowTask.wt_LateIconList, &iwt->iwt_WindowTask.wt_IconList, in);
2140 ScalosUnLockIconList(iwt);
2146 static BOOL DropPopupMenu(struct internalScaWindowTask *iwtSrc,
2147 struct DropInfo *DrInfo, const struct DropOps *AllowedDrops)
2149 BOOL DoDrop = TRUE;
2151 if (CurrentPrefs.pref_EnableDropMenu && !DrInfo->drin_Drops.drop_PutAway && !DrInfo->drin_Drops.drop_LeaveOut)
2153 if (DrInfo->drin_LastAllowedDrops.drop_Copy != AllowedDrops->drop_Copy
2154 || DrInfo->drin_LastAllowedDrops.drop_Move != AllowedDrops->drop_Move
2155 || DrInfo->drin_LastAllowedDrops.drop_CreateLink != AllowedDrops->drop_CreateLink
2156 || DrInfo->drin_LastAllowedDrops.drop_PutAway != AllowedDrops->drop_PutAway
2157 || DrInfo->drin_LastAllowedDrops.drop_LeaveOut != AllowedDrops->drop_LeaveOut)
2158 DrInfo->drin_LastDropMenuResult = DROPMENURESULT_Unknown;
2160 d1(KPrintF("%s/%s/%ld: drin_LastDropMenuResult=%ld\n", __FILE__, __FUNC__, __LINE__, DrInfo->drin_LastDropMenuResult));
2162 if (DROPMENURESULT_Unknown != DrInfo->drin_LastDropMenuResult)
2164 switch (DrInfo->drin_LastDropMenuResult)
2166 case DROPMENURESULT_Copy:
2167 DrInfo->drin_Drops.drop_Copy = TRUE;
2168 DrInfo->drin_Drops.drop_Move = FALSE;
2169 DrInfo->drin_Drops.drop_CreateLink = FALSE;
2170 break;
2171 case DROPMENURESULT_Move:
2172 DrInfo->drin_Drops.drop_Copy = FALSE;
2173 DrInfo->drin_Drops.drop_Move = TRUE;
2174 DrInfo->drin_Drops.drop_CreateLink = FALSE;
2175 break;
2176 case DROPMENURESULT_CreateLink:
2177 DrInfo->drin_Drops.drop_Copy = FALSE;
2178 DrInfo->drin_Drops.drop_Move = FALSE;
2179 DrInfo->drin_Drops.drop_CreateLink = TRUE;
2180 break;
2181 default:
2182 DoDrop = FALSE;
2183 break;
2186 else
2188 struct PopupMenu *pm;
2189 struct PopupMenu *pmLast;
2190 Object *MenuImages[DROPMENUIMAGE_MAX];
2191 ULONG n;
2193 MenuImages[DROPMENUIMAGE_Abort] = NewObject(DtImageClass, NULL,
2194 DTIMG_ImageName, (IPTR) "THEME:Menu/DropMenu/Abort",
2195 TAG_END);
2196 d1(KPrintF("%s/%s/%ld: DROPMENUIMAGE_Abort=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuImages[DROPMENUIMAGE_Abort]));
2197 MenuImages[DROPMENUIMAGE_Copy] = NewObject(DtImageClass, NULL,
2198 DTIMG_ImageName, (IPTR) "THEME:Menu/DropMenu/Copy",
2199 TAG_END);
2200 d1(KPrintF("%s/%s/%ld: DROPMENUIMAGE_Copy=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuImages[DROPMENUIMAGE_Copy]));
2201 MenuImages[DROPMENUIMAGE_Move] = NewObject(DtImageClass, NULL,
2202 DTIMG_ImageName, (IPTR) "THEME:Menu/DropMenu/Move",
2203 TAG_END);
2204 d1(KPrintF("%s/%s/%ld: DROPMENUIMAGE_Move=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuImages[DROPMENUIMAGE_Move]));
2205 MenuImages[DROPMENUIMAGE_CreateLink] = NewObject(DtImageClass, NULL,
2206 DTIMG_ImageName, (IPTR) "THEME:Menu/DropMenu/CreateLink",
2207 TAG_END);
2208 d1(KPrintF("%s/%s/%ld: DROPMENUIMAGE_CreateLink=%08lx\n", __FILE__, __FUNC__, __LINE__, MenuImages[DROPMENUIMAGE_CreateLink]));
2210 pm = PM_MakeMenu(PM_Item, (IPTR) PM_MakeItem(PM_TitleID, MSGID_DROPMENU_DROPMENUTITLE,
2211 PM_NoSelect, TRUE,
2212 PM_ShinePen, TRUE,
2213 PM_Shadowed, TRUE,
2214 PM_Center, TRUE,
2215 TAG_END),
2216 PM_Item, (IPTR) (pmLast = PM_MakeItem(PM_WideTitleBar, TRUE,
2217 TAG_END)),
2218 PM_Item, (IPTR) PM_MakeItem(PM_TitleBar, TRUE,
2219 TAG_END),
2220 PM_Item, (IPTR) PM_MakeItem(PM_TitleID, MSGID_DROPMENU_CANCEL,
2221 PM_UserData, DROPMENURESULT_Cancel,
2222 MenuImages[DROPMENUIMAGE_Abort] ? PM_IconUnselected : TAG_IGNORE, (IPTR) MenuImages[DROPMENUIMAGE_Abort],
2223 MenuImages[DROPMENUIMAGE_Abort] ? PM_IconSelected : TAG_IGNORE, (IPTR) MenuImages[DROPMENUIMAGE_Abort],
2224 TAG_END),
2225 TAG_END);
2227 d1(KPrintF("%s/%s/%ld: pm=%08lx pmLast=%08lx\n", __FILE__, __FUNC__, __LINE__, pm, pmLast));
2228 if (pm)
2230 ULONG UserData;
2231 struct PopupMenu *pmLastNext;
2233 d1(KPrintF("%s/%s/%ld: drop_Copy=%ld\n", __FILE__, __FUNC__, __LINE__, AllowedDrops->drop_Copy));
2234 d1(KPrintF("%s/%s/%ld: drop_Move=%ld\n", __FILE__, __FUNC__, __LINE__, AllowedDrops->drop_Move));
2235 d1(KPrintF("%s/%s/%ld: drop_CreateLink=%ld\n", __FILE__, __FUNC__, __LINE__, AllowedDrops->drop_CreateLink));
2237 if (AllowedDrops->drop_Copy)
2239 d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
2240 PM_InsertMenuItem(pm,
2241 PM_Insert_After, (IPTR) pmLast,
2242 PM_Insert_Item, (IPTR) (pmLastNext = PM_MakeItem(PM_TitleID, MSGID_DROPMENU_COPY,
2243 PM_UserData, DROPMENURESULT_Copy,
2244 MenuImages[DROPMENUIMAGE_Copy] ? PM_IconUnselected : TAG_IGNORE, (IPTR) MenuImages[DROPMENUIMAGE_Copy],
2245 MenuImages[DROPMENUIMAGE_Copy] ? PM_IconSelected : TAG_IGNORE, (IPTR) MenuImages[DROPMENUIMAGE_Copy],
2246 TAG_END)),
2247 TAG_END);
2248 pmLast = pmLastNext;
2249 d1(KPrintF("%s/%s/%ld: pmLast=%08lx\n", __FILE__, __FUNC__, __LINE__, pmLast));
2251 if (AllowedDrops->drop_Move)
2253 d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
2254 PM_InsertMenuItem(pm,
2255 PM_Insert_After, (IPTR) pmLast,
2256 PM_Insert_Item, (IPTR) (pmLastNext = PM_MakeItem(PM_TitleID, MSGID_DROPMENU_MOVE,
2257 PM_UserData, DROPMENURESULT_Move,
2258 MenuImages[DROPMENUIMAGE_Move] ? PM_IconUnselected : TAG_IGNORE, (IPTR) MenuImages[DROPMENUIMAGE_Move],
2259 MenuImages[DROPMENUIMAGE_Move] ? PM_IconSelected : TAG_IGNORE, (IPTR) MenuImages[DROPMENUIMAGE_Move],
2260 TAG_END)),
2261 TAG_END);
2262 pmLast = pmLastNext;
2263 d1(KPrintF("%s/%s/%ld: pmLast=%08lx\n", __FILE__, __FUNC__, __LINE__, pmLast));
2265 if (AllowedDrops->drop_CreateLink)
2267 d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
2268 PM_InsertMenuItem(pm,
2269 PM_Insert_After, (IPTR) pmLast,
2270 PM_Insert_Item, (IPTR) (pmLastNext = PM_MakeItem(PM_TitleID, MSGID_DROPMENU_CREATE_LINK,
2271 PM_UserData, DROPMENURESULT_CreateLink,
2272 MenuImages[DROPMENUIMAGE_CreateLink] ? PM_IconUnselected : TAG_IGNORE, (IPTR) MenuImages[DROPMENUIMAGE_CreateLink],
2273 MenuImages[DROPMENUIMAGE_CreateLink] ? PM_IconSelected : TAG_IGNORE, (IPTR) MenuImages[DROPMENUIMAGE_CreateLink],
2274 TAG_END)),
2275 TAG_END);
2276 //pmLast = pmLastNext;
2277 d1(KPrintF("%s/%s/%ld: pmLast=%08lx\n", __FILE__, __FUNC__, __LINE__, pmLast));
2280 // PM_OpenPopupMenuA()
2281 UserData = PM_OpenPopupMenu(iwtSrc->iwt_WindowTask.wt_Window,
2282 PM_Menu, (IPTR) pm,
2283 PM_LocaleHook, (IPTR) &PMGetStringHook,
2284 TAG_END);
2285 d1(KPrintF("%s/%s/%ld: UserData=%ld\n", __FILE__, __FUNC__, __LINE__, UserData));
2287 DrInfo->drin_LastAllowedDrops = *AllowedDrops;
2288 DrInfo->drin_LastDropMenuResult = UserData;
2290 switch (UserData)
2292 case DROPMENURESULT_Copy:
2293 DrInfo->drin_Drops.drop_Copy = TRUE;
2294 DrInfo->drin_Drops.drop_Move = FALSE;
2295 DrInfo->drin_Drops.drop_CreateLink = FALSE;
2296 break;
2297 case DROPMENURESULT_Move:
2298 DrInfo->drin_Drops.drop_Copy = FALSE;
2299 DrInfo->drin_Drops.drop_Move = TRUE;
2300 DrInfo->drin_Drops.drop_CreateLink = FALSE;
2301 break;
2302 case DROPMENURESULT_CreateLink:
2303 DrInfo->drin_Drops.drop_Copy = FALSE;
2304 DrInfo->drin_Drops.drop_Move = FALSE;
2305 DrInfo->drin_Drops.drop_CreateLink = TRUE;
2306 break;
2307 default:
2308 DoDrop = FALSE;
2309 break;
2313 for (n = 0; n < Sizeof(MenuImages); n++)
2315 if (MenuImages[n])
2316 DisposeObject(MenuImages[n]);
2321 ClosePopupWindows(TRUE);
2323 return DoDrop;