aboutsummaryrefslogblamecommitdiffstats
path: root/libgamma-method.cc
blob: 2dfee7626a51245d44209e12af43bdb36e4afd98 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                                                         
                             
                            
                 

                  

 

                  






































































































































































































































































































                                                                                                        
               


                                          






































































































































































































                                                                                                       
               

                           
 
/* See LICENSE file for copyright and license details. */
#include "libgamma-method.hh"
#include "libgamma-error.hh"
#include <cerrno>
#include <cstdlib>
#include <cstring>


namespace libgamma
{
	/**
	 * Constructor
	 */
	MethodCapabilities::MethodCapabilities() :
		crtc_information(0),
		default_site_known(false),
		multiple_sites(false),
		multiple_partitions(false),
		multiple_crtcs(false),
		partitions_are_graphics_cards(false),
		site_restore(false),
		partition_restore(false),
		crtc_restore(false),
		identical_gamma_sizes(false),
		fixed_gamma_size(false),
		fixed_gamma_depth(false),
		real(false),
		fake(false)
	{
		/* do nothing */
	}

	/**
	 * Constructor
	 * 
	 * @param  caps  The information in the native structure
	 */
	MethodCapabilities::MethodCapabilities(libgamma_method_capabilities_t *caps) :
		crtc_information(caps->crtc_information),
		default_site_known(caps->default_site_known),
		multiple_sites(caps->multiple_sites),
		multiple_partitions(caps->multiple_partitions),
		multiple_crtcs(caps->multiple_crtcs),
		partitions_are_graphics_cards(caps->partitions_are_graphics_cards),
		site_restore(caps->site_restore),
		partition_restore(caps->partition_restore),
		crtc_restore(caps->crtc_restore),
		identical_gamma_sizes(caps->identical_gamma_sizes),
		fixed_gamma_size(caps->fixed_gamma_size),
		fixed_gamma_depth(caps->fixed_gamma_depth),
		real(caps->real),
		fake(caps->fake)
	{
		/* do nothing */
	}

	/**
	 * Copy constructor
	 * 
	 * @param  other  The information to copy.
	 */
	MethodCapabilities::MethodCapabilities(const MethodCapabilities &other) :
		crtc_information(other.crtc_information),
		default_site_known(other.default_site_known),
		multiple_sites(other.multiple_sites),
		multiple_partitions(other.multiple_partitions),
		multiple_crtcs(other.multiple_crtcs),
		partitions_are_graphics_cards(other.partitions_are_graphics_cards),
		site_restore(other.site_restore),
		partition_restore(other.partition_restore),
		crtc_restore(other.crtc_restore),
		identical_gamma_sizes(other.identical_gamma_sizes),
		fixed_gamma_size(other.fixed_gamma_size),
		fixed_gamma_depth(other.fixed_gamma_depth),
		real(other.real),
		fake(other.fake)
	{
		/* do nothing */
	}

	/**
	 * Destructor
	 */
	MethodCapabilities::~MethodCapabilities()
	{
		/* do nothing */
	}

	/**
	 * Copy operator
	 * 
	 * @param  other  The information to copy
	 */
	MethodCapabilities &
	MethodCapabilities::operator =(const MethodCapabilities &other)
	{
		this->crtc_information = other.crtc_information;
		this->default_site_known = other.default_site_known;
		this->multiple_sites = other.multiple_sites;
		this->multiple_partitions = other.multiple_partitions;
		this->multiple_crtcs = other.multiple_crtcs;
		this->partitions_are_graphics_cards = other.partitions_are_graphics_cards;
		this->site_restore = other.site_restore;
		this->partition_restore = other.partition_restore;
		this->crtc_restore = other.crtc_restore;
		this->identical_gamma_sizes = other.identical_gamma_sizes;
		this->fixed_gamma_size = other.fixed_gamma_size;
		this->fixed_gamma_depth = other.fixed_gamma_depth;
		this->real = other.real;
		this->fake = other.fake;

		return *this;
	}



	/**
	 * Constructor
	 */
	CRTCInformation::CRTCInformation() :
		edid(nullptr),
		edid_length(0),
		edid_error(0),
		width_mm(0),
		width_mm_error(0),
		height_mm(0),
		height_mm_error(0),
		width_mm_edid(0),
		width_mm_edid_error(0),
		height_mm_edid(0),
		height_mm_edid_error(0),
		red_gamma_size(0),
		green_gamma_size(0),
		blue_gamma_size(0),
		gamma_size_error(0),
		gamma_depth(0),
		gamma_depth_error(0),
		gamma_support(0),
		gamma_support_error(0),
		subpixel_order((SubpixelOrder)0),
		subpixel_order_error(0),
		active(0),
		active_error(0),
		connector_name(nullptr),
		connector_name_error(0),
		connector_type((ConnectorType)0),
		connector_type_error(0),
		gamma_red(0),
		gamma_green(0),
		gamma_blue(0),
		gamma_error(0)
	{
		/* do nothing */
	}

	/**
	 * Constructor
	 * 
	 * @param  info  The information in the native structure
	 */
	CRTCInformation::CRTCInformation(libgamma_crtc_information_t *info) :
		edid(info->edid),
		edid_length(info->edid_length),
		edid_error(info->edid_error),
		width_mm(info->width_mm),
		width_mm_error(info->width_mm_error),
		height_mm(info->height_mm),
		height_mm_error(info->height_mm_error),
		width_mm_edid(info->width_mm_edid),
		width_mm_edid_error(info->width_mm_edid_error),
		height_mm_edid(info->height_mm_edid),
		height_mm_edid_error(info->height_mm_edid_error),
		red_gamma_size(info->red_gamma_size),
		green_gamma_size(info->green_gamma_size),
		blue_gamma_size(info->blue_gamma_size),
		gamma_size_error(info->gamma_size_error),
		gamma_depth(info->gamma_depth),
		gamma_depth_error(info->gamma_depth_error),
		gamma_support(info->gamma_support),
		gamma_support_error(info->gamma_support_error),
		subpixel_order(info->subpixel_order),
		subpixel_order_error(info->subpixel_order_error),
		active(info->active),
		active_error(info->active_error),
		connector_name(nullptr),
		connector_name_error(info->connector_name_error),
		connector_type(info->connector_type),
		connector_type_error(info->connector_type_error),
		gamma_red(info->gamma_red),
		gamma_green(info->gamma_green),
		gamma_blue(info->gamma_blue),
		gamma_error(info->gamma_error)
	{
		if (info->connector_name != nullptr) {
			this->connector_name = new std::string(info->connector_name);
			free(info->connector_name);
		}
	}

	/**
	 * Copy constructor
	 * 
	 * @param  other  The information to copy
	 */
	CRTCInformation::CRTCInformation(const CRTCInformation &other) :
		edid(nullptr),
		edid_length(other.edid_length),
		edid_error(other.edid_error),
		width_mm(other.width_mm),
		width_mm_error(other.width_mm_error),
		height_mm(other.height_mm),
		height_mm_error(other.height_mm_error),
		width_mm_edid(other.width_mm_edid),
		width_mm_edid_error(other.width_mm_edid_error),
		height_mm_edid(other.height_mm_edid),
		height_mm_edid_error(other.height_mm_edid_error),
		red_gamma_size(other.red_gamma_size),
		green_gamma_size(other.green_gamma_size),
		blue_gamma_size(other.blue_gamma_size),
		gamma_size_error(other.gamma_size_error),
		gamma_depth(other.gamma_depth),
		gamma_depth_error(other.gamma_depth_error),
		gamma_support(other.gamma_support),
		gamma_support_error(other.gamma_support_error),
		subpixel_order(other.subpixel_order),
		subpixel_order_error(other.subpixel_order_error),
		active(other.active),
		active_error(other.active_error),
		connector_name(nullptr),
		connector_name_error(other.connector_name_error),
		connector_type(other.connector_type),
		connector_type_error(other.connector_type_error),
		gamma_red(other.gamma_red),
		gamma_green(other.gamma_green),
		gamma_blue(other.gamma_blue),
		gamma_error(other.gamma_error)
	{
		if (other.edid != nullptr) {
			this->edid = (unsigned char *)malloc(this->edid_length * sizeof(unsigned char));
			memcpy(this->edid, other.edid, this->edid_length * sizeof(unsigned char));
		}
		if (other.connector_name != nullptr)
			this->connector_name = new std::string(*(other.connector_name));
	}

	/**
	 * Destructor
	 */
	CRTCInformation::~CRTCInformation()
	{
		if (this->connector_name != nullptr)
			delete this->connector_name;
		free(this->edid);
	}

	/**
	 * Copy operator
	 * 
	 * @param  other  The information to copy
	 */
	CRTCInformation &
	CRTCInformation::operator =(const CRTCInformation &other)
	{
		this->edid = nullptr;
		this->edid_length = other.edid_length;
		this->edid_error = other.edid_error;
		this->width_mm = other.width_mm;
		this->width_mm_error = other.width_mm_error;
		this->height_mm = other.height_mm;
		this->height_mm_error = other.height_mm_error;
		this->width_mm_edid = other.width_mm_edid;
		this->width_mm_edid_error = other.width_mm_edid_error;
		this->height_mm_edid = other.height_mm_edid;
		this->height_mm_edid_error = other.height_mm_edid_error;
		this->red_gamma_size = other.red_gamma_size;
		this->green_gamma_size = other.green_gamma_size;
		this->blue_gamma_size = other.blue_gamma_size;
		this->gamma_size_error = other.gamma_size_error;
		this->gamma_depth = other.gamma_depth;
		this->gamma_depth_error = other.gamma_depth_error;
		this->gamma_support = other.gamma_support;
		this->gamma_support_error = other.gamma_support_error;
		this->subpixel_order = other.subpixel_order;
		this->subpixel_order_error = other.subpixel_order_error;
		this->active = other.active;
		this->active_error = other.active_error;
		this->connector_name = nullptr;
		this->connector_name_error = other.connector_name_error;
		this->connector_type = other.connector_type;
		this->connector_type_error = other.connector_type_error;
		this->gamma_red = other.gamma_red;
		this->gamma_green = other.gamma_green;
		this->gamma_blue = other.gamma_blue;
		this->gamma_error = other.gamma_error;

		if (other.edid != nullptr) {
			this->edid = (unsigned char *)malloc(this->edid_length * sizeof(unsigned char));
			memcpy(this->edid, other.edid, this->edid_length * sizeof(unsigned char));
		}
		if (other.connector_name != nullptr)
			this->connector_name = new std::string(*(other.connector_name));

		return *this;
	}

#ifdef __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wshadow"
#endif

	/**
	 * Constructor
	 */
	Site::Site() :
		method(0),
		site(nullptr),
		partitions_available(0),
		native(nullptr)
	{
		/* do nothing */
	}

	/**
	 * Constructor
	 * 
	 * @param  method  The adjustment method of the site
	 * @param  site    The site identifier, will be moved into
	 *                 the structure, must be `delete`:able
	 */
	Site::Site(int method, std::string *site) :
		method(method),
		site(site),
		partitions_available(0),
		native(nullptr)
	{
		char *cstr = nullptr;
		int r;

		if (site != nullptr) {
			const char *cstr_ = site->c_str();
			cstr = (char *)malloc((strlen(cstr_) + 1) * sizeof(char));
			memcpy(cstr, cstr_, (strlen(cstr_) + 1) * sizeof(char));
		}
		this->native = (libgamma_site_state_t*)malloc(sizeof(libgamma_site_state_t));
		r = libgamma_site_initialise(this->native, method, cstr);
		if (r < 0) {
			int saved_errno = errno;
			free(this->native);
			this->native = nullptr;
			errno = saved_errno;
			throw create_error(r);
		}
		this->partitions_available = this->native->partitions_available;
	}

