mirror of
https://github.com/videolan/vlc.git
synced 2024-11-29 04:45:36 +08:00
. nouveaux plugins - ne fonctionnent pas encore tous
This commit is contained in:
parent
1b79957ceb
commit
3cbfc06dc3
30
ChangeLog
30
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
|
Sun Jun 18 18:54:48 CEST 2000
|
||||||
0.1.99c :
|
0.1.99c :
|
||||||
|
|
||||||
* fixed Makefile.in for debug version
|
* fixed Makefile.in for debug version
|
||||||
* caught Delete Window event in Gnome and X11 modes
|
* caught Delete Window event in Gnome and X11 modes
|
||||||
* fixed manpage
|
* fixed manpage
|
||||||
* GGI output now works
|
* GGI output now works
|
||||||
* fixed a segfault on exit for the Gnome plugin
|
* fixed a segfault on exit for the Gnome plugin
|
||||||
* fixed compile problems for BeOS
|
* fixed compile problems for BeOS
|
||||||
* sound support almost works under BeOS
|
* sound support almost works under BeOS
|
||||||
* fixed a warning in ac3_exponent.c
|
* fixed a warning in ac3_exponent.c
|
||||||
* automatic support for .rpm and .deb building
|
* automatic support for .rpm and .deb building
|
||||||
|
|
||||||
Sat Jun 17 03:35:02 CEST 2000
|
Sat Jun 17 03:35:02 CEST 2000
|
||||||
0.1.99b :
|
0.1.99b :
|
||||||
|
|
||||||
* fixed a bug preventing to quit when run with no arguments
|
* fixed a bug preventing to quit when run with no arguments
|
||||||
* new VLAN changing code
|
* new VLAN changing code
|
||||||
* created the ChangeLog file :)
|
* created the ChangeLog file :)
|
||||||
|
|
||||||
|
37
INSTALL
37
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
|
||||||
|
|
140
Makefile.in
140
Makefile.in
@ -13,10 +13,7 @@
|
|||||||
DEBUG=0
|
DEBUG=0
|
||||||
|
|
||||||
SYS=@SYS@
|
SYS=@SYS@
|
||||||
ARCH=@ARCH@
|
PLUGINS=@PLUGINS@
|
||||||
AOUT=@AOUT@
|
|
||||||
VOUT=@VOUT@
|
|
||||||
INTF=@VOUT@
|
|
||||||
SNAPSHOTDIR=vlc-@VLC_VERSION@
|
SNAPSHOTDIR=vlc-@VLC_VERSION@
|
||||||
INSTALL=@INSTALL@
|
INSTALL=@INSTALL@
|
||||||
prefix=@prefix@
|
prefix=@prefix@
|
||||||
@ -249,12 +246,44 @@ endif
|
|||||||
#
|
#
|
||||||
# Plugins
|
# Plugins
|
||||||
#
|
#
|
||||||
intf_plugin = $(INTF:%=plugins/intf/intf_%.so)
|
PLUGINS := $(PLUGINS:%=lib/%.so)
|
||||||
aout_plugin = $(AOUT:%=plugins/aout/aout_%.so)
|
|
||||||
vout_plugin = $(VOUT:%=plugins/vout/vout_%.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
|
# Other lists of files
|
||||||
#
|
#
|
||||||
@ -280,7 +309,7 @@ clean:
|
|||||||
rm -f $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ)
|
rm -f $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ)
|
||||||
|
|
||||||
distclean: clean
|
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 Makefile include/defs.h include/config.h
|
||||||
rm -f config.status config.cache config.log
|
rm -f config.status config.cache config.log
|
||||||
rm -f vlc gmon.out core build-stamp
|
rm -f vlc gmon.out core build-stamp
|
||||||
@ -290,9 +319,9 @@ install:
|
|||||||
$(INSTALL) vlc $(prefix)/bin
|
$(INSTALL) vlc $(prefix)/bin
|
||||||
mkdir -p $(prefix)/lib/videolan/vlc
|
mkdir -p $(prefix)/lib/videolan/vlc
|
||||||
mkdir -p $(prefix)/share/videolan/vlc
|
mkdir -p $(prefix)/share/videolan/vlc
|
||||||
$(INSTALL) $(PLUGIN_OBJ) $(prefix)/lib/videolan/vlc
|
$(INSTALL) -m 644 $(PLUGINS) $(prefix)/lib/videolan/vlc
|
||||||
$(INSTALL) share/*.psf $(prefix)/share/videolan/vlc
|
$(INSTALL) -m 644 share/*.psf $(prefix)/share/videolan/vlc
|
||||||
$(INSTALL) share/*.png $(prefix)/share/videolan/vlc
|
$(INSTALL) -m 644 share/*.png $(prefix)/share/videolan/vlc
|
||||||
|
|
||||||
show:
|
show:
|
||||||
@echo "Command line for C objects:"
|
@echo "Command line for C objects:"
|
||||||
@ -316,12 +345,6 @@ snapshot:
|
|||||||
mv /tmp/${SNAPSHOTDIR}.tar.gz ..
|
mv /tmp/${SNAPSHOTDIR}.tar.gz ..
|
||||||
@echo "Sources are in ../${SNAPSHOTDIR}.tar.gz"
|
@echo "Sources are in ../${SNAPSHOTDIR}.tar.gz"
|
||||||
|
|
||||||
deb:
|
|
||||||
dpkg-buildpackage -rfakeroot -us -uc
|
|
||||||
|
|
||||||
rpm:
|
|
||||||
rpm -ba vlc.spec
|
|
||||||
|
|
||||||
FORCE:
|
FORCE:
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -336,7 +359,7 @@ else
|
|||||||
$(CC) $(CCFLAGS) $(LCFLAGS) $(CFLAGS) --export-dynamic -rdynamic -o $@ $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ)
|
$(CC) $(CCFLAGS) $(LCFLAGS) $(CFLAGS) --export-dynamic -rdynamic -o $@ $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
plugins: $(PLUGIN_OBJ)
|
plugins: $(PLUGINS)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Generic rules (see below)
|
# Generic rules (see below)
|
||||||
@ -359,57 +382,56 @@ $(ASM_OBJ): %.o: %.S
|
|||||||
#$(PLUGIN_OBJ): %.so: Makefile.dep
|
#$(PLUGIN_OBJ): %.so: Makefile.dep
|
||||||
#$(PLUGIN_OBJ): %.so: .dep/%.d
|
#$(PLUGIN_OBJ): %.so: .dep/%.d
|
||||||
|
|
||||||
# audio plugins
|
#$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
|
||||||
plugins/aout/aout_dummy.so plugins/aout/aout_dsp.so: %.so: %.c
|
|
||||||
ifeq ($(SYS),beos)
|
lib/beos.so: $(PLUGIN_BEOS)
|
||||||
$(CC) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
|
ld -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
|
||||||
else
|
$(PLUGIN_BEOS): %.o: %.c
|
||||||
$(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $<
|
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
endif
|
|
||||||
|
|
||||||
plugins/aout/aout_esd.so: %.so: %.c
|
lib/esd.so: $(PLUGIN_ESD)
|
||||||
ifneq (,$(findstring bsd,$(SYS)))
|
ifneq (,$(findstring bsd,$(SYS)))
|
||||||
$(CC) $(CCFLAGS) $(CFLAGS) -lesd -shared -o $@ $<
|
ld -shared -lesd -o $@ $^
|
||||||
else
|
else
|
||||||
$(CC) $(CCFLAGS) $(CFLAGS) -laudiofile -lesd -shared -o $@ $<
|
ld -shared -laudiofile -lesd -o $@ $^
|
||||||
endif
|
endif
|
||||||
|
$(PLUGIN_ESD): %.o: %.c
|
||||||
|
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
plugins/aout/aout_beos.so: %.so: %.cpp
|
lib/dummy.so: $(PLUGIN_DUMMY)
|
||||||
$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
|
ld -shared -o $@ $^
|
||||||
|
$(PLUGIN_DUMMY): %.o: %.c
|
||||||
# video plugins
|
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
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
|
lib/fb.so: $(PLUGIN_FB)
|
||||||
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
|
ld -shared -o $@ $^
|
||||||
|
$(PLUGIN_FB): %.o: %.c
|
||||||
|
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
plugins/intf/intf_mga.so plugins/vout/vout_mga.so: %.so: %.c
|
lib/x11.so: $(PLUGIN_X11)
|
||||||
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
|
ld -shared -L/usr/X11R6/lib -lX11 -lXext -o $@ $^
|
||||||
|
$(PLUGIN_X11): %.o: %.c
|
||||||
|
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
plugins/intf/intf_gnome.so: %.so: %.c
|
lib/mga.so: $(PLUGIN_MGA)
|
||||||
$(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
|
ld -shared -L/usr/X11R6/lib -lX11 -lXext -o $@ $^
|
||||||
|
$(PLUGIN_MGA): %.o: %.c
|
||||||
|
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
plugins/vout/vout_gnome.so: %.so: %.c
|
lib/gnome.so: $(PLUGIN_GNOME)
|
||||||
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
|
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_glide.so plugins/vout/vout_glide.so: %.so: %.c
|
lib/glide.so: $(PLUGIN_GLIDE)
|
||||||
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/include/glide -lglide2x -shared -o $@ $<
|
ld -shared -lglide2x -o $@ $^
|
||||||
|
$(PLUGIN_GLIDE): %.o: %.c
|
||||||
|
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/include/glide -c -o $@ $<
|
||||||
|
|
||||||
plugins/intf/intf_ggi.so plugins/vout/vout_ggi.so: %.so: %.c
|
lib/ggi.so: $(PLUGIN_GGI)
|
||||||
$(CC) $(CCFLAGS) $(CFLAGS) -lggi -shared -o $@ $<
|
ld -shared -lggi -o $@ $^
|
||||||
|
$(PLUGIN_GGI): %.o: %.c
|
||||||
plugins/intf/intf_beos.so: %.so: %.cpp
|
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
|
|
||||||
|
|
||||||
plugins/vout/vout_beos.so: %.so: %.cpp
|
|
||||||
$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Note on generic rules and dependancies
|
# Note on generic rules and dependancies
|
||||||
|
62
README
62
README
@ -1,44 +1,48 @@
|
|||||||
|
README for vlc, the VideoLAN Client
|
||||||
README for vlc, the VideoLAN Client
|
|
||||||
|
|
||||||
|
|
||||||
|
Introduction
|
||||||
... Introduction
|
============
|
||||||
|
|
||||||
[ nothing appropriate yet ]
|
[ 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
|
|
||||||
|
|
||||||
See `./configure --help' for more information.
|
|
||||||
|
|
||||||
Then, run `make'.
|
|
||||||
|
|
||||||
|
|
||||||
... Running VideoLAN
|
Troubleshooting
|
||||||
|
===============
|
||||||
|
|
||||||
|
A mailing-list has been set up for support and discussion about the
|
||||||
|
vlc. Its address is :
|
||||||
|
|
||||||
|
<vlc@videolan.org>
|
||||||
|
|
||||||
|
To subscribe, send a mail to <listar@videolan.org> with the following
|
||||||
|
words in the mail body :
|
||||||
|
|
||||||
|
subscribe vlc
|
||||||
|
|
||||||
|
To unsubscribe, do the same with the words :
|
||||||
|
|
||||||
|
unsubscribe vlc
|
||||||
|
|
||||||
|
|
||||||
|
When reporting bugs, try to be as precise as possible (which OS, which
|
||||||
|
distribution, what plugins you were trying, and so on).
|
||||||
|
|
||||||
|
|
||||||
|
Resources
|
||||||
|
=========
|
||||||
|
|
||||||
[ nothing appropriate yet ]
|
[ nothing appropriate yet ]
|
||||||
|
|
||||||
|
|
||||||
|
The team
|
||||||
... Troubleshooting
|
========
|
||||||
|
|
||||||
[ nothing appropriate yet ]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
... Resources
|
|
||||||
|
|
||||||
[ nothing appropriate yet ]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
... The team
|
|
||||||
|
|
||||||
The following teachers were involved in the VideoLAN project :
|
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>
|
Antoine Brenner <brenner@via.ecp.fr>
|
||||||
Régis Duchesne <regis@via.ecp.fr>
|
Régis Duchesne <regis@via.ecp.fr>
|
||||||
Alexandre Francois <francois@via.ecp.fr>
|
Alexandre Francois <francois@via.ecp.fr>
|
||||||
|
Christian Gross <gross@via.ecp.fr>
|
||||||
Hugo Haas <hugo@via.ecp.fr>
|
Hugo Haas <hugo@via.ecp.fr>
|
||||||
Mikael Journo <mj32@cornell.edu>
|
Mikael Journo <mj32@cornell.edu>
|
||||||
Michel Lespinasse <walken@wrs.com>
|
Michel Lespinasse <walken@wrs.com>
|
||||||
@ -61,7 +66,6 @@ The following students were members of the VideoLAN team :
|
|||||||
|
|
||||||
Olivier Baxa <oli@via.ecp.fr>
|
Olivier Baxa <oli@via.ecp.fr>
|
||||||
Patrice Bazerque <patrice.bazerque@via.ecp.fr>
|
Patrice Bazerque <patrice.bazerque@via.ecp.fr>
|
||||||
Etienne Bernard <eb@via.ecp.fr>
|
|
||||||
Arnaud Bienvenu <arnaud.bienvenu@via.ecp.fr>
|
Arnaud Bienvenu <arnaud.bienvenu@via.ecp.fr>
|
||||||
Régis Clément <clement@via.ecp.fr>
|
Régis Clément <clement@via.ecp.fr>
|
||||||
Alexandre Duret <alex@via.ecp.fr>
|
Alexandre Duret <alex@via.ecp.fr>
|
||||||
|
55
configure.in
55
configure.in
@ -4,7 +4,7 @@ AC_CONFIG_HEADER(include/defs.h)
|
|||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
|
|
||||||
VLC_VERSION=0.1.99c
|
VLC_VERSION=0.1.99d
|
||||||
AC_SUBST(VLC_VERSION)
|
AC_SUBST(VLC_VERSION)
|
||||||
VLC_CODENAME=Onatopp
|
VLC_CODENAME=Onatopp
|
||||||
AC_SUBST(VLC_CODENAME)
|
AC_SUBST(VLC_CODENAME)
|
||||||
@ -58,34 +58,30 @@ AC_C_CONST
|
|||||||
AC_TYPE_SIZE_T
|
AC_TYPE_SIZE_T
|
||||||
AC_HEADER_TIME
|
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,
|
AC_ARG_ENABLE(dsp,
|
||||||
[ --enable-dsp Linux /dev/dsp support (default enabled)])
|
[ --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,
|
AC_ARG_ENABLE(esd,
|
||||||
[ --enable-esd Esound library support (default disabled)],
|
[ --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}
|
ARCH=${host_cpu}
|
||||||
AC_ARG_ENABLE(ppro,
|
AC_ARG_ENABLE(ppro,
|
||||||
@ -99,14 +95,12 @@ SYS=${host_os}
|
|||||||
|
|
||||||
# special cases
|
# special cases
|
||||||
if test x$host_os = xbeos; then
|
if test x$host_os = xbeos; then
|
||||||
VOUT="dummy beos"
|
PLUGINS="dummy beos"
|
||||||
AOUT="dummy beos"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_SUBST(SYS)
|
AC_SUBST(SYS)
|
||||||
AC_SUBST(ARCH)
|
AC_SUBST(ARCH)
|
||||||
AC_SUBST(VOUT)
|
AC_SUBST(PLUGINS)
|
||||||
AC_SUBST(AOUT)
|
|
||||||
|
|
||||||
AC_OUTPUT([Makefile include/config.h])
|
AC_OUTPUT([Makefile include/config.h])
|
||||||
|
|
||||||
@ -116,6 +110,5 @@ vlc configuration
|
|||||||
vlc version : ${VLC_VERSION}
|
vlc version : ${VLC_VERSION}
|
||||||
system : ${SYS}
|
system : ${SYS}
|
||||||
architecture : ${ARCH}
|
architecture : ${ARCH}
|
||||||
vout : ${VOUT}
|
plugins : ${PLUGINS}
|
||||||
aout : ${AOUT}
|
|
||||||
"
|
"
|
||||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -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
|
vlc (0.1.99c) unstable; urgency=low
|
||||||
|
|
||||||
* Caught Delete Window event in Gnome and X11 modes
|
* Caught Delete Window event in Gnome and X11 modes
|
||||||
|
@ -26,7 +26,7 @@ typedef int plugin_id_t;
|
|||||||
typedef void* plugin_id_t;
|
typedef void* plugin_id_t;
|
||||||
#endif
|
#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 TrashPlugin ( plugin_id_t p_plugin );
|
||||||
void * GetPluginFunction ( plugin_id_t plugin, char *name );
|
void * GetPluginFunction ( plugin_id_t plugin, char *name );
|
||||||
|
|
||||||
|
238
plugins/beos/aout_beos.cpp
Normal file
238
plugins/beos/aout_beos.cpp
Normal file
@ -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" */
|
||||||
|
|
202
plugins/beos/intf_beos.cpp
Normal file
202
plugins/beos/intf_beos.cpp
Normal file
@ -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" */
|
559
plugins/beos/vout_beos.cpp
Normal file
559
plugins/beos/vout_beos.cpp
Normal file
@ -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" */
|
242
plugins/dsp/aout_dsp.c
Normal file
242
plugins/dsp/aout_dsp.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
|
118
plugins/dummy/aout_dummy.c
Normal file
118
plugins/dummy/aout_dummy.c
Normal file
@ -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 )
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
109
plugins/dummy/intf_dummy.c
Normal file
109
plugins/dummy/intf_dummy.c
Normal file
@ -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 )
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
189
plugins/dummy/vout_dummy.c
Normal file
189
plugins/dummy/vout_dummy.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
|
191
plugins/esd/aout_esd.c
Normal file
191
plugins/esd/aout_esd.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
|
286
plugins/fb/intf_fb.c
Normal file
286
plugins/fb/intf_fb.c
Normal file
@ -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 )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
365
plugins/fb/vout_fb.c
Normal file
365
plugins/fb/vout_fb.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
|
156
plugins/ggi/intf_ggi.c
Normal file
156
plugins/ggi/intf_ggi.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
330
plugins/ggi/vout_ggi.c
Normal file
330
plugins/ggi/vout_ggi.c
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
|
119
plugins/glide/intf_glide.c
Normal file
119
plugins/glide/intf_glide.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
273
plugins/glide/vout_glide.c
Normal file
273
plugins/glide/vout_glide.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
|
664
plugins/gnome/intf_gnome.c
Normal file
664
plugins/gnome/intf_gnome.c
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
|
67
plugins/gnome/intf_gnome.h
Normal file
67
plugins/gnome/intf_gnome.h
Normal file
@ -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 );
|
||||||
|
|
500
plugins/gnome/intf_gnome_callbacks.c
Normal file
500
plugins/gnome/intf_gnome_callbacks.c
Normal file
@ -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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
216
plugins/gnome/intf_gnome_callbacks.h
Normal file
216
plugins/gnome/intf_gnome_callbacks.h
Normal file
@ -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);
|
811
plugins/gnome/intf_gnome_interface.c
Normal file
811
plugins/gnome/intf_gnome_interface.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
8
plugins/gnome/intf_gnome_interface.h
Normal file
8
plugins/gnome/intf_gnome_interface.h
Normal file
@ -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);
|
143
plugins/gnome/intf_gnome_support.c
Normal file
143
plugins/gnome/intf_gnome_support.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
34
plugins/gnome/intf_gnome_support.h
Normal file
34
plugins/gnome/intf_gnome_support.h
Normal file
@ -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);
|
||||||
|
|
58
plugins/gnome/intf_gnome_thread.h
Normal file
58
plugins/gnome/intf_gnome_thread.h
Normal file
@ -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 );
|
||||||
|
|
692
plugins/gnome/vout_gnome.c
Normal file
692
plugins/gnome/vout_gnome.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
|
523
plugins/mga/intf_mga.c
Normal file
523
plugins/mga/intf_mga.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
685
plugins/mga/vout_mga.c
Normal file
685
plugins/mga/vout_mga.c
Normal file
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
100
plugins/mga/vout_mga.h
Normal file
100
plugins/mga/vout_mga.h
Normal file
@ -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 );
|
||||||
|
|
550
plugins/x11/intf_x11.c
Normal file
550
plugins/x11/intf_x11.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
694
plugins/x11/vout_x11.c
Normal file
694
plugins/x11/vout_x11.c
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
|
@ -95,9 +95,9 @@ aout_thread_t *aout_CreateThread( int *pi_status )
|
|||||||
/* Request an interface plugin */
|
/* Request an interface plugin */
|
||||||
psz_method = main_GetPszVariable( AOUT_METHOD_VAR, AOUT_DEFAULT_METHOD );
|
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 );
|
free( p_aout );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
@ -103,9 +103,9 @@ intf_thread_t* intf_Create( void )
|
|||||||
/* Request an interface plugin */
|
/* Request an interface plugin */
|
||||||
psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
|
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 );
|
free( p_intf );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
@ -40,20 +40,20 @@
|
|||||||
|
|
||||||
#include "plugins.h"
|
#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;
|
int i_count, i_length;
|
||||||
char * psz_plugin;
|
char * psz_plugin;
|
||||||
char * psz_plugin_path[ PLUGIN_PATH_COUNT ] =
|
char * psz_plugin_path[ PLUGIN_PATH_COUNT ] =
|
||||||
{
|
{
|
||||||
".",
|
".",
|
||||||
"plugins/aout", "plugins/vout", "plugins/intf", /* these ones should disappear */
|
"lib", /* this one should disappear */
|
||||||
PLUGIN_PATH
|
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++ )
|
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;
|
char * psz_program_path;
|
||||||
|
|
||||||
psz_program_path = beos_GetProgramPath();
|
psz_program_path = beos_GetProgramPath();
|
||||||
psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + strlen(psz_program_path) + i_length + 6 );
|
psz_plugin = malloc( strlen(psz_plugin_path[i_count]) +
|
||||||
sprintf( psz_plugin, "%s/%s/%s_%s.so", psz_program_path, psz_plugin_path[i_count], psz_mask, psz_name );
|
strlen(psz_program_path) + i_length + 5 );
|
||||||
#else
|
sprintf( psz_plugin, "%s/%s/%s.so", psz_program_path,
|
||||||
psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 6 );
|
psz_plugin_path[i_count], psz_name );
|
||||||
sprintf( psz_plugin, "%s/%s_%s.so", psz_plugin_path[i_count], psz_mask, psz_name );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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 );
|
*p_plugin = load_add_on( psz_plugin );
|
||||||
|
#else
|
||||||
|
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 );
|
||||||
|
|
||||||
|
*p_plugin = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free( psz_plugin );
|
free( psz_plugin );
|
||||||
|
@ -107,9 +107,9 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window,
|
|||||||
/* Request an interface plugin */
|
/* Request an interface plugin */
|
||||||
psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
|
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 );
|
free( p_vout );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,8 @@
|
|||||||
#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
|
#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
|
||||||
#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
|
#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
|
||||||
|
|
||||||
|
//#define NODITHER
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Local prototypes
|
* 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_start; /* offset array start */
|
||||||
int * p_offset; /* offset array pointer */
|
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 dither10[4] = { 0x0, 0x8, 0x2, 0xa };
|
||||||
int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
|
int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
|
||||||
int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
|
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 dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
|
||||||
int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
|
int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
|
||||||
int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
|
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
|
#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
|
* Initialize some values - i_pic_line_width will store the line skip
|
||||||
*/
|
*/
|
||||||
|
12
vlc.spec
12
vlc.spec
@ -1,10 +1,10 @@
|
|||||||
Name: vlc
|
Name: vlc
|
||||||
Version: 0.1.99c
|
Version: 0.1.99d
|
||||||
Release: 1
|
Release: 1
|
||||||
Copyright: GPL
|
Copyright: GPL
|
||||||
Url: http://www.videolan.org/
|
Url: http://www.videolan.org/
|
||||||
Group: X11/Applications/Graphics
|
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>
|
Packager: Eric Doutreleau <Eric.doutreleau@int-evry.fr>
|
||||||
|
|
||||||
Buildroot: /tmp/vlc-build
|
Buildroot: /tmp/vlc-build
|
||||||
@ -33,10 +33,10 @@ mkdir -p $RPM_BUILD_ROOT/usr/bin
|
|||||||
make install prefix=$RPM_BUILD_ROOT/usr
|
make install prefix=$RPM_BUILD_ROOT/usr
|
||||||
|
|
||||||
%files
|
%files
|
||||||
/usr/bin/vlc
|
%attr(-, root, root) /usr/bin/vlc
|
||||||
/usr/share/videolan/vlc
|
%attr(-, root, root) /usr/share/videolan/vlc
|
||||||
/usr/lib/videolan
|
%attr(-, root, root) /usr/lib/videolan
|
||||||
%doc AUTHORS COPYING INSTALL NEWS README doc
|
%attr(-, root, root) %doc AUTHORS COPYING INSTALL NEWS README doc
|
||||||
%clean
|
%clean
|
||||||
rm -rf $RPM_BUILD_ROOT
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user