* Applied 2 patches:
authorBrenden Matthews <brenden1@rty.ca>
Mon, 17 Mar 2008 22:27:20 +0000 (22:27 +0000)
committerBrenden Matthews <brenden1@rty.ca>
Mon, 17 Mar 2008 22:27:20 +0000 (22:27 +0000)
1) sysfs battery support (for Linux >=2.6.24) (thanks Kapil)
2) Improved audacious support patch (thanks Miroslav)

git-svn-id: https://conky.svn.sourceforge.net/svnroot/conky/trunk/conky1@1009 7f574dfc-610e-0410-a909-a81674777703

AUTHORS
ChangeLog
src/audacious.c
src/conky.c
src/linux.c

diff --git a/AUTHORS b/AUTHORS
index 2ab67bd..fc9499b 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -146,7 +146,8 @@ J
 Kapil Hari Paranjape <kapil@imsc.res.in>
   ibm_volume patch
   kFreeBSD support patch
-  realtime clock patck
+  realtime clock patch
+  sysfs battery patch
 
 Kevin Lyles <kevinlyles at gmail dot com>
   add long options patch
@@ -178,6 +179,9 @@ Lucas Brutschy <lbrutschy at users dot sourceforge dot net>
 Michal Januszewski <spock at gentoo dot org>
   hddtemp support
 
+Miroslav Lichvar <lichvarm at gmail dot com>
+  move audacious thread init to update_audacious() patch
+
 Moncelier Camille <pixdamix at users dot sourceforge dot net>
   METAR patch
 
@@ -201,6 +205,7 @@ Petr Holub <hopet@users.sourceforge.net>
 
 Philip Kovacs <pkovacs at users dot sourceforge dot net>
   tcp port monitor with hashing functionality
+  
   Audacious, Xmms, BMP, Infopipe stuff
   Various Xlib changes, e.g. own_window hints, etc.
 
index c54a935..b6bd380 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 # $Id$
 
+2008-03-17
+       * Applied 2 patches:
+               1) sysfs battery support (for Linux >=2.6.24) (thanks Kapil)
+               2) Improved audacious support patch (thanks Miroslav)
+
 2008-02-08
        * Applied 2 patches:
                1) Add diskio for individual devices
index ed7e644..4f2cdfb 100644 (file)
@@ -73,7 +73,11 @@ void update_audacious(void)
         * We merely copy the audacious_items array into the main thread's info
         * structure when the main thread's update cycle fires. */
        if (!info.audacious.p_timed_thread) {
-               return;
+               if (create_audacious_thread() != 0) {
+                       CRIT_ERR("unable to create audacious thread!");
+               }
+               timed_thread_register(info.audacious.p_timed_thread,
+                       &info.audacious.p_timed_thread);
        }
 
        timed_thread_lock(info.audacious.p_timed_thread);
index 3fd05c8..da1e71c 100644 (file)
@@ -7102,13 +7102,6 @@ void reload_config(void)
 #ifdef TCP_PORT_MONITOR
                info.p_tcp_port_monitor_collection = NULL;
 #endif
-#ifdef AUDACIOUS
-               if (create_audacious_thread() != 0) {
-                       CRIT_ERR("unable to create audacious thread!");
-               }
-               timed_thread_register(info.audacious.p_timed_thread,
-                       &info.audacious.p_timed_thread);
-#endif
                extract_variable_text(text);
                free(text);
                text = NULL;
@@ -8305,14 +8298,6 @@ int main(int argc, char **argv)
                ERR("error setting signal handler: %s", strerror(errno));
        }
 
-#ifdef AUDACIOUS
-       if (create_audacious_thread() != 0) {
-               CRIT_ERR("unable to create audacious thread!");
-       }
-       timed_thread_register(info.audacious.p_timed_thread,
-               &info.audacious.p_timed_thread);
-#endif
-
        /* *************** *
         * MAIN CONKY LOOP *
         * *************** */
index a49e9bf..9dea1ef 100644 (file)
@@ -1291,10 +1291,36 @@ present voltage:         16608 mV
 2241<@jupet�kellari��> 1.16 1.2 0x03 0x00 0x00 0x01 99% -1 ? monitori p��ll� mutta ilman verkkovirtaa
 */
 
