~ubuntu-branches/ubuntu/saucy/cairo-dock-plug-ins/saucy

« back to all changes in this revision

Viewing changes to powermanager/src/powermanager-dbus.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2009-08-26 21:07:39 UTC
  • Revision ID: james.westby@ubuntu.com-20090826210739-gyjuuqezrzuluao4
Tags: upstream-2.0.8.1
Import upstream version 2.0.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
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.
 
11
*
 
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/>.
 
18
*/
 
19
 
 
20
#include <math.h>
 
21
#include <string.h>
 
22
#include <dirent.h>
 
23
#include <dbus/dbus-glib.h>
 
24
 
 
25
#include "powermanager-draw.h"
 
26
#include "powermanager-struct.h"
 
27
#include "powermanager-dbus.h"
 
28
 
 
29
#define MY_BATTERY_DIR "/proc/acpi/battery"
 
30
#define MY_DEFAULT_BATTERY_NAME "BAT0"
 
31
 
 
32
static DBusGProxy *dbus_proxy_power = NULL;
 
33
static DBusGProxy *dbus_proxy_stats = NULL;
 
34
static DBusGProxy *dbus_proxy_battery = NULL;
 
35
 
 
36
 
 
37
static gboolean cd_powermanager_find_battery (void) {
 
38
        GError *erreur = NULL;
 
39
        GDir *dir = g_dir_open (MY_BATTERY_DIR, 0, &erreur);
 
40
        if (erreur != NULL)
 
41
        {
 
42
                cd_warning ("powermanager : %s", erreur->message);
 
43
                g_error_free (erreur);
 
44
                return FALSE;
 
45
        }
 
46
        
 
47
        GString *sBatteryStateFilePath = g_string_new ("");
 
48
        gchar *cContent = NULL, *cPresentLine;
 
49
        gsize length=0;
 
50
        const gchar *cBatteryName;
 
51
        gboolean bBatteryFound = FALSE;
 
52
        do
 
53
        {
 
54
                cBatteryName = g_dir_read_name (dir);
 
55
                if (cBatteryName == NULL)
 
56
                        break ;
 
57
                
 
58
                g_string_printf (sBatteryStateFilePath, "%s/%s/info", MY_BATTERY_DIR, cBatteryName);
 
59
                length=0;
 
60
                cd_message ("  examen de la batterie '%s' ...", sBatteryStateFilePath->str);
 
61
                g_file_get_contents(sBatteryStateFilePath->str, &cContent, &length, &erreur);
 
62
                if (erreur != NULL)
 
63
                {
 
64
                        cd_warning("powermanager : %s", erreur->message);
 
65
                        g_error_free(erreur);
 
66
                        erreur = NULL;
 
67
                }
 
68
                else
 
69
                {
 
70
                        gchar *str = strchr (cContent, '\n');  // "present:    yes"
 
71
                        if (str != NULL)
 
72
                        {
 
73
                                *str = '\0';
 
74
                                
 
75
                                if (g_strstr_len (cContent, -1, "yes") != NULL)  // on l'a trouvee !
 
76
                                {
 
77
                                        bBatteryFound = TRUE;
 
78
                                        myData.cBatteryStateFilePath = g_strdup_printf ("%s/%s/state", MY_BATTERY_DIR, cBatteryName);
 
79
                                        
 
80
                                        str ++;
 
81
                                        gchar *str2 = strchr (str, ':');
 
82
                                        if (str2 != NULL)
 
83
                                        {
 
84
                                                str2 ++;
 
85
                                                myData.iCapacity = atoi (str2);
 
86
                                                g_print ("Design capacity : %d mWsh\n", myData.iCapacity);
 
87
                                        }
 
88
                                        
 
89
                                        gchar *str3 = strchr (str2, ':');
 
90
                                        if (str3 != NULL)
 
91
                                        {
 
92
                                                str3 ++;
 
93
                                                myData.iCapacity = atoi (str3);
 
94
                                                g_print ("Last full capacity : %d mWsh\n", myData.iCapacity);
 
95
                                        }
 
96
                                }
 
97
                                else
 
98
                                {
 
99
                                        g_print ("cette batterie (%s) n'est pas presente.\n", cBatteryName);
 
100
                                }
 
101
                        }
 
102
                }
 
103
                g_free (cContent);
 
104
        }
 
105
        while (! bBatteryFound);
 
106
        g_dir_close (dir);
 
107
        return bBatteryFound;
 
108
}
 
