Skip to content
Snippets Groups Projects
Commit f9980385 authored by OlivierDuchateau's avatar OlivierDuchateau Committed by Eric Koegel
Browse files

Use sysctl(3) to get or set brightness level on FreeBSD and DragonFly systems


Signed-off-by: default avatarEric Koegel <eric.koegel@gmail.com>
parent 10076da7
No related branches found
No related tags found
No related merge requests found
...@@ -333,12 +333,16 @@ xfpm_brightness_helper_get_value (const gchar *argument) ...@@ -333,12 +333,16 @@ xfpm_brightness_helper_get_value (const gchar *argument)
if ( exit_status != 0 ) if ( exit_status != 0 )
goto out; goto out;
#if !defined(BACKEND_TYPE_FREEBSD)
if ( stdout_data[0] == 'N' ) if ( stdout_data[0] == 'N' )
value = 0; value = 0;
else if ( stdout_data[0] == 'Y' ) else if ( stdout_data[0] == 'Y' )
value = 1; value = 1;
else else
value = atoi (stdout_data); value = atoi (stdout_data);
#else
value = atoi (stdout_data);
#endif
out: out:
g_free (command); g_free (command);
...@@ -606,7 +610,11 @@ xfpm_brightness_setup (XfpmBrightness *brightness) ...@@ -606,7 +610,11 @@ xfpm_brightness_setup (XfpmBrightness *brightness)
else else
{ {
if ( xfpm_brightness_setup_helper (brightness) ) { if ( xfpm_brightness_setup_helper (brightness) ) {
g_debug ("xrandr not available, brightness controlled by sysfs helper; min_level=%d max_level=%d", #if defined(BACKEND_TYPE_FREEBSD)
g_debug ("xrandr not available, brightness controlled by sysctl helper; min_level=%d max_level=%d",
#else
g_debug ("xrandr not available, brightness controlled by sysfs helper; min_level=%d max_level=%d",
#endif
brightness->priv->min_level, brightness->priv->min_level,
brightness->priv->max_level); brightness->priv->max_level);
return TRUE; return TRUE;
......
...@@ -19,7 +19,9 @@ ...@@ -19,7 +19,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
...@@ -36,6 +38,10 @@ ...@@ -36,6 +38,10 @@
#include <string.h> #include <string.h>
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#if defined(BACKEND_TYPE_FREEBSD)
#include <sys/sysctl.h>
#endif
#define EXIT_CODE_SUCCESS 0 #define EXIT_CODE_SUCCESS 0
#define EXIT_CODE_FAILED 1 #define EXIT_CODE_FAILED 1
...@@ -43,10 +49,325 @@ ...@@ -43,10 +49,325 @@
#define EXIT_CODE_INVALID_USER 4 #define EXIT_CODE_INVALID_USER 4
#define EXIT_CODE_NO_BRIGHTNESS_SWITCH 5 #define EXIT_CODE_NO_BRIGHTNESS_SWITCH 5
#if !defined(BACKEND_TYPE_FREEBSD)
#define BACKLIGHT_SYSFS_LOCATION "/sys/class/backlight" #define BACKLIGHT_SYSFS_LOCATION "/sys/class/backlight"
#define BRIGHTNESS_SWITCH_LOCATION "/sys/module/video/parameters/brightness_switch_enabled" #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 * Find best backlight using an ordered interface list
*/ */
...@@ -323,4 +644,4 @@ out: ...@@ -323,4 +644,4 @@ out:
g_free (contents); g_free (contents);
return retval; return retval;
} }
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment