libexplain  1.4.D001
libexplain/iocontrol/vidioc_s_ctrl.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - a library of system-call-specific strerror replacements
00003  * Copyright (C) 2011, 2013 Peter Miller
00004  * Written by Peter Miller <pmiller@opensource.org.au>
00005  *
00006  * This program is free software; you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 3 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful, but WITHOUT
00012  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00014  * License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 #include <libexplain/ac/errno.h>
00021 #include <libexplain/ac/linux/videodev2.h>
00022 #include <libexplain/ac/string.h>
00023 #include <libexplain/ac/sys/ioctl.h>
00024 
00025 #include <libexplain/buffer/einval.h>
00026 #include <libexplain/buffer/enotsup.h>
00027 #include <libexplain/buffer/is_the_null_pointer.h>
00028 #include <libexplain/buffer/v4l2_control.h>
00029 #include <libexplain/iocontrol/generic.h>
00030 #include <libexplain/iocontrol/vidioc_s_ctrl.h>
00031 #include <libexplain/is_efault.h>
00032 
00033 #ifdef VIDIOC_S_CTRL
00034 
00035 
00036 static void
00037 print_data(const explain_iocontrol_t *p, explain_string_buffer_t *sb,
00038     int errnum, int fildes, int request, const void *data)
00039 {
00040     (void)p;
00041     (void)errnum;
00042     (void)request;
00043     explain_buffer_v4l2_control(sb, data, 1, fildes);
00044 }
00045 
00046 
00047 static void
00048 print_explanation(const explain_iocontrol_t *p, explain_string_buffer_t *sb,
00049     int errnum, int fildes, int request, const void *data)
00050 {
00051     switch (errnum)
00052     {
00053     case EIO:
00054         explain_string_buffer_puts
00055         (
00056             sb,
00057             /* FIXME: i18n */
00058             "writing a device register failed"
00059         );
00060         return;
00061 
00062     case EINVAL:
00063         if (!data)
00064         {
00065             explain_buffer_is_the_null_pointer(sb, "data");
00066             return;
00067         }
00068 
00069         {
00070             const struct v4l2_control *arg;
00071             struct v4l2_queryctrl ctrl;
00072 
00073             arg = data;
00074             if (explain_is_efault_pointer(arg, sizeof(*arg)))
00075                 goto generic;
00076 
00077             /*
00078              * Check the the control id.
00079              */
00080             memset(&ctrl, 0, sizeof(ctrl));
00081             ctrl.id = arg->id;
00082             if (ioctl(fildes, VIDIOC_QUERYCTRL, &ctrl) < 0)
00083             {
00084                 if (errno != EINVAL)
00085                     goto generic;
00086                 explain_buffer_einval_vague(sb, "data->id");
00087                 return;
00088             }
00089 
00090             /*
00091              * Check the control value.
00092              */
00093             if (arg->value < ctrl.minimum || arg->value > ctrl.maximum)
00094             {
00095                 explain_buffer_einval_out_of_range
00096                 (
00097                     sb,
00098                     "data->value",
00099                     ctrl.minimum,
00100                     ctrl.maximum
00101                 );
00102                 return;
00103             }
00104             if (ctrl.step >= 2 && (arg->value - ctrl.minimum) % ctrl.step != 0)
00105             {
00106                 explain_buffer_einval_multiple(sb, "data->value", ctrl.step);
00107                 return;
00108             }
00109         }
00110 
00111         /* no idea */
00112         goto generic;
00113 
00114     default:
00115         generic:
00116         explain_iocontrol_generic_print_explanation
00117         (
00118             p,
00119             sb,
00120             errnum,
00121             fildes,
00122             request,
00123             data
00124         );
00125         break;
00126     }
00127 }
00128 
00129 
00130 static void
00131 print_data_returned(const explain_iocontrol_t *p, explain_string_buffer_t *sb,
00132     int errnum, int fildes, int request, const void *data)
00133 {
00134     (void)p;
00135     (void)errnum;
00136     (void)request;
00137     explain_buffer_v4l2_control(sb, data, 1, fildes);
00138 }
00139 
00140 
00141 const explain_iocontrol_t explain_iocontrol_vidioc_s_ctrl =
00142 {
00143     "VIDIOC_S_CTRL", /* name */
00144     VIDIOC_S_CTRL, /* value */
00145     0, /* disambiguate */
00146     0, /* print_name */
00147     print_data,
00148     print_explanation,
00149     print_data_returned,
00150     sizeof(struct v4l2_control), /* data_size */
00151     "struct v4l2_control *", /* data_type */
00152     0, /* flags */
00153     __FILE__,
00154     __LINE__,
00155 };
00156 
00157 #else /* ndef VIDIOC_S_CTRL */
00158 
00159 const explain_iocontrol_t explain_iocontrol_vidioc_s_ctrl =
00160 {
00161     0, /* name */
00162     0, /* value */
00163     0, /* disambiguate */
00164     0, /* print_name */
00165     0, /* print_data */
00166     0, /* print_explanation */
00167     0, /* print_data_returned */
00168     0, /* data_size */
00169     0, /* data_type */
00170     0, /* flags */
00171     __FILE__,
00172     __LINE__,
00173 };
00174 
00175 #endif /* VIDIOC_S_CTRL */
00176 
00177 /* vim: set ts=8 sw=4 et : */