~ubuntu-branches/ubuntu/oneiric/gnome-settings-daemon/oneiric

« back to all changes in this revision

Viewing changes to plugins/power/gsd-power-manager.c

  • Committer: Package Import Robot
  • Author(s): Rodrigo Moya
  • Date: 2011-09-19 17:05:48 UTC
  • mfrom: (1.1.51 upstream)
  • Revision ID: package-import@ubuntu.com-20110919170548-gegm8ewt6qf7v7lp
Tags: 3.1.92-0ubuntu1
* New upstream release
* debian/control:
  - Bump libcolord-dev build dependency
* debian/patches/00git_guard_against_division_by_0.patch:
* debian/patches/00git_dont_crash_if_session_not_ready.patch:
* debian/patches/00git_numlock_status.patch:
* debian/patches/00git_disconnect_callbacks.patch:
  - Remove upstream patches
* debian/patches/06_use_application_indicator.patch:
* debian/patches/16_use_synchronous_notifications.patch:
  - Rebased

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include <stdio.h>
27
27
#include <glib/gi18n.h>
28
28
#include <gtk/gtk.h>
29
 
#include <canberra-gtk.h>
30
29
#include <libupower-glib/upower.h>
31
30
#include <libnotify/notify.h>
32
31
 
33
32
#define GNOME_DESKTOP_USE_UNSTABLE_API
34
33
#include <libgnome-desktop/gnome-rr.h>
35
34
 
 
35
#ifdef HAVE_LIBCANBERRA
 
36
#include <canberra-gtk.h>
 
37
#endif /* HAVE_LIBCANBERRA */
 
38
 
36
39
#include "gpm-common.h"
37
40
#include "gpm-phone.h"
38
41
#include "gpm-idletime.h"
39
42
#include "gnome-settings-profile.h"
 
43
#include "gnome-settings-session.h"
40
44
#include "gsd-enums.h"
41
45
#include "gsd-power-manager.h"
42
46
 
146
150
 
147
151
struct GsdPowerManagerPrivate
148
152
{
 
153
        GnomeSettingsSession    *session;
149
154
        gboolean                 lid_is_closed;
150
155
        GSettings               *settings;
151
156
        GSettings               *settings_screensaver;
173
178
        UpDevice                *device_composite;
174
179
        NotifyNotification      *notification_discharging;
175
180
        NotifyNotification      *notification_low;
 
181
#ifdef HAVE_LIBCANBERRA
176
182
        ca_context              *canberra_context;
177
183
        ca_proplist             *critical_alert_loop_props;
178
184
        guint32                  critical_alert_timeout_id;
 
185
#endif /* HAVE_LIBCANBERRA */
179
186
        GDBusProxy              *screensaver_proxy;
180
187
        GDBusProxy              *session_proxy;
181
188
        GDBusProxy              *session_presence_proxy;
212
219
        return quark;
213
220
}
214
221
 
215
 
 
 
222
#ifdef HAVE_LIBCANBERRA
216
223
static gboolean
217
224
play_loop_timeout_cb (GsdPowerManager *manager)
218
225
{
281
288
                         CA_PROP_EVENT_DESCRIPTION, desc, NULL);
282
289
        return TRUE;
283
290
}
 
291
#endif /* HAVE_LIBCANBERRA */
284
292
 
285
293
static void
286
294
notify_close_if_showing (NotifyNotification *notification)
629
637
 
630
638
                /* set fallback icon */
631
639
                gtk_status_icon_set_visible (manager->priv->status_icon, FALSE);
632
 
 
633
 
                /* icon before, now none */
634
 
                engine_emit_changed (manager);
635
 
 
636
640
                return TRUE;
637
641
        }
638
642
 
642
646
                /* set fallback icon */
643
647
                gtk_status_icon_set_visible (manager->priv->status_icon, TRUE);
644
648
                gtk_status_icon_set_from_gicon (manager->priv->status_icon, icon);
645
 
 
646
 
                engine_emit_changed (manager);
647
 
                manager->priv->previous_icon = g_object_ref (icon);
 
649
                manager->priv->previous_icon = icon;
648
650
                return TRUE;
649
651
        }
650
652
 
651
653
        /* icon before, now different */