+/* Kapil Hari Paranjape <kapil@imsc.res.in>
+  Linux 2.6.24 onwards battery info is in
+  /sys/class/power_supply/BAT0/
+  On my system I get the following.
+       /sys/class/power_supply/BAT0/uevent:
+       PHYSDEVPATH=/devices/LNXSYSTM:00/device:00/PNP0A03:00/device:01/PNP0C09:00/PNP0C0A:00
+       PHYSDEVBUS=acpi
+       PHYSDEVDRIVER=battery
+       POWER_SUPPLY_NAME=BAT0
+       POWER_SUPPLY_TYPE=Battery
+       POWER_SUPPLY_STATUS=Discharging
+       POWER_SUPPLY_PRESENT=1
+       POWER_SUPPLY_TECHNOLOGY=Li-ion
+       POWER_SUPPLY_VOLTAGE_MIN_DESIGN=10800000
+       POWER_SUPPLY_VOLTAGE_NOW=10780000
+       POWER_SUPPLY_CURRENT_NOW=13970000
+       POWER_SUPPLY_ENERGY_FULL_DESIGN=47510000
+       POWER_SUPPLY_ENERGY_FULL=27370000
+       POWER_SUPPLY_ENERGY_NOW=11810000
+       POWER_SUPPLY_MODEL_NAME=IBM-92P1060
+       POWER_SUPPLY_MANUFACTURER=Panasonic
+  On some systems POWER_SUPPLY_ENERGY_* is replaced by POWER_SUPPLY_CHARGE_*
+*/
+
+#define SYSFS_BATTERY_BASE_PATH "/sys/class/power_supply"
 #define ACPI_BATTERY_BASE_PATH "/proc/acpi/battery"
 #define APM_PATH "/proc/apm"
 #define MAX_BATTERY_COUNT 4
 
+static FILE *sysfs_bat_fp[MAX_BATTERY_COUNT];
 static FILE *acpi_bat_fp[MAX_BATTERY_COUNT];
 static FILE *apm_bat_fp[MAX_BATTERY_COUNT];
 
@@ -1351,6 +1377,8 @@ void get_battery_stuff(char *buf, unsigned int n, const char *bat, int item)
        char acpi_path[128];
 
        snprintf(acpi_path, 127, ACPI_BATTERY_BASE_PATH "/%s/state", bat);
+       char sysfs_path[128];
+       snprintf(sysfs_path, 127, SYSFS_BATTERY_BASE_PATH "/%s/uevent", bat);
 
        init_batteries();
 
@@ -1366,13 +1394,117 @@ void get_battery_stuff(char *buf, unsigned int n, const char *bat, int item)
        memset(last_battery_str[idx], 0, sizeof(last_battery_str[idx]));
        memset(last_battery_time_str[idx], 0, sizeof(last_battery_time_str[idx]));
 
