; -*- lisp -*-
; The line above sets the editors to LISP mode, which probably
; is the mode with best syntax highlighting for this file.
; This configuration file requires the LISP-esque example
; configuration scripts


; Copyright © 2014  Mattias Andrée (maandree@member.fsf.org)
; 
; 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, no Front-Cover Texts, and no Back-Cover Texts.
; You should have received a copy of the GNU General Public License
; along with this software package.  If not, see <http://www.gnu.org/licenses/>.


; Both ; (semicolon) and # (pound) start commands ending the end of the line

; If you know LISP, you might find this to be a bit different,
; it is only superficially like LISP. Anthing it is inside brackets
; is a list of strings. A string starting with a colon is a function
; call with next string being its argument, or the next list being
; its arguments. The first string in a list may or may not be function
; call, depending on situation; it can be first not to be bit adding
; a dot the string before it, the first string is ignored if it is a dot.
; Quotes have no effect other than cancelling out the effect of whitespace.


(blueshift
	; Indices of monitors to use.
	(monitors) ; For all monitors
	;    For the primary monitor:                       (monitors 0)
	;    For the first two monitors:                    (monitors 0 1)
	;    For the primary on the screen 0 and screen 1:  (monitors 0:0 1:0)
	;    For all monitors on screen 0:                  (monitors 0:)
	;    For monitors with output name DVI-0:           (monitors :crtc "DVI-0")
	;    For monitors with output name DVI-0 or VGA-0:  (monitors :crtc ("DVI-0" "VGA-0"))
	;    For monitors with size 364 mm × 291 mm:        (monitors :size (364 291))
	;    For monitors with EDID xyz:                    (monitors :edid xyz)
	;    If you want :crtc, :size or :edid to add an exact number of monitors
	;    (non-found will monitors be skipped when it is time to use them)
	;    you can use :crtc:n, :size:n and :edid, where n is the number of monitors.
	
	
	; Geographical coodinates: latitude longitude (northwards and eastwards in degrees)
	(coordinates 59.3326, 18.0652)
	;    If you have this store in ~/.location you can use
	;        (coordinates :parse (read "~/.location"))
	;    If the command `~/.location` prints the information you can use
	;        (coordinates :parse (spawn "~/.location"))
	;        Or if you want to the location to be updates continuously:
	;            (coordinates:cont :parse (spawn "~/.location"))
	;    You can also store the text "(coordinates 59.3472 18.0728)" in
	;    file named ~/.location:
	;        :include "~/.location"
	;    A more advance alternative is to have a Python file named "~/.location.py"
	;    that is parsed and have its function `location` invoked with not arguments:
	;        (source "~/.location.py")
	;        (coordinates :eval "location()")
	;        If location can continuously update your location you can use:
	;            (source "~/.location.py")
	;            (coordinates:cont :eval location)
	;    You can combine having a static location and continuously updating,
	;    which allows Blueshift to use the static location if the dynamic cannot
	;    be fetch when Blueshift starts:
	;        (coordinates 59.3472 18.0728)
	;        (coordinates:cont :parse (spawn "~/.location"))
	
	; Time points when different settings are applied, continuous transition
	; betweem them will be used. This are not used by default, be can be
	; enabled in the next section.
	(timepoints 2:00 8:00 22:00)
	
	; Select method for calculating the time the different settings are (fully) applied
	(points solar)
        ;    Use the two default solar elevations
	; (points solar :eval SOLAR_ELEVATION_ASTRONOMICAL_DUSK_DAWN :eval SOLAR_ELEVATION_SUNSET_SUNRISE)
	;    Use two standard solar elevations
	; (points solar -18 -12 -6 0 6)
	;    Use four custom solar elevations
	; (points time)
	;    Use the time points from (timepoints) (from the previous section)
	; (points constant)
	;    Assume it 100 % are day long, and exit when settings have been applied.
	;    (One shot mode instead of continuous mode)
	
	; If you have multiple values in (points) they can be reduced to two:
	; (dayness 0 1 1)
	; For example, if we have (points time) and (timepoints 2:00 8:00 22:00)
	; than (dayness 0 1 1) will reduce it so that the settings only have to
	; define values for day and night (in that order). At 2:00 it would be
	; 100 % night, and at 8:00 to 22:00 it would be 100 % day.
	
	
	; Colour curve applying method.
	(method randr) ### --- MODERATE LEVEL ---
	;    Alternatively (limited to primary monitors):  (method vidmode)
	;    For debugging (or passing to another application) you can use
	;        (method print)
	;    It is possible to use both:
	;        (method print randr)
	;    drm does not exist as an alternative but will be used
	;    automatically under ttymode.
	
	
	(transfrom randr) ; yes, this it says ‘from’ not ‘form’
	; This lets Blueshift transition from the currently applied settings
	; when it starts. If you prefer to use vidmode instead of randr you
	; can use
	;     (transfrom randr)
	; If you do not want to do this you can use
	;     (transfrom nil)
	; It an also be configured individually for the monitors:
	;     (transfrom randr nil)
	;         This will not do this for the second monitor
	; drm does not exist as an alternative but will be used
	; automatically under ttymode.
	
	
	;; Important: The following options are applied in order of appearance
	;;            moving them around can cause inexact monitors calibration
	;;            or other unwanted effects. But it could perhaps also do
	;;            something wonderful.
	
	; ICC profile for video filtering (monitor calibration will be later.)
	; Replace `nil` with the pathname of the profile. It is assumed to not be
	; already applied and it is assumed that it should not be applied on exit.
	#(icc:filter nil) ### --- MODERATE LEVEL ---
	;     If you have three monitors: (icc:filter (nil nil nil))
	;     On all the monitors but time dependent: (icc:filter nil nil)
	;     The two above combined: (icc:filter (nil nil nil) (nil nil nil))
	
	; Negative image settings.
	(negative no)               ; Does nothing
	; (negative yes)            ; Inverts the colours on the encoding axes
	; (negative)                ; Synonym for the above
	; (negative (yes no no))    ; Inverts the red colour on the encoding axis
	; (negative yes no)         ; Inverts the colours on the encoding axes on the first monitor
	;                           ; but not the second monitor selected by (monitors)
	; (invert yes)              ; Inverts the colours on the output axes using the sRGB colour space
	; (invert (yes no no))      ; Inverts the red colour on the output axes using the sRGB colour space
	; (invert:cie yes)          ; Inverts the colours on the output axes using the CIE xyY colour space
	; (invert:cie (yes no no))  ; Inverts the red colour on the output axes using the CIE xyY colour space
	;     These cannot be time dependent.
	
	; Colour temperature at high day and high night, respectively.
	(temperature 6500 3700)
	;    If you the second monitor selected by (monitors) to always be at 6500K you can use
	;        (temperature (6500 6500) (3700 6500))
	;    It is also possible to use (temperature:cie), although its behaviour is probably not
	;    what you are looking for.
	
	### --- EXPERT LEVEL ---
	; If you want a more advance calculation of the correlated colour
	; temperature you can replace (temperature) in the step about with
	; (temperature') and add the following *before* it:
	;     (compose temperature' temperature as-is (divide_by_maximum cmf_10deg))
	;         This is the default, but you can also use for example and of the following:
	;             (compose temperature' temperature as-is (divide_by_maximum series_d))
	;             (compose temperature' temperature as-is (clip_whitepoint simple_whitepoint))
	;             (compose temperature' temperature as-is (divide_by_maximum cmf_2deg))
	;             (compose temperature' temperature as-is redshift')
	;             Where Redshift' needs to be composed before temperature':
	;                 (compose redshift' redshift as-is yes)     ; as in redshift<=1.8
	;                 (compose redshift' redshift as-is no)      ; as in redshift>1.8
	;                 (compose redshift' redshift as-is yes yes) ; as in redshift<=1.8
        ;                                                            ;   but interpolating in linear RGB
	;                 (compose redshift' redshift as-is no yes)  ; as in redshift>1.8
        ;                                                            ;   but interpolating in linear RGB
	;         See `info blueshift 'configuration api' 'colour curve manipulators'`
	;         and look for ‘temperature’ for details.
	
	; It is possible to calibrations that were applied when Blueshift started.
	#(current nil) ### --- EXPERT LEVEL ---
	;    This is ignored if --panicgate is used (it is assumed that Blueshift
	;    crashed if --panicgate is used). It also has no effect in one shot mode.
	;    `nil` means that it does nothing, but you can also use `randr` or
	;    `vidmode`, but `vidmode` is restricted to primary monitors:
	;        (current randr)   ; of using randr
	;        (current vidmode) ; of using vidmode
	;    You can also controll the monitors individually:
	;        (current randr nil) ; does this only for the first monitor
	;    drm does not exist as an alternative but will be used
	;    automatically under ttymode.
	
	; Colour brightness at high day and high night, respectively.
	; This setting uses the CIE xyY colour space for calculating values.
	(brightness:cie 1 1)
	;    If you have multiple monitors, they can be configured indiviudally.
	;    For example if you have two monitors, we can keep the first monitor
	;    on full brightness all day long, but make the second monitor be
	;    at 75 % during the night:
	;        (brightness:cie (1 1) (1 0.75))
	
	; Colour brightness of the red, green and blue components,
	; respectively, at high day and high night, respectively.
	; This settings uses the sRGB colour space for calculating values.
	(brightness (1 1 1) (1 1 1)) ### --- MODERATE LEVEL ---
	;    Because red, green and blue are identical in this example,
	;    writting (brightness 1 1) instead with do the same thing.
	;    If you want the second monitor selected by (monitors) to always
	;    be at 100 % but the primary to shift between 100 % and 75 % you can use
	;        (brightness ((1) (1)) ((1) (0.75)))
	;    As this indicates you use the following if you want only the blue
	;    part to shift to 75 %:
	;        (brightness ((1) (1)) ((1) (0.75 1 1)))
	;     Or alternatively:
	;        (brightness:red (1 1) (1 0.75))
	
	; Colour contrast at high day and high night, respectively.
	; This setting uses the CIE xyY colour space for calculating values.
	#(contrast:cie 1 1) ### --- MODERATE LEVEL ---
	;    This can be done monitors dependently as in (brightness:cie).
	
	; Colour contrast of the red, green and blue components,
	; respectively, at high day and high night, respectively.
	; This settings uses the sRGB colour space for calculating values.
	#(contrast (1 1 1) (1 1 1)) ### --- MODERATE LEVEL ---
	;    Because red, green and blue are identical in this example,
	;    writting (contrast 1 1) instead with do the same thing.
	;    This can be done monitors dependently as in (brightness).
	
	
	;; Note: brightness and contrast is not intended for colour
	;;       calibration, it should be calibrated on the monitors'
	;;       control panels.
	
	
	; These are fun curve manipulator settings that lowers the
	; colour resolution on the encoding and output axes respectively.
	; In this example (resolution:encoding) only has one argument,
	; it applies all day long on each colour curve.
	#(resolution:encoding :eval i_size) ### -- ADVANCED LEVEL --
	;    This is evaluated into:
	;        (resolution:encoding 256)
	; (resolution:output) in this example this one argument that
	; is a tuple of three values which represent red, green, and
	; blue respectively. Because it is only one argument it
	; applies all day long as well.
	#(resolution:output (:eval (o_size o_size o_size))) ### -- ADVANCED LEVEL --
	;    This is evaluated into any of:
	;        (resolution:output (65536 65536 65536))
	;        (resolution:output (eval o_size o_size o_size))
	;    As always you can control the monitors individually:
	;        (resolution:output (:eval ((o_size o_size o_size) (o_size o_size o_size))))
	;        This evaluated into:
	;            (resolution:output ((65536 65536 65536) (65536 65536 65536)))
	
	; Gamma correction for the red, green and blue components, respectively,
	; at high day, high night and monitor default, respectively.
	; This settings uses the sRGB colour space for calculating values.
	#(gamma (1 1 1) (1 1 1)) ### --- MODERATE LEVEL ---
	(gamma:default (1 1 1))
	;    All configurations can use :default, but it only makes since
	;    for gamma because it is the only actual monitors calibration
	;    configurations, with the exception of ICC profiles and white
	;    point and black point calibration and sigmoid curve correction.
	;    (gamma) automatically run (clip) to avoid mathematical errors,
	;    If you prefer not to run (clip) you can use
	;        ('gamma (1 1 1) (1 1 1))
	;        ('gamma:default (1 1 1))
	;    You can also run clip manually:
	;        (clip)
	;        Or for the first but not second monitor:
	;            (clip yes no)
	;        You can also clip individual colour curves:
	;            (clip (yes, no, no) no)
	;                 Clips only the red curve on the primary monitor
	;        Clipping cannot time dependent.
	
	
	;; Note: gamma is supposted to be static, it purpose is to
	;;       correct the colours on the monitors the monitor's gamma
	;;       is exactly 2,2 and the colours look correct in relation
	;;       too each other. It is supported to have different settings
	;;       at day and night because there are no technical limitings
	;;       and it can presumable increase readability on text when
	;;       the colour temperature is low.
	
	
	; If you have an LCD monitor you can use (well you could on CRT as
	; well but it would not make since) sigmoid curve correction to
	; calibrate your monitor. 4.5 is a good value to start testing at,
	; but be aware, it is very difficult to get right is it depens on
	; other calibrations as well. For now we have `nil` which means that
	; no sigmoid curve correction will take place.
	#(sigmoid:default (nil nil nil)) ### -- EXPERT LEVEL --
	;    This three `nil`:s are for red, green and blue respectively,
	;    but you can just one argument instead of a tuple of three, if
	;    the colour curves should have the same sigmoid curve correction.
	;    If you have two monitors you can use (and replace nil with
	;    your correction parameters):
	;        (sigmoid:default (nil nil nil) (nil nil nil))
	;        or
	;        (sigmoid:default nil nil)
	; You can also so time dependent correction:
	#(sigmoid (nil nil nil) (nil nil nil)) ### -- EXPERT LEVEL --
	;    (sigmoid ((nil nil nil) (nil nil nil)) ((nil nil nil) (nil nil nil)))
	;    (sigmoid (nil nil) (nil nil))
	
	; If you have require software level brightness and contract
	; calibration (needed to calibrate most LCD monitors), you and
	; use (limits) and (limits:cie). These will calibrate the
	; black point (brightness) and the white point (contrast). This
	; brightness and contrast is not the same thing as the settings
	; (brightness) and (contrast). (brightness) is more similar to
	; backlight and (contrast) is a flattening of the colour curves
	; towards 50 %. In (limits:cie) and first argument (for each time)
	; is the brightness [black point] and the second is the [white point].
	#(limits:cie:default 0 1) ### -- ADVANCED LEVEL --
	; If you have three monitors they can be controlled individually:
	;    (limits:cie:default (0 1) (0 1) (0 1))
	; You can so also do time dependent correction:
	;    (limits:cie ((0 1) (0 1) (0 1)) ((0 1) (0 1) (0 1)))
	
	; ICC profile for monitor calibration will be later.
	; Replace `nil` with the pathname of the profile. It is assumed to
	; already be applied and that it should be applied on exit.
	#(icc:calib nil) ### -- MODERATE LEVEL --
	;     If you have three monitors: (icc (nil nil nil))
	;     On all the monitors but time dependent: (icc nil nil)
	;     The two above combined: (icc (nil nil nil) (nil nil nil))
	;     (icc) is a synonym for (icc:calib).
	
	### -- EXPERT LEVEL --
	; It is also possible to some of your own manipulations:
	; where is an example that temporary switches to linear RGB
	; change makes the colour curves logarithmical:
	;     (linearise)
	;     (manipulate 'lambda x : math.log(x + 1, 2)')
	;          Or for the colour colurves individually:
	;              (manipulate 'lambda x : math.log(x + 1, 2)'
	;                          'lambda x : math.log(x + 1, 2)'
	;                          'lambda x : math.log(x + 1, 2)' 
	;              )
	;     (standardise)
	; As with (clip) (linearise) and (standardise) can depend
	; on the monitor, so can (manipulate):
	;     (linearise yes no)
	;     (manipulate 'lambda x : math.log(x + 1, 2)')
	;          Or for the colour colurves individually:
	;              (manipulate ('lambda x : math.log(x + 1, 2)'
	;                           'lambda x : math.log(x + 1, 2)'
	;                           'lambda x : math.log(x + 1, 2)'
	;                          )
	;                          nil ; Do nothing on the second monitor
	;              )
	;     (standardise yes no)
	; You can also use (manipulate) on the Y component of the CIE xyY
	; colour space:
	;    (manipulate:cie 'lambda x : math.log(x + 1, 2)'
	;                    nil ; Do nothing on the second monitor
	;    )
)