aboutsummaryrefslogblamecommitdiffstats
path: root/common.h
blob: 2daa9941cd66e78e3e91383909f1d28fc49f8404 (plain) (tree)








































































































































































































































































































































































































                                                                                                                             
/* See LICENSE file for copyright and license details. */
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

#include <xf86drm.h>
#include <xf86drmMode.h>


/**
 * Framebuffer information
 */
typedef struct framebuffer
{
	/**
	 * The file descriptor used to access the framebuffer, -1 if not opened
	 */
	int fd;

	/**
	 * The width of the display in pixels
	 */
	uint32_t width;

	/**
	 * The height of the display in pixels
	 */
	uint32_t height;

	/**
	 * Increment for `mem` to move to next pixel on the line
	 */
	uint32_t bytes_per_pixel;

	/**
	 * Increment for `mem` to move down one line but stay in the same column
	 */
	uint32_t line_length;

	/**
	 * Framebuffer pointer, `MAP_FAILED` (from <sys/mman.h>) if not mapped
	 */
	int8_t *mem;

} framebuffer_t;


/**
 * Graphics card information
 */
typedef struct drm_card
{
	/**
	 * File descriptor for the connection to the graphics card,
	 * -1 if not opened
	 */
	int fd;

	/**
	 * The graphics card's mode resources, `NULL` if not acquired
	 */
	drmModeRes *restrict res;

	/**
	 * The number of CRTC:s available on the graphics card
	 */
	size_t crtc_count;

	/**
	 * The available connectors
	 */
	drmModeConnector **restrict connectors;

	/**
	 * The available encoders
	 */
	drmModeEncoder **restrict encoders;

	/**
	 * The number of connectors and encoders
	 */
	size_t connector_count;

} drm_card_t;


/**
 * CRT controller information
 */
typedef struct drm_crtc
{
	/**
	 * CRT controller identifier
	 */
	uint32_t id;

	/**
	 * The graphics card
	 */
	drm_card_t *restrict card;

	/**
	 * The CRT controller's connector
	 */
	drmModeConnector *restrict connector;

	/**
	 * The CRT controller's encoder
	 */
	drmModeEncoder *restrict encoder;

	/**
	 * Whether the connector is connected
	 */
	int connected;

	/**
	 * The CRT's EDID, hexadecimally encoded
	 */
	char *restrict edid;

	/**
	 * The number of stops on the gamma ramps
	 */
	size_t gamma_stops;

	/**
	 * The gamma ramp for the red channel
	 */
	uint16_t *restrict red;

	/**
	 * The gamma ramp for the green channel
	 */
	uint16_t *restrict green;

	/**
	 * The gamma ramp for the blue channel
	 */
	uint16_t *restrict blue;

} drm_crtc_t;



/***** gamma.c *****/

/**
 * Analyse a gamma ramp
 * 
 * @param  stops       The number of stops in the gamma ramp
 * @param  ramp        The gamma ramp
 * @param  gamma       Output parameter for the gamma
 * @param  contrast    Output parameter for the contrast
 * @param  brightness  Output parameter for the brightness
 */
void gamma_analyse(size_t stops, const uint16_t* restrict ramp, double *restrict gamma,
                   double *restrict contrast, double* restrict brightness);

/**
 * Generate a gamma ramp
 * 
 * @param  stops       The number of stops in the gamma ramp
 * @param  ramp        Memory area to where to write the gamma ramp
 * @param  gamma       The gamma
 * @param  contrast    The contrast
 * @param  brightness  The brightness
 */
void gamma_generate(size_t stops, uint16_t *restrict ramp, double gamma, double contrast, double brightness);



/***** framebuffer.c *****/

/**
 * Figure out how many framebuffers there are on the system
 * 
 * @return  The number of framebuffers on the system
 */
size_t fb_count(void);

/**
 * Open a framebuffer
 * 
 * @param   index  The index of the framebuffer to open
 * @param   fb     Framebuffer information to fill in
 * @return         Zero on success, -1 on error
 */
int fb_open(size_t index, framebuffer_t *restrict fb);

/**
 * Close a framebuffer
 * 
 * @param  fb  The framebuffer information
 */
void fb_close(framebuffer_t *restrict fb);

/**
 * Construct an sRGB colour in 32-bit XRGB encoding to
 * use when specifying colours
 * 
 * @param   red    The red   component from [0, 255] sRGB
 * @param   green  The green component from [0, 255] sRGB
 * @param   blue   The blue  component from [0, 255] sRGB
 * @return         The colour as one 32-bit integer
 */
#ifdef __GNUC__
__attribute__((__const__))
#endif
uint32_t fb_colour(int red, int green, int blue);

