source: pkg/main/gnome-panel/branches/upstream/current/gnome-panel/panel-power-manager.c @ 180

Revision 180, 11.3 KB checked in by alanbach-guest, 6 years ago (diff)

[svn-inject] Installing original source of gnome-panel

Line 
1/* panel-power-manager.c - functions for powering down, restarting, and
2 *                         suspending the computer
3 *
4 * Copyright (C) 2006 Ray Strode <rstrode@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21#ifdef HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#include "panel-power-manager.h"
26
27#include <errno.h>
28#include <string.h>
29
30#include <glib.h>
31#include <glib-object.h>
32#include <glib/gi18n.h>
33
34#include <dbus/dbus-glib.h>
35
36struct _PanelPowerManagerPrivate {
37        DBusGConnection *dbus_connection;
38        DBusGProxy      *bus_proxy;
39        DBusGProxy      *gpm_proxy;
40        guint32          is_connected : 1;
41};
42
43
44static void panel_power_manager_finalize (GObject *object);
45static void panel_power_manager_class_install_signals (PanelPowerManagerClass *manager_class);
46static void panel_power_manager_class_install_properties (PanelPowerManagerClass *manager_class);
47
48static void panel_power_manager_get_property (GObject    *object,
49                                              guint       prop_id,
50                                              GValue     *value,
51                                              GParamSpec *pspec);
52
53static gboolean panel_power_manager_ensure_gpm_connection (PanelPowerManager  *manager,
54                                                           GError            **error);
55
56enum {
57  PROP_0 = 0,
58  PROP_IS_CONNECTED
59};
60
61enum {
62  REQUEST_FAILED = 0,
63  NUMBER_OF_SIGNALS
64};
65
66static guint panel_power_manager_signals[NUMBER_OF_SIGNALS];
67
68G_DEFINE_TYPE (PanelPowerManager, panel_power_manager, G_TYPE_OBJECT);
69
70static void
71panel_power_manager_class_init (PanelPowerManagerClass *manager_class)
72{
73        GObjectClass *object_class;
74
75        object_class = G_OBJECT_CLASS (manager_class);
76
77        object_class->finalize = panel_power_manager_finalize;
78
79        panel_power_manager_class_install_properties (manager_class);
80        panel_power_manager_class_install_signals (manager_class);
81
82        g_type_class_add_private (manager_class,
83                                  sizeof (PanelPowerManagerPrivate));
84}
85
86static void
87panel_power_manager_class_install_signals (PanelPowerManagerClass *manager_class)
88{
89        GObjectClass *object_class;
90
91        object_class = G_OBJECT_CLASS (manager_class);
92
93        panel_power_manager_signals[REQUEST_FAILED] =
94                g_signal_new ("request-failed",
95                              G_OBJECT_CLASS_TYPE (object_class),
96                              G_SIGNAL_RUN_LAST,
97                              G_STRUCT_OFFSET (PanelPowerManagerClass, request_failed),
98                              NULL,
99                              NULL,
100                              g_cclosure_marshal_VOID__POINTER,
101                              G_TYPE_NONE,
102                              1, G_TYPE_POINTER);
103        manager_class->request_failed = NULL;
104}
105
106static void
107panel_power_manager_class_install_properties (PanelPowerManagerClass *manager_class)
108{
109        GObjectClass *object_class;
110        GParamSpec *param_spec;
111
112        object_class = G_OBJECT_CLASS (manager_class);
113        object_class->get_property = panel_power_manager_get_property;
114
115        param_spec = g_param_spec_boolean ("is-connected",
116                                           "Is connected",
117                                           "Whether the panel is connected to "
118                                           "the power manager",
119                                           FALSE,
120                                           G_PARAM_READABLE);
121        g_object_class_install_property (object_class, PROP_IS_CONNECTED,
122                                         param_spec);
123}
124
125static void
126panel_power_manager_on_name_owner_changed (DBusGProxy        *bus_proxy,
127                                           const char        *name,
128                                           const char        *prev_owner,
129                                           const char        *new_owner,
130                                           PanelPowerManager *manager)
131{
132        if (strcmp (name, "org.gnome.PowerManager") != 0)
133                return;
134
135        if (manager->priv->gpm_proxy != NULL) {
136                g_object_unref (manager->priv->gpm_proxy);
137                manager->priv->gpm_proxy = NULL;
138        }
139
140        panel_power_manager_ensure_gpm_connection (manager, NULL);
141}
142
143static gboolean
144panel_power_manager_ensure_gpm_connection (PanelPowerManager  *manager,
145                                           GError            **error)
146{
147        GError   *connection_error;
148        gboolean  is_connected;
149
150        connection_error = NULL;
151        if (manager->priv->dbus_connection == NULL) {
152                manager->priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION,
153                                                                 &connection_error);
154
155                if (manager->priv->dbus_connection == NULL) {
156                        g_propagate_error (error, connection_error);
157                        is_connected = FALSE;
158                        goto out;
159                }
160        }
161
162        if (manager->priv->bus_proxy == NULL) {
163                manager->priv->bus_proxy =
164                        dbus_g_proxy_new_for_name_owner (manager->priv->dbus_connection,
165                                                         DBUS_SERVICE_DBUS,
166                                                         DBUS_PATH_DBUS,
167                                                         DBUS_INTERFACE_DBUS,
168                                                         &connection_error);
169
170                if (manager->priv->bus_proxy == NULL) {
171                        g_propagate_error (error, connection_error);
172                        is_connected = FALSE;
173                        goto out;
174                }
175
176                dbus_g_proxy_add_signal (manager->priv->bus_proxy,
177                                         "NameOwnerChanged",
178                                         G_TYPE_STRING,
179                                         G_TYPE_STRING,
180                                         G_TYPE_STRING,
181                                         G_TYPE_INVALID);
182                dbus_g_proxy_connect_signal (manager->priv->bus_proxy,
183                                             "NameOwnerChanged",
184                                             G_CALLBACK (panel_power_manager_on_name_owner_changed),
185                                             manager, NULL);
186        }
187
188        if (manager->priv->gpm_proxy == NULL) {
189                manager->priv->gpm_proxy =
190                        dbus_g_proxy_new_for_name_owner (
191                                        manager->priv->dbus_connection,
192                                        "org.gnome.PowerManager",
193                                        "/org/gnome/PowerManager",
194                                        "org.gnome.PowerManager",
195                                        &connection_error);
196
197                if (manager->priv->gpm_proxy == NULL) {
198                        g_propagate_error (error, connection_error);
199                        is_connected = FALSE;
200                        goto out;
201                }
202        }
203        is_connected = TRUE;
204
205out:
206        if (manager->priv->is_connected != is_connected) {
207                manager->priv->is_connected = is_connected;
208                g_object_notify (G_OBJECT (manager), "is-connected");
209        }
210
211        if (!is_connected) {
212                if (manager->priv->dbus_connection == NULL) {
213                        if (manager->priv->bus_proxy != NULL) {
214                                g_object_unref (manager->priv->bus_proxy);
215                                manager->priv->bus_proxy = NULL;
216                        }
217
218                        if (manager->priv->gpm_proxy != NULL) {
219                                g_object_unref (manager->priv->gpm_proxy);
220                                manager->priv->gpm_proxy = NULL;
221                        }
222                } else if (manager->priv->bus_proxy == NULL) {
223                        if (manager->priv->gpm_proxy != NULL) {
224                                g_object_unref (manager->priv->gpm_proxy);
225                                manager->priv->gpm_proxy = NULL;
226                        }
227                }
228        }
229
230        return is_connected;
231}
232
233static void
234panel_power_manager_init (PanelPowerManager *manager)
235{
236        GError *error;
237
238        manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
239                                                     PANEL_TYPE_POWER_MANAGER,
240                                                     PanelPowerManagerPrivate);
241
242        manager->priv->dbus_connection = NULL;
243        manager->priv->bus_proxy = NULL;
244        manager->priv->gpm_proxy = NULL;
245        manager->priv->is_connected = FALSE;
246
247        error = NULL;
248        if (!panel_power_manager_ensure_gpm_connection (manager, &error)) {
249                g_message ("Could not connect to power manager: %s",
250                           error->message);
251                g_error_free (error);
252        }
253}
254
255static void
256panel_power_manager_finalize (GObject *object)
257{
258        PanelPowerManager *manager;
259        GObjectClass *parent_class;
260
261        manager = PANEL_POWER_MANAGER (object);
262
263        parent_class = G_OBJECT_CLASS (panel_power_manager_parent_class);
264
265        if (parent_class->finalize != NULL)
266                parent_class->finalize (object);
267}
268
269static void
270panel_power_manager_get_property (GObject    *object,
271                                  guint       prop_id,
272                                  GValue     *value,
273                                  GParamSpec *pspec)
274{
275        PanelPowerManager *manager = PANEL_POWER_MANAGER (object);
276
277        switch (prop_id) {
278        case PROP_IS_CONNECTED:
279                g_value_set_boolean (value,
280                                     manager->priv->is_connected);
281                break;
282
283        default:
284                G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
285                                                   prop_id,
286                                                   pspec);
287        }
288}
289
290GQuark
291panel_power_manager_error_quark (void)
292{
293        static GQuark error_quark = 0;
294
295        if (error_quark == 0)
296                error_quark = g_quark_from_static_string ("panel-power-manager-error");
297
298        return error_quark;
299}
300
301PanelPowerManager *
302panel_power_manager_new (void)
303{
304        PanelPowerManager *manager;
305
306        manager = g_object_new (PANEL_TYPE_POWER_MANAGER, NULL);
307
308        return manager;
309}
310
311gboolean
312panel_power_manager_can_suspend (PanelPowerManager *manager)
313{
314        GError *error;
315        gboolean can_suspend;
316
317        error = NULL;
318
319        if (!panel_power_manager_ensure_gpm_connection (manager, &error)) {
320                g_message ("Could not connect to power manager: %s",
321                           error->message);
322                g_error_free (error);
323                return FALSE;
324        }
325
326        can_suspend = FALSE;
327        if (!dbus_g_proxy_call (manager->priv->gpm_proxy, "AllowedSuspend",
328                                &error,
329                                G_TYPE_INVALID,
330                                G_TYPE_BOOLEAN, &can_suspend, G_TYPE_INVALID)) {
331                if (error != NULL) {
332                        g_message ("Could not ask power manager if user can suspend: %s",
333                                   error->message);
334                        g_error_free (error);
335                }
336                can_suspend = FALSE;
337        }
338
339        return can_suspend;
340}
341
342gboolean
343panel_power_manager_can_hibernate (PanelPowerManager *manager)
344{
345        GError *error;
346        gboolean can_hibernate;
347
348        error = NULL;
349
350        if (!panel_power_manager_ensure_gpm_connection (manager, &error)) {
351                g_message ("Could not connect to power manager: %s",
352                           error->message);
353                g_error_free (error);
354                return FALSE;
355        }
356
357        can_hibernate = FALSE;
358        if (!dbus_g_proxy_call (manager->priv->gpm_proxy, "AllowedHibernate",
359                                &error,
360                                G_TYPE_INVALID,
361                                G_TYPE_BOOLEAN, &can_hibernate, G_TYPE_INVALID)) {
362                if (error != NULL) {
363                        g_message ("Could not ask power manager if user can suspend: %s",
364                                   error->message);
365                        g_error_free (error);
366                }
367                can_hibernate = FALSE;
368        }
369
370        return can_hibernate;
371}
372
373void
374panel_power_manager_attempt_suspend (PanelPowerManager *manager)
375{
376        GError *error;
377
378        error = NULL;
379
380        if (!panel_power_manager_ensure_gpm_connection (manager, &error)) {
381                g_warning ("Could not connect to power manager: %s",
382                           error->message);
383                g_error_free (error);
384                return;
385        }
386
387        if (!dbus_g_proxy_call (manager->priv->gpm_proxy, "Suspend",
388                                &error,
389                                G_TYPE_INVALID, G_TYPE_INVALID) &&
390            error != NULL) {
391                GError *call_error;
392
393                g_warning ("Could not ask power manager to suspend: %s",
394                           error->message);
395
396                call_error = g_error_new_literal (PANEL_POWER_MANAGER_ERROR,
397                                                  PANEL_POWER_MANAGER_ERROR_SUSPENDING,
398                                                  error->message);
399                g_error_free (error);
400
401                g_signal_emit (G_OBJECT (manager),
402                               panel_power_manager_signals[REQUEST_FAILED],
403                               0, call_error);
404                g_error_free (call_error);
405        }
406}
407
408
409void
410panel_power_manager_attempt_hibernate (PanelPowerManager *manager)
411{
412        GError *error;
413
414        error = NULL;
415
416        if (!panel_power_manager_ensure_gpm_connection (manager, &error)) {
417                g_warning ("Could not connect to power manager: %s",
418                           error->message);
419                g_error_free (error);
420                return;
421        }
422
423        if (!dbus_g_proxy_call (manager->priv->gpm_proxy, "Hibernate",
424                                &error,
425                                G_TYPE_INVALID, G_TYPE_INVALID) &&
426            error != NULL) {
427                GError *call_error;
428
429                g_warning ("Could not ask power manager to hibernate: %s",
430                           error->message);
431
432                call_error = g_error_new_literal (PANEL_POWER_MANAGER_ERROR,
433                                                  PANEL_POWER_MANAGER_ERROR_HIBERNATING,
434                                                  error->message);
435                g_error_free (error);
436
437                g_signal_emit (G_OBJECT (manager),
438                               panel_power_manager_signals[REQUEST_FAILED],
439                               0, call_error);
440                g_error_free (call_error);
441        }
442}
443
444
445PanelPowerManager *
446panel_get_power_manager (void)
447{
448        static PanelPowerManager *manager = NULL;
449
450        if (manager == NULL)
451                manager = panel_power_manager_new ();
452
453        return g_object_ref (manager);
454}
Note: See TracBrowser for help on using the repository browser.