From: Thierry Reding <treding@xxxxxxxxxx> Allow connector names to be used in the specification of the -s option. This requires storing the string passed on the command-line so that it can later be resolved to a connector ID (after the DRM device has been opened). Signed-off-by: Thierry Reding <treding@xxxxxxxxxx> --- tests/modetest/modetest.c | 134 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 123 insertions(+), 11 deletions(-) diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index d5fd99ebe1fd..a7cc94f8938c 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -82,6 +82,7 @@ struct connector { drmModeConnector *connector; drmModeObjectProperties *props; drmModePropertyRes **props_info; + char *name; }; struct fb { @@ -327,7 +328,7 @@ static void dump_connectors(struct device *dev) int i, j; printf("Connectors:\n"); - printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\tencoders\n"); + printf("id\tencoder\tstatus\t\tname\t\tsize (mm)\tmodes\tencoders\n"); for (i = 0; i < dev->resources->res->count_connectors; i++) { struct connector *_connector = &dev->resources->connectors[i]; drmModeConnector *connector = _connector->connector; @@ -338,7 +339,7 @@ static void dump_connectors(struct device *dev) connector->connector_id, connector->encoder_id, util_lookup_connector_status_name(connector->connection), - util_lookup_connector_type_name(connector->connector_type), + _connector->name, connector->mmWidth, connector->mmHeight, connector->count_modes); @@ -464,12 +465,13 @@ static void dump_planes(struct device *dev) static void free_resources(struct resources *res) { + int i; + if (!res) return; #define free_resource(_res, __res, type, Type) \ do { \ - int i; \ if (!(_res)->type##s) \ break; \ for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ @@ -482,7 +484,6 @@ static void free_resources(struct resources *res) #define free_properties(_res, __res, type) \ do { \ - int i; \ for (i = 0; i < (int)(_res)->__res->count_##type##s; ++i) { \ drmModeFreeObjectProperties(res->type##s[i].props); \ free(res->type##s[i].props_info); \ @@ -494,6 +495,10 @@ static void free_resources(struct resources *res) free_resource(res, res, crtc, Crtc); free_resource(res, res, encoder, Encoder); + + for (i = 0; i < res->res->count_connectors; i++) + free(res->connectors[i].name); + free_resource(res, res, connector, Connector); free_resource(res, res, fb, FB); @@ -511,6 +516,47 @@ static void free_resources(struct resources *res) free(res); } +static unsigned int get_connector_index(struct resources *res, uint32_t type) +{ + unsigned int index = 0; + int i; + + for (i = 0; i < res->res->count_connectors; i++) + if (res->connectors[i].connector->connector_type == type) + index++; + + return index - 1; +} + +static unsigned int get_order(unsigned int value) +{ + unsigned int order = 0; + + do { + value /= 10; + order++; + } while (value > 0); + + return order - 1; +} + +static void connector_set_name(struct connector *connector, + struct resources *res) +{ + uint32_t type = connector->connector->connector_type; + const char *type_name; + unsigned int index; + int len; + + type_name = util_lookup_connector_type_name(type); + index = get_connector_index(res, type); + len = strlen(type_name) + get_order(index) + 2; + + connector->name = malloc(len + 1); + if (connector->name) + snprintf(connector->name, len + 1, "%s-%u", type_name, index); +} + static struct resources *get_resources(struct device *dev) { struct resources *res; @@ -562,6 +608,12 @@ static struct resources *get_resources(struct device *dev) get_resource(res, res, connector, Connector); get_resource(res, res, fb, FB); + for (i = 0; i < res->res->count_connectors; i++) { + struct connector *connector = &res->connectors[i]; + + connector_set_name(connector, res); + } + #define get_properties(_res, __res, type, Type) \ do { \ int i; \ @@ -630,6 +682,21 @@ static int get_crtc_index(struct device *dev, uint32_t id) return -1; } +static drmModeConnector *get_connector_by_name(struct device *dev, const char *name) +{ + struct connector *connector; + int i; + + for (i = 0; i < dev->resources->res->count_connectors; i++) { + connector = &dev->resources->connectors[i]; + + if (strcmp(connector->name, name) == 0) + return connector->connector; + } + + return NULL; +} + static drmModeConnector *get_connector_by_id(struct device *dev, uint32_t id) { drmModeConnector *connector; @@ -670,6 +737,7 @@ static drmModeEncoder *get_encoder_by_id(struct device *dev, uint32_t id) * can bind it with a free crtc. */ struct pipe_arg { + const char **cons; uint32_t *con_ids; unsigned int num_cons; uint32_t crtc_id; @@ -784,8 +852,8 @@ static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe) pipe->mode_str, pipe->vrefresh); if (mode == NULL) { fprintf(stderr, - "failed to find mode \"%s\" for connector %u\n", - pipe->mode_str, pipe->con_ids[i]); + "failed to find mode \"%s\" for connector %s\n", + pipe->mode_str, pipe->cons[i]); return -EINVAL; } } @@ -1054,7 +1122,7 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co printf("setting mode %s-%dHz@%s on connectors ", pipe->mode_str, pipe->mode->vrefresh, pipe->format_str); for (j = 0; j < pipe->num_cons; ++j) - printf("%u, ", pipe->con_ids[j]); + printf("%s, ", pipe->cons[j]); printf("crtc %d\n", pipe->crtc->crtc->crtc_id); ret = drmModeSetCrtc(dev->fd, pipe->crtc->crtc->crtc_id, fb_id, @@ -1230,18 +1298,28 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg) /* Count the number of connectors and allocate them. */ pipe->num_cons = 1; - for (p = arg; isdigit(*p) || *p == ','; ++p) { + for (p = arg; *p && *p != ':' && *p != '@'; ++p) { if (*p == ',') pipe->num_cons++; } - pipe->con_ids = malloc(pipe->num_cons * sizeof *pipe->con_ids); + pipe->cons = malloc(pipe->num_cons * sizeof(*pipe->cons)); + if (pipe->cons == NULL) + return -1; + + 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); + endp = strpbrk(p, ",@:"); + + if (endp) + pipe->cons[i] = strndup(p, endp - p); + else + pipe->cons[i] = strdup(p); + if (*endp != ',') break; } @@ -1405,6 +1483,32 @@ static int cursor_supported(void) return 1; } +static int pipe_resolve_connectors(struct pipe_arg *pipe, struct device *dev) +{ + drmModeConnector *connector; + unsigned int i; + uint32_t id; + char *endp; + + for (i = 0; i < pipe->num_cons; i++) { + id = strtoul(pipe->cons[i], &endp, 10); + if (endp == pipe->cons[i]) { + connector = get_connector_by_name(dev, pipe->cons[i]); + if (!connector) { + fprintf(stderr, "no connector named %s\n", + pipe->cons[i]); + return -ENODEV; + } + + id = connector->connector_id; + } + + pipe->con_ids[i] = id; + } + + return 0; +} + static char optstr[] = "cdD:efM:P:ps:Cvw:"; int main(int argc, char **argv) @@ -1420,7 +1524,7 @@ int main(int argc, char **argv) char *device = NULL; char *module = NULL; unsigned int i; - int count = 0, plane_count = 0; + unsigned int count = 0, plane_count = 0; unsigned int prop_count = 0; struct pipe_arg *pipe_args = NULL; struct plane_arg *plane_args = NULL; @@ -1559,6 +1663,14 @@ int main(int argc, char **argv) return 1; } + for (i = 0; i < count; i++) { + if (pipe_resolve_connectors(&pipe_args[i], &dev) < 0) { + free_resources(dev.resources); + drmClose(dev.fd); + return 1; + } + } + #define dump_resource(dev, res) if (res) dump_##res(dev) dump_resource(&dev, encoders); -- 2.1.3 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel