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);
|