. nouveaux plugins - ne fonctionnent pas encore tous

This commit is contained in:
Sam Hocevar 2000-06-23 22:28:42 +00:00
parent 1b79957ceb
commit 3cbfc06dc3
43 changed files with 9568 additions and 377 deletions

View File

@ -1,20 +1,26 @@
Tue Jun 20 14:17:56 CEST 2000
0.1.99d :
* fixed RPM build
* .deb is now more lintian-friendly
Sun Jun 18 18:54:48 CEST 2000 Sun Jun 18 18:54:48 CEST 2000
0.1.99c : 0.1.99c :
* fixed Makefile.in for debug version * fixed Makefile.in for debug version
* caught Delete Window event in Gnome and X11 modes * caught Delete Window event in Gnome and X11 modes
* fixed manpage * fixed manpage
* GGI output now works * GGI output now works
* fixed a segfault on exit for the Gnome plugin * fixed a segfault on exit for the Gnome plugin
* fixed compile problems for BeOS * fixed compile problems for BeOS
* sound support almost works under BeOS * sound support almost works under BeOS
* fixed a warning in ac3_exponent.c * fixed a warning in ac3_exponent.c
* automatic support for .rpm and .deb building * automatic support for .rpm and .deb building
Sat Jun 17 03:35:02 CEST 2000 Sat Jun 17 03:35:02 CEST 2000
0.1.99b : 0.1.99b :
* fixed a bug preventing to quit when run with no arguments * fixed a bug preventing to quit when run with no arguments
* new VLAN changing code * new VLAN changing code
* created the ChangeLog file :) * created the ChangeLog file :)

37
INSTALL
View File

@ -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

View File

