2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
3* 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-struct.h"
26
#include "powermanager-draw.h"
27
#include "powermanager-common.h"
28
#include "powermanager-upower.h"
31
#ifdef CD_UPOWER_AVAILABLE // code with libupower
33
static void _cd_upower_connect_async (CDSharedMemory *pSharedMemory)
35
// connect to UPower on Dbus.
36
UpClient *pUPowerClient = up_client_new ();
38
// get the list of devices.
39
if (! up_client_enumerate_devices_sync (pUPowerClient, NULL, NULL))
41
cd_warning ("couldn't get devices from UPower daemon");
42
g_object_unref (pUPowerClient);
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;
52
for (i = 0; i < pDevices->len; i ++)
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)
58
pBatteryDevice = pDevice;
62
if (pBatteryDevice == NULL)
64
cd_debug ("no battery found amongst %d devices", pDevices->len);
65
g_object_unref (pUPowerClient);
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;
74
static void _fetch_current_values (UpDevice *pDevice)
77
g_object_get (G_OBJECT (pDevice), "is-present", &is_present, NULL);
78
myData.bBatteryPresent = is_present;
79
if (myData.bBatteryPresent)
82
g_object_get (G_OBJECT (pDevice), "state", &iState, NULL);
83
myData.bOnBattery = (iState == UP_DEVICE_STATE_DISCHARGING || iState == UP_DEVICE_STATE_PENDING_DISCHARGE);
86
g_object_get (G_OBJECT (pDevice), "percentage", &percentage, NULL);
87
myData.iPercentage = round (percentage);
90
g_object_get (G_OBJECT (pDevice), myData.bOnBattery ? "time-to-empty" : "time-to-full", &time, NULL);
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 ();
98
myData.bOnBattery = FALSE;
100
myData.iPercentage = 0; // since we are not on battery, this will not trigger any alert.
104
static void _on_device_changed (UpDevice *pDevice, gpointer data)
107
cd_debug ("battery properties changed");
109
// the client object is already up-to-date, just fetch its values.
110
_fetch_current_values (pDevice);
112
// and update the icon.
117
static gboolean _cd_upower_update_state (CDSharedMemory *pSharedMemory)
120
if (pSharedMemory->pUPowerClient == NULL) // no UPower available, try to find the battery by ourselves.
122
cd_debug ("no UPower available");
123
cd_check_power_files ();
125
else // UPower is available, fetch the values we got from it.
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);
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);
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.
139
myData.pUPowerClient = pSharedMemory->pUPowerClient;
140
pSharedMemory->pUPowerClient = NULL;
143
// in any case, update the icon to show the current state we are in.
146
cairo_dock_discard_task (myData.pTask);
149
CD_APPLET_LEAVE (FALSE);
152
static void _free_shared_memory (CDSharedMemory *pSharedMemory)
154
if (pSharedMemory->pUPowerClient)
155
g_object_unref (pSharedMemory->pUPowerClient);
156
if (pSharedMemory->pBatteryDevice)
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.
163
g_free (pSharedMemory);
166
void cd_powermanager_start (void)
168
if (myData.pTask != NULL)
170
cairo_dock_discard_task (myData.pTask);
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,
180
cairo_dock_launch_task (myData.pTask);
184
gboolean cd_power_hibernate (void)
186
if (myData.pUPowerClient != NULL)
187
return up_client_hibernate_sync (myData.pUPowerClient, NULL, NULL);
192
gboolean cd_power_suspend (void)
194
if (myData.pUPowerClient != NULL)
195
return up_client_suspend_sync (myData.pUPowerClient, NULL, NULL);
200
gboolean cd_power_can_hibernate (void)
202
if (myData.pUPowerClient != NULL)
203
return up_client_get_can_hibernate (myData.pUPowerClient);
208
gboolean cd_power_can_suspend (void)
210
if (myData.pUPowerClient != NULL)
211
return up_client_get_can_suspend (myData.pUPowerClient);
216
#else // code without libupower
218
void cd_powermanager_start (void)
220
cd_check_power_files ();
223
gboolean cd_power_hibernate (void)
228
gboolean cd_power_suspend (void)
233
gboolean cd_power_can_hibernate (void)
238
gboolean cd_power_can_suspend (void)