/* * * Copyright (C) 2009-2011 Ali * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H #include #endif #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_SYS_WAIT_H #include #endif #ifdef HAVE_SYS_RESOURCE_H #include #endif #ifdef HAVE_SYS_SYSCTL_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #include #include "xfpm-common.h" #include "xfpm-debug.h" #include "xfpm-suspend.h" #ifdef BACKEND_TYPE_FREEBSD static gchar * get_string_sysctl (GError **err, const gchar *format, ...) { va_list args; gchar *name; size_t value_len; gchar *str = NULL; g_return_val_if_fail(format != NULL, FALSE); va_start (args, format); name = g_strdup_vprintf (format, args); va_end (args); if (sysctlbyname (name, NULL, &value_len, NULL, 0) == 0) { str = g_new (char, value_len + 1); if (sysctlbyname (name, str, &value_len, NULL, 0) == 0) str[value_len] = 0; else { g_free (str); str = NULL; } } if (!str) g_set_error (err, 0, 0, "%s", g_strerror(errno)); g_free(name); return str; } static gboolean freebsd_supports_sleep_state (const gchar *state) { gboolean ret = FALSE; gchar *sleep_states; XFPM_DEBUG("entering"); sleep_states = get_string_sysctl (NULL, "hw.acpi.supported_sleep_state"); if (sleep_states != NULL) { if (strstr (sleep_states, state) != NULL) ret = TRUE; } g_free (sleep_states); return ret; } #endif #ifdef BACKEND_TYPE_LINUX static gboolean linux_supports_sleep_state (const gchar *state) { gboolean ret = FALSE; gchar *command; GError *error = NULL; gint exit_status; XFPM_DEBUG("entering"); /* run script from pm-utils */ command = g_strdup_printf ("/usr/bin/pm-is-supported --%s", state); g_debug ("executing command: %s", command); ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, &error); if (!ret) { if (error) { g_warning ("failed to run script: %s", error->message); g_error_free (error); } goto out; } ret = (WIFEXITED(exit_status) && (WEXITSTATUS(exit_status) == EXIT_SUCCESS)); out: g_free (command); return ret; } #endif gboolean xfpm_suspend_can_suspend (void) { XFPM_DEBUG("entering"); #ifdef BACKEND_TYPE_FREEBSD return freebsd_supports_sleep_state ("S3"); #endif #ifdef BACKEND_TYPE_LINUX return linux_supports_sleep_state ("suspend"); #endif #ifdef BACKEND_TYPE_OPENBSD return TRUE; #endif return FALSE; } gboolean xfpm_suspend_can_hibernate (void) { XFPM_DEBUG("entering"); #ifdef BACKEND_TYPE_FREEBSD return freebsd_supports_sleep_state ("S4"); #endif #ifdef BACKEND_TYPE_LINUX return linux_supports_sleep_state ("hibernate"); #endif #ifdef BACKEND_TYPE_OPENBSD return TRUE; #endif return FALSE; } gboolean xfpm_suspend_try_action (XfpmActionType type) { const gchar *action; gboolean ret; GError *error = NULL; gint exit_status = 0; gchar *command = NULL; TRACE("entering"); if (type == XFPM_SUSPEND) action = "suspend"; else if (type == XFPM_HIBERNATE) action = "hibernate"; else return FALSE; command = g_strdup_printf ("pkexec " SBINDIR "/xfce4-pm-helper --%s", action); ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, &error); if ( !ret ) { if (error) { g_warning ("xfce4-pm-helper: failed to suspend/hibernate: %s", error->message); g_error_free (error); } } else { XFPM_DEBUG ("executed %s; retval: %i", command, exit_status); ret = (exit_status == 0); } g_free (command); return ret; }