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