forwarding build fix when MUIA_Scrollgroup_AutoBars is defined (NicJA).
[AROS-Contrib.git] / scalos / main / ScanDir.c
blobfaa2c242e25517ffb1fe47702b271bd75f84baad
1 // ScanDir.c
2 // $Date$
3 // $Revision$
5 #include <exec/types.h>
6 #include <intuition/classes.h>
7 #include <intuition/classusr.h>
8 #include <utility/hooks.h>
9 #include <intuition/gadgetclass.h>
10 #include <datatypes/pictureclass.h>
11 #include <dos/dos.h>
12 #include <dos/dostags.h>
13 #include <dos/exall.h>
15 #define __USE_SYSBASE
17 #include <proto/dos.h>
18 #include <proto/exec.h>
19 #include <proto/graphics.h>
20 #include <proto/intuition.h>
21 #include <proto/iconobject.h>
22 #include <proto/utility.h>
23 #include <proto/gadtools.h>
24 #include <proto/datatypes.h>
25 #include "debug.h"
26 #include <proto/scalos.h>
28 #include <clib/alib_protos.h>
30 #include <defs.h>
31 #include <datatypes/iconobject.h>
32 #include <scalos/GadgetBar.h>
33 #include <scalos/scalos.h>
35 #include <DefIcons.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <stdarg.h>
41 #include "scalos_structures.h"
42 #include "locale.h"
43 #include "functions.h"
44 #include "Variables.h"
46 //----------------------------------------------------------------------------
48 // local data definitions
50 #define ExAllBuffer_SIZE 10000 // Alloc size for rilc_ExAllBuffer
52 //----------------------------------------------------------------------------
54 // local functions
56 static enum ScanDirResult CheckCleanup(struct ReadIconListControl *rilc);
57 static enum ScanDirResult GenerateIcons(struct ReadIconListControl *rilc, BOOL Final);
58 static struct ScaIconNode *CreateDefaultIcon(struct ReadIconListControl *rilc, const struct ReadIconListData *rild,
59 struct ScaReadIconArg *ria, BOOL CheckForDuplicates);
60 static struct ScaIconNode *ScanDirInitIcon(struct ReadIconListControl *rilc, const struct ReadIconListData *rild,
61 struct ScaReadIconArg *ria, BOOL isDefIcon, BOOL isLink, Object *IconObj);
62 static struct ScaIconNode *ScanDirCreateIcon(struct ReadIconListControl *rilc,
63 const struct ReadIconListData *rild, struct ScaReadIconArg *ria);
64 static SAVEDS(LONG) CompareNameFunc(struct Hook *hook, struct ScaIconNode *in2,
65 struct ScaIconNode *in1);
66 static enum ScanDirResult BeginScan_ExAll(struct ReadIconListControl *rilc);
67 static enum ScanDirResult ScanDir_ExAll(struct ReadIconListControl *rilc);
68 static enum ScanDirResult BeginScan_Examine(struct ReadIconListControl *rilc);
69 static enum ScanDirResult ScanDir_Examine(struct ReadIconListControl *rilc);
70 //static LONG ReExamine(struct ReadIconListData *rild);
71 static struct IconScanEntry *NewIconScanEntry(struct internalScaWindowTask *iwt, const struct ReadIconListData *rild);
72 static void DisposeIconScanEntry(struct IconScanEntry *ise);
73 static void RilcDisposeData(void *data);
74 static void RilcDisposeKey(void *key);
75 static int RilcCompare(const void *data1, const void *data2);
76 static ULONG AdjustIconType(Object *IconObj, LONG DirEntryType, BOOL isLink);
77 static BOOL ScanDirFindIcon(struct ReadIconListControl *rilc, CONST_STRPTR IconName);
79 //----------------------------------------------------------------------------
81 // local data
83 static struct Hook CompareNameHook =
85 { NULL, NULL },
86 HOOKFUNC_DEF(CompareNameFunc), // h_Entry + h_SubEntry
87 NULL, // h_Data
90 //----------------------------------------------------------------------------
92 // public data items
94 //----------------------------------------------------------------------------
96 // Result : Success
97 /// IconWindowReadIcon
98 struct ScaIconNode *IconWindowReadIcon(struct internalScaWindowTask *iwt,
99 CONST_STRPTR Name, struct ScaReadIconArg *ria)
101 struct ReadIconListControl rilc;
102 struct ScaIconNode *in = NULL;
103 ULONG err;
104 T_ExamineData *fib = NULL;
105 BPTR oldDir = NOT_A_LOCK;
106 BPTR dirLock;
107 BOOL VolumeIsWritable;
108 BOOL ScanDirSemaphoreLocked = FALSE;
110 do {
111 struct ReadIconListData rild;
112 BPTR iLock;
114 d1(KPrintF("%s/%s/%ld: Name=<%s> ria=%08lx iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, Name, ria, iwt));
116 if (!RilcInit(&rilc, iwt))
117 break;
119 // Always ignore "disk.info" in root windows
120 if ((iwt->iwt_WindowTask.mt_WindowStruct->ws_Flags & WSV_FlagF_RootWindow)
121 && 0 == Stricmp(Name, "disk"))
122 break;
124 BackdropWait(iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock);
126 if (!AttemptSemaphoreNoNest(&iwt->iwt_ScanDirSemaphore))
127 break;
129 ScanDirSemaphoreLocked = TRUE;
131 if (!CurrentPrefs.pref_ShowThumbnailsAsDefault && (THUMBNAILS_AsDefault == iwt->iwt_ThumbnailMode))
133 if (!IsShowAllType(iwt->iwt_OldShowType))
135 if (0 != IsIconName(Name))
137 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
138 break; // Display thumbnail only if object has a icon
143 if (!ScalosExamineBegin(&fib))
145 d1(kprintf("%s/%s/%ld: ScalosExamineBegin failed\n", __FILE__, __FUNC__, __LINE__));
146 break;
149 if (ria && ria->ria_Lock)
150 dirLock = ria->ria_Lock;
151 else
152 dirLock = iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock;
154 debugLock_d1(dirLock);
155 if ((BPTR)NULL == dirLock)
156 break;
158 VolumeIsWritable = ClassIsDiskWritable(dirLock);
160 oldDir = CurrentDir(dirLock);
162 err = RETURN_OK;
163 iLock = Lock((STRPTR) Name, ACCESS_READ);
164 if (BNULL == iLock)
166 err = IoErr();
167 d1(kprintf("%s/%s/%ld: Lock returned %ld\n", __FILE__, __FUNC__, __LINE__, err));
169 else
171 if (!ScalosExamineLock(iLock, &fib))
172 err = IoErr();
173 UnLock(iLock);
175 d1(kprintf("%s/%s/%ld: ScalosExamineLock returned %ld\n", __FILE__, __FUNC__, __LINE__, err));
178 if (ERROR_OBJECT_IN_USE == err)
179 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_ScheduleUpdate);
181 rild.rild_SoloIcon = FALSE;
183 if (ERROR_OBJECT_NOT_FOUND == err)
185 // object doesn't exist - check if associated icon is there
186 BOOL iconExists = FALSE;
187 STRPTR iconName = AllocPathBuffer();
189 d1(kprintf("%s/%s/%ld: iconName=%08lx\n", __FILE__, __FUNC__, __LINE__, iconName));
191 if (iconName)
193 stccpy(iconName, Name, Max_PathLen);
194 SafeStrCat(iconName, ".info", Max_PathLen);
196 iLock = Lock(iconName, ACCESS_READ);
197 if (iLock)
199 rild.rild_SoloIcon = TRUE;
200 ScalosExamineLock(iLock, &fib);
201 iconExists = TRUE;
202 UnLock(iLock);
205 FreePathBuffer(iconName);
208 if (!iconExists)
210 break;
213 // switch back to original object name (w/o ".info")
214 stccpy(rild.rild_Name, Name, sizeof(rild.rild_Name));
216 else if (RETURN_OK != err)
218 stccpy(rild.rild_Name, Name, sizeof(rild.rild_Name));
220 else
222 stccpy(rild.rild_Name, ScalosExamineGetName(fib), sizeof(rild.rild_Name));
225 if (NULL == fib)
227 break;
230 stccpy(rild.rild_Comment, ScalosExamineGetComment(fib), sizeof(rild.rild_Comment));
231 rild.rild_OwnerUID = ScalosExamineGetDirUID(fib);
232 rild.rild_OwnerGID = ScalosExamineGetDirGID(fib);
233 rild.rild_Protection = ScalosExamineGetProtection(fib);
234 rild.rild_DateStamp = *ScalosExamineGetDate(fib);
235 rild.rild_DiskWriteProtected = iwt->iwt_ReadOnly;
236 rild.rild_CheckOverlap = TRUE;
238 if (IsFileHidden(rild.rild_Name, rild.rild_Protection))
240 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
241 break;
244 if (rild.rild_SoloIcon)
246 // icon without object
247 rild.rild_Type = 0; // type of object is undefined
248 rild.rild_Size64 = MakeU64(0);
250 else
252 if ((RETURN_OK != err) && (ERROR_OBJECT_NOT_FOUND == err))
253 rild.rild_Type = MAKE_ID('E','R','R','O');
254 else
255 rild.rild_Type = ScalosExamineGetDirEntryType(fib);
256 rild.rild_Size64 = ScalosExamineGetSize(fib);
258 d1(kprintf("%s/%s/%ld: rild_Type=%ld\n", __FILE__, __FUNC__, __LINE__, rild.rild_Type));
261 // ReExamine(&rild);
263 d1(kprintf("%s/%s/%ld: rild_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, rild.rild_Name));
265 // this might be a softlink?
266 if (IsSoftLink(Name))
268 stccpy(rild.rild_Name, Name, sizeof(rild.rild_Name));
269 rild.rild_Type = ST_SOFTLINK;
270 d1(kprintf("%s/%s/%ld: ST_SOFTLINK rild_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, rild.rild_Name));
273 in = ScanDirCreateIcon(&rilc, &rild, ria);
275 d1(KPrintF("%s/%s/%ld: in=%08lx\n", __FILE__, __FUNC__, __LINE__, in));
277 if (NULL == in)
279 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_CleanUp);
280 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_SetVirtSize,
281 SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider);
283 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
285 break;
288 d1(KPrintF("%s/%s/%ld: ViewByType\n", __FILE__, __FUNC__, __LINE__));
290 SetIconSupportsFlags(in, VolumeIsWritable);
292 if (ria && ria->ria_Lock && ((BPTR)NULL == iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock))
294 in->in_Lock = DupLock(ria->ria_Lock);
295 CreateSbiForIcon(in);
298 // in_Lock must be valid for SCCM_IconWin_GetIconFileType
299 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_GetIconFileType, in);
301 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_CleanUp);
302 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_SetVirtSize,
303 SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider);
305 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
306 } while (0);
308 RilcCleanup(&rilc);
310 if (ScanDirSemaphoreLocked)
311 ScalosReleaseSemaphore(&iwt->iwt_ScanDirSemaphore);
313 if (in)
315 d1({ \
316 ULONG TextStyle = 0; \
318 GetAttr(IDTA_TextStyle, in->in_Icon, &TextStyle); \
319 d1(KPrintF("%s/%s/%ld: TextStyle=%ld\n", __FILE__, __FUNC__, __LINE__, TextStyle)); \
322 GenerateThumbnails(iwt);
325 if (IS_VALID_LOCK(oldDir))
326 CurrentDir(oldDir);
327 ScalosExamineEnd(&fib);
329 d1(KPrintF("%s/%s/%ld: in=%08lx\n", __FILE__, __FUNC__, __LINE__, in));
331 return in;
335 /// SetIconName
336 void SetIconName(Object *IconObj, struct ScaIconNode *in)
338 STRPTR IconName;
340 in->in_Name = (STRPTR) "";
342 GetAttr(DTA_Name, IconObj, (APTR) &IconName);
343 if (IconName && *IconName)
344 in->in_Name = IconName;
348 /// IsNoIconPosition
349 BOOL IsNoIconPosition(const struct ExtGadget *gg)
351 return (BOOL) ((UWORD) NO_ICON_POSITION_SHORT == (UWORD) gg->LeftEdge);
355 /// ReadIconList
356 // Result :
357 // ==0 Success
358 // !=0 Failure
359 enum ScanDirResult ReadIconList(struct internalScaWindowTask *iwt)
361 struct ReadIconListControl rilc;
362 enum ScanDirResult sdResult;
363 BOOL UpdateSemaphoreLocked = FALSE;
364 BOOL ScanDirSemaphoreLocked = FALSE;
365 enum ScanDirResult Result = SCANDIR_OK;
367 d1(KPrintF("\n" "%s/%s/%ld: START iwt=%08lx ws=%08lx\n", \
368 __FILE__, __FUNC__, __LINE__, iwt, iwt->iwt_WindowTask.mt_WindowStruct));
370 TIMESTAMP_d1();
371 TIMESTAMPCOUNT_RESET_d1(iwt);
372 TIMESTAMPCOUNT_START_d1(iwt, 0);
374 do {
375 struct ScaIconNode *in;
377 if (!RilcInit(&rilc, iwt))
378 break;
380 FlushThumbnailEntries(iwt);
382 rilc.rilc_OrigViewByType = iwt->iwt_WindowTask.mt_WindowStruct->ws_Viewmodes;
383 rilc.rilc_TotalFound = 0;
385 if (!AttemptSemaphoreNoNest(&iwt->iwt_UpdateSemaphore))
387 d1(kprintf("%s/%s/%ld: AttemptSemaphoreNoNest(iwt_UpdateSemaphore) failed\n", __FILE__, __FUNC__, __LINE__));
388 break;
391 UpdateSemaphoreLocked = TRUE;
393 if (!AttemptSemaphoreNoNest(&iwt->iwt_ScanDirSemaphore))
395 d1(kprintf("%s/%s/%ld: AttemptSemaphoreNoNest(iwt_ScanDirSemaphore) failed\n", __FILE__, __FUNC__, __LINE__));
396 break;
399 ScanDirSemaphoreLocked = TRUE;
401 d1(kprintf("%s/%s/%ld: UpdateSemaphore=%08lx NestCount=%ld\n", \
402 __FILE__, __FUNC__, __LINE__, &iwt->iwt_UpdateSemaphore, iwt->iwt_UpdateSemaphore.Sema.ss_NestCount));
404 iwt->iwt_AbortScanDir = FALSE;
406 ScalosLockIconListExclusive(iwt);
407 FreeIconList(iwt, &iwt->iwt_WindowTask.wt_LateIconList);
408 ScalosUnLockIconList(iwt);
410 ScanDirUpdateStatusBarText(iwt, 0);
412 BackdropWait(iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock);
414 // Add currently present icons to rilc_IconTree
415 // to allow for correct check for duplicates
416 ScalosLockIconListShared(iwt);
417 for (in=iwt->iwt_WindowTask.wt_IconList; in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
419 BTreeInsert(rilc.rilc_IconTree,
420 GetIconName(in),
421 in);
423 ScalosUnLockIconList(iwt);
425 if (iwt->iwt_WindowTask.wt_Window)
427 SetABPenDrMd(iwt->iwt_WindowTask.wt_Window->RPort, FontPrefs.fprf_FontFrontPen,
428 FontPrefs.fprf_FontBackPen, FontPrefs.fprf_TextDrawMode);
431 TIMESTAMP_d1();
433 sdResult = GetFileList(&rilc, CheckCleanup, CurrentPrefs.pref_UseExAll, FALSE, iwt->iwt_CheckOverlappingIcons);
435 d1(KPrintF("%s/%s/%ld: sdResult=%ld\n", __FILE__, __FUNC__, __LINE__, sdResult));
437 switch (sdResult)
439 case SCANDIR_VIEWMODE_CHANGE:
440 case SCANDIR_FINISHED:
441 case SCANDIR_ABORT:
442 Result = SCANDIR_OK; // Success
443 break;
444 default: // Failure
445 d1(kprintf("%s/%s/%ld: sdResult=%ld\n", __FILE__, __FUNC__, __LINE__, sdResult));
446 Result = sdResult;
447 break;
450 d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
451 d1(KPrintF("%s/%s/%ld: ws_Viewmodes=%ld\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_WindowTask.mt_WindowStruct->ws_Viewmodes));
452 TIMESTAMP_d1();
454 if (rilc.rilc_OrigViewByType == iwt->iwt_WindowTask.mt_WindowStruct->ws_Viewmodes)
456 d1(kprintf("%s/%s/%ld: LateIconList=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_WindowTask.wt_LateIconList));
458 ScanDirUpdateStatusBarText(iwt, rilc.rilc_TotalFound);
460 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
462 Result = sdResult = GenerateIcons(&rilc, TRUE);
464 d1(KPrintF("%s/%s/%ld: sdResult=%ld\n", __FILE__, __FUNC__, __LINE__, sdResult));
466 if (!ScanDirIsError(sdResult) && iwt->iwt_WindowTask.wt_Window)
468 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
470 SCA_SortNodes((struct ScalosNodeList *) &iwt->iwt_WindowTask.wt_LateIconList, &CompareNameHook, SCA_SortType_Best);
472 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
474 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_CleanUp);
475 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
476 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_SetVirtSize,
477 SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider);
478 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
481 TIMESTAMP_d1();
482 d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
483 } while (0);
485 RilcCleanup(&rilc);
487 if (ScanDirSemaphoreLocked)
488 ScalosReleaseSemaphore(&iwt->iwt_ScanDirSemaphore);
489 if (UpdateSemaphoreLocked)
490 ScalosReleaseSemaphore(&iwt->iwt_UpdateSemaphore);
492 TIMESTAMP_d1();
494 if (rilc.rilc_OrigViewByType != iwt->iwt_WindowTask.mt_WindowStruct->ws_Viewmodes)
495 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_Update);
497 d1(KPrintF("%s/%s/%ld: END iwt=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, iwt, iwt->iwt_WinTitle));
499 TIMESTAMP_d1();
501 if (SCANDIR_OK == Result && !iwt->iwt_CloseWindow && !iwt->iwt_AbortScanDir && (THUMBNAILS_Never != iwt->iwt_ThumbnailMode))
502 GenerateThumbnails(iwt);
504 TIMESTAMP_d1();
505 TIMESTAMPCOUNT_END_d1(iwt, 0);
506 TIMESTATS_d1(iwt);
508 d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
510 return Result;
514 /// BeginScan_ExAll
515 static enum ScanDirResult BeginScan_ExAll(struct ReadIconListControl *rilc)
517 rilc->rilc_exallControl = AllocDosObject(DOS_EXALLCONTROL, NULL);
518 if (NULL == rilc->rilc_exallControl)
520 d1(KPrintF("%s/%s/%ld: AllocDosObject(DOS_EXALLCONTROL) failed\n", __FILE__, __FUNC__, __LINE__));
521 return SCANDIR_FAIL_ABORT;
524 rilc->rilc_exallControl->eac_MatchFunc = NULL;
526 rilc->rilc_replyPort = CreateMsgPort();
527 if (NULL == rilc->rilc_replyPort)
529 d1(kprintf("%s/%s/%ld: CreateMsgPort() failed\n", __FILE__, __FUNC__, __LINE__));
530 return SCANDIR_FAIL_ABORT;
533 rilc->rilc_FileSysPort = GetFileSysTask();
535 if (NULL == rilc->rilc_FileSysPort)
537 d1(kprintf("%s/%s/%ld: GetFileSysTask() failed\n", __FILE__, __FUNC__, __LINE__));
538 return SCANDIR_FAIL_ABORT;
541 d1(kprintf("%s/%s/%ld: FileSysTask=%08lx\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_FileSysPort));
542 d1(kprintf("%s/%s/%ld: Lock Port=%08lx\n", __FILE__, __FUNC__, __LINE__, ((struct FileLock *)BADDR(rilc->rilc_dirLock))->fl_Task));
544 rilc->rilc_pkt = AllocDosObject(DOS_STDPKT, NULL);
545 if (NULL == rilc->rilc_pkt)
547 d1(kprintf("%s/%s/%ld: AllocDosObject(DOS_STDPKT) failed\n", __FILE__, __FUNC__, __LINE__));
548 return SCANDIR_FAIL_ABORT;
551 rilc->rilc_pkt->dp_Type = ACTION_EXAMINE_ALL;
552 rilc->rilc_pkt->dp_Arg1 = (SIPTR) rilc->rilc_dirLock;
553 rilc->rilc_pkt->dp_Arg2 = (IPTR) rilc->rilc_ExAllBuffer; // Buffer to store results
554 rilc->rilc_pkt->dp_Arg3 = ExAllBuffer_SIZE; // Length (in bytes) of buffer (ARG2)
555 rilc->rilc_pkt->dp_Arg4 = rilc->rilc_ExAllType; // Type of request
556 rilc->rilc_pkt->dp_Arg5 = (IPTR) rilc->rilc_exallControl; // Control structure to store state information.
558 rilc->rilc_PacketPending = TRUE;
559 SendPkt(rilc->rilc_pkt, rilc->rilc_FileSysPort, rilc->rilc_replyPort);
561 rilc->rilc_ExNextOk = FALSE;
563 return SCANDIR_OK;
567 /// ScanDir_ExAll
568 static enum ScanDirResult ScanDir_ExAll(struct ReadIconListControl *rilc)
570 struct internalScaWindowTask *iwt = rilc->rilc_WindowTask;
571 struct StandardPacket *replyPkt;
572 struct ExAllData *ead = rilc->rilc_edNext;
574 d1(kprintf("%s/%s/%ld: START edNext=%08lx\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_edNext));
576 if (NULL == rilc->rilc_edNext)
578 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
579 WaitPort(rilc->rilc_replyPort);
580 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
581 replyPkt = (struct StandardPacket *) GetMsg(rilc->rilc_replyPort);
583 if (NULL == replyPkt)
584 return SCANDIR_OK;
586 rilc->rilc_PacketPending = FALSE;
587 rilc->rilc_FlagFinished = FALSE;
589 d1(KPrintF("%s/%s/%ld: Entries=%ld Res1=%ld Res2=%ld\n", __FILE__, __FUNC__, __LINE__, \
590 rilc->rilc_exallControl->eac_Entries, \
591 replyPkt->sp_Pkt.dp_Res1, replyPkt->sp_Pkt.dp_Res2));
593 if (!replyPkt->sp_Pkt.dp_Res1)
595 switch (replyPkt->sp_Pkt.dp_Res2)
597 case ERROR_BAD_NUMBER:
598 return SCANDIR_EXALL_BADNUMBER;
599 break;
600 case ERROR_ACTION_NOT_KNOWN:
601 return SCANDIR_EXALL_FAIL;
602 break;
603 case ERROR_NO_MORE_ENTRIES:
604 rilc->rilc_FlagFinished = TRUE;
605 break;
606 default:
607 d1(kprintf("%s/%s/%ld: Result2=%ld\n", __FILE__, __FUNC__, __LINE__, replyPkt->sp_Pkt.dp_Res2));
608 return SCANDIR_FAIL_ABORT;
609 break;
613 ead = (struct ExAllData *) rilc->rilc_ExAllBuffer;
614 rilc->rilc_edNext = ead->ed_Next;
616 d1(kprintf("%s/%s/%ld: edNext=%08lx\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_edNext));
619 d1(kprintf("%s/%s/%ld: Finished=%ld Entries=%ld\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_FlagFinished, \
620 rilc->rilc_exallControl->eac_Entries));
622 if (rilc->rilc_exallControl->eac_Entries)
624 struct IconScanEntry *ise;
626 rilc->rilc_edNext = ead->ed_Next;
628 d1(KPrintF("%s/%s/%ld: edNext=%08lx\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_edNext));
630 rilc->rilc_rd.rild_SoloIcon = FALSE;
632 // !! be sure to copy the results from ead BEFORE starting next scan !!
633 rilc->rilc_rd.rild_Type = ead->ed_Type;
634 rilc->rilc_rd.rild_Protection = ead->ed_Prot;
635 rilc->rilc_rd.rild_Size64 = ScalosExAllSize64(ead, rilc->rilc_ExAllType);
637 rilc->rilc_rd.rild_DateStamp.ds_Days = ead->ed_Days;
638 rilc->rilc_rd.rild_DateStamp.ds_Minute = ead->ed_Mins;
639 rilc->rilc_rd.rild_DateStamp.ds_Tick = ead->ed_Ticks;
641 rilc->rilc_rd.rild_SoloIcon = FALSE;
643 stccpy(rilc->rilc_rd.rild_Name, ead->ed_Name, sizeof(rilc->rilc_rd.rild_Name));
645 d1(KPrintF("%s/%s/%ld: <%s> ed_Comment=<%s>\n", \
646 __FILE__, __FUNC__, __LINE__, ead->ed_Name, ead->ed_Comment));
648 if (rilc->rilc_ExAllType >= ED_COMMENT && ead->ed_Comment)
649 stccpy(rilc->rilc_rd.rild_Comment, ead->ed_Comment, sizeof(rilc->rilc_rd.rild_Comment));
650 else
651 strcpy(rilc->rilc_rd.rild_Comment, "");
653 if (rilc->rilc_ExAllType >= ED_OWNER)
655 rilc->rilc_rd.rild_OwnerUID = ead->ed_OwnerUID;
656 rilc->rilc_rd.rild_OwnerUID = ead->ed_OwnerGID;
658 else
660 rilc->rilc_rd.rild_OwnerUID = 0;
661 rilc->rilc_rd.rild_OwnerUID = 0;
664 if (NULL == rilc->rilc_edNext && !rilc->rilc_FlagFinished)
666 // Start scanning for next entries - only if last call didn't return ERROR_NO_MORE_ENTRIES
667 rilc->rilc_PacketPending = TRUE;
668 SendPkt(rilc->rilc_pkt, rilc->rilc_FileSysPort, rilc->rilc_replyPort);
670 rilc->rilc_edNext = NULL;
673 d1(KPrintF("%s/%s/%ld: Name=<%s> Type=%ld Prot=%08lx\n", __FILE__, __FUNC__, __LINE__, \
674 rilc->rilc_rd.rild_Name, ead->ed_Type, ead->ed_Prot));
675 d1(KPrintF("%s/%s/%ld: rild_Size64=%08lx-%08lx\n", __FILE__, __FUNC__, __LINE__, \
676 ULONG64_HIGH(rilc->rilc_rd.rild_Size64), ULONG64_LOW(rilc->rilc_rd.rild_Size64)));
678 ise = NewIconScanEntry(iwt, &rilc->rilc_rd);
679 if (ise)
681 if (ise->ise_Flags & ISEFLG_IsIcon)
683 AddTail(&rilc->rilc_UnlinkedIconScanList, &ise->ise_Node);
685 else
687 AddTail(&rilc->rilc_NonIconScanList, &ise->ise_Node);
688 d1(KPrintF("%s/%s/%ld: key=<%s> ise=%08lx\n", __FILE__, __FUNC__, __LINE__, ise->ise_Fib.fib_FileName, ise));
689 BTreeInsert(rilc->rilc_StdFilesTree,
690 ise->ise_Fib.fib_FileName,
691 ise);
694 rilc->rilc_TotalFound++;
697 if (rilc->rilc_Check)
699 enum ScanDirResult sdResult;
701 sdResult = (*rilc->rilc_Check)(rilc);
702 if (SCANDIR_OK != sdResult)
703 return sdResult;
706 else
707 return SCANDIR_FINISHED;
709 d1(kprintf("%s/%s/%ld: Finished=%ld edNext=%08lx\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_FlagFinished, \
710 rilc->rilc_edNext));
712 // Stop if last entry of last ExAllData has been read
713 if (rilc->rilc_FlagFinished && (NULL == rilc->rilc_edNext))
714 return SCANDIR_FINISHED;
716 return SCANDIR_OK;
720 /// BeginScan_Examine
721 static enum ScanDirResult BeginScan_Examine(struct ReadIconListControl *rilc)
723 d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
725 if (!ScalosExamineDirBegin(rilc->rilc_dirLock, &rilc->rilc_DirHandle))
726 return SCANDIR_FAIL_ABORT;
728 rilc->rilc_replyPort = CreateMsgPort();
729 if (NULL == rilc->rilc_replyPort)
730 return SCANDIR_FAIL_ABORT;
732 rilc->rilc_FileSysPort = GetFileSysTask();
733 if (NULL == rilc->rilc_FileSysPort)
734 return SCANDIR_FAIL_ABORT;
736 rilc->rilc_FlagLargeFileSupported = ScalosSupportsExamineDir(rilc->rilc_FileSysPort,
737 rilc->rilc_dirLock, &rilc->rilc_DirHandle);
739 d1(KPrintF("%s/%s/%ld: rilc_FlagLargeFileSupported=%ld\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_FlagLargeFileSupported));
741 rilc->rilc_pkt = AllocDosObject(DOS_STDPKT, NULL);
742 if (NULL == rilc->rilc_pkt)
743 return SCANDIR_FAIL_ABORT;
745 if (rilc->rilc_FlagLargeFileSupported)
747 d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
748 ScalosDosPacketExamineDir(rilc->rilc_pkt, rilc->rilc_dirLock, &rilc->rilc_DirHandle);
749 d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
751 else
753 LONG rc;
755 d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
757 rilc->rilc_Fib = AllocDosObject(DOS_FIB, NULL);
758 if (NULL == rilc->rilc_Fib)
759 return SCANDIR_FAIL_ABORT;
761 rc = DoPkt2(rilc->rilc_FileSysPort,
762 ACTION_EXAMINE_OBJECT,
763 (SIPTR) rilc->rilc_dirLock,
764 (SIPTR) MKBADDR(rilc->rilc_Fib));
765 if (!rc)
766 return SCANDIR_FAIL_ABORT;
768 rilc->rilc_pkt->dp_Type = ACTION_EXAMINE_NEXT;
769 rilc->rilc_pkt->dp_Arg1 = (SIPTR) rilc->rilc_dirLock;
770 rilc->rilc_pkt->dp_Arg2 = (SIPTR) MKBADDR(rilc->rilc_Fib);
772 d1(KPrintF("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
775 rilc->rilc_PacketPending = TRUE;
776 SendPkt(rilc->rilc_pkt, rilc->rilc_FileSysPort, rilc->rilc_replyPort);
778 d1(KPrintF("%s/%s/%ld: END(SCANDIR_OK)\n", __FILE__, __FUNC__, __LINE__));
780 return SCANDIR_OK;
784 /// BeginScan_Examine
785 static enum ScanDirResult ScanDir_Examine(struct ReadIconListControl *rilc)
787 struct internalScaWindowTask *iwt = rilc->rilc_WindowTask;
788 struct IconScanEntry *ise;
789 struct StandardPacket *replyPkt;
790 T_ExamineData *exd;
791 CONST_STRPTR Filename;
792 CONST_STRPTR Comment;
793 size_t len;
795 d1(kprintf("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
797 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
798 WaitPort(rilc->rilc_replyPort);
799 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
800 replyPkt = (struct StandardPacket *) GetMsg(rilc->rilc_replyPort);
801 if (NULL == replyPkt)
802 return SCANDIR_OK;
804 rilc->rilc_PacketPending = FALSE;
806 d1(kprintf("%s/%s/%ld: Res1=%ld\n", __FILE__, __FUNC__, __LINE__, replyPkt->sp_Pkt.dp_Res1));
808 if (!replyPkt->sp_Pkt.dp_Res1)
810 d1(kprintf("%s/%s/%ld: Res2=%ld\n", __FILE__, __FUNC__, __LINE__, replyPkt->sp_Pkt.dp_Res2));
812 switch (replyPkt->sp_Pkt.dp_Res2)
814 case ERROR_NO_MORE_ENTRIES:
815 return SCANDIR_FINISHED;
816 break;
817 default:
818 return SCANDIR_FAIL_ABORT;
819 break;
823 if (rilc->rilc_FlagLargeFileSupported)
825 if (!ScalosDosPacketExamineDirResult(replyPkt, &exd, &rilc->rilc_DirHandle))
826 return SCANDIR_FAIL_ABORT;
828 d1(kprintf("%s/%s/%ld: exd=%08lx\n", __FILE__, __FUNC__, __LINE__, exd));
830 rilc->rilc_rd.rild_Type = ScalosExamineGetDirEntryType(exd);
831 rilc->rilc_rd.rild_Protection = ScalosExamineGetProtection(exd);
832 rilc->rilc_rd.rild_Size64 = ScalosExamineGetSize(exd);
833 rilc->rilc_rd.rild_DateStamp = *ScalosExamineGetDate(exd);
834 rilc->rilc_rd.rild_SoloIcon = FALSE;
835 Filename = ScalosExamineGetName(exd);
836 Comment = ScalosExamineGetComment(exd);
838 else
840 rilc->rilc_rd.rild_Type = rilc->rilc_Fib->fib_DirEntryType;
841 rilc->rilc_rd.rild_Protection = rilc->rilc_Fib->fib_Protection;
842 rilc->rilc_rd.rild_Size64 = MakeU64(rilc->rilc_Fib->fib_Size);
843 rilc->rilc_rd.rild_DateStamp = rilc->rilc_Fib->fib_Date;
844 rilc->rilc_rd.rild_SoloIcon = FALSE;
845 Filename = rilc->rilc_Fib->fib_FileName;
846 Comment = rilc->rilc_Fib->fib_Comment;
849 // when using Dos Packet interface,
850 // fib_FileName is NOT 0-terminated and is preceded by length byte.
852 len = (size_t) Filename[0];
853 if (len >= sizeof(rilc->rilc_rd.rild_Name))
854 len = sizeof(rilc->rilc_rd.rild_Name) - 1;
856 strncpy(rilc->rilc_rd.rild_Name, &Filename[1], len);
857 rilc->rilc_rd.rild_Name[len] = 0;
859 d1(kprintf("%s/%s/%ld: fib_Filename=%02lx %02lx %02lx %02lx %02lx %02lx %02lx %02lx\n", __FILE__, __FUNC__, __LINE__, \
860 Filename[0], Filename[1], \
861 Filename[2], Filename[3], \
862 Filename[4], Filename[5], \
863 Filename[6], Filename[7] ));
865 d1(kprintf("%s/%s/%ld: Name=<%s> Type=%ld Prot=%08lx\n", __FILE__, __FUNC__, __LINE__, \
866 rilc->rilc_rd.rild_Name, rilc->rilc_rd.rild_Type, rilc->rilc_rd.rild_Protection));
868 len = (size_t) Comment[0];
869 if (len >= sizeof(rilc->rilc_rd.rild_Comment))
870 len = sizeof(rilc->rilc_rd.rild_Comment) - 1;
872 strncpy(rilc->rilc_rd.rild_Comment, &Comment[1], len);
873 rilc->rilc_rd.rild_Comment[len] = 0;
876 rilc->rilc_PacketPending = TRUE;
877 SendPkt(rilc->rilc_pkt, rilc->rilc_FileSysPort, rilc->rilc_replyPort);
879 ise = NewIconScanEntry(iwt, &rilc->rilc_rd);
880 if (ise)
882 if (ise->ise_Flags & ISEFLG_IsIcon)
884 AddTail(&rilc->rilc_UnlinkedIconScanList, &ise->ise_Node);
886 else
888 AddTail(&rilc->rilc_NonIconScanList, &ise->ise_Node);
889 d1(KPrintF("%s/%s/%ld: key=<%s> ise=%08lx\n", __FILE__, __FUNC__, __LINE__, ise->ise_Fib.fib_FileName, ise));
890 BTreeInsert(rilc->rilc_StdFilesTree,
891 ise->ise_Fib.fib_FileName,
892 ise);
895 rilc->rilc_TotalFound++;
898 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
900 if (rilc->rilc_Check)
901 return (*rilc->rilc_Check)(rilc);
903 return SCANDIR_OK;
907 /// ScanDirIsBackDropIcon
908 BOOL ScanDirIsBackDropIcon(struct internalScaWindowTask *iwt, struct BackDropList *bdl,
909 BPTR fLock, CONST_STRPTR FileName)
911 struct ScaWindowStruct *wsMain = iInfos.xii_iinfos.ii_MainWindowStruct;
913 if ((BPTR)NULL == fLock)
914 return FALSE;
915 if (NULL == wsMain)
916 return FALSE;
918 if (wsMain != iwt->iwt_WindowTask.mt_WindowStruct)
920 struct internalScaWindowTask *iwtMain = (struct internalScaWindowTask *) wsMain->ws_WindowTask;
921 struct ScaIconNode *inx;
923 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
924 inx = FindBackdropIcon(fLock, FileName);
926 if (inx)
928 d1(kprintf("%s/%s/%ld: iwtMain=%08lx inx=%08lx\n", __FILE__, __FUNC__, __LINE__, iwtMain, inx));
929 ScalosUnLockIconList(iwtMain);
930 return TRUE;
932 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
935 return FALSE;
939 /// ScanDirInitIcon
940 static struct ScaIconNode *ScanDirInitIcon(struct ReadIconListControl *rilc, const struct ReadIconListData *rild,
941 struct ScaReadIconArg *ria, BOOL isDefIcon, BOOL isLink, Object *IconObj)
943 struct internalScaWindowTask *iwt = rilc->rilc_WindowTask;
944 BPTR currentDirLock;
945 struct ExtGadget *gg = (struct ExtGadget *) IconObj;
946 struct ScaIconNode *in;
947 IPTR IconType;
948 STRPTR tt;
949 BOOL FreePosition;
951 if ('\0' == *rild->rild_Name)
952 return NULL;
954 TIMESTAMPCOUNT_START_d1(iwt, 9);
956 d1(KPrintF("%s/%s/%ld: iwt=%08lx ws=%08lx rild_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, \
957 iwt, iwt->iwt_WindowTask.mt_WindowStruct, rild->rild_Name));
959 d1(KPrintF("%s/%s/%ld: <%s> Type=%08lx\n", __FILE__, __FUNC__, __LINE__, rild->rild_Name, rild->rild_Type));
961 if (NULL == IconObj)
963 TIMESTAMPCOUNT_END_d1(iwt, 9);
964 return NULL;
967 IconType = AdjustIconType(IconObj, rild->rild_Type, isLink);
968 d1(KPrintF("%s/%s/%ld: IconType=%ld\n", __FILE__, __FUNC__, __LINE__, IconType));
970 if (WBDISK == IconType)
972 d1(KPrintF("%s/%s/%ld: IconType=%ld\n", __FILE__, __FUNC__, __LINE__, IconType));
973 DisposeIconObject(IconObj);
974 TIMESTAMPCOUNT_END_d1(iwt, 9);
975 return NULL;
978 currentDirLock = CurrentDir((BPTR)NULL);
979 CurrentDir(currentDirLock);
981 if (ScanDirIsBackDropIcon(iwt, &rilc->rilc_BackdropList, currentDirLock, rild->rild_Name))
983 DisposeIconObject(IconObj);
984 TIMESTAMPCOUNT_END_d1(iwt, 9);
985 return NULL;
988 d1(KPrintF("%s/%s/%ld: iwt_ThumbnailMode=%ld\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_ThumbnailMode));
990 TIMESTAMPCOUNT_START_d1(iwt, 11);
991 if ((THUMBNAILS_Always == iwt->iwt_ThumbnailMode)
992 || (isDefIcon && THUMBNAILS_AsDefault == iwt->iwt_ThumbnailMode))
994 if (!AddThumbnailIcon(iwt, IconObj, currentDirLock, rild->rild_Name, 0, NULL)
995 && isDefIcon && !IsShowAllType(iwt->iwt_OldShowType))
997 // fail with default icons w/o thumbnails
998 // in "show only icons" windows
999 DisposeIconObject(IconObj);
1000 TIMESTAMPCOUNT_END_d1(iwt, 11);
1001 return NULL;
1004 TIMESTAMPCOUNT_END_d1(iwt, 11);
1006 TIMESTAMPCOUNT_START_d1(iwt, 19);
1007 FreePosition = IsNoIconPosition(gg);
1009 if (ria)
1011 gg->LeftEdge = ria->ria_x;
1012 gg->TopEdge = ria->ria_y;
1015 tt = NULL;
1016 if (DoMethod(IconObj, IDTM_FindToolType, "SCALOS_NOTEXT", &tt))
1018 SetAttrs(IconObj,
1019 IDTA_Text, NULL,
1020 TAG_END);
1022 TIMESTAMPCOUNT_END_d1(iwt, 19);
1024 d1(KPrintF("%s/%s/%ld: Left=%ld Top=%ld\n", __FILE__, __FUNC__, __LINE__, gg->LeftEdge, gg->TopEdge));
1025 d1(KPrintF("%s/%s/%ld: mt_MainObject=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_WindowTask.mt_MainObject));
1027 TIMESTAMPCOUNT_START_d1(iwt, 8);
1028 if (iwt->iwt_WindowTask.mt_MainObject)
1030 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_LayoutIcon,
1031 IconObj, IOLAYOUTF_NormalImage);
1033 TIMESTAMPCOUNT_END_d1(iwt, 8);
1035 ScalosLockIconListExclusive(iwt);
1037 TIMESTAMPCOUNT_START_d1(iwt, 17);
1038 if (IsNoIconPosition(gg))
1039 in = SCA_AllocIconNode(&iwt->iwt_WindowTask.wt_LateIconList);
1040 else
1041 in = SCA_AllocIconNode(&iwt->iwt_WindowTask.wt_IconList);
1042 TIMESTAMPCOUNT_END_d1(iwt, 17);
1044 d1(KPrintF("%s/%s/%ld: ScaIconNode=%08lx\n", __FILE__, __FUNC__, __LINE__, in));
1046 if (in)
1048 TIMESTAMPCOUNT_START_d1(iwt, 18);
1050 SetIconName(IconObj, in);
1052 BTreeInsert(rilc->rilc_IconTree,
1053 GetIconName(in),
1054 in);
1056 in->in_Icon = IconObj;
1057 in->in_FileType = (struct TypeNode *) IconType;
1059 in->in_SupportFlags = INF_SupportsOpen | INF_SupportsCopy |
1060 INF_SupportsSnapshot |
1061 INF_SupportsInformation | INF_SupportsLeaveOut;
1063 if (FreePosition)
1065 in->in_Flags |= INF_FreeIconPosition;
1067 else
1069 in->in_SupportFlags |= INF_SupportsUnSnapshot;
1072 TIMESTAMPCOUNT_START_d1(iwt, 15);
1073 if (!rild->rild_DiskWriteProtected)
1075 if (IsPermanentBackDropIcon(iwt, &rilc->rilc_BackdropList, currentDirLock, rild->rild_Name) )
1077 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1078 in->in_SupportFlags |= INF_SupportsPutAway;
1079 in->in_SupportFlags &= ~INF_SupportsLeaveOut;
1081 SetAttrs(IconObj,
1082 IDTA_OverlayType, ICONOVERLAYF_LeftOut,
1083 TAG_END);
1085 else
1087 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1088 in->in_SupportFlags &= ~INF_SupportsPutAway;
1089 in->in_SupportFlags |= INF_SupportsLeaveOut;
1092 TIMESTAMPCOUNT_END_d1(iwt, 15);
1094 if (!(rild->rild_Protection & FIBF_DELETE))
1095 in->in_SupportFlags |= INF_SupportsDelete;
1096 if (!(rild->rild_Protection & FIBF_WRITE))
1097 in->in_SupportFlags |= INF_SupportsRename;
1099 in->in_FileDateStamp = rild->rild_DateStamp;
1100 in->in_FileSize = ULONG64_LOW(rild->rild_Size64);
1102 DateStamp(&in->in_DateStamp);
1104 d1(KPrintF("%s/%s/%ld: <%s> Protection=%08lx SupportFlags=%08lx\n", \
1105 __FILE__, __FUNC__, __LINE__, rild->rild_Name, rild->rild_Protection, in->in_SupportFlags));
1106 d1(KPrintF("%s/%s/%ld: LeftEdge=%ld\n", __FILE__, __FUNC__, __LINE__, gg->LeftEdge));
1108 if (WBTOOL == IconType || WBPROJECT == IconType)
1110 in->in_Flags |= INF_File;
1113 tt = NULL;
1114 if (DoMethod(IconObj, IDTM_FindToolType, "SCALOS_NODRAG", &tt))
1115 in->in_Flags |= INF_Sticky;
1116 if (isDefIcon)
1118 TIMESTAMPCOUNT_START_d1(iwt, 16);
1119 ClassSetDefaultIconFlags(in, TRUE);
1120 TIMESTAMPCOUNT_END_d1(iwt, 16);
1123 if (rild->rild_DiskWriteProtected)
1125 in->in_Flags |= INF_VolumeWriteProtected;
1127 ScalosUnLockIconList(iwt);
1129 d1(KPrintF("%s/%s/%ld: LeftEdge=%ld TopEdge=%ld\n", __FILE__, __FUNC__, __LINE__, gg->LeftEdge, gg->TopEdge));
1131 TIMESTAMPCOUNT_START_d1(iwt, 10);
1132 if (!IsNoIconPosition(gg) && iwt->iwt_WindowTask.mt_MainObject)
1134 d1(KPrintF("%s/%s/%ld: Fixed Icon Position\n", __FILE__, __FUNC__, __LINE__));
1136 if ((!iwt->iwt_BackDrop || !CheckPosition(iwt, in)) && (!rild->rild_CheckOverlap || !CheckOverlap(iwt, in)))
1138 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_DrawIcon, IconObj);
1141 TIMESTAMPCOUNT_END_d1(iwt, 10);
1143 TIMESTAMPCOUNT_END_d1(iwt, 18);
1146 d1(KPrintF("%s/%s/%ld: in=%08lx\n", __FILE__, __FUNC__, __LINE__, in));
1147 TIMESTAMPCOUNT_END_d1(iwt, 9);
1149 d1({ \
1150 ULONG TextStyle = 0; \
1152 GetAttr(IDTA_TextStyle, in->in_Icon, &TextStyle); \
1153 d1(KPrintF("%s/%s/%ld: TextStyle=%ld\n", __FILE__, __FUNC__, __LINE__, TextStyle)); \
1156 return in;
1160 /// ScanDirCreateIcon
1161 static struct ScaIconNode *ScanDirCreateIcon(struct ReadIconListControl *rilc,
1162 const struct ReadIconListData *rild, struct ScaReadIconArg *ria)
1164 struct internalScaWindowTask *iwt = rilc->rilc_WindowTask;
1165 Object *IconObj;
1166 BOOL isLink;
1168 if ('\0' == *rild->rild_Name)
1169 return NULL;
1171 d1(KPrintF("%s/%s/%ld: iwt=%08lx ws=%08lx rild_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, \
1172 iwt, iwt->iwt_WindowTask.mt_WindowStruct, rild->rild_Name));
1173 d1(KPrintF("%s/%s/%ld: ria=%08lx\n", __FILE__, __FUNC__, __LINE__, ria));
1175 TIMESTAMPCOUNT_START_d1(iwt, 3);
1177 // If not root window, check for duplicate icon names
1178 if ((BPTR)NULL != iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock)
1180 if (ScanDirFindIcon(rilc, rild->rild_Name))
1182 d1(KPrintF("%s/%s/%ld: Icon found\n", __FILE__, __FUNC__, __LINE__));
1183 TIMESTAMPCOUNT_END_d1(iwt, 3);
1184 return NULL;
1187 TIMESTAMPCOUNT_END_d1(iwt, 3);
1189 isLink = (ST_SOFTLINK == rild->rild_Type) || (ST_LINKDIR == rild->rild_Type) ||
1190 (ST_LINKFILE == rild->rild_Type) || IsSoftLink(rild->rild_Name);
1192 d1(KPrintF("%s/%s/%ld: <%s> Type=%08lx isLink=%ld\n", __FILE__, __FUNC__, __LINE__, rild->rild_Name, rild->rild_Type, isLink));
1194 TIMESTAMPCOUNT_START_d1(iwt, 4);
1196 // NewIconObject()
1197 IconObj = (Object *) NewIconObjectTags((STRPTR) rild->rild_Name,
1198 IDTA_InnerBottom, CurrentPrefs.pref_ImageBorders.Bottom,
1199 IDTA_InnerRight, CurrentPrefs.pref_ImageBorders.Right,
1200 IDTA_InnerTop, CurrentPrefs.pref_ImageBorders.Top,
1201 IDTA_InnerLeft, CurrentPrefs.pref_ImageBorders.Left,
1202 IDTA_SupportedIconTypes, CurrentPrefs.pref_SupportedIconTypes,
1203 IDTA_SizeConstraints, (IPTR) &iwt->iwt_WindowTask.mt_WindowStruct->ws_IconSizeConstraints,
1204 IDTA_ScalePercentage, iwt->iwt_WindowTask.mt_WindowStruct->ws_IconScaleFactor,
1205 IDTA_Text, (IPTR) rild->rild_Name,
1206 DTA_Name, (IPTR) rild->rild_Name,
1207 IDTA_HalfShinePen, PalettePrefs.pal_PensList[PENIDX_HSHINEPEN],
1208 IDTA_HalfShadowPen, PalettePrefs.pal_PensList[PENIDX_HSHADOWPEN],
1209 IDTA_FrameTypeSel, CurrentPrefs.pref_FrameTypeSel,
1210 IDTA_FrameType, CurrentPrefs.pref_FrameType,
1211 IDTA_TextSkip, CurrentPrefs.pref_TextSkip,
1212 IDTA_MultiLineText, (IPTR) CurrentPrefs.pref_IconTextMuliLine,
1213 IDTA_TextPen, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPEN],
1214 IDTA_TextPenSel, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPENSEL],
1215 IDTA_TextPenShadow, PalettePrefs.pal_PensList[PENIDX_ICONTEXTSHADOWPEN],
1216 IDTA_TextPenOutline, PalettePrefs.pal_PensList[PENIDX_ICONTEXTOUTLINEPEN],
1217 IDTA_TextPenBgSel, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPENBGSEL],
1218 IDTA_SelectedTextRectangle, CurrentPrefs.pref_SelectedTextRectangle,
1219 IDTA_SelTextRectBorderX, CurrentPrefs.pref_SelTextRectBorderX,
1220 IDTA_SelTextRectBorderY, CurrentPrefs.pref_SelTextRectBorderY,
1221 IDTA_SelTextRectRadius, CurrentPrefs.pref_SelTextRectRadius,
1222 IDTA_TextMode, CurrentPrefs.pref_TextMode,
1223 IDTA_TextDrawMode, FontPrefs.fprf_TextDrawMode,
1224 IDTA_TextBackPen, FontPrefs.fprf_FontBackPen,
1225 IDTA_TextStyle, isLink ? CurrentPrefs.pref_LinkTextStyle : FS_NORMAL,
1226 IDTA_Font, (IPTR) iwt->iwt_IconFont,
1227 IDTA_Fonthandle, (IPTR) &iwt->iwt_IconTTFont,
1228 IDTA_FontHook, (IPTR) (TTEngineBase ? &ScalosFontHook : NULL),
1229 TAG_END);
1231 d1(KPrintF("%s/%s/%ld: <%s> IconObj=%08lx\n", __FILE__, __FUNC__, __LINE__, rild->rild_Name, IconObj));
1232 TIMESTAMPCOUNT_END_d1(iwt, 4);
1234 if (NULL == IconObj)
1236 d1(if (ria) KPrintF("%s/%s/%ld: ria_IconType=%lu\n", __FILE__, __FUNC__, __LINE__, ria->ria_IconType));
1238 return CreateDefaultIcon(rilc, rild, ria, FALSE);
1241 d1({ \
1242 ULONG TextStyle = 0; \
1244 GetAttr(IDTA_TextStyle, IconObj, &TextStyle); \
1245 d1(KPrintF("%s/%s/%ld: TextStyle=%ld\n", __FILE__, __FUNC__, __LINE__, TextStyle)); \
1248 TIMESTAMPCOUNT_END_d1(iwt, 3);
1250 return ScanDirInitIcon(rilc, rild, ria, FALSE, isLink, IconObj);
1254 /// CreateDefaultIcon
1255 static struct ScaIconNode *CreateDefaultIcon(struct ReadIconListControl *rilc, const struct ReadIconListData *rild,
1256 struct ScaReadIconArg *ria, BOOL CheckForDuplicates)
1258 struct internalScaWindowTask *iwt = rilc->rilc_WindowTask;
1259 Object *IconObj = NULL;
1260 STRPTR PathBuffer = NULL;
1262 do {
1263 CONST_STRPTR IconName = rild->rild_Name;
1264 ULONG IconViewMode;
1265 ULONG ddFlags;
1266 BOOL isLink;
1267 ULONG IconType = ICONTYPE_NONE;
1269 if (NULL == iwt->iwt_WindowTask.mt_MainObject || '\0' == *rild->rild_Name)
1270 break;;
1272 d1(KPrintF("%s/%s/%ld: iwt=%08lx ws=%08lx rild_Name=<%s>\n", __FILE__, __FUNC__, __LINE__, \
1273 iwt, iwt->iwt_WindowTask.mt_WindowStruct, rild->rild_Name));
1275 if (CheckForDuplicates)
1277 TIMESTAMPCOUNT_START_d1(iwt, 5);
1278 // If not root window, check for duplicate icon names
1279 if ((BPTR)NULL != iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock)
1281 if (ScanDirFindIcon(rilc, rild->rild_Name))
1283 d1(KPrintF("%s/%s/%ld: Duplicate Icon found\n", __FILE__, __FUNC__, __LINE__));
1284 TIMESTAMPCOUNT_END_d1(iwt, 5);
1285 break;
1288 TIMESTAMPCOUNT_END_d1(iwt, 5);
1291 d1(KPrintF("%s/%s/%ld: ria=%08lx\n", __FILE__, __FUNC__, __LINE__, ria));
1292 if (ria)
1294 IconType = ria->ria_IconType;
1296 d1(KPrintF("%s/%s/%ld: ria_IconType=%lu\n", __FILE__, __FUNC__, __LINE__, ria->ria_IconType));
1298 if (ria->ria_Lock && (BPTR)NULL == iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock)
1300 IconName = PathBuffer = AllocPathBuffer();
1301 if (NULL == PathBuffer)
1302 break;;
1304 NameFromLock(ria->ria_Lock, PathBuffer, Max_PathLen);
1305 AddPart(PathBuffer, (STRPTR) rild->rild_Name, Max_PathLen);
1309 d1(KPrintF("%s/%s/%ld: <%s> Type=%08lx IconType=%lu\n", __FILE__, __FUNC__, __LINE__, rild->rild_Name, rild->rild_Type, IconType));
1310 d1(KPrintF("%s/%s/%ld: IconName=<%s>\n", __FILE__, __FUNC__, __LINE__, IconName));
1312 // try to get default icon
1313 TIMESTAMPCOUNT_START_d1(iwt, 7);
1314 IconObj = (Object *) DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_GetDefIcon,
1315 IconName,
1316 rild->rild_Type,
1317 rild->rild_Protection,
1318 IconType);
1319 TIMESTAMPCOUNT_END_d1(iwt, 7);
1321 if (NULL == IconObj)
1322 break;
1324 // default icons inherit ShowAllFiles and ViewMode settings from parent window.
1325 IconViewMode = TranslateViewModesToIcon(iwt->iwt_WindowTask.mt_WindowStruct->ws_Viewmodes);
1327 ddFlags = iwt->iwt_WindowTask.mt_WindowStruct->ws_ViewAll;
1328 if (SortOrder_Ascending == iwt->iwt_WindowTask.mt_WindowStruct->ws_SortOrder)
1329 ddFlags |= DDFLAGS_SORTASC;
1330 else if (SortOrder_Descending == iwt->iwt_WindowTask.mt_WindowStruct->ws_SortOrder)
1331 ddFlags |= DDFLAGS_SORTDESC;
1333 isLink = (ST_SOFTLINK == rild->rild_Type) || (ST_LINKDIR == rild->rild_Type) ||
1334 (ST_LINKFILE == rild->rild_Type) || IsSoftLink(rild->rild_Name);
1336 TIMESTAMPCOUNT_START_d1(iwt, 6);
1338 SetAttrs(IconObj,
1339 IDTA_Flags, ddFlags,
1340 IDTA_ViewModes, IconViewMode,
1341 IDTA_InnerBottom, CurrentPrefs.pref_ImageBorders.Bottom,
1342 IDTA_InnerRight, CurrentPrefs.pref_ImageBorders.Right,
1343 IDTA_InnerTop, CurrentPrefs.pref_ImageBorders.Top,
1344 IDTA_InnerLeft, CurrentPrefs.pref_ImageBorders.Left,
1345 IDTA_SupportedIconTypes, CurrentPrefs.pref_SupportedIconTypes,
1346 IDTA_TextStyle, isLink ? CurrentPrefs.pref_LinkTextStyle : FS_NORMAL,
1347 TAG_END);
1348 TIMESTAMPCOUNT_END_d1(iwt, 6);
1349 } while (0);
1351 if (PathBuffer)
1352 FreePathBuffer(PathBuffer);
1354 return ScanDirInitIcon(rilc, rild, NULL, TRUE, FALSE, IconObj);
1358 /// CheckCleanup
1359 static enum ScanDirResult CheckCleanup(struct ReadIconListControl *rilc)
1361 enum ScanDirResult sdResult = SCANDIR_OK;
1363 if (rilc->rilc_CleanupCount++ > 20)
1365 struct internalScaWindowTask *iwt = rilc->rilc_WindowTask;
1367 rilc->rilc_CleanupCount = 0;
1369 sdResult = GenerateIcons(rilc, FALSE);
1371 d1(kprintf("%s/%s/%ld: IconList=%08lx\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_WindowTask->iwt_WindowTask.wt_LateIconList));
1373 if (iwt->iwt_WindowTask.wt_Window)
1375 SCA_SortNodes((struct ScalosNodeList *) &iwt->iwt_WindowTask.wt_LateIconList, &CompareNameHook, SCA_SortType_Best);
1377 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_SetVirtSize,
1378 SETVIRTF_AdjustRightSlider | SETVIRTF_AdjustBottomSlider);
1381 ScanDirUpdateStatusBarText(iwt, rilc->rilc_TotalFound);
1384 return sdResult;
1388 /// GenerateIcons
1389 static enum ScanDirResult GenerateIcons(struct ReadIconListControl *rilc, BOOL Final)
1391 struct IconScanEntry *ise;
1392 enum ScanDirResult sdResult;
1393 ULONG n;
1395 d1(KPrintF("%s/%s/%ld: START Final=%ld\n", __FILE__, __FUNC__, __LINE__, Final));
1396 TIMESTAMP_d1();
1397 TIMESTAMPCOUNT_START_d1(rilc->rilc_WindowTask, 1);
1399 // build links between icons and objects
1400 sdResult = LinkIconScanList(rilc);
1401 if (SCANDIR_OK != sdResult)
1403 d1(KPrintF("%s/%s/%ld: END sdResult=%ld\n", __FILE__, __FUNC__, __LINE__, sdResult));
1404 return sdResult;
1407 TIMESTAMP_d1();
1409 if (Final)
1411 while ((ise = (struct IconScanEntry *) RemTail(&rilc->rilc_UnlinkedIconScanList)))
1413 // Move all remaining unlinked icons from rilc_UnlinkedIconScanList to rilc_IconScanList
1414 Remove(&ise->ise_Node);
1415 AddTail(&rilc->rilc_IconScanList, &ise->ise_Node);
1419 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1420 TIMESTAMP_d1();
1422 for (n = 0, ise = (struct IconScanEntry *) rilc->rilc_IconScanList.lh_Head;
1423 SCANDIR_OK == sdResult && ise != (struct IconScanEntry *) &rilc->rilc_IconScanList.lh_Tail;
1424 ise = (struct IconScanEntry *) ise->ise_Node.ln_Succ)
1426 BOOL ShowEntry = TRUE;
1428 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1429 if (ise->ise_Flags & ISEFLG_Used)
1430 continue;
1432 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1433 if (!Final && NULL == ise->ise_ObjPtr && NULL == ise->ise_IconPtr)
1434 continue;
1436 d1(KPrintF("%s/%s/%ld: ise=<%s> Flags=%08lx ObjPtr=%08lx IconPtr=%08lx\n", \
1437 __FILE__, __FUNC__, __LINE__, ise->ise_Fib.fib_FileName, ise->ise_Flags, ise->ise_ObjPtr, ise->ise_IconPtr));
1439 if (!IsShowAllType(rilc->rilc_WindowTask->iwt_OldShowType))
1441 ShowEntry = (NULL == ise->ise_ObjPtr); // Icon w/o object
1443 if (WBDISK == ise->ise_IconType)
1444 ShowEntry = FALSE; // don't show WBDISK icons
1447 if (ShowEntry && IsFileHidden(ise->ise_Fib.fib_FileName, ise->ise_Fib.fib_Protection))
1448 ShowEntry = FALSE;
1450 d1(kprintf("%s/%s/%ld: <%s> ShowEntry=%ld\n", __FILE__, __FUNC__, __LINE__, ise->ise_Fib.fib_FileName, ShowEntry));
1452 if (ShowEntry)
1454 struct ScaIconNode *in;
1455 struct ReadIconListData rild;
1457 rild.rild_DiskWriteProtected = !rilc->rilc_DiskWritable;
1459 if (ise->ise_ObjPtr)
1461 ScanDirFillRildFromIse(&rild, ise->ise_ObjPtr);
1463 else
1465 // icon without object
1466 ScanDirFillRildFromIse(&rild, ise);
1467 rild.rild_Type = 0; // type of object is undefined
1469 rild.rild_Size64 = MakeU64(0);
1470 rild.rild_SoloIcon = TRUE;
1472 d1(kprintf("%s/%s/%ld: ise=<%s> Flags=%08lx ObjPtr=%08lx IconPtr=%08lx SOLOicon\n", \
1473 __FILE__, __FUNC__, __LINE__, ise->ise_Fib.fib_FileName, ise->ise_Flags, ise->ise_ObjPtr, ise->ise_IconPtr));
1475 rild.rild_CheckOverlap = rilc->rilc_WindowTask->iwt_CheckOverlappingIcons;
1477 if (0 != ise->ise_Pos && ~0 != ise->ise_Pos)
1479 // strip ".info" from name
1480 STRPTR ppos = rild.rild_Name + ((STRPTR) ise->ise_Pos - (STRPTR) ise->ise_Fib.fib_FileName);
1482 *ppos = '\0';
1485 d1(KPrintF("%s/%s/%ld: ScanDirCreateIcon(%s)\n", __FILE__, __FUNC__, __LINE__, rild.rild_Name));
1487 in = ScanDirCreateIcon(rilc, &rild, NULL);
1489 d1(kprintf("%s/%s/%ld: in=%08lx\n", __FILE__, __FUNC__, __LINE__, in));
1491 if (in)
1493 d1(KPrintF("%s/%s/%ld: Name=<%s> rild_IconType=%ld\n", \
1494 __FILE__, __FUNC__, __LINE__, rild.rild_Name, rild.rild_IconType));
1496 SetIconSupportsFlags(in, rilc->rilc_DiskWritable);
1500 if (rilc->rilc_WindowTask->iwt_WindowTask.mt_MainObject && n++ > 5)
1502 n = 0;
1503 if (rilc->rilc_WindowTask->iwt_AbortScanDir)
1504 sdResult = SCANDIR_ABORT;
1505 else if (DoMethod(rilc->rilc_WindowTask->iwt_WindowTask.mt_MainObject, SCCM_CheckForMessages) )
1506 sdResult = SCANDIR_WINDOW_CLOSING;
1509 ise->ise_Flags |= ISEFLG_Used;
1512 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1513 TIMESTAMP_d1();
1515 for (n = 0, ise = (struct IconScanEntry *) rilc->rilc_NonIconScanList.lh_Head;
1516 SCANDIR_OK == sdResult && ise != (struct IconScanEntry *) &rilc->rilc_NonIconScanList.lh_Tail;
1517 ise = (struct IconScanEntry *) ise->ise_Node.ln_Succ)
1519 BOOL ShowEntry = TRUE;
1521 if (ise->ise_Flags & ISEFLG_Used)
1522 continue;
1524 if (!Final && NULL == ise->ise_ObjPtr && NULL == ise->ise_IconPtr)
1525 continue;
1527 d1(kprintf("%s/%s/%ld: ise=<%s> Flags=%08lx ObjPtr=%08lx IconPtr=%08lx\n", \
1528 __FILE__, __FUNC__, __LINE__, ise->ise_Fib.fib_FileName, ise->ise_Flags, ise->ise_ObjPtr, ise->ise_IconPtr));
1530 if (!CurrentPrefs.pref_ShowThumbnailsAsDefault && (THUMBNAILS_AsDefault == rilc->rilc_WindowTask->iwt_ThumbnailMode))
1532 if (!IsShowAllType(rilc->rilc_WindowTask->iwt_OldShowType))
1534 if (NULL == ise->ise_IconPtr)
1535 ShowEntry = FALSE; // Display thumbnail only if object has a icon
1539 if (THUMBNAILS_Never == rilc->rilc_WindowTask->iwt_ThumbnailMode)
1541 if (!IsShowAllType(rilc->rilc_WindowTask->iwt_OldShowType))
1543 ShowEntry = (NULL != ise->ise_IconPtr); // Object with icon
1545 else
1547 if (NULL != ise->ise_IconPtr)
1548 ShowEntry = FALSE; // suppress object if icon attached
1552 if (ShowEntry && IsFileHidden(ise->ise_Fib.fib_FileName, ise->ise_Fib.fib_Protection))
1553 ShowEntry = FALSE;
1555 d1(kprintf("%s/%s/%ld: ShowEntry=%ld\n", __FILE__, __FUNC__, __LINE__, ShowEntry));
1557 if (ShowEntry)
1559 struct ScaIconNode *in;
1560 struct ReadIconListData rild;
1562 rild.rild_DiskWriteProtected = !rilc->rilc_DiskWritable;
1564 ScanDirFillRildFromIse(&rild, ise);
1565 rild.rild_CheckOverlap = rilc->rilc_WindowTask->iwt_CheckOverlappingIcons;
1567 d1(KPrintF("%s/%s/%ld: ScanDirCreateIcon(%s) ObjPtr=%08lx IconPtr=%08lx\n", \
1568 __FILE__, __FUNC__, __LINE__, rild.rild_Name, \
1569 ise->ise_ObjPtr, ise->ise_IconPtr));
1571 TIMESTAMPCOUNT_START_d1(rilc->rilc_WindowTask, 2);
1573 if (ise->ise_IconPtr)
1574 in = ScanDirCreateIcon(rilc, &rild, NULL);
1575 else
1576 in = CreateDefaultIcon(rilc, &rild, NULL, TRUE);
1578 TIMESTAMPCOUNT_END_d1(rilc->rilc_WindowTask, 2);
1580 d1(kprintf("%s/%s/%ld: in=%08lx\n", __FILE__, __FUNC__, __LINE__, in));
1582 if (in)
1584 d1(KPrintF("%s/%s/%ld: Name=<%s> rild_IconType=%ld\n", \
1585 __FILE__, __FUNC__, __LINE__, rild.rild_Name, rild.rild_IconType));
1587 SetIconSupportsFlags(in, rilc->rilc_DiskWritable);
1591 if (rilc->rilc_WindowTask->iwt_WindowTask.mt_MainObject && n++ > 5)
1593 n = 0;
1594 if (rilc->rilc_WindowTask->iwt_AbortScanDir)
1595 sdResult = SCANDIR_ABORT;
1596 else if ( DoMethod(rilc->rilc_WindowTask->iwt_WindowTask.mt_MainObject, SCCM_CheckForMessages) )
1597 sdResult = SCANDIR_WINDOW_CLOSING;
1600 ise->ise_Flags |= ISEFLG_Used;
1603 TIMESTAMP_d1();
1605 d1(KPrintF("%s/%s/%ld: END sdResult=%ld\n", __FILE__, __FUNC__, __LINE__, sdResult));
1606 TIMESTAMP_d1();
1607 TIMESTAMPCOUNT_END_d1(rilc->rilc_WindowTask, 1);
1609 return sdResult;
1613 /// CompareNameFunc
1614 // compare function for icon list sorting
1615 // drawers are sorted first
1616 static SAVEDS(LONG) CompareNameFunc(
1617 struct Hook *hook,
1618 struct ScaIconNode *in2,
1619 struct ScaIconNode *in1)
1621 d1(kprintf("%s/%s/%ld: in1=%08lx in2=%08lx\n", __FILE__, __FUNC__, __LINE__, in1, in2));
1623 (void) hook;
1625 if (IntuitionBase)
1627 IPTR IconType1, IconType2;
1629 GetAttr(IDTA_Type, in1->in_Icon, &IconType1);
1630 GetAttr(IDTA_Type, in2->in_Icon, &IconType2);
1632 if (WBDRAWER == IconType2)
1634 if (WBDRAWER != IconType1)
1635 return -1;
1637 else
1639 if (WBDRAWER == IconType1)
1640 return 1;
1644 return Stricmp(in2->in_Name, in1->in_Name);
1648 /// SetIconSupportsFlags
1649 void SetIconSupportsFlags(struct ScaIconNode *in, BOOL isDiskWritable)
1651 IPTR IconType;
1653 if (NULL == in || NULL == in->in_Icon)
1654 return;
1656 GetAttr(IDTA_Type, in->in_Icon, &IconType);
1658 d1(kprintf("%s/%s/%ld: Name=<%s> IconType=%ld in_SupportFlags=%08lx\n", __FILE__, __FUNC__, __LINE__, GetIconName(in), IconType, in->in_SupportFlags));
1660 if (WBGARBAGE == IconType)
1662 in->in_SupportFlags |= INF_SupportsEmptyTrash;
1663 in->in_SupportFlags &= ~INF_SupportsDelete;
1665 if (!isDiskWritable)
1667 in->in_SupportFlags &= ~(INF_SupportsDelete | INF_SupportsRename |
1668 INF_SupportsSnapshot | INF_SupportsUnSnapshot |
1669 INF_SupportsPutAway | INF_SupportsLeaveOut |
1670 INF_SupportsEmptyTrash );
1672 if (in->in_Flags & INF_DefaultIcon)
1674 // forbid "Leave Out" for default icons
1675 in->in_SupportFlags &= ~(INF_SupportsLeaveOut);
1676 d1(kprintf("%s/%s/%ld: in=<%s> supportFlags=%08lx\n", \
1677 __FILE__, __FUNC__, __LINE__, GetIconName(in), in->in_SupportFlags));
1679 if (in->in_DeviceIcon)
1681 // forbid "Leave Out" and "Put away" for device icons
1682 in->in_SupportFlags &= ~(INF_SupportsLeaveOut | INF_SupportsPutAway);
1685 d1(kprintf("%s/%s/%ld: in=%08lx <%s> isDiskWritable=%ld SupportFlags=%08lx\n", \
1686 __FILE__, __FUNC__, __LINE__, in, in->in_Name, isDiskWritable, in->in_SupportFlags));
1690 /// IsSoftLink
1691 BOOL IsSoftLink(CONST_STRPTR Name)
1693 BOOL isLink = FALSE;
1694 IPTR Success;
1695 char *Buffer = NULL;
1696 BPTR fLock = (BPTR)NULL;
1698 d1(kprintf("%s/%s/%ld: Name=<%s>\n", __FILE__, __FUNC__, __LINE__, Name));
1700 do {
1701 struct MsgPort *FileSysPort;
1702 BPTR dirLock;
1704 dirLock = CurrentDir((BPTR)NULL);
1705 CurrentDir(dirLock);
1707 if ((BPTR)NULL == dirLock)
1708 break;
1710 d1(kprintf("%s/%s/%ld: dirLock=%08lx\n", __FILE__, __FUNC__, __LINE__, dirLock));
1711 debugLock_d1(dirLock);
1713 FileSysPort = ((struct FileLock *) BADDR(dirLock))->fl_Task;
1715 Buffer = AllocPathBuffer();
1716 d1(kprintf("%s/%s/%ld: Buffer=%08lx\n", __FILE__, __FUNC__, __LINE__, Buffer));
1717 if (NULL == Buffer)
1718 break;
1720 // make BSTRING from Name (prepend length byte)
1721 stccpy(Buffer + 1, Name, Max_PathLen - 1);
1722 *Buffer = strlen(Name);
1724 Success = DoPkt(FileSysPort,
1725 ACTION_LOCATE_OBJECT,
1726 (SIPTR) dirLock,
1727 (SIPTR) MKBADDR(Buffer),
1728 ACCESS_READ,
1729 0, 0);
1731 d1(kprintf("%s/%s/%ld: Success=%ld\n", __FILE__, __FUNC__, __LINE__, Success));
1733 if (Success)
1735 fLock = (BPTR) Success;
1736 d1(kprintf("%s/%s/%ld: Success=%08lx IoErr=%ld\n", __FILE__, __FUNC__, __LINE__, Success, IoErr()));
1738 else
1740 LONG errCode = IoErr();
1742 d1(kprintf("%s/%s/%ld: Success=%08lx IoErr=%ld\n", __FILE__, __FUNC__, __LINE__, Success, errCode));
1744 if (ERROR_IS_SOFT_LINK == errCode)
1745 isLink = TRUE;
1747 } while (0);
1749 d1(kprintf("%s/%s/%ld: Buffer=%08lx\n", __FILE__, __FUNC__, __LINE__, Buffer));
1750 if (fLock)
1751 UnLock(fLock);
1752 d1(kprintf("%s/%s/%ld: Buffer=%08lx\n", __FILE__, __FUNC__, __LINE__, Buffer));
1753 if (Buffer)
1754 FreePathBuffer(Buffer);
1756 d1(kprintf("%s/%s/%ld: END isLink=%ld\n", __FILE__, __FUNC__, __LINE__, isLink));
1758 return isLink;
1762 /// RilcDisposeData
1763 static void RilcDisposeData(void *data)
1765 // No-op since data is only handed as reference to IconScanEntry node
1766 // and IconScanEntry nodes are managed within rilc_NonIconScanList
1767 (void) data;
1771 /// RilcDisposeKey
1772 static void RilcDisposeKey(void *key)
1774 // No-op since key is only handed as reference to IconScanEntry->ise_Fib.fib_FileName
1775 // and IconScanEntry nodes are managed within rilc_NonIconScanList
1776 (void) key;
1780 /// RilcCompare
1781 static int RilcCompare(const void *key1, const void *key2)
1783 return Stricmp((CONST_STRPTR) key2, (CONST_STRPTR) key1);
1787 /// RilcInit
1788 BOOL RilcInit(struct ReadIconListControl *rilc, struct internalScaWindowTask *iwt)
1790 BOOL Success = FALSE;
1792 do {
1793 memset(rilc, 0, sizeof(struct ReadIconListControl));
1795 NewList(&rilc->rilc_IconScanList);
1796 NewList(&rilc->rilc_NonIconScanList);
1797 NewList(&rilc->rilc_UnlinkedIconScanList);
1799 rilc->rilc_replyPort = NULL;
1800 rilc->rilc_pkt = NULL;
1801 rilc->rilc_exallControl = NULL;
1802 rilc->rilc_ExAllBuffer = NULL;
1803 rilc->rilc_dirLock = (BPTR)NULL;
1804 rilc->rilc_FlagFinished = FALSE;
1805 rilc->rilc_edNext = NULL;
1806 rilc->rilc_exd = NULL;
1807 rilc->rilc_CleanupCount = 0;
1808 rilc->rilc_PacketPending = FALSE;
1809 rilc->rilc_TotalFound = 0;
1810 rilc->rilc_WindowTask = iwt;
1812 BackDropInitList(&rilc->rilc_BackdropList);
1814 rilc->rilc_StdFilesTree = BTreeCreate(RilcDisposeData, RilcDisposeKey, RilcCompare);
1815 d1(KPrintF("%s/%s/%ld: rilc_StdFilesTree=%08lx\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_StdFilesTree));
1816 if (NULL == rilc->rilc_StdFilesTree)
1817 break;
1819 rilc->rilc_IconTree = BTreeCreate(RilcDisposeData, RilcDisposeKey, RilcCompare);
1820 d1(KPrintF("%s/%s/%ld: rilc_IconTree=%08lx\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_IconTree));
1821 if (NULL == rilc->rilc_IconTree)
1822 break;
1824 BackdropFilterList(&rilc->rilc_BackdropList, iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock);
1826 Success = TRUE;
1827 } while (0);
1829 return Success;
1833 /// RilcCleanup
1834 void RilcCleanup(struct ReadIconListControl *rilc)
1836 struct IconScanEntry *ise;
1838 BackdropFreeList(&rilc->rilc_BackdropList);
1840 if (rilc->rilc_PacketPending && rilc->rilc_replyPort)
1842 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1844 rilc->rilc_PacketPending = FALSE;
1846 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1847 WaitPort(rilc->rilc_replyPort);
1848 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
1849 GetMsg(rilc->rilc_replyPort);
1852 while ((ise = (struct IconScanEntry *) RemTail(&rilc->rilc_IconScanList)))
1854 DisposeIconScanEntry(ise);
1856 while ((ise = (struct IconScanEntry *) RemTail(&rilc->rilc_UnlinkedIconScanList)))
1858 DisposeIconScanEntry(ise);
1860 while ((ise = (struct IconScanEntry *) RemTail(&rilc->rilc_NonIconScanList)))
1862 DisposeIconScanEntry(ise);
1865 if (rilc->rilc_IconTree)
1867 BTreeDispose(rilc->rilc_IconTree);
1868 rilc->rilc_IconTree = NULL;
1870 if (rilc->rilc_StdFilesTree)
1872 BTreeDispose(rilc->rilc_StdFilesTree);
1873 rilc->rilc_StdFilesTree = NULL;
1875 if (rilc->rilc_Fib)
1877 FreeDosObject(DOS_FIB, rilc->rilc_Fib);
1878 rilc->rilc_Fib = NULL;
1880 ScalosExamineDirEnd(&rilc->rilc_DirHandle);
1881 if (rilc->rilc_exallControl)
1883 FreeDosObject(DOS_EXALLCONTROL, rilc->rilc_exallControl);
1884 rilc->rilc_exallControl = NULL;
1886 if (rilc->rilc_pkt)
1888 FreeDosObject(DOS_STDPKT, rilc->rilc_pkt);
1889 rilc->rilc_pkt = NULL;
1891 if (rilc->rilc_dirLock)
1893 UnLock(rilc->rilc_dirLock);
1894 rilc->rilc_dirLock = (BPTR)NULL;
1896 if (rilc->rilc_replyPort)
1898 DeleteMsgPort(rilc->rilc_replyPort);
1899 rilc->rilc_replyPort = NULL;
1901 if (rilc->rilc_ExAllBuffer)
1903 FreeVec(rilc->rilc_ExAllBuffer);
1904 rilc->rilc_ExAllBuffer = NULL;
1909 /// ReExamine
1910 #if 0
1911 static LONG ReExamine(struct ReadIconListData *rild)
1913 T_ExamineData *fib;
1914 BPTR fLock = (BPTR)NULL;
1915 BOOL Result = RETURN_OK;
1917 do {
1918 if (!ScalosExamineBegin(&fib))
1920 Result = IoErr();
1921 break;
1924 fLock = Lock(rild->rild_Name, ACCESS_READ);
1925 if ((BPTR)NULL == fLock)
1927 Result = IoErr();
1928 break;
1931 if (!ScalosExamineLock(fLock, &fib))
1933 Result = IoErr();
1934 break;
1937 rild->rild_Type = ScalosExamineGetDirEntryType(fib);
1938 rild->rild_Protection = ScalosExamineGetProtection(fib);
1939 rild->rild_Size64 = ScalosExamineGetSize(fib);
1940 rild->rild_DateStamp = *ScalosExamineGetDate(fib);
1942 stccpy(rild->rild_Comment, ScalosExamineGetComment(fib), sizeof(rild->rild_Comment));
1943 stccpy(rild->rild_Name, ScalosExamineGetName(fib), sizeof(rild->rild_Name));
1944 } while (0);
1946 ScalosExamineEnd(&fib);
1947 if (fLock)
1948 UnLock(fLock);
1950 return Result;
1952 #endif
1955 /// NewIconScanEntry
1956 static struct IconScanEntry *NewIconScanEntry(struct internalScaWindowTask *iwt, const struct ReadIconListData *rild)
1958 struct IconScanEntry *ise;
1960 ise = ScalosAlloc(sizeof(struct IconScanEntry));
1961 if (ise)
1963 ise->ise_Flags = 0;
1964 ise->ise_IconObj = NULL;
1965 ise->ise_IconPtr = NULL;
1966 ise->ise_ObjPtr = NULL;
1968 d1(kprintf("%s/%s/%ld: <%s> comment=<%s>\n", __FILE__, __FUNC__, __LINE__, rild->rild_Name, rild->rild_Comment));
1970 stccpy(ise->ise_Fib.fib_FileName, rild->rild_Name, sizeof(ise->ise_Fib.fib_FileName));
1971 ise->ise_Fib.fib_DirEntryType = rild->rild_Type;
1972 ise->ise_Size64 = rild->rild_Size64;
1973 ise->ise_Fib.fib_Protection = rild->rild_Protection;
1974 ise->ise_Fib.fib_Date = rild->rild_DateStamp;
1975 stccpy(ise->ise_Fib.fib_Comment, rild->rild_Comment, sizeof(ise->ise_Fib.fib_Comment));
1977 // guess ise_IconType and set ISEFLG_IsLink flag
1978 switch (rild->rild_Type)
1980 case ST_ROOT:
1981 ise->ise_IconType = WBDISK;
1982 break;
1983 case ST_USERDIR:
1984 ise->ise_IconType = WBDRAWER;
1985 break;
1986 case ST_LINKDIR:
1987 ise->ise_Flags |= ISEFLG_IsLink;
1988 ise->ise_IconType = WBDRAWER;
1989 break;
1990 case ST_SOFTLINK:
1991 case ST_LINKFILE:
1992 ise->ise_Flags |= ISEFLG_IsLink;
1993 ise->ise_IconType = WBPROJECT;
1994 break;
1995 default:
1996 if (IsSoftLink(rild->rild_Name))
1997 ise->ise_Flags |= ISEFLG_IsLink;
1999 if (!(ise->ise_Fib.fib_Protection & FIBF_EXECUTE))
2000 ise->ise_IconType = WBTOOL;
2001 else
2002 ise->ise_IconType = WBPROJECT;
2003 break;
2006 ise->ise_Pos = IsIconName(ise->ise_Fib.fib_FileName);
2008 if (0 != ise->ise_Pos && ~0 != ise->ise_Pos)
2010 ise->ise_Flags |= ISEFLG_IsIcon;
2012 if (rild->rild_FetchIconType)
2014 ise->ise_PosChar = *((char *) ise->ise_Pos);
2015 *((char *) ise->ise_Pos) = '\0'; // strip ".info" from name
2017 // NewIconObject()
2018 ise->ise_IconObj = NewIconObjectTags(ise->ise_Fib.fib_FileName,
2019 IDTA_InnerBottom, CurrentPrefs.pref_ImageBorders.Bottom,
2020 IDTA_InnerRight, CurrentPrefs.pref_ImageBorders.Right,
2021 IDTA_InnerTop, CurrentPrefs.pref_ImageBorders.Top,
2022 IDTA_InnerLeft, CurrentPrefs.pref_ImageBorders.Left,
2023 IDTA_Text, (IPTR) rild->rild_Name,
2024 IDTA_HalfShinePen, PalettePrefs.pal_PensList[PENIDX_HSHINEPEN],
2025 IDTA_HalfShadowPen, PalettePrefs.pal_PensList[PENIDX_HSHADOWPEN],
2026 IDTA_FrameTypeSel, CurrentPrefs.pref_FrameTypeSel,
2027 IDTA_FrameType, CurrentPrefs.pref_FrameType,
2028 IDTA_TextSkip, CurrentPrefs.pref_TextSkip,
2029 IDTA_MultiLineText, (IPTR) CurrentPrefs.pref_IconTextMuliLine,
2030 IDTA_TextPen, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPEN],
2031 IDTA_TextPenSel, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPENSEL],
2032 IDTA_TextPenShadow, PalettePrefs.pal_PensList[PENIDX_ICONTEXTSHADOWPEN],
2033 IDTA_TextPenOutline, PalettePrefs.pal_PensList[PENIDX_ICONTEXTOUTLINEPEN],
2034 IDTA_TextPenBgSel, PalettePrefs.pal_PensList[PENIDX_ICONTEXTPENBGSEL],
2035 IDTA_SelectedTextRectangle, CurrentPrefs.pref_SelectedTextRectangle,
2036 IDTA_SelTextRectBorderX, CurrentPrefs.pref_SelTextRectBorderX,
2037 IDTA_SelTextRectBorderY, CurrentPrefs.pref_SelTextRectBorderY,
2038 IDTA_SelTextRectRadius, CurrentPrefs.pref_SelTextRectRadius,
2039 IDTA_TextMode, CurrentPrefs.pref_TextMode,
2040 IDTA_TextDrawMode, FontPrefs.fprf_TextDrawMode,
2041 IDTA_TextBackPen, FontPrefs.fprf_FontBackPen,
2042 IDTA_TextStyle, (ise->ise_Flags & ISEFLG_IsLink) ? CurrentPrefs.pref_LinkTextStyle : FS_NORMAL,
2043 IDTA_SupportedIconTypes, CurrentPrefs.pref_SupportedIconTypes,
2044 IDTA_SizeConstraints, (IPTR) &iwt->iwt_WindowTask.mt_WindowStruct->ws_IconSizeConstraints,
2045 IDTA_ScalePercentage, iwt->iwt_WindowTask.mt_WindowStruct->ws_IconScaleFactor,
2046 TAG_END);
2048 d1(KPrintF("%s/%s/%ld: Name=<%s> IconObj=%08lx\n", \
2049 __FILE__, __FUNC__, __LINE__, ise->ise_Fib.fib_FileName, ise->ise_IconObj));
2050 if (ise->ise_IconObj)
2052 ise->ise_IconType = AdjustIconType(ise->ise_IconObj, rild->rild_Type, ise->ise_Flags & ISEFLG_IsLink);
2054 d1(KPrintF("%s/%s/%ld: IconType=%ld\n", \
2055 __FILE__, __FUNC__, __LINE__, ise->ise_IconType));
2058 *((char *) ise->ise_Pos) = ise->ise_PosChar; // restore file name
2063 return ise;
2067 /// DisposeIconScanEntry
2068 static void DisposeIconScanEntry(struct IconScanEntry *ise)
2070 if (ise)
2072 if (ise->ise_IconObj)
2074 DisposeIconObject(ise->ise_IconObj);
2075 ise->ise_IconObj = NULL;
2078 ScalosFree(ise);
2083 /// LinkIconScanList
2084 // build links between icons and objects
2085 enum ScanDirResult LinkIconScanList(struct ReadIconListControl *rilc)
2087 struct internalScaWindowTask *iwt = rilc->rilc_WindowTask;
2088 struct IconScanEntry *iseIcon;
2089 struct IconScanEntry *iseNext;
2090 enum ScanDirResult sdResult = SCANDIR_OK;
2091 ULONG n = 0;
2093 d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));
2095 for (iseIcon = (struct IconScanEntry *) rilc->rilc_UnlinkedIconScanList.lh_Head;
2096 iseIcon != (struct IconScanEntry *) &rilc->rilc_UnlinkedIconScanList.lh_Tail;
2097 iseIcon = iseNext)
2099 d1(kprintf("%s/%s/%ld: Name=<%s>\n", \
2100 __FILE__, __FUNC__, __LINE__, iseIcon->ise_Fib.fib_FileName));
2102 iseNext = (struct IconScanEntry *) iseIcon->ise_Node.ln_Succ;
2104 if (NULL == iseIcon->ise_ObjPtr)
2106 d1(kprintf("%s/%s/%ld: Pos=%08lx\n", __FILE__, __FUNC__, __LINE__, iseIcon->ise_Pos));
2108 if (iseIcon->ise_Pos != 0 && iseIcon->ise_Pos != ~0)
2110 struct IconScanEntry *iseObject;
2111 size_t Length = ((STRPTR) iseIcon->ise_Pos) - (STRPTR) iseIcon->ise_Fib.fib_FileName;
2112 char key[sizeof(iseIcon->ise_Fib.fib_FileName)];
2114 strncpy(key, iseIcon->ise_Fib.fib_FileName, Length);
2115 key[Length] = '\0';
2117 iseObject = (struct IconScanEntry *) BTreeFind(rilc->rilc_StdFilesTree, key);
2118 d1(KPrintF("%s/%s/%ld: key=<%s> iseObject=%08lx\n", __FILE__, __FUNC__, __LINE__, key, iseObject));
2120 if (iseObject && iseIcon != iseObject && NULL == iseObject->ise_IconPtr)
2122 d1(kprintf("%s/%s/%ld: Name=<%s>\n", \
2123 __FILE__, __FUNC__, __LINE__, iseObject->ise_Fib.fib_FileName));
2125 BTreeHide(rilc->rilc_StdFilesTree, key);
2127 iseIcon->ise_ObjPtr = iseObject;
2128 iseObject->ise_IconPtr = iseIcon;
2129 iseObject->ise_IconType = iseIcon->ise_IconType;
2131 // Move completed icon node from rilc_UnlinkedIconScanList to rilc_IconScanList
2132 Remove(&iseIcon->ise_Node);
2133 AddTail(&rilc->rilc_IconScanList, &iseIcon->ise_Node);
2137 if (iwt->iwt_WindowTask.mt_MainObject && n++ >= 20)
2139 n = 0;
2140 if (rilc->rilc_WindowTask->iwt_AbortScanDir)
2141 sdResult = SCANDIR_ABORT;
2142 else if ( DoMethod(rilc->rilc_WindowTask->iwt_WindowTask.mt_MainObject, SCCM_CheckForMessages) )
2143 sdResult = SCANDIR_WINDOW_CLOSING;
2147 d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
2149 return sdResult;
2153 /// GetFileList
2154 enum ScanDirResult GetFileList(struct ReadIconListControl *rilc,
2155 enum ScanDirResult (*CheckFunc)(struct ReadIconListControl *rilc),
2156 BOOL UseExAll, BOOL FetchIconType, BOOL CheckOverlap)
2158 struct internalScaWindowTask *iwt = rilc->rilc_WindowTask;
2159 UBYTE OldViewType = iwt->iwt_WindowTask.mt_WindowStruct->ws_Viewmodes;
2160 enum ScanDirResult sdResult;
2161 struct MsgPort *oldFsTask;
2162 BPTR oldDir;
2164 rilc->rilc_Check = CheckFunc;
2166 DateStamp(&iwt->iwt_LastIconUpdateTime); // remember time of last icon update
2168 d1(KPrintF("%s/%s/%ld: START UseExAll=%ld iwt=%08lx\n", __FILE__, __FUNC__, __LINE__, UseExAll, iwt));
2170 rilc->rilc_ExAllBuffer = AllocVec(ExAllBuffer_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
2171 if (NULL == rilc->rilc_ExAllBuffer)
2173 return SCANDIR_FAIL_ABORT;
2176 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
2178 rilc->rilc_rd.rild_FetchIconType = FetchIconType;
2179 rilc->rilc_rd.rild_Type = 0;
2180 rilc->rilc_rd.rild_CheckOverlap = CheckOverlap;
2181 rilc->rilc_rd.rild_SoloIcon = FALSE;
2183 d1(kprintf("%s/%s/%ld: iwt->iwt_WindowTask.mt_WindowStruct=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_WindowTask.mt_WindowStruct));
2185 if (iwt->iwt_WindowTask.mt_WindowStruct)
2187 d1(kprintf("%s/%s/%ld: ws_Lock=%08lx\n", __FILE__, __FUNC__, __LINE__, iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock));
2188 debugLock_d1(iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock);
2189 rilc->rilc_dirLock = iwt->iwt_WindowTask.mt_WindowStruct->ws_Lock;
2191 else
2193 rilc->rilc_dirLock = CurrentDir((BPTR)NULL);
2194 CurrentDir(rilc->rilc_dirLock);
2195 d1(kprintf("%s/%s/%ld: DirLock=%08lx\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_dirLock));
2198 if ((BPTR)NULL == rilc->rilc_dirLock)
2199 return SCANDIR_FINISHED;
2201 rilc->rilc_dirLock = DupLock(rilc->rilc_dirLock);
2203 if ((BPTR)NULL == rilc->rilc_dirLock)
2204 return SCANDIR_FINISHED;
2206 rilc->rilc_DiskWritable = !iwt->iwt_ReadOnly;
2207 rilc->rilc_rd.rild_DiskWriteProtected = !rilc->rilc_DiskWritable;
2209 #if defined(ED_SIZE64)
2210 rilc->rilc_ExAllType = ED_SIZE64;
2211 #else /* ED_SIZE64 */
2212 rilc->rilc_ExAllType = ED_OWNER;
2213 #endif /* ED_SIZE64 */
2215 d1(kprintf("%s/%s/%ld: Disk Writable=%ld\n", __FILE__, __FUNC__, __LINE__, rilc->rilc_DiskWritable));
2217 oldDir = CurrentDir(rilc->rilc_dirLock);
2219 oldFsTask = SetFileSysTask(((struct FileLock *) BADDR(rilc->rilc_dirLock))->fl_Task);
2221 debugLock_d1(rilc->rilc_dirLock);
2223 if (UseExAll)
2225 sdResult = BeginScan_ExAll(rilc);
2227 else
2229 sdResult = BeginScan_Examine(rilc);
2232 d1(kprintf("%s/%s/%ld: sdResult=%ld\n", __FILE__, __FUNC__, __LINE__, sdResult));
2234 while (SCANDIR_OK == sdResult || SCANDIR_FAIL_RETRY == sdResult)
2236 if (UseExAll)
2238 sdResult = ScanDir_ExAll(rilc);
2240 switch (sdResult)
2242 case SCANDIR_EXALL_BADNUMBER:
2243 // failure because of unsupported rilc_ExAllType.
2244 // retry with ED_COMMENT because
2245 // All filesystems supporting ExAll() must support through ED_COMMENT
2247 if (rilc->rilc_exallControl)
2249 FreeDosObject(DOS_EXALLCONTROL, rilc->rilc_exallControl);
2250 rilc->rilc_exallControl = NULL;
2252 if (rilc->rilc_pkt)
2254 FreeDosObject(DOS_STDPKT, rilc->rilc_pkt);
2255 rilc->rilc_pkt = NULL;
2257 if (rilc->rilc_replyPort)
2259 DeleteMsgPort(rilc->rilc_replyPort);
2260 rilc->rilc_replyPort = NULL;
2263 rilc->rilc_ExAllType = ED_COMMENT;
2264 sdResult = BeginScan_ExAll(rilc);
2265 break;
2267 case SCANDIR_EXALL_FAIL:
2268 UseExAll = FALSE;
2270 if (rilc->rilc_exallControl)
2272 FreeDosObject(DOS_EXALLCONTROL, rilc->rilc_exallControl);
2273 rilc->rilc_exallControl = NULL;
2275 if (rilc->rilc_pkt)
2277 FreeDosObject(DOS_STDPKT, rilc->rilc_pkt);
2278 rilc->rilc_pkt = NULL;
2280 if (rilc->rilc_replyPort)
2282 DeleteMsgPort(rilc->rilc_replyPort);
2283 rilc->rilc_replyPort = NULL;
2286 sdResult = BeginScan_Examine(rilc);
2287 break;
2289 default:
2290 break;
2293 else
2295 sdResult = ScanDir_Examine(rilc);
2298 d1(KPrintF("%s/%s/%ld: sdResult=%ld OldViewType=%ld ws_Viewmodes=%ld\n", \
2299 __FILE__, __FUNC__, __LINE__, sdResult, OldViewType, iwt->iwt_WindowTask.mt_WindowStruct->ws_Viewmodes));
2301 if (OldViewType != iwt->iwt_WindowTask.mt_WindowStruct->ws_Viewmodes)
2302 sdResult = SCANDIR_VIEWMODE_CHANGE;
2304 if (iwt->iwt_WindowTask.mt_MainObject && (SCANDIR_OK == sdResult || SCANDIR_FAIL_RETRY == sdResult))
2306 if (rilc->rilc_WindowTask->iwt_AbortScanDir)
2307 sdResult = SCANDIR_ABORT;
2308 else if ( DoMethod(rilc->rilc_WindowTask->iwt_WindowTask.mt_MainObject, SCCM_CheckForMessages) )
2309 sdResult = SCANDIR_WINDOW_CLOSING;
2313 d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
2315 CurrentDir(oldDir);
2316 SetFileSysTask(oldFsTask);
2318 d1(KPrintF("%s/%s/%ld: END sdResult=%ld\n", __FILE__, __FUNC__, __LINE__, sdResult));
2320 return sdResult;
2324 /// AddFileToFilesList
2325 // add a single file/directory to rilc->rilc_IconScanList
2326 LONG AddFileToFilesList(struct ReadIconListControl *rilc, BPTR dirLock, CONST_STRPTR Name)
2328 BPTR oldDir;
2329 BPTR fLock = (BPTR)NULL;
2330 LONG Result = RETURN_OK;
2332 debugLock_d1(dirLock);
2333 d1(kprintf("%s/%s/%ld: Name=<%s>\n", __FILE__, __FUNC__, __LINE__, Name));
2335 do {
2336 struct internalScaWindowTask *iwt = rilc->rilc_WindowTask;
2337 CONST_STRPTR Filename;
2338 CONST_STRPTR Comment;
2339 struct IconScanEntry *ise;
2341 oldDir = CurrentDir(dirLock);
2343 if (!ScalosExamineBegin(&rilc->rilc_exd))
2345 Result = IoErr();
2346 break;
2349 fLock = Lock((STRPTR) Name, ACCESS_READ);
2350 if ((BPTR)NULL == fLock)
2352 Result = IoErr();
2353 break;
2356 if (!ScalosExamineLock(fLock, &rilc->rilc_exd))
2358 Result = IoErr();
2359 break;
2362 rilc->rilc_rd.rild_Type = ScalosExamineGetDirEntryType(rilc->rilc_exd);
2363 rilc->rilc_rd.rild_Protection = ScalosExamineGetProtection(rilc->rilc_exd);
2364 rilc->rilc_rd.rild_Size64 = ScalosExamineGetSize(rilc->rilc_exd);
2365 rilc->rilc_rd.rild_DateStamp = *ScalosExamineGetDate(rilc->rilc_exd);
2366 rilc->rilc_rd.rild_SoloIcon = FALSE;
2368 Filename = ScalosExamineGetName(rilc->rilc_exd);
2369 Comment = ScalosExamineGetComment(rilc->rilc_exd);
2371 stccpy(rilc->rilc_rd.rild_Name, Filename, sizeof(rilc->rilc_rd.rild_Name));
2373 d1(kprintf("%s/%s/%ld: Name=<%s> Type=%ld Prot=%08lx\n", __FILE__, __FUNC__, __LINE__, \
2374 rilc->rilc_rd.rild_Name, rilc->rilc_rd.rild_Type, rilc->rilc_rd.rild_Protection));
2376 stccpy(rilc->rilc_rd.rild_Comment, Comment, sizeof(rilc->rilc_rd.rild_Comment));
2378 ise = NewIconScanEntry(iwt, &rilc->rilc_rd);
2379 d1(kprintf("%s/%s/%ld: ise=%08lx\n", __FILE__, __FUNC__, __LINE__, ise));
2380 if (ise)
2382 if (IsIconName(Name))
2384 ise->ise_Flags |= ISEFLG_IsIcon;
2385 AddTail(&rilc->rilc_IconScanList, &ise->ise_Node);
2387 else
2388 AddTail(&rilc->rilc_NonIconScanList, &ise->ise_Node);
2390 rilc->rilc_TotalFound++;
2392 } while (0);
2394 if (fLock)
2395 UnLock(fLock);
2396 ScalosExamineEnd(&rilc->rilc_exd);
2398 CurrentDir(oldDir);
2400 d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
2402 return Result;
2406 /// ScanDirFillRildFromIse
2407 void ScanDirFillRildFromIse(struct ReadIconListData *rild, const struct IconScanEntry *ise)
2409 rild->rild_Type = ise->ise_Fib.fib_DirEntryType;
2410 rild->rild_Protection = ise->ise_Fib.fib_Protection;
2411 rild->rild_Size64 = ise->ise_Size64;
2412 rild->rild_DateStamp = ise->ise_Fib.fib_Date;
2413 rild->rild_IconType = ise->ise_IconType;
2414 rild->rild_TypeNode = NULL;
2415 rild->rild_SoloIcon = FALSE;
2417 d1(KPrintF("%s/%s/%ld: %08lx comment=%08lx fib_FileName=<%s>...fib_Comment=<%s>\n", \
2418 __FILE__, __FUNC__, __LINE__, rild->rild_Name, rild->rild_Comment, ise->ise_Fib.fib_FileName, ise->ise_Fib.fib_Comment));
2420 stccpy(rild->rild_Name, ise->ise_Fib.fib_FileName, sizeof(rild->rild_Name));
2421 stccpy(rild->rild_Comment, ise->ise_Fib.fib_Comment, sizeof(rild->rild_Comment));
2423 d1(KPrintF("%s/%s/%ld: END <%s> comment=<%s> IconType=%ld\n", \
2424 __FILE__, __FUNC__, __LINE__, rild->rild_Name, rild->rild_Comment, rild->rild_IconType));
2428 /// ScanDirUpdateStatusBarText
2429 void ScanDirUpdateStatusBarText(struct internalScaWindowTask *iwt, ULONG TotalIcons)
2431 if (iwt->iwt_StatusBar && iwt->iwt_StatusBarMembers[STATUSBARGADGET_StatusText])
2433 char StatusBarText[256];
2435 ScaFormatStringMaxLength(StatusBarText, sizeof(StatusBarText),
2436 GetLocString(MSGID_STATUSBARTEXT), TotalIcons, 0);
2438 d1(kprintf("%s/%s/%ld: StatusBarText=<%s>\n", __FILE__, __FUNC__, __LINE__, StatusBarText));
2440 DoMethod(iwt->iwt_WindowTask.mt_MainObject, SCCM_IconWin_UpdateStatusBar,
2441 iwt->iwt_StatusBarMembers[STATUSBARGADGET_StatusText],
2442 GBTDTA_Text, StatusBarText,
2443 TAG_END);
2448 /// IsFileHidden
2449 BOOL IsFileHidden(CONST_STRPTR Filename, ULONG Protection)
2451 if (CurrentPrefs.pref_HideHiddenFlag && ('.' == Filename[0]))
2452 return TRUE;
2454 if (CurrentPrefs.pref_HideProtectHiddenFlag && (Protection & FIBF_HIDDEN))
2455 return TRUE;
2457 return FALSE;
2461 /// AdjustIconType
2462 static ULONG AdjustIconType(Object *IconObj, LONG DirEntryType, BOOL isLink)
2464 IPTR IconType;
2465 ULONG NewIconType;
2467 GetAttr(IDTA_Type, IconObj, &IconType);
2468 NewIconType = IconType;
2470 d1(KPrintF("%s/%s/%ld: IconType=%lu DirEntryType=%ld\n", __FILE__, __FUNC__, __LINE__, IconType, DirEntryType));
2472 // Try to adjust IconType for icons with wrong type
2473 switch (DirEntryType)
2475 case ST_ROOT:
2476 if (isLink && WBDRAWER != IconType)
2478 NewIconType = WBDRAWER;
2480 if (!isLink && WBDISK != IconType)
2482 NewIconType = WBDISK;
2484 break;
2485 case ST_USERDIR:
2486 case ST_LINKDIR:
2487 if (WBDRAWER != IconType)
2489 NewIconType = WBDRAWER;
2491 break;
2492 case ST_FILE:
2493 case ST_LINKFILE:
2494 if (WBTOOL != IconType && WBPROJECT != IconType)
2496 NewIconType = WBPROJECT;
2498 break;
2499 default:
2500 break;
2503 d1(KPrintF("%s/%s/%ld: NewIconType=%lu\n", __FILE__, __FUNC__, __LINE__, NewIconType));
2504 if (IconType != NewIconType)
2506 SetAttrs(IconObj,
2507 IDTA_Type, NewIconType,
2508 TAG_END);
2511 return NewIconType;
2515 /// ScanDirFindIcon
2516 static BOOL ScanDirFindIcon(struct ReadIconListControl *rilc, CONST_STRPTR IconName)
2518 struct internalScaWindowTask *iwt = rilc->rilc_WindowTask;
2519 struct ScaIconNode *in;
2520 BOOL IconFound = FALSE;
2522 ScalosLockIconListShared(iwt);
2524 if (rilc)
2526 in = (struct ScaIconNode *) BTreeFind(rilc->rilc_IconTree, IconName);
2528 IconFound = NULL != in;
2530 else
2532 for (in=iwt->iwt_WindowTask.wt_IconList; !IconFound && in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
2534 if (0 == Stricmp((STRPTR) GetIconName(in), (STRPTR) IconName))
2536 d1(kprintf("%s/%s/%ld: Icon found <%s>\n", __FILE__, __FUNC__, __LINE__, GetIconName(in)));
2537 IconFound = TRUE;
2538 break;
2542 for (in=iwt->iwt_WindowTask.wt_LateIconList; !IconFound && in; in = (struct ScaIconNode *) in->in_Node.mln_Succ)
2544 if (0 == Stricmp((STRPTR) GetIconName(in), (STRPTR) IconName))
2546 d1(kprintf("%s/%s/%ld: Icon found <%s>\n", __FILE__, __FUNC__, __LINE__, GetIconName(in)));
2547 IconFound = TRUE;
2548 break;
2553 ScalosUnLockIconList(iwt);
2555 return IconFound;
2559 /// ScanDirIsError
2560 BOOL ScanDirIsError(enum ScanDirResult sdResult)
2562 BOOL isError;
2564 switch (sdResult)
2566 case SCANDIR_OK:
2567 case SCANDIR_ABORT:
2568 case SCANDIR_FINISHED:
2569 case SCANDIR_VIEWMODE_CHANGE:
2570 isError = FALSE;
2571 break;
2572 case SCANDIR_WINDOW_CLOSING:
2573 case SCANDIR_FAIL_ABORT:
2574 case SCANDIR_FAIL_RETRY:
2575 case SCANDIR_EXALL_FAIL:
2576 case SCANDIR_EXALL_BADNUMBER:
2577 default:
2578 isError = TRUE;
2579 break;
2582 return isError;