Unix Technical Forum

add tunerctl to base system

This is a discussion on add tunerctl to base system within the lucky.openbsd.tech forums, part of the OpenBSD category; --> robert@ suggested that tunerctl(1), a program for manipulating /dev/tunerN devices associated with bktr(4), be part of the base system. ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > lucky.openbsd.tech

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-22-2008, 11:40 AM
Jacob Meuser
 
Posts: n/a
Default add tunerctl to base system

robert@ suggested that tunerctl(1), a program for manipulating
/dev/tunerN devices associated with bktr(4), be part of the
base system. mickey@ had also suggested this some time ago,
and now that bktr(4) behaves a little nicer, I think it would
be nice as well.

below is a patch to add tunerctl and a manpage for it in
src/usr.bin.

comments/testing would be appreciated, thanks!

--
<jakemsr@jakemsr.com>

Index: usr.bin/Makefile
================================================== =================
RCS file: /home/cvs/OpenBSD/src/usr.bin/Makefile,v
retrieving revision 1.93
diff -u -r1.93 Makefile
--- usr.bin/Makefile 28 May 2005 04:43:18 -0000 1.93
+++ usr.bin/Makefile 4 Jul 2005 00:15:52 -0000
@@ -19,8 +19,8 @@
rup ruptime rusers rwall rwho script sectok sed shar showmount skey \
skeyaudit skeyinfo skeyinit sort spell split ssh stat su sup systat \
sudo tail talk tcopy tee telnet tftp tic time tip tn3270 top touch \
- tput tr true tset tsort tty usbhidaction usbhidctl ul uname unexpand \
- unifdef uniq units \
+ tput tr true tset tsort tty tunerctl usbhidaction usbhidctl ul uname \
+ unexpand unifdef uniq units \
unvis users uudecode uuencode vacation vgrind vi vis vmstat w wall wc \
what whatis which who whois window write x99token xargs xinstall xlint \
xstr yacc yes
Index: usr.bin/tunerctl/Makefile
================================================== =================
RCS file: usr.bin/tunerctl/Makefile
diff -N usr.bin/tunerctl/Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ usr.bin/tunerctl/Makefile 4 Jul 2005 00:17:00 -0000
@@ -0,0 +1,6 @@
+# $OpenBSD$
+
+PROG= tunerctl
+CFLAGS+=-Wall
+
+.include <bsd.prog.mk>
Index: usr.bin/tunerctl/tunerctl.1
================================================== =================
RCS file: usr.bin/tunerctl/tunerctl.1
diff -N usr.bin/tunerctl/tunerctl.1
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ usr.bin/tunerctl/tunerctl.1 4 Jul 2005 01:13:02 -0000
@@ -0,0 +1,129 @@
+.\"
+.\" Copyright (c) 2005 Jacob Meuser <jakemsr@jakemsr.com>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" $OpenBSD$
+.\"
+.Dd Mar 27, 2005
+.Dt TUNERCTL 1
+.Os
+.Sh NAME
+.Nm tunerctl
+.Nd manipulate
+.Xr bktr 4
+tuner devices.
+.Sh SYNOPSIS
+.Nm
+.Op Fl nv
+.Op Fl f Ar file
+.Fl a
+.Nm
+.Op Fl nv
+.Op Fl f Ar file
+.Ar name
+.Op Ar ...
+.Nm
+.Op Fl q
+.Pf \ \& Op Fl f Ar file
+.Xo
+.Ar name Ns = Ns Ar value
+.Op Ar ...
+.Xc
+.Sh DESCRIPTION
+The
+.Nm
+command displays or sets various variables that affect the behaviour of
+.Xr bktr 4
+device tuners.
+If a list of variables is present on the command line,
+.Nm
+prints the current value of those variables for the specified device.
+By default,
+.Nm
+operates on the
+.Pa /dev/tuner0
+device.
+.Pp
+The options are as follows:
+.Bl -tag -width "name=value"
+.It Fl a
+Print all device variables and their current values.
+.It Fl f Ar file
+Specify an alternative tuner device.
+.It Fl n
+Suppress printing of the variable names.
+.It Fl q
+Suppress all printing when setting a variable.
+.It Fl v
+Show the possible values of enumeration and range valued queries.
+Enumeration values are show in
+.Dq []
+and ranges are show in
+.Dq () .
+.It Ar name Ns = Ns Ar value
+Attempt to set the specified variable
+.Ar name
+to
+.Ar value .
+.El
+.Pp
+Depending on the features of a specific tuner, the setting of some
+variables may not have any effect.
+.Pp
+Variable names explained:
+.Bl -tag -width contrast
+.It Ic chanset
+TV tuner channel set.
+.It Ic channel
+TV tuner channel.
+.It Ic freq
+Frequency in MHz.
+.It Ic afc
+Automatic Frequency Control.
+.It Ic audio
+Audio source.
+.It Ic mute
+Audio mute.
+.It Ic bright
+Video brightness.
+.It Ic contrast
+Video contrast.
+.It Ic hue
+Video hue.
+.It Ic usat
+Video
+.Ql U
+(blue) saturation.
+.It Ic vsat
+Video
+.Ql V
+(red) saturation.
+.El
+.Sh FILES
+.Bl -tag -width /dev/tuner0
+.It Pa /dev/tuner0
+default tuner device
+.El
+.Sh EXAMPLES
+The command
+.Pp
+.Dl "$ tunerctl chanset=nabcst channel=13"
+.Pp
+sets the tuner to North American broadcast TV channel 13.
+.Sh SEE ALSO
+.Xr bktr 4
+.Sh AUTHORS
+.Nm
+and this manual page were written by
+.An Jacob Meuser Aq jakemsr@jakemsr.com .
Index: usr.bin/tunerctl/tunerctl.c
================================================== =================
RCS file: usr.bin/tunerctl/tunerctl.c
diff -N usr.bin/tunerctl/tunerctl.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ usr.bin/tunerctl/tunerctl.c 4 Jul 2005 00:43:12 -0000
@@ -0,0 +1,469 @@
+/*
+ * Copyright (c) 2005 Jacob Meuser <jakemsr@jakemsr.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * $OpenBSD$
+ */
+
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+
+#include <dev/ic/bt8xx.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define DEFAULT_TUNER_DEVICE "/dev/tuner0"
+
+struct fields {
+ char *name;
+ int type;
+#define INT 1
+#define ASRC 2
+#define CSET 3
+#define MUTE 4
+#define OFFON 5
+#define FREQ 6
+#define VSAT 7
+#define USAT 8
+#define HUE 9
+#define BRIGHT 10
+#define CONTR 11
+ int val;
+ long io_set;
+ long io_get;
+ int valmin;
+ int valmax;
+} fields[] = {
+{ "chanset", CSET, 0, TVTUNER_SETTYPE, TVTUNER_GETTYPE, 0, 0 },
+{ "channel", INT, 0, TVTUNER_SETCHNL, TVTUNER_GETCHNL, 0, 150 },
+{ "freq", FREQ, 0, TVTUNER_SETFREQ, TVTUNER_GETFREQ, 608, 14240 },
+{ "afc", OFFON, 0, TVTUNER_SETAFC, TVTUNER_GETAFC, 0, 1 },
+{ "audio", ASRC, 0, BT848_SAUDIO, BT848_GAUDIO, 0, 0 },
+{ "mute", MUTE, 0, BT848_SAUDIO, BT848_GAUDIO, 0, 1 },
+{ "bright", BRIGHT, 0, BT848_SBRIG, BT848_GBRIG,
+ BT848_BRIGHTMIN, BT848_BRIGHTMAX },
+{ "contrast", CONTR, 0, BT848_SCONT, BT848_GCONT,
+ BT848_CONTRASTMIN, BT848_CONTRASTMAX },
+{ "hue", HUE, 0, BT848_SHUE, BT848_GHUE, BT848_HUEMIN,
+ BT848_HUEMAX },
+{ "usat", USAT, 0, BT848_SUSAT, BT848_GUSAT, BT848_SATUMIN,
+ BT848_SATUMAX },
+{ "vsat", VSAT, 0, BT848_SVSAT, BT848_GVSAT, BT848_SATVMIN,
+ BT848_SATVMAX },
+{ 0, 0, 0, 0, 0, 0, 0}
+};
+
+struct chansets {
+ int value;
+ char *name;
+} chansets[] = {
+{ CHNLSET_NABCST, "nabcst", },
+{ CHNLSET_CABLEIRC, "cableirc", },
+{ CHNLSET_CABLEHRC, "cablehrc", },
+{ CHNLSET_WEUROPE, "weurope", },
+{ CHNLSET_JPNBCST, "jpnbcst", },
+{ CHNLSET_JPNCABLE, "jpncable", },
+{ CHNLSET_XUSSR, "xussr", },
+{ CHNLSET_AUSTRALIA, "australia", },
+{ CHNLSET_FRANCE, "france", },
+{ 0, 0 }
+};
+
+struct audiosources {
+ int value;
+ char *name;
+} audiosources[] = {
+{ AUDIO_TUNER, "tuner", },
+{ AUDIO_EXTERN, "extern", },
+{ AUDIO_INTERN, "intern", },
+{ 0, 0 }
+};
+
+int tuner_fd;
+int print_choices;
+int print_name;
+int print_value;
+
+__dead void usage(void);
+int run(int, char *);
+int findfield(char *);
+int prfield(int);
+int do_ioctls(int, char *);
+#define OFF 0
+#define ON 1
+int isoffon(const char *);
+
+
+/* getopt externs */
+extern char *optarg;
+extern int opterr;
+extern int optind;
+extern int optopt;
+extern int optreset;
+
+
+__dead void
+usage(void)
+{
+ extern char *__progname;
+
+ fprintf(stderr,
+ "usage: %s [-nv] [-f file] -a\n"
+ " %s [-nv] [-f file] name [...]\n"
+ " %s [-q] [-f file] name=value [...]\n",
+ __progname, __progname, __progname);
+
+ exit (1);
+}
+
+int
+isoffon(const char *offon)
+{
+ if (strncmp(offon, "off", 3) == 0)
+ return (OFF);
+ else if (strncmp(offon, "on", 2) == 0)
+ return (ON);
+
+ return (-1);
+}
+
+int
+findfield(char *name)
+{
+ int i, found = 0;
+
+ for (i = 0; fields[i].name; i++) {
+ if (strncmp(fields[i].name, name, strlen(fields[i].name)) ==0) {
+ found = 1;
+ break;
+ }
+ }
+ if (found == 1)
+ return (i);
+ else
+ return (-1);
+}
+
+int
+prfield(int index)
+{
+ int switchval;
+ int i;
+
+ if (print_name == 1)
+ printf("%s=", fields[index].name);
+
+ if (ioctl(tuner_fd, fields[index].io_get, &fields[index].val) < 0) {
+ warn("%s", fields[index].name);
+ return (1);
+ }
+
+ switchval = fields[index].type;
+ switch (switchval) {
+ case ASRC:
+ for (i = 0; audiosources[i].name; i++)
+ if (audiosources[i].value ==
+ (fields[index].val & ~AUDIO_MUTE))
+ break;
+ printf("%s", audiosources[i].name);
+ if (print_choices == 1) {
+ printf(" [ ");
+ for (i = 0; audiosources[i].name; i++)
+ printf("%s ", audiosources[i].name);
+ printf("]");
+ }
+ break;
+ case CSET:
+ for (i = 0; chansets[i].name; i++)
+ if (chansets[i].value == fields[index].val)
+ break;
+ printf("%s", chansets[i].name);
+ if (print_choices == 1) {
+ printf(" [ ");
+ for (i = 0; chansets[i].name; i++)
+ printf("%s ", chansets[i].name);
+ printf("]");
+ }
+ break;
+ case FREQ:
+ printf("%0.2f", (double)fields[index].val / 16);
+ if (print_choices == 1)
+ printf(" ( %0.2f - %0.2f )",
+ (double)fields[index].valmin / 16,
+ (double)fields[index].valmax / 16);
+ break;
+ case INT:
+ case BRIGHT:
+ case CONTR:
+ case HUE:
+ case VSAT:
+ case USAT:
+ i = fields[index].val;
+ if (switchval == BRIGHT) {
+ i = (i - BT848_BRIGHTREGMIN) *
+ BT848_BRIGHTRANGE / BT848_BRIGHTSTEPS +
+ BT848_BRIGHTMIN + (i < 0 ? -0.5 : 0.5);
+ } else if (switchval == CONTR) {
+ i = (i - BT848_CONTRASTREGMIN) *
+ BT848_CONTRASTRANGE / BT848_CONTRASTSTEPS +
+ BT848_CONTRASTMIN + (i < 0 ? -0.5 : 0.5);
+ } else if (switchval == HUE) {
+ i = (i - BT848_HUEREGMIN) *
+ BT848_HUERANGE / BT848_HUESTEPS +
+ BT848_HUEMIN + (i < 0 ? -0.5 : 0.5);
+ } else if (switchval == USAT) {
+ i = (i - BT848_SATUREGMIN) *
+ BT848_SATURANGE / BT848_SATUSTEPS +
+ BT848_SATUMIN + (i < 0 ? -0.5 : 0.5);
+ } else if (switchval == VSAT) {
+ i = (i - BT848_SATVREGMIN) *
+ BT848_SATVRANGE / BT848_SATVSTEPS +
+ BT848_SATVMIN + (i < 0 ? -0.5 : 0.5);
+ }
+ printf("%d", i);
+ if (print_choices == 1)
+ printf(" ( %d - %d )", fields[index].valmin,
+ fields[index].valmax);
+ break;
+ case MUTE:
+ case OFFON:
+ if (((switchval == MUTE) && (fields[index].val & AUDIO_MUTE)) ||
+ ((switchval != MUTE) && (fields[index].val == 1)))
+ printf("on");
+ else
+ printf("off");
+ if (print_choices == 1)
+ printf(" [ off on ]");
+ break;
+ default:
+ warnx("internal error: prfield");
+ break;
+ }
+ printf("\n");
+
+ return (0);
+}
+
+int
+do_ioctls(int index, char *arg)
+{
+ const char *errstr;
+ int i;
+ int switchval;
+
+ switchval = fields[index].type;
+
+ if (arg != NULL) {
+ switch(switchval) {
+ case ASRC:
+ for (i = 0; audiosources[i].name; i++)
+ if (strncmp(audiosources[i].name, arg,
+ strlen(audiosources[i].name)) == 0)
+ break;
+ if (audiosources[i].name[0] != '\0')
+ fields[index].val = audiosources[i].value;
+ else {
+ warnx("%s is invalid: %s", fields[index].name,
+ arg);
+ return (1);
+ }
+ break;
+ case CSET:
+ for (i = 0; chansets[i].name; i++)
+ if (strncmp(chansets[i].name, arg,
+ strlen(chansets[i].name)) == 0)
+ break;
+ if (chansets[i].name[0] != '\0')
+ fields[index].val = chansets[i].value;
+ else {
+ warnx("%s is invalid: %s", fields[index].name,
+ arg);
+ return (1);
+ }
+ break;
+ case FREQ:
+ fields[index].val = strtod(arg, (char **)NULL) * 16;
+ if ((fields[index].val < fields[index].valmin) ||
+ (fields[index].val > fields[index].valmax)) {
+ warnx("%s is invalid: %s", fields[index].name,
+ arg);
+ return (1);
+ }
+ break;
+ case INT:
+ case BRIGHT:
+ case CONTR:
+ case HUE:
+ case USAT:
+ case VSAT:
+ i = strtonum(arg, fields[index].valmin,
+ fields[index].valmax, &errstr);
+ if (errstr != NULL) {
+ warnx("%s is %s: %s", fields[index].name,
+ errstr, arg);
+ return (1);
+ }
+ if (switchval == BRIGHT) {
+ i = (i - BT848_BRIGHTMIN) *
+ BT848_BRIGHTSTEPS / BT848_BRIGHTRANGE +
+ BT848_BRIGHTREGMIN + (i < 0 ? -0.5 : 0.5);
+ if (i > BT848_BRIGHTREGMAX)
+ i = BT848_BRIGHTREGMAX;
+ } else if (switchval == CONTR) {
+ i = (i - BT848_CONTRASTMIN) *
+ BT848_CONTRASTSTEPS / BT848_CONTRASTRANGE +
+ BT848_CONTRASTREGMIN + (i < 0 ? -0.5 : 0.5);
+ if (i > BT848_CONTRASTREGMAX)
+ i = BT848_CONTRASTREGMAX;
+ } else if (switchval == HUE) {
+ i = (i - BT848_HUEMIN) *
+ BT848_HUESTEPS / BT848_HUERANGE +
+ BT848_HUEREGMIN + (i < 0 ? -0.5 : 0.5);
+ if (i > BT848_HUEREGMAX)
+ i = BT848_HUEREGMAX;
+ } else if (switchval == USAT) {
+ i = (i - BT848_SATUMIN) *
+ BT848_SATUSTEPS / BT848_SATURANGE +
+ BT848_SATUREGMIN + (i < 0 ? -0.5 : 0.5);
+ if (i > BT848_SATUREGMAX)
+ i = BT848_SATUREGMAX;
+ } else if (switchval == VSAT) {
+ i = (i - BT848_SATVMIN) *
+ BT848_SATVSTEPS / BT848_SATVRANGE +
+ BT848_SATVREGMIN + (i < 0 ? -0.5 : 0.5);
+ if (i > BT848_SATVREGMAX)
+ i = BT848_SATVREGMAX;
+ }
+ fields[index].val = i;
+ break;
+ case MUTE:
+ case OFFON:
+ fields[index].val = isoffon(arg);
+ if (fields[index].val < 0) {
+ warnx("%s is invalid: %s", fields[index].name,
+ optarg);
+ return (1);
+ }
+ if (switchval == MUTE) {
+ if (fields[index].val == 1)
+ fields[index].val = AUDIO_MUTE;
+ else
+ fields[index].val = AUDIO_UNMUTE;
+ }
+ break;
+ default:
+ warnx("internal error: do_ioctls: set");
+ break;
+ }
+ if (ioctl(tuner_fd, fields[index].io_set,&fields[index].val)<0){
+ warn("%s", fields[index].name);
+ return (1);
+ }
+ } else {
+ /* nothing is being set, so the -q option is meaningless */
+ print_value = 1;
+ }
+
+ if (print_value == 1)
+ if (prfield(index) > 0)
+ return (1);
+
+ return (0);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ char *device = DEFAULT_TUNER_DEVICE;
+ int aflag = 0;
+ int err = 0;
+ int ch, i;
+
+ print_choices = 0;
+ print_name = 1;
+ print_value = 1;
+
+ while ((ch = getopt(argc, argv, "af:nqv")) != -1) {
+ switch (ch) {
+ case 'a':
+ aflag++;
+ break;
+ case 'f':
+ device = optarg;
+ break;
+ case 'n':
+ print_name = 0;
+ break;
+ case 'q':
+ print_value = 0;
+ break;
+ case 'v':
+ print_choices = 1;
+ break;
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if ((argc == 0) && (aflag == 0))
+ usage();
+
+ if ((tuner_fd = open(device, O_RDONLY)) < 0) {
+ warn("%s", device);
+ close(tuner_fd);
+ exit (1);
+ }
+
+ if (aflag > 0) {
+ for (i = 0; fields[i].name; i++) {
+ if (do_ioctls(i, NULL) > 0) {
+ err++;
+ break;
+ }
+ }
+ } else {
+ for (; argc--; argv++) {
+ char *q;
+
+ q = strchr(*argv, '=');
+ i = findfield(*argv);
+ if (i < 0) {
+ warnx("field '%s' does not exist", *argv);
+ err++;
+ break;
+ } else {
+ if (q != NULL)
+ *q++ = 0;
+ if (do_ioctls(i, q) > 0) {
+ err++;
+ break;
+ }
+ }
+ }
+ }
+ close(tuner_fd);
+ exit (err);
+}

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 08:56 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com