]> git.sesse.net Git - vlc/commitdiff
. nouveaux plugins - ne fonctionnent pas encore tous
authorSam Hocevar <sam@videolan.org>
Fri, 23 Jun 2000 22:28:42 +0000 (22:28 +0000)
committerSam Hocevar <sam@videolan.org>
Fri, 23 Jun 2000 22:28:42 +0000 (22:28 +0000)
43 files changed:
ChangeLog
INSTALL
Makefile.in
README
configure
configure.in
debian/changelog
include/plugins.h
plugins/beos/aout_beos.cpp [new file with mode: 0644]
plugins/beos/intf_beos.cpp [new file with mode: 0644]
plugins/beos/vout_beos.cpp [new file with mode: 0644]
plugins/dsp/aout_dsp.c [new file with mode: 0644]
plugins/dummy/aout_dummy.c [new file with mode: 0644]
plugins/dummy/intf_dummy.c [new file with mode: 0644]
plugins/dummy/vout_dummy.c [new file with mode: 0644]
plugins/esd/aout_esd.c [new file with mode: 0644]
plugins/fb/intf_fb.c [new file with mode: 0644]
plugins/fb/vout_fb.c [new file with mode: 0644]
plugins/ggi/intf_ggi.c [new file with mode: 0644]
plugins/ggi/vout_ggi.c [new file with mode: 0644]
plugins/glide/intf_glide.c [new file with mode: 0644]
plugins/glide/vout_glide.c [new file with mode: 0644]
plugins/gnome/intf_gnome.c [new file with mode: 0644]
plugins/gnome/intf_gnome.h [new file with mode: 0644]
plugins/gnome/intf_gnome_callbacks.c [new file with mode: 0644]
plugins/gnome/intf_gnome_callbacks.h [new file with mode: 0644]
plugins/gnome/intf_gnome_interface.c [new file with mode: 0644]
plugins/gnome/intf_gnome_interface.h [new file with mode: 0644]
plugins/gnome/intf_gnome_support.c [new file with mode: 0644]
plugins/gnome/intf_gnome_support.h [new file with mode: 0644]
plugins/gnome/intf_gnome_thread.h [new file with mode: 0644]
plugins/gnome/vout_gnome.c [new file with mode: 0644]
plugins/mga/intf_mga.c [new file with mode: 0644]
plugins/mga/vout_mga.c [new file with mode: 0644]
plugins/mga/vout_mga.h [new file with mode: 0644]
plugins/x11/intf_x11.c [new file with mode: 0644]
plugins/x11/vout_x11.c [new file with mode: 0644]
src/audio_output/audio_output.c
src/interface/interface.c
src/misc/plugins.c
src/video_output/video_output.c
src/video_output/video_yuv.c
vlc.spec

index 81eb9c6bbd131742e5d43877bbf3be9b1d0c9c9b..bec708be96bcf70cb6e5421a4a30ad069d59f709 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,20 +1,26 @@
+Tue Jun 20 14:17:56 CEST 2000
+0.1.99d :
+
+  * fixed RPM build
+  * .deb is now more lintian-friendly
+
 Sun Jun 18 18:54:48 CEST 2000
 0.1.99c :
 
- * fixed Makefile.in for debug version
- * caught Delete Window event in Gnome and X11 modes
- * fixed manpage
- * GGI output now works
- * fixed a segfault on exit for the Gnome plugin
- * fixed compile problems for BeOS
- * sound support almost works under BeOS
- * fixed a warning in ac3_exponent.c
- * automatic support for .rpm and .deb building
 * fixed Makefile.in for debug version
 * caught Delete Window event in Gnome and X11 modes
 * fixed manpage
 * GGI output now works
 * fixed a segfault on exit for the Gnome plugin
 * fixed compile problems for BeOS
 * sound support almost works under BeOS
 * fixed a warning in ac3_exponent.c
 * automatic support for .rpm and .deb building
 
 Sat Jun 17 03:35:02 CEST 2000
 0.1.99b :
 
- * fixed a bug preventing to quit when run with no arguments
- * new VLAN changing code
- * created the ChangeLog file :)
 * fixed a bug preventing to quit when run with no arguments
 * new VLAN changing code
 * created the ChangeLog file :)
 
diff --git a/INSTALL b/INSTALL
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ab1379a84919e31fe6d04a2e56229f6f25ee535a 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -0,0 +1,37 @@
+INSTALL file for vlc, the VideoLAN Client
+
+
+Building VideoLAN
+=================
+
+A typical way to configure the vlc is :
+
+   ./configure --prefix=/usr --enable-ppro --enable-mmx --enable-gnome
+
+See `./configure --help' for more information.
+
+Then, run `make', and `make install' to install it.
+
+
+To build a Debian package, you may use :
+
+   dpkg-buildpackage -rfakeroot -us -uc
+
+
+To build RedHat packages, use :
+
+   rpm -ba vlc.spec
+
+
+Installing and running VideoLAN
+===============================
+
+You can install the vlc and its plugins by typing :
+
+   make install
+
+But you don't need to do it if you don't want ; vlc can be launched
+from the current directory as well :
+
+   ./vlc
+
index 94599a04e7b7f03a6e4ab9ce2709147f3fe8b4a9..7e7ef54f9f06271602dcf0a6ad3868975d4b5d46 100644 (file)
 DEBUG=0
 
 SYS=@SYS@
-ARCH=@ARCH@
-AOUT=@AOUT@
-VOUT=@VOUT@
-INTF=@VOUT@
+PLUGINS=@PLUGINS@
 SNAPSHOTDIR=vlc-@VLC_VERSION@
 INSTALL=@INSTALL@
 prefix=@prefix@
@@ -249,12 +246,44 @@ endif
 #
 # Plugins
 #
-intf_plugin =           $(INTF:%=plugins/intf/intf_%.so)
-aout_plugin =           $(AOUT:%=plugins/aout/aout_%.so)
-vout_plugin =           $(VOUT:%=plugins/vout/vout_%.so)
+PLUGINS := $(PLUGINS:%=lib/%.so)
 
-PLUGIN_OBJ = $(intf_plugin) $(aout_plugin) $(vout_plugin)
+PLUGIN_BEOS   = plugins/beos/aout_beos.o \
+               plugins/beos/intf_beos.o \
+               plugins/beos/vout_beos.o
 
+PLUGIN_DSP    = plugins/dsp/aout_dsp.o
+
+PLUGIN_DUMMY  = plugins/dummy/aout_dummy.o \
+               plugins/dummy/intf_dummy.o \
+               plugins/dummy/vout_dummy.o
+
+PLUGIN_ESD    = plugins/esd/aout_esd.o
+
+PLUGIN_FB     = plugins/fb/intf_fb.o \
+               plugins/fb/vout_fb.o
+
+PLUGIN_GGI    = plugins/ggi/intf_ggi.o \
+               plugins/ggi/vout_ggi.o
+
+PLUGIN_GLIDE  = plugins/glide/intf_glide.o \
+               plugins/glide/vout_glide.o
+
+PLUGIN_GNOME  = plugins/gnome/intf_gnome.o \
+               plugins/gnome/intf_gnome_callbacks.o \
+               plugins/gnome/intf_gnome_interface.o \
+               plugins/gnome/intf_gnome_support.o \
+               plugins/gnome/vout_gnome.o
+
+PLUGIN_MGA    = plugins/mga/intf_mga.o \
+               plugins/fb/vout_mga.o
+
+PLUGIN_X11    = plugins/x11/intf_x11.o \
+               plugins/x11/vout_x11.o
+
+PLUGIN_OBJ = $(PLUGIN_BEOS) $(PLUGIN_DSP) $(PLUGIN_DUMMY) $(PLUGIN_ESD) \
+               $(PLUGIN_FB) $(PLUGIN_GGI) $(PLUGIN_GLIDE) $(PLUGIN_GNOME) \
+               $(PLUGIN_MGA) $(PLUGIN_X11)
 #
 # Other lists of files
 #
@@ -280,7 +309,7 @@ clean:
        rm -f $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ)
 
 distclean: clean
-       rm -f */*/*.o plugins/*/*.so **/*~ *.log
+       rm -f src/*/*.o plugins/*/*.o lib/*.so **/*~ *.log
        rm -f Makefile include/defs.h include/config.h
        rm -f config.status config.cache config.log
        rm -f vlc gmon.out core build-stamp
@@ -290,9 +319,9 @@ install:
        $(INSTALL) vlc $(prefix)/bin
        mkdir -p $(prefix)/lib/videolan/vlc
        mkdir -p $(prefix)/share/videolan/vlc
-       $(INSTALL) $(PLUGIN_OBJ) $(prefix)/lib/videolan/vlc
-       $(INSTALL) share/*.psf $(prefix)/share/videolan/vlc
-       $(INSTALL) share/*.png $(prefix)/share/videolan/vlc
+       $(INSTALL) -m 644 $(PLUGINS) $(prefix)/lib/videolan/vlc
+       $(INSTALL) -m 644 share/*.psf $(prefix)/share/videolan/vlc
+       $(INSTALL) -m 644 share/*.png $(prefix)/share/videolan/vlc
 
 show:
        @echo "Command line for C objects:"
@@ -316,12 +345,6 @@ snapshot:
        mv /tmp/${SNAPSHOTDIR}.tar.gz ..
        @echo "Sources are in ../${SNAPSHOTDIR}.tar.gz"
 
-deb:
-       dpkg-buildpackage -rfakeroot -us -uc
-
-rpm:
-       rpm -ba vlc.spec
-
 FORCE:
 
 #
@@ -336,7 +359,7 @@ else
        $(CC) $(CCFLAGS) $(LCFLAGS) $(CFLAGS) --export-dynamic -rdynamic -o $@ $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ)   
 endif
 
-plugins: $(PLUGIN_OBJ)
+plugins: $(PLUGINS)
 
 #
 # Generic rules (see below)
@@ -359,57 +382,56 @@ $(ASM_OBJ): %.o: %.S
 #$(PLUGIN_OBJ): %.so: Makefile.dep
 #$(PLUGIN_OBJ): %.so: .dep/%.d
 
-# audio plugins
-plugins/aout/aout_dummy.so plugins/aout/aout_dsp.so: %.so: %.c
-ifeq ($(SYS),beos)
-       $(CC) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
-else
-       $(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $<
-endif
+#$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
+               
+lib/beos.so: $(PLUGIN_BEOS)
+       ld -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
+$(PLUGIN_BEOS): %.o: %.c
+       $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
 
-plugins/aout/aout_esd.so: %.so: %.c
+lib/esd.so: $(PLUGIN_ESD)
 ifneq (,$(findstring bsd,$(SYS)))
-       $(CC) $(CCFLAGS) $(CFLAGS) -lesd -shared -o $@ $<
+       ld -shared -lesd -o $@ $^
 else
-       $(CC) $(CCFLAGS) $(CFLAGS) -laudiofile -lesd -shared -o $@ $<
+       ld -shared -laudiofile -lesd -o $@ $^
 endif
+$(PLUGIN_ESD): %.o: %.c
+       $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
 
-plugins/aout/aout_beos.so: %.so: %.cpp
-       $(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
-               
-# video plugins
-plugins/intf/intf_dummy.so plugins/vout/vout_dummy.so \
-       plugins/intf/intf_fb.so plugins/vout/vout_fb.so: %.so: %.c
-ifeq ($(SYS),beos)
-       $(CC) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
-else
-       $(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $<
-endif
-
-plugins/intf/intf_x11.so plugins/vout/vout_x11.so: %.so: %.c
-       $(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
-
-plugins/intf/intf_mga.so plugins/vout/vout_mga.so: %.so: %.c
-       $(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
+lib/dummy.so: $(PLUGIN_DUMMY)
+       ld -shared -o $@ $^
+$(PLUGIN_DUMMY): %.o: %.c
+       $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
 
-plugins/intf/intf_gnome.so: %.so: %.c
-       $(CC) $(CCFLAGS) $(CFLAGS) $(LCFLAGS) `gnome-config --libs --cflags gnomeui` -shared -o $@ $< plugins/intf/intf_gnome_callbacks.c plugins/intf/intf_gnome_interface.c plugins/intf/intf_gnome_support.c
+lib/fb.so: $(PLUGIN_FB)
+       ld -shared -o $@ $^
+$(PLUGIN_FB): %.o: %.c
+       $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
 
-plugins/vout/vout_gnome.so: %.so: %.c
-       $(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
+lib/x11.so: $(PLUGIN_X11)
+       ld -shared -L/usr/X11R6/lib -lX11 -lXext -o $@ $^
+$(PLUGIN_X11): %.o: %.c
+       $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
 
-plugins/intf/intf_glide.so plugins/vout/vout_glide.so: %.so: %.c
-       $(CC) $(CCFLAGS) $(CFLAGS) -I/usr/include/glide -lglide2x -shared -o $@ $<
+lib/mga.so: $(PLUGIN_MGA)
+       ld -shared -L/usr/X11R6/lib -lX11 -lXext -o $@ $^
+$(PLUGIN_MGA): %.o: %.c
+       $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
 
-plugins/intf/intf_ggi.so plugins/vout/vout_ggi.so: %.so: %.c
-       $(CC) $(CCFLAGS) $(CFLAGS) -lggi -shared -o $@ $<
+lib/gnome.so: $(PLUGIN_GNOME)
+       ld -shared `gnome-config --libs gnomeui | sed 's,-rdynamic,,'` -o $@ $^
+$(PLUGIN_GNOME): %.o: %.c
+       $(CC) $(CCFLAGS) $(CFLAGS) `gnome-config --cflags gnomeui`-c -o $@ $<
 
-plugins/intf/intf_beos.so: %.so: %.cpp
-       $(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
+lib/glide.so: $(PLUGIN_GLIDE)
+       ld -shared -lglide2x -o $@ $^
+$(PLUGIN_GLIDE): %.o: %.c
+       $(CC) $(CCFLAGS) $(CFLAGS) -I/usr/include/glide -c -o $@ $<
 
-plugins/vout/vout_beos.so: %.so: %.cpp
-       $(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
-               
+lib/ggi.so: $(PLUGIN_GGI)
+       ld -shared -lggi -o $@ $^
+$(PLUGIN_GGI): %.o: %.c
+       $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
 
 ################################################################################
 # Note on generic rules and dependancies
diff --git a/README b/README
index 17aeeaf7caf55ba53990927a1c03fd72bdb4bef3..f9803ea21fff89da9116fa4947978f7698826483 100644 (file)
--- a/README
+++ b/README
@@ -1,44 +1,48 @@
+README for vlc, the VideoLAN Client
 
-               README for vlc, the VideoLAN Client
 
-
-
-... Introduction
+Introduction
+============
 
 [ nothing appropriate yet ]
 
 
+Building, Installing and Running VideoLAN
+=========================================
 
-... Building VideoLAN
+See the INSTALL file for this.
 
-A typical way to configure the vlc is :
 
-   ./configure --prefix=/usr --enable-ppro --enable-mmx --enable-gnome
+Troubleshooting
+===============
 
-See `./configure --help' for more information.
+A mailing-list has been set up for support and discussion about the
+vlc. Its address is :
 
-Then, run `make'.
+   <vlc@videolan.org>
 
+To subscribe, send a mail to <listar@videolan.org> with the following
+words in the mail body :
 
-... Running VideoLAN
+   subscribe vlc
 
-[ nothing appropriate yet ]
+To unsubscribe, do the same with the words :
 
+   unsubscribe vlc
 
 
-... Troubleshooting
+When reporting bugs, try to be as precise as possible (which OS, which
+distribution, what plugins you were trying, and so on).
 
-[ nothing appropriate yet ]
 
-
-
-... Resources
+Resources
+=========
 
 [ nothing appropriate yet ]
 
 
-
-... The team
+The team
+========
 
 The following teachers were involved in the VideoLAN project :
 
@@ -52,6 +56,7 @@ The following students were members of the VideoLAN team :
   Antoine Brenner <brenner@via.ecp.fr>
   RĂ©gis Duchesne <regis@via.ecp.fr>
   Alexandre Francois <francois@via.ecp.fr>
+  Christian Gross <gross@via.ecp.fr>
   Hugo Haas <hugo@via.ecp.fr>
   Mikael Journo <mj32@cornell.edu>
   Michel Lespinasse <walken@wrs.com>
@@ -61,7 +66,6 @@ The following students were members of the VideoLAN team :
 
   Olivier Baxa <oli@via.ecp.fr>
   Patrice Bazerque <patrice.bazerque@via.ecp.fr>
-  Etienne Bernard <eb@via.ecp.fr>
   Arnaud Bienvenu <arnaud.bienvenu@via.ecp.fr>
   RĂ©gis ClĂ©ment <clement@via.ecp.fr>
   Alexandre Duret <alex@via.ecp.fr>
index 39dda5dcc4aaf1bfa36423e644ac1772e0ceb515..0ced8394c32d22139bdee9e83964c4f2a6e25732 100755 (executable)
--- a/configure
+++ b/configure
@@ -12,23 +12,21 @@ ac_help=
 ac_default_prefix=/usr/local
 # Any additions from configure.in:
 ac_help="$ac_help
-  --enable-vout-dummy     dummy video support (default enabled)"
+  --enable-dsp            Linux /dev/dsp support (default enabled)"
 ac_help="$ac_help
-  --enable-x11            X11 video support (default enabled)"
+  --enable-dummy          dummy audio and video support (default enabled)"
 ac_help="$ac_help
-  --enable-fb             Linux framebuffer video support (default disabled)"
+  --enable-esd            Esound library support (default disabled)"
 ac_help="$ac_help
-  --enable-gnome          Gnome video support (default disabled)"
+  --enable-fb             Linux framebuffer support (default disabled)"
 ac_help="$ac_help
-  --enable-glide          Glide (3dfx) video support (default disabled)"
+  --enable-ggi            GGI support (default disabled)"
 ac_help="$ac_help
-  --enable-ggi            GGI video support (default disabled)"
+  --enable-glide          Glide (3dfx) support (default disabled)"
 ac_help="$ac_help
-  --enable-aout-dummy     dummy audio support (default enabled)"
+  --enable-gnome          Gnome support (default disabled)"
 ac_help="$ac_help
-  --enable-dsp            Linux /dev/dsp support (default enabled)"
-ac_help="$ac_help
-  --enable-esd            Esound library support (default disabled)"
+  --enable-x11            X11 support (default enabled)"
 ac_help="$ac_help
   --enable-ppro           Enable PentiumPro optimizations (default is no)"
 ac_help="$ac_help
@@ -571,7 +569,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:575: checking host system type" >&5
+echo "configure:573: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -592,13 +590,13 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$host" 1>&6
 
 
-VLC_VERSION=0.1.99c
+VLC_VERSION=0.1.99d
 
 VLC_CODENAME=Onatopp
 
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:602: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:600: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -627,7 +625,7 @@ fi
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:631: checking for $ac_word" >&5
+echo "configure:629: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -657,7 +655,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:661: checking for $ac_word" >&5
+echo "configure:659: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -708,7 +706,7 @@ fi
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:712: checking for $ac_word" >&5
+echo "configure:710: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -740,7 +738,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:744: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:742: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -751,12 +749,12 @@ cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 755 "configure"
+#line 753 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:760: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -782,12 +780,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:786: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:784: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:791: checking whether we are using GNU C" >&5
+echo "configure:789: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -796,7 +794,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:800: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:798: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -815,7 +813,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:819: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:817: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -847,7 +845,7 @@ else
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:851: checking how to run the C preprocessor" >&5
+echo "configure:849: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -862,13 +860,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 866 "configure"
+#line 864 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:872: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:870: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -879,13 +877,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 883 "configure"
+#line 881 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:889: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:887: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -896,13 +894,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 900 "configure"
+#line 898 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:906: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:904: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -939,7 +937,7 @@ echo "$ac_t""$CPP" 1>&6
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:943: checking for a BSD compatible install" >&5
+echo "configure:941: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -993,12 +991,12 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:997: checking for working const" >&5
+echo "configure:995: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1002 "configure"
+#line 1000 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1047,7 +1045,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:1051: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1049: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -1068,14 +1066,14 @@ EOF
 fi
 
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:1072: checking whether byte ordering is bigendian" >&5
+echo "configure:1070: checking whether byte ordering is bigendian" >&5
 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat > conftest.$ac_ext <<EOF
-#line 1079 "configure"
+#line 1077 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -1086,11 +1084,11 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:1090: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1088: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 1094 "configure"
+#line 1092 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -1101,7 +1099,7 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:1105: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1103: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -1121,7 +1119,7 @@ if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 1125 "configure"
+#line 1123 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -1134,7 +1132,7 @@ main () {
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:1138: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1136: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_bigendian=no
 else
@@ -1161,12 +1159,12 @@ fi
 for ac_func in gettimeofday select strerror strtod strtol
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1165: checking for $ac_func" >&5
+echo "configure:1163: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1170 "configure"
+#line 1168 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1189,7 +1187,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1193: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1191: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1216,12 +1214,12 @@ done
 for ac_func in setenv putenv
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1220: checking for $ac_func" >&5
+echo "configure:1218: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1225 "configure"
+#line 1223 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1244,7 +1242,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1248: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1269,12 +1267,12 @@ fi
 done
 
 echo $ac_n "checking for connect""... $ac_c" 1>&6
-echo "configure:1273: checking for connect" >&5
+echo "configure:1271: checking for connect" >&5
 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1278 "configure"
+#line 1276 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char connect(); below.  */
@@ -1297,7 +1295,7 @@ connect();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1301: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1299: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_connect=yes"
 else
@@ -1315,7 +1313,7 @@ if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
-echo "configure:1319: checking for connect in -lsocket" >&5
+echo "configure:1317: checking for connect in -lsocket" >&5
 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1323,7 +1321,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1327 "configure"
+#line 1325 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1334,7 +1332,7 @@ int main() {
 connect()
 ; return 0; }
 EOF
-if { (eval echo configure:1338: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1336: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1364,12 +1362,12 @@ fi
 fi
 
 echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
-echo "configure:1368: checking for gethostbyname" >&5
+echo "configure:1366: checking for gethostbyname" >&5
 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1373 "configure"
+#line 1371 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char gethostbyname(); below.  */
@@ -1392,7 +1390,7 @@ gethostbyname();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1396: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1394: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_gethostbyname=yes"
 else
@@ -1410,7 +1408,7 @@ if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
-echo "configure:1414: checking for gethostbyname in -lnsl" >&5
+echo "configure:1412: checking for gethostbyname in -lnsl" >&5
 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1418,7 +1416,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1422 "configure"
+#line 1420 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1429,7 +1427,7 @@ int main() {
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:1433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1459,12 +1457,12 @@ fi
 fi
 
 echo $ac_n "checking for nanosleep""... $ac_c" 1>&6
-echo "configure:1463: checking for nanosleep" >&5
+echo "configure:1461: checking for nanosleep" >&5
 if eval "test \"`echo '$''{'ac_cv_func_nanosleep'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1468 "configure"
+#line 1466 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char nanosleep(); below.  */
@@ -1487,7 +1485,7 @@ nanosleep();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1489: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_nanosleep=yes"
 else
@@ -1505,7 +1503,7 @@ if eval "test \"`echo '$ac_cv_func_'nanosleep`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for nanosleep in -lrt""... $ac_c" 1>&6
-echo "configure:1509: checking for nanosleep in -lrt" >&5
+echo "configure:1507: checking for nanosleep in -lrt" >&5
 ac_lib_var=`echo rt'_'nanosleep | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1513,7 +1511,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lrt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1517 "configure"
+#line 1515 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1524,7 +1522,7 @@ int main() {
 nanosleep()
 ; return 0; }
 EOF
-if { (eval echo configure:1528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1550,7 +1548,7 @@ EOF
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for nanosleep in -lposix4""... $ac_c" 1>&6
-echo "configure:1554: checking for nanosleep in -lposix4" >&5
+echo "configure:1552: checking for nanosleep in -lposix4" >&5
 ac_lib_var=`echo posix4'_'nanosleep | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1558,7 +1556,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lposix4  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1562 "configure"
+#line 1560 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1569,7 +1567,7 @@ int main() {
 nanosleep()
 ; return 0; }
 EOF
-if { (eval echo configure:1573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1571: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1603,12 +1601,12 @@ fi
 for ac_func in usleep
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1607: checking for $ac_func" >&5
+echo "configure:1605: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1612 "configure"
+#line 1610 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1631,7 +1629,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1635: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1633: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1656,12 +1654,12 @@ fi
 done
 
 echo $ac_n "checking for inet_aton""... $ac_c" 1>&6
-echo "configure:1660: checking for inet_aton" >&5
+echo "configure:1658: checking for inet_aton" >&5
 if eval "test \"`echo '$''{'ac_cv_func_inet_aton'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1665 "configure"
+#line 1663 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char inet_aton(); below.  */
@@ -1684,7 +1682,7 @@ inet_aton();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1686: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_inet_aton=yes"
 else
@@ -1702,7 +1700,7 @@ if eval "test \"`echo '$ac_cv_func_'inet_aton`\" = yes"; then
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for inet_aton in -lresolv""... $ac_c" 1>&6
-echo "configure:1706: checking for inet_aton in -lresolv" >&5
+echo "configure:1704: checking for inet_aton in -lresolv" >&5
 ac_lib_var=`echo resolv'_'inet_aton | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1710,7 +1708,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lresolv  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1714 "configure"
+#line 1712 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1721,7 +1719,7 @@ int main() {
 inet_aton()
 ; return 0; }
 EOF
-if { (eval echo configure:1725: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1723: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1754,17 +1752,17 @@ for ac_hdr in unistd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1758: checking for $ac_hdr" >&5
+echo "configure:1756: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1763 "configure"
+#line 1761 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1768: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1766: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1793,12 +1791,12 @@ done
 for ac_func in getpagesize
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1797: checking for $ac_func" >&5
+echo "configure:1795: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1802 "configure"
+#line 1800 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1821,7 +1819,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1846,7 +1844,7 @@ fi
 done
 
 echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:1850: checking for working mmap" >&5
+echo "configure:1848: checking for working mmap" >&5
 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1854,7 +1852,7 @@ else
   ac_cv_func_mmap_fixed_mapped=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 1858 "configure"
+#line 1856 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test.
@@ -1997,7 +1995,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:2001: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_mmap_fixed_mapped=yes
 else
@@ -2020,12 +2018,12 @@ EOF
 fi
 
 echo $ac_n "checking for vprintf""... $ac_c" 1>&6
-echo "configure:2024: checking for vprintf" >&5
+echo "configure:2022: checking for vprintf" >&5
 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2029 "configure"
+#line 2027 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vprintf(); below.  */
@@ -2048,7 +2046,7 @@ vprintf();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2052: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2050: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_vprintf=yes"
 else
@@ -2072,12 +2070,12 @@ fi
 
 if test "$ac_cv_func_vprintf" != yes; then
 echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
-echo "configure:2076: checking for _doprnt" >&5
+echo "configure:2074: checking for _doprnt" >&5
 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2081 "configure"
+#line 2079 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char _doprnt(); below.  */
@@ -2100,7 +2098,7 @@ _doprnt();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2102: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func__doprnt=yes"
 else
@@ -2125,12 +2123,12 @@ fi
 fi
 
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:2129: checking return type of signal handlers" >&5
+echo "configure:2127: checking return type of signal handlers" >&5
 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2134 "configure"
+#line 2132 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -2147,7 +2145,7 @@ int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:2151: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2149: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -2166,7 +2164,7 @@ EOF
 
 
 echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:2170: checking for dlopen in -ldl" >&5
+echo "configure:2168: checking for dlopen in -ldl" >&5
 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2174,7 +2172,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ldl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2178 "configure"
+#line 2176 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2185,7 +2183,7 @@ int main() {
 dlopen()
 ; return 0; }
 EOF
-if { (eval echo configure:2189: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2213,7 +2211,7 @@ else
 fi
 
 echo $ac_n "checking for optarg in -lgnugetopt""... $ac_c" 1>&6
-echo "configure:2217: checking for optarg in -lgnugetopt" >&5
+echo "configure:2215: checking for optarg in -lgnugetopt" >&5
 ac_lib_var=`echo gnugetopt'_'optarg | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2221,7 +2219,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgnugetopt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2225 "configure"
+#line 2223 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2232,7 +2230,7 @@ int main() {
 optarg()
 ; return 0; }
 EOF
-if { (eval echo configure:2236: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2260,7 +2258,7 @@ else
 fi
 
 echo $ac_n "checking for _ in -lbe""... $ac_c" 1>&6
-echo "configure:2264: checking for _ in -lbe" >&5
+echo "configure:2262: checking for _ in -lbe" >&5
 ac_lib_var=`echo be'_'_ | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2268,7 +2266,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lbe  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2272 "configure"
+#line 2270 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2279,7 +2277,7 @@ int main() {
 _()
 ; return 0; }
 EOF
-if { (eval echo configure:2283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2281: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2307,7 +2305,7 @@ else
 fi
 
 echo $ac_n "checking for _ in -lgame""... $ac_c" 1>&6
-echo "configure:2311: checking for _ in -lgame" >&5
+echo "configure:2309: checking for _ in -lgame" >&5
 ac_lib_var=`echo game'_'_ | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2315,7 +2313,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgame  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2319 "configure"
+#line 2317 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2326,7 +2324,7 @@ int main() {
 _()
 ; return 0; }
 EOF
-if { (eval echo configure:2330: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2328: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2354,7 +2352,7 @@ else
 fi
 
 echo $ac_n "checking for _ in -lroot""... $ac_c" 1>&6
-echo "configure:2358: checking for _ in -lroot" >&5
+echo "configure:2356: checking for _ in -lroot" >&5
 ac_lib_var=`echo root'_'_ | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2362,7 +2360,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lroot  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2366 "configure"
+#line 2364 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2373,7 +2371,7 @@ int main() {
 _()
 ; return 0; }
 EOF
-if { (eval echo configure:2377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2401,7 +2399,7 @@ else
 fi
 
 echo $ac_n "checking for powl in -lm""... $ac_c" 1>&6
-echo "configure:2405: checking for powl in -lm" >&5
+echo "configure:2403: checking for powl in -lm" >&5
 ac_lib_var=`echo m'_'powl | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2409,7 +2407,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2413 "configure"
+#line 2411 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2420,7 +2418,7 @@ int main() {
 powl()
 ; return 0; }
 EOF
-if { (eval echo configure:2424: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2422: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2448,7 +2446,7 @@ else
 fi
 
 echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
-echo "configure:2452: checking for pthread_create in -lpthread" >&5
+echo "configure:2450: checking for pthread_create in -lpthread" >&5
 ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2456,7 +2454,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lpthread  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2460 "configure"
+#line 2458 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2467,7 +2465,7 @@ int main() {
 pthread_create()
 ; return 0; }
 EOF
-if { (eval echo configure:2471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2469: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2495,7 +2493,7 @@ else
 fi
 
 echo $ac_n "checking for thread_create in -lthreads""... $ac_c" 1>&6
-echo "configure:2499: checking for thread_create in -lthreads" >&5
+echo "configure:2497: checking for thread_create in -lthreads" >&5
 ac_lib_var=`echo threads'_'thread_create | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2503,7 +2501,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lthreads  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2507 "configure"
+#line 2505 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2514,7 +2512,7 @@ int main() {
 thread_create()
 ; return 0; }
 EOF
-if { (eval echo configure:2518: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2543,12 +2541,12 @@ fi
 
 
 echo $ac_n "checking for getopt_long""... $ac_c" 1>&6
-echo "configure:2547: checking for getopt_long" >&5
+echo "configure:2545: checking for getopt_long" >&5
 if eval "test \"`echo '$''{'ac_cv_func_getopt_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2552 "configure"
+#line 2550 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char getopt_long(); below.  */
@@ -2571,7 +2569,7 @@ getopt_long();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_getopt_long=yes"
 else
@@ -2597,17 +2595,17 @@ for ac_hdr in fcntl.h sys/ioctl.h sys/time.h unistd.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2601: checking for $ac_hdr" >&5
+echo "configure:2599: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2606 "configure"
+#line 2604 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2611: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2609: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2637,17 +2635,17 @@ for ac_hdr in sys/soundcard.h machine/soundcard.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2641: checking for $ac_hdr" >&5
+echo "configure:2639: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2646 "configure"
+#line 2644 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2651: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2649: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2677,17 +2675,17 @@ for ac_hdr in dlfcn.h image.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2681: checking for $ac_hdr" >&5
+echo "configure:2679: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2686 "configure"
+#line 2684 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2691: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2689: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2717,17 +2715,17 @@ for ac_hdr in arpa/inet.h net/if.h netinet/in.h sys/socket.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2721: checking for $ac_hdr" >&5
+echo "configure:2719: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2726 "configure"
+#line 2724 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2731: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2729: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2758,17 +2756,17 @@ for ac_hdr in cthreads.h pthread.h kernel/scheduler.h kernel/OS.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2762: checking for $ac_hdr" >&5
+echo "configure:2760: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2767 "configure"
+#line 2765 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2772: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2770: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2796,12 +2794,12 @@ done
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2800: checking for working const" >&5
+echo "configure:2798: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2805 "configure"
+#line 2803 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2850,7 +2848,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
-if { (eval echo configure:2854: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2852: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -2871,12 +2869,12 @@ EOF
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2875: checking for ANSI C header files" >&5
+echo "configure:2873: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2880 "configure"
+#line 2878 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2884,7 +2882,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2888: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2886: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2901,7 +2899,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2905 "configure"
+#line 2903 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2919,7 +2917,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2923 "configure"
+#line 2921 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2940,7 +2938,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2944 "configure"
+#line 2942 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2951,7 +2949,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:2955: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2953: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2975,12 +2973,12 @@ EOF
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:2979: checking for size_t" >&5
+echo "configure:2977: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2984 "configure"
+#line 2982 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -3008,12 +3006,12 @@ EOF
 fi
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:3012: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:3010: checking whether time.h and sys/time.h may both be included" >&5
 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3017 "configure"
+#line 3015 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -3022,7 +3020,7 @@ int main() {
 struct tm *tp;
 ; return 0; }
 EOF
-if { (eval echo configure:3026: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3024: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -3043,65 +3041,57 @@ EOF
 fi
 
 
+# Check whether --enable-dsp or --disable-dsp was given.
+if test "${enable_dsp+set}" = set; then
+  enableval="$enable_dsp"
+  :
+fi
+
+if test x$enable_dsp != xno; then PLUGINS=${PLUGINS}"dsp "; fi
 # Check whether --enable-dummy or --disable-dummy was given.
 if test "${enable_dummy+set}" = set; then
   enableval="$enable_dummy"
   :
 fi
 
-if test x$enable_vout_dummy != xno; then VOUT=${VOUT}"dummy "; fi
-# Check whether --enable-x11 or --disable-x11 was given.
-if test "${enable_x11+set}" = set; then
-  enableval="$enable_x11"
-  :
+if test x$enable_dummy != xno; then PLUGINS=${PLUGINS}"dummy "; fi
+# Check whether --enable-esd or --disable-esd was given.
+if test "${enable_esd+set}" = set; then
+  enableval="$enable_esd"
+  if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"esd "; fi
 fi
 
-if test x$enable_x11 != xno; then VOUT=${VOUT}"x11 "; fi
 # Check whether --enable-fb or --disable-fb was given.
 if test "${enable_fb+set}" = set; then
   enableval="$enable_fb"
-  if test x$enable_fb = xyes; then VOUT=${VOUT}"fb "; fi
+  if test x$enable_fb = xyes; then PLUGINS=${PLUGINS}"fb "; fi
 fi
 
-# Check whether --enable-gnome or --disable-gnome was given.
-if test "${enable_gnome+set}" = set; then
-  enableval="$enable_gnome"
-  if test x$enable_gnome = xyes; then VOUT=${VOUT}"gnome "; fi
+# Check whether --enable-ggi or --disable-ggi was given.
+if test "${enable_ggi+set}" = set; then
+  enableval="$enable_ggi"
+  if test x$enable_ggi = xyes; then PLUGINS=${PLUGINS}"ggi "; fi
 fi
 
 # Check whether --enable-glide or --disable-glide was given.
 if test "${enable_glide+set}" = set; then
   enableval="$enable_glide"
-  if test x$enable_glide = xyes; then VOUT=${VOUT}"glide "; fi
+  if test x$enable_glide = xyes; then PLUGINS=${PLUGINS}"glide "; fi
 fi
 
-# Check whether --enable-ggi or --disable-ggi was given.
-if test "${enable_ggi+set}" = set; then
-  enableval="$enable_ggi"
-  if test x$enable_ggi = xyes; then VOUT=${VOUT}"ggi "; fi
-fi
-
-
-# Check whether --enable-dummy or --disable-dummy was given.
-if test "${enable_dummy+set}" = set; then
-  enableval="$enable_dummy"
-  :
+# Check whether --enable-gnome or --disable-gnome was given.
+if test "${enable_gnome+set}" = set; then
+  enableval="$enable_gnome"
+  if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; fi
 fi
 
-if test x$enable_aout_dummy != xno; then AOUT=${AOUT}"dummy "; fi
-# Check whether --enable-dsp or --disable-dsp was given.
-if test "${enable_dsp+set}" = set; then
-  enableval="$enable_dsp"
+# Check whether --enable-x11 or --disable-x11 was given.
+if test "${enable_x11+set}" = set; then
+  enableval="$enable_x11"
   :
 fi
 
-if test x$enable_dsp != xno; then AOUT=${AOUT}"dsp "; fi
-# Check whether --enable-esd or --disable-esd was given.
-if test "${enable_esd+set}" = set; then
-  enableval="$enable_esd"
-  if test x$enable_gnome = xyes; then AOUT=${AOUT}"esd "; fi
-fi
-
+if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi
 
 ARCH=${host_cpu}
 # Check whether --enable-ppro or --disable-ppro was given.
@@ -3121,15 +3111,13 @@ SYS=${host_os}
 
 # special cases
 if test x$host_os = xbeos; then
-    VOUT="dummy beos"
-    AOUT="dummy beos"
+    PLUGINS="dummy beos"
 fi
 
 
 
 
 
-
 trap '' 1 2 15
 cat > confcache <<\EOF
 # This file is a shell script that caches the results of configure
@@ -3279,8 +3267,7 @@ s%@INSTALL_DATA@%$INSTALL_DATA%g
 s%@LIBOBJS@%$LIBOBJS%g
 s%@SYS@%$SYS%g
 s%@ARCH@%$ARCH%g
-s%@VOUT@%$VOUT%g
-s%@AOUT@%$AOUT%g
+s%@PLUGINS@%$PLUGINS%g
 
 CEOF
 EOF
@@ -3507,6 +3494,5 @@ vlc configuration
 vlc version           : ${VLC_VERSION}
 system                : ${SYS}
 architecture          : ${ARCH}
-vout                  : ${VOUT}
-aout                  : ${AOUT}
+plugins               : ${PLUGINS}
 "
index 3e54d719a0bde4ef072420522d30aa86b27127c2..8089b09f87e78ebcf6dbefac7469f1c4a0cbb294 100644 (file)
@@ -4,7 +4,7 @@ AC_CONFIG_HEADER(include/defs.h)
 
 AC_CANONICAL_HOST
 
-VLC_VERSION=0.1.99c
+VLC_VERSION=0.1.99d
 AC_SUBST(VLC_VERSION)
 VLC_CODENAME=Onatopp
 AC_SUBST(VLC_CODENAME)
@@ -58,34 +58,30 @@ AC_C_CONST
 AC_TYPE_SIZE_T
 AC_HEADER_TIME
 
-AC_ARG_ENABLE(dummy,
-  [  --enable-vout-dummy     dummy video support (default enabled)])
-if test x$enable_vout_dummy != xno; then VOUT=${VOUT}"dummy "; fi
-AC_ARG_ENABLE(x11,
-  [  --enable-x11            X11 video support (default enabled)])
-if test x$enable_x11 != xno; then VOUT=${VOUT}"x11 "; fi
-AC_ARG_ENABLE(fb,
-  [  --enable-fb             Linux framebuffer video support (default disabled)],
-  [if test x$enable_fb = xyes; then VOUT=${VOUT}"fb "; fi])
-AC_ARG_ENABLE(gnome,
-  [  --enable-gnome          Gnome video support (default disabled)],
-  [if test x$enable_gnome = xyes; then VOUT=${VOUT}"gnome "; fi])
-AC_ARG_ENABLE(glide,
-  [  --enable-glide          Glide (3dfx) video support (default disabled)],
-  [if test x$enable_glide = xyes; then VOUT=${VOUT}"glide "; fi])
-AC_ARG_ENABLE(ggi,
-  [  --enable-ggi            GGI video support (default disabled)],
-  [if test x$enable_ggi = xyes; then VOUT=${VOUT}"ggi "; fi])
-
-AC_ARG_ENABLE(dummy,
-  [  --enable-aout-dummy     dummy audio support (default enabled)])
-if test x$enable_aout_dummy != xno; then AOUT=${AOUT}"dummy "; fi
 AC_ARG_ENABLE(dsp,
   [  --enable-dsp            Linux /dev/dsp support (default enabled)])
-if test x$enable_dsp != xno; then AOUT=${AOUT}"dsp "; fi
+if test x$enable_dsp != xno; then PLUGINS=${PLUGINS}"dsp "; fi
+AC_ARG_ENABLE(dummy,
+  [  --enable-dummy          dummy audio and video support (default enabled)])
+if test x$enable_dummy != xno; then PLUGINS=${PLUGINS}"dummy "; fi
 AC_ARG_ENABLE(esd,
   [  --enable-esd            Esound library support (default disabled)],
-  [if test x$enable_gnome = xyes; then AOUT=${AOUT}"esd "; fi])
+  [if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"esd "; fi])
+AC_ARG_ENABLE(fb,
+  [  --enable-fb             Linux framebuffer support (default disabled)],
+  [if test x$enable_fb = xyes; then PLUGINS=${PLUGINS}"fb "; fi])
+AC_ARG_ENABLE(ggi,
+  [  --enable-ggi            GGI support (default disabled)],
+  [if test x$enable_ggi = xyes; then PLUGINS=${PLUGINS}"ggi "; fi])
+AC_ARG_ENABLE(glide,
+  [  --enable-glide          Glide (3dfx) support (default disabled)],
+  [if test x$enable_glide = xyes; then PLUGINS=${PLUGINS}"glide "; fi])
+AC_ARG_ENABLE(gnome,
+  [  --enable-gnome          Gnome support (default disabled)],
+  [if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; fi])
+AC_ARG_ENABLE(x11,
+  [  --enable-x11            X11 support (default enabled)])
+if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi
 
 ARCH=${host_cpu}
 AC_ARG_ENABLE(ppro,
@@ -99,14 +95,12 @@ SYS=${host_os}
 
 # special cases
 if test x$host_os = xbeos; then
-    VOUT="dummy beos"
-    AOUT="dummy beos"
+    PLUGINS="dummy beos"
 fi
 
 AC_SUBST(SYS)
 AC_SUBST(ARCH)
-AC_SUBST(VOUT)
-AC_SUBST(AOUT)
+AC_SUBST(PLUGINS)
 
 AC_OUTPUT([Makefile include/config.h])
 
@@ -116,6 +110,5 @@ vlc configuration
 vlc version           : ${VLC_VERSION}
 system                : ${SYS}
 architecture          : ${ARCH}
-vout                  : ${VOUT}
-aout                  : ${AOUT}
+plugins               : ${PLUGINS}
 "
index beb24a39f430913a13839fc52b83cb7fb558f08c..4972fd7e02b2ebaf70b7f6a3844f7387af26e3b6 100644 (file)
@@ -1,3 +1,9 @@
+vlc (0.1.99d) unstable; urgency=low
+
+  * .deb is now more lintian-friendly
+
+ -- Samuel Hocevar <sam@via.ecp.fr>  Tue, 20 Jun 2000 14:17:33 +0200
+
 vlc (0.1.99c) unstable; urgency=low
 
   * Caught Delete Window event in Gnome and X11 modes
index a258cbaa9d6c1b9f26bc7267df522f35576332c4..31fa941d9ce3f49d0de2bf8ee978a444f26c0214 100644 (file)
@@ -26,7 +26,7 @@ typedef int plugin_id_t;
 typedef void* plugin_id_t;
 #endif
 
-int    RequestPlugin     ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name );
+int    RequestPlugin     ( plugin_id_t * p_plugin, char * psz_name );
 void   TrashPlugin       ( plugin_id_t p_plugin );
 void * GetPluginFunction ( plugin_id_t plugin, char *name );
 
diff --git a/plugins/beos/aout_beos.cpp b/plugins/beos/aout_beos.cpp
new file mode 100644 (file)
index 0000000..0a2cdd1
--- /dev/null
@@ -0,0 +1,238 @@
+/*****************************************************************************
+ * aout_beos.cpp: beos interface
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ * Samuel Hocevar <sam@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdio.h>
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <sys/types.h>                        /* on BSD, uio.h needs types.h */
+#include <sys/uio.h>                                            /* "input.h" */
+#include <kernel/OS.h>
+#include <View.h>
+#include <Application.h>
+#include <Message.h>
+#include <Locker.h>
+#include <media/MediaDefs.h>
+#include <game/PushGameSound.h>
+#include <malloc.h>
+#include <string.h>
+
+extern "C"
+{
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "audio_output.h"
+
+#include "intf_msg.h"
+
+#include "main.h"
+}
+
+/*****************************************************************************
+ * aout_sys_t: esd audio output method descriptor
+ *****************************************************************************
+ * This structure is part of the audio output thread descriptor.
+ * It describes some esd specific variables.
+ *****************************************************************************/
+typedef struct aout_sys_s
+{
+    BPushGameSound * p_sound;
+    gs_audio_format * p_format;
+    void * p_buffer;
+    long i_buffer_size;
+    long i_buffer_pos;
+
+} aout_sys_t;
+
+extern "C"
+{
+
+/*****************************************************************************
+ * aout_SysOpen: opens a BPushGameSound
+ *****************************************************************************/
+int aout_SysOpen( aout_thread_t *p_aout )
+{
+    /* Allocate structure */
+    p_aout->p_sys = (aout_sys_t*) malloc( sizeof( aout_sys_t ) );
+    if( p_aout->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Allocate gs_audio_format */
+    p_aout->p_sys->p_format = (gs_audio_format *) malloc( sizeof( gs_audio_format ) );
+    if( p_aout->p_sys->p_format == NULL )
+    {
+        free( p_aout->p_sys );
+        intf_ErrMsg("error: cannot allocate memory for gs_audio_format\n" );
+        return( 1 );
+    }
+
+    /* Initialize some variables */
+    p_aout->i_format = AOUT_DEFAULT_FORMAT;
+    p_aout->i_channels = 1 + main_GetIntVariable( AOUT_STEREO_VAR,
+                                                  AOUT_STEREO_DEFAULT );
+    p_aout->l_rate = main_GetIntVariable( AOUT_RATE_VAR, AOUT_RATE_DEFAULT );
+
+    p_aout->p_sys->p_format->frame_rate = 44100.0;
+    p_aout->p_sys->p_format->channel_count = p_aout->i_channels;
+    p_aout->p_sys->p_format->format = gs_audio_format::B_GS_S16;
+    p_aout->p_sys->p_format->byte_order = B_MEDIA_LITTLE_ENDIAN;
+    p_aout->p_sys->p_format->buffer_size = 8192;
+
+    /* Allocate BPushGameSound */
+    p_aout->p_sys->p_sound = new BPushGameSound( 8192,
+                                                 p_aout->p_sys->p_format,
+                                                 2, NULL );
+    if( p_aout->p_sys->p_sound == NULL )
+    {
+        free( p_aout->p_sys->p_format );
+        free( p_aout->p_sys );
+        intf_ErrMsg("error: cannot allocate memory for BPushGameSound\n" );
+        return( 1 );
+    }
+
+    if( p_aout->p_sys->p_sound->InitCheck() != B_OK )
+    {
+        free( p_aout->p_sys->p_format );
+        free( p_aout->p_sys );
+        intf_ErrMsg("error: cannot allocate memory for BPushGameSound\n" );
+        return( 1 );
+    }
+
+    p_aout->p_sys->p_sound->StartPlaying( );
+
+    p_aout->p_sys->p_sound->LockForCyclic( &p_aout->p_sys->p_buffer,
+                            (size_t *)&p_aout->p_sys->i_buffer_size );
+
+    return( 0 );
+}
+/*****************************************************************************
+ * aout_SysReset: resets the dsp
+ *****************************************************************************/
+int aout_SysReset( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetFormat: sets the dsp output format
+ *****************************************************************************/
+int aout_SysSetFormat( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetChannels: sets the dsp's stereo or mono mode
+ *****************************************************************************/
+int aout_SysSetChannels( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetRate: sets the dsp's audio output rate
+ *****************************************************************************/
+int aout_SysSetRate( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysGetBufInfo: buffer status query
+ *****************************************************************************/
+long aout_SysGetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
+{
+
+    long i_hard_pos = 4 * p_aout->p_sys->p_sound->CurrentPosition();
+
+    /*fprintf( stderr, "read 0x%.6lx - write 0x%.6lx = ",
+             i_hard_pos, p_aout->p_sys->i_buffer_pos );*/
+
+    if( i_hard_pos < p_aout->p_sys->i_buffer_pos )
+    {
+        i_hard_pos += p_aout->p_sys->i_buffer_size;
+    }
+
+    /*fprintf( stderr, "0x%.6lx\n", i_hard_pos - p_aout->p_sys->i_buffer_pos ); */
+
+    return( (p_aout->p_sys->i_buffer_size - (i_hard_pos - p_aout->p_sys->i_buffer_pos)) );
+}
+
+/*****************************************************************************
+ * aout_SysPlaySamples: plays a sound samples buffer
+ *****************************************************************************
+ * This function writes a buffer of i_length bytes in the dsp
+ *****************************************************************************/
+void aout_SysPlaySamples( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+{
+    long i_newbuf_pos;
+
+    //fprintf( stderr, "writing %i\n", i_size );
+
+    if( (i_newbuf_pos = p_aout->p_sys->i_buffer_pos + i_size)
+              > p_aout->p_sys->i_buffer_size )
+    {
+        memcpy( (void *)((int)p_aout->p_sys->p_buffer
+                        + p_aout->p_sys->i_buffer_pos),
+                buffer,
+                p_aout->p_sys->i_buffer_size - p_aout->p_sys->i_buffer_pos );
+
+        memcpy( (void *)((int)p_aout->p_sys->p_buffer),
+                buffer,
+                i_size - ( p_aout->p_sys->i_buffer_size
+                             - p_aout->p_sys->i_buffer_pos ) );
+
+        p_aout->p_sys->i_buffer_pos = i_newbuf_pos - p_aout->p_sys->i_buffer_size;
+    }
+    else
+    {
+        memcpy( (void *)((int)p_aout->p_sys->p_buffer + p_aout->p_sys->i_buffer_pos),
+                buffer, i_size );
+        p_aout->p_sys->i_buffer_pos = i_newbuf_pos;
+    }
+}
+
+/*****************************************************************************
+ * aout_SysClose: closes the dsp audio device
+ *****************************************************************************/
+void aout_SysClose( aout_thread_t *p_aout )
+{
+    p_aout->p_sys->p_sound->UnlockCyclic();
+    p_aout->p_sys->p_sound->StopPlaying( );
+    delete p_aout->p_sys->p_sound;
+    free( p_aout->p_sys->p_format );
+    free( p_aout->p_sys );
+}
+
+} /* extern "C" */
+
diff --git a/plugins/beos/intf_beos.cpp b/plugins/beos/intf_beos.cpp
new file mode 100644 (file)
index 0000000..51c13eb
--- /dev/null
@@ -0,0 +1,202 @@
+/*****************************************************************************
+ * intf_beos.cpp: beos interface
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ * Jean-Marc Dressler
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdio.h>
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <sys/types.h>                        /* on BSD, uio.h needs types.h */
+#include <sys/uio.h>                                            /* "input.h" */
+#include <kernel/OS.h>
+#include <View.h>
+#include <Application.h>
+#include <Message.h>
+#include <Locker.h>
+#include <DirectWindow.h>
+#include <malloc.h>
+#include <string.h>
+
+extern "C"
+{
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "input.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+#include "interface.h"
+
+#include "main.h"
+}
+
+#include "beos_window.h"
+
+/*****************************************************************************
+ * intf_sys_t: description and status of FB interface
+ *****************************************************************************/
+typedef struct intf_sys_s
+{
+    InterfaceWindow * p_window;
+    char              i_key;
+} intf_sys_t;
+
+/*****************************************************************************
+ * InterfaceWindow
+ *****************************************************************************/
+InterfaceWindow::InterfaceWindow( BRect frame, const char *name , intf_thread_t  *p_intf )
+    : BWindow(frame, name, B_TITLED_WINDOW, B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
+{
+    p_interface = p_intf;
+    SetName( "interface" );
+    
+    BView * p_view;
+    
+    p_view = new BView( Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW );
+    AddChild( p_view );
+    
+    Show();
+}
+
+InterfaceWindow::~InterfaceWindow()
+{
+}
+
+/*****************************************************************************
+ * InterfaceWindow::MessageReceived
+ *****************************************************************************/
+
+void InterfaceWindow::MessageReceived( BMessage * p_message )
+{
+    char * psz_key;
+    
+    switch( p_message->what )
+    {
+    case B_KEY_DOWN:
+        p_message->FindString( "bytes", (const char **)&psz_key );
+        p_interface->p_sys->i_key = psz_key[0];
+        break;
+        
+    default:
+        BWindow::MessageReceived( p_message );
+        break;
+    }
+}
+
+/*****************************************************************************
+ * InterfaceWindow::QuitRequested
+ *****************************************************************************/
+
+bool InterfaceWindow::QuitRequested()
+{
+    return( false );
+}
+
+
+extern "C"
+{
+
+/*****************************************************************************
+ * intf_SysCreate: initialize dummy interface
+ *****************************************************************************/
+int intf_SysCreate( intf_thread_t *p_intf )
+{
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = (intf_sys_t*) malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        return( 1 );
+    }
+    p_intf->p_sys->i_key = -1;
+    
+    /* Create the interface window */
+    p_intf->p_sys->p_window =
+        new InterfaceWindow( BRect( 100, 100, 200, 200 ), "Interface :)", p_intf );
+    if( p_intf->p_sys->p_window == 0 )
+    {
+        free( p_intf->p_sys );
+        intf_ErrMsg( "error: cannot allocate memory for InterfaceWindow\n" );
+        return( 1 );
+    }
+    
+    /* Spawn video output thread */
+    if( p_main->b_video )
+    {
+        p_intf->p_vout = vout_CreateThread( NULL, 0, 0, 0, NULL, 0, NULL );
+        if( p_intf->p_vout == NULL )                                /* error */
+        {
+            intf_ErrMsg("intf error: can't create output thread\n" );
+            return( 1 );
+        }
+    }
+    return( 0 );
+}
+
+/*****************************************************************************
+ * intf_SysDestroy: destroy dummy interface
+ *****************************************************************************/
+void intf_SysDestroy( intf_thread_t *p_intf )
+{
+    /* Close input thread, if any (blocking) */
+    if( p_intf->p_input )
+    {
+        input_DestroyThread( p_intf->p_input, NULL );
+    }
+
+    /* Close video output thread, if any (blocking) */
+    if( p_intf->p_vout )
+    {
+        vout_DestroyThread( p_intf->p_vout, NULL );
+    }
+
+    /* Destroy the interface window */
+    p_intf->p_sys->p_window->Lock();
+    p_intf->p_sys->p_window->Quit();    
+
+    /* Destroy structure */
+    free( p_intf->p_sys );
+}
+
+
+/*****************************************************************************
+ * intf_SysManage: event loop
+ *****************************************************************************/
+void intf_SysManage( intf_thread_t *p_intf )
+{
+    if( p_intf->p_sys->i_key != -1 )
+    {
+        intf_ProcessKey( p_intf, p_intf->p_sys->i_key );
+        p_intf->p_sys->i_key = -1;
+    }
+}
+
+} /* extern "C" */
diff --git a/plugins/beos/vout_beos.cpp b/plugins/beos/vout_beos.cpp
new file mode 100644 (file)
index 0000000..979ea3f
--- /dev/null
@@ -0,0 +1,559 @@
+/*****************************************************************************
+ * vout_beos.cpp: beos video output display method
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ * Jean-Marc Dressler
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <stdio.h>
+#include <string.h>                                            /* strerror() */
+#include <kernel/OS.h>
+#include <View.h>
+#include <Application.h>
+#include <DirectWindow.h>
+#include <Locker.h>
+#include <malloc.h>
+#include <string.h>
+
+extern "C"
+{
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+#include "interface.h" /* XXX maybe to remove if beos_window.h is splitted */
+
+#include "main.h"
+}
+
+#include "beos_window.h"
+
+#define WIDTH 128
+#define HEIGHT 64
+#define BITS_PER_PLANE 16
+#define BYTES_PER_PIXEL 2
+
+/*****************************************************************************
+ * vout_sys_t: dummy video output method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the dummy specific properties of an output thread.
+ *****************************************************************************/
+typedef struct vout_sys_s
+{
+    VideoWindow *         p_window;
+    
+    byte_t *              pp_buffer[2];
+    s32                   i_width;
+    s32                   i_height;
+} vout_sys_t;
+
+
+/*****************************************************************************
+ * beos_GetAppWindow : retrieve a BWindow pointer from the window name
+ *****************************************************************************/
+
+BWindow *beos_GetAppWindow(char *name)
+{
+    int32       index;
+    BWindow     *window;
+    
+    for (index = 0 ; ; index++)
+    {
+        window = be_app->WindowAt(index);
+        if (window == NULL)
+            break;
+        if (window->LockWithTimeout(200000) == B_OK)
+        {
+            if (strcmp(window->Name(), name) == 0)
+            {
+                window->Unlock();
+                break;
+            }
+            window->Unlock();
+        }
+    }
+    return window; 
+}
+
+/*****************************************************************************
+ * DrawingThread : thread that really does the drawing
+ *****************************************************************************/
+
+int32 DrawingThread(void *data)
+{
+    uint32 i, j, y;
+    uint64 *pp, *qq;
+    uint8 *p, *q;
+    uint32 byte_width;
+    uint32 height, bytes_per_line;
+    clipping_rect *clip;
+
+    VideoWindow *w;
+    w = (VideoWindow*) data;
+    
+    while(!w->fConnectionDisabled)
+    {
+        w->locker->Lock();
+        if( w->fConnected )
+        {
+            if( w->fDirty && (!w->fReady || w->i_screen_depth != w->p_vout->i_screen_depth) )
+            {
+                bytes_per_line = w->fRowBytes;
+                for( i=0 ; i < w->fNumClipRects ; i++ )
+                {
+                    clip = &(w->fClipList[i]);
+                    height = clip->bottom - clip->top +1;
+                    byte_width = w->i_bytes_per_pixel * ((clip->right - clip->left)+1);
+                    p = w->fBits + clip->top*w->fRowBytes + clip->left * w->i_bytes_per_pixel;
+                    for( y=0 ; y < height ; )
+                    {
+                        pp = (uint64*) p;
+                        for( j=0 ; j < byte_width/64 ; j++ )
+                        {
+                            *pp++ = 0;
+                            *pp++ = 0; 
+                            *pp++ = 0;
+                            *pp++ = 0; 
+                            *pp++ = 0;
+                            *pp++ = 0; 
+                            *pp++ = 0;
+                            *pp++ = 0; 
+                        }
+                        memset( pp , 0, byte_width & 63 );
+                        y++;
+                        p += bytes_per_line;
+                    }
+                }
+            }
+            else if( w->fDirty )
+            {
+                bytes_per_line = w->fRowBytes;
+                for( i=0 ; i < w->fNumClipRects ; i++ )
+                {
+                    clip = &(w->fClipList[i]);
+                    height = clip->bottom - clip->top +1;
+                    byte_width = w->i_bytes_per_pixel * ((clip->right - clip->left)+1);
+                    p = w->fBits + clip->top * bytes_per_line + clip->left * w->i_bytes_per_pixel;
+                    q = w->p_vout->p_sys->pp_buffer[ !w->p_vout->i_buffer_index ] +
+                        clip->top * w->p_vout->i_bytes_per_line + clip->left *
+                        w->p_vout->i_bytes_per_pixel;
+                    for( y=0 ; y < height ; )
+                    {
+                        pp = (uint64*) p;
+                        qq = (uint64*) q;
+                        for( j=0 ; j < byte_width/64 ; j++ )
+                        {
+                            *pp++ = *qq++;
+                            *pp++ = *qq++; 
+                            *pp++ = *qq++;
+                            *pp++ = *qq++; 
+                            *pp++ = *qq++;
+                            *pp++ = *qq++; 
+                            *pp++ = *qq++;
+                            *pp++ = *qq++; 
+                        }
+                        memcpy( pp , qq, byte_width & 63 );
+                        y++;
+                        p += bytes_per_line;
+                        q += w->p_vout->p_sys->i_width * w->p_vout->i_bytes_per_pixel;
+                    }
+                }
+            }
+            w->fDirty = false;
+        }
+        w->locker->Unlock();
+        snooze( 20000 );
+    }
+    return B_OK;
+}
+
+/*****************************************************************************
+ * VideoWindow constructor and destructor
+ *****************************************************************************/
+
+VideoWindow::VideoWindow(BRect frame, const char *name, vout_thread_t *p_video_output )
+        : BDirectWindow(frame, name, B_TITLED_WINDOW, B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
+{
+    BView * view;
+
+    fReady = false;
+    fConnected = false;
+    fConnectionDisabled = false;
+    locker = new BLocker();
+    fClipList = NULL;
+    fNumClipRects = 0;
+    p_vout = p_video_output;
+
+    view = new BView(Bounds(), "", B_FOLLOW_ALL, B_WILL_DRAW);
+    view->SetViewColor(B_TRANSPARENT_32_BIT);
+    AddChild(view);
+/*
+    if(!SupportsWindowMode())
+    {
+        SetFullScreen(true);
+    }
+*/
+    fDirty = false;
+    fDrawThreadID = spawn_thread(DrawingThread, "drawing_thread",
+                    B_DISPLAY_PRIORITY, (void*) this);
+    resume_thread(fDrawThreadID);
+    Show();
+}
+
+VideoWindow::~VideoWindow()
+{
+    int32 result;
+
+    fConnectionDisabled = true;
+    Hide();
+    Sync();
+    wait_for_thread(fDrawThreadID, &result);
+    free(fClipList);
+    delete locker;
+}
+
+/*****************************************************************************
+ * VideoWindow::DirectConnected
+ *****************************************************************************/
+
+void VideoWindow::DirectConnected(direct_buffer_info *info)
+{
+    unsigned int i;
+
+    if(!fConnected && fConnectionDisabled)
+    {
+        return;
+    }
+    locker->Lock();
+
+    switch(info->buffer_state & B_DIRECT_MODE_MASK)
+    {
+    case B_DIRECT_START:
+        fConnected = true;
+    case B_DIRECT_MODIFY:
+        fBits = (uint8*)((char*)info->bits +
+        (info->window_bounds.top) * info->bytes_per_row +
+        (info->window_bounds.left) * (info->bits_per_pixel>>3));;
+        
+        i_bytes_per_pixel = info->bits_per_pixel >> 3;
+        i_screen_depth = info->bits_per_pixel;
+        
+        fRowBytes = info->bytes_per_row;
+        fFormat = info->pixel_format;
+        fBounds = info->window_bounds;
+        fDirty = true;
+
+        if(fClipList)
+        {
+            free(fClipList);
+            fClipList = NULL;
+        }
+        fNumClipRects = info->clip_list_count;
+        fClipList = (clipping_rect*) malloc(fNumClipRects*sizeof(clipping_rect));
+        for( i=0 ; i<info->clip_list_count ; i++ )
+        {
+            fClipList[i].top = info->clip_list[i].top - info->window_bounds.top;
+            fClipList[i].left = info->clip_list[i].left - info->window_bounds.left;
+            fClipList[i].bottom = info->clip_list[i].bottom - info->window_bounds.top;
+            fClipList[i].right = info->clip_list[i].right - info->window_bounds.left;
+        }
+        break;
+    case B_DIRECT_STOP:
+        fConnected = false;
+        break;
+    }
+    locker->Unlock();
+}
+
+/*****************************************************************************
+ * VideoWindow::MessageReceived
+ *****************************************************************************/
+
+void VideoWindow::MessageReceived( BMessage * p_message )
+{
+    BWindow * p_win;
+    
+    switch( p_message->what )
+    {
+    case B_KEY_DOWN:
+        // post the message to the interface window which will handle it
+        p_win = beos_GetAppWindow( "interface" );
+        if( p_win != NULL )
+        {
+            p_win->PostMessage( p_message );
+        }
+        break;
+    
+    default:
+        BWindow::MessageReceived( p_message );
+        break;
+    }
+}
+
+/*****************************************************************************
+ * VideoWindow::QuitRequested
+ *****************************************************************************/
+
+bool VideoWindow::QuitRequested()
+{
+    return( true );
+}
+
+extern "C"
+{
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int     BeosOpenDisplay   ( vout_thread_t *p_vout );
+static void    BeosCloseDisplay  ( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * vout_SysCreate: allocates dummy video thread output method
+ *****************************************************************************
+ * This function allocates and initializes a dummy vout method.
+ *****************************************************************************/
+int vout_SysCreate( vout_thread_t *p_vout, char *psz_display,
+                    int i_root_window, void *p_data )
+{
+    /* Allocate structure */
+    p_vout->p_sys = (vout_sys_t*) malloc( sizeof( vout_sys_t ) );
+    if( p_vout->p_sys == NULL )
+    {
+        intf_ErrMsg( "error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+    
+    /* Set video window's size */
+    p_vout->i_width =  main_GetIntVariable( VOUT_WIDTH_VAR, VOUT_WIDTH_DEFAULT );
+    p_vout->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR, VOUT_HEIGHT_DEFAULT );
+
+    /* Open and initialize device */
+    if( BeosOpenDisplay( p_vout ) )
+    {
+        intf_ErrMsg("vout error: can't open display\n");
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysInit: initialize dummy video thread output method
+ *****************************************************************************/
+int vout_SysInit( vout_thread_t *p_vout )
+{
+    VideoWindow * p_win = p_vout->p_sys->p_window;
+    u32 i_page_size;
+
+    p_win->locker->Lock();
+
+    i_page_size =   p_vout->i_width * p_vout->i_height * p_vout->i_bytes_per_pixel;
+    
+    p_vout->p_sys->i_width =         p_vout->i_width;
+    p_vout->p_sys->i_height =        p_vout->i_height;    
+
+    /* Allocate memory for the 2 display buffers */
+    p_vout->p_sys->pp_buffer[0] = (byte_t*) malloc( i_page_size );
+    p_vout->p_sys->pp_buffer[1] = (byte_t*) malloc( i_page_size );
+    if( p_vout->p_sys->pp_buffer[0] == NULL  || p_vout->p_sys->pp_buffer[0] == NULL )
+    {
+        intf_ErrMsg("vout error: can't allocate video memory (%s)\n", strerror(errno) );
+        if( p_vout->p_sys->pp_buffer[0] != NULL ) free( p_vout->p_sys->pp_buffer[0] );
+        if( p_vout->p_sys->pp_buffer[1] != NULL ) free( p_vout->p_sys->pp_buffer[1] );
+        p_win->locker->Unlock();
+        return( 1 );
+    }
+
+    /* Set and initialize buffers */
+    vout_SetBuffers( p_vout, p_vout->p_sys->pp_buffer[0],
+                     p_vout->p_sys->pp_buffer[1] );
+
+    p_win->locker->Unlock();
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysEnd: terminate dummy video thread output method
+ *****************************************************************************/
+void vout_SysEnd( vout_thread_t *p_vout )
+{
+   VideoWindow * p_win = p_vout->p_sys->p_window;
+   
+   p_win->Lock();
+   
+   free( p_vout->p_sys->pp_buffer[0] );
+   free( p_vout->p_sys->pp_buffer[1] );
+
+   p_win->fReady = false;
+   p_win->Unlock();   
+}
+
+/*****************************************************************************
+ * vout_SysDestroy: destroy dummy video thread output method
+ *****************************************************************************
+ * Terminate an output method created by DummyCreateOutputMethod
+ *****************************************************************************/
+void vout_SysDestroy( vout_thread_t *p_vout )
+{
+    BeosCloseDisplay( p_vout );
+    
+    free( p_vout->p_sys );
+}
+
+/*****************************************************************************
+ * vout_SysManage: handle dummy events
+ *****************************************************************************
+ * This function should be called regularly by video output thread. It manages
+ * console events. It returns a non null value on error.
+ *****************************************************************************/
+int vout_SysManage( vout_thread_t *p_vout )
+{
+    if( p_vout->i_changes & VOUT_SIZE_CHANGE )
+    {
+        intf_DbgMsg("resizing window\n");
+        p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
+
+        /* Resize window */
+        p_vout->p_sys->p_window->ResizeTo( p_vout->i_width, p_vout->i_height );
+
+        /* Destroy XImages to change their size */
+        vout_SysEnd( p_vout );
+
+        /* Recreate XImages. If SysInit failed, the thread can't go on. */
+        if( vout_SysInit( p_vout ) )
+        {
+            intf_ErrMsg("error: can't resize display\n");
+            return( 1 );
+        }
+
+        /* Tell the video output thread that it will need to rebuild YUV
+         * tables. This is needed since convertion buffer size may have changed */
+        p_vout->i_changes |= VOUT_YUV_CHANGE;
+        intf_Msg("Video display resized (%dx%d)\n", p_vout->i_width, p_vout->i_height);
+    }
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysDisplay: displays previously rendered output
+ *****************************************************************************
+ * This function send the currently rendered image to dummy image, waits until
+ * it is displayed and switch the two rendering buffers, preparing next frame.
+ *****************************************************************************/
+void vout_SysDisplay( vout_thread_t *p_vout )
+{
+    VideoWindow * p_win = p_vout->p_sys->p_window;
+    
+    p_win->locker->Lock();
+    p_vout->i_buffer_index = ++p_vout->i_buffer_index & 1;
+    p_win->fReady = true;
+    p_win->fDirty = true;
+    p_win->locker->Unlock();
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * BeosOpenDisplay: open and initialize dummy device
+ *****************************************************************************
+ * XXX?? The framebuffer mode is only provided as a fast and efficient way to
+ * display video, providing the card is configured and the mode ok. It is
+ * not portable, and is not supposed to work with many cards. Use at your
+ * own risk !
+ *****************************************************************************/
+
+static int BeosOpenDisplay( vout_thread_t *p_vout )
+{ 
+    /* Create the DirectDraw video window */
+    p_vout->p_sys->p_window =
+        new VideoWindow(  BRect( 100, 100, 100+p_vout->i_width, 100+p_vout->i_height ), "VideoLAN", p_vout );
+    if( p_vout->p_sys->p_window == 0 )
+    {
+        free( p_vout->p_sys );
+        intf_ErrMsg( "error: cannot allocate memory for VideoWindow\n" );
+        return( 1 );
+    }   
+    VideoWindow * p_win = p_vout->p_sys->p_window;
+    
+    /* Wait until DirectConnected has been called */
+    while( !p_win->fConnected )
+        snooze( 50000 );
+
+    p_vout->i_screen_depth =         p_win->i_screen_depth;
+    p_vout->i_bytes_per_pixel =      p_win->i_bytes_per_pixel;
+    p_vout->i_bytes_per_line =       p_vout->i_width*p_win->i_bytes_per_pixel;
+    
+    switch( p_vout->i_screen_depth )
+    {
+    case 8:
+        intf_ErrMsg( "vout error: 8 bit mode not fully supported\n" );
+        break;
+    case 15:
+        p_vout->i_red_mask =        0x7c00;
+        p_vout->i_green_mask =      0x03e0;
+        p_vout->i_blue_mask =       0x001f;
+        break;
+    case 16:
+        p_vout->i_red_mask =        0xf800;
+        p_vout->i_green_mask =      0x07e0;
+        p_vout->i_blue_mask =       0x001f;
+        break;
+    case 24:
+    case 32:
+    default:
+        p_vout->i_red_mask =        0xff0000;
+        p_vout->i_green_mask =      0x00ff00;
+        p_vout->i_blue_mask =       0x0000ff;
+        break;
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * BeosDisplay: close and reset dummy device
+ *****************************************************************************
+ * Returns all resources allocated by BeosOpenDisplay and restore the original
+ * state of the device.
+ *****************************************************************************/
+static void BeosCloseDisplay( vout_thread_t *p_vout )
+{    
+    /* Destroy the video window */
+    p_vout->p_sys->p_window->Lock();
+    p_vout->p_sys->p_window->Quit();
+}
+
+} /* extern "C" */
diff --git a/plugins/dsp/aout_dsp.c b/plugins/dsp/aout_dsp.c
new file mode 100644 (file)
index 0000000..157ce25
--- /dev/null
@@ -0,0 +1,242 @@
+/*****************************************************************************
+ * aout_dsp.c : dsp functions library
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/* TODO:
+ *
+ * - an aout_sysGetFormats() function
+ * - dsp inline/static
+ * - make this library portable (see mpg123)
+ * - macroify aout_sysPlaySamples &/| aout_sysGetBufInfo ?
+ *
+ */
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <fcntl.h>                                       /* open(), O_WRONLY */
+#include <sys/ioctl.h>                                            /* ioctl() */
+#include <string.h>                                            /* strerror() */
+#include <unistd.h>                                      /* write(), close() */
+#include <stdio.h>                                           /* "intf_msg.h" */
+#include <stdlib.h>                            /* calloc(), malloc(), free() */
+
+#ifdef SYS_BSD
+#include <machine/soundcard.h>       /* SNDCTL_DSP_RESET, SNDCTL_DSP_SETFMT,
+                   SNDCTL_DSP_STEREO, SNDCTL_DSP_SPEED, SNDCTL_DSP_GETOSPACE */
+#else
+#include <sys/soundcard.h>           /* SNDCTL_DSP_RESET, SNDCTL_DSP_SETFMT,
+                   SNDCTL_DSP_STEREO, SNDCTL_DSP_SPEED, SNDCTL_DSP_GETOSPACE */
+#endif
+
+#include "config.h"
+#include "common.h"                                     /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "audio_output.h"                                   /* aout_thread_t */
+
+#include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
+#include "main.h"
+
+/*****************************************************************************
+ * vout_dsp_t: dsp audio output method descriptor
+ *****************************************************************************
+ * This structure is part of the audio output thread descriptor.
+ * It describes the dsp specific properties of an audio device.
+ *****************************************************************************/
+typedef struct aout_sys_s
+{
+    audio_buf_info        audio_buf;
+
+} aout_sys_t;
+
+/*****************************************************************************
+ * aout_SysOpen: opens the audio device (the digital sound processor)
+ *****************************************************************************
+ * - This function opens the dsp as an usual non-blocking write-only file, and
+ *   modifies the p_aout->p_sys->i_fd with the file's descriptor.
+ *****************************************************************************/
+int aout_SysOpen( aout_thread_t *p_aout )
+{
+    /* Allocate structure */
+    p_aout->p_sys = malloc( sizeof( aout_sys_t ) );
+    if( p_aout->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Initialize some variables */
+    p_aout->i_format = AOUT_DEFAULT_FORMAT;
+    p_aout->psz_device = main_GetPszVariable( AOUT_DSP_VAR, AOUT_DSP_DEFAULT );
+    p_aout->i_channels = 1 + main_GetIntVariable( AOUT_STEREO_VAR, AOUT_STEREO_DEFAULT );
+    p_aout->l_rate     = main_GetIntVariable( AOUT_RATE_VAR, AOUT_RATE_DEFAULT );
+
+    /* Open the sound device */
+    if ( (p_aout->i_fd = open( p_aout->psz_device, O_WRONLY )) < 0 )
+    {
+        intf_ErrMsg( "aout error: can't open audio device (%s)\n", p_aout->psz_device );
+        return( -1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysReset: resets the dsp
+ *****************************************************************************/
+int aout_SysReset( aout_thread_t *p_aout )
+{
+    if ( ioctl( p_aout->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 )
+    {
+        intf_ErrMsg( "aout error: can't reset audio device (%s)\n", p_aout->psz_device );
+    return( -1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetFormat: sets the dsp output format
+ *****************************************************************************
+ * This functions tries to initialize the dsp output format with the value
+ * contained in the dsp structure, and if this value could not be set, the
+ * default value returned by ioctl is set.
+ *****************************************************************************/
+int aout_SysSetFormat( aout_thread_t *p_aout )
+{
+    int i_format;
+
+    i_format = p_aout->i_format;
+    if ( ioctl( p_aout->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 )
+    {
+        intf_ErrMsg( "aout error: can't set audio output format (%i)\n", p_aout->i_format );
+        return( -1 );
+    }
+
+    if ( i_format != p_aout->i_format )
+    {
+        intf_DbgMsg( "aout debug: audio output format not supported (%i)\n", p_aout->i_format );
+        p_aout->i_format = i_format;
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetChannels: sets the dsp's stereo or mono mode
+ *****************************************************************************
+ * This function acts just like the previous one...
+ *****************************************************************************/
+int aout_SysSetChannels( aout_thread_t *p_aout )
+{
+    boolean_t b_stereo = p_aout->b_stereo;
+
+    if ( ioctl( p_aout->i_fd, SNDCTL_DSP_STEREO, &b_stereo ) < 0 )
+    {
+        intf_ErrMsg( "aout error: can't set number of audio channels (%i)\n", p_aout->i_channels );
+        return( -1 );
+    }
+
+    if ( b_stereo != p_aout->b_stereo )
+    {
+        intf_DbgMsg( "aout debug: number of audio channels not supported (%i)\n", p_aout->i_channels );
+        p_aout->b_stereo = b_stereo;
+        p_aout->i_channels = 1 + b_stereo;
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetRate: sets the dsp's audio output rate
+ *****************************************************************************
+ * This function tries to initialize the dsp with the rate contained in the
+ * dsp structure, but if the dsp doesn't support this value, the function uses
+ * the value returned by ioctl...
+ *****************************************************************************/
+int aout_SysSetRate( aout_thread_t *p_aout )
+{
+    long l_rate;
+
+    l_rate = p_aout->l_rate;
+    if ( ioctl( p_aout->i_fd, SNDCTL_DSP_SPEED, &l_rate ) < 0 )
+    {
+        intf_ErrMsg( "aout error: can't set audio output rate (%li)\n", p_aout->l_rate );
+        return( -1 );
+    }
+
+    if ( l_rate != p_aout->l_rate )
+    {
+        intf_DbgMsg( "aout debug: audio output rate not supported (%li)\n", p_aout->l_rate );
+        p_aout->l_rate = l_rate;
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysGetBufInfo: buffer status query
+ *****************************************************************************
+ * This function fills in the audio_buf_info structure :
+ * - int fragments : number of available fragments (partially usend ones not
+ *   counted)
+ * - int fragstotal : total number of fragments allocated
+ * - int fragsize : size of a fragment in bytes
+ * - int bytes : available space in bytes (includes partially used fragments)
+ * Note! 'bytes' could be more than fragments*fragsize
+ *****************************************************************************/
+long aout_SysGetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
+{
+    ioctl( p_aout->i_fd, SNDCTL_DSP_GETOSPACE, &p_aout->p_sys->audio_buf );
+
+    /* returns the allocated space in bytes */
+    return ( (p_aout->p_sys->audio_buf.fragstotal
+                 * p_aout->p_sys->audio_buf.fragsize)
+            - p_aout->p_sys->audio_buf.bytes );
+}
+
+/*****************************************************************************
+ * aout_SysPlaySamples: plays a sound samples buffer
+ *****************************************************************************
+ * This function writes a buffer of i_length bytes in the dsp
+ *****************************************************************************/
+void aout_SysPlaySamples( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+{
+    if( p_aout->b_active )
+    {
+        write( p_aout->i_fd, buffer, i_size );
+    }
+}
+
+/*****************************************************************************
+ * aout_SysClose: closes the dsp audio device
+ *****************************************************************************/
+void aout_SysClose( aout_thread_t *p_aout )
+{
+    close( p_aout->i_fd );
+}
+
diff --git a/plugins/dummy/aout_dummy.c b/plugins/dummy/aout_dummy.c
new file mode 100644 (file)
index 0000000..ae05633
--- /dev/null
@@ -0,0 +1,118 @@
+/*****************************************************************************
+ * aout_dummy.c : dummy audio output plugin
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include "config.h"
+#include "common.h"                                     /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "audio_output.h"                                   /* aout_thread_t */
+
+#include "main.h"
+
+/*****************************************************************************
+ * vout_dummy_t: dummy video output method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the dummy specific properties of an output thread.
+ *****************************************************************************/
+typedef struct aout_sys_s
+{
+
+
+} aout_sys_t;
+
+/*****************************************************************************
+ * aout_SysOpen: opens a dummy audio device
+ *****************************************************************************/
+int aout_SysOpen( aout_thread_t *p_aout )
+{
+    /* Initialize some variables */
+    p_aout->i_format = AOUT_DEFAULT_FORMAT;
+    p_aout->i_channels = 1 + main_GetIntVariable( AOUT_STEREO_VAR, AOUT_STEREO_DEFAULT );
+    p_aout->l_rate     = main_GetIntVariable( AOUT_RATE_VAR, AOUT_RATE_DEFAULT );
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysReset: fake reset
+ *****************************************************************************/
+int aout_SysReset( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetFormat: pretends to set the dsp output format
+ *****************************************************************************/
+int aout_SysSetFormat( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetChannels: pretends to set stereo or mono mode
+ *****************************************************************************/
+int aout_SysSetChannels( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetRate: pretends to set audio output rate
+ *****************************************************************************/
+int aout_SysSetRate( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysGetBufInfo: returns available bytes in buffer
+ *****************************************************************************/
+long aout_SysGetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
+{
+    return( 2 * l_buffer_limit );               /* value big enough to sleep */
+}
+
+/*****************************************************************************
+ * aout_SysPlaySamples: pretends to play a sound
+ *****************************************************************************/
+void aout_SysPlaySamples( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+{
+    ;
+}
+
+/*****************************************************************************
+ * aout_SysClose: closes the dummy audio device
+ *****************************************************************************/
+void aout_SysClose( aout_thread_t *p_aout )
+{
+    ;
+}
+
diff --git a/plugins/dummy/intf_dummy.c b/plugins/dummy/intf_dummy.c
new file mode 100644 (file)
index 0000000..0e04a90
--- /dev/null
@@ -0,0 +1,109 @@
+/*****************************************************************************
+ * intf_dummy.c: dummy interface plugin
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <sys/types.h>                        /* on BSD, uio.h needs types.h */
+#include <sys/uio.h>                                            /* "input.h" */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "input.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+#include "interface.h"
+
+#include "main.h"
+
+/*****************************************************************************
+ * intf_sys_t: description and status of FB interface
+ *****************************************************************************/
+typedef struct intf_sys_s
+{
+
+} intf_sys_t;
+
+/*****************************************************************************
+ * intf_SysCreate: initialize dummy interface
+ *****************************************************************************/
+int intf_SysCreate( intf_thread_t *p_intf )
+{
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        return( 1 );
+    };
+
+    /* Spawn video output thread */
+    if( p_main->b_video )
+    {
+        p_intf->p_vout = vout_CreateThread( NULL, 0, 0, 0, NULL, 0, NULL );
+        if( p_intf->p_vout == NULL )                                /* error */
+        {
+            intf_ErrMsg("intf error: can't create output thread\n" );
+            return( 1 );
+        }
+    }
+    return( 0 );
+}
+
+/*****************************************************************************
+ * intf_SysDestroy: destroy dummy interface
+ *****************************************************************************/
+void intf_SysDestroy( intf_thread_t *p_intf )
+{
+    /* Close input thread, if any (blocking) */
+    if( p_intf->p_input )
+    {
+        input_DestroyThread( p_intf->p_input, NULL );
+    }
+
+    /* Close video output thread, if any (blocking) */
+    if( p_intf->p_vout )
+    {
+        vout_DestroyThread( p_intf->p_vout, NULL );
+    }
+
+    /* Destroy structure */
+    free( p_intf->p_sys );
+}
+
+
+/*****************************************************************************
+ * intf_SysManage: event loop
+ *****************************************************************************/
+void intf_SysManage( intf_thread_t *p_intf )
+{
+    ;
+}
+
diff --git a/plugins/dummy/vout_dummy.c b/plugins/dummy/vout_dummy.c
new file mode 100644 (file)
index 0000000..c0b77ed
--- /dev/null
@@ -0,0 +1,189 @@
+/*****************************************************************************
+ * vout_dummy.c: Dummy video output display method for testing purposes
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+
+#define WIDTH 128
+#define HEIGHT 64
+#define BITS_PER_PLANE 16
+#define BYTES_PER_PIXEL 2
+
+/*****************************************************************************
+ * vout_sys_t: dummy video output method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the dummy specific properties of an output thread.
+ *****************************************************************************/
+typedef struct vout_sys_s
+{
+    /* Dummy video memory */
+    byte_t *                    p_video;                      /* base adress */
+    size_t                      i_page_size;                    /* page size */
+
+} vout_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int     DummyOpenDisplay   ( vout_thread_t *p_vout );
+static void    DummyCloseDisplay  ( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * vout_SysCreate: allocates dummy video thread output method
+ *****************************************************************************
+ * This function allocates and initializes a dummy vout method.
+ *****************************************************************************/
+int vout_SysCreate( vout_thread_t *p_vout, char *psz_display,
+                    int i_root_window, void *p_data )
+{
+    /* Allocate structure */
+    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+    if( p_vout->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Open and initialize device */
+    if( DummyOpenDisplay( p_vout ) )
+    {
+        intf_ErrMsg("vout error: can't open display\n");
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysInit: initialize dummy video thread output method
+ *****************************************************************************/
+int vout_SysInit( vout_thread_t *p_vout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysEnd: terminate dummy video thread output method
+ *****************************************************************************/
+void vout_SysEnd( vout_thread_t *p_vout )
+{
+    ;
+}
+
+/*****************************************************************************
+ * vout_SysDestroy: destroy dummy video thread output method
+ *****************************************************************************
+ * Terminate an output method created by DummyCreateOutputMethod
+ *****************************************************************************/
+void vout_SysDestroy( vout_thread_t *p_vout )
+{
+    DummyCloseDisplay( p_vout );
+    free( p_vout->p_sys );
+}
+
+/*****************************************************************************
+ * vout_SysManage: handle dummy events
+ *****************************************************************************
+ * This function should be called regularly by video output thread. It manages
+ * console events. It returns a non null value on error.
+ *****************************************************************************/
+int vout_SysManage( vout_thread_t *p_vout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysDisplay: displays previously rendered output
+ *****************************************************************************
+ * This function send the currently rendered image to dummy image, waits until
+ * it is displayed and switch the two rendering buffers, preparing next frame.
+ *****************************************************************************/
+void vout_SysDisplay( vout_thread_t *p_vout )
+{
+    ;
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * DummyOpenDisplay: open and initialize dummy device
+ *****************************************************************************
+ * XXX?? The framebuffer mode is only provided as a fast and efficient way to
+ * display video, providing the card is configured and the mode ok. It is
+ * not portable, and is not supposed to work with many cards. Use at your
+ * own risk !
+ *****************************************************************************/
+
+static int DummyOpenDisplay( vout_thread_t *p_vout )
+{
+    p_vout->i_width =                   WIDTH;
+    p_vout->i_height =                  HEIGHT;
+    p_vout->i_screen_depth =            BITS_PER_PLANE;
+    p_vout->i_bytes_per_pixel =         BYTES_PER_PIXEL;
+    p_vout->i_bytes_per_line =          WIDTH * BYTES_PER_PIXEL;
+
+    p_vout->p_sys->i_page_size = WIDTH * HEIGHT * BYTES_PER_PIXEL;
+
+    /* Map two framebuffers a the very beginning of the fb */
+    p_vout->p_sys->p_video = malloc( p_vout->p_sys->i_page_size * 2 );
+    if( (int)p_vout->p_sys->p_video == -1 )
+    {
+        intf_ErrMsg("vout error: can't map video memory (%s)\n", strerror(errno) );
+        return( 1 );
+    }
+
+    /* Set and initialize buffers */
+    vout_SetBuffers( p_vout, p_vout->p_sys->p_video,
+                     p_vout->p_sys->p_video + p_vout->p_sys->i_page_size );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * DummyCloseDisplay: close and reset dummy device
+ *****************************************************************************
+ * Returns all resources allocated by DummyOpenDisplay and restore the original
+ * state of the device.
+ *****************************************************************************/
+static void DummyCloseDisplay( vout_thread_t *p_vout )
+{
+    free( p_vout->p_sys->p_video );
+}
+
diff --git a/plugins/esd/aout_esd.c b/plugins/esd/aout_esd.c
new file mode 100644 (file)
index 0000000..c7a42bf
--- /dev/null
@@ -0,0 +1,191 @@
+/*****************************************************************************
+ * aout_esd.c : Esound functions library
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/* TODO:
+ *
+ * - use the libesd function to get latency when it's not buggy anymore
+ *
+ */
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <fcntl.h>                                       /* open(), O_WRONLY */
+#include <string.h>                                            /* strerror() */
+#include <unistd.h>                                      /* write(), close() */
+#include <stdio.h>                                           /* "intf_msg.h" */
+#include <stdlib.h>                            /* calloc(), malloc(), free() */
+
+#include <esd.h>
+
+#include "config.h"
+#include "common.h"                                     /* boolean_t, byte_t */
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "audio_output.h"                                   /* aout_thread_t */
+
+#include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
+#include "main.h"
+
+/*****************************************************************************
+ * aout_sys_t: esd audio output method descriptor
+ *****************************************************************************
+ * This structure is part of the audio output thread descriptor.
+ * It describes some esd specific variables.
+ *****************************************************************************/
+typedef struct aout_sys_s
+{
+    esd_format_t esd_format;
+
+} aout_sys_t;
+
+/*****************************************************************************
+ * aout_SysOpen: opens an esd socket
+ *****************************************************************************/
+int aout_SysOpen( aout_thread_t *p_aout )
+{
+    /* mpg123 does it this way */
+    int i_bits = ESD_BITS16;
+    int i_mode = ESD_STREAM;
+    int i_func = ESD_PLAY;
+
+    /* Allocate structure */
+    p_aout->p_sys = malloc( sizeof( aout_sys_t ) );
+    if( p_aout->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Initialize some variables */
+    p_aout->i_format = AOUT_DEFAULT_FORMAT;
+    p_aout->i_channels = 1 + main_GetIntVariable( AOUT_STEREO_VAR, AOUT_STEREO_DEFAULT );
+    p_aout->l_rate     = main_GetIntVariable( AOUT_RATE_VAR, AOUT_RATE_DEFAULT );
+
+    i_bits = ESD_BITS16;
+    i_mode = ESD_STREAM;
+    i_func = ESD_PLAY;
+    p_aout->p_sys->esd_format = (i_bits | i_mode | i_func) & (~ESD_MASK_CHAN);
+
+    if( p_aout->i_channels == 1 )
+        p_aout->p_sys->esd_format |= ESD_MONO;
+    else
+        p_aout->p_sys->esd_format |= ESD_STEREO;
+
+    /* open a socket for playing a stream
+     * and try to open /dev/dsp if there's no EsounD */
+    if ( (p_aout->i_fd
+            = esd_play_stream_fallback(p_aout->p_sys->esd_format,
+                p_aout->l_rate, NULL, "vlc")) < 0 )
+    {
+        intf_ErrMsg( "aout error: can't open esound socket"
+                     " (format 0x%08x at %ld Hz)\n",
+                     p_aout->p_sys->esd_format, p_aout->l_rate );
+        return( -1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysReset: resets the dsp
+ *****************************************************************************/
+int aout_SysReset( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetFormat: sets the dsp output format
+ *****************************************************************************/
+int aout_SysSetFormat( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetChannels: sets the dsp's stereo or mono mode
+ *****************************************************************************/
+int aout_SysSetChannels( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysSetRate: sets the dsp's audio output rate
+ *****************************************************************************/
+int aout_SysSetRate( aout_thread_t *p_aout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * aout_SysGetBufInfo: buffer status query
+ *****************************************************************************/
+long aout_SysGetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
+{
+    /* arbitrary value that should be changed */
+    return( l_buffer_limit );
+}
+
+/*****************************************************************************
+ * aout_SysPlaySamples: plays a sound samples buffer
+ *****************************************************************************
+ * This function writes a buffer of i_length bytes in the dsp
+ *****************************************************************************/
+void aout_SysPlaySamples( aout_thread_t *p_aout, byte_t *buffer, int i_size )
+{
+    int amount;
+
+    if (p_aout->p_sys->esd_format & ESD_STEREO)
+    {
+        if (p_aout->p_sys->esd_format & ESD_BITS16)
+            amount = (44100 * (ESD_BUF_SIZE + 64)) / p_aout->l_rate;
+        else
+            amount = (44100 * (ESD_BUF_SIZE + 128)) / p_aout->l_rate;
+    }
+    else
+    {
+        if (p_aout->p_sys->esd_format & ESD_BITS16)
+            amount = (2 * 44100 * (ESD_BUF_SIZE + 128)) / p_aout->l_rate;
+        else
+            amount = (2 * 44100 * (ESD_BUF_SIZE + 256)) / p_aout->l_rate;
+    }
+
+    intf_DbgMsg( "aout: latency is %i\n", amount );
+
+    write( p_aout->i_fd, buffer, i_size );
+}
+
+/*****************************************************************************
+ * aout_SysClose: closes the dsp audio device
+ *****************************************************************************/
+void aout_SysClose( aout_thread_t *p_aout )
+{
+    close( p_aout->i_fd );
+}
+
diff --git a/plugins/fb/intf_fb.c b/plugins/fb/intf_fb.c
new file mode 100644 (file)
index 0000000..c60bac2
--- /dev/null
@@ -0,0 +1,286 @@
+/*****************************************************************************
+ * intf_fb.c: Linux framebuffer interface plugin
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                  /* errno */
+#include <signal.h>                                      /* SIGUSR1, SIGUSR2 */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+#include <unistd.h>                                                /* read() */
+#include <sys/ioctl.h>                                            /* ioctl() */
+#include <sys/types.h>                        /* on BSD, uio.h needs types.h */
+#include <sys/uio.h>                                          /* for input.h */
+
+#include <termios.h>                                       /* struct termios */
+#include <linux/vt.h>                                                /* VT_* */
+#include <linux/kd.h>                                                 /* KD* */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "input.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+#include "interface.h"
+
+#include "main.h"
+
+/*****************************************************************************
+ * intf_sys_t: description and status of FB interface
+ *****************************************************************************/
+typedef struct intf_sys_s
+{
+    /* System informations */
+    int                         i_tty_dev;              /* tty device handle */
+
+    /* Original configuration informations */
+    struct sigaction            sig_usr1;           /* USR1 previous handler */
+    struct sigaction            sig_usr2;           /* USR2 previous handler */
+    struct vt_mode              vt_mode;                 /* previous VT mode */
+
+    int                 i_width;                     /* width of main window */
+    int                 i_height;                   /* height of main window */
+
+    struct termios      old_termios;
+    struct termios      new_termios;
+
+} intf_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void    FBSwitchDisplay            ( int i_signal );
+static void    FBTextMode                 ( int i_tty_dev );
+static void    FBGfxMode                  ( int i_tty_dev );
+
+/*****************************************************************************
+ * intf_SysCreate: initialize and create window
+ *****************************************************************************/
+int intf_SysCreate( intf_thread_t *p_intf )
+{
+    struct sigaction            sig_tty;         /* sigaction for tty change */
+    struct vt_mode              vt_mode;                  /* vt current mode */
+
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        return( 1 );
+    };
+    intf_DbgMsg("0x%x\n", p_intf );
+
+    /* Set tty and fb devices */
+    p_intf->p_sys->i_tty_dev = 0;       /* 0 == /dev/tty0 == current console */
+
+    FBGfxMode( p_intf->p_sys->i_tty_dev );
+
+    /* set keyboard settings */
+    if (tcgetattr(0, &p_intf->p_sys->old_termios) == -1)
+        intf_ErrMsg( "intf error: tcgetattr" );
+    if (tcgetattr(0, &p_intf->p_sys->new_termios) == -1)
+        intf_ErrMsg( "intf error: tcgetattr" );
+
+    p_intf->p_sys->new_termios.c_lflag &= ~ (ICANON | ISIG);
+    p_intf->p_sys->new_termios.c_lflag |= (ECHO | ECHOCTL);
+    p_intf->p_sys->new_termios.c_iflag = 0;
+    p_intf->p_sys->new_termios.c_cc[VMIN] = 1;
+    p_intf->p_sys->new_termios.c_cc[VTIME] = 0;
+
+    if (tcsetattr(0, TCSAFLUSH, &p_intf->p_sys->new_termios) == -1)
+        intf_ErrMsg( "intf error: tcsetattr" );
+
+    ioctl(p_intf->p_sys->i_tty_dev, VT_RELDISP, VT_ACKACQ);
+
+    /* Set-up tty signal handler to be aware of tty changes */
+    memset( &sig_tty, 0, sizeof( sig_tty ) );
+    sig_tty.sa_handler = FBSwitchDisplay;
+    sigemptyset( &sig_tty.sa_mask );
+    if( sigaction( SIGUSR1, &sig_tty, &p_intf->p_sys->sig_usr1 ) ||
+        sigaction( SIGUSR2, &sig_tty, &p_intf->p_sys->sig_usr2 ) )
+    {
+        intf_ErrMsg("intf error: can't set up signal handler (%s)\n", strerror(errno) );
+        FBTextMode( p_intf->p_sys->i_tty_dev );
+        return( 1 );
+    }
+
+    /* Set-up tty according to new signal handler */
+    if( ioctl(p_intf->p_sys->i_tty_dev, VT_GETMODE, &p_intf->p_sys->vt_mode) == -1 )
+    {
+        intf_ErrMsg("intf error: cant get terminal mode (%s)\n", strerror(errno) );
+        sigaction( SIGUSR1, &p_intf->p_sys->sig_usr1, NULL );
+        sigaction( SIGUSR2, &p_intf->p_sys->sig_usr2, NULL );
+        FBTextMode( p_intf->p_sys->i_tty_dev );
+        return( 1 );
+    }
+    memcpy( &vt_mode, &p_intf->p_sys->vt_mode, sizeof( vt_mode ) );
+    vt_mode.mode   = VT_PROCESS;
+    vt_mode.waitv  = 0;
+    vt_mode.relsig = SIGUSR1;
+    vt_mode.acqsig = SIGUSR2;
+
+    if( ioctl(p_intf->p_sys->i_tty_dev, VT_SETMODE, &vt_mode) == -1 )
+    {
+        intf_ErrMsg("intf error: can't set terminal mode (%s)\n", strerror(errno) );
+        sigaction( SIGUSR1, &p_intf->p_sys->sig_usr1, NULL );
+        sigaction( SIGUSR2, &p_intf->p_sys->sig_usr2, NULL );
+        FBTextMode( p_intf->p_sys->i_tty_dev );
+        return( 1 );
+    }
+
+    /* Spawn video output thread */
+    if( p_main->b_video )
+    {
+        p_intf->p_vout = vout_CreateThread( NULL, 0,
+                                            p_intf->p_sys->i_width,
+                                            p_intf->p_sys->i_height, NULL, 0, NULL );
+        if( p_intf->p_vout == NULL )                          /* XXX?? error */
+        {
+            intf_ErrMsg("intf error: can't create output thread\n" );
+            ioctl(p_intf->p_sys->i_tty_dev, VT_SETMODE, &p_intf->p_sys->vt_mode);
+            sigaction( SIGUSR1, &p_intf->p_sys->sig_usr1, NULL );
+            sigaction( SIGUSR2, &p_intf->p_sys->sig_usr2, NULL );
+            free( p_intf->p_sys );
+            FBTextMode( p_intf->p_sys->i_tty_dev );
+            return( 1 );
+        }
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * intf_SysDestroy: destroy interface window
+ *****************************************************************************/
+void intf_SysDestroy( intf_thread_t *p_intf )
+{
+    /* resets the keyboard state */
+    tcsetattr(0, 0, &p_intf->p_sys->old_termios);
+
+    /* return to text mode */
+    FBTextMode( p_intf->p_sys->i_tty_dev );
+
+    /* Close input thread, if any (blocking) */
+    if( p_intf->p_input )
+    {
+        input_DestroyThread( p_intf->p_input, NULL );
+    }
+
+    /* Close video output thread, if any (blocking) */
+    if( p_intf->p_vout )
+    {
+        vout_DestroyThread( p_intf->p_vout, NULL );
+    }
+
+    /* Destroy structure */
+    free( p_intf->p_sys );
+}
+
+
+/*****************************************************************************
+ * intf_SysManage: event loop
+ *****************************************************************************/
+void intf_SysManage( intf_thread_t *p_intf )
+{
+    unsigned char buf[16];
+
+    //while ( read(0, buf, 1) == 1)
+    if ( read(0, buf, 1) == 1)
+    {
+        if( intf_ProcessKey(p_intf, (int)buf[0]) )
+        {
+            intf_ErrMsg("unhandled key '%c' (%i)\n", (char) buf[0], buf[0] );
+        }
+    }
+}
+
+/*****************************************************************************
+ * FBSwitchDisplay: VT change signal handler
+ *****************************************************************************
+ * This function activate or desactivate the output of the thread. It is called
+ * by the VT driver, on terminal change.
+ *****************************************************************************/
+static void FBSwitchDisplay(int i_signal)
+{
+    if( p_main->p_intf->p_vout != NULL )
+    {
+        switch( i_signal )
+        {
+        case SIGUSR1:                                /* vt has been released */
+            p_main->p_intf->p_vout->b_active = 0;
+            ioctl( ((intf_sys_t *)p_main->p_intf->p_sys)->i_tty_dev,
+                   VT_RELDISP, 1 );
+            break;
+        case SIGUSR2:                                /* vt has been acquired */
+            p_main->p_intf->p_vout->b_active = 1;
+            ioctl( ((intf_sys_t *)p_main->p_intf->p_sys)->i_tty_dev,
+                   VT_RELDISP, VT_ACTIVATE );
+            /* handle blanking */
+            p_main->p_intf->p_vout->i_changes |= VOUT_SIZE_CHANGE;
+            break;
+        }
+    }
+}
+
+/*****************************************************************************
+ * FBTextMode and FBGfxMode : switch tty to text/graphic mode
+ *****************************************************************************
+ * These functions toggle the tty mode.
+ *****************************************************************************/
+static void FBTextMode( int i_tty_dev )
+{
+    /* return to text mode */
+    if (-1 == ioctl(i_tty_dev, KDSETMODE, KD_TEXT))
+    {
+        intf_ErrMsg("intf error: ioctl KDSETMODE\n");
+    }
+}
+
+static void FBGfxMode( int i_tty_dev )
+{
+    /* switch to graphic mode */
+    if (-1 == ioctl(i_tty_dev, KDSETMODE, KD_GRAPHICS))
+    {
+        intf_ErrMsg("intf error: ioctl KDSETMODE\n");
+    }
+}
+
+/*****************************************************************************
+ * vout_SysPrint: print simple text on a picture
+ *****************************************************************************
+ * This function will print a simple text on the picture. It is designed to
+ * print debugging or general informations, not to render subtitles.
+ *****************************************************************************/
+void vout_SysPrint( vout_thread_t *p_vout, int i_x, int i_y, int i_halign,
+                    int i_valign, unsigned char *psz_text )
+{
+
+}
+
diff --git a/plugins/fb/vout_fb.c b/plugins/fb/vout_fb.c
new file mode 100644 (file)
index 0000000..228ff35
--- /dev/null
@@ -0,0 +1,365 @@
+/*****************************************************************************
+ * vout_fb.c: Linux framebuffer video output display method
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+
+#include <fcntl.h>                                                 /* open() */
+#include <unistd.h>                                               /* close() */
+#include <linux/fb.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>                                              /* mmap() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+#include "main.h"
+
+/*****************************************************************************
+ * vout_sys_t: video output framebuffer method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the FB specific properties of an output thread.
+ *****************************************************************************/
+typedef struct vout_sys_s
+{
+    /* System informations */
+    int                         i_fb_dev;       /* framebuffer device handle */
+    struct fb_var_screeninfo    var_info;   /* framebuffer mode informations */
+
+    /* Video memory */
+    byte_t *                    p_video;                      /* base adress */
+    size_t                      i_page_size;                    /* page size */
+
+    struct fb_cmap              fb_cmap;                /* original colormap */
+    unsigned short              *fb_palette;             /* original palette */
+
+} vout_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int     FBOpenDisplay   ( vout_thread_t *p_vout );
+static void    FBCloseDisplay  ( vout_thread_t *p_vout );
+static void    FBSetPalette    ( p_vout_thread_t p_vout,
+                                 u16 *red, u16 *green, u16 *blue, u16 *transp );
+
+/*****************************************************************************
+ * vout_SysCreate: allocates FB video thread output method
+ *****************************************************************************
+ * This function allocates and initializes a FB vout method.
+ *****************************************************************************/
+int vout_SysCreate( vout_thread_t *p_vout, char *psz_display,
+                    int i_root_window, void *p_data )
+{
+    /* Allocate structure */
+    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+    if( p_vout->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Open and initialize device */
+    if( FBOpenDisplay( p_vout ) )
+    {
+        intf_ErrMsg("vout error: can't open display\n");
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysInit: initialize framebuffer video thread output method
+ *****************************************************************************/
+int vout_SysInit( vout_thread_t *p_vout )
+{
+    p_vout->p_set_palette       = FBSetPalette;
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysEnd: terminate FB video thread output method
+ *****************************************************************************/
+void vout_SysEnd( vout_thread_t *p_vout )
+{
+    ;
+}
+
+/*****************************************************************************
+ * vout_SysDestroy: destroy FB video thread output method
+ *****************************************************************************
+ * Terminate an output method created by vout_CreateOutputMethod
+ *****************************************************************************/
+void vout_SysDestroy( vout_thread_t *p_vout )
+{
+    FBCloseDisplay( p_vout );
+    free( p_vout->p_sys );
+}
+
+/*****************************************************************************
+ * vout_SysManage: handle FB events
+ *****************************************************************************
+ * This function should be called regularly by video output thread. It manages
+ * console events. It returns a non null value on error.
+ *****************************************************************************/
+int vout_SysManage( vout_thread_t *p_vout )
+{
+    /*
+     * Size change
+     */
+    if( p_vout->i_changes & VOUT_SIZE_CHANGE )
+    {
+        intf_DbgMsg("resizing window\n");
+        p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
+
+        /* Destroy XImages to change their size */
+        vout_SysEnd( p_vout );
+
+        /* Recreate XImages. If SysInit failed, the thread can't go on. */
+        if( vout_SysInit( p_vout ) )
+        {
+            intf_ErrMsg("error: can't resize display\n");
+            return( 1 );
+        }
+
+#if 1
+        /* Tell the video output thread that it will need to rebuild YUV
+         * tables. This is needed since conversion buffer size may have changed */
+        p_vout->i_changes |= VOUT_YUV_CHANGE;
+        intf_Msg("Video display resized (%dx%d)\n", p_vout->i_width, p_vout->i_height);
+#endif
+    }
+
+    return 0;
+}
+
+/*****************************************************************************
+ * vout_SysDisplay: displays previously rendered output
+ *****************************************************************************
+ * This function send the currently rendered image to FB image, waits until
+ * it is displayed and switch the two rendering buffers, preparing next frame.
+ *****************************************************************************/
+void vout_SysDisplay( vout_thread_t *p_vout )
+{
+    /* swap the two Y offsets */
+    p_vout->p_sys->var_info.yoffset = p_vout->i_buffer_index ? p_vout->p_sys->var_info.yres : 0;
+    /* the X offset should be 0, but who knows ...
+     * some other app might have played with the framebuffer */
+    p_vout->p_sys->var_info.xoffset = 0;
+
+    //ioctl( p_vout->p_sys->i_fb_dev, FBIOPUT_VSCREENINFO, &p_vout->p_sys->var_info );
+    ioctl( p_vout->p_sys->i_fb_dev, FBIOPAN_DISPLAY, &p_vout->p_sys->var_info );
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * FBOpenDisplay: open and initialize framebuffer device
+ *****************************************************************************
+ * XXX?? The framebuffer mode is only provided as a fast and efficient way to
+ * display video, providing the card is configured and the mode ok. It is
+ * not portable, and is not supposed to work with many cards. Use at your
+ * own risk !
+ *****************************************************************************/
+
+static int FBOpenDisplay( vout_thread_t *p_vout )
+{
+    char *psz_device;                             /* framebuffer device path */
+    struct fb_fix_screeninfo    fix_info;     /* framebuffer fix information */
+
+    /* Open framebuffer device */
+    psz_device = main_GetPszVariable( VOUT_FB_DEV_VAR, VOUT_FB_DEV_DEFAULT );
+    p_vout->p_sys->i_fb_dev = open( psz_device, O_RDWR);
+    if( p_vout->p_sys->i_fb_dev == -1 )
+    {
+        intf_ErrMsg("vout error: can't open %s (%s)\n", psz_device, strerror(errno) );
+        return( 1 );
+    }
+
+    /* Get framebuffer device informations */
+    if( ioctl( p_vout->p_sys->i_fb_dev, FBIOGET_VSCREENINFO, &p_vout->p_sys->var_info ) )
+    {
+        intf_ErrMsg( "vout error: can't get framebuffer informations (%s)\n", strerror(errno) );
+        close( p_vout->p_sys->i_fb_dev );
+        return( 1 );
+    }
+
+    /* Framebuffer must have some basic properties to be usable */
+    /* XXX?? */
+
+    /* Set some attributes */
+    p_vout->p_sys->var_info.activate = FB_ACTIVATE_NXTOPEN;
+    p_vout->p_sys->var_info.xoffset =  0;
+    p_vout->p_sys->var_info.yoffset =  0;
+    intf_ErrMsg( "vout: ypanstep is %i\n", fix_info.ypanstep );
+    /* XXX?? ask sam p_vout->p_sys->mode_info.sync = FB_SYNC_VERT_HIGH_ACT; */
+
+    if( ioctl( p_vout->p_sys->i_fb_dev, FBIOPUT_VSCREENINFO, &p_vout->p_sys->var_info ) )
+    {
+        intf_ErrMsg("vout error: can't set framebuffer informations (%s)\n", strerror(errno) );
+        close( p_vout->p_sys->i_fb_dev );
+        return( 1 );
+    }
+
+    /* Get some informations again, in the definitive configuration */
+    if( ioctl( p_vout->p_sys->i_fb_dev, FBIOGET_FSCREENINFO, &fix_info ) ||
+        ioctl( p_vout->p_sys->i_fb_dev, FBIOGET_VSCREENINFO, &p_vout->p_sys->var_info ) )
+    {
+        intf_ErrMsg("vout error: can't get framebuffer informations (%s)\n", strerror(errno) );
+        /* FIXME: restore fb config ?? */
+        close( p_vout->p_sys->i_fb_dev );
+        return( 1 );
+    }
+
+    /* FIXME: if the image is full-size, it gets cropped on the left
+     * because of the xres / xres_virtual slight difference */
+    intf_Msg( "%ix%i (virtual %ix%i)\n", p_vout->p_sys->var_info.xres, p_vout->p_sys->var_info.yres, p_vout->p_sys->var_info.xres_virtual, p_vout->p_sys->var_info.yres_virtual );
+    p_vout->i_width =                   p_vout->p_sys->var_info.xres_virtual ? p_vout->p_sys->var_info.xres_virtual : p_vout->p_sys->var_info.xres;
+    p_vout->i_height =                  p_vout->p_sys->var_info.yres;
+    p_vout->i_screen_depth =            p_vout->p_sys->var_info.bits_per_pixel;
+    switch( p_vout->i_screen_depth )
+    {
+    case 8:                                                         /* 8 bpp */
+        p_vout->p_sys->fb_palette = malloc( 8 * 256 * sizeof(unsigned short) );
+        p_vout->p_sys->fb_cmap.start = 0;
+        p_vout->p_sys->fb_cmap.len = 256;
+        p_vout->p_sys->fb_cmap.red = p_vout->p_sys->fb_palette;
+        p_vout->p_sys->fb_cmap.green = p_vout->p_sys->fb_palette + 256 * sizeof(unsigned short);
+        p_vout->p_sys->fb_cmap.blue = p_vout->p_sys->fb_palette + 2 * 256 * sizeof(unsigned short);
+        p_vout->p_sys->fb_cmap.transp = p_vout->p_sys->fb_palette + 3 * 256 * sizeof(unsigned short);
+
+        /* saves the colormap */
+        ioctl( p_vout->p_sys->i_fb_dev, FBIOGETCMAP, &p_vout->p_sys->fb_cmap );
+
+        p_vout->i_bytes_per_pixel = 1;
+        p_vout->i_bytes_per_line = p_vout->i_width;
+        break;
+
+    case 15:                      /* 15 bpp (16bpp with a missing green bit) */
+    case 16:                                        /* 16 bpp (65536 colors) */
+        p_vout->i_bytes_per_pixel = 2;
+        p_vout->i_bytes_per_line = p_vout->i_width * 2;
+        break;
+
+    case 24:                                  /* 24 bpp (millions of colors) */
+        p_vout->i_bytes_per_pixel = 3;
+        p_vout->i_bytes_per_line = p_vout->i_width * 3;
+        break;
+
+    case 32:                                  /* 32 bpp (millions of colors) */
+        p_vout->i_bytes_per_pixel = 4;
+        p_vout->i_bytes_per_line = p_vout->i_width * 4;
+        break;
+
+    default:                                     /* unsupported screen depth */
+        intf_ErrMsg( "vout error: screen depth %d is not supported\n",
+                     p_vout->i_screen_depth);
+        return( 1 );
+        break;
+    }
+
+    switch( p_vout->i_screen_depth )
+    {
+    case 15:
+    case 16:
+    case 24:
+    case 32:
+        p_vout->i_red_mask =    ( (1 << p_vout->p_sys->var_info.red.length) - 1 )
+                                    << p_vout->p_sys->var_info.red.offset;
+        p_vout->i_green_mask =    ( (1 << p_vout->p_sys->var_info.green.length) - 1 )
+                                    << p_vout->p_sys->var_info.green.offset;
+        p_vout->i_blue_mask =    ( (1 << p_vout->p_sys->var_info.blue.length) - 1 )
+                                    << p_vout->p_sys->var_info.blue.offset;
+    }
+
+    p_vout->p_sys->i_page_size = p_vout->i_width *
+                p_vout->i_height * p_vout->i_bytes_per_pixel;
+
+    /* Map two framebuffers a the very beginning of the fb */
+    p_vout->p_sys->p_video = mmap(0, p_vout->p_sys->i_page_size * 2,
+                          PROT_READ | PROT_WRITE, MAP_SHARED,
+                          p_vout->p_sys->i_fb_dev, 0 );
+    if( (int)p_vout->p_sys->p_video == -1 ) /* XXX?? according to man, it is -1. What about NULL ? */
+    {
+        intf_ErrMsg("vout error: can't map video memory (%s)\n", strerror(errno) );
+        /* FIXME: restore fb config ?? */
+        close( p_vout->p_sys->i_fb_dev );
+        return( 1 );
+    }
+
+    /* Set and initialize buffers */
+    vout_SetBuffers( p_vout, p_vout->p_sys->p_video,
+                     p_vout->p_sys->p_video + p_vout->p_sys->i_page_size );
+    intf_DbgMsg("framebuffer type=%d, visual=%d, ypanstep=%d, ywrap=%d, accel=%d\n",
+                fix_info.type, fix_info.visual, fix_info.ypanstep, fix_info.ywrapstep, fix_info.accel );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * FBCloseDisplay: close and reset framebuffer device
+ *****************************************************************************
+ * Returns all resources allocated by FBOpenDisplay and restore the original
+ * state of the device.
+ *****************************************************************************/
+static void FBCloseDisplay( vout_thread_t *p_vout )
+{
+    /* Restore palette */
+    if( p_vout->i_screen_depth == 8 );
+    {
+        ioctl( p_vout->p_sys->i_fb_dev, FBIOPUTCMAP, &p_vout->p_sys->fb_cmap );
+        free( p_vout->p_sys->fb_palette );
+    }
+
+    /* Destroy window and close display */
+    close( p_vout->p_sys->i_fb_dev );
+}
+
+/*****************************************************************************
+ * FBSetPalette: sets an 8 bpp palette
+ *****************************************************************************
+ * This function sets the palette given as an argument. It does not return
+ * anything, but could later send information on which colors it was unable
+ * to set.
+ *****************************************************************************/
+static void    FBSetPalette   ( p_vout_thread_t p_vout,
+                                u16 *red, u16 *green, u16 *blue, u16 *transp )
+{
+    struct fb_cmap cmap = { 0, 256, red, green, blue, transp };
+    ioctl( p_vout->p_sys->i_fb_dev, FBIOPUTCMAP, &cmap );
+}
+
diff --git a/plugins/ggi/intf_ggi.c b/plugins/ggi/intf_ggi.c
new file mode 100644 (file)
index 0000000..d1eac68
--- /dev/null
@@ -0,0 +1,156 @@
+/*****************************************************************************
+ * intf_ggi.c: GGI interface plugin
+ * Since GII doesnt seem to work well for keyboard events, the GGI display is
+ * used, and therefore the GII interface can't be spawned without a video output
+ * thread. It also needs a kludge to get the visual from the video output GGI
+ * driver.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ggi/ggi.h>
+#include <sys/types.h>                        /* on BSD, uio.h needs types.h */
+#include <sys/uio.h>                                          /* for input.h */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "input.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "interface.h"
+#include "intf_msg.h"
+
+#include "main.h"
+
+/*****************************************************************************
+ * intf_sys_t: description and status of GGI interface
+ *****************************************************************************/
+typedef struct intf_sys_s
+{
+    /* GGI system information */
+    ggi_visual_t                 p_display;                       /* display */
+
+} intf_sys_t;
+
+/*****************************************************************************
+ * External prototypes
+ *****************************************************************************/
+
+/* vout_SysGetVisual: get back visual from video output thread - in video_ggi.c
+ * This function is used to get back the display pointer once the video output
+ * thread has been spawned. */
+ggi_visual_t    vout_SysGetVisual( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * intf_SysCreate: initialize and create GII interface
+ *****************************************************************************/
+int intf_SysCreate( intf_thread_t *p_intf )
+{
+    /* Check that b_video is set */
+    if( !p_main->b_video )
+    {
+        intf_ErrMsg("error: GGI interface require a video output thread\n");
+        return( 1 );
+    }
+
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Spawn video output thread */
+    p_intf->p_vout = vout_CreateThread( main_GetPszVariable( VOUT_DISPLAY_VAR,
+                                                             NULL), 0,
+                                        main_GetIntVariable( VOUT_WIDTH_VAR,
+                                                         VOUT_WIDTH_DEFAULT ),
+                                        main_GetIntVariable( VOUT_HEIGHT_VAR,
+                                                        VOUT_HEIGHT_DEFAULT ),
+                                        NULL, 0,
+                                        (void *)&p_intf->p_sys->p_display );
+
+    fprintf(stderr, "display is %i\n", p_intf->p_sys->p_display);
+    
+    if( p_intf->p_vout == NULL )                                  /* error */
+    {
+        intf_ErrMsg("error: can't create video output thread\n" );
+        free( p_intf->p_sys );
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * intf_SysDestroy: destroy interface
+ *****************************************************************************/
+void intf_SysDestroy( intf_thread_t *p_intf )
+{
+    /* Close input thread, if any (blocking) */
+    if( p_intf->p_input )
+    {
+        input_DestroyThread( p_intf->p_input, NULL );
+    }
+
+    /* Close video output thread, if any (blocking) */
+    if( p_intf->p_vout )
+    {
+        vout_DestroyThread( p_intf->p_vout, NULL );
+    }
+
+    /* Destroy structure */
+    free( p_intf->p_sys );
+}
+
+
+/*****************************************************************************
+ * intf_SysManage: event loop
+ *****************************************************************************/
+void intf_SysManage( intf_thread_t *p_intf )
+{
+    int         i_key;                                        /* unicode key */
+
+    /* For all events in queue */
+    while( ggiKbhit( p_intf->p_sys->p_display ) )
+    {
+        i_key = ggiGetc( p_intf->p_sys->p_display );
+        if( intf_ProcessKey( p_intf, i_key ) )
+        {
+            intf_DbgMsg("unhandled key '%c' (%i)\n", (char) i_key, i_key );
+        }
+    }
+}
+
+
+
diff --git a/plugins/ggi/vout_ggi.c b/plugins/ggi/vout_ggi.c
new file mode 100644 (file)
index 0000000..873f335
--- /dev/null
@@ -0,0 +1,330 @@
+/*****************************************************************************
+ * vout_ggi.c: GGI video output display method
+ *****************************************************************************
+ * Copyright (C) 1998, 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+
+#include <ggi/ggi.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * vout_sys_t: video output GGI method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the GGI specific properties of an output thread.
+ *****************************************************************************/
+typedef struct vout_sys_s
+{
+    /* GGI system informations */
+    ggi_visual_t        p_display;                         /* display device */
+
+    /* Buffers informations */
+    ggi_directbuffer *  p_buffer[2];                              /* buffers */
+    boolean_t           b_must_acquire;   /* must be acquired before writing */
+} vout_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int     GGIOpenDisplay   ( vout_thread_t *p_vout, char *psz_display, void *p_data );
+static void    GGICloseDisplay  ( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * vout_SysCreate: allocate GGI video thread output method
+ *****************************************************************************
+ * This function allocate and initialize a GGI vout method. It uses some of the
+ * vout properties to choose the correct mode, and change them according to the
+ * mode actually used.
+ *****************************************************************************/
+int vout_SysCreate( vout_thread_t *p_vout, char *psz_display, int i_root_window, void *p_data )
+{
+    /* Allocate structure */
+    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+    if( p_vout->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Open and initialize device */
+    if( GGIOpenDisplay( p_vout, psz_display, p_data ) )
+    {
+        intf_ErrMsg("error: can't initialize GGI display\n");
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysInit: initialize GGI video thread output method
+ *****************************************************************************
+ * This function initialize the GGI display device.
+ *****************************************************************************/
+int vout_SysInit( vout_thread_t *p_vout )
+{
+    /* Acquire first buffer */
+    if( p_vout->p_sys->b_must_acquire )
+    {
+        ggiResourceAcquire( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource, GGI_ACTYPE_WRITE );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysEnd: terminate Sys video thread output method
+ *****************************************************************************
+ * Terminate an output method created by vout_SysCreate
+ *****************************************************************************/
+void vout_SysEnd( vout_thread_t *p_vout )
+{
+    /* Release buffer */
+    if( p_vout->p_sys->b_must_acquire )
+    {
+        ggiResourceRelease( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource );
+    }
+}
+
+/*****************************************************************************
+ * vout_SysDestroy: destroy Sys video thread output method
+ *****************************************************************************
+ * Terminate an output method created by vout_SysCreate
+ *****************************************************************************/
+void vout_SysDestroy( vout_thread_t *p_vout )
+{
+    GGICloseDisplay( p_vout );
+    free( p_vout->p_sys );
+}
+
+/*****************************************************************************
+ * vout_SysManage: handle Sys events
+ *****************************************************************************
+ * This function should be called regularly by video output thread. It returns
+ * a non null value if an error occured.
+ *****************************************************************************/
+int vout_SysManage( vout_thread_t *p_vout )
+{
+    /* FIXME: 8bpp: change palette ?? */
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysDisplay: displays previously rendered output
+ *****************************************************************************
+ * This function send the currently rendered image to the display, wait until
+ * it is displayed and switch the two rendering buffer, preparing next frame.
+ *****************************************************************************/
+void vout_SysDisplay( vout_thread_t *p_vout )
+{
+    /* Change display frame */
+    if( p_vout->p_sys->b_must_acquire )
+    {
+        ggiResourceRelease( p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->resource );
+    }
+    ggiFlush( p_vout->p_sys->p_display ); /* XXX?? */
+    ggiSetDisplayFrame( p_vout->p_sys->p_display,
+                        p_vout->p_sys->p_buffer[ p_vout->i_buffer_index ]->frame );
+
+    /* Swap buffers and change write frame */
+    if( p_vout->p_sys->b_must_acquire )
+    {
+        ggiResourceAcquire( p_vout->p_sys->p_buffer[ (p_vout->i_buffer_index + 1) & 1]->resource,
+                            GGI_ACTYPE_WRITE );
+    }
+    ggiSetWriteFrame( p_vout->p_sys->p_display,
+                      p_vout->p_sys->p_buffer[ (p_vout->i_buffer_index + 1) & 1]->frame );
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * GGIOpenDisplay: open and initialize GGI device
+ *****************************************************************************
+ * Open and initialize display according to preferences specified in the vout
+ * thread fields.
+ *****************************************************************************/
+static int GGIOpenDisplay( vout_thread_t *p_vout, char *psz_display, void *p_data )
+{
+    ggi_mode    mode;                                     /* mode descriptor */
+    ggi_color   col_fg;                                  /* foreground color */
+    ggi_color   col_bg;                                  /* background color */
+    int         i_index;                               /* all purposes index */
+
+    /* Initialize library */
+    if( ggiInit() )
+    {
+        intf_ErrMsg("error: can't initialize GGI library\n");
+        return( 1 );
+    }
+
+    /* Open display */
+    p_vout->p_sys->p_display = ggiOpen( psz_display, NULL );
+    if( p_vout->p_sys->p_display == NULL )
+    {
+        intf_ErrMsg("error: can't open GGI default display\n");
+        ggiExit();
+        return( 1 );
+    }
+
+    /* give the data back to the interface */
+    fprintf(stderr, "display is %i\n", p_vout->p_sys->p_display);
+    *(ggi_visual_t *)p_data = p_vout->p_sys->p_display;
+
+    /* Find most appropriate mode */
+    mode.frames =       2;                                      /* 2 buffers */
+    mode.visible.x =    p_vout->i_width;                    /* minimum width */
+    mode.visible.y =    p_vout->i_height;                  /* minimum height */
+    mode.virt.x =       GGI_AUTO;
+    mode.virt.y =       GGI_AUTO;
+    mode.size.x =       GGI_AUTO;
+    mode.size.y =       GGI_AUTO;
+    mode.graphtype =    GT_15BIT;             /* minimum usable screen depth */
+    mode.dpp.x =        GGI_AUTO;
+    mode.dpp.y =        GGI_AUTO;
+    ggiCheckMode( p_vout->p_sys->p_display, &mode );
+
+    /* Check that returned mode has some minimum properties */
+    /* XXX?? */
+
+    /* Set mode */
+    if( ggiSetMode( p_vout->p_sys->p_display, &mode ) )
+    {
+        intf_ErrMsg("error: can't set GGI mode\n");
+        ggiClose( p_vout->p_sys->p_display );
+        ggiExit();
+        return( 1 );
+    }
+
+    /* Check buffers properties */
+    p_vout->p_sys->b_must_acquire = 0;
+    for( i_index = 0; i_index < 2; i_index++ )
+    {
+        /* Get buffer address */
+        p_vout->p_sys->p_buffer[ i_index ] =
+            ggiDBGetBuffer( p_vout->p_sys->p_display, i_index );
+        if( p_vout->p_sys->p_buffer[ i_index ] == NULL )
+        {
+            intf_ErrMsg("error: double buffering is not possible\n");
+            ggiClose( p_vout->p_sys->p_display );
+            ggiExit();
+            return( 1 );
+        }
+
+        /* Check buffer properties */
+        if( ! (p_vout->p_sys->p_buffer[ i_index ]->type & GGI_DB_SIMPLE_PLB) ||
+            (p_vout->p_sys->p_buffer[ i_index ]->page_size != 0) ||
+            (p_vout->p_sys->p_buffer[ i_index ]->write == NULL ) ||
+            (p_vout->p_sys->p_buffer[ i_index ]->noaccess != 0) ||
+            (p_vout->p_sys->p_buffer[ i_index ]->align != 0) )
+        {
+            intf_ErrMsg("error: incorrect video memory type\n");
+            ggiClose( p_vout->p_sys->p_display );
+            ggiExit();
+            return( 1 );
+        }
+
+        /* Check if buffer needs to be acquired before write */
+        if( ggiResourceMustAcquire( p_vout->p_sys->p_buffer[ i_index ]->resource ) )
+        {
+            p_vout->p_sys->b_must_acquire = 1;
+        }
+    }
+#ifdef DEBUG
+    if( p_vout->p_sys->b_must_acquire )
+    {
+        intf_DbgMsg("buffers must be acquired\n");
+    }
+#endif
+
+    /* Set graphic context colors */
+    col_fg.r = col_fg.g = col_fg.b = -1;
+    col_bg.r = col_bg.g = col_bg.b = 0;
+    if( ggiSetGCForeground(p_vout->p_sys->p_display,
+                           ggiMapColor(p_vout->p_sys->p_display,&col_fg)) ||
+        ggiSetGCBackground(p_vout->p_sys->p_display,
+                           ggiMapColor(p_vout->p_sys->p_display,&col_bg)) )
+    {
+        intf_ErrMsg("error: can't set colors\n");
+        ggiClose( p_vout->p_sys->p_display );
+        ggiExit();
+        return( 1 );
+    }
+
+    /* Set clipping for text */
+    if( ggiSetGCClipping(p_vout->p_sys->p_display, 0, 0,
+                         mode.visible.x, mode.visible.y ) )
+    {
+        intf_ErrMsg("error: can't set clipping\n");
+        ggiClose( p_vout->p_sys->p_display );
+        ggiExit();
+        return( 1 );
+    }
+
+    /* Set thread information */
+    p_vout->i_width =           mode.visible.x;
+    p_vout->i_height =          mode.visible.y;
+    p_vout->i_bytes_per_line =  p_vout->p_sys->p_buffer[ 0 ]->buffer.plb.stride;
+    p_vout->i_screen_depth =    p_vout->p_sys->p_buffer[ 0 ]->buffer.plb.pixelformat->depth;
+    p_vout->i_bytes_per_pixel = p_vout->p_sys->p_buffer[ 0 ]->buffer.plb.pixelformat->size / 8;
+    p_vout->i_red_mask =        p_vout->p_sys->p_buffer[ 0 ]->buffer.plb.pixelformat->red_mask;
+    p_vout->i_green_mask =      p_vout->p_sys->p_buffer[ 0 ]->buffer.plb.pixelformat->green_mask;
+    p_vout->i_blue_mask =       p_vout->p_sys->p_buffer[ 0 ]->buffer.plb.pixelformat->blue_mask;
+    /* FIXME: palette in 8bpp ?? */
+
+    /* Set and initialize buffers */
+    vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ]->write, p_vout->p_sys->p_buffer[ 1 ]->write );
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * GGICloseDisplay: close and reset GGI device
+ *****************************************************************************
+ * This function returns all resources allocated by GGIOpenDisplay and restore
+ * the original state of the device.
+ *****************************************************************************/
+static void GGICloseDisplay( vout_thread_t *p_vout )
+{
+    /* Restore original mode and close display */
+    ggiClose( p_vout->p_sys->p_display );
+
+    /* Exit library */
+    ggiExit();
+}
+
diff --git a/plugins/glide/intf_glide.c b/plugins/glide/intf_glide.c
new file mode 100644 (file)
index 0000000..acd1ea7
--- /dev/null
@@ -0,0 +1,119 @@
+/*****************************************************************************
+ * intf_glide.c: 3dfx interface plugin
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <stdlib.h>                                      /* malloc(), free() */
+#include <sys/types.h>                        /* on BSD, uio.h needs types.h */
+#include <sys/uio.h>                                          /* for input.h */
+#include <linutil.h>                            /* Glide kbhit() and getch() */
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "input.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+#include "interface.h"
+
+#include "main.h"
+
+/*****************************************************************************
+ * intf_sys_t: description and status of 3dfx interface
+ *****************************************************************************/
+typedef struct intf_sys_s
+{
+
+} intf_sys_t;
+
+/*****************************************************************************
+ * intf_SysCreate: initialize 3dfx interface
+ *****************************************************************************/
+int intf_SysCreate( intf_thread_t *p_intf )
+{
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        return( 1 );
+    };
+
+    /* Spawn video output thread */
+    if( p_main->b_video )
+    {
+        p_intf->p_vout = vout_CreateThread( NULL, 0, 0, 0, NULL, 0, NULL );
+        if( p_intf->p_vout == NULL )                                /* error */
+        {
+            intf_ErrMsg("intf error: can't create output thread\n" );
+            return( 1 );
+        }
+    }
+    return( 0 );
+}
+
+/*****************************************************************************
+ * intf_SysDestroy: destroy 3dfx interface
+ *****************************************************************************/
+void intf_SysDestroy( intf_thread_t *p_intf )
+{
+    /* Close input thread, if any (blocking) */
+    if( p_intf->p_input )
+    {
+        input_DestroyThread( p_intf->p_input, NULL );
+    }
+
+    /* Close video output thread, if any (blocking) */
+    if( p_intf->p_vout )
+    {
+        vout_DestroyThread( p_intf->p_vout, NULL );
+    }
+
+    /* Destroy structure */
+    free( p_intf->p_sys );
+}
+
+
+/*****************************************************************************
+ * intf_SysManage: event loop
+ *****************************************************************************/
+void intf_SysManage( intf_thread_t *p_intf )
+{
+    unsigned int buf;
+
+    /* very Linux specific - see tlib.c in Glide for other versions */
+    while( kbhit() )
+    {
+        if( intf_ProcessKey(p_intf, (int)buf = getch()) )
+        {
+            intf_ErrMsg( "unhandled key '%c' (%i)\n", (char) buf, buf );
+        }
+    }
+}
+
diff --git a/plugins/glide/vout_glide.c b/plugins/glide/vout_glide.c
new file mode 100644 (file)
index 0000000..6d6ff9c
--- /dev/null
@@ -0,0 +1,273 @@
+/*****************************************************************************
+ * vout_glide.c: 3dfx video output display method for 3dfx cards
+ *****************************************************************************
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+
+#ifndef __linux__
+#include <conio.h>                                            /* for glide ? */
+#endif
+#include <glide.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+#include "main.h"
+
+#define WIDTH 640
+#define HEIGHT 480
+#define BITS_PER_PLANE 16
+#define BYTES_PER_PIXEL 2
+
+/*****************************************************************************
+ * vout_sys_t: Glide video output method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the Glide specific properties of an output thread.
+ *****************************************************************************/
+typedef struct vout_sys_s
+{
+    GrLfbInfo_t                 p_buffer_info;           /* back buffer info */
+
+    /* Dummy video memory */
+    byte_t *                    p_video;                      /* base adress */
+    size_t                      i_page_size;                    /* page size */
+
+} vout_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int     GlideOpenDisplay   ( vout_thread_t *p_vout );
+static void    GlideCloseDisplay  ( vout_thread_t *p_vout );
+
+/*****************************************************************************
+ * vout_SysCreate: allocates Glide video thread output method
+ *****************************************************************************
+ * This function allocates and initializes a Glide vout method.
+ *****************************************************************************/
+int vout_SysCreate( vout_thread_t *p_vout, char *psz_display,
+                    int i_root_window, void *p_data )
+{
+    /* Allocate structure */
+    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+    if( p_vout->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Open and initialize device */
+    if( GlideOpenDisplay( p_vout ) )
+    {
+        intf_ErrMsg("vout error: can't open display\n");
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysInit: initialize Glide video thread output method
+ *****************************************************************************/
+int vout_SysInit( vout_thread_t *p_vout )
+{
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysEnd: terminate Glide video thread output method
+ *****************************************************************************/
+void vout_SysEnd( vout_thread_t *p_vout )
+{
+    ;
+}
+
+/*****************************************************************************
+ * vout_SysDestroy: destroy Glide video thread output method
+ *****************************************************************************
+ * Terminate an output method created by vout_CreateOutputMethod
+ *****************************************************************************/
+void vout_SysDestroy( vout_thread_t *p_vout )
+{
+    GlideCloseDisplay( p_vout );
+    free( p_vout->p_sys );
+}
+
+/*****************************************************************************
+ * vout_SysManage: handle Glide events
+ *****************************************************************************
+ * This function should be called regularly by video output thread. It manages
+ * console events. It returns a non null value on error.
+ *****************************************************************************/
+int vout_SysManage( vout_thread_t *p_vout )
+{
+    return 0;
+}
+
+/*****************************************************************************
+ * vout_SysDisplay: displays previously rendered output
+ *****************************************************************************
+ * This function send the currently rendered image to Glide image, waits until
+ * it is displayed and switch the two rendering buffers, preparing next frame.
+ *****************************************************************************/
+void vout_SysDisplay( vout_thread_t *p_vout )
+{
+    grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
+
+    grBufferSwap( 0 );
+
+    if ( grLfbLock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER,
+                   GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE,
+                   &p_vout->p_sys->p_buffer_info) == FXFALSE )
+    {
+        intf_ErrMsg( "vout error: can't take 3dfx back buffer lock\n" );
+    }
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * GlideOpenDisplay: open and initialize 3dfx device
+ *****************************************************************************/
+
+static int GlideOpenDisplay( vout_thread_t *p_vout )
+{
+    static char version[80];
+    GrHwConfiguration hwconfig;
+    GrScreenResolution_t resolution = GR_RESOLUTION_640x480;
+    GrLfbInfo_t p_front_buffer_info;                    /* front buffer info */
+
+    p_vout->i_width =                   WIDTH;
+    p_vout->i_height =                  HEIGHT;
+    p_vout->i_screen_depth =            BITS_PER_PLANE;
+    p_vout->i_bytes_per_pixel =         BYTES_PER_PIXEL;
+    /* bytes per line value overriden later */
+    p_vout->i_bytes_per_line =          1024 * BYTES_PER_PIXEL;
+
+    p_vout->p_sys->i_page_size = WIDTH * HEIGHT * BYTES_PER_PIXEL;
+
+    p_vout->i_red_mask =   0xf800;
+    p_vout->i_green_mask = 0x07e0;
+    p_vout->i_blue_mask =  0x001f;
+
+    /* Map two framebuffers a the very beginning of the fb */
+    p_vout->p_sys->p_video = malloc( p_vout->p_sys->i_page_size * 2 );
+    if( (int)p_vout->p_sys->p_video == -1 )
+    {
+        intf_ErrMsg( "vout error: can't map video memory (%s)\n", strerror(errno) );
+        return( 1 );
+    }
+
+    grGlideGetVersion( version );
+    grGlideInit();
+
+    if( !grSstQueryHardware(&hwconfig) )
+    {
+        intf_ErrMsg( "vout error: can't get 3dfx hardware config\n" );
+        return( 1 );
+    }
+
+    grSstSelect( 0 );
+    if( !grSstWinOpen(0, resolution, GR_REFRESH_60Hz,
+                        GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1) )
+    {
+        intf_ErrMsg( "vout error: can't open 3dfx screen\n" );
+        return( 1 );
+    }
+
+    /* disable dithering */
+    //grDitherMode( GR_DITHER_DISABLE );
+
+    /* clear both buffers */
+    grRenderBuffer( GR_BUFFER_BACKBUFFER );
+    grBufferClear( 0, 0, 0 );
+    grRenderBuffer( GR_BUFFER_FRONTBUFFER );
+    grBufferClear( 0, 0, 0 );
+    grRenderBuffer( GR_BUFFER_BACKBUFFER );
+
+    p_vout->p_sys->p_buffer_info.size = sizeof( GrLfbInfo_t );
+    p_front_buffer_info.size          = sizeof( GrLfbInfo_t );
+
+    /* lock the buffers to find their adresses */
+    if ( grLfbLock(GR_LFB_WRITE_ONLY, GR_BUFFER_FRONTBUFFER,
+                   GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE,
+                   &p_front_buffer_info) == FXFALSE )
+    {
+        intf_ErrMsg( "vout error: can't take 3dfx front buffer lock\n" );
+        grGlideShutdown();
+        return( 1 );
+    }
+    grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_FRONTBUFFER );
+
+    if ( grLfbLock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER,
+                   GR_LFBWRITEMODE_565, GR_ORIGIN_UPPER_LEFT, FXFALSE,
+                   &p_vout->p_sys->p_buffer_info) == FXFALSE )
+    {
+        intf_ErrMsg( "vout error: can't take 3dfx back buffer lock\n" );
+        grGlideShutdown();
+        return( 1 );
+    }
+    grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
+    
+    /* Get the number of bytes per line */
+    p_vout->i_bytes_per_line = p_vout->p_sys->p_buffer_info.strideInBytes;
+
+    grBufferClear( 0, 0, 0 );
+
+    /* Set and initialize buffers */
+    vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer_info.lfbPtr,
+                     p_front_buffer_info.lfbPtr );
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * GlideCloseDisplay: close and reset 3dfx device
+ *****************************************************************************
+ * Returns all resources allocated by GlideOpenDisplay and restore the original
+ * state of the device.
+ *****************************************************************************/
+static void GlideCloseDisplay( vout_thread_t *p_vout )
+{
+    /* unlock the hidden buffer */
+    grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER );
+
+    /* shutdown Glide */
+    grGlideShutdown();
+    free( p_vout->p_sys->p_video );
+}
+
diff --git a/plugins/gnome/intf_gnome.c b/plugins/gnome/intf_gnome.c
new file mode 100644 (file)
index 0000000..0ed936a
--- /dev/null
@@ -0,0 +1,664 @@
+/*****************************************************************************
+ * intf_gnome.c: Gnome interface
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+#include <sys/types.h>                        /* on BSD, uio.h needs types.h */
+#include <sys/uio.h>                                          /* for input.h */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "input.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "audio_output.h" /* needed for mute */
+
+#include "intf_msg.h"
+#include "interface.h"
+
+#include "main.h"
+
+#include <stdio.h>
+
+#include <gnome.h>
+
+#include "intf_gnome_thread.h"
+#include "intf_gnome.h"
+#include "intf_gnome_interface.h"
+#include "intf_gnome_support.h"
+
+/*****************************************************************************
+ * intf_SysCreate: initialize and create window
+ *****************************************************************************/
+int intf_SysCreate( intf_thread_t *p_intf )
+{
+    char       *psz_display;
+
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        return( 1 );
+    }
+
+    p_intf->p_sys->p_gnome = malloc( sizeof( gnome_thread_t ) );
+    if( p_intf->p_sys->p_gnome == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        free( p_intf->p_sys );
+        return( 1 );
+    }
+
+    /* Open display, unsing 'vlc_display' or DISPLAY environment variable */
+    psz_display = XDisplayName( main_GetPszVariable( VOUT_DISPLAY_VAR, NULL ) );
+    p_intf->p_sys->p_display = XOpenDisplay( psz_display );
+    if( !p_intf->p_sys->p_display )                                 /* error */
+    {
+        intf_ErrMsg("error: can't open display %s\n", psz_display );
+        free( p_intf->p_sys->p_gnome );
+        free( p_intf->p_sys );
+        return( 1 );
+    }
+    p_intf->p_sys->i_screen = DefaultScreen( p_intf->p_sys->p_display );
+
+    /* Spawn base window - this window will include the video output window */
+    if( GnomeCreateWindow( p_intf ) )
+    {
+        intf_ErrMsg( "error: can't create output window\n" );
+        XCloseDisplay( p_intf->p_sys->p_display );
+        free( p_intf->p_sys->p_gnome );
+        free( p_intf->p_sys );
+        return( 1 );
+    }
+
+    /* Spawn video output thread */
+    if( p_main->b_video )
+    {
+        p_intf->p_vout = vout_CreateThread( psz_display, p_intf->p_sys->window,
+                                            p_intf->p_sys->i_width,
+                                            p_intf->p_sys->i_height, NULL, 0,
+                                            (void *)&p_intf->p_sys->colormap );
+
+        if( p_intf->p_vout == NULL )                                /* error */
+        {
+            intf_ErrMsg("error: can't create video output thread\n" );
+            GnomeDestroyWindow( p_intf );
+            XCloseDisplay( p_intf->p_sys->p_display );
+            free( p_intf->p_sys->p_gnome );
+            free( p_intf->p_sys );
+            return( 1 );
+        }
+    }
+
+    /* Spawn Gnome thread */
+    p_intf->p_sys->p_gnome->b_die = 0;
+    p_intf->p_sys->p_gnome->b_error = 0;
+    
+    p_intf->p_sys->p_gnome->b_popup_changed = 0;
+    p_intf->p_sys->p_gnome->b_window_changed = 0;
+    p_intf->p_sys->p_gnome->b_playlist_changed = 0;
+
+    vlc_thread_create( &p_intf->p_sys->p_gnome->thread_id, "gnome",
+                       (void *)GnomeThread, p_intf->p_sys->p_gnome );
+
+    /* Disable screen saver and return */
+    p_intf->p_sys->i_ss_count = 1;
+    GnomeDisableScreenSaver( p_intf );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * intf_SysDestroy: destroy interface window
+ *****************************************************************************/
+void intf_SysDestroy( intf_thread_t *p_intf )
+{
+    /* Enable screen saver */
+    GnomeEnableScreenSaver( p_intf );
+
+    /* Close input thread, if any (blocking) */
+    if( p_intf->p_input )
+    {
+        input_DestroyThread( p_intf->p_input, NULL );
+    }
+
+    /* Close video output thread, if any (blocking) */
+    if( p_intf->p_vout )
+    {
+        vout_DestroyThread( p_intf->p_vout, NULL );
+    }
+
+    /* Close gnome thread, if any (blocking) */
+    if( p_intf->p_sys->p_gnome->thread_id )
+    {
+        p_intf->p_sys->p_gnome->b_die = 1;
+        intf_Msg( "waiting for Gnome thread to terminate\n" );
+        vlc_thread_join( p_intf->p_sys->p_gnome->thread_id );
+        intf_Msg( "Gnome thread terminated\n" );
+    }
+
+    /* Close main window and display */
+    GnomeDestroyWindow( p_intf );
+    XCloseDisplay( p_intf->p_sys->p_display );
+
+    /* Destroy structures */
+    free( p_intf->p_sys->p_gnome );
+    free( p_intf->p_sys );
+}
+
+/*****************************************************************************
+ * intf_SysManage: event loop
+ *****************************************************************************/
+void intf_SysManage( intf_thread_t *p_intf )
+{
+    /* Manage main window */
+    GnomeManageWindow( p_intf );
+
+    /* Manage messages from the Gnome interface */
+    GnomeManageInterface( p_intf );
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * GnomeCreateWindow: open and set-up X11 main window
+ *****************************************************************************/
+static int GnomeCreateWindow( intf_thread_t *p_intf )
+{
+    XSizeHints              xsize_hints;
+    XSetWindowAttributes    xwindow_attributes;
+    XGCValues               xgcvalues;
+    XEvent                  xevent;
+    boolean_t               b_expose;
+    boolean_t               b_configure_notify;
+    boolean_t               b_map_notify;
+
+    /* Set main window's size */
+    p_intf->p_sys->i_width =  main_GetIntVariable( VOUT_WIDTH_VAR,
+                                                   VOUT_WIDTH_DEFAULT );
+    p_intf->p_sys->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR,
+                                                   VOUT_HEIGHT_DEFAULT );
+
+    /* Prepare window manager hints and properties */
+    xsize_hints.base_width =            p_intf->p_sys->i_width;
+    xsize_hints.base_height =           p_intf->p_sys->i_height;
+    xsize_hints.flags =                 PSize;
+    p_intf->p_sys->wm_protocols =       XInternAtom( p_intf->p_sys->p_display,
+                                                     "WM_PROTOCOLS", True );
+    p_intf->p_sys->wm_delete_window =   XInternAtom( p_intf->p_sys->p_display,
+                                                     "WM_DELETE_WINDOW", True );
+
+    /* Prepare window attributes */
+    xwindow_attributes.backing_store = Always;       /* save the hidden part */
+    xwindow_attributes.background_pixel = WhitePixel( p_intf->p_sys->p_display,
+                                                      p_intf->p_sys->i_screen );
+
+    xwindow_attributes.event_mask = ExposureMask | StructureNotifyMask;
+
+    /* Create the window and set hints - the window must receive ConfigureNotify
+     * events, and, until it is displayed, Expose and MapNotify events. */
+    p_intf->p_sys->window =
+            XCreateWindow( p_intf->p_sys->p_display,
+                           DefaultRootWindow( p_intf->p_sys->p_display ),
+                           0, 0,
+                           p_intf->p_sys->i_width, p_intf->p_sys->i_height, 1,
+                           0, InputOutput, 0,
+                           CWBackingStore | CWBackPixel | CWEventMask,
+                           &xwindow_attributes );
+
+    /* Set window manager hints and properties: size hints, command,
+     * window's name, and accepted protocols */
+    XSetWMNormalHints( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                       &xsize_hints );
+    XSetCommand( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                 p_main->ppsz_argv, p_main->i_argc );
+    XStoreName( p_intf->p_sys->p_display, p_intf->p_sys->window, VOUT_TITLE );
+    if( (p_intf->p_sys->wm_protocols == None)        /* use WM_DELETE_WINDOW */
+        || (p_intf->p_sys->wm_delete_window == None)
+        || !XSetWMProtocols( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                             &p_intf->p_sys->wm_delete_window, 1 ) )
+    {
+        /* WM_DELETE_WINDOW is not supported by window manager */
+        intf_Msg("error: missing or bad window manager - please exit program kindly.\n");
+    }
+
+    /* Creation of a graphic context that doesn't generate a GraphicsExpose
+     * event when using functions like XCopyArea */
+    xgcvalues.graphics_exposures = False;
+    p_intf->p_sys->gc =  XCreateGC( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                                    GCGraphicsExposures, &xgcvalues);
+
+    /* Send orders to server, and wait until window is displayed - three
+     * events must be received: a MapNotify event, an Expose event allowing
+     * drawing in the window, and a ConfigureNotify to get the window
+     * dimensions. Once those events have been received, only ConfigureNotify
+     * events need to be received. */
+    b_expose = 0;
+    b_configure_notify = 0;
+    b_map_notify = 0;
+    XMapWindow( p_intf->p_sys->p_display, p_intf->p_sys->window);
+    do
+    {
+        XNextEvent( p_intf->p_sys->p_display, &xevent);
+        if( (xevent.type == Expose)
+            && (xevent.xexpose.window == p_intf->p_sys->window) )
+        {
+            b_expose = 1;
+        }
+        else if( (xevent.type == MapNotify)
+                 && (xevent.xmap.window == p_intf->p_sys->window) )
+        {
+            b_map_notify = 1;
+        }
+        else if( (xevent.type == ConfigureNotify)
+                 && (xevent.xconfigure.window == p_intf->p_sys->window) )
+        {
+            b_configure_notify = 1;
+            p_intf->p_sys->i_width = xevent.xconfigure.width;
+            p_intf->p_sys->i_height = xevent.xconfigure.height;
+        }
+    } while( !( b_expose && b_configure_notify && b_map_notify ) );
+
+    XSelectInput( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                  StructureNotifyMask | KeyPressMask | ButtonPressMask );
+
+    if( XDefaultDepth(p_intf->p_sys->p_display, p_intf->p_sys->i_screen) == 8 )
+    {
+        /* Allocate a new palette */
+        p_intf->p_sys->colormap = XCreateColormap( p_intf->p_sys->p_display,
+                              DefaultRootWindow( p_intf->p_sys->p_display ),
+                              DefaultVisual( p_intf->p_sys->p_display,
+                                             p_intf->p_sys->i_screen ),
+                              AllocAll );
+
+        xwindow_attributes.colormap = p_intf->p_sys->colormap;
+        XChangeWindowAttributes( p_intf->p_sys->p_display,
+                                 p_intf->p_sys->window,
+                                 CWColormap, &xwindow_attributes );
+    }
+
+    /* At this stage, the window is open, displayed, and ready to receive data */
+    return( 0 );
+}
+
+/*****************************************************************************
+ * GnomeDestroyWindow: destroy X11 main window
+ *****************************************************************************/
+static void GnomeDestroyWindow( intf_thread_t *p_intf )
+{
+    XUnmapWindow( p_intf->p_sys->p_display, p_intf->p_sys->window );
+    XFreeGC( p_intf->p_sys->p_display, p_intf->p_sys->gc );
+    XDestroyWindow( p_intf->p_sys->p_display, p_intf->p_sys->window );
+}
+
+/*****************************************************************************
+ * GnomeManageWindow: manage X11 main window
+ *****************************************************************************/
+static void GnomeManageWindow( intf_thread_t *p_intf )
+{
+    XEvent      xevent;                                         /* X11 event */
+    boolean_t   b_resized;                        /* window has been resized */
+    char        i_key;                                    /* ISO Latin-1 key */
+
+    /* Handle X11 events: ConfigureNotify events are parsed to know if the
+     * output window's size changed, MapNotify and UnmapNotify to know if the
+     * window is mapped (and if the display is useful), and ClientMessages
+     * to intercept window destruction requests */
+    b_resized = 0;
+    while( XCheckWindowEvent( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                              StructureNotifyMask | KeyPressMask |
+                              ButtonPressMask, &xevent ) == True )
+    {
+        /* ConfigureNotify event: prepare  */
+        if( (xevent.type == ConfigureNotify)
+            && ((xevent.xconfigure.width != p_intf->p_sys->i_width)
+                || (xevent.xconfigure.height != p_intf->p_sys->i_height)) )
+        {
+            /* Update dimensions */
+            b_resized = 1;
+            p_intf->p_sys->i_width = xevent.xconfigure.width;
+            p_intf->p_sys->i_height = xevent.xconfigure.height;
+        }
+        /* MapNotify event: change window status and disable screen saver */
+        else if( xevent.type == MapNotify)
+        {
+            if( (p_intf->p_vout != NULL) && !p_intf->p_vout->b_active )
+            {
+                GnomeDisableScreenSaver( p_intf );
+                p_intf->p_vout->b_active = 1;
+            }
+        }
+        /* UnmapNotify event: change window status and enable screen saver */
+        else if( xevent.type == UnmapNotify )
+        {
+            if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_active )
+            {
+                GnomeEnableScreenSaver( p_intf );
+                p_intf->p_vout->b_active = 0;
+            }
+        }
+        /* Keyboard event */
+        else if( xevent.type == KeyPress )
+        {
+            if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
+            {
+                if( intf_ProcessKey( p_intf, i_key ) )
+                {
+                    intf_DbgMsg( "unhandled key '%c' (%i)\n", (char) i_key, i_key );
+                }
+            }
+        }
+        /* Mouse click */
+        else if( xevent.type == ButtonPress )
+        {
+            switch( ((XButtonEvent *)&xevent)->button )
+            {
+                case Button1:
+                    /* in this part we will eventually manage
+                     * clicks for DVD navigation for instance */
+                    break;
+
+                case Button2:
+                    GnomeTogglePointer( p_intf );
+                    break;
+
+                case Button3:
+                    /* toggle the menu display */
+                    vlc_mutex_lock( &p_intf->p_sys->p_gnome->change_lock );
+                    p_intf->p_sys->p_gnome->b_popup_changed = 1;
+                    vlc_mutex_unlock( &p_intf->p_sys->p_gnome->change_lock );
+                    break;
+            }
+
+        }
+#ifdef DEBUG
+        /* Other event */
+        else
+        {
+            intf_DbgMsg( "%p -> unhandled event type %d received\n",
+                         p_intf, xevent.type );
+        }
+#endif
+    }
+
+    /* ClientMessage event - only WM_PROTOCOLS with WM_DELETE_WINDOW data
+     * are handled - according to the man pages, the format is always 32
+     * in this case */
+    while( XCheckTypedEvent( p_intf->p_sys->p_display,
+                             ClientMessage, &xevent ) )
+    {
+        if( (xevent.xclient.message_type == p_intf->p_sys->wm_protocols)
+            && (xevent.xclient.data.l[0] == p_intf->p_sys->wm_delete_window ) )
+        {
+            p_intf->b_die = 1;
+        }
+        else
+        {
+            intf_DbgMsg( "%p -> unhandled ClientMessage received\n", p_intf );
+        }
+    }
+
+    /*
+     * Handle vout or interface windows resizing
+     */
+    if( p_intf->p_vout != NULL )
+    {
+        if( b_resized )
+        {
+            /* If interface window has been resized, change vout size */
+            intf_DbgMsg( "resizing output window\n" );
+            vlc_mutex_lock( &p_intf->p_vout->change_lock );
+            p_intf->p_vout->i_width =  p_intf->p_sys->i_width;
+            p_intf->p_vout->i_height = p_intf->p_sys->i_height;
+            p_intf->p_vout->i_changes |= VOUT_SIZE_CHANGE;
+            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
+        }
+        else if( (p_intf->p_vout->i_width  != p_intf->p_sys->i_width) ||
+                 (p_intf->p_vout->i_height != p_intf->p_sys->i_height) )
+        {
+           /* If video output size has changed, change interface window size */
+            intf_DbgMsg( "resizing output window\n" );
+            p_intf->p_sys->i_width =    p_intf->p_vout->i_width;
+            p_intf->p_sys->i_height =   p_intf->p_vout->i_height;
+            XResizeWindow( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                           p_intf->p_sys->i_width, p_intf->p_sys->i_height );
+        }
+    }
+}
+
+/*****************************************************************************
+ * GnomeEnableScreenSaver: enable screen saver
+ *****************************************************************************
+ * This function enable the screen saver on a display after it had been
+ * disabled by XDisableScreenSaver. Both functions use a counter mechanism to
+ * know wether the screen saver can be activated or not: if n successive calls
+ * are made to XDisableScreenSaver, n successive calls to XEnableScreenSaver
+ * will be required before the screen saver could effectively be activated.
+ *****************************************************************************/
+void GnomeEnableScreenSaver( intf_thread_t *p_intf )
+{
+    if( p_intf->p_sys->i_ss_count++ == 0 )
+    {
+        intf_Msg( "Enabling screen saver\n" );
+        XSetScreenSaver( p_intf->p_sys->p_display, p_intf->p_sys->i_ss_timeout,
+                         p_intf->p_sys->i_ss_interval, p_intf->p_sys->i_ss_blanking,
+                         p_intf->p_sys->i_ss_exposure );
+    }
+}
+
+/*****************************************************************************
+ * GnomeDisableScreenSaver: disable screen saver
+ *****************************************************************************
+ * See XEnableScreenSaver
+ *****************************************************************************/
+void GnomeDisableScreenSaver( intf_thread_t *p_intf )
+{
+    if( --p_intf->p_sys->i_ss_count == 0 )
+    {
+        /* Save screen saver informations */
+        XGetScreenSaver( p_intf->p_sys->p_display, &p_intf->p_sys->i_ss_timeout,
+                         &p_intf->p_sys->i_ss_interval, &p_intf->p_sys->i_ss_blanking,
+                         &p_intf->p_sys->i_ss_exposure );
+
+        /* Disable screen saver */
+        intf_Msg("Disabling screen saver\n");
+        XSetScreenSaver( p_intf->p_sys->p_display, 0,
+                         p_intf->p_sys->i_ss_interval, p_intf->p_sys->i_ss_blanking,
+                         p_intf->p_sys->i_ss_exposure );
+    }
+}
+
+/*****************************************************************************
+ * GnomeTogglePointer: hide or show the mouse pointer
+ *****************************************************************************
+ * This function hides the X pointer if it is visible by putting it at
+ * coordinates (32,32) and setting the pointer sprite to a blank one. To
+ * show it again, we disable the sprite and restore the original coordinates.
+ *****************************************************************************/
+void GnomeTogglePointer( intf_thread_t *p_intf )
+{
+    static Cursor cursor;
+    static boolean_t b_cursor = 0;
+
+    if( p_intf->p_sys->b_mouse )
+    {
+        p_intf->p_sys->b_mouse = 0;
+
+        if( !b_cursor )
+        {
+            XColor color;
+            Pixmap blank = XCreatePixmap( p_intf->p_sys->p_display,
+                               DefaultRootWindow(p_intf->p_sys->p_display),
+                               1, 1, 1 );
+
+            XParseColor( p_intf->p_sys->p_display,
+                         XCreateColormap( p_intf->p_sys->p_display,
+                                          DefaultRootWindow(
+                                                  p_intf->p_sys->p_display ),
+                                          DefaultVisual(
+                                                  p_intf->p_sys->p_display,
+                                                  p_intf->p_sys->i_screen ),
+                                          AllocNone ),
+                         "black", &color );
+
+            cursor = XCreatePixmapCursor( p_intf->p_sys->p_display,
+                           blank, blank, &color, &color, 1, 1 );
+
+            b_cursor = 1;
+        }
+        XDefineCursor( p_intf->p_sys->p_display,
+                       p_intf->p_sys->window, cursor );
+    }
+    else
+    {
+        p_intf->p_sys->b_mouse = 1;
+
+        XUndefineCursor( p_intf->p_sys->p_display, p_intf->p_sys->window );
+    }
+}
+
+/*****************************************************************************
+ * GnomeManageInterface: manage messages from the Gnome interface
+
+ *****************************************************************************
+ * In this function, called approx. 10 times a second, we check what the
+ * Gnome interface wanted to tell us.
+ *****************************************************************************/
+static void GnomeManageInterface( intf_thread_t *p_intf )
+{
+    gnome_thread_t *p_gnome = p_intf->p_sys->p_gnome;
+
+    /* lock the change structure */
+    vlc_mutex_lock( &p_gnome->change_lock );
+
+    /* you killed my father, prepare to die */
+    if( p_gnome->b_die )
+    {
+        p_intf->b_die = 1;
+    }
+
+    if( p_gnome->b_activity_changed )
+    {
+        vlc_mutex_lock( &p_intf->p_vout->picture_lock );
+        p_intf->p_vout->b_active = p_gnome->b_activity;
+        /* having to access p_main sucks */
+        p_main->p_aout->b_active = p_gnome->b_activity;
+        vlc_mutex_unlock( &p_intf->p_vout->picture_lock );
+
+        p_gnome->b_activity_changed = 0;
+    }
+
+    /* unlock the change structure */
+    vlc_mutex_unlock( &p_gnome->change_lock );
+}
+
+/*****************************************************************************
+ * GnomeManageMain: manage main thread messages
+ *****************************************************************************
+ * In this function, called approx. 10 times a second, we check what the
+ * main program wanted to tell us.
+ *****************************************************************************/
+static gint GnomeManageMain( gpointer p_data )
+{
+    gnome_thread_t *p_gnome = (void *)p_data;
+
+    /* lock the change structure */
+    vlc_mutex_lock( &p_gnome->change_lock );
+
+    if( p_gnome->b_die )
+    {
+        /* unlock the change structure */
+        vlc_mutex_unlock( &p_gnome->change_lock );
+
+        /* prepare to die, young man */
+        gtk_main_quit();
+        return( FALSE );
+    }
+
+    /* if the "display popup" flag has changed */
+    if( p_gnome->b_popup_changed )
+    {
+        gnome_popup_menu_do_popup( p_gnome->p_popup,
+                                   NULL, NULL, NULL, NULL );
+        p_gnome->b_popup_changed = 0;
+    }
+
+    /* unlock the change structure */
+    vlc_mutex_unlock( &p_gnome->change_lock );
+
+    return( TRUE );
+}
+
+/*****************************************************************************
+ * GnomeThread: special Gnome thread
+ *****************************************************************************
+ * this part of the interface is in a separate thread so that we can call
+ * gtk_main() from within it without annoying the rest of the program.
+ * XXX: the approach may look kludgy, and probably is, but I could not find
+ * a better way to dynamically load a Gnome interface at runtime.
+ *****************************************************************************/
+void GnomeThread( gnome_thread_t *p_gnome )
+{
+    /* gnome_init needs to know the command line. We don't care, so we
+     * give it an empty one */
+    char *p_args[] = { };
+
+    /* Sleep to avoid using all CPU - since some interfaces needs to access
+     * keyboard events, a 100ms delay is a good compromise */
+    gtk_timeout_add( INTF_IDLE_SLEEP / 1000, GnomeManageMain, p_gnome );
+    gnome_init( "vlc", VERSION, 1, p_args );
+
+    /* create some useful widgets that will certainly be used */
+    p_gnome->p_window = create_intf_window();
+    p_gnome->p_popup = create_intf_popup( );
+
+    /* we don't create these ones yet because we perhaps won't need them */
+    p_gnome->p_about = NULL;
+    p_gnome->p_playlist = NULL;
+
+    /* store p_sys to keep an eye on it */
+    gtk_object_set_data( GTK_OBJECT(p_gnome->p_window), "p_gnome", p_gnome );
+    gtk_object_set_data( GTK_OBJECT(p_gnome->p_popup), "p_gnome", p_gnome );
+
+    /* show the control window */
+    //gtk_widget_show( p_gnome->p_window );
+
+    /* enter gnome mode */
+    gtk_main();
+}
+
diff --git a/plugins/gnome/intf_gnome.h b/plugins/gnome/intf_gnome.h
new file mode 100644 (file)
index 0000000..198e54e
--- /dev/null
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * intf_gnome.h: Gnome interface
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Boston, MA 02111-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * intf_sys_t: description and status of Gnome interface
+ *****************************************************************************/
+typedef struct intf_sys_s
+{
+    /* X11 generic properties */
+    Display *           p_display;                    /* X11 display pointer */
+    int                 i_screen;                              /* X11 screen */
+    Atom                wm_protocols;
+    Atom                wm_delete_window;
+
+    /* Main window properties */
+    Window              window;                               /* main window */
+    GC                  gc;               /* graphic context for main window */
+    int                 i_width;                     /* width of main window */
+    int                 i_height;                   /* height of main window */
+    Colormap            colormap;               /* colormap used (8bpp only) */
+
+    /* Screen saver properties */
+    int                 i_ss_count;              /* enabling/disabling count */
+    int                 i_ss_timeout;                             /* timeout */
+    int                 i_ss_interval;           /* interval between changes */
+    int                 i_ss_blanking;                      /* blanking mode */
+    int                 i_ss_exposure;                      /* exposure mode */
+
+    /* Mouse pointer properties */
+    boolean_t           b_mouse;         /* is the mouse pointer displayed ? */
+
+    /* Gnome part properties */
+    gnome_thread_t *    p_gnome;
+
+} intf_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  GnomeCreateWindow             ( intf_thread_t *p_intf );
+static void GnomeDestroyWindow            ( intf_thread_t *p_intf );
+static void GnomeManageInterface          ( intf_thread_t *p_intf );
+static gint GnomeManageMain               ( gpointer p_data );
+static void GnomeManageWindow             ( intf_thread_t *p_intf );
+static void GnomeEnableScreenSaver        ( intf_thread_t *p_intf );
+static void GnomeDisableScreenSaver       ( intf_thread_t *p_intf );
+static void GnomeTogglePointer            ( intf_thread_t *p_intf );
+
diff --git a/plugins/gnome/intf_gnome_callbacks.c b/plugins/gnome/intf_gnome_callbacks.c
new file mode 100644 (file)
index 0000000..d01088c
--- /dev/null
@@ -0,0 +1,500 @@
+#include "defs.h"
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+
+#include <gnome.h>
+
+#include "intf_gnome_thread.h"
+#include "intf_gnome_callbacks.h"
+#include "intf_gnome_interface.h"
+#include "intf_gnome_support.h"
+
+#define GET_GNOME_STRUCT( item, parent ) \
+gtk_object_get_data( \
+    GTK_OBJECT( lookup_widget(GTK_WIDGET(item), parent) ), \
+    "p_gnome" );
+
+void
+on_modules_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_exit_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" );
+
+    p_gnome->b_die = 1;
+}
+
+
+void
+on_open_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_preferences_activate                (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_plugins_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_about_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" );
+
+    if( !GTK_IS_WIDGET( p_gnome->p_about ) )
+    {
+        p_gnome->p_about = create_intf_about ();
+    }
+    gtk_widget_show( p_gnome->p_about );
+}
+
+
+void
+on_stop_clicked                        (GtkButton       *button,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_control_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" );
+
+    /* lock the change structure */
+    vlc_mutex_lock( &p_gnome->change_lock );
+
+    if( p_gnome->b_window )
+    {
+        gtk_widget_hide( p_gnome->p_window );
+        p_gnome->b_window = 0;
+    }
+    else
+    {
+        if( !GTK_IS_WIDGET( p_gnome->p_window ) )
+        {
+            p_gnome->p_window = create_intf_window ();
+        }
+        gtk_widget_show( p_gnome->p_window );
+        gtk_object_set_data( GTK_OBJECT(p_gnome->p_window),
+                             "p_gnome", p_gnome );
+        p_gnome->b_window = 1;
+    }
+
+    /* unlock the change structure */
+    vlc_mutex_unlock( &p_gnome->change_lock );
+}
+
+
+void
+on_playlist_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_window" );
+
+    /* lock the change structure */
+    vlc_mutex_lock( &p_gnome->change_lock );
+
+    if( p_gnome->b_playlist )
+    {
+        gtk_widget_hide( p_gnome->p_playlist );
+        p_gnome->b_playlist = 0;
+    }
+    else
+    {
+        if( !GTK_IS_WIDGET( p_gnome->p_playlist ) )
+        {
+            p_gnome->p_playlist = create_intf_playlist ();
+        }
+        gtk_widget_show( p_gnome->p_playlist );
+        gtk_object_set_data( GTK_OBJECT(p_gnome->p_playlist),
+                             "p_gnome", p_gnome );
+        p_gnome->b_playlist = 1;
+    }
+
+    /* unlock the change structure */
+    vlc_mutex_unlock( &p_gnome->change_lock );
+}
+
+void
+on_popup_control_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+
+    /* lock the change structure */
+    vlc_mutex_lock( &p_gnome->change_lock );
+
+    if( p_gnome->b_window )
+    {
+        gtk_widget_hide( p_gnome->p_window );
+        p_gnome->b_window = 0;
+    }
+    else
+    {
+        if( !GTK_IS_WIDGET( p_gnome->p_window ) )
+        {
+            p_gnome->p_window = create_intf_window ();
+        }
+        gtk_widget_show( p_gnome->p_window );
+        gtk_object_set_data( GTK_OBJECT(p_gnome->p_window),
+                             "p_gnome", p_gnome );
+        p_gnome->b_window = 1;
+    }
+
+    /* unlock the change structure */
+    vlc_mutex_unlock( &p_gnome->change_lock );
+}
+
+
+void
+on_popup_playlist_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+
+    /* lock the change structure */
+    vlc_mutex_lock( &p_gnome->change_lock );
+
+    if( p_gnome->b_playlist )
+    {
+        gtk_widget_hide( p_gnome->p_playlist );
+        p_gnome->b_playlist = 0;
+    }
+    else
+    {
+        if( !GTK_IS_WIDGET( p_gnome->p_playlist ) )
+        {
+            p_gnome->p_playlist = create_intf_playlist ();
+        }
+        gtk_widget_show( p_gnome->p_playlist );
+        gtk_object_set_data( GTK_OBJECT(p_gnome->p_playlist),
+                             "p_gnome", p_gnome );
+        p_gnome->b_playlist = 1;
+    }
+
+    /* unlock the change structure */
+    vlc_mutex_unlock( &p_gnome->change_lock );
+}
+
+
+
+void
+on_popup_exit_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+
+    p_gnome->b_die = 1;
+}
+
+
+void
+on_popup_about_activate                (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+
+    if( !GTK_IS_WIDGET( p_gnome->p_about ) )
+    {
+        p_gnome->p_about = create_intf_about ();
+    }
+    gtk_widget_show( p_gnome->p_about );
+}
+
+
+void
+on_intf_window_destroy                 (GtkObject       *object,
+                                        gpointer         user_data)
+{
+   fprintf( stderr, "interface window destroyed !\n" );
+}
+
+
+void
+on_intf_playlist_destroy               (GtkObject       *object,
+                                        gpointer         user_data)
+{
+   fprintf( stderr, "playlist window destroyed !\n" );
+}
+
+
+
+void
+on_channel1_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_channel2_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_channel3_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_channel4_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_channel5_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_popup_channel1_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_popup_channel2_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_popup_channel3_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_popup_channel4_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_popup_channel5_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_popup_config_channels_activate      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_config_channels_activate            (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_user_guide_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_popup_stop_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_popup_play_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+
+    vlc_mutex_lock( &p_gnome->change_lock );
+    p_gnome->b_activity_changed = 1;
+    p_gnome->b_activity = 1;
+    vlc_mutex_unlock( &p_gnome->change_lock );
+}
+
+
+void
+on_playlist_close_clicked              (GtkButton       *button,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_play_clicked                        (GtkButton       *button,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( button, "intf_window" );
+
+    vlc_mutex_lock( &p_gnome->change_lock );
+    p_gnome->b_activity_changed = 1;
+    p_gnome->b_activity = 1;
+    vlc_mutex_unlock( &p_gnome->change_lock );
+}
+
+
+void
+on_channel0_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_popup_channel0_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_open_clicked                        (GtkButton       *button,
+                                        gpointer         user_data)
+{
+    GnomeUIInfo test_uiinfo[] =
+    {
+        {
+            GNOME_APP_UI_ITEM, N_( "Barf" ),
+            NULL,
+            on_exit_activate, NULL, NULL,
+            GNOME_APP_PIXMAP_NONE, NULL,
+            0, 0, NULL
+        }
+    };
+
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( button, "intf_window" );
+
+    gnome_app_insert_menus (GNOME_APP (p_gnome->p_window),
+                              "_View/Channel/None",
+                              test_uiinfo);
+}
+
+
+void
+on_pause_clicked                       (GtkButton       *button,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( button, "intf_window" );
+
+    vlc_mutex_lock( &p_gnome->change_lock );
+    p_gnome->b_activity_changed = 1;
+    p_gnome->b_activity = 0;
+    vlc_mutex_unlock( &p_gnome->change_lock );
+}
+
+
+void
+on_popup_pause_activate                (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+    gnome_thread_t *p_gnome;
+
+    p_gnome = GET_GNOME_STRUCT( menuitem, "intf_popup" );
+
+    vlc_mutex_lock( &p_gnome->change_lock );
+    p_gnome->b_activity_changed = 1;
+    p_gnome->b_activity = 0;
+    vlc_mutex_unlock( &p_gnome->change_lock );
+}
+
+
+
+void
+on_mute_clicked                        (GtkButton       *button,
+                                        gpointer         user_data)
+{
+
+}
+
+
+void
+on_popup_mute_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+
+}
+
diff --git a/plugins/gnome/intf_gnome_callbacks.h b/plugins/gnome/intf_gnome_callbacks.h
new file mode 100644 (file)
index 0000000..f0d450a
--- /dev/null
@@ -0,0 +1,216 @@
+/* make VERSION visible to all Gnome components */
+#include "config.h"
+#include <gnome.h>
+
+
+void
+on_open_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_preferences_activate                (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_modules_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_about_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_exit_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_open_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_hide_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_exit_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_preferences_activate                (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_plugins_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_about_activate                      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_show_activate                       (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_stop_clicked                        (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_popup_control_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_playlist_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_control_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_playlist_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_exit_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_about_activate                (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_intf_window_destroy                 (GtkObject       *object,
+                                        gpointer         user_data);
+
+void
+on_intf_playlist_destroy               (GtkObject       *object,
+                                        gpointer         user_data);
+
+void
+on_control_activate                    (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_playlist_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_channel1_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_channel2_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_channel3_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_channel4_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_channel5_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_channel1_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_channel2_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_channel3_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_channel4_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_channel5_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_config_channels_activate      (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_channel1_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_channel2_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_channel3_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_channel4_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_channel5_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_config_channels_activate            (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_user_guide_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_stop_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_play_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_playlist_close_clicked              (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_play_clicked                        (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_channel0_activate                   (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_popup_channel0_activate             (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_open_clicked                        (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_pause_clicked                       (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_popup_pause_activate                (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_stop_clicked                        (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_mute_clicked                        (GtkButton       *button,
+                                        gpointer         user_data);
+
+void
+on_popup_mute_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
diff --git a/plugins/gnome/intf_gnome_interface.c b/plugins/gnome/intf_gnome_interface.c
new file mode 100644 (file)
index 0000000..a9c60d7
--- /dev/null
@@ -0,0 +1,811 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <gnome.h>
+
+#include "intf_gnome_callbacks.h"
+#include "intf_gnome_interface.h"
+#include "intf_gnome_support.h"
+
+static GnomeUIInfo file_menu_menu_uiinfo[] =
+{
+  GNOMEUIINFO_MENU_OPEN_ITEM (on_open_activate, NULL),
+  GNOMEUIINFO_SEPARATOR,
+  GNOMEUIINFO_MENU_EXIT_ITEM (on_exit_activate, NULL),
+  GNOMEUIINFO_END
+};
+
+static GnomeUIInfo channel_menu_uiinfo[] =
+{
+  {
+    GNOME_APP_UI_ITEM, N_("None"),
+    NULL,
+    on_channel0_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("1"),
+    NULL,
+    on_channel1_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("2"),
+    NULL,
+    on_channel2_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("3"),
+    NULL,
+    on_channel3_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("4"),
+    NULL,
+    on_channel4_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("5"),
+    NULL,
+    on_channel5_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("Configure..."),
+    NULL,
+    on_config_channels_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  GNOMEUIINFO_END
+};
+
+static GnomeUIInfo view_menu_menu_uiinfo[] =
+{
+  {
+    GNOME_APP_UI_ITEM, N_("Control window"),
+    NULL,
+    on_control_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_EXEC,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("Playlist"),
+    NULL,
+    on_playlist_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_INDEX,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_SUBTREE, N_("Channel"),
+    NULL,
+    channel_menu_uiinfo, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  GNOMEUIINFO_END
+};
+
+static GnomeUIInfo settings_menu_menu_uiinfo[] =
+{
+  GNOMEUIINFO_MENU_PREFERENCES_ITEM (on_preferences_activate, NULL),
+  {
+    GNOME_APP_UI_ITEM, N_("Plugins..."),
+    NULL,
+    on_plugins_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  GNOMEUIINFO_END
+};
+
+static GnomeUIInfo help_menu_menu_uiinfo[] =
+{
+  {
+    GNOME_APP_UI_ITEM, N_("User guide"),
+    NULL,
+    on_user_guide_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  GNOMEUIINFO_MENU_ABOUT_ITEM (on_about_activate, NULL),
+  GNOMEUIINFO_END
+};
+
+static GnomeUIInfo menubar_uiinfo[] =
+{
+  GNOMEUIINFO_MENU_FILE_TREE (file_menu_menu_uiinfo),
+  GNOMEUIINFO_MENU_VIEW_TREE (view_menu_menu_uiinfo),
+  GNOMEUIINFO_MENU_SETTINGS_TREE (settings_menu_menu_uiinfo),
+  GNOMEUIINFO_MENU_HELP_TREE (help_menu_menu_uiinfo),
+  GNOMEUIINFO_END
+};
+
+GtkWidget*
+create_intf_window (void)
+{
+  GtkWidget *intf_window;
+  GtkWidget *dock;
+  GtkWidget *toolbar;
+  GtkWidget *tmp_toolbar_icon;
+  GtkWidget *open;
+  GtkWidget *jump;
+  GtkWidget *vseparator1;
+  GtkWidget *prev;
+  GtkWidget *rewind;
+  GtkWidget *stop;
+  GtkWidget *play;
+  GtkWidget *next;
+  GtkWidget *vseparator2;
+  GtkWidget *pause;
+  GtkWidget *mute;
+  GtkWidget *table1;
+  GtkWidget *hscale1;
+  GtkWidget *appbar;
+
+  intf_window = gnome_app_new ("Vlc", _("VideoLAN Client"));
+  gtk_object_set_data (GTK_OBJECT (intf_window), "intf_window", intf_window);
+
+  dock = GNOME_APP (intf_window)->dock;
+  gtk_widget_ref (dock);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "dock", dock,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (dock);
+
+  gnome_app_create_menus (GNOME_APP (intf_window), menubar_uiinfo);
+
+  gtk_widget_ref (menubar_uiinfo[0].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "file_menu",
+                            menubar_uiinfo[0].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (file_menu_menu_uiinfo[0].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "open",
+                            file_menu_menu_uiinfo[0].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (file_menu_menu_uiinfo[1].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "separator1",
+                            file_menu_menu_uiinfo[1].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (file_menu_menu_uiinfo[2].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "exit",
+                            file_menu_menu_uiinfo[2].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (menubar_uiinfo[1].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "view_menu",
+                            menubar_uiinfo[1].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (view_menu_menu_uiinfo[0].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "control",
+                            view_menu_menu_uiinfo[0].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (view_menu_menu_uiinfo[1].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "playlist",
+                            view_menu_menu_uiinfo[1].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (view_menu_menu_uiinfo[2].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "channel",
+                            view_menu_menu_uiinfo[2].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (channel_menu_uiinfo[0].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "channel0",
+                            channel_menu_uiinfo[0].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (channel_menu_uiinfo[1].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "channel1",
+                            channel_menu_uiinfo[1].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (channel_menu_uiinfo[2].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "channel2",
+                            channel_menu_uiinfo[2].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (channel_menu_uiinfo[3].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "channel3",
+                            channel_menu_uiinfo[3].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (channel_menu_uiinfo[4].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "channel4",
+                            channel_menu_uiinfo[4].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (channel_menu_uiinfo[5].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "channel5",
+                            channel_menu_uiinfo[5].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (channel_menu_uiinfo[6].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "config_channels",
+                            channel_menu_uiinfo[6].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (menubar_uiinfo[2].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "settings_menu",
+                            menubar_uiinfo[2].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (settings_menu_menu_uiinfo[0].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "preferences",
+                            settings_menu_menu_uiinfo[0].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (settings_menu_menu_uiinfo[1].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "plugins",
+                            settings_menu_menu_uiinfo[1].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (menubar_uiinfo[3].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "help_menu",
+                            menubar_uiinfo[3].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (help_menu_menu_uiinfo[0].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "user_guide",
+                            help_menu_menu_uiinfo[0].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (help_menu_menu_uiinfo[1].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "about",
+                            help_menu_menu_uiinfo[1].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);
+  gtk_widget_ref (toolbar);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "toolbar", toolbar,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (toolbar);
+  gnome_app_add_toolbar (GNOME_APP (intf_window), GTK_TOOLBAR (toolbar), "toolbar",
+                                GNOME_DOCK_ITEM_BEH_EXCLUSIVE,
+                                GNOME_DOCK_TOP, 1, 0, 0);
+  gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NONE);
+
+  tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_OPEN);
+  open = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                _("Open"),
+                                NULL, NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_widget_ref (open);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "open", open,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (open);
+
+  tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_JUMP_TO);
+  jump = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                _("Jump"),
+                                NULL, NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_widget_ref (jump);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "jump", jump,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (jump);
+
+  vseparator1 = gtk_vseparator_new ();
+  gtk_widget_ref (vseparator1);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "vseparator1", vseparator1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vseparator1);
+  gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), vseparator1, NULL, NULL);
+  gtk_widget_set_usize (vseparator1, 16, 32);
+
+  tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_FIRST);
+  prev = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                _("Prev"),
+                                NULL, NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_widget_ref (prev);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "prev", prev,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (prev);
+
+  tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_BACK);
+  rewind = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                _("Back"),
+                                NULL, NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_widget_ref (rewind);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "rewind", rewind,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (rewind);
+
+  tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_STOP);
+  stop = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                _("Stop"),
+                                NULL, NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_widget_ref (stop);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "stop", stop,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (stop);
+
+  tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_FORWARD);
+  play = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                _("Play"),
+                                NULL, NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_widget_ref (play);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "play", play,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (play);
+
+  tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_LAST);
+  next = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                _("Next"),
+                                NULL, NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_widget_ref (next);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "next", next,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (next);
+
+  vseparator2 = gtk_vseparator_new ();
+  gtk_widget_ref (vseparator2);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "vseparator2", vseparator2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vseparator2);
+  gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), vseparator2, NULL, NULL);
+  gtk_widget_set_usize (vseparator2, 16, 32);
+
+  tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_TIMER_STOP);
+  pause = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                _("Pause"),
+                                NULL, NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_widget_ref (pause);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "pause", pause,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (pause);
+
+  tmp_toolbar_icon = gnome_stock_pixmap_widget (intf_window, GNOME_STOCK_PIXMAP_VOLUME);
+  mute = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
+                                GTK_TOOLBAR_CHILD_BUTTON,
+                                NULL,
+                                _("Mute"),
+                                NULL, NULL,
+                                tmp_toolbar_icon, NULL, NULL);
+  gtk_widget_ref (mute);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "mute", mute,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (mute);
+
+  table1 = gtk_table_new (4, 3, FALSE);
+  gtk_widget_ref (table1);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "table1", table1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (table1);
+  gnome_app_set_contents (GNOME_APP (intf_window), table1);
+
+  hscale1 = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 12, 0.1, 1, 1)));
+  gtk_widget_ref (hscale1);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "hscale1", hscale1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hscale1);
+  gtk_table_attach (GTK_TABLE (table1), hscale1, 1, 2, 1, 2,
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+
+  appbar = gnome_appbar_new (TRUE, TRUE, GNOME_PREFERENCES_NEVER);
+  gtk_widget_ref (appbar);
+  gtk_object_set_data_full (GTK_OBJECT (intf_window), "appbar", appbar,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (appbar);
+  gnome_app_set_statusbar (GNOME_APP (intf_window), appbar);
+
+  gtk_signal_connect (GTK_OBJECT (intf_window), "destroy",
+                      GTK_SIGNAL_FUNC (on_intf_window_destroy),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (open), "clicked",
+                      GTK_SIGNAL_FUNC (on_open_clicked),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (stop), "clicked",
+                      GTK_SIGNAL_FUNC (on_stop_clicked),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (play), "clicked",
+                      GTK_SIGNAL_FUNC (on_play_clicked),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (pause), "clicked",
+                      GTK_SIGNAL_FUNC (on_pause_clicked),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (mute), "clicked",
+                      GTK_SIGNAL_FUNC (on_mute_clicked),
+                      NULL);
+
+  return intf_window;
+}
+
+GtkWidget*
+create_intf_about (void)
+{
+  const gchar *authors[] = {
+    "too many to list here ...",
+    "see http://www.videolan.org/ for more details",
+    NULL
+  };
+  GtkWidget *intf_about;
+
+  intf_about = gnome_about_new ("Vlc", VERSION,
+                        _("(C) 1996-2000 the VideoLAN Team"),
+                        authors,
+                        _("This is the VideoLAN client.\nIt plays MPEG streams from a file or a network source."),
+                        NULL);
+  gtk_object_set_data (GTK_OBJECT (intf_about), "intf_about", intf_about);
+
+  return intf_about;
+}
+
+static GnomeUIInfo popup_channel_menu_uiinfo[] =
+{
+  {
+    GNOME_APP_UI_ITEM, N_("None"),
+    NULL,
+    on_popup_channel0_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("1"),
+    NULL,
+    on_popup_channel1_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("2"),
+    NULL,
+    on_popup_channel2_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("3"),
+    NULL,
+    on_popup_channel3_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("4"),
+    NULL,
+    on_popup_channel4_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("5"),
+    NULL,
+    on_popup_channel5_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("Configure..."),
+    NULL,
+    on_popup_config_channels_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  GNOMEUIINFO_END
+};
+
+static GnomeUIInfo intf_popup_uiinfo[] =
+{
+  {
+    GNOME_APP_UI_ITEM, N_("Play"),
+    NULL,
+    on_popup_play_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_FORWARD,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("Stop"),
+    NULL,
+    on_popup_stop_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_STOP,
+    0, 0, NULL
+  },
+  GNOMEUIINFO_SEPARATOR,
+  {
+    GNOME_APP_UI_ITEM, N_("Pause"),
+    NULL,
+    on_popup_pause_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_TIMER_STOP,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("Mute"),
+    NULL,
+    on_popup_mute_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_VOLUME,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_SUBTREE, N_("Channel"),
+    NULL,
+    popup_channel_menu_uiinfo, NULL, NULL,
+    GNOME_APP_PIXMAP_NONE, NULL,
+    0, 0, NULL
+  },
+  GNOMEUIINFO_SEPARATOR,
+  {
+    GNOME_APP_UI_ITEM, N_("Control window"),
+    NULL,
+    on_popup_control_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_EXEC,
+    0, 0, NULL
+  },
+  {
+    GNOME_APP_UI_ITEM, N_("Playlist"),
+    NULL,
+    on_popup_playlist_activate, NULL, NULL,
+    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_INDEX,
+    0, 0, NULL
+  },
+  GNOMEUIINFO_SEPARATOR,
+  GNOMEUIINFO_MENU_ABOUT_ITEM (on_popup_about_activate, NULL),
+  GNOMEUIINFO_MENU_EXIT_ITEM (on_popup_exit_activate, NULL),
+  GNOMEUIINFO_END
+};
+
+GtkWidget*
+create_intf_popup (void)
+{
+  GtkWidget *intf_popup;
+
+  intf_popup = gtk_menu_new ();
+  gtk_object_set_data (GTK_OBJECT (intf_popup), "intf_popup", intf_popup);
+  gnome_app_fill_menu (GTK_MENU_SHELL (intf_popup), intf_popup_uiinfo,
+                       NULL, FALSE, 0);
+
+  gtk_widget_ref (intf_popup_uiinfo[0].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_play",
+                            intf_popup_uiinfo[0].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[1].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_stop",
+                            intf_popup_uiinfo[1].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[2].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "separator2",
+                            intf_popup_uiinfo[2].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[3].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_pause",
+                            intf_popup_uiinfo[3].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[4].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_mute",
+                            intf_popup_uiinfo[4].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[5].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_channel",
+                            intf_popup_uiinfo[5].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (popup_channel_menu_uiinfo[0].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_channel0",
+                            popup_channel_menu_uiinfo[0].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (popup_channel_menu_uiinfo[1].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_channel1",
+                            popup_channel_menu_uiinfo[1].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (popup_channel_menu_uiinfo[2].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_channel2",
+                            popup_channel_menu_uiinfo[2].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (popup_channel_menu_uiinfo[3].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_channel3",
+                            popup_channel_menu_uiinfo[3].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (popup_channel_menu_uiinfo[4].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_channel4",
+                            popup_channel_menu_uiinfo[4].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (popup_channel_menu_uiinfo[5].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_channel5",
+                            popup_channel_menu_uiinfo[5].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (popup_channel_menu_uiinfo[6].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_config_channels",
+                            popup_channel_menu_uiinfo[6].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[6].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "separator3",
+                            intf_popup_uiinfo[6].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[7].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_control",
+                            intf_popup_uiinfo[7].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[8].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_playlist",
+                            intf_popup_uiinfo[8].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[9].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "separator2",
+                            intf_popup_uiinfo[9].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[10].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_about",
+                            intf_popup_uiinfo[10].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  gtk_widget_ref (intf_popup_uiinfo[11].widget);
+  gtk_object_set_data_full (GTK_OBJECT (intf_popup), "popup_exit",
+                            intf_popup_uiinfo[11].widget,
+                            (GtkDestroyNotify) gtk_widget_unref);
+
+  return intf_popup;
+}
+
+GtkWidget*
+create_intf_playlist (void)
+{
+  GtkWidget *intf_playlist;
+  GtkWidget *vbox1;
+  GtkWidget *scrolledwindow;
+  GtkWidget *clist;
+  GtkWidget *label_name;
+  GtkWidget *label_type;
+  GtkWidget *label_length;
+  GtkWidget *hbuttonbox;
+  GtkWidget *playlist_load;
+  GtkWidget *playlist_close;
+  GtkWidget *playlist_help;
+
+  intf_playlist = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_object_set_data (GTK_OBJECT (intf_playlist), "intf_playlist", intf_playlist);
+  gtk_window_set_title (GTK_WINDOW (intf_playlist), _("Playlist"));
+  gtk_window_set_default_size (GTK_WINDOW (intf_playlist), -1, 400);
+  gtk_window_set_policy (GTK_WINDOW (intf_playlist), TRUE, TRUE, FALSE);
+
+  vbox1 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox1);
+  gtk_object_set_data_full (GTK_OBJECT (intf_playlist), "vbox1", vbox1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox1);
+  gtk_container_add (GTK_CONTAINER (intf_playlist), vbox1);
+
+  scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_ref (scrolledwindow);
+  gtk_object_set_data_full (GTK_OBJECT (intf_playlist), "scrolledwindow", scrolledwindow,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (scrolledwindow);
+  gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow, TRUE, TRUE, 0);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+  clist = gtk_clist_new (3);
+  gtk_widget_ref (clist);
+  gtk_object_set_data_full (GTK_OBJECT (intf_playlist), "clist", clist,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (clist);
+  gtk_container_add (GTK_CONTAINER (scrolledwindow), clist);
+  gtk_clist_set_column_width (GTK_CLIST (clist), 0, 147);
+  gtk_clist_set_column_width (GTK_CLIST (clist), 1, 76);
+  gtk_clist_set_column_width (GTK_CLIST (clist), 2, 98);
+  gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_MULTIPLE);
+  gtk_clist_column_titles_show (GTK_CLIST (clist));
+
+  label_name = gtk_label_new (_("Name"));
+  gtk_widget_ref (label_name);
+  gtk_object_set_data_full (GTK_OBJECT (intf_playlist), "label_name", label_name,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label_name);
+  gtk_clist_set_column_widget (GTK_CLIST (clist), 0, label_name);
+
+  label_type = gtk_label_new (_("Type"));
+  gtk_widget_ref (label_type);
+  gtk_object_set_data_full (GTK_OBJECT (intf_playlist), "label_type", label_type,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label_type);
+  gtk_clist_set_column_widget (GTK_CLIST (clist), 1, label_type);
+
+  label_length = gtk_label_new (_("Length"));
+  gtk_widget_ref (label_length);
+  gtk_object_set_data_full (GTK_OBJECT (intf_playlist), "label_length", label_length,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label_length);
+  gtk_clist_set_column_widget (GTK_CLIST (clist), 2, label_length);
+
+  hbuttonbox = gtk_hbutton_box_new ();
+  gtk_widget_ref (hbuttonbox);
+  gtk_object_set_data_full (GTK_OBJECT (intf_playlist), "hbuttonbox", hbuttonbox,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbuttonbox);
+  gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox, FALSE, FALSE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox), 5);
+
+  playlist_load = gtk_button_new_with_label (_("Load"));
+  gtk_widget_ref (playlist_load);
+  gtk_object_set_data_full (GTK_OBJECT (intf_playlist), "playlist_load", playlist_load,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (playlist_load);
+  gtk_container_add (GTK_CONTAINER (hbuttonbox), playlist_load);
+  GTK_WIDGET_SET_FLAGS (playlist_load, GTK_CAN_DEFAULT);
+
+  playlist_close = gnome_stock_button (GNOME_STOCK_BUTTON_CLOSE);
+  gtk_widget_ref (playlist_close);
+  gtk_object_set_data_full (GTK_OBJECT (intf_playlist), "playlist_close", playlist_close,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (playlist_close);
+  gtk_container_add (GTK_CONTAINER (hbuttonbox), playlist_close);
+  GTK_WIDGET_SET_FLAGS (playlist_close, GTK_CAN_DEFAULT);
+
+  playlist_help = gnome_stock_button (GNOME_STOCK_BUTTON_HELP);
+  gtk_widget_ref (playlist_help);
+  gtk_object_set_data_full (GTK_OBJECT (intf_playlist), "playlist_help", playlist_help,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (playlist_help);
+  gtk_container_add (GTK_CONTAINER (hbuttonbox), playlist_help);
+  GTK_WIDGET_SET_FLAGS (playlist_help, GTK_CAN_DEFAULT);
+
+  gtk_signal_connect (GTK_OBJECT (intf_playlist), "destroy",
+                      GTK_SIGNAL_FUNC (on_intf_playlist_destroy),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (playlist_close), "clicked",
+                      GTK_SIGNAL_FUNC (on_playlist_close_clicked),
+                      NULL);
+
+  return intf_playlist;
+}
+
diff --git a/plugins/gnome/intf_gnome_interface.h b/plugins/gnome/intf_gnome_interface.h
new file mode 100644 (file)
index 0000000..cf7ba41
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+GtkWidget* create_intf_window (void);
+GtkWidget* create_intf_about (void);
+GtkWidget* create_intf_popup (void);
+GtkWidget* create_intf_playlist (void);
diff --git a/plugins/gnome/intf_gnome_support.c b/plugins/gnome/intf_gnome_support.c
new file mode 100644 (file)
index 0000000..d13ea74
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <gnome.h>
+
+#include "intf_gnome_support.h"
+
+/* This is an internally used function to create pixmaps. */
+static GtkWidget* create_dummy_pixmap  (GtkWidget       *widget,
+                                        gboolean         gnome_pixmap);
+
+GtkWidget*
+lookup_widget                          (GtkWidget       *widget,
+                                        const gchar     *widget_name)
+{
+  GtkWidget *parent, *found_widget;
+
+  for (;;)
+    {
+      if (GTK_IS_MENU (widget))
+        parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
+      else
+        parent = widget->parent;
+      if (parent == NULL)
+        break;
+      widget = parent;
+    }
+
+  found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget),
+                                                   widget_name);
+  if (!found_widget)
+    g_warning ("Widget not found: %s", widget_name);
+  return found_widget;
+}
+
+/* This is a dummy pixmap we use when a pixmap can't be found. */
+static char *dummy_pixmap_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"1 1 1 1",
+"  c None",
+/* pixels */
+" ",
+" "
+};
+
+/* This is an internally used function to create pixmaps. */
+static GtkWidget*
+create_dummy_pixmap                    (GtkWidget       *widget,
+                                        gboolean         gnome_pixmap)
+{
+  GdkColormap *colormap;
+  GdkPixmap *gdkpixmap;
+  GdkBitmap *mask;
+  GtkWidget *pixmap;
+
+  if (gnome_pixmap)
+    {
+      return gnome_pixmap_new_from_xpm_d (dummy_pixmap_xpm);
+    }
+
+  colormap = gtk_widget_get_colormap (widget);
+  gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask,
+                                                     NULL, dummy_pixmap_xpm);
+  if (gdkpixmap == NULL)
+    g_error ("Couldn't create replacement pixmap.");
+  pixmap = gtk_pixmap_new (gdkpixmap, mask);
+  gdk_pixmap_unref (gdkpixmap);
+  gdk_bitmap_unref (mask);
+  return pixmap;
+}
+
+/* This is an internally used function to create pixmaps. */
+GtkWidget*
+create_pixmap                          (GtkWidget       *widget,
+                                        const gchar     *filename,
+                                        gboolean         gnome_pixmap)
+{
+  GtkWidget *pixmap;
+  GdkColormap *colormap;
+  GdkPixmap *gdkpixmap;
+  GdkBitmap *mask;
+  gchar *pathname;
+
+  pathname = gnome_pixmap_file (filename);
+  if (!pathname)
+    {
+      g_warning (_("Couldn't find pixmap file: %s"), filename);
+      return create_dummy_pixmap (widget, gnome_pixmap);
+    }
+
+  if (gnome_pixmap)
+    {
+      pixmap = gnome_pixmap_new_from_file (pathname);
+      g_free (pathname);
+      return pixmap;
+    }
+
+  colormap = gtk_widget_get_colormap (widget);
+  gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask,
+                                                   NULL, pathname);
+  if (gdkpixmap == NULL)
+    {
+      g_warning (_("Couldn't create pixmap from file: %s"), pathname);
+      g_free (pathname);
+      return create_dummy_pixmap (widget, gnome_pixmap);
+    }
+  g_free (pathname);
+
+  pixmap = gtk_pixmap_new (gdkpixmap, mask);
+  gdk_pixmap_unref (gdkpixmap);
+  gdk_bitmap_unref (mask);
+  return pixmap;
+}
+
+/* This is an internally used function to create imlib images. */
+GdkImlibImage*
+create_image                           (const gchar     *filename)
+{
+  GdkImlibImage *image;
+  gchar *pathname;
+
+  pathname = gnome_pixmap_file (filename);
+  if (!pathname)
+    {
+      g_warning (_("Couldn't find pixmap file: %s"), filename);
+      return NULL;
+    }
+
+  image = gdk_imlib_load_image (pathname);
+  g_free (pathname);
+  return image;
+}
+
diff --git a/plugins/gnome/intf_gnome_support.h b/plugins/gnome/intf_gnome_support.h
new file mode 100644 (file)
index 0000000..d9bb072
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#include <gnome.h>
+
+/*
+ * Public Functions.
+ */
+
+/*
+ * This function returns a widget in a component created by Glade.
+ * Call it with the toplevel widget in the component (i.e. a window/dialog),
+ * or alternatively any widget in the component, and the name of the widget
+ * you want returned.
+ */
+GtkWidget*  lookup_widget              (GtkWidget       *widget,
+                                        const gchar     *widget_name);
+
+/* get_widget() is deprecated. Use lookup_widget instead. */
+#define get_widget lookup_widget
+
+
+/*
+ * Private Functions.
+ */
+
+/* This is used to create the pixmaps in the interface. */
+GtkWidget*  create_pixmap              (GtkWidget       *widget,
+                                        const gchar     *filename,
+                                        gboolean         gnome_pixmap);
+
+GdkImlibImage* create_image            (const gchar     *filename);
+
diff --git a/plugins/gnome/intf_gnome_thread.h b/plugins/gnome/intf_gnome_thread.h
new file mode 100644 (file)
index 0000000..293cd7e
--- /dev/null
@@ -0,0 +1,58 @@
+/*****************************************************************************
+ * intf_gnome_thread.h: Gnome thread
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Boston, MA 02111-1307, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * intf_sys_t: description and status of Gnome interface
+ *****************************************************************************/
+typedef struct gnome_thread_s
+{
+    vlc_thread_t        thread_id;                /* id for thread functions */
+    boolean_t           b_die;                                 /* `die' flag */
+    boolean_t           b_error;                             /* `error' flag */
+
+    /* special actions */
+    vlc_mutex_t         change_lock;                      /* the change lock */
+
+    boolean_t           b_activity_changed;       /* vout activity toggled ? */
+    boolean_t           b_activity;                         /* vout activity */
+
+    boolean_t           b_popup_changed;                   /* display menu ? */
+
+    boolean_t           b_window_changed;        /* window display toggled ? */
+    boolean_t           b_window;                        /* display window ? */
+
+    boolean_t           b_playlist_changed;    /* playlist display toggled ? */
+    boolean_t           b_playlist;                    /* display playlist ? */
+
+    /* windows and widgets */
+    GtkWidget *         p_window;                             /* main window */
+    GtkWidget *         p_popup;                               /* popup menu */
+    GtkWidget *         p_playlist;                              /* playlist */
+    GtkWidget *         p_about;                             /* about window */
+
+} gnome_thread_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+void        GnomeThread              ( gnome_thread_t *p_gnome );
+
diff --git a/plugins/gnome/vout_gnome.c b/plugins/gnome/vout_gnome.c
new file mode 100644 (file)
index 0000000..3dcbbd9
--- /dev/null
@@ -0,0 +1,692 @@
+/*****************************************************************************
+ * vout_gnome.c: Gnome video output display method
+ *****************************************************************************
+ * Copyright (C) 1998, 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+
+#ifdef SYS_BSD
+#include <sys/types.h>                                     /* typedef ushort */
+#endif
+
+#include <sys/shm.h>                                   /* shmget(), shmctl() */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * vout_sys_t: video output X11 method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the X11 specific properties of an output thread. X11 video
+ * output is performed through regular resizable windows. Windows can be
+ * dynamically resized to adapt to the size of the streams.
+ *****************************************************************************/
+typedef struct vout_sys_s
+{
+    /* User settings */
+    boolean_t           b_shm;               /* shared memory extension flag */
+
+    /* Internal settings and properties */
+    Display *           p_display;                        /* display pointer */
+    Visual *            p_visual;                          /* visual pointer */
+    int                 i_screen;                           /* screen number */
+    Window              root_window;                          /* root window */
+    Window              window;                   /* window instance handler */
+    GC                  gc;              /* graphic context instance handler */
+    Colormap            colormap;               /* colormap used (8bpp only) */
+
+    /* Display buffers and shared memory information */
+    XImage *            p_ximage[2];                       /* XImage pointer */
+    XShmSegmentInfo     shm_info[2];       /* shared memory zone information */
+} vout_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  X11OpenDisplay      ( vout_thread_t *p_vout, char *psz_display, Window root_window, void *p_data );
+static void X11CloseDisplay     ( vout_thread_t *p_vout );
+static int  X11CreateWindow     ( vout_thread_t *p_vout );
+static void X11DestroyWindow    ( vout_thread_t *p_vout );
+static int  X11CreateImage      ( vout_thread_t *p_vout, XImage **pp_ximage );
+static void X11DestroyImage     ( XImage *p_ximage );
+static int  X11CreateShmImage   ( vout_thread_t *p_vout, XImage **pp_ximage,
+                                  XShmSegmentInfo *p_shm_info );
+static void X11DestroyShmImage  ( vout_thread_t *p_vout, XImage *p_ximage,
+                                  XShmSegmentInfo *p_shm_info );
+static void X11SetPalette       ( p_vout_thread_t p_vout,
+                                  u16 *red, u16 *green, u16 *blue, u16 *transp );
+
+/*****************************************************************************
+ * vout_SysCreate: allocate X11 video thread output method
+ *****************************************************************************
+ * This function allocate and initialize a X11 vout method. It uses some of the
+ * vout properties to choose the window size, and change them according to the
+ * actual properties of the display.
+ *****************************************************************************/
+int vout_SysCreate( vout_thread_t *p_vout, char *psz_display,
+                    int i_root_window, void *p_data )
+{
+    /* Allocate structure */
+    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+    if( p_vout->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Open and initialize device. This function issues its own error messages.
+     * Since XLib is usually not thread-safe, we can't use the same display
+     * pointer than the interface or another thread. However, the root window
+     * id is still valid. */
+    if( X11OpenDisplay( p_vout, psz_display, i_root_window, p_data ) )
+    {
+        intf_ErrMsg("error: can't initialize X11 display\n" );
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysInit: initialize X11 video thread output method
+ *****************************************************************************
+ * This function create the XImages needed by the output thread. It is called
+ * at the beginning of the thread, but also each time the window is resized.
+ *****************************************************************************/
+int vout_SysInit( vout_thread_t *p_vout )
+{
+    int i_err;
+
+    /* Initialize palette changing procedure */
+    p_vout->p_set_palette       = X11SetPalette;
+
+    /* Create XImages using XShm extension - on failure, fall back to regular
+     * way (and destroy the first image if it was created successfully) */
+    if( p_vout->p_sys->b_shm )
+    {
+        /* Create first image */
+        i_err = X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[0],
+                                   &p_vout->p_sys->shm_info[0] );
+        if( !i_err )                         /* first image has been created */
+        {
+            /* Create second image */
+            if( X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[1],
+                                   &p_vout->p_sys->shm_info[1] ) )
+            {                             /* error creating the second image */
+                X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0],
+                                    &p_vout->p_sys->shm_info[0] );
+                i_err = 1;
+            }
+        }
+        if( i_err )                                      /* an error occured */
+        {
+            intf_Msg("XShm video sextension desactivated\n" );
+            p_vout->p_sys->b_shm = 0;
+        }
+    }
+
+    /* Create XImages without XShm extension */
+    if( !p_vout->p_sys->b_shm )
+    {
+        if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[0] ) )
+        {
+            intf_ErrMsg("error: can't create images\n");
+            p_vout->p_sys->p_ximage[0] = NULL;
+            p_vout->p_sys->p_ximage[1] = NULL;
+            return( 1 );
+        }
+        if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[1] ) )
+        {
+            intf_ErrMsg("error: can't create images\n");
+            X11DestroyImage( p_vout->p_sys->p_ximage[0] );
+            p_vout->p_sys->p_ximage[0] = NULL;
+            p_vout->p_sys->p_ximage[1] = NULL;
+            return( 1 );
+        }
+    }
+
+    /* Set bytes per line and initialize buffers */
+    p_vout->i_bytes_per_line = p_vout->p_sys->p_ximage[0]->bytes_per_line;
+    vout_SetBuffers( p_vout, p_vout->p_sys->p_ximage[ 0 ]->data,
+                     p_vout->p_sys->p_ximage[ 1 ]->data );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysEnd: terminate X11 video thread output method
+ *****************************************************************************
+ * Destroy the X11 XImages created by vout_SysInit. It is called at the end of
+ * the thread, but also each time the window is resized.
+ *****************************************************************************/
+void vout_SysEnd( vout_thread_t *p_vout )
+{
+    if( p_vout->p_sys->b_shm )                             /* Shm XImages... */
+    {
+        X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0],
+                            &p_vout->p_sys->shm_info[0] );
+        X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[1],
+                            &p_vout->p_sys->shm_info[1] );
+    }
+    else                                          /* ...or regular XImages */
+    {
+        X11DestroyImage( p_vout->p_sys->p_ximage[0] );
+        X11DestroyImage( p_vout->p_sys->p_ximage[1] );
+    }
+}
+
+/*****************************************************************************
+ * vout_SysDestroy: destroy X11 video thread output method
+ *****************************************************************************
+ * Terminate an output method created by vout_CreateOutputMethod
+ *****************************************************************************/
+void vout_SysDestroy( vout_thread_t *p_vout )
+{
+    X11CloseDisplay( p_vout );
+    free( p_vout->p_sys );
+}
+
+/*****************************************************************************
+ * vout_SysManage: handle X11 events
+ *****************************************************************************
+ * This function should be called regularly by video output thread. It manages
+ * X11 events and allows window resizing. It returns a non null value on
+ * error.
+ *****************************************************************************/
+int vout_SysManage( vout_thread_t *p_vout )
+{
+    /*
+     * Color/Grayscale or gamma change: in 8bpp, just change the colormap
+     */
+    if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE) && (p_vout->i_screen_depth == 8) )
+    {
+        /* FIXME: clear flags ?? */
+    }
+
+    /*
+     * Size change
+     */
+    if( p_vout->i_changes & VOUT_SIZE_CHANGE )
+    {
+        intf_DbgMsg("resizing window\n");
+        p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
+
+        /* Resize window */
+        XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                       p_vout->i_width, p_vout->i_height );
+
+        /* Destroy XImages to change their size */
+        vout_SysEnd( p_vout );
+
+        /* Recreate XImages. If SysInit failed, the thread can't go on. */
+        if( vout_SysInit( p_vout ) )
+        {
+            intf_ErrMsg("error: can't resize display\n");
+            return( 1 );
+        }
+
+        /* Tell the video output thread that it will need to rebuild YUV
+         * tables. This is needed since convertion buffer size may have changed */
+        p_vout->i_changes |= VOUT_YUV_CHANGE;
+        intf_Msg("Video display resized (%dx%d)\n", p_vout->i_width, p_vout->i_height);
+    }
+
+    return 0;
+}
+
+/*****************************************************************************
+ * vout_SysDisplay: displays previously rendered output
+ *****************************************************************************
+ * This function send the currently rendered image to X11 server, wait until
+ * it is displayed and switch the two rendering buffer, preparing next frame.
+ *****************************************************************************/
+void vout_SysDisplay( vout_thread_t *p_vout )
+{
+    if( p_vout->p_sys->b_shm)                                /* XShm is used */
+    {
+        /* Display rendered image using shared memory extension */
+        XShmPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
+                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ],
+                     0, 0, 0, 0,
+                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width,
+                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height, True);
+
+        /* Send the order to the X server */
+        XFlush(p_vout->p_sys->p_display);
+    }
+    else                                /* regular X11 capabilities are used */
+    {
+        XPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
+                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ],
+                  0, 0, 0, 0,
+                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width,
+                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height);
+
+        /* Send the order to the X server */
+        XFlush(p_vout->p_sys->p_display);
+    }
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * X11OpenDisplay: open and initialize X11 device
+ *****************************************************************************
+ * Create a window according to video output given size, and set other
+ * properties according to the display properties.
+ *****************************************************************************/
+static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root_window, void *p_data )
+{
+    XPixmapFormatValues *       p_xpixmap_format;          /* pixmap formats */
+    XVisualInfo *               p_xvisual;           /* visuals informations */
+    XVisualInfo                 xvisual_template;         /* visual template */
+    int                         i_count;                       /* array size */
+
+    /* Open display */
+    p_vout->p_sys->p_display = XOpenDisplay( psz_display );
+    if( p_vout->p_sys->p_display == NULL )
+    {
+        intf_ErrMsg("error: can't open display %s\n", psz_display );
+        return( 1 );
+    }
+
+    /* Initialize structure */
+    p_vout->p_sys->root_window  = root_window;
+    p_vout->p_sys->b_shm        = (XShmQueryExtension(p_vout->p_sys->p_display) == True);
+    p_vout->p_sys->i_screen     = DefaultScreen( p_vout->p_sys->p_display );
+    if( !p_vout->p_sys->b_shm )
+    {
+        intf_Msg("XShm video extension is not available\n");
+    }
+
+    /* Get screen depth */
+    p_vout->i_screen_depth = XDefaultDepth( p_vout->p_sys->p_display, p_vout->p_sys->i_screen );
+    switch( p_vout->i_screen_depth )
+    {
+    case 8:
+        /*
+         * Screen depth is 8bpp. Use PseudoColor visual with private colormap.
+         */
+        xvisual_template.screen =   p_vout->p_sys->i_screen;
+        xvisual_template.class =    DirectColor;
+        p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask,
+                                    &xvisual_template, &i_count );
+        if( p_xvisual == NULL )
+        {
+            intf_ErrMsg("error: no PseudoColor visual available\n");
+            XCloseDisplay( p_vout->p_sys->p_display );
+            return( 1 );
+        }
+        p_vout->i_bytes_per_pixel = 1;
+
+        /* put the colormap in place */
+        p_vout->p_sys->colormap = *(Colormap *)p_data;
+        break;
+    case 15:
+    case 16:
+    case 24:
+    default:
+        /*
+         * Screen depth is higher than 8bpp. TrueColor visual is used.
+         */
+        xvisual_template.screen =   p_vout->p_sys->i_screen;
+        xvisual_template.class =    TrueColor;
+        p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask,
+                                    &xvisual_template, &i_count );
+        if( p_xvisual == NULL )
+        {
+            intf_ErrMsg("error: no TrueColor visual available\n");
+            XCloseDisplay( p_vout->p_sys->p_display );
+            return( 1 );
+        }
+        p_vout->i_red_mask =        p_xvisual->red_mask;
+        p_vout->i_green_mask =      p_xvisual->green_mask;
+        p_vout->i_blue_mask =       p_xvisual->blue_mask;
+
+        /* There is no difference yet between 3 and 4 Bpp. The only way to find
+         * the actual number of bytes per pixel is to list supported pixmap
+         * formats. */
+        p_xpixmap_format = XListPixmapFormats( p_vout->p_sys->p_display, &i_count );
+        p_vout->i_bytes_per_pixel = 0;
+        for( ; i_count--; p_xpixmap_format++ )
+        {
+            if( p_xpixmap_format->bits_per_pixel / 8 > p_vout->i_bytes_per_pixel )
+            {
+                p_vout->i_bytes_per_pixel = p_xpixmap_format->bits_per_pixel / 8;
+            }
+        }
+        break;
+    }
+    p_vout->p_sys->p_visual = p_xvisual->visual;
+    XFree( p_xvisual );
+
+    /* Create a window */
+    if( X11CreateWindow( p_vout ) )
+    {
+        intf_ErrMsg("error: can't open a window\n");
+        XCloseDisplay( p_vout->p_sys->p_display );
+        return( 1 );
+    }
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11CloseDisplay: close X11 device
+ *****************************************************************************
+ * Returns all resources allocated by X11OpenDisplay and restore the original
+ * state of the display.
+ *****************************************************************************/
+static void X11CloseDisplay( vout_thread_t *p_vout )
+{
+    /* Destroy colormap */
+    if( p_vout->i_screen_depth == 8 )
+    {
+        XFreeColormap( p_vout->p_sys->p_display, p_vout->p_sys->colormap );
+    }
+    
+    /* Destroy window */
+    X11DestroyWindow( p_vout );
+
+    /* FIXME: We should close the display here, but X returns an error. */
+    //XCloseDisplay( p_vout->p_sys->p_display );
+}
+
+/*****************************************************************************
+ * X11CreateWindow: create X11 vout window
+ *****************************************************************************
+ * The video output window will be created. Normally, this window is wether
+ * full screen or part of a parent window. Therefore, it does not need a
+ * title or other hints. Thery are still supplied in case the window would be
+ * spawned as a standalone one by the interface.
+ *****************************************************************************/
+static int X11CreateWindow( vout_thread_t *p_vout )
+{
+    XSetWindowAttributes    xwindow_attributes;         /* window attributes */
+    XGCValues               xgcvalues;      /* graphic context configuration */
+    XEvent                  xevent;                          /* first events */
+    boolean_t               b_expose;             /* 'expose' event received */
+    boolean_t               b_map_notify;     /* 'map_notify' event received */
+
+    /* Prepare window attributes */
+    xwindow_attributes.backing_store = Always;       /* save the hidden part */
+
+    /* Create the window and set hints */
+    p_vout->p_sys->window = XCreateSimpleWindow( p_vout->p_sys->p_display,
+                                         p_vout->p_sys->root_window,
+                                         0, 0,
+                                         p_vout->i_width, p_vout->i_height,
+                                         0, 0, 0);
+    XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                  ExposureMask | StructureNotifyMask );
+    XChangeWindowAttributes( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                             CWBackingStore, &xwindow_attributes);
+
+    /* Creation of a graphic context that doesn't generate a GraphicsExpose event
+       when using functions like XCopyArea */
+    xgcvalues.graphics_exposures = False;
+    p_vout->p_sys->gc =  XCreateGC( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                                    GCGraphicsExposures, &xgcvalues);
+
+    /* Send orders to server, and wait until window is displayed - two events
+     * must be received: a MapNotify event, an Expose event allowing drawing in the
+     * window */
+    b_expose = 0;
+    b_map_notify = 0;
+    XMapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window);
+    do
+    {
+        XNextEvent( p_vout->p_sys->p_display, &xevent);
+        if( (xevent.type == Expose)
+            && (xevent.xexpose.window == p_vout->p_sys->window) )
+        {
+            b_expose = 1;
+        }
+        else if( (xevent.type == MapNotify)
+                 && (xevent.xmap.window == p_vout->p_sys->window) )
+        {
+            b_map_notify = 1;
+        }
+    }
+    while( !( b_expose && b_map_notify ) );
+    XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window, 0 );
+
+    /* At this stage, the window is open, displayed, and ready to receive
+     * data */
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11DestroyWindow: destroy X11 window
+ *****************************************************************************
+ * Destroy an X11 window created by vout_CreateWindow
+ *****************************************************************************/
+static void X11DestroyWindow( vout_thread_t *p_vout )
+{
+    XUnmapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
+    XFreeGC( p_vout->p_sys->p_display, p_vout->p_sys->gc );
+    XDestroyWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
+}
+
+/*****************************************************************************
+ * X11CreateImage: create an XImage
+ *****************************************************************************
+ * Create a simple XImage used as a buffer.
+ *****************************************************************************/
+static int X11CreateImage( vout_thread_t *p_vout, XImage **pp_ximage )
+{
+    byte_t *    pb_data;                          /* image data storage zone */
+    int         i_quantum;                     /* XImage quantum (see below) */
+
+    /* Allocate memory for image */
+    p_vout->i_bytes_per_line = p_vout->i_width * p_vout->i_bytes_per_pixel;
+    pb_data = (byte_t *) malloc( p_vout->i_bytes_per_line * p_vout->i_height );
+    if( !pb_data )                                                  /* error */
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        return( 1 );
+    }
+
+    /* Optimize the quantum of a scanline regarding its size - the quantum is
+       a diviser of the number of bits between the start of two scanlines. */
+    if( !(( p_vout->i_bytes_per_line ) % 32) )
+    {
+        i_quantum = 32;
+    }
+    else
+    {
+        if( !(( p_vout->i_bytes_per_line ) % 16) )
+        {
+            i_quantum = 16;
+        }
+        else
+        {
+            i_quantum = 8;
+        }
+    }
+
+    /* Create XImage */
+    *pp_ximage = XCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual,
+                               p_vout->i_screen_depth, ZPixmap, 0, pb_data,
+                               p_vout->i_width, p_vout->i_height, i_quantum, 0);
+    if(! *pp_ximage )                                               /* error */
+    {
+        intf_ErrMsg( "error: XCreateImage() failed\n" );
+        free( pb_data );
+        return( 1 );
+    }
+
+    return 0;
+}
+
+/*****************************************************************************
+ * X11CreateShmImage: create an XImage using shared memory extension
+ *****************************************************************************
+ * Prepare an XImage for DisplayX11ShmImage function.
+ * The order of the operations respects the recommandations of the mit-shm
+ * document by J.Corbet and K.Packard. Most of the parameters were copied from
+ * there.
+ *****************************************************************************/
+static int X11CreateShmImage( vout_thread_t *p_vout, XImage **pp_ximage,
+                              XShmSegmentInfo *p_shm_info)
+{
+    /* Create XImage */
+    *pp_ximage = XShmCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual,
+                                  p_vout->i_screen_depth, ZPixmap, 0,
+                                  p_shm_info, p_vout->i_width, p_vout->i_height );
+    if(! *pp_ximage )                                               /* error */
+    {
+        intf_ErrMsg("error: XShmCreateImage() failed\n");
+        return( 1 );
+    }
+
+    /* Allocate shared memory segment - 0777 set the access permission
+     * rights (like umask), they are not yet supported by X servers */
+    p_shm_info->shmid = shmget( IPC_PRIVATE,
+                                (*pp_ximage)->bytes_per_line * (*pp_ximage)->height,
+                                IPC_CREAT | 0777);
+    if( p_shm_info->shmid < 0)                                      /* error */
+    {
+        intf_ErrMsg("error: can't allocate shared image data (%s)\n",
+                    strerror(errno));
+        XDestroyImage( *pp_ximage );
+        return( 1 );
+    }
+
+    /* Attach shared memory segment to process (read/write) */
+    p_shm_info->shmaddr = (*pp_ximage)->data = shmat(p_shm_info->shmid, 0, 0);
+    if(! p_shm_info->shmaddr )
+    {                                                               /* error */
+        intf_ErrMsg("error: can't attach shared memory (%s)\n",
+                    strerror(errno));
+        shmctl( p_shm_info->shmid, IPC_RMID, 0 );      /* free shared memory */
+        XDestroyImage( *pp_ximage );
+        return( 1 );
+    }
+
+    /* Mark the shm segment to be removed when there will be no more
+     * attachements, so it is automatic on process exit or after shmdt */
+    shmctl( p_shm_info->shmid, IPC_RMID, 0 );
+
+    /* Attach shared memory segment to X server (read only) */
+    p_shm_info->readOnly = True;
+    if( XShmAttach( p_vout->p_sys->p_display, p_shm_info ) == False )    /* error */
+    {
+        intf_ErrMsg("error: can't attach shared memory to X11 server\n");
+        shmdt( p_shm_info->shmaddr );     /* detach shared memory from process
+                                           * and automatic free                */
+        XDestroyImage( *pp_ximage );
+        return( 1 );
+    }
+
+    /* Send image to X server. This instruction is required, since having
+     * built a Shm XImage and not using it causes an error on XCloseDisplay */
+    XFlush( p_vout->p_sys->p_display );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11DestroyImage: destroy an XImage
+ *****************************************************************************
+ * Destroy XImage AND associated data. If pointer is NULL, the image won't be
+ * destroyed (see vout_ManageOutputMethod())
+ *****************************************************************************/
+static void X11DestroyImage( XImage *p_ximage )
+{
+    if( p_ximage != NULL )
+    {
+        XDestroyImage( p_ximage );                     /* no free() required */
+    }
+}
+
+/*****************************************************************************
+ * X11DestroyShmImage
+ *****************************************************************************
+ * Destroy XImage AND associated data. Detach shared memory segment from
+ * server and process, then free it. If pointer is NULL, the image won't be
+ * destroyed (see vout_ManageOutputMethod())
+ *****************************************************************************/
+static void X11DestroyShmImage( vout_thread_t *p_vout, XImage *p_ximage,
+                                XShmSegmentInfo *p_shm_info )
+{
+    /* If pointer is NULL, do nothing */
+    if( p_ximage == NULL )
+    {
+        return;
+    }
+
+    XShmDetach( p_vout->p_sys->p_display, p_shm_info );     /* detach from server */
+    XDestroyImage( p_ximage );
+    if( shmdt( p_shm_info->shmaddr ) )  /* detach shared memory from process */
+    {                                   /* also automatic freeing...         */
+        intf_ErrMsg( "error: can't detach shared memory (%s)\n",
+                     strerror(errno) );
+    }
+}
+
+/*****************************************************************************
+ * X11SetPalette: sets an 8 bpp palette
+ *****************************************************************************
+ * This function sets the palette given as an argument. It does not return
+ * anything, but could later send information on which colors it was unable
+ * to set.
+ *****************************************************************************/
+static void X11SetPalette       ( p_vout_thread_t p_vout,
+                                  u16 *red, u16 *green, u16 *blue, u16 *transp )
+{
+    int i;
+    XColor color[255];
+
+    intf_DbgMsg( "Palette change called\n" );
+
+    /* allocate palette */
+    for( i = 0; i < 255; i++ )
+    {
+        /* kludge: colors are indexed reversely because color 255 seems
+         * to be reserved for black even if we try to set it to white */
+        color[i].pixel = 255-i;
+        color[i].pad = 0;
+        color[i].flags = DoRed|DoGreen|DoBlue;
+        color[i].red = red[255-i];
+        color[i].blue = blue[255-i];
+        color[i].green = green[255-i];
+    }
+
+    XStoreColors( p_vout->p_sys->p_display, p_vout->p_sys->colormap, color, 256 );
+}
+
diff --git a/plugins/mga/intf_mga.c b/plugins/mga/intf_mga.c
new file mode 100644 (file)
index 0000000..895f98b
--- /dev/null
@@ -0,0 +1,523 @@
+/*****************************************************************************
+ * intf_mga.c: MGA interface
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+#include <sys/types.h>                        /* on BSD, uio.h needs types.h */
+#include <sys/uio.h>                                          /* for input.h */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "input.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+#include "interface.h"
+
+#include "main.h"
+
+/*****************************************************************************
+ * intf_sys_t: description and status of X11 interface
+ *****************************************************************************/
+typedef struct intf_sys_s
+{
+    /* X11 generic properties */
+    Display *           p_display;                    /* X11 display pointer */
+    int                 i_screen;                              /* X11 screen */
+    Atom                wm_protocols;
+    Atom                wm_delete_window;
+
+    /* Main window properties */
+    Window              window;                               /* main window */
+    GC                  gc;               /* graphic context for main window */
+    int                 i_width;                     /* width of main window */
+    int                 i_height;                   /* height of main window */
+
+    /* Screen saver properties */
+    int                 i_ss_count;              /* enabling/disabling count */
+    int                 i_ss_timeout;                             /* timeout */
+    int                 i_ss_interval;           /* interval between changes */
+    int                 i_ss_blanking;                      /* blanking mode */
+    int                 i_ss_exposure;                      /* exposure mode */
+
+    /* Mouse pointer properties */
+    boolean_t           b_mouse;         /* is the mouse pointer displayed ? */
+
+} intf_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  X11CreateWindow             ( intf_thread_t *p_intf );
+static void X11DestroyWindow            ( intf_thread_t *p_intf );
+static void X11ManageWindow             ( intf_thread_t *p_intf );
+static void X11EnableScreenSaver        ( intf_thread_t *p_intf );
+static void X11DisableScreenSaver       ( intf_thread_t *p_intf );
+static void X11TogglePointer            ( intf_thread_t *p_intf );
+
+/*****************************************************************************
+ * intf_SysCreate: initialize and create window
+ *****************************************************************************/
+int intf_SysCreate( intf_thread_t *p_intf )
+{
+    char       *psz_display;
+
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        return( 1 );
+    }
+
+    /* Open display, unsing 'vlc_display' or DISPLAY environment variable */
+    psz_display = XDisplayName( main_GetPszVariable( VOUT_DISPLAY_VAR, NULL ) );
+    p_intf->p_sys->p_display = XOpenDisplay( psz_display );
+    if( !p_intf->p_sys->p_display )                                 /* error */
+    {
+        intf_ErrMsg("error: can't open display %s\n", psz_display );
+        free( p_intf->p_sys );
+        return( 1 );
+    }
+    p_intf->p_sys->i_screen = DefaultScreen( p_intf->p_sys->p_display );
+
+    /* Spawn base window - this window will include the video output window,
+     * but also command buttons, subtitles and other indicators */
+    if( X11CreateWindow( p_intf ) )
+    {
+        intf_ErrMsg("error: can't create interface window\n" );
+        XCloseDisplay( p_intf->p_sys->p_display );
+        free( p_intf->p_sys );
+        return( 1 );
+    }
+
+    /* Spawn video output thread */
+    if( p_main->b_video )
+    {
+        p_intf->p_vout = vout_CreateThread( psz_display, p_intf->p_sys->window,
+                                            p_intf->p_sys->i_width,
+                                            p_intf->p_sys->i_height, NULL, 0, NULL );
+        if( p_intf->p_vout == NULL )                                /* error */
+        {
+            intf_ErrMsg("error: can't create video output thread\n" );
+            X11DestroyWindow( p_intf );
+            XCloseDisplay( p_intf->p_sys->p_display );
+            free( p_intf->p_sys );
+            return( 1 );
+        }
+    }
+
+    p_intf->p_sys->b_mouse = 1;
+
+    /* Disable screen saver and return */
+    p_intf->p_sys->i_ss_count = 1;
+    X11DisableScreenSaver( p_intf );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * intf_SysDestroy: destroy interface window
+ *****************************************************************************/
+void intf_SysDestroy( intf_thread_t *p_intf )
+{
+    /* Enable screen saver */
+    X11EnableScreenSaver( p_intf );
+
+    /* Close input thread, if any (blocking) */
+    if( p_intf->p_input )
+    {
+        input_DestroyThread( p_intf->p_input, NULL );
+    }
+
+    /* Close video output thread, if any (blocking) */
+    if( p_intf->p_vout )
+    {
+        vout_DestroyThread( p_intf->p_vout, NULL );
+    }
+
+    /* Close main window and display */
+    X11DestroyWindow( p_intf );
+    XCloseDisplay( p_intf->p_sys->p_display );
+
+    /* Destroy structure */
+    free( p_intf->p_sys );
+}
+
+
+/*****************************************************************************
+ * intf_SysManage: event loop
+ *****************************************************************************/
+void intf_SysManage( intf_thread_t *p_intf )
+{
+    /* Manage main window */
+    X11ManageWindow( p_intf );
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * X11CreateWindow: open and set-up X11 main window
+ *****************************************************************************/
+static int X11CreateWindow( intf_thread_t *p_intf )
+{
+    XSizeHints              xsize_hints;
+    XSetWindowAttributes    xwindow_attributes;
+    XGCValues               xgcvalues;
+    XEvent                  xevent;
+    boolean_t               b_expose;
+    boolean_t               b_configure_notify;
+    boolean_t               b_map_notify;
+
+    /* Set main window's size */
+    p_intf->p_sys->i_width =  main_GetIntVariable( VOUT_WIDTH_VAR, VOUT_WIDTH_DEFAULT );
+    p_intf->p_sys->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR, VOUT_HEIGHT_DEFAULT );
+
+    /* Prepare window manager hints and properties */
+    xsize_hints.base_width =            p_intf->p_sys->i_width;
+    xsize_hints.base_height =           p_intf->p_sys->i_height;
+    xsize_hints.flags =                 PSize;
+    p_intf->p_sys->wm_protocols =       XInternAtom( p_intf->p_sys->p_display,
+                                                     "WM_PROTOCOLS", True );
+    p_intf->p_sys->wm_delete_window =   XInternAtom( p_intf->p_sys->p_display,
+                                                     "WM_DELETE_WINDOW", True );
+
+    /* Prepare window attributes */
+    xwindow_attributes.backing_store = Always;       /* save the hidden part */
+    xwindow_attributes.background_pixel = WhitePixel( p_intf->p_sys->p_display,
+                                                      p_intf->p_sys->i_screen );
+
+    /* Create the window and set hints - the window must receive ConfigureNotify
+     * events, and, until it is displayed, Expose and MapNotify events. */
+    p_intf->p_sys->window = XCreateSimpleWindow( p_intf->p_sys->p_display,
+                                         DefaultRootWindow( p_intf->p_sys->p_display ),
+                                         0, 0,
+                                         p_intf->p_sys->i_width, p_intf->p_sys->i_height,
+                                         0, 0, 0);
+    XSelectInput( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                  ExposureMask | StructureNotifyMask );
+    XChangeWindowAttributes( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                             CWBackingStore | CWBackPixel, &xwindow_attributes);
+
+    /* Set window manager hints and properties: size hints, command, window's name,
+     * and accepted protocols */
+    XSetWMNormalHints( p_intf->p_sys->p_display, p_intf->p_sys->window, &xsize_hints );
+    XSetCommand( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                 p_main->ppsz_argv, p_main->i_argc );
+    XStoreName( p_intf->p_sys->p_display, p_intf->p_sys->window, VOUT_TITLE );
+    if( (p_intf->p_sys->wm_protocols == None)        /* use WM_DELETE_WINDOW */
+        || (p_intf->p_sys->wm_delete_window == None)
+        || !XSetWMProtocols( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                             &p_intf->p_sys->wm_delete_window, 1 ) )
+    {
+        /* WM_DELETE_WINDOW is not supported by window manager */
+        intf_Msg("error: missing or bad window manager - please exit program kindly.\n");
+    }
+
+    /* Creation of a graphic context that doesn't generate a GraphicsExpose event
+       when using functions like XCopyArea */
+    xgcvalues.graphics_exposures = False;
+    p_intf->p_sys->gc =  XCreateGC( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                                    GCGraphicsExposures, &xgcvalues);
+
+    /* Send orders to server, and wait until window is displayed - three events
+     * must be received: a MapNotify event, an Expose event allowing drawing in the
+     * window, and a ConfigureNotify to get the window dimensions. Once those events
+     * have been received, only ConfigureNotify events need to be received. */
+    b_expose = 0;
+    b_configure_notify = 0;
+    b_map_notify = 0;
+    XMapWindow( p_intf->p_sys->p_display, p_intf->p_sys->window);
+    do
+    {
+        XNextEvent( p_intf->p_sys->p_display, &xevent);
+        if( (xevent.type == Expose)
+            && (xevent.xexpose.window == p_intf->p_sys->window) )
+        {
+            b_expose = 1;
+        }
+        else if( (xevent.type == MapNotify)
+                 && (xevent.xmap.window == p_intf->p_sys->window) )
+        {
+            b_map_notify = 1;
+        }
+        else if( (xevent.type == ConfigureNotify)
+                 && (xevent.xconfigure.window == p_intf->p_sys->window) )
+        {
+            b_configure_notify = 1;
+            p_intf->p_sys->i_width = xevent.xconfigure.width;
+            p_intf->p_sys->i_height = xevent.xconfigure.height;
+        }
+    }
+    while( !( b_expose && b_configure_notify && b_map_notify ) );
+    XSelectInput( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                  StructureNotifyMask | KeyPressMask | ButtonPressMask );
+
+    /* At this stage, the window is openned, displayed, and ready to receive data */
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11DestroyWindow: destroy X11 main window
+ *****************************************************************************/
+static void X11DestroyWindow( intf_thread_t *p_intf )
+{
+    XUnmapWindow( p_intf->p_sys->p_display, p_intf->p_sys->window );
+    XFreeGC( p_intf->p_sys->p_display, p_intf->p_sys->gc );
+    XDestroyWindow( p_intf->p_sys->p_display, p_intf->p_sys->window );
+}
+
+/*****************************************************************************
+ * X11ManageWindow: manage X11 main window
+ *****************************************************************************/
+static void X11ManageWindow( intf_thread_t *p_intf )
+{
+    XEvent      xevent;                                         /* X11 event */
+    boolean_t   b_resized;                        /* window has been resized */
+    char        i_key;                                    /* ISO Latin-1 key */
+
+    /* Handle X11 events: ConfigureNotify events are parsed to know if the
+     * output window's size changed, MapNotify and UnmapNotify to know if the
+     * window is mapped (and if the display is useful), and ClientMessages
+     * to intercept window destruction requests */
+    b_resized = 0;
+    while( XCheckWindowEvent( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                              StructureNotifyMask | KeyPressMask |
+                              ButtonPressMask, &xevent ) == True )
+    {
+        /* ConfigureNotify event: prepare  */
+        if( (xevent.type == ConfigureNotify)
+            && ((xevent.xconfigure.width != p_intf->p_sys->i_width)
+                || (xevent.xconfigure.height != p_intf->p_sys->i_height)) )
+        {
+            /* Update dimensions */
+            b_resized = 1;
+            p_intf->p_sys->i_width = xevent.xconfigure.width;
+            p_intf->p_sys->i_height = xevent.xconfigure.height;
+        }
+        /* MapNotify event: change window status and disable screen saver */
+        else if( xevent.type == MapNotify)
+        {
+            if( (p_intf->p_vout != NULL) && !p_intf->p_vout->b_active )
+            {
+                X11DisableScreenSaver( p_intf );
+                p_intf->p_vout->b_active = 1;
+            }
+        }
+        /* UnmapNotify event: change window status and enable screen saver */
+        else if( xevent.type == UnmapNotify )
+        {
+            if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_active )
+            {
+                X11EnableScreenSaver( p_intf );
+                p_intf->p_vout->b_active = 0;
+            }
+        }
+        /* DestroyNotify event: window has been destroyed */
+        else if( xevent.type == DestroyNotify )
+        {
+            intf_ErrMsg( "vout: window destroyed !\n");
+        }
+        /* Keyboard event */
+        else if( xevent.type == KeyPress )
+        {
+            if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
+            {
+                if( intf_ProcessKey( p_intf, i_key ) )
+                {
+                    intf_DbgMsg("unhandled key '%c' (%i)\n", (char) i_key, i_key );
+                }
+            }
+        }
+        /* Mouse click */
+        else if( xevent.type == ButtonPress )
+        {
+            switch( ((XButtonEvent *)&xevent)->button )
+            {
+                case Button1:
+                    /* in this part we will eventually manage
+                     * clicks for DVD navigation for instance */
+                    break;
+
+                case Button2:
+                    X11TogglePointer( p_intf );
+                    break;
+
+                case Button3:
+                    vlc_mutex_lock( &p_intf->p_vout->change_lock );
+                    p_intf->p_vout->b_interface = !p_intf->p_vout->b_interface;
+                    p_intf->p_vout->i_changes  |= VOUT_INTF_CHANGE;
+                    vlc_mutex_unlock( &p_intf->p_vout->change_lock );
+                    break;
+            }
+        }
+        /* ClientMessage event - only WM_PROTOCOLS with WM_DELETE_WINDOW data
+         * are handled - according to the man pages, the format is always 32
+         * in this case */
+        else if( (xevent.type == ClientMessage)
+                 && (xevent.xclient.message_type == p_intf->p_sys->wm_protocols)
+                 && (xevent.xclient.data.l[0] == p_intf->p_sys->wm_delete_window ) )
+        {
+            /* FIXME: this never happens :( how to receive wm messages ?? */
+            intf_DbgMsg("ClientMessage received\n");
+        }
+#ifdef DEBUG
+        /* Other event */
+        else
+        {
+            intf_DbgMsg("%p -> unhandled event type %d received\n", p_intf, xevent.type );
+        }
+#endif
+    }
+
+    /*
+     * Handle vout or interface windows resizing
+     */
+    if( p_intf->p_vout != NULL )
+    {
+        if( b_resized )
+        {
+            /* If interface window has been resized, change vout size */
+            intf_DbgMsg("resizing output window\n");
+            vlc_mutex_lock( &p_intf->p_vout->change_lock );
+            p_intf->p_vout->i_width =  p_intf->p_sys->i_width;
+            p_intf->p_vout->i_height = p_intf->p_sys->i_height;
+            p_intf->p_vout->i_changes |= VOUT_SIZE_CHANGE;
+            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
+        }
+        else if( (p_intf->p_vout->i_width  != p_intf->p_sys->i_width) ||
+                 (p_intf->p_vout->i_height != p_intf->p_sys->i_height) )
+        {
+           /* If video output size has changed, change interface window size */
+            intf_DbgMsg("resizing interface window\n");
+            p_intf->p_sys->i_width =    p_intf->p_vout->i_width;
+            p_intf->p_sys->i_height =   p_intf->p_vout->i_height;
+            XResizeWindow( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                           p_intf->p_sys->i_width, p_intf->p_sys->i_height );
+        }
+    }
+}
+
+/*****************************************************************************
+ * X11EnableScreenSaver: enable screen saver
+ *****************************************************************************
+ * This function enable the screen saver on a display after it had been
+ * disabled by XDisableScreenSaver. Both functions use a counter mechanism to
+ * know wether the screen saver can be activated or not: if n successive calls
+ * are made to XDisableScreenSaver, n successive calls to XEnableScreenSaver
+ * will be required before the screen saver could effectively be activated.
+ *****************************************************************************/
+void X11EnableScreenSaver( intf_thread_t *p_intf )
+{
+    if( p_intf->p_sys->i_ss_count++ == 0 )
+    {
+        intf_Msg("Enabling screen saver\n");
+        XSetScreenSaver( p_intf->p_sys->p_display, p_intf->p_sys->i_ss_timeout,
+                         p_intf->p_sys->i_ss_interval, p_intf->p_sys->i_ss_blanking,
+                         p_intf->p_sys->i_ss_exposure );
+    }
+}
+
+/*****************************************************************************
+ * X11DisableScreenSaver: disable screen saver
+ *****************************************************************************
+ * See XEnableScreenSaver
+ *****************************************************************************/
+void X11DisableScreenSaver( intf_thread_t *p_intf )
+{
+    if( --p_intf->p_sys->i_ss_count == 0 )
+    {
+        /* Save screen saver informations */
+        XGetScreenSaver( p_intf->p_sys->p_display, &p_intf->p_sys->i_ss_timeout,
+                         &p_intf->p_sys->i_ss_interval, &p_intf->p_sys->i_ss_blanking,
+                         &p_intf->p_sys->i_ss_exposure );
+
+        /* Disable screen saver */
+        intf_Msg("Disabling screen saver\n");
+        XSetScreenSaver( p_intf->p_sys->p_display, 0,
+                         p_intf->p_sys->i_ss_interval, p_intf->p_sys->i_ss_blanking,
+                         p_intf->p_sys->i_ss_exposure );
+    }
+}
+
+/*****************************************************************************
+ * X11TogglePointer: hide or show the mouse pointer
+ *****************************************************************************
+ * This function hides the X pointer if it is visible by putting it at
+ * coordinates (32,32) and setting the pointer sprite to a blank one. To
+ * show it again, we disable the sprite and restore the original coordinates.
+ *****************************************************************************/
+void X11TogglePointer( intf_thread_t *p_intf )
+{
+    static Cursor cursor;
+    static boolean_t b_cursor = 0;
+
+    if( p_intf->p_sys->b_mouse )
+    {
+        p_intf->p_sys->b_mouse = 0;
+
+        if( !b_cursor )
+        {
+            XColor color;
+            Pixmap blank = XCreatePixmap( p_intf->p_sys->p_display,
+                               DefaultRootWindow(p_intf->p_sys->p_display),
+                               1, 1, 1 );
+
+            XParseColor( p_intf->p_sys->p_display,
+                         XCreateColormap( p_intf->p_sys->p_display,
+                                          DefaultRootWindow(
+                                                  p_intf->p_sys->p_display ),
+                                          DefaultVisual(
+                                                  p_intf->p_sys->p_display,
+                                                  p_intf->p_sys->i_screen ),
+                                          AllocNone ),
+                         "black", &color );
+
+            cursor = XCreatePixmapCursor( p_intf->p_sys->p_display,
+                           blank, blank, &color, &color, 1, 1 );
+
+            b_cursor = 1;
+        }
+        XDefineCursor( p_intf->p_sys->p_display,
+                       p_intf->p_sys->window, cursor );
+    }
+    else
+    {
+        p_intf->p_sys->b_mouse = 1;
+
+        XUndefineCursor( p_intf->p_sys->p_display, p_intf->p_sys->window );
+    }
+}
diff --git a/plugins/mga/vout_mga.c b/plugins/mga/vout_mga.c
new file mode 100644 (file)
index 0000000..dcf387a
--- /dev/null
@@ -0,0 +1,685 @@
+/*****************************************************************************
+ * vout_mga.c: MGA video output display method
+ *****************************************************************************
+ * Copyright (C) 1998, 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+#include <fcntl.h>                                                 /* open() */
+#include <sys/ioctl.h>                                            /* ioctl() */
+#include <sys/mman.h>                                          /* PROT_WRITE */
+
+#ifdef SYS_BSD
+#include <sys/types.h>                                     /* typedef ushort */
+#endif
+
+#include <sys/shm.h>                                   /* shmget(), shmctl() */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+
+#include "vout_mga.h"
+
+/*****************************************************************************
+ * vout_SysCreate: allocate X11 video thread output method
+ *****************************************************************************
+ * This function allocate and initialize a X11 vout method. It uses some of the
+ * vout properties to choose the window size, and change them according to the
+ * actual properties of the display.
+ *****************************************************************************/
+int vout_SysCreate( vout_thread_t *p_vout, char *psz_display,
+                    int i_root_window, void *p_data )
+{
+    /* Allocate structure */
+    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+    if( p_vout->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Allocate MGA configuration structure */
+    p_vout->p_sys->p_mga = malloc( sizeof( mga_vid_config_t ) );
+    if( p_vout->p_sys->p_mga == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+
+    if( (p_vout->p_sys->i_fd = open("/dev/mga_vid",O_RDWR)) == -1 )
+    {
+        intf_ErrMsg("error: can't open MGA driver /dev/mga_vid\n" );
+        free( p_vout->p_sys->p_mga );
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+
+    /* Open and initialize device. This function issues its own error messages.
+     * Since XLib is usually not thread-safe, we can't use the same display
+     * pointer than the interface or another thread. However, the root window
+     * id is still valid. */
+    if( X11OpenDisplay( p_vout, psz_display, i_root_window ) )
+    {
+        intf_ErrMsg("error: can't initialize X11 display\n" );
+        free( p_vout->p_sys->p_mga );
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysInit: initialize X11 video thread output method
+ *****************************************************************************
+ * This function create the XImages needed by the output thread. It is called
+ * at the beginning of the thread, but also each time the window is resized.
+ *****************************************************************************/
+int vout_SysInit( vout_thread_t *p_vout )
+{
+    int i_err, i_dummy;
+
+    /* create the MGA output */
+    p_vout->p_sys->p_mga->src_width = p_vout->i_width;
+    p_vout->p_sys->p_mga->src_height = p_vout->i_height;
+    /* FIXME: we should initialize these ones according to the streams */
+    p_vout->p_sys->p_mga->dest_width = p_vout->i_width;
+    p_vout->p_sys->p_mga->dest_height = p_vout->i_height;
+    //p_vout->p_sys->p_mga->dest_width = 400;
+    //p_vout->p_sys->p_mga->dest_height = 300;
+    p_vout->p_sys->p_mga->x_org = 100;
+    p_vout->p_sys->p_mga->y_org = 100;
+    p_vout->p_sys->p_mga->colkey_on = 0;
+
+    if( ioctl(p_vout->p_sys->i_fd, MGA_VID_CONFIG, p_vout->p_sys->p_mga) )
+    {
+        intf_ErrMsg("error in config ioctl\n");
+    }
+
+    if (p_vout->p_sys->p_mga->card_type == MGA_G200)
+    {
+        intf_Msg( "detected MGA G200 (%d MB Ram)\n",
+                  p_vout->p_sys->p_mga->ram_size );
+        p_vout->p_sys->b_g400 = 0;
+    }
+    else
+    {
+        intf_Msg( "detected MGA G400 (%d MB Ram)\n",
+                  p_vout->p_sys->p_mga->ram_size );
+        p_vout->p_sys->b_g400 = 1;
+    }
+
+    ioctl( p_vout->p_sys->i_fd, MGA_VID_ON, 0 );
+
+    p_vout->p_sys->i_size = ( (p_vout->p_sys->p_mga->src_width + 31) & ~31 )
+                             * p_vout->p_sys->p_mga->src_height;
+
+    p_vout->p_sys->p_mga_vid_base = mmap( 0, p_vout->p_sys->i_size
+                                             + p_vout->p_sys->i_size / 2,
+                                          PROT_WRITE, MAP_SHARED,
+                                          p_vout->p_sys->i_fd, 0 );
+
+    memset( p_vout->p_sys->p_mga_vid_base,
+            0x00, p_vout->p_sys->i_size );
+
+    memset( p_vout->p_sys->p_mga_vid_base + p_vout->p_sys->i_size,
+            0x80, p_vout->p_sys->i_size / 2 );
+
+    /* Create XImages using XShm extension - on failure, fall back to regular
+     * way (and destroy the first image if it was created successfully) */
+    if( p_vout->p_sys->b_shm )
+    {
+        /* Create first image */
+        i_err = X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[0],
+                                   &p_vout->p_sys->shm_info[0] );
+        if( !i_err )                         /* first image has been created */
+        {
+            /* Create second image */
+            if( X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[1],
+                                   &p_vout->p_sys->shm_info[1] ) )
+            {                             /* error creating the second image */
+                X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0],
+                                    &p_vout->p_sys->shm_info[0] );
+                i_err = 1;
+            }
+        }
+        if( i_err )                                      /* an error occured */
+        {
+            intf_Msg("XShm video sextension desactivated\n" );
+            p_vout->p_sys->b_shm = 0;
+        }
+    }
+
+    /* Create XImages without XShm extension */
+    if( !p_vout->p_sys->b_shm )
+    {
+        if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[0] ) )
+        {
+            intf_ErrMsg("error: can't create images\n");
+            p_vout->p_sys->p_ximage[0] = NULL;
+            p_vout->p_sys->p_ximage[1] = NULL;
+            return( 1 );
+        }
+        if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[1] ) )
+        {
+            intf_ErrMsg("error: can't create images\n");
+            X11DestroyImage( p_vout->p_sys->p_ximage[0] );
+            p_vout->p_sys->p_ximage[0] = NULL;
+            p_vout->p_sys->p_ximage[1] = NULL;
+            return( 1 );
+        }
+    }
+
+    /* Set bytes per line and initialize buffers */
+    p_vout->i_bytes_per_line = p_vout->p_sys->p_ximage[0]->bytes_per_line;
+    vout_SetBuffers( p_vout, p_vout->p_sys->p_ximage[ 0 ]->data,
+                     p_vout->p_sys->p_ximage[ 1 ]->data );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysEnd: terminate X11 video thread output method
+ *****************************************************************************
+ * Destroy the X11 XImages created by vout_SysInit. It is called at the end of
+ * the thread, but also each time the window is resized.
+ *****************************************************************************/
+void vout_SysEnd( vout_thread_t *p_vout )
+{
+    if( p_vout->p_sys->b_shm )                             /* Shm XImages... */
+    {
+        X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0],
+                            &p_vout->p_sys->shm_info[0] );
+        X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[1],
+                            &p_vout->p_sys->shm_info[1] );
+    }
+    else                                          /* ...or regular XImages */
+    {
+        X11DestroyImage( p_vout->p_sys->p_ximage[0] );
+        X11DestroyImage( p_vout->p_sys->p_ximage[1] );
+    }
+}
+
+/*****************************************************************************
+ * vout_SysDestroy: destroy X11 video thread output method
+ *****************************************************************************
+ * Terminate an output method created by vout_CreateOutputMethod
+ *****************************************************************************/
+void vout_SysDestroy( vout_thread_t *p_vout )
+{
+    X11CloseDisplay( p_vout );
+
+    ioctl( p_vout->p_sys->i_fd, MGA_VID_OFF, 0 );
+    close( p_vout->p_sys->i_fd );
+
+    free( p_vout->p_sys->p_mga );
+    free( p_vout->p_sys );
+}
+
+/*****************************************************************************
+ * vout_SysManage: handle X11 events
+ *****************************************************************************
+ * This function should be called regularly by video output thread. It manages
+ * X11 events and allows window resizing. It returns a non null value on
+ * error.
+ *****************************************************************************/
+int vout_SysManage( vout_thread_t *p_vout )
+{
+    /*
+     * Color/Grayscale or gamma change: in 8bpp, just change the colormap
+     */
+    if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE) && (p_vout->i_screen_depth == 8) )
+    {
+        /* FIXME: clear flags ?? */
+    }
+
+    /*
+     * Size change
+     */
+    if( p_vout->i_changes & VOUT_SIZE_CHANGE )
+    {
+        intf_DbgMsg("resizing window\n");
+        p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
+
+        /* Resize window */
+        XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                       p_vout->i_width, p_vout->i_height );
+
+        /* Destroy XImages to change their size */
+        vout_SysEnd( p_vout );
+
+        /* Recreate XImages. If SysInit failed, the thread can't go on. */
+        if( vout_SysInit( p_vout ) )
+        {
+            intf_ErrMsg("error: can't resize display\n");
+            return( 1 );
+        }
+
+        /* Tell the video output thread that it will need to rebuild YUV
+         * tables. This is needed since convertion buffer size may have changed */
+        p_vout->i_changes |= VOUT_YUV_CHANGE;
+        intf_Msg("Video display resized (%dx%d)\n", p_vout->i_width, p_vout->i_height);
+    }
+
+    return 0;
+}
+
+/*****************************************************************************
+ * vout_SysDisplay: displays previously rendered output
+ *****************************************************************************
+ * This function send the currently rendered image to X11 server, wait until
+ * it is displayed and switch the two rendering buffer, preparing next frame.
+ *****************************************************************************/
+void vout_SysDisplay( vout_thread_t *p_vout )
+{
+    if( p_vout->p_sys->b_shm)                                /* XShm is used */
+    {
+        /* Display rendered image using shared memory extension */
+        XShmPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
+                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ],
+                     0, 0, 0, 0,
+                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width,
+                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height, True);
+
+        /* Send the order to the X server */
+        XFlush(p_vout->p_sys->p_display);
+    }
+    else                                /* regular X11 capabilities are used */
+    {
+        XPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
+                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ],
+                  0, 0, 0, 0,
+                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width,
+                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height);
+
+        /* Send the order to the X server */
+        XFlush(p_vout->p_sys->p_display);
+    }
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * X11OpenDisplay: open and initialize X11 device
+ *****************************************************************************
+ * Create a window according to video output given size, and set other
+ * properties according to the display properties.
+ *****************************************************************************/
+static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root_window )
+{
+    XPixmapFormatValues *       p_xpixmap_format;          /* pixmap formats */
+    XVisualInfo *               p_xvisual;           /* visuals informations */
+    XVisualInfo                 xvisual_template;         /* visual template */
+    int                         i_count;                       /* array size */
+
+    /* Open display */
+    p_vout->p_sys->p_display = XOpenDisplay( psz_display );
+    if( p_vout->p_sys->p_display == NULL )
+    {
+        intf_ErrMsg("error: can't open display %s\n", psz_display );
+        return( 1 );
+    }
+
+    /* Initialize structure */
+    p_vout->p_sys->root_window  = root_window;
+    p_vout->p_sys->b_shm        = (XShmQueryExtension(p_vout->p_sys->p_display) == True);
+    p_vout->p_sys->i_screen     = DefaultScreen( p_vout->p_sys->p_display );
+    if( !p_vout->p_sys->b_shm )
+    {
+        intf_Msg("XShm video extension is not available\n");
+    }
+
+    /* Get screen depth */
+    p_vout->i_screen_depth = XDefaultDepth( p_vout->p_sys->p_display, p_vout->p_sys->i_screen );
+    switch( p_vout->i_screen_depth )
+    {
+    case 8:
+        /*
+         * Screen depth is 8bpp. Use PseudoColor visual with private colormap.
+         */
+        xvisual_template.screen =   p_vout->p_sys->i_screen;
+        xvisual_template.class =    DirectColor;
+        p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask,
+                                    &xvisual_template, &i_count );
+        if( p_xvisual == NULL )
+        {
+            intf_ErrMsg("error: no PseudoColor visual available\n");
+            XCloseDisplay( p_vout->p_sys->p_display );
+            return( 1 );
+        }
+        /* FIXME: SetColormap; ?? */
+        p_vout->i_bytes_per_pixel = 1;
+        break;
+    case 15:
+    case 16:
+    case 24:
+    default:
+        /*
+         * Screen depth is higher than 8bpp. TrueColor visual is used.
+         */
+        xvisual_template.screen =   p_vout->p_sys->i_screen;
+        xvisual_template.class =    TrueColor;
+        p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask,
+                                    &xvisual_template, &i_count );
+        if( p_xvisual == NULL )
+        {
+            intf_ErrMsg("error: no TrueColor visual available\n");
+            XCloseDisplay( p_vout->p_sys->p_display );
+            return( 1 );
+        }
+        p_vout->i_red_mask =        p_xvisual->red_mask;
+        p_vout->i_green_mask =      p_xvisual->green_mask;
+        p_vout->i_blue_mask =       p_xvisual->blue_mask;
+
+        /* There is no difference yet between 3 and 4 Bpp. The only way to find
+         * the actual number of bytes per pixel is to list supported pixmap
+         * formats. */
+        p_xpixmap_format = XListPixmapFormats( p_vout->p_sys->p_display, &i_count );
+        p_vout->i_bytes_per_pixel = 0;
+        for( ; i_count--; p_xpixmap_format++ )
+        {
+            if( p_xpixmap_format->bits_per_pixel / 8 > p_vout->i_bytes_per_pixel )
+            {
+                p_vout->i_bytes_per_pixel = p_xpixmap_format->bits_per_pixel / 8;
+            }
+        }
+        break;
+    }
+    p_vout->p_sys->p_visual = p_xvisual->visual;
+    XFree( p_xvisual );
+
+    /* Create a window */
+    if( X11CreateWindow( p_vout ) )
+    {
+        intf_ErrMsg("error: can't open a window\n");
+        XCloseDisplay( p_vout->p_sys->p_display );
+        return( 1 );
+    }
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11CloseDisplay: close X11 device
+ *****************************************************************************
+ * Returns all resources allocated by X11OpenDisplay and restore the original
+ * state of the display.
+ *****************************************************************************/
+static void X11CloseDisplay( vout_thread_t *p_vout )
+{
+    /* Destroy colormap */
+    if( p_vout->i_screen_depth == 8 )
+    {
+        XFreeColormap( p_vout->p_sys->p_display, p_vout->p_sys->colormap );
+    }
+
+    /* Destroy window and close display */
+    X11DestroyWindow( p_vout );
+    XCloseDisplay( p_vout->p_sys->p_display );
+}
+
+/*****************************************************************************
+ * X11CreateWindow: create X11 vout window
+ *****************************************************************************
+ * The video output window will be created. Normally, this window is wether
+ * full screen or part of a parent window. Therefore, it does not need a
+ * title or other hints. Thery are still supplied in case the window would be
+ * spawned as a standalone one by the interface.
+ *****************************************************************************/
+static int X11CreateWindow( vout_thread_t *p_vout )
+{
+    XSetWindowAttributes    xwindow_attributes;         /* window attributes */
+    XGCValues               xgcvalues;      /* graphic context configuration */
+    XEvent                  xevent;                          /* first events */
+    boolean_t               b_expose;             /* 'expose' event received */
+    boolean_t               b_map_notify;     /* 'map_notify' event received */
+
+    /* Prepare window attributes */
+    xwindow_attributes.backing_store = Always;       /* save the hidden part */
+
+    /* Create the window and set hints */
+    p_vout->p_sys->window = XCreateSimpleWindow( p_vout->p_sys->p_display,
+                                         p_vout->p_sys->root_window,
+                                         0, 0,
+                                         p_vout->i_width, p_vout->i_height,
+                                         0, 0, 0);
+    XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                  ExposureMask | StructureNotifyMask );
+    XChangeWindowAttributes( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                             CWBackingStore, &xwindow_attributes);
+
+    /* Creation of a graphic context that doesn't generate a GraphicsExpose event
+       when using functions like XCopyArea */
+    xgcvalues.graphics_exposures = False;
+    p_vout->p_sys->gc =  XCreateGC( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                                    GCGraphicsExposures, &xgcvalues);
+
+    /* Send orders to server, and wait until window is displayed - two events
+     * must be received: a MapNotify event, an Expose event allowing drawing in the
+     * window */
+    b_expose = 0;
+    b_map_notify = 0;
+    XMapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window);
+    do
+    {
+        XNextEvent( p_vout->p_sys->p_display, &xevent);
+        if( (xevent.type == Expose)
+            && (xevent.xexpose.window == p_vout->p_sys->window) )
+        {
+            b_expose = 1;
+        }
+        else if( (xevent.type == MapNotify)
+                 && (xevent.xmap.window == p_vout->p_sys->window) )
+        {
+            b_map_notify = 1;
+        }
+    }
+    while( !( b_expose && b_map_notify ) );
+    XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window, 0 );
+
+    /* At this stage, the window is openned, displayed, and ready to receive
+     * data */
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11DestroyWindow: destroy X11 window
+ *****************************************************************************
+ * Destroy an X11 window created by vout_CreateWindow
+ *****************************************************************************/
+static void X11DestroyWindow( vout_thread_t *p_vout )
+{
+    XUnmapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
+    XFreeGC( p_vout->p_sys->p_display, p_vout->p_sys->gc );
+    XDestroyWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
+}
+
+/*****************************************************************************
+ * X11CreateImage: create an XImage
+ *****************************************************************************
+ * Create a simple XImage used as a buffer.
+ *****************************************************************************/
+static int X11CreateImage( vout_thread_t *p_vout, XImage **pp_ximage )
+{
+    byte_t *    pb_data;                          /* image data storage zone */
+    int         i_quantum;                     /* XImage quantum (see below) */
+
+    /* Allocate memory for image */
+    p_vout->i_bytes_per_line = p_vout->i_width * p_vout->i_bytes_per_pixel;
+    pb_data = (byte_t *) malloc( p_vout->i_bytes_per_line * p_vout->i_height );
+    if( !pb_data )                                                  /* error */
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        return( 1 );
+    }
+
+    /* Optimize the quantum of a scanline regarding its size - the quantum is
+       a diviser of the number of bits between the start of two scanlines. */
+    if( !(( p_vout->i_bytes_per_line ) % 32) )
+    {
+        i_quantum = 32;
+    }
+    else
+    {
+        if( !(( p_vout->i_bytes_per_line ) % 16) )
+        {
+            i_quantum = 16;
+        }
+        else
+        {
+            i_quantum = 8;
+        }
+    }
+
+    /* Create XImage */
+    *pp_ximage = XCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual,
+                               p_vout->i_screen_depth, ZPixmap, 0, pb_data,
+                               p_vout->i_width, p_vout->i_height, i_quantum, 0);
+    if(! *pp_ximage )                                               /* error */
+    {
+        intf_ErrMsg( "error: XCreateImage() failed\n" );
+        free( pb_data );
+        return( 1 );
+    }
+
+    return 0;
+}
+
+/*****************************************************************************
+ * X11CreateShmImage: create an XImage using shared memory extension
+ *****************************************************************************
+ * Prepare an XImage for DisplayX11ShmImage function.
+ * The order of the operations respects the recommandations of the mit-shm
+ * document by J.Corbet and K.Packard. Most of the parameters were copied from
+ * there.
+ *****************************************************************************/
+static int X11CreateShmImage( vout_thread_t *p_vout, XImage **pp_ximage,
+                              XShmSegmentInfo *p_shm_info)
+{
+    /* Create XImage */
+    *pp_ximage = XShmCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual,
+                                  p_vout->i_screen_depth, ZPixmap, 0,
+                                  p_shm_info, p_vout->i_width, p_vout->i_height );
+    if(! *pp_ximage )                                               /* error */
+    {
+        intf_ErrMsg("error: XShmCreateImage() failed\n");
+        return( 1 );
+    }
+
+    /* Allocate shared memory segment - 0777 set the access permission
+     * rights (like umask), they are not yet supported by X servers */
+    p_shm_info->shmid = shmget( IPC_PRIVATE,
+                                (*pp_ximage)->bytes_per_line * (*pp_ximage)->height,
+                                IPC_CREAT | 0777);
+    if( p_shm_info->shmid < 0)                                      /* error */
+    {
+        intf_ErrMsg("error: can't allocate shared image data (%s)\n",
+                    strerror(errno));
+        XDestroyImage( *pp_ximage );
+        return( 1 );
+    }
+
+    /* Attach shared memory segment to process (read/write) */
+    p_shm_info->shmaddr = (*pp_ximage)->data = shmat(p_shm_info->shmid, 0, 0);
+    if(! p_shm_info->shmaddr )
+    {                                                               /* error */
+        intf_ErrMsg("error: can't attach shared memory (%s)\n",
+                    strerror(errno));
+        shmctl( p_shm_info->shmid, IPC_RMID, 0 );      /* free shared memory */
+        XDestroyImage( *pp_ximage );
+        return( 1 );
+    }
+
+    /* Mark the shm segment to be removed when there will be no more
+     * attachements, so it is automatic on process exit or after shmdt */
+    shmctl( p_shm_info->shmid, IPC_RMID, 0 );
+
+    /* Attach shared memory segment to X server (read only) */
+    p_shm_info->readOnly = True;
+    if( XShmAttach( p_vout->p_sys->p_display, p_shm_info ) == False )    /* error */
+    {
+        intf_ErrMsg("error: can't attach shared memory to X11 server\n");
+        shmdt( p_shm_info->shmaddr );     /* detach shared memory from process
+                                           * and automatic free                */
+        XDestroyImage( *pp_ximage );
+        return( 1 );
+    }
+
+    /* Send image to X server. This instruction is required, since having
+     * built a Shm XImage and not using it causes an error on XCloseDisplay */
+    XFlush( p_vout->p_sys->p_display );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11DestroyImage: destroy an XImage
+ *****************************************************************************
+ * Destroy XImage AND associated data. If pointer is NULL, the image won't be
+ * destroyed (see vout_ManageOutputMethod())
+ *****************************************************************************/
+static void X11DestroyImage( XImage *p_ximage )
+{
+    if( p_ximage != NULL )
+    {
+        XDestroyImage( p_ximage );                     /* no free() required */
+    }
+}
+
+/*****************************************************************************
+ * X11DestroyShmImage
+ *****************************************************************************
+ * Destroy XImage AND associated data. Detach shared memory segment from
+ * server and process, then free it. If pointer is NULL, the image won't be
+ * destroyed (see vout_ManageOutputMethod())
+ *****************************************************************************/
+static void X11DestroyShmImage( vout_thread_t *p_vout, XImage *p_ximage,
+                                XShmSegmentInfo *p_shm_info )
+{
+    /* If pointer is NULL, do nothing */
+    if( p_ximage == NULL )
+    {
+        return;
+    }
+
+    XShmDetach( p_vout->p_sys->p_display, p_shm_info );     /* detach from server */
+    XDestroyImage( p_ximage );
+    if( shmdt( p_shm_info->shmaddr ) )  /* detach shared memory from process */
+    {                                   /* also automatic freeing...         */
+        intf_ErrMsg("error: can't detach shared memory (%s)\n",
+                    strerror(errno));
+    }
+}
+
diff --git a/plugins/mga/vout_mga.h b/plugins/mga/vout_mga.h
new file mode 100644 (file)
index 0000000..7d23e8d
--- /dev/null
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * vout_mga.h: MGA video output display method headers
+ *****************************************************************************
+ * Copyright (C) 1999 Aaron Holtzman
+ * Copyright (C) 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Boston, MA 02111-1307, USA.
+ *****************************************************************************/
+
+#ifndef __LINUX_MGAVID_H
+#define __LINUX_MGAVID_H
+
+typedef struct mga_vid_config_s
+{
+    u32     card_type;
+    u32     ram_size;
+    u32     src_width;
+    u32     src_height;
+    u32     dest_width;
+    u32     dest_height;
+    u32     x_org;
+    u32     y_org;
+    u8      colkey_on;
+    u8      colkey_red;
+    u8      colkey_green;
+    u8      colkey_blue;
+} mga_vid_config_t;
+
+#define MGA_VID_CONFIG _IOR('J', 1, mga_vid_config_t)
+#define MGA_VID_ON     _IO ('J', 2)
+#define MGA_VID_OFF    _IO ('J', 3)
+
+#define MGA_G200 0x1234
+#define MGA_G400 0x5678
+
+#endif
+
+/*****************************************************************************
+ * vout_sys_t: video output X11 method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the X11 specific properties of an output thread. X11 video
+ * output is performed through regular resizable windows. Windows can be
+ * dynamically resized to adapt to the size of the streams.
+ *****************************************************************************/
+typedef struct vout_sys_s
+{
+    /* User settings */
+    boolean_t           b_shm;               /* shared memory extension flag */
+
+    /* Internal settings and properties */
+    Display *           p_display;                        /* display pointer */
+    Visual *            p_visual;                          /* visual pointer */
+    int                 i_screen;                           /* screen number */
+    Window              root_window;                          /* root window */
+    Window              window;                   /* window instance handler */
+    GC                  gc;              /* graphic context instance handler */
+    Colormap            colormap;               /* colormap used (8bpp only) */
+
+    /* Display buffers and shared memory information */
+    XImage *            p_ximage[2];                       /* XImage pointer */
+    XShmSegmentInfo     shm_info[2];       /* shared memory zone information */
+
+    /* MGA specific variables */
+    int                 i_fd;
+    int                 i_size;
+    mga_vid_config_t *  p_mga;
+    byte_t *            p_mga_vid_base;
+    boolean_t           b_g400;
+
+} vout_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  X11OpenDisplay      ( vout_thread_t *p_vout, char *psz_display, Window root_window );
+static void X11CloseDisplay     ( vout_thread_t *p_vout );
+static int  X11CreateWindow     ( vout_thread_t *p_vout );
+static void X11DestroyWindow    ( vout_thread_t *p_vout );
+static int  X11CreateImage      ( vout_thread_t *p_vout, XImage **pp_ximage );
+static void X11DestroyImage     ( XImage *p_ximage );
+static int  X11CreateShmImage   ( vout_thread_t *p_vout, XImage **pp_ximage,
+                                  XShmSegmentInfo *p_shm_info );
+static void X11DestroyShmImage  ( vout_thread_t *p_vout, XImage *p_ximage,
+                                  XShmSegmentInfo *p_shm_info );
+
diff --git a/plugins/x11/intf_x11.c b/plugins/x11/intf_x11.c
new file mode 100644 (file)
index 0000000..fb54442
--- /dev/null
@@ -0,0 +1,550 @@
+/*****************************************************************************
+ * intf_x11.c: X11 interface
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+#include <sys/types.h>                        /* on BSD, uio.h needs types.h */
+#include <sys/uio.h>                                          /* for input.h */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "input.h"
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+#include "interface.h"
+
+#include "main.h"
+
+/*****************************************************************************
+ * intf_sys_t: description and status of X11 interface
+ *****************************************************************************/
+typedef struct intf_sys_s
+{
+    /* X11 generic properties */
+    Display *           p_display;                    /* X11 display pointer */
+    int                 i_screen;                              /* X11 screen */
+    Atom                wm_protocols;
+    Atom                wm_delete_window;
+
+    /* Main window properties */
+    Window              window;                               /* main window */
+    GC                  gc;               /* graphic context for main window */
+    int                 i_width;                     /* width of main window */
+    int                 i_height;                   /* height of main window */
+    Colormap            colormap;               /* colormap used (8bpp only) */
+
+    /* Screen saver properties */
+    int                 i_ss_count;              /* enabling/disabling count */
+    int                 i_ss_timeout;                             /* timeout */
+    int                 i_ss_interval;           /* interval between changes */
+    int                 i_ss_blanking;                      /* blanking mode */
+    int                 i_ss_exposure;                      /* exposure mode */
+
+    /* Mouse pointer properties */
+    boolean_t           b_mouse;         /* is the mouse pointer displayed ? */
+
+} intf_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  X11CreateWindow             ( intf_thread_t *p_intf );
+static void X11DestroyWindow            ( intf_thread_t *p_intf );
+static void X11ManageWindow             ( intf_thread_t *p_intf );
+static void X11EnableScreenSaver        ( intf_thread_t *p_intf );
+static void X11DisableScreenSaver       ( intf_thread_t *p_intf );
+static void X11TogglePointer            ( intf_thread_t *p_intf );
+
+/*****************************************************************************
+ * intf_SysCreate: initialize and create window
+ *****************************************************************************/
+int intf_SysCreate( intf_thread_t *p_intf )
+{
+    char       *psz_display;
+
+    /* Allocate instance and initialize some members */
+    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    if( p_intf->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        return( 1 );
+    }
+
+    /* Open display, unsing 'vlc_display' or DISPLAY environment variable */
+    psz_display = XDisplayName( main_GetPszVariable( VOUT_DISPLAY_VAR, NULL ) );
+    p_intf->p_sys->p_display = XOpenDisplay( psz_display );
+    if( !p_intf->p_sys->p_display )                                 /* error */
+    {
+        intf_ErrMsg("error: can't open display %s\n", psz_display );
+        free( p_intf->p_sys );
+        return( 1 );
+    }
+    p_intf->p_sys->i_screen = DefaultScreen( p_intf->p_sys->p_display );
+
+    /* Spawn base window - this window will include the video output window,
+     * but also command buttons, subtitles and other indicators */
+    if( X11CreateWindow( p_intf ) )
+    {
+        intf_ErrMsg("error: can't create interface window\n" );
+        XCloseDisplay( p_intf->p_sys->p_display );
+        free( p_intf->p_sys );
+        return( 1 );
+    }
+
+    /* Spawn video output thread */
+    if( p_main->b_video )
+    {
+        p_intf->p_vout = vout_CreateThread( psz_display, p_intf->p_sys->window,
+                                            p_intf->p_sys->i_width,
+                                            p_intf->p_sys->i_height, NULL, 0,
+                                            (void *)&p_intf->p_sys->colormap );
+
+        if( p_intf->p_vout == NULL )                                /* error */
+        {
+            intf_ErrMsg("error: can't create video output thread\n" );
+            X11DestroyWindow( p_intf );
+            XCloseDisplay( p_intf->p_sys->p_display );
+            free( p_intf->p_sys );
+            return( 1 );
+        }
+    }
+
+    p_intf->p_sys->b_mouse = 1;
+
+    /* Disable screen saver and return */
+    p_intf->p_sys->i_ss_count = 1;
+    X11DisableScreenSaver( p_intf );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * intf_SysDestroy: destroy interface window
+ *****************************************************************************/
+void intf_SysDestroy( intf_thread_t *p_intf )
+{
+    /* Enable screen saver */
+    X11EnableScreenSaver( p_intf );
+
+    /* Close input thread, if any (blocking) */
+    if( p_intf->p_input )
+    {
+        input_DestroyThread( p_intf->p_input, NULL );
+    }
+
+    /* Close video output thread, if any (blocking) */
+    if( p_intf->p_vout )
+    {
+        vout_DestroyThread( p_intf->p_vout, NULL );
+    }
+
+    /* Close main window and display */
+    X11DestroyWindow( p_intf );
+    XCloseDisplay( p_intf->p_sys->p_display );
+
+    /* Destroy structure */
+    free( p_intf->p_sys );
+}
+
+
+/*****************************************************************************
+ * intf_SysManage: event loop
+ *****************************************************************************/
+void intf_SysManage( intf_thread_t *p_intf )
+{
+    /* Manage main window */
+    X11ManageWindow( p_intf );
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * X11CreateWindow: open and set-up X11 main window
+ *****************************************************************************/
+static int X11CreateWindow( intf_thread_t *p_intf )
+{
+    XSizeHints              xsize_hints;
+    XSetWindowAttributes    xwindow_attributes;
+    XGCValues               xgcvalues;
+    XEvent                  xevent;
+    boolean_t               b_expose;
+    boolean_t               b_configure_notify;
+    boolean_t               b_map_notify;
+
+    /* Set main window's size */
+    p_intf->p_sys->i_width =  main_GetIntVariable( VOUT_WIDTH_VAR,
+                                                   VOUT_WIDTH_DEFAULT );
+    p_intf->p_sys->i_height = main_GetIntVariable( VOUT_HEIGHT_VAR,
+                                                   VOUT_HEIGHT_DEFAULT );
+
+    /* Prepare window manager hints and properties */
+    xsize_hints.base_width =            p_intf->p_sys->i_width;
+    xsize_hints.base_height =           p_intf->p_sys->i_height;
+    xsize_hints.flags =                 PSize;
+    p_intf->p_sys->wm_protocols =       XInternAtom( p_intf->p_sys->p_display,
+                                                     "WM_PROTOCOLS", True );
+    p_intf->p_sys->wm_delete_window =   XInternAtom( p_intf->p_sys->p_display,
+                                                     "WM_DELETE_WINDOW", True );
+
+    /* Prepare window attributes */
+    xwindow_attributes.backing_store = Always;       /* save the hidden part */
+    xwindow_attributes.background_pixel = WhitePixel( p_intf->p_sys->p_display,
+                                                      p_intf->p_sys->i_screen );
+
+    xwindow_attributes.event_mask = ExposureMask | StructureNotifyMask;
+
+    /* Create the window and set hints - the window must receive ConfigureNotify
+     * events, and, until it is displayed, Expose and MapNotify events. */
+    p_intf->p_sys->window =
+            XCreateWindow( p_intf->p_sys->p_display,
+                           DefaultRootWindow( p_intf->p_sys->p_display ),
+                           0, 0,
+                           p_intf->p_sys->i_width, p_intf->p_sys->i_height, 1,
+                           0, InputOutput, 0,
+                           CWBackingStore | CWBackPixel | CWEventMask,
+                           &xwindow_attributes );
+
+    /* Set window manager hints and properties: size hints, command,
+     * window's name, and accepted protocols */
+    XSetWMNormalHints( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                       &xsize_hints );
+    XSetCommand( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                 p_main->ppsz_argv, p_main->i_argc );
+    XStoreName( p_intf->p_sys->p_display, p_intf->p_sys->window, VOUT_TITLE );
+
+    if( (p_intf->p_sys->wm_protocols == None)        /* use WM_DELETE_WINDOW */
+        || (p_intf->p_sys->wm_delete_window == None)
+        || !XSetWMProtocols( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                             &p_intf->p_sys->wm_delete_window, 1 ) )
+    {
+        /* WM_DELETE_WINDOW is not supported by window manager */
+        intf_Msg("error: missing or bad window manager - please exit program kindly.\n");
+    }
+
+    /* Creation of a graphic context that doesn't generate a GraphicsExpose
+     * event when using functions like XCopyArea */
+    xgcvalues.graphics_exposures = False;
+    p_intf->p_sys->gc =  XCreateGC( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                                    GCGraphicsExposures, &xgcvalues);
+
+    /* Send orders to server, and wait until window is displayed - three
+     * events must be received: a MapNotify event, an Expose event allowing
+     * drawing in the window, and a ConfigureNotify to get the window
+     * dimensions. Once those events have been received, only ConfigureNotify
+     * events need to be received. */
+    b_expose = 0;
+    b_configure_notify = 0;
+    b_map_notify = 0;
+    XMapWindow( p_intf->p_sys->p_display, p_intf->p_sys->window);
+    do
+    {
+        XNextEvent( p_intf->p_sys->p_display, &xevent);
+        if( (xevent.type == Expose)
+            && (xevent.xexpose.window == p_intf->p_sys->window) )
+        {
+            b_expose = 1;
+        }
+        else if( (xevent.type == MapNotify)
+                 && (xevent.xmap.window == p_intf->p_sys->window) )
+        {
+            b_map_notify = 1;
+        }
+        else if( (xevent.type == ConfigureNotify)
+                 && (xevent.xconfigure.window == p_intf->p_sys->window) )
+        {
+            b_configure_notify = 1;
+            p_intf->p_sys->i_width = xevent.xconfigure.width;
+            p_intf->p_sys->i_height = xevent.xconfigure.height;
+        }
+    } while( !( b_expose && b_configure_notify && b_map_notify ) );
+
+    XSelectInput( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                  StructureNotifyMask | KeyPressMask | ButtonPressMask );
+
+    if( XDefaultDepth(p_intf->p_sys->p_display, p_intf->p_sys->i_screen) == 8 )
+    {
+        /* Allocate a new palette */
+        p_intf->p_sys->colormap = XCreateColormap( p_intf->p_sys->p_display,
+                              DefaultRootWindow( p_intf->p_sys->p_display ),
+                              DefaultVisual( p_intf->p_sys->p_display,
+                                             p_intf->p_sys->i_screen ),
+                              AllocAll );
+
+        xwindow_attributes.colormap = p_intf->p_sys->colormap;
+        XChangeWindowAttributes( p_intf->p_sys->p_display,
+                                 p_intf->p_sys->window,
+                                 CWColormap, &xwindow_attributes );
+    }
+
+    /* At this stage, the window is open, displayed, and ready to receive data */
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11DestroyWindow: destroy X11 main window
+ *****************************************************************************/
+static void X11DestroyWindow( intf_thread_t *p_intf )
+{
+    XUnmapWindow( p_intf->p_sys->p_display, p_intf->p_sys->window );
+    XFreeGC( p_intf->p_sys->p_display, p_intf->p_sys->gc );
+    XDestroyWindow( p_intf->p_sys->p_display, p_intf->p_sys->window );
+}
+
+/*****************************************************************************
+ * X11ManageWindow: manage X11 main window
+ *****************************************************************************/
+static void X11ManageWindow( intf_thread_t *p_intf )
+{
+    XEvent      xevent;                                         /* X11 event */
+    boolean_t   b_resized;                        /* window has been resized */
+    char        i_key;                                    /* ISO Latin-1 key */
+
+    /* Handle X11 events: ConfigureNotify events are parsed to know if the
+     * output window's size changed, MapNotify and UnmapNotify to know if the
+     * window is mapped (and if the display is useful), and ClientMessages
+     * to intercept window destruction requests */
+    b_resized = 0;
+    while( XCheckWindowEvent( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                              StructureNotifyMask | KeyPressMask |
+                              ButtonPressMask, &xevent ) == True )
+    {
+        /* ConfigureNotify event: prepare  */
+        if( (xevent.type == ConfigureNotify)
+            && ((xevent.xconfigure.width != p_intf->p_sys->i_width)
+                || (xevent.xconfigure.height != p_intf->p_sys->i_height)) )
+        {
+            /* Update dimensions */
+            b_resized = 1;
+            p_intf->p_sys->i_width = xevent.xconfigure.width;
+            p_intf->p_sys->i_height = xevent.xconfigure.height;
+        }
+        /* MapNotify event: change window status and disable screen saver */
+        else if( xevent.type == MapNotify)
+        {
+            if( (p_intf->p_vout != NULL) && !p_intf->p_vout->b_active )
+            {
+                X11DisableScreenSaver( p_intf );
+                p_intf->p_vout->b_active = 1;
+            }
+        }
+        /* UnmapNotify event: change window status and enable screen saver */
+        else if( xevent.type == UnmapNotify )
+        {
+            if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_active )
+            {
+                X11EnableScreenSaver( p_intf );
+                p_intf->p_vout->b_active = 0;
+            }
+        }
+        /* Keyboard event */
+        else if( xevent.type == KeyPress )
+        {
+            if( XLookupString( &xevent.xkey, &i_key, 1, NULL, NULL ) )
+            {
+                if( intf_ProcessKey( p_intf, i_key ) )
+                {
+                    intf_DbgMsg("unhandled key '%c' (%i)\n", (char) i_key, i_key );
+                }
+            }
+        }
+        /* Mouse click */
+        else if( xevent.type == ButtonPress )
+        {
+            switch( ((XButtonEvent *)&xevent)->button )
+            {
+                case Button1:
+                    /* in this part we will eventually manage
+                     * clicks for DVD navigation for instance */
+                    break;
+
+                case Button2:
+                    X11TogglePointer( p_intf );
+                    break;
+
+                case Button3:
+                    vlc_mutex_lock( &p_intf->p_vout->change_lock );
+                    p_intf->p_vout->b_interface = !p_intf->p_vout->b_interface;
+                    p_intf->p_vout->i_changes |= VOUT_INTF_CHANGE;
+                    vlc_mutex_unlock( &p_intf->p_vout->change_lock );
+                    break;
+            }
+        }
+#ifdef DEBUG
+        /* Other event */
+        else
+        {
+            intf_DbgMsg( "%p -> unhandled event type %d received\n",
+                         p_intf, xevent.type );
+        }
+#endif
+    }
+
+    /* ClientMessage event - only WM_PROTOCOLS with WM_DELETE_WINDOW data
+     * are handled - according to the man pages, the format is always 32
+     * in this case */
+    while( XCheckTypedEvent( p_intf->p_sys->p_display,
+                             ClientMessage, &xevent ) )
+    {
+        if( (xevent.xclient.message_type == p_intf->p_sys->wm_protocols)
+            && (xevent.xclient.data.l[0] == p_intf->p_sys->wm_delete_window ) )
+        {
+            p_intf->b_die = 1;
+        }
+        else
+        {
+            intf_DbgMsg( "%p -> unhandled ClientMessage received\n", p_intf );
+        }
+    }
+
+    /*
+     * Handle vout or interface windows resizing
+     */
+    if( p_intf->p_vout != NULL )
+    {
+        if( b_resized )
+        {
+            /* If interface window has been resized, change vout size */
+            intf_DbgMsg( "resizing output window\n" );
+            vlc_mutex_lock( &p_intf->p_vout->change_lock );
+            p_intf->p_vout->i_width =  p_intf->p_sys->i_width;
+            p_intf->p_vout->i_height = p_intf->p_sys->i_height;
+            p_intf->p_vout->i_changes |= VOUT_SIZE_CHANGE;
+            vlc_mutex_unlock( &p_intf->p_vout->change_lock );
+        }
+        else if( (p_intf->p_vout->i_width  != p_intf->p_sys->i_width) ||
+                 (p_intf->p_vout->i_height != p_intf->p_sys->i_height) )
+        {
+           /* If video output size has changed, change interface window size */
+            intf_DbgMsg( "resizing output window\n" );
+            p_intf->p_sys->i_width =    p_intf->p_vout->i_width;
+            p_intf->p_sys->i_height =   p_intf->p_vout->i_height;
+            XResizeWindow( p_intf->p_sys->p_display, p_intf->p_sys->window,
+                           p_intf->p_sys->i_width, p_intf->p_sys->i_height );
+        }
+    }
+}
+
+/*****************************************************************************
+ * X11EnableScreenSaver: enable screen saver
+ *****************************************************************************
+ * This function enable the screen saver on a display after it had been
+ * disabled by XDisableScreenSaver. Both functions use a counter mechanism to
+ * know wether the screen saver can be activated or not: if n successive calls
+ * are made to XDisableScreenSaver, n successive calls to XEnableScreenSaver
+ * will be required before the screen saver could effectively be activated.
+ *****************************************************************************/
+void X11EnableScreenSaver( intf_thread_t *p_intf )
+{
+    if( p_intf->p_sys->i_ss_count++ == 0 )
+    {
+        intf_Msg( "Enabling screen saver\n" );
+        XSetScreenSaver( p_intf->p_sys->p_display, p_intf->p_sys->i_ss_timeout,
+                         p_intf->p_sys->i_ss_interval, p_intf->p_sys->i_ss_blanking,
+                         p_intf->p_sys->i_ss_exposure );
+    }
+}
+
+/*****************************************************************************
+ * X11DisableScreenSaver: disable screen saver
+ *****************************************************************************
+ * See XEnableScreenSaver
+ *****************************************************************************/
+void X11DisableScreenSaver( intf_thread_t *p_intf )
+{
+    if( --p_intf->p_sys->i_ss_count == 0 )
+    {
+        /* Save screen saver informations */
+        XGetScreenSaver( p_intf->p_sys->p_display, &p_intf->p_sys->i_ss_timeout,
+                         &p_intf->p_sys->i_ss_interval, &p_intf->p_sys->i_ss_blanking,
+                         &p_intf->p_sys->i_ss_exposure );
+
+        /* Disable screen saver */
+        intf_Msg("Disabling screen saver\n");
+        XSetScreenSaver( p_intf->p_sys->p_display, 0,
+                         p_intf->p_sys->i_ss_interval, p_intf->p_sys->i_ss_blanking,
+                         p_intf->p_sys->i_ss_exposure );
+    }
+}
+
+/*****************************************************************************
+ * X11TogglePointer: hide or show the mouse pointer
+ *****************************************************************************
+ * This function hides the X pointer if it is visible by putting it at
+ * coordinates (32,32) and setting the pointer sprite to a blank one. To
+ * show it again, we disable the sprite and restore the original coordinates.
+ *****************************************************************************/
+void X11TogglePointer( intf_thread_t *p_intf )
+{
+    static Cursor cursor;
+    static boolean_t b_cursor = 0;
+
+    if( p_intf->p_sys->b_mouse )
+    {
+        p_intf->p_sys->b_mouse = 0;
+
+        if( !b_cursor )
+        {
+            XColor color;
+            Pixmap blank = XCreatePixmap( p_intf->p_sys->p_display,
+                               DefaultRootWindow(p_intf->p_sys->p_display),
+                               1, 1, 1 );
+
+            XParseColor( p_intf->p_sys->p_display,
+                         XCreateColormap( p_intf->p_sys->p_display,
+                                          DefaultRootWindow(
+                                                  p_intf->p_sys->p_display ),
+                                          DefaultVisual(
+                                                  p_intf->p_sys->p_display,
+                                                  p_intf->p_sys->i_screen ),
+                                          AllocNone ),
+                         "black", &color );
+
+            cursor = XCreatePixmapCursor( p_intf->p_sys->p_display,
+                           blank, blank, &color, &color, 1, 1 );
+
+            b_cursor = 1;
+        }
+        XDefineCursor( p_intf->p_sys->p_display,
+                       p_intf->p_sys->window, cursor );
+    }
+    else
+    {
+        p_intf->p_sys->b_mouse = 1;
+
+        XUndefineCursor( p_intf->p_sys->p_display, p_intf->p_sys->window );
+    }
+}
diff --git a/plugins/x11/vout_x11.c b/plugins/x11/vout_x11.c
new file mode 100644 (file)
index 0000000..14be4a5
--- /dev/null
@@ -0,0 +1,694 @@
+/*****************************************************************************
+ * vout_x11.c: X11 video output display method
+ *****************************************************************************
+ * Copyright (C) 1998, 1999, 2000 VideoLAN
+ *
+ * Authors:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include "defs.h"
+
+#include <errno.h>                                                 /* ENOMEM */
+#include <stdlib.h>                                                /* free() */
+#include <string.h>                                            /* strerror() */
+
+#ifdef SYS_BSD
+#include <sys/types.h>                                     /* typedef ushort */
+#endif
+
+#include <sys/shm.h>                                   /* shmget(), shmctl() */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+
+#include "config.h"
+#include "common.h"
+#include "threads.h"
+#include "mtime.h"
+#include "plugins.h"
+
+#include "video.h"
+#include "video_output.h"
+
+#include "intf_msg.h"
+
+/*****************************************************************************
+ * vout_sys_t: video output X11 method descriptor
+ *****************************************************************************
+ * This structure is part of the video output thread descriptor.
+ * It describes the X11 specific properties of an output thread. X11 video
+ * output is performed through regular resizable windows. Windows can be
+ * dynamically resized to adapt to the size of the streams.
+ *****************************************************************************/
+typedef struct vout_sys_s
+{
+    /* User settings */
+    boolean_t           b_shm;               /* shared memory extension flag */
+
+    /* Internal settings and properties */
+    Display *           p_display;                        /* display pointer */
+    Visual *            p_visual;                          /* visual pointer */
+    int                 i_screen;                           /* screen number */
+    Window              root_window;                          /* root window */
+    Window              window;                   /* window instance handler */
+    GC                  gc;              /* graphic context instance handler */
+    Colormap            colormap;               /* colormap used (8bpp only) */
+
+    /* Display buffers and shared memory information */
+    XImage *            p_ximage[2];                       /* XImage pointer */
+    XShmSegmentInfo     shm_info[2];       /* shared memory zone information */
+} vout_sys_t;
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int  X11OpenDisplay      ( vout_thread_t *p_vout, char *psz_display, Window root_window, void *p_data );
+static void X11CloseDisplay     ( vout_thread_t *p_vout );
+static int  X11CreateWindow     ( vout_thread_t *p_vout );
+static void X11DestroyWindow    ( vout_thread_t *p_vout );
+static int  X11CreateImage      ( vout_thread_t *p_vout, XImage **pp_ximage );
+static void X11DestroyImage     ( XImage *p_ximage );
+static int  X11CreateShmImage   ( vout_thread_t *p_vout, XImage **pp_ximage,
+                                  XShmSegmentInfo *p_shm_info );
+static void X11DestroyShmImage  ( vout_thread_t *p_vout, XImage *p_ximage,
+                                  XShmSegmentInfo *p_shm_info );
+static void X11SetPalette       ( p_vout_thread_t p_vout,
+                                  u16 *red, u16 *green, u16 *blue, u16 *transp );
+
+/*****************************************************************************
+ * vout_SysCreate: allocate X11 video thread output method
+ *****************************************************************************
+ * This function allocate and initialize a X11 vout method. It uses some of the
+ * vout properties to choose the window size, and change them according to the
+ * actual properties of the display.
+ *****************************************************************************/
+int vout_SysCreate( vout_thread_t *p_vout, char *psz_display,
+                    int i_root_window, void *p_data )
+{
+    /* Allocate structure */
+    p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
+    if( p_vout->p_sys == NULL )
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM) );
+        return( 1 );
+    }
+
+    /* Open and initialize device. This function issues its own error messages.
+     * Since XLib is usually not thread-safe, we can't use the same display
+     * pointer than the interface or another thread. However, the root window
+     * id is still valid. */
+    if( X11OpenDisplay( p_vout, psz_display, i_root_window, p_data ) )
+    {
+        intf_ErrMsg("error: can't initialize X11 display\n" );
+        free( p_vout->p_sys );
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysInit: initialize X11 video thread output method
+ *****************************************************************************
+ * This function create the XImages needed by the output thread. It is called
+ * at the beginning of the thread, but also each time the window is resized.
+ *****************************************************************************/
+int vout_SysInit( vout_thread_t *p_vout )
+{
+    int i_err;
+
+    /* Initialize palette changing procedure */
+    p_vout->p_set_palette       = X11SetPalette;
+
+    /* Create XImages using XShm extension - on failure, fall back to regular
+     * way (and destroy the first image if it was created successfully) */
+    if( p_vout->p_sys->b_shm )
+    {
+        /* Create first image */
+        i_err = X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[0],
+                                   &p_vout->p_sys->shm_info[0] );
+        if( !i_err )                         /* first image has been created */
+        {
+            /* Create second image */
+            if( X11CreateShmImage( p_vout, &p_vout->p_sys->p_ximage[1],
+                                   &p_vout->p_sys->shm_info[1] ) )
+            {                             /* error creating the second image */
+                X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0],
+                                    &p_vout->p_sys->shm_info[0] );
+                i_err = 1;
+            }
+        }
+        if( i_err )                                      /* an error occured */
+        {
+            intf_Msg("XShm video sextension desactivated\n" );
+            p_vout->p_sys->b_shm = 0;
+        }
+    }
+
+    /* Create XImages without XShm extension */
+    if( !p_vout->p_sys->b_shm )
+    {
+        if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[0] ) )
+        {
+            intf_ErrMsg("error: can't create images\n");
+            p_vout->p_sys->p_ximage[0] = NULL;
+            p_vout->p_sys->p_ximage[1] = NULL;
+            return( 1 );
+        }
+        if( X11CreateImage( p_vout, &p_vout->p_sys->p_ximage[1] ) )
+        {
+            intf_ErrMsg("error: can't create images\n");
+            X11DestroyImage( p_vout->p_sys->p_ximage[0] );
+            p_vout->p_sys->p_ximage[0] = NULL;
+            p_vout->p_sys->p_ximage[1] = NULL;
+            return( 1 );
+        }
+    }
+
+    /* Set bytes per line and initialize buffers */
+    p_vout->i_bytes_per_line = p_vout->p_sys->p_ximage[0]->bytes_per_line;
+    vout_SetBuffers( p_vout, p_vout->p_sys->p_ximage[ 0 ]->data,
+                     p_vout->p_sys->p_ximage[ 1 ]->data );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * vout_SysEnd: terminate X11 video thread output method
+ *****************************************************************************
+ * Destroy the X11 XImages created by vout_SysInit. It is called at the end of
+ * the thread, but also each time the window is resized.
+ *****************************************************************************/
+void vout_SysEnd( vout_thread_t *p_vout )
+{
+    if( p_vout->p_sys->b_shm )                             /* Shm XImages... */
+    {
+        X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[0],
+                            &p_vout->p_sys->shm_info[0] );
+        X11DestroyShmImage( p_vout, p_vout->p_sys->p_ximage[1],
+                            &p_vout->p_sys->shm_info[1] );
+    }
+    else                                          /* ...or regular XImages */
+    {
+        X11DestroyImage( p_vout->p_sys->p_ximage[0] );
+        X11DestroyImage( p_vout->p_sys->p_ximage[1] );
+    }
+}
+
+/*****************************************************************************
+ * vout_SysDestroy: destroy X11 video thread output method
+ *****************************************************************************
+ * Terminate an output method created by vout_CreateOutputMethod
+ *****************************************************************************/
+void vout_SysDestroy( vout_thread_t *p_vout )
+{
+    X11CloseDisplay( p_vout );
+    free( p_vout->p_sys );
+}
+
+/*****************************************************************************
+ * vout_SysManage: handle X11 events
+ *****************************************************************************
+ * This function should be called regularly by video output thread. It manages
+ * X11 events and allows window resizing. It returns a non null value on
+ * error.
+ *****************************************************************************/
+int vout_SysManage( vout_thread_t *p_vout )
+{
+    /*
+     * Color/Grayscale or gamma change: in 8bpp, just change the colormap
+     */
+    if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE) && (p_vout->i_screen_depth == 8) )
+    {
+        /* FIXME: clear flags ?? */
+    }
+
+    /*
+     * Size change
+     */
+    if( p_vout->i_changes & VOUT_SIZE_CHANGE )
+    {
+        intf_DbgMsg("resizing window\n");
+        p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
+
+        /* Resize window */
+        XResizeWindow( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                       p_vout->i_width, p_vout->i_height );
+
+        /* Destroy XImages to change their size */
+        vout_SysEnd( p_vout );
+
+        /* Recreate XImages. If SysInit failed, the thread can't go on. */
+        if( vout_SysInit( p_vout ) )
+        {
+            intf_ErrMsg("error: can't resize display\n");
+            return( 1 );
+        }
+
+        /* Tell the video output thread that it will need to rebuild YUV
+         * tables. This is needed since conversion buffer size may have changed */
+        p_vout->i_changes |= VOUT_YUV_CHANGE;
+        intf_Msg("Video display resized (%dx%d)\n", p_vout->i_width, p_vout->i_height);
+    }
+
+    return 0;
+}
+
+/*****************************************************************************
+ * vout_SysDisplay: displays previously rendered output
+ *****************************************************************************
+ * This function send the currently rendered image to X11 server, wait until
+ * it is displayed and switch the two rendering buffer, preparing next frame.
+ *****************************************************************************/
+void vout_SysDisplay( vout_thread_t *p_vout )
+{
+    if( p_vout->p_sys->b_shm)                                /* XShm is used */
+    {
+        /* Display rendered image using shared memory extension */
+        XShmPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
+                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ],
+                     0, 0, 0, 0,
+                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width,
+                     p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height, True);
+
+        /* Send the order to the X server */
+        XFlush(p_vout->p_sys->p_display);
+    }
+    else                                /* regular X11 capabilities are used */
+    {
+        XPutImage(p_vout->p_sys->p_display, p_vout->p_sys->window, p_vout->p_sys->gc,
+                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ],
+                  0, 0, 0, 0,
+                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->width,
+                  p_vout->p_sys->p_ximage[ p_vout->i_buffer_index ]->height);
+
+        /* Send the order to the X server */
+        XFlush(p_vout->p_sys->p_display);
+    }
+}
+
+/* following functions are local */
+
+/*****************************************************************************
+ * X11OpenDisplay: open and initialize X11 device
+ *****************************************************************************
+ * Create a window according to video output given size, and set other
+ * properties according to the display properties.
+ *****************************************************************************/
+static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root_window, void *p_data )
+{
+    XPixmapFormatValues *       p_xpixmap_format;          /* pixmap formats */
+    XVisualInfo *               p_xvisual;           /* visuals informations */
+    XVisualInfo                 xvisual_template;         /* visual template */
+    int                         i_count;                       /* array size */
+
+    /* Open display */
+    p_vout->p_sys->p_display = XOpenDisplay( psz_display );
+    if( p_vout->p_sys->p_display == NULL )
+    {
+        intf_ErrMsg("error: can't open display %s\n", psz_display );
+        return( 1 );
+    }
+
+    /* Initialize structure */
+    p_vout->p_sys->root_window  = root_window;
+    p_vout->p_sys->b_shm        = (XShmQueryExtension(p_vout->p_sys->p_display) == True);
+    p_vout->p_sys->i_screen     = DefaultScreen( p_vout->p_sys->p_display );
+    if( !p_vout->p_sys->b_shm )
+    {
+        intf_Msg("XShm video extension is not available\n");
+    }
+
+    /* Get screen depth */
+    p_vout->i_screen_depth = XDefaultDepth( p_vout->p_sys->p_display, p_vout->p_sys->i_screen );
+    switch( p_vout->i_screen_depth )
+    {
+    case 8:
+        /*
+         * Screen depth is 8bpp. Use PseudoColor visual with private colormap.
+         */
+        xvisual_template.screen =   p_vout->p_sys->i_screen;
+        xvisual_template.class =    DirectColor;
+        p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask,
+                                    &xvisual_template, &i_count );
+        if( p_xvisual == NULL )
+        {
+            intf_ErrMsg("error: no PseudoColor visual available\n");
+            XCloseDisplay( p_vout->p_sys->p_display );
+            return( 1 );
+        }
+        p_vout->i_bytes_per_pixel = 1;
+
+        /* put the colormap in place */
+        p_vout->p_sys->colormap = *(Colormap *)p_data;
+        break;
+    case 15:
+    case 16:
+    case 24:
+    default:
+        /*
+         * Screen depth is higher than 8bpp. TrueColor visual is used.
+         */
+        xvisual_template.screen =   p_vout->p_sys->i_screen;
+        xvisual_template.class =    TrueColor;
+        p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask,
+                                    &xvisual_template, &i_count );
+        if( p_xvisual == NULL )
+        {
+            intf_ErrMsg("error: no TrueColor visual available\n");
+            XCloseDisplay( p_vout->p_sys->p_display );
+            return( 1 );
+        }
+        p_vout->i_red_mask =        p_xvisual->red_mask;
+        p_vout->i_green_mask =      p_xvisual->green_mask;
+        p_vout->i_blue_mask =       p_xvisual->blue_mask;
+
+        /* There is no difference yet between 3 and 4 Bpp. The only way to find
+         * the actual number of bytes per pixel is to list supported pixmap
+         * formats. */
+        p_xpixmap_format = XListPixmapFormats( p_vout->p_sys->p_display, &i_count );
+
+       /* FIXME: under XFree4.0, we can get some strange values. Check this */
+        p_vout->i_bytes_per_pixel = 0;
+        for( ; i_count--; p_xpixmap_format++ )
+        {
+            if( p_xpixmap_format->bits_per_pixel / 8 > p_vout->i_bytes_per_pixel )
+            {
+                p_vout->i_bytes_per_pixel = p_xpixmap_format->bits_per_pixel / 8;
+            }
+        }
+        break;
+    }
+    p_vout->p_sys->p_visual = p_xvisual->visual;
+    XFree( p_xvisual );
+
+    /* Create a window */
+    if( X11CreateWindow( p_vout ) )
+    {
+        intf_ErrMsg("error: can't open a window\n");
+        XCloseDisplay( p_vout->p_sys->p_display );
+        return( 1 );
+    }
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11CloseDisplay: close X11 device
+ *****************************************************************************
+ * Returns all resources allocated by X11OpenDisplay and restore the original
+ * state of the display.
+ *****************************************************************************/
+static void X11CloseDisplay( vout_thread_t *p_vout )
+{
+    /* Destroy colormap */
+    if( p_vout->i_screen_depth == 8 )
+    {
+        XFreeColormap( p_vout->p_sys->p_display, p_vout->p_sys->colormap );
+    }
+    
+    /* Destroy window */
+    X11DestroyWindow( p_vout );
+
+    /* FIXME: We should close the display here, but X returns an error. */
+    //XCloseDisplay( p_vout->p_sys->p_display );
+}
+
+/*****************************************************************************
+ * X11CreateWindow: create X11 vout window
+ *****************************************************************************
+ * The video output window will be created. Normally, this window is wether
+ * full screen or part of a parent window. Therefore, it does not need a
+ * title or other hints. Thery are still supplied in case the window would be
+ * spawned as a standalone one by the interface.
+ *****************************************************************************/
+static int X11CreateWindow( vout_thread_t *p_vout )
+{
+    XSetWindowAttributes    xwindow_attributes;         /* window attributes */
+    XGCValues               xgcvalues;      /* graphic context configuration */
+    XEvent                  xevent;                          /* first events */
+    boolean_t               b_expose;             /* 'expose' event received */
+    boolean_t               b_map_notify;     /* 'map_notify' event received */
+
+    /* Prepare window attributes */
+    xwindow_attributes.backing_store = Always;       /* save the hidden part */
+
+    /* Create the window and set hints */
+    p_vout->p_sys->window = XCreateSimpleWindow( p_vout->p_sys->p_display,
+                                         p_vout->p_sys->root_window,
+                                         0, 0,
+                                         p_vout->i_width, p_vout->i_height,
+                                         0, 0, 0);
+    XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                  ExposureMask | StructureNotifyMask );
+    XChangeWindowAttributes( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                             CWBackingStore, &xwindow_attributes);
+
+    /* Creation of a graphic context that doesn't generate a GraphicsExpose event
+       when using functions like XCopyArea */
+    xgcvalues.graphics_exposures = False;
+    p_vout->p_sys->gc =  XCreateGC( p_vout->p_sys->p_display, p_vout->p_sys->window,
+                                    GCGraphicsExposures, &xgcvalues);
+
+    /* Send orders to server, and wait until window is displayed - two events
+     * must be received: a MapNotify event, an Expose event allowing drawing in the
+     * window */
+    b_expose = 0;
+    b_map_notify = 0;
+    XMapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window);
+    do
+    {
+        XNextEvent( p_vout->p_sys->p_display, &xevent);
+        if( (xevent.type == Expose)
+            && (xevent.xexpose.window == p_vout->p_sys->window) )
+        {
+            b_expose = 1;
+        }
+        else if( (xevent.type == MapNotify)
+                 && (xevent.xmap.window == p_vout->p_sys->window) )
+        {
+            b_map_notify = 1;
+        }
+    }
+    while( !( b_expose && b_map_notify ) );
+    XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->window, 0 );
+
+    /* At this stage, the window is open, displayed, and ready to receive
+     * data */
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11DestroyWindow: destroy X11 window
+ *****************************************************************************
+ * Destroy an X11 window created by vout_CreateWindow
+ *****************************************************************************/
+static void X11DestroyWindow( vout_thread_t *p_vout )
+{
+    XUnmapWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
+    XFreeGC( p_vout->p_sys->p_display, p_vout->p_sys->gc );
+    XDestroyWindow( p_vout->p_sys->p_display, p_vout->p_sys->window );
+}
+
+/*****************************************************************************
+ * X11CreateImage: create an XImage
+ *****************************************************************************
+ * Create a simple XImage used as a buffer.
+ *****************************************************************************/
+static int X11CreateImage( vout_thread_t *p_vout, XImage **pp_ximage )
+{
+    byte_t *    pb_data;                          /* image data storage zone */
+    int         i_quantum;                     /* XImage quantum (see below) */
+
+    /* Allocate memory for image */
+    p_vout->i_bytes_per_line = p_vout->i_width * p_vout->i_bytes_per_pixel;
+    pb_data = (byte_t *) malloc( p_vout->i_bytes_per_line * p_vout->i_height );
+    if( !pb_data )                                                  /* error */
+    {
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
+        return( 1 );
+    }
+
+    /* Optimize the quantum of a scanline regarding its size - the quantum is
+       a diviser of the number of bits between the start of two scanlines. */
+    if( !(( p_vout->i_bytes_per_line ) % 32) )
+    {
+        i_quantum = 32;
+    }
+    else
+    {
+        if( !(( p_vout->i_bytes_per_line ) % 16) )
+        {
+            i_quantum = 16;
+        }
+        else
+        {
+            i_quantum = 8;
+        }
+    }
+
+    /* Create XImage */
+    *pp_ximage = XCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual,
+                               p_vout->i_screen_depth, ZPixmap, 0, pb_data,
+                               p_vout->i_width, p_vout->i_height, i_quantum, 0);
+    if(! *pp_ximage )                                               /* error */
+    {
+        intf_ErrMsg( "error: XCreateImage() failed\n" );
+        free( pb_data );
+        return( 1 );
+    }
+
+    return 0;
+}
+
+/*****************************************************************************
+ * X11CreateShmImage: create an XImage using shared memory extension
+ *****************************************************************************
+ * Prepare an XImage for DisplayX11ShmImage function.
+ * The order of the operations respects the recommandations of the mit-shm
+ * document by J.Corbet and K.Packard. Most of the parameters were copied from
+ * there.
+ *****************************************************************************/
+static int X11CreateShmImage( vout_thread_t *p_vout, XImage **pp_ximage,
+                              XShmSegmentInfo *p_shm_info)
+{
+    /* Create XImage */
+    *pp_ximage = XShmCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual,
+                                  p_vout->i_screen_depth, ZPixmap, 0,
+                                  p_shm_info, p_vout->i_width, p_vout->i_height );
+    if(! *pp_ximage )                                               /* error */
+    {
+        intf_ErrMsg("error: XShmCreateImage() failed\n");
+        return( 1 );
+    }
+
+    /* Allocate shared memory segment - 0777 set the access permission
+     * rights (like umask), they are not yet supported by X servers */
+    p_shm_info->shmid = shmget( IPC_PRIVATE,
+                                (*pp_ximage)->bytes_per_line * (*pp_ximage)->height,
+                                IPC_CREAT | 0777);
+    if( p_shm_info->shmid < 0)                                      /* error */
+    {
+        intf_ErrMsg("error: can't allocate shared image data (%s)\n",
+                    strerror(errno));
+        XDestroyImage( *pp_ximage );
+        return( 1 );
+    }
+
+    /* Attach shared memory segment to process (read/write) */
+    p_shm_info->shmaddr = (*pp_ximage)->data = shmat(p_shm_info->shmid, 0, 0);
+    if(! p_shm_info->shmaddr )
+    {                                                               /* error */
+        intf_ErrMsg("error: can't attach shared memory (%s)\n",
+                    strerror(errno));
+        shmctl( p_shm_info->shmid, IPC_RMID, 0 );      /* free shared memory */
+        XDestroyImage( *pp_ximage );
+        return( 1 );
+    }
+
+    /* Mark the shm segment to be removed when there will be no more
+     * attachements, so it is automatic on process exit or after shmdt */
+    shmctl( p_shm_info->shmid, IPC_RMID, 0 );
+
+    /* Attach shared memory segment to X server (read only) */
+    p_shm_info->readOnly = True;
+    if( XShmAttach( p_vout->p_sys->p_display, p_shm_info ) == False )    /* error */
+    {
+        intf_ErrMsg("error: can't attach shared memory to X11 server\n");
+        shmdt( p_shm_info->shmaddr );     /* detach shared memory from process
+                                           * and automatic free                */
+        XDestroyImage( *pp_ximage );
+        return( 1 );
+    }
+
+    /* Send image to X server. This instruction is required, since having
+     * built a Shm XImage and not using it causes an error on XCloseDisplay */
+    XFlush( p_vout->p_sys->p_display );
+    return( 0 );
+}
+
+/*****************************************************************************
+ * X11DestroyImage: destroy an XImage
+ *****************************************************************************
+ * Destroy XImage AND associated data. If pointer is NULL, the image won't be
+ * destroyed (see vout_ManageOutputMethod())
+ *****************************************************************************/
+static void X11DestroyImage( XImage *p_ximage )
+{
+    if( p_ximage != NULL )
+    {
+        XDestroyImage( p_ximage );                     /* no free() required */
+    }
+}
+
+/*****************************************************************************
+ * X11DestroyShmImage
+ *****************************************************************************
+ * Destroy XImage AND associated data. Detach shared memory segment from
+ * server and process, then free it. If pointer is NULL, the image won't be
+ * destroyed (see vout_ManageOutputMethod())
+ *****************************************************************************/
+static void X11DestroyShmImage( vout_thread_t *p_vout, XImage *p_ximage,
+                                XShmSegmentInfo *p_shm_info )
+{
+    /* If pointer is NULL, do nothing */
+    if( p_ximage == NULL )
+    {
+        return;
+    }
+
+    XShmDetach( p_vout->p_sys->p_display, p_shm_info );     /* detach from server */
+    XDestroyImage( p_ximage );
+    if( shmdt( p_shm_info->shmaddr ) )  /* detach shared memory from process */
+    {                                   /* also automatic freeing...         */
+        intf_ErrMsg( "error: can't detach shared memory (%s)\n",
+                     strerror(errno) );
+    }
+}
+
+/*****************************************************************************
+ * X11SetPalette: sets an 8 bpp palette
+ *****************************************************************************
+ * This function sets the palette given as an argument. It does not return
+ * anything, but could later send information on which colors it was unable
+ * to set.
+ *****************************************************************************/
+static void X11SetPalette       ( p_vout_thread_t p_vout,
+                                  u16 *red, u16 *green, u16 *blue, u16 *transp )
+{
+    int i;
+    XColor color[255];
+
+    intf_DbgMsg( "Palette change called\n" );
+
+    /* allocate palette */
+    for( i = 0; i < 255; i++ )
+    {
+        /* kludge: colors are indexed reversely because color 255 seems
+         * to be reserved for black even if we try to set it to white */
+        color[i].pixel = 255-i;
+        color[i].pad = 0;
+        color[i].flags = DoRed|DoGreen|DoBlue;
+        color[i].red = red[255-i];
+        color[i].blue = blue[255-i];
+        color[i].green = green[255-i];
+    }
+
+    XStoreColors( p_vout->p_sys->p_display, p_vout->p_sys->colormap, color, 256 );
+}
+
index b616989bbd3fa6cdada1906a128d3cb465045b6c..69813ca39bcf1691d8dccf8c54554d06ff150730 100644 (file)
@@ -95,9 +95,9 @@ aout_thread_t *aout_CreateThread( int *pi_status )
     /* Request an interface plugin */
     psz_method = main_GetPszVariable( AOUT_METHOD_VAR, AOUT_DEFAULT_METHOD );
     
-    if( RequestPlugin( &p_aout->aout_plugin, "aout", psz_method ) )
+    if( RequestPlugin( &p_aout->aout_plugin, psz_method ) )
     {
-        intf_ErrMsg( "error: could not open audio plugin aout_%s.so\n", psz_method );
+        intf_ErrMsg( "error: could not open audio plugin %s.so\n", psz_method );
         free( p_aout );
         return( NULL );
     }
index b62abe583096accdd0c4850cb61ac9fc948a2d8d..a6ef8ba435ce3a70493ed6d6ab1565190d7eadf6 100644 (file)
@@ -103,9 +103,9 @@ intf_thread_t* intf_Create( void )
     /* Request an interface plugin */
     psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
 
-    if( RequestPlugin( &p_intf->intf_plugin, "intf", psz_method ) < 0 )
+    if( RequestPlugin( &p_intf->intf_plugin, psz_method ) < 0 )
     {
-        intf_ErrMsg( "error: could not open interface plugin intf_%s.so\n", psz_method );
+        intf_ErrMsg( "error: could not open interface plugin %s.so\n", psz_method );
         free( p_intf );
         return( NULL );
     }
index 6f61d777cfc1443e64e4ea9b4c0d98f79306fee9..105adf4b59b7b41adde4dd13ab265a6ecc66e049 100644 (file)
 
 #include "plugins.h"
 
-#define PLUGIN_PATH_COUNT 5
+#define PLUGIN_PATH_COUNT 3
 
-int RequestPlugin ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name )
+int RequestPlugin ( plugin_id_t * p_plugin, char * psz_name )
 {
     int i_count, i_length;
     char * psz_plugin;
     char * psz_plugin_path[ PLUGIN_PATH_COUNT ] =
     {
         ".",
-        "plugins/aout", "plugins/vout", "plugins/intf", /* these ones should disappear */
+        "lib", /* this one should disappear */
         PLUGIN_PATH
     };
 
-    i_length = strlen( psz_mask ) + strlen( psz_name );
+    i_length = strlen( psz_name );
 
     for ( i_count = 0 ; i_count < PLUGIN_PATH_COUNT ; i_count++ )
     {
@@ -61,17 +61,17 @@ int RequestPlugin ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name )
         char * psz_program_path;
         
         psz_program_path = beos_GetProgramPath();
-        psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + strlen(psz_program_path) + i_length + 6 );
-        sprintf( psz_plugin, "%s/%s/%s_%s.so", psz_program_path, psz_plugin_path[i_count], psz_mask, psz_name );        
+        psz_plugin = malloc( strlen(psz_plugin_path[i_count]) +
+                             strlen(psz_program_path) + i_length + 5 );
+        sprintf( psz_plugin, "%s/%s/%s.so", psz_program_path,
+                 psz_plugin_path[i_count], psz_name );        
+
+        *p_plugin = load_add_on( psz_plugin );
 #else
-        psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 6 );
-        sprintf( psz_plugin, "%s/%s_%s.so", psz_plugin_path[i_count], psz_mask, psz_name );
-#endif
+        psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 5 );
+        sprintf( psz_plugin, "%s/%s.so", psz_plugin_path[i_count], psz_name );
 
-#if defined(HAVE_DLFCN_H)
         *p_plugin = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
-#elif defined(HAVE_IMAGE_H)
-        *p_plugin = load_add_on( psz_plugin );
 #endif
 
         free( psz_plugin );
index 8a2a650b6fa24c234ac5875526366a4a32085313..2514f4d7f465e304909e81573d9587c12792d27d 100644 (file)
@@ -107,9 +107,9 @@ vout_thread_t * vout_CreateThread   ( char *psz_display, int i_root_window,
     /* Request an interface plugin */
     psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
 
-    if( RequestPlugin( &p_vout->vout_plugin, "vout", psz_method ) < 0 )
+    if( RequestPlugin( &p_vout->vout_plugin, psz_method ) < 0 )
     {
-        intf_ErrMsg( "error: could not open video plugin vout_%s.so\n", psz_method );
+        intf_ErrMsg( "error: could not open video plugin %s.so\n", psz_method );
         free( p_vout );
         return( NULL );
     }
index 7e6f7822207d1e399c926a1a3ee350aa21b82efa..2c3bc260427da5d22119db66316e960844707708 100644 (file)
@@ -73,6 +73,8 @@
 #define V_RED_COEF      ((int)(1.596 * (1<<SHIFT) / 1.164))
 #define V_GREEN_COEF    ((int)(-0.813 * (1<<SHIFT) / 1.164))
 
+//#define NODITHER
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -1093,6 +1095,17 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
     int *       p_offset_start;                        /* offset array start */
     int *       p_offset;                            /* offset array pointer */
 
+#ifdef NODITHER
+    int dither10[4] = {  0x7,  0x8,  0x7,  0x8 };
+    int dither11[4] = {  0x8,  0x7,  0x8,  0x7 };
+    int dither12[4] = {  0x7,  0x8,  0x7,  0x8 };
+    int dither13[4] = {  0x8,  0x7,  0x8,  0x7 };
+
+    int dither20[4] = {  0xf, 0x10,  0xf, 0x10 };
+    int dither21[4] = { 0x10,  0xf, 0x10,  0xf };
+    int dither22[4] = {  0xf, 0x10,  0xf, 0x10 };
+    int dither23[4] = { 0x10,  0xf, 0x10,  0xf };
+#else
     int dither10[4] = {  0x0,  0x8,  0x2,  0xa };
     int dither11[4] = {  0xc,  0x4,  0xe,  0x6 };
     int dither12[4] = {  0x3,  0xb,  0x1,  0x9 };
@@ -1102,17 +1115,19 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
     int dither21[4] = { 0x18,  0x8, 0x1c,  0xc };
     int dither22[4] = {  0x6, 0x16,  0x2, 0x12 };
     int dither23[4] = { 0x1e,  0xe, 0x1a,  0xa };
-
-    /* other matrices that can be interesting, either for debugging or for effects */
-#if 0
-    int dither[4][4] = { { 0, 8, 2, 10 }, { 12, 4, 14, 16 }, { 3, 11, 1, 9}, {15, 7, 13, 5} };
-    int dither[4][4] = { { 7, 8, 0, 15 }, { 0, 15, 8, 7 }, { 7, 0, 15, 8 }, { 15, 7, 8, 0 } };
-    int dither[4][4] = { { 0, 15, 0, 15 }, { 15, 0, 15, 0 }, { 0, 15, 0, 15 }, { 15, 0, 15, 0 } };
-    int dither[4][4] = { { 15, 15, 0, 0 }, { 15, 15, 0, 0 }, { 0, 0, 15, 15 }, { 0, 0, 15, 15 } };
-    int dither[4][4] = { { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 } };
-    int dither[4][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
 #endif
 
+    /* some other matrices that can be interesting, either for debugging
+     *  or for effects :
+     *  
+     * { { 0, 8, 2, 10 }, { 12, 4, 14, 16 }, { 3, 11, 1, 9}, {15, 7, 13, 5} }
+     * { { 7, 8, 0, 15 }, { 0, 15, 8, 7 }, { 7, 0, 15, 8 }, { 15, 7, 8, 0 } }
+     * { { 0, 15, 0, 15 }, { 15, 0, 15, 0 }, { 0, 15, 0, 15 }, { 15, 0, 15, 0 } }
+     * { { 15, 15, 0, 0 }, { 15, 15, 0, 0 }, { 0, 0, 15, 15 }, { 0, 0, 15, 15 } }
+     * { { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 } }
+     * { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } }
+     */
+
     /*
      * Initialize some values  - i_pic_line_width will store the line skip
      */
index b7fe384f283e9258028a3f9180f7de06eea10716..36092648fee833acc30a2d0dddcdfda9ba73940b 100644 (file)
--- a/vlc.spec
+++ b/vlc.spec
@@ -1,10 +1,10 @@
 Name: vlc
-Version: 0.1.99c
+Version: 0.1.99d
 Release: 1
 Copyright: GPL
 Url: http://www.videolan.org/
 Group: X11/Applications/Graphics
-Source0: http://www.videolan.org/packages/vlc-0.1.99c.tar.gz
+Source0: http://www.videolan.org/packages/0.1.99c/vlc-0.1.99c.tar.gz
 Packager: Eric Doutreleau <Eric.doutreleau@int-evry.fr>
 
 Buildroot: /tmp/vlc-build
@@ -33,10 +33,10 @@ mkdir -p $RPM_BUILD_ROOT/usr/bin
 make install prefix=$RPM_BUILD_ROOT/usr
 
 %files
-/usr/bin/vlc
-/usr/share/videolan/vlc
-/usr/lib/videolan
-%doc AUTHORS COPYING INSTALL NEWS README doc
+%attr(-, root, root) /usr/bin/vlc
+%attr(-, root, root) /usr/share/videolan/vlc
+%attr(-, root, root) /usr/lib/videolan
+%attr(-, root, root) %doc AUTHORS COPYING INSTALL NEWS README doc
 %clean
 rm -rf $RPM_BUILD_ROOT