1 //:
2 // \file
3 //
4 // \author Antonio Garrido
5 // \verbatim
6 // Modifications
7 // 10 Nov 2008 Created (A. Garrido)
8 //\endverbatim
9
10
11 #include <cstdio>
12 #include <cstring>
13 #include <iostream>
14 #include "vidl_v4l2_control.h"
15 #ifdef _MSC_VER
16 # include "vcl_msvc_warnings.h"
17 #endif
18
19 extern "C"
20 {
21 #include <sys/ioctl.h>
22 };
23
24 vidl_v4l2_control *
new_control(const v4l2_queryctrl & ctr,int f)25 vidl_v4l2_control::new_control(const v4l2_queryctrl & ctr, int f)
26 {
27 if ((ctr.flags & V4L2_CTRL_FLAG_DISABLED)
28 #ifdef V4L2_CTRL_FLAG_INACTIVE
29 || (ctr.flags & V4L2_CTRL_FLAG_INACTIVE)
30 #endif
31 )
32 return 0;
33 switch (ctr.type)
34 {
35 case V4L2_CTRL_TYPE_INTEGER:
36 return new vidl_v4l2_control_integer(ctr, f);
37 break;
38 case V4L2_CTRL_TYPE_BOOLEAN:
39 return new vidl_v4l2_control_boolean(ctr, f);
40 break;
41 case V4L2_CTRL_TYPE_MENU: {
42 vidl_v4l2_control_menu * p = new vidl_v4l2_control_menu(ctr, f);
43 if (p->n_items() == 0)
44 {
45 delete p;
46 p = 0;
47 }
48 return p;
49 }
50 break;
51 case V4L2_CTRL_TYPE_BUTTON:
52 return new vidl_v4l2_control_button(ctr, f);
53 break;
54 default:
55 break;
56 }
57
58 return 0;
59 }
60
61 void
set_value(int v) const62 vidl_v4l2_control::set_value(int v) const
63 {
64 struct v4l2_control control;
65 std::memset(&control, 0, sizeof(control));
66 control.id = ctrl_.id;
67 control.value = v;
68 ioctl(fd, VIDIOC_S_CTRL, &control); // error ignored
69 }
70
71 int
get_value() const72 vidl_v4l2_control::get_value() const
73 {
74 struct v4l2_control control;
75 std::memset(&control, 0, sizeof(control));
76 control.id = ctrl_.id;
77 ioctl(fd, VIDIOC_G_CTRL, &control); // error ignored
78 return control.value;
79 }
80
81 // ----------------- Control integer ---------------
82
83 void
set(int value) const84 vidl_v4l2_control_integer::set(int value) const
85 {
86 if (value < ctrl_.minimum)
87 value = ctrl_.minimum;
88 else if (value > ctrl_.maximum)
89 value = ctrl_.maximum;
90 else
91 value = ctrl_.minimum + (value - ctrl_.minimum) / ctrl_.step * ctrl_.step;
92 set_value(value);
93 }
94
95 void
set_100(int value) const96 vidl_v4l2_control_integer::set_100(int value) const
97 {
98 if (value <= 0)
99 value = ctrl_.minimum;
100 else if (value >= 100)
101 value = ctrl_.maximum;
102 else
103 value = ctrl_.minimum + (ctrl_.maximum - ctrl_.minimum) * value / 100;
104 set_value(value);
105 }
106
107 std::string
description() const108 vidl_v4l2_control_integer::description() const
109 {
110 char cad[256];
111 std::snprintf(cad,
112 256,
113 "Control \"%s\": integer (min: %d, max: %d, step: %d, default: %d)",
114 (const char *)ctrl_.name,
115 minimum(),
116 maximum(),
117 step(),
118 default_value());
119 return cad;
120 }
121
122 // ----------------- Control menu ---------------
123
vidl_v4l2_control_menu(const v4l2_queryctrl & ctr,int f)124 vidl_v4l2_control_menu::vidl_v4l2_control_menu(const v4l2_queryctrl & ctr, int f)
125 : vidl_v4l2_control(ctr, f)
126 {
127 struct v4l2_querymenu menu;
128 std::memset(&menu, 0, sizeof(menu));
129 menu.id = ctrl_.id;
130 for (menu.index = ctrl_.minimum; (int)menu.index <= ctrl_.maximum; menu.index++)
131 {
132 if (0 == ioctl(fd, VIDIOC_QUERYMENU, &menu))
133 {
134 items.push_back((char *)menu.name);
135 }
136 else
137 {
138 // std::cerr << "VIDIOC_QUERYMENU\n";
139 items.clear(); // control menu is not added to the list
140 return;
141 }
142 }
143 }
144
145 std::string
description() const146 vidl_v4l2_control_menu::description() const
147 {
148 char cad[256];
149 std::snprintf(
150 cad, 256, "Control \"%s\": menu (%d items, default: %d)", (const char *)ctrl_.name, n_items(), default_value());
151 return cad;
152 }
153
154 // ----------------- Control boolean ---------------
155