-       /* first try ACPI */
-
-       if (acpi_bat_fp[idx] == NULL && apm_bat_fp[idx] == NULL) {
-               acpi_bat_fp[idx] = open_file(acpi_path, &rep);
-       }
-
-       if (acpi_bat_fp[idx] != NULL) {
+       /* first try SYSFS if that fails try ACPI */
+       if (sysfs_bat_fp[idx] == NULL && acpi_bat_fp[idx] == NULL && apm_bat_fp[idx] == NULL)
+               sysfs_bat_fp[idx] = open_file(sysfs_path, &rep);
+  
+       if (sysfs_bat_fp[idx] == NULL && acpi_bat_fp[idx] == NULL && apm_bat_fp[idx] == NULL)
+               acpi_bat_fp[idx] = open_file(acpi_path, &rep);
+  
+       if (sysfs_bat_fp[idx] != NULL) {
+               /* SYSFS */
+               int present_rate = -1;
+               int remaining_capacity = -1;
+               char charging_state[64];
+               char present[4];
+               strcpy(charging_state, "Unknown");
+               while (!feof(sysfs_bat_fp[idx])) {
+                       char buf[256];
+                       if (fgets(buf, 256, sysfs_bat_fp[idx]) == NULL)
+                               break;
+                       /* let's just hope units are ok */
+                       if (strncmp (buf, "POWER_SUPPLY_PRESENT=1", 22) == 0)
+                               strcpy(present, "Yes");
+                       else if (strncmp (buf, "POWER_SUPPLY_PRESENT=0", 22) == 0)
+                               strcpy(present, "No");
+                       else if (strncmp (buf, "POWER_SUPPLY_STATUS=", 20) == 0)
+                               sscanf(buf, "POWER_SUPPLY_STATUS=%63s", charging_state);
+                       /* present_rate is not the same as the
+                       current flowing now but it is the same value
+                       which was used in the past. so we continue
+                       the tradition! */
+                       else if (strncmp(buf, "POWER_SUPPLY_CURRENT_NOW=", 25) == 0)
+                               sscanf(buf, "POWER_SUPPLY_CURRENT_NOW=%d", &present_rate);
+                       else if (strncmp(buf, "POWER_SUPPLY_ENERGY_NOW=", 24) == 0)
+                               sscanf(buf, "POWER_SUPPLY_ENERGY_NOW=%d", &remaining_capacity);
+                       else if (strncmp(buf, "POWER_SUPPLY_ENERGY_FULL=", 25) == 0)
+                               sscanf(buf, "POWER_SUPPLY_ENERGY_FULL=%d", &acpi_last_full[idx]);
+                       else if (strncmp(buf, "POWER_SUPPLY_CHARGE_NOW=", 24) == 0)
+                               sscanf(buf, "POWER_SUPPLY_CHARGE_NOW=%d", &remaining_capacity);
+                       else if (strncmp(buf, "POWER_SUPPLY_CHARGE_FULL=", 25) == 0)
+                               sscanf(buf, "POWER_SUPPLY_CHARGE_FULL=%d", &acpi_last_full[idx]);
+               }
+               fclose(sysfs_bat_fp[idx]);
+               sysfs_bat_fp[idx] = NULL;
+               /* Hellf[i]re notes that remaining capacity can exceed acpi_last_full */
+               if (remaining_capacity > acpi_last_full[idx])
+                       acpi_last_full[idx] = remaining_capacity;  /* normalize to 100% */
+               /* not present */
+               if (strcmp(present, "No") == 0) {
+                       strncpy(last_battery_str[idx], "not present", 64);
+               }
+               /* charging */
+               else if (strcmp(charging_state, "Charging") == 0) {
+                       if (acpi_last_full[idx] != 0 && present_rate > 0) {
+                               /* e.g. charging 75% */
+                               snprintf(last_battery_str[idx], sizeof(last_battery_str[idx])-1, "Charging %i%%",
+                                       (int) (((float) remaining_capacity / acpi_last_full[idx]) * 100 ));
+                               /* e.g. 2h 37m */
+                               format_seconds(last_battery_time_str[idx], sizeof(last_battery_time_str[idx])-1,
+                                             (long) (((float)(acpi_last_full[idx] - remaining_capacity) / present_rate) * 3600));
+                       } else if (acpi_last_full[idx] != 0 && present_rate <= 0) {
+                               snprintf(last_battery_str[idx], sizeof(last_battery_str[idx])-1, "Charging %d%%",
+                                       (int) (((float)remaining_capacity / acpi_last_full[idx]) * 100));
+                       } else {
+                               strncpy(last_battery_str[idx], "Charging", sizeof(last_battery_str[idx])-1);
+                       }
+               }
+               /* discharging */
+               else if (strncmp(charging_state, "Discharging", 64) == 0) {
+                       if (present_rate > 0) {
+                               /* e.g. discharging 35% */
+                               snprintf(last_battery_str[idx], sizeof(last_battery_str[idx])-1, "Discharging %i%%",
+                                       (int) (((float) remaining_capacity / acpi_last_full[idx]) * 100 ));
+                               /* e.g. 1h 12m */
+                               format_seconds(last_battery_time_str[idx], sizeof(last_battery_time_str[idx])-1,
+                                             (long) (((float)(acpi_last_full[idx] - remaining_capacity) / present_rate) * 3600));
+                       } else if (present_rate == 0) { /* Thanks to Nexox for this one */
+                               snprintf(last_battery_str[idx], sizeof(last_battery_str[idx])-1, "Full");
+                       } else {
+                               snprintf(last_battery_str[idx], sizeof(last_battery_str[idx])-1,
+                                       "Discharging %d%%",
+                                       (int) (((float)remaining_capacity / acpi_last_full[idx]) * 100));
+                       }
+               }
+               /* charged */
+               /* thanks to Lukas Zapletal <lzap@seznam.cz> */
+               else if (strncmp(charging_state, "Charged", 64) == 0) {
+                               /* Below happens with the second battery on my X40,
+                                * when the second one is empty and the first one
+                                * being charged. */
+                               if (remaining_capacity == 0)
+                                       strcpy(last_battery_str[idx], "Empty");
+                               else
+                                       strcpy(last_battery_str[idx], "Charged");
+               }
+               /* unknown, probably full / AC */
+               else {
+                       if (acpi_last_full[idx] != 0
+                           && remaining_capacity != acpi_last_full[idx])
+                               snprintf(last_battery_str[idx], 64, "Unknown %d%%",
+                                       (int) (((float)remaining_capacity / acpi_last_full[idx]) * 100));
+                       else
+                               strncpy(last_battery_str[idx], "AC", 64);
+               }
+       } else if (acpi_bat_fp[idx] != NULL) {
+               /* ACPI */
                int present_rate = -1;
                int remaining_capacity = -1;
                char charging_state[64];
@@ -1543,6 +1675,8 @@ int get_battery_perct(const char *bat)
        char acpi_path[128];
 
        snprintf(acpi_path, 127, ACPI_BATTERY_BASE_PATH "/%s/state", bat);
+       char sysfs_path[128];
+       snprintf(sysfs_path, 127, SYSFS_BATTERY_BASE_PATH "/%s/uevent", bat);
 
        init_batteries();
 
@@ -1554,15 +1688,38 @@ int get_battery_perct(const char *bat)
        }
        last_battery_perct_time[idx] = current_update_time;
 
-       /* Only check for ACPI */
+       /* Only check for SYSFS or ACPI */
+
+       if (sysfs_bat_fp[idx] == NULL && acpi_bat_fp[idx] == NULL && apm_bat_fp[idx] == NULL)
+               sysfs_bat_fp[idx] = open_file(sysfs_path, &rep);
 
-       if (acpi_bat_fp[idx] == NULL && apm_bat_fp[idx] == NULL) {
+       if (sysfs_bat_fp[idx] == NULL && acpi_bat_fp[idx] == NULL && apm_bat_fp[idx] == NULL)
                acpi_bat_fp[idx] = open_file(acpi_path, &rep);
-       }
 
        int remaining_capacity = -1;
 
-       if (acpi_bat_fp[idx] != NULL) {
+       if (sysfs_bat_fp[idx] != NULL) {
+               /* SYSFS */
+               while (!feof(sysfs_bat_fp[idx])) {
+                       char buf[256];
+                       if (fgets(buf, 256, sysfs_bat_fp[idx]) == NULL)
+                               break;
+
+                       if (strncmp(buf, "POWER_SUPPLY_CHARGE_NOW=", 24) == 0)
+                               sscanf(buf, "POWER_SUPPLY_CHARGE_NOW=%d", &remaining_capacity);
+                       else if (strncmp(buf, "POWER_SUPPLY_CHARGE_FULL=",25) != 0)
+                               sscanf(buf, "POWER_SUPPLY_CHARGE_FULL=%d", &acpi_last_full[idx]);
+                       else if (strncmp(buf, "POWER_SUPPLY_ENERGY_NOW=", 24) == 0)
+                               sscanf(buf, "POWER_SUPPLY_ENERGY_NOW=%d", &remaining_capacity);
+                       else if (strncmp(buf, "POWER_SUPPLY_ENERGY_FULL=",25) != 0)
+                               sscanf(buf, "POWER_SUPPLY_ENERGY_FULL=%d", &acpi_last_full[idx]);
+               }
+
+               fclose(sysfs_bat_fp[idx]);
+               sysfs_bat_fp[idx] = NULL;
+
+       } else if (acpi_bat_fp[idx] != NULL) {
+               /* ACPI */
                /* read last full capacity if it's zero */
                if (acpi_design_capacity[idx] == 0) {
                        static int rep;
@@ -1579,7 +1736,7 @@ int get_battery_perct(const char *bat)
                                                break;
                                        }
                                        if (sscanf(b, "last full capacity: %d",
-                                                       &acpi_design_capacity[idx]) != 0) {
+                                                               &acpi_design_capacity[idx]) != 0) {
                                                break;
                                        }
                                }