109
 
 
110
gboolean dbus_connect_to_bus (void)
 
111
{
 
112
        cd_message ("");
 
113
        
 
114
        if (cairo_dock_bdus_is_enabled ())
 
115
        {
 
116
                dbus_proxy_power = cairo_dock_create_new_session_proxy (
 
117
                        "org.freedesktop.PowerManagement",
 
118
                        "/org/freedesktop/PowerManagement",
 
119
                        "org.freedesktop.PowerManagement"
 
120
                );
 
121
 
 
122
                /**dbus_proxy_stats = cairo_dock_create_new_session_proxy (
 
123
                        "org.freedesktop.PowerManagement",
 
124
                        "/org/freedesktop/PowerManagement/Statistics",
 
125
                        "org.freedesktop.PowerManagement.Statistics");*/
 
126
                
 
127
                dbus_g_proxy_add_signal(dbus_proxy_power, "OnBatteryChanged",
 
128
                        G_TYPE_BOOLEAN,
 
129
                        G_TYPE_INVALID);
 
130
                        
 
131
                dbus_g_proxy_connect_signal(dbus_proxy_power, "OnBatteryChanged",
 
132
                        G_CALLBACK(on_battery_changed), NULL, NULL);
 
133
                
 
134
                gboolean bBatteryFound = cd_powermanager_find_battery();
 
135
                if (! bBatteryFound)  // on n'a pas trouve de batterie nous-meme.
 
136
                {
 
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");
 
139
                        
 
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",
 
145
                                batteryPath,
 
146
                                "org.freedesktop.Hal.Device"
 
147
                        );
 
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);
 
151
                        
 
152
                        detect_battery ();*/
 
153
                }
 
154
                else
 
155
                {
 
156
                        myData.battery_present = TRUE;  // a verifier mais ca parait logique.
 
157
                        g_print ("batterie presente\n");
 
158
                }
 
159
                
 
160
                return TRUE;
 
161
        }
 
162
        return FALSE;
 
163
}
 
164
 
 
165
void dbus_disconnect_from_bus (void)
 
166
{
 
167
        cd_message ("");
 
168
        if (dbus_proxy_power != NULL)
 
169
        {
 
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;
 
175
        }
 
176
        /**if (dbus_proxy_battery != NULL)
 
177
        {
 
178
                g_object_unref (dbus_proxy_battery);
 
179
                dbus_proxy_battery = NULL;
 
180
        }*/
 
181
        if (dbus_proxy_stats != NULL)
 
182
        {
 
183
                g_object_unref (dbus_proxy_stats);
 
184
                dbus_proxy_stats = NULL;
 
185
        }
 
186
}
 
187
 
 
188
 
 
189
void on_battery_changed(DBusGProxy *proxy, gboolean onBattery, gpointer data)
 
190
{
 
191
        g_print ("Dbus : batery changed\n");
 
192
        if (myData.on_battery != onBattery)
 
193
        {
 
194
                update_stats();
 
195
                update_icon();
 
196
        }
 
197
}
 
198
 
 
199
 
 
200
#define go_to_next_line \
 
201
        cCurLine = strchr (cCurVal, '\n'); \
 
202
        g_return_val_if_fail (cCurLine != NULL, FALSE); \
 
203
        cCurLine ++; \
 
204
        cCurVal = cCurLine;
 
205
 
 
206
#define jump_to_value \
 
207
        cCurVal = strchr (cCurLine, ':'); \
 
208
        g_return_val_if_fail (cCurVal != NULL, FALSE); \
 
