⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctrl-tab.cpp

📁 trident tm5600的linux驱动
💻 CPP
字号:
#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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -