forked from enlightenment/enlightenment
backlight: Use basic ACPI sysctl knob on FreeBSD (kernel)
Summary: Unconditionally build the suid-helper _backlight program; conditionalize behavior on Eeze, FreeBSD (doing nothing on neither). Add logic to set the FreeBSD sysctl in a similar manner to udev devices on Linux. Add _bl_sys_find/_get helpers for FreeBSD that check for and consult the video ACPI sysctl. Test Plan: Seems to work okay on my laptop (with EINA_CPU_FAKE=1 to workaround a threadq race that I believe is unrelated -- T2287). Reviewers: zmike, q66 Reviewed By: q66 Subscribers: cedric, seoz Differential Revision: https://phab.enlightenment.org/D2337
This commit is contained in:
parent
de943ddfa7
commit
4fc5495f4e
|
@ -27,6 +27,7 @@ src/bin/enlightenment_open
|
|||
|
||||
internal_bindir = $(libdir)/enlightenment/utils
|
||||
internal_bin_PROGRAMS = \
|
||||
src/bin/enlightenment_backlight \
|
||||
src/bin/enlightenment_fm_op \
|
||||
src/bin/enlightenment_sys \
|
||||
src/bin/enlightenment_thumb \
|
||||
|
@ -36,10 +37,6 @@ if ! HAVE_WAYLAND_ONLY
|
|||
internal_bin_PROGRAMS += src/bin/enlightenment_alert
|
||||
endif
|
||||
|
||||
if HAVE_EEZE
|
||||
internal_bin_PROGRAMS += src/bin/enlightenment_backlight
|
||||
endif
|
||||
|
||||
ENLIGHTENMENTHEADERS = \
|
||||
src/bin/e_about.h \
|
||||
src/bin/e_acpi.h \
|
||||
|
@ -420,13 +417,11 @@ src/bin/e_sys_l2ping.c
|
|||
src_bin_enlightenment_sys_LDADD = @SUID_LDFLAGS@ @E_SYS_LIBS@ @BLUEZ_LIBS@
|
||||
src_bin_enlightenment_sys_CPPFLAGS = @SUID_CFLAGS@ @E_SYS_CFLAGS@ @BLUEZ_CFLAGS@ -DPACKAGE_SYSCONF_DIR=\"@PACKAGE_SYSCONF_DIR@\"
|
||||
|
||||
if HAVE_EEZE
|
||||
src_bin_enlightenment_backlight_SOURCES = \
|
||||
src/bin/e_backlight_main.c
|
||||
|
||||
src_bin_enlightenment_backlight_CPPFLAGS = @SUID_CFLAGS@ @EEZE_CFLAGS@
|
||||
src_bin_enlightenment_backlight_LDADD = @SUID_LDFLAGS@ @EEZE_LIBS@
|
||||
endif
|
||||
|
||||
src_bin_enlightenment_alert_SOURCES = \
|
||||
src/bin/e_alert_main.c
|
||||
|
@ -455,14 +450,9 @@ include src/bin/e_fm/Makefile.mk
|
|||
# and before internal_bin_PROGRAMS are installed. install-data-hook is
|
||||
# run after both
|
||||
setuid_root_mode = a=rx,u+xs
|
||||
if HAVE_EEZE
|
||||
enlightenment-sys-install-data-hook:
|
||||
@chmod $(setuid_root_mode) $(DESTDIR)$(libdir)/enlightenment/utils/enlightenment_sys$(EXEEXT) || true
|
||||
@chmod $(setuid_root_mode) $(DESTDIR)$(libdir)/enlightenment/utils/enlightenment_backlight$(EXEEXT) || true
|
||||
else
|
||||
enlightenment-sys-install-data-hook:
|
||||
@chmod $(setuid_root_mode) $(DESTDIR)$(libdir)/enlightenment/utils/enlightenment_sys$(EXEEXT) || true
|
||||
endif
|
||||
installed_headersdir = $(prefix)/include/enlightenment
|
||||
installed_headers_DATA = $(ENLIGHTENMENTHEADERS) src/bin/e_fm_shared_types.h
|
||||
INSTALL_DATA_HOOKS += enlightenment-sys-install-data-hook
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
#ifdef HAVE_EEZE
|
||||
# include <Eeze.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#ifdef __FreeBSD_kernel__
|
||||
# include <sys/sysctl.h>
|
||||
# include <errno.h>
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
// FIXME: backlight should be tied per zone but this implementation is just
|
||||
// a signleton right now as thats 99% of use cases. but api supports
|
||||
|
@ -25,7 +31,7 @@ static Eina_Bool bl_avail = EINA_TRUE;
|
|||
#ifndef HAVE_WAYLAND_ONLY
|
||||
static Eina_Bool xbl_avail = EINA_FALSE;
|
||||
#endif
|
||||
#ifdef HAVE_EEZE
|
||||
#if defined(HAVE_EEZE) || defined(__FreeBSD_kernel__)
|
||||
static double bl_delayval = 1.0;
|
||||
static const char *bl_sysval = NULL;
|
||||
static Ecore_Event_Handler *bl_sys_exit_handler = NULL;
|
||||
|
@ -38,6 +44,11 @@ static void _bl_sys_level_get(void);
|
|||
static Eina_Bool _e_bl_cb_exit(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
||||
static void _bl_sys_level_set(double val);
|
||||
#endif
|
||||
#ifdef __FreeBSD_kernel__
|
||||
static const char *bl_acpi_sysctl = "hw.acpi.video.lcd0.brightness";
|
||||
static int bl_mib[CTL_MAXNAME];
|
||||
static int bl_mib_len = -1;
|
||||
#endif
|
||||
|
||||
EAPI int E_EVENT_BACKLIGHT_CHANGE = -1;
|
||||
|
||||
|
@ -240,7 +251,7 @@ _e_backlight_update(void)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_EEZE
|
||||
#if defined(HAVE_EEZE) || defined(__FreeBSD_kernel__)
|
||||
_bl_sys_find();
|
||||
if (bl_sysval)
|
||||
{
|
||||
|
@ -299,7 +310,7 @@ _e_backlight_set(double val)
|
|||
free(out);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_EEZE
|
||||
#if defined(HAVE_EEZE) || defined(__FreeBSD_kernel__)
|
||||
else if (sysmode == MODE_SYS)
|
||||
{
|
||||
if (bl_sysval)
|
||||
|
@ -445,7 +456,9 @@ _bl_sys_level_get(void)
|
|||
e_bl_val = (double)val / (double)maxval;
|
||||
// fprintf(stderr, "GET: %i/%i (%1.3f)\n", val, maxval, e_bl_val);
|
||||
}
|
||||
#endif // HAVE_EEZE
|
||||
|
||||
#if defined(HAVE_EEZE) || defined(__FreeBSD_kernel__)
|
||||
static Eina_Bool
|
||||
_e_bl_cb_ext_delay(void *data EINA_UNUSED)
|
||||
{
|
||||
|
@ -494,5 +507,64 @@ _bl_sys_level_set(double val)
|
|||
e_prefix_lib_get(), (int)(val * 1000.0), bl_sysval);
|
||||
bl_sys_set_exe = ecore_exe_run(buf, NULL);
|
||||
}
|
||||
#endif // HAVE_EEZE || __FreeBSD_kernel__
|
||||
|
||||
#endif
|
||||
#ifdef __FreeBSD_kernel__
|
||||
static void
|
||||
_bl_sys_find(void)
|
||||
{
|
||||
int rc;
|
||||
size_t mlen;
|
||||
|
||||
if (!bl_avail) return;
|
||||
if (bl_mib_len >= 0) return;
|
||||
|
||||
mlen = sizeof(bl_mib) / sizeof(bl_mib[0]);
|
||||
rc = sysctlnametomib(bl_acpi_sysctl, bl_mib, &mlen);
|
||||
if (rc < 0)
|
||||
{
|
||||
if (errno == ENOENT) ERR("ACPI brightness sysctl '%s' not found, consider 'kldload acpi_video'", bl_acpi_sysctl);
|
||||
else ERR("sysctlnametomib(%s): %s(%d)", bl_acpi_sysctl, strerror(errno), errno);
|
||||
|
||||
bl_avail = EINA_FALSE;
|
||||
return;
|
||||
}
|
||||
bl_mib_len = (int)mlen;
|
||||
sysmode = MODE_SYS;
|
||||
eina_stringshare_replace(&bl_sysval, bl_acpi_sysctl);
|
||||
}
|
||||
|
||||
static void
|
||||
_bl_sys_level_get(void)
|
||||
{
|
||||
int rc, brightness;
|
||||
size_t oldlen;
|
||||
|
||||
if (!bl_avail) return;
|
||||
if (bl_mib_len < 0) return;
|
||||
|
||||
oldlen = sizeof(brightness);
|
||||
rc = sysctl(bl_mib, bl_mib_len, &brightness, &oldlen, NULL, 0);
|
||||
if (rc < 0)
|
||||
{
|
||||
ERR("Could not retrieve ACPI brightness: %s(%d)", strerror(errno), errno);
|
||||
bl_avail = EINA_FALSE;
|
||||
return;
|
||||
}
|
||||
if (oldlen != sizeof(brightness))
|
||||
{
|
||||
// This really should not happen.
|
||||
ERR("!!! Brightness sysctl changed size !!!");
|
||||
bl_avail = EINA_FALSE;
|
||||
return;
|
||||
}
|
||||
if (brightness < 0 || brightness > 100)
|
||||
{
|
||||
// This really should not happen either.
|
||||
ERR("!!! Brightness sysctl out of range !!!");
|
||||
bl_avail = EINA_FALSE;
|
||||
return;
|
||||
}
|
||||
e_bl_val = (double)brightness / 100.;
|
||||
}
|
||||
#endif // __FreeBSD_kernel__
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(HAVE_EEZE)
|
||||
#include <Eeze.h>
|
||||
|
||||
/* local subsystem functions */
|
||||
|
@ -33,48 +35,15 @@ _bl_write_file(const char *file, int val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* externally accessible functions */
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
static int
|
||||
_bl_set(const char *dev, int level)
|
||||
{
|
||||
int i, level, devok = 0;
|
||||
const char *f, *dev = NULL, *str;
|
||||
const char *f, *str;
|
||||
int maxlevel = 0, curlevel = -1;
|
||||
Eina_List *devs, *l;
|
||||
Eina_Bool devok = EINA_FALSE;
|
||||
char buf[4096] = "";
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if ((!strcmp(argv[i], "-h")) ||
|
||||
(!strcmp(argv[i], "-help")) ||
|
||||
(!strcmp(argv[i], "--help")))
|
||||
{
|
||||
printf("This is an internal tool for Enlightenment.\n"
|
||||
"do not use it.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
if (argc == 3)
|
||||
{
|
||||
level = atoi(argv[1]);
|
||||
dev = argv[2];
|
||||
}
|
||||
else
|
||||
exit(1);
|
||||
|
||||
if (!dev) return -1;
|
||||
|
||||
if (setuid(0) != 0)
|
||||
{
|
||||
printf("ERROR: UNABLE TO ASSUME ROOT PRIVILEGES\n");
|
||||
exit(5);
|
||||
}
|
||||
if (setgid(0) != 0)
|
||||
{
|
||||
printf("ERROR: UNABLE TO ASSUME ROOT GROUP PRIVILEGES\n");
|
||||
exit(7);
|
||||
}
|
||||
|
||||
eeze_init();
|
||||
devs = eeze_udev_find_by_filter("backlight", NULL, NULL);
|
||||
if (!devs)
|
||||
|
@ -89,7 +58,7 @@ main(int argc, char **argv)
|
|||
if (!strcmp(f, dev))
|
||||
{
|
||||
dev = f;
|
||||
devok = 1;
|
||||
devok = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +92,85 @@ main(int argc, char **argv)
|
|||
|
||||
EINA_LIST_FREE(devs, f)
|
||||
eina_stringshare_del(f);
|
||||
}
|
||||
#elif defined(__FreeBSD_kernel__) // !HAVE_EEZE
|
||||
#include <sys/sysctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
static const char *bl_acpi_sysctl = "hw.acpi.video.lcd0.brightness";
|
||||
|
||||
static int
|
||||
_bl_set(const char *dev, int level)
|
||||
{
|
||||
int rc;
|
||||
|
||||
level = ((100 * level) + 500) / 1000;
|
||||
if (level > 100) level = 100;
|
||||
else if (level < 0) level = 0;
|
||||
|
||||
// Be slightly careful if making this more permissive. We don't want to
|
||||
// allow non-root users to set arbitrary integer sysctls between 0-100.
|
||||
if (strcmp(bl_acpi_sysctl, dev) != 0)
|
||||
{
|
||||
printf("bad device: %s\n", dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = sysctlbyname(bl_acpi_sysctl, NULL, NULL, &level, sizeof(level));
|
||||
if (rc < 0)
|
||||
{
|
||||
perror("sysctlbyname");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // __FreeBSD_kernel__
|
||||
|
||||
#if defined(HAVE_EEZE) || defined(__FreeBSD_kernel__)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *dev = NULL;
|
||||
int i, level;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if ((!strcmp(argv[i], "-h")) ||
|
||||
(!strcmp(argv[i], "-help")) ||
|
||||
(!strcmp(argv[i], "--help")))
|
||||
{
|
||||
printf("This is an internal tool for Enlightenment.\n"
|
||||
"do not use it.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
if (argc == 3)
|
||||
{
|
||||
level = atoi(argv[1]);
|
||||
dev = argv[2];
|
||||
}
|
||||
else
|
||||
exit(1);
|
||||
|
||||
if (!dev) return -1;
|
||||
|
||||
if (setuid(0) != 0)
|
||||
{
|
||||
printf("ERROR: UNABLE TO ASSUME ROOT PRIVILEGES\n");
|
||||
exit(5);
|
||||
}
|
||||
if (setgid(0) != 0)
|
||||
{
|
||||
printf("ERROR: UNABLE TO ASSUME ROOT GROUP PRIVILEGES\n");
|
||||
exit(7);
|
||||
}
|
||||
|
||||
return _bl_set(dev, level);
|
||||
}
|
||||
#else // !HAVE_EEZE && !__FreeBSD_kernel__
|
||||
int
|
||||
main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue