Corrections to SVN properties.
[AROS.git] / workbench / tools / SysExplorer / main.c
blob13849fe70fbb91332fbaa952881d93f998caf8a2
1 /*
2 Copyright (C) 2013, The AROS Development Team.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/memory.h>
9 #include <hidd/ata.h>
10 #include <hidd/hidd.h>
11 #include <libraries/asl.h>
12 #include <mui/NListtree_mcc.h>
13 #include <mui/NListview_mcc.h>
14 #include <utility/tagitem.h>
15 #include <utility/hooks.h>
17 #include <proto/alib.h>
18 #include <proto/dos.h>
19 #include <proto/exec.h>
20 #include <proto/muimaster.h>
21 #include <proto/oop.h>
22 #include <proto/utility.h>
23 #include <proto/intuition.h>
25 #include <ctype.h>
26 #include <stdio.h>
27 #include <stdlib.h>
29 #include "locale.h"
30 #include "classes.h"
32 #include <aros/debug.h>
34 #define APPNAME "SysExplorer"
35 #define VERSION "SysExplorer 0.2"
37 struct ObjectUserData
39 OOP_Object *obj;
40 struct MUI_CustomClass *winClass;
41 Object *win;
44 struct InsertObjectMsg
46 OOP_Object *obj;
47 struct MUI_CustomClass *winClass;
50 struct ClassHandlers
52 CONST_STRPTR classID;
53 struct MUI_CustomClass **muiClass;
54 void (*enumFunc)(OOP_Object *obj, struct MUI_NListtree_TreeNode *parent);
57 static const struct ClassHandlers *FindClassHandler(OOP_Object *obj);
59 const char version[] = "$VER: " VERSION " (" ADATE ")\n";
61 static Object *app, *main_window, *property_window, *hidd_tree;
62 static Object *property_menu, *expand_menu, *collapse_menu, *quit_menu;
64 OOP_AttrBase HiddAttrBase;
65 OOP_AttrBase HWAttrBase;
66 OOP_AttrBase HiddATABusAB;
67 OOP_AttrBase HiddATAUnitAB;
69 const struct OOP_ABDescr abd[] =
71 {IID_Hidd , &HiddAttrBase },
72 {IID_HW , &HWAttrBase },
73 {IID_Hidd_ATABus , &HiddATABusAB },
74 {IID_Hidd_ATAUnit, &HiddATAUnitAB},
75 {NULL , NULL }
78 /* Here we have enumerators for different device and subsystem classes */
80 static void addATAUnit(OOP_Object *dev, ULONG attrID, struct MUI_NListtree_TreeNode *parent)
82 OOP_Object *unit = NULL;
84 OOP_GetAttr(dev, attrID, (IPTR *)&unit);
85 if (unit)
87 struct InsertObjectMsg msg =
89 .obj = unit,
90 .winClass = ATAUnitWindow_CLASS
92 CONST_STRPTR name;
94 OOP_GetAttr(unit, aHidd_ATAUnit_Model, (IPTR *)&name);
95 DoMethod(hidd_tree, MUIM_NListtree_Insert, name, &msg,
96 parent, MUIV_NListtree_Insert_PrevNode_Tail, 0);
100 static void ataUnitsEnum(OOP_Object *dev, struct MUI_NListtree_TreeNode *parent)
102 addATAUnit(dev, aHidd_ATABus_Master, parent);
103 addATAUnit(dev, aHidd_ATABus_Slave , parent);
106 AROS_UFH3S(BOOL, enumFunc,
107 AROS_UFHA(struct Hook *, h, A0),
108 AROS_UFHA(OOP_Object*, obj, A2),
109 AROS_UFHA(void *, parent, A1))
111 AROS_USERFUNC_INIT
113 CONST_STRPTR name = NULL;
114 struct MUI_NListtree_TreeNode *tn;
115 ULONG flags = 0;
116 struct InsertObjectMsg msg =
118 .obj = obj,
119 .winClass = NULL
121 const struct ClassHandlers *clHandlers = FindClassHandler(obj);
123 /* This is either HW or HIDD subclass */
124 OOP_GetAttr(obj, aHW_ClassName, (IPTR *)&name);
125 if (!name)
126 OOP_GetAttr(obj, aHidd_HardwareName, (IPTR *)&name);
128 if (clHandlers)
130 if (clHandlers->muiClass)
131 msg.winClass = *(clHandlers->muiClass);
132 if (clHandlers->enumFunc)
133 flags = TNF_LIST|TNF_OPEN;
136 tn = (APTR)DoMethod(hidd_tree, MUIM_NListtree_Insert, name, &msg,
137 parent, MUIV_NListtree_Insert_PrevNode_Tail, flags);
138 D(bug("Inserted TreeNode 0x%p <%s> UserData 0x%p\n", tn, tn->tn_Name, tn->tn_User));
140 /* If we have enumerator for this class, call it now */
141 if (clHandlers && clHandlers->enumFunc)
142 clHandlers->enumFunc(obj, tn);
144 return FALSE; /* Continue enumeration */
146 AROS_USERFUNC_EXIT
149 static const struct Hook enum_hook =
151 .h_Entry = enumFunc
154 static void hwEnum(OOP_Object *obj, struct MUI_NListtree_TreeNode *tn)
156 HW_EnumDrivers(obj, (struct Hook *)&enum_hook, tn);
160 * This table lists handlers for known public classes.
161 * It specifies information window class, as well as function
162 * to enumerate children objects for the class.
164 * For proper operation CLIDs in this table should
165 * be sorted from subclasses to superclasses.
167 static const struct ClassHandlers classHandlers[] =
169 {CLID_HW_Root , &ComputerWindow_CLASS, hwEnum },
170 {CLID_HW , NULL , hwEnum },
171 {CLID_Hidd_ATABus, &ATAWindow_CLASS , ataUnitsEnum},
172 {CLID_Hidd , &GenericWindow_CLASS , NULL },
173 {NULL , NULL , NULL }
176 static const struct ClassHandlers *FindClassHandler(OOP_Object *obj)
178 unsigned int i;
180 for (i = 0; classHandlers[i].classID; i++)
182 OOP_Class *cl;
184 for (cl = OOP_OCLASS(obj); cl ; cl = cl->superclass)
186 if (!strcmp(cl->ClassNode.ln_Name, classHandlers[i].classID))
187 return &classHandlers[i];
190 return NULL;
193 AROS_UFH3S(void, closeFunc,
194 AROS_UFHA(struct Hook *, h, A0),
195 AROS_UFHA(Object*, obj, A2),
196 AROS_UFHA(struct ObjectUserData **, msg, A1))
198 AROS_USERFUNC_INIT
200 D(bug("closeFunc address 0x%p\n", closeFunc));
201 D(bug("Close window 0x%p, ObjectUserData 0x%p\n", obj, *msg));
203 SET(obj, MUIA_Window_Open, FALSE);
204 DoMethod(app, OM_REMMEMBER, obj);
205 DoMethod(app, MUIM_Application_PushMethod, obj, 1, OM_DISPOSE);
207 (*msg)->win = NULL;
209 AROS_USERFUNC_EXIT
212 static const struct Hook close_hook =
214 .h_Entry = closeFunc
217 AROS_UFH3S(APTR, constructFunc,
218 AROS_UFHA(struct Hook *, h, A0),
219 AROS_UFHA(Object*, obj, A2),
220 AROS_UFHA(struct MUIP_NListtree_ConstructMessage *, msg, A1))
222 AROS_USERFUNC_INIT
224 struct InsertObjectMsg *insertMsg = msg->UserData;
225 struct ObjectUserData *data = AllocPooled(msg->MemPool, sizeof(struct ObjectUserData));
227 D(bug("%s: insertMsg 0x%p ObjectUserData 0x%p\n", msg->Name, insertMsg, data));
228 if (data)
230 data->obj = insertMsg->obj;
231 data->winClass = insertMsg->winClass;
232 data->win = NULL;
234 return data;
236 AROS_USERFUNC_EXIT
239 AROS_UFH3S(void, destructFunc,
240 AROS_UFHA(struct Hook *, h, A0),
241 AROS_UFHA(Object*, obj, A2),
242 AROS_UFHA(struct MUIP_NListtree_DestructMessage *, msg, A1))
244 AROS_USERFUNC_INIT
246 FreePooled(msg->MemPool, msg->UserData, sizeof(struct ObjectUserData));
248 AROS_USERFUNC_EXIT
251 static const struct Hook constructHook =
253 .h_Entry = constructFunc
256 static const struct Hook destructHook =
258 .h_Entry = destructFunc
261 AROS_UFH3S(void, propertyFunc,
262 AROS_UFHA(struct Hook *, h, A0),
263 AROS_UFHA(Object*, obj, A2),
264 AROS_UFHA(struct MUI_NListtree_TreeNode **, tn, A1))
266 AROS_USERFUNC_INIT
268 struct MUI_NListtree_TreeNode *node = *tn;
269 struct ObjectUserData *data;
271 if (node == NULL)
273 /* if we were called from menu we must 1st find the current entry */
274 node = (struct MUI_NListtree_TreeNode *)XGET(hidd_tree, MUIA_NListtree_Active);
277 if (node == NULL)
279 /* Do nothing if still no current entry */
280 return;
283 data = node->tn_User;
284 D(bug("propertyFunc called: TreeNode 0x%p <%s> UserData 0x%p\n", node, node->tn_Name, data));
285 D(bug("Window 0x%p\n", data->win));
287 if (data->win)
289 /* The window is already open, show it to the user */
290 DoMethod(data->win, MUIM_Window_ToFront);
291 SET(data->win, MUIA_Window_Activate, TRUE);
292 return;
295 if (data->winClass)
297 /* We have information window class. Open the window. */
298 data->win = NewObject(data->winClass->mcc_Class, NULL,
299 MUIA_PropertyWin_Object, (IPTR)data->obj,
300 TAG_DONE);
301 D(bug("Created window 0x%p\n", data->win));
303 if (data->win)
305 DoMethod(app, OM_ADDMEMBER, data->win);
306 DoMethod(data->win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
307 data->win, 3,
308 MUIM_CallHook, &close_hook, data);
309 SET(data->win, MUIA_Window_Open, TRUE);
313 AROS_USERFUNC_EXIT
316 static const struct Hook property_hook =
318 .h_Entry = propertyFunc
321 static BOOL GUIinit()
323 BOOL retval = FALSE;
325 app = ApplicationObject,
326 MUIA_Application_Title, (IPTR)APPNAME,
327 MUIA_Application_Version, (IPTR)VERSION,
328 MUIA_Application_Copyright, (IPTR)"(C) 2013, The AROS Development Team",
329 MUIA_Application_Author, (IPTR)"Pavel Fedin",
330 MUIA_Application_Base, (IPTR)APPNAME,
331 MUIA_Application_Description, __(MSG_DESCRIPTION),
333 MUIA_Application_Menustrip, (IPTR)(MenuitemObject,
334 MUIA_Family_Child, (IPTR)(MenuitemObject,
335 MUIA_Menuitem_Title, __(MSG_MENU_PROJECT),
336 MUIA_Family_Child, (IPTR)(property_menu = MenuitemObject,
337 MUIA_Menuitem_Title, (IPTR)"Properties",
338 End),
339 MUIA_Family_Child, (IPTR)(expand_menu = MenuitemObject,
340 MUIA_Menuitem_Title, (IPTR)"Expand All",
341 End),
342 MUIA_Family_Child, (IPTR)(collapse_menu = MenuitemObject,
343 MUIA_Menuitem_Title, (IPTR)"Collapse All",
344 End),
345 MUIA_Family_Child, (IPTR)(quit_menu = MenuitemObject,
346 MUIA_Menuitem_Title, __(MSG_MENU_QUIT),
347 End),
348 End),
349 End),
351 SubWindow, (IPTR)(main_window = WindowObject,
352 MUIA_Window_Title, __(MSG_WINTITLE),
353 MUIA_Window_ID, MAKE_ID('S', 'Y', 'E', 'X'),
354 WindowContents, (IPTR)(HGroup,
355 Child, (IPTR)(NListviewObject,
356 MUIA_NListview_NList, (IPTR)(hidd_tree = NListtreeObject,
357 ReadListFrame,
358 MUIA_CycleChain, TRUE,
359 MUIA_NListtree_ConstructHook, (IPTR)&constructHook,
360 MUIA_NListtree_DestructHook, (IPTR)&destructHook,
361 MUIA_NListtree_DragDropSort, FALSE, /* forbid sorting by drag'n'drop */
362 End),
363 End),
364 End),
365 End),
366 End;
368 if (app)
370 OOP_Object *hwRoot = OOP_NewObject(NULL, CLID_HW_Root, NULL);
372 if (hwRoot)
374 /* This will kick our recursive enumeration into action */
375 CALLHOOKPKT((struct Hook *)&enum_hook, hwRoot, MUIV_NListtree_Insert_ListNode_Root);
378 /* Quit application if the main window's closegadget or the esc key is pressed. */
379 DoMethod(main_window, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
380 app, 2,
381 MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
383 DoMethod(property_window, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
384 property_window, 3,
385 MUIM_Set, MUIA_Window_Open, FALSE);
388 DoMethod(property_menu, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
389 app, 3,
390 MUIM_CallHook, &property_hook, 0);
392 DoMethod(expand_menu, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
393 hidd_tree, 4,
394 MUIM_NListtree_Open, MUIV_NListtree_Open_ListNode_Root, MUIV_NListtree_Open_TreeNode_All, 0);
396 DoMethod(collapse_menu, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
397 hidd_tree, 4,
398 MUIM_NListtree_Close, MUIV_NListtree_Close_ListNode_Root, MUIV_NListtree_Close_TreeNode_All, 0);
400 DoMethod(quit_menu, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
401 app, 2,
402 MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
404 DoMethod(hidd_tree, MUIM_Notify, MUIA_NListtree_DoubleClick, MUIV_EveryTime,
405 app, 3,
406 MUIM_CallHook, &property_hook, MUIV_TriggerValue);
408 retval = TRUE;
411 return retval;
414 int __nocommandline = 1;
416 int main(void)
418 if (!Locale_Initialize())
419 return 20;
421 if (!OOP_ObtainAttrBases(abd))
423 Locale_Deinitialize();
424 return 20;
427 if (GUIinit())
429 SET(main_window, MUIA_Window_Open, TRUE);
431 if (XGET(main_window, MUIA_Window_Open))
433 DoMethod(app, MUIM_Application_Execute);
434 SET(main_window, MUIA_Window_Open, FALSE);
437 DisposeObject(app);
440 OOP_ReleaseAttrBases(abd);
442 Locale_Deinitialize();
443 return 0;