652
654
        if (!g_icon_equal (manager->priv->previous_icon, icon)) {
653
655
                g_object_unref (manager->priv->previous_icon);
654
 
                manager->priv->previous_icon = g_object_ref (icon);
 
656
                manager->priv->previous_icon = icon;
655
657
 
656
658
                /* set fallback icon */
657
659
                gtk_status_icon_set_from_gicon (manager->priv->status_icon, icon);
658
 
 
659
 
                engine_emit_changed (manager);
660
660
                return TRUE;
661
661
        }
662
662
 
679
679
                gtk_status_icon_set_tooltip_text (manager->priv->status_icon,
680
680
                                                  summary);
681
681
 
682
 
                engine_emit_changed (manager);
683
682
                return TRUE;
684
683
        }
685
684
 
691
690
                gtk_status_icon_set_tooltip_text (manager->priv->status_icon,
692
691
                                                  summary);
693
692
 
694
 
                engine_emit_changed (manager);
695
693
                return TRUE;
696
694
        }
697
695
        g_debug ("no change");
703
701
static void
704
702
engine_recalculate_state (GsdPowerManager *manager)
705
703
{
706
 
        engine_recalculate_state_icon (manager);
707
 
        engine_recalculate_state_summary (manager);
708
 
 
709
 
        engine_emit_changed (manager);
 
704
        gboolean ret;
 
705
        gboolean has_changed = FALSE;
 
706
 
 
707
        ret = engine_recalculate_state_icon (manager);
 
708
        if (ret)
 
709
                has_changed = TRUE;
 
710
        ret = engine_recalculate_state_summary (manager);
 
711
        if (ret)
 
712
                has_changed = TRUE;
 
713
 
 
714
        /* only emit if the icon or summary has changed */
 
715
        if (has_changed)
 
716
                engine_emit_changed (manager);
710
717
}
711
718
 
712
719
static UpDevice *
768
775
        gboolean is_charging = FALSE;
769
776
        gboolean is_discharging = FALSE;
770
777
        gboolean is_fully_charged = TRUE;
 
778
        gboolean has_changed;
771
779
        GPtrArray *array;
772
780
        UpDevice *device;
773
781
        UpDeviceState state;
816
824
        }
817
825
 
818
826
        /* use percentage weighted for each battery capacity */
819
 
        percentage = 100.0 * energy_total / energy_full_total;
 
827
        if (energy_full_total > 0.0)
 
828
                percentage = 100.0 * energy_total / energy_full_total;
820
829
 
821
830
        /* set composite state */
822
831
        if (is_charging)
851
860
                      NULL);
852
861
 
853
862
        /* force update of icon */
854
 
        engine_recalculate_state_icon (manager);
 
863
        has_changed = engine_recalculate_state_icon (manager);
 
864
        if (has_changed)
 
865
                engine_emit_changed (manager);
855
866
out:
856
867
        /* return composite device or original device */
857
868
        return device;
1206
1217
{
1207
1218
        GsdPowerActionType action_type;
1208
1219
 
 
1220
#ifdef HAVE_LIBCANBERRA
1209
1221
        /* stop playing the alert as it's too late to do anything now */
1210
1222
        if (manager->priv->critical_alert_timeout_id > 0)
1211
1223
                play_loop_stop (manager);
 
1224
#endif /* HAVE_LIBCANBERRA */
1212
1225
 
1213
1226
        action_type = g_settings_get_enum (manager->priv->settings,
1214
1227
                                           "critical-battery-action");
1372
1385
                g_object_unref (manager->priv->notification_low);
1373
1386
        }
1374
1387
 
 
1388
#ifdef HAVE_LIBCANBERRA
1375
1389
        /* play the sound, using sounds from the naming spec */
1376
1390
        ca_context_play (manager->priv->canberra_context, 0,
1377
1391
                         CA_PROP_EVENT_ID, "battery-low",
1378
1392
                         /* TRANSLATORS: this is the sound description */
1379
1393
                         CA_PROP_EVENT_DESCRIPTION, _("Battery is low"), NULL);
 
1394
#endif /* HAVE_LIBCANBERRA */
 
1395
 
1380
1396
out:
1381
1397
        if (icon != NULL)
1382
1398
                g_object_unref (icon);
1555
1571
        case UP_DEVICE_KIND_BATTERY:
1556
1572
        case UP_DEVICE_KIND_UPS:
1557
1573
                g_debug ("critical charge level reached, starting sound loop");
 
