Forward compatibility: build relative-base link libraries where needed
[AROS.git] / workbench / libs / icon / identify.c
blob9907a58fe05c83ccbc782b569b899da17fcc980a
1 /*
2 Copyright © 2003-2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
8 #include <dos/dos.h>
9 #include <dos/dosextens.h>
10 #include <workbench/workbench.h>
11 #include <workbench/icon.h>
12 #include <datatypes/datatypes.h>
13 #include <datatypes/datatypesclass.h>
14 #include <utility/hooks.h>
16 #include <proto/exec.h>
17 #include <proto/dos.h>
18 #include <proto/icon.h>
19 #include <proto/utility.h>
20 #include <proto/datatypes.h>
22 #include "icon_intern.h"
24 #include <string.h>
26 #ifndef ID_FAT12_DISK
27 #define ID_FAT12_DISK AROS_MAKE_ID('F','A','T',0) /* FAT12 */
28 #define ID_FAT16_DISK AROS_MAKE_ID('F','A','T',1) /* FAT16 */
29 #define ID_FAT32_DISK AROS_MAKE_ID('F','A','T',2) /* FAT32 */
30 #endif
31 #ifndef ID_CDFS_DISK
32 #define ID_CDFS_DISK AROS_MAKE_ID('C','D','F','S') /* CDFS */
33 #endif
35 /*** Prototypes *************************************************************/
36 BOOL __FindDeviceName_WB(STRPTR buffer, LONG length, BPTR lock, APTR *theDOSBase);
37 struct DiskObject *__GetDefaultIconFromName_WB(CONST_STRPTR name, const struct TagItem *tags, struct IconBase *IconBase);
38 struct DiskObject *__GetDefaultIconFromType_WB(LONG type, const struct TagItem *tags, struct IconBase *IconBase);
39 LONG __FindDiskType_WB(STRPTR volname, BPTR lock, struct IconBase *IconBase);
41 /*** Macros *****************************************************************/
42 #define FindDeviceName(buffer, length, volume) (__FindDeviceName_WB((buffer), (length), (volume), DOSBase))
43 #define GetDefaultIconFromName(name, tags) (__GetDefaultIconFromName_WB((name), (tags), IconBase))
44 #define GetDefaultIconFromType(type, tags) (__GetDefaultIconFromType_WB((type), (tags), IconBase))
45 #define FindDiskType(volname, lock) (__FindDiskType_WB((volname),(lock),IconBase))
46 /*** Functions **************************************************************/
47 LONG __FindType_WB(BPTR lock, struct IconBase *IconBase)
49 LONG type = -1;
50 struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, TAG_DONE);
52 if (fib != NULL)
54 if (Examine(lock, fib))
56 D(bug("[%s] Examine says: fib_DirEntryType=%d\n", __func__, fib->fib_DirEntryType));
57 D(bug("[%s] Examine says: fib_Protection=%x\n", __func__, fib->fib_Protection));
58 /* Identify object ---------------------------------------------*/
59 if (fib->fib_DirEntryType == ST_ROOT)
61 /* It's a disk/volume/root ---------------------------------*/
62 type = WBDISK;
64 else if (fib->fib_DirEntryType > 0)
66 /* It's a directory ----------------------------------------*/
67 type = WBDRAWER;
69 else
71 /* It's a file ---------------------------------------------*/
72 if (DataTypesBase != NULL)
74 /* Use datatypes to identify the file ------------------*/
75 struct DataType *dt = ObtainDataType
77 DTST_FILE, (APTR)lock, TAG_DONE
80 if (dt != NULL)
82 struct DataTypeHeader *dth = dt->dtn_Header;
86 dth->dth_GroupID == GID_SYSTEM
87 && dth->dth_ID == ID_EXECUTABLE
90 /* It's an executable file */
91 type = WBTOOL;
93 else
95 /* It's a project file of some kind */
96 type = WBPROJECT;
99 ReleaseDataType(dt);
103 if (type == -1)
105 /* Fallback to a more primitive identification ---------*/
106 if ((fib->fib_Protection & FIBF_EXECUTE) == 0)
108 type = WBTOOL;
110 else
112 type = WBPROJECT;
119 FreeDosObject(DOS_FIB, fib);
122 return type;
125 struct DiskObject *__FindDefaultIcon_WB
127 struct IconIdentifyMsg *iim, struct IconBase *IconBase
130 struct DiskObject *icon = NULL;
132 /* Identify object -----------------------------------------------------*/
133 if (iim->iim_FIB->fib_DirEntryType == ST_ROOT)
135 /* It's a disk/volume/root -------------------------------------*/
136 TEXT device[MAXFILENAMELENGTH];
140 FindDeviceName
142 device, MAXFILENAMELENGTH,
143 iim->iim_FileLock
147 BPTR lock = Lock(device, SHARED_LOCK);
148 LONG type = FindDiskType(iim->iim_FIB->fib_FileName, lock);
149 UnLock(lock);
150 if (strlen(device) <= 5)
152 if (strcasecmp(device, "RAM:") == 0)
154 icon = GetDefaultIconFromName("RAM", iim->iim_Tags);
156 else if (strncasecmp(device, "RAD", 3) == 0)
158 icon = GetDefaultIconFromName("RAD", iim->iim_Tags);
160 else if (strncasecmp(device, "DF", 2) == 0)
162 icon = GetDefaultIconFromName("Floppy", iim->iim_Tags);
164 else if (strncasecmp(device, "CD", 2) == 0)
166 icon = GetDefaultIconFromName("CDROM", iim->iim_Tags);
168 else if
170 strncasecmp(device, "DH", 2) == 0
171 || strncasecmp(device, "HD", 2) == 0
172 || strncasecmp(device, "EMU", 3) == 0
175 icon = GetDefaultIconFromName("Harddisk", iim->iim_Tags);
177 else if (strcasecmp(device, "HOME") == 0)
179 icon = GetDefaultIconFromName("Home", iim->iim_Tags);
181 else if (type)
183 D(bug("[icon] Identify Type: 0x%8x\n",type));
184 switch(type)
186 case ID_MSDOS_DISK:
187 case ID_FAT12_DISK:
188 case ID_FAT16_DISK:
189 case ID_FAT32_DISK:
190 icon = GetDefaultIconFromName("FAT", iim->iim_Tags);
191 break;
192 case ID_SFS_BE_DISK:
193 case ID_SFS_LE_DISK:
194 icon = GetDefaultIconFromName("SFS", iim->iim_Tags);
195 break;
196 case ID_FFS_DISK:
197 case ID_INTER_DOS_DISK:
198 case ID_INTER_FFS_DISK:
199 case ID_FASTDIR_DOS_DISK:
200 case ID_FASTDIR_FFS_DISK:
201 icon = GetDefaultIconFromName("ADF", iim->iim_Tags);
202 break;
203 case ID_CDFS_DISK:
204 icon = GetDefaultIconFromName("CDROM", iim->iim_Tags);
205 break;
206 default:
207 icon = GetDefaultIconFromName("Disk", iim->iim_Tags);
208 break;
212 else if (strncasecmp(device, "USB", 3) ==0)
214 icon = GetDefaultIconFromName("USB", iim->iim_Tags);
216 else
218 /* Fall back to generic harddisk icon */
219 if (icon == NULL)
221 icon = GetDefaultIconFromName("Harddisk", iim->iim_Tags);
226 /* Fall back to generic disk icon */
227 if (icon == NULL)
229 icon = GetDefaultIconFromType(WBDISK, iim->iim_Tags);
232 if (icon != NULL)
234 /* Force the icon type */
235 icon->do_Type = WBDISK;
238 else if (iim->iim_FIB->fib_DirEntryType > 0)
240 /* It's a directory --------------------------------------------*/
241 /* Check if it is a trashcan directory */
242 if (iim->iim_ParentLock != BNULL)
244 /* Is iim_ParentLock a root? */
245 BPTR root = ParentDir(iim->iim_ParentLock);
247 if (root == BNULL)
249 /* Yes, it's a root. See if it contains our trashcan. */
250 BPTR cd = CurrentDir(iim->iim_ParentLock);
252 UBYTE buffer[MAXFILENAMELENGTH], buffer1[MAXFILENAMELENGTH];
254 /* SFS .recycled Trashcan */
255 BPTR lock = Lock(".recycled", ACCESS_READ);
256 NameFromLock(iim->iim_FileLock, buffer, MAXFILENAMELENGTH);
258 if (lock != BNULL)
260 NameFromLock(lock, buffer1, MAXFILENAMELENGTH);
261 if (strcasecmp(buffer, buffer1) == 0)
263 icon = GetDefaultIconFromType(WBGARBAGE, iim->iim_Tags);
265 UnLock(lock);
267 CurrentDir(cd);
269 else
271 UnLock(root);
275 /* Fall back to generic drawer icon */
276 if (icon == NULL)
278 icon = GetDefaultIconFromType(WBDRAWER, iim->iim_Tags);
281 if (icon != NULL)
283 /* Force the icon type */
284 icon->do_Type = WBDRAWER;
287 else
289 /* It's a file -----------------------------------------------------*/
290 if (DataTypesBase != NULL)
292 /* Use datatypes to identify the file --------------------------*/
293 struct DataType *dt = ObtainDataType
295 DTST_FILE, (APTR)iim->iim_FileLock, TAG_DONE
298 if (dt != NULL)
300 struct DataTypeHeader *dth = dt->dtn_Header;
304 dth->dth_GroupID == GID_SYSTEM
305 && dth->dth_ID == ID_EXECUTABLE
308 /* It's an executable file -----------------------------*/
309 icon = GetDefaultIconFromType(WBTOOL, iim->iim_Tags);
311 if (icon != NULL)
313 /* Force the icon type */
314 icon->do_Type = WBTOOL;
317 else
319 /* It's a project file of some kind --------------------*/
320 icon = GetDefaultIconFromName(dth->dth_Name, iim->iim_Tags);
322 /* Fall back to generic filetype group icon */
323 if (icon == NULL)
325 STRPTR name = NULL;
327 switch (dth->dth_GroupID)
329 case GID_SYSTEM: name = "System"; break;
330 case GID_TEXT: name = "Text"; break;
331 case GID_DOCUMENT: name = "Document"; break;
332 case GID_SOUND: name = "Sound"; break;
333 case GID_INSTRUMENT: name = "Instrument"; break;
334 case GID_MUSIC: name = "Music"; break;
335 case GID_PICTURE: name = "Picture"; break;
336 case GID_ANIMATION: name = "Animation"; break;
337 case GID_MOVIE: name = "Movie"; break;
340 if (name != NULL)
342 icon = GetDefaultIconFromName(name, iim->iim_Tags);
346 /* Fall back to generic project icon */
347 if (icon == NULL)
349 icon = GetDefaultIconFromType(WBPROJECT, iim->iim_Tags);
352 if (icon != NULL)
354 /* Force the icon type */
355 icon->do_Type = WBPROJECT;
359 ReleaseDataType(dt);
363 if (icon == NULL)
365 /* Fallback to a more primitive identification -----------------*/
366 if ((iim->iim_FIB->fib_Protection & FIBF_EXECUTE) == 0)
368 /* It's an executable files --------------------------------*/
369 icon = GetDefaultIconFromType(WBTOOL, iim->iim_Tags);
371 if (icon != NULL)
373 /* Force the icon type */
374 icon->do_Type = WBTOOL;
377 else
379 /* It's a project file of some kind ------------------------*/
380 icon = GetDefaultIconFromType(WBPROJECT, iim->iim_Tags);
382 if (icon != NULL)
384 /* Force the icon type */
385 icon->do_Type = WBPROJECT;
391 return icon;
394 /*** Support functions ******************************************************/
395 LONG __FindDiskType_WB(STRPTR volname, BPTR lock, struct IconBase *IconBase)
397 LONG disktype = ID_NO_DISK_PRESENT;
398 struct DosList *dl, *dn;
400 dl = LockDosList(LDF_VOLUMES|LDF_READ);
401 if (dl)
403 dn = FindDosEntry(dl, volname, LDF_VOLUMES);
404 if (dn)
406 disktype = dn->dol_misc.dol_volume.dol_DiskType;
408 UnLockDosList(LDF_VOLUMES|LDF_READ);
411 if (disktype == 0) //FFS workaround (dol_DiskType == 0)
413 struct InfoData *id = AllocMem(sizeof(struct InfoData), MEMF_PUBLIC|MEMF_CLEAR);
414 if (id != NULL)
416 if (Info(lock, id))
418 disktype = id->id_DiskType;
420 FreeMem(id,sizeof(struct InfoData));
423 return disktype;
426 BOOL __FindDeviceName_WB
428 STRPTR device, LONG length, BPTR lock,
429 APTR *theDOSBase
432 #undef DOSBase
433 #define DOSBase theDOSBase
434 struct DosList *dl = LockDosList(LDF_DEVICES | LDF_READ);
435 BOOL success = FALSE;
437 if (dl != NULL)
439 struct DosList *dol = dl;
440 struct MsgPort *port = ((struct FileLock *) BADDR(lock))->fl_Task;
442 while ((dol = NextDosEntry(dol, LDF_DEVICES | LDF_READ)) != NULL)
444 STRPTR devname = AROS_BSTR_ADDR(dol->dol_Name);
445 ULONG len = AROS_BSTR_strlen(dol->dol_Name);
447 if (dol->dol_Task == port) {
448 CopyMem(devname, device, len);
449 device[len++] = ':';
450 device[len] = 0;
452 success = TRUE;
453 break;
457 UnLockDosList(LDF_DEVICES | LDF_READ);
460 return success;
463 struct DiskObject *__GetDefaultIconFromName_WB
465 CONST_STRPTR name, const struct TagItem *tags, struct IconBase *IconBase
468 return GetIconTags
470 NULL,
471 ICONGETA_GetDefaultName, (IPTR) name,
472 TAG_END,
476 struct DiskObject *__GetDefaultIconFromType_WB
478 LONG type, const struct TagItem *tags, struct IconBase *IconBase
481 return GetIconTags
483 NULL,
484 ICONGETA_GetDefaultType, type,
485 TAG_END,