aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changes18
-rw-r--r--Makefile.in30
-rw-r--r--common/Subdir.mk4
-rw-r--r--common/channel.c12
-rw-r--r--common/channel.h2
-rwxr-xr-xconfigure2
-rw-r--r--configure.ac2
-rw-r--r--console/fbtools.c4
-rw-r--r--console/radio.c23
-rw-r--r--console/record.c12
-rw-r--r--console/streamer.c63
-rw-r--r--console/v4l-conf.c2
-rw-r--r--console/webcam.c3
-rw-r--r--contrib/vdr.config45
-rw-r--r--debian/changelog9
-rw-r--r--debian/control16
-rw-r--r--debian/xawtv-plugin-alsa.files1
-rw-r--r--debian/xawtv-plugin-qt.files1
-rw-r--r--debian/xawtv.template.da67
-rw-r--r--debian/xawtv.templates71
-rw-r--r--libng/color_lut.c50
-rw-r--r--libng/color_packed.c67
-rw-r--r--libng/color_yuv2rgb.c49
-rw-r--r--libng/grab-ng.c7
-rw-r--r--libng/grab-ng.h21
-rw-r--r--libng/plugins/Subdir.mk7
-rw-r--r--libng/plugins/conv-audio.c163
-rw-r--r--libng/plugins/drv0-v4l2.c6
-rw-r--r--libng/plugins/drv1-v4l.c2
-rw-r--r--libng/plugins/write-dv.c2
-rw-r--r--man/propwatch.133
-rw-r--r--man/record.14
-rw-r--r--man/streamer.18
-rw-r--r--man/xawtvrc.57
-rw-r--r--mk/Compile.mk (renamed from mk/compile.mk)28
-rw-r--r--structs/struct-dump.c3
-rw-r--r--todo/tmohan/webcam.c1650
-rw-r--r--vbistuff/Subdir.mk2
-rw-r--r--x11/Subdir.mk10
-rw-r--r--x11/motv.c2
-rw-r--r--x11/propwatch.c408
-rw-r--r--x11/wmhooks.c9
-rw-r--r--x11/wmhooks.h2
-rw-r--r--x11/xt.c86
-rw-r--r--xawtv.spec2
45 files changed, 2637 insertions, 378 deletions
diff --git a/Changes b/Changes
index 8802972..5afa42a 100644
--- a/Changes
+++ b/Changes
@@ -1,4 +1,22 @@
+3.82 => 3.83
+============
+
+ * compile fixes.
+ * propwatch updates.
+ * added config option to disable _NET_WM_STATE_FULLSCREEN support.
+ * added config option to move the OSD (Alex Ibrado <alex@ibrado.com>).
+ * minor radio tweaks (DAVID BALAZIC <david.balazic@uni-mb.si>).
+
+
+3.81 => 3.82
+============
+
+ * compile fixes again ...
+ * v4l-conf fix (Kyosti Malkki <kmalkki@cc.hut.fi>).
+ * wmhook fix (Marcin Krzyzanowski <krzak@hakore.com>).
+
+
3.81 => 3.82
============
diff --git a/Makefile.in b/Makefile.in
index e34fcf3..e487b6b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -46,7 +46,7 @@ OSS_LIBS := @LIBOSS@
ALSA_LIBS := @LIBALSA@
AA_LIBS := @AALIBS@
QT_LIBS := @QTLIBS@
-VBI_LIBS := @LIBZVBI@ -lm -lpng
+VBI_LIBS := @LIBZVBI@
GL_LIBS := @LIBGL@
DV_LIBS := @LIBDV@
FS_LIBS := -L@x_libraries@ @FSLIB@
@@ -65,19 +65,23 @@ FOUND_ZVBI := @FOUND_ZVBI@
USE_MMX := @USE_MMX@
# build final cflags
-CFLAGS := @CFLAGS@
-CFLAGS += $(WARN_FLAGS)
-CFLAGS += $(LFS_FLAGS)
-CFLAGS += $(X11_FLAGS)
-CFLAGS += $(LIB_FLAGS)
-CFLAGS += -DCONFIGFILE='"$(config)"'
-CFLAGS += -DLIBDIR='"$(libdir)"'
-CFLAGS += -DDATADIR='"$(datadir)"'
-CFLAGS += -DVERSION='"$(VERSION)"'
-CXXFLAGS = $(CFLAGS)
+CFLAGS := @CFLAGS@
+CFLAGS += $(WARN_FLAGS)
+CFLAGS += $(LFS_FLAGS)
+CFLAGS += $(X11_FLAGS)
+CFLAGS += $(LIB_FLAGS)
+CFLAGS += -DCONFIGFILE='"$(config)"'
+CFLAGS += -DLIBDIR='"$(libdir)"'
+CFLAGS += -DDATADIR='"$(datadir)"'
+CFLAGS += -DVERSION='"$(VERSION)"'
+CXXFLAGS := $(CFLAGS)
+
+# for gcc3
+#CFLAGS += -std-gnu99
# shared objects need -fPIC
-%.so : CFLAGS += -fPIC
+%.so : CFLAGS += -fPIC
+%.so : CXXFLAGS += -fPIC
# libraries
LDLIBS := @LDLIBS@
@@ -119,7 +123,7 @@ realclean:: distclean
#########################################################
# some rules ...
-include $(srcdir)/mk/compile.mk
+include $(srcdir)/mk/Compile.mk
%.h: %.in
perl $(srcdir)/scripts/html.pl < $< > $@
diff --git a/common/Subdir.mk b/common/Subdir.mk
index 0b8b5ec..1bb72d2 100644
--- a/common/Subdir.mk
+++ b/common/Subdir.mk
@@ -16,10 +16,10 @@ OBJS-common-input := \
common/midictrl.o
# RegEdit.c is good old K&R ...
-common/RegEdit.o : CFLAGS += -Wno-missing-prototypes -Wno-strict-prototypes
+common/RegEdit.o: CFLAGS += -Wno-missing-prototypes -Wno-strict-prototypes
common/channel-no-x11.o: CFLAGS += -DNO_X11=1
-common/channel-no-x11.o:: common/channel.c
+common/channel-no-x11.o: common/channel.c
@$(echo_compile_c)
@$(compile_c)
@$(fixup_deps)
diff --git a/common/channel.c b/common/channel.c
index 0c79355..567f6ae 100644
--- a/common/channel.c
+++ b/common/channel.c
@@ -75,7 +75,10 @@ int cur_capture = CAPTURE_OFF;
int have_config;
int keypad_ntsc = 0;
int keypad_partial = 1;
+int use_wm_fullscreen = 1;
int use_osd = 1;
+int osd_x = 30;
+int osd_y = 20;
int fs_width,fs_height,fs_xoff,fs_yoff;
int pix_width=128, pix_height=96, pix_cols=1;
@@ -468,6 +471,12 @@ read_config(char *conffile, int *argc, char **argv)
if (NULL != (val = cfg_get_str("global","osd")))
if (-1 != (i = str_to_int(val,booltab)))
use_osd = i;
+ if (NULL != (val = cfg_get_str("global","osd-position")))
+ if (2 != sscanf(val,"%d , %d",&osd_x,&osd_y))
+ fprintf(stderr,"invalid values for osd-position: %s\n",val);
+ if (NULL != (val = cfg_get_str("global","use-wm-fullscreen")))
+ if (-1 != (i = str_to_int(val,booltab)))
+ use_wm_fullscreen = i;
if (NULL != (val = cfg_get_str("global","mov-driver")))
mov_driver = val;
@@ -580,6 +589,9 @@ save_config()
fprintf(fp,"keypad-ntsc = %s\n",int_to_str(keypad_ntsc,booltab));
fprintf(fp,"keypad-partial = %s\n",int_to_str(keypad_partial,booltab));
fprintf(fp,"osd = %s\n",int_to_str(use_osd,booltab));
+ fprintf(fp,"osd-position = %d , %d\n",osd_x,osd_y);
+ fprintf(fp,"use-wm-fullscreen = %s\n",
+ int_to_str(use_wm_fullscreen,booltab));
if (mixer)
fprintf(fp,"mixer = %s\n",mixer);
if (midi)
diff --git a/common/channel.h b/common/channel.h
index 4d92893..fbc44f1 100644
--- a/common/channel.h
+++ b/common/channel.h
@@ -45,6 +45,8 @@ extern int jpeg_quality;
extern int keypad_ntsc;
extern int keypad_partial;
extern int use_osd;
+extern int osd_x, osd_y;
+extern int use_wm_fullscreen;
extern int fs_width,fs_height,fs_xoff,fs_yoff;
extern int pix_width,pix_height,pix_cols;
extern int last_sender, cur_sender;
diff --git a/configure b/configure
index 5872f35..5ed1770 100755
--- a/configure
+++ b/configure
@@ -5001,7 +5001,7 @@ if test $ac_cv_lib_zvbi_vbi_capture_fd = yes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_ZVBI 1
_ACEOF
- FOUND_ZVBI="yes"; LIBZVBI="-lzvbi -lpthread"
+ FOUND_ZVBI="yes"; LIBZVBI="-lzvbi -lpthread -lm -lpng -lz"
fi
else
diff --git a/configure.ac b/configure.ac
index e987ce0..eedbb60 100644
--- a/configure.ac
+++ b/configure.ac
@@ -177,7 +177,7 @@ AC_SUBST(LIBZVBI)
LIBZVBI=""
if test "$enable_zvbi" != "no"; then
AC_CHECK_LIB(zvbi, vbi_capture_fd,
- AC_DEFINE(HAVE_ZVBI,1,"have zvbi") FOUND_ZVBI="yes"; LIBZVBI="-lzvbi -lpthread",,)
+ AC_DEFINE(HAVE_ZVBI,1,"have zvbi") FOUND_ZVBI="yes"; LIBZVBI="-lzvbi -lpthread -lm -lpng -lz",,)
else
echo "*** zvbi disabled"
fi
diff --git a/console/fbtools.c b/console/fbtools.c
index b7473f0..228589f 100644
--- a/console/fbtools.c
+++ b/console/fbtools.c
@@ -262,7 +262,7 @@ fb_setvt(int vtno)
vtno &= 0xff;
sprintf(vtname, devices->ttynr, vtno);
chown(vtname, getuid(), getgid());
- if (-1 == access(vtname,R_OK | W_OK)) {
+ if (-1 == access(vtname, R_OK | W_OK)) {
fprintf(stderr,"access %s: %s\n",vtname,strerror(errno));
exit(1);
}
@@ -349,12 +349,12 @@ fb_init(char *device, char *mode, int vt)
struct stat st;
char fbdev[16];
+ dev_init();
tty = 0;
if (vt != 0)
fb_setvt(vt);
/* FIXME: where are MAJOR() / MINOR() ??? */
- dev_init();
fstat(tty,&st);
if (((st.st_rdev >> 8) & 0xff) != TTY_MAJOR) {
/* catch that here, give a more user friendly error message that just
diff --git a/console/radio.c b/console/radio.c
index 010b4a4..fb0e5a6 100644
--- a/console/radio.c
+++ b/console/radio.c
@@ -56,6 +56,17 @@ radio_setfreq(int fd, float freq)
return ioctl(fd, VIDIOCSFREQ, &ifreq);
}
+static int radio_getfreq(int fd, float *freq)
+{
+ int ioctl_status;
+ int ifreq;
+ ioctl_status = ioctl(fd,VIDIOCGFREQ, &ifreq);
+ if (ioctl_status == -1)
+ return ioctl_status;
+ *freq = (float) ifreq / get_freq_fact(fd);
+ return 0;
+}
+
static void
radio_unmute(int fd)
{
@@ -521,6 +532,12 @@ main(int argc, char *argv[])
if (!stset)
mvwprintw(wstations,1,1,"[none]");
wrefresh(wstations);
+
+ if (ifreq == 0) {
+ float ffreq;
+ radio_getfreq(fd,&ffreq);
+ ifreq = ffreq * 1000000;
+ }
radio_unmute(fd);
for (done = 0; done == 0;) {
@@ -569,7 +586,11 @@ main(int argc, char *argv[])
noecho();
curs_set(0);
wrefresh(wcommand);
- ifreq = newfreq * 1000000;
+ if ( (newfreq >= 87.5) && (newfreq <= 108) )
+ ifreq = newfreq * 1000000;
+ else
+ mvwprintw(wcommand, 1, 2,
+ "Frequency out of range (87.5-108 MHz)");
break;
case KEY_UP:
ifreq += 50000;
diff --git a/console/record.c b/console/record.c
index 5638fc6..b334a1e 100644
--- a/console/record.c
+++ b/console/record.c
@@ -535,6 +535,8 @@ usage(FILE *fp)
" until stopped by a signal (^C)\n"
" -s size set max file size [%s]. You have to give number\n"
" and unit without space inbetween, i.e. \"100mb\".\n"
+ " -n num limit amount of files recorded, quits when\n"
+ " reached.\n"
" -l signal level triggered recording.\n"
" -L level same as above + specify trigger level [%d]\n"
"\n",
@@ -552,6 +554,7 @@ main(int argc, char *argv[])
char *outfile;
fd_set s;
int sec,maxhour,maxmin,maxsec;
+ int maxfiles = 0;
off_t maxsize;
/* init some vars */
@@ -565,7 +568,7 @@ main(int argc, char *argv[])
/* parse options */
for (;;) {
- if (-1 == (c = getopt(argc, argv, "vhlci:o:d:m:r:t:s:L:p:")))
+ if (-1 == (c = getopt(argc, argv, "vhlci:o:d:m:r:t:s:L:p:n:")))
break;
switch (c) {
case 'v':
@@ -612,6 +615,9 @@ main(int argc, char *argv[])
case 's':
str_maxsize = optarg;
break;
+ case 'n':
+ maxfiles = atoi(optarg);
+ break;
case 'h':
usage(stdout);
exit(0);
@@ -649,7 +655,7 @@ main(int argc, char *argv[])
mvprintw(11,0,"'N' next file (same as space twice, but without break)");
mvprintw(12,0,"'Q' quit");
mvprintw(LINES-3,0,"--");
- mvprintw(LINES-2,0,"(c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>");
+ mvprintw(LINES-2,0,"(c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>");
for (;!stop;) {
refresh();
@@ -766,6 +772,8 @@ main(int argc, char *argv[])
secr < level_trigger) {
record_stop(wav);
record=0;
+ if (maxfiles && nr == maxfiles)
+ break;
}
}
if (!record) {
diff --git a/console/streamer.c b/console/streamer.c
index a4e9399..50fd7c8 100644
--- a/console/streamer.c
+++ b/console/streamer.c
@@ -107,6 +107,7 @@ usage(FILE *out)
"general options:\n"
" -h print this help text\n"
" -q quiet operation\n"
+ " -d enable debug output\n"
" -p n use n compression threads [%d]\n"
" -w seconds wait before grabbing [%d]\n"
"\n"
@@ -203,71 +204,83 @@ find_formats(void)
for (w = 0; NULL != ng_writers[w]; w++) {
wr = ng_writers[w];
if (debug)
- fprintf(stderr,"checking writer %s... ",wr->name);
+ fprintf(stderr,"checking writer %s [%s] ...\n",wr->name,wr->desc);
if ((/*!wr->combined && */mext) || NULL != vfmt_name) {
if (NULL == wr->video) {
if (debug)
- fprintf(stderr,"no video\n");
+ fprintf(stderr," no video, skipping\n");
continue;
}
for (v = 0; NULL != wr->video[v].name; v++) {
- if (mext && 0 != strcasecmp(wr->video[v].ext,mext))
+ if (debug)
+ fprintf(stderr," video name=%s ext=%s: ",
+ wr->video[v].name,wr->video[v].ext);
+ if (mext && 0 != strcasecmp(wr->video[v].ext,mext)) {
+ if (debug)
+ fprintf(stderr,"ext mismatch [need %s]\n",mext);
continue;
- if (vfmt_name && 0 != strcasecmp(wr->video[v].name,vfmt_name))
+ }
+ if (vfmt_name && 0 != strcasecmp(wr->video[v].name,vfmt_name)) {
+ if (debug)
+ fprintf(stderr,"name mismatch [need %s]\n",vfmt_name);
continue;
+ }
+ if (debug)
+ fprintf(stderr,"OK\n");
break;
}
- if (NULL == wr->video[v].name) {
- if (debug)
- fprintf(stderr,"video fmt not found [ext=%s,name=%s]\n",
- mext,vfmt_name);
+ if (NULL == wr->video[v].name)
continue;
- }
}
if ((!wr->combined && aext) || NULL != afmt_name) {
if (NULL == wr->audio) {
if (debug)
- fprintf(stderr,"no audio\n");
+ fprintf(stderr," no audio, skipping\n");
continue;
}
for (a = 0; NULL != wr->audio[a].name; a++) {
+ if (debug)
+ fprintf(stderr," audio name=%s ext=%s: ",
+ wr->audio[a].name,wr->audio[a].ext);
if (!wr->combined &&
- aext && 0 != strcasecmp(wr->audio[a].ext,aext))
+ aext && 0 != strcasecmp(wr->audio[a].ext,aext)) {
+ if (debug)
+ fprintf(stderr,"ext mismatch [need %s]\n",aext);
continue;
+ }
if (wr->combined &&
- mext && 0 != strcasecmp(wr->audio[a].ext,mext))
+ mext && 0 != strcasecmp(wr->audio[a].ext,mext)) {
+ if (debug)
+ fprintf(stderr,"ext mismatch [need %s]\n",mext);
continue;
- if (afmt_name && 0 != strcasecmp(wr->audio[a].name,afmt_name))
+ }
+ if (afmt_name && 0 != strcasecmp(wr->audio[a].name,afmt_name)) {
+ if (debug)
+ fprintf(stderr,"name mismatch [need %s]\n",afmt_name);
continue;
+ }
+ if (debug)
+ fprintf(stderr,"OK\n");
break;
}
- if (NULL == wr->audio[a].name) {
- if (debug)
- fprintf(stderr,"audio fmt not found [ext=%s,name=%s]\n",
- wr->combined ? mext : aext, afmt_name);
+ if (NULL == wr->audio[a].name)
continue;
- }
}
- if (debug)
- fprintf(stderr,"ok:");
break;
}
if (NULL != ng_writers[w]) {
writer = wr;
if (-1 != v) {
- if (debug)
- fprintf(stderr," video=%s",wr->video[v].name);
video.fmtid = wr->video[v].fmtid;
video_priv = wr->video[v].priv;
}
if (-1 != a) {
- if (debug)
- fprintf(stderr," audio=%s",wr->audio[a].name);
audio.fmtid = wr->audio[a].fmtid;
audio_priv = wr->audio[a].priv;
}
+ } else {
if (debug)
- fprintf(stderr,"\n");
+ fprintf(stderr,"no match found\n");
}
}
diff --git a/console/v4l-conf.c b/console/v4l-conf.c
index 9d0139f..a17e416 100644
--- a/console/v4l-conf.c
+++ b/console/v4l-conf.c
@@ -339,7 +339,7 @@ displayinfo_v4l2(int fd, struct DISPLAYINFO *d)
/* set values */
fb.fmt.width = d->width;
fb.fmt.height = d->height;
- switch (d->depth) {
+ switch (d->bpp) {
case 8: fb.fmt.pixelformat = V4L2_PIX_FMT_HI240; break;
#if BYTE_ORDER == BIG_ENDIAN
case 15: fb.fmt.pixelformat = V4L2_PIX_FMT_RGB555X; break;
diff --git a/console/webcam.c b/console/webcam.c
index a4421a1..4baf12a 100644
--- a/console/webcam.c
+++ b/console/webcam.c
@@ -686,7 +686,8 @@ main(int argc, char *argv[])
if (-1 != (i = cfg_get_int("grab","trigger")))
grab_trigger = i;
if (-1 != (i = cfg_get_int("grab","once")))
- grab_times = 1;
+ if (i > 0)
+ grab_times = 1;
if (-1 != (i = cfg_get_int("grab","times")))
grab_times = i;
if (NULL != (val = cfg_get_str("grab","archive")))
diff --git a/contrib/vdr.config b/contrib/vdr.config
new file mode 100644
index 0000000..8d13ec1
--- /dev/null
+++ b/contrib/vdr.config
@@ -0,0 +1,45 @@
+# eventmap config for using xawtv with vdr
+# contributed by Gregoire Favre <greg@ulima.unil.ch>
+
+[eventmap]
+kbd-key-Return = vdr "HITK" "Ok"
+kbd-key-Up = vdr "HITK" "Up"
+kbd-key-Down = vdr "HITK" "Down"
+kbd-key-M = vdr "HITK" "Menu"
+kbd-key-Return = vdr "HITK" "Ok"
+kbd-key-BackSpace = vdr "HITK" "Back"
+kbd-key-Left = vdr "HITK" "Left"
+kbd-key-Right = vdr "HITK" "Right"
+kbd-key-F1 = vdr "HITK" "Red"
+kbd-key-F2 = vdr "HITK" "Green"
+kbd-key-F3 = vdr "HITK" "Yellow"
+kbd-key-F4 = vdr "HITK" "Blue"
+kbd-key-KP_0 = vdr "HITK" "0"
+kbd-key-KP_1 = vdr "HITK" "1"
+kbd-key-KP_2 = vdr "HITK" "2"
+kbd-key-KP_3 = vdr "HITK" "3"
+kbd-key-KP_4 = vdr "HITK" "4"
+kbd-key-KP_5 = vdr "HITK" "5"
+kbd-key-KP_6 = vdr "HITK" "6"
+kbd-key-KP_7 = vdr "HITK" "7"
+kbd-key-KP_8 = vdr "HITK" "8"
+kbd-key-KP_9 = vdr "HITK" "9"
+kbd-key-F5 = vdr "HITK" "Play"
+kbd-key-F6 = vdr "HITK" "Pause"
+kbd-key-F7 = vdr "HITK" "Stop"
+kbd-key-R = vdr "HITK" "Record"
+kbd-key-F12 = vdr "HITK" "FastFwd"
+kbd-key-F11 = vdr "HITK" "FastRew"
+kbd-key-P = vdr "HITK" "Power"
+kbd-key-F9 = vdr "HITK" "Channel+"
+kbd-key-F10 = vdr "HITK" "Channel-"
+kbd-key-KP_Add = vdr "HITK" "Volume+"
+kbd-key-KP_Subtract = vdr "HITK" "Volume-"
+kbd-key-$ = vdr "HITK" "Mute"
+kbd-key-S = vdr "HITK" "Schedule"
+kbd-key-C = vdr "HITK" "Channels"
+kbd-key-T = vdr "HITK" "Timers"
+kbd-key-G = vdr "HITK" "Recordings"
+kbd-key-X = vdr "HITK" "Setup"
+kbd-key-V = vdr "HITK" "Commands"
+kbd-key-N = vdr "HITK" "None"
diff --git a/debian/changelog b/debian/changelog
index 8985ef8..74ecd47 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+xawtv (3.83) unstable; urgency=low
+
+ * new release (closes: #175886, #171884).
+ * added danish template (closes: #175424).
+ * fixed radio description text (closes: #175115).
+ * splitted alsa and quicktime plugins into separate sub-packages.
+
+ -- Gerd Knorr <kraxel@debian.org> Fri, 17 Jan 2003 18:51:34 +0100
+
xawtv (3.82) unstable; urgency=low
* new release (closes: #173791).
diff --git a/debian/control b/debian/control
index 6cea323..f704386 100644
--- a/debian/control
+++ b/debian/control
@@ -9,6 +9,7 @@ Package: xawtv
Section: x11
Architecture: any
Depends: ${shlibs:Depends}, v4l-conf, xutils, debconf, scantv, xawtv-plugins (=${Source-Version}), tv-fonts, pia
+Suggests: xawtv-plugin-qt (=${Source-Version}), xawtv-plugin-alsa (=${Source-Version})
Description: X11 TV application
TV application for X11. Supports video4linux
devices and the Xvideo extension.
@@ -60,7 +61,7 @@ Package: radio
Section: sound
Architecture: any
Depends: ${shlibs:Depends}
-Description: ncurses-bases radio application
+Description: ncurses-based radio application
This is a ncurses-based radio application. It
supports the video4linux API.
@@ -89,6 +90,19 @@ Description: Miscellaneous tools distributed with xawtv
shoot sound problems.
* showriff - display the structure of RIFF files (avi, wav).
+Package: xawtv-plugin-qt
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: quicktime plugin for xawtv and motv
+ this plugin is needed to record quicktime movies with
+ xawtv and motv.
+
+Package: xawtv-plugin-alsa
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: alsa plugin for xawtv and motv
+ this plugin adds alsa mixer support to xawtv and motv.
+
Package: xawtv-plugins
Architecture: any
Depends: ${shlibs:Depends}
diff --git a/debian/xawtv-plugin-alsa.files b/debian/xawtv-plugin-alsa.files
new file mode 100644
index 0000000..d70dde6
--- /dev/null
+++ b/debian/xawtv-plugin-alsa.files
@@ -0,0 +1 @@
+/usr/lib/xawtv/snd-alsa.so
diff --git a/debian/xawtv-plugin-qt.files b/debian/xawtv-plugin-qt.files
new file mode 100644
index 0000000..1bf958d
--- /dev/null
+++ b/debian/xawtv-plugin-qt.files
@@ -0,0 +1 @@
+/usr/lib/xawtv/*qt.so
diff --git a/debian/xawtv.template.da b/debian/xawtv.template.da
new file mode 100644
index 0000000..577ad2c
--- /dev/null
+++ b/debian/xawtv.template.da
@@ -0,0 +1,67 @@
+Template: xawtv/channel-scan
+Type: boolean
+Default: yes
+Description: scan for TV stations?
+ I can do a scan of all channels and put a list of the TV stations I've
+ found into the config file.
+ .
+ This requires a working bttv driver. If bttv isn't configured correctly I
+ might not find the TV stations.
+ .
+ I'll try to pick up the channel names from videotext. This will work with
+ PAL only.
+Description-da: Skan efter TV stationer?
+ Jeg kan lave en skanning efter alle kanaler og putte dem i en liste af de
+ TV stationer jeg har fundet, ind i en konfigurations fil.
+ .
+ Dette kræver en virkende bttv driver. Hvis bttv ikke er korrekt
+ konfigureret, vil du måske ikke finde TV stationerne.
+ .
+ Jeg vil prøve at finde kanal navne fra videotext. Dette vil kun virke med
+ PAL.
+
+Template: xawtv/makedev
+Type: boolean
+Default: true
+Description: Create video4linux (/dev/video*) special files?
+Description-da: Opret video4linux (/dev/video*) specielle filer?
+
+Template: xawtv/tvnorm
+Type: select
+Choices: PAL, SECAM, NTSC
+Choices-da: PAL, SECAM, NTSC
+Description: Which TV norm is used in your country?
+Description-da: Hvilken TV norm er brugt i dit land?
+
+Template: xawtv/freqtab
+Type: select
+Choices: us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, europe-east, italy, newzealand, australia, ireland, france, china-bcast
+Choices-da: us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, europe-east, italy, newzealand, australia, ireland, france, china-bcast
+Description: Which frequency table should be used?
+ A frequency table is just a list of TV channel names/numbers and the
+ corresponding broadcast frequencies for these channels. Different regions
+ use different standards here...
+Description-da: Hvilken frekvens tabel skal bruges?
+ En frekvens tabel er bare en liste af kanal navne/tal og de tilsvarende
+ frekvenser for disse kanaler. Forskellige regioner bruger forskellige
+ standarder her...
+
+Template: xawtv/build-config
+Type: boolean
+Default: false
+Description: Create a default configuration for xawtv?
+ You can create a system-wide configuration file for xawtv with reasonable
+ default values for the country you live in (which TV norm is used for
+ example).
+ .
+ It is not required to have a global configuration file, but it will be
+ more comfortable for your users if they find a working default
+ configuration.
+Description-da: Opret en standard konfigurations fil til xawtv?
+ Du kan oprette en system-bred konfigurations fil til xawtv med fornuftige
+ standard værdier for landet du lever i (f.eks. hvilken TV norm der bliver
+ brugt i dit land).
+ .
+ Det er ikke krævet at have en global konfigurations fil, men det vil gøre
+ det mere behageligt for dine brugere, hvis de finder en standard virkende
+ konfiguration.
diff --git a/debian/xawtv.templates b/debian/xawtv.templates
index e6d0e80..df24fd0 100644
--- a/debian/xawtv.templates
+++ b/debian/xawtv.templates
@@ -1,3 +1,11 @@
+Template: xawtv/makedev
+Type: boolean
+Default: true
+Description: Create video4linux (/dev/video*) special files?
+Description-da: Opret video4linux (/dev/video*) specielle filer?
+Description-de: Sollen Geräte-Dateien (/dev/video*) für video4linux erstellt werden?
+Description-es: ¿Crear los ficheros especiales video4linux (/dev/video*)?
+
Template: xawtv/channel-scan
Type: boolean
Default: yes
@@ -10,6 +18,15 @@ Description: scan for TV stations?
.
I'll try to pick up the channel names from videotext. This will work with
PAL only.
+Description-da: Skan efter TV stationer?
+ Jeg kan lave en skanning efter alle kanaler og putte dem i en liste af de
+ TV stationer jeg har fundet, ind i en konfigurations fil.
+ .
+ Dette kræver en virkende bttv driver. Hvis bttv ikke er korrekt
+ konfigureret, vil du måske ikke finde TV stationerne.
+ .
+ Jeg vil prøve at finde kanal navne fra videotext. Dette vil kun virke med
+ PAL.
Description-de: Soll nach TV-Stationen gesucht werden?
Ich kann einen Suche nach Kanälen durchführen und eine Liste der
gefundenen TV-Stationen in die Konfigurationsdatei schreiben.
@@ -30,36 +47,15 @@ Description-es: ¿Buscar cadenas de televisión?
Trataré de obtener los nombres de los canales del teletexto. Esto sólo
funcionará con PAL.
-Template: xawtv/makedev
-Type: boolean
-Default: true
-Description: Create video4linux (/dev/video*) special files?
-Description-de: Sollen Geräte-Dateien (/dev/video*) für video4linux erstellt werden?
-Description-es: ¿Crear los ficheros especiales video4linux (/dev/video*)?
-
Template: xawtv/tvnorm
Type: select
Choices: PAL, SECAM, NTSC
+Choices-da: PAL, SECAM, NTSC
Description: Which TV norm is used in your country?
+Description-da: Hvilken TV norm er brugt i dit land?
Description-de: Welche TV-Norm benutzt man in ihrem Land?
Description-es: ¿Qué sistema de televisión se usa en su país?
-Template: xawtv/freqtab
-Type: select
-Choices: us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, europe-east, italy, newzealand, australia, ireland, france, china-bcast
-Description: Which frequency table should be used?
- A frequency table is just a list of TV channel names/numbers and the
- corresponding broadcast frequencies for these channels. Different regions
- use different standards here...
-Description-de: Welche Frequenzen-Tabelle soll benutzt werden?
- Eine Frequenzen-Tabelle ist einfach nur eine Liste der TV-Kanäle (Namen
- oder Nummern) mit dazugehörigen Frequenzen. Verschiedene Regionen
- verwenden unterschiedliche Standards.
-Description-es: ¿Que tabla de frecuencias se debería usar?
- Una tabla de frecuencias es sólo una lista de nombres/números de canales
- de televisión y sus correspondientes frecuencias de emisión. Diferentes
- regiones utilizan diferentes estándares para esto...
-
Template: xawtv/build-config
Type: boolean
Default: false
@@ -71,6 +67,14 @@ Description: Create a default configuration for xawtv?
It is not required to have a global configuration file, but it will be
more comfortable for your users if they find a working default
configuration.
+Description-da: Opret en standard konfigurations fil til xawtv?
+ Du kan oprette en system-bred konfigurations fil til xawtv med fornuftige
+ standard værdier for landet du lever i (f.eks. hvilken TV norm der bliver
+ brugt i dit land).
+ .
+ Det er ikke krævet at have en global konfigurations fil, men det vil gøre
+ det mere behageligt for dine brugere, hvis de finder en standard virkende
+ konfiguration.
Description-de: Soll eine Standard-Konfiguration für xawtv erstellt werden?
Sie können für xawtv eine systemweite Konfigurationsdatei erstellen, die
vernünftige Voreinstellungen für ihr Land enthält (z.B. welche TV-Norm
@@ -87,3 +91,24 @@ Description-es: ¿Crear una configuración por defecto para xawtv?
No es obligatorio tener un fichero de configuración global, pero será más
cómodo para sus usuarios encontrarse una configuración por defecto que
funciona.
+
+Template: xawtv/freqtab
+Type: select
+Choices: us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, europe-east, italy, newzealand, australia, ireland, france, china-bcast
+Choices-da: us-bcast, us-cable, us-cable-hrc, japan-bcast, japan-cable, europe-west, europe-east, italy, newzealand, australia, ireland, france, china-bcast
+Description: Which frequency table should be used?
+ A frequency table is just a list of TV channel names/numbers and the
+ corresponding broadcast frequencies for these channels. Different regions
+ use different standards here...
+Description-da: Hvilken frekvens tabel skal bruges?
+ En frekvens tabel er bare en liste af kanal navne/tal og de tilsvarende
+ frekvenser for disse kanaler. Forskellige regioner bruger forskellige
+ standarder her...
+Description-de: Welche Frequenzen-Tabelle soll benutzt werden?
+ Eine Frequenzen-Tabelle ist einfach nur eine Liste der TV-Kanäle (Namen
+ oder Nummern) mit dazugehörigen Frequenzen. Verschiedene Regionen
+ verwenden unterschiedliche Standards.
+Description-es: ¿Que tabla de frecuencias se debería usar?
+ Una tabla de frecuencias es sólo una lista de nombres/números de canales
+ de televisión y sus correspondientes frecuencias de emisión. Diferentes
+ regiones utilizan diferentes estándares para esto...
diff --git a/libng/color_lut.c b/libng/color_lut.c
index b9f857e..ed87e21 100644
--- a/libng/color_lut.c
+++ b/libng/color_lut.c
@@ -27,9 +27,10 @@ unsigned long ng_lut_blue[256];
/* ------------------------------------------------------------------- */
void
-ng_rgb24_to_lut2(unsigned char *dest, unsigned char *src, int p)
+ng_rgb24_to_lut2(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- uint16_t *d = (uint16_t*)dest;
+ uint16_t* restrict d = (uint16_t*)dest;
while (p-- > 0) {
*(d++) = ng_lut_red[src[0]] | ng_lut_green[src[1]] |
@@ -39,9 +40,10 @@ ng_rgb24_to_lut2(unsigned char *dest, unsigned char *src, int p)
}
static void
-bgr24_to_lut2(unsigned char *dest, unsigned char *src, int p)
+bgr24_to_lut2(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- uint16_t *d = (uint16_t*)dest;
+ uint16_t* restrict d = (uint16_t*)dest;
while (p-- > 0) {
*(d++) = ng_lut_red[src[2]] | ng_lut_green[src[1]] |
@@ -51,9 +53,10 @@ bgr24_to_lut2(unsigned char *dest, unsigned char *src, int p)
}
static void
-rgb32_to_lut2(unsigned char *dest, unsigned char *src, int p)
+rgb32_to_lut2(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- uint16_t *d = (uint16_t*)dest;
+ uint16_t* restrict d = (uint16_t*)dest;
while (p-- > 0) {
*(d++) = ng_lut_red[src[1]] | ng_lut_green[src[2]] |
@@ -63,9 +66,10 @@ rgb32_to_lut2(unsigned char *dest, unsigned char *src, int p)
}
static void
-bgr32_to_lut2(unsigned char *dest, unsigned char *src, int p)
+bgr32_to_lut2(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- uint16_t *d = (uint16_t*)dest;
+ uint16_t* restrict d = (uint16_t*)dest;
while (p-- > 0) {
*(d++) = ng_lut_red[src[2]] | ng_lut_green[src[1]] |
@@ -75,9 +79,10 @@ bgr32_to_lut2(unsigned char *dest, unsigned char *src, int p)
}
static void
-gray_to_lut2(unsigned char *dest, unsigned char *src, int p)
+gray_to_lut2(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- uint16_t *d = (uint16_t*)dest;
+ uint16_t* restrict d = (uint16_t*)dest;
while (p-- > 0) {
*(d++) = ng_lut_red[*src] | ng_lut_green[*src] | ng_lut_blue[*src];
@@ -88,9 +93,10 @@ gray_to_lut2(unsigned char *dest, unsigned char *src, int p)
/* ------------------------------------------------------------------- */
void
-ng_rgb24_to_lut4(unsigned char *dest, unsigned char *src, int p)
+ng_rgb24_to_lut4(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- unsigned int *d = (unsigned int*)dest;
+ unsigned int* restrict d = (unsigned int*)dest;
while (p-- > 0) {
*(d++) = ng_lut_red[src[0]] | ng_lut_green[src[1]] |
@@ -100,9 +106,10 @@ ng_rgb24_to_lut4(unsigned char *dest, unsigned char *src, int p)
}
static void
-bgr24_to_lut4(unsigned char *dest, unsigned char *src, int p)
+bgr24_to_lut4(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- unsigned int *d = (unsigned int*)dest;
+ unsigned int* restrict d = (unsigned int*)dest;
while (p-- > 0) {
*(d++) = ng_lut_red[src[2]] | ng_lut_green[src[1]] |
@@ -112,9 +119,10 @@ bgr24_to_lut4(unsigned char *dest, unsigned char *src, int p)
}
static void
-rgb32_to_lut4(unsigned char *dest, unsigned char *src, int p)
+rgb32_to_lut4(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- unsigned int *d = (unsigned int*)dest;
+ unsigned int* restrict d = (unsigned int*)dest;
while (p-- > 0) {
*(d++) = ng_lut_red[src[1]] | ng_lut_green[src[2]] |
@@ -124,9 +132,10 @@ rgb32_to_lut4(unsigned char *dest, unsigned char *src, int p)
}
static void
-bgr32_to_lut4(unsigned char *dest, unsigned char *src, int p)
+bgr32_to_lut4(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- unsigned int *d = (unsigned int*)dest;
+ unsigned int* restrict d = (unsigned int*)dest;
while (p-- > 0) {
*(d++) = ng_lut_red[src[2]] | ng_lut_green[src[1]] |
@@ -136,9 +145,10 @@ bgr32_to_lut4(unsigned char *dest, unsigned char *src, int p)
}
static void
-gray_to_lut4(unsigned char *dest, unsigned char *src, int p)
+gray_to_lut4(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- unsigned int *d = (unsigned int*)dest;
+ unsigned int* restrict d = (unsigned int*)dest;
while (p-- > 0) {
*(d++) = ng_lut_red[*src] | ng_lut_green[*src] | ng_lut_blue[*src];
diff --git a/libng/color_packed.c b/libng/color_packed.c
index faad23b..7c9aae4 100644
--- a/libng/color_packed.c
+++ b/libng/color_packed.c
@@ -36,10 +36,11 @@ redblue_swap(unsigned char *dest, unsigned char *src, int p)
}
static void
-bgr24_to_bgr32(unsigned char *dest, unsigned char *src, int p)
+bgr24_to_bgr32(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- register unsigned char *s = src;
- register unsigned char *d = dest;
+ register unsigned char* restrict s = src;
+ register unsigned char* restrict d = dest;
while (p--) {
*(d++) = *(s++);
@@ -50,10 +51,11 @@ bgr24_to_bgr32(unsigned char *dest, unsigned char *src, int p)
}
static void
-bgr24_to_rgb32(unsigned char *dest, unsigned char *src, int p)
+bgr24_to_rgb32(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- register unsigned char *s = src;
- register unsigned char *d = dest;
+ register unsigned char* restrict s = src;
+ register unsigned char* restrict d = dest;
while (p--) {
*(d++) = 0;
@@ -65,10 +67,11 @@ bgr24_to_rgb32(unsigned char *dest, unsigned char *src, int p)
}
static void
-rgb32_to_rgb24(unsigned char *dest, unsigned char *src, int p)
+rgb32_to_rgb24(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- register unsigned char *s = src;
- register unsigned char *d = dest;
+ register unsigned char* restrict s = src;
+ register unsigned char* restrict d = dest;
while (p--) {
s++;
@@ -79,10 +82,11 @@ rgb32_to_rgb24(unsigned char *dest, unsigned char *src, int p)
}
static void
-rgb32_to_bgr24(unsigned char *dest, unsigned char *src, int p)
+rgb32_to_bgr24(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- register unsigned char *s = src;
- register unsigned char *d = dest;
+ register unsigned char* restrict s = src;
+ register unsigned char* restrict d = dest;
while (p--) {
s++;
@@ -95,10 +99,11 @@ rgb32_to_bgr24(unsigned char *dest, unsigned char *src, int p)
/* 15+16 bpp LE <=> BE */
static void
-byteswap_short(unsigned char *dest, unsigned char *src, int p)
+byteswap_short(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- register unsigned char *s = src;
- register unsigned char *d = dest;
+ register unsigned char* restrict s = src;
+ register unsigned char* restrict d = dest;
while (--p) {
*(d++) = s[1];
@@ -111,15 +116,16 @@ byteswap_short(unsigned char *dest, unsigned char *src, int p)
/* color => grayscale */
static void
-rgb15_native_gray(unsigned char *dest, unsigned char *s, int p)
+rgb15_native_gray(unsigned char* restrict dest, unsigned char *s,
+ int p)
{
- int r,g,b;
- unsigned short *src = (unsigned short*)s;
+ int r,g,b;
+ unsigned short* restrict src = (unsigned short*)s;
while (p--) {
r = (src[0] & 0x7c00) >> 10;
g = (src[0] & 0x03e0) >> 5;
- b = src[1] & 0x001f;
+ b = src[0] & 0x001f;
*(dest++) = ((3*r + 6*g + b)/10) << 3;
src++;
@@ -128,14 +134,16 @@ rgb15_native_gray(unsigned char *dest, unsigned char *s, int p)
#if BYTE_ORDER == LITTLE_ENDIAN
static void
-rgb15_be_gray(unsigned char *dest, unsigned char *src, int p)
+rgb15_be_gray(unsigned char* restrict dest, unsigned char* restrict src,
+ int p)
{
- register unsigned char *d = dest;
+ int r,g,b;
+ register unsigned char* restrict d = dest;
while (p--) {
- unsigned char r = (src[0] & 0x7c) >> 2;
- unsigned char g = (src[0] & 0x03) << 3 | (src[1] & 0xe0) >> 5;
- unsigned char b = src[1] & 0x1f;
+ r = (src[0] & 0x7c) >> 2;
+ g = (src[0] & 0x03) << 3 | (src[1] & 0xe0) >> 5;
+ b = src[1] & 0x1f;
*(d++) = ((3*r + 6*g + b)/10) << 3;
src += 2;
@@ -145,14 +153,15 @@ rgb15_be_gray(unsigned char *dest, unsigned char *src, int p)
#if BYTE_ORDER == BIG_ENDIAN
static void
-rgb15_le_gray(unsigned char *dest, unsigned char *src, int p)
+rgb15_le_gray(unsigned char* restrict dest, unsigned char* restrict src, int p)
{
- register unsigned char *d = dest;
+ int r,g,b;
+ register unsigned char* restrict d = dest;
while (p--) {
- unsigned char r = (src[1] & 0x7c) >> 2;
- unsigned char g = (src[1] & 0x03) << 3 | (src[0] & 0xe0) >> 5;
- unsigned char b = src[0] & 0x1f;
+ r = (src[1] & 0x7c) >> 2;
+ g = (src[1] & 0x03) << 3 | (src[0] & 0xe0) >> 5;
+ b = src[0] & 0x1f;
*(d++) = ((3*r + 6*g + b)/10) << 3;
src += 2;
diff --git a/libng/color_yuv2rgb.c b/libng/color_yuv2rgb.c
index 629643a..66291a3 100644
--- a/libng/color_yuv2rgb.c
+++ b/libng/color_yuv2rgb.c
@@ -61,9 +61,10 @@ static unsigned int ng_clip[256 + 2 * CLIP];
/* packed pixel yuv to gray / rgb */
static void
-yuv422_to_gray(unsigned char *dest, unsigned char *s, int p)
+yuv422_to_gray(unsigned char* restrict dest, unsigned char* restrict s,
+ int p)
{
- unsigned char *d = dest;
+ unsigned char* restrict d = dest;
while (p) {
d[0] = GRAY(s[0]);
@@ -74,9 +75,10 @@ yuv422_to_gray(unsigned char *dest, unsigned char *s, int p)
}
static void
-yuv422_to_rgb24(unsigned char *dest, unsigned char *s, int p)
+yuv422_to_rgb24(unsigned char* restrict dest, unsigned char* restrict s,
+ int p)
{
- unsigned char *d = dest;
+ unsigned char* restrict d = dest;
int gray;
while (p) {
@@ -95,9 +97,10 @@ yuv422_to_rgb24(unsigned char *dest, unsigned char *s, int p)
}
void
-ng_yuv422_to_lut2(unsigned char *dest, unsigned char *s, int p)
+ng_yuv422_to_lut2(unsigned char* restrict dest, unsigned char* restrict s,
+ int p)
{
- unsigned short *d = (unsigned short*)dest;
+ unsigned short* restrict d = (unsigned short*)dest;
int gray;
while (p) {
@@ -117,9 +120,10 @@ ng_yuv422_to_lut2(unsigned char *dest, unsigned char *s, int p)
}
void
-ng_yuv422_to_lut4(unsigned char *dest, unsigned char *s, int p)
+ng_yuv422_to_lut4(unsigned char* restrict dest, unsigned char* restrict s,
+ int p)
{
- unsigned int *d = (unsigned int*)dest;
+ unsigned int* restrict d = (unsigned int*)dest;
int gray;
while (p) {
@@ -144,8 +148,9 @@ ng_yuv422_to_lut4(unsigned char *dest, unsigned char *s, int p)
static void
yuv42xp_to_gray(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
{
- unsigned char *y;
- unsigned char *dp,*d;
+ unsigned char* restrict y;
+ unsigned char* restrict d;
+ unsigned char* dp;
int i,j;
dp = out->data;
@@ -164,9 +169,9 @@ yuv42xp_to_gray(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
static void
yuv420p_to_rgb24(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
{
- unsigned char *y,*u,*v;
+ unsigned char *restrict y, *restrict u, *restrict v, *restrict d;
unsigned char *us,*vs;
- unsigned char *dp,*d;
+ unsigned char *dp;
int i,j,gray;
dp = out->data;
@@ -199,8 +204,8 @@ yuv420p_to_rgb24(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
static void
yuv422p_to_rgb24(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
{
- unsigned char *y,*u,*v;
- unsigned char *dp,*d;
+ unsigned char *restrict y, *restrict u, *restrict v, *restrict d;
+ unsigned char *dp;
int i,j,gray;
dp = out->data;
@@ -229,10 +234,10 @@ yuv422p_to_rgb24(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
void
ng_yuv420p_to_lut2(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
{
- unsigned char *y,*u,*v;
+ unsigned char *restrict y, *restrict u, *restrict v;
unsigned char *us,*vs;
unsigned char *dp;
- unsigned short *d;
+ unsigned short *restrict d;
int i,j,gray;
dp = out->data;
@@ -267,9 +272,9 @@ ng_yuv420p_to_lut2(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
void
ng_yuv422p_to_lut2(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
{
- unsigned char *y,*u,*v;
+ unsigned char *restrict y, *restrict u, *restrict v;
unsigned char *dp;
- unsigned short *d;
+ unsigned short *restrict d;
int i,j,gray;
dp = out->data;
@@ -300,10 +305,10 @@ ng_yuv422p_to_lut2(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
void
ng_yuv420p_to_lut4(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
{
- unsigned char *y,*u,*v;
+ unsigned char *restrict y, *restrict u, *restrict v;
unsigned char *us,*vs;
unsigned char *dp;
- unsigned int *d;
+ unsigned int *restrict d;
int i,j,gray;
dp = out->data;
@@ -338,9 +343,9 @@ ng_yuv420p_to_lut4(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
void
ng_yuv422p_to_lut4(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
{
- unsigned char *y,*u,*v;
+ unsigned char *restrict y, *restrict u, *restrict v;
unsigned char *dp;
- unsigned int *d;
+ unsigned int *restrict d;
int i,j,gray;
dp = out->data;
diff --git a/libng/grab-ng.c b/libng/grab-ng.c
index 6ed2a1e..607085f 100644
--- a/libng/grab-ng.c
+++ b/libng/grab-ng.c
@@ -83,10 +83,10 @@ const char* ng_vfmt_to_desc[] = {
/* --------------------------------------------------------------------- */
const unsigned int ng_afmt_to_channels[] = {
- 0, 1, 2, 1, 2, 1, 2
+ 0, 1, 2, 1, 2, 1, 2, 0
};
const unsigned int ng_afmt_to_bits[] = {
- 0, 8, 8, 16, 16, 16, 16
+ 0, 8, 8, 16, 16, 16, 16, 0
};
const char* ng_afmt_to_desc[] = {
"none",
@@ -95,7 +95,8 @@ const char* ng_afmt_to_desc[] = {
"16bit mono (LE)",
"16bit stereo (LE)",
"16bit mono (BE)",
- "16bit stereo (BE)"
+ "16bit stereo (BE)",
+ "mp3 compressed audio",
};
/* --------------------------------------------------------------------- */
diff --git a/libng/grab-ng.h b/libng/grab-ng.h
index 1fc35cc..3940565 100644
--- a/libng/grab-ng.h
+++ b/libng/grab-ng.h
@@ -22,6 +22,11 @@ extern char ng_v4l_conf[256];
message,__FILE__,__LINE__);\
exit(1);}
+#if __STDC_VERSION__ < 199901
+# define restrict
+#endif
+
+
/* --------------------------------------------------------------------- */
/* defines */
@@ -52,7 +57,8 @@ extern char ng_v4l_conf[256];
#define AUDIO_S16_LE_STEREO 4
#define AUDIO_S16_BE_MONO 5
#define AUDIO_S16_BE_STEREO 6
-#define AUDIO_FMT_COUNT 7
+#define AUDIO_MP3 7
+#define AUDIO_FMT_COUNT 8
#if BYTE_ORDER == BIG_ENDIAN
# define AUDIO_S16_NATIVE_MONO AUDIO_S16_BE_MONO
@@ -355,6 +361,19 @@ struct ng_video_buf* ng_convert_single(struct ng_convert_handle *h,
struct ng_video_buf *in);
/* --------------------------------------------------------------------- */
+/* audio converters */
+
+struct ng_audio_conv {
+ int fmtid_in;
+ int fmtid_out;
+ void* (*init)(void *priv);
+ struct ng_audio_buf* (*frame)(void *handle,
+ struct ng_audio_buf *in);
+ void (*fini)(void *handle);
+ void *priv;
+};
+
+/* --------------------------------------------------------------------- */
/* filters */
struct ng_filter {
diff --git a/libng/plugins/Subdir.mk b/libng/plugins/Subdir.mk
index 3e9943c..30c9fb1 100644
--- a/libng/plugins/Subdir.mk
+++ b/libng/plugins/Subdir.mk
@@ -5,6 +5,7 @@ TARGETS-plugins := \
libng/plugins/flt-invert.so \
libng/plugins/flt-disor.so \
libng/plugins/conv-mjpeg.so \
+ libng/plugins/conv-audio.so \
libng/plugins/read-avi.so \
libng/plugins/write-avi.so
ifeq ($(FOUND_LQT),yes)
@@ -77,17 +78,17 @@ libng/plugins/drv1-v4l.so: \
libng/plugins/struct-v4l.o \
libng/plugins/struct-dump.o
-libng/plugins/struct-dump.o:: structs/struct-dump.c
+libng/plugins/struct-dump.o: structs/struct-dump.c
@$(echo_compile_c)
@$(compile_c)
@$(fixup_deps)
-libng/plugins/struct-v4l.o:: structs/struct-v4l.c
+libng/plugins/struct-v4l.o: structs/struct-v4l.c
@$(echo_compile_c)
@$(compile_c)
@$(fixup_deps)
-libng/plugins/struct-v4l2.o:: structs/struct-v4l2.c
+libng/plugins/struct-v4l2.o: structs/struct-v4l2.c
@$(echo_compile_c)
@$(compile_c)
@$(fixup_deps)
diff --git a/libng/plugins/conv-audio.c b/libng/plugins/conv-audio.c
new file mode 100644
index 0000000..a510423
--- /dev/null
+++ b/libng/plugins/conv-audio.c
@@ -0,0 +1,163 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <dlfcn.h>
+
+#include "grab-ng.h"
+
+/* ---------------------------------------------------------------------- */
+/* stuff we need from lame.h */
+
+struct lame_global_struct;
+typedef struct lame_global_struct lame_global_flags;
+
+static lame_global_flags* (*lame_init)(void);
+static int (*lame_close)(lame_global_flags *);
+
+static int (*lame_set_in_samplerate)(lame_global_flags *, int);
+static int (*lame_set_num_channels)(lame_global_flags *, int);
+static int (*lame_set_quality)(lame_global_flags *, int);
+static int (*lame_init_params)(lame_global_flags * const );
+
+/*
+ * num_samples = number of samples in the L (or R)
+ * channel, not the total number of samples in pcm[]
+ * returns # of output bytes
+ * mp3buffer_size_max = 1.25*num_samples + 7200
+ */
+static int (*lame_encode_buffer_interleaved)(
+ lame_global_flags* gfp, /* global context handlei */
+ short int pcm[], /* PCM data for left and right
+ channel, interleaved */
+ int num_samples, /* number of samples per channel,
+ _not_ number of samples in
+ pcm[] */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ int mp3buf_size ); /* number of valid octets in this
+ stream */
+static int (*lame_encode_flush)(
+ lame_global_flags * gfp, /* global context handle */
+ unsigned char* mp3buf, /* pointer to encoded MP3 stream */
+ int size); /* number of valid octets in this stream */
+
+/* ---------------------------------------------------------------------- */
+/* do dynamic linking */
+
+typedef void (*dlcall)(void);
+#define SYM(symbol) { .func = (dlcall*)(&symbol), .name = #symbol }
+static struct {
+ dlcall *func;
+ char *name;
+} symtab[] = {
+ SYM(lame_init),
+ SYM(lame_close),
+ SYM(lame_set_in_samplerate),
+ SYM(lame_set_num_channels),
+ SYM(lame_set_quality),
+ SYM(lame_init_params),
+ SYM(lame_encode_buffer_interleaved),
+ SYM(lame_encode_flush),
+};
+
+static int link_lame(void)
+{
+ void *handle;
+ void *symbol;
+ int i;
+
+ handle = dlopen("libmp3lame.so.0",RTLD_NOW);
+ if (NULL == handle)
+ return -1;
+ for (i = 0; i < sizeof(symtab)/sizeof(symtab[0]); i++) {
+ symbol = dlsym(handle,symtab[i].name);
+ if (NULL == symbol) {
+ fprintf(stderr,"dlsym(mp3lame,%s): %s\n",
+ symtab[i].name, dlerror());
+ dlclose(handle);
+ return -1;
+ }
+ *(symtab[i].func) = symbol;
+ }
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+struct mp3_enc_state {
+ lame_global_flags *gf;
+ int first;
+};
+
+static void* mp3_enc_init(void *priv)
+{
+ struct mp3_enc_state *h;
+
+ h = malloc(sizeof(*h));
+ if (NULL == h)
+ return NULL;
+ memset(h,0,sizeof(*h));
+ h->gf = lame_init();
+ h->first = 1;
+ return h;
+}
+
+static struct ng_audio_buf*
+mp3_enc_data(void *handle, struct ng_audio_buf *in)
+{
+ static struct ng_audio_fmt fmt = {
+ .fmtid = AUDIO_MP3,
+ .rate = 0,
+ };
+ struct mp3_enc_state *h = handle;
+ struct ng_audio_buf *out;
+ int samples, size;
+
+ if (h->first) {
+ lame_set_in_samplerate(h->gf, in->fmt.rate);
+ lame_set_num_channels(h->gf, ng_afmt_to_channels[in->fmt.fmtid]);
+ lame_set_quality(h->gf, 5 /* FIXME */);
+ lame_init_params(h->gf);
+ h->first = 0;
+ }
+ samples = in->size >> 2;
+ size = 7200 + samples * 5 / 4; /* worst case */
+ out = ng_malloc_audio_buf(&fmt, size);
+
+ out->size = lame_encode_buffer_interleaved
+ (h->gf, (short int*) in->data, samples, out->data, size);
+ return out;
+}
+
+static void mp3_enc_fini(void *handle)
+{
+ struct mp3_enc_state *h = handle;
+
+ lame_close(h->gf);
+ free(h);
+}
+
+static struct ng_audio_conv mp3_list[] = {
+ {
+ /* --- compress --- */
+ init: mp3_enc_init,
+ frame: mp3_enc_data,
+ fini: mp3_enc_fini,
+ fmtid_in: AUDIO_S16_NATIVE_STEREO,
+ fmtid_out: AUDIO_MP3,
+ priv: NULL,
+ }
+};
+static const int nconv = sizeof(mp3_list)/sizeof(mp3_list[0]);
+
+/* ---------------------------------------------------------------------- */
+/* init stuff */
+
+extern void ng_plugin_init(void);
+void ng_plugin_init(void)
+{
+ if (0 != link_lame())
+ return;
+ // ng_aconv_register(NG_PLUGIN_MAGIC,__FILE__,mp3_list,nconv);
+}
diff --git a/libng/plugins/drv0-v4l2.c b/libng/plugins/drv0-v4l2.c
index 6d7b73b..bde242f 100644
--- a/libng/plugins/drv0-v4l2.c
+++ b/libng/plugins/drv0-v4l2.c
@@ -565,6 +565,7 @@ v4l2_tuned(void *handle)
struct v4l2_tuner tuner;
usleep(10000);
+ memset(&tuner,0,sizeof(tuner));
if (-1 == xioctl(h->fd,VIDIOC_G_TUNER,&tuner,0))
return 0;
return tuner.signal ? 1 : 0;
@@ -862,8 +863,11 @@ v4l2_setformat(void *handle, struct ng_video_fmt *fmt)
h->fmt_v4l2.fmt.pix.pixelformat = xawtv_pixelformat[fmt->fmtid];
h->fmt_v4l2.fmt.pix.width = fmt->width;
h->fmt_v4l2.fmt.pix.height = fmt->height;
- h->fmt_v4l2.fmt.pix.bytesperline = fmt->bytesperline;
h->fmt_v4l2.fmt.pix.field = V4L2_FIELD_ANY;
+ if (fmt->bytesperline != fmt->width * ng_vfmt_to_depth[fmt->fmtid]/8)
+ h->fmt_v4l2.fmt.pix.bytesperline = fmt->bytesperline;
+ else
+ h->fmt_v4l2.fmt.pix.bytesperline = 0;
if (-1 == xioctl(h->fd, VIDIOC_S_FMT, &h->fmt_v4l2, EINVAL))
return -1;
diff --git a/libng/plugins/drv1-v4l.c b/libng/plugins/drv1-v4l.c
index 19da489..c41f7ad 100644
--- a/libng/plugins/drv1-v4l.c
+++ b/libng/plugins/drv1-v4l.c
@@ -28,7 +28,7 @@
#include "struct-dump.h"
#include "struct-v4l.h"
-#define SYNC_TIMEOUT 3
+#define SYNC_TIMEOUT 5
/* ---------------------------------------------------------------------- */
diff --git a/libng/plugins/write-dv.c b/libng/plugins/write-dv.c
index fe17e1e..a40e219 100644
--- a/libng/plugins/write-dv.c
+++ b/libng/plugins/write-dv.c
@@ -222,5 +222,5 @@ struct ng_writer dv_writer = {
extern void ng_plugin_init(void);
void ng_plugin_init(void)
{
- ng_writer_register(NG_PLUGIN_MAGIC,__FILE__,&dv_writer);
+ //ng_writer_register(NG_PLUGIN_MAGIC,__FILE__,&dv_writer);
}
diff --git a/man/propwatch.1 b/man/propwatch.1
index 795c5a7..c015a24 100644
--- a/man/propwatch.1
+++ b/man/propwatch.1
@@ -1,8 +1,8 @@
-.TH propwatch 1 "(c) 1998,99 Gerd Knorr"
+.TH propwatch 1 "(c) 1997-2003 Gerd Knorr"
.SH NAME
propwatch - a tool to monitor X11 properties
.SH SYNOPSIS
-.B propwatch [ toolkit-options ] property-name ...
+.B propwatch [ options ] property-name ...
.SH DESCRIPTION
.B propwatch
is a tool to monitor window properties of root and application
@@ -10,24 +10,37 @@ windows. Nice for debugging property-based IPC of X11 programs.
.SH OPTIONS
.B propwatch
uses the Athena Widgets and accepts the usual toolkit options like
--geometry.
+-display and -geometry.
+.P
+Additional options are:
+.TP
+.B -watch display
+Display to monitor the windows on. By default the display specified
+in the DISPLAY environment variable or via -display is used, but it is
+possible to watch another display instead.
+.TP
+.B -verbose
+be verbose.
+.TP
+.B -proplog
+Log property changes to stdout.
+.TP
+.B -kbdlog
+Log keystrokes to stdout.
.P
All remaining command line arguments are assumed to be property names
which should be monitored. If no property names are specified, a
-build in default set will be used.
+build in default (WM_COMMAND) will be used.
.SH ENVIRONMENT
.TP
.B DISPLAY
specifies the display to use for the propwatch window.
-.TP
-.B PROPWATCH
-specifies the display to monitor. It unset, DISPLAY will be used.
.SH SEE ALSO
-xprop(1), xhost(1), xauth(1)
+xprop(1), xhost(1), xauth(1), xwd(1)
.SH AUTHOR
-Gerd Knorr <kraxel@goldbach.in-berlin.de>
+Gerd Knorr <kraxel@bytesex.org>
.SH COPYRIGHT
-Copyright (C) 1997-99 Gerd Knorr
+Copyright (C) 1997-2003 Gerd Knorr
.br
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/man/record.1 b/man/record.1
index e6ec887..643f487 100644
--- a/man/record.1
+++ b/man/record.1
@@ -54,6 +54,10 @@ until stopped by a signal (by typing ^C for example).
Limit the file size (console mode only). record will continue with
a new file once the limit is reached.
.TP
+.B -n num
+Limit the file count (console mode only). record will stop recording
+after num files.
+.TP
.B -l
Enable level triggered recording (console mode only) with the default
trigger level (1000).
diff --git a/man/streamer.1 b/man/streamer.1
index d450cd0..6c3431e 100644
--- a/man/streamer.1
+++ b/man/streamer.1
@@ -12,7 +12,9 @@ formats.
.P
streamer will use the file extention of the output file name to figure
which format to use. You need the -f/-F options only if the extention
-allows more than one format.
+allows more than one format. If you get the "neither audio nor video
+format specified/found" message and don't know why, you can enable the
+debug output (-d switch) to see what is going on.
.P
You can safely stop the recording at any time with Ctrl+C. streamer
will catch the signal and stop recording correctly (i.e. write movie
@@ -22,8 +24,8 @@ file headers) before exiting.
.B streamer -o foobar.jpeg
write a single jpeg file.
.TP
-.B streamer -o quicktime.mov -f yuv2 -F stereo -r 12 -t 120
-record a short quicktime movie (120 frames / 12 fps => 10 seconds).
+.B streamer -o quicktime.mov -f yuv2 -F stereo -r 12 -t 0:10
+record a short quicktime movie.
.SH SEE ALSO
xawtv(1), v4lctl(1)
.SH AUTHOR
diff --git a/man/xawtvrc.5 b/man/xawtvrc.5
index 6411c19..10b1068 100644
--- a/man/xawtvrc.5
+++ b/man/xawtvrc.5
@@ -177,6 +177,13 @@ there are two-digit station numbers starting with that digit.
Enable/disable the onscreen display in fullscreen mode. Default is
on.
.TP
+.B osd-position = x , y
+Position the onscreen display, in pixels. Default is 30,20.
+.TP
+.B use-wm-fullscreen = on | off
+Enter fullscreen mode by asking the window manager to handle that via
+_NET_WM_STATE_FULLSCREEN (if supported by the wm). Default is on.
+.TP
.B ratio = x:y
Set a fixed aspect ratio for the TV image. Default is 4:3. Use 0:0
if you don't want a fixed aspect ratio.
diff --git a/mk/compile.mk b/mk/Compile.mk
index a281e00..75dadde 100644
--- a/mk/compile.mk
+++ b/mk/Compile.mk
@@ -22,25 +22,32 @@ depfiles = mk/*.dep
compile_c = $(CC) $(CFLAGS) -Wp,-MD,$(tmpdep) -c -o $@ $<
compile_cc = $(CXX) $(CXXFLAGS) -Wp,-MD,$(tmpdep) -c -o $@ $<
-fixup_deps = sed -e "s|.*\.o:|$@::|" < $(tmpdep) > $(depfile) && rm -f $(tmpdep)
+fixup_deps = sed -e "s|.*\.o:|$@:|" < $(tmpdep) > $(depfile) && rm -f $(tmpdep)
link_app = $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
link_so = $(CC) $(LDFLAGS) -shared -Wl,-soname,$(@F) -o $@ $^ $(LDLIBS)
ar_lib = rm -f $@ && ar -r $@ $^ && ranlib $@
+moc_h = $(MOC) $< -o $@
+msgfmt_po = msgfmt -o $@ $<
+
# non-verbose output
ifeq ($(verbose),no)
- echo_compile_c = echo " CC " $@
- echo_compile_cc = echo " CXX " $@
- echo_link_app = echo " LD " $@
- echo_link_so = echo " LD " $@
- echo_ar_lib = echo " AR " $@
+ echo_compile_c = echo " CC " $@
+ echo_compile_cc = echo " CXX " $@
+ echo_link_app = echo " LD " $@
+ echo_link_so = echo " LD " $@
+ echo_ar_lib = echo " AR " $@
+ echo_moc_h = echo " MOC " $@
+ echo_msgfmt_po = echo " MSGFMT " $@
else
echo_compile_c = echo $(compile_c)
echo_compile_cc = echo $(compile_cc)
echo_link_app = echo $(link_app)
echo_link_so = echo $(link_so)
echo_ar_lib = echo $(ar_lib)
+ echo_moc_h = echo $(moc_h)
+ echo_msgfmt_po = echo $(msgfmt_po)
endif
%.o: %.c
@@ -66,3 +73,12 @@ endif
%: %.o
@$(echo_link_app)
@$(link_app)
+
+%.moc : %.h
+ @$(echo_moc_h)
+ @$(moc_h)
+
+%.mo : %.po
+ @$(echo_msgfmt_po)
+ @$(msgfmt_po)
+
diff --git a/structs/struct-dump.c b/structs/struct-dump.c
index 602975d..be3e312 100644
--- a/structs/struct-dump.c
+++ b/structs/struct-dump.c
@@ -43,6 +43,7 @@ int print_struct(FILE *fp, struct struct_desc *desc, void *data,
int16_t s16;
uint8_t u8;
int8_t s8;
+ int al = sizeof(long)-1; /* struct + union alignment */
void *p;
int i,j,first;
@@ -50,6 +51,7 @@ int print_struct(FILE *fp, struct struct_desc *desc, void *data,
sprintf(name,"%s%s",prefix,desc[i].name);
if (STRUCT == desc[i].type) {
strcat(name,".");
+ ptr = (void*)(((intptr_t)ptr + al) & ~al);
print_struct(fp,desc[i].desc, ptr, name, tab);
ptr += desc[i].length;
if (!tab && desc[i+1].name != NULL)
@@ -58,6 +60,7 @@ int print_struct(FILE *fp, struct struct_desc *desc, void *data,
}
if (UNION == desc[i].type) {
u32 = *((uint32_t*)(ptr-4));
+ ptr = (void*)(((intptr_t)ptr + al) & ~al);
for (j = 0; desc[i].u[j].name != NULL; j++)
if (desc[i].u[j].value == u32)
break;
diff --git a/todo/tmohan/webcam.c b/todo/tmohan/webcam.c
new file mode 100644
index 0000000..0d1e35e
--- /dev/null
+++ b/todo/tmohan/webcam.c
@@ -0,0 +1,1650 @@
+/*
+ * (c) 1998-2002 Gerd Knorr
+ *
+ * capture a image, compress as jpeg and upload to the webserver
+ * using the ftp utility or ssh
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pthread.h>
+#include <math.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+
+#include "grab-ng.h"
+#include "jpeglib.h"
+#include "ftp.h"
+#include "parseconfig.h"
+#include "list.h"
+
+const char *HTMLSTART = {
+"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
+"<HTML>\n\n"
+"<HEAD>\n"
+"<TITLE>Webcam</TITLE>\n"
+"<META HTTP-EQUIV=\"Refresh\" CONTENT=\"60\">\n"
+"<META HTTP-EQUIV=\"Expires\" CONTENT=\"0\">\n"
+"<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">\n"
+"<META HTTP-EQUIV=\"Cache-Control\" content=\"no-cache\">\n"
+"<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-1\">\n"
+"</HEAD>\n\n" "<BODY BGCOLOR=\"#ffffff\">\n\n"
+};
+const char *HTMLEND = {
+ "\n</BODY>\n\n" "</HTML>\n"
+};
+const char *HTMLIMAGE = {
+ "<IMG VSPACE=5 SRC=\"%%webcam.jpg%%\">\n"
+};
+
+/* ---------------------------------------------------------------------- */
+/* configuration */
+
+int daemonize = 0;
+char *archive = NULL;
+char *tmpdir;
+struct list_head connections;
+struct list_head plugin_list;
+struct plugin_s
+{
+ struct ng_filter *filter;
+ struct list_head list;
+};
+
+char *grab_text = "webcam %Y-%m-%d %H:%M:%S"; /* strftime */
+char *grab_infofile = NULL;
+int grab_width = 320;
+int grab_height = 240;
+int grab_delay = 3;
+int grab_wait = 0;
+int grab_rotate = 0;
+int grab_top = 0;
+int grab_left = 0;
+int grab_bottom = -1;
+int grab_right = -1;
+int grab_quality = 75;
+int grab_trigger = 0;
+char *grab_trigger_area = "0%,0%,100%,100%";
+int grab_trigger_average = 0;
+int grab_trigger_delay = 0;
+int grab_times = -1;
+int grab_fg_r = 255;
+int grab_fg_g = 255;
+int grab_fg_b = 255;
+int grab_bg_r = -1;
+int grab_bg_g = -1;
+int grab_bg_b = -1;
+char *grab_input = NULL;
+char *grab_norm = NULL;
+
+/* ---------------------------------------------------------------------- */
+/* jpeg stuff */
+
+static int
+write_file (int fd, char *data, int width, int height)
+{
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ FILE *fp;
+ int i;
+ unsigned char *line;
+
+ fp = fdopen (fd, "w");
+ cinfo.err = jpeg_std_error (&jerr);
+ jpeg_create_compress (&cinfo);
+ jpeg_stdio_dest (&cinfo, fp);
+ cinfo.image_width = width;
+ cinfo.image_height = height;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ jpeg_set_defaults (&cinfo);
+ jpeg_set_quality (&cinfo, grab_quality, TRUE);
+ jpeg_start_compress (&cinfo, TRUE);
+
+ for (i = 0, line = data; i < height; i++, line += width * 3)
+ jpeg_write_scanlines (&cinfo, &line, 1);
+
+ jpeg_finish_compress (&(cinfo));
+ jpeg_destroy_compress (&(cinfo));
+ fclose (fp);
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+/* image transfer */
+
+struct xfer_ops;
+
+struct xfer_state
+{
+ char *name;
+ struct list_head list;
+
+ /* xfer options */
+ char *host;
+ char *user;
+ char *pass;
+ char *dir;
+ char *file;
+ char *tmpfile;
+ int debug;
+ int keepjpegs;
+ int currentCount;
+ char *htmlfile;
+ char *custom_htmlfile;
+
+ /* ftp options */
+ int passive, autologin;
+
+ /* function pointers + private date */
+ struct xfer_ops *ops;
+ void *data;
+};
+
+struct xfer_ops
+{
+ int (*open) (struct xfer_state *);
+ void (*info) (struct xfer_state *);
+ int (*xfer) (struct xfer_state *, char *image, int width, int height);
+ void (*close) (struct xfer_state *);
+};
+
+static int
+ftp_open (struct xfer_state *s)
+{
+ s->data = ftp_init (s->name, s->autologin, s->passive, s->debug);
+ ftp_connect (s->data, s->host, s->user, s->pass, s->dir);
+ return 0;
+}
+
+static void
+ftp_info (struct xfer_state *s)
+{
+ fprintf (stderr, "ftp config [%s]:\n %s@%s:%s\n %s => %s\n",
+ s->name, s->user, s->host, s->dir, s->tmpfile, s->file);
+}
+
+static int
+ftp_xfer (struct xfer_state *s, char *image, int width, int height)
+{
+ char filename[1024];
+ int fh;
+
+ sprintf (filename, "%s/webcamXXXXXX", tmpdir);
+ if (-1 == (fh = mkstemp (filename)))
+ {
+ perror ("mkstemp");
+ exit (1);
+ }
+ write_file (fh, image, width, height);
+
+ if (!ftp_stillconnected (s->data))
+ ftp_connect (s->data, s->host, s->user, s->pass, s->dir);
+
+ char ftpfilename[1024];
+ strcpy (ftpfilename, s->file);
+
+ if (s->keepjpegs > 1)
+ {
+ //tack a number to the file. ..before the extension
+ char *extpos, *ext = NULL;
+ if ((extpos = strrchr (ftpfilename, '.')))
+ {
+ ext = strdup (extpos);
+ *(extpos) = '\0';
+ }
+
+ sprintf (ftpfilename, "%s%02i", ftpfilename, s->currentCount);
+ if (ext)
+ {
+ strcat (ftpfilename, ext);
+ free (ext);
+ }
+
+ }
+
+ ftp_upload (s->data, filename, ftpfilename, s->tmpfile);
+
+ unlink (filename);
+
+ return 0;
+}
+
+static void
+ftp_close (struct xfer_state *s)
+{
+ ftp_fini (s->data);
+}
+
+static struct xfer_ops ftp_ops = {
+ open:ftp_open,
+ info:ftp_info,
+ xfer:ftp_xfer,
+ close:ftp_close,
+};
+
+static int
+ssh_open (struct xfer_state *s)
+{
+ s->data =
+ malloc (strlen (s->user) + strlen (s->host) + strlen (s->tmpfile) * 2 +
+ strlen (s->dir) + strlen (s->file) + 32);
+ sprintf (s->data, "ssh %s@%s \"cat >%s && mv %s %s/%s\"", s->user, s->host,
+ s->tmpfile, s->tmpfile, s->dir, s->file);
+ return 0;
+}
+
+static void
+ssh_info (struct xfer_state *s)
+{
+ fprintf (stderr, "ssh config [%s]:\n %s@%s:%s\n %s => %s\n",
+ s->name, s->user, s->host, s->dir, s->tmpfile, s->file);
+}
+
+static int
+ssh_xfer (struct xfer_state *s, char *image, int width, int height)
+{
+ char filename[1024];
+ char *cmd = s->data;
+ unsigned char buf[4096];
+ FILE *sshp, *imgdata;
+ int len, fh;
+
+ sprintf (filename, "%s/webcamXXXXXX", tmpdir);
+ if (-1 == (fh = mkstemp (filename)))
+ {
+ perror ("mkstemp");
+ exit (1);
+ }
+ write_file (fh, image, width, height);
+
+ if ((sshp = popen (cmd, "w")) == NULL)
+ {
+ perror ("popen");
+ exit (1);
+ }
+ if ((imgdata = fopen (filename, "rb")) == NULL)
+ {
+ perror ("fopen");
+ exit (1);
+ }
+ for (;;)
+ {
+ len = fread (buf, 1, sizeof (buf), imgdata);
+ if (len <= 0)
+ break;
+ fwrite (buf, 1, len, sshp);
+ }
+ fclose (imgdata);
+ pclose (sshp);
+
+ unlink (filename);
+ return 0;
+}
+
+static void
+ssh_close (struct xfer_state *s)
+{
+ char *cmd = s->data;
+ free (cmd);
+}
+
+static struct xfer_ops ssh_ops = {
+ open:ssh_open,
+ info:ssh_info,
+ xfer:ssh_xfer,
+ close:ssh_close,
+};
+
+static int
+local_open (struct xfer_state *s)
+{
+ char *t;
+
+ if (s->dir != NULL && s->dir[0] != '\0')
+ {
+ t = malloc (strlen (s->tmpfile) + strlen (s->dir) + 2);
+ sprintf (t, "%s/%s", s->dir, s->tmpfile);
+ s->tmpfile = t;
+
+ t = malloc (strlen (s->file) + strlen (s->dir) + 2);
+ sprintf (t, "%s/%s", s->dir, s->file);
+ s->file = t;
+ }
+ return 0;
+}
+
+static void
+local_info (struct xfer_state *s)
+{
+ fprintf (stderr, "write config [%s]:\n local transfer %s => %s\n",
+ s->name, s->tmpfile, s->file);
+}
+
+static int
+local_xfer (struct xfer_state *s, char *image, int width, int height)
+{
+ int fh;
+
+ if (-1 == (fh = open (s->tmpfile, O_CREAT | O_WRONLY | O_TRUNC, 0666)))
+ {
+ fprintf (stderr, "open %s: %s\n", s->tmpfile, strerror (errno));
+ exit (1);
+ }
+ write_file (fh, image, width, height);
+ if (rename (s->tmpfile, s->file))
+ {
+ fprintf (stderr, "can't move %s -> %s\n", s->tmpfile, s->file);
+ exit (1);
+ }
+ return 0;
+}
+
+static void
+local_close (struct xfer_state *s)
+{
+ /* nothing */
+}
+
+static struct xfer_ops local_ops = {
+ open:local_open,
+ info:local_info,
+ xfer:local_xfer,
+ close:local_close,
+};
+
+/* ---------------------------------------------------------------------- */
+/* capture stuff */
+
+static struct ng_video_buf *ng_buf;
+const struct ng_vid_driver *drv;
+void *h_drv;
+struct ng_video_fmt fmt, gfmt;
+struct ng_video_conv *conv;
+struct ng_filter filter;
+void *hconv;
+
+static void
+grab_init (void)
+{
+ struct ng_attribute *attr;
+ int val, i;
+
+ drv = ng_vid_open (ng_dev.video, NULL, NULL, 0, &h_drv);
+ if (NULL == drv)
+ {
+ fprintf (stderr, "no grabber device available\n");
+ exit (1);
+ }
+ if (!(drv->capabilities (h_drv) & CAN_CAPTURE))
+ {
+ fprintf (stderr, "device does'nt support capture\n");
+ exit (1);
+ }
+
+ if (grab_input)
+ {
+ attr = ng_attr_byid (drv->list_attrs (h_drv), ATTR_ID_INPUT);
+ val = ng_attr_getint (attr, grab_input);
+ if (-1 == val)
+ {
+ fprintf (stderr, "invalid input: %s\n", grab_input);
+ exit (1);
+ }
+ attr->write (attr, val);
+ }
+ if (grab_norm)
+ {
+ attr = ng_attr_byid (drv->list_attrs (h_drv), ATTR_ID_NORM);
+ val = ng_attr_getint (attr, grab_norm);
+ if (-1 == val)
+ {
+ fprintf (stderr, "invalid norm: %s\n", grab_norm);
+ exit (1);
+ }
+ attr->write (attr, val);
+ }
+
+ /* try native */
+ fmt.fmtid = VIDEO_RGB24;
+ fmt.width = grab_width;
+ fmt.height = grab_height;
+ if (0 == drv->setformat (h_drv, &fmt))
+ return;
+
+ /* check all available conversion functions */
+ fmt.bytesperline = fmt.width * ng_vfmt_to_depth[fmt.fmtid] / 8;
+ for (i = 0;;)
+ {
+ conv = ng_conv_find_to (fmt.fmtid, &i);
+ if (NULL == conv)
+ break;
+ gfmt = fmt;
+ gfmt.fmtid = conv->fmtid_in;
+ gfmt.bytesperline = 0;
+ if (0 == drv->setformat (h_drv, &gfmt))
+ {
+ fmt.width = gfmt.width;
+ fmt.height = gfmt.height;
+ hconv = conv->init (&fmt, conv->priv);
+ return;
+ }
+ }
+ fprintf (stderr, "can't get rgb24 data\n");
+ exit (1);
+}
+
+static unsigned char *
+grab_one (int *width, int *height, struct ng_video_buf **buf)
+{
+ struct ng_video_buf *ng_cap;
+
+ if (NULL != *buf)
+ ng_release_video_buf (*buf);
+ if (NULL == (ng_cap = drv->getimage (h_drv)))
+ {
+ fprintf (stderr, "capturing image failed\n");
+ exit (1);
+ }
+
+ if (NULL != conv)
+ {
+ *buf = ng_malloc_video_buf (&fmt, 3 * fmt.width * fmt.height);
+ conv->frame (hconv, *buf, ng_cap);
+ (*buf)->info = ng_cap->info;
+ ng_release_video_buf (ng_cap);
+ }
+ else
+ {
+ *buf = ng_cap;
+ }
+
+ *width = (*buf)->fmt.width;
+ *height = (*buf)->fmt.height;
+
+ return (*buf)->data;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define MSG_MAXLEN 256
+
+#define CHAR_HEIGHT 11
+#define CHAR_WIDTH 6
+#define CHAR_START 4
+#include "font-6x11.h"
+
+static char *
+get_message (void)
+{
+ static char buffer[MSG_MAXLEN + 1];
+ FILE *fp;
+ char *p;
+
+ if (NULL == grab_infofile)
+ return grab_text;
+
+ if (NULL == (fp = fopen (grab_infofile, "r")))
+ {
+ fprintf (stderr, "open %s: %s\n", grab_infofile, strerror (errno));
+ return grab_text;
+ }
+
+ fgets (buffer, MSG_MAXLEN, fp);
+ fclose (fp);
+ if (NULL != (p = strchr (buffer, '\n')))
+ *p = '\0';
+
+ return buffer;
+}
+
+static void
+add_text (char *image, int width, int height)
+{
+ time_t t;
+ struct tm *tm;
+ char line[MSG_MAXLEN + 1], *ptr;
+ int i, x, y, f, len;
+
+ time (&t);
+ tm = localtime (&t);
+ len = strftime (line, MSG_MAXLEN, get_message (), tm);
+ fprintf (stderr, "%s\n", line);
+
+ for (y = 0; y < CHAR_HEIGHT; y++)
+ {
+ ptr = image + 3 * width * (height - CHAR_HEIGHT - 2 + y) + 12;
+ for (x = 0; x < len; x++)
+ {
+ f = fontdata[line[x] * CHAR_HEIGHT + y];
+ for (i = CHAR_WIDTH - 1; i >= 0; i--)
+ {
+ if (f & (CHAR_START << i))
+ {
+ ptr[0] = grab_fg_r;
+ ptr[1] = grab_fg_g;
+ ptr[2] = grab_fg_b;
+ }
+ else if (grab_bg_r != -1)
+ {
+ ptr[0] = grab_bg_r;
+ ptr[1] = grab_bg_g;
+ ptr[2] = grab_bg_b;
+ }
+ ptr += 3;
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+/* Frederic Helin <Frederic.Helin@inrialpes.fr> - 15/07/2002 */
+/* Correction fonction of stereographic radial distortion */
+
+int grab_dist_on = 0;
+int grab_dist_k = 700;
+int grab_dist_cx = -1;
+int grab_dist_cy = -1;
+int grab_dist_zoom = 50;
+int grab_dist_sensorw = 640;
+int grab_dist_sensorh = 480;
+
+static unsigned char *
+correct_distor (unsigned char *in, int width, int height,
+ int grab_zoom, int grap_k, int cx, int cy,
+ int grab_sensorw, int grab_sensorh)
+{
+ static unsigned char *corrimg = NULL;
+
+ int i, j, di, dj;
+ float dr, cr, ca, sensor_w, sensor_h, sx, zoom, k;
+
+ sensor_w = grab_dist_sensorw / 100.0;
+ sensor_h = grab_dist_sensorh / 100.0;
+ zoom = grab_zoom / 100.0;
+ k = grap_k / 100.0;
+
+ if (corrimg == NULL && (corrimg = malloc (width * height * 3)) == NULL)
+ {
+ fprintf (stderr, "out of memory\n");
+ exit (1);
+ }
+
+ sensor_w = 6.4;
+ sensor_h = 4.8;
+
+ // calc ratio x/y
+ sx = width * sensor_h / (height * sensor_w);
+
+ // calc new value of k in the coordonates systeme of computer
+ k = k * height / sensor_h;
+
+ // Clear image
+ for (i = 0; i < height * width * 3; i++)
+ corrimg[i] = 255;
+
+ for (j = 0; j < height; j++)
+ {
+ for (i = 0; i < width; i++)
+ {
+
+ // compute radial distortion / parameters of center of image
+ cr = sqrt ((i - cx) / sx * (i - cx) / sx + (j - cy) * (j - cy));
+ ca = atan (cr / k / zoom);
+ dr = k * tan (ca / 2);
+
+ if (i == cx && j == cy)
+ {
+ di = cx;
+ dj = cy;
+ }
+ else
+ {
+ di = (i - cx) * dr / cr + cx;
+ dj = (j - cy) * dr / cr + cy;
+ }
+
+ if (dj < height && di < width && di >= 0 && dj >= 0 &&
+ j < height && i < width && i >= 0 && j >= 0)
+ {
+ corrimg[3 * (j * width + i)] = in[3 * (dj * width + di)];
+ corrimg[3 * (j * width + i) + 1] = in[3 * (dj * width + di) + 1];
+ corrimg[3 * (j * width + i) + 2] = in[3 * (dj * width + di) + 2];
+ }
+ }
+ }
+ return corrimg;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*static unsigned int
+compare_images(unsigned char *last, unsigned char *current,
+ int width, int height)
+{
+ unsigned char *p1 = last;
+ unsigned char *p2 = current;
+ int avg, diff, max, i = width*height*3;
+
+ for (max = 0, avg = 0; --i; p1++,p2++)
+ {
+ //diff = (*p1 < *p2) ? (*p2 - *p1) : (*p1 - *p2);
+ diff = abs(*p1 - *p2);
+ avg += diff;
+ if (diff > max)
+ max = diff;
+ }
+
+ avg = avg / width / height;
+ fprintf(stderr,"compare: max=%d,avg=%d\n",max,avg);
+
+ // return max
+ return max;
+}*/
+
+static unsigned int
+compare_images (unsigned char *last, unsigned char *current,
+ int offsetx, int offsety, int iwidth, int iheight,
+ int imagewidth)
+{
+ unsigned char *p1 = last;
+ unsigned char *p2 = current;
+ unsigned int p;
+ int x, y, diff, max = 0;
+ unsigned int avg = 0;
+
+ offsety *= 3;
+ offsetx *= 3;
+ iheight *= 3;
+ iwidth *= 3;
+
+ for (y = offsety; y < offsety + iheight; y += 3)
+ {
+ p = imagewidth * y;
+
+ for (x = offsetx; x < offsetx + iwidth; x++)
+ {
+ p1 = last + p + x;
+ p2 = current + p + x;
+
+ diff = abs (*p1 - *p2);
+ avg += diff;
+ if (diff > max)
+ max = diff;
+ }
+ }
+
+ avg = 3 * avg / iwidth / iheight;
+ fprintf (stderr, "compare: max=%d,avg=%d\n", max, avg);
+
+ // return max and average
+ return (max << 8) | avg;
+}
+
+/*int max2 = 0;
+static unsigned int
+compare_images(unsigned char *saved, unsigned char *last, unsigned char *current, int width, int height)
+{
+ unsigned char *p1 = last;
+ unsigned char *p2 = current;
+ unsigned char *p3 = saved;
+ int avg, diff, max, i = width*height*3;
+ int avg2, diff2;
+
+ for (max = 0, avg = 0, max2=0,avg2=0; --i; p1++,p2++,p3++)
+ {
+ diff = abs(*p1 - *p2);
+ avg += diff;
+ if (diff > max)
+ max = diff;
+
+ diff2 = abs(*p3 - *p2);
+ avg2 += diff2;
+ if (diff2 > max2)
+ max2 = diff2;
+
+ }
+
+ avg = avg / width / height;
+ avg2 = avg2 / width / height;
+ fprintf(stderr,"compare: max=%d,%d,avg=%d,%d\n",max,max2,avg,avg2);
+
+
+ return max;
+}*/
+
+static unsigned char *
+rotate_image (unsigned char *in, int *wp, int *hp, int rot,
+ int top, int left, int bottom, int right)
+{
+ static unsigned char *rotimg = NULL;
+
+ int i, j;
+
+ int w = *wp;
+ int ow = (right - left);
+ int oh = (bottom - top);
+
+ if (rotimg == NULL && (rotimg = malloc (ow * oh * 3)) == NULL)
+ {
+ fprintf (stderr, "out of memory\n");
+ exit (1);
+ }
+
+ switch (rot)
+ {
+ default:
+ case 0:
+ for (j = 0; j < oh; j++)
+ {
+ int ir = (j + top) * w + left;
+ int or = j * ow;
+ for (i = 0; i < ow; i++)
+ {
+ rotimg[3 * (or + i)] = in[3 * (ir + i)];
+ rotimg[3 * (or + i) + 1] = in[3 * (ir + i) + 1];
+ rotimg[3 * (or + i) + 2] = in[3 * (ir + i) + 2];
+ }
+ }
+ *wp = ow;
+ *hp = oh;
+ break;
+ case 1:
+ for (i = 0; i < ow; i++)
+ {
+ int rr = (ow - 1 - i) * oh;
+ int ic = i + left;
+ for (j = 0; j < oh; j++)
+ {
+ rotimg[3 * (rr + j)] = in[3 * ((j + top) * w + ic)];
+ rotimg[3 * (rr + j) + 1] = in[3 * ((j + top) * w + ic) + 1];
+ rotimg[3 * (rr + j) + 2] = in[3 * ((j + top) * w + ic) + 2];
+ }
+ }
+ *wp = oh;
+ *hp = ow;
+ break;
+ case 2:
+ for (j = 0; j < oh; j++)
+ {
+ int ir = (j + top) * w;
+ for (i = 0; i < ow; i++)
+ {
+ rotimg[3 * ((oh - 1 - j) * ow + (ow - 1 - i))] =
+ in[3 * (ir + i + left)];
+ rotimg[3 * ((oh - 1 - j) * ow + (ow - 1 - i)) + 1] =
+ in[3 * (ir + i + left) + 1];
+ rotimg[3 * ((oh - 1 - j) * ow + (ow - 1 - i)) + 2] =
+ in[3 * (ir + i + left) + 2];
+ }
+ }
+ *wp = ow;
+ *hp = oh;
+ break;
+ case 3:
+ for (i = 0; i < ow; i++)
+ {
+ int rr = i * oh;
+ int ic = i + left;
+ rr += oh - 1;
+ for (j = 0; j < oh; j++)
+ {
+ rotimg[3 * (rr - j)] = in[3 * ((j + top) * w + ic)];
+ rotimg[3 * (rr - j) + 1] = in[3 * ((j + top) * w + ic) + 1];
+ rotimg[3 * (rr - j) + 2] = in[3 * ((j + top) * w + ic) + 2];
+ }
+ }
+ *wp = oh;
+ *hp = ow;
+ break;
+ }
+
+ return rotimg;
+}
+
+//-----------------------------------------------------
+// T.Mohan - 28 July 2002
+// # strnsub() is based on source by Erik Bachmann and
+// # was released to public domain on 27 Oct 1995.
+//-----------------------------------------------------
+
+static char *
+strnsub (char *pszString, char *pszPattern, char *pszReplacement,
+ int iMaxLength, int bOnce)
+{
+ char *pszSubstring, *pszTmpSubstring, *pszlast, *pszTempReplacement;
+ int iPatternLength, iReplacementLength;
+
+ pszSubstring = pszString;
+ pszTmpSubstring = NULL;
+ iPatternLength = strlen (pszPattern);
+ pszlast = NULL;
+
+ if (!strcmp (pszPattern, pszReplacement))
+ return NULL; // Pattern == replacement: loop
+
+ while ((pszSubstring = strstr (pszSubstring, pszPattern)))
+ {
+ iReplacementLength = strlen (pszReplacement);
+ pszTempReplacement = pszReplacement;
+
+ if ((strlen (pszString) + (iReplacementLength - iPatternLength)) >
+ iMaxLength)
+ break; // Not enough space for replacement
+
+ if (pszTmpSubstring == NULL) //allocate some memory only once
+ {
+ if ((pszTmpSubstring =
+ (char *) calloc (iMaxLength, sizeof (char))) == NULL)
+ return NULL; // oops, not enough memory?
+ }
+
+ strcpy (pszTmpSubstring, pszSubstring + iPatternLength);
+
+ while (iReplacementLength--)
+ { // Copy replacement
+ *pszSubstring++ = *pszTempReplacement++;
+ }
+
+ strcpy (pszSubstring, pszTmpSubstring);
+
+ pszlast = pszSubstring - iPatternLength;
+
+ if (bOnce)
+ break; //just change one
+
+ }
+
+ if (pszTmpSubstring)
+ free (pszTmpSubstring);
+
+ return pszlast;
+
+}
+
+//-----------------------------------------------------
+// T.Mohan - 28 July 2002
+//-----------------------------------------------------
+static int
+ftp_upload_htmlfile (struct xfer_state *s)
+{
+
+#define MAXLINELEN 1024
+
+ FILE *filecustom, *filewrite;
+ int filetemp;
+ char line[MAXLINELEN];
+ char tmpfname[1024];
+ char jpegnumbered[1024], jpegfilename[1024];
+ char pattern[20], pattern_newest[20];
+ char *pszFound;
+
+ strcpy (pattern, "%%webcam.jpg%%"); //replace with numbered .jpg's
+ strcpy (pattern_newest, "%%newest.jpg%%"); //replace with newest .jpg
+ pszFound = NULL;
+ filecustom = filewrite = NULL;
+
+ //open the custom html file if requested
+ if (s->custom_htmlfile)
+ {
+ if ((filecustom = fopen (s->custom_htmlfile, "r")) == NULL)
+ {
+ perror (s->htmlfile);
+ return 1;
+ }
+ }
+
+ //create a temporary file
+ sprintf (tmpfname, "%s/webcamhtmlXXXXXX", tmpdir);
+
+ if (-1 == (filetemp = mkstemp (tmpfname)))
+ {
+ perror ("mkstemp create");
+ fclose (filecustom);
+ return 1;
+ }
+
+ if ((filewrite = fdopen (filetemp, "w")) == NULL)
+ {
+ perror ("htmlfile open for write");
+ fclose (filecustom);
+ unlink (tmpfname);
+ return 1;
+ }
+
+ if (s->keepjpegs > 1) //format the filename
+ {
+ strcpy (jpegfilename, s->file);
+ char *extpos, *ext = NULL;
+
+ if ((extpos = strrchr (jpegfilename, '.')))
+ {
+ ext = strdup (extpos);
+ *(extpos) = '\0';
+ }
+
+ //end up with something like 'webcam%02i.jpg'
+ sprintf (jpegfilename, "%s%%02i", jpegfilename);
+
+ if (ext) //tack on the extension if there is one
+ {
+ strcat (jpegfilename, ext);
+ free (ext);
+ }
+ }
+ else
+ {
+ strcpy (jpegnumbered, s->file);
+ }
+
+ //find pattern and replace with approriate filename in custom html file
+ int count = s->currentCount;
+ if (filecustom)
+ {
+ int actualcount = 0;
+
+ while (fgets (line, sizeof (line), filecustom) != NULL)
+ {
+ if (s->keepjpegs > 1)
+ sprintf (jpegnumbered, jpegfilename, count);
+
+ //replace patterns in entire line with the numbered jpeg
+ if (strnsub (line, pattern, jpegnumbered, MAXLINELEN, FALSE))
+ {
+ if (--count < 1)
+ count = s->keepjpegs;
+
+ actualcount++;
+ }
+
+ //replace tag for %%newest.jpg%%
+ if (s->keepjpegs > 1)
+ sprintf (jpegnumbered, jpegfilename, s->currentCount);
+
+ strnsub (line, pattern_newest, jpegnumbered, MAXLINELEN, FALSE);
+
+ //write line
+ fputs (line, filewrite);
+ }
+
+ if ((s->keepjpegs > 1) && (actualcount != s->keepjpegs))
+ fprintf (stderr,
+ "\n*** Warning: Found %i patterns, but keepjpegs = %i\n\n",
+ actualcount, s->keepjpegs);
+ }
+ else
+ {
+ fputs (HTMLSTART, filewrite);
+
+ int i = s->keepjpegs;
+ while (i--)
+ {
+ strcpy (line, HTMLIMAGE);
+
+ if (s->keepjpegs > 1)
+ sprintf (jpegnumbered, jpegfilename, count);
+
+ if (strnsub (line, pattern, jpegnumbered, MAXLINELEN, TRUE))
+ {
+ if (--count < 1)
+ count = s->keepjpegs;
+ }
+
+ //replace tag for %%newest.jpg%%
+ //sprintf(jpegnumbered,jpegfilename,s->currentCount);
+ //strnsub(line, pattern_newest, jpegnumbered, MAXLINELEN, FALSE);
+
+ fputs (line, filewrite);
+ }
+
+ fputs (HTMLEND, filewrite);
+ }
+
+ if (filecustom)
+ fclose (filecustom);
+ if (filewrite)
+ fclose (filewrite);
+
+ //upload the html file
+ sprintf (jpegfilename, "%s%s", s->tmpfile, ".html");
+ fprintf (stderr, "%s,%s,%s\n", tmpfname, s->htmlfile, jpegfilename);
+ ftp_upload (s->data, tmpfname, s->htmlfile, jpegfilename);
+
+ unlink (tmpfname);
+
+ return 0;
+}
+
+static void
+parse_trigger_area (char *pszTriggerArea, int *ixoffset, int *iyoffset,
+ int *width, int *height)
+{
+ if (!ixoffset || !iyoffset || !width || !height)
+ return;
+ if (!pszTriggerArea)
+ pszTriggerArea = "0%,0%,100%,100%";
+
+ char *str, *perc, *tmpStr;
+ int count = -1, ta[4], err = 0;
+
+ tmpStr = strdup (pszTriggerArea);
+ str = strtok (tmpStr, ",");
+
+ while (str && (++count < 4))
+ {
+ if ((perc = strstr (str, "%")))
+ *perc = '\0';
+
+ if (perc)
+ ta[count] = atoi (str) * ((count % 2) ? *height : *width) / 100;
+ else
+ ta[count] = atoi (str);
+
+ str = strtok (NULL, ",");
+ }
+
+ free (tmpStr);
+
+ //some foolproofing...
+ if ((ta[0] < 0) || (ta[0] > *width))
+ {
+ ta[0] = 0;
+ err = 1;
+ }
+ if ((ta[1] < 0) || (ta[1] > *height))
+ {
+ ta[1] = 0;
+ err = 1;
+ }
+ if ((ta[2] < 0) || (ta[2] > *width))
+ {
+ ta[2] = *width;
+ err = 1;
+ }
+ if ((ta[3] < 0) || (ta[3] > *height))
+ {
+ ta[3] = *height;
+ err = 1;
+ }
+ if (ta[0] >= ta[2])
+ {
+ ta[2] = *width;
+ err = 1;
+ }
+ if (ta[1] >= ta[3])
+ {
+ ta[3] = *height;
+ err = 1;
+ }
+ if (ta[2] <= ta[0])
+ {
+ ta[0] = 0;
+ err = 1;
+ }
+ if (ta[3] <= ta[1])
+ {
+ ta[1] = 0;
+ err = 1;
+ }
+
+ if (err)
+ fprintf (stderr, "\n*** Invalid trigger area was fixed.\n\n");
+
+ *ixoffset = ta[0];
+ *iyoffset = ta[1];
+ *width = ta[2] - ta[0];
+ *height = ta[3] - ta[1];
+}
+
+static void
+draw_trigger_area (unsigned char *image, int offsetx, int offsety,
+ int iTriggerwidth, int iTriggerheight, int iImageWidth)
+{
+ unsigned char *p;
+ int x, y;
+
+ offsety *= 3;
+ offsetx *= 3;
+ iTriggerheight *= 3;
+ iTriggerwidth *= 3;
+
+ for (y = offsety; y < offsety + iTriggerheight; y += 3)
+ {
+ p = image + iImageWidth * y;
+
+ for (x = offsetx; x < offsetx + iTriggerwidth; x++)
+ {
+ //trigger area is drawn inverted
+ *(p + x) = 255 - *(p + x);
+ }
+ }
+
+}
+
+static char *
+trim (char *p)
+{
+ while ((*p == ' '))
+ p++;
+ while ((p[strlen (p) - 1]) == ' ')
+ p[strlen (p) - 1] = '\0';
+
+ return p;
+}
+
+static struct ng_filter *
+get_plugin (char *name)
+{
+ int i;
+
+ for (i = 0; NULL != ng_filters[i]; i++)
+ if (!strcmp (ng_filters[i]->name, name))
+ return ng_filters[i];
+
+ return NULL;
+}
+
+static void
+parse_plugins (void)
+{
+ char *name, *attributes, *str;
+ int count = 0;
+ struct ng_filter *plugin;
+ struct plugin_s *currfilter = NULL;
+
+ INIT_LIST_HEAD (&plugin_list);
+
+ if ((str = cfg_get_str ("plugins", "names")) == NULL)
+ return;
+
+ while ((name = strtok (str, ",")))
+ {
+ str = NULL;
+
+ //remove asterix for spaces
+ strnsub (name, "*", " ", strlen (name), FALSE);
+ name = trim (name);
+
+ //plugin actually exists?
+ if ((plugin = get_plugin (name)) == NULL)
+ {
+ fprintf (stderr, "plugin: [%s] not found.\n", name);
+ continue;
+ }
+
+ currfilter = malloc (sizeof (*currfilter));
+ memset (currfilter, 0, sizeof (*currfilter));
+ currfilter->filter = plugin;
+ list_add_tail (&currfilter->list, &plugin_list);
+
+ fprintf (stderr, "plugin: [%s] found.\n", name);
+
+ count++;
+ }
+
+ //parse the attributes
+ struct list_head *item;
+ name = NULL;
+ list_for_each (item, &plugin_list)
+ {
+ struct plugin_s *currfilter = NULL;
+
+ currfilter = list_entry (item, struct plugin_s, list);
+
+ if (name)
+ free (name);
+ name = strdup (currfilter->filter->name);
+ //replace spaces in the name with asterix
+ strnsub (name, " ", "*", strlen (name), FALSE);
+ attributes = cfg_get_str ("plugins", name);
+ //remove asterix for spaces
+ strnsub (name, "*", " ", strlen (name), FALSE);
+
+ //parse the attributes
+ if (!attributes)
+ {
+ if (currfilter->filter->attrs)
+ fprintf (stderr, "plugin: [%s] Using default attributes.\n", name);
+ continue;
+ }
+
+ char *attr = attributes;
+ char attrname[64], attrvalue[192];
+ struct ng_attribute *nga = NULL;
+ while ((attributes = strtok (attr, ",")))
+ {
+ attr = NULL;
+ if (sscanf (attributes, " %63[^=] = %191[^\n]", attrname, attrvalue) !=
+ 2)
+ fprintf (stderr, "plugin: [%s] Parse error for attribute %s\n", name,
+ attrname);
+
+ trim (attrname);
+
+ if (currfilter->filter->attrs == NULL)
+ {
+ fprintf (stderr, "plugin: [%s] has no attributes to set.\n", name);
+ break;
+ }
+
+ if (!(nga = ng_attr_byname (currfilter->filter->attrs, attrname)))
+ {
+ fprintf (stderr, "plugin: [%s] Unkown attribute: %s\n", name,
+ attrname);
+ }
+ else
+ {
+ nga->write (nga, atoi (attrvalue));
+ fprintf (stderr, "plugin: [%s] Wrote attribute: %s, value: %s\n",
+ name, attrname, attrvalue);
+ }
+
+ }
+
+ }
+
+ if (name)
+ free (name);
+
+ if (count)
+ fprintf (stderr, "plugin: Using %d plugin%s.\n", count,
+ (count == 1) ? "" : "s");
+
+
+}
+
+/* ---------------------------------------------------------------------- */
+
+int
+main (int argc, char *argv[])
+{
+ unsigned char *image, *val, *gimg, *lastimg = NULL;
+ int width, height, i, fh;
+ char filename[1024];
+ char **sections;
+ struct list_head *item;
+ struct xfer_state *s = NULL;
+ int iTrigX, iTrigY, iTrigWidth, iTrigHeight;
+ struct plugin_s *currfilter;
+
+ /* read config */
+ if (argc > 1)
+ {
+ strcpy (filename, argv[1]);
+ }
+ else
+ {
+ sprintf (filename, "%s/%s", getenv ("HOME"), ".webcamrc");
+ }
+
+ fprintf (stderr, "reading config file: %s\n", filename);
+ cfg_parse_file (filename);
+ ng_init ();
+
+ //setup the plugins
+ parse_plugins ();
+
+ if (NULL != (val = cfg_get_str ("grab", "device")))
+ ng_dev.video = val;
+ if (NULL != (val = cfg_get_str ("grab", "text")))
+ grab_text = val;
+ if (NULL != (val = cfg_get_str ("grab", "infofile")))
+ grab_infofile = val;
+ if (NULL != (val = cfg_get_str ("grab", "input")))
+ grab_input = val;
+ if (NULL != (val = cfg_get_str ("grab", "norm")))
+ grab_norm = val;
+ if (-1 != (i = cfg_get_int ("grab", "width")))
+ grab_width = i;
+ if (-1 != (i = cfg_get_int ("grab", "height")))
+ grab_height = i;
+ if (-1 != (i = cfg_get_int ("grab", "delay")))
+ grab_delay = i;
+ if (-1 != (i = cfg_get_int ("grab", "wait")))
+ grab_wait = i;
+ if (-1 != (i = cfg_get_int ("grab", "rotate")))
+ grab_rotate = i;
+ if (-1 != (i = cfg_get_int ("grab", "top")))
+ grab_top = i;
+ if (-1 != (i = cfg_get_int ("grab", "left")))
+ grab_left = i;
+ grab_bottom = cfg_get_int ("grab", "bottom");
+ grab_right = cfg_get_int ("grab", "right");
+ if (-1 != (i = cfg_get_int ("grab", "quality")))
+ grab_quality = i;
+ if (-1 != (i = cfg_get_int ("grab", "trigger")))
+ grab_trigger = i;
+ if (NULL != (val = cfg_get_str ("grab", "trigger_area")))
+ grab_trigger_area = val;
+ if (-1 != (i = cfg_get_int ("grab", "trigger_average")))
+ grab_trigger_average = i;
+ if (-1 != (i = cfg_get_int ("grab", "trigger_delay")))
+ grab_trigger_delay = i;
+ if (-1 != (i = cfg_get_int ("grab", "once")))
+ if (i)
+ grab_times = 1;
+ if (-1 != (i = cfg_get_int ("grab", "times")))
+ grab_times = i;
+ if (NULL != (val = cfg_get_str ("grab", "archive")))
+ archive = val;
+
+ if (-1 != (i = cfg_get_int ("grab", "fg_red")))
+ if (i >= 0 && i <= 255)
+ grab_fg_r = i;
+ if (-1 != (i = cfg_get_int ("grab", "fg_green")))
+ if (i >= 0 && i <= 255)
+ grab_fg_g = i;
+ if (-1 != (i = cfg_get_int ("grab", "fg_blue")))
+ if (i >= 0 && i <= 255)
+ grab_fg_b = i;
+ if (-1 != (i = cfg_get_int ("grab", "bg_red")))
+ if (i >= 0 && i <= 255)
+ grab_bg_r = i;
+ if (-1 != (i = cfg_get_int ("grab", "bg_green")))
+ if (i >= 0 && i <= 255)
+ grab_bg_g = i;
+ if (-1 != (i = cfg_get_int ("grab", "bg_blue")))
+ if (i >= 0 && i <= 255)
+ grab_bg_b = i;
+
+ if (-1 != (i = cfg_get_int ("grab", "distor")))
+ grab_dist_on = i;
+ if (-1 != (i = cfg_get_int ("grab", "distor_k")))
+ grab_dist_k = i;
+ if (-1 != (i = cfg_get_int ("grab", "distor_cx")))
+ grab_dist_cx = i;
+ if (-1 != (i = cfg_get_int ("grab", "distor_cy")))
+ grab_dist_cy = i;
+ if (-1 != (i = cfg_get_int ("grab", "distor_zoom")))
+ grab_dist_zoom = i;
+ if (-1 != (i = cfg_get_int ("grab", "distor_sensorw")))
+ grab_dist_sensorw = i;
+ if (-1 != (i = cfg_get_int ("grab", "distor_sensorh")))
+ grab_dist_sensorh = i;
+
+ if (grab_top < 0)
+ grab_top = 0;
+ if (grab_left < 0)
+ grab_left = 0;
+ if (grab_bottom > grab_height)
+ grab_bottom = grab_height;
+ if (grab_right > grab_width)
+ grab_right = grab_width;
+ if (grab_bottom < 0)
+ grab_bottom = grab_height;
+ if (grab_right < 0)
+ grab_right = grab_width;
+ if (grab_top >= grab_bottom)
+ grab_top = 0;
+ if (grab_left >= grab_right)
+ grab_left = 0;
+
+ if (grab_dist_k < 1 || grab_dist_k > 10000)
+ grab_dist_k = 700;
+ if (grab_dist_cx < 0 || grab_dist_cx > grab_width)
+ grab_dist_cx = grab_width / 2;
+ if (grab_dist_cy < 0 || grab_dist_cy > grab_height)
+ grab_dist_cy = grab_height / 2;
+ if (grab_dist_zoom < 1 || grab_dist_zoom > 1000)
+ grab_dist_zoom = 100;
+ if (grab_dist_sensorw < 1 || grab_dist_sensorw > 9999)
+ grab_dist_sensorw = 640;
+ if (grab_dist_sensorh < 1 || grab_dist_sensorh > 9999)
+ grab_dist_sensorh = 480;
+
+ INIT_LIST_HEAD (&connections);
+ for (sections = cfg_list_sections (); *sections != NULL; sections++)
+ {
+ if ((0 == strcasecmp (*sections, "grab"))
+ || (0 == strcasecmp (*sections, "plugins")))
+ continue;
+
+ /* init + set defaults */
+ s = malloc (sizeof (*s));
+ memset (s, 0, sizeof (*s));
+ s->name = *sections;
+ s->host = "www";
+ s->user = "webcam";
+ s->pass = "xxxxxx";
+ s->dir = "public_html/images";
+ s->file = "webcam.jpeg";
+ s->tmpfile = "uploading.jpeg";
+ s->passive = 1;
+ s->autologin = 0;
+ s->ops = &ftp_ops;
+ s->keepjpegs = 1; //number of jpeg files to rotate through. 0 & 1 are synonymous
+ s->htmlfile = NULL;
+ s->custom_htmlfile = NULL;
+ s->currentCount = 0;
+
+ /* from config */
+ if (NULL != (val = cfg_get_str (*sections, "host")))
+ s->host = val;
+ if (NULL != (val = cfg_get_str (*sections, "user")))
+ s->user = val;
+ if (NULL != (val = cfg_get_str (*sections, "pass")))
+ s->pass = val;
+ if (NULL != (val = cfg_get_str (*sections, "dir")))
+ s->dir = val;
+ if (NULL != (val = cfg_get_str (*sections, "file")))
+ s->file = val;
+ if (NULL != (val = cfg_get_str (*sections, "tmp")))
+ s->tmpfile = val;
+ if (-1 != (i = cfg_get_int (*sections, "passive")))
+ s->passive = i;
+ if (-1 != (i = cfg_get_int (*sections, "auto")))
+ s->autologin = i;
+ if (-1 != (i = cfg_get_int (*sections, "debug")))
+ s->debug = i;
+ if (-1 != (i = cfg_get_int (*sections, "local")))
+ if (i)
+ s->ops = &local_ops;
+ if (-1 != (i = cfg_get_int (*sections, "ssh")))
+ if (i)
+ s->ops = &ssh_ops;
+ if (-1 != (i = cfg_get_int (*sections, "keepjpegs")))
+ s->keepjpegs = (i < 1) ? 1 : i;
+ if (NULL != (val = cfg_get_str (*sections, "htmlfile")))
+ s->htmlfile = val;
+ if (NULL != (val = cfg_get_str (*sections, "custom_htmlfile")))
+ s->custom_htmlfile = val;
+
+ /* all done */
+ list_add_tail (&s->list, &connections);
+ }
+
+ /* init everything */
+ grab_init ();
+ sleep (grab_wait);
+ tmpdir = (NULL != getenv ("TMPDIR")) ? getenv ("TMPDIR") : "/tmp";
+ list_for_each (item, &connections)
+ {
+ s = list_entry (item, struct xfer_state, list);
+ s->ops->open (s);
+ }
+
+ /* print config */
+ fprintf (stderr, "video4linux webcam v1.5 - (c) 1998-2002 Gerd Knorr\n");
+ fprintf (stderr, "grabber config:\n size %dx%d [%s]\n",
+ fmt.width, fmt.height, ng_vfmt_to_desc[gfmt.fmtid]);
+ fprintf (stderr, " input %s, norm %s, jpeg quality %d\n",
+ grab_input, grab_norm, grab_quality);
+ fprintf (stderr, " rotate=%d, top=%d, left=%d, bottom=%d, right=%d\n",
+ grab_rotate, grab_top, grab_left, grab_bottom, grab_right);
+ list_for_each (item, &connections)
+ {
+ s = list_entry (item, struct xfer_state, list);
+ s->ops->info (s);
+ }
+
+ /* run as daemon - detach from terminal */
+ if (daemonize)
+ {
+ switch (fork ())
+ {
+ case -1:
+ perror ("fork");
+ exit (1);
+ case 0:
+ close (0);
+ close (1);
+ close (2);
+ setsid ();
+ break;
+ default:
+ exit (0);
+ }
+ }
+
+
+ /* main loop */
+ for (;;)
+ {
+ /* grab a new one */
+ gimg = grab_one (&width, &height, &ng_buf);
+
+ if (grab_top != 0 || grab_left != 0 ||
+ grab_right != width || grab_bottom != height)
+ { //don't call rotate_image() if nothing to do
+ gimg = rotate_image (gimg, &width, &height, grab_rotate,
+ grab_top, grab_left, grab_bottom, grab_right);
+ }
+
+ if (grab_dist_on)
+ {
+ gimg = correct_distor (gimg, width, height,
+ grab_dist_zoom, grab_dist_k,
+ grab_dist_cx, grab_dist_cy,
+ grab_dist_sensorw, grab_dist_sensorh);
+ }
+
+ image = gimg;
+
+ if (grab_trigger)
+ {
+ /* look if it has changed */
+ if (NULL != lastimg)
+ {
+ i = compare_images (lastimg, image, iTrigX, iTrigY, iTrigWidth,
+ iTrigHeight, width);
+
+ if (grab_trigger_average)
+ i = i & 0xFF;
+ else
+ i = i >> 8;
+
+ if (i < grab_trigger)
+ {
+ if (grab_trigger_delay)
+ usleep (grab_trigger_delay * 1000);
+
+ continue;
+ }
+
+ }
+ else
+ {
+ lastimg = malloc (width * height * 3);
+
+ iTrigWidth = width;
+ iTrigHeight = height;
+ fprintf (stderr, "width: %d,height:%d\n", width, height);
+ parse_trigger_area (grab_trigger_area, &iTrigX, &iTrigY, &iTrigWidth,
+ &iTrigHeight);
+ }
+
+ memcpy (lastimg, image, width * height * 3);
+
+ //draw inverted trigger area if debug > 1
+ if (s->debug > 1)
+ draw_trigger_area (image, iTrigX, iTrigY, iTrigWidth, iTrigHeight,
+ width);
+
+ }
+
+ if (!list_empty (&plugin_list))
+ {
+ //if we're using plugins ng_buf will have to be valid
+ // to pass to the filters.
+ //assign the current image to ng_buf and make sure fmt is
+ // valid due to possible size change in rotate_image()
+ if (!conv && !ng_buf)
+ ng_buf = ng_malloc_video_buf (&fmt, 3 * fmt.width * fmt.height);
+
+ ng_buf->fmt.width = width;
+ ng_buf->fmt.height = height;
+ ng_buf->fmt.bytesperline = width * (ng_vfmt_to_depth[fmt.fmtid] / 8);
+ ng_buf->size = ng_buf->fmt.bytesperline * height;
+ memcpy (ng_buf->data, image, ng_buf->size);
+
+ //call the plugins....
+ list_for_each (item, &plugin_list)
+ {
+ currfilter = list_entry (item, struct plugin_s, list);
+ ng_buf = ng_filter_single (currfilter->filter, ng_buf);
+ image = ng_buf->data;
+ }
+
+ }
+
+ /* ok, label it and upload */
+ add_text (image, width, height);
+
+ list_for_each (item, &connections)
+ {
+ s = list_entry (item, struct xfer_state, list);
+
+ if (++s->currentCount > s->keepjpegs)
+ s->currentCount = 1;
+
+ s->ops->xfer (s, image, width, height);
+
+ if (s->htmlfile) // || s->custom_htmlfile)
+ ftp_upload_htmlfile (s);
+ }
+
+ if (archive)
+ {
+ time_t t;
+ struct tm *tm;
+
+ time (&t);
+ tm = localtime (&t);
+ strftime (filename, sizeof (filename) - 1, archive, tm);
+ if (-1 == (fh = open (filename, O_CREAT | O_WRONLY | O_TRUNC, 0666)))
+ {
+ fprintf (stderr, "open %s: %s\n", filename, strerror (errno));
+ exit (1);
+ }
+ write_file (fh, image, width, height);
+ }
+
+ if (-1 != grab_times && --grab_times == 0)
+ {
+ fprintf (stderr, "grab \"times\" reached 0\n");
+ break;
+ }
+ if (grab_delay > 0)
+ {
+ fprintf (stderr, "delay for %d seconds...\n", grab_delay);
+ sleep (grab_delay);
+ }
+ }
+
+ list_for_each (item, &connections)
+ {
+ s = list_entry (item, struct xfer_state, list);
+ s->ops->close (s);
+ }
+
+ return 0;
+}
diff --git a/vbistuff/Subdir.mk b/vbistuff/Subdir.mk
index 8dfb8c1..4731da3 100644
--- a/vbistuff/Subdir.mk
+++ b/vbistuff/Subdir.mk
@@ -41,4 +41,4 @@ distclean::
rm -f $(TARGETS-vbistuff)
# special dependences
-vbistuff/alevtd.o:: vbistuff/alevtd.c $(HTML-alevtd)
+vbistuff/alevtd.o: $(HTML-alevtd)
diff --git a/x11/Subdir.mk b/x11/Subdir.mk
index e4f801a..b20aeb8 100644
--- a/x11/Subdir.mk
+++ b/x11/Subdir.mk
@@ -120,12 +120,12 @@ MOTV-app := $(patsubst %,x11/MoTV.%.ad,$(LANGUAGES))
# local targets
-x11/complete-xaw.o:: x11/complete.c
+x11/complete-xaw.o: x11/complete.c
@$(echo_compile_c)
@$(compile_c)
@$(fixup_deps)
-x11/complete-motif.o:: x11/complete.c
+x11/complete-motif.o: x11/complete.c
@$(echo_compile_c)
@$(compile_c)
@$(fixup_deps)
@@ -154,9 +154,9 @@ distclean::
rm -f $(MOTV-app) x11/MoTV.ad x11/MoTV.h x11/Xawtv.h x11/mtt.h
# special dependences / rules
-x11/xawtv.o:: x11/xawtv.c x11/Xawtv.h
-x11/motv.o:: x11/motv.c x11/MoTV.h
-x11/mtt.o:: x11/mtt.c x11/mtt.h
+x11/xawtv.o: x11/Xawtv.h
+x11/motv.o: x11/MoTV.h
+x11/mtt.o: x11/mtt.h
x11/MoTV.ad: $(srcdir)/x11/MoTV-default $(srcdir)/x11/MoTV-fixed
cat $(srcdir)/x11/MoTV-default $(srcdir)/x11/MoTV-fixed > x11/MoTV.ad
diff --git a/x11/motv.c b/x11/motv.c
index 1c1dfb8..e24fd4e 100644
--- a/x11/motv.c
+++ b/x11/motv.c
@@ -961,6 +961,8 @@ create_filter_prop(void)
rc1 = XtVaCreateManagedWidget("rc", xmRowColumnWidgetClass, filter_shell,
NULL);
+ if (NULL == ng_filters)
+ return;
for (i = 0; NULL != ng_filters[i]; i++) {
if (NULL == ng_filters[i]->attrs)
continue;
diff --git a/x11/propwatch.c b/x11/propwatch.c
index 5c25c8c..678d630 100644
--- a/x11/propwatch.c
+++ b/x11/propwatch.c
@@ -1,25 +1,11 @@
-#if 0
-set -x
-gcc -o propwatch -I/usr/X11R6/include -L/usr/X11R6/lib \
- -lXaw3d -lXmu -lSM -lICE -lXext -lXt -lX11 $0
-exit
-#endif
/*
- * propwatch.c -- (c) 1998,99 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ * propwatch.c -- (c) 1997-2003 Gerd Knorr <kraxel@bytesex.org>
*
* A tool to monitor window properties of root and application windows.
* Nice for debugging property-based IPC of X11 programs.
*
- * usage:
- * propwatch [ property-list ]
- *
- * environment:
- * $DISPLAY - which display propwatch should use for its window.
- * $PROPWATCH - which display propwatch should monitor. $DISPLAY
- * will be used if unset.
- *
* see also:
- * xprop(1), xhost(1)
+ * xhost(1), xauth(1), xprop(1), xwd(1)
*
*/
@@ -40,7 +26,6 @@ exit
#include <X11/Xaw/Label.h>
#include <X11/Xaw/List.h>
#include <X11/Xaw/Viewport.h>
-#include <X11/Xmu/WinUtil.h>
#ifndef TRUE
#define TRUE 1
@@ -53,7 +38,7 @@ struct WATCHLIST {
Window win;
int watch;
struct WATCHLIST *next;
- char text[4096];
+ char *text;
};
/* WM */
@@ -69,26 +54,61 @@ static Atom *watch_atom;
static int watch_count;
static char *watch_default[] = {
- "CUT_BUFFER0",
- "WM_CLASS", "WM_COMMAND",
- "_MOZILLA_URL", "_XAWTV_STATION" };
+ "WM_COMMAND",
+};
static String *str_list;
static int str_count;
-static int verbose = 0;
-
-static char *drop[] = {
- "WM_",
- "CUT_BUFFER",
- "KWM_ACTIVE_WINDOW",
- "KWM_WIN_",
- NULL
+
+static void AddWatch(Display *dpy, Window win, int i);
+static void DeleteWatch(Window win);
+static void CheckWindow(Display *dpy, Window win);
+static void Update(Display *dpy, Window win, Atom prop);
+
+/*-------------------------------------------------------------------------*/
+
+struct ARGS {
+ char *watch;
+ int verbose;
+ int proplog;
+ int kbdlog;
+} args;
+
+XtResource args_desc[] = {
+ /* name, class, type, size, offset, default_type, default_addr */
+ {
+ /* ----- Strings ----- */
+ "watch",
+ XtCString, XtRString, sizeof(char*),
+ XtOffset(struct ARGS*,watch),
+ XtRString, NULL,
+ },{
+ /* ----- Integer ----- */
+ "verbose",
+ XtCValue, XtRInt, sizeof(int),
+ XtOffset(struct ARGS*,verbose),
+ XtRString, "0"
+ },{
+ "proplog",
+ XtCValue, XtRInt, sizeof(int),
+ XtOffset(struct ARGS*,proplog),
+ XtRString, "0"
+ },{
+ "kbdlog",
+ XtCValue, XtRInt, sizeof(int),
+ XtOffset(struct ARGS*,kbdlog),
+ XtRString, "0"
+ }
};
+const int args_count = XtNumber(args_desc);
-void AddWatch(Display *dpy, Window win, int i);
-void DeleteWatch(Window win);
-void CheckWindow(Display *dpy, Window win);
-void Update(Display *dpy, Window win, Atom prop);
+XrmOptionDescRec opt_desc[] = {
+ { "-watch", "watch", XrmoptionSepArg, NULL },
+ { "-verbose", "verbose", XrmoptionNoArg, "1" },
+ { "-proplog", "proplog", XrmoptionNoArg, "1" },
+ { "-kbdlog", "kbdlog", XrmoptionNoArg, "1" },
+};
+const int opt_count = (sizeof(opt_desc)/sizeof(XrmOptionDescRec));
/*-------------------------------------------------------------------------*/
@@ -97,15 +117,19 @@ Widget app_shell;
Cursor left_ptr;
Cursor menu_ptr;
-void QuitAction(Widget, XEvent*, String*, Cardinal*);
+static void QuitAction(Widget, XEvent*, String*, Cardinal*);
+static void HookAction(Widget, XEvent*, String*, Cardinal*);
-void ProcessPropertyChange(Display*,XEvent*);
-void ProcessKeyPress(Display*,XEvent*);
-void ProcessCreateWindow(Display*,XEvent*);
+static void ProcessPropertyChange(Display*,XEvent*);
+static void ProcessKeyPress(Display*,XEvent*);
+static void ProcessClientMessage(Display*,XEvent*);
+static void ProcessCreateWindow(Display*,XEvent*);
+static void ProcessEvent(Display *dpy, XEvent *event);
/* Actions */
static XtActionsRec actionTable[] = {
- { "Quit", QuitAction }
+ { "Quit", QuitAction },
+ { "Hook", HookAction },
};
/*-------------------------------------------------------------------------*/
@@ -113,6 +137,8 @@ static XtActionsRec actionTable[] = {
static int
x11_error_dev_null(Display * dpy, XErrorEvent * event)
{
+ if (args.verbose)
+ printf("x11 error -- ignored (likely just a race as X11 is async)\n");
return 0;
}
@@ -120,19 +146,36 @@ static void
spy_input(XtPointer client_data, int *src, XtInputId *id)
{
Display *spy_dpy = client_data;
- Window root = DefaultRootWindow(spy_dpy);
XEvent event;
- while (True == XCheckMaskEvent(spy_dpy, 0xffffffff, &event)) {
- if (event.type == PropertyNotify)
- ProcessPropertyChange(spy_dpy,&event);
- else if (event.type == CreateNotify &&
- event.xcreatewindow.parent == root)
- ProcessCreateWindow(spy_dpy,&event);
- else if (event.type == DestroyNotify) {
- DeleteWatch(event.xdestroywindow.window);
- }
+ while (True == XCheckMaskEvent(spy_dpy, 0xffffffff, &event))
+ ProcessEvent(spy_dpy,&event);
+}
+
+static void
+add_window(Display *dpy, Window win)
+{
+ Window rroot,parent,*children = NULL;
+ int i, n;
+
+ if (NULL == args.watch && XtWindow(app_shell) == win)
+ /* don't f*ck up ourself */
+ return;
+
+ XSelectInput(dpy, win,
+ (args.kbdlog ? KeyPressMask | KeyReleaseMask : 0) |
+ PropertyChangeMask |
+ SubstructureNotifyMask);
+
+ if (0 != XQueryTree(dpy, win, &rroot, &parent, &children, &n)) {
+ for (i = 0; i < n; i++)
+ add_window(dpy,children[i]);
+ if (children)
+ XFree(children);
}
+
+ /* look for properties to show */
+ CheckWindow(dpy, win);
}
int
@@ -140,34 +183,39 @@ main(int argc, char *argv[])
{
Screen *scr;
XColor white,red,dummy;
- int i,n;
- Window root,rroot,parent,*children,w;
+ int i;
+ Window root;
Display *dpy, *spy_dpy;
- char *spy_name,title[1024];
+ char title[1024];
XEvent event;
/* init X11 */
- app_shell = XtAppInitialize(&app_context,
- "Propwatch",
- NULL, 0,
+ app_shell = XtAppInitialize(&app_context, "Propwatch",
+ opt_desc, opt_count,
&argc, argv,
NULL,
NULL, 0);
+ XtGetApplicationResources(app_shell,&args,
+ args_desc,args_count,
+ NULL,0);
+
XtAppAddActions(app_context,actionTable,
sizeof(actionTable)/sizeof(XtActionsRec));
XtOverrideTranslations
(app_shell,XtParseTranslationTable("<Message>WM_PROTOCOLS: Quit()\n"));
dpy = XtDisplay(app_shell);
- if (NULL != (spy_name = getenv("PROPWATCH"))) {
- if (NULL == (spy_dpy = XOpenDisplay(spy_name)))
+ if (NULL != args.watch) {
+ if (NULL == (spy_dpy = XOpenDisplay(args.watch))) {
+ fprintf(stderr,"can't open display: %s\n",args.watch);
exit(1);
- sprintf(title,"watch on %s - ",spy_name);
+ }
+ sprintf(title,"watch on %s - ",args.watch);
} else {
spy_dpy = dpy;
sprintf(title,"watch - ");
}
root = DefaultRootWindow(spy_dpy);
-
+
XSetErrorHandler(x11_error_dev_null);
/* args */
@@ -209,32 +257,24 @@ main(int argc, char *argv[])
vp = XtVaCreateManagedWidget("vp",viewportWidgetClass,app_shell,
XtNallowHoriz, False,
XtNallowVert, True,
- XtNwidth, 400,
- XtNheight, 250,
+ XtNwidth, 600,
+ XtNheight, 400,
NULL);
bl = XtVaCreateManagedWidget("box",listWidgetClass,vp,
XtNdefaultColumns,1,
XtNforceColumns,True,
NULL);
-
- XSelectInput(spy_dpy,root, /* KeyPressMask | */
- SubstructureNotifyMask | PropertyChangeMask);
- CheckWindow(spy_dpy,root);
-
- XQueryTree(spy_dpy, root, &rroot, &parent, &children, &n);
- for (i = 0; i < n; i++) {
- w = XmuClientWindow(spy_dpy, children[i]);
- XSelectInput(spy_dpy,w, /* KeyPressMask | */
- StructureNotifyMask | PropertyChangeMask);
- CheckWindow(spy_dpy,w);
- }
- XFree((char *) children);
+ XtOverrideTranslations(bl,XtParseTranslationTable
+ ("<Key>Q: Quit()\n"
+ "<Key>P: Hook(xprop)\n"));
/* display main window */
XtRealizeWidget(app_shell);
XDefineCursor(dpy,XtWindow(app_shell),left_ptr);
XSetWMProtocols(dpy,XtWindow(app_shell),&wm_del_win,1);
+ add_window(spy_dpy,root);
+
/* enter main loop */
if (spy_dpy != dpy) {
XtAppAddInput(app_context,ConnectionNumber(spy_dpy),
@@ -245,16 +285,7 @@ main(int argc, char *argv[])
XtAppNextEvent(app_context,&event);
if (XtDispatchEvent(&event))
continue;
- if (event.type == PropertyNotify) {
- ProcessPropertyChange(spy_dpy,&event);
- } else if (event.type == CreateNotify &&
- event.xcreatewindow.parent == root) {
- ProcessCreateWindow(spy_dpy,&event);
- } else if (event.type == KeyPress) {
- ProcessKeyPress(spy_dpy,&event);
- } else if (event.type == DestroyNotify) {
- DeleteWatch(event.xdestroywindow.window);
- }
+ ProcessEvent(spy_dpy,&event);
}
/* keep compiler happy */
@@ -350,63 +381,96 @@ CheckWindow(Display *dpy, Window win)
/*-------------------------------------------------------------------------*/
-static void
-PropertyToString(Display *dpy, Window win, Atom prop, char *value)
+static char* str_append(char *dest, char *sep, char *quot, char *str)
+{
+ int size, pos;
+
+ pos = dest ? strlen(dest) : 0;
+ size = str ? strlen(str) : 0;
+ size += sep ? strlen(sep) : 0;
+ size += quot ? strlen(quot)*2 : 0;
+ dest = realloc(dest,pos+size+1);
+ sprintf(dest+pos,"%s%s%s%s",
+ sep ? sep : "",
+ quot ? quot : "",
+ str ? str : "",
+ quot ? quot : "");
+ return dest;
+}
+
+static char*
+PropertyToString(Display *dpy, Window win, Atom prop)
{
Atom type;
- int format,i,j;
+ int format,i;
unsigned long nitems,rest;
- unsigned char *cdata,*name;
+ unsigned char *cdata;
unsigned long *ldata;
- char *typename;
+ char window[12],*name;
+ char *buf = NULL;
+ char *sep = NULL;
if (Success != XGetWindowProperty
(dpy,win,prop,0,64,False,AnyPropertyType,
&type,&format,&nitems,&rest,&cdata))
- return;
+ return NULL;
ldata = (unsigned long*)cdata;
switch (type) {
case XA_STRING:
- for (i = 0, j = 0; i < nitems; i += strlen(cdata+i)+1)
- j += sprintf(value+j,"\"%s\", ",cdata+i);
- value[j-2]=0;
+ for (i = 0; i < nitems; i += strlen(cdata+i)+1) {
+ buf = str_append(buf,sep,"\"",cdata+i);
+ sep = ", ";
+ }
break;
case XA_ATOM:
- for (i = 0, j = 0; i < nitems; i++) {
+ for (i = 0; i < nitems; i++) {
name = XGetAtomName(dpy,ldata[i]);
- j += sprintf(value+j,"%s, ",name);
- XFree(name);
- }
- value[j-2]=0;
- break;
- case XA_WINDOW:
- for (i = 0, j = 0; i < nitems; i++) {
- j += sprintf(value+j,"0x%x, ",(unsigned int)ldata[i]);
+ buf = str_append(buf,sep,NULL,name);
+ sep = ", ";
+ if (name)
+ XFree(name);
}
- value[j-2]=0;
break;
default:
- typename = XGetAtomName(dpy,type);
- sprintf(value,"unknown type (%s)",typename);
- XFree(typename);
+ if (32 == format) {
+ for (i = 0; i < nitems; i++) {
+ sprintf(window,"0x%x",(unsigned int)ldata[i]);
+ buf = str_append(buf,sep,NULL,window);
+ sep = ", ";
+ }
+ } else {
+ name = XGetAtomName(dpy,type);
+ buf = malloc(40 + (name ? strlen(name) : 4));
+ sprintf(buf,"can't handle: format=%d type=%s",
+ format, name ? name : "NULL");
+ if (name)
+ XFree(name);
+ }
break;
}
- XFree(cdata);
+ XFree(cdata);
+ return buf;
}
void
Update(Display *dpy, Window win, Atom prop)
{
- int n;
struct WATCHLIST *this;
+ char *str;
for (this = watchlist; this != NULL; this = this->next)
if (this->win == win && watch_atom[this->watch] == prop)
break;
if (this) {
- n = sprintf(this->text,"%8x: %s: ", (unsigned int)this->win,
- watch_name[this->watch]);
- PropertyToString(dpy,win,prop,this->text+n);
+ if (this->text)
+ free(this->text);
+ str = PropertyToString(dpy,win,prop);
+ this->text = malloc((str ? strlen(str) : 4) +
+ strlen(watch_name[this->watch]) + 20);
+ sprintf(this->text,"0x%08lx: %s: %s",
+ this->win, watch_name[this->watch], str ? str : "NULL");
+ if (str)
+ free(str);
}
}
@@ -415,8 +479,10 @@ ProcessPropertyChange(Display *dpy, XEvent* event)
{
int i;
struct WATCHLIST *this;
- char *name;
+ char *name = NULL;
+ char *prop = NULL;
+ name = XGetAtomName(dpy,event->xproperty.atom);
for (i = 0; i < watch_count; i++) {
if (watch_atom[i] == event->xproperty.atom) {
for (this = watchlist; this != NULL; this = this->next)
@@ -432,62 +498,62 @@ ProcessPropertyChange(Display *dpy, XEvent* event)
}
}
- if (verbose) {
- /* get it */
- name = XGetAtomName(dpy,event->xproperty.atom);
-
- for (i = 0; drop[i] != NULL; i++)
- if (0 == strncmp(name,drop[i],strlen(drop[i])))
- break;
- if (NULL == drop[i])
- printf("%8x: %s\n", (int)event->xproperty.window,name);
- XFree(name);
+ if (args.proplog) {
+ prop = PropertyToString(dpy, event->xproperty.window,
+ event->xproperty.atom);
+ printf("0x%-8lx: PropertyChange: %s: %s\n",
+ event->xproperty.window,
+ name ? name : "NULL",
+ prop ? prop : "NULL");
+ if (prop)
+ free(prop);
}
+ if (name)
+ XFree(name);
}
void
-ProcessKeyPress(Display *dpy, XEvent* event)
+ProcessClientMessage(Display *dpy, XEvent* event)
{
- static int last_window;
-
- if (event->xkey.window != last_window) {
- last_window = event->xkey.window;
- fprintf(stderr,"\n%8x: ",last_window);
- }
- fprintf(stderr,"%d ",event->xkey.keycode);
+ fprintf(stderr,"0x%-8lx: ClientMessage\n",
+ event->xclient.window);
}
-/*-------------------------------------------------------------------------*/
+void
+ProcessKeyPress(Display *dpy, XEvent* event)
+{
+ fprintf(stderr,"0x%-8lx: %s: code=%d sym=%s\n",
+ event->xkey.window,
+ event->type == KeyPress ? "KeyPress" : "KeyRelease",
+ event->xkey.keycode,
+ XKeysymToString(XKeycodeToKeysym(dpy,event->xkey.keycode,0)));
+}
void
ProcessCreateWindow(Display *dpy, XEvent* event)
{
- Atom type;
- int format;
- unsigned long nitems,rest;
- unsigned char *class = NULL, *class2 = NULL;
-
- if (Success != XGetWindowProperty
- (dpy,event->xcreatewindow.window,wm_class,
- 0,64,False,AnyPropertyType,
- &type,&format,&nitems,&rest,&class))
- return;
- if (class != NULL && strlen(class)+1 < nitems)
- class2 = class + strlen(class)+1;
-
- if (verbose) {
- printf("%8x: new: %s %s\n",
- (unsigned int)event->xcreatewindow.window,
- class?class:(unsigned char*)"-",
- class2?class2:(unsigned char*)"-");
+ add_window(dpy,event->xcreatewindow.window);
+}
+
+void
+ProcessEvent(Display *dpy, XEvent *event)
+{
+ if (event->type == PropertyNotify) {
+ ProcessPropertyChange(dpy,event);
+
+ } else if (event->type == CreateNotify) {
+ ProcessCreateWindow(dpy,event);
+
+ } else if (event->type == KeyPress ||
+ event->type == KeyRelease) {
+ ProcessKeyPress(dpy,event);
+
+ } else if (event->type == ClientMessage) {
+ ProcessClientMessage(dpy,event);
+
+ } else if (event->type == DestroyNotify) {
+ DeleteWatch(event->xdestroywindow.window);
}
-
- XSelectInput(dpy, event->xcreatewindow.window, /* KeyPressMask | */
- StructureNotifyMask | PropertyChangeMask);
- CheckWindow(dpy, event->xcreatewindow.window);
-
- if (class != NULL)
- XFree(class);
}
/*-------------------------------------------------------------------------*/
@@ -498,3 +564,35 @@ QuitAction(Widget widget, XEvent* event, String* arg, Cardinal* arg_count)
exit(0);
}
+void
+HookAction(Widget widget, XEvent* event, String* arg, Cardinal* arg_count)
+{
+ XawListReturnStruct *ret;
+ struct WATCHLIST *this;
+ char *dname;
+ char cmd[256];
+ int i;
+
+ /* find window */
+ if (0 != strcmp(XtName(widget),"box"))
+ return;
+ ret = XawListShowCurrent(widget);
+ for (i = 0, this = watchlist; this != NULL; i++, this=this->next)
+ if (0 == strcmp(ret->string,this->text))
+ break;
+ if (NULL == this)
+ return;
+ if (0 == arg_count)
+ return;
+ dname = DisplayString(XtDisplay(widget));
+
+ if (0 == strcmp(arg[0],"xprop")) {
+ /* dump window properties */
+ sprintf(cmd,"xprop -display %s -id 0x%lx",
+ args.watch ? args.watch : dname,
+ this->win);
+ printf("### %s\n",cmd);
+ system(cmd);
+ printf("### done\n");
+ }
+}
diff --git a/x11/wmhooks.c b/x11/wmhooks.c
index 6e5dc77..5e54a75 100644
--- a/x11/wmhooks.c
+++ b/x11/wmhooks.c
@@ -124,7 +124,7 @@ wm_check_capability(Display *dpy, Window root, Atom list, Atom wanted)
return retval;
}
-int
+void
wm_detect(Display *dpy)
{
Window root = DefaultRootWindow(dpy);
@@ -136,7 +136,6 @@ wm_detect(Display *dpy)
if (debug)
fprintf(stderr,"wmhooks: netwm state above\n");
wm_stay_on_top = netwm_stay_on_top;
- return 0;
}
if (NULL == wm_stay_on_top &&
0 == wm_check_capability(dpy,root,_NET_SUPPORTED,
@@ -144,7 +143,6 @@ wm_detect(Display *dpy)
if (debug)
fprintf(stderr,"wmhooks: netwm state stays_on_top\n");
wm_stay_on_top = netwm_old_stay_on_top;
- return 0;
}
if (NULL == wm_fullscreen &&
0 == wm_check_capability(dpy,root,_NET_SUPPORTED,
@@ -152,7 +150,6 @@ wm_detect(Display *dpy)
if (debug)
fprintf(stderr,"wmhooks: netwm state fullscreen\n");
wm_fullscreen = netwm_fullscreen;
- return 0;
}
/* gnome checks */
@@ -161,9 +158,5 @@ wm_detect(Display *dpy)
if (debug)
fprintf(stderr,"wmhooks: gnome layer\n");
wm_stay_on_top = gnome_stay_on_top;
- return 0;
}
-
- /* nothing found... */
- return -1;
}
diff --git a/x11/wmhooks.h b/x11/wmhooks.h
index 3b97102..d0341fa 100644
--- a/x11/wmhooks.h
+++ b/x11/wmhooks.h
@@ -1,3 +1,3 @@
-int wm_detect(Display *dpy);
+void wm_detect(Display *dpy);
void (*wm_stay_on_top)(Display *dpy, Window win, int state);
void (*wm_fullscreen)(Display *dpy, Window win, int state);
diff --git a/x11/xt.c b/x11/xt.c
index c8d6f20..c7c3ca4 100644
--- a/x11/xt.c
+++ b/x11/xt.c
@@ -530,7 +530,7 @@ display_onscreen(char *title)
if (debug)
fprintf(stderr,"osd: show (%s)\n",title);
XtVaGetValues(app_shell,XtNx,&x,XtNy,&y,NULL);
- XtVaSetValues(on_shell,XtNx,x+30,XtNy,y+20,NULL);
+ XtVaSetValues(on_shell,XtNx,x+osd_x,XtNy,y+osd_y,NULL);
toolkit_set_label(on_label,title);
XtPopup(on_shell, XtGrabNone);
if (wm_stay_on_top && stay_on_top > 0)
@@ -815,27 +815,67 @@ set_vidmode(XF86VidModeModeInfo *mode)
}
#endif
-void
-do_fullscreen(void)
+static void
+do_screensaver(int fs_state)
{
- static Dimension x,y,w,h;
- static int timeout,interval,prefer_blanking,allow_exposures,rpx,rpy;
- static int warp_pointer;
+ static int timeout,interval,prefer_blanking,allow_exposures;
#ifdef HAVE_LIBXDPMS
static BOOL dpms_on;
CARD16 dpms_state;
int dpms_dummy;
#endif
+ if (fs_state) {
+ /* fullscreen on -- disable screensaver */
+ XGetScreenSaver(dpy,&timeout,&interval,
+ &prefer_blanking,&allow_exposures);
+ XSetScreenSaver(dpy,0,0,DefaultBlanking,DefaultExposures);
+#ifdef HAVE_LIBXDPMS
+ if ((DPMSQueryExtension(dpy, &dpms_dummy, &dpms_dummy)) &&
+ (DPMSCapable(dpy))) {
+ DPMSInfo(dpy, &dpms_state, &dpms_on);
+ DPMSDisable(dpy);
+ }
+#endif
+ xscreensaver_timer = XtAppAddTimeOut(app_context,60000,
+ xscreensaver_timefunc,NULL);
+ } else {
+ /* fullscreen off -- enable screensaver */
+ XSetScreenSaver(dpy,timeout,interval,prefer_blanking,allow_exposures);
+#ifdef HAVE_LIBXDPMS
+ if ((DPMSQueryExtension(dpy, &dpms_dummy, &dpms_dummy)) &&
+ (DPMSCapable(dpy)) && (dpms_on)) {
+ DPMSEnable(dpy);
+ }
+#endif
+ if (xscreensaver_timer)
+ XtRemoveTimeOut(xscreensaver_timer);
+ }
+}
+
+void
+do_fullscreen(void)
+{
+ static Dimension x,y,w,h;
+ static int rpx,rpy;
+ static int warp_pointer;
+
Window root,child;
int wpx,wpy,mask;
- if (wm_fullscreen) {
- /* full service for us :-) */
+ if (use_wm_fullscreen && wm_fullscreen) {
+ /* full service for us, next to nothing to do */
fs = !fs;
if (debug)
fprintf(stderr,"fullscreen %s via netwm\n", fs ? "on" : "off");
wm_fullscreen(dpy,XtWindow(app_shell),fs);
+
+ if (0 == fs && on_timer) {
+ XtPopdown(on_shell);
+ XtRemoveTimeOut(on_timer);
+ on_timer = 0;
+ }
+ do_screensaver(fs);
return;
}
@@ -854,7 +894,7 @@ do_fullscreen(void)
XtRemoveTimeOut(on_timer);
on_timer = 0;
}
-
+
XtVaSetValues(app_shell,
XtNwidthInc, WIDTH_INC,
XtNheightInc,HEIGHT_INC,
@@ -864,17 +904,8 @@ do_fullscreen(void)
XtNheight, h,
NULL);
- XSetScreenSaver(dpy,timeout,interval,prefer_blanking,allow_exposures);
-#ifdef HAVE_LIBXDPMS
- if ((DPMSQueryExtension(dpy, &dpms_dummy, &dpms_dummy)) &&
- (DPMSCapable(dpy)) && (dpms_on)) {
- DPMSEnable(dpy);
- }
-#endif
- if (xscreensaver_timer)
- XtRemoveTimeOut(xscreensaver_timer);
-
- if (warp_pointer)
+ do_screensaver(0);
+ if (warp_pointer)
XWarpPointer(dpy, None, RootWindowOfScreen(XtScreen(tv)),
0, 0, 0, 0, rpx, rpy);
fs = 0;
@@ -975,20 +1006,7 @@ do_fullscreen(void)
NULL);
XRaiseWindow(dpy, XtWindow(app_shell));
-
- XGetScreenSaver(dpy,&timeout,&interval,
- &prefer_blanking,&allow_exposures);
- XSetScreenSaver(dpy,0,0,DefaultBlanking,DefaultExposures);
-#ifdef HAVE_LIBXDPMS
- if ((DPMSQueryExtension(dpy, &dpms_dummy, &dpms_dummy)) &&
- (DPMSCapable(dpy))) {
- DPMSInfo(dpy, &dpms_state, &dpms_on);
- DPMSDisable(dpy);
- }
-#endif
- xscreensaver_timer = XtAppAddTimeOut(app_context,60000,
- xscreensaver_timefunc,NULL);
-
+ do_screensaver(1);
if (warp_pointer)
XWarpPointer(dpy, None, XtWindow(tv), 0, 0, 0, 0, 30, 15);
fs = 1;
diff --git a/xawtv.spec b/xawtv.spec
index 0b1fe8b..4344906 100644
--- a/xawtv.spec
+++ b/xawtv.spec
@@ -1,7 +1,7 @@
Name: xawtv
Group: Applications/Multimedia
Autoreqprov: on
-Version: 3.82
+Version: 3.83
Release: 0
License: GPL
Summary: v4l applications

Privacy Policy