#include <sys/cdefs.h>
#include <mach/mach.h>
#include <IOKit/iokitmig.h> // mig generated
#include <mach/mach_init.h>
#include <IOKit/pwr_mgt/IOPM.h>
#include "IOPMLib.h"
io_connect_t IOPMFindPowerManagement( mach_port_t master_device_port )
{
io_connect_t fb;
kern_return_t kr;
io_service_t obj = MACH_PORT_NULL;
obj = IORegistryEntryFromPath( master_device_port, kIOPowerPlane ":/IOPowerConnection/IOPMrootDomain");
if( obj ) {
kr = IOServiceOpen( obj,mach_task_self(), 0, &fb);
if ( kr == kIOReturnSuccess ) {
IOObjectRelease(obj);
return fb;
}
IOObjectRelease(obj);
}
return 0;
}
IOReturn IOPMGetAggressiveness ( io_connect_t fb, unsigned long type, unsigned long * aggressiveness )
{
mach_msg_type_number_t len = 1;
kern_return_t err;
int param = type;
err = io_connect_method_scalarI_scalarO( (io_connect_t) fb, kPMGetAggressiveness, ¶m, 1, (int *)aggressiveness, &len);
if (err==KERN_SUCCESS)
return kIOReturnSuccess;
else
return kIOReturnError;
}
IOReturn IOPMSetAggressiveness ( io_connect_t fb, unsigned long type, unsigned long aggressiveness )
{
mach_msg_type_number_t len = 1;
kern_return_t err;
int params[2];
int ret_val = kIOReturnSuccess;
params[0] = (int)type;
params[1] = (int)aggressiveness;
err = io_connect_method_scalarI_scalarO( (io_connect_t) fb, kPMSetAggressiveness, params, 2, &ret_val, &len);
if (err==KERN_SUCCESS)
return ret_val;
else
return kIOReturnError;
}
IOReturn IOPMSleepSystem ( io_connect_t fb )
{
mach_msg_type_number_t len = 1;
kern_return_t err;
int ret_val = kIOReturnSuccess;
err = io_connect_method_scalarI_scalarO( (io_connect_t) fb, kPMSleepSystem, NULL, 0, &ret_val, &len);
if (err==KERN_SUCCESS)
return ret_val;
else
return kIOReturnError;
}
IOReturn IOPMCopyBatteryInfo( mach_port_t masterPort, CFArrayRef * oInfo )
{
io_registry_entry_t root_domain;
IOReturn kr = kIOReturnUnsupported;
*oInfo = NULL;
root_domain = IORegistryEntryFromPath( masterPort,
kIOPowerPlane ":/IOPowerConnection/IOPMrootDomain");
if(!root_domain) return kIOReturnUnsupported;
*oInfo = IORegistryEntryCreateCFProperty( root_domain, CFSTR(kIOBatteryInfoKey),
kCFAllocatorDefault, kNilOptions);
IOObjectRelease(root_domain);
if(*oInfo) {
return kIOReturnSuccess;
}
int batt_count = 0;
io_registry_entry_t battery;
io_iterator_t ioreg_batteries;
CFMutableArrayRef legacyArray = CFArrayCreateMutable(
kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
if(!legacyArray) return kIOReturnNoMemory;
kr = IOServiceGetMatchingServices(
MACH_PORT_NULL,
IOServiceMatching("IOPMPowerSource"),
&ioreg_batteries);
if(KERN_SUCCESS != kr) {
CFRelease(legacyArray);
return kIOReturnError;
}
while( battery = (io_registry_entry_t)IOIteratorNext(ioreg_batteries) )
{
CFDictionaryRef legacyDict;
legacyDict = IORegistryEntryCreateCFProperty( battery,
CFSTR(kIOPMPSLegacyBatteryInfoKey),
kCFAllocatorDefault,
0);
if(!legacyDict) continue;
batt_count++;
CFArrayAppendValue(legacyArray, legacyDict);
CFRelease(legacyDict);
IOObjectRelease(battery);
}
IOObjectRelease(ioreg_batteries);
if(batt_count > 0) {
*oInfo = legacyArray;
} else {
CFRelease(legacyArray);
return kIOReturnUnsupported;
}
return kIOReturnSuccess;
}
io_connect_t IORegisterApp( void * refcon,
io_service_t theDriver,
IONotificationPortRef * thePortRef,
IOServiceInterestCallback callback,
io_object_t * notifier )
{
io_connect_t fb = MACH_PORT_NULL;
kern_return_t kr;
*notifier = MACH_PORT_NULL;
if ( theDriver != MACH_PORT_NULL ) {
kr = IOServiceOpen(theDriver,mach_task_self(), 0, &fb);
if ( kr == kIOReturnSuccess ) {
if ( fb != MACH_PORT_NULL ) {
kr = IOServiceAddInterestNotification(*thePortRef,theDriver,kIOAppPowerStateInterest,
callback,refcon,notifier);
if ( kr == KERN_SUCCESS ) {
return fb;
}
}
}
}
if ( fb != MACH_PORT_NULL ) {
IOServiceClose(fb);
}
if ( *notifier != MACH_PORT_NULL ) {
IOObjectRelease(*notifier);
}
return MACH_PORT_NULL;
}
io_connect_t IORegisterForSystemPower ( void * refcon,
IONotificationPortRef * thePortRef,
IOServiceInterestCallback callback,
io_object_t * root_notifier )
{
mach_port_t master_device_port;
io_connect_t fb = MACH_PORT_NULL;
IONotificationPortRef notify = NULL;
kern_return_t kr;
io_service_t obj = MACH_PORT_NULL;
*root_notifier = MACH_PORT_NULL;
IOMasterPort(bootstrap_port,&master_device_port);
notify = IONotificationPortCreate( master_device_port );
obj = IORegistryEntryFromPath( master_device_port, kIOPowerPlane ":/IOPowerConnection/IOPMrootDomain");
if( obj != MACH_PORT_NULL ) {
kr = IOServiceOpen( obj,mach_task_self(), 0, &fb);
if ( kr == kIOReturnSuccess ) {
if ( fb != MACH_PORT_NULL ) {
kr = IOServiceAddInterestNotification(notify,obj,kIOAppPowerStateInterest,
callback,refcon,root_notifier);
IOObjectRelease(obj);
if ( kr == KERN_SUCCESS ) {
*thePortRef = notify;
return fb;
}
}
}
}
if ( obj != MACH_PORT_NULL ) {
IOObjectRelease(obj);
}
if ( notify != MACH_PORT_NULL ) {
IONotificationPortDestroy(notify);
}
if ( fb != MACH_PORT_NULL ) {
IOServiceClose(fb);
}
if ( *root_notifier != MACH_PORT_NULL ) {
IOObjectRelease(*root_notifier);
}
return MACH_PORT_NULL;
}
IOReturn IODeregisterApp ( io_object_t * notifier )
{
if ( *notifier ) {
IOObjectRelease(*notifier);
*notifier = MACH_PORT_NULL;
}
return kIOReturnSuccess;
}
IOReturn IODeregisterForSystemPower ( io_object_t * root_notifier )
{
if ( *root_notifier ) {
IOObjectRelease(*root_notifier);
*root_notifier = MACH_PORT_NULL;
}
return kIOReturnSuccess;
}
IOReturn IOAllowPowerChange ( io_connect_t kernelPort, long notificationID )
{
kern_return_t err;
mach_msg_type_number_t len = 0;
err = io_connect_method_scalarI_scalarO( kernelPort, kPMAllowPowerChange, (int *)¬ificationID, 1, NULL, &len);
if (err==KERN_SUCCESS)
return kIOReturnSuccess;
else
return kIOReturnError;
}
IOReturn IOCancelPowerChange ( io_connect_t kernelPort, long notificationID )
{
kern_return_t err;
mach_msg_type_number_t len = 0;
err = io_connect_method_scalarI_scalarO( kernelPort, kPMCancelPowerChange, (int *)¬ificationID, 1, NULL, &len);
if (err==KERN_SUCCESS)
return kIOReturnSuccess;
else
return kIOReturnError;
}
boolean_t IOPMSleepEnabled ( void ) {
mach_port_t masterPort;
io_registry_entry_t root;
kern_return_t kr;
boolean_t flag = false;
kr = IOMasterPort(bootstrap_port,&masterPort);
if ( kIOReturnSuccess == kr ) {
root = IORegistryEntryFromPath(masterPort,kIOPowerPlane ":/IOPowerConnection/IOPMrootDomain");
if ( root ) {
CFTypeRef data;
data = IORegistryEntryCreateCFProperty(root,CFSTR("IOSleepSupported"),kCFAllocatorDefault,kNilOptions);
if ( data ) {
flag = true;
CFRelease(data);
}
IOObjectRelease(root);
}
}
return flag;
}