diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2016-04-26 19:44:38 +1000 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2016-04-26 19:44:38 +1000 |
commit | ba3ed714c6ef94db907740a44dd75bdd701d3ff3 (patch) | |
tree | d5c3b197ef58fde1ccfba182ac035725d4c55720 /tdecore | |
parent | 3b095cf3cd208624f0f7fdb353982185827aa6a4 (diff) | |
download | tdelibs-ba3ed714c6ef94db907740a44dd75bdd701d3ff3.tar.gz tdelibs-ba3ed714c6ef94db907740a44dd75bdd701d3ff3.zip |
tdecore: Added DBus support for hybrid suspend (aka suspend to RAM + suspend to disk).
This relates to bug 2601.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'tdecore')
-rw-r--r-- | tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c | 131 |
1 files changed, 129 insertions, 2 deletions
diff --git a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c index f88c5ab5a..aed9984ed 100644 --- a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c +++ b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c @@ -291,6 +291,121 @@ void reply_SetPower(DBusMessage* msg, DBusConnection* conn, char* state) { reply_SetGivenPath(msg, conn, "/sys/power/state", state); } +void reply_CanSetHibernation(DBusMessage* msg, DBusConnection* conn, char* state, char* disk) { + + // check if path is writable + bool state_writable = false; + int rval = access ("/sys/power/state", W_OK); + if (rval == 0) { + state_writable = true; + } + bool disk_writable = false; + rval = access ("/sys/power/disk", W_OK); + if (rval == 0) { + disk_writable = true; + } + + // check if method is supported + bool method1 = false, method2 = false; + if (state_writable && disk_writable) { + FILE *statenode = fopen("/sys/power/state", "r"); + if (statenode != NULL) { + char *line = NULL; + size_t len = 0; + ssize_t read = getline(&line, &len, statenode); + if (read > 0 && line) { + method1 = (strstr(line, state) != NULL); + free(line); + } + if (fclose(statenode) == EOF) { + // Error! + } + } + FILE *disknode = fopen("/sys/power/disk", "r"); + if (disknode != NULL) { + char *line = NULL; + size_t len = 0; + ssize_t read = getline(&line, &len, disknode); + if (read > 0 && line) { + method2 = (strstr(line, disk) != NULL); + free(line); + } + if (fclose(disknode) == EOF) { + // Error! + } + } + } + + // send reply + reply_Bool(msg, conn, state_writable && disk_writable && method1 && method2); +} + +void reply_SetHibernation(DBusMessage* msg, DBusConnection* conn, char* state, char* disk) { + // set hibernation state + DBusMessage* reply; + DBusMessageIter args; + const char* member = dbus_message_get_member(msg); + dbus_uint32_t serial = 0; + bool written1 = false, written2 = false; + + // check if path is writable + int state_writable = false; + int rval = access ("/sys/power/state", W_OK); + if (rval == 0) { + state_writable = true; + } + int disk_writable = false; + rval = access ("/sys/power/disk", W_OK); + if (rval == 0) { + disk_writable = true; + } + + if (state_writable && disk_writable) { + FILE *disknode = fopen("/sys/power/disk", "w"); + if (disknode != NULL) { + if (fputs(disk, disknode) != EOF) { + written1 = true; + } + if (fclose(disknode) == EOF) { + // Error! + } + } + if (written1) + { + FILE *statenode = fopen("/sys/power/state", "w"); + if (statenode != NULL) { + if (fputs(state, statenode) != EOF) { + written2 = true; + } + if (fclose(statenode) == EOF) { + // Error! + } + } + } + } + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + + // add the arguments to the reply + bool written = written1 && written2; + dbus_message_iter_init_append(reply, &args); + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &written)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_message_iter_append_basic failed\n", member); + return; + } + + // send the reply && flush the connection + if (!dbus_connection_send(conn, reply, &serial)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_connection_send failed\n", member); + return; + } + dbus_connection_flush(conn); + + // free the reply + dbus_message_unref(reply); +} + void reply_CanSetHibernationMethod(DBusMessage* msg, DBusConnection* conn) { // check if path is writable @@ -514,6 +629,12 @@ void reply_Introspect(DBusMessage* msg, DBusConnection* conn) { " <method name=\"Hibernate\">\n" " <arg name=\"value\" direction=\"out\" type=\"b\" />\n" " </method>\n" + " <method name=\"CanHybridSuspend\">\n" + " <arg name=\"value\" direction=\"out\" type=\"b\" />\n" + " </method>\n" + " <method name=\"HybridSuspend\">\n" + " <arg name=\"value\" direction=\"out\" type=\"b\" />\n" + " </method>\n" " <method name=\"CanSetHibernationMethod\">\n" " <arg name=\"value\" direction=\"out\" type=\"b\" />\n" " </method>\n" @@ -684,10 +805,16 @@ void listen() { reply_SetPower(msg, conn, "mem"); } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHibernate")) { - reply_CanSetPower(msg, conn, "disk"); + reply_CanSetHibernation(msg, conn, "disk", "platform"); } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Hibernate")) { - reply_SetPower(msg, conn, "disk"); + reply_SetHibernation(msg, conn, "disk", "platform"); + } + else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHybridSuspend")) { + reply_CanSetHibernation(msg, conn, "disk", "suspend"); + } + else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "HybridSuspend")) { + reply_SetHibernation(msg, conn, "disk", "suspend"); } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSetHibernationMethod")) { reply_CanSetHibernationMethod(msg, conn); |