chiark / gitweb /
logind: support for hybrid sleep (i.e. suspend+hibernate at the same time)
[elogind.git] / src / login / logind-button.c
index e2d9fd2b0f374079149c890e50511175d6d61f4c..753d95454c866f91108ebddbbf9c6412839617ea 100644 (file)
@@ -163,16 +163,18 @@ static int button_handle(
                 [HANDLE_HALT] = "Halting...",
                 [HANDLE_KEXEC] = "Rebooting via kexec...",
                 [HANDLE_SUSPEND] = "Suspending...",
-                [HANDLE_HIBERNATE] = "Hibernating..."
+                [HANDLE_HIBERNATE] = "Hibernating...",
+                [HANDLE_HYBRID_SLEEP] = "Hibernating and suspend...",
         };
 
         static const char * const target_table[_HANDLE_BUTTON_MAX] = {
-                [HANDLE_POWEROFF] = "poweroff.target",
-                [HANDLE_REBOOT] = "reboot.target",
-                [HANDLE_HALT] = "halt.target",
-                [HANDLE_KEXEC] = "kexec.target",
-                [HANDLE_SUSPEND] = "suspend.target",
-                [HANDLE_HIBERNATE] = "hibernate.target"
+                [HANDLE_POWEROFF] = SPECIAL_POWEROFF_TARGET,
+                [HANDLE_REBOOT] = SPECIAL_REBOOT_TARGET,
+                [HANDLE_HALT] = SPECIAL_HALT_TARGET,
+                [HANDLE_KEXEC] = SPECIAL_KEXEC_TARGET,
+                [HANDLE_SUSPEND] = SPECIAL_SUSPEND_TARGET,
+                [HANDLE_HIBERNATE] = SPECIAL_HIBERNATE_TARGET,
+                [HANDLE_HYBRID_SLEEP] = SPECIAL_HYBRID_SLEEP_TARGET
         };
 
         DBusError error;
@@ -193,7 +195,7 @@ static int button_handle(
                 return 0;
         }
 
-        inhibit_operation = handle == HANDLE_SUSPEND || handle == HANDLE_HIBERNATE ? INHIBIT_SLEEP : INHIBIT_SHUTDOWN;
+        inhibit_operation = handle == HANDLE_SUSPEND || handle == HANDLE_HIBERNATE || handle == HANDLE_HYBRID_SLEEP ? INHIBIT_SLEEP : INHIBIT_SHUTDOWN;
 
         /* If the actual operation is inhibited, warn and fail */
         if (!ignore_inhibited &&
@@ -249,12 +251,21 @@ int button_process(Button *b) {
                         log_info("Power key pressed.");
                         return button_handle(b, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
 
+                /* The kernel is a bit confused here:
+
+                   KEY_SLEEP   = suspend-to-ram, which everybody else calls "suspend"
+                   KEY_SUSPEND = suspend-to-disk, which everybody else calls "hibernate"
+                */
+
                 case KEY_SLEEP:
-                case KEY_SUSPEND:
-                        log_info("Sleep key pressed.");
-                        return button_handle(b, INHIBIT_HANDLE_SLEEP_KEY, b->manager->handle_sleep_key, b->manager->sleep_key_ignore_inhibited, true);
+                        log_info("Suspend key pressed.");
+                        return button_handle(b, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true);
 
+                case KEY_SUSPEND:
+                        log_info("Hibernate key pressed.");
+                        return button_handle(b, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true);
                 }
+
         } else if (ev.type == EV_SW && ev.value > 0) {
 
                 switch (ev.code) {
@@ -296,7 +307,8 @@ static const char* const handle_button_table[_HANDLE_BUTTON_MAX] = {
         [HANDLE_HALT] = "halt",
         [HANDLE_KEXEC] = "kexec",
         [HANDLE_SUSPEND] = "suspend",
-        [HANDLE_HIBERNATE] = "hibernate"
+        [HANDLE_HIBERNATE] = "hibernate",
+        [HANDLE_HYBRID_SLEEP] = "hybrid-sleep",
 };
 DEFINE_STRING_TABLE_LOOKUP(handle_button, HandleButton);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_handle_button, handle_button, HandleButton, "Failed to parse handle button setting");