mirror of
https://github.com/videolan/vlc.git
synced 2024-11-25 02:44:30 +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
|
||||
0.1.99c :
|
||||
|
||||
* fixed Makefile.in for debug version
|
||||
* caught Delete Window event in Gnome and X11 modes
|
||||
* fixed manpage
|
||||
* GGI output now works
|
||||
* fixed a segfault on exit for the Gnome plugin
|
||||
* fixed compile problems for BeOS
|
||||
* sound support almost works under BeOS
|
||||
* fixed a warning in ac3_exponent.c
|
||||
* automatic support for .rpm and .deb building
|
||||
* fixed Makefile.in for debug version
|
||||
* caught Delete Window event in Gnome and X11 modes
|
||||
* fixed manpage
|
||||
* GGI output now works
|
||||
* fixed a segfault on exit for the Gnome plugin
|
||||
* fixed compile problems for BeOS
|
||||
* sound support almost works under BeOS
|
||||
* fixed a warning in ac3_exponent.c
|
||||
* automatic support for .rpm and .deb building
|
||||
|
||||
Sat Jun 17 03:35:02 CEST 2000
|
||||
0.1.99b :
|
||||
|
||||
* fixed a bug preventing to quit when run with no arguments
|
||||
* new VLAN changing code
|
||||
* created the ChangeLog file :)
|
||||
* fixed a bug preventing to quit when run with no arguments
|
||||
* new VLAN changing code
|
||||
* created the ChangeLog file :)
|
||||
|
||||
|
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
|
||||
|
||||
SYS=@SYS@
|
||||
ARCH=@ARCH@
|
||||
AOUT=@AOUT@
|
||||
VOUT=@VOUT@
|
||||
INTF=@VOUT@
|
||||
PLUGINS=@PLUGINS@
|
||||
SNAPSHOTDIR=vlc-@VLC_VERSION@
|
||||
INSTALL=@INSTALL@
|
||||
prefix=@prefix@
|
||||
@ -249,12 +246,44 @@ endif
|
||||
#
|
||||
# Plugins
|
||||
#
|
||||
intf_plugin = $(INTF:%=plugins/intf/intf_%.so)
|
||||
aout_plugin = $(AOUT:%=plugins/aout/aout_%.so)
|
||||
vout_plugin = $(VOUT:%=plugins/vout/vout_%.so)
|
||||
PLUGINS := $(PLUGINS:%=lib/%.so)
|
||||
|
||||
PLUGIN_OBJ = $(intf_plugin) $(aout_plugin) $(vout_plugin)
|
||||
PLUGIN_BEOS = plugins/beos/aout_beos.o \
|
||||
plugins/beos/intf_beos.o \
|
||||
plugins/beos/vout_beos.o
|
||||
|
||||
PLUGIN_DSP = plugins/dsp/aout_dsp.o
|
||||
|
||||
PLUGIN_DUMMY = plugins/dummy/aout_dummy.o \
|
||||
plugins/dummy/intf_dummy.o \
|
||||
plugins/dummy/vout_dummy.o
|
||||
|
||||
PLUGIN_ESD = plugins/esd/aout_esd.o
|
||||
|
||||
PLUGIN_FB = plugins/fb/intf_fb.o \
|
||||
plugins/fb/vout_fb.o
|
||||
|
||||
PLUGIN_GGI = plugins/ggi/intf_ggi.o \
|
||||
plugins/ggi/vout_ggi.o
|
||||
|
||||
PLUGIN_GLIDE = plugins/glide/intf_glide.o \
|
||||
plugins/glide/vout_glide.o
|
||||
|
||||
PLUGIN_GNOME = plugins/gnome/intf_gnome.o \
|
||||
plugins/gnome/intf_gnome_callbacks.o \
|
||||
plugins/gnome/intf_gnome_interface.o \
|
||||
plugins/gnome/intf_gnome_support.o \
|
||||
plugins/gnome/vout_gnome.o
|
||||
|
||||
PLUGIN_MGA = plugins/mga/intf_mga.o \
|
||||
plugins/fb/vout_mga.o
|
||||
|
||||
PLUGIN_X11 = plugins/x11/intf_x11.o \
|
||||
plugins/x11/vout_x11.o
|
||||
|
||||
PLUGIN_OBJ = $(PLUGIN_BEOS) $(PLUGIN_DSP) $(PLUGIN_DUMMY) $(PLUGIN_ESD) \
|
||||
$(PLUGIN_FB) $(PLUGIN_GGI) $(PLUGIN_GLIDE) $(PLUGIN_GNOME) \
|
||||
$(PLUGIN_MGA) $(PLUGIN_X11)
|
||||
#
|
||||
# Other lists of files
|
||||
#
|
||||
@ -280,7 +309,7 @@ clean:
|
||||
rm -f $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ)
|
||||
|
||||
distclean: clean
|
||||
rm -f */*/*.o plugins/*/*.so **/*~ *.log
|
||||
rm -f src/*/*.o plugins/*/*.o lib/*.so **/*~ *.log
|
||||
rm -f Makefile include/defs.h include/config.h
|
||||
rm -f config.status config.cache config.log
|
||||
rm -f vlc gmon.out core build-stamp
|
||||
@ -290,9 +319,9 @@ install:
|
||||
$(INSTALL) vlc $(prefix)/bin
|
||||
mkdir -p $(prefix)/lib/videolan/vlc
|
||||
mkdir -p $(prefix)/share/videolan/vlc
|
||||
$(INSTALL) $(PLUGIN_OBJ) $(prefix)/lib/videolan/vlc
|
||||
$(INSTALL) share/*.psf $(prefix)/share/videolan/vlc
|
||||
$(INSTALL) share/*.png $(prefix)/share/videolan/vlc
|
||||
$(INSTALL) -m 644 $(PLUGINS) $(prefix)/lib/videolan/vlc
|
||||
$(INSTALL) -m 644 share/*.psf $(prefix)/share/videolan/vlc
|
||||
$(INSTALL) -m 644 share/*.png $(prefix)/share/videolan/vlc
|
||||
|
||||
show:
|
||||
@echo "Command line for C objects:"
|
||||
@ -316,12 +345,6 @@ snapshot:
|
||||
mv /tmp/${SNAPSHOTDIR}.tar.gz ..
|
||||
@echo "Sources are in ../${SNAPSHOTDIR}.tar.gz"
|
||||
|
||||
deb:
|
||||
dpkg-buildpackage -rfakeroot -us -uc
|
||||
|
||||
rpm:
|
||||
rpm -ba vlc.spec
|
||||
|
||||
FORCE:
|
||||
|
||||
#
|
||||
@ -336,7 +359,7 @@ else
|
||||
$(CC) $(CCFLAGS) $(LCFLAGS) $(CFLAGS) --export-dynamic -rdynamic -o $@ $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ)
|
||||
endif
|
||||
|
||||
plugins: $(PLUGIN_OBJ)
|
||||
plugins: $(PLUGINS)
|
||||
|
||||
#
|
||||
# Generic rules (see below)
|
||||
@ -359,57 +382,56 @@ $(ASM_OBJ): %.o: %.S
|
||||
#$(PLUGIN_OBJ): %.so: Makefile.dep
|
||||
#$(PLUGIN_OBJ): %.so: .dep/%.d
|
||||
|
||||
# audio plugins
|
||||
plugins/aout/aout_dummy.so plugins/aout/aout_dsp.so: %.so: %.c
|
||||
ifeq ($(SYS),beos)
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
|
||||
else
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $<
|
||||
endif
|
||||
#$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
|
||||
|
||||
lib/beos.so: $(PLUGIN_BEOS)
|
||||
ld -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
|
||||
$(PLUGIN_BEOS): %.o: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
plugins/aout/aout_esd.so: %.so: %.c
|
||||
lib/esd.so: $(PLUGIN_ESD)
|
||||
ifneq (,$(findstring bsd,$(SYS)))
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -lesd -shared -o $@ $<
|
||||
ld -shared -lesd -o $@ $^
|
||||
else
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -laudiofile -lesd -shared -o $@ $<
|
||||
ld -shared -laudiofile -lesd -o $@ $^
|
||||
endif
|
||||
$(PLUGIN_ESD): %.o: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
plugins/aout/aout_beos.so: %.so: %.cpp
|
||||
$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
|
||||
|
||||
# video plugins
|
||||
plugins/intf/intf_dummy.so plugins/vout/vout_dummy.so \
|
||||
plugins/intf/intf_fb.so plugins/vout/vout_fb.so: %.so: %.c
|
||||
ifeq ($(SYS),beos)
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
|
||||
else
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $<
|
||||
endif
|
||||
lib/dummy.so: $(PLUGIN_DUMMY)
|
||||
ld -shared -o $@ $^
|
||||
$(PLUGIN_DUMMY): %.o: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
plugins/intf/intf_x11.so plugins/vout/vout_x11.so: %.so: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
|
||||
lib/fb.so: $(PLUGIN_FB)
|
||||
ld -shared -o $@ $^
|
||||
$(PLUGIN_FB): %.o: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
plugins/intf/intf_mga.so plugins/vout/vout_mga.so: %.so: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
|
||||
lib/x11.so: $(PLUGIN_X11)
|
||||
ld -shared -L/usr/X11R6/lib -lX11 -lXext -o $@ $^
|
||||
$(PLUGIN_X11): %.o: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
plugins/intf/intf_gnome.so: %.so: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) $(LCFLAGS) `gnome-config --libs --cflags gnomeui` -shared -o $@ $< plugins/intf/intf_gnome_callbacks.c plugins/intf/intf_gnome_interface.c plugins/intf/intf_gnome_support.c
|
||||
lib/mga.so: $(PLUGIN_MGA)
|
||||
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
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $<
|
||||
lib/gnome.so: $(PLUGIN_GNOME)
|
||||
ld -shared `gnome-config --libs gnomeui | sed 's,-rdynamic,,'` -o $@ $^
|
||||
$(PLUGIN_GNOME): %.o: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) `gnome-config --cflags gnomeui`-c -o $@ $<
|
||||
|
||||
plugins/intf/intf_glide.so plugins/vout/vout_glide.so: %.so: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/include/glide -lglide2x -shared -o $@ $<
|
||||
lib/glide.so: $(PLUGIN_GLIDE)
|
||||
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
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -lggi -shared -o $@ $<
|
||||
|
||||
plugins/intf/intf_beos.so: %.so: %.cpp
|
||||
$(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_
|
||||
|
||||
lib/ggi.so: $(PLUGIN_GGI)
|
||||
ld -shared -lggi -o $@ $^
|
||||
$(PLUGIN_GGI): %.o: %.c
|
||||
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
################################################################################
|
||||
# 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 ]
|
||||
|
||||
|
||||
Building, Installing and Running VideoLAN
|
||||
=========================================
|
||||
|
||||
... 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'.
|
||||
See the INSTALL file for this.
|
||||
|
||||
|
||||
... 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 ]
|
||||
|
||||
|
||||
|
||||
... Troubleshooting
|
||||
|
||||
[ nothing appropriate yet ]
|
||||
|
||||
|
||||
|
||||
... Resources
|
||||
|
||||
[ nothing appropriate yet ]
|
||||
|
||||
|
||||
|
||||
... The team
|
||||
The team
|
||||
========
|
||||
|
||||
The following teachers were involved in the VideoLAN project :
|
||||
|
||||
@ -52,6 +56,7 @@ The following students were members of the VideoLAN team :
|
||||
Antoine Brenner <brenner@via.ecp.fr>
|
||||
Régis Duchesne <regis@via.ecp.fr>
|
||||
Alexandre Francois <francois@via.ecp.fr>
|
||||
Christian Gross <gross@via.ecp.fr>
|
||||
Hugo Haas <hugo@via.ecp.fr>
|
||||
Mikael Journo <mj32@cornell.edu>
|
||||
Michel Lespinasse <walken@wrs.com>
|
||||
@ -61,7 +66,6 @@ The following students were members of the VideoLAN team :
|
||||
|
||||
Olivier Baxa <oli@via.ecp.fr>
|
||||
Patrice Bazerque <patrice.bazerque@via.ecp.fr>
|
||||
Etienne Bernard <eb@via.ecp.fr>
|
||||
Arnaud Bienvenu <arnaud.bienvenu@via.ecp.fr>
|
||||
Régis Clément <clement@via.ecp.fr>
|
||||
Alexandre Duret <alex@via.ecp.fr>
|
||||
|
55
configure.in
55
configure.in
@ -4,7 +4,7 @@ AC_CONFIG_HEADER(include/defs.h)
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
VLC_VERSION=0.1.99c
|
||||
VLC_VERSION=0.1.99d
|
||||
AC_SUBST(VLC_VERSION)
|
||||
VLC_CODENAME=Onatopp
|
||||
AC_SUBST(VLC_CODENAME)
|
||||
@ -58,34 +58,30 @@ AC_C_CONST
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
|
||||
AC_ARG_ENABLE(dummy,
|
||||
[ --enable-vout-dummy dummy video support (default enabled)])
|
||||
if test x$enable_vout_dummy != xno; then VOUT=${VOUT}"dummy "; fi
|
||||
AC_ARG_ENABLE(x11,
|
||||
[ --enable-x11 X11 video support (default enabled)])
|
||||
if test x$enable_x11 != xno; then VOUT=${VOUT}"x11 "; fi
|
||||
AC_ARG_ENABLE(fb,
|
||||
[ --enable-fb Linux framebuffer video support (default disabled)],
|
||||
[if test x$enable_fb = xyes; then VOUT=${VOUT}"fb "; fi])
|
||||
AC_ARG_ENABLE(gnome,
|
||||
[ --enable-gnome Gnome video support (default disabled)],
|
||||
[if test x$enable_gnome = xyes; then VOUT=${VOUT}"gnome "; fi])
|
||||
AC_ARG_ENABLE(glide,
|
||||
[ --enable-glide Glide (3dfx) video support (default disabled)],
|
||||
[if test x$enable_glide = xyes; then VOUT=${VOUT}"glide "; fi])
|
||||
AC_ARG_ENABLE(ggi,
|
||||
[ --enable-ggi GGI video support (default disabled)],
|
||||
[if test x$enable_ggi = xyes; then VOUT=${VOUT}"ggi "; fi])
|
||||
|
||||
AC_ARG_ENABLE(dummy,
|
||||
[ --enable-aout-dummy dummy audio support (default enabled)])
|
||||
if test x$enable_aout_dummy != xno; then AOUT=${AOUT}"dummy "; fi
|
||||
AC_ARG_ENABLE(dsp,
|
||||
[ --enable-dsp Linux /dev/dsp support (default enabled)])
|
||||
if test x$enable_dsp != xno; then AOUT=${AOUT}"dsp "; fi
|
||||
if test x$enable_dsp != xno; then PLUGINS=${PLUGINS}"dsp "; fi
|
||||
AC_ARG_ENABLE(dummy,
|
||||
[ --enable-dummy dummy audio and video support (default enabled)])
|
||||
if test x$enable_dummy != xno; then PLUGINS=${PLUGINS}"dummy "; fi
|
||||
AC_ARG_ENABLE(esd,
|
||||
[ --enable-esd Esound library support (default disabled)],
|
||||
[if test x$enable_gnome = xyes; then AOUT=${AOUT}"esd "; fi])
|
||||
[if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"esd "; fi])
|
||||
AC_ARG_ENABLE(fb,
|
||||
[ --enable-fb Linux framebuffer support (default disabled)],
|
||||
[if test x$enable_fb = xyes; then PLUGINS=${PLUGINS}"fb "; fi])
|
||||
AC_ARG_ENABLE(ggi,
|
||||
[ --enable-ggi GGI support (default disabled)],
|
||||
[if test x$enable_ggi = xyes; then PLUGINS=${PLUGINS}"ggi "; fi])
|
||||
AC_ARG_ENABLE(glide,
|
||||
[ --enable-glide Glide (3dfx) support (default disabled)],
|
||||
[if test x$enable_glide = xyes; then PLUGINS=${PLUGINS}"glide "; fi])
|
||||
AC_ARG_ENABLE(gnome,
|
||||
[ --enable-gnome Gnome support (default disabled)],
|
||||
[if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; fi])
|
||||
AC_ARG_ENABLE(x11,
|
||||
[ --enable-x11 X11 support (default enabled)])
|
||||
if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi
|
||||
|
||||
ARCH=${host_cpu}
|
||||
AC_ARG_ENABLE(ppro,
|
||||
@ -99,14 +95,12 @@ SYS=${host_os}
|
||||
|
||||
# special cases
|
||||
if test x$host_os = xbeos; then
|
||||
VOUT="dummy beos"
|
||||
AOUT="dummy beos"
|
||||
PLUGINS="dummy beos"
|
||||
fi
|
||||
|
||||
AC_SUBST(SYS)
|
||||
AC_SUBST(ARCH)
|
||||
AC_SUBST(VOUT)
|
||||
AC_SUBST(AOUT)
|
||||
AC_SUBST(PLUGINS)
|
||||
|
||||
AC_OUTPUT([Makefile include/config.h])
|
||||
|
||||
@ -116,6 +110,5 @@ vlc configuration
|
||||
vlc version : ${VLC_VERSION}
|
||||
system : ${SYS}
|
||||
architecture : ${ARCH}
|
||||
vout : ${VOUT}
|
||||
aout : ${AOUT}
|
||||
plugins : ${PLUGINS}
|
||||
"
|
||||
|
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
|
||||
|
||||
* Caught Delete Window event in Gnome and X11 modes
|
||||
|
@ -26,7 +26,7 @@ typedef int plugin_id_t;
|
||||
typedef void* plugin_id_t;
|
||||
#endif
|
||||
|
||||
int RequestPlugin ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name );
|
||||
int RequestPlugin ( plugin_id_t * p_plugin, char * psz_name );
|
||||
void TrashPlugin ( plugin_id_t p_plugin );
|
||||
void * GetPluginFunction ( plugin_id_t plugin, char *name );
|
||||
|
||||
|
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 */
|
||||
psz_method = main_GetPszVariable( AOUT_METHOD_VAR, AOUT_DEFAULT_METHOD );
|
||||
|
||||
if( RequestPlugin( &p_aout->aout_plugin, "aout", psz_method ) )
|
||||
if( RequestPlugin( &p_aout->aout_plugin, psz_method ) )
|
||||
{
|
||||
intf_ErrMsg( "error: could not open audio plugin aout_%s.so\n", psz_method );
|
||||
intf_ErrMsg( "error: could not open audio plugin %s.so\n", psz_method );
|
||||
free( p_aout );
|
||||
return( NULL );
|
||||
}
|
||||
|
@ -103,9 +103,9 @@ intf_thread_t* intf_Create( void )
|
||||
/* Request an interface plugin */
|
||||
psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
|
||||
|
||||
if( RequestPlugin( &p_intf->intf_plugin, "intf", psz_method ) < 0 )
|
||||
if( RequestPlugin( &p_intf->intf_plugin, psz_method ) < 0 )
|
||||
{
|
||||
intf_ErrMsg( "error: could not open interface plugin intf_%s.so\n", psz_method );
|
||||
intf_ErrMsg( "error: could not open interface plugin %s.so\n", psz_method );
|
||||
free( p_intf );
|
||||
return( NULL );
|
||||
}
|
||||
|
@ -40,20 +40,20 @@
|
||||
|
||||
#include "plugins.h"
|
||||
|
||||
#define PLUGIN_PATH_COUNT 5
|
||||
#define PLUGIN_PATH_COUNT 3
|
||||
|
||||
int RequestPlugin ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name )
|
||||
int RequestPlugin ( plugin_id_t * p_plugin, char * psz_name )
|
||||
{
|
||||
int i_count, i_length;
|
||||
char * psz_plugin;
|
||||
char * psz_plugin_path[ PLUGIN_PATH_COUNT ] =
|
||||
{
|
||||
".",
|
||||
"plugins/aout", "plugins/vout", "plugins/intf", /* these ones should disappear */
|
||||
"lib", /* this one should disappear */
|
||||
PLUGIN_PATH
|
||||
};
|
||||
|
||||
i_length = strlen( psz_mask ) + strlen( psz_name );
|
||||
i_length = strlen( psz_name );
|
||||
|
||||
for ( i_count = 0 ; i_count < PLUGIN_PATH_COUNT ; i_count++ )
|
||||
{
|
||||
@ -61,17 +61,17 @@ int RequestPlugin ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name )
|
||||
char * psz_program_path;
|
||||
|
||||
psz_program_path = beos_GetProgramPath();
|
||||
psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + strlen(psz_program_path) + i_length + 6 );
|
||||
sprintf( psz_plugin, "%s/%s/%s_%s.so", psz_program_path, psz_plugin_path[i_count], psz_mask, psz_name );
|
||||
#else
|
||||
psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 6 );
|
||||
sprintf( psz_plugin, "%s/%s_%s.so", psz_plugin_path[i_count], psz_mask, psz_name );
|
||||
#endif
|
||||
psz_plugin = malloc( strlen(psz_plugin_path[i_count]) +
|
||||
strlen(psz_program_path) + i_length + 5 );
|
||||
sprintf( psz_plugin, "%s/%s/%s.so", psz_program_path,
|
||||
psz_plugin_path[i_count], psz_name );
|
||||
|
||||
#if defined(HAVE_DLFCN_H)
|
||||
*p_plugin = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
|
||||
#elif defined(HAVE_IMAGE_H)
|
||||
*p_plugin = load_add_on( psz_plugin );
|
||||
#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
|
||||
|
||||
free( psz_plugin );
|
||||
|
@ -107,9 +107,9 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window,
|
||||
/* Request an interface plugin */
|
||||
psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
|
||||
|
||||
if( RequestPlugin( &p_vout->vout_plugin, "vout", psz_method ) < 0 )
|
||||
if( RequestPlugin( &p_vout->vout_plugin, psz_method ) < 0 )
|
||||
{
|
||||
intf_ErrMsg( "error: could not open video plugin vout_%s.so\n", psz_method );
|
||||
intf_ErrMsg( "error: could not open video plugin %s.so\n", psz_method );
|
||||
free( p_vout );
|
||||
return( NULL );
|
||||
}
|
||||
|
@ -73,6 +73,8 @@
|
||||
#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
|
||||
#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
|
||||
|
||||
//#define NODITHER
|
||||
|
||||
/*****************************************************************************
|
||||
* Local prototypes
|
||||
*****************************************************************************/
|
||||
@ -1093,6 +1095,17 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
|
||||
int * p_offset_start; /* offset array start */
|
||||
int * p_offset; /* offset array pointer */
|
||||
|
||||
#ifdef NODITHER
|
||||
int dither10[4] = { 0x7, 0x8, 0x7, 0x8 };
|
||||
int dither11[4] = { 0x8, 0x7, 0x8, 0x7 };
|
||||
int dither12[4] = { 0x7, 0x8, 0x7, 0x8 };
|
||||
int dither13[4] = { 0x8, 0x7, 0x8, 0x7 };
|
||||
|
||||
int dither20[4] = { 0xf, 0x10, 0xf, 0x10 };
|
||||
int dither21[4] = { 0x10, 0xf, 0x10, 0xf };
|
||||
int dither22[4] = { 0xf, 0x10, 0xf, 0x10 };
|
||||
int dither23[4] = { 0x10, 0xf, 0x10, 0xf };
|
||||
#else
|
||||
int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
|
||||
int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
|
||||
int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
|
||||
@ -1102,17 +1115,19 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
|
||||
int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
|
||||
int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
|
||||
int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
|
||||
|
||||
/* other matrices that can be interesting, either for debugging or for effects */
|
||||
#if 0
|
||||
int dither[4][4] = { { 0, 8, 2, 10 }, { 12, 4, 14, 16 }, { 3, 11, 1, 9}, {15, 7, 13, 5} };
|
||||
int dither[4][4] = { { 7, 8, 0, 15 }, { 0, 15, 8, 7 }, { 7, 0, 15, 8 }, { 15, 7, 8, 0 } };
|
||||
int dither[4][4] = { { 0, 15, 0, 15 }, { 15, 0, 15, 0 }, { 0, 15, 0, 15 }, { 15, 0, 15, 0 } };
|
||||
int dither[4][4] = { { 15, 15, 0, 0 }, { 15, 15, 0, 0 }, { 0, 0, 15, 15 }, { 0, 0, 15, 15 } };
|
||||
int dither[4][4] = { { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 } };
|
||||
int dither[4][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
|
||||
#endif
|
||||
|
||||
/* some other matrices that can be interesting, either for debugging
|
||||
* or for effects :
|
||||
*
|
||||
* { { 0, 8, 2, 10 }, { 12, 4, 14, 16 }, { 3, 11, 1, 9}, {15, 7, 13, 5} }
|
||||
* { { 7, 8, 0, 15 }, { 0, 15, 8, 7 }, { 7, 0, 15, 8 }, { 15, 7, 8, 0 } }
|
||||
* { { 0, 15, 0, 15 }, { 15, 0, 15, 0 }, { 0, 15, 0, 15 }, { 15, 0, 15, 0 } }
|
||||
* { { 15, 15, 0, 0 }, { 15, 15, 0, 0 }, { 0, 0, 15, 15 }, { 0, 0, 15, 15 } }
|
||||
* { { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 } }
|
||||
* { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialize some values - i_pic_line_width will store the line skip
|
||||
*/
|
||||
|
12
vlc.spec
12
vlc.spec
@ -1,10 +1,10 @@
|
||||
Name: vlc
|
||||
Version: 0.1.99c
|
||||
Version: 0.1.99d
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Url: http://www.videolan.org/
|
||||
Group: X11/Applications/Graphics
|
||||
Source0: http://www.videolan.org/packages/vlc-0.1.99c.tar.gz
|
||||
Source0: http://www.videolan.org/packages/0.1.99c/vlc-0.1.99c.tar.gz
|
||||
Packager: Eric Doutreleau <Eric.doutreleau@int-evry.fr>
|
||||
|
||||
Buildroot: /tmp/vlc-build
|
||||
@ -33,10 +33,10 @@ mkdir -p $RPM_BUILD_ROOT/usr/bin
|
||||
make install prefix=$RPM_BUILD_ROOT/usr
|
||||
|
||||
%files
|
||||
/usr/bin/vlc
|
||||
/usr/share/videolan/vlc
|
||||
/usr/lib/videolan
|
||||
%doc AUTHORS COPYING INSTALL NEWS README doc
|
||||
%attr(-, root, root) /usr/bin/vlc
|
||||
%attr(-, root, root) /usr/share/videolan/vlc
|
||||
%attr(-, root, root) /usr/lib/videolan
|
||||
%attr(-, root, root) %doc AUTHORS COPYING INSTALL NEWS README doc
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user