static double getBatData() { CFTypeRef sourceInfo = IOPSCopyPowerSourcesInfo(); CFArrayRef sourceList = IOPSCopyPowerSourcesList(sourceInfo); // Loop through sources, find the first battery int count = CFArrayGetCount(sourceList); CFDictionaryRef source = NULL; for(int i=0; i < count; i++) { source = IOPSGetPowerSourceDescription(sourceInfo, CFArrayGetValueAtIndex(sourceList, i)); // Is this a battery? CFStringRef type = (CFStringRef)CFDictionaryGetValue(source, CFSTR(kIOPSTransportTypeKey)); if(kCFCompareEqualTo == CFStringCompare(type, CFSTR(kIOPSInternalType), 0)) { break; } } float percent = 0; if(source != NULL) { int curCapacity; CFNumberGetValue(CFDictionaryGetValue(source, CFSTR(kIOPSCurrentCapacityKey)), kCFNumberIntType, &curCapacity); int maxCapacity; CFNumberGetValue(CFDictionaryGetValue(source, CFSTR(kIOPSMaxCapacityKey)), kCFNumberIntType, &maxCapacity); percent = curCapacity / (float)maxCapacity*100.f; } CFRelease(sourceInfo); CFRelease(sourceList); return percent; }
static ACPresence chkIsOnline() { CFTypeRef sourceInfo = IOPSCopyPowerSourcesInfo(); CFArrayRef sourceList = IOPSCopyPowerSourcesList(sourceInfo); // Loop through sources, find the first battery int count = CFArrayGetCount(sourceList); CFDictionaryRef source = NULL; for(int i=0; i < count; i++) { source = IOPSGetPowerSourceDescription(sourceInfo, CFArrayGetValueAtIndex(sourceList, i)); // Is this a battery? CFStringRef type = (CFStringRef)CFDictionaryGetValue(source, CFSTR(kIOPSTransportTypeKey)); if(kCFCompareEqualTo == CFStringCompare(type, CFSTR(kIOPSInternalType), 0)) { break; } } ACPresence isOn = AC_ERROR; if(source != NULL) { CFStringRef state = CFDictionaryGetValue(source, CFSTR(kIOPSPowerSourceStateKey)); if(kCFCompareEqualTo == CFStringCompare(state, CFSTR(kIOPSACPowerValue), 0)) { isOn = AC_PRESENT; } else { isOn = AC_ABSENT; } } CFRelease(sourceInfo); CFRelease(sourceList); return isOn; }
int getPowerSource (void) // returns one of the three #defines above { int result = POWER_SOURCE_ERROR; CFTypeRef info = NULL; CFArrayRef powerSources = NULL; CFTypeRef source = NULL; CFDictionaryRef description = NULL; CFStringRef powerSourceState = NULL; info = IOPSCopyPowerSourcesInfo(); if (! info) goto ret; powerSources = IOPSCopyPowerSourcesList(info); if (! powerSources) goto ret; if (CFArrayGetCount(powerSources) == 0) goto ret; source = CFArrayGetValueAtIndex(powerSources, 0); if (! source) goto ret; description = IOPSGetPowerSourceDescription(info, source); if (! description) goto ret; powerSourceState = CFDictionaryGetValue(description, CFSTR(kIOPSPowerSourceStateKey)); if (! powerSourceState) goto ret; result = (CFStringCompare(powerSourceState, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo) ? POWER_SOURCE_AC : POWER_SOURCE_BATTERY; ret : if (info) CFRelease (info); if (powerSources) CFRelease (powerSources); //if (source) CFRelease (source); //if (description) CFRelease (description); //if (powerSourceState) CFRelease (powerSourceState); return result; }
static void get_via_io_power_sources(double *ret_charge, /* {{{ */ double *ret_current, double *ret_voltage) { CFTypeRef ps_raw; CFArrayRef ps_array; int ps_array_len; CFDictionaryRef ps_dict; CFTypeRef ps_obj; double temp_double; ps_raw = IOPSCopyPowerSourcesInfo(); ps_array = IOPSCopyPowerSourcesList(ps_raw); ps_array_len = CFArrayGetCount(ps_array); DEBUG("ps_array_len == %i", ps_array_len); for (int i = 0; i < ps_array_len; i++) { ps_obj = CFArrayGetValueAtIndex(ps_array, i); ps_dict = IOPSGetPowerSourceDescription(ps_raw, ps_obj); if (ps_dict == NULL) { DEBUG("IOPSGetPowerSourceDescription failed."); continue; } if (CFGetTypeID(ps_dict) != CFDictionaryGetTypeID()) { DEBUG("IOPSGetPowerSourceDescription did not return a CFDictionaryRef"); continue; } /* FIXME: Check if this is really an internal battery */ if (isnan(*ret_charge)) { /* This is the charge in percent. */ temp_double = dict_get_double(ps_dict, kIOPSCurrentCapacityKey); if (!isnan((temp_double)) && (temp_double >= 0.0) && (temp_double <= 100.0)) *ret_charge = temp_double; } if (isnan(*ret_current)) { temp_double = dict_get_double(ps_dict, kIOPSCurrentKey); if (!isnan(temp_double)) *ret_current = temp_double / 1000.0; } if (isnan(*ret_voltage)) { temp_double = dict_get_double(ps_dict, kIOPSVoltageKey); if (!isnan(temp_double)) *ret_voltage = temp_double / 1000.0; } } CFRelease(ps_array); CFRelease(ps_raw); } /* }}} void get_via_io_power_sources */
void CCocoaPowerSyscall::OSPowerSourceCallBack(void *refcon) { #if !defined(TARGET_DARWIN_IOS) // Called whenever any power source is added, removed, or changes. // When on battery, we get called periodically as battery level changes. CCocoaAutoPool autopool; CCocoaPowerSyscall *ctx = (CCocoaPowerSyscall*)refcon; CFTypeRef power_sources_info = IOPSCopyPowerSourcesInfo(); CFArrayRef power_sources_list = IOPSCopyPowerSourcesList(power_sources_info); for (int i = 0; i < CFArrayGetCount(power_sources_list); i++) { CFTypeRef power_source; CFDictionaryRef description; power_source = CFArrayGetValueAtIndex(power_sources_list, i); description = IOPSGetPowerSourceDescription(power_sources_info, power_source); // skip power sources that are not present (i.e. an absent second battery in a 2-battery machine) if ((CFBooleanRef)CFDictionaryGetValue(description, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse) continue; if (stringsAreEqual((CFStringRef)CFDictionaryGetValue(description, CFSTR (kIOPSTransportTypeKey)), CFSTR (kIOPSInternalType))) { CFStringRef currentState = (CFStringRef)CFDictionaryGetValue(description, CFSTR (kIOPSPowerSourceStateKey)); if (stringsAreEqual (currentState, CFSTR (kIOPSACPowerValue))) { ctx->m_OnBattery = false; ctx->m_BatteryPercent = 100; ctx->m_SentBatteryMessage = false; } else if (stringsAreEqual (currentState, CFSTR (kIOPSBatteryPowerValue))) { CFNumberRef cf_number_ref; int32_t curCapacity, maxCapacity; cf_number_ref = (CFNumberRef)CFDictionaryGetValue(description, CFSTR(kIOPSCurrentCapacityKey)); CFNumberGetValue(cf_number_ref, kCFNumberSInt32Type, &curCapacity); cf_number_ref = (CFNumberRef)CFDictionaryGetValue(description, CFSTR(kIOPSMaxCapacityKey)); CFNumberGetValue(cf_number_ref, kCFNumberSInt32Type, &maxCapacity); ctx->m_OnBattery = true; ctx->m_BatteryPercent = (int)((double)curCapacity/(double)maxCapacity * 100); } } } CFRelease(power_sources_list); CFRelease(power_sources_info); #endif }
SDL_bool SDL_GetPowerInfo_MacOSX(SDL_PowerState * state, int *seconds, int *percent) { CFTypeRef blob = IOPSCopyPowerSourcesInfo(); *seconds = -1; *percent = -1; *state = SDL_POWERSTATE_UNKNOWN; if (blob != NULL) { CFArrayRef list = IOPSCopyPowerSourcesList(blob); if (list != NULL) { /* don't CFRelease() the list items, or dictionaries! */ SDL_bool have_ac = SDL_FALSE; SDL_bool have_battery = SDL_FALSE; SDL_bool charging = SDL_FALSE; const CFIndex total = CFArrayGetCount(list); CFIndex i; for (i = 0; i < total; i++) { CFTypeRef ps = (CFTypeRef) CFArrayGetValueAtIndex(list, i); CFDictionaryRef dict = IOPSGetPowerSourceDescription(blob, ps); if (dict != NULL) { checkps(dict, &have_ac, &have_battery, &charging, seconds, percent); } } if (!have_battery) { *state = SDL_POWERSTATE_NO_BATTERY; } else if (charging) { *state = SDL_POWERSTATE_CHARGING; } else if (have_ac) { *state = SDL_POWERSTATE_CHARGED; } else { *state = SDL_POWERSTATE_ON_BATTERY; } CFRelease(list); } CFRelease(blob); } return SDL_TRUE; /* always the definitive answer on Mac OS X. */ }
// CODE CHUNK IMPORTED FROM SDL 2.0 bool power_osx::GetPowerInfo_MacOSX() { CFTypeRef blob = IOPSCopyPowerSourcesInfo(); nsecs_left = -1; percent_left = -1; power_state = OS::POWERSTATE_UNKNOWN; if (blob != NULL) { CFArrayRef list = IOPSCopyPowerSourcesList(blob); if (list != NULL) { /* don't CFRelease() the list items, or dictionaries! */ bool have_ac = false; bool have_battery = false; bool charging = false; const CFIndex total = CFArrayGetCount(list); CFIndex i; for (i = 0; i < total; i++) { CFTypeRef ps = (CFTypeRef)CFArrayGetValueAtIndex(list, i); CFDictionaryRef dict = IOPSGetPowerSourceDescription(blob, ps); if (dict != NULL) { checkps(dict, &have_ac, &have_battery, &charging); } } if (!have_battery) { power_state = OS::POWERSTATE_NO_BATTERY; } else if (charging) { power_state = OS::POWERSTATE_CHARGING; } else if (have_ac) { power_state = OS::POWERSTATE_CHARGED; } else { power_state = OS::POWERSTATE_ON_BATTERY; } CFRelease(list); } CFRelease(blob); } return true; /* always the definitive answer on Mac OS X. */ }
/* IOPSCopyUPSArray * * Argument: * CFTypeRef power_sources: The return value from IOPSCoyPowerSourcesInfo() * Return value: * CFArrayRef: all the UPS's we found * NULL if none are found */ CFArrayRef IOPSCopyUPSArray(CFTypeRef power_sources) { CFArrayRef array = isA_CFArray(IOPSCopyPowerSourcesList(power_sources)); CFMutableArrayRef ret_arr; CFTypeRef name = NULL; CFDictionaryRef ps; CFStringRef transport_type; int i, count; if(!array) return NULL; count = CFArrayGetCount(array); name = NULL; ret_arr = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); if(!ret_arr) goto exit; // Iterate through power_sources for(i=0; i<count; i++) { name = CFArrayGetValueAtIndex(array, i); ps = isA_CFDictionary(IOPSGetPowerSourceDescription(power_sources, name)); if(ps) { transport_type = isA_CFString(CFDictionaryGetValue(ps, CFSTR(kIOPSTransportTypeKey))); if(transport_type && ( CFEqual(transport_type, CFSTR(kIOPSSerialTransportType)) || CFEqual(transport_type, CFSTR(kIOPSUSBTransportType)) || CFEqual(transport_type, CFSTR(kIOPSNetworkTransportType)) ) ) { CFArrayAppendValue(ret_arr, name); } } } if(0 == CFArrayGetCount(ret_arr)) { CFRelease(ret_arr); ret_arr = NULL; } exit: CFRelease(array); return ret_arr; }
bool CScreensaver::Host_is_running_on_batteries() { CFDictionaryRef pSource = NULL; CFStringRef psState; int i; bool retval = false; CFTypeRef blob = IOPSCopyPowerSourcesInfo(); CFArrayRef list = IOPSCopyPowerSourcesList(blob); for (i=0; i<CFArrayGetCount(list); i++) { pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(list, i)); if(!pSource) break; psState = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSPowerSourceStateKey)); if(!CFStringCompare(psState,CFSTR(kIOPSBatteryPowerValue),0)) retval = true; } CFRelease(blob); CFRelease(list); return retval; }
void HostPowerServiceDarwin::checkBatteryCriticalLevel(bool *pfCriticalChanged) { CFTypeRef pBlob = IOPSCopyPowerSourcesInfo(); CFArrayRef pSources = IOPSCopyPowerSourcesList(pBlob); CFDictionaryRef pSource = NULL; const void *psValue; bool result; int powerSource = POWER_SOURCE_OUTLET; bool critical = false; if (CFArrayGetCount(pSources) > 0) { for (int i = 0; i < CFArrayGetCount(pSources); ++i) { pSource = IOPSGetPowerSourceDescription(pBlob, CFArrayGetValueAtIndex(pSources, i)); /* If the source is empty skip over to the next one. */ if (!pSource) continue; /* Skip all power sources which are currently not present like a * second battery. */ if (CFDictionaryGetValue(pSource, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse) continue; /* Only internal power types are of interest. */ result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTransportTypeKey), &psValue); if (result && CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo) { /* First check which power source we are connect on. */ result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue); if (result && CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo) powerSource = POWER_SOURCE_OUTLET; else if (result && CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) powerSource = POWER_SOURCE_BATTERY; int curCapacity = 0; int maxCapacity = 1; float remCapacity = 0.0f; /* Fetch the current capacity value of the power source */ result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSCurrentCapacityKey), &psValue); if (result) CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity); /* Fetch the maximum capacity value of the power source */ result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSMaxCapacityKey), &psValue); if (result) CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity); /* Calculate the remaining capacity in percent */ remCapacity = ((float)curCapacity/(float)maxCapacity * 100.0); /* Check for critical. 5 percent is default. */ int criticalValue = 5; result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSDeadWarnLevelKey), &psValue); if (result) CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &criticalValue); critical = (remCapacity < criticalValue); /* We have to take action only if we are on battery, the * previous state wasn't critical, the state has changed & the * user requested that info. */ if (powerSource == POWER_SOURCE_BATTERY && mCritical == false && mCritical != critical && pfCriticalChanged) *pfCriticalChanged = true; Log(("checkBatteryCriticalLevel: Remains: %d.%d%% Critical: %d Critical State Changed: %d\n", (int)remCapacity, (int)(remCapacity * 10) % 10, critical, pfCriticalChanged?*pfCriticalChanged:-1)); } } } /* Save the new state */ mCritical = critical; CFRelease(pBlob); CFRelease(pSources); }
int machine_get_battstat(int *acstat, int *battflag, int *percent) { CFTypeRef blob = IOPSCopyPowerSourcesInfo(); CFArrayRef sources = IOPSCopyPowerSourcesList(blob); int i; CFDictionaryRef pSource = NULL; const void *psValue; *acstat = LCDP_AC_ON; *battflag = LCDP_BATT_ABSENT; *percent = 100; if (CFArrayGetCount(sources) == 0) return (FALSE); for (i = 0; i < CFArrayGetCount(sources); i++) { pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i)); if (!pSource) break; psValue = (CFStringRef) CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey)); if (CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsPresentKey), &psValue) && (CFBooleanGetValue(psValue) > 0)) { psValue = (CFStringRef) CFDictionaryGetValue(pSource, CFSTR(kIOPSPowerSourceStateKey)); if (CFStringCompare(psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) { /* We are running on a battery power source. */ *battflag = LCDP_BATT_UNKNOWN; *acstat = LCDP_AC_OFF; } else if (CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsChargingKey), &psValue)) { /* * We are running on an AC power source, but * we also have a battery power source * present. */ if (CFBooleanGetValue(psValue) > 0) *battflag = LCDP_BATT_CHARGING; else *battflag = LCDP_BATT_UNKNOWN; } if (*battflag != LCDP_BATT_ABSENT) { int curCapacity = 0; int maxCapacity = 0; psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSCurrentCapacityKey)); CFNumberGetValue(psValue, kCFNumberSInt32Type, &curCapacity); psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSMaxCapacityKey)); CFNumberGetValue(psValue, kCFNumberSInt32Type, &maxCapacity); *percent = (int)((double)curCapacity / (double)maxCapacity * 100); /* * There is a way to check this through the * IOKit, but I am not sure what gets * returned for kIOPSLowWarnLevelKey and * kIOPSDeadWarnLevelKey, and this is easier. */ if (*battflag == LCDP_BATT_UNKNOWN) { if (*percent > 50) *battflag = LCDP_BATT_HIGH; else if (*percent > 2) *battflag = LCDP_BATT_LOW; else *battflag = LCDP_BATT_CRITICAL; } /* printf ("powerSource %d of %d: percent: %d/%d %d\n", i, CFArrayGetCount(sources), curCapacity, maxCapacity, *percent);*/ } } } CFRelease(blob); CFRelease(sources); return (TRUE); }
void upsdrv_initups(void) { CFArrayRef power_source_key_list; CFIndex num_keys, index; CFDictionaryRef power_dictionary; CFTypeRef power_blob; CFStringRef potential_key, potential_model; char *device_name = device_path, *model_name; /* regex(3) */ char potential_device_name[80], potential_model_name[80]; regex_t name_regex, model_regex; int ret; upsdebugx(3, "upsdrv_initups(): Power Sources blob:"); /* upsfd = ser_open(device_path); */ /* ser_set_speed(upsfd, device_path, B1200); */ power_blob = IOPSCopyPowerSourcesInfo(); if(!power_blob) { fatalx(EXIT_FAILURE, "Couldn't retrieve Power Sources blob"); } if(nut_debug_level >= 3) CFShow(power_blob); if(!strcmp(device_name, "auto")) { device_name = "/UPS"; } upsdebugx(2, "Matching power supply key names against regex '%s'", device_name); ret = regcomp(&name_regex, device_name, REG_EXTENDED|REG_NOSUB|REG_ICASE); if(ret) { fatalx(EXIT_FAILURE, "Failed to compile regex from 'port' parameter: '%s'.", device_name); } if((model_name = getval("model"))) { upsdebugx(2, "Matching power supply model names against regex '%s'", model_name); ret = regcomp(&model_regex, model_name, REG_EXTENDED|REG_NOSUB|REG_ICASE); if(ret) { fatalx(EXIT_FAILURE, "Failed to compile regex from 'model' parameter: '%s'.", model_name); } } power_source_key_list = IOPSCopyPowerSourcesList(power_blob); num_keys = CFArrayGetCount(power_source_key_list); upsdebugx(1, "Number of power supplies found: %d", (int)num_keys); if(nut_debug_level >= 3) CFShow(power_source_key_list); if(num_keys < 1) { /* bail */ fatalx(EXIT_FAILURE, "Couldn't find any UPS or battery"); } for(index=0; index < num_keys; index++) { potential_key = CFArrayGetValueAtIndex(power_source_key_list, index); CFStringGetCString(potential_key, potential_device_name, sizeof(potential_device_name), kCFStringEncodingUTF8); upsdebugx(1, " Power supply: %s", potential_device_name); ret = regexec(&name_regex, potential_device_name, 0,0,0); power_dictionary = copy_power_dictionary(potential_key); upsdebugx(2, "Getting 'Name' key (UPS model)"); potential_model = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSNameKey)); CFStringGetCString(potential_model, potential_model_name, sizeof(potential_model_name), kCFStringEncodingUTF8); upsdebugx(1, " model name: %s", potential_model_name); CFRelease(power_dictionary); /* Does key match? Check model: */ if (!ret) { if(model_name) { ret = regexec(&model_regex, potential_model_name, 0,0,0); if(!ret) { upsdebugx(2, "Matched model name"); break; } } else { upsdebugx(2, "Matched key name"); break; } } } regfree(&name_regex); if(model_name) { regfree(&model_regex); } if(ret) { fatalx(EXIT_FAILURE, "Couldn't find UPS or battery matching both 'port' (%s) and 'model' (%s)", device_name, model_name); } g_power_key = potential_key; CFRetain(g_power_key); upsdebugx(2, "g_power_key = "); if(nut_debug_level >= 2) CFShow(g_power_key); upsdebugx(2, "end g_power_key."); power_dictionary = copy_power_dictionary(g_power_key); assert(power_dictionary); if(nut_debug_level >= 3) CFShow(power_dictionary); /* the upsh handlers can't be done here, as they get initialized * shortly after upsdrv_initups returns to main. */ /* don't try to detect the UPS here */ /* do stuff */ CFRelease(power_dictionary); }
static void darwin_check(void) { const void *values; int device_num, device_count; int currentval = 0, maxval = 0; char buf[4096]; CFTypeRef blob; CFArrayRef sources; CFDictionaryRef device_dict; time_left = -1; battery_full = -1; have_battery = 0; have_power = 0; /* Retrieve the power source data and the array of sources. */ blob = IOPSCopyPowerSourcesInfo(); sources = IOPSCopyPowerSourcesList(blob); device_count = CFArrayGetCount(sources); for (device_num = 0; device_num < device_count; device_num++) { CFTypeRef ps; /* Retrieve a dictionary of values for this device and the count of keys in the dictionary. */ ps = CFArrayGetValueAtIndex(sources, device_num); device_dict = IOPSGetPowerSourceDescription(blob, ps); /* Retrieve the charging key and save the present charging value if one exists. */ if (CFDictionaryGetValueIfPresent(device_dict, CFSTR(kIOPSIsChargingKey), &values)) { have_battery = 1; if (CFBooleanGetValue(values) > 0) have_power = 1; break; } } if (!have_battery) { CFRelease(sources); CFRelease(blob); have_power = 1; return; } /* Retrieve the current capacity key. */ values = CFDictionaryGetValue(device_dict, CFSTR(kIOPSCurrentCapacityKey)); CFNumberGetValue(values, kCFNumberSInt32Type, ¤tval); /* Retrieve the max capacity key. */ values = CFDictionaryGetValue(device_dict, CFSTR(kIOPSMaxCapacityKey)); CFNumberGetValue(values, kCFNumberSInt32Type, &maxval); /* Calculate the percentage charged. */ battery_full = (currentval * 100) / maxval; /* Retrieve the remaining battery power or time until charged in minutes. */ if (!have_power) { values = CFDictionaryGetValue(device_dict, CFSTR(kIOPSTimeToEmptyKey)); CFNumberGetValue(values, kCFNumberSInt32Type, ¤tval); time_left = currentval * 60; } else { values = CFDictionaryGetValue(device_dict, CFSTR(kIOPSTimeToFullChargeKey)); CFNumberGetValue(values, kCFNumberSInt32Type, ¤tval); time_left = currentval * 60; } CFRelease(sources); CFRelease(blob); }
PowerInfo GetPowerState() { PowerInfo info; info.state = PowerInfo::STATE_UNKNOWN; info.seconds = 0; info.percent = 0.0f; #if defined(TARGET_OSX) CFTypeRef blob = IOPSCopyPowerSourcesInfo(); if (blob != NULL) { CFArrayRef list = IOPSCopyPowerSourcesList(blob); if (list != NULL) { /* don't CFRelease() the list items, or dictionaries! */ bool have_ac = false; bool have_battery = false; bool charging = false; const CFIndex total = CFArrayGetCount(list); CFIndex i; for (i = 0; i < total; i++) { CFTypeRef ps = (CFTypeRef) CFArrayGetValueAtIndex(list, i); CFDictionaryRef dict = IOPSGetPowerSourceDescription(blob, ps); if (dict != NULL) { checkps(dict, &have_ac, &have_battery, &charging, &info.seconds, &info.percent); } } if (!have_battery) { info.state = PowerInfo::STATE_NO_BATTERY; } else if (charging) { info.state = PowerInfo::STATE_CHARGING; } else if (have_ac) { info.state = PowerInfo::STATE_CHARGED; } else { info.state = PowerInfo::STATE_ON_BATTERY; } CFRelease(list); } CFRelease(blob); } #elif defined(TARGET_LINUX) #else #endif return info; }
int OnBattery (void) { #if defined (__APPLE__) /* The following copyright applies to the battery detection code below. I did modify */ /* substantially as it did far more than I needed. */ /* Copyright (c) 2003 Thomas Runge ([email protected]) * Mach and Darwin specific code is Copyright (c) 2006 Eric Pooch ([email protected]) * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of its contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ CFTypeRef blob = IOPSCopyPowerSourcesInfo(); CFArrayRef sources = IOPSCopyPowerSourcesList(blob); int i, acstat; CFDictionaryRef pSource = NULL; const void *psValue; acstat = TRUE; for(i = 0; i < CFArrayGetCount(sources); i++) { pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i)); if(!pSource) break; psValue = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey)); if (CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsPresentKey), &psValue) && (CFBooleanGetValue(psValue) > 0)) { psValue = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSPowerSourceStateKey)); if (CFStringCompare(psValue,CFSTR(kIOPSBatteryPowerValue),0)==kCFCompareEqualTo) { /* We are running on a battery power source. */ acstat = FALSE; } } } CFRelease(blob); CFRelease(sources); return(!acstat); #elif defined (__linux__) FILE *fd; char buf[180]; int ac_state; ac_state = -1; fd = fopen ("/proc/acpi/battery/BAT0/state", "r"); if (fd != NULL) { while (fgets (buf, sizeof (buf), fd) != NULL) { char *p; p = strstr (buf, "charging state:"); if (p == NULL) continue; if (strstr (p+14, "discharging") != NULL) ac_state = 0; else if (strstr (p+14, "charging") != NULL) ac_state = 1; else if (strstr (p+14, "charged") != NULL) ac_state = 1; } fclose (fd); } return (ac_state == 0); #else return (FALSE); /* Assume we're on AC power */ #endif }
static void powerSourceChanged(void *context) { #pragma unused(context) CFTypeRef powerBlob = IOPSCopyPowerSourcesInfo(); CFArrayRef powerSourcesList = IOPSCopyPowerSourcesList(powerBlob); CFIndex count = CFArrayGetCount(powerSourcesList); for (CFIndex i = 0; i < count; ++i) { CFTypeRef powerSource; CFDictionaryRef description; HGPowerSource hgPowerSource; CFBooleanRef charging = kCFBooleanFalse; CFIndex batteryTime = -1; CFIndex percentageCapacity = -1; powerSource = CFArrayGetValueAtIndex(powerSourcesList, i); description = IOPSGetPowerSourceDescription(powerBlob, powerSource); //Don't display anything for power sources that aren't present (i.e. an absent second battery in a 2-battery machine) if (CFDictionaryGetValue(description, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse) continue; //We only know how to handle internal (battery, a/c power) transport types. The other values indicate UPS usage. if (stringsAreEqual(CFDictionaryGetValue(description, CFSTR(kIOPSTransportTypeKey)), CFSTR(kIOPSInternalType))) { CFStringRef currentState = CFDictionaryGetValue(description, CFSTR(kIOPSPowerSourceStateKey)); if (stringsAreEqual(currentState, CFSTR(kIOPSACPowerValue))) hgPowerSource = HGACPower; else if (stringsAreEqual(currentState, CFSTR(kIOPSBatteryPowerValue))) hgPowerSource = HGBatteryPower; else hgPowerSource = HGUnknownPower; //Battery power if (CFDictionaryGetValue(description, CFSTR(kIOPSIsChargingKey)) == kCFBooleanTrue) { //Charging charging = kCFBooleanTrue; CFNumberRef timeToChargeNum = CFDictionaryGetValue(description, CFSTR(kIOPSTimeToFullChargeKey)); CFIndex timeToCharge; if (CFNumberGetValue(timeToChargeNum, kCFNumberCFIndexType, &timeToCharge)) batteryTime = timeToCharge; } else { //Not charging charging = kCFBooleanFalse; CFNumberRef timeToEmptyNum = CFDictionaryGetValue(description, CFSTR(kIOPSTimeToEmptyKey)); CFIndex timeToEmpty; if (CFNumberGetValue(timeToEmptyNum, kCFNumberCFIndexType, &timeToEmpty)) batteryTime = timeToEmpty; } /* Capacity */ CFNumberRef currentCapacityNum = CFDictionaryGetValue(description, CFSTR(kIOPSCurrentCapacityKey)); CFNumberRef maxCapacityNum = CFDictionaryGetValue(description, CFSTR(kIOPSMaxCapacityKey)); CFIndex currentCapacity, maxCapacity; if (CFNumberGetValue(currentCapacityNum, kCFNumberCFIndexType, ¤tCapacity) && CFNumberGetValue(maxCapacityNum, kCFNumberCFIndexType, &maxCapacity)) percentageCapacity = roundf((currentCapacity / (float)maxCapacity) * 100.0f); } else { //UPS power hgPowerSource = HGUPSPower; } //Avoid sending notifications on the same power source multiple times, unless the charging state or presence/absence of a time estimate has changed. if (lastPowerSource != hgPowerSource || lastChargingState != charging || (lastBatteryTime == -1) != (batteryTime == -1)) { lastPowerSource = hgPowerSource; lastChargingState = charging; lastBatteryTime = batteryTime; AppController_powerSwitched(hgPowerSource, charging, batteryTime, percentageCapacity); } } CFRelease(powerSourcesList); CFRelease(powerBlob); }