~ubuntu-branches/ubuntu/oneiric/cairo-dock-plug-ins/oneiric-updates

« back to all changes in this revision

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

  • Committer: Kees Cook
  • Date: 2011-08-11 23:17:39 UTC
  • mfrom: (20.1.1 cairo-dock-plug-ins)
  • Revision ID: kees@outflux.net-20110811231739-cteedan51tmdg77v
Tags: 2.4.0~0beta2-0ubuntu1
releasing version 2.4.0~0beta2-0ubuntu1

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
3* 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-struct.h"
 
26
#include "powermanager-draw.h"
 
27
#include "powermanager-common.h"
 
28
#include "powermanager-upower.h"
 
29
 
 
30
 
 
31
#ifdef CD_UPOWER_AVAILABLE  // code with libupower
 
32
 
 
33
static void _cd_upower_connect_async (CDSharedMemory *pSharedMemory)
 
34
{
 
35
        // connect to UPower on Dbus.
 
36
        UpClient *pUPowerClient = up_client_new ();
 
37
        
 
38
        // get the list of devices.
 
39
        if (! up_client_enumerate_devices_sync (pUPowerClient, NULL, NULL))
 
40
        {       
 
41
                cd_warning ("couldn't get devices from UPower daemon");
 
42
                g_object_unref (pUPowerClient);
 
43
                return;
 
44
        }
 
45
        
 
46
        // find the battery device.
 
47
        GPtrArray *pDevices = up_client_get_devices (pUPowerClient);
 
48
        g_return_if_fail (pDevices != NULL);  // just to be sure.
 
49
        UpDevice *pDevice, *pBatteryDevice = NULL;
 
50
        UpDeviceKind kind;
 
51
        guint i;
 
52
        for (i = 0; i < pDevices->len; i ++)
 
53
        {
 
54
                pDevice = g_ptr_array_index (pDevices, i);
 
55
                g_object_get (G_OBJECT (pDevice), "kind", &kind, NULL);
 
56
                if (kind == UP_DEVICE_KIND_BATTERY)
 
57
                {
 
58
                        pBatteryDevice = pDevice;
 
59
                        break;
 
60
                }
 
61
        }
 
62
        if (pBatteryDevice == NULL)
 
63
        {
 
64
                cd_debug ("no battery found amongst %d devices", pDevices->len);
 
65
                g_object_unref (pUPowerClient);
 
66
                return;
 
67
        }
 
68
        
 
69
        pSharedMemory->pUPowerClient = pUPowerClient;
 
70
        g_object_ref (pBatteryDevice);  // just to be sure it won't be destroyed before we go back to the main loop (shouldn't happen, since devices don't change over time).
 
71
        pSharedMemory->pBatteryDevice = pBatteryDevice;
 
72
}
 
73
 
 
74
static void _fetch_current_values (UpDevice *pDevice)
 
75
{
 
76
        gboolean is_present;
 
77
        g_object_get (G_OBJECT (pDevice), "is-present", &is_present, NULL);
 
78
        myData.bBatteryPresent = is_present;
 
79
        if (myData.bBatteryPresent)
 
80
        {
 
81
                UpDeviceState iState;
 
82
                g_object_get (G_OBJECT (pDevice), "state", &iState, NULL);
 
83
                myData.bOnBattery = (iState == UP_DEVICE_STATE_DISCHARGING || iState == UP_DEVICE_STATE_PENDING_DISCHARGE);
 
84
                
 
85
                gdouble percentage;
 
86
                g_object_get (G_OBJECT (pDevice), "percentage", &percentage, NULL);
 
87
                myData.iPercentage = round (percentage);
 
88
                
 
89
                guint64 time;
 
90
                g_object_get (G_OBJECT (pDevice), myData.bOnBattery ? "time-to-empty" : "time-to-full", &time, NULL);
 
91
                myData.iTime = time;
 
92
                
 
93
                if (myData.iTime == 0 && myData.iPercentage < 100)  // the UPower daemon doesn't give us a time, let's compute it ourselves.
 
94
                        myData.iTime = cd_estimate_time ();
 
95
        }
 
96
        else
 
97
        {
 
98
                myData.bOnBattery = FALSE;
 
99
                myData.iTime = 0;
 
100
                myData.iPercentage = 0;  // since we are not on battery, this will not trigger any alert.
 
101
        }
 
102
}
 
103
 
 
104
static void _on_device_changed (UpDevice *pDevice, gpointer data)
 
105
{
 
106
        CD_APPLET_ENTER;
 
107
        cd_debug ("battery properties changed");
 
108
        
 
109
        // the client object is already up-to-date, just fetch its values.
 
110
        _fetch_current_values (pDevice);
 
111
        
 
112
        // and update the icon.
 
113
        update_icon ();
 
114
        CD_APPLET_LEAVE ();
 
115
}
 
116
 
 
117
static gboolean _cd_upower_update_state (CDSharedMemory *pSharedMemory)
 
