raster pushed a commit to branch master.

commit ea88d880a785ed83b470e5e7b9e973edafa8d6bb
Author: Carsten Haitzler (Rasterman) <[email protected]>
Date:   Thu Aug 15 19:09:33 2013 +0900

    add systemd support to e_sys for shutdown/reboot/suspend/hibernate
---
 src/bin/e_sys.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 197 insertions(+), 11 deletions(-)

diff --git a/src/bin/e_sys.c b/src/bin/e_sys.c
index 1966717..d6cd060 100644
--- a/src/bin/e_sys.c
+++ b/src/bin/e_sys.c
@@ -42,9 +42,20 @@ static void (*_e_sys_shutdown_func)(void) = NULL;
 static void (*_e_sys_logout_func)(void) = NULL;
 static void (*_e_sys_resume_func)(void) = NULL;
 
+static void _e_sys_systemd_handle_inhibit(void);
+static void _e_sys_systemd_works_check(void);
+static void _e_sys_systemd_poweroff(void);
+static void _e_sys_systemd_reboot(void);
+static void _e_sys_systemd_suspend(void);
+static void _e_sys_systemd_hibernate(void);
+
+static Eina_Bool systemd_works = EINA_FALSE;
+
 static const int E_LOGOUT_AUTO_TIME = 60;
 static const int E_LOGOUT_WAIT_TIME = 15;
 
+static Eldbus_Connection *conn = NULL;
+
 EAPI int E_EVENT_SYS_SUSPEND = -1;
 EAPI int E_EVENT_SYS_HIBERNATE = -1;
 EAPI int E_EVENT_SYS_RESUME = -1;
@@ -53,14 +64,17 @@ EAPI int E_EVENT_SYS_RESUME = -1;
 EINTERN int
 e_sys_init(void)
 {
+   eldbus_init();
+   conn = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM);
+   _e_sys_systemd_handle_inhibit();
+   
    E_EVENT_SYS_SUSPEND = ecore_event_type_new();
    E_EVENT_SYS_HIBERNATE = ecore_event_type_new();
    E_EVENT_SYS_RESUME = ecore_event_type_new();
    /* this is not optimal - but it does work cleanly */
    _e_sys_exe_exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
                                                      _e_sys_cb_exit, NULL);
-   /* delay this for 1.0 seconds while the rest of e starts up */
-   ecore_timer_add(1.0, _e_sys_cb_timer, NULL);
+   _e_sys_systemd_works_check();
    return 1;
 }
 
@@ -74,6 +88,9 @@ e_sys_shutdown(void)
    _e_sys_reboot_check_exe = NULL;
    _e_sys_suspend_check_exe = NULL;
    _e_sys_hibernate_check_exe = NULL;
+   if (conn) eldbus_connection_unref(conn);
+   conn = NULL;
+   eldbus_shutdown();
    return 1;
 }
 
@@ -253,6 +270,126 @@ e_sys_handlers_set(void (*suspend_func)(void),
    _e_sys_resume_func = resume_func;
 }
 
