diff options
author | Olivier Duchateau <duchateau.olivier@gmail.com> | 2014-12-31 11:52:52 +0100 |
---|---|---|
committer | Eric Koegel <eric.koegel@gmail.com> | 2015-02-07 18:53:45 +0300 |
commit | f9980385de8ba5bb33391cf3bc8b283db0fb1de2 (patch) | |
tree | 8c6fad5fd5cf79ce34c374395f68a3c31f945175 /src | |
parent | 10076da7caa49320b3e907d319a9f27ee6702969 (diff) | |
download | ixfce4-power-manager-f9980385de8ba5bb33391cf3bc8b283db0fb1de2.tar.gz |
Use sysctl(3) to get or set brightness level on FreeBSD and DragonFly systems
Signed-off-by: Eric Koegel <eric.koegel@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/xfpm-backlight-helper.c | 323 |
1 files changed, 322 insertions, 1 deletions
diff --git a/src/xfpm-backlight-helper.c b/src/xfpm-backlight-helper.c index 5f23d524..4584edc2 100644 --- a/src/xfpm-backlight-helper.c +++ b/src/xfpm-backlight-helper.c @@ -19,7 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #ifdef HAVE_UNISTD_H #include <unistd.h> @@ -36,6 +38,10 @@ #include <string.h> #endif #include <stdio.h> +#include <stdlib.h> +#if defined(BACKEND_TYPE_FREEBSD) +#include <sys/sysctl.h> +#endif #define EXIT_CODE_SUCCESS 0 #define EXIT_CODE_FAILED 1 @@ -43,10 +49,325 @@ #define EXIT_CODE_INVALID_USER 4 #define EXIT_CODE_NO_BRIGHTNESS_SWITCH 5 +#if !defined(BACKEND_TYPE_FREEBSD) #define BACKLIGHT_SYSFS_LOCATION "/sys/class/backlight" #define BRIGHTNESS_SWITCH_LOCATION "/sys/module/video/parameters/brightness_switch_enabled" +#endif + + +#if defined(BACKEND_TYPE_FREEBSD) +gboolean +acpi_video_is_enabled (gchar *device) +{ + return (backlight_helper_get_switch (device) == 1) ? TRUE : FALSE; +} + +gint +backlight_helper_get_switch (gchar *device) +{ + size_t size; + gint buf, res = -1; + gchar *name; + + name = g_strdup_printf ("hw.acpi.video.%s.active", device); + size = sizeof (buf); + + if (sysctlbyname (name, &buf, &size, NULL, 0) == 0) + res = buf; + + g_free (name); + return res; +} + +gint +backlight_helper_get_brightness (gchar *device) +{ + size_t size; + gint buf, res = -1; + gchar *name; + + name = g_strdup_printf ("hw.acpi.video.%s.brightness", device); + size = sizeof (buf); + + if (sysctlbyname (name, &buf, &size, NULL, 0) == 0) + res = buf; + + g_free (name); + return res; +} + +gint +int_cmp (gconstpointer a, gconstpointer b) +{ + return (gint) a < (gint) b ? -1 : ((gint) a == (gint) b ? 0 : 1); +} + +GList * +backlight_helper_get_levels (gchar *device) +{ + size_t size; + gint *levels; + gint nlevels, i; + GList *list = NULL, *item; + gchar *name; + + name = g_strdup_printf ("hw.acpi.video.%s.levels", device); + + /* allocate memory */ + sysctlbyname (name, NULL, &size, NULL, 0); + levels = (int *) malloc (size); + + if (sysctlbyname (name, levels, &size, NULL, 0) == 0) { + nlevels = size / sizeof (gint); + + for (i = 0; i < nlevels; i++) { + /* no duplicate item */ + item = g_list_find (list, GINT_TO_POINTER (levels[i])); + if (item == NULL) + list = g_list_append (list, + GINT_TO_POINTER (levels[i])); + } + } + + g_free (levels); + g_free (name); + + if (list != NULL) + list = g_list_sort (list, int_cmp); + + return list; +} + +gboolean +backlight_helper_set_switch (gchar *device, gint value) +{ + size_t size; + gint buf, old_buf; + gchar *name; + gint res = -1; + gboolean result = FALSE; + + name = g_strdup_printf ("hw.acpi.video.%s.active", device); + + res = backlight_helper_get_switch (device); + if (res != -1) { + old_buf = res; + size = sizeof (buf); + + /* we change value and check if it's really different */ + if (sysctlbyname (name, &buf, &size, &value, sizeof (value)) == 0) { + res = backlight_helper_get_switch (device); + if (res != -1 && res != old_buf) + result = TRUE; + } + } + g_free (name); + + return result; +} + +gboolean +backlight_helper_set_brightness (gchar *device, gint value) +{ + size_t size; + gint buf, old_buf; + gchar *name; + gint res = -1; + gboolean result = FALSE; + + name = g_strdup_printf ("hw.acpi.video.%s.brightness", device); + + res = backlight_helper_get_brightness (device); + if (res != -1) { + old_buf = res; + size = sizeof (buf); + + /* we change value, and check if it's really different */ + if (sysctlbyname (name, &buf, &size, &value, sizeof (value)) == 0) { + res = backlight_helper_get_brightness (device); + if (res != -1 && res != old_buf) + result = TRUE; + } + } + + g_free (name); + + return result; +} + +/* + * Find device which supports backlight brightness + */ +static gchar * +backlight_helper_get_device (void) +{ + /* 'tv' device is also available */ + gchar *types[] = { "lcd", "crt", "out", "ext", NULL }; + gchar *device = NULL; + gint i; + + device = (gchar *) g_malloc (sizeof (gchar)); + + for (i = 0; types[i] != NULL; i++) { + g_snprintf (device, 5, "%s0", types[i]); + + /* stop, when first device is found */ + if (acpi_video_is_enabled (device)) + break; + } + + return device; +} + +/* + * Backlight helper main function + */ +gint +main (gint argc, gchar *argv[]) +{ + GOptionContext *context; + gint uid; + gint euid; + guint retval = 0; + const gchar *pkexec_uid_str; + gint ret = -1; + gint set_brightness = -1; + gboolean get_brightness = FALSE; + gboolean get_max_brightness = FALSE; + gint set_brightness_switch = -1; + gboolean get_brightness_switch = FALSE; + gchar *device = NULL; + GList *list = NULL; + + const GOptionEntry options[] = { + { "set-brightness", '\0', 0, G_OPTION_ARG_INT, &set_brightness, + /* command line argument */ + "Set the current brightness", NULL }, + { "get-brightness", '\0', 0, G_OPTION_ARG_NONE, &get_brightness, + /* command line argument */ + "Get the current brightness", NULL }, + { "get-max-brightness", '\0', 0, G_OPTION_ARG_NONE, &get_max_brightness, + /* command line argument */ + "Get the number of brightness levels supported", NULL }, + { "set-brightness-switch", '\0', 0, G_OPTION_ARG_INT, &set_brightness_switch, + /* command line argument */ + "Enable or disable ACPI video brightness switch handling", NULL }, + { "get-brightness-switch", '\0', 0, G_OPTION_ARG_NONE, &get_brightness_switch, + /* command line argument */ + "Get the current setting of the ACPI video brightness switch handling", NULL }, + { NULL } + }; + + context = g_option_context_new (NULL); + g_option_context_set_summary (context, "XFCE Power Manager Backlight Helper"); + g_option_context_add_main_entries (context, options, NULL); + g_option_context_parse (context, &argc, &argv, NULL); + g_option_context_free (context); + /* no input */ + if (set_brightness == -1 && !get_brightness && !get_max_brightness && + set_brightness_switch == -1 && !get_brightness_switch) { + g_print ("No valid option was specifiedi\n"); + retval = EXIT_CODE_ARGUMENTS_INVALID; + goto out; + } + + /* find backlight device */ + device = backlight_helper_get_device (); + + if (device != NULL) { + /* get the current setting of the ACPI video brightness switch handling */ + if (get_brightness_switch) { + ret = backlight_helper_get_switch (device); + /* just print result to stdout */ + g_print ("%d", ret); + if (ret == -1) + retval = EXIT_CODE_FAILED; + else + retval = EXIT_CODE_SUCCESS; + goto out; + } + /* get current brightness level */ + if (get_brightness) { + ret = backlight_helper_get_brightness (device); + /* just print result to stdout */ + g_print ("%d", ret); + if (ret == -1) + retval = EXIT_CODE_FAILED; + else + retval = EXIT_CODE_SUCCESS; + goto out; + } + + /* get maximum brightness level */ + if (get_max_brightness) { + list = backlight_helper_get_levels (device); + if (list != NULL) { + /* just print result to stdout */ + g_print ("%d", (gint) g_list_last (list)->data); + g_list_free (list); + retval = EXIT_CODE_SUCCESS; + goto out; + } + else { + g_print ("Could not get the maximum value of the backlight\n"); + retval = EXIT_CODE_FAILED; + goto out; + } + } + + /* get calling process */ + uid = getuid (); + euid = geteuid (); + if (uid != 0 || euid != 0) { + g_print ("This program can only be used by the root user\n"); + retval = EXIT_CODE_ARGUMENTS_INVALID; + goto out; + } + + /* check we're not being spoofed */ + pkexec_uid_str = g_getenv ("PKEXEC_UID"); + if (pkexec_uid_str == NULL) { + g_print ("This program must only be run through pkexec\n"); + retval = EXIT_CODE_INVALID_USER; + goto out; + } + + /* set the brightness level */ + if (set_brightness != -1) { + if (backlight_helper_set_brightness (device, set_brightness)) { + retval = EXIT_CODE_SUCCESS; + goto out; + } + else { + g_print ("Could not set the value of the backlight\n"); + retval = EXIT_CODE_FAILED; + goto out; + } + } + + /* enable or disable ACPI video brightness switch handling */ + if (set_brightness_switch != -1) { + if (backlight_helper_set_switch (device, set_brightness_switch)) { + retval = EXIT_CODE_SUCCESS; + goto out; + } + else { + g_print ("Could not set the value of the brightness switch\n"); + retval = EXIT_CODE_FAILED; + goto out; + } + } + } + else { + retval = ret; + goto out; + } +out: + return retval; +} +#else /* * Find best backlight using an ordered interface list */ @@ -323,4 +644,4 @@ out: g_free (contents); return retval; } - +#endif |