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-dbus.h"
29
#define MY_BATTERY_DIR "/proc/acpi/battery"
30
#define MY_DEFAULT_BATTERY_NAME "BAT0"
32
static DBusGProxy *dbus_proxy_power = NULL;
33
static DBusGProxy *dbus_proxy_stats = NULL;
34
static DBusGProxy *dbus_proxy_battery = NULL;
37
static gboolean cd_powermanager_find_battery (void) {
38
GError *erreur = NULL;
39
GDir *dir = g_dir_open (MY_BATTERY_DIR, 0, &erreur);
42
cd_warning ("powermanager : %s", erreur->message);
43
g_error_free (erreur);
47
GString *sBatteryStateFilePath = g_string_new ("");
48
gchar *cContent = NULL, *cPresentLine;
50
const gchar *cBatteryName;
51
gboolean bBatteryFound = FALSE;
54
cBatteryName = g_dir_read_name (dir);
55
if (cBatteryName == NULL)
58
g_string_printf (sBatteryStateFilePath, "%s/%s/info", MY_BATTERY_DIR, cBatteryName);
60
cd_message (" examen de la batterie '%s' ...", sBatteryStateFilePath->str);
61
g_file_get_contents(sBatteryStateFilePath->str, &cContent, &length, &erreur);
64
cd_warning("powermanager : %s", erreur->message);
70
gchar *str = strchr (cContent, '\n'); // "present: yes"
75
if (g_strstr_len (cContent, -1, "yes") != NULL) // on l'a trouvee !
78
myData.cBatteryStateFilePath = g_strdup_printf ("%s/%s/state", MY_BATTERY_DIR, cBatteryName);
81
gchar *str2 = strchr (str, ':');
85
myData.iCapacity = atoi (str2);
86
g_print ("Design capacity : %d mWsh\n", myData.iCapacity);
89
gchar *str3 = strchr (str2, ':');
93
myData.iCapacity = atoi (str3);
94
g_print ("Last full capacity : %d mWsh\n", myData.iCapacity);
99
g_print ("cette batterie (%s) n'est pas presente.\n", cBatteryName);
105
while (! bBatteryFound);
107
return bBatteryFound;
110
gboolean dbus_connect_to_bus (void)
114
if (cairo_dock_bdus_is_enabled ())
116
dbus_proxy_power = cairo_dock_create_new_session_proxy (
117
"org.freedesktop.PowerManagement",
118
"/org/freedesktop/PowerManagement",
119
"org.freedesktop.PowerManagement"
122
/**dbus_proxy_stats = cairo_dock_create_new_session_proxy (
123
"org.freedesktop.PowerManagement",
124
"/org/freedesktop/PowerManagement/Statistics",
125
"org.freedesktop.PowerManagement.Statistics");*/
127
dbus_g_proxy_add_signal(dbus_proxy_power, "OnBatteryChanged",
131
dbus_g_proxy_connect_signal(dbus_proxy_power, "OnBatteryChanged",
132
G_CALLBACK(on_battery_changed), NULL, NULL);
134
gboolean bBatteryFound = cd_powermanager_find_battery();
135
if (! bBatteryFound) // on n'a pas trouve de batterie nous-meme.
137
gchar *cBatteryName = MY_DEFAULT_BATTERY_NAME; // utile ? si on a rien trouve, c'est surement qu'il n'y a pas de batterie non ?
138
cd_warning ("No battery were found");
140
/**cd_message ("Battery Name : %s", cBatteryName);
141
gchar *batteryPath = g_strdup_printf ("/org/freedesktop/Hal/devices/acpi_%s", cBatteryName);
142
cd_message (" batteryPath : %s", batteryPath);
143
dbus_proxy_battery = cairo_dock_create_new_system_proxy (
144
"org.freedesktop.Hal",
146
"org.freedesktop.Hal.Device"
148
cd_message (" acquisition de la batterie -> %x", dbus_proxy_battery);
149
myData.battery_present = (dbus_proxy_battery != NULL); // a priori toujours vrai.
150
g_free (batteryPath);
156
myData.battery_present = TRUE; // a verifier mais ca parait logique.
157
g_print ("batterie presente\n");
165
void dbus_disconnect_from_bus (void)
168
if (dbus_proxy_power != NULL)
170
dbus_g_proxy_disconnect_signal(dbus_proxy_power, "OnBatteryChanged",
171
G_CALLBACK(on_battery_changed), NULL);
172
cd_message ("OnBatteryChanged deconnecte");
173
g_object_unref (dbus_proxy_power);
174
dbus_proxy_power = NULL;
176
/**if (dbus_proxy_battery != NULL)
178
g_object_unref (dbus_proxy_battery);
179
dbus_proxy_battery = NULL;
181
if (dbus_proxy_stats != NULL)
183
g_object_unref (dbus_proxy_stats);
184
dbus_proxy_stats = NULL;
189
void on_battery_changed(DBusGProxy *proxy, gboolean onBattery, gpointer data)
191
g_print ("Dbus : batery changed\n");
192
if (myData.on_battery != onBattery)
200
#define go_to_next_line \
201
cCurLine = strchr (cCurVal, '\n'); \
202
g_return_val_if_fail (cCurLine != NULL, FALSE); \
206
#define jump_to_value \
207
cCurVal = strchr (cCurLine, ':'); \
208
g_return_val_if_fail (cCurVal != NULL, FALSE); \
210
while (*cCurVal == ' ') \
213
/*void get_on_battery(void)
215
dbus_g_proxy_call (dbus_proxy_power, "GetOnBattery", NULL,
217
G_TYPE_BOOLEAN, &myData.on_battery,
219
gchar *cContent = NULL;
221
GError *erreur = NULL;
222
g_file_get_contents(myData.cBatteryStateFilePath, &cContent, &length, &erreur);
225
cd_warning("powermanager : %s", erreur->message);
226
g_error_free(erreur);
228
myData.on_battery = FALSE;
232
gchar *cCurLine = cContent, *cCurVal = cContent;
237
myData.on_battery = (*cCurVal == 'd'); // discharging
243
gboolean update_stats(void)
245
if (myData.cBatteryStateFilePath == NULL)
246
cd_powermanager_find_battery ();
247
if (myData.cBatteryStateFilePath == NULL)
251
gchar *cContent = NULL;
253
GError *erreur = NULL;
254
g_file_get_contents(myData.cBatteryStateFilePath, &cContent, &length, &erreur);
257
cd_warning ("powermanager : %s", erreur->message);
258
g_error_free(erreur);
264
gchar *cCurLine = cContent, *cCurVal = cContent;
267
gboolean bBatteryPresent = (*cCurVal == 'y');
268
if (bBatteryPresent != myData.battery_present)
270
myData.battery_present = bBatteryPresent;
271
if (! bBatteryPresent)
273
g_print ("la batterie a ete enlevee\n");
280
g_print ("la batterie a ete connectee\n");
281
myData.previous_battery_time = 0;
282
myData.previous_battery_charge = 0;
284
for (k = 0; k < PM_NB_VALUES; k ++)
285
myData.fRateHistory[k] = 0;
286
myData.iCurrentIndex = 0;
287
myData.iIndexMax = 0;
290
go_to_next_line // "present: yes"
292
go_to_next_line // capacity state: ok
293
//Ajouter un warning si ce n'est pas le cas.
296
gboolean bOnBatteryOld = myData.on_battery;
297
myData.on_battery = (*cCurVal == 'd'); // discharging
298
if (bOnBatteryOld != myData.on_battery)
300
for (k = 0; k < PM_NB_VALUES; k ++)
301
myData.fRateHistory[k] = 0;
302
myData.iCurrentIndex = 0;
303
myData.iIndexMax = 0;
306
go_to_next_line // charging state: discharging
309
double fPresentRate = atoi (cCurVal); // 15000 mW OU 1400 mA
312
while (*cCurVal != ' ')
314
while (*cCurVal == ' ')
317
cd_warning ("PowerManager : expecting mA or mW as the present rate unit");
321
else if (*cCurVal == 'A')
324
cd_warning ("PowerManager : expecting A or W as the present rate unit");*/
326
go_to_next_line // present rate: 15000 mW
329
int iRemainingCapacity = atoi (cCurVal); // 47040 mWh
331
go_to_next_line // remaining capacity: 47040 mWh
334
int iPresentVoltage = atoi (cCurVal); // 15000 mV
336
myData.battery_charge = 100. * iRemainingCapacity / myData.iCapacity;
337
g_print ("myData.battery_charge : %.2f (%d / %d)\n", myData.battery_charge, iRemainingCapacity, myData.iCapacity);
338
if (myData.battery_charge > 100)
339
myData.battery_charge = 100;
340
if (myData.battery_charge < 0)
341
myData.battery_charge = 0.;
343
if (fPresentRate == 0 && myConfig.bUseDBusFallback)
345
cd_message ("on se rabat sur DBus");
346
myData.battery_time = get_stats("time");
348
else if (fPresentRate == 0 && myData.previous_battery_charge > 0)
350
fPresentRate = (myData.previous_battery_charge - myData.battery_charge) * 36. * myData.iCapacity / myConfig.iCheckInterval;
351
cd_message ("instant rate : %.2f -> %.2f => %.2f", myData.previous_battery_charge, myData.battery_charge, fPresentRate);
352
myData.fRateHistory[myData.iCurrentIndex] = fPresentRate;
354
double fMeanRate = 0.;
356
double fNextValue = 0.;
357
int iNbStackingValues = 0;
359
for (k = 0; k < myData.iIndexMax; k ++)
361
if (myData.iIndexMax == PM_NB_VALUES)
362
i = (myData.iCurrentIndex + 1 + k) % PM_NB_VALUES;
365
if (myData.fRateHistory[i] != 0)
369
nb_values += iNbStackingValues;
370
fMeanRate += fNextValue;
372
fNextValue = myData.fRateHistory[i];
373
iNbStackingValues = 1;
377
iNbStackingValues ++;
381
fPresentRate = fabs (fMeanRate) / nb_values;
382
cd_message ("mean calculated on %d value(s) : %.2f (current index:%d/%d)", nb_values, fPresentRate, myData.iCurrentIndex, myData.iIndexMax);
384
myData.iCurrentIndex ++;
385
if (myData.iIndexMax < PM_NB_VALUES)
386
myData.iIndexMax = myData.iCurrentIndex;
387
if (myData.iCurrentIndex == PM_NB_VALUES)
388
myData.iCurrentIndex = 0;
391
cd_message ("found fPresentRate = %.2f\n", fPresentRate);
394
//Utile de connaitre l'autonomie estimée quand la batterie est chargée
395
if (myData.on_battery || myData.battery_charge == 100) { //Decompte avant décharge complete
396
if (fPresentRate > 0) {
397
myData.battery_time = 3600. * iRemainingCapacity / fPresentRate;
400
myData.battery_time = 0.;
403
if (fPresentRate > 0) { //Decompte avant charge complete
404
myData.battery_time = 3600. * (myData.iCapacity - iRemainingCapacity) / fPresentRate;
407
myData.battery_time = 0.;
410
//cd_message ("PowerManager : On Battery:%d ; iCapacity:%dmWh ; iRemainingCapacity:%dmWh ; fPresentRate:%.2fmW ; iPresentVoltage:%dmV", myData.on_battery, myData.iCapacity, iRemainingCapacity, fPresentRate, iPresentVoltage);
417
charging state: discharging
418
present rate: 15000 mW
419
remaining capacity: 47040 mWh
420
present voltage: 15000 mV*/
424
int get_stats(gchar *dataType) // code repris de Gnome-power-manager.
426
if (dbus_proxy_stats == NULL)
427
dbus_proxy_stats = cairo_dock_create_new_session_proxy (
428
"org.freedesktop.PowerManagement",
429
"/org/freedesktop/PowerManagement/Statistics",
430
"org.freedesktop.PowerManagement.Statistics"
432
g_return_val_if_fail (dbus_proxy_stats != NULL, 0);
436
GPtrArray *ptrarray = NULL;
437
GType g_type_ptrarray;
439
int x, y, col; /// mettre des nom comprehensibles...
442
g_type_ptrarray = dbus_g_type_get_collection ("GPtrArray",
443
dbus_g_type_get_struct("GValueArray",
449
dbus_g_proxy_call (dbus_proxy_stats, "GetData", NULL,
451
G_TYPE_STRING, dataType,
453
g_type_ptrarray, &ptrarray,
455
g_return_val_if_fail (ptrarray != NULL, 0);
457
for (i=0; i< ptrarray->len; i++) /// il semble que seule la derniere valeur ait de l'interet ....
459
gva = (GValueArray *) g_ptr_array_index (ptrarray, i);
460
gv = g_value_array_get_nth (gva, 0);
461
x = g_value_get_int (gv);
463
gv = g_value_array_get_nth (gva, 1);
464
y = g_value_get_int (gv);
466
gv = g_value_array_get_nth (gva, 2);
467
col = g_value_get_int (gv);
469
g_value_array_free (gva);
471
g_ptr_array_free (ptrarray, TRUE);
473
cd_message ("PowerManager [%s]: %d", dataType, y);
474
return y; /// a quoi servent x et col alors ??
477
/**void detect_battery(void)
479
if (dbus_proxy_battery != NULL)
480
dbus_g_proxy_call (dbus_proxy_battery, "GetPropertyBoolean", NULL,
481
G_TYPE_STRING,"battery.present",
483
G_TYPE_BOOLEAN, &myData.battery_present,
487
void power_halt(void)
489
dbus_g_proxy_call (dbus_proxy_power, "Shutdown", NULL,
493
void power_hibernate(void)
495
dbus_g_proxy_call (dbus_proxy_power, "Hibernate", NULL,
499
void power_suspend(void)
501
dbus_g_proxy_call (dbus_proxy_power, "Suspend", NULL,
505
void power_reboot(void)
507
dbus_g_proxy_call (dbus_proxy_power, "Reboot", NULL,