/** * This file is a part of the Cairo-Dock project * * Copyright : (C) see the 'copyright' file. * E-mail : see the 'copyright' file. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "powermanager-draw.h" #include "powermanager-struct.h" #include "powermanager-common.h" #include "powermanager-proc-acpi.h" #define CD_BATTERY_DIR "/proc/acpi/battery" //#define CD_BATTERY_DIR "/home/fab/proc/acpi/battery" /*present: yes capacity state: ok charging state: discharging present rate: 15000 mW remaining capacity: 47040 mWh present voltage: 15000 mV*/ static gboolean _find_battery_in_dir (const gchar *cBatteryPath) { // open the folder containing battery data. GDir *dir = g_dir_open (cBatteryPath, 0, NULL); if (dir == NULL) { cd_debug ("powermanager: no battery in %s",cBatteryPath ); return FALSE; } // parse the folder and search the battery files. GString *sBatteryInfoFilePath = g_string_new (""); gchar *cContent = NULL; gsize length=0; const gchar *cBatteryName; gboolean bBatteryFound = FALSE; do { cBatteryName = g_dir_read_name (dir); // usually "BAT0". if (cBatteryName == NULL) break ; // check the battery info. g_string_printf (sBatteryInfoFilePath, "%s/%s/info", cBatteryPath, cBatteryName); length=0; cd_debug (" examen de la batterie '%s' ...", sBatteryInfoFilePath->str); g_file_get_contents (sBatteryInfoFilePath->str, &cContent, &length, NULL); if (cContent != NULL) { gchar *str = strchr (cContent, '\n'); // first line: "present: yes" if (str != NULL) { gchar *str2 = strchr (str+1, ':'); if (str2 != NULL) { str2 ++; myData.iCapacity = atoi (str2); gchar *str3 = strchr (str2, ':'); if (str3 != NULL) // prefer the last full capacity if available. { str3 ++; myData.iCapacity = atoi (str3); } cd_debug ("Capacity : %d mWsh", myData.iCapacity); myData.cBatteryStateFilePath = g_strdup_printf ("%s/%s/state", cBatteryPath, cBatteryName); bBatteryFound = TRUE; } } g_free (cContent); } } while (! bBatteryFound); g_dir_close (dir); return bBatteryFound; } gboolean cd_find_battery_proc_acpi (void) { gboolean bBatteryFound = _find_battery_in_dir (CD_BATTERY_DIR); return bBatteryFound; } #define go_to_next_line \ cCurLine = strchr (cCurVal, '\n'); \ g_return_val_if_fail (cCurLine != NULL, FALSE); \ cCurLine ++; \ cCurVal = cCurLine; #define jump_to_value \ cCurVal = strchr (cCurLine, ':'); \ g_return_val_if_fail (cCurVal != NULL, FALSE); \ cCurVal ++; \ while (*cCurVal == ' ') \ cCurVal ++; gboolean cd_get_stats_from_proc_acpi (void) { //\_______________ get the content of the stats file. gchar *cContent = NULL; gsize length=0; GError *erreur = NULL; g_file_get_contents (myData.cBatteryStateFilePath, &cContent, &length, &erreur); if (erreur != NULL) { cd_warning ("powermanager : %s", erreur->message); g_error_free(erreur); erreur = NULL; return FALSE; } g_return_val_if_fail (cContent != NULL, FALSE); gchar *cCurLine = cContent, *cCurVal = cContent; //\_______________ check the battery presence. jump_to_value // "present: yes" gboolean bBatteryPresent = (*cCurVal == 'y'); if (bBatteryPresent != myData.bBatteryPresent) // the battery has just been inserted/removed. { myData.bBatteryPresent = bBatteryPresent; if (! bBatteryPresent) // if the battery has been removed, we are obviously on the sector. { cd_debug ("la batterie a ete enlevee\n"); myData.bOnBattery = FALSE; update_icon(); g_free (cContent); return TRUE; } // reset the history. cd_debug ("la batterie a ete connectee\n"); myData.iPrevTime = 0; myData.iPrevPercentage = 0; /**for (k = 0; k < PM_NB_VALUES; k ++) myData.fRateHistory[k] = 0; myData.iCurrentIndex = 0; myData.iIndexMax = 0;*/ myData.iStatPercentageBegin = 0; myData.iStatPercentage = 0; } go_to_next_line // -> "capacity state: ok" go_to_next_line // -> "charging state: discharging" //\_______________ check 'on battery' state. jump_to_value gboolean bOnBattery = (*cCurVal == 'd'); // "discharging" if (bOnBattery != myData.bOnBattery) // state changed { /**for (k = 0; k < PM_NB_VALUES; k ++) // reset the history. myData.fRateHistory[k] = 0; myData.iCurrentIndex = 0; myData.iIndexMax = 0;*/ myData.iStatPercentageBegin = 0; myData.iStatPercentage = 0; myData.bOnBattery = bOnBattery; } go_to_next_line // -> present rate: 15000 mW //\_______________ get the current charge and rate (this one can be 0 if not available). jump_to_value // double fPresentRate = atoi (cCurVal); // 15000 mW OU 1400 mA /*cCurVal ++; while (*cCurVal != ' ') cCurVal ++; while (*cCurVal == ' ') cCurVal ++; if (*cCurVal != 'm') cd_warning ("PowerManager : expecting mA or mW as the present rate unit"); cCurVal ++; if (*cCurVal == 'W') bWatt = TRUE; else if (*cCurVal == 'A') bWatt = FALSE; else cd_warning ("PowerManager : expecting A or W as the present rate unit");*/ go_to_next_line // -> "remaining capacity: 47040 mWh" jump_to_value int iRemainingCapacity = atoi (cCurVal); // 47040 mWh /**go_to_next_line // -> "present voltage: 15000 mV" jump_to_value int iPresentVoltage = atoi (cCurVal); // 15000 mV */ myData.iPercentage = 100. * iRemainingCapacity / myData.iCapacity; cd_debug ("myData.iPercentage : %.2f%% (%d / %d)", (double)myData.iPercentage, iRemainingCapacity, myData.iCapacity); if (myData.iPercentage > 100) myData.iPercentage = 100; if (myData.iPercentage < 0) myData.iPercentage = 0.; //\_______________ now compute the time. myData.iTime = cd_estimate_time (); //cd_message ("PowerManager : On Battery:%d ; iCapacity:%dmWh ; iRemainingCapacity:%dmWh ; fPresentRate:%.2fmW ; iPresentVoltage:%dmV", myData.bOnBattery, myData.iCapacity, iRemainingCapacity, fPresentRate, iPresentVoltage); g_free (cContent); return (TRUE); }