summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-02-19 17:34:07 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-02-20 14:39:40 +0200
commit157e3a357b9792a9179f3a178898483a25dd4edc (patch)
tree625e71294a3c3d75b52b8966efb7a00654e38a5f
parent6fcc59050fc03afde84a73082bed9b891a35708a (diff)
yavta: Refactor video_list_controls()
Separate iteration over controls from printing, in order to reuse the iteration to implement control reset. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--yavta.c133
1 files changed, 82 insertions, 51 deletions
diff --git a/yavta.c b/yavta.c
index 2d3b2d0..98bc098 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,45 @@ 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, const struct v4l2_queryctrl *query))
+{
+ 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, &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 +1183,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 query.id;
+ if (query->flags & V4L2_CTRL_FLAG_DISABLED)
+ return 0;
- 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 0;
}
- 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 1;
+}
- return query.id;
+static int __video_print_control(struct device *dev,
+ const struct v4l2_queryctrl *query)
+{
+ return video_print_control(dev, query, true);
}
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;
-
- 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++;
- }
+ ret = video_for_each_control(dev, __video_print_control);
+ if (ret < 0)
+ return;
- 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 +2210,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);