Commit 76378e9d authored by Andreas Tille's avatar Andreas Tille

New upstream version 1.2

ACTION=="add", SUBSYSTEM=="backlight", RUN+="/bin/chgrp video /sys/class/backlight/%k/brightness"
ACTION=="add", SUBSYSTEM=="backlight", RUN+="/bin/chmod g+w /sys/class/backlight/%k/brightness"
ACTION=="add", SUBSYSTEM=="leds", RUN+="/bin/chgrp video /sys/class/leds/%k/brightness"
ACTION=="add", SUBSYSTEM=="leds", RUN+="/bin/chmod g+w /sys/class/leds/%k/brightness"
This diff is collapsed.
Change Log
All relevant changes to the project are documented in this file.
[v1.2][] - 2018-09-23
### Changes
- Converted to GNU configure & build system
- Major rewrite to add a device system, folds in all kinds of
display/keyboard/LED controllers under one roof. Note, this
change break command line options from previous releases
- Support for installing as non-SUID root using an udev rule
enabled `--with-udev` to the new configure script
- Migrated to use `~/.cache/light` instead of `/etc/light` for
unpriviliged operation. Respects XDG_CACHE_HOME if set
- Added proper light.1 man page, remvoes help2man dependency
- Update presentation of commands and options in built-in help text,
as well as in the README and man page
- Overhaul of coding style, see for details
- Add Fedora installation instructions
[v1.1.2][] - 2018-06-20
Panic release to fix save/restore.
### Changes
- Add help2man dependency in README
- Better Support for Overriding Install Prefix
- Restore DESTDIR support
### Fixes
- Issue #29: Fix save and restore arguments
- Issue #27: Use the install command instead of raw cp/mv/chmod.
[v1.1][] - 2017-11-23
Various fixes and improvements. Credits to Abdullah ibn Nadjo
### Changes
- Add `-k` flag for keyboard backlight support
- Cache max brightness data from automatic controller detection
- Improve overall logging
- Logging of clamps, saves and restores
- Support for save, restore, get [max] brightness etc. for both screen
and keyboard controllers
### Fixes
- Avoid checking for write permission if just getting value
- Check if controller is accessible before getting value
- Avoid redondant checking
- Don't truncate file contents when checking if file is writable
- Fix `light_controllerAccessible()` and `light_getBrightness()` this
functions were:
- Reading values from the controller
- Checking write permission even when we just want reading values
- Checking the mincap file instead of the actual controller
- Don't try to read brightness values when only targetting max bright
- Fix issues with string buffers and pointers
- Use `NAME_MAX` and `PATH_MAX` instead of hardcoded values
- Allow paths to be longer than 256 chars
- Check pointers everywhere
- Use `strncpy()`/`snprintf()` instead of `strcpy()`/`sprintf()`
- Validate controllers' name (`-s` flag + a very long name = bad
things happening)
- Get rid of globals for dir iteration
[v1.0][] - 2016-05-10
First major release. Light has been around for a while now and seems to
make some people happy. Also someone wanted a new release, so here you
### Changes
- Added save/restore functionality
- Generate man page on `make install`
### Fixes
- Issue #5: Can't increase brightness on ATI propietary driver
- Issue #10: Honor `$DESTDIR` on man page installation
[v0.9][] - 2014-06-08
### Changes
- Complete rewrite of program (Every single byte)
- Cleaner, safer code
- Completely new intuitive usage (Sorry, it was needed)
- Added functionality:
- Ability to set/get minimum brightness directly from commandline
- Ability to specify the backlight controller to use directly from commandline
- Better verbosity
- Probably missed some stuff
v0.7 - 2012-11-18
### Changes
- Ported bash script to C
# Developer Instructions
This file is aimed at developers of light, or developers who want to implement "drivers" (enumerators) for their own hardware.
## Coding Standards
Light is a small project, which helps keep it clean. However we still would like to see a consistent styling throughout the project, as well as in third-party enumerator implementations. The actual source code may not be fully "up to code" yet, but it's getting there.
We use 4 spaces for indentation. We have an empty line at the top and bottom of each file.
The following two sources should be clear enough examples of our coding style:
### Header files
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stdfoo.h> /* foo_type_t */
typedef struct _some_struct_t some_struct_t;
struct _some_struct_t
uint64_t id;
foo_type_t my_foo_thing;
foo_type_t *my_foo_ptr;
/* Describe what the purpose of this function is, what it does with/to foo_struct, and what it returns. */
bool do_some_stuff(some_struct_t *foo_struct);
### Source files
The second line of each source file should be the include to the corresponding header file, followed by an empty line.
Internal/static functions are always prefixed with an underscore (_).
#include "some_struct.h"
static void _increment_one(uint64_t *out_value)
*out_value += 1;
bool do_some_stuff(some_struct_t *foo_struct)
if(foo_struct->id > 33)
return false;
if(foo_struct->my_foo_ptr != NULL)
foo_struct->my_foo_ptr = malloc(sizeof(foo_type_t));
return true;
## Implementing an enumerator
Implementing your own devices through an enumerator is pretty easy. The required steps are as follows:
### Step 1
Create a headerfile and a corresponding sourcefile under the `impl` folder, Call them `foo.h` and `foo.c`. Open up the `sysfs.c` and `sysfs.h` files for reference implementations.
### Step 2
In the header, you need to first do a `#pragma once` (obviously), then `#include "light.h"` to get access to some struct declarations, then at the bare minimum declare 6 functions. If you need to store your own data for each device or device-target, you will need to declare structs for these as well.
#pragma once
#include "light.h"
// Implementation of the foo enumerator
// Enumerates devices for quacking ducks
// Device target data
struct _impl_foo_data_t
int32_t internal_quack_id;
typedef struct _impl_foo_data_t impl_foo_data_t;
bool impl_foo_init(light_device_enumerator_t *enumerator);
bool impl_foo_free(light_device_enumerator_t *enumerator);
bool impl_foo_set(light_device_target_t *target, uint64_t in_value);
bool impl_foo_get(light_device_target_t *target, uint64_t *out_value);
bool impl_foo_getmax(light_device_target_t *target, uint64_t *out_value);
bool impl_foo_command(light_device_target_t *target, char const *command_string);
### Step 3
In the sourcefile, you need to implement the 6 methods. Make sure to return `true` on success and `false` on failure. If you do not actually implement a function (for example `impl_foo_command`), just return `true`.
The job of the enumerator is to identify/enumerate a bunch of different devices (or just one, or even zero if it doesnt find any). You are also responsible to create the device targets for them (i.e, the things that you actually write to on the device). You do this by setting the devices and targets up in `impl_foo_init`. You are not required to do anything in `impl_foo_free`, any allocated memory will be automatically free'd by light, including device/target data that you allocate yourself. You may use `impl_foo_free` to free resources you allocate outside of the light API.
#include "impl/foo.h"
#include "light.h"
#include "helpers.h"
bool impl_foo_init(light_device_enumerator_t *enumerator)
/* Lets create a single device, with a single target, for simplicity */
/* Create a new device called new_device_name, we dont need any userdata so pass NULL to the device_data parameter */
light_device_t *new_device = light_create_device(enumerator, "new_device_name", NULL)
/* Setup userdata specific to the target we will create*/
/* Useful to for example reference an ID in a third-party API or likewise */
/* NOTE: The userdata will be free()'d automatically on exit, so you do not need to free it yourself */
impl_foo_data_t *custom_data = malloc(sizeof(impl_foo_data_t));
custom_data->internal_quack_id = 333;
/* Create a new device target called new_target_name, and pass in the functions and userdata that we just allocated */
light_create_device_target(new_device, "new_target_name", impl_foo_set, impl_foo_get, impl_foo_getmax, impl_foo_command, custom_data)
/* Return true because we didnt get any errors! */
return true;
bool impl_foo_free(light_device_enumerator_t *enumerator)
/* We dont need to do anything here, but if we want to, we can free some third-party API resources */
return true;
/* Implement the other functions to do their thing. Get, Set and GetMax should be self-explanatory. Command is reserved for future use, but basically will allow the user to run custom commands on a target. */
### Step 4
Now that you have implemented your enumerator, it is time to inject it to the application itself. You will be able to compile your enumerator into a plugin in the future, but for now, locate the `light_initialize` function inside `light.c`. You will see some calls (perhaps just one call) to `light_create_enumerator` inside of this function. Add one more call to this function to register your enumerator in the application:
The first argument is the application context, the second is the name that your enumerator will get, and the last two are the init and free functions that we implemented.
light_create_enumerator(new_ctx, "foo", &impl_foo_init, &impl_foo_free);
Once you do this, you should be able to find your device target when running `light -L`, and it should be called something like `foo/new_device_name/new_target_name` if you followed this guide.
The only thing left now is to create a pull request so that the rest of the world can share the functionality that you just implemented!
## Troubleshooting
If you run into any issues, feel free to create a new Github issue, even if you are just asking for "support" or likewise.
dist_man1_MANS = light.1
udev_DATA = 90-backlight.rules
EXTRA_DIST += $(top_srcdir)/90-backlight.rules
# lintian --profile debian -i -I --show-overrides ../$PKG.changes
dpkg-buildpackage -uc -us -B
# Target to run when building a release
release: distcheck
@for file in $(DIST_ARCHIVES); do \
md5sum $$file > ../$$file.md5; \
@mv $(DIST_ARCHIVES) ../
@echo "Resulting release files:"
@echo "================================================================="
@for file in $(DIST_ARCHIVES); do \
printf "%-32s Distribution tarball\n" $$file; \
printf "%-32s " $$file.md5; cat ../$$file.md5 | cut -f1 -d' '; \
@for file in `cd ..; ls $(PACKAGE)_$(VERSION)*`; do \
printf "%-32s Debian/Ubuntu file\n" $$file; \
Light - A program to control backlights (and other hardware lights) in GNU/Linux
*Copyright (C) 2012 - 2018*
*Author: Fredrik Haikarainen*
*Contributor & Maintainer: Joachim Nilsson*
*This is free software, see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE*
- [Introduction](#introduction)
- [Examples](#examples)
- [Usage](#usage)
- [Command options](#command-options)
- [Extra options](#extra-options)
- [Installation](#installation)
- [Arch Linux](#arch-linux)
- [Fedora](#fedora)
- [Manual](#manual)
- [Permissions](#permissions)
- [Origin & References](#origin--references)
[Light][] is a program to control backlights and other lights under GNU/Linux:
* Works where other software has proven unreliable (xbacklight etc.)
* Works even in a fully CLI-environment, i.e. it does not rely on X
* Provides functionality to automatically control backlights with the highest precision available
* Extra features, like setting a minimum brightness value for controllers, or saving/restoring the value for poweroffs/boots.
See the following sections for the detailed descriptions of all available commands, options and how to access different controllers.
Light is available in many GNU/Linux distributions already.
Get the current backlight brightness in percent
light -G
Increase backlight brightness by 5 percent
light -A 5
Set the minimum cap to 2 in raw value on the sysfs/backlight/acpi_video0 device:
light -Nrs "sysfs/backlight/acpi_video0" 2
List available devices
light -L
Activate the Num. Lock keyboard LED, here `sysfs/leds/input3::numlock` is used, but this varies
between different systems:
light -Srs "sysfs/leds/input3::numlock" 1
Usage follows the following pattern, where options are optional and the neccesity of value depends on the options used
light [options] <value>
### Command options
You may only specify one command flag at a time. These flags decide what the program will ultimately end up doing.
* `-H` Show help and exit
* `-V` Show program version and exit
* `-L` List available devices
* `-A` Increase brightness by value (value needed!)
* `-U` Decrease brightness by value (value needed!)
* `-S` Set brightness to value (value needed!)
* `-G` Get brightness
* `-N` Set minimum brightness to value (value needed!)
* `-P` Get minimum brightness
* `-I` Save the current brightness
* `-O` Restore the previously saved brightness
Without any extra options, the command will operate on the device called `sysfs/backlight/auto`, which works as it's own device however it proxies the backlight device that has the highest controller resolution (read: highest precision). Values are interpreted and printed as percentage between 0.0 - 100.0.
**Note:** If something goes wrong, you can find out by maxing out the verbosity flag by passing `-v 3` to the options. This will activate the logging of warnings, errors and notices. Light will never print these by default, as it is designed to primarily interface with other applications and not humanbeings directly.
### Extra options
These can be mixed, combined and matched after convenience.
* `-r` Raw mode, values (printed and interpreted from commandline) will be treated as integers in the controllers native range, instead of in percent.
* `-v <verbosity>` Specifies the verbosity level. 0 is default and prints nothing. 1 prints only errors, 2 prints only errors and warnings, and 3 prints both errors, warnings and notices.
* `-s <devicepath>` Specifies which device to work on. List available devices with the -L command. Full path is needed.
### Arch Linux
If you run Arch Linux, we highly recommend the PKGBUILD in the repo. However there also exist 2 packages in the AUR, which we aim to replace;
* [light-git][] - For the latest development branch (master)
* [light][] - For the latest stable release
### Fedora
Fedora already has light packaged in main repos, so just run:
dnf install light
and you're good to go.
### Debian/Ubuntu
Pre-built .deb files, for the latest Ubuntu release, can be downloaded
from the [GitHub][Light] releases page. If you want to build your own
there is native support available in the GIT sources. Clone and follow
the development branch guidelines below followed by:
make deb
### Manual
If you download a stable release, these are the commands that will get you up and running:
tar xf light-x.yy.tar.gz
cd light-x.yy/
./configure && make
sudo make install
However the latest development branch requires some extras. Clone the repository and run the `` script. This requires that `automake` and `autoconf` is installed on your system.
./configure && make
sudo make install
The `configure` script and `` files are not part of GIT because they are generated at release time with `make release`.
### Permissions
Optionally, instead of the classic SUID root mode of operation, udev rules can be set up to manage the kernel sysfs permissions. Use the configure script to enable this mode of operation:
./configure --with-udev && make
sudo make install
This installs the `90-backlight.rules` into `/usr/lib/udev/rules.d/`.
If your udev rules are located elsewhere, use `--with-udev=PATH`.
**Note:** make sure that your user is part of the `video` group, otherwise you will not get access to the devices.
**Note:** in this mode `light` runs unpriviliged, so the `/etc/light`
directory (for cached settings) is not used, instead the per-user
specific `~/.cache/light` is used.
# Maintainer: Fredrik Haikarainen <>
pkgdesc='Application to control hardware lights, backlights, leds.'
arch=('i686' 'x86_64')
pkgver() {
cd "$srcdir/light"
git describe --tags --long | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g'
cd "$srcdir/light"
./configure --with-udev --prefix=/usr
cd "$srcdir/light"
make DESTDIR="$pkgdir/" install
autoreconf -W portability -visfm
AC_INIT([light], [1.2], [])
AM_INIT_AUTOMAKE([1.11 foreign subdir-objects])
AC_CONFIG_FILES([Makefile src/Makefile])
AS_HELP_STRING([--with-udev@<:@=PATH@:>@], [use udev instead of SUID root, optional rules.d path]),
[udev=$withval], [udev=no])
AC_MSG_CHECKING(for udev rules.d)
AS_IF([test "x$udev" != "xno"], [
AS_IF([test "x$udev" = "xyes"], [
AC_MSG_RESULT([disabled, classic SUID root mode])
# Allow classic SUID root behavior if udev rule is not used
AM_CONDITIONAL(UDEV, [test "x$udev" != "xno"])
AM_CONDITIONAL(CLASSIC, [test "x$udev" = "xno"])
light (1.2) unstable; urgency=low
* Initial Debian Release.
-- Joachim Nilsson <> Sat, 22 Sep 2018 11:53:32 +0200
Source: light
Section: x11
Priority: optional
Maintainer: Joachim Nilsson <>
Build-Depends: debhelper (>= 10)
Standards-Version: 4.2.1
Package: light
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Control display backlight controllers and LEDs
Light is a useful tool to control display brightness in lightweight
desktops or window managers that do not have bundled appliations for
this purpose.
Most modern laptops have moved away from hardware controlled brightness
and require software control. Light works where other software has
proven to be unreliable, e.g. xbacklight. It can even be used from the
console as it does not rely on X.
Light has features like setting a minimum brightness value, as well as
saving and restoring the brightness at reboot and startup.
Upstream-Name: light
Files: *
Copyright: Copyright 2012-2018 Fredrik Haikarainen <>
License: GPL-3
Files: debian/*
Copyright: Copyright 2018 Joachim Nilsson <>
License: GPL-3
License: GPL-3
Indicator Weather is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
License version 3 as published by the Free Software Foundation.
Indicator Weather is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
PURPOSE. See the GNU General Public License for more
You should have received a copy of the GNU General Public
License along with this package; if not, write to the Free
Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Boston, MA 02110-1301 USA
On Debian systems, the full text of the GNU General Public
License version 3 can be found in the file
\ No newline at end of file
#!/usr/bin/make -f
# export DH_VERBOSE=1
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
dh $@
dh_auto_configure -- --with-udev
rm -f debian/light/usr/share/doc/light/COPYING
rm -f debian/light/usr/share/doc/light/
opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/light-$1\.tar\.gz/ \ .*/light-?(\d\S*)\.tar\.gz
.\" -*- nroff -*-
.Dd August 4, 2018
.Os GNU/Linux
.Nm light
.Nd a program to control backlight controllers
.Nm light
is a program to control backlight display and keyboard controllers under
.Bl -bullet -compact
Operates independently of X (X-Window)
Can automatically figure out the best controller to use, making full use
of the underlying hardware
Supports a minimum cap on the brightness value, as some controllers set
the display to be pitch black at a vaĺue of 0 (or higher)
The following unique commands are supported:
.Bl -tag -width Ds
.It Fl H , Fl h
Show help text and exit
.It Fl V
Show program version and exit
.It Fl L
List available devices
.It Fl A
Increase brightness by value
.It Fl U
Decrease brightness by value
.It Fl S
Set brightness to value
.It Fl G
Get brightness, default
.It Fl N
Set minimum brightness to value
.It Fl P
Get minimum brightness
.It Fl I
Save current brightness
.It Fl O
Restore previously saved brightness
The behavior of the above commands can be modified using these options:
.Bl -tag -width Ds
.It Fl r
Interpret input and output values in raw mode
.It Fl s Ar PATH
Specify device target path. Use
.Fl L
to list available devices
.It Fl v Ar LEVEL
Set verbosity level, by default
only outputs read values:
.Bl -tag -width 0: -compact
.It 0:
Read values
.It 1:
Read values, Errors
.It 2: