2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 3
10
* of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23
#include <dbus/dbus-glib.h>
25
#include "powermanager-draw.h"
26
#include "powermanager-struct.h"
27
#include "powermanager-common.h"
28
#include "powermanager-proc-acpi.h"
30
#define CD_BATTERY_DIR "/proc/acpi/battery"
31
//#define CD_BATTERY_DIR "/home/fab/proc/acpi/battery"
35
charging state: discharging
36
present rate: 15000 mW
37
remaining capacity: 47040 mWh
38
present voltage: 15000 mV*/
40
static gboolean _find_battery_in_dir (const gchar *cBatteryPath)
42
// open the folder containing battery data.
43
GDir *dir = g_dir_open (cBatteryPath, 0, NULL);
46
cd_debug ("powermanager: no battery in %s",cBatteryPath );
50
// parse the folder and search the battery files.
51
GString *sBatteryInfoFilePath = g_string_new ("");
52
gchar *cContent = NULL, *cPresentLine;
54
const gchar *cBatteryName;
55
gboolean bBatteryFound = FALSE;
58
cBatteryName = g_dir_read_name (dir); // usually "BAT0".
59
if (cBatteryName == NULL)
62
// check the battery info.
63
g_string_printf (sBatteryInfoFilePath, "%s/%s/info", cBatteryPath, cBatteryName);
65
cd_debug (" examen de la batterie '%s' ...", sBatteryInfoFilePath->str);
66
g_file_get_contents (sBatteryInfoFilePath->str, &cContent, &length, NULL);
69
gchar *str = strchr (cContent, '\n'); // first line: "present: yes"
72
gchar *str2 = strchr (str+1, ':');
76
myData.iCapacity = atoi (str2);
78
gchar *str3 = strchr (str2, ':');
79
if (str3 != NULL) // prefer the last full capacity if available.
82
myData.iCapacity = atoi (str3);
85
cd_debug ("Capacity : %d mWsh\n", myData.iCapacity);
86
myData.cBatteryStateFilePath = g_strdup_printf ("%s/%s/state", cBatteryPath, cBatteryName);
93
while (! bBatteryFound);
97
gboolean cd_find_battery_proc_acpi (void)
99
gboolean bBatteryFound = _find_battery_in_dir (CD_BATTERY_DIR);
100
return bBatteryFound;
104
#define go_to_next_line \
105
cCurLine = strchr (cCurVal, '\n'); \
106
g_return_val_if_fail (cCurLine != NULL, FALSE); \
110
#define jump_to_value \
111
cCurVal = strchr (cCurLine, ':'); \
112
g_return_val_if_fail (cCurVal != NULL, FALSE); \
114
while (*cCurVal == ' ') \
117
gboolean cd_get_stats_from_proc_acpi (void)
119
//\_______________ get the content of the stats file.
120
gchar *cContent = NULL;
122
GError *erreur = NULL;
123
g_file_get_contents (myData.cBatteryStateFilePath, &cContent, &length, &erreur);
126
cd_warning ("powermanager : %s", erreur->message);
127
g_error_free(erreur);
131
g_return_val_if_fail (cContent != NULL, FALSE);
134
gchar *cCurLine = cContent, *cCurVal = cContent;
136
//\_______________ check the battery presence.
137
jump_to_value // "present: yes"
138
gboolean bBatteryPresent = (*cCurVal == 'y');
139
if (bBatteryPresent != myData.bBatteryPresent) // the battery has just been inserted/removed.
141
myData.bBatteryPresent = bBatteryPresent;
142
if (! bBatteryPresent) // if the battery has been removed, we are obviously on the sector.
144
cd_debug ("la batterie a ete enlevee\n");
145
myData.bOnBattery = FALSE;
151
// reset the history.
152
cd_debug ("la batterie a ete connectee\n");
153
myData.iPrevTime = 0;
154
myData.iPrevPercentage = 0;
155
/**for (k = 0; k < PM_NB_VALUES; k ++)
156
myData.fRateHistory[k] = 0;
157
myData.iCurrentIndex = 0;
158
myData.iIndexMax = 0;*/
159
myData.iStatPercentageBegin = 0;
160
myData.iStatPercentage = 0;
163
go_to_next_line // -> "capacity state: ok"
165
go_to_next_line // -> "charging state: discharging"
167
//\_______________ check 'on battery' state.
169
gboolean bOnBattery = (*cCurVal == 'd'); // "discharging"
170
if (bOnBattery != myData.bOnBattery) // state changed
172
/**for (k = 0; k < PM_NB_VALUES; k ++) // reset the history.
173
myData.fRateHistory[k] = 0;
174
myData.iCurrentIndex = 0;
175
myData.iIndexMax = 0;*/
176
myData.iStatPercentageBegin = 0;
177
myData.iStatPercentage = 0;
178
myData.bOnBattery = bOnBattery;
181
go_to_next_line // -> present rate: 15000 mW
183
//\_______________ get the current charge and rate (this one can be 0 if not available).
185
double fPresentRate = atoi (cCurVal); // 15000 mW OU 1400 mA
188
while (*cCurVal != ' ')
190
while (*cCurVal == ' ')
193
cd_warning ("PowerManager : expecting mA or mW as the present rate unit");
197
else if (*cCurVal == 'A')
200
cd_warning ("PowerManager : expecting A or W as the present rate unit");*/
202
go_to_next_line // -> "remaining capacity: 47040 mWh"
205
int iRemainingCapacity = atoi (cCurVal); // 47040 mWh
207
/**go_to_next_line // -> "present voltage: 15000 mV"
210
int iPresentVoltage = atoi (cCurVal); // 15000 mV
212
myData.iPercentage = 100. * iRemainingCapacity / myData.iCapacity;
213
cd_debug ("myData.iPercentage : %.2f%% (%d / %d)", (double)myData.iPercentage, iRemainingCapacity, myData.iCapacity);
214
if (myData.iPercentage > 100)
215
myData.iPercentage = 100;
216
if (myData.iPercentage < 0)
217
myData.iPercentage = 0.;
219
//\_______________ now compute the time.
220
myData.iTime = cd_estimate_time ();
222
//cd_message ("PowerManager : On Battery:%d ; iCapacity:%dmWh ; iRemainingCapacity:%dmWh ; fPresentRate:%.2fmW ; iPresentVoltage:%dmV", myData.bOnBattery, myData.iCapacity, iRemainingCapacity, fPresentRate, iPresentVoltage);