/* * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #import "IORegistryController.h" @implementation IORegistryController - init { if (self = [super init]) { int plane; _rootNode = [[IORegOutlineViewNode alloc] initWithName:@"Root" value:@"Root"]; _detailRootNode = [[IORegDetailOutlineViewNode alloc] init]; if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"IORegistryPlane"] intValue] == 1) { plane = kIOService_Plane; } else { plane = kIOUSB_Plane; } _infoGatherer = [[IORegInfoGatherer alloc] initWithListener:self rootNode:_rootNode plane:plane]; } return self; } - (void)dealloc { [_rootNode release]; [_detailRootNode release]; [_infoGatherer release]; [super dealloc]; } - (void)awakeFromNib { if ([[NSUserDefaults standardUserDefaults] boolForKey:@"IORegistryDontAutoRefresh"] == YES) { [RefreshCheckBox setState:NSOffState]; //enable/disable button [RefreshButton setEnabled:YES]; } else { [RefreshCheckBox setState:NSOnState]; //enable/disable button [RefreshButton setEnabled:NO]; } if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"IORegistryPlane"] intValue] == 1) { [PlanePopUpButton selectItemAtIndex:1]; } else { [PlanePopUpButton selectItemAtIndex:0]; } [IORegOutputOV setTarget:self]; [IORegOutputOV setAction:@selector(ioregItemSingleClicked:)]; [IORegOutputOV setDoubleAction:@selector(ioregItemDoubleClicked:)]; [IORegDetailedOutput setTarget:IORegDetailedOutput]; [IORegDetailedOutput setDoubleAction:@selector(itemDoubleClicked)]; [self expandOutlineViewItems]; } - (IBAction)Refresh:(id)sender { [_detailRootNode removeAllChildren]; [IORegDetailedOutput reloadData]; [_infoGatherer refreshData:YES]; } - (IBAction)SaveOutput:(id)sender { NSSavePanel *sp = [NSSavePanel savePanel]; int result; [sp setRequiredFileType:@"txt"]; result = [sp runModalForDirectory:NSHomeDirectory() file:@"IORegistry"]; if (result == NSOKButton) { NSString *finalString = [_rootNode stringRepresentationOfValues:0]; if (![finalString writeToFile:[sp filename] atomically:YES]) NSBeep(); } } - (IBAction)ToggleAutoRefresh:(id)sender { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([sender state] == NSOffState) { [defaults setBool:YES forKey:@"IORegistryDontAutoRefresh"]; //enable/disable button [RefreshButton setEnabled:YES]; } else { [defaults setBool:NO forKey:@"IORegistryDontAutoRefresh"]; //enable/disable button [RefreshButton setEnabled:NO]; [self Refresh:self]; } } - (IBAction)TogglePlane:(id)sender { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([sender indexOfSelectedItem] == 0) { [defaults setObject:[NSNumber numberWithInt:0] forKey:@"IORegistryPlane"]; [_infoGatherer setPlane:0]; } else if ([sender indexOfSelectedItem] == 1) { [defaults setObject:[NSNumber numberWithInt:1] forKey:@"IORegistryPlane"]; [_infoGatherer setPlane:1]; } [self Refresh:self]; } - (void)ioRegInfoGathererInformationDidChange:(IORegInfoGatherer *)aGatherer { [IORegOutputOV reloadData]; [self expandOutlineViewItems]; } - (void)expandOutlineViewItems { NSEnumerator *enumerator; id thisNode; enumerator = [[_rootNode children] objectEnumerator]; while (thisNode = [enumerator nextObject]) { if ([PlanePopUpButton indexOfSelectedItem] == 0) { [IORegOutputOV expandItem:thisNode expandChildren:YES]; } else { NSEnumerator *childEnumerator = [[thisNode children] objectEnumerator]; id thisChild; [IORegOutputOV expandItem:thisNode]; while(thisChild = [childEnumerator nextObject]) { [IORegOutputOV expandItem:thisChild]; } } } } - (id)outlineView:(NSOutlineView *)ov child:(int)index ofItem:(id)item { if (ov == IORegOutputOV) { if (item == nil) { return [_rootNode childAtIndex:index]; } return [item childAtIndex:index]; } else if (ov = IORegDetailedOutput) { if (item == nil) { return [_detailRootNode childAtIndex:index]; } return [item childAtIndex:index]; } return nil; } - (BOOL)outlineView:(NSOutlineView *)ov isItemExpandable:(id)item { return [item isExpandable]; } - (int)outlineView:(NSOutlineView *)ov numberOfChildrenOfItem:(id)item { if (ov == IORegOutputOV) { if (item == nil) { return [_rootNode childrenCount]; } return [item childrenCount]; } else if (ov = IORegDetailedOutput) { if (item == nil) { return [_detailRootNode childrenCount]; } return [item childrenCount]; } return 0; } - (id)outlineView:(NSOutlineView *)ov objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { if (ov == IORegOutputOV) { return [item value]; } else if (ov = IORegDetailedOutput) { if ([[tableColumn identifier] intValue] == 0) { return [item name]; } else if ([[tableColumn identifier] intValue] == 1) { return [(IORegDetailOutlineViewNode *)item type]; } else if ([[tableColumn identifier] intValue] == 2) { return [item value]; } } return nil; } - (void)outlineViewSelectionDidChange:(NSNotification *)aNotification { if ([aNotification object] == IORegOutputOV) { [_detailRootNode removeAllChildren]; [IORegDetailedOutput reloadData]; } } - (void)ioregItemSingleClicked:(id)sender { if ([IORegDetailedOutputDrawer state] == NSDrawerOpenState) { IORegOutlineViewNode *item = [sender itemAtRow:[sender selectedRow]]; if ([item representedDevice] != NULL) { NSMutableDictionary *propertiesDict; if (IORegistryEntryCreateCFProperties( [item representedDevice], (CFMutableDictionaryRef *)&propertiesDict, kCFAllocatorDefault, 0 ) == 0) { [_detailRootNode removeAllChildren]; [self populateNode:_detailRootNode withContentsOfDictionary:propertiesDict]; [IORegDetailedOutput reloadData]; CFRelease(propertiesDict); } } } } - (void)ioregItemDoubleClicked:(id)sender { [sender itemDoubleClicked]; } - (void)populateNode:(IORegDetailOutlineViewNode *)node withKey:(NSString *)key value:(id)value { IORegDetailOutlineViewNode * aNewNode; if (CFGetTypeID(value) == CFStringGetTypeID()) { aNewNode = [[IORegDetailOutlineViewNode alloc] initWithName:(NSString *)key value:(NSString *)value]; [aNewNode setType:@"String"]; [node addChild:aNewNode]; [aNewNode release]; } else if (CFGetTypeID(value) == CFNumberGetTypeID()) { switch (CFNumberGetType((CFNumberRef)value)) { case kCFNumberSInt32Type: aNewNode = [[IORegDetailOutlineViewNode alloc] initWithName:(NSString *)key value:[NSString stringWithFormat:@"%@ (0x%x)",[value description], [value longValue]]]; break; case kCFNumberSInt64Type: aNewNode = [[IORegDetailOutlineViewNode alloc] initWithName:(NSString *)key value:[NSString stringWithFormat:@"%@ (0x%x%x)",[value description], [value longLongValue],[value longValue]]]; break; default: aNewNode = [[IORegDetailOutlineViewNode alloc] initWithName:(NSString *)key value:[NSString stringWithFormat:@"%@ (0x%x)",[value description], [value intValue]]]; } [aNewNode setType:@"Number"]; [node addChild:aNewNode]; [aNewNode release]; } else if (CFGetTypeID(value) == CFDataGetTypeID()) { aNewNode = [[IORegDetailOutlineViewNode alloc] initWithName:(NSString *)key value:[value description]]; [node addChild:aNewNode]; [aNewNode release]; } else if (CFGetTypeID(value) == CFDictionaryGetTypeID()) { aNewNode = [[IORegDetailOutlineViewNode alloc] initWithName:(NSString *)key value:@""]; [aNewNode setType:@"Dictionary"]; [self populateNode:aNewNode withContentsOfDictionary:value]; [node addChild:aNewNode]; [aNewNode release]; } else if (CFGetTypeID(value) == CFArrayGetTypeID()) { aNewNode = [[IORegDetailOutlineViewNode alloc] initWithName:(NSString *)key value:@""]; [aNewNode setType:@"Array"]; [self populateNode:aNewNode withContentsOfArray:value]; [node addChild:aNewNode]; [aNewNode release]; } } - (void)populateNode:(IORegDetailOutlineViewNode *)node withContentsOfDictionary:(NSDictionary *)dictionary { NSMutableArray * keys = [[dictionary allKeys] mutableCopy]; NSEnumerator * enumerator; NSString * key; [keys sortUsingSelector:@selector(caseInsensitiveCompare:)]; enumerator = [keys objectEnumerator]; while (key = [enumerator nextObject]) { [self populateNode:node withKey:key value:[dictionary objectForKey:key]]; } [keys release]; } - (void)populateNode:(IORegDetailOutlineViewNode *)node withContentsOfArray:(NSArray *)array { NSEnumerator * enumerator = [array objectEnumerator]; id value; int counter = 0; while (value = [enumerator nextObject]) { [self populateNode:node withKey:[NSString stringWithFormat:@"%d",counter] value:value]; counter++; } } @end