libexplain
1.4.D001
|
00001 /* 00002 * libexplain - a library of system-call-specific strerror replacements 00003 * Copyright (C) 2011, 2013 Peter Miller 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU Lesser General Public License as 00007 * published by the Free Software Foundation; either version 3 of the 00008 * License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00018 00019 #include <libexplain/ac/errno.h> 00020 #include <libexplain/ac/linux/videodev2.h> 00021 #include <libexplain/ac/string.h> 00022 #include <libexplain/ac/sys/ioctl.h> 00023 00024 #include <libexplain/buffer/int32_t.h> 00025 #include <libexplain/buffer/pointer.h> 00026 #include <libexplain/buffer/v4l2_input.h> 00027 #include <libexplain/buffer/v4l2_input_capabilities.h> 00028 #include <libexplain/buffer/v4l2_input_status.h> 00029 #include <libexplain/buffer/v4l2_input_type.h> 00030 #include <libexplain/buffer/v4l2_std_id.h> 00031 #include <libexplain/is_efault.h> 00032 #include <libexplain/sizeof.h> 00033 00034 00035 #ifdef HAVE_LINUX_VIDEODEV2_H 00036 00037 void 00038 explain_buffer_v4l2_input(explain_string_buffer_t *sb, 00039 const struct v4l2_input *data, int extra) 00040 { 00041 if (explain_is_efault_pointer(data, sizeof(*data))) 00042 { 00043 explain_buffer_pointer(sb, data); 00044 return; 00045 } 00046 00047 explain_string_buffer_puts(sb, "{ index = "); 00048 explain_buffer_uint32_t(sb, data->index); 00049 if (extra) 00050 { 00051 explain_string_buffer_puts(sb, ", name = "); 00052 explain_string_buffer_putsu_quoted_n(sb, data->name, 00053 sizeof(data->name)); 00054 explain_string_buffer_puts(sb, ", type = "); 00055 explain_buffer_v4l2_input_type(sb, data->type); 00056 explain_string_buffer_puts(sb, ", audioset = "); 00057 explain_buffer_uint32_t(sb, data->audioset); /* FIXME: bitfield */ 00058 explain_string_buffer_puts(sb, ", tuner = "); 00059 explain_buffer_uint32_t(sb, data->tuner); /* name? */ 00060 explain_string_buffer_puts(sb, ", std = "); 00061 explain_buffer_v4l2_std_id(sb, data->std); 00062 explain_string_buffer_puts(sb, ", status = "); 00063 explain_buffer_v4l2_input_status(sb, data->status); 00064 #ifdef V4L2_IN_CAP_PRESETS 00065 if (data->capabilities) 00066 { 00067 explain_string_buffer_puts(sb, ", capabilities = "); 00068 explain_buffer_v4l2_input_capabilities(sb, data->capabilities); 00069 } 00070 #endif 00071 if (!explain_uint32_array_all_zero(data->reserved, 00072 SIZEOF(data->reserved))) 00073 { 00074 explain_string_buffer_puts(sb, ", reserved = "); 00075 explain_buffer_uint32_array(sb, data->reserved, 00076 SIZEOF(data->reserved)); 00077 } 00078 } 00079 explain_string_buffer_puts(sb, " }"); 00080 } 00081 00082 00083 void 00084 explain_buffer_v4l2_input_index(explain_string_buffer_t *sb, int value, 00085 int fildes) 00086 { 00087 struct v4l2_input in; 00088 00089 explain_buffer_uint32_t(sb, value); 00090 00091 memset(&in, 0, sizeof(in)); 00092 in.index = value; 00093 if (ioctl(fildes, VIDIOC_ENUMINPUT, &in) >= 0) 00094 { 00095 explain_string_buffer_putc(sb, ' '); 00096 explain_string_buffer_putsu_quoted_n(sb, in.name, sizeof(in.name)); 00097 } 00098 } 00099 00100 00101 void 00102 explain_buffer_v4l2_input_index_ptr(explain_string_buffer_t *sb, 00103 const int *data, int fildes) 00104 { 00105 if (explain_is_efault_pointer(data, sizeof(*data))) 00106 { 00107 explain_buffer_pointer(sb, data); 00108 return; 00109 } 00110 00111 explain_string_buffer_puts(sb, "{ "); 00112 explain_buffer_v4l2_input_index(sb, *data, fildes); 00113 explain_string_buffer_puts(sb, " }"); 00114 } 00115 00116 00117 int 00118 explain_v4l2_input_get_ninputs(int fildes) 00119 { 00120 int lo = 0; 00121 int hi = 200; 00122 for (;;) 00123 { 00124 int mid = (lo + hi) / 2; 00125 struct v4l2_input qry; 00126 memset(&qry, 0, sizeof(qry)); 00127 qry.index = mid; 00128 if (ioctl(fildes, VIDIOC_ENUMINPUT, &qry) >= 0) 00129 { 00130 if (hi <= 0 && lo <= 0) 00131 return -1; 00132 /* mid < ninputs */ 00133 lo = mid + 1; 00134 if (lo > hi) 00135 return lo; 00136 } 00137 else if (errno != EINVAL) 00138 { 00139 return -1; 00140 } 00141 else 00142 { 00143 if (hi <= 0 && lo <= 0) 00144 return -1; 00145 /* mid >= ninputs */ 00146 hi = mid - 1; 00147 if (lo >= hi) 00148 return lo; 00149 } 00150 } 00151 } 00152 00153 #endif 00154 00155 /* vim: set ts=8 sw=4 et : */