1574
#ifdef HAVE_LIBCANBERRA
1558
1575
                play_loop_start (manager,
1559
1576
                                 "battery-caution",
1560
1577
                                 _("Battery is critically low"),
1561
1578
                                 TRUE,
1562
1579
                                 GSD_POWER_MANAGER_CRITICAL_ALERT_TIMEOUT);
 
1580
#endif /* HAVE_LIBCANBERRA */
1563
1581
                break;
1564
1582
 
1565
1583
        default:
 
1584
#ifdef HAVE_LIBCANBERRA
1566
1585
                /* play the sound, using sounds from the naming spec */
1567
1586
                ca_context_play (manager->priv->canberra_context, 0,
1568
1587
                                 CA_PROP_EVENT_ID, "battery-caution",
1569
1588
                                 /* TRANSLATORS: this is the sound description */
1570
1589
                                 CA_PROP_EVENT_DESCRIPTION, _("Battery is critically low"), NULL);
 
1590
#endif /* HAVE_LIBCANBERRA */
1571
1591
                break;
1572
1592
        }
1573
1593
out:
1699
1719
                g_object_unref (manager->priv->notification_low);
1700
1720
        }
1701
1721
 
 
1722
#ifdef HAVE_LIBCANBERRA
1702
1723
        /* play the sound, using sounds from the naming spec */
1703
1724
        ca_context_play (manager->priv->canberra_context, 0,
1704
1725
                         CA_PROP_EVENT_ID, "battery-caution",
1705
1726
                         /* TRANSLATORS: this is the sound description */
1706
1727
                         CA_PROP_EVENT_DESCRIPTION, _("Battery is critically low"), NULL);
 
1728
#endif /* HAVE_LIBCANBERRA */
1707
1729
out:
1708
1730
        if (icon != NULL)
1709
1731
                g_object_unref (icon);
2047
2069
                 * hibernate is not available and is marginally better
2048
2070
                 * than just powering down the computer mid-write */
2049
2071
                consolekit_stop ();
 
2072
                break;
2050
2073
        case GSD_POWER_ACTION_BLANK:
2051
2074
                ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen,
2052
2075
                                                     GNOME_RR_DPMS_OFF,
2068
2091
        gboolean ret;
2069
2092
        GError *error = NULL;
2070
2093
 
 
2094
#ifdef HAVE_LIBCANBERRA
2071
2095
        /* play a sound, using sounds from the naming spec */
2072
2096
        ca_context_play (manager->priv->canberra_context, 0,
2073
2097
                         CA_PROP_EVENT_ID, "lid-open",
2074
2098
                         /* TRANSLATORS: this is the sound description */
2075
2099
                         CA_PROP_EVENT_DESCRIPTION, _("Lid has been opened"),
2076
2100
                         NULL);
 
2101
#endif /* HAVE_LIBCANBERRA */
2077
2102
 
2078
2103
        /* ensure we turn the panel back on after lid open */
