+ unsigned int len;
+ unsigned int i;
+ const char *p;
+ char *endp;
+
+ pipe->vrefresh = 0;
+ pipe->crtc_id = (uint32_t)-1;
+ strcpy(pipe->format_str, "XR24");
+
+ /* Count the number of connectors and allocate them. */
+ pipe->num_cons = 1;
+ for (p = arg; isdigit(*p) || *p == ','; ++p) {
+ if (*p == ',')
+ pipe->num_cons++;
+ }
+
+ pipe->con_ids = malloc(pipe->num_cons * sizeof *pipe->con_ids);
+ if (pipe->con_ids == NULL)
+ return -1;
+
+ /* Parse the connectors. */
+ for (i = 0, p = arg; i < pipe->num_cons; ++i, p = endp + 1) {
+ pipe->con_ids[i] = strtoul(p, &endp, 10);
+ if (*endp != ',')
+ break;
+ }
+
+ if (i != pipe->num_cons - 1)
+ return -1;
+
+ /* Parse the remaining parameters. */
+ if (*endp == '@') {
+ arg = endp + 1;
+ pipe->crtc_id = strtoul(arg, &endp, 10);
+ }
+ if (*endp != ':')
+ return -1;
+
+ arg = endp + 1;
+
+ /* Search for the vertical refresh or the format. */
+ p = strpbrk(arg, "-@");
+ if (p == NULL)
+ p = arg + strlen(arg);
+ len = min(sizeof pipe->mode_str - 1, (unsigned int)(p - arg));
+ strncpy(pipe->mode_str, arg, len);
+ pipe->mode_str[len] = '\0';
+
+ if (*p == '-') {
+ pipe->vrefresh = strtoul(p + 1, &endp, 10);
+ p = endp;
+ }
+
+ if (*p == '@') {
+ strncpy(pipe->format_str, p + 1, 4);
+ pipe->format_str[4] = '\0';
+ }
+
+ pipe->fourcc = format_fourcc(pipe->format_str);
+ if (pipe->fourcc == 0) {
+ fprintf(stderr, "unknown format %s\n", pipe->format_str);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int parse_plane(struct plane_arg *plane, const char *p)
+{
+ char *end;
+
+ memset(plane, 0, sizeof *plane);
+
+ plane->crtc_id = strtoul(p, &end, 10);
+ if (*end != ':')
+ return -EINVAL;
+
+ p = end + 1;
+ plane->w = strtoul(p, &end, 10);
+ if (*end != 'x')
+ return -EINVAL;
+
+ p = end + 1;
+ plane->h = strtoul(p, &end, 10);
+
+ if (*end == '+' || *end == '-') {
+ plane->x = strtol(end, &end, 10);
+ if (*end != '+' && *end != '-')
+ return -EINVAL;
+ plane->y = strtol(end, &end, 10);
+
+ plane->has_position = true;
+ }
+
+ if (*end == '*') {
+ p = end + 1;
+ plane->scale = strtod(p, &end);
+ if (plane->scale <= 0.0)
+ return -EINVAL;
+ } else {
+ plane->scale = 1.0;
+ }
+
+ if (*end == '@') {
+ p = end + 1;
+ if (strlen(p) != 4)
+ return -EINVAL;
+
+ strcpy(plane->format_str, p);
+ } else {
+ strcpy(plane->format_str, "XR24");
+ }
+
+ plane->fourcc = format_fourcc(plane->format_str);
+ if (plane->fourcc == 0) {
+ fprintf(stderr, "unknown format %s\n", plane->format_str);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int parse_property(struct property_arg *p, const char *arg)
+{
+ if (sscanf(arg, "%d:%32[^:]:%" SCNu64, &p->obj_id, p->name, &p->value) != 3)
+ return -1;
+
+ p->obj_type = 0;
+ p->name[DRM_PROP_NAME_LEN] = '\0';
+
+ return 0;
+}
+
+static void usage(char *name)
+{
+ fprintf(stderr, "usage: %s [-cDdefMPpsCvw]\n", name);
+
+ fprintf(stderr, "\n Query options:\n\n");