118
{
 
119
        CD_APPLET_ENTER;
 
120
        if (pSharedMemory->pUPowerClient == NULL)  // no UPower available, try to find the battery by ourselves.
 
121
        {
 
122
                cd_debug ("no UPower available");
 
123
                cd_check_power_files ();
 
124
        }
 
125
        else  // UPower is available, fetch the values we got from it.
 
126
        {
 
127
                // fetch the values we got on the device, and keep them up-to-date (we don't need the device itself).
 
128
                // a priori, no need to watch the "onBattery" signal on the client, since we can deduce this property from the device state.
 
129
                _fetch_current_values (pSharedMemory->pBatteryDevice);
 
130
                
 
131
                g_object_get (pSharedMemory->pBatteryDevice, "technology", &myData.cTechnology, NULL);
 
132
                g_object_get (pSharedMemory->pBatteryDevice, "vendor", &myData.cVendor, NULL);
 
133
                g_object_get (pSharedMemory->pBatteryDevice, "model", &myData.cModel, NULL);
 
134
                g_object_get (pSharedMemory->pBatteryDevice, "capacity", &myData.fMaxAvailableCapacity, NULL);
 
135
                
 
136
                myData.iSignalID = g_signal_connect (pSharedMemory->pBatteryDevice, "changed", G_CALLBACK (_on_device_changed), NULL);  // a battery not present is still a valid device. So if we could find a battery device, it will stay here forever, so we don't need to watch for the destruction/creation of a battery device.
 
137
                
 
138
                // keep our client.
 
139
                myData.pUPowerClient = pSharedMemory->pUPowerClient;
 
140
                pSharedMemory->pUPowerClient = NULL;
 
141
        }
 
142
        
 
143
        // in any case, update the icon to show the current state we are in.
 
144
        update_icon ();
 
145
        
 
146
        cairo_dock_discard_task (myData.pTask);
 
147
        myData.pTask = NULL;
 
148
        
 
149
        CD_APPLET_LEAVE (FALSE);
 
150
}
 
151
 
 
152
static void _free_shared_memory (CDSharedMemory *pSharedMemory)
 
153
{
 
154
        if (pSharedMemory->pUPowerClient)
 
155
                g_object_unref (pSharedMemory->pUPowerClient);
 
156
        if (pSharedMemory->pBatteryDevice)
 
157
        {
 
158
                // _on_device_changed can still be called
 
159
                if (g_signal_handler_is_connected (pSharedMemory->pBatteryDevice, myData.iSignalID))
 
160
                        g_signal_handler_disconnect (pSharedMemory->pBatteryDevice, myData.iSignalID);
 
161
                g_object_unref (pSharedMemory->pBatteryDevice);  // remove the ref we took on it.
 
162
        }
 
163
        g_free (pSharedMemory);
 
164
}
 
165
 
 
166
void cd_powermanager_start (void)
 
167
{
 
168
        if (myData.pTask != NULL)
 
169
        {
 
170
                cairo_dock_discard_task (myData.pTask);
 
171
                myData.pTask = NULL;
 
172
        }
 
173
        
 
174
        CDSharedMemory *pSharedMemory = g_new0 (CDSharedMemory, 1);
 
175
        myData.pTask = cairo_dock_new_task_full (0,
 
176
                (CairoDockGetDataAsyncFunc) _cd_upower_connect_async,
 
177
                (CairoDockUpdateSyncFunc) _cd_upower_update_state,
 
178
                (GFreeFunc) _free_shared_memory,
 
179
                pSharedMemory);
 
180
        cairo_dock_launch_task (myData.pTask);
 
181
}
 
182
 
 
183
 
 
184
gboolean cd_power_hibernate (void)
 
185
{
 
186
        if (myData.pUPowerClient != NULL)
 
187
                return up_client_hibernate_sync (myData.pUPowerClient, NULL, NULL);
 
188
        else
 
189
                return FALSE;
 
190
}
 
191
 
 
192
gboolean cd_power_suspend (void)
 
193
{
 
194
        if (myData.pUPowerClient != NULL)
 
195
                return up_client_suspend_sync (myData.pUPowerClient, NULL, NULL);
 
196
        else
 
197
                return FALSE;
 
198
}
 
199
 
 
200
gboolean cd_power_can_hibernate (void)
 
201
{
 
202
        if (myData.pUPowerClient != NULL)
 
203
                return up_client_get_can_hibernate (myData.pUPowerClient);
 
204
        else
 
205
                return FALSE;
 
206
}
 
207
 
 
208
gboolean cd_power_can_suspend (void)
 
209
{
 
210
        if (myData.pUPowerClient != NULL)
 
211
                return up_client_get_can_suspend (myData.pUPowerClient);
 
212
        else
 
213
                return FALSE;
 
214
}
 
215
 
 
216
#else // code without libupower
 
217
 
 
218
void cd_powermanager_start (void)
 
219
{
 
220
        cd_check_power_files ();
 
221
}
 
222
 
 
223
gboolean cd_power_hibernate (void)
 
224
{
 
225
        return FALSE;
 
226
}
 
227
 
 
228
gboolean cd_power_suspend (void)
 
229
{
 
230
        return FALSE;
 
231
}
 
232
 
 
233
gboolean cd_power_can_hibernate (void)
 
234
{
 
235
        return FALSE;
 
236
}
 
237
 
 
238
gboolean cd_power_can_suspend (void)
 
239
{
 
240
        return FALSE;
 
241
}
 
242
 
 
243
#endif