2079
2104
        ret = gnome_rr_screen_set_dpms_mode (manager->priv->x11_screen,
2093
2118
        GError *error = NULL;
2094
2119
        GsdPowerActionType action_type;
2095
2120
 
 
2121
#ifdef HAVE_LIBCANBERRA
2096
2122
        /* play a sound, using sounds from the naming spec */
2097
2123
        ca_context_play (manager->priv->canberra_context, 0,
2098
2124
                         CA_PROP_EVENT_ID, "lid-close",
2099
2125
                         /* TRANSLATORS: this is the sound description */
2100
2126
                         CA_PROP_EVENT_DESCRIPTION, _("Lid has been closed"),
2101
2127
                         NULL);
 
2128
#endif /* HAVE_LIBCANBERRA */
2102
2129
 
2103
2130
        /* we have different settings depending on AC state */
2104
2131
        if (up_client_get_on_battery (manager->priv->up_client)) {
2145
2172
{
2146
2173
        gboolean tmp;
2147
2174
 
 
2175
#ifdef HAVE_LIBCANBERRA
2148
2176
        /* if we are playing a critical charge sound loop on AC, stop it */
2149
2177
        if (!up_client_get_on_battery (client) &&
2150
2178
            manager->priv->critical_alert_timeout_id > 0) {
2151
2179
                g_debug ("stopping alert loop due to ac being present");
2152
2180
                play_loop_stop (manager);
2153
2181
        }
 
2182
#endif /* HAVE_LIBCANBERRA */
2154
2183
 
2155
2184
        /* same state */
2156
2185
        tmp = up_client_get_lid_is_closed (manager->priv->up_client);
2254
2283
                                         NULL,
2255
2284
                                         &exit_status,
2256
2285
                                         error);
 
2286
        g_debug ("executed %s retval: %i", command, exit_status);
 
2287
 
2257
2288
        if (!ret)
2258
2289
                goto out;
2259
2290
 
2260
 
        g_debug ("executed %s retval: %i", command, exit_status);
 
2291
        if (WEXITSTATUS (exit_status) != 0) {
 
2292
                 g_set_error (error,
 
2293
                             GSD_POWER_MANAGER_ERROR,
 
2294
                             GSD_POWER_MANAGER_ERROR_FAILED,
 
2295
                             "gsd-backlight-helper failed: %s",
 
2296
                             stdout_data ? stdout_data : "No reason");
 
2297
                goto out;
 
2298
        }
2261
2299
 
2262
2300
        /* parse */
2263
2301
        value = g_ascii_strtoll (stdout_data, &endptr, 10);
2264
2302
 
2265
2303
        /* parsing error */
2266
2304
        if (endptr == stdout_data) {
 
2305
                value = -1;
2267
2306
                g_set_error (error,
2268
2307
                             GSD_POWER_MANAGER_ERROR,
2269
2308
                             GSD_POWER_MANAGER_ERROR_FAILED,
2322
2361
                                         NULL,
2323
2362
                                         &exit_status,
2324
2363
                                         error);
2325
 
        if (!ret)
 
2364
 
 
2365
        g_debug ("executed %s retval: %i", command, exit_status);
 
2366
 
 
2367
        if (!ret || WEXITSTATUS (exit_status) != 0)
2326
2368
                goto out;
2327
2369
 
2328
 
        g_debug ("executed %s retval: %i", command, exit_status);
2329
2370
out:
2330
2371
        g_free (command);
2331
2372
        return ret;
2592
2633
        gint max;
2593
2634
        gint now;
2594
2635
        GsdPowerActionType action_type;
 
2636
        GnomeSettingsSessionState state;
2595
2637
 
2596
2638
        if (mode == manager->priv->current_idle_mode)
2597
2639
                return;
2598
2640
 
 
2641
        /* ensure we're still on an active console */
 
2642
        state = gnome_settings_session_get_state (manager->priv->session);
 
2643
        if (state == GNOME_SETTINGS_SESSION_STATE_INACTIVE) {
 
2644
                g_debug ("ignoring state transition to %s as inactive",
 
2645
                         idle_mode_to_string (mode));
 
2646
                return;
 
2647
        }
 
2648
 
2599
2649
        manager->priv->current_idle_mode = mode;
2600
2650
        g_debug ("Doing a state transition: %s", idle_mode_to_string (mode));
2601
2651
 
2727
2777
        /* get the session status */
2728
2778
        result = g_dbus_proxy_get_cached_property (manager->priv->session_presence_proxy,
2729
2779
                                                   "status");
2730
 
        if (result == NULL)
 
2780
        if (result == NULL) {
 
2781
                g_warning ("no readable status property on %s",
 
2782
                           g_dbus_proxy_get_interface_name (manager->priv->session_presence_proxy));
2731
2783
                return FALSE;
 
2784
        }
2732
2785
 
2733
2786
        g_variant_get (result, "u", &status);
2734
2787
        ret = (status == SESSION_STATUS_CODE_IDLE);
2764
2817
                return FALSE;
2765
2818
        }
2766
2819
 
2767
 
        ret = g_variant_get_boolean (retval);
 
2820
        g_variant_get (retval, "(b)", &ret);
2768
2821
        g_variant_unref (retval);
2769
2822
 
2770
2823
        return ret;
2867
2920
                        g_source_set_name_by_id (manager->priv->timeout_sleep_id,
2868
2921
                                                 "[GsdPowerManager] sleep");
2869
2922
                }
 
2923
        } else {
 
2924
                g_debug ("session is not idle");
2870
2925
        }
2871
2926
}
2872
2927
 
3016
3071
                g_warning ("Could not connect to gnome-sesson: %s",
3017
3072
                           error->message);
3018
3073
                g_error_free (error);
 
3074
                return;
3019
3075
        }
3020
3076
        g_signal_connect (manager->priv->session_proxy, "g-signal",
3021
3077
                          G_CALLBACK (idle_dbus_signal_cb), manager);
3034
3090
                g_warning ("Could not connect to gnome-sesson: %s",
3035
3091
                           error->message);
