Separate iteration over controls from printing, in order to reuse the
iteration to implement control reset.

Signed-off-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
---
 yavta.c | 134 +++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 83 insertions(+), 51 deletions(-)

diff --git a/yavta.c b/yavta.c
index 2d3b2d096f7d..607a2883af4c 100644
--- a/yavta.c
+++ b/yavta.c
@@ -484,9 +484,12 @@ static int query_control(struct device *dev, unsigned int 
id,
        query->id = id;
 
        ret = ioctl(dev->fd, VIDIOC_QUERYCTRL, query);
-       if (ret < 0 && errno != EINVAL)
-               printf("unable to query control 0x%8.8x: %s (%d).\n",
-                      id, strerror(errno), errno);
+       if (ret < 0) {
+               ret = -errno;
+               if (ret != -EINVAL)
+                       printf("unable to query control 0x%8.8x: %s (%d).\n",
+                              id, strerror(errno), errno);
+       }
 
        return ret;
 }
@@ -1120,7 +1123,46 @@ static int video_enable(struct device *dev, int enable)
        return 0;
 }
 
-static void video_query_menu(struct device *dev, struct v4l2_queryctrl *query,
+static int video_for_each_control(struct device *dev,
+                                 int(*callback)(struct device *dev, void 
*data, const struct v4l2_queryctrl *query),
+                                 void *data)
+{
+       struct v4l2_queryctrl query;
+       unsigned int nctrls = 0;
+       unsigned int id;
+       int ret;
+
+#ifndef V4L2_CTRL_FLAG_NEXT_CTRL
+       unsigned int i;
+
+       for (i = V4L2_CID_BASE; i <= V4L2_CID_LASTP1; ++i) {
+               id = i;
+#else
+       id = 0;
+       while (1) {
+               id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+#endif
+
+               ret = query_control(dev, id, &query);
+               if (ret == -EINVAL)
+                       break;
+               if (ret < 0)
+                       return ret;
+
+               id = query.id;
+
+               ret = callback(dev, data, &query);
+               if (ret < 0)
+                       return ret;
+
+               if (ret)
+                       nctrls++;
+       }
+
+       return nctrls;
+}
+
+static void video_query_menu(struct device *dev, const struct v4l2_queryctrl 
*query,
                             unsigned int value)
 {
        struct v4l2_querymenu menu;
@@ -1142,83 +1184,68 @@ static void video_query_menu(struct device *dev, struct 
v4l2_queryctrl *query,
        };
 }
 
-static int video_print_control(struct device *dev, unsigned int id, bool full)
+static int video_print_control(struct device *dev,
+                              const struct v4l2_queryctrl *query, bool full)
 {
        struct v4l2_ext_control ctrl;
-       struct v4l2_queryctrl query;
        char sval[24];
        char *current = sval;
        int ret;
 
-       ret = query_control(dev, id, &query);
-       if (ret < 0)
-               return ret;
+       if (query->flags & V4L2_CTRL_FLAG_DISABLED)
+               return 1;
 
-       if (query.flags & V4L2_CTRL_FLAG_DISABLED)
-               return query.id;
-
-       if (query.type == V4L2_CTRL_TYPE_CTRL_CLASS) {
-               printf("--- %s (class 0x%08x) ---\n", query.name, query.id);
-               return query.id;
+       if (query->type == V4L2_CTRL_TYPE_CTRL_CLASS) {
+               printf("--- %s (class 0x%08x) ---\n", query->name, query->id);
+               return 1;
        }
 
-       ret = get_control(dev, &query, &ctrl);
+       ret = get_control(dev, query, &ctrl);
        if (ret < 0)
                strcpy(sval, "n/a");
-       else if (query.type == V4L2_CTRL_TYPE_INTEGER64)
+       else if (query->type == V4L2_CTRL_TYPE_INTEGER64)
                sprintf(sval, "%lld", ctrl.value64);
-       else if (query.type == V4L2_CTRL_TYPE_STRING)
+       else if (query->type == V4L2_CTRL_TYPE_STRING)
                current = ctrl.string;
        else
                sprintf(sval, "%d", ctrl.value);
 
        if (full)
                printf("control 0x%08x `%s' min %d max %d step %d default %d 
current %s.\n",
-                       query.id, query.name, query.minimum, query.maximum,
-                       query.step, query.default_value, current);
+                       query->id, query->name, query->minimum, query->maximum,
+                       query->step, query->default_value, current);
        else
-               printf("control 0x%08x current %s.\n", query.id, current);
+               printf("control 0x%08x current %s.\n", query->id, current);
 
-       if (query.type == V4L2_CTRL_TYPE_STRING)
+       if (query->type == V4L2_CTRL_TYPE_STRING)
                free(ctrl.string);
 
        if (!full)
-               return query.id;
+               return 1;
 
-       if (query.type == V4L2_CTRL_TYPE_MENU ||
-           query.type == V4L2_CTRL_TYPE_INTEGER_MENU)
-               video_query_menu(dev, &query, ctrl.value);
+       if (query->type == V4L2_CTRL_TYPE_MENU ||
+           query->type == V4L2_CTRL_TYPE_INTEGER_MENU)
+               video_query_menu(dev, query, ctrl.value);
 
-       return query.id;
+       return 1;
+}
+
+static int __video_print_control(struct device *dev, void *data,
+                                const struct v4l2_queryctrl *query)
+{
+       return video_print_control(dev, query, (bool)data);
 }
 
 static void video_list_controls(struct device *dev)
 {
-       unsigned int nctrls = 0;
-       unsigned int id;
        int ret;
 
-#ifndef V4L2_CTRL_FLAG_NEXT_CTRL
-       unsigned int i;
+       ret = video_for_each_control(dev, __video_print_control, (void *)true);
+       if (ret < 0)
+               return;
 
-       for (i = V4L2_CID_BASE; i <= V4L2_CID_LASTP1; ++i) {
-               id = i;
-#else
-       id = 0;
-       while (1) {
-               id |= V4L2_CTRL_FLAG_NEXT_CTRL;
-#endif
-
-               ret = video_print_control(dev, id, true);
-               if (ret < 0)
-                       break;
-
-               id = ret;
-               nctrls++;
-       }
-
-       if (nctrls)
-               printf("%u control%s found.\n", nctrls, nctrls > 1 ? "s" : "");
+       if (ret)
+               printf("%u control%s found.\n", ret, ret > 1 ? "s" : "");
        else
                printf("No control found.\n");
 }
@@ -2184,8 +2211,13 @@ int main(int argc, char *argv[])
        if (do_log_status)
                video_log_status(&dev);
 
-       if (do_get_control)
-               video_print_control(&dev, ctrl_name, false);
+       if (do_get_control) {
+               struct v4l2_queryctrl query;
+
+               ret = query_control(&dev, ctrl_name, &query);
+               if (ret == 0)
+                       video_print_control(&dev, &query, false);
+       }
 
        if (do_set_control)
                set_control(&dev, ctrl_name, ctrl_value);
-- 
Regards,

Laurent Pinchart

Reply via email to