@ -13,10 +13,7 @@
DEBUG=0 DEBUG=0
SYS=@SYS@ SYS=@SYS@
ARCH=@ARCH@ PLUGINS=@PLUGINS@
AOUT=@AOUT@
VOUT=@VOUT@
INTF=@VOUT@
SNAPSHOTDIR=vlc-@VLC_VERSION@ SNAPSHOTDIR=vlc-@VLC_VERSION@
INSTALL=@INSTALL@ INSTALL=@INSTALL@
prefix=@prefix@ prefix=@prefix@
@ -249,12 +246,44 @@ endif
# #
# Plugins # Plugins
# #
intf_plugin = $(INTF:%=plugins/intf/intf_%.so) PLUGINS := $(PLUGINS:%=lib/%.so)
aout_plugin = $(AOUT:%=plugins/aout/aout_%.so)
vout_plugin = $(VOUT:%=plugins/vout/vout_%.so)
PLUGIN_OBJ = $(intf_plugin) $(aout_plugin) $(vout_plugin) PLUGIN_BEOS = plugins/beos/aout_beos.o \
plugins/beos/intf_beos.o \
plugins/beos/vout_beos.o
PLUGIN_DSP = plugins/dsp/aout_dsp.o
PLUGIN_DUMMY = plugins/dummy/aout_dummy.o \
plugins/dummy/intf_dummy.o \
plugins/dummy/vout_dummy.o
PLUGIN_ESD = plugins/esd/aout_esd.o
PLUGIN_FB = plugins/fb/intf_fb.o \
plugins/fb/vout_fb.o
PLUGIN_GGI = plugins/ggi/intf_ggi.o \
plugins/ggi/vout_ggi.o
PLUGIN_GLIDE = plugins/glide/intf_glide.o \
plugins/glide/vout_glide.o
PLUGIN_GNOME = plugins/gnome/intf_gnome.o \
plugins/gnome/intf_gnome_callbacks.o \
plugins/gnome/intf_gnome_interface.o \
plugins/gnome/intf_gnome_support.o \
plugins/gnome/vout_gnome.o
PLUGIN_MGA = plugins/mga/intf_mga.o \
plugins/fb/vout_mga.o
PLUGIN_X11 = plugins/x11/intf_x11.o \
plugins/x11/vout_x11.o
PLUGIN_OBJ = $(PLUGIN_BEOS) $(PLUGIN_DSP) $(PLUGIN_DUMMY) $(PLUGIN_ESD) \
$(PLUGIN_FB) $(PLUGIN_GGI) $(PLUGIN_GLIDE) $(PLUGIN_GNOME) \
$(PLUGIN_MGA) $(PLUGIN_X11)
# #
# Other lists of files # Other lists of files
# #
@ -280,7 +309,7 @@ clean:
rm -f $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ) rm -f $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(PLUGIN_OBJ)
distclean: clean distclean: clean
rm -f */*/*.o plugins/*/*.so **/*~ *.log rm -f src/*/*.o plugins/*/*.o lib/*.so **/*~ *.log
rm -f Makefile include/defs.h include/config.h rm -f Makefile include/defs.h include/config.h
rm -f config.status config.cache config.log rm -f config.status config.cache config.log
rm -f vlc gmon.out core build-stamp rm -f vlc gmon.out core build-stamp
@ -290,9 +319,9 @@ install:
$(INSTALL) vlc $(prefix)/bin $(INSTALL) vlc $(prefix)/bin
mkdir -p $(prefix)/lib/videolan/vlc mkdir -p $(prefix)/lib/videolan/vlc
mkdir -p $(prefix)/share/videolan/vlc mkdir -p $(prefix)/share/videolan/vlc
$(INSTALL) $(PLUGIN_OBJ) $(prefix)/lib/videolan/vlc $(INSTALL) -m 644 $(PLUGINS) $(prefix)/lib/videolan/vlc
$(INSTALL) share/*.psf $(prefix)/share/videolan/vlc $(INSTALL) -m 644 share/*.psf $(prefix)/share/videolan/vlc
$(INSTALL) share/*.png $(prefix)/share/videolan/vlc $(INSTALL) -m 644 share/*.png $(prefix)/share/videolan/vlc
show: show:
@echo "Command line for C objects:" @echo "Command line for C objects:"
@ -316,12 +345,6 @@ snapshot:
mv /tmp/${SNAPSHOTDIR}.tar.gz .. mv /tmp/${SNAPSHOTDIR}.tar.gz ..
@echo "Sources are in ../${SNAPSHOTDIR}.tar.gz" @echo "Sources are in ../${SNAPSHOTDIR}.tar.gz"
deb:
dpkg-buildpackage -rfakeroot -us -uc
rpm:
rpm -ba vlc.spec
FORCE: FORCE:
# #
@ -336,7 +359,7 @@ else
$(CC) $(CCFLAGS) $(LCFLAGS) $(CFLAGS) --export-dynamic -rdynamic -o $@ $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ) $(CC) $(CCFLAGS) $(LCFLAGS) $(CFLAGS) --export-dynamic -rdynamic -o $@ $(C_OBJ) $(CPP_OBJ) $(ASM_OBJ)
endif endif
plugins: $(PLUGIN_OBJ) plugins: $(PLUGINS)
# #
# Generic rules (see below) # Generic rules (see below)
@ -359,57 +382,56 @@ $(ASM_OBJ): %.o: %.S
#$(PLUGIN_OBJ): %.so: Makefile.dep #$(PLUGIN_OBJ): %.so: Makefile.dep
#$(PLUGIN_OBJ): %.so: .dep/%.d #$(PLUGIN_OBJ): %.so: .dep/%.d
# audio plugins #$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
plugins/aout/aout_dummy.so plugins/aout/aout_dsp.so: %.so: %.c
ifeq ($(SYS),beos) lib/beos.so: $(PLUGIN_BEOS)
$(CC) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_ ld -nostart -Xlinker -soname=$@ -o $@ $^ plugins/_APP_
else $(PLUGIN_BEOS): %.o: %.c
$(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $< $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
endif
plugins/aout/aout_esd.so: %.so: %.c lib/esd.so: $(PLUGIN_ESD)
ifneq (,$(findstring bsd,$(SYS))) ifneq (,$(findstring bsd,$(SYS)))
$(CC) $(CCFLAGS) $(CFLAGS) -lesd -shared -o $@ $< ld -shared -lesd -o $@ $^
else else
$(CC) $(CCFLAGS) $(CFLAGS) -laudiofile -lesd -shared -o $@ $< ld -shared -laudiofile -lesd -o $@ $^
endif endif
$(PLUGIN_ESD): %.o: %.c
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
plugins/aout/aout_beos.so: %.so: %.cpp lib/dummy.so: $(PLUGIN_DUMMY)
$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_ ld -shared -o $@ $^
$(PLUGIN_DUMMY): %.o: %.c
# video plugins $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
plugins/intf/intf_dummy.so plugins/vout/vout_dummy.so \
plugins/intf/intf_fb.so plugins/vout/vout_fb.so: %.so: %.c
ifeq ($(SYS),beos)
$(CC) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
else
$(CC) $(CCFLAGS) $(CFLAGS) -shared -o $@ $<
endif
plugins/intf/intf_x11.so plugins/vout/vout_x11.so: %.so: %.c lib/fb.so: $(PLUGIN_FB)
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $< ld -shared -o $@ $^
$(PLUGIN_FB): %.o: %.c
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
plugins/intf/intf_mga.so plugins/vout/vout_mga.so: %.so: %.c lib/x11.so: $(PLUGIN_X11)
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $< ld -shared -L/usr/X11R6/lib -lX11 -lXext -o $@ $^
$(PLUGIN_X11): %.o: %.c
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
plugins/intf/intf_gnome.so: %.so: %.c lib/mga.so: $(PLUGIN_MGA)
$(CC) $(CCFLAGS) $(CFLAGS) $(LCFLAGS) `gnome-config --libs --cflags gnomeui` -shared -o $@ $< plugins/intf/intf_gnome_callbacks.c plugins/intf/intf_gnome_interface.c plugins/intf/intf_gnome_support.c ld -shared -L/usr/X11R6/lib -lX11 -lXext -o $@ $^
$(PLUGIN_MGA): %.o: %.c
$(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
plugins/vout/vout_gnome.so: %.so: %.c lib/gnome.so: $(PLUGIN_GNOME)
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lXext -shared -o $@ $< ld -shared `gnome-config --libs gnomeui | sed 's,-rdynamic,,'` -o $@ $^
$(PLUGIN_GNOME): %.o: %.c
$(CC) $(CCFLAGS) $(CFLAGS) `gnome-config --cflags gnomeui`-c -o $@ $<
plugins/intf/intf_glide.so plugins/vout/vout_glide.so: %.so: %.c lib/glide.so: $(PLUGIN_GLIDE)
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/include/glide -lglide2x -shared -o $@ $< ld -shared -lglide2x -o $@ $^
$(PLUGIN_GLIDE): %.o: %.c
$(CC) $(CCFLAGS) $(CFLAGS) -I/usr/include/glide -c -o $@ $<
plugins/intf/intf_ggi.so plugins/vout/vout_ggi.so: %.so: %.c lib/ggi.so: $(PLUGIN_GGI)
$(CC) $(CCFLAGS) $(CFLAGS) -lggi -shared -o $@ $< ld -shared -lggi -o $@ $^
$(PLUGIN_GGI): %.o: %.c
plugins/intf/intf_beos.so: %.so: %.cpp $(CC) $(CCFLAGS) $(CFLAGS) -c -o $@ $<
$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
plugins/vout/vout_beos.so: %.so: %.cpp
$(CC) $(LCFLAGS) $(CCFLAGS) $(CFLAGS) -nostart -Xlinker -soname=$@ -o $@ $< plugins/_APP_
################################################################################ ################################################################################
# Note on generic rules and dependancies # Note on generic rules and dependancies

62
README
View File

@ -1,44 +1,48 @@
README for vlc, the VideoLAN Client
README for vlc, the VideoLAN Client
Introduction
... Introduction ============
[ nothing appropriate yet ] [ nothing appropriate yet ]
Building, Installing and Running VideoLAN
=========================================
... Building VideoLAN See the INSTALL file for this.
A typical way to configure the vlc is :
./configure --prefix=/usr --enable-ppro --enable-mmx --enable-gnome
See `./configure --help' for more information.
Then, run `make'.
... Running VideoLAN Troubleshooting
===============
A mailing-list has been set up for support and discussion about the
vlc. Its address is :
<vlc@videolan.org>
To subscribe, send a mail to <listar@videolan.org> with the following
words in the mail body :
subscribe vlc
To unsubscribe, do the same with the words :
unsubscribe vlc
When reporting bugs, try to be as precise as possible (which OS, which
distribution, what plugins you were trying, and so on).
Resources
=========
[ nothing appropriate yet ] [ nothing appropriate yet ]
The team
... Troubleshooting ========
[ nothing appropriate yet ]
... Resources
[ nothing appropriate yet ]
... The team
The following teachers were involved in the VideoLAN project : The following teachers were involved in the VideoLAN project :
@ -52,6 +56,7 @@ The following students were members of the VideoLAN team :
Antoine Brenner <brenner@via.ecp.fr> Antoine Brenner <brenner@via.ecp.fr>
Régis Duchesne <regis@via.ecp.fr> Régis Duchesne <regis@via.ecp.fr>
Alexandre Francois <francois@via.ecp.fr> Alexandre Francois <francois@via.ecp.fr>
Christian Gross <gross@via.ecp.fr>
Hugo Haas <hugo@via.ecp.fr> Hugo Haas <hugo@via.ecp.fr>
Mikael Journo <mj32@cornell.edu> Mikael Journo <mj32@cornell.edu>
Michel Lespinasse <walken@wrs.com> Michel Lespinasse <walken@wrs.com>
@ -61,7 +66,6 @@ The following students were members of the VideoLAN team :
Olivier Baxa <oli@via.ecp.fr> Olivier Baxa <oli@via.ecp.fr>
Patrice Bazerque <patrice.bazerque@via.ecp.fr> Patrice Bazerque <patrice.bazerque@via.ecp.fr>
Etienne Bernard <eb@via.ecp.fr>
Arnaud Bienvenu <arnaud.bienvenu@via.ecp.fr> Arnaud Bienvenu <arnaud.bienvenu@via.ecp.fr>
Régis Clément <clement@via.ecp.fr> Régis Clément <clement@via.ecp.fr>
Alexandre Duret <alex@via.ecp.fr> Alexandre Duret <alex@via.ecp.fr>

408
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@ AC_CONFIG_HEADER(include/defs.h)
AC_CANONICAL_HOST AC_CANONICAL_HOST
VLC_VERSION=0.1.99c VLC_VERSION=0.1.99d
AC_SUBST(VLC_VERSION) AC_SUBST(VLC_VERSION)
VLC_CODENAME=Onatopp VLC_CODENAME=Onatopp
AC_SUBST(VLC_CODENAME) AC_SUBST(VLC_CODENAME)
@ -58,34 +58,30 @@ AC_C_CONST
AC_TYPE_SIZE_T AC_TYPE_SIZE_T
AC_HEADER_TIME AC_HEADER_TIME
AC_ARG_ENABLE(dummy,
[ --enable-vout-dummy dummy video support (default enabled)])
if test x$enable_vout_dummy != xno; then VOUT=${VOUT}"dummy "; fi
AC_ARG_ENABLE(x11,
[ --enable-x11 X11 video support (default enabled)])
if test x$enable_x11 != xno; then VOUT=${VOUT}"x11 "; fi
AC_ARG_ENABLE(fb,
[ --enable-fb Linux framebuffer video support (default disabled)],
[if test x$enable_fb = xyes; then VOUT=${VOUT}"fb "; fi])
AC_ARG_ENABLE(gnome,
[ --enable-gnome Gnome video support (default disabled)],
[if test x$enable_gnome = xyes; then VOUT=${VOUT}"gnome "; fi])
AC_ARG_ENABLE(glide,
[ --enable-glide Glide (3dfx) video support (default disabled)],
[if test x$enable_glide = xyes; then VOUT=${VOUT}"glide "; fi])
AC_ARG_ENABLE(ggi,
[ --enable-ggi GGI video support (default disabled)],
[if test x$enable_ggi = xyes; then VOUT=${VOUT}"ggi "; fi])
AC_ARG_ENABLE(dummy,
[ --enable-aout-dummy dummy audio support (default enabled)])
if test x$enable_aout_dummy != xno; then AOUT=${AOUT}"dummy "; fi
AC_ARG_ENABLE(dsp, AC_ARG_ENABLE(dsp,
[ --enable-dsp Linux /dev/dsp support (default enabled)]) [ --enable-dsp Linux /dev/dsp support (default enabled)])
if test x$enable_dsp != xno; then AOUT=${AOUT}"dsp "; fi if test x$enable_dsp != xno; then PLUGINS=${PLUGINS}"dsp "; fi
AC_ARG_ENABLE(dummy,
[ --enable-dummy dummy audio and video support (default enabled)])
if test x$enable_dummy != xno; then PLUGINS=${PLUGINS}"dummy "; fi
AC_ARG_ENABLE(esd, AC_ARG_ENABLE(esd,
[ --enable-esd Esound library support (default disabled)], [ --enable-esd Esound library support (default disabled)],
[if test x$enable_gnome = xyes; then AOUT=${AOUT}"esd "; fi]) [if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"esd "; fi])
AC_ARG_ENABLE(fb,
[ --enable-fb Linux framebuffer support (default disabled)],
[if test x$enable_fb = xyes; then PLUGINS=${PLUGINS}"fb "; fi])
AC_ARG_ENABLE(ggi,
[ --enable-ggi GGI support (default disabled)],
[if test x$enable_ggi = xyes; then PLUGINS=${PLUGINS}"ggi "; fi])
AC_ARG_ENABLE(glide,
[ --enable-glide Glide (3dfx) support (default disabled)],
[if test x$enable_glide = xyes; then PLUGINS=${PLUGINS}"glide "; fi])
AC_ARG_ENABLE(gnome,
[ --enable-gnome Gnome support (default disabled)],
[if test x$enable_gnome = xyes; then PLUGINS=${PLUGINS}"gnome "; fi])
AC_ARG_ENABLE(x11,
[ --enable-x11 X11 support (default enabled)])
if test x$enable_x11 != xno; then PLUGINS=${PLUGINS}"x11 "; fi
ARCH=${host_cpu} ARCH=${host_cpu}
AC_ARG_ENABLE(ppro, AC_ARG_ENABLE(ppro,
@ -99,14 +95,12 @@ SYS=${host_os}
# special cases # special cases
if test x$host_os = xbeos; then if test x$host_os = xbeos; then
VOUT="dummy beos" PLUGINS="dummy beos"
AOUT="dummy beos"
fi fi
AC_SUBST(SYS) AC_SUBST(SYS)
AC_SUBST(ARCH) AC_SUBST(ARCH)
AC_SUBST(VOUT) AC_SUBST(PLUGINS)
AC_SUBST(AOUT)
AC_OUTPUT([Makefile include/config.h]) AC_OUTPUT([Makefile include/config.h])
@ -116,6 +110,5 @@ vlc configuration
vlc version : ${VLC_VERSION} vlc version : ${VLC_VERSION}
system : ${SYS} system : ${SYS}
architecture : ${ARCH} architecture : ${ARCH}
vout : ${VOUT} plugins : ${PLUGINS}
aout : ${AOUT}
" "

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
vlc (0.1.99d) unstable; urgency=low
* .deb is now more lintian-friendly
-- Samuel Hocevar <sam@via.ecp.fr> Tue, 20 Jun 2000 14:17:33 +0200
vlc (0.1.99c) unstable; urgency=low vlc (0.1.99c) unstable; urgency=low
* Caught Delete Window event in Gnome and X11 modes * Caught Delete Window event in Gnome and X11 modes

View File

@ -26,7 +26,7 @@ typedef int plugin_id_t;
typedef void* plugin_id_t; typedef void* plugin_id_t;
#endif #endif
int RequestPlugin ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name ); int RequestPlugin ( plugin_id_t * p_plugin, char * psz_name );
void TrashPlugin ( plugin_id_t p_plugin ); void TrashPlugin ( plugin_id_t p_plugin );
void * GetPluginFunction ( plugin_id_t plugin, char *name ); void * GetPluginFunction ( plugin_id_t plugin, char *name );

238
plugins/beos/aout_beos.cpp Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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();
}

View 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 );

View 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)
{
}

View 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);

View 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;
}

View 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);

View 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;
}

View 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);

View 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
View 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
View 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
View 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
View 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
View 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
View 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 );
}

View File

@ -95,9 +95,9 @@ aout_thread_t *aout_CreateThread( int *pi_status )
/* Request an interface plugin */ /* Request an interface plugin */
psz_method = main_GetPszVariable( AOUT_METHOD_VAR, AOUT_DEFAULT_METHOD ); psz_method = main_GetPszVariable( AOUT_METHOD_VAR, AOUT_DEFAULT_METHOD );
if( RequestPlugin( &p_aout->aout_plugin, "aout", psz_method ) ) if( RequestPlugin( &p_aout->aout_plugin, psz_method ) )
{ {
intf_ErrMsg( "error: could not open audio plugin aout_%s.so\n", psz_method ); intf_ErrMsg( "error: could not open audio plugin %s.so\n", psz_method );
free( p_aout ); free( p_aout );
return( NULL ); return( NULL );
} }

