\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename blueshift.info @settitle blueshift @afourpaper @documentencoding UTF-8 @documentlanguage en @finalout @c %**end of header @c --- start of do not touch --- @set DOCDIR /usr/share/doc @set PKGNAME blueshift @c --- end of do not touch --- @dircategory Ergonomy @direntry @c * blueshift: (blueshift). Automatically adjust the colour temperature * blueshift: (blueshift). The grand unified dynamic colour adjustment framework @end direntry @copying Copyright @copyright{} 2014 Mattias Andrée @quotation Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. @end quotation @end copying @ifnottex @node Top @c @top blueshift -- Automatically adjust the colour temperature @top blueshift -- The grand unified dynamic colour adjustment framework @insertcopying @end ifnottex @titlepage @title blueshift @c @subtitle Automatically adjust the colour temperature @subtitle The grand unified dynamic colour adjustment framework @author by Mattias Andrée (maandree) @page @vskip 0pt plus 1filll @insertcopying @end titlepage @contents @menu * Overview:: Brief overview of @command{blueshift}. * Invoking:: Invocation of @command{blueshift}. * Signals:: Signals handled by @command{blueshift}. * Configuration API:: How to write configuration files. * Configuration examples:: Example configuration files. * Related software:: Software related to @command{blueshift}. * Terminology:: Related terminology. * GNU Free Documentation License:: Copying and sharing this manual. @end menu @node Overview @chapter Overview Inspired by Redshift, Blueshift adjusts the colour temperature of your monitor according to brightness outside to reduce eye strain and make it easier to fall asleep when going to bed. It can also be used to increase the colour temperature and make the monitor bluer, this helps you focus on your work. Blueshift is not user friendly and it is not meant to be. Blueshift does offer limited use of command line options to apply settings, but it is really meant for you to have configuration files (written in Python 3) where all the policies are implemented, Blueshift is only meant to provide the mechanism for modifying the colour curves. Blueshift neither provides any means of automatically getting your geographical position; the intention is that you should implement that in the policy yourself using library which can do that. Additionally Blueshift provides not safe guards from making your screen unreadable or otherwise miscoloured; and Blueshift will never, officially, add support specifically for any proprietary operating system. Blueshift is fully extensible so it is possible to make extensions that make it usable under unsupported systems, the base code is written in Python 3 without calls to any system dependent functions. If Blueshift does not work for you for any of these reasons, you should take a look at Redshift. @node Invoking @chapter Invoking Blueshift uses argparser to read options from the commnad line. It inherits a few properaties from this: abbreviations are supported, you only need to type the beginning of the long options so that the rest can be filled in unambiguously by the program; @option{--} can be used, as usual, to make all following options being parsed as just arguments; and @option{++} works like @option{--}, except it only allied to the next option. Any argument that is not parsed as an option for Blueshift is passed onto the configuration script. Blueshift recognises the following options: @table @option @item -c @itemx --configurations FILE Select configuration script. This defaults to the first file of the following the exists: @itemize @bullet @item @file{$XDG_CONFIG_HOME/blueshift/blueshiftrc} @item @file{$HOME/.config/blueshift/blueshiftrc} @item @file{$HOME/.blueshiftrc} @item @file{/etc/blueshiftrc} @end itemize Blueshift does not check the user home, rather it checks @env{HOME} which should be the user home, unless you change it yourself. You update the configuration file you can send a SIGUSR1 signal to reload it. @item -p @c the long name of option is inspired from openntpd @itemx --panic-gate @itemx --panicgate Applies the settings directly instead of transitioning into the initial settings. There is not option for doing this when the program exists. But you press @kbd{Control+c} twice, or send SIGTERM twice, to skip transition into default settings. @item -h @itemx -? @itemx --help Prints help information. @item -C @itemx --copying @itemx --copyright Prints copyright information. @item -W @itemx --warranty Prints non-warranty information, included in the copyright information. @item -v @itemx --version Prints the name of the program and the installed version of the program @end table Blueshift also supports a few options for ad-hoc settings. These are ignored (unless fetched by the configuration file) if @option{-c} (@option{--configurations}) is used. @table @option @item -g @itemx --gamma RGB Apply gamma correction to the colour curves. All values in the three colour curves are raised to the power of 1 divided by @code{RGB}. Assuming no values in the curves are larger than 1 (100 %) the curves are bent upwards if @code{RGB} is larger than 1. @item -g @itemx --gamma R:G:B This works as @option{--gamma RGB}, except the gamma is applied separately for the three colour curves. If we want to apply the 0,9 gamma to the red colour component, and 1,1 and 1,2 for the green and blue colour components, respectively use @option{-g 0.9:1.1:1.2} or @option{-gamma 0.9:1.1:1.2}. @item -b @itemx --brightness RGB This multiplies all values in the colour curves with @env{RGB}, effectively making the display @env{RGB} times as bright. Values larger than 1, will be clipped to 1. This is indented to be used to make the screen slightly darker during the night. @item -b @itemx --brightness R:G:B This option is to @option{--brightness RGB} as @option{--gamma R:G:B} is to @option{--gamma RGB}. @item +b @itemx ++brightness Y This option works as @option{--brightness RGB}, except the CIE xyY colour spaces is used instead of sRGB and will probably make the colour curves look better. @item -t @itemx --temperature TEMP Changes the colour tempurature to @code{TEMP} Kelvin. The standard colour tempurature is 6500 K@footnote{Or actually 6504 K using revised constants in Planck's law}. If not specified, the colour temperature will be 3700 K during high night and 6500 K during the high day. @item -l @itemx --location LAT:LON Specify your geographical coordinates. This is used to determine how dark it is outside. @env{LAT} is the latitude, floating point measured in degrees celestial northwards from the equator. It is negative if you are on the southern hemisphere. @env{LON} is the longitude, floating point measured in degrees eastwards from Greenwich. Negative if you are on the west side of the Earth. @item -r @itemx --reset Transition from the specified settings to normal, clean, settings. @item -o @itemx --output @itemx --crtc CRTC Select CRTC to apply changes to. This is comma separated list, and multiple options may be used. It is best to start one instance per monitor with colour calibration. Be aware than under X — using RandR — the primary monitor is reported to have the zeroth CRTC. But under TTY — using DRM — this is no concept of primary monitors, and thus the CRTC indices can slightly different. @end table @option{-g}, @option{-b}, @option{+b}, and @option{-t} can be use twice, each, to use different settings during the night and during the day. While this is possible for gamma, it is not recommended. The purpose of gamma is to adjust the same error that are present in minors and make all colours look correct in relation to each other. @node Signals @chapter Signals @command{blueshift}, by default in continuous mode, implements special support for three signals: @table @asis @item SIGTERM Fades out the settings and exits the first time SIGTERM is received. If SIGTERM is received again, Blueshift immediately resets effects and exits. @kbd{Control+c} is treated as SIGTERM. @item SIGTSTP @itemx SIGCONT Blueshift does implement special handling of the termporary stop signal (SIGTSTP), or continue signal (SIGCONT). So if you send SIGTSTP to Blueshift it pause until you send SIGCONT. With usual TTY settings, the terminal sends SIGTSTP when @kbd{Control+z} is processed. Shells can send SIGCONT if you type either of @code{%}, @code{fg}, @code{%blueshift} or @code{fg blueshift}. @code{bg} or @code{bg blueshift} can be used to continue in the background instead of in the foreground. @item SIGUSR1 Reloads the configuration script. @item SIGUSR2 Disables or enables Blueshift. @end table @node Configuration API @chapter Configuration API @menu * Configuration variables:: Configuration variables. * Colour curve manipulators:: Configuration functions colour adjustments. * Custom colour curve manipulators:: Creating custom colour adjustment functions. * Preexisting adjustments:: Using preexisting adjustment, in use and ICC. * Applying colour curves:: Appying colour adjustments to the video drivers. * Hardware detection:: Detecting connected monitors. * Backlight:: Adjusting monitor backlight. * Continuous mode:: Creating continuous mode configurations. * Solar time:: Solar functions, such as elevation calcuation. * Weather:: Making weather dependent settings. * Running without X:: Configuration options for running without X. * Optimising:: Functions that can be used to optimise performance. @end menu @node Configuration variables @section Configuration variables Blueshift has three colour curves: @table @code @item r_curve The curve for the red colour component. @item g_curve The curve for the green colour component. @item b_curve The curve for the blue colour component. @end table These are @code{i_size} sized floating point lists, where 0 is the darkest colour and 1 is the brightest colour. Values outside this range are clipped unless @code{clip_result} is set to @code{False}. By calling @code{clip} this clipping is done independently of the value of @code{clip_result}. @code{clip} optionally takes one or three arguments, if one, nothing will happen if it is @code{False}, if three, nothing will happen for the red, green and blue colour curves if the first, second and third arguments, respectively, is @code{False}. When applied these values are automatically translated to appropriate integer values: [0, @code{o_size} - 1]. Additionally if the variable @code{panicgate} is @code{True}, there is no fading when the program starts. And @code{conf_opts} is a list of command line arguments passed onto the configuration script; and @code{conf_storage} is a dictionary can be used to store information is required to survive a configuration reload, such as replaced functions. If you want to use the settings intended for ad-hoc mode, set @code{uses_adhoc_opts} to @code{True}. This lets you use @code{parser}, which is an instance of @code{ArgParser} (from the argparser library) which @code{parser} and @code{support_alternatives} already invoked, without a warning being printed. If you do not do this, @code{parser} will be @code{None} at the time @code{periodically} is first invoked by Blueshift. @node Colour curve manipulators @section Colour curve manipulators Blueshift provides a set of functions to manipulate these curves: @table @code @item rgb_contrast(rgb) Adjusts the contrast to @code{rgb}. This function assumes the black is 0, and white is 1, so you should apply this before brightness. Note: This does not correspond to the contrast on monitors control panels used to calibrate the white point. @item rgb_contrast(r, g, b) Adjusts the contrast to @code{r}, @code{g} and @code{b} on the red, green and blue colour curves, respectively. This function assumes the black is 0, and white is 1, so you should apply this before brightness. Note: This does not correspond to the contrast on monitors control panels used to calibrate the white point. @item cie_contrast(rgb) Adjusts the contrast to @code{rgb}. The function calculate the values by using the CIE xyY colour space instead of the sRGB colour space. This function assumes the black is 0, and white is 1, so you should apply this before brightness. Note: This does not correspond to the contrast on monitors control panels used to calibrate the white point. @item cie_contrast(r, g, b) Adjusts the contrast to @code{r}, @code{g} and @code{b} on the red, green and blue colour curves, respectively. The function calculate the values by using the CIE xyY colour space instead of the sRGB colour space. This function assumes the black is 0, and white is 1, so you should apply this before brightness. Note: This does not correspond to the contrast on monitors control panels used to calibrate the white point. @item rgb_brightness(rgb) Adjusts the brightness to @code{rgb}. Note: This does not correspond to the contrast on monitors control panels used to calibrate the white point. Note: This does not correspond to the brightness on monitors control panels used to calibrate the black point point, rather it corresponds to the contrast on monitors control panels used to calibrate white point. @item rgb_brightness(r, g, b) Adjusts the brightness to @code{r}, @code{g} and @code{b} on the red, green and blue colour curves, respectively. Note: This does not correspond to the brightness on monitors control panels used to calibrate the black point point, rather it corresponds to the contrast on monitors control panels used to calibrate white point. @item cie_brightness(rgb) Adjusts the brightness to @code{rgb}. The function calculate the values by using the CIE xyY colour space instead of the sRGB colour space. Note: This does not correspond to the brightness on monitors control panels used to calibrate the black point point, rather it corresponds to the contrast on monitors control panels used to calibrate white point. @item cie_brightness(r, g, b) Adjusts the brightness to @code{r}, @code{g} and @code{b} on the red, green and blue colour curves, respectively. The function calculate the values by using the CIE xyY colour space instead of the sRGB colour space. Note: This does not correspond to the brightness on monitors control panels used to calibrate the black point point, rather it corresponds to the contrast on monitors control panels used to calibrate white point. @item linearise() Converts the colour curves from sRGB to linear RGB. sRGB is the default colour space. @item linearise(rgb) Converts the colour curves from sRGB to linear RGB if @code{rgb} is @code{True}. sRGB is the default colour space. @item linearise(r, g, b) Converts the colour curves from sRGB to linear RGB, but only for the red, green and blue colour curves if @code{red}, @code{green}, @code{blue} is @code{True}, respectively. sRGB is the default colour space. @item standardise() Converts the colour curves from linear RGB to sRGB, the default colour space. @item standardise(rgb) Converts the colour curves from linear RGB to sRGB, the default colour space, if @code{rgb} is @code{True}. @item standardise(r, g, b) Converts the colour curves from linear RGB to sRGB, the default colour space, but only for the red, green and blue colour curves if @code{red}, @code{green}, @code{blue} is @code{True}, respectively. @item gamma(rgb) Adjusts the gamma to @code{rgb}. @item gamma(r, g, b) Adjusts the gamma to @code{r}, @code{g} and @code{b} on the red, green and blue colour curves, respectively. @item negative() Reverse the colour curves on the encoding axis. This creates a negative image with preserved gamma. @item negative(rgb) Reverse the colour curves on the encoding axis if @code{rgb} is @code{True}. @item negative(r, g, b) Reverse the red, green and blue colour curves on the encoding axis if @code{r}, @code{g} and @code{b} are @code{True}, respectively. @item rgb_invert() Inverts the all values on the colour curves. This creates a negative image with inverted gamma. @item rgb_invert(rgb) Inverts the all values on the colour curves if @code{rgb} is @code{True}. @item rgb_invert(r, g, b) Inverts the all values on the red, green and blue colour curves if @code{r}, @code{g} and @code{b} are @code{True}, respectively. @item cie_invert() Inverts the all values on the colour curves using the CIE xyY colour space instead of sRGB. @item cie_invert(rgb) Inverts the all values on the colour curves using the CIE xyY colour space instead of sRGB, if @code{rgb} is @code{true}. @item cie_invert(r, g, b) Inverts the all values on the red, green and blue colour curves using the CIE xyY colour space instead of sRGB if @code{r}, @code{g} and @code{b} are @code{True}, respectively. @item sigmoid(rgb) An inverted sigmoid curve function is applied to the values of in colour curves if @code{rgb} is not @code{None}, @code{rgb} is the sigmoid curve multiplier. @item sigmoid(r, g, b) An inverted sigmoid curve function is applied to the values of in the red, green and blue colour curves if @code{r}, @code{g} and @code{b} are not @code{None}, respectively. @code{r}, @code{g} and @code{b} are the sigmoid curve multipliers for the red, green and blue colour curves, respectively. @item rgb_limits(rgb_min, rgb_max) Changes the black point to @code{rgb_min}, and the white point to @code{rgb_max}. @code{rgb_min} corresponds to the brightness on monitor control panels used to calibrate the black point. @code{rgb_max} corresponds to the contrast on monitor control panels used to calibrate the white point. @item rgb_limits(r_min, r_max, g_min, g_max, b_min, b_max) Changes the black point to (@code{r_min}, @code{g_min}, @code{b_min}), and the white point to (@code{r_max}, @code{g_max}, @code{b_max}). @item cie_limits(rgb_min, rgb_max) Changes the black point to @code{rgb_min}, and the white point to @code{rgb_max}, using the CIE xyY colour space instead of sRGB. @item cie_limits(r_min, r_max, g_min, g_max, b_min, b_max) Changes the black point to (@code{r_min}, @code{g_min}, @code{b_min}), and the white point to (@code{r_max}, @code{g_max}, @code{b_max}), using the CIE xyY colour space instead of sRGB. @item manipulate(rgb) Applies the function @code{rgb} : float @click{} float to the colour curves. Nothing is done if @code{rgb} is @code{None}. @item manipulate(r, g, b) Applies the functions @code{r}, @code{g} and @code{b} : float @click{} float to the red, green and blue colour curves, respectively. Nothing is done for the red, green and blue colour curves if @code{red}, @code{green} and @code{blue} are @code{None}, respectively. @item cie_manipulate(rgb) Applies the function @code{rgb} : float @click{} float to Y component (illumination) of the colour curves when converted to CIE xyY. Nothing is done if @code{rgb} is @code{None}. @item cie_manipulate(r, g, b) Applies the function @code{r}, @code{g} and @code{b} : float @click{} float to Y component (illumination) of the red, green and blue colour curves, respectively, when converted to CIE xyY. Nothing is done for the red, green and blue colour curves if @code{red}, @code{green} and @code{blue} are @code{None}, respectively. @item temperature(temperature, algorithm) Applies the a blackbody colour temperature of @code{temperature}@footnote{Actually multiplied by 1,000556328, due to revisions of natural constants.} Kelvin. Where the white point for that temperature is calculates by the function @code{algorithm} : @code{temperature} @click{} (red, green, blue). When the white point has been calculates, its components are used as parameters in a componentwise brightness adjustment. There are a few algorithm for calculating the white point included: @table @code @item series_d(temperature) Can only calculate the white point correctly for temperatures inside [4000, 7000]. The CIE illuminant series D is used to calculate the white point. @item simple_whitepoint(temperature) Can only calculate the white point accurately for temperatures inside [1000, 40000]. A mathematical model of the @code{cmf_10deg} function is used. @item cmf_2deg(temperature) Uses a lookup table with linear interpolation to calculate temperatures inside [1000, 40000]. CIE 1931 2 degree CMF is used. @item cmf_10deg(temperature) Uses a lookup table with linear interpolation to calculate temperatures inside [1000, 40000]. CIE 1964 10 degree CMF is used. This is the preferred algorithm. @item redshift(temperature, old_version, linear_interpolation = False) Uses the lookup table from Redshift with linear interpolation. If @code{old_version} is @code{True} the table Redshift<=1.8 is used, which is limited to [1000, 10000], and is not that accurate. Otherwise (the default) the table from Redshift>1.8 is used, which is limited to [1000, 25100], and is accurate. If @code{linear_interpolation} is @code{False} (the default) the sRGB colour space is used for interpolation, otherwise linear RGB is used. @end table Some of these algorithms (including @code{cmf_10deg}) are not very good by themself and should be wrapped with @code{divide_by_maximum} or @code{clip_whitepoint} ((red, green, blue) @click{} (red, green, blue) functions.) For example, instead of using @code{cmf_10deg}, you can use @code{lambda t : divide_by_maximum(cmf_10deg(t))}. @item lower_resolution(x, y) Emulate low resolution. @code{x} is the number of colours to emulate that each subpixel can have. @code{y} does the same thing as @code{x}, except on the output axis rather than the encoding axis. For arguments taht are set to @code{None}, the default value will be used. @item lower_resolution(rx, ry, gx, gy, bx, by) This works the same way as @code{lower_resolution(x, y)}, except the subpixels are controlled individually. @code{rx} and @code{ry} are @code{x} and @code{y} for the red subpixel, and analogously for @code{gx} and @code{gy} for green, and @code{bx} and @code{by} for blue. For arguments taht are set to @code{None}, the default value will be used. @end table Keep in mind that the order your call the function matters. For example, adjusting the gamma before the brightness does not yeild the same result as in the reverse order, the latter is the correct way to apply gamma correction. Before performing adjusts you must (not required the very first time) reset the curves by invoking @code{start_over} (no parameters.) Otherwise the adjustments will accumulate. @node Custom colour curve manipulators @section Custom colour curve manipulators If you want to write your own functions @code{curves(r, g, b)} returns a tuple containing the tuples @code{(r_curve, r)}, @code{(g_curve, g)} and @code{(b_curve, b)}. To make this easier Blueshift provies a set of functions used to convert colour space: @table @code @item linear_to_standard(r, g, b) Convert [0, 1] linear RGB to [0, 1] sRGB @item standard_to_linear(r, g, b) Convert [0, 1] sRGB to [0, 1] linear RGB @item ciexyy_to_ciexyz(x, y, Y) Convert CIE xyY to CIE XYZ @item ciexyz_to_ciexyy(X, Y, Z) Convert CIE XYZ to CIE xyY @item ciexyz_to_linear(X, Y, Z) Convert CIE XYZ to [0, 1] linear RGB @item linear_to_ciexyz(r, g, b) Convert [0, 1] linear RGB to CIE XYZ @item srgb_to_ciexyy(r, g, b) Convert [0, 1] sRGB to CIE xyY @item ciexyy_to_srgb(x, y, Y) Convert CIE xyY to [0, 1] sRGB @item ciexyz_to_cielab(x, y, z) Convert CIE XYZ to CIE L*a*b* @item cielab_to_xiexyz(l, a, b) Convert CIE L*a*b* to CIE XYZ @end table All these functions return lists with the three colour components, not tuples. Input and output is one colour instance. If you want to calculated the distance (difference) between two colours, you can use @code{delta_e}. It has two parameters, each is red–green–blue-tuple of an sRGB colour. The just notice difference is circa 2,3. @node Preexisting adjustments @section Preexisting adjustments If you have an ICC profile for calibration (applied last) or want to use one for as a video filter (applied first), the function @code{load_icc} can be used to load an ICC profile file. @code{load_icc} takes one argument, the pathname of the ICC profile file; the function returns a fuction that can be invoked to apply the profile. Alternatively, you can use either of the functions: @table @code @item parse_icc(data) Parse raw (series of bytes) ICC profile data into a function that applies the profile when invoked. @item get_current_icc_raw() Load the raw data for the currently applied ICC profiles, stored on the X server. This function returns a list of 3-tuples, each tuple contains the index of a screen, the index of a monitor and the raw data (series of bytes) of the ICC profile for indicated monitor on the indicated screen. Monitors without profiles are not listed. Associated ICC profile is mapped as properties of the root window of X screens. The ICC profile of a primary monitor in a screen is saved as a property named @var{_ICC_PROFILE}, the secondary monitor is stored as @var{_ICC_PROFILE_1}, the tertiary monitor is stored as @var{_ICC_PROFILE_2}, and so on. @item get_current_icc() This function works like @code{get_current_icc_raw}, except rather than returning raw profile data it returns functions that apply the profiles when invoked. @end table If you have multiple profiles you want to interpolate or want to, possible with an interpolation, apply a profile partially, that is, interpolate between it an an identity profile, you can use the function @code{make_icc_interpolation}. It takes your profiles as one argument, as a list, and outputs a function that applies an interpolation of the profiles, it takes to arguments: the timepoint and the filter alpha. The timepoint is normally a [0, 1] floating point of the dayness level, this means that you only have two ICC profiles, but you have multiple profiles, in such case profile the floor of the timepoint value is takes as the index of the first profile to use in the interpolation as well as the following profile (first profile if the last profile was select). They are interpolated linearly. The filter alpha is a [0, 1] floating point of the degree to which the profile should be applied. If you want to apply your adjustments on top of the current colour adjustments, you can use the functions @code{randr_get} or @code{vidmode_get}. @code{randr_get} and @code{vidmode_get} have optional two parameters, @code{crtc} and @code{screen}, which are the CRTC of the monitor to read from, and the screen to which the monitor belongs, respectively. The functions return a parameterless function that applies adjustsments that were applied at the time of invokation of @code{randr_get} or @code{vidmode_get} to the current working curves. @node Applying colour curves @section Applying colour curves To apply a colour curve to the display server, invoke the @code{randr} function, or @code{vidmode}@footnote{@code{vidmode} has the same API as @code{randr}, but it only supports using the zeroth CRTC.}; @code{print_curves} can be used to print the curves to stdout instead (for debugging). These functions apply the curves to all monitors in the default screen (screen 0), put you can also use select monitors by specifying each monitor in as separate arguments. The monitors are indexed from zero. The screen by can be selected by adding the argument @code{screen = X}, where @code{X} is the index of the screen. @code{print_curves} has a third optional parameters: @code{compact}, if it is set to @code{True}, the curves will be printed with run-length encoding. If you want to write your own curve flushing fucntion @code{translate_to_integers} can be used, it returned the colour curves converted from floating point lists to integer lists in a tuple of three (red, green and blue.) Replace the parameterless function @code{close_c_bindings} to make it free all used resource, this is invoked when Blueshift exits. When Blueshift exists, it invoked the parameterless function @code{reset} which you should replace. By default it resets the colour curves and flushes it to all monitors. To restrict which monitors it applies the changes to replace @code{monitor_controller} with a parameterless function that sends the colour curves to the desired monitors to the display server. This is only done if Blueshift runs in continuous mode. @node Hardware detection @section Hardware detection To support multiple monitors in a dynamic way, the function @code{list_screens} can be used. @code{list_screens} has one optional parameter and returns the an instance of the class @code{Screens}. Instances of @code{Screens} have one variable: @code{screens}, a list of instances of the class @code{Screen}. The index of each screens is their index in @code{screens}. @code{list_screens}'s parameter, @code{method}, selects the method and defaults to `randr', it also supports the method `drm'. Instances of the class @code{Screen} have two variables: @code{crtc_count}, the number of CRT controllers used within the screen, and @code{outputs}, a list of all output ports as instances of the class @code{Output}. Instances of @code{Output} have six variables: @table @code @item name The name of the output port. @item connected Whether the output is known to be connected to a monitor. @item widthmm The physical width of the monitor, measured in millimetres. @code{None} if unknown or if not connected. @item heightmm The physical height of the monitor, measured in millimetres. @code{None} if unknown or if not connected. @item crtc The CRT controller index. @code{None} if not connected. @item screen The screen index. @code{None} if not used. @item edid The extended display identification data of the monitor in lower case hexadecimal representations. @code{None} if not used or not found. If the monitor is used it is probably found because it is needed for plug and play support of the monitor. @end table @code{Screens} and @code{Screen} provide a set of functions for finding the output, and traversal the CRTC and screen, a monitor is connected to: @table @code @item find_by_crtc(index) Matches outputs by CRTC index. If @code{index} is @code{None}, it will find unused outputs. @item find_by_name(name) Matches outputs by output name. @item find_by_size(widthmm, heightmm) Matches outputs by physical size of the monitor. @code{widthmm} and @code{heightmm} are the monitor's physical width and heigth, respectively, measured in millimetres. IF @code{widthmm} and @code{heightmm} are @code{None} it will find unused outputs and outputs whether the monitor's size is unknown. @item find_by_connected(status) Matches outputs that are known to be in used (if @code{status} is @code{True}) or outputs that are either unused or not known whether they are used or not (if @code{status} is @code{False}.) @item find_by_edid(name) Matches outputs by monitor extended display identification data. @end table These functions returns a list of matching @code{Output}:s. The list is empty if non are found. @node Backlight @section Backlight @command{blueshift} offers support for adjusting the backlight on monitors through Linux's sysfs. When available this preferable to adjusting the brightness. It does however have two drawbacks: it interferes with manual adjustments and depending on the backlight controller you may have very few backlight levels available. To list the available backlight controllers, run the function @code{list_backlights}, has ho parameters, it returns a list of controller names. To use a backlight controller, invoke the contructor of the class @code{Backlight}. It takes one manditory argument, the backlight controller either by name or path, and two optional arguments: @code{adjbacklight} and @code{minimum}. @code{adjbacklight} is booleanic, if @code{True} the command @command{adjbacklight} from the package with the same name will be used to set the backlight, rather than @command{blueshift} setting it by itself; this lets you adjust the backlight without root permissions and without the administrator justing the permission of @file{/sys/class/backlight/*/brightness} files. @code{minimum} is an integer and is zero by default, which is the lowest logical value to have. @code{minimum} raises the minimum value from zero to avaoid the backlight from getting stuck at zero when reached, as happens on some controllers. Instances of the class @code{Backlight} have one variable: @code{maximum}. @code{maximum} is an integer and is the highest inclusive brightness level. Instances also have two properties: @code{actual} and @code{brightness}. @code{actual} is read-only and gets the current actual backlight level. @code{brightness} can both be read and write and gets or sets the current backlight level. Both are integer properties. @node Continuous mode @section Continuous mode In continuous mode, there are some interesting variables you can adjust at any time: @table @code @item wait_period The number of seconds to wait before updating the colour curves again. This is a floating point variable. @item fadein_time he number of seconds used to fade in on start, @code{None} for no fading. This is a floating point variable. @item fadeout_time The number of seconds used to fade out on exit, @code{None} for no fading. This is a floating point variable. @item fadein_steps The number of steps in the fade in phase, if any. @item fadeout_steps The number of steps in the fade out phase, if any. @item running Set to @code{False} to exit the program. This is normally done when @kbd{Control+c} is pressed or a SIGTERM signal has been received. @item panic This variable only have effect if @code{running} is @code{False}. If this variable is set to @code{True}, the program will immediately run @code{reset} and exit. This is normally done the second time @kbd{Control+c} is pressed or the second time a SIGTERM signal has been received. (Or if both has happend.) @end table The parameterless function @code{continuous_run}, may replace if you want to do something very special, is invoked to run the continuous mode, it the program shall run in continuous mode. Which is determined by whether the function @code{periodically} is defined. Updates to @code{continuous_run} are ignored when SIGUSR1 signals are received. You can also replace the function @code{signal_SIGTERM}. @code{continuous_run} sets up the program to run it when the program receive a SIGTERM signal. @code{continuous_run} also invokes it when @kbd{Control+c} is pressed. @code{signal_SIGTERM} has two parameters, the second can be ignored as it is normally @code{None}; the first parameter is the signal that is received (an integer), and zero if @kbd{Control+c} has been pressed. Similarly @code{signal_SIGUSR1} and @code{signal_SIGUSR2} are invoked when the programs received a SIGUSR1 signal or a SIGUSR2 signal, respectively. SIGUSR1 reloads the configurations and SIGUSR2 enables or disables Blueshift. To run in continuous mode, you must implement the function @code{periodically}. It takes 8 positional arguments: @table @code @item year The year. @item month The month, 1 = January, 12 = December. @item day The day, minimum value is 1, probable maximum value is 31. Theoretically, but most probably not, a change in the calender system could happen and the month's could length could be increased. This has happend once, giving us 1712-(02)Feb-30. @item hour The hour, minimum value is 0, maximum value is 23. @item minute The minute, minimum value is 0, maximum value is 59. @item second The second, minimum value is 0, probable maximum value is 60. We can get 60, or even higher (but that has never happend yet) due to leapseconds. A minutes length could also be shortend, but that has never happend yet either. @item weekday The weekday, 1 = Monday, 7 = Sunday. @item fade Normally, @code{periodically} is invoked with @code{fade} set to @code{None}. This is note the case when the program starts or exits. When @code{fade} is not @code{None}, @code{wait_period} is not honoured. Blueshift can use @code{periodically} to fade into a state when it start or exits. @code{fade} can either be negative, zero or positive or @code{None}, but the magnitude of value cannot exceed 1. When Blueshift starts, the function will be invoked multiple with the time parameters of the time it is invoked and each time @code{fade} will increase towards 1, starting at 0, when the value is 1, the settings should be applied to 100 %. After this this function will be invoked once again with @code{fade} being @code{None}. When Blueshift exits the same behaviour is used except, @code{fade} decrease towards @math{-1} but start slightly below 0, when @math{-1} is reached all settings should be normal. Then Blueshift will @emph{not} invoke this function with @code{fade} being @code{None}, instead it will by itself revert all settings, by calling @code{reset} and quit. @end table Python does not specify that the exceptions can happen, but do not could on them not. Python's documentation could be work, or the API could change. If you want higher time precision --- the time parameters are integers --- you are welcome to use Python's time API. @code{periodically} will never be invoked with fake time. Just do not mix as you could theoretically get on two different seconds, minutes, hours, or even days, months or years, the delay between Blueshift's timestamp and yours could overlap an increase in the second. @node Solar time @section Solar time Blueshift includes a simple way to get the Sun's position. The function @code{sun(latitude, longitude)} returns the visibility of the Sun as an [0, 1] floating point. It has three optional, additional, parameters: @table @code @item t = None The time in Julian Centuries. @item low = -6.0 The Suns elevation at the limit to high night, that is, the highest possible position (measured in degrees) of the Sun before it becomes visible. @item high = 3.0 The Suns elevation at the limit to high day, that is, the lowest possible position (measured in degrees) of the before it starts becoming less visible (twilight.) @end table To convert a time to Julian Centuries, you can use the function @code{epoch_to_julian_centuries}. It takes one argument, the POSIX time, that is, the number of seconds that have elapsed since 1970-(01)Jan-01 00:00:00 UTC, not counting leap seconds. A set of functions that are used to calculate the Sun's are provided: @table @code @item julian_day_to_epoch(t) Converts a Julian Day timestamp to a POSIX time timestamp. @item epoch_to_julian_day(t) Converts a POSIX time timestamp to a Julian Day timestamp. @item julian_day_to_julian_centuries(t) Converts a Julian Day timestamp to a Julian Centuries timestamp. @item julian_centuries_to_julian_day(t) Converts a Julian Centuries timestamp to a Julian Day timestamp. @item epoch_to_julian_centuries(t) Converts a POSIX time timestamp to a Julian Centuries timestamp. @item julian_centuries_to_epoch(t) Converts a Julian Centuries timestamp to a POSIX time timestamp. @item epoch() Returns the current time in POSIX time. @item julian_day() Returns the current time in Julian Day time. @item julian_centuries() Returns the current time in Julian Centuries time (100 Julian days since J2000.) @item radians(deg) Converts from degrees to radians. @item degrees(rad) Converts from radians to degrees. @item sun_geometric_mean_longitude(t) Calculates the Sun's geometric mean longitude, in radians. @item sun_geometric_mean_anomaly(t) Calculates the Sun's geometric mean anomaly, in radians. @item earth_orbit_eccentricity(t) Calculates the Earth's orbit eccentricity. @item sun_equation_of_centre(t) Calculates the Sun's equation of the centre, the difference between the true anomaly and the mean anomaly, in radians. @item sun_real_longitude(t) Calculates the Sun's real longitudinal position, in radians. @item sun_apparent_longitude(t) Calculates the Sun's apparent longitudinal position, in radians. @item mean_ecliptic_obliquity(t) Calculates the mean ecliptic obliquity, in radians, of the Sun's apparent motion without variation correction. @item corrected_mean_ecliptic_obliquity(t) Calculates the mean ecliptic obliquity, in radians, of the Sun's apparent motion with variation correction. @item solar_declination(t) Calculates the Sun's declination, in radians. @item equation_of_time(t) Calculates the equation of time, the discrepancy between apparent and mean solar time, in degrees. @item hour_angle_from_elevation(latitude, declination, elevation) Calculates the solar hour angle from the Sun's elevation. @item elevation_from_hour_angle(latitude, declination, hour_angle) Calculates the Sun's elevation from the solar hour angle. @item time_of_solar_noon(t, longitude) Calculates the time of the closest solar noon. @item time_of_solar_elevation(t, noon, latitude, longitude, elevation) Calculates the time the Sun has the apparent elevation @code{elevation}, in degrees, at the geographical position (@code{latitude}, @code{longitude}). @code{noon} is the time the closest the solar noon. @item solar_elevation_from_time(t, latitude, longitude) Calculates the Suns elevation, in degrees, as apparent from the geographical position (@code{latitude}, @code{longitude}). @item solar_elevation(latitude, longitude, t = None) Calculates the same thing as @code{solar_elevation_from_time}, except the time is optional and defaults to the current time. @end table For all functions beneath @code{degrees}, @code{t} is the time in Julian Centuries. All parameters are floating point and may not be @code{None}, except for in @code{solar_elevation}, as specified. Blueshift provides constants with important elevations of the Sun during twilight. @table @code @item SOLAR_ELEVATION_SUNSET_SUNRISE The Sun's elevation at sunset and sunrise, measured in degrees. @item SOLAR_ELEVATION_CIVIL_DUSK_DAWN The Sun's elevation at civil dusk and civil dawn, measured in degrees. @item SOLAR_ELEVATION_NAUTICAL_DUSK_DAWN The Sun's elevation at nautical dusk and nautical dawn, measured in degrees. @item SOLAR_ELEVATION_ASTRONOMICAL_DUSK_DAWN The Sun's elevation at astronomical dusk and astronomical dawn, measured in degrees. @item SOLAR_ELEVATION_RANGE_TWILIGHT The Sun's lowest and highest elevation during all periods of twilight, measured in degrees. @item SOLAR_ELEVATION_RANGE_CIVIL_TWILIGHT The Sun's lowest and highest elevation during civil twilight, measured in degrees. @item SOLAR_ELEVATION_RANGE_NAUTICAL_TWILIGHT The Sun's lowest and highest elevation during nautical twilight, measured in degrees. @item SOLAR_ELEVATION_RANGE_ASTRONOMICAL_TWILIGHT The Sun's lowest and highest elevation during astronomical twilight, measured in degrees. @end table @node Weather @section Weather Blueshift includes the function @code{whether} which gives a brief weather report. @code{whether} takes one argument: the International Civil Aviation Organization (ICAO) code of your closest airport. If Blueshift is unable to download the latest METAR (Meteorological Aerodrome Report) @code{whether} will return @code{None}. If successful it will return the sky conditions (assumed clear if not included in the report,) the visiblity range and the weather. These components are returned as a 3-tuple with the components in the same order as mentioned. The sky condition is returned as a string. And can be either of: `clear', `mostly clear', `partly cloudy', `mostly cloudy', `overcast' and `obscured'. If the visibility range is not included in the report it will be @code{None}; if it is included in the report it will be an int–float-tuple. The first element in the tuple will be either @code{-1}, @code{0} or @code{1}, and the second element will be an approximate visibility range measured in kilometers. If the first element is @code{-1} this measurement is an upper bound, if it it @code{1} the measurement is an lower bound, and if it is @code{0} the measurement is approximate. The weather is reported as an string list, that can and often is empty. @node Running without X @section Running without X Blueshift has the capability of operating, in fullness, without a display server like X. Using Direct Rendering Manager (DRM), in Linux, Blueshift is able to get monitor information and get and set the colour curves for each monitor, just as it is under X using RandR; except this only works if the active VT does not have a display server. There are however a few differences: @itemize @bullet{} @item DRM returns more exact physical monitor dimensions. For example, my CRT:s have a visible area of slightly (off by a millimeter or two) larger than 400 mm by 300 mm, but RandR returns 364 mm by 291 mm which is an aspect ratio of 5:4 rather than 4:3. @item DRM does not have the concept of primary monitors, which RandR has. RandR changes the indices of the CRTC:s so that the primary monitors have zero as their indices. @item DRM does not have a concept of screens, but it does have the concept of graphic cards which is missing from RandR. In practice, these are however equivalent, and therefore the DRM methods which have a RandR version caps the parameters for graphic cards for @code{screen} rather than @code{card} to maintain API compatibility with the RandR versions. @end itemize Unless your system administator have change the requires permissions of devices in @file{/dev/dri}, you need to be a member of the group @code{video}. Blueshift checks for you whether you are running in a TTY by checking the @var{DISPLAY} environment variable, and sets the variable @code{ttymode}. That is Blueshift will set the variable @code{ttymode} to @code{True} if it thinks that it is not connected to a display server, and @code{False} otherwise. Not that it is still possible to use the DRM functions when connected to a display server: nothing will happen because, all requests to change the colour curves will be rejected. However if you switch VT to a TTY, the requests will be accepted and the requests to the display server will be ignored until you reenter the VT with that display. The DRM equivalent to the RandR functions @code{randr} (applying colour curves) and @code{randr_get} (reading current colour curves) are @code{drm} and @code{drm_get}, respectively. The paramers are exactly the same for the DRM functions as they are for the RandR functions. The function @code{list_screens}, which lists all screens, CRTC:s and outputs, runs @code{list_screens_randr} by default. By invoking @code{list_screens} with the argument `drm' it will instead run @code{list_screens_drm}. It will return equivalent data, except with it calls screens are actually graphics cards, and as mentioned, the CRTC:s may have different indices and the monitors may have different physical sizes. But the names of the outputs (which are called connectors in DRM contected, but for this function it will still be called outputs for API compatibility with the RandR version) by be different. @node Optimising @section Optimising If you have adjustments that reused, perhaps between adjustments or shared between monitors. You can reduce the amount of calculates your script needs to do my reusing made adjustments. To snapshot the current state of the working colour curves (those that are not applied yet) you can use the function @code{store}. It is parameterless and returns a 3-tuple of the colour curves. To reset the to curves stored by @code{store} you can use the function @code{restore}: @example stored = store() # To stuff ... restore(stored) @end example You can also make a function of the stored settings. A function like this will apply the adjustments on top of current adjustments. To do this input the output of @code{store} into the function @code{functionise}: @example brightness(0.75) stored = functionise(store()) stored() stored() # Now the brightness is 0,75 to the power of 3 = 0,421875. @end example Note that the @code{functionise(stored)()} might be heavier than applying the adjustments by invoking them. @node Configuration examples @chapter Configuration examples The Blueshift packages comes with a set of example configuration scripts. These are installed to @file{@value{DOCDIR}/@value{PKGNAME}/examples}. These examples include: @table @file @item backlight This example demonstrates how to use adjust backlight without interfering to much with manual adjustments. The example with oscillate the backlight between 50 % and 100 % but include any manual adjustments. @item battery This is a small example that inverts the colours when the battery's capacity is low. It includes very little from the configuration API but uses Linux's sysfs to determine the battery's capacity an charging status. @item comprehensive This example includes most of Blueshift's features and lets you use them very generically. It does include all basic features of Blueshift. @item crtc-detection This is a small example that identifies which monitors you have plugged in to the computer, and applied their proper calibration. @item crtc-searching This example uses option parsing and CRTC searching. @command{Screens.find_by_crtc} and @command{Screen.find_by_crtc}, are not used, those are not useful for anything. They can be used for seaching the number of connected monitors, but @command{Screen.crtc_count} is much more effective. @item current-settings This is a small example demonstrates how the currents settings can be read and transitioned from. @item darkroom This is a samll example inverts the colours and then makes the monitors red and dim. It is exited by running again with Blueshift's @option{-r} (@option{--reset}) option. @item icc-profile-atoms This is a tiny example that demonstrates how to read and use the @var{_ICC_PROFILE(_n)} atoms for X screens. @c @item lisp-esque @c @itemx lisp-esque.conf @item logarithmic A very small example that uses free function modifier and temporary curve linearisation to make the colour curves logarithmic. @item modes This example can be used to name a mode you want to use, without having to use Blueshift's @option{-c} option and give a pathname. You will only need to give a filename. In this example, those modes are installed in the directory @file{$@var{XDG_CONFIG_HOME}/blueshift-modes}, and the default mode is named @file{default}. @item sleepmode This example graciously fades out the screen on start and in on exit. It is a nice alternative to turning off the monitor, just press @kbd{Control+c} when you wake up. @item stored-settings This example demonstrates how settings can be stored and be transition from later. @item textconf @itemx textconf.conf This example uses a text based configuration file to make it easier for non-programmers to use Blueshift. It will read a file with the same pathname just with @file{.conf} appended (@file{textconf.conf} in this case.) However, if the filename of this file ends with with @file{rc}, that part will be removed, for example, if you rename this script to @file{~/.blueshiftrc} it will read @file{~/.blueshift.conf} rather than @file{~/.blueshiftrc.conf}. @item threaded This is an example demonstrates how you can make a multithreaded configurations script. @item weather This is a samll example demonstrates how to include weather conditions in your configuration scripts. @item xmobar This example can be used in @command{xmobar} to display the Sun's elevation and to what degree it is day time. @item xmonad This configuration scripts read the @command{xmonad} log to detect which workspace you are viewing. It can also disable adjustments when you are in selected programs such as The GIMP and Inkscape. @item xpybar This example can be used in @command{xpybar} to display the Sun's elevation and to what degree it is day time. @end table @node Related software @chapter Related software @command{blueshift} by itself have a wide range of feature, but it can be extended further by additional software: @table @command @item blueshift-tray A wrapper for Blueshift that makes it easy to temporarily activate and deactivate Blueshift by placing it in the X system tray. @item blueshift-curse (Under development)@* @command{blueshift-curse} is an extension for Blueshift that can be used by configuration scripts to make it possible for other applications, included an ncurses interface that comes with it, to do modifications to the configurations. @command{blueshift-curse} uses domain sockets for interprocess communication. @item blueshift-vt-cues (Development planned)@* @command{blueshift-vt-cues} is an extension for Blueshift that, with the support of a daemon, can listen for virtual terminal (VT) switching events. @command{blueshift-vt-cues} uses domain sockets for interprocess communication between the daemons and users. It provides information about the currently active VT such as VT number, wich user has ownership of the VT and either it is a text (or framebuffer) session or a graphical session (such as X, Wayland and Mir.) @command{blueshift-vt-cues} also provides the capability of informing the Blueshift configuration scripts whether or not they should reset the the adjustments to make sure that one user's adjustments does not interfere with another user's adjustments. @end table If you want to extend the capabilities of Blueshift for your configuration scripts there are some library packages that can be of particular interest: @table @command @item python3-xlib X library for Python based on the Xlib library. @item xpyb (Not ported to Python 3)@* X library for Python based on the XCB library. @item xpybutil (Not ported to Python 3)@* A Python rendition of xcb-util including EWMH, ICCCM, key binding, Xinerama, &c. @item ooxcb (Not ported to Python 3)@* An object-oriented X library for Python based on xpyb. @item pygtk (Not ported to Python 3)@* GTK+ 2 bindings for Python. @item python-gobject GTK+ 3 bindings for Python. @item python2-geoclue (Not ported to Python 3)@* GeoClue library for Python, can be used to get your geographical position. GeoClue uses D-Bus, and can use multiple position providers: @itemize @bullet{} @item GPS: Position information from a Global Positioning System receiver via @command{gpsd} and @command{gypsy}. @item GSM: Position information from cellular network connection. @item Plazes: Position information from the Plazes Wi-Fi location service. @item Hostip: Position information based on IP address. @item Manual: User-provided position information. @end itemize @item python-dbus Python bindings for D-Bus. @item python-networkmanager Python interface to NetworkManager. @item locateme (Under development)@* A command to get your geographical position. @end table @node Terminology @chapter Terminology Terminology related to Blueshift: @table @asis @item Ad-hoc mode @itemx One time mode Running Blueshift without a configuration script. @item Configuration mode Running Blueshift with a configuration script. @item Configuration script Blueshift provides a mechanism for adjusting colours on the monitors. Configuration scripts, invoked by Blueshift, implements the policy for doing so. @item Continuous mode Running Blueshift such at it applies adjustments but than continues to run and applies now (time dependent) adjustments every now and then until the user terminates Blueshift. @item One shot mode Running Blueshift such at it applies adjustments and than exits. @item Panicgate Applying adjustments immediately without transitioning. This terminology is borrowed from OpenNTPD. @item High day @itemx Day @itemx Daytime The time during the day when the Sun elevated to be 100 % visible. The time between sunrise and sunset; when it is full daylight. @item High night @itemx Night @itemx Nighttime The time during the day when the Sun elevated to be 0 % visible. The time between dusk and dawn; when it is complete darkness. @end table @node GNU Free Documentation License @appendix GNU Free Documentation License @include fdl.texinfo @bye