diff --git a/AVRsack.xcodeproj/project.pbxproj b/AVRsack.xcodeproj/project.pbxproj index 2a02e5a..3fe0bdc 100644 --- a/AVRsack.xcodeproj/project.pbxproj +++ b/AVRsack.xcodeproj/project.pbxproj @@ -14,11 +14,11 @@ 9501D80C1A17025C0034C530 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9501D80A1A17025C0034C530 /* MainMenu.xib */; }; 9501D8181A17025C0034C530 /* AVRsackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9501D8171A17025C0034C530 /* AVRsackTests.swift */; }; 950AB9271A296A160033A9DA /* ProjIcon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 950AB9261A296A160033A9DA /* ProjIcon.icns */; }; - 950AB9291A2D4F9B0033A9DA /* ASSerial.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950AB9281A2D4F9B0033A9DA /* ASSerial.swift */; }; 951CD1741A23C9FC0066C1A1 /* ASBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 951CD1731A23C9FC0066C1A1 /* ASBuilder.swift */; }; 951CD1771A2615000066C1A1 /* BuildProject in Resources */ = {isa = PBXBuildFile; fileRef = 951CD1761A2615000066C1A1 /* BuildProject */; }; 95468DDF1A228BE600668EE2 /* ASHardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95468DDE1A228BE600668EE2 /* ASHardware.swift */; }; 95468DE31A228E1300668EE2 /* Defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 95468DE21A228E1300668EE2 /* Defaults.plist */; }; + 95539B681A3E7EAF00D8595C /* ASSerial.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95539B671A3E7EAF00D8595C /* ASSerial.mm */; }; 95A7C6401A38914300EF1963 /* ASPreferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 95A7C63E1A38914300EF1963 /* ASPreferences.xib */; }; 95A7C6461A3894C900EF1963 /* ASPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A7C6451A3894C900EF1963 /* ASPreferences.swift */; }; 95BF80EB1A185C9E0004A693 /* ASFileTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95BF80EA1A185C9E0004A693 /* ASFileTree.swift */; }; @@ -76,11 +76,12 @@ 9501D8161A17025C0034C530 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9501D8171A17025C0034C530 /* AVRsackTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVRsackTests.swift; sourceTree = ""; }; 950AB9261A296A160033A9DA /* ProjIcon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ProjIcon.icns; path = IconResources/ProjIcon.icns; sourceTree = ""; }; - 950AB9281A2D4F9B0033A9DA /* ASSerial.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASSerial.swift; sourceTree = ""; }; 951CD1731A23C9FC0066C1A1 /* ASBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASBuilder.swift; sourceTree = ""; }; 951CD1761A2615000066C1A1 /* BuildProject */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; path = BuildProject; sourceTree = ""; }; 95468DDE1A228BE600668EE2 /* ASHardware.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASHardware.swift; sourceTree = ""; }; 95468DE21A228E1300668EE2 /* Defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Defaults.plist; sourceTree = ""; }; + 95539B661A3E7EAF00D8595C /* ASSerial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSerial.h; sourceTree = ""; }; + 95539B671A3E7EAF00D8595C /* ASSerial.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASSerial.mm; sourceTree = ""; }; 958D76811A17DA1C00917D96 /* AVRsack-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AVRsack-Bridging-Header.h"; sourceTree = ""; }; 95A7C63F1A38914300EF1963 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ASPreferences.xib; sourceTree = ""; }; 95A7C6451A3894C900EF1963 /* ASPreferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASPreferences.swift; sourceTree = ""; }; @@ -173,10 +174,11 @@ 9501D8031A17025C0034C530 /* ASProjDoc.swift */, 95BF80EA1A185C9E0004A693 /* ASFileTree.swift */, 95468DDE1A228BE600668EE2 /* ASHardware.swift */, - 950AB9281A2D4F9B0033A9DA /* ASSerial.swift */, 951CD1731A23C9FC0066C1A1 /* ASBuilder.swift */, 95A7C6451A3894C900EF1963 /* ASPreferences.swift */, 951CD1761A2615000066C1A1 /* BuildProject */, + 95539B661A3E7EAF00D8595C /* ASSerial.h */, + 95539B671A3E7EAF00D8595C /* ASSerial.mm */, ); name = Source; sourceTree = ""; @@ -349,9 +351,9 @@ buildActionMask = 2147483647; files = ( 9501D8041A17025C0034C530 /* ASProjDoc.swift in Sources */, + 95539B681A3E7EAF00D8595C /* ASSerial.mm in Sources */, 95468DDF1A228BE600668EE2 /* ASHardware.swift in Sources */, 951CD1741A23C9FC0066C1A1 /* ASBuilder.swift in Sources */, - 950AB9291A2D4F9B0033A9DA /* ASSerial.swift in Sources */, 9501D8021A17025C0034C530 /* ASApplication.swift in Sources */, 95BF80EB1A185C9E0004A693 /* ASFileTree.swift in Sources */, 95A7C6461A3894C900EF1963 /* ASPreferences.swift in Sources */, diff --git a/AVRsack/ASProjDoc.swift b/AVRsack/ASProjDoc.swift index b2356fb..ecb87c1 100644 --- a/AVRsack/ASProjDoc.swift +++ b/AVRsack/ASProjDoc.swift @@ -352,7 +352,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate { willChangeValueForKey("hasValidPort") portTool.removeAllItems() portTool.addItemWithTitle("Title") - portTool.addItemsWithTitles(ASSerial.instance().ports()) + portTool.addItemsWithTitles(ASSerial.ports()) portTool.setTitle(port) didChangeValueForKey("hasValidPort") } @@ -453,7 +453,7 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate { var hasValidPort : Bool { get { - return (ASSerial.instance().ports() as NSArray).containsObject(port) + return (ASSerial.ports() as NSArray).containsObject(port) } } class func keyPathsForValuesAffectingHasValidPort() -> NSSet { diff --git a/AVRsack/ASSerial.h b/AVRsack/ASSerial.h new file mode 100644 index 0000000..686a6a8 --- /dev/null +++ b/AVRsack/ASSerial.h @@ -0,0 +1,18 @@ +// +// ASSerial.h +// AVRsack +// +// Created by Matthias Neeracher on 12/15/14. +// Copyright © 2014 Aere Perennius. All rights reserved. +// + +#import + +extern NSString * kASSerialPortsChanged; + +@interface ASSerial : NSObject + ++ (NSArray *) ports; ++ (NSFileHandle *)openPort:(NSString *) port withSpeed:(int)speed; + +@end diff --git a/AVRsack/ASSerial.mm b/AVRsack/ASSerial.mm new file mode 100644 index 0000000..05fb65f --- /dev/null +++ b/AVRsack/ASSerial.mm @@ -0,0 +1,38 @@ +// +// ASSerial.m +// AVRsack +// +// Created by Matthias Neeracher on 12/15/14. +// Copyright © 2014 Aere Perennius. All rights reserved. +// + +#import "ASSerial.h" + +#include + +static dispatch_source_t watchSlashDev; + +NSString * kASSerialPortsChanged = @"PortsChanged"; + +@implementation ASSerial + ++ (void)initialize { + int fd = open("/dev", O_EVTONLY); + watchSlashDev = + dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, fd, DISPATCH_VNODE_WRITE, dispatch_get_main_queue()); + dispatch_source_set_event_handler(watchSlashDev, ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:kASSerialPortsChanged object: nil]; + }); + dispatch_resume(watchSlashDev); +} + ++ (NSArray *)ports { + NSMutableArray * cuPorts = [NSMutableArray array]; + for (NSString * port in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/dev" error: nil]) { + if ([[port substringToIndex:2] isEqualToString:@"cu"]) + [cuPorts addObject:[@"/dev/" stringByAppendingString:port]]; + } + return cuPorts; +} + +@end diff --git a/AVRsack/ASSerial.swift b/AVRsack/ASSerial.swift deleted file mode 100644 index feef296..0000000 --- a/AVRsack/ASSerial.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// ASSerial.swift -// AVRsack -// -// Created by Matthias Neeracher on 12/2/14. -// Copyright © 2014 Aere Perennius. All rights reserved. -// - -import Foundation - -let kASSerialPortsChanged = "PortsChanged" - -class ASSerialWatcher { -} - -private let serialInstance = ASSerial() - -class ASSerial { - class func instance() -> ASSerial { return serialInstance } - - let watchSlashDev : dispatch_source_t - init() { - let fd = open("/dev", O_EVTONLY) - watchSlashDev = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, UInt(fd), DISPATCH_VNODE_WRITE, dispatch_get_main_queue()) - dispatch_source_set_event_handler(watchSlashDev) { () -> Void in - NSNotificationCenter.defaultCenter().postNotificationName(kASSerialPortsChanged, object: nil) - } - dispatch_resume(watchSlashDev) - } - - func ports() -> [String] { - let devices = NSFileManager.defaultManager().contentsOfDirectoryAtPath("/dev", error: nil)! - var cuDevs = [String]() - for dev in devices as [String] { - if dev.hasPrefix("cu") { - cuDevs.append("/dev/"+dev) - } - } - return cuDevs - } -} \ No newline at end of file diff --git a/AVRsack/AVRsack-Bridging-Header.h b/AVRsack/AVRsack-Bridging-Header.h index 7b757d3..4305640 100644 --- a/AVRsack/AVRsack-Bridging-Header.h +++ b/AVRsack/AVRsack-Bridging-Header.h @@ -4,3 +4,5 @@ #import #import #import + +#import "ASSerial.h" \ No newline at end of file