	/**
	 * Destructor
	 */
	Site::~Site()
	{
		if (this->site != nullptr)
			delete this->site;
		if (this->native != nullptr)
			libgamma_site_free(this->native);
	}

	/**
	 * Restore the gamma ramps all CRTC:s with a site to
	 * the system settings
	 */
	void Site::restore()
	{
		int r = libgamma_site_restore(this->native);
		if (r)
			throw create_error(r);
	}


	/**
	 * Constructor
	 */
	Partition::Partition() :
		site(nullptr),
		partition(0),
		crtcs_available(0),
		native(nullptr)
	{
		/* do nothing */
	}

	/**
	 * Constructor
	 * 
	 * @param  site       The site of the partition
	 * @param  partition  The index of the partition
	 */
	Partition::Partition(Site *site, size_t partition) :
		site(site),
		partition(partition),
		crtcs_available(0),
		native(nullptr)
	{
		int r;
		this->native = (libgamma_partition_state_t*)malloc(sizeof(libgamma_partition_state_t));
		r = libgamma_partition_initialise(this->native, site->native, partition);
		if (r < 0) {
			int saved_errno = errno;
			free(this->native);
			this->native = nullptr;
			errno = saved_errno;
			throw create_error(r);
		}
		this->crtcs_available = this->native->crtcs_available;
	}

	/**
	 * Destructor
	 */
	Partition::~Partition()
	{
		if (this->native != nullptr)
			libgamma_partition_free(this->native);
	}

	/**
	 * Restore the gamma ramps all CRTC:s with a partition
	 * to the system settings
	 */
	void
	Partition::restore()
	{
		int r = libgamma_partition_restore(this->native);
		if (r)
			throw create_error(r);
	}


	/**
	 * Constructor
	 */
	CRTC::CRTC() :
		partition(nullptr),
		crtc(0),
		native(nullptr)
	{
		/* do nothing */
	}

	/**
	 * Constructor
	 * 
	 * @param  partition  The partition of the CRTC
	 * @param  crtc       The index of the CRTC
	 */
	CRTC::CRTC(Partition *partition, size_t crtc) :
		partition(partition),
		crtc(crtc),
		native(nullptr)
	{
		int r;
		this->native = (libgamma_crtc_state_t *)malloc(sizeof(libgamma_crtc_state_t));
		r = libgamma_crtc_initialise(this->native, partition->native, crtc);
		if (r < 0) {
			int saved_errno = errno;
			free(this->native);
			this->native = nullptr;
			errno = saved_errno;
			throw create_error(r);
		}
	}

	/**
	 * Destructor
	 */
	CRTC::~CRTC()
	{
		if (this->native != nullptr)
			libgamma_crtc_free(this->native);
	}

	/**
	 * Restore the gamma ramps for a CRTC to the system
	 * settings for that CRTC
	 */
	void
	CRTC::restore()
	{
		int r = libgamma_crtc_restore(this->native);
		if (r)
			throw create_error(r);
	}

	/**
	 * Read information about a CRTC
	 * 
	 * @param   output  Instance of a data structure to fill with the information about the CRTC
	 * @param   fields  OR:ed identifiers for the information about the CRTC that should be read
	 * @return          Whether an error has occurred and is stored in a `*_error` field
	 */
	bool
	CRTC::information(CRTCInformation *output, int32_t fields)
	{
		libgamma_crtc_information_t info;
		int r = libgamma_get_crtc_information(&info, this->native, fields);
		*output = CRTCInformation(&info);
		return r != 0;
	}

#ifdef __GNUC__
# pragma GCC diagnostic pop
#endif
}