aboutsummaryrefslogtreecommitdiffstats
path: root/libgamma_method.py
diff options
context:
space:
mode:
Diffstat (limited to 'libgamma_method.py')
-rw-r--r--libgamma_method.py1093
1 files changed, 1093 insertions, 0 deletions
diff --git a/libgamma_method.py b/libgamma_method.py
new file mode 100644
index 0000000..c606959
--- /dev/null
+++ b/libgamma_method.py
@@ -0,0 +1,1093 @@
+# See LICENSE file for copyright and license details.
+from libgamma_error import create_error
+
+
+LIBGAMMA_METHOD_DUMMY = 0
+'''
+The identifier for the dummy adjustment method.
+This method can be configured and is useful for
+testing your program's ability to handle errors.
+'''
+
+LIBGAMMA_METHOD_X_RANDR = 1
+'''
+The identifier for the adjustment method with
+uses the RandR protocol under the X display server
+'''
+
+LIBGAMMA_METHOD_X_VIDMODE = 2
+'''
+The identifier for the adjustment method with
+uses the VidMode protocol under the X display server.
+This is an older alternative to RandR that can
+work on some drivers that are not supported by RandR,
+however it can only control the primary CRTC per
+screen (partition).
+'''
+
+LIBGAMMA_METHOD_LINUX_DRM = 3
+'''
+The identifier for the Direct Rendering Manager
+adjustment method that is available in Linux
+(built in to the Linux kernel with a userland
+library for access) and is a part of the
+Direct Rendering Infrastructure. This adjustment
+method all work when you are in non-graphical
+mode; however a display server cannnot be
+started while this is running, but it can be
+started while a display server is running.
+'''
+
+LIBGAMMA_METHOD_W32_GDI = 4
+'''
+The identifier for the Graphics Device Interface
+adjustment method that is available in Windows.
+This method is not well tested; it can be compiled
+to be available under X.org using a translation layer.
+'''
+
+LIBGAMMA_METHOD_QUARTZ_CORE_GRAPHICS = 5
+'''
+The identifier for the CoreGraphics adjustment
+method that is available in Mac OS X that can
+adjust gamma ramps under the Quartz display server.
+This method is not well tested; it can be compiled
+to be available under X.org using a translation layer.
+'''
+
+
+LIBGAMMA_METHOD_MAX = 5
+'''
+The index of the last gamma method, neither it
+nor any index before it may actually be supported
+as it could have been disabled at compile-time
+'''
+
+LIBGAMMA_METHOD_COUNT = (LIBGAMMA_METHOD_MAX + 1)
+'''
+The number adjustment methods provided by this library.
+Note however that this includes adjstment methods that
+have been removed at compile-time.
+'''
+
+
+class MethodCapabilities:
+ '''
+ Capabilities of adjustment methods
+
+ ---- Integer variables ----
+
+ @variable crtc_information OR of the CRTC information fields in `CRTCInformation`
+ that may (but can fail) be read successfully
+
+ ---- Boolean variables ----
+
+ @variable default_site_known Whether the default site is known, if true the site is integrated
+ to the system or can be determined using environment variables
+ @variable multiple_sites Whether the adjustment method supports multiple sites rather
+ than just the default site
+ @variable multiple_partitions Whether the adjustment method supports multiple partitions
+ per site
+ @variable multiple_crtcs Whether the adjustment method supports multiple CRTC:s
+ per partition per site
+ @variable partitions_are_graphics_cards Whether the partition to graphics card is a bijection
+ @variable site_restore Whether the adjustment method supports `site_restore`
+ @variable partition_restore Whether the adjustment method supports `partition_restore`
+ @variable crtc_restore Whether the adjustment method supports `crtc_restore`
+ @variable identical_gamma_sizes Whether the `red_gamma_size`, `green_gamma_size` and
+ `blue_gamma_size` fields in `CRTCInformation` will always
+ have the same values as each other for the adjustment method
+ @variable fixed_gamma_size Whether the `red_gamma_size`, `green_gamma_size` and
+ `blue_gamma_size` fields in `CRTCInformation` will always be
+ filled with the same value for the adjustment method
+ @variable fixed_gamma_depth Whether the `gamma_depth` field in `CRTCInformation` will
+ always be filled with the same value for the adjustment method
+ @variable real Whether the adjustment method will actually perform adjustments
+ @variable fake Whether the adjustment method is implement using a translation
+ layer
+ '''
+
+ def __init__(self, crtc_information : int = 0, booleans : int = 0):
+ '''
+ Constructor
+
+ @param crtc_information The value for `CRTCInformation`
+ @param booleans The value for each boolean variable
+ '''
+ self.crtc_information = crtc_information
+ self.default_site_known = (booleans & (1 << 0)) != 0
+ self.multiple_sites = (booleans & (1 << 1)) != 0
+ self.multiple_partitions = (booleans & (1 << 2)) != 0
+ self.multiple_crtcs = (booleans & (1 << 3)) != 0
+ self.partitions_are_graphics_cards = (booleans & (1 << 4)) != 0
+ self.site_restore = (booleans & (1 << 5)) != 0
+ self.partition_restore = (booleans & (1 << 6)) != 0
+ self.crtc_restore = (booleans & (1 << 7)) != 0
+ self.identical_gamma_sizes = (booleans & (1 << 8)) != 0
+ self.fixed_gamma_size = (booleans & (1 << 9)) != 0
+ self.fixed_gamma_depth = (booleans & (1 << 10)) != 0
+ self.real = (booleans & (1 << 11)) != 0
+ self.fake = (booleans & (1 << 12)) != 0
+
+
+class CRTCInformation:
+ '''
+ Cathode ray tube controller information data structure
+
+ @variable edid:bytes The Extended Display Identification Data associated with
+ the attached monitor. This is raw byte array that is usually
+ 128 bytes long.
+ @variable edid_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+
+ @variable width_mm:int The phyical width, in millimetres, of the viewport of the
+ attached monitor, as reported by the adjustment method. This
+ value may be incorrect, which is a known issue with the X
+ server where it is the result of the X server attempting
+ the estimate the size on its own.
+ Zero means that its is not applicable, which is the case
+ for projectors.
+ @variable width_mm_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+ @variable height_mm:int The phyical height, in millimetres, of the viewport of the
+ attached monitor, as reported by the adjustment method. This
+ value may be incorrect, which is a known issue with the X
+ server where it is the result of the X server attempting
+ the estimate the size on its own.
+ Zero means that its is not applicable, which is the case
+ for projectors.
+ @variable height_mm_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+
+ @variable width_mm_edid:int The phyical width, in millimetres, of the viewport of the
+ attached monitor, as reported by it the monitor's Extended
+ Display Information Data. This value can only contain whole
+ centimetres, which means that the result is always zero
+ modulus ten. However, this could change with revisions of
+ the EDID structure.
+ Zero means that its is not applicable, which is the case
+ for projectors.
+ @variable width_mm_edid_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+ @variable height_mm_edid:int The phyical height, in millimetres, of the viewport of the
+ attached monitor, as reported by it the monitor's Extended
+ Display Information Data. This value can only contain whole
+ centimetres, which means that the result is always zero
+ modulus ten. However, this could change with revisions of
+ the EDID structure.
+ Zero means that its is not applicable, which is the case
+ for projectors.
+ @variable height_mm_edid_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+
+ @variable red_gamma_size:int The size of the encoding axis of the red gamma ramp
+ @variable green_gamma_size:int The size of the encoding axis of the green gamma ramp
+ @variable blue_gamma_size:int The size of the encoding axis of the blue gamma ramp
+ @variable gamma_size_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+
+ @variable gamma_depth:int The bit-depth of the value axes of gamma ramps,
+ -1 for single precision floating point, and -2 for
+ double precision floating point
+ @variable gamma_depth_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+
+ @variable gamma_support:int Non-zero gamma ramp adjustments are supported
+ @variable gamma_support_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+
+ @variable subpixel_order:int The layout of the subpixels.
+ You cannot count on this value — especially for CRT:s —
+ but it is provided anyway as a means of distinguishing monitors.
+ @variable subpixel_order_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+
+ @variable active:bool Whether there is a monitors connected to the CRTC
+ @variable active_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+
+ @variable connector_name:str The name of the connector as designated by the display
+ server or as give by this library in case the display
+ server lacks this feature
+ @variable connector_name_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+
+ @variable connector_type:int The type of the connector that is associated with the CRTC
+ @variable connector_type_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+
+ @variable gamma_red:float The gamma characteristics of the monitor as reported
+ in its Extended Display Information Data. The value
+ holds the value for the red channel. If you do not have
+ and more accurate measurement of the gamma for the
+ monitor this could be used to give a rought gamma
+ correction; simply divide the value with 2.2 and use
+ the result for the red channel in the gamma correction.
+ @variable gamma_green:float The gamma characteristics of the monitor as reported
+ in its Extended Display Information Data. The value
+ holds the value for the green channel. If you do not have
+ and more accurate measurement of the gamma for the
+ monitor this could be used to give a rought gamma
+ correction; simply divide the value with 2.2 and use
+ the result for the green channel in the gamma correction.
+ @variable gamma_blue:float The gamma characteristics of the monitor as reported
+ in its Extended Display Information Data. The value
+ holds the value for the blue channel. If you do not have
+ and more accurate measurement of the gamma for the
+ monitor this could be used to give a rought gamma
+ correction; simply divide the value with 2.2 and use
+ the result for the blue channel in the gamma correction.
+ @variable gamma_error:int Zero on success, positive it holds the value `errno` had
+ when the reading failed, otherwise (negative) the value
+ of an error identifier provided by this library
+ '''
+
+ def __init__(self, data):
+ '''
+ Constructor
+
+ @param data:list The value of each variable
+ '''
+ self.edid = data[0]
+ self.edid_error = data[1]
+ self.width_mm = data[2]
+ self.width_mm_error = data[3]
+ self.height_mm = data[4]
+ self.height_mm_error = data[5]
+ self.width_mm_edid = data[6]
+ self.width_mm_edid_error = data[7]
+ self.height_mm_edid = data[8]
+ self.height_mm_edid_error = data[9]
+ self.red_gamma_size = data[10]
+ self.green_gamma_size = data[11]
+ self.blue_gamma_size = data[12]
+ self.gamma_size_error = data[13]
+ self.gamma_depth = data[14]
+ self.gamma_depth_error = data[15]
+ self.gamma_support = data[16]
+ self.gamma_support_error = data[17]
+ self.subpixel_order = data[18]
+ self.subpixel_order_error = data[19]
+ self.active = data[20]
+ self.active_error = data[21]
+ self.connector_name = data[22]
+ self.connector_name_error = data[23]
+ self.connector_type = data[24]
+ self.connector_type_error = data[25]
+ self.gamma_red = data[26]
+ self.gamma_green = data[27]
+ self.gamma_blue = data[28]
+ self.gamma_error = data[29]
+
+
+LIBGAMMA_CONNECTOR_TYPE_Unknown = 0
+'''
+The adjustment method does not know the connector's type
+(This could be considered an error)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_VGA = 1
+'''
+Video Graphics Array (VGA)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_DVI = 2
+'''
+Digital Visual Interface, unknown type
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_DVII = 3
+'''
+Digital Visual Interface, integrated (DVI-I)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_DVID = 4
+'''
+Digital Visual Interface, digital only (DVI-D)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_DVIA = 5
+'''
+Digital Visual Interface, analogue only (DVI-A)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_Composite = 6
+'''
+Composite video
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_SVIDEO = 7
+'''
+Separate Video (S-video)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_LVDS = 8
+'''
+Low-voltage differential signaling (LVDS)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_Component = 9
+'''
+Component video, usually separate cables for each channel
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_9PinDIN = 10
+'''
+9 pin DIN (Deutsches Institut für Normung) connector
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_DisplayPort = 11
+'''
+DisplayPort
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_HDMI = 12
+'''
+High-Definition Multimedia Interface (HDMI), unknown type
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_HDMIA = 13
+'''
+High-Definition Multimedia Interface, type A (HDMI-A)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_HDMIB = 14
+'''
+High-Definition Multimedia Interface, type B (HDMI-B)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_TV = 15
+'''
+Television, unknown connector
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_eDP = 16
+'''
+Embedded DisplayPort (eDP)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_VIRTUAL = 17
+'''
+A virtual connector
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_DSI = 18
+'''
+Display Serial Interface (DSI)
+'''
+
+LIBGAMMA_CONNECTOR_TYPE_LFP = 19
+'''
+LFP connector
+(If you know what this is add it to Wikipedia)
+'''
+
+
+LIBGAMMA_CONNECTOR_TYPE_COUNT = 20
+'''
+The number of `LIBGAMMA_CONNECTOR_*` values defined
+'''
+
+
+
+LIBGAMMA_SUBPIXEL_ORDER_UNKNOWN = 0
+'''
+The adjustment method does not know the order of the subpixels
+(This could be considered an error)
+'''
+
+LIBGAMMA_SUBPIXEL_ORDER_NONE = 1
+'''
+There are no subpixels in the monitor
+'''
+
+LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB = 2
+'''
+The subpixels are ordered red, green and then blue, from left to right
+'''
+
+LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_BGR = 3
+'''
+The subpixels are ordered blue, green and then red, from left to right
+'''
+
+LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_RGB = 4
+'''
+The subpixels are ordered red, green and then blue, from the top down
+'''
+
+LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_BGR = 5
+'''
+The subpixels are ordered blue, green and then red, from the top down
+'''
+
+
+LIBGAMMA_SUBPIXEL_ORDER_COUNT = 6
+'''
+The number of `LIBGAMMA_SUBPIXEL_ORDER_*` values defined
+'''
+
+
+
+LIBGAMMA_CRTC_INFO_EDID = 1 << 0
+'''
+For a `CRTCInformation` fill in the values for
+`edid` and `edid_length` and report errors to `edid_error`
+'''
+
+LIBGAMMA_CRTC_INFO_WIDTH_MM = 1 << 1
+'''
+For a `CRTCInformation` fill in the value for
+`width_mm` and report errors to `width_mm_error`
+'''
+
+LIBGAMMA_CRTC_INFO_HEIGHT_MM = 1 << 2
+'''
+For a `CRTCInformation` fill in the value for
+`height_mm` and report errors to `height_mm_error`
+'''
+
+LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID = 1 << 3
+'''
+For a `CRTCInformation` fill in the value for
+`width_mm_edid` and report errors to `width_mm_edid_error`
+'''
+
+LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID = 1 << 4
+'''
+For a `CRTCInformation` fill in the value for
+`height_mm_edid` and report errors to `height_mm_edid_error`
+'''
+
+LIBGAMMA_CRTC_INFO_GAMMA_SIZE = 1 << 5
+'''
+For a `CRTCInformation` fill in the values for
+`red_gamma_size`, `green_gamma_size` and `blue_gamma_size`,
+and report errors to `gamma_size_error`
+'''
+
+LIBGAMMA_CRTC_INFO_GAMMA_DEPTH = 1 << 6
+'''
+For a `CRTCInformation` fill in the value for
+`gamma_depth` and report errors to `gamma_depth_error`
+'''
+
+LIBGAMMA_CRTC_INFO_GAMMA_SUPPORT = 1 << 7
+'''
+For a `CRTCInformation` fill in the value for
+`gamma_support` and report errors to `gamma_support_error`
+'''
+
+LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER = 1 << 8
+'''
+For a `CRTCInformation` fill in the value for
+`subpixel_order` and report errors to `subpixel_order_error`
+'''
+
+LIBGAMMA_CRTC_INFO_ACTIVE = 1 << 9
+'''
+For a `CRTCInformation` fill in the value for
+`active` and report errors to `active_error`
+'''
+
+LIBGAMMA_CRTC_INFO_CONNECTOR_NAME = 1 << 10
+'''
+For a `CRTCInformation` fill in the value for
+`connector_name` and report errors to `connector_name_error`
+'''
+
+LIBGAMMA_CRTC_INFO_CONNECTOR_TYPE = 1 << 11
+'''
+For a `CRTCInformation` fill in the value for
+`connector_type` and report errors to `connector_type_error`
+'''
+
+LIBGAMMA_CRTC_INFO_GAMMA = 1 << 12
+'''
+For a `CRTCInformation` fill in the values for
+`gamma_red`, `gamma_green` and `gamma_blue` and
+report errors to `gamma_error`
+'''
+
+
+LIBGAMMA_CRTC_INFO_COUNT = 13
+'''
+The number of `LIBGAMMA_CRTC_INFO_*` values defined
+'''
+
+
+
+LIBGAMMA_CRTC_INFO_MACRO_EDID_VIEWPORT = LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID | \
+ LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID
+'''
+Macro for both `CRTCInformation` fields that can
+specify the size of the monitor's viewport as specified
+in the monitor's Extended Display Information Data
+'''
+
+LIBGAMMA_CRTC_INFO_MACRO_EDID = LIBGAMMA_CRTC_INFO_EDID | \
+ LIBGAMMA_CRTC_INFO_MACRO_EDID_VIEWPORT | \
+ LIBGAMMA_CRTC_INFO_GAMMA
+'''
+Macro for all `CRTCInformation` fields that can be
+filled if the adjustment method have support for
+reading the monitors' Extended Display Information Data
+'''
+
+LIBGAMMA_CRTC_INFO_MACRO_VIEWPORT = LIBGAMMA_CRTC_INFO_WIDTH_MM | \
+ LIBGAMMA_CRTC_INFO_HEIGHT_MM
+'''
+Macro for both `CRTCInformation` fields that can
+specify the size of the monitor's viewport as provided
+by the adjustment method without this library having to
+parse the monitor's Extended Display Information Data
+'''
+
+LIBGAMMA_CRTC_INFO_MACRO_RAMP = LIBGAMMA_CRTC_INFO_GAMMA_SIZE | \
+ LIBGAMMA_CRTC_INFO_GAMMA_DEPTH
+'''
+Macro for the `CRTCInformation` fields that specifies
+the CRTC's gamma ramp sizes and gamma ramp depth
+'''
+
+LIBGAMMA_CRTC_INFO_MACRO_CONNECTOR = LIBGAMMA_CRTC_INFO_CONNECTOR_NAME | \
+ LIBGAMMA_CRTC_INFO_CONNECTOR_TYPE
+'''
+Macro for the `CRTCInformation` fields that specifies
+the CRTC's connector type and the partition unique
+name of the connector
+'''
+
+LIBGAMMA_CRTC_INFO_MACRO_ACTIVE = LIBGAMMA_CRTC_INFO_MACRO_EDID | \
+ LIBGAMMA_CRTC_INFO_MACRO_VIEWPORT | \
+ LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER | \
+ LIBGAMMA_CRTC_INFO_ACTIVE
+'''
+Macro for the `CRTCInformation` fields that required
+there is a monitor attached to the connector, and
+that status itself
+'''
+
+
+
+class GammaRamps:
+ '''
+ Gamma ramp structure
+ '''
+
+ class Ramp:
+ '''
+ A gamma ramp for one single channel
+ '''
+
+ def __init__(self, ramp, size : int, depth : int):
+ '''
+ Constructor
+
+ @param ramp The gamma ramp
+ @param size The number of stops in the gamma ramp
+ @param depth The depth of the gamma ramp
+ '''
+ from libgamma_native_method import libgamma_native_gamma_ramps8_get
+ from libgamma_native_method import libgamma_native_gamma_ramps16_get
+ from libgamma_native_method import libgamma_native_gamma_ramps32_get
+ from libgamma_native_method import libgamma_native_gamma_ramps64_get
+ from libgamma_native_method import libgamma_native_gamma_rampsf_get
+ from libgamma_native_method import libgamma_native_gamma_rampsd_get
+ from libgamma_native_method import libgamma_native_gamma_ramps8_set
+ from libgamma_native_method import libgamma_native_gamma_ramps16_set
+ from libgamma_native_method import libgamma_native_gamma_ramps32_set
+ from libgamma_native_method import libgamma_native_gamma_ramps64_set
+ from libgamma_native_method import libgamma_native_gamma_rampsf_set
+ from libgamma_native_method import libgamma_native_gamma_rampsd_set
+ self._size = size
+ self._ramp = ramp
+ if depth == 8: fs = (libgamma_native_gamma_ramps8_get, libgamma_native_gamma_ramps8_set)
+ elif depth == 16: fs = (libgamma_native_gamma_ramps16_get, libgamma_native_gamma_ramps16_set)
+ elif depth == 32: fs = (libgamma_native_gamma_ramps32_get, libgamma_native_gamma_ramps32_set)
+ elif depth == 64: fs = (libgamma_native_gamma_ramps64_get, libgamma_native_gamma_ramps64_set)
+ elif depth == -1: fs = (libgamma_native_gamma_rampsf_get, libgamma_native_gamma_rampsf_set)
+ elif depth == -2: fs = (libgamma_native_gamma_rampsd_get, libgamma_native_gamma_rampsd_set)
+ (self._get, self._set) = fs
+
+
+ @property
+ def size(self) -> int:
+ '''
+ Get the number of stops in the gamma ramp
+
+ @return The number of stops in the gamma ramp
+ '''
+ return self._size
+
+ @size.setter
+ def size(self, value : int):
+ '''
+ It is not possible to change this attribute, but
+ a setter is required for the getter to function
+ '''
+ raise AttributeError('cannot resize ramp')
+
+ def __len__(self) -> int:
+ '''
+ Get the number of stops in the gamma ramp
+
+ @return The number of stops in the gamma ramp
+ '''
+ return self._size
+
+ def __getitem__(self, indices):
+ '''
+ Read the gamma ramp
+
+ @param indices:slice The stops to read
+ @return :list<int|float> The values of the read stops
+
+ -- OR --
+
+ @param indices:int The index of the stop to read
+ @return :int|float The value of the read stop
+ '''
+ if isinstance(indices, slice):
+ start = indices.start
+ stop = indices.stop
+ step = indices.step
+ if start is None: start = 0
+ elif start < 0: start += self._size
+ if stop is None: stop = self._size
+ elif stop < 0: stop += self._size
+ if step is None: step = 1
+ return [self._get(self._ramp, i) for i in range(start, stop, step)]
+ else:
+ if indices < 0:
+ indices += self._size
+ return self._get(self._ramp, indices)
+
+ def __setitem__(self, indices, values):
+ '''
+ Modify the gamma ramp
+
+ @param indices:slice The stops to modify
+ @param values:itr<int|float> The values for the selected stops
+
+ -- OR --
+
+ @param indices:int The index of the stop to modify
+ @param values:int|float The new value for the stop
+ '''
+ if isinstance(indices, slice):
+ start = indices.start
+ stop = indices.stop
+ step = indices.step
+ if start is None: start = 0
+ elif start < 0: start += self._size
+ if stop is None: stop = self._size
+ elif stop < 0: stop += self._size
+ if step is None: step = 1
+ indices = list(range(start, stop, step))
+ if not len(indices) == len(values):
+ raise ValueError('cannot resize ramp')
+ for index, value in zip(indices, values):
+ self._set(self._ramp, index, value)
+ else:
+ if indices < 0:
+ indices += self._size
+ self._set(self._ramp, indices, values)
+
+ def __iter__(self) -> iter:
+ '''
+ Read the gamma ramp
+
+ @return :itr<int|float> The values of each stop
+ '''
+ for value in self[:]:
+ yield value
+
+ def map(self, function):
+ '''
+ Modify the entire ramp using a function that
+ maps encoding value to output value
+
+ @param function:(float)→int|float Function that takes the encoding value as a
+ [0, 1] floating point and returns its output
+ value as the format using in the gamma ramp
+ '''
+ max_i = self._size - 1
+ for i in range(self._size):
+ self._set(self._ramp, i, function(i / max_i))
+
+
+ def __init__(self, red_size : int, green_size : int = ..., blue_size : int = ..., *, depth : int = 16):
+ '''
+ Constructor
+
+ @param red_size The number of stops in the gamma ramp for the red channel
+ @param green_size The number of stops in the gamma ramp for the green channel, `...` for `red_size`
+ @param blue_size The number of stops in the gamma ramp for the blue channel, `...` for `green_size`
+ @param depth The depth of the gamma ramps
+ '''
+ if green_size is ...: green_size = red_size
+ if blue_size is ...: blue_size = green_size
+
+ self._depth = depth
+
+ from libgamma_native_method import libgamma_native_gamma_ramps8_create
+ from libgamma_native_method import libgamma_native_gamma_ramps16_create
+ from libgamma_native_method import libgamma_native_gamma_ramps32_create
+ from libgamma_native_method import libgamma_native_gamma_ramps64_create
+ from libgamma_native_method import libgamma_native_gamma_rampsf_create
+ from libgamma_native_method import libgamma_native_gamma_rampsd_create
+ if depth == 8: ramp_struct = libgamma_native_gamma_ramps8_create (red_size, green_size, blue_size)
+ elif depth == 16: ramp_struct = libgamma_native_gamma_ramps16_create(red_size, green_size, blue_size)
+ elif depth == 32: ramp_struct = libgamma_native_gamma_ramps32_create(red_size, green_size, blue_size)
+ elif depth == 64: ramp_struct = libgamma_native_gamma_ramps64_create(red_size, green_size, blue_size)
+ elif depth == -1: ramp_struct = libgamma_native_gamma_rampsf_create (red_size, green_size, blue_size)
+ elif depth == -2: ramp_struct = libgamma_native_gamma_rampsd_create (red_size, green_size, blue_size)
+ else:
+ raise ValueError('invalid gamma ramp depth')
+ if isinstance(ramp_struct, int):
+ import libgamma_native_error as c
+ error = OSError()
+ error.errno = ramp_struct
+ error.strerror = c.strerror(error.errno)
+ raise error
+ (self._ramps, red, green, blue) = ramp_struct
+
+ self._red = GammaRamps.Ramp(red, red_size, depth)
+ self._green = GammaRamps.Ramp(green, green_size, depth)
+ self._blue = GammaRamps.Ramp(blue, blue_size, depth)
+
+
+ def __del__(self):
+ '''
+ This function is called when the object is not longer in use
+ '''
+ from libgamma_native_method import libgamma_native_gamma_ramps8_free
+ from libgamma_native_method import libgamma_native_gamma_ramps16_free
+ from libgamma_native_method import libgamma_native_gamma_ramps32_free
+ from libgamma_native_method import libgamma_native_gamma_ramps64_free
+ from libgamma_native_method import libgamma_native_gamma_rampsf_free
+ from libgamma_native_method import libgamma_native_gamma_rampsd_free
+ if self._ramps == 0:
+ return
+ if self._depth == 8: libgamma_native_gamma_ramps8_free(self._ramps)
+ elif self._depth == 16: libgamma_native_gamma_ramps16_free(self._ramps)
+ elif self._depth == 32: libgamma_native_gamma_ramps32_free(self._ramps)
+ elif self._depth == 64: libgamma_native_gamma_ramps64_free(self._ramps)
+ elif self._depth == -1: libgamma_native_gamma_rampsf_free(self._ramps)
+ elif self._depth == -2: libgamma_native_gamma_rampsd_free(self._ramps)
+
+
+ @property
+ def red(self) -> Ramp:
+ '''
+ Get the gamma ramp for the red channel
+
+ @return The gamma ramp for the red channel
+ '''
+ return self._red
+
+
+ @red.setter
+ def red(self, value):
+ '''
+ It is not possible to change this attribute, but a setter is
+ required for the getter to function
+ '''
+ raise AttributeError('cannot change ramps')
+
+
+ @property
+ def green(self) -> Ramp:
+ '''
+ Get the gamma ramp for the green channel
+
+ @return The gamma ramp for the green channel
+ '''
+ return self._green
+
+
+ @green.setter
+ def green(self, value) -> Ramp:
+ '''
+ It is not possible to change this attribute, but a setter is
+ required for the getter to function
+ '''
+ raise AttributeError('cannot change ramps')
+
+
+ @property
+ def blue(self):
+ '''
+ Get the gamma ramp for the blue channel
+
+ @return The gamma ramp for the blue channel
+ '''
+ return self._blue
+
+
+ @blue.setter
+ def blue(self, value):
+ '''
+ It is not possible to change this attribute, but a setter is
+ required for the getter to function
+ '''
+ raise AttributeError('cannot change ramps')
+
+
+ @property
+ def size(self) -> tuple:
+ '''
+ Get the ramps' sizes
+
+ @return :(red:int, green:int, blue:int) The size of each individual ramp
+ '''
+ return (self._red.size, self._green.size, self._blue.size)
+
+
+ @size.setter
+ def size(self, value):
+ '''
+ It is not possible to change this attribute, but a setter is
+ required for the getter to function
+ '''
+ raise AttributeError('cannot resize ramps')
+
+
+ @property
+ def depth(self) -> int:
+ '''
+ Get the depth of ramps
+
+ @return :int The ramps' depth in bits and -1 for single precision floating
+ point and -2 for doublesingle precision floating point
+ '''
+ return self._depth
+
+
+ @depth.setter
+ def depth(self, value):
+ '''
+ It is not possible to change this attribute, but a setter is
+ required for the getter to function
+ '''
+ raise AttributeError('cannot change depth')
+
+
+class Site:
+ '''
+ Site state
+
+ On operating systems that integrate a graphical environment
+ there is usually just one site. However, one systems with
+ pluggable graphics, like Unix-like systems such as GNU/Linux
+ and the BSD:s, there can usually be any (feasible) number of
+ sites. In X.org parlance they are called displays.
+
+ @variable method:int The adjustment method of the site
+ @variable site:str? The site identifier
+ @variable partitions_available:int The number of paritions available in the site
+ '''
+
+ def __init__(self, method : int, site : str = None):
+ '''
+ Constructor
+
+ @param method:int The adjustment method of the site
+ @param site:str? The site identifier
+ '''
+ from libgamma_native_facade import libgamma_native_site_create
+ (self._state, n) = libgamma_native_site_create(method, site)
+ if self._state == 0:
+ raise create_error(n)
+ self.partitions_available = n
+ self.method = method
+ self.site = site
+
+
+ def __del__(self):
+ '''
+ This function is called when the object is not longer in use
+ '''
+ from libgamma_native_facade import libgamma_native_site_free
+ if not self._state == 0:
+ libgamma_native_site_free(self._state)
+
+
+ def restore(self):
+ '''
+ Restore the gamma ramps all CRTC:s with the site to the system settings
+ '''
+ from libgamma_native_facade import libgamma_native_site_restore
+ r = libgamma_native_site_restore(self._state)
+ if not r == 0:
+ raise create_error(r)
+
+
+class Partition:
+ '''
+ Partition state
+
+ Probably the majority of display server only one partition
+ per site. However, X.org can, and traditional used to have
+ on multi-headed environments, multiple partitions per site.
+ In X.org partitions are called 'screens'. It is not to be
+ confused with monitor. A screen is a collection of monitors,
+ and the mapping from monitors to screens is a surjection.
+ On hardware-level adjustment methods, such as Direct
+ Rendering Manager, a partition is a graphics card
+
+ @variable site:Site The site of the partition
+ @variable partition:int The index of the partition
+ @variable crtcs_available:int The number of CRTC:s available in the parition
+ '''
+
+ def __init__(self, site : Site, partition : int):
+ '''
+ Constructor.
+
+ @param site The site of the partition
+ @param partition The index of the partition
+ '''
+ from libgamma_native_facade import libgamma_native_partition_create
+ (self._state, n) = libgamma_native_partition_create(site._state, partition)
+ if self._state == 0:
+ raise create_error(n)
+ self.crtcs_available = n
+ self.site = site
+ self.partition = partition
+
+
+ def __del__(self):
+ '''
+ This function is called when the object is not longer in use
+ '''
+ from libgamma_native_facade import libgamma_native_partition_free
+ if not self._state == 0:
+ libgamma_native_partition_free(self._state)
+
+
+ def restore(self):
+ '''
+ Restore the gamma ramps all CRTC:s with the partition to the system settings
+ '''
+ from libgamma_native_facade import libgamma_native_partition_restore
+ r = libgamma_native_partition_restore(self._state)
+ if not r == 0:
+ raise create_error(r)
+
+
+class CRTC:
+ '''
+ Cathode ray tube controller state
+
+ The CRTC controls the gamma ramps for the
+ monitor that is plugged in to the connector
+ that the CRTC belongs to
+
+ @variable partition:Partition The partition of the CRTC
+ @variable crtc:int The index of the CRTC
+ '''
+
+ def __init__(self, partition : Partition, crtc : int):
+ '''
+ Constructor
+
+ @param partition The partition the of the CRTC
+ @param crtc The index of the CRTC
+ '''
+ from libgamma_native_facade import libgamma_native_crtc_create
+ (self._state, n) = libgamma_native_crtc_create(partition._state, crtc)
+ if self._state == 0:
+ raise create_error(n)
+ self.partition = partition
+ self.crtc = crtc
+
+
+ def __del__(self):
+ '''
+ This function is called when the object is not longer in use
+ '''
+ from libgamma_native_facade import libgamma_native_crtc_free
+ if not self._state == 0:
+ libgamma_native_crtc_free(self._state)
+
+
+ def restore(self):
+ '''
+ Restore the gamma ramps for a CRTC to the system settings for that CRTC
+ '''
+ from libgamma_native_facade import libgamma_native_crtc_restore
+ r = libgamma_native_crtc_restore(self._state)
+ if not r == 0:
+ raise create_error(r)
+
+
+ def information(self, fields : int) -> tuple:
+ '''
+ Read information about a CRTC
+
+ @param field OR:ed identifiers for the information
+ about the CRTC that should be read
+ @return :(:CRTCInformation, :bool) The information about the CRTC and
+ whether no errors occurred
+ '''
+ from libgamma_native_facade import libgamma_native_get_crtc_information
+ (data, e) = libgamma_native_get_crtc_information(self._state, fields)
+ return (CRTCInformation(data), e == 0)
+
+
+ def get_gamma(self, ramps : GammaRamps):
+ '''
+ Get the current gamma ramps for the CRTC
+
+ @param ramps The gamma ramps to fill with the current values
+ '''
+ from libgamma_native_facade import libgamma_native_crtc_get_gamma_ramps8
+ from libgamma_native_facade import libgamma_native_crtc_get_gamma_ramps16
+ from libgamma_native_facade import libgamma_native_crtc_get_gamma_ramps32
+ from libgamma_native_facade import libgamma_native_crtc_get_gamma_ramps64
+ from libgamma_native_facade import libgamma_native_crtc_get_gamma_rampsf
+ from libgamma_native_facade import libgamma_native_crtc_get_gamma_rampsd
+ if ramps.depth == 8: r = libgamma_native_crtc_get_gamma_ramps8(self._state, ramps._ramps)
+ elif ramps.depth == 16: r = libgamma_native_crtc_get_gamma_ramps16(self._state, ramps._ramps)
+ elif ramps.depth == 32: r = libgamma_native_crtc_get_gamma_ramps32(self._state, ramps._ramps)
+ elif ramps.depth == 64: r = libgamma_native_crtc_get_gamma_ramps64(self._state, ramps._ramps)
+ elif ramps.depth == -1: r = libgamma_native_crtc_get_gamma_rampsf(self._state, ramps._ramps)
+ elif ramps.depth == -2: r = libgamma_native_crtc_get_gamma_rampsd(self._state, ramps._ramps)
+ if not r == 0:
+ raise create_error(r)
+
+
+ def set_gamma(self, ramps : GammaRamps):
+ '''
+ Set gamma ramps for the CRTC
+
+ @param ramps The gamma ramps to apply
+ '''
+ from libgamma_native_facade import libgamma_native_crtc_set_gamma_ramps8
+ from libgamma_native_facade import libgamma_native_crtc_set_gamma_ramps16
+ from libgamma_native_facade import libgamma_native_crtc_set_gamma_ramps32
+ from libgamma_native_facade import libgamma_native_crtc_set_gamma_ramps64
+ from libgamma_native_facade import libgamma_native_crtc_set_gamma_rampsf
+ from libgamma_native_facade import libgamma_native_crtc_set_gamma_rampsd
+ if ramps.depth == 8: r = libgamma_native_crtc_set_gamma_ramps8(self._state, ramps._ramps)
+ elif ramps.depth == 16: r = libgamma_native_crtc_set_gamma_ramps16(self._state, ramps._ramps)
+ elif ramps.depth == 32: r = libgamma_native_crtc_set_gamma_ramps32(self._state, ramps._ramps)
+ elif ramps.depth == 64: r = libgamma_native_crtc_set_gamma_ramps64(self._state, ramps._ramps)
+ elif ramps.depth == -1: r = libgamma_native_crtc_set_gamma_rampsf(self._state, ramps._ramps)
+ elif ramps.depth == -2: r = libgamma_native_crtc_set_gamma_rampsd(self._state, ramps._ramps)
+ if not r == 0:
+ raise create_error(r)