summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOlivier Duchateau <duchateau.olivier@gmail.com>2014-12-31 11:52:52 +0100
committerEric Koegel <eric.koegel@gmail.com>2015-02-07 18:53:45 +0300
commitf9980385de8ba5bb33391cf3bc8b283db0fb1de2 (patch)
tree8c6fad5fd5cf79ce34c374395f68a3c31f945175 /src
parent10076da7caa49320b3e907d319a9f27ee6702969 (diff)
downloadixfce4-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.c323
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