├── IMLight.xcodeproj
├── xcuserdata
│ └── BlahGeek.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── IMLight.xcscheme
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── BlahGeek.xcuserdatad
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── WorkspaceSettings.xcsettings
└── project.pbxproj
├── IMLight
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ ├── Editing-Generic-Text-icon.png
│ │ ├── Editing-Generic-Text-icon-1.png
│ │ ├── Editing-Generic-Text-icon-2.png
│ │ └── Contents.json
├── IMLight.entitlements
├── main.m
├── Credits.rtf
├── AppDelegate.h
├── LED.h
├── Info.plist
├── LaunchAtLoginController.h
├── AppDelegate.m
├── README.md
├── LaunchAtLoginController.m
├── LED.m
└── Base.lproj
│ └── MainMenu.xib
└── IMLightTests
├── Info.plist
└── IMLightTests.m
/IMLight.xcodeproj/xcuserdata/BlahGeek.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/IMLight/Images.xcassets/AppIcon.appiconset/Editing-Generic-Text-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blahgeek/IMLight/HEAD/IMLight/Images.xcassets/AppIcon.appiconset/Editing-Generic-Text-icon.png
--------------------------------------------------------------------------------
/IMLight/Images.xcassets/AppIcon.appiconset/Editing-Generic-Text-icon-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blahgeek/IMLight/HEAD/IMLight/Images.xcassets/AppIcon.appiconset/Editing-Generic-Text-icon-1.png
--------------------------------------------------------------------------------
/IMLight/Images.xcassets/AppIcon.appiconset/Editing-Generic-Text-icon-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blahgeek/IMLight/HEAD/IMLight/Images.xcassets/AppIcon.appiconset/Editing-Generic-Text-icon-2.png
--------------------------------------------------------------------------------
/IMLight/IMLight.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/IMLight.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/IMLight.xcodeproj/project.xcworkspace/xcuserdata/BlahGeek.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blahgeek/IMLight/HEAD/IMLight.xcodeproj/project.xcworkspace/xcuserdata/BlahGeek.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/IMLight/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // IMLight
4 | //
5 | // Created by BlahGeek on 14/11/6.
6 | // Copyright (c) 2014年 BlahGeek. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/IMLight/Credits.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg936\cocoartf1343\cocoasubrtf140
2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;}
3 | {\colortbl;\red255\green255\blue255;}
4 | \paperw12240\paperh15840\margl1440\margr1440\vieww11040\viewh8400\viewkind0
5 | \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc
6 |
7 | \f0\fs28 \cf0 This is a simple application to turn on Caps Lock light when an input method is selected, which is useful if you use \'93Caps Lock\'94 to switch IM. \
8 | \
9 | See {\field{\*\fldinst{HYPERLINK "http://blog.blahgeek.com/IMLight"}}{\fldrslt this post}} to see HOWTO.}
--------------------------------------------------------------------------------
/IMLight/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // IMLight
4 | //
5 | // Created by BlahGeek on 14/11/6.
6 | // Copyright (c) 2014年 BlahGeek. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LED.h"
11 | #import "LaunchAtLoginController.h"
12 |
13 | @interface AppDelegate : NSObject
14 |
15 | @property (weak) IBOutlet NSMenu *statusMenu;
16 | @property (weak) IBOutlet NSMenuItem *startAtLoginItem;
17 | @property (strong, nonatomic) NSStatusItem *statusBar;
18 |
19 | @property (strong) LED * caps_led;
20 | @property (strong) LaunchAtLoginController * launchController;
21 |
22 | - (void)initLED;
23 | - (IBAction)setStartAtLogin:(id)sender;
24 |
25 | @end
26 |
27 |
--------------------------------------------------------------------------------
/IMLight/LED.h:
--------------------------------------------------------------------------------
1 | //
2 | // LED.h
3 | // IMMonitor
4 | //
5 | // Created by BlahGeek on 14/11/6.
6 | // Copyright (c) 2014年 BlahGeek. All rights reserved.
7 | //
8 |
9 | #ifndef IMMonitor_LED_h
10 | #define IMMonitor_LED_h
11 |
12 | #import
13 | #include
14 | #include
15 |
16 | #define MAX_DEVICE_COUNT 16
17 |
18 | @interface LED : NSObject
19 | {
20 | IOHIDDeviceRef ledDevices[MAX_DEVICE_COUNT];
21 | IOHIDElementRef ledElements[MAX_DEVICE_COUNT];
22 | int device_count;
23 | }
24 | // Pass either kHIDUsage_LED_NumLock or kHIDUsage_LED_CapsLock
25 | -(id)initWithUsage:(uint32_t)usage;
26 | -(void)setValue:(SInt32)value;
27 | @end
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/IMLight.xcodeproj/xcuserdata/BlahGeek.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | IMLight.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | DAA79EA11A0B65810094CD1A
16 |
17 | primary
18 |
19 |
20 | DAA79EB41A0B65810094CD1A
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/IMLight.xcodeproj/project.xcworkspace/xcuserdata/BlahGeek.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildLocationStyle
6 | UseAppPreferences
7 | CustomBuildLocationType
8 | RelativeToDerivedData
9 | DerivedDataLocationStyle
10 | Default
11 | IssueFilterStyle
12 | ShowActiveSchemeOnly
13 | LiveSourceIssuesEnabled
14 |
15 | SnapshotAutomaticallyBeforeSignificantChanges
16 |
17 | SnapshotLocationStyle
18 | Default
19 |
20 |
21 |
--------------------------------------------------------------------------------
/IMLightTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | blahgeek.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/IMLightTests/IMLightTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // IMLightTests.m
3 | // IMLightTests
4 | //
5 | // Created by BlahGeek on 14/11/6.
6 | // Copyright (c) 2014年 BlahGeek. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface IMLightTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation IMLightTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/IMLight/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | blahgeek.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | LSUIElement
26 |
27 | NSHumanReadableCopyright
28 | Copyright © 2014年 BlahGeek. All rights reserved.
29 | NSMainNibFile
30 | MainMenu
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/IMLight/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "size" : "32x32",
15 | "idiom" : "mac",
16 | "filename" : "Editing-Generic-Text-icon-2.png",
17 | "scale" : "1x"
18 | },
19 | {
20 | "idiom" : "mac",
21 | "size" : "32x32",
22 | "scale" : "2x"
23 | },
24 | {
25 | "size" : "128x128",
26 | "idiom" : "mac",
27 | "filename" : "Editing-Generic-Text-icon-1.png",
28 | "scale" : "1x"
29 | },
30 | {
31 | "idiom" : "mac",
32 | "size" : "128x128",
33 | "scale" : "2x"
34 | },
35 | {
36 | "size" : "256x256",
37 | "idiom" : "mac",
38 | "filename" : "Editing-Generic-Text-icon.png",
39 | "scale" : "1x"
40 | },
41 | {
42 | "idiom" : "mac",
43 | "size" : "256x256",
44 | "scale" : "2x"
45 | },
46 | {
47 | "idiom" : "mac",
48 | "size" : "512x512",
49 | "scale" : "1x"
50 | },
51 | {
52 | "idiom" : "mac",
53 | "size" : "512x512",
54 | "scale" : "2x"
55 | }
56 | ],
57 | "info" : {
58 | "version" : 1,
59 | "author" : "xcode"
60 | }
61 | }
--------------------------------------------------------------------------------
/IMLight/LaunchAtLoginController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LaunchAtLoginController.h
3 | //
4 | // Copyright 2011 Tomáš Znamenáček
5 | // Copyright 2010 Ben Clark-Robinson
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining
8 | // a copy of this software and associated documentation files (the ‘Software’),
9 | // to deal in the Software without restriction, including without limitation
10 | // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 | // and/or sell copies of the Software, and to permit persons to whom the
12 | // Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be
15 | // included in all copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND,
18 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | #import
26 |
27 | @interface LaunchAtLoginController : NSObject {}
28 |
29 | @property(assign) BOOL launchAtLogin;
30 |
31 | - (BOOL) willLaunchAtLogin: (NSURL*) itemURL;
32 | - (void) setLaunchAtLogin: (BOOL) enabled forURL: (NSURL*) itemURL;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/IMLight/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // IMLight
4 | //
5 | // Created by BlahGeek on 14/11/6.
6 | // Copyright (c) 2014年 BlahGeek. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import
11 |
12 | @interface AppDelegate ()
13 |
14 | @property (weak) IBOutlet NSWindow *window;
15 | @end
16 |
17 | @implementation AppDelegate
18 |
19 | - (void)initLED {
20 | self.caps_led = [[LED alloc] initWithUsage:kHIDUsage_LED_CapsLock];
21 | NSLog(@"LED inited!");
22 | }
23 |
24 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
25 | self.launchController = [[LaunchAtLoginController alloc] init];
26 | [self.startAtLoginItem setState:([self.launchController launchAtLogin] ? NSOnState : NSOffState)];
27 |
28 | [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
29 | selector:@selector(initLED)
30 | name:NSWorkspaceDidWakeNotification
31 | object:NULL];
32 | [self initLED];
33 |
34 | [[NSDistributedNotificationCenter defaultCenter]
35 | addObserverForName:(__bridge NSString *)kTISNotifySelectedKeyboardInputSourceChanged
36 | object:nil
37 | queue:nil
38 | usingBlock:^(NSNotification * noti) {
39 |
40 | NSLog(@"In callback block of notification.");
41 |
42 | CFArrayRef all_im = TISCreateInputSourceList(NULL, false);
43 | for(int i = 0 ; i < CFArrayGetCount(all_im) ; i += 1) {
44 | TISInputSourceRef im = (TISInputSourceRef)CFArrayGetValueAtIndex(all_im, i);
45 |
46 | CFStringRef im_type = TISGetInputSourceProperty(im, kTISPropertyInputSourceType);
47 | CFBooleanRef im_selected = TISGetInputSourceProperty(im, kTISPropertyInputSourceIsSelected);
48 | if (CFBooleanGetValue(im_selected) == YES) {
49 | [self.caps_led setValue:(im_type != kTISTypeKeyboardLayout)];
50 | break;
51 | }
52 | }
53 | CFRelease(all_im);
54 | }
55 | ];
56 | // Insert code here to initialize your application
57 | }
58 |
59 | - (void)applicationWillTerminate:(NSNotification *)aNotification {
60 | // Insert code here to tear down your application
61 | }
62 |
63 | - (void)awakeFromNib {
64 | self.statusBar = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
65 | [self.statusBar setTitle:@"A"];
66 | self.statusBar.menu = self.statusMenu;
67 | self.statusBar.highlightMode = YES;
68 | }
69 |
70 | - (IBAction)setStartAtLogin:(id)sender {
71 | NSUInteger state = NSOffState;
72 | if(self.startAtLoginItem.state == NSOffState)
73 | state = NSOnState;
74 | [self.startAtLoginItem setState:state];
75 | [self.launchController setLaunchAtLogin: (state == NSOnState)];
76 | }
77 | @end
78 |
--------------------------------------------------------------------------------
/IMLight/README.md:
--------------------------------------------------------------------------------
1 | # LaunchAtLoginController
2 |
3 | A very simple to implement Controller for use in Cocoa Mac Apps to register/deregister itself for Launch at Login using LSSharedFileList.
4 |
5 | It uses LSSharedFileList which means your Users will be able to check System Preferences > Accounts > Login Items.
6 |
7 | I'm currently using it on 10.6 (32/64) successfully. I've not investigated being able to flag the "Hide" flag which is possible from System Preferences.
8 |
9 | ## IMPLEMENTATION (Code):
10 |
11 | ### Will app launch at login?
12 |
13 | LaunchAtLoginController *launchController = [[LaunchAtLoginController alloc] init];
14 | BOOL launch = [launchController launchAtLogin];
15 | [launchController release];
16 |
17 | ### Set launch at login state.
18 |
19 | LaunchAtLoginController *launchController = [[LaunchAtLoginController alloc] init];
20 | [launchController setLaunchAtLogin:YES];
21 | [launchController release];
22 |
23 | ## IMPLEMENTATION (Interface builder):
24 |
25 | * Open Interface Builder
26 | * Place a NSObject (the blue box) into the nib window
27 | * From the Inspector - Identity Tab (Cmd+6) set the Class to LaunchAtLoginController
28 | * Place a Checkbox on your Window/View
29 | * From the Inspector - Bindings Tab (Cmd+4) unroll the > Value item
30 | * Bind to Launch at Login Controller
31 | * Model Key Path: launchAtLogin
32 |
33 | ## IS IT WORKING:
34 |
35 | After implementing either through code or through IB, setLaunchAtLogin:YES and then check System Preferences > Accounts > Login Items. You should see your app in the list of apps that will start when the user logs in.
36 |
37 | ## CAVEATS (HelperApp Bundles):
38 |
39 | If you're trying to set a different bundle (perhaps a HelperApp as a resource to your main bundle) you will simply want to change
40 | - (NSURL *)appURL
41 | to return the path to this other bundle.
42 |
43 | ## REQUIREMENTS:
44 |
45 | Works on 10.6/10.5
46 |
47 | ## ORIGINAL CODE IDEAS:
48 |
49 | * Growl.
50 | * User: invariant Link: (http://stackoverflow.com/questions/815063/how-do-you-make-your-app-open-at-login/2318004#2318004)
51 |
52 |
53 | ## LICENSE:
54 |
55 | (The MIT License)
56 |
57 | Copyright (c) 2010 Ben Clark-Robinson, ben.clarkrobinson@gmail.com
58 |
59 | Permission is hereby granted, free of charge, to any person obtaining
60 | a copy of this software and associated documentation files (the
61 | 'Software'), to deal in the Software without restriction, including
62 | without limitation the rights to use, copy, modify, merge, publish,
63 | distribute, sublicense, and/or sell copies of the Software, and to
64 | permit persons to whom the Software is furnished to do so, subject to
65 | the following conditions:
66 |
67 | The above copyright notice and this permission notice shall be
68 | included in all copies or substantial portions of the Software.
69 |
70 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
71 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
72 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
73 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
74 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
75 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
76 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
77 |
--------------------------------------------------------------------------------
/IMLight/LaunchAtLoginController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LaunchAtLoginController.m
3 | //
4 | // Copyright 2011 Tomáš Znamenáček
5 | // Copyright 2010 Ben Clark-Robinson
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining
8 | // a copy of this software and associated documentation files (the ‘Software’),
9 | // to deal in the Software without restriction, including without limitation
10 | // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 | // and/or sell copies of the Software, and to permit persons to whom the
12 | // Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be
15 | // included in all copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND,
18 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | #import "LaunchAtLoginController.h"
26 |
27 | static NSString *const StartAtLoginKey = @"launchAtLogin";
28 |
29 | @interface LaunchAtLoginController ()
30 | @property(assign) LSSharedFileListRef loginItems;
31 | @end
32 |
33 | @implementation LaunchAtLoginController
34 | @synthesize loginItems;
35 |
36 | #pragma mark Change Observing
37 |
38 | void sharedFileListDidChange(LSSharedFileListRef inList, void *context)
39 | {
40 | LaunchAtLoginController *self = (id) context;
41 | [self willChangeValueForKey:StartAtLoginKey];
42 | [self didChangeValueForKey:StartAtLoginKey];
43 | }
44 |
45 | #pragma mark Initialization
46 |
47 | - (id) init
48 | {
49 | [super init];
50 | loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
51 | LSSharedFileListAddObserver(loginItems, CFRunLoopGetMain(),
52 | (CFStringRef)NSDefaultRunLoopMode, sharedFileListDidChange, self);
53 | return self;
54 | }
55 |
56 | - (void) dealloc
57 | {
58 | LSSharedFileListRemoveObserver(loginItems, CFRunLoopGetMain(),
59 | (CFStringRef)NSDefaultRunLoopMode, sharedFileListDidChange, self);
60 | CFRelease(loginItems);
61 | [super dealloc];
62 | }
63 |
64 | #pragma mark Launch List Control
65 |
66 | - (LSSharedFileListItemRef) findItemWithURL: (NSURL*) wantedURL inFileList: (LSSharedFileListRef) fileList
67 | {
68 | if (wantedURL == NULL || fileList == NULL)
69 | return NULL;
70 |
71 | NSArray *listSnapshot = [NSMakeCollectable(LSSharedFileListCopySnapshot(fileList, NULL)) autorelease];
72 | for (id itemObject in listSnapshot) {
73 | LSSharedFileListItemRef item = (LSSharedFileListItemRef) itemObject;
74 | UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
75 | CFURLRef currentItemURL = NULL;
76 | LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL);
77 | if (currentItemURL && CFEqual(currentItemURL, wantedURL)) {
78 | CFRelease(currentItemURL);
79 | return item;
80 | }
81 | if (currentItemURL)
82 | CFRelease(currentItemURL);
83 | }
84 |
85 | return NULL;
86 | }
87 |
88 | - (BOOL) willLaunchAtLogin: (NSURL*) itemURL
89 | {
90 | return !![self findItemWithURL:itemURL inFileList:loginItems];
91 | }
92 |
93 | - (void) setLaunchAtLogin: (BOOL) enabled forURL: (NSURL*) itemURL
94 | {
95 | LSSharedFileListItemRef appItem = [self findItemWithURL:itemURL inFileList:loginItems];
96 | if (enabled && !appItem) {
97 | LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst,
98 | NULL, NULL, (CFURLRef)itemURL, NULL, NULL);
99 | } else if (!enabled && appItem)
100 | LSSharedFileListItemRemove(loginItems, appItem);
101 | }
102 |
103 | #pragma mark Basic Interface
104 |
105 | - (NSURL*) appURL
106 | {
107 | return [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
108 | }
109 |
110 | - (void) setLaunchAtLogin: (BOOL) enabled
111 | {
112 | [self willChangeValueForKey:StartAtLoginKey];
113 | [self setLaunchAtLogin:enabled forURL:[self appURL]];
114 | [self didChangeValueForKey:StartAtLoginKey];
115 | }
116 |
117 | - (BOOL) launchAtLogin
118 | {
119 | return [self willLaunchAtLogin:[self appURL]];
120 | }
121 |
122 | @end
123 |
--------------------------------------------------------------------------------
/IMLight.xcodeproj/xcuserdata/BlahGeek.xcuserdatad/xcschemes/IMLight.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/IMLight/LED.m:
--------------------------------------------------------------------------------
1 | //
2 | // LED.m
3 | // IMMonitor
4 | //
5 | // Created by BlahGeek on 14/11/6.
6 | // Copyright (c) 2014年 BlahGeek. All rights reserved.
7 | //
8 |
9 | #import
10 | #include
11 | #include
12 | #include "LED.h"
13 |
14 | static NSMutableDictionary* _CreateMatchingDict(Boolean isDeviceNotElement,
15 | uint32_t inUsagePage,
16 | uint32_t inUsage);
17 |
18 | static NSMutableDictionary* _CreateMatchingDict(Boolean isDeviceNotElement,
19 | uint32_t inUsagePage,
20 | uint32_t inUsage)
21 | {
22 | NSMutableDictionary* dic = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
23 | [NSNumber numberWithUnsignedInt:inUsagePage],
24 | (isDeviceNotElement)?
25 | CFSTR(kIOHIDDeviceUsagePageKey):
26 | CFSTR(kIOHIDElementUsagePageKey),
27 | NULL];
28 | if (inUsage) [dic setObject:[NSNumber numberWithUnsignedInt:inUsage]
29 | forKey:(isDeviceNotElement)?
30 | (NSString*)CFSTR(kIOHIDDeviceUsageKey):
31 | (NSString*)CFSTR(kIOHIDElementUsageKey)];
32 | return dic;
33 | }
34 |
35 | @implementation LED
36 | -(id)init
37 | {
38 | return [self initWithUsage:kHIDUsage_LED_CapsLock];
39 | }
40 |
41 | -(id)initWithUsage:(uint32_t)usage
42 | {
43 | self = [super init];
44 | device_count = 0;
45 |
46 | CFSetRef deviceCFSetRef = NULL;
47 | IOHIDDeviceRef* refs = NULL;
48 | // create a IO HID Manager reference
49 | IOHIDManagerRef mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
50 | if(!mgr)
51 | return self;
52 | // Create a device matching dictionary
53 | NSDictionary* dic = _CreateMatchingDict(true, kHIDPage_GenericDesktop,
54 | kHIDUsage_GD_Keyboard);
55 | require(dic, Oops);
56 | // set the HID device matching dictionary
57 | IOHIDManagerSetDeviceMatching(mgr, (__bridge CFDictionaryRef)dic);
58 | // [dic release];
59 | // Now open the IO HID Manager reference
60 | IOReturn err = IOHIDManagerOpen(mgr, kIOHIDOptionsTypeNone);
61 | require_noerr(err, Oops);
62 | // and copy out its devices
63 | deviceCFSetRef = IOHIDManagerCopyDevices(mgr);
64 | require(deviceCFSetRef, Oops);
65 | // how many devices in the set?
66 | CFIndex deviceIndex, deviceCount = CFSetGetCount(deviceCFSetRef);
67 | // allocate a block of memory to extact the device refs from the set into
68 | refs = malloc(sizeof(IOHIDDeviceRef) * deviceCount);
69 | require(refs, Oops);
70 | // now extract the device refs from the set
71 | CFSetGetValues(deviceCFSetRef, (const void**)refs);
72 | // before we get into the device loop set up element matching dictionary
73 | dic = _CreateMatchingDict(false, kHIDPage_LEDs, 0);
74 | require(dic, Oops);
75 | for (deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
76 | {
77 | // if this isn't a keyboard device...
78 | if (!IOHIDDeviceConformsTo(refs[deviceIndex], kHIDPage_GenericDesktop,
79 | kHIDUsage_GD_Keyboard))
80 | {
81 | //printf("skipping nonconforming device at %d\n", deviceIndex);
82 | continue; // ...skip it
83 | }
84 | // copy all the elements
85 | CFArrayRef elements = IOHIDDeviceCopyMatchingElements(refs[deviceIndex],
86 | (__bridge CFDictionaryRef)dic,
87 | kIOHIDOptionsTypeNone);
88 | if(!elements)
89 | continue;
90 | // iterate over all the elements
91 | CFIndex i, n = CFArrayGetCount(elements);
92 | for (i = 0; i < n; i++)
93 | {
94 | IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
95 | if(!element)
96 | continue;
97 | uint32_t usagePage = IOHIDElementGetUsagePage(element);
98 | // if this isn't an LED element, skip it
99 | if (kHIDPage_LEDs != usagePage) continue;
100 | uint32_t elusage = IOHIDElementGetUsage(element);
101 | if (elusage == usage)
102 | {
103 | ledDevices[device_count] = (IOHIDDeviceRef)CFRetain(refs[deviceIndex]);
104 | ledElements[device_count++] = (IOHIDElementRef)CFRetain(element);
105 | break;
106 | }
107 | next_element: ;
108 | continue;
109 | }
110 | next_device: ;
111 | if (elements) CFRelease(elements);
112 | continue;
113 | }
114 | if (mgr) CFRelease(mgr);
115 | // [dic release];
116 | Oops: ;
117 | if (deviceCFSetRef) CFRelease(deviceCFSetRef);
118 | if (refs) free(refs);
119 |
120 | NSLog(@"LED Inited, %d devices found", device_count);
121 | return self;
122 | }
123 |
124 | -(void)dealloc
125 | {
126 | for(int i = 0 ; i < device_count ; i += 1) {
127 |
128 | if (ledDevices[i]) CFRelease(ledDevices[i]);
129 | if (ledElements[i]) CFRelease(ledElements[i]);
130 | }
131 | // [super dealloc];
132 | }
133 |
134 | -(void)setValue:(SInt32)value
135 | {
136 | for(int i = 0 ; i < device_count ; i += 1) {
137 | if (ledDevices[i] && ledElements[i])
138 | {
139 | IOReturn err = IOHIDDeviceOpen(ledDevices[i], 0);
140 | if (!err)
141 | {
142 | // create the IO HID Value to be sent to this LED element
143 | uint64_t timestamp = 0;
144 | IOHIDValueRef val = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault,
145 | ledElements[i], timestamp,
146 | value);
147 | if (val)
148 | {
149 | // now set it on the device
150 | err = IOHIDDeviceSetValue(ledDevices[i], ledElements[i], val);
151 | CFRelease(val);
152 | }
153 | IOHIDDeviceClose(ledDevices[i], 0);
154 | }
155 | if (err) printf("error 0x%X\n", err);
156 | }
157 | }
158 |
159 | }
160 | @end
--------------------------------------------------------------------------------
/IMLight.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | DA6182EB1A0B88D600735728 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = DA6182EA1A0B88D600735728 /* Credits.rtf */; };
11 | DAA79EA91A0B65810094CD1A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA79EA81A0B65810094CD1A /* AppDelegate.m */; };
12 | DAA79EAB1A0B65810094CD1A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA79EAA1A0B65810094CD1A /* main.m */; };
13 | DAA79EAD1A0B65810094CD1A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DAA79EAC1A0B65810094CD1A /* Images.xcassets */; };
14 | DAA79EB01A0B65810094CD1A /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DAA79EAE1A0B65810094CD1A /* MainMenu.xib */; };
15 | DAA79EBC1A0B65810094CD1A /* IMLightTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA79EBB1A0B65810094CD1A /* IMLightTests.m */; };
16 | DAA79EC61A0B68850094CD1A /* LED.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA79EC51A0B68850094CD1A /* LED.m */; };
17 | DAA79ECE1A0B7F6A0094CD1A /* LaunchAtLoginController.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA79ECC1A0B7F6A0094CD1A /* LaunchAtLoginController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
18 | DAA79ECF1A0B7F6A0094CD1A /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = DAA79ECD1A0B7F6A0094CD1A /* README.md */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXContainerItemProxy section */
22 | DAA79EB61A0B65810094CD1A /* PBXContainerItemProxy */ = {
23 | isa = PBXContainerItemProxy;
24 | containerPortal = DAA79E9A1A0B65810094CD1A /* Project object */;
25 | proxyType = 1;
26 | remoteGlobalIDString = DAA79EA11A0B65810094CD1A;
27 | remoteInfo = IMLight;
28 | };
29 | /* End PBXContainerItemProxy section */
30 |
31 | /* Begin PBXFileReference section */
32 | DA6182E91A0B851F00735728 /* IMLight.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = IMLight.entitlements; sourceTree = ""; };
33 | DA6182EA1A0B88D600735728 /* Credits.rtf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = ""; };
34 | DAA79EA21A0B65810094CD1A /* IMLight.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IMLight.app; sourceTree = BUILT_PRODUCTS_DIR; };
35 | DAA79EA61A0B65810094CD1A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
36 | DAA79EA71A0B65810094CD1A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
37 | DAA79EA81A0B65810094CD1A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
38 | DAA79EAA1A0B65810094CD1A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
39 | DAA79EAC1A0B65810094CD1A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
40 | DAA79EAF1A0B65810094CD1A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
41 | DAA79EB51A0B65810094CD1A /* IMLightTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IMLightTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
42 | DAA79EBA1A0B65810094CD1A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
43 | DAA79EBB1A0B65810094CD1A /* IMLightTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IMLightTests.m; sourceTree = ""; };
44 | DAA79EC51A0B68850094CD1A /* LED.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LED.m; sourceTree = ""; };
45 | DAA79EC71A0B688B0094CD1A /* LED.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LED.h; sourceTree = ""; };
46 | DAA79ECB1A0B7F6A0094CD1A /* LaunchAtLoginController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LaunchAtLoginController.h; sourceTree = ""; };
47 | DAA79ECC1A0B7F6A0094CD1A /* LaunchAtLoginController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LaunchAtLoginController.m; sourceTree = ""; };
48 | DAA79ECD1A0B7F6A0094CD1A /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
49 | /* End PBXFileReference section */
50 |
51 | /* Begin PBXFrameworksBuildPhase section */
52 | DAA79E9F1A0B65810094CD1A /* Frameworks */ = {
53 | isa = PBXFrameworksBuildPhase;
54 | buildActionMask = 2147483647;
55 | files = (
56 | );
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | DAA79EB21A0B65810094CD1A /* Frameworks */ = {
60 | isa = PBXFrameworksBuildPhase;
61 | buildActionMask = 2147483647;
62 | files = (
63 | );
64 | runOnlyForDeploymentPostprocessing = 0;
65 | };
66 | /* End PBXFrameworksBuildPhase section */
67 |
68 | /* Begin PBXGroup section */
69 | DAA79E991A0B65810094CD1A = {
70 | isa = PBXGroup;
71 | children = (
72 | DAA79EA41A0B65810094CD1A /* IMLight */,
73 | DAA79EB81A0B65810094CD1A /* IMLightTests */,
74 | DAA79EA31A0B65810094CD1A /* Products */,
75 | );
76 | sourceTree = "";
77 | };
78 | DAA79EA31A0B65810094CD1A /* Products */ = {
79 | isa = PBXGroup;
80 | children = (
81 | DAA79EA21A0B65810094CD1A /* IMLight.app */,
82 | DAA79EB51A0B65810094CD1A /* IMLightTests.xctest */,
83 | );
84 | name = Products;
85 | sourceTree = "";
86 | };
87 | DAA79EA41A0B65810094CD1A /* IMLight */ = {
88 | isa = PBXGroup;
89 | children = (
90 | DA6182E91A0B851F00735728 /* IMLight.entitlements */,
91 | DAA79ED01A0B7F740094CD1A /* LaunchAtLoginController */,
92 | DAA79EC71A0B688B0094CD1A /* LED.h */,
93 | DAA79EC51A0B68850094CD1A /* LED.m */,
94 | DAA79EA71A0B65810094CD1A /* AppDelegate.h */,
95 | DAA79EA81A0B65810094CD1A /* AppDelegate.m */,
96 | DAA79EAC1A0B65810094CD1A /* Images.xcassets */,
97 | DAA79EAE1A0B65810094CD1A /* MainMenu.xib */,
98 | DAA79EA51A0B65810094CD1A /* Supporting Files */,
99 | );
100 | path = IMLight;
101 | sourceTree = "";
102 | };
103 | DAA79EA51A0B65810094CD1A /* Supporting Files */ = {
104 | isa = PBXGroup;
105 | children = (
106 | DAA79EA61A0B65810094CD1A /* Info.plist */,
107 | DAA79EAA1A0B65810094CD1A /* main.m */,
108 | DA6182EA1A0B88D600735728 /* Credits.rtf */,
109 | );
110 | name = "Supporting Files";
111 | sourceTree = "";
112 | };
113 | DAA79EB81A0B65810094CD1A /* IMLightTests */ = {
114 | isa = PBXGroup;
115 | children = (
116 | DAA79EBB1A0B65810094CD1A /* IMLightTests.m */,
117 | DAA79EB91A0B65810094CD1A /* Supporting Files */,
118 | );
119 | path = IMLightTests;
120 | sourceTree = "";
121 | };
122 | DAA79EB91A0B65810094CD1A /* Supporting Files */ = {
123 | isa = PBXGroup;
124 | children = (
125 | DAA79EBA1A0B65810094CD1A /* Info.plist */,
126 | );
127 | name = "Supporting Files";
128 | sourceTree = "";
129 | };
130 | DAA79ED01A0B7F740094CD1A /* LaunchAtLoginController */ = {
131 | isa = PBXGroup;
132 | children = (
133 | DAA79ECB1A0B7F6A0094CD1A /* LaunchAtLoginController.h */,
134 | DAA79ECC1A0B7F6A0094CD1A /* LaunchAtLoginController.m */,
135 | DAA79ECD1A0B7F6A0094CD1A /* README.md */,
136 | );
137 | name = LaunchAtLoginController;
138 | sourceTree = "";
139 | };
140 | /* End PBXGroup section */
141 |
142 | /* Begin PBXNativeTarget section */
143 | DAA79EA11A0B65810094CD1A /* IMLight */ = {
144 | isa = PBXNativeTarget;
145 | buildConfigurationList = DAA79EBF1A0B65810094CD1A /* Build configuration list for PBXNativeTarget "IMLight" */;
146 | buildPhases = (
147 | DAA79E9E1A0B65810094CD1A /* Sources */,
148 | DAA79E9F1A0B65810094CD1A /* Frameworks */,
149 | DAA79EA01A0B65810094CD1A /* Resources */,
150 | );
151 | buildRules = (
152 | );
153 | dependencies = (
154 | );
155 | name = IMLight;
156 | productName = IMLight;
157 | productReference = DAA79EA21A0B65810094CD1A /* IMLight.app */;
158 | productType = "com.apple.product-type.application";
159 | };
160 | DAA79EB41A0B65810094CD1A /* IMLightTests */ = {
161 | isa = PBXNativeTarget;
162 | buildConfigurationList = DAA79EC21A0B65810094CD1A /* Build configuration list for PBXNativeTarget "IMLightTests" */;
163 | buildPhases = (
164 | DAA79EB11A0B65810094CD1A /* Sources */,
165 | DAA79EB21A0B65810094CD1A /* Frameworks */,
166 | DAA79EB31A0B65810094CD1A /* Resources */,
167 | );
168 | buildRules = (
169 | );
170 | dependencies = (
171 | DAA79EB71A0B65810094CD1A /* PBXTargetDependency */,
172 | );
173 | name = IMLightTests;
174 | productName = IMLightTests;
175 | productReference = DAA79EB51A0B65810094CD1A /* IMLightTests.xctest */;
176 | productType = "com.apple.product-type.bundle.unit-test";
177 | };
178 | /* End PBXNativeTarget section */
179 |
180 | /* Begin PBXProject section */
181 | DAA79E9A1A0B65810094CD1A /* Project object */ = {
182 | isa = PBXProject;
183 | attributes = {
184 | LastUpgradeCheck = 0610;
185 | ORGANIZATIONNAME = BlahGeek;
186 | TargetAttributes = {
187 | DAA79EA11A0B65810094CD1A = {
188 | CreatedOnToolsVersion = 6.1;
189 | SystemCapabilities = {
190 | com.apple.Sandbox = {
191 | enabled = 0;
192 | };
193 | };
194 | };
195 | DAA79EB41A0B65810094CD1A = {
196 | CreatedOnToolsVersion = 6.1;
197 | TestTargetID = DAA79EA11A0B65810094CD1A;
198 | };
199 | };
200 | };
201 | buildConfigurationList = DAA79E9D1A0B65810094CD1A /* Build configuration list for PBXProject "IMLight" */;
202 | compatibilityVersion = "Xcode 3.2";
203 | developmentRegion = English;
204 | hasScannedForEncodings = 0;
205 | knownRegions = (
206 | en,
207 | Base,
208 | );
209 | mainGroup = DAA79E991A0B65810094CD1A;
210 | productRefGroup = DAA79EA31A0B65810094CD1A /* Products */;
211 | projectDirPath = "";
212 | projectRoot = "";
213 | targets = (
214 | DAA79EA11A0B65810094CD1A /* IMLight */,
215 | DAA79EB41A0B65810094CD1A /* IMLightTests */,
216 | );
217 | };
218 | /* End PBXProject section */
219 |
220 | /* Begin PBXResourcesBuildPhase section */
221 | DAA79EA01A0B65810094CD1A /* Resources */ = {
222 | isa = PBXResourcesBuildPhase;
223 | buildActionMask = 2147483647;
224 | files = (
225 | DAA79EAD1A0B65810094CD1A /* Images.xcassets in Resources */,
226 | DA6182EB1A0B88D600735728 /* Credits.rtf in Resources */,
227 | DAA79EB01A0B65810094CD1A /* MainMenu.xib in Resources */,
228 | );
229 | runOnlyForDeploymentPostprocessing = 0;
230 | };
231 | DAA79EB31A0B65810094CD1A /* Resources */ = {
232 | isa = PBXResourcesBuildPhase;
233 | buildActionMask = 2147483647;
234 | files = (
235 | );
236 | runOnlyForDeploymentPostprocessing = 0;
237 | };
238 | /* End PBXResourcesBuildPhase section */
239 |
240 | /* Begin PBXSourcesBuildPhase section */
241 | DAA79E9E1A0B65810094CD1A /* Sources */ = {
242 | isa = PBXSourcesBuildPhase;
243 | buildActionMask = 2147483647;
244 | files = (
245 | DAA79EC61A0B68850094CD1A /* LED.m in Sources */,
246 | DAA79ECE1A0B7F6A0094CD1A /* LaunchAtLoginController.m in Sources */,
247 | DAA79ECF1A0B7F6A0094CD1A /* README.md in Sources */,
248 | DAA79EAB1A0B65810094CD1A /* main.m in Sources */,
249 | DAA79EA91A0B65810094CD1A /* AppDelegate.m in Sources */,
250 | );
251 | runOnlyForDeploymentPostprocessing = 0;
252 | };
253 | DAA79EB11A0B65810094CD1A /* Sources */ = {
254 | isa = PBXSourcesBuildPhase;
255 | buildActionMask = 2147483647;
256 | files = (
257 | DAA79EBC1A0B65810094CD1A /* IMLightTests.m in Sources */,
258 | );
259 | runOnlyForDeploymentPostprocessing = 0;
260 | };
261 | /* End PBXSourcesBuildPhase section */
262 |
263 | /* Begin PBXTargetDependency section */
264 | DAA79EB71A0B65810094CD1A /* PBXTargetDependency */ = {
265 | isa = PBXTargetDependency;
266 | target = DAA79EA11A0B65810094CD1A /* IMLight */;
267 | targetProxy = DAA79EB61A0B65810094CD1A /* PBXContainerItemProxy */;
268 | };
269 | /* End PBXTargetDependency section */
270 |
271 | /* Begin PBXVariantGroup section */
272 | DAA79EAE1A0B65810094CD1A /* MainMenu.xib */ = {
273 | isa = PBXVariantGroup;
274 | children = (
275 | DAA79EAF1A0B65810094CD1A /* Base */,
276 | );
277 | name = MainMenu.xib;
278 | sourceTree = "";
279 | };
280 | /* End PBXVariantGroup section */
281 |
282 | /* Begin XCBuildConfiguration section */
283 | DAA79EBD1A0B65810094CD1A /* Debug */ = {
284 | isa = XCBuildConfiguration;
285 | buildSettings = {
286 | ALWAYS_SEARCH_USER_PATHS = NO;
287 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
288 | CLANG_CXX_LIBRARY = "libc++";
289 | CLANG_ENABLE_MODULES = YES;
290 | CLANG_ENABLE_OBJC_ARC = YES;
291 | CLANG_WARN_BOOL_CONVERSION = YES;
292 | CLANG_WARN_CONSTANT_CONVERSION = YES;
293 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
294 | CLANG_WARN_EMPTY_BODY = YES;
295 | CLANG_WARN_ENUM_CONVERSION = YES;
296 | CLANG_WARN_INT_CONVERSION = YES;
297 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
298 | CLANG_WARN_UNREACHABLE_CODE = YES;
299 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
300 | CODE_SIGN_IDENTITY = "-";
301 | COPY_PHASE_STRIP = NO;
302 | ENABLE_STRICT_OBJC_MSGSEND = YES;
303 | GCC_C_LANGUAGE_STANDARD = gnu99;
304 | GCC_DYNAMIC_NO_PIC = NO;
305 | GCC_OPTIMIZATION_LEVEL = 0;
306 | GCC_PREPROCESSOR_DEFINITIONS = (
307 | "DEBUG=1",
308 | "$(inherited)",
309 | );
310 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
311 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
312 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
313 | GCC_WARN_UNDECLARED_SELECTOR = YES;
314 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
315 | GCC_WARN_UNUSED_FUNCTION = YES;
316 | GCC_WARN_UNUSED_VARIABLE = YES;
317 | MACOSX_DEPLOYMENT_TARGET = 10.10;
318 | MTL_ENABLE_DEBUG_INFO = YES;
319 | ONLY_ACTIVE_ARCH = YES;
320 | SDKROOT = macosx;
321 | };
322 | name = Debug;
323 | };
324 | DAA79EBE1A0B65810094CD1A /* Release */ = {
325 | isa = XCBuildConfiguration;
326 | buildSettings = {
327 | ALWAYS_SEARCH_USER_PATHS = NO;
328 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
329 | CLANG_CXX_LIBRARY = "libc++";
330 | CLANG_ENABLE_MODULES = YES;
331 | CLANG_ENABLE_OBJC_ARC = YES;
332 | CLANG_WARN_BOOL_CONVERSION = YES;
333 | CLANG_WARN_CONSTANT_CONVERSION = YES;
334 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
335 | CLANG_WARN_EMPTY_BODY = YES;
336 | CLANG_WARN_ENUM_CONVERSION = YES;
337 | CLANG_WARN_INT_CONVERSION = YES;
338 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
339 | CLANG_WARN_UNREACHABLE_CODE = YES;
340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
341 | CODE_SIGN_IDENTITY = "-";
342 | COPY_PHASE_STRIP = YES;
343 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
344 | ENABLE_NS_ASSERTIONS = NO;
345 | ENABLE_STRICT_OBJC_MSGSEND = YES;
346 | GCC_C_LANGUAGE_STANDARD = gnu99;
347 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
348 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
349 | GCC_WARN_UNDECLARED_SELECTOR = YES;
350 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
351 | GCC_WARN_UNUSED_FUNCTION = YES;
352 | GCC_WARN_UNUSED_VARIABLE = YES;
353 | MACOSX_DEPLOYMENT_TARGET = 10.10;
354 | MTL_ENABLE_DEBUG_INFO = NO;
355 | SDKROOT = macosx;
356 | };
357 | name = Release;
358 | };
359 | DAA79EC01A0B65810094CD1A /* Debug */ = {
360 | isa = XCBuildConfiguration;
361 | buildSettings = {
362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
363 | COMBINE_HIDPI_IMAGES = YES;
364 | INFOPLIST_FILE = IMLight/Info.plist;
365 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
366 | PRODUCT_NAME = "$(TARGET_NAME)";
367 | };
368 | name = Debug;
369 | };
370 | DAA79EC11A0B65810094CD1A /* Release */ = {
371 | isa = XCBuildConfiguration;
372 | buildSettings = {
373 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
374 | COMBINE_HIDPI_IMAGES = YES;
375 | INFOPLIST_FILE = IMLight/Info.plist;
376 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
377 | PRODUCT_NAME = "$(TARGET_NAME)";
378 | };
379 | name = Release;
380 | };
381 | DAA79EC31A0B65810094CD1A /* Debug */ = {
382 | isa = XCBuildConfiguration;
383 | buildSettings = {
384 | BUNDLE_LOADER = "$(TEST_HOST)";
385 | COMBINE_HIDPI_IMAGES = YES;
386 | FRAMEWORK_SEARCH_PATHS = (
387 | "$(DEVELOPER_FRAMEWORKS_DIR)",
388 | "$(inherited)",
389 | );
390 | GCC_PREPROCESSOR_DEFINITIONS = (
391 | "DEBUG=1",
392 | "$(inherited)",
393 | );
394 | INFOPLIST_FILE = IMLightTests/Info.plist;
395 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
396 | PRODUCT_NAME = "$(TARGET_NAME)";
397 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/IMLight.app/Contents/MacOS/IMLight";
398 | };
399 | name = Debug;
400 | };
401 | DAA79EC41A0B65810094CD1A /* Release */ = {
402 | isa = XCBuildConfiguration;
403 | buildSettings = {
404 | BUNDLE_LOADER = "$(TEST_HOST)";
405 | COMBINE_HIDPI_IMAGES = YES;
406 | FRAMEWORK_SEARCH_PATHS = (
407 | "$(DEVELOPER_FRAMEWORKS_DIR)",
408 | "$(inherited)",
409 | );
410 | INFOPLIST_FILE = IMLightTests/Info.plist;
411 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
412 | PRODUCT_NAME = "$(TARGET_NAME)";
413 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/IMLight.app/Contents/MacOS/IMLight";
414 | };
415 | name = Release;
416 | };
417 | /* End XCBuildConfiguration section */
418 |
419 | /* Begin XCConfigurationList section */
420 | DAA79E9D1A0B65810094CD1A /* Build configuration list for PBXProject "IMLight" */ = {
421 | isa = XCConfigurationList;
422 | buildConfigurations = (
423 | DAA79EBD1A0B65810094CD1A /* Debug */,
424 | DAA79EBE1A0B65810094CD1A /* Release */,
425 | );
426 | defaultConfigurationIsVisible = 0;
427 | defaultConfigurationName = Release;
428 | };
429 | DAA79EBF1A0B65810094CD1A /* Build configuration list for PBXNativeTarget "IMLight" */ = {
430 | isa = XCConfigurationList;
431 | buildConfigurations = (
432 | DAA79EC01A0B65810094CD1A /* Debug */,
433 | DAA79EC11A0B65810094CD1A /* Release */,
434 | );
435 | defaultConfigurationIsVisible = 0;
436 | defaultConfigurationName = Release;
437 | };
438 | DAA79EC21A0B65810094CD1A /* Build configuration list for PBXNativeTarget "IMLightTests" */ = {
439 | isa = XCConfigurationList;
440 | buildConfigurations = (
441 | DAA79EC31A0B65810094CD1A /* Debug */,
442 | DAA79EC41A0B65810094CD1A /* Release */,
443 | );
444 | defaultConfigurationIsVisible = 0;
445 | defaultConfigurationName = Release;
446 | };
447 | /* End XCConfigurationList section */
448 | };
449 | rootObject = DAA79E9A1A0B65810094CD1A /* Project object */;
450 | }
451 |
--------------------------------------------------------------------------------
/IMLight/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
670 |
671 |
672 |
678 |
679 |
685 |
691 |
692 |
693 |
694 |
695 |
696 |
--------------------------------------------------------------------------------