209
        cCurVal ++; \
 
210
        while (*cCurVal == ' ') \
 
211
                cCurVal ++;
 
212
 
 
213
/*void get_on_battery(void)
 
214
{
 
215
        dbus_g_proxy_call (dbus_proxy_power, "GetOnBattery", NULL,
 
216
                G_TYPE_INVALID,
 
217
                G_TYPE_BOOLEAN, &myData.on_battery,
 
218
                G_TYPE_INVALID);
 
219
        gchar *cContent = NULL;
 
220
        gsize length=0;
 
221
        GError *erreur = NULL;
 
222
        g_file_get_contents(myData.cBatteryStateFilePath, &cContent, &length, &erreur);
 
223
        if (erreur != NULL)
 
224
        {
 
225
                cd_warning("powermanager : %s", erreur->message);
 
226
                g_error_free(erreur);
 
227
                erreur = NULL;
 
228
                myData.on_battery = FALSE;
 
229
        }
 
230
        else
 
231
        {
 
232
                gchar *cCurLine = cContent, *cCurVal = cContent;
 
233
                
 
234
                go_to_next_line
 
235
                go_to_next_line
 
236
                jump_to_value
 
237
                myData.on_battery = (*cCurVal == 'd');  // discharging
 
238
                
 
239
                g_free (cContent);
 
240
        }
 
241
}*/
 
242
 
 
243
gboolean update_stats(void)
 
