299 lines
9.8 KiB
Diff
299 lines
9.8 KiB
Diff
|
From 032e57b4e9a90dc11352f1d6640ee246e3f32fb7 Mon Sep 17 00:00:00 2001
|
||
|
From: Lennart Poettering <lennart@poettering.net>
|
||
|
Date: Wed, 14 Aug 2013 01:57:02 +0200
|
||
|
Subject: [PATCH] backlight: add minimal tool to save/restore screen brightness
|
||
|
across reboots
|
||
|
|
||
|
As many laptops don't save/restore screen brightness across reboots,
|
||
|
let's do this in systemd with a minimal tool, that restores the
|
||
|
brightness as early as possible, and saves it as late as possible. This
|
||
|
will cover consoles and graphical logins, but graphical desktops should
|
||
|
do their own per-user stuff probably.
|
||
|
|
||
|
This only touches firmware brightness controls for now.
|
||
|
---
|
||
|
.gitignore | 1 +
|
||
|
Makefile.am | 20 ++++++
|
||
|
configure.ac | 9 +++
|
||
|
rules/99-systemd.rules.in | 4 ++
|
||
|
rules/Makefile | 1 +
|
||
|
src/backlight/Makefile | 1 +
|
||
|
src/backlight/backlight.c | 126 ++++++++++++++++++++++++++++++++++++
|
||
|
units/.gitignore | 1 +
|
||
|
units/systemd-backlight@.service.in | 21 ++++++
|
||
|
9 files changed, 184 insertions(+)
|
||
|
create mode 120000 rules/Makefile
|
||
|
create mode 120000 src/backlight/Makefile
|
||
|
create mode 100644 src/backlight/backlight.c
|
||
|
create mode 100644 units/systemd-backlight@.service.in
|
||
|
|
||
|
diff --git a/.gitignore b/.gitignore
|
||
|
index bdf9d4a..379a3c1 100644
|
||
|
--- a/.gitignore
|
||
|
+++ b/.gitignore
|
||
|
@@ -29,6 +29,7 @@
|
||
|
/systemd-ac-power
|
||
|
/systemd-analyze
|
||
|
/systemd-ask-password
|
||
|
+/systemd-backlight
|
||
|
/systemd-binfmt
|
||
|
/systemd-bootchart
|
||
|
/systemd-cat
|
||
|
diff --git a/Makefile.am b/Makefile.am
|
||
|
index 7933de6..0059b1d 100644
|
||
|
--- a/Makefile.am
|
||
|
+++ b/Makefile.am
|
||
|
@@ -3267,6 +3267,26 @@ EXTRA_DIST += \
|
||
|
units/systemd-random-seed.service.in
|
||
|
|
||
|
# ------------------------------------------------------------------------------
|
||
|
+if ENABLE_BACKLIGHT
|
||
|
+rootlibexec_PROGRAMS += \
|
||
|
+ systemd-backlight
|
||
|
+
|
||
|
+nodist_systemunit_DATA += \
|
||
|
+ units/systemd-backlight@.service
|
||
|
+
|
||
|
+systemd_backlight_SOURCES = \
|
||
|
+ src/backlight/backlight.c
|
||
|
+
|
||
|
+systemd_backlight_LDADD = \
|
||
|
+ libsystemd-label.la \
|
||
|
+ libsystemd-shared.la \
|
||
|
+ libudev-private.la
|
||
|
+endif
|
||
|
+
|
||
|
+EXTRA_DIST += \
|
||
|
+ units/systemd-backlight@.service.in
|
||
|
+
|
||
|
+# ------------------------------------------------------------------------------
|
||
|
if HAVE_LIBCRYPTSETUP
|
||
|
rootlibexec_PROGRAMS += \
|
||
|
systemd-cryptsetup
|
||
|
diff --git a/configure.ac b/configure.ac
|
||
|
index 759073a..f7237bd 100644
|
||
|
--- a/configure.ac
|
||
|
+++ b/configure.ac
|
||
|
@@ -667,6 +667,14 @@ fi
|
||
|
AM_CONDITIONAL(ENABLE_RANDOMSEED, [test "$have_randomseed" = "yes"])
|
||
|
|
||
|
# ------------------------------------------------------------------------------
|
||
|
+have_backlight=no
|
||
|
+AC_ARG_ENABLE(backlight, AS_HELP_STRING([--disable-backlight], [disable backlight tools]))
|
||
|
+if test "x$enable_backlight" != "xno"; then
|
||
|
+ have_backlight=yes
|
||
|
+fi
|
||
|
+AM_CONDITIONAL(ENABLE_BACKLIGHT, [test "$have_backlight" = "yes"])
|
||
|
+
|
||
|
+# ------------------------------------------------------------------------------
|
||
|
have_logind=no
|
||
|
AC_ARG_ENABLE(logind, AS_HELP_STRING([--disable-logind], [disable login daemon]))
|
||
|
if test "x$enable_logind" != "xno"; then
|
||
|
@@ -992,6 +1000,7 @@ AC_MSG_RESULT([
|
||
|
quotacheck: ${have_quotacheck}
|
||
|
tmpfiles: ${have_tmpfiles}
|
||
|
randomseed: ${have_randomseed}
|
||
|
+ backlight: ${have_backlight}
|
||
|
logind: ${have_logind}
|
||
|
machined: ${have_machined}
|
||
|
hostnamed: ${have_hostnamed}
|
||
|
diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in
|
||
|
index e9b2da7..ac4bc86 100644
|
||
|
--- a/rules/99-systemd.rules.in
|
||
|
+++ b/rules/99-systemd.rules.in
|
||
|
@@ -51,6 +51,10 @@ SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:
|
||
|
|
||
|
ACTION=="add", SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name"
|
||
|
|
||
|
+# Pull in backlight save/restore for all firmware backlight devices
|
||
|
+
|
||
|
+ACTION=="add", SUBSYSTEM=="backlight", ATTR{type}=="firmware", TAG+="systemd", ENV{SYSTEMD_WANTS}+="systemd-backlight@sys%p.service"
|
||
|
+
|
||
|
# Asynchronously mount file systems implemented by these modules as
|
||
|
# soon as they are loaded.
|
||
|
|
||
|
diff --git a/rules/Makefile b/rules/Makefile
|
||
|
new file mode 120000
|
||
|
index 0000000..bd10475
|
||
|
--- /dev/null
|
||
|
+++ b/rules/Makefile
|
||
|
@@ -0,0 +1 @@
|
||
|
+../src/Makefile
|
||
|
\ No newline at end of file
|
||
|
diff --git a/src/backlight/Makefile b/src/backlight/Makefile
|
||
|
new file mode 120000
|
||
|
index 0000000..d0b0e8e
|
||
|
--- /dev/null
|
||
|
+++ b/src/backlight/Makefile
|
||
|
@@ -0,0 +1 @@
|
||
|
+../Makefile
|
||
|
\ No newline at end of file
|
||
|
diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c
|
||
|
new file mode 100644
|
||
|
index 0000000..3378907
|
||
|
--- /dev/null
|
||
|
+++ b/src/backlight/backlight.c
|
||
|
@@ -0,0 +1,126 @@
|
||
|
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||
|
+
|
||
|
+/***
|
||
|
+ This file is part of systemd.
|
||
|
+
|
||
|
+ Copyright 2013 Lennart Poettering
|
||
|
+
|
||
|
+ systemd is free software; you can redistribute it and/or modify it
|
||
|
+ under the terms of the GNU Lesser General Public License as published by
|
||
|
+ the Free Software Foundation; either version 2.1 of the License, or
|
||
|
+ (at your option) any later version.
|
||
|
+
|
||
|
+ systemd 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
|
||
|
+ Lesser General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU Lesser General Public License
|
||
|
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||
|
+***/
|
||
|
+
|
||
|
+#include <libudev.h>
|
||
|
+
|
||
|
+#include "util.h"
|
||
|
+#include "mkdir.h"
|
||
|
+#include "fileio.h"
|
||
|
+
|
||
|
+int main(int argc, char *argv[]) {
|
||
|
+ struct udev *udev = NULL;
|
||
|
+ struct udev_device *device = NULL;
|
||
|
+ _cleanup_free_ char *saved = NULL;
|
||
|
+ int r;
|
||
|
+
|
||
|
+ if (argc != 3) {
|
||
|
+ log_error("This program requires two arguments.");
|
||
|
+ return EXIT_FAILURE;
|
||
|
+ }
|
||
|
+
|
||
|
+ log_set_target(LOG_TARGET_AUTO);
|
||
|
+ log_parse_environment();
|
||
|
+ log_open();
|
||
|
+
|
||
|
+ umask(0022);
|
||
|
+
|
||
|
+ r = mkdir_p("/var/lib/backlight", 0755);
|
||
|
+ if (r < 0) {
|
||
|
+ log_error("Failed to create backlight directory: %s", strerror(-r));
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ udev = udev_new();
|
||
|
+ if (!udev) {
|
||
|
+ r = log_oom();
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ device = udev_device_new_from_syspath(udev, argv[2]);
|
||
|
+ if (!device) {
|
||
|
+ r = log_oom();
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!streq_ptr(udev_device_get_subsystem(device), "backlight")) {
|
||
|
+ log_error("Not a backlight device: %s", argv[2]);
|
||
|
+ r = -ENODEV;
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ saved = strappend("/var/lib/backlight/", udev_device_get_sysname(device));
|
||
|
+ if (!saved) {
|
||
|
+ r = log_oom();
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (streq(argv[1], "load")) {
|
||
|
+ _cleanup_free_ char *value = NULL;
|
||
|
+
|
||
|
+ r = read_one_line_file(saved, &value);
|
||
|
+ if (r < 0) {
|
||
|
+
|
||
|
+ if (r == -ENOENT) {
|
||
|
+ r = 0;
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ log_error("Failed to read %s: %s", saved, strerror(-r));
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ r = udev_device_set_sysattr_value(device, "brightness", value);
|
||
|
+ if (r < 0) {
|
||
|
+ log_error("Failed to write system attribute: %s", strerror(-r));
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ } else if (streq(argv[1], "save")) {
|
||
|
+ const char *value;
|
||
|
+
|
||
|
+ value = udev_device_get_sysattr_value(device, "brightness");
|
||
|
+ if (!value) {
|
||
|
+ log_error("Failed to read system attribute: %s", strerror(-r));
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ r = write_string_file(saved, value);
|
||
|
+ if (r < 0) {
|
||
|
+ log_error("Failed to write %s: %s", saved, strerror(-r));
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+ } else {
|
||
|
+ log_error("Unknown verb %s.", argv[1]);
|
||
|
+ r = -EINVAL;
|
||
|
+ goto finish;
|
||
|
+ }
|
||
|
+
|
||
|
+finish:
|
||
|
+ if (device)
|
||
|
+ udev_device_unref(device);
|
||
|
+
|
||
|
+ if (udev)
|
||
|
+ udev_unref(udev);
|
||
|
+
|
||
|
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||
|
+
|
||
|
+}
|
||
|
diff --git a/units/.gitignore b/units/.gitignore
|
||
|
index 9aee00f..9c65075 100644
|
||
|
--- a/units/.gitignore
|
||
|
+++ b/units/.gitignore
|
||
|
@@ -1,3 +1,4 @@
|
||
|
+/systemd-backlight@.service
|
||
|
/halt-local.service
|
||
|
/rc-local.service
|
||
|
/systemd-hybrid-sleep.service
|
||
|
diff --git a/units/systemd-backlight@.service.in b/units/systemd-backlight@.service.in
|
||
|
new file mode 100644
|
||
|
index 0000000..14b1219
|
||
|
--- /dev/null
|
||
|
+++ b/units/systemd-backlight@.service.in
|
||
|
@@ -0,0 +1,21 @@
|
||
|
+# This file is part of systemd.
|
||
|
+#
|
||
|
+# systemd is free software; you can redistribute it and/or modify it
|
||
|
+# under the terms of the GNU Lesser General Public License as published by
|
||
|
+# the Free Software Foundation; either version 2.1 of the License, or
|
||
|
+# (at your option) any later version.
|
||
|
+
|
||
|
+[Unit]
|
||
|
+Description=Load/Save Screen Backlight Brightness of %f
|
||
|
+Documentation=man:systemd-backlight@.service(8)
|
||
|
+DefaultDependencies=no
|
||
|
+RequiresMountsFor=/var/lib/backlight
|
||
|
+Conflicts=shutdown.target
|
||
|
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
|
||
|
+Before=sysinit.target shutdown.target
|
||
|
+
|
||
|
+[Service]
|
||
|
+Type=oneshot
|
||
|
+RemainAfterExit=yes
|
||
|
+ExecStart=@rootlibexecdir@/systemd-backlight load %f
|
||
|
+ExecStop=@rootlibexecdir@/systemd-backlight save %f
|