aboutsummaryrefslogtreecommitdiffstats
path: root/common.h
blob: 2daa9941cd66e78e3e91383909f1d28fc49f8404 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
/* 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);