/**
 * Print a filled in rectangle to a framebuffer
 * 
 * @param  fb      The framebuffer
 * @param  colour  The colour to use when drawing the rectangle
 * @param  x       The starting pixel on the X axis for the rectangle
 * @param  y       The starting pixel on the Y axis for the rectangle
 * @param  width   The width of the rectangle, in pixels
 * @param  height  The height of the rectangle, in pixels
 */
void fb_fill_rectangle(framebuffer_t *restrict fb, uint32_t colour, uint32_t x, uint32_t y, uint32_t width, uint32_t height);

/**
 * Draw a horizontal line segment on a framebuffer
 * 
 * @param  fb      The framebuffer
 * @param  colour  The colour to use when drawing the rectangle
 * @param  x       The starting pixel on the X axis for the line segment
 * @param  y       The starting pixel on the Y axis for the line segment
 * @param  length  The length of the line segment, in pixels
 */
void fb_draw_horizontal_line(framebuffer_t *restrict fb, uint32_t colour, uint32_t x, uint32_t y, uint32_t length);

/**
 * Draw a vertical line segment on a framebuffer
 * 
 * @param  fb      The framebuffer
 * @param  colour  The colour to use when drawing the rectangle
 * @param  x       The starting pixel on the X axis for the line segment
 * @param  y       The starting pixel on the Y axis for the line segment
 * @param  length  The length of the line segment, in pixels
 */
void fb_draw_vertical_line(framebuffer_t *restrict fb, uint32_t colour, uint32_t x, uint32_t y, uint32_t length);

/**
 * Draw a single on a framebuffer
 * 
 * @param  fb      The framebuffer
 * @param  colour  The colour to use when drawing the rectangle
 * @param  x       The pixel's position on the X axis
 * @param  y       The pixel's position on the Y axis
 */
static inline void
fb_draw_pixel(framebuffer_t *restrict fb, uint32_t colour, uint32_t x, uint32_t y)
{
	int8_t *mem = fb->mem + y * fb->line_length + x * fb->bytes_per_pixel;
	*(uint32_t *)mem = colour;
}



/***** state.c ******/

/**
 * The framebuffers on the system
 */
extern framebuffer_t *restrict framebuffers;

/**
 * The number of elements in `framebuffers`
 */
extern size_t framebuffer_count;

/**
 * The graphics cards on the system
 */
extern drm_card_t *restrict cards;

/**
 * The number of elements in `cards`
 */
extern size_t card_count;

/**
 * The connected CRT controllers on the system
 */
extern drm_crtc_t *restrict crtcs;

/**
 * The software brightness setting on each connected CRT controller, on each channel
 */
extern double *restrict brightnesses[3];

/**
 * The software contrast setting on each connected CRT controller, on each channel
 */
extern double *restrict contrasts[3];

/**
 * The gamma correction on each connected CRT controller, on each channel
 */
extern double *restrict gammas[3];

/**
 * The number of elements in `crtcs`, `brightnesses[]`, `contrasts[]` and `gammas[]`
 */
extern size_t crtc_count;

/**
 * Acquire video control
 * 
 * @return  Zero on success, -1 on error
 */
int acquire_video(void);

/**
 * Release video control
 */
void release_video(void);



/***** drmgamma.c ******/

/**
 * Figure out how many graphics cards there are on the system
 * 
 * @return  The number of graphics cards on the system
 */
size_t drm_card_count(void);

/**
 * Acquire access to a graphics card
 * 
 * @param   index  The index of the graphics card
 * @param   card   Graphics card information to fill in
 * @return         Zero on success, -1 on error
 */
int drm_card_open(size_t index, drm_card_t *restrict card);

/**
 * Release access to a graphics card
 * 
 * @param  card  The graphics card information
 */
void drm_card_close(drm_card_t *restrict card);

/**
 * Acquire access to a CRT controller
 * 
 * @param   index  The index of the CRT controller
 * @param   card   The graphics card information
 * @param   crtc   CRT controller information to fill in
 * @return         Zero on success, -1 on error
 */
int drm_crtc_open(size_t index, drm_card_t *restrict card, drm_crtc_t *restrict crtc);

/**
 * Release access to a CRT controller
 * 
 * @param  crtc  The CRT controller information to fill in
 */
void drm_crtc_close(drm_crtc_t *restrict crtc);

/**
 * Read the gamma ramps for a CRT controller
 * 
 * @param   crtc  CRT controller information
 * @return        Zero on success, -1 on error 
 */
int drm_get_gamma(drm_crtc_t *restrict crtc);

/**
 * Apply gamma ramps for a CRT controller
 * 
 * @param   crtc  CRT controller information
 * @return        Zero on success, -1 on error
 */
int drm_set_gamma(drm_crtc_t *restrict crtc);