244
{
 
245
        if (myData.cBatteryStateFilePath == NULL)
 
246
                cd_powermanager_find_battery ();
 
247
        if (myData.cBatteryStateFilePath == NULL)
 
248
                return TRUE;
 
249
        
 
250
        int k;
 
251
        gchar *cContent = NULL;
 
252
        gsize length=0;
 
253
        GError *erreur = NULL;
 
254
        g_file_get_contents(myData.cBatteryStateFilePath, &cContent, &length, &erreur);
 
255
        if (erreur != NULL)
 
256
        {
 
257
                cd_warning ("powermanager : %s", erreur->message);
 
258
                g_error_free(erreur);
 
259
                erreur = NULL;
 
260
                return FALSE;
 
261
        }
 
262
        else
 
263
        {
 
264
                gchar *cCurLine = cContent, *cCurVal = cContent;
 
265
                
 
266
                jump_to_value
 
267
                gboolean bBatteryPresent = (*cCurVal == 'y');
 
268
                if (bBatteryPresent != myData.battery_present)
 
269
                {
 
270
                        myData.battery_present = bBatteryPresent;
 
271
                        if (! bBatteryPresent)
 
272
                        {
 
273
                                g_print ("la batterie a ete enlevee\n");
 
274
                                g_free (cContent);
 
275
                                update_icon();
 
276
                                return TRUE;
 
277
                        }
 
278
                        else
 
279
                        {
 
280
                                g_print ("la batterie a ete connectee\n");
 
281
                                myData.previous_battery_time = 0;
 
282
                                myData.previous_battery_charge = 0;
 
283
                        }
 
284
                        for (k = 0; k < PM_NB_VALUES; k ++)
 
285
                                myData.fRateHistory[k] = 0;
 
286
                        myData.iCurrentIndex = 0;
 
287
                        myData.iIndexMax = 0;
 
288
                }
 
289
                
 
290
                go_to_next_line  // "present: yes"
 
291
                
 
292
                go_to_next_line  // capacity state: ok
 
293
                //Ajouter un warning si ce n'est pas le cas.
 
294
                
 
295
                jump_to_value
 
296
                gboolean bOnBatteryOld = myData.on_battery;
 
297
                myData.on_battery = (*cCurVal == 'd');  // discharging
 
298
                if (bOnBatteryOld != myData.on_battery)
 
299
                {
 
300
                        for (k = 0; k < PM_NB_VALUES; k ++)
 
301
                                myData.fRateHistory[k] = 0;
 
302
                        myData.iCurrentIndex = 0;
 
303
                        myData.iIndexMax = 0;
 
304
                }
 
305
                
 
306
                go_to_next_line  // charging state: discharging
 
307
                
 
308
                jump_to_value
 
309
                double fPresentRate = atoi (cCurVal);  // 15000 mW OU 1400 mA
 
310
                
 
311
                /*cCurVal ++;
 
312
                while (*cCurVal != ' ')
 
313
                        cCurVal ++;
 
314
                while (*cCurVal == ' ')
 
315
                        cCurVal ++;
 
316
                if (*cCurVal != 'm')
 
317
                        cd_warning ("PowerManager : expecting mA or mW as the present rate unit");
 
318
                cCurVal ++;
 
319
                if (*cCurVal == 'W')
 
320
                        bWatt = TRUE;
 
321
                else if (*cCurVal == 'A')
 
322
                        bWatt = FALSE;
 
323
                else
 
324
                        cd_warning ("PowerManager : expecting A or W as the present rate unit");*/
 
325
                
 
326
                go_to_next_line  // present rate: 15000 mW
 
327
                
 
328
                jump_to_value
 
329
                int iRemainingCapacity = atoi (cCurVal);  // 47040 mWh
 
330
                
 
331
                go_to_next_line  // remaining capacity: 47040 mWh
 
332
                
 
333
                jump_to_value
 
334
                int iPresentVoltage = atoi (cCurVal);  // 15000 mV
 
335
                
 
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.;
 
342
                
 
343
                if (fPresentRate == 0 && myConfig.bUseDBusFallback)
 
344
                {
 
345
                        cd_message ("on se rabat sur DBus");
 
346
                        myData.battery_time = get_stats("time");
 
347
                }
 
348
                else if (fPresentRate == 0 && myData.previous_battery_charge > 0)
 
349
                {
 
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;
 
353
                        
 
354
                        double fMeanRate = 0.;
 
355
                        int nb_values=0;
 
356
                        double fNextValue = 0.;
 
357
                        int iNbStackingValues = 0;
 
358
                        int i;
 
359
                        for (k = 0; k < myData.iIndexMax; k ++)
 
360
                        {
 
361
                                if (myData.iIndexMax == PM_NB_VALUES)
 
362
                                        i = (myData.iCurrentIndex + 1 + k) % PM_NB_VALUES;
 
363
                                else
 
364
                                        i = k;
 
365
                                if (myData.fRateHistory[i] != 0)
 
366
                                {
 
367
                                        if (fNextValue != 0)
 
368
                                        {
 
369
                                                nb_values += iNbStackingValues;
 
370
                                                fMeanRate += fNextValue;
 
371
                                        }
 
372
                                        fNextValue = myData.fRateHistory[i];
 
373
                                        iNbStackingValues = 1;
 
374
                                }
 
375
                                else
 
376
                                {
 
377
                                        iNbStackingValues ++;
 
378
                                }
 
379
                        }
 
380
                        if (nb_values != 0)
 
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);
 
383
                        
 
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;
 
389
                }
 
390
                else
 
391
                        cd_message ("found fPresentRate = %.2f\n", fPresentRate);
 
392
                
 
393
                
 
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;
 
398
                        }
 
399
                        else
 
400
                                myData.battery_time = 0.;
 
401
                }
 
402
                else {
 
403
                        if (fPresentRate > 0) { //Decompte avant charge complete
 
404
                                myData.battery_time = 3600. * (myData.iCapacity - iRemainingCapacity) / fPresentRate;
 
405
                        }
 
406
                        else
 
407
                                myData.battery_time = 0.;
 
408
                }
 
409
                
 
410
                //cd_message ("PowerManager : On Battery:%d ; iCapacity:%dmWh ; iRemainingCapacity:%dmWh ; fPresentRate:%.2fmW ; iPresentVoltage:%dmV", myData.on_battery, myData.iCapacity, iRemainingCapacity, fPresentRate, iPresentVoltage); 
 
411
                g_free (cContent);
 
412
                
 
413
                update_icon();
 
