aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2010-04-01 11:24:38 +0200
committerGerd Hoffmann <kraxel@redhat.com>2010-04-01 11:24:38 +0200
commit4e106fb2760a11001f50ca5773b51ebc1a39ec23 (patch)
treec5ce810a35be78c97073d89042776e569db3f614
parent6fdf6d3b6364f8e2da4e2db6468153c426a59533 (diff)
v3.70
-rw-r--r--Changes21
-rw-r--r--README.lirc22
-rw-r--r--debian/changelog6
-rw-r--r--debian/control2
-rw-r--r--libng/plugins/drv0-bsd.c14
-rw-r--r--man/xawtvrc.554
-rw-r--r--src/Makefile.in2
-rw-r--r--src/MoTV-de8
-rw-r--r--src/MoTV-default8
-rw-r--r--src/MoTV-fixed7
-rw-r--r--src/MoTV-it8
-rw-r--r--src/MoTV.de.ad15
-rw-r--r--src/MoTV.it.ad15
-rw-r--r--src/aa.c2
-rw-r--r--src/channel.c49
-rw-r--r--src/channel.h4
-rw-r--r--src/commands.c17
-rw-r--r--src/event.c157
-rw-r--r--src/event.h23
-rw-r--r--src/fbtv.c209
-rw-r--r--src/joystick.c51
-rw-r--r--src/lirc.c87
-rw-r--r--src/main.c30
-rw-r--r--src/midictrl.c30
-rw-r--r--src/motif.c6
-rw-r--r--src/scantv.c128
-rw-r--r--src/v4lctl.c2
-rw-r--r--src/xt.c76
-rw-r--r--src/xt.h2
-rw-r--r--tools/record.c6
-rw-r--r--tools/record.man4
-rw-r--r--xawtv.spec2
32 files changed, 822 insertions, 245 deletions
diff --git a/Changes b/Changes
index c7c8c16..983781f 100644
--- a/Changes
+++ b/Changes
@@ -1,4 +1,25 @@
+3.69 => 3.70
+============
+
+ * Hacked up configureable input event mapping infrastructure. There
+ is a new [eventmap] section in the config file. Check the xawtvrc
+ man page for details.
+ * Made lirc code use the event mapping. xawtv does not use the
+ ~/.lircrc file config any more, but is configured using the
+ [eventmap] mentioned above. xawtv also has a reasonable default
+ configuration now, so lirc works out-of-the-box.
+ * Made midi input configurable via event mapping.
+ * Made joystick input configurable via event mapping.
+ * Made fbtv's ncurses kbd keys go through event mapping.
+ * added -a switch to scantv.
+ * fixed some bugs in handling TV stations which are specified by
+ frequency instead of channel name.
+ * fixed volume control segfault.
+ * added tooltips for motv (needs OpenMotif 2.2).
+ * color support for bktr driver (Rolandas Naujikas <rolnauj@delfi.lt>).
+
+
3.68 => 3.69
============
diff --git a/README.lirc b/README.lirc
index d7826d6..5970492 100644
--- a/README.lirc
+++ b/README.lirc
@@ -1,21 +1,13 @@
-For lirc support you have to install lirc-0.6.0pre1 or newer. There
-is a library with the lirc client code now. You can get it from the
-lirc snapshot directory:
- http://fsinfo.cs.uni-sb.de/~columbus/lirc/software/snapshots/
+Starting with version 3.70 xawtv + friends do _not_ read $HOME/.lircrc
+any more.
-xawtv and fbtv accept the same commands via lirc as with xawtv-remote,
-i.e. if you stick the following lines into your .lircrc ...
+Check the xawtvrc manpage ([eventmap] section) for hints on
+configuring lirc support. There is a default configuration througth,
+so lirc should work out-of-the-box. You have to touch the
+$HOME/.xawtv config file only if you don't like my defaults.
- begin
- prog = xawtv
- button = MUTE
- config = volume mute
- end
-
-... this should have the same effect like "xawtv-remote volume mute".
-Check the xawtv-remote manpage for a more complete list. A sample
-config file is in the contrib directory.
+Have fun,
Gerd
diff --git a/debian/changelog b/debian/changelog
index 80460aa..14d5811 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+xawtv (3.70) unstable; urgency=low
+
+ * new release.
+
+ -- Gerd Knorr <kraxel@debian.org> Tue, 5 Feb 2002 11:03:48 +0100
+
xawtv (3.69) unstable; urgency=low
* new release (closes: #112892)
diff --git a/debian/control b/debian/control
index 4b3df95..e3101e7 100644
--- a/debian/control
+++ b/debian/control
@@ -1,7 +1,7 @@
Source: xawtv
Section: graphics
Priority: extra
-Build-Depends: libjpeg-dev, libncurses5-dev, xlibs-dev (>= 4.0.1), xaw3dg-dev, liblircclient-dev, debhelper, xutils, libquicktime4linux-dev, xbase-clients, aalib1-dev, libasound1-dev
+Build-Depends: libjpeg-dev, libncurses5-dev, xlibs-dev (>= 4.0.1), xaw3dg-dev, liblircclient-dev, debhelper, xutils, libquicktime4linux-dev, xbase-clients, aalib1-dev, libasound2-dev
Maintainer: Gerd Knorr <kraxel@debian.org>
Standards-Version: 3.5.2
diff --git a/libng/plugins/drv0-bsd.c b/libng/plugins/drv0-bsd.c
index da76cd5..fa24abf 100644
--- a/libng/plugins/drv0-bsd.c
+++ b/libng/plugins/drv0-bsd.c
@@ -203,6 +203,14 @@ static struct ng_attribute bsd_attr[] = {
read: bsd_read_attr,
write: bsd_write_attr,
},{
+ id: ATTR_ID_COLOR,
+ name: "color",
+ type: ATTR_TYPE_INTEGER,
+ min: BT848_CHROMAREGMIN,
+ max: BT848_CHROMAREGMAX,
+ read: bsd_read_attr,
+ write: bsd_write_attr,
+ },{
/* end of list */
}
};
@@ -465,6 +473,10 @@ bsd_get_range(int id, int *get, int *set)
*get = BT848_GCONT;
*set = BT848_SCONT;
break;
+ case ATTR_ID_COLOR:
+ *get = BT848_GCSAT;
+ *set = BT848_SCSAT;
+ break;
default:
return -1;
}
@@ -497,6 +509,7 @@ static int bsd_read_attr(struct ng_attribute *attr)
case ATTR_ID_HUE:
case ATTR_ID_BRIGHT:
case ATTR_ID_CONTRAST:
+ case ATTR_ID_COLOR:
bsd_get_range(attr->id,&get,&set);
if (-1 != xioctl(h->tfd,get,&arg))
value = arg;
@@ -527,6 +540,7 @@ static void bsd_write_attr(struct ng_attribute *attr, int value)
case ATTR_ID_HUE:
case ATTR_ID_BRIGHT:
case ATTR_ID_CONTRAST:
+ case ATTR_ID_COLOR:
bsd_get_range(attr->id,&get,&set);
arg = value;
xioctl(h->tfd,set,&arg);
diff --git a/man/xawtvrc.5 b/man/xawtvrc.5
index 9c0bf1f..feb4fdf 100644
--- a/man/xawtvrc.5
+++ b/man/xawtvrc.5
@@ -52,8 +52,8 @@ file.
uses the same syntax like smb.conf: sections starting with [name],
followed by lines with option = value pairs.
.P
-There are three special sections: [global], [launch] and [default].
-All other sections describe a TV station each.
+There are four special sections: [global], [launch], [eventmap] and
+[default]. All other sections describe a TV station each.
.SS TV station options.
The following options are allowed for TV stations and the [default]
section. The options from the [default] sections are used -- as the
@@ -91,7 +91,8 @@ by the hardware, whatever) the applications will automatically fallback to
.TP
.B input = Television | Composite1 | Composite2 | SVHS
input source. The valid choices depend on the hardware driver, the
-values above are just examples.
+values above are just examples. You can use "v4lctl list" to get a
+list of valid choices.
.TP
.B color = n
.TP
@@ -189,9 +190,10 @@ valid choices. "streamer -h" will print a nice list.
.TP
.B midi = port
You can specify a ALSA port where xawtv should receive midi events
-from. If configured this way, you can program your midi keyboard
-keys as station hotkeys and control the volume via midi.
-.P
+from. If configured this way, you can program your midi keyboard keys
+as station hotkeys and use midi controller events to control settings
+like volume, bright etc. Check the [eventmap] description below for
+details.
.SS The [launch] section
You can start other programs from within xawtv. This is configured
with entries in the "[launch]" section:
@@ -201,6 +203,39 @@ The specified hotkey will run the configured program. Calling the
Action "Launch(label)" works too. If you want to play with the Xt
translation tables, feel free to do so. But don't complain if you
broke something while doing so...
+.SS The [eventmap] section
+The eventmap simply has a number of "event = action" lines. "action"
+can be any command which xawtv understands (check the xawtv-remote man
+page for a list). "event" is some event generated by any input device
+xawtv listens to. An event might have some argument, the midi-ctrl
+events for example have one. If present the argument is appended to
+the action.
+.P
+There are default mappings for lirc and joystick input events, so you
+don't have to create a eventmap to use them. But if you don't like
+the defaults you can change them easily.
+.P
+Here is a list of valid events:
+.TP
+.B lirc-key-<name>
+The key <name> was pressed on the IR remote control.
+.TP
+.B joy-button-<n>
+Joystick button <n> was pressed.
+.TP
+.B joy-axis-<left|right|up|down>
+Joystick was moved into the given direction.
+.TP
+.B midi-note-<n>
+noteon event for note <n> was received (i.e. you probably pressed some
+key on the midi keyboard).
+.TP
+.B midi-ctrl-<n>
+midi controller message for control <n> was received. This event has
+an argument (the current value of the control).
+.TP
+.B kbd-key-<name>
+Key <name> was pressed on the keyboard. Only fbtv supports this one.
.SS sample config file
.nf
# this is a comment
@@ -209,6 +244,8 @@ broke something while doing so...
[global]
freqtab = europe-west
#mixer = line
+jpeg-quality = 75
+midi = 64:0
fullscreen = 768x576
# for /etc/XF86Config
@@ -218,6 +255,9 @@ fullscreen = 768x576
mixer = M, gtkaumix
AleVT = Ctrl+A, alevt
+[eventmap]
+midi-ctrl-7 = volume
+
[defaults]
input = television
norm = pal
@@ -238,4 +278,4 @@ key = K
.fi
.SH SEE ALSO
-scantv(1), xawtv(1), motv(1), fbtv(1), ttv(1)
+scantv(1), xawtv(1), motv(1), fbtv(1), ttv(1), v4lctl(1)
diff --git a/src/Makefile.in b/src/Makefile.in
index 4483a4d..d0bfff1 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -9,7 +9,7 @@ CFLAGS=-g @CFLAGS@ $(WARN_FLAGS) $(LFS_FLAGS) $(X11_FLAGS) $(LIB_FLAGS) \
# object files /libraries
COMMON_OBJS = sound.o webcam.o frequencies.o commands.o parseconfig.o \
- capture.o ../libng/libng.a
+ capture.o event.o ../libng/libng.a
XAWTV_OBJS = main.o xt.o toolbox.o conf.o x11.o xv.o complete-xaw.o \
wmhooks.o channel.o lirc.o midictrl.o joystick.o \
diff --git a/src/MoTV-de b/src/MoTV-de
index 1d973d7..90a6628 100644
--- a/src/MoTV-de
+++ b/src/MoTV-de
@@ -180,6 +180,14 @@ control*menubar*man.mnemonic: M
control*menubar*about.labelString: Über ...
control*menubar*about.mnemonic: b
+! tooltips (needs openmotif 2.2)
+control*tool.prev.toolTipString: nächster Sender
+control*tool.next.toolTipString: vorheriger Sender
+control*tool.snap.toolTipString: Bild speichern
+control*tool.movie.toolTipString: Film aufnehmen
+control*tool.mute.toolTipString: Ton aus
+control*tool.exit.toolTipString: Beenden
+
control*box.XmPushButton*menu.del.labelString: Löschen
control*box.XmPushButton*menu.edit.labelString: Ändern ...
diff --git a/src/MoTV-default b/src/MoTV-default
index 526adc1..4a618b4 100644
--- a/src/MoTV-default
+++ b/src/MoTV-default
@@ -184,6 +184,14 @@ control*menubar*man.mnemonic: m
control*menubar*about.labelString: About ...
control*menubar*about.mnemonic: A
+! tooltips (needs openmotif 2.2)
+control*tool.prev.toolTipString: previous station
+control*tool.next.toolTipString: next station
+control*tool.snap.toolTipString: grab image
+control*tool.movie.toolTipString: record movie
+control*tool.mute.toolTipString: mute audio
+control*tool.exit.toolTipString: quit
+
control*box.XmPushButton*menu.del.labelString: Delete
control*box.XmPushButton*menu.edit.labelString: Edit ...
diff --git a/src/MoTV-fixed b/src/MoTV-fixed
index 6a7c422..e310dbe 100644
--- a/src/MoTV-fixed
+++ b/src/MoTV-fixed
@@ -89,6 +89,13 @@ control*highlightThickness: 0
control*XmPushButton.highlightThickness: 1
control.XmDialogShell*highlightThickness: 1
+control.toolTipEnable: 1
+control.toolTipPostDelay: 3000
+control.toolTipPostDuration: 8000
+control*TipLabel.foreground: black
+control*TipLabel.background: lightyellow
+control*TipShell.borderWidth: 1
+control*TipShell.borderColor: black
control*tool.orientation: HORIZONTAL
control*tool.?.shadowThickness: 1
control*tool.?.labelType: PIXMAP
diff --git a/src/MoTV-it b/src/MoTV-it
index 41b81fd..0b67b9e 100644
--- a/src/MoTV-it
+++ b/src/MoTV-it
@@ -185,6 +185,14 @@ control*menubar*man.mnemonic: m
control*menubar*about.labelString: Informazioni ...
control*menubar*about.mnemonic: A
+! tooltips (needs openmotif 2.2)
+control*tool.prev.toolTipString: Stazione precedente
+control*tool.next.toolTipString: Stazione successiva
+control*tool.snap.toolTipString: Cattura immagine
+control*tool.movie.toolTipString: Registra filmato
+control*tool.mute.toolTipString: Muto
+control*tool.exit.toolTipString: Esci
+
control*box.XmPushButton*menu.del.labelString: Cancella
control*box.XmPushButton*menu.edit.labelString: Modifica ...
diff --git a/src/MoTV.de.ad b/src/MoTV.de.ad
index 6aa818a..e7831d7 100644
--- a/src/MoTV.de.ad
+++ b/src/MoTV.de.ad
@@ -180,6 +180,14 @@ control*menubar*man.mnemonic: M
control*menubar*about.labelString: Über ...
control*menubar*about.mnemonic: b
+! tooltips (needs openmotif 2.2)
+control*tool.prev.toolTipString: nächster Sender
+control*tool.next.toolTipString: vorheriger Sender
+control*tool.snap.toolTipString: Bild speichern
+control*tool.movie.toolTipString: Film aufnehmen
+control*tool.mute.toolTipString: Ton aus
+control*tool.exit.toolTipString: Beenden
+
control*box.XmPushButton*menu.del.labelString: Löschen
control*box.XmPushButton*menu.edit.labelString: Ändern ...
@@ -350,6 +358,13 @@ control*highlightThickness: 0
control*XmPushButton.highlightThickness: 1
control.XmDialogShell*highlightThickness: 1
+control.toolTipEnable: 1
+control.toolTipPostDelay: 3000
+control.toolTipPostDuration: 8000
+control*TipLabel.foreground: black
+control*TipLabel.background: lightyellow
+control*TipShell.borderWidth: 1
+control*TipShell.borderColor: black
control*tool.orientation: HORIZONTAL
control*tool.?.shadowThickness: 1
control*tool.?.labelType: PIXMAP
diff --git a/src/MoTV.it.ad b/src/MoTV.it.ad
index fd60263..2eb4527 100644
--- a/src/MoTV.it.ad
+++ b/src/MoTV.it.ad
@@ -185,6 +185,14 @@ control*menubar*man.mnemonic: m
control*menubar*about.labelString: Informazioni ...
control*menubar*about.mnemonic: A
+! tooltips (needs openmotif 2.2)
+control*tool.prev.toolTipString: Stazione precedente
+control*tool.next.toolTipString: Stazione successiva
+control*tool.snap.toolTipString: Cattura immagine
+control*tool.movie.toolTipString: Registra filmato
+control*tool.mute.toolTipString: Muto
+control*tool.exit.toolTipString: Esci
+
control*box.XmPushButton*menu.del.labelString: Cancella
control*box.XmPushButton*menu.edit.labelString: Modifica ...
@@ -356,6 +364,13 @@ control*highlightThickness: 0
control*XmPushButton.highlightThickness: 1
control.XmDialogShell*highlightThickness: 1
+control.toolTipEnable: 1
+control.toolTipPostDelay: 3000
+control.toolTipPostDuration: 8000
+control*TipLabel.foreground: black
+control*TipLabel.background: lightyellow
+control*TipShell.borderWidth: 1
+control*TipShell.borderColor: black
control*tool.orientation: HORIZONTAL
control*tool.?.shadowThickness: 1
control*tool.?.labelType: PIXMAP
diff --git a/src/aa.c b/src/aa.c
index d956e7e..4c1e86f 100644
--- a/src/aa.c
+++ b/src/aa.c
@@ -208,7 +208,7 @@ main(int argc, char **argv)
/* init v4l */
grabber_init();
- read_config();
+ read_config(NULL);
ng_ratio_x = 0;
ng_ratio_y = 0;
diff --git a/src/channel.c b/src/channel.c
index 221a62a..57c3750 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -46,14 +46,15 @@
#include "frequencies.h"
#include "sound.h"
#include "parseconfig.h"
+#include "event.h"
/* ----------------------------------------------------------------------- */
/* misc common stuff, not only channel related */
struct CHANNEL defaults = {
name: "defaults",
- cname: "none",
capture: CAPTURE_ON,
+ channel: -1,
audio: -1,
color: -1,
bright: -1,
@@ -101,6 +102,9 @@ int lookup_channel(char *channel)
int i,nr1,nr2;
char tag1[5],tag2[5];
+ if (NULL == channel)
+ return -1;
+
if (isdigit(channel[0])) {
tag1[0] = 0;
nr1 = atoi(channel);
@@ -280,14 +284,14 @@ calc_frequencies()
int i;
for (i = 0; i < count; i++) {
- if (0 != strcmp(channels[i]->cname,"none")) {
- channels[i]->channel = lookup_channel(channels[i]->cname);
- if (-1 == channels[i]->channel)
- channels[i]->freq = -1;
- else
- channels[i]->freq = get_freq(channels[i]->channel)
- + channels[i]->fine;
- }
+ if (NULL == channels[i]->cname)
+ continue;
+ channels[i]->channel = lookup_channel(channels[i]->cname);
+ if (-1 == channels[i]->channel)
+ channels[i]->freq = -1;
+ else
+ channels[i]->freq = get_freq(channels[i]->channel)
+ + channels[i]->fine;
}
}
@@ -361,17 +365,22 @@ init_channel(char *name, struct CHANNEL *c)
}
void
-read_config(void)
+read_config(char *conffile)
{
char filename[100];
char *val;
int i;
- sprintf(filename,"%s/%s",getenv("HOME"),".xawtv");
- if (0 == cfg_parse_file(CONFIGFILE))
- have_config = 1;
- if (0 == cfg_parse_file(filename))
- have_config = 1;
+ if (conffile) {
+ if (0 == cfg_parse_file(conffile))
+ have_config = 1;
+ } else {
+ sprintf(filename,"%s/%s",getenv("HOME"),".xawtv");
+ if (0 == cfg_parse_file(CONFIGFILE))
+ have_config = 1;
+ if (0 == cfg_parse_file(filename))
+ have_config = 1;
+ }
/* misc global settings */
if (NULL != (val = cfg_get_str("global","mixer"))) {
@@ -463,7 +472,7 @@ parse_config(void)
#endif
/* launch */
- list = list = cfg_list_entries("launch");
+ list = cfg_list_entries("launch");
if (NULL != list) {
for (; *list != NULL; list++) {
if (NULL != (val = cfg_get_str("launch",*list)) &&
@@ -483,12 +492,16 @@ parse_config(void)
}
}
+ /* events */
+ event_readconfig();
+
/* channels */
init_channel("defaults",&defaults);
for (list = cfg_list_sections(); *list != NULL; list++) {
if (0 == strcmp(*list,"defaults")) continue;
if (0 == strcmp(*list,"global")) continue;
if (0 == strcmp(*list,"launch")) continue;
+ if (0 == strcmp(*list,"eventmap")) continue;
init_channel(*list,add_channel(*list));
}
@@ -570,8 +583,10 @@ save_config()
fprintf(fp,"\n");
}
- /* write help */
+ /* events */
+ event_writeconfig(fp);
+ /* write help */
fprintf(fp,"# [Station name]\n");
fprintf(fp,"# capture = overlay | grabdisplay | on | off\n");
fprintf(fp,"# input = Television | Composite1 | S-Video | ...\n");
diff --git a/src/channel.h b/src/channel.h
index 562d53c..b5b04f1 100644
--- a/src/channel.h
+++ b/src/channel.h
@@ -33,8 +33,6 @@ struct CHANNEL {
Pixmap pixmap;
Widget button;
#endif
-
- int ckey;
};
extern struct CHANNEL defaults;
@@ -72,7 +70,7 @@ void configure_channel(struct CHANNEL *channel);
void del_channel(int nr);
void calc_frequencies(void);
-void read_config(void);
+void read_config(char *conffile);
void parse_config(void);
void save_config(void);
diff --git a/src/commands.c b/src/commands.c
index f4040b8..64fe9dc 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -350,7 +350,7 @@ set_title(void)
sprintf(title+strlen(title)," (%s/%s)",
norm ? norm : "???", chanlists[chantab].name);
} else {
- sprintf(title,"???");
+ sprintf(title,"%.3f MHz",cur_freq/16.0);
}
update_title(title);
}
@@ -678,7 +678,12 @@ static int setchannel_handler(char *name, int argc, char **argv)
set_capture(CAPTURE_OFF,1);
cur_sender = -1;
- cur_freq = get_freq(cur_channel)+cur_fine;
+ if (-1 != cur_channel)
+ cur_freq = get_freq(cur_channel)+cur_fine;
+ else {
+ cur_freq += cur_fine;
+ cur_fine = 0;
+ }
mute = ng_attr_byid(attrs,ATTR_ID_MUTE);
if (mute && !cur_attrs[ATTR_ID_MUTE])
@@ -760,8 +765,11 @@ static int volume_handler(char *name, int argc, char **argv)
}
} else {
/* volume */
- cur_attrs[ATTR_ID_VOLUME] =
- update_int(vol,cur_attrs[ATTR_ID_VOLUME],argv[0]);
+ if (NULL != vol) {
+ cur_attrs[ATTR_ID_VOLUME] = vol->read(vol);
+ cur_attrs[ATTR_ID_VOLUME] =
+ update_int(vol,cur_attrs[ATTR_ID_VOLUME],argv[0]);
+ }
}
set_volume();
@@ -829,6 +837,7 @@ static int attr_handler(char *name, int argc, char **argv)
break;
case ATTR_TYPE_INTEGER:
if (argc > arg) {
+ cur_attrs[attr->id] = attr->read(attr);
val = update_int(attr,cur_attrs[attr->id],argv[arg]);
set_attr(attr,val);
}
diff --git a/src/event.c b/src/event.c
new file mode 100644
index 0000000..36bfed6
--- /dev/null
+++ b/src/event.c
@@ -0,0 +1,157 @@
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+
+#include "grab-ng.h"
+#include "commands.h"
+#include "event.h"
+#include "parseconfig.h"
+
+/* ----------------------------------------------------------------------- */
+
+static struct event_entry *event_conf_list;
+static struct event_entry *event_builtin_list;
+
+/* ----------------------------------------------------------------------- */
+
+static void parse_action(struct event_entry *entry)
+{
+ char *token,*h;
+
+ strcpy(entry->argbuf,entry->action);
+ h = entry->argbuf;
+ for (;;) {
+ while (' ' == *h || '\t' == *h)
+ h++;
+ if ('\0' == *h)
+ break;
+ if ('"' == *h) {
+ /* quoted string */
+ h++;
+ token = h;
+ while ('\0' != *h && '"' != *h)
+ h++;
+ } else {
+ /* normal string */
+ token = h;
+ while ('\0' != *h && ' ' != *h && '\t' != *h)
+ h++;
+ }
+ if ('\0' != *h) {
+ *h = 0;
+ h++;
+ }
+ entry->argv[entry->argc++] = token;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+int event_register(char *event, char *action)
+{
+ struct event_entry *entry;
+
+ entry = malloc(sizeof(*entry));
+ memset(entry,0,sizeof(*entry));
+ strncpy(entry->event,event,127);
+ strncpy(entry->action,action,127);
+ entry->next = event_conf_list;
+ event_conf_list = entry;
+ parse_action(entry);
+ if (debug)
+ fprintf(stderr,"ev: reg conf \"%s\" => \"%s\"\n",
+ entry->event,entry->action);
+ return 0;
+}
+
+int event_register_list(struct event_entry *entry)
+{
+ for (; NULL != entry && 0 != entry->event[0]; entry++) {
+ entry->next = event_builtin_list;
+ event_builtin_list = entry;
+ parse_action(entry);
+ if (debug)
+ fprintf(stderr,"ev: reg built-in \"%s\" => \"%s\"\n",
+ entry->event,entry->action);
+ }
+ return 0;
+}
+
+void event_readconfig(void)
+{
+ char **list,*val;
+
+ list = cfg_list_entries("eventmap");
+ if (NULL == list)
+ return;
+
+ for (; *list != NULL; list++)
+ if (NULL != (val = cfg_get_str("eventmap",*list)))
+ event_register(*list,val);
+}
+
+void event_writeconfig(FILE *fp)
+{
+ struct event_entry *entry;
+
+ if (NULL == event_conf_list)
+ return;
+
+ fprintf(fp,"[eventmap]\n");
+ for (entry = event_conf_list; NULL != entry; entry = entry->next)
+ fprintf(stderr,"%s = %s\n",entry->event,entry->action);
+ fprintf(fp,"\n");
+}
+
+/* ----------------------------------------------------------------------- */
+
+int event_dispatch(char *event)
+{
+ struct event_entry *entry = NULL;
+ char *name,*arg,*h,*argv[EVENT_ARGV_SIZE];
+ int argc;
+
+ /* parse */
+ if (NULL != (h = strchr(event,'('))) {
+ name = event;
+ arg = h+1;
+ *h = 0;
+ if (NULL != (h = strchr(arg,')')))
+ *h = 0;
+ if (debug)
+ fprintf(stderr,"ev: dispatch name=%s arg=%s\n",name,arg);
+ } else {
+ name = event;
+ arg = NULL;
+ if (debug)
+ fprintf(stderr,"ev: dispatch name=%s\n",name);
+ }
+
+ /* search lists */
+ if (NULL == entry)
+ for (entry = event_conf_list; NULL != entry; entry = entry->next)
+ if (0 == strcasecmp(name,entry->event))
+ break;
+ if (NULL == entry)
+ for (entry = event_builtin_list; NULL != entry; entry = entry->next)
+ if (0 == strcasecmp(name,entry->event))
+ break;
+ if (NULL == entry) {
+ if (debug)
+ fprintf(stderr,"ev: 404: %s\n",name);
+ return 0;
+ }
+
+ /* call action */
+ memcpy(argv,entry->argv,sizeof(argv));
+ argc = entry->argc;
+ if (arg)
+ argv[argc++] = arg;
+ do_command(argc,argv);
+
+ return 0;
+}
diff --git a/src/event.h b/src/event.h
new file mode 100644
index 0000000..8f14e57
--- /dev/null
+++ b/src/event.h
@@ -0,0 +1,23 @@
+#define EVENT_ARGV_SIZE 16
+
+struct event_entry {
+ /* the entry */
+ char event[128];
+ char action[128];
+
+ /* pre-parsed action for do_command */
+ char argbuf[128];
+ int argc;
+ char *argv[EVENT_ARGV_SIZE];
+
+ /* linked list */
+ struct event_entry *next;
+};
+
+int event_register(char *event, char *action);
+int event_register_list(struct event_entry *entry);
+
+void event_readconfig(void);
+void event_writeconfig(FILE *fp);
+
+int event_dispatch(char *event);
diff --git a/src/fbtv.c b/src/fbtv.c
index e51a3b6..b56b230 100644
--- a/src/fbtv.c
+++ b/src/fbtv.c
@@ -39,6 +39,7 @@
#include "lirc.h"
#include "joystick.h"
#include "midictrl.h"
+#include "event.h"
#include "fbtools.h"
#include "fs.h"
@@ -80,58 +81,109 @@ int x11_native_format,have_dga=1,debug;
/*--- channels ------------------------------------------------------------*/
+struct event_entry kbd_events[] = {
+ {
+ event: "kbd-key-+",
+ action: "volume inc",
+ },{
+ event: "kbd-key--",
+ action: "volume dec",
+ },{
+ event: "kbd-key-enter",
+ action: "volume mute",
+ },{
+ event: "kbd-key-space",
+ action: "setstation next",
+ },{
+ event: "kbd-key-backspace",
+ action: "setstation back",
+ },{
+ event: "kbd-key-pgup",
+ action: "setstation prev",
+ },{
+ event: "kbd-key-pgdown",
+ action: "setstation next",
+ },{
+ event: "kbd-key-right",
+ action: "setchannel fine_up",
+ },{
+ event: "kbd-key-left",
+ action: "setchannel fine_down",
+ },{
+ event: "kbd-key-up",
+ action: "setchannel next",
+ },{
+ event: "kbd-key-down",
+ action: "setchannel prev",
+ },{
+ event: "kbd-key-g",
+ action: "snap ppm",
+ },{
+ event: "kbd-key-j",
+ action: "snap jpeg",
+ },{
+ event: "kbd-key-v",
+ action: "capture toggle",
+ },{
+ event: "kbd-key-f",
+ action: "fullscreen toggle",
+ },{
+ event: "kbd-key-0",
+ action: "keypad 0",
+ },{
+ event: "kbd-key-1",
+ action: "keypad 1",
+ },{
+ event: "kbd-key-2",
+ action: "keypad 2",
+ },{
+ event: "kbd-key-3",
+ action: "keypad 3",
+ },{
+ event: "kbd-key-4",
+ action: "keypad 4",
+ },{
+ event: "kbd-key-5",
+ action: "keypad 5",
+ },{
+ event: "kbd-key-6",
+ action: "keypad 6",
+ },{
+ event: "kbd-key-7",
+ action: "keypad 7",
+ },{
+ event: "kbd-key-8",
+ action: "keypad 8",
+ },{
+ event: "kbd-key-9",
+ action: "keypad 9",
+ },{
+
+ /* end of list */
+ }
+};
struct KEYTAB {
int key;
- int argc;
- char *argv[8];
+ char *name;
};
static struct KEYTAB keytab[] = {
- { '+', 2, { "volume", "inc" }},
- { '-', 2, { "volume", "dec" }},
- { 10, 2, { "volume", "mute" }},
- { 13, 2, { "volume", "mute" }},
- { KEY_ENTER, 2, { "volume", "mute" }},
-
- { KEY_F(5), 2, { "bright", "dec" }},
- { KEY_F(6), 2, { "bright", "inc" }},
- { KEY_F(7), 2, { "hue", "dec" }},
- { KEY_F(8), 2, { "hue", "inc" }},
- { KEY_F(9), 2, { "contrast", "dec" }},
- { KEY_F(10), 2, { "contrast", "inc" }},
- { KEY_F(11), 2, { "color", "dec" }},
- { KEY_F(12), 2, { "color", "inc" }},
-
- { ' ', 2, { "setstation", "next" }},
- { KEY_BACKSPACE, 2, { "setstation", "back" }},
- { KEY_PPAGE, 2, { "setstation", "next" }},
- { KEY_NPAGE, 2, { "setstation", "prev" }},
- { KEY_RIGHT, 2, { "setchannel", "fine_up" }},
- { KEY_LEFT, 2, { "setchannel", "fine_down" }},
- { KEY_UP, 2, { "setchannel", "next" }},
- { KEY_DOWN, 2, { "setchannel", "prev" }},
-
- { 'G', 2, { "snap", "ppm" }},
- { 'g', 2, { "snap", "ppm" }},
- { 'J', 2, { "snap", "jpeg" }},
- { 'j', 2, { "snap", "jpeg" }},
-
- { 'V', 2, { "capture", "toggle" }},
- { 'v', 2, { "capture", "toggle" }},
-
- { 'F', 2, { "fullscreen", "toggle" }},
- { 'f', 2, { "fullscreen", "toggle" }},
-
- { '0', 2, { "keypad", "0" }},
- { '1', 2, { "keypad", "1" }},
- { '2', 2, { "keypad", "2" }},
- { '3', 2, { "keypad", "3" }},
- { '4', 2, { "keypad", "4" }},
- { '5', 2, { "keypad", "5" }},
- { '6', 2, { "keypad", "6" }},
- { '7', 2, { "keypad", "7" }},
- { '8', 2, { "keypad", "8" }},
- { '9', 2, { "keypad", "9" }},
+ { 9, "tab" },
+ { 10, "enter" },
+ { 13, "enter" },
+ { KEY_ENTER, "enter" },
+
+ { ' ', "space" },
+ { KEY_BACKSPACE, "backspace" },
+
+ { KEY_RIGHT, "right" },
+ { KEY_LEFT, "left" },
+ { KEY_UP, "up" },
+ { KEY_DOWN, "down" },
+ { KEY_PPAGE, "pgup" },
+ { KEY_NPAGE, "pgdown" },
+ { KEY_HOME, "home" },
+ { KEY_END, "end" },
};
#define NKEYTAB (sizeof(keytab)/sizeof(struct KEYTAB))
@@ -432,21 +484,17 @@ new_message(char *txt)
static void
channel_menu(void)
{
- int i,f;
- char key[32],ctrl[16];
+ char key[32],ctrl[16],event[64],action[128];
+ int i;
for (i = 0; i < count; i++) {
if (channels[i]->key) {
if (2 != sscanf(channels[i]->key,"%15[A-Za-z0-9_]+%31[A-Za-z0-9_]",
ctrl,key))
strcpy(key,channels[i]->key);
- if (1 == sscanf(key,"F%d",&f)) {
- channels[i]->ckey = KEY_F(f); /* Function keys */
- } else if (strlen(key) == 1) {
- if (isalpha(key[0]))
- key[0] = tolower(key[0]);
- channels[i]->ckey = (int)key[0]; /* single letter/digit */
- }
+ sprintf(event,"kbd-key-%s",key);
+ sprintf(action,"setstation \"%s\"",channels[i]->name);
+ event_register(event,action);
}
}
}
@@ -532,7 +580,7 @@ main(int argc, char *argv[])
unsigned long freq;
struct timeval tv;
time_t t;
- char text[80],*env,*dst;
+ char text[80],event[64],*env,*dst;
fd_set set;
if (0 == geteuid() && 0 != getuid()) {
@@ -625,7 +673,7 @@ main(int argc, char *argv[])
strcat(ng_v4l_conf," -y ");
grabber_init();
- read_config();
+ read_config(NULL);
if (0 != strlen(mixerdev)) {
struct ng_attribute *attr;
if (NULL != (attr = ng_mix_init(mixerdev,mixerctl)))
@@ -674,7 +722,8 @@ main(int argc, char *argv[])
}
}
- /* lirc + midi + joystick support */
+ /* keyboard, lirc + midi + joystick input support */
+ event_register_list(kbd_events);
lirc = lirc_tv_init();
js = joystick_tv_init(joydev);
#ifdef HAVE_ALSA
@@ -800,33 +849,27 @@ main(int argc, char *argv[])
#endif
default:
- /* look for station hotkeys */
- if (isalpha(key))
- key = tolower(key);
- for (i = 0; i < count; i++)
- if (channels[i]->ckey == key) {
- cur_sender = i;
- break;
+ event[0] = 0;
+ if (key > ' ' && key < 127) {
+ /* as is */
+ sprintf(event,"kbd-key-%c",key);
+ } else if (key >= KEY_F(0) && key <= KEY_F(12)) {
+ /* function keys */
+ sprintf(event,"kbd-key-f%d",key - KEY_F(0));
+ } else {
+ /* other special keys */
+ for (i = 0; i < NKEYTAB; i++) {
+ if (keytab[i].key == key)
+ break;
}
- if (i < count) {
- do_va_cmd(2,"setstation",channels[i]->name);
- break;
+ if (i != NKEYTAB)
+ sprintf(event,"kbd-key-%s",keytab[i].name);
}
-
- /* for commands */
- for (i = 0; i < NKEYTAB; i++) {
- if (keytab[i].key == key)
- break;
- }
- if (i != NKEYTAB) {
- do_command(keytab[i].argc,keytab[i].argv);
- break;
+ if (0 != event[0]) {
+ event_dispatch(event);
+ } else {
+ sprintf(message,"unknown key: %d 0x%x ",key,key);
}
-
- /* nothing found -- some maybe useful debug output */
- sprintf(message,"key: %d 0x%x ",key,key);
- if (key > 0x20 && key < 128)
- sprintf(message+strlen(message),"'%c' ",key);
}
} /* if (FD_ISSET(0,&set)) */
diff --git a/src/joystick.c b/src/joystick.c
index 10b731a..69ed3fe 100644
--- a/src/joystick.c
+++ b/src/joystick.c
@@ -16,6 +16,7 @@
#include "grab-ng.h"
#include "commands.h"
#include "joystick.h"
+#include "event.h"
/*-----------------------------------------------------------------------*/
@@ -23,23 +24,46 @@ extern int debug;
#ifdef HAVE_LINUX_JOYSTICK_H
struct JOYTAB {
- int class;
- int number;
- int value;
- int argc;
- char *argv[8];
+ int class;
+ int number;
+ int value;
+ char *event;
};
static struct JOYTAB joytab[] = {
- { JS_EVENT_BUTTON, 0, 1, 1, {"quit"}},
- { JS_EVENT_BUTTON, 1, 1, 1, {"fullscreen"}},
- { JS_EVENT_AXIS, 1, -32767, 2, {"volume", "inc"}},
- { JS_EVENT_AXIS, 1, 32767, 2, {"volume", "dec"}},
- { JS_EVENT_AXIS, 0, 32767, 2, {"setchannel", "next"}},
- { JS_EVENT_AXIS, 0, -32767, 2, {"setchannel", "prev"}},
+ { JS_EVENT_BUTTON, 0, 1, "joy-button-0" },
+ { JS_EVENT_BUTTON, 1, 1, "joy-button-1" },
+ { JS_EVENT_AXIS, 1, -32767, "joy-axis-up" },
+ { JS_EVENT_AXIS, 1, 32767, "joy-axis-down" },
+ { JS_EVENT_AXIS, 0, 32767, "joy-axis-left" },
+ { JS_EVENT_AXIS, 0, -32767, "joy-axis-right" },
};
-
#define NJOYTAB (sizeof(joytab)/sizeof(struct JOYTAB))
+
+static struct event_entry joy_events[] = {
+ {
+ event: "joy-button-0",
+ action: "quit",
+ },{
+ event: "joy-button-1",
+ action: "fullscreen",
+ },{
+ event: "joy-axis-up",
+ action: "volume inc",
+ },{
+ event: "joy-axis-down",
+ action: "volume dec",
+ },{
+ event: "joy-axis-left",
+ action: "setchannel prev",
+ },{
+ event: "joy-axis-right",
+ action: "setchannel next",
+ },{
+ /* end of list */
+ }
+};
+
#endif
int joystick_tv_init(char *dev)
@@ -54,6 +78,7 @@ int joystick_tv_init(char *dev)
return -1;
}
fcntl(fd,F_SETFD,FD_CLOEXEC);
+ event_register_list(joy_events);
return fd;
#else
return -1;
@@ -74,7 +99,7 @@ void joystick_tv_havedata(int js)
&& joytab[i].value == event.value)
break;
if (i != NJOYTAB)
- do_command(joytab[i].argc, joytab[i].argv);
+ event_dispatch(joytab[i].event);
}
#endif
}
diff --git a/src/lirc.c b/src/lirc.c
index 47bd5b6..ef9d1b4 100644
--- a/src/lirc.c
+++ b/src/lirc.c
@@ -13,13 +13,72 @@
#include "grab-ng.h"
#include "commands.h"
#include "lirc.h"
+#include "event.h"
/*-----------------------------------------------------------------------*/
extern int debug;
#ifdef HAVE_LIBLIRC_CLIENT
-static struct lirc_config *config;
+static struct event_entry lirc_events[] = {
+ {
+ event: "lirc-key-ch+",
+ action: "setstation next",
+ },{
+ event: "lirc-key-ch-",
+ action: "setstation prev",
+ },{
+ event: "lirc-key-vol+",
+ action: "volume inc",
+ },{
+ event: "lirc-key-vol-",
+ action: "volume dec",
+ },{
+ event: "lirc-key-mute",
+ action: "volume mute",
+ },{
+ event: "lirc-key-full_screen",
+ action: "fullscreen toggle",
+ },{
+ event: "lirc-key-source",
+ action: "setinput next",
+ },{
+ event: "lirc-key-reserved",
+ action: "quit",
+ },{
+ event: "lirc-key-0",
+ action: "keypad 0",
+ },{
+ event: "lirc-key-1",
+ action: "keypad 1",
+ },{
+ event: "lirc-key-2",
+ action: "keypad 2",
+ },{
+ event: "lirc-key-3",
+ action: "keypad 3",
+ },{
+ event: "lirc-key-4",
+ action: "keypad 4",
+ },{
+ event: "lirc-key-5",
+ action: "keypad 5",
+ },{
+ event: "lirc-key-6",
+ action: "keypad 6",
+ },{
+ event: "lirc-key-7",
+ action: "keypad 7",
+ },{
+ event: "lirc-key-8",
+ action: "keypad 8",
+ },{
+ event: "lirc-key-9",
+ action: "keypad 9",
+ },{
+ /* end of list */
+ }
+};
#endif
int lirc_tv_init()
@@ -29,16 +88,14 @@ int lirc_tv_init()
if (-1 == (fd = lirc_init("xawtv",debug))) {
if (debug)
- fprintf(stderr,"no infrared remote support available\n");
- return -1;
- }
-
- if (0 != lirc_readconfig(NULL,&config,NULL)) {
- lirc_deinit();
+ fprintf(stderr,"lirc: no infrared remote support available\n");
return -1;
}
fcntl(fd,F_SETFL,O_NONBLOCK);
fcntl(fd,F_SETFD,FD_CLOEXEC);
+ event_register_list(lirc_events);
+ if (debug)
+ fprintf(stderr,"lirc: init ok\n");
return fd;
#else
@@ -49,18 +106,18 @@ int lirc_tv_init()
int lirc_tv_havedata()
{
#ifdef HAVE_LIBLIRC_CLIENT
- char *code,*cmd,**argv;
- int argc;
+ char *code,event[32];
+ int dummy1,dummy2;
int ret=-1;
- while (lirc_nextcode(&code)==0 && code!=NULL) {
+ strcpy(event,"lirc-key-");
+ while (lirc_nextcode(&code)==0 && code!=NULL) {
ret = 0;
- while (lirc_code2char(config,code,&cmd)==0 && cmd!=NULL) {
- if (debug)
- fprintf(stderr,"lirc: \"%s\"\n", cmd);
- argv = split_cmdline(cmd,&argc);
- do_command(argc,argv);
+ if (3 != sscanf(code,"%x %x %20s",&dummy1,&dummy2,event+9)) {
+ fprintf(stderr,"lirc: oops, parse error: %s",code);
+ continue;
}
+ event_dispatch(event);
free(code);
}
return ret;
diff --git a/src/main.c b/src/main.c
index fc1cd6c..f751e06 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1512,32 +1512,6 @@ create_launchwin(void)
launch_shell, NULL);
}
-/*------------------------------------------------------------------------*/
-
-static void
-segfault(int signal)
-{
- fprintf(stderr,"[pid=%d] segfault catched\n",getpid());
- abort();
-}
-
-
-static void
-siginit(void)
-{
- struct sigaction act,old;
-
- memset(&act,0,sizeof(act));
- sigemptyset(&act.sa_mask);
- act.sa_handler = exec_done;
- sigaction(SIGCHLD,&act,&old);
- if (debug) {
- act.sa_handler = segfault;
- sigaction(SIGSEGV,&act,&old);
- fprintf(stderr,"main thread [pid=%d]\n",getpid());
- }
-}
-
/*--- main ---------------------------------------------------------------*/
int
@@ -1640,7 +1614,7 @@ main(int argc, char *argv[])
}
if (debug)
fprintf(stderr,"main: install signal handlers...\n");
- siginit();
+ xt_siginit();
if (NULL == drv) {
if (debug)
fprintf(stderr,"main: open grabber device...\n");
@@ -1666,7 +1640,7 @@ main(int argc, char *argv[])
if (args.readconfig) {
if (debug)
fprintf(stderr,"main: read config file ...\n");
- read_config();
+ read_config(args.conffile ? args.conffile : NULL);
}
if (0 != strlen(mixerdev)) {
struct ng_attribute *attr;
diff --git a/src/midictrl.c b/src/midictrl.c
index cf30e3e..5617c4e 100644
--- a/src/midictrl.c
+++ b/src/midictrl.c
@@ -12,6 +12,7 @@
#include "commands.h"
#include "channel.h"
#include "midictrl.h"
+#include "event.h"
extern int debug;
@@ -248,7 +249,7 @@ int midi_read(struct midi_handle *h)
fprintf(stderr, "midi: snd_seq_event_input: %s\n",snd_strerror(rc));
return -1;
}
- if (debug)
+ if (debug > 1)
midi_dump_ev(stderr,h->ev);
return 0;
}
@@ -257,7 +258,7 @@ int midi_read(struct midi_handle *h)
#ifdef STANDALONE
-int debug = 1;
+int debug = 2;
int main(int argc, char *argv[])
{
@@ -281,23 +282,28 @@ int main(int argc, char *argv[])
void midi_translate(struct midi_handle *h)
{
- char val[8];
+ char event[64];
int i;
switch (h->ev->type) {
case SND_SEQ_EVENT_NOTEON:
- if (h->ev->data.note.velocity > 0) {
- for (i = 0; i < count; i++)
- if (channels[i]->midi != 0 &&
- channels[i]->midi == h->ev->data.note.note)
- do_va_cmd(2,"setstation",channels[i]->name);
+ if (0 == h->ev->data.note.velocity)
+ return;
+ for (i = 0; i < count; i++) {
+ if (channels[i]->midi != 0 &&
+ channels[i]->midi == h->ev->data.note.note) {
+ do_va_cmd(2,"setstation",channels[i]->name);
+ return;
+ }
}
+ sprintf(event,"midi-note-%d",h->ev->data.note.note);
+ event_dispatch(event);
break;
case SND_SEQ_EVENT_CONTROLLER:
- if (h->ev->data.control.param == 7 /* VOLUME */) {
- sprintf(val,"%d", h->ev->data.control.value * 65535/128);
- do_va_cmd(2,"volume",val);
- }
+ sprintf(event,"midi-ctrl-%d(%d%%)",
+ h->ev->data.control.param,
+ h->ev->data.control.value*100/128);
+ event_dispatch(event);
}
}
diff --git a/src/motif.c b/src/motif.c
index 91f7a9a..cbbfab8 100644
--- a/src/motif.c
+++ b/src/motif.c
@@ -3130,11 +3130,9 @@ main(int argc, char *argv[])
args.bpp = 0;
}
}
-#if 0
if (debug)
fprintf(stderr,"main: install signal handlers...\n");
- siginit();
-#endif
+ xt_siginit();
if (NULL == drv) {
if (debug)
fprintf(stderr,"main: open grabber device...\n");
@@ -3162,7 +3160,7 @@ main(int argc, char *argv[])
if (args.readconfig) {
if (debug)
fprintf(stderr,"main: read config file ...\n");
- read_config();
+ read_config(args.conffile ? args.conffile : NULL);
}
if (0 != strlen(mixerdev)) {
struct ng_attribute *attr;
diff --git a/src/scantv.c b/src/scantv.c
index 1706835..8cfd327 100644
--- a/src/scantv.c
+++ b/src/scantv.c
@@ -1,5 +1,5 @@
/*
- * (c) 2000,01 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ * (c) 2000-2002 Gerd Knorr <kraxel@goldbach.in-berlin.de>
*
*/
#include "config.h"
@@ -183,7 +183,7 @@ main(int argc, char **argv)
{
struct vbi *vbi;
struct ng_attribute *attr;
- int c,i,j,scan=1;
+ int c,f,f1,f2,fc,fi,on,tuned,i,j,scan=1,fullscan=0;
char *name,dummy[32];
char *tvnorm = NULL;
char *freqtab = NULL;
@@ -195,7 +195,7 @@ main(int argc, char **argv)
/* parse options */
ng_init();
for (;;) {
- if (-1 == (c = getopt(argc, argv, "hsdn:f:o:c:C:")))
+ if (-1 == (c = getopt(argc, argv, "hsadn:f:o:c:C:")))
break;
switch (c) {
case 'd':
@@ -204,6 +204,9 @@ main(int argc, char **argv)
case 's':
scan=0;
break;
+ case 'a':
+ fullscan=1;
+ break;
case 'n':
tvnorm = optarg;
break;
@@ -258,6 +261,7 @@ main(int argc, char **argv)
fprintf(conf,"input = Television\n");
fprintf(conf,"norm = %s\n",ng_attr_getstr(attr,i));
fprintf(conf,"\n");
+ fflush(conf);
if (!scan)
exit(0);
@@ -274,26 +278,110 @@ main(int argc, char **argv)
fdset_init(fds);
if (not(vbi = vbi_open(ng_dev.vbi, 0, 0, -1)))
fatal("cannot open %s", ng_dev.vbi);
-
- /* scan channels */
- fprintf(stderr,"\nscanning...\n");
vbi_add_handler(vbi, event, NULL);
- for (i = 0; i < chancount; i++) {
- fprintf(stderr,"%-4s (%6.2f MHz): ",chanlist[i].name,(float)chanlist[i].freq/1000);
- do_va_cmd(2,"setchannel",chanlist[i].name);
- usleep(200000); /* 0.2 sec */
- if (0 == drv->is_tuned(h_drv)) {
- fprintf(stderr,"no station\n");
- continue;
+
+ if (!fullscan) {
+ /* scan channels */
+ fprintf(stderr,"\nscanning channel list %s...\n",
+ chanlist_names[j].str);
+ for (i = 0; i < chancount; i++) {
+ fprintf(stderr,"%-4s (%6.2f MHz): ",chanlist[i].name,
+ (float)chanlist[i].freq/1000);
+ do_va_cmd(2,"setchannel",chanlist[i].name);
+ usleep(200000); /* 0.2 sec */
+ if (0 == drv->is_tuned(h_drv)) {
+ fprintf(stderr,"no station\n");
+ continue;
+ }
+ fdset_select(fds, 1000 * timeout);
+ name = get_vbi_name();
+ fprintf(stderr,"%s\n",name ? name : "???");
+ if (NULL == name) {
+ sprintf(dummy,"unknown (%s)",chanlist[i].name);
+ name = dummy;
+ }
+ fprintf(conf,"[%s]\nchannel = %s\n\n",name,chanlist[i].name);
+ fflush(conf);
}
- fdset_select(fds, 1000 * timeout);
- name = get_vbi_name();
- fprintf(stderr,"%s\n",name ? name : "???");
- if (NULL == name) {
- sprintf(dummy,"unknown (%s)",chanlist[i].name);
- name = dummy;
+ } else {
+ /* scan freqnencies */
+ fprintf(stderr,"\nscanning freqencies...\n");
+ on = 0;
+ fc = 0;
+ f1 = 0;
+ f2 = 0;
+ fi = -1;
+ for (f = 44*16; f <= 958*16; f += 4) {
+ for (i = 0; i < chancount; i++)
+ if (chanlist[i].freq * 16 == f * 1000)
+ break;
+ fprintf(stderr,"?? %6.2f MHz (%-4s): ",f/16.0,
+ (i == chancount) ? "-" : chanlist[i].name);
+ drv->setfreq(h_drv,f);
+ usleep(200000); /* 0.2 sec */
+ tuned = drv->is_tuned(h_drv);
+
+ /* state machine */
+ if (0 == on && 0 == tuned) {
+ fprintf(stderr,"| no\n");
+ continue;
+ }
+ if (0 == on && 0 != tuned) {
+ fprintf(stderr," \\ raise\n");
+ f1 = f;
+ if (i != chancount) {
+ fi = i;
+ fc = f;
+ }
+ on = 1;
+ continue;
+ }
+ if (0 != on && 0 != tuned) {
+ fprintf(stderr," | yes\n");
+ if (i != chancount) {
+ fi = i;
+ fc = f;
+ }
+ continue;
+ }
+ /* if (on != 0 && 0 == tuned) -- found one, read name from vbi */
+ fprintf(stderr," / fall\n");
+ f2 = f;
+ if (0 == fc)
+ fc = (f1+f2)/2;
+
+ fprintf(stderr,"=> %6.2f MHz (%-4s): ", fc/16.0,
+ (-1 != fi) ? chanlist[fi].name : "-");
+ drv->setfreq(h_drv,fc);
+
+ fdset_select(fds, 1000 * timeout);
+ name = get_vbi_name();
+ fprintf(stderr,"%s\n",name ? name : "???");
+ if (NULL == name) {
+ sprintf(dummy,"unknown (%s)",chanlist[fi].name);
+ name = dummy;
+ }
+ if (-1 != fi) {
+ if (NULL == name) {
+ sprintf(dummy,"unknown (%s)",chanlist[fi].name);
+ name = dummy;
+ }
+ fprintf(conf,"[%s]\nchannel = %s\n\n",name,chanlist[fi].name);
+ } else {
+ if (NULL == name) {
+ sprintf(dummy,"unknown (%.3f)", fc/16.0);
+ name = dummy;
+ }
+ fprintf(conf,"[%s]\nfreq = %.3f\n\n", name, fc/16.0);
+ }
+ fflush(conf);
+
+ on = 0;
+ fc = 0;
+ f1 = 0;
+ f2 = 0;
+ fi = -1;
}
- fprintf(conf,"[%s]\nchannel = %s\n\n",name,chanlist[i].name);
}
/* cleanup */
diff --git a/src/v4lctl.c b/src/v4lctl.c
index c945389..9366c6b 100644
--- a/src/v4lctl.c
+++ b/src/v4lctl.c
@@ -94,7 +94,7 @@ int main(int argc, char *argv[])
#endif
if (NULL == drv)
grabber_init();
- read_config();
+ read_config(NULL);
attr_init();
audio_init();
diff --git a/src/xt.c b/src/xt.c
index 9d67d30..ab976f4 100644
--- a/src/xt.c
+++ b/src/xt.c
@@ -132,28 +132,33 @@ XtResource args_desc[] = {
"device",
XtCString, XtRString, sizeof(char*),
XtOffset(struct ARGS*,device),
- XtRString, "default"
+ XtRString, NULL
},{
"dspdev",
XtCString, XtRString, sizeof(char*),
XtOffset(struct ARGS*,dspdev),
- XtRString, "default"
+ XtRString, NULL
},{
"vbidev",
XtCString, XtRString, sizeof(char*),
XtOffset(struct ARGS*,vbidev),
- XtRString, "default"
+ XtRString, NULL
},{
"joydev",
XtCString, XtRString, sizeof(char*),
XtOffset(struct ARGS*,joydev),
- XtRString, "default"
+ XtRString, NULL
},{
"basename",
XtCString, XtRString, sizeof(char*),
XtOffset(struct ARGS*,basename),
XtRString, "snap"
},{
+ "conffile",
+ XtCString, XtRString, sizeof(char*),
+ XtOffset(struct ARGS*,conffile),
+ XtRString, NULL
+ },{
/* Integer */
"debug",
XtCValue, XtRInt, sizeof(int),
@@ -249,6 +254,7 @@ XrmOptionDescRec opt_desc[] = {
{ "-joydev", "joydev", XrmoptionSepArg, NULL },
{ "-o", "basename", XrmoptionSepArg, NULL },
{ "-outfile", "basename", XrmoptionSepArg, NULL },
+ { "-conffile", "conffile", XrmoptionSepArg, NULL },
{ "-v", "debug", XrmoptionSepArg, NULL },
{ "-debug", "debug", XrmoptionSepArg, NULL },
@@ -312,7 +318,7 @@ ExitCB(Widget widget, XtPointer client_data, XtPointer calldata)
void
do_exit(void)
{
- ExitCB(NULL,NULL,NULL);
+ ExitCB(NULL,NULL,NULL);
}
void
@@ -669,6 +675,52 @@ LaunchAction(Widget widget, XEvent *event,
}
}
+/*------------------------------------------------------------------------*/
+
+XtSignalId sig_id;
+
+static void termsig_handler(XtPointer data, XtSignalId *id)
+{
+ ExitCB(NULL,NULL,NULL);
+}
+
+static void
+termsig(int signal)
+{
+ if (debug)
+ fprintf(stderr,"received signal %d [%s]\n",signal,strsignal(signal));
+ XtNoticeSignal(sig_id);
+}
+
+static void
+segfault(int signal)
+{
+ fprintf(stderr,"[pid=%d] segfault catched, aborting\n",getpid());
+ abort();
+}
+
+void
+xt_siginit(void)
+{
+ struct sigaction act,old;
+
+ memset(&act,0,sizeof(act));
+ sigemptyset(&act.sa_mask);
+ act.sa_handler = exec_done;
+ sigaction(SIGCHLD,&act,&old);
+
+ sig_id = XtAppAddSignal(app_context,termsig_handler,NULL);
+ act.sa_handler = termsig;
+ sigaction(SIGINT,&act,&old);
+ sigaction(SIGTERM,&act,&old);
+
+ if (debug) {
+ act.sa_handler = segfault;
+ sigaction(SIGSEGV,&act,&old);
+ fprintf(stderr,"main thread [pid=%d]\n",getpid());
+ }
+}
+
/*----------------------------------------------------------------------*/
Boolean
@@ -950,10 +1002,8 @@ set_property(int freq, char *channel, char *name)
char line[80];
len = sprintf(line,"%.3f",(float)freq/16)+1;
- if (NULL != channel)
- len += sprintf(line+len,"%s",channel)+1;
- if (NULL != name)
- len += sprintf(line+len,"%s",name)+1;
+ len += sprintf(line+len,"%s",channel ? channel : "?") +1;
+ len += sprintf(line+len,"%s",name ? name : "?") +1;
XChangeProperty(dpy, XtWindow(app_shell),
xawtv_station, XA_STRING,
8, PropModeReplace,
@@ -1378,13 +1428,11 @@ handle_cmdline_args(void)
debug = args.debug;
ng_debug = args.debug;
- if (0 == strcmp(args.joydev,"default"))
- args.joydev = NULL;
- if (0 == strcmp(args.dspdev,"default"))
+ if (NULL == args.dspdev)
args.dspdev = ng_dev.dsp;
- if (0 == strcmp(args.vbidev,"default"))
+ if (NULL == args.vbidev)
args.vbidev = ng_dev.vbi;
- if (0 == strcmp(args.device,"default")) {
+ if (NULL == args.device) {
args.device = ng_dev.video;
} else {
args.xv_video = 0;
diff --git a/src/xt.h b/src/xt.h
index 8377bd2..c4f8292 100644
--- a/src/xt.h
+++ b/src/xt.h
@@ -6,6 +6,7 @@ struct ARGS {
char *vbidev;
char *joydev;
char *basename;
+ char *conffile;
/* int */
int debug;
@@ -107,6 +108,7 @@ void exec_done(int signal);
/* static void exec_output(XtPointer data, int *fd, XtInputId * iproc); */
int exec_x11(char **argv);
void exec_player(char *moviefile);
+void xt_siginit(void);
void new_title(char *txt);
void new_message(char *txt);
diff --git a/tools/record.c b/tools/record.c
index ee084ad..afe8228 100644
--- a/tools/record.c
+++ b/tools/record.c
@@ -45,7 +45,7 @@ static short *sound_buffer;
static int maxl,maxr;
static int secl,secr;
static int *histl,*histr,histn,histi;
-static int peak_seconds = 2;
+static float peak_seconds = 1.5;
static char *audio_dev = "/dev/dsp";
static int
@@ -526,7 +526,7 @@ usage(FILE *fp)
" -m dev set mixer device [%s]\n"
" -d dev set dsp device [%s]\n"
" -r rate set sample rate [%d]\n"
- " -p sec peak seconds [%d]\n"
+ " -p sec peak seconds [%.1f]\n"
"\n"
"for non-interactive usage only:\n"
" -c enable console (non-interactive) mode\n"
@@ -596,7 +596,7 @@ main(int argc, char *argv[])
rate = atoi(optarg);
break;
case 'p':
- peak_seconds = atoi(optarg);
+ peak_seconds = atof(optarg);
break;
case 't':
if (3 != sscanf(optarg,"%d:%d:%d",&maxhour,&maxmin,&maxsec)) {
diff --git a/tools/record.man b/tools/record.man
index 668332c..e6ec887 100644
--- a/tools/record.man
+++ b/tools/record.man
@@ -36,7 +36,7 @@ set sample rate. Default is 44100.
.B -p sec
peak seconds (number of seconds which should be scanned for the volume
maximum). This affects both peak level display and level triggered
-recording (see below). Default is two seconds.
+recording (see below). Default is 1.5 seconds.
.P
record can also be used non-interactive:
.TP
@@ -65,7 +65,7 @@ If level triggered recording is active, record will start and stop
recording depending on the signal strength. Recording will be started
if the signal strength is above the trigger level (1000/32768 =>
around 3%). Recording will be stopped if the signal is below the
-trigger level for some time (two seconds by default, the -p switch
+trigger level for some time (1.5 seconds by default, the -p switch
changes this).
.SH AUTHOR
Gerd Knorr <kraxel@bytesex.org>
diff --git a/xawtv.spec b/xawtv.spec
index 690f42f..9c264df 100644
--- a/xawtv.spec
+++ b/xawtv.spec
@@ -2,7 +2,7 @@ Name: xawtv
Group: Applications/Multimedia
Requires: v4l-conf, tv-common
Autoreqprov: on
-Version: 3.69
+Version: 3.70
Release: 0
License: GPL
Summary: Video4Linux TV application (Athena)

Privacy Policy