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
|
/* See LICENSE file for copyright and license details. */
#include "common.h"
/**
* Retrieve information about a CRTC:s gamma ramps, receive response part
*
* @param info Output parameter for the information, must be initialised
* @param ctx The state of the library, must be connected
* @param async Information about the request
* @return Zero on success, -1 on error, in which case `ctx->error`
* (rather than `errno`) is read for information about the error
*/
int
libcoopgamma_get_gamma_info_recv(libcoopgamma_crtc_info_t *restrict info, libcoopgamma_context_t *restrict ctx,
libcoopgamma_async_context_t *restrict async)
{
char temp[3 * sizeof(size_t) + 1];
char *line;
char *value;
size_t _n;
int have_cooperative = 0, have_gamma_support = 0, have_colourspace = 0;
int have_depth = 0, have_white_x = 0, have_white_y = 0;
int have_red_size = 0, have_red_x = 0, have_red_y = 0;
int have_green_size = 0, have_green_x = 0, have_green_y = 0;
int have_blue_size = 0, have_blue_x = 0, have_blue_y = 0;
int bad = 0, r = 0, g = 0, b = 0, x = 0;
size_t *outz;
unsigned *outu;
int *have;
if (libcoopgamma_check_error__(ctx, async))
return -1;
info->cooperative = 0; /* Should be in the response, but ... */
info->colourspace = LIBCOOPGAMMA_UNKNOWN;
for (;;) {
line = libcoopgamma_next_header__(ctx);
value = &strchr(line, ':')[2U];
if (!*line) {
break;
} else if (strstr(line, "Cooperative: ") == line) {
have_cooperative = 1 + !!have_cooperative;
if (!strcmp(value, "yes")) info->cooperative = 1;
else if (!strcmp(value, "no")) info->cooperative = 0;
else
bad = 1;
} else if (strstr(line, "Depth: ") == line) {
have_depth = 1 + !!have_depth;
if (!strcmp(value, "8")) info->depth = LIBCOOPGAMMA_UINT8;
else if (!strcmp(value, "16")) info->depth = LIBCOOPGAMMA_UINT16;
else if (!strcmp(value, "32")) info->depth = LIBCOOPGAMMA_UINT32;
else if (!strcmp(value, "64")) info->depth = LIBCOOPGAMMA_UINT64;
else if (!strcmp(value, "f")) info->depth = LIBCOOPGAMMA_FLOAT;
else if (!strcmp(value, "d")) info->depth = LIBCOOPGAMMA_DOUBLE;
else
bad = 1;
} else if (strstr(line, "Gamma support: ") == line) {
have_gamma_support = 1 + !!have_gamma_support;
if (!strcmp(value, "yes")) info->supported = LIBCOOPGAMMA_YES;
else if (!strcmp(value, "no")) info->supported = LIBCOOPGAMMA_NO;
else if (!strcmp(value, "maybe")) info->supported = LIBCOOPGAMMA_MAYBE;
else
bad = 1;
} else if ((r = (strstr(line, "Red size: ") == line)) ||
(g = (strstr(line, "Green size: ") == line)) ||
strstr(line, "Blue size: ") == line) {
if (r) have_red_size = 1 + !!have_red_size, outz = &info->red_size;
else if (g) have_green_size = 1 + !!have_green_size, outz = &info->green_size;
else have_blue_size = 1 + !!have_blue_size, outz = &info->blue_size;
*outz = (size_t)atol(value);
sprintf(temp, "%zu", *outz);
if (strcmp(value, temp))
bad = 1;
} else if ((x = r = (strstr(line, "Red x: ") == line)) ||
(r = (strstr(line, "Red y: ") == line)) ||
(x = g = (strstr(line, "Green x: ") == line)) ||
(g = (strstr(line, "Green y: ") == line)) ||
(x = b = (strstr(line, "Blue x: ") == line)) ||
(b = (strstr(line, "Blue y: ") == line)) ||
(x = (strstr(line, "White x: ") == line)) ||
strstr(line, "White y: ") == line) {
if (r && x) have = &have_red_x, outu = &info->red_x;
else if (r) have = &have_red_y, outu = &info->red_y;
else if (g && x) have = &have_green_x, outu = &info->green_x;
else if (g) have = &have_green_y, outu = &info->green_y;
else if (b && x) have = &have_blue_x, outu = &info->blue_x;
else if (b) have = &have_blue_y, outu = &info->blue_y;
else if (x) have = &have_white_x, outu = &info->white_x;
else have = &have_white_y, outu = &info->white_y;
*have = 1 + !!*have;
*outu = (unsigned)atoi(value);
sprintf(temp, "%u", *outu);
if (strcmp(value, temp))
bad = 1;
} else if (strstr(line, "Colour space: ") == line) {
have_colourspace = 1 + !!have_colourspace;
if (!strcmp(value, "sRGB")) info->colourspace = LIBCOOPGAMMA_SRGB;
else if (!strcmp(value, "RGB")) info->colourspace = LIBCOOPGAMMA_RGB;
else if (!strcmp(value, "non-RGB")) info->colourspace = LIBCOOPGAMMA_NON_RGB;
else if (!strcmp(value, "grey")) info->colourspace = LIBCOOPGAMMA_GREY;
else
info->colourspace = LIBCOOPGAMMA_UNKNOWN;
}
}
(void) libcoopgamma_next_payload__(ctx, &_n);
info->have_gamut = (have_red_x && have_green_x && have_blue_x && have_white_x &&
have_red_y && have_green_y && have_blue_y && have_white_y);
if (bad || have_gamma_support != 1 || have_red_x > 1 || have_red_y > 1 ||
have_green_x > 1 || have_green_y > 1 || have_blue_x > 1 || have_blue_y > 1 ||
have_white_x > 1 || have_white_y > 1 || have_colourspace > 1) {
errno = EBADMSG;
copy_errno(ctx);
return -1;
}
if (info->supported != LIBCOOPGAMMA_NO) {
if (have_cooperative > 1 || have_depth != 1 || have_gamma_support != 1 ||
have_red_size != 1 || have_green_size != 1 || have_blue_size != 1) {
errno = EBADMSG;
copy_errno(ctx);
return -1;
}
}
return 0;
}
|