|
|
|
@ -254,148 +254,142 @@ void reply_SetBrightness(DBusMessage* msg, DBusConnection* conn) {
|
|
|
|
|
free(safepath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void reply_CanSetPower(DBusMessage* msg, DBusConnection* conn, char* state) {
|
|
|
|
|
|
|
|
|
|
// check if path is writable
|
|
|
|
|
int writable = false;
|
|
|
|
|
int rval = access ("/sys/power/state", W_OK);
|
|
|
|
|
if (rval == 0) {
|
|
|
|
|
writable = true;
|
|
|
|
|
void reply_CanSetSuspend(DBusMessage* msg, DBusConnection* conn, 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)
|
|
|
|
|
{
|
|
|
|
|
reply_Bool(msg, conn, false); // send reply
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// check if method is supported
|
|
|
|
|
int method = false;
|
|
|
|
|
if (writable) {
|
|
|
|
|
FILE *node = fopen("/sys/power/state", "r");
|
|
|
|
|
if (node != NULL) {
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
reply_Bool(msg, conn, false); // send reply
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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, node);
|
|
|
|
|
ssize_t read = getline(&line, &len, disk_node);
|
|
|
|
|
if (read > 0 && line) {
|
|
|
|
|
method = strstr(line, state) != NULL;
|
|
|
|
|
result &= (strstr(line, disk) != NULL);
|
|
|
|
|
free(line);
|
|
|
|
|
}
|
|
|
|
|
if (fclose(node) == EOF) {
|
|
|
|
|
// Error!
|
|
|
|
|
}
|
|
|
|
|
fclose(disk_node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// send reply
|
|
|
|
|
reply_Bool(msg, conn, writable && method);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void reply_SetPower(DBusMessage* msg, DBusConnection* conn, char* state) {
|
|
|
|
|
|
|
|
|
|
// set power 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;
|
|
|
|
|
if (!result)
|
|
|
|
|
{
|
|
|
|
|
reply_Bool(msg, conn, false); // send reply
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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) {
|
|
|
|
|
// 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, disknode);
|
|
|
|
|
ssize_t read = getline(&line, &len, mem_node);
|
|
|
|
|
if (read > 0 && line) {
|
|
|
|
|
method2 = (strstr(line, disk) != NULL);
|
|
|
|
|
result &= (strstr(line, mem) != NULL);
|
|
|
|
|
free(line);
|
|
|
|
|
}
|
|
|
|
|
if (fclose(disknode) == EOF) {
|
|
|
|
|
// Error!
|
|
|
|
|
}
|
|
|
|
|
fclose(mem_node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// send reply
|
|
|
|
|
reply_Bool(msg, conn, state_writable && disk_writable && method1 && method2);
|
|
|
|
|
reply_Bool(msg, conn, result); // send reply
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
void reply_SetSuspend(DBusMessage* msg, DBusConnection* conn, 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);
|
|
|
|
|
}
|
|
|
|
|
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 (mem)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
if (files_writable)
|
|
|
|
|
{
|
|
|
|
|
// disk
|
|
|
|
|
if (disk)
|
|
|
|
|
{
|
|
|
|
|
FILE *disk_node = fopen("/sys/power/disk", "w");
|
|
|
|
|
if (disk_node) {
|
|
|
|
|
result &= (fputs(disk, disk_node) != EOF);
|
|
|
|
|
fclose(disk_node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (written1)
|
|
|
|
|
|
|
|
|
|
// mem_sleep
|
|
|
|
|
if (mem)
|
|
|
|
|
{
|
|
|
|
|
FILE *statenode = fopen("/sys/power/state", "w");
|
|
|
|
|
if (statenode != NULL) {
|
|
|
|
|
if (fputs(state, statenode) != EOF) {
|
|
|
|
|
written2 = true;
|
|
|
|
|
}
|
|
|
|
|
if (fclose(statenode) == EOF) {
|
|
|
|
|
// Error!
|
|
|
|
|
}
|
|
|
|
|
FILE *mem_node = fopen("/sys/power/mem_sleep", "w");
|
|
|
|
|
if (mem_node) {
|
|
|
|
|
result &= (fputs(mem, mem_node) != EOF);
|
|
|
|
|
fclose(mem_node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// state
|
|
|
|
|
FILE *state_node = fopen("/sys/power/state", "w");
|
|
|
|
|
if (state_node) {
|
|
|
|
|
result &= (fputs(state, state_node) != EOF);
|
|
|
|
|
fclose(state_node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create a reply from the message
|
|
|
|
|
reply = dbus_message_new_method_return(msg);
|
|
|
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
|
|
|
const char* member = dbus_message_get_member(msg);
|
|
|
|
|
|
|
|
|
|
// add the arguments to the reply
|
|
|
|
|
bool written = written1 && written2;
|
|
|
|
|
DBusMessageIter args;
|
|
|
|
|
dbus_message_iter_init_append(reply, &args);
|
|
|
|
|
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &written)) {
|
|
|
|
|
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &result)) {
|
|
|
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_message_iter_append_basic failed\n", member);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// send the reply && flush the connection
|
|
|
|
|
dbus_uint32_t serial = 0;
|
|
|
|
|
if (!dbus_connection_send(conn, reply, &serial)) {
|
|
|
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_connection_send failed\n", member);
|
|
|
|
|
return;
|
|
|
|
@ -786,35 +780,35 @@ void listen() {
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Brightness", "SetBrightness")) {
|
|
|
|
|
reply_SetBrightness(msg, conn);
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanStandby")) {
|
|
|
|
|
reply_CanSetPower(msg, conn, "standby");
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Standby")) {
|
|
|
|
|
reply_SetPower(msg, conn, "standby");
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanFreeze")) {
|
|
|
|
|
reply_CanSetPower(msg, conn, "freeze");
|
|
|
|
|
reply_CanSetSuspend(msg, conn, "freeze", NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Freeze")) {
|
|
|
|
|
reply_SetPower(msg, conn, "freeze");
|
|
|
|
|
reply_SetSuspend(msg, conn, "freeze", NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSuspend")) {
|
|
|
|
|
reply_CanSetPower(msg, conn, "mem");
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanStandby")) {
|
|
|
|
|
reply_CanSetSuspend(msg, conn, "standby", NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Suspend")) {
|
|
|
|
|
reply_SetPower(msg, conn, "mem");
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Standby")) {
|
|
|
|
|
reply_SetSuspend(msg, conn, "standby", NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHibernate")) {
|
|
|
|
|
reply_CanSetHibernation(msg, conn, "disk", "platform");
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSuspend")) {
|
|
|
|
|
reply_CanSetSuspend(msg, conn, "mem", NULL, "deep");
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Hibernate")) {
|
|
|
|
|
reply_SetHibernation(msg, conn, "disk", "platform");
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Suspend")) {
|
|
|
|
|
reply_SetSuspend(msg, conn, "mem", NULL, "deep");
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHybridSuspend")) {
|
|
|
|
|
reply_CanSetHibernation(msg, conn, "disk", "suspend");
|
|
|
|
|
reply_CanSetSuspend(msg, conn, "disk", "suspend", NULL);
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "HybridSuspend")) {
|
|
|
|
|
reply_SetHibernation(msg, conn, "disk", "suspend");
|
|
|
|
|
reply_SetSuspend(msg, conn, "disk", "suspend", NULL);
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHibernate")) {
|
|
|
|
|
reply_CanSetSuspend(msg, conn, "disk", "shutdown", NULL);
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Hibernate")) {
|
|
|
|
|
reply_SetSuspend(msg, conn, "disk", "shutdown", NULL);
|
|
|
|
|
}
|
|
|
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSetHibernationMethod")) {
|
|
|
|
|
reply_CanSetHibernationMethod(msg, conn);
|
|
|
|
|