414
        }
 
415
        /*present: yes
 
416
        capacity state: ok
 
417
        charging state: discharging
 
418
        present rate: 15000 mW
 
419
        remaining capacity: 47040 mWh
 
420
        present voltage: 15000 mV*/
 
421
        return TRUE;
 
422
}
 
423
 
 
424
int get_stats(gchar *dataType)  // code repris de Gnome-power-manager.
 
425
{
 
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"
 
431
                );
 
432
        g_return_val_if_fail (dbus_proxy_stats != NULL, 0);
 
433
        
 
434
        GValueArray *gva;
 
435
        GValue *gv;
 
436
        GPtrArray *ptrarray = NULL;
 
437
        GType g_type_ptrarray;
 
438
        int i;
 
439
        int x, y, col;  /// mettre des nom comprehensibles...
 
440
        gint time = 0;
 
441
 
 
442
        g_type_ptrarray = dbus_g_type_get_collection ("GPtrArray",
 
443
                dbus_g_type_get_struct("GValueArray",
 
444
                        G_TYPE_INT,
 
445
                        G_TYPE_INT,
 
446
                        G_TYPE_INT,
 
447
                        G_TYPE_INVALID));
 
448
        
 
449
        dbus_g_proxy_call (dbus_proxy_stats, "GetData", NULL,
 
450
                G_TYPE_INT, time,
 
451
                G_TYPE_STRING, dataType,
 
452
                G_TYPE_INVALID,
 
453
                g_type_ptrarray, &ptrarray,
 
454
                G_TYPE_INVALID);
 
455
        g_return_val_if_fail (ptrarray != NULL, 0);
 
456
        
 
457
        for (i=0; i< ptrarray->len; i++)  /// il semble que seule la derniere valeur ait de l'interet ....
 
458
        {
 
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);
 
462
                g_value_unset (gv);
 
463
                gv = g_value_array_get_nth (gva, 1);
 
464
                y = g_value_get_int (gv);
 
465
                g_value_unset (gv);
 
466
                gv = g_value_array_get_nth (gva, 2);
 
467
                col = g_value_get_int (gv);
 
468
                g_value_unset (gv);
 
469
                g_value_array_free (gva);
 
470
        }
 
471
        g_ptr_array_free (ptrarray, TRUE);
 
472
        
 
473
        cd_message ("PowerManager [%s]: %d", dataType, y);
 
474
        return y;  /// a quoi servent x et col alors ??
 
475
}
 
476
 
 
477
/**void detect_battery(void)
 
478
{
 
479
        if (dbus_proxy_battery != NULL)
 
480
                dbus_g_proxy_call (dbus_proxy_battery, "GetPropertyBoolean", NULL,
 
481
                        G_TYPE_STRING,"battery.present",
 
482
                        G_TYPE_INVALID,
 
483
                        G_TYPE_BOOLEAN, &myData.battery_present,
 
484
                        G_TYPE_INVALID);
 
485
}*/
 
486
 
 
487
void power_halt(void)
 
488
{
 
489
        dbus_g_proxy_call (dbus_proxy_power, "Shutdown", NULL,
 
490
                G_TYPE_INVALID,
 
491
                G_TYPE_INVALID);
 
492
}
 
493
void power_hibernate(void)
 
494
{
 
495
        dbus_g_proxy_call (dbus_proxy_power, "Hibernate", NULL,
 
496
                G_TYPE_INVALID,
 
497
                G_TYPE_INVALID);
 
498
}
 
499
void power_suspend(void)
 
500
{
 
501
        dbus_g_proxy_call (dbus_proxy_power, "Suspend", NULL,
 
502
                G_TYPE_INVALID,
 
503
                G_TYPE_INVALID);
 
504
}
 
505
void power_reboot(void)
 
506
{
 
507
        dbus_g_proxy_call (dbus_proxy_power, "Reboot", NULL,
 
508
                G_TYPE_INVALID,
 
509
                G_TYPE_INVALID);
 
510
}