25
25
#include "powermanager-draw.h"
26
26
#include "powermanager-struct.h"
27
#include "powermanager-proc-acpi.h"
28
#include "powermanager-sys-class.h"
27
29
#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;
31
$ qdbus org.kde.powerdevil /modules/powerdevil # tab tab
33
org.kde.PowerDevil.brightnessChanged
34
org.kde.PowerDevil.getSupportedSuspendMethods
35
org.kde.PowerDevil.lidClosed
36
org.kde.PowerDevil.profileChanged
37
org.kde.PowerDevil.refreshStatus
38
org.kde.PowerDevil.reloadAndStream
39
org.kde.PowerDevil.setBrightness
40
org.kde.PowerDevil.setPowerSave
41
org.kde.PowerDevil.setProfile
42
org.kde.PowerDevil.stateChanged
43
org.kde.PowerDevil.streamData
44
org.kde.PowerDevil.suspend
45
org.kde.PowerDevil.turnOffScreen */
48
get /org/freedesktop/PowerManagement -> ko => display broken.svg, abort
49
get /org/freedesktop/PowerManagement/Widget -> ko => display ourselves
50
get /org/freedesktop/PowerManagement/Statistics -> ko => if Widget: use it, else: display broken.svg, abort (possibly use a fallback low-level method)
52
representation: gauge/graph/icons/Widget
54
title: Widget, else: "time until discharge/charge: xxmn / xhyy (xx%)"
55
quick-info: none/charge "xx%"/time "xhyy"
58
#define CD_POWER_MANAGER_ADDR "org.freedesktop.PowerManagement"
59
#define CD_POWER_MANAGER_OBJ "org/freedesktop/PowerManagement"
60
#define CD_POWER_MANAGER_IFACE "org.freedesktop.PowerManagement"
61
#define CD_POWER_MANAGER_STATS_OBJ "org/freedesktop/PowerManagement/Statistics"
62
#define CD_POWER_MANAGER_STATS_IFACE "org.freedesktop.PowerManagement.Statistics"
63
#define CD_POWER_MANAGER_WIDGET_IFACE "org.freedesktop.PowerManagement.Widget "
64
#define CD_POWER_MANAGER_WIDGET_OBJ "/org/freedesktop/PowerManagement/Widget"
66
static DBusGProxyCall *s_pDetectPMCall = NULL;
67
static DBusGProxyCall *s_pGetStateCall = NULL;
68
static DBusGProxyCall *s_pGetStatsCall = NULL;
69
static DBusGProxyCall *s_pGetDescriptionCall = NULL;
70
static DBusGProxyCall *s_pGetIconCall = NULL;
36
71
static void on_battery_changed(DBusGProxy *proxy, gboolean onBattery, gpointer data);
39
gboolean cd_powermanager_find_battery (void)
41
GError *erreur = NULL;
42
GDir *dir = g_dir_open (MY_BATTERY_DIR, 0, &erreur);
45
cd_warning ("powermanager : %s", erreur->message);
46
g_error_free (erreur);
50
GString *sBatteryStateFilePath = g_string_new ("");
51
gchar *cContent = NULL, *cPresentLine;
53
const gchar *cBatteryName;
54
gboolean bBatteryFound = FALSE;
57
cBatteryName = g_dir_read_name (dir);
58
if (cBatteryName == NULL)
61
g_string_printf (sBatteryStateFilePath, "%s/%s/info", MY_BATTERY_DIR, cBatteryName);
63
cd_message (" examen de la batterie '%s' ...", sBatteryStateFilePath->str);
64
g_file_get_contents(sBatteryStateFilePath->str, &cContent, &length, &erreur);
67
cd_warning("powermanager : %s", erreur->message);
73
gchar *str = strchr (cContent, '\n'); // "present: yes"
78
if (g_strstr_len (cContent, -1, "yes") != NULL) // on l'a trouvee !
81
myData.cBatteryStateFilePath = g_strdup_printf ("%s/%s/state", MY_BATTERY_DIR, cBatteryName);
84
gchar *str2 = strchr (str, ':');
88
myData.iCapacity = atoi (str2);
89
cd_debug ("Design capacity : %d mWsh\n", myData.iCapacity);
92
gchar *str3 = strchr (str2, ':');
96
myData.iCapacity = atoi (str3);
97
cd_debug ("Last full capacity : %d mWsh\n", myData.iCapacity);
102
cd_debug ("cette batterie (%s) n'est pas presente.\n", cBatteryName);
108
while (! bBatteryFound);
110
return bBatteryFound;
113
gboolean dbus_connect_to_bus (void)
117
if (cairo_dock_dbus_is_enabled ())
119
dbus_proxy_power = cairo_dock_create_new_session_proxy (
120
"org.freedesktop.PowerManagement",
121
"/org/freedesktop/PowerManagement",
122
"org.freedesktop.PowerManagement"
124
if (dbus_proxy_power == NULL)
127
/**dbus_proxy_stats = cairo_dock_create_new_session_proxy (
128
"org.freedesktop.PowerManagement",
129
"/org/freedesktop/PowerManagement/Statistics",
130
"org.freedesktop.PowerManagement.Statistics");*/
132
dbus_g_proxy_add_signal(dbus_proxy_power, "OnBatteryChanged",
136
dbus_g_proxy_connect_signal(dbus_proxy_power, "OnBatteryChanged",
137
G_CALLBACK(on_battery_changed), NULL, NULL);
138
cd_debug ("connected to OnBatteryChanged\n");
140
/*gboolean bBatteryFound = cd_powermanager_find_battery();
141
if (! bBatteryFound) // on n'a pas trouve de batterie nous-meme.
143
gchar *cBatteryName = MY_DEFAULT_BATTERY_NAME; // utile ? si on a rien trouve, c'est surement qu'il n'y a pas de batterie non ?
144
cd_warning ("No battery were found");
146
cd_message ("Battery Name : %s", cBatteryName);
147
gchar *batteryPath = g_strdup_printf ("/org/freedesktop/Hal/devices/acpi_%s", cBatteryName);
148
cd_message (" batteryPath : %s", batteryPath);
149
dbus_proxy_battery = cairo_dock_create_new_system_proxy (
150
"org.freedesktop.Hal",
152
"org.freedesktop.Hal.Device"
154
cd_message (" acquisition de la batterie -> %x", dbus_proxy_battery);
155
myData.battery_present = (dbus_proxy_battery != NULL); // a priori toujours vrai.
156
g_free (batteryPath);
162
myData.battery_present = TRUE; // a verifier mais ca parait logique.
163
cd_debug ("batterie presente\n");
171
void dbus_disconnect_from_bus (void)
174
if (dbus_proxy_power != NULL)
176
dbus_g_proxy_disconnect_signal(dbus_proxy_power, "OnBatteryChanged",
177
G_CALLBACK(on_battery_changed), NULL);
178
cd_message ("OnBatteryChanged deconnecte");
179
g_object_unref (dbus_proxy_power);
180
dbus_proxy_power = NULL;
182
/**if (dbus_proxy_battery != NULL)
184
g_object_unref (dbus_proxy_battery);
185
dbus_proxy_battery = NULL;
187
if (dbus_proxy_stats != NULL)
189
g_object_unref (dbus_proxy_stats);
190
dbus_proxy_stats = NULL;
195
static void on_battery_changed(DBusGProxy *proxy, gboolean onBattery, gpointer data)
198
cd_debug ("Dbus : battery changed\n");
199
if (myData.on_battery != onBattery)
208
#define go_to_next_line \
209
cCurLine = strchr (cCurVal, '\n'); \
210
g_return_val_if_fail (cCurLine != NULL, FALSE); \
214
#define jump_to_value \
215
cCurVal = strchr (cCurLine, ':'); \
216
g_return_val_if_fail (cCurVal != NULL, FALSE); \
218
while (*cCurVal == ' ') \
221
/*void get_on_battery(void)
223
dbus_g_proxy_call (dbus_proxy_power, "GetOnBattery", NULL,
225
G_TYPE_BOOLEAN, &myData.on_battery,
230
static int get_stats(const gchar *dataType) // code repris de Gnome-power-manager.
232
if (dbus_proxy_stats == NULL)
233
dbus_proxy_stats = cairo_dock_create_new_session_proxy (
234
"org.freedesktop.PowerManagement",
235
"/org/freedesktop/PowerManagement/Statistics",
236
"org.freedesktop.PowerManagement.Statistics"
238
g_return_val_if_fail (dbus_proxy_stats != NULL, 0);
242
GPtrArray *ptrarray = NULL;
243
GType g_type_ptrarray;
245
int x, y=0, col; /// mettre des nom comprehensibles...
248
g_type_ptrarray = dbus_g_type_get_collection ("GPtrArray",
78
static void on_battery_changed (DBusGProxy *proxy, gboolean bOnBattery, gpointer data)
81
cd_debug ("%s (%d)", __func__, bOnBattery);
83
// store the new state
84
myData.bOnBattery = bOnBattery;
92
static void on_description_changed (DBusGProxy *proxy, const gchar *cDescription, gpointer data)
95
cd_debug ("%s (%s)", __func__, cDescription);
96
CD_APPLET_SET_NAME_FOR_MY_ICON (cDescription);
100
static void on_icon_changed (DBusGProxy *proxy, const gchar *cImage, gpointer data)
103
cd_debug ("%s (%s)", __func__, cImage);
104
if (myData.pProxyStats == NULL)
105
CD_APPLET_SET_IMAGE_ON_MY_ICON (cImage); // the image represents both the current charge and the state.
114
static void _on_get_state (DBusGProxy *proxy, DBusGProxyCall *call_id, CairoDockModuleInstance *myApplet)
117
cd_debug ("%s ()", __func__);
118
s_pGetStateCall = NULL;
120
GError *erreur = NULL;
122
// fetch the state from the request result.
123
gboolean bSuccess = dbus_g_proxy_end_call (proxy,
126
G_TYPE_BOOLEAN, &bOnBattery,
130
cd_debug (" couldn't get the current state (%s)", erreur->message);
131
g_error_free (erreur);
133
myData.bOnBattery = FALSE;
137
myData.bOnBattery = bOnBattery;
148
void cd_get_current_state (void)
150
if (s_pGetStateCall != NULL)
153
s_pGetStateCall = dbus_g_proxy_begin_call (myData.pProxyPower,
155
(DBusGProxyCallNotify)_on_get_state,
157
(GDestroyNotify) NULL,
161
static void _on_get_description (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer data)
164
cd_debug ("%s ()", __func__);
165
s_pGetDescriptionCall = NULL;
166
gchar *cDescription = NULL;
167
GError *erreur = NULL;
169
// fetch the state from the request result.
170
gboolean bSuccess = dbus_g_proxy_end_call (proxy,
173
G_TYPE_STRING, &cDescription,
177
cd_debug (" couldn't get the current description (%s)", erreur->message);
178
g_error_free (erreur);
180
// don't try this method any more.
181
if (myData.pProxyWidget)
183
g_object_unref (myData.pProxyWidget);
184
myData.pProxyWidget = NULL;
189
CD_APPLET_SET_NAME_FOR_MY_ICON (cDescription);
192
g_free (cDescription);
195
void cd_get_widget_description (void)
197
if (s_pGetDescriptionCall != NULL || myData.pProxyWidget == NULL)
199
s_pGetDescriptionCall = dbus_g_proxy_begin_call (myData.pProxyWidget,
201
(DBusGProxyCallNotify)_on_get_description,
203
(GDestroyNotify) NULL,
207
static void _on_get_icon (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer data)
210
cd_debug ("%s ()", __func__);
211
s_pGetIconCall = NULL;
212
gchar *cImage = NULL;
213
GError *erreur = NULL;
215
// fetch the state from the request result.
216
gboolean bSuccess = dbus_g_proxy_end_call (proxy,
219
G_TYPE_STRING, &cImage,
223
cd_debug (" couldn't get the current image (%s)", erreur->message);
224
g_error_free (erreur);
226
// don't try this method any more.
227
if (myData.pProxyWidget)
229
g_object_unref (myData.pProxyWidget);
230
myData.pProxyWidget = NULL;
235
CD_APPLET_SET_IMAGE_ON_MY_ICON (cImage);
241
void cd_get_widget_icon (void)
243
if (s_pGetIconCall != NULL || myData.pProxyWidget == NULL)
245
s_pGetIconCall = dbus_g_proxy_begin_call (myData.pProxyWidget,
247
(DBusGProxyCallNotify)_on_get_icon,
249
(GDestroyNotify) NULL,
253
static void _cd_get_one_stat (const gchar *cDataType, gboolean bFirst);
254
static void _on_get_data (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer data)
257
cd_debug ("%s ()", __func__);
258
gboolean bFirstRound = (data != NULL);
259
s_pGetStatsCall = NULL;
261
GError *erreur = NULL;
263
// fetch the data from the request result.
265
GType g_type_ptrarray = dbus_g_type_get_collection ("GPtrArray",
249
266
dbus_g_type_get_struct("GValueArray",
253
270
G_TYPE_INVALID));
255
dbus_g_proxy_call (dbus_proxy_stats, "GetData", NULL,
257
G_TYPE_STRING, dataType,
271
GPtrArray *ptrarray = NULL;
272
gboolean bSuccess = dbus_g_proxy_end_call (proxy,
259
275
g_type_ptrarray, &ptrarray,
261
g_return_val_if_fail (ptrarray != NULL, 0);
263
for (i=0; i< ptrarray->len; i++) /// il semble que seule la derniere valeur ait de l'interet ....
265
gva = (GValueArray *) g_ptr_array_index (ptrarray, i);
266
gv = g_value_array_get_nth (gva, 0);
267
x = g_value_get_int (gv);
269
gv = g_value_array_get_nth (gva, 1);
270
y = g_value_get_int (gv);
272
gv = g_value_array_get_nth (gva, 2);
273
col = g_value_get_int (gv);
275
g_value_array_free (gva);
277
g_ptr_array_free (ptrarray, TRUE);
279
cd_message ("PowerManager [%s]: %d", dataType, y);
280
return y; /// a quoi servent x et col alors ??
282
gboolean update_stats(void)
285
//\_______________ On recupere le contenu du buffer de la batterie.
286
if (myData.cBatteryStateFilePath == NULL)
287
cd_powermanager_find_battery ();
288
if (myData.cBatteryStateFilePath == NULL)
289
CD_APPLET_LEAVE (TRUE);
292
gchar *cContent = NULL;
294
GError *erreur = NULL;
295
g_file_get_contents(myData.cBatteryStateFilePath, &cContent, &length, &erreur);
296
277
if (erreur != NULL)
298
cd_warning ("powermanager : %s", erreur->message);
299
g_error_free(erreur);
279
cd_debug (" couldn't get the current data (%s)", erreur->message);
280
g_error_free (erreur);
301
CD_APPLET_LEAVE (FALSE);
304
CD_APPLET_LEAVE_IF_FAIL (cContent, FALSE);
305
//g_return_val_if_fail (cContent, FALSE);
306
gchar *cCurLine = cContent, *cCurVal = cContent;
308
//\_______________ On gere la presence de la batterie.
310
gboolean bBatteryPresent = (*cCurVal == 'y');
311
if (bBatteryPresent != myData.battery_present) // la batterie vient d'etre (de)branchee.
313
myData.battery_present = bBatteryPresent;
314
if (! bBatteryPresent)
316
cd_debug ("la batterie a ete enlevee\n");
319
CD_APPLET_LEAVE (TRUE);
323
// on remet a zero l'historique.
324
cd_debug ("la batterie a ete connectee\n");
325
myData.previous_battery_time = 0;
326
myData.previous_battery_charge = 0;
328
for (k = 0; k < PM_NB_VALUES; k ++)
329
myData.fRateHistory[k] = 0;
330
myData.iCurrentIndex = 0;
331
myData.iIndexMax = 0;
334
go_to_next_line // "present: yes"
336
go_to_next_line // capacity state: ok
337
///Ajouter un warning si ce n'est pas le cas...
339
//\_______________ On gere le (de)branchage de la batterie.
341
gboolean bOnBatteryOld = myData.on_battery;
342
myData.on_battery = (*cCurVal == 'd'); // discharging
343
if (bOnBatteryOld != myData.on_battery) // (de)branchage de la batterie.
345
for (k = 0; k < PM_NB_VALUES; k ++) // on remet a zero l'historique.
346
myData.fRateHistory[k] = 0;
347
myData.iCurrentIndex = 0;
348
myData.iIndexMax = 0;
351
go_to_next_line // charging state: discharging
353
//\_______________ On recupere le taux de (de)charge.
355
double fPresentRate = atoi (cCurVal); // 15000 mW OU 1400 mA
358
while (*cCurVal != ' ')
360
while (*cCurVal == ' ')
363
cd_warning ("PowerManager : expecting mA or mW as the present rate unit");
367
else if (*cCurVal == 'A')
370
cd_warning ("PowerManager : expecting A or W as the present rate unit");*/
372
go_to_next_line // present rate: 15000 mW
375
int iRemainingCapacity = atoi (cCurVal); // 47040 mWh
377
go_to_next_line // remaining capacity: 47040 mWh
380
int iPresentVoltage = atoi (cCurVal); // 15000 mV
382
myData.battery_charge = 100. * iRemainingCapacity / myData.iCapacity;
383
cd_debug ("myData.battery_charge : %.2f (%d / %d)", myData.battery_charge, iRemainingCapacity, myData.iCapacity);
384
if (myData.battery_charge > 100)
385
myData.battery_charge = 100;
386
if (myData.battery_charge < 0)
387
myData.battery_charge = 0.;
389
//\_______________ On calcule le taux de variation par derive de la charge s'il n'est pas présent dans le buffer.
390
if (fPresentRate == 0 && myConfig.bUseDBusFallback)
392
cd_message ("on se rabat sur DBus");
393
myData.battery_time = get_stats("time");
395
else if (fPresentRate == 0 && myData.previous_battery_charge > 0)
397
fPresentRate = (myData.previous_battery_charge - myData.battery_charge) * 36. * myData.iCapacity / myConfig.iCheckInterval;
398
cd_message ("instant rate : %.2f -> %.2f => %.2f", myData.previous_battery_charge, myData.battery_charge, fPresentRate);
399
myData.fRateHistory[myData.iCurrentIndex] = fPresentRate;
401
double fMeanRate = 0.;
403
double fNextValue = 0.;
404
int iNbStackingValues = 0;
406
for (k = 0; k < myData.iIndexMax; k ++)
408
if (myData.iIndexMax == PM_NB_VALUES)
409
i = (myData.iCurrentIndex + 1 + k) % PM_NB_VALUES;
412
if (myData.fRateHistory[i] != 0)
416
nb_values += iNbStackingValues;
417
fMeanRate += fNextValue;
419
fNextValue = myData.fRateHistory[i];
420
iNbStackingValues = 1;
424
iNbStackingValues ++;
428
fPresentRate = fabs (fMeanRate) / nb_values;
429
cd_message ("mean calculated on %d value(s) : %.2f (current index:%d/%d)", nb_values, fPresentRate, myData.iCurrentIndex, myData.iIndexMax);
431
myData.iCurrentIndex ++;
432
if (myData.iIndexMax < PM_NB_VALUES)
433
myData.iIndexMax = myData.iCurrentIndex;
434
if (myData.iCurrentIndex == PM_NB_VALUES)
435
myData.iCurrentIndex = 0;
438
cd_message ("found fPresentRate = %.2f\n", fPresentRate);
440
//\_______________ On enregistre les dernieres valeurs si elles ont beaucoup change.
441
if (fPresentRate > 0)
443
if (myData.on_battery)
445
myData.fDischargeMeanRate = (myData.fDischargeMeanRate * myData.iNbDischargeMeasures + fPresentRate) / (myData.iNbDischargeMeasures + 1);
446
myData.iNbDischargeMeasures ++;
447
cd_debug ("fDischargeMeanRate : %.2f (%d)\n", myData.fDischargeMeanRate, myData.iNbDischargeMeasures);
449
if (fabs (myConfig.fLastDischargeMeanRate - myData.fDischargeMeanRate) > 30) // l'ecart avec la valeur stockee en conf est devenue grande, on met a jour cette derniere.
451
myConfig.fLastDischargeMeanRate = myData.fDischargeMeanRate;
452
cairo_dock_update_conf_file (CD_APPLET_MY_CONF_FILE,
453
G_TYPE_DOUBLE, "Configuration", "discharge rate", myConfig.fLastDischargeMeanRate,
459
myData.fChargeMeanRate = (myData.fChargeMeanRate * myData.iNbChargeMeasures + fPresentRate) / (myData.iNbChargeMeasures + 1);
460
myData.iNbChargeMeasures ++;
461
cd_debug ("fChargeMeanRate : %.2f (%d)\n", myData.fChargeMeanRate, myData.iNbChargeMeasures);
462
if (fabs (myConfig.fLastChargeMeanRate - myData.fChargeMeanRate) > 30) // l'ecart avec la valeur stockee en conf est devenue grande, on met a jour cette derniere.
464
myConfig.fLastChargeMeanRate = myData.fChargeMeanRate;
465
cairo_dock_update_conf_file (CD_APPLET_MY_CONF_FILE,
466
G_TYPE_DOUBLE, "Configuration", "charge rate", myConfig.fLastChargeMeanRate,
471
else if (myData.on_battery || myData.battery_charge < 99.9)
473
cd_debug ("no rate, using last know values : %.2f ; %.2f\n", myConfig.fLastDischargeMeanRate, myConfig.fLastChargeMeanRate);
474
fPresentRate = (myData.on_battery ? myConfig.fLastDischargeMeanRate : myConfig.fLastChargeMeanRate);
477
//Utile de connaitre l'autonomie estimée quand la batterie est chargée
478
if (myData.battery_charge > 99.9) // on evite le point a 100, trop instable
480
myData.battery_time = 0.;
482
else if (myData.on_battery/** || myData.battery_charge == 100*/) { //Decompte avant décharge complete
483
if (fPresentRate > 0) {
484
myData.battery_time = 3600. * iRemainingCapacity / fPresentRate;
487
myData.battery_time = 0.;
490
if (fPresentRate > 0) { //Decompte avant charge complete
491
myData.battery_time = 3600. * (myData.iCapacity - iRemainingCapacity) / fPresentRate;
494
myData.battery_time = 0.;
497
//cd_message ("PowerManager : On Battery:%d ; iCapacity:%dmWh ; iRemainingCapacity:%dmWh ; fPresentRate:%.2fmW ; iPresentVoltage:%dmV", myData.on_battery, myData.iCapacity, iRemainingCapacity, fPresentRate, iPresentVoltage);
500
//\_______________ On met a jour l'icone.
282
// don't try this method any more.
283
g_object_unref (myData.pProxyStats);
284
myData.pProxyStats = NULL;
285
// instead, rely on the widget icon.
286
cd_get_widget_icon ();
291
cd_debug (" got %d values", ptrarray->len);
292
GValueArray *va = (GValueArray *) g_ptr_array_index (ptrarray, ptrarray->len-1); // get the latest data
293
GValue *v = g_value_array_get_nth (va, 2); // (x, y, data)
294
if (v && G_VALUE_HOLDS_INT (v))
295
val = g_value_get_int (v);
296
cd_debug (" data: %d", val);
298
g_ptr_array_foreach (ptrarray, (GFunc)g_value_array_free, NULL);
299
g_ptr_array_free (ptrarray, TRUE);
304
cd_debug (" got percentage: %d%%\n", (int)val);
305
myData.iPercentage = val;
306
_cd_get_one_stat ("time", FALSE);
310
cd_debug (" got time: %d%%\n", (int)val);
317
static void _cd_get_one_stat (const gchar *cDataType, gboolean bFirst)
319
if (s_pGetStatsCall != NULL || myData.pProxyStats == NULL)
321
s_pGetStatsCall = dbus_g_proxy_begin_call (myData.pProxyStats,
323
(DBusGProxyCallNotify)_on_get_data,
324
GINT_TO_POINTER (bFirst),
325
(GDestroyNotify) NULL,
326
G_TYPE_UINT, 0, // we just want the latest data
327
G_TYPE_STRING, cDataType,
330
void cd_get_stats_from_bus (void)
333
_cd_get_one_stat ("percentage", TRUE);
341
static void _on_start_service (DBusGProxy *proxy, guint status, GError *error, gpointer data) // just for info
343
if (status != DBUS_START_REPLY_SUCCESS && status != DBUS_START_REPLY_ALREADY_RUNNING) // service is not started.
345
if (error != NULL) // couldn't start the service
346
cd_debug ("Unable to start the Power-Manager service (%s)", error->message);
348
cd_debug ("Unable to start the Power-Manager service (got status %d)", status);
351
cd_debug ("Power-Manager service has started");
354
static void _on_power_manager_owner_changed (gboolean bOwned, gpointer data)
357
cd_debug ("Power-Manager service is on the bus (%d)", bOwned);
360
// set up a proxy to the Service
361
myData.pProxyPower = cairo_dock_create_new_session_proxy (
362
CD_POWER_MANAGER_ADDR,
363
CD_POWER_MANAGER_OBJ,
364
CD_POWER_MANAGER_IFACE);
366
dbus_g_proxy_add_signal(myData.pProxyPower, "OnBatteryChanged",
369
dbus_g_proxy_connect_signal(myData.pProxyPower, "OnBatteryChanged",
370
G_CALLBACK(on_battery_changed), NULL, NULL);
372
// set up a proxy to the optionnal Statistics object
373
myData.pProxyStats = cairo_dock_create_new_session_proxy (
374
CD_POWER_MANAGER_ADDR,
375
CD_POWER_MANAGER_STATS_OBJ,
376
CD_POWER_MANAGER_STATS_IFACE);
378
// set up a proxy to the optionnal Widget object
379
myData.pProxyWidget = cairo_dock_create_new_session_proxy (
380
CD_POWER_MANAGER_ADDR,
381
CD_POWER_MANAGER_WIDGET_OBJ,
382
CD_POWER_MANAGER_WIDGET_IFACE);
384
dbus_g_proxy_add_signal(myData.pProxyWidget, "DescriptionChanged",
387
dbus_g_proxy_connect_signal(myData.pProxyPower, "DescriptionChanged",
388
G_CALLBACK(on_description_changed), NULL, NULL);
390
dbus_g_proxy_add_signal(myData.pProxyWidget, "IconChanged",
393
dbus_g_proxy_connect_signal(myData.pProxyPower, "IconChanged",
394
G_CALLBACK(on_icon_changed), NULL, NULL);
396
// get the current state.
397
if (myData.cBatteryStateFilePath == NULL) // couldn't get the state from files, so get it now from dbus.
398
cd_get_current_state ();
400
// get the current description.
401
cd_get_widget_description ();
403
else // no more service on the bus.
405
g_object_unref (myData.pProxyPower);
406
myData.pProxyPower = NULL;
408
if (myData.pProxyStats)
410
g_object_unref (myData.pProxyStats);
411
myData.pProxyStats = NULL;
414
if (myData.pProxyWidget)
416
g_object_unref (myData.pProxyWidget);
417
myData.pProxyWidget = NULL;
422
static void _on_detect_power_manager (gboolean bPresent, gpointer data)
425
cd_debug ("Power-Manager is present: %d", bPresent);
426
s_pDetectPMCall = NULL;
429
_on_power_manager_owner_changed (TRUE, NULL);
431
else // not present, maybe the service is not started => try starting it.
433
cd_debug (" try to start the Power-Manager service...");
434
DBusGProxy *dbus_proxy = cairo_dock_get_main_proxy ();
435
org_freedesktop_DBus_start_service_by_name_async (dbus_proxy,
436
CD_POWER_MANAGER_ADDR,
441
// until it's launched, get the current values from files.
446
// now that we know if we can use Dbus or not, get the current values with what we have found since the beginning.
505
charging state: discharging
506
present rate: 15000 mW
507
remaining capacity: 47040 mWh
508
present voltage: 15000 mV*/
509
CD_APPLET_LEAVE (TRUE);
513
/**void detect_battery(void)
515
if (dbus_proxy_battery != NULL)
516
dbus_g_proxy_call (dbus_proxy_battery, "GetPropertyBoolean", NULL,
517
G_TYPE_STRING,"battery.present",
519
G_TYPE_BOOLEAN, &myData.battery_present,
450
// and periodically update the data.
451
if (myData.checkLoop == 0)
452
myData.checkLoop = g_timeout_add_seconds (myConfig.iCheckInterval, (GSourceFunc) update_stats_loop, (gpointer) NULL);
454
// watch whenever the Service goes up or down.
455
cairo_dock_watch_dbus_name_owner (CD_POWER_MANAGER_ADDR,
456
(CairoDockDbusNameOwnerChangedFunc) _on_power_manager_owner_changed,
460
void cd_detect_power_manager_on_bus (void)
462
s_pDetectPMCall = cairo_dock_dbus_detect_application_async (CD_POWER_MANAGER_ADDR,
463
(CairoDockOnAppliPresentOnDbus) _on_detect_power_manager,
468
void cd_disconnect_from_bus (void)
470
// cancel current calls
471
if (s_pDetectPMCall != NULL)
473
dbus_g_proxy_cancel_call (myData.pProxyPower, s_pDetectPMCall);
474
s_pDetectPMCall = NULL;
477
if (s_pGetStateCall != NULL)
479
dbus_g_proxy_cancel_call (myData.pProxyPower, s_pGetStateCall);
480
s_pGetStateCall = NULL;
483
if (s_pGetStatsCall != NULL)
485
dbus_g_proxy_cancel_call (myData.pProxyStats, s_pGetStatsCall);
486
s_pGetStatsCall = NULL;
489
if (s_pGetDescriptionCall != NULL)
491
dbus_g_proxy_cancel_call (myData.pProxyWidget, s_pGetDescriptionCall);
492
s_pGetDescriptionCall = NULL;
495
if (s_pGetIconCall != NULL)
497
dbus_g_proxy_cancel_call (myData.pProxyWidget, s_pGetIconCall);
498
s_pGetIconCall = NULL;
503
g_object_unref (myData.pProxyPower);
504
myData.pProxyPower = NULL;
506
if (myData.pProxyStats)
508
g_object_unref (myData.pProxyStats);
509
myData.pProxyStats = NULL;
512
if (myData.pProxyWidget)
514
g_object_unref (myData.pProxyWidget);
515
myData.pProxyWidget = NULL;
519
gboolean update_stats (void)
521
if (myData.cBatteryStateFilePath != NULL) // found the battery, get the info from files and compute ourselves.
523
if (myData.bProcAcpiFound)
524
cd_get_stats_from_proc_acpi ();
526
cd_get_stats_from_sys_class ();
528
else if (myData.pProxyStats != NULL)
530
cd_get_stats_from_bus ();
539
gboolean update_stats_loop (void)
543
gboolean bContinue = update_stats ();
548
myData.checkLoop = 0;
549
CD_APPLET_LEAVE (bContinue);
523
557
void power_halt(void)
525
dbus_g_proxy_call (dbus_proxy_power, "Shutdown", NULL,
559
dbus_g_proxy_call (myData.pProxyPower, "Shutdown", NULL,
529
563
void power_hibernate(void)
531
dbus_g_proxy_call (dbus_proxy_power, "Hibernate", NULL,
565
dbus_g_proxy_call (myData.pProxyPower, "Hibernate", NULL,
535
569
void power_suspend(void)
537
dbus_g_proxy_call (dbus_proxy_power, "Suspend", NULL,
571
dbus_g_proxy_call (myData.pProxyPower, "Suspend", NULL,
541
575
void power_reboot(void)
543
dbus_g_proxy_call (dbus_proxy_power, "Reboot", NULL,
577
dbus_g_proxy_call (myData.pProxyPower, "Reboot", NULL,