forwarding build fix when MUIA_Scrollgroup_AutoBars is defined (NicJA).
[AROS-Contrib.git] / scalos / main / Class.c
blob1d73f3745656387884988b7d701e8f2523831fde
1 // Class.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 <intuition/gadgetclass.h>
13 #include <intuition/newmouse.h>
14 #include <workbench/workbench.h>
15 #include <workbench/startup.h>
16 #include <cybergraphx/cybergraphics.h>
17 #include <dos/dostags.h>
18 #include <dos/datetime.h>
20 #define __USE_SYSBASE
22 #include <proto/dos.h>
23 #include <proto/exec.h>
24 #include <proto/layers.h>
25 #include <proto/intuition.h>
26 #include <proto/graphics.h>
27 #include <proto/cybergraphics.h>
28 #include <proto/utility.h>
29 #include <proto/locale.h>
30 #include <proto/iconobject.h>
31 #include <proto/rexxsyslib.h>
32 #include "debug.h"
33 #include <proto/scalos.h>
35 #include <clib/alib_protos.h>
37 #include <defs.h>
38 #include <datatypes/iconobject.h>
39 #include <scalos/scalos.h>
40 #include <scalos/GadgetBar.h>
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <string.h>
46 #include <DefIcons.h>
48 #include "scalos_structures.h"
49 #include "functions.h"
50 #include "Variables.h"
52 //----------------------------------------------------------------------------
54 // local data structures
56 struct ScaMakeWbArg
58 struct ScaIconNode *mwa_IconNode;
59 struct WBArg *mwa_Buffer;
62 struct FormatDateHookData
64 STRPTR fdhd_Buffer; // buffer to write characters to
65 size_t fdhd_Length; // length of buffer
68 //----------------------------------------------------------------------------
70 // local functions
72 static BOOL IsSameWindowIcon(struct internalScaWindowTask *iwtSrc,
73 struct internalScaWindowTask *iwtDest, struct ScaIconNode *inDest);
74 static SAVEDS(void) FormatDateHookFunc(struct Hook *theHook, struct Locale *locale, char ch);
75 static BOOL isParentOf(BPTR srcDirLock, struct DragNode *dragList, BPTR dirLock, CONST_STRPTR objName);
76 static BPTR LockIcon(BPTR dirLock, struct ScaIconNode *in);
77 static void NotifyAppIconSelected(struct ScaWindowStruct *ws, Object *IconObj, BOOL Selected);
79 //----------------------------------------------------------------------------
81 // public data items :
83 //----------------------------------------------------------------------------
85 // iwt is Destination window
86 // returns BOOL :
87 // TRUE yes, we may drop here
88 // FALSE no, no drop allowed
89 ULONG ClassDragQuery(struct DragEnter *drge, struct internalScaWindowTask *iwt)
91 ULONG Result = TRUE;
92 struct internalScaWindowTask *iwtSrc = (struct internalScaWindowTask *) drge->drage_Window->ws_WindowTask;
93 struct DragNode *dn;
94 BOOL SrcIsAppIcon = FALSE;
95 BOOL SrcIsGarbage = FALSE;
96 BOOL SrcIsKick = FALSE;
97 BOOL SrcIsNoDrag = FALSE;
98 BOOL SrcIsDiskOrDrawer = FALSE;
100 // Check for source icons which may not be dropped on any other icon
101 for (dn = iwtSrc->iwt_DragNodeList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
103 IPTR SrcIconType;
104 STRPTR tt;
106 GetAttr(IDTA_Type, dn->drgn_icon, &SrcIconType);
108 tt = NULL;
109 if (DoMethod(dn->drgn_icon, IDTM_FindToolType, "SCALOS_NODRAG", &tt))
110 SrcIsNoDrag = TRUE;
112 switch (SrcIconType)
114 case WBAPPICON:
115 SrcIsAppIcon = TRUE;
116 break;
117 case WBGARBAGE:
118 SrcIsGarbage = TRUE;
119 break;
120 case WBKICK:
121 SrcIsKick = TRUE;
122 break;
123 case WBDISK:
124 case WBDRAWER:
125 case WBDEVICE:
126 case WB_TEXTICON_DRAWER:
127 SrcIsDiskOrDrawer = TRUE;
128 break;
132 if (drge->drage_Window && iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock)
134 // Device icons may not be copied into window on same volume
136 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
138 for (dn = iwtSrc->iwt_DragNodeList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
140 d1(kprintf("%s/%s/%ld: icon=%08lx <%s> Type=%ld DeviceIcon=%08lx\n", \
141 __FILE__, __FUNC__, __LINE__, drge->drage_Icon, drge->drage_Icon->in_Name, dn->drgn_iconnode->in_DeviceIcon));
143 if (dn->drgn_iconnode->in_DeviceIcon)
145 BPTR devLock = (BPTR)NULL;
147 if (dn->drgn_iconnode->in_DeviceIcon->di_Volume)
148 devLock = Lock(dn->drgn_iconnode->in_DeviceIcon->di_Volume, ACCESS_READ);
150 if ((BPTR)NULL == devLock && dn->drgn_iconnode->in_DeviceIcon->di_Device)
151 devLock = Lock(dn->drgn_iconnode->in_DeviceIcon->di_Device, ACCESS_READ);
153 if (devLock)
155 LONG sameLockVal = ScaSameLock(iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock, devLock);
157 debugLock_d1(devLock);
158 debugLock_d1(iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock);
159 d1(kprintf("%s/%s/%ld: ScaSameLock()=%ld\n", __FILE__, __FUNC__, __LINE__, sameLockVal));
161 UnLock(devLock);
163 if (LOCK_SAME == sameLockVal)
164 return FALSE;
165 if (LOCK_SAME_VOLUME == sameLockVal)
166 return FALSE;
173 if (drge->drage_Icon)
175 BOOL SameWindow;
177 // Kick, Garbage, AppIcons may not be dropped on other icons
178 if (SrcIsKick || SrcIsGarbage || SrcIsAppIcon)
179 return FALSE;
181 if (drge->drage_Icon->in_Icon)
183 // query icon if we may drop here
184 IPTR DestIconType;
186 GetAttr(IDTA_Type, drge->drage_Icon->in_Icon, &DestIconType);
188 d1(KPrintF("%s/%s/%ld: icon=%08lx <%s> Type=%ld\n", __FILE__, __FUNC__, __LINE__, drge->drage_Icon, drge->drage_Icon->in_Name, DestIconType));
190 switch (DestIconType)
192 case WBAPPICON:
193 case WBGARBAGE:
194 Result = TRUE;
195 break;
196 case WBTOOL:
197 Result = CurrentPrefs.pref_DragStartFlag ? TRUE : FALSE;
198 break;
199 case WBKICK:
200 case WBPROJECT:
201 case WB_TEXTICON_TOOL:
202 Result = FALSE;
203 break;
204 case WBDISK:
205 case WBDRAWER:
206 case WBDEVICE:
207 case WB_TEXTICON_DRAWER:
208 SameWindow = IsSameWindowIcon(iwtSrc, iwt, drge->drage_Icon);
210 d1(KPrintF("%s/%s/%ld: SameWindow=%ld SrcIsNoDrag=%ld\n", __FILE__, __FUNC__, __LINE__, SameWindow, SrcIsNoDrag));
211 if (SameWindow && SrcIsNoDrag)
213 Result = FALSE;
214 break;
217 if (drge->drage_Icon->in_DeviceIcon)
219 if (!ClassCheckInfoData(drge->drage_Icon->in_DeviceIcon->di_Info))
220 Result = FALSE;
222 else
224 Result = !(drge->drage_Icon->in_Flags & INF_VolumeWriteProtected);
227 if (SrcIsDiskOrDrawer && Result)
229 BPTR DestLock;
231 if (drge->drage_Icon->in_Lock)
232 DestLock = drge->drage_Icon->in_Lock;
233 else
234 DestLock = iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock;
236 d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
237 Result = !isParentOf(iwtSrc->iwt_WindowTask.mt_WindowStruct->ws_Lock, iwtSrc->iwt_DragNodeList,
238 DestLock, GetIconName(drge->drage_Icon));
239 d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
241 break;
242 default:
243 Result = TRUE;
244 break;
249 else
251 // query window if we may drop here
253 // AppIcons may not be dropped into different windows
254 if (SrcIsAppIcon && iwt != iwtSrc)
255 return FALSE;
257 if (iwt == iwtSrc)
259 // drop in same window
260 if (SrcIsNoDrag)
261 return FALSE; // SCALOS_NODRAG icons must not be dropped in same window
263 return TRUE; // always may drop in same window (no move/copy)
266 if ((BPTR)NULL == iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock && SrcIsNoDrag)
267 return FALSE; // SCALOS_NODRAG icons must not be dropped in desktop window
269 if (SrcIsDiskOrDrawer)
271 if (isParentOf(iwtSrc->iwt_WindowTask.mt_WindowStruct->ws_Lock, iwtSrc->iwt_DragNodeList,
272 iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock, NULL))
274 return FALSE;
278 Result = ClassIsDiskWritable(iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock);
281 return Result;
285 // return TRUE if Disk is writable
286 ULONG ClassCheckInfoData(const struct InfoData *info)
288 ULONG Result = TRUE;
290 d1(kprintf("%s/%s/%ld: DiskType=%ld DiskState=%ld\n", __FILE__, __FUNC__, __LINE__, info->id_DiskType, info->id_DiskState));
292 switch (info->id_DiskType)
294 case ID_NO_DISK_PRESENT:
295 case ID_UNREADABLE_DISK:
296 case ID_NOT_REALLY_DOS:
297 Result = FALSE;
298 break;
301 if (ID_WRITE_PROTECTED == info->id_DiskState)
302 Result = FALSE;
304 return Result;
308 // Note: it is VERY IMPORTANT that for every call to ClassDragEnter() (icon or window) you execute
309 // a corresponding ClassDragLeave() (icon or window) call !!!
310 ULONG ClassDragEnter(struct DragEnter *drge, struct internalScaWindowTask *iwtDest)
312 struct internalScaWindowTask *iwtSrc = (struct internalScaWindowTask *) drge->drage_Window->ws_WindowTask;
313 struct DragHandle *dh = iwtSrc->iwt_myDragHandle;
314 ULONG WasLocked;
316 // iwtDest : Window dragged into
317 // iwtSrc : Window dragged from (where dragging started)
319 d1(kprintf("%s/%s/%ld: Started. \n", __FILE__, __FUNC__, __LINE__));
321 d1(kprintf("%s/%s/%ld: iwtDest=%08lx icon=%08lx\n", __FILE__, __FUNC__, __LINE__, iwtDest, drge->drage_Icon));
323 if (dh)
324 ClassHideDragBobs(iwtDest, dh);
326 WasLocked = SCA_UnlockDrag(dh);
328 if (drge->drage_Icon)
330 // Pointer entered Icon area
331 // and left window area
333 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
335 if (iwtSrc->iwt_DragMayDrop)
337 IPTR IconType;
339 d1(kprintf("%s/%s/%ld: icon=%08lx <%s> Type=%ld\n", __FILE__, __FUNC__, __LINE__, drge->drage_Icon, drge->drage_Icon->in_Name));
341 ClassSelectIcon(iwtDest->iwt_WindowTask.mt_WindowStruct, drge->drage_Icon, TRUE);
343 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
345 GetAttr(IDTA_Type, drge->drage_Icon->in_Icon, &IconType);
346 switch (IconType)
348 case WBDRAWER:
349 case WBDISK:
350 case WBGARBAGE:
351 case WB_TEXTICON_DRAWER:
352 DoMethod(iwtSrc->iwt_WindowTask.mt_MainObject,
353 SCCM_IconWin_StartPopOpenTimer,
354 iwtDest,
355 dh, drge->drage_Icon);
356 break;
357 default:
358 break;
361 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
363 DisplayIconDropMark(iwtDest, drge->drage_Icon);
366 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
368 else
371 d1(kprintf("%s/%s/%ld: DisplayWindowDropMark(%s) \n", __FILE__, __FUNC__, __LINE__, iwtDest->iwt_WinTitle));
373 DisplayWindowDropMark(iwtDest);
375 DoMethod(iwtDest->iwt_WindowTask.mt_WindowObject, SCCM_Window_LockUpdate, TRUE);
378 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
380 ReLockDrag(dh, iwtSrc, WasLocked);
382 d1(kprintf("%s/%s/%ld: Finished. \n", __FILE__, __FUNC__, __LINE__));
384 return 0;
388 // Note: it is VERY IMPORTANT that for every call to ClassDragEnter() (icon or window) you execute
389 // a corresponding ClassDragLeave() (icon or window) call !!!
390 ULONG ClassDragLeave(struct DragEnter *drge, struct internalScaWindowTask *iwtDest)
392 struct internalScaWindowTask *iwtSrc = (struct internalScaWindowTask *) drge->drage_Window->ws_WindowTask;
393 struct DragHandle *dh = iwtSrc->iwt_myDragHandle;
394 ULONG WasLocked;
396 // iwtDest : Window dragged into
397 // iwtSrc : Window dragged from (where dragging started)
399 d1(kprintf("%s/%s/%ld: Started. \n", __FILE__, __FUNC__, __LINE__));
400 d1(kprintf("%s/%s/%ld: iwtDest=%08lx title=<%s> icon=%08lx\n", __FILE__, __FUNC__, __LINE__, iwtDest, iwtDest->iwt_WinTitle, drge->drage_Icon));
402 if (dh)
403 ClassHideDragBobs(iwtDest, dh);
405 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
407 WasLocked = SCA_UnlockDrag(dh);
409 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
411 DoMethod(iwtSrc->iwt_WindowTask.mt_MainObject, SCCM_IconWin_StopPopOpenTimer, dh);
413 if (drge->drage_Icon)
415 // pointer left icon area
416 // and is back in window area
417 struct Gadget *gg = (struct Gadget *) drge->drage_Icon->in_Icon;
419 if (gg->Flags & GFLG_SELECTED)
421 // remove icon drop mark
422 d1(kprintf("%s/%s/%ld: icon=%08lx <%s> Type=%ld\n", __FILE__, __FUNC__, __LINE__, drge->drage_Icon, drge->drage_Icon->in_Name));
424 EraseIconDropMark(iwtDest, drge->drage_Icon);
425 ClassSelectIcon(iwtDest->iwt_WindowTask.mt_WindowStruct, drge->drage_Icon, FALSE);
428 else
430 // Pointer left window area
431 d1(kprintf("%s/%s/%ld: CALL EraseWindowDropMark(%s)\n", __FILE__, __FUNC__, __LINE__ , iwtDest->iwt_WinTitle));
433 iwtDest->iwt_DragScrollX = iwtDest->iwt_DragScrollY = 0;
435 EraseWindowDropMark(iwtDest);
437 DoMethod(iwtDest->iwt_WindowTask.mt_WindowObject, SCCM_Window_UnlockUpdate);
440 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
442 ReLockDrag(dh, iwtSrc, WasLocked);
444 d1(kprintf("%s/%s/%ld: Finished. \n", __FILE__, __FUNC__, __LINE__));
446 return 0;
450 void ClassHideDragBobs(struct internalScaWindowTask *iwt, struct DragHandle *dh)
452 SCA_DrawDrag(dh, iwt->iwt_WinScreen->Width + 400, 0, SCAF_Drag_Hide);
456 void ClassSelectIcon(struct ScaWindowStruct *swi, struct ScaIconNode *sIcon, BOOL Selected)
458 d1(kprintf("%s/%s/%ld: swi=%08lx sIcon=%08lx Selected=%ld\n", __FILE__, __FUNC__, __LINE__, swi, sIcon, Selected);)
460 ClassSelectIconObj(swi, sIcon->in_Icon, Selected);
464 void ClassSelectIconObj(struct ScaWindowStruct *swi, Object *IconObj, BOOL Selected)
466 struct ExtGadget *gg = (struct ExtGadget *) IconObj;
468 d1(KPrintF("%s/%s/%ld: swi=%08lx IconObj=%08lx Selected=%ld\n", __FILE__, __FUNC__, __LINE__, swi, IconObj, Selected);)
470 if ( (!Selected && (gg->Flags & GFLG_SELECTED)) || (Selected && !(gg->Flags & GFLG_SELECTED)))
472 struct Window *win = swi->ws_Window;
474 SetAttrs(IconObj,
475 GA_Selected, Selected,
476 TAG_END);
478 if (Selected)
480 if (NULL == gg->SelectRender)
482 DoMethod(swi->ws_WindowTask->mt_MainObject,
483 SCCM_IconWin_LayoutIcon, IconObj,
484 IOLAYOUTF_SelectedImage, 0);
487 else
489 if (NULL == gg->GadgetRender)
491 DoMethod(swi->ws_WindowTask->mt_MainObject,
492 SCCM_IconWin_LayoutIcon, IconObj,
493 IOLAYOUTF_NormalImage);
497 if (win)
499 struct internalScaWindowTask *iwt = (struct internalScaWindowTask *) swi->ws_WindowTask;
501 d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
503 DoMethod(swi->ws_WindowTask->mt_MainObject,
504 SCCM_IconWin_DrawIcon, IconObj);
506 if (iwt->iwt_DragFlags & DRAGFLAGF_WindowMarked)
508 // Restore the part of the Window drop mark
509 // that has been destroyed by the icon redraw
510 struct Region *iconRegion;
512 iconRegion = NewRegion();
513 d1(kprintf("Restore the part of the Window drop mark\nthat has been destroyed by the icon redraw: \n"));
514 d1(kprintf("%s/%s/%ld: iconRegion=%08lx\n", __FILE__, __FUNC__, __LINE__, iconRegion));
515 if (iconRegion)
517 struct Rectangle IconRect;
519 IconRect.MinX = IconRect.MaxX = gg->BoundsLeftEdge - iwt->iwt_WindowTask.wt_XOffset + iwt->iwt_InnerLeft;
520 IconRect.MinY = IconRect.MaxY = gg->BoundsTopEdge - iwt->iwt_WindowTask.wt_YOffset + iwt->iwt_InnerTop;
521 IconRect.MaxX += gg->BoundsWidth - 1;
522 IconRect.MaxY += gg->BoundsHeight - 1;
524 d1(kprintf("%s/%s/%ld: MinX=%ld MinY=%ld MaxX=%ld MaxY=%ld\n", \
525 __FILE__, __FUNC__, __LINE__, IconRect.MinX, IconRect.MinY, IconRect.MaxX, IconRect.MaxY));
527 OrRectRegion(iconRegion, &IconRect);
529 d1(kprintf("%s/%s/%ld: CALL DrawWindowDropMark(iwt, iconRegion)\n"));
530 RedrawWindowDropMark(iwt, iconRegion);
532 DisposeRegion(iconRegion);
537 NotifyAppIconSelected(swi, IconObj, Selected);
542 BOOL ClassIsDiskWritable(BPTR dLock)
544 struct InfoData *info = ScalosAllocInfoData();
545 BOOL Result = TRUE;
547 if (info)
549 Info(dLock, info);
551 if (!ClassCheckInfoData(info))
552 Result = FALSE;
554 ScalosFreeInfoData(&info);
557 return Result;
561 ULONG ClassWinTimerMsg(struct internalScaWindowTask *iwt, struct Message *Msg, APTR p)
563 d1(KPrintF("%s/%s/%ld: START iwt=%08lx <%s> MoveGadId=%ld ws_Flags=%04lx\n", __FILE__, __FUNC__, __LINE__, \
564 iwt, iwt->iwt_WinTitle, iwt->iwt_MoveGadId, iwt->iwt_WindowTask.mt_WindowStruct->ws_Flags));
566 if (iwt->iwt_LockFlag)
568 struct SM_Timer *smtm = (struct SM_Timer *) Msg;
569 ULONG Seconds, Micros;
571 if (smtm->smtm_Time.tv_secs >= iwt->iwt_LockCount.tv_secs)
572 Seconds = smtm->smtm_Time.tv_secs - iwt->iwt_LockCount.tv_secs;
573 else
574 Seconds = 0;
576 if (smtm->smtm_Time.tv_micro >= iwt->iwt_LockCount.tv_micro)
577 Micros = smtm->smtm_Time.tv_micro - iwt->iwt_LockCount.tv_micro;
578 else
579 Micros = 0;
581 d1(kprintf("%s/%s/%ld: iwt_LockCount: Seconds=%lu Micros=%lu\n", __FILE__, __FUNC__, __LINE__, \
582 iwt->iwt_LockCount.tv_secs, iwt->iwt_LockCount.tv_micro));
583 d1(kprintf("%s/%s/%ld: Seconds=%lu Micros=%lu\n", __FILE__, __FUNC__, __LINE__, Seconds, Micros));
585 if (Micros > 500000)
586 Seconds++;
588 if (Seconds >= 2)
590 d1(kprintf("%s/%s/%ld: try to AbortFunctions() \n", __FILE__, __FUNC__, __LINE__));
592 AbortFunctions(iwt);
594 if (iwt->iwt_WindowTask.wt_Window)
595 ModifyIDCMP(iwt->iwt_WindowTask.wt_Window, iwt->iwt_IDCMPFlags);
597 if (!iwt->iwt_NeedsTimerFlag && !(iwt->iwt_WindowTask.mt_WindowStruct->ws_Flags & (WSV_FlagF_CheckUpdatePending | WSV_FlagF_Typing)))
598 iwt->iwt_WindowTask.mt_WindowStruct->ws_Flags &= ~WSV_FlagF_NeedsTimerMsg;
602 if (!iwt->iwt_LockFlag)
604 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_Ping);
605 d1(KPrintF("%s/%s/%ld: DOMETHOD mt_MainObject [SCCM_Ping]\n", __FILE__, __FUNC__, __LINE__));
606 DoMethod(iwt->iwt_WindowTask.mt_WindowObject, SCCM_Ping);
607 d1(KPrintF("%s/%s/%ld: DOMETHOD mt_WindowObject [SCCM_Ping]\n", __FILE__, __FUNC__, __LINE__));
610 d1(kprintf("%s/%s/%ld: Finished \n", __FILE__, __FUNC__, __LINE__));
612 return 0;
616 void ClassTimerToolTipMsg(struct internalScaWindowTask *iwt)
618 struct ScaIconNode *iconUnderPointer;
619 struct internalScaWindowTask *iwtUnderPointer;
620 struct internalScaWindowTask *iwtActiveWindow = NULL;
621 struct Window *foreignWindow;
622 struct ScaWindowStruct *ws;
623 BOOL LockFlag = FALSE;
625 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
627 SCA_LockWindowList(SCA_LockWindowList_Shared);
629 for (ws=winlist.wl_WindowStruct; ws; ws = (struct ScaWindowStruct *) ws->ws_Node.mln_Succ)
631 struct internalScaWindowTask *iwtx = (struct internalScaWindowTask *) ws->ws_WindowTask;
633 if (iwtx->iwt_LockFlag)
634 LockFlag = TRUE;
636 if (ws->ws_Window && ws->ws_Window->Flags & WFLG_WINDOWACTIVE)
638 iwtActiveWindow = (struct internalScaWindowTask *) ws->ws_WindowTask;
639 break;
643 SCA_UnLockWindowList();
645 d1(kprintf("%s/%s/%ld: iwtActiveWindow=%08lx \n", __FILE__, __FUNC__, __LINE__, iwtActiveWindow));
647 if (NULL == iwtActiveWindow)
649 // return if no Scalos window active
650 MainWindowTask->miwt_IconUnderPtrCount = 0;
651 MainWindowTask->miwt_LastIconUnderPtr = NULL;
652 MainWindowTask->miwt_LastGadgetUnderPtr = SGTT_GADGETID_unknown;
654 return;
657 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
659 if (!LockFlag)
661 enum sgttGadgetIDs gadgetUnderPointer = iInfos.xii_GlobalGadgetUnderPointer.ggd_GadgetID;
663 QueryObjectUnderPointer(&iwtUnderPointer, &iconUnderPointer, NULL, &foreignWindow);
665 d1(KPrintF("%s/%s/%ld: iconUnderPointer=%08lx\n", __FILE__, __FUNC__, __LINE__, iconUnderPointer));
666 d1(KPrintF("%s/%s/%ld: gadgetUnderPointer=%ld\n", __FILE__, __FUNC__, __LINE__, gadgetUnderPointer));
668 if (iwtUnderPointer != iInfos.xii_GlobalGadgetUnderPointer.ggd_iwt)
669 gadgetUnderPointer = SGTT_GADGETID_unknown;
671 d1(KPrintF("%s/%s/%ld: gadgetUnderPointer=%ld\n", __FILE__, __FUNC__, __LINE__, gadgetUnderPointer));
673 if ((SGTT_GADGETID_unknown == MainWindowTask->miwt_LastGadgetUnderPtr
674 || gadgetUnderPointer != MainWindowTask->miwt_LastGadgetUnderPtr)
676 (NULL == iconUnderPointer ||
677 iconUnderPointer != MainWindowTask->miwt_LastIconUnderPtr))
679 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
681 MainWindowTask->miwt_IconUnderPtrCount = 0;
682 MainWindowTask->miwt_LastIconUnderPtr = iconUnderPointer;
683 MainWindowTask->miwt_LastGadgetUnderPtr = gadgetUnderPointer;
685 else
687 d1(KPrintF("%s/%s/%ld: iwt_IconUnderPtrCount=%ld\n", __FILE__, __FUNC__, __LINE__, MainWindowTask->miwt_IconUnderPtrCount));
689 if (NULL == iwtUnderPointer || VGADGETID_IDLE != iwtActiveWindow->iwt_MoveGadId)
691 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
693 MainWindowTask->miwt_IconUnderPtrCount = 0;
694 MainWindowTask->miwt_LastIconUnderPtr = NULL;
695 MainWindowTask->miwt_LastGadgetUnderPtr = SGTT_GADGETID_unknown;
697 else
699 if (++MainWindowTask->miwt_IconUnderPtrCount == CurrentPrefs.pref_ToolTipDelaySeconds)
701 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
703 if (iconUnderPointer)
705 d1(KPrintF("%s/%s/%ld: iconUnderPointer=%08lx <%s>\n", \
706 __FILE__, __FUNC__, __LINE__, iconUnderPointer, iconUnderPointer->in_Name));
708 DoMethod(iwtUnderPointer->iwt_WindowTask.mt_MainObject,
709 SCCM_IconWin_ShowIconToolTip, iconUnderPointer);
711 else if (SGTT_GADGETID_unknown != gadgetUnderPointer)
713 d1(KPrintF("%s/%s/%ld: gadgetUnderPointer=%08lx\n", \
714 __FILE__, __FUNC__, __LINE__, gadgetUnderPointer));
716 DoMethod(iwtUnderPointer->iwt_WindowTask.mt_MainObject,
717 SCCM_IconWin_ShowGadgetToolTip, gadgetUnderPointer);
724 if (iwtUnderPointer)
726 if (iconUnderPointer)
727 ScalosUnLockIconList(iwtUnderPointer);
728 SCA_UnLockWindowList();
734 // Check if <inDest> is the disk/drawer icon for <inDest>
735 static BOOL IsSameWindowIcon(struct internalScaWindowTask *iwtSrc,
736 struct internalScaWindowTask *iwtDest, struct ScaIconNode *inDest)
738 BPTR iLock = (BPTR)NULL;
739 BOOL SameWindow = FALSE;
741 d1(KPrintF("%s/%s/%ld: iwtSrc=%08lx iwtDest=%08lx inDest=%08lx\n", \
742 __FILE__, __FUNC__, __LINE__, iwtSrc, iwtDest, inDest));
744 if (inDest->in_DeviceIcon)
746 if (inDest->in_DeviceIcon->di_Volume)
747 iLock = Lock(inDest->in_DeviceIcon->di_Volume, ACCESS_READ);
749 else
751 BPTR oldDir;
753 if (inDest->in_Lock)
755 // backdrop icon on desktop
756 oldDir = CurrentDir(inDest->in_Lock);
758 else
760 oldDir = CurrentDir(iwtDest->iwt_WindowTask.mt_WindowStruct->ws_Lock);
763 iLock = Lock(inDest->in_Name, ACCESS_READ);
765 CurrentDir(oldDir);
768 if (iLock)
770 debugLock_d1(iLock);
771 debugLock_d1(iwtSrc->iwt_WindowTask.mt_WindowStruct->ws_Lock);
773 SameWindow = LOCK_SAME == ScaSameLock(iwtSrc->iwt_WindowTask.mt_WindowStruct->ws_Lock, iLock);
774 UnLock(iLock);
777 return SameWindow;
781 // find corresponding (parent) icon for given Scalos window
782 Object *ClassGetWindowIconObject(struct internalScaWindowTask *iwt, Object **allocIconObj)
784 struct ScaWindowStruct *ws = iwt->iwt_WindowTask.mt_WindowStruct;
785 Object *IconObj = NULL;
786 LONG DirEntryType;
787 BPTR parentLock;
788 BPTR oldDir = NOT_A_LOCK;
789 CONST_STRPTR iconName;
791 do {
792 if (ws->ws_Flags & WSV_FlagF_RootWindow)
794 parentLock = DupLock(ws->ws_Lock);
796 iconName = "disk";
797 DirEntryType = ST_ROOT;
799 // first look in main window's device icon list
800 if (parentLock)
802 struct internalScaWindowTask *iwtMain = (struct internalScaWindowTask *) iInfos.xii_iinfos.ii_MainWindowStruct->ws_WindowTask;
803 struct ScaDeviceIcon *sdi;
804 struct FileLock *fLock = BADDR(parentLock);
806 for (sdi=iwtMain->iwt_DevIconList; sdi; sdi = (struct ScaDeviceIcon *) sdi->di_Node.mln_Succ)
808 if (sdi->di_Handler == fLock->fl_Task)
810 d1(kprintf("%s/%s/%ld: sdi=%08lx Icon=%08lx\n", __FILE__, __FUNC__, __LINE__, sdi, sdi->di_Icon));
811 IconObj = sdi->di_Icon;
816 else
818 parentLock = ParentDir(ws->ws_Lock);
820 iconName = ws->ws_Name;
821 DirEntryType = ST_USERDIR;
824 if ((BPTR)NULL == parentLock)
825 break;
827 oldDir = CurrentDir(parentLock);
829 if (NULL == IconObj)
830 IconObj = *allocIconObj = NewIconObject(iconName, NULL);
832 d1(kprintf("%s/%s/%ld: iconName=<%s> IconObj=%08lx\n", __FILE__, __FUNC__, __LINE__, iconName, IconObj));
833 if (NULL == IconObj)
835 ULONG Protection = 0L;
836 STRPTR IconPath;
838 do {
839 IconPath = AllocPathBuffer();
840 if (NULL == IconPath)
841 break;
843 if (!NameFromLock(parentLock, IconPath, Max_PathLen-1))
844 break;
846 if (!AddPart(IconPath, iconName, Max_PathLen-1))
847 break;
849 IconObj = *allocIconObj = (Object *) DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_GetDefIcon,
850 IconPath, DirEntryType, Protection, ICONTYPE_NONE);
851 } while (0);
853 if (IconPath)
854 FreePathBuffer(IconPath);
856 } while (0);
858 if (IS_VALID_LOCK(oldDir))
859 CurrentDir(oldDir);
860 if (parentLock)
861 UnLock(parentLock);
863 return IconObj;
867 void ClassFormatDate(struct DateTime *dt, ULONG DateMaxLen, ULONG TimeMaxLen)
869 if (ScalosLocale)
871 struct FormatDateHookData fd;
872 struct Hook fmtHook;
874 d1(kprintf("%s/%s/%ld: DateBuff=%08lx Len=%ld TimeBuff=%08lx Len=%ld\n", \
875 __FILE__, __FUNC__, __LINE__, dt->dat_StrDate, DateMaxLen, dt->dat_StrTime, DateMaxLen));
877 SETHOOKFUNC(fmtHook, FormatDateHookFunc);
878 fmtHook.h_Data = &fd;
880 fd.fdhd_Buffer = dt->dat_StrDate;
881 fd.fdhd_Length = DateMaxLen;
883 FormatDate(ScalosLocale, ScalosLocale->loc_ShortDateFormat,
884 &dt->dat_Stamp, &fmtHook);
886 fd.fdhd_Buffer = dt->dat_StrTime;
887 fd.fdhd_Length = TimeMaxLen;
889 FormatDate(ScalosLocale, ScalosLocale->loc_ShortTimeFormat,
890 &dt->dat_Stamp, &fmtHook);
892 else
894 DateToStr(dt); // no size checking possible here :(
899 static SAVEDS(void) FormatDateHookFunc(struct Hook *theHook, struct Locale *locale, char ch)
901 struct FormatDateHookData *fd = (struct FormatDateHookData *) theHook->h_Data;
903 (void) locale;
905 if (fd->fdhd_Length >= 1)
907 *(fd->fdhd_Buffer)++ = ch;
908 fd->fdhd_Length--;
913 // forbid drag-copying or -moving icon into own sibling window or on sibling icon
914 // to avoid errors or endless recursion
915 static BOOL isParentOf(BPTR srcDirLock, struct DragNode *dragList, BPTR dirLock, CONST_STRPTR objName)
917 BPTR destLock;
918 BOOL isParent = FALSE;
919 BPTR oldDir;
921 d1(kprintf("%s/%s/%ld: objName=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, objName, objName ? objName : ""));
923 if (objName)
925 BPTR oldDir = CurrentDir(dirLock);
927 destLock = Lock((STRPTR) objName, ACCESS_READ);
929 CurrentDir(oldDir);
931 else
932 destLock = DupLock(dirLock);
934 debugLock_d1(destLock);
936 if ((BPTR)NULL == destLock)
937 return FALSE;
939 oldDir = CurrentDir(srcDirLock);
941 while (dragList && !isParent)
943 BPTR srcLock;
945 srcLock = LockIcon(srcDirLock, dragList->drgn_iconnode);
947 debugLock_d1(srcLock);
948 if (srcLock)
950 BPTR prevLock = (BPTR)NULL;
951 BPTR parentLock;
953 switch (ScaSameLock(srcLock, destLock))
955 case LOCK_SAME:
956 return isParent = TRUE;
958 case LOCK_SAME_VOLUME:
959 parentLock = destLock;
960 do {
961 parentLock = ParentDir(parentLock);
962 if (prevLock)
963 UnLock(prevLock);
965 debugLock_d1(parentLock);
967 if (LOCK_SAME == ScaSameLock(srcLock, parentLock))
968 isParent = TRUE;
970 d1(kprintf("%s/%s/%ld: isParent=%ld\n", __FILE__, __FUNC__, __LINE__, isParent));
972 prevLock = parentLock;
973 } while (parentLock && !isParent);
975 if (prevLock)
976 UnLock(prevLock);
977 break;
979 default:
980 break;
982 UnLock(srcLock);
984 dragList = (struct DragNode *) dragList->drgn_Node.mln_Succ;
987 CurrentDir(oldDir);
988 UnLock(destLock);
990 d1(kprintf("%s/%s/%ld: isParent=%ld\n", __FILE__, __FUNC__, __LINE__, isParent));
992 return isParent;
996 static BPTR LockIcon(BPTR dirLock, struct ScaIconNode *in)
998 BPTR lock;
999 BPTR oldDir;
1001 if (in->in_Lock)
1002 oldDir = CurrentDir(in->in_Lock);
1003 else
1005 if (in->in_DeviceIcon)
1006 return DiskInfoLock(in);
1007 else
1008 oldDir = CurrentDir(dirLock);
1011 lock = Lock((STRPTR) GetIconName(in), ACCESS_READ);
1013 if (IS_VALID_LOCK(oldDir))
1014 CurrentDir(oldDir);
1016 return lock;
1020 ULONG ClassCountSelectedIcons(struct internalScaWindowTask *iwt)
1022 struct ScaIconNode *in;
1023 ULONG Count = 0;
1025 ScalosLockIconListShared(iwt);
1027 for (in=iwt->iwt_WindowTask.wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
1029 struct Gadget *gg = (struct Gadget *) in->in_Icon;
1031 if (gg->Flags & GFLG_SELECTED)
1032 Count++;
1035 ScalosUnLockIconList(iwt);
1037 return Count;
1041 static void NotifyAppIconSelected(struct ScaWindowStruct *ws, Object *IconObj, BOOL Selected)
1043 struct internalScaWindowTask *iwt = (struct internalScaWindowTask *) ws->ws_WindowTask;
1044 IPTR IconType;
1045 struct AppObject *appo;
1047 if (ws != iInfos.xii_iinfos.ii_MainWindowStruct)
1048 return;
1050 GetAttr(IDTA_Type, IconObj, &IconType);
1051 if (WBAPPICON != IconType)
1052 return;
1054 ScalosObtainSemaphoreShared(iwt->iwt_AppListSemaphore);
1056 for (appo=iwt->iwt_AppList; appo; appo = (struct AppObject *) appo->appo_Node.mln_Succ)
1058 if (APPTYPE_AppIcon == appo->appo_type &&
1059 appo->appo_object.appoo_IconObject == IconObj &&
1060 appo->appo_TagList &&
1061 GetTagData(WBAPPICONA_NotifySelectState, FALSE, appo->appo_TagList))
1063 SendAppMessage(appo,
1064 Selected ? AMCLASSICON_Selected : AMCLASSICON_Unselected,
1065 0, 0);
1066 break;
1070 ScalosReleaseSemaphore(iwt->iwt_AppListSemaphore);
1074 void ClassDragFinish_IconWin(struct ScalosArg **arglist)
1076 struct ScalosArg *scarg, *argNext;
1078 for (scarg=*arglist; scarg; scarg=argNext)
1080 argNext = (struct ScalosArg *) scarg->scarg_Node.mln_Succ;
1082 if (scarg->scarg_lock)
1083 UnLock(scarg->scarg_lock);
1084 if (scarg->scarg_name)
1085 FreeCopyString(scarg->scarg_name);
1086 if (scarg->scarg_ext)
1087 FreeCopyString(scarg->scarg_ext);
1089 SCA_FreeNode((struct ScalosNodeList *) arglist, &scarg->scarg_Node);
1094 void ClassDragBegin_DeviceWin(struct ScalosArg **ArgList, struct DragNode **dnList)
1096 ClassDragBegin_IconWin(ArgList, dnList);
1100 void ClassDragBegin_IconWin(struct ScalosArg **ArgList, struct DragNode **dnList)
1102 struct DragNode *dn;
1103 CONST_STRPTR Extension = NULL;
1104 Object *tempIconObj;
1106 for (dn=*dnList; dn; dn = (struct DragNode *) dn->drgn_Node.mln_Succ)
1108 struct ScalosArg *scarg = (struct ScalosArg *) SCA_AllocStdNode((struct ScalosNodeList *) ArgList, NTYP_ScalosArg);
1110 if (scarg)
1112 IPTR IconType = 0;
1114 scarg->scarg_xpos = dn->drgn_x;
1115 scarg->scarg_ypos = dn->drgn_y;
1117 scarg->scarg_DeltaX = dn->drgn_DeltaX;
1118 scarg->scarg_DeltaY = dn->drgn_DeltaY;
1120 GetAttr(IDTA_Type, dn->drgn_icon, &IconType);
1122 switch (IconType)
1124 case WBDISK:
1125 case WBKICK:
1126 //.disk
1127 scarg->scarg_icontype = WBDISK;
1129 scarg->scarg_lock = DiskInfoLock(dn->drgn_iconnode);
1130 if ((BPTR)NULL == scarg->scarg_lock)
1132 if (NULL == dn->drgn_iconnode->in_DeviceIcon->di_Volume)
1134 SCA_FreeNode((struct ScalosNodeList *) ArgList, &dn->drgn_Node);
1135 break;
1138 scarg->scarg_name = AllocCopyString(dn->drgn_iconnode->in_DeviceIcon->di_Device);
1140 else
1142 scarg->scarg_name = AllocCopyString(dn->drgn_iconnode->in_Name);
1144 GetAttr(IDTA_Extention, dn->drgn_icon, (APTR) &Extension);
1145 if (Extension)
1146 scarg->scarg_ext = AllocCopyString(Extension);
1148 d1(kprintf("%s/%s/%ld: scarg_name=<%s>\n", __FILE__, __FUNC__, __LINE__, scarg->scarg_name));
1149 break;
1151 case WBDRAWER:
1152 case WBGARBAGE:
1153 case WBDEVICE:
1154 //.drawer
1155 scarg->scarg_icontype = WBDRAWER;
1156 if (dn->drgn_iconnode->in_Lock)
1157 scarg->scarg_lock = DupLock(dn->drgn_iconnode->in_Lock);
1158 else
1159 scarg->scarg_lock = Lock("", ACCESS_READ);
1161 if ((BPTR)NULL == scarg->scarg_lock)
1163 SCA_FreeNode((struct ScalosNodeList *) ArgList, &dn->drgn_Node);
1164 break;
1167 scarg->scarg_name = AllocCopyString(GetIconName(dn->drgn_iconnode));
1169 GetAttr(IDTA_Extention, dn->drgn_icon, (APTR) &Extension);
1170 if (Extension)
1171 scarg->scarg_ext = AllocCopyString(Extension);
1172 break;
1174 case WBTOOL:
1175 case WBPROJECT:
1176 //.tool
1177 scarg->scarg_icontype = WBTOOL;
1178 if (dn->drgn_iconnode->in_Lock)
1179 scarg->scarg_lock = DupLock(dn->drgn_iconnode->in_Lock);
1180 else
1181 scarg->scarg_lock = Lock("", ACCESS_READ);
1183 if ((BPTR)NULL == scarg->scarg_lock)
1185 SCA_FreeNode((struct ScalosNodeList *) ArgList, &dn->drgn_Node);
1186 break;
1189 scarg->scarg_name = AllocCopyString(GetIconName(dn->drgn_iconnode));
1191 GetAttr(IDTA_Extention, dn->drgn_icon, (APTR) &Extension);
1192 if (Extension)
1193 scarg->scarg_ext = AllocCopyString(Extension);
1194 break;
1196 case WB_TEXTICON_TOOL:
1197 //.texttool
1198 scarg->scarg_icontype = WBTOOL;
1199 if (dn->drgn_iconnode->in_Lock)
1200 scarg->scarg_lock = DupLock(dn->drgn_iconnode->in_Lock);
1201 else
1202 scarg->scarg_lock = Lock("", ACCESS_READ);
1204 scarg->scarg_name = AllocCopyString(GetIconName(dn->drgn_iconnode));
1206 tempIconObj = NewIconObject(GetIconName(dn->drgn_iconnode), NULL);
1208 if (tempIconObj)
1210 GetAttr(IDTA_Extention, dn->drgn_icon, (APTR) &Extension);
1211 if (Extension)
1212 scarg->scarg_ext = AllocCopyString(Extension);
1214 DisposeIconObject(tempIconObj);
1216 break;
1218 case WB_TEXTICON_DRAWER:
1219 //.textdrawer
1220 scarg->scarg_icontype = WBDRAWER;
1221 if (dn->drgn_iconnode->in_Lock)
1222 scarg->scarg_lock = DupLock(dn->drgn_iconnode->in_Lock);
1223 else
1224 scarg->scarg_lock = Lock("", ACCESS_READ);
1226 scarg->scarg_name = AllocCopyString(GetIconName(dn->drgn_iconnode));
1228 tempIconObj = NewIconObject(GetIconName(dn->drgn_iconnode), NULL);
1230 if (tempIconObj)
1232 GetAttr(IDTA_Extention, dn->drgn_icon, (APTR) &Extension);
1233 if (Extension)
1234 scarg->scarg_ext = AllocCopyString(Extension);
1236 DisposeIconObject(tempIconObj);
1238 break;
1240 case WBAPPICON:
1241 SCA_FreeNode((struct ScalosNodeList *) ArgList, &dn->drgn_Node);
1242 break;
1244 default:
1245 SCA_FreeNode((struct ScalosNodeList *) ArgList, &dn->drgn_Node);
1246 break;
1253 void ClassSetDefaultIconFlags(struct ScaIconNode *in, BOOL IsDefIcon)
1255 IPTR UserFlags;
1257 GetAttr(IDTA_UserFlags, in->in_Icon, &UserFlags);
1259 if (IsDefIcon)
1261 d1(kprintf("%s/%s/%ld: in=<%s> supportFlags=%08lx\n", \
1262 __FILE__, __FUNC__, __LINE__, GetIconName(in), in->in_SupportFlags));
1264 UserFlags |= ICONOBJ_USERFLAGF_DefaultIcon;
1265 in->in_Flags |= INF_DefaultIcon;
1267 else
1269 UserFlags &= ~ICONOBJ_USERFLAGF_DefaultIcon;
1270 in->in_Flags &= ~INF_DefaultIcon;
1273 SetAttrs(in->in_Icon, IDTA_UserFlags, UserFlags, TAG_END);