You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1213 lines
39 KiB
1213 lines
39 KiB
#define DBUS_API_SUBJECT_TO_CHANGE
|
|
#include <dbus/dbus.h>
|
|
#include <stdbool.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
|
|
#include <tqdbusconnection.h>
|
|
#include <tqdbusdata.h>
|
|
#include <tqdbusdatamap.h>
|
|
#include <tqdbuserror.h>
|
|
#include <tqdbusmessage.h>
|
|
#include <tqdbusproxy.h>
|
|
#include <tqdbusvariant.h>
|
|
|
|
// Input devices
|
|
#include <linux/input.h>
|
|
|
|
#define BITS_PER_LONG (sizeof(long) * 8)
|
|
#define NUM_BITS(x) ((((x) - 1) / BITS_PER_LONG) + 1)
|
|
|
|
bool checkPolKitAuthorization(DBusMessage* msg, const TQString &action_id) {
|
|
if (!msg) {
|
|
return false;
|
|
}
|
|
TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
|
|
if (!dbusConn.isConnected()) {
|
|
return false;
|
|
}
|
|
TQT_DBusProxy polkitProxy("org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority",
|
|
"org.freedesktop.PolicyKit1.Authority", dbusConn);
|
|
if (polkitProxy.canSend()) {
|
|
// Check whether the requested action is authorized
|
|
TQString sender(dbus_message_get_sender(msg));
|
|
TQT_DBusVariant sysname;
|
|
sysname.value = TQT_DBusData::fromString(sender);
|
|
sysname.signature = sysname.value.buildDBusSignature();
|
|
TQT_DBusDataMap<TQString> subjectMap = TQT_DBusDataMap<TQString>();
|
|
subjectMap.insert(TQString("name"), TQT_DBusData::fromVariant(sysname));
|
|
TQValueList<TQT_DBusData> subjectStruct;
|
|
subjectStruct << TQT_DBusData::fromString("system-bus-name");
|
|
subjectStruct << TQT_DBusData::fromStringKeyMap(subjectMap);
|
|
|
|
TQMap<TQString, TQString> detailsMap;
|
|
detailsMap.insert(TQString(""), TQString(""));
|
|
TQT_DBusDataMap<TQString> dbusDetailsMap(detailsMap);
|
|
|
|
TQValueList<TQT_DBusData> params;
|
|
params << TQT_DBusData::fromStruct(subjectStruct);
|
|
params << TQT_DBusData::fromString(action_id);
|
|
params << TQT_DBusData::fromStringKeyMap(dbusDetailsMap);
|
|
params << TQT_DBusData::fromUInt32(0); // No user interaction
|
|
params << TQT_DBusData::fromString(""); // No cancellation
|
|
|
|
TQT_DBusMessage reply = polkitProxy.sendWithReply("CheckAuthorization", params);
|
|
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) {
|
|
return (reply[0].toStruct())[0].toBool();
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void replyBool(DBusMessage* msg, DBusConnection* conn, int value) {
|
|
DBusMessage* reply;
|
|
DBusMessageIter args;
|
|
const char* member = dbus_message_get_member(msg);
|
|
dbus_uint32_t serial = 0;
|
|
|
|
// create a reply from the message
|
|
reply = dbus_message_new_method_return(msg);
|
|
|
|
// add the arguments to the reply
|
|
dbus_message_iter_init_append(reply, &args);
|
|
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &value)) {
|
|
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 replyString(DBusMessage* msg, DBusConnection* conn, const char *str) {
|
|
DBusMessage* reply;
|
|
DBusMessageIter args;
|
|
const char* member = dbus_message_get_member(msg);
|
|
dbus_uint32_t serial = 0;
|
|
|
|
// create a reply from the message
|
|
reply = dbus_message_new_method_return(msg);
|
|
|
|
// add the arguments to the reply
|
|
dbus_message_iter_init_append(reply, &args);
|
|
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &str)) {
|
|
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);
|
|
}
|
|
|
|
bool setGivenPath(const char *path, const char *contents) {
|
|
int writable = (access(path, W_OK) == 0);
|
|
bool result = false;
|
|
if (writable) {
|
|
FILE *node = fopen(path, "w");
|
|
if (node != NULL) {
|
|
if (fputs(contents, node) != EOF) {
|
|
result = true;
|
|
}
|
|
fclose(node);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool canSetCPUGovernor(DBusMessage *msg, DBusConnection *conn) {
|
|
DBusMessageIter args;
|
|
const char *member = dbus_message_get_member(msg);
|
|
|
|
// read the arguments
|
|
if (!dbus_message_iter_init(msg, &args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no argument supplied\n", member);
|
|
return false;
|
|
}
|
|
else if (DBUS_TYPE_INT32 != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: argument not 32-bit integer\n", member);
|
|
return false;
|
|
}
|
|
dbus_int32_t cpunum;
|
|
dbus_message_iter_get_basic(&args, &cpunum);
|
|
|
|
char path[256];
|
|
snprintf(path, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpunum);
|
|
return (access(path, W_OK) == 0);
|
|
}
|
|
|
|
bool setCPUGovernor(DBusMessage *msg, DBusConnection *conn) {
|
|
DBusMessageIter args;
|
|
const char *member = dbus_message_get_member(msg);
|
|
|
|
// read the arguments
|
|
if (!dbus_message_iter_init(msg, &args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member);
|
|
return false;
|
|
}
|
|
else if (DBUS_TYPE_INT32 != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: first argument not 32-bit integer\n", member);
|
|
return false;
|
|
|
|
}
|
|
dbus_int32_t cpunum = -1;
|
|
dbus_message_iter_get_basic(&args, &cpunum);
|
|
|
|
if (!dbus_message_iter_next(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not supplied\n", member);
|
|
return false;
|
|
}
|
|
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not string\n", member);
|
|
return false;
|
|
}
|
|
char *governor = NULL;
|
|
dbus_message_iter_get_basic(&args, &governor);
|
|
|
|
bool result = false;
|
|
char path[256];
|
|
snprintf(path, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpunum);
|
|
if ((cpunum > -1) && governor) {
|
|
result = setGivenPath(path, governor);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool CanSetBrightness(DBusMessage* msg, DBusConnection* conn) {
|
|
DBusMessageIter args;
|
|
const char* member = dbus_message_get_member(msg);
|
|
|
|
// read the arguments
|
|
if (!dbus_message_iter_init(msg, &args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no argument supplied\n", member);
|
|
return false;
|
|
}
|
|
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: argument not string\n", member);
|
|
return false;
|
|
}
|
|
char *rawpath;
|
|
dbus_message_iter_get_basic(&args, &rawpath);
|
|
|
|
bool result = false;
|
|
char *safepath = realpath(rawpath, NULL);
|
|
if (safepath && (strstr(safepath, "/sys/devices") == safepath) &&
|
|
(strstr(safepath, "/brightness") == (safepath+strlen(safepath)-strlen("/brightness")))) {
|
|
result = (access(safepath, W_OK) == 0);
|
|
}
|
|
free(safepath);
|
|
return result;
|
|
}
|
|
|
|
bool SetBrightness(DBusMessage* msg, DBusConnection* conn) {
|
|
DBusMessageIter args;
|
|
const char* member = dbus_message_get_member(msg);
|
|
|
|
// read the arguments
|
|
if (!dbus_message_iter_init(msg, &args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member);
|
|
return false;
|
|
}
|
|
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: first argument not string\n", member);
|
|
return false;
|
|
}
|
|
char* rawpath;
|
|
dbus_message_iter_get_basic(&args, &rawpath);
|
|
|
|
if (!dbus_message_iter_next(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not supplied\n", member);
|
|
return false;
|
|
}
|
|
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not string\n", member);
|
|
return false;
|
|
}
|
|
char* brightness;
|
|
dbus_message_iter_get_basic(&args, &brightness);
|
|
|
|
bool result = false;
|
|
char* safepath;
|
|
safepath = realpath(rawpath, NULL);
|
|
if (safepath && brightness && (strstr(safepath, "/sys/devices") == safepath) &&
|
|
(strstr(safepath, "/brightness") == (safepath+strlen(safepath)-strlen("/brightness")))) {
|
|
result = setGivenPath(safepath, brightness);
|
|
}
|
|
free(safepath);
|
|
return result;
|
|
}
|
|
|
|
bool CanSetPowerState(const char* state, const char* disk, const 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 SetPowerState(const char* state, const char* disk, const 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);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
// mem_sleep
|
|
if (mem)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool CanSetHibernationMethod(DBusMessage* msg, DBusConnection* conn) {
|
|
return (access("/sys/power/disk", W_OK) == 0);
|
|
}
|
|
|
|
bool SetHibernationMethod(DBusMessage* msg, DBusConnection* conn) {
|
|
DBusMessageIter args;
|
|
const char* member = dbus_message_get_member(msg);
|
|
|
|
// read the arguments
|
|
if (!dbus_message_iter_init(msg, &args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member);
|
|
return false;
|
|
}
|
|
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: argument not string\n", member);
|
|
return false;
|
|
}
|
|
char* method = NULL;
|
|
dbus_message_iter_get_basic(&args, &method);
|
|
|
|
// set hibernation method
|
|
if (method) {
|
|
return setGivenPath("/sys/power/disk", method);
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void reply_InputEventsGetSwitches(DBusMessage* msg, DBusConnection* conn, bool active) {
|
|
DBusMessage* reply;
|
|
DBusMessageIter args, arrayIter;
|
|
const char* member = dbus_message_get_member(msg);
|
|
dbus_uint32_t serial = 0;
|
|
char* rawpath;
|
|
char* safepath;
|
|
int fd, r;
|
|
unsigned long switches[NUM_BITS(EV_CNT)];
|
|
|
|
// read the arguments
|
|
if (!dbus_message_iter_init(msg, &args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no argument supplied\n", member);
|
|
}
|
|
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: argument not string\n", member);
|
|
}
|
|
else {
|
|
dbus_message_iter_get_basic(&args, &rawpath);
|
|
}
|
|
|
|
safepath = realpath(rawpath, NULL);
|
|
|
|
if (safepath &&
|
|
(strstr(safepath, "/dev/input/event") == safepath)
|
|
) {
|
|
|
|
fd = open(safepath, O_RDONLY);
|
|
if( active ) {
|
|
r = ioctl(fd, EVIOCGSW(sizeof(switches)), switches);
|
|
}
|
|
else {
|
|
r = ioctl(fd, EVIOCGBIT(EV_SW, EV_CNT), switches);
|
|
}
|
|
if( r > 0 ) {
|
|
dbus_uint32_t dSwitches[NUM_BITS(EV_CNT)];
|
|
dbus_uint32_t *dSwitchesP = dSwitches;
|
|
int i;
|
|
|
|
// create a reply from the message
|
|
reply = dbus_message_new_method_return(msg);
|
|
|
|
// add the arguments to the reply
|
|
for( i = 0; i < sizeof(switches)/sizeof(switches[0]); i++ ) {
|
|
dSwitches[i] = switches[i];
|
|
}
|
|
dbus_message_iter_init_append(reply, &args);
|
|
if (!dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "u", &arrayIter)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_message_iter_open_container failed\n", member);
|
|
return;
|
|
}
|
|
if( !dbus_message_iter_append_fixed_array(&arrayIter, DBUS_TYPE_UINT32,
|
|
&dSwitchesP, sizeof(switches)/sizeof(switches[0])) ) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_message_iter_append_fixed_array failed\n", member);
|
|
return;
|
|
}
|
|
if (!dbus_message_iter_close_container(&args, &arrayIter)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_message_iter_close_container failed\n", member);
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
// create a reply from the message
|
|
reply = dbus_message_new_error_printf(msg,
|
|
"org.freedesktop.DBus.Error.NotSupported",
|
|
"Event device \"%s\" not support EV_SW ioctl",
|
|
safepath);
|
|
}
|
|
close(fd);
|
|
}
|
|
else {
|
|
// create a reply from the message
|
|
reply = dbus_message_new_error_printf(msg,
|
|
"org.freedesktop.DBus.Error.InvalidArgs",
|
|
"Event device \"%s\" is invalid",
|
|
rawpath);
|
|
}
|
|
|
|
// 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);
|
|
|
|
// free safepath
|
|
free(safepath);
|
|
}
|
|
|
|
void signal_NameAcquired(DBusMessage* msg) {
|
|
DBusMessageIter args;
|
|
char *name = NULL;
|
|
if(dbus_message_iter_init(msg, &args)) {
|
|
if(DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&args)) {
|
|
dbus_message_iter_get_basic(&args, &name);
|
|
}
|
|
}
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Name acquired: %s\n", name);
|
|
}
|
|
|
|
void reply_Introspect(DBusMessage* msg, DBusConnection* conn) {
|
|
DBusMessage* reply;
|
|
DBusMessageIter args;
|
|
dbus_uint32_t serial = 0;
|
|
size_t size = 4096;
|
|
const char* member = dbus_message_get_member(msg);
|
|
const char *path = dbus_message_get_path(msg);
|
|
char *data = new char[size];
|
|
|
|
// compose reply
|
|
strncpy(data,
|
|
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
|
|
" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n",
|
|
size);
|
|
strncat(data, "<node>\n", size-strlen(data));
|
|
if(strcmp("/", path) == 0) {
|
|
strncat(data, " <node name=\"org\" />\n", size-strlen(data));
|
|
}
|
|
else if(strcmp("/org", path) == 0) {
|
|
strncat(data, " <node name=\"trinitydesktop\" />\n", size-strlen(data));
|
|
}
|
|
else if(strcmp("/org/trinitydesktop", path) == 0) {
|
|
strncat(data, " <node name=\"hardwarecontrol\" />\n", size-strlen(data));
|
|
}
|
|
else if(strcmp("/org/trinitydesktop/hardwarecontrol", path) == 0) {
|
|
strncat(data,
|
|
" <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
|
|
" <method name=\"Introspect\">\n"
|
|
" <arg name=\"xml_data\" direction=\"out\" type=\"s\" />\n"
|
|
" </method>\n"
|
|
" </interface>\n"
|
|
" <interface name=\"org.freedesktop.DBus.Peer\">\n"
|
|
" <method name=\"Ping\"/>\n"
|
|
" <method name=\"GetMachineId\">\n"
|
|
" <arg name=\"machineUuid\" direction=\"out\" type=\"s\"/>\n"
|
|
" </method>\n"
|
|
" </interface>\n"
|
|
" <interface name=\"org.freedesktop.DBus.Properties\">\n"
|
|
" <method name=\"Get\">\n"
|
|
" <arg name=\"interfaceName\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"propertyName\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"v\"/>\n"
|
|
" </method>\n"
|
|
" <method name=\"GetAll\">\n"
|
|
" <arg name=\"interfaceName\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"propertyValues\" direction=\"out\" type=\"a{sv}\"/>\n"
|
|
" </method>\n"
|
|
" <method name=\"Set\">\n"
|
|
" <arg name=\"interfaceName\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"propertyName\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"value\" direction=\"in\" type=\"v\"/>\n"
|
|
" </method>\n"
|
|
" <signal name=\"PropertiesChanged\">\n"
|
|
" <arg name=\"interfaceName\" type=\"s\"/>\n"
|
|
" <arg name=\"changedProperties\" type=\"a{sv}\"/>\n"
|
|
" <arg name=\"invalidatedProperties\" type=\"as\"/>\n"
|
|
" </signal>\n"
|
|
" </interface>\n",
|
|
size-strlen(data));
|
|
strncat(data,
|
|
" <interface name=\"org.trinitydesktop.hardwarecontrol.Brightness\">\n"
|
|
" <method name=\"CanSetBrightness\">\n"
|
|
" <arg name=\"device\" direction=\"in\" type=\"s\" />\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" <method name=\"SetBrightness\">\n"
|
|
" <arg name=\"device\" direction=\"in\" type=\"s\" />\n"
|
|
" <arg name=\"brightness\" direction=\"in\" type=\"s\" />\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" </interface>\n",
|
|
size-strlen(data));
|
|
strncat(data,
|
|
" <interface name=\"org.trinitydesktop.hardwarecontrol.CPUGovernor\">\n"
|
|
" <method name=\"CanSetCPUGovernor\">\n"
|
|
" <arg name=\"cpu\" direction=\"in\" type=\"i\" />\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" <method name=\"SetCPUGovernor\">\n"
|
|
" <arg name=\"cpu\" direction=\"in\" type=\"i\" />\n"
|
|
" <arg name=\"governor\" direction=\"in\" type=\"s\" />\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" </interface>\n",
|
|
size-strlen(data));
|
|
strncat(data,
|
|
" <interface name=\"org.trinitydesktop.hardwarecontrol.InputEvents\">\n"
|
|
" <method name=\"GetProvidedSwitches\">\n"
|
|
" <arg name=\"device\" direction=\"in\" type=\"s\" />\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"au\" />\n"
|
|
" </method>\n"
|
|
" <method name=\"GetActiveSwitches\">\n"
|
|
" <arg name=\"device\" direction=\"in\" type=\"s\" />\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"au\" />\n"
|
|
" </method>\n"
|
|
" </interface>\n",
|
|
size-strlen(data));
|
|
strncat(data,
|
|
" <interface name=\"org.trinitydesktop.hardwarecontrol.Power\">\n"
|
|
" <method name=\"CanStandby\">\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" <method name=\"Standby\">\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" <method name=\"CanFreeze\">\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" <method name=\"Freeze\">\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" <method name=\"CanSuspend\">\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" <method name=\"Suspend\">\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" <method name=\"CanHibernate\">\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" <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"
|
|
" <method name=\"SetHibernationMethod\">\n"
|
|
" <arg name=\"method\" direction=\"in\" type=\"s\" />\n"
|
|
" <arg name=\"value\" direction=\"out\" type=\"b\" />\n"
|
|
" </method>\n"
|
|
" </interface>\n",
|
|
size-strlen(data));
|
|
}
|
|
strncat(data, "</node>\n", size-strlen(data));
|
|
|
|
// create a reply from the message
|
|
reply = dbus_message_new_method_return(msg);
|
|
|
|
// add the arguments to the reply
|
|
dbus_message_iter_init_append(reply, &args);
|
|
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &data)) {
|
|
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);
|
|
delete[] data;
|
|
}
|
|
|
|
void reply_PeerPing(DBusMessage* msg, DBusConnection* conn) {
|
|
// create and send a reply from the message
|
|
DBusMessage *reply = dbus_message_new_method_return(msg);
|
|
const char* member = dbus_message_get_member(msg);
|
|
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;
|
|
}
|
|
|
|
// flush the connection
|
|
dbus_connection_flush(conn);
|
|
|
|
// free the reply
|
|
dbus_message_unref(reply);
|
|
}
|
|
|
|
void reply_PeerGetMachineId(DBusMessage* msg, DBusConnection* conn) {
|
|
// get machine id from polkit service
|
|
TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
|
|
if (dbusConn.isConnected()) {
|
|
TQT_DBusProxy polkitProxy("org.freedesktop.PolicyKit1", "/org/freedesktop/DBus",
|
|
"org.freedesktop.DBus.Peer", dbusConn);
|
|
if (polkitProxy.canSend()) {
|
|
TQValueList<TQT_DBusData> params;
|
|
TQT_DBusMessage reply = polkitProxy.sendWithReply("GetMachineId", params);
|
|
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) {
|
|
TQCString machineId = reply[0].toString().utf8();
|
|
replyString(msg, conn, (const char*)machineId);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return an error in case of failure
|
|
DBusMessage* reply = dbus_message_new_error(msg, "org.freedesktop.DBus.Error.Failed", "Failed to get machine id.");
|
|
dbus_uint32_t serial = 0;
|
|
if (!dbus_connection_send(conn, reply, &serial)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Failed to get machine id.\n");
|
|
return;
|
|
}
|
|
|
|
// flush the connection
|
|
dbus_connection_flush(conn);
|
|
|
|
// free the reply
|
|
dbus_message_unref(reply);
|
|
|
|
}
|
|
|
|
void reply_PropertiesGet(DBusMessage* msg, DBusConnection* conn) {
|
|
// create a reply from the message
|
|
DBusMessage* reply = dbus_message_new_method_return(msg);
|
|
const char* member = dbus_message_get_member(msg);
|
|
|
|
// read the arguments
|
|
char *interfaceName, *propertyName;
|
|
|
|
bool argsOk = true;
|
|
DBusMessageIter args;
|
|
if (!dbus_message_iter_init(msg, &args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member);
|
|
argsOk = false;
|
|
}
|
|
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: first argument not string\n", member);
|
|
argsOk = false;
|
|
}
|
|
else {
|
|
dbus_message_iter_get_basic(&args, &interfaceName);
|
|
}
|
|
|
|
if (argsOk) {
|
|
if (!dbus_message_iter_next(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not supplied\n", member);
|
|
argsOk = false;
|
|
}
|
|
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not string\n", member);
|
|
argsOk = false;
|
|
}
|
|
else {
|
|
dbus_message_iter_get_basic(&args, &propertyName);
|
|
}
|
|
}
|
|
|
|
// send the reply
|
|
if (!argsOk) {
|
|
DBusMessage* reply = dbus_message_new_error(msg,
|
|
"org.freedesktop.DBus.Error.InvalidArgs", "Number or type of arguments do not match the expected signature.");
|
|
|
|
dbus_uint32_t serial = 0;
|
|
if (!dbus_connection_send(conn, reply, &serial)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Number or type of arguments do not match the expected signature.\n");
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
// Currently there are no properties at all, so return an error in all cases.
|
|
DBusMessage* reply = dbus_message_new_error_printf(msg,
|
|
"org.freedesktop.DBus.Error.InvalidArgs", "Property '%s' not found in interface '%s'.",
|
|
propertyName, interfaceName);
|
|
|
|
dbus_uint32_t serial = 0;
|
|
if (!dbus_connection_send(conn, reply, &serial)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Property '%s' not found in interface '%s'.\n",
|
|
propertyName, interfaceName);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// flush the connection
|
|
dbus_connection_flush(conn);
|
|
|
|
// free the reply
|
|
dbus_message_unref(reply);
|
|
}
|
|
|
|
void reply_PropertiesGetAll(DBusMessage* msg, DBusConnection* conn) {
|
|
// create a reply from the message
|
|
DBusMessage* reply = dbus_message_new_method_return(msg);
|
|
const char* member = dbus_message_get_member(msg);
|
|
|
|
// add the arguments to the reply
|
|
DBusMessageIter args, arrayIter;
|
|
dbus_message_iter_init_append(reply, &args);
|
|
if (!dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "sv", &arrayIter)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_message_iter_open_container failed\n", member);
|
|
return;
|
|
}
|
|
if (!dbus_message_iter_close_container(&args, &arrayIter)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_message_iter_close_container 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;
|
|
}
|
|
dbus_connection_flush(conn);
|
|
|
|
// free the reply
|
|
dbus_message_unref(reply);
|
|
}
|
|
|
|
void reply_PropertiesSet(DBusMessage* msg, DBusConnection* conn) {
|
|
// create a reply from the message
|
|
DBusMessage* reply = dbus_message_new_method_return(msg);
|
|
const char* member = dbus_message_get_member(msg);
|
|
|
|
// read the arguments
|
|
char *interfaceName, *propertyName;
|
|
|
|
bool argsOk = true;
|
|
DBusMessageIter args;
|
|
if (!dbus_message_iter_init(msg, &args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member);
|
|
argsOk = false;
|
|
}
|
|
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: first argument not string\n", member);
|
|
argsOk = false;
|
|
}
|
|
else {
|
|
dbus_message_iter_get_basic(&args, &interfaceName);
|
|
}
|
|
|
|
if (argsOk) {
|
|
if (!dbus_message_iter_next(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not supplied\n", member);
|
|
argsOk = false;
|
|
}
|
|
else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not string\n", member);
|
|
argsOk = false;
|
|
}
|
|
else {
|
|
dbus_message_iter_get_basic(&args, &propertyName);
|
|
}
|
|
}
|
|
|
|
if (argsOk) {
|
|
if (!dbus_message_iter_next(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: third argument not supplied\n", member);
|
|
argsOk = false;
|
|
}
|
|
else if (DBUS_TYPE_VARIANT != dbus_message_iter_get_arg_type(&args)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: third argument not variant\n", member);
|
|
argsOk = false;
|
|
}
|
|
else {
|
|
// TODO when real properties are passed: check variant type is consistent with required property
|
|
}
|
|
}
|
|
|
|
// send the reply
|
|
if (!argsOk) {
|
|
DBusMessage* reply = dbus_message_new_error(msg,
|
|
"org.freedesktop.DBus.Error.InvalidArgs", "Number or type of arguments do not match the expected signature.");
|
|
|
|
dbus_uint32_t serial = 0;
|
|
if (!dbus_connection_send(conn, reply, &serial)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Number or type of arguments do not match the expected signature.\n");
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
// Currently there are no properties at all, so nothing to set
|
|
DBusMessage* reply = dbus_message_new_error_printf(msg,
|
|
"org.freedesktop.DBus.Error.InvalidArgs", "Property '%s' not found in interface '%s'.",
|
|
propertyName, interfaceName);
|
|
|
|
dbus_uint32_t serial = 0;
|
|
if (!dbus_connection_send(conn, reply, &serial)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Property '%s' not found in interface '%s'.\n",
|
|
propertyName, interfaceName);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// flush the connection
|
|
dbus_connection_flush(conn);
|
|
|
|
// free the reply
|
|
dbus_message_unref(reply);
|
|
}
|
|
|
|
void signal_PropertiesChanged(DBusMessage* msg) {
|
|
// Currently there are no properties at all, so nothing to do
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] PropertiesChanged signal was received\n");
|
|
}
|
|
|
|
void error_UnknownMessage(DBusMessage* msg, DBusConnection* conn) {
|
|
const char* member = dbus_message_get_member(msg);
|
|
const char* interface = dbus_message_get_interface(msg);
|
|
// print message
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Unknown method '%s' called on interface '%s', ignoring\n", member, interface);
|
|
if (DBUS_MESSAGE_TYPE_METHOD_CALL != dbus_message_get_type(msg)) {
|
|
return;
|
|
}
|
|
|
|
// create a reply from the message
|
|
DBusMessage* reply = dbus_message_new_error_printf(msg,
|
|
"org.freedesktop.DBus.Error.UnknownMethod",
|
|
"Method \"%s\" on interface \"%s\" doesn't exist",
|
|
member, interface);
|
|
|
|
// 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;
|
|
}
|
|
dbus_connection_flush(conn);
|
|
|
|
// free the reply
|
|
dbus_message_unref(reply);
|
|
}
|
|
|
|
void error_PolkitAccessDenied(DBusMessage* msg, DBusConnection* conn) {
|
|
// create a reply from the message
|
|
DBusMessage* reply = dbus_message_new_error(msg,
|
|
"org.freedesktop.DBus.Error.AccessDenied", "Permission denied.");
|
|
|
|
// send the reply && flush the connection
|
|
dbus_uint32_t serial = 0;
|
|
if (!dbus_connection_send(conn, reply, &serial)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] error_PolkitAccessDenied: dbus_connection_send failed\n");
|
|
return;
|
|
}
|
|
dbus_connection_flush(conn);
|
|
|
|
// free the reply
|
|
dbus_message_unref(reply);
|
|
}
|
|
|
|
void listen() {
|
|
DBusMessage* msg;
|
|
DBusConnection* conn;
|
|
DBusError err;
|
|
int ret;
|
|
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Listening...\n");
|
|
|
|
// initialise the error structure
|
|
dbus_error_init(&err);
|
|
|
|
// connect to the bus and check for errors
|
|
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
|
|
if (dbus_error_is_set(&err)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Connection failed with error '%s'\n", err.message);
|
|
dbus_error_free(&err);
|
|
}
|
|
if (NULL == conn) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] No connection, exiting!\n");
|
|
exit(1);
|
|
}
|
|
|
|
// request our name on the bus and check for errors
|
|
ret = dbus_bus_request_name(conn, "org.trinitydesktop.hardwarecontrol", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
|
|
if (dbus_error_is_set(&err)) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Name request failed with error '%s'\n", err.message);
|
|
dbus_error_free(&err);
|
|
}
|
|
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
|
|
fprintf(stderr, "[tde_dbus_hardwarecontrol] Not primary owner (%d), exiting!\n", ret);
|
|
exit(1);
|
|
}
|
|
|
|
// loop, testing for new messages
|
|
// block for up to 1 second, exit in case the connection was lost
|
|
while (dbus_connection_read_write(conn, 1000)) {
|
|
// non blocking read of the next available message
|
|
msg = dbus_connection_pop_message(conn);
|
|
|
|
// loop again if we haven't got a message
|
|
if (NULL == msg) {
|
|
continue;
|
|
}
|
|
|
|
// check this is a method call for the right interface & method
|
|
if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.CPUGovernor", "CanSetCPUGovernor")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.cpugovernor.setcpugovernor");
|
|
if (result) {
|
|
result = canSetCPUGovernor(msg, conn);
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.CPUGovernor", "SetCPUGovernor")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.cpugovernor.setcpugovernor");
|
|
if (!result) {
|
|
error_PolkitAccessDenied(msg, conn);
|
|
}
|
|
else {
|
|
result = false;
|
|
if (canSetCPUGovernor(msg, conn)) {
|
|
result = setCPUGovernor(msg, conn);
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Brightness", "CanSetBrightness")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.brightness.setbrightness");
|
|
if (result) {
|
|
result = CanSetBrightness(msg, conn);
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Brightness", "SetBrightness")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.brightness.setbrightness");
|
|
if (!result) {
|
|
error_PolkitAccessDenied(msg, conn);
|
|
}
|
|
else {
|
|
result = false;
|
|
if (CanSetBrightness(msg, conn)) {
|
|
result = SetBrightness(msg, conn);
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanFreeze")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.freeze");
|
|
if (result) {
|
|
result = CanSetPowerState("freeze", NULL, NULL) || CanSetPowerState("mem", NULL, "s2idle");
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Freeze")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.freeze");
|
|
if (!result) {
|
|
error_PolkitAccessDenied(msg, conn);
|
|
}
|
|
else {
|
|
result = false;
|
|
if (CanSetPowerState("freeze", NULL, NULL)) {
|
|
result = SetPowerState("freeze", NULL, NULL);
|
|
}
|
|
else if (CanSetPowerState("mem", NULL, "s2idle")) {
|
|
result = SetPowerState("mem", NULL, "s2idle");
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanStandby")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.standby");
|
|
if (result) {
|
|
result = CanSetPowerState("standby", NULL, NULL) || CanSetPowerState("mem", NULL, "shallow");
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Standby")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.standby");
|
|
if (!result) {
|
|
error_PolkitAccessDenied(msg, conn);
|
|
}
|
|
else {
|
|
result = false;
|
|
if (CanSetPowerState("standby", NULL, NULL)) {
|
|
result = SetPowerState("standby", NULL, NULL);
|
|
}
|
|
else if (CanSetPowerState("mem", NULL, "shallow")) {
|
|
result = SetPowerState("mem", NULL, "shallow");
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSuspend")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.suspend");
|
|
if (result) {
|
|
result = (CanSetPowerState("mem", NULL, NULL) && access("/sys/power/mem_sleep", R_OK) != 0) ||
|
|
CanSetPowerState("mem", NULL, "deep");
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Suspend")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.suspend");
|
|
if (!result) {
|
|
error_PolkitAccessDenied(msg, conn);
|
|
}
|
|
else {
|
|
result = false;
|
|
if (CanSetPowerState("mem", NULL, NULL) && access("/sys/power/mem_sleep", R_OK) != 0) {
|
|
result = SetPowerState("mem", NULL, NULL);
|
|
}
|
|
else if (CanSetPowerState("mem", NULL, "deep")) {
|
|
result = SetPowerState("mem", NULL, "deep");
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHybridSuspend")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.hybridsuspend");
|
|
if (result) {
|
|
result = CanSetPowerState("disk", "suspend", NULL);
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "HybridSuspend")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.hybridsuspend");
|
|
if (!result) {
|
|
error_PolkitAccessDenied(msg, conn);
|
|
}
|
|
else {
|
|
result = false;
|
|
if (CanSetPowerState("disk", "suspend", NULL)) {
|
|
result = SetPowerState("disk", "suspend", NULL);
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHibernate")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.hibernate");
|
|
if (result) {
|
|
result = CanSetPowerState("disk", "shutdown", NULL) || CanSetPowerState("disk", "platform", NULL);
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Hibernate")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.hibernate");
|
|
if (!result) {
|
|
error_PolkitAccessDenied(msg, conn);
|
|
}
|
|
else {
|
|
result = false;
|
|
if (CanSetPowerState("disk", "shutdown", NULL)) {
|
|
result = SetPowerState("disk", "shutdown", NULL);
|
|
}
|
|
else if (CanSetPowerState("disk", "platform", NULL)) {
|
|
result = SetPowerState("disk", "platform", NULL);
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSetHibernationMethod")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.sethibernationmethod");
|
|
if (result) {
|
|
result = CanSetHibernationMethod(msg, conn);
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "SetHibernationMethod")) {
|
|
bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.sethibernationmethod");
|
|
if (!result) {
|
|
error_PolkitAccessDenied(msg, conn);
|
|
}
|
|
else {
|
|
result = false;
|
|
if (CanSetHibernationMethod(msg, conn)) {
|
|
result = SetHibernationMethod(msg, conn);
|
|
}
|
|
replyBool(msg, conn, result);
|
|
}
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.InputEvents", "GetProvidedSwitches")) {
|
|
reply_InputEventsGetSwitches(msg, conn, false);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.InputEvents", "GetActiveSwitches")) {
|
|
reply_InputEventsGetSwitches(msg, conn, true);
|
|
}
|
|
else if (dbus_message_is_signal(msg, "org.freedesktop.DBus", "NameAcquired")) {
|
|
signal_NameAcquired(msg);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")) {
|
|
reply_Introspect(msg, conn);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Peer", "Ping")) {
|
|
reply_PeerPing(msg, conn);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Peer", "GetMachineId")) {
|
|
reply_PeerGetMachineId(msg, conn);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties", "Get")) {
|
|
reply_PropertiesGet(msg, conn);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties", "GetAll")) {
|
|
reply_PropertiesGetAll(msg, conn);
|
|
}
|
|
else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Properties", "Set")) {
|
|
reply_PropertiesSet(msg, conn);
|
|
}
|
|
else if (dbus_message_is_signal(msg, "org.freedesktop.DBus", "PropertiesChanged")) {
|
|
signal_PropertiesChanged(msg);
|
|
}
|
|
else {
|
|
error_UnknownMessage(msg, conn);
|
|
}
|
|
|
|
// free the message
|
|
dbus_message_unref(msg);
|
|
}
|
|
|
|
// close the connection
|
|
dbus_connection_unref(conn);
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
listen();
|
|
return 0;
|
|
}
|