View File

@ -103,9 +103,9 @@ intf_thread_t* intf_Create( void )
/* Request an interface plugin */ /* Request an interface plugin */
psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD ); psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
if( RequestPlugin( &p_intf->intf_plugin, "intf", psz_method ) < 0 ) if( RequestPlugin( &p_intf->intf_plugin, psz_method ) < 0 )
{ {
intf_ErrMsg( "error: could not open interface plugin intf_%s.so\n", psz_method ); intf_ErrMsg( "error: could not open interface plugin %s.so\n", psz_method );
free( p_intf ); free( p_intf );
return( NULL ); return( NULL );
} }

View File

@ -40,20 +40,20 @@
#include "plugins.h" #include "plugins.h"
#define PLUGIN_PATH_COUNT 5 #define PLUGIN_PATH_COUNT 3
int RequestPlugin ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name ) int RequestPlugin ( plugin_id_t * p_plugin, char * psz_name )
{ {
int i_count, i_length; int i_count, i_length;
char * psz_plugin; char * psz_plugin;
char * psz_plugin_path[ PLUGIN_PATH_COUNT ] = char * psz_plugin_path[ PLUGIN_PATH_COUNT ] =
{ {
".", ".",
"plugins/aout", "plugins/vout", "plugins/intf", /* these ones should disappear */ "lib", /* this one should disappear */
PLUGIN_PATH PLUGIN_PATH
}; };
i_length = strlen( psz_mask ) + strlen( psz_name ); i_length = strlen( psz_name );
for ( i_count = 0 ; i_count < PLUGIN_PATH_COUNT ; i_count++ ) for ( i_count = 0 ; i_count < PLUGIN_PATH_COUNT ; i_count++ )
{ {
@ -61,17 +61,17 @@ int RequestPlugin ( plugin_id_t * p_plugin, char * psz_mask, char * psz_name )
char * psz_program_path; char * psz_program_path;
psz_program_path = beos_GetProgramPath(); psz_program_path = beos_GetProgramPath();
psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + strlen(psz_program_path) + i_length + 6 ); psz_plugin = malloc( strlen(psz_plugin_path[i_count]) +
sprintf( psz_plugin, "%s/%s/%s_%s.so", psz_program_path, psz_plugin_path[i_count], psz_mask, psz_name ); strlen(psz_program_path) + i_length + 5 );
#else sprintf( psz_plugin, "%s/%s/%s.so", psz_program_path,
psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 6 ); psz_plugin_path[i_count], psz_name );
sprintf( psz_plugin, "%s/%s_%s.so", psz_plugin_path[i_count], psz_mask, psz_name );
#endif
#if defined(HAVE_DLFCN_H)
*p_plugin = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
#elif defined(HAVE_IMAGE_H)
*p_plugin = load_add_on( psz_plugin ); *p_plugin = load_add_on( psz_plugin );
#else
psz_plugin = malloc( strlen(psz_plugin_path[i_count]) + i_length + 5 );
sprintf( psz_plugin, "%s/%s.so", psz_plugin_path[i_count], psz_name );
*p_plugin = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
#endif #endif
free( psz_plugin ); free( psz_plugin );

View File

@ -107,9 +107,9 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_window,
/* Request an interface plugin */ /* Request an interface plugin */
psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD ); psz_method = main_GetPszVariable( VOUT_METHOD_VAR, VOUT_DEFAULT_METHOD );
if( RequestPlugin( &p_vout->vout_plugin, "vout", psz_method ) < 0 ) if( RequestPlugin( &p_vout->vout_plugin, psz_method ) < 0 )
{ {
intf_ErrMsg( "error: could not open video plugin vout_%s.so\n", psz_method ); intf_ErrMsg( "error: could not open video plugin %s.so\n", psz_method );
free( p_vout ); free( p_vout );
return( NULL ); return( NULL );
} }

View File

@ -73,6 +73,8 @@
#define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164)) #define V_RED_COEF ((int)(1.596 * (1<<SHIFT) / 1.164))
#define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164)) #define V_GREEN_COEF ((int)(-0.813 * (1<<SHIFT) / 1.164))
//#define NODITHER
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
@ -1093,6 +1095,17 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
int * p_offset_start; /* offset array start */ int * p_offset_start; /* offset array start */
int * p_offset; /* offset array pointer */ int * p_offset; /* offset array pointer */
#ifdef NODITHER
int dither10[4] = { 0x7, 0x8, 0x7, 0x8 };
int dither11[4] = { 0x8, 0x7, 0x8, 0x7 };
int dither12[4] = { 0x7, 0x8, 0x7, 0x8 };
int dither13[4] = { 0x8, 0x7, 0x8, 0x7 };
int dither20[4] = { 0xf, 0x10, 0xf, 0x10 };
int dither21[4] = { 0x10, 0xf, 0x10, 0xf };
int dither22[4] = { 0xf, 0x10, 0xf, 0x10 };
int dither23[4] = { 0x10, 0xf, 0x10, 0xf };
#else
int dither10[4] = { 0x0, 0x8, 0x2, 0xa }; int dither10[4] = { 0x0, 0x8, 0x2, 0xa };
int dither11[4] = { 0xc, 0x4, 0xe, 0x6 }; int dither11[4] = { 0xc, 0x4, 0xe, 0x6 };
int dither12[4] = { 0x3, 0xb, 0x1, 0x9 }; int dither12[4] = { 0x3, 0xb, 0x1, 0x9 };
@ -1102,17 +1115,19 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
int dither21[4] = { 0x18, 0x8, 0x1c, 0xc }; int dither21[4] = { 0x18, 0x8, 0x1c, 0xc };
int dither22[4] = { 0x6, 0x16, 0x2, 0x12 }; int dither22[4] = { 0x6, 0x16, 0x2, 0x12 };
int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa }; int dither23[4] = { 0x1e, 0xe, 0x1a, 0xa };
/* other matrices that can be interesting, either for debugging or for effects */
#if 0
int dither[4][4] = { { 0, 8, 2, 10 }, { 12, 4, 14, 16 }, { 3, 11, 1, 9}, {15, 7, 13, 5} };
int dither[4][4] = { { 7, 8, 0, 15 }, { 0, 15, 8, 7 }, { 7, 0, 15, 8 }, { 15, 7, 8, 0 } };
int dither[4][4] = { { 0, 15, 0, 15 }, { 15, 0, 15, 0 }, { 0, 15, 0, 15 }, { 15, 0, 15, 0 } };
int dither[4][4] = { { 15, 15, 0, 0 }, { 15, 15, 0, 0 }, { 0, 0, 15, 15 }, { 0, 0, 15, 15 } };
int dither[4][4] = { { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 } };
int dither[4][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
#endif #endif
/* some other matrices that can be interesting, either for debugging
* or for effects :
*
* { { 0, 8, 2, 10 }, { 12, 4, 14, 16 }, { 3, 11, 1, 9}, {15, 7, 13, 5} }
* { { 7, 8, 0, 15 }, { 0, 15, 8, 7 }, { 7, 0, 15, 8 }, { 15, 7, 8, 0 } }
* { { 0, 15, 0, 15 }, { 15, 0, 15, 0 }, { 0, 15, 0, 15 }, { 15, 0, 15, 0 } }
* { { 15, 15, 0, 0 }, { 15, 15, 0, 0 }, { 0, 0, 15, 15 }, { 0, 0, 15, 15 } }
* { { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 }, { 8, 8, 8, 8 } }
* { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } }
*/
/* /*
* Initialize some values - i_pic_line_width will store the line skip * Initialize some values - i_pic_line_width will store the line skip
*/ */

View File

@ -1,10 +1,10 @@
Name: vlc Name: vlc
Version: 0.1.99c Version: 0.1.99d
Release: 1 Release: 1
Copyright: GPL Copyright: GPL
Url: http://www.videolan.org/ Url: http://www.videolan.org/
Group: X11/Applications/Graphics Group: X11/Applications/Graphics
Source0: http://www.videolan.org/packages/vlc-0.1.99c.tar.gz Source0: http://www.videolan.org/packages/0.1.99c/vlc-0.1.99c.tar.gz
Packager: Eric Doutreleau <Eric.doutreleau@int-evry.fr> Packager: Eric Doutreleau <Eric.doutreleau@int-evry.fr>
Buildroot: /tmp/vlc-build Buildroot: /tmp/vlc-build
@ -33,10 +33,10 @@ mkdir -p $RPM_BUILD_ROOT/usr/bin
make install prefix=$RPM_BUILD_ROOT/usr make install prefix=$RPM_BUILD_ROOT/usr
%files %files
/usr/bin/vlc %attr(-, root, root) /usr/bin/vlc
/usr/share/videolan/vlc %attr(-, root, root) /usr/share/videolan/vlc
/usr/lib/videolan %attr(-, root, root) /usr/lib/videolan
%doc AUTHORS COPYING INSTALL NEWS README doc %attr(-, root, root) %doc AUTHORS COPYING INSTALL NEWS README doc
%clean %clean
rm -rf $RPM_BUILD_ROOT rm -rf $RPM_BUILD_ROOT