summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2018-11-10 01:06:57 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2019-02-06 23:37:11 +0900
commitcebadfa114d50a465f9d04d59da5015fed673b26 (patch)
tree72e80ca3cebccc9a665f53830e71ee898f47b0ea
parentbd468a3703ac47e559a945ed7e1afbc082bcaddf (diff)
downloadtdelibs-cebadfa114d50a465f9d04d59da5015fed673b26.tar.gz
tdelibs-cebadfa114d50a465f9d04d59da5015fed673b26.zip
Improved support for suspend modes for both older and newer kernels.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
-rw-r--r--tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c75
-rw-r--r--tdecore/tdehw/tdehardwaredevices.cpp35
-rw-r--r--tdecore/tdehw/tderootsystemdevice.cpp161
3 files changed, 212 insertions, 59 deletions
diff --git a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c
index a0b6870b..2a10d67c 100644
--- a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c
+++ b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c
@@ -254,7 +254,7 @@ void reply_SetBrightness(DBusMessage* msg, DBusConnection* conn) {
free(safepath);
}
-void reply_CanSetSuspend(DBusMessage* msg, DBusConnection* conn, char* state, char* disk, char* mem) {
+bool check_CanSetSuspend(char* state, char* disk, char* mem) {
// check if required files are writable
bool files_writable = (access("/sys/power/state", W_OK) == 0);
if (disk)
@@ -267,7 +267,7 @@ void reply_CanSetSuspend(DBusMessage* msg, DBusConnection* conn, char* state, ch
}
if (!files_writable)
{
- reply_Bool(msg, conn, false); // send reply
+ return false;
}
// check if method is supported
@@ -286,7 +286,7 @@ void reply_CanSetSuspend(DBusMessage* msg, DBusConnection* conn, char* state, ch
}
if (!result)
{
- reply_Bool(msg, conn, false); // send reply
+ return false;
}
// disk
@@ -306,7 +306,7 @@ void reply_CanSetSuspend(DBusMessage* msg, DBusConnection* conn, char* state, ch
}
if (!result)
{
- reply_Bool(msg, conn, false); // send reply
+ return false;
}
// mem_sleep
@@ -324,11 +324,10 @@ void reply_CanSetSuspend(DBusMessage* msg, DBusConnection* conn, char* state, ch
fclose(mem_node);
}
}
-
- reply_Bool(msg, conn, result); // send reply
+ return result;
}
-void reply_SetSuspend(DBusMessage* msg, DBusConnection* conn, char* state, char* disk, char* mem) {
+bool do_SetSuspend(char* state, char* disk, char* mem) {
// check if required files are writable
bool files_writable = (access("/sys/power/state", W_OK) == 0);
if (disk)
@@ -339,10 +338,6 @@ void reply_SetSuspend(DBusMessage* msg, DBusConnection* conn, char* state, char*
{
files_writable &= (access("/sys/power/mem_sleep", W_OK) == 0);
}
- if (!files_writable)
- {
- reply_Bool(msg, conn, false); // send reply
- }
// set suspend mode
bool result = files_writable;
@@ -375,7 +370,10 @@ void reply_SetSuspend(DBusMessage* msg, DBusConnection* conn, char* state, char*
fclose(state_node);
}
}
+ return result;
+}
+void reply_SetSuspend(DBusMessage* msg, DBusConnection* conn, bool result) {
// create a reply from the message
DBusMessage *reply = dbus_message_new_method_return(msg);
const char* member = dbus_message_get_member(msg);
@@ -781,34 +779,69 @@ void listen() {
reply_SetBrightness(msg, conn);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanFreeze")) {
- reply_CanSetSuspend(msg, conn, "freeze", NULL, NULL);
+ bool result = check_CanSetSuspend("freeze", NULL, NULL) || check_CanSetSuspend("mem", NULL, "s2idle");
+ reply_Bool(msg, conn, result);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Freeze")) {
- reply_SetSuspend(msg, conn, "freeze", NULL, NULL);
+ bool result = false;
+ if (check_CanSetSuspend("freeze", NULL, NULL)) {
+ result = do_SetSuspend("freeze", NULL, NULL);
+ }
+ else if (check_CanSetSuspend("mem", NULL, "s2idle")) {
+ result = do_SetSuspend("mem", NULL, "s2idle");
+ }
+ reply_SetSuspend(msg, conn, result);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanStandby")) {
- reply_CanSetSuspend(msg, conn, "standby", NULL, NULL);
+ bool result = check_CanSetSuspend("standby", NULL, NULL) || check_CanSetSuspend("mem", NULL, "shallow");
+ reply_Bool(msg, conn, result);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Standby")) {
- reply_SetSuspend(msg, conn, "standby", NULL, NULL);
+ bool result = false;
+ if (check_CanSetSuspend("standby", NULL, NULL)) {
+ result = do_SetSuspend("standby", NULL, NULL);
+ }
+ else if (check_CanSetSuspend("mem", NULL, "shallow")) {
+ result = do_SetSuspend("mem", NULL, "shallow");
+ }
+ reply_SetSuspend(msg, conn, result);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSuspend")) {
- reply_CanSetSuspend(msg, conn, "mem", NULL, "deep");
+ bool result = (check_CanSetSuspend("mem", NULL, NULL) && access("/sys/power/mem_sleep", R_OK) != 0) ||
+ check_CanSetSuspend("mem", NULL, "deep");
+ reply_Bool(msg, conn, result);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Suspend")) {
- reply_SetSuspend(msg, conn, "mem", NULL, "deep");
+ bool result = false;
+ if (check_CanSetSuspend("mem", NULL, NULL) && access("/sys/power/mem_sleep", R_OK) != 0) {
+ result = do_SetSuspend("mem", NULL, NULL);
+ }
+ else if (check_CanSetSuspend("mem", NULL, "deep")) {
+ result = do_SetSuspend("mem", NULL, "deep");
+ }
+ reply_SetSuspend(msg, conn, result);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHybridSuspend")) {
- reply_CanSetSuspend(msg, conn, "disk", "suspend", NULL);
+ bool result = check_CanSetSuspend("disk", "suspend", NULL);
+ reply_Bool(msg, conn, result);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "HybridSuspend")) {
- reply_SetSuspend(msg, conn, "disk", "suspend", NULL);
+ bool result = do_SetSuspend("disk", "suspend", NULL);
+ reply_SetSuspend(msg, conn, result);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHibernate")) {
- reply_CanSetSuspend(msg, conn, "disk", "shutdown", NULL);
+ bool result = check_CanSetSuspend("disk", "shutdown", NULL) || check_CanSetSuspend("disk", "platform", NULL);
+ reply_Bool(msg, conn, result);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Hibernate")) {
- reply_SetSuspend(msg, conn, "disk", "shutdown", NULL);
+ bool result = false;
+ if (check_CanSetSuspend("disk", "shutdown", NULL)) {
+ result = do_SetSuspend("disk", "shutdown", NULL);
+ }
+ else if (check_CanSetSuspend("disk", "platform", NULL)) {
+ result = do_SetSuspend("disk", "platform", NULL);
+ }
+ reply_SetSuspend(msg, conn, result);
}
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSetHibernationMethod")) {
reply_CanSetHibernationMethod(msg, conn);
diff --git a/tdecore/tdehw/tdehardwaredevices.cpp b/tdecore/tdehw/tdehardwaredevices.cpp
index c636e088..fb08ae48 100644
--- a/tdecore/tdehw/tdehardwaredevices.cpp
+++ b/tdecore/tdehw/tdehardwaredevices.cpp
@@ -3366,12 +3366,12 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
// Always assume that these two fully on/fully off states are available
powerstates.append(TDESystemPowerState::Active);
powerstates.append(TDESystemPowerState::PowerOff);
- if (line.contains("standby")) {
- powerstates.append(TDESystemPowerState::Standby);
- }
if (line.contains("freeze")) {
powerstates.append(TDESystemPowerState::Freeze);
}
+ if (line.contains("standby")) {
+ powerstates.append(TDESystemPowerState::Standby);
+ }
if (line.contains("mem")) {
powerstates.append(TDESystemPowerState::Mem);
}
@@ -3440,17 +3440,34 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
}
++valuesdirit;
}
- // Suspend-to-RAM requires a combination of 'mem' and 'deep' in two different files
- if (powerstates.contains(TDESystemPowerState::Mem) &&
- suspendmodes.contains(TDESystemSuspendMode::SuspendToRAM)) {
- powerstates.append(TDESystemPowerState::Suspend);
- powerstates.remove(TDESystemPowerState::Mem);
+ // Freeze can also be set if /sys/power/mem_sleep exists and contains 's2idle'
+ if (!powerstates.contains(TDESystemPowerState::Freeze) &&
+ powerstates.contains(TDESystemPowerState::Mem) &&
+ suspendmodes.contains(TDESystemSuspendMode::Standby)) {
+ powerstates.append(TDESystemPowerState::Freeze);
+ }
+ // Standby can also be set if /sys/power/mem_sleep exists and contains 'shallow'
+ if (!powerstates.contains(TDESystemPowerState::Standby) &&
+ powerstates.contains(TDESystemPowerState::Mem) &&
+ suspendmodes.contains(TDESystemSuspendMode::Standby)) {
+ powerstates.append(TDESystemPowerState::Standby);
+ }
+ // Suspend-to-RAM can be set in various ways (not necessarily all available in the same system)
+ // 1) if /sys/power/mem_sleep exists and contains 'deep'
+ // 2) if /sys/power/mem_sleep does not exists, requires support for 'mem' in /sys/power/state
+ if (!powerstates.contains(TDESystemPowerState::Suspend) &&
+ powerstates.contains(TDESystemPowerState::Mem)) {
+ if (suspendmodes.contains(TDESystemSuspendMode::SuspendToRAM) || suspendmodes.count() == 0) {
+ powerstates.append(TDESystemPowerState::Suspend);
+ }
}
+ powerstates.remove(TDESystemPowerState::Mem);
// Hibernation and Hybrid Suspend are not real power states, being just two different
// ways of suspending to disk. Since they are very common and it is very convenient to
// treat them as power states, we do so, as other power frameworks also do.
if (powerstates.contains(TDESystemPowerState::Disk) &&
- hibernationmethods.contains(TDESystemHibernationMethod::Shutdown)) {
+ (hibernationmethods.contains(TDESystemHibernationMethod::Shutdown) ||
+ hibernationmethods.contains(TDESystemHibernationMethod::Platform))) {
powerstates.append(TDESystemPowerState::Hibernate);
}
if (powerstates.contains(TDESystemPowerState::Disk) &&
diff --git a/tdecore/tdehw/tderootsystemdevice.cpp b/tdecore/tdehw/tderootsystemdevice.cpp
index bbbd63b1..e53342ae 100644
--- a/tdecore/tdehw/tderootsystemdevice.cpp
+++ b/tdecore/tdehw/tderootsystemdevice.cpp
@@ -21,6 +21,7 @@
#include "tdestoragedevice.h"
#include <unistd.h>
+#include <stdlib.h>
#include <tqfile.h>
@@ -657,41 +658,143 @@ void TDERootSystemDevice::setHibernationMethod(TDESystemHibernationMethod::TDESy
}
+bool check_CanSetSuspend(char* state, char* disk, char* mem) {
+ // check if required files are writable
+ bool files_writable = (access("/sys/power/state", W_OK) == 0);
+ if (disk)
+ {
+ files_writable &= (access("/sys/power/disk", W_OK) == 0);
+ }
+ if (mem)
+ {
+ files_writable &= (access("/sys/power/mem_sleep", W_OK) == 0);
+ }
+ if (!files_writable)
+ {
+ return false;
+ }
+
+ // check if method is supported
+ bool result = false;
+ // state
+ FILE *state_node = fopen("/sys/power/state", "r");
+ if (state_node) {
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t read = getline(&line, &len, state_node);
+ if (read > 0 && line) {
+ result = (strstr(line, state) != NULL);
+ free(line);
+ }
+ fclose(state_node);
+ }
+ if (!result)
+ {
+ return false;
+ }
+
+ // disk
+ if (disk)
+ {
+ FILE *disk_node = fopen("/sys/power/disk", "r");
+ if (disk_node) {
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t read = getline(&line, &len, disk_node);
+ if (read > 0 && line) {
+ result &= (strstr(line, disk) != NULL);
+ free(line);
+ }
+ fclose(disk_node);
+ }
+ }
+ if (!result)
+ {
+ return false;
+ }
+
+ // mem_sleep
+ if (mem)
+ {
+ FILE *mem_node = fopen("/sys/power/mem_sleep", "r");
+ if (mem_node) {
+ char *line = NULL;
+ size_t len = 0;
+ ssize_t read = getline(&line, &len, mem_node);
+ if (read > 0 && line) {
+ result &= (strstr(line, mem) != NULL);
+ free(line);
+ }
+ fclose(mem_node);
+ }
+ }
+ return result;
+}
+
bool TDERootSystemDevice::setPowerState(TDESystemPowerState::TDESystemPowerState ps) {
if ((ps == TDESystemPowerState::Freeze) || (ps == TDESystemPowerState::Standby) ||
(ps == TDESystemPowerState::Suspend) || (ps == TDESystemPowerState::Hibernate) ||
(ps == TDESystemPowerState::HybridSuspend)) {
TQString statenode = "/sys/power/state";
TQString disknode = "/sys/power/disk";
+ TQString memnode = "/sys/power/mem_sleep";
TQFile statefile( statenode );
TQFile diskfile( disknode );
- if ( statefile.open( IO_WriteOnly ) &&
- ((ps != TDESystemPowerState::Hibernate && ps != TDESystemPowerState::HybridSuspend) ||
- diskfile.open( IO_WriteOnly )) ) {
- TQString powerCommand;
- if (ps == TDESystemPowerState::Freeze) {
- powerCommand = "freeze";
+ TQFile memfile( memnode );
+ TQString stateCommand = TQString::null;
+ TQString diskCommand = TQString::null;
+ TQString memCommand = TQString::null;
+ if (ps == TDESystemPowerState::Freeze) {
+ if (check_CanSetSuspend("freeze", NULL, NULL)) {
+ stateCommand = "freeze";
}
- else if (ps == TDESystemPowerState::Standby) {
- powerCommand = "standby";
+ else {
+ stateCommand = "mem";
+ diskCommand = "s2idle";
}
- else if (ps == TDESystemPowerState::Suspend) {
- powerCommand = "mem";
+ }
+ else if (ps == TDESystemPowerState::Standby) {
+ if (check_CanSetSuspend("standby", NULL, NULL)) {
+ stateCommand = "standby";
}
- else if (ps == TDESystemPowerState::Hibernate) {
- powerCommand = "disk";
- TQTextStream diskstream( &diskfile );
- diskstream << "platform";
- diskfile.close();
+ else {
+ stateCommand = "mem";
+ diskCommand = "shallow";
}
- else if (ps == TDESystemPowerState::HybridSuspend) {
- powerCommand = "disk";
- TQTextStream diskstream( &diskfile );
- diskstream << "suspend";
- diskfile.close();
+ }
+ else if (ps == TDESystemPowerState::Suspend) {
+ stateCommand = "mem";
+ if (check_CanSetSuspend("mem", NULL, "deep")) {
+ diskCommand = "deep";
+ }
+ }
+ else if (ps == TDESystemPowerState::HybridSuspend) {
+ stateCommand = "disk";
+ diskCommand = "suspend";
+ }
+ else if (ps == TDESystemPowerState::Hibernate) {
+ stateCommand = "disk";
+ if (check_CanSetSuspend("disk", "shutdown", NULL)) {
+ diskCommand = "shutdown";
+ }
+ else {
+ diskCommand = "platform";
}
+ }
+
+ if (memCommand != TQString::null && memfile.open( IO_WriteOnly )) {
+ TQTextStream memstream( &memfile );
+ memstream << memCommand;
+ memfile.close();
+ }
+ if (diskCommand != TQString::null && diskfile.open( IO_WriteOnly )) {
+ TQTextStream diskstream( &diskfile );
+ diskstream << diskCommand;
+ diskfile.close();
+ }
+ if (stateCommand != TQString::null && statefile.open( IO_WriteOnly )) {
TQTextStream statestream( &statefile );
- statestream << powerCommand;
+ statestream << stateCommand;
statefile.close();
return true;
}
@@ -855,23 +958,23 @@ bool TDERootSystemDevice::setPowerState(TDESystemPowerState::TDESystemPowerState
TQT_DBusConnection dbusConn;
dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
if ( dbusConn.isConnected() ) {
- if (ps == TDESystemPowerState::Standby) {
+ if (ps == TDESystemPowerState::Freeze) {
TQT_DBusMessage msg = TQT_DBusMessage::methodCall(
"org.trinitydesktop.hardwarecontrol",
"/org/trinitydesktop/hardwarecontrol",
"org.trinitydesktop.hardwarecontrol.Power",
- "Standby");
+ "Freeze");
TQT_DBusMessage reply = dbusConn.sendWithReply(msg);
if (reply.type() == TQT_DBusMessage::ReplyMessage) {
return true;
}
}
- else if (ps == TDESystemPowerState::Freeze) {
+ else if (ps == TDESystemPowerState::Standby) {
TQT_DBusMessage msg = TQT_DBusMessage::methodCall(
"org.trinitydesktop.hardwarecontrol",
"/org/trinitydesktop/hardwarecontrol",
"org.trinitydesktop.hardwarecontrol.Power",
- "Freeze");
+ "Standby");
TQT_DBusMessage reply = dbusConn.sendWithReply(msg);
if (reply.type() == TQT_DBusMessage::ReplyMessage) {
return true;
@@ -888,23 +991,23 @@ bool TDERootSystemDevice::setPowerState(TDESystemPowerState::TDESystemPowerState
return true;
}
}
- else if (ps == TDESystemPowerState::Hibernate) {
+ else if (ps == TDESystemPowerState::HybridSuspend) {
TQT_DBusMessage msg = TQT_DBusMessage::methodCall(
"org.trinitydesktop.hardwarecontrol",
"/org/trinitydesktop/hardwarecontrol",
"org.trinitydesktop.hardwarecontrol.Power",
- "Hibernate");
+ "HybridSuspend");
TQT_DBusMessage reply = dbusConn.sendWithReply(msg);
if (reply.type() == TQT_DBusMessage::ReplyMessage) {
return true;
}
}
- else if (ps == TDESystemPowerState::HybridSuspend) {
+ else if (ps == TDESystemPowerState::Hibernate) {
TQT_DBusMessage msg = TQT_DBusMessage::methodCall(
"org.trinitydesktop.hardwarecontrol",
"/org/trinitydesktop/hardwarecontrol",
"org.trinitydesktop.hardwarecontrol.Power",
- "HybridSuspend");
+ "Hibernate");
TQT_DBusMessage reply = dbusConn.sendWithReply(msg);
if (reply.type() == TQT_DBusMessage::ReplyMessage) {
return true;