\input texinfo @c -*-texinfo-*- @c %%**start of header @setfilename libgamma.info @settitle libgamma @afourpaper @documentencoding UTF-8 @documentlanguage en @finalout @c %%**end of header @dircategory Library @direntry * libgamma: (libgamma). Display server abstraction layer for gamma ramp adjustments @end direntry @copying Copyright @copyright{} 2014 Mattias Andr@'ee @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 %>set -u %>cd src/extract %>export PATH=".:../../info:${PATH}" @ifnottex @node Top @top libgamma -- Display server abstraction layer for gamma ramp adjustments @insertcopying @end ifnottex @titlepage @title libgamma @subtitle Display server abstraction layer for gamma ramp adjustments @author by Mattias Andr@'e (maandree) @page @c @center `' @vskip 0pt plus 1filll @insertcopying @end titlepage @contents @menu * Overview:: Brief overview of @command{libgamma}. * Jargon:: The jargon of @command{libgamma}. * Compiling:: Configuring, compiling and installing @command{libgamma}. * Linking:: Linking your software to @command{libgamma}. * API:: @command{libgamma}'s advanced programming interface. * GNU Free Documentation License:: Copying and sharing this manual. @end menu @node Overview @chapter Overview @command{libgamma} is a C library that aims to abstract away the display server when adjusting the colours curves for monitors via gamma ramps, and to be cross-platform. @command{libgamma} have support for the X RandR (Resize and Rotate) extension, the X VidMode extension and under Linux the Direct Rendering Manager which lets software work with graphics outside of graphical environments. Additionally @command{libgamma} have support for Windows Graphics Device Interface (Windows GDI) under Windows and Quartz using CoreGraphics under OS X. However Windows GDI and Quartz/CoreGraphics do not receive first-party testing on their target platforms but do receive first-party testing using a compatibility layer that translates the calls to RandR calls. Neither does @command{libgamma}, currently, receive testing on any of the BSD:s, it is only tested on GNU/Linux. Furthermore @command{libgamma} provides a dummy method that can be used to ignore adjustments and can be controlled from another program to pretend like the environment has changed. This can be used test how well your software handles such events. It can also be configured at runtime to use another adjustment method such as RandR. @node Jargon @chapter Jargon @command{libgamma} uses a small jargon, parts of which is loaned from X.org, and some is commonly used jargon. @table @asis @item adjustment method [libgamma] A combination of the display server and a protocol used to tell to the display server. @item display server [X.org] The program used to display graphical elements to the monitors. In @command{libgamma} we also call the non-graphical environment a display server. @item display [X.org] @itemx site [libgamma] An instance of a display server. Non-graphical environment are only covered by `site'. @item screen [X.org] A group of CRTC:s within a display. @item CRTC @itemx cathode ray tube controller Controller for the output on monitor. Mapping from CRTC:s to encoders is an injection. @item monitor The physical medium used to display text and graphics. @item partition [libgamma] Umbrella term for `screen' and `graphics card'. @item page [libgamma] The desktop workspace or virtual terminal that is displayed on a CRTC. (This jargon is not currently used, but is reserved for future features.) @item output [X.org] A connector and its encoder. @item connector Physical port on the graphics card where a monitor can be plugged in. If and only if the connector is disabled it does not have a port and does not have a CRTC. @item encoder Translation layer between CRTC:s and connectors. @item gamma ramp @itemx colour curve A lookup table that translates an encoded value for a subpixel into its output value. @item subpixel @itemx colour channel One of the three colours that makes up a pixel: red, green or blue. @item gamma ramp size @itemx gamma stops The number of possible values on the encoding axis of a gamma ramp. @end table @node Compiling @chapter Compiling The build @command{libgamma} you will need to run @command{./configure} before you run @command{make}. @file{./configure} is not a configuration script from the GNU build system, rather it is just a simple shell script. Each adjustment method needs selected, if none are selected no adjustment method will be compiled into @command{libgamma}. They can either be selected explicitly and independently or by operating system. @table @option @item --enable-dummy Enables the dummy adjustment method. @item --enable-randr @itemx --linux @itemx --bsd Enables the X RandR extension adjustment method. @item --enable-vidmode @itemx --linux @itemx --bsd Enables the X VidMode extension adjustment method. @item --enable-drm @itemx --linux Enables the Direct Rendering Manager adjustment method. @item --enable-w32gdi @itemx --windows Enables the Windows GDI adjustment method. @item --enable-quartz @itemx --mac-os-x Enables the Quartz/CoreGraphics adjustment method. @item --enable-w32gdi=fake Enables the Windows GDI adjustment method using compatibility layer to either RandR or ``/dev/null'' depending on whether RandR is enabled or not. @item --enable-quartz=fake Enables the Quartz/CoreGraphics adjustment method using a compatibility layer to either RandR or ``/dev/null'' depending on whether RandR is enabled or not. @end table You may prefix anything to `bsd', for example @option{--freebsd} or @option{--openbsd}. Any prefix will be discard, but it may be a good idea incase there will be a difference in the future between the platforms. Developers of @command{libgamma} and developers who use @command{libgamma} for their software may also want to use @option{--debug} which enables extra checks to produce better error reports. Additionally @option{--debug} adds the @option{-Og -g} flags to the C compiler rather than @option{-Ofast}. Developers can also use the developer options instead of @option{--debug}, the adjustment and operating systems. @table @option @item --linux=developer @itemx --developer Enables all adjustment methods, with compatibility layers for Windows GDI and Quartz/CoreGraphics. Also enables @option{--debug}. @item --bsd=developer Enables all adjustment methods, except the Linux Direct Rendering Manager adjustment method, with compatibility layers for Windows GDI and Quartz/CoreGraphics. Also enables @option{--debug}. @item --windows=developer Enables the dummy adjustment method and the Windows GDI adjustment method. Also enables @option{--debug}. @item --mac-os-x=developer Enables the dummy adjustment method and the Quartz/CoreGraphics adjustment method. Also enables @option{--debug}. @end table Configuring with @option{--windows} or @option{--windows=developer} will also add configurations to the make script needed to compile for Windows. @option{--mac-os-x} or @option{--mac-os-x=developer} will do add configurations to the make script needed to compile for OS X. When you have configured @command{libgamma} using @command{./configure} you can compile the library with @command{make}. Straight up @command{make} without additions options should be all you need. But you can also use specify some build rules. @table @option @item default Builds the library, the test and the info manual. @item all Builds the library, the test and manual to all available formats: info, PDF, DVI, PostScript. @item lib Builds the library. @item test Builds the test, which in turns builts the library. @item doc Builds the manual to all available formats: info, PDF, DVI, PostScript. @item info Builds the info manual. @item pdf Builds the PDF manual. @item dvi Builds the DVI manual. @item ps Builds the PostScript manual. @end table You can also use @command{make clean} to remove all compiled files, and @command{make distclean} to remove all compiled files and the files generated by @command{./configure}. To install @command{libgamma} once it is compiled run @command{make install} and then @command{make uninstall} once you want to uninstall the library. When running @command{make install} include the option @option{DESTDIR="$@{pkgdir@}"}, where @file{$@{pkgdir@}} is the directory you want the files to be installed to instead of @file{/}, this could for example be @file{/mnt} where you have mounted another installed operating system or a temporary location used by the package manager. This is also a set of options to specify how the system's file system hierarchy is structured. @table @option @item PREFIX The package path prefix, if you want to install to another root, set @option{DESTDIR} to that root. Defaults to @file{/usr}. @item LIB The library path excluding prefix. Defaults to @file{/lib}. @item INCLUDE The library header path excluding prefix. Defaults to @file{/include}. @item DATA The resource path excluding prefix. Defaults to @file{/share}. @item LIBDIR The library path including prefix. Defaults to @file{$(PREFIX)$(LIB)}. @item INCLUDEDIR The library header including prefix Defaults to @file{$(PREFIX)$(INCLUDE)}. @item DATADIR The resource path including prefix. Defaults to @file{$(PREFIX)$(DATA)}. @item DOCDIR The generic documentation path including prefix. Defaults to @file{$(DATADIR)/doc}. @item INFODIR The info manual documentation path including prefix. Defaults to @file{$(DATADIR)/info}. @item LICENSEDIR The license base path including prefix. Defaults to @file{$(DATADIR)/licenses} @end table There is also an option to specify the package name of the library: @option{PKGNAME}. This only affects the name and location of files installed into @option{DOCDIR}, @option{INFODIR} and @option{LICENSEDIR}. It does not affect the name of the library. For more control on what should be installed, subsitute @option{install} from @command{make install} for one or more of the following rules: @table @option @item install Macro for @option{install-base} and @option{install-info}. Installs everything but only the manual in the info format. @command{install-info} will not be execute the install the manual to the @file{dir} file for @command{info}. @item install-all Macro for @option{install-base} and @option{install-doc}. Installs everything including all available formats of the manual. @command{install-info} will not be execute the install the manual to the @file{dir} file for @command{info}. @item install-base Macro for @option{install-lib}, @option{install-include} and @option{install-copyright}. Installs the library, the headers files for the library so that you can compile other software that uses the library, and the copyright file and the license file. @item install-lib Installs the library, but not its header files. @item install-include Installs the library's header files but not the library itself. @item install-copyright Macro for @option{install-copying}, and @option{install-license}. Installs the copyright file and the license file. @item install-copying Installs the copyright file but not the license file. @item install-license Installs the license file but not the copyright file. @item install-doc Macro for @option{install-info}, @option{install-pdf}, @option{install-ps} and @option{install-dvi}. Installs the manual in all available formats. @command{install-info} will not be execute the install the manual to the @file{dir} file for @command{info}. @item install-info Installs the info manual. @command{install-info} will not be execute the install the manual to the @file{dir} file for @command{info}. @item install-pdf Installs the PDF manual. @item install-ps Installs the PostScript manual. @item install-dvi Installs the DVI manual. @end table @node Linking @chapter Linking When compiling your program use @command{libgamma}, you will not need to do anything for the compiling phase. But for the linking phase, will need to add the option @option{-lgamma}. Currently @command{libgamma}, does not provide a pkg-config file. Keep in mind that @command{libgamma} is GNU General Public License version 3 software for your freedom and for the freedom of all. @node API @chapter API @menu * Adjustment methods:: Selecting adjustment method. * Monitors:: Selecting monitors. * Adjustment method capabilities:: Identifying capabilities of adjustment methods. * CRTC information:: Retrieving information about CRTC:s. * Gamma ramps:: Fetch and manipulating gamma ramps. * Errors:: Error codes and how to handle errors. @end menu To use @command{libgamma} add ``@code{#include }'' to and C file or C header file that requires anything from @command{libgamma}. @file{libgamma.h} is the only header file from @command{libgamma} which should be included directly. Once @file{libgamma.h} is included your program will have access the @command{libgamma}'s API which includes functions, data structures, error codes, and adjustment method identifers. It is highly recommened to add a check for new error codes if your program will be using error codes from @command{libgamma}. This allows you to get a notification if you program is not up to date with new error codes in @command{libgamma}. To do this, @file{libgamma.h} provides the C preprocessor definition @code{LIBGAMMA_ERROR_MIN}; this is the lowest value of that any error code has, all error codes are negative, a new error code is added it will have a lower value that the ones added before it. The first step in adding this check is to figure out what the value of @code{LIBGAMMA_ERROR_MIN} is on your system. To do this, use the @command{cpp} program, it should be included with your C compiler. @example cpp < LIBGAMMA_ERROR_MIN EOF @end example The next step is to add some C preprocessor directives to one of your C files that includes @file{libgamma.h}. @example #if LIBGAMMA_ERROR_MIN < -10 # warning New error codes have been added to libgamma. #endif @end example In this example, we assume that output of the first step was `-10', which it really was not. So if you use this in your program you should receive a warning until you update the value. In a similar manner, you should all a check to detect when the value of either @code{GAMMA_METHOD_MAX} or @code{GAMMA_METHOD_COUNT} (the latter will have value of one higher than the earlier) have increased. This will allow you to get a warning for when new adjustment method have been added so you can take appropriate actions if required. @command{libgamma} does not only provide display server abstract, it optionally lets you choose any available method you want despite of what display server you are used. You may also want to add checks for update to @code{LIBGAMMA_CONNECTOR_TYPE_COUNT}, @code{LIBGAMMA_SUBPIXEL_ORDER_COUNT} and @code{LIBGAMMA_CRTC_INFO_COUNT}. @node Adjustment methods @section Adjustment methods @command{libgamma} is an abstraction layer that lets you select which display server and protocol --- together called adjustment method --- it should use to work with the monitors' gamma ramps. Supported adjustment method, even if excluded at compile-time are identfier by numerical values. @table @code %>for method in $(libgamma-method-extract --list --method); do @item %{method} %>libgamma-method-extract --method $method | texise %>done @end table You can test whether an adjustment method is available with the function @code{libgamma_is_method_available}. It takes the adjustment method's identifer as its only argument, and returns an @code{int}. The returned value is non-zero if and only if the adjustment exists and is available. A more flexible more but advanced function, that you probably want to use instead, is @code{libgamma_list_methods}. It lists all List available adjustment methods by their order of preference based on the environment, and can filter its output. This function takes three arguments: @table @asis @item @code{methods} [@code{int*}] Output array of adjustment method identifiers. It should be able to hold @code{LIBGAMMA_METHOD_COUNT} elements. @item @code{buf_size} [@code{size_t}] The number of elements that fits in @code{methods}, it should be @code{LIBGAMMA_METHOD_COUNT}, This is used to avoid writing outside the output buffer if this library adds new adjustment methods without the users of the library recompiling. @item @code{operation} [@code{int}] Describes what adjustment methods to include. There are five valid values for this parameter, all other values invoke undefined behaviour. @table @code @item 0 Adjustment methods that the environment suggests will work, excluding fake Adjustment methods. @item 1 Adjustment methods that the environment suggests will work, including fake Adjustment methods. @item 2 All real non-fake adjustment methods. @item 3 All real adjustment methods. @item 4 All adjustment methods. @end table @end table @code{libgamma_list_methods} returns an @code{size_t} with the value of how many adjustment method that should have been stored in the parameter @code{methods} if were @code{buf_size}. This value is how many value that have been stored in @code{methods} if @code{buf_size} is large enough. @node Monitors @section Monitors @menu * Site:: Display sites. * Partition:: Display partitions. * CRTC:: Display outputs. @end menu @command{libgamma} have a three level hierarchy for addressing monitors. These levels are: @table @asis @item Sites %>libgamma-method-extract --doc --site-t | behead 2 | texise @item Partitions %>libgamma-method-extract --doc --part-t | behead 2 | texise @item CRTC:s (cathode ray tube controllers) @footnote{Do not be fooled by the legacy name, they are general video controllers.} %>libgamma-method-extract --doc --crtc-t | behead 2 | texise @end table @command{libgamma} keeps tracks of these layers' states, because of this there are one state data structure per layer that also identifies the instance of the layer. @node Site @subsection Site The state and identity of the site is track by the data structure @code{libgamma_site_state_t} @footnote{@code{struct libgamma_site_state}}. This structure contains the following variables: @table @asis %>for site in $(libgamma-method-extract --list --site-t); do @item @code{%{site}} [@code{%(libgamma-method-extract --type --site-t $site)}] %>libgamma-method-extract --site-t $site | texise | sed -e 's/"/``/1' | sed -e 's/"/'\'\''/' %>done @end table To select a site and initialise its state call the function @code{libgamma_site_initialise}. It returns zero on success, and and negative @code{int} on failure. If the return is negative, it is a @code{libgamma} error code; these are listed in @ref{Errors}. For input @code{libgamma_site_initialise} takes three arguments: @table @asis @item @code{this} [@code{libgamma_site_state_t*}] The site state to initialise. @item @code{method} [@code{int}] The adjustment method (display server and protocol), these are listed in @ref{Adjustment methods}. @item @code{site} [@code{char*}] The site identifier, unless it is @code{NULL} it must a @code{free}:able. One the state is destroyed the library will attempt to free it. There you should not free it yourself, and it must not be a string constant or allocated on the stack. Note however that it will not be @code{free}:d if this function fails. The name of the default site can be fetched with the function @code{libgamma_method_default_site}. It takes the value of @code{method} as its only argument and returns the default site's name. The returned value may be @code{NULL}, and the value should not be @code{free}:d. Because it should not be @code{free}:d you should duplicate it with @code{strdup} if it is not @code{NULL}. This value is @code{NULL} if the default site cannot be determined or if the adjustment method only supports one site. The function @code{libgamma_method_default_site_variable} works identically is @code{libgamma_method_default_site} except it returns the name of the environment variable that is read by @code{libgamma_method_default_site} to determine the default site for the adjustment method. @end table To release all resources held by a site state, call the function @code{libgamma_site_destroy}, whose only parameter is the site state to destroy. It does not return any value, and is always successful assuming that the site is valid and properly initialised. If you also want to free the allocation for the site state itself call the function @code{libgamma_site_free} instead. These two functions are identical with the exception that the latter also performs a @code{free} call for the state. @node Partition @subsection Partition The state and identity of the partition is track by the data structure @code{libgamma_partition_state_t} @footnote{@code{struct libgamma_partition_state}}. This structure contains the following variables: @table @asis %>for part in $(libgamma-method-extract --list --part-t); do @item @code{%{part}} [@code{%(libgamma-method-extract --type --part-t $part)}] %>libgamma-method-extract --part-t $part | texise %>done @end table To select a partition and initialise its state call the function @code{libgamma_partition_initialise}. It returns zero on success, and and negative @code{int} on failure. If the return is negative, it is a @code{libgamma} error code; these are listed in @ref{Errors}. For input @code{libgamma_partition_initialise} takes three arguments: @table @asis @item @code{this} [@code{libgamma_partition_state_t*}] The partition state to initialise. @item @code{site} [@code{libgamma_site_state_t*}] The site state for the site that the partition belongs to. @item @code{partition} [@code{size_t}] The the index of the partition within the site. @end table To release all resources held by a partition state, call the function @code{libgamma_partition_destroy}, whose only parameter is the partition state to destroy. It does not return any value, and is always successful assuming that the partition is valid and properly initialised. If you also want to free the allocation for the partition state itself call the function @code{libgamma_partition_free} instead. These two functions are identical with the exception that the latter also performs a @code{free} call for the state. @node CRTC @subsection CRTC The state and identity of the partition is track by the data structure @code{libgamma_crtc_state_t} @footnote{@code{struct libgamma_crtc_state}}. This structure contains the following variables: @table @asis %>for crtc in $(libgamma-method-extract --list --crtc-t); do @item @code{%{crtc}} [@code{%(libgamma-method-extract --type --crtc-t crtc)}] %>libgamma-method-extract --crtc-t $crtc | texise %>done @end table To select a CRTC and initialise its state call the function @code{libgamma_crtc_initialise}. It returns zero on success, and and negative @code{int} on failure. If the return is negative, it is a @code{libgamma} error code; these are listed in @ref{Errors}. For input @code{libgamma_crtc_initialise} takes three arguments: @table @asis @item @code{this} [@code{libgamma_crtc_state_t*}] The CRTC state to initialise. @item @code{partition} [@code{libgamma_partition_state_t*}] The partition state for the partition that the CRTC belongs to. @item @code{crtc} [@code{size_t}] The the index of the CRTC within the partition. Be aware that adjustment methods do not necessarily order than CRTC:s in the same way. For example, display environment may order the CRTC:s so that the primary monitors has the CRTC with index 0; but cannot be done if there is no concept of primary monitors, such as the case of the Linux TTY and the Linux Direct Rendering Manager adjustment method. @end table To release all resources held by a CRTC state, call the function @code{libgamma_crtc_destroy}, whose only parameter is the CRTC state to destroy. It does not return any value, and is always successful assuming that the CRTC is valid and properly initialised. If you also want to free the allocation for the CRTC state itself call the function @code{libgamma_crtc_free} instead. These two functions are identical with the exception that the latter also performs a @code{free} call for the state. @node Adjustment method capabilities @section Adjustment method capabilities Adjustment methods have different capabilities. Because of this, you will probably want to know at least some this the capabilities of the adjustment method that you are using. This can be used to filter out unimportant information for the user. The function @code{libgamma_method_capabilities}, which does not return anything, can be used to get an adjustment methods capabilities. This function takes two arguments. The first argument is a @code{libgamma_method_capabilities_t*} that will be filled with this information, and the second argument is an @code{int} whose value should be the adjument method's identifier. @code{libgamma_method_capabilities_t} @footnote{@code{struct libgamma_method_capabilities}} is a data structure with the following variables: @table @asis %>for cap in $(libgamma-method-extract --list --cap-t); do @item @code{%{cap}} [@code{%(libgamma-method-extract --type --cap-t $cap)}] %>libgamma-method-extract --cap-t $cap | texise %>if [ $cap = crtc_information ]; then See @ref{CRTC information} for more information. %>fi %>done @end table @node CRTC information @section CRTC information It is possible query information about a CRTC using the function @code{libgamma_get_crtc_information}. This function returns an @code{int} whose value is zero on success and @code{-1} if at least on of the requested informations about the CRTC could not successfully be read. This function takes three arguments: @table @asis @item @code{this} [@code{libgamma_crtc_information_t*}] Instance of a data structure to fill with the information about the CRTC. @item @code{crtc} [@code{libgamma_crtc_state_t*}] The state of the CRTC whose information should be read. @item @code{fields} [@code{int32_t}] OR:ed identifiers for the information about the CRTC that should be read. @end table The valid values that can be OR:ed for the @code{fields} parameters are: @table @code %>for info in $(libgamma-method-extract --list --info); do @item %{info} %>libgamma-method-extract --info $info | texise %>done @end table @code{libgamma_crtc_information_t} @footnote{@code{struct libgamma_crtc_information}}, which is the data structure that the read information is stored in, contains the following variables: @table @asis %>for info in $(libgamma-method-extract --list --info-t); do @item @code{%{info}} [@code{%(libgamma-method-extract --type --info-t $info)}] %>libgamma-method-extract --info-t $info | texise %>done @end table The data type for the variable @code{subpixel_order} is @code{libgamma_subpixel_order_t} @footnote{@code{enum libgamma_subpixel_order}}. Its possible values are: @table @code %>for order in $(libgamma-method-extract --list --subpixel); do @item %{order} %>libgamma-method-extract --subpixel $order | texise %>done @end table The data type for the variable @code{connector_type} is @code{libgamma_connector_type_t} @footnote{@code{enum libgamma_connector_type}}. Its possible values are: @table @code %>for type in $(libgamma-method-extract --list --connector); do @item %{type} %>libgamma-method-extract --connector $type | texise %>done @end table The variable @code{edid} is in raw format. To convert it to a human-readable format you should convert it to hexadecimal representation. To do this, you can call either of the functions @table @code @item libgamma_behex_edid @itemx libgamma_behex_edid_lowercase Converts to lowercase hexadecimal. @item libgamma_behex_edid_uppercase Converts to uppercase hexadecimal. @end table These functions return the EDID as a hexadecimal NUL-terminated non-@code{NULL} string of the data type @code{char*}, which you should free when you do not need it anymore. If enough memory cannot be allocated @code{NULL} is returned and @code{errno} is set accordingly. These functions take two arguments: @table @asis @item @code{edid} [@code{const unsigned char*}] The EDID in raw representation. @item @code{length} [@code{size_t}] The length of @code{edid}. @end table The values of these arguments should be the values of the variables @code{edid} and @code{edid_length}, respectively. If you want to identify a monitor by it's EDID@footnote{EDID:s should be unique and even if the manufacture for the monitor has not made sure if this it is very unlikely that it is not.} it is more effective to convert the EDID you want to raw format and compare the raw format rather than converting all monitors EDID to hexadecimal representation. To do this use the function @code{libgamma_unhex_edid}. This function takes the EDID in NUL-terminated non-@code{NULL} hexadecimal representation as a @code{const char*} as its only argument. The function returns the EDID in raw format as an @code{unsigned char*}. The returned value will be @code{NULL} if enough memory for the output cannot be allocated or if the input is a hexadecimal representation of a byte array; @code{errno} will be set accordingly. To release resources that are held by a @code{libgamma_crtc_information_t*} whose variables have been set by @code{libgamma_get_crtc_information} call the function @code{libgamma_crtc_information_destroy} with that @code{libgamma_crtc_information_t} as its only argument. If you also want to release the allocation if the @code{libgamma_crtc_information_t*} itself call the function @code{libgamma_crtc_information_free} instead. @node Gamma ramps @section Gamma ramps @command{libgamma} has support for 5 different gamma ramps structures: 16-bit depth, 32-bit depth, 64-bit depth, single precision floating point, and double precision floating point. For best performance, you should select the one that the adjustment method uses. If you choose a type other than what the adjustment method uses, it will be converted. @table @asis @item @code{libgamma_gamma_ramps8_t} (@code{struct libgamma_gamma_ramps8}) 8-bit integer (@code{uint8_t}). Currently no adjustment method. @item @code{libgamma_gamma_ramps16_t} (@code{struct libgamma_gamma_ramps16}) 16-bit integer (@code{uint16_t}). This is by far the most common. @item @code{libgamma_gamma_ramps32_t} (@code{struct libgamma_gamma_ramps32}) 32-bit integer (@code{uint32_t}). Currently no adjustment method. @item @code{libgamma_gamma_ramps64_t} (@code{struct libgamma_gamma_ramps64}) 64-bit integer (@code{uint64_t}). Currently no adjustment method. @item @code{libgamma_gamma_rampsf_t} (@code{struct libgamma_gamma_rampsf}) Single precision floating point (@code{float}). Currently this is only used by the Quartz/CoreGraphics adjustment method. @item @code{libgamma_gamma_rampsd_t} (@code{struct libgamma_gamma_rampsd}) Double precision floating point (@code{double}). Currently no adjustment method. @end table These structures are very similar. They have three ramps, one per channels, each have an array that is a lookup table with one associated variable that describes the size of the table. They only differ in the element type of the arrays --- @code{red}, @code{green} and @code{blue} --- whose type is specified in the table above. @code{red}, @code{green} and @code{blue} is a pointer of that type. For example, for @code{libgamma_gamma_ramps16_t} @code{red}, @code{green} and @code{blue} are of type @code{uint16_t*} since the element type is @code{uint16_t}. @table @asis @item @code{red_size} [@code{size_t}] The number of stops in @code{red}. @item @code{green_size} [@code{size_t}] The number of stops in @code{green}. @item @code{blue_size} [@code{size_t}] The number of stops in @code{blue}. @item @code{red} The lookup table for the red channel. @item @code{green} The lookup table for the green channel. @item @code{blue} The lookup table for the blue channel. @end table Because of how the adjustment method's own API's are designed @code{red}, @code{green} and @code{blue} should actually one array. To make sure that this is done the right way and to reduce you own code @code{libgamma} provides functions to create and destroy gamma ramp structures. @table @asis @item @code{libgamma_gamma_ramps8_initialise} [@code{int *(libgamma_gamma_ramps8_t*)}] @itemx @code{libgamma_gamma_ramps16_initialise} [@code{int *(libgamma_gamma_ramps16_t*)}] @itemx @code{libgamma_gamma_ramps32_initialise} [@code{int *(libgamma_gamma_ramps32_t*)}] @itemx @code{libgamma_gamma_ramps64_initialise} [@code{int *(libgamma_gamma_ramps64_t*)}] @itemx @code{libgamma_gamma_rampsf_initialise} [@code{int *(libgamma_gamma_rampsf_t*)}] @itemx @code{libgamma_gamma_rampsd_initialise} [@code{int *(libgamma_gamma_rampsd_t*)}] Initialise a gamma ramp in the proper way that allows all adjustment methods to read from and write to it without causing segmentation violation. The input must have @code{red_size}, @code{green_size} and @code{blue_size} set to the sizes of the gamma ramps that should be allocated. Zero is returned on success. On error @code{-1} is returned and @code{errno} is set accordingly. These functions can only fail on @code{malloc} error. @item @code{libgamma_gamma_ramps8_destroy} [@code{void *(libgamma_gamma_ramps8_t*)}] @itemx @code{libgamma_gamma_ramps16_destroy} [@code{void *(libgamma_gamma_ramps16_t*)}] @itemx @code{libgamma_gamma_ramps32_destroy} [@code{void *(libgamma_gamma_ramps32_t*)}] @itemx @code{libgamma_gamma_ramps64_destroy} [@code{void *(libgamma_gamma_ramps64_t*)}] @itemx @code{libgamma_gamma_rampsf_destroy} [@code{void *(libgamma_gamma_rampsf_t*)}] @itemx @code{libgamma_gamma_rampsd_destroy} [@code{void *(libgamma_gamma_rampsd_t*)}] Release resources that are held by a gamma ramp structure that has been allocated by @code{libgamma_gamma_ramps_initialise} or otherwise initialises in the proper manner. @item @code{libgamma_gamma_ramps8_free} [@code{void *(libgamma_gamma_ramps8_t*)}] @itemx @code{libgamma_gamma_ramps16_free} [@code{void *(libgamma_gamma_ramps16_t*)}] @itemx @code{libgamma_gamma_ramps32_free} [@code{void *(libgamma_gamma_ramps32_t*)}] @itemx @code{libgamma_gamma_ramps64_free} [@code{void *(libgamma_gamma_ramps64_t*)}] @itemx @code{libgamma_gamma_rampsf_free} [@code{void *(libgamma_gamma_rampsf_t*)}] @itemx @code{libgamma_gamma_rampsd_free} [@code{void *(libgamma_gamma_rampsd_t*)}] Release resources that are held by a gamma ramp structure that has been allocated by @code{libgamma_gamma_ramps*_initialise} or otherwise initialises in the proper manner, as well as release the pointer to the structure. @end table To read the current gamma ramps for a CRTC, you can use the function @code{libgamma_crtc_get_gamma_ramps16}. This function returns zero on success, and a negative @code{int} on failure. If the function fails, the return value will be one of the error codes listed in @ref{Errors}. The function takes two arguments: the @code{libgamma_crtc_state_t*} for the CRTC, and a @code{libgamma_gamma_rampsd_t*} that will be filled with the current gamma ramps, it must have been initialise by @code{libgamma_gamma_ramps16_initialise} or in a compatible manner. Similarly you can use @code{libgamma_crtc_set_gamma_ramps16} to apply gamma ramps to a CRTC. This function has the same return value and the same first argument as @code{libgamma_crtc_get_gamma_ramps16}, but its second argument is a @code{libgamma_gamma_rampsd_t} rather than a @code{libgamma_gamma_rampsd_t*}. Alternatively, but with some performance impact, you can use the function @code{libgamma_crtc_set_gamma_ramps16_f}. The difference between @code{libgamma_crtc_set_gamma_ramps16_f} and @code{libgamma_crtc_set_gamma_ramps16} is that the second argument is substitute for three separate argument that are used to generate the gamma ramps: @table @asis @item @code{red_function} [@code{libgamma_gamma_ramps16_fun*}] The function that generates the the gamma ramp for the red channel. @item @code{green_function} [@code{libgamma_gamma_ramps16_fun*}] The function that generates the the gamma ramp for the green channel. @item @code{blue_function} [@code{libgamma_gamma_ramps16_fun*}] The function that generates the the gamma ramp for the blue channel. @end table @code{libgamma_gamma_ramps16_fun} is a @code{typedef} of @code{uint16_t (float encoding)}. As input, it takes a [0, 1] float of the encoding value and as output it should return the output value. These functions for reading and applying gamma ramps are for @code{uint16_t} element type gamma ramps. But it is possible to use other element types as well: @table @code @item uint8_t Substitute all @code{ramps16} for @code{ramps8} in the the function names and date type definition names. @item uint32_t Substitute all @code{ramps16} for @code{ramps32} in the the function names and date type definition names. @item uint64_t Substitute all @code{ramps16} for @code{ramps64} in the the function names and date type definition names. @item float Substitute all @code{ramps16} for @code{rampsf} in the the function names and date type definition names. @item double Substitute all @code{ramps16} for @code{rampsd} in the the function names and date type definition names. @end table @node Errors @section Errors Many @command{libgamma} functions will return @command{libgamma} specific error codes rather than setting @code{errno} and return @code{-1}. However @code{errno} may have been set, but should in such case be ignored unless @code{LIBGAMMA_ERRNO_SET} has been returned. Other functions do set @code{errno} and return @code{-1}. Other functions may store the error code. In this case @code{LIBGAMMA_ERRNO_SET} cannot be stored but the value that @code{errno} had when an error occured can be stored instead of a @command{libgamma} specific error codes. @code{errno} values are allows positive whereas @command{libgamma} specific error codes are allows negative. On success zero is returned or stored. If @code{LIBGAMMA_DEVICE_REQUIRE_GROUP} is returned the ID of the required group is stored in @code{libgamma_group_gid} and the name of that group is stored in @code{libgamma_group_name}. @code{NULL} is stored if the name of the group cannto be determined. @file{libgamma.h} give you access to these variables, they are defined as @code{gid_t} (@code{short int} for Windows) and @code{const char*} types respectively. Additionally, except on Windows, these use thread local storage, defined with the @code{__thread} qualifier. @command{libgamma} defines the following error codes that its functions may return: @table @code %>for err in $(libgamma-error-extract --list | sort); do @item %{err} %>libgamma-error-extract $err | texise %>done @end table The function @code{libgamma_name_of_error} can be used to return the name of an libgamma error. For example @code{libgamma_name_of_error(LIBGAMMA_ERRNO_SET)} will return the string ``LIBGAMMA_ERRNO_SET''. Similarly @code{libgamma_value_of_error("LIBGAMMA_ERRNO_SET")} will return the value of @code{LIBGAMMA_ERRNO_SET}. The value returned from @code{libgamma_name_of_error} shall not be @code{free}:d. @code{NULL} is returned if the value does nto refer to a @command{libgamma} error. @code{libgamma_value_of_error} will return zero if the input is @code{NULL} or string that is not the name of a @command{libgamma} error. The function @code{libgamma_perror} can be used to print an error to stderr in a @code{perror} fashion. However @code{libgamma_perror} will not translate the @command{libgamma} errors into human-readable strings, it will simply print the name of the error. @code{libgamma_perror} takes two arguments: a @code{const char*} that work like the parameter for @code{perror}, and an @code{int} with the error code. If the error code is the value of @code{LIBGAMMA_ERRNO_SET} @code{perror} will be used to print the current error stored in @code{errno}. If the error code is non-negative (an @code{errno} value), that value will be stored in @code{errno} and @code{perror} will be used to print it. Additionally, if the error code is the value of @code{LIBGAMMA_DEVICE_REQUIRE_GROUP} the required group will be printed with its numerical value and, if known, its name. @node GNU Free Documentation License @appendix GNU Free Documentation License @include fdl.texinfo @bye