gamma

package
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 9, 2020 License: GPL-3.0, GPL-3.0-or-later Imports: 6 Imported by: 0

Documentation

Overview

Package gamma provides a completely hardware-independent interface for querying and programming the CRTC lookup tables in terms of simple, real-number functions. This can be used to dim the screen, change its gamma compensation, change its color temperature, invert its colors, or increase its contrast, among other things.

(With the package gamma/animate, part of the same module, you can do all of that continuously over time.)

This package depends on the XRandR extension to X11 and requires its headers to build.

Nomenclature

CRTCs are "cathode ray tube controllers." Despite the name, they're still a part of modern-day display controllers.

There's a nonlinear relationship between a CRT's electron gun voltage and its display brightness, and this relationship may vary from tube to tube and even from channel to channel within a tube. The power-law function that approximates this nonlinear relationship is called the CRT's "gamma." To compensate for gammas that differed between tubes and between channels, CRTCs were equipped with per-channel lookup tables that could be programmed with the inverse of the monitor's gamma function, providing a virtually linear relationship between the colors expressed in software and the colors displayed on the screen.

Today, CRT displays are increasingly rare, and the LCDs that have displaced them are smart enough to correct for their nonlinearities themselves. Nevertheless, the original CRTC lookup tables persist, since they provide a convenient, generic, and ubiquitous target for color correction and color temperature adjustments. Although these are no longer strictly "gamma" functions, the nomenclature has stuck around, since it's short and matches code and documentation that was written back when gamma was the principal concern.

Example
package main

import (
	"github.com/branen/go-xrr-gamma/gamma"
	"log"
)

func main() {
	var (
		cl  *gamma.Client
		s   *gamma.Session
		err error
	)
	if cl, err = gamma.NewClient(); err != nil {
		log.Fatal(err)
	}
	defer cl.Close()
	if s, err = cl.NewSession(); err != nil {
		log.Fatal(err)
	}
	defer s.Close()
	s.SetGamma(gamma.IdentityFn())
}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Channel

type Channel int

Channel specifies a primary additive color channel.

const (
	Red Channel = iota
	Green
	Blue
)

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client represents a thread-safe, persistent connection to the XRandR extension. For most applications, one client may be cached for the lifetime of a process.

Client instances must be created by NewClient--its zero value is not valid for use.

func NewClient

func NewClient() (cl *Client, err error)

func (*Client) Close

func (cl *Client) Close()

Close "closes" a Client, releasing its underlying resources. Once a Client has been closed, it may not be used again.

Calling Close more than once is a no-op.

func (*Client) Closed

func (cl *Client) Closed() bool

func (*Client) NewSession

func (cl *Client) NewSession() (s *Session, err error)

type LookupTable

type LookupTable struct {
	// contains filtered or unexported fields
}

LookupTable represents the state of the CRTC lookup tables at some point in time. Once created, a LookupTable instance does not refer to the underlying resources from which it was derived, so its lifespan may exceed that of the session from which it was created.

func (LookupTable) Equals

func (lt LookupTable) Equals(o LookupTable) bool

Equals compares two LookupTable instances and returns true if their values and topology are the same. This can be used to detect gamma updates by other processes (e.g. redshift).

func (LookupTable) IsZero

func (lt LookupTable) IsZero() bool

IsZero returns true if a LookupTable is the zero value.

func (LookupTable) XferFn

func (lt LookupTable) XferFn() XferFn

XferFn constructs an XferFn instance from a LookupTable using linear interpolation.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session represents a "transaction" with the XRandR extension.

Specifically, a Session corresponds to an underlying XRRScreenResources instance, which may become stale when displays are hotplugged. Accordingly, a Session should live no longer than is required to perform one or more closely consecutive calls to SetGamma. If the spacing between calls is long enough to complete a call to NewSession (i.e. hundreds of milliseconds), then separate sessions should be used.

Session instances must be created by NewSession--its zero value is not valid for use.

func (*Session) Close

func (s *Session) Close()

Close "closes" a Session, releasing its underlying resources. Once a Session has been closed, it may not be used again.

Calling Close more than once is a no-op.

func (*Session) Closed

func (s *Session) Closed() bool

func (*Session) GetLookupTable

func (s *Session) GetLookupTable() (LookupTable, error)

GetLookupTable saves the current gamma lookup tables.

NOTE: The non-primary CRTCs don't always read back correctly on some systems, so for the time being, GetLookupTable ignores all but the primary CRTC. This is subject to change in a future minor release.

func (*Session) SetGamma

func (s *Session) SetGamma(fn XferFn)

SetGamma programs the CRTCs gamma lookup tables using an XferFn.

type XferFn

type XferFn func(ch Channel, in float64) (out float64)

XferFn specifies a function that maps all values in [0.0, 0.1] to some values in [0.0, 0.1] for each Channel Red, Green, and Blue, but which needn't necessarily be continuous or unique.

(In other words, f ∈ F(ℝ, ℝ), and 0 ≤ f(x) ≤ 1 for all x where 0 ≤ x ≤ 1.)

Example
var invert, red, dim XferFn
invert = func(ch Channel, in float64) (out float64) {
	return 1 - in
}
red = func(ch Channel, in float64) (out float64) {
	if ch != Red {
		return 0
	}
	return in
}
dim = func(ch Channel, in float64) (out float64) {
	return in / 2
}
fmt.Printf("%01.1f\n", invert(Red, 0.8))
fmt.Printf("%01.1f\n", red(Green, 0.8))
fmt.Printf("%01.1f\n", dim(Blue, 0.8))
Output:

0.2
0.0
0.4

func DimFn

func DimFn(coef float64) XferFn

DimFn returns the XferFn f(ch, in) = coef * in.

func IdentityFn added in v0.1.3

func IdentityFn() XferFn

IdentityFn returns the XferFn f(ch, in) = in.

func PowerFn

func PowerFn(exp float64) XferFn

PowerFn returns the XferFn f(ch, in) = math.Pow(in, exp). In the context of traditional CRT gamma correction, exp is the "gamma correction value."

func (XferFn) Chain

func (a XferFn) Chain(b XferFn) XferFn

Chain combines two XferFns a and b such that a.Chain(b)(x) = b(a(x)).

func (XferFn) Mul

func (a XferFn) Mul(b XferFn) XferFn

Mul combines two XferFns a and b such that a.Mul(b)(x) = a(x) * b(x).

Directories

Path Synopsis
Package animate provides type XferFnAtTime and function Animate, which comprise a simple framework for building and running animated and event-responsive gamma transitions.
Package animate provides type XferFnAtTime and function Animate, which comprise a simple framework for building and running animated and event-responsive gamma transitions.
alert
Package alert provides Xft, an event-responsive animate.XferFnAtTime that turns the screen a soft red; two emphasis events (one gentle, one bold); and an exit event that causes the animation to fade out smoothly.
Package alert provides Xft, an event-responsive animate.XferFnAtTime that turns the screen a soft red; two emphasis events (one gentle, one bold); and an exit event that causes the animation to fade out smoothly.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL