@@ -380,4 +380,75 @@ void Platform_getBattery(BatteryInfo* info) {
380380 size_t acline_len = sizeof (acline );
381381 if (sysctlbyname ("hw.acpi.acline" , & acline , & acline_len , NULL , 0 ) != -1 )
382382 info -> ac = (acline == 0 ) ? AC_ABSENT : AC_PRESENT ;
383+
384+ int units = 0 ;
385+ int fd = open ("/dev/acpi" , O_RDONLY | O_CLOEXEC );
386+ if (fd == -1 )
387+ return ;
388+
389+ if (ioctl (fd , ACPIIO_BATT_GET_UNITS , & units ) == -1 || units <= 0 ) {
390+ close (fd );
391+ return ;
392+ }
393+
394+ bool haveTotalRemain = false;
395+ bool haveTotalFull = false;
396+
397+ int64_t totalRemain = 0 ;
398+ int64_t totalFull = 0 ;
399+
400+ for (int u = 0 ; u < units ; u ++ ) {
401+ union acpi_battery_ioctl_arg bifArg = { .unit = u };
402+ if (ioctl (fd , ACPIIO_BATT_GET_BIF , & bifArg ) == -1 )
403+ continue ;
404+
405+ union acpi_battery_ioctl_arg bstArg = { .unit = u };
406+ if (ioctl (fd , ACPIIO_BATT_GET_BST , & bstArg ) == -1 )
407+ continue ;
408+
409+ const struct acpi_bif * bif = & bifArg .bif ;
410+ const struct acpi_bst * bst = & bstArg .bst ;
411+
412+ bool haveBatteryEnergyCurr = false;
413+ bool haveBatteryEnergyFull = false;
414+
415+ int64_t batteryEnergyCurr = 0 ;
416+ int64_t batteryEnergyFull = 0 ;
417+
418+ if (bif -> lfcap != ACPI_BATT_UNKNOWN && bst -> cap != ACPI_BATT_UNKNOWN ) {
419+ if (bif -> units == ACPI_BIF_UNITS_MW ) {
420+ batteryEnergyCurr = (int64_t ) bst -> cap * 1000 ;
421+ batteryEnergyFull = (int64_t ) bif -> lfcap * 1000 ;
422+ haveBatteryEnergyCurr = true;
423+ haveBatteryEnergyFull = true;
424+ } else {
425+ uint32_t batteryVoltage = (bst -> volt != ACPI_BATT_UNKNOWN ) ? bst -> volt : bif -> dvol ;
426+ if (batteryVoltage != ACPI_BATT_UNKNOWN && batteryVoltage != 0 ) {
427+ batteryEnergyCurr = (int64_t ) bst -> cap * batteryVoltage ;
428+ batteryEnergyFull = (int64_t ) bif -> lfcap * batteryVoltage ;
429+ haveBatteryEnergyCurr = true;
430+ haveBatteryEnergyFull = true;
431+ }
432+ }
433+ }
434+
435+ if (haveBatteryEnergyCurr && haveBatteryEnergyFull && batteryEnergyFull > 0 ) {
436+ totalRemain += batteryEnergyCurr ;
437+ haveTotalRemain = true;
438+
439+ totalFull += batteryEnergyFull ;
440+ haveTotalFull = true;
441+ }
442+ }
443+
444+ close (fd );
445+
446+ if (haveTotalRemain && haveTotalFull && totalFull > 0 ) {
447+ info -> percent = ((double ) totalRemain * 100.0 ) / (double ) totalFull ;
448+ if (totalRemain >= totalFull )
449+ info -> percent = 100 ;
450+
451+ info -> energyCurr = (double ) totalRemain / 1000000.0 ;
452+ info -> energyFull = (double ) totalFull / 1000000.0 ;
453+ }
383454}
0 commit comments