+static Eldbus_Message *
+_e_sys_systemd_login_manager_msg(const char *method)
+{
+   return eldbus_message_method_call_new("org.freedesktop.login1",
+                                      "/org/freedesktop/login1",
+                                      "org.freedesktop.login1.Manager",
+                                      method);
+}
+
+static void
+_e_sys_systemd_handle_inhibit(void)
+{
+   Eldbus_Message *m;
+   
+   if (!conn) return;
+   if (!(m = _e_sys_systemd_login_manager_msg("Inhibit"))) return;
+   eldbus_message_arguments_append
+     (m, "ssss",
+         "handle-power-key:"
+         "handle-suspend-key:"
+         "handle-hibernate-key:"
+         "handle-lid-switch", // what
+         "Enlightenment", // who (string)
+         "Normal Execution", // why (string)
+         "block");
+   eldbus_connection_send(conn, m, NULL, NULL, -1);
+}
+
+static void
+_e_sys_systemd_check_cb(void *data, const Eldbus_Message *m, Eldbus_Pending *p 
__UNUSED__)
+{
+   int *dest = data;
+   char *s = NULL;
+   if (!eldbus_message_arguments_get(m, "s", &s)) return;
+   if (!s) return;
+   if (!strcmp(s, "yes")) *dest = 1;
+   else *dest = 1;
+}
+
+static void
+_e_sys_systemd_check(void)
+{
+   Eldbus_Message *m;
+   
+   if (!conn) return;
+   if (!(m = _e_sys_systemd_login_manager_msg("CanPowerOff"))) return;
+   eldbus_connection_send(conn, m, _e_sys_systemd_check_cb, &_e_sys_can_halt, 
-1);
+   if (!(m = _e_sys_systemd_login_manager_msg("CanReboot"))) return;
+   eldbus_connection_send(conn, m, _e_sys_systemd_check_cb, 
&_e_sys_can_reboot, -1);
+   if (!(m = _e_sys_systemd_login_manager_msg("CanSuspend"))) return;
+   eldbus_connection_send(conn, m, _e_sys_systemd_check_cb, 
&_e_sys_can_suspend, -1);
+   if (!(m = _e_sys_systemd_login_manager_msg("CanHibernate"))) return;
+   eldbus_connection_send(conn, m, _e_sys_systemd_check_cb, 
&_e_sys_can_hibernate, -1);
+}
+
+static void
+_e_sys_systemd_exists_cb(void *data __UNUSED__, const Eldbus_Message *m, 
Eldbus_Pending *p __UNUSED__)
+{
+   const char *id = NULL;
+   
+   if (eldbus_message_error_get(m, NULL, NULL)) goto fail;
+   if (!eldbus_message_arguments_get(m, "s", &id)) goto fail;
+   if ((!id) || (id[0] != ':')) goto fail;
+   systemd_works = EINA_TRUE;
+   _e_sys_systemd_check();
+   return;
+fail:
+   systemd_works = EINA_FALSE;
+   /* delay this for 1.0 seconds while the rest of e starts up */
+   ecore_timer_add(1.0, _e_sys_cb_timer, NULL);
+}
+
+static void
+_e_sys_systemd_works_check(void)
+{
+   if (!conn)
+     {
+        /* delay this for 1.0 seconds while the rest of e starts up */
+        ecore_timer_add(1.0, _e_sys_cb_timer, NULL);
+        return;
+     }
+   eldbus_name_owner_get(conn, "org.freedesktop.login1",
+                         _e_sys_systemd_exists_cb, NULL);
+}
+
+static void
+_e_sys_systemd_login_manager_power_call(const char *method)
+{
+   Eldbus_Message *m;
+   
+   if (!conn) return;
+   if (!(m = _e_sys_systemd_login_manager_msg(method))) return;
+   eldbus_message_arguments_append(m, "b", 0);
+   eldbus_connection_send(conn, m, NULL, NULL, -1);
+}
+
+static void
+_e_sys_systemd_poweroff(void)
+{
+   _e_sys_systemd_login_manager_power_call("PowerOff");
+}
+
+static void
+_e_sys_systemd_reboot(void)
+{
+   _e_sys_systemd_login_manager_power_call("Reboot");
+}
+
+static void
+_e_sys_systemd_suspend(void)
+{
+   _e_sys_systemd_login_manager_power_call("Suspend");
+}
+
+static void
+_e_sys_systemd_hibernate(void)
+{
+   _e_sys_systemd_login_manager_power_call("Hibernate");
+}
+
 static Eina_Bool
 _e_sys_susp_hib_check_timer_cb(void *data __UNUSED__)
 {
@@ -668,6 +805,7 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, 
Eina_Bool raw)
 {
    char buf[PATH_MAX];
    E_Obj_Dialog *od;
+   int ret = 0;
 
    switch (a)
      {
@@ -733,7 +871,13 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, 
Eina_Bool raw)
              if (raw)
                {
                   _e_sys_begin_time = ecore_time_get();
-                  _e_sys_exe = ecore_exe_run(buf, NULL);
+                  if (systemd_works)
+                    _e_sys_systemd_poweroff();
+                  else
+                    {
+                       _e_sys_exe = ecore_exe_run(buf, NULL);
+                       ret = 1;
+                    }
                }
              else
                {
@@ -745,7 +889,13 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, 
Eina_Bool raw)
                   else
                     {
                        _e_sys_begin_time = ecore_time_get();
-                       _e_sys_exe = ecore_exe_run(buf, NULL);
+                       if (systemd_works)
+                         _e_sys_systemd_hibernate();
+                       else
+                         {
+                            _e_sys_exe = ecore_exe_run(buf, NULL);
+                            ret = 1;
+                         }
                        od = 
e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
                                              _("Power off"), "E", "_sys_halt");
                        e_obj_dialog_obj_theme_set(od, "base/theme/sys", 
"e/sys/halt");
@@ -780,7 +930,13 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, 
Eina_Bool raw)
              if (raw)
                {
                   _e_sys_begin_time = ecore_time_get();
-                  _e_sys_exe = ecore_exe_run(buf, NULL);
+                  if (systemd_works)
+                    _e_sys_systemd_reboot();
+                  else
+                    {
+                       _e_sys_exe = ecore_exe_run(buf, NULL);
+                       ret = 1;
+                    }
                }
              else
                {
@@ -792,7 +948,13 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, 
Eina_Bool raw)
                   else
                     {
                        _e_sys_begin_time = ecore_time_get();
-                       _e_sys_exe = ecore_exe_run(buf, NULL);
+                       if (systemd_works)
+                         _e_sys_systemd_reboot();
+                       else
+                         {
+                            _e_sys_exe = ecore_exe_run(buf, NULL);
+                            ret = 1;
+                         }
                        od = 
e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
                                              _("Resetting"), "E", 
"_sys_reboot");
                        e_obj_dialog_obj_theme_set(od, "base/theme/sys", 
"e/sys/reboot");
@@ -829,7 +991,13 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, 
Eina_Bool raw)
                   if (e_config->desklock_on_suspend)
                     e_desklock_show(EINA_TRUE);
                   _e_sys_begin_time = ecore_time_get();
