aboutsummaryrefslogtreecommitdiffstats
path: root/libcoopgamma_get_crtcs_recv.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcoopgamma_get_crtcs_recv.c')
-rw-r--r--libcoopgamma_get_crtcs_recv.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/libcoopgamma_get_crtcs_recv.c b/libcoopgamma_get_crtcs_recv.c
new file mode 100644
index 0000000..16e9ba5
--- /dev/null
+++ b/libcoopgamma_get_crtcs_recv.c
@@ -0,0 +1,70 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+/**
+ * List all available CRTC:s, receive response part
+ *
+ * @param ctx The state of the library, must be connected
+ * @param async Information about the request
+ * @return A `NULL`-terminated list of names. You should only free
+ * the outer pointer, inner pointers are subpointers of the
+ * outer pointer and cannot be freed. `NULL` on error, in
+ * which case `ctx->error` (rather than `errno`) is read
+ * for information about the error.
+ */
+char **
+libcoopgamma_get_crtcs_recv(libcoopgamma_context_t *restrict ctx, libcoopgamma_async_context_t *restrict async)
+{
+ char *line;
+ char *payload;
+ char *end;
+ int command_ok = 0;
+ size_t i, n, lines, len, length;
+ char **rc;
+
+ if (libcoopgamma_check_error__(ctx, async))
+ return NULL;
+
+ for (;;) {
+ line = libcoopgamma_next_header__(ctx);
+ if (!*line)
+ break;
+ else if (!strcmp(line, "Command: crtc-enumeration"))
+ command_ok = 1;
+ }
+
+ payload = libcoopgamma_next_payload__(ctx, &n);
+
+ if (!command_ok || (n > 0 && payload[n - 1U] != '\n')) {
+ errno = EBADMSG;
+ copy_errno(ctx);
+ return NULL;
+ }
+
+ line = payload;
+ end = &payload[n];
+ lines = length = 0;
+ while (line != end) {
+ lines += 1U;
+ length += len = (size_t)(&strchr(line, '\n')[1U] - line);
+ line += len;
+ line[-1] = '\0';
+ }
+
+ rc = malloc((lines + 1U) * sizeof(char *) + length);
+ if (!rc) {
+ copy_errno(ctx);
+ return NULL;
+ }
+
+ line = ((char *)rc) + (lines + 1U) * sizeof(char *);
+ memcpy(line, payload, length);
+ rc[lines] = NULL;
+ for (i = 0; i < lines; i++) {
+ rc[i] = line;
+ line = &strchr(line, '\0')[1U];
+ }
+
+ return rc;
+}