/* 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;
}