2
* * Copyright (C) 2008-2011 Ali <aliov@xfce.org>
4
* Licensed under the GNU General Public License Version 2
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 of the License, or
9
* (at your option) any later version.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32
#include <libxfce4util/libxfce4util.h>
33
#include <libxfce4ui/libxfce4ui.h>
34
#include <xfconf/xfconf.h>
36
#include <dbus/dbus-glib.h>
37
#include <dbus/dbus-glib-lowlevel.h>
39
#include <libnotify/notify.h>
41
#include "xfpm-power.h"
42
#include "xfpm-dbus.h"
43
#include "xfpm-disks.h"
44
#include "xfpm-dpms.h"
45
#include "xfpm-manager.h"
46
#include "xfpm-console-kit.h"
47
#include "xfpm-button.h"
48
#include "xfpm-backlight.h"
49
#include "xfpm-inhibit.h"
50
#include "egg-idletime.h"
51
#include "xfpm-config.h"
52
#include "xfpm-debug.h"
53
#include "xfpm-xfconf.h"
54
#include "xfpm-errors.h"
55
#include "xfpm-common.h"
56
#include "xfpm-enum.h"
57
#include "xfpm-enum-glib.h"
58
#include "xfpm-enum-types.h"
59
#include "xfpm-dbus-monitor.h"
62
#include "xfpm-systemd.h"
65
static void xfpm_manager_finalize (GObject *object);
67
static void xfpm_manager_dbus_class_init (XfpmManagerClass *klass);
68
static void xfpm_manager_dbus_init (XfpmManager *manager);
70
static gboolean xfpm_manager_quit (XfpmManager *manager);
72
#define XFPM_MANAGER_GET_PRIVATE(o) \
73
(G_TYPE_INSTANCE_GET_PRIVATE((o), XFPM_TYPE_MANAGER, XfpmManagerPrivate))
75
#define SLEEP_KEY_TIMEOUT 6.0f
77
struct XfpmManagerPrivate
79
DBusGConnection *session_bus;
86
XfpmBacklight *backlight;
90
XfpmConsoleKit *console;
91
XfpmDBusMonitor *monitor;
102
gboolean session_managed;
105
G_DEFINE_TYPE (XfpmManager, xfpm_manager, G_TYPE_OBJECT)
108
xfpm_manager_class_init (XfpmManagerClass *klass)
110
GObjectClass *object_class = G_OBJECT_CLASS(klass);
112
object_class->finalize = xfpm_manager_finalize;
114
g_type_class_add_private (klass, sizeof (XfpmManagerPrivate));
118
xfpm_manager_init (XfpmManager *manager)
120
manager->priv = XFPM_MANAGER_GET_PRIVATE (manager);
122
manager->priv->timer = g_timer_new ();
124
notify_init ("xfce4-power-manager");
128
xfpm_manager_finalize (GObject *object)
130
XfpmManager *manager;
132
manager = XFPM_MANAGER(object);
134
if ( manager->priv->session_bus )
135
dbus_g_connection_unref (manager->priv->session_bus);
137
g_object_unref (manager->priv->power);
138
g_object_unref (manager->priv->button);
139
g_object_unref (manager->priv->conf);
140
g_object_unref (manager->priv->client);
142
if ( manager->priv->systemd != NULL )
143
g_object_unref (manager->priv->systemd);
145
if ( manager->priv->console != NULL )
146
g_object_unref (manager->priv->console);
147
g_object_unref (manager->priv->monitor);
148
g_object_unref (manager->priv->disks);
149
g_object_unref (manager->priv->inhibit);
150
g_object_unref (manager->priv->idle);
152
g_timer_destroy (manager->priv->timer);
155
g_object_unref (manager->priv->dpms);
158
g_object_unref (manager->priv->backlight);
160
G_OBJECT_CLASS (xfpm_manager_parent_class)->finalize (object);
164
xfpm_manager_release_names (XfpmManager *manager)
166
xfpm_dbus_release_name (dbus_g_connection_get_connection(manager->priv->session_bus),
167
"org.xfce.PowerManager");
169
xfpm_dbus_release_name (dbus_g_connection_get_connection(manager->priv->session_bus),
170
"org.freedesktop.PowerManagement");
174
xfpm_manager_quit (XfpmManager *manager)
176
XFPM_DEBUG ("Exiting");
178
xfpm_manager_release_names (manager);
184
xfpm_manager_system_bus_connection_changed_cb (XfpmDBusMonitor *monitor, gboolean connected, XfpmManager *manager)
186
if ( connected == TRUE )
188
XFPM_DEBUG ("System bus connection changed to TRUE, restarting the power manager");
189
xfpm_manager_quit (manager);
190
g_spawn_command_line_async ("xfce4-power-manager", NULL);
195
xfpm_manager_reserve_names (XfpmManager *manager)
197
if ( !xfpm_dbus_register_name (dbus_g_connection_get_connection (manager->priv->session_bus),
198
"org.xfce.PowerManager") ||
199
!xfpm_dbus_register_name (dbus_g_connection_get_connection (manager->priv->session_bus),
200
"org.freedesktop.PowerManagement") )
202
g_warning ("Unable to reserve bus name: Maybe any already running instance?\n");
204
g_object_unref (G_OBJECT (manager));
213
xfpm_manager_shutdown (XfpmManager *manager)
215
GError *error = NULL;
217
if ( LOGIND_RUNNING () )
218
xfpm_systemd_shutdown (manager->priv->systemd, &error );
221
xfpm_console_kit_shutdown (manager->priv->console, &error );
225
g_warning ("Failed to shutdown the system : %s", error->message);
226
g_error_free (error);
227
/* Try with the session then */
228
if ( manager->priv->session_managed )
229
xfce_sm_client_request_shutdown (manager->priv->client, XFCE_SM_CLIENT_SHUTDOWN_HINT_HALT);
234
xfpm_manager_ask_shutdown (XfpmManager *manager)
236
if ( manager->priv->session_managed )
237
xfce_sm_client_request_shutdown (manager->priv->client, XFCE_SM_CLIENT_SHUTDOWN_HINT_ASK);
241
xfpm_manager_sleep_request (XfpmManager *manager, XfpmShutdownRequest req, gboolean force)
245
case XFPM_DO_NOTHING:
247
case XFPM_DO_SUSPEND:
248
xfpm_power_suspend (manager->priv->power, force);
250
case XFPM_DO_HIBERNATE:
251
xfpm_power_hibernate (manager->priv->power, force);
253
case XFPM_DO_SHUTDOWN:
254
xfpm_manager_shutdown (manager);
257
xfpm_manager_ask_shutdown (manager);
260
g_warn_if_reached ();
266
xfpm_manager_reset_sleep_timer (XfpmManager *manager)
268
g_timer_reset (manager->priv->timer);
272
xfpm_manager_button_pressed_cb (XfpmButton *bt, XfpmButtonKey type, XfpmManager *manager)
274
XfpmShutdownRequest req = XFPM_DO_NOTHING;
276
XFPM_DEBUG_ENUM (type, XFPM_TYPE_BUTTON_KEY, "Received button press event");
278
if ( type == BUTTON_MON_BRIGHTNESS_DOWN || type == BUTTON_MON_BRIGHTNESS_UP )
281
if ( type == BUTTON_POWER_OFF )
283
g_object_get (G_OBJECT (manager->priv->conf),
284
POWER_SWITCH_CFG, &req,
287
else if ( type == BUTTON_SLEEP )
289
g_object_get (G_OBJECT (manager->priv->conf),
290
SLEEP_SWITCH_CFG, &req,
293
else if ( type == BUTTON_HIBERNATE )
295
g_object_get (G_OBJECT (manager->priv->conf),
296
HIBERNATE_SWITCH_CFG, &req,
301
g_return_if_reached ();
304
XFPM_DEBUG_ENUM (req, XFPM_TYPE_SHUTDOWN_REQUEST, "Shutdown request : ");
306
if ( req == XFPM_ASK )
307
xfpm_manager_ask_shutdown (manager);
310
if ( g_timer_elapsed (manager->priv->timer, NULL) > SLEEP_KEY_TIMEOUT )
312
g_timer_reset (manager->priv->timer);
313
xfpm_manager_sleep_request (manager, req, FALSE);
319
xfpm_manager_lid_changed_cb (XfpmPower *power, gboolean lid_is_closed, XfpmManager *manager)
321
XfpmLidTriggerAction action;
324
g_object_get (G_OBJECT (power),
325
"on-battery", &on_battery,
328
g_object_get (G_OBJECT (manager->priv->conf),
329
on_battery ? LID_SWITCH_ON_BATTERY_CFG : LID_SWITCH_ON_AC_CFG, &action,
334
XFPM_DEBUG_ENUM (action, XFPM_TYPE_LID_TRIGGER_ACTION, "LID close event");
336
if ( action == LID_TRIGGER_NOTHING )
339
if ( !xfpm_is_multihead_connected () )
340
xfpm_dpms_force_level (manager->priv->dpms, DPMSModeOff);
343
else if ( action == LID_TRIGGER_LOCK_SCREEN )
345
if ( !xfpm_is_multihead_connected () )
351
* Force sleep here as lid is closed and no point of asking the
352
* user for confirmation in case of an application is inhibiting
355
xfpm_manager_sleep_request (manager, action, TRUE);
361
XFPM_DEBUG_ENUM (action, XFPM_TYPE_LID_TRIGGER_ACTION, "LID opened");
363
xfpm_dpms_force_level (manager->priv->dpms, DPMSModeOn);
369
xfpm_manager_inhibit_changed_cb (XfpmInhibit *inhibit, gboolean inhibited, XfpmManager *manager)
371
manager->priv->inhibited = inhibited;
375
xfpm_manager_alarm_timeout_cb (EggIdletime *idle, guint id, XfpmManager *manager)
377
if (xfpm_power_get_mode (manager->priv->power) == XFPM_POWER_MODE_PRESENTATION)
380
XFPM_DEBUG ("Alarm inactivity timeout id %d", id);
382
if ( id == TIMEOUT_INACTIVITY_ON_AC || id == TIMEOUT_INACTIVITY_ON_BATTERY )
384
XfpmShutdownRequest req = XFPM_DO_NOTHING;
388
if ( manager->priv->inhibited )
390
XFPM_DEBUG ("Idle sleep alarm timeout, but power manager is currently inhibited, action ignored");
394
g_object_get (G_OBJECT (manager->priv->conf),
395
INACTIVITY_SLEEP_MODE, &sleep_mode,
398
g_object_get (G_OBJECT (manager->priv->power),
399
"on-battery", &on_battery,
402
if ( !g_strcmp0 (sleep_mode, "Suspend") )
403
req = XFPM_DO_SUSPEND;
405
req = XFPM_DO_HIBERNATE;
409
if ( id == TIMEOUT_INACTIVITY_ON_AC && on_battery == FALSE )
410
xfpm_manager_sleep_request (manager, req, FALSE);
411
else if ( id == TIMEOUT_INACTIVITY_ON_BATTERY && on_battery )
412
xfpm_manager_sleep_request (manager, req, FALSE);
417
xfpm_manager_set_idle_alarm_on_ac (XfpmManager *manager)
421
g_object_get (G_OBJECT (manager->priv->conf),
422
ON_AC_INACTIVITY_TIMEOUT, &on_ac,
427
TRACE ("setting inactivity sleep timeout on ac to never");
429
TRACE ("setting inactivity sleep timeout on ac to %d", on_ac);
434
egg_idletime_alarm_remove (manager->priv->idle, TIMEOUT_INACTIVITY_ON_AC );
438
egg_idletime_alarm_set (manager->priv->idle, TIMEOUT_INACTIVITY_ON_AC, on_ac * 1000 * 60);
443
xfpm_manager_set_idle_alarm_on_battery (XfpmManager *manager)
447
g_object_get (G_OBJECT (manager->priv->conf),
448
ON_BATTERY_INACTIVITY_TIMEOUT, &on_battery,
452
if ( on_battery == 14 )
453
TRACE ("setting inactivity sleep timeout on battery to never");
455
TRACE ("setting inactivity sleep timeout on battery to %d", on_battery);
458
if ( on_battery == 14 )
460
egg_idletime_alarm_remove (manager->priv->idle, TIMEOUT_INACTIVITY_ON_BATTERY );
464
egg_idletime_alarm_set (manager->priv->idle, TIMEOUT_INACTIVITY_ON_BATTERY, on_battery * 1000 * 60);
469
xfpm_manager_on_battery_changed_cb (XfpmPower *power, gboolean on_battery, XfpmManager *manager)
471
egg_idletime_alarm_reset_all (manager->priv->idle);
475
xfpm_manager_set_idle_alarm (XfpmManager *manager)
477
xfpm_manager_set_idle_alarm_on_ac (manager);
478
xfpm_manager_set_idle_alarm_on_battery (manager);
483
xfpm_manager_new (DBusGConnection *bus, const gchar *client_id)
485
XfpmManager *manager = NULL;
486
GError *error = NULL;
489
const gchar *restart_command[] =
491
"xfce4-power-manager",
496
manager = g_object_new (XFPM_TYPE_MANAGER, NULL);
498
manager->priv->session_bus = bus;
500
current_dir = g_get_current_dir ();
501
manager->priv->client = xfce_sm_client_get_full (XFCE_SM_CLIENT_RESTART_NORMAL,
502
XFCE_SM_CLIENT_PRIORITY_DEFAULT,
506
SYSCONFDIR "/xdg/autostart/" PACKAGE_NAME ".desktop");
508
g_free (current_dir);
510
manager->priv->session_managed = xfce_sm_client_connect (manager->priv->client, &error);
514
g_warning ("Unable to connect to session managet : %s", error->message);
515
g_error_free (error);
519
g_signal_connect_swapped (manager->priv->client, "quit",
520
G_CALLBACK (xfpm_manager_quit), manager);
523
xfpm_manager_dbus_class_init (XFPM_MANAGER_GET_CLASS (manager));
524
xfpm_manager_dbus_init (manager);
529
void xfpm_manager_start (XfpmManager *manager)
531
if ( !xfpm_manager_reserve_names (manager) )
534
dbus_g_error_domain_register (XFPM_ERROR,
538
manager->priv->power = xfpm_power_get ();
539
manager->priv->button = xfpm_button_new ();
540
manager->priv->conf = xfpm_xfconf_new ();
542
manager->priv->console = NULL;
543
manager->priv->systemd = NULL;
544
if ( LOGIND_RUNNING () )
545
manager->priv->systemd = xfpm_systemd_new ();
548
manager->priv->console = xfpm_console_kit_new ();
549
manager->priv->monitor = xfpm_dbus_monitor_new ();
550
manager->priv->disks = xfpm_disks_new ();
551
manager->priv->inhibit = xfpm_inhibit_new ();
552
manager->priv->idle = egg_idletime_new ();
554
g_signal_connect (manager->priv->idle, "alarm-expired",
555
G_CALLBACK (xfpm_manager_alarm_timeout_cb), manager);
557
g_signal_connect_swapped (manager->priv->conf, "notify::" ON_AC_INACTIVITY_TIMEOUT,
558
G_CALLBACK (xfpm_manager_set_idle_alarm_on_ac), manager);
560
g_signal_connect_swapped (manager->priv->conf, "notify::" ON_BATTERY_INACTIVITY_TIMEOUT,
561
G_CALLBACK (xfpm_manager_set_idle_alarm_on_battery), manager);
563
xfpm_manager_set_idle_alarm (manager);
565
g_signal_connect (manager->priv->inhibit, "has-inhibit-changed",
566
G_CALLBACK (xfpm_manager_inhibit_changed_cb), manager);
568
g_signal_connect (manager->priv->monitor, "system-bus-connection-changed",
569
G_CALLBACK (xfpm_manager_system_bus_connection_changed_cb), manager);
571
manager->priv->backlight = xfpm_backlight_new ();
574
manager->priv->dpms = xfpm_dpms_new ();
577
g_signal_connect (manager->priv->button, "button_pressed",
578
G_CALLBACK (xfpm_manager_button_pressed_cb), manager);
580
g_signal_connect (manager->priv->power, "lid-changed",
581
G_CALLBACK (xfpm_manager_lid_changed_cb), manager);
583
g_signal_connect (manager->priv->power, "on-battery-changed",
584
G_CALLBACK (xfpm_manager_on_battery_changed_cb), manager);
586
g_signal_connect_swapped (manager->priv->power, "waking-up",
587
G_CALLBACK (xfpm_manager_reset_sleep_timer), manager);
589
g_signal_connect_swapped (manager->priv->power, "sleeping",
590
G_CALLBACK (xfpm_manager_reset_sleep_timer), manager);
592
g_signal_connect_swapped (manager->priv->power, "ask-shutdown",
593
G_CALLBACK (xfpm_manager_ask_shutdown), manager);
595
g_signal_connect_swapped (manager->priv->power, "shutdown",
596
G_CALLBACK (xfpm_manager_shutdown), manager);
602
void xfpm_manager_stop (XfpmManager *manager)
604
XFPM_DEBUG ("Stopping");
605
g_return_if_fail (XFPM_IS_MANAGER (manager));
606
xfpm_manager_quit (manager);
609
GHashTable *xfpm_manager_get_config (XfpmManager *manager)
613
guint8 mapped_buttons;
614
gboolean auth_hibernate = FALSE;
615
gboolean auth_suspend = FALSE;
616
gboolean can_suspend = FALSE;
617
gboolean can_hibernate = FALSE;
618
gboolean has_sleep_button = FALSE;
619
gboolean has_hibernate_button = FALSE;
620
gboolean has_power_button = FALSE;
621
gboolean has_battery = TRUE;
622
gboolean has_lcd_brightness = TRUE;
623
gboolean can_shutdown = TRUE;
624
gboolean has_lid = FALSE;
625
gboolean can_spin = FALSE;
626
gboolean devkit_disk = FALSE;
628
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
631
if ( LOGIND_RUNNING () )
632
g_object_get (G_OBJECT (manager->priv->systemd),
633
"can-shutdown", &can_shutdown,
637
g_object_get (G_OBJECT (manager->priv->console),
638
"can-shutdown", &can_shutdown,
641
g_object_get (G_OBJECT (manager->priv->power),
642
"auth-suspend", &auth_suspend,
643
"auth-hibernate", &auth_hibernate,
644
"can-suspend", &can_suspend,
645
"can-hibernate", &can_hibernate,
649
can_spin = xfpm_disks_get_can_spin (manager->priv->disks);
650
devkit_disk = xfpm_disks_kit_is_running (manager->priv->disks);
652
has_battery = xfpm_power_has_battery (manager->priv->power);
653
has_lcd_brightness = xfpm_backlight_has_hw (manager->priv->backlight);
655
mapped_buttons = xfpm_button_get_mapped (manager->priv->button);
657
if ( mapped_buttons & SLEEP_KEY )
658
has_sleep_button = TRUE;
659
if ( mapped_buttons & HIBERNATE_KEY )
660
has_hibernate_button = TRUE;
661
if ( mapped_buttons & POWER_KEY )
662
has_power_button = TRUE;
664
g_hash_table_insert (hash, g_strdup ("sleep-button"), g_strdup (xfpm_bool_to_string (has_sleep_button)));
665
g_hash_table_insert (hash, g_strdup ("power-button"), g_strdup (xfpm_bool_to_string (has_power_button)));
666
g_hash_table_insert (hash, g_strdup ("hibernate-button"), g_strdup (xfpm_bool_to_string (has_hibernate_button)));
667
g_hash_table_insert (hash, g_strdup ("auth-suspend"), g_strdup (xfpm_bool_to_string (auth_suspend)));
668
g_hash_table_insert (hash, g_strdup ("auth-hibernate"), g_strdup (xfpm_bool_to_string (auth_hibernate)));
669
g_hash_table_insert (hash, g_strdup ("can-suspend"), g_strdup (xfpm_bool_to_string (can_suspend)));
670
g_hash_table_insert (hash, g_strdup ("can-hibernate"), g_strdup (xfpm_bool_to_string (can_hibernate)));
671
g_hash_table_insert (hash, g_strdup ("can-shutdown"), g_strdup (xfpm_bool_to_string (can_shutdown)));
673
g_hash_table_insert (hash, g_strdup ("has-battery"), g_strdup (xfpm_bool_to_string (has_battery)));
674
g_hash_table_insert (hash, g_strdup ("has-lid"), g_strdup (xfpm_bool_to_string (has_lid)));
675
g_hash_table_insert (hash, g_strdup ("can-spin"), g_strdup (xfpm_bool_to_string (can_spin)));
676
g_hash_table_insert (hash, g_strdup ("devkit-disk"), g_strdup (xfpm_bool_to_string (devkit_disk)));
678
g_hash_table_insert (hash, g_strdup ("has-brightness"), g_strdup (xfpm_bool_to_string (has_lcd_brightness)));
685
* DBus server implementation
688
static gboolean xfpm_manager_dbus_quit (XfpmManager *manager,
691
static gboolean xfpm_manager_dbus_restart (XfpmManager *manager,
694
static gboolean xfpm_manager_dbus_get_config (XfpmManager *manager,
695
GHashTable **OUT_config,
698
static gboolean xfpm_manager_dbus_get_info (XfpmManager *manager,
704
#include "xfce-power-manager-dbus-server.h"
707
xfpm_manager_dbus_class_init (XfpmManagerClass *klass)
709
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
710
&dbus_glib_xfpm_manager_object_info);
714
xfpm_manager_dbus_init (XfpmManager *manager)
716
dbus_g_connection_register_g_object (manager->priv->session_bus,
717
"/org/xfce/PowerManager",
722
xfpm_manager_dbus_quit (XfpmManager *manager, GError **error)
724
XFPM_DEBUG("Quit message received\n");
726
xfpm_manager_quit (manager);
731
static gboolean xfpm_manager_dbus_restart (XfpmManager *manager,
734
XFPM_DEBUG("Restart message received");
736
xfpm_manager_quit (manager);
738
g_spawn_command_line_async ("xfce4-power-manager", NULL);
743
static gboolean xfpm_manager_dbus_get_config (XfpmManager *manager,
744
GHashTable **OUT_config,
748
*OUT_config = xfpm_manager_get_config (manager);
753
xfpm_manager_dbus_get_info (XfpmManager *manager,
760
*OUT_name = g_strdup(PACKAGE);
761
*OUT_version = g_strdup(VERSION);
762
*OUT_vendor = g_strdup("Xfce-goodies");