| 181 | | #else /* !RT_OS_LINUX either - what could this be? */ |
|---|
| | 187 | #elif defined (RT_OS_DARWIN) /* !RT_OS_LINUX */ |
|---|
| | 188 | *pPowerSource = PDM_ACPI_POWER_SOURCE_UNKNOWN; |
|---|
| | 189 | |
|---|
| | 190 | CFTypeRef pBlob = IOPSCopyPowerSourcesInfo(); |
|---|
| | 191 | CFArrayRef pSources = IOPSCopyPowerSourcesList(pBlob); |
|---|
| | 192 | |
|---|
| | 193 | CFDictionaryRef pSource = NULL; |
|---|
| | 194 | const void *psValue; |
|---|
| | 195 | bool result; |
|---|
| | 196 | |
|---|
| | 197 | if (CFArrayGetCount(pSources) > 0) |
|---|
| | 198 | { |
|---|
| | 199 | for(int i = 0; i < CFArrayGetCount(pSources); ++i) |
|---|
| | 200 | { |
|---|
| | 201 | pSource = IOPSGetPowerSourceDescription(pBlob, CFArrayGetValueAtIndex(pSources, i)); |
|---|
| | 202 | /* If the source is empty skip over to the next one. */ |
|---|
| | 203 | if(!pSource) |
|---|
| | 204 | continue; |
|---|
| | 205 | /* Skip all power sources which are currently not present like a |
|---|
| | 206 | * second battery. */ |
|---|
| | 207 | if (CFDictionaryGetValue(pSource, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse) |
|---|
| | 208 | continue; |
|---|
| | 209 | /* Only internal power types are of interest. */ |
|---|
| | 210 | result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTransportTypeKey), &psValue); |
|---|
| | 211 | if (result && |
|---|
| | 212 | CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo) |
|---|
| | 213 | { |
|---|
| | 214 | /* Check which power source we are connect on. */ |
|---|
| | 215 | result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue); |
|---|
| | 216 | if (result && |
|---|
| | 217 | CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo) |
|---|
| | 218 | *pPowerSource = PDM_ACPI_POWER_SOURCE_OUTLET; |
|---|
| | 219 | else if (result && |
|---|
| | 220 | CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) |
|---|
| | 221 | *pPowerSource = PDM_ACPI_POWER_SOURCE_BATTERY; |
|---|
| | 222 | } |
|---|
| | 223 | } |
|---|
| | 224 | } |
|---|
| | 225 | CFRelease(pBlob); |
|---|
| | 226 | CFRelease(pSources); |
|---|
| | 227 | #else /* !RT_OS_DARWIN either - what could this be? */ |
|---|
| 415 | | #endif /* RT_OS_LINUX */ |
|---|
| | 461 | #elif defined(RT_OS_DARWIN) |
|---|
| | 462 | CFTypeRef pBlob = IOPSCopyPowerSourcesInfo(); |
|---|
| | 463 | CFArrayRef pSources = IOPSCopyPowerSourcesList(pBlob); |
|---|
| | 464 | |
|---|
| | 465 | CFDictionaryRef pSource = NULL; |
|---|
| | 466 | const void *psValue; |
|---|
| | 467 | bool result; |
|---|
| | 468 | |
|---|
| | 469 | if (CFArrayGetCount(pSources) > 0) |
|---|
| | 470 | { |
|---|
| | 471 | for(int i = 0; i < CFArrayGetCount(pSources); ++i) |
|---|
| | 472 | { |
|---|
| | 473 | pSource = IOPSGetPowerSourceDescription(pBlob, CFArrayGetValueAtIndex(pSources, i)); |
|---|
| | 474 | /* If the source is empty skip over to the next one. */ |
|---|
| | 475 | if(!pSource) |
|---|
| | 476 | continue; |
|---|
| | 477 | /* Skip all power sources which are currently not present like a |
|---|
| | 478 | * second battery. */ |
|---|
| | 479 | if (CFDictionaryGetValue(pSource, CFSTR(kIOPSIsPresentKey)) == kCFBooleanFalse) |
|---|
| | 480 | continue; |
|---|
| | 481 | /* Only internal power types are of interest. */ |
|---|
| | 482 | result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTransportTypeKey), &psValue); |
|---|
| | 483 | if (result && |
|---|
| | 484 | CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo) |
|---|
| | 485 | { |
|---|
| | 486 | PDMACPIPOWERSOURCE powerSource = PDM_ACPI_POWER_SOURCE_UNKNOWN; |
|---|
| | 487 | /* First check which power source we are connect on. */ |
|---|
| | 488 | result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue); |
|---|
| | 489 | if (result && |
|---|
| | 490 | CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo) |
|---|
| | 491 | powerSource = PDM_ACPI_POWER_SOURCE_OUTLET; |
|---|
| | 492 | else if (result && |
|---|
| | 493 | CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) |
|---|
| | 494 | powerSource = PDM_ACPI_POWER_SOURCE_BATTERY; |
|---|
| | 495 | |
|---|
| | 496 | /* At this point the power source is present. */ |
|---|
| | 497 | *pfPresent = true; |
|---|
| | 498 | *penmBatteryState = PDM_ACPI_BAT_STATE_CHARGED; |
|---|
| | 499 | |
|---|
| | 500 | int curCapacity = 0; |
|---|
| | 501 | int maxCapacity = 1; |
|---|
| | 502 | float remCapacity = 0.0f; |
|---|
| | 503 | |
|---|
| | 504 | /* Fetch the current capacity value of the power source */ |
|---|
| | 505 | result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSCurrentCapacityKey), &psValue); |
|---|
| | 506 | if (result) |
|---|
| | 507 | CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity); |
|---|
| | 508 | /* Fetch the maximum capacity value of the power source */ |
|---|
| | 509 | result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSMaxCapacityKey), &psValue); |
|---|
| | 510 | if (result) |
|---|
| | 511 | CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity); |
|---|
| | 512 | |
|---|
| | 513 | /* Calculate the remaining capacity in percent */ |
|---|
| | 514 | remCapacity = ((float)curCapacity/(float)maxCapacity * PDM_ACPI_BAT_CAPACITY_MAX); |
|---|
| | 515 | *penmRemainingCapacity = (PDMACPIBATCAPACITY)remCapacity; |
|---|
| | 516 | |
|---|
| | 517 | if (powerSource == PDM_ACPI_POWER_SOURCE_BATTERY) |
|---|
| | 518 | { |
|---|
| | 519 | /* If we are on battery power we are discharging in every |
|---|
| | 520 | * case */ |
|---|
| | 521 | *penmBatteryState = PDM_ACPI_BAT_STATE_DISCHARGING; |
|---|
| | 522 | int timeToEmpty = -1; |
|---|
| | 523 | /* Get the time till the battery source will be empty */ |
|---|
| | 524 | result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTimeToEmptyKey), &psValue); |
|---|
| | 525 | if (result) |
|---|
| | 526 | CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &timeToEmpty); |
|---|
| | 527 | if (timeToEmpty != -1) |
|---|
| | 528 | /* 0...1000 */ |
|---|
| | 529 | *pu32PresentRate = (uint32_t)roundf((remCapacity / ((float)timeToEmpty/60.0)) * 10.0); |
|---|
| | 530 | } |
|---|
| | 531 | |
|---|
| | 532 | if (powerSource == PDM_ACPI_POWER_SOURCE_OUTLET && |
|---|
| | 533 | CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsChargingKey), &psValue)) |
|---|
| | 534 | { |
|---|
| | 535 | /* We are running on an AC power source, but we also have a |
|---|
| | 536 | * battery power source present. */ |
|---|
| | 537 | if (CFBooleanGetValue((CFBooleanRef)psValue) > 0) |
|---|
| | 538 | { |
|---|
| | 539 | /* This means charging. */ |
|---|
| | 540 | *penmBatteryState = PDM_ACPI_BAT_STATE_CHARGING; |
|---|
| | 541 | int timeToFull = -1; |
|---|
| | 542 | /* Get the time till the battery source will be charged */ |
|---|
| | 543 | result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTimeToFullChargeKey), &psValue); |
|---|
| | 544 | if (result) |
|---|
| | 545 | CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &timeToFull); |
|---|
| | 546 | if (timeToFull != -1) |
|---|
| | 547 | /* 0...1000 */ |
|---|
| | 548 | *pu32PresentRate = (uint32_t)roundf((100.0-(float)remCapacity) / ((float)timeToFull/60.0)) * 10.0; |
|---|
| | 549 | } |
|---|
| | 550 | } |
|---|
| | 551 | |
|---|
| | 552 | /* Check for critical */ |
|---|
| | 553 | int criticalValue = 20; |
|---|
| | 554 | result = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSDeadWarnLevelKey), &psValue); |
|---|
| | 555 | if (result) |
|---|
| | 556 | CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &criticalValue); |
|---|
| | 557 | if (remCapacity < criticalValue) |
|---|
| | 558 | *penmBatteryState = (PDMACPIBATSTATE)(*penmBatteryState | PDM_ACPI_BAT_STATE_CRITICAL); |
|---|
| | 559 | } |
|---|
| | 560 | } |
|---|
| | 561 | } |
|---|
| | 562 | CFRelease(pBlob); |
|---|
| | 563 | CFRelease(pSources); |
|---|
| | 564 | #endif /* RT_OS_DARWIN */ |
|---|