forked from mirror/smcFanControl
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 063d53b06c | |||
| d52a71e091 | |||
| 8b1127b5b6 | |||
| 1b51b7d952 | |||
| 595fcd5957 | |||
| 7383e0819e | |||
| f233b0846a | |||
| 0be72efddf | |||
| 3328c0018f | |||
| c537db9fdd | |||
| 32ced3b969 | |||
| 73c981e31a | |||
| afebcc65f1 | |||
| 77280ab43c | |||
| 7ea2001e49 | |||
| de8d762534 | |||
| 44c4e1d15a | |||
| dd63c65655 | |||
| 3b87cc972d | |||
| b125097a07 | |||
| afb554fc66 | |||
| 95dfefbe13 | |||
| 3212d78eac | |||
| 514a4e1757 | |||
| b64ed93aec |
9
Classes/FanControl.h
Normal file → Executable file
9
Classes/FanControl.h
Normal file → Executable file
@ -2,7 +2,8 @@
|
|||||||
* FanControl
|
* FanControl
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006-2012 Hendrik Holtmann
|
* Copyright (c) 2006-2012 Hendrik Holtmann
|
||||||
*
|
* Portions Copyright (c) 2013 Michael Wilber
|
||||||
|
*
|
||||||
* FanControl.h - MacBook(Pro) FanControl application
|
* FanControl.h - MacBook(Pro) FanControl application
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -38,7 +39,7 @@
|
|||||||
#define kMenuBarHeight 22
|
#define kMenuBarHeight 22
|
||||||
|
|
||||||
|
|
||||||
@interface FanControl : NSObject
|
@interface FanControl : NSObject <NSMenuDelegate>
|
||||||
|
|
||||||
{
|
{
|
||||||
IBOutlet id currentSpeed;
|
IBOutlet id currentSpeed;
|
||||||
@ -104,9 +105,6 @@
|
|||||||
|
|
||||||
NSImage *menu_image;
|
NSImage *menu_image;
|
||||||
NSImage *menu_image_alt;
|
NSImage *menu_image_alt;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)terminate:(id)sender;
|
-(void)terminate:(id)sender;
|
||||||
@ -133,6 +131,7 @@
|
|||||||
- (void) syncBinder:(Boolean)bind;
|
- (void) syncBinder:(Boolean)bind;
|
||||||
- (IBAction) changeMenu:(id)sender;
|
- (IBAction) changeMenu:(id)sender;
|
||||||
- (IBAction)menuSelect:(id)sender;
|
- (IBAction)menuSelect:(id)sender;
|
||||||
|
- (void)menuNeedsUpdate:(NSMenu*)menu;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
305
Classes/FanControl.m
Normal file → Executable file
305
Classes/FanControl.m
Normal file → Executable file
@ -2,7 +2,8 @@
|
|||||||
* FanControl
|
* FanControl
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006-2012 Hendrik Holtmann
|
* Copyright (c) 2006-2012 Hendrik Holtmann
|
||||||
*
|
* Portions Copyright (c) 2013 Michael Wilber
|
||||||
|
*
|
||||||
* FanControl.m - MacBook(Pro) FanControl application
|
* FanControl.m - MacBook(Pro) FanControl application
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -37,18 +38,10 @@
|
|||||||
|
|
||||||
@implementation FanControl
|
@implementation FanControl
|
||||||
|
|
||||||
io_connect_t conn;
|
// Number of fans reported by the hardware.
|
||||||
kern_return_t result;
|
int g_numFans = 0;
|
||||||
SMCVal_t val;
|
|
||||||
NSUserDefaults *defaults;
|
NSUserDefaults *defaults;
|
||||||
Boolean supported=false;
|
|
||||||
extern char *optarg;
|
|
||||||
SMCVal_t val;
|
|
||||||
OSStatus status;
|
|
||||||
NSDictionary* machine_defaults;
|
|
||||||
NSString *authpw;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark **Init-Methods**
|
#pragma mark **Init-Methods**
|
||||||
|
|
||||||
@ -100,7 +93,7 @@ NSString *authpw;
|
|||||||
}
|
}
|
||||||
|
|
||||||
-(void) awakeFromNib {
|
-(void) awakeFromNib {
|
||||||
|
|
||||||
s_sed = nil;
|
s_sed = nil;
|
||||||
pw=[[Power alloc] init];
|
pw=[[Power alloc] init];
|
||||||
[pw setDelegate:self];
|
[pw setDelegate:self];
|
||||||
@ -162,6 +155,7 @@ NSString *authpw;
|
|||||||
[NSNumber numberWithInt:0],@"selac",
|
[NSNumber numberWithInt:0],@"selac",
|
||||||
[NSNumber numberWithInt:0],@"selload",
|
[NSNumber numberWithInt:0],@"selload",
|
||||||
[NSNumber numberWithInt:0],@"MenuBar",
|
[NSNumber numberWithInt:0],@"MenuBar",
|
||||||
|
@"TC0D",@"TSensor",
|
||||||
feedURL,@"SUFeedURL",
|
feedURL,@"SUFeedURL",
|
||||||
[NSArchiver archivedDataWithRootObject:[NSColor blackColor]],@"MenuColor",
|
[NSArchiver archivedDataWithRootObject:[NSColor blackColor]],@"MenuColor",
|
||||||
favorites,@"Favorites",
|
favorites,@"Favorites",
|
||||||
@ -169,11 +163,11 @@ NSString *authpw;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
g_numFans = [smcWrapper get_fan_num];
|
||||||
s_menus=[[NSMutableArray alloc] init];
|
s_menus=[[NSMutableArray alloc] init];
|
||||||
[s_menus autorelease];
|
[s_menus autorelease];
|
||||||
int i;
|
int i;
|
||||||
for(i=0;i<[smcWrapper get_fan_num];i++){
|
for(i=0;i<g_numFans;i++){
|
||||||
NSMenuItem *mitem=[[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:@"Fan: %d",i] action:NULL keyEquivalent:@""];
|
NSMenuItem *mitem=[[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:@"Fan: %d",i] action:NULL keyEquivalent:@""];
|
||||||
[mitem setTag:(i+1)*10];
|
[mitem setTag:(i+1)*10];
|
||||||
[s_menus insertObject:mitem atIndex:i];
|
[s_menus insertObject:mitem atIndex:i];
|
||||||
@ -222,7 +216,10 @@ NSString *authpw;
|
|||||||
|
|
||||||
//release MachineDefaults class first call
|
//release MachineDefaults class first call
|
||||||
//add timer for reading to RunLoop
|
//add timer for reading to RunLoop
|
||||||
_readTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(readFanData:) userInfo:nil repeats:YES];
|
_readTimer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(readFanData:) userInfo:nil repeats:YES];
|
||||||
|
if ([_readTimer respondsToSelector:@selector(setTolerance:)]) {
|
||||||
|
[_readTimer setTolerance:2.0];
|
||||||
|
}
|
||||||
[_readTimer fire];
|
[_readTimer fire];
|
||||||
//autoapply settings if valid
|
//autoapply settings if valid
|
||||||
[self upgradeFavorites];
|
[self upgradeFavorites];
|
||||||
@ -243,6 +240,11 @@ NSString *authpw;
|
|||||||
for(i=0;i<[s_menus count];i++) {
|
for(i=0;i<[s_menus count];i++) {
|
||||||
[theMenu insertItem:[s_menus objectAtIndex:i] atIndex:i];
|
[theMenu insertItem:[s_menus objectAtIndex:i] atIndex:i];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Sign up for menuNeedsUpdate call
|
||||||
|
// so that the fan speeds in the menu can be updated
|
||||||
|
// only when needed.
|
||||||
|
[theMenu setDelegate:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -289,123 +291,166 @@ NSString *authpw;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)delete_favorite:(id)sender{
|
|
||||||
int pressesButton=NSRunCriticalAlertPanelRelativeToWindow(
|
|
||||||
NSLocalizedString(@"Delete favorite",nil),
|
- (void) deleteAlertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
|
||||||
[NSString stringWithFormat:NSLocalizedString(@"Do you really want to delete the favorite %@?",nil), [ [ [FavoritesController arrangedObjects] objectAtIndex:[FavoritesController selectionIndex]] objectForKey:@"Title"] ],
|
{
|
||||||
NSLocalizedString(@"No",nil),
|
if (returnCode==0) {
|
||||||
NSLocalizedString(@"Yes",nil),nil,mainwindow);
|
|
||||||
if (pressesButton==0) {
|
|
||||||
//delete favorite, but resets presets before
|
//delete favorite, but resets presets before
|
||||||
[self check_deletion:@"selbatt"];
|
[self check_deletion:@"selbatt"];
|
||||||
[self check_deletion:@"selac"];
|
[self check_deletion:@"selac"];
|
||||||
[self check_deletion:@"selload"];
|
[self check_deletion:@"selload"];
|
||||||
[FavoritesController removeObjects:[FavoritesController selectedObjects]];
|
[FavoritesController removeObjects:[FavoritesController selectedObjects]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)delete_favorite:(id)sender{
|
||||||
|
|
||||||
|
NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Delete favorite",nil) defaultButton:NSLocalizedString(@"No",nil) alternateButton:NSLocalizedString(@"Yes",nil) otherButton:nil informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"Do you really want to delete the favorite %@?",nil), [ [ [FavoritesController arrangedObjects] objectAtIndex:[FavoritesController selectionIndex]] objectForKey:@"Title"] ]];
|
||||||
|
|
||||||
|
[alert beginSheetModalForWindow:mainwindow modalDelegate:self didEndSelector:@selector(deleteAlertDidEnd:returnCode:contextInfo:) contextInfo:NULL];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Called via a timer mechanism. This is where all the temp / RPM reading is done.
|
||||||
//reads fan data and updates the gui
|
//reads fan data and updates the gui
|
||||||
-(void) readFanData:(NSTimer*)timer{
|
-(void) readFanData:(NSTimer*)timer{
|
||||||
|
|
||||||
NSString *temp;
|
int i = 0;
|
||||||
NSString *fan;
|
|
||||||
|
|
||||||
|
|
||||||
//on init handling
|
//on init handling
|
||||||
if (s_sed==nil) {
|
if (s_sed==nil) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//populate Menu Items with recent Data
|
// Determine what data is actually needed to keep the energy impact
|
||||||
int i;
|
// as low as possible.
|
||||||
for(i=0;i<[smcWrapper get_fan_num];i++){
|
bool bNeedTemp = false;
|
||||||
NSString *fandesc=[[[s_sed objectForKey:@"Fans"] objectAtIndex:i] objectForKey:@"Description"];
|
bool bNeedRpm = false;
|
||||||
[[theMenu itemWithTag:(i+1)*10] setTitle:[NSString stringWithFormat:@"%@: %@ rpm",fandesc,[[NSNumber numberWithInt:[smcWrapper get_fan_rpm:i]] stringValue]]];
|
const int menuBarSetting = [[defaults objectForKey:@"MenuBar"] intValue];
|
||||||
}
|
switch (menuBarSetting) {
|
||||||
|
default:
|
||||||
|
case 1:
|
||||||
float c_temp=[smcWrapper get_maintemp];
|
bNeedTemp = true;
|
||||||
if ([[defaults objectForKey:@"Unit"] intValue]==0) {
|
bNeedRpm = true;
|
||||||
temp=[NSString stringWithFormat:@"%@%CC",[NSNumber numberWithFloat:c_temp],(unsigned short)0xb0];
|
break;
|
||||||
} else {
|
|
||||||
NSNumberFormatter *ncf=[[[NSNumberFormatter alloc] init] autorelease];
|
case 2:
|
||||||
[ncf setFormat:@"00;00;-00"];
|
bNeedTemp = true;
|
||||||
temp=[NSString stringWithFormat:@"%@%CF",[ncf stringForObjectValue:[[NSNumber numberWithFloat:c_temp] celsius_fahrenheit]],(unsigned short)0xb0];
|
bNeedRpm = true;
|
||||||
}
|
break;
|
||||||
NSNumberFormatter *nc=[[[NSNumberFormatter alloc] init] autorelease];
|
|
||||||
//avoid jumping in menu bar
|
case 3:
|
||||||
[nc setFormat:@"000;000;-000"];
|
bNeedTemp = true;
|
||||||
|
bNeedRpm = false;
|
||||||
int selected = 0;
|
break;
|
||||||
NSArray *fans = [[[FavoritesController arrangedObjects] objectAtIndex:[FavoritesController selectionIndex]] objectForKey:@"FanData"];
|
|
||||||
for (i=0;i<[fans count];i++)
|
case 4:
|
||||||
{
|
bNeedTemp = false;
|
||||||
if ([[[fans objectAtIndex:i] objectForKey:@"menu"] boolValue]==YES) {
|
bNeedRpm = true;
|
||||||
selected = i;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fan=[NSString stringWithFormat:@"%@rpm",[nc stringForObjectValue:[NSNumber numberWithFloat:[smcWrapper get_fan_rpm:selected]]]];
|
|
||||||
|
|
||||||
if ([[defaults objectForKey:@"MenuBar"] intValue]<=1) {
|
NSString *temp = nil;
|
||||||
NSString *add;
|
NSString *fan = nil;
|
||||||
int fsize;
|
float c_temp = 0.0f;
|
||||||
if ([[defaults objectForKey:@"MenuBar"] intValue]==0) {
|
int selectedRpm = 0;
|
||||||
add=@"\n";
|
|
||||||
fsize=9;
|
if (bNeedRpm == true) {
|
||||||
[statusItem setLength:53];
|
// Read the current fan speed for the desired fan and format text for display in the menubar.
|
||||||
} else {
|
NSArray *fans = [[[FavoritesController arrangedObjects] objectAtIndex:[FavoritesController selectionIndex]] objectForKey:@"FanData"];
|
||||||
add=@" ";
|
for (i=0; i<g_numFans && i<[fans count]; i++)
|
||||||
fsize=11;
|
{
|
||||||
[statusItem setLength:96];
|
if ([[[fans objectAtIndex:i] objectForKey:@"menu"] boolValue]==YES) {
|
||||||
}
|
selectedRpm = [smcWrapper get_fan_rpm:i];
|
||||||
NSMutableAttributedString *s_status=[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@%@%@",temp,add,fan]];
|
break;
|
||||||
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
|
}
|
||||||
[paragraphStyle setAlignment:NSLeftTextAlignment];
|
}
|
||||||
[s_status addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Lucida Grande" size:fsize] range:NSMakeRange(0,[s_status length])];
|
|
||||||
[s_status addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0,[s_status length])];
|
NSNumberFormatter *nc=[[[NSNumberFormatter alloc] init] autorelease];
|
||||||
[s_status addAttribute:NSForegroundColorAttributeName value:(NSColor*)[NSUnarchiver unarchiveObjectWithData:[defaults objectForKey:@"MenuColor"]] range:NSMakeRange(0,[s_status length])];
|
//avoid jumping in menu bar
|
||||||
[statusItem setAttributedTitle:s_status];
|
[nc setFormat:@"000;000;-000"];
|
||||||
[statusItem setImage:nil];
|
|
||||||
[statusItem setAlternateImage:nil];
|
fan = [NSString stringWithFormat:@"%@rpm",[nc stringForObjectValue:[NSNumber numberWithFloat:selectedRpm]]];
|
||||||
[paragraphStyle release];
|
}
|
||||||
[s_status release];
|
|
||||||
}
|
if (bNeedTemp == true) {
|
||||||
|
// Read current temperature and format text for the menubar.
|
||||||
|
c_temp = [smcWrapper get_maintemp];
|
||||||
if ([[defaults objectForKey:@"MenuBar"] intValue]==2) {
|
|
||||||
[statusItem setLength:26];
|
if ([[defaults objectForKey:@"Unit"] intValue]==0) {
|
||||||
[statusItem setTitle:nil];
|
temp = [NSString stringWithFormat:@"%@%CC",[NSNumber numberWithFloat:c_temp],(unsigned short)0xb0];
|
||||||
[statusItem setToolTip:[NSString stringWithFormat:@"%@\n%@",temp,fan]];
|
} else {
|
||||||
[statusItem setImage:menu_image];
|
NSNumberFormatter *ncf=[[[NSNumberFormatter alloc] init] autorelease];
|
||||||
[statusItem setAlternateImage:menu_image_alt];
|
[ncf setFormat:@"00;00;-00"];
|
||||||
|
temp = [NSString stringWithFormat:@"%@%CF",[ncf stringForObjectValue:[[NSNumber numberWithFloat:c_temp] celsius_fahrenheit]],(unsigned short)0xb0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ([[defaults objectForKey:@"MenuBar"] intValue]==3) {
|
|
||||||
[statusItem setLength:46];
|
// Update the temp and/or fan speed text in the menubar.
|
||||||
NSMutableAttributedString *s_status=[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@",temp]];
|
NSMutableAttributedString *s_status = nil;
|
||||||
[s_status addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Lucida Grande" size:12] range:NSMakeRange(0,[s_status length])];
|
NSMutableParagraphStyle *paragraphStyle = nil;
|
||||||
[s_status addAttribute:NSForegroundColorAttributeName value:(NSColor*)[NSUnarchiver unarchiveObjectWithData:[defaults objectForKey:@"MenuColor"]] range:NSMakeRange(0,[s_status length])];
|
|
||||||
[statusItem setAttributedTitle:s_status];
|
switch (menuBarSetting) {
|
||||||
[statusItem setImage:nil];
|
default:
|
||||||
[statusItem setAlternateImage:nil];
|
case 1: {
|
||||||
[s_status release];
|
int fsize = 0;
|
||||||
|
NSString *add = nil;
|
||||||
}
|
if (menuBarSetting==0) {
|
||||||
if ([[defaults objectForKey:@"MenuBar"] intValue]==4) {
|
add=@"\n";
|
||||||
[statusItem setLength:65];
|
fsize=9;
|
||||||
NSMutableAttributedString *s_status=[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@",fan]];
|
[statusItem setLength:53];
|
||||||
[s_status addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Lucida Grande" size:12] range:NSMakeRange(0,[s_status length])];
|
} else {
|
||||||
[s_status addAttribute:NSForegroundColorAttributeName value:(NSColor*)[NSUnarchiver unarchiveObjectWithData:[defaults objectForKey:@"MenuColor"]] range:NSMakeRange(0,[s_status length])];
|
add=@" ";
|
||||||
[statusItem setAttributedTitle:s_status];
|
fsize=11;
|
||||||
[statusItem setImage:nil];
|
[statusItem setLength:96];
|
||||||
[statusItem setAlternateImage:nil];
|
}
|
||||||
[s_status release];
|
|
||||||
|
s_status=[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@%@%@",temp,add,fan]];
|
||||||
}
|
paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
|
||||||
|
[paragraphStyle setAlignment:NSLeftTextAlignment];
|
||||||
|
[s_status addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Lucida Grande" size:fsize] range:NSMakeRange(0,[s_status length])];
|
||||||
|
[s_status addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0,[s_status length])];
|
||||||
|
[s_status addAttribute:NSForegroundColorAttributeName value:(NSColor*)[NSUnarchiver unarchiveObjectWithData:[defaults objectForKey:@"MenuColor"]] range:NSMakeRange(0,[s_status length])];
|
||||||
|
[statusItem setAttributedTitle:s_status];
|
||||||
|
[statusItem setImage:nil];
|
||||||
|
[statusItem setAlternateImage:nil];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
// TODO: Big waste of energy to update this tooltip every X seconds when the user
|
||||||
|
// is unlikely to hover the smcFanControl icon over and over again.
|
||||||
|
[statusItem setLength:26];
|
||||||
|
[statusItem setTitle:nil];
|
||||||
|
[statusItem setToolTip:[NSString stringWithFormat:@"%@\n%@",temp,fan]];
|
||||||
|
[statusItem setImage:menu_image];
|
||||||
|
[statusItem setAlternateImage:menu_image_alt];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
[statusItem setLength:46];
|
||||||
|
s_status=[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@",temp]];
|
||||||
|
[s_status addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Lucida Grande" size:12] range:NSMakeRange(0,[s_status length])];
|
||||||
|
[s_status addAttribute:NSForegroundColorAttributeName value:(NSColor*)[NSUnarchiver unarchiveObjectWithData:[defaults objectForKey:@"MenuColor"]] range:NSMakeRange(0,[s_status length])];
|
||||||
|
[statusItem setAttributedTitle:s_status];
|
||||||
|
[statusItem setImage:nil];
|
||||||
|
[statusItem setAlternateImage:nil];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
[statusItem setLength:65];
|
||||||
|
s_status=[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@",fan]];
|
||||||
|
[s_status addAttribute:NSFontAttributeName value:[NSFont fontWithName:@"Lucida Grande" size:12] range:NSMakeRange(0,[s_status length])];
|
||||||
|
[s_status addAttribute:NSForegroundColorAttributeName value:(NSColor*)[NSUnarchiver unarchiveObjectWithData:[defaults objectForKey:@"MenuColor"]] range:NSMakeRange(0,[s_status length])];
|
||||||
|
[statusItem setAttributedTitle:s_status];
|
||||||
|
[statusItem setImage:nil];
|
||||||
|
[statusItem setAlternateImage:nil];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[paragraphStyle release];
|
||||||
|
[s_status release];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -474,7 +519,7 @@ NSString *authpw;
|
|||||||
-(void)terminate:(id)sender{
|
-(void)terminate:(id)sender{
|
||||||
//get last active selection
|
//get last active selection
|
||||||
[defaults synchronize];
|
[defaults synchronize];
|
||||||
SMCClose(conn);
|
[smcWrapper cleanUp];
|
||||||
[_readTimer invalidate];
|
[_readTimer invalidate];
|
||||||
[pw deregisterForSleepWakeNotification];
|
[pw deregisterForSleepWakeNotification];
|
||||||
[pw deregisterForPowerChange];
|
[pw deregisterForPowerChange];
|
||||||
@ -516,7 +561,24 @@ NSString *authpw;
|
|||||||
[[[FanController arrangedObjects] objectAtIndex:i] setValue:[NSNumber numberWithBool:NO] forKey:@"menu"];
|
[[[FanController arrangedObjects] objectAtIndex:i] setValue:[NSNumber numberWithBool:NO] forKey:@"menu"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called when user clicks on smcFanControl status bar item
|
||||||
|
// in the status area of the menubar. The fan speed
|
||||||
|
// menu items are now only updated here in order to
|
||||||
|
// reduce the energy impact of -readFanData.
|
||||||
|
- (void)menuNeedsUpdate:(NSMenu*)menu {
|
||||||
|
if (theMenu == menu) {
|
||||||
|
if (s_sed == nil)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for(i=0; i<g_numFans; ++i){
|
||||||
|
NSString *fandesc=[[[s_sed objectForKey:@"Fans"] objectAtIndex:i] objectForKey:@"Description"];
|
||||||
|
[[theMenu itemWithTag:(i+1)*10] setTitle:[NSString stringWithFormat:@"%@: %@ rpm",fandesc,[[NSNumber numberWithInt:[smcWrapper get_fan_rpm:i]] stringValue]]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -669,20 +731,23 @@ NSString *authpw;
|
|||||||
|
|
||||||
|
|
||||||
#pragma mark **SMC-Binary Owner/Right Check**
|
#pragma mark **SMC-Binary Owner/Right Check**
|
||||||
|
//TODO: It looks like this function is called inefficiently.
|
||||||
//call smc binary with sudo rights and apply
|
//call smc binary with sudo rights and apply
|
||||||
+(void)setRights{
|
+(void)setRights{
|
||||||
NSString *smcpath = [[NSBundle mainBundle] pathForResource:@"smc" ofType:@""];
|
NSString *smcpath = [[NSBundle mainBundle] pathForResource:@"smc" ofType:@""];
|
||||||
NSFileManager *fmanage=[NSFileManager defaultManager];
|
NSFileManager *fmanage=[NSFileManager defaultManager];
|
||||||
NSDictionary *fdic = [fmanage attributesOfItemAtPath:smcpath error:nil];
|
NSDictionary *fdic = [fmanage attributesOfItemAtPath:smcpath error:nil];
|
||||||
if ([[fdic valueForKey:@"NSFileOwnerAccountName"] isEqualToString:@"root"] && [[fdic valueForKey:@"NSFileGroupOwnerAccountName"] isEqualToString:@"admin"] && ([[fdic valueForKey:@"NSFilePosixPermissions"] intValue]==3437)) {
|
if ([[fdic valueForKey:@"NSFileOwnerAccountName"] isEqualToString:@"root"] && [[fdic valueForKey:@"NSFileGroupOwnerAccountName"] isEqualToString:@"admin"] && ([[fdic valueForKey:@"NSFilePosixPermissions"] intValue]==3437)) {
|
||||||
return;
|
// If the SMC binary has already been modified to run as root, then do nothing.
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
//TODO: Is the usage of commPipe safe?
|
||||||
FILE *commPipe;
|
FILE *commPipe;
|
||||||
AuthorizationRef authorizationRef;
|
AuthorizationRef authorizationRef;
|
||||||
AuthorizationItem gencitem = { "system.privilege.admin", 0, NULL, 0 };
|
AuthorizationItem gencitem = { "system.privilege.admin", 0, NULL, 0 };
|
||||||
AuthorizationRights gencright = { 1, &gencitem };
|
AuthorizationRights gencright = { 1, &gencitem };
|
||||||
int flags = kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed;
|
int flags = kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed;
|
||||||
status = AuthorizationCreate(&gencright, kAuthorizationEmptyEnvironment, flags, &authorizationRef);
|
OSStatus status = AuthorizationCreate(&gencright, kAuthorizationEmptyEnvironment, flags, &authorizationRef);
|
||||||
NSString *tool=@"/usr/sbin/chown";
|
NSString *tool=@"/usr/sbin/chown";
|
||||||
NSArray *argsArray = [NSArray arrayWithObjects: @"root:admin",smcpath,nil];
|
NSArray *argsArray = [NSArray arrayWithObjects: @"root:admin",smcpath,nil];
|
||||||
int i;
|
int i;
|
||||||
|
|||||||
@ -56,7 +56,9 @@ static void powerSourceChanged(void * refCon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (id)init{
|
- (id)init{
|
||||||
[super init];
|
if (self = [super init]) {
|
||||||
|
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
5
Classes/smcWrapper.h
Normal file → Executable file
5
Classes/smcWrapper.h
Normal file → Executable file
@ -2,7 +2,8 @@
|
|||||||
* FanControl
|
* FanControl
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006-2012 Hendrik Holtmann
|
* Copyright (c) 2006-2012 Hendrik Holtmann
|
||||||
*
|
* Portions Copyright (c) 2013 Michael Wilber
|
||||||
|
*
|
||||||
* smcWrapper.m - MacBook(Pro) FanControl application
|
* smcWrapper.m - MacBook(Pro) FanControl application
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -28,6 +29,8 @@
|
|||||||
@interface smcWrapper : NSObject {
|
@interface smcWrapper : NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+(void) cleanUp;
|
||||||
|
|
||||||
+(int) get_fan_rpm:(int)fan_number;
|
+(int) get_fan_rpm:(int)fan_number;
|
||||||
+(float) get_maintemp;
|
+(float) get_maintemp;
|
||||||
+(float) get_mptemp;
|
+(float) get_mptemp;
|
||||||
|
|||||||
56
Classes/smcWrapper.m
Normal file → Executable file
56
Classes/smcWrapper.m
Normal file → Executable file
@ -2,7 +2,8 @@
|
|||||||
* FanControl
|
* FanControl
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006-2012 Hendrik Holtmann
|
* Copyright (c) 2006-2012 Hendrik Holtmann
|
||||||
*
|
* Portions Copyright (c) 2013 Michael Wilber
|
||||||
|
*
|
||||||
* smcWrapper.m - MacBook(Pro) FanControl application
|
* smcWrapper.m - MacBook(Pro) FanControl application
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -23,46 +24,43 @@
|
|||||||
#import "smcWrapper.h"
|
#import "smcWrapper.h"
|
||||||
#import <CommonCrypto/CommonDigest.h>
|
#import <CommonCrypto/CommonDigest.h>
|
||||||
|
|
||||||
NSString * const smc_checksum=@"2ea544babe8a58dccc1364c920d473c8";
|
//TODO: This is the smcFanControl 2.5ß checksum, it needs to be updated for the next release.
|
||||||
static NSDictionary *tsensors = nil;
|
NSString * const smc_checksum=@"03548c5634bd01315b19c46bf329cceb";
|
||||||
|
static NSArray *allSensors = nil;
|
||||||
|
|
||||||
|
|
||||||
@implementation smcWrapper
|
@implementation smcWrapper
|
||||||
io_connect_t conn;
|
io_connect_t conn;
|
||||||
|
|
||||||
+(void)init{
|
+(void)init{
|
||||||
SMCOpen(&conn);
|
SMCOpen(&conn);
|
||||||
tsensors = [[NSDictionary alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tsensors" ofType:@"plist"]];
|
allSensors = [[NSArray alloc] initWithObjects:@"TC0D",@"TC0H",@"TC0F",@"TCAH",@"TCBH",@"TC0P",nil];
|
||||||
|
}
|
||||||
|
+(void)cleanUp{
|
||||||
|
SMCClose(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
+(float) get_maintemp{
|
+(float) get_maintemp{
|
||||||
float c_temp;
|
float c_temp;
|
||||||
|
|
||||||
NSRange range_pro=[[MachineDefaults computerModel] rangeOfString:@"MacPro"];
|
SMCVal_t val;
|
||||||
if (range_pro.length > 0) {
|
NSString *sensor = [[NSUserDefaults standardUserDefaults] objectForKey:@"TSensor"];
|
||||||
//special readout for MacPro
|
SMCReadKey2((char*)[sensor UTF8String], &val,conn);
|
||||||
c_temp=[smcWrapper get_mptemp];
|
c_temp= ((val.bytes[0] * 256 + val.bytes[1]) >> 2)/64;
|
||||||
} else {
|
|
||||||
SMCVal_t val;
|
if (c_temp<=0) {
|
||||||
NSMutableArray *allTSensors = [[tsensors allKeys] mutableCopy];
|
for (NSString *sensor in allSensors) {
|
||||||
NSString *foundKey = [tsensors objectForKey:[MachineDefaults computerModel]];
|
SMCReadKey2((char*)[sensor UTF8String], &val,conn);
|
||||||
if (foundKey !=nil) {
|
|
||||||
foundKey = [MachineDefaults computerModel];
|
|
||||||
} else {
|
|
||||||
foundKey = @"standard";
|
|
||||||
}
|
|
||||||
[allTSensors removeObject:foundKey];
|
|
||||||
SMCReadKey2((char*)[[tsensors objectForKey:foundKey] UTF8String], &val,conn);
|
|
||||||
c_temp= ((val.bytes[0] * 256 + val.bytes[1]) >> 2)/64;
|
|
||||||
|
|
||||||
if (c_temp<=0) {
|
|
||||||
for (NSString *key in allTSensors) {
|
|
||||||
SMCReadKey2((char*)[[tsensors objectForKey:key] UTF8String], &val,conn);
|
|
||||||
c_temp= ((val.bytes[0] * 256 + val.bytes[1]) >> 2)/64;
|
c_temp= ((val.bytes[0] * 256 + val.bytes[1]) >> 2)/64;
|
||||||
if (c_temp>0) break;
|
if (c_temp>0) {
|
||||||
}
|
[[NSUserDefaults standardUserDefaults] setObject:sensor forKey:@"TSensor"];
|
||||||
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return c_temp;
|
return c_temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,10 +166,12 @@ static NSDictionary *tsensors = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
//call smc binary with setuid rights and apply
|
//call smc binary with setuid rights and apply
|
||||||
|
// The smc binary is given root permissions in FanControl.m with the setRights method.
|
||||||
+(void)setKey_external:(NSString *)key value:(NSString *)value{
|
+(void)setKey_external:(NSString *)key value:(NSString *)value{
|
||||||
NSString *launchPath = [[NSBundle mainBundle] pathForResource:@"smc" ofType:@""];
|
NSString *launchPath = [[NSBundle mainBundle] pathForResource:@"smc" ofType:@""];
|
||||||
//first check if it's the right binary (security)
|
|
||||||
NSString *checksum=[smcWrapper createCheckSum:launchPath];
|
NSString *checksum=[smcWrapper createCheckSum:launchPath];
|
||||||
|
//first check if it's the right binary (security)
|
||||||
|
// MW: Disabled smc binary checksum. This should be re-enabled in an official release.
|
||||||
if (![checksum isEqualToString:smc_checksum]) {
|
if (![checksum isEqualToString:smc_checksum]) {
|
||||||
NSLog(@"smcFanControl: Security Error: smc-binary is not the distributed one");
|
NSLog(@"smcFanControl: Security Error: smc-binary is not the distributed one");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>smcFanControl</string>
|
<string>smcFanControl</string>
|
||||||
<key>CFBundleGetInfoString</key>
|
<key>CFBundleGetInfoString</key>
|
||||||
<string>smcFanControl 2.4, Hendrik Holtmann (GPL)</string>
|
<string>smcFanControl 2.5ß, Hendrik Holtmann (GPL)</string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>smcfancontrol_v2</string>
|
<string>smcfancontrol_v2</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
@ -19,11 +19,11 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2.4</string>
|
<string>2.5ß</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>2.4</string>
|
<string>2.5ß</string>
|
||||||
<key>LSUIElement</key>
|
<key>LSUIElement</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
|||||||
5
README
5
README
@ -1,5 +0,0 @@
|
|||||||
smcFanControl lets the user set the minimum speed of the build in fans. So you can increase your minimum fan speed to make your Intel Mac run cooler. However in order not to damage your machines smcFanControl doesn't let you set a minimum speed to a value below Apple's defaults.
|
|
||||||
|
|
||||||
Requirements: Intel Mac / OS X 10.5 or higher
|
|
||||||
|
|
||||||
License: GPL 2
|
|
||||||
14
Readme.md
Normal file
14
Readme.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
smcFanControl
|
||||||
|
=============
|
||||||
|
|
||||||
|
smcFanControl lets the user set a minimum speed for built-in fans. It allows you to increase your minimum fan speed to make your Intel Mac run cooler. In order to not damage your machine, smcFanControl does not let you set a minimum speed to a value below Apple's defaults.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Requirements: Intel Mac / OS X 10.5 or higher
|
||||||
|
|
||||||
|
Compiled version: http://www.eidac.de/smcfancontrol/smcfancontrol_2_4.zip
|
||||||
|
|
||||||
|
FAQ / More info: Found in project under "Ressources/*.lproj/F.A.Q.rtf" or included in above .zip
|
||||||
|
|
||||||
|
License: GPL 2
|
||||||
@ -1,16 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>standard</key>
|
|
||||||
<string>TC0D</string>
|
|
||||||
<key>lastAlternative</key>
|
|
||||||
<string>TCAH</string>
|
|
||||||
<key>MacBookPro10,1</key>
|
|
||||||
<string>TC0F</string>
|
|
||||||
<key>iMac12,2</key>
|
|
||||||
<string>TC0H</string>
|
|
||||||
<key>iMac12,1</key>
|
|
||||||
<string>TC0H</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
658
smc-command/smc.c
Normal file → Executable file
658
smc-command/smc.c
Normal file → Executable file
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Apple System Management Control (SMC) Tool
|
* Apple System Management Control (SMC) Tool
|
||||||
* Copyright (C) 2006 devnull
|
* Copyright (C) 2006 devnull
|
||||||
|
* Portions Copyright (C) 2013 Michael Wilber
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -22,10 +23,22 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <IOKit/IOKitLib.h>
|
#include <IOKit/IOKitLib.h>
|
||||||
|
|
||||||
#include "smc.h"
|
#include "smc.h"
|
||||||
|
#include <libkern/OSAtomic.h>
|
||||||
|
|
||||||
io_connect_t conn;
|
// Cache the keyInfo to lower the energy impact of SMCReadKey() / SMCReadKey2()
|
||||||
|
#define KEY_INFO_CACHE_SIZE 100
|
||||||
|
struct {
|
||||||
|
UInt32 key;
|
||||||
|
SMCKeyData_keyInfo_t keyInfo;
|
||||||
|
} g_keyInfoCache[KEY_INFO_CACHE_SIZE];
|
||||||
|
|
||||||
|
int g_keyInfoCacheCount = 0;
|
||||||
|
OSSpinLock g_keyInfoSpinLock = 0;
|
||||||
|
|
||||||
|
kern_return_t SMCCall2(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure, io_connect_t conn);
|
||||||
|
|
||||||
|
#pragma mark C Helpers
|
||||||
|
|
||||||
UInt32 _strtoul(char *str, int size, int base)
|
UInt32 _strtoul(char *str, int size, int base)
|
||||||
{
|
{
|
||||||
@ -37,7 +50,7 @@ UInt32 _strtoul(char *str, int size, int base)
|
|||||||
if (base == 16)
|
if (base == 16)
|
||||||
total += str[i] << (size - 1 - i) * 8;
|
total += str[i] << (size - 1 - i) * 8;
|
||||||
else
|
else
|
||||||
total += (unsigned char) (str[i] << (size - 1 - i) * 8);
|
total += ((unsigned char) (str[i]) << (size - 1 - i) * 8);
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
@ -52,34 +65,68 @@ void _ultostr(char *str, UInt32 val)
|
|||||||
(unsigned int) val);
|
(unsigned int) val);
|
||||||
}
|
}
|
||||||
|
|
||||||
float _strtof(char *str, int size, int e)
|
float _strtof(unsigned char *str, int size, int e)
|
||||||
{
|
{
|
||||||
float total = 0;
|
float total = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
if (i == (size - 1))
|
if (i == (size - 1))
|
||||||
total += (str[i] & 0xff) >> e;
|
total += (str[i] & 0xff) >> e;
|
||||||
else
|
else
|
||||||
total += str[i] << (size - 1 - i) * (8 - e);
|
total += str[i] << (size - 1 - i) * (8 - e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
total += (str[size-1] & 0x03) * 0.25;
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smc_init(){
|
|
||||||
SMCOpen(&conn);
|
void printFP1F(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.5f ", ntohs(*(UInt16*)val.bytes) / 32768.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void smc_close(){
|
void printFP4C(SMCVal_t val)
|
||||||
SMCClose(conn);
|
{
|
||||||
|
printf("%.5f ", ntohs(*(UInt16*)val.bytes) / 4096.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printFP5B(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.5f ", ntohs(*(UInt16*)val.bytes) / 2048.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFP6A(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.4f ", ntohs(*(UInt16*)val.bytes) / 1024.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFP79(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.4f ", ntohs(*(UInt16*)val.bytes) / 512.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFP88(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.3f ", ntohs(*(UInt16*)val.bytes) / 256.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFPA6(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.2f ", ntohs(*(UInt16*)val.bytes) / 64.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printFPC4(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.2f ", ntohs(*(UInt16*)val.bytes) / 16.0);
|
||||||
|
}
|
||||||
|
|
||||||
void printFPE2(SMCVal_t val)
|
void printFPE2(SMCVal_t val)
|
||||||
{
|
{
|
||||||
/* FIXME: This decode is incomplete, last 2 bits are dropped */
|
printf("%.2f ", ntohs(*(UInt16*)val.bytes) / 4.0);
|
||||||
|
|
||||||
printf("%.0f ", _strtof(val.bytes, val.dataSize, 2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void printUInt(SMCVal_t val)
|
void printUInt(SMCVal_t val)
|
||||||
@ -87,6 +134,71 @@ void printUInt(SMCVal_t val)
|
|||||||
printf("%u ", (unsigned int) _strtoul(val.bytes, val.dataSize, 10));
|
printf("%u ", (unsigned int) _strtoul(val.bytes, val.dataSize, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printSP1E(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.5f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 16384.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP3C(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.5f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 4096.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP4B(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.4f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 2048.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP5A(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.4f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 1024.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP69(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.3f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 512.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP78(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.3f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 256.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP87(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.3f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 128.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSP96(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.2f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 64.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSPB4(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.2f ", ((SInt16)ntohs(*(UInt16*)val.bytes)) / 16.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSPF0(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.0f ", (float)ntohs(*(UInt16*)val.bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSI8(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%d ", (signed char)*val.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSI16(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%d ", ntohs(*(SInt16*)val.bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
void printPWM(SMCVal_t val)
|
||||||
|
{
|
||||||
|
printf("%.1f%% ", ntohs(*(UInt16*)val.bytes) * 100 / 65536.0);
|
||||||
|
}
|
||||||
|
|
||||||
void printBytesHex(SMCVal_t val)
|
void printBytesHex(SMCVal_t val)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -106,8 +218,50 @@ void printVal(SMCVal_t val)
|
|||||||
(strcmp(val.dataType, DATATYPE_UINT16) == 0) ||
|
(strcmp(val.dataType, DATATYPE_UINT16) == 0) ||
|
||||||
(strcmp(val.dataType, DATATYPE_UINT32) == 0))
|
(strcmp(val.dataType, DATATYPE_UINT32) == 0))
|
||||||
printUInt(val);
|
printUInt(val);
|
||||||
else if (strcmp(val.dataType, DATATYPE_FPE2) == 0)
|
else if (strcmp(val.dataType, DATATYPE_FP1F) == 0 && val.dataSize == 2)
|
||||||
|
printFP1F(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP4C) == 0 && val.dataSize == 2)
|
||||||
|
printFP4C(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP5B) == 0 && val.dataSize == 2)
|
||||||
|
printFP5B(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP6A) == 0 && val.dataSize == 2)
|
||||||
|
printFP6A(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP79) == 0 && val.dataSize == 2)
|
||||||
|
printFP79(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FP88) == 0 && val.dataSize == 2)
|
||||||
|
printFP88(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FPA6) == 0 && val.dataSize == 2)
|
||||||
|
printFPA6(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FPC4) == 0 && val.dataSize == 2)
|
||||||
|
printFPC4(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_FPE2) == 0 && val.dataSize == 2)
|
||||||
printFPE2(val);
|
printFPE2(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP1E) == 0 && val.dataSize == 2)
|
||||||
|
printSP1E(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP3C) == 0 && val.dataSize == 2)
|
||||||
|
printSP3C(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP4B) == 0 && val.dataSize == 2)
|
||||||
|
printSP4B(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP5A) == 0 && val.dataSize == 2)
|
||||||
|
printSP5A(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP69) == 0 && val.dataSize == 2)
|
||||||
|
printSP69(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP78) == 0 && val.dataSize == 2)
|
||||||
|
printSP78(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP87) == 0 && val.dataSize == 2)
|
||||||
|
printSP87(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SP96) == 0 && val.dataSize == 2)
|
||||||
|
printSP96(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SPB4) == 0 && val.dataSize == 2)
|
||||||
|
printSPB4(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SPF0) == 0 && val.dataSize == 2)
|
||||||
|
printSPF0(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SI8) == 0 && val.dataSize == 1)
|
||||||
|
printSI8(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_SI16) == 0 && val.dataSize == 2)
|
||||||
|
printSI16(val);
|
||||||
|
else if (strcmp(val.dataType, DATATYPE_PWM) == 0 && val.dataSize == 2)
|
||||||
|
printPWM(val);
|
||||||
|
|
||||||
printBytesHex(val);
|
printBytesHex(val);
|
||||||
}
|
}
|
||||||
@ -117,15 +271,17 @@ void printVal(SMCVal_t val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark Shared SMC functions
|
||||||
|
|
||||||
kern_return_t SMCOpen(io_connect_t *conn)
|
kern_return_t SMCOpen(io_connect_t *conn)
|
||||||
{
|
{
|
||||||
kern_return_t result;
|
kern_return_t result;
|
||||||
mach_port_t masterPort;
|
mach_port_t masterPort;
|
||||||
io_iterator_t iterator;
|
io_iterator_t iterator;
|
||||||
io_object_t device;
|
io_object_t device;
|
||||||
|
|
||||||
IOMasterPort(MACH_PORT_NULL, &masterPort);
|
IOMasterPort(MACH_PORT_NULL, &masterPort);
|
||||||
|
|
||||||
CFMutableDictionaryRef matchingDictionary = IOServiceMatching("AppleSMC");
|
CFMutableDictionaryRef matchingDictionary = IOServiceMatching("AppleSMC");
|
||||||
result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator);
|
result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator);
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
@ -133,7 +289,7 @@ kern_return_t SMCOpen(io_connect_t *conn)
|
|||||||
printf("Error: IOServiceGetMatchingServices() = %08x\n", result);
|
printf("Error: IOServiceGetMatchingServices() = %08x\n", result);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
device = IOIteratorNext(iterator);
|
device = IOIteratorNext(iterator);
|
||||||
IOObjectRelease(iterator);
|
IOObjectRelease(iterator);
|
||||||
if (device == 0)
|
if (device == 0)
|
||||||
@ -141,7 +297,7 @@ kern_return_t SMCOpen(io_connect_t *conn)
|
|||||||
printf("Error: no SMC found\n");
|
printf("Error: no SMC found\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = IOServiceOpen(device, mach_task_self(), 0, conn);
|
result = IOServiceOpen(device, mach_task_self(), 0, conn);
|
||||||
IOObjectRelease(device);
|
IOObjectRelease(device);
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
@ -149,7 +305,7 @@ kern_return_t SMCOpen(io_connect_t *conn)
|
|||||||
printf("Error: IOServiceOpen() = %08x\n", result);
|
printf("Error: IOServiceOpen() = %08x\n", result);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return kIOReturnSuccess;
|
return kIOReturnSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,45 +314,60 @@ kern_return_t SMCClose(io_connect_t conn)
|
|||||||
return IOServiceClose(conn);
|
return IOServiceClose(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
kern_return_t SMCCall(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure)
|
|
||||||
{
|
|
||||||
size_t structureInputSize;
|
|
||||||
size_t structureOutputSize;
|
|
||||||
|
|
||||||
structureInputSize = sizeof(SMCKeyData_t);
|
|
||||||
structureOutputSize = sizeof(SMCKeyData_t);
|
|
||||||
/*
|
|
||||||
return IOConnectMethodStructureIStructureO(
|
|
||||||
conn,
|
|
||||||
index,
|
|
||||||
structureInputSize,
|
|
||||||
&structureOutputSize,
|
|
||||||
inputStructure,
|
|
||||||
outputStructure
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
return IOConnectCallStructMethod(conn, index, inputStructure, structureInputSize, outputStructure, &structureOutputSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
kern_return_t SMCCall2(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure,io_connect_t conn)
|
kern_return_t SMCCall2(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure,io_connect_t conn)
|
||||||
{
|
{
|
||||||
size_t structureInputSize;
|
size_t structureInputSize;
|
||||||
size_t structureOutputSize;
|
size_t structureOutputSize;
|
||||||
structureInputSize = sizeof(SMCKeyData_t);
|
structureInputSize = sizeof(SMCKeyData_t);
|
||||||
structureOutputSize = sizeof(SMCKeyData_t);
|
structureOutputSize = sizeof(SMCKeyData_t);
|
||||||
|
|
||||||
/* return IOConnectMethodStructureIStructureO(
|
|
||||||
conn,
|
|
||||||
index,
|
|
||||||
structureInputSize,
|
|
||||||
&structureOutputSize,
|
|
||||||
inputStructure,
|
|
||||||
outputStructure
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
return IOConnectCallStructMethod(conn, index, inputStructure, structureInputSize, outputStructure, &structureOutputSize);
|
return IOConnectCallStructMethod(conn, index, inputStructure, structureInputSize, outputStructure, &structureOutputSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provides key info, using a cache to dramatically improve the energy impact of smcFanControl
|
||||||
|
kern_return_t SMCGetKeyInfo(UInt32 key, SMCKeyData_keyInfo_t* keyInfo, io_connect_t conn)
|
||||||
|
{
|
||||||
|
SMCKeyData_t inputStructure;
|
||||||
|
SMCKeyData_t outputStructure;
|
||||||
|
kern_return_t result = kIOReturnSuccess;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
OSSpinLockLock(&g_keyInfoSpinLock);
|
||||||
|
|
||||||
|
for (; i < g_keyInfoCacheCount; ++i)
|
||||||
|
{
|
||||||
|
if (key == g_keyInfoCache[i].key)
|
||||||
|
{
|
||||||
|
*keyInfo = g_keyInfoCache[i].keyInfo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == g_keyInfoCacheCount)
|
||||||
|
{
|
||||||
|
// Not in cache, must look it up.
|
||||||
|
memset(&inputStructure, 0, sizeof(inputStructure));
|
||||||
|
memset(&outputStructure, 0, sizeof(outputStructure));
|
||||||
|
|
||||||
|
inputStructure.key = key;
|
||||||
|
inputStructure.data8 = SMC_CMD_READ_KEYINFO;
|
||||||
|
|
||||||
|
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure, conn);
|
||||||
|
if (result == kIOReturnSuccess)
|
||||||
|
{
|
||||||
|
*keyInfo = outputStructure.keyInfo;
|
||||||
|
if (g_keyInfoCacheCount < KEY_INFO_CACHE_SIZE)
|
||||||
|
{
|
||||||
|
g_keyInfoCache[g_keyInfoCacheCount].key = key;
|
||||||
|
g_keyInfoCache[g_keyInfoCacheCount].keyInfo = outputStructure.keyInfo;
|
||||||
|
++g_keyInfoCacheCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OSSpinLockUnlock(&g_keyInfoSpinLock);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_return_t SMCReadKey2(UInt32Char_t key, SMCVal_t *val,io_connect_t conn)
|
kern_return_t SMCReadKey2(UInt32Char_t key, SMCVal_t *val,io_connect_t conn)
|
||||||
@ -204,129 +375,98 @@ kern_return_t SMCReadKey2(UInt32Char_t key, SMCVal_t *val,io_connect_t conn)
|
|||||||
kern_return_t result;
|
kern_return_t result;
|
||||||
SMCKeyData_t inputStructure;
|
SMCKeyData_t inputStructure;
|
||||||
SMCKeyData_t outputStructure;
|
SMCKeyData_t outputStructure;
|
||||||
|
|
||||||
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
memset(val, 0, sizeof(SMCVal_t));
|
memset(val, 0, sizeof(SMCVal_t));
|
||||||
|
|
||||||
inputStructure.key = _strtoul(key, 4, 16);
|
inputStructure.key = _strtoul(key, 4, 16);
|
||||||
sprintf(val->key, key);
|
sprintf(val->key, key);
|
||||||
inputStructure.data8 = SMC_CMD_READ_KEYINFO;
|
|
||||||
|
result = SMCGetKeyInfo(inputStructure.key, &outputStructure.keyInfo, conn);
|
||||||
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn);
|
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
|
{
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
val->dataSize = outputStructure.keyInfo.dataSize;
|
val->dataSize = outputStructure.keyInfo.dataSize;
|
||||||
_ultostr(val->dataType, outputStructure.keyInfo.dataType);
|
_ultostr(val->dataType, outputStructure.keyInfo.dataType);
|
||||||
inputStructure.keyInfo.dataSize = val->dataSize;
|
inputStructure.keyInfo.dataSize = val->dataSize;
|
||||||
inputStructure.data8 = SMC_CMD_READ_BYTES;
|
inputStructure.data8 = SMC_CMD_READ_BYTES;
|
||||||
|
|
||||||
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn);
|
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn);
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
return result;
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes));
|
memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes));
|
||||||
|
|
||||||
return kIOReturnSuccess;
|
return kIOReturnSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark Command line only
|
||||||
|
// Exclude command-line only code from smcFanControl UI
|
||||||
|
#ifdef CMD_TOOL
|
||||||
|
|
||||||
|
io_connect_t g_conn = 0;
|
||||||
|
|
||||||
|
void smc_init(){
|
||||||
|
SMCOpen(&g_conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void smc_close(){
|
||||||
|
SMCClose(g_conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCCall(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure)
|
||||||
|
{
|
||||||
|
return SMCCall2(index, inputStructure, outputStructure, g_conn);
|
||||||
|
}
|
||||||
|
|
||||||
kern_return_t SMCReadKey(UInt32Char_t key, SMCVal_t *val)
|
kern_return_t SMCReadKey(UInt32Char_t key, SMCVal_t *val)
|
||||||
|
{
|
||||||
|
return SMCReadKey2(key, val, g_conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_return_t SMCWriteKey2(SMCVal_t writeVal, io_connect_t conn)
|
||||||
{
|
{
|
||||||
kern_return_t result;
|
kern_return_t result;
|
||||||
SMCKeyData_t inputStructure;
|
SMCKeyData_t inputStructure;
|
||||||
SMCKeyData_t outputStructure;
|
SMCKeyData_t outputStructure;
|
||||||
|
|
||||||
|
SMCVal_t readVal;
|
||||||
|
|
||||||
|
result = SMCReadKey2(writeVal.key, &readVal,conn);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (readVal.dataSize != writeVal.dataSize)
|
||||||
|
return kIOReturnError;
|
||||||
|
|
||||||
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
memset(val, 0, sizeof(SMCVal_t));
|
|
||||||
|
inputStructure.key = _strtoul(writeVal.key, 4, 16);
|
||||||
inputStructure.key = _strtoul(key, 4, 16);
|
inputStructure.data8 = SMC_CMD_WRITE_BYTES;
|
||||||
sprintf(val->key, key);
|
inputStructure.keyInfo.dataSize = writeVal.dataSize;
|
||||||
inputStructure.data8 = SMC_CMD_READ_KEYINFO;
|
memcpy(inputStructure.bytes, writeVal.bytes, sizeof(writeVal.bytes));
|
||||||
|
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn);
|
||||||
result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure);
|
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
val->dataSize = outputStructure.keyInfo.dataSize;
|
|
||||||
_ultostr(val->dataType, outputStructure.keyInfo.dataType);
|
|
||||||
inputStructure.keyInfo.dataSize = val->dataSize;
|
|
||||||
inputStructure.data8 = SMC_CMD_READ_BYTES;
|
|
||||||
|
|
||||||
result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure);
|
|
||||||
if (result != kIOReturnSuccess)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes));
|
|
||||||
|
|
||||||
return kIOReturnSuccess;
|
return kIOReturnSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
kern_return_t SMCWriteKey(SMCVal_t writeVal)
|
kern_return_t SMCWriteKey(SMCVal_t writeVal)
|
||||||
{
|
{
|
||||||
kern_return_t result;
|
return SMCWriteKey2(writeVal, g_conn);
|
||||||
SMCKeyData_t inputStructure;
|
|
||||||
SMCKeyData_t outputStructure;
|
|
||||||
|
|
||||||
SMCVal_t readVal;
|
|
||||||
|
|
||||||
result = SMCReadKey(writeVal.key, &readVal);
|
|
||||||
if (result != kIOReturnSuccess)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
if (readVal.dataSize != writeVal.dataSize)
|
|
||||||
return kIOReturnError;
|
|
||||||
|
|
||||||
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
|
||||||
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
|
||||||
|
|
||||||
inputStructure.key = _strtoul(writeVal.key, 4, 16);
|
|
||||||
inputStructure.data8 = SMC_CMD_WRITE_BYTES;
|
|
||||||
inputStructure.keyInfo.dataSize = writeVal.dataSize;
|
|
||||||
memcpy(inputStructure.bytes, writeVal.bytes, sizeof(writeVal.bytes));
|
|
||||||
|
|
||||||
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn);
|
|
||||||
if (result != kIOReturnSuccess)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
return kIOReturnSuccess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_return_t SMCWriteKey2(SMCVal_t writeVal,io_connect_t conn)
|
|
||||||
{
|
|
||||||
kern_return_t result;
|
|
||||||
SMCKeyData_t inputStructure;
|
|
||||||
SMCKeyData_t outputStructure;
|
|
||||||
|
|
||||||
SMCVal_t readVal;
|
|
||||||
|
|
||||||
result = SMCReadKey2(writeVal.key, &readVal,conn);
|
|
||||||
if (result != kIOReturnSuccess)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
if (readVal.dataSize != writeVal.dataSize)
|
|
||||||
return kIOReturnError;
|
|
||||||
|
|
||||||
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
|
||||||
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
|
||||||
|
|
||||||
inputStructure.key = _strtoul(writeVal.key, 4, 16);
|
|
||||||
inputStructure.data8 = SMC_CMD_WRITE_BYTES;
|
|
||||||
inputStructure.keyInfo.dataSize = writeVal.dataSize;
|
|
||||||
memcpy(inputStructure.bytes, writeVal.bytes, sizeof(writeVal.bytes));
|
|
||||||
result = SMCCall2(KERNEL_INDEX_SMC, &inputStructure, &outputStructure,conn);
|
|
||||||
|
|
||||||
if (result != kIOReturnSuccess)
|
|
||||||
return result;
|
|
||||||
return kIOReturnSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
UInt32 SMCReadIndexCount(void)
|
UInt32 SMCReadIndexCount(void)
|
||||||
{
|
{
|
||||||
SMCVal_t val;
|
SMCVal_t val;
|
||||||
|
|
||||||
SMCReadKey("#KEY", &val);
|
SMCReadKey("#KEY", &val);
|
||||||
return _strtoul(val.bytes, val.dataSize, 10);
|
return _strtoul(val.bytes, val.dataSize, 10);
|
||||||
}
|
}
|
||||||
@ -336,31 +476,31 @@ kern_return_t SMCPrintAll(void)
|
|||||||
kern_return_t result;
|
kern_return_t result;
|
||||||
SMCKeyData_t inputStructure;
|
SMCKeyData_t inputStructure;
|
||||||
SMCKeyData_t outputStructure;
|
SMCKeyData_t outputStructure;
|
||||||
|
|
||||||
int totalKeys, i;
|
int totalKeys, i;
|
||||||
UInt32Char_t key;
|
UInt32Char_t key;
|
||||||
SMCVal_t val;
|
SMCVal_t val;
|
||||||
|
|
||||||
totalKeys = SMCReadIndexCount();
|
totalKeys = SMCReadIndexCount();
|
||||||
for (i = 0; i < totalKeys; i++)
|
for (i = 0; i < totalKeys; i++)
|
||||||
{
|
{
|
||||||
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
memset(&inputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
memset(&outputStructure, 0, sizeof(SMCKeyData_t));
|
||||||
memset(&val, 0, sizeof(SMCVal_t));
|
memset(&val, 0, sizeof(SMCVal_t));
|
||||||
|
|
||||||
inputStructure.data8 = SMC_CMD_READ_INDEX;
|
inputStructure.data8 = SMC_CMD_READ_INDEX;
|
||||||
inputStructure.data32 = i;
|
inputStructure.data32 = i;
|
||||||
|
|
||||||
result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure);
|
result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure);
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
_ultostr(key, outputStructure.key);
|
_ultostr(key, outputStructure.key);
|
||||||
|
|
||||||
SMCReadKey(key, &val);
|
SMCReadKey(key, &val);
|
||||||
printVal(val);
|
printVal(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return kIOReturnSuccess;
|
return kIOReturnSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,112 +510,114 @@ kern_return_t SMCPrintFans(void)
|
|||||||
SMCVal_t val;
|
SMCVal_t val;
|
||||||
UInt32Char_t key;
|
UInt32Char_t key;
|
||||||
int totalFans, i;
|
int totalFans, i;
|
||||||
|
|
||||||
result = SMCReadKey("FNum", &val);
|
result = SMCReadKey("FNum", &val);
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
return kIOReturnError;
|
return kIOReturnError;
|
||||||
|
|
||||||
totalFans = _strtoul(val.bytes, val.dataSize, 10);
|
totalFans = _strtoul(val.bytes, val.dataSize, 10);
|
||||||
printf("Total fans in system: %d\n", totalFans);
|
printf("Total fans in system: %d\n", totalFans);
|
||||||
|
|
||||||
for (i = 0; i < totalFans; i++)
|
for (i = 0; i < totalFans; i++)
|
||||||
{
|
{
|
||||||
printf("\nFan #%d:\n", i);
|
printf("\nFan #%d:\n", i);
|
||||||
|
sprintf(key, "F%dID", i);
|
||||||
|
SMCReadKey(key, &val);
|
||||||
|
printf(" Fan ID : %s\n", val.bytes+4);
|
||||||
sprintf(key, "F%dAc", i);
|
sprintf(key, "F%dAc", i);
|
||||||
SMCReadKey(key, &val);
|
SMCReadKey(key, &val);
|
||||||
printf(" Actual speed : %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
printf(" Actual speed : %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
||||||
sprintf(key, "F%dMn", i);
|
sprintf(key, "F%dMn", i);
|
||||||
SMCReadKey(key, &val);
|
SMCReadKey(key, &val);
|
||||||
printf(" Minimum speed: %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
printf(" Minimum speed: %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
||||||
sprintf(key, "F%dMx", i);
|
sprintf(key, "F%dMx", i);
|
||||||
SMCReadKey(key, &val);
|
SMCReadKey(key, &val);
|
||||||
printf(" Maximum speed: %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
printf(" Maximum speed: %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
||||||
sprintf(key, "F%dSf", i);
|
sprintf(key, "F%dSf", i);
|
||||||
SMCReadKey(key, &val);
|
SMCReadKey(key, &val);
|
||||||
printf(" Safe speed : %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
printf(" Safe speed : %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
||||||
sprintf(key, "F%dTg", i);
|
sprintf(key, "F%dTg", i);
|
||||||
SMCReadKey(key, &val);
|
SMCReadKey(key, &val);
|
||||||
printf(" Target speed : %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
printf(" Target speed : %.0f\n", _strtof(val.bytes, val.dataSize, 2));
|
||||||
SMCReadKey("FS! ", &val);
|
SMCReadKey("FS! ", &val);
|
||||||
if ((_strtoul(val.bytes, 2, 16) & (1 << i)) == 0)
|
if ((_strtoul(val.bytes, 2, 16) & (1 << i)) == 0)
|
||||||
printf(" Mode : auto\n");
|
printf(" Mode : auto\n");
|
||||||
else
|
else
|
||||||
printf(" Mode : forced\n");
|
printf(" Mode : forced\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return kIOReturnSuccess;
|
return kIOReturnSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usage(char* prog)
|
void usage(char* prog)
|
||||||
{
|
{
|
||||||
printf("Apple System Management Control (SMC) tool %s\n", VERSION);
|
printf("Apple System Management Control (SMC) tool %s\n", VERSION);
|
||||||
printf("Usage:\n");
|
printf("Usage:\n");
|
||||||
printf("%s [options]\n", prog);
|
printf("%s [options]\n", prog);
|
||||||
printf(" -f : fan info decoded\n");
|
printf(" -f : fan info decoded\n");
|
||||||
printf(" -h : help\n");
|
printf(" -h : help\n");
|
||||||
printf(" -k <key> : key to manipulate\n");
|
printf(" -k <key> : key to manipulate\n");
|
||||||
printf(" -l : list all keys and values\n");
|
printf(" -l : list all keys and values\n");
|
||||||
printf(" -r : read the value of a key\n");
|
printf(" -r : read the value of a key\n");
|
||||||
printf(" -w <value> : write the specified value to a key\n");
|
printf(" -w <value> : write the specified value to a key\n");
|
||||||
printf(" -v : version\n");
|
printf(" -v : version\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_return_t SMCWriteSimple(UInt32Char_t key,char *wvalue,io_connect_t conn)
|
kern_return_t SMCWriteSimple(UInt32Char_t key, char *wvalue, io_connect_t conn)
|
||||||
{
|
{
|
||||||
kern_return_t result;
|
kern_return_t result;
|
||||||
SMCVal_t val;
|
SMCVal_t val;
|
||||||
int i;
|
int i;
|
||||||
char c[3];
|
char c[3];
|
||||||
for (i = 0; i < strlen(wvalue); i++)
|
for (i = 0; i < strlen(wvalue); i++)
|
||||||
{
|
{
|
||||||
sprintf(c, "%c%c", wvalue[i * 2], wvalue[(i * 2) + 1]);
|
sprintf(c, "%c%c", wvalue[i * 2], wvalue[(i * 2) + 1]);
|
||||||
val.bytes[i] = (int) strtol(c, NULL, 16);
|
val.bytes[i] = (int) strtol(c, NULL, 16);
|
||||||
}
|
}
|
||||||
val.dataSize = i / 2;
|
val.dataSize = i / 2;
|
||||||
sprintf(val.key, key);
|
sprintf(val.key, key);
|
||||||
result = SMCWriteKey2(val,conn);
|
result = SMCWriteKey2(val, conn);
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
printf("Error: SMCWriteKey() = %08x\n", result);
|
printf("Error: SMCWriteKey() = %08x\n", result);
|
||||||
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef CMD_TOOL
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
|
|
||||||
kern_return_t result;
|
kern_return_t result;
|
||||||
int op = OP_NONE;
|
int op = OP_NONE;
|
||||||
UInt32Char_t key = "\0";
|
UInt32Char_t key = { 0 };
|
||||||
SMCVal_t val;
|
SMCVal_t val;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "fhk:lrw:v")) != -1)
|
while ((c = getopt(argc, argv, "fhk:lrw:v")) != -1)
|
||||||
{
|
{
|
||||||
switch(c)
|
switch(c)
|
||||||
{
|
{
|
||||||
case 'f':
|
case 'f':
|
||||||
op = OP_READ_FAN;
|
op = OP_READ_FAN;
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
strncpy(key, optarg, sizeof(key)); //fix for buffer overflow
|
strncpy(key, optarg, sizeof(key)); //fix for buffer overflow
|
||||||
break;
|
key[sizeof(key) - 1] = '\0';
|
||||||
case 'l':
|
break;
|
||||||
op = OP_LIST;
|
case 'l':
|
||||||
break;
|
op = OP_LIST;
|
||||||
case 'r':
|
break;
|
||||||
op = OP_READ;
|
case 'r':
|
||||||
break;
|
op = OP_READ;
|
||||||
case 'v':
|
break;
|
||||||
printf("%s\n", VERSION);
|
case 'v':
|
||||||
return 0;
|
printf("%s\n", VERSION);
|
||||||
break;
|
return 0;
|
||||||
case 'w':
|
break;
|
||||||
op = OP_WRITE;
|
case 'w':
|
||||||
|
op = OP_WRITE;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char c[3];
|
char c[3];
|
||||||
@ -491,65 +633,67 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case '?':
|
case '?':
|
||||||
op = OP_NONE;
|
op = OP_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == OP_NONE)
|
if (op == OP_NONE)
|
||||||
{
|
{
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMCOpen(&conn);
|
smc_init();
|
||||||
|
|
||||||
switch(op)
|
switch(op)
|
||||||
{
|
{
|
||||||
case OP_LIST:
|
case OP_LIST:
|
||||||
result = SMCPrintAll();
|
result = SMCPrintAll();
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
printf("Error: SMCPrintAll() = %08x\n", result);
|
printf("Error: SMCPrintAll() = %08x\n", result);
|
||||||
break;
|
break;
|
||||||
case OP_READ:
|
case OP_READ:
|
||||||
if (strlen(key) > 0)
|
if (strlen(key) > 0)
|
||||||
{
|
{
|
||||||
result = SMCReadKey(key, &val);
|
result = SMCReadKey(key, &val);
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
printf("Error: SMCReadKey() = %08x\n", result);
|
printf("Error: SMCReadKey() = %08x\n", result);
|
||||||
|
else
|
||||||
|
printVal(val);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
printVal(val);
|
{
|
||||||
}
|
printf("Error: specify a key to read\n");
|
||||||
else
|
}
|
||||||
{
|
break;
|
||||||
printf("Error: specify a key to read\n");
|
case OP_READ_FAN:
|
||||||
}
|
result = SMCPrintFans();
|
||||||
break;
|
|
||||||
case OP_READ_FAN:
|
|
||||||
result = SMCPrintFans();
|
|
||||||
if (result != kIOReturnSuccess)
|
|
||||||
printf("Error: SMCPrintFans() = %08x\n", result);
|
|
||||||
break;
|
|
||||||
case OP_WRITE:
|
|
||||||
if (strlen(key) > 0)
|
|
||||||
{
|
|
||||||
sprintf(val.key, key);
|
|
||||||
result = SMCWriteKey(val);
|
|
||||||
if (result != kIOReturnSuccess)
|
if (result != kIOReturnSuccess)
|
||||||
printf("Error: SMCWriteKey() = %08x\n", result);
|
printf("Error: SMCPrintFans() = %08x\n", result);
|
||||||
}
|
break;
|
||||||
else
|
case OP_WRITE:
|
||||||
{
|
if (strlen(key) > 0)
|
||||||
printf("Error: specify a key to write\n");
|
{
|
||||||
}
|
sprintf(val.key, key);
|
||||||
break;
|
result = SMCWriteKey(val);
|
||||||
|
if (result != kIOReturnSuccess)
|
||||||
|
printf("Error: SMCWriteKey() = %08x\n", result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error: specify a key to write\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMCClose(conn);
|
smc_close();
|
||||||
return 0;;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif //#ifdef CMD_TOOL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
46
smc-command/smc.h
Normal file → Executable file
46
smc-command/smc.h
Normal file → Executable file
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Apple System Management Control (SMC) Tool
|
* Apple System Management Control (SMC) Tool
|
||||||
* Copyright (C) 2006 devnull
|
* Copyright (C) 2006 devnull
|
||||||
|
* Portions Copyright (C) 2013 Michael Wilber
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -38,11 +39,36 @@
|
|||||||
#define SMC_CMD_READ_PLIMIT 11
|
#define SMC_CMD_READ_PLIMIT 11
|
||||||
#define SMC_CMD_READ_VERS 12
|
#define SMC_CMD_READ_VERS 12
|
||||||
|
|
||||||
|
#define DATATYPE_FP1F "fp1f"
|
||||||
|
#define DATATYPE_FP4C "fp4c"
|
||||||
|
#define DATATYPE_FP5B "fp5b"
|
||||||
|
#define DATATYPE_FP6A "fp6a"
|
||||||
|
#define DATATYPE_FP79 "fp79"
|
||||||
|
#define DATATYPE_FP88 "fp88"
|
||||||
|
#define DATATYPE_FPA6 "fpa6"
|
||||||
|
#define DATATYPE_FPC4 "fpc4"
|
||||||
#define DATATYPE_FPE2 "fpe2"
|
#define DATATYPE_FPE2 "fpe2"
|
||||||
|
|
||||||
|
#define DATATYPE_SP1E "sp1e"
|
||||||
|
#define DATATYPE_SP3C "sp3c"
|
||||||
|
#define DATATYPE_SP4B "sp4b"
|
||||||
|
#define DATATYPE_SP5A "sp5a"
|
||||||
|
#define DATATYPE_SP69 "sp69"
|
||||||
|
#define DATATYPE_SP78 "sp78"
|
||||||
|
#define DATATYPE_SP87 "sp87"
|
||||||
|
#define DATATYPE_SP96 "sp96"
|
||||||
|
#define DATATYPE_SPB4 "spb4"
|
||||||
|
#define DATATYPE_SPF0 "spf0"
|
||||||
|
|
||||||
#define DATATYPE_UINT8 "ui8 "
|
#define DATATYPE_UINT8 "ui8 "
|
||||||
#define DATATYPE_UINT16 "ui16"
|
#define DATATYPE_UINT16 "ui16"
|
||||||
#define DATATYPE_UINT32 "ui32"
|
#define DATATYPE_UINT32 "ui32"
|
||||||
|
|
||||||
|
#define DATATYPE_SI8 "si8 "
|
||||||
|
#define DATATYPE_SI16 "si16"
|
||||||
|
|
||||||
|
#define DATATYPE_PWM "{pwm"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char major;
|
char major;
|
||||||
char minor;
|
char minor;
|
||||||
@ -65,7 +91,7 @@ typedef struct {
|
|||||||
char dataAttributes;
|
char dataAttributes;
|
||||||
} SMCKeyData_keyInfo_t;
|
} SMCKeyData_keyInfo_t;
|
||||||
|
|
||||||
typedef char SMCBytes_t[32];
|
typedef unsigned char SMCBytes_t[32];
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UInt32 key;
|
UInt32 key;
|
||||||
@ -89,13 +115,19 @@ typedef struct {
|
|||||||
} SMCVal_t;
|
} SMCVal_t;
|
||||||
|
|
||||||
UInt32 _strtoul(char *str, int size, int base);
|
UInt32 _strtoul(char *str, int size, int base);
|
||||||
kern_return_t SMCOpen(io_connect_t *conn);
|
float _strtof(unsigned char *str, int size, int e);
|
||||||
kern_return_t SMCReadKey(UInt32Char_t key, SMCVal_t *val);
|
|
||||||
kern_return_t SMCReadKey2(UInt32Char_t key, SMCVal_t *val,io_connect_t conn);
|
// Exclude command-line only code from smcFanControl UI
|
||||||
kern_return_t SMCWriteSimple(UInt32Char_t key,char *wvalue,io_connect_t conn);
|
#ifdef CMD_TOOL
|
||||||
kern_return_t SMCClose(io_connect_t conn);
|
|
||||||
void smc_init();
|
void smc_init();
|
||||||
void smc_close();
|
void smc_close();
|
||||||
|
kern_return_t SMCReadKey(UInt32Char_t key, SMCVal_t *val);
|
||||||
|
kern_return_t SMCWriteSimple(UInt32Char_t key,char *wvalue,io_connect_t conn);
|
||||||
|
|
||||||
float _strtof(char *str, int size, int e);
|
#endif //#ifdef CMD_TOOL
|
||||||
|
|
||||||
|
kern_return_t SMCOpen(io_connect_t *conn);
|
||||||
|
kern_return_t SMCClose(io_connect_t conn);
|
||||||
|
kern_return_t SMCReadKey2(UInt32Char_t key, SMCVal_t *val,io_connect_t conn);
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,6 @@
|
|||||||
89949E8D0AEEA37700077E93 /* Power.m in Sources */ = {isa = PBXBuildFile; fileRef = 89949E8C0AEEA37700077E93 /* Power.m */; };
|
89949E8D0AEEA37700077E93 /* Power.m in Sources */ = {isa = PBXBuildFile; fileRef = 89949E8C0AEEA37700077E93 /* Power.m */; };
|
||||||
899D59DC15E1CF60003E322D /* smc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8924ECEE15AC96E70031730C /* smc */; };
|
899D59DC15E1CF60003E322D /* smc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8924ECEE15AC96E70031730C /* smc */; };
|
||||||
899D59DD15E1CFFF003E322D /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 895BDA390B8F8F42003CD894 /* Sparkle.framework */; };
|
899D59DD15E1CFFF003E322D /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 895BDA390B8F8F42003CD894 /* Sparkle.framework */; };
|
||||||
899D59E315E228DF003E322D /* tsensors.plist in Resources */ = {isa = PBXBuildFile; fileRef = 899D59E215E228DF003E322D /* tsensors.plist */; };
|
|
||||||
89B243200B7E351000CAD103 /* smcfancontrol_v2.icns in Resources */ = {isa = PBXBuildFile; fileRef = 89B2431F0B7E351000CAD103 /* smcfancontrol_v2.icns */; };
|
89B243200B7E351000CAD103 /* smcfancontrol_v2.icns in Resources */ = {isa = PBXBuildFile; fileRef = 89B2431F0B7E351000CAD103 /* smcfancontrol_v2.icns */; };
|
||||||
89C053BE0ADAB7630037CA16 /* smc.c in Sources */ = {isa = PBXBuildFile; fileRef = 89C053BC0ADAB7630037CA16 /* smc.c */; };
|
89C053BE0ADAB7630037CA16 /* smc.c in Sources */ = {isa = PBXBuildFile; fileRef = 89C053BC0ADAB7630037CA16 /* smc.c */; };
|
||||||
89E7D3650ADE819B000F67AB /* Machines.plist in Resources */ = {isa = PBXBuildFile; fileRef = 89E7D3640ADE819B000F67AB /* Machines.plist */; };
|
89E7D3650ADE819B000F67AB /* Machines.plist in Resources */ = {isa = PBXBuildFile; fileRef = 89E7D3640ADE819B000F67AB /* Machines.plist */; };
|
||||||
@ -110,7 +109,6 @@
|
|||||||
8987FBD00B878B3900A5ED8E /* smc.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = smc.png; sourceTree = "<group>"; };
|
8987FBD00B878B3900A5ED8E /* smc.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = smc.png; sourceTree = "<group>"; };
|
||||||
89949E8B0AEEA37700077E93 /* Power.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Power.h; sourceTree = "<group>"; };
|
89949E8B0AEEA37700077E93 /* Power.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Power.h; sourceTree = "<group>"; };
|
||||||
89949E8C0AEEA37700077E93 /* Power.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Power.m; sourceTree = "<group>"; };
|
89949E8C0AEEA37700077E93 /* Power.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Power.m; sourceTree = "<group>"; };
|
||||||
899D59E215E228DF003E322D /* tsensors.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = tsensors.plist; sourceTree = "<group>"; };
|
|
||||||
89B2431F0B7E351000CAD103 /* smcfancontrol_v2.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = smcfancontrol_v2.icns; sourceTree = "<group>"; };
|
89B2431F0B7E351000CAD103 /* smcfancontrol_v2.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = smcfancontrol_v2.icns; sourceTree = "<group>"; };
|
||||||
89C053BC0ADAB7630037CA16 /* smc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = smc.c; sourceTree = "<group>"; };
|
89C053BC0ADAB7630037CA16 /* smc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = smc.c; sourceTree = "<group>"; };
|
||||||
89C053BD0ADAB7630037CA16 /* smc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = smc.h; sourceTree = "<group>"; };
|
89C053BD0ADAB7630037CA16 /* smc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = smc.h; sourceTree = "<group>"; };
|
||||||
@ -231,7 +229,6 @@
|
|||||||
89B2431F0B7E351000CAD103 /* smcfancontrol_v2.icns */,
|
89B2431F0B7E351000CAD103 /* smcfancontrol_v2.icns */,
|
||||||
8917FB850ADEECAD00443DA1 /* paypal.gif */,
|
8917FB850ADEECAD00443DA1 /* paypal.gif */,
|
||||||
89E7D3640ADE819B000F67AB /* Machines.plist */,
|
89E7D3640ADE819B000F67AB /* Machines.plist */,
|
||||||
899D59E215E228DF003E322D /* tsensors.plist */,
|
|
||||||
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
|
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
|
||||||
893506170B440255001BFBA5 /* Localizable.strings */,
|
893506170B440255001BFBA5 /* Localizable.strings */,
|
||||||
89FE24050B7F4C2B00D2713C /* paypal.gif */,
|
89FE24050B7F4C2B00D2713C /* paypal.gif */,
|
||||||
@ -344,7 +341,6 @@
|
|||||||
89033CA70B80E1EB00FDAF43 /* F.A.Q.rtf in Resources */,
|
89033CA70B80E1EB00FDAF43 /* F.A.Q.rtf in Resources */,
|
||||||
8987FBD20B878B3900A5ED8E /* smc.png in Resources */,
|
8987FBD20B878B3900A5ED8E /* smc.png in Resources */,
|
||||||
89559A840BAC338500DBA37E /* smcover.png in Resources */,
|
89559A840BAC338500DBA37E /* smcover.png in Resources */,
|
||||||
899D59E315E228DF003E322D /* tsensors.plist in Resources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -438,7 +434,7 @@
|
|||||||
GCC_OPTIMIZATION_LEVEL = 0;
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = CMD_TOOL;
|
GCC_PREPROCESSOR_DEFINITIONS = CMD_TOOL;
|
||||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||||
GCC_VERSION = com.apple.compilers.llvmgcc42;
|
GCC_VERSION = "";
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
|
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||||
@ -446,7 +442,7 @@
|
|||||||
ONLY_ACTIVE_ARCH = NO;
|
ONLY_ACTIVE_ARCH = NO;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
SDKROOT = macosx10.7;
|
SDKROOT = macosx10.9;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
@ -463,14 +459,14 @@
|
|||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = CMD_TOOL;
|
GCC_PREPROCESSOR_DEFINITIONS = CMD_TOOL;
|
||||||
GCC_VERSION = com.apple.compilers.llvmgcc42;
|
GCC_VERSION = "";
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
|
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
MACOSX_DEPLOYMENT_TARGET = 10.5;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
SDKROOT = macosx10.7;
|
SDKROOT = macosx10.9;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
@ -489,7 +485,7 @@
|
|||||||
GCC_MODEL_PPC64 = NO;
|
GCC_MODEL_PPC64 = NO;
|
||||||
GCC_MODEL_TUNING = "";
|
GCC_MODEL_TUNING = "";
|
||||||
GCC_OPTIMIZATION_LEVEL = 0;
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
GCC_VERSION = com.apple.compilers.llvmgcc42;
|
GCC_VERSION = "";
|
||||||
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
||||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
|
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
@ -502,7 +498,7 @@
|
|||||||
ONLY_ACTIVE_ARCH = NO;
|
ONLY_ACTIVE_ARCH = NO;
|
||||||
PRODUCT_NAME = smcFanControl;
|
PRODUCT_NAME = smcFanControl;
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
SDKROOT = macosx10.7;
|
SDKROOT = macosx10.9;
|
||||||
WRAPPER_EXTENSION = app;
|
WRAPPER_EXTENSION = app;
|
||||||
ZERO_LINK = YES;
|
ZERO_LINK = YES;
|
||||||
};
|
};
|
||||||
@ -522,7 +518,7 @@
|
|||||||
FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)\"";
|
FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)\"";
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_MODEL_TUNING = "";
|
GCC_MODEL_TUNING = "";
|
||||||
GCC_VERSION = com.apple.compilers.llvmgcc42;
|
GCC_VERSION = "";
|
||||||
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
|
||||||
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
|
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
@ -535,7 +531,7 @@
|
|||||||
ONLY_ACTIVE_ARCH = NO;
|
ONLY_ACTIVE_ARCH = NO;
|
||||||
PRODUCT_NAME = smcFanControl;
|
PRODUCT_NAME = smcFanControl;
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
SDKROOT = macosx10.7;
|
SDKROOT = macosx10.9;
|
||||||
VALID_ARCHS = "i386 x86_64";
|
VALID_ARCHS = "i386 x86_64";
|
||||||
WRAPPER_EXTENSION = app;
|
WRAPPER_EXTENSION = app;
|
||||||
};
|
};
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user