aboutsummaryrefslogblamecommitdiffstats
path: root/src/test/crtcinfo.c
blob: 627559bcb8a9e349f294178085101b7efdbf8f5a (plain) (tree)
1
2
3
4
5
6
7
                                                         

                     

   
                                               
   





                                                                                                      
   













                                                                                                        



                                                                       
                                                                    
   

                                                














                                                    
                                                

   
                                                  
   

                                        
   

                                                   
 









                                                        



   
                                                  
   

                                        
   

                                                   
 























                                                     

 

   
                                            
   

                                        
   

                                       
 






                                   

 



             
                                  
   
                         
   

                                                      
 














                                                                                                 
         










                                                                                                      

  



























































                                                                                                                   

             
 



                                  
/* See LICENSE file for copyright and license details. */
#include "crtcinfo.h"


/**
 * Conditionally print a CRTC information field
 * 
 * @param  type:data-type           Data type for the value of the information field
 * @param  notation:string-literal  %-pattern for `printf` (excluding the %) that is used for `type`
 * @param  do_print                 Whether the information should be included in the process's output
 * @param  description              A description of the information field
 * @param  error                    The error of the information field
 * @param  value                    The value of the information field
 */
#define print_crtc_information_(type, notation)\
	static void\
	print_crtc_information_##type(int do_print, const char *description, int error, type value)\
	{\
		char buf[256];\
		if (do_print) {\
			if (error) {\
				snprintf(buf, sizeof(buf) / sizeof(char), "  (error) %s", description);\
				libgamma_perror(buf, error);\
			} else {\
				printf("  %s: %" notation "\n", description, value);\
			}\
		}\
	}


/**
 * A single [a-z] word alternative to `const char*`, we need it for the
 * function name of the string variant of `print_crtc_information_*`
 */
typedef const char *str;
/* Create `print_crtc_information_*` variants */
print_crtc_information_(size_t, "lu")
print_crtc_information_(signed, "i")
print_crtc_information_(int, "i")
#ifdef __GCC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdouble-promotion"
#endif
print_crtc_information_(float, "f")
#ifdef __GCC__
# pragma GCC diagnostic pop
#endif
print_crtc_information_(str, "s")
#undef print_crtc_information_


#define __case(VALUE)  case VALUE: return #VALUE

/**
 * Get a string representation of a subpixel order
 * 
 * @param   value  The subpixel order
 * @return         String representation
 */
static const char *
subpixel_order_str(libgamma_subpixel_order_t value)
{
	switch (value) {
	__case (LIBGAMMA_SUBPIXEL_ORDER_UNKNOWN);
	__case (LIBGAMMA_SUBPIXEL_ORDER_NONE);
	__case (LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB);
	__case (LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_BGR);
	__case (LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_RGB);
	__case (LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_BGR);
	default:
		return "(unknown)";
	}
}


/**
 * Get a string representation of a connector type
 * 
 * @param   value  The connector type
 * @return         String representation
 */
static const char *
connector_type_str(libgamma_connector_type_t value)
{
	switch (value) {
	__case (LIBGAMMA_CONNECTOR_TYPE_Unknown);
	__case (LIBGAMMA_CONNECTOR_TYPE_VGA);
	__case (LIBGAMMA_CONNECTOR_TYPE_DVI);
	__case (LIBGAMMA_CONNECTOR_TYPE_DVII);
	__case (LIBGAMMA_CONNECTOR_TYPE_DVID);
	__case (LIBGAMMA_CONNECTOR_TYPE_DVIA);
	__case (LIBGAMMA_CONNECTOR_TYPE_Composite);
	__case (LIBGAMMA_CONNECTOR_TYPE_SVIDEO);
	__case (LIBGAMMA_CONNECTOR_TYPE_LVDS);
	__case (LIBGAMMA_CONNECTOR_TYPE_Component);
	__case (LIBGAMMA_CONNECTOR_TYPE_9PinDIN);
	__case (LIBGAMMA_CONNECTOR_TYPE_DisplayPort);
	__case (LIBGAMMA_CONNECTOR_TYPE_HDMI);
	__case (LIBGAMMA_CONNECTOR_TYPE_HDMIA);
	__case (LIBGAMMA_CONNECTOR_TYPE_HDMIB);
	__case (LIBGAMMA_CONNECTOR_TYPE_TV);
	__case (LIBGAMMA_CONNECTOR_TYPE_eDP);
	__case (LIBGAMMA_CONNECTOR_TYPE_VIRTUAL);
	__case (LIBGAMMA_CONNECTOR_TYPE_DSI);
	__case (LIBGAMMA_CONNECTOR_TYPE_LFP);
	default:
		return "(unknown)";
	}
}


/**
 * Get a string representation of a decision
 * 
 * @param   value  The decision
 * @return         String representation
 */
static const char *
decision_str(libgamma_decision_t value)
{
	switch (value) {
	__case (LIBGAMMA_NO);
	__case (LIBGAMMA_MAYBE);
	__case (LIBGAMMA_YES);
	default:
		return "(unknown)";
	}
}

#undef __case


/**
 * The CRTC information for a CRTC
 * 
 * @param  crtc  The CRTC
 */
