├── MacLight.xcodeproj └── project.pbxproj ├── MacLight ├── MacLight-Info.plist ├── MacLight-Prefix.pch ├── MacLightAppDelegate.h ├── MacLightAppDelegate.m ├── OpenGLScreenReader.h ├── OpenGLScreenReader.m ├── en.lproj │ ├── Credits.rtf │ ├── InfoPlist.strings │ └── MainMenu.xib └── main.m └── readme.md /MacLight.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DA071F7913B7409D00BB98F9 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA071F7813B7409D00BB98F9 /* Cocoa.framework */; }; 11 | DA071F8313B7409D00BB98F9 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA071F8113B7409D00BB98F9 /* InfoPlist.strings */; }; 12 | DA071F8613B7409D00BB98F9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DA071F8513B7409D00BB98F9 /* main.m */; }; 13 | DA071F8913B7409D00BB98F9 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = DA071F8713B7409D00BB98F9 /* Credits.rtf */; }; 14 | DA071F8C13B7409D00BB98F9 /* MacLightAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DA071F8B13B7409D00BB98F9 /* MacLightAppDelegate.m */; }; 15 | DA071F8F13B7409D00BB98F9 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DA071F8D13B7409D00BB98F9 /* MainMenu.xib */; }; 16 | DA071FA513B7490900BB98F9 /* OpenGLScreenReader.m in Sources */ = {isa = PBXBuildFile; fileRef = DA071FA413B7490900BB98F9 /* OpenGLScreenReader.m */; }; 17 | DA071FA713B753C000BB98F9 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA071FA613B753C000BB98F9 /* IOKit.framework */; }; 18 | DA071FA913B753CC00BB98F9 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA071FA813B753CC00BB98F9 /* OpenGL.framework */; }; 19 | DADAE65B13BCA28400DEEDA7 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DADAE65A13BCA28400DEEDA7 /* CoreVideo.framework */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | DA071F7413B7409D00BB98F9 /* MacLight.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MacLight.app; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | DA071F7813B7409D00BB98F9 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 25 | DA071F7B13B7409D00BB98F9 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 26 | DA071F7C13B7409D00BB98F9 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 27 | DA071F7D13B7409D00BB98F9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 28 | DA071F8013B7409D00BB98F9 /* MacLight-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MacLight-Info.plist"; sourceTree = ""; }; 29 | DA071F8213B7409D00BB98F9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 30 | DA071F8413B7409D00BB98F9 /* MacLight-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MacLight-Prefix.pch"; sourceTree = ""; }; 31 | DA071F8513B7409D00BB98F9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32 | DA071F8813B7409D00BB98F9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; 33 | DA071F8A13B7409D00BB98F9 /* MacLightAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MacLightAppDelegate.h; sourceTree = ""; }; 34 | DA071F8B13B7409D00BB98F9 /* MacLightAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MacLightAppDelegate.m; sourceTree = ""; }; 35 | DA071F8E13B7409D00BB98F9 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; 36 | DA071FA313B7490900BB98F9 /* OpenGLScreenReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenGLScreenReader.h; sourceTree = ""; }; 37 | DA071FA413B7490900BB98F9 /* OpenGLScreenReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OpenGLScreenReader.m; sourceTree = ""; }; 38 | DA071FA613B753C000BB98F9 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 39 | DA071FA813B753CC00BB98F9 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; 40 | DADAE65A13BCA28400DEEDA7 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | DA071F7113B7409D00BB98F9 /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | DADAE65B13BCA28400DEEDA7 /* CoreVideo.framework in Frameworks */, 49 | DA071FA913B753CC00BB98F9 /* OpenGL.framework in Frameworks */, 50 | DA071FA713B753C000BB98F9 /* IOKit.framework in Frameworks */, 51 | DA071F7913B7409D00BB98F9 /* Cocoa.framework in Frameworks */, 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | DA071F6913B7409D00BB98F9 = { 59 | isa = PBXGroup; 60 | children = ( 61 | DA071F7E13B7409D00BB98F9 /* MacLight */, 62 | DA071F7713B7409D00BB98F9 /* Frameworks */, 63 | DA071F7513B7409D00BB98F9 /* Products */, 64 | ); 65 | sourceTree = ""; 66 | }; 67 | DA071F7513B7409D00BB98F9 /* Products */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | DA071F7413B7409D00BB98F9 /* MacLight.app */, 71 | ); 72 | name = Products; 73 | sourceTree = ""; 74 | }; 75 | DA071F7713B7409D00BB98F9 /* Frameworks */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | DADAE65A13BCA28400DEEDA7 /* CoreVideo.framework */, 79 | DA071FA813B753CC00BB98F9 /* OpenGL.framework */, 80 | DA071FA613B753C000BB98F9 /* IOKit.framework */, 81 | DA071F7813B7409D00BB98F9 /* Cocoa.framework */, 82 | DA071F7A13B7409D00BB98F9 /* Other Frameworks */, 83 | ); 84 | name = Frameworks; 85 | sourceTree = ""; 86 | }; 87 | DA071F7A13B7409D00BB98F9 /* Other Frameworks */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | DA071F7B13B7409D00BB98F9 /* AppKit.framework */, 91 | DA071F7C13B7409D00BB98F9 /* CoreData.framework */, 92 | DA071F7D13B7409D00BB98F9 /* Foundation.framework */, 93 | ); 94 | name = "Other Frameworks"; 95 | sourceTree = ""; 96 | }; 97 | DA071F7E13B7409D00BB98F9 /* MacLight */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | DA071F8A13B7409D00BB98F9 /* MacLightAppDelegate.h */, 101 | DA071F8B13B7409D00BB98F9 /* MacLightAppDelegate.m */, 102 | DA071F8D13B7409D00BB98F9 /* MainMenu.xib */, 103 | DA071FA313B7490900BB98F9 /* OpenGLScreenReader.h */, 104 | DA071FA413B7490900BB98F9 /* OpenGLScreenReader.m */, 105 | DA071F7F13B7409D00BB98F9 /* Supporting Files */, 106 | ); 107 | path = MacLight; 108 | sourceTree = ""; 109 | }; 110 | DA071F7F13B7409D00BB98F9 /* Supporting Files */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | DA071F8013B7409D00BB98F9 /* MacLight-Info.plist */, 114 | DA071F8113B7409D00BB98F9 /* InfoPlist.strings */, 115 | DA071F8413B7409D00BB98F9 /* MacLight-Prefix.pch */, 116 | DA071F8513B7409D00BB98F9 /* main.m */, 117 | DA071F8713B7409D00BB98F9 /* Credits.rtf */, 118 | ); 119 | name = "Supporting Files"; 120 | sourceTree = ""; 121 | }; 122 | /* End PBXGroup section */ 123 | 124 | /* Begin PBXNativeTarget section */ 125 | DA071F7313B7409D00BB98F9 /* MacLight */ = { 126 | isa = PBXNativeTarget; 127 | buildConfigurationList = DA071F9213B7409D00BB98F9 /* Build configuration list for PBXNativeTarget "MacLight" */; 128 | buildPhases = ( 129 | DA071F7013B7409D00BB98F9 /* Sources */, 130 | DA071F7113B7409D00BB98F9 /* Frameworks */, 131 | DA071F7213B7409D00BB98F9 /* Resources */, 132 | ); 133 | buildRules = ( 134 | ); 135 | dependencies = ( 136 | ); 137 | name = MacLight; 138 | productName = MacLight; 139 | productReference = DA071F7413B7409D00BB98F9 /* MacLight.app */; 140 | productType = "com.apple.product-type.application"; 141 | }; 142 | /* End PBXNativeTarget section */ 143 | 144 | /* Begin PBXProject section */ 145 | DA071F6B13B7409D00BB98F9 /* Project object */ = { 146 | isa = PBXProject; 147 | attributes = { 148 | LastUpgradeCheck = 0420; 149 | }; 150 | buildConfigurationList = DA071F6E13B7409D00BB98F9 /* Build configuration list for PBXProject "MacLight" */; 151 | compatibilityVersion = "Xcode 3.2"; 152 | developmentRegion = English; 153 | hasScannedForEncodings = 0; 154 | knownRegions = ( 155 | en, 156 | ); 157 | mainGroup = DA071F6913B7409D00BB98F9; 158 | productRefGroup = DA071F7513B7409D00BB98F9 /* Products */; 159 | projectDirPath = ""; 160 | projectRoot = ""; 161 | targets = ( 162 | DA071F7313B7409D00BB98F9 /* MacLight */, 163 | ); 164 | }; 165 | /* End PBXProject section */ 166 | 167 | /* Begin PBXResourcesBuildPhase section */ 168 | DA071F7213B7409D00BB98F9 /* Resources */ = { 169 | isa = PBXResourcesBuildPhase; 170 | buildActionMask = 2147483647; 171 | files = ( 172 | DA071F8313B7409D00BB98F9 /* InfoPlist.strings in Resources */, 173 | DA071F8913B7409D00BB98F9 /* Credits.rtf in Resources */, 174 | DA071F8F13B7409D00BB98F9 /* MainMenu.xib in Resources */, 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | /* End PBXResourcesBuildPhase section */ 179 | 180 | /* Begin PBXSourcesBuildPhase section */ 181 | DA071F7013B7409D00BB98F9 /* Sources */ = { 182 | isa = PBXSourcesBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | DA071F8613B7409D00BB98F9 /* main.m in Sources */, 186 | DA071F8C13B7409D00BB98F9 /* MacLightAppDelegate.m in Sources */, 187 | DA071FA513B7490900BB98F9 /* OpenGLScreenReader.m in Sources */, 188 | ); 189 | runOnlyForDeploymentPostprocessing = 0; 190 | }; 191 | /* End PBXSourcesBuildPhase section */ 192 | 193 | /* Begin PBXVariantGroup section */ 194 | DA071F8113B7409D00BB98F9 /* InfoPlist.strings */ = { 195 | isa = PBXVariantGroup; 196 | children = ( 197 | DA071F8213B7409D00BB98F9 /* en */, 198 | ); 199 | name = InfoPlist.strings; 200 | sourceTree = ""; 201 | }; 202 | DA071F8713B7409D00BB98F9 /* Credits.rtf */ = { 203 | isa = PBXVariantGroup; 204 | children = ( 205 | DA071F8813B7409D00BB98F9 /* en */, 206 | ); 207 | name = Credits.rtf; 208 | sourceTree = ""; 209 | }; 210 | DA071F8D13B7409D00BB98F9 /* MainMenu.xib */ = { 211 | isa = PBXVariantGroup; 212 | children = ( 213 | DA071F8E13B7409D00BB98F9 /* en */, 214 | ); 215 | name = MainMenu.xib; 216 | sourceTree = ""; 217 | }; 218 | /* End PBXVariantGroup section */ 219 | 220 | /* Begin XCBuildConfiguration section */ 221 | DA071F9013B7409D00BB98F9 /* Debug */ = { 222 | isa = XCBuildConfiguration; 223 | buildSettings = { 224 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 225 | GCC_C_LANGUAGE_STANDARD = gnu99; 226 | GCC_OPTIMIZATION_LEVEL = 0; 227 | GCC_PREPROCESSOR_DEFINITIONS = DEBUG; 228 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 229 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 230 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 231 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 232 | GCC_WARN_UNUSED_VARIABLE = YES; 233 | MACOSX_DEPLOYMENT_TARGET = 10.6; 234 | ONLY_ACTIVE_ARCH = YES; 235 | SDKROOT = macosx; 236 | }; 237 | name = Debug; 238 | }; 239 | DA071F9113B7409D00BB98F9 /* Release */ = { 240 | isa = XCBuildConfiguration; 241 | buildSettings = { 242 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 243 | GCC_C_LANGUAGE_STANDARD = gnu99; 244 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 245 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 246 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 247 | GCC_WARN_UNUSED_VARIABLE = YES; 248 | MACOSX_DEPLOYMENT_TARGET = 10.6; 249 | SDKROOT = macosx; 250 | }; 251 | name = Release; 252 | }; 253 | DA071F9313B7409D00BB98F9 /* Debug */ = { 254 | isa = XCBuildConfiguration; 255 | buildSettings = { 256 | ALWAYS_SEARCH_USER_PATHS = NO; 257 | COPY_PHASE_STRIP = NO; 258 | GCC_DYNAMIC_NO_PIC = NO; 259 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 260 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 261 | GCC_PREFIX_HEADER = "MacLight/MacLight-Prefix.pch"; 262 | INFOPLIST_FILE = "MacLight/MacLight-Info.plist"; 263 | PRODUCT_NAME = "$(TARGET_NAME)"; 264 | WRAPPER_EXTENSION = app; 265 | }; 266 | name = Debug; 267 | }; 268 | DA071F9413B7409D00BB98F9 /* Release */ = { 269 | isa = XCBuildConfiguration; 270 | buildSettings = { 271 | ALWAYS_SEARCH_USER_PATHS = NO; 272 | COPY_PHASE_STRIP = YES; 273 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 274 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 275 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 276 | GCC_PREFIX_HEADER = "MacLight/MacLight-Prefix.pch"; 277 | INFOPLIST_FILE = "MacLight/MacLight-Info.plist"; 278 | PRODUCT_NAME = "$(TARGET_NAME)"; 279 | WRAPPER_EXTENSION = app; 280 | }; 281 | name = Release; 282 | }; 283 | /* End XCBuildConfiguration section */ 284 | 285 | /* Begin XCConfigurationList section */ 286 | DA071F6E13B7409D00BB98F9 /* Build configuration list for PBXProject "MacLight" */ = { 287 | isa = XCConfigurationList; 288 | buildConfigurations = ( 289 | DA071F9013B7409D00BB98F9 /* Debug */, 290 | DA071F9113B7409D00BB98F9 /* Release */, 291 | ); 292 | defaultConfigurationIsVisible = 0; 293 | defaultConfigurationName = Release; 294 | }; 295 | DA071F9213B7409D00BB98F9 /* Build configuration list for PBXNativeTarget "MacLight" */ = { 296 | isa = XCConfigurationList; 297 | buildConfigurations = ( 298 | DA071F9313B7409D00BB98F9 /* Debug */, 299 | DA071F9413B7409D00BB98F9 /* Release */, 300 | ); 301 | defaultConfigurationIsVisible = 0; 302 | defaultConfigurationName = Release; 303 | }; 304 | /* End XCConfigurationList section */ 305 | }; 306 | rootObject = DA071F6B13B7409D00BB98F9 /* Project object */; 307 | } 308 | -------------------------------------------------------------------------------- /MacLight/MacLight-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | skattyadz.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | LSUIElement 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /MacLight/MacLight-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'MacLight' target in the 'MacLight' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /MacLight/MacLightAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // MacLightAppDelegate.h 3 | // MacLight 4 | // 5 | // Created by skattyadz on 26/06/2011. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OpenGLScreenReader.h" 11 | 12 | // import IOKit headers 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | 20 | 21 | @interface MacLightAppDelegate : NSObject { 22 | @private 23 | IBOutlet NSMenu *statusMenu; 24 | NSStatusItem *statusItem; 25 | IBOutlet NSMenuItem *captureMenuItem; 26 | IBOutlet NSMenuItem *manualMenuItem; 27 | IBOutlet NSMenuItem *startupMenuItem; 28 | 29 | NSString *selectedSerialPort; 30 | NSMutableArray *serialPortList; 31 | OpenGLScreenReader *mOpenGLScreenReader; 32 | 33 | struct termios gOriginalTTYAttrs; // Hold the original termios attributes so we can reset them on quit ( best practice ) 34 | int serialFileDescriptor; // file handle to the serial port 35 | NSTimer *sampleTimer; 36 | 37 | CVDisplayLinkRef displayLink; 38 | } 39 | // 40 | - (NSString *) openSerialPort: (NSString *)serialPortFile baud: (speed_t)baudRate; 41 | - (void) loadSerialPortList; 42 | - (void) writeColor: (NSColor *)color; 43 | - (void) writeByte: (int) val; 44 | - (void) sampleScreen; 45 | - (IBAction)startCapturing:(id)sender; 46 | - (void)stopCapturing; 47 | - (void) colorPicked:(NSColorWell *) picker; 48 | - (IBAction)openColorPicker:(id)sender; 49 | - (IBAction)closeApp:(id)sender; 50 | - (IBAction)toggleLaunchAtStartup:(id)sender; 51 | - (LSSharedFileListItemRef)itemRefInLoginItems; 52 | - (BOOL)isLaunchAtStartup; 53 | 54 | @end 55 | 56 | CVReturn DisplayLinkCallback ( 57 | CVDisplayLinkRef displayLink, 58 | const CVTimeStamp *inNow, 59 | const CVTimeStamp *inOutputTime, 60 | CVOptionFlags flagsIn, 61 | CVOptionFlags *flagsOut, 62 | void *displayLinkContext); -------------------------------------------------------------------------------- /MacLight/MacLightAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // MacLightAppDelegate.m 3 | // MacLight 4 | // 5 | // Created by skattyadz on 26/06/2011. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "MacLightAppDelegate.h" 10 | 11 | @implementation MacLightAppDelegate 12 | 13 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 14 | 15 | } 16 | 17 | -(void)awakeFromNib{ 18 | statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain]; 19 | [statusItem setMenu:statusMenu]; 20 | [statusItem setTitle:@"MacLight"]; 21 | [statusItem setHighlightMode:YES]; 22 | 23 | [startupMenuItem setState:[self isLaunchAtStartup]]; 24 | 25 | // we don't have a serial port open yet 26 | serialFileDescriptor = -1; 27 | 28 | [self loadSerialPortList]; 29 | 30 | for (NSString *serialPort in serialPortList) { 31 | NSLog(@"Found a port: %@", serialPort); 32 | if ([serialPort rangeOfString:@"usbserial"].location != NSNotFound || [serialPort rangeOfString:@"usbmodem"].location != NSNotFound) { 33 | selectedSerialPort = serialPort; 34 | NSLog(@"Found an arduino: %@", serialPort); 35 | } 36 | } 37 | [self openSerialPort: selectedSerialPort baud:9600]; 38 | 39 | // [self startCapturing:nil]; 40 | } 41 | 42 | 43 | CVReturn DisplayLinkCallback ( 44 | CVDisplayLinkRef displayLink, 45 | const CVTimeStamp *inNow, 46 | const CVTimeStamp *inOutputTime, 47 | CVOptionFlags flagsIn, 48 | CVOptionFlags *flagsOut, 49 | void *displayLinkContext) 50 | { 51 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 52 | [(MacLightAppDelegate*) displayLinkContext sampleScreen]; 53 | [pool release]; 54 | return YES; 55 | } 56 | 57 | - (void)dealloc { 58 | CVDisplayLinkStop(displayLink); 59 | [super dealloc]; 60 | } 61 | 62 | 63 | -(IBAction)closeApp:(id)sender{ 64 | // Add a delay to ensure that it terminates at the top of the next pass through the event loop 65 | [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; 66 | } 67 | 68 | 69 | - (void) loadSerialPortList { 70 | io_object_t serialPort; 71 | io_iterator_t serialPortIterator; 72 | 73 | serialPortList = [[NSMutableArray alloc] init]; 74 | 75 | // ask for all the serial ports 76 | IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(kIOSerialBSDServiceValue), &serialPortIterator); 77 | 78 | // loop through all the serial ports and add them to the array 79 | while ((serialPort = IOIteratorNext(serialPortIterator))) { 80 | [serialPortList addObject: 81 | [(NSString*)IORegistryEntryCreateCFProperty(serialPort, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0) autorelease]]; 82 | 83 | IOObjectRelease(serialPort); 84 | } 85 | 86 | IOObjectRelease(serialPortIterator); 87 | } 88 | 89 | 90 | - (void)sampleScreen { 91 | NSAssert(mOpenGLScreenReader, @"No screen reader"); 92 | NSColor *averageCol = [mOpenGLScreenReader readFullScreenToBuffer]; 93 | [self writeColor:averageCol]; 94 | } 95 | 96 | 97 | - (IBAction)startCapturing:(id)sender 98 | { 99 | [captureMenuItem setState:NSOnState]; 100 | [manualMenuItem setState:NSOffState]; 101 | 102 | mOpenGLScreenReader = [[[OpenGLScreenReader alloc] init] retain]; 103 | NSAssert( mOpenGLScreenReader != 0, @"OpenGLScreenReader alloc failed"); 104 | 105 | CVReturn error = kCVReturnSuccess; 106 | CGDirectDisplayID displayID = CGMainDisplayID(); 107 | 108 | error = CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink); 109 | if(error) 110 | { 111 | NSLog(@"DisplayLink created with error:%d", error); 112 | displayLink = NULL; 113 | } 114 | error = CVDisplayLinkSetOutputCallback(displayLink, DisplayLinkCallback, self); 115 | if(error) 116 | { 117 | NSLog(@"DisplayLink callback creation failed with error:%d", error); 118 | displayLink = NULL; 119 | } 120 | 121 | if (displayLink){ 122 | CVDisplayLinkStart(displayLink); 123 | } 124 | } 125 | 126 | - (void)stopCapturing { 127 | CVDisplayLinkStop(displayLink); 128 | 129 | if (sampleTimer) { 130 | [captureMenuItem setState:NSOffState]; 131 | [manualMenuItem setState:NSOnState]; 132 | [sampleTimer invalidate]; 133 | [sampleTimer release]; 134 | sampleTimer = nil; 135 | if (mOpenGLScreenReader){ 136 | [mOpenGLScreenReader release]; 137 | mOpenGLScreenReader = nil; 138 | } 139 | } 140 | } 141 | 142 | // open the serial port 143 | // - nil is returned on success 144 | // - an error message is returned otherwise 145 | - (NSString *) openSerialPort: (NSString *)serialPortFile baud: (speed_t)baudRate { 146 | int success; 147 | 148 | // close the port if it is already open 149 | if (serialFileDescriptor != -1) { 150 | close(serialFileDescriptor); 151 | serialFileDescriptor = -1; 152 | 153 | // re-opening the same port REALLY fast will fail spectacularly... better to sleep a sec 154 | sleep(0.5); 155 | } 156 | 157 | // c-string path to serial-port file 158 | const char *bsdPath = [serialPortFile cStringUsingEncoding:NSUTF8StringEncoding]; 159 | 160 | // Hold the original termios attributes we are setting 161 | struct termios options; 162 | 163 | // receive latency ( in microseconds ) 164 | unsigned long mics = 3; 165 | 166 | // error message string 167 | NSString *errorMessage = nil; 168 | 169 | // open the port 170 | // O_NONBLOCK causes the port to open without any delay (we'll block with another call) 171 | serialFileDescriptor = open(bsdPath, O_RDWR | O_NOCTTY | O_NONBLOCK ); 172 | 173 | if (serialFileDescriptor == -1) { 174 | // check if the port opened correctly 175 | errorMessage = @"Error: couldn't open serial port"; 176 | } else { 177 | // TIOCEXCL causes blocking of non-root processes on this serial-port 178 | success = ioctl(serialFileDescriptor, TIOCEXCL); 179 | if ( success == -1) { 180 | errorMessage = @"Error: couldn't obtain lock on serial port"; 181 | } else { 182 | success = fcntl(serialFileDescriptor, F_SETFL, 0); 183 | if ( success == -1) { 184 | // clear the O_NONBLOCK flag; all calls from here on out are blocking for non-root processes 185 | errorMessage = @"Error: couldn't obtain lock on serial port"; 186 | } else { 187 | // Get the current options and save them so we can restore the default settings later. 188 | success = tcgetattr(serialFileDescriptor, &gOriginalTTYAttrs); 189 | if ( success == -1) { 190 | errorMessage = @"Error: couldn't get serial attributes"; 191 | } else { 192 | // copy the old termios settings into the current 193 | // you want to do this so that you get all the control characters assigned 194 | options = gOriginalTTYAttrs; 195 | 196 | /* 197 | cfmakeraw(&options) is equivilent to: 198 | options->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); 199 | options->c_oflag &= ~OPOST; 200 | options->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 201 | options->c_cflag &= ~(CSIZE | PARENB); 202 | options->c_cflag |= CS8; 203 | */ 204 | cfmakeraw(&options); 205 | 206 | // set tty attributes (raw-mode in this case) 207 | success = tcsetattr(serialFileDescriptor, TCSANOW, &options); 208 | if ( success == -1) { 209 | errorMessage = @"Error: coudln't set serial attributes"; 210 | } else { 211 | // Set baud rate (any arbitrary baud rate can be set this way) 212 | success = ioctl(serialFileDescriptor, IOSSIOSPEED, &baudRate); 213 | if ( success == -1) { 214 | errorMessage = @"Error: Baud Rate out of bounds"; 215 | } else { 216 | // Set the receive latency (a.k.a. don't wait to buffer data) 217 | success = ioctl(serialFileDescriptor, IOSSDATALAT, &mics); 218 | if ( success == -1) { 219 | errorMessage = @"Error: coudln't set serial latency"; 220 | } 221 | } 222 | } 223 | } 224 | } 225 | } 226 | } 227 | 228 | // make sure the port is closed if a problem happens 229 | if ((serialFileDescriptor != -1) && (errorMessage != nil)) { 230 | close(serialFileDescriptor); 231 | serialFileDescriptor = -1; 232 | } 233 | 234 | return errorMessage; 235 | } 236 | 237 | - (void) writeColor: (NSColor *) color { 238 | [self writeByte:0x55]; 239 | [self writeByte:0xAA]; 240 | 241 | int val; 242 | val = [color redComponent]*255*0.9; 243 | [self writeByte:val]; 244 | 245 | val = [color greenComponent]*255; 246 | [self writeByte:val]; 247 | 248 | val = [color blueComponent]*255; 249 | [self writeByte:val]; 250 | } 251 | 252 | - (void) writeByte: (int)val { 253 | if(serialFileDescriptor!=-1) { 254 | write(serialFileDescriptor, &val, 1); 255 | } else { 256 | NSLog(@"Tried to write byte but no Serial Port found"); 257 | } 258 | } 259 | 260 | - (IBAction) openColorPicker:(id)sender { 261 | [NSApp activateIgnoringOtherApps:YES]; 262 | [[NSColorPanel sharedColorPanel] setTarget:self]; 263 | [[NSColorPanel sharedColorPanel] setAction:@selector(colorPicked:)]; 264 | [[NSColorPanel sharedColorPanel] makeKeyAndOrderFront:nil]; 265 | } 266 | 267 | - (void) colorPicked: (NSColorWell *) picker{ 268 | [self stopCapturing]; 269 | [self writeColor:picker.color]; 270 | } 271 | 272 | // action sent when serial port selected 273 | - (IBAction) serialPortSelected: (id) cntrl { 274 | // open the serial port 275 | NSString *error = [self openSerialPort: selectedSerialPort baud:9600]; 276 | 277 | if(error!=nil) { 278 | NSLog(error); 279 | } else { 280 | } 281 | } 282 | 283 | - (BOOL)isLaunchAtStartup { 284 | // See if the app is currently in LoginItems. 285 | LSSharedFileListItemRef itemRef = [self itemRefInLoginItems]; 286 | // Store away that boolean. 287 | BOOL isInList = itemRef != nil; 288 | // Release the reference if it exists. 289 | if (itemRef != nil) CFRelease(itemRef); 290 | 291 | return isInList; 292 | } 293 | 294 | - (IBAction)toggleLaunchAtStartup:(id)sender { 295 | // Toggle the state. 296 | BOOL shouldBeToggled = ![self isLaunchAtStartup]; 297 | // Get the LoginItems list. 298 | LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); 299 | if (loginItemsRef == nil) return; 300 | if (shouldBeToggled) { 301 | // Add the app to the LoginItems list. 302 | CFURLRef appUrl = (CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; 303 | LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL); 304 | if (itemRef) CFRelease(itemRef); 305 | } 306 | else { 307 | // Remove the app from the LoginItems list. 308 | LSSharedFileListItemRef itemRef = [self itemRefInLoginItems]; 309 | LSSharedFileListItemRemove(loginItemsRef,itemRef); 310 | if (itemRef != nil) CFRelease(itemRef); 311 | } 312 | CFRelease(loginItemsRef); 313 | [sender setState:shouldBeToggled]; 314 | } 315 | 316 | - (LSSharedFileListItemRef)itemRefInLoginItems { 317 | LSSharedFileListItemRef itemRef = nil; 318 | NSURL *itemUrl = nil; 319 | 320 | // Get the app's URL. 321 | NSURL *appUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; 322 | // Get the LoginItems list. 323 | LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); 324 | if (loginItemsRef == nil) return nil; 325 | // Iterate over the LoginItems. 326 | NSArray *loginItems = (NSArray *)LSSharedFileListCopySnapshot(loginItemsRef, nil); 327 | for (int currentIndex = 0; currentIndex < [loginItems count]; currentIndex++) { 328 | // Get the current LoginItem and resolve its URL. 329 | LSSharedFileListItemRef currentItemRef = (LSSharedFileListItemRef)[loginItems objectAtIndex:currentIndex]; 330 | if (LSSharedFileListItemResolve(currentItemRef, 0, (CFURLRef *) &itemUrl, NULL) == noErr) { 331 | // Compare the URLs for the current LoginItem and the app. 332 | if ([itemUrl isEqual:appUrl]) { 333 | // Save the LoginItem reference. 334 | itemRef = currentItemRef; 335 | } 336 | } 337 | } 338 | // Retain the LoginItem reference. 339 | if (itemRef != nil) CFRetain(itemRef); 340 | // Release the LoginItems lists. 341 | [loginItems release]; 342 | CFRelease(loginItemsRef); 343 | 344 | return itemRef; 345 | } 346 | 347 | 348 | @end -------------------------------------------------------------------------------- /MacLight/OpenGLScreenReader.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | File: OpenGLScreenReader.h 4 | 5 | Abstract: Interface file for OpenGLScreenReader class 6 | 7 | Version: 1.0 8 | 9 | Disclaimer: IMPORTANT: This Apple software is supplied to you by 10 | Apple Inc. ("Apple") in consideration of your agreement to the 11 | following terms, and your use, installation, modification or 12 | redistribution of this Apple software constitutes acceptance of these 13 | terms. If you do not agree with these terms, please do not use, 14 | install, modify or redistribute this Apple software. 15 | 16 | In consideration of your agreement to abide by the following terms, and 17 | subject to these terms, Apple grants you a personal, non-exclusive 18 | license, under Apple's copyrights in this original Apple software (the 19 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 20 | Software, with or without modifications, in source and/or binary forms; 21 | provided that if you redistribute the Apple Software in its entirety and 22 | without modifications, you must retain this notice and the following 23 | text and disclaimers in all such redistributions of the Apple Software. 24 | Neither the name, trademarks, service marks or logos of Apple Inc. 25 | may be used to endorse or promote products derived from the Apple 26 | Software without specific prior written permission from Apple. Except 27 | as expressly stated in this notice, no other rights or licenses, express 28 | or implied, are granted by Apple herein, including but not limited to 29 | any patent rights that may be infringed by your derivative works or by 30 | other works in which the Apple Software may be incorporated. 31 | 32 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 33 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 34 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 35 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 36 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 37 | 38 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 39 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 40 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 41 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 42 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 43 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 44 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 45 | POSSIBILITY OF SUCH DAMAGE. 46 | 47 | Copyright (C) 2007 Apple Inc. All Rights Reserved. 48 | 49 | */ 50 | 51 | #import 52 | #import 53 | 54 | 55 | @interface OpenGLScreenReader : NSObject { 56 | NSOpenGLContext *mGLContext; 57 | void *mData; 58 | long mByteWidth, mWidth, mHeight; 59 | } 60 | 61 | - (NSColor *) readPartialScreenToBuffer: (size_t) width bufferHeight:(size_t) height bufferBaseAddress: (void *) baseAddress; 62 | - (NSColor *) readFullScreenToBuffer; 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /MacLight/OpenGLScreenReader.m: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | File: OpenGLScreenReader.m 4 | 5 | Abstract: OpenGLScreenReader class implementation. Contains 6 | OpenGL code which creates a full-screen OpenGL context 7 | to use for rendering, then calls glReadPixels to read the 8 | actual screen bits. 9 | 10 | Version: 1.0 11 | 12 | */ 13 | 14 | #import "OpenGLScreenReader.h" 15 | 16 | @implementation OpenGLScreenReader 17 | 18 | #pragma mark ---------- Initialization ---------- 19 | 20 | -(id) init 21 | { 22 | if ((self = [super init])) 23 | { 24 | // Create a full-screen OpenGL graphics context 25 | 26 | // Specify attributes of the GL graphics context 27 | NSOpenGLPixelFormatAttribute attributes[] = { 28 | NSOpenGLPFAFullScreen, 29 | NSOpenGLPFAScreenMask, 30 | CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), 31 | (NSOpenGLPixelFormatAttribute) 0 32 | }; 33 | 34 | NSOpenGLPixelFormat *glPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; 35 | if (!glPixelFormat) 36 | { 37 | return nil; 38 | } 39 | 40 | // Create OpenGL context used to render 41 | mGLContext = [[[NSOpenGLContext alloc] initWithFormat:glPixelFormat shareContext:nil] autorelease]; 42 | 43 | // Cleanup, pixel format object no longer needed 44 | [glPixelFormat release]; 45 | 46 | if (!mGLContext) 47 | { 48 | [self release]; 49 | return nil; 50 | } 51 | [mGLContext retain]; 52 | 53 | // Set our context as the current OpenGL context 54 | [mGLContext makeCurrentContext]; 55 | // Set full-screen mode 56 | [mGLContext setFullScreen]; 57 | 58 | NSRect mainScreenRect = [[NSScreen mainScreen] frame]; 59 | mWidth = mainScreenRect.size.width; 60 | mHeight = mainScreenRect.size.height; 61 | 62 | mByteWidth = mWidth * 4; // Assume 4 bytes/pixel for now 63 | mByteWidth = (mByteWidth + 3) & ~3; // Align to 4 bytes 64 | 65 | mData = malloc(mByteWidth * mHeight); 66 | NSAssert( mData != 0, @"malloc failed"); 67 | } 68 | return self; 69 | } 70 | 71 | #pragma mark ---------- Screen Reader ---------- 72 | 73 | // Perform a simple, synchronous full-screen read operation using glReadPixels(). 74 | // Although this is not the most optimal technique, it is sufficient for doing 75 | // simple one-shot screen grabs. 76 | - (NSColor *)readFullScreenToBuffer 77 | { 78 | return [self readPartialScreenToBuffer: mWidth bufferHeight: mHeight bufferBaseAddress: mData]; 79 | } 80 | 81 | // Use this routine if you want to read only a portion of the screen pixels 82 | - (NSColor *)readPartialScreenToBuffer: (size_t) width bufferHeight:(size_t) height bufferBaseAddress: (void *)baseAddress 83 | { 84 | // Set our context as the current OpenGL context 85 | [mGLContext makeCurrentContext]; 86 | 87 | // select front buffer as our source for pixel data 88 | glReadBuffer(GL_FRONT); 89 | 90 | //Read OpenGL context pixels directly. 91 | 92 | // For extra safety, save & restore OpenGL states that are changed 93 | glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); 94 | 95 | glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */ 96 | glPixelStorei(GL_PACK_ROW_LENGTH, 0); 97 | glPixelStorei(GL_PACK_SKIP_ROWS, 0); 98 | glPixelStorei(GL_PACK_SKIP_PIXELS, 0); 99 | 100 | 101 | //Read a block of pixels from the frame buffer 102 | glReadPixels(0, 0, width, height, GL_BGRA, 103 | GL_UNSIGNED_INT_8_8_8_8_REV, 104 | baseAddress); 105 | int pixelIndex; 106 | unsigned char blue, green, red; 107 | unsigned char *restrict tempBuffer = baseAddress; 108 | 109 | NSInteger sumRed = 0; 110 | NSInteger sumGreen = 0; 111 | NSInteger sumBlue = 0; 112 | NSInteger sampleCount = 0; 113 | 114 | NSInteger skipFactor = 10; 115 | NSAssert( skipFactor > 0, @"accuraccy below 1"); 116 | 117 | 118 | int topMargin = 200; 119 | int bottomMargin = 200; 120 | int leftMargin = 200; 121 | int rightMargin = 200; 122 | 123 | NSInteger yPixels = height - topMargin - bottomMargin; 124 | NSInteger xPixels = width - leftMargin - rightMargin; 125 | 126 | for( int j=topMargin; j 2 | 3 | 4 | 1060 5 | 10J869 6 | 1306 7 | 1038.35 8 | 461.00 9 | 10 | com.apple.InterfaceBuilder.CocoaPlugin 11 | 1306 12 | 13 | 14 | YES 15 | NSMenu 16 | NSMenuItem 17 | NSCustomObject 18 | 19 | 20 | YES 21 | com.apple.InterfaceBuilder.CocoaPlugin 22 | 23 | 24 | YES 25 | 26 | YES 27 | 28 | 29 | 30 | 31 | YES 32 | 33 | NSApplication 34 | 35 | 36 | FirstResponder 37 | 38 | 39 | NSApplication 40 | 41 | 42 | MacLightAppDelegate 43 | 44 | 45 | NSFontManager 46 | 47 | 48 | 49 | 50 | YES 51 | 52 | 53 | Screen Average 54 | 55 | 2147483647 56 | 57 | NSImage 58 | NSMenuCheckmark 59 | 60 | 61 | NSImage 62 | NSMenuMixedState 63 | 64 | 65 | 66 | 67 | Pick Color 68 | 69 | 2147483647 70 | 71 | 72 | 73 | 74 | 75 | YES 76 | YES 77 | 78 | 79 | 2147483647 80 | 81 | 82 | 83 | 84 | 85 | Launch on Startup 86 | 87 | 2147483647 88 | 89 | 90 | 91 | 92 | 93 | YES 94 | YES 95 | 96 | 97 | 2147483647 98 | 99 | 100 | 101 | 102 | 103 | Quit 104 | 105 | 2147483647 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | YES 115 | 116 | 117 | statusMenu 118 | 119 | 120 | 121 | 538 122 | 123 | 124 | 125 | openColorPicker 126 | 127 | 128 | 129 | 539 130 | 131 | 132 | 133 | manualMenuItem 134 | 135 | 136 | 137 | 540 138 | 139 | 140 | 141 | captureMenuItem 142 | 143 | 144 | 145 | 541 146 | 147 | 148 | 149 | startCapturing: 150 | 151 | 152 | 153 | 542 154 | 155 | 156 | 157 | closeApp: 158 | 159 | 160 | 161 | 550 162 | 163 | 164 | 165 | startupMenuItem 166 | 167 | 168 | 169 | 553 170 | 171 | 172 | 173 | toggleLaunchAtStartup: 174 | 175 | 176 | 177 | 554 178 | 179 | 180 | 181 | 182 | YES 183 | 184 | 0 185 | 186 | 187 | 188 | 189 | 190 | -2 191 | 192 | 193 | File's Owner 194 | 195 | 196 | -1 197 | 198 | 199 | First Responder 200 | 201 | 202 | -3 203 | 204 | 205 | Application 206 | 207 | 208 | 420 209 | 210 | 211 | 212 | 213 | 494 214 | 215 | 216 | 217 | 218 | 533 219 | 220 | 221 | YES 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 534 233 | 234 | 235 | 236 | 237 | 535 238 | 239 | 240 | 241 | 242 | 546 243 | 244 | 245 | 246 | 247 | 548 248 | 249 | 250 | 251 | 252 | 551 253 | 254 | 255 | 256 | 257 | 552 258 | 259 | 260 | 261 | 262 | 263 | 264 | YES 265 | 266 | YES 267 | -1.IBPluginDependency 268 | -2.IBPluginDependency 269 | -3.IBPluginDependency 270 | 420.IBPluginDependency 271 | 494.IBPluginDependency 272 | 533.IBPluginDependency 273 | 534.IBPluginDependency 274 | 535.IBPluginDependency 275 | 546.IBPluginDependency 276 | 548.IBPluginDependency 277 | 551.IBPluginDependency 278 | 552.IBPluginDependency 279 | 280 | 281 | YES 282 | com.apple.InterfaceBuilder.CocoaPlugin 283 | com.apple.InterfaceBuilder.CocoaPlugin 284 | com.apple.InterfaceBuilder.CocoaPlugin 285 | com.apple.InterfaceBuilder.CocoaPlugin 286 | com.apple.InterfaceBuilder.CocoaPlugin 287 | com.apple.InterfaceBuilder.CocoaPlugin 288 | com.apple.InterfaceBuilder.CocoaPlugin 289 | com.apple.InterfaceBuilder.CocoaPlugin 290 | com.apple.InterfaceBuilder.CocoaPlugin 291 | com.apple.InterfaceBuilder.CocoaPlugin 292 | com.apple.InterfaceBuilder.CocoaPlugin 293 | com.apple.InterfaceBuilder.CocoaPlugin 294 | 295 | 296 | 297 | YES 298 | 299 | 300 | 301 | 302 | 303 | YES 304 | 305 | 306 | 307 | 308 | 554 309 | 310 | 311 | 312 | YES 313 | 314 | MacLightAppDelegate 315 | NSObject 316 | 317 | YES 318 | 319 | YES 320 | closeApp: 321 | openColorPicker: 322 | startCapturing: 323 | toggleLaunchAtStartup: 324 | 325 | 326 | YES 327 | id 328 | id 329 | id 330 | id 331 | 332 | 333 | 334 | YES 335 | 336 | YES 337 | closeApp: 338 | openColorPicker: 339 | startCapturing: 340 | toggleLaunchAtStartup: 341 | 342 | 343 | YES 344 | 345 | closeApp: 346 | id 347 | 348 | 349 | openColorPicker: 350 | id 351 | 352 | 353 | startCapturing: 354 | id 355 | 356 | 357 | toggleLaunchAtStartup: 358 | id 359 | 360 | 361 | 362 | 363 | YES 364 | 365 | YES 366 | captureMenuItem 367 | manualMenuItem 368 | startupMenuItem 369 | statusMenu 370 | 371 | 372 | YES 373 | NSMenuItem 374 | NSMenuItem 375 | NSMenuItem 376 | NSMenu 377 | 378 | 379 | 380 | YES 381 | 382 | YES 383 | captureMenuItem 384 | manualMenuItem 385 | startupMenuItem 386 | statusMenu 387 | 388 | 389 | YES 390 | 391 | captureMenuItem 392 | NSMenuItem 393 | 394 | 395 | manualMenuItem 396 | NSMenuItem 397 | 398 | 399 | startupMenuItem 400 | NSMenuItem 401 | 402 | 403 | statusMenu 404 | NSMenu 405 | 406 | 407 | 408 | 409 | IBProjectSource 410 | ./Classes/MacLightAppDelegate.h 411 | 412 | 413 | 414 | 415 | 0 416 | IBCocoaFramework 417 | 418 | com.apple.InterfaceBuilder.CocoaPlugin.macosx 419 | 420 | 421 | 422 | com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 423 | 424 | 425 | YES 426 | 3 427 | 428 | YES 429 | 430 | YES 431 | NSMenuCheckmark 432 | NSMenuMixedState 433 | 434 | 435 | YES 436 | {9, 8} 437 | {7, 2} 438 | 439 | 440 | 441 | 442 | -------------------------------------------------------------------------------- /MacLight/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MacLight 4 | // 5 | // Created by skattyadz on 26/06/2011. 6 | // Copyright 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | MacLight 2 | -------------- 3 | 4 | Ready for your use, but very much undocumented. 5 | 6 | #### PROBLEMS: 7 | There is an issue with screen capturing in Lion. See issue #1. It is fixable, but I haven't personally had the time yet. 8 | 9 | #### TODO: 10 | * Allow user to select a serial port. Currently default to first arduino found 11 | * Allow user to calibrate the output level of each channel. The red LEDs in my setup are slightly too bright, so all red values are multiplied by 0.9 at the moment. 12 | * Refactor things out of app delegate where possible 13 | * Retain user settings --------------------------------------------------------------------------------