3036
3092
                g_error_free (error);
 
3093
                return;
3037
3094
        }
3038
3095
        g_signal_connect (manager->priv->session_presence_proxy, "g-signal",
3039
3096
                          G_CALLBACK (idle_dbus_signal_cb), manager);
3081
3138
                                        NULL,
3082
3139
                                        &error);
3083
3140
        if (k_now == NULL) {
3084
 
                g_warning ("Failed to get brightness: %s", error->message);
 
3141
                if (error->domain != G_DBUS_ERROR ||
 
3142
                    error->code != G_DBUS_ERROR_UNKNOWN_METHOD) {
 
3143
                        g_warning ("Failed to get brightness: %s",
 
3144
                                   error->message);
 
3145
                }
3085
3146
                g_error_free (error);
3086
3147
                goto out;
3087
3148
        }
3204
3265
        }
3205
3266
}
3206
3267
 
 
3268
static void
 
3269
engine_session_active_changed_cb (GnomeSettingsSession *session,
 
3270
                                  GParamSpec *pspec,
 
3271
                                  GsdPowerManager *manager)
 
3272
{
 
3273
        /* when doing the fast-user-switch into a new account,
 
3274
         * ensure the new account is undimmed and with the backlight on */
 
3275
        idle_set_mode (manager, GSD_POWER_IDLE_MODE_NORMAL);
 
3276
}
 
3277
 
3207
3278
gboolean
3208
3279
gsd_power_manager_start (GsdPowerManager *manager,
3209
3280
                         GError **error)
3211
3282
        g_debug ("Starting power manager");
3212
3283
        gnome_settings_profile_start (NULL);
3213
3284
 
 
3285
        /* track the active session */
 
3286
        manager->priv->session = gnome_settings_session_new ();
 
3287
        g_signal_connect (manager->priv->session, "notify::state",
 
3288
                          G_CALLBACK (engine_session_active_changed_cb),
 
3289
                          manager);
 
3290
 
3214
3291
        manager->priv->kbd_brightness_old = -1;
3215
3292
        manager->priv->pre_dim_brightness = 100;
3216
3293
        manager->priv->settings = g_settings_new (GSD_POWER_SETTINGS_SCHEMA);
3285
3362
                                  session_proxy_ready_cb,
3286
3363
                                  manager);
3287
3364
        g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
3288
 
                                  G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
 
3365
                                  0,
3289
3366
                                  NULL,
3290
3367
                                  GNOME_SESSION_DBUS_NAME,
3291
3368
                                  GNOME_SESSION_DBUS_PATH_PRESENCE,
3295
3372
                                  manager);
3296
3373
 
3297
3374
        manager->priv->devices_array = g_ptr_array_new_with_free_func (g_object_unref);
 
3375
#ifdef HAVE_LIBCANBERRA
3298
3376
        manager->priv->canberra_context = ca_gtk_context_get_for_screen (gdk_screen_get_default ());
 
3377
#endif /* HAVE_LIBCANBERRA */
3299
3378
 
3300
3379
        manager->priv->phone = gpm_phone_new ();
3301
3380
        g_signal_connect (manager->priv->phone, "device-added",
3378
3457
        if (manager->priv->timeout_sleep_id != 0)
3379
3458
                g_source_remove (manager->priv->timeout_sleep_id);
3380
3459
 
 
3460
        g_object_unref (manager->priv->session);
3381
3461
        g_object_unref (manager->priv->settings);
3382
3462
        g_object_unref (manager->priv->settings_screensaver);
3383
3463
        g_object_unref (manager->priv->up_client);
3399
3479
        if (manager->priv->session_presence_proxy != NULL)
3400
3480
                g_object_unref (manager->priv->session_presence_proxy);
3401
3481
 
 
3482
#ifdef HAVE_LIBCANBERRA
3402
3483
        if (manager->priv->critical_alert_timeout_id > 0)
3403
3484
                g_source_remove (manager->priv->critical_alert_timeout_id);
 
3485
#endif /* HAVE_LIBCANBERRA */
3404
3486
 
3405
3487
        gpm_idletime_alarm_remove (manager->priv->idletime,
3406
3488
                                   GSD_POWER_IDLETIME_ID);
3599
3681
                               state,
3600
3682
                               time_state);
3601
3683
        g_free (device_icon);
 
3684
        g_object_unref (icon);
3602
3685
        return value;
3603
3686
}
3604
3687