void
crtc_information(libgamma_crtc_state_t *restrict crtc)
{
	libgamma_method_capabilities_t caps;
	libgamma_crtc_information_t info;
	int fields, field;
	char *edid_lc, *edid_uc;
	unsigned char *edid_raw;

	/* Get supported CRTC informations fields */
	libgamma_method_capabilities(&caps, crtc->partition->site->method);

	/* List unsupport information fields by testing them one by one */
	for (fields = caps.crtc_information; field = fields & -fields, fields; fields ^= field) {
		if (libgamma_get_crtc_information(&info, crtc, field))
			printf("Could not read CRTC information field %i\n", field);
		free(info.edid);
		free(info.connector_name);
	}

	/* Get CRTC information, that is supported */
	fields = caps.crtc_information;
	if (libgamma_get_crtc_information(&info, crtc, fields))
		printf("An error occurred while reading CRTC information\n");

	/* Macros for printing CRTC information */
#define print2(TYPE, FIELD_ID, DESCRIPTION, FIELD_VAR, ERROR_VAR)\
	print_crtc_information_##TYPE(fields & FIELD_ID, DESCRIPTION, info.ERROR_VAR, info.FIELD_VAR);
#define print(TYPE, FIELD_ID, DESCRIPTION, FIELD_VAR)\
	print2(TYPE, FIELD_ID, DESCRIPTION, FIELD_VAR, FIELD_VAR##_error);
  
  
	/* Print CRTC information */

	printf("CRTC information:\n");

	/* Print the EDID field */
	if ((fields & LIBGAMMA_CRTC_INFO_EDID)) {
		if (info.edid_error) {
			libgamma_perror("  (error) EDID", info.edid_error);
		} else {
			edid_lc  = libgamma_behex_edid(info.edid, info.edid_length);
			edid_raw = libgamma_unhex_edid(edid_lc);
			edid_uc  = libgamma_behex_edid_uppercase(edid_raw, info.edid_length);
			printf("  EDID: %s\n", edid_lc);
			printf("  EDID (uppercase): %s\n", edid_uc);
			printf("  EDID (length): %lu\n", info.edid_length);
			free(edid_lc);
			free(edid_raw);
			free(edid_uc);
		}
	}
	/* Print physical dimensions of the monitor */
	print(size_t, LIBGAMMA_CRTC_INFO_WIDTH_MM, "width", width_mm);
	print(size_t, LIBGAMMA_CRTC_INFO_HEIGHT_MM, "height", height_mm);
	print(size_t, LIBGAMMA_CRTC_INFO_WIDTH_MM_EDID, "width per EDID", width_mm_edid);
	print(size_t, LIBGAMMA_CRTC_INFO_HEIGHT_MM_EDID, "height per EDID", height_mm_edid);
	/* Print gamma ramp information */
	print2(size_t, LIBGAMMA_CRTC_INFO_GAMMA_SIZE, "red gamma ramp size", red_gamma_size, gamma_size_error);
	print2(size_t, LIBGAMMA_CRTC_INFO_GAMMA_SIZE, "green gamma ramp size", green_gamma_size, gamma_size_error);
	print2(size_t, LIBGAMMA_CRTC_INFO_GAMMA_SIZE, "blue gamma ramp size", blue_gamma_size, gamma_size_error);
	print(signed, LIBGAMMA_CRTC_INFO_GAMMA_DEPTH, "gamma ramp depth", gamma_depth);
	/* Print gamma ramp support */
	if (fields & LIBGAMMA_CRTC_INFO_GAMMA_SUPPORT) {
		if (info.gamma_support_error)
			libgamma_perror("  (error) gamma support", info.gamma_support_error);
		else
			printf("  gamma support: %s\n", decision_str(info.gamma_support));
	}
	/* Print subpixel order for the monitor */
	if (fields & LIBGAMMA_CRTC_INFO_SUBPIXEL_ORDER) {
		if (info.subpixel_order_error)
			libgamma_perror("  (error) subpixel order", info.subpixel_order_error);
		else
			printf("  subpixel order: %s\n", subpixel_order_str(info.subpixel_order));
	}
	/* Print connector information */
	print(int, LIBGAMMA_CRTC_INFO_ACTIVE, "active", active);
	print(str, LIBGAMMA_CRTC_INFO_CONNECTOR_NAME, "connector name", connector_name);
	if (fields & LIBGAMMA_CRTC_INFO_CONNECTOR_TYPE) {
		if (info.connector_type_error)
			libgamma_perror("  (error) subpixel order", info.connector_type_error);
		else
			printf("  subpixel order: %s\n", connector_type_str(info.connector_type));
	}
	/* Print the gamma characteristics of the monitor */
	print2(float, LIBGAMMA_CRTC_INFO_GAMMA, "red gamma characteristics", gamma_red, gamma_error);
	print2(float, LIBGAMMA_CRTC_INFO_GAMMA, "green gamma characteristics", gamma_green, gamma_error);
	print2(float, LIBGAMMA_CRTC_INFO_GAMMA, "blue gamma characteristics", gamma_blue, gamma_error);
	printf("\n");


#undef print
#undef print2

	/* Release resouces */
	free(info.edid);
	free(info.connector_name);
}