2 // usblisterAppDelegate.m
5 // Created by Rex Feany on 4/8/11.
6 // Copyright 2011 Fnordsoft, Inc. All rights reserved.
9 #import "usblisterAppDelegate.h"
12 #include <IOKit/IOCFPlugIn.h>
13 #include <IOKit/hid/IOHIDKeys.h>
14 #include <CoreFoundation/CoreFoundation.h>
16 #import "OutlineData.h"
18 @implementation usblisterAppDelegate
29 static NSArray *kv_pair(NSString *key, id value)
31 return [NSArray arrayWithObjects:key, value, nil];
34 static NSArray *dict_to_array(NSDictionary *d)
36 NSMutableArray *a = [NSMutableArray array];
37 [d enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
38 if ([obj isKindOfClass:[NSDictionary class]]) {
39 obj = dict_to_array(obj);
41 [a addObject:kv_pair(key, obj)];
47 static BOOL iterate(NSMutableArray *hash_a, NSMutableArray *array_a, const io_name_t plane) {
49 io_iterator_t hidObjectIterator = 0;
50 io_object_t hidDevice = IO_OBJECT_NULL;
51 CFMutableDictionaryRef hidProperties = 0;
53 result = IORegistryCreateIterator(kIOMasterPortDefault, kIOUSBPlane, kIORegistryIterateRecursively, &hidObjectIterator);
55 if ((result != kIOReturnSuccess) || (hidObjectIterator == 0)) {
56 NSLog(@"Can't obtain an IO iterator\n");
60 while ((hidDevice = IOIteratorNext(hidObjectIterator))) {
62 result = IORegistryEntryCreateCFProperties(hidDevice, &hidProperties,
63 kCFAllocatorDefault, kNilOptions);
64 if ((result == KERN_SUCCESS) && hidProperties) {
65 NSDictionary *d = (NSDictionary *)hidProperties;
66 NSString *s = [d objectForKey:@"USB Product Name"];
69 CFRetain(hidProperties);
71 [array_a addObject:kv_pair(s, dict_to_array(d))];
74 IOObjectRelease(hidDevice);
76 IOObjectRelease(hidObjectIterator);
80 static BOOL magic(NSMutableArray *hash_a, NSMutableArray *array_a) {
81 [hash_a removeAllObjects];
82 [array_a removeAllObjects];
84 if (!iterate(hash_a, array_a, kIOUSBPlane)) return NO;
89 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
91 // Insert code here to initialize your application
92 [self performSelector:@selector(scanClick:) withObject:nil afterDelay:.3];
96 - (IBAction)scanClick:(id)sender {
97 if (self.hash_a == nil) {
98 self.hash_a = [NSMutableArray array];
100 if (self.array_a == nil) {
101 self.array_a = [NSMutableArray array];
103 if (self.data == nil) {
104 self.data = [[OutlineData alloc] init];
105 self.data.data = self.array_a;
106 [self.outline setDataSource:self.data];
108 magic(self.hash_a, self.array_a);
109 [self.field setString:[NSString stringWithFormat:@"%@", self.hash_a]];
110 [self.outline reloadData];
113 - (IBAction)saveClick:(id)sender {
114 NSSavePanel *spanel = [NSSavePanel savePanel];
115 NSArray *array = [NSArray arrayWithObject:@"txt"];
117 [spanel setAllowedFileTypes:array];
119 if ([spanel runModal] == NSFileHandlingPanelOKButton) {
120 NSString *str = [self.field string];
121 [str writeToURL:[spanel URL] atomically:FALSE encoding:NSASCIIStringEncoding error:NULL];
125 - (BOOL)textView:(NSTextView *)aTextView shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString {