From b11c80958878278a87e6b75ed8d47aff6ac1219c Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Mon, 21 Jan 2019 23:29:28 +0900 Subject: Added polkit support to TDE HW DBus daemon and removed obsolete "at_console" support. Signed-off-by: Michele Calgaro --- CMakeLists.txt | 8 + tdecore/tdehw/hwlibdaemons/dbus/CMakeLists.txt | 19 +- .../dbus/org.trinitydesktop.hardwarecontrol.conf | 11 +- .../dbus/org.trinitydesktop.hardwarecontrol.policy | 60 ++ .../hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c | 856 ------------------ .../hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp | 982 +++++++++++++++++++++ 6 files changed, 1063 insertions(+), 873 deletions(-) create mode 100644 tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.policy delete mode 100644 tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c create mode 100644 tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 60c6a60a5..d0aff45ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1128,6 +1128,14 @@ tde_setup_dbus( dbus-1-tqt ) list( APPEND TDECORE_LIBRARY_DIRS ${DBUS_TQT_LIBRARY_DIRS} ) +##### set POLKIT-1 file locations ################## + +if( NOT DEFINED POLKIT_ACTIONS_DIRECTORY ) + set (POLKIT_ACTIONS_DIRECTORY "/usr/share/polkit-1/actions/" ) + message( STATUS "Using " ${POLKIT_ACTIONS_DIRECTORY} " for Polkit-1 policy action files" ) +endif( NOT DEFINED POLKIT_ACTIONS_DIRECTORY ) + + ##### Add '[KDE4]' to KDE4 menu items ######### if( WITH_KDE4_MENU_SUFFIX ) diff --git a/tdecore/tdehw/hwlibdaemons/dbus/CMakeLists.txt b/tdecore/tdehw/hwlibdaemons/dbus/CMakeLists.txt index 4d1f4618a..d6e75af12 100644 --- a/tdecore/tdehw/hwlibdaemons/dbus/CMakeLists.txt +++ b/tdecore/tdehw/hwlibdaemons/dbus/CMakeLists.txt @@ -9,8 +9,10 @@ # ################################################# + include_directories( ${DBUS_INCLUDE_DIRS} + ${DBUS_TQT_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} @@ -19,8 +21,8 @@ include_directories( ##### tde_dbus_hardwarecontrol ################## tde_add_executable( tde_dbus_hardwarecontrol - SOURCES tde_dbus_hardwarecontrol.c - LINK ${DBUS_LIBRARIES} + SOURCES tde_dbus_hardwarecontrol.cpp + LINK ${DBUS_LIBRARIES} ${DBUS_TQT_LIBRARIES} ${TQT_LIBRARIES} DESTINATION ${BIN_INSTALL_DIR} ) @@ -28,10 +30,11 @@ tde_add_executable( tde_dbus_hardwarecontrol configure_file( org.trinitydesktop.hardwarecontrol.service.cmake org.trinitydesktop.hardwarecontrol.service @ONLY ) -install( FILES - org.trinitydesktop.hardwarecontrol.conf - DESTINATION ${DBUS_SYSTEM_CONF_DIRECTORY} ) +install( FILES org.trinitydesktop.hardwarecontrol.conf + DESTINATION ${DBUS_SYSTEM_CONF_DIRECTORY} ) + +install( FILES ${CMAKE_CURRENT_BINARY_DIR}/org.trinitydesktop.hardwarecontrol.service + DESTINATION ${DBUS_SERVICE_DIRECTORY} ) -install( FILES - ${CMAKE_CURRENT_BINARY_DIR}/org.trinitydesktop.hardwarecontrol.service - DESTINATION ${DBUS_SERVICE_DIRECTORY} ) +install( FILES org.trinitydesktop.hardwarecontrol.policy + DESTINATION ${POLKIT_ACTIONS_DIRECTORY} ) diff --git a/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf b/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf index b897da36b..47fbee050 100644 --- a/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf +++ b/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf @@ -3,14 +3,14 @@ + - - + @@ -36,11 +36,4 @@ - - - - - - - diff --git a/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.policy b/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.policy new file mode 100644 index 000000000..5183b47cb --- /dev/null +++ b/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.policy @@ -0,0 +1,60 @@ + + + + + + The Trinity Desktop Environment Project + http://www.trinitydesktop.org + + + Freeze the system. + Authentication is required to freeze the system. + + no + no + yes + + + + + Put the system in standby mode. + Authentication is required to put the system in standby. + + no + no + yes + + + + + Put the system in suspend mode. + Authentication is required to suspend the system. + + no + no + yes + + + + + Put the system in hybrid suspend mode. + Authentication is required to put the system in hybrid suspend mode. + + no + no + yes + + + + + Hibernate the system. + Authentication is required to hibernate the system. + + no + no + yes + + + + diff --git a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c deleted file mode 100644 index 77200334e..000000000 --- a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c +++ /dev/null @@ -1,856 +0,0 @@ -#define DBUS_API_SUBJECT_TO_CHANGE -#include -#include -#include -#include -#include -#include -#include - -// Input devices -#include - -#define BITS_PER_LONG (sizeof(long) * 8) -#define NUM_BITS(x) ((((x) - 1) / BITS_PER_LONG) + 1) - -void reply_Bool(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 reply_CanSetGivenPath(DBusMessage* msg, DBusConnection* conn, const char* param) { - DBusMessage* reply; - DBusMessageIter args; - const char* member = dbus_message_get_member(msg); - dbus_uint32_t serial = 0; - int writable = false; - - // check if path is writable - int rval = access (param, W_OK); - if (rval == 0) { - writable = true; - } - - // 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, &writable)) { - 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_SetGivenPath(DBusMessage* msg, DBusConnection* conn, const char* param, const char* contents) { - DBusMessage* reply; - DBusMessageIter args; - const char* member = dbus_message_get_member(msg); - dbus_uint32_t serial = 0; - int writable = false; - int written = false; - - // check if path is writable - int rval = access (param, W_OK); - if (rval == 0) { - writable = true; - } - - if (writable) { - FILE *node = fopen(param, "w"); - if (node != NULL) { - if (fputs(contents, node) != EOF) { - written = true; - } - if (fclose(node) == EOF) { - // Error! - } - } - } - - // 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, &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_CanSetCPUGovernor(DBusMessage* msg, DBusConnection* conn) { - DBusMessageIter args; - const char* member = dbus_message_get_member(msg); - dbus_int32_t cpunum; - char path[256]; - - // 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_INT32 != dbus_message_iter_get_arg_type(&args)) { - fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: argument not 32-bit integer\n", member); - } - else { - dbus_message_iter_get_basic(&args, &cpunum); - } - - snprintf(path, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpunum); - reply_CanSetGivenPath(msg, conn, path); -} - -void reply_SetCPUGovernor(DBusMessage* msg, DBusConnection* conn) { - DBusMessageIter args; - const char* member = dbus_message_get_member(msg); - dbus_int32_t cpunum = -1; - char* governor = NULL; - char path[256]; - - // read the arguments - if (!dbus_message_iter_init(msg, &args)) { - fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member); - } - 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); - } - else { - 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); - } - else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { - fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not string\n", member); - } - else { - dbus_message_iter_get_basic(&args, &governor); - } - - snprintf(path, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpunum); - if ((cpunum>-1) && governor) { - reply_SetGivenPath(msg, conn, path, governor); - } - else { - reply_Bool(msg, conn, false); - } -} - -void reply_CanSetBrightness(DBusMessage* msg, DBusConnection* conn) { - DBusMessageIter args; - const char* member = dbus_message_get_member(msg); - char* rawpath; - char* safepath; - - // 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, "/sys/devices") == safepath) && - (strstr(safepath, "/brightness") == (safepath+strlen(safepath)-strlen("/brightness"))) - ) { - reply_CanSetGivenPath(msg, conn, safepath); - } - else { - reply_Bool(msg, conn, false); - } - - free(safepath); -} - -void reply_SetBrightness(DBusMessage* msg, DBusConnection* conn) { - DBusMessageIter args; - const char* member = dbus_message_get_member(msg); - char* rawpath; - char* safepath; - char* brightness; - - // read the arguments - if (!dbus_message_iter_init(msg, &args)) { - fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member); - } - else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { - fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: first argument not string\n", member); - } - else { - 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); - } - else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { - fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not string\n", member); - } - else { - dbus_message_iter_get_basic(&args, &brightness); - } - - safepath = realpath(rawpath, NULL); - - if (safepath && brightness && - (strstr(safepath, "/sys/devices") == safepath) && - (strstr(safepath, "/brightness") == (safepath+strlen(safepath)-strlen("/brightness"))) - ) { - reply_SetGivenPath(msg, conn, safepath, brightness); - } - else { - reply_Bool(msg, conn, false); - } - - free(safepath); -} - -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; -} - -void reply_CanSetHibernationMethod(DBusMessage* msg, DBusConnection* conn) { - // check if path is writable - reply_CanSetGivenPath(msg, conn, "/sys/power/disk"); -} - -void reply_SetHibernationMethod(DBusMessage* msg, DBusConnection* conn) { - DBusMessageIter args; - const char* member = dbus_message_get_member(msg); - char* method = NULL; - - // read the arguments - if (!dbus_message_iter_init(msg, &args)) { - fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments 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, &method); - } - - // set hibernation method - if (method) { - reply_SetGivenPath(msg, conn, "/sys/power/disk", method); - } - else { - reply_Bool(msg, conn, 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 = malloc(size); - - // compose reply - strncpy(data, - "\n", - size); - strncat(data, "\n", size-strlen(data)); - if(strcmp("/", path) == 0) { - strncat(data, " \n", size-strlen(data)); - } - else if(strcmp("/org", path) == 0) { - strncat(data, " \n", size-strlen(data)); - } - else if(strcmp("/org/trinitydesktop", path) == 0) { - strncat(data, " \n", size-strlen(data)); - } - else if(strcmp("/org/trinitydesktop/hardwarecontrol", path) == 0) { - strncat(data, - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n", - size-strlen(data)); - strncat(data, - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n", - size-strlen(data)); - strncat(data, - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n", - size-strlen(data)); - strncat(data, - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n", - size-strlen(data)); - } - strncat(data, "\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); - free((void*)data); -} - -void reply_PropertiesGetAll(DBusMessage* msg, DBusConnection* conn) { - DBusMessage* reply; - DBusMessageIter args, arrayIter; - 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_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 - 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_UnknownMessage(DBusMessage* msg, DBusConnection* conn) { - DBusMessage* reply; - dbus_uint32_t serial = 0; - 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 - 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 - 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 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")) { - reply_CanSetCPUGovernor(msg, conn); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.CPUGovernor", "SetCPUGovernor")) { - reply_SetCPUGovernor(msg, conn); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Brightness", "CanSetBrightness")) { - reply_CanSetBrightness(msg, conn); - } - 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", "CanFreeze")) { - bool result = CanSetPowerState("freeze", NULL, NULL) || CanSetPowerState("mem", NULL, "s2idle"); - reply_Bool(msg, conn, result); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Freeze")) { - bool result = false; - if (CanSetPowerState("freeze", NULL, NULL)) { - result = SetPowerState("freeze", NULL, NULL); - } - else if (CanSetPowerState("mem", NULL, "s2idle")) { - result = SetPowerState("mem", NULL, "s2idle"); - } - reply_Bool(msg, conn, result); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanStandby")) { - bool result = CanSetPowerState("standby", NULL, NULL) || CanSetPowerState("mem", NULL, "shallow"); - reply_Bool(msg, conn, result); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Standby")) { - bool result = false; - if (CanSetPowerState("standby", NULL, NULL)) { - result = SetPowerState("standby", NULL, NULL); - } - else if (CanSetPowerState("mem", NULL, "shallow")) { - result = SetPowerState("mem", NULL, "shallow"); - } - reply_Bool(msg, conn, result); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSuspend")) { - bool result = (CanSetPowerState("mem", NULL, NULL) && access("/sys/power/mem_sleep", R_OK) != 0) || - CanSetPowerState("mem", NULL, "deep"); - reply_Bool(msg, conn, result); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Suspend")) { - bool 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"); - } - reply_Bool(msg, conn, result); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHybridSuspend")) { - bool result = CanSetPowerState("disk", "suspend", NULL); - reply_Bool(msg, conn, result); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "HybridSuspend")) { - bool result = SetPowerState("disk", "suspend", NULL); - reply_Bool(msg, conn, result); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHibernate")) { - bool result = CanSetPowerState("disk", "shutdown", NULL) || CanSetPowerState("disk", "platform", NULL); - reply_Bool(msg, conn, result); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Hibernate")) { - bool result = false; - if (CanSetPowerState("disk", "shutdown", NULL)) { - result = SetPowerState("disk", "shutdown", NULL); - } - else if (CanSetPowerState("disk", "platform", NULL)) { - result = SetPowerState("disk", "platform", NULL); - } - reply_Bool(msg, conn, result); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSetHibernationMethod")) { - reply_CanSetHibernationMethod(msg, conn); - } - else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "SetHibernationMethod")) { - reply_SetHibernationMethod(msg, conn); - } - 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.Properties", "GetAll")) { - reply_PropertiesGetAll(msg, conn); - } - 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; -} diff --git a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp new file mode 100644 index 000000000..8ba765c34 --- /dev/null +++ b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp @@ -0,0 +1,982 @@ +#define DBUS_API_SUBJECT_TO_CHANGE +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +// Input devices +#include + +#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 subjectMap = TQT_DBusDataMap(); + subjectMap.insert(TQString("name"), TQT_DBusData::fromVariant(sysname)); + TQValueList subjectStruct; + subjectStruct << TQT_DBusData::fromString("system-bus-name"); + subjectStruct << TQT_DBusData::fromStringKeyMap(subjectMap); + + TQMap detailsMap; + detailsMap.insert(TQString(""), TQString("")); + TQT_DBusDataMap dbusDetailsMap(detailsMap); + + TQValueList 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 reply_Bool(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 reply_CanSetGivenPath(DBusMessage* msg, DBusConnection* conn, const char* param) { + DBusMessage* reply; + DBusMessageIter args; + const char* member = dbus_message_get_member(msg); + dbus_uint32_t serial = 0; + int writable = false; + + // check if path is writable + int rval = access (param, W_OK); + if (rval == 0) { + writable = true; + } + + // 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, &writable)) { + 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_SetGivenPath(DBusMessage* msg, DBusConnection* conn, const char* param, const char* contents) { + DBusMessage* reply; + DBusMessageIter args; + const char* member = dbus_message_get_member(msg); + dbus_uint32_t serial = 0; + int writable = false; + int written = false; + + // check if path is writable + int rval = access (param, W_OK); + if (rval == 0) { + writable = true; + } + + if (writable) { + FILE *node = fopen(param, "w"); + if (node != NULL) { + if (fputs(contents, node) != EOF) { + written = true; + } + if (fclose(node) == EOF) { + // Error! + } + } + } + + // 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, &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_CanSetCPUGovernor(DBusMessage* msg, DBusConnection* conn) { + DBusMessageIter args; + const char* member = dbus_message_get_member(msg); + dbus_int32_t cpunum; + char path[256]; + + // 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_INT32 != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: argument not 32-bit integer\n", member); + } + else { + dbus_message_iter_get_basic(&args, &cpunum); + } + + snprintf(path, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpunum); + reply_CanSetGivenPath(msg, conn, path); +} + +void reply_SetCPUGovernor(DBusMessage* msg, DBusConnection* conn) { + DBusMessageIter args; + const char* member = dbus_message_get_member(msg); + dbus_int32_t cpunum = -1; + char* governor = NULL; + char path[256]; + + // read the arguments + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member); + } + 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); + } + else { + 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); + } + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not string\n", member); + } + else { + dbus_message_iter_get_basic(&args, &governor); + } + + snprintf(path, 256, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpunum); + if ((cpunum>-1) && governor) { + reply_SetGivenPath(msg, conn, path, governor); + } + else { + reply_Bool(msg, conn, false); + } +} + +void reply_CanSetBrightness(DBusMessage* msg, DBusConnection* conn) { + DBusMessageIter args; + const char* member = dbus_message_get_member(msg); + char* rawpath; + char* safepath; + + // 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, "/sys/devices") == safepath) && + (strstr(safepath, "/brightness") == (safepath+strlen(safepath)-strlen("/brightness"))) + ) { + reply_CanSetGivenPath(msg, conn, safepath); + } + else { + reply_Bool(msg, conn, false); + } + + free(safepath); +} + +void reply_SetBrightness(DBusMessage* msg, DBusConnection* conn) { + DBusMessageIter args; + const char* member = dbus_message_get_member(msg); + char* rawpath; + char* safepath; + char* brightness; + + // read the arguments + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments supplied\n", member); + } + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: first argument not string\n", member); + } + else { + 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); + } + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: second argument not string\n", member); + } + else { + dbus_message_iter_get_basic(&args, &brightness); + } + + safepath = realpath(rawpath, NULL); + + if (safepath && brightness && + (strstr(safepath, "/sys/devices") == safepath) && + (strstr(safepath, "/brightness") == (safepath+strlen(safepath)-strlen("/brightness"))) + ) { + reply_SetGivenPath(msg, conn, safepath, brightness); + } + else { + reply_Bool(msg, conn, false); + } + + free(safepath); +} + +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; +} + +void reply_CanSetHibernationMethod(DBusMessage* msg, DBusConnection* conn) { + // check if path is writable + reply_CanSetGivenPath(msg, conn, "/sys/power/disk"); +} + +void reply_SetHibernationMethod(DBusMessage* msg, DBusConnection* conn) { + DBusMessageIter args; + const char* member = dbus_message_get_member(msg); + char* method = NULL; + + // read the arguments + if (!dbus_message_iter_init(msg, &args)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: no arguments 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, &method); + } + + // set hibernation method + if (method) { + reply_SetGivenPath(msg, conn, "/sys/power/disk", method); + } + else { + reply_Bool(msg, conn, 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, + "\n", + size); + strncat(data, "\n", size-strlen(data)); + if(strcmp("/", path) == 0) { + strncat(data, " \n", size-strlen(data)); + } + else if(strcmp("/org", path) == 0) { + strncat(data, " \n", size-strlen(data)); + } + else if(strcmp("/org/trinitydesktop", path) == 0) { + strncat(data, " \n", size-strlen(data)); + } + else if(strcmp("/org/trinitydesktop/hardwarecontrol", path) == 0) { + strncat(data, + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n", + size-strlen(data)); + strncat(data, + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n", + size-strlen(data)); + strncat(data, + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n", + size-strlen(data)); + strncat(data, + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n", + size-strlen(data)); + } + strncat(data, "\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_PropertiesGetAll(DBusMessage* msg, DBusConnection* conn) { + DBusMessage* reply; + DBusMessageIter args, arrayIter; + 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_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 + 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_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")) { + reply_CanSetCPUGovernor(msg, conn); + } + else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.CPUGovernor", "SetCPUGovernor")) { + reply_SetCPUGovernor(msg, conn); + } + else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Brightness", "CanSetBrightness")) { + reply_CanSetBrightness(msg, conn); + } + 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", "CanFreeze")) { + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.freeze"); + if (!result) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = CanSetPowerState("freeze", NULL, NULL) || CanSetPowerState("mem", NULL, "s2idle"); + reply_Bool(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"); + } + reply_Bool(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) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = CanSetPowerState("standby", NULL, NULL) || CanSetPowerState("mem", NULL, "shallow"); + reply_Bool(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"); + } + reply_Bool(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) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = (CanSetPowerState("mem", NULL, NULL) && access("/sys/power/mem_sleep", R_OK) != 0) || + CanSetPowerState("mem", NULL, "deep"); + reply_Bool(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"); + } + reply_Bool(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) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = CanSetPowerState("disk", "suspend", NULL); + reply_Bool(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 = SetPowerState("disk", "suspend", NULL); + reply_Bool(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) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = CanSetPowerState("disk", "shutdown", NULL) || CanSetPowerState("disk", "platform", NULL); + reply_Bool(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); + } + reply_Bool(msg, conn, result); + } + } + else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSetHibernationMethod")) { + reply_CanSetHibernationMethod(msg, conn); + } + else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "SetHibernationMethod")) { + reply_SetHibernationMethod(msg, conn); + } + 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.Properties", "GetAll")) { + reply_PropertiesGetAll(msg, conn); + } + 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; +} -- cgit v1.2.1