2 Copyright (C) 2013-2017, The AROS Development Team.
6 #include <aros/debug.h>
8 #define MUIMASTER_YES_INLINE_STDARG
10 #include <exec/memory.h>
11 #include <hidd/hidd.h>
12 #include <hidd/system.h>
14 #include <hidd/storage.h>
15 #include <libraries/asl.h>
16 #include <mui/NListtree_mcc.h>
17 #include <mui/NListview_mcc.h>
18 #include <utility/tagitem.h>
19 #include <utility/hooks.h>
21 #include <proto/alib.h>
22 #include <proto/dos.h>
23 #include <proto/exec.h>
24 #include <proto/muimaster.h>
25 #include <proto/oop.h>
26 #include <proto/utility.h>
27 #include <proto/intuition.h>
38 #define APPNAME "SysExplorer"
39 #define VERSION "SysExplorer 0.2"
41 const char version
[] = "$VER: " VERSION
" (" ADATE
")\n";
43 static Object
*app
, *main_window
, *property_window
;
44 static Object
*property_menu
, *expand_menu
, *collapse_menu
, *quit_menu
;
47 OOP_AttrBase HiddAttrBase
;
48 OOP_AttrBase HWAttrBase
;
50 const struct OOP_ABDescr abd
[] =
52 {IID_Hidd
, &HiddAttrBase
},
53 {IID_HW
, &HWAttrBase
},
58 * This lists contains handlers for known public classes.
59 * It specifies information window class, as well as function
60 * to enumerate children objects for the class.
62 * For proper operation CLIDs in this list should
63 * be sorted from subclasses to superclasses.
65 struct List seClassHandlers
;
67 AROS_UFH3S(BOOL
, enumFunc
,
68 AROS_UFHA(struct Hook
*, h
, A0
),
69 AROS_UFHA(OOP_Object
*, obj
, A2
),
70 AROS_UFHA(void *, parent
, A1
))
75 CONST_STRPTR name
= NULL
;
76 struct MUI_NListtree_TreeNode
*tn
;
78 struct InsertObjectMsg msg
=
83 struct ClassHandlerNode
*clHandlers
= FindObjectHandler(obj
, h
->h_Data
);
87 if (clHandlers
->muiClass
)
88 msg
.winClass
= *(clHandlers
->muiClass
);
89 if (clHandlers
->enumFunc
)
90 flags
= TNF_LIST
|TNF_OPEN
;
91 if (clHandlers
->validFunc
)
92 objValid
= clHandlers
->validFunc(obj
, &flags
);
97 /* This is either HW or HIDD subclass */
98 OOP_GetAttr(obj
, aHW_ClassName
, (IPTR
*)&name
);
100 OOP_GetAttr(obj
, aHidd_HardwareName
, (IPTR
*)&name
);
102 tn
= (APTR
)DoMethod(hidd_tree
, MUIM_NListtree_Insert
, name
, &msg
,
103 parent
, MUIV_NListtree_Insert_PrevNode_Sorted
, flags
);
104 D(bug("Inserted TreeNode 0x%p <%s> UserData 0x%p\n", tn
, tn
->tn_Name
, tn
->tn_User
));
106 /* If we have enumerator for this class, call it now */
107 if (clHandlers
&& clHandlers
->enumFunc
&& (flags
& TNF_LIST
))
108 clHandlers
->enumFunc(obj
, tn
);
110 return FALSE
; /* Continue enumeration */
115 static struct Hook enum_hook
=
118 .h_Data
= &seClassHandlers
121 void hwEnum(OOP_Object
*obj
, struct MUI_NListtree_TreeNode
*tn
)
123 HW_EnumDrivers(obj
, &enum_hook
, tn
);
126 struct ClassHandlerNode
*FindClassHandler(CONST_STRPTR classid
, struct List
*_handlers
)
128 struct ClassHandlerNode
*curHandler
;
130 ForeachNode(_handlers
, curHandler
)
132 if (!strncmp(classid
, curHandler
->ch_Node
.ln_Name
, strlen(classid
)))
134 D(bug("[SysExplorer] Returning class '%s'\n", curHandler
->ch_Node
.ln_Name
));
141 struct ClassHandlerNode
*FindObjectHandler(OOP_Object
*obj
, struct List
*_handlers
)
143 struct ClassHandlerNode
*curHandler
;
145 ForeachNode(_handlers
, curHandler
)
148 D(bug("[SysExplorer] class '%s'\n", curHandler
->ch_Node
.ln_Name
));
150 for (cl
= OOP_OCLASS(obj
); cl
; cl
= cl
->superclass
)
152 D(bug("[SysExplorer] obj '%s'\n", cl
->ClassNode
.ln_Name
));
153 if (!strncmp(cl
->ClassNode
.ln_Name
, curHandler
->ch_Node
.ln_Name
, strlen(curHandler
->ch_Node
.ln_Name
)))
155 D(bug("[SysExplorer] Returning obj class '%s'\n", curHandler
->ch_Node
.ln_Name
));
163 AROS_UFH3S(void, closeFunc
,
164 AROS_UFHA(struct Hook
*, h
, A0
),
165 AROS_UFHA(Object
*, obj
, A2
),
166 AROS_UFHA(struct ObjectUserData
**, msg
, A1
))
170 D(bug("closeFunc address 0x%p\n", closeFunc
));
171 D(bug("Close window 0x%p, ObjectUserData 0x%p\n", obj
, *msg
));
173 SET(obj
, MUIA_Window_Open
, FALSE
);
174 DoMethod(app
, OM_REMMEMBER
, obj
);
175 DoMethod(app
, MUIM_Application_PushMethod
, obj
, 1, OM_DISPOSE
);
182 static const struct Hook close_hook
=
187 AROS_UFH3S(APTR
, constructFunc
,
188 AROS_UFHA(struct Hook
*, h
, A0
),
189 AROS_UFHA(Object
*, obj
, A2
),
190 AROS_UFHA(struct MUIP_NListtree_ConstructMessage
*, msg
, A1
))
194 struct InsertObjectMsg
*insertMsg
= msg
->UserData
;
195 struct ObjectUserData
*data
= AllocPooled(msg
->MemPool
, sizeof(struct ObjectUserData
));
197 D(bug("%s: insertMsg 0x%p ObjectUserData 0x%p\n", msg
->Name
, insertMsg
, data
));
200 data
->obj
= insertMsg
->obj
;
201 data
->winClass
= insertMsg
->winClass
;
209 AROS_UFH3S(void, destructFunc
,
210 AROS_UFHA(struct Hook
*, h
, A0
),
211 AROS_UFHA(Object
*, obj
, A2
),
212 AROS_UFHA(struct MUIP_NListtree_DestructMessage
*, msg
, A1
))
216 FreePooled(msg
->MemPool
, msg
->UserData
, sizeof(struct ObjectUserData
));
221 static const struct Hook constructHook
=
223 .h_Entry
= constructFunc
226 static const struct Hook destructHook
=
228 .h_Entry
= destructFunc
231 AROS_UFH3S(void, propertyFunc
,
232 AROS_UFHA(struct Hook
*, h
, A0
),
233 AROS_UFHA(Object
*, obj
, A2
),
234 AROS_UFHA(struct MUI_NListtree_TreeNode
**, tn
, A1
))
238 struct MUI_NListtree_TreeNode
*node
= *tn
;
239 struct ObjectUserData
*data
;
243 /* if we were called from menu we must 1st find the current entry */
244 node
= (struct MUI_NListtree_TreeNode
*)XGET(hidd_tree
, MUIA_NListtree_Active
);
249 /* Do nothing if still no current entry */
253 data
= node
->tn_User
;
254 D(bug("propertyFunc called: TreeNode 0x%p <%s> UserData 0x%p\n", node
, node
->tn_Name
, data
));
255 D(bug("Window 0x%p\n", data
->win
));
259 /* The window is already open, show it to the user */
260 DoMethod(data
->win
, MUIM_Window_ToFront
);
261 SET(data
->win
, MUIA_Window_Activate
, TRUE
);
267 /* We have information window class. Open the window. */
268 data
->win
= NewObject(data
->winClass
->mcc_Class
, NULL
,
269 MUIA_PropertyWin_Object
, (IPTR
)data
->obj
,
271 D(bug("Created window 0x%p\n", data
->win
));
275 DoMethod(app
, OM_ADDMEMBER
, data
->win
);
276 DoMethod(data
->win
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
278 MUIM_CallHook
, &close_hook
, data
);
279 SET(data
->win
, MUIA_Window_Open
, TRUE
);
286 static const struct Hook property_hook
=
288 .h_Entry
= propertyFunc
291 static BOOL
GUIinit()
295 app
= ApplicationObject
,
296 MUIA_Application_Title
, (IPTR
)APPNAME
,
297 MUIA_Application_Version
, (IPTR
)VERSION
,
298 MUIA_Application_Copyright
, (IPTR
)"(C) 2013, The AROS Development Team",
299 MUIA_Application_Author
, (IPTR
)"Pavel Fedin",
300 MUIA_Application_Base
, (IPTR
)APPNAME
,
301 MUIA_Application_Description
, __(MSG_DESCRIPTION
),
303 MUIA_Application_Menustrip
, (IPTR
)(MenustripObject
,
304 MUIA_Family_Child
, (IPTR
)(MenuObject
,
305 MUIA_Menu_Title
, __(MSG_MENU_PROJECT
),
306 MUIA_Family_Child
, (IPTR
)(property_menu
= MenuitemObject
,
307 MUIA_Menuitem_Title
, __(MSG_MENU_PROPERTIES
),
309 MUIA_Family_Child
, (IPTR
)(expand_menu
= MenuitemObject
,
310 MUIA_Menuitem_Title
, __(MSG_MENU_EXPANDALL
),
312 MUIA_Family_Child
, (IPTR
)(collapse_menu
= MenuitemObject
,
313 MUIA_Menuitem_Title
, __(MSG_MENU_COLLAPSEALL
),
315 MUIA_Family_Child
, (IPTR
)(quit_menu
= MenuitemObject
,
316 MUIA_Menuitem_Title
, __(MSG_MENU_QUIT
),
321 SubWindow
, (IPTR
)(main_window
= WindowObject
,
322 MUIA_Window_Title
, __(MSG_WINTITLE
),
323 MUIA_Window_ID
, MAKE_ID('S', 'Y', 'E', 'X'),
324 WindowContents
, (IPTR
)(HGroup
,
325 Child
, (IPTR
)(NListviewObject
,
326 MUIA_NListview_NList
, (IPTR
)(hidd_tree
= NListtreeObject
,
328 MUIA_CycleChain
, TRUE
,
329 MUIA_NListtree_ConstructHook
, (IPTR
)&constructHook
,
330 MUIA_NListtree_DestructHook
, (IPTR
)&destructHook
,
331 MUIA_NListtree_DragDropSort
, FALSE
, /* forbid sorting by drag'n'drop */
340 OOP_Object
*hwRoot
= OOP_NewObject(NULL
, CLID_HW_Root
, NULL
);
344 /* This will kick our recursive enumeration into action */
345 CALLHOOKPKT((struct Hook
*)&enum_hook
, hwRoot
, MUIV_NListtree_Insert_ListNode_Root
);
348 /* Quit application if the main window's closegadget or the esc key is pressed. */
349 DoMethod(main_window
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
351 MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
353 DoMethod(property_window
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
,
355 MUIM_Set
, MUIA_Window_Open
, FALSE
);
358 DoMethod(property_menu
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
360 MUIM_CallHook
, &property_hook
, 0);
362 DoMethod(expand_menu
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
364 MUIM_NListtree_Open
, MUIV_NListtree_Open_ListNode_Root
, MUIV_NListtree_Open_TreeNode_All
, 0);
366 DoMethod(collapse_menu
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
368 MUIM_NListtree_Close
, MUIV_NListtree_Close_ListNode_Root
, MUIV_NListtree_Close_TreeNode_All
, 0);
370 DoMethod(quit_menu
, MUIM_Notify
, MUIA_Menuitem_Trigger
, MUIV_EveryTime
,
372 MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
374 DoMethod(hidd_tree
, MUIM_Notify
, MUIA_NListtree_DoubleClick
, MUIV_EveryTime
,
376 MUIM_CallHook
, &property_hook
, MUIV_TriggerValue
);
384 int __nocommandline
= 1;
388 if (!Locale_Initialize())
391 if (!OOP_ObtainAttrBases(abd
))
393 Locale_Deinitialize();
399 SET(main_window
, MUIA_Window_Open
, TRUE
);
401 if (XGET(main_window
, MUIA_Window_Open
))
403 DoMethod(app
, MUIM_Application_Execute
);
404 SET(main_window
, MUIA_Window_Open
, FALSE
);
410 OOP_ReleaseAttrBases(abd
);
412 Locale_Deinitialize();
416 BOOL
RegisterClassHandler(CONST_STRPTR classid
, BYTE pri
, struct MUI_CustomClass
** customwinclass
, CLASS_ENUMFUNC enumfunc
, CLASS_VALIDFUNC validfunc
)
418 struct ClassHandlerNode
*newClass
;
420 if ((newClass
= FindClassHandler(classid
, &seClassHandlers
)))
422 if (newClass
->enumFunc
!= hwEnum
)
425 D(bug("[SysExplorer] Updating '%s'..\n", classid
));
431 D(bug("[SysExplorer] Registering '%s'..\n", classid
));
432 newClass
= AllocMem(sizeof(struct ClassHandlerNode
), MEMF_CLEAR
);
437 newClass
->ch_Node
.ln_Name
= (char *)classid
;
438 newClass
->ch_Node
.ln_Pri
= pri
;
439 newClass
->muiClass
= customwinclass
;
440 newClass
->enumFunc
= enumfunc
;
441 newClass
->validFunc
= validfunc
;
444 Enqueue(&seClassHandlers
, &newClass
->ch_Node
);
451 BOOL
sysexplorer_init(void)
453 D(bug("[SysExplorer] Initialising..\n"));
454 NEWLIST(&seClassHandlers
);
456 RegisterClassHandler(CLID_Hidd_Storage
, 90, NULL
, hwEnum
, NULL
);
457 RegisterClassHandler(CLID_Hidd_Gfx
, 60, NULL
, hwEnum
, NULL
);
458 RegisterClassHandler(CLID_Hidd_System
, 30, NULL
, hwEnum
, NULL
);
459 RegisterClassHandler(CLID_HW_Root
, 0, &ComputerWindow_CLASS
, hwEnum
, NULL
);
460 RegisterClassHandler(CLID_HW
, -30, NULL
, hwEnum
, NULL
);
461 RegisterClassHandler(CLID_Hidd
, -60, &GenericWindow_CLASS
, NULL
, NULL
);
463 D(bug("[SysExplorer] Init complete\n"));
468 ADD2INIT(sysexplorer_init
, 0);