Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / muimaster / classes / volumelist.c
blob655f5c012d0e778e2f8b182c2334e15512cf9818
1 /*
2 Copyright © 2002-2007, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/memory.h>
9 #include <clib/alib_protos.h>
10 #include <proto/exec.h>
11 #include <proto/dos.h>
12 #include <proto/intuition.h>
13 #include <proto/utility.h>
14 #include <proto/muimaster.h>
16 #include <string.h>
17 #include <stdio.h>
19 #include "mui.h"
20 #include "muimaster_intern.h"
21 #include "support.h"
22 #include "support_classes.h"
23 #include "volumelist_private.h"
25 extern struct Library *MUIMasterBase;
28 static void printSize(STRPTR string, size_t bufsize, UQUAD size)
30 char unit = 'B';
32 if (size >= 9999999999ULL)
34 size = size >> 30;
35 unit = 'G';
37 else if (size >= 9999999UL)
39 size = size >> 20;
40 unit = 'M';
42 else if (size > 9999)
44 size = size >> 10;
45 unit = 'K';
48 snprintf(string, bufsize, "%u%c", (ULONG)size, unit);
49 string[bufsize - 1] = '\0';
52 AROS_UFH3S(APTR, construct_func,
53 AROS_UFHA(struct Hook *, hook, A0),
54 AROS_UFHA(APTR, pool, A2),
55 AROS_UFHA(struct Volumelist_Entry *, entry, A1))
57 AROS_USERFUNC_INIT
59 struct Volumelist_Entry *new;
61 if ((new = AllocPooled(pool, sizeof(*new))))
63 *new = *entry;
65 return new;
67 AROS_USERFUNC_EXIT
70 AROS_UFH3S(void, destruct_func,
71 AROS_UFHA(struct Hook *, hook, A0),
72 AROS_UFHA(APTR, pool, A2),
73 AROS_UFHA(struct Volumelist_Entry *, entry, A1))
75 AROS_USERFUNC_INIT
77 FreePooled(pool, entry, sizeof(struct Volumelist_Entry));
79 AROS_USERFUNC_EXIT
82 AROS_UFH3S(LONG, display_func,
83 AROS_UFHA(struct Hook *, hook, A0),
84 AROS_UFHA(char **, array, A2),
85 AROS_UFHA(struct Volumelist_Entry *, entry, A1))
87 AROS_USERFUNC_INIT
89 /* MUI: logo | devicename | %-used | bytes free | bytes used */
91 if (entry)
93 if (entry->type == DLT_DEVICE)
95 *array++ = "\33I[6:24]";
97 else if (entry->type == DLT_VOLUME)
99 *array++ = "\33I[6:26]";
101 else
103 *array++ = "\33I[6:29]";
106 *array++ = entry->name;
107 *array++ = entry->full;
108 *array++ = entry->free;
109 *array = entry->used;
111 else
113 *array++ = "";
114 *array++ = "Name";
115 *array++ = "full";
116 *array++ = "free";
117 *array = "used";
120 return 0;
122 AROS_USERFUNC_EXIT
126 IPTR Volumelist__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
128 struct DosList *dl, *actdl;
130 STRPTR format = (STRPTR)GetTagData(MUIA_List_Format, 0, msg->ops_AttrList);
132 obj = (Object *)DoSuperNewTags
134 cl, obj, NULL,
135 MUIA_List_Format, format
136 ? TAG_IGNORE
137 : (IPTR)",,P=\33r,P=\33r,P=\33r",
138 TAG_MORE, (IPTR) msg->ops_AttrList
141 if (obj)
143 struct Volumelist_DATA *data = INST_DATA(cl, obj);
145 data->construct_hook.h_Entry = (HOOKFUNC)construct_func;
146 data->destruct_hook.h_Entry = (HOOKFUNC)destruct_func;
147 data->display_hook.h_Entry = (HOOKFUNC)display_func;
149 SetAttrs(obj, MUIA_List_ConstructHook, (IPTR)&data->construct_hook,
150 MUIA_List_DestructHook, (IPTR)&data->destruct_hook,
151 MUIA_List_DisplayHook, (IPTR)&data->display_hook,
152 TAG_DONE);
154 dl = LockDosList(LDF_READ | LDF_VOLUMES | LDF_ASSIGNS | LDF_DEVICES);
156 actdl = dl;
157 while((actdl = NextDosEntry(actdl, LDF_DEVICES)))
159 struct Volumelist_Entry entry;
161 entry.full[0] = '\0';
162 entry.free[0] = '\0';
163 entry.used[0] = '\0';
165 entry.type = DLT_DEVICE;
166 #ifdef __AROS__
167 strncpy(entry.name, actdl->dol_Ext.dol_AROS.dol_DevName, sizeof(entry.name));
168 #else
169 #warning "FIXME: AmigaOS: get device name"
170 strncpy(entry.name, "???", sizeof(entry.name));
171 #endif
172 entry.name[sizeof(entry.name) - 2] = '\0';
173 strcat(entry.name, ":");
175 DoMethod(obj, MUIM_List_InsertSingle, (IPTR)&entry, MUIV_List_Insert_Bottom);
178 actdl = dl;
179 while((actdl = NextDosEntry(actdl, LDF_VOLUMES)))
181 struct Volumelist_Entry entry;
182 struct InfoData diskinfo;
183 BPTR lock;
184 UQUAD free;
185 UQUAD used;
187 entry.full[0] = '\0';
188 entry.free[0] = '\0';
189 entry.used[0] = '\0';
191 entry.type = DLT_VOLUME;
192 #ifdef __AROS__
193 strncpy(entry.name, actdl->dol_Ext.dol_AROS.dol_DevName, sizeof(entry.name));
194 #else
195 #warning "FIXME: AmigaOS: get device name"
196 strncpy(entry.name, "???", sizeof(entry.name));
197 #endif
198 entry.name[sizeof(entry.name) - 2] = '\0';
199 strcat(entry.name, ":");
201 if ((lock = Lock(entry.name, SHARED_LOCK)) != NULL)
203 if (Info(lock, &diskinfo) != DOSFALSE)
205 snprintf
207 entry.full,
208 sizeof(entry.full),
209 "%d%%",
210 100 * diskinfo.id_NumBlocksUsed / diskinfo.id_NumBlocks
212 entry.full[sizeof(entry.full) - 1] = '\0';
214 used = (UQUAD)diskinfo.id_NumBlocksUsed * diskinfo.id_BytesPerBlock;
215 free = (UQUAD)diskinfo.id_NumBlocks * diskinfo.id_BytesPerBlock - used;
216 printSize(entry.free, sizeof entry.free, free);
217 printSize(entry.used, sizeof entry.used, used);
219 UnLock(lock);
222 DoMethod(obj, MUIM_List_InsertSingle, (IPTR)&entry, MUIV_List_Insert_Bottom);
225 actdl = dl;
226 while((actdl = NextDosEntry(actdl, LDF_ASSIGNS)))
228 struct Volumelist_Entry entry;
230 entry.full[0] = '\0';
231 entry.free[0] = '\0';
232 entry.used[0] = '\0';
234 entry.type = DLT_DIRECTORY;
235 #ifdef __AROS__
236 strncpy(entry.name, actdl->dol_Ext.dol_AROS.dol_DevName, sizeof(entry.name));
237 #else
238 #warning "FIXME: AmigaOS: get assign name"
239 strncpy(entry.name, "???", sizeof(entry.name));
240 #endif
241 entry.name[sizeof(entry.name) - 2] = '\0';
242 strcat(entry.name, ":");
244 DoMethod(obj, MUIM_List_InsertSingle, (IPTR)&entry, MUIV_List_Insert_Bottom);
247 UnLockDosList(LDF_READ | LDF_VOLUMES | LDF_ASSIGNS | LDF_DEVICES);
250 return (IPTR)obj;
254 #if ZUNE_BUILTIN_VOLUMELIST
255 BOOPSI_DISPATCHER(IPTR, Volumelist_Dispatcher, cl, obj, msg)
257 switch (msg->MethodID)
259 case OM_NEW: return Volumelist__OM_NEW(cl, obj, (struct opSet *)msg);
261 default: return DoSuperMethodA(cl, obj, msg);
264 BOOPSI_DISPATCHER_END
266 const struct __MUIBuiltinClass _MUI_Volumelist_desc =
268 MUIC_Volumelist,
269 MUIC_List,
270 sizeof(struct Volumelist_DATA),
271 (void*)Volumelist_Dispatcher
273 #endif /* ZUNE_BUILTIN_VOLUMELIST */