-                  _e_sys_exe = ecore_exe_run(buf, NULL);
+                  if (systemd_works)
+                    _e_sys_systemd_suspend();
+                  else
+                    {
+                       _e_sys_exe = ecore_exe_run(buf, NULL);
+                       ret = 1;
+                    }
                }
              else
                {
@@ -847,7 +1015,13 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, 
Eina_Bool raw)
                        _e_sys_susp_hib_check();
 
                        _e_sys_begin_time = ecore_time_get();
-                       _e_sys_exe = ecore_exe_run(buf, NULL);
+                       if (systemd_works)
+                         _e_sys_systemd_suspend();
+                       else
+                         {
+                            _e_sys_exe = ecore_exe_run(buf, NULL);
+                            ret = 1;
+                         }
                        od = 
e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
                                              _("Suspending"), "E", 
"_sys_suspend");
                        e_obj_dialog_obj_theme_set(od, "base/theme/sys", 
"e/sys/suspend");
@@ -884,7 +1058,13 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, 
Eina_Bool raw)
                   if (e_config->desklock_on_suspend)
                     e_desklock_show(EINA_TRUE);
                   _e_sys_begin_time = ecore_time_get();
-                  _e_sys_exe = ecore_exe_run(buf, NULL);
+                  if (systemd_works)
+                    _e_sys_systemd_hibernate();
+                  else
+                    {
+                       _e_sys_exe = ecore_exe_run(buf, NULL);
+                       ret = 1;
+                    }
                }
              else
                {
@@ -902,7 +1082,13 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, 
Eina_Bool raw)
                        _e_sys_susp_hib_check();
 
                        _e_sys_begin_time = ecore_time_get();
-                       _e_sys_exe = ecore_exe_run(buf, NULL);
+                       if (systemd_works)
+                         _e_sys_systemd_hibernate();
+                       else
+                         {
+                            _e_sys_exe = ecore_exe_run(buf, NULL);
+                            ret = 1;
+                         }
                        od = 
e_obj_dialog_new(e_container_current_get(e_manager_current_get()),
                                              _("Hibernating"), "E", 
"_sys_hibernate");
                        e_obj_dialog_obj_theme_set(od, "base/theme/sys", 
"e/sys/hibernate");
@@ -923,7 +1109,7 @@ _e_sys_action_do(E_Sys_Action a, char *param __UNUSED__, 
Eina_Bool raw)
       default:
         return 0;
      }
-   return 1;
+   return ret;
 }
 
 static void

-- 

------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite!
It's a free troubleshooting tool designed for production.
Get down to code-level detail for bottlenecks, with <2% overhead. 
Download for free and get started troubleshooting in minutes. 
http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk

Reply via email to