10 #include <exec/types.h>
11 #include <exec/execbase.h>
12 #include <exec/memory.h>
13 #include <dos/dosextens.h>
14 #include <dos/dostags.h>
15 #include <dos/filehandler.h>
17 #include <dos/anchorpath.h>
19 #include <libraries/iffparse.h>
20 #include <libraries/locale.h>
21 #include <intuition/intuitionbase.h>
22 #include <workbench/startup.h>
23 #include <workbench/workbench.h>
24 #include <utility/tagitem.h>
28 #include <proto/exec.h>
29 #include <proto/intuition.h>
30 #include <proto/dos.h>
32 #include <proto/icon.h>
33 #include <proto/utility.h>
34 #include <proto/locale.h>
35 #include <proto/iconobject.h>
37 #include <proto/scalos.h>
39 #include <clib/alib_protos.h>
42 #include <scalos/scalos.h>
50 #include "scalos_structures.h"
51 #include "FsAbstraction.h"
52 #include "functions.h"
53 #include "Variables.h"
55 //----------------------------------------------------------------------------
57 // local data structures
59 #define IOBUFFERLEN 480
60 #define NO_TYPE_NODE ((struct TypeNode *) -1)
62 #define DEFICON_THEME_PREFIX "THEME:DefIcons/def_"
63 #define DEFICON_PATH_PREFIX "def_"
65 //----------------------------------------------------------------------------
69 static void ReloadDefIcons(void);
71 static VOID
InitTypeTree(struct TypeNode
*parentnode
,STRPTR
*desclist
);
72 static struct TypeNode
*AllocTypeNode(STRPTR
*description
);
73 static VOID
AddSon(struct TypeNode
*parent
,struct TypeNode
*son
);
75 static LONG
match(CONST_STRPTR a
, CONST_STRPTR b
, size_t len
);
76 static struct TypeNode
*DefIconsIdentifyDisk(BPTR lock
);
77 static struct TypeNode
*DefIconsIdentifyProject(CONST_STRPTR Name
, T_ExamineData
*fib
);
78 static void DeleteTypeNode(struct TypeNode
*tn
);
79 static Object
*ReadDefIconObjectForName(ULONG IconType
, CONST_STRPTR TypeName
,
80 BPTR dirLock
, CONST_STRPTR OriginalName
, struct TagItem
*TagList
);
81 static Object
*ReadDefIconObjectForNameFallback(ULONG IconType
, CONST_STRPTR TypeName
,
82 BPTR dirLock
, CONST_STRPTR OriginalName
, struct TagItem
*TagList
);
83 static Object
*CloneDefIconObject(Object
*IconObj
, BPTR dirLock
,
84 CONST_STRPTR OriginalName
, struct TagItem
*TagList
);
85 static STRPTR
DefIconsGetDeviceName(CONST_STRPTR DosDevice
, ULONG
*DosType
);
87 //----------------------------------------------------------------------------
91 /* A table of clearly invalid ASCII characters (8 bits). */
92 static const UBYTE InvalidTab
[256] =
94 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,
95 1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,
96 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
97 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
98 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
99 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
100 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
101 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
102 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
103 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,
104 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
105 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
106 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
107 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
108 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
109 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
112 static struct TypeNode
*RootType
= NULL
;
113 static BPTR seglist
= (BPTR
)NULL
;
114 static BOOL DefIconsInit
= FALSE
;
115 static ULONG DefIconsPrefsCRC
= 0;
117 static Object
*CachedDefIconObjects
[1 + WBAPPICON
];
119 //----------------------------------------------------------------------------
122 SCALOSSEMAPHORE DefIconsSemaphore
;
123 SCALOSSEMAPHORE DefIconsCacheSemaphore
;
125 //----------------------------------------------------------------------------
127 LONG
InitDefIcons(void)
129 ScalosInitSemaphore(&DefIconsSemaphore
);
130 ScalosInitSemaphore(&DefIconsCacheSemaphore
);
140 static void ReloadDefIcons(void)
142 static CONST_STRPTR DefIconsPrefsFileName
= "ENV:deficons.prefs";
146 ScalosObtainSemaphore(&DefIconsSemaphore
);
148 DefIconsPrefsCRC
= GetPrefsCRCFromName(DefIconsPrefsFileName
);
149 seglist
= LoadSeg((STRPTR
) DefIconsPrefsFileName
);
151 d1(kprintf("%s/%s/%ld: SegList=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, seglist
));
157 inittable
= ((STRPTR
)BADDR(seglist
))+4;
158 InitTypeTree(NO_TYPE_NODE
, &inittable
);
160 d1(kprintf("%s/%s/%ld: RootType=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, RootType
));
163 ScalosReleaseSemaphore(&DefIconsSemaphore
);
167 void CleanupDefIcons(void)
173 ScalosObtainSemaphore(&DefIconsSemaphore
);
175 DeleteTypeNode(RootType
);
181 seglist
= (BPTR
)NULL
;
184 ScalosReleaseSemaphore(&DefIconsSemaphore
);
187 // Cleanup cached DefIcons
188 ScalosObtainSemaphore(&DefIconsCacheSemaphore
);
189 for (n
= 0; n
< Sizeof(CachedDefIconObjects
); n
++)
191 if (CachedDefIconObjects
[n
])
193 DisposeIconObject(CachedDefIconObjects
[n
]);
194 CachedDefIconObjects
[n
] = NULL
;
197 ScalosReleaseSemaphore(&DefIconsCacheSemaphore
);
201 void NewDefIconsPrefs(struct internalScaWindowTask
*iwt
, struct NotifyMessage
*msg
)
203 struct SM_NewPreferences
*smnp
;
205 d1(KPrintF("%s/%s/%ld: smnp_PrefsFlags=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, SMNPFLAGF_DEFICONSPREFS
));
207 smnp
= (struct SM_NewPreferences
*) SCA_AllocMessage(MTYP_NewPreferences
, 0);
210 smnp
->smnp_PrefsFlags
= SMNPFLAGF_DEFICONSPREFS
;
211 PutMsg(iInfos
.xii_iinfos
.ii_MainMsgPort
, &smnp
->ScalosMessage
.sm_Message
);
216 BOOL
ChangedDefIconsPrefs(void)
218 ULONG NewDefIconsPrefsCRC
;
219 BOOL Changed
= FALSE
;
221 NewDefIconsPrefsCRC
= GetPrefsCRCFromName("ENV:deficons.prefs");
222 d1(kprintf("%s/%s/%ld: NewDefIconsPrefsCRC=%08lx DefIconsPrefsCRC=%08lx\n",
223 __FILE__
, __FUNC__
, __LINE__
, NewDefIconsPrefsCRC
, DefIconsPrefsCRC
));
225 if (NewDefIconsPrefsCRC
!= DefIconsPrefsCRC
)
227 struct ScaWindowStruct
*ws
;
231 // Remove all references to DefIcons structure members
232 SCA_LockWindowList(SCA_LockWindowList_Shared
);
233 for (ws
=winlist
.wl_WindowStruct
; ws
; ws
= (struct ScaWindowStruct
*) ws
->ws_Node
.mln_Succ
)
235 struct internalScaWindowTask
*iwt
= (struct internalScaWindowTask
*) ws
->ws_WindowTask
;
237 DoMethod(iwt
->iwt_WindowTask
.mt_WindowObject
, SCCM_IconWin_ClearIconFileTypes
);
239 SCA_UnLockWindowList();
241 FileTypeFlush(FALSE
);
249 static VOID
InitTypeTree(struct TypeNode
*parentnode
,STRPTR
*desclist
)
251 struct TypeNode
*newTn
= NULL
;
257 case TYPE_DOWN_LEVEL
:
259 InitTypeTree(newTn
, desclist
);
264 /* fall thru next case */
270 if ((newTn
= AllocTypeNode(desclist
))) /* desclist will be incremented by */
273 if (parentnode
!= NO_TYPE_NODE
)
275 AddSon(parentnode
, newTn
);
280 RootType
->tn_RightBrother
= newTn
;
292 static struct TypeNode
*AllocTypeNode(STRPTR
*description
)
301 arg
= name
+ strlen(name
) + 1;
302 while (*arg
!= ACT_END
)
308 arg
= arg
+ 3 + abs((BYTE
)arg
[2]);
311 case ACT_SEARCHSKIPSPACES
:
312 arg
= arg
+ 1 + abs((BYTE
)arg
[0]);
321 case ACT_NAMEPATTERN
:
325 arg
= arg
+ strlen(arg
) + 1;
328 arg
= arg
+ 1 + arg
[0];
333 if ((nd
= ScalosAlloc(sizeof(struct TypeNode
) + j
* sizeof(struct Magic
))))
335 nd
->tn_RightBrother
= nd
->tn_FirstSon
= nd
->tn_Parent
= NULL
;
336 nd
->tn_IconObject
= NULL
;
340 arg
= name
+ strlen(name
) + 1;
341 while (*arg
!= ACT_END
)
343 switch(nd
->tn_Description
[j
].action
= *(arg
++))
346 nd
->tn_Description
[j
].arg1
= *(arg
++);
347 nd
->tn_Description
[j
].arg1
<<= 8;
348 nd
->tn_Description
[j
].arg1
|= *(arg
++);
349 nd
->tn_Description
[j
].arg2
= (BYTE
)*(arg
++);
350 nd
->tn_Description
[j
].str
= (STRPTR
) arg
;
351 arg
+= abs(nd
->tn_Description
[j
].arg2
);
354 case ACT_SEARCHSKIPSPACES
:
355 nd
->tn_Description
[j
].arg2
= (BYTE
)*(arg
++);
356 nd
->tn_Description
[j
].str
= arg
;
357 arg
+= abs(nd
->tn_Description
[j
].arg2
);
361 nd
->tn_Description
[j
].arg2
= *(arg
++);
362 nd
->tn_Description
[j
].arg2
<<= 8;
363 nd
->tn_Description
[j
].arg2
|= *(arg
++);
364 nd
->tn_Description
[j
].arg2
<<= 8;
365 nd
->tn_Description
[j
].arg2
|= *(arg
++);
366 nd
->tn_Description
[j
].arg2
<<= 8;
367 nd
->tn_Description
[j
].arg2
|= *(arg
++);
370 nd
->tn_Description
[j
].arg2
= (BYTE
)*(arg
++);
371 nd
->tn_Description
[j
].str
= (STRPTR
) arg
;
372 arg
+= nd
->tn_Description
[j
].arg2
;
374 case ACT_NAMEPATTERN
:
378 nd
->tn_Description
[j
].str
= arg
;
379 arg
+= strlen(arg
) + 1;
382 nd
->tn_Description
[j
].arg1
= *(arg
++);
383 nd
->tn_Description
[j
].arg1
<<= 8;
384 nd
->tn_Description
[j
].arg1
|= *(arg
++);
385 nd
->tn_Description
[j
].arg1
<<= 8;
386 nd
->tn_Description
[j
].arg1
|= *(arg
++);
387 nd
->tn_Description
[j
].arg1
<<= 8;
388 nd
->tn_Description
[j
].arg1
|= *(arg
++);
389 nd
->tn_Description
[j
].arg2
= *(arg
++);
390 nd
->tn_Description
[j
].arg2
<<= 8;
391 nd
->tn_Description
[j
].arg2
|= *(arg
++);
392 nd
->tn_Description
[j
].arg2
<<= 8;
393 nd
->tn_Description
[j
].arg2
|= *(arg
++);
394 nd
->tn_Description
[j
].arg2
<<= 8;
395 nd
->tn_Description
[j
].arg2
|= *(arg
++);
401 nd
->tn_Description
[j
].action
= ACT_END
;
404 *description
= arg
+1; /* increment *description for recursion */
411 static VOID
AddSon(struct TypeNode
*parent
,struct TypeNode
*son
)
418 if ((nd
= parent
->tn_FirstSon
))
420 while (nd
->tn_RightBrother
)
421 nd
= nd
->tn_RightBrother
;
423 nd
->tn_RightBrother
= son
;
426 parent
->tn_FirstSon
= son
;
428 son
->tn_Parent
= parent
;
433 /* compare two buffers of length 'len'. These functions cannot be replaced */
434 /* with strn(i)cmp() because the buffers may contain NULLs */
435 static LONG
match(CONST_STRPTR a
, CONST_STRPTR b
, size_t len
)
437 if (len
> 0) /* case sensitive */
448 else /* ignore case */
450 while (toupper(*a
) == toupper(*b
))
452 if (!(++len
)) return(0);
464 /* DefIconsIdentify(BPTR dirLock, CONST_STRPTR *Name, ULONG IconType):
466 * Heuristically identify the type of a file.
468 * IMPORTANT: this function usually returns a TypeNode *, but may also return
469 * one of the special values WBDISK and WBDRAWER
470 it returns NULL for failure
473 struct TypeNode
*DefIconsIdentify(BPTR dirLock
, CONST_STRPTR Name
, IPTR IconType
)
475 struct TypeNode
*type
= NULL
;
476 T_ExamineData
*fib
= NULL
;
480 debugLock_d1(dirLock
);
481 d1(KPrintF("%s/%s/%ld: Name=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, Name
));
483 oldDirLock
= CurrentDir(dirLock
);
485 if ((lock
= Lock((STRPTR
) Name
, ACCESS_READ
)) && ScalosExamineBegin(&fib
) &&
486 ScalosExamineLock(lock
, &fib
))
490 if (ScalosExamineIsDrawer(fib
))
494 if ((dirlock
= ParentDir(lock
)))
498 type
= (struct TypeNode
*) WBDRAWER
;
501 // extra check for WBGARBAGE
502 IconObj
= NewIconObjectTags(Name
,
506 GetAttr(IDTA_Type
, IconObj
, (APTR
) &type
);
507 DisposeIconObject(IconObj
);
512 type
= DefIconsIdentifyDisk(lock
);
517 type
= DefIconsIdentifyProject(Name
, fib
);
522 d1(KPrintF("%s/%s/%ld: Name=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, Name
));
524 if (!stricmp(Name
, "disk"))
528 curdir
= CurrentDir((BPTR
)NULL
);
531 if ((lock
= ParentDir(curdir
)))
534 type
= (struct TypeNode
*)WBDISK
;
536 else if (ICONTYPE_NONE
!= IconType
)
538 type
= (struct TypeNode
*) IconType
;
542 ScalosExamineEnd(&fib
);
546 CurrentDir(oldDirLock
);
548 d1(KPrintF("%s/%s/%ld: type=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, type
));
554 static struct TypeNode
*DefIconsIdentifyDisk(BPTR lock
)
556 struct InfoData
*infoData
= NULL
;
557 struct TypeNode
*type
= (struct TypeNode
*) WBDISK
;
558 STRPTR AllocatedDevName
= NULL
;
562 ScalosObtainSemaphoreShared(&DefIconsSemaphore
);
565 struct TypeNode
*candidate
;
567 const struct DosList
*VolumeNode
;
568 CONST_STRPTR DosDevice
= "";
569 CONST_STRPTR DeviceName
= "";
570 ULONG DosType
= MAKE_ID('D','O','S',0);
573 while (tn
&& 0 != Stricmp(tn
->tn_Name
, "disk"))
574 tn
= tn
->tn_RightBrother
;
579 infoData
= ScalosAllocInfoData();
580 if (NULL
== infoData
)
583 if (!Info(lock
, infoData
))
587 d1(KPrintF("%s/%s/%ld: type=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, type
->tn_Name
));
588 d1(KPrintF("%s/%s/%ld: id_NumBlocks=%lu id_DiskType=%08lx id_VolumeNode=%08lx\n", \
589 __FILE__
, __FUNC__
, __LINE__
, \
590 infoData
->id_NumBlocks
, infoData
->id_DiskType
, infoData
->id_VolumeNode
));
592 VolumeNode
= BADDR(infoData
->id_VolumeNode
);
593 if (TypeOfMem((APTR
) VolumeNode
) & MEMF_PUBLIC
)
595 d1(KPrintF("%s/%s/%ld: dol_Type=%ld dol_Name=%08lx dol_Task=%08lx\n", \
596 __FILE__
, __FUNC__
, __LINE__
, VolumeNode
->dol_Type
, VolumeNode
->dol_Name
, VolumeNode
->dol_Task
));
598 if (VolumeNode
->dol_Task
&& (TypeOfMem(VolumeNode
->dol_Task
) & MEMF_PUBLIC
))
600 struct Task
*DevTask
= VolumeNode
->dol_Task
->mp_SigTask
;
602 d1(KPrintF("%s/%s/%ld: dol_DiskType=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, VolumeNode
->dol_misc
.dol_volume
.dol_DiskType
));
604 DosDevice
= DevTask
->tc_Node
.ln_Name
;
605 d1(KPrintF("%s/%s/%ld: DevTask=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, DosDevice
));
607 AllocatedDevName
= DefIconsGetDeviceName(DosDevice
, &DosType
);
608 if (AllocatedDevName
)
609 DeviceName
= AllocatedDevName
;
610 d1(KPrintF("%s/%s/%ld: DeviceName=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, DeviceName
));
614 candidate
= type
->tn_FirstSon
;
622 curr
= candidate
->tn_Description
;
626 switch (curr
->action
)
632 goto loop
; /* ////// */
640 goto loop
; /* ////// */
650 case ACT_SEARCHSKIPSPACES
:
652 case ACT_NAMEPATTERN
:
661 ULONG BlocksPerMByte
= (1024 * 1024) / infoData
->id_BytesPerBlock
;
663 d1(KPrintF("%s/%s/%ld: BlocksPerMByte=%lu id_NumBlocks=%lu\n", __FILE__
, __FUNC__
, __LINE__
, BlocksPerMByte
, infoData
->id_NumBlocks
));
665 if ((infoData
->id_NumBlocks
/ BlocksPerMByte
) < curr
->arg2
)
676 if (ParsePatternNoCase(curr
->str
, (STRPTR
) buf
, sizeof(buf
)) >= 0 &&
677 MatchPatternNoCase((STRPTR
) buf
, (STRPTR
) DosDevice
))
688 if (ParsePatternNoCase(curr
->str
, (STRPTR
) buf
, sizeof(buf
)) >= 0 &&
689 MatchPatternNoCase((STRPTR
) buf
, (STRPTR
) DeviceName
))
697 UBYTE DosTypeString
[5];
699 memcpy(DosTypeString
, &DosType
, sizeof(DosType
));
700 DosTypeString
[4] = '\0';
702 d1(KPrintF("%s/%s/%ld: arg2=%ld DosType=<%s> str=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, curr
->arg2
, DosTypeString
, curr
->str
));
704 if (abs(curr
->arg2
) > sizeof(ULONG
) ||
705 match((CONST_STRPTR
)DosTypeString
, curr
->str
, curr
->arg2
))
717 struct AnchorPath
*ap
;
718 BPTR OldDir
= CurrentDir(lock
);
722 ap
= ScalosAllocAnchorPath(APF_DOWILD
, 0);
725 result
= MatchFirst(curr
->str
, ap
);
726 if (RETURN_OK
== result
)
729 d1(KPrintF("%s/%s/%ld: str=<%s> result=%ld\n", __FILE__
, __FUNC__
, __LINE__
, curr
->str
, result
));
732 ScalosFreeAnchorPath(ap
);
739 } while ((curr
++)->action
!= ACT_END
);
741 candidate
= candidate
->tn_RightBrother
;
744 /* don't consider valid a macroclass alone */
745 if (type
->tn_Description
->action
== ACT_MACROCLASS
)
747 candidate
= type
->tn_RightBrother
;
748 type
= type
->tn_Parent
;
749 goto loop1
; /* ////// */
753 ScalosReleaseSemaphore(&DefIconsSemaphore
);
755 if (AllocatedDevName
)
756 ScalosFree(AllocatedDevName
);
757 ScalosFreeInfoData(&infoData
);
763 static struct TypeNode
*DefIconsIdentifyProject(CONST_STRPTR Name
, T_ExamineData
*fib
)
765 UBYTE
*Buffer
= NULL
;
766 BPTR File
= (BPTR
) NULL
;
767 struct TypeNode
*type
= (struct TypeNode
*) WBPROJECT
;
770 ScalosObtainSemaphoreShared(&DefIconsSemaphore
);
773 while (tn
&& 0 != Stricmp(tn
->tn_Name
, "project"))
774 tn
= tn
->tn_RightBrother
;
776 if (tn
&& (Buffer
= ScalosAlloc(IOBUFFERLEN
)) && (File
= Open((STRPTR
) Name
,MODE_OLDFILE
)))
782 d1(KPrintF("%s/%s/%ld: fib_FileName=<%s> type=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, fib
->fib_FileName
, type
->tn_Name
));
784 /* Read the first IOBUFFERLEN bytes. */
785 if ((Size
= Read(File
,Buffer
,IOBUFFERLEN
)) >= 0)
787 struct TypeNode
*candidate
;
791 candidate
= type
->tn_FirstSon
;
799 curr
= candidate
->tn_Description
;
804 switch (curr
->action
)
810 goto loop
; /* ////// */
818 goto loop
; /* ////// */
830 if (Size
- (buf
- Buffer
) < curr
->arg1
+ abs(curr
->arg2
) ||
831 match((STRPTR
)&buf
[curr
->arg1
],curr
->str
,abs(curr
->arg2
)))
837 case ACT_SEARCHSKIPSPACES
:
843 loop
= Size
- (buf
- Buffer
) - abs(curr
->arg2
);
847 if (!match((STRPTR
)buf
,curr
->str
,curr
->arg2
))
850 if (curr
->action
== ACT_SEARCHSKIPSPACES
&& !isspace(*buf
))
859 if (loop
< 0) matching
= 0;
866 if (0 != Cmp64(ScalosExamineGetSize(fib
), MakeU64(curr
->arg2
)))
867 //if (fib->fib_Size != curr->arg2)
872 case ACT_NAMEPATTERN
:
878 if (ParsePatternNoCase(curr
->str
,(STRPTR
)buf
,sizeof(buf
)) >= 0 &&
879 MatchPatternNoCase((STRPTR
)buf
, (STRPTR
)ScalosExamineGetName(fib
)))
887 if ((ScalosExamineGetProtection(fib
) & curr
->arg1
) != curr
->arg2
)
900 while (buf
> Buffer
&& !InvalidTab
[*(--buf
)]);
902 if (buf
== Buffer
) matching
= 1;
914 } while ((curr
++)->action
!= ACT_END
);
916 candidate
= candidate
->tn_RightBrother
;
919 /* don't consider valid a macroclass alone */
920 if (type
->tn_Description
->action
== ACT_MACROCLASS
)
922 candidate
= type
->tn_RightBrother
;
923 type
= type
->tn_Parent
;
924 goto loop1
; /* ////// */
927 if (!stricmp(type
->tn_Name
,"iff"))
929 struct TypeNode
*new;
933 if ((desc
= ScalosAlloc(14)))
937 strncpy(desc
,(char *)&Buffer
[8],4);
943 strncpy(&desc
[9],(char *)&Buffer
[8],4);
946 if ((new = AllocTypeNode(&descp
)))
959 ScalosReleaseSemaphore(&DefIconsSemaphore
);
969 static void DeleteTypeNode(struct TypeNode
*tn
)
973 struct TypeNode
*tnNext
= tn
->tn_RightBrother
;
975 DeleteTypeNode(tn
->tn_FirstSon
);
977 if (tn
->tn_IconObject
)
979 DisposeIconObject(tn
->tn_IconObject
);
980 tn
->tn_IconObject
= NULL
;
989 Object
*ReturnDefIconObjTags(BPTR dirLock
, CONST_STRPTR Name
, ULONG FirstTag
, ...)
992 struct TagItem
*TagList
;
995 d1(KPrintF("%s/%s/%ld: Name=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, Name
));
997 va_start(args
, FirstTag
);
999 TagList
= ScalosVTagList(FirstTag
, args
);
1003 o
= ReturnDefIconObj(dirLock
, Name
, TagList
);
1004 FreeTagItems(TagList
);
1012 Object
*ReturnDefIconObj(BPTR dirLock
, CONST_STRPTR Name
, struct TagItem
*TagList
)
1014 struct TypeNode
*tn
;
1015 Object
*IconObj
= NULL
;
1017 if (Name
&& strlen(Name
) > 0)
1018 tn
= DefIconsIdentify(dirLock
, Name
, GetTagData(IDTA_Type
, ICONTYPE_NONE
, TagList
));
1020 tn
= DefIconsIdentifyDisk(dirLock
);
1022 d1(KPrintF("%s/%s/%ld: tn=%08lx Name=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, tn
, Name
));
1023 debugLock_d1(dirLock
);
1028 IconObj
= ReadDefIconObjectForNameFallback(WBDISK
,
1029 "disk", dirLock
, Name
, TagList
);
1030 d1(KPrintF("%s/%s/%ld: WBDISK IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1034 IconObj
= ReadDefIconObjectForNameFallback(WBDRAWER
,
1035 "drawer", dirLock
, Name
, TagList
);
1036 d1(KPrintF("%s/%s/%ld: WBDRAWER IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1040 IconObj
= ReadDefIconObjectForNameFallback(WBAPPICON
,
1041 "appicon", dirLock
, Name
, TagList
);
1042 d1(KPrintF("%s/%s/%ld: WBAPPICON IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1043 if (NULL
== IconObj
)
1045 IconObj
= ReadDefIconObjectForNameFallback(WBPROJECT
,
1046 "project", dirLock
, Name
, TagList
);
1048 d1(KPrintF("%s/%s/%ld: WBAPPICON IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1052 IconObj
= ReadDefIconObjectForNameFallback(WBPROJECT
,
1053 "project", dirLock
, Name
, TagList
);
1054 d1(KPrintF("%s/%s/%ld: ??? IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1058 if (IS_TYPENODE(tn
))
1060 d1(KPrintF("%s/%s/%ld: tn=%08lx tn_IconObject=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, tn
, tn
->tn_IconObject
));
1061 if (tn
->tn_IconObject
)
1063 // We have a cached iconObject, try to clone it now
1064 IconObj
= CloneDefIconObject(tn
->tn_IconObject
, dirLock
, Name
, TagList
);
1065 d1(KPrintF("%s/%s/%ld: CloneDefIconObject returned IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1068 d1(KPrintF("%s/%s/%ld: IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1069 if (NULL
== IconObj
)
1071 struct TypeNode
*tn2
= tn
;
1073 while (tn2
&& NULL
== IconObj
)
1075 IconObj
= ReadDefIconObjectForName(WBPROJECT
,
1076 tn2
->tn_Name
, dirLock
, Name
, TagList
);
1078 d1(KPrintF("%s/%s/%ld: IconObj=%08lx tn2=%08lx <%s> Parent=%08lx\n", \
1079 __FILE__
, __FUNC__
, __LINE__
, IconObj
, tn2
, tn2
->tn_Name
, tn2
->tn_Parent
));
1080 tn2
= tn2
->tn_Parent
;
1083 d1(KPrintF("%s/%s/%ld: IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1084 tn
->tn_IconObject
= IconObj
;
1085 if (tn
->tn_IconObject
)
1087 IconObj
= CloneDefIconObject(tn
->tn_IconObject
, dirLock
, Name
, TagList
);
1088 d1(KPrintF("%s/%s/%ld: CloneDefIconObject returned IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1089 if (NULL
== IconObj
)
1092 IconObj
= tn
->tn_IconObject
;
1093 tn
->tn_IconObject
= NULL
;
1098 if (NULL
== IconObj
)
1100 IconObj
= GetDefIconObjectTags(WBPROJECT
,
1101 IDTA_Text
, (IPTR
) Name
,
1102 TAG_MORE
, (IPTR
) TagList
,
1108 d1(KPrintF("%s/%s/%ld: IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1114 static Object
*ReadDefIconObjectForName(ULONG IconType
, CONST_STRPTR TypeName
,
1115 BPTR dirLock
, CONST_STRPTR OriginalName
, struct TagItem
*TagList
)
1118 Object
*IconObj
= NULL
;
1120 DefIconPath
= AllocPathBuffer();
1121 d1(KPrintF("%s/%s/%ld: DefIconPath=%08lx TypeName=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, \
1122 DefIconPath
, TypeName
));
1125 struct WBArg OriginalLocation
;
1127 strcpy(DefIconPath
, DEFICON_THEME_PREFIX
);
1128 SafeStrCat(DefIconPath
, TypeName
, Max_PathLen
);
1130 OriginalLocation
.wa_Lock
= dirLock
;
1131 OriginalLocation
.wa_Name
= (STRPTR
) OriginalName
;
1133 d1(KPrintF("%s/%s/%ld: DefIconPath=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, DefIconPath
));
1135 IconObj
= (Object
*) NewIconObjectTags(DefIconPath
,
1136 IDTA_IconLocation
, (IPTR
) &OriginalLocation
,
1137 IDTA_SupportedIconTypes
, GetTagData(IDTA_SupportedIconTypes
, CurrentPrefs
.pref_SupportedIconTypes
, TagList
),
1138 IDTA_SizeConstraints
, GetTagData(IDTA_SizeConstraints
, (IPTR
) &CurrentPrefs
.pref_IconSizeConstraints
, TagList
),
1139 IDTA_ScalePercentage
, GetTagData(IDTA_ScalePercentage
, CurrentPrefs
.pref_IconScaleFactor
, TagList
),
1140 TagList
? TAG_MORE
: TAG_IGNORE
, (IPTR
) TagList
,
1143 d1(kprintf("%s/%s/%ld: IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1145 if (NULL
== IconObj
)
1147 stccpy(DefIconPath
, CurrentPrefs
.pref_DefIconPath
, Max_PathLen
);
1148 AddPart(DefIconPath
, DEFICON_PATH_PREFIX
, Max_PathLen
);
1149 SafeStrCat(DefIconPath
, TypeName
, Max_PathLen
);
1151 d1(KPrintF("%s/%s/%ld: DefIconPath=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, DefIconPath
));
1153 IconObj
= (Object
*) NewIconObjectTags(DefIconPath
,
1154 IDTA_IconLocation
, (IPTR
) &OriginalLocation
,
1155 IDTA_SupportedIconTypes
, GetTagData(IDTA_SupportedIconTypes
, CurrentPrefs
.pref_SupportedIconTypes
, TagList
),
1156 IDTA_SizeConstraints
, GetTagData(IDTA_SizeConstraints
, (IPTR
) &CurrentPrefs
.pref_IconSizeConstraints
, TagList
),
1157 IDTA_ScalePercentage
, GetTagData(IDTA_ScalePercentage
, CurrentPrefs
.pref_IconScaleFactor
, TagList
),
1158 TagList
? TAG_MORE
: TAG_IGNORE
, (IPTR
) TagList
,
1161 d1(kprintf("%s/%s/%ld: IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1164 FreePathBuffer(DefIconPath
);
1167 d1(KPrintF("%s/%s/%ld: IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1173 static Object
*ReadDefIconObjectForNameFallback(ULONG IconType
, CONST_STRPTR TypeName
,
1174 BPTR dirLock
, CONST_STRPTR OriginalName
, struct TagItem
*TagList
)
1176 Object
*IconObj
= NULL
;
1178 ScalosObtainSemaphoreShared(&DefIconsCacheSemaphore
);
1179 if (IconType
>= WBDISK
&& IconType
<= WBAPPICON
&& CachedDefIconObjects
[IconType
])
1181 // We have a cached iconObject, try to clone it now
1182 IconObj
= CloneDefIconObject(CachedDefIconObjects
[IconType
], dirLock
, OriginalName
, TagList
);
1183 d1(KPrintF("%s/%s/%ld: CloneDefIconObject returned IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1185 ScalosReleaseSemaphore(&DefIconsCacheSemaphore
);
1187 if (NULL
== IconObj
)
1189 IconObj
= ReadDefIconObjectForName(IconType
, TypeName
,
1190 dirLock
, OriginalName
, TagList
);
1192 if (IconType
>= WBDISK
&& IconType
<= WBAPPICON
&& IconObj
)
1194 ScalosObtainSemaphore(&DefIconsCacheSemaphore
);
1196 if (CachedDefIconObjects
[IconType
])
1197 DisposeIconObject(CachedDefIconObjects
[IconType
]);
1199 CachedDefIconObjects
[IconType
] = IconObj
;
1200 IconObj
= CloneDefIconObject(CachedDefIconObjects
[IconType
], dirLock
, OriginalName
, TagList
);
1201 d1(KPrintF("%s/%s/%ld: IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1202 if (NULL
== IconObj
)
1205 IconObj
= CachedDefIconObjects
[IconType
];
1206 CachedDefIconObjects
[IconType
] = NULL
;
1209 ScalosReleaseSemaphore(&DefIconsCacheSemaphore
);
1213 IconObj
= GetDefIconObjectTags(IconType
,
1214 IDTA_Text
, (IPTR
) OriginalName
,
1215 TAG_MORE
, (IPTR
) TagList
,
1224 static Object
*CloneDefIconObject(Object
*IconObj
, BPTR dirLock
,
1225 CONST_STRPTR OriginalName
, struct TagItem
*TagList
)
1227 struct WBArg OriginalLocation
;
1228 struct TagItem CloneTags
[6];
1230 if (NULL
== IconObj
)
1233 OriginalLocation
.wa_Lock
= dirLock
;
1234 OriginalLocation
.wa_Name
= (STRPTR
) OriginalName
;
1236 d1(KPrintF("%s/%s/%ld: DefIconPath=<%s>\n", __FILE__
, __FUNC__
, __LINE__
, OriginalName
));
1237 d1(KPrintF("%s/%s/%ld: IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1239 CloneTags
[0].ti_Tag
= IDTA_IconLocation
;
1240 CloneTags
[0].ti_Data
= (IPTR
) &OriginalLocation
;
1242 CloneTags
[1].ti_Tag
= IDTA_SupportedIconTypes
;
1243 CloneTags
[1].ti_Data
= GetTagData(IDTA_SupportedIconTypes
, CurrentPrefs
.pref_SupportedIconTypes
, TagList
);
1245 CloneTags
[2].ti_Tag
= IDTA_SizeConstraints
;
1246 CloneTags
[2].ti_Data
= GetTagData(IDTA_SizeConstraints
, (IPTR
) &CurrentPrefs
.pref_IconSizeConstraints
, TagList
);
1248 CloneTags
[3].ti_Tag
= IDTA_ScalePercentage
;
1249 CloneTags
[3].ti_Data
= GetTagData(IDTA_ScalePercentage
, CurrentPrefs
.pref_IconScaleFactor
, TagList
);
1251 CloneTags
[4].ti_Tag
= TagList
? TAG_MORE
: TAG_IGNORE
;
1252 CloneTags
[4].ti_Data
= (IPTR
) TagList
;
1254 CloneTags
[5].ti_Tag
= TAG_END
;
1255 CloneTags
[5].ti_Data
= 0;
1257 IconObj
= (Object
*) DoMethod(IconObj
,
1258 IDTM_CloneIconObject
, CloneTags
);
1260 d1(KPrintF("%s/%s/%ld: IconObj=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, IconObj
));
1266 // DosDevice : DOS device name ("DH0"), without trailing ":"
1267 static STRPTR
DefIconsGetDeviceName(CONST_STRPTR DosDevice
, ULONG
*DosType
)
1269 STRPTR DevName
= NULL
;
1273 struct FileSysStartupMsg
*fssm
;
1274 struct DosEnvec
*env
;
1275 CONST_STRPTR BDevName
;
1278 dl
= LockDosList(LDF_DEVICES
| LDF_READ
);
1280 dl
= FindDosEntry(dl
, DosDevice
, LDF_DEVICES
);
1284 if (BNULL
== dl
->dol_misc
.dol_handler
.dol_Startup
)
1287 fssm
= BADDR(dl
->dol_misc
.dol_handler
.dol_Startup
);
1288 if (!(TypeOfMem(fssm
) & MEMF_PUBLIC
))
1291 if (BNULL
== fssm
->fssm_Device
)
1294 BDevName
= BADDR(fssm
->fssm_Device
);
1295 if (!(TypeOfMem((APTR
) BDevName
) & MEMF_PUBLIC
))
1298 Length
= BDevName
[0];
1299 DevName
= ScalosAlloc(1 + Length
);
1300 if (NULL
== DevName
)
1303 memcpy(DevName
, BDevName
+ 1, Length
);
1304 DevName
[Length
] = '\0';
1306 env
= BADDR(fssm
->fssm_Environ
);
1309 if (!(TypeOfMem((APTR
) env
) & MEMF_PUBLIC
))
1312 *DosType
= env
->de_DosType
;
1315 UnLockDosList(LDF_DEVICES
| LDF_READ
);