Commit a4d6ff5f authored by Unknown's avatar Unknown

This commit was manufactured by cvs2svn to create tag 'v0_4_6'.

parent c8d6aecd
......@@ -87,6 +87,12 @@ C: tcastley
D: BeOS interface, BeOS Video
S: Australia
N: Stephan Assmus
E:
C: stippi
D: BeOS interface, BeOS video
S:
N: Rudolf Cornelissen
E: rag.cornelissen@inter.nl.net
D: BeOS fixes
......@@ -176,6 +182,15 @@ E: alexis.guillard@bt.com
D: IPv6
S: United Kingdom
N: Roine Gustafsson
E: roine@popstar.com
D: spudec bug fixes
N: Gerald Hansink
E: gerald.hansink@ordina.nl
D: Qt Embedded Video Output
S: Netherlands
N: Shane Harper
E: shanegh@optusnet.com.au
D: SDL plugin fixes and enhancements
......@@ -299,6 +314,10 @@ D: Many ports (Mac OS X, iPAQ, *BSD, Solaris...)
D: documentation
S: France
N: Benjamin Mironer
E: bmironer@noos.fr
D: Mac OS X fixes
N: Arkadiusz Miskiewicz
E: misiek@pld.ORG.PL
D: autoconf and Makefile patches
......@@ -320,10 +339,16 @@ E: pomel@via.ecp.fr
C: pomel
S: France
N: Remco Poortinga
E: poortinga@telin.nl
D: IPv6 multicast patch
S: Netherlands
N: Jean-Paul Saman
E: jpsaman@wxs.nl
D: libmad plug-in
D: iPAQ port
D: Familiar Linux interface
S: Netherlands
N: Steven M. Schultz
......
List of known vlc bugs $Id: BUGS,v 1.13 2002/05/20 22:30:19 sam Exp $
List of known vlc bugs $Id: BUGS,v 1.13.2.1 2002/07/11 07:58:53 tcastley Exp $
Please try to keep this file up to date. Also, grep for FIXME in the
source files for more and more bugs to fix.
......@@ -36,6 +36,9 @@ Video output:
* On-the-fly resizing when using a chroma transformation doesn't work for
all plugins. Currently it is only implemented for x11 and SDL.
* The SPU decoder does not respect the pitch of the output buffer. This
causes distortion of subtitles on GeForce cards in BeOS (and Windows I think).
Chroma transformations:
* Most chroma transformation modules completely ignore margins.
......
......@@ -2,9 +2,247 @@
# ChangeLog for vlc #
#===================#
HEAD
0.4.6
Wed, 13 Nov 2002 23:41:00 +0200
* Nothing yet.
* FAQ: changed Debian repository location to HTTP (for better upload
stats estimations on our side).
* plugins/a52/a52.c: is now the default ac3/a52 decoder (because it has a
nicer audio quality than ac3_adec).
* configure, Makefile.modules, configure.in: --enable-familiar accepts now:
--with-sdl-prefix=[PATH], --enable-gtk-prefix=[PATH] and
--enable-gpe-prefix=[PATH] to enable cross-compiling.
* plugins/familiar/familiar_callbacks.c: Bug in ReadDirectory() it results
in empty file/directory names in the user interface.
* configure.in: Added GPE support to familiar interface.
Use --with-gpe-prefix=<installation-dir> to enable it.
* ipkg/*: GPE is integrated in familiar files.
* ipkg/*: Familiar packaging files.
* include/defs.h.in: Added HAVE_GPE_INIT_H define for autodetection of
libgpewidget and GPE headerfiles.
* ALL: changes to reflect the fact that libdvdcss now needs a colon after
the DVD drive letter.
* src/misc/modules.c: plugin extension check is now case unsensitive.
* plugins/dsp/aout_dsp.c: replaced O_NONBLOCK by O_NDELAY, and put the
device back in blocking mode once open.
* plugins/network/ipv4.c: fixed a crash with multicast addresses when no
interface address is given.
* plugins/directx/vout_directx.c: fixed a nasty segfault on initialization.
* plugins/dsp/aout_dsp.c: Added O_NONBLOCK flag to the open command,
so that if /dev/dsp is used, vlc tries with other plugins (like esd).
0.4.5
Fri, 11 Oct 2002 15:37:41 +0200
* src/interface/main.c, src/misc/modules.c: added a quick hack for a
--plugin-path command line option.
* INSTALL.win32: removed note about running in administrator mode to play
a DVD.
* ./plugins/beos/InterfaceWindow.cpp: user can now drop a DVD disk icon
onto the interface or playlist window to open a DVD.
* ./plugins/x11/xcommon.c: we include Xmd.h before dpms.h (compilation fix
for Solaris).
* ALL: many BeOS fixes and enhancements.
* ALL: VLC is now compliant with MPEG-2 TS standards embedding A/52
audio. It can still read from the old VLS with --vls-backwards-compat.
* ./plugins/familiar: interface for familiar Linux.
* ./plugins/qte: Qt/embedded video output.
* ./plugins/network/ipv4.c: added a --iface-addr option to select which
interface to use for multicast sockets.
* configure.in, configure: use -mms-bitfields instead of -fnative-struct
for mingw32 gcc-3.x.
* include/interface.h, plugins/dummy/intf_dummy.c, plugins/text/logger.c,
plugins/text/rc.c: display message on Win32 explaining how to get back
to the GUI mode.
* include/threads_funcs.h, src/misc/win32_specific.c: ignore the
win9x-cv-method config option on WinNT when fast-mutex is not enabled.
* plugins/access/rtp.c: backported RTP access module from HEAD.
* plugins/access/http.c: fixed a compile issue in the HTTP plug-in.
* configure.in: fixed bug with $(QTDIR).
* plugins/filter/deinterlace.c: fixed an issue with the linear method.
0.4.4
Sun, 11 Aug 2002 01:18:13 +0200
* ./src/misc/messages.c: fixed an extremely old buffer overflow.
* ./plugins/spudec/spu_decoder.c: fixed a moronic endianness bug.
* ./plugins/dvd/dvd.c: added a --dvd-css-method config option to the dvd
plugin.
* ./include/threads_funcs.h: fixed the --fast-mutex option.
* ./plugins/directx/vout_directx.*: the directx vout plugin now uses the
IID_IDirectDrawSurface2 interface, this shouldn't break anything and we
should now support WinNT4+DirectX3. Added support for YUY2 overlays because
a few graphics cards only support this. Some code cleanup too.
* ./plugins/directx/vout_events.c: small bugfix.
* ./plugins/network/ipv6.c: attempt to fix the win32 IPv6 implementation.
Multicast should even work (untested) although we'll need to find a way to
replace if_nametoindex() tohave a fully functionnal win32 port.
* ./include/threads.h, ./include/threads_funcs.h: reverted Win32 pthread
implementation to the old code. Fixed vlc_cond_broadcast() for WinNT/2K/XP.
Additional vlc_cond_* implementations for Win9x.
* ./src/interface/main.c: renamed --fast_pthread option into --fast-mutex.
Added a--win9x-cv-method option to choose which vlc_cond_* implementation
we want on Win9x.
* ./plugins/avi/avi.c: kludge to play AVI files created by ffmpeg.
0.4.3
Fri, 26 Jul 2002 00:03:13 +0200
* ./README.MacOSX.rtf : updated README.
* ./plugins/macosx/vout_macosx.c : additional QuickTime fix, thanks to
David Eldred from Apple.
* ./include/threads_funcs.h: Win32 compilation fix.
* ./plugins/macosx/vout_macosx.m : fixed _the_ bug with QuickTime 6.
* ./plugins/access/http.c: we are now parsing the http return code and
failing cleanly if it is >= 400.
* ./plugins/mpeg_system/mpeg_es.c, ./src/input/input_ext-dec.c: fixed
a deadlock issue with demuxers waiting on p_fifo->data_lock.
* ./src/input/input_ext-plugins.c: fixed a memory leak.
* ./plugins/access/http.c: fixed a bug with HTTP/1.0 servers.
* ./src/interface/main.c: new --mtu option.
* ./configure.in: fixed nanosleep detection on some platforms.
* ./plugins/beos/*: created a wrapper class for VLC functions and
interaction, improved file and disk opening, fixed drag and drop, added
right click menu and always on top mode.
* ./plugins/beos/VideoWindow.h: fixed pop-up menu's radio mode.
* ./plugins/beos/VideoWindow.h: fixed changing workspaces problem.
* ./plugins/beos/VideoWindow.h: added a popup menu to enable changing.
0.4.2
Sun, 7 Jul 2002 22:15:33 +0200
* ./plugins/beos/VideoWindow.h: changed default bitmap to 16bit to fix
green distortion problem.
* ./plugins/network/ipv6.c: enabled IPv6 multicast support.
* ./plugins/dvd/dvd_es.c: error in selecting SPU stream.
* ./plugins/spudec/spu_decoder.c: endianness fix for subtitles colour.
* ./plugins/spudec/spu_decoder.c: little hack for preventing blank alpha
palette.
* ./plugins/spudec/spu_decoder.c: subtitle transparency support.
* ./plugins/macosx: new controls for audio output, and deinterlacing
support.
* ./plugins/macosx: fixed a bug with language and subtitle menus.
* ./plugins/access/http.c: should be more tolerant with old servers and
non-seekable streams.
* ./plugins/filter/deinterlace.c: backported new deinterlacing routines.
* ./include/threads.h, ./include/threads_funcs.h: backported the new Win32
cond_wait implementation from MAIN.
* ./plugins/gtk/gnome_callbacks.c: fixed a crash when activating preferences
from the popup menu.
0.4.1
Mon, 3 Jun 2002 23:43:35 +0200
* ./plugins/gtk/gnome.glade: added lines this #@%$! Glade had munched, fixes
a segfault in the Gnome popup menu when toggling the interface.
* ./configure.in, ./plugins/mpeg_system/mpeg_ts.c: fixed libdvbpsi handling.
* ./src/misc/configuration.c: fixed the --nofoo option handling.
* ./src/interface/main.c: fixed two compilation warnings under Solaris.
* ./plugins/avi/avi.c, ./plugins/mpeg_system/mpeg_audio.c: ES will be
selected only once.
* ./plugins/win32/waveout.c: waveOutUnprepareHeader() was never being
called. This should fix the memory leak some people reported when using
the waveout plugin.
* ./src/misc/netutils.c: factored code common to the interfaces into the
network_ChannelJoin function.
* ./plugins/mga/xmga.c, ./plugins/x11/xcommon.c, ./plugins/sdl/vout_sdl.c,
./plugins/directx/vout_events.c: we can now use keys F1 to F12 to switch
channels from the video output window.
* ./plugins/motion/motionmmx.c: MMX motion optimizations courtesy of
Vladimir Chernyshov <greengrass@writeme.com>.
* ./plugins/dvdread/dvdread.c: disabled the dvdread plugin because it
currently sucks.
* ./src/misc/configuration.c, ./src/interface/main.c: we now accept --nofoo
and --no-foo as negations for --foo. Also, the --help output is nicer.
* ./plugins/macosx/*: rewrote the net panel for OS X
* ./plugins/qnx/vout_qnx.c: QNX compilation fix.
* ./plugins/spudec/spu_decoder.c: fixed a margin bug in the SPU renderer
which caused subtitles to appear slanted in odd width windows.
* ./plugins/gtk/gtk_display.c, ./plugins/win32/mainframe.cpp: we deactivate
popup menus when no stream is being played, even in network mode.
* ./src/input/mpeg_system.c: removed unnecessarily verbose message.
* ./src/video_output/video_output.c: fixed the "picture has invalid status"
bug which might have been the cause of crashes.
* ./plugins/filter/crop.c: attempt at an automatic border cropping filter,
using "--filter crop --autocrop".
* ./vlc.spec: added missing filters to the RPM generation.
* ./plugins/macosx/*: channel change support on Mac OS X.
* ./extras/MacOSX/Resources/vlc.icns: new OS X icon, courtesy of Benjamin
Mironer <bmironer@noos.fr>.
* ./plugins/filter/crop.c: crop filter. Usage examples:
--filter crop --crop-geometry 640x480
--filter crop --crop-geometry 320x200+10+10
* ./plugins/macosx/intf_vlc_wrapper.m: fixed a bug in the chapter handling.
* ./plugins/macosx/vout_vlc_wrapper.m: more keystrokes.
* ./plugins/chroma/i420_yuy2.h: simplified the chroma code. Please test
under BeOS and QNX.
* ./plugins/macosx/intf_vlc_wrapper.m: fix for non-ASCII filenames in the
MacOS X interface, courtesy of Watanabe Go <go@dsl.gr.jp>.
* ./plugins/chroma/i420_yuy2.h: fixed an old overflow bug spotted by
Rudolf Cornelissen.
* ./plugins/chroma/i420_rgb16.c: fix for skewed display in software RV32
mode, courtesy of Pascal Levesque.
* ./plugins/beos/InterfaceWindow.h: stopped more than one playlist being
opened.
* ./plugins/beos/InterfaceWindow.cpp: fixed segfault on exit with playlist
open.
* ./plugins/beos/vout_beos.cpp: corrected size of output window.
* ./plugins/a52/a52.c, ./plugins/satellite/satellite_tools.c: compilation
fixes for Solaris.
* ./plugins/sdl/aout_sdl.c: fixed an endianness issue created by a
brain-dead developer :p
* ./plugins/win32/mainframe.cpp: the "Eject" button is enabled only after we
played a dvd or vcd.
* ./plugins/win32/mainframe.cpp: the toolbar is now flat and less cubist.
* ./plugins/win32/mainframe.cpp: got rid of the ugly slider with some winXP
skins.
* ./plugins/win32/messages.cpp: added a config option to limit the number of
messages in the log window (default is set to 500).
* ./plugins/mpeg_vdec/vpar_headers.c: don't try to deference a null
pointer.
* ./plugins/gtk/gnome.c: compilation fix.
* ./src/misc/netutils.c: removed the obsolete artificial delay when switching
channels.
* ./src/interface/intf_eject.c: added ejection code for Win32.
* ./plugins/win32/*: enabled the "Eject" button (thanks Ipkiss).
* ./include/configuration.h: changed ADD_BOOL and ADD_BOOL_WITH_SHORT config
macros to accept a default value as an argument.
* ./src/misc/configuration.c: modified the command line parsing to accept
--foo and --no-foo when a "foo" boolean config option is defined.
* ./src/interface/main.c: modified the help menu to indicate whether the
option is enabled or disabled by default.
* ./src/video_output/video_output.c: when the video output hasn't received
a new picture for a while, it redisplays the last displayed one. This will
be useful for DVD menus, but also solves the "picture becomes black when
vlc is paused" issue.
* ./plugins/dummy/dummy.c: added a CATEGORY_HINT to the config.
* ./plugins/x11/xcommon.c: small change to the ToggleFullscreen routine
to avoid a flickering during the switch.
* ./plugins/filters/*: fixed inconsistencies.
* ./plugins/win32/mainframe.dfm: new icons for the toolbar buttons.
* ./plugins/win32/network.cpp: URL can now start with "http://" in the
Network dialog box.
* ./plugins/win32/about.dfm: updated the About dialog box.
* ./include/video.h: added a b_force flag to picture_t so that we can force
the display of an image even if it is late.
* ./plugins/filter/*: filters are now configurable through the configuration
system. Patch from Sigmund Augdal <sigmunau@stud.ntnu.no>.
* ./po/vlc.pot: updated potfile.
* ./po/pl.po: polish translation, courtesy of Arkadiusz Lipiec
<A.Lipiec@elka.pw.edu.pl>.
* ./debian/control: updated Debian package descriptions.
* ./plugins/aa/aa.c: removed all palette code as it was unused.
* ./plugins/aa/aa.c: moved the aa_fastrender call from vout_Display to
vout_Render.
* ./plugins/aa/aa.c: added support for resizing and right-click menu.
* ./src/input/mpeg_system.c: in order to make ac3 working in avi file, moved
some code from ac3 decoder to mpeg_system.c. (skip 3 bytes is now done in
mpeg_system.c and no longer in ac3 audio decoder).
* src/misc/netutils.c: tests if message from vlcs begins with 'E:' or 'I:'
instead of testing 'E: ' and 'I: ' (to simplify miniVLCS).
* ./plugins/avi/avi.c, ./plugins/avi/libioRIFF.c: added more safety tests.
* ./include/inpu_ext-dec.h: added a check to fifo->b_die after the call
to BitstreamNextDataPacket() in GetChunk().
0.4.0
Thu, 23 May 2002 01:27:05 +0200
......
Frequentely Asked Questions for VideoLAN Client
$Id: FAQ,v 1.6 2002/05/02 23:06:27 massiot Exp $
$Id: FAQ,v 1.6.2.3 2002/11/13 09:45:50 sam Exp $
1. Using VLC
......@@ -55,6 +55,41 @@ You shouldn't need any option. If you're paranoid and want to control
everything, here is the exact syntax :
vlc udp:[<server>[:<server port>]][@[<bind address>][:<bind port>]]
1.8 How do I uninstall / reinstall VLC ?
--------------------------------------
Why would you want to ? ;)
If you're using a source distribution of VLC, for example a tarball or
the CVS, then you have probably used "make install" to install the
compiled VLC. To remove it just "make uninstall". If you want to
install a newer version than the currently installed one, you should
first uninstall the first one. If you deleted the original source tree,
a "make uninstall" in the newer tree should still work.
For binary packages, remove old packages first and install the new ones
(normally this should be handled automagically by your sytem).
1.9 Debian: what should I put in my sources.list for videolan ?
-------------------------------------------------------------
deb http://www.videolan.org/pub/videolan/debian $(ARCH)/
deb-src http://www.videolan.org/pub/videolan/debian sources/
1.10 How can I save my VLC configuration ?
----------------------------------------
Currently, the only way to save the configuration options in VLC is through
the preferences menu in one of the graphical user interface plugins.
1.11 Where does VLC store it's config file ?
------------------------------------------
Currently, a config file is created on a per user basis (there is no global
configuration file). If you modify the available options in VLC and save the
new configuration, then a configuration file will be created in your user
directory. The precise location of this file depends on the Operating System
you are running:
- Unices (linux, etc...): "~/.videolan/vlcrc"
- Windows: "Application Data\videolan\vlcrc"
2. Troubleshooting
......@@ -118,7 +153,48 @@ is being investigated.
2.9 Sound volume is too low
----------------------------
You can raise it with --volume commandline switch.
You can raise it with --volume commandline switch or in the preferences
window of your graphical interface.
2.10 I have no image under DirectX
----------------------------------
Check that your video card drivers are in their latest version and that
your DirectX is up-to-date.
2.11 VLC crashes
----------------
Increase the verbosity level (either in the preferences or with a
"-vvvv" command-line option) and look at the debug messages (on the
terminal or in the Messages window).
2.12 I can only play a DVD as root
----------------------------------
Check that as user you have write access to your DVD drive / device.
2.13 I'm stuck with option xxx, how do I reset options ?
------------------------------------------------------
Under unices, remove your ~/.videolan/vlcrc; for Windows, remove vlcrc
in the videolan subfolder of your "Application Data" directory.
2.14 I don't have access to the GUI anymore
-------------------------------------------
If you change the default interface module in the preferences menu to a non
GUI module (ie. to a command line interface) and then save the configuration,
the only way to get VLC to show a GUI again is to run it directly from the
command line.
For instance on Windows, you need to open a dos command box, go to the
directory where you installed VLC (usually
c:\Program Files\VideoLAN\VideoLAN Client) and then type "vlc --intf win32"
You will then be able to modify the configuration again and save it.
2.15 I have just upgraded to VLC 0.4.5, and now I don't have any sound
with the streams coming from the VLS !
---------------------------------------------------------------------------
This is a known problem. VLC 0.4.5 and later are now compliant to general
usage regarding A/52 sound, and the new behavior is incompatible with the
previous one. VLS version 0.4.0 and later now fixes this problem. If, for
a reason or another, you wish to keep VLS 0.3.3, you can still read those
streams if you launch VLC (0.4.5 or later) with --vls-backwards-compat.
3. Ports and features
......@@ -130,6 +206,9 @@ You can raise it with --volume commandline switch.
Currently it doesn't. We'd be glad to support them, but we lack technical
information on them.
3.1.2 [REMOVED]
---------------
3.2 Win32 port
3.2.2 When moving the focus to another window, VLC network input stops
......@@ -137,3 +216,20 @@ working properly !
---------------------------------------------------------------------------
This is a known problem with Win 95-class systems. Upgrade to an NT-class
system.
3.3 Planned ports
3.3.1 Do you have plans for a MacOS 9 / OS/2 / &{#!@}~ port ?
--------------------------------------------------------
No, nobody reported to be actually working on a MacOS 9 port. If you
feel like you could write it, we would of course welcome it. Currently,
the developers are more interested in supporting the latest Operating
Systems and completing the functionalities.
3.3.2 Does VLC have dxr2 / dxr3 cards support ?
---------------------------------------------
This support is currently being developed.
3.3.3 Does VLC support RTP ?
--------------------------
Yes. Just use vlc rtp:@<mcast addr>:<local port>.
......@@ -14,10 +14,8 @@ To store a debug log of the current vlc session, you can use
disable the GUI. You will end-up with a vlc.log file in your current directory.
If you want to play a DVD, run vlc and click on the Disc option in the
interface. You then have to type your drive letter in the 'Device name'
box (eg. 'D' if this is the letter for your dvdrom drive).
( !WARNING: you have to be in administrator mode (for now) on Win2k/XP or the
DVD won't play. )
interface. You then have to type your drive letter followed by a colon in
the 'Device name' box (eg. 'D:' if this is the letter for your dvdrom drive).
Building VideoLAN Client from the source code
=============================================
......
......@@ -33,6 +33,7 @@ PLUGINS_DIR := a52 \
dvd \
dvdread \
esd \
familiar \
fb \
ffmpeg \
filter \
......@@ -55,8 +56,10 @@ PLUGINS_DIR := a52 \
mpeg_vdec \
network \
ogg \
opie \
qnx \
qt \
qte \
satellite \
sdl \
spudec \
......@@ -71,6 +74,7 @@ PLUGINS_TARGETS := a52/a52 \
ac3_spdif/ac3_spdif \
access/file \
access/udp \
access/rtp \
access/http \
alsa/alsa \
arts/arts \
......@@ -94,6 +98,7 @@ PLUGINS_TARGETS := a52/a52 \
dvd/dvd \
dvdread/dvdread \
esd/esd \
familiar/familiar \
fb/fb \
ffmpeg/ffmpeg \
filter/filter_deinterlace \
......@@ -102,6 +107,7 @@ PLUGINS_TARGETS := a52/a52 \
filter/filter_distort \
filter/filter_wall \
filter/filter_clone \
filter/filter_crop \
fx/fx_scope \
ggi/ggi \
glide/glide \
......@@ -142,8 +148,10 @@ PLUGINS_TARGETS := a52/a52 \
network/ipv4 \
network/ipv6 \
ogg/vorbis \
opie/opie \
qnx/qnx \
qt/qt \
qte/qte \
satellite/satellite \
sdl/sdl \
spudec/spudec \
......@@ -342,7 +350,7 @@ dist:
echo "OK."; mkdir tmp; \
fi
# Copy directory structure in tmp
find -type d | grep -v '\(\.dep\|snapshot\|CVS\)' | while read i ; \
find . -type d | grep -v '\(\.dep\|snapshot\|CVS\)' | while read i ; \
do mkdir -p tmp/vlc/$$i ; \
done
rm -Rf tmp/vlc/tmp
......@@ -368,7 +376,7 @@ dist:
for i in Makefile.in.in POTFILES.in ; do cp po/$$i tmp/vlc/po ; done
# Copy misc files
cp FAQ AUTHORS COPYING TODO todo.pl ChangeLog* README* INSTALL* \
ABOUT-NLS BUGS MODULES vlc.spec \
ABOUT-NLS BUGS plugins/LIST vlc.spec \
Makefile Makefile.*.in Makefile.dep Makefile.modules \
configure configure.in install-sh install-win32 macosx-dmg \
config.sub config.guess aclocal.m4 mkinstalldirs \
......@@ -379,8 +387,8 @@ dist:
for file in control changelog rules ; do \
cp debian/$$file tmp/vlc/debian/ ; done
# Copy ipkg control files
for file in control rules patch ; do \
cp ipkg/$$file tmp/vlc/ipkg/ ; done
for file in ipkg/* ; do \
cp $$file tmp/vlc/ipkg/ ; done
# Copy fonts and icons
for file in share/*vlc* share/*psf; do \
cp $$file tmp/vlc/share ; done
......@@ -437,6 +445,7 @@ package-beos:
# Copy relevant files
cp vlc tmp/vlc/
strip tmp/vlc/vlc
xres -o tmp/vlc/vlc ./share/vlc_beos.rsrc
cp AUTHORS COPYING ChangeLog README FAQ TODO tmp/vlc/
for file in default8x16.psf default8x9.psf ; \
do cp share/$$file tmp/vlc/share/ ; done
......
......@@ -89,7 +89,7 @@ ifeq (,$($(module_name)_CUSTOM))
../$(module_name).a: $(EXTRA_DEP) $(OBJ_ALL)
rm -f $@
ar rc $@ $(OBJ_ALL)
$(AR) rc $@ $(OBJ_ALL)
$(RANLIB) $@
endif
......@@ -63,6 +63,7 @@ dvdread_CFLAGS = @dvdread_CFLAGS@
mpeg_ts_dvbpsi_CFLAGS = @mpeg_ts_dvbpsi_CFLAGS@
directx_CFLAGS = @directx_CFLAGS@
esd_CFLAGS = @esd_CFLAGS@
familiar_CFLAGS = @familiar_CFLAGS@
ffmpeg_CFLAGS = @ffmpeg_CFLAGS@
glide_CFLAGS = @glide_CFLAGS@
gnome_CFLAGS = @gnome_CFLAGS@
......@@ -72,7 +73,9 @@ idctaltivec_CFLAGS = @idctaltivec_CFLAGS@
mad_CFLAGS = @mad_CFLAGS@
memcpyaltivec_CFLAGS = @memcpyaltivec_CFLAGS@
motionaltivec_CFLAGS = @motionaltivec_CFLAGS@
opie_CFLAGS = @opie_CFLAGS@
qt_CFLAGS = @qt_CFLAGS@
qte_CFLAGS = @qte_CFLAGS@
sdl_CFLAGS = @sdl_CFLAGS@
x11_CFLAGS = @x11_CFLAGS@
xvideo_CFLAGS = @xvideo_CFLAGS@
......@@ -96,6 +99,7 @@ dvd_LDFLAGS = @dvd_LDFLAGS@
dvdread_LDFLAGS = @dvdread_LDFLAGS@
mpeg_ts_dvbpsi_LDFLAGS = @mpeg_ts_dvbpsi_LDFLAGS@
esd_LDFLAGS = @esd_LDFLAGS@
familiar_LDFLAGS = @familiar_LDFLAGS@
filter_distort_LDFLAGS = @filter_distort_LDFLAGS@
ffmpeg_LDFLAGS = @ffmpeg_LDFLAGS@
ggi_LDFLAGS = @ggi_LDFLAGS@
......@@ -116,8 +120,10 @@ mad_LDFLAGS = @mad_LDFLAGS@
memcpyaltivec_LDFLAGS = @memcpyaltivec_LDFLAGS@
motionaltivec_LDFLAGS = @motionaltivec_LDFLAGS@
ncurses_LDFLAGS = @ncurses_LDFLAGS@
opie_LDFLAGS = @opie_LDFLAGS@
qnx_LDFLAGS = @qnx_LDFLAGS@
qt_LDFLAGS = @qt_LDFLAGS@
qte_LDFLAGS = @qte_LDFLAGS@
rc_LDFLAGS = @rc_LDFLAGS@
sdl_LDFLAGS = @sdl_LDFLAGS@
vcd_LDFLAGS = @vcd_LDFLAGS@
......
{\rtf1\mac\ansicpg10000\cocoartf100 {\fonttbl\f0\fswiss\fcharset77 Helvetica;\f1\fswiss\fcharset77 Helvetica-Bold;\f2\fmodern\fcharset77 Courier; } {\colortbl;\red255\green255\blue255;} \margl1440\margr1440\vieww11240\viewh10380\viewkind0 \hyphauto1\hyphfactor90 \pard\tx1440\tx2880\tx4320\tx5760\tx7200\qc \f0\fs48 \cf0 VideoLAN Client (VLC) version 0.4\ Mac OS X-specific information \fs24 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural \cf0 \ \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\qj \cf0 Welcome to the VideoLAN Client ! VLC is a multi-purpose mutimedia tool : it can play DVDs and VCDs, or read a stream from the network. It also supports DivX/MPEG-4 files and is unaffected by the dreaded .avi bug which can cause choppy sound when playing DivX in Quicktime. VLC has originally been developed for GNU/Linux systems, but has been ported to numerous operating systems, including Mac OS X and Win32. The Mac OS X port is a bit young and immature, as you will notice, and there are many caveats. We are working hard to improve it, and if you think you can help us in any way, please drop us a line.\ \ You may find the following frequentely asked questions useful :\ \ \f1\b \ul 1. How do I install ? \f0\b0 \ulnone \ When you download VLC, you will end up with a vlc-0.4.0.dmg file. Doubleclick, or drop it on the application Disk Copy, to open this file. An icon will now appear on your Desktop, right beside your drive(s). Open it and drag the vlc application from the resulting window to the place where you want to install it. Most often this is /Applications.\ \ \ \f1\b \ul 2. How do use VLC? \f0\b0 \ulnone \ To use VLC, you will need to open the application first and then from the "File" menu open the file or disk, you would like to view. Doubleclicking a file will result in Quicktime trying to open it and Quicktime can not benefit from the advantages VLC brings.\ \f1\b \ul \ \ 3. How do I read an SVCD ? \f0\b0 \ulnone \ VLC is currently unable to read SVCD directly from the drive. SVCDs contain plain MPEG-2 files which can be directly read. Just copy the .dat files in the SVCD onto your hard drive, and use the "Open File" menu item in VLC (drag and drop doesn't work yet).\ \ \ \f1\b \ul 4. The video is choppy ! It's like we're dropping frames\ \f0\b0 \ulnone That's the normal behavior when the CPU isn't fast enough to decode all frames. Though there is some room for improvement, do never expect VLC to be able to decode MPEG-2 streams on a low-end G3 machine. Apple DVD player uses specific hardware accelerations from the video board of those systems, and we currently lack documentation to do the same. If you think you have information which might help us, please contact us, otherwise please don't complain about this.\ \ If VLC is slow on your G4 system, try and quit or hide all running applications. See with \f2 top -u \f0 in a terminal window which applications take the CPU. Minimizing the VLC controller window might help, too. Be aware of bouncing icons in the dock. Bounces seriously effect the performance of VLC. The same goes for any time interval process (Checking mail every 2 minutes).\ \ \ \f1\b \ul 5. I only get a black picture !\ \f0\b0 \ulnone We haven't found the reason why some people get this problem. However, users have indicated a workaround : switch your screen depth to thousands of colors instead of millions. If you think you have information to help us find the bug, please drop us a mail.\ \ \ \f1\b \ul 6. How do I hide the mouse cursor ? \f0\b0 \ulnone \ Just double-click on the movie.\ \ \ \f1\b \ul 7. How do remove VLC ? \f0\b0 \ulnone \ Simply drag VLC from the place where you have installed it, to the Trash.\ \ \ Thanks for reading this file. For additional information, subscribe to the vlc mailing list on \ul http://www.videolan.org/.\ulnone \ -- \ Christophe Massiot <massiot@via.ecp.fr>, for the VideoLAN team.\ $Id: README.MacOSX.rtf,v 1.3 2002/05/23 21:42:43 massiot Exp $}
\ No newline at end of file
{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;\f1\fswiss\fcharset77 Helvetica-Bold;\f2\fmodern\fcharset77 Courier;
}
{\colortbl;\red255\green255\blue255;}
\margl1440\margr1440\vieww11240\viewh10380\viewkind0
\hyphauto1\hyphfactor90
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\qc
\f0\fs48 \cf0 VideoLAN Client (VLC) version 0.4\
Mac OS X-specific information
\fs24 \
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\cf0 \
\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\qj
\cf0 Welcome to the VideoLAN Client ! VLC is a multi-purpose mutimedia tool : it can play DVDs and VCDs, or read a stream from the network. It also supports DivX/MPEG-4 files and is unaffected by the dreaded .avi bug which can cause choppy sound when playing DivX in Quicktime. VLC has originally been developed for GNU/Linux systems, but has been ported to numerous operating systems, including Mac OS X and Win32. The Mac OS X port is a bit young and immature, as you will notice, and there are many caveats. We are working hard to improve it, and if you think you can help us in any way, please drop us a line.\
\
You may find the following frequentely asked questions useful :\
\
\f1\b \ul 1. How do I install ?
\f0\b0 \ulnone \
When you download VLC, you will end up with a vlc-0.4.5.dmg file. Double-click, or drop it on the application Disk Copy, to open this file. An icon will now appear on your Desktop, right beside your drive(s). Open it and drag the vlc application from the resulting window to the place where you want to install it. Most often this is /Applications.\
\
\
\f1\b \ul 2. How do use VLC?
\f0\b0 \ulnone \
To use VLC, you will need to open the application first and then from the "File" menu open the file or disk, you would like to view. Doubleclicking a file will result in QuickTime Player trying to open it and QuickTime Player can not benefit from the advantages VLC brings.\
\f1\b \ul \
\
3. How do I read an SVCD ?
\f0\b0 \ulnone \
VLC is currently unable to read SVCD directly from the drive. SVCDs contain plain MPEG-2 files which can be directly read. Just copy the .dat files in the SVCD onto your hard drive, and use the "Open File" menu item in VLC (drag and drop doesn't work yet). Some SVCDs can be read if you tell VLC they're VCDs, in the "Open Disc" dialog.\
\
\
\f1\b \ul 4. The video is choppy ! It's like we're dropping frames\
\f0\b0 \ulnone That's the normal behavior when the CPU isn't fast enough to decode all frames. Though there is some room for improvement, do never expect VLC to be able to decode MPEG-2 streams on a low-end G3 machine. Apple DVD player uses specific hardware accelerations from the video board of those systems, and we currently lack documentation to do the same. If you think you have information which might help us, please contact us, otherwise please don't complain about this.\
\
If VLC is slow on your G4 system, try and quit or hide all running applications. See with
\f2 top -u
\f0 in a terminal window which applications take the CPU. Minimizing the VLC controller window might help, too. Be aware of bouncing icons in the dock. Bounces seriously effect the performance of VLC. The same goes for any time interval process (Checking mail every 2 minutes).\
\
\
\f1\b \ul 5. How do I hide the mouse cursor ?
\f0\b0 \ulnone \
Just double-click on the movie.\
\
\
\f1\b \ul 6. How do I remove VLC ?
\f0\b0 \ulnone \
Simply drag VLC from the place where you have installed it, to the Trash.\
\
\
\f1\b \ul 7. Where can I find an older version for Mac OS 9 ?\
\f0\b0 \ulnone There is no version for Mac OS 9. VLC is originally a UNIX application and has never been ported to Mac OS 9. Considering the amount of differences between Mac OS 9 and modern systems, it would require a tremendous work to port VLC. We do not plan to do it. So please don't ask.\
\
\
\f1\b \ul 8. How do I enable deinterlacing ?\
\f0\b0 \ulnone You must select the "Deinterlace" menu item
\f1\b before
\f0\b0 opening any file. If the item is selected while reading a file, nothing will happen. This is a known issue, please do not report it.\
\
\
Thanks for reading this file. For additional information, subscribe to the vlc mailing list on \ul http://www.videolan.org/.\ulnone \
-- \
Christophe Massiot <massiot@via.ecp.fr>, for the VideoLAN team.\
$Id: README.MacOSX.rtf,v 1.3.2.5 2002/10/13 22:34:21 massiot Exp $}
\ No newline at end of file
......@@ -47,7 +47,7 @@ Urgency: Wishlist
Description: Share stream information between vlc and vls
vls should send misc TS packets to let us know what the stream PID
contain, such as the language, or the subtitle palette.
Status: Todo
Status: Done (collective work)
Task: 0x59
Difficulty: Hard
......@@ -137,7 +137,7 @@ Description: Fix all known DVD playback issues
A few DVDs are still reported not to work at all. Try to find what is
causing this, have a more robust DVD input, and list all discs reported
to work flawlessly to prevent bug regression.
Status: Todo
Status: Done (collective work)
Task: 0x4e
Difficulty: Hard
......@@ -169,7 +169,7 @@ Urgency: Normal
Description: Write AVI input plugin
.avi files can use MPEG codec, if this is the case it shouldn't be
hard to read those files -> Meuuh
Status: Todo
Status: Done 23 Apr 2002 (fenrir)
Task: 0x4a
Difficulty: Medium
......@@ -459,7 +459,7 @@ Difficulty: Hard
Urgency: Wishlist
Description: MP3 support
The vlc cannot play MPEG1/2 layer 3 yet. It might be nice to fix that.
Status: Todo
Status: Done 10 May 2002 (fenrir)
Task: 0x25
Difficulty: Hard
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -4,7 +4,7 @@ AC_CONFIG_HEADER(include/defs.h)
AC_CANONICAL_SYSTEM
PACKAGE="vlc"
VERSION="0.4.0"
VERSION="0.4.6"
CODENAME=Ourumov
dnl Save CFLAGS and LDFLAGS
......@@ -20,6 +20,8 @@ AC_PROG_CPP
dnl Find the right ranlib, even when cross-compiling
AC_CHECK_TOOL(RANLIB, ranlib, :)
AC_CHECK_TOOL(STRIP, strip, :)
AC_CHECK_TOOL(AR, ar, :)
AC_CHECK_TOOL(LD, ld, :)
dnl Check for GNU make
AC_PATH_PROG(GMAKE, gmake, no)
......@@ -75,7 +77,7 @@ case x"${target_os}" in
x*mingw32*)
SYS=mingw32
AC_CHECK_TOOL(WINDRES, windres, :)
save_CFLAGS="${save_CFLAGS} -fnative-struct -D_OFF_T_ -D_off_t=long"
save_CFLAGS="${save_CFLAGS} -D_OFF_T_ -D_off_t=long"
vlc_LDFLAGS="${vlc_LDFLAGS} -mwindows -Xlinker --force-exe-suffix"
vlc_LDFLAGS="${vlc_LDFLAGS} -lws2_32 -lnetapi32"
ipv4_LDFLAGS="${ipv4_LDFLAGS} -lws2_32"
......@@ -93,7 +95,7 @@ case x"${target_os}" in
save_CFLAGS="${save_CFLAGS} -Wno-multichar -Wno-ctor-dtor-privacy -Woverloaded-virtual"
vlc_LDFLAGS="${vlc_LDFLAGS} -lbe"
plugins_LDFLAGS="${plugins_LDFLAGS} -nostart"
beos_LDFLAGS="${beos_LDFLAGS} -lbe -lgame -lroot -ltracker"
beos_LDFLAGS="${beos_LDFLAGS} -lbe -lgame -lroot -ltracker -ltranslation -lstdc++.r4"
ipv4_LDFLAGS="${ipv4_LDFLAGS} -lbind"
;;
x*)
......@@ -102,18 +104,25 @@ case x"${target_os}" in
esac
dnl Flags for plugin compilation
if test x"${SYS}" = xmingw32
then
plugins_CFLAGS="${plugins_CFLAGS} -fnative-struct"
else
if test x"${SYS}" != xmingw32; then
plugins_CFLAGS="${plugins_CFLAGS} -fPIC"
fi
dnl Check for the need to include the mingwex lib for mingw32
if test x$SYS = xmingw32
then
AC_CHECK_LIB(mingwex,opendir,
AC_CHECK_LIB(mingw32,opendir,vlc_LDFLAGS="${vlc_LDFLAGS}",
[vlc_LDFLAGS="${vlc_LDFLAGS} -lmingwex"
gtk_LDFLAGS="${gtk_LDFLAGS} -lmingwex"])
)
fi
dnl The -DSYS_FOO flag
save_CFLAGS="${save_CFLAGS} -DSYS_`echo ${SYS} | sed -e 's/-.*//' | tr 'abcdefghijklmnopqrstuvwxyz.' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`"
dnl Check for system libs needed
AC_CHECK_FUNCS(gettimeofday select strerror strtod strtol isatty vasprintf swab sigrelse getpwuid memalign posix_memalign gethostbyname2)
AC_CHECK_FUNCS(gettimeofday select strerror strtod strtol isatty vasprintf swab sigrelse getpwuid memalign posix_memalign gethostbyname2 atoll)
AC_CHECK_FUNC(connect,,[
AC_CHECK_LIB(socket,connect,
......@@ -126,13 +135,18 @@ AC_CHECK_FUNC(gethostbyname,,[
AC_CHECK_FUNC(gethostbyname,,[
AC_CHECK_LIB(bind,gethostbyname,ipv4_LDFLAGS="${ipv4_LDFLAGS} -lbind")
])
AC_CHECK_FUNCS(nanosleep,,[
have_nanosleep=0
AC_CHECK_FUNC(nanosleep,have_nanosleep=1,[
AC_CHECK_LIB(rt,nanosleep,
[vlc_LDFLAGS="${vlc_LDFLAGS} -lrt"],
[vlc_LDFLAGS="${vlc_LDFLAGS} -lrt"; have_nanosleep=1],
[AC_CHECK_LIB(posix4,nanosleep,
[vlc_LDFLAGS="${vlc_LDFLAGS} -lposix4"])]
[vlc_LDFLAGS="${vlc_LDFLAGS} -lposix4"; have_nanosleep=1])]
)
])
if test x$have_nanosleep = x1; then
AC_DEFINE(HAVE_NANOSLEEP, 1,
Define if nanosleep is available.)
fi
AC_CHECK_FUNC(inet_aton,,[
AC_CHECK_LIB(resolv,inet_aton,ipv4_LDFLAGS="${ipv4_LDFLAGS} -lresolv")
])
......@@ -188,7 +202,7 @@ AC_EGREP_HEADER(strncasecmp,strings.h,[
Define if <strings.h> defines strncasecmp.)])
dnl Check for headers
AC_CHECK_HEADERS(getopt.h strings.h)
AC_CHECK_HEADERS(stdint.h getopt.h strings.h inttypes.h sys/int_types.h)
AC_CHECK_HEADERS(sys/sockio.h fcntl.h sys/types.h sys/time.h sys/times.h)
AC_CHECK_HEADERS(dlfcn.h image.h)
AC_CHECK_HEADERS(arpa/inet.h net/if.h netinet/in.h sys/socket.h)
......@@ -329,6 +343,23 @@ if test x"$ac_cv_c_omit_frame_pointer" != x"no"; then
CFLAGS_OPTIM_NODEBUG="${CFLAGS_OPTIM_NODEBUG} -fomit-frame-pointer"
fi
dnl Check for fnative-struct or mms-bitfields support for mingw32
if test x$SYS = xmingw32
then
AC_CACHE_CHECK([if \$CC accepts -mms-bitfields],
[ac_cv_c_mms_bitfields],
[CFLAGS="${save_CFLAGS} -mms-bitfields"
AC_TRY_COMPILE([],,ac_cv_c_mms_bitfields=yes,
ac_cv_c_mms_bitfields=no)])
if test x"$ac_cv_c_mms_bitfields" != x"no"; then
save_CFLAGS="${save_CFLAGS} -mms-bitfields"
plugins_CFLAGS="${plugins_CFLAGS} -mms-bitfields"
else
save_CFLAGS="${save_CFLAGS} -fnative-struct"
plugins_CFLAGS="${plugins_CFLAGS} -fnative-struct"
fi
fi
dnl Check for Darwin plugin linking flags
AC_CACHE_CHECK([if \$CC accepts -bundle -undefined error -lcc_dynamic],
[ac_cv_ld_darwin],
......@@ -422,7 +453,12 @@ dnl
dnl default modules
dnl
BUILTINS="${BUILTINS} idct idctclassic motion imdct downmix chroma_i420_rgb chroma_i420_yuy2 chroma_i422_yuy2 chroma_i420_ymga mpeg_adec ac3_adec mpeg_vdec"
PLUGINS="${PLUGINS} dummy null rc logger mpeg_es mpeg_ps mpeg_ts mpeg_audio file udp http ipv4 memcpy lpcm_adec ac3_spdif spudec filter_deinterlace filter_invert filter_wall filter_transform filter_distort filter_clone fx_scope"
PLUGINS="${PLUGINS} dummy null rc logger mpeg_es mpeg_ps mpeg_ts mpeg_audio file memcpy lpcm_adec ac3_spdif spudec filter_deinterlace filter_invert filter_wall filter_transform filter_distort filter_clone filter_crop fx_scope"
dnl
dnl Network modules
dnl
NETWORK_MODULES="udp http rtp ipv4"
dnl
dnl Accelerated modules
......@@ -433,6 +469,11 @@ THREEDNOW_MODULES="memcpy3dn imdct3dn downmix3dn"
SSE_MODULES="imdctsse downmixsse"
ALTIVEC_MODULES="idctaltivec motionaltivec memcpyaltivec"
if test x$SYS != xbeos
then
PLUGINS="${PLUGINS} ${NETWORK_MODULES}"
fi
AC_CACHE_CHECK([if \$CC groks MMX inline assembly],
[ac_cv_mmx_inline],
[AC_TRY_COMPILE(,[void *p;asm volatile("packuswb %%mm1,%%mm2"::"r"(p));],
......@@ -719,6 +760,44 @@ if test "x$enable_dvbpsi" != "xno"
then
AC_ARG_WITH(dvbpsi,
[ --with-dvbpsi=PATH libdvbpsi headers and libraries])
AC_ARG_WITH(dvbpsi,
[ --with-dvbpsi-tree=PATH libdvbpsi tree for static linking])
case "x$with_dvbpsi" in
x|xyes)
if test "x$with_dvbpsi_tree" = x
then
AC_CHECK_HEADERS(dvbpsi/dr.h,
[ PLUGINS="${PLUGINS} mpeg_ts_dvbpsi"
mpeg_ts_dvbpsi_LDFLAGS="${mpeg_ts_dvbpsi_LDFLAGS} -ldvbpsi" ], [],
[ AC_MSG_ERROR([cannot find libdvbpsi headers]) ])
else
AC_MSG_CHECKING(for libdvbpsi.a in ${with_dvbpsi_tree})
real_dvbpsi_tree="`cd ${with_dvbpsi_tree} 2>/dev/null && pwd`"
if test "x$real_dvbpsi_tree" = x
then
dnl The given directory can't be found
AC_MSG_RESULT(no)
AC_MSG_ERROR([cannot cd to ${with_dvbpsi_tree}])
fi
if test -f "${real_dvbpsi_tree}/src/.libs/libdvbpsi.a"
then
dnl Use a custom libdvbpsi
AC_MSG_RESULT(${real_dvbpsi_tree}/src/.libs/libdvbpsi.a)
BUILTINS="${BUILTINS} mpeg_ts_dvbpsi"
mpeg_ts_dvbpsi_LDFLAGS="${mpeg_ts_dvbpsi_LDFLAGS} ${real_dvbpsi_tree}/src/.libs/libdvbpsi.a"
mpeg_ts_dvbpsi_CFLAGS="${mpeg_ts_dvbpsi_CFLAGS} -I${real_dvbpsi_tree}/src"
else
dnl The given libdvbpsi wasn't built
AC_MSG_RESULT(no)
AC_MSG_ERROR([cannot find ${real_dvbpsi_tree}/src/.libs/libdvbpsi.a, make sure you compiled libdvbpsi in ${with_dvbpsi_tree}])
fi
fi
;;
xno)
dnl Compile without dvbpsi (dlopen version, works only under Linux)
;;
*)
AC_MSG_CHECKING(for dvbpsi headers in ${with_dvbpsi})
if test "x$with_dvbpsi" = x
then
test_LDFLAGS=""
......@@ -739,6 +818,8 @@ then
fi
])
CPPFLAGS="$save_CPPFLAGS"
;;
esac
fi
dnl
......@@ -765,7 +846,7 @@ then
if test "x${SYS}" = "xdarwin"
then
# No need to add vcd to PLUGINS, Darwin is already based on FreeBSD
PLUGINS="${PLUGINS} vcd"
vcd_LDFLAGS="${vcd_LDFLAGS} -framework IOKit -framework CoreFoundation"
fi
fi
......@@ -903,7 +984,11 @@ then
dnl Use a custom libffmpeg
AC_MSG_RESULT(${real_ffmpeg_tree}/libavcodec/libavcodec.a)
BUILTINS="${BUILTINS} ffmpeg"
ffmpeg_LDFLAGS="${ffmpeg_LDFLAGS} ${real_ffmpeg_tree}/libavcodec/libavcodec.a -lm"
ffmpeg_LDFLAGS="${ffmpeg_LDFLAGS} ${real_ffmpeg_tree}/libavcodec/libavcodec.a"
if test x$SYS != xbeos
then
ffmpeg_LDFLAGS="${ffmpeg_LDFLAGS} -lm"
fi
ffmpeg_CFLAGS="${ffmpeg_CFLAGS} -I${real_ffmpeg_tree}/libavcodec"
else
dnl The given libavcodec wasn't built
......@@ -914,10 +999,18 @@ then
save_CFLAGS=$CFLAGS
save_LDFLAGS=$LDFLAGS
CFLAGS="$CFLAGS $ffmpeg_CFLAGS"
LDFLAGS="$LDFLAGS $ffmpeg_LDFLAGS -lm"
LDFLAGS="$LDFLAGS $ffmpeg_LDFLAGS"
if test x$SYS != xbeos
then
ffmpeg_LDFLAGS="${ffmpeg_LDFLAGS} -lm"
fi
AC_CHECK_LIB(avcodec, avcodec_init, [
BUILTINS="${BUILTINS} ffmpeg"
ffmpeg_LDFLAGS="${ffmpeg_LDFLAGS} -lavcodec -lm" ],
ffmpeg_LDFLAGS="${ffmpeg_LDFLAGS} -lavcodec"
if test x$SYS != xbeos
then
ffmpeg_LDFLAGS="${ffmpeg_LDFLAGS} -lm"
fi ],
[ AC_MSG_ERROR([Cannot find libavcodec library...]) ])
CFLAGS=$save_CFLAGS
LDFLAGS=$save_LDFLAGS
......@@ -1090,11 +1183,21 @@ then
AC_PATH_PROG(SDL_CONFIG, sdl-config, no, $SDL_PATH)
SDL_HEADER="SDL/SDL.h"
fi
# check for cross-compiling
SDL_PREFIX=
AC_ARG_WITH(sdl,
[ --with-sdl-prefix=PATH path to libsdl (needed for cross-compiling),
e.g use as:
--with-sdl-prefix=/usr/local/arm/2.95.3/arm-linux/usr)],[],[])
if test "x$with_sdl_prefix" != "xno" -a "x$with_sdl_prefix" != "x"
then
SDL_PREFIX="--prefix=$with_sdl_prefix"
fi
if test x${SDL_CONFIG} != xno
then
PLUGINS="${PLUGINS} sdl"
sdl_CFLAGS="${sdl_CFLAGS} `${SDL_CONFIG} --cflags`"
sdl_LDFLAGS="${sdl_LDFLAGS} `${SDL_CONFIG} --libs | sed 's,-rdynamic,,'`"
sdl_CFLAGS="${sdl_CFLAGS} `${SDL_CONFIG} ${SDL_PREFIX} --cflags`"
sdl_LDFLAGS="${sdl_LDFLAGS} `${SDL_CONFIG} ${SDL_PREFIX} --libs | sed 's,-rdynamic,,'`"
CPPFLAGS="$save_CPPFLAGS $sdl_CFLAGS"
AC_CHECK_HEADERS(${SDL_HEADER}, AC_DEFINE_UNQUOTED(SDL_INCLUDE_FILE,
<${SDL_HEADER}>, Indicate whether we should use SDL/SDL.h or SDL11/SDL.h),
......@@ -1117,6 +1220,39 @@ from http://www.libsdl.org/, or configure with --disable-sdl. Have a nice day.
fi
fi
dnl
dnl Qt Embedded module
dnl (disabled by default)
dnl
AC_ARG_ENABLE(qte,
[ --enable-qte QT Embedded support (default disabled)])
if test "x${enable_qte}" != "xno"
then
AC_ARG_WITH(qte,
[ --with-qte=PATH Qt Embedded headers and libraries])
if test "x${with_qte}" = "x"
then
test_LDFLAGS="-L${QTDIR}/lib"
test_CFLAGS="-I${QTDIR}/include"
else
test_LDFLAGS="-L${with_qte}/lib"
test_CFLAGS="-I${with_qte}/include"
fi
CPPFLAGS="${save_CPPFLAGS} ${test_CFLAGS}"
AC_CHECK_HEADERS(qt.h, [
qte_CFLAGS="${qte_CFLAGS} ${test_CFLAGS} -DQT_QWS_IPAQ -DQWS -fno-exceptions -fno-rtti"
qte_LDFLAGS="${qte_LDFLAGS} ${test_LDFLAGS} -lqpe -lqte"
if test "x${with_qte}" = "x"
then
PLUGINS="${PLUGINS} qte"
else
BUILTINS="${BUILTINS} qte"
fi
])
CPPFLAGS="${save_CPPFLAGS}"
fi
dnl
dnl Windows DirectX module
dnl
......@@ -1353,6 +1489,90 @@ then
fi
fi
dnl
dnl Familiar module uses Gtk+ library
dnl
AC_ARG_ENABLE(familiar,
[ --enable-familiar Familiar Gtk+ support (default disabled)])
if test "x${enable_familiar}" = "xyes"
then
GTK_PATH="${PATH}"
AC_ARG_WITH(gtk-config-path,
[ --with-gtk-config-path=PATH gtk-config path (default search in \$PATH)],
[ if test "x${with_gtk_config_path}" != "xno"
then
GTK_PATH="${with_gtk_config_path}:${PATH}"
fi ])
# look for gtk-config
AC_PATH_PROG(GTK12_CONFIG, gtk12-config, no, ${GTK_PATH})
GTK_CONFIG=${GTK12_CONFIG}
if test "x${GTK_CONFIG}" = "xno"
then
AC_PATH_PROG(GTK_CONFIG, gtk-config, no, ${GTK_PATH})
fi
# check for cross-compiling
GTK_PREFIX=
AC_ARG_WITH(gtk,
[ --with-gtk-prefix=PATH path to libgtk (needed for cross-compiling),
e.g use as:
--with-gtk-prefix=/usr/local/arm/2.95.3/arm-linux/usr)],[],[])
if test "x$with_gtk_prefix" != "xno" -a "x$with_gtk_prefix" != "x"
then
GTK_PREFIX="--prefix=$with_gtk_prefix"
fi
if test "x${GTK_CONFIG}" != "xno"
then
if expr 1.2.0 \> `${GTK_CONFIG} --version` >/dev/null
then
AC_MSG_ERROR([Your development package for Gtk+ is too old, you need at least version 1.2.0. Please upgrade and try again. Alternatively you can also configure with --disable-familiar.])
fi
familiar_CFLAGS="${familiar_CFLAGS} `${GTK_CONFIG} ${GTK_PREFIX} --cflags gtk gthread`"
familiar_LDFLAGS="${familiar_LDFLAGS} `${GTK_CONFIG} ${GTK_PREFIX} --libs gtk gthread | sed 's,-rdynamic,,'`"
# now look for the gtk.h header
CPPFLAGS="${save_CPPFLAGS} ${familiar_CFLAGS}"
ac_cv_gtk_headers=yes
AC_CHECK_HEADERS(gtk/gtk.h glib.h gdk/gdk.h, , [
ac_cv_gtk_headers=no
echo "Cannot find gtk development headers."
])
# now look for gpe support
AC_ARG_WITH(gpe-prefix,
[ --with-gpe-prefix=PATH gpe installation path prefix (default search in \$PATH)],[],[])
if test "x$with_gpe_prefix" != "xno" -a "x$with_gpe_prefix" != "x"
then
gpe_CFLAGS="-I$with_gpe_prefix/include"
gpe_LDFLAGS="-lXi -lgdk_pixbuf -L$with_gpe_prefix/lib"
# now look for gpe/init.h header file
save_CFLAGS=$CFLAGS
save_LDFLAGS=$LDFLAGS
# CFLAGS="${familiar_CFLAGS} ${gpe_CFLAGS}"
LDFLAGS="${familiar_LDFLAGS} ${gpe_LDFLAGS}"
CPPFLAGS="${save_CPPFLAGS} ${familiar_CFLAGS} ${gpe_CFLAGS}"
ac_cv_gpe_headers=yes
AC_CHECK_HEADERS(gpe/init.h, ,
[ ac_cv_gpe_headers=no
AC_MSG_ERROR([Cannot find development headers for libgpewidget...]) ])
AC_CHECK_LIB(gpewidget, gpe_application_init,
[ gpe_LDFLAGS="${gpe_LDFLAGS} -lgpewidget" ],
[ AC_MSG_ERROR([Cannot find libgpewidget library...]) ])
CFLAGS=$save_CFLAGS
LDFLAGS=$save_LDFLAG
if test "x${ac_cv_gpe_headers}" = "xyes"
then
familiar_CFLAGS="${familiar_CFLAGS} ${gpe_CFLAGS}"
familiar_LDFLAGS="${familiar_LDFLAGS} ${gpe_LDFLAGS}"
fi
fi
if test "x${ac_cv_gtk_headers}" = "xyes"
then
PLUGINS="${PLUGINS} familiar"
fi
CPPFLAGS="${save_CPPFLAGS}"
fi
fi
dnl
dnl Gnome module
dnl
......@@ -1415,6 +1635,34 @@ AC_ARG_ENABLE(kde,
fi
fi])
dnl
dnl Opie QT embedded module
dnl
AC_ARG_ENABLE(opie,
[ --enable-opie Qt embedded interface support (default disabled)],
[if test "x${enable_opie}" = "xyes"; then
AC_ARG_WITH(qte,
[ --with-qte=PATH Qt Embedded headers and libraries])
if test "x${with_qte}" = "x"
then
test_LDFLAGS="-L${QTDIR}/lib"
test_CFLAGS="-I${QTDIR}/include"
else
test_LDFLAGS="-L${with_qte}/lib"
test_CFLAGS="-I${with_qte}/include"
fi
PLUGINS="${PLUGINS} opie"
opie_LDFLAGS="${opie_LDFLAGS} ${test_LDFLAGS} -lqpe -lqte"
opie_CFLAGS="${opie_CFLAGS} ${test_CFLAGS}-DQT_QWS_IPAQ -DQWS -fno-exceptions -fno-rtti"
if test -x ${QTDIR}/bin/moc
then
MOC=${QTDIR}/bin/moc
else
MOC=moc
fi
fi])
dnl
dnl MacOS X module
dnl
......@@ -1666,6 +1914,7 @@ AC_SUBST(dvdread_CFLAGS)
AC_SUBST(mpeg_ts_dvbpsi_CFLAGS)
AC_SUBST(directx_CFLAGS)
AC_SUBST(esd_CFLAGS)
AC_SUBST(familiar_CFLAGS)
AC_SUBST(ffmpeg_CFLAGS)
AC_SUBST(glide_CFLAGS)
AC_SUBST(gnome_CFLAGS)
......@@ -1676,7 +1925,9 @@ AC_SUBST(macosx_CFLAGS)
AC_SUBST(mad_CFLAGS)
AC_SUBST(memcpyaltivec_CFLAGS)
AC_SUBST(motionaltivec_CFLAGS)
AC_SUBST(opie_CFLAGS)
AC_SUBST(qt_CFLAGS)
AC_SUBST(qte_CFLAGS)
AC_SUBST(sdl_CFLAGS)
AC_SUBST(x11_CFLAGS)
AC_SUBST(xvideo_CFLAGS)
......@@ -1697,6 +1948,7 @@ AC_SUBST(dvd_LDFLAGS)
AC_SUBST(dvdread_LDFLAGS)
AC_SUBST(mpeg_ts_dvbpsi_LDFLAGS)
AC_SUBST(esd_LDFLAGS)
AC_SUBST(familiar_LDFLAGS)
AC_SUBST(filter_distort_LDFLAGS)
AC_SUBST(ffmpeg_LDFLAGS)
AC_SUBST(ggi_LDFLAGS)
......@@ -1717,8 +1969,10 @@ AC_SUBST(mad_LDFLAGS)
AC_SUBST(memcpyaltivec_LDFLAGS)
AC_SUBST(motionaltivec_LDFLAGS)
AC_SUBST(ncurses_LDFLAGS)
AC_SUBST(opie_LDFLAGS)
AC_SUBST(qnx_LDFLAGS)
AC_SUBST(qt_LDFLAGS)
AC_SUBST(qte_LDFLAGS)
AC_SUBST(rc_LDFLAGS)
AC_SUBST(sdl_LDFLAGS)
AC_SUBST(vcd_LDFLAGS)
......
Package: vlc
Section: graphics
Priority: optional
Version: 0.4.0
Version: 0.4.6
Release: 1
Architecture: arm
Maintainer: Jean-Paul Saman <jpsaman@wxs.nl>, Christophe Massiot <massiot@via.ecp.fr>
Depends: libc6, task-x
Depends: libc6, task-x, sdl, libgtk1.2, libgtk2.0
Copyright: GPL
Description: VideoLAN Client is a free network-aware MPEG and DVD player.
VideoLAN is a free MPEG1/2 software solution licensed under GPL. The original
......
Package: vlc
Section: graphics
Priority: optional
Version: 0.4.5
Release: 1
Architecture: arm
Maintainer: Jean-Paul Saman <jpsaman@wxs.nl>, Christophe Massiot <massiot@via.ecp.fr>
Depends: libc6, task-x, libsdl, libgpewidget0, libgtk1.2
Copyright: GPL
Description: VideoLAN Client is a free network-aware MPEG and DVD player.
VideoLAN is a free MPEG1/2 software solution licensed under GPL. The original
source can be found on:
http://www.videolan.org/pub/videolan/vlc/
The VideoLAN Client allows to play MPEG1, MPEG2 Transport Streams and
Program Streams from the network or from a file, as well as direct DVD
playback.
Package: vlc
Section: graphics
Priority: optional
Version: 0.4.5
Release: 1
Architecture: arm
Maintainer: Jean-Paul Saman <jpsaman@wxs.nl>, Christophe Massiot <massiot@via.ecp.fr>
Depends: libc6
Copyright: GPL
Description: VideoLAN Client is a free network-aware MPEG and DVD player.
VideoLAN is a free MPEG1/2 software solution licensed under GPL. The original
source can be found on:
http://www.videolan.org/pub/videolan/vlc/
The VideoLAN Client allows to play MPEG1, MPEG2 Transport Streams and
Program Streams from the network or from a file, as well as direct DVD
playback.
#!/bin/sh
# patch for gtk-1.2 installation
#if [ ! -x /usr/lib/libgtk.so ] ; then
# ln -s /usr/lib/libgtk-1.2.so.0.9.1 /usr/lib/libgtk.so
#fi
#if [ ! -x /usr/lib/libgdk.so ] ; then
# ln -s /usr/lib/libgdk-1.2.so.0.9.1 /usr/lib/libgdk.so
#fi
#ldconfig
# update menus
if [ -x /usr/bin/update-menus ] && [ ! /usr/bin/update-menus ] ; then
exit $?;
fi
#!/bin/sh
if [ -x /usr/share/vlc ] ; then
ln -s /usr/share/vlc /opt/QtPalmtop/pics/vlc
fi
exit 0
#!/bin/sh
#if [ -x /usr/lib/libgtk.so ] ; then
# rm /usr/lib/libgtk.so
#fi
#if [ -x /usr/lib/libgdk.so ] ; then
# rm /usr/lib/libgdk.so
#fi
#ldconfig
if [ -x /usr/bin/update-menus ] && [ ! /usr/bin/update-menus ] ; then
exit $?;
fi
#!/bin/sh
[ -x /opt/QtPalmtop/pics/vlc ] || rm /opt/QtPalmtop/pics/vlc
exit 0
......@@ -19,7 +19,7 @@ build-stamp:
$(shell echo $(CONFIG_FLAGS))
# This is ugly -- I know
patch -p 0 < ipkg/patch
patch -p 0 < ipkg/sdl.patch
$(MAKE)
......
[Desktop Entry]
Comment=Multiplatform Multimedia Player
Exec=vlc.opie
Icon=vlc/vlc48x48.png
Name=VideoLAN Client
?package(vlc): \
needs=x11 \
section=Graphics \
logtitle="VideoLAN Client" \
title="VideoLAN Client" \
command="vlc" \
icon48=/usr/share/videolan/vlc48x48.png \
windowtitle="VideoLAN Client"
#!/bin/sh
export QTDIR=/opt/QtPalmtop
export LD_LIBRARY_PATH=.:/usr/X11R6/lib:/opt/QtPalmtop/lib:/lib/videolan/vlc
/usr/bin/vlc
List of vlc plugins
$Id: MODULES,v 1.3 2002/01/30 00:09:49 sam Exp $
$Id: LIST,v 1.1.2.2 2002/09/30 20:13:19 jpsaman Exp $
* ac3_adec: software AC3 decoder.
......@@ -41,6 +41,8 @@ $Id: MODULES,v 1.3 2002/01/30 00:09:49 sam Exp $
* esd: audio output module using the Esound sound daemon.
* familiar: interface for iPaq using the Gtk+ widget set.
* fb: video output module for the Linux framebuffer.
* filter_deinterlace: naive deinterlacing filter.
......@@ -123,6 +125,8 @@ $Id: MODULES,v 1.3 2002/01/30 00:09:49 sam Exp $
* qt: interface module using the Qt widget set.
* qte: video output module for Qt Embedded.
* rc: interface module using stdio.
* sdl: audio output and video output module using the SDL library.
......
/*****************************************************************************
* rtp.c: RTP access plug-in
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: rtp.c,v 1.1.2.1 2002/10/03 22:14:58 massiot Exp $
*
* Authors: Tristan Leteurtre <tooney@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 <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <videolan/vlc.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#elif defined( _MSC_VER ) && defined( _WIN32 )
# include <io.h>
#endif
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include "stream_control.h"
#include "input_ext-intf.h"
#include "input_ext-dec.h"
#include "input_ext-plugins.h"
#include "network.h"
#define RTP_HEADER_LEN 12
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static void input_getfunctions( function_list_t * );
static int Open ( struct input_thread_s * );
static ssize_t RTPNetworkRead( input_thread_t *, byte_t *, size_t );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
MODULE_CONFIG_START
MODULE_CONFIG_STOP
MODULE_INIT_START
SET_DESCRIPTION( _("RTP access module") )
ADD_CAPABILITY( ACCESS, 0 )
ADD_SHORTCUT( "rtp" )
ADD_SHORTCUT( "rtpstream" )
ADD_SHORTCUT( "rtp4" )
ADD_SHORTCUT( "rtp6" )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
input_getfunctions( &p_module->p_functions->access );
MODULE_ACTIVATE_STOP
MODULE_DEACTIVATE_START
MODULE_DEACTIVATE_STOP
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
static void input_getfunctions( function_list_t * p_function_list )
{
#define input p_function_list->functions.access
input.pf_open = Open;
input.pf_read = RTPNetworkRead;
input.pf_close = input_FDNetworkClose;
input.pf_set_program = input_SetProgram;
input.pf_set_area = NULL;
input.pf_seek = NULL;
#undef input
}
/*****************************************************************************
* Open: open the socket
*****************************************************************************/
static int Open( struct input_thread_s *p_this )
{
input_thread_t * p_input = (input_thread_t *)p_this;
input_socket_t * p_access_data;
module_t * p_network;
char * psz_network = "";
char * psz_name = strdup(p_input->psz_name);
char * psz_parser = psz_name;
char * psz_server_addr = "";
char * psz_server_port = "";
char * psz_bind_addr = "";
char * psz_bind_port = "";
int i_bind_port = 0, i_server_port = 0;
network_socket_t socket_desc;
if( config_GetIntVariable( "ipv4" ) )
{
psz_network = "ipv4";
}
if( config_GetIntVariable( "ipv6" ) )
{
psz_network = "ipv6";
}
if( *p_input->psz_access )
{
/* Find out which shortcut was used */
if( !strncmp( p_input->psz_access, "rtp6", 5 ) )
{
psz_network = "ipv6";
}
else if( !strncmp( p_input->psz_access, "rtp4", 5 ) )
{
psz_network = "ipv4";
}
}
/* Parse psz_name syntax :
* [serveraddr[:serverport]][@[bindaddr]:[bindport]] */
if( *psz_parser && *psz_parser != '@' )
{
/* Found server */
psz_server_addr = psz_parser;
while( *psz_parser && *psz_parser != ':' && *psz_parser != '@' )
{
if( *psz_parser == '[' )
{
/* IPv6 address */
while( *psz_parser && *psz_parser != ']' )
{
psz_parser++;
}
}
psz_parser++;
}
if( *psz_parser == ':' )
{
/* Found server port */
*psz_parser = '\0'; /* Terminate server name */
psz_parser++;
psz_server_port = psz_parser;
while( *psz_parser && *psz_parser != '@' )
{
psz_parser++;
}
}
}
if( *psz_parser == '@' )
{
/* Found bind address or bind port */
*psz_parser = '\0'; /* Terminate server port or name if necessary */
psz_parser++;
if( *psz_parser && *psz_parser != ':' )
{
/* Found bind address */
psz_bind_addr = psz_parser;
while( *psz_parser && *psz_parser != ':' )
{
if( *psz_parser == '[' )
{
/* IPv6 address */
while( *psz_parser && *psz_parser != ']' )
{
psz_parser++;
}
}
psz_parser++;
}
}
if( *psz_parser == ':' )
{
/* Found bind port */
*psz_parser = '\0'; /* Terminate bind address if necessary */
psz_parser++;
psz_bind_port = psz_parser;
}
}
/* Convert ports format */
if( *psz_server_port )
{
i_server_port = strtol( psz_server_port, &psz_parser, 10 );
if( *psz_parser )
{
intf_ErrMsg( "cannot parse server port near %s", psz_parser );
free(psz_name);
return( -1 );
}
}
if( *psz_bind_port )
{
i_bind_port = strtol( psz_bind_port, &psz_parser, 10 );
if( *psz_parser )
{
intf_ErrMsg( "cannot parse bind port near %s", psz_parser );
free(psz_name);
return( -1 );
}
}
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.b_pace_control = 0;
p_input->stream.b_seekable = 0;
p_input->stream.p_selected_area->i_tell = 0;
p_input->stream.i_method = INPUT_METHOD_NETWORK;
vlc_mutex_unlock( &p_input->stream.stream_lock );
if( *psz_server_addr || i_server_port )
{
intf_ErrMsg( "this RTP syntax is deprecated; the server argument will be");
intf_ErrMsg( "ignored (%s:%d). If you wanted to enter a multicast address",
psz_server_addr, i_server_port);
intf_ErrMsg( "or local port, type : %s:@%s:%d",
*p_input->psz_access ? p_input->psz_access : "udp",
psz_server_addr, i_server_port );
i_server_port = 0;
psz_server_addr = "";
}
intf_WarnMsg( 2, "opening server=%s:%d local=%s:%d",
psz_server_addr, i_server_port, psz_bind_addr, i_bind_port );
/* Prepare the network_socket_t structure */
socket_desc.i_type = NETWORK_UDP;
socket_desc.psz_bind_addr = psz_bind_addr;
socket_desc.i_bind_port = i_bind_port;
socket_desc.psz_server_addr = psz_server_addr;
socket_desc.i_server_port = i_server_port;
/* Find an appropriate network module */
p_network = module_Need( MODULE_CAPABILITY_NETWORK, psz_network,
&socket_desc );
free(psz_name);
if( p_network == NULL )
{
return( -1 );
}
module_Unneed( p_network );
p_access_data = malloc( sizeof(input_socket_t) );
p_input->p_access_data = (void *)p_access_data;
if( p_access_data == NULL )
{
intf_ErrMsg( "out of memory" );
return( -1 );
}
p_access_data->i_handle = socket_desc.i_handle;
p_input->i_mtu = socket_desc.i_mtu;
p_input->psz_demux = "ts";
return( 0 );
}
/*****************************************************************************
* RTPNetworkRead : Read for the network, and parses the RTP header
*****************************************************************************/
static ssize_t RTPNetworkRead( input_thread_t * p_input, byte_t * p_buffer,
size_t i_len )
{
int i_rtp_version;
int i_CSRC_count;
int i_payload_type;
byte_t * p_tmp_buffer = alloca( p_input->i_mtu );
/* Get the raw data from the socket.
* We first assume that RTP header size is the classic RTP_HEADER_LEN. */
ssize_t i_ret = input_FDNetworkRead( p_input, p_tmp_buffer,
p_input->i_mtu );
if (!i_ret) return 0;
/* Parse the header and make some verifications.
* See RFC 1889 & RFC 2250. */
i_rtp_version = ( p_tmp_buffer[0] & 0xC0 ) >> 6;
i_CSRC_count = ( p_tmp_buffer[0] & 0x0F );
i_payload_type = ( p_tmp_buffer[1] & 0x7F );
if ( i_rtp_version != 2 )
intf_WarnMsg( 1, "RTP version is %u, should be 2", i_rtp_version );
if ( i_payload_type != 33 )
intf_WarnMsg( 1, "RTP payload type is %u, only 33 (Mpeg2-TS) " \
"is supported", i_payload_type );
/* Return the packet without the RTP header. */
i_ret -= ( RTP_HEADER_LEN + 4 * i_CSRC_count );
if ( i_ret > i_len )
{
/* This should NOT happen. */
intf_WarnMsg( 1, "RTP input trashing %d bytes", i_ret - i_len );
i_ret = i_len;
}
FAST_MEMCPY( p_buffer,
p_tmp_buffer + RTP_HEADER_LEN + 4 * i_CSRC_count,
i_ret );
return i_ret;
}
/*****************************************************************************
* ListViews.h: BeOS interface list view class implementation
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ListViews.cpp,v 1.1.2.1 2002/09/29 12:06:08 titer Exp $
*
* Authors: Stephan Aßmus <stippi@yellowbites.com>
*
* 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.
*****************************************************************************/
#include <stdio.h>
#include <Bitmap.h>
#include <String.h>
extern "C"
{
#include <videolan/vlc.h>
#include "stream_control.h"
#include "interface.h"
#include "input_ext-intf.h"
}
#include "InterfaceWindow.h"
#include "ListViews.h"
#include "MsgVals.h"
#include "intf_vlc_wrapper.h"
#define MAX_DRAG_HEIGHT 200.0
#define ALPHA 170
#define TEXT_OFFSET 20.0
/*****************************************************************************
* PlaylistItem class
*****************************************************************************/
PlaylistItem::PlaylistItem( const char *name )
: BStringItem( name )
{
}
PlaylistItem::~PlaylistItem()
{
}
/*****************************************************************************
* PlaylistItem::DrawItem
*****************************************************************************/
void
PlaylistItem::Draw( BView *owner, BRect frame, bool tintedLine,
bool active, bool playing )
{
rgb_color color = (rgb_color){ 255, 255, 255, 255 };
if ( tintedLine )
color = tint_color( color, 1.04 );
// background
if ( IsSelected() )
color = tint_color( color, B_DARKEN_2_TINT );
owner->SetLowColor( color );
owner->FillRect( frame, B_SOLID_LOW );
// label
owner->SetHighColor( 0, 0, 0, 255 );
font_height fh;
owner->GetFontHeight( &fh );
BString truncatedString( Text() );
owner->TruncateString( &truncatedString, B_TRUNCATE_MIDDLE,
frame.Width() - TEXT_OFFSET - 4.0 );
owner->DrawString( truncatedString.String(),
BPoint( frame.left + TEXT_OFFSET,
frame.top + fh.ascent + 1.0 ) );
// playmark
if ( active )
{
rgb_color black = (rgb_color){ 0, 0, 0, 255 };
rgb_color green = (rgb_color){ 0, 255, 0, 255 };
BRect r( 0.0, 0.0, 10.0, 10.0 );
r.OffsetTo( frame.left + 4.0,
ceilf( ( frame.top + frame.bottom ) / 2.0 ) - 5.0 );
if ( !playing )
green = tint_color( color, B_DARKEN_1_TINT );
rgb_color lightGreen = tint_color( green, B_LIGHTEN_2_TINT );
rgb_color darkGreen = tint_color( green, B_DARKEN_2_TINT );
BPoint arrow[3];
arrow[0] = r.LeftTop();
arrow[1] = r.LeftBottom();
arrow[2].x = r.right;
arrow[2].y = ( r.top + r.bottom ) / 2.0;
owner->BeginLineArray( 6 );
// black outline
owner->AddLine( arrow[0], arrow[1], black );
owner->AddLine( BPoint( arrow[1].x + 1.0, arrow[1].y - 1.0 ),
arrow[2], black );
owner->AddLine( arrow[0], arrow[2], black );
// inset arrow
arrow[0].x += 1.0;
arrow[0].y += 2.0;
arrow[1].x += 1.0;
arrow[1].y -= 2.0;
arrow[2].x -= 2.0;
// highlights and shadow
owner->AddLine( arrow[1], arrow[2], darkGreen );
owner->AddLine( arrow[0], arrow[2], lightGreen );
owner->AddLine( arrow[0], arrow[1], lightGreen );
owner->EndLineArray();
// fill green
arrow[0].x += 1.0;
arrow[0].y += 1.0;
arrow[1].x += 1.0;
arrow[1].y -= 1.0;
arrow[2].x -= 2.0;
owner->SetHighColor( green );
owner->FillPolygon( arrow, 3 );
}
}
/*****************************************************************************
* DragSortableListView class
*****************************************************************************/
DragSortableListView::DragSortableListView( BRect frame, const char* name,
list_view_type type, uint32 resizingMode,
uint32 flags )
: BListView( frame, name, type, resizingMode, flags ),
fDropIndex( -1 )
{
SetViewColor( B_TRANSPARENT_32_BIT );
}
DragSortableListView::~DragSortableListView()
{
}
/*****************************************************************************
* DragSortableListView::Draw
*****************************************************************************/
void
DragSortableListView::Draw( BRect updateRect )
{
int32 firstIndex = IndexOf( updateRect.LeftTop() );
int32 lastIndex = IndexOf( updateRect.RightBottom() );
if ( firstIndex >= 0 )
{
if ( lastIndex < firstIndex )
lastIndex = CountItems() - 1;
// update rect contains items
BRect r( updateRect );
for ( int32 i = firstIndex; i <= lastIndex; i++)
{
r = ItemFrame( i );
DrawListItem( this, i, r );
}
updateRect.top = r.bottom + 1.0;
if ( updateRect.IsValid() )
{
SetLowColor( 255, 255, 255, 255 );
FillRect( updateRect, B_SOLID_LOW );
}
}
else
{
SetLowColor( 255, 255, 255, 255 );
FillRect( updateRect, B_SOLID_LOW );
}
}
/*****************************************************************************
* DragSortableListView::InitiateDrag
*****************************************************************************/
bool
DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
{
return false;
bool success = false;
BListItem* item = ItemAt( CurrentSelection( 0 ) );
if ( !item )
{
// workarround a timing problem
Select( index );
item = ItemAt( index );
}
if ( item )
{
// create drag message
BMessage msg( B_SIMPLE_DATA );
MakeDragMessage( &msg );
// figure out drag rect
float width = Bounds().Width();
BRect dragRect(0.0, 0.0, width, -1.0);
// figure out, how many items fit into our bitmap
int32 numItems;
bool fade = false;
for (numItems = 0; BListItem* item = ItemAt( CurrentSelection( numItems ) ); numItems++) {
dragRect.bottom += item->Height();
if ( dragRect.Height() > MAX_DRAG_HEIGHT ) {
fade = true;
dragRect.bottom = MAX_DRAG_HEIGHT;
numItems++;
break;
}
}
BBitmap* dragBitmap = new BBitmap( dragRect, B_RGB32, true );
if ( dragBitmap && dragBitmap->IsValid() ) {
if ( BView *v = new BView( dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW ) ) {
dragBitmap->AddChild( v );
dragBitmap->Lock();
BRect itemBounds( dragRect) ;
itemBounds.bottom = 0.0;
// let all selected items, that fit into our drag_bitmap, draw
for ( int32 i = 0; i < numItems; i++ ) {
int32 index = CurrentSelection( i );
BListItem* item = ItemAt( index );
itemBounds.bottom = itemBounds.top + item->Height() - 1.0;
if ( itemBounds.bottom > dragRect.bottom )
itemBounds.bottom = dragRect.bottom;
DrawListItem( v, index, itemBounds );
itemBounds.top = itemBounds.bottom + 1.0;
}
// make a black frame arround the edge
v->SetHighColor( 0, 0, 0, 255 );
v->StrokeRect( v->Bounds() );
v->Sync();
uint8 *bits = (uint8 *)dragBitmap->Bits();
int32 height = (int32)dragBitmap->Bounds().Height() + 1;
int32 width = (int32)dragBitmap->Bounds().Width() + 1;
int32 bpr = dragBitmap->BytesPerRow();
if (fade) {
for ( int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr ) {
uint8 *line = bits + 3;
for (uint8 *end = line + 4 * width; line < end; line += 4)
*line = ALPHA;
}
for ( int32 y = height - ALPHA / 2; y < height; y++, bits += bpr ) {
uint8 *line = bits + 3;
for (uint8 *end = line + 4 * width; line < end; line += 4)
*line = (height - y) << 1;
}
} else {
for ( int32 y = 0; y < height; y++, bits += bpr ) {
uint8 *line = bits + 3;
for (uint8 *end = line + 4 * width; line < end; line += 4)
*line = ALPHA;
}
}
dragBitmap->Unlock();
success = true;
}
}
if (success)
DragMessage( &msg, dragBitmap, B_OP_ALPHA, BPoint( 0.0, 0.0 ) );
else {
delete dragBitmap;
DragMessage( &msg, dragRect.OffsetToCopy( point ), this );
}
}
return success;
}
/*****************************************************************************
* DragSortableListView::WindowActivated
*****************************************************************************/
void
DragSortableListView::WindowActivated( bool active )
{
// workarround for buggy focus indication of BScrollView
if ( BView* view = Parent() )
view->Invalidate();
}
/*****************************************************************************
* DragSortableListView::MessageReceived
*****************************************************************************/
void
DragSortableListView::MessageReceived(BMessage* message)
{
BListItem *item = NULL;
DragSortableListView *list = NULL;
if ( message->FindPointer( "list", (void **)&list ) == B_OK
&& list == this )
{
int32 count = CountItems();
if ( fDropIndex < 0 || fDropIndex > count )
fDropIndex = count;
bool copy = ( modifiers() & B_SHIFT_KEY );
for ( int32 i = 0; message->FindPointer( "item", i, (void **)&item ) == B_OK; i++ )
{
if ( HasItem( item ) )
{
BListItem* itemToAdd = NULL;
int32 index = IndexOf( item );
if ( copy )
{
// add cloned item
itemToAdd = CloneItem( index );
Deselect( IndexOf( item ) );
}
else
{
// drag sort
if ( index < fDropIndex )
fDropIndex--;
if ( RemoveItem( item ) )
itemToAdd = item;
}
if ( itemToAdd )
{
if ( AddItem( itemToAdd, fDropIndex ) )
Select( IndexOf( itemToAdd ), true );
else
delete itemToAdd;
}
}
fDropIndex++;
}
fDropIndex = -1;
} else
BListView::MessageReceived( message );
}
/*****************************************************************************
* DragSortableListView::MouseMoved
*****************************************************************************/
void
DragSortableListView::MouseMoved(BPoint where, uint32 transit, const BMessage *msg)
{
if ( msg && msg->what == B_SIMPLE_DATA )
{
switch ( transit )
{
case B_ENTERED_VIEW:
{
// draw drop mark
BRect r(ItemFrame(0L));
where.y += r.Height() / 2.0;
int32 count = CountItems();
bool found = false;
for (int32 index = 0; index <= count; index++)
{
r = ItemFrame(index);
if (r.Contains(where))
{
SetHighColor(255, 0, 0, 255);
StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
r.top++;
StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
fDropIndex = index;
found = true;
break;
}
}
if (found)
break;
// mouse is after last item
fDropIndex = count;
r = Bounds();
if (count > 0)
r.top = ItemFrame(count - 1).bottom + 1.0;
SetHighColor(255, 0, 0, 255);
StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
r.top++;
StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
break;
}
case B_INSIDE_VIEW:
{
// draw drop mark and invalidate previous drop mark
BRect r(ItemFrame(0L));
where.y += r.Height() / 2.0;
int32 count = CountItems();
// mouse still after last item?
if (fDropIndex == count)
{
r = Bounds();
if (count > 0)
r.top = ItemFrame(count - 1).bottom + 1.0;
if (r.Contains(where))
break;
else
{
r.bottom = r.top + 2.0;
Invalidate(r);
}
}
// mouse still over same item?
if (ItemFrame(fDropIndex).Contains(where))
break;
else
InvalidateItem(fDropIndex);
// mouse over new item
bool found = false;
for (int32 index = 0; index <= count; index++)
{
r = ItemFrame(index);
if (r.Contains(where))
{
SetHighColor(255, 0, 0, 255);
StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
r.top++;
StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
fDropIndex = index;
found = true;
break;
}
}
if (found)
break;
// mouse is after last item
fDropIndex = count;
r = Bounds();
if (count > 0)
r.top = ItemFrame(count - 1).bottom + 1.0;
SetHighColor(255, 0, 0, 255);
StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
r.top++;
StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
break;
}
case B_EXITED_VIEW:
{
int32 count = CountItems();
if (count > 0)
{
if (fDropIndex == count)
{
BRect r(Bounds());
r.top = ItemFrame(count - 1).bottom + 1.0;
r.bottom = r.top + 2.0;
Invalidate(r);
}
else
InvalidateItem(fDropIndex);
}
break;
}
case B_OUTSIDE_VIEW:
break;
}
}
else
BListView::MouseMoved(where, transit, msg);
}
/*****************************************************************************
* DragSortableListView::MouseUp
*****************************************************************************/
void
DragSortableListView::MouseUp( BPoint where )
{
// remove drop mark
if ( fDropIndex >= 0 && fDropIndex < CountItems() )
InvalidateItem( fDropIndex );
BListView::MouseUp( where );
}
/*****************************************************************************
* DragSortableListView::DrawItem
*****************************************************************************/
void
DragSortableListView::DrawItem( BListItem *item, BRect itemFrame, bool complete )
{
DrawListItem( this, IndexOf( item ), itemFrame );
}
/*****************************************************************************
* PlaylistView class
*****************************************************************************/
PlaylistView::PlaylistView( BRect frame, InterfaceWindow* mainWindow )
: DragSortableListView( frame, "playlist listview",
B_MULTIPLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES,
B_WILL_DRAW | B_NAVIGABLE | B_PULSE_NEEDED
| B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE ),
fCurrentIndex( -1 ),
fPlaying( false ),
fMainWindow( mainWindow )
{
}
PlaylistView::~PlaylistView()
{
}
/*****************************************************************************
* PlaylistView::AttachedToWindow
*****************************************************************************/
void
PlaylistView::AttachedToWindow()
{
// get pulse message every two frames
Window()->SetPulseRate(80000);
}
/*****************************************************************************
* PlaylistView::MouseDown
*****************************************************************************/
void
PlaylistView::MouseDown( BPoint where )
{
int32 clicks = 1;
Window()->CurrentMessage()->FindInt32( "clicks", &clicks );
bool handled = false;
for ( int32 i = 0; PlaylistItem* item = (PlaylistItem*)ItemAt( i ); i++ )
{
BRect r = ItemFrame( i );
if ( r.Contains( where ) )
{
if ( clicks == 2 )
{
Intf_VLCWrapper::playlistJumpTo( i );
handled = true;
}
else if ( i == fCurrentIndex )
{
r.right = r.left + TEXT_OFFSET;
if ( r.Contains ( where ) )
{
fMainWindow->PostMessage( PAUSE_PLAYBACK );
InvalidateItem( i );
handled = true;
}
}
break;
}
}
if ( !handled )
DragSortableListView::MouseDown(where);
}
/*****************************************************************************
* PlaylistView::KeyDown
*****************************************************************************/
void
PlaylistView::KeyDown( const char* bytes, int32 numBytes )
{
if (numBytes < 1)
return;
if ( ( bytes[0] == B_BACKSPACE ) || ( bytes[0] == B_DELETE ) )
{
int32 i = CurrentSelection();
if ( BListItem *item = ItemAt( i ) )
{
/* if ( RemoveItem( item ) )
{
delete item;
Select( i + 1 );
}*/
}
}
DragSortableListView::KeyDown( bytes, numBytes );
}
/*****************************************************************************
* PlaylistView::Pulse
*****************************************************************************/
void
PlaylistView::Pulse()
{
if (fMainWindow->IsStopped())
SetPlaying( false );
}
/*****************************************************************************
* PlaylistView::CloneItem
*****************************************************************************/
BListItem*
PlaylistView::CloneItem( int32 atIndex ) const
{
BListItem* clone = NULL;
if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( atIndex ) ) )
clone = new PlaylistItem( item->Text() );
return clone;
}
/*****************************************************************************
* PlaylistView::DrawListItem
*****************************************************************************/
void
PlaylistView::DrawListItem( BView* owner, int32 index, BRect frame ) const
{
if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( index ) ) )
item->Draw( owner, frame, index % 2, index == fCurrentIndex, fPlaying );
}
/*****************************************************************************
* PlaylistView::MakeDragMessage
*****************************************************************************/
void
PlaylistView::MakeDragMessage( BMessage* message ) const
{
if ( message )
{
message->AddPointer( "list", (void*)this );
for ( int32 i = 0; BListItem* item = ItemAt( CurrentSelection( i ) ); i++ )
message->AddPointer( "item", (void*)item );
}
}
/*****************************************************************************
* PlaylistView::SetCurrent
*****************************************************************************/
void
PlaylistView::SetCurrent( int32 index )
{
if ( fCurrentIndex != index )
{
InvalidateItem( fCurrentIndex );
fCurrentIndex = index;
InvalidateItem( fCurrentIndex );
}
}
/*****************************************************************************
* PlaylistView::SetPlaying
*****************************************************************************/
void
PlaylistView::SetPlaying( bool playing )
{
if ( fPlaying != playing )
{
fPlaying = playing;
InvalidateItem( fCurrentIndex );
}
}
/*****************************************************************************
* ListViews.h: BeOS interface list view class prototype
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ListViews.h,v 1.1.2.1 2002/09/29 12:06:08 titer Exp $
*
* Authors: Stephan Aßmus <stippi@yellowbites.com>
*
* 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.
*****************************************************************************/
#ifndef LIST_VIEWS_H
#define LIST_VIEWS_H
#include <ListItem.h>
#include <ListView.h>
class InterfaceWindow;
// PlaylistItem
class PlaylistItem : public BStringItem
{
public:
PlaylistItem( const char* name );
virtual ~PlaylistItem();
virtual void Draw( BView* owner, BRect frame,
bool tintedLine,
bool active = false,
bool playing = false );
};
// DragSortableListView
class DragSortableListView : public BListView
{
public:
DragSortableListView( BRect frame,
const char* name,
list_view_type type
= B_SINGLE_SELECTION_LIST,
uint32 resizingMode
= B_FOLLOW_LEFT
| B_FOLLOW_TOP,
uint32 flags
= B_WILL_DRAW
| B_NAVIGABLE
| B_FRAME_EVENTS );
virtual ~DragSortableListView();
// BListView
virtual void Draw( BRect updateRect );
virtual bool InitiateDrag( BPoint point, int32 index,
bool wasSelected );
virtual void MessageReceived( BMessage* message );
virtual void MouseMoved( BPoint where, uint32 transit,
const BMessage* dragMessage );
virtual void MouseUp( BPoint where );
virtual void WindowActivated( bool active );
virtual void DrawItem( BListItem *item, BRect itemFrame,
bool complete = false);
// DragSortableListView
virtual BListItem* CloneItem( int32 atIndex ) const = 0;
virtual void DrawListItem( BView* owner, int32 index,
BRect itemFrame ) const = 0;
virtual void MakeDragMessage( BMessage* message ) const = 0;
private:
int32 fDropIndex;
};
// PlaylistView
class PlaylistView : public DragSortableListView
{
public:
PlaylistView( BRect frame,
InterfaceWindow* mainWindow );
~PlaylistView();
// BListView
virtual void AttachedToWindow();
virtual void MouseDown( BPoint where );
virtual void KeyDown( const char* bytes, int32 numBytes );
virtual void Pulse();
// DragSortableListView
virtual BListItem* CloneItem( int32 atIndex ) const;
virtual void DrawListItem( BView* owner, int32 index,
BRect itemFrame ) const;
virtual void MakeDragMessage( BMessage* message ) const;
// PlaylistView
void SetCurrent( int32 index );
void SetPlaying( bool playing );
private:
int32 fCurrentIndex;
bool fPlaying;
InterfaceWindow* fMainWindow;
};
#endif // LIST_VIEWS_H
/*****************************************************************************
* intf_vlc_wrapper.h: BeOS plugin for vlc (derived from MacOS X port )
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: intf_vlc_wrapper.cpp,v 1.1.2.4 2002/10/09 15:29:51 stippi Exp $
*
* Authors: Florian G. Pflug <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
* Tony Casltey <tony@castley.net>
* Stephan Aßmus <stippi@yellowbites.com>
*
* 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.
*****************************************************************************/
/* VLC headers */
#include <SupportKit.h>
extern "C"
{
#include <videolan/vlc.h>
#include "stream_control.h"
#include "input_ext-intf.h"
#include "interface.h"
#include "intf_playlist.h"
#include "audio_output.h"
#include "video.h"
#include "video_output.h"
}
#include "intf_vlc_wrapper.h"
bool Intf_VLCWrapper::manage()
{
p_main->p_intf->pf_manage( p_main->p_intf );
if ( p_main->p_intf->b_die )
{
// exit the lot
return( 1 );
}
if ( p_input_bank->pp_input[0] != NULL )
{
vlc_mutex_lock( &p_input_bank->pp_input[0]->stream.stream_lock );
if( !p_input_bank->pp_input[0]->b_die )
{
/* New input or stream map change */
if( p_input_bank->pp_input[0]->stream.b_changed ||
p_main->p_intf->p_sys->i_part !=
p_input_bank->pp_input[0]->stream.p_selected_area->i_part )
{
setupMenus();
p_main->p_intf->p_sys->b_disabled_menus = 0;
}
}
vlc_mutex_unlock( &p_input_bank->pp_input[0]->stream.stream_lock );
}
else if ( !p_main->p_intf->p_sys->b_disabled_menus )
{
setupMenus();
p_main->p_intf->p_sys->b_disabled_menus = 1;
}
return( 0 );
}
void Intf_VLCWrapper::quit()
{
p_main->p_intf->b_die = 1;
}
/* playlist control */
bool Intf_VLCWrapper::playlistPlay()
{
if( p_input_bank->pp_input[0] != NULL )
{
input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
playlistLock();
p_main->p_playlist->b_stopped = 0;
playlistUnlock();
p_main->p_intf->p_sys->b_mute = 0;
}
else
{
playlistLock();
if( p_main->p_playlist->b_stopped )
{
if( p_main->p_playlist->i_size )
{
playlistUnlock();
intf_PlaylistJumpto( p_main->p_playlist,
p_main->p_playlist->i_index - 1 );
p_main->p_intf->p_sys->b_mute = 0;
}
else
playlistUnlock();
}
else
playlistUnlock();
}
return( true );
}
void Intf_VLCWrapper::playlistPause()
{
if ( p_input_bank->pp_input[0] != NULL )
{
input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PAUSE );
playlistLock();
p_main->p_playlist->b_stopped = 0;
playlistUnlock();
}
}
void Intf_VLCWrapper::playlistStop()
{
if( p_input_bank->pp_input[0] != NULL )
{
/* end playing item */
input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_END );
/* update playlist */
playlistLock();
p_main->p_playlist->b_stopped = 1;
playlistUnlock();
}
}
void Intf_VLCWrapper::playlistNext()
{
playlistJumpTo( playlistCurrentPos() + 1 );
}
void Intf_VLCWrapper::playlistPrev()
{
playlistJumpTo( playlistCurrentPos() - 1 );
}
void Intf_VLCWrapper::playlistJumpTo( int pos )
{
// sanity checks
if ( pos < 0 )
pos = 0;
int size = playlistSize();
if (pos >= size)
pos = size - 1;
// weird hack
if( p_input_bank->pp_input[0] != NULL )
pos--;
// stop current stream
playlistStop();
// modify current position in playlist
playlistLock();
p_main->p_playlist->i_index = pos;
playlistUnlock();
// start playing
playlistPlay();
}
int Intf_VLCWrapper::playlistCurrentPos()
{
playlistLock();
int pos = p_main->p_playlist->i_index;
playlistUnlock();
return pos;
}
int Intf_VLCWrapper::playlistSize()
{
playlistLock();
int size = p_main->p_playlist->i_size;
playlistUnlock();
return size;
}
void Intf_VLCWrapper::playlistLock()
{
vlc_mutex_lock( &p_main->p_playlist->change_lock );
}
void Intf_VLCWrapper::playlistUnlock()
{
vlc_mutex_unlock( &p_main->p_playlist->change_lock );
}
void Intf_VLCWrapper::getNavCapabilities( bool* canSkipPrev,
bool* canSkipNext )
{
if ( canSkipPrev && canSkipNext )
{
// init the parameters
*canSkipPrev = false;
*canSkipNext = false;
// get playlist info
playlistLock();
int pos = p_main->p_playlist->i_index;
int size = p_main->p_playlist->i_size;
playlistUnlock();
input_thread_s* input = p_input_bank->pp_input[0];
// see if we have got a stream going
if ( input )
{
vlc_mutex_lock( &input->stream.stream_lock );
bool hasTitles = input->stream.i_area_nb > 1;
int numChapters = input->stream.p_selected_area->i_part_nb;
bool hasChapters = numChapters > 1;
// first, look for chapters
if ( hasChapters )
{
*canSkipPrev = input->stream.p_selected_area->i_part > 1;
*canSkipNext = input->stream.p_selected_area->i_part <
input->stream.p_selected_area->i_part_nb - 1;
}
// if one of the skip capabilities is false,
// make it depend on titles instead
if ( !*canSkipPrev && hasTitles )
*canSkipPrev = input->stream.p_selected_area->i_id > 1;
if ( !*canSkipNext && hasTitles )
*canSkipNext = input->stream.p_selected_area->i_id < input->stream.i_area_nb - 1;
vlc_mutex_unlock( &input->stream.stream_lock );
}
// last but not least, make capabilities depend on playlist
if ( !*canSkipPrev )
*canSkipPrev = pos > 0;
if ( !*canSkipNext )
*canSkipNext = pos < size - 1;
}
}
void Intf_VLCWrapper::navigatePrev()
{
bool hasSkiped = false;
input_thread_s* input = p_input_bank->pp_input[0];
// see if we have got a stream going
if ( input )
{
// get information from stream (lock it while looking at it)
vlc_mutex_lock( &input->stream.stream_lock );
int currentTitle = input->stream.p_selected_area->i_id;
int currentChapter = input->stream.p_selected_area->i_part;
int numTitles = input->stream.i_area_nb;
bool hasTitles = numTitles > 1;
int numChapters = input->stream.p_selected_area->i_part_nb;
bool hasChapters = numChapters > 1;
vlc_mutex_unlock( &input->stream.stream_lock );
// first, look for chapters
if ( hasChapters )
{
// skip to the previous chapter
currentChapter--;
if ( currentChapter >= 1 )
{
toggleChapter( currentChapter );
hasSkiped = true;
}
}
// if we couldn't skip chapters, try titles instead
if ( !hasSkiped && hasTitles )
{
// skip to the previous title
currentTitle--;
// disallow area 0 since it is used for video_ts.vob
if( currentTitle > 0 )
{
toggleTitle(currentTitle);
hasSkiped = true;
}
}
}
// last but not least, skip to previous file
if ( !hasSkiped )
playlistPrev();
}
void Intf_VLCWrapper::navigateNext()
{
bool hasSkiped = false;
input_thread_s* input = p_input_bank->pp_input[0];
// see if we have got a stream going
if ( input )
{
// get information from stream (lock it while looking at it)
vlc_mutex_lock( &input->stream.stream_lock );
int currentTitle = input->stream.p_selected_area->i_id;
int currentChapter = input->stream.p_selected_area->i_part;
int numTitles = input->stream.i_area_nb;
bool hasTitles = numTitles > 1;
int numChapters = input->stream.p_selected_area->i_part_nb;
bool hasChapters = numChapters > 1;
vlc_mutex_unlock( &input->stream.stream_lock );
// first, look for chapters
if ( hasChapters )
{
// skip to the next chapter
currentChapter++;
if ( currentChapter < numChapters )
{
toggleChapter( currentChapter );
hasSkiped = true;
}
}
// if we couldn't skip chapters, try titles instead
if ( !hasSkiped && hasTitles )
{
// skip to the next title
currentTitle++;
// disallow area 0 since it is used for video_ts.vob
if ( currentTitle < numTitles - 1 )
{
toggleTitle(currentTitle);
hasSkiped = true;
}
}
}
// last but not least, skip to next file
if ( !hasSkiped )
playlistNext();
}
//void Intf_VLCWrapper::channelNext()
//{
// intf_thread_t * p_intf = p_main->p_intf;
//
// p_intf->p_sys->i_channel++;
//
// intf_WarnMsg( 3, "intf info: joining channel %d", p_intf->p_sys->i_channel );
//
// vlc_mutex_lock( &p_intf->change_lock );
//
// network_ChannelJoin( p_intf->p_sys->i_channel );
// p_intf->pf_manage( p_intf );
//
// vlc_mutex_unlock( &p_intf->change_lock );
//}
//
//void Intf_VLCWrapper::channelPrev()
//{
// intf_thread_t * p_intf = p_main->p_intf;
//
// if ( p_intf->p_sys->i_channel )
// {
// p_intf->p_sys->i_channel--;
// }
//
// intf_WarnMsg( 3, "intf info: joining channel %d", p_intf->p_sys->i_channel );
//
// vlc_mutex_lock( &p_intf->change_lock );
//
// network_ChannelJoin( p_intf->p_sys->i_channel );
// p_intf->pf_manage( p_intf );
//
// vlc_mutex_unlock( &p_intf->change_lock );
//
//}
void Intf_VLCWrapper::loop()
{
intf_thread_t * p_intf = p_main->p_intf;
if ( p_intf->p_sys->b_loop )
{
intf_PlaylistDelete( p_main->p_playlist,
p_main->p_playlist->i_size - 1 );
}
else
{
intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END,
"vlc:loop" );
}
p_intf->p_sys->b_loop = !p_intf->p_sys->b_loop;
}
/* playback control */
void Intf_VLCWrapper::playSlower()
{
if( p_input_bank->pp_input[0] != NULL )
{
input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_SLOWER );
vlc_mutex_lock( &p_main->p_playlist->change_lock );
p_main->p_playlist->b_stopped = 0;
vlc_mutex_unlock( &p_main->p_playlist->change_lock );
}
}
void Intf_VLCWrapper::playFaster()
{
if( p_input_bank->pp_input[0] != NULL )
{
input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_FASTER );
vlc_mutex_lock( &p_main->p_playlist->change_lock );
p_main->p_playlist->b_stopped = 0;
vlc_mutex_unlock( &p_main->p_playlist->change_lock );
}
}
void Intf_VLCWrapper::volume_mute()
{
if( p_aout_bank->i_count > 0
&& p_aout_bank->pp_aout[0] != NULL )
{
if( !p_main->p_intf->p_sys->b_mute )
{
p_main->p_intf->p_sys->i_saved_volume =
p_aout_bank->pp_aout[0]->i_volume;
p_aout_bank->pp_aout[0]->i_volume = 0;
p_main->p_intf->p_sys->b_mute = 1;
}
}
}
void Intf_VLCWrapper::volume_restore()
{
if( p_aout_bank->i_count > 0
&& p_aout_bank->pp_aout[0] != NULL )
{
p_aout_bank->pp_aout[0]->i_volume =
p_main->p_intf->p_sys->i_saved_volume;
p_main->p_intf->p_sys->i_saved_volume = 0;
p_main->p_intf->p_sys->b_mute = 0;
}
}
void Intf_VLCWrapper::set_volume(int value)
{
if( p_aout_bank->i_count > 0
&& p_aout_bank->pp_aout[0] != NULL )
{
// make sure value is within bounds
if (value < 0)
value = 0;
if (value > VOLUME_MAX)
value = VOLUME_MAX;
vlc_mutex_lock( &p_aout_bank->lock );
// unmute volume if muted
if ( p_main->p_intf->p_sys->b_mute )
p_main->p_intf->p_sys->b_mute = 0;
// set every stream to the given value
for ( int i = 0 ; i < p_aout_bank->i_count ; i++ )
{
if ( p_aout_bank->pp_aout[i] )
p_aout_bank->pp_aout[i]->i_volume = value;
}
vlc_mutex_unlock( &p_aout_bank->lock );
}
}
void Intf_VLCWrapper::toggle_mute()
{
if( p_aout_bank->i_count > 0
&& p_aout_bank->pp_aout[0] != NULL )
{
if ( p_main->p_intf->p_sys->b_mute )
{
Intf_VLCWrapper::volume_restore();
}
else
{
Intf_VLCWrapper::volume_mute();
}
}
}
bool Intf_VLCWrapper::is_muted()
{
bool muted = true;
if ( p_aout_bank->i_count > 0 )
{
vlc_mutex_lock( &p_aout_bank->lock );
for ( int i = 0 ; i < p_aout_bank->i_count ; i++ )
{
if ( p_aout_bank->pp_aout[i]
&& p_aout_bank->pp_aout[i]->i_volume > 0 )
{
muted = false;
break;
}
}
vlc_mutex_unlock( &p_aout_bank->lock );
// unfortunately, this is not reliable!
// return p_main->p_intf->p_sys->b_mute;
}
return muted;
}
bool Intf_VLCWrapper::is_playing()
{
bool playing = false;
if ( p_input_bank->pp_input[0] )
{
switch ( p_input_bank->pp_input[0]->stream.control.i_status )
{
case PLAYING_S:
case FORWARD_S:
case BACKWARD_S:
case START_S:
playing = true;
break;
case PAUSE_S:
case UNDEF_S:
case NOT_STARTED_S:
default:
break;
}
}
return playing;
}
void Intf_VLCWrapper::maxvolume()
{
if( p_aout_bank->i_count > 0
&& p_aout_bank->pp_aout[0] != NULL )
{
if( p_main->p_intf->p_sys->b_mute )
{
p_main->p_intf->p_sys->i_saved_volume = VOLUME_MAX;
}
else
{
p_aout_bank->pp_aout[0]->i_volume = VOLUME_MAX;
}
}
}
bool Intf_VLCWrapper::has_audio()
{
return (p_aout_bank->i_count > 0);
}
//void Intf_VLCWrapper::fullscreen()
//{
// if( p_vout_bank->pp_vout[0] != NULL )
// {
// p_vout_bank->pp_vout[0]->i_changes |= VOUT_FULLSCREEN_CHANGE;
// }
//}
void Intf_VLCWrapper::eject(){}
/* playback info */
const char*
Intf_VLCWrapper::getTimeAsString()
{
static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
if( p_input_bank->pp_input[0] == NULL )
return ("-:--:--");
input_OffsetToTime( p_input_bank->pp_input[0],
psz_currenttime,
p_input_bank->pp_input[0]->stream.p_selected_area->i_tell );
return(psz_currenttime);
}
float Intf_VLCWrapper::getTimeAsFloat()
{
float f_time = 0.0;
if( p_input_bank->pp_input[0] != NULL )
{
f_time = (float)p_input_bank->pp_input[0]->stream.p_selected_area->i_tell /
(float)p_input_bank->pp_input[0]->stream.p_selected_area->i_size;
}
return( f_time );
}
void Intf_VLCWrapper::setTimeAsFloat(float f_position)
{
if( p_input_bank->pp_input[0] != NULL )
{
input_Seek( p_input_bank->pp_input[0],
(long long int)(p_input_bank->pp_input[0]->stream.p_selected_area->i_size * f_position) );
}
}
bool Intf_VLCWrapper::playlistPlaying()
{
return( !p_main->p_playlist->b_stopped );
}
BList *Intf_VLCWrapper::playlistAsArray()
{
int i;
BList* p_list = new BList(p_main->p_playlist->i_size);
vlc_mutex_lock( &p_main->p_playlist->change_lock );
for( i = 0; i < p_main->p_playlist->i_size; i++ )
{
p_list->AddItem(new BString(p_main->p_playlist->p_item[i].psz_name));
}
vlc_mutex_unlock( &p_main->p_playlist->change_lock );
return( p_list );
}
// getPlaylistInfo
void
Intf_VLCWrapper::getPlaylistInfo( int32& currentIndex, int32& maxIndex )
{
currentIndex = -1;
maxIndex = -1;
if ( playlist_t* list = (playlist_t*)p_main->p_playlist )
{
vlc_mutex_lock( &list->change_lock );
maxIndex = list->i_size;
if ( maxIndex > 0 )
currentIndex = list->i_index + 1;
else
maxIndex = -1;
vlc_mutex_unlock( &list->change_lock );
}
}
// getTitleInfo
void
Intf_VLCWrapper::getTitleInfo( int32& currentIndex, int32& maxIndex )
{
currentIndex = -1;
maxIndex = -1;
if ( input_thread_s* input = p_input_bank->pp_input[0] )
{
vlc_mutex_lock( &input->stream.stream_lock );
maxIndex = input->stream.i_area_nb - 1;
if ( maxIndex > 0)
currentIndex = input->stream.p_selected_area->i_id;
else
maxIndex = -1;
vlc_mutex_unlock( &input->stream.stream_lock );
}
}
// getChapterInfo
void
Intf_VLCWrapper::getChapterInfo( int32& currentIndex, int32& maxIndex )
{
currentIndex = -1;
maxIndex = -1;
if ( input_thread_s* input = p_input_bank->pp_input[0] )
{
vlc_mutex_lock( &input->stream.stream_lock );
maxIndex = input->stream.p_selected_area->i_part_nb - 1;
if ( maxIndex > 0)
currentIndex = input->stream.p_selected_area->i_part;
else
maxIndex = -1;
vlc_mutex_unlock( &input->stream.stream_lock );
}
}
/* open file/disc/network */
void Intf_VLCWrapper::openFiles( BList* o_files, bool replace )
{
BString *o_file;
int i_end = p_main->p_playlist->i_size;
intf_thread_t * p_intf = p_main->p_intf;
// make sure we remove the "loop" item from the end before mucking arround
if ( p_intf->p_sys->b_loop )
{
intf_PlaylistDelete( p_main->p_playlist, i_end - 1 );
i_end--;
}
// add the new files to the playlist
while ( ( o_file = (BString *)o_files->LastItem() ) )
{
o_files->RemoveItem(o_files->CountItems() - 1);
intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END,
o_file->String() );
delete o_file;
}
if ( replace || i_end < 1 )
{
// end current item
if ( p_input_bank->pp_input[0] != NULL )
p_input_bank->pp_input[0]->b_eof = 1;
// remove everything that was in playlist before
for ( int i = 0; i < i_end; i++ )
intf_PlaylistDelete( p_main->p_playlist, 0 );
// jump to beginning and start playing
intf_PlaylistJumpto( p_main->p_playlist, -1 );
}
// if we were looping, add special "loop" item back to list
if ( p_intf->p_sys->b_loop )
intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, "vlc:loop" );
}
void Intf_VLCWrapper::openDisc(BString o_type, BString o_device, int i_title, int i_chapter)
{
BString o_source("");
int i_end = p_main->p_playlist->i_size;
intf_thread_t * p_intf = p_main->p_intf;
o_source << o_type << ":" << o_device ;
if ( p_intf->p_sys->b_loop )
{
intf_PlaylistDelete( p_main->p_playlist,
p_main->p_playlist->i_size - 1 );
}
intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END,
o_source.String() );
/* stop current item, select added item */
if( p_input_bank->pp_input[0] != NULL )
{
p_input_bank->pp_input[0]->b_eof = 1;
}
intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
if ( p_intf->p_sys->b_loop )
{
intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END,
"vlc:loop" );
}
}
void Intf_VLCWrapper::openNet(BString o_addr, int i_port)
{
}
void Intf_VLCWrapper::openNetChannel(BString o_addr, int i_port)
{
}
void Intf_VLCWrapper::openNetHTTP(BString o_addr)
{
}
/* menus management */
void Intf_VLCWrapper::toggleProgram(int i_program){}
void Intf_VLCWrapper::toggleTitle(int i_title)
{
input_thread_t * p_input = p_input_bank->pp_input[0];
input_ChangeArea( p_input,
p_input->stream.pp_areas[i_title] );
vlc_mutex_lock( &p_input->stream.stream_lock );
setupMenus();
vlc_mutex_unlock( &p_input->stream.stream_lock );
input_SetStatus( p_input, INPUT_STATUS_PLAY );
}
void Intf_VLCWrapper::toggleChapter(int i_chapter)
{
input_thread_t * p_input = p_input_bank->pp_input[0];
p_input->stream.p_selected_area->i_part = i_chapter;
input_ChangeArea( p_input,
p_input->stream.p_selected_area );
vlc_mutex_lock( &p_input->stream.stream_lock );
setupMenus();
vlc_mutex_unlock( &p_input->stream.stream_lock );
input_SetStatus( p_input, INPUT_STATUS_PLAY );
}
void Intf_VLCWrapper::toggleLanguage( int i_language )
{
if ( input_thread_t * p_input = p_input_bank->pp_input[0] )
{
if ( i_language == -1 )
{
input_ChangeES( p_input, NULL, AUDIO_ES );
}
else if ( i_language >= 0
&& i_language < p_input->stream.i_es_number )
{
input_ChangeES( p_input, p_input->stream.pp_es[i_language], AUDIO_ES );
}
}
}
void Intf_VLCWrapper::toggleSubtitle(int i_subtitle)
{
if ( input_thread_t * p_input = p_input_bank->pp_input[0] )
{
if ( i_subtitle == -1 )
{
input_ChangeES( p_input, NULL, SPU_ES );
}
else if ( i_subtitle >= 0
&& i_subtitle < p_input->stream.i_es_number )
{
input_ChangeES( p_input, p_input->stream.pp_es[i_subtitle], SPU_ES );
}
}
}
void Intf_VLCWrapper::setupMenus(){}
/*****************************************************************************
* intf_vlc_wrapper.h: BeOS plugin for vlc (derived from MacOS X port )
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: intf_vlc_wrapper.h,v 1.1.2.4 2002/10/09 15:29:51 stippi Exp $
*
* Authors: Florian G. Pflug <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
* Tony Casltey <tony@castley.net>
* Stephan Aßmus <stippi@yellowbites.com>
*
* 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.
*****************************************************************************/
class InterfaceWindow;
/*****************************************************************************
* intf_sys_t: description and status of FB interface
*****************************************************************************/
typedef struct intf_sys_s
{
InterfaceWindow * p_window;
char i_key;
int b_disabled_menus;
int i_part;
int i_saved_volume;
int b_loop;
int i_channel;
int b_mute;
} intf_sys_t;
/* Intf_VLCWrapper is a singleton class
(only one instance at any time) */
class Intf_VLCWrapper
{
public:
static bool manage();
static void quit();
/* playlist control */
static bool playlistPlay();
static void playlistPause();
static void playlistStop();
static void playlistNext();
static void playlistPrev();
static void playlistJumpTo( int pos );
static int playlistCurrentPos();
static int playlistSize();
static void playlistLock();
static void playlistUnlock();
static void getNavCapabilities( bool* canSkipPrev,
bool* canSkipNext );
static void navigatePrev();
static void navigateNext();
// static void channelNext();
// static void channelPrev();
static void loop();
/* playback control */
static void playSlower();
static void playFaster();
static void volume_mute();
static void volume_restore();
static void set_volume(int value);
static void toggle_mute();
static bool is_muted();
static bool is_playing();
static void maxvolume();
static bool has_audio();
// static void fullscreen();
static void eject();
/* playback info */
static const char* getTimeAsString();
static float getTimeAsFloat();
static void setTimeAsFloat( float i_offset );
static bool playlistPlaying();
static BList* playlistAsArray();
static void getPlaylistInfo( int32& currentIndex,
int32& maxIndex );
static void getTitleInfo( int32& currentIndex,
int32& maxIndex );
static void getChapterInfo( int32& currentIndex,
int32& maxIndex );
/* open file/disc/network */
static void openFiles( BList *o_files, bool replace = true );
static void openDisc( BString o_type, BString o_device,
int i_title, int i_chapter );
static void openNet( BString o_addr, int i_port );
static void openNetChannel( BString o_addr, int i_port );
static void openNetHTTP( BString o_addr );
/* menus management */
static void toggleProgram( int i_program );
static void toggleTitle( int i_title );
static void toggleChapter( int i_chapter );
static void toggleLanguage( int i_language );
static void toggleSubtitle( int i_subtitle );
static void setupMenus();
};
familiar_SOURCES = familiar.c familiar_interface.c familiar_support.c familiar_callbacks.c
/*****************************************************************************
* familiar.c : familiar plugin for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: familiar.c,v 1.8.2.9 2002/10/29 20:53:30 jpsaman Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
* 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 <stdlib.h> /* malloc(), free() */
#include <errno.h> /* ENOMEM */
#include <string.h> /* strerror() */
#include <stdio.h>
#include <videolan/vlc.h>
#include <gtk/gtk.h>
#ifdef HAVE_GPE_INIT_H
#include <gpe/init.h>
#endif
#include "stream_control.h"
#include "input_ext-intf.h"
#include "interface.h"
#include "intf_playlist.h"
#include "video.h"
#include "video_output.h"
#include "familiar_callbacks.h"
#include "familiar_interface.h"
#include "familiar_support.h"
#include "familiar.h"
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static void intf_getfunctions ( function_list_t * p_function_list );
static int Open ( intf_thread_t *p_intf );
static void Close ( intf_thread_t *p_intf );
static void Run ( intf_thread_t * );
static gint GtkManage ( gpointer p_data );
void GtkAutoPlayFile( void );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define AUTOPLAYFILE_TEXT N_("autoplay selected file")
#define AUTOPLAYFILE_LONGTEXT N_("automatically play a file when selected in the "\
"file selection list")
MODULE_CONFIG_START
ADD_CATEGORY_HINT( N_("Miscellaneous"), NULL )
ADD_BOOL( "familiar-autoplayfile", 1, GtkAutoPlayFile, AUTOPLAYFILE_TEXT, AUTOPLAYFILE_LONGTEXT)
MODULE_CONFIG_STOP
MODULE_INIT_START
SET_DESCRIPTION( _("Familiar Linux Gtk+ interface module") )
#ifndef WIN32
if( getenv( "DISPLAY" ) == NULL )
{
ADD_CAPABILITY( INTF, 10 )
}
else
#endif
{
ADD_CAPABILITY( INTF, 70 )
}
MODULE_INIT_STOP
MODULE_ACTIVATE_START
intf_getfunctions( &p_module->p_functions->intf );
MODULE_ACTIVATE_STOP
MODULE_DEACTIVATE_START
MODULE_DEACTIVATE_STOP
/*****************************************************************************
* g_atexit: kludge to avoid the Gtk+ thread to segfault at exit
*****************************************************************************
* gtk_init() makes several calls to g_atexit() which calls atexit() to
* register tidying callbacks to be called at program exit. Since the Gtk+
* plugin is likely to be unloaded at program exit, we have to export this
* symbol to intercept the g_atexit() calls. Talk about crude hack.
*****************************************************************************/
void g_atexit( GVoidFunc func )
{
intf_thread_t *p_intf = p_main->p_intf;
int i_dummy;
for( i_dummy = 0;
i_dummy < MAX_ATEXIT && p_intf->p_sys->pf_callback[i_dummy] != NULL;
i_dummy++ )
{
;
}
if( i_dummy >= MAX_ATEXIT - 1 )
{
intf_ErrMsg( "too many atexit() callbacks to register" );
return;
}
p_intf->p_sys->pf_callback[i_dummy] = func;
p_intf->p_sys->pf_callback[i_dummy + 1] = NULL;
}
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
static void intf_getfunctions( function_list_t * p_function_list )
{
p_function_list->functions.intf.pf_open = Open;
p_function_list->functions.intf.pf_close = Close;
p_function_list->functions.intf.pf_run = Run;
}
/*****************************************************************************
* Open: initialize and create window
*****************************************************************************/
static int Open( 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 )
{
intf_ErrMsg("error: %s", strerror(ENOMEM));
return (1);
}
/* Initialize Gtk+ thread */
p_intf->p_sys->b_autoplayfile = 1;
p_intf->p_sys->pf_callback[0] = NULL;
p_intf->pf_run = Run;
return (0);
}
/*****************************************************************************
* Close: destroy interface window
*****************************************************************************/
static void Close( intf_thread_t *p_intf )
{
/* Destroy structure */
free( p_intf->p_sys );
}
/*****************************************************************************
* Run: Gtk+ 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.
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
/* gtk_init needs to know the command line. We don't care, so we
* give it an empty one */
char *p_args[] = { "" };
char **pp_args = p_args;
int i_args = 1;
int i_dummy = 0;
#ifdef HAVE_GPE_INIT_H
/* Initialize GPE interface */
if (gpe_application_init(&i_args, &pp_args) == FALSE)
exit (1);
#else
/* Initialize Gtk+ */
gtk_set_locale ();
/* gtk_init will register stuff with g_atexit, so we need to take
* the global lock if we want to be able to intercept the calls */
gtk_init( &i_args, &pp_args );
#endif
/* Create some useful widgets that will certainly be used */
// FIXME: magic path
add_pixmap_directory("share");
add_pixmap_directory("/usr/share/videolan");
p_intf->p_sys->p_window = create_familiar();
if (p_intf->p_sys->p_window == NULL)
{
intf_ErrMsg( "unable to create familiar interface" );
}
/* Set the title of the main window */
gtk_window_set_title( GTK_WINDOW(p_intf->p_sys->p_window),
VOUT_TITLE " (Familiar Linux interface)");
p_intf->p_sys->p_notebook = GTK_NOTEBOOK( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_window ), "notebook" ) );
p_intf->p_sys->p_clist = GTK_CLIST( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_window ), "clistmedia" ) );
gtk_clist_set_column_visibility (GTK_CLIST (p_intf->p_sys->p_clist), 2, FALSE);
gtk_clist_set_column_visibility (GTK_CLIST (p_intf->p_sys->p_clist), 3, FALSE);
gtk_clist_set_column_visibility (GTK_CLIST (p_intf->p_sys->p_clist), 4, FALSE);
gtk_clist_column_titles_show (GTK_CLIST (p_intf->p_sys->p_clist));
/* Store p_intf to keep an eye on it */
gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window),
"p_intf", p_intf );
/* Show the control window */
gtk_widget_show( p_intf->p_sys->p_window );
ReadDirectory(p_intf->p_sys->p_clist, "/mnt");
// OpenDirectory(p_intf->p_sys->p_clist, "/mnt");
/* Sleep to avoid using all CPU - since some interfaces needs to access
* keyboard events, a 100ms delay is a good compromise */
i_dummy = gtk_timeout_add( INTF_IDLE_SLEEP / 1000, GtkManage, p_intf );
/* Enter Gtk mode */
gtk_main();
/* Remove the timeout */
gtk_timeout_remove( i_dummy );
/* Launch stored callbacks */
for( i_dummy = 0;
i_dummy < MAX_ATEXIT && p_intf->p_sys->pf_callback[i_dummy] != NULL;
i_dummy++ )
{
p_intf->p_sys->pf_callback[i_dummy]();
}
}
/* following functions are local */
/*****************************************************************************
* GtkManage: 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 GtkManage( gpointer p_data )
{
#define p_intf ((intf_thread_t *)p_data)
vlc_mutex_lock( &p_intf->change_lock );
/* Manage core vlc functions through the callback */
p_intf->pf_manage( p_intf );
if( p_intf->b_die )
{
vlc_mutex_unlock( &p_intf->change_lock );
/* Prepare to die, young Skywalker */
gtk_main_quit();
/* Just in case */
return( FALSE );
}
vlc_mutex_unlock( &p_intf->change_lock );
return( TRUE );
#undef p_intf
}
/*****************************************************************************
* GtkAutoplayFile: Autoplay file depending on configuration settings
*****************************************************************************
* FIXME: we should get the intf as parameter
*****************************************************************************/
void GtkAutoPlayFile( void )
{
GtkWidget *cbautoplay;
cbautoplay = GTK_WIDGET( gtk_object_get_data(
GTK_OBJECT( p_main->p_intf->p_sys->p_window ), "cbautoplay" ) );
if( !config_GetIntVariable( "familiar-autoplayfile" ) )
p_main->p_intf->p_sys->b_autoplayfile=0;
else
p_main->p_intf->p_sys->b_autoplayfile=1;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(cbautoplay),p_main->p_intf->p_sys->b_autoplayfile);
}
<?xml version="1.0"?>
<GTK-Interface>
<project>
<name>Familiar</name>
<program_name>familiar</program_name>
<directory></directory>
<source_directory></source_directory>
<pixmaps_directory>../../share</pixmaps_directory>
<language>C</language>
<gnome_support>False</gnome_support>
<gettext_support>True</gettext_support>
<use_widget_names>True</use_widget_names>
<output_main_file>False</output_main_file>
<output_build_files>False</output_build_files>
<main_source_file>familiar_interface.c</main_source_file>
<main_header_file>familiar_interface.h</main_header_file>
<handler_source_file>familiar_callbacks.c</handler_source_file>
<handler_header_file>familiar_callbacks.h</handler_header_file>
<support_source_file>familiar_support.c</support_source_file>
<support_header_file>familiar_support.h</support_header_file>
</project>
<widget>
<class>GtkWindow</class>
<name>familiar</name>
<width>240</width>
<height>300</height>
<signal>
<name>delete_event</name>
<handler>on_familiar_delete_event</handler>
<last_modification_time>Wed, 21 Aug 2002 19:12:40 GMT</last_modification_time>
</signal>
<title>vlc (familiar)</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
<modal>False</modal>
<allow_shrink>True</allow_shrink>
<allow_grow>True</allow_grow>
<auto_shrink>True</auto_shrink>
<widget>
<class>GtkVBox</class>
<name>vbox</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<widget>
<class>GtkToolbar</class>
<name>toolbar</name>
<border_width>2</border_width>
<width>112</width>
<height>16</height>
<orientation>GTK_ORIENTATION_HORIZONTAL</orientation>
<type>GTK_TOOLBAR_ICONS</type>
<space_size>5</space_size>
<space_style>GTK_TOOLBAR_SPACE_EMPTY</space_style>
<relief>GTK_RELIEF_NORMAL</relief>
<tooltips>True</tooltips>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkButton</class>
<child_name>Toolbar:button</child_name>
<name>toolbar_open</name>
<tooltip>Open file</tooltip>
<signal>
<name>clicked</name>
<handler>on_toolbar_open_clicked</handler>
<last_modification_time>Wed, 24 Jul 2002 18:28:31 GMT</last_modification_time>
</signal>
<label>Open</label>
<icon>familiar-openb16x16.xpm</icon>
</widget>
<widget>
<class>GtkButton</class>
<child_name>Toolbar:button</child_name>
<name>toolbar_preferences</name>
<tooltip>Preferences</tooltip>
<signal>
<name>clicked</name>
<handler>on_toolbar_preferences_clicked</handler>
<last_modification_time>Wed, 24 Jul 2002 18:29:05 GMT</last_modification_time>
</signal>
<label>Preferences</label>
<icon>familiar-preferencesb16x16.xpm</icon>
</widget>
<widget>
<class>GtkButton</class>
<child_name>Toolbar:button</child_name>
<name>toolbar_rewind</name>
<tooltip>Rewind stream</tooltip>
<signal>
<name>clicked</name>
<handler>on_toolbar_rewind_clicked</handler>
<last_modification_time>Wed, 24 Jul 2002 18:28:45 GMT</last_modification_time>
</signal>
<label>Rewind</label>
<icon>familiar-rewindb16x16.xpm</icon>
<child>
<new_group>True</new_group>
</child>
</widget>
<widget>
<class>GtkButton</class>
<child_name>Toolbar:button</child_name>
<name>toolbar_pause</name>
<tooltip>Pause stream</tooltip>
<signal>
<name>clicked</name>
<handler>on_toolbar_pause_clicked</handler>
<last_modification_time>Wed, 24 Jul 2002 18:28:58 GMT</last_modification_time>
</signal>
<label>Pause</label>
<icon>familiar-pauseb16x16.xpm</icon>
</widget>
<widget>
<class>GtkButton</class>
<child_name>Toolbar:button</child_name>
<name>toolbar_play</name>
<tooltip>Play stream</tooltip>
<signal>
<name>clicked</name>
<handler>on_toolbar_play_clicked</handler>
<last_modification_time>Wed, 24 Jul 2002 18:29:12 GMT</last_modification_time>
</signal>
<label>Play</label>
<icon>familiar-playb16x16.xpm</icon>
</widget>
<widget>
<class>GtkButton</class>
<child_name>Toolbar:button</child_name>
<name>toolbar_stop</name>
<tooltip>Stop stream</tooltip>
<signal>
<name>clicked</name>
<handler>on_toolbar_stop_clicked</handler>
<last_modification_time>Wed, 24 Jul 2002 18:29:18 GMT</last_modification_time>
</signal>
<label>Stop</label>
<icon>familiar-stopb16x16.xpm</icon>
</widget>
<widget>
<class>GtkButton</class>
<child_name>Toolbar:button</child_name>
<name>toolbar_forward</name>
<tooltip>Forward stream</tooltip>
<signal>
<name>clicked</name>
<handler>on_toolbar_forward_clicked</handler>
<last_modification_time>Wed, 24 Jul 2002 18:29:25 GMT</last_modification_time>
</signal>
<label>Forward</label>
<icon>familiar-forwardb16x16.xpm</icon>
</widget>
<widget>
<class>GtkButton</class>
<child_name>Toolbar:button</child_name>
<name>toolbar_about</name>
<tooltip>About</tooltip>
<signal>
<name>clicked</name>
<handler>on_toolbar_about_clicked</handler>
<last_modification_time>Wed, 24 Jul 2002 18:29:31 GMT</last_modification_time>
</signal>
<label>About</label>
<icon>vlc16x16.xpm</icon>
<child>
<new_group>True</new_group>
</child>
</widget>
</widget>
<widget>
<class>GtkNotebook</class>
<name>notebook</name>
<can_focus>True</can_focus>
<show_tabs>True</show_tabs>
<show_border>True</show_border>
<tab_pos>GTK_POS_TOP</tab_pos>
<scrollable>False</scrollable>
<tab_hborder>2</tab_hborder>
<tab_vborder>2</tab_vborder>
<popup_enable>False</popup_enable>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkFixed</class>
<name>fixedMedia</name>
<widget>
<class>GtkLabel</class>
<name>labelUrl</name>
<x>4</x>
<y>8</y>
<width>38</width>
<height>18</height>
<label>URL:</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkScrolledWindow</class>
<name>scrolledwindow1</name>
<x>0</x>
<y>32</y>
<width>240</width>
<height>208</height>
<hscrollbar_policy>GTK_POLICY_ALWAYS</hscrollbar_policy>
<vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
<widget>
<class>GtkCList</class>
<name>clistmedia</name>
<can_focus>True</can_focus>
<signal>
<name>select_row</name>
<handler>on_clistmedia_select_row</handler>
<last_modification_time>Sun, 18 Aug 2002 19:40:44 GMT</last_modification_time>
</signal>
<signal>
<name>click_column</name>
<handler>on_clistmedia_click_column</handler>
<last_modification_time>Sun, 18 Aug 2002 19:41:06 GMT</last_modification_time>
</signal>
<columns>5</columns>
<column_widths>123,80,80,80,80</column_widths>
<selection_mode>GTK_SELECTION_SINGLE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>labelname</name>
<label>Name</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>labeltype</name>
<label>Type</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>labelsize</name>
<label>Size</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>labeluid</name>
<label>User</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>labelgid</name>
<label>Group</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
<widget>
<class>GtkCombo</class>
<name>comboURL</name>
<x>40</x>
<y>4</y>
<width>185</width>
<height>24</height>
<value_in_list>False</value_in_list>
<ok_if_empty>True</ok_if_empty>
<case_sensitive>False</case_sensitive>
<use_arrows>True</use_arrows>
<use_arrows_always>False</use_arrows_always>
<items>/mnt
file://
ftp://
http://
udp://@:1234
udpstream://@:1234
</items>
<widget>
<class>GtkEntry</class>
<child_name>GtkCombo:entry</child_name>
<name>comboURL-entry</name>
<can_focus>True</can_focus>
<signal>
<name>changed</name>
<handler>on_comboURL-entry_changed</handler>
<last_modification_time>Thu, 01 Aug 2002 19:37:06 GMT</last_modification_time>
</signal>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text>/mnt</text>
</widget>
</widget>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>Notebook:tab</child_name>
<name>media</name>
<label>Media</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkFixed</class>
<name>fixedPreferences</name>
<widget>
<class>GtkButton</class>
<name>buttonSave</name>
<x>8</x>
<y>216</y>
<width>54</width>
<height>24</height>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_buttonSave_clicked</handler>
<last_modification_time>Tue, 01 Oct 2002 21:12:20 GMT</last_modification_time>
</signal>
<label>Save</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
<widget>
<class>GtkButton</class>
<name>buttonApply</name>
<x>64</x>
<y>216</y>
<width>54</width>
<height>24</height>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_buttonApply_clicked</handler>
<last_modification_time>Tue, 01 Oct 2002 21:12:27 GMT</last_modification_time>
</signal>
<label>Apply</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
<widget>
<class>GtkButton</class>
<name>buttonCancel</name>
<x>176</x>
<y>216</y>
<width>54</width>
<height>24</height>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_buttonCancel_clicked</handler>
<last_modification_time>Tue, 01 Oct 2002 21:12:35 GMT</last_modification_time>
</signal>
<label>Cancel</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
<widget>
<class>GtkCheckButton</class>
<name>cbautoplay</name>
<x>8</x>
<y>8</y>
<width>216</width>
<height>24</height>
<can_focus>True</can_focus>
<signal>
<name>toggled</name>
<handler>on_cbautoplay_toggled</handler>
<last_modification_time>Sun, 18 Aug 2002 20:00:52 GMT</last_modification_time>
</signal>
<label>Automatically play file.</label>
<active>True</active>
<draw_indicator>True</draw_indicator>
</widget>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>Notebook:tab</child_name>
<name>preferences</name>
<label>Preference</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkFixed</class>
<name>fixedAbout</name>
<widget>
<class>GtkPixmap</class>
<name>logo</name>
<x>8</x>
<y>0</y>
<width>50</width>
<height>50</height>
<filename>vlc32x32.xpm</filename>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<build_insensitive>True</build_insensitive>
</widget>
<widget>
<class>GtkLabel</class>
<name>labelVlc</name>
<x>64</x>
<y>8</y>
<width>120</width>
<height>40</height>
<label>VideoLAN Client
for familiar Linux</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>True</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<name>labelCopyright</name>
<x>16</x>
<y>56</y>
<width>200</width>
<height>18</height>
<label>(c) 2002, the VideoLAN Team</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<name>labelAuthors</name>
<x>16</x>
<y>80</y>
<width>200</width>
<height>40</height>
<label>Authors: The VideoLAN Team, http://www.videolan.org</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>True</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<name>labelAbout</name>
<x>16</x>
<y>128</y>
<width>200</width>
<height>70</height>
<label>The VideoLAN Client is a MPEG, MPEG 2, MP3, DivX player, that accepts input from local or network sources.</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>True</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>Notebook:tab</child_name>
<name>about</name>
<label>About</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
</widget>
</GTK-Interface>
/*****************************************************************************
* familiar.h: private Gtk+ interface description
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: familiar.h,v 1.6.2.3 2002/10/07 21:49:53 jpsaman Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
* 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.
*****************************************************************************/
#define MAX_ATEXIT 10
/*****************************************************************************
* intf_sys_t: description and status of Gtk+ interface
*****************************************************************************/
typedef struct intf_sys_s
{
/* windows and widgets */
GtkWidget * p_window; /* main window */
GtkNotebook * p_notebook;
GtkCList * p_clist;
// GHashTable * config_hash_table;
boolean_t b_autoplayfile;
/* XXX: Ugly kludge, see gtk.c */
void ( *pf_callback[MAX_ATEXIT] ) ( void );
} intf_sys_t;
/*****************************************************************************
* Useful macro
****************************************************************************/
#define GtkGetIntf( widget ) __GtkGetIntf( GTK_WIDGET( widget ) )
void * __GtkGetIntf( GtkWidget * );
/*****************************************************************************
* familiar_callbacks.c : Callbacks for the Familiar Linux Gtk+ plugin.
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: familiar_callbacks.c,v 1.6.2.12 2002/10/30 22:42:26 jpsaman Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h> /* off_t */
#include <dirent.h>
#include <unistd.h>
#include <videolan/vlc.h>
#include "stream_control.h"
#include "input_ext-intf.h"
#include "interface.h"
#include "intf_playlist.h"
#include "video.h"
#include "video_output.h"
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
#include "familiar_callbacks.h"
#include "familiar_interface.h"
#include "familiar_support.h"
#include "familiar.h"
#include "netutils.h"
static void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url );
static char* get_file_perm(const char *path);
/*****************************************************************************
* Useful function to retrieve p_intf
****************************************************************************/
void * __GtkGetIntf( GtkWidget * widget )
{
void *p_data;
if( GTK_IS_MENU_ITEM( widget ) )
{
/* Look for a GTK_MENU */
while( widget->parent && !GTK_IS_MENU( widget ) )
{
widget = widget->parent;
}
/* Maybe this one has the data */
p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
if( p_data )
{
return p_data;
}
/* Otherwise, the parent widget has it */
widget = gtk_menu_get_attach_widget( GTK_MENU( widget ) );
}
/* We look for the top widget */
widget = gtk_widget_get_toplevel( GTK_WIDGET( widget ) );
p_data = gtk_object_get_data( GTK_OBJECT( widget ), "p_intf" );
return p_data;
}
/*****************************************************************************
* Helper functions for URL changes in Media and Preferences notebook pages.
****************************************************************************/
static void MediaURLOpenChanged( GtkWidget *widget, gchar *psz_url )
{
intf_thread_t *p_intf = GtkGetIntf( widget );
int i_end = p_main->p_playlist->i_size;
// Add p_url to playlist .... but how ?
if( p_main->p_playlist )
{
intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, (char*)psz_url );
}
if (p_intf->p_sys->b_autoplayfile)
{
/* end current item, select added item */
if( p_input_bank->pp_input[0] != NULL )
{
p_input_bank->pp_input[0]->b_eof = 1;
}
intf_PlaylistJumpto( p_main->p_playlist, i_end - 1 );
if( p_input_bank->pp_input[0] != NULL )
{
input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
p_main->p_playlist->b_stopped = 0;
}
}
}
/*****************************************************************
* Read directory helper function.
****************************************************************/
void ReadDirectory( GtkCList *clist, char *psz_dir )
{
intf_thread_t *p_intf = GtkGetIntf( clist );
struct dirent **namelist;
int n=-1;
int status=-1;
printf( "Read directory: %s\n", psz_dir );
if (psz_dir)
{
status = chdir(psz_dir);
if (status<0)
intf_ErrMsg("File is not a directory.");
}
n = scandir(psz_dir, &namelist, 0, NULL);
printf( "n=%d\n", n);
if (n<0)
perror("scandir");
else
{
gchar *ppsz_text[2];
int i;
gtk_clist_freeze( p_intf->p_sys->p_clist );
gtk_clist_clear( p_intf->p_sys->p_clist );
for (i=0; i<n; i++)
{
/* This is a list of strings. */
ppsz_text[0] = namelist[i]->d_name;
ppsz_text[1] = get_file_perm(namelist[i]->d_name);
printf( "Entry: %s, %s\n", namelist[i]->d_name, ppsz_text[1] );
gtk_clist_insert( p_intf->p_sys->p_clist, i, ppsz_text );
free(namelist[i]);
}
gtk_clist_thaw( p_intf->p_sys->p_clist );
free(namelist);
}
}
void OpenDirectory( GtkCList *clist, char *psz_dir )
{
intf_thread_t *p_intf = GtkGetIntf( clist );
gchar *ppsz_text[2];
int row=0;
char* dir_path;
DIR* dir;
struct dirent* entry=NULL;
char entry_path[PATH_MAX+1];
size_t path_len;
if (psz_dir)
dir_path = psz_dir;
else
dir_path = ".";
strncpy( &entry_path[0], dir_path, sizeof(entry_path) );
/* always force end of string */
entry_path[PATH_MAX+1]='\0';
path_len = strlen(dir_path);
/* Make sure we do not run over our buffer here */
if (path_len > PATH_MAX)
path_len = PATH_MAX;
/* Add backslash to directory path */
if (entry_path[path_len-1] != '/')
{
entry_path[path_len] = '/';
entry_path[path_len+1] = '\0';
++path_len;
}
printf( "path_len=%d\n", path_len );
printf( "entry_path=%s\n", entry_path);
if( p_intf->p_sys->p_clist == NULL )
intf_ErrMsg("OpenDirectory - ERROR p_intf->p_sys->p_clist == NULL");
gtk_clist_freeze( p_intf->p_sys->p_clist );
gtk_clist_clear( p_intf->p_sys->p_clist );
dir = opendir(dir_path);
if (!dir) perror("opendir");
while( (entry = readdir(dir))!=NULL )
{
if (!entry) perror("readdir");
printf( "sizeof(entry->d_name)=%d\n",sizeof(&(entry)->d_name[0]) );
printf( "entry->d_name=%s\n",&(entry->d_name)[0] );
strncpy( entry_path + path_len, &(entry)->d_name[0], sizeof(entry_path) - path_len );
/* always force end of string */
entry_path[PATH_MAX+1]='\0';
/* This is a list of strings. */
ppsz_text[0] = &(entry)->d_name[0];
ppsz_text[1] = get_file_perm(entry_path);
printf( "%-18s %s\n", ppsz_text[1], &(entry)->d_name[0] );
// gtk_clist_insert( p_intf->p_sys->p_clist, row, ppsz_text );
row++;
}
closedir(dir);
gtk_clist_thaw( p_intf->p_sys->p_clist );
}
static char* get_file_perm(const char *path)
{
struct stat st;
char *perm;
perm = (char *) malloc(sizeof(char)*10);
strncpy( perm, "----------", sizeof("----------"));
if (lstat(path, &st)==0)
{
if (S_ISLNK(st.st_mode))
perm[0]= 'l';
else if (S_ISDIR(st.st_mode))
perm[0]= 'd';
else if (S_ISCHR(st.st_mode))
perm[0]= 'c';
else if (S_ISBLK(st.st_mode))
perm[0]= 'b';
else if (S_ISFIFO(st.st_mode))
perm[0]= 'f';
else if (S_ISSOCK(st.st_mode))
perm[0]= 's';
else if (S_ISREG(st.st_mode))
perm[0]= '-';
else /* Unknown type is an error */
perm[0]= '?';
/* Get file permissions */
/* User */
if (st.st_mode & S_IRUSR)
perm[1]= 'r';
if (st.st_mode & S_IWUSR)
perm[2]= 'w';
if (st.st_mode & S_IXUSR)
{
if (st.st_mode & S_ISUID)
perm[3] = 's';
else
perm[3]= 'x';
}
else if (st.st_mode & S_ISUID)
perm[3] = 'S';
/* Group */
if (st.st_mode & S_IRGRP)
perm[4]= 'r';
if (st.st_mode & S_IWGRP)
perm[5]= 'w';
if (st.st_mode & S_IXGRP)
{
if (st.st_mode & S_ISGID)
perm[6] = 's';
else
perm[6]= 'x';
}
else if (st.st_mode & S_ISGID)
perm[6] = 'S';
/* Other */
if (st.st_mode & S_IROTH)
perm[7]= 'r';
if (st.st_mode & S_IWOTH)
perm[8]= 'w';
if (st.st_mode & S_IXOTH)
{
// 'sticky' bit
if (st.st_mode &S_ISVTX)
perm[9] = 't';
else
perm[9]= 'x';
}
else if (st.st_mode &S_ISVTX)
perm[9]= 'T';
}
return perm;
}
/*
* Main interface callbacks
*/
gboolean GtkExit( GtkWidget *widget,
gpointer user_data )
{
intf_thread_t *p_intf = GtkGetIntf( widget );
vlc_mutex_lock( &p_intf->change_lock );
p_intf->b_die = 1;
vlc_mutex_unlock( &p_intf->change_lock );
return TRUE;
}
void
on_toolbar_open_clicked (GtkButton *button,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( button );
if (p_intf->p_sys->p_notebook)
{
gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
gtk_notebook_set_page(p_intf->p_sys->p_notebook,0);
}
gdk_window_raise( p_intf->p_sys->p_window->window );
if (p_intf->p_sys->p_clist)
{
ReadDirectory(p_intf->p_sys->p_clist, ".");
// OpenDirectory(p_intf->p_sys->p_clist, ".");
}
}
void
on_toolbar_preferences_clicked (GtkButton *button,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( button );
if (p_intf->p_sys->p_notebook)
{
gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
gtk_notebook_set_page(p_intf->p_sys->p_notebook,1);
}
gdk_window_raise( p_intf->p_sys->p_window->window );
}
void
on_toolbar_rewind_clicked (GtkButton *button,
gpointer user_data)
{
// intf_thread_t * p_intf = GtkGetIntf( button );
if( p_input_bank->pp_input[0] != NULL )
{
input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_SLOWER );
}
}
void
on_toolbar_pause_clicked (GtkButton *button,
gpointer user_data)
{
// intf_thread_t * p_intf = GtkGetIntf( button );
if( p_input_bank->pp_input[0] != NULL )
{
input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PAUSE );
}
}
void
on_toolbar_play_clicked (GtkButton *button,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( button );
if( p_input_bank->pp_input[0] != NULL )
{
input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_PLAY );
p_main->p_playlist->b_stopped = 0;
gdk_window_lower( p_intf->p_sys->p_window->window );
}
else
{
vlc_mutex_lock( &p_main->p_playlist->change_lock );
if( p_main->p_playlist->b_stopped )
{
if( p_main->p_playlist->i_size )
{
vlc_mutex_unlock( &p_main->p_playlist->change_lock );
intf_PlaylistJumpto( p_main->p_playlist,
p_main->p_playlist->i_index );
}
else
{
vlc_mutex_unlock( &p_main->p_playlist->change_lock );
/* simulate on open button click */
on_toolbar_open_clicked(button,user_data);
}
}
else
{
vlc_mutex_unlock( &p_main->p_playlist->change_lock );
}
}
}
void
on_toolbar_stop_clicked (GtkButton *button,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( button );
if( p_input_bank->pp_input[0] != NULL )
{
/* end playing item */
p_input_bank->pp_input[0]->b_eof = 1;
/* update playlist */
vlc_mutex_lock( &p_main->p_playlist->change_lock );
p_main->p_playlist->i_index--;
p_main->p_playlist->b_stopped = 1;
vlc_mutex_unlock( &p_main->p_playlist->change_lock );
gdk_window_raise( p_intf->p_sys->p_window->window );
}
}
void
on_toolbar_forward_clicked (GtkButton *button,
gpointer user_data)
{
// intf_thread_t * p_intf = GtkGetIntf( button );
if( p_input_bank->pp_input[0] != NULL )
{
input_SetStatus( p_input_bank->pp_input[0], INPUT_STATUS_FASTER );
}
}
void
on_toolbar_about_clicked (GtkButton *button,
gpointer user_data)
{
intf_thread_t *p_intf = GtkGetIntf( button );
// Toggle notebook
if (p_intf->p_sys->p_notebook)
{
gtk_widget_show( GTK_WIDGET(p_intf->p_sys->p_notebook) );
gtk_notebook_set_page(p_intf->p_sys->p_notebook,2);
}
gdk_window_raise( p_intf->p_sys->p_window->window );
}
void
on_comboURL_entry_changed (GtkEditable *editable,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( editable );
gchar * psz_url;
struct stat st;
psz_url = gtk_entry_get_text(GTK_ENTRY(editable));
if( (strncmp("file://",(const char *) psz_url,7)==0) ||
(strncmp("udp://",(const char *) psz_url,6)==0) ||
(strncmp("udp4://",(const char *) psz_url,7)==0) ||
(strncmp("udp6://",(const char *) psz_url,7)==0) ||
(strncmp("udpstream://",(const char *) psz_url,12)==0) ||
(strncmp("rtp://",(const char *) psz_url,6)==0) ||
(strncmp("rtp4://",(const char *) psz_url,7)==0) ||
(strncmp("rtp6://",(const char *) psz_url,7)==0) ||
(strncmp("rtpstream://",(const char *) psz_url,12)==0) ||
(strncmp("ftp://",(const char *) psz_url,6)==0) ||
(strncmp("http://",(const char *) psz_url,7)==0) )
{
MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
}
else if (lstat((char*)psz_url, &st)==0)
{
if (S_ISDIR(st.st_mode))
ReadDirectory(p_intf->p_sys->p_clist, psz_url);
// OpenDirectory(p_intf->p_sys->p_clist, psz_url);
else if( (S_ISLNK(st.st_mode)) || (S_ISCHR(st.st_mode)) ||
(S_ISBLK(st.st_mode)) || (S_ISFIFO(st.st_mode))||
(S_ISSOCK(st.st_mode))|| (S_ISREG(st.st_mode)) )
{
MediaURLOpenChanged(GTK_WIDGET(editable), psz_url);
}
}
}
void
on_clistmedia_click_column (GtkCList *clist,
gint column,
gpointer user_data)
{
static GtkSortType sort_type = GTK_SORT_ASCENDING;
// Should sort on column
switch(sort_type)
{
case GTK_SORT_ASCENDING:
sort_type = GTK_SORT_DESCENDING;
break;
case GTK_SORT_DESCENDING:
sort_type = GTK_SORT_ASCENDING;
break;
}
gtk_clist_freeze( clist );
gtk_clist_set_sort_type( clist, sort_type );
gtk_clist_sort( clist );
gtk_clist_thaw( clist );
}
void
on_clistmedia_select_row (GtkCList *clist,
gint row,
gint column,
GdkEvent *event,
gpointer user_data)
{
// intf_thread_t *p_intf = GtkGetIntf( clist );
intf_thread_t *p_intf = p_main->p_intf;
gchar *text[2];
gint ret;
struct stat st;
ret = gtk_clist_get_text (p_intf->p_sys->p_clist, row, 0, text);
if (ret)
{
if (lstat((char*)text[0], &st)==0)
{
if (S_ISDIR(st.st_mode))
ReadDirectory(p_intf->p_sys->p_clist, text[0]);
// OpenDirectory(p_intf->p_sys->p_clist, text[0]);
else if( (S_ISLNK(st.st_mode)) || (S_ISCHR(st.st_mode)) ||
(S_ISBLK(st.st_mode)) || (S_ISFIFO(st.st_mode))||
(S_ISSOCK(st.st_mode))|| (S_ISREG(st.st_mode)) )
{
MediaURLOpenChanged(GTK_WIDGET(p_intf->p_sys->p_clist), text[0]);
}
}
}
}
void
on_cbautoplay_toggled (GtkToggleButton *togglebutton,
gpointer user_data)
{
};
gboolean
on_familiar_delete_event (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
GtkExit( GTK_WIDGET( widget ), user_data );
return TRUE;
}
void
on_buttonSave_clicked (GtkButton *button,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( button );
on_buttonApply_clicked( button, user_data );
config_PutIntVariable( "familiar-autoplayfile", p_intf->p_sys->b_autoplayfile );
// config_SaveConfigFile( NULL );
}
void
on_buttonApply_clicked (GtkButton *button,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( button );
GtkWidget *cbautoplay;
cbautoplay = GTK_WIDGET( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_window ), "cbautoplay" ) );
p_intf->p_sys->b_autoplayfile = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(cbautoplay));
}
void
on_buttonCancel_clicked (GtkButton *button,
gpointer user_data)
{
intf_thread_t * p_intf = GtkGetIntf( button );
GtkWidget *cbautoplay;
cbautoplay = GTK_WIDGET( gtk_object_get_data(
GTK_OBJECT( p_intf->p_sys->p_window ), "cbautoplay" ) );
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(cbautoplay),p_intf->p_sys->b_autoplayfile);
}
/*****************************************************************************
* familiar_callbacks.h : familiar plugin for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: familiar_callbacks.h,v 1.7.2.6 2002/10/29 20:53:30 jpsaman Exp $
*
* Authors: Jean-Paul Saman <jpsaman@wxs.nl>
*
* 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.
*****************************************************************************/
#include <gtk/gtk.h>
gboolean GtkExit ( GtkWidget *, gpointer );
void ReadDirectory(GtkCList *clist, char *psz_dir);
void OpenDirectory(GtkCList *clist, char *psz_dir);
void
on_toolbar_open_clicked (GtkButton *button,
gpointer user_data);
void
on_toolbar_preferences_clicked (GtkButton *button,
gpointer user_data);
void
on_toolbar_rewind_clicked (GtkButton *button,
gpointer user_data);
void
on_toolbar_pause_clicked (GtkButton *button,
gpointer user_data);
void
on_toolbar_play_clicked (GtkButton *button,
gpointer user_data);
void
on_toolbar_stop_clicked (GtkButton *button,
gpointer user_data);
void
on_toolbar_forward_clicked (GtkButton *button,
gpointer user_data);
void
on_toolbar_about_clicked (GtkButton *button,
gpointer user_data);
void
on_comboURL_entry_changed (GtkEditable *editable,
gpointer user_data);
void
on_clistmedia_click_column (GtkCList *clist,
gint column,
gpointer user_data);
void
on_clistmedia_select_row (GtkCList *clist,
gint row,
gint column,
GdkEvent *event,
gpointer user_data);
void
on_cbautoplay_toggled (GtkToggleButton *togglebutton,
gpointer user_data);
gboolean
on_familiar_delete_event (GtkWidget *widget,
GdkEvent *event,
gpointer user_data);
void
on_buttonSave_clicked (GtkButton *button,
gpointer user_data);
void
on_buttonApply_clicked (GtkButton *button,
gpointer user_data);
void
on_buttonCancel_clicked (GtkButton *button,
gpointer user_data);
/*
* 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 <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include "familiar_callbacks.h"
#include "familiar_interface.h"
#include "familiar_support.h"
GtkWidget*
create_familiar (void)
{
GtkWidget *familiar;
GtkWidget *vbox;
GtkWidget *toolbar;
GtkWidget *tmp_toolbar_icon;
GtkWidget *toolbar_open;
GtkWidget *toolbar_preferences;
GtkWidget *toolbar_rewind;
GtkWidget *toolbar_pause;
GtkWidget *toolbar_play;
GtkWidget *toolbar_stop;
GtkWidget *toolbar_forward;
GtkWidget *toolbar_about;
GtkWidget *notebook;
GtkWidget *fixedMedia;
GtkWidget *labelUrl;
GtkWidget *scrolledwindow1;
GtkWidget *clistmedia;
GtkWidget *labelname;
GtkWidget *labeltype;
GtkWidget *labelsize;
GtkWidget *labeluid;
GtkWidget *labelgid;
GtkWidget *comboURL;
GList *comboURL_items = NULL;
GtkWidget *comboURL_entry;
GtkWidget *media;
GtkWidget *fixedPreferences;
GtkWidget *buttonSave;
GtkWidget *buttonApply;
GtkWidget *buttonCancel;
GtkWidget *cbautoplay;
GtkWidget *preferences;
GtkWidget *fixedAbout;
GtkWidget *logo;
GtkWidget *labelVlc;
GtkWidget *labelCopyright;
GtkWidget *labelAuthors;
GtkWidget *labelAbout;
GtkWidget *about;
familiar = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_name (familiar, "familiar");
gtk_object_set_data (GTK_OBJECT (familiar), "familiar", familiar);
gtk_widget_set_usize (familiar, 240, 300);
gtk_window_set_title (GTK_WINDOW (familiar), _("vlc (familiar)"));
gtk_window_set_policy (GTK_WINDOW (familiar), TRUE, TRUE, TRUE);
vbox = gtk_vbox_new (FALSE, 0);
gtk_widget_set_name (vbox, "vbox");
gtk_widget_ref (vbox);
gtk_object_set_data_full (GTK_OBJECT (familiar), "vbox", vbox,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (familiar), vbox);
toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
gtk_widget_set_name (toolbar, "toolbar");
gtk_widget_ref (toolbar);
gtk_object_set_data_full (GTK_OBJECT (familiar), "toolbar", toolbar,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar);
gtk_box_pack_start (GTK_BOX (vbox), toolbar, TRUE, TRUE, 0);
gtk_widget_set_usize (toolbar, 112, 16);
gtk_container_set_border_width (GTK_CONTAINER (toolbar), 2);
tmp_toolbar_icon = create_pixmap (familiar, "familiar-openb16x16.xpm");
toolbar_open = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Open"),
_("Open file"), NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_widget_set_name (toolbar_open, "toolbar_open");
gtk_widget_ref (toolbar_open);
gtk_object_set_data_full (GTK_OBJECT (familiar), "toolbar_open", toolbar_open,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_open);
tmp_toolbar_icon = create_pixmap (familiar, "familiar-preferencesb16x16.xpm");
toolbar_preferences = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Preferences"),
_("Preferences"), NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_widget_set_name (toolbar_preferences, "toolbar_preferences");
gtk_widget_ref (toolbar_preferences);
gtk_object_set_data_full (GTK_OBJECT (familiar), "toolbar_preferences", toolbar_preferences,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_preferences);
gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
tmp_toolbar_icon = create_pixmap (familiar, "familiar-rewindb16x16.xpm");
toolbar_rewind = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Rewind"),
_("Rewind stream"), NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_widget_set_name (toolbar_rewind, "toolbar_rewind");
gtk_widget_ref (toolbar_rewind);
gtk_object_set_data_full (GTK_OBJECT (familiar), "toolbar_rewind", toolbar_rewind,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_rewind);
tmp_toolbar_icon = create_pixmap (familiar, "familiar-pauseb16x16.xpm");
toolbar_pause = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Pause"),
_("Pause stream"), NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_widget_set_name (toolbar_pause, "toolbar_pause");
gtk_widget_ref (toolbar_pause);
gtk_object_set_data_full (GTK_OBJECT (familiar), "toolbar_pause", toolbar_pause,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_pause);
tmp_toolbar_icon = create_pixmap (familiar, "familiar-playb16x16.xpm");
toolbar_play = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Play"),
_("Play stream"), NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_widget_set_name (toolbar_play, "toolbar_play");
gtk_widget_ref (toolbar_play);
gtk_object_set_data_full (GTK_OBJECT (familiar), "toolbar_play", toolbar_play,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_play);
tmp_toolbar_icon = create_pixmap (familiar, "familiar-stopb16x16.xpm");
toolbar_stop = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Stop"),
_("Stop stream"), NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_widget_set_name (toolbar_stop, "toolbar_stop");
gtk_widget_ref (toolbar_stop);
gtk_object_set_data_full (GTK_OBJECT (familiar), "toolbar_stop", toolbar_stop,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_stop);
tmp_toolbar_icon = create_pixmap (familiar, "familiar-forwardb16x16.xpm");
toolbar_forward = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Forward"),
_("Forward stream"), NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_widget_set_name (toolbar_forward, "toolbar_forward");
gtk_widget_ref (toolbar_forward);
gtk_object_set_data_full (GTK_OBJECT (familiar), "toolbar_forward", toolbar_forward,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_forward);
gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
tmp_toolbar_icon = create_pixmap (familiar, "vlc16x16.xpm");
toolbar_about = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("About"),
_("About"), NULL,
tmp_toolbar_icon, NULL, NULL);
gtk_widget_set_name (toolbar_about, "toolbar_about");
gtk_widget_ref (toolbar_about);
gtk_object_set_data_full (GTK_OBJECT (familiar), "toolbar_about", toolbar_about,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar_about);
notebook = gtk_notebook_new ();
gtk_widget_set_name (notebook, "notebook");
gtk_widget_ref (notebook);
gtk_object_set_data_full (GTK_OBJECT (familiar), "notebook", notebook,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (notebook);
gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
fixedMedia = gtk_fixed_new ();
gtk_widget_set_name (fixedMedia, "fixedMedia");
gtk_widget_ref (fixedMedia);
gtk_object_set_data_full (GTK_OBJECT (familiar), "fixedMedia", fixedMedia,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (fixedMedia);
gtk_container_add (GTK_CONTAINER (notebook), fixedMedia);
labelUrl = gtk_label_new (_("URL:"));
gtk_widget_set_name (labelUrl, "labelUrl");
gtk_widget_ref (labelUrl);
gtk_object_set_data_full (GTK_OBJECT (familiar), "labelUrl", labelUrl,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (labelUrl);
gtk_fixed_put (GTK_FIXED (fixedMedia), labelUrl, 4, 8);
gtk_widget_set_uposition (labelUrl, 4, 8);
gtk_widget_set_usize (labelUrl, 38, 18);
scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_name (scrolledwindow1, "scrolledwindow1");
gtk_widget_ref (scrolledwindow1);
gtk_object_set_data_full (GTK_OBJECT (familiar), "scrolledwindow1", scrolledwindow1,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (scrolledwindow1);
gtk_fixed_put (GTK_FIXED (fixedMedia), scrolledwindow1, 0, 32);
gtk_widget_set_uposition (scrolledwindow1, 0, 32);
gtk_widget_set_usize (scrolledwindow1, 240, 208);
clistmedia = gtk_clist_new (5);
gtk_widget_set_name (clistmedia, "clistmedia");
gtk_widget_ref (clistmedia);
gtk_object_set_data_full (GTK_OBJECT (familiar), "clistmedia", clistmedia,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (clistmedia);
gtk_container_add (GTK_CONTAINER (scrolledwindow1), clistmedia);
gtk_clist_set_column_width (GTK_CLIST (clistmedia), 0, 123);
gtk_clist_set_column_width (GTK_CLIST (clistmedia), 1, 80);
gtk_clist_set_column_width (GTK_CLIST (clistmedia), 2, 80);
gtk_clist_set_column_width (GTK_CLIST (clistmedia), 3, 80);
gtk_clist_set_column_width (GTK_CLIST (clistmedia), 4, 80);
gtk_clist_column_titles_show (GTK_CLIST (clistmedia));
labelname = gtk_label_new (_("Name"));
gtk_widget_set_name (labelname, "labelname");
gtk_widget_ref (labelname);
gtk_object_set_data_full (GTK_OBJECT (familiar), "labelname", labelname,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (labelname);
gtk_clist_set_column_widget (GTK_CLIST (clistmedia), 0, labelname);
labeltype = gtk_label_new (_("Type"));
gtk_widget_set_name (labeltype, "labeltype");
gtk_widget_ref (labeltype);
gtk_object_set_data_full (GTK_OBJECT (familiar), "labeltype", labeltype,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (labeltype);
gtk_clist_set_column_widget (GTK_CLIST (clistmedia), 1, labeltype);
labelsize = gtk_label_new (_("Size"));
gtk_widget_set_name (labelsize, "labelsize");
gtk_widget_ref (labelsize);
gtk_object_set_data_full (GTK_OBJECT (familiar), "labelsize", labelsize,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (labelsize);
gtk_clist_set_column_widget (GTK_CLIST (clistmedia), 2, labelsize);
labeluid = gtk_label_new (_("User"));
gtk_widget_set_name (labeluid, "labeluid");
gtk_widget_ref (labeluid);
gtk_object_set_data_full (GTK_OBJECT (familiar), "labeluid", labeluid,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (labeluid);
gtk_clist_set_column_widget (GTK_CLIST (clistmedia), 3, labeluid);
labelgid = gtk_label_new (_("Group"));
gtk_widget_set_name (labelgid, "labelgid");
gtk_widget_ref (labelgid);
gtk_object_set_data_full (GTK_OBJECT (familiar), "labelgid", labelgid,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (labelgid);
gtk_clist_set_column_widget (GTK_CLIST (clistmedia), 4, labelgid);
comboURL = gtk_combo_new ();
gtk_widget_set_name (comboURL, "comboURL");
gtk_widget_ref (comboURL);
gtk_object_set_data_full (GTK_OBJECT (familiar), "comboURL", comboURL,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (comboURL);
gtk_fixed_put (GTK_FIXED (fixedMedia), comboURL, 40, 4);
gtk_widget_set_uposition (comboURL, 40, 4);
gtk_widget_set_usize (comboURL, 185, 24);
comboURL_items = g_list_append (comboURL_items, (gpointer) _("/mnt"));
comboURL_items = g_list_append (comboURL_items, (gpointer) _("file://"));
comboURL_items = g_list_append (comboURL_items, (gpointer) _("ftp://"));
comboURL_items = g_list_append (comboURL_items, (gpointer) _("http://"));
comboURL_items = g_list_append (comboURL_items, (gpointer) _("udp://@:1234"));
comboURL_items = g_list_append (comboURL_items, (gpointer) _("udpstream://@:1234"));
gtk_combo_set_popdown_strings (GTK_COMBO (comboURL), comboURL_items);
g_list_free (comboURL_items);
comboURL_entry = GTK_COMBO (comboURL)->entry;
gtk_widget_set_name (comboURL_entry, "comboURL_entry");
gtk_widget_ref (comboURL_entry);
gtk_object_set_data_full (GTK_OBJECT (familiar), "comboURL_entry", comboURL_entry,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (comboURL_entry);
gtk_entry_set_text (GTK_ENTRY (comboURL_entry), _("/mnt"));
media = gtk_label_new (_("Media"));
gtk_widget_set_name (media, "media");
gtk_widget_ref (media);
gtk_object_set_data_full (GTK_OBJECT (familiar), "media", media,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (media);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 0), media);
fixedPreferences = gtk_fixed_new ();
gtk_widget_set_name (fixedPreferences, "fixedPreferences");
gtk_widget_ref (fixedPreferences);
gtk_object_set_data_full (GTK_OBJECT (familiar), "fixedPreferences", fixedPreferences,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (fixedPreferences);
gtk_container_add (GTK_CONTAINER (notebook), fixedPreferences);
buttonSave = gtk_button_new_with_label (_("Save"));
gtk_widget_set_name (buttonSave, "buttonSave");
gtk_widget_ref (buttonSave);
gtk_object_set_data_full (GTK_OBJECT (familiar), "buttonSave", buttonSave,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (buttonSave);
gtk_fixed_put (GTK_FIXED (fixedPreferences), buttonSave, 8, 216);
gtk_widget_set_uposition (buttonSave, 8, 216);
gtk_widget_set_usize (buttonSave, 54, 24);
buttonApply = gtk_button_new_with_label (_("Apply"));
gtk_widget_set_name (buttonApply, "buttonApply");
gtk_widget_ref (buttonApply);
gtk_object_set_data_full (GTK_OBJECT (familiar), "buttonApply", buttonApply,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (buttonApply);
gtk_fixed_put (GTK_FIXED (fixedPreferences), buttonApply, 64, 216);
gtk_widget_set_uposition (buttonApply, 64, 216);
gtk_widget_set_usize (buttonApply, 54, 24);
buttonCancel = gtk_button_new_with_label (_("Cancel"));
gtk_widget_set_name (buttonCancel, "buttonCancel");
gtk_widget_ref (buttonCancel);
gtk_object_set_data_full (GTK_OBJECT (familiar), "buttonCancel", buttonCancel,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (buttonCancel);
gtk_fixed_put (GTK_FIXED (fixedPreferences), buttonCancel, 176, 216);
gtk_widget_set_uposition (buttonCancel, 176, 216);
gtk_widget_set_usize (buttonCancel, 54, 24);
cbautoplay = gtk_check_button_new_with_label (_("Automatically play file."));
gtk_widget_set_name (cbautoplay, "cbautoplay");
gtk_widget_ref (cbautoplay);
gtk_object_set_data_full (GTK_OBJECT (familiar), "cbautoplay", cbautoplay,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (cbautoplay);
gtk_fixed_put (GTK_FIXED (fixedPreferences), cbautoplay, 8, 8);
gtk_widget_set_uposition (cbautoplay, 8, 8);
gtk_widget_set_usize (cbautoplay, 216, 24);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbautoplay), TRUE);
preferences = gtk_label_new (_("Preference"));
gtk_widget_set_name (preferences, "preferences");
gtk_widget_ref (preferences);
gtk_object_set_data_full (GTK_OBJECT (familiar), "preferences", preferences,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (preferences);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1), preferences);
fixedAbout = gtk_fixed_new ();
gtk_widget_set_name (fixedAbout, "fixedAbout");
gtk_widget_ref (fixedAbout);
gtk_object_set_data_full (GTK_OBJECT (familiar), "fixedAbout", fixedAbout,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (fixedAbout);
gtk_container_add (GTK_CONTAINER (notebook), fixedAbout);
logo = create_pixmap (familiar, "vlc32x32.xpm");
gtk_widget_set_name (logo, "logo");
gtk_widget_ref (logo);
gtk_object_set_data_full (GTK_OBJECT (familiar), "logo", logo,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (logo);
gtk_fixed_put (GTK_FIXED (fixedAbout), logo, 8, 0);
gtk_widget_set_uposition (logo, 8, 0);
gtk_widget_set_usize (logo, 50, 50);
labelVlc = gtk_label_new (_("VideoLAN Client\n for familiar Linux"));
gtk_widget_set_name (labelVlc, "labelVlc");
gtk_widget_ref (labelVlc);
gtk_object_set_data_full (GTK_OBJECT (familiar), "labelVlc", labelVlc,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (labelVlc);
gtk_fixed_put (GTK_FIXED (fixedAbout), labelVlc, 64, 8);
gtk_widget_set_uposition (labelVlc, 64, 8);
gtk_widget_set_usize (labelVlc, 120, 40);
gtk_label_set_line_wrap (GTK_LABEL (labelVlc), TRUE);
labelCopyright = gtk_label_new (_("(c) 2002, the VideoLAN Team"));
gtk_widget_set_name (labelCopyright, "labelCopyright");
gtk_widget_ref (labelCopyright);
gtk_object_set_data_full (GTK_OBJECT (familiar), "labelCopyright", labelCopyright,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (labelCopyright);
gtk_fixed_put (GTK_FIXED (fixedAbout), labelCopyright, 16, 56);
gtk_widget_set_uposition (labelCopyright, 16, 56);
gtk_widget_set_usize (labelCopyright, 200, 18);
labelAuthors = gtk_label_new (_("Authors: The VideoLAN Team, http://www.videolan.org"));
gtk_widget_set_name (labelAuthors, "labelAuthors");
gtk_widget_ref (labelAuthors);
gtk_object_set_data_full (GTK_OBJECT (familiar), "labelAuthors", labelAuthors,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (labelAuthors);
gtk_fixed_put (GTK_FIXED (fixedAbout), labelAuthors, 16, 80);
gtk_widget_set_uposition (labelAuthors, 16, 80);
gtk_widget_set_usize (labelAuthors, 200, 40);
gtk_label_set_line_wrap (GTK_LABEL (labelAuthors), TRUE);
labelAbout = gtk_label_new (_("The VideoLAN Client is a MPEG, MPEG 2, MP3, DivX player, that accepts input from local or network sources."));
gtk_widget_set_name (labelAbout, "labelAbout");
gtk_widget_ref (labelAbout);
gtk_object_set_data_full (GTK_OBJECT (familiar), "labelAbout", labelAbout,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (labelAbout);
gtk_fixed_put (GTK_FIXED (fixedAbout), labelAbout, 16, 128);
gtk_widget_set_uposition (labelAbout, 16, 128);
gtk_widget_set_usize (labelAbout, 200, 70);
gtk_label_set_justify (GTK_LABEL (labelAbout), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (labelAbout), TRUE);
about = gtk_label_new (_("About"));
gtk_widget_set_name (about, "about");
gtk_widget_ref (about);
gtk_object_set_data_full (GTK_OBJECT (familiar), "about", about,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (about);
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 2), about);
gtk_signal_connect (GTK_OBJECT (familiar), "delete_event",
GTK_SIGNAL_FUNC (on_familiar_delete_event),
NULL);
gtk_signal_connect (GTK_OBJECT (toolbar_open), "clicked",
GTK_SIGNAL_FUNC (on_toolbar_open_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (toolbar_preferences), "clicked",
GTK_SIGNAL_FUNC (on_toolbar_preferences_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (toolbar_rewind), "clicked",
GTK_SIGNAL_FUNC (on_toolbar_rewind_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (toolbar_pause), "clicked",
GTK_SIGNAL_FUNC (on_toolbar_pause_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (toolbar_play), "clicked",
GTK_SIGNAL_FUNC (on_toolbar_play_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (toolbar_stop), "clicked",
GTK_SIGNAL_FUNC (on_toolbar_stop_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (toolbar_forward), "clicked",
GTK_SIGNAL_FUNC (on_toolbar_forward_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (toolbar_about), "clicked",
GTK_SIGNAL_FUNC (on_toolbar_about_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (clistmedia), "select_row",
GTK_SIGNAL_FUNC (on_clistmedia_select_row),
NULL);
gtk_signal_connect (GTK_OBJECT (clistmedia), "click_column",
GTK_SIGNAL_FUNC (on_clistmedia_click_column),
NULL);
gtk_signal_connect (GTK_OBJECT (comboURL_entry), "changed",
GTK_SIGNAL_FUNC (on_comboURL_entry_changed),
NULL);
gtk_signal_connect (GTK_OBJECT (buttonSave), "clicked",
GTK_SIGNAL_FUNC (on_buttonSave_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (buttonApply), "clicked",
GTK_SIGNAL_FUNC (on_buttonApply_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (buttonCancel), "clicked",
GTK_SIGNAL_FUNC (on_buttonCancel_clicked),
NULL);
gtk_signal_connect (GTK_OBJECT (cbautoplay), "toggled",
GTK_SIGNAL_FUNC (on_cbautoplay_toggled),
NULL);
return familiar;
}
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
GtkWidget* create_familiar (void);
/*
* 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 <gtk/gtk.h>
#include "familiar_support.h"
/* This is an internally used function to check if a pixmap file exists. */
static gchar* check_file_exists (const gchar *directory,
const gchar *filename);
/* This is an internally used function to create pixmaps. */
static GtkWidget* create_dummy_pixmap (GtkWidget *widget);
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)
{
GdkColormap *colormap;
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
GtkWidget *pixmap;
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;
}
static GList *pixmaps_directories = NULL;
/* Use this function to set the directory containing installed pixmaps. */
void
add_pixmap_directory (const gchar *directory)
{
pixmaps_directories = g_list_prepend (pixmaps_directories,
g_strdup (directory));
}
/* This is an internally used function to create pixmaps. */
GtkWidget*
create_pixmap (GtkWidget *widget,
const gchar *filename)
{
gchar *found_filename = NULL;
GdkColormap *colormap;
GdkPixmap *gdkpixmap;
GdkBitmap *mask;
GtkWidget *pixmap;
GList *elem;
if (!filename || !filename[0])
return create_dummy_pixmap (widget);
/* We first try any pixmaps directories set by the application. */
elem = pixmaps_directories;
while (elem)
{
found_filename = check_file_exists ((gchar*)elem->data, filename);
if (found_filename)
break;
elem = elem->next;
}
/* If we haven't found the pixmap, try the source directory. */
if (!found_filename)
{
found_filename = check_file_exists ("../../share", filename);
}
if (!found_filename)
{
g_warning (_("Couldn't find pixmap file: %s"), filename);
return create_dummy_pixmap (widget);
}
colormap = gtk_widget_get_colormap (widget);
gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask,
NULL, found_filename);
if (gdkpixmap == NULL)
{
g_warning (_("Error loading pixmap file: %s"), found_filename);
g_free (found_filename);
return create_dummy_pixmap (widget);
}
g_free (found_filename);
pixmap = gtk_pixmap_new (gdkpixmap, mask);
gdk_pixmap_unref (gdkpixmap);
gdk_bitmap_unref (mask);
return pixmap;
}
/* This is an internally used function to check if a pixmap file exists. */
static gchar*
check_file_exists (const gchar *directory,
const gchar *filename)
{
gchar *full_filename;
struct stat s;
gint status;
full_filename = (gchar*) g_malloc (strlen (directory) + 1
+ strlen (filename) + 1);
strcpy (full_filename, directory);
strcat (full_filename, G_DIR_SEPARATOR_S);
strcat (full_filename, filename);
status = stat (full_filename, &s);
if (status == 0 && S_ISREG (s.st_mode))
return full_filename;
g_free (full_filename);
return NULL;
}
/*
* DO NOT EDIT THIS FILE - it is generated by Glade.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
/*
* Standard gettext macros.
*/
#ifdef ENABLE_NLS
# include <libintl.h>
# undef _
# define _(String) dgettext (PACKAGE, String)
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
# define N_(String) (String)
# endif
#else
# define textdomain(String) (String)
# define gettext(String) (String)
# define dgettext(Domain,Message) (Message)
# define dcgettext(Domain,Message,Type) (Message)
# define bindtextdomain(Domain,Directory) (Domain)
# define _(String) (String)
# define N_(String) (String)
#endif
/*
* 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
/* Use this function to set the directory containing installed pixmaps. */
void add_pixmap_directory (const gchar *directory);
/*
* Private Functions.
*/
/* This is used to create the pixmaps in the interface. */
GtkWidget* create_pixmap (GtkWidget *widget,
const gchar *filename);
/*****************************************************************************
* crop.c : Crop video plugin for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: crop.c,v 1.1.2.2 2002/06/02 02:04:37 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* 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 <errno.h>
#include <stdlib.h> /* malloc(), free() */
#include <string.h>
#include <videolan/vlc.h>
#include "video.h"
#include "video_output.h"
#include "filter_common.h"
/*****************************************************************************
* Capabilities defined in the other files.
*****************************************************************************/
static void vout_getfunctions( function_list_t * p_function_list );
/*****************************************************************************
* Build configuration tree.
*****************************************************************************/
MODULE_CONFIG_START
ADD_CATEGORY_HINT( N_("Miscellaneous"), NULL )
ADD_STRING ( "crop-geometry", NULL, NULL, N_("Crop geometry"), N_("Set the geometry of the zone to crop") )
ADD_BOOL ( "autocrop", 0, NULL, N_("Automatic cropping"), N_("Activate automatic black border cropping") )
MODULE_CONFIG_STOP
MODULE_INIT_START
SET_DESCRIPTION( _("image crop video module") )
/* Capability score set to 0 because we don't want to be spawned
* as a video output unless explicitly requested to */
ADD_CAPABILITY( VOUT, 0 )
ADD_SHORTCUT( "crop" )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
vout_getfunctions( &p_module->p_functions->vout );
MODULE_ACTIVATE_STOP
MODULE_DEACTIVATE_START
MODULE_DEACTIVATE_STOP
/*****************************************************************************
* vout_sys_t: Crop video output method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the Crop specific properties of an output thread.
*****************************************************************************/
typedef struct vout_sys_s
{
vout_thread_t *p_vout;
unsigned int i_x, i_y;
unsigned int i_width, i_height, i_aspect;
boolean_t b_autocrop;
/* Autocrop specific variables */
unsigned int i_lastchange;
boolean_t b_changed;
} vout_sys_t;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int vout_Create ( vout_thread_t * );
static int vout_Init ( vout_thread_t * );
static void vout_End ( vout_thread_t * );
static void vout_Destroy ( vout_thread_t * );
static int vout_Manage ( vout_thread_t * );
static void vout_Render ( vout_thread_t *, picture_t * );
static void vout_Display ( vout_thread_t *, picture_t * );
static void UpdateStats ( vout_thread_t *, picture_t * );
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
static void vout_getfunctions( function_list_t * p_function_list )
{
p_function_list->functions.vout.pf_create = vout_Create;
p_function_list->functions.vout.pf_init = vout_Init;
p_function_list->functions.vout.pf_end = vout_End;
p_function_list->functions.vout.pf_destroy = vout_Destroy;
p_function_list->functions.vout.pf_manage = vout_Manage;
p_function_list->functions.vout.pf_render = vout_Render;
p_function_list->functions.vout.pf_display = vout_Display;
}
/*****************************************************************************
* vout_Create: allocates Crop video thread output method
*****************************************************************************
* This function allocates and initializes a Crop vout method.
*****************************************************************************/
static int vout_Create( vout_thread_t *p_vout )
{
/* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
{
intf_ErrMsg( "vout error: out of memory" );
return 1;
}
return 0;
}
/*****************************************************************************
* vout_Init: initialize Crop video thread output method
*****************************************************************************/
static int vout_Init( vout_thread_t *p_vout )
{
int i_index;
char *psz_var;
picture_t *p_pic;
I_OUTPUTPICTURES = 0;
p_vout->p_sys->i_lastchange = 0;
p_vout->p_sys->b_changed = 0;
/* Initialize the output structure */
p_vout->output.i_chroma = p_vout->render.i_chroma;
p_vout->output.i_width = p_vout->render.i_width;
p_vout->output.i_height = p_vout->render.i_height;
p_vout->output.i_aspect = p_vout->render.i_aspect;
/* Shall we use autocrop ? */
p_vout->p_sys->b_autocrop = config_GetIntVariable( "autocrop" );
/* Get geometry value from the user */
psz_var = config_GetPszVariable( "crop-geometry" );
if( psz_var )
{
char *psz_parser, *psz_tmp;
psz_parser = psz_tmp = psz_var;
while( *psz_tmp && *psz_tmp != 'x' ) psz_tmp++;
if( *psz_tmp )
{
psz_tmp[0] = '\0';
p_vout->p_sys->i_width = atoi( psz_parser );
psz_parser = ++psz_tmp;
while( *psz_tmp && *psz_tmp != '+' ) psz_tmp++;
if( *psz_tmp )
{
psz_tmp[0] = '\0';
p_vout->p_sys->i_height = atoi( psz_parser );
psz_parser = ++psz_tmp;
while( *psz_tmp && *psz_tmp != '+' ) psz_tmp++;
if( *psz_tmp )
{
psz_tmp[0] = '\0';
p_vout->p_sys->i_x = atoi( psz_parser );
p_vout->p_sys->i_y = atoi( ++psz_tmp );
}
else
{
p_vout->p_sys->i_x = atoi( psz_parser );
p_vout->p_sys->i_y =
( p_vout->output.i_height - p_vout->p_sys->i_height ) / 2;
}
}
else
{
p_vout->p_sys->i_height = atoi( psz_parser );
p_vout->p_sys->i_x =
( p_vout->output.i_width - p_vout->p_sys->i_width ) / 2;
p_vout->p_sys->i_y =
( p_vout->output.i_height - p_vout->p_sys->i_height ) / 2;
}
}
else
{
p_vout->p_sys->i_width = atoi( psz_parser );
p_vout->p_sys->i_height = p_vout->output.i_height;
p_vout->p_sys->i_x =
( p_vout->output.i_width - p_vout->p_sys->i_width ) / 2;
p_vout->p_sys->i_y =
( p_vout->output.i_height - p_vout->p_sys->i_height ) / 2;
}
/* Check for validity */
if( p_vout->p_sys->i_x + p_vout->p_sys->i_width
> p_vout->output.i_width )
{
p_vout->p_sys->i_x = 0;
if( p_vout->p_sys->i_width > p_vout->output.i_width )
{
p_vout->p_sys->i_width = p_vout->output.i_width;
}
}
if( p_vout->p_sys->i_y + p_vout->p_sys->i_height
> p_vout->output.i_height )
{
p_vout->p_sys->i_y = 0;
if( p_vout->p_sys->i_height > p_vout->output.i_height )
{
p_vout->p_sys->i_height = p_vout->output.i_height;
}
}
free( psz_var );
}
else
{
p_vout->p_sys->i_width = p_vout->output.i_width;
p_vout->p_sys->i_height = p_vout->output.i_height;
p_vout->p_sys->i_x = p_vout->p_sys->i_y = 0;
}
/* Pheeew. Parsing done. */
intf_WarnMsg( 3, "vout info: cropping at %ix%i+%i+%i, %sautocropping",
p_vout->p_sys->i_width, p_vout->p_sys->i_height,
p_vout->p_sys->i_x, p_vout->p_sys->i_y,
p_vout->p_sys->b_autocrop ? "" : "not " );
/* Set current output image properties */
p_vout->p_sys->i_aspect = p_vout->output.i_aspect
* p_vout->output.i_height / p_vout->p_sys->i_height
* p_vout->p_sys->i_width / p_vout->output.i_width;
/* Try to open the real video output */
psz_var = config_GetPszVariable( "filter" );
config_PutPszVariable( "filter", NULL );
intf_WarnMsg( 3, "vout info: spawning the real video outputs" );
p_vout->p_sys->p_vout =
vout_CreateThread( NULL,
p_vout->p_sys->i_width, p_vout->p_sys->i_height,
p_vout->render.i_chroma, p_vout->p_sys->i_aspect );
if( p_vout->p_sys->p_vout == NULL )
{
intf_ErrMsg( "vout error: failed to create vout" );
config_PutPszVariable( "filter", psz_var );
if( psz_var ) free( psz_var );
return 0;
}
config_PutPszVariable( "filter", psz_var );
if( psz_var ) free( psz_var );
ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
return 0;
}
/*****************************************************************************
* vout_End: terminate Crop video thread output method
*****************************************************************************/
static void vout_End( vout_thread_t *p_vout )
{
int i_index;
/* Free the fake output buffers we allocated */
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
free( PP_OUTPUTPICTURE[ i_index ]->p_data_orig );
}
}
/*****************************************************************************
* vout_Destroy: destroy Crop video thread output method
*****************************************************************************
* Terminate an output method created by CropCreateOutputMethod
*****************************************************************************/
static void vout_Destroy( vout_thread_t *p_vout )
{
vout_DestroyThread( p_vout->p_sys->p_vout, NULL );
free( p_vout->p_sys );
}
/*****************************************************************************
* vout_Manage: handle Crop events
*****************************************************************************
* This function should be called regularly by video output thread. It manages
* console events. It returns a non null value on error.
*****************************************************************************/
static int vout_Manage( vout_thread_t *p_vout )
{
if( !p_vout->p_sys->b_changed )
{
return 0;
}
vout_DestroyThread( p_vout->p_sys->p_vout, NULL );
p_vout->p_sys->p_vout =
vout_CreateThread( NULL,
p_vout->p_sys->i_width, p_vout->p_sys->i_height,
p_vout->render.i_chroma, p_vout->p_sys->i_aspect );
if( p_vout->p_sys->p_vout == NULL )
{
intf_ErrMsg( "vout error: failed to create vout" );
return 1;
}
p_vout->p_sys->b_changed = 0;
p_vout->p_sys->i_lastchange = 0;
return 0;
}
/*****************************************************************************
* vout_Render: display previously rendered output
*****************************************************************************
* This function sends the currently rendered image to Crop image, waits
* until it is displayed and switches the two rendering buffers, preparing next
* frame.
*****************************************************************************/
static void vout_Render( vout_thread_t *p_vout, picture_t *p_pic )
{
picture_t *p_outpic = NULL;
int i_plane;
if( p_vout->p_sys->b_changed )
{
return;
}
while( ( p_outpic =
vout_CreatePicture( p_vout->p_sys->p_vout, 0, 0, 0 )
) == NULL )
{
if( p_vout->b_die || p_vout->b_error )
{
vout_DestroyPicture( p_vout->p_sys->p_vout, p_outpic );
return;
}
msleep( VOUT_OUTMEM_SLEEP );
}
vout_DatePicture( p_vout->p_sys->p_vout, p_outpic, p_pic->date );
vout_LinkPicture( p_vout->p_sys->p_vout, p_outpic );
for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
{
u8 *p_in, *p_out, *p_out_end;
int i_in_pitch = p_pic->p[i_plane].i_pitch;
const int i_out_pitch = p_outpic->p[i_plane].i_pitch;
p_in = p_pic->p[i_plane].p_pixels
/* Skip the right amount of lines */
+ i_in_pitch * ( p_pic->p[i_plane].i_lines * p_vout->p_sys->i_y
/ p_vout->output.i_height )
/* Skip the right amount of columns */
+ i_in_pitch * p_vout->p_sys->i_x / p_vout->output.i_width;
p_out = p_outpic->p[i_plane].p_pixels;
p_out_end = p_out + i_out_pitch * p_outpic->p[i_plane].i_lines;
while( p_out < p_out_end )
{
FAST_MEMCPY( p_out, p_in, i_out_pitch );
p_in += i_in_pitch;
p_out += i_out_pitch;
}
}
vout_UnlinkPicture( p_vout->p_sys->p_vout, p_outpic );
vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic );
/* The source image may still be in the cache ... parse it! */
if( !p_vout->p_sys->b_autocrop )
{
return;
}
UpdateStats( p_vout, p_pic );
}
/*****************************************************************************
* vout_Display: displays previously rendered output
*****************************************************************************
* This function send the currently rendered image to Invert image, waits
* until it is displayed and switch the two rendering buffers, preparing next
* frame.
*****************************************************************************/
static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
{
;
}
static void UpdateStats( vout_thread_t *p_vout, picture_t *p_pic )
{
u8 *p_in = p_pic->p[0].p_pixels;
int i_pitch = p_pic->p[0].i_pitch;
int i_lines = p_pic->p[0].i_lines;
int i_firstwhite = -1, i_lastwhite = -1, i;
/* Determine where black borders are */
switch( p_vout->output.i_chroma )
{
case FOURCC_I420:
/* XXX: Do not laugh ! I know this is very naive. But it's just a
* proof of concept code snippet... */
for( i = i_lines ; i-- ; )
{
const int i_col = i * i_pitch / i_lines;
if( p_in[i_col/2] > 40
&& p_in[i_pitch / 2] > 40
&& p_in[i_pitch/2 + i_col/2] > 40 )
{
if( i_lastwhite == -1 )
{
i_lastwhite = i;
}
i_firstwhite = i;
}
p_in += i_pitch;
}
break;
default:
break;
}
/* Decide whether it's worth changing the size */
if( i_lastwhite == -1 )
{
p_vout->p_sys->i_lastchange = 0;
return;
}
if( i_lastwhite - i_firstwhite < p_vout->p_sys->i_height / 2 )
{
p_vout->p_sys->i_lastchange = 0;
return;
}
if( i_lastwhite - i_firstwhite < p_vout->p_sys->i_height + 16
&& i_lastwhite - i_firstwhite + 16 > p_vout->p_sys->i_height )
{
p_vout->p_sys->i_lastchange = 0;
return;
}
/* We need at least 25 images to make up our mind */
p_vout->p_sys->i_lastchange++;
if( p_vout->p_sys->i_lastchange < 25 )
{
return;
}
/* Tune a few values */
if( i_firstwhite & 1 )
{
i_firstwhite--;
}
if( !(i_lastwhite & 1) )
{
i_lastwhite++;
}
/* Change size */
p_vout->p_sys->i_y = i_firstwhite;
p_vout->p_sys->i_height = i_lastwhite - i_firstwhite + 1;
p_vout->p_sys->i_aspect = p_vout->output.i_aspect
* p_vout->output.i_height / p_vout->p_sys->i_height
* p_vout->p_sys->i_width / p_vout->output.i_width;
p_vout->p_sys->b_changed = 1;
}
qte_SOURCES = qte.c qte.cpp
#qte_CFLAGS = -I$(QTDIR)/include -DQT_QWS_IPAQ -DQWS -fno-exceptions -fno-rtti
#qte_LDFLAGS = -L$(QTDIR)/lib -lqpe -lqte
/*****************************************************************************
* qte.c : Qt Embedded video output
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: qte.c,v 1.1.2.1 2002/09/30 20:32:46 jpsaman Exp $
*
* Authors: Gerald Hansink <gerald.hansink@ordina.nl>
* Jean-Paul Saman <jpsaman@wxs.nl>
*
* 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 <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <videolan/vlc.h>
void _M( vout_getfunctions )( function_list_t * p_function_list );
MODULE_CONFIG_START
ADD_CATEGORY_HINT( N_("Miscellaneous"), NULL )
ADD_STRING ( "qte-display", NULL, NULL, NULL, NULL )
ADD_BOOL ( "qte-altfullscreen", NULL, NULL, NULL, NULL )
MODULE_CONFIG_STOP
MODULE_INIT_START
SET_DESCRIPTION( _("Qt Embedded video output module") )
ADD_CAPABILITY( VOUT, 150 )
ADD_SHORTCUT( "qtevlc" )
MODULE_INIT_STOP
MODULE_ACTIVATE_START
_M( vout_getfunctions )( &p_module->p_functions->vout );
MODULE_ACTIVATE_STOP
MODULE_DEACTIVATE_START
MODULE_DEACTIVATE_STOP
/*****************************************************************************
* qte.cpp : Qt Embedded video output plugin implementation
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: qte.cpp,v 1.1.2.1 2002/09/30 20:32:46 jpsaman Exp $
*
* Authors: Gerald Hansink <gerald.hansink@ordina.nl>
* Jean-Paul Saman <jpsaman@wxs.nl>
*
* 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.
*****************************************************************************/
/*****************************************************************************
* notes:
* - written for ipaq, so hardcoded assumptions specific for ipaq...
* - runs full screen
* - no "mouse events" handling
* - etc.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <qapplication.h>
#include <qpainter.h>
#ifdef Q_WS_QWS
# define USE_DIRECT_PAINTER
# include <qdirectpainter_qws.h>
# include <qgfxraster_qws.h>
#endif
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <videolan/vlc.h>
#ifdef HAVE_MACHINE_PARAM_H
/* BSD */
# include <machine/param.h>
# include <sys/types.h> /* typedef ushort */
# include <sys/ipc.h>
#endif
#ifndef WIN32
# include <netinet/in.h> /* BSD: struct in_addr */
#endif
#ifdef HAVE_SYS_SHM_H
# include <sys/shm.h> /* shmget(), shmctl() */
#endif
#include "video.h"
#include "video_output.h"
#include "interface.h"
#include "netutils.h" /* network_ChannelJoin */
#include "stream_control.h" /* needed by input_ext-intf.h... */
#include "input_ext-intf.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int vout_Create ( vout_thread_t * );
static void vout_Destroy ( vout_thread_t * );
static void vout_Render ( vout_thread_t *, picture_t * );
static void vout_Display ( vout_thread_t *, picture_t * );
static int vout_Manage ( vout_thread_t * );
static int vout_Init ( vout_thread_t * );
static void vout_End ( vout_thread_t * );
static int CreateQtWindow ( vout_thread_t * );
static void DestroyQtWindow( vout_thread_t * );
static int NewPicture ( vout_thread_t *, picture_t * );
static void FreePicture ( vout_thread_t *, picture_t * );
static void ToggleFullScreen ( vout_thread_t * );
static void* vout_run_qtapp_exec (void* pVoid);
/*****************************************************************************
* vout_sys_t: video output method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the specific properties of an video output plugin
*****************************************************************************/
typedef struct vout_sys_s
{
/* Internal settings and properties */
int i_width;
int i_height;
bool bRunning;
bool bOwnsQApp;
QApplication* pcQApplication;
QWidget* pcVoutWidget;
} vout_sys_t;
/*****************************************************************************
* picture_sys_t: direct buffer method descriptor
*****************************************************************************/
typedef struct picture_sys_s
{
QImage* pQImage;
} picture_sys_t;
/*****************************************************************************
* Chroma defines
*****************************************************************************/
#define QTE_MAX_DIRECTBUFFERS 2
/*****************************************************************************
* Seeking function TODO: put this in a generic location !
*****************************************************************************/
static inline void vout_Seek( off_t i_seek )
{
}
extern "C"
{
void _M( vout_getfunctions )( function_list_t * p_function_list );
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
*****************************************************************************/
void _M( vout_getfunctions )( function_list_t * p_function_list )
{
p_function_list->functions.vout.pf_create = vout_Create;
p_function_list->functions.vout.pf_init = vout_Init;
p_function_list->functions.vout.pf_end = vout_End;
p_function_list->functions.vout.pf_destroy = vout_Destroy;
p_function_list->functions.vout.pf_manage = vout_Manage;
p_function_list->functions.vout.pf_render = vout_Render;
p_function_list->functions.vout.pf_display = vout_Display;
}
}
/*****************************************************************************
* vout_Create: allocate video thread output method
*****************************************************************************/
static int vout_Create( vout_thread_t *p_vout )
{
//intf_ErrMsg( "+vout_Create::qte" );
/* Allocate structure */
p_vout->p_sys = (vout_sys_s*) malloc( sizeof( vout_sys_t ) );
if( p_vout->p_sys == NULL )
{
intf_ErrMsg( "vout error: %s", strerror(ENOMEM) );
return( 1 );
}
memset(p_vout->p_sys, 0, sizeof( vout_sys_t ));
CreateQtWindow(p_vout);
//intf_ErrMsg( "-vout_Create::qte\n" );
return( 0 );
}
/*****************************************************************************
* vout_Destroy: destroy video thread output method
*****************************************************************************
* Terminate an output method created by vout_Create
*****************************************************************************/
static void vout_Destroy( vout_thread_t *p_vout )
{
//intf_ErrMsg( "+vout_Destroy::qte\n" );
DestroyQtWindow(p_vout);
free(p_vout->p_sys);
}
/*****************************************************************************
* vout_Init: initialize video thread output method
*****************************************************************************
* This function create the buffers needed by the output thread. It is called
* at the beginning of the thread, but also each time the window is resized.
*****************************************************************************/
static int vout_Init( vout_thread_t *p_vout )
{
int i_index;
picture_t* p_pic;
int dd = QPixmap::defaultDepth();
//intf_ErrMsg( "+vout_Init::qte\n" );
I_OUTPUTPICTURES = 0;
p_vout->output.i_chroma = (dd == 16) ? FOURCC_RV16 : FOURCC_RV32;
p_vout->output.i_rmask = 0xf800;
p_vout->output.i_gmask = 0x07e0;
p_vout->output.i_bmask = 0x001f;
//p_vout->output.i_width = p_vout->render.i_width;
//p_vout->output.i_height = p_vout->render.i_height;
p_vout->output.i_width = p_vout->p_sys->i_width;
p_vout->output.i_height = p_vout->p_sys->i_height;
p_vout->output.i_aspect = p_vout->render.i_aspect;
/* Try to initialize MAX_DIRECTBUFFERS direct buffers */
while( I_OUTPUTPICTURES < QTE_MAX_DIRECTBUFFERS )
{
p_pic = NULL;
/* Find an empty picture slot */
for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
{
if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
{
p_pic = p_vout->p_picture + i_index;
break;
}
}
/* Allocate the picture */
if( p_pic == NULL || NewPicture( p_vout, p_pic ) )
{
break;
}
p_pic->i_status = DESTROYED_PICTURE;
p_pic->i_type = DIRECT_PICTURE;
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
I_OUTPUTPICTURES++;
}
//intf_ErrMsg( "-vout_Init::qte %d output pictures\n", I_OUTPUTPICTURES);
return( 0 );
}
/*****************************************************************************
* vout_Render: render previously calculated output
*****************************************************************************/
static void vout_Render( vout_thread_t *p_vout, picture_t *p_pic )
{
//intf_ErrMsg( "+vout_Render::qte\n" );
;
}
/*****************************************************************************
* vout_Display: displays previously rendered output
*****************************************************************************
* This function sends the currently rendered image to screen.
*****************************************************************************/
static void vout_Display( vout_thread_t *p_vout, picture_t *p_pic )
{
int x, y, w, h;
vout_PlacePicture( p_vout, p_vout->p_sys->i_width, p_vout->p_sys->i_height,
&x, &y, &w, &h );
if(p_vout->p_sys->pcVoutWidget)
{
// shameless borrowed from opie mediaplayer....
#ifndef USE_DIRECT_PAINTER
QPainter p(p_vout->p_sys->pcVoutWidget);
/* rotate frame */
int dd = QPixmap::defaultDepth();
int bytes = ( dd == 16 ) ? 2 : 4;
int rw = h, rh = w;
QImage rotatedFrame( rw, rh, bytes << 3 );
ushort* in = (ushort*)p_pic->p_sys->pQImage->bits();
ushort* out = (ushort*)rotatedFrame.bits();
int spl = rotatedFrame.bytesPerLine() / bytes;
for (int x=0; x<h; x++)
{
if ( bytes == 2 )
{
ushort* lout = out++ + (w - 1)*spl;
for (int y=0; y<w; y++)
{
*lout=*in++;
lout-=spl;
}
}
else
{
ulong* lout = ((ulong *)out)++ + (w - 1)*spl;
for (int y=0; y<w; y++)
{
*lout=*((ulong*)in)++;
lout-=spl;
}
}
}
p.drawImage( x, y, rotatedFrame, 0, 0, rw, rh );
#else
QDirectPainter p(p_vout->p_sys->pcVoutWidget);
// just copy the image to the frame buffer...
memcpy(p.frameBuffer(), (p_pic->p_sys->pQImage->jumpTable())[0], h * p.lineStep());
#endif
}
}
/*****************************************************************************
* vout_Manage: 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.
*****************************************************************************/
static int vout_Manage( vout_thread_t *p_vout )
{
//intf_ErrMsg( "+vout_Manage::qte\n" );
return 0;
}
/*****************************************************************************
* vout_End: terminate video thread output method
*****************************************************************************
* Destroy the buffers created by vout_Init. It is called at the end of
* the thread, but also each time the window is resized.
*****************************************************************************/
static void vout_End( vout_thread_t *p_vout )
{
int i_index;
//intf_ErrMsg( "+vout_End::qte\n" );
/* Free the direct buffers we allocated */
for( i_index = I_OUTPUTPICTURES ; i_index ; )
{
i_index--;
FreePicture( p_vout, PP_OUTPUTPICTURE[ i_index ] );
}
}
/*****************************************************************************
* NewPicture: allocate a picture
*****************************************************************************
* Returns 0 on success, -1 otherwise
*****************************************************************************/
static int NewPicture( vout_thread_t *p_vout, picture_t *p_pic )
{
int dd = QPixmap::defaultDepth();
//intf_ErrMsg( "+NewPicture::dd = %d\n",dd );
p_pic->p_sys = (picture_sys_t*) malloc( sizeof( picture_sys_t ) );
if( p_pic->p_sys == NULL )
{
return -1;
}
switch(p_vout->output.i_chroma)
{
case FOURCC_RV16:
if(dd == 16)
{
p_pic->p_sys->pQImage = new QImage(p_vout->output.i_width,
p_vout->output.i_height,
dd );
if(p_pic->p_sys->pQImage == NULL)
{
return -1;
}
p_pic->p->p_pixels = (p_pic->p_sys->pQImage->jumpTable())[0];
p_pic->p->i_pitch = p_pic->p_sys->pQImage->bytesPerLine();
p_pic->p->i_lines = p_vout->output.i_height;
p_pic->p->i_pixel_bytes = 2;
p_pic->p->b_margin = 0;
p_pic->i_planes = 1;
}
else
{
return -1;
}
break;
case FOURCC_RV32:
if(dd == 32)
{
p_pic->p_sys->pQImage = new QImage(p_vout->output.i_width,
p_vout->output.i_height,
dd );
if(p_pic->p_sys->pQImage == NULL)
{
return -1;
}
p_pic->p->p_pixels = (p_pic->p_sys->pQImage->jumpTable())[0];
p_pic->p->i_pitch = p_pic->p_sys->pQImage->bytesPerLine();
p_pic->p->i_lines = p_vout->output.i_height;
p_pic->p->i_pixel_bytes = 4;
p_pic->p->b_margin = 0;
p_pic->i_planes = 1;
}
else
{
return -1;
}
break;
default:
return -1;
break;
}
/*
intf_ErrMsg( "NewPicture: %d %d %d\n",p_vout->output.i_width,
p_vout->output.i_height,
p_vout->output.i_chroma );
*/
return 0;
}
/*****************************************************************************
* FreePicture: destroy a picture allocated with NewPicture
*****************************************************************************/
static void FreePicture( vout_thread_t *p_vout, picture_t *p_pic )
{
delete p_pic->p_sys->pQImage;
}
/*****************************************************************************
* ToggleFullScreen: Enable or disable full screen mode
*****************************************************************************
* This function will switch between fullscreen and window mode.
*
*****************************************************************************/
static void ToggleFullScreen ( vout_thread_t *p_vout )
{
}
/*****************************************************************************
* CreateQtWindow: create qte applicaton / window
*****************************************************************************
* Create a window according to video output given size, and set other
* properties according to the display properties.
*****************************************************************************/
static int CreateQtWindow( vout_thread_t *p_vout )
{
//intf_ErrMsg( "vout_qt: +init qt window");
/* for displaying the vout in a qt window we need the QtApplication */
vlc_thread_t thread_id;
//intf_ErrMsg( "vout_qt: +init qt window, creating qpe application");
p_vout->p_sys->pcVoutWidget = NULL;
/* create thread to exec the qpe application */
if ( vlc_thread_create( &thread_id, "vout qte",
(vlc_thread_func_t)vout_run_qtapp_exec,
(void *)p_vout) )
{
intf_ErrMsg( "input error: can't spawn vout thread");
return( -1 );
}
p_vout->p_sys->i_width = 320;
p_vout->p_sys->i_height = 240;
// just wait until the crew is complete...
while(p_vout->p_sys->pcVoutWidget == NULL)
{
msleep(1);
}
//intf_ErrMsg( "vout_qt: -init qt window");
return( 0 );
}
/*****************************************************************************
* DestroyQtWindow: destroy the window
*****************************************************************************/
static void DestroyQtWindow( vout_thread_t *p_vout )
{
// quit qt application loop
if(p_vout->p_sys->pcQApplication)
{
if(p_vout->p_sys->bOwnsQApp)
{
p_vout->p_sys->pcQApplication->quit();
}
else
{
p_vout->p_sys->bRunning = FALSE;
}
while(p_vout->p_sys->pcVoutWidget)
{
msleep(1);
}
}
}
/*****************************************************************************
* main loop of qtapplication
*****************************************************************************/
static void*
vout_run_qtapp_exec(void* pVoid)
{
int argc = 0;
char arg0[] = "vout qte";
vout_thread_t* p_vout = (vout_thread_t*) pVoid;
if(qApp == NULL)
{
QApplication* pApp = new QApplication(argc, NULL);
if(pApp)
{
p_vout->p_sys->pcQApplication = pApp;
p_vout->p_sys->bOwnsQApp = TRUE;
}
else
{
return NULL;
}
}
else
{
p_vout->p_sys->pcQApplication = qApp;
}
{
QWidget vo(0, "vout");
vo.showFullScreen();
vo.show();
p_vout->p_sys->pcVoutWidget = &vo;
p_vout->p_sys->bRunning = TRUE;
if(p_vout->p_sys->bOwnsQApp)
{
// run the main loop of qtapplication until someone says: 'quit'
p_vout->p_sys->pcQApplication->exec();
}
else
{
while(p_vout->p_sys->bRunning) msleep(100);
}
}
p_vout->p_sys->pcVoutWidget = NULL;
if(p_vout->p_sys->bOwnsQApp)
{
delete p_vout->p_sys->pcQApplication;
p_vout->p_sys->pcQApplication = NULL;
}
return 0;
}
/* XPM */
static char * familiar_forwardb16x16_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
" ",
" ",
" .. ... ",
" ... ... ",
" .... ... ",
" ..... ... ",
" ......... ",
" ......... ",
" ......... ",
" ..... ... ",
" .... ... ",
" ... ... ",
" .. ... ",
" ",
" ",
" "};
/* XPM */
static char * familiar_openb16x16_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
" ",
" ",
" .. ",
" .... ",
" ...... ",
" ........ ",
" .......... ",
" ............ ",
" ............ ",
" ",
" ............ ",
" ............ ",
" ............ ",
" ............ ",
" ",
" "};
/* XPM */
static char * familiar_pauseb16x16_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
" ",
" ",
" .... .... ",
" .... .... ",
" .... .... ",
" .... .... ",
" .... .... ",
" .... .... ",
" .... .... ",
" .... .... ",
" .... .... ",
" .... .... ",
" .... .... ",
" .... .... ",
" ",
" "};
/* XPM */
static char * familiar_playb16x16_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
" ",
" ",
" .. ",
" .... ",
" ...... ",
" ........ ",
" .......... ",
" ........... ",
" ........... ",
" .......... ",
" ........ ",
" ...... ",
" .... ",
" .. ",
" ",
" "};
/* XPM */
static char * familiar_preferencesb16x16_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
" ",
" ",
" ....... ",
" ......... ",
" ........... ",
" ..... ..... ",
" ..... ..... ",
" ..... ..... ",
" ..... ..... ",
" ..... ..... ",
" ..... ..... ",
" ..... ..... ",
" ........... ",
" ......... ",
" ....... ",
" "};
/* XPM */
static char * familiar_rewindb16x16_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
" ",
" ",
" ... .. ",
" ... ... ",
" ... .... ",
" ... ..... ",
" ......... ",
" ......... ",
" ......... ",
" ... ..... ",
" ... .... ",
" ... ... ",
" ... .. ",
" ",
" ",
" "};
/* XPM */
static char * familiar_stopb16x16_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
" ",
" ",
" ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ........ ",
" ",
" ",
" "};
/* XPM */
static char * vlc16x16_xpm[] = {
"16 16 71 1",
" c None",
". c #3E2201",
"+ c #B07732",
"@ c #483622",
"# c #653D0D",
"$ c #FFC462",
"% c #B68653",
"& c #9D815F",
"* c #F8CB8B",
"= c #F1CEA8",
"- c #BDB8B3",
"; c #E4ECF7",
"> c #FFFFFF",
", c #75706B",
"' c #F19827",
") c #F1B670",
"! c #FED69D",
"~ c #B78F65",
"{ c #693D07",
"] c #FF9000",
"^ c #FD8E0B",
"/ c #FEAA46",
"( c #F1B36D",
"_ c #918576",
": c #EDC797",
"< c #F1AE5F",
"[ c #FCC382",
"} c #FFECCE",
"| c #908B88",
"1 c #B6A38C",
"2 c #DADCDF",
"3 c #DFE9F5",
"4 c #FDFFFF",
"5 c #FEFFFF",
"6 c #D6C4B3",
"7 c #F18A09",
"8 c #F79822",
"9 c #F2A84F",
"0 c #FDBC71",
"a c #FCC079",
"b c #FABF7B",
"c c #362819",
"d c #8F4E00",
"e c #FB8C00",
"f c #FF8900",
"g c #FF8800",
"h c #FF9410",
"i c #FFAC4D",
"j c #F8C382",
"k c #AA7233",
"l c #A25500",
"m c #7B4300",
"n c #BA6600",
"o c #D17300",
"p c #D97B02",
"q c #E48102",
"r c #DC830F",
"s c #D88C2D",
"t c #DF8E27",
"u c #E38003",
"v c #884A00",
"w c #000000",
"x c #231300",
"y c #492800",
"z c #7B4500",
"A c #B66500",
"B c #C16900",
"C c #693600",
"D c #1F1000",
"E c #090400",
"F c #070400",
" ",
" . ",
" +@ ",
" #$% ",
" &*= ",
" -;>, ",
" ')!~ ",
" {]^/( ",
" _:<[}| ",
" 123456 ",
" 7890abc ",
" defghijkl ",
" mnopqrstuv ",
" wxyzABCDw ",
" EF ",
" "};
%define name vlc
%define vlc_ver 0.4.0
%define vlc_ver 0.4.6
%define version %vlc_ver
%define cvs 0
%if %{cvs}
%define cvsdate 20010619
%define release 0.%{cvsdate}mdk
%define release 0.%{cvsdate}
%define cvs_name %{name}-snapshot-%{cvsdate}-00
%else
%define release 1mdk
%define release 1
%endif
# The QT interface is not functional yet
%define plugin_qt 0
%define plugin_lirc 1
......@@ -31,12 +30,12 @@ License: GPL
Group: Video
URL: http://www.videolan.org/
Requires: vlc-gui
# yves 0.4.0-1mdk needed by ffmpeg builtin (i want MPEG4 support out of box)
# vlc-mad needed by ffmpeg builtin (i want MPEG4 support out of box)
Requires: vlc-mad
BuildRoot: %_tmppath/%name-%version-%release-root
Buildrequires: libncurses5-devel
Buildrequires: libqt2-devel
#Buildrequires: libqt2-devel
Buildrequires: libgtk+1.2-devel
Buildrequires: gnome-libs-devel
Buildrequires: db1-devel
......@@ -51,18 +50,16 @@ Buildrequires: liblirc-devel
Buildrequires: libffmpeg-devel
%description
VideoLAN is a free network-aware MPEG1, MPEG2, MPEG4 (aka DivX)
and DVD player.
The VideoLAN Client allows to play MPEG2 Transport Streams from the
network or from a file, as well as direct DVD playback.
VideoLAN is a project of students from the Ecole Centrale Paris.
This version add MPEG1 support, direct DVD support, DVD decryption,
arbitrary, seeking in the stream, pause, fast forward and slow motion,
hardware YUV acceleration and a few new interface features
including drag'n'drop.
You may install vlc-gnome, vlc-gtk and vlc-ncurses.
This package contains no CSS unscrambling functionality.
You need the libdvdcss library available from
VideoLAN is an OpenSource streaming solution for every OS developed by
students from the Ecole Centrale Paris and developers from all over the
World.
The VideoLAN Client (vlc) plays MPEG1, MPEG2 and MPEG4 (aka DivX) files,
DVDs, VCDs, SVCDs, from a satellite card, from an MPEG2 Transport
Streams sent by the VideoLAN Server (vls) or from a Web server (with the
HTTP input).
You may install vlc-gnome or vlc-gtk to have a nice graphical interface.
This package contains no CSS unscrambling functionality for DVDs ;
you need the libdvdcss library available from
http://www.videolan.org/libdvdcss/ or http://plf.zarb.org/
# intf plugins
......@@ -277,7 +274,6 @@ rm -fr %buildroot
%dir %{_libdir}/videolan/vlc
%{_libdir}/videolan/vlc/ac3_spdif.so
%{_libdir}/videolan/vlc/avi.so
%{_libdir}/videolan/vlc/dsp.so
%{_libdir}/videolan/vlc/dummy.so
%{_libdir}/videolan/vlc/dvd.so
%{_libdir}/videolan/vlc/fb.so
......@@ -287,6 +283,8 @@ rm -fr %buildroot
%{_libdir}/videolan/vlc/filter_invert.so
%{_libdir}/videolan/vlc/filter_transform.so
%{_libdir}/videolan/vlc/filter_wall.so
%{_libdir}/videolan/vlc/filter_clone.so
%{_libdir}/videolan/vlc/filter_crop.so
%{_libdir}/videolan/vlc/fx_scope.so
%{_libdir}/videolan/vlc/http.so
%{_libdir}/videolan/vlc/ipv4.so
......@@ -299,6 +297,7 @@ rm -fr %buildroot
%{_libdir}/videolan/vlc/mpeg_ps.so
%{_libdir}/videolan/vlc/mpeg_ts.so
%{_libdir}/videolan/vlc/null.so
%{_libdir}/videolan/vlc/dsp.so
%{_libdir}/videolan/vlc/rc.so
%{_libdir}/videolan/vlc/spudec.so
%{_libdir}/videolan/vlc/udp.so
......@@ -409,6 +408,18 @@ rm -fr %buildroot
%{_libdir}/videolan/vlc/alsa.so
%changelog
* Wed Nov 13 2002 Alexis de Lattre <alexis@videolan.org> 0.4.6
- new upstream release
* Mon Oct 14 2002 Alexis de Lattre <alexis@videolan.org> 0.4.5
- new upstream release
* Mon Jun 20 2002 Yves Duret <yduret@mandrakesoft.com> 0.4.2-1mdk
- new upstream release
* Mon Jun 3 2002 Yves Duret <yduret@mandrakesoft.com> 0.4.1-1mdk
- new upstream release
* Thu May 23 2002 Yves Duret <yduret@mandrakesoft.com> 0.4.0-1mdk
- version 0.4.0 with MPEG4 (DivX) support thx ffmpeg.
thus s/MPEG, MPEG2 and DVD/multimedia/g
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment