<para>All controls are accessed using an ID value. V4L2 defines
several IDs for specific purposes. Drivers can also implement their
own custom controls using <constant>V4L2_CID_PRIVATE_BASE</constant>
+<footnote><para>The use of <constant>V4L2_CID_PRIVATE_BASE</constant>
+is problematic because different drivers may use the same
+<constant>V4L2_CID_PRIVATE_BASE</constant> ID for different controls.
+This makes it hard to programatically set such controls since the meaning
+of the control with that ID is driver dependent. In order to resolve this
+drivers use unique IDs and the <constant>V4L2_CID_PRIVATE_BASE</constant>
+IDs are mapped to those unique IDs by the kernel. Consider these
+<constant>V4L2_CID_PRIVATE_BASE</constant> IDs as aliases to the real
+IDs.</para>
+<para>Many applications today still use the <constant>V4L2_CID_PRIVATE_BASE</constant>
+IDs instead of using &VIDIOC-QUERYCTRL; with the <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant>
+flag to enumerate all IDs, so support for <constant>V4L2_CID_PRIVATE_BASE</constant>
+is still around.</para></footnote>
and higher values. The pre-defined control IDs have the prefix
<constant>V4L2_CID_</constant>, and are listed in <xref
linkend="control-id" />. The ID is used when querying the attributes of
or output. Different in the sense of other bounds, another default and
current value, step size or other menu items. A control with a certain
<emphasis>custom</emphasis> ID can also change name and
-type.<footnote>
- <para>It will be more convenient for applications if drivers
-make use of the <constant>V4L2_CTRL_FLAG_DISABLED</constant> flag, but
-that was never required.</para>
- </footnote> Control values are stored globally, they do not
+type.</para>
+
+ <para>If a control is not applicable to the current configuration
+of the device (for example, it doesn't apply to the current video input)
+drivers set the <constant>V4L2_CTRL_FLAG_INACTIVE</constant> flag.</para>
+
+ <para>Control values are stored globally, they do not
change when switching except to stay within the reported bounds. They
also do not change ⪚ when the device is opened or closed, when the
tuner radio frequency is changed or generally never without
-application request. Since V4L2 specifies no event mechanism, panel
-applications intended to cooperate with other panel applications (be
-they built into a larger application, as a TV viewer) may need to
-regularly poll control values to update their user
-interface.<footnote>
- <para>Applications could call an ioctl to request events.
-After another process called &VIDIOC-S-CTRL; or another ioctl changing
-shared properties the &func-select; function would indicate
-readability until any ioctl (querying the properties) is
-called.</para>
- </footnote></para>
+application request.</para>
+
+ <para>V4L2 specifies an event mechanism to notify applications
+when controls change value (see &VIDIOC-SUBSCRIBE-EVENT;, event
+<constant>V4L2_EVENT_CTRL</constant>), panel applications might want to make
+use of that in order to always reflect the correct control value.</para>
<para>
All controls use machine endianness.
controls, <constant>VIDIOC_QUERYMENU</constant> when it has one or
more menu type controls.</para>
- <example>
- <title>Enumerating all controls</title>
+ <example id="enum_all_controls">
+ <title>Enumerating all user controls</title>
<programlisting>
&v4l2-queryctrl; queryctrl;
</programlisting>
</example>
+ <example>
+ <title>Enumerating all user controls (alternative)</title>
+ <programlisting>
+memset(&queryctrl, 0, sizeof(queryctrl));
+
+queryctrl.id = V4L2_CTRL_CLASS_USER | V4L2_CTRL_FLAG_NEXT_CTRL;
+while (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &queryctrl)) {
+ if (V4L2_CTRL_ID2CLASS(queryctrl.id) != V4L2_CTRL_CLASS_USER)
+ break;
+ if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
+ continue;
+
+ printf("Control %s\n", queryctrl.name);
+
+ if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
+ enumerate_menu();
+
+ queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+}
+if (errno != EINVAL) {
+ perror("VIDIOC_QUERYCTRL");
+ exit(EXIT_FAILURE);
+}
+</programlisting>
+ </example>
+
<example>
<title>Changing controls</title>
<constant>VIDIOC_QUERYCTRL</constant> will fail when used in
combination with <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant>. In
that case the old method of enumerating control should be used (see
-1.8). But if it is supported, then it is guaranteed to enumerate over
+<xref linkend="enum_all_controls" />). But if it is supported, then it is guaranteed to enumerate over
all controls, including driver-private controls.</para>
</section>