summaryrefslogtreecommitdiff
path: root/v4l2-apps/util
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2006-07-01 18:04:09 +0200
committerHans Verkuil <hverkuil@xs4all.nl>2006-07-01 18:04:09 +0200
commit46b7750285822f2a41f56d5a1e211d472b4783be (patch)
tree00602df94c9d87c5e72f85e79dff3428ee83d632 /v4l2-apps/util
parent6c65b97fa5448a31004227926f04f7f13bf14b88 (diff)
downloadmediapointer-dvb-s2-46b7750285822f2a41f56d5a1e211d472b4783be.tar.gz
mediapointer-dvb-s2-46b7750285822f2a41f56d5a1e211d472b4783be.tar.bz2
Split qv4l2.cpp into multiple sources.
From: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Diffstat (limited to 'v4l2-apps/util')
-rw-r--r--v4l2-apps/util/qv4l2/ctrl-tab.cpp592
-rw-r--r--v4l2-apps/util/qv4l2/general-tab.cpp326
-rw-r--r--v4l2-apps/util/qv4l2/general-tab.h71
-rw-r--r--v4l2-apps/util/qv4l2/qv4l2.cpp887
-rw-r--r--v4l2-apps/util/qv4l2/qv4l2.h57
-rw-r--r--v4l2-apps/util/qv4l2/qv4l2.pro5
6 files changed, 1023 insertions, 915 deletions
diff --git a/v4l2-apps/util/qv4l2/ctrl-tab.cpp b/v4l2-apps/util/qv4l2/ctrl-tab.cpp
new file mode 100644
index 000000000..c7d1a275c
--- /dev/null
+++ b/v4l2-apps/util/qv4l2/ctrl-tab.cpp
@@ -0,0 +1,592 @@
+
+#include "qv4l2.h"
+#include "v4l2.h"
+
+#include <qstatusbar.h>
+#include <qlineedit.h>
+#include <qvalidator.h>
+#include <qlayout.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qslider.h>
+#include <qspinbox.h>
+#include <qcombobox.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+void ApplicationWindow::addTabs()
+{
+ struct v4l2_queryctrl qctrl;
+ unsigned ctrl_class;
+ unsigned i;
+ int id;
+
+ memset(&qctrl, 0, sizeof(qctrl));
+ qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
+ while (::ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) {
+ if ((qctrl.flags & V4L2_CTRL_FLAG_DISABLED) == 0) {
+ ctrlMap[qctrl.id] = qctrl;
+ if (qctrl.type != V4L2_CTRL_TYPE_CTRL_CLASS)
+ classMap[V4L2_CTRL_ID2CLASS(qctrl.id)].push_back(qctrl.id);
+ }
+ qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+ }
+ if (qctrl.id == V4L2_CTRL_FLAG_NEXT_CTRL) {
+ strcpy((char *)qctrl.name, "User Controls");
+ qctrl.id = V4L2_CTRL_CLASS_USER | 1;
+ qctrl.type = V4L2_CTRL_TYPE_CTRL_CLASS;
+ ctrlMap[qctrl.id] = qctrl;
+ for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) {
+ qctrl.id = id;
+ if (::ioctl(fd, VIDIOC_QUERYCTRL, &qctrl))
+ continue;
+ if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED)
+ continue;
+ ctrlMap[qctrl.id] = qctrl;
+ classMap[V4L2_CTRL_CLASS_USER].push_back(qctrl.id);
+ }
+ for (qctrl.id = V4L2_CID_PRIVATE_BASE;
+ ::ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) {
+ if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED)
+ continue;
+ ctrlMap[qctrl.id] = qctrl;
+ classMap[V4L2_CTRL_CLASS_USER].push_back(qctrl.id);
+ }
+ }
+
+ for (ClassMap::iterator iter = classMap.begin(); iter != classMap.end(); ++iter) {
+ ctrl_class = V4L2_CTRL_ID2CLASS(iter->second[0]);
+ id = ctrl_class | 1;
+ const struct v4l2_queryctrl &qctrl = ctrlMap[id];
+ QVBox *vbox = new QVBox(tabs);
+ QGrid *grid = new QGrid(4, vbox);
+ grid->setSpacing(3);
+ tabs->addTab(vbox, (char *)qctrl.name);
+ for (i = 0; i < iter->second.size(); i++) {
+ if (i & 1)
+ id = iter->second[(1+iter->second.size()) / 2 + i / 2];
+ else
+ id = iter->second[i / 2];
+ addCtrl(grid, ctrlMap[id]);
+ }
+ finishGrid(vbox, grid, ctrl_class, i & 1);
+ }
+}
+
+void ApplicationWindow::finishGrid(QWidget *vbox, QGrid *grid, unsigned ctrl_class, bool odd)
+{
+ if (odd) {
+ new QWidget(grid);
+ new QWidget(grid);
+ }
+ QWidget *stretch = new QWidget(grid);
+ stretch->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
+
+ QFrame *frame = new QFrame(vbox);
+ frame->setFrameShape(QFrame::HLine);
+ frame->setFrameShadow(QFrame::Sunken);
+ frame->setMargin(3);
+
+ QHBox *hbox = new QHBox(vbox);
+ hbox->setSpacing(3);
+
+ QCheckBox *cbox = new QCheckBox("Update on change", hbox);
+ widgetMap[ctrl_class | CTRL_UPDATE_ON_CHANGE] = cbox;
+ connect(cbox, SIGNAL(clicked()), sigMapper, SLOT(map()));
+ sigMapper->setMapping(cbox, ctrl_class | CTRL_UPDATE_ON_CHANGE);
+
+ stretch = new QWidget(hbox);
+ stretch->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
+
+ QPushButton *defBut = new QPushButton("Set Defaults", hbox);
+ widgetMap[ctrl_class | CTRL_DEFAULTS] = defBut;
+ connect(defBut, SIGNAL(clicked()), sigMapper, SLOT(map()));
+ sigMapper->setMapping(defBut, ctrl_class | CTRL_DEFAULTS);
+
+ QPushButton *refreshBut = new QPushButton("Refresh", hbox);
+ widgetMap[ctrl_class | CTRL_REFRESH] = refreshBut;
+ connect(refreshBut, SIGNAL(clicked()), sigMapper, SLOT(map()));
+ sigMapper->setMapping(refreshBut, ctrl_class | CTRL_REFRESH);
+
+ QPushButton *button = new QPushButton("Update", hbox);
+ widgetMap[ctrl_class | CTRL_UPDATE] = button;
+ connect(button, SIGNAL(clicked()), sigMapper, SLOT(map()));
+ sigMapper->setMapping(button, ctrl_class | CTRL_UPDATE);
+ connect(cbox, SIGNAL(toggled(bool)), button, SLOT(setDisabled(bool)));
+
+ cbox->setChecked(ctrl_class == V4L2_CTRL_CLASS_USER);
+
+ refresh(ctrl_class);
+}
+
+void ApplicationWindow::addCtrl(QGrid *grid, const struct v4l2_queryctrl &qctrl)
+{
+ QIntValidator *val;
+ QLineEdit *edit;
+ QString name((char *)qctrl.name);
+ QComboBox *combo;
+ struct v4l2_querymenu qmenu;
+
+ QLabel *label = new QLabel(name, grid);
+ label->setAlignment(Qt::AlignRight);
+
+ switch (qctrl.type) {
+ case V4L2_CTRL_TYPE_INTEGER:
+ if (qctrl.flags & V4L2_CTRL_FLAG_SLIDER) {
+ widgetMap[qctrl.id] =
+ new QSlider(qctrl.minimum, qctrl.maximum,
+ qctrl.step, qctrl.default_value,
+ Horizontal, grid);
+ connect(widgetMap[qctrl.id], SIGNAL(valueChanged(int)),
+ sigMapper, SLOT(map()));
+ break;
+ }
+
+ if (qctrl.maximum - qctrl.minimum <= 255) {
+ widgetMap[qctrl.id] =
+ new QSpinBox(qctrl.minimum, qctrl.maximum, 1, grid);
+ connect(widgetMap[qctrl.id], SIGNAL(valueChanged(int)),
+ sigMapper, SLOT(map()));
+ break;
+ }
+
+ val = new QIntValidator(qctrl.minimum, qctrl.maximum, grid);
+ edit = new QLineEdit(grid);
+ edit->setValidator(val);
+ widgetMap[qctrl.id] = edit;
+ connect(widgetMap[qctrl.id], SIGNAL(lostFocus()),
+ sigMapper, SLOT(map()));
+ connect(widgetMap[qctrl.id], SIGNAL(returnPressed()),
+ sigMapper, SLOT(map()));
+ break;
+
+ case V4L2_CTRL_TYPE_INTEGER64:
+ widgetMap[qctrl.id] = new QLineEdit(grid);
+ connect(widgetMap[qctrl.id], SIGNAL(lostFocus()),
+ sigMapper, SLOT(map()));
+ connect(widgetMap[qctrl.id], SIGNAL(returnPressed()),
+ sigMapper, SLOT(map()));
+ break;
+
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ label->setText("");
+ widgetMap[qctrl.id] = new QCheckBox(name, grid);
+ connect(widgetMap[qctrl.id], SIGNAL(clicked()),
+ sigMapper, SLOT(map()));
+ break;
+
+ case V4L2_CTRL_TYPE_BUTTON:
+ label->setText("");
+ widgetMap[qctrl.id] = new QPushButton((char *)qctrl.name, grid);
+ connect(widgetMap[qctrl.id], SIGNAL(clicked()),
+ sigMapper, SLOT(map()));
+ break;
+
+ case V4L2_CTRL_TYPE_MENU:
+ combo = new QComboBox(grid);
+ widgetMap[qctrl.id] = combo;
+ for (int i = qctrl.minimum; i <= qctrl.maximum; i++) {
+ qmenu.id = qctrl.id;
+ qmenu.index = i;
+ if (::ioctl(fd, VIDIOC_QUERYMENU, &qmenu))
+ continue;
+ combo->insertItem((char *)qmenu.name);
+ }
+ connect(widgetMap[qctrl.id], SIGNAL(activated(int)),
+ sigMapper, SLOT(map()));
+ break;
+
+ default:
+ return;
+ }
+ sigMapper->setMapping(widgetMap[qctrl.id], qctrl.id);
+ if (qctrl.flags & (V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_INACTIVE))
+ widgetMap[qctrl.id]->setDisabled(true);
+}
+
+void ApplicationWindow::ctrlAction(int id)
+{
+ unsigned ctrl_class = V4L2_CTRL_ID2CLASS(id);
+ if (ctrl_class == V4L2_CID_PRIVATE_BASE)
+ ctrl_class = V4L2_CTRL_CLASS_USER;
+ unsigned ctrl = id & 0xffff;
+ QCheckBox *cbox = static_cast<QCheckBox *>(widgetMap[ctrl_class | CTRL_UPDATE_ON_CHANGE]);
+ bool update = cbox->isChecked();
+ bool all = (ctrl == CTRL_UPDATE || (update && ctrl == CTRL_UPDATE_ON_CHANGE));
+
+ if (ctrl == CTRL_DEFAULTS) {
+ setDefaults(ctrl_class);
+ return;
+ }
+ if (ctrl == CTRL_REFRESH) {
+ refresh(ctrl_class);
+ return;
+ }
+ if (!update && !all && ctrlMap[id].type != V4L2_CTRL_TYPE_BUTTON)
+ return;
+ if (ctrl_class == V4L2_CTRL_CLASS_USER) {
+ if (!all) {
+ updateCtrl(id);
+ return;
+ }
+ for (unsigned i = 0; i < classMap[ctrl_class].size(); i++) {
+ updateCtrl(classMap[ctrl_class][i]);
+ }
+ return;
+ }
+ if (!all) {
+ updateCtrl(id);
+ return;
+ }
+ unsigned count = classMap[ctrl_class].size();
+ struct v4l2_ext_control *c = new v4l2_ext_control[count];
+ struct v4l2_ext_controls ctrls;
+ int idx = 0;
+
+ for (unsigned i = 0; i < count; i++) {
+ unsigned id = classMap[ctrl_class][i];
+
+ if (ctrlMap[id].flags & (V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_INACTIVE))
+ continue;
+ c[idx].id = id;
+ if (ctrlMap[id].type == V4L2_CTRL_TYPE_INTEGER64)
+ c[idx].value64 = getVal64(id);
+ else
+ c[idx].value = getVal(id);
+ idx++;
+ }
+ memset(&ctrls, 0, sizeof(ctrls));
+ ctrls.count = idx;
+ ctrls.ctrl_class = ctrl_class;
+ ctrls.controls = c;
+ if (::ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls)) {
+ int err = errno;
+
+ if (ctrls.error_idx >= ctrls.count) {
+ printf("error: %s\n", strerror(err));
+ }
+ else {
+ id = c[ctrls.error_idx].id;
+ printf("error %08x (%s): %s\n", id,
+ ctrlMap[id].name, strerror(err));
+ }
+ }
+ delete [] c;
+ refresh(ctrl_class);
+}
+
+long long ApplicationWindow::getVal64(unsigned id)
+{
+ const v4l2_queryctrl &qctrl = ctrlMap[id];
+ QWidget *w = widgetMap[qctrl.id];
+ long long v = 0;
+
+ switch (qctrl.type) {
+ case V4L2_CTRL_TYPE_INTEGER64:
+ v = static_cast<QLineEdit *>(w)->text().toLongLong();
+ break;
+ default:
+ break;
+ }
+ setWhat(w, id, v);
+ return v;
+}
+
+int ApplicationWindow::getVal(unsigned id)
+{
+ const v4l2_queryctrl &qctrl = ctrlMap[id];
+ QWidget *w = widgetMap[qctrl.id];
+ v4l2_querymenu qmenu;
+ int i, idx;
+ int v = 0;
+
+ switch (qctrl.type) {
+ case V4L2_CTRL_TYPE_INTEGER:
+ if (qctrl.flags & V4L2_CTRL_FLAG_SLIDER) {
+ v = static_cast<QSlider *>(w)->value();
+ break;
+ }
+
+ if (qctrl.maximum - qctrl.minimum <= 255) {
+ v = static_cast<QSpinBox *>(w)->value();
+ break;
+ }
+ v = static_cast<QLineEdit *>(w)->text().toInt();
+ break;
+
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ v = static_cast<QCheckBox *>(w)->isChecked();
+ break;
+
+ case V4L2_CTRL_TYPE_MENU:
+ idx = static_cast<QComboBox *>(w)->currentItem();
+ for (i = qctrl.minimum; i <= qctrl.maximum; i++) {
+ qmenu.id = qctrl.id;
+ qmenu.index = i;
+ if (::ioctl(fd, VIDIOC_QUERYMENU, &qmenu))
+ continue;
+ if (idx-- == 0)
+ break;
+ }
+ v = i;
+ break;
+
+ default:
+ break;
+ }
+ setWhat(w, id, v);
+ return v;
+}
+
+void ApplicationWindow::updateCtrl(unsigned id)
+{
+ unsigned ctrl_class = V4L2_CTRL_ID2CLASS(id);
+ if (ctrl_class == V4L2_CID_PRIVATE_BASE)
+ ctrl_class = V4L2_CTRL_CLASS_USER;
+
+ if (ctrlMap[id].flags & (V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_INACTIVE))
+ return;
+
+ if (ctrl_class == V4L2_CTRL_CLASS_USER) {
+ struct v4l2_control c;
+
+ c.id = id;
+ c.value = getVal(id);
+ if (::ioctl(fd, VIDIOC_S_CTRL, &c)) {
+ int err = errno;
+ char buf[200];
+
+ sprintf(buf, "Error %08x (%s): %s", id,
+ ctrlMap[id].name, strerror(err));
+ statusBar()->message(buf, 10000);
+ }
+ return;
+ }
+ struct v4l2_ext_control c;
+ struct v4l2_ext_controls ctrls;
+
+ memset(&c, 0, sizeof(c));
+ memset(&ctrls, 0, sizeof(ctrls));
+ c.id = id;
+ if (ctrlMap[id].type == V4L2_CTRL_TYPE_INTEGER64)
+ c.value64 = getVal64(id);
+ else
+ c.value = getVal(id);
+ ctrls.count = 1;
+ ctrls.ctrl_class = ctrl_class;
+ ctrls.controls = &c;
+ if (::ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls)) {
+ int err = errno;
+ char buf[200];
+
+ sprintf(buf, "Error %08x (%s): %s", id,
+ ctrlMap[id].name, strerror(err));
+ statusBar()->message(buf, 10000);
+ }
+ else if (ctrlMap[id].flags & V4L2_CTRL_FLAG_UPDATE)
+ refresh(ctrl_class);
+ else {
+ if (ctrlMap[id].type == V4L2_CTRL_TYPE_INTEGER64)
+ setVal64(id, c.value64);
+ else
+ setVal(id, c.value);
+ }
+}
+
+void ApplicationWindow::refresh(unsigned ctrl_class)
+{
+ if (ctrl_class == V4L2_CTRL_CLASS_USER) {
+ for (unsigned i = 0; i < classMap[ctrl_class].size(); i++) {
+ unsigned id = classMap[ctrl_class][i];
+
+ v4l2_control c;
+
+ c.id = id;
+ if (::ioctl(fd, VIDIOC_G_CTRL, &c)) {
+ int err = errno;
+ char buf[200];
+
+ sprintf(buf, "Error %08x (%s): %s", id,
+ ctrlMap[id].name, strerror(err));
+ statusBar()->message(buf, 10000);
+ }
+ setVal(id, c.value);
+ }
+ return;
+ }
+ unsigned count = classMap[ctrl_class].size();
+ struct v4l2_ext_control *c = new v4l2_ext_control[count];
+ struct v4l2_ext_controls ctrls;
+
+ for (unsigned i = 0; i < count; i++) {
+ c[i].id = classMap[ctrl_class][i];
+ }
+ memset(&ctrls, 0, sizeof(ctrls));
+ ctrls.count = count;
+ ctrls.ctrl_class = ctrl_class;
+ ctrls.controls = c;
+ if (::ioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls)) {
+ int err = errno;
+
+ if (ctrls.error_idx >= ctrls.count) {
+ statusBar()->message(strerror(err), 10000);
+ }
+ else {
+ unsigned id = c[ctrls.error_idx].id;
+ char buf[200];
+
+ sprintf(buf, "Error %08x (%s): %s", id,
+ ctrlMap[id].name, strerror(err));
+ statusBar()->message(buf, 10000);
+ }
+ }
+ else {
+ for (unsigned i = 0; i < ctrls.count; i++) {
+ unsigned id = c[i].id;
+ if (ctrlMap[id].type == V4L2_CTRL_TYPE_INTEGER64)
+ setVal64(id, c[i].value64);
+ else
+ setVal(id, c[i].value);
+ ::ioctl(fd, VIDIOC_QUERYCTRL, &ctrlMap[id]);
+ widgetMap[id]->setDisabled(ctrlMap[id].flags &
+ (V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_INACTIVE));
+ }
+ }
+ delete [] c;
+}
+
+void ApplicationWindow::setWhat(QWidget *w, unsigned id, long long v)
+{
+ const v4l2_queryctrl &qctrl = ctrlMap[id];
+ QString what;
+ QString flags = getCtrlFlags(qctrl.flags);
+
+ switch (qctrl.type) {
+ case V4L2_CTRL_TYPE_INTEGER:
+ QWhatsThis::add(w, what.sprintf("Integer type control\n"
+ "Minimum: %d\n"
+ "Maximum: %d\n"
+ "Current: %d\n"
+ "Default: %d\n",
+ qctrl.minimum, qctrl.maximum, (int)v, qctrl.default_value) + flags);
+ break;
+
+ case V4L2_CTRL_TYPE_INTEGER64:
+ QWhatsThis::add(w, what.sprintf("64-bit Integer type control\n"
+ "Current: %lld\n", v) + flags);
+ break;
+
+ case V4L2_CTRL_TYPE_BUTTON:
+ QWhatsThis::add(w, what.sprintf("Button type control\n") + flags);
+ break;
+
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ QWhatsThis::add(w, what.sprintf("Boolean type control\n"
+ "Current: %d\n"
+ "Default: %d\n",
+ (int)v, qctrl.default_value) + flags);
+ break;
+
+ case V4L2_CTRL_TYPE_MENU:
+ QWhatsThis::add(w, what.sprintf("Menu type control\n"
+ "Minimum: %d\n"
+ "Maximum: %d\n"
+ "Current: %d\n"
+ "Default: %d\n",
+ qctrl.minimum, qctrl.maximum, (int)v, qctrl.default_value) + flags);
+ break;
+ default:
+ break;
+ }
+}
+
+void ApplicationWindow::setVal(unsigned id, int v)
+{
+ const v4l2_queryctrl &qctrl = ctrlMap[id];
+ v4l2_querymenu qmenu;
+ QWidget *w = widgetMap[qctrl.id];
+ int i, idx;
+
+ switch (qctrl.type) {
+ case V4L2_CTRL_TYPE_INTEGER:
+ if (qctrl.flags & V4L2_CTRL_FLAG_SLIDER)
+ static_cast<QSlider *>(w)->setValue(v);
+ else if (qctrl.maximum - qctrl.minimum <= 255)
+ static_cast<QSpinBox *>(w)->setValue(v);
+ else
+ static_cast<QLineEdit *>(w)->setText(QString::number(v));
+ break;
+
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ static_cast<QCheckBox *>(w)->setChecked(v);
+ break;
+
+ case V4L2_CTRL_TYPE_MENU:
+ idx = 0;
+ for (i = qctrl.minimum; i <= v; i++) {
+ qmenu.id = id;
+ qmenu.index = i;
+ if (::ioctl(fd, VIDIOC_QUERYMENU, &qmenu))
+ continue;
+ idx++;
+ }
+ static_cast<QComboBox *>(w)->setCurrentItem(idx - 1);
+ break;
+ default:
+ break;
+ }
+ setWhat(w, id, v);
+}
+
+void ApplicationWindow::setVal64(unsigned id, long long v)
+{
+ const v4l2_queryctrl &qctrl = ctrlMap[id];
+ QWidget *w = widgetMap[qctrl.id];
+
+ switch (qctrl.type) {
+ case V4L2_CTRL_TYPE_INTEGER64:
+ static_cast<QLineEdit *>(w)->setText(QString::number(v));
+ break;
+ default:
+ break;
+ }
+ setWhat(w, id, v);
+}
+
+void ApplicationWindow::setDefaults(unsigned ctrl_class)
+{
+ for (unsigned i = 0; i < classMap[ctrl_class].size(); i++) {
+ unsigned id = classMap[ctrl_class][i];
+
+ if (ctrlMap[id].type != V4L2_CTRL_TYPE_INTEGER64 &&
+ ctrlMap[id].type != V4L2_CTRL_TYPE_BUTTON)
+ setVal(id, ctrlMap[id].default_value);
+ }
+ ctrlAction(ctrl_class | CTRL_UPDATE);
+}
+
+QString ApplicationWindow::getCtrlFlags(unsigned flags)
+{
+ QString s;
+
+ if (flags & V4L2_CTRL_FLAG_GRABBED)
+ s += "grabbed ";
+ if (flags & V4L2_CTRL_FLAG_READ_ONLY)
+ s += "readonly ";
+ if (flags & V4L2_CTRL_FLAG_UPDATE)
+ s += "update ";
+ if (flags & V4L2_CTRL_FLAG_INACTIVE)
+ s += "inactive ";
+ if (flags & V4L2_CTRL_FLAG_SLIDER)
+ s += "slider ";
+ if (s.length()) s = QString("Flags: ") + s;
+ return s;
+}
+
diff --git a/v4l2-apps/util/qv4l2/general-tab.cpp b/v4l2-apps/util/qv4l2/general-tab.cpp
new file mode 100644
index 000000000..a19cf911b
--- /dev/null
+++ b/v4l2-apps/util/qv4l2/general-tab.cpp
@@ -0,0 +1,326 @@
+/* qv4l2: a control panel controlling v4l2 devices.
+ *
+ * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#include "qv4l2.h"
+#include "general-tab.h"
+#include "v4l2.h"
+
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <qcombobox.h>
+#include <qwhatsthis.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+GeneralTab::GeneralTab(int _fd, int n, QWidget *parent) :
+ QGrid(n, parent),
+ fd(_fd)
+{
+ int cnt = 0;
+
+ setSpacing(3);
+
+ memset(&tuner, 0, sizeof(tuner));
+ ioctl(fd, VIDIOC_G_TUNER, &tuner);
+
+ struct v4l2_input vin;
+ memset(&vin, 0, sizeof(vin));
+ if (ioctl(fd, VIDIOC_ENUMINPUT, &vin) >= 0) {
+ QLabel *label = new QLabel("Input", this);
+ label->setAlignment(Qt::AlignRight);
+ videoInput = new QComboBox(this);
+ while (ioctl(fd, VIDIOC_ENUMINPUT, &vin) >= 0) {
+ videoInput->insertItem((char *)vin.name);
+ vin.index++;
+ }
+ connect(videoInput, SIGNAL(activated(int)), SLOT(inputChanged(int)));
+ updateVideoInput();
+ cnt++;
+ }
+
+ struct v4l2_output vout;
+ memset(&vout, 0, sizeof(vout));
+ if (ioctl(fd, VIDIOC_ENUMOUTPUT, &vout) >= 0) {
+ QLabel *label = new QLabel("Output", this);
+ label->setAlignment(Qt::AlignRight);
+ videoOutput = new QComboBox(this);
+ while (ioctl(fd, VIDIOC_ENUMOUTPUT, &vout) >= 0) {
+ videoOutput->insertItem((char *)vout.name);
+ vout.index++;
+ }
+ connect(videoOutput, SIGNAL(activated(int)), SLOT(outputChanged(int)));
+ updateVideoOutput();
+ cnt++;
+ }
+
+ struct v4l2_audio vaudio;
+ memset(&vaudio, 0, sizeof(vaudio));
+ if (ioctl(fd, VIDIOC_ENUMAUDIO, &vaudio) >= 0) {
+ QLabel *label = new QLabel("Input Audio", this);
+ label->setAlignment(Qt::AlignRight);
+ audioInput = new QComboBox(this);
+ vaudio.index = 0;
+ while (ioctl(fd, VIDIOC_ENUMAUDIO, &vaudio) >= 0) {
+ audioInput->insertItem((char *)vaudio.name);
+ vaudio.index++;
+ }
+ connect(audioInput, SIGNAL(activated(int)), SLOT(inputAudioChanged(int)));
+ updateAudioInput();
+ cnt++;
+ }
+
+ struct v4l2_audioout vaudioout;
+ memset(&vaudioout, 0, sizeof(vaudioout));
+ if (ioctl(fd, VIDIOC_ENUMAUDOUT, &vaudioout) >= 0) {
+ QLabel *label = new QLabel("Output Audio", this);
+ label->setAlignment(Qt::AlignRight);
+ audioOutput = new QComboBox(this);
+ while (ioctl(fd, VIDIOC_ENUMAUDOUT, &vaudioout) >= 0) {
+ audioOutput->insertItem((char *)vaudioout.name);
+ vaudioout.index++;
+ }
+ connect(audioOutput, SIGNAL(activated(int)), SLOT(outputAudioChanged(int)));
+ updateAudioOutput();
+ cnt++;
+ }
+
+ struct v4l2_standard vs;
+ memset(&vs, 0, sizeof(vs));
+ if (ioctl(fd, VIDIOC_ENUMSTD, &vs) >= 0) {
+ QLabel *label = new QLabel("TV Standard", this);
+ label->setAlignment(Qt::AlignRight);
+ tvStandard = new QComboBox(this);
+ while (ioctl(fd, VIDIOC_ENUMSTD, &vs) >= 0) {
+ tvStandard->insertItem((char *)vs.name);
+ vs.index++;
+ }
+ connect(tvStandard, SIGNAL(activated(int)), SLOT(standardChanged(int)));
+ updateStandard();
+ cnt++;
+ }
+
+ bool first = cnt & 1;
+
+ if (first) {
+ QString what;
+ QLabel *label = new QLabel("Frequency", this);
+ label->setAlignment(Qt::AlignRight);
+ freq = new QSpinBox(tuner.rangelow, tuner.rangehigh, 1, this);
+ QWhatsThis::add(freq, what.sprintf("Frequency\n"
+ "Low: %d\n"
+ "High: %d\n",
+ tuner.rangelow, tuner.rangehigh));
+ connect(freq, SIGNAL(valueChanged(int)), SLOT(freqChanged(int)));
+ updateFreq();
+ cnt++;
+ }
+
+ {
+ QLabel *label = new QLabel("Frequency Tables", this);
+ label->setAlignment(Qt::AlignRight);
+ freqTable = new QComboBox(this);
+ for (int i = 0; v4l2_channel_lists[i].name; i++) {
+ freqTable->insertItem(v4l2_channel_lists[i].name);
+ }
+ connect(freqTable, SIGNAL(activated(int)), SLOT(freqTableChanged(int)));
+
+ label = new QLabel("Channels", this);
+ label->setAlignment(Qt::AlignRight);
+ freqChannel = new QComboBox(this);
+ connect(freqChannel, SIGNAL(activated(int)), SLOT(freqChannelChanged(int)));
+ updateFreqChannel();
+ }
+
+ if (!first) {
+ QString what;
+ QLabel *label = new QLabel("Frequency", this);
+ label->setAlignment(Qt::AlignRight);
+ freq = new QSpinBox(tuner.rangelow, tuner.rangehigh, 1, this);
+ QWhatsThis::add(freq, what.sprintf("Frequency\n"
+ "Low: %d\n"
+ "High: %d\n",
+ tuner.rangelow, tuner.rangehigh));
+ connect(freq, SIGNAL(valueChanged(int)), SLOT(freqChanged(int)));
+ updateFreq();
+ cnt++;
+ }
+
+ if (cnt & 1) {
+ new QWidget(this);
+ new QWidget(this);
+ }
+ QWidget *stretch = new QWidget(this);
+ stretch->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
+}
+
+void GeneralTab::inputChanged(int input)
+{
+ g_mw->doIoctl("Set Input", VIDIOC_S_INPUT, &input);
+ struct v4l2_audio vaudio;
+ memset(&vaudio, 0, sizeof(vaudio));
+ if (audioInput && ioctl(fd, VIDIOC_G_AUDIO, &vaudio) >= 0) {
+ audioInput->setCurrentItem(vaudio.index);
+ updateAudioInput();
+ }
+ updateVideoInput();
+}
+
+void GeneralTab::outputChanged(int output)
+{
+ g_mw->doIoctl("Set Output", VIDIOC_S_OUTPUT, &output);
+ updateVideoOutput();
+}
+
+void GeneralTab::inputAudioChanged(int input)
+{
+ struct v4l2_audio vaudio;
+ memset(&vaudio, 0, sizeof(vaudio));
+ vaudio.index = input;
+ g_mw->doIoctl("Set Audio Input", VIDIOC_S_AUDIO, &vaudio);
+ updateAudioInput();
+}
+
+void GeneralTab::outputAudioChanged(int output)
+{
+ struct v4l2_audioout vaudioout;
+ memset(&vaudioout, 0, sizeof(vaudioout));
+ vaudioout.index = output;
+ g_mw->doIoctl("Set Audio Output", VIDIOC_S_AUDOUT, &vaudioout);
+ updateAudioOutput();
+}
+
+void GeneralTab::standardChanged(int std)
+{
+ struct v4l2_standard vs;
+ memset(&vs, 0, sizeof(vs));
+ vs.index = std;
+ ioctl(fd, VIDIOC_ENUMSTD, &vs);
+ g_mw->doIoctl("Set TV Standard", VIDIOC_S_STD, &vs.id);
+ updateStandard();
+}
+
+void GeneralTab::freqTableChanged(int)
+{
+ updateFreqChannel();
+ freqChannelChanged(0);
+}
+
+void GeneralTab::freqChannelChanged(int idx)
+{
+ freq->setValue((int)(v4l2_channel_lists[freqTable->currentItem()].list[idx].freq / 62.5));
+}
+
+void GeneralTab::freqChanged(int val)
+{
+ struct v4l2_frequency f;
+
+ memset(&f, 0, sizeof(f));
+ f.type = V4L2_TUNER_ANALOG_TV;
+ f.frequency = val;
+ g_mw->doIoctl("Set frequency", VIDIOC_S_FREQUENCY, &f);
+}
+
+void GeneralTab::updateVideoInput()
+{
+ int input;
+
+ ioctl(fd, VIDIOC_G_INPUT, &input);
+ videoInput->setCurrentItem(input);
+}
+
+void GeneralTab::updateVideoOutput()
+{
+ int output;
+
+ ioctl(fd, VIDIOC_G_OUTPUT, &output);
+ videoOutput->setCurrentItem(output);
+}
+
+void GeneralTab::updateAudioInput()
+{
+ struct v4l2_audio audio;
+ QString what;
+
+ memset(&audio, 0, sizeof(audio));
+ ioctl(fd, VIDIOC_G_AUDIO, &audio);
+ audioInput->setCurrentItem(audio.index);
+ if (audio.capability & V4L2_AUDCAP_STEREO)
+ what = "stereo input";
+ else
+ what = "mono input";
+ if (audio.capability & V4L2_AUDCAP_AVL)
+ what += ", has AVL";
+ if (audio.mode & V4L2_AUDMODE_AVL)
+ what += ", AVL is on";
+ QWhatsThis::add(audioInput, what);
+}
+
+void GeneralTab::updateAudioOutput()
+{
+ struct v4l2_audioout audio;
+
+ memset(&audio, 0, sizeof(audio));
+ ioctl(fd, VIDIOC_G_AUDOUT, &audio);
+ audioOutput->setCurrentItem(audio.index);
+}
+
+void GeneralTab::updateStandard()
+{
+ v4l2_std_id std;
+ struct v4l2_standard vs;
+ QString what;
+ ioctl(fd, VIDIOC_G_STD, &std);
+ memset(&vs, 0, sizeof(vs));
+ while (ioctl(fd, VIDIOC_ENUMSTD, &vs) != -1) {
+ if (vs.id & std) {
+ tvStandard->setCurrentItem(vs.index);
+ what.sprintf("TV Standard (0x%llX)\n"
+ "Frame period: %f (%d/%d)\n"
+ "Frame lines: %d\n", std,
+ (double)vs.frameperiod.numerator / vs.frameperiod.denominator,
+ vs.frameperiod.numerator, vs.frameperiod.denominator,
+ vs.framelines);
+ QWhatsThis::add(tvStandard, what);
+ return;
+ }
+ vs.index++;
+ }
+}
+
+void GeneralTab::updateFreq()
+{
+ struct v4l2_frequency f;
+
+ memset(&f, 0, sizeof(f));
+ ioctl(fd, VIDIOC_G_FREQUENCY, &f);
+ freq->setValue(f.frequency);
+}
+
+void GeneralTab::updateFreqChannel()
+{
+ freqChannel->clear();
+ int tbl = freqTable->currentItem();
+ const struct v4l2_channel_list *list = v4l2_channel_lists[tbl].list;
+ for (unsigned i = 0; i < v4l2_channel_lists[tbl].count; i++)
+ freqChannel->insertItem(list[i].name);
+}
+
diff --git a/v4l2-apps/util/qv4l2/general-tab.h b/v4l2-apps/util/qv4l2/general-tab.h
new file mode 100644
index 000000000..44003fd40
--- /dev/null
+++ b/v4l2-apps/util/qv4l2/general-tab.h
@@ -0,0 +1,71 @@
+/* qv4l2: a control panel controlling v4l2 devices.
+ *
+ * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef GENERAL_TAB_H
+#define GENERAL_TAB_H
+
+#include <linux/videodev2.h>
+#include <qgrid.h>
+
+class QComboBox;
+class QSpinBox;
+
+class GeneralTab: public QGrid
+{
+ Q_OBJECT
+
+public:
+ GeneralTab(int fd, int n, QWidget *parent = 0);
+ virtual ~GeneralTab() {}
+
+private slots:
+ void inputChanged(int);
+ void outputChanged(int);
+ void inputAudioChanged(int);
+ void outputAudioChanged(int);
+ void standardChanged(int);
+ void freqTableChanged(int);
+ void freqChannelChanged(int);
+ void freqChanged(int);
+
+private:
+ void updateVideoInput();
+ void updateVideoOutput();
+ void updateAudioInput();
+ void updateAudioOutput();
+ void updateStandard();
+ void updateFreq();
+ void updateFreqChannel();
+
+ int fd;
+ struct v4l2_tuner tuner;
+
+ // General tab
+ QComboBox *videoInput;
+ QComboBox *videoOutput;
+ QComboBox *audioInput;
+ QComboBox *audioOutput;
+ QComboBox *tvStandard;
+ QSpinBox *freq;
+ QComboBox *freqTable;
+ QComboBox *freqChannel;
+};
+
+#endif
diff --git a/v4l2-apps/util/qv4l2/qv4l2.cpp b/v4l2-apps/util/qv4l2/qv4l2.cpp
index 1a6ef6a47..f9fb07e09 100644
--- a/v4l2-apps/util/qv4l2/qv4l2.cpp
+++ b/v4l2-apps/util/qv4l2/qv4l2.cpp
@@ -1,5 +1,6 @@
#include "qv4l2.h"
+#include "general-tab.h"
#include "v4l2.h"
#include <qimage.h>
@@ -11,9 +12,8 @@
#include <qfile.h>
#include <qfiledialog.h>
#include <qstatusbar.h>
-#include <qmessagebox.h>
#include <qapplication.h>
-#include <qaccel.h>
+#include <qmessagebox.h>
#include <qlineedit.h>
#include <qvalidator.h>
#include <qlayout.h>
@@ -26,8 +26,6 @@
#include <qcheckbox.h>
#include <qpushbutton.h>
#include <qtooltip.h>
-#include <qpainter.h>
-#include <qpaintdevicemetrics.h>
#include <qwhatsthis.h>
#include <fcntl.h>
@@ -117,18 +115,10 @@ void ApplicationWindow::setDevice(const QString &device)
ctrlMap.clear();
widgetMap.clear();
classMap.clear();
- videoInput = NULL;
- videoOutput = NULL;
- audioInput = NULL;
- audioOutput = NULL;
- tvStandard = NULL;
- freq = NULL;
- freqChannel = NULL;
- freqTable = NULL;
fd = ::open(device, O_RDONLY);
if (fd >= 0) {
- addGeneralTab();
+ tabs->addTab(new GeneralTab(fd, 4, tabs), "General");
addTabs();
}
if (QWidget *current = tabs->currentPage()) {
@@ -139,716 +129,6 @@ void ApplicationWindow::setDevice(const QString &device)
setCentralWidget(tabs);
}
-void ApplicationWindow::addGeneralTab()
-{
- int cnt = 0;
- QVBox *vbox = new QVBox(tabs);
- QGrid *grid = new QGrid(4, vbox);
- grid->setSpacing(3);
- tabs->addTab(vbox, "General");
-
- memset(&tuner, 0, sizeof(tuner));
- ioctl(fd, VIDIOC_G_TUNER, &tuner);
-
- struct v4l2_input vin;
- memset(&vin, 0, sizeof(vin));
- if (ioctl(fd, VIDIOC_ENUMINPUT, &vin) >= 0) {
- QLabel *label = new QLabel("Input", grid);
- label->setAlignment(Qt::AlignRight);
- videoInput = new QComboBox(grid);
- while (ioctl(fd, VIDIOC_ENUMINPUT, &vin) >= 0) {
- videoInput->insertItem((char *)vin.name);
- vin.index++;
- }
- connect(videoInput, SIGNAL(activated(int)), SLOT(inputChanged(int)));
- updateVideoInput();
- cnt++;
- }
-
- struct v4l2_output vout;
- memset(&vout, 0, sizeof(vout));
- if (ioctl(fd, VIDIOC_ENUMOUTPUT, &vout) >= 0) {
- QLabel *label = new QLabel("Output", grid);
- label->setAlignment(Qt::AlignRight);
- videoOutput = new QComboBox(grid);
- while (ioctl(fd, VIDIOC_ENUMOUTPUT, &vout) >= 0) {
- videoOutput->insertItem((char *)vout.name);
- vout.index++;
- }
- connect(videoOutput, SIGNAL(activated(int)), SLOT(outputChanged(int)));
- updateVideoOutput();
- cnt++;
- }
-
- struct v4l2_audio vaudio;
- memset(&vaudio, 0, sizeof(vaudio));
- if (ioctl(fd, VIDIOC_ENUMAUDIO, &vaudio) >= 0) {
- QLabel *label = new QLabel("Input Audio", grid);
- label->setAlignment(Qt::AlignRight);
- audioInput = new QComboBox(grid);
- vaudio.index = 0;
- while (ioctl(fd, VIDIOC_ENUMAUDIO, &vaudio) >= 0) {
- audioInput->insertItem((char *)vaudio.name);
- vaudio.index++;
- }
- connect(audioInput, SIGNAL(activated(int)), SLOT(inputAudioChanged(int)));
- updateAudioInput();
- cnt++;
- }
-
- struct v4l2_audioout vaudioout;
- memset(&vaudioout, 0, sizeof(vaudioout));
- if (ioctl(fd, VIDIOC_ENUMAUDOUT, &vaudioout) >= 0) {
- QLabel *label = new QLabel("Output Audio", grid);
- label->setAlignment(Qt::AlignRight);
- audioOutput = new QComboBox(grid);
- while (ioctl(fd, VIDIOC_ENUMAUDOUT, &vaudioout) >= 0) {
- audioOutput->insertItem((char *)vaudioout.name);
- vaudioout.index++;
- }
- connect(audioOutput, SIGNAL(activated(int)), SLOT(outputAudioChanged(int)));
- updateAudioOutput();
- cnt++;
- }
-
- struct v4l2_standard vs;
- memset(&vs, 0, sizeof(vs));
- if (ioctl(fd, VIDIOC_ENUMSTD, &vs) >= 0) {
- QLabel *label = new QLabel("TV Standard", grid);
- label->setAlignment(Qt::AlignRight);
- tvStandard = new QComboBox(grid);
- while (ioctl(fd, VIDIOC_ENUMSTD, &vs) >= 0) {
- tvStandard->insertItem((char *)vs.name);
- vs.index++;
- }
- connect(tvStandard, SIGNAL(activated(int)), SLOT(standardChanged(int)));
- updateStandard();
- cnt++;
- }
-
- bool first = cnt & 1;
-
- if (first) {
- QString what;
- QLabel *label = new QLabel("Frequency", grid);
- label->setAlignment(Qt::AlignRight);
- freq = new QSpinBox(tuner.rangelow, tuner.rangehigh, 1, grid);
- QWhatsThis::add(freq, what.sprintf("Frequency\n"
- "Low: %d\n"
- "High: %d\n",
- tuner.rangelow, tuner.rangehigh));
- connect(freq, SIGNAL(valueChanged(int)), SLOT(freqChanged(int)));
- updateFreq();
- cnt++;
- }
-
- {
- QLabel *label = new QLabel("Frequency Tables", grid);
- label->setAlignment(Qt::AlignRight);
- freqTable = new QComboBox(grid);
- for (int i = 0; v4l2_channel_lists[i].name; i++) {
- freqTable->insertItem(v4l2_channel_lists[i].name);
- }
- connect(freqTable, SIGNAL(activated(int)), SLOT(freqTableChanged(int)));
-
- label = new QLabel("Channels", grid);
- label->setAlignment(Qt::AlignRight);
- freqChannel = new QComboBox(grid);
- connect(freqChannel, SIGNAL(activated(int)), SLOT(freqChannelChanged(int)));
- updateFreqChannel();
- }
-
- if (!first) {
- QString what;
- QLabel *label = new QLabel("Frequency", grid);
- label->setAlignment(Qt::AlignRight);
- freq = new QSpinBox(tuner.rangelow, tuner.rangehigh, 1, grid);
- QWhatsThis::add(freq, what.sprintf("Frequency\n"
- "Low: %d\n"
- "High: %d\n",
- tuner.rangelow, tuner.rangehigh));
- connect(freq, SIGNAL(valueChanged(int)), SLOT(freqChanged(int)));
- updateFreq();
- cnt++;
- }
-
- if (cnt & 1) {
- new QWidget(grid);
- new QWidget(grid);
- }
- QWidget *stretch = new QWidget(grid);
- stretch->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
-}
-
-void ApplicationWindow::addTabs()
-{
- struct v4l2_queryctrl qctrl;
- unsigned ctrl_class;
- unsigned i;
- int id;
-
- memset(&qctrl, 0, sizeof(qctrl));
- qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
- while (::ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) {
- if ((qctrl.flags & V4L2_CTRL_FLAG_DISABLED) == 0) {
- ctrlMap[qctrl.id] = qctrl;
- if (qctrl.type != V4L2_CTRL_TYPE_CTRL_CLASS)
- classMap[V4L2_CTRL_ID2CLASS(qctrl.id)].push_back(qctrl.id);
- }
- qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
- }
- if (qctrl.id == V4L2_CTRL_FLAG_NEXT_CTRL) {
- strcpy((char *)qctrl.name, "User Controls");
- qctrl.id = V4L2_CTRL_CLASS_USER | 1;
- qctrl.type = V4L2_CTRL_TYPE_CTRL_CLASS;
- ctrlMap[qctrl.id] = qctrl;
- for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) {
- qctrl.id = id;
- if (::ioctl(fd, VIDIOC_QUERYCTRL, &qctrl))
- continue;
- if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED)
- continue;
- ctrlMap[qctrl.id] = qctrl;
- classMap[V4L2_CTRL_CLASS_USER].push_back(qctrl.id);
- }
- for (qctrl.id = V4L2_CID_PRIVATE_BASE;
- ::ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) {
- if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED)
- continue;
- ctrlMap[qctrl.id] = qctrl;
- classMap[V4L2_CTRL_CLASS_USER].push_back(qctrl.id);
- }
- }
-
- for (ClassMap::iterator iter = classMap.begin(); iter != classMap.end(); ++iter) {
- ctrl_class = V4L2_CTRL_ID2CLASS(iter->second[0]);
- id = ctrl_class | 1;
- const struct v4l2_queryctrl &qctrl = ctrlMap[id];
- QVBox *vbox = new QVBox(tabs);
- QGrid *grid = new QGrid(4, vbox);
- grid->setSpacing(3);
- tabs->addTab(vbox, (char *)qctrl.name);
- for (i = 0; i < iter->second.size(); i++) {
- if (i & 1)
- id = iter->second[(1+iter->second.size()) / 2 + i / 2];
- else
- id = iter->second[i / 2];
- addCtrl(grid, ctrlMap[id]);
- }
- finishGrid(vbox, grid, ctrl_class, i & 1);
- }
-}
-
-void ApplicationWindow::finishGrid(QWidget *vbox, QGrid *grid, unsigned ctrl_class, bool odd)
-{
- if (odd) {
- new QWidget(grid);
- new QWidget(grid);
- }
- QWidget *stretch = new QWidget(grid);
- stretch->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
-
- QFrame *frame = new QFrame(vbox);
- frame->setFrameShape(QFrame::HLine);
- frame->setFrameShadow(QFrame::Sunken);
- frame->setMargin(3);
-
- QHBox *hbox = new QHBox(vbox);
- hbox->setSpacing(3);
-
- QCheckBox *cbox = new QCheckBox("Update on change", hbox);
- widgetMap[ctrl_class | CTRL_UPDATE_ON_CHANGE] = cbox;
- connect(cbox, SIGNAL(clicked()), sigMapper, SLOT(map()));
- sigMapper->setMapping(cbox, ctrl_class | CTRL_UPDATE_ON_CHANGE);
-
- stretch = new QWidget(hbox);
- stretch->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
-
- QPushButton *defBut = new QPushButton("Set Defaults", hbox);
- widgetMap[ctrl_class | CTRL_DEFAULTS] = defBut;
- connect(defBut, SIGNAL(clicked()), sigMapper, SLOT(map()));
- sigMapper->setMapping(defBut, ctrl_class | CTRL_DEFAULTS);
-
- QPushButton *refreshBut = new QPushButton("Refresh", hbox);
- widgetMap[ctrl_class | CTRL_REFRESH] = refreshBut;
- connect(refreshBut, SIGNAL(clicked()), sigMapper, SLOT(map()));
- sigMapper->setMapping(refreshBut, ctrl_class | CTRL_REFRESH);
-
- QPushButton *button = new QPushButton("Update", hbox);
- widgetMap[ctrl_class | CTRL_UPDATE] = button;
- connect(button, SIGNAL(clicked()), sigMapper, SLOT(map()));
- sigMapper->setMapping(button, ctrl_class | CTRL_UPDATE);
- connect(cbox, SIGNAL(toggled(bool)), button, SLOT(setDisabled(bool)));
-
- cbox->setChecked(ctrl_class == V4L2_CTRL_CLASS_USER);
-
- refresh(ctrl_class);
-}
-
-void ApplicationWindow::addCtrl(QGrid *grid, const struct v4l2_queryctrl &qctrl)
-{
- QIntValidator *val;
- QLineEdit *edit;
- QString name((char *)qctrl.name);
- QComboBox *combo;
- struct v4l2_querymenu qmenu;
-
- QLabel *label = new QLabel(name, grid);
- label->setAlignment(Qt::AlignRight);
-
- switch (qctrl.type) {
- case V4L2_CTRL_TYPE_INTEGER:
- if (qctrl.flags & V4L2_CTRL_FLAG_SLIDER) {
- widgetMap[qctrl.id] =
- new QSlider(qctrl.minimum, qctrl.maximum,
- qctrl.step, qctrl.default_value,
- Horizontal, grid);
- connect(widgetMap[qctrl.id], SIGNAL(valueChanged(int)),
- sigMapper, SLOT(map()));
- break;
- }
-
- if (qctrl.maximum - qctrl.minimum <= 255) {
- widgetMap[qctrl.id] =
- new QSpinBox(qctrl.minimum, qctrl.maximum, 1, grid);
- connect(widgetMap[qctrl.id], SIGNAL(valueChanged(int)),
- sigMapper, SLOT(map()));
- break;
- }
-
- val = new QIntValidator(qctrl.minimum, qctrl.maximum, grid);
- edit = new QLineEdit(grid);
- edit->setValidator(val);
- widgetMap[qctrl.id] = edit;
- connect(widgetMap[qctrl.id], SIGNAL(lostFocus()),
- sigMapper, SLOT(map()));
- connect(widgetMap[qctrl.id], SIGNAL(returnPressed()),
- sigMapper, SLOT(map()));
- break;
-
- case V4L2_CTRL_TYPE_INTEGER64:
- widgetMap[qctrl.id] = new QLineEdit(grid);
- connect(widgetMap[qctrl.id], SIGNAL(lostFocus()),
- sigMapper, SLOT(map()));
- connect(widgetMap[qctrl.id], SIGNAL(returnPressed()),
- sigMapper, SLOT(map()));
- break;
-
- case V4L2_CTRL_TYPE_BOOLEAN:
- label->setText("");
- widgetMap[qctrl.id] = new QCheckBox(name, grid);
- connect(widgetMap[qctrl.id], SIGNAL(clicked()),
- sigMapper, SLOT(map()));
- break;
-
- case V4L2_CTRL_TYPE_BUTTON:
- label->setText("");
- widgetMap[qctrl.id] = new QPushButton((char *)qctrl.name, grid);
- connect(widgetMap[qctrl.id], SIGNAL(clicked()),
- sigMapper, SLOT(map()));
- break;
-
- case V4L2_CTRL_TYPE_MENU:
- combo = new QComboBox(grid);
- widgetMap[qctrl.id] = combo;
- for (int i = qctrl.minimum; i <= qctrl.maximum; i++) {
- qmenu.id = qctrl.id;
- qmenu.index = i;
- if (::ioctl(fd, VIDIOC_QUERYMENU, &qmenu))
- continue;
- combo->insertItem((char *)qmenu.name);
- }
- connect(widgetMap[qctrl.id], SIGNAL(activated(int)),
- sigMapper, SLOT(map()));
- break;
-
- default:
- return;
- }
- sigMapper->setMapping(widgetMap[qctrl.id], qctrl.id);
- if (qctrl.flags & (V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_INACTIVE))
- widgetMap[qctrl.id]->setDisabled(true);
-}
-
-void ApplicationWindow::ctrlAction(int id)
-{
- unsigned ctrl_class = V4L2_CTRL_ID2CLASS(id);
- if (ctrl_class == V4L2_CID_PRIVATE_BASE)
- ctrl_class = V4L2_CTRL_CLASS_USER;
- unsigned ctrl = id & 0xffff;
- QCheckBox *cbox = static_cast<QCheckBox *>(widgetMap[ctrl_class | CTRL_UPDATE_ON_CHANGE]);
- bool update = cbox->isChecked();
- bool all = (ctrl == CTRL_UPDATE || (update && ctrl == CTRL_UPDATE_ON_CHANGE));
-
- if (ctrl == CTRL_DEFAULTS) {
- setDefaults(ctrl_class);
- return;
- }
- if (ctrl == CTRL_REFRESH) {
- refresh(ctrl_class);
- return;
- }
- if (!update && !all && ctrlMap[id].type != V4L2_CTRL_TYPE_BUTTON)
- return;
- if (ctrl_class == V4L2_CTRL_CLASS_USER) {
- if (!all) {
- updateCtrl(id);
- return;
- }
- for (unsigned i = 0; i < classMap[ctrl_class].size(); i++) {
- updateCtrl(classMap[ctrl_class][i]);
- }
- return;
- }
- if (!all) {
- updateCtrl(id);
- return;
- }
- unsigned count = classMap[ctrl_class].size();
- struct v4l2_ext_control *c = new v4l2_ext_control[count];
- struct v4l2_ext_controls ctrls;
- int idx = 0;
-
- for (unsigned i = 0; i < count; i++) {
- unsigned id = classMap[ctrl_class][i];
-
- if (ctrlMap[id].flags & (V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_INACTIVE))
- continue;
- c[idx].id = id;
- if (ctrlMap[id].type == V4L2_CTRL_TYPE_INTEGER64)
- c[idx].value64 = getVal64(id);
- else
- c[idx].value = getVal(id);
- idx++;
- }
- memset(&ctrls, 0, sizeof(ctrls));
- ctrls.count = idx;
- ctrls.ctrl_class = ctrl_class;
- ctrls.controls = c;
- if (::ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls)) {
- int err = errno;
-
- if (ctrls.error_idx >= ctrls.count) {
- printf("error: %s\n", strerror(err));
- }
- else {
- id = c[ctrls.error_idx].id;
- printf("error %08x (%s): %s\n", id,
- ctrlMap[id].name, strerror(err));
- }
- }
- delete [] c;
- refresh(ctrl_class);
-}
-
-long long ApplicationWindow::getVal64(unsigned id)
-{
- const v4l2_queryctrl &qctrl = ctrlMap[id];
- QWidget *w = widgetMap[qctrl.id];
- long long v = 0;
-
- switch (qctrl.type) {
- case V4L2_CTRL_TYPE_INTEGER64:
- v = static_cast<QLineEdit *>(w)->text().toLongLong();
- break;
- default:
- break;
- }
- setWhat(w, id, v);
- return v;
-}
-
-int ApplicationWindow::getVal(unsigned id)
-{
- const v4l2_queryctrl &qctrl = ctrlMap[id];
- QWidget *w = widgetMap[qctrl.id];
- v4l2_querymenu qmenu;
- int i, idx;
- int v = 0;
-
- switch (qctrl.type) {
- case V4L2_CTRL_TYPE_INTEGER:
- if (qctrl.flags & V4L2_CTRL_FLAG_SLIDER) {
- v = static_cast<QSlider *>(w)->value();
- break;
- }
-
- if (qctrl.maximum - qctrl.minimum <= 255) {
- v = static_cast<QSpinBox *>(w)->value();
- break;
- }
- v = static_cast<QLineEdit *>(w)->text().toInt();
- break;
-
- case V4L2_CTRL_TYPE_BOOLEAN:
- v = static_cast<QCheckBox *>(w)->isChecked();
- break;
-
- case V4L2_CTRL_TYPE_MENU:
- idx = static_cast<QComboBox *>(w)->currentItem();
- for (i = qctrl.minimum; i <= qctrl.maximum; i++) {
- qmenu.id = qctrl.id;
- qmenu.index = i;
- if (::ioctl(fd, VIDIOC_QUERYMENU, &qmenu))
- continue;
- if (idx-- == 0)
- break;
- }
- v = i;
- break;
-
- default:
- break;
- }
- setWhat(w, id, v);
- return v;
-}
-
-void ApplicationWindow::updateCtrl(unsigned id)
-{
- unsigned ctrl_class = V4L2_CTRL_ID2CLASS(id);
- if (ctrl_class == V4L2_CID_PRIVATE_BASE)
- ctrl_class = V4L2_CTRL_CLASS_USER;
-
- if (ctrlMap[id].flags & (V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_INACTIVE))
- return;
-
- if (ctrl_class == V4L2_CTRL_CLASS_USER) {
- struct v4l2_control c;
-
- c.id = id;
- c.value = getVal(id);
- if (::ioctl(fd, VIDIOC_S_CTRL, &c)) {
- int err = errno;
- char buf[200];
-
- sprintf(buf, "Error %08x (%s): %s", id,
- ctrlMap[id].name, strerror(err));
- statusBar()->message(buf, 10000);
- }
- return;
- }
- struct v4l2_ext_control c;
- struct v4l2_ext_controls ctrls;
-
- memset(&c, 0, sizeof(c));
- memset(&ctrls, 0, sizeof(ctrls));
- c.id = id;
- if (ctrlMap[id].type == V4L2_CTRL_TYPE_INTEGER64)
- c.value64 = getVal64(id);
- else
- c.value = getVal(id);
- ctrls.count = 1;
- ctrls.ctrl_class = ctrl_class;
- ctrls.controls = &c;
- if (::ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls)) {
- int err = errno;
- char buf[200];
-
- sprintf(buf, "Error %08x (%s): %s", id,
- ctrlMap[id].name, strerror(err));
- statusBar()->message(buf, 10000);
- }
- else if (ctrlMap[id].flags & V4L2_CTRL_FLAG_UPDATE)
- refresh(ctrl_class);
- else {
- if (ctrlMap[id].type == V4L2_CTRL_TYPE_INTEGER64)
- setVal64(id, c.value64);
- else
- setVal(id, c.value);
- }
-}
-
-void ApplicationWindow::refresh(unsigned ctrl_class)
-{
- if (ctrl_class == V4L2_CTRL_CLASS_USER) {
- for (unsigned i = 0; i < classMap[ctrl_class].size(); i++) {
- unsigned id = classMap[ctrl_class][i];
-
- v4l2_control c;
-
- c.id = id;
- if (::ioctl(fd, VIDIOC_G_CTRL, &c)) {
- int err = errno;
- char buf[200];
-
- sprintf(buf, "Error %08x (%s): %s", id,
- ctrlMap[id].name, strerror(err));
- statusBar()->message(buf, 10000);
- }
- setVal(id, c.value);
- }
- return;
- }
- unsigned count = classMap[ctrl_class].size();
- struct v4l2_ext_control *c = new v4l2_ext_control[count];
- struct v4l2_ext_controls ctrls;
-
- for (unsigned i = 0; i < count; i++) {
- c[i].id = classMap[ctrl_class][i];
- }
- memset(&ctrls, 0, sizeof(ctrls));
- ctrls.count = count;
- ctrls.ctrl_class = ctrl_class;
- ctrls.controls = c;
- if (::ioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls)) {
- int err = errno;
-
- if (ctrls.error_idx >= ctrls.count) {
- statusBar()->message(strerror(err), 10000);
- }
- else {
- unsigned id = c[ctrls.error_idx].id;
- char buf[200];
-
- sprintf(buf, "Error %08x (%s): %s", id,
- ctrlMap[id].name, strerror(err));
- statusBar()->message(buf, 10000);
- }
- }
- else {
- for (unsigned i = 0; i < ctrls.count; i++) {
- unsigned id = c[i].id;
- if (ctrlMap[id].type == V4L2_CTRL_TYPE_INTEGER64)
- setVal64(id, c[i].value64);
- else
- setVal(id, c[i].value);
- ::ioctl(fd, VIDIOC_QUERYCTRL, &ctrlMap[id]);
- widgetMap[id]->setDisabled(ctrlMap[id].flags &
- (V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_INACTIVE));
- }
- }
- delete [] c;
-}
-
-void ApplicationWindow::setWhat(QWidget *w, unsigned id, long long v)
-{
- const v4l2_queryctrl &qctrl = ctrlMap[id];
- QString what;
- QString flags = getCtrlFlags(qctrl.flags);
-
- switch (qctrl.type) {
- case V4L2_CTRL_TYPE_INTEGER:
- QWhatsThis::add(w, what.sprintf("Integer type control\n"
- "Minimum: %d\n"
- "Maximum: %d\n"
- "Current: %d\n"
- "Default: %d\n",
- qctrl.minimum, qctrl.maximum, (int)v, qctrl.default_value) + flags);
- break;
-
- case V4L2_CTRL_TYPE_INTEGER64:
- QWhatsThis::add(w, what.sprintf("64-bit Integer type control\n"
- "Current: %lld\n", v) + flags);
- break;
-
- case V4L2_CTRL_TYPE_BUTTON:
- QWhatsThis::add(w, what.sprintf("Button type control\n") + flags);
- break;
-
- case V4L2_CTRL_TYPE_BOOLEAN:
- QWhatsThis::add(w, what.sprintf("Boolean type control\n"
- "Current: %d\n"
- "Default: %d\n",
- (int)v, qctrl.default_value) + flags);
- break;
-
- case V4L2_CTRL_TYPE_MENU:
- QWhatsThis::add(w, what.sprintf("Menu type control\n"
- "Minimum: %d\n"
- "Maximum: %d\n"
- "Current: %d\n"
- "Default: %d\n",
- qctrl.minimum, qctrl.maximum, (int)v, qctrl.default_value) + flags);
- break;
- default:
- break;
- }
-}
-
-void ApplicationWindow::setVal(unsigned id, int v)
-{
- const v4l2_queryctrl &qctrl = ctrlMap[id];
- v4l2_querymenu qmenu;
- QWidget *w = widgetMap[qctrl.id];
- int i, idx;
-
- switch (qctrl.type) {
- case V4L2_CTRL_TYPE_INTEGER:
- if (qctrl.flags & V4L2_CTRL_FLAG_SLIDER)
- static_cast<QSlider *>(w)->setValue(v);
- else if (qctrl.maximum - qctrl.minimum <= 255)
- static_cast<QSpinBox *>(w)->setValue(v);
- else
- static_cast<QLineEdit *>(w)->setText(QString::number(v));
- break;
-
- case V4L2_CTRL_TYPE_BOOLEAN:
- static_cast<QCheckBox *>(w)->setChecked(v);
- break;
-
- case V4L2_CTRL_TYPE_MENU:
- idx = 0;
- for (i = qctrl.minimum; i <= v; i++) {
- qmenu.id = id;
- qmenu.index = i;
- if (::ioctl(fd, VIDIOC_QUERYMENU, &qmenu))
- continue;
- idx++;
- }
- static_cast<QComboBox *>(w)->setCurrentItem(idx - 1);
- break;
- default:
- break;
- }
- setWhat(w, id, v);
-}
-
-void ApplicationWindow::setVal64(unsigned id, long long v)
-{
- const v4l2_queryctrl &qctrl = ctrlMap[id];
- QWidget *w = widgetMap[qctrl.id];
-
- switch (qctrl.type) {
- case V4L2_CTRL_TYPE_INTEGER64:
- static_cast<QLineEdit *>(w)->setText(QString::number(v));
- break;
- default:
- break;
- }
- setWhat(w, id, v);
-}
-
-void ApplicationWindow::setDefaults(unsigned ctrl_class)
-{
- for (unsigned i = 0; i < classMap[ctrl_class].size(); i++) {
- unsigned id = classMap[ctrl_class][i];
-
- if (ctrlMap[id].type != V4L2_CTRL_TYPE_INTEGER64 &&
- ctrlMap[id].type != V4L2_CTRL_TYPE_BUTTON)
- setVal(id, ctrlMap[id].default_value);
- }
- ctrlAction(ctrl_class | CTRL_UPDATE);
-}
-
-QString ApplicationWindow::getCtrlFlags(unsigned flags)
-{
- QString s;
-
- if (flags & V4L2_CTRL_FLAG_GRABBED)
- s += "grabbed ";
- if (flags & V4L2_CTRL_FLAG_READ_ONLY)
- s += "readonly ";
- if (flags & V4L2_CTRL_FLAG_UPDATE)
- s += "update ";
- if (flags & V4L2_CTRL_FLAG_INACTIVE)
- s += "inactive ";
- if (flags & V4L2_CTRL_FLAG_SLIDER)
- s += "slider ";
- if (s.length()) s = QString("Flags: ") + s;
- return s;
-}
-
void ApplicationWindow::choose()
{
QString fn = QFileDialog::getOpenFileName( "/dev/v4l", QString::null,
@@ -866,158 +146,6 @@ void ApplicationWindow::closeEvent( QCloseEvent* ce )
ce->accept();
}
-void ApplicationWindow::inputChanged(int input)
-{
- doIoctl("Set Input", VIDIOC_S_INPUT, &input);
- struct v4l2_audio vaudio;
- memset(&vaudio, 0, sizeof(vaudio));
- if (audioInput && ioctl(fd, VIDIOC_G_AUDIO, &vaudio) >= 0) {
- audioInput->setCurrentItem(vaudio.index);
- updateAudioInput();
- }
- updateVideoInput();
-}
-
-void ApplicationWindow::outputChanged(int output)
-{
- doIoctl("Set Output", VIDIOC_S_OUTPUT, &output);
- updateVideoOutput();
-}
-
-void ApplicationWindow::inputAudioChanged(int input)
-{
- struct v4l2_audio vaudio;
- memset(&vaudio, 0, sizeof(vaudio));
- vaudio.index = input;
- doIoctl("Set Audio Input", VIDIOC_S_AUDIO, &vaudio);
- updateAudioInput();
-}
-
-void ApplicationWindow::outputAudioChanged(int output)
-{
- struct v4l2_audioout vaudioout;
- memset(&vaudioout, 0, sizeof(vaudioout));
- vaudioout.index = output;
- doIoctl("Set Audio Output", VIDIOC_S_AUDOUT, &vaudioout);
- updateAudioOutput();
-}
-
-void ApplicationWindow::standardChanged(int std)
-{
- struct v4l2_standard vs;
- memset(&vs, 0, sizeof(vs));
- vs.index = std;
- ioctl(fd, VIDIOC_ENUMSTD, &vs);
- doIoctl("Set TV Standard", VIDIOC_S_STD, &vs.id);
- updateStandard();
-}
-
-void ApplicationWindow::freqTableChanged(int)
-{
- updateFreqChannel();
- freqChannelChanged(0);
-}
-
-void ApplicationWindow::freqChannelChanged(int idx)
-{
- freq->setValue((int)(v4l2_channel_lists[freqTable->currentItem()].list[idx].freq / 62.5));
-}
-
-void ApplicationWindow::freqChanged(int val)
-{
- struct v4l2_frequency f;
-
- memset(&f, 0, sizeof(f));
- f.type = V4L2_TUNER_ANALOG_TV;
- f.frequency = val;
- doIoctl("Set frequency", VIDIOC_S_FREQUENCY, &f);
-}
-
-void ApplicationWindow::updateVideoInput()
-{
- int input;
-
- ioctl(fd, VIDIOC_G_INPUT, &input);
- videoInput->setCurrentItem(input);
-}
-
-void ApplicationWindow::updateVideoOutput()
-{
- int output;
-
- ioctl(fd, VIDIOC_G_OUTPUT, &output);
- videoOutput->setCurrentItem(output);
-}
-
-void ApplicationWindow::updateAudioInput()
-{
- struct v4l2_audio audio;
- QString what;
-
- memset(&audio, 0, sizeof(audio));
- ioctl(fd, VIDIOC_G_AUDIO, &audio);
- audioInput->setCurrentItem(audio.index);
- if (audio.capability & V4L2_AUDCAP_STEREO)
- what = "stereo input";
- else
- what = "mono input";
- if (audio.capability & V4L2_AUDCAP_AVL)
- what += ", has AVL";
- if (audio.mode & V4L2_AUDMODE_AVL)
- what += ", AVL is on";
- QWhatsThis::add(audioInput, what);
-}
-
-void ApplicationWindow::updateAudioOutput()
-{
- struct v4l2_audioout audio;
-
- memset(&audio, 0, sizeof(audio));
- ioctl(fd, VIDIOC_G_AUDOUT, &audio);
- audioOutput->setCurrentItem(audio.index);
-}
-
-void ApplicationWindow::updateStandard()
-{
- v4l2_std_id std;
- struct v4l2_standard vs;
- QString what;
- ioctl(fd, VIDIOC_G_STD, &std);
- memset(&vs, 0, sizeof(vs));
- while (ioctl(fd, VIDIOC_ENUMSTD, &vs) != -1) {
- if (vs.id & std) {
- tvStandard->setCurrentItem(vs.index);
- what.sprintf("TV Standard (0x%llX)\n"
- "Frame period: %f (%d/%d)\n"
- "Frame lines: %d\n", std,
- (double)vs.frameperiod.numerator / vs.frameperiod.denominator,
- vs.frameperiod.numerator, vs.frameperiod.denominator,
- vs.framelines);
- QWhatsThis::add(tvStandard, what);
- return;
- }
- vs.index++;
- }
-}
-
-void ApplicationWindow::updateFreq()
-{
- struct v4l2_frequency f;
-
- memset(&f, 0, sizeof(f));
- ioctl(fd, VIDIOC_G_FREQUENCY, &f);
- freq->setValue(f.frequency);
-}
-
-void ApplicationWindow::updateFreqChannel()
-{
- freqChannel->clear();
- int tbl = freqTable->currentItem();
- const struct v4l2_channel_list *list = v4l2_channel_lists[tbl].list;
- for (unsigned i = 0; i < v4l2_channel_lists[tbl].count; i++)
- freqChannel->insertItem(list[i].name);
-}
-
bool ApplicationWindow::doIoctl(QString descr, unsigned cmd, void *arg)
{
statusBar()->clear();
@@ -1036,14 +164,15 @@ void ApplicationWindow::about()
"This program allows easy experimenting with video4linux devices.");
}
+ApplicationWindow *g_mw;
int main(int argc, char **argv)
{
QApplication a(argc, argv);
- ApplicationWindow *mw = new ApplicationWindow();
- mw->setCaption( "V4L2 Control Panel" );
- mw->setDevice("/dev/video0");
- mw->show();
+ g_mw = new ApplicationWindow();
+ g_mw->setCaption( "V4L2 Control Panel" );
+ g_mw->setDevice("/dev/video0");
+ g_mw->show();
a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) );
return a.exec();
}
diff --git a/v4l2-apps/util/qv4l2/qv4l2.h b/v4l2-apps/util/qv4l2/qv4l2.h
index 1145af417..1a0a8e15d 100644
--- a/v4l2-apps/util/qv4l2/qv4l2.h
+++ b/v4l2-apps/util/qv4l2/qv4l2.h
@@ -1,15 +1,24 @@
-/****************************************************************************
-** $Id: qt/application.h 3.3.6 edited Aug 31 2005 $
-**
-** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
-**
-** This file is part of an example program for Qt. This example
-** program may be used, distributed and modified without limitation.
-**
-*****************************************************************************/
-
-#ifndef APPLICATION_H
-#define APPLICATION_H
+/* qv4l2: a control panel controlling v4l2 devices.
+ *
+ * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef QV4L2_H
+#define QV4L2_H
#include <qmainwindow.h>
#include <qtabwidget.h>
@@ -18,7 +27,6 @@
#include <map>
#include <vector>
-#define __user
#include <linux/videodev2.h>
class QComboBox;
@@ -45,6 +53,7 @@ public:
~ApplicationWindow();
void setDevice(const QString &device);
+ bool doIoctl(QString descr, unsigned cmd, void *arg);
protected:
void closeEvent( QCloseEvent* );
@@ -52,20 +61,11 @@ protected:
private slots:
void choose();
void ctrlAction(int);
- void inputChanged(int);
- void outputChanged(int);
- void inputAudioChanged(int);
- void outputAudioChanged(int);
- void standardChanged(int);
- void freqTableChanged(int);
- void freqChannelChanged(int);
- void freqChanged(int);
void about();
private:
void addTabs();
- void addGeneralTab();
void finishGrid(QWidget *vbox, QGrid *grid, unsigned ctrl_class, bool odd);
void addCtrl(QGrid *grid, const struct v4l2_queryctrl &qctrl);
void updateCtrl(unsigned id);
@@ -77,7 +77,6 @@ private:
void setVal64(unsigned id, long long v);
QString getCtrlFlags(unsigned flags);
void setWhat(QWidget *w, unsigned id, long long v);
- bool doIoctl(QString descr, unsigned cmd, void *arg);
void updateVideoInput();
void updateVideoOutput();
void updateAudioInput();
@@ -93,18 +92,8 @@ private:
CtrlMap ctrlMap;
WidgetMap widgetMap;
ClassMap classMap;
- struct v4l2_tuner tuner;
-
- // General tab
- QComboBox *videoInput;
- QComboBox *videoOutput;
- QComboBox *audioInput;
- QComboBox *audioOutput;
- QComboBox *tvStandard;
- QSpinBox *freq;
- QComboBox *freqTable;
- QComboBox *freqChannel;
};
+extern ApplicationWindow *g_mw;
#endif
diff --git a/v4l2-apps/util/qv4l2/qv4l2.pro b/v4l2-apps/util/qv4l2/qv4l2.pro
index d9b5162aa..c53a098b5 100644
--- a/v4l2-apps/util/qv4l2/qv4l2.pro
+++ b/v4l2-apps/util/qv4l2/qv4l2.pro
@@ -4,8 +4,9 @@
TEMPLATE = app
INCLUDEPATH += . ../../../linux/include ../../lib
+CONFIG += debug
# Input
-HEADERS += qv4l2.h
-SOURCES += qv4l2.cpp
+HEADERS += qv4l2.h general-tab.h
+SOURCES += qv4l2.cpp general-tab.cpp ctrl-tab.cpp
LIBS += -lv4l2 -L../../lib