changeset 23:0db4a1dc75c4 trunk

[svn] libvisual. P3 detection appears to be borked. I'll work on it later.
author nenolod
date Mon, 24 Oct 2005 23:13:56 -0700
parents 696f87ed66e2
children 1b5332e32298
files Makefile.am Makefile.in configure configure.ac libvisual/Makefile.am libvisual/Makefile.in libvisual/libvisual.h libvisual/lv_actor.c libvisual/lv_actor.h libvisual/lv_audio.c libvisual/lv_audio.h libvisual/lv_bin.c libvisual/lv_bin.h libvisual/lv_bmp.c libvisual/lv_bmp.h libvisual/lv_color.c libvisual/lv_color.h libvisual/lv_common.h libvisual/lv_cpu.c libvisual/lv_cpu.h libvisual/lv_endianess.h libvisual/lv_error.c libvisual/lv_error.h libvisual/lv_event.c libvisual/lv_event.h libvisual/lv_fft.c libvisual/lv_fft.h libvisual/lv_input.c libvisual/lv_input.h libvisual/lv_keysym.h libvisual/lv_libvisual.c libvisual/lv_libvisual.h libvisual/lv_list.c libvisual/lv_list.h libvisual/lv_log.c libvisual/lv_log.h libvisual/lv_mem.c libvisual/lv_mem.h libvisual/lv_morph.c libvisual/lv_morph.h libvisual/lv_object.c libvisual/lv_object.h libvisual/lv_palette.c libvisual/lv_palette.h libvisual/lv_param.c libvisual/lv_param.h libvisual/lv_plugin.c libvisual/lv_plugin.h libvisual/lv_random.c libvisual/lv_random.h libvisual/lv_songinfo.c libvisual/lv_songinfo.h libvisual/lv_thread.c libvisual/lv_thread.h libvisual/lv_time.c libvisual/lv_time.h libvisual/lv_transform.c libvisual/lv_transform.h libvisual/lv_types.h libvisual/lv_ui.c libvisual/lv_ui.h libvisual/lv_video.c libvisual/lv_video.h libvisual/lv_video_mmx.c libvisual/lvconfig.h
diffstat 65 files changed, 18234 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.am	Mon Oct 24 20:25:00 2005 -0700
+++ b/Makefile.am	Mon Oct 24 23:13:56 2005 -0700
@@ -1,6 +1,6 @@
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = intl libaudacious audacious Output Input Visualization po icons skin
+SUBDIRS = intl libaudacious libvisual audacious Output Input Visualization po icons skin
 
 man_MANS = audacious.1
 
--- a/Makefile.in	Mon Oct 24 20:25:00 2005 -0700
+++ b/Makefile.in	Mon Oct 24 23:13:56 2005 -0700
@@ -296,7 +296,7 @@
 target_os = @target_os@
 target_vendor = @target_vendor@
 ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = intl libaudacious audacious Output Input Visualization po icons skin
+SUBDIRS = intl libaudacious libvisual audacious Output Input Visualization po icons skin
 man_MANS = audacious.1
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = audacious.pc
--- a/configure	Mon Oct 24 20:25:00 2005 -0700
+++ b/configure	Mon Oct 24 23:13:56 2005 -0700
@@ -28907,7 +28907,7 @@
 
 
 
-                                                                                                                                                                                                                                                                                                  ac_config_files="$ac_config_files Makefile audacious.1 audacious.spec audacious.pc audacious/audacious.desktop audacious/Makefile audacious/glade/Makefile audacious/images/Makefile libaudacious/Makefile Output/Makefile Output/OSS/Makefile Output/esd/Makefile Output/alsa/Makefile Input/Makefile Input/mpg123/Makefile Input/aac/Makefile Input/aac/libmp4v2/Makefile Input/aac/libfaad2/Makefile Input/aac/src/Makefile Input/tonegen/Makefile Input/vorbis/Makefile Input/cdaudio/Makefile Input/wav/Makefile Visualization/Makefile Visualization/blur_scope/Makefile po/Makefile.in intl/Makefile icons/Makefile skin/Makefile"
+                                                                                                                                                                                                                                                                                                            ac_config_files="$ac_config_files Makefile audacious.1 audacious.spec audacious.pc audacious/audacious.desktop audacious/Makefile audacious/glade/Makefile audacious/images/Makefile libaudacious/Makefile libvisual/Makefile Output/Makefile Output/OSS/Makefile Output/esd/Makefile Output/alsa/Makefile Input/Makefile Input/mpg123/Makefile Input/aac/Makefile Input/aac/libmp4v2/Makefile Input/aac/libfaad2/Makefile Input/aac/src/Makefile Input/tonegen/Makefile Input/vorbis/Makefile Input/cdaudio/Makefile Input/wav/Makefile Visualization/Makefile Visualization/blur_scope/Makefile po/Makefile.in intl/Makefile icons/Makefile skin/Makefile"
 
 
 cat >confcache <<\_ACEOF
@@ -29587,6 +29587,7 @@
   "audacious/glade/Makefile" ) CONFIG_FILES="$CONFIG_FILES audacious/glade/Makefile" ;;
   "audacious/images/Makefile" ) CONFIG_FILES="$CONFIG_FILES audacious/images/Makefile" ;;
   "libaudacious/Makefile" ) CONFIG_FILES="$CONFIG_FILES libaudacious/Makefile" ;;
+  "libvisual/Makefile" ) CONFIG_FILES="$CONFIG_FILES libvisual/Makefile" ;;
   "Output/Makefile" ) CONFIG_FILES="$CONFIG_FILES Output/Makefile" ;;
   "Output/OSS/Makefile" ) CONFIG_FILES="$CONFIG_FILES Output/OSS/Makefile" ;;
   "Output/esd/Makefile" ) CONFIG_FILES="$CONFIG_FILES Output/esd/Makefile" ;;
--- a/configure.ac	Mon Oct 24 20:25:00 2005 -0700
+++ b/configure.ac	Mon Oct 24 23:13:56 2005 -0700
@@ -592,6 +592,7 @@
         audacious/glade/Makefile
 	audacious/images/Makefile
         libaudacious/Makefile
+	libvisual/Makefile
         Output/Makefile
         Output/OSS/Makefile
         Output/esd/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/Makefile.am	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,36 @@
+## Process this file with automake to generate a Makefile.in
+
+library_includedir = $(includedir)/libvisual
+library_include_HEADERS = lvconfig.h libvisual.h lv_actor.h \
+			  lv_audio.h lv_bin.h lv_common.h lv_fft.h \
+			  lv_input.h lv_event.h lv_keysym.h \
+			  lv_list.h lv_log.h lv_palette.h lv_plugin.h \
+			  lv_video.h lv_libvisual.h lv_songinfo.h \
+			  lv_morph.h lv_bmp.h lv_param.h lv_mem.h \
+			  lv_endianess.h lv_cpu.h lv_color.h \
+			  lv_time.h lv_random.h lv_error.h lv_ui.h \
+			  lv_types.h lv_thread.h lv_object.h \
+			  lv_transform.h
+
+lib_LTLIBRARIES = libvisual.la
+
+DEFS = @DEFS@
+
+LIBS += -L. -L$(libdir)
+
+PLUGPATH = $(libdir)/libvisual
+
+AM_CFLAGS = -DPLUGPATH="\"$(plugindir)/$(VISUALIZATION_PLUGIN_DIR)\""
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/libvisual \
+	   -I$(top_builddir) -I$(top_builddir)/libvisual
+
+libvisual_la_LDFLAGS = -export-dynamic -no-undefined
+
+libvisual_la_SOURCES = lv_actor.c lv_input.c lv_event.c \
+		       lv_bin.c lv_plugin.c lv_video.c lv_video_mmx.c lv_mem.c \
+		       lv_audio.c lv_fft.c lv_list.c lv_log.c lv_palette.c \
+		       lv_libvisual.c lv_songinfo.c lv_morph.c lv_bmp.c lv_param.c \
+		       lv_cpu.c lv_color.c lv_time.c lv_random.c lv_error.c lv_ui.c \
+		       lv_thread.c lv_object.c lv_transform.c
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/Makefile.in	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,637 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = libvisual
+DIST_COMMON = $(library_include_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/codeset.m4 \
+	$(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc21.m4 \
+	$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intdiv0.m4 \
+	$(top_srcdir)/m4/inttypes-pri.m4 $(top_srcdir)/m4/inttypes.m4 \
+	$(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/lcmessage.m4 \
+	$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+	$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/nls.m4 \
+	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \
+	$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/stdint_h.m4 \
+	$(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/ulonglong.m4 \
+	$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" \
+	"$(DESTDIR)$(library_includedir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libvisual_la_LIBADD =
+am_libvisual_la_OBJECTS = lv_actor.lo lv_input.lo lv_event.lo \
+	lv_bin.lo lv_plugin.lo lv_video.lo lv_video_mmx.lo lv_mem.lo \
+	lv_audio.lo lv_fft.lo lv_list.lo lv_log.lo lv_palette.lo \
+	lv_libvisual.lo lv_songinfo.lo lv_morph.lo lv_bmp.lo \
+	lv_param.lo lv_cpu.lo lv_color.lo lv_time.lo lv_random.lo \
+	lv_error.lo lv_ui.lo lv_thread.lo lv_object.lo lv_transform.lo
+libvisual_la_OBJECTS = $(am_libvisual_la_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libvisual_la_SOURCES)
+DIST_SOURCES = $(libvisual_la_SOURCES)
+library_includeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(library_include_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALSA_CFLAGS = @ALSA_CFLAGS@
+ALSA_LIBS = @ALSA_LIBS@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+ARCH_DEFINES = @ARCH_DEFINES@
+ARCH_X86_FALSE = @ARCH_X86_FALSE@
+ARCH_X86_TRUE = @ARCH_X86_TRUE@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BEEP_DEFINES = @BEEP_DEFINES@
+BEEP_PATH = @BEEP_PATH@
+BMP_RCPATH = @BMP_RCPATH@
+BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EFFECT_PLUGINS = @EFFECT_PLUGINS@
+EFFECT_PLUGIN_DIR = @EFFECT_PLUGIN_DIR@
+EGREP = @EGREP@
+ENABLE_AAC_FALSE = @ENABLE_AAC_FALSE@
+ENABLE_AAC_TRUE = @ENABLE_AAC_TRUE@
+ENABLE_MPG123_FALSE = @ENABLE_MPG123_FALSE@
+ENABLE_MPG123_TRUE = @ENABLE_MPG123_TRUE@
+ESD_CFLAGS = @ESD_CFLAGS@
+ESD_LIBS = @ESD_LIBS@
+EXEEXT = @EXEEXT@
+GCONF_CFLAGS = @GCONF_CFLAGS@
+GCONF_LIBS = @GCONF_LIBS@
+GENCAT = @GENCAT@
+GENERAL_PLUGINS = @GENERAL_PLUGINS@
+GENERAL_PLUGIN_DIR = @GENERAL_PLUGIN_DIR@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GNOMEVFS_CFLAGS = @GNOMEVFS_CFLAGS@
+GNOMEVFS_LIBS = @GNOMEVFS_LIBS@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+HAVE_ALSA_FALSE = @HAVE_ALSA_FALSE@
+HAVE_ALSA_TRUE = @HAVE_ALSA_TRUE@
+HAVE_CDROM_FALSE = @HAVE_CDROM_FALSE@
+HAVE_CDROM_TRUE = @HAVE_CDROM_TRUE@
+HAVE_ESD_FALSE = @HAVE_ESD_FALSE@
+HAVE_ESD_TRUE = @HAVE_ESD_TRUE@
+HAVE_GCONF_FALSE = @HAVE_GCONF_FALSE@
+HAVE_GCONF_TRUE = @HAVE_GCONF_TRUE@
+HAVE_GNOME_VFS_FALSE = @HAVE_GNOME_VFS_FALSE@
+HAVE_GNOME_VFS_TRUE = @HAVE_GNOME_VFS_TRUE@
+HAVE_LINUX_JOYSTICK_FALSE = @HAVE_LINUX_JOYSTICK_FALSE@
+HAVE_LINUX_JOYSTICK_TRUE = @HAVE_LINUX_JOYSTICK_TRUE@
+HAVE_OGGVORBIS_FALSE = @HAVE_OGGVORBIS_FALSE@
+HAVE_OGGVORBIS_TRUE = @HAVE_OGGVORBIS_TRUE@
+HAVE_OSS_FALSE = @HAVE_OSS_FALSE@
+HAVE_OSS_TRUE = @HAVE_OSS_TRUE@
+HAVE_SOLARIS_FALSE = @HAVE_SOLARIS_FALSE@
+HAVE_SOLARIS_TRUE = @HAVE_SOLARIS_TRUE@
+HAVE_SUN_FALSE = @HAVE_SUN_FALSE@
+HAVE_SUN_TRUE = @HAVE_SUN_TRUE@
+ID3LIBS = @ID3LIBS@
+INPUT_PLUGINS = @INPUT_PLUGINS@
+INPUT_PLUGIN_DIR = @INPUT_PLUGIN_DIR@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLBISON = @INTLBISON@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
+LDFLAGS = @LDFLAGS@
+LIBBEEP_MAJOR_VERSION = @LIBBEEP_MAJOR_VERSION@
+LIBBEEP_MICRO_VERSION = @LIBBEEP_MICRO_VERSION@
+LIBBEEP_MINOR_VERSION = @LIBBEEP_MINOR_VERSION@
+LIBGLADE_CFLAGS = @LIBGLADE_CFLAGS@
+LIBGLADE_LIBS = @LIBGLADE_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@ -L. -L$(libdir)
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+OGG_VORBIS_CFLAGS = @OGG_VORBIS_CFLAGS@
+OGG_VORBIS_LIBS = @OGG_VORBIS_LIBS@
+OUTPUT_PLUGINS = @OUTPUT_PLUGINS@
+OUTPUT_PLUGIN_DIR = @OUTPUT_PLUGIN_DIR@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PC_REQUIRES = @PC_REQUIRES@
+PKG_CONFIG = @PKG_CONFIG@
+PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+USE_SIMD_FALSE = @USE_SIMD_FALSE@
+USE_SIMD_TRUE = @USE_SIMD_TRUE@
+USE_X86ASM_FALSE = @USE_X86ASM_FALSE@
+USE_X86ASM_TRUE = @USE_X86ASM_TRUE@
+VERSION = @VERSION@
+VISUALIZATION_PLUGINS = @VISUALIZATION_PLUGINS@
+VISUALIZATION_PLUGIN_DIR = @VISUALIZATION_PLUGIN_DIR@
+XGETTEXT = @XGETTEXT@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+beepdir = @beepdir@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+pluginsubs = @pluginsubs@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+library_includedir = $(includedir)/libvisual
+library_include_HEADERS = lvconfig.h libvisual.h lv_actor.h \
+			  lv_audio.h lv_bin.h lv_common.h lv_fft.h \
+			  lv_input.h lv_event.h lv_keysym.h \
+			  lv_list.h lv_log.h lv_palette.h lv_plugin.h \
+			  lv_video.h lv_libvisual.h lv_songinfo.h \
+			  lv_morph.h lv_bmp.h lv_param.h lv_mem.h \
+			  lv_endianess.h lv_cpu.h lv_color.h \
+			  lv_time.h lv_random.h lv_error.h lv_ui.h \
+			  lv_types.h lv_thread.h lv_object.h \
+			  lv_transform.h
+
+lib_LTLIBRARIES = libvisual.la
+PLUGPATH = $(libdir)/libvisual
+AM_CFLAGS = -DPLUGPATH="\"$(plugindir)/$(VISUALIZATION_PLUGIN_DIR)\""
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/libvisual \
+	   -I$(top_builddir) -I$(top_builddir)/libvisual
+
+libvisual_la_LDFLAGS = -export-dynamic -no-undefined
+libvisual_la_SOURCES = lv_actor.c lv_input.c lv_event.c \
+		       lv_bin.c lv_plugin.c lv_video.c lv_video_mmx.c lv_mem.c \
+		       lv_audio.c lv_fft.c lv_list.c lv_log.c lv_palette.c \
+		       lv_libvisual.c lv_songinfo.c lv_morph.c lv_bmp.c lv_param.c \
+		       lv_cpu.c lv_color.c lv_time.c lv_random.c lv_error.c lv_ui.c \
+		       lv_thread.c lv_object.c lv_transform.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  libvisual/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  libvisual/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    f=$(am__strip_dir) \
+	    echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+	    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+	  else :; fi; \
+	done
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  p=$(am__strip_dir) \
+	  echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+	  $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+	done
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" != "$$p" || dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+libvisual.la: $(libvisual_la_OBJECTS) $(libvisual_la_DEPENDENCIES) 
+	$(LINK) -rpath $(libdir) $(libvisual_la_LDFLAGS) $(libvisual_la_OBJECTS) $(libvisual_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_actor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_audio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_bin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_bmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_color.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_cpu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_event.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_fft.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_input.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_libvisual.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_list.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_log.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_mem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_morph.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_object.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_palette.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_param.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_random.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_songinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_thread.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_time.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_transform.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_ui.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_video.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lv_video_mmx.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool
+uninstall-info-am:
+install-library_includeHEADERS: $(library_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(library_includedir)" || $(mkdir_p) "$(DESTDIR)$(library_includedir)"
+	@list='$(library_include_HEADERS)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(am__strip_dir) \
+	  echo " $(library_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(library_includedir)/$$f'"; \
+	  $(library_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(library_includedir)/$$f"; \
+	done
+
+uninstall-library_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(library_include_HEADERS)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(library_includedir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(library_includedir)/$$f"; \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(library_includedir)"; do \
+	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-library_includeHEADERS
+
+install-exec-am: install-libLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES \
+	uninstall-library_includeHEADERS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-libLTLIBRARIES clean-libtool ctags distclean \
+	distclean-compile distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-exec \
+	install-exec-am install-info install-info-am \
+	install-libLTLIBRARIES install-library_includeHEADERS \
+	install-man install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-info-am uninstall-libLTLIBRARIES \
+	uninstall-library_includeHEADERS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/libvisual.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,59 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef LV_LIBVISUAL_H
+#define LV_LIBVISUAL_H
+
+#include <libvisual/lvconfig.h>
+
+#include <libvisual/lv_endianess.h>
+#include <libvisual/lv_time.h>
+#include <libvisual/lv_color.h>
+#include <libvisual/lv_param.h>
+#include <libvisual/lv_cpu.h>
+#include <libvisual/lv_bin.h>
+#include <libvisual/lv_event.h>
+#include <libvisual/lv_keysym.h>
+#include <libvisual/lv_actor.h>
+#include <libvisual/lv_input.h>
+#include <libvisual/lv_audio.h>
+#include <libvisual/lv_fft.h>
+#include <libvisual/lv_list.h>
+#include <libvisual/lv_palette.h>
+#include <libvisual/lv_plugin.h>
+#include <libvisual/lv_video.h>
+#include <libvisual/lv_libvisual.h>
+#include <libvisual/lv_songinfo.h>
+#include <libvisual/lv_morph.h>
+#include <libvisual/lv_transform.h>
+#include <libvisual/lv_bmp.h>
+#include <libvisual/lv_log.h>
+#include <libvisual/lv_random.h>
+#include <libvisual/lv_ui.h>
+#include <libvisual/lv_error.h>
+#include <libvisual/lv_thread.h>
+#include <libvisual/lv_object.h>
+#include <libvisual/lv_types.h>
+#include <libvisual/lv_common.h>
+
+#endif /* LV_LIBVISUAL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_actor.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,719 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lvconfig.h"
+#include "lv_log.h"
+#include "lv_list.h"
+#include "lv_actor.h"
+#include "lv_mem.h"
+
+extern VisList *__lv_plugins_actor;
+
+static int actor_dtor (VisObject *object);
+
+static VisActorPlugin *get_actor_plugin (VisActor *actor);
+static int negotiate_video_with_unsupported_depth (VisActor *actor, int rundepth, int noevent, int forced);
+static int negotiate_video (VisActor *actor, int noevent);
+
+
+static int actor_dtor (VisObject *object)
+{
+	VisActor *actor = VISUAL_ACTOR (object);
+
+	if (actor->plugin != NULL)
+		visual_plugin_unload (actor->plugin);
+
+	if (actor->transform != NULL)
+		visual_object_unref (VISUAL_OBJECT (actor->transform));
+
+	if (actor->fitting != NULL)
+		visual_object_unref (VISUAL_OBJECT (actor->fitting));
+
+	visual_object_unref (VISUAL_OBJECT (&actor->songcompare));
+
+	actor->plugin = NULL;
+	actor->transform = NULL;
+	actor->fitting = NULL;
+
+	return VISUAL_OK;
+}
+
+static VisActorPlugin *get_actor_plugin (VisActor *actor)
+{
+	VisActorPlugin *actplugin;
+
+	visual_log_return_val_if_fail (actor != NULL, NULL);
+	visual_log_return_val_if_fail (actor->plugin != NULL, NULL);
+
+	actplugin = VISUAL_PLUGIN_ACTOR (actor->plugin->info->plugin);
+
+	return actplugin;
+}
+
+/**
+ * @defgroup VisActor VisActor
+ * @{
+ */
+
+/**
+ * Gives the encapsulated VisPluginData from a VisActor.
+ *
+ * @param actor Pointer of a VisActor of which the VisPluginData needs to be returned.
+ *
+ * @return VisPluginData that is encapsulated in the VisActor, possibly NULL.
+ */
+VisPluginData *visual_actor_get_plugin (VisActor *actor)
+{
+	return actor->plugin;
+}
+
+/**
+ * Gives a list of VisActors in the current plugin registry.
+ *
+ * @return An VisList containing the VisActors in the plugin registry.
+ */
+VisList *visual_actor_get_list ()
+{
+	return __lv_plugins_actor;
+}
+
+/** @todo find a way to NOT load, unload the plugins */
+
+/**
+ * Gives the next actor plugin based on the name of a plugin but skips non
+ * GL plugins.
+ *
+ * @see visual_actor_get_prev_by_name_gl
+ *
+ * @param name The name of the current plugin or NULL to get the first.
+ *
+ * @return The name of the next plugin within the list that is a GL plugin.
+ */
+const char *visual_actor_get_next_by_name_gl (const char *name)
+{
+	const char *next = name;
+	VisPluginData *plugin;
+	VisPluginRef *ref;
+	VisActorPlugin *actplugin;
+	int gl;
+
+	do {
+		next = visual_plugin_get_next_by_name (visual_actor_get_list (), next);
+
+		if (next == NULL)
+			return NULL;
+		
+		ref = visual_plugin_find (__lv_plugins_actor, next);
+		plugin = visual_plugin_load (ref);
+
+		actplugin = VISUAL_PLUGIN_ACTOR (plugin->info->plugin);
+
+		if ((actplugin->depth & VISUAL_VIDEO_DEPTH_GL) > 0)
+			gl = TRUE;
+		else
+			gl = FALSE;
+	
+		visual_plugin_unload (plugin);
+
+	} while (gl == FALSE);
+
+	return next;
+}
+
+/**
+ * Gives the previous actor plugin based on the name of a plugin but skips non
+ * GL plugins.
+ *
+ * @see visual_actor_get_next_by_name_gl
+ *
+ * @param name The name of the current plugin or NULL to get the last.
+ *
+ * @return The name of the previous plugin within the list that is a GL plugin.
+ */
+const char *visual_actor_get_prev_by_name_gl (const char *name)
+{
+	const char *prev = name;
+	VisPluginData *plugin;
+	VisPluginRef *ref;
+	VisActorPlugin *actplugin;
+	int gl;
+
+	do {
+		prev = visual_plugin_get_prev_by_name (visual_actor_get_list (), prev);
+
+		if (prev == NULL)
+			return NULL;
+		
+		ref = visual_plugin_find (__lv_plugins_actor, prev);
+		plugin = visual_plugin_load (ref);
+		actplugin = VISUAL_PLUGIN_ACTOR (plugin->info->plugin);
+
+		if ((actplugin->depth & VISUAL_VIDEO_DEPTH_GL) > 0)
+			gl = TRUE;
+		else
+			gl = FALSE;
+	
+		visual_plugin_unload (plugin);
+
+	} while (gl == FALSE);
+
+	return prev;
+}
+
+/**
+ * Gives the next actor plugin based on the name of a plugin but skips
+ * GL plugins.
+ *
+ * @see visual_actor_get_prev_by_name_nogl
+ *
+ * @param name The name of the current plugin or NULL to get the first.
+ *
+ * @return The name of the next plugin within the list that is not a GL plugin.
+ */
+const char *visual_actor_get_next_by_name_nogl (const char *name)
+{
+	const char *next = name;
+	VisPluginData *plugin;
+	VisPluginRef *ref;
+	VisActorPlugin *actplugin;
+	int gl;
+
+	do {
+		next = visual_plugin_get_next_by_name (visual_actor_get_list (), next);
+
+		if (next == NULL)
+			return NULL;
+		
+		ref = visual_plugin_find (__lv_plugins_actor, next);
+		plugin = visual_plugin_load (ref);
+		actplugin = VISUAL_PLUGIN_ACTOR (plugin->info->plugin);
+
+		if ((actplugin->depth & VISUAL_VIDEO_DEPTH_GL) > 0)
+			gl = TRUE;
+		else
+			gl = FALSE;
+	
+		visual_plugin_unload (plugin);
+
+	} while (gl == TRUE);
+
+	return next;
+}
+
+/**
+ * Gives the previous actor plugin based on the name of a plugin but skips
+ * GL plugins.
+ *
+ * @see visual_actor_get_next_by_name_nogl
+ *
+ * @param name The name of the current plugin or NULL to get the last.
+ *
+ * @return The name of the previous plugin within the list that is not a GL plugin.
+ */
+const char *visual_actor_get_prev_by_name_nogl (const char *name)
+{
+	const char *prev = name;
+	VisPluginData *plugin;
+	VisPluginRef *ref;
+	VisActorPlugin *actplugin;
+	int gl;
+
+	do {
+		prev = visual_plugin_get_prev_by_name (visual_actor_get_list (), prev);
+
+		if (prev == NULL)
+			return NULL;
+		
+		ref = visual_plugin_find (__lv_plugins_actor, prev);
+		plugin = visual_plugin_load (ref);
+		actplugin = VISUAL_PLUGIN_ACTOR (plugin->info->plugin);
+
+		if ((actplugin->depth & VISUAL_VIDEO_DEPTH_GL) > 0)
+			gl = TRUE;
+		else
+			gl = FALSE;
+	
+		visual_plugin_unload (plugin);
+
+	} while (gl == TRUE);
+
+	return prev;
+}
+
+/**
+ * Gives the next actor plugin based on the name of a plugin.
+ *
+ * @see visual_actor_get_prev_by_name
+ * 
+ * @param name The name of the current plugin, or NULL to get the first.
+ *
+ * @return The name of the next plugin within the list.
+ */
+const char *visual_actor_get_next_by_name (const char *name)
+{
+	return visual_plugin_get_next_by_name (visual_actor_get_list (), name);
+}
+
+/**
+ * Gives the previous actor plugin based on the name of a plugin.
+ *
+ * @see visual_actor_get_next_by_name
+ * 
+ * @param name The name of the current plugin. or NULL to get the last.
+ *
+ * @return The name of the previous plugin within the list.
+ */
+const char *visual_actor_get_prev_by_name (const char *name)
+{
+	return visual_plugin_get_prev_by_name (visual_actor_get_list (), name);
+}
+
+/**
+ * Checks if the actor plugin is in the registry, based on it's name.
+ *
+ * @param name The name of the plugin that needs to be checked.
+ *
+ * @return TRUE if found, else FALSE.
+ */
+int visual_actor_valid_by_name (const char *name)
+{
+	if (visual_plugin_find (visual_actor_get_list (), name) == NULL)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+/**
+ * Creates a new actor from name, the plugin will be loaded but won't be realized.
+ *
+ * @param actorname
+ * 	The name of the plugin to load, or NULL to simply allocate a new
+ * 	actor. 
+ *
+ * @return A newly allocated VisActor, optionally containing a loaded plugin. Or NULL on failure.
+ */
+VisActor *visual_actor_new (const char *actorname)
+{
+	VisActor *actor;
+	VisPluginRef *ref;
+
+	if (__lv_plugins_actor == NULL && actorname != NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "the plugin list is NULL");
+		return NULL;
+	}
+	
+	actor = visual_mem_new0 (VisActor, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (actor), TRUE, actor_dtor);
+
+	if (actorname == NULL)
+		return actor;
+
+	ref = visual_plugin_find (__lv_plugins_actor, actorname);
+
+	actor->plugin = visual_plugin_load (ref);
+
+	return actor;
+}
+
+/**
+ * Realize the VisActor. This also calls the plugin init function.
+ *
+ * @param actor Pointer to a VisActor that needs to be realized.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_ACTOR_NULL, -VISUAL_ERROR_PLUGIN_NULL or
+ *	error values returned by visual_plugin_realize () on failure.
+ * 
+ */
+int visual_actor_realize (VisActor *actor)
+{
+	visual_log_return_val_if_fail (actor != NULL, -VISUAL_ERROR_ACTOR_NULL);
+	visual_log_return_val_if_fail (actor->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+
+	return visual_plugin_realize (actor->plugin);
+}
+
+/**
+ * Gives a pointer to the song info data within the VisActor. This song info data can be used
+ * to set name, artist and even coverart which can be used by the plugins and the framework itself.
+ *
+ * @see VisSongInfo
+ *
+ * @param actor Pointer to a VisActor of which the song info is needed.
+ *
+ * @return Pointer to the song info structure on succes or NULL on failure.
+ */
+VisSongInfo *visual_actor_get_songinfo (VisActor *actor)
+{
+	VisActorPlugin *actplugin;
+
+	visual_log_return_val_if_fail (actor != NULL, NULL);
+
+	actplugin = get_actor_plugin (actor);
+	visual_log_return_val_if_fail (actplugin != NULL, NULL);
+
+	return &actplugin->songinfo;
+}
+
+/**
+ * Gives a pointer to the palette within the VisActor. This can be needed to set a palette on the target
+ * display when it's in index mode.
+ *
+ * @see VisPalette
+ *
+ * @param actor Pointer to a VisActor of which the palette is needed.
+ *
+ * @return Pointer to the palette structure on succes or NULL on failure. Also it's possible that NULL
+ * is returned when the plugin is running in a full color mode or openGL. The returned palette is
+ * read only.
+ */
+VisPalette *visual_actor_get_palette (VisActor *actor)
+{
+	VisActorPlugin *actplugin;
+
+	visual_log_return_val_if_fail (actor != NULL, NULL);
+
+	actplugin = get_actor_plugin (actor);
+	
+	if (actplugin == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL,
+			"The given actor does not reference any actor plugin");
+		return NULL;
+	}
+
+	if (actor->transform != NULL &&
+		actor->video->depth == VISUAL_VIDEO_DEPTH_8BIT) {
+		
+		return actor->ditherpal;
+
+	} else {
+		return actplugin->palette (visual_actor_get_plugin (actor));
+	}
+
+	return NULL;
+}
+
+/**
+ * This function negotiates the VisActor with it's target video that is set by visual_actor_set_video.
+ * When needed it also sets up size fitting environment and depth transformation environment.
+ *
+ * The function has a few extra arguments that are mainly to be used from within internal code.
+ *
+ * This function needs to be called everytime there is a change within either the size or depth of
+ * the target video. 
+ *
+ * The main method of calling this function is: "visual_actor_video_negotiate (actor, 0, FALSE, FALSE)"
+ * 
+ * @see visual_actor_set_video
+ *
+ * @param actor Pointer to a VisActor that needs negotiation.
+ * @param rundepth An depth in the form of the VISUAL_VIDEO_DEPTH_* style when a depth is forced.
+ * 	  This could be needed when for example a plugin has both a 8 bits and a 32 bits display method
+ * 	  but while the target video is in 32 bits you still want to run the plugin in 8 bits. If this
+ * 	  is desired the "forced" argument also needs to be set on TRUE.
+ * @param noevent When set on TRUE this does only renegotiate depth transformation environments. For example
+ * 	  when the target display was running in 32 bits and switched to 8 bits while the plugin was already
+ * 	  in 8 bits it doesn't need an events, which possibly reinitializes the plugin.
+ * @param forced This should be set if the rundepth argument is set, so it forces the plugin in a certain
+ * 	  depth.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_ACTOR_NULL, -VISUAL_ERROR_PLUGIN_NULL, -VISUAL_ERROR_PLUGIN_REF_NULL,
+ * 	-VISUAL_ERROR_ACTOR_VIDEO_NULL or -VISUAL_ERROR_ACTOR_GL_NEGOTIATE on failure. 
+ */ 
+int visual_actor_video_negotiate (VisActor *actor, int rundepth, int noevent, int forced)
+{
+	int depthflag;
+
+	visual_log_return_val_if_fail (actor != NULL, -VISUAL_ERROR_ACTOR_NULL);
+	visual_log_return_val_if_fail (actor->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+	visual_log_return_val_if_fail (actor->plugin->ref != NULL, -VISUAL_ERROR_PLUGIN_REF_NULL);
+	visual_log_return_val_if_fail (actor->video != NULL, -VISUAL_ERROR_ACTOR_VIDEO_NULL);
+
+	if (actor->transform != NULL) {
+		visual_object_unref (VISUAL_OBJECT (actor->transform));
+
+		actor->transform = NULL;
+	}
+	
+	if (actor->fitting != NULL) {
+		visual_object_unref (VISUAL_OBJECT (actor->fitting));
+		
+		actor->fitting = NULL;
+	}
+
+	if (actor->ditherpal != NULL) {
+		visual_object_unref (VISUAL_OBJECT (actor->ditherpal));
+		
+		actor->ditherpal = NULL;
+	}
+
+	depthflag = visual_actor_get_supported_depth (actor);
+
+	visual_log (VISUAL_LOG_INFO, "negotiating plugin %s", actor->plugin->info->name);
+
+	/* Set up depth transformation enviroment */
+	if (visual_video_depth_is_supported (depthflag, actor->video->depth) != TRUE ||
+			(forced == TRUE && actor->video->depth != rundepth))
+		/* When the depth is not supported, or if we only switch the depth and not
+		 * the size */
+		return negotiate_video_with_unsupported_depth (actor, rundepth, noevent, forced);
+	else
+		return negotiate_video (actor, noevent);
+
+	return -VISUAL_ERROR_IMPOSSIBLE;
+}
+
+static int negotiate_video_with_unsupported_depth (VisActor *actor, int rundepth, int noevent, int forced)
+{
+	VisActorPlugin *actplugin = get_actor_plugin (actor);
+	int depthflag = visual_actor_get_supported_depth (actor);
+	
+	/* Depth transform enviroment, it automaticly
+	 * fits size because it can use the pitch from
+	 * the dest video context */
+	actor->transform = visual_video_new ();
+
+	visual_log (VISUAL_LOG_INFO, "run depth %d forced %d\n", rundepth, forced);
+
+	if (forced == TRUE)
+		visual_video_set_depth (actor->transform, rundepth);
+	else
+		visual_video_set_depth (actor->transform,
+				visual_video_depth_get_highest_nogl (depthflag));
+
+	visual_log (VISUAL_LOG_INFO, "transpitch1 %d depth %d bpp %d", actor->transform->pitch, actor->transform->depth,
+			actor->transform->bpp);
+	/* If there is only GL (which gets returned by highest nogl if
+	 * nothing else is there, stop here */
+	if (actor->transform->depth == VISUAL_VIDEO_DEPTH_GL)
+		return -VISUAL_ERROR_ACTOR_GL_NEGOTIATE;
+
+	visual_video_set_dimension (actor->transform, actor->video->width, actor->video->height);
+	visual_log (VISUAL_LOG_INFO, "transpitch2 %d %d", actor->transform->width, actor->transform->pitch);
+
+	actplugin->requisition (visual_actor_get_plugin (actor), &actor->transform->width, &actor->transform->height);
+	visual_log (VISUAL_LOG_INFO, "transpitch3 %d", actor->transform->pitch);
+
+	if (noevent == FALSE) {
+		visual_event_queue_add_resize (&actor->plugin->eventqueue, actor->transform,
+				actor->transform->width, actor->transform->height);
+		visual_plugin_events_pump (actor->plugin);
+	} else {
+		/* Normally a visual_video_set_dimension get's called within the
+		 * event handler, but we won't come there right now so we've
+		 * got to set the pitch ourself */
+		visual_video_set_dimension (actor->transform,
+				actor->transform->width, actor->transform->height);
+	}
+
+	visual_log (VISUAL_LOG_INFO, "rundepth: %d transpitch %d\n", rundepth, actor->transform->pitch);
+	visual_video_allocate_buffer (actor->transform);
+
+	if (actor->video->depth == VISUAL_VIDEO_DEPTH_8BIT)
+		actor->ditherpal = visual_palette_new (256);
+
+	return VISUAL_OK;
+}
+
+static int negotiate_video (VisActor *actor, int noevent)
+{
+	VisActorPlugin *actplugin = get_actor_plugin (actor);
+	int tmpwidth, tmpheight, tmppitch;
+
+	tmpwidth = actor->video->width;
+	tmpheight = actor->video->height;
+	tmppitch = actor->video->pitch;
+
+	/* Pump the resize events and handle all the pending events */
+	actplugin->requisition (visual_actor_get_plugin (actor), &actor->video->width, &actor->video->height);
+
+	if (noevent == FALSE) {
+		visual_event_queue_add_resize (&actor->plugin->eventqueue, actor->video,
+				actor->video->width, actor->video->height);
+
+		visual_plugin_events_pump (actor->plugin);
+	}
+
+	/* Size fitting enviroment */
+	if (tmpwidth != actor->video->width || tmpheight != actor->video->height) {
+		actor->fitting = visual_video_new_with_buffer (actor->video->width,
+				actor->video->height, actor->video->depth);
+
+		visual_video_set_dimension (actor->video, tmpwidth, tmpheight);
+	}
+
+	/* Set the pitch seen this is the framebuffer context */
+	visual_video_set_pitch (actor->video, tmppitch);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Gives the by the plugin natively supported depths
+ *
+ * @param actor Pointer to a VisActor of which the supported depth of it's
+ * 	  encapsulated plugin is requested.
+ *
+ * @return an OR value of the VISUAL_VIDEO_DEPTH_* values which can be checked against using AND on succes,
+ * 	-VISUAL_ERROR_ACTOR_NULL, -VISUAL_ERROR_PLUGIN_NULL or -VISUAL_ERROR_ACTOR_PLUGIN_NULL on failure.
+ */
+int visual_actor_get_supported_depth (VisActor *actor)
+{
+	VisActorPlugin *actplugin;
+
+	visual_log_return_val_if_fail (actor != NULL, -VISUAL_ERROR_ACTOR_NULL);
+	visual_log_return_val_if_fail (actor->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+
+	actplugin = get_actor_plugin (actor);
+
+	if (actplugin == NULL)
+		return -VISUAL_ERROR_ACTOR_PLUGIN_NULL;
+
+	return actplugin->depth;
+}
+
+/**
+ * Used to connect the target display it's VisVideo structure to the VisActor.
+ *
+ * Using the visual_video methods the screenbuffer, it's depth and dimension and optionally it's pitch
+ * can be set so the actor plugins know about their graphical environment and have a place to draw.
+ *
+ * After this function it's most likely that visual_actor_video_negotiate needs to be called.
+ *
+ * @see visual_video_new
+ * @see visual_actor_video_negotiate
+ * 
+ * @param actor Pointer to a VisActor to which the VisVideo needs to be set.
+ * @param video Pointer to a VisVideo which contains information about the target display and the pointer
+ * 	  to it's screenbuffer.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_ACTOR_NULL on failure.
+ */
+int visual_actor_set_video (VisActor *actor, VisVideo *video)
+{
+	visual_log_return_val_if_fail (actor != NULL, -VISUAL_ERROR_ACTOR_NULL);
+
+	actor->video = video;
+
+	return VISUAL_OK;
+}
+
+/**
+ * This is called to run a VisActor. It also pump it's events when needed, checks for new song events and also does the fitting 
+ * and depth transformation actions when needed.
+ *
+ * Every run cycle one frame is created, so this function needs to be used in the main draw loop of the application.
+ *
+ * @param actor Pointer to a VisActor that needs to be runned.
+ * @param audio Pointer to a VisAudio that contains all the audio data.
+ *
+ * return VISUAL_OK on succes, -VISUAL_ERROR_ACTOR_NULL, -VISUAL_ERROR_ACTOR_VIDEO_NULL, -VISUAL_ERROR_NULL or
+ * 	-VISUAL_ERROR_ACTOR_PLUGIN_NULL on failure.
+ */
+int visual_actor_run (VisActor *actor, VisAudio *audio)
+{
+	VisActorPlugin *actplugin;
+	VisPluginData *plugin;
+	VisVideo *video;
+	VisVideo *transform;
+	VisVideo *fitting;
+
+	/* We don't check for video, because we don't always need a video */
+	/*
+	 * Really? take a look at visual_video_set_palette bellow
+	 */
+	visual_log_return_val_if_fail (actor != NULL, -VISUAL_ERROR_ACTOR_NULL);
+	visual_log_return_val_if_fail (actor->video != NULL, -VISUAL_ERROR_ACTOR_VIDEO_NULL);
+	visual_log_return_val_if_fail (audio != NULL, -VISUAL_ERROR_NULL);
+
+	actplugin = get_actor_plugin (actor);
+	plugin = visual_actor_get_plugin (actor);
+
+	if (actplugin == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL,
+			"The given actor does not reference any actor plugin");
+
+		return -VISUAL_ERROR_ACTOR_PLUGIN_NULL;
+	}
+
+	/* Songinfo handling */
+	if (visual_songinfo_compare (&actor->songcompare, &actplugin->songinfo) == FALSE) {
+		visual_songinfo_mark (&actplugin->songinfo);
+		
+		visual_event_queue_add_newsong (
+			visual_plugin_get_eventqueue (plugin),
+			&actplugin->songinfo);
+
+		visual_songinfo_free_strings (&actor->songcompare);
+		visual_songinfo_copy (&actor->songcompare, &actplugin->songinfo);
+	}
+
+	video = actor->video;
+	transform = actor->transform;
+	fitting = actor->fitting;
+
+	/*
+	 * This needs to happen before palette, render stuff, always, period.
+	 * Also internal vars can be initialized when params have been set in init on the param
+	 * events in the event loop.
+	 */
+	visual_plugin_events_pump (actor->plugin);
+	
+	visual_video_set_palette (video, visual_actor_get_palette (actor));
+	
+	/* Set the palette to the target video */
+	video->pal = visual_actor_get_palette (actor);
+
+	/* Yeah some transformation magic is going on here when needed */
+	if (transform != NULL && (transform->depth != video->depth)) {
+		actplugin->render (plugin, transform, audio);
+
+		if (transform->depth == VISUAL_VIDEO_DEPTH_8BIT) {
+			visual_video_set_palette (transform, visual_actor_get_palette (actor));
+			visual_video_depth_transform (video, transform);
+		} else {
+			visual_video_set_palette (transform, actor->ditherpal);
+			visual_video_depth_transform (video, transform);
+		}
+	} else {
+		if (fitting != NULL && (fitting->width != video->width || fitting->height != video->height)) {
+			actplugin->render (plugin, fitting, audio);
+			visual_video_blit_overlay (video, fitting, 0, 0, FALSE);
+		} else {
+			actplugin->render (plugin, video, audio);
+		}
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_actor.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,102 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_ACTOR_H
+#define _LV_ACTOR_H
+
+#include <libvisual/lv_audio.h>
+#include <libvisual/lv_video.h>
+#include <libvisual/lv_palette.h>
+#include <libvisual/lv_plugin.h>
+#include <libvisual/lv_songinfo.h>
+#include <libvisual/lv_event.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_ACTOR(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisActor))
+
+typedef struct _VisActor VisActor;
+
+/**
+ * The VisActor structure encapsulates the actor plugin and provides
+ * abstract interfaces to the actor. The VisActor system 
+ * it's methods are also capable of doing automatic size fitting 
+ * and depth transformations, and it keeps track on songinfo and events.
+ *
+ * Members in the structure shouldn't be accessed directly but instead
+ * it's adviced to use the methods provided.
+ *
+ * @see visual_actor_new
+ */
+struct _VisActor {
+	VisObject	 object;		/**< The VisObject data. */
+
+	VisPluginData	*plugin;		/**< Pointer to the plugin itself. */
+
+	/* Video management and fake environments when needed */
+	VisVideo	*video;			/**< Pointer to the target display video. 
+						 * @see visual_actor_set_video */
+	VisVideo	*transform;		/**< Private member which is used for depth transformation. */
+	VisVideo	*fitting;		/**< Private member which is used to fit the plugin. */
+	VisPalette	*ditherpal;		/**< Private member in which a palette is set when transforming
+						 * depth from true color to indexed.
+						 * @see visual_actor_get_palette */
+
+	/* Songinfo management */
+	VisSongInfo	 songcompare;		/**< Private member which is used to compare with new songinfo
+						  * to check if a new song event should be emitted. */
+};
+
+/* prototypes */
+VisPluginData *visual_actor_get_plugin (VisActor *actor);
+
+VisList *visual_actor_get_list (void);
+const char *visual_actor_get_next_by_name_gl (const char *name);
+const char *visual_actor_get_prev_by_name_gl (const char *name);
+const char *visual_actor_get_next_by_name_nogl (const char *name);
+const char *visual_actor_get_prev_by_name_nogl (const char *name);
+const char *visual_actor_get_next_by_name (const char *name);
+const char *visual_actor_get_prev_by_name (const char *name);
+int visual_actor_valid_by_name (const char *name);
+
+VisActor *visual_actor_new (const char *actorname);
+
+int visual_actor_realize (VisActor *actor);
+
+VisSongInfo *visual_actor_get_songinfo (VisActor *actor);
+VisPalette *visual_actor_get_palette (VisActor *actor);
+
+int visual_actor_video_negotiate (VisActor *actor, int rundepth, int noevent, int forced);
+int visual_actor_get_supported_depth (VisActor *actor);
+
+int visual_actor_set_video (VisActor *actor, VisVideo *video);
+
+int visual_actor_run (VisActor *actor, VisAudio *audio);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_ACTOR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_audio.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,187 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "lv_common.h"
+#include "lv_audio.h"
+
+static int audio_dtor (VisObject *object);
+
+static int audio_band_total (VisAudio *audio, int begin, int end);
+static int audio_band_energy (VisAudio *audio, int band, int length);
+
+static int audio_dtor (VisObject *object)
+{
+	VisAudio *audio = VISUAL_AUDIO (object);
+
+	visual_object_unref (VISUAL_OBJECT (audio->fft_state));
+
+	return VISUAL_OK;
+}
+
+static int audio_band_total (VisAudio *audio, int begin, int end)
+{
+	int bpmtotal = 0;
+	int i;
+
+	for (i = begin; i < end; i++)
+		bpmtotal += audio->freq[2][i];
+
+	if (bpmtotal > 0)
+		return bpmtotal / (end - begin);
+	else
+		return 0;
+}
+
+static int audio_band_energy (VisAudio *audio, int band, int length)
+{
+	int energytotal = 0;
+	int i;
+
+	for (i = 0; i < length; i++)
+		energytotal += audio->bpmhistory[i][band];
+
+	if (energytotal > 0)
+		return energytotal / length;
+	else
+		return 0;
+}
+
+/**
+ * @defgroup VisAudio VisAudio
+ * @{
+ */
+
+/**
+ * Creates a new VisAudio structure.
+ *
+ * @return A newly allocated VisAudio, or NULL on failure.
+ */
+VisAudio *visual_audio_new ()
+{
+	VisAudio *audio;
+
+	audio = visual_mem_new0 (VisAudio, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (audio), TRUE, audio_dtor);
+
+	return audio;
+}
+
+/**
+ * This function analyzes the VisAudio, the FFT frequency magic gets done here, also
+ * the audio energy is calculated and some other magic to provide the developer more
+ * information about the current sample and the stream.
+ *
+ * For every sample that is being retrieved this needs to be called. However keep in mind
+ * that the VisBin runs it automaticly.
+ *
+ * @param audio Pointer to a VisAudio that needs to be analyzed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_AUDIO_NULL on failure.
+ */
+int visual_audio_analyze (VisAudio *audio)
+{
+        float tmp_out[256];
+	double scale;
+	int i, j, y;
+
+	visual_log_return_val_if_fail (audio != NULL, -VISUAL_ERROR_AUDIO_NULL);
+
+	/* Load the pcm data */
+	for (i = 0; i < 512; i++) {
+		audio->pcm[0][i] = audio->plugpcm[0][i];
+		audio->pcm[1][i] = audio->plugpcm[1][i];
+		audio->pcm[2][i] = (audio->plugpcm[0][i] + audio->plugpcm[1][i]) >> 1;
+	}
+
+	/* Initialize fft if not yet initialized */
+	if (audio->fft_state == NULL)
+		audio->fft_state = visual_fft_init ();
+
+	/* FFT analyze the pcm data */
+	visual_fft_perform (audio->plugpcm[0], tmp_out, audio->fft_state);
+		
+	for (i = 0; i < 256; i++)
+		audio->freq[0][i] = ((int) sqrt (tmp_out[i + 1])) >> 8;
+
+	visual_fft_perform (audio->plugpcm[1], tmp_out, audio->fft_state);
+
+	for (i = 0; i < 256; i++)
+		audio->freq[1][i] = ((int) sqrt (tmp_out[i + 1])) >> 8;
+
+	for (i = 0; i < 256; i++)
+		audio->freq[2][i] = (audio->freq[0][i] + audio->freq[1][i]) >> 1;
+
+	/* Normalized frequency analyzer */
+	/** @todo FIXME Not sure if this is totally correct */
+	for (i = 0; i < 3; i++) {
+		for (j = 0; j < 256; j++) {
+			/* (Height / log (256)) */
+			scale = 256 / log (256);
+
+			y = audio->freq[i][j];
+			y = log (y) * scale;
+
+			if (y < 0)
+				y = 0;
+
+			audio->freqnorm[i][j] = y;
+		}
+	}
+
+	
+	/* BPM stuff, used for the audio energy only right now */
+	for (i = 1023; i > 0; i--) {
+		visual_mem_copy (&audio->bpmhistory[i], &audio->bpmhistory[i - 1], 6 * sizeof (short int));
+		visual_mem_copy (&audio->bpmdata[i], &audio->bpmdata[i - 1], 6 * sizeof (short int));
+	}
+
+	/* Calculate the audio energy */
+	audio->energy = 0;
+	
+	for (i = 0; i < 6; i++)	{
+		audio->bpmhistory[0][i] = audio_band_total (audio, i * 2, (i * 2) + 3);
+		audio->bpmenergy[i] = audio_band_energy (audio, i, 10);
+
+		audio->bpmdata[0][i] = audio->bpmhistory[0][i] - audio->bpmenergy[i];
+
+		audio->energy += audio_band_energy(audio, i, 50);
+	}
+
+	audio->energy >>= 7;
+
+	if (audio->energy > 100)
+		audio->energy = 100;
+
+	return VISUAL_OK;
+}
+
+/**
+ * @}
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_audio.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,71 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_AUDIO_H
+#define _LV_AUDIO_H
+
+#include <libvisual/lv_fft.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_AUDIO(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisAudio))
+
+typedef struct _VisAudio VisAudio;
+
+/**
+ * The VisAudio structure contains the sample and extra information
+ * about the sample like a 256 bands analyzer, sound energy and
+ * in the future BPM detection.
+ *
+ * @see visual_audio_new
+ */
+struct _VisAudio {
+	VisObject	 object;			/**< The VisObject data. */
+
+	short		 plugpcm[2][512];		/**< PCM data that comes from the input plugin
+							 * or a callback function. */
+	short		 pcm[3][512];			/**< PCM data that should be used within plugins
+							 * pcm[0][x] is the left channel, pcm[1][x] is the right
+							 * channel and pcm[2][x] is an average of both channels. */
+	short		 freq[3][256];			/**< Frequency data as a 256 bands analyzer, with the channels
+							 * like with the pcm element. */
+	short		 freqnorm[3][256];		/**< Frequency data like the freq member, however this time the bands
+							 * are normalized. */
+	VisFFTState	*fft_state;			/**< Private member that contains context information for the FFT engine. */
+
+	short int	 bpmhistory[1024][6];		/**< Private member for BPM detection, not implemented right now. */
+	short int	 bpmdata[1024][6];		/**< Private member for BPM detection, not implemented right now. */
+	short int	 bpmenergy[6];			/**< Private member for BPM detection, not implemented right now. */
+	int		 energy;			/**< Audio energy level. */
+};
+
+VisAudio *visual_audio_new (void);
+int visual_audio_analyze (VisAudio *audio);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_AUDIO_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_bin.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,898 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>                                                                                            
+
+/*
+ * lvconfig.h must be included in order to show correct log messages
+ */
+#include "lvconfig.h"
+#include "lv_log.h"
+
+#include "lv_list.h"
+#include "lv_input.h"
+#include "lv_actor.h"
+#include "lv_bin.h"
+#include "lv_bin.h"
+
+/* WARNING: Utterly shit ahead, i've screwed up on this and i need to
+ * rewrite it. And i can't say i feel like it at the moment so be
+ * patient :) */
+
+static int bin_dtor (VisObject *object);
+
+static void fix_depth_with_bin (VisBin *bin, VisVideo *video, int depth);
+static int bin_get_depth_using_preferred (VisBin *bin, int depthflag);
+
+static int bin_dtor (VisObject *object)
+{
+	VisBin *bin = VISUAL_BIN (object);
+
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	if (bin->actor != NULL)
+		visual_object_unref (VISUAL_OBJECT (bin->actor));
+
+	if (bin->input != NULL)
+		visual_object_unref (VISUAL_OBJECT (bin->input));
+
+	if (bin->morph != NULL)
+		visual_object_unref (VISUAL_OBJECT (bin->morph));
+
+	if (bin->actmorphmanaged == TRUE) {
+		if (bin->actmorph != NULL)
+			visual_object_unref (VISUAL_OBJECT (bin->actmorph));
+
+		if (bin->actmorphvideo != NULL)
+			visual_object_unref (VISUAL_OBJECT (bin->actmorphvideo));
+	}
+
+	if (bin->privvid != NULL)
+		visual_object_unref (VISUAL_OBJECT (bin->privvid));
+
+	bin->actor = NULL;
+	bin->input = NULL;
+	bin->morph = NULL;
+	bin->actmorph = NULL;
+	bin->actmorphvideo = NULL;
+	bin->privvid = NULL;
+
+	return VISUAL_OK;
+}
+
+static void fix_depth_with_bin (VisBin *bin, VisVideo *video, int depth)
+{
+	/* Is supported within bin natively */
+	if ((bin->depthflag & depth) > 0) {
+		visual_video_set_depth (video, depth);
+	} else {
+		/* Not supported by the bin, taking the highest depth from the bin */
+		visual_video_set_depth (video,
+				visual_video_depth_get_highest_nogl (bin->depthflag));
+	}
+}
+
+static int bin_get_depth_using_preferred (VisBin *bin, int depthflag)
+{
+	if (bin->depthpreferred == VISUAL_BIN_DEPTH_LOWEST)
+		return visual_video_depth_get_lowest (depthflag);
+	else
+		return visual_video_depth_get_highest (depthflag);
+}
+
+/**
+ * @defgroup VisBin VisBin
+ * @{
+ */
+
+VisBin *visual_bin_new ()
+{
+	VisBin *bin;
+
+	bin = visual_mem_new0 (VisBin, 1);
+
+	/* VisObject stuff.. */
+	visual_object_initialize (VISUAL_OBJECT (bin), TRUE, bin_dtor);
+
+	bin->morphautomatic = TRUE;
+
+	bin->morphmode = VISUAL_MORPH_MODE_TIME;
+	visual_time_set (&bin->morphtime, 4, 0);
+	
+	bin->depthpreferred = VISUAL_BIN_DEPTH_HIGHEST;
+
+	return bin;
+}
+
+int visual_bin_realize (VisBin *bin)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	if (bin->actor != NULL)
+		visual_actor_realize (bin->actor);
+
+	if (bin->input != NULL)
+		visual_input_realize (bin->input);
+
+	if (bin->morph != NULL)
+		visual_morph_realize (bin->morph);
+
+	return 0;
+}
+
+int visual_bin_set_actor (VisBin *bin, VisActor *actor)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->actor = actor;
+
+	bin->managed = FALSE;
+
+	return 0;
+}
+
+VisActor *visual_bin_get_actor (VisBin *bin)
+{
+	visual_log_return_val_if_fail (bin != NULL, NULL);
+
+	return bin->actor;
+}
+
+int visual_bin_set_input (VisBin *bin, VisInput *input)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->input = input;
+
+	bin->inputmanaged = FALSE;
+
+	return 0;
+}
+
+VisInput *visual_bin_get_input (VisBin *bin)
+{
+	visual_log_return_val_if_fail (bin != NULL, NULL);
+
+	return bin->input;
+}
+
+int visual_bin_set_morph (VisBin *bin, VisMorph *morph)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->morph = morph;
+
+	bin->morphmanaged = FALSE;
+
+	return 0;
+}
+
+int visual_bin_set_morph_by_name (VisBin *bin, char *morphname)
+{
+	VisMorph *morph;
+	int depthflag;
+
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	if (bin->morph != NULL)
+		visual_object_unref (VISUAL_OBJECT (bin->morph));
+
+	morph = visual_morph_new (morphname);
+
+	bin->morph = morph;
+	bin->morphmanaged = TRUE;
+	
+	visual_log_return_val_if_fail (morph->plugin != NULL, -1);
+
+	depthflag = visual_morph_get_supported_depth (morph);
+
+	if (visual_video_depth_is_supported (depthflag, bin->actvideo->depth) <= 0) {
+		visual_object_unref (VISUAL_OBJECT (morph));
+		bin->morph = NULL;
+
+		return -2;
+	}
+	
+	return 0;
+}
+
+VisMorph *visual_bin_get_morph (VisBin *bin)
+{
+	visual_log_return_val_if_fail (bin != NULL, NULL);
+
+	return bin->morph;
+}
+
+int visual_bin_connect (VisBin *bin, VisActor *actor, VisInput *input)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	visual_bin_set_actor (bin, actor);
+	visual_bin_set_input (bin, input);
+
+	return 0;
+}
+
+int visual_bin_connect_by_names (VisBin *bin, char *actname, char *inname)
+{
+	VisActor *actor;
+	VisInput *input;
+	int depthflag;
+	int depth;
+
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	/* Create the actor */
+	actor = visual_actor_new (actname);
+	visual_log_return_val_if_fail (actor != NULL, -1);
+
+	/* Check and set required depth */
+	depthflag = visual_actor_get_supported_depth (actor);
+
+	/* GL plugin, and ONLY a GL plugin */
+	if (depthflag == VISUAL_VIDEO_DEPTH_GL)
+		visual_bin_set_depth (bin, VISUAL_VIDEO_DEPTH_GL);
+	else {
+		depth = bin_get_depth_using_preferred (bin, depthflag);
+
+		/* Is supported within bin natively */
+		if ((bin->depthflag & depth) > 0) {
+			visual_bin_set_depth (bin, depth);
+		} else {
+			/* Not supported by the bin, taking the highest depth from the bin */
+			visual_bin_set_depth (bin,
+				visual_video_depth_get_highest_nogl (bin->depthflag));
+		}
+	}
+
+	/* Initialize the managed depth */
+	bin->depthforcedmain = bin->depth;
+
+	/* Create the input */
+	input = visual_input_new (inname);
+	visual_log_return_val_if_fail (input != NULL, -1);
+
+	/* Connect */
+	visual_bin_connect (bin, actor, input);
+
+	bin->managed = TRUE;
+	bin->inputmanaged = TRUE;
+
+	return 0;
+}
+
+int visual_bin_sync (VisBin *bin, int noevent)
+{
+	VisVideo *video;
+	VisVideo *actvideo;
+
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	visual_log (VISUAL_LOG_DEBUG, "starting sync");
+
+	/* Sync the actor regarding morph */
+	if (bin->morphing == TRUE && bin->morphstyle == VISUAL_SWITCH_STYLE_MORPH &&
+			bin->actvideo->depth != VISUAL_VIDEO_DEPTH_GL &&
+			bin->depthfromGL != TRUE) {
+		visual_morph_set_video (bin->morph, bin->actvideo);
+	
+		video = bin->privvid;
+		if (video == NULL) {
+			visual_log (VISUAL_LOG_DEBUG, "Private video data NULL");
+			return -1;
+		}
+
+		visual_video_free_buffer (video);
+		visual_video_clone (video, bin->actvideo);
+
+		visual_log (VISUAL_LOG_DEBUG, "pitches actvideo %d, new video %d", bin->actvideo->pitch, video->pitch);
+
+		visual_log (VISUAL_LOG_DEBUG, "phase1 bin->privvid %p", bin->privvid);
+		if (bin->actmorph->video->depth == VISUAL_VIDEO_DEPTH_GL) {
+			visual_video_set_buffer (video, NULL);
+			video = bin->actvideo;
+		} else
+			visual_video_allocate_buffer (video);
+		
+		visual_log (VISUAL_LOG_DEBUG, "phase2");
+	} else {
+		video = bin->actvideo;
+		if (video == NULL) {
+			visual_log (VISUAL_LOG_DEBUG, "Actor video is NULL");
+			return -1;
+		}
+
+		visual_log (VISUAL_LOG_DEBUG, "setting new video from actvideo %d %d", video->depth, video->bpp);
+	}
+
+	/* Main actor */
+//	visual_actor_realize (bin->actor);
+	visual_actor_set_video (bin->actor, video);
+
+	visual_log (VISUAL_LOG_DEBUG, "one last video pitch check %d depth old %d forcedmain %d noevent %d",
+			video->pitch, bin->depthold,
+			bin->depthforcedmain, noevent);
+
+	if (bin->managed == TRUE) {
+		if (bin->depthold == VISUAL_VIDEO_DEPTH_GL)
+			visual_actor_video_negotiate (bin->actor, bin->depthforcedmain, FALSE, TRUE);
+		else
+			visual_actor_video_negotiate (bin->actor, bin->depthforcedmain, noevent, TRUE);
+	} else {
+		if (bin->depthold == VISUAL_VIDEO_DEPTH_GL)
+			visual_actor_video_negotiate (bin->actor, 0, FALSE, TRUE);
+		else
+			visual_actor_video_negotiate (bin->actor, 0, noevent, FALSE);
+	}
+	
+	visual_log (VISUAL_LOG_DEBUG, "pitch after main actor negotiate %d", video->pitch);
+
+	/* Morphing actor */
+	if (bin->actmorphmanaged == TRUE && bin->morphing == TRUE &&
+			bin->morphstyle == VISUAL_SWITCH_STYLE_MORPH) {
+
+		actvideo = bin->actmorphvideo;
+		if (actvideo == NULL) {
+			visual_log (VISUAL_LOG_DEBUG, "Morph video is NULL");
+			return -1;
+		}
+
+		visual_video_free_buffer (actvideo);
+
+		visual_video_clone (actvideo, video);
+
+		if (bin->actor->video->depth != VISUAL_VIDEO_DEPTH_GL)
+			visual_video_allocate_buffer (actvideo);
+
+		visual_actor_realize (bin->actmorph);
+
+		visual_log (VISUAL_LOG_DEBUG, "phase3 pitch of real framebuffer %d", bin->actvideo->pitch);
+		if (bin->actmorphmanaged == TRUE)
+			visual_actor_video_negotiate (bin->actmorph, bin->depthforced, FALSE, TRUE);
+		else
+			visual_actor_video_negotiate (bin->actmorph, 0, FALSE, FALSE);
+	}
+
+	visual_log (VISUAL_LOG_DEBUG, "end sync function");
+
+	return 0;
+}
+
+int visual_bin_set_video (VisBin *bin, VisVideo *video)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+	
+	bin->actvideo = video;
+
+	return 0;
+}
+
+int visual_bin_set_supported_depth (VisBin *bin, int depthflag)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->depthflag = depthflag;
+
+	return 0;
+}
+
+int visual_bin_set_preferred_depth (VisBin *bin, VisBinDepth depthpreferred)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->depthpreferred = depthpreferred;
+
+	return 0;
+}
+
+int visual_bin_set_depth (VisBin *bin, int depth)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->depthold = bin->depth;
+
+	if (visual_video_depth_is_supported (bin->depthflag, depth) != TRUE)
+		return -2;
+
+	visual_log (VISUAL_LOG_DEBUG, "old: %d new: %d", bin->depth, depth);
+	if (bin->depth != depth)
+		bin->depthchanged = TRUE;
+
+	if (bin->depth == VISUAL_VIDEO_DEPTH_GL && bin->depthchanged == TRUE)
+		bin->depthfromGL = TRUE;
+	else
+		bin->depthfromGL = FALSE;
+
+	bin->depth = depth;
+
+	visual_video_set_depth (bin->actvideo, depth);
+
+	return 0;
+}
+
+int visual_bin_get_depth (VisBin *bin)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	return bin->depth;
+}
+
+int visual_bin_depth_changed (VisBin *bin)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+	
+	if (bin->depthchanged == FALSE)
+		return FALSE;
+
+	bin->depthchanged = FALSE;
+
+	return TRUE;
+}
+
+VisPalette *visual_bin_get_palette (VisBin *bin)
+{
+	visual_log_return_val_if_fail (bin != NULL, NULL);
+
+	if (bin->morphing == TRUE)
+		return visual_morph_get_palette (bin->morph);
+	else
+		return visual_actor_get_palette (bin->actor);
+}
+
+int visual_bin_switch_actor_by_name (VisBin *bin, char *actname)
+{
+	VisActor *actor;
+	VisVideo *video;
+	int depthflag;
+	int depth;
+
+	visual_log_return_val_if_fail (bin != NULL, -1);
+	visual_log_return_val_if_fail (actname != NULL, -1);
+
+	visual_log (VISUAL_LOG_DEBUG, "switching to a new actor: %s, old actor: %s", actname, bin->actor->plugin->info->name);
+
+	/* Destroy if there already is a managed one */
+	if (bin->actmorphmanaged == TRUE) {
+		if (bin->actmorph != NULL) {
+			visual_object_unref (VISUAL_OBJECT (bin->actmorph));
+
+			if (bin->actmorphvideo != NULL)
+				visual_object_unref (VISUAL_OBJECT (bin->actmorphvideo));
+		}
+	}
+
+	/* Create a new managed actor */
+	actor = visual_actor_new (actname);
+	visual_log_return_val_if_fail (actor != NULL, -1);
+
+	video = visual_video_new ();
+
+	visual_video_clone (video, bin->actvideo);
+
+	depthflag = visual_actor_get_supported_depth (actor);
+	if (visual_video_depth_is_supported (depthflag, VISUAL_VIDEO_DEPTH_GL) == TRUE) {
+		visual_log (VISUAL_LOG_INFO, "Switching to Gl mode");
+
+		bin->depthforced = VISUAL_VIDEO_DEPTH_GL;
+		bin->depthforcedmain = VISUAL_VIDEO_DEPTH_GL;
+	
+		visual_video_set_depth (video, VISUAL_VIDEO_DEPTH_GL);
+
+		visual_bin_set_depth (bin, VISUAL_VIDEO_DEPTH_GL);
+		bin->depthchanged = TRUE;
+
+	} else {
+		visual_log (VISUAL_LOG_INFO, "Switching away from Gl mode -- or non Gl switch");
+
+		
+		/* Switching from GL */
+		depth = bin_get_depth_using_preferred (bin, depthflag);
+
+		fix_depth_with_bin (bin, video, depth);
+
+		visual_log (VISUAL_LOG_DEBUG, "after depth fixating");
+		
+		/* After a depth change, the pitch value needs an update from the client
+		 * if it's different from width * bpp, after a visual_bin_sync
+		 * the issues are fixed again */
+		visual_log (VISUAL_LOG_INFO, "video depth (from fixate): %d", video->depth);
+
+		/* FIXME check if there are any unneeded depth transform environments and drop these */
+		visual_log (VISUAL_LOG_DEBUG, "checking if we need to drop something: depthforcedmain: %d actvideo->depth %d",
+				bin->depthforcedmain, bin->actvideo->depth);
+
+		/* Drop a transformation environment when not needed */
+		if (bin->depthforcedmain != bin->actvideo->depth) {
+			visual_actor_video_negotiate (bin->actor, bin->depthforcedmain, TRUE, TRUE);
+			visual_log (VISUAL_LOG_DEBUG, "[[[[optionally a bogus transform environment, dropping]]]]\n");
+		}
+
+		if (bin->actvideo->depth > video->depth
+				&& bin->actvideo->depth != VISUAL_VIDEO_DEPTH_GL
+				&& bin->morphstyle == VISUAL_SWITCH_STYLE_MORPH) {
+
+			visual_log (VISUAL_LOG_INFO, "old depth is higher, video depth %d, depth %d, bin depth %d", video->depth, depth,
+					bin->depth);
+			
+			bin->depthforced = depth;
+			bin->depthforcedmain = bin->depth;
+			
+			visual_bin_set_depth (bin, bin->actvideo->depth);
+
+			visual_video_set_depth (video, bin->actvideo->depth);
+
+		} else if (bin->actvideo->depth != VISUAL_VIDEO_DEPTH_GL) {
+
+			visual_log (VISUAL_LOG_INFO, "new depth is higher, or equal: video depth %d, depth %d bin depth %d", video->depth, depth,
+					bin->depth);
+
+			visual_log (VISUAL_LOG_DEBUG, "depths i can locate: actvideo: %d   bin: %d   bin-old: %d", bin->actvideo->depth,
+					bin->depth, bin->depthold);
+			
+			bin->depthforced = video->depth;
+			bin->depthforcedmain = bin->depth;
+
+			visual_log (VISUAL_LOG_DEBUG, "depthforcedmain in switch by name: %d", bin->depthforcedmain);
+			visual_log (VISUAL_LOG_DEBUG, "visual_bin_set_depth %d", video->depth);
+			visual_bin_set_depth (bin, video->depth);
+
+		} else {
+			/* Don't force ourself into a GL depth, seen we do a direct
+			 * switch in the run */
+			bin->depthforced = video->depth;
+			bin->depthforcedmain = video->depth;
+			
+			visual_log (VISUAL_LOG_INFO, "Switching from Gl TO framebuffer for real, framebuffer depth: %d", video->depth);
+		}
+
+		visual_log (VISUAL_LOG_INFO, "Target depth selected: %d", depth);
+		visual_video_set_dimension (video, video->width, video->height);
+
+		visual_log (VISUAL_LOG_INFO, "Switch to new pitch: %d", bin->actvideo->pitch);
+		if (bin->actvideo->depth != VISUAL_VIDEO_DEPTH_GL)
+			visual_video_set_pitch (video, bin->actvideo->pitch);
+		
+		visual_log (VISUAL_LOG_DEBUG, "before allocating buffer");
+		visual_video_allocate_buffer (video);
+		visual_log (VISUAL_LOG_DEBUG, "after allocating buffer");
+	}
+
+	visual_log (VISUAL_LOG_INFO, "video pitch of that what connects to the new actor %d", video->pitch);
+	visual_actor_set_video (actor, video);
+
+	bin->actmorphvideo = video;
+	bin->actmorphmanaged = TRUE;
+
+	visual_log (VISUAL_LOG_INFO, "switching... ******************************************");
+	visual_bin_switch_actor (bin, actor);
+
+	visual_log (VISUAL_LOG_INFO, "end switch actor by name function ******************");
+	return 0;
+}
+
+int visual_bin_switch_actor (VisBin *bin, VisActor *actor)
+{
+	VisVideo *privvid;
+
+	visual_log_return_val_if_fail (bin != NULL, -1);
+	visual_log_return_val_if_fail (actor != NULL, -1);
+
+	/* Set the new actor */
+	bin->actmorph = actor;
+
+	visual_log (VISUAL_LOG_DEBUG, "entering...");
+	
+	/* Free the private video */
+	if (bin->privvid != NULL) {
+		visual_object_unref (VISUAL_OBJECT (bin->privvid));
+		
+		bin->privvid = NULL;
+	}
+
+	visual_log (VISUAL_LOG_INFO, "depth of the main actor: %d", bin->actor->video->depth);
+
+	/* Starting the morph, but first check if we don't have anything todo with openGL */
+	if (bin->morphstyle == VISUAL_SWITCH_STYLE_MORPH &&
+			bin->actor->video->depth != VISUAL_VIDEO_DEPTH_GL &&
+			bin->actmorph->video->depth != VISUAL_VIDEO_DEPTH_GL &&
+			bin->depthfromGL != TRUE) {
+
+		if (bin->morph != NULL && bin->morph->plugin != NULL) {
+			visual_morph_set_rate (bin->morph, 0);
+		
+			visual_morph_set_video (bin->morph, bin->actvideo);
+
+			if (bin->morphautomatic == TRUE)
+				visual_morph_set_mode (bin->morph, bin->morphmode);
+			else
+				visual_morph_set_mode (bin->morph, VISUAL_MORPH_MODE_SET);
+			
+			visual_morph_set_time (bin->morph, &bin->morphtime);
+			visual_morph_set_steps (bin->morph, bin->morphsteps);
+		}
+
+		bin->morphrate = 0;
+		bin->morphstepsdone = 0;
+
+		visual_log (VISUAL_LOG_DEBUG, "phase 1");
+		/* Allocate a private video for the main actor, so the morph
+		 * can draw to the framebuffer */
+		privvid = visual_video_new ();
+
+		visual_log (VISUAL_LOG_DEBUG, "actvideo->depth %d actmorph->video->depth %d",
+				bin->actvideo->depth, bin->actmorph->video->depth);
+
+		visual_log (VISUAL_LOG_DEBUG, "phase 2");
+		visual_video_clone (privvid, bin->actvideo);
+		visual_log (VISUAL_LOG_DEBUG, "phase 3 pitch privvid %d actvideo %d", privvid->pitch, bin->actvideo->pitch);
+
+		visual_video_allocate_buffer (privvid);
+
+		visual_log (VISUAL_LOG_DEBUG, "phase 4");
+		/* Initial privvid initialize */
+	
+		visual_log (VISUAL_LOG_DEBUG, "actmorph->video->depth %d %p", bin->actmorph->video->depth,
+				bin->actvideo->pixels);
+		
+		if (bin->actvideo->pixels != NULL && privvid->pixels != NULL)
+			visual_mem_copy (privvid->pixels, bin->actvideo->pixels, privvid->size);
+		else if (privvid->pixels != NULL)
+			memset (privvid->pixels, 0, privvid->size);
+
+		visual_actor_set_video (bin->actor, privvid);
+		bin->privvid = privvid;
+	} else {
+		visual_log (VISUAL_LOG_DEBUG, "Pointer actvideo->pixels %p", bin->actvideo->pixels);
+		if (bin->actor->video->depth != VISUAL_VIDEO_DEPTH_GL &&
+				bin->actvideo->pixels != NULL) {
+			memset (bin->actvideo->pixels, 0, bin->actvideo->size);
+		}
+	}
+
+	visual_log (VISUAL_LOG_DEBUG, "Leaving, actor->video->depth: %d actmorph->video->depth: %d",
+			bin->actor->video->depth, bin->actmorph->video->depth);
+
+	bin->morphing = TRUE;
+
+	return 0;
+}
+
+int visual_bin_switch_finalize (VisBin *bin)
+{
+	int depthflag;
+
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	visual_log (VISUAL_LOG_DEBUG, "Entering...");
+	if (bin->managed == TRUE)
+		visual_object_unref (VISUAL_OBJECT (bin->actor));
+
+	/* Copy over the depth to be sure, and for GL plugins */
+//	bin->actvideo->depth = bin->actmorphvideo->depth;
+//	visual_video_set_depth (bin->actvideo, bin->actmorphvideo->depth);
+
+	if (bin->actmorphmanaged == TRUE) {
+		visual_object_unref (VISUAL_OBJECT (bin->actmorphvideo));
+
+		bin->actmorphvideo = NULL;
+	}
+
+	if (bin->privvid != NULL) {
+		visual_object_unref (VISUAL_OBJECT (bin->privvid));
+		
+		bin->privvid = NULL;
+	}
+
+	bin->actor = bin->actmorph;
+	bin->actmorph = NULL;
+	
+	visual_actor_set_video (bin->actor, bin->actvideo);
+	
+	bin->morphing = FALSE;
+
+	if (bin->morphmanaged == TRUE) {
+		visual_object_unref (VISUAL_OBJECT (bin->morph));
+		bin->morph = NULL;
+	}
+
+	visual_log (VISUAL_LOG_DEBUG, " - in finalize - fscking depth from actvideo: %d %d", bin->actvideo->depth, bin->actvideo->bpp);
+
+	
+//	visual_bin_set_depth (bin, bin->actvideo->depth);
+
+	depthflag = visual_actor_get_supported_depth (bin->actor);
+	fix_depth_with_bin (bin, bin->actvideo, bin_get_depth_using_preferred (bin, depthflag));
+	visual_bin_set_depth (bin, bin->actvideo->depth);
+
+	bin->depthforcedmain = bin->actvideo->depth;
+	visual_log (VISUAL_LOG_DEBUG, "bin->depthforcedmain in finalize %d", bin->depthforcedmain);
+
+	// FIXME replace with a depth fixer
+	if (bin->depthchanged == TRUE) {
+		visual_log (VISUAL_LOG_INFO, "negotiate without event");
+		visual_actor_video_negotiate (bin->actor, bin->depthforcedmain, TRUE, TRUE);
+		visual_log (VISUAL_LOG_INFO, "end negotiate without event");
+	//	visual_bin_sync (bin);
+	}
+
+	visual_log (VISUAL_LOG_DEBUG, "Leaving...");
+
+	return 0;
+}
+
+int visual_bin_switch_set_style (VisBin *bin, VisBinSwitchStyle style)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->morphstyle = style;
+
+	return 0;
+}
+
+int visual_bin_switch_set_steps (VisBin *bin, int steps)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->morphsteps = steps;
+
+	return 0;
+}
+
+int visual_bin_switch_set_automatic (VisBin *bin, int automatic)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->morphautomatic = automatic;
+
+	return 0;
+}
+
+int visual_bin_switch_set_rate (VisBin *bin, float rate)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->morphrate = rate;
+
+	return 0;
+}
+
+int visual_bin_switch_set_mode (VisBin *bin, VisMorphMode mode)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	bin->morphmode = mode;
+
+	return 0;
+}
+
+int visual_bin_switch_set_time (VisBin *bin, long sec, long usec)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+
+	visual_time_set (&bin->morphtime, sec, usec);
+
+	return 0;
+}
+
+
+int visual_bin_run (VisBin *bin)
+{
+	visual_log_return_val_if_fail (bin != NULL, -1);
+	visual_log_return_val_if_fail (bin->actor != NULL, -1);
+	visual_log_return_val_if_fail (bin->input != NULL, -1);
+
+	visual_input_run (bin->input);
+
+	/* If we have a direct switch, do this BEFORE we run the actor,
+	 * else we can get into trouble especially with GL, also when
+	 * switching away from a GL plugin this is needed */
+	if (bin->morphing == TRUE) {
+		/* We realize here, because it doesn't realize
+		 * on switch, the reason for this is so that after a
+		 * switch call, especially in a managed bin the
+		 * depth can be requested and set, this is important
+		 * for openGL plugins, the realize method checks
+		 * for double realize itself so we don't have
+		 * to check this, it's a bit hacky */
+		visual_log_return_val_if_fail (bin->actmorph != NULL, -1);
+		visual_log_return_val_if_fail (bin->actmorph->plugin != NULL, -1);
+ 		if (bin->actmorph->plugin->realized == FALSE) {
+			visual_actor_realize (bin->actmorph);
+			
+			if (bin->actmorphmanaged == TRUE)
+				visual_actor_video_negotiate (bin->actmorph, bin->depthforced, FALSE, TRUE);
+			else
+				visual_actor_video_negotiate (bin->actmorph, 0, FALSE, FALSE);
+		}
+
+		/* When we've got multiple switch events without a sync we need
+		 * to realize the main actor as well */
+		visual_log_return_val_if_fail (bin->actor->plugin != NULL, -1);
+		if (bin->actor->plugin->realized == FALSE) {
+			visual_actor_realize (bin->actor);
+			
+			if (bin->managed == TRUE)
+				visual_actor_video_negotiate (bin->actor, bin->depthforced, FALSE, TRUE);
+			else
+				visual_actor_video_negotiate (bin->actor, 0, FALSE, FALSE);
+		}
+
+		/* When the style is DIRECT or the context is GL we shouldn't try
+		 * to morph and instead finalize at once */
+		visual_log_return_val_if_fail (bin->actor->video != NULL, -1);
+		if (bin->morphstyle == VISUAL_SWITCH_STYLE_DIRECT ||
+			bin->actor->video->depth == VISUAL_VIDEO_DEPTH_GL) {
+		
+			visual_bin_switch_finalize (bin);
+
+			/* We can't start drawing yet, the client needs to catch up with
+			 * the depth change */
+			return 0;
+		}
+	}
+
+	/* We realize here because in a managed bin the depth for openGL is
+	 * requested after the connect, thus we can realize there yet */
+	visual_actor_realize (bin->actor);
+
+	visual_actor_run (bin->actor, bin->input->audio);
+
+	if (bin->morphing == TRUE) {
+		visual_log_return_val_if_fail (bin->actmorph != NULL, -1);
+		visual_log_return_val_if_fail (bin->actmorph->video != NULL, -1);
+		visual_log_return_val_if_fail (bin->actor->video != NULL, -1);
+
+		if (bin->morphstyle == VISUAL_SWITCH_STYLE_MORPH &&
+			bin->actmorph->video->depth != VISUAL_VIDEO_DEPTH_GL &&
+			bin->actor->video->depth != VISUAL_VIDEO_DEPTH_GL) {
+
+			visual_actor_run (bin->actmorph, bin->input->audio);
+
+			if (bin->morph == NULL || bin->morph->plugin == NULL) {
+				visual_bin_switch_finalize (bin);
+		
+				return 0;
+			}
+
+			/* Same goes for the morph, we realize it here for depth changes
+			 * (especially the openGL case */
+			visual_morph_realize (bin->morph);
+			visual_morph_run (bin->morph, bin->input->audio, bin->actor->video, bin->actmorph->video);
+
+			if (visual_morph_is_done (bin->morph) == TRUE)
+				visual_bin_switch_finalize (bin);
+		} else {
+//			visual_bin_switch_finalize (bin);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_bin.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,133 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_BIN_H
+#define _LV_BIN_H
+
+#include <libvisual/lv_actor.h>
+#include <libvisual/lv_input.h>
+#include <libvisual/lv_morph.h>
+#include <libvisual/lv_video.h>
+#include <libvisual/lv_time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_BIN(obj)					(VISUAL_CHECK_CAST ((obj), 0, VisBin))
+
+typedef enum {
+	VISUAL_SWITCH_STYLE_DIRECT,
+	VISUAL_SWITCH_STYLE_MORPH
+} VisBinSwitchStyle;
+
+typedef enum {
+	VISUAL_BIN_DEPTH_LOWEST,
+	VISUAL_BIN_DEPTH_HIGHEST
+} VisBinDepth;
+
+typedef struct _VisBin VisBin;
+
+struct _VisBin {
+	VisObject	 object;
+
+	int		 managed;
+	VisActor	*actor;
+	VisVideo	*actvideo;
+	VisVideo	*privvid;
+	
+	int		 actmorphmanaged;
+	VisVideo	*actmorphvideo;
+	VisActor	*actmorph;
+
+	int		 inputmanaged;
+	VisInput	*input;
+
+	int		 morphmanaged;
+	VisMorph	*morph;
+	int		 morphstyle;
+	int		 morphing;
+	int		 morphautomatic;
+	int		 morphsteps;
+	int		 morphstepsdone;
+	float		 morphrate;
+	VisMorphMode	 morphmode;
+	VisTime		 morphtime;
+
+	int		 depthpreferred;	/* Prefered depth, highest or lowest */
+	int		 depthflag;		/* Supported depths */
+	int		 depthold;		/* Previous depth */
+	int		 depth;			/* Depth we're running in */
+	int		 depthchanged;		/* Set TRUE if the depth has changed */
+	int		 depthfromGL;		/* Set when switching away from openGL */
+	int		 depthforced;		/* Contains forced depth value, for the actmorph so we've got smooth transformations */
+	int		 depthforcedmain;	/* Contains forced depth value, for the main actor */
+};
+
+/* prototypes */
+VisBin *visual_bin_new (void);
+
+int visual_bin_realize (VisBin *bin);
+
+int visual_bin_set_actor (VisBin *bin, VisActor *actor);
+VisActor *visual_bin_get_actor (VisBin *bin);
+
+int visual_bin_set_input (VisBin *bin, VisInput *input);
+VisInput *visual_bin_get_input (VisBin *bin);
+
+int visual_bin_set_morph (VisBin *bin, VisMorph *morph);
+int visual_bin_set_morph_by_name (VisBin *bin, char *morphname);
+VisMorph *visual_bin_get_morph (VisBin *bin);
+
+int visual_bin_connect (VisBin *bin, VisActor *actor, VisInput *input);
+int visual_bin_connect_by_names (VisBin *bin, char *actname, char *inname);
+
+int visual_bin_sync (VisBin *bin, int noevent);
+
+int visual_bin_set_video (VisBin *bin, VisVideo *video);
+
+int visual_bin_set_supported_depth (VisBin *bin, int depthflag);
+int visual_bin_set_preferred_depth (VisBin *bin, VisBinDepth depthpreferred);
+int visual_bin_set_depth (VisBin *bin, int depth);
+int visual_bin_get_depth (VisBin *bin);
+int visual_bin_depth_changed (VisBin *bin);
+
+VisPalette *visual_bin_get_palette (VisBin *bin);
+
+int visual_bin_switch_actor_by_name (VisBin *bin, char *actname);
+int visual_bin_switch_actor (VisBin *bin, VisActor *actor);
+int visual_bin_switch_finalize (VisBin *bin);
+int visual_bin_switch_set_style (VisBin *bin, VisBinSwitchStyle style);
+int visual_bin_switch_set_steps (VisBin *bin, int steps);
+int visual_bin_switch_set_automatic (VisBin *bin, int automatic);
+int visual_bin_switch_set_rate (VisBin *bin, float rate);
+int visual_bin_switch_set_mode (VisBin *bin, VisMorphMode mode);
+int visual_bin_switch_set_time (VisBin *bin, long sec, long usec);
+	
+int visual_bin_run (VisBin *bin);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_BIN_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_bmp.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,289 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "lv_common.h"
+#include "lv_log.h"
+#include "lv_endianess.h"
+#include "lv_bmp.h"
+
+#define BI_RGB	0
+#define BI_RLE8	1
+#define BI_RLE	2
+
+/**
+ * @defgroup VisBitmap VisBitmap
+ * @{
+ */
+
+/**
+ * Loads a BMP file into a VisVideo. The buffer will be located
+ * for the VisVideo.
+ *
+ * The loader currently only supports uncompressed bitmaps in the form
+ * of either 8 bits indexed or 24 bits RGB.
+ *
+ * Keep in mind that you need to free the palette by hand.
+ * 
+ * @param video Destination video where the bitmap should be loaded in.
+ * @param filename The filename of the bitmap to be loaded.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL, -VISUAL_ERROR_BMP_NOT_FOUND,
+ * 	-VISUAL_ERROR_BMP_NO_BMP, -VISUAL_ERROR_BMP_NOT_SUPPORTED or -VISUAL_ERROR_BMP_CORRUPTED
+ * 	on failure.
+ */
+int visual_bitmap_load (VisVideo *video, const char *filename)
+{
+	/* The win32 BMP header */
+	char magic[2];
+	uint32_t bf_size = 0;
+	uint32_t bf_bits = 0;
+
+	/* The win32 BITMAPINFOHEADER */
+	int32_t bi_size = 0;
+	int32_t bi_width = 0;
+	int32_t bi_height = 0;
+	int16_t bi_bitcount = 0;	
+	uint32_t bi_compression;
+	uint32_t bi_clrused;
+
+	/* File read vars */
+	int fd;
+
+	/* Worker vars */
+	uint8_t *data;
+	int pad;
+	int i;
+
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	fd = open (filename, O_RDONLY);
+
+	if (fd < 0) {
+		visual_log (VISUAL_LOG_WARNING, "Bitmap file not found: %s", filename);
+
+		return -VISUAL_ERROR_BMP_NOT_FOUND;
+	}
+
+	/* Read the magic string */
+	read (fd, magic, 2);
+
+	if (strncmp (magic, "BM", 2) != 0) {
+		visual_log (VISUAL_LOG_WARNING, "Not a bitmap file"); 
+	
+		return -VISUAL_ERROR_BMP_NO_BMP;
+	}
+
+	/* Read the file size */
+	read (fd, &bf_size, 4);
+	bf_size = VISUAL_ENDIAN_LEI32 (bf_size);
+
+	/* Skip past the reserved bits */
+	lseek (fd, 4, SEEK_CUR);
+
+	/* Read the offset bits */
+	read (fd, &bf_bits, 4);
+	bf_bits = VISUAL_ENDIAN_LEI32 (bf_bits);
+
+	/* Read the info structure size */
+	read (fd, &bi_size, 4);
+	bi_size = VISUAL_ENDIAN_LEI32 (bi_size);
+
+	if (bi_size == 12) {
+		/* And read the width, height */
+		read (fd, &bi_width, 2);
+		read (fd, &bi_height, 2);
+		bi_width = VISUAL_ENDIAN_LEI16 (bi_width);
+		bi_height = VISUAL_ENDIAN_LEI16 (bi_height);
+
+		/* Skip over the planet */
+		lseek (fd, 2, SEEK_CUR);
+
+		/* Read the bits per pixel */
+		read (fd, &bi_bitcount, 2);
+		bi_bitcount = VISUAL_ENDIAN_LEI16 (bi_bitcount);
+
+		bi_compression = BI_RGB;
+	} else {
+		/* And read the width, height */
+		read (fd, &bi_width, 4);
+		read (fd, &bi_height, 4);
+		bi_width = VISUAL_ENDIAN_LEI16 (bi_width);
+		bi_height = VISUAL_ENDIAN_LEI16 (bi_height);
+
+		/* Skip over the planet */
+		lseek (fd, 2, SEEK_CUR);
+
+		/* Read the bits per pixel */
+		read (fd, &bi_bitcount, 2);
+		bi_bitcount = VISUAL_ENDIAN_LEI16 (bi_bitcount);
+
+		/* Read the compression flag */
+		read (fd, &bi_compression, 4);
+		bi_compression = VISUAL_ENDIAN_LEI32 (bi_compression);
+
+		/* Skip over the nonsense we don't want to know */
+		lseek (fd, 12, SEEK_CUR);
+
+		/* Number of colors in palette */
+		read (fd, &bi_clrused, 4);
+		bi_clrused = VISUAL_ENDIAN_LEI32 (bi_clrused);
+
+		/* Skip over the other nonsense */
+		lseek (fd, 4, SEEK_CUR);
+	}
+
+	/* Check if we can handle it */
+	if (bi_bitcount != 8 && bi_bitcount != 24) {
+		visual_log (VISUAL_LOG_CRITICAL, "Only bitmaps with 8 bits or 24 bits per pixel are supported");
+		
+		return -VISUAL_ERROR_BMP_NOT_SUPPORTED;
+	}
+
+	/* We only handle uncompressed bitmaps */
+	if (bi_compression != BI_RGB) {
+		visual_log (VISUAL_LOG_CRITICAL, "Only uncompressed bitmaps are supported");
+
+		return -VISUAL_ERROR_BMP_NOT_SUPPORTED;
+	}
+
+	/* Load the palette */
+	if (bi_bitcount == 8) {
+		if (bi_clrused == 0)
+			bi_clrused = 256;
+
+		if (video->pal == NULL)
+			visual_object_unref (VISUAL_OBJECT (video->pal));
+		
+		video->pal = visual_palette_new (bi_clrused);
+
+		if (bi_size == 12) {
+			for (i = 0; i < bi_clrused; i++) {
+				read (fd, &video->pal->colors[i].b, 1);
+				read (fd, &video->pal->colors[i].g, 1);
+				read (fd, &video->pal->colors[i].r, 1);
+			}
+		} else {
+			for (i = 0; i < bi_clrused; i++) {
+				read (fd, &video->pal->colors[i].b, 1);
+				read (fd, &video->pal->colors[i].g, 1);
+				read (fd, &video->pal->colors[i].r, 1);
+				lseek (fd, 1, SEEK_CUR);
+			}
+		}
+	}
+
+	/* Make the target VisVideo ready for use */
+	visual_video_set_depth (video, visual_video_depth_enum_from_value (bi_bitcount));
+	visual_video_set_dimension (video, bi_width, bi_height);
+	visual_video_allocate_buffer (video);
+
+	/* Set to the beginning of image data, note that MickeySoft likes stuff upside down .. */
+	lseek (fd, bf_bits, SEEK_SET);
+
+	pad = ((video->pitch % 4) ? (4 - (video->pitch % 4)) : 0);
+
+	data = video->pixels + (video->height * video->pitch);
+	while (data > (uint8_t *) video->pixels) {
+		data -= video->pitch;
+
+		if (read (fd, data, video->pitch) != video->pitch) {
+			visual_log (VISUAL_LOG_CRITICAL, "Bitmap data is not complete");
+			
+			visual_video_free_buffer (video);
+
+			return -VISUAL_ERROR_BMP_CORRUPTED;
+		}
+
+#if !VISUAL_LITTLE_ENDIAN
+		switch (bi_bitcount) {
+			case 24: {
+				int i, p;
+				for (p=0, i=0; i<bi_width; i++){
+#	if VISUAL_BIG_ENDIAN
+					uint8_t c[2];
+
+					c[0] = data[p];
+					c[1] = data[p+2];
+
+					data[p] = c[1];
+					data[p+2] = c[0];
+
+					p+=3;
+#	else
+#		error todo
+#	endif
+				}
+				break;
+			}
+			default:
+				visual_log (VISUAL_LOG_CRITICAL, "Internal error.");
+		}
+#endif
+
+		if (pad != 0) {
+			lseek (fd, 4, pad);
+		}
+	}
+
+	close (fd);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Loads a bitmap into a VisVideo and return this, so it's not needed to 
+ * allocate a VisVideo before by hand.
+ *
+ * @see visual_bitmap_load
+ *
+ * @param filename The filename of the bitmap to be loaded.
+ *
+ * @return The VisVideo containing the bitmap or NULL on failure.
+ */
+VisVideo *visual_bitmap_load_new_video (const char *filename)
+{
+	VisVideo *video;
+
+	video = visual_video_new ();
+	
+	if (visual_bitmap_load (video, filename) < 0) {
+		visual_object_unref (VISUAL_OBJECT (video));
+
+		return NULL;
+	}
+
+	return video;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_bmp.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,40 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_BMP_H
+#define _LV_BMP_H
+
+#include <libvisual/lv_video.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int visual_bitmap_load (VisVideo *video, const char *filename);
+VisVideo *visual_bitmap_load_new_video (const char *filename);
+	
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_BMP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_color.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,212 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lv_common.h"
+#include "lv_color.h"
+
+/**
+ * @defgroup VisColor VisColor
+ * @{
+ */
+
+/**
+ * Creates a new VisColor structure
+ *
+ * @return A newly allocated VisColor.
+ */
+VisColor *visual_color_new ()
+{
+	VisColor *color;
+
+	color = visual_mem_new0 (VisColor, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (color), TRUE, NULL);
+
+	return color;
+}
+
+/**
+ * Compares two VisColors with each other. If they are not the same, 0 is returned, if the same 1.
+ *
+ * @param src1 Pointer to the first VisColor for comparison.
+ * @param src2 Pointer to the second VisColor for comparison.
+ *
+ * @return FALSE on different, TRUE on same, -VISUAL_ERROR_COLOR_NULL on failure.
+ */
+int visual_color_compare (VisColor *src1, VisColor *src2)
+{
+	visual_log_return_val_if_fail (src1 != NULL, -VISUAL_ERROR_COLOR_NULL)
+	visual_log_return_val_if_fail (src2 != NULL, -VISUAL_ERROR_COLOR_NULL)
+
+	if (src1->r != src2->r || src1->g != src2->g || src1->b != src2->b)
+		return FALSE;
+
+	return TRUE;
+}
+
+/**
+ * Fills the VisColor it's rgb values from hsv colorspace values.
+ *
+ * @param color Pointer to a VisColor which rgb values are filled.
+ * @param h Hue value for the hsv colorspace, ranging from 0 to 360.
+ * @param s Saturation value for the hsv colorspace, ranging from 0 to 1.
+ * @param v Value value for the hsv colorspace, ranging from 0 to 1.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_COLOR_NULL on failure.
+ */
+int visual_color_from_hsv (VisColor *color, float h, float s, float v)
+{
+	int i;
+	float f, w, q, t, r = 0, g = 0, b = 0;
+
+	visual_log_return_val_if_fail (color != NULL, -VISUAL_ERROR_COLOR_NULL);
+
+	if (s == 0.0)
+		s = 0.000001;
+
+	if (h == 360.0)
+		h = 0.0;
+
+	h = h / 60.0;
+	i = (int) h;
+	f = h - i;
+	w = v * (1.0 - s);
+	q = v * (1.0 - (s * f));
+	t = v * (1.0 - (s * (1.0 - f)));
+
+	switch (i) {
+		case 0: r = v; g = t; b = w; break;
+		case 1: r = q; g = v; b = w; break;
+		case 2: r = w; g = v; b = t; break;
+		case 3: r = w; g = q; b = v; break;
+		case 4: r = t; g = w; b = v; break;
+		case 5: r = v; g = w; b = q; break;
+
+		default:
+			break;
+	}
+
+	color->r = (float) r * 255;
+	color->g = (float) g * 255;
+	color->b = (float) b * 255;
+	
+	return VISUAL_OK;
+}
+
+/**
+ * Creates hsv colorspace values from a VisColor
+ *
+ * @param color Pointer to a VisColor from which hsv colorspace values are created.
+ * @param h Float pointer to a hue value for the hsv colorspace, ranging from 0 to 360.
+ * @param s Float pointer to a saturation value for the hsv colorspace, ranging from 0 to 1.
+ * @param v Float pointer to a value value for the hsv colorspace, ranging from 0 to 1.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_COLOR_NULL on failure.
+ */
+int visual_color_to_hsv (VisColor *color, float *h, float *s, float *v)
+{
+
+        float max, min, delta, r, g, b;
+
+	visual_log_return_val_if_fail (color != NULL, -VISUAL_ERROR_COLOR_NULL);
+
+	r = (float) color->r / 255.0;
+	g = (float) color->g / 255.0;
+	b = (float) color->b / 255.0;
+
+	max = r;
+	if (g > max)
+		max = g;
+
+	if (b > max)
+		max = b;
+
+	min = r;
+	if (g < min)
+		min = g;
+
+	if (b < min)
+		min = b;
+
+	*v = max;
+
+	if (max != 0.0)
+		*s = (max - min) / max;
+	else
+		*s = 0.0;
+
+	if (*s == 0.0) {
+		*h = 0.0;
+	} else {
+		delta = max - min;
+
+		if (r == max)
+			*h = (g - b) / delta;
+		else if (g == max)
+			*h = 2.0 + (b - r) / delta;
+		else if (b == max)
+			*h = 4.0 + (r - g) / delta;
+
+		*h = *h * 60.0;
+
+		if (*h < 0.0)
+			*h = *h + 360;
+	}
+
+
+	return VISUAL_OK;
+}
+
+/**
+ * Copies the RGB data of one VisColor into another.
+ *
+ * @param dest Pointer to the destination VisColor in which the RGB data is copied.
+ * @param src Pointer to the source VisColor from which the RGB data is copied.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_COLOR_NULL on failure.
+ */
+int visual_color_copy (VisColor *dest, VisColor *src)
+{
+	visual_log_return_val_if_fail (dest != NULL, -VISUAL_ERROR_COLOR_NULL);
+	visual_log_return_val_if_fail (src != NULL, -VISUAL_ERROR_COLOR_NULL);
+	
+	dest->r = src->r;
+	dest->g = src->g;
+	dest->b = src->b;
+	
+	/* You never know ;) */
+	dest->unused = src->unused;
+
+	return VISUAL_OK;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_color.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,59 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_COLOR_H
+#define _LV_COLOR_H
+
+#include <libvisual/lv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_COLOR(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisColor))
+
+typedef struct _VisColor VisColor;
+
+/**
+ * Data type to describe a palette entry, or a color. The HSV isn't kept in sync with RGB automaticly
+ * but it's there especially for VisUI.
+ */
+struct _VisColor {
+	VisObject	object;	/**< The VisObject data. */
+	uint8_t		r;	/**< The red channel of this VisColor. */
+	uint8_t		g;	/**< The green channel of this VisColor. */
+	uint8_t		b;	/**< The blue channel of this VisColor. */
+	uint8_t		unused;	/**< Unused. */
+};
+
+VisColor *visual_color_new (void);
+int visual_color_compare (VisColor *src1, VisColor *src2);
+int visual_color_from_hsv (VisColor *color, float h, float s, float v);
+int visual_color_to_hsv (VisColor *color, float *h, float *s, float *v);
+int visual_color_copy (VisColor *dest, VisColor *src);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_COLOR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_common.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,62 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_COMMON_H
+#define _LV_COMMON_H
+
+#include <libvisual/lv_mem.h>
+#include <libvisual/lv_log.h>
+#include <libvisual/lv_error.h>
+#include <libvisual/lv_types.h>
+#include <libvisual/lv_object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef NULL
+/**
+ * NULL define.
+ */
+#define NULL	(0)
+#endif
+
+#ifndef FALSE
+/**
+ * FALSE define.
+ */
+#define FALSE	(0)
+#endif
+
+#ifndef TRUE
+/**
+ * TRUE define.
+ */
+#define TRUE	(!FALSE)
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+	
+#endif /* _LV_COMMON_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_cpu.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,459 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *	    Chong Kai Xiong <descender@phreaker.net>
+ *	    Eric Anholt <anholt@FreeBSD.org>
+ *
+ * Extra Credits: MPlayer cpudetect hackers.
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* FIXME: clean this entire file up */
+
+#include "lvconfig.h"
+
+#if defined(VISUAL_ARCH_POWERPC)
+#if defined(VISUAL_OS_DARWIN)
+#include <sys/sysctl.h>
+#else
+#include <signal.h>
+#include <setjmp.h>
+#endif
+#endif
+
+#if defined(VISUAL_OS_NETBSD) || defined(VISUAL_OS_OPENBSD)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <machine/cpu.h>
+#endif
+
+#if defined(VISUAL_OS_FREEBSD)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+
+#if defined(VISUAL_OS_LINUX)
+#include <signal.h>
+#endif
+
+#if defined(VISUAL_OS_WIN32)
+#include <windows.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lv_log.h"
+#include "lv_cpu.h"
+
+static VisCPU _lv_cpu_caps;
+static int _lv_cpu_initialized = FALSE;
+
+static int has_cpuid (void);
+static int cpuid (unsigned int ax, unsigned int *p);
+
+/* The sigill handlers */
+#if defined(VISUAL_ARCH_X86) //x86 (linux katmai handler check thing)
+#if defined(VISUAL_OS_LINUX) && defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC)
+static void sigill_handler_sse( int signal, struct sigcontext sc )
+{
+	/* Both the "xorps %%xmm0,%%xmm0" and "divps %xmm0,%%xmm1"
+	 * instructions are 3 bytes long.  We must increment the instruction
+	 * pointer manually to avoid repeated execution of the offending
+	 * instruction.
+	 *
+	 * If the SIGILL is caused by a divide-by-zero when unmasked
+	 * exceptions aren't supported, the SIMD FPU status and control
+	 * word will be restored at the end of the test, so we don't need
+	 * to worry about doing it here.  Besides, we may not be able to...
+	 */
+	sc.eip += 3;
+
+	_lv_cpu_caps.hasSSE=0;
+}
+
+static void sigfpe_handler_sse( int signal, struct sigcontext sc )
+{
+	if ( sc.fpstate->magic != 0xffff ) {
+		/* Our signal context has the extended FPU state, so reset the
+		 * divide-by-zero exception mask and clear the divide-by-zero
+		 * exception bit.
+		 */
+		sc.fpstate->mxcsr |= 0x00000200;
+		sc.fpstate->mxcsr &= 0xfffffffb;
+	} else {
+		/* If we ever get here, we're completely hosed.
+		*/
+	}
+}
+#endif
+#endif /* VISUAL_OS_LINUX && _POSIX_SOURCE && X86_FXSR_MAGIC */
+
+#if defined(VISUAL_OS_WIN32)
+LONG CALLBACK win32_sig_handler_sse(EXCEPTION_POINTERS* ep)
+{
+	if(ep->ExceptionRecord->ExceptionCode==EXCEPTION_ILLEGAL_INSTRUCTION){
+		ep->ContextRecord->Eip +=3;
+		_lv_cpu_caps.hasSSE=0;       
+		return EXCEPTION_CONTINUE_EXECUTION;
+	}
+	return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif /* VISUAL_OS_WIN32 */
+
+
+#if defined(VISUAL_ARCH_POWERPC) && !defined(VISUAL_OS_DARWIN)
+static sigjmp_buf _lv_powerpc_jmpbuf;
+static volatile sig_atomic_t _lv_powerpc_canjump = 0;
+
+static void sigill_handler (int sig);
+
+static void sigill_handler (int sig)
+{
+	if (!_lv_powerpc_canjump) {
+		signal (sig, SIG_DFL);
+		raise (sig);
+	}
+
+	_lv_powerpc_canjump = 0;
+	siglongjmp (_lv_powerpc_jmpbuf, 1);
+}
+
+static void check_os_altivec_support( void )
+{
+#if defined(VISUAL_OS_DARWIN)
+	int sels[2] = {CTL_HW, HW_VECTORUNIT};
+	int has_vu = 0;
+	size_t len = sizeof(has_vu);
+	int err;
+
+	err = sysctl (sels, 2, &has_vu, &len, NULL, 0);   
+
+	if (err == 0)
+		if (has_vu != 0)
+			_lv_cpu_caps.hasAltiVec = 1;
+#else /* !VISUAL_OS_DARWIN */
+	/* no Darwin, do it the brute-force way */
+	/* this is borrowed from the libmpeg2 library */
+	signal (SIGILL, sigill_handler);
+	if (sigsetjmp (_lv_powerpc_jmpbuf, 1)) {
+		signal (SIGILL, SIG_DFL);
+	} else {
+		_lv_powerpc_canjump = 1;
+
+		asm volatile
+			("mtspr 256, %0\n\t"
+			 "vand %%v0, %%v0, %%v0"
+			 :
+			 : "r" (-1));
+
+		signal (SIGILL, SIG_DFL);
+		_lv_cpu_caps.hasAltiVec = 1;
+	}
+#endif
+}
+#endif
+
+/* If we're running on a processor that can do SSE, let's see if we
+ * are allowed to or not.  This will catch 2.4.0 or later kernels that
+ * haven't been configured for a Pentium III but are running on one,
+ * and RedHat patched 2.2 kernels that have broken exception handling
+ * support for user space apps that do SSE.
+ */
+static void check_os_katmai_support( void )
+{
+//	printf ("omg\n");
+#if defined(VISUAL_ARCH_X86)
+#if defined(VISUAL_OS_FREEBSD)
+	int has_sse=0, ret;
+	size_t len=sizeof(has_sse);
+
+	ret = sysctlbyname("hw.instruction_sse", &has_sse, &len, NULL, 0);
+	if (ret || !has_sse)
+		_lv_cpu_caps.hasSSE=0;
+
+#elif defined(VISUAL_OS_NETBSD) || defined(VISUAL_OS_OPENBSD)
+	int has_sse, has_sse2, ret, mib[2];
+	size_t varlen;
+
+	mib[0] = CTL_MACHDEP;
+	mib[1] = CPU_SSE;
+	varlen = sizeof(has_sse);
+
+	ret = sysctl(mib, 2, &has_sse, &varlen, NULL, 0);
+	if (ret < 0 || !has_sse) {
+		_lv_cpu_caps.hasSSE=0;
+	} else {
+		_lv_cpu_caps.hasSSE=1;
+	}
+
+	mib[1] = CPU_SSE2;
+	varlen = sizeof(has_sse2);
+	ret = sysctl(mib, 2, &has_sse2, &varlen, NULL, 0);
+	if (ret < 0 || !has_sse2) {
+		_lv_cpu_caps.hasSSE2=0;
+	} else {
+		_lv_cpu_caps.hasSSE2=1;
+	}
+	_lv_cpu_caps.hasSSE = 0; /* FIXME ?!?!? */
+
+#elif defined(VISUAL_OS_WIN32)
+	LPTOP_LEVEL_EXCEPTION_FILTER exc_fil;
+	if ( _lv_cpu_caps.hasSSE ) {
+		exc_fil = SetUnhandledExceptionFilter(win32_sig_handler_sse);
+		__asm __volatile ("xorps %xmm0, %xmm0");
+		SetUnhandledExceptionFilter(exc_fil);
+	}
+#elif defined(VISUAL_OS_LINUX)
+//	printf ("omg1\n");
+//	printf ("omg2\n");
+	struct sigaction saved_sigill;
+	struct sigaction saved_sigfpe;
+
+	/* Save the original signal handlers.
+	*/
+	sigaction( SIGILL, NULL, &saved_sigill );
+	sigaction( SIGFPE, NULL, &saved_sigfpe );
+
+#if 0		/* broken :( --nenolod */
+	signal( SIGILL, (void (*)(int))sigill_handler_sse );
+	signal( SIGFPE, (void (*)(int))sigfpe_handler_sse );
+#endif
+
+	/* Emulate test for OSFXSR in CR4.  The OS will set this bit if it
+	 * supports the extended FPU save and restore required for SSE.  If
+	 * we execute an SSE instruction on a PIII and get a SIGILL, the OS
+	 * doesn't support Streaming SIMD Exceptions, even if the processor
+	 * does.
+	 */
+	if ( _lv_cpu_caps.hasSSE ) {
+		__asm __volatile ("xorps %xmm1, %xmm0");
+	}
+
+	/* Emulate test for OSXMMEXCPT in CR4.  The OS will set this bit if
+	 * it supports unmasked SIMD FPU exceptions.  If we unmask the
+	 * exceptions, do a SIMD divide-by-zero and get a SIGILL, the OS
+	 * doesn't support unmasked SIMD FPU exceptions.  If we get a SIGFPE
+	 * as expected, we're okay but we need to clean up after it.
+	 *
+	 * Are we being too stringent in our requirement that the OS support
+	 * unmasked exceptions?  Certain RedHat 2.2 kernels enable SSE by
+	 * setting CR4.OSFXSR but don't support unmasked exceptions.  Win98
+	 * doesn't even support them.  We at least know the user-space SSE
+	 * support is good in kernels that do support unmasked exceptions,
+	 * and therefore to be safe I'm going to leave this test in here.
+	 */
+	if ( _lv_cpu_caps.hasSSE ) {
+		//      test_os_katmai_exception_support();
+	}
+
+	/* Restore the original signal handlers.
+	*/
+	sigaction( SIGILL, &saved_sigill, NULL );
+	sigaction( SIGFPE, &saved_sigfpe, NULL );
+
+#else
+//	printf ("hier dan3\n");
+	/* We can't use POSIX signal handling to test the availability of
+	 * SSE, so we disable it by default.
+	 */
+	_lv_cpu_caps.hasSSE=0;
+#endif /* __linux__ */
+//	printf ("hier dan\n");
+#endif
+//	printf ("hier dan ha\n");
+}
+
+
+static int has_cpuid (void)
+{
+#ifdef VISUAL_ARCH_X86
+	int a, c;
+
+	__asm __volatile
+		("pushf\n"
+		 "popl %0\n"
+		 "movl %0, %1\n"
+		 "xorl $0x200000, %0\n"
+		 "push %0\n"
+		 "popf\n"
+		 "pushf\n"
+		 "popl %0\n"
+		 : "=a" (a), "=c" (c)
+		 :
+		 : "cc");
+
+	return a != c;
+#else
+	return 0;
+#endif
+}
+
+static int cpuid (unsigned int ax, unsigned int *p)
+{
+#ifdef VISUAL_ARCH_X86
+	uint32_t flags;
+
+	__asm __volatile
+		("movl %%ebx, %%esi\n\t"
+		 "cpuid\n\t"
+		 "xchgl %%ebx, %%esi"
+		 : "=a" (p[0]), "=S" (p[1]),
+		 "=c" (p[2]), "=d" (p[3])
+		 : "0" (ax));
+
+	return VISUAL_OK;
+#else
+	return VISUAL_ERROR_CPU_INVALID_CODE;
+#endif
+}
+
+/**
+ * @defgroup VisCPU VisCPU
+ * @{
+ */
+
+void visual_cpu_initialize ()
+{
+	uint32_t cpu_flags;
+	unsigned int regs[4];
+	unsigned int regs2[4];
+
+	memset (&_lv_cpu_caps, 0, sizeof (VisCPU));
+
+	/* Check for arch type */
+#if defined(VISUAL_ARCH_MIPS)
+	_lv_cpu_caps.type = VISUAL_CPU_TYPE_MIPS;
+#elif defined(VISUAL_ARCH_ALPHA)
+	_lv_cpu_caps.type = VISUAL_CPU_TYPE_ALPHA;
+#elif defined(VISUAL_ARCH_SPARC)
+	_lv_cpu_caps.type = VISUAL_CPU_TYPE_SPARC;
+#elif defined(VISUAL_ARCH_X86)
+	_lv_cpu_caps.type = VISUAL_CPU_TYPE_X86;
+#elif defined(VISUAL_ARCH_POWERPC)
+	_lv_cpu_caps.type = VISUAL_CPU_TYPE_POWERPC;
+#else
+	_lv_cpu_caps.type = VISUAL_CPU_TYPE_OTHER;
+#endif
+
+	/* Count the number of CPUs in system */
+#if !defined(VISUAL_OS_WIN32) && !defined(VISUAL_OS_UNKNOWN)
+	_lv_cpu_caps.nrcpu = sysconf (_SC_NPROCESSORS_ONLN);
+	if (_lv_cpu_caps.nrcpu == -1)
+		_lv_cpu_caps.nrcpu = 1;
+#else
+	_lv_cpu_caps.nrcpu = 1;
+#endif
+	
+#if defined(VISUAL_ARCH_X86)
+	/* No cpuid, old 486 or lower */
+	if (has_cpuid () == 0)
+		return;
+
+	_lv_cpu_caps.cacheline = 32;
+	
+	/* Get max cpuid level */
+	cpuid (0x00000000, regs);
+	
+	if (regs[0] >= 0x00000001) {
+		unsigned int cacheline;
+
+		cpuid (0x00000001, regs2);
+
+		_lv_cpu_caps.x86cpuType = (regs2[0] >> 8) & 0xf;
+		if (_lv_cpu_caps.x86cpuType == 0xf)
+		    _lv_cpu_caps.x86cpuType = 8 + ((regs2[0] >> 20) & 255); /* use extended family (P4, IA64) */
+		
+		/* general feature flags */
+		_lv_cpu_caps.hasTSC  = (regs2[3] & (1 << 8  )) >>  8; /* 0x0000010 */
+		_lv_cpu_caps.hasMMX  = (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */
+		_lv_cpu_caps.hasSSE  = (regs2[3] & (1 << 25 )) >> 25; /* 0x2000000 */
+		_lv_cpu_caps.hasSSE2 = (regs2[3] & (1 << 26 )) >> 26; /* 0x4000000 */
+		_lv_cpu_caps.hasMMX2 = _lv_cpu_caps.hasSSE; /* SSE cpus supports mmxext too */
+
+		cacheline = ((regs2[1] >> 8) & 0xFF) * 8;
+		if (cacheline > 0)
+			_lv_cpu_caps.cacheline = cacheline;
+	}
+	
+	cpuid (0x80000000, regs);
+	
+	if (regs[0] >= 0x80000001) {
+
+		cpuid (0x80000001, regs2);
+		
+		_lv_cpu_caps.hasMMX  |= (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */
+		_lv_cpu_caps.hasMMX2 |= (regs2[3] & (1 << 22 )) >> 22; /* 0x400000 */
+		_lv_cpu_caps.has3DNow    = (regs2[3] & (1 << 31 )) >> 31; /* 0x80000000 */
+		_lv_cpu_caps.has3DNowExt = (regs2[3] & (1 << 30 )) >> 30;
+	}
+
+	if (regs[0] >= 0x80000006) {
+		cpuid (0x80000006, regs2);
+		_lv_cpu_caps.cacheline = regs2[2] & 0xFF;
+	}
+
+
+#if defined(VISUAL_OS_LINUX) || defined(VISUAL_OS_FREEBSD) || defined(VISUAL_OS_NETBSD) || defined(VISUAL_OS_CYGWIN) || defined(VISUAL_OS_OPENBSD)
+	if (_lv_cpu_caps.hasSSE)
+		check_os_katmai_support ();
+
+	if (!_lv_cpu_caps.hasSSE)
+		_lv_cpu_caps.hasSSE2 = 0;
+#else
+	_lv_cpu_caps.hasSSE=0;
+	_lv_cpu_caps.hasSSE2 = 0;
+#endif
+#endif /* VISUAL_ARCH_X86 */
+
+#if VISUAL_ARCH_POWERPC
+	check_os_altivec_support ();
+#endif /* VISUAL_ARCH_POWERPC */
+
+	visual_log (VISUAL_LOG_DEBUG, "CPU: Number of CPUs: %d", _lv_cpu_caps.nrcpu);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: type %d", _lv_cpu_caps.type);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: X86 type %d", _lv_cpu_caps.x86cpuType);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: cacheline %d", _lv_cpu_caps.cacheline);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: TSC %d", _lv_cpu_caps.hasTSC);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: MMX %d", _lv_cpu_caps.hasMMX);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: MMX2 %d", _lv_cpu_caps.hasMMX2);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: SSE %d", _lv_cpu_caps.hasSSE);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: SSE2 %d", _lv_cpu_caps.hasSSE2);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: 3DNow %d", _lv_cpu_caps.has3DNow);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: 3DNowExt %d", _lv_cpu_caps.has3DNowExt);
+	visual_log (VISUAL_LOG_DEBUG, "CPU: AltiVec %d", _lv_cpu_caps.hasAltiVec);
+
+	_lv_cpu_initialized = TRUE;
+}
+
+VisCPU *visual_cpu_get_caps ()
+{
+	if (_lv_cpu_initialized == FALSE)
+		return NULL;
+
+	return &_lv_cpu_caps;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_cpu.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,77 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *	    Chong Kai Xiong <descender@phreaker.net>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_CPU_H
+#define _LV_CPU_H
+
+#include <libvisual/lvconfig.h>
+#include <libvisual/lv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef enum {
+	VISUAL_CPU_TYPE_MIPS,
+	VISUAL_CPU_TYPE_ALPHA,
+	VISUAL_CPU_TYPE_SPARC,
+	VISUAL_CPU_TYPE_X86,
+	VISUAL_CPU_TYPE_POWERPC,
+	VISUAL_CPU_TYPE_OTHER
+} VisCPUType;
+
+typedef struct _VisCPU VisCPU;
+
+/**
+ * This VisCPU structure contains information regarding the processor.
+ *
+ * @see visual_cpu_get_info
+ */
+struct _VisCPU {
+	VisObject	object;	/**< The VisObject data. */
+	VisCPUType	type;	/**< Contains the CPU/arch type. */
+	int		nrcpu;	/**< Contains the number of CPUs in the system. */
+
+	/* Feature flags */
+	int		x86cpuType;
+	int		cacheline;
+	int		hasTSC;
+	int		hasMMX;
+	int		hasMMX2;
+	int		hasSSE;
+	int		hasSSE2;
+	int		has3DNow;
+	int		has3DNowExt;
+
+	int		hasAltiVec;
+};
+
+void visual_cpu_initialize (void);
+VisCPU *visual_cpu_get_caps (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_CPU_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_endianess.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,75 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_ENDIANESS_H
+#define _LV_ENDIANESS_H
+
+#include <libvisual/lvconfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Macros to convert LE <-> BE
+ * 'I' stands for integer here.
+ */
+#define VISUAL_ENDIAN_LE_BE_I16(w) (\
+	(((w) & 0xff00) >> 8) |\
+	(((w) & 0x00ff) << 8) )
+
+#define VISUAL_ENDIAN_LE_BE_I32(w) (\
+	(((w) & 0x000000ff) << 24) | \
+	(((w) & 0x0000ff00) << 8) | \
+	(((w) & 0x00ff0000) >> 8) | \
+	(((w) & 0xff000000) >> 24) )
+
+
+#if VISUAL_BIG_ENDIAN & VISUAL_LITTLE_ENDIAN
+#	error determining system endianess.
+#endif
+
+/**
+ * Arch. dependant definitions
+ */
+
+#if VISUAL_BIG_ENDIAN
+#	define VISUAL_ENDIAN_BEI16(x) (x)
+#	define VISUAL_ENDIAN_BEI32(x) (x)
+#	define VISUAL_ENDIAN_LEI16(x) VISUAL_ENDIAN_LE_BE_I16(x)
+#	define VISUAL_ENDIAN_LEI32(x) VISUAL_ENDIAN_LE_BE_I32(x)
+#endif
+
+#if VISUAL_LITTLE_ENDIAN
+#	define VISUAL_ENDIAN_LEI16(x) (x)
+#	define VISUAL_ENDIAN_LEI32(x) (x)
+#	define VISUAL_ENDIAN_BEI16(x) VISUAL_ENDIAN_LE_BE_I16(x)
+#	define VISUAL_ENDIAN_BEI32(x) VISUAL_ENDIAN_LE_BE_I32(x)
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */   
+
+#endif /* _LV_ENDIANESS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_error.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,223 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <signal.h>
+
+#include "lv_log.h"
+#include "lv_error.h"
+
+static const char *__lv_error_human_readable[] = {
+	"There was no error",							/* VISUAL_OK */
+
+	"General error occurred",						/* VISUAL_ERROR_GENERAL */
+	"General NULL pointer error",						/* VISUAL_ERROR_NULL */
+	"An impossible event occurred",						/* VISUAL_ERROR_IMPOSSIBLE */
+
+	"VisActor is NULL",							/* VISUAL_ERROR_ACTOR_NULL */
+	"VisActor it's video is NULL",						/* VISUAL_ERROR_ACTOR_VIDEO_NULL */
+	"VisActor it's plugin is NULL",						/* VISUAL_ERROR_ACTOR_PLUGIN_NULL */
+	"VisActor failed while trying to forcefully negotiate a GL surface",	/* VISUAL_ERROR_ACTOR_GL_NEGOTIATE */
+
+	"VisAudio is NULL",							/* VISUAL_ERROR_AUDIO_NULL */
+	
+	"Bitmap is not a bitmap file",						/* VISUAL_ERROR_BMP_NO_BMP */
+	"Bitmap can not be found",						/* VISUAL_ERROR_BMP_NOT_FOUND */
+	"Bitmap is not supported",						/* VISUAL_ERROR_BMP_NOT_SUPPORTED */
+	"Bitmap is corrupted",							/* VISUAL_ERROR_BMP_CORRUPTED */
+
+	"VisColor is NULL",							/* VISUAL_ERROR_COLOR_NULL */
+	
+	"The code can not run on this architecture",				/* VISUAL_ERROR_CPU_INVALID_CODE */
+	
+	"Global error handler is NULL",						/* VISUAL_ERROR_ERROR_HANDLER_NULL */
+	
+	"VisEvent is NULL",							/* VISUAL_ERROR_EVENT_NULL */
+	"VisEventQueue is NULL",						/* VISUAL_ERROR_EVENT_QUEUE_NULL */
+	
+	"VisInput is NULL",							/* VISUAL_ERROR_INPUT_NULL */
+	"VisInput it's plugin is NULL",						/* VISUAL_ERROR_INPUT_PLUGIN_NULL */
+	
+	"No paths were given to seek for plugins",				/* VISUAL_ERROR_LIBVISUAL_NO_PATHS */
+	"Libvisual is already initialized",					/* VISUAL_ERROR_LIBVISUAL_ALREADY_INITIALIZED */
+	"Libvisual is not initialized",						/* VISUAL_ERROR_LIBVISUAL_NOT_INITIALIZED */
+	"Libvisual has not build a plugin registry",				/* VISUAL_ERROR_LIBVISUAL_NO_REGISTRY */
+	
+	"VisList is NULL",							/* VISUAL_ERROR_LIST_NULL */
+	"VisListEntry is NULL",							/* VISUAL_ERROR_LIST_ENTRY_NULL */
+	"VisListEntry is invalid",						/* VISUAL_ERROR_LIST_ENTRY_INVALID */
+	
+	"Given memory pointer is NULL",						/* VISUAL_ERROR_MEM_NULL */
+	
+	"VisMorph is NULL",							/* VISUAL_ERROR_MORPH_NULL */
+	"VisMorph it's plugin is NULL",						/* VISUAL_ERROR_MORPH_PLUGIN_NULL */
+	
+	"VisPalette is NULL",							/* VISUAL_ERROR_PALETTE_NULL */
+	"VisPalette it's size conflicts",					/* VISUAL_ERROR_PALETTE_SIZE */
+	
+	"VisParamEntry is NULL",						/* VISUAL_ERROR_PARAM_NULL */
+	"VisParamContainer is NULL",						/* VISUAL_ERROR_PARAM_CONTAINER_NULL */
+	"VisParamEntry not found in VisParamContainer",				/* VISUAL_ERROR_PARAM_NOT_FOUND */
+	"VisParamEntry it's change notify callback is NULL",			/* VISUAL_ERROR_PARAM_CALLBACK_NULL */
+	"VisParamEntry contains too many change notify callbacks",		/* VISUAL_ERROR_PARAM_CALLBACK_TOO_MANY */
+	"VisParamEntry is of invalid type",					/* VISUAL_ERROR_PARAM_INVALID_TYPE */
+	
+	"VisPluginData is NULL",						/* VISUAL_ERROR_PLUGIN_NULL */
+	"VisPluginInfo is NULL",						/* VISUAL_ERROR_PLUGIN_INFO_NULL */
+	"VisPluginRef is NULL",							/* VISUAL_ERROR_PLUGIN_REF_NULL */
+	"VisPluginEnvironElement is NULL",					/* VISUAL_ERROR_PLUGIN_ENVIRON_NULL */
+	"Plugin does not have an event handler",				/* VISUAL_ERROR_PLUGIN_NO_EVENT_HANDLER */
+	"Plugin handle is NULL",						/* VISUAL_ERROR_PLUGIN_HANDLE_NULL */
+	"Plugin is already realized",						/* VISUAL_ERROR_PLUGIN_ALREADY_REALIZED */
+	
+	"VisRandomContext is NULL",						/* VISUAL_ERROR_RANDOM_CONTEXT_NULL */
+	
+	"VisSongInfo is NULL",							/* VISUAL_ERROR_SONGINFO_NULL */
+
+	"VisThread is NULL",							/* VISUAL_ERROR_THREAD_NULL */
+	"Threading is disabled or not supported",				/* VISUAL_ERROR_THREAD_NO_THREADING */
+	"VisMutex is NULL",							/* VISUAL_ERROR_MUTEX_NULL */
+	"VisMutex lock failed",							/* VISUAL_ERROR_MUTEX_LOCK_FAILURE */
+	"VisMutex trylock failed",						/* VISUAL_ERROR_MUTEX_TRYLOCK_FAILURE */
+	"VisMutex unlock failed",						/* VISUAL_ERROR_MUTEX_UNLOCK_FAILURE */
+
+	"VisTransform is NULL",							/* VISUAL_ERROR_TRANSFORM_NULL */
+	"The VisTransform negotiate with the target VisVideo failed",		/* VISUAL_ERROR_TRANSFORM_NEGOTIATE */
+	"The VisTransform it's plugin is NULL",					/* VISUAL_ERROR_TRANSFORM_PLUGIN_NULL */
+	"The VisTransform it's video is NULL",					/* VISUAL_ERROR_TRANSFORM_VIDEO_NULL */
+	"The VisTransform it's palette is NULL",				/* VISUAL_ERROR_TRANSFORM_PALETTE_NULL */
+
+	"VisObject destruction failed",						/* VISUAL_ERROR_OBJECT_DTOR_FAILED */
+	"VisObject is NULL",							/* VISUAL_ERROR_OBJECT_NULL */
+	"VisObject is not allocated",						/* VISUAL_ERROR_OBJECT_NOT_ALLOCATED */
+	
+	"VisTime is NULL",							/* VISUAL_ERROR_TIME_NULL */
+	"visual_time_usleep() is not supported",				/* VISUAL_ERROR_TIME_NO_USLEEP */
+	"VisTimer is NULL",							/* VISUAL_ERROR_TIMER_NULL */
+	
+	"VisUIWidget is NULL",							/* VISUAL_ERROR_UI_WIDGET_NULL */
+	"VisUIContainer is NULL",						/* VISUAL_ERROR_UI_CONTAINER_NULL */
+	"VisUIBox is NULL",							/* VISUAL_ERROR_UI_BOX_NULL */
+	"VisUITable is NULL",							/* VISUAL_ERROR_UI_TABLE_NULL */
+	"VisUIFrame is NULL",							/* VISUAL_ERROR_UI_FRAME_NULL */
+	"VisUILabel is NULL",							/* VISUAL_ERROR_UI_LABEL_NULL */
+	"VisUIImage is NULL",							/* VISUAL_ERROR_UI_IMAGE_NULL */
+	"VisUISeparator is NULL",						/* VISUAL_ERROR_UI_SEPARATOR_NULL */
+	"VisUIMutator is NULL",							/* VISUAL_ERROR_UI_MUTATOR_NULL */
+	"VisUIRange is NULL",							/* VISUAL_ERROR_UI_RANGE_NULL */
+	"VisUIEntry is NULL",							/* VISUAL_ERROR_UI_ENTRY_NULL */
+	"VisUISlider is NULL",							/* VISUAL_ERROR_UI_SLIDER_NULL */
+	"VisUINumeric is NULL",							/* VISUAL_ERROR_UI_NUMERIC_NULL */
+	"VisUIColor is NULL",							/* VISUAL_ERROR_UI_COLOR_NULL */
+	"VisUIChoice is NULL",							/* VISUAL_ERROR_UI_CHOICE_NULL */
+	"VisUIPopup is NULL",							/* VISUAL_ERROR_UI_POPUP_NULL */
+	"VisUIList is NULL",							/* VISUAL_ERROR_UI_LIST_NULL */
+	"VisUIRadio is NULL",							/* VISUAL_ERROR_UI_RADIO_NULL */
+	"VisUICheckbox is NULL",						/* VISUAL_ERROR_UI_CHECKBOX_NULL */
+	"VisUIChoiceEntry is NULL",						/* VISUAL_ERROR_UI_CHOICE_ENTRY_NULL */
+	"No choice in VisUIChoice is activated",				/* VISUAL_ERROR_UI_CHOICE_NONE_ACTIVE */
+
+	"VisVideo is NULL",							/* VISUAL_ERROR_VIDEO_NULL */
+	"VisVideo has allocated pixel buffer",					/* VISUAL_ERROR_VIDEO_HAS_ALLOCATED */
+	"VisVideo it's pixel buffer is NULL",					/* VISUAL_ERROR_VIDEO_PIXELS_NULL */
+	"VisVideo it's pixel buffer is not allocated",				/* VISUAL_ERROR_VIDEO_NO_ALLOCATED */
+	"VisVideo has pixel buffer",						/* VISUAL_ERROR_VIDEO_HAS_PIXELS */
+	"VisVideo is of invalid bytes per pixel",				/* VISUAL_ERROR_VIDEO_INVALID_BPP */
+	"VisVideo is of invalid depth",						/* VISUAL_ERROR_VIDEO_INVALID_DEPTH */
+	"Invalid scale method given",						/* VISUAL_ERROR_VIDEO_INVALID_SCALE_METHOD */
+	"Given coordinates are out of bounds",					/* VISUAL_ERROR_VIDEO_OUT_OF_BOUNDS */
+	"Given VisVideos are not indentical",					/* VISUAL_ERROR_VIDEO_NOT_INDENTICAL */
+	"VisVideo is not depth transformed as requested"			/* VISUAL_ERROR_VIDEO_NOT_TRANSFORMED */
+};
+
+static VisErrorHandlerFunc error_handler = NULL;
+static void *error_handler_priv = NULL;
+
+/**
+ * @defgroup VisError VisError
+ * @{
+ */
+
+/**
+ * Raise a libvisual error. With the standard error handler this will
+ * do a raise(SIGTRAP). You can set your own error handler function using the
+ * visual_error_set_handler.
+ *
+ * @see visual_error_set_handler
+ *
+ * @return Returns the return value from the handler that is set.
+ */
+int visual_error_raise ()
+{
+	if (error_handler == NULL) {
+		raise (SIGTRAP);
+		exit (1);
+	}
+	
+	return error_handler (error_handler_priv);
+}
+
+/**
+ * Sets the error handler callback. By using this function you
+ * can override libvisual it's default error handler.
+ *
+ * @param handler The error handler which you want to use
+ *      to handle libvisual errors.
+ * @param priv Optional private data which could be needed in the
+ *      error handler that has been set.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_ERROR_HANDLER_NULL on failure.
+ */
+int visual_error_set_handler (VisErrorHandlerFunc handler, void *priv)
+{
+	visual_log_return_val_if_fail (handler != NULL, -VISUAL_ERROR_ERROR_HANDLER_NULL);
+
+	error_handler = handler;
+	error_handler_priv = priv;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Translates an error into a human readable string, the returned string should not be freed.
+ *
+ * @param err Numeric error value.
+ * 
+ * @return Human readable string, or NULL on failure.
+ */
+const char *visual_error_to_string (int err)
+{
+	if (abs (err) >= VISUAL_ERROR_LIST_END)
+		return "The error value given to visual_error_to_string() is invalid";
+
+	return __lv_error_human_readable[abs (err)];
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_error.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,206 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_ERROR_H
+#define _LV_ERROR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* WARNING when you add an new error to this list, make sure that you update lv_error.c it's
+ * human readable string list as well!!! */
+/**
+ * Enumerate of all possible numeric error values. 
+ */
+enum {
+	/* Ok! */
+	VISUAL_OK,					/**< No error. */
+
+	/* Standard error entries */
+	VISUAL_ERROR_GENERAL,				/**< General error. */
+	VISUAL_ERROR_NULL,				/**< Something is NULL that shouldn't be. */
+	VISUAL_ERROR_IMPOSSIBLE,			/**< The impossible happened, this should never happen. */
+
+	/* Error entries for the VisActor system */
+	VISUAL_ERROR_ACTOR_NULL,			/**< The VisActor is NULL. */
+	VISUAL_ERROR_ACTOR_VIDEO_NULL,			/**< The VisVideo target member in the VisActor is NULL. */
+	VISUAL_ERROR_ACTOR_PLUGIN_NULL,			/**< The VisActor plugin in this context is NULL. */
+	VISUAL_ERROR_ACTOR_GL_NEGOTIATE,		/**< Tried depth forcing a GL VisACtor. */
+
+	/* Error entries for the VisAudio system */
+	VISUAL_ERROR_AUDIO_NULL,			/**< The VisAudio is NULL. */
+	
+	/* Error entries for the VisBMP system */
+	VISUAL_ERROR_BMP_NO_BMP,			/**< Not a bitmap file. */
+	VISUAL_ERROR_BMP_NOT_FOUND,			/**< File not found. */
+	VISUAL_ERROR_BMP_NOT_SUPPORTED,			/**< File format not supported. */
+	VISUAL_ERROR_BMP_CORRUPTED,			/**< Bitmap file is corrupted. */
+	
+	/* Error entries for the VisColor system */
+	VISUAL_ERROR_COLOR_NULL,			/**< The VisColor is NULL. */
+
+	/* Error entries for arch related errors and VisCPU system */
+	VISUAL_ERROR_CPU_INVALID_CODE,
+	
+	/* Error entries for the VisError system */
+	VISUAL_ERROR_ERROR_HANDLER_NULL,		/**< Error handler is NULL. */
+	
+	/* Error entries for the VisEvent system */
+	VISUAL_ERROR_EVENT_NULL,			/**< The VisEvent is NULL. */
+	VISUAL_ERROR_EVENT_QUEUE_NULL,			/**< The VisEventQueue is nULL. */
+	
+	/* Error entries for the VisInput system */
+	VISUAL_ERROR_INPUT_NULL,			/**< The VisInput is NULL. */
+	VISUAL_ERROR_INPUT_PLUGIN_NULL,			/**< The VisInputPlugin is NULL. */
+	
+	/* Error entries for the VisLibvisual system */
+	VISUAL_ERROR_LIBVISUAL_NO_PATHS,		/**< Paths can be added to plugin dir list. */
+	VISUAL_ERROR_LIBVISUAL_ALREADY_INITIALIZED,	/**< Libvisual is already initialized. */
+	VISUAL_ERROR_LIBVISUAL_NOT_INITIALIZED,		/**< Libvisual is not initialized. */
+	VISUAL_ERROR_LIBVISUAL_NO_REGISTRY,		/**< No internal plugin registry is set up. */
+	
+	/* Error entries for the VisList system */
+	VISUAL_ERROR_LIST_NULL,				/**< The VisList is NULL. */
+	VISUAL_ERROR_LIST_ENTRY_NULL,			/**< The VisListEntry is NULL. */
+	VISUAL_ERROR_LIST_ENTRY_INVALID,		/**< The VisListEntry is invalid. */
+	
+	/* Error entries for the VisMem system */
+	VISUAL_ERROR_MEM_NULL,				/**< The memory pointer given is NULL. */
+	
+	/* Error entries for the VisMorph system */
+	VISUAL_ERROR_MORPH_NULL,			/**< The VisMorph is NULL. */
+	VISUAL_ERROR_MORPH_PLUGIN_NULL,			/**< The VisMorphPlugin is NULL. */
+	
+	/* Error entries for the VisPalette system */
+	VISUAL_ERROR_PALETTE_NULL,			/**< The VisPalette is NULL. */
+	VISUAL_ERROR_PALETTE_SIZE,			/**< Given VisPalette entries are not of the same size. */
+	
+	/* Error entries for the VisParam system */
+	VISUAL_ERROR_PARAM_NULL,			/**< The VisParamEntry is NULL. */
+	VISUAL_ERROR_PARAM_CONTAINER_NULL,		/**< The VisParamContainer is NULL. */
+	VISUAL_ERROR_PARAM_NOT_FOUND,			/**< The requested VisParamEntry is not found. */
+	VISUAL_ERROR_PARAM_CALLBACK_NULL,		/**< The given param change callback is NULL. */
+	VISUAL_ERROR_PARAM_CALLBACK_TOO_MANY,		/**< Too many param change callbacks are registered. */
+	VISUAL_ERROR_PARAM_INVALID_TYPE,		/**< The VisParamEntry is of invalid type. */
+	
+	/* Error entries for the VisPlugin system */
+	VISUAL_ERROR_PLUGIN_NULL,			/**< The VisPluginData is NULL. */
+	VISUAL_ERROR_PLUGIN_INFO_NULL,			/**< The VisPluginInfo is NULL. */
+	VISUAL_ERROR_PLUGIN_REF_NULL,			/**< The VisPluginRef is NULL. */
+	VISUAL_ERROR_PLUGIN_ENVIRON_NULL,		/**< The VisPluginEnvironElement is NULL. */
+	VISUAL_ERROR_PLUGIN_NO_EVENT_HANDLER,		/**< The plugin has no event handler registrated. */
+	VISUAL_ERROR_PLUGIN_HANDLE_NULL,		/**< The dlopen handle of the plugin is NULL. */
+	VISUAL_ERROR_PLUGIN_ALREADY_REALIZED,		/**< The plugin is already realized. */
+	
+	/* Error entries for the VisRandom system */
+	VISUAL_ERROR_RANDOM_CONTEXT_NULL,		/**< The VisRandomContext is NULL. */
+	
+	/* Error entries for the VisSonginfo system */
+	VISUAL_ERROR_SONGINFO_NULL,			/**< The VisSongInfo is NULL. */
+
+	/* Error entries for the VisThread system */
+	VISUAL_ERROR_THREAD_NULL,			/**< The VisThread is NULL. */
+	VISUAL_ERROR_THREAD_NO_THREADING,		/**< Threading is not supported in this build. */
+	VISUAL_ERROR_MUTEX_NULL,			/**< The VisMutex is NULL. */
+	VISUAL_ERROR_MUTEX_LOCK_FAILURE,		/**< Failed locking the VisMutex. */
+	VISUAL_ERROR_MUTEX_TRYLOCK_FAILURE,		/**< Failed trylocking the VisMutex. */
+	VISUAL_ERROR_MUTEX_UNLOCK_FAILURE,		/**< Failed unlocking the VisMutex. */
+
+	/* Error entries for the VisTransform system */
+	VISUAL_ERROR_TRANSFORM_NULL,			/**< The VisTransform is NULL. */
+	VISUAL_ERROR_TRANSFORM_NEGOTIATE,		/**< The VisTransform negotiate with the VisVideo failed. */
+	VISUAL_ERROR_TRANSFORM_PLUGIN_NULL,		/**< The VisTransform plugin in this context is NULL. */
+	VISUAL_ERROR_TRANSFORM_VIDEO_NULL,		/**< The VisVideo target member in the VisTransform is NULL. */
+	VISUAL_ERROR_TRANSFORM_PALETTE_NULL,		/**< The VisPalette target member in this VisTransform is NULL. */
+
+	/* Error entries for the VisObject system */
+	VISUAL_ERROR_OBJECT_DTOR_FAILED,		/**< The destructor assigned to a VisObject failed destroying the VisObject. */
+	VISUAL_ERROR_OBJECT_NULL,			/**< The VisObject is NULL. */
+	VISUAL_ERROR_OBJECT_NOT_ALLOCATED,		/**< The VisObject is not allocated. */
+	
+	/* Error entries for the VisTime system */
+	VISUAL_ERROR_TIME_NULL,				/**< The VisTime is NULL. */
+	VISUAL_ERROR_TIME_NO_USLEEP,			/**< visual_time_usleep is not working on this system. */
+	VISUAL_ERROR_TIMER_NULL,			/**< The VisTimer is NULL. */
+	
+	/* Error entries for the VisUI system */
+	VISUAL_ERROR_UI_WIDGET_NULL,			/**< The VisUIWidget is NULL. */
+	VISUAL_ERROR_UI_CONTAINER_NULL,			/**< The VisUIContainer is NULL. */
+	VISUAL_ERROR_UI_BOX_NULL,			/**< The VisUIBox is NULL. */
+	VISUAL_ERROR_UI_TABLE_NULL,			/**< The VisUITable is NULL. */
+	VISUAL_ERROR_UI_FRAME_NULL,			/**< The VisUIFrame is NULL. */
+	VISUAL_ERROR_UI_LABEL_NULL,			/**< The VisUILabel is NULL. */
+	VISUAL_ERROR_UI_IMAGE_NULL,			/**< The VisUIImage is NULL. */
+	VISUAL_ERROR_UI_SEPARATOR_NULL,			/**< The VisUISperator is NULL. */
+	VISUAL_ERROR_UI_MUTATOR_NULL,			/**< The VisUIMutator is NULL. */
+	VISUAL_ERROR_UI_RANGE_NULL,			/**< The VisUIRange is NULL. */
+	VISUAL_ERROR_UI_ENTRY_NULL,			/**< The VisUIEntry is NULL. */
+	VISUAL_ERROR_UI_SLIDER_NULL,			/**< The VisUISlider is NULL. */
+	VISUAL_ERROR_UI_NUMERIC_NULL,			/**< The VisUINumeric is NULL. */
+	VISUAL_ERROR_UI_COLOR_NULL,			/**< The VisUIColor is NULL. */
+	VISUAL_ERROR_UI_CHOICE_NULL,			/**< The VisUIChoice is NULL. */
+	VISUAL_ERROR_UI_POPUP_NULL,			/**< The VisUIPopup is NULL. */
+	VISUAL_ERROR_UI_LIST_NULL,			/**< The VisUIList is NULL. */
+	VISUAL_ERROR_UI_RADIO_NULL,			/**< The VisUIRadio is NULL. */
+	VISUAL_ERROR_UI_CHECKBOX_NULL,			/**< The VisUICheckbox is NULL. */
+	VISUAL_ERROR_UI_CHOICE_ENTRY_NULL,		/**< The VisUIChoiceEntry is NULL. */
+	VISUAL_ERROR_UI_CHOICE_NONE_ACTIVE,		/**< there is no VisUIChoiceEntry active. */
+
+	/* Error entries for the VisVideo system */
+	VISUAL_ERROR_VIDEO_NULL,			/**< The VisVideo is NULL. */
+	VISUAL_ERROR_VIDEO_HAS_ALLOCATED,		/**< The VisVideo has an allocated buffer. */
+	VISUAL_ERROR_VIDEO_PIXELS_NULL,			/**< The VisVideo doesn't point to a pixel buffer. */
+	VISUAL_ERROR_VIDEO_NO_ALLOCATED,		/**< The VisVideo doesn't have an allocated pixel buffer. */
+	VISUAL_ERROR_VIDEO_HAS_PIXELS,			/**< The VisVideo already points to a pixel buffer. */
+	VISUAL_ERROR_VIDEO_INVALID_BPP,			/**< The VisVideo it's bytes per pixel is invalid. */
+	VISUAL_ERROR_VIDEO_INVALID_DEPTH,		/**< The VisVideoDepth value is not valid. */
+	VISUAL_ERROR_VIDEO_INVALID_SCALE_METHOD,	/**< The VisVideoScaleMethod argument is not valid. */
+	VISUAL_ERROR_VIDEO_OUT_OF_BOUNDS,		/**< The X or Y value are greater than the VisVideo it's dimension. */
+	VISUAL_ERROR_VIDEO_NOT_INDENTICAL,		/**< The two VisVideo their configuration are not indentical. */
+	VISUAL_ERROR_VIDEO_NOT_TRANSFORMED,		/**< Could not depth transform a VisVideo. */
+
+	VISUAL_ERROR_LIST_END				/**< Last entry, to check against for the number of errors. */
+};
+
+/**
+ * Functions that want to handle libvisual errors must match this signature. The standard
+ * libvisual error handler aborts the program after an error by raise(SIGTRAP). If it's
+ * desired to override this use visual_set_error_handler to set your own error handler.
+ *
+ * @see visual_set_error_handler
+ *
+ * @arg priv Private field to be used by the client. The library will never touch this.
+ */
+typedef int (*VisErrorHandlerFunc) (void *priv);
+
+int visual_error_raise (void);
+int visual_error_set_handler (VisErrorHandlerFunc handler, void *priv);
+
+const char *visual_error_to_string (int err);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_ERROR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_event.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,454 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lvconfig.h"
+#include "lv_event.h"
+#include "lv_log.h"
+
+static int eventqueue_dtor (VisObject *object);
+
+static void event_list_destroy (void *data);
+
+static int eventqueue_dtor (VisObject *object)
+{
+	VisEventQueue *eventqueue = VISUAL_EVENTQUEUE (object);
+
+	visual_list_destroy_elements (&eventqueue->events);
+
+	return VISUAL_OK;
+}
+
+static void event_list_destroy (void *data)
+{
+	VisEvent *event = VISUAL_EVENT (data);
+
+	if (event == NULL)
+		return;
+
+	visual_object_unref (VISUAL_OBJECT (event));
+}
+
+
+/**
+ * @defgroup VisEvent VisEvent
+ * @{
+ */
+
+/**
+ * Creates a new VisEvent structure.
+ *
+ * @see visual_actor_get_eventqueue
+ *
+ * @return A newly allocated VisEvent
+ */
+VisEvent *visual_event_new ()
+{
+	VisEvent *event;
+
+	event = visual_mem_new0 (VisEvent, 1);
+
+	/* Do the VisObject initialization*/
+	visual_object_initialize (VISUAL_OBJECT (event), TRUE, NULL);
+
+	return event;
+}
+
+/**
+ * Creates a new VisEventQueue data structure.
+ *
+ * @return Newly allocated VisEventQueue.
+ */
+VisEventQueue *visual_event_queue_new ()
+{
+	VisEventQueue *eventqueue;
+
+	eventqueue = visual_mem_new0 (VisEventQueue, 1);
+
+	/* Do the VisObject initialization*/
+	visual_object_initialize (VISUAL_OBJECT (eventqueue), TRUE, eventqueue_dtor);
+
+	eventqueue->mousestate = VISUAL_MOUSE_UP;
+
+	visual_list_set_destroyer (&eventqueue->events, event_list_destroy);
+
+	return eventqueue;
+}
+
+/**
+ * Polls for new events. Looks at the event queue for new events and deletes
+ * them from the queue while loading them into the event argument.
+ *
+ * @param eventqueue Pointer to a VisEventQueue from which new events should be taken.
+ * @param event Pointer to a VisEvent in which the new events should be loaded.
+ *
+ * @return TRUE when events are handled and FALSE when the queue is out of events.
+ */
+int visual_event_queue_poll (VisEventQueue *eventqueue, VisEvent *event)
+{
+	VisEvent *lev;
+	VisListEntry *listentry = NULL;;
+
+	visual_log_return_val_if_fail (eventqueue != NULL, FALSE);
+	visual_log_return_val_if_fail (event != NULL, FALSE);
+
+	if (eventqueue->resizenew == TRUE) {
+		eventqueue->resizenew = FALSE;
+
+		visual_mem_copy (event, &eventqueue->lastresize, sizeof (VisEvent));
+
+		return TRUE;
+	}
+
+	if (eventqueue->eventcount <= 0)
+		return FALSE;
+	
+	lev = visual_list_next (&eventqueue->events, &listentry);
+	visual_mem_copy (event, lev, sizeof (VisEvent));
+
+	visual_object_unref (VISUAL_OBJECT (lev));
+
+	visual_list_delete (&eventqueue->events, &listentry);
+	
+	eventqueue->eventcount--;
+
+	return TRUE;
+}
+
+/**
+ * Adds an event to the event queue. Add new VisEvents into the VisEventQueue.
+ *
+ * @param eventqueue Pointer to the VisEventQueue to which new events are added.
+ * @param event Pointer to a VisEvent that needs to be added to the queue.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_EVENT_QUEUE_NULL or -VISUAL_ERROR_EVENT_NULL
+ *	on failure.
+ */
+int visual_event_queue_add (VisEventQueue *eventqueue, VisEvent *event)
+{
+	visual_log_return_val_if_fail (eventqueue != NULL, -VISUAL_ERROR_EVENT_QUEUE_NULL);
+	visual_log_return_val_if_fail (event != NULL, -VISUAL_ERROR_EVENT_NULL);
+
+	/* We've got way too much on the queue, not adding events, the important
+	 * resize event got data in the event queue structure that makes sure it gets
+	 * looked at */
+	if (eventqueue->eventcount > VISUAL_EVENT_MAXEVENTS) {
+		visual_object_unref (VISUAL_OBJECT (event));
+
+		return -1;
+	}
+
+	visual_list_add (&eventqueue->events, event);
+
+	eventqueue->eventcount++;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Adds a new keyboard event to the event queue. By giving keyboard state information
+ * a new VisEvent will be created and added to the event queue.
+ *
+ * @param eventqueue Pointer to the VisEventQueue to which new events are added.
+ * @param keysym A keysym from the VisKey enumerate to set the key to which the event relates.
+ * @param keymod Key modifier information from the VisKeyMod enumerate.
+ * @param state Contains information about whatever the key is down or up.
+ *
+ * return VISUAL_OK on succes -VISUAL_ERROR_EVENT_QUEUE_NULL, -VISUAL_ERROR_EVENT_NULL or error values
+ *	returned by visual_event_queue_add on failure.
+ */
+int visual_event_queue_add_keyboard (VisEventQueue *eventqueue, VisKey keysym, int keymod, VisKeyState state)
+{
+	VisEvent *event;
+
+	visual_log_return_val_if_fail (eventqueue != NULL, -VISUAL_ERROR_EVENT_QUEUE_NULL);
+
+	event = visual_event_new ();
+	if (event == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL,
+				"Cannot create a new VisEvent structure");
+
+		return -VISUAL_ERROR_EVENT_NULL;
+	}
+	
+	/* FIXME name to VISUAL_KEYB_DOWN and KEYB_UP */
+	if (state == VISUAL_KEY_DOWN)
+		event->type = VISUAL_EVENT_KEYDOWN;
+	else
+		event->type = VISUAL_EVENT_KEYUP;
+
+	event->keyboard.type = event->type;
+	event->keyboard.keysym.sym = keysym;
+	event->keyboard.keysym.mod = keymod;
+
+	return visual_event_queue_add (eventqueue, event);
+}
+
+/**
+ * Adds a new mouse movement event to the event queue. By giving absolute X and Y coordinates
+ * for the mouse a new VisEvent will be created and added to the event queue.
+ *
+ * @param eventqueue Pointer to the VisEventQueue to which new events are added.
+ * @param x Absolute X value for the mouse location.
+ * @param y Absolute Y value for the mouse location.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_EVENT_QUEUE_NULL or error values returned by
+ *	visual_event_queue_add () on failure.
+ */
+int visual_event_queue_add_mousemotion (VisEventQueue *eventqueue, int x, int y)
+{
+	VisEvent *event;
+
+	visual_log_return_val_if_fail (eventqueue != NULL, -VISUAL_ERROR_EVENT_QUEUE_NULL);
+
+	event = visual_event_new ();
+
+	event->type = VISUAL_EVENT_MOUSEMOTION;
+
+	event->mousemotion.type = event->type;
+
+	event->mousemotion.state = eventqueue->mousestate;
+	event->mousemotion.x = x;
+	event->mousemotion.y = y;
+
+	event->mousemotion.xrel = x - eventqueue->mousex;
+	event->mousemotion.yrel = y - eventqueue->mousey;
+
+	eventqueue->mousex = x;
+	eventqueue->mousey = y;
+
+	return visual_event_queue_add (eventqueue, event);;
+}
+
+/**
+ * Adds a new mouse button event to the event queue. By giving a mouse button index number and
+ * a mouse button key state a new VisEvent will be created and added to the event queue.
+ *
+ * @param eventqueue Pointer to the VisEventQueue to which new events are added.
+ * @param button Index that indicates to which mouse button the state relates.
+ * @param state Contains information about whatever the button is down or up
+ * @param x Absolute X value for the mouse location.
+ * @param y Absolute Y value for the mouse location.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_EVENT_QUEUE_NULL or error values returned by
+ *	visual_event_queue_add () on failure.
+ */
+int visual_event_queue_add_mousebutton (VisEventQueue *eventqueue, int button, VisMouseState state, int x, int y)
+{
+	VisEvent *event;
+
+	visual_log_return_val_if_fail (eventqueue != NULL, -VISUAL_ERROR_EVENT_QUEUE_NULL);
+
+	event = visual_event_new ();
+
+	if (state == VISUAL_MOUSE_DOWN)
+		event->type = VISUAL_EVENT_MOUSEBUTTONDOWN;
+	else
+		event->type = VISUAL_EVENT_MOUSEBUTTONUP;
+
+	event->mousebutton.type = event->type;
+	
+	event->mousebutton.button = button;
+	event->mousebutton.state = state;
+	
+	event->mousebutton.x = x;
+	event->mousebutton.y = y;
+
+	eventqueue->mousestate = state;
+
+	return visual_event_queue_add (eventqueue, event);
+}
+
+/**
+ * Adds a new dimension change event to the event queue. By giving a pointer to
+ * the VisVideo containing all the surface information and new width and height
+ * a new VisEvent will be created and added to the event queue.
+ *
+ * @param eventqueue Pointer to the VisEventQueue to which new events are added.
+ * @param video Pointer to the VisVideo containing all the display information,
+ * 	also used for negotiation so values can change within the VisVideo
+ * 	structure.
+ * @param width The width for the new surface.
+ * @param height The height for the new surface.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_EVENT_QUEUE_NULL on failure.
+ */
+int visual_event_queue_add_resize (VisEventQueue *eventqueue, VisVideo *video, int width, int height)
+{
+	VisEvent *event;
+
+	visual_log_return_val_if_fail (eventqueue != NULL, -VISUAL_ERROR_EVENT_QUEUE_NULL);
+
+	event = &eventqueue->lastresize;
+	
+	event->type = VISUAL_EVENT_RESIZE;
+
+	event->resize.type = event->type;
+
+	event->resize.video = video;
+	event->resize.width = width;
+	event->resize.height = height;
+
+	eventqueue->resizenew = TRUE;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Adds a new song change event to the event queue. By giving a pointer to the
+ * new VisSongInfo structure a new VisEvent will be created and added to the event queue.
+ *
+ * @param eventqueue Pointer to the VisEventQueue to which new events are added.
+ * @param songinfo Pointer to the VisSongInfo containing all the new song information.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_EVENT_QUEUE_NULL, -VISUAL_ERROR_SONGINFO_NULL
+ * 	or error values returned by visual_event_queue_add () on failure.
+ */
+int visual_event_queue_add_newsong (VisEventQueue *eventqueue, VisSongInfo *songinfo)
+{
+	VisEvent *event;
+
+	visual_log_return_val_if_fail (eventqueue != NULL, -VISUAL_ERROR_EVENT_QUEUE_NULL);
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+
+	event = visual_event_new ();
+
+	event->type = VISUAL_EVENT_NEWSONG;
+
+	event->newsong.type = event->type;
+	event->newsong.songinfo = songinfo;
+
+	return visual_event_queue_add (eventqueue, event);
+}
+
+/**
+ * Adds a new parameter change event to the event queue. By giving the pointer to the
+ * VisParamEntry structure a new VisEvent will be created and added to the event queue.
+ *
+ * @param eventqueue Pointer to the VisEventQueue to which new events are added.
+ * @param param Pointer to the VisParamEntry containing the parameter that has been changed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_EVENT_QUEUE_NULL, -VISUAL_ERROR_PARAM_NULL
+ * 	or error values returned by visual_event_queue_add () on failure.
+ */
+int visual_event_queue_add_param (VisEventQueue *eventqueue, void *param)
+{
+	VisEvent *event;
+
+	visual_log_return_val_if_fail (eventqueue != NULL, -VISUAL_ERROR_EVENT_QUEUE_NULL);
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	event = visual_event_new ();
+	event->type = VISUAL_EVENT_PARAM;
+
+	event->param.type = event->type;
+	event->param.param = param;
+
+	return visual_event_queue_add (eventqueue, event);
+}
+
+/**
+ * Adds a new quit event to the event queue.
+ *
+ * @param eventqueue Pointer to the VisEventQueue to which new events are added.
+ * @param pass_zero_please Might be used in the future, but for now just pass .
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_EVENT_QUEUE_NULL
+ * 	or error values returned by visual_event_queue_add () on failure.
+ */
+int visual_event_queue_add_quit (VisEventQueue *eventqueue, int pass_zero_please)
+{
+	VisEvent *event;
+
+	visual_log_return_val_if_fail (eventqueue != NULL, -VISUAL_ERROR_EVENT_QUEUE_NULL);
+
+	event = visual_event_new ();
+	event->type = VISUAL_EVENT_QUIT;
+
+	event->quit.type = event->type;
+
+	return visual_event_queue_add (eventqueue, event);
+}
+
+/**
+ * Adds a new visibility event to the event queue.
+ *
+ * @param eventqueue Pointer to the VisEventQueue to which new events are added.
+ * @param is_visible TRUE when visible, FALSE when not visible.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_EVENT_QUEUE_NULL
+ * 	or error values returned by visual_event_queue_add () on failure.
+ */
+int visual_event_queue_add_visibility (VisEventQueue *eventqueue, int is_visible)
+{
+	VisEvent *event;
+
+	visual_log_return_val_if_fail (eventqueue != NULL, -VISUAL_ERROR_EVENT_QUEUE_NULL);
+
+	event = visual_event_new ();
+	event->type = VISUAL_EVENT_VISIBILITY;
+
+	event->visibility.type = event->type;
+	event->visibility.is_visible = is_visible;
+
+	return visual_event_queue_add (eventqueue, event);
+}
+
+/**
+ * Adds a new generic event to the event queue.
+ *
+ * @param eventqueue Pointer to the VisEventQueue to which new events are added.
+ * @param eid ID of the custom event..
+ * @param param_int Integer value for the custom event.
+ * @param param_ptr Pointer to data for the custom event..
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_EVENT_QUEUE_NULL
+ * 	or error values returned by visual_event_queue_add () on failure.
+ */
+
+int visual_event_queue_add_generic (VisEventQueue *eventqueue, int eid, int param_int, void *param_ptr)
+{
+	VisEvent *event;
+
+	visual_log_return_val_if_fail (eventqueue != NULL, -VISUAL_ERROR_EVENT_QUEUE_NULL);
+
+	event = visual_event_new ();
+	event->type = VISUAL_EVENT_GENERIC;
+
+	event->generic.type = event->type;
+	event->generic.event_id = eid;
+	event->generic.data_int = param_int;
+	event->generic.data_ptr = param_ptr;
+
+	return visual_event_queue_add (eventqueue, event);
+}
+
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_event.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,271 @@
+#ifndef _LV_EVENT_H
+#define _LV_EVENT_H
+
+#include <libvisual/lv_songinfo.h>
+#include <libvisual/lv_video.h>
+#include <libvisual/lv_list.h>
+#include <libvisual/lv_keysym.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_EVENT_KEYBOARD(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisEventKeyboard))
+#define VISUAL_EVENT_MOUSEMOTION(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisEventMouseMotion))
+#define VISUAL_EVENT_MOUSEBUTTON(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisEventMouseButton))
+#define VISUAL_EVENT_RESIZE(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisEventResize))
+#define VISUAL_EVENT_NEWSONG(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisEventNewSong))
+#define VISUAL_EVENT_QUIT(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisEventQuit))
+#define VISUAL_EVENT_VISIBILITY(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisEventVisibility))
+#define VISUAL_EVENT_GENERIC(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisEventGeneric))
+#define VISUAL_EVENT_PARAM(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisEventParam))
+#define VISUAL_EVENT(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisEvent))
+#define VISUAL_EVENTQUEUE(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisEventQueue))
+
+/**
+ * Number of events allowed in the queue
+ */
+#define VISUAL_EVENT_MAXEVENTS	256
+
+/**
+ * Used to define what kind of event is emitted by the VisEvent system.
+ */
+typedef enum {
+	VISUAL_EVENT_NOEVENT,		/**< No event. */
+	VISUAL_EVENT_KEYDOWN,		/**< Keyboard key pressed event. */
+	VISUAL_EVENT_KEYUP,		/**< Keyboard key released event. */
+	VISUAL_EVENT_MOUSEMOTION,	/**< Mouse movement event. */
+	VISUAL_EVENT_MOUSEBUTTONDOWN,	/**< Mouse button pressed event. */
+	VISUAL_EVENT_MOUSEBUTTONUP,	/**< Mouse button released event. */
+	VISUAL_EVENT_NEWSONG,		/**< Song change event. */
+	VISUAL_EVENT_RESIZE,		/**< Window dimension change event. */
+	VISUAL_EVENT_PARAM,		/**< Param set event, gets emitted when a parameter has been changed. */
+	VISUAL_EVENT_QUIT,		/**< Quit event, Should get emitted when a program is about to quit. */
+	VISUAL_EVENT_GENERIC,		/**< A Generic event. Libvisual has nothing to do with it, this can be used for custom events. */
+	VISUAL_EVENT_VISIBILITY,	/**< A visibility event. Will be emited by lvdisplay (?) or app itself when window becomes (in)visible */
+
+	VISUAL_EVENT_LAST = 0xffffff,	/**< last event number. Libvisual & friends will never use ids greater than this */
+} VisEventType;
+
+/**
+ * Used to define key states within the VisEvent system.
+ */
+typedef enum {
+	VISUAL_KEY_DOWN,		/**< Key is pressed. */
+	VISUAL_KEY_UP			/**< Key is released. */
+} VisKeyState;
+
+/**
+ * Used to define mouse button states within the VisEvent system.
+ */
+typedef enum {
+	VISUAL_MOUSE_DOWN,		/**< Mouse button is pressed. */
+	VISUAL_MOUSE_UP			/**< Mouse button is released. */
+} VisMouseState;
+
+
+typedef struct _VisEventKeyboard VisEventKeyboard;
+typedef struct _VisEventMouseMotion VisEventMouseMotion;
+typedef struct _VisEventMouseButton VisEventMouseButton;
+typedef struct _VisEventResize VisEventResize;
+typedef struct _VisEventNewSong VisEventNewSong;
+typedef struct _VisEventQuit VisEventQuit;
+typedef struct _VisEventVisibility VisEventVisibility;
+typedef struct _VisEventGeneric VisEventGeneric;
+typedef struct _VisEventParam VisEventParam;
+typedef union _VisEvent VisEvent;
+typedef struct _VisEventQueue VisEventQueue;
+
+/**
+ * Keyboard event data structure.
+ *
+ * Contains information about keyboard events.
+ *
+ * @see visual_event_queue_add_keyboard
+ */
+struct _VisEventKeyboard {
+	VisObject	object;		/**< The VisObject data. */
+	VisEventType	type;		/**< Event type of the event being emitted */
+	VisKeySym	keysym;		/**< A keysym entry that contains which key had an
+					  * event and information about modifier keys. */
+};
+
+/**
+ * Mouse movement event data structure.
+ *
+ * Contains information about mouse movement events.
+ *
+ * @see visual_event_queue_add_mousemotion
+ */
+struct _VisEventMouseMotion {
+	VisObject	object;		/**< The VisObject data. */
+	VisEventType	type;		/**< Event type of the event being emitted. */
+	VisMouseState	state;		/**< Mouse button state. */
+	int		x;		/**< The absolute mouse X value, where 0 is left of screen. */
+	int		y;		/**< The absolute mouse Y value. where 0 is top of screen. */
+	int		xrel;		/**< Relative X movement to the previous location. */
+	int		yrel;		/**< Relative Y movement to the previous location. */
+};
+
+/**
+ * Mouse button event data structure.
+ *
+ * Contains information about mouse button events.
+ *
+ * @see visual_event_queue_add_mousebutton
+ */
+struct _VisEventMouseButton {
+	VisObject	object;		/**< The VisObject data. */
+	VisEventType	type;		/**< Event type of the event being emitted. */
+	VisMouseState	state;		/**< Mouse button state. */
+	int		button;		/**< The button the state relates to. */
+	int		x;		/**< The absolute mouse X value. */
+	int		y;		/**< The absolute mouse Y value. */
+};
+
+/**
+ * Dimension change event data structure.
+ *
+ * Contains information about screen dimension and depth changes.
+ *
+ * @see visual_event_queue_add_resize
+ */
+struct _VisEventResize {
+	VisObject	 object;	/**< The VisObject data. */
+	VisEventType	 type;		/**< Event type of the event being emitted. */
+	VisVideo	*video;		/**< Pointer to the VisVideo structure containing all the screen information. */
+	int		 width;		/**< Width of the surface. */
+	int		 height;	/**< Height of the surface. */
+};
+
+/**
+ * Song change event data structure.
+ *
+ * Contains information about song changes.
+ *
+ * @see visual_event_queue_add_newsong
+ */
+struct _VisEventNewSong {
+	VisObject	 object;	/**< The VisObject data. */
+	VisEventType	 type;		/**< Event type of the event being emitted. */
+	VisSongInfo	*songinfo;	/**< Pointer to the VisSongInfo structure containing all the information about
+					 * the new song. */
+};
+
+/**
+ * Quit event data structure.
+ *
+ * Contains quit request.
+ *
+ * @see visual_event_queue_add_quit
+ */
+struct _VisEventQuit {
+	VisObject	 object;	/**< The VisObject data. */
+	VisEventType	 type;		/**< Event type of the event being emitted. */
+	int		 dummy;		/**< some day may contain a request urgency: quit NOW or schedule quit. */
+};
+
+/**
+ * Visibility event data structure.
+ *
+ * Contains window's new visibility value.
+ *
+ * @see visual_event_queue_add_visibiity
+ */
+struct _VisEventVisibility {
+	VisObject	 object;	/**< The VisObject data. */
+	VisEventType	 type;		/**< Event type of the event being emitted. */
+	int		 dummy;		/**< Some day will contain window ID. very OS-specific. maybe use indices ? */
+	int		 is_visible;	/**< Set TRUE or FALSE to indicate visibility. */
+};
+
+/**
+ * Generic event data structure.
+ *
+ * Contains pointer to some struct.
+ *
+ * @see visual_event_queue_add_generic
+ */
+struct _VisEventGeneric {
+	VisObject	 object;	/**< The VisObject data. */
+	VisEventType	 type;		/**< Event type of the event being emitted. */
+	int		 event_id;	/**< some event id. */
+	int		 data_int;	/**< Data in the form of an integer. */
+	void		*data_ptr;	/**< More advanced generic events can use a pointer. */
+};
+
+/**
+ * Param change event data structure.
+ *
+ * Contains information about parameter changes.
+ *
+ * @see visual_event_queue_add_param
+ */
+struct _VisEventParam {
+	VisObject	 object;	/**< The VisObject data. */
+	VisEventType	 type;		/**< Event type of the event being emitted. */
+	/* FiXME: Having VisEventParam here creates a circulair depency in lv_event.h and lv_param.h */
+	void		*param;		/**< The parameter entry which has been changed. */
+};
+
+/**
+ * The main event data structure.
+ * 
+ * All events are encapsulated using the VisEvent structure.
+ *
+ * @see visual_event_new
+ */
+union _VisEvent {
+	VisObject		object;		/**< The VisObject data. */
+	VisEventType		type;		/**< Event type of the event being emitted. */
+	VisEventKeyboard	keyboard;	/**< Keyboard event. */
+	VisEventMouseMotion	mousemotion;	/**< Mouse movement event. */
+	VisEventMouseButton	mousebutton;	/**< Mouse button event. */
+	VisEventResize		resize;		/**< Dimension change event. */
+	VisEventNewSong		newsong;	/**< Song change event. */
+	VisEventQuit		quit;		/**< Quit event. */
+	VisEventVisibility	visibility;	/**< Plugin visible event. */
+	VisEventGeneric		generic;	/**< Generic event. */
+	VisEventParam		param;		/**< Param change event. */
+};
+
+/**
+ * The event queue data structure.
+ *
+ * Used to manage events queues and also provides quick access to
+ * high piority data from events.
+ *
+ * @see visual_event_queue_new
+ */
+struct _VisEventQueue {
+	VisObject	 object;	/**< The VisObject data. */
+	VisList		 events;	/**< List of VisEvents in the queue. */
+	VisEvent 	 lastresize;	/**< Last resize event to provide quick access
+					  * to this high piority event. */
+	int		 resizenew;	/**< Flag that is set when there is a new resize event. */
+	int		 eventcount;	/**< Contains the number of events in queue. */
+
+	int		 mousex;	/**< Current absolute mouse X value. */
+	int		 mousey;	/**< Current absolute mouse Y value. */
+	VisMouseState	 mousestate;	/**< Current mouse button state. */
+};
+
+VisEvent *visual_event_new (void);
+VisEventQueue *visual_event_queue_new (void);
+int visual_event_queue_poll (VisEventQueue *eventqueue, VisEvent *event);
+int visual_event_queue_add (VisEventQueue *eventqueue, VisEvent *event);
+int visual_event_queue_add_keyboard (VisEventQueue *eventqueue, VisKey keysym, int keymod, VisKeyState state);
+int visual_event_queue_add_mousemotion (VisEventQueue *eventqueue, int x, int y);
+int visual_event_queue_add_mousebutton (VisEventQueue *eventqueue, int button, VisMouseState state, int x, int y);
+int visual_event_queue_add_resize (VisEventQueue *eventqueue, VisVideo *video, int width, int height);
+int visual_event_queue_add_newsong (VisEventQueue *eventqueue, VisSongInfo *songinfo);
+int visual_event_queue_add_param (VisEventQueue *eventqueue, void *param);
+int visual_event_queue_add_quit (VisEventQueue *eventqueue, int pass_zero_please);
+int visual_event_queue_add_visibility (VisEventQueue *eventqueue, int is_visible);
+int visual_event_queue_add_generic (VisEventQueue *eventqueue, int eid, int param_int, void *param_ptr);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_EVENT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_fft.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,300 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Iterative FFT implementation found in this file is
+ * Copyright (C) 1999 Richard Boulton <richard@tartarus.org>
+ * Richard gave permission to relicense the FFT code under the LGPL.
+ * 
+ * Authors: Richard Boulton <richard@tartarus.org>
+ * 	    Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * TODO
+ * Remove compiling in of VISUAL_FFT_BUFFER_SIZE?  (Might slow things down, but would
+ * be nice to be able to change size at runtime.)
+ * Finish making / checking thread-safety.
+ * More optimisations.
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#ifndef PI
+ #ifdef M_PI
+  #define PI M_PI
+ #else
+  #define PI            3.14159265358979323846  /* pi */
+ #endif
+#endif
+
+#include "lv_fft.h"
+
+static void _lv_fft_prepare (const int16_t *input, float * re, float * im);
+static void _lv_fft_calculate (float * re, float * im);
+static void _lv_fft_output (const float *re, const float *im, float *output);
+static int _reverseBits (unsigned int initial);
+
+/* #################### */
+/* # Global variables # */
+/* #################### */
+
+/* Table to speed up bit reverse copy */
+static unsigned int bitReverse[VISUAL_FFT_BUFFER_SIZE];
+
+/* The next two tables could be made to use less space in memory, since they
+ * overlap hugely, but hey. */
+static float sintable[VISUAL_FFT_BUFFER_SIZE / 2];
+static float costable[VISUAL_FFT_BUFFER_SIZE / 2];
+
+/* --------- */
+/* FFT stuff */
+/* --------- */
+
+/*
+ * Initialisation routine - sets up tables and space to work in.
+ * Returns a pointer to internal state, to be used when performing calls.
+ * On error, returns NULL.
+ * The pointer should be freed when it is finished with, by fft_close().
+ */
+
+/**
+ * @defgroup VisFFT VisFFT
+ * @{
+ */
+
+/**
+ * Private function that creates and initialize a new VisFFTState that is
+ * used by the Fast Fourier Transform engine.
+ *
+ * @return A newly created VisFFTState to be used for the FFT engine
+ */
+VisFFTState *visual_fft_init ()
+{
+	VisFFTState *state;
+	unsigned int i;
+
+	state = visual_mem_new0 (VisFFTState, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (state), TRUE, NULL);
+
+	if (state == NULL)
+		return NULL;
+
+	for (i = 0; i < VISUAL_FFT_BUFFER_SIZE; i++) {
+		bitReverse[i] = _reverseBits (i);
+	}
+	
+	for (i = 0; i < VISUAL_FFT_BUFFER_SIZE / 2; i++) {
+		float j = 2 * PI * i / VISUAL_FFT_BUFFER_SIZE;
+		costable[i] = cos (j);
+		sintable[i] = sin (j);
+	}
+
+	return state;
+}
+
+/*
+ * Do all the steps of the FFT, taking as input sound data (as described in
+ * sound.h) and returning the intensities of each frequency as floats in the
+ * range 0 to ((VISUAL_FFT_BUFFER_SIZE / 2) * 32768) ^ 2
+ *
+ * FIXME - the above range assumes no frequencies present have an amplitude
+ * larger than that of the sample variation.  But this is false: we could have
+ * a wave such that its maximums are always between samples, and it's just
+ * inside the representable range at the places samples get taken.
+ * Question: what _is_ the maximum value possible.  Twice that value?  Root
+ * two times that value?  Hmmm.  Think it depends on the frequency, too.
+ *
+ * The input array is assumed to have VISUAL_FFT_BUFFER_SIZE elements,
+ * and the output array is assumed to have (VISUAL_FFT_BUFFER_SIZE / 2 + 1) elements.
+ * state is a (non-NULL) pointer returned by fft_init.
+ */
+
+/**
+ * Private function to perform a FFT calculation which is used within
+ * libvisual it's audio core.
+ *
+ * @param input Sample data which need to be FFT analyzed.
+ * @param output FFT analyse output.
+ * @param state Contains the FFT context needed to run the FFT calculation.
+ */
+void visual_fft_perform (int16_t *input, float *output, VisFFTState *state)
+{
+	/* Convert data from sound format to be ready for FFT */
+	_lv_fft_prepare (input, state->real, state->imag);
+
+	/* Do the actual FFT */
+	_lv_fft_calculate (state->real, state->imag);
+
+	/* Convert the FFT output into intensities */
+	_lv_fft_output (state->real, state->imag, output);
+}
+
+/* ########################### */
+/* # Locally called routines # */
+/* ########################### */
+
+/**
+ * @}
+ */
+
+/*
+ * Prepare data to perform a FFT on
+ */
+static void _lv_fft_prepare (const int16_t *input, float * re, float * im)
+{
+	unsigned int i;
+	float *realptr = re;
+	float *imagptr = im;
+
+	/* Get input, in reverse bit order */
+	for (i = 0; i < VISUAL_FFT_BUFFER_SIZE; i++) {
+		*realptr++ = input[bitReverse[i]];
+		*imagptr++ = 0;
+	}
+}
+
+/*
+ * Take result of a FFT and calculate the intensities of each frequency
+ * Note: only produces half as many data points as the input had.
+ * This is roughly a consequence of the Nyquist sampling theorm thingy.
+ * (FIXME - make this comment better, and helpful.)
+ * 
+ * The two divisions by 4 are also a consequence of this: the contributions
+ * returned for each frequency are split into two parts, one at i in the
+ * table, and the other at VISUAL_FFT_BUFFER_SIZE - i, except for i = 0 and
+ * VISUAL_FFT_BUFFER_SIZE which would otherwise get float (and then 4* when squared)
+ * the contributions.
+ */
+static void _lv_fft_output (const float * re, const float * im, float *output)
+{
+	float *outputptr = output;
+	const float *realptr = re;
+	const float *imagptr = im;
+	float *endptr = output + VISUAL_FFT_BUFFER_SIZE / 2;
+
+#ifdef DEBUG
+	unsigned int i, j;
+#endif
+
+	while (outputptr <= endptr) {
+		*outputptr = (*realptr * *realptr) + (*imagptr * *imagptr);
+		outputptr++; realptr++; imagptr++;
+	}
+	/* Do divisions to keep the constant and highest frequency terms in scale
+	 * with the other terms. */
+	*output /= 4;
+	*endptr /= 4;
+
+#ifdef DEBUG
+	printf ("Recalculated input:\n");
+	for(i = 0; i < VISUAL_FFT_BUFFER_SIZE; i++) {
+		float val_real = 0;
+		float val_imag = 0;
+		for (j = 0; j < VISUAL_FFT_BUFFER_SIZE; j++) {
+			float fact_real = cos (- 2 * j * i * PI / VISUAL_FFT_BUFFER_SIZE);
+			float fact_imag = sin (- 2 * j * i * PI / VISUAL_FFT_BUFFER_SIZE);
+			val_real += fact_real * re[j] - fact_imag * im[j];
+			val_imag += fact_real * im[j] + fact_imag * re[j];
+		}
+
+		printf ("%5d = %8f + i * %8f\n", i,
+				val_real / VISUAL_FFT_BUFFER_SIZE,
+				val_imag / VISUAL_FFT_BUFFER_SIZE);
+	}
+	printf ("\n");
+#endif
+}
+
+/*
+ * Actually perform the FFT
+ */
+static void _lv_fft_calculate (float * re, float * im)
+{
+	unsigned int i, j, k;
+	unsigned int exchanges;
+	float fact_real, fact_imag;
+	float tmp_real, tmp_imag;
+	unsigned int factfact;
+
+	/* Set up some variables to reduce calculation in the loops */
+	exchanges = 1;
+	factfact = VISUAL_FFT_BUFFER_SIZE / 2;
+
+	/* Loop through the divide and conquer steps */
+	for (i = VISUAL_FFT_BUFFER_SIZE_LOG; i != 0; i--) {
+		/* In this step, we have 2 ^ (i - 1) exchange groups, each with
+		 * 2 ^ (VISUAL_FFT_BUFFER_SIZE_LOG - i) exchanges
+		 */
+		/* Loop through the exchanges in a group */
+		for (j = 0; j != exchanges; j++) {
+			/* Work out factor for this exchange
+			 * factor ^ (exchanges) = -1
+			 * So, real = cos(j * PI / exchanges),
+			 *     imag = sin(j * PI / exchanges)
+			 */
+			fact_real = costable[j * factfact];
+			fact_imag = sintable[j * factfact];
+
+			/* Loop through all the exchange groups */
+			for (k = j; k < VISUAL_FFT_BUFFER_SIZE; k += exchanges << 1) {
+				int k1 = k + exchanges;
+				/* newval[k]  := val[k] + factor * val[k1]
+				 * newval[k1] := val[k] - factor * val[k1]
+				 **/
+#ifdef DEBUG
+				printf("%d %d %d\n", i,j,k);
+				printf("Exchange %d with %d\n", k, k1);
+				printf("Factor %9f + i * %8f\n", fact_real, fact_imag);
+#endif
+				/* FIXME - potential scope for more optimization here? */
+				tmp_real = fact_real * re[k1] - fact_imag * im[k1];
+				tmp_imag = fact_real * im[k1] + fact_imag * re[k1];
+				re[k1] = re[k] - tmp_real;
+				im[k1] = im[k] - tmp_imag;
+				re[k]  += tmp_real;
+				im[k]  += tmp_imag;
+#ifdef DEBUG
+				for (k1 = 0; k1 < VISUAL_FFT_BUFFER_SIZE; k1++) {
+					printf("%5d = %8f + i * %8f\n", k1, real[k1], imag[k1]);
+				}
+#endif
+			}
+		}
+
+		exchanges <<= 1;
+		factfact >>= 1;
+	}
+}
+
+static int _reverseBits (unsigned int initial)
+{
+	unsigned int reversed = 0, loop;
+
+	for (loop = 0; loop < VISUAL_FFT_BUFFER_SIZE_LOG; loop++) {
+		reversed <<= 1;
+		reversed += (initial & 1);
+		initial >>= 1;
+	}
+
+	return reversed;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_fft.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,69 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Iterative FFT implementation found in this file is
+ * Copyright (C) 1999 Richard Boulton <richard@tartarus.org>
+ * Richard gave permission to relicense the FFT code under the LGPL.
+ * 
+ * Authors: Richard Boulton <richard@tartarus.org>
+ * 	    Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_FFT_H
+#define _LV_FFT_H
+
+#include <libvisual/lv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_FFTSTATE(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisFFTState))
+
+/**
+ * Private FFT define that contains the log size.
+ */
+#define VISUAL_FFT_BUFFER_SIZE_LOG 9
+
+/**
+ * Private FFT define that contains the buffer size.
+ */
+#define VISUAL_FFT_BUFFER_SIZE (1 << VISUAL_FFT_BUFFER_SIZE_LOG)
+
+typedef struct _VisFFTState VisFFTState;
+
+/**
+ * Private structure to contain Fast Fourier Transform states in.
+ */
+struct _VisFFTState {
+	VisObject	object;				/**< The VisObject data. */
+	/* Temporary data stores to perform FFT in. */
+	float		real[VISUAL_FFT_BUFFER_SIZE];	/**< Private data that is used by the FFT engine. */
+	float		imag[VISUAL_FFT_BUFFER_SIZE];	/**< Private data that is used by the FFT engine. */
+};
+
+VisFFTState *visual_fft_init (void);
+void visual_fft_perform (int16_t *input, float *output, VisFFTState *state);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_FFT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_input.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,250 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lv_list.h"
+#include "lv_input.h"
+
+extern VisList *__lv_plugins_input;
+
+static int input_dtor (VisObject *object);
+
+static VisInputPlugin *get_input_plugin (VisInput *input);
+
+static int input_dtor (VisObject *object)
+{
+	VisInput *input = VISUAL_INPUT (object);
+
+	if (input->plugin != NULL)
+		visual_plugin_unload (input->plugin);
+
+	if (input->audio != NULL)
+		visual_object_unref (VISUAL_OBJECT (input->audio));
+
+	input->plugin = NULL;
+	input->audio = NULL;
+
+	return VISUAL_OK;
+}
+
+static VisInputPlugin *get_input_plugin (VisInput *input)
+{
+	VisInputPlugin *inplugin;
+
+	visual_log_return_val_if_fail (input != NULL, NULL);
+	visual_log_return_val_if_fail (input->plugin != NULL, NULL);
+
+	inplugin = VISUAL_PLUGIN_INPUT (input->plugin->info->plugin);
+
+	return inplugin;
+}
+
+/**
+ * @defgroup VisInput VisInput
+ * @{
+ */
+
+/**
+ * Gives the encapsulated VisPluginData from a VisInput.
+ *
+ * @param input Pointer of a VisInput of which the VisPluginData needs to be returned.
+ *
+ * @return VisPluginData that is encapsulated in the VisInput, possibly NULL.
+ */
+VisPluginData *visual_input_get_plugin (VisInput *input)
+{
+	        return input->plugin;
+}
+
+/**
+ * Gives a list of input plugins in the current plugin registry.
+ *
+ * @return An VisList of VisPluginRef's containing the input plugins in the plugin registry.
+ */
+VisList *visual_input_get_list ()
+{
+	return __lv_plugins_input;
+}
+
+/**
+ * Gives the next input plugin based on the name of a plugin.
+ *
+ * @see visual_input_get_prev_by_name
+ *
+ * @param name The name of the current plugin, or NULL to get the first.
+ *
+ * @return The name of the next plugin within the list.
+ */
+const char *visual_input_get_next_by_name (const char *name)
+{
+	return visual_plugin_get_next_by_name (visual_input_get_list (), name);
+}
+
+/**
+ * Gives the previous input plugin based on the name of a plugin.
+ *
+ * @see visual_input_get_next_by_name
+ *
+ * @param name The name of the current plugin. or NULL to get the last.
+ *
+ * @return The name of the previous plugin within the list.
+ */
+const char *visual_input_get_prev_by_name (const char *name)
+{
+	return visual_plugin_get_prev_by_name (visual_input_get_list (), name);
+}
+
+
+/**
+ * Checks if the input plugin is in the registry, based on it's name.
+ *
+ * @param name The name of the plugin that needs to be checked.
+ *
+ * @return TRUE if found, else FALSE.
+ */
+int visual_input_valid_by_name (const char *name)
+{
+	if (visual_plugin_find (visual_input_get_list (), name) == NULL)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+/**
+ * Creates a new VisInput from name, the plugin will be loaded but won't be realized.
+ *
+ * @param inputname
+ * 	The name of the plugin to load, or NULL to simply allocate a new
+ * 	input.
+ *
+ * @return A newly allocated VisInput, optionally containing a loaded plugin. Or NULL on failure.
+ */
+VisInput *visual_input_new (const char *inputname)
+{
+	VisInput *input;
+	VisPluginRef *ref;
+
+//	visual_log_return_val_if_fail (__lv_plugins_input != NULL && inputname == NULL, NULL);
+
+	if (__lv_plugins_input == NULL && inputname != NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "the plugin list is NULL");
+		return NULL;
+	}
+	
+	input = visual_mem_new0 (VisInput, 1);
+	
+	input->audio = visual_audio_new ();
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (input), TRUE, input_dtor);
+
+	if (inputname == NULL)
+		return input;
+	
+	ref = visual_plugin_find (__lv_plugins_input, inputname);
+	
+	input->plugin = visual_plugin_load (ref);
+
+	return input;
+}
+
+/**
+ * Realize the VisInput. This also calls the plugin init function.
+ * 
+ * @param input Pointer to a VisInput that needs to be realized.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_INPUT_NULL or error values returned by
+ *	visual_plugin_realize () on failure.
+ */
+int visual_input_realize (VisInput *input)
+{
+	visual_log_return_val_if_fail (input != NULL, -VISUAL_ERROR_INPUT_NULL);
+
+	if (input->plugin != NULL && input->callback == NULL)
+		return visual_plugin_realize (input->plugin);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets a callback function for VisInput. Callback functions can be used instead of plugins. Using
+ * a callback function you can implement an in app PCM data upload function which is like the
+ * upload callback that is used for input plugins.
+ *
+ * @param input Pointer to a VisInput that to which a callback needs to be set.
+ * @param callback The in app callback function that should be used instead of a plugin.
+ * @param priv A private that can be read within the callback function.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_INPUT_NULL on failure.
+ */
+int visual_input_set_callback (VisInput *input, VisInputUploadCallbackFunc callback, void *priv)
+{
+	visual_log_return_val_if_fail (input != NULL, -VISUAL_ERROR_INPUT_NULL);
+
+	input->callback = callback;
+	visual_object_set_private (VISUAL_OBJECT (input), priv);
+
+	return VISUAL_OK;
+}
+
+/**
+ * This is called to run a VisInput. This function will call the plugin to upload it's samples and run it
+ * through the visual_audio_analyze function. If a callback is set it will use the callback instead of
+ * the plugin.
+ *
+ * @param input A pointer to a VisInput that needs to be runned.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_INPUT_NULL or -VISUAL_ERROR_INPUT_PLUGIN_NULL on failure.
+ */
+int visual_input_run (VisInput *input)
+{
+	VisInputPlugin *inplugin;
+
+	visual_log_return_val_if_fail (input != NULL, -VISUAL_ERROR_INPUT_NULL);
+
+	if (input->callback == NULL) {
+		inplugin = get_input_plugin (input);
+
+		if (inplugin == NULL) {
+			visual_log (VISUAL_LOG_CRITICAL, "The input plugin is not loaded correctly.");
+		
+			return -VISUAL_ERROR_INPUT_PLUGIN_NULL;
+		}
+		
+		inplugin->upload (input->plugin, input->audio);
+	} else
+		input->callback (input, input->audio, visual_object_get_private (VISUAL_OBJECT (input)));
+
+	visual_audio_analyze (input->audio);
+
+	return VISUAL_OK;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_input.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,96 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_INPUT_H
+#define _LV_INPUT_H
+
+#include <libvisual/lv_audio.h>
+#include <libvisual/lv_plugin.h>
+#include <libvisual/lv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_INPUT(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisInput))
+
+typedef struct _VisInput VisInput;
+
+/**
+ * Callback function that is set using visual_input_set_callback should use this signature.
+ *
+ * @see visual_input_set_callback
+ *
+ * @arg input Pointer to the VisInput structure.
+ *
+ * @arg audio Pointer to the VisAudio containing all the audio information, and in which
+ * data needs to be set within the callback.
+ *
+ * @arg priv Private field to be used by the client. The library will never touch this.
+ */
+typedef int (*VisInputUploadCallbackFunc)(VisInput *input, VisAudio *audio, void *priv);
+
+/**
+ * The VisInput structure encapsulates the input plugin and provides
+ * abstract interfaces to the input. The VisInput system provides
+ * PCM data to the visualisation elements of libvisual. This can be done
+ * through both plugins and callback functions.
+ *
+ * Members in the structure shouldn't be accessed directly but instead
+ * it's adviced to use the methods provided.
+ *
+ * @see visual_input_new
+ */ 
+struct _VisInput {
+	VisObject			 object;	/**< The VisObject data. */
+
+	VisPluginData			*plugin;	/**< Pointer to the plugin itself. */
+	VisAudio			*audio;		/**< Pointer to the VisAudio structure
+							  * that contains the audio analyse
+							  * results.
+							  * @see visual_audio_analyse */
+	VisInputUploadCallbackFunc	 callback;	/**< Callback function when a callback
+							  * is used instead of a plugin. */
+};
+
+/* prototypes */
+VisPluginData *visual_input_get_plugin (VisInput *input);
+
+VisList *visual_input_get_list (void);
+const char *visual_input_get_next_by_name (const char *name);
+const char *visual_input_get_prev_by_name (const char *name);
+int visual_input_valid_by_name (const char *name);
+
+VisInput *visual_input_new (const char *inputname);
+
+int visual_input_realize (VisInput *input);
+
+int visual_input_set_callback (VisInput *input, VisInputUploadCallbackFunc callback, void *priv);
+
+int visual_input_run (VisInput *input);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_INPUT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_keysym.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,235 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_KEYSYM_H
+#define _LV_KEYSYM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Enumerate values used within the libvisual event system for keyboard events.
+ *
+ * The table is closely modelled after that of SDL and the SDL1.2 
+ * SDLK defines can be directly translated to those of libvisual, however
+ * some keys are left out, but these are rarely or never used.
+ *
+ * The basic keys are also mapped as in the ASCII table so basic
+ * keyboard support is easy to implement within a libvisual client.
+ *
+ * @see visual_event_queue_add_keyboard
+ */
+typedef enum {
+	VKEY_UNKNOWN		= 0,
+	VKEY_FIRST		= 0,
+	VKEY_BACKSPACE		= 8,
+	VKEY_TAB		= 9,
+	VKEY_CLEAR		= 12,
+	VKEY_RETURN		= 13,
+	VKEY_PAUSE		= 19,
+	VKEY_ESCAPE		= 27,
+	VKEY_SPACE		= 32,
+	VKEY_EXCLAIM		= 33,
+	VKEY_QUOTEDBL		= 34,
+	VKEY_HASH		= 35,
+	VKEY_DOLLAR		= 36,
+	VKEY_AMPERSAND		= 38,
+	VKEY_QUOTE		= 39,
+	VKEY_LEFTPAREN		= 40,
+	VKEY_RIGHTPAREN		= 41,
+	VKEY_ASTERISK		= 42,
+	VKEY_PLUS		= 43,
+	VKEY_COMMA		= 44,
+	VKEY_MINUS		= 45,
+	VKEY_PERIOD		= 46,
+	VKEY_SLASH		= 47,
+	VKEY_0			= 48,
+	VKEY_1			= 49,
+	VKEY_2			= 50,
+	VKEY_3			= 51,
+	VKEY_4			= 52,
+	VKEY_5			= 53,
+	VKEY_6			= 54,
+	VKEY_7			= 55,
+	VKEY_8			= 56,
+	VKEY_9			= 57,
+	VKEY_COLON		= 58,
+	VKEY_SEMICOLON		= 59,
+	VKEY_LESS		= 60,
+	VKEY_EQUALS		= 61,
+	VKEY_GREATER		= 62,
+	VKEY_QUESTION		= 63,
+	VKEY_AT			= 64,
+	
+	/* Skip uppercase here because it's done via the VisKeyMod */
+	VKEY_LEFTBRACKET	= 91,
+	VKEY_BACKSLASH		= 92,
+	VKEY_RIGHTBRACKET	= 93,
+	VKEY_CARET		= 94,
+	VKEY_UNDERSCORE		= 95,
+	VKEY_BACKQUOTE		= 96,
+	VKEY_a			= 97,
+	VKEY_b			= 98,
+	VKEY_c			= 99,
+	VKEY_d			= 100,
+	VKEY_e			= 101,
+	VKEY_f			= 102,
+	VKEY_g			= 103,
+	VKEY_h			= 104,
+	VKEY_i			= 105,
+	VKEY_j			= 106,
+	VKEY_k			= 107,
+	VKEY_l			= 108,
+	VKEY_m			= 109,
+	VKEY_n			= 110,
+	VKEY_o			= 111,
+	VKEY_p			= 112,
+	VKEY_q			= 113,
+	VKEY_r			= 114,
+	VKEY_s			= 115,
+	VKEY_t			= 116,
+	VKEY_u			= 117,
+	VKEY_v			= 118,
+	VKEY_w			= 119,
+	VKEY_x			= 120,
+	VKEY_y			= 121,
+	VKEY_z			= 122,
+	VKEY_DELETE		= 127,
+
+	/* Numeric keypad */
+	VKEY_KP0		= 256,
+	VKEY_KP1		= 257,
+	VKEY_KP2		= 258,
+	VKEY_KP3		= 259,
+	VKEY_KP4		= 260,
+	VKEY_KP5		= 261,
+	VKEY_KP6		= 262,
+	VKEY_KP7		= 263,
+	VKEY_KP8		= 264,
+	VKEY_KP9		= 265,
+	VKEY_KP_PERIOD		= 266,
+	VKEY_KP_DIVIDE		= 267,
+	VKEY_KP_MULTIPLY	= 268,
+	VKEY_KP_MINUS		= 269,
+	VKEY_KP_PLUS		= 270,
+	VKEY_KP_ENTER		= 271,
+	VKEY_KP_EQUALS		= 272,
+
+	/* Arrows + Home/End pad */
+	VKEY_UP			= 273,
+	VKEY_DOWN		= 274,
+	VKEY_RIGHT		= 275,
+	VKEY_LEFT		= 276,
+	VKEY_INSERT		= 277,
+	VKEY_HOME		= 278,
+	VKEY_END		= 279,
+	VKEY_PAGEUP		= 280,
+	VKEY_PAGEDOWN		= 281,
+
+	/* Function keys */
+	VKEY_F1			= 282,
+	VKEY_F2			= 283,
+	VKEY_F3			= 284,
+	VKEY_F4			= 285,
+	VKEY_F5			= 286,
+	VKEY_F6			= 287,
+	VKEY_F7			= 288,
+	VKEY_F8			= 289,
+	VKEY_F9			= 290,
+	VKEY_F10		= 291,
+	VKEY_F11		= 292,
+	VKEY_F12		= 293,
+	VKEY_F13		= 294,
+	VKEY_F14		= 295,
+	VKEY_F15		= 296,
+
+	/* Key state modifier keys */
+	VKEY_NUMLOCK		= 300,
+	VKEY_CAPSLOCK		= 301,
+	VKEY_SCROLLOCK		= 302,
+	VKEY_RSHIFT		= 303,
+	VKEY_LSHIFT		= 304,
+	VKEY_RCTRL		= 305,
+	VKEY_LCTRL		= 306,
+	VKEY_RALT		= 307,
+	VKEY_LALT		= 308,
+	VKEY_RMETA		= 309,
+	VKEY_LMETA		= 310,
+	VKEY_LSUPER		= 311,		/* Left "Windows" key */
+	VKEY_RSUPER		= 312,		/* Right "Windows" key */
+	VKEY_MODE		= 313,		/* "Alt Gr" key */
+	VKEY_COMPOSE		= 314,		/* Multi-key compose key */
+
+	/* Miscellaneous function keys */
+	VKEY_HELP		= 315,
+	VKEY_PRINT		= 316,
+	VKEY_SYSREQ		= 317,
+	VKEY_BREAK		= 318,
+	VKEY_MENU		= 319,
+
+	VKEY_LAST
+} VisKey;
+
+/**
+ * Enumerate values used within the libvisual event system to set modifier keys.
+ * 
+ * Values can ben ORred together.
+ *
+ * @see visual_event_queue_add_keyboard
+ */
+typedef enum {
+	VKMOD_NONE	= 0x0000,
+	VKMOD_LSHIFT	= 0x0001,
+	VKMOD_RSHIFT	= 0x0002,
+	VKMOD_LCTRL	= 0x0040,
+	VKMOD_RCTRL	= 0x0080,
+	VKMOD_LALT	= 0x0100,
+	VKMOD_RALT	= 0x0200,
+	VKMOD_LMETA	= 0x0400,
+	VKMOD_RMETA	= 0x0800,
+	VKMOD_NUM	= 0x1000,
+	VKMOD_CAPS	= 0x2000,
+	VKMOD_MODE	= 0x4000,
+} VisKeyMod;
+
+#define VKMOD_CTRL	(VKMOD_LCTRL  | VKMOD_RCTRL)
+#define VKMOD_SHIFT	(VKMOD_LSHIFT | VKMOD_RSHIFT)
+#define VKMOD_ALT	(VKMOD_LALT   | VKMOD_RALT)
+#define VKMOD_META	(VKMOD_LMETA  | VKMOD_RMETA)
+
+typedef struct _VisKeySym VisKeySym;
+
+/**
+ * Cantains data about the current keyboard state.
+ */
+struct _VisKeySym {
+	VisKey		sym;	/**< Keyboard key to which everything relates. */
+	int		mod;	/**< Modifier vlags, Using key modifiers from the VisKeyMod enumerate. */
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_KEYSYM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_libvisual.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,338 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lvconfig.h"
+#include "lv_plugin.h"
+#include "lv_libvisual.h"
+#include "lv_log.h"
+#include "lv_param.h"
+#include "config.h"
+
+
+/** Set when libvisual is initialized. */
+int __lv_initialized = FALSE;
+/** Set a progname from argv[0] when we're capable of doing so. */
+char *__lv_progname = NULL;
+
+/** Contains the completely plugin registry after initialize. */
+VisList *__lv_plugins = NULL;
+/** Contains all the actor plugins after initialize. */
+VisList *__lv_plugins_actor = NULL;
+/** Contains all the input plugins after initialize. */
+VisList *__lv_plugins_input = NULL;
+/** Contains all the morph plugins after initialize. */
+VisList *__lv_plugins_morph = NULL;
+/** Contains all the transform plugins after initialize. */
+VisList *__lv_plugins_transform = NULL;
+
+/** The global params container */
+VisParamContainer *__lv_paramcontainer = NULL;
+
+/** The userinterface for the global params */
+VisUIWidget *__lv_userinterface = NULL;
+
+/** Contains the number of plugin registry paths. */
+int __lv_plugpath_cnt = 0;
+/** Char ** list of all the plugin paths. */
+char **__lv_plugpaths = NULL;
+
+
+static int init_params (VisParamContainer *paramcontainer);
+static VisUIWidget *make_userinterface (void);
+
+static int init_params (VisParamContainer *paramcontainer)
+{
+	VisParamEntry *param;
+
+	visual_log_return_val_if_fail (paramcontainer != NULL, -1);
+
+	/* Initialize all the global parameters here */
+
+	/* Song information parameters */
+	/* Show songinfo */
+	param = visual_param_entry_new ("songinfo show");
+	visual_param_entry_set_integer (param, 1);
+	visual_param_container_add (paramcontainer, param);
+
+	/* Songinfo timeout, in seconds */
+	param = visual_param_entry_new ("songinfo timeout");
+	visual_param_entry_set_integer (param, 5);
+	visual_param_container_add (paramcontainer, param);
+	
+	/* 
+	 * Show songinfo in plugins, plugins that optionally show song
+	 * info should query this parameter
+	 */
+	param = visual_param_entry_new ("songinfo in plugin");
+	visual_param_entry_set_integer (param, 1);
+	visual_param_container_add (paramcontainer, param);
+
+	return 0;
+}
+
+static VisUIWidget *make_userinterface ()
+{
+	VisUIWidget *vbox;
+	VisUIWidget *hbox;
+	VisUIWidget *label1;
+	VisUIWidget *label2;
+	VisUIWidget *checkbox1;
+	VisUIWidget *checkbox2;
+	VisUIWidget *numeric;
+
+	vbox = visual_ui_box_new (VISUAL_ORIENT_TYPE_VERTICAL);
+	hbox = visual_ui_box_new (VISUAL_ORIENT_TYPE_HORIZONTAL);
+	
+	label1 = visual_ui_label_new ("Show info for", FALSE);
+	label2 = visual_ui_label_new ("seconds", FALSE);
+
+	checkbox1 = visual_ui_checkbox_new ("Show song information", TRUE);
+	visual_ui_mutator_set_param (VISUAL_UI_MUTATOR (checkbox1),
+			visual_param_container_get (__lv_paramcontainer, "songinfo show"));
+
+	checkbox2 = visual_ui_checkbox_new ("Show song information in plugins", TRUE);
+	visual_ui_mutator_set_param (VISUAL_UI_MUTATOR (checkbox2),
+			visual_param_container_get (__lv_paramcontainer, "songinfo in plugin"));
+
+	numeric = visual_ui_numeric_new ();
+	visual_ui_mutator_set_param (VISUAL_UI_MUTATOR (numeric),
+			visual_param_container_get (__lv_paramcontainer, "songinfo timeout"));
+	visual_ui_range_set_properties (VISUAL_UI_RANGE (numeric), 1, 60, 1, 0);
+
+	visual_ui_box_pack (VISUAL_UI_BOX (hbox), label1);
+	visual_ui_box_pack (VISUAL_UI_BOX (hbox), numeric);
+	visual_ui_box_pack (VISUAL_UI_BOX (hbox), label2);
+
+	visual_ui_box_pack (VISUAL_UI_BOX (vbox), checkbox1);
+	visual_ui_box_pack (VISUAL_UI_BOX (vbox), checkbox2);
+	visual_ui_box_pack (VISUAL_UI_BOX (vbox), hbox);
+
+	return vbox;
+}
+
+/**
+ * @defgroup Libvisual Libvisual
+ * @{
+ */
+
+/**
+ * Gives the libvisual version.
+ *
+ * @return A const char containing the libvisual version.
+ */
+const char *visual_get_version ()
+{
+	return VERSION;
+}
+
+/**
+ * Returns a pointer to the libvisual global VisParamContainer.
+ *
+ * @return A pointer to the libvisual global VisParamContainer.
+ */
+VisParamContainer *visual_get_params ()
+{
+	return __lv_paramcontainer;
+}
+
+/**
+ * Returns a pointer to the top container of libvisual it's configuration userinterface.
+ *
+ * @return A pointer to the libvisual configuration VisUIWidget.
+ */
+VisUIWidget *visual_get_userinterface ()
+{
+	return __lv_userinterface;
+}
+
+/**
+ * Adds extra plugin registry paths.
+ *
+ * @param pathadd A string containing a path where plugins are located.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_LIBVISUAL_NO_PATHS on failure.
+ */
+int visual_init_path_add (char *pathadd)
+{
+	__lv_plugpath_cnt++;
+	__lv_plugpaths = realloc (__lv_plugpaths, sizeof (char *) * __lv_plugpath_cnt);
+
+	visual_log_return_val_if_fail (__lv_plugpaths != NULL, -VISUAL_ERROR_LIBVISUAL_NO_PATHS);
+
+	__lv_plugpaths[__lv_plugpath_cnt - 1] = pathadd;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Initialize libvisual. Sets up a plugin registry, register the program name and such.
+ *
+ * @param argc Pointer to an int containing the number of arguments within argv or NULL.
+ * @param argv Pointer to a list of strings that make up the argument vector or NULL.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_LIBVISUAL_ALREADY_INITIALIZED,
+ *	-VISUAL_ERROR_LIBVISUAL_NO_REGISTRY or error values returned by visual_init_path_add () on failure.
+ */
+int visual_init (int *argc, char ***argv)
+{
+	int ret = 0;
+
+	if (__lv_initialized == TRUE) {
+		visual_log (VISUAL_LOG_ERROR, "Over initialized");
+                return -VISUAL_ERROR_LIBVISUAL_ALREADY_INITIALIZED;
+        }
+		
+	if (argc == NULL || argv == NULL) {
+		if (argc == NULL && argv == NULL) {
+			__lv_progname = strdup ("no progname");
+	
+
+			if (__lv_progname == NULL)
+				visual_log (VISUAL_LOG_WARNING, "Could not set program name");
+		} else
+			visual_log (VISUAL_LOG_ERROR, "Initialization failed, bad argv, argc");
+		
+	} else {
+                /*
+                 * We must copy the argument, to let the client
+                 * call this method from any context.
+                 */
+#ifdef __USE_GNU
+                __lv_progname = strndup (*argv[0], 1024);
+#else
+                __lv_progname = strdup (*argv[0]);
+#endif
+                if (__lv_progname == NULL)
+                        visual_log (VISUAL_LOG_WARNING, "Could not set program name");
+        }
+	
+	/* Initialize CPU caps */
+	visual_cpu_initialize ();
+
+	/* Add the standard plugin paths */
+	ret = visual_init_path_add (PLUGPATH"/actor");
+	visual_log_return_val_if_fail (ret == VISUAL_OK, ret);
+
+	ret = visual_init_path_add (PLUGPATH"/input");
+	visual_log_return_val_if_fail (ret == VISUAL_OK, ret);
+
+	ret = visual_init_path_add (PLUGPATH"/morph");
+	visual_log_return_val_if_fail (ret == VISUAL_OK, ret);
+
+	ret = visual_init_path_add (PLUGPATH"/transform");
+	visual_log_return_val_if_fail (ret == VISUAL_OK, ret);
+
+	/* And null terminate the list */
+	ret = visual_init_path_add (NULL);
+	visual_log_return_val_if_fail (ret == VISUAL_OK, ret);
+
+	__lv_plugins = visual_plugin_get_list ((const char**)__lv_plugpaths);
+	visual_log_return_val_if_fail (__lv_plugins != NULL, -VISUAL_ERROR_LIBVISUAL_NO_REGISTRY);
+
+	__lv_plugins_actor = visual_plugin_registry_filter (__lv_plugins, VISUAL_PLUGIN_TYPE_ACTOR);
+	__lv_plugins_input = visual_plugin_registry_filter (__lv_plugins, VISUAL_PLUGIN_TYPE_INPUT);
+	__lv_plugins_morph = visual_plugin_registry_filter (__lv_plugins, VISUAL_PLUGIN_TYPE_MORPH);
+	__lv_plugins_transform = visual_plugin_registry_filter (__lv_plugins, VISUAL_PLUGIN_TYPE_TRANSFORM);
+
+	__lv_paramcontainer = visual_param_container_new ();
+	init_params (__lv_paramcontainer);
+	__lv_userinterface = make_userinterface ();
+
+	__lv_initialized = TRUE;
+
+	return VISUAL_OK;
+}
+
+/*
+ * Tells whether Libvisual is (correctly) initialized.
+ *
+ * @return TRUE if is it is initialized, FALSE otherwise.
+ */
+int visual_is_initialized ()
+{
+	return __lv_initialized;
+}
+
+/**
+ * Quits libvisual, destroys all the plugin registries.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_LIBVISUAL_NOT_INITIALIZED on failure.
+ */
+int visual_quit ()
+{
+	int ret;
+
+	if (__lv_initialized == FALSE) {
+                visual_log (VISUAL_LOG_WARNING, "Never initialized");
+
+		return -VISUAL_ERROR_LIBVISUAL_NOT_INITIALIZED;
+	}
+
+	/* FIXME: Use VisError here, for human readable error strings */
+	ret = visual_object_unref (VISUAL_OBJECT (__lv_plugins));
+	if (ret < 0)
+		visual_log (VISUAL_LOG_WARNING, "Plugins references list: destroy failed");
+
+	ret = visual_object_unref (VISUAL_OBJECT (__lv_plugins_actor));
+	if (ret < 0)
+		visual_log (VISUAL_LOG_WARNING, "Actor plugins list: destroy failed");
+
+	ret = visual_object_unref (VISUAL_OBJECT (__lv_plugins_input));
+	if (ret < 0)
+		visual_log (VISUAL_LOG_WARNING, "Input plugins list: destroy failed");
+
+	ret = visual_object_unref (VISUAL_OBJECT (__lv_plugins_morph));
+	if (ret < 0)
+		visual_log (VISUAL_LOG_WARNING, "Morph plugins list: destroy failed");
+
+	ret = visual_object_unref (VISUAL_OBJECT (__lv_plugins_transform));
+	if (ret < 0)
+		visual_log (VISUAL_LOG_WARNING, "Transform plugins list: destroy failed");
+
+	ret = visual_object_unref (VISUAL_OBJECT (__lv_paramcontainer));
+	if (ret < 0)
+		visual_log (VISUAL_LOG_WARNING, "Global param container: destroy failed");
+
+	ret = visual_object_unref (VISUAL_OBJECT (__lv_userinterface));
+	if (ret < 0)
+		visual_log (VISUAL_LOG_WARNING, "Error during UI destroy:");
+
+        if (__lv_progname != NULL) {
+                visual_mem_free (__lv_progname);
+	
+		__lv_progname = NULL;
+	}
+
+	__lv_initialized = FALSE;
+	return VISUAL_OK;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_libvisual.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,46 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_LIBVISUAL_H
+#define _LV_LIBVISUAL_H
+
+#include <libvisual/lv_param.h>
+#include <libvisual/lv_ui.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+const char *visual_get_version (void);
+VisParamContainer *visual_get_params (void);
+VisUIWidget *visual_get_userinterface (void);
+int visual_init_path_add (char *pathadd);
+int visual_init (int *argc, char ***argv);
+int visual_is_initialized (void);
+int visual_quit (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_LIBVISUAL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_list.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,453 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * List implementation from RCL.
+ * Copyright (C) 2002, 2003, 2004
+ * 				Dennis Smit <ds@nerds-incorporated.org>,
+ *			  	Sepp Wijnands <mrrazz@nerds-incorporated.org>,
+ *			   	Tom Wimmenhove <nohup@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *  	    Sepp Wijnands <mrrazz@nerds-incorporated.org>,
+ *   	    Tom Wimmenhove <nohup@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include <lvconfig.h>
+#include "lv_list.h"
+#include "lv_log.h"
+#include "lv_mem.h"
+
+static int list_dtor (VisObject *object);
+
+static int list_dtor (VisObject *object)
+{
+	VisList *list = VISUAL_LIST (object);
+
+	visual_list_destroy_elements (list);	
+
+	return VISUAL_OK;
+}
+
+/**
+ * @defgroup VisList VisList
+ * @{
+ */
+
+/**
+ * Creates a new VisList structure.
+ * The VisList system is a double linked list implementation.
+ *
+ * @return A newly allocated VisList.
+ */
+VisList *visual_list_new (VisListDestroyerFunc destroyer)
+{
+	VisList *list;
+
+	list = visual_mem_new0 (VisList, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (list), TRUE, list_dtor);
+
+	list->destroyer = destroyer;
+
+	return list;
+}
+
+/**
+ * Frees the VisList. This frees the VisList data structure.
+ *
+ * @param list Pointer to a VisList that needs to be freed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_LIST_NULL or error values returned by
+ * 	visual_mem_free () on failure.
+ */
+int visual_list_free (VisList *list)
+{
+	visual_log_return_val_if_fail (list != NULL, -VISUAL_ERROR_LIST_NULL);
+
+	return visual_mem_free (list);
+}
+
+/**
+ * Destroys the entries that are in a list, but not the list itself. It uses the element
+ * destroyer set at visual_list_new or visual_list_set_destroyer.
+ *
+ * @param list Pointer to a VisList of which the elements need to be destroyed.
+ *
+ * @return VISUAL_OK on succes, or -VISUAL_ERROR_LIST_NULL on failure.
+ */
+int visual_list_destroy_elements (VisList *list)
+{
+	VisListEntry *le = NULL;
+	void *elem;
+
+	visual_log_return_val_if_fail (list != NULL, -VISUAL_ERROR_LIST_NULL);
+		
+	/* Walk through the given list, possibly calling the destroyer for it */
+	if (list->destroyer == NULL) {
+		while ((elem = visual_list_next (list, &le)) != NULL)
+			visual_list_delete (list, &le);
+	} else {
+		while ((elem = visual_list_next (list, &le)) != NULL) {
+			list->destroyer (elem);
+			visual_list_delete (list, &le);
+		}
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets a VisListEntry destroyer function a VisList.
+ *
+ * @param list Pointer to a VisList to which the VisListDestroyerFunc is set.
+ * @param destroyer The VisListEntry destroyer function.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_LIST_NULL on failure.
+ */
+int visual_list_set_destroyer (VisList *list, VisListDestroyerFunc destroyer)
+{
+	visual_log_return_val_if_fail (list != NULL, -VISUAL_ERROR_LIST_NULL);
+
+	list->destroyer = destroyer;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Go to the next entry in the list and return it's data element.
+ * This function will load the next entry in le and return a pointer
+ * to the data element.
+ *
+ * @see visual_list_prev
+ * 
+ * @param list Pointer to the VisList we're traversing.
+ * @param le Pointer to a VisListEntry to store the next entry within
+ * 	and also to use as a reference to determine at which entry we're
+ * 	currently. To begin traversing do: VisListEntry *le = NULL and pass
+ * 	it as &le in the argument.
+ *
+ * @return The data element of the next entry, or NULL.
+ */
+void *visual_list_next (VisList *list, VisListEntry **le)
+{
+	visual_log_return_val_if_fail (list != NULL, NULL);
+	visual_log_return_val_if_fail (le != NULL, NULL);
+
+	if (*le == NULL)
+		*le = list->head;
+	else
+		*le = (*le)->next;
+
+	if (*le != NULL)
+		return (*le)->data;
+
+	return NULL;
+}
+
+/**
+ * Go to the previous entry in the list and return it's data element.
+ * This function will load the previous entry in le and return a pointer
+ * to the data element.
+ *
+ * @see visual_list_next
+ * 
+ * @param list Pointer to the VisList we're traversing.
+ * @param le Pointer to a VisListEntry to store the previous entry within
+ * 	and also to use as a reference to determine at which entry we're
+ * 	currently. To begin traversing at the end of the list do:
+ * 	VisList *le = NULL and pass it as &le in the argument.
+ *
+ * @return The data element of the previous entry, or NULL.
+ */
+void *visual_list_prev (VisList *list, VisListEntry **le)
+{
+	visual_log_return_val_if_fail (list != NULL, NULL);
+	visual_log_return_val_if_fail (le != NULL, NULL);
+
+	if (!*le)
+		*le = list->tail;
+	else
+		*le = (*le)->prev;
+
+	if (*le)
+		return (*le)->data;
+
+	return NULL;
+}
+
+/**
+ * Get an data entry by index. This will give the pointer to an data
+ * element based on the index in the list.
+ *
+ * @param list Pointer to the VisList of which we want an element.
+ * @param index Index to determine which entry we want. The index starts at
+ * 	1.
+ *
+ * @return The data element of the requested entry, or NULL.
+ */
+void *visual_list_get (VisList *list, int index)
+{
+	VisListEntry *le = NULL;
+	void *data = NULL;
+	int i, lc;
+
+	visual_log_return_val_if_fail (list != NULL, NULL);
+	visual_log_return_val_if_fail (index >= 0, NULL);
+
+	lc = visual_list_count (list);
+
+	if (lc - 1 < index)
+		return NULL;
+	
+	for (i = 0; i <= index; i++) {
+		data = visual_list_next (list, &le);
+		
+		if (data == NULL)
+			return NULL;
+	}
+
+	return data;
+}
+
+/**
+ * Adds an entry at the beginning of the list.
+ *
+ * @param list Pointer to the VisList to which an entry needs to be added
+ * 	at it's head.
+ * @param data A pointer to the data that needs to be added to the list.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_LIST_NULL on failure.
+ */
+int visual_list_add_at_begin (VisList *list, void *data)
+{
+	VisListEntry *current, *next;
+
+	visual_log_return_val_if_fail (list != NULL, -VISUAL_ERROR_LIST_NULL);
+
+	/* Allocate memory for new list entry */
+	current = visual_mem_new0 (VisListEntry, 1);
+
+	/* Assign data element */
+	current->data = data;
+
+	if (list->head == NULL) {
+		list->head = current;
+		list->tail = current;
+	} else {
+		next = list->head;
+
+		current->next = next;
+		list->head = current;
+	}
+
+	/* Done */
+	list->count++;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Adds an entry at the end of the list.
+ *
+ * @param list Pointer to the VisList to which an entry needs to be added
+ * 	at it's tail.
+ * @param data A pointer to the data that needs to be added to the list.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_LIST_NULL on failure.
+ */	
+int visual_list_add (VisList *list, void *data)
+{
+	VisListEntry *current, *prev;
+	
+	visual_log_return_val_if_fail (list != NULL, -VISUAL_ERROR_LIST_NULL);
+
+	current = visual_mem_new0 (VisListEntry, 1);
+
+	/* Assign data element */
+	current->data = data;
+
+	/* Add list entry to list */
+	/* Is this the first entry for this list ? */
+	if (list->head == NULL) {
+		list->head = current;
+		list->tail = current;
+	} else {
+		/* Nope, add to tail of this list */
+		prev = list->tail;
+
+		/* Exchange pointers */
+		prev->next = current;
+		current->prev = prev;
+		
+		/* Point tail to new entry */
+		list->tail = current;
+	}
+
+	/* Done */
+	list->count++;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Insert an entry in the middle of a list. By adding it
+ * after the le entry.
+ *
+ * @param list Pointer to the VisList in which an entry needs to be inserted.
+ * @param le Pointer to a VisListEntry after which the entry needs to be inserted.
+ * @param data Pointer to the data the new entry represents.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_LIST_NULL, -VISUAL_ERROR_LIST_ENTRY_NULL or
+ * 	-VISUAL_ERROR_NULL on failure.
+ */
+int visual_list_insert (VisList *list, VisListEntry **le, void *data)
+{
+	VisListEntry *prev, *next, *current;
+	
+	visual_log_return_val_if_fail (list != NULL, -VISUAL_ERROR_LIST_NULL);
+	visual_log_return_val_if_fail (le != NULL, -VISUAL_ERROR_LIST_ENTRY_NULL);
+	visual_log_return_val_if_fail (data != NULL, -VISUAL_ERROR_NULL);
+	
+	current = visual_mem_new0 (VisListEntry, 1);
+
+	/* Assign data element */
+	current->data = data;
+
+	/* Add entry to list */
+	if (list->head == NULL && *le == NULL) {
+		/* First entry */
+		list->head = current;
+		list->tail = current;
+	} else if (*le == NULL) {
+		/* Insert entry at first position */
+		next = list->head;
+		/* Exchange pointers */
+		current->next = next;
+		next->prev = current;
+		/* Point head to current pointer */
+		list->head = current;
+	} else {
+		/* Insert entry at *le's position */
+		prev = *le;
+		next = prev->next;
+		
+		current->prev = prev;
+		current->next = next;
+
+		prev->next = current;
+		if (next != NULL)
+			next->prev = current;
+		else
+			list->tail = current;
+	}
+
+	/* Hop to new entry */
+	*le = current;
+	
+	/* Done */
+	list->count++;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Removes an entry from the list.
+ *
+ * @param list A pointer to the VisList in which an entry needs to be deleted.
+ * @param le A pointer to the entry that needs to be deleted.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_LIST_NULL or -VISUAL_ERROR_LIST_ENTRY_NULL on failure.
+ */
+int visual_list_delete (VisList *list, VisListEntry **le)
+{
+	VisListEntry *prev, *current, *next;
+	
+	visual_log_return_val_if_fail (list != NULL, -VISUAL_ERROR_LIST_NULL);
+	visual_log_return_val_if_fail (le != NULL, -VISUAL_ERROR_LIST_ENTRY_NULL);
+	
+	prev = current = next = NULL;
+
+	/* Valid list entry ? */
+	if (*le == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "There is no list entry to delete");
+
+		return -VISUAL_ERROR_LIST_ENTRY_INVALID; /* Nope */
+	}
+
+	/* Point new to le's previous entry */
+	current = *le;
+	prev = current->prev;
+	next = current->next;
+
+	/* Does it have a previous entry ? */
+	if (prev != NULL) 
+		prev->next = next;
+	else
+		list->head = next;
+	
+	if (next != NULL) /* It does have a next entry ? */
+		next->prev = prev;
+	else
+		list->tail = prev;
+
+	/* Point current entry to previous one */
+	*le = prev;
+
+	/* Free 'old' pointer */
+	list->count--;
+	visual_mem_free (current);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Counts the number of entries within the list.
+ *
+ * @param list A pointer to the list from which an entry count is needed.
+ * 
+ * @return The number of elements or -VISUAL_ERROR_LIST_NULL on failure.
+ */
+int visual_list_count (VisList *list)
+{
+	VisListEntry *le = NULL;
+	int count = 0;
+	
+	visual_log_return_val_if_fail (list != NULL, -VISUAL_ERROR_LIST_NULL);
+	
+	/* Walk through list */
+	while (visual_list_next (list, &le) != NULL) 
+		count++;
+
+	list->count = count;
+
+	return count;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_list.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,106 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * List implementation from RCL.
+ * Copyright (C) 2002, 2003, 2004
+ * 				Dennis Smit <ds@nerds-incorporated.org>,
+ *			  	Sepp Wijnands <mrrazz@nerds-incorporated.org>,
+ *			   	Tom Wimmenhove <nohup@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *  	    Sepp Wijnands <mrrazz@nerds-incorporated.org>,
+ *   	    Tom Wimmenhove <nohup@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_LIST_H
+#define _LV_LIST_H
+
+#include <libvisual/lv_common.h>
+
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
+#include <sys/queue.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_LIST(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisList))
+
+typedef struct _VisListEntry VisListEntry;
+typedef struct _VisList VisList;
+
+/**
+ * An VisList destroyer function needs this signature.
+ *
+ * @arg data The data that was stored in a VisListEntry and thus can be destroyed.
+ */
+typedef void (*VisListDestroyerFunc)(void *data);
+
+/**
+ * The VisListEntry data structure is an entry within the linked list.
+ * It does contain a pointer to both the previous and next entry in the list and
+ * a void * to the data.
+ */
+struct _VisListEntry {
+	VisListEntry		*prev;	/**< Previous entry in the list. */
+	VisListEntry		*next;	/**< Next entry in the list. */
+	void			*data;	/**< Pointer to the data for this entry. */
+};
+
+/**
+ * The VisList data structure holds the linked list.
+ * It contains an entry pointer to both the head and tail of the list as well
+ * an entry counter.
+ */
+struct _VisList {
+	VisObject		 object;	/**< The VisObject data. */
+	VisListDestroyerFunc	 destroyer;	/**< The List destroyer function. */
+	VisListEntry		*head;		/**< Pointer to the beginning of the list. */
+	VisListEntry		*tail;		/**< Pointer to the end of the list. */
+	int			 count;		/**< Number of entries that are in the list. */
+};
+
+
+/* prototypes */
+VisList *visual_list_new (VisListDestroyerFunc destroyer);
+int visual_list_free (VisList *list);
+int visual_list_destroy_elements (VisList *list);
+
+int visual_list_set_destroyer (VisList *list, VisListDestroyerFunc destroyer);
+
+void *visual_list_next (VisList *list, VisListEntry **le);
+void *visual_list_prev (VisList *list, VisListEntry **le);
+
+void *visual_list_get (VisList *list, int index);
+
+int visual_list_add_at_begin (VisList *list, void *data);
+int visual_list_add (VisList *list, void *data);
+
+int visual_list_insert (VisList *list, VisListEntry **le, void *data);
+int visual_list_delete (VisList *list, VisListEntry **le);
+
+int visual_list_count (VisList *list);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_LIST_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_log.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,270 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <signal.h>
+
+#include "lv_common.h"
+#include "lv_error.h"
+#include "lv_log.h"
+
+
+static VisLogVerboseness verboseness = VISUAL_LOG_VERBOSENESS_MEDIUM;
+
+static void default_info_handler (const char *msg, const char *funcname, void *privdata);
+static void default_warning_handler (const char *msg, const char *funcname, void *privdata);
+static void default_critical_handler (const char *msg, const char *funcname, void *privdata);
+static void default_error_handler (const char *msg, const char *funcname, void *privdata);
+
+static struct _message_handlers {
+	VisLogMessageHandlerFunc	 info_handler;
+	VisLogMessageHandlerFunc	 warning_handler;
+	VisLogMessageHandlerFunc	 critical_handler;
+	VisLogMessageHandlerFunc	 error_handler;
+
+	void				*info_priv;
+	void				*warning_priv;
+	void				*critical_priv;
+	void				*error_priv;
+} message_handlers;
+
+
+/**
+ * @defgroup VisLog VisLog
+ * @{
+ */
+
+/**
+ * Set the library it's verbosity level.
+ *
+ * @param v The verbose level as a VisLogVerboseness enumerate value.
+ */
+void visual_log_set_verboseness (VisLogVerboseness v)
+{
+	verboseness = v;
+}
+
+/**
+ * Get the current library it's verbosity level.
+ *
+ * @return The verboseness level as a VisLogVerboseness enumerate value.
+ */
+VisLogVerboseness visual_log_get_verboseness ()
+{
+	return verboseness;
+}
+
+/**
+ * Set the callback function that handles info messages.
+ *
+ * @param handler The custom message handler callback.
+ * @param priv Optional private data to pass on to the handler.
+ */
+void visual_log_set_info_handler (VisLogMessageHandlerFunc handler, void *priv)
+{
+	visual_log_return_if_fail (handler != NULL);
+
+	message_handlers.info_handler = handler;
+
+	message_handlers.info_priv = priv;
+}
+
+/**
+ * Set the callback function that handles warning messages.
+ *
+ * @param handler The custom message handler callback.
+ * @param priv Optional private data to pass on to the handler.
+ */
+void visual_log_set_warning_handler (VisLogMessageHandlerFunc handler, void *priv)
+{
+	visual_log_return_if_fail (handler != NULL);
+
+	message_handlers.warning_handler = handler;
+
+	message_handlers.warning_priv = priv;
+}
+
+/**
+ * Set the callback function that handles critical messages.
+ *
+ * @param handler The custom message handler callback.
+ * @param priv Optional private data to pass on to the handler.
+ */
+void visual_log_set_critical_handler (VisLogMessageHandlerFunc handler, void *priv)
+{
+	visual_log_return_if_fail (handler != NULL);
+
+	message_handlers.critical_handler = handler;
+
+	message_handlers.critical_priv = priv;
+}
+
+/**
+ * Set the callback function that handles error messages. After handling the message with
+ * this function, libvisual will abort the program. This behavior cannot be
+ * changed.
+ *
+ * @param handler The custom message handler callback.
+ * @param priv Optional private data to pass on to the handler.
+ */
+void visual_log_set_error_handler (VisLogMessageHandlerFunc handler, void *priv)
+{
+	visual_log_return_if_fail (handler != NULL);
+
+	message_handlers.error_handler = handler;
+
+	message_handlers.error_priv = priv;
+}
+
+/**
+ * Set callback the function that handles all the messages.
+ *
+ * @param handler The custom message handler callback.
+ * @param priv Optional private data to pass on to the handler.
+ */
+void visual_log_set_all_messages_handler (VisLogMessageHandlerFunc handler, void *priv)
+{
+	visual_log_return_if_fail (handler != NULL);
+
+	message_handlers.info_handler = handler;
+	message_handlers.warning_handler = handler;
+	message_handlers.critical_handler = handler;
+	message_handlers.error_handler = handler;
+
+	message_handlers.info_priv = priv;
+	message_handlers.warning_priv = priv;
+	message_handlers.critical_priv = priv;
+	message_handlers.error_priv = priv;
+}
+	
+/**
+ * Private library call used by the visual_log define to display debug,
+ * warning and error messages.
+ *
+ * @see visual_log
+ * 
+ * @param severity Severity of the log message.
+ * @param file Char pointer to a string that contains the source filename.
+ * @param line Line number for which the log message is.
+ * @param funcname Function name in which the log message is called.
+ * @param fmt Format string to display the log message.
+ */
+void _lv_log (VisLogSeverity severity, const char *file,
+			int line, const char *funcname, const char *fmt, ...)
+{
+	char str[1024];
+	va_list va;
+	
+	assert (fmt != NULL);
+
+	va_start (va, fmt);
+	vsnprintf (str, 1023, fmt, va);
+	va_end (va);
+
+	switch (severity) {
+		case VISUAL_LOG_DEBUG:
+			if (verboseness == VISUAL_LOG_VERBOSENESS_HIGH)
+				fprintf (stderr, "libvisual DEBUG: %s: %s() [(%s,%d)]: %s\n",
+						__lv_progname, funcname, file, line, str);
+		
+			break;
+		case VISUAL_LOG_INFO:
+			if (!message_handlers.info_handler)
+				visual_log_set_info_handler (default_info_handler, NULL);
+
+			if (verboseness >= VISUAL_LOG_VERBOSENESS_MEDIUM)
+				message_handlers.info_handler (str, funcname, message_handlers.info_priv);
+
+			break;
+		case VISUAL_LOG_WARNING:
+			if (!message_handlers.warning_handler)
+				visual_log_set_warning_handler (default_warning_handler, NULL);
+
+			if (verboseness >= VISUAL_LOG_VERBOSENESS_MEDIUM)
+				message_handlers.warning_handler (str, funcname, message_handlers.warning_priv);
+			
+			break;
+
+		case VISUAL_LOG_CRITICAL:
+			if (!message_handlers.critical_handler)
+				visual_log_set_critical_handler (default_critical_handler, NULL);
+
+			if (verboseness >= VISUAL_LOG_VERBOSENESS_LOW)
+				message_handlers.critical_handler (str, funcname, message_handlers.critical_priv);
+		
+			break;
+
+		case VISUAL_LOG_ERROR:
+			if (!message_handlers.error_handler)
+				visual_log_set_error_handler (default_error_handler, NULL);
+
+			if (verboseness >= VISUAL_LOG_VERBOSENESS_LOW)
+				message_handlers.error_handler (str, funcname, message_handlers.error_priv);
+
+			visual_error_raise ();
+
+			break;
+	}
+}
+
+/**
+ * @}
+ */
+
+static void default_info_handler (const char *msg, const char *funcname, void *privdata)
+{
+	printf ("libvisual INFO: %s: %s\n", __lv_progname, msg);
+}
+
+static void default_warning_handler (const char *msg, const char *funcname, void *privdata)
+{
+	if (funcname)
+		fprintf (stderr, "libvisual WARNING: %s: %s(): %s\n",
+				__lv_progname, funcname, msg);
+	else
+		fprintf (stderr, "libvisual WARNING: %s: %s\n", __lv_progname, msg);
+}
+
+static void default_critical_handler (const char *msg, const char *funcname, void *privdata)
+{
+	if (funcname)
+		fprintf (stderr, "libvisual CRITICAL: %s: %s(): %s\n",
+				__lv_progname, funcname, msg);
+	else
+		fprintf (stderr, "libvisual CRITICAL: %s: %s\n", __lv_progname, msg);
+}
+
+static void default_error_handler (const char *msg, const char *funcname, void *privdata)
+{
+	if (funcname)
+		fprintf (stderr, "libvisual ERROR: %s: %s(): %s\n",
+				__lv_progname, funcname, msg);
+	else
+		fprintf (stderr, "libvisual ERROR: %s: %s\n", __lv_progname, msg);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_log.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,313 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_LOG_H
+#define _LV_LOG_H
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* This is read-only */
+extern char *__lv_progname;
+
+/**
+ * Used to determine the severity of the log message using the visual_log
+ * define.
+ *
+ * @see visual_log
+ */
+typedef enum {
+	VISUAL_LOG_DEBUG,	/**< Debug message, to use for debug messages. */
+	VISUAL_LOG_INFO,	/**< Informative message, can be used for general info. */
+	VISUAL_LOG_WARNING,	/**< Warning message, use to warn the user. */
+	VISUAL_LOG_CRITICAL,	/**< Critical message, when a critical situation happens.
+				 * Like a NULL pointer passed to a method. */
+	VISUAL_LOG_ERROR	/**< Error message, use to notify the user of fatals. 
+				 * After the message has been showed, the program is aborted. */
+} VisLogSeverity;
+
+/**
+ * Used to determine how much verbose the log system should be.
+ *
+ * @see visual_log_set_verboseness
+ */
+typedef enum {
+	VISUAL_LOG_VERBOSENESS_NONE,	/**< Don't show any message at all. */
+	VISUAL_LOG_VERBOSENESS_LOW,	/**< Show only VISUAL_LOG_ERROR and
+					  VISUAL_LOG_CRITICAL messages. */
+	VISUAL_LOG_VERBOSENESS_MEDIUM,	/**< Show all log messages except VISUAL_LOG_DEBUG ones. */
+	VISUAL_LOG_VERBOSENESS_HIGH	/**< Show all log messages. */
+} VisLogVerboseness;
+
+/**
+ * Functions that want to handle messages must match this signature.
+ *
+ * @arg message The message that will be shown, exactly the same as that was passed
+ * to visual_log(), but after formatting.
+ *
+ * @arg funcname The name of the function that invokes visual_log(). On non-GNU systems
+ * this will probably be NULL.
+ *
+ * @arg priv Private field to be used by the client. The library will never touch this.
+ */
+typedef void (*VisLogMessageHandlerFunc) (const char *message,
+							const char *funcname, void *priv);
+
+void visual_log_set_verboseness (VisLogVerboseness verboseness);
+VisLogVerboseness visual_log_get_verboseness (void);
+
+void visual_log_set_info_handler (VisLogMessageHandlerFunc handler, void *priv);
+void visual_log_set_warning_handler (VisLogMessageHandlerFunc handler, void *priv);
+void visual_log_set_critical_handler (VisLogMessageHandlerFunc handler, void *priv);
+void visual_log_set_error_handler (VisLogMessageHandlerFunc handler, void *priv);
+
+void visual_log_set_all_messages_handler (VisLogMessageHandlerFunc handler, void *priv);
+
+/**
+ * Used for log messages, this is brought under a define so
+ * that the __FILE__ and __LINE__ macros (and probably __PRETTY_FUNC__) work,
+ * and thus provide better information.
+ *
+ * @see VisLogSeverity
+ *
+ * @param severity Determines the severity of the message using VisLogSeverity.
+ * @param format The format string of the log message.
+ */
+#ifdef __GNUC__
+
+#ifdef LV_HAVE_ISO_VARARGS
+#define visual_log(severity,...)		\
+		_lv_log (severity,		\
+			__FILE__,		\
+			__LINE__,		\
+			__PRETTY_FUNCTION__,	\
+			__VA_ARGS__)
+#elif defined(LV_HAVE_GNUC_VARARGS)
+#define visual_log(severity,format...)		\
+		_lv_log (severity,		\
+			__FILE__,		\
+			__LINE__,		\
+			__PRETTY_FUNCTION__,	\
+			format)
+#else
+
+#include <signal.h>
+
+static void visual_log (VisLogSeverity severity, const char *fmt, ...)
+{
+	char str[1024];
+	va_list va;
+	char sever_msg[10];
+	VisLogVerboseness v;
+	
+	assert (fmt != NULL);
+
+	va_start (va, fmt);
+	vsnprintf (str, 1023, fmt, va);
+	va_end (va);
+
+	switch (severity) {
+		case VISUAL_LOG_DEBUG:
+			strncpy (sever_msg, "DEBUG", 9);
+			break;
+		case VISUAL_LOG_INFO:
+			strncpy (sever_msg, "INFO", 9);
+			break;
+		case VISUAL_LOG_WARNING:
+			strncpy (sever_msg, "WARNING", 9);
+			break;
+		case VISUAL_LOG_CRITICAL:
+			strncpy (sever_msg, "CRITICAL", 9);
+			break;
+		case VISUAL_LOG_ERROR:
+			strncpy (sever_msg, "ERROR", 9);
+			break;
+		default:
+			assert (0);
+	}
+	/*
+	 * Sorry, we doesn't have (file,line) information
+	 */
+	v = visual_log_get_verboseness ();
+	switch (severity) {
+		case VISUAL_LOG_DEBUG:
+			if (v == VISUAL_LOG_VERBOSENESS_HIGH)
+				fprintf (stderr, "libvisual %s: %s: %s\n",
+					sever_msg, __lv_progname, str);
+			break;
+		case VISUAL_LOG_INFO:
+			if (v >= VISUAL_LOG_VERBOSENESS_MEDIUM)
+				printf ("libvisual %s: %s: %s\n",
+					sever_msg, __lv_progname, str);
+			break;
+		case VISUAL_LOG_WARNING:
+			if (v >= VISUAL_LOG_VERBOSENESS_MEDIUM)
+				fprintf (stderr, "libvisual %s: %s: %s\n",
+					sever_msg, __lv_progname, str);
+			break;
+		case VISUAL_LOG_CRITICAL:
+			if (v >= VISUAL_LOG_VERBOSENESS_LOW)
+				fprintf (stderr, "libvisual %s: %s: %s\n",
+					sever_msg, __lv_progname, str);
+			break;
+		case VISUAL_LOG_ERROR:
+			if (v >= VISUAL_LOG_VERBOSENESS_LOW)
+				printf ("libvisual %s: %s: %s\n",
+					sever_msg, __lv_progname, str);
+			visual_error_raise ();
+			break;
+	}
+}
+#endif /* !(ISO_VARARGS || GNUC_VARARGS) */
+
+#endif /* __GNUC__ */
+
+
+#ifndef __GNUC__
+
+#ifdef LV_HAVE_ISO_VARARGS
+#define visual_log(severity,...)		\
+		_lv_log (severity,		\
+			__FILE__,		\
+			__LINE__,		\
+			(NULL),			\
+			__VA_ARGS__)
+#else
+
+#include <signal.h>
+
+static void visual_log (VisLogSeverity severity, const char *fmt, ...)
+{
+	char str[1024];
+	va_list va;
+	char sever_msg[10];
+	VisLogVerboseness v;
+	
+	assert (fmt != NULL);
+
+	va_start (va, fmt);
+	vsnprintf (str, 1023, fmt, va);
+	va_end (va);
+
+	switch (severity) {
+		case VISUAL_LOG_DEBUG:
+			strncpy (sever_msg, "DEBUG", 9);
+			break;
+		case VISUAL_LOG_INFO:
+			strncpy (sever_msg, "INFO", 9);
+			break;
+		case VISUAL_LOG_WARNING:
+			strncpy (sever_msg, "WARNING", 9);
+			break;
+		case VISUAL_LOG_CRITICAL:
+			strncpy (sever_msg, "CRITICAL", 9);
+			break;
+		case VISUAL_LOG_ERROR:
+			strncpy (sever_msg, "ERROR", 9);
+			break;
+		default:
+			assert (0);
+	}
+	/*
+	 * Sorry, we don't have (file,line) information
+	 */
+	v = visual_log_get_verboseness ();
+	switch (severity) {
+		case VISUAL_LOG_DEBUG:
+			if (v == VISUAL_LOG_VERBOSENESS_HIGH)
+				fprintf (stderr, "libvisual %s: %s: %s\n",
+					sever_msg, __lv_progname, str);
+			break;
+		case VISUAL_LOG_INFO:
+			if (v >= VISUAL_LOG_VERBOSENESS_MEDIUM)
+				printf ("libvisual %s: %s: %s\n",
+					sever_msg, __lv_progname, str);
+			break;
+		case VISUAL_LOG_WARNING:
+			if (v >= VISUAL_LOG_VERBOSENESS_MEDIUM)
+				fprintf (stderr, "libvisual %s: %s: %s\n",
+					sever_msg, __lv_progname, str);
+			break;
+		case VISUAL_LOG_CRITICAL:
+			if (v >= VISUAL_LOG_VERBOSENESS_LOW)
+				fprintf (stderr, "libvisual %s: %s: %s\n",
+					sever_msg, __lv_progname, str);
+			break;
+		case VISUAL_LOG_ERROR:
+			if (v >= VISUAL_LOG_VERBOSENESS_LOW)
+				printf ("libvisual %s: %s: %s\n",
+					sever_msg, __lv_progname, str);
+			visual_error_raise ();
+			break;
+	}
+}
+#endif /* ISO_VARARGS */
+
+#endif /* !__GNUC__ */
+
+/**
+ * Return if @a expr is FALSE, showing a critical message with
+ * useful information.
+ */
+#define visual_log_return_if_fail(expr)				\
+	if (expr) { } else					\
+	{							\
+	visual_log (VISUAL_LOG_CRITICAL,			\
+		 "assertion `%s' failed",			\
+		#expr);						\
+	return;							\
+	}
+
+/**
+ * Return if @a val if @a expr is FALSE, showing a critical message
+ * with useful information.
+ */
+#define visual_log_return_val_if_fail(expr, val)		\
+	if (expr) { } else					\
+	{							\
+	visual_log (VISUAL_LOG_CRITICAL,			\
+		 "assertion `%s' failed",			\
+		#expr);						\
+	return (val);						\
+	}
+
+#if defined __GNUC__
+void _lv_log (VisLogSeverity severity, const char *file,
+		int line, const char *funcname, const char *fmt, ...)
+			__attribute__ ((__format__ (__printf__, 5, 6)));
+#else
+void _lv_log (VisLogSeverity severity, const char *file,
+		int line, const char *funcname, const char *fmt, ...);
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_LOG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_mem.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,155 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "lv_mem.h"
+#include "lv_common.h"
+#include "lv_log.h"
+#include "lv_error.h"
+#include "lv_cpu.h"
+
+/**
+ * @defgroup VisMem VisMem
+ * @{
+ */
+
+/**
+ * Allocates @a nbytes of memory initialized to 0.
+ *
+ * @param nbytes N bytes of mem requested to be allocated.
+ * 
+ * @return On success, a pointer to a new allocated memory initialized
+ * to 0 of size @a nbytes, on failure, program is aborted, so you never need
+ * to check the return value.
+ */
+void *visual_mem_malloc0 (visual_size_t nbytes)
+{
+	void *buf = malloc (nbytes);
+
+	visual_log_return_val_if_fail (nbytes > 0, NULL);
+
+	if (buf == NULL) {
+		visual_log (VISUAL_LOG_ERROR, "Cannot get %" VISUAL_SIZE_T_FORMAT " bytes of memory", nbytes);
+		return NULL;
+	}
+	
+	memset (buf, 0, nbytes);
+
+	return buf;
+}
+
+/**
+ * Frees allocated memory.
+ *
+ * @param ptr Frees memory to which ptr points to.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MEM_NULL on failure.
+ */
+int visual_mem_free (void *ptr)
+{
+	visual_log_return_val_if_fail (ptr != NULL, -VISUAL_ERROR_MEM_NULL);
+
+	free (ptr);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Copies a block of mem using optimized methods.
+ *
+ * @param dest Pointer to destination.
+ * @param src Pointer to source.
+ * @param n The number of bytes to be copied.
+ *
+ * @return Pointer to dest.
+ */
+void *visual_mem_copy (void *dest, const void *src, size_t n)
+{
+	VisCPU *cpucaps = visual_cpu_get_caps ();
+	uint32_t *d = dest;
+	const uint32_t *s = src;
+	uint8_t *dc = dest;
+	const uint8_t *sc = src;
+
+	/* FIXME Add mmx,sse versions, optionally with prefetching and such
+	 * with checking for optimal scan lines */
+
+	/* FIXME #else for the VISUAL_ARCH_X86 */
+
+	/* FIXME fix this stuff ! */
+	return memcpy (dest, src, n);
+	
+	if (cpucaps->hasMMX == 1) {
+#ifdef VISUAL_ARCH_X86
+		while (n > 64) {
+			__asm __volatile
+				(//"\n\t prefetch 256(%0)" /* < only use when 3dnow is present */
+				 //"\n\t prefetch 320(%0)"
+				 "\n\t movq (%0), %%mm0"
+				 "\n\t movq 8(%0), %%mm1"
+				 "\n\t movq 16(%0), %%mm2"
+				 "\n\t movq 24(%0), %%mm3"
+				 "\n\t movq 32(%0), %%mm4"
+				 "\n\t movq 40(%0), %%mm5"
+				 "\n\t movq 48(%0), %%mm6"
+				 "\n\t movq 56(%0), %%mm7"
+				 "\n\t movntq %%mm0, (%1)"
+				 "\n\t movntq %%mm1, 8(%1)"
+				 "\n\t movntq %%mm2, 16(%1)"
+				 "\n\t movntq %%mm3, 24(%1)"
+				 "\n\t movntq %%mm4, 32(%1)"
+				 "\n\t movntq %%mm5, 40(%1)"
+				 "\n\t movntq %%mm6, 48(%1)"
+				 "\n\t movntq %%mm7, 56(%1)"
+				 :: "r" (s), "r" (d) : "memory");
+
+
+			d += 16;
+			s += 16;
+
+			n -= 64;
+		}
+#endif /* VISUAL_ARCH_X86 */
+	} else {
+		while (n >= 4) {
+			*d++ = *s++;
+			n -= 4;
+		}
+
+		dc = (uint8_t *) d;
+		sc = (const uint8_t *) s;
+
+	}
+	
+	while (n--)
+		*dc++ = *sc++;
+
+	return dest;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_mem.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,55 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_MEM_H
+#define _LV_MEM_H
+
+#include <libvisual/lvconfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef __attribute_malloc__
+#define __attribute_malloc__
+#endif
+	
+void *visual_mem_malloc0 (visual_size_t nbytes) __attribute_malloc__;
+int visual_mem_free (void *ptr);
+
+void *visual_mem_copy (void *dest, const void *src, size_t n);
+
+/**
+ * @ingroup VisMem
+ * 
+ * Convenient macro to request @a n_structs structures of type @a struct_type
+ * initialized to 0.
+ */
+#define visual_mem_new0(struct_type, n_structs)           \
+    ((struct_type *) visual_mem_malloc0 (((visual_size_t) sizeof (struct_type)) * ((visual_size_t) (n_structs))))
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_MEM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_morph.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,462 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <lvconfig.h>
+#include "lv_log.h"
+#include "lv_morph.h"
+#include "lv_log.h"
+#include "lv_mem.h"
+
+extern VisList *__lv_plugins_morph;
+
+static int morph_dtor (VisObject *object);
+
+static VisMorphPlugin *get_morph_plugin (VisMorph *morph);
+
+static int morph_dtor (VisObject *object)
+{
+	VisMorph *morph = VISUAL_MORPH (object);
+
+	if (morph->plugin != NULL)
+		visual_plugin_unload (morph->plugin);
+
+	visual_palette_free_colors (&morph->morphpal);
+
+	morph->plugin = NULL;
+
+	return VISUAL_OK;
+}
+
+static VisMorphPlugin *get_morph_plugin (VisMorph *morph)
+{
+	VisMorphPlugin *morphplugin;
+
+	visual_log_return_val_if_fail (morph != NULL, NULL);
+	visual_log_return_val_if_fail (morph->plugin != NULL, NULL);
+
+	morphplugin = VISUAL_PLUGIN_MORPH (morph->plugin->info->plugin);
+
+	return morphplugin;
+}
+
+/**
+ * @defgroup VisMorph VisMorph
+ * @{
+ */
+
+/**
+ * Gives the encapsulated VisPluginData from a VisMorph.
+ *
+ * @param morph Pointer of a VisMorph of which the VisPluginData needs to be returned.
+ *
+ * @return VisPluginData that is encapsulated in the VisMorph, possibly NULL.
+ */
+VisPluginData *visual_morph_get_plugin (VisMorph *morph)
+{
+	        return morph->plugin;
+}
+
+/**
+ * Gives a list of morph plugins in the current plugin registry.
+ *
+ * @return a VisList containing the morph plugins in the plugin registry.
+ */
+VisList *visual_morph_get_list ()
+{
+	return __lv_plugins_morph;
+}
+
+/**
+ * Gives the next morph plugin based on the name of a plugin.
+ *
+ * @see visual_morph_get_prev_by_name
+ *
+ * @param name The name of the current plugin, or NULL to get the first.
+ *
+ * @return The name of the next plugin within the list.
+ */
+const char *visual_morph_get_next_by_name (const char *name)
+{
+	return visual_plugin_get_next_by_name (visual_morph_get_list (), name);
+}
+
+/**
+ * Gives the previous morph plugin based on the name of a plugin.
+ *
+ * @see visual_morph_get_next_by_name
+ *
+ * @param name The name of the current plugin. or NULL to get the last.
+ *
+ * @return The name of the previous plugin within the list.
+ */
+const char *visual_morph_get_prev_by_name (const char *name)
+{
+	return visual_plugin_get_prev_by_name (visual_morph_get_list (), name);
+}
+
+/**
+ * Checks if the morph plugin is in the registry, based on it's name.
+ *
+ * @param name The name of the plugin that needs to be checked.
+ *
+ * @return TRUE if found, else FALSE.
+ */
+int visual_morph_valid_by_name (const char *name)
+{
+	if (visual_plugin_find (visual_morph_get_list (), name) == NULL)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+/**
+ * Creates a new VisMorph from name, the plugin will be loaded but won't be realized.
+ *
+ * @param morphname
+ * 	The name of the plugin to load, or NULL to simply allocate a new
+ * 	morph.
+ * 
+ * @return A newly allocated VisMorph, optionally containing a loaded plugin. Or NULL on failure.
+ */  
+VisMorph *visual_morph_new (const char *morphname)
+{
+	VisMorph *morph;
+	VisPluginRef *ref;
+
+	if (__lv_plugins_morph == NULL && morphname != NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "the plugin list is NULL");
+		return NULL;
+	}
+
+	morph = visual_mem_new0 (VisMorph, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (morph), TRUE, morph_dtor);
+
+	visual_palette_allocate_colors (&morph->morphpal, 256);
+
+	visual_morph_set_mode (morph, VISUAL_MORPH_MODE_SET);
+
+	if (morphname == NULL)
+		return morph;
+
+	ref = visual_plugin_find (__lv_plugins_morph, morphname);
+
+	morph->plugin = visual_plugin_load (ref);
+
+	return morph;
+}
+
+/**
+ * Realize the VisMorph. This also calls the plugin init function.
+ *
+ * @param morph Pointer to a VisMorph that needs to be realized.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MORPH_NULL, -VISUAL_ERROR_PLUGIN_NULL or error values
+ *	returned by visual_plugin_realize () on failure.
+ */
+int visual_morph_realize (VisMorph *morph)
+{
+	visual_log_return_val_if_fail (morph != NULL, -VISUAL_ERROR_MORPH_NULL);
+	visual_log_return_val_if_fail (morph->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+
+	return visual_plugin_realize (morph->plugin);
+}
+
+/**
+ * Gives the by the plugin natively supported depths
+ *
+ * @param morph Pointer to a VisMorph of which the supported depth of it's
+ * 	  encapsulated plugin is requested.
+ *
+ * @return an OR value of the VISUAL_VIDEO_CONTEXT_* values which can be checked against using AND on succes, -1 on failure
+ */
+int visual_morph_get_supported_depth (VisMorph *morph)
+{
+	VisPluginData *plugin;
+	VisMorphPlugin *morphplugin;
+
+	visual_log_return_val_if_fail (morph != NULL, -VISUAL_ERROR_MORPH_NULL);
+	visual_log_return_val_if_fail (morph->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+
+	morphplugin = get_morph_plugin (morph);
+
+	if (morphplugin == NULL)
+		return -VISUAL_ERROR_MORPH_PLUGIN_NULL;
+
+	return morphplugin->depth;
+}
+
+/**
+ * Used to connect the target display, or a buffer it's VisVideo to the VisMorph plugin.
+ *
+ * @see visual_video_new
+ *
+ * @param morph Pointer to a VisMorph to which the VisVideo needs to be set.
+ * @param video Pointer to a VisVideo which contains information about the target display and the pointer
+ * 	  to it's screenbuffer.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MORPH_NULL or -VISUAL_ERROR_VIDEO_NULL on failure.
+ */
+int visual_morph_set_video (VisMorph *morph, VisVideo *video)
+{
+	visual_log_return_val_if_fail (morph != NULL, -VISUAL_ERROR_MORPH_NULL);
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	morph->dest = video;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Set the time when the morph should be finished morphing.
+ * The VisMorph keeps a local copy of the given time.
+ *
+ * @param morph Pointer to the VisMorph to which finish time is set.
+ * @param time Pointer to the VisTime that contains the finish time.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MORPH_NULL, -VISUAL_ERROR_TIME_NULL or error values returned by
+ * 	visual_time_copy () on failure.
+ */
+int visual_morph_set_time (VisMorph *morph, VisTime *time)
+{
+	visual_log_return_val_if_fail (morph != NULL, -VISUAL_ERROR_MORPH_NULL);
+	visual_log_return_val_if_fail (time != NULL, -VISUAL_ERROR_TIME_NULL);
+
+	return visual_time_copy (&morph->morphtime, time);
+}
+
+/**
+ * Used to set the rate of the VisMmorph. The rate ranges from 0 to 1
+ * and the content of the result depends on the morph plugin being used.
+ *
+ * @param morph Pointer to a VisMorph to which the rate needs to be set.
+ * @param rate Value that sets the rate of the current morph. The rate 
+ * 	  contains the amount that is currently being morphed and needs to be
+ * 	  manually adjust. The morph system doesn't increase the rate itself.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MORPH_NULL on failure.
+ */
+int visual_morph_set_rate (VisMorph *morph, float rate)
+{
+	visual_log_return_val_if_fail (morph != NULL, -VISUAL_ERROR_MORPH_NULL);
+
+	morph->rate = rate;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Used to set the number of steps that a morph will take to finish.
+ *
+ * @param morph Pointer to a VisMorph to which the number of morph steps is set.
+ * @param steps The number of steps that a morph should take.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MORPH_NULL on failure.
+ */
+int visual_morph_set_steps (VisMorph *morph, int steps)
+{
+	visual_log_return_val_if_fail (morph != NULL, -VISUAL_ERROR_MORPH_NULL);
+
+	morph->steps = steps;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Used to set the method of morphing.
+ *
+ * @param morph Pointer to a VisMorph to which the method of morphing is set.
+ * @param mode Method of morphing that is of type VisMorphMode.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MORPH_NULL on failure.
+ */
+int visual_morph_set_mode (VisMorph *morph, VisMorphMode mode)
+{
+	visual_log_return_val_if_fail (morph != NULL, -VISUAL_ERROR_MORPH_NULL);
+
+	morph->mode = mode;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Some morph plugins can give a custom palette while morphing two 8 bits plugins.
+ *
+ * @param morph Pointer to a VisMorph of which the palette needs to be retrieved.
+ *
+ * @return The pointer to the custom palette on succes or NULL on failure.
+ */
+VisPalette *visual_morph_get_palette (VisMorph *morph)
+{
+	visual_log_return_val_if_fail (morph != NULL, NULL);
+
+	return &morph->morphpal;
+}
+
+/**
+ * Function that helps to check if a morph is done with it's morphing.
+ *
+ * @param morph Pointer to a VisMorph of which we want to know if it's done yet.
+ *
+ * @return TRUE or FALSE, -VISUAL_ERROR_MORPH_NULL on failure.
+ */
+int visual_morph_is_done (VisMorph *morph)
+{
+	visual_log_return_val_if_fail (morph != NULL, -VISUAL_ERROR_MORPH_NULL);
+
+	if (morph->mode == VISUAL_MORPH_MODE_SET)
+		return FALSE;
+
+	if (morph->rate >= 1.0) {
+		if (morph->mode == VISUAL_MORPH_MODE_TIME)
+			visual_timer_stop (&morph->timer);
+
+		if (morph->mode == VISUAL_MORPH_MODE_STEPS)
+			morph->stepsdone = 0;
+
+		return TRUE;
+	}
+
+	/* Always be sure ;) */
+	if (morph->mode == VISUAL_MORPH_MODE_STEPS && morph->steps == morph->stepsdone)
+		return TRUE;
+
+	return FALSE;
+}
+
+/**
+ * Some morph plugins request an VisAudio context to draw properly. Using this function
+ * you can check if the VisMorphPlugin being used in the VisMorph requests this.
+ *
+ * @param morph Pointer to a VisMorph of which we want to know if it wants a VisAudio.
+ *
+ * @return TRUE or FALSE, -VISUAL_ERROR_MORPH_NULL or -VISUAL_ERROR_MORPH_PLUGIN_NULL on failure. 
+ */
+int visual_morph_requests_audio (VisMorph *morph)
+{
+	VisMorphPlugin *morphplugin;
+
+	visual_log_return_val_if_fail (morph != NULL, -VISUAL_ERROR_MORPH_NULL);
+
+	morphplugin = get_morph_plugin (morph);
+	
+	if (morphplugin == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL,
+			"The given morph does not reference any plugin");
+
+		return -VISUAL_ERROR_MORPH_PLUGIN_NULL;
+	}
+
+	return morphplugin->requests_audio;
+}
+
+/**
+ * This is called to run the VisMorph. It will put the result in the buffer that is previously
+ * set by visual_morph_set_video and also when the morph is being runned in 8 bits mode
+ * it will automaticly interpolate between the two palettes if the plugin doesn't have
+ * a method for adjusting the palette.
+ *
+ * Note that all the VisVideo structures being used need to be clones.
+ *
+ * @param morph Pointer to a VisMorph that needs to be runned.
+ * @param audio Pointer to a VisAudio which a morph could use for extra effects
+ * @param src1 Pointer to a VisVideo that acts as the first source for the morph.
+ * @param src2 Pointer to a VisVideo that acts as the second source for the morph.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MORPH_NULL, -VISUAL_ERROR_AUDIO_NULL,
+ * 	-VISUAL_ERROR_VIDEO_NULL or -VISUAL_ERROR_VIDEO_NULL on failure.
+ */ 
+int visual_morph_run (VisMorph *morph, VisAudio *audio, VisVideo *src1, VisVideo *src2)
+{
+	VisMorphPlugin *morphplugin;
+	VisTime elapsed;
+	double usec_elapsed, usec_morph;
+	
+	visual_log_return_val_if_fail (morph != NULL, -VISUAL_ERROR_MORPH_NULL);
+	visual_log_return_val_if_fail (audio != NULL, -VISUAL_ERROR_AUDIO_NULL);
+	visual_log_return_val_if_fail (src1 != NULL, -VISUAL_ERROR_VIDEO_NULL);
+	visual_log_return_val_if_fail (src2 != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	morphplugin = get_morph_plugin (morph);
+
+	if (morphplugin == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL,
+			"The given morph does not reference any plugin");
+
+		return -VISUAL_ERROR_MORPH_PLUGIN_NULL;
+	}
+	
+	/* If we're morphing using the timer, start the timer. */
+	if (visual_timer_is_active (&morph->timer) == FALSE)
+		visual_timer_start (&morph->timer);
+
+	if (morphplugin->palette != NULL)
+		morphplugin->palette (morph->plugin, morph->rate, audio, &morph->morphpal, src1, src2);
+	else {
+		if (src1->pal != NULL && src2->pal != NULL)
+			visual_palette_blend (&morph->morphpal, src1->pal, src2->pal, morph->rate);
+	}
+
+	morphplugin->apply (morph->plugin, morph->rate, audio, morph->dest, src1, src2);
+
+	morph->dest->pal = visual_morph_get_palette (morph);
+
+	/* On automatic morphing increase the rate. */
+	if (morph->mode == VISUAL_MORPH_MODE_STEPS) {
+		morph->rate += (1.000 / morph->steps);
+		morph->stepsdone++;
+
+		if (morph->rate > 1.0)
+			morph->rate = 1;
+
+	} else if (morph->mode == VISUAL_MORPH_MODE_TIME) {
+		visual_timer_elapsed (&morph->timer, &elapsed);
+
+		/**
+		 * @todo: We might want to have a bigger type here, but long longs aren't atomic
+		 * on most architectures, so that won't do for now, maybe when we can lock (for threading)
+		 * we can look into that
+		 */
+		usec_elapsed = ((double) elapsed.tv_sec) * VISUAL_USEC_PER_SEC + elapsed.tv_usec;
+		usec_morph = ((double) morph->morphtime.tv_sec) * VISUAL_USEC_PER_SEC + morph->morphtime.tv_usec;
+
+		morph->rate = usec_elapsed / usec_morph;
+
+		if (morph->rate > 1.0)
+			morph->rate = 1;
+	}
+
+
+	return VISUAL_OK;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_morph.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,114 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_MORPH_H
+#define _LV_MORPH_H
+
+#include <libvisual/lv_palette.h>
+#include <libvisual/lv_plugin.h>
+#include <libvisual/lv_list.h>
+#include <libvisual/lv_video.h>
+#include <libvisual/lv_time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_MORPH(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisMorph))
+
+/**
+ * Morph morphing methods.
+ */
+typedef enum {
+	VISUAL_MORPH_MODE_SET,		/**< Morphing is done by a rate set,
+					  * nothing is automated here. */
+	VISUAL_MORPH_MODE_STEPS,	/**< Morphing is done by setting a number of steps,
+					  * the morph will be automated. */
+	VISUAL_MORPH_MODE_TIME		/**< Morphing is done by setting a target time when the morph should be done,
+					  * This is as well automated. */
+} VisMorphMode;
+
+typedef struct _VisMorph VisMorph;
+
+/**
+ * The VisMorph structure encapsulates the morph plugin and provides 
+ * abstract interfaces for morphing between actors, or rather between
+ * two video sources.
+ *
+ * Members in the structure shouldn't be accessed directly but instead
+ * it's adviced to use the methods provided.
+ *
+ * @see visual_morph_new
+ */
+struct _VisMorph {
+	VisObject	 object;	/**< The VisObject data. */
+	VisPluginData	*plugin;	/**< Pointer to the plugin itself. */
+	VisVideo	*dest;		/**< Destination video, this is where
+					 * the result of the morph gets drawn. */
+	float		 rate;		/**< The rate of morph, 0 draws the first video source
+					 * 1 the second video source, 0.5 is a 50/50, final
+					 * content depends on the plugin being used. */
+	VisPalette	 morphpal;	/**< Morph plugins can also set a palette for indexed
+					 * color depths. */
+	VisTime		 morphtime;	/**< Amount of time which the morphing should take. */
+	VisTimer	 timer;		/**< Private entry that holds the time elapsed from 
+					 * the beginning of the switch. */
+	int		 steps;		/**< Private entry that contains the number of steps
+					 * a morph suppose to take. */
+	int		 stepsdone;	/**< Private entry that contains the number of steps done. */
+
+	VisMorphMode	 mode;		/**< Private entry that holds the mode of morphing. */
+};
+
+VisPluginData *visual_morph_get_plugin (VisMorph *morph);
+
+VisList *visual_morph_get_list (void);
+const char *visual_morph_get_next_by_name (const char *name);
+const char *visual_morph_get_prev_by_name (const char *name);
+int visual_morph_valid_by_name (const char *name);
+
+VisMorph *visual_morph_new (const char *morphname);
+
+int visual_morph_realize (VisMorph *morph);
+
+int visual_morph_get_supported_depth (VisMorph *morph);
+
+int visual_morph_set_video (VisMorph *morph, VisVideo *video);
+int visual_morph_set_time (VisMorph *morph, VisTime *time);
+int visual_morph_set_rate (VisMorph *morph, float rate);
+int visual_morph_set_steps (VisMorph *morph, int steps);
+int visual_morph_set_mode (VisMorph *morph, VisMorphMode mode);
+
+VisPalette *visual_morph_get_palette (VisMorph *morph);
+
+int visual_morph_is_done (VisMorph *morph);
+
+int visual_morph_requests_audio (VisMorph *morph);
+
+int visual_morph_run (VisMorph *morph, VisAudio *audio, VisVideo *src1, VisVideo *src2);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_MORPH_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_object.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,207 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lv_log.h"
+#include "lv_object.h"
+
+
+/**
+ * @defgroup VisObject VisObject
+ * @{
+ */
+
+/**
+ * This function is a global VisListDestroyerFunc handler that unrefs VisObjects.
+ *
+ * @param data Pointer to the VisObject that needs to be unrefed
+ */
+void visual_object_list_destroyer (void *data)
+{
+	if (data == NULL)
+		return;
+
+	visual_object_unref (VISUAL_OBJECT (data));
+}
+
+/**
+ * Creates a new VisObject structure.
+ *
+ * @return A newly allocated VisObject, or NULL on failure.
+ */
+VisObject *visual_object_new ()
+{
+	VisObject *object;
+
+	object = visual_mem_new0 (VisObject, 1);
+
+	object->allocated = TRUE;
+
+	visual_object_ref (object);
+
+	return object;
+}
+
+/**
+ * Frees the VisObject. This does not destroy the object itself but only releases the memory it's using.
+ *
+ * @param object Pointer to a VisObject that needs to be freed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_OBJECT_NULL, -VISUAL_ERROR_OBJECT_NOT_ALLOCATED or error values
+ *	returned by visual_mem_free on failure.
+ */
+int visual_object_free (VisObject *object)
+{
+	visual_log_return_val_if_fail (object != NULL, -VISUAL_ERROR_OBJECT_NULL);
+	visual_log_return_val_if_fail (object->allocated == TRUE, -VISUAL_ERROR_OBJECT_NOT_ALLOCATED);
+
+	return visual_mem_free (object);
+}
+
+/**
+ * Destroys the VisObject. This does destruct the VisObject 
+ * by using the dtor function if it's set and also frees the memory
+ * it's using. It's valid to pass non allocated VisObjects,
+ * the function will recognize this by a flag that is set in the VisObject.
+ *
+ * @param object Pointer to a VisObject that needs to be destroyed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_OBJECT_NULL or error values returned byvisual_object_free on failure.
+ */
+int visual_object_destroy (VisObject *object)
+{
+	visual_log_return_val_if_fail (object != NULL, -VISUAL_ERROR_OBJECT_NULL);
+
+	if (object->dtor != NULL)
+		object->dtor (object);
+
+	if (object->allocated == TRUE)
+		return visual_object_free (object);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Initializes a VisObject for usage. This also ups the refcount by one, so this function really is for initial object
+ * creation.
+ *
+ * @param object Pointer to a VisObject that is initialized.
+ * @param allocated Flag to indicate if the VisObject itself is an allocated piece of memory.
+ * @param dtor The destructor function, that is used to destroy the VisObject when it loses all references or when it's
+ *	being destroyed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_OBJECT_NULL on failure.
+ */
+int visual_object_initialize (VisObject *object, int allocated, VisObjectDtorFunc dtor)
+{
+	visual_log_return_val_if_fail (object != NULL, -VISUAL_ERROR_OBJECT_NULL);
+
+	object->allocated = allocated;
+	object->dtor = dtor;
+
+	visual_object_ref (object);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Increases the reference counter for a VisObject.
+ *
+ * @param object Pointer to a VisObject in which the reference count is increased.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_OBJECT_NULL on failure.
+ */
+int visual_object_ref (VisObject *object)
+{
+	visual_log_return_val_if_fail (object != NULL, -VISUAL_ERROR_OBJECT_NULL);
+	
+	object->refcount++;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Decreases the reference counter for a VisObject. If the reference counter hits zero it will
+ * destruct the object using visual_object_destroy.
+ *
+ * @see visual_object_destroy
+ *
+ * @param object Pointer to a VisObject in which the reference count is decreased.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_OBJECT_NULL or error values returned by
+ *	visual_object_destroy on failure.
+ */
+int visual_object_unref (VisObject *object)
+{
+	visual_log_return_val_if_fail (object != NULL, -VISUAL_ERROR_OBJECT_NULL);
+	
+	object->refcount--;
+
+	/* No reference left, start dtoring of this VisObject */
+	if (object->refcount <= 0) {
+		object->refcount = 0;
+
+		return visual_object_destroy (object);
+	}
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the private data pointer to a VisObject.
+ *
+ * @param object Pointer to a VisObject to which the private data is set.
+ * @param priv Pointer to the private data that is set to the VisObject.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_OBJECT_NULL on failure.
+ */
+int visual_object_set_private (VisObject *object, void *priv)
+{
+	visual_log_return_val_if_fail (object != NULL, -VISUAL_ERROR_OBJECT_NULL);
+
+	object->priv = priv;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Retrieves the private data from a VisObject.
+ *
+ * @param object Pointer to a VisObject from which the private data is requested.
+ *
+ * @return Pointer to the private data or NULL.
+ */
+void *visual_object_get_private (VisObject *object)
+{
+	visual_log_return_val_if_fail (object != NULL, NULL);
+
+	return object->priv;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_object.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,86 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_OBJECT_H
+#define _LV_OBJECT_H
+
+#include <libvisual/lv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_OBJECT(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisObject))
+
+typedef struct _VisObject VisObject;
+
+/**
+ * The function defination for an object destructor. This can be assigned to any VisObject
+ * and is mostly used for internal usage or by support libraries. Keep in mind that this should not free
+ * the VisObject itself. This is done in the visual_object_destroy function itself.
+ *
+ * The destructor function should be safe to enter more than once, the object always contains the object
+ * however make sure that freed members are set to NULL and that it's checked.
+ *
+ * @arg object The VisObject that is passed to the destructor.
+ * 
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_OBJECT_DTOR_FAILED on failure.
+ */
+typedef int (*VisObjectDtorFunc)(VisObject *object);
+
+/**
+ * The VisObject structure contains all the VisObject housekeeping data like refcounting and a pointer
+ * to the VisObjectDtorFunc. Also it's possible to set private data on a VisObject.
+ *
+ * Nearly all libvisual structures inherent from a VisObject.
+ */
+struct _VisObject {
+	int			 allocated;	/**< Set to TRUE if this object is allocated and should be freed completely.
+						  * if set to FALSE, it will run the VisObjectDtorFunc but won't free the VisObject
+						  * itself when refcount reaches 0. */
+	int			 refcount;	/**< Contains the number of references to this object. */
+	VisObjectDtorFunc	 dtor;		/**< Pointer to the object destruction function. */
+
+	void			*priv;		/**< Private which can be used by application or plugin developers
+						 * depending on the sub class object. */
+};
+
+void visual_object_list_destroyer (void *data);
+
+VisObject *visual_object_new (void);
+int visual_object_free (VisObject *object);
+int visual_object_destroy (VisObject *object);
+
+int visual_object_initialize (VisObject *object, int allocated, VisObjectDtorFunc dtor);
+
+int visual_object_ref (VisObject *object);
+int visual_object_unref (VisObject *object);
+
+int visual_object_set_private (VisObject *object, void *priv);
+void *visual_object_get_private (VisObject *object);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_OBJECT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_palette.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,210 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lv_common.h"
+#include "lv_palette.h"
+
+static int palette_dtor (VisObject *object);
+
+static int palette_dtor (VisObject *object)
+{
+	VisPalette *pal = VISUAL_PALETTE (object);
+
+	if (pal->colors != NULL)
+		visual_palette_free_colors (pal);
+
+	pal->colors = NULL;
+
+	return VISUAL_OK;
+}
+
+/**
+ * @defgroup VisPalette VisPalette
+ * @{
+ */
+
+/**
+ * Creates a new VisPalette.
+ *
+ * @return A newly allocated VisPalette.
+ */
+VisPalette *visual_palette_new (int ncolors)
+{
+	VisPalette *pal;
+
+	pal = visual_mem_new0 (VisPalette, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (pal), TRUE, palette_dtor);
+
+	visual_palette_allocate_colors (pal, ncolors);
+
+	return pal;
+}
+
+/**
+ * Copies the colors from one VisPalette to another.
+ *
+ * @param dest Pointer to the destination VisPalette.
+ * @param src Pointer to the source VisPalette from which colors are copied into the destination VisPalette.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PALETTE_NULL or -VISUAL_ERROR_PALETTE_SIZE on failure.
+ */
+int visual_palette_copy (VisPalette *dest, VisPalette *src)
+{
+	visual_log_return_val_if_fail (dest != NULL, -VISUAL_ERROR_PALETTE_NULL);
+	visual_log_return_val_if_fail (src != NULL, -VISUAL_ERROR_PALETTE_NULL);
+	visual_log_return_val_if_fail (dest->ncolors == src->ncolors, -VISUAL_ERROR_PALETTE_SIZE);
+
+	visual_mem_copy (dest->colors, src->colors, sizeof (VisColor) * dest->ncolors);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Allocate an amount of colors for a VisPalette.
+ *
+ * @param pal Pointer to the VisPalette for which colors are allocated.
+ * @param ncolors The number of colors allocated for the VisPalette.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PALETTE_NULL on failure.
+ */
+int visual_palette_allocate_colors (VisPalette *pal, int ncolors)
+{
+	visual_log_return_val_if_fail (pal != NULL, -VISUAL_ERROR_PALETTE_NULL);
+
+	pal->colors = visual_mem_new0 (VisColor, ncolors);
+	pal->ncolors = ncolors;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Frees allocated colors from a VisPalette.
+ * 
+ * @param pal Pointer to the VisPalette from which colors need to be freed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PALETTE_NULL on failure.
+ */
+int visual_palette_free_colors (VisPalette *pal)
+{
+	visual_log_return_val_if_fail (pal != NULL, -VISUAL_ERROR_PALETTE_NULL);
+
+	if (pal->colors != NULL)
+		visual_mem_free (pal->colors);
+	
+	pal->colors = NULL;
+	pal->ncolors = 0;
+
+	return VISUAL_OK;
+}
+
+/**
+ * This function is capable of morphing from one palette to another.
+ *
+ * @param dest Pointer to the destination VisPalette, this is where the result of the morph
+ * 	  is put.
+ * @param src1 Pointer to a VisPalette that acts as the first source for the morph.
+ * @param src2 Pointer to a VisPalette that acts as the second source for the morph.
+ * @param rate Value that sets the rate of the morph, which is valid between 0 and 1.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PALETTE_NULL or -VISUAL_ERROR_PALETTE_SIZE on failure.
+ */
+int visual_palette_blend (VisPalette *dest, VisPalette *src1, VisPalette *src2, float rate)
+{
+	int i;
+
+	visual_log_return_val_if_fail (dest != NULL, -VISUAL_ERROR_PALETTE_NULL);
+	visual_log_return_val_if_fail (src1 != NULL, -VISUAL_ERROR_PALETTE_NULL);
+	visual_log_return_val_if_fail (src2 != NULL, -VISUAL_ERROR_PALETTE_NULL);
+	
+	if (src1->ncolors != src2->ncolors)
+		return -VISUAL_ERROR_PALETTE_SIZE;
+
+	if (dest->ncolors != src1->ncolors)
+		return -VISUAL_ERROR_PALETTE_SIZE;
+
+	for (i = 0; i < dest->ncolors; i++) {
+		dest->colors[i].r = src1->colors[i].r + ((src2->colors[i].r - src1->colors[i].r) * rate);
+		dest->colors[i].g = src1->colors[i].g + ((src2->colors[i].g - src1->colors[i].g) * rate);
+		dest->colors[i].b = src1->colors[i].b + ((src2->colors[i].b - src1->colors[i].b) * rate);
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Can be used to cycle through the colors of a VisPalette and blend between elements. The rate is from 0.0 to number of
+ * VisColors in the VisPalette. The VisColor is newly allocated so you have to unref it. The last VisColor in the VisPalette is
+ * morphed with the first.
+ *
+ * @param pal Pointer to the VisPalette in which the VisColors are cycled.
+ * @param rate Selection of the VisColor from the VisPalette, goes from 0.0 to number of VisColors in the VisPalette
+ * 	and morphs between colors if needed.
+ *
+ * @return A new VisColor, possibly a morph between two VisColors, NULL on failure.
+ */
+VisColor *visual_palette_color_cycle (VisPalette *pal, float rate)
+{
+	VisColor *color, *tmp1, *tmp2;
+	int irate = (int) rate;
+	unsigned char alpha;
+	float rdiff = rate - irate;
+
+	visual_log_return_val_if_fail (pal != NULL, NULL);
+	
+	irate = irate % pal->ncolors;
+	alpha = rdiff * 255;
+
+	color = visual_color_new ();
+
+	/* If rate is exactly an item, return that item */
+	if (rdiff == 0) {
+		visual_color_copy (color, &pal->colors[irate]);
+
+		return color;
+	}
+
+	tmp1 = &pal->colors[irate];
+
+	if (irate == pal->ncolors - 1)
+		tmp2 = &pal->colors[0];
+	else
+		tmp2 = &pal->colors[irate + 1];
+
+	color->r = ((alpha * (tmp1->r - tmp2->r) >> 8) + tmp2->r);
+	color->g = ((alpha * (tmp1->g - tmp2->g) >> 8) + tmp2->g);
+	color->b = ((alpha * (tmp1->b - tmp2->b) >> 8) + tmp2->b);
+
+	return color;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_palette.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,63 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_PALETTE_H
+#define _LV_PALETTE_H
+
+#include <libvisual/lv_common.h>
+#include <libvisual/lv_color.h>
+	
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_PALETTE(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisPalette))
+	
+typedef struct _VisPalette VisPalette;
+
+/**
+ * Data type to describe the palette for an 8 bits screen depth.
+ * 
+ * To access the RGB value of a certain indexed color simply do:
+ * pal->colors[index].(r,g,b)
+ *
+ * @see visual_palette_new
+ */
+struct _VisPalette {
+	VisObject	 object;	/**< The VisObject data. */
+	int		 ncolors;	/**< Number of color entries in palette. */
+	VisColor	*colors;	/**< Pointer to the colors. */
+};
+
+VisPalette *visual_palette_new (int ncolors);
+int visual_palette_copy (VisPalette *dest, VisPalette *src);
+int visual_palette_allocate_colors (VisPalette *pal, int ncolors);
+int visual_palette_free_colors (VisPalette *pal);
+int visual_palette_blend (VisPalette *dest, VisPalette *src1, VisPalette *src2, float rate);
+VisColor *visual_palette_color_cycle (VisPalette *pal, float rate);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_PALETTE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_param.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,1029 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lv_log.h"
+#include "lv_param.h"
+
+static int paramcontainer_dtor (VisObject *object);
+static int paramentry_dtor (VisObject *object);
+
+static int get_next_pcall_id (VisList *callbacks);
+
+static int paramcontainer_dtor (VisObject *object)
+{
+	VisParamContainer *paramcontainer = VISUAL_PARAMCONTAINER (object);
+
+	visual_list_destroy_elements (&paramcontainer->entries);
+
+	return VISUAL_OK;
+}
+
+static int paramentry_dtor (VisObject *object)
+{
+	VisParamEntry *param = VISUAL_PARAMENTRY (object);
+
+	if (param->string != NULL)
+		visual_mem_free (param->string);
+
+	if (param->name != NULL)
+		visual_mem_free (param->name);
+
+	if (param->objdata != NULL)
+		visual_object_unref (param->objdata);
+	
+	visual_palette_free_colors (&param->pal);
+
+	visual_list_destroy_elements (&param->callbacks);
+
+	param->string = NULL;
+	param->name = NULL;
+	param->objdata = NULL;
+
+	return VISUAL_OK;
+}
+
+static int get_next_pcall_id (VisList *callbacks)
+{
+	VisListEntry *le = NULL;
+	VisParamEntryCallback *pcall;
+	int found = FALSE;
+	int i;
+
+	/* Walk through all possible ids */
+	for (i = 0; i < VISUAL_PARAM_CALLBACK_ID_MAX; i++) {
+
+		found = FALSE;
+		/* Check all the callbacks if the id is used */
+		while ((pcall = visual_list_next (callbacks, &le)) != NULL) {
+		
+			/* Found the ID, break and get ready for the next iterate */
+			if (pcall->id == i) {
+				found = TRUE;
+
+				break;
+			}
+		}
+
+		/* The id has NOT been found, thus is an original, and we return this as the next id */
+		if (found == FALSE)
+			return i;
+	}
+
+	/* This is virtually impossible, or something very wrong is going ok, but no id seems to be left */
+	return -1;
+}
+
+
+/**
+ * @defgroup VisParam VisParam
+ * @{
+ */
+
+/**
+ * Creates a new VisParamContainer structure.
+ *
+ * @return A newly allocated VisParamContainer structure.
+ */
+VisParamContainer *visual_param_container_new ()
+{
+	VisParamContainer *paramcontainer;
+
+	paramcontainer = visual_mem_new0 (VisParamContainer, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (paramcontainer), TRUE, paramcontainer_dtor);
+
+	visual_list_set_destroyer (&paramcontainer->entries, visual_object_list_destroyer);
+
+	return paramcontainer;
+}
+
+/**
+ * Sets the eventqueue in the VisParamContainer, so events can be emitted on param changes.
+ *
+ * @param paramcontainer A pointer to the VisParamContainer to which the VisEventQueue needs to be set.
+ * @param eventqueue A Pointer to the VisEventQueue that is used for the events the VisParamContainer can emit.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_CONTAINER_NULL on failure.
+ */
+int visual_param_container_set_eventqueue (VisParamContainer *paramcontainer, VisEventQueue *eventqueue)
+{
+	visual_log_return_val_if_fail (paramcontainer != NULL, -VISUAL_ERROR_PARAM_CONTAINER_NULL);
+
+	paramcontainer->eventqueue = eventqueue;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Get the pointer to the VisEventQueue the VisParamContainer is emitting events to.
+ *
+ * @param paramcontainer A pointer to the VisParamContainer from which the VisEventQueue is requested.
+ * 
+ * @return Pointer to the VisEventQueue possibly NULL, NULL on failure.
+ */
+VisEventQueue *visual_param_container_get_eventqueue (VisParamContainer *paramcontainer)
+{
+	visual_log_return_val_if_fail (paramcontainer != NULL, NULL);
+
+	return paramcontainer->eventqueue;
+}
+
+/**
+ * Adds a VisParamEntry to a VisParamContainer.
+ *
+ * @param paramcontainer A pointer to the VisParamContainer in which the VisParamEntry is added.
+ * @param param A pointer to the VisParamEntry that is added to the VisParamContainer.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_CONTAINER_NULL, -VISUAL_ERROR_PARAM_NULL or
+ *	error values returned by visual_list_add () on failure.
+ */
+int visual_param_container_add (VisParamContainer *paramcontainer, VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (paramcontainer != NULL, -VISUAL_ERROR_PARAM_CONTAINER_NULL);
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	param->parent = paramcontainer;
+
+	/* On container add, we always set changed once, so vars can be synchronised in the plugin
+	 * it's event loop */
+	visual_param_entry_changed (param);
+
+	return visual_list_add (&paramcontainer->entries, param);
+}
+
+/**
+ * Adds a list of VisParamEntry elements, the list is terminated by an entry of type VISUAL_PARAM_ENTRY_TYPE_END.
+ * All the elements are reallocated, so this function can be used for static param lists.
+ *
+ * @param paramcontainer A pointer to the VisParamContainer in which the VisParamEntry elements are added.
+ * @param params A pointer to the VisParamEntry elements that are added to the VisParamContainer.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_CONTAINER_NULL or -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_container_add_many (VisParamContainer *paramcontainer, VisParamEntry *params)
+{
+	VisParamEntry *pnew;
+	int i = 0;
+
+	visual_log_return_val_if_fail (paramcontainer != NULL, -VISUAL_ERROR_PARAM_CONTAINER_NULL);
+	visual_log_return_val_if_fail (params != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	while (params[i].type != VISUAL_PARAM_ENTRY_TYPE_END) {
+		pnew = visual_param_entry_new (visual_param_entry_get_name (&params[i]));
+		visual_param_entry_set_from_param (pnew, &params[i]);
+
+		visual_param_container_add (paramcontainer, pnew);
+		
+		i++;
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Removes a VisParamEntry from the VisParamContainer by giving the name of the VisParamEntry that needs
+ * to be removed.
+ *
+ * @param paramcontainer A pointer to the VisParamContainer from which a VisParamEntry needs to be removed.
+ * @param name The name of the VisParamEntry that needs to be removed from the VisParamContainer.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_CONTAINER_NULL, -VISUAL_ERROR_NULL
+ *	or -VISUAL_ERROR_PARAM_NOT_FOUND on failure.
+ */
+int visual_param_container_remove (VisParamContainer *paramcontainer, const char *name)
+{
+	VisListEntry *le = NULL;
+	VisParamEntry *param;
+
+	visual_log_return_val_if_fail (paramcontainer != NULL, -VISUAL_ERROR_PARAM_CONTAINER_NULL);
+	visual_log_return_val_if_fail (name != NULL, -VISUAL_ERROR_NULL);
+	
+	while ((param = visual_list_next (&paramcontainer->entries, &le)) != NULL) {
+
+		if (strcmp (param->name, name) == 0) {
+			visual_list_delete (&paramcontainer->entries, &le);
+
+			return VISUAL_OK;
+		}
+	}
+
+	return -VISUAL_ERROR_PARAM_NOT_FOUND;
+}
+
+/**
+ * Clones the source VisParamContainer into the destination VisParamContainer. When an entry with a certain name
+ * already exists in the destination container, it will be overwritten with a new value.
+ *
+ * @param destcont A pointer to the VisParamContainer in which the VisParamEntry values are copied.
+ * @param srccont A pointer to the VisParamContainer from which the VisParamEntry values are copied.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_CONTAINER_NULL, on failure.
+ */
+int visual_param_container_copy (VisParamContainer *destcont, VisParamContainer *srccont)
+{
+	VisListEntry *le = NULL;
+	VisParamEntry *destparam;
+	VisParamEntry *srcparam;
+	VisParamEntry *tempparam;
+
+	visual_log_return_val_if_fail (destcont != NULL, -VISUAL_ERROR_PARAM_CONTAINER_NULL);
+	visual_log_return_val_if_fail (srccont != NULL, -VISUAL_ERROR_PARAM_CONTAINER_NULL);
+
+	while ((srcparam = visual_list_next (&srccont->entries, &le)) != NULL) {
+		tempparam = visual_param_container_get (destcont, visual_param_entry_get_name (srcparam));
+
+		/* Already exists, overwrite */
+		if (tempparam != NULL) {
+			visual_param_entry_set_from_param (tempparam, srcparam);
+			
+			continue;
+		}
+		
+		/* Does not yet exist, create a new entry */
+		destparam = visual_param_entry_new (visual_param_entry_get_name (srcparam));
+		visual_param_entry_set_from_param (destparam, srcparam);
+
+		visual_param_container_add (destcont, destparam);
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Copies matching VisParamEntry elements from srccont into destcont, matching on the name.
+ *
+ * @param destcont A pointer to the VisParamContainer in which the VisParamEntry values are copied.
+ * @param srccont A pointer to the VisParamContainer from which the VisParamEntry values are copied.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_CONTAINER_NULL, on failure.
+ */
+int visual_param_container_copy_match (VisParamContainer *destcont, VisParamContainer *srccont)
+{
+	VisListEntry *le = NULL;
+	VisParamEntry *destparam;
+	VisParamEntry *srcparam;
+
+	visual_log_return_val_if_fail (destcont != NULL, -VISUAL_ERROR_PARAM_CONTAINER_NULL);
+	visual_log_return_val_if_fail (srccont != NULL, -VISUAL_ERROR_PARAM_CONTAINER_NULL);
+
+	while ((destparam = visual_list_next (&destcont->entries, &le)) != NULL) {
+		srcparam = visual_param_container_get (srccont, visual_param_entry_get_name (destparam));
+
+		if (srcparam != NULL)
+			visual_param_entry_set_from_param (destparam, srcparam);
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Retrieve a VisParamEntry from a VisParamContainer by giving the name of the VisParamEntry that is requested.
+ *
+ * @param paramcontainer A pointer to the VisParamContainer from which a VisParamEntry is requested.
+ * @param name The name of the VisParamEntry that is requested from the VisParamContainer.
+ *
+ * @return Pointer to the VisParamEntry, or NULL.
+ */
+VisParamEntry *visual_param_container_get (VisParamContainer *paramcontainer, const char *name)
+{
+	VisListEntry *le = NULL;
+	VisParamEntry *param;
+
+	visual_log_return_val_if_fail (paramcontainer != NULL, NULL);
+	visual_log_return_val_if_fail (name != NULL, NULL);
+
+	while ((param = visual_list_next (&paramcontainer->entries, &le)) != NULL) {
+		param = le->data;
+		
+		if (strcmp (param->name, name) == 0)
+			return param;
+	}
+	
+	return NULL;
+}
+
+/**
+ * Creates a new VisParamEntry structure.
+ *
+ * @param name The name that is assigned to the VisParamEntry.
+ *
+ * @return A newly allocated VisParamEntry structure.
+ */
+VisParamEntry *visual_param_entry_new (char *name)
+{
+	VisParamEntry *param;
+
+	param = visual_mem_new0 (VisParamEntry, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (param), TRUE, paramentry_dtor);
+
+	visual_param_entry_set_name (param, name);
+	
+	visual_list_set_destroyer (&param->callbacks, visual_object_list_destroyer);
+
+	return param;
+}
+
+/**
+ * Adds a change notification callback, this shouldn't be used to get notificated within a plugin, but is for
+ * things like VisUI.
+ *
+ * @param param Pointer to the VisParamEntry to which a change notification callback is added.
+ * @param callback The notification callback, which is called on changes in the VisParamEntry.
+ * @param priv A private that can be used in the callback function.
+ *
+ * return callback id in the form of a positive value on succes,
+ * 	-VISUAL_ERROR_PARAM_NULL, -VISUAL_ERROR_PARAM_CALLBACK_NULL or
+ * 	-VISUAL_ERROR_PARAM_CALLBACK_TOO_MANY on failure.
+ */
+int visual_param_entry_add_callback (VisParamEntry *param, VisParamChangedCallbackFunc callback, void *priv)
+{
+	VisParamEntryCallback *pcall;
+	int id;
+
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+	visual_log_return_val_if_fail (callback != NULL, -VISUAL_ERROR_PARAM_CALLBACK_NULL);
+
+	id = get_next_pcall_id (&param->callbacks);
+
+	visual_log_return_val_if_fail (id >= 0, -VISUAL_ERROR_PARAM_CALLBACK_TOO_MANY);
+
+	pcall = visual_mem_new0 (VisParamEntryCallback, 1);
+
+	/* Do the VisObject initialization for the VisParamEntryCallback */
+	visual_object_initialize (VISUAL_OBJECT (pcall), TRUE, NULL);
+
+	pcall->id = id;
+	pcall->callback = callback;
+	visual_object_set_private (VISUAL_OBJECT (pcall), priv);
+	
+	visual_list_add (&param->callbacks, pcall);
+
+	return id;
+}
+
+/**
+ * Removes a change notification callback from the list of callbacks.
+ *
+ * @param param Pointer to the VisParamEntry from which a change notification callback is removed.
+ * @param id The callback ID that was given by the visual_param_entry_add_callback method.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_remove_callback (VisParamEntry *param, int id)
+{
+	VisListEntry *le = NULL;
+	VisParamEntryCallback *pcall;
+
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	while ((pcall = visual_list_next (&param->callbacks, &le)) != NULL) {
+		
+		if (id == pcall->id) {
+			visual_list_delete (&param->callbacks, &le);
+
+			visual_object_unref (VISUAL_OBJECT (pcall));
+
+			return VISUAL_OK;
+		}
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Notifies all the callbacks for the given VisParamEntry parameter.
+ *
+ * @param param Pointer to the VisParamEntry of which all the change notification
+ * 	callbacks need to be called.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_notify_callbacks (VisParamEntry *param)
+{
+	VisListEntry *le = NULL;
+	VisParamEntryCallback *pcall;
+	
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	while ((pcall = visual_list_next (&param->callbacks, &le)) != NULL)
+		pcall->callback (param, visual_object_get_private (VISUAL_OBJECT (pcall)));
+
+	return VISUAL_OK;
+}
+
+/**
+ * Checks if the VisParamEntry it's name is the given name.
+ *
+ * @param param Pointer to the VisParamEntry of which we want to check the name.
+ * @param name The name we want to check against.
+ *
+ * @return TRUE if the VisParamEntry is the one we requested, or FALSE if not.
+ */
+int visual_param_entry_is (VisParamEntry *param, const char *name)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	if (strcmp (param->name, name) == 0)
+		return TRUE;
+
+	return FALSE;
+}
+
+/**
+ * When called, emits an event in the VisParamContainer it's VisEventQueue when the VisEventQueue
+ * is set.
+ * 
+ * @param param Pointer to the VisParamEntry that is changed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_changed (VisParamEntry *param)
+{
+	VisEventQueue *eventqueue;
+
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	if (param->parent == NULL)
+		return VISUAL_OK;
+
+	eventqueue = param->parent->eventqueue;
+
+	if (eventqueue != NULL)
+		visual_event_queue_add_param (eventqueue, param);
+
+	visual_param_entry_notify_callbacks (param);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Retrieves the VisParamEntryType from a VisParamEntry.
+ *
+ * @param param Pointer to the VisParamEntry from which the VisParamEntryType is requested.
+ *
+ * @return The VisParamEntryType on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+VisParamEntryType visual_param_entry_get_type (VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	return param->type;
+}
+
+/**
+ * Compares two parameters with each other, When they are the same, TRUE is returned, if not FALSE.
+ * Keep in mind that FALSE is always returned for VISUAL_PARAM_ENTRY_TYPE_PALETTE and VISUAL_PARAM_ENTRY_TYPE_OBJECT.
+ *
+ * @param src1 Pointer to the first VisParamEntry for comparison.
+ * @param src2 Pointer to the second VisParamEntry for comparison.
+ *
+ * @return TRUE if the same, FALSE if not the same,
+ *	-VISUAL_ERROR_PARAM_NULL, -VISUAL_ERROR_PARAM_INVALID_TYPE or -VISUAL_ERROR_IMPOSSIBLE on failure.
+ */
+int visual_param_entry_compare (VisParamEntry *src1, VisParamEntry *src2)
+{
+	visual_log_return_val_if_fail (src1 != NULL, -VISUAL_ERROR_PARAM_NULL);
+	visual_log_return_val_if_fail (src2 != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	if (src1->type != src2->type)
+		return FALSE;
+
+	switch (src1->type) {
+		case VISUAL_PARAM_ENTRY_TYPE_NULL:
+			return TRUE;
+			
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_STRING:
+			if (!strcmp (src1->string, src2->string))
+				return TRUE;
+
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_INTEGER:
+			if (src1->numeric.integer == src2->numeric.integer)
+				return TRUE;
+			
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_FLOAT:
+			if (src1->numeric.floating == src2->numeric.floating)
+				return TRUE;
+
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_DOUBLE:
+			if (src1->numeric.doubleflt == src2->numeric.doubleflt)
+				return TRUE;
+
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_COLOR:
+			return visual_color_compare (&src1->color, &src2->color);
+			
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_PALETTE:
+			return FALSE;
+
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_OBJECT:
+			return FALSE;
+
+			break;
+
+		default:
+			visual_log (VISUAL_LOG_CRITICAL, "param type is not valid");
+
+			return -VISUAL_ERROR_PARAM_INVALID_TYPE;
+
+			break;
+	}
+
+	return -VISUAL_ERROR_IMPOSSIBLE;
+}
+
+/**
+ * Copies the value of the src param into the param. Also sets the param to the type of which the
+ * source param is.
+ *
+ * @param param Pointer to the VisParamEntry to which a parameter is set.
+ * @param src Pointer to the VisParamEntry from which the value is retrieved.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL, -VISUAL_ERROR_PARAM_INVALID_TYPE on failure.
+ */
+int visual_param_entry_set_from_param (VisParamEntry *param, VisParamEntry *src)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+	visual_log_return_val_if_fail (src != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	switch (src->type) {
+		case VISUAL_PARAM_ENTRY_TYPE_NULL:
+
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_STRING:
+			visual_param_entry_set_string (param, visual_param_entry_get_string (src));
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_INTEGER:
+			visual_param_entry_set_integer (param, visual_param_entry_get_integer (src));
+			
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_FLOAT:
+			visual_param_entry_set_float (param, visual_param_entry_get_float (src));
+
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_DOUBLE:
+			visual_param_entry_set_double (param, visual_param_entry_get_double (src));
+
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_COLOR:
+			visual_param_entry_set_color_by_color (param, visual_param_entry_get_color (src));
+
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_PALETTE:
+			visual_param_entry_set_palette (param, visual_param_entry_get_palette (src));
+
+			break;
+
+		case VISUAL_PARAM_ENTRY_TYPE_OBJECT:
+			visual_param_entry_set_object (param, visual_param_entry_get_object (src));
+
+			break;
+		
+		default:
+			visual_log (VISUAL_LOG_CRITICAL, "param type is not valid");
+
+			return -VISUAL_ERROR_PARAM_INVALID_TYPE;
+
+			break;
+	}
+	
+	return VISUAL_OK;
+}
+
+/**
+ * Set the name for a VisParamEntry.
+ *
+ * @param param Pointer to the VisParamEntry to which the name is set.
+ * @param name The name that is set to the VisParamEntry.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_set_name (VisParamEntry *param, char *name)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	if (param->name != NULL)
+		visual_mem_free (param->name);
+
+	param->name = NULL;
+	
+	if (name != NULL)
+		param->name = strdup (name);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the VisParamEntry to VISUAL_PARAM_ENTRY_TYPE_STRING and assigns the string given as argument to it.
+ *
+ * @param param Pointer to the VisParamEntry to which a parameter is set.
+ * @param string The string for this parameter.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_set_string (VisParamEntry *param, char *string)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	param->type = VISUAL_PARAM_ENTRY_TYPE_STRING;
+
+	if (string == NULL && param->string == NULL)
+		return VISUAL_OK;
+
+	if (string == NULL && param->string != NULL) {
+		visual_mem_free (param->string);
+		param->string = NULL;
+
+		visual_param_entry_changed (param);
+
+	} else if (param->string == NULL && string != NULL) {
+		param->string = strdup (string);
+
+		visual_param_entry_changed (param);
+
+	} else if (strcmp (string, param->string) != 0) {
+		visual_mem_free (param->string);
+		
+		param->string = strdup (string);
+
+		visual_param_entry_changed (param);
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the VisParamEntry to VISUAL_PARAM_ENTRY_TYPE_INTEGER and assigns the integer given as argument to it.
+ *
+ * @param param Pointer to the VisParamEntry to which a parameter is set.
+ * @param integer The integer value for this parameter.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_set_integer (VisParamEntry *param, int integer)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	param->type = VISUAL_PARAM_ENTRY_TYPE_INTEGER;
+
+	if (param->numeric.integer != integer) {
+		param->numeric.integer = integer;
+
+		visual_param_entry_changed (param);
+	}
+	
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the VisParamEntry to VISUAL_PARAM_ENTRY_TYPE_FLOAT and assigns the float given as argument to it.
+ *
+ * @param param Pointer to the VisParamEntry to which a parameter is set.
+ * @param floating The float value for this parameter.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_set_float (VisParamEntry *param, float floating)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	param->type = VISUAL_PARAM_ENTRY_TYPE_FLOAT;
+
+	if (param->numeric.floating != floating) {
+		param->numeric.floating = floating;
+
+		visual_param_entry_changed (param);
+	}
+	
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the VisParamEntry to VISUAL_PARAM_ENTRY_TYPE_DOUBLE and assigns the double given as argument to it.
+ *
+ * @param param Pointer to the VisParamEntry to which a parameter is set.
+ * @param doubleflt The double value for this parameter.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_set_double (VisParamEntry *param, double doubleflt)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	param->type = VISUAL_PARAM_ENTRY_TYPE_DOUBLE;
+
+	if (param->numeric.doubleflt != doubleflt) {
+		param->numeric.doubleflt = doubleflt;
+
+		visual_param_entry_changed (param);
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the VisParamEntry to VISUAL_PARAM_ENTRY_TYPE_COLOR and assigns the rgb values given as arguments to it.
+ *
+ * @param param Pointer to the VisParamEntry to which a parameter is set.
+ * @param r The red value for this color parameter.
+ * @param g The green value for this color parameter.
+ * @param b The blue value for this color parameter.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_set_color (VisParamEntry *param, uint8_t r, uint8_t g, uint8_t b)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	param->type = VISUAL_PARAM_ENTRY_TYPE_COLOR;
+
+	if (param->color.r != r || param->color.g != g || param->color.b != b) {
+		param->color.r = r;
+		param->color.g = g;
+		param->color.b = b;
+
+		visual_param_entry_changed (param);
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the VisParamEntry to VISUAL_PARAM_ENTRY_TYPE_COLOR and assigns the rgb values from the given VisColor as argument to it.
+ *
+ * @param param Pointer to the VisParamEntry to which a parameter is set.
+ * @param color Pointer to the VisColor from which the rgb values are copied into the parameter.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_set_color_by_color (VisParamEntry *param, VisColor *color)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	param->type = VISUAL_PARAM_ENTRY_TYPE_COLOR;
+
+	if (visual_color_compare (&param->color, color) == FALSE) {
+		visual_color_copy (&param->color, color);
+
+		visual_param_entry_changed (param);
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the VisParamEntry to VISUAL_PARAM_ENTRY_TYPE_PALETTE and assigns a VisPalette to the VisParamEntry.
+ * This function does not check if there is a difference between the prior set palette and the new one, and always
+ * emits the changed event. so watch out with usage.
+ *
+ * @param param Pointer to the VisParamEntry to which a parameter is set.
+ * @param pal Pointer to the VisPalette from which the palette data is retrieved for the VisParamEntry.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_set_palette (VisParamEntry *param, VisPalette *pal)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	param->type = VISUAL_PARAM_ENTRY_TYPE_PALETTE;
+
+	visual_palette_free_colors (&param->pal);
+	
+	if (pal != NULL) {
+		visual_palette_allocate_colors (&param->pal, pal->ncolors);
+		
+		visual_palette_copy (&param->pal, pal);
+	}
+
+	visual_param_entry_changed (param);
+	
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the VisParamEntry to VISUAL_PARAM_ENTRY_TYPE_OBJECT and assigns a VisObject to the VisParamEntry.
+ * With a VisObject VisParamEntry, the VisObject is referenced, not cloned.
+ *
+ * @param param Pointer to the VisParamEntry to which a parameter is set.
+ * @param object Pointer to the VisObject that is linked to the VisParamEntry.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_param_entry_set_object (VisParamEntry *param, VisObject *object)
+{
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	param->type = VISUAL_PARAM_ENTRY_TYPE_OBJECT;
+
+	if (param->objdata != NULL)
+		visual_object_unref (param->objdata);
+
+	param->objdata = object;
+
+	if (param->objdata != NULL)
+		visual_object_ref (param->objdata);
+
+	visual_param_entry_changed (param);
+	
+	return VISUAL_OK;
+}
+
+/**
+ * Get the name of the VisParamEntry.
+ *
+ * @param param Pointer to the VisParamEntry from which the name is requested.
+ * 
+ * @return The name of the VisParamEntry or NULL.
+ */
+char *visual_param_entry_get_name (VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (param != NULL, NULL);
+
+	return param->name;
+}
+
+/**
+ * Get the string parameter from a VisParamEntry.
+ *
+ * @param param Pointer to the VisParamEntry from which the string parameter is requested.
+ *
+ * @return The string parameter from the VisParamEntry or NULL.
+ */
+char *visual_param_entry_get_string (VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (param != NULL, NULL);
+
+	if (param->type != VISUAL_PARAM_ENTRY_TYPE_STRING) {
+		visual_log (VISUAL_LOG_WARNING, "Requesting string from a non string param");
+
+		return NULL;
+	}
+
+	return param->string;
+}
+
+/**
+ * Get the integer parameter from a VisParamEntry.
+ *
+ * @param param Pointer to the VisParamEntry from which the integer parameter is requested.
+ *
+ * @return The integer parameter from the VisParamEntry.
+ */
+int visual_param_entry_get_integer (VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (param != NULL, 0);
+
+	if (param->type != VISUAL_PARAM_ENTRY_TYPE_INTEGER)
+		visual_log (VISUAL_LOG_WARNING, "Requesting integer from a non integer param");
+
+	return param->numeric.integer;
+}
+
+/**
+ * Get the float parameter from a VisParamEntry.
+ *
+ * @param param Pointer to the VisParamEntry from which the float parameter is requested.
+ *
+ * @return The float parameter from the VisParamEntry.
+ */
+float visual_param_entry_get_float (VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (param != NULL, 0);
+
+	if (param->type != VISUAL_PARAM_ENTRY_TYPE_FLOAT)
+		visual_log (VISUAL_LOG_WARNING, "Requesting float from a non float param");
+
+	return param->numeric.floating;
+}
+
+/**
+ * Get the double parameter from a VisParamEntry.
+ *
+ * @param param Pointer to the VisParamEntry from which the double parameter is requested.
+ *
+ * @return The double parameter from the VisParamEntry.
+ */
+double visual_param_entry_get_double (VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (param != NULL, 0);
+
+	if (param->type != VISUAL_PARAM_ENTRY_TYPE_DOUBLE)
+		visual_log (VISUAL_LOG_WARNING, "Requesting double from a non double param");
+
+	return param->numeric.doubleflt;
+}
+
+/**
+ * Get the color parameter from a VisParamEntry.
+ *
+ * @param param Pointer to the VisParamEntry from which the color parameter is requested.
+ *
+ * @return Pointer to the VisColor parameter from the VisParamEntry. It's adviced to
+ *	use the VisColor that is returned as read only seen changing it directly won't emit events and
+ *	can cause synchronous problems between the plugin and the parameter system. Instead use the
+ *	visual_param_entry_set_color* methods to change the parameter value.
+ */
+VisColor *visual_param_entry_get_color (VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (param != NULL, NULL);
+
+	if (param->type != VISUAL_PARAM_ENTRY_TYPE_COLOR) {
+		visual_log (VISUAL_LOG_WARNING, "Requesting color from a non color param");
+
+		return NULL;
+	}
+
+	return &param->color;
+}
+
+/**
+ * Get the palette parameter from a VisParamEntry.
+ *
+ * @param param Pointer to the VisParamEntry from which the palette parameter is requested.
+ *
+ * @return Pointer to the VisPalette parameter from the VisParamEntry. The returned VisPalette
+ *	should be exclusively used as read only.
+ */
+VisPalette *visual_param_entry_get_palette (VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (param != NULL, NULL);
+
+	if (param->type != VISUAL_PARAM_ENTRY_TYPE_PALETTE) {
+		visual_log (VISUAL_LOG_WARNING, "Requested palette from a non palette param\n");
+
+		return NULL;
+	}
+
+	return &param->pal;
+}
+
+/**
+ * Get the object parameter from a VisParamEntry.
+ *
+ * @param param Pointer to the VisParamEntry from which the object parameter is requested.
+ *
+ * @return Pointer to the VisObject parameter from the VisParamEntry.
+ */
+VisObject *visual_param_entry_get_object (VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (param != NULL, NULL);
+
+	if (param->type != VISUAL_PARAM_ENTRY_TYPE_OBJECT) {
+		visual_log (VISUAL_LOG_WARNING, "Requested object from a non object param\n");
+
+		return NULL;
+	}
+
+	return param->objdata;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_param.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,174 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_PARAM_H
+#define _LV_PARAM_H
+
+#include <libvisual/lv_common.h>
+#include <libvisual/lv_color.h>
+#include <libvisual/lv_palette.h>
+#include <libvisual/lv_list.h>
+#include <libvisual/lv_event.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_PARAMCONTAINER(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisParamContainer))
+#define VISUAL_PARAMENTRY_CALLBACK(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisParamEntryCallback))
+#define VISUAL_PARAMENTRY(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisParamEntry))
+
+#define VISUAL_PARAM_LIST_ENTRY(name)			{ {}, NULL, name, VISUAL_PARAM_ENTRY_TYPE_NULL }
+#define VISUAL_PARAM_LIST_ENTRY_STRING(name, string)	{ {}, NULL, name, VISUAL_PARAM_ENTRY_TYPE_STRING, string, {0, 0, 0}}
+#define VISUAL_PARAM_LIST_ENTRY_INTEGER(name, val)	{ {}, NULL, name, VISUAL_PARAM_ENTRY_TYPE_INTEGER, NULL, {val, 0, 0}}
+#define VISUAL_PARAM_LIST_ENTRY_FLOAT(name, val)	{ {}, NULL, name, VISUAL_PARAM_ENTRY_TYPE_FLOAT, NULL, {0, val, 0}}
+#define VISUAL_PARAM_LIST_ENTRY_DOUBLE(name, val)	{ {}, NULL, name, VISUAL_PARAM_ENTRY_TYPE_DOUBLE, NULL, {0, 0, val}}
+#define VISUAL_PARAM_LIST_ENTRY_COLOR(name, r, g, b)	{ {}, NULL, name, VISUAL_PARAM_ENTRY_TYPE_COLOR, NULL, {0, 0, 0}, {{}, r, g, b, 0}}
+#define VISUAL_PARAM_LIST_END				{ {}, NULL, NULL, VISUAL_PARAM_ENTRY_TYPE_END }
+
+#define VISUAL_PARAM_CALLBACK_ID_MAX	2147483647
+
+/**
+ * Different types of parameters that can be used.
+ */
+typedef enum {
+	VISUAL_PARAM_ENTRY_TYPE_NULL,		/**< No parameter. */
+	VISUAL_PARAM_ENTRY_TYPE_STRING,		/**< String parameter. */
+	VISUAL_PARAM_ENTRY_TYPE_INTEGER,	/**< Integer parameter. */
+	VISUAL_PARAM_ENTRY_TYPE_FLOAT,		/**< Floating point parameter. */
+	VISUAL_PARAM_ENTRY_TYPE_DOUBLE,		/**< Double floating point parameter. */
+	VISUAL_PARAM_ENTRY_TYPE_COLOR,		/**< VisColor parameter. */
+	VISUAL_PARAM_ENTRY_TYPE_PALETTE,	/**< VisPalette parameter. */
+	VISUAL_PARAM_ENTRY_TYPE_OBJECT,		/**< VisObject parameter. */
+	VISUAL_PARAM_ENTRY_TYPE_END		/**< List end, and used as terminator for VisParamEntry lists. */
+} VisParamEntryType;
+
+typedef struct _VisParamContainer VisParamContainer;
+typedef struct _VisParamEntryCallback VisParamEntryCallback;
+typedef struct _VisParamEntry VisParamEntry;
+
+/**
+ * The param changed callback is used to be able to notify of changes within parameters. This should
+ * not be used within the plugin itself, instead use the event queue there. This is so it's possible to
+ * notify of changes outside the plugin. For example, this is needed by VisUI.
+ * 
+ * @arg param Pointer to the param that has been changed, and to which the callback was set.
+ * @arg priv Private argument, that can be set when adding the callback to the callback list.
+ */
+typedef void (*VisParamChangedCallbackFunc)(VisParamEntry *param, void *priv);
+
+
+/**
+ * Parameter container, is the container for a set of parameters.
+ *
+ * All members should never be accessed directly, instead methods should be used.
+ */
+struct _VisParamContainer {
+	VisObject	 object;	/**< The VisObject data. */
+	VisList		 entries;	/**< The list that contains all the parameters. */
+	VisEventQueue	*eventqueue;	/**< Pointer to an optional eventqueue to which events can be emitted
+					  * on parameter changes. */
+};
+
+/**
+ * A parameter callback entry, used for change notification callbacks.
+ */
+struct _VisParamEntryCallback {
+	VisObject		 	 object;	/**< The VisObject data. */
+	int				 id;		/**< Callback ID. */
+	VisParamChangedCallbackFunc	 callback;	/**< The param change callback function. */
+};
+
+/**
+ * A parameter entry, used for plugin parameters and such.
+ *
+ * All members should never be accessed directly, instead methods should be used.
+ */
+struct _VisParamEntry {
+	VisObject		 object;	/**< The VisObject data. */
+	VisParamContainer	*parent;	/**< Parameter container in which the param entry is encapsulated. */
+	char			*name;		/**< Parameter name. */
+	VisParamEntryType	 type;		/**< Parameter type. */
+
+	char			*string;	/**< String data. */
+
+	/* No union, we can't choose a member of the union using static initializers */
+	struct {
+		int		 integer;		/**< Integer data. */
+		float		 floating;		/**< Floating point data. */
+		double		 doubleflt;		/**< Double floating point data. */
+	} numeric;
+
+	VisColor		 color;		/**< VisColor data. */
+	VisPalette		 pal;		/**< VisPalette data. */
+	VisObject		*objdata;	/**< VisObject data for a VisObject parameter. */
+
+	VisList			 callbacks;	/**< The change notify callbacks. */
+};
+
+/* prototypes */
+VisParamContainer *visual_param_container_new (void);
+int visual_param_container_set_eventqueue (VisParamContainer *paramcontainer, VisEventQueue *eventqueue);
+VisEventQueue *visual_param_container_get_eventqueue (VisParamContainer *paramcontainer);
+
+int visual_param_container_add (VisParamContainer *paramcontainer, VisParamEntry *param);
+int visual_param_container_add_many (VisParamContainer *paramcontainer, VisParamEntry *params);
+int visual_param_container_remove (VisParamContainer *paramcontainer, const char *name);
+int visual_param_container_copy (VisParamContainer *destcont, VisParamContainer *srccont);
+int visual_param_container_copy_match (VisParamContainer *destcont, VisParamContainer *srccont);
+VisParamEntry *visual_param_container_get (VisParamContainer *paramcontainer, const char *name);
+
+VisParamEntry *visual_param_entry_new (char *name);
+int visual_param_entry_add_callback (VisParamEntry *param, VisParamChangedCallbackFunc callback, void *priv);
+int visual_param_entry_remove_callback (VisParamEntry *param, int id);
+int visual_param_entry_notify_callbacks (VisParamEntry *param);
+int visual_param_entry_is (VisParamEntry *param, const char *name);
+int visual_param_entry_compare (VisParamEntry *src1, VisParamEntry *src2);
+int visual_param_entry_changed (VisParamEntry *param);
+VisParamEntryType visual_param_entry_get_type (VisParamEntry *param);
+
+int visual_param_entry_set_from_param (VisParamEntry *param, VisParamEntry *src);
+int visual_param_entry_set_name (VisParamEntry *param, char *name);
+int visual_param_entry_set_string (VisParamEntry *param, char *string);
+int visual_param_entry_set_integer (VisParamEntry *param, int integer);
+int visual_param_entry_set_float (VisParamEntry *param, float floating);
+int visual_param_entry_set_double (VisParamEntry *param, double doubleflt);
+int visual_param_entry_set_color (VisParamEntry *param, uint8_t r, uint8_t g, uint8_t b);
+int visual_param_entry_set_color_by_color (VisParamEntry *param, VisColor *color);
+int visual_param_entry_set_palette (VisParamEntry *param, VisPalette *pal);
+int visual_param_entry_set_object (VisParamEntry *param, VisObject *object);
+
+char *visual_param_entry_get_name (VisParamEntry *param);
+char *visual_param_entry_get_string (VisParamEntry *param);
+int visual_param_entry_get_integer (VisParamEntry *param);
+float visual_param_entry_get_float (VisParamEntry *param);
+double visual_param_entry_get_double (VisParamEntry *param);
+VisColor *visual_param_entry_get_color (VisParamEntry *param);
+VisPalette *visual_param_entry_get_palette (VisParamEntry *param);
+VisObject *visual_param_entry_get_object (VisParamEntry *param);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_PARAM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_plugin.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,1088 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <dirent.h>
+
+#include "lvconfig.h"
+#include "lv_libvisual.h"
+#include "lv_plugin.h"
+#include "lv_log.h"
+#include "lv_mem.h"
+
+extern VisList *__lv_plugins;
+
+static int plugin_info_dtor (VisObject *object);
+static int plugin_ref_dtor (VisObject *object);
+static int plugin_environ_dtor (VisObject *object);
+static int plugin_dtor (VisObject *object);
+
+static int plugin_add_dir_to_list (VisList *list, const char *dir);
+static char *get_delim_node (const char *str, char delim, int index);
+
+static int plugin_info_dtor (VisObject *object)
+{
+	VisPluginInfo *pluginfo = VISUAL_PLUGININFO (object);
+
+	if (pluginfo->plugname != NULL)
+		visual_mem_free (pluginfo->plugname);
+
+	if (pluginfo->type != NULL)
+		visual_mem_free (pluginfo->type);
+
+	if (pluginfo->name != NULL)
+		visual_mem_free (pluginfo->name);
+
+	if (pluginfo->author != NULL)
+		visual_mem_free (pluginfo->author);
+
+	if (pluginfo->version != NULL)
+		visual_mem_free (pluginfo->version);
+
+	if (pluginfo->about != NULL)
+		visual_mem_free (pluginfo->about);
+
+	if (pluginfo->help != NULL)
+		visual_mem_free (pluginfo->help);
+
+	pluginfo->plugname = NULL;
+	pluginfo->type = NULL;
+	pluginfo->name = NULL;
+	pluginfo->author = NULL;
+	pluginfo->version = NULL;
+	pluginfo->about = NULL;
+	pluginfo->help = NULL;
+
+	return VISUAL_OK;
+}
+
+static int plugin_ref_dtor (VisObject *object)
+{
+	VisPluginRef *ref = VISUAL_PLUGINREF (object);
+
+	if (ref->file != NULL)
+		visual_mem_free (ref->file);
+
+	if (ref->usecount > 0)
+		visual_log (VISUAL_LOG_CRITICAL, "A plugin reference with %d instances has been destroyed.", ref->usecount);
+
+	if (ref->info != NULL)
+		visual_object_unref (VISUAL_OBJECT (ref->info));
+	
+	ref->file = NULL;
+	ref->info = NULL;
+
+	return VISUAL_OK;
+}
+
+static int plugin_environ_dtor (VisObject *object)
+{
+	VisPluginEnviron *enve = VISUAL_PLUGINENVIRON (object);
+
+	if (enve->environ != NULL)
+		visual_object_unref (enve->environ);
+
+	enve->environ = NULL;
+
+	return VISUAL_OK;
+}
+
+static int plugin_dtor (VisObject *object)
+{
+	VisPluginData *plugin = VISUAL_PLUGINDATA (object);
+
+	if (plugin->ref != NULL)	
+		visual_object_unref (VISUAL_OBJECT (plugin->ref));
+
+	if (plugin->params != NULL)
+		visual_object_unref (VISUAL_OBJECT (plugin->params));
+
+	visual_list_destroy_elements (&plugin->environ);	
+	
+	plugin->ref = NULL;
+	plugin->params = NULL;
+
+	return VISUAL_OK;
+}
+
+static char *get_delim_node (const char *str, char delim, int index)
+{
+	char *buf;
+	const char *start;
+	const char *end = str;
+	int i = 0;
+
+	do {
+		start = end;
+
+		end = strchr (start + 1, delim);
+
+		if (i == index) {
+			/* Last section doesn't contain a delim */
+			if (end == NULL)
+				end = str + strlen (str);
+			
+			/* Cut off the delim that is in front */
+			if (i > 0)
+				start++;
+			
+			break;
+		}
+
+		i++;
+
+	} while (end != NULL);
+
+	if (end == NULL)
+		return NULL;
+
+	buf = visual_mem_malloc0 ((end - start) + 1);
+	strncpy (buf, start, end - start);
+
+	return buf;
+}
+
+/**
+ * @defgroup VisPlugin VisPlugin
+ * @{
+ */
+
+/**
+ * Creates a new VisPluginInfo structure.
+ *
+ * @return A newly allocated VisPluginInfo
+ */
+VisPluginInfo *visual_plugin_info_new ()
+{
+	VisPluginInfo *pluginfo;
+
+	pluginfo = visual_mem_new0 (VisPluginInfo, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (pluginfo), TRUE, plugin_info_dtor);
+
+	return pluginfo;
+}
+
+/**
+ * Copies data from one VisPluginInfo to another, this does not copy everything
+ * but only things that are needed in the local copy for the plugin registry.
+ *
+ * @param dest Pointer to the destination VisPluginInfo in which some data is copied.
+ * @param src Pointer to the source VisPluginInfo from which some data is copied.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PLUGIN_INFO_NULL on failure.
+ */
+int visual_plugin_info_copy (VisPluginInfo *dest, VisPluginInfo *src)
+{
+	visual_log_return_val_if_fail (dest != NULL, -VISUAL_ERROR_PLUGIN_INFO_NULL);
+	visual_log_return_val_if_fail (src != NULL, -VISUAL_ERROR_PLUGIN_INFO_NULL);
+
+	visual_mem_copy (dest, src, sizeof (VisPluginInfo));
+
+	dest->plugname = strdup (src->plugname);
+	dest->type = strdup (src->type);
+	dest->name = strdup (src->name);
+	dest->author = strdup (src->author);
+	dest->version = strdup (src->version);
+	dest->about = strdup (src->about);
+	dest->help = strdup (src->help);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Pumps the queued events into the plugin it's event handler if it has one.
+ *
+ * @param plugin Pointer to a VisPluginData of which the events need to be pumped into
+ *	the handler.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PLUGIN_NULL or -VISUAL_ERROR_PLUGIN_NO_EVENT_HANDLER on failure.
+ */
+int visual_plugin_events_pump (VisPluginData *plugin)
+{
+	visual_log_return_val_if_fail (plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+
+	if (plugin->info->events != NULL) {
+		plugin->info->events (plugin, &plugin->eventqueue);
+
+		return VISUAL_OK;
+	}
+
+	return -VISUAL_ERROR_PLUGIN_NO_EVENT_HANDLER;
+}
+
+/**
+ * Gives the event queue from a VisPluginData. This queue needs to be used
+ * when you want to send events to the plugin.
+ *
+ * @see visual_plugin_events_pump
+ *
+ * @param plugin Pointer to the VisPluginData from which we want the queue.
+ *
+ * @return A pointer to the requested VisEventQueue or NULL on failure.
+ */
+VisEventQueue *visual_plugin_get_eventqueue (VisPluginData *plugin)
+{
+	visual_log_return_val_if_fail (plugin != NULL, NULL);
+
+	return &plugin->eventqueue;
+}
+
+/**
+ * Sets a VisUIWidget as top user interface widget for the plugin. When a VisUI
+ * tree is requested by a client, to render a configuration userinterface, this
+ * VisUIWidget is used as top widget.
+ *
+ * @param plugin Pointer to the VisPluginData to which we set the VisUIWidget as top widget.
+ * @param widget Pointer to the VisUIWidget that we use as top widget for the user interface.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PLUGIN_NULL on failure.
+ */
+int visual_plugin_set_userinterface (VisPluginData *plugin, VisUIWidget *widget)
+{
+	visual_log_return_val_if_fail (plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+
+	plugin->userinterface = widget;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Retrieves the VisUI top widget for the plugin.
+ *
+ * @param plugin Pointer to the VisPluginData of which we request the VisUIWidget that serves as top widget.
+ *
+ * @return Pointer to the VisUIWidget that serves as top widget, possibly NULL.
+ */
+VisUIWidget *visual_plugin_get_userinterface (VisPluginData *plugin)
+{
+	visual_log_return_val_if_fail (plugin != NULL, NULL);
+
+	return plugin->userinterface;
+}
+
+/**
+ * Gives the VisPluginInfo related to a VisPluginData.
+ *
+ * @param plugin The VisPluginData of which the VisPluginInfo is requested.
+ *
+ * @return The VisPluginInfo within the VisPluginData, or NULL on failure.
+ */
+VisPluginInfo *visual_plugin_get_info (VisPluginData *plugin)
+{
+	visual_log_return_val_if_fail (plugin != NULL, NULL);
+
+	return plugin->info;
+}
+
+/**
+ * Gives the VisParamContainer related to a VisPluginData.
+ *
+ * @param plugin The VisPluginData of which the VisParamContainer is requested.
+ *
+ * @return The VisParamContainer within the VisPluginData, or NULL on failure.
+ */
+VisParamContainer *visual_plugin_get_params (VisPluginData *plugin)
+{
+	visual_log_return_val_if_fail (plugin != NULL, NULL);
+
+	return plugin->params;
+}
+
+/**
+ * Gives the VisRandomContext related to a VisPluginData.
+ *
+ * @param plugin The VisPluginData of which the VisRandomContext is requested.
+ *
+ * @return The VisRandomContext within the VisPluginDAta, or NULL on failure.
+ */
+VisRandomContext *visual_plugin_get_random_context (VisPluginData *plugin)
+{
+	visual_log_return_val_if_fail (plugin != NULL, NULL);
+
+	return &plugin->random;
+}
+
+/**
+ * Retrieves the plugin specific part of a plugin.
+ *
+ * @see VISUAL_PLUGIN_ACTOR
+ * @see VISUAL_PLUGIN_INPUT
+ * @see VISUAL_PLUGIN_MORPH
+ * 
+ * @param plugin The pointer to the VisPluginData from which we want the plugin specific part.
+ *
+ * @return Void * pointing to the plugin specific part which can be cast.
+ */
+void *visual_plugin_get_specific (VisPluginData *plugin)
+{
+	VisPluginInfo *pluginfo;
+
+	visual_log_return_val_if_fail (plugin != NULL, NULL);
+
+	pluginfo = visual_plugin_get_info (plugin);
+	visual_log_return_val_if_fail (pluginfo != NULL, NULL);
+	
+	return pluginfo->plugin;
+}
+
+/**
+ * Creates a new VisPluginRef structure.
+ *
+ * The VisPluginRef contains data for the plugin loader.
+ *
+ * @return Newly allocated VisPluginRef.
+ */
+VisPluginRef *visual_plugin_ref_new ()
+{
+	VisPluginRef *ref;
+
+	ref = visual_mem_new0 (VisPluginRef, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (ref), TRUE, plugin_ref_dtor);
+
+	return ref;
+}
+
+/**
+ * Creates a new VisPluginData structure.
+ *
+ * @return A newly allocated VisPluginData.
+ */
+VisPluginData *visual_plugin_new ()
+{
+	VisPluginData *plugin;
+
+	plugin = visual_mem_new0 (VisPluginData, 1);
+	
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (plugin), TRUE, plugin_dtor);
+
+	plugin->params = visual_param_container_new ();
+
+	return plugin;
+}
+
+/**
+ * Gives a VisList that contains references to all the plugins in the registry.
+ *
+ * @see VisPluginRef
+ * 
+ * @return VisList of references to all the libvisual plugins.
+ */
+VisList *visual_plugin_get_registry ()
+{
+	return __lv_plugins;
+}
+
+/**
+ * Gives a newly allocated VisList with references for one plugin type.
+ *
+ * @see VisPluginRef
+ *
+ * @param pluglist Pointer to the VisList that contains the plugin registry.
+ * @param domain The plugin type that is filtered for.
+ *
+ * @return Newly allocated VisList that is a filtered version of the plugin registry.
+ */
+VisList *visual_plugin_registry_filter (VisList *pluglist, const char *domain)
+{
+	VisList *list;
+	VisListEntry *entry = NULL;
+	VisPluginRef *ref;
+
+	visual_log_return_val_if_fail (pluglist != NULL, NULL);
+
+	list = visual_list_new (visual_object_list_destroyer);
+
+	if (list == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "Cannot create a new list");
+
+		return NULL;
+	}
+
+	while ((ref = visual_list_next (pluglist, &entry)) != NULL) {
+		
+		if (visual_plugin_type_member_of (ref->info->type, domain)) {
+			visual_object_ref (VISUAL_OBJECT (ref));
+			
+			visual_list_add (list, ref);
+		}
+	}
+
+	return list;
+}
+
+/**
+ * Get the next plugin based on it's name.
+ *
+ * @see visual_plugin_registry_filter
+ * 
+ * @param list Pointer to the VisList containing the plugins. Adviced is to filter
+ *	this list first using visual_plugin_registry_filter.
+ * @param name Name of a plugin entry of which we want the next entry or NULL to get
+ * 	the first entry.
+ *
+ * @return The name of the next plugin or NULL on failure.
+ */
+const char *visual_plugin_get_next_by_name (VisList *list, const char *name)
+{
+	VisListEntry *entry = NULL;
+	VisPluginRef *ref;
+	int tagged = FALSE;
+
+	visual_log_return_val_if_fail (list != NULL, NULL);
+
+	while ((ref = visual_list_next (list, &entry)) != NULL) {
+		if (name == NULL)
+			return ref->info->plugname;
+
+		if (tagged == TRUE)
+			return ref->info->plugname;
+
+		if (strcmp (name, ref->info->plugname) == 0)
+			tagged = TRUE;
+	}
+
+	return NULL;
+}
+
+/**
+ * Get the previous plugin based on it's name.
+ *
+ * @see visual_plugin_registry_filter
+ * 
+ * @param list Pointer to the VisList containing the plugins. Adviced is to filter
+ *	this list first using visual_plugin_registry_filter.
+ * @param name Name of a plugin entry of which we want the previous entry or NULL to get
+ * 	the last entry.
+ *
+ * @return The name of the next plugin or NULL on failure.
+ */
+const char *visual_plugin_get_prev_by_name (VisList *list, const char *name)
+{
+	VisListEntry *entry = NULL;
+	VisPluginRef *ref, *pref = NULL;
+	
+	visual_log_return_val_if_fail (list != NULL, NULL);
+
+	if (name == NULL) {
+		ref = visual_list_get (list, visual_list_count (list) - 1);
+		
+		if (ref == NULL)
+			return NULL;
+		
+		return ref->info->plugname;
+	}
+
+	while ((ref = visual_list_next (list, &entry)) != NULL) {
+		if (strcmp (name, ref->info->plugname) == 0) {
+			if (pref != NULL)
+				return pref->info->plugname;
+			else
+				return NULL;
+		}
+
+		pref = ref;
+	}
+
+	return NULL;
+}
+
+static int plugin_add_dir_to_list (VisList *list, const char *dir)
+{
+	VisPluginRef **ref;
+	char temp[1024];
+	struct dirent **namelist;
+	int i, j, n, len;
+	int cnt = 0;
+
+	n = scandir (dir, &namelist, 0, alphasort);
+
+	if (n < 0)
+		return -1;
+
+	/* Free the . and .. entries */
+	visual_mem_free (namelist[0]);
+	visual_mem_free (namelist[1]);
+
+	for (i = 2; i < n; i++) {
+		ref = NULL;
+
+		snprintf (temp, 1023, "%s/%s", dir, namelist[i]->d_name);
+
+		len = strlen (temp);
+		if (len > 3 && (strncmp (&temp[len - 3], ".so", 3)) == 0)
+			ref = visual_plugin_get_references (temp, &cnt);
+
+		if (ref != NULL) {
+			for (j = 0; j < cnt; j++) 
+				visual_list_add (list, ref[j]);
+		
+			/* This is the pointer pointer pointer, not a ref itself */
+			visual_mem_free (ref);
+		}
+
+		visual_mem_free (namelist[i]);
+	}
+
+	visual_mem_free (namelist);
+
+	return 0;
+}
+
+/**
+ * Private function to unload a plugin. After calling this function the
+ * given argument is no longer usable.
+ *
+ * @param plugin Pointer to the VisPluginData that needs to be unloaded.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PLUGIN_NULL, -VISUAL_ERROR_PLUGIN_HANDLE_NULL or
+ *	-VISUAL_ERROR_PLUGIN_REF_NULL on failure.
+ */
+int visual_plugin_unload (VisPluginData *plugin)
+{
+	VisPluginRef *ref;
+
+	visual_log_return_val_if_fail (plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+
+	ref = plugin->ref;
+
+	/* Not loaded */
+	if (plugin->handle == NULL) {
+		visual_object_unref (VISUAL_OBJECT (plugin));
+
+		visual_log (VISUAL_LOG_CRITICAL, "Tried unloading a plugin that never has been loaded.");
+
+		return -VISUAL_ERROR_PLUGIN_HANDLE_NULL;
+	}
+	
+	if (plugin->realized == TRUE)
+		plugin->info->cleanup (plugin);
+
+	if (plugin->info->plugin != NULL)
+		visual_object_unref (VISUAL_OBJECT (plugin->info->plugin));
+
+	if (plugin->info != NULL)
+		visual_object_unref (VISUAL_OBJECT (plugin->info));
+
+	dlclose (plugin->handle);
+	plugin->info = NULL;
+
+	if (ref != NULL) {
+		if (ref->usecount > 0)
+			ref->usecount--;
+	}
+
+	visual_param_container_set_eventqueue (plugin->params, NULL);
+
+	visual_object_unref (VISUAL_OBJECT (plugin));
+	
+	return VISUAL_OK;
+}
+
+/**
+ * Private function to load a plugin.
+ *
+ * @param ref Pointer to the VisPluginRef containing information about
+ *	the plugin that needs to be loaded.
+ *
+ * @return A newly created and loaded VisPluginData.
+ */
+VisPluginData *visual_plugin_load (VisPluginRef *ref)
+{
+	VisPluginData *plugin;
+	VisTime time_;
+	VisPluginInfo *pluginfo;
+	VisPluginGetInfoFunc get_plugin_info;
+	void *handle;
+	int cnt;
+
+	visual_log_return_val_if_fail (ref != NULL, NULL);
+	visual_log_return_val_if_fail (ref->info != NULL, NULL);
+
+	/* Check if this plugin is reentrant */
+	if (ref->usecount > 0 && (ref->info->flags & VISUAL_PLUGIN_FLAG_NOT_REENTRANT)) {
+		visual_log (VISUAL_LOG_CRITICAL, "Cannot load plugin %s, the plugin is already loaded and is not reentrant.",
+				ref->info->plugname);
+
+		return NULL;
+	}
+
+	handle = dlopen (ref->file, RTLD_LAZY);
+
+	if (handle == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "Cannot load plugin: %s", dlerror ());
+
+		return NULL;
+	}
+
+	get_plugin_info = (VisPluginGetInfoFunc) dlsym (handle, "get_plugin_info");
+	
+	if (get_plugin_info == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "Cannot initialize plugin: %s", dlerror ());
+
+		dlclose (handle);
+
+		return NULL;
+	}
+
+	pluginfo = VISUAL_PLUGININFO (get_plugin_info (&cnt));
+
+	if (pluginfo == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "Cannot get plugin info while loading.");
+
+		dlclose (handle);
+		
+		return NULL;
+	}
+
+	plugin = visual_plugin_new ();
+	plugin->ref = ref;
+	plugin->info = &pluginfo[ref->index];
+
+	visual_object_ref (VISUAL_OBJECT (ref));
+
+	ref->usecount++;
+	plugin->realized = FALSE;
+	plugin->handle = handle;
+
+	/* Now the plugin is set up and ready to be realized, also random seed it's random context */
+	visual_time_get (&time_);
+	visual_random_context_set_seed (&plugin->random, time_.tv_usec);
+
+	return plugin;
+}
+
+/**
+ * Private function to realize the plugin. This initializes the plugin.
+ *
+ * @param plugin Pointer to the VisPluginData that needs to be realized.
+ * 
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PLUGIN_NULL or -VISUAL_ERROR_PLUGIN_ALREADY_REALIZED on failure.
+ */
+int visual_plugin_realize (VisPluginData *plugin)
+{
+	VisParamContainer *paramcontainer;
+
+	visual_log_return_val_if_fail (plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+
+	if (plugin->realized == TRUE)
+		return -VISUAL_ERROR_PLUGIN_ALREADY_REALIZED;
+
+	paramcontainer = visual_plugin_get_params (plugin);
+	visual_param_container_set_eventqueue (paramcontainer, &plugin->eventqueue);
+
+	plugin->info->init (plugin);
+	plugin->realized = TRUE;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Private function to create VisPluginRefs from plugins.
+ *
+ * @param pluginpath The full path and filename to the plugin of which a reference
+ *	needs to be obtained.
+ * @param count Int pointer that will contain the number of VisPluginRefs returned.
+ *
+ * @return The optionally newly allocated VisPluginRefs for the plugin.
+ */
+VisPluginRef **visual_plugin_get_references (const char *pluginpath, int *count)
+{
+	VisPluginRef **ref;
+	VisPluginInfo *plug_info;
+	VisPluginInfo *dup_info;
+	const char *plug_name;
+	VisPluginGetInfoFunc get_plugin_info;
+	void *handle;
+	int cnt = 1, i;
+
+	visual_log_return_val_if_fail (pluginpath != NULL, NULL);
+
+	handle = dlopen (pluginpath, RTLD_LAZY);
+	
+	if (handle == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "Cannot load plugin: %s", dlerror ());
+
+		return NULL;
+	}
+
+	get_plugin_info = (VisPluginGetInfoFunc) dlsym (handle, "get_plugin_info");
+
+	if (get_plugin_info == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "Cannot initialize plugin: %s", dlerror ());
+
+		dlclose (handle);
+
+		return NULL;
+	}
+
+	plug_info = VISUAL_PLUGININFO (get_plugin_info (&cnt));
+
+	if (plug_info == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "Cannot get plugin info");
+
+		dlclose (handle);
+		
+		return NULL;
+	}
+
+	/* FIXME we do leak the object when it fails the sanity check, tho
+	 * it is not always safe (with VERY stuff laying around) to unref it. */
+	
+	/* Check for API and struct size */
+	if (plug_info[0].struct_size != sizeof (VisPluginInfo) ||
+			plug_info[0].api_version != VISUAL_PLUGIN_API_VERSION) {
+
+		visual_log (VISUAL_LOG_CRITICAL, "Plugin %s is not compatible with version %s of libvisual",
+				pluginpath, visual_get_version ());
+
+		dlclose (handle);
+
+		return NULL;
+	}
+
+	ref = visual_mem_new0 (VisPluginRef *, cnt);
+	
+	for (i = 0; i < cnt; i++) {
+		ref[i] = visual_plugin_ref_new ();
+
+		dup_info = visual_plugin_info_new ();
+		visual_plugin_info_copy (dup_info, &plug_info[i]);
+		
+		ref[i]->index = i;
+		ref[i]->info = dup_info;
+		ref[i]->file = strdup (pluginpath);
+
+		visual_object_unref (plug_info[i].plugin);
+		visual_object_unref (VISUAL_OBJECT (&plug_info[i]));
+	}
+
+	dlclose (handle);
+	
+	*count = cnt;	
+
+	return ref;
+}
+
+/**
+ * Private function to create the complete plugin registry from a set of paths.
+ *
+ * @param paths A pointer list to a set of paths.
+ *
+ * @return A newly allocated VisList containing the plugin registry for the set of paths.
+ */
+VisList *visual_plugin_get_list (const char **paths)
+{
+	VisList *list;
+	int i = 0;
+
+	list = visual_list_new (visual_object_list_destroyer);
+	
+	while (paths[i] != NULL) {
+		if (plugin_add_dir_to_list (list, paths[i]) < 0) {
+			visual_log (VISUAL_LOG_WARNING, "Failed to add the %s directory to the plugin registry",
+					paths[i]);
+		}
+
+		i++;
+	}
+	
+	return list;
+}
+
+/**
+ * Private function to find a plugin in a plugin registry.
+ *
+ * @param list Pointer to a VisList containing VisPluginRefs in which
+ *	the search is done.
+ * @param name The name of the plugin we're looking for.
+ *
+ * @return The VisPluginRef for the plugin if found, or NULL when not found.
+ */
+VisPluginRef *visual_plugin_find (VisList *list, const char *name)
+{
+	VisListEntry *entry = NULL;
+	VisPluginRef *ref;
+
+	while ((ref = visual_list_next (list, &entry)) != NULL) {
+
+		if (ref->info->plugname == NULL)
+			continue;
+
+		if (strcmp (name, ref->info->plugname) == 0)
+			return ref;
+	}
+
+	return NULL;
+}
+
+/**
+ * Gives the VISUAL_PLUGIN_API_VERSION value for which the library is compiled.
+ * This can be used to check against for API/ABI compatibility check.
+ *
+ * @return The VISUAL_PLUGIN_API_VERSION define value.
+ */
+int visual_plugin_get_api_version ()
+{
+	return VISUAL_PLUGIN_API_VERSION;
+}
+
+/**
+ * Retrieves the VisSongInfo from a VisActorPlugin.
+ *
+ * @param actplugin Pointer to the VisActorPlugin from which the VisSongInfo is requested.
+ *
+ * @return The requested VisSongInfo or NULL on failure.
+ */
+VisSongInfo *visual_plugin_actor_get_songinfo (VisActorPlugin *actplugin)
+{
+	visual_log_return_val_if_fail (actplugin != NULL, NULL);
+
+	return &actplugin->songinfo;
+}
+
+/**
+ * Get the domain part from a plugin type string.
+ *
+ * @param type The type string.
+ *
+ * @return A newly allocated string containing the domain part of this plugin type, or NULL on failure.
+ */
+const char *visual_plugin_type_get_domain (const char *type)
+{
+	visual_log_return_val_if_fail (type != NULL, NULL);
+
+	return get_delim_node (type, ':', 0);
+}
+
+/**
+ * Get the package part from a plugin type string.
+ *
+ * @param type The type string.
+ *
+ * @return A newly allocated string containing the package part of this plugin type, or NULL on failure.
+ */
+const char *visual_plugin_type_get_package (const char *type)
+{
+	visual_log_return_val_if_fail (type != NULL, NULL);
+
+	return get_delim_node (type, ':', 1);
+}
+
+/**
+ * Get the type part from a plugin type string.
+ *
+ * @param type The type string.
+ *
+ * @return A newly allocated string containing the type part of this plugin type, or NULL on failure.
+ */
+const char *visual_plugin_type_get_type (const char *type)
+{
+	visual_log_return_val_if_fail (type != NULL, NULL);
+
+	return get_delim_node (type, ':', 2);
+}
+
+/**
+ * Get the depth of a plugin type string.
+ *
+ * @param type The type string.
+ *
+ * @return A VisPluginTypeDepth enum value that describes out of how many parts this plugin
+ *	type string consists, -VISUAL_ERROR_NULL on failure.
+ */
+VisPluginTypeDepth visual_plugin_type_get_depth (const char *type)
+{
+	int i = 0;
+
+	visual_log_return_val_if_fail (type != NULL, -VISUAL_ERROR_NULL);
+
+	while (i < VISUAL_PLUGIN_TYPE_DEPTH_TYPE) {
+		char *part;
+
+		part = get_delim_node (type, ':', i);
+
+		if (part == NULL)
+			break;
+
+		i++;
+
+		visual_mem_free (part);
+	}
+
+	return i;
+}
+
+/**
+ * Check if a certain plugin type string falls within the domain of the other.
+ *
+ * @param domain The domain in which the type string should fall.
+ * @param type The type string that is checked against the given domain.
+ *
+ * @return TRUE if it falls within the domain, FALSE when not, -VISUAL_ERROR_NULL on failure
+ */
+int visual_plugin_type_member_of (const char *domain, const char *type)
+{
+	char *comp1;
+	char *comp2;
+	int diff = 0;
+	int i = 0;
+
+	visual_log_return_val_if_fail (type != NULL, -VISUAL_ERROR_NULL);
+
+	while (i < visual_plugin_type_get_depth (domain)) {
+		comp1 = get_delim_node (domain, ':', i);
+		comp2 = get_delim_node (type, ':', i);
+
+		if (comp1 == NULL)
+			return FALSE;
+
+		if (comp2 == NULL)
+			return FALSE;
+
+		if (strcmp (comp1, comp2) != 0)
+			diff++;
+
+		visual_mem_free (comp1);
+		visual_mem_free (comp2);
+
+		i++;
+	}
+
+	if (diff > 0)
+		return FALSE;
+
+	return TRUE;
+}
+
+/**
+ * Creates a VisPluginEnviron structure.
+ *
+ * @param type The Environ type that is requested.
+ * @param envobj The VisObject connected to this Environ type.
+ *
+ * @return A newly allocated VisPluginEnviron, or NULL on failure.
+ */
+VisPluginEnviron *visual_plugin_environ_new (const char *type, VisObject *envobj)
+{
+	VisPluginEnviron *enve;
+
+	enve = visual_mem_new0 (VisPluginEnviron, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (enve), TRUE, plugin_environ_dtor);
+
+	enve->type = type;
+	enve->environ = envobj;
+	
+	return enve;
+}
+
+/**
+ * Adds a VisPluginEnviron to the plugin it's environment list.
+ *
+ * @param plugin Pointer to the VisPluginData to which the VisPluginEnviron is added.
+ * @param enve Pointer to the VisPluginEnviron that is added to the VisPluginData.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PLUGIN_NULL, -VISUAL_ERROR_PLUGIN_ENVIRON_NULL,
+ *	-VISUAL_ERROR_NULL or error values returned by visual_list_add() on failure.
+ */
+int visual_plugin_environ_add (VisPluginData *plugin, VisPluginEnviron *enve)
+{
+	visual_log_return_val_if_fail (plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+	visual_log_return_val_if_fail (enve != NULL, -VISUAL_ERROR_PLUGIN_ENVIRON_NULL);
+	visual_log_return_val_if_fail (enve->type != NULL, -VISUAL_ERROR_NULL);
+
+	visual_plugin_environ_remove (plugin, enve->type);
+		
+	return visual_list_add (&plugin->environ, enve);
+}
+
+/**
+ * Removes a VisPluginEnviron from the plugin it's environment list.
+ *
+ * @param plugin Pointer to the VisPluginData from which the VisPluginEnviron is removed.
+ * @param type The Environ type that is removed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_PLUGIN_NULL or -VISUAL_ERROR_NULL on failure.
+ */
+int visual_plugin_environ_remove (VisPluginData *plugin, const char *type)
+{
+	VisPluginEnviron *enve;
+	VisListEntry *le = NULL;
+
+	visual_log_return_val_if_fail (plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+	visual_log_return_val_if_fail (type != NULL, -VISUAL_ERROR_NULL);
+
+	while ((enve = visual_list_next (&plugin->environ, &le)) != NULL) {
+		
+		/* Remove from list */
+		if (strcmp (enve->type, type) == 0) {
+			visual_list_delete (&plugin->environ, &le);
+
+			visual_object_unref (VISUAL_OBJECT (enve));
+
+			return VISUAL_OK;
+		}
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Retrieves a VisPluginEnviron from the plugin it's environment list.
+ *
+ * @param plugin Pointer to the VisPluginData from which the VisPluginEnviron is requested.
+ * @param type The Environ type that is requested.
+ *
+ * @return The requested VisPluginEnviron it's environ specific VisObject, or NULL on failure
+ */
+VisObject *visual_plugin_environ_get (VisPluginData *plugin, const char *type)
+{
+	VisPluginEnviron *enve;
+	VisListEntry *le = NULL;
+	
+	visual_log_return_val_if_fail (plugin != NULL, NULL);
+	visual_log_return_val_if_fail (type != NULL, NULL);
+
+	while ((enve = visual_list_next (&plugin->environ, &le)) != NULL) {
+		
+		if (strcmp (enve->type, type) == 0)
+			return enve->environ;
+	}
+
+	return NULL;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_plugin.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,509 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_PLUGIN_H
+#define _LV_PLUGIN_H
+
+#include <libvisual/lv_video.h>
+#include <libvisual/lv_audio.h>
+#include <libvisual/lv_palette.h>
+#include <libvisual/lv_list.h>
+#include <libvisual/lv_songinfo.h>
+#include <libvisual/lv_event.h>
+#include <libvisual/lv_param.h>
+#include <libvisual/lv_ui.h>
+#include <libvisual/lv_random.h>
+#include <libvisual/lv_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_PLUGINREF(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisPluginRef))
+#define VISUAL_PLUGININFO(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisPluginInfo))
+#define VISUAL_PLUGINDATA(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisPluginData))
+#define VISUAL_PLUGINENVIRON(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisPluginEnviron))
+	
+#define VISUAL_PLUGIN_ACTOR(obj)			(VISUAL_CHECK_CAST ((obj), VISUAL_PLUGIN_TYPE_ACTOR_ENUM, VisActorPlugin))
+#define VISUAL_PLUGIN_INPUT(obj)			(VISUAL_CHECK_CAST ((obj), VISUAL_PLUGIN_TYPE_INPUT_ENUM, VisInputPlugin))
+#define VISUAL_PLUGIN_MORPH(obj)			(VISUAL_CHECK_CAST ((obj), VISUAL_PLUGIN_TYPE_MORPH_ENUM, VisMorphPlugin))
+#define VISUAL_PLUGIN_TRANSFORM(obj)			(VISUAL_CHECK_CAST ((obj), VISUAL_PLUGIN_TYPE_TRANSFORM_ENUM, VisTransformPlugin))
+
+/**
+ * Indicates at which version the plugin API is.
+ */
+#define VISUAL_PLUGIN_API_VERSION	2
+
+/**
+ * Type defination that should be used in plugins to set the plugin type for a NULL plugin.
+ */
+#define VISUAL_PLUGIN_TYPE_NULL		"Libvisual:core:null"
+/**
+ * Type defination that should be used in plugins to set the plugin type for an actor plugin.
+ */
+#define VISUAL_PLUGIN_TYPE_ACTOR	"Libvisual:core:actor"
+/**
+ * Type defination that should be used in plugins to set the plugin type for an input  plugin.
+ */
+#define VISUAL_PLUGIN_TYPE_INPUT	"Libvisual:core:input"
+/**
+ * Type defination that should be used in plugins to set the plugin type for a morph plugin.
+ */
+#define VISUAL_PLUGIN_TYPE_MORPH	"Libvisual:core:morph"
+/**
+ * Type defination that should be used in plugins to set the plugin type for a transform plugin.
+ */
+#define VISUAL_PLUGIN_TYPE_TRANSFORM	"Libvisual:core:transform"
+	
+/**
+ * Enumerate to define the plugin type. Especially used
+ * within the VisPlugin system and for type checking within the core library itself.
+ *
+ * For plugin type defination use the VISUAL_PLUGIN_TYPE_NULL, VISUAL_PLUGIN_TYPE_ACTOR
+ * VISUAL_PLUGIN_TYPE_INPUT or VISUAL_PLUGIN_TYPE_MORPH defines that contain the domain string.
+ *
+ * There are three different plugins being:
+ * 	-# Actor plugins: These are the actual
+ * 	visualisation plugins.
+ * 	-# Input plugins: These can be used to obtain
+ * 	PCM data through, for example different sound servers.
+ * 	-# Morph plugins: These are capable of morphing
+ * 	between different plugins.
+ * 	-# Transform plugins: These are capable of transforming a video or palette
+ * 	into something new.
+ */
+typedef enum {
+	VISUAL_PLUGIN_TYPE_NULL_ENUM,		/**< Used when there is no plugin. */
+	VISUAL_PLUGIN_TYPE_ACTOR_ENUM,		/**< Used when the plugin is an actor plugin. */
+	VISUAL_PLUGIN_TYPE_INPUT_ENUM,		/**< Used when the plugin is an input plugin. */
+	VISUAL_PLUGIN_TYPE_MORPH_ENUM,		/**< Used when the plugin is a morph plugin. */
+	VISUAL_PLUGIN_TYPE_TRANSFORM_ENUM	/**< Used when the plugin is a transform plugin. */
+} VisPluginType;
+
+/**
+ * Enumerate to define the plugin flags. Plugin flags can be used to
+ * define some of the plugin it's behavior.
+ */
+typedef enum {
+	VISUAL_PLUGIN_FLAG_NONE			= 0,	/**< Used to set no flags. */
+	VISUAL_PLUGIN_FLAG_NOT_REENTRANT	= 1,	/**< Used to tell the plugin loader that this plugin
+							  * is not reentrant, and can be loaded only once. */
+	VISUAL_PLUGIN_FLAG_SPECIAL		= 2	/**< Used to tell the plugin loader that this plugin has
+							  * special purpose, like the GdkPixbuf plugin, or a webcam
+							  * plugin. */
+} VisPluginFlags;
+
+/**
+ * Enumerate to check the depth of the type wildcard/defination used, used together with the visual_plugin_type functions.
+ */
+typedef enum {
+	VISUAL_PLUGIN_TYPE_DEPTH_NONE		= 0,	/**< No type found.*/
+	VISUAL_PLUGIN_TYPE_DEPTH_DOMAIN		= 1,	/**< Only domain in type. */
+	VISUAL_PLUGIN_TYPE_DEPTH_PACKAGE	= 2,	/**< Domain and package in type. */
+	VISUAL_PLUGIN_TYPE_DEPTH_TYPE		= 3,	/**< Domain, package and type found in type. */
+} VisPluginTypeDepth;
+
+typedef struct _VisPluginRef VisPluginRef;
+typedef struct _VisPluginInfo VisPluginInfo;
+typedef struct _VisPluginData VisPluginData;
+typedef struct _VisPluginEnviron VisPluginEnviron;
+
+typedef struct _VisActorPlugin VisActorPlugin;
+typedef struct _VisInputPlugin VisInputPlugin;
+typedef struct _VisMorphPlugin VisMorphPlugin;
+typedef struct _VisTransformPlugin VisTransformPlugin;
+
+/* Actor plugin methods */
+
+/**
+ * An actor plugin needs this signature for the requisition function. The requisition function
+ * is used to determine the size required by the plugin for a given width/height value.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ * @arg width Pointer to an int containing the width requested, will be altered to the nearest
+ * 	supported width.
+ * @arg height Pointer to an int containing the height requested, will be altered to the nearest
+ * 	supported height.
+ *
+ * @return 0 on succes -1 on error.
+ */
+typedef int (*VisPluginActorRequisitionFunc)(VisPluginData *plugin, int *width, int *height);
+
+/**
+ * An actor plugin needs this signature for the palette function. The palette function
+ * is used to retrieve the desired palette from the plugin.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ *
+ * @return Pointer to the VisPalette used by the plugin, this should be a VisPalette with 256
+ *	VisColor entries, NULL is also allowed to be returned.
+ */
+typedef VisPalette *(*VisPluginActorPaletteFunc)(VisPluginData *plugin);
+
+/**
+ * An actor plugin needs this signature for the render function. The render function
+ * is used to render the frame for the visualisation.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ * @arg video Pointer to the VisVideo containing all information about the display surface.
+ *	Params like height and width won't suddenly change, this is always notified as an event
+ *	so the plugin can adjust to the new dimension.
+ * @arg audio Pointer to the VisAudio containing all the data regarding the current audio sample.
+ *
+ * @return 0 on succes -1 on error.
+ */
+typedef int (*VisPluginActorRenderFunc)(VisPluginData *plugin, VisVideo *video, VisAudio *audio);
+
+/* Input plugin methods */
+
+/**
+ * An input plugin needs this signature for the sample upload function. The sample upload function
+ * is used to retrieve sample information when a input is being used to retrieve the
+ * audio sample.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ * @arg audio Pointer to the VisAudio in which the new sample data is set.
+ *
+ * @return 0 on succes -1 on error.
+ */
+typedef int (*VisPluginInputUploadFunc)(VisPluginData *plugin, VisAudio *audio);
+
+/* Morph plugin methods */
+
+/**
+ * A morph plugin needs this signature for the palette function. The palette function
+ * is used to give a palette for the morph. The palette function isn't mandatory and the
+ * VisMorph system will interpolate between the two palettes in VISUAL_VIDEO_DEPTH_8BIT when
+ * a palette function isn't set.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ * @arg rate A float between 0.0 and 1.0 that tells how far the morph has proceeded.
+ * @arg audio Pointer to the VisAudio containing all the data regarding the current audio sample.
+ * @arg pal A pointer to the target VisPalette in which the morph between the two palettes is saved. Should have
+ * 	256 VisColor entries.
+ * @arg src1 A pointer to the first VisVideo source.
+ * @arg src2 A pointer to the second VisVideo source.
+ *
+ * @return 0 on succes -1 on error.
+ */
+typedef int (*VisPluginMorphPaletteFunc)(VisPluginData *plugin, float rate, VisAudio *audio, VisPalette *pal,
+		VisVideo *src1, VisVideo *src2);
+
+/**
+ * A morph plugin needs this signature for the apply function. The apply function
+ * is used to execute a morph between two VisVideo sources. It's the 'render' function of
+ * the morph plugin and here is the morphing done.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ * @arg rate A float between 0.0 and 1.0 that tells how far the morph has proceeded.
+ * @arg audio Pointer to the VisAudio containing all the data regarding the current audio sample.
+ * @arg src1 A pointer to the first VisVideo source.
+ * @arg src2 A pointer to the second VisVideo source.
+ *
+ * @return 0 on succes -1 on error.
+ */
+typedef int (*VisPluginMorphApplyFunc)(VisPluginData *plugin, float rate, VisAudio *audio, VisVideo *dest,
+		VisVideo *src1, VisVideo *src2);
+
+/* Transform plugin methodes */
+
+/**
+ * A transform plugin needs this signature to transform VisPalettes.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ * @arg pal Pointer to the VisPalette that is to be morphed.
+ *	Only 256 entry VisPalettes have to be supported.
+ * @arg audio Optionally a pointer to the VisAudio, when requested.
+ *
+ * @return 0 on succes -1 on error.
+ */
+typedef int (*VisPluginTransformPaletteFunc)(VisPluginData *plugin, VisPalette *pal, VisAudio *audio);
+
+/**
+ * A transform plugin needs this signature to transform VisVideos.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ * @arg video Pointer to the VisVideo that needs to be transformed.
+ * @arg audio Optionally a pointer to the VisAudio, when requested.
+ *
+ * @return 0 on succes -1 on error.
+ */
+typedef int (*VisPluginTransformVideoFunc)(VisPluginData *plugin, VisVideo *video, VisAudio *audio);
+
+/* Plugin standard get_plugin_info method */
+/**
+ * This is the signature for the 'get_plugin_info' function every libvisual plugin needs to have. The 
+ * 'get_plugin_info' function provides libvisual plugin data and all the detailed information regarding
+ * the plugin. This function is compulsory without it libvisual won't load the plugin.
+ *
+ * @arg count An int pointer in which the number of VisPluginData entries within the plugin. Plugins can have
+ * 	multiple 'features' and thus the count is needed.
+ *
+ * @return Pointer to the VisPluginInfo array which contains information about the plugin.
+ */
+typedef const VisPluginInfo *(*VisPluginGetInfoFunc)(int *count);
+
+/* Standard plugin methods */
+
+/**
+ * Every libvisual plugin that is loaded by the libvisual plugin loader needs this signature for it's
+ * intialize function.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ *
+ * @return 0 on succes -1 on error.
+ */
+typedef int (*VisPluginInitFunc)(VisPluginData *plugin);
+
+/**
+ * Every libvisual plugin that is loaded by the libvisual plugin loader needs this signature for it's
+ * cleanup function.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ *
+ * @return 0 on succes -1 on error.
+ */
+typedef int (*VisPluginCleanupFunc)(VisPluginData *plugin);
+
+/**
+ * This is the signature for the event handler within libvisual plugins. An event handler is not mandatory because
+ * it has no use in some plugin classes but some plugin types require it nonetheless.
+ *
+ * @arg plugin Pointer to the VisPluginData instance structure.
+ * @arg events Pointer to the VisEventQueue that might contain events that need to be handled.
+ *
+ * @return 0 on succes -1 on error.
+ */
+typedef int (*VisPluginEventsFunc)(VisPluginData *plugin, VisEventQueue *events);
+
+/**
+ * The VisPluginRef data structure contains information about the plugins
+ * and does refcounting. It is also used as entries in the plugin registry.
+ */
+struct _VisPluginRef {
+	VisObject		 object;	/**< The VisObject data. */	
+
+	char			*file;		/**< The file location of the plugin. */
+	int			 index;		/**< Contains the index number for the entry in the VisPluginInfo table. */
+	int			 usecount;	/**< The use count, this indicates how many instances are loaded. */
+	VisPluginInfo		*info;		/**< A copy of the VisPluginInfo structure. */
+};
+
+/**
+ * The VisPluginInfo data structure contains information about a plugin
+ * and is filled within the plugin itself.
+ */
+struct _VisPluginInfo {
+	VisObject		 object;	/**< The VisObject data. */
+
+	uint32_t		 struct_size;	/**< Struct size, should always be set for compatability checks. */
+	uint32_t		 api_version;	/**< API version, compile plugins always with .api_version = VISUAL_PLUGIN_API_VERSION. */
+	char			*type;		/**< Plugin type, in the format of "domain:package:type", as example,
+						 * this could be "Libvisual:core:actor". It's adviced to use the defination macros here
+						 * instead of filling in the string yourself. */
+	char			*plugname;	/**< The plugin name as it's saved in the registry. */
+
+	char			*name;		/**< Long name */
+	char			*author;	/**< Author */
+	char			*version;	/**< Version */
+	char			*about;		/**< About */
+	char			*help;		/**< Help */
+
+	VisPluginInitFunc	 init;		/**< The standard init function, every plugin has to implement this. */
+	VisPluginCleanupFunc	 cleanup;	/**< The standard cleanup function, every plugin has to implement this. */
+	VisPluginEventsFunc	 events;	/**< The standard event function, implementation is optional. */
+
+	int			 flags;		/**< Plugin flags from the VisPluginFlags enumerate. */
+
+	VisObject		*plugin;	/**< Pointer to the plugin specific data structures. */
+};
+
+/**
+ * The VisPluginData structure is the main plugin structure, every plugin
+ * is encapsulated in this.
+ */
+struct _VisPluginData {
+	VisObject		 object;	/**< The VisObject data. */
+
+	VisPluginRef		*ref;		/**< Pointer to the plugin references corresponding to this VisPluginData. */
+
+	VisPluginInfo		*info;		/**< Pointer to the VisPluginInfo that is obtained from the plugin. */
+
+	VisEventQueue		 eventqueue;	/**< The plugin it's VisEventQueue for queueing events. */
+	VisParamContainer	*params;	/**< The plugin it's VisParamContainer in which VisParamEntries can be placed. */
+	VisUIWidget		*userinterface;	/**< The plugin it's top level VisUIWidget, this acts as the container for the
+						  * rest of the user interface. */
+
+	int			 plugflags;	/**< Plugin flags, currently unused but will be used in the future. */
+
+	VisRandomContext	 random;	/**< Pointer to the plugin it's private random context. It's highly adviced to use
+						  * the plugin it's randomize functions. The reason is so more advanced apps can
+						  * semi reproduce visuals. */
+
+	int			 realized;	/**< Flag that indicates if the plugin is realized. */
+	void			*handle;	/**< The dlopen handle */
+	VisList			 environ;	/**< Misc environment specific data. */
+};
+
+/**
+ * The VisPluginEnviron is used to setup a pre realize/init environment for plugins.
+ * Some types of plugins might need this internally and thus this system provides this function.
+ */
+struct _VisPluginEnviron {
+	VisObject		 object;	/**< The VisObject data. */
+	const char		*type;		/**< Almost the same as _VisPluginInfo.type. */
+	VisObject		*environ;	/**< VisObject that contains environ specific data. */
+};
+
+/**
+ * The VisActorPlugin structure is the main data structure
+ * for the actor (visualisation) plugin.
+ *
+ * The actor plugin is the visualisation plugin.
+ */
+struct _VisActorPlugin {
+	VisObject			 object;	/**< The VisObject data. */
+	VisPluginActorRequisitionFunc	 requisition;	/**< The requisition function. This is used to
+							 * get the desired VisVideo surface size of the plugin. */
+	VisPluginActorPaletteFunc	 palette;	/**< Used to retrieve the desired palette from the plugin. */
+	VisPluginActorRenderFunc	 render;	/**< The main render loop. This is called to draw a frame. */
+
+	VisSongInfo			 songinfo;	/**< Pointer to VisSongInfo that contains information about
+							 *the current playing song. This can be NULL. */
+
+	int				 depth;		/**< The depth flag for the VisActorPlugin. This contains an ORred
+							  * value of depths that are supported by the plugin. */
+};
+
+/**
+ * The VisInputPlugin structure is the main data structure
+ * for the input plugin.
+ *
+ * The input plugin is used to retrieve PCM samples from
+ * certain sources.
+ */
+struct _VisInputPlugin {
+	VisObject			 object;	/**< The VisObject data. */
+	VisPluginInputUploadFunc	 upload;	/**< The sample upload function. This is the main function
+							  * of the plugin which uploads sample data into
+							  * libvisual. */
+};
+
+/**
+ * The VisMorphPlugin structure is the main data structure
+ * for the morph plugin.
+ *
+ * The morph plugin is capable of morphing between two VisVideo
+ * sources, and thus is capable of morphing between two
+ * VisActors.
+ */
+struct _VisMorphPlugin {
+	VisObject			 object;	/**< The VisObject data. */
+	VisPluginMorphPaletteFunc	 palette;	/**< The plugin's palette function. This can be used
+							  * to obtain a palette for VISUAL_VIDEO_DEPTH_8BIT surfaces.
+							  * However the function may be set to NULL. In this case the
+							  * VisMorph system morphs between palettes itself. */
+	VisPluginMorphApplyFunc		 apply;		/**< The plugin it's main function. This is used to morph
+							  * between two VisVideo sources. */
+	int				 depth;		/**< The depth flag for the VisMorphPlugin. This contains an ORred
+							  * value of depths that are supported by the plugin. */
+	int				 requests_audio;/**< When set on TRUE this will indicate that the Morph plugin
+							  * requires an VisAudio context in order to render properly. */
+};
+
+/**
+ * The VisTransformPlugin structure is the main data structure
+ * for the transform plugin.
+ *
+ * The transform plugin is used to transform videos and palettes
+ * and can be used in visualisation pipelines.
+ */
+struct _VisTransformPlugin {
+	VisObject			 object;	/**< The VisObject data. */
+	VisPluginTransformPaletteFunc	 palette;	/**< Used to transform a VisPalette. Writes directly into the source. */
+	VisPluginTransformVideoFunc	 video;		/**< Used to transform a VisVideo. Writes directly into the source. */
+
+	int				 depth;		/**< The depth flag for the VisActorPlugin. This contains an ORred
+							  * value of depths that are supported by the plugin. */
+	int				 requests_audio;/**< When set on TRUE this will indicate that the Morph plugin
+							  * requires an VisAudio context in order to render properly. */
+};
+
+
+/* prototypes */
+VisPluginInfo *visual_plugin_info_new (void);
+int visual_plugin_info_copy (VisPluginInfo *dest, VisPluginInfo *src);
+
+int visual_plugin_events_pump (VisPluginData *plugin);
+VisEventQueue *visual_plugin_get_eventqueue (VisPluginData *plugin);
+int visual_plugin_set_userinterface (VisPluginData *plugin, VisUIWidget *widget);
+VisUIWidget *visual_plugin_get_userinterface (VisPluginData *plugin);
+
+VisPluginInfo *visual_plugin_get_info (VisPluginData *plugin);
+
+VisParamContainer *visual_plugin_get_params (VisPluginData *plugin);
+
+VisRandomContext *visual_plugin_get_random_context (VisPluginData *plugin);
+
+void *visual_plugin_get_specific (VisPluginData *plugin);
+
+VisPluginRef *visual_plugin_ref_new (void);
+
+VisPluginData *visual_plugin_new (void);
+
+VisList *visual_plugin_get_registry (void);
+VisList *visual_plugin_registry_filter (VisList *pluglist, const char *domain);
+
+const char *visual_plugin_get_next_by_name (VisList *list, const char *name);
+const char *visual_plugin_get_prev_by_name (VisList *list, const char *name);
+
+int visual_plugin_unload (VisPluginData *plugin);
+VisPluginData *visual_plugin_load (VisPluginRef *ref);
+int visual_plugin_realize (VisPluginData *plugin);
+
+VisPluginRef **visual_plugin_get_references (const char *pluginpath, int *count);
+VisList *visual_plugin_get_list (const char **paths);
+
+VisPluginRef *visual_plugin_find (VisList *list, const char *name);
+
+int visual_plugin_get_api_version (void);
+
+VisSongInfo *visual_plugin_actor_get_songinfo (VisActorPlugin *actplugin);
+
+const char *visual_plugin_type_get_domain (const char *type);
+const char *visual_plugin_type_get_package (const char *type);
+const char *visual_plugin_type_get_type (const char *type);
+VisPluginTypeDepth visual_plugin_type_get_depth (const char *type);
+int visual_plugin_type_member_of (const char *domain, const char *type);
+
+VisPluginEnviron *visual_plugin_environ_new (const char *type, VisObject *environ);
+int visual_plugin_environ_add (VisPluginData *plugin, VisPluginEnviron *penve);
+int visual_plugin_environ_remove (VisPluginData *plugin, const char *type);
+VisObject *visual_plugin_environ_get (VisPluginData *plugin, const char *type);
+	
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_PLUGIN_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_random.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,248 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ * 	    Vitaly V. Bursov <vitalyvb@ukr.net>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lv_random.h"
+
+/* Thanks Burkhard Plaum <plaum@ipf.uni-stuttgart.de> for these values and some other hints */
+#define val_a 1664525L		/* As suggested by Knuth */
+#define val_c 1013904223L	/* As suggested by H.W. Lewis and is a prime close to 2^32 * (sqrt(5) - 2)) */
+
+
+/**
+ * @defgroup VisRandom VisRandom
+ * @{
+ */
+
+/**
+ * Creates a new VisRandomContext data structure.
+ *
+ * @param seed The seed to be used to initialize the VisRandomContext with.
+ *
+ * @return A newly allocated VisRandomContext, or NULL on failure.
+ */
+VisRandomContext *visual_random_context_new (uint32_t seed)
+{
+	VisRandomContext *rcontext;
+
+	rcontext = visual_mem_new0 (VisRandomContext, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (rcontext), TRUE, NULL);
+
+	visual_random_context_set_seed (rcontext, seed);
+
+	return rcontext;
+}
+
+/**
+ * Set the seed to for a VisRandomContext.
+ *
+ * @param rcontext Pointer to the VisRandomContext for which the seed it set.
+ * @param seed The seed which is set in the VisRandomContext.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_RANDOM_CONTEXT_NULL on failure.
+ */
+int visual_random_context_set_seed (VisRandomContext *rcontext, uint32_t seed)
+{
+	visual_log_return_val_if_fail (rcontext != NULL, -VISUAL_ERROR_RANDOM_CONTEXT_NULL);
+
+	rcontext->seed = seed;
+	rcontext->seed_state = seed;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Get the seed that has been set to the VisRandomContext. This returns
+ * the initial seed. Not the state seed.
+ *
+ * @see visual_random_context_get_seed_state
+ *
+ * @param rcontext The pointer to the VisRandomContext of which the initial random seed is requested.
+ *
+ * @return The initial random seed.
+ */
+uint32_t visual_random_context_get_seed (VisRandomContext *rcontext)
+{
+	visual_log_return_val_if_fail (rcontext != NULL, 0);
+
+	return rcontext->seed;
+}
+
+/**
+ * Get the current state seed for the VisRandomContext.
+ *
+ * @see visual_random_context_get_seed
+ *
+ * @param rcontext The pointer to the VisRandomContext of which the state seed is requested.
+ *
+ * @return The current state seed for the randomizer.
+ */
+uint32_t visual_random_context_get_seed_state (VisRandomContext *rcontext)
+{
+	visual_log_return_val_if_fail (rcontext != NULL, 0);
+
+	return rcontext->seed_state;
+}
+
+/**
+ * Gives a random integer using the VisRandomContext as context for the randomizer.
+ *
+ * @param rcontext The pointer to the VisRandomContext in which the state of the randomizer is set.
+ *
+ * @return A pseudo random integer.
+ */
+uint32_t visual_random_context_int (VisRandomContext *rcontext)
+{
+	visual_log_return_val_if_fail (rcontext != NULL, 0);
+
+	return (rcontext->seed_state = val_a * rcontext->seed_state + val_c);
+}
+
+/**
+ * Gives a random integer ranging between min and max using the VisRandomContext as context
+ * for the randomizer.
+ * This function may use floating point instructions. Remeber, this will break
+ * things if used inside of MMX code.
+ *
+ * @param rcontext The pointer to the VisRandomContext in which the state of the randomizer is set.
+ * @param min The minimum for the output.
+ * @param max The maximum for the output.
+ *   
+ * @return A pseudo random integer confirm to the minimum and maximum.
+ */
+uint32_t visual_random_context_int_range (VisRandomContext *rcontext, int min, int max)
+{
+#if VISUAL_RANDOM_FAST_FP_RND
+	/* Uses fast floating number generator and two divisions elimitated.
+	 * More than 2 times faster than original.
+	 */
+	float fm = min; /* +10% speedup... */
+
+	visual_log_return_val_if_fail (rcontext != NULL, 0);
+
+	return visual_random_context_float (rcontext) * (max - min + 1) + fm;
+#else
+	visual_log_return_val_if_fail (rcontext != NULL, 0);
+
+	return (visual_random_context_int (rcontext) / (VISUAL_RANDOM_MAX / (max - min + 1))) + min;
+#endif
+}
+
+/**
+ * Gives a random double precision floating point value
+ * using the VisRandomContext as context for the randomizer.
+ *
+ * @param rcontext The pointer to the VisRandomContext in which the state of the randomizer is set.
+ *
+ * @return A pseudo random integer.
+ */
+double visual_random_context_double (VisRandomContext *rcontext)
+{
+#if VISUAL_RANDOM_FAST_FP_RND
+	union {
+		unsigned int i[2];
+		double d;
+	} value;
+#endif
+	uint32_t irnd;
+
+	visual_log_return_val_if_fail (rcontext != NULL, -1);
+
+	irnd = (rcontext->seed_state = val_a * rcontext->seed_state + val_c);
+#if VISUAL_RANDOM_FAST_FP_RND
+	/* This saves floating point division (20 clocks on AXP, 
+	 * 38 on P4) and introduces store-to-load data size mismatch penalty
+	 * and substraction op.
+	 * Faster on AXP anyway :)
+	 */
+
+	value.i[0] = (irnd << 20);
+	value.i[1] = 0x3ff00000 | (irnd >> 12);
+
+	return value.d - 1.0;
+#else
+	return (double) irnd / VISUAL_RANDOM_MAX;
+#endif
+}
+
+/**
+ * Gives a random single precision floating point value
+ * using the VisRandomContext as context for the randomizer.
+ *
+ * @param rcontext The pointer to the VisRandomContext in which the state of the randomizer is set.
+ *
+ * @return A pseudo random integer.
+ */
+float visual_random_context_float (VisRandomContext *rcontext)
+{
+#if VISUAL_RANDOM_FAST_FP_RND
+	union {
+		unsigned int i;
+		float f;
+	} value;
+#endif
+	uint32_t irnd;
+
+	visual_log_return_val_if_fail (rcontext != NULL, -1);
+
+	irnd = (rcontext->seed_state = val_a * rcontext->seed_state + val_c);
+#if VISUAL_RANDOM_FAST_FP_RND
+	/* Saves floating point division. Introduces substraction.
+	 * Yet faster! :)
+	 */
+
+	value.i = 0x3f800000 | (t >> 9);
+
+	return value.f - 1.0f;
+#else
+	return (float) irnd / VISUAL_RANDOM_MAX;
+#endif
+}
+
+/**
+ * Function which returns 1 with a propability of p (0.0 <= p <= 1.0) using the VisRandomContext
+ * as context for the randomizer.
+ *
+ * @param rcontext The pointer to the VisRandomContext in which the state of the randomizer is set.
+ * @param a The float to be used in the decide.
+ *
+ * @returns 0 or 1, -VISUAL_ERROR_RANDOM_CONTEXT_NULL on failure.
+ */
+int visual_random_context_decide (VisRandomContext *rcontext, float a)
+{
+	visual_log_return_val_if_fail (rcontext != NULL, -VISUAL_ERROR_RANDOM_CONTEXT_NULL);
+
+	return visual_random_context_float (rcontext) <= a;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_random.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,81 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ * 	    Vitaly V. Bursov <vitalyvb@ukr.net>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_RANDOM_H
+#define _LV_RANDOM_H
+
+#include <libvisual/lv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_RANDOMCONTEXT(obj)			(VISUAL_CHECK_CAST ((obj), 0, VisRandomContext))
+	
+/**
+ * The highest random nummer.
+ */
+#define VISUAL_RANDOM_MAX	4294967295U
+
+typedef struct _VisRandomContext VisRandomContext;
+
+/**
+ * The VisRandomContext data structure is used to keep track of
+ * the randomizer it's state. When state tracking is used you need
+ * to use the visual_random_context_* functions.
+ */
+struct _VisRandomContext {
+	VisObject	object;		/**< The VisObject data. */
+	uint32_t	seed;		/**< The initial random seed. */
+	uint32_t	seed_state;	/**< The current state seed. */
+};
+
+/* Non context random macros */
+extern VisRandomContext __lv_internal_random_context;
+#define visual_random_set_seed(a) visual_random_context_set_seed(__lv_internal_random_context, a)
+#define visual_random_get_seed() visual_random_context_get_seed(__lv_internal_random_context)
+#define visual_random_int() visual_random_context_int(__lv_internal_random_context)
+#define visual_random_int_range(a, b) visual_random_context_int(__lv_internal_random_context, a, b)
+#define visual_random_double () visual_random_context_double(__lv_internal_random_context);
+#define visual_random_float () visual_random_context_float(__lv_internal_random_context);
+#define visual_random_decide(a) visual_random_int(__lv_internal_random_context, a)
+
+/* Context management */
+VisRandomContext *visual_random_context_new (uint32_t seed);
+int visual_random_context_set_seed (VisRandomContext *rcontext, uint32_t seed);
+uint32_t visual_random_context_get_seed (VisRandomContext *rcontext);
+uint32_t visual_random_context_get_seed_state (VisRandomContext *rcontext);
+
+/* Context random functions */
+uint32_t visual_random_context_int (VisRandomContext *rcontext);
+uint32_t visual_random_context_int_range (VisRandomContext *rcontext, int min, int max);
+double visual_random_context_double (VisRandomContext *rcontext);
+float visual_random_context_float (VisRandomContext *rcontext);
+int visual_random_context_decide (VisRandomContext *rcontext, float a);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_RANDOM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_songinfo.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,425 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lv_common.h"
+#include "lv_songinfo.h"
+
+static int songinfo_dtor (VisObject *object)
+{
+	VisSongInfo *songinfo = VISUAL_SONGINFO (object);
+
+	visual_songinfo_free_strings (songinfo);
+
+	if (songinfo->cover != NULL)
+		visual_object_unref (VISUAL_OBJECT (songinfo->cover));
+
+	songinfo->cover = NULL;
+
+	return VISUAL_OK;
+}
+
+/**
+ * @defgroup VisSongInfo VisSongInfo
+ * @{
+ */
+
+/**
+ * Creates a new VisSongInfo structure.
+ *
+ * @param type Type of interface being used.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+VisSongInfo *visual_songinfo_new (VisSongInfoType type)
+{
+	VisSongInfo *songinfo;
+
+	songinfo = visual_mem_new0 (VisSongInfo, 1);
+	
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (songinfo), TRUE, songinfo_dtor);
+
+	songinfo->type = type;
+
+	return songinfo;
+}
+
+/**
+ * Frees all the strings within the structure. This frees all the
+ * strings used by the structure.
+ *
+ * @param songinfo Pointer to a VisSongInfo of which the strings need to
+ * 	freed.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+int visual_songinfo_free_strings (VisSongInfo *songinfo)
+{
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+
+	if (songinfo->songname != NULL)
+		visual_mem_free (songinfo->songname);
+
+	if (songinfo->artist != NULL)
+		visual_mem_free (songinfo->artist);
+
+	if (songinfo->album != NULL)
+		visual_mem_free (songinfo->album);
+
+	if (songinfo->song != NULL)
+		visual_mem_free (songinfo->song);
+
+	songinfo->songname = NULL;
+	songinfo->artist = NULL;
+	songinfo->album = NULL;
+	songinfo->song = NULL;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the interface type to a VisSongInfo. Used to set the interface
+ * type to the VisSongInfo structure. The interface type defines if we're
+ * providing a simple string containing the song name or an separated
+ * set of data containing all the information about a song.
+ *
+ * @param songinfo Pointer to a VisSongInfo to which the interface type is set.
+ * @param type Interface type that is set against the VisSongInfo.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+int visual_songinfo_set_type (VisSongInfo *songinfo, VisSongInfoType type)
+{
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+	
+	songinfo->type = type;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the length of a song. Used to set the length of a song when the
+ * advanced interface is being used.
+ *
+ * @param songinfo Pointer to a VisSongInfo to which the song length is set.
+ * @param length The length in seconds.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+int visual_songinfo_set_length (VisSongInfo *songinfo, int length)
+{
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+	
+	songinfo->length = length;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the elapsed time of a song. Used to set the elapsed time of a song when
+ * the advanced interface is being used.
+ *
+ * @param songinfo Pointer to a VisSongInfo to which the elapsed time is set.
+ * @param elapsed The elapsed time in seconds.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+int visual_songinfo_set_elapsed (VisSongInfo *songinfo, int elapsed)
+{
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+
+	songinfo->elapsed = elapsed;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets a simple song name. Used when the simple interface is being used
+ * to set a song name.
+ *
+ * @param songinfo Pointer to a VisSongInfo to which the simple song name is set.
+ * @param name The simple song name.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+int visual_songinfo_set_simple_name (VisSongInfo *songinfo, char *name)
+{
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+	
+	if (songinfo->songname != NULL)
+		visual_mem_free (songinfo->songname);
+
+	songinfo->songname = strdup (name);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the artist name. Used to set the artist name when the advanced
+ * interface is being used.
+ *
+ * @param songinfo Pointer to a VisSongInfo to which the artist name is set.
+ * @param artist The artist name.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+int visual_songinfo_set_artist (VisSongInfo *songinfo, char *artist)
+{
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+
+	if (songinfo->artist != NULL)
+		visual_mem_free (songinfo->artist);
+
+	songinfo->artist = strdup (artist);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the album name. Used to set the album name when the advanced
+ * interface is being used.
+ *
+ * @param songinfo Pointer to a VisSongInfo to which the album name is set.
+ * @param album The album name.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+int visual_songinfo_set_album (VisSongInfo *songinfo, char *album)
+{
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+
+	if (songinfo->album != NULL)
+		visual_mem_free (songinfo->album);
+
+	songinfo->album = strdup (album);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the song name. Used to set the song name when the advanced
+ * interface is being used.
+ *
+ * @param songinfo Pointer to a VisSongInfo to which the song name is set.
+ * @param song The song name.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+int visual_songinfo_set_song (VisSongInfo *songinfo, char *song)
+{
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+
+	if (songinfo->song != NULL)
+		visual_mem_free (songinfo->song);
+
+	songinfo->song = strdup (song);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the cover art. Used to set the cover art when the advanced
+ * interface is being used.
+ *
+ * @param songinfo Pointer to a VisSongInfo to which the cover art is set.
+ * @param cover Pointer to a VisVideo containing the cover art.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+int visual_songinfo_set_cover (VisSongInfo *songinfo, VisVideo *cover)
+{
+	VisVideo dtransform;
+
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+
+	if (songinfo->cover != NULL)
+		visual_object_unref (VISUAL_OBJECT (songinfo->cover));
+
+	/* The coverart image */
+	songinfo->cover = visual_video_new ();
+	visual_video_set_depth (songinfo->cover, VISUAL_VIDEO_DEPTH_32BIT);
+	visual_video_set_dimension (songinfo->cover, 64, 64);
+	visual_video_allocate_buffer (songinfo->cover);
+	
+	/* The temp depth transform video */
+	memset (&dtransform, 0, sizeof (VisVideo));
+
+	visual_video_set_depth (&dtransform, VISUAL_VIDEO_DEPTH_32BIT);
+	visual_video_set_dimension (&dtransform, cover->width, cover->height);
+	visual_video_allocate_buffer (&dtransform);
+
+	visual_video_depth_transform (&dtransform, cover);
+
+	/* Now scale it */
+	/* FIXME make cover image size settable ??? */
+	visual_video_scale (songinfo->cover, &dtransform, VISUAL_VIDEO_SCALE_BILINEAR);
+
+	/* Unref the depth transform video */
+	visual_object_unref (VISUAL_OBJECT (&dtransform));
+
+	return VISUAL_OK;
+}
+
+/**
+ * Resets the age timer. Used to timestamp a song to the current
+ * time.
+ *
+ * @param songinfo Pointer to a VisSongInfo that is timestamped.
+ *
+ * @return 0 on succes -1 on failure.
+ */
+int visual_songinfo_mark (VisSongInfo *songinfo)
+{
+	visual_log_return_val_if_fail (songinfo != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+
+	visual_timer_start (&songinfo->timer);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Gives the age of the VisSongInfo. Returns the age in seconds
+ * stored in a long.
+ *
+ * @param songinfo Pointer to a VisSongInfo of which the age is requested.
+ *
+ * @return The age in seconds.
+ */
+
+long visual_songinfo_age (VisSongInfo *songinfo)
+{
+	VisTime cur;
+
+	visual_time_get (&cur);
+
+	/* Clock has been changed into the past */
+	if (cur.tv_sec < songinfo->timer.start.tv_sec)
+		visual_songinfo_mark (songinfo);
+
+	visual_time_difference (&cur, &songinfo->timer.start, &cur);
+
+	return cur.tv_sec;
+}
+
+/**
+ * Copies the content of a VisSongInfo. Used to copy the content of
+ * a VisSongInfo in that of another.
+ *
+ * @param dest Pointer to the destination VisSongInfo.
+ * @param src Pointer to the source VisSongInfo.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_SONGINFO_NULL on failure.
+ */
+int visual_songinfo_copy (VisSongInfo *dest, VisSongInfo *src)
+{
+	visual_log_return_val_if_fail (dest != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+	visual_log_return_val_if_fail (src != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+
+	dest->type = src->type;
+	dest->length = src->length;
+	dest->elapsed = src->elapsed;
+
+	visual_mem_copy (&dest->timer, &src->timer, sizeof (VisTimer));
+
+	if (src->songname != NULL)
+		dest->songname = strdup (src->songname);
+	
+	if (src->artist != NULL)
+		dest->artist = strdup (src->artist);
+	
+	if (src->album != NULL)
+		dest->album = strdup (src->album);
+	
+	if (src->song != NULL)
+		dest->song = strdup (src->song);
+
+	/* Point the coverart VisVideo to that of the original and up it's refcount */
+	dest->cover = src->cover;
+
+	if (src->cover != NULL)
+		visual_object_ref (VISUAL_OBJECT (src->cover));
+
+	return VISUAL_OK;
+}
+
+/**
+ * Compares the VisSongInfo strings. Used to compare the content
+ * of two VisSongInfos by comparing their strings. This can be used
+ * to detect if there is a song change.
+ *
+ * @param s1 Pointer to the first VisSongInfo.
+ * @param s2 Pointer to the second VisSongInfo.
+ *
+ * @return FALSE on different, TRUE on same, -VISUAL_ERROR_SONGINFO_NULL on failure.
+ */
+int visual_songinfo_compare (VisSongInfo *s1, VisSongInfo *s2)
+{
+	int diff = 0;
+
+	visual_log_return_val_if_fail (s1 != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+	visual_log_return_val_if_fail (s2 != NULL, -VISUAL_ERROR_SONGINFO_NULL);
+
+	if (s1->songname != NULL && s2->songname != NULL) {
+		if (strcmp (s1->songname, s2->songname) != 0)
+			diff++;
+	} else if ((s1->songname == NULL || s2->songname == NULL) &&
+			!(s1->songname == NULL && s2->songname == NULL)) {
+		diff++;
+	}
+
+	if (s1->artist != NULL && s2->artist != NULL) {
+		if (strcmp (s1->artist, s2->artist) != 0)
+			diff++;
+	} else if ((s1->artist == NULL || s2->artist == NULL) &&
+			!(s1->artist == NULL && s2->artist == NULL)) {
+		diff++;
+	}
+
+	if (s1->album != NULL && s2->album != NULL) {
+		if (strcmp (s1->album, s2->album) != 0)
+			diff++;
+	} else if ((s1->album == NULL || s2->album == NULL) &&
+			!(s1->album == NULL && s2->album == NULL)) {
+		diff++;
+	}
+
+	if (s1->song != NULL && s2->song != NULL) {
+		if (strcmp (s1->song, s2->song) != 0)
+			diff++;
+	} else if ((s1->song == NULL || s2->song == NULL) &&
+			!(s1->song == NULL && s2->song == NULL)) {
+		diff++;
+	}
+
+	return (diff > 0 ? FALSE : TRUE);
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_songinfo.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,103 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_SONGINFO_H
+#define _LV_SONGINFO_H
+
+#include <libvisual/lv_time.h>
+#include <libvisual/lv_video.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_SONGINFO(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisSongInfo))
+	
+/**
+ * Used to define the type of song info being used.
+ * There are two interfaces to notify libvisual of song
+ * information, being a simple and a advanced interface.
+ */
+typedef enum {
+	VISUAL_SONGINFO_TYPE_NULL,	/**< No song info is given. */
+	VISUAL_SONGINFO_TYPE_SIMPLE,	/**< Simple interface only sets a songname. */
+	VISUAL_SONGINFO_TYPE_ADVANCED	/**< Advanced interface splits all the stats
+					  * in separated entries */
+} VisSongInfoType;
+
+typedef struct _VisSongInfo VisSongInfo;
+
+/**
+ * Song info data structure.
+ *
+ * Contains information about the current played song. Information like
+ * artist, album, song, elapsed time and even coverart can be set using the
+ * methods of the VisSongInfo system.
+ */
+struct _VisSongInfo {
+	VisObject	 object;	/**< The VisObject data. */
+	VisSongInfoType	 type;		/**< Sets the interface type. */
+
+	/* In seconds */
+	int		 length;	/**< Total length of the song playing. */
+	int		 elapsed;	/**< Elapsed time of the song playing. */
+
+	/* Simple type */
+	char		*songname;	/**< A string containing the song name using
+					  * the simple interface. */
+	
+	/* Advanced type */
+	char		*artist;	/**< A string containing the artist name using
+					  * the advanced interface. */
+	char		*album;		/**< A string containing the album name using
+					  * the advanced interface. */
+	char		*song;		/**< A string containing the song name using
+					  * the advanced interface. */
+
+	/* Timing */
+	VisTimer	 timer;		/**< Used to internal timing to keep track on the
+					  * age of the record. */
+	/* Cover art */
+	VisVideo	*cover;		/**< Pointer to a VisVideo that contains the cover art. */
+};
+
+VisSongInfo *visual_songinfo_new (VisSongInfoType type);
+int visual_songinfo_free_strings (VisSongInfo *songinfo);
+int visual_songinfo_set_type (VisSongInfo *songinfo, VisSongInfoType type);
+int visual_songinfo_set_length (VisSongInfo *songinfo, int length);
+int visual_songinfo_set_elapsed (VisSongInfo *songinfo, int elapsed);
+int visual_songinfo_set_simple_name (VisSongInfo *songinfo, char *name);
+int visual_songinfo_set_artist (VisSongInfo *songinfo, char *artist);
+int visual_songinfo_set_album (VisSongInfo *songinfo, char *album);
+int visual_songinfo_set_song (VisSongInfo *songinfo, char *song);
+int visual_songinfo_set_cover (VisSongInfo *songinfo, VisVideo *cover);
+int visual_songinfo_mark (VisSongInfo *songinfo);
+long visual_songinfo_age (VisSongInfo *songinfo);
+int visual_songinfo_copy (VisSongInfo *dest, VisSongInfo *src);
+int visual_songinfo_compare (VisSongInfo *s1, VisSongInfo *s2);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_SONGINFO_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_thread.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,381 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lv_log.h"
+#include "lv_thread.h"
+
+static int __lv_thread_enabled = TRUE;
+
+/* FIXME add more threading backends here:
+ * glib			(could proof to be a nice fallback when needed)
+ * native windows	(says nuff)
+ * what is used on Mac os X ?
+ */
+
+
+/**
+ * @defgroup VisThread VisThread
+ * @{
+ */
+
+/**
+ * Enable or disable threading support. This can be used to disallow threads, which might be needed in some environments.
+ * 
+ * @see visual_thread_is_enabled
+ *
+ * @param enabled TRUE to enable threads, FALSE to disable threads.
+ */
+void visual_thread_enable (int enabled)
+{
+	__lv_thread_enabled = enabled > 0 ? TRUE : FALSE;
+}
+
+/**
+ * Request if threads are enabled or not. This function should not be confused with visual_thread_is_supported().
+ *
+ * @return TRUE if enabled, FALSE if disabled.
+ */
+int visual_thread_is_enabled (void)
+{
+	return __lv_thread_enabled;
+}
+
+/**
+ * Is used to check if threading is supported. When threading is used this should always
+ * be checked, it's possible to disable threads from within the code, so no #ifdefs should
+ * be used.
+ *
+ * @return TRUE if threading is supported or FALSE if not.
+ */
+int visual_thread_is_supported ()
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	return TRUE;
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+	return FALSE;
+#endif
+#else
+	return FALSE;
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * Creates a new VisThread that is used in threading.
+ *
+ * @param func The threading function.
+ * @param data The private data that is send to the threading function.
+ * @param joinable Flag that contains whatever the thread can be joined or not.
+ *
+ * @return A newly allocated VisThread, or NULL on failure.
+ */
+VisThread *visual_thread_create (VisThreadFunc func, void *data, int joinable)
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	VisThread *thread;
+	pthread_attr_t attr;
+	int res;
+
+	if (visual_thread_is_enabled () == FALSE)
+		return NULL;
+
+	thread = visual_mem_new0 (VisThread, 1);
+
+	pthread_attr_init(&attr);
+
+	if (joinable == TRUE)
+		pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE);
+	else
+		pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
+
+	res = pthread_create (&thread->thread, &attr, func, data);
+
+	pthread_attr_destroy (&attr);
+
+	if (res != 0) {
+		visual_log (VISUAL_LOG_CRITICAL, "Error while creating thread");
+
+		visual_mem_free (thread);
+
+		return NULL;
+	}
+
+	return thread;
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+	return NULL;
+#endif 
+#else
+	return NULL;
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * After a VisThread is not needed anylonger it needs to be freed using this function.
+ *
+ * @param thread The VisThread that needs to be freed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_THREAD_NULL, -VISUAL_ERROR_THREAD_NO_THREADING or
+ *	error values returned by visual_mem_free on failure.
+ */
+int visual_thread_free (VisThread *thread)
+{
+#ifdef VISUAL_HAVE_THREADS
+	visual_log_return_val_if_fail (thread != NULL, -VISUAL_ERROR_THREAD_NULL);
+
+	return visual_mem_free (thread);
+#else
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * Joins a VisThread with another.
+ *
+ * @param thread The VisThread that is about to be joined.
+ *
+ * @return Possible result that was passed to visual_thread_exit as retval or
+ *	NULL.
+ */
+void *visual_thread_join (VisThread *thread)
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	void *result;
+
+	if (thread == NULL)
+		return NULL;
+
+	if (pthread_join (thread->thread, &result) < 0) {
+		visual_log (VISUAL_LOG_CRITICAL, "Error while joining thread");
+
+		return NULL;
+	}
+
+	return result;
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+	return NULL;
+#endif
+#else
+	return NULL;
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * Exits a VisThread, this will terminate the thread.
+ *
+ * @param retval The return value that is catched by the visual_thread_join function.
+ */
+void visual_thread_exit (void *retval)
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	pthread_exit (retval);
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+
+#endif
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * Yield the current VisThread so another gets time.
+ */
+void visual_thread_yield ()
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	sched_yield ();
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+	
+#endif
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * Creates a new VisMutex that is used to do thread locking so data can be synchronized.
+ *
+ * @return A newly allocated VisMutex that can be used with the visual_mutex_lock and
+ *	visual_mutex_unlock functions or NULL on failure.
+ */
+VisMutex *visual_mutex_new ()
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	VisMutex *mutex;
+
+	if (visual_thread_is_enabled () == FALSE)
+		return NULL;
+
+	mutex = visual_mem_new0 (VisMutex, 1);
+
+	pthread_mutex_init (&mutex->mutex, NULL);
+
+	return mutex;
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+	return NULL;
+#endif
+#else
+	return NULL;
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * A VisMutex is allocated to have more flexibility with the actual thread backend. Thus they need
+ * to be freed as well.
+ *
+ * @param mutex Pointer to the VisMutex that needs to be freed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MUTEX_NULL or -VISUAL_ERROR_THREAD_NO_THREADING on failure.
+ */
+int visual_mutex_free (VisMutex *mutex)
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	visual_log_return_val_if_fail (mutex != NULL, -VISUAL_ERROR_MUTEX_NULL);
+
+	return visual_mem_free (mutex);
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif
+#else
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * A VisMutex that has not been allocated using visual_mutex_new () can be initialized using this function. You can
+ * use non allocated VisMutex variables in this context by giving a reference to them.
+ *
+ * @param mutex Pointer to the VisMutex which needs to be initialized.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MUTEX_NULL or -VISUAL_ERROR_THREAD_NO_THREADING on failure.
+ */
+int visual_mutex_init (VisMutex *mutex)
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	visual_log_return_val_if_fail (mutex != NULL, -VISUAL_ERROR_MUTEX_NULL);
+
+	memset (mutex, 0, sizeof (VisMutex));
+
+	pthread_mutex_init (&mutex->mutex, NULL);
+
+	return VISUAL_OK;
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif
+#else	
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif /* VISUAL_HAVE_THREADS */
+
+}
+
+/**
+ * Locks a VisMutex, with the VisMutex locks checked right, only one thread can access the area at once.
+ *	This will block if the thread is already locked.
+ *
+ * @param mutex Pointer to the VisMutex to register the lock.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MUTEX_NULL, -VISUAL_ERROR_MUTEX_LOCK_FAILURE or
+ *	-VISUAL_ERROR_THREAD_NO_THREADING on failure.
+ */
+int visual_mutex_lock (VisMutex *mutex)
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	visual_log_return_val_if_fail (mutex != NULL, -VISUAL_ERROR_MUTEX_NULL);
+
+	if (pthread_mutex_lock (&mutex->mutex) < 0)
+		return -VISUAL_ERROR_MUTEX_LOCK_FAILURE;
+
+	return VISUAL_OK;
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif
+#else
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * Tries to lock a VisMutex, however instead of visual_mutex_lock it does not block on failure. but returns
+ * instead with -VISUAL_ERROR_MUTEX_TRYLOCK_FAILURE as error value.
+ *
+ * @param mutex Pointer to the VisMutex that needs to be locked.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MUTEX_NULL, -VISUAL_ERROR_MUTEX_TRYLOCK_FAILURE or
+ *	-VISUAL_ERROR_THREAD_NO_THREADING on failure.
+ */
+int visual_mutex_trylock (VisMutex *mutex)
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	visual_log_return_val_if_fail (mutex != NULL, -VISUAL_ERROR_MUTEX_NULL);
+
+	if (pthread_mutex_trylock (&mutex->mutex) < 0)
+		return -VISUAL_ERROR_MUTEX_TRYLOCK_FAILURE;
+
+	return VISUAL_OK;
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif
+#else
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * Unlocks a VisMutex so other threads that use the same lock can now enter the critical area.
+ *
+ * @param mutex Pointer to the VisMutex that is unlocked.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_MUTEX_NULL, -VISUAL_ERROR_MUTEX_UNLOCK_FAILURE or
+ *	-VISUAL_ERROR_THREAD_NO_THREADING on failure.
+ */
+int visual_mutex_unlock (VisMutex *mutex)
+{
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	visual_log_return_val_if_fail (mutex != NULL, -VISUAL_ERROR_MUTEX_NULL);
+
+	if (pthread_mutex_unlock (&mutex->mutex) < 0)
+		return -VISUAL_ERROR_MUTEX_UNLOCK_FAILURE;
+
+	return VISUAL_OK;
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif
+#else
+	return -VISUAL_ERROR_THREAD_NO_THREADING;
+#endif /* VISUAL_HAVE_THREADS */
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_thread.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,84 @@
+#ifndef _LV_THREAD_H
+#define _LV_THREAD_H
+
+#include <libvisual/lvconfig.h>
+#include <libvisual/lv_common.h>
+
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+#include <pthread.h>
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+
+#endif
+#endif /* VISUAL_HAVE_THREADS */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _VisThread VisThread;
+typedef struct _VisMutex VisMutex;
+
+/**
+ * The function defination for a function that forms the base of a new VisThread when
+ * visual_thread_create is used.
+ *
+ * @see visual_thread_create
+ *
+ * @arg data Pointer that can contains the private data from the visual_thread_create function.
+ *
+ * @return Pointer to the data when a thread is joined.
+ */
+typedef void *(*VisThreadFunc)(void *data);
+
+/**
+ * The VisThread data structure and the VisThread subsystem is a wrapper system for native
+ * threading implementations.
+ */
+struct _VisThread {
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	pthread_t thread;		/**< Private used for the pthread implementation. */
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+
+#endif
+#endif /* VISUAL_HAVE_THREADS */
+};
+
+/**
+ * The VisMutex data structure and the VisMutex subsystem is a wrapper system for native
+ * thread locking implementations.
+ */
+struct _VisMutex {
+#ifdef VISUAL_HAVE_THREADS
+#ifdef VISUAL_THREAD_MODEL_POSIX
+	pthread_mutex_t mutex;		/**< Private used for the pthreads implementation. */
+#else /* !VISUAL_THREAD_MODEL_POSIX */
+
+#endif
+#endif /* VISUAL_HAVE_THREADS */
+};
+
+void visual_thread_enable (int enabled);
+int visual_thread_is_enabled (void);
+
+int visual_thread_is_supported (void);
+VisThread *visual_thread_create (VisThreadFunc func, void *data, int joinable);
+int visual_thread_free (VisThread *thread);
+void *visual_thread_join (VisThread *thread);
+void visual_thread_exit (void *retval);
+void visual_thread_yield (void);
+VisThread *visual_thread_self (void);
+
+VisMutex *visual_mutex_new (void);
+int visual_mutex_free (VisMutex *mutex);
+int visual_mutex_init (VisMutex *mutex);
+int visual_mutex_lock (VisMutex *mutex);
+int visual_mutex_trylock (VisMutex *mutex);
+int visual_mutex_unlock (VisMutex *mutex);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_THREAD_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_time.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,362 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include "config.h"
+#include "lv_common.h"
+#include "lv_thread.h"
+#include "lv_time.h"
+
+/**
+ * @defgroup VisTime VisTime
+ * @{
+ */
+
+/**
+ * Creates a new VisTime structure.
+ *
+ * @return A newly allocated VisTime.
+ */
+VisTime *visual_time_new ()
+{
+	VisTime *time_;
+
+	time_ = visual_mem_new0 (VisTime, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (time_), TRUE, NULL);
+
+	return time_;
+}
+
+/**
+ * Loads the current time into the VisTime structure.
+ *
+ * @param time_ Pointer to the VisTime in which the current time needs to be set.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TIME_NULL on failure.
+ */
+int visual_time_get (VisTime *time_)
+{
+	struct timeval tv;
+	
+	visual_log_return_val_if_fail (time_ != NULL, -VISUAL_ERROR_TIME_NULL);
+
+	gettimeofday (&tv, NULL);
+
+	visual_time_set (time_, tv.tv_sec, tv.tv_usec);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the time by sec, usec in a VisTime structure.
+ *
+ * @param time_ Pointer to the VisTime in which the time is set.
+ * @param sec The seconds.
+ * @param usec The microseconds.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TIME_NULL on failure.
+ */
+int visual_time_set (VisTime *time_, long sec, long usec)
+{
+	visual_log_return_val_if_fail (time_ != NULL, -VISUAL_ERROR_TIME_NULL);
+	
+	time_->tv_sec = sec;
+	time_->tv_usec = usec;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Copies ine VisTime into another.
+ *
+ * @param dest Pointer to the destination VisTime in which the source VisTime is copied.
+ * @param src Pointer to the source VisTime that is copied to the destination VisTime.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TIME_NULL on failure.
+ */
+int visual_time_copy (VisTime *dest, VisTime *src)
+{
+	visual_log_return_val_if_fail (dest != NULL, -VISUAL_ERROR_TIME_NULL);
+	visual_log_return_val_if_fail (src != NULL, -VISUAL_ERROR_TIME_NULL);
+
+	dest->tv_sec = src->tv_sec;
+	dest->tv_usec = src->tv_usec;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Calculates the difference between two VisTime structures.
+ *
+ * @param dest Pointer to the VisTime that contains the difference between time1 and time2.
+ * @param time1 Pointer to the first VisTime.
+ * @param time2 Pointer to the second VisTime from which the first is substracted to generate a result.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TIME_NULL on failure.
+ */
+int visual_time_difference (VisTime *dest, VisTime *time1, VisTime *time2)
+{
+	visual_log_return_val_if_fail (dest != NULL, -VISUAL_ERROR_TIME_NULL);
+	visual_log_return_val_if_fail (time1 != NULL, -VISUAL_ERROR_TIME_NULL);
+	visual_log_return_val_if_fail (time2 != NULL, -VISUAL_ERROR_TIME_NULL);
+
+	dest->tv_usec = time2->tv_usec - time1->tv_usec;
+	dest->tv_sec = time2->tv_sec - time1->tv_sec;
+
+	if (dest->tv_usec < 0) {
+		dest->tv_usec = VISUAL_USEC_PER_SEC + dest->tv_usec;
+		dest->tv_sec--;
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sleeps an certain amount of microseconds.
+ *
+ * @param microseconds The amount of microseconds we're going to sleep. To sleep a certain amount of
+ *	seconds you can call this function with visual_time_usleep (VISUAL_USEC_PER_SEC * seconds).
+ * 
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TIME_NO_USLEEP or -1 on failure.
+ */
+int visual_time_usleep (unsigned long microseconds)
+{
+#ifdef HAVE_NANOSLEEP
+	struct timespec request, remaining;
+	request.tv_sec = microseconds / VISUAL_USEC_PER_SEC;
+	request.tv_nsec = 1000 * (microseconds % VISUAL_USEC_PER_SEC);
+	while (nanosleep (&request, &remaining) == EINTR)
+		request = remaining;
+#elif HAVE_SELECT
+	struct timeval tv;
+	tv.tv_sec = microseconds / VISUAL_USEC_PER_SEC;
+	tv.tv_usec = microseconds % VISUAL_USEC_PER_SEC;
+	select (0, NULL, NULL, NULL, &tv);
+#elif HAVE_USLEEP
+	return usleep (microseconds);
+#else
+#warning visual_time_usleep() will does not work!
+	return -VISUAL_ERROR_TIME_NO_USLEEP;
+#endif
+	return VISUAL_OK;
+}
+
+/**
+ * Creates a new VisTimer structure.
+ *
+ * @return A newly allocated VisTimer.
+ */
+VisTimer *visual_timer_new ()
+{
+	VisTimer *timer;
+
+	timer = visual_mem_new0 (VisTimer, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (timer), TRUE, NULL);
+
+	return timer;
+}
+
+/**
+ * Checks if the timer is active.
+ *
+ * @param timer Pointer to the VisTimer of which we want to know if it's active.
+ *
+ * @return TRUE or FALSE, -VISUAL_ERROR_TIMER_NULL on failure.
+ */
+int visual_timer_is_active (VisTimer *timer)
+{
+	visual_log_return_val_if_fail (timer != NULL, -VISUAL_ERROR_TIMER_NULL);
+
+	return timer->active;
+}
+
+/**
+ * Starts a timer.
+ *
+ * @param timer Pointer to the VisTimer in which we start the timer.
+ *
+ * return VISUAL_OK on succes, -VISUAL_ERROR_TIMER_NULL on failure.
+ */ 
+int visual_timer_start (VisTimer *timer)
+{
+	visual_log_return_val_if_fail (timer != NULL, -VISUAL_ERROR_TIMER_NULL);
+
+	visual_time_get (&timer->start);
+
+	timer->active = TRUE;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Stops a timer.
+ *
+ * @param timer Pointer to the VisTimer that is stopped.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TIMER_NULL on failure.
+ */
+int visual_timer_stop (VisTimer *timer)
+{
+	visual_log_return_val_if_fail (timer != NULL, -VISUAL_ERROR_TIMER_NULL);
+
+	visual_time_get (&timer->stop);
+
+	timer->active = FALSE;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Continues a stopped timer. The timer needs to be stopped before continueing.
+ *
+ * @param timer Pointer to the VisTimer that is continued.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TIMER_NULL on failure.
+ */
+int visual_timer_continue (VisTimer *timer)
+{
+	VisTime elapsed;
+
+	visual_log_return_val_if_fail (timer != NULL, -VISUAL_ERROR_TIMER_NULL);
+	visual_log_return_val_if_fail (timer->active != FALSE, -VISUAL_ERROR_TIMER_NULL);
+
+	visual_time_difference (&elapsed, &timer->start, &timer->stop);
+
+	visual_time_get (&timer->start);
+
+	if (timer->start.tv_usec < elapsed.tv_usec) {
+		timer->start.tv_usec += VISUAL_USEC_PER_SEC;
+		timer->start.tv_sec--;
+	}
+
+	timer->start.tv_sec -= elapsed.tv_sec;
+	timer->start.tv_usec -= elapsed.tv_usec;
+
+	timer->active = TRUE;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Retrieve the amount of time passed since the timer has started.
+ *
+ * @param timer Pointer to the VisTimer from which we want to know the amount of time passed.
+ * @param time_ Pointer to the VisTime in which we put the amount of time passed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TIMER_NULL or -VISUAL_ERROR_TIME_NULL on failure.
+ */
+int visual_timer_elapsed (VisTimer *timer, VisTime *time_)
+{
+	VisTime cur;
+
+	visual_log_return_val_if_fail (timer != NULL, -VISUAL_ERROR_TIMER_NULL);
+	visual_log_return_val_if_fail (time_ != NULL, -VISUAL_ERROR_TIME_NULL);
+
+	visual_time_get (&cur);
+
+	if (timer->active == TRUE)
+		visual_time_difference (time_, &timer->start, &cur);
+	else
+		visual_time_difference (time_, &timer->start, &timer->stop);
+
+
+	return VISUAL_OK;
+}
+
+/**
+ * Returns the amount of milliseconds passed since the timer has started.
+ * Be aware to not confuse milliseconds with microseconds.
+ *
+ * @param timer Pointer to the VisTimer from which we want to know the amount of milliseconds passed since activation.
+ *
+ * @return The amount of milliseconds passed, or -1 on error, this function is not clockscrew safe.
+ */
+int visual_timer_elapsed_msecs (VisTimer *timer)
+{
+	VisTime cur;
+
+	visual_log_return_val_if_fail (timer != NULL, -1);
+
+	visual_timer_elapsed (timer, &cur);
+
+	return (cur.tv_sec * 1000) + (cur.tv_usec / 1000);
+}
+
+/**
+ * Checks if the timer has passed a certain age.
+ *
+ * @param timer Pointer to the VisTimer which we check for age.
+ * @param time_ Pointer to the VisTime containing the age we check against.
+ *
+ * @return TRUE on passed, FALSE if not passed, -VISUAL_ERROR_TIMER_NULL or -VISUAL_ERROR_TIME_NULL on failure.
+ */
+int visual_timer_has_passed (VisTimer *timer, VisTime *time_)
+{
+	VisTime elapsed;
+
+	visual_log_return_val_if_fail (timer != NULL, -VISUAL_ERROR_TIMER_NULL);
+	visual_log_return_val_if_fail (time_ != NULL, -VISUAL_ERROR_TIME_NULL);
+
+	visual_timer_elapsed (timer, &elapsed);
+
+	if (time_->tv_sec == elapsed.tv_sec && time_->tv_usec <= elapsed.tv_usec)
+		return TRUE;
+	else if (time_->tv_sec < elapsed.tv_sec)
+		return TRUE;
+
+	return FALSE;
+}
+
+/**
+ * Checks if the timer has passed a certain age by values.
+ *
+ * @param timer Pointer to the VisTimer which we check for age.
+ * @param sec The number of seconds we check against.
+ * @param usec The number of microseconds we check against.
+ *
+ * @return TRUE on passed, FALSE if not passed, -VISUAL_ERROR_TIMER_NULL on failure.
+ */
+int visual_timer_has_passed_by_values (VisTimer *timer, long sec, long usec)
+{
+	VisTime passed;
+
+	visual_log_return_val_if_fail (timer != NULL, -VISUAL_ERROR_TIMER_NULL);
+
+	visual_time_set (&passed, sec, usec);
+
+	return visual_timer_has_passed (timer, &passed);
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_time.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,84 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_TIME_H
+#define _LV_TIME_H
+
+#include <sys/time.h>
+#include <time.h>
+
+#include <libvisual/lv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+	
+#define VISUAL_USEC_PER_SEC	1000000
+
+typedef struct _VisTime VisTime;
+typedef struct _VisTimer VisTimer;
+
+/**
+ * The VisTime structure can contain seconds and microseconds for timing purpose.
+ */
+struct _VisTime {
+	VisObject	object;		/**< The VisObject data. */
+	long		tv_sec;		/**< seconds. */
+	long		tv_usec;	/**< microseconds. */
+};
+
+/**
+ * The VisTimer structure is used for timing using the visual_timer_* methods.
+ */
+struct _VisTimer {
+	VisObject	object;		/**< The VisObject data. */
+	VisTime		start;		/**< Private entry to indicate the starting point,
+					 * Shouldn't be read for reliable starting point because
+					 * the visual_timer_continue method changes it's value. */
+	VisTime		stop;		/**< Private entry to indicate the stopping point. */
+
+	int		active;		/**< Private entry to indicate if the timer is currently active or inactive. */
+};
+
+VisTime *visual_time_new (void);
+int visual_time_get (VisTime *time_);
+int visual_time_set (VisTime *time_, long sec, long usec);
+int visual_time_difference (VisTime *dest, VisTime *time1, VisTime *time2);
+int visual_time_copy (VisTime *dest, VisTime *src);
+int visual_time_usleep (unsigned long microseconds);
+
+VisTimer *visual_timer_new (void);
+int visual_timer_is_active (VisTimer *timer);
+int visual_timer_start (VisTimer *timer);
+int visual_timer_stop (VisTimer *timer);
+int visual_timer_continue (VisTimer *timer);
+int visual_timer_elapsed (VisTimer *timer, VisTime *time_);
+int visual_timer_elapsed_msecs (VisTimer *timer);
+int visual_timer_has_passed (VisTimer *timer, VisTime *time_);
+int visual_timer_has_passed_by_values (VisTimer *timer, long sec, long usec);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_TIME_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_transform.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,398 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "lvconfig.h"
+#include "lv_log.h"
+#include "lv_list.h"
+#include "lv_transform.h"
+#include "lv_mem.h"
+
+extern VisList *__lv_plugins_transform;
+
+static int transform_dtor (VisObject *object);
+
+static VisTransformPlugin *get_transform_plugin (VisTransform *transform);
+
+
+static int transform_dtor (VisObject *object)
+{
+	VisTransform *transform = VISUAL_TRANSFORM (object);
+
+	if (transform->plugin != NULL)
+		visual_plugin_unload (transform->plugin);
+
+	transform->plugin = NULL;
+
+	return VISUAL_OK;
+}
+
+static VisTransformPlugin *get_transform_plugin (VisTransform *transform)
+{
+	VisTransformPlugin *transplugin;
+
+	visual_log_return_val_if_fail (transform != NULL, NULL);
+	visual_log_return_val_if_fail (transform->plugin != NULL, NULL);
+
+	transplugin = VISUAL_PLUGIN_TRANSFORM (transform->plugin->info->plugin);
+
+	return transplugin;
+}
+
+/**
+ * @defgroup VisTransform VisTransform
+ * @{
+ */
+
+/**
+ * Gives the encapsulated VisPluginData from a VisTransform.
+ *
+ * @param transform Pointer of a VisTransform of which the VisPluginData needs to be returned.
+ *
+ * @return VisPluginData that is encapsulated in the VisTransform, possibly NULL.
+ */
+VisPluginData *visual_transform_get_plugin (VisTransform *transform)
+{
+	return transform->plugin;
+}
+
+/**
+ * Gives a list of VisTransforms in the current plugin registry.
+ *
+ * @return An VisList containing the VisTransforms in the plugin registry.
+ */
+VisList *visual_transform_get_list ()
+{
+	return __lv_plugins_transform;
+}
+
+/**
+ * Gives the next transform plugin based on the name of a plugin.
+ *
+ * @see visual_transform_get_prev_by_name
+ * 
+ * @param name The name of the current plugin, or NULL to get the first.
+ *
+ * @return The name of the next plugin within the list.
+ */
+const char *visual_transform_get_next_by_name (const char *name)
+{
+	return visual_plugin_get_next_by_name (visual_transform_get_list (), name);
+}
+
+/**
+ * Gives the previous transform plugin based on the name of a plugin.
+ *
+ * @see visual_transform_get_next_by_name
+ * 
+ * @param name The name of the current plugin. or NULL to get the last.
+ *
+ * @return The name of the previous plugin within the list.
+ */
+const char *visual_transform_get_prev_by_name (const char *name)
+{
+	return visual_plugin_get_prev_by_name (visual_transform_get_list (), name);
+}
+
+/**
+ * Checks if the transform plugin is in the registry, based on it's name.
+ *
+ * @param name The name of the plugin that needs to be checked.
+ *
+ * @return TRUE if found, else FALSE.
+ */
+int visual_transform_valid_by_name (const char *name)
+{
+	if (visual_plugin_find (visual_transform_get_list (), name) == NULL)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+/**
+ * Creates a new transform from name, the plugin will be loaded but won't be realized.
+ *
+ * @param transformname
+ * 	The name of the plugin to load, or NULL to simply allocate a new
+ * 	transform. 
+ *
+ * @return A newly allocated VisTransform, optionally containing a loaded plugin. Or NULL on failure.
+ */
+VisTransform *visual_transform_new (const char *transformname)
+{
+	VisTransform *transform;
+	VisPluginRef *ref;
+
+	if (__lv_plugins_transform == NULL && transformname != NULL) {
+		visual_log (VISUAL_LOG_CRITICAL, "the plugin list is NULL");
+		return NULL;
+	}
+	
+	transform = visual_mem_new0 (VisTransform, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (transform), TRUE, transform_dtor);
+
+	if (transformname == NULL)
+		return transform;
+
+	ref = visual_plugin_find (__lv_plugins_transform, transformname);
+
+	transform->plugin = visual_plugin_load (ref);
+
+	return transform;
+}
+
+/**
+ * Realize the VisTransform. This also calls the plugin init function.
+ *
+ * @param transform Pointer to a VisTransform that needs to be realized.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL, -VISUAL_ERROR_PLUGIN_NULL or
+ *	error values returned by visual_plugin_realize () on failure.
+ * 
+ */
+int visual_transform_realize (VisTransform *transform)
+{
+	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
+	visual_log_return_val_if_fail (transform->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+
+	return visual_plugin_realize (transform->plugin);
+}
+
+/**
+ * This function negotiates the VisTransform with it's target video that is set by visual_transform_set_video.
+ * When needed it also sets up size fitting environment and depth transformation environment.
+ *
+ * @param transform Pointer to a VisTransform that needs negotiation.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL, -VISUAL_ERROR_PLUGIN_NULL, -VISUAL_ERROR_PLUGIN_REF_NULL
+ * 	or -VISUAL_ERROR_TRANSFORM_NEGOTIATE on failure. 
+ */ 
+int visual_transform_video_negotiate (VisTransform *transform)
+{
+	int depthflag;
+
+	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
+	visual_log_return_val_if_fail (transform->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+	visual_log_return_val_if_fail (transform->plugin->ref != NULL, -VISUAL_ERROR_PLUGIN_REF_NULL);
+
+	depthflag = visual_transform_get_supported_depth (transform);
+
+	if (visual_video_depth_is_supported (depthflag, transform->video->depth) == FALSE)
+		return -VISUAL_ERROR_TRANSFORM_NEGOTIATE;
+	
+	visual_event_queue_add_resize (&transform->plugin->eventqueue, transform->video,
+			transform->video->width, transform->video->height);
+
+	visual_plugin_events_pump (transform->plugin);
+
+	return -VISUAL_OK;
+}
+
+/**
+ * Gives the by the plugin natively supported depths
+ *
+ * @param transform Pointer to a VisTransform of which the supported depth of it's
+ * 	  encapsulated plugin is requested.
+ *
+ * @return an OR value of the VISUAL_VIDEO_DEPTH_* values which can be checked against using AND on succes,
+ * 	-VISUAL_ERROR_TRANSFORM_NULL, -VISUAL_ERROR_PLUGIN_NULL or -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL on failure.
+ */
+int visual_transform_get_supported_depth (VisTransform *transform)
+{
+	VisTransformPlugin *transplugin;
+
+	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
+	visual_log_return_val_if_fail (transform->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
+
+	transplugin = get_transform_plugin (transform);
+
+	if (transplugin == NULL)
+		return -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL;
+
+	return transplugin->depth;
+}
+
+/**
+ * Used to connect the target display it's VisVideo structure to the VisTransform.
+ *
+ * Using the visual_video methods the screenbuffer, it's depth and dimension and optionally it's pitch
+ * can be set so the transform plugins know about their graphical environment and have a place to draw.
+ *
+ * After this function it's most likely that visual_transform_video_negotiate needs to be called.
+ *
+ * @see visual_video_new
+ * @see visual_transform_video_negotiate
+ * 
+ * @param transform Pointer to a VisTransform to which the VisVideo needs to be set.
+ * @param video Pointer to a VisVideo which contains information about the target display and the pointer
+ * 	  to it's screenbuffer.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL on failure.
+ */
+int visual_transform_set_video (VisTransform *transform, VisVideo *video)
+{
+	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
+
+	transform->video = video;
+
+	if (video != NULL)
+		transform->pal = video->pal;
+	else
+		transform->pal = NULL;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Used to override the palette that is extracted from the VisVideo that is given using
+ * visual_transform_set_video. Always call this function after visual_transform_set_video is called.
+ * 
+ * @see visual_transform_set_video
+ *
+ * @param transform Pointer to a VisTransform to which the VisVideo needs to be set.
+ * @param palette Pointer to the VisPalette which is used to override the palette in the VisTransform.
+ * 
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL on failure.
+ */ 
+int visual_transform_set_palette (VisTransform *transform, VisPalette *palette)
+{
+	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
+
+	transform->pal = palette;
+
+	return VISUAL_OK;
+}
+
+
+/**
+ * This is called to run a VisTransform.
+ *
+ * @see visual_transform_run_video
+ * @see visual_transform_run_palette
+ *
+ * @param transform Pointer to a VisTransform that needs to be runned.
+ * @param audio Pointer to a VisAudio that contains all the audio data.
+ *
+ * return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL or error values returned by
+ *	either visual_transform_run_video or visual_transform_run_palette on failure.
+ */
+int visual_transform_run (VisTransform *transform, VisAudio *audio)
+{
+	int ret;
+	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
+
+	if (transform->video != NULL) {
+		if ((ret = visual_transform_run_video (transform, audio)) != VISUAL_OK)
+			return ret;
+	}
+	
+	if (transform->pal != NULL) {
+		if ((ret = visual_transform_run_palette (transform, audio)) != VISUAL_OK)
+			return ret;
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * This is called to run the video part of a VisTransform.
+ *
+ * @see visual_transform_run
+ *
+ * @param transform Pointer to a VisTransform that needs to be runned.
+ * @param audio Pointer to a VisAudio that contains all the audio data.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL, -VISUAL_ERROR_TRANSFORM_VIDEO_NULL
+ *	or -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL on failure.
+ */
+int visual_transform_run_video (VisTransform *transform, VisAudio *audio)
+{
+	VisTransformPlugin *transplugin;
+	VisPluginData *plugin;
+
+	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
+	visual_log_return_val_if_fail (transform->video != NULL, -VISUAL_ERROR_TRANSFORM_VIDEO_NULL);
+
+	transplugin = get_transform_plugin (transform);
+	plugin = visual_transform_get_plugin (transform);
+
+	if (transplugin == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL,
+			"The given transform does not reference any transform plugin");
+
+		return -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL;
+	}
+
+	visual_plugin_events_pump (plugin);
+
+	transplugin->video (plugin, transform->video, audio);
+
+	return VISUAL_OK;
+}
+
+/**
+ * This is called to run the palette part of a VisTransform.
+ *
+ * @see visual_transform_run
+ *
+ * @param transform Pointer to a VisTransform that needs to be runned.
+ * @param audio Pointer to a VisAudio that contains all the audio data.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL, -VISUAL_ERROR_TRANSFORM_PALETTE_NULL
+ *	or -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL on failure.
+ */
+int visual_transform_run_palette (VisTransform *transform, VisAudio *audio)
+{
+	VisTransformPlugin *transplugin;
+	VisPluginData *plugin;
+
+	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
+	visual_log_return_val_if_fail (transform->pal != NULL, -VISUAL_ERROR_TRANSFORM_PALETTE_NULL);
+
+	transplugin = get_transform_plugin (transform);
+	plugin = visual_transform_get_plugin (transform);
+
+	if (transplugin == NULL) {
+		visual_log (VISUAL_LOG_CRITICAL,
+			"The given transform does not reference any transform plugin");
+
+		return -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL;
+	}
+
+	visual_plugin_events_pump (plugin);
+
+	transplugin->palette (plugin, transform->pal, audio);
+
+	return VISUAL_OK;
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_transform.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,89 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_TRANSFORM_H
+#define _LV_TRANSFORM_H
+
+#include <libvisual/lv_audio.h>
+#include <libvisual/lv_video.h>
+#include <libvisual/lv_palette.h>
+#include <libvisual/lv_plugin.h>
+#include <libvisual/lv_songinfo.h>
+#include <libvisual/lv_event.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_TRANSFORM(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisTransform))
+
+typedef struct _VisTransform VisTransform;
+
+/**
+ * The VisTransform structure encapsulates the transform plugin and provides
+ * abstract interfaces to the transform. 
+ *
+ * Members in the structure shouldn't be accessed directly but instead
+ * it's adviced to use the methods provided.
+ *
+ * @see visual_transform_new
+ */
+struct _VisTransform {
+	VisObject	 object;		/**< The VisObject data. */
+
+	VisPluginData	*plugin;		/**< Pointer to the plugin itself. */
+
+	/* Video management and fake environments when needed */
+	VisVideo	*video;			/**< Pointer to the target display video. 
+						 * @see visual_transform_set_video */
+	VisPalette	*pal;			/**< Pointer to the VisPalette that is to be transformed.
+						 * @see visual_transform_set_palette */
+};
+
+/* prototypes */
+VisPluginData *visual_transform_get_plugin (VisTransform *transform);
+
+VisList *visual_transform_get_list (void);
+const char *visual_transform_get_next_by_name (const char *name);
+const char *visual_transform_get_prev_by_name (const char *name);
+int visual_transform_valid_by_name (const char *name);
+
+VisTransform *visual_transform_new (const char *transformname);
+
+int visual_transform_realize (VisTransform *transform);
+
+int visual_transform_video_negotiate (VisTransform *transform);
+int visual_transform_get_supported_depth (VisTransform *transform);
+
+int visual_transform_set_video (VisTransform *transform, VisVideo *video);
+int visual_transform_set_palette (VisTransform *transform, VisPalette *palette);
+
+int visual_transform_run (VisTransform *transform, VisAudio *audio);
+int visual_transform_run_video (VisTransform *transform, VisAudio *audio);
+int visual_transform_run_palette (VisTransform *transform, VisAudio *audio);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_TRANSFORM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_types.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,51 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_TYPES_H
+#define _LV_TYPES_H
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_CHECK_CAST(uiobj, cast_type, cast)    ((cast*) (uiobj))
+
+#ifndef uint8_t
+#define uint8_t		u_int8_t
+#endif
+	
+#ifndef uint16_t
+#define uint16_t	u_int16_t
+#endif
+
+#ifndef uint32_t
+#define uint32_t	u_int32_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_TYPES_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_ui.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,1169 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include "lv_log.h"
+#include "lv_ui.h"
+
+static int box_dtor (VisObject *object);
+static int table_dtor (VisObject *object);
+static int table_entry_dtor (VisObject *object);
+static int frame_dtor (VisObject *object);
+static int choice_dtor (VisObject *object);
+static int widget_dtor (VisObject *object);
+
+static int box_dtor (VisObject *object)
+{
+	VisUIBox *box = VISUAL_UI_BOX (object);
+
+	visual_list_destroy_elements (&box->childs);
+
+	widget_dtor (object);
+
+	return VISUAL_OK;
+}
+
+static int table_dtor (VisObject *object)
+{
+	VisUITable *table = VISUAL_UI_TABLE (object);
+
+	visual_list_destroy_elements (&table->childs);
+	
+	widget_dtor (object);
+
+	return VISUAL_OK;
+}
+
+static int table_entry_dtor (VisObject *object)
+{
+	VisUITableEntry *tentry = VISUAL_UI_TABLE_ENTRY (object);
+
+	if (tentry->widget != NULL)
+		visual_object_unref (VISUAL_OBJECT (tentry->widget));
+
+	tentry->widget = NULL;
+
+	return VISUAL_OK;
+}
+
+static int frame_dtor (VisObject *object)
+{
+	VisUIContainer *container = VISUAL_UI_CONTAINER (object);
+
+	if (container->child != NULL)
+		visual_object_unref (VISUAL_OBJECT (container->child));
+
+	container->child = NULL;
+
+	widget_dtor (object);
+
+	return VISUAL_OK;
+}
+
+
+static int choice_dtor (VisObject *object)
+{
+	visual_ui_choice_free_choices (VISUAL_UI_CHOICE (object));
+
+	widget_dtor (object);
+	
+	return VISUAL_OK;
+}
+
+static int widget_dtor (VisObject *object)
+{
+	VisUIWidget *widget = VISUAL_UI_WIDGET (object);
+
+	if (widget->tooltip != NULL)
+		visual_mem_free ((char *) widget->tooltip);
+
+	widget->tooltip = NULL;
+
+	return VISUAL_OK;
+}
+
+/**
+ * @defgroup VisUI VisUI
+ * @{
+ */
+
+/**
+ * Creates a new VisUIWidget structure.
+ *
+ * @return A newly allocated VisUIWidget, or NULL on failure.
+ */
+VisUIWidget *visual_ui_widget_new ()
+{
+	VisUIWidget *widget;
+
+	widget = visual_mem_new0 (VisUIWidget, 1);
+	widget->type = VISUAL_WIDGET_TYPE_NULL;
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (widget), TRUE, widget_dtor);
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (widget), -1, -1);
+
+	return widget;
+}
+
+/**
+ * Sets a request for size to a VisUIWidget, to be used to request a certain dimension.
+ *
+ * @param widget Pointer to the VisUIWidget to which the size request is set.
+ * @param width The width in pixels of the size requested.
+ * @param height The height in pixels of the size requested.
+ *
+ * @return VISUAL_OK on succes, or -VISUAL_ERROR_UI_WIDGET_NULL on failure.
+ */
+int visual_ui_widget_set_size_request (VisUIWidget *widget, int width, int height)
+{
+	visual_log_return_val_if_fail (widget != NULL, -VISUAL_ERROR_UI_WIDGET_NULL);
+
+	widget->width = width;
+	widget->height = height;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets a tooltip to a VisUIWidget.
+ *
+ * @param widget Pointer to the VisUIWidget to which the tooltip is set.
+ * @param tooltip A string containing the tooltip text.
+ *
+ * @return VISUAL_OK on succes, or -VISUAL_ERROR_UI_WIDGET_NULL on failure.
+ */
+int visual_ui_widget_set_tooltip (VisUIWidget *widget, const char *tooltip)
+{
+	visual_log_return_val_if_fail (widget != NULL, -VISUAL_ERROR_UI_WIDGET_NULL);
+
+	if (widget->tooltip != NULL)
+		visual_mem_free ((char *) widget->tooltip);
+	
+	widget->tooltip = strdup (tooltip);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Retrieves the tooltip that is set to a VisUIWidget.
+ *
+ * @param widget Pointer to the VisUIWidget from which the tooltip is requested.
+ *
+ * @return The tooltip, possibly NULL, NULL on failure.
+ */
+const char *visual_ui_widget_get_tooltip (VisUIWidget *widget)
+{
+	visual_log_return_val_if_fail (widget != NULL, NULL);
+
+	return widget->tooltip;
+}
+
+/**
+ * Gets the top VisUIWidget from a VisUIWidget, this means that it will retrieve
+ * the widget that is the parent of all underlaying widgets.
+ *
+ * @param widget Pointer to the VisUIWidget of which we want to have the top VisUIWidget.
+ *
+ * @return Pointer to the top VisUIWidget, or NULL on failure.
+ */
+VisUIWidget *visual_ui_widget_get_top (VisUIWidget *widget)
+{
+	VisUIWidget *above;
+	VisUIWidget *prev = widget;
+
+	visual_log_return_val_if_fail (widget != NULL, NULL);
+
+	while ((above = visual_ui_widget_get_parent (widget)) != NULL) {
+		prev = widget;
+	}
+
+	return prev;
+}
+
+/**
+ * Gets the parent VisUIWidget from a VisUIWidget, this retrieves the parent of the given
+ * widget.
+ *
+ * @param widget Pointer to the VisUIWidget of which the parent is requested.
+ *
+ * @return Pointer to the parent VisUIWidget, or NULL on failure.
+ */
+VisUIWidget *visual_ui_widget_get_parent (VisUIWidget *widget)
+{
+	visual_log_return_val_if_fail (widget != NULL, NULL);
+
+	return widget->parent;
+}
+
+/**
+ * Gets the VisUIWidgetType type from a VisUIWidget, this contains what kind of widget the given
+ * VisUIWidget is.
+ *
+ * @param widget Pointer to the VisUIWidget of which the type is requested.
+ *
+ * @return The VisUIWidgetType of the given VisUIWidget.
+ */
+VisUIWidgetType visual_ui_widget_get_type (VisUIWidget *widget)
+{
+	visual_log_return_val_if_fail (widget != NULL, VISUAL_WIDGET_TYPE_NULL);
+
+	return widget->type;
+}
+
+/**
+ * Adds a VisUIWidget to a VisUIContainer.
+ *
+ * @see visual_ui_box_pack
+ * @see visual_ui_table_attach
+ * 
+ * @param container Pointer to the VisUIContainer in which a VisUIWidget is put.
+ * @param widget Pointer to the VisUIWidget that is been put in the VisUIContainer.
+ *
+ * @return VISUAL_OK on succes, or -VISUAL_ERROR_UI_CONTAINER_NULL, -VISUAL_ERROR_UI_WIDGET_NULL on failure.
+ */
+int visual_ui_container_add (VisUIContainer *container, VisUIWidget *widget)
+{
+	visual_log_return_val_if_fail (container != NULL, -VISUAL_ERROR_UI_CONTAINER_NULL);
+	visual_log_return_val_if_fail (widget != NULL, -VISUAL_ERROR_UI_WIDGET_NULL);
+
+	container->child = widget;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Gets the child VisUIWidget from a VisUIContainer.
+ *
+ * @param container Pointer to the VisUIContainer of which we want the child VisUIWidget.
+ *
+ * @return The child VisUIWidget, or NULL on failure.
+ */
+VisUIWidget *visual_ui_container_get_child (VisUIContainer *container)
+{
+	visual_log_return_val_if_fail (container != NULL, NULL);
+
+	return container->child;
+}
+
+/**
+ * Creates a new VisUIBox, that can be used to pack VisUIWidgets in.
+ *
+ * @param orient Indicates the orientation style of the box, being either
+ * 	VISUAL_ORIENT_TYPE_HORIZONTAL or VISUAL_ORIENT_TYPE_VERTICAL.
+ *
+ * @return The newly created VisUIBox in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_box_new (VisUIOrientType orient)
+{
+	VisUIBox *box;
+
+	box = visual_mem_new0 (VisUIBox, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (box), TRUE, box_dtor);
+
+	VISUAL_UI_WIDGET (box)->type = VISUAL_WIDGET_TYPE_BOX;
+
+	box->orient = orient;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (box), -1, -1);
+
+	visual_list_set_destroyer (&box->childs, visual_object_list_destroyer);
+
+	return VISUAL_UI_WIDGET (box);
+}
+
+/**
+ * Packs VisUIWidgets into a VisUIBox, this can be used to pack widgets either vertically or horizontally,
+ * depending on the type of box.
+ *
+ * @param box Pointer to the VisUIBox in which the widget is packed.
+ * @param widget Pointer to the VisUIWidget which is packed in the box.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_BOX_NULL, -VISUAL_ERROR_UI_WIDGET_NULL or
+ * 	error values returned by visual_list_add () on failure.
+ */
+int visual_ui_box_pack (VisUIBox *box, VisUIWidget *widget)
+{
+	visual_log_return_val_if_fail (box != NULL, -VISUAL_ERROR_UI_BOX_NULL);
+	visual_log_return_val_if_fail (widget != NULL, -VISUAL_ERROR_UI_WIDGET_NULL);
+
+	return visual_list_add (&box->childs, widget);
+}
+
+/**
+ * Retrieve a VisList of VisUIWidget elements, being the childs of the VisUIBox.
+ * 
+ * @param box Pointer to the VisUIBox from which the childs are requested.
+ * 
+ * @return VisList containing the childs of the VisUIBox or NULL on failure.
+ */
+VisList *visual_ui_box_get_childs (VisUIBox *box)
+{
+	VisUIWidget *next;
+	VisListEntry *le = NULL;
+
+	visual_log_return_val_if_fail (box != NULL, NULL);
+
+	return &box->childs;
+}
+
+/**
+ * Get the VisUIOrientType value from a VisUIBox.
+ *
+ * @param box VisUIBox from which the VisUIOrientType is requested.
+ *
+ * @return VisUIOrientType containing the orientation style for this VisUIBox.
+ */
+VisUIOrientType visual_ui_box_get_orient (VisUIBox *box)
+{
+	visual_log_return_val_if_fail (box != NULL, VISUAL_ORIENT_TYPE_NONE);
+
+	return box->orient;
+}
+
+/**
+ * Creates a new VisUITable, that can be used to attach VisUIWidgets to cells in the table.
+ *
+ * @param rows The number of rows in the table.
+ * @param cols The number of columns in the table.
+ *
+ * @return The newly created VisUITable in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_table_new (int rows, int cols)
+{
+	VisUITable *table;
+
+	table = visual_mem_new0 (VisUITable, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (table), TRUE, table_dtor);
+
+	VISUAL_UI_WIDGET (table)->type = VISUAL_WIDGET_TYPE_TABLE;
+
+	table->rows = rows;
+	table->cols = cols;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (table), -1, -1);
+
+	visual_list_set_destroyer (&table->childs, visual_object_list_destroyer);
+
+	return VISUAL_UI_WIDGET (table);
+}
+
+/**
+ * Creates a new VisUITableEntry. You probably never need this function, but it's used internally.
+ *
+ * @param widget Pointer to the VisUIWidget of which a VisUITableEntry is created.
+ * @param row The row this entry will be placed.
+ * @param col The column this entry will be placed.
+ *
+ * @return A newly allocated VisUITableEntry, NULL on failure.
+ */
+VisUITableEntry *visual_ui_table_entry_new (VisUIWidget *widget, int row, int col)
+{
+	VisUITableEntry *tentry;
+	
+	visual_log_return_val_if_fail (widget != NULL, NULL);
+
+	tentry = visual_mem_new0 (VisUITableEntry, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (tentry), TRUE, table_entry_dtor);
+
+	tentry->row = row;
+	tentry->col = col;
+
+	tentry->widget = widget;
+
+	return tentry;
+}
+
+/**
+ * Attaches a VisUIWidget to a cell within a VisUITable.
+ * 
+ * @param table Pointer to the VisUITable to which a VisUiWidget is attached.
+ * @param widget Pointer to the VisUIWidget that is being attached to the VisUITable.
+ * @param row The row number starting at 0.
+ * @param col The column number starting at 0.
+ * 
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_TABLE_NULL, -VISUAL_ERROR_UI_WIDGET_NULL or
+ * 	error values returned by visual_list_add () on failure.
+ */
+int visual_ui_table_attach (VisUITable *table, VisUIWidget *widget, int row, int col)
+{
+	VisUITableEntry *tentry;
+
+	visual_log_return_val_if_fail (table != NULL, -VISUAL_ERROR_UI_TABLE_NULL);
+	visual_log_return_val_if_fail (widget != NULL, -VISUAL_ERROR_UI_WIDGET_NULL);
+
+	tentry = visual_ui_table_entry_new (widget, row, col);
+
+	return visual_list_add (&table->childs, tentry);
+}
+
+/**
+ * Retrieve a VisList containing VisUITableEntry elements, in which the child VisUIWidget and it's place
+ * 	in the VisUITable is stored.
+ *
+ * @param table Pointer to the VisUITable from which the childs are requested.
+ *
+ * @return VisList containing the childs of the VisUITable, or NULL on failure.
+ */
+VisList *visual_ui_table_get_childs (VisUITable *table)
+{
+	visual_log_return_val_if_fail (table != NULL, NULL);
+
+	return &table->childs;
+}
+
+/**
+ * Creates a new VisUIFrame, which can be used to put a frame around a VisUIWidget.
+ * 
+ * @param name The name of this frame.
+ *
+ * @return The newly created VisUIFrame in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_frame_new (const char *name)
+{
+	VisUIFrame *frame;
+
+	frame = visual_mem_new0 (VisUIFrame, 1);
+	
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (frame), TRUE, frame_dtor);
+
+	VISUAL_UI_WIDGET (frame)->type = VISUAL_WIDGET_TYPE_FRAME;
+
+	frame->name = name;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (frame), -1, -1);
+	
+	return VISUAL_UI_WIDGET (frame);
+}
+
+/**
+ * Creates a new VisUILabel, which can be used as a one line piece of text in an user interface.
+ *
+ * @param text Text of which the label consists.
+ * @param bold Flag that indicates if a label should be drawn bold or not.
+ *
+ * @return The newly created VisUILabel in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_label_new (const char *text, int bold)
+{
+	VisUILabel *label;
+
+	label = visual_mem_new0 (VisUILabel, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (label), TRUE, widget_dtor);
+
+	VISUAL_UI_WIDGET (label)->type = VISUAL_WIDGET_TYPE_LABEL;
+
+	label->text = text;
+	label->bold = bold;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (label), -1, -1);
+	
+	return VISUAL_UI_WIDGET (label);
+}
+
+/**
+ * Sets the bold flag for a VisUILabel.
+ * 
+ * @param label Pointer to the VisUILabel of which the bold flag is set, or unset.
+ * @param bold Flag that indicates if a label should be drawn bold or not.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_LABEL_NULL on failure.
+ */
+int visual_ui_label_set_bold (VisUILabel *label, int bold)
+{
+	visual_log_return_val_if_fail (label != NULL, -VISUAL_ERROR_UI_LABEL_NULL);
+
+	label->bold = bold;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the text for a VisUILabel.
+ *
+ * @param label Pointer to the VisUILabel to which text is being set.
+ * @param text The text that is being set to the VisUILabel.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_LABEL_NULL on failure.
+ */
+int visual_ui_label_set_text (VisUILabel *label, const char *text)
+{
+	visual_log_return_val_if_fail (label != NULL, -VISUAL_ERROR_UI_LABEL_NULL);
+
+	label->text = text;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Retrieve the text from a VisUILabel.
+ *
+ * @param label Pointer to the VisUILabel from which the text is being requested.
+ * 
+ * return The text contained in the label, NULL on failure.
+ */
+const char *visual_ui_label_get_text (VisUILabel *label)
+{
+	visual_log_return_val_if_fail (label != NULL, NULL);
+
+	return label->text;
+}
+
+/**
+ * Creates a new VisUIImage, which can contain an image, loaded from a VisVideo.
+ *
+ * @param video The VisVideo containing the image to be displayed.
+ *
+ * @return The newly created VisUIImage in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_image_new (VisVideo *video)
+{
+	VisUIImage *image;
+
+	image = visual_mem_new0 (VisUIImage, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (image), TRUE, widget_dtor);
+
+	VISUAL_UI_WIDGET (image)->type = VISUAL_WIDGET_TYPE_IMAGE;
+
+	image->image = video;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (image), -1, -1);
+
+	return VISUAL_UI_WIDGET (image);
+}
+
+/**
+ * Sets a VisVideo to a VisUIImage. The VisVideo contains the content of the image.
+ *
+ * @param image Pointer to the VisUIImage to which the VisVideo is set.
+ * @param video Pointer to the VisVideo that is set to the VisUIImage.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_IMAGE_NULL on failure.
+ */
+int visual_ui_image_set_video (VisUIImage *image, VisVideo *video)
+{
+	visual_log_return_val_if_fail (image != NULL, -VISUAL_ERROR_UI_IMAGE_NULL);
+
+	image->image = video;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Retrieves the VisVideo from a VisUIImage.
+ *
+ * @param image Pointer to the VisUIImage from which the VisVideo is requested.
+ * 
+ * return The VisVideo that is connected to the VisUIImage.
+ */
+VisVideo *visual_ui_image_get_video (VisUIImage *image)
+{
+	visual_log_return_val_if_fail (image != NULL, NULL);
+
+	return image->image;
+}
+
+/**
+ * Creates a new VisUISeparator, which can function as a separation item between other VisUIWidgets.
+ *
+ * @param orient Indicates the orientation style of the separator, being either
+ *	VISUAL_ORIENT_TYPE_HORIZONTAL or VISUAL_ORIENT_TYPE_VERTICAL.
+ *
+ * @return The newly created VisUISeparator in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_separator_new (VisUIOrientType orient)
+{
+	VisUISeparator *separator;
+
+	separator = visual_mem_new0 (VisUISeparator, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (separator), TRUE, widget_dtor);
+
+	VISUAL_UI_WIDGET (separator)->type = VISUAL_WIDGET_TYPE_SEPARATOR;
+
+	separator->orient = orient;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (separator), -1, -1);
+
+	return VISUAL_UI_WIDGET (separator);
+}
+
+/**
+ * Get the VisUIOrientType value from a VisUISeparator.
+ *
+ * @param separator VisUISeparator from which the VisUIOrientType is requested.
+ *
+ * @return VisUIOrientType containing the orientation style for this VisUISeparator.
+ */
+VisUIOrientType visual_ui_separator_get_orient (VisUISeparator *separator)
+{
+	visual_log_return_val_if_fail (separator != NULL, VISUAL_ORIENT_TYPE_NONE);
+
+	return separator->orient;
+}
+
+/**
+ * Links a VisParamEntry to a VisUIMutator type.
+ *
+ * @param mutator Pointer to the VisUIMutator to which the VisParamEntry is linked.
+ * @param param Pointer to the VisParamEntry that is linked to the VisUIMutator.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_MUTATOR_NULL or -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_ui_mutator_set_param (VisUIMutator *mutator, VisParamEntry *param)
+{
+	visual_log_return_val_if_fail (mutator != NULL, -VISUAL_ERROR_UI_MUTATOR_NULL);
+	visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	/* FIXME Check if param is valid with mutator type, if not, give a critical */
+
+	mutator->param = param;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Request the VisParamEntry that is linked to a VisUIMutator.
+ *
+ * @param mutator Pointer to the VisUIMutator from which the VisParamEntry is requested.
+ *
+ * return The VisParamEntry that links to the VisUIMutator, or NULL on failure.
+ */
+VisParamEntry *visual_ui_mutator_get_param (VisUIMutator *mutator)
+{
+	visual_log_return_val_if_fail (mutator != NULL, NULL);
+
+	return mutator->param;
+}
+
+/**
+ * Set the properties for a VisUIRange.
+ *
+ * @param range Pointer to the VisUIRange to which the properties are set.
+ * @param min The minimal value.
+ * @param max The maximal value.
+ * @param step The increase/decrease step value.
+ * @param precision The precision in numbers behind the comma.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_RANGE_NULL on failure.
+ */
+int visual_ui_range_set_properties (VisUIRange *range, double min, double max, double step, int precision)
+{
+	visual_log_return_val_if_fail (range != NULL, -VISUAL_ERROR_UI_RANGE_NULL);
+
+	range->min = min;
+	range->max = max;
+	range->step = step;
+	range->precision = precision;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the maximal value for a VisUIRange.
+ *
+ * @param range Pointer to the VisUIRange to which the maximum value is set.
+ * @param max The maximal value.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_RANGE_NULL on failure.
+ */
+int visual_ui_range_set_max (VisUIRange *range, double max)
+{
+	visual_log_return_val_if_fail (range != NULL, -VISUAL_ERROR_UI_RANGE_NULL);
+
+	range->max = max;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the minimal value for a VisUIRange.
+ *
+ * @param range Pointer to the VisUIRange to which the minimal value is set.
+ * @param min The minimal value.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_RANGE_NULL on failure.
+ */
+int visual_ui_range_set_min (VisUIRange *range, double min)
+{
+	visual_log_return_val_if_fail (range != NULL, -VISUAL_ERROR_UI_RANGE_NULL);
+
+	range->min = min;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the increase/decrease step size for a VisUIRange.
+ *
+ * @param range Pointer to the VisUIRange to which the step size value is set.
+ * @param step The increase/decrase step value.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_RANGE_NULL on failure.
+ */
+int visual_ui_range_set_step (VisUIRange *range, double step)
+{
+	visual_log_return_val_if_fail (range != NULL, -VISUAL_ERROR_UI_RANGE_NULL);
+
+	range->step = step;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the precision for a VisUIRange.
+ *
+ * @param range Pointer to the VisUIRange to which the step size value is set.
+ * @param precision The precision in numbers behind the comma.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_RANGE_NULL on failure.
+ */
+int visual_ui_range_set_precision (VisUIRange *range, int precision)
+{
+	visual_log_return_val_if_fail (range != NULL, -VISUAL_ERROR_UI_RANGE_NULL);
+
+	range->precision = precision;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Creates a new VisUIEntry, which can be used to enter text.
+ *
+ * @return The newly created VisUIEntry in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_entry_new ()
+{
+	VisUIEntry *entry;
+
+	entry = visual_mem_new0 (VisUIEntry, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (entry), TRUE, widget_dtor);
+
+	VISUAL_UI_WIDGET (entry)->type = VISUAL_WIDGET_TYPE_ENTRY;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (entry), -1, -1);
+
+	return VISUAL_UI_WIDGET (entry);
+}
+
+/**
+ * Sets the maximum length for the text in a VisUIEntry.
+ *
+ * @param entry Pointer to the VisUIEntry to which the maximum text length is set.
+ * @param length The maximum text length for the VisUIEntry.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_ENTRY_NULL on failure.
+ */
+int visual_ui_entry_set_length (VisUIEntry *entry, int length)
+{
+	visual_log_return_val_if_fail (entry != NULL, -VISUAL_ERROR_UI_ENTRY_NULL);
+
+	entry->length = length;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Creates a new VisUISlider, which can be used as a VisUIRange type, in the form of a slider.
+ *
+ * @param showvalue Show the value of the slider place.
+ * 
+ * @return The newly created VisUISlider in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_slider_new (int showvalue)
+{
+	VisUISlider *slider;
+
+	slider = visual_mem_new0 (VisUISlider, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (slider), TRUE, widget_dtor);
+
+	VISUAL_UI_WIDGET (slider)->type = VISUAL_WIDGET_TYPE_SLIDER;
+
+	slider->showvalue = showvalue;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (slider), -1, -1);
+
+	return VISUAL_UI_WIDGET (slider);
+}
+
+/**
+ * Creates a new VisUINumerici, which can be used as a VisUIRange type, in the form of a numeric spinbutton.
+ *
+ * @return The newly created VisUINumeric in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_numeric_new ()
+{
+	VisUINumeric *numeric;
+
+	numeric = visual_mem_new0 (VisUINumeric, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (numeric), TRUE, widget_dtor);
+
+	VISUAL_UI_WIDGET (numeric)->type = VISUAL_WIDGET_TYPE_NUMERIC;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (numeric), -1, -1);
+
+	return VISUAL_UI_WIDGET (numeric);
+}
+
+/**
+ * Creates a new VisUIColor, which can be used to select a color.
+ *
+ * @return The newly created VisUIColor in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_color_new ()
+{
+	VisUIColor *color;
+
+	color = visual_mem_new0 (VisUIColor, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (color), TRUE, widget_dtor);
+	
+	VISUAL_UI_WIDGET (color)->type = VISUAL_WIDGET_TYPE_COLOR;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (color), -1, -1);
+
+	return VISUAL_UI_WIDGET (color);
+}
+
+/**
+ * Creates a new VisUIChoiceEntry, this is an entry in an entry in VisUIChoiceList, that is used
+ * by the different VisUIChoice inherentence.
+ *
+ * @param name The name ofe the choice.
+ * @param value The VisParamEntry associated with this choice.
+ *
+ * @return The newly created VisUIChoiceEntry.
+ */
+VisUIChoiceEntry *visual_ui_choice_entry_new (const char *name, VisParamEntry *value)
+{
+	VisUIChoiceEntry *centry;
+
+	visual_log_return_val_if_fail (name != NULL, NULL);
+	visual_log_return_val_if_fail (value != NULL, NULL);
+
+	centry = visual_mem_new0 (VisUIChoiceEntry, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (centry), TRUE, NULL);
+	
+	centry->name = name;
+	centry->value = value;
+
+	return centry;
+}
+
+/**
+ * Add a VisParamEntry as a choice for a VisUIWidget that inherents from VisUIChoice.
+ *
+ * @param choice Pointer to the VisUIChoice widget to which the choice is added.
+ * @param name The name of this choice.
+ * @param value Pointer to the VisParamEntry that is associated with this choice.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_CHOICE_NULL, -VISUAL_ERROR_NULL
+ *	or -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_ui_choice_add (VisUIChoice *choice, const char *name, VisParamEntry *value)
+{
+	VisUIChoiceEntry *centry;
+
+	visual_log_return_val_if_fail (choice != NULL, -VISUAL_ERROR_UI_CHOICE_NULL);
+	visual_log_return_val_if_fail (name != NULL, -VISUAL_ERROR_NULL);
+	visual_log_return_val_if_fail (value != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	centry = visual_ui_choice_entry_new (name, value);
+
+	choice->choices.count++;
+
+	visual_list_add (&choice->choices.choices, centry);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Add many choices using a VisParamEntry array.
+ *
+ * @see visual_ui_choice_add
+ *
+ * @param choice Pointer to the VisUIChoice widget to which the choices are added.
+ * @param paramchoices Pointer to the array of VisParamEntries that are added to the internal
+ *	VisUIChoiceList of the VisUIChoice widget.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_CHOICE_NULL or -VISUAL_ERROR_PARAM_NULL on failure.
+ */
+int visual_ui_choice_add_many (VisUIChoice *choice, VisParamEntry *paramchoices)
+{
+	VisUIChoiceEntry *centry;
+	int i = 0;
+
+	visual_log_return_val_if_fail (choice != NULL, -VISUAL_ERROR_UI_CHOICE_NULL);
+	visual_log_return_val_if_fail (paramchoices != NULL, -VISUAL_ERROR_PARAM_NULL);
+
+	while (paramchoices[i].type != VISUAL_PARAM_ENTRY_TYPE_END) {
+		visual_ui_choice_add (choice, paramchoices[i].name, &paramchoices[i]);
+
+		i++;
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Frees all the memory used by the VisUIChoiceList and it's entries for the given VisUIChoice.
+ *
+ * @param choice Pointer to the VisUIChoice for which the VisUIChoiceList and it's entries
+ *	are being freed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_CHOICE_NULL on failure.
+ */
+int visual_ui_choice_free_choices (VisUIChoice *choice)
+{
+	visual_log_return_val_if_fail (choice != NULL, -VISUAL_ERROR_UI_CHOICE_NULL);
+
+	visual_list_set_destroyer (&choice->choices.choices, visual_object_list_destroyer);
+	visual_list_destroy_elements (&choice->choices.choices); 
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the active choice for a VisUIChoice widget.
+ *
+ * @param choice Pointer to the VisUIChoice widget for which an entry is being activated.
+ * @param index Index containing which choice needs to be activated, counting starts at 0.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_UI_CHOICE_NULL, -VISUAL_ERROR_UI_CHOICE_ENTRY_NULL or
+ *	error values returned by visual_ui_mutator_get_param () on failure.
+ */
+int visual_ui_choice_set_active (VisUIChoice *choice, int index)
+{
+	VisUIChoiceEntry *centry;
+	VisParamEntry *param;
+	VisParamEntry *newparam;
+
+	visual_log_return_val_if_fail (choice != NULL, -VISUAL_ERROR_UI_CHOICE_NULL);
+
+	centry = visual_ui_choice_get_choice (choice, index);
+	visual_log_return_val_if_fail (centry != NULL, -VISUAL_ERROR_UI_CHOICE_ENTRY_NULL);
+
+	param = visual_ui_mutator_get_param (VISUAL_UI_MUTATOR (choice));
+
+	newparam = (VisParamEntry *) centry->value;
+
+	return visual_param_entry_set_from_param (param, newparam);
+}
+
+/**
+ * Retrieves the index of the current active choice.
+ *
+ * @param choice Pointer to the VisUIChoice widget from which the active choice is requested.
+ *
+ * @return Index of the active choice entry.
+ */
+int visual_ui_choice_get_active (VisUIChoice *choice)
+{
+	VisListEntry *le = NULL;
+	VisUIChoiceEntry *centry;
+	VisParamEntry *param;
+	int i = 0;
+
+	visual_log_return_val_if_fail (choice != NULL, -VISUAL_ERROR_UI_CHOICE_NULL);
+
+	param = visual_ui_mutator_get_param (VISUAL_UI_MUTATOR (choice));
+
+	while ((centry = visual_list_next (&choice->choices.choices, &le)) != NULL) {
+		VisParamEntry *cparam;
+		
+		cparam = centry->value;
+
+		if (visual_param_entry_compare (param, cparam) == TRUE)
+			return i;
+
+		i++;
+	}
+
+	return -VISUAL_ERROR_UI_CHOICE_NONE_ACTIVE;
+}
+
+/**
+ * Retrieves a VisUIChoiceEntry from a VisUIChoice based on the index.
+ *
+ * @param choice Pointer to the VisUIChoice widget from which a VisUIChoiceEntry is requested.
+ * @param index Index of the requested VisUIChoiceEntry.
+ *
+ * @return The VisUIChoiceEntry that is located on the given index, or NULL on failure.
+ */
+VisUIChoiceEntry *visual_ui_choice_get_choice (VisUIChoice *choice, int index)
+{
+	visual_log_return_val_if_fail (choice != NULL, NULL);
+
+	return visual_list_get (&choice->choices.choices, index);
+}
+
+/**
+ * Retrvies the VisUIChoiceList from a VisUIChoice widget.
+ *
+ * @param choice Pointer to the VisUIChoice widget from which the VisUIChoiceList is requested.
+ * 
+ * @return The VisUIChoiceList that is associated to the VisUIChoice.
+ */
+VisUIChoiceList *visual_ui_choice_get_choices (VisUIChoice *choice)
+{
+	visual_log_return_val_if_fail (choice != NULL, NULL);
+
+	return &choice->choices;
+}
+
+/**
+ * Creates a new VisUIPopup. This can be used to show a popup list containing items from which
+ * can be choosen.
+ *
+ * @return The newly created VisUIPopup in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_popup_new ()
+{
+	VisUIPopup *popup;
+
+	popup = visual_mem_new0 (VisUIPopup, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (popup), TRUE, choice_dtor);
+	
+	VISUAL_UI_WIDGET (popup)->type = VISUAL_WIDGET_TYPE_POPUP;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (popup), -1, -1);
+
+	return VISUAL_UI_WIDGET (popup);
+}
+
+/**
+ * Creates a new VisUIList. This can be used to show a list containing items from which
+ * can be choosen.
+ *
+ * @return The newly created VisUIList in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_list_new ()
+{
+	VisUIList *list;
+
+	list = visual_mem_new0 (VisUIList, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (list), TRUE, choice_dtor);
+	
+	VISUAL_UI_WIDGET (list)->type = VISUAL_WIDGET_TYPE_LIST;
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (list), -1, -1);
+
+	return VISUAL_UI_WIDGET (list);
+}
+
+/**
+ * Creates a new VisUIRadio. This can be used to show a list of radio buttons containing items from which
+ * can be choosen.
+ *
+ * @param orient The orientation of the radio button layout.
+ * 
+ * @return The newly created VisUIRadio in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_radio_new (VisUIOrientType orient)
+{
+	VisUIRadio *radio;
+
+	radio = visual_mem_new0 (VisUIRadio, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (radio), TRUE, choice_dtor);
+
+	VISUAL_UI_WIDGET (radio)->type = VISUAL_WIDGET_TYPE_RADIO;
+
+	radio->orient = orient;
+	
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (radio), -1, -1);
+
+	return VISUAL_UI_WIDGET (radio);
+}
+
+/**
+ * Creates a new VisUICheckbox. This can be used to show a checkbox that can be toggled and untoggled.
+ *
+ * @param name The text behind the checkbox.
+ * @param boolcheck Automaticly set a boolean, TRUE and FALSE VisUIChoiceList on the VisUICheckbox.
+ *
+ * @return The newly created VisUICheckbox in the form of a VisUIWidget.
+ */
+VisUIWidget *visual_ui_checkbox_new (const char *name, int boolcheck)
+{
+	VisUICheckbox *checkbox;
+	static VisParamEntry truefalse[] = {
+		VISUAL_PARAM_LIST_ENTRY_INTEGER ("false",	FALSE),
+		VISUAL_PARAM_LIST_ENTRY_INTEGER ("true",	TRUE),
+		VISUAL_PARAM_LIST_END
+	};
+
+	checkbox = visual_mem_new0 (VisUICheckbox, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (checkbox), TRUE, choice_dtor);
+
+	VISUAL_UI_WIDGET (checkbox)->type = VISUAL_WIDGET_TYPE_CHECKBOX;
+
+	checkbox->name = name;
+
+	/* Boolean checkbox, generate a FALSE, TRUE choicelist ourself */
+	if (boolcheck == TRUE)
+		visual_ui_choice_add_many (VISUAL_UI_CHOICE (checkbox), truefalse);
+
+	visual_ui_widget_set_size_request (VISUAL_UI_WIDGET (checkbox), -1, -1);
+
+	return VISUAL_UI_WIDGET (checkbox);
+}
+
+/**
+ * @}
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_ui.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,472 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_UI_H
+#define _LV_UI_H
+
+#include <libvisual/lv_list.h>
+#include <libvisual/lv_param.h>
+#include <libvisual/lv_video.h>
+#include <libvisual/lv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_UI_WIDGET(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_WIDGET, VisUIWidget))
+#define VISUAL_UI_CONTAINER(obj)			(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_CONTAINER, VisUIContainer))
+#define VISUAL_UI_BOX(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_BOX, VisUIBox))
+#define VISUAL_UI_TABLE_ENTRY(obj)			(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_TABLE, VisUITableEntry))
+#define VISUAL_UI_TABLE(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_TABLE, VisUITable))
+#define VISUAL_UI_FRAME(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_FRAME, VisUIFrame))
+#define VISUAL_UI_LABEL(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_LABEL, VisUILabel))
+#define VISUAL_UI_IMAGE(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_IMAGE, VisUIImage))
+#define VISUAL_UI_SEPARATOR(obj)			(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_SEPARATOR, VisUISeparator))
+#define VISUAL_UI_MUTATOR(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_MUTATOR, VisUIMutator))
+#define VISUAL_UI_RANGE(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_RANGE, VisUIRange))
+#define VISUAL_UI_ENTRY(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_ENTRY, VisUIEntry))
+#define VISUAL_UI_SLIDER(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_SLIDER, VisUISlider))
+#define VISUAL_UI_NUMERIC(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_NUMERIC, VisUINumeric))
+#define VISUAL_UI_COLOR(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_COLOR, VisUIColor))
+#define VISUAL_UI_CHOICE_ENTRY(obj)			(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_CHOICE, VisUIChoiceEntry))
+#define VISUAL_UI_CHOICE(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_CHOICE, VisUIChoice))
+#define VISUAL_UI_POPUP(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_POPUP, VisUIPopup))
+#define VISUAL_UI_LIST(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_LIST, VisUIList))
+#define VISUAL_UI_RADIO(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_RADIO, VisUIRadio))
+#define VISUAL_UI_CHECKBOX(obj)				(VISUAL_CHECK_CAST ((obj), VISUAL_WIDGET_TYPE_CHECKBOX, VisUICheckbox))
+
+/**
+ * Enumerate to define the different types of VisUIWidgets.
+ */
+typedef enum {
+	VISUAL_WIDGET_TYPE_NULL,	/**< NULL widget */
+	VISUAL_WIDGET_TYPE_WIDGET,	/**< Base widget: \a VisUIWidget. */
+	VISUAL_WIDGET_TYPE_CONTAINER,	/**< Container widget: \a VisUIContainer. */
+	VISUAL_WIDGET_TYPE_BOX,		/**< Box widget: \a VisUIBox. */
+	VISUAL_WIDGET_TYPE_TABLE,	/**< Table widget: \a VisUITable. */
+	VISUAL_WIDGET_TYPE_FRAME,	/**< Frame widget: \a VisUIFrame. */
+	VISUAL_WIDGET_TYPE_LABEL,	/**< Label widget: \a VisUILabel. */
+	VISUAL_WIDGET_TYPE_IMAGE,	/**< Image widget: \a VisUIImage. */
+	VISUAL_WIDGET_TYPE_SEPARATOR,	/**< Separator widget: \a VisUISeparator. */
+	VISUAL_WIDGET_TYPE_MUTATOR,	/**< Mutator base widget: \a VisUIMutator. */
+	VISUAL_WIDGET_TYPE_RANGE,	/**< Range base widget: \a VisUIRange. */
+	VISUAL_WIDGET_TYPE_ENTRY,	/**< Entry box widget: \a VisUIEntry. */
+	VISUAL_WIDGET_TYPE_SLIDER,	/**< Slider widget: \a VisUISlider. */
+	VISUAL_WIDGET_TYPE_NUMERIC,	/**< Numeric widget: \a VisUINumeric. */
+	VISUAL_WIDGET_TYPE_COLOR,	/**< Color widget: \a VisUIColor. */
+	VISUAL_WIDGET_TYPE_CHOICE,	/**< Choice base widget: \a VisUIChoice. */
+	VISUAL_WIDGET_TYPE_POPUP,	/**< Popup widget: \a VisUIPopup. */
+	VISUAL_WIDGET_TYPE_LIST,	/**< List widget: \a VisUIList. */
+	VISUAL_WIDGET_TYPE_RADIO,	/**< Radio widget: \a VisUIRadio. */
+	VISUAL_WIDGET_TYPE_CHECKBOX	/**< Checkbox widget: \a VisUICheckbox. */
+} VisUIWidgetType;
+
+/**
+ * Enumerate to define the different types of widget orientation. This is used
+ * by a few widgets that can be aligned both vertical and horizontal.
+ */
+typedef enum {
+	VISUAL_ORIENT_TYPE_NONE,	/**< No orientation, use the default. */
+	VISUAL_ORIENT_TYPE_HORIZONTAL,	/**< Horizontal orientation. */
+	VISUAL_ORIENT_TYPE_VERTICAL	/**< Vertical orientation. */
+} VisUIOrientType;
+
+typedef struct _VisUIWidget VisUIWidget;
+typedef struct _VisUIContainer VisUIContainer;
+typedef struct _VisUIBox VisUIBox;
+typedef struct _VisUITableEntry VisUITableEntry;
+typedef struct _VisUITable VisUITable;
+typedef struct _VisUIFrame VisUIFrame;
+typedef struct _VisUILabel VisUILabel;
+typedef struct _VisUIImage VisUIImage;
+typedef struct _VisUISeparator VisUISeparator;
+typedef struct _VisUIMutator VisUIMutator;
+typedef struct _VisUIRange VisUIRange;
+typedef struct _VisUIEntry VisUIEntry;
+typedef struct _VisUISlider VisUISlider;
+typedef struct _VisUINumeric VisUINumeric;
+typedef struct _VisUIColor VisUIColor;
+typedef struct _VisUIChoiceList VisUIChoiceList;
+typedef struct _VisUIChoiceEntry VisUIChoiceEntry;
+typedef struct _VisUIChoice VisUIChoice;
+typedef struct _VisUIPopup VisUIPopup;
+typedef struct _VisUIList VisUIList;
+typedef struct _VisUIRadio VisUIRadio;
+typedef struct _VisUICheckbox VisUICheckbox;
+
+/* FIXME, fix the links, they are screwed up because of the typedefs, there is some way around it
+ * but hey. */
+/**
+ * 
+ * The super class for al VisUIWidgets. All the typical VisUIWidgets
+ * derive from this. VisUIWidget is used as an intermediate user interface
+ * description. Mainly to set up configuration dialogs for plugins that
+ * are not widget set dependant.
+ *
+ * The VisUIWidget class hierarchy looks like following:
+ * - \a _VisUIWidget
+ *	- \a VisUILabel
+ *	- \a VisUIImage
+ *	- \a VisUIContainer
+ *		- \a VisUIBox
+ *		- \a VisUITable
+ *		- \a VisUIFrame
+ *	- \a VisUIMutator
+ *		- \a VisUIText
+ *		- \a VisUIColor
+ *		- \a VisUIRange
+ *			- \a VisUISlider
+ *			- \a VisUINumeric
+ *		- \a VisUIChoice
+ *			- \a VisUIPopup
+ *			- \a VisUIList
+ *			- \a VisUIRadio
+ *			- \a VisUICheckbox
+ */
+struct _VisUIWidget {
+	VisObject		 object;	/**< The VisObject data. */
+
+	VisUIWidget		*parent;	/**< Parent in which this VisUIWidget is packed.
+						 * This is possibly NULL. */
+	
+	VisUIWidgetType		 type;		/**< Type of VisUIWidget. */
+
+	const char		*tooltip;	/**< Optional tooltip text, this can be used to
+						 * give the user some extra explanation about the
+						 * user interface. */
+
+	int			 width;		/**< When size requisition is used, the width value will
+						 * be stored in this. */
+	int			 height;	/**< When size requisition is used. the height value will
+						 * be stored in this. When size requisition is not being
+						 * done both width and height will contain of -1. */
+};
+
+/**
+ * The VisUIContainer is a VisUIWidget that is used to pack other widgets in.
+ * A basic container can contain just one VisUIWidget, however when VisUIBox or
+ * VisUITable is used, it's possible to add more elements.
+ */
+struct _VisUIContainer {
+	VisUIWidget		 widget;	/**< The VisUIWidget data. */
+
+	VisUIWidget		*child;		/**< Pointer to the child VisUIWidget that is packed in this VisUIContainer. */
+};
+
+/**
+ * The VisUIBox inherents from VisUIContainer, but is capable to contain more childeren.
+ * The VisUIBox is used as a box of VisUIWidgets, packed vertical or horizontal.
+ */
+struct _VisUIBox {
+	VisUIContainer		 container;	/**< The VisUIContainer data. */
+
+	VisUIOrientType		 orient;	/**< Orientation, whatever the box packs the item in a vertical
+						 * order or in a horizontal order. */
+
+	VisList			 childs;	/**< A list of all child VisUIWidgets. */
+};
+
+/**
+ * VisUITableEntry is an entry in a VisUITable. the VisUITableEntry is not a VisUIWidget on
+ * itself. Instead it rembers the cell in which a VisUIWidget is placed in VisUITable and
+ * also has a reference to the VisUIWidget.
+ */
+struct _VisUITableEntry {
+	VisObject		object;		/**< The VisObject data. */
+
+	int			row;		/**< Row to which the VisUITableEntry is associated. */
+	int			col;		/**< Column to which the VisUITableEntry is associated. */
+
+	VisUIWidget		*widget;	/**< The VisUIWidget that is connected to this entry in the VisUITable. */
+};
+
+/**
+ * The VisUITable inherents from VisUIContainer, but is capable of placing VisUIWidgets in an aligned grid.
+ */
+struct _VisUITable {
+	VisUIContainer		 container;	/**< The VisUIContainer data. */
+
+	int			 rows;		/**< The number of rows in this VisUITable. */
+	int			 cols;		/**< The number of columns in this VisUITable. */
+
+	VisList			 childs;	/**< A list of all VisUITableEntry items that are related to
+						 * this table. */
+};
+
+/**
+ * The VisUIFrame inherents from VisUIContainer, it's used to put a frame with a label around a VisUIWidget.
+ */
+struct _VisUIFrame {
+	VisUIContainer		 container;	/**< The VisUIContainer data. */
+
+	const char		*name;		/**< The frame label text. */
+};
+
+/**
+ * The VisUILabel inherents from a VisUIWidget, it's used to as a label item in the user interface.
+ */
+struct _VisUILabel {
+	VisUIWidget		 widget;	/**< The VisUIWidget data. */
+
+	const char		*text;		/**< The label text. */
+	int			 bold;		/**< Whatever the label is being printed in bold or not. */
+};
+
+/**
+ * The VisUIImage inherents from a VisUIWidget, it's used to display a VisVideo within the user interface. For
+ * example it can be used to show a picture.
+ */
+struct _VisUIImage {
+	VisUIWidget		 widget;	/**< The VisUIWidget data. */
+
+	VisVideo		*image;		/**< The VisUIImage containing the image data. */
+};
+
+/**
+ * The VisUISeparator inherents from a VisUIWidget, it's used to display a separator between different user interface
+ * elements.
+ */
+struct _VisUISeparator {
+	VisUIWidget		 widget;	/**< The VisUIWidget data. */
+
+	VisUIOrientType		 orient;	/**< The orientation, whatever the separator is drawn in vertical
+						 * or horizontal style. */
+};
+
+/**
+ * The VisUIMutator inherents from a VisUIWidget, it's used as a super class for different type of mutator VisUIWidgets.
+ * Mutator VisUIWidgets are used to change a value in a VisParamEntry.
+ */
+struct _VisUIMutator {
+	VisUIWidget		 widget;	/**< The VisUIWidget data. */
+
+	VisParamEntry		*param;		/**< The VisParamEntry parameter that is associated with this
+						 * VisUIMutator. */
+};
+
+/**
+ * The VisUIRange inherents from a VisUIMutator, it's a type of mutator widget that focus on numeric input and
+ * numeric adjustment within a range.
+ */
+struct _VisUIRange {
+	VisUIMutator		 mutator;	/**< The VisUIMutator data. */
+
+	double			 min;		/**< The minimal value. */
+	double			 max;		/**< The maximal value. */
+	double			 step;		/**< Increase / decrease steps. */
+
+	int			 precision;	/**< Precision, in the fashion of how many numbers behind
+						 * the point. */
+};
+
+/**
+ * The VisUIEntry inherents from a VisUIMutator, it's used as a way to input text.
+ */
+struct _VisUIEntry {
+	VisUIMutator		 mutator;	/**< The VisUIMutator data. */
+
+	int			 length;	/**< Maximal length for the text. */
+};
+
+/**
+ * The VisUISlider inherents from a VisUIRange, it's used to display a slider which can be used
+ * to adjust a numeric value.
+ */
+struct _VisUISlider {
+	VisUIRange		 range;		/**< The VisUIRange data. */
+
+	int			 showvalue;	/**< Don't show just the slider, but also the  value it
+						 * represents at it's current position. */
+};
+
+/**
+ * The VisUINumeric inherents from a VisUIRange, it's used to display a numeric spin button that
+ * can be used to adjust a numeric value. A numeric spin button contains out of a small text field
+ * displaying the actual value, followed by two buttons which are used to increase or decrease the value.
+ *
+ * In most VisUI native implementations it's also possible to adjust the text field directly using
+ * the keyboard.
+ */
+struct _VisUINumeric {
+	VisUIRange		 range;		/**< The VisUIRange data. */
+};
+
+/**
+ * The VisUIColor inherents from a VisUIMutator, it's used to adjust the color that is encapsulated by
+ * a VisParamEntry.
+ */
+struct _VisUIColor {
+	VisUIMutator		 mutator;	/**< The VisUIMutator data. */
+};
+
+/**
+ * The VisUIChoiceList is not a VisUIWidget, but it's used by the different types of VisUIChoice widgets to
+ * store information about choices.
+ */
+struct _VisUIChoiceList {
+	VisObject		 object;	/**< The VisObject data. */
+
+	int			 count;		/**< The amount of choices that are present. */
+	VisList			 choices;	/**< A list of VisUIChoiceEntry elements. */ 
+};
+
+/**
+ * The VisUIChoiceEntry is not a VisUIWidget, but it's used by the different types of VisUIChoice widgets to
+ * store information regarding a choice within a VisUIChoiceList.
+ */
+struct _VisUIChoiceEntry {
+	VisObject		 object;	/**< The VisObject data. */
+
+	const char		*name;		/**< Name of this VisChoiceEntry. */
+	
+	VisParamEntry		*value;		/**< Link to the VisParamEntry that contains the value
+						 * for this VisChoiceEntry. */
+};
+
+/**
+ * The VisUIChoice inherents from a VisUIMutator, it's used as a super class for the different types of
+ * VisUIChoice VisUIWidgets.
+ */
+struct _VisUIChoice {
+	VisUIMutator		 mutator;	/**< The VisUIMutator data. */
+
+	VisParamEntry		*param;		/**< Pointer to the VisParamEntry that is the target to
+						 * contain the actual value. */
+
+	VisUIChoiceList		 choices;	/**< The different choices present. */
+};
+
+/**
+ * The VisUIPopup inherents from a VisUIChoice, it's used to represent choices in a popup fashion, where you
+ * can select an item.
+ */
+struct _VisUIPopup {
+	VisUIChoice		 choice;	/**< The VisUIChoice data. */
+};
+
+/**
+ * The VisUIList inherents from a VisUIChoice, it's used to represent choices in a list fashion.
+ */
+struct _VisUIList {
+	VisUIChoice		 choice;	/**< The VisUIChoice data. */
+};
+
+/**
+ * The VisUIRadio inherents from a VisUIChoice, it's used to represent choices in the fashion of radio buttons. These
+ * are a grouped type of checkboxes where only one item can be active at once.
+ */
+struct _VisUIRadio {
+	VisUIChoice		 choice;	/**< The VisUIChoice data. */
+
+	VisUIOrientType		 orient;	/**< Orientation of how the different radio buttons in the VisUIRadio button
+						 * group is ordered. */
+};
+
+/**
+ * The VisUICheckbox inherents from a VisUIChoice, it's used to represent one single checkbox widget. For this reason it
+ * can only represent two choices. One for the toggled state and one for the untoggled state.
+ */
+struct _VisUICheckbox {
+	VisUIChoice		 choice;	/**< The VisUIChoice data. */
+
+	const char		*name;		/**< Optional text behind the textbox. */
+};
+
+/* prototypes */
+VisUIWidget *visual_ui_widget_new (void);
+int visual_ui_widget_set_size_request (VisUIWidget *widget, int width, int height);
+int visual_ui_widget_set_tooltip (VisUIWidget *widget, const char *tooltip);
+const char *visual_ui_widget_get_tooltip (VisUIWidget *widget);
+VisUIWidget *visual_ui_widget_get_top (VisUIWidget *widget);
+VisUIWidget *visual_ui_widget_get_parent (VisUIWidget *widget);
+VisUIWidgetType visual_ui_widget_get_type (VisUIWidget *widget);
+
+int visual_ui_container_add (VisUIContainer *container, VisUIWidget *widget);
+VisUIWidget *visual_ui_container_get_child (VisUIContainer *container);
+
+VisUIWidget *visual_ui_box_new (VisUIOrientType orient);
+int visual_ui_box_pack (VisUIBox *box, VisUIWidget *widget);
+VisList *visual_ui_box_get_childs (VisUIBox *box);
+VisUIOrientType visual_ui_box_get_orient (VisUIBox *box);
+
+VisUIWidget *visual_ui_table_new (int rows, int cols);
+VisUITableEntry *visual_ui_table_entry_new (VisUIWidget *widget, int row, int col);
+int visual_ui_table_attach (VisUITable *table, VisUIWidget *widget, int row, int col);
+VisList *visual_ui_table_get_childs (VisUITable *table);
+
+VisUIWidget *visual_ui_frame_new (const char *name);
+
+VisUIWidget *visual_ui_label_new (const char *text, int bold);
+int visual_ui_label_set_text (VisUILabel *label, const char *text);
+int visual_ui_label_set_bold (VisUILabel *label, int bold);
+const char *visual_ui_label_get_text (VisUILabel *label);
+
+VisUIWidget *visual_ui_image_new (VisVideo *video);
+int visual_ui_image_set_video (VisUIImage *image, VisVideo *video);
+VisVideo *visual_ui_image_get_video (VisUIImage *image);
+
+VisUIWidget *visual_ui_separator_new (VisUIOrientType orient);
+VisUIOrientType visual_ui_separator_get_orient (VisUISeparator *separator);
+
+int visual_ui_mutator_set_param (VisUIMutator *mutator, VisParamEntry *param);
+VisParamEntry *visual_ui_mutator_get_param (VisUIMutator *mutator);
+
+int visual_ui_range_set_properties (VisUIRange *range, double min, double max, double step, int precision);
+int visual_ui_range_set_max (VisUIRange *range, double max);
+int visual_ui_range_set_min (VisUIRange *range, double min);
+int visual_ui_range_set_step (VisUIRange *range, double step);
+int visual_ui_range_set_precision (VisUIRange *range, int precision);
+
+VisUIWidget *visual_ui_entry_new (void);
+int visual_ui_entry_set_length (VisUIEntry *entry, int length);
+
+VisUIWidget *visual_ui_slider_new (int showvalue);
+
+VisUIWidget *visual_ui_numeric_new (void);
+
+VisUIWidget *visual_ui_color_new (void);
+
+VisUIChoiceEntry *visual_ui_choice_entry_new (const char *name, VisParamEntry *value);
+int visual_ui_choice_add (VisUIChoice *choice, const char *name, VisParamEntry *value);
+int visual_ui_choice_add_many (VisUIChoice *choice, VisParamEntry *paramchoices);
+int visual_ui_choice_free_choices (VisUIChoice *choice);
+int visual_ui_choice_set_active (VisUIChoice *choice, int index);
+int visual_ui_choice_get_active (VisUIChoice *choice);
+VisUIChoiceEntry *visual_ui_choice_get_choice (VisUIChoice *choice, int index);
+VisUIChoiceList *visual_ui_choice_get_choices (VisUIChoice *choice);
+
+/* FIXME look at lists with multiple selections... */
+
+VisUIWidget *visual_ui_popup_new (void);
+
+VisUIWidget *visual_ui_list_new (void);
+
+VisUIWidget *visual_ui_radio_new (VisUIOrientType orient);
+
+VisUIWidget *visual_ui_checkbox_new (const char *name, int boolcheck);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_UI_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_video.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,1934 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ * 	    Duilio J. Protti <dprotti@users.sourceforge.net>
+ *	    Chong Kai Xiong <descender@phreaker.net>
+ *	    Jean-Christophe Hoelt <jeko@ios-software.com>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <lvconfig.h>
+#include "lv_common.h"
+#include "lv_video.h"
+#include "lv_cpu.h"
+#include "lv_log.h"
+#include "lv_mem.h"
+
+#define HAVE_ALLOCATED_BUFFER(video)	((video)->flags & VISUAL_VIDEO_FLAG_ALLOCATED_BUFFER)
+#define HAVE_EXTERNAL_BUFFER(video)	((video)->flags & VISUAL_VIDEO_FLAG_EXTERNAL_BUFFER)
+
+
+typedef struct {
+	uint16_t b:5, g:6, r:5;
+} _color16;
+
+typedef struct {
+	uint8_t r;
+	uint8_t g;
+	uint8_t b;
+} _color24;
+
+/* The VisVideo dtor function */
+static int video_dtor (VisObject *object);
+
+/* Precomputation functions */
+static void precompute_row_table (VisVideo *video);
+
+/* Blit overlay functions */
+static int blit_overlay_noalpha (VisVideo *dest, const VisVideo *src, int x, int y);
+static int blit_overlay_alpha32 (VisVideo *dest, const VisVideo *src, int x, int y);
+	
+/* Depth conversions */
+static int depth_transform_8_to_16_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+static int depth_transform_8_to_24_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+static int depth_transform_8_to_32_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+
+static int depth_transform_16_to_8_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+static int depth_transform_16_to_24_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+static int depth_transform_16_to_32_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+
+static int depth_transform_24_to_8_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+static int depth_transform_24_to_16_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+static int depth_transform_24_to_32_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+
+static int depth_transform_32_to_8_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+static int depth_transform_32_to_16_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+static int depth_transform_32_to_24_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal);
+
+/* BGR to RGB conversions */
+static int bgr_to_rgb16 (VisVideo *dest, const VisVideo *src);
+static int bgr_to_rgb24 (VisVideo *dest, const VisVideo *src);
+static int bgr_to_rgb32 (VisVideo *dest, const VisVideo *src);
+
+/* Scaling functions */
+static int scale_nearest_8 (VisVideo *dest, const VisVideo *src);
+static int scale_nearest_16 (VisVideo *dest, const VisVideo *src);
+static int scale_nearest_24 (VisVideo *dest, const VisVideo *src);
+static int scale_nearest_32 (VisVideo *dest, const VisVideo *src);
+
+/* Bilinear filter functions */
+static int scale_bilinear_8 (VisVideo *dest, const VisVideo *src);
+static int scale_bilinear_16 (VisVideo *dest, const VisVideo *src);
+static int scale_bilinear_24 (VisVideo *dest, const VisVideo *src);
+static int scale_bilinear_32 (VisVideo *dest, const VisVideo *src);
+
+static int video_dtor (VisObject *object)
+{
+	VisVideo *video = VISUAL_VIDEO (object);
+
+	if (HAVE_ALLOCATED_BUFFER (video)) {
+		if (video->pixels != NULL)
+			visual_video_free_buffer (video);
+
+		video->pixels = NULL;
+	}
+
+	video->pixel_rows = NULL;
+
+	return VISUAL_OK;
+}
+
+
+/**
+ * @defgroup VisVideo VisVideo
+ * @{
+ */
+
+/**
+ * Creates a new VisVideo structure, without an associated screen buffer.
+ *
+ * @return A newly allocated VisVideo.
+ */
+VisVideo *visual_video_new ()
+{
+	VisVideo *video;
+
+	video = visual_mem_new0 (VisVideo, 1);
+
+	/* Do the VisObject initialization */
+	visual_object_initialize (VISUAL_OBJECT (video), TRUE, video_dtor);
+
+	video->pixels = NULL;
+
+	/*
+	 * By default, we suppose an external buffer will be used.
+	 */
+	video->flags = VISUAL_VIDEO_FLAG_EXTERNAL_BUFFER;
+
+	return video;
+}
+
+/**
+ * Creates a new VisVideo and also allocates a buffer.
+ *
+ * @param width The width for the new buffer.
+ * @param height The height for the new buffer.
+ * @param depth The depth being used.
+ *
+ * @return A newly allocates VisVideo with a buffer allocated.
+ */
+VisVideo *visual_video_new_with_buffer (int width, int height, VisVideoDepth depth)
+{
+	VisVideo *video;
+	int ret;
+	
+	video = visual_video_new ();
+
+	visual_video_set_depth (video, depth);
+	visual_video_set_dimension (video, width, height);
+
+	video->pixels = NULL;
+	ret = visual_video_allocate_buffer (video);
+
+	if (ret < 0) {
+		/*
+		 * Restore the flag set by visual_video_new().
+		 */
+		video->flags = VISUAL_VIDEO_FLAG_EXTERNAL_BUFFER;
+		visual_object_unref (VISUAL_OBJECT (video));
+		
+		return NULL;
+	}
+
+	return video;
+}
+
+/**
+ * Frees the buffer that relates to the VisVideo.
+ *
+ * @param video Pointer to a VisVideo of which the buffer needs to be freed.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL, -VISUAL_ERROR_VIDEO_PIXELS_NULL or -VISUAL_ERROR_VIDEO_NO_ALLOCATED
+ *	on failure.
+ */
+int visual_video_free_buffer (VisVideo *video)
+{
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+	visual_log_return_val_if_fail (video->pixels != NULL, -VISUAL_ERROR_VIDEO_PIXELS_NULL);
+
+	if (HAVE_ALLOCATED_BUFFER (video)) {
+		if (video->pixel_rows != NULL)
+			visual_mem_free (video->pixel_rows);
+
+		visual_mem_free (video->pixels);
+
+	} else {
+		return -VISUAL_ERROR_VIDEO_NO_ALLOCATED;
+	}
+
+	video->pixel_rows = NULL;
+	video->pixels = NULL;
+
+	video->flags = VISUAL_VIDEO_FLAG_NONE;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Allocates a buffer for the VisVideo. Allocates based on the
+ * VisVideo it's information about the screen dimension and depth.
+ *
+ * @param video Pointer to a VisVideo that needs an allocated buffer.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL or -VISUAL_ERROR_VIDEO_HAS_PIXELS  on failure.
+ */
+int visual_video_allocate_buffer (VisVideo *video)
+{
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	if (video->pixels != NULL) {
+		if (HAVE_ALLOCATED_BUFFER (video)) {
+			visual_video_free_buffer (video);
+		} else {
+			visual_log (VISUAL_LOG_CRITICAL, "Trying to allocate an screen buffer on "
+					"a VisVideo structure which points to an external screen buffer");
+
+			return -VISUAL_ERROR_VIDEO_HAS_PIXELS;
+		}
+	}
+
+	if (video->size == 0) {
+		video->pixels = NULL;
+		video->flags = VISUAL_VIDEO_FLAG_NONE;
+
+		return VISUAL_OK;
+	}
+	
+	video->pixels = visual_mem_malloc0 (video->size);
+
+	video->pixel_rows = visual_mem_new0 (void *, video->height);
+	precompute_row_table (video);
+
+	video->flags = VISUAL_VIDEO_FLAG_ALLOCATED_BUFFER;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Checks if the given VisVideo has a private allocated buffer.
+ *
+ * @param video Pointer to the VisVideo of which we want to know if it has a private allocated buffer.
+ *
+ * @return TRUE if the VisVideo has an allocated buffer, or FALSE if not.
+ */
+int visual_video_have_allocated_buffer (const VisVideo *video)
+{
+	visual_log_return_val_if_fail (video != NULL, FALSE);
+
+	if (HAVE_ALLOCATED_BUFFER (video))
+		return TRUE;
+
+	return FALSE;
+}
+
+static void precompute_row_table (VisVideo *video)
+{
+	void **table, *row;
+	int y;
+
+	visual_log_return_if_fail (video->pixel_rows != NULL);
+	
+	table = video->pixel_rows;
+	
+	for (y = 0, row = video->pixels; y < video->height; y++, row += video->pitch)
+		*table++ = row;
+}
+
+/**
+ * Clones the information from a VisVideo to another.
+ * This will clone the depth, dimension and screen pitch into another VisVideo.
+ * It doesn't clone the palette or buffer.
+ *
+ * @param dest Pointer to a destination VisVideo in which the information needs to
+ *	be placed.
+ * @param src Pointer to a source VisVideo from which the information needs to
+ *	be obtained.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL on failure.
+ */
+int visual_video_clone (VisVideo *dest, const VisVideo *src)
+{
+	visual_log_return_val_if_fail (dest != NULL, -VISUAL_ERROR_VIDEO_NULL);
+	visual_log_return_val_if_fail (src != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	visual_video_set_depth (dest, src->depth);
+	visual_video_set_dimension (dest, src->width, src->height);
+	visual_video_set_pitch (dest, src->pitch);
+
+	dest->flags = src->flags;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Checks if two VisVideo objects are the same depth, pitch and dimension wise.
+ *
+ * @param src1 Pointer to the first VisVideo that is used in the compare.
+ * @param src2 Pointer to the second VisVideo that is used in the compare.
+ *
+ * @return FALSE on different, TRUE on same, -VISUAL_ERROR_VIDEO_NULL on failure.
+ */
+int visual_video_compare (const VisVideo *src1, const VisVideo *src2)
+{
+	visual_log_return_val_if_fail (src1 != NULL, -VISUAL_ERROR_VIDEO_NULL);
+	visual_log_return_val_if_fail (src2 != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	if (src1->depth != src2->depth)
+		return FALSE;
+
+	if (src1->width != src2->width)
+		return FALSE;
+
+	if (src1->height != src2->height)
+		return FALSE;
+
+	if (src1->pitch != src2->pitch)
+		return FALSE;
+
+	/* We made it to the end, the VisVideos are likewise in depth, pitch, dimensions */
+	return TRUE;
+}
+
+
+/**
+ * Sets a palette to a VisVideo. Links a VisPalette to the
+ * VisVideo.
+ *
+ * @param video Pointer to a VisVideo to which a VisPalette needs to be linked.
+ * @param pal Pointer to a Vispalette that needs to be linked with the VisVideo.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL on failure.
+ */
+int visual_video_set_palette (VisVideo *video, VisPalette *pal)
+{
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	video->pal = pal;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets a buffer to a VisVideo. Links a sreenbuffer to the
+ * VisVideo.
+ *
+ * @warning The given @a video must be one previously created with visual_video_new(),
+ * and not with visual_video_new_with_buffer().
+ *
+ * @param video Pointer to a VisVideo to which a buffer needs to be linked.
+ * @param buffer Pointer to a buffer that needs to be linked with the VisVideo.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL or -VISUAL_ERROR_VIDEO_HAS_ALLOCATED on failure.
+ */
+int visual_video_set_buffer (VisVideo *video, void *buffer)
+{
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	if (HAVE_ALLOCATED_BUFFER (video)) {
+		visual_log (VISUAL_LOG_CRITICAL, "Trying to set a screen buffer on "
+				"a VisVideo structure which points to an allocated screen buffer");
+
+		return -VISUAL_ERROR_VIDEO_HAS_ALLOCATED;
+	}
+
+	video->pixels = buffer;
+
+	if (video->pixel_rows != NULL)
+		visual_mem_free (video->pixel_rows);
+
+	video->pixel_rows = visual_mem_new0 (void *, video->height);
+	precompute_row_table (video);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the dimension for a VisVideo. Used to set the dimension for a
+ * surface.
+ *
+ * @param video Pointer to a VisVideo to which the dimension is set.
+ * @param width The width of the surface.
+ * @param height The height of the surface.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL on failure.
+ */
+int visual_video_set_dimension (VisVideo *video, int width, int height)
+{
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	video->width = width;
+	video->height = height;
+
+	video->pitch = video->width * video->bpp;
+	video->size = video->pitch * video->height;
+	
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the pitch for a VisVideo. Used to set the screen
+ * pitch for a surface. If the pitch doesn't differ from the
+ * screen width * bpp you only need to call the
+ * visual_video_set_dimension method.
+ *
+ * @param video Pointer to a VisVideo to which the pitch is set.
+ * @param pitch The screen pitch in bytes per line.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL or -VISUAL_ERROR_VIDEO_INVALID_BPP on failure.
+ */
+int visual_video_set_pitch (VisVideo *video, int pitch)
+{
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	if (video->bpp <= 0)
+		return -VISUAL_ERROR_VIDEO_INVALID_BPP;
+
+	video->pitch = pitch;
+	video->size = video->pitch * video->height;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets the depth for a VisVideo. Used to set the depth for
+ * a surface. This will also define the number of bytes per pixel.
+ *
+ * @param video Pointer to a VisVideo to which the depth is set.
+ * @param depth The depth choosen from the VisVideoDepth enumerate.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL on failure.
+ */
+int visual_video_set_depth (VisVideo *video, VisVideoDepth depth)
+{
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+
+	video->depth = depth;
+	video->bpp = visual_video_bpp_from_depth (video->depth);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Checks if a certain depth is supported by checking against an ORred depthflag.
+ *
+ * @param depthflag The ORred depthflag that we check against.
+ * @param depth The depth that we want to test.
+ *
+ * @return TRUE when supported, FALSE when unsupported and -VISUAL_ERROR_VIDEO_INVALID_DEPTH on failure.
+ */
+int visual_video_depth_is_supported (int depthflag, VisVideoDepth depth)
+{
+	if (visual_video_depth_is_sane (depth) == 0)
+		return -VISUAL_ERROR_VIDEO_INVALID_DEPTH;
+
+	if ((depth & depthflag) > 0)
+		return TRUE;
+
+	return FALSE;
+}
+
+/**
+ * Get the next depth from the ORred depthflag. By giving a depth and a depthflag
+ * this returns the next supported depth checked from the depthflag.
+ *
+ * @see visual_video_depth_get_prev
+ * 
+ * @param depthflag The ORred depthflag that we check against.
+ * @param depth The depth of which we want the next supported depth.
+ *
+ * @return The next supported depth or VISUAL_VIDEO_DEPTH_ERROR on failure.
+ */
+VisVideoDepth visual_video_depth_get_next (int depthflag, VisVideoDepth depth)
+{
+	int i = depth;
+	
+	if (visual_video_depth_is_sane (depth) == 0)
+		return VISUAL_VIDEO_DEPTH_ERROR;
+
+	if (i == VISUAL_VIDEO_DEPTH_NONE) {
+		i = VISUAL_VIDEO_DEPTH_8BIT;
+
+		if ((i & depthflag) > 0)
+			return i;
+	}
+
+	while (i < VISUAL_VIDEO_DEPTH_GL) {
+		i *= 2;
+
+		if ((i & depthflag) > 0)
+			return i;
+	}
+
+	return depth;
+}
+
+/**
+ * Get the previous depth from the ORred depthflag. By giving a depth and a depthflag
+ * this returns the previous supported depth checked from the depthflag.
+ *
+ * @see visual_video_depth_get_next
+ * 
+ * @param depthflag The ORred depthflag that we check against.
+ * @param depth The depth of which we want the previous supported depth.
+ *
+ * @return The previous supported depth or VISUAL_VIDEO_DEPTH_ERROR on failure.
+ */
+VisVideoDepth visual_video_depth_get_prev (int depthflag, VisVideoDepth depth)
+{
+	int i = depth;
+
+	if (visual_video_depth_is_sane (depth) == 0)
+		return VISUAL_VIDEO_DEPTH_ERROR;
+
+	if (i == VISUAL_VIDEO_DEPTH_NONE)
+		return VISUAL_VIDEO_DEPTH_NONE;
+
+	while (i > VISUAL_VIDEO_DEPTH_NONE) {
+		i >>= 1;
+
+		if ((i & depthflag) > 0)
+			return i;
+	}
+
+	return depth;
+}
+
+/**
+ * Return the lowest supported graphical depth from the ORred depthflag.
+ *
+ * @param depthflag The ORred depthflag that we check against.
+ * 
+ * @return The lowest supported depth or VISUAL_VIDEO_DEPTH_ERROR on failure.
+ */
+VisVideoDepth visual_video_depth_get_lowest (int depthflag)
+{
+	return visual_video_depth_get_next (depthflag, VISUAL_VIDEO_DEPTH_NONE);
+}
+
+/**
+ * Return the highest supported graphical depth from the ORred depthflag.
+ *
+ * @param depthflag The ORred depthflag that we check against.
+ *
+ * @return The highest supported depth or VISUAL_VIDEO_DEPTH_ERROR on failure.
+ */
+VisVideoDepth visual_video_depth_get_highest (int depthflag)
+{
+	VisVideoDepth highest = VISUAL_VIDEO_DEPTH_NONE;
+	VisVideoDepth i = 0;
+	int firstentry = TRUE;
+
+	while (highest != i || firstentry == TRUE) {
+		highest = i;
+
+		i = visual_video_depth_get_next (depthflag, i);
+
+		firstentry = FALSE;
+	}
+
+	return highest;
+}
+
+/**
+ * Return the highest supported depth that is NOT openGL.
+ *
+ * @param depthflag The ORred depthflag that we check against.
+ *
+ * @return The highest supported depth that is not openGL or
+ *	VISUAL_VIDEO_DEPTH_ERROR on failure.
+ */
+VisVideoDepth visual_video_depth_get_highest_nogl (int depthflag)
+{
+	VisVideoDepth depth;
+
+	depth = visual_video_depth_get_highest (depthflag);
+
+	/* Get previous depth if the highest is openGL */
+	if (depth == VISUAL_VIDEO_DEPTH_GL) {
+		depth = visual_video_depth_get_prev (depthflag, depth);
+
+		/* Is it still on openGL ? Return an error */
+		if (depth == VISUAL_VIDEO_DEPTH_GL)
+			return VISUAL_VIDEO_DEPTH_ERROR;
+
+	} else {
+		return depth;
+	}
+
+	return -VISUAL_ERROR_IMPOSSIBLE;
+}
+
+/**
+ * Checks if a certain value is a sane depth.
+ *
+ * @param depth Depth to be checked if it's sane.
+ *
+ * @return TRUE if the depth is sane, FALSE if the depth is not sane.
+ */
+int visual_video_depth_is_sane (VisVideoDepth depth)
+{
+	int count = 0;
+	int i = 1;
+
+	if (depth == VISUAL_VIDEO_DEPTH_NONE)
+		return TRUE;
+
+	if (depth >= VISUAL_VIDEO_DEPTH_ENDLIST)
+		return FALSE;
+	
+	while (i < VISUAL_VIDEO_DEPTH_ENDLIST) {
+		if ((i & depth) > 0)
+			count++;
+
+		if (count > 1)
+			return FALSE;
+
+		i <<= 1;
+	}
+
+	return TRUE;
+}
+
+/**
+ * Returns the number of bits per pixel from a VisVideoDepth enumerate value.
+ *
+ * @param depth The VisVideodepth enumerate value from which the bits per pixel
+ *	needs to be returned.
+ *
+ * @return The bits per pixel or -VISUAL_ERROR_VIDEO_INVALID_DEPTH on failure.
+ */
+int visual_video_depth_value_from_enum (VisVideoDepth depth)
+{
+	switch (depth) {
+		case VISUAL_VIDEO_DEPTH_8BIT:
+			return 8;
+
+		case VISUAL_VIDEO_DEPTH_16BIT:
+			return 16;
+
+		case VISUAL_VIDEO_DEPTH_24BIT:
+			return 24;
+
+		case VISUAL_VIDEO_DEPTH_32BIT:
+			return 32;
+
+		default:
+			return -VISUAL_ERROR_VIDEO_INVALID_DEPTH;
+	}
+
+	return -VISUAL_ERROR_VIDEO_INVALID_DEPTH;
+}
+
+/**
+ * Returns a VisVideoDepth enumerate value from bits per pixel.
+ *
+ * @param depthvalue Integer containing the number of bits per pixel.
+ *
+ * @return The corespondending enumerate value or VISUAL_VIDEO_DEPTH_ERROR on failure.
+ */
+VisVideoDepth visual_video_depth_enum_from_value (int depthvalue)
+{
+	switch (depthvalue) {
+		case 8:
+			return VISUAL_VIDEO_DEPTH_8BIT;
+
+		case 16:
+			return VISUAL_VIDEO_DEPTH_16BIT;
+
+		case 24:
+			return VISUAL_VIDEO_DEPTH_24BIT;
+
+		case 32:
+			return VISUAL_VIDEO_DEPTH_32BIT;
+
+		default:
+			return VISUAL_VIDEO_DEPTH_ERROR;
+
+	}
+
+	return -VISUAL_ERROR_IMPOSSIBLE;
+}
+
+/**
+ * Returns the number of bytes per pixel from the VisVideoDepth enumerate.
+ *
+ * @param depth The VisVideodepth enumerate value from which the bytes per pixel
+ *	needs to be returned.
+ *
+ * @return The number of bytes per pixel, -VISUAL_ERROR_VIDEO_INVALID_DEPTH on failure.
+ */
+int visual_video_bpp_from_depth (VisVideoDepth depth)
+{
+	switch (depth) {
+		case VISUAL_VIDEO_DEPTH_8BIT:
+			return 1;
+		
+		case VISUAL_VIDEO_DEPTH_16BIT:
+			return 2;
+
+		case VISUAL_VIDEO_DEPTH_24BIT:
+			return 3;
+
+		case VISUAL_VIDEO_DEPTH_32BIT:
+			return 4;
+
+		case VISUAL_VIDEO_DEPTH_GL:
+			return 0;
+
+		default:
+			return -VISUAL_ERROR_VIDEO_INVALID_DEPTH;
+	}
+
+	return -VISUAL_ERROR_IMPOSSIBLE;
+}
+
+/**
+ * This function blits a VisVideo into another VisVideo. Placement can be done and there
+ * is support for the alpha channel.
+ *
+ * @param dest Pointer to the destination VisVideo in which the source is overlayed.
+ * @param src Pointer to the source VisVideo which is overlayed in the destination.
+ * @param x Horizontal placement offset.
+ * @param y Vertical placement offset.
+ * @param alpha Sets if we want to check the alpha channel. Use FALSE or TRUE here.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_INVALID_DEPTH or -VISUAL_ERROR_VIDEO_OUT_OF_BOUNDS on failure.
+ */
+int visual_video_blit_overlay (VisVideo *dest, const VisVideo *src, int x, int y, int alpha)
+{
+	VisVideo *transform = NULL;
+	VisCPU *cpucaps;
+	const VisVideo *srcp = NULL;
+
+	/* We can't overlay GL surfaces so don't even try */
+	visual_log_return_val_if_fail (dest->depth != VISUAL_VIDEO_DEPTH_GL ||
+			src->depth != VISUAL_VIDEO_DEPTH_GL, -VISUAL_ERROR_VIDEO_INVALID_DEPTH);
+	
+	cpucaps = visual_cpu_get_caps ();
+	
+	/* Placement is outside dest buffer, no use to continue */
+	if (x > dest->width)
+		return -VISUAL_ERROR_VIDEO_OUT_OF_BOUNDS;
+
+	if (y > dest->height)
+		return -VISUAL_ERROR_VIDEO_OUT_OF_BOUNDS;
+
+	/* We're not the same depth, converting */
+	if (dest->depth != src->depth) {
+		transform = visual_video_new ();
+
+		visual_video_set_depth (transform, dest->depth);
+		visual_video_set_dimension (transform, src->width, src->height);
+
+		visual_video_allocate_buffer (transform);
+
+		visual_video_depth_transform (transform, src);
+	}
+	
+	/* Setting all the pointers right */
+	if (transform != NULL)
+		srcp = transform;
+	else
+		srcp = src;
+	
+	/* We're looking at exactly the same types of VisVideo objects */
+	if (visual_video_compare (dest, src) == TRUE && alpha == FALSE && x == 0 && y == 0)
+		visual_mem_copy (dest->pixels, src->pixels, dest->size);
+	else if (alpha == FALSE || src->depth != VISUAL_VIDEO_DEPTH_32BIT)
+		blit_overlay_noalpha (dest, srcp, x, y);
+	else {
+		if (cpucaps->hasMMX != 0)
+			_lv_blit_overlay_alpha32_mmx (dest, srcp, x, y);
+		else
+			blit_overlay_alpha32 (dest, srcp, x, y);
+	}
+
+	
+	if (transform != NULL)
+		visual_object_unref (VISUAL_OBJECT (transform));
+	
+	return VISUAL_OK;
+}
+
+static int blit_overlay_noalpha (VisVideo *dest, const VisVideo *src, int x, int y)
+{
+	uint8_t *destbuf;
+	uint8_t *srcbuf;
+	int destp = dest->pitch;
+	int srcp = src->pitch;
+	int lwidth = (x + src->width);
+	int lheight = (y + src->height);
+	int ya, xa;
+
+	if (lwidth > dest->width)
+		lwidth += dest->width - lwidth;
+
+	if (lheight > dest->height)
+		lheight += dest->height - lheight;
+
+	destbuf = dest->pixels;
+	srcbuf = src->pixels;
+
+	if (lwidth < 0)
+		return VISUAL_OK;
+
+	xa = x > 0 ? x : 0;
+	for (ya = y > 0 ? y : 0; ya < lheight; ya++) {
+		visual_mem_copy (destbuf + ((ya * destp) + (xa * dest->bpp)),
+				srcbuf + (((ya - y) * srcp) + ((xa - x) * dest->bpp)),
+				(lwidth - (x > 0 ? x : 0)) * dest->bpp);
+	}
+
+	return VISUAL_OK;
+}
+
+static int blit_overlay_alpha32 (VisVideo *dest, const VisVideo *src, int x, int y)
+{
+	uint8_t *destbuf;
+	uint8_t *srcbuf;
+	int lwidth = (x + src->width);
+	int lwidth4;
+	int lheight = (y + src->height);
+	int ya, xa;
+	uint8_t alpha;
+
+	if (lwidth > dest->width)
+		lwidth += dest->width - lwidth;
+
+	if (lheight > dest->height)
+		lheight += dest->height - lheight;
+
+	destbuf = dest->pixels;
+	srcbuf = src->pixels;
+
+	if (lwidth < 0)
+		return VISUAL_OK;
+
+	lwidth4 = lwidth * 4;
+	
+	destbuf += ((y > 0 ? y : 0) * dest->pitch) + (x > 0 ? x * 4 : 0);
+	srcbuf += ((y < 0 ? abs(y) : 0) * src->pitch) + (x < 0 ? abs(x) * 4 : 0);
+	for (ya = y > 0 ? y : 0; ya < lheight; ya++) {
+		for (xa = x > 0 ? x * 4 : 0; xa < lwidth4; xa += 4) {
+			alpha = *(srcbuf + 3);
+			
+			*destbuf = ((alpha * (*srcbuf - *destbuf) >> 8) + *destbuf);
+			*(destbuf + 1) = ((alpha * (*(srcbuf + 1) - *(destbuf + 1)) >> 8) + *(destbuf + 1));
+			*(destbuf + 2) = ((alpha * (*(srcbuf + 2) - *(destbuf + 2)) >> 8) + *(destbuf + 2));
+                         
+			destbuf += 4;
+			srcbuf += 4;
+		}
+
+		destbuf += (dest->pitch - ((lwidth - x) * 4)) - (x < 0 ? x * 4 : 0);
+		srcbuf += x < 0 ? abs(x) * 4 : 0;
+		srcbuf += x + src->width > dest->width ? ((x + (src->pitch / 4)) - dest->width) * 4 : 0;
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets a certain color as the alpha channel and the density for the non alpha channel
+ * colors. This function can be only used on VISUAL_VIDEO_DEPTH_32BIT surfaces.
+ *
+ * @param video Pointer to the VisVideo in which the alpha channel is made.
+ * @param r The red value for the alpha channel color.
+ * @param g The green value for the alpha channel color.
+ * @param b The blue value for the alpha channel color.
+ * @param density The alpha density for the other colors.
+ * 
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL or -VISUAL_ERROR_VIDEO_INVALID_DEPTH on failure.
+ */
+int visual_video_alpha_color (VisVideo *video, uint8_t r, uint8_t g, uint8_t b, uint8_t density)
+{
+	int col = 0;
+	int i;
+	uint32_t *vidbuf;
+
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+	visual_log_return_val_if_fail (video->depth == VISUAL_VIDEO_DEPTH_32BIT, -VISUAL_ERROR_VIDEO_INVALID_DEPTH);
+
+	col = (r << 16 | g << 8 | b);
+
+	vidbuf = video->pixels;
+
+	for (i = 0; i < video->size / video->bpp; i++) {
+		if ((vidbuf[i] & 0x00ffffff) == col)
+			vidbuf[i] = col;
+		else
+			vidbuf[i] += (density << 24);
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Sets a certain alpha value for the complete buffer in the VisVideo. This function
+ * can be only used on VISUAL_VIDEO_DEPTH_32BIT surfaces.
+ *
+ * @param video Pointer to the VisVideo in which the alpha channel density is set.
+ * @param density The alpha density that is to be set.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NULL, -VISUAL_ERROR_VIDEO_INVALID_DEPTH on failure.
+ */
+int visual_video_alpha_fill (VisVideo *video, uint8_t density)
+{
+	int i;
+	uint8_t *vidbuf;
+
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+	visual_log_return_val_if_fail (video->depth == VISUAL_VIDEO_DEPTH_32BIT, -VISUAL_ERROR_VIDEO_INVALID_DEPTH);
+
+	/* FIXME byte order sensitive */
+	vidbuf = video->pixels + 3;
+
+	i = video->size;
+	while (i -= 4)
+		*(vidbuf += 4) = density;
+
+	return VISUAL_OK;
+}
+
+/**
+ * Video color transforms one VisVideo bgr pixel ordering into bgr pixel ordering.
+ * 
+ * @param dest Pointer to the destination VisVideo, which should be a clone of the source VisVideo
+ *	depth, pitch, dimension wise.
+ * @param src Pointer to the source VisVideo from which the bgr data is read.
+ *
+ * @return VISUAL_OK on succes, -VISUAL_ERROR_VIDEO_NOT_INDENTICAL, -VISUAL_ERROR_VIDEO_PIXELS_NULL or
+ *	-VISUAL_ERROR_VIDEO_INVALID_DEPTH on failure.
+ */
+int visual_video_color_bgr_to_rgb (VisVideo *dest, const VisVideo *src)
+{
+	visual_log_return_val_if_fail (visual_video_compare (dest, src) == TRUE, -VISUAL_ERROR_VIDEO_NOT_INDENTICAL);
+	visual_log_return_val_if_fail (dest->pixels != NULL, -VISUAL_ERROR_VIDEO_PIXELS_NULL);
+	visual_log_return_val_if_fail (src->pixels != NULL, -VISUAL_ERROR_VIDEO_PIXELS_NULL);
+	visual_log_return_val_if_fail (dest->depth != VISUAL_VIDEO_DEPTH_8BIT, -VISUAL_ERROR_VIDEO_INVALID_DEPTH);
+	
+	if (dest->depth == VISUAL_VIDEO_DEPTH_16BIT)
+		bgr_to_rgb16 (dest, src);
+	else if (dest->depth == VISUAL_VIDEO_DEPTH_24BIT)
+		bgr_to_rgb24 (dest, src);
+	else if (dest->depth == VISUAL_VIDEO_DEPTH_32BIT)
+		bgr_to_rgb32 (dest, src);
+
+	return VISUAL_OK;
+}
+
+/**
+ * Video depth transforms one VisVideo into another using the depth information
+ * stored within the VisVideos. The dimension should be equal however the pitch
+ * value of the destination may be set.
+ *
+ * @param viddest Pointer to the destination VisVideo to which the source
+ *	VisVideo is transformed.
+ * @param vidsrc Pointer to the source VisVideo.
+ *
+ * @return VISUAL_OK on succes, error values returned by visual_video_blit_overlay or
+ *	visual_video_depth_transform_to_buffer on failure.
+ */
+int visual_video_depth_transform (VisVideo *viddest, const VisVideo *vidsrc)
+{
+	/* We blit overlay it instead of just visual_mem_copy because the pitch can still be different */
+	if (viddest->depth == vidsrc->depth)
+		return visual_video_blit_overlay (viddest, vidsrc, 0, 0, FALSE);
+	
+	return visual_video_depth_transform_to_buffer (viddest->pixels,
+			vidsrc, vidsrc->pal, viddest->depth, viddest->pitch);
+}
+
+/**
+ * Less abstract video depth transform used by visual_video_depth_transform.
+ *
+ * @see visual_video_depth_transform
+ *
+ * @param dest Destination buffer.
+ * @param video Source VisVideo.
+ * @param pal Pointer to a VisPalette that can be set by full color to indexed color transforms.
+ * @param destdepth The destination depth.
+ * @param pitch The destination number of bytes per line.
+ *
+ * return VISUAL_OK on succes -VISUAL_ERROR_VIDEO_NULL, -VISUAL_ERROR_PALETTE_NULL, -VISUAL_ERROR_PALETTE_SIZE
+ *	or -VISUAL_ERROR_VIDEO_NOT_TRANSFORMED on failure.
+ */
+int visual_video_depth_transform_to_buffer (uint8_t *dest, const VisVideo *video,
+		VisPalette *pal, VisVideoDepth destdepth, int pitch)
+{
+	uint8_t *srcbuf = video->pixels;
+	int width = video->width;
+	int height = video->height;
+
+	visual_log_return_val_if_fail (video != NULL, -VISUAL_ERROR_VIDEO_NULL);
+	
+	if (destdepth == VISUAL_VIDEO_DEPTH_8BIT || video->depth == VISUAL_VIDEO_DEPTH_8BIT) {
+		visual_log_return_val_if_fail (pal != NULL, -VISUAL_ERROR_PALETTE_NULL);
+		visual_log_return_val_if_fail (pal->ncolors == 256, -VISUAL_ERROR_PALETTE_SIZE);
+	}
+
+	/* Destdepth is equal to sourcedepth case */
+	if (video->depth == destdepth) {
+		visual_mem_copy (dest, video->pixels, video->width * video->height * video->bpp);
+
+		return VISUAL_OK;
+	}
+	
+	if (video->depth == VISUAL_VIDEO_DEPTH_8BIT) {
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_16BIT)
+			return depth_transform_8_to_16_c (dest, srcbuf, width, height, pitch, pal);
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_24BIT)
+			return depth_transform_8_to_24_c (dest, srcbuf, width, height, pitch, pal);
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_32BIT)
+			return depth_transform_8_to_32_c (dest, srcbuf, width, height, pitch, pal);
+
+	} else if (video->depth == VISUAL_VIDEO_DEPTH_16BIT) {
+		
+		if (destdepth == VISUAL_VIDEO_DEPTH_8BIT)
+			return depth_transform_16_to_8_c (dest, srcbuf, width, height, pitch, pal);
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_24BIT)
+			return depth_transform_16_to_24_c (dest, srcbuf, width, height, pitch, NULL);
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_32BIT)
+			return depth_transform_16_to_32_c (dest, srcbuf, width, height, pitch, NULL);
+	
+	} else if (video->depth == VISUAL_VIDEO_DEPTH_24BIT) {
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_8BIT)
+			return depth_transform_24_to_8_c (dest, srcbuf, width, height, pitch, pal);
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_16BIT)
+			return depth_transform_24_to_16_c (dest, srcbuf, width, height, pitch, NULL);
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_32BIT)
+			return depth_transform_24_to_32_c (dest, srcbuf, width, height, pitch, NULL);
+
+	} else if (video->depth == VISUAL_VIDEO_DEPTH_32BIT) {
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_8BIT)
+			return depth_transform_32_to_8_c (dest, srcbuf, width, height, pitch, pal);
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_16BIT)
+			return depth_transform_32_to_16_c (dest, srcbuf, width, height, pitch, NULL);
+
+		if (destdepth == VISUAL_VIDEO_DEPTH_24BIT)
+			return depth_transform_32_to_24_c (dest, srcbuf, width, height, pitch, NULL);
+	}
+
+	return -VISUAL_ERROR_VIDEO_NOT_TRANSFORMED;
+}
+
+/**
+ * @}
+ */
+
+/* Depth transform C code */
+/* FIXME TODO depths:	c	sse	mmx	altivec
+ * 8 - 16		x
+ * 8 - 24		x
+ * 8 - 32		x
+ * 16 - 8		x
+ * 16 - 24		x
+ * 16 - 32		x
+ * 24 - 8		x
+ * 24 - 16		x
+ * 24 - 32		x
+ * 32 - 8		x
+ * 32 - 24		x
+ * 32 - 16		x
+ */
+
+static int depth_transform_8_to_16_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int i;
+	_color16 *destr = (_color16 *) dest;
+	int pitchdiff = (pitch - (width * 2)) >> 1;
+	_color16 colors[256];
+
+	for (i = 0; i < 256; i++) {
+		colors[i].r = pal->colors[i].r >> 3;	
+		colors[i].g = pal->colors[i].g >> 2;
+		colors[i].b = pal->colors[i].b >> 3;	
+	}
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++)
+			*destr++ = colors[*src++];
+
+		destr += pitchdiff;
+	}
+
+	return VISUAL_OK;
+}
+
+static int depth_transform_8_to_24_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int pitchdiff = pitch - (width * 3);
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++) {
+			*(dest++) = pal->colors[*(src)].r;
+			*(dest++) = pal->colors[*(src)].g;
+			*(dest++) = pal->colors[*(src)].b;
+			src++;
+		}
+
+		dest += pitchdiff;
+	}
+
+	return VISUAL_OK;
+}
+
+static int depth_transform_8_to_32_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y, i;
+	uint32_t *destr = (uint32_t *) dest;
+	uint32_t col;
+	int pitchdiff = (pitch - (width * 4)) >> 2;
+	
+	uint32_t colors[256];
+
+	for (i = 0; i < 256; i++) {
+		colors[i] =
+			pal->colors[i].r << 16 |
+			pal->colors[i].g << 8 |
+			pal->colors[i].b;
+	}
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++)
+			*destr++ = colors[*src++];
+
+		destr += pitchdiff;
+	}
+
+	return VISUAL_OK;
+}
+
+static int depth_transform_16_to_8_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int i = 0, j = 0;
+	_color16 *srcr = (_color16 *) src;
+	uint8_t r, g, b;
+	uint8_t col;
+	int pitchdiff = pitch - width;
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++) {
+			r = srcr[j].r << 3;
+			g = srcr[j].g << 2;
+			b = srcr[j].b << 3;
+			j++;
+
+			/* FIXME optimize */
+			col = (r + g + b) / 3;
+
+			pal->colors[col].r = r;
+			pal->colors[col].g = g;
+			pal->colors[col].b = b;
+
+			dest[i++] = col;
+		}
+
+		i += pitchdiff;	
+	}
+
+	return VISUAL_OK;
+}
+
+static int depth_transform_16_to_24_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int i = 0, j = 0;
+	_color16 *srcr = (_color16 *) src;
+	int pitchdiff = pitch - (width * 3);
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++) {
+			dest[j++] = srcr[i].r << 3;
+			dest[j++] = srcr[i].g << 2;
+			dest[j++] = srcr[i].b << 3;
+			i++;	
+		}
+
+		j += pitchdiff;
+	}
+
+	return VISUAL_OK;
+}
+
+static int depth_transform_16_to_32_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int i = 0, j = 0;
+	_color16 *srcr = (_color16 *) src;
+	int pitchdiff = pitch - (width * 4);
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++) {
+			dest[j++] = srcr[i].b << 3;
+			dest[j++] = srcr[i].g << 2;
+			dest[j++] = srcr[i].r << 3;
+			dest[j++] = 0;
+			i++;
+		}
+	
+		j += pitchdiff;
+	}
+	
+	return VISUAL_OK;
+}
+
+static int depth_transform_24_to_8_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int i = 0, j = 0;
+	uint8_t r, g, b;
+	uint8_t col;
+	int pitchdiff = pitch - width;
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++) {
+			b = src[j++];
+			g = src[j++];
+			r = src[j++];
+
+			/* FIXME optimize */
+			col = (b + g + r) / 3;
+			
+			pal->colors[col].r = r;
+			pal->colors[col].g = g;
+			pal->colors[col].b = b;
+
+			dest[i++] = col;
+		}
+
+		i += pitchdiff;	
+	}
+
+	return VISUAL_OK;
+}
+
+static int depth_transform_24_to_16_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int i = 0, j = 0;
+	_color16 *destr = (_color16 *) dest;
+	int pitchdiff = (pitch - (width * 2)) >> 1;
+	
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++) {
+			destr[i].b = src[j++] >> 3;
+			destr[i].g = src[j++] >> 2;
+			destr[i].r = src[j++] >> 3;
+			i++;
+		}
+
+		i += pitchdiff;
+	}
+	
+	return VISUAL_OK;
+}
+
+static int depth_transform_24_to_32_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int i = 0, j = 0;
+	int pitchdiff = pitch - (width * 4);
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++) {
+			dest[j++] = src[i++];
+			dest[j++] = src[i++];
+			dest[j++] = src[i++];
+			dest[j++] = 0;
+		}
+
+		j += pitchdiff;
+	}
+	
+	return VISUAL_OK;
+}
+
+static int depth_transform_32_to_8_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int i = 0, j = 0;
+	uint8_t r, g, b;
+	uint8_t col;
+	int pitchdiff = pitch - width;
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++) {
+			r = src[j++];
+			g = src[j++];
+			b = src[j++];
+			j++;
+
+			/* FIXME optimize */
+			col = (r + g + b) / 3;
+
+			pal->colors[col].r = r;
+			pal->colors[col].g = g;
+			pal->colors[col].b = b;
+
+			dest[i++] = col;
+		}
+
+		i += pitchdiff;	
+	}
+	
+	return VISUAL_OK;
+}
+
+static int depth_transform_32_to_16_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int i = 0, j = 0;
+	_color16 *destr = (_color16 *) dest;
+	int pitchdiff = (pitch - (width * 2)) >> 1;
+	
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++) {
+			destr[i].r = src[j++] >> 3;
+			destr[i].g = src[j++] >> 2;
+			destr[i].b = src[j++] >> 3;
+			j++;
+			i++;
+		}
+
+		i += pitchdiff;
+	}
+
+	return VISUAL_OK;
+}
+
+static int depth_transform_32_to_24_c (uint8_t *dest, uint8_t *src, int width, int height, int pitch, VisPalette *pal)
+{
+	int x, y;
+	int i = 0, j = 0;
+	int pitchdiff = pitch - (width * 3);
+
+	for (y = 0; y < height; y++) {
+		for (x = 0; x < width; x++) {
+			dest[i++] = src[j++];
+			dest[i++] = src[j++];
+			dest[i++] = src[j++];
+			j++;
+		}
+		
+		i += pitchdiff;
+	}
+	
+	return VISUAL_OK;
+}
+
+static int bgr_to_rgb16 (VisVideo *dest, const VisVideo *src)
+{
+	_color16 *destbuf, *srcbuf;
+	int x, y;
+	int i = 0;
+	int pitchdiff = (dest->pitch - (dest->width * 2)) >> 1;
+	
+	destbuf = (_color16 *) dest->pixels;
+	srcbuf = (_color16 *) src->pixels;
+	
+	for (y = 0; y < dest->height; y++) {
+		for (x = 0; x < dest->width; x++) {
+			destbuf[i].b = srcbuf[i].r;
+			destbuf[i].g = srcbuf[i].g;
+			destbuf[i].r = srcbuf[i].b;
+			i++;
+		}
+
+		i += pitchdiff;
+	}
+	
+	return VISUAL_OK;
+}
+
+static int bgr_to_rgb24 (VisVideo *dest, const VisVideo *src)
+{
+	uint8_t *destbuf, *srcbuf;
+	int x, y;
+	int i = 0;
+	int pitchdiff = dest->pitch - (dest->width * 3);
+
+	destbuf = dest->pixels;
+	srcbuf = src->pixels;
+	
+	for (y = 0; y < dest->height; y++) {
+		for (x = 0; x < dest->width; x++) {
+			destbuf[i + 2] = srcbuf[i];
+			destbuf[i + 1] = srcbuf[i + 1];
+			destbuf[i] = srcbuf[i + 2];
+		
+			i += 3;
+		}
+
+		i += pitchdiff;
+	}
+
+	return VISUAL_OK;
+}
+
+static int bgr_to_rgb32 (VisVideo *dest, const VisVideo *src)
+{
+	uint8_t *destbuf, *srcbuf;
+	int x, y;
+	int i = 0;
+	int pitchdiff = dest->pitch - (dest->width * 4);
+
+	destbuf = dest->pixels;
+	srcbuf = src->pixels;
+	
+	for (y = 0; y < dest->height; y++) {
+		for (x = 0; x < dest->width; x++) {
+			destbuf[i + 2] = srcbuf[i];
+			destbuf[i + 1] = srcbuf[i + 1];
+			destbuf[i] = srcbuf[i + 2];
+
+			destbuf[i + 3] = srcbuf[i + 3];
+
+			i += 4;
+		}
+
+		i += pitchdiff;
+	}
+
+	return VISUAL_OK;
+}
+
+/**
+ * Scale video.
+ *
+ * @param dest Pointer to VisVideo object for storing scaled image.
+ * @param src Pointer to VisVideo object whose image is to be scaled.
+ * @param scale_method Scaling method to use.
+ *
+ * @return VISUAL_OK on success, -VISUAL_ERROR_VIDEO_NULL or -VISUAL_ERROR_VIDEO_INVALID_DEPTH on failure.
+ */
+int visual_video_scale (VisVideo *dest, const VisVideo *src, VisVideoScaleMethod scale_method)
+{
+	VisCPU *cpucaps;
+
+	visual_log_return_val_if_fail (dest != NULL, -VISUAL_ERROR_VIDEO_NULL);
+	visual_log_return_val_if_fail (src != NULL, -VISUAL_ERROR_VIDEO_NULL);
+	visual_log_return_val_if_fail (dest->depth == src->depth, -VISUAL_ERROR_VIDEO_INVALID_DEPTH);
+	visual_log_return_val_if_fail (scale_method == VISUAL_VIDEO_SCALE_NEAREST ||
+			scale_method == VISUAL_VIDEO_SCALE_BILINEAR, -VISUAL_ERROR_VIDEO_INVALID_SCALE_METHOD);
+
+	cpucaps = visual_cpu_get_caps ();
+	
+	switch (dest->depth) {
+		case VISUAL_VIDEO_DEPTH_8BIT:
+			if (scale_method == VISUAL_VIDEO_SCALE_NEAREST)
+				scale_nearest_8 (dest, src);
+			else if (scale_method == VISUAL_VIDEO_SCALE_BILINEAR)
+				scale_bilinear_8 (dest, src);
+
+			break;
+
+		case VISUAL_VIDEO_DEPTH_16BIT:
+			if (scale_method == VISUAL_VIDEO_SCALE_NEAREST)
+				scale_nearest_16 (dest, src);
+			else if (scale_method == VISUAL_VIDEO_SCALE_BILINEAR)
+				scale_bilinear_16 (dest, src);
+
+			break;
+		
+		case VISUAL_VIDEO_DEPTH_24BIT:
+			if (scale_method == VISUAL_VIDEO_SCALE_NEAREST)
+				scale_nearest_24 (dest, src);
+			else if (scale_method == VISUAL_VIDEO_SCALE_BILINEAR)
+				scale_bilinear_24 (dest, src);
+
+			break;
+
+		case VISUAL_VIDEO_DEPTH_32BIT:
+			if (scale_method == VISUAL_VIDEO_SCALE_NEAREST)
+				scale_nearest_32 (dest, src);
+			else if (scale_method == VISUAL_VIDEO_SCALE_BILINEAR) {
+				if (cpucaps->hasMMX != 0)
+					_lv_scale_bilinear_32_mmx (dest, src);
+				else	
+					scale_bilinear_32 (dest, src);
+			}
+
+			break;
+
+		default:
+			visual_log (VISUAL_LOG_CRITICAL, "Invalid depth passed to the scaler");
+
+			return -VISUAL_ERROR_VIDEO_INVALID_DEPTH;
+
+			break;
+	}
+
+	return VISUAL_OK;
+}
+
+static int scale_nearest_8 (VisVideo *dest, const VisVideo *src)
+{
+	int x, y;
+	uint32_t u, v, du, dv; /* fixed point 16.16 */
+	uint8_t *dest_pixel, *src_pixel_row;
+
+	du = (src->width << 16) / dest->width;
+	dv = (src->height << 16) / dest->height;
+	v = 0;
+
+	dest_pixel = dest->pixels;
+
+	for (y = 0; y < dest->height; y++, v += dv) {
+		src_pixel_row = (uint8_t *) src->pixel_rows[v >> 16];
+
+                if (v >> 16 >= src->height)
+			v -= 0x10000;
+	
+		u = 0;
+		for (x = 0; x < dest->width; x++, u += du)
+			*dest_pixel++ = src_pixel_row[u >> 16];
+
+		dest_pixel += dest->pitch - dest->width;
+	}
+
+	return VISUAL_OK;
+}
+
+static int scale_nearest_16 (VisVideo *dest, const VisVideo *src)
+{
+	int x, y;
+	uint32_t u, v, du, dv; /* fixed point 16.16 */
+	uint16_t *dest_pixel, *src_pixel_row;
+
+	du = (src->width << 16) / dest->width;
+	dv = (src->height << 16) / dest->height;
+	v = 0;
+
+	dest_pixel = dest->pixels;
+
+	for (y = 0; y < dest->height; y++, v += dv) {
+		src_pixel_row = (uint16_t *) src->pixel_rows[v >> 16];
+
+		if (v >> 16 >= src->height)
+			v -= 0x10000;
+		
+		u = 0;
+		for (x = 0; x < dest->width; x++, u += du)
+			*dest_pixel++ = src_pixel_row[u >> 16];
+
+		dest_pixel += (dest->pitch / 2) - dest->width;
+	}
+
+	return VISUAL_OK;
+}
+
+/* FIXME this version is of course butt ugly */
+/* IF color24 is allowed use it here as well */
+static int scale_nearest_24 (VisVideo *dest, const VisVideo *src)
+{
+	int x, y;
+	uint32_t u, v, du, dv; /* fixed point 16.16 */
+	_color24 *dest_pixel, *src_pixel_row;
+
+	du = (src->width << 16) / dest->width;
+	dv = (src->height << 16) / dest->height;
+	v = 0;
+
+	dest_pixel = dest->pixels;
+
+	for (y = 0; y < dest->height; y++, v += dv) {
+		src_pixel_row = (_color24 *) src->pixel_rows[v >> 16];
+
+		if (v >> 16 >= src->height)
+			v -= 0x10000;
+		
+		u = 0;
+		for (x = 0; x < dest->width; x++, u += du)
+			*dest_pixel++ = src_pixel_row[u >> 16];
+
+		dest_pixel += (dest->pitch / 3) - dest->width;
+	}
+
+	return VISUAL_OK;
+}
+
+static int scale_nearest_32 (VisVideo *dest, const VisVideo *src)
+{
+	int x, y;
+	uint32_t u, v, du, dv; /* fixed point 16.16 */
+	uint32_t *dest_pixel, *src_pixel_row;
+
+	du = (src->width << 16) / dest->width;
+	dv = (src->height << 16) / dest->height;
+	v = 0;
+
+	dest_pixel = dest->pixels;
+
+	for (y = 0; y < dest->height; y++, v += dv) {
+		src_pixel_row = (uint32_t *) src->pixel_rows[v >> 16];
+
+		if (v >> 16 >= src->height)
+			v -= 0x10000;
+		
+		u = 0;
+		for (x = 0; x < dest->width; x++, u += du)
+			*dest_pixel++ = src_pixel_row[u >> 16];
+
+		dest_pixel += (dest->pitch / 4) - dest->width;
+	}
+
+	return VISUAL_OK;
+}
+
+static int scale_bilinear_8 (VisVideo *dest, const VisVideo *src)
+{
+	uint32_t y;
+	uint32_t u, v, du, dv; /* fixed point 16.16 */
+	uint8_t *dest_pixel, *src_pixel_rowu, *src_pixel_rowl;
+
+	dest_pixel = dest->pixels;
+
+	du = ((src->width - 1)  << 16) / dest->width;
+	dv = ((src->height - 1) << 16) / dest->height;
+	v = 0;
+
+	for (y = dest->height; y--; v += dv) {
+		uint32_t x;
+		uint32_t fracU, fracV;     /* fixed point 24.8 [0,1[    */
+
+		if (v >> 16 >= src->height - 1)
+			v -= 0x10000;
+
+		src_pixel_rowu = (uint8_t *) src->pixel_rows[v >> 16];
+		src_pixel_rowl = (uint8_t *) src->pixel_rows[(v >> 16) + 1];
+
+		/* fracV = frac(v) = v & 0xffff */
+		/* fixed point format convertion: fracV >>= 8) */
+		fracV = (v & 0xffff) >> 8;
+		u = 0;
+
+		for (x = dest->width - 1; x--; u += du) {
+			uint8_t cul, cll, cur, clr, b;
+			uint32_t ul, ll, ur, lr; /* fixed point 16.16 [0,1[   */
+			uint32_t b0; /* fixed point 16.16 [0,255[ */
+
+			/* fracU = frac(u) = u & 0xffff */
+			/* fixed point format convertion: fracU >>= 8) */
+			fracU  = (u & 0xffff) >> 8;
+
+			/* notice 0x100 = 1.0 (fixed point 24.8) */
+			ul = (0x100 - fracU) * (0x100 - fracV);
+			ll = (0x100 - fracU) * fracV;
+			ur = fracU * (0x100 - fracV);
+			lr = fracU * fracV;
+
+			cul = src_pixel_rowu[u >> 16];
+			cll = src_pixel_rowl[u >> 16];
+			cur = src_pixel_rowu[(u >> 16) + 1];
+			clr = src_pixel_rowl[(u >> 16) + 1];
+
+			b0 = ul * cul;
+			b0 += ll * cll;
+			b0 += ur * cur;
+			b0 += lr * clr;
+
+			*dest_pixel++ = b0 >> 16;
+		}
+
+		memset (dest_pixel, 0, dest->pitch - (dest->width - 1));
+		dest_pixel += dest->pitch - (dest->width - 1);
+
+	}
+
+	return VISUAL_OK;
+}
+
+static int scale_bilinear_16 (VisVideo *dest, const VisVideo *src)
+{
+	uint32_t y;
+	uint32_t u, v, du, dv; /* fixed point 16.16 */
+	_color16 *dest_pixel, *src_pixel_rowu, *src_pixel_rowl;
+	dest_pixel = dest->pixels;
+
+	du = ((src->width - 1)  << 16) / dest->width;
+	dv = ((src->height - 1) << 16) / dest->height;
+	v = 0;
+
+	for (y = dest->height; y--; v += dv) {
+		uint32_t x;
+		uint32_t fracU, fracV;     /* fixed point 24.8 [0,1[    */
+
+		if (v >> 16 >= src->height - 1)
+			v -= 0x10000;
+
+		src_pixel_rowu = (_color16 *) src->pixel_rows[v >> 16];
+		src_pixel_rowl = (_color16 *) src->pixel_rows[(v >> 16) + 1];
+
+		/* fracV = frac(v) = v & 0xffff */
+		/* fixed point format convertion: fracV >>= 8) */
+		fracV = (v & 0xffff) >> 8;
+		u = 0.0;
+
+		for (x = dest->width - 1; x--; u += du) {
+			_color16 cul, cll, cur, clr, b;
+			uint32_t ul, ll, ur, lr; /* fixed point 16.16 [0,1[   */
+			uint32_t b3, b2, b1, b0; /* fixed point 16.16 [0,255[ */
+
+			/* fracU = frac(u) = u & 0xffff */
+			/* fixed point format convertion: fracU >>= 8) */
+			fracU  = (u & 0xffff) >> 8;
+
+			/* notice 0x100 = 1.0 (fixed point 24.8) */
+			ul = (0x100 - fracU) * (0x100 - fracV);
+			ll = (0x100 - fracU) * fracV;
+			ur = fracU * (0x100 - fracV);
+			lr = fracU * fracV;
+
+			cul = src_pixel_rowu[u >> 16];
+			cll = src_pixel_rowl[u >> 16];
+			cur = src_pixel_rowu[(u >> 16) + 1];
+			clr = src_pixel_rowl[(u >> 16) + 1];
+
+			b0 = ul * cul.r;
+			b1 = ul * cul.g;
+			b2 = ul * cul.b;
+
+			b0 += ll * cll.r;
+			b1 += ll * cll.g;
+			b2 += ll * cll.b;
+
+			b0 += ur * cur.r;
+			b1 += ur * cur.g;
+			b2 += ur * cur.b;
+
+			b0 += lr * clr.r;
+			b1 += lr * clr.g;
+			b2 += lr * clr.b;
+
+			b.r = b0 >> 16;
+			b.g = b1 >> 16;
+			b.b = b2 >> 16;
+
+			*dest_pixel++ = b;
+		}
+
+		memset (dest_pixel, 0, (dest->pitch - ((dest->width - 1) * 2)));
+		dest_pixel += (dest->pitch / 2) - ((dest->width - 1));
+	}
+
+	return VISUAL_OK;
+}
+
+static int scale_bilinear_24 (VisVideo *dest, const VisVideo *src)
+{
+	uint32_t y;
+	uint32_t u, v, du, dv; /* fixed point 16.16 */
+	_color24 *dest_pixel, *src_pixel_rowu, *src_pixel_rowl;
+	dest_pixel = dest->pixels;
+
+	du = ((src->width - 1)  << 16) / dest->width;
+	dv = ((src->height - 1) << 16) / dest->height;
+	v = 0;
+
+	for (y = dest->height; y--; v += dv) {
+		uint32_t x;
+		uint32_t fracU, fracV;     /* fixed point 24.8 [0,1[    */
+
+		if (v >> 16 >= src->height - 1)
+			v -= 0x10000;
+
+		src_pixel_rowu = (_color24 *) src->pixel_rows[v >> 16];
+		src_pixel_rowl = (_color24 *) src->pixel_rows[(v >> 16) + 1];
+
+		/* fracV = frac(v) = v & 0xffff */
+		/* fixed point format convertion: fracV >>= 8) */
+		fracV = (v & 0xffff) >> 8;
+		u = 0;
+
+		for (x = dest->width - 1; x--; u += du) {
+			_color24 cul, cll, cur, clr, b;
+			uint32_t ul, ll, ur, lr; /* fixed point 16.16 [0,1[   */
+			uint32_t b3, b2, b1, b0; /* fixed point 16.16 [0,255[ */
+
+			/* fracU = frac(u) = u & 0xffff */
+			/* fixed point format convertion: fracU >>= 8) */
+			fracU  = (u & 0xffff) >> 8;
+
+			/* notice 0x100 = 1.0 (fixed point 24.8) */
+			ul = (0x100 - fracU) * (0x100 - fracV);
+			ll = (0x100 - fracU) * fracV;
+			ur = fracU * (0x100 - fracV);
+			lr = fracU * fracV;
+
+			cul = src_pixel_rowu[u >> 16];
+			cll = src_pixel_rowl[u >> 16];
+			cur = src_pixel_rowu[(u >> 16) + 1];
+			clr = src_pixel_rowl[(u >> 16) + 1];
+
+			b0 = ul * cul.r;
+			b1 = ul * cul.g;
+			b2 = ul * cul.b;
+
+			b0 += ll * cll.r;
+			b1 += ll * cll.g;
+			b2 += ll * cll.b;
+
+			b0 += ur * cur.r;
+			b1 += ur * cur.g;
+			b2 += ur * cur.b;
+
+			b0 += lr * clr.r;
+			b1 += lr * clr.g;
+			b2 += lr * clr.b;
+
+			b.r = b0 >> 16;
+			b.g = b1 >> 16;
+			b.b = b2 >> 16;
+
+			*dest_pixel++ = b;
+		}
+
+		memset (dest_pixel, 0, (dest->pitch - ((dest->width - 1) * 3)));
+		dest_pixel += (dest->pitch / 3) - ((dest->width - 1));
+	}
+
+	return VISUAL_OK;
+}
+
+static int scale_bilinear_32 (VisVideo *dest, const VisVideo *src)
+{
+	uint32_t y;
+	uint32_t u, v, du, dv; /* fixed point 16.16 */
+	uint32_t *dest_pixel, *src_pixel_rowu, *src_pixel_rowl;
+
+	dest_pixel = dest->pixels;
+
+	du = ((src->width - 1)  << 16) / dest->width;
+	dv = ((src->height - 1) << 16) / dest->height;
+	v = 0;
+
+	for (y = dest->height; y--; v += dv) {
+		uint32_t x;
+		uint32_t fracU, fracV;     /* fixed point 24.8 [0,1[    */
+
+		if (v >> 16 >= src->height - 1)
+			v -= 0x10000;
+
+		src_pixel_rowu = (uint32_t *) src->pixel_rows[v >> 16];
+		src_pixel_rowl = (uint32_t *) src->pixel_rows[(v >> 16) + 1];
+
+		/* fracV = frac(v) = v & 0xffff */
+		/* fixed point format convertion: fracV >>= 8) */
+		fracV = (v & 0xffff) >> 8;
+		u = 0;
+
+		for (x = dest->width - 1; x--; u += du) {
+			union {
+				uint8_t  c8[4];
+				uint32_t c32;
+			} cul, cll, cur, clr, b;
+			uint32_t ul, ll, ur, lr; /* fixed point 16.16 [0,1[   */
+			uint32_t b3, b2, b1, b0; /* fixed point 16.16 [0,255[ */
+
+			/* fracU = frac(u) = u & 0xffff */
+			/* fixed point format convertion: fracU >>= 8) */
+			fracU  = (u & 0xffff) >> 8;
+
+			/* notice 0x100 = 1.0 (fixed point 24.8) */
+			ul = (0x100 - fracU) * (0x100 - fracV);
+			ll = (0x100 - fracU) * fracV;
+			ur = fracU * (0x100 - fracV);
+			lr = fracU * fracV;
+
+			cul.c32 = src_pixel_rowu[u >> 16];
+			cll.c32 = src_pixel_rowl[u >> 16];
+			cur.c32 = src_pixel_rowu[(u >> 16) + 1];
+			clr.c32 = src_pixel_rowl[(u >> 16) + 1];
+
+			b0 = ul * cul.c8[0];
+			b1 = ul * cul.c8[1];
+			b2 = ul * cul.c8[2];
+			b3 = ul * cul.c8[3];
+
+			b0 += ll * cll.c8[0];
+			b1 += ll * cll.c8[1];
+			b2 += ll * cll.c8[2];
+			b3 += ll * cll.c8[3];
+
+			b0 += ur * cur.c8[0];
+			b1 += ur * cur.c8[1];
+			b2 += ur * cur.c8[2];
+			b3 += ur * cur.c8[3];
+
+			b0 += lr * clr.c8[0];
+			b1 += lr * clr.c8[1];
+			b2 += lr * clr.c8[2];
+			b3 += lr * clr.c8[3];
+
+			b.c8[0] = b0 >> 16;
+			b.c8[1] = b1 >> 16;
+			b.c8[2] = b2 >> 16;
+			b.c8[3] = b3 >> 16;
+
+			*dest_pixel++ = b.c32;
+		}
+
+		memset (dest_pixel, 0, (dest->pitch - ((dest->width - 1) * 4)));
+		dest_pixel += (dest->pitch / 4) - ((dest->width - 1));
+
+	}
+
+	return VISUAL_OK;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_video.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,155 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *	    Duilio J. Protti <dprotti@users.sourceforge.net>
+ *	    Chong Kai Xiong <descender@phreaker.net>
+ *	    Jean-Christophe Hoelt <jeko@ios-software.com>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _LV_VIDEO_H
+#define _LV_VIDEO_H
+
+#include <libvisual/lv_common.h>
+#include <libvisual/lv_palette.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define VISUAL_VIDEO(obj)				(VISUAL_CHECK_CAST ((obj), 0, VisVideo))
+
+/* NOTE: The depth find helper code in lv_actor depends on an arrangment from low to high */
+
+/**
+ * Video flags, for internal use only.
+ */
+typedef enum {
+	VISUAL_VIDEO_FLAG_NONE			= 0,	/**< No flags. */
+	VISUAL_VIDEO_FLAG_ALLOCATED_BUFFER	= 1,	/**< Libvisual allocated this buffer. */
+	VISUAL_VIDEO_FLAG_EXTERNAL_BUFFER	= 2,	/**< External allocated buffer. */
+} VisVideoFlags;
+
+/**
+ * Enumerate that defines video depths for use within plugins, libvisual functions, etc.
+ */
+typedef enum {
+	VISUAL_VIDEO_DEPTH_NONE		= 0,	/**< No video surface flag. */
+	VISUAL_VIDEO_DEPTH_8BIT		= 1,	/**< 8 bits indexed surface flag. */
+	VISUAL_VIDEO_DEPTH_16BIT	= 2,	/**< 16 bits 5-6-5 surface flag. */
+	VISUAL_VIDEO_DEPTH_24BIT	= 4,	/**< 24 bits surface flag. */
+	VISUAL_VIDEO_DEPTH_32BIT	= 8,	/**< 32 bits surface flag. */
+	VISUAL_VIDEO_DEPTH_GL		= 16,	/**< openGL surface flag. */
+	VISUAL_VIDEO_DEPTH_ENDLIST	= 32,	/**< Used to mark the end of the depth list. */
+	VISUAL_VIDEO_DEPTH_ERROR	= -1,	/**< Used when there is an error. */
+	VISUAL_VIDEO_DEPTH_ALL		= VISUAL_VIDEO_DEPTH_8BIT |  \
+					  VISUAL_VIDEO_DEPTH_16BIT | \
+					  VISUAL_VIDEO_DEPTH_24BIT | \
+					  VISUAL_VIDEO_DEPTH_32BIT | \
+					  VISUAL_VIDEO_DEPTH_GL /**< All graphical depths. */
+} VisVideoDepth;
+
+/**
+ * Enumerate that defines the different methods of scaling within VisVideo.
+ */
+typedef enum {
+	VISUAL_VIDEO_SCALE_NEAREST  = 0,    /**< Nearest neighbour. */
+	VISUAL_VIDEO_SCALE_BILINEAR = 1	    /**< Bilinearly interpolated. */
+} VisVideoScaleMethod;
+
+
+typedef struct _VisVideo VisVideo;
+
+/**
+ * Data structure that contains all the information about a screen surface.
+ * Contains all the information regarding a screen surface like the current depth it's in,
+ * width, height, bpp, the size in bytes it's pixel buffer is and the screen pitch.
+ *
+ * It also contains a pointer to the pixels and an optional pointer to the palette.
+ *
+ * Elements within the structure should be set using the VisVideo system it's methods.
+ */
+struct _VisVideo {
+	VisObject	 object;	/**< The VisObject data. */
+
+	VisVideoDepth	 depth;		/**< Surface it's depth. */
+	int		 width;		/**< Surface it's width. */
+	int		 height;	/**< Surface it's height. */
+	int		 bpp;		/**< Surface it's bytes per pixel. */
+	int		 size;		/**< Surface it's screen buffer size in bytes. */
+	int		 pitch;		/**< Surface it's pitch value. Value contains
+					  * the number of bytes per line. */
+	void		*pixels;	/**< Pointer to the pixels. */
+	void		**pixel_rows;	/**< Pixel row start pointer table. */
+	VisPalette	*pal;		/**< Optional pointer to the palette. */
+
+	VisVideoFlags	flags;		/**< Private field */
+};
+
+/* prototypes */
+VisVideo *visual_video_new (void);
+VisVideo *visual_video_new_with_buffer (int width, int height, VisVideoDepth depth);
+int visual_video_free_buffer (VisVideo *video);
+int visual_video_allocate_buffer (VisVideo *video);
+int visual_video_have_allocated_buffer (const VisVideo *video);
+int visual_video_clone (VisVideo *dest, const VisVideo *src);
+int visual_video_compare (const VisVideo *src1, const VisVideo *src2);
+
+int visual_video_set_palette (VisVideo *video, VisPalette *pal);
+int visual_video_set_buffer (VisVideo *video, void *buffer);
+int visual_video_set_dimension (VisVideo *video, int width, int height);
+int visual_video_set_pitch (VisVideo *video, int pitch);
+int visual_video_set_depth (VisVideo *video, VisVideoDepth depth);
+
+int visual_video_depth_is_supported (int depthflag, VisVideoDepth depth);
+VisVideoDepth visual_video_depth_get_next (int depthflag, VisVideoDepth depth);
+VisVideoDepth visual_video_depth_get_prev (int depthflag, VisVideoDepth depth);
+VisVideoDepth visual_video_depth_get_lowest (int depthflag);
+VisVideoDepth visual_video_depth_get_highest (int depthflag);
+VisVideoDepth visual_video_depth_get_highest_nogl (int depthflag);
+int visual_video_depth_is_sane (VisVideoDepth depth);
+int visual_video_depth_value_from_enum (VisVideoDepth depth);
+VisVideoDepth visual_video_depth_enum_from_value (int depthvalue);
+
+int visual_video_bpp_from_depth (VisVideoDepth depth);
+
+int visual_video_blit_overlay (VisVideo *dest, const VisVideo *src, int x, int y, int alpha);
+
+int visual_video_alpha_color (VisVideo *video, uint8_t r, uint8_t g, uint8_t b, uint8_t density);
+int visual_video_alpha_fill (VisVideo *video, uint8_t density);
+
+int visual_video_color_bgr_to_rgb (VisVideo *dest, const VisVideo *src);
+
+int visual_video_depth_transform (VisVideo *viddest, const VisVideo *vidsrc);
+int visual_video_depth_transform_to_buffer (uint8_t *dest, const VisVideo *video,
+		VisPalette *pal, VisVideoDepth destdepth, int pitch);
+
+int visual_video_scale (VisVideo *dest, const VisVideo *src, VisVideoScaleMethod scale_method);
+
+/* Optimized versions of performance sensitive routines */
+/* mmx from lv_video_mmx.c */ /* FIXME can we do this nicer ? */
+int _lv_blit_overlay_alpha32_mmx (VisVideo *dest, const VisVideo *src, int x, int y);
+int _lv_scale_bilinear_32_mmx (VisVideo *dest, const VisVideo *src);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LV_VIDEO_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lv_video_mmx.c	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,257 @@
+/* Libvisual - The audio visualisation framework.
+ * 
+ * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
+ *
+ * Authors: Dennis Smit <ds@nerds-incorporated.org>
+ *	    Jean-Christophe Hoelt <jeko@ios-software.com>
+ *
+ * $Id:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <lvconfig.h>
+#include "lv_common.h"
+#include "lv_video.h"
+
+int _lv_blit_overlay_alpha32_mmx (VisVideo *dest, const VisVideo *src, int x, int y)
+{
+#ifdef VISUAL_ARCH_X86
+	uint8_t *destbuf;
+	uint8_t *srcbuf;
+	int lwidth = (x + src->width);
+	int lwidth4;
+	int lheight = (y + src->height);
+	int ya, xa;
+	uint8_t alpha;
+
+	if (lwidth > dest->width)
+		lwidth += dest->width - lwidth;
+
+	if (lheight > dest->height)
+		lheight += dest->height - lheight;
+
+	destbuf = dest->pixels;
+	srcbuf = src->pixels;
+
+	if (lwidth < 0)
+		return VISUAL_OK;
+
+	lwidth4 = lwidth * 4;
+	
+	/* Reset some regs */
+	__asm __volatile
+		("\n\t pxor %%mm6, %%mm6"
+		 ::: "mm6");
+	
+	destbuf += ((y > 0 ? y : 0) * dest->pitch) + (x > 0 ? x * 4 : 0);
+	srcbuf += ((y < 0 ? abs(y) : 0) * src->pitch) + (x < 0 ? abs(x) * 4 : 0);
+	for (ya = y > 0 ? y : 0; ya < lheight; ya++) {
+		for (xa = x > 0 ? x * 4 : 0; xa < lwidth4; xa += 4) {
+			/* pixel = ((alpha * ((src - dest)) / 255) + dest) */
+			__asm __volatile
+				("\n\t movd %[spix], %%mm0"
+				 "\n\t movd %[dpix], %%mm1"
+				 "\n\t movq %%mm0, %%mm2"
+				 "\n\t movq %%mm0, %%mm3"
+				 "\n\t psrlq $24, %%mm2"	/* The alpha */
+				 "\n\t movq %%mm0, %%mm4"
+				 "\n\t psrld $24, %%mm3"
+				 "\n\t psrld $24, %%mm4"
+				 "\n\t psllq $32, %%mm2"
+				 "\n\t psllq $16, %%mm3"
+				 "\n\t por %%mm4, %%mm2"
+				 "\n\t punpcklbw %%mm6, %%mm0"	/* interleaving dest */
+				 "\n\t por %%mm3, %%mm2"
+				 "\n\t punpcklbw %%mm6, %%mm1"	/* interleaving source */
+				 "\n\t psubsw %%mm1, %%mm0"	/* (src - dest) part */
+				 "\n\t pmullw %%mm2, %%mm0"	/* alpha * (src - dest) */
+				 "\n\t psrlw $8, %%mm0"		/* / 256 */
+				 "\n\t paddb %%mm1, %%mm0"	/* + dest */
+				 "\n\t packuswb %%mm0, %%mm0"
+				 "\n\t movd %%mm0, %[dest]"
+				 : [dest] "=m" (*destbuf)
+				 : [dpix] "m" (*destbuf)
+				 , [spix] "m" (*srcbuf)
+				 : "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
+
+			destbuf += 4;
+			srcbuf += 4;
+		}
+
+		destbuf += (dest->pitch - ((lwidth - x) * 4)) - (x < 0 ? x * 4 : 0);
+		srcbuf += x < 0 ? abs(x) * 4 : 0;
+		srcbuf += x + src->width > dest->width ? ((x + (src->pitch / 4)) - dest->width) * 4 : 0;
+	}
+
+	__asm __volatile
+		("\n\t emms");
+
+	return VISUAL_OK;
+#else /* !VISUAL_ARCH_X86 */
+	return VISUAL_ERROR_CPU_INVALID_CODE;
+#endif
+}
+
+int _lv_scale_bilinear_32_mmx (VisVideo *dest, const VisVideo *src)
+{
+#ifdef VISUAL_ARCH_X86
+	uint32_t y;
+	uint32_t u, v, du, dv; /* fixed point 16.16 */
+	uint32_t *dest_pixel, *src_pixel_rowu, *src_pixel_rowl;
+
+	dest_pixel = dest->pixels;
+
+	du = ((src->width - 1)  << 16) / dest->width;
+	dv = ((src->height - 1) << 16) / dest->height;
+	v = 0;
+
+	__asm__ __volatile__ ("\n\temms");
+	
+	for (y = dest->height; y--; v += dv) {
+		uint32_t x;
+		uint32_t fracU, fracV;     /* fixed point 28.4 [0,1[    */
+
+		if (v >> 16 >= src->height - 1)
+			v -= 0x10000;
+
+		src_pixel_rowu = (src->pixel_rows[v >> 16]);
+		src_pixel_rowl = (src->pixel_rows[(v >> 16) + 1]);
+
+		/* fracV = frac(v) = v & 0xffff */
+		/* fixed point format convertion: fracV >>= 8) */
+		fracV = ((v & 0xffff) >> 12) | 0x100000;
+		u = 0;
+
+
+		for (x = dest->width - 1; x--; u += du) {
+
+			/* fracU = frac(u) = u & 0xffff */
+			/* fixed point format convertion: fracU >>= 8) */
+			fracU  = ((u & 0xffff) >> 12) | 0x100000;
+			
+			__asm__ __volatile__
+				("\n\t pxor %%mm7, %%mm7"
+				 /* Prefetching does not show improvement on my Duron (maybe due to its small cache?) */
+				 /*"\n\t prefetch  64%[pixel_l]" / * only work on 3now!/SSE cpu */
+				 /*"\n\t prefetchw 64%[output]"  / * only work on 3now!/SSE cpu */
+
+				 /* Computing coefs values (Thread #1 and #2) => ends on #C
+				  *
+				  * notice 0x10 = 1.0 (fixed point 28.4 - like fracU and fracV)
+				  *
+				  * coef[0] = (0x10 - fracU) * (0x10 - fracV); * UL=0 *
+				  * coef[1] = (0x10 - fracU) * fracV;          * LL=1 *
+				  * coef[2] = fracU * (0x10 - fracV);          * UR=2 *
+				  * coef[3] = fracU * fracV;                   * LR=3 *
+				  */
+
+				 /*
+				  * Unpacking colors (Thread #3 and #4)
+				  */
+				 /*
+				  * Multiplying colors by coefs (Threads #5 and #6)
+				  */
+				 /*
+				  * Adding colors together. (Thread #7)
+				  */
+
+				"#1\n\t movd %[fracu], %%mm4"   /* mm4 = [ 0 | 0 | 0x10 | fracU ] */
+				"#2\n\t movd %[fracv], %%mm6"   /* mm6 = [ 0 | 0 | 0x10 | fracV ] */
+
+				"#1\n\t punpcklwd %%mm4, %%mm4" /* mm4 = [ 0x10 | 0x10 | fracU | fracU ] */
+				"#2\n\t movq      %%mm6, %%mm3"
+
+				"#1\n\t pxor      %%mm5, %%mm5"
+				"#2\n\t punpckldq %%mm6, %%mm6" /* mm6 = [ 0x10 | fracv | 0x10 | fracV ] */ 
+				"#3\n\t movq %[pixel_u], %%mm0" /* mm0 = [ col[0] | col[2] ] */
+
+				"#1\n\t punpckldq %%mm4, %%mm5" /* mm5 = [ fracU | fracU | 0 | 0 ] */
+				"#2\n\t punpcklwd %%mm7, %%mm3" /* mm3 = [ 0    | 0x10  | 0    | fracV ] */
+				"#3\n\t movq      %%mm0, %%mm2"
+
+				"#1\n\t psubusw   %%mm5, %%mm4" /* mm4 = [ 0x10-fracU | 0x10-fracU | fracU | fracU ] */
+				"#2\n\t punpckldq %%mm3, %%mm3" /* mm3 = [ 0    | fracV | 0    | fracV ] */
+				"#4\n\t movq %[pixel_l], %%mm1" /* mm1 = [ col[1] | col[3] ] */
+
+				"#2\n\t pslld     $16,   %%mm3" /* mm3 = [ fracV | 0 | fracV | 0 ] */
+				"#3\n\t punpcklbw %%mm7, %%mm0" /* mm0 = [ col[0] unpacked ] */
+
+				"#2\n\t psubusw   %%mm3, %%mm6" /* mm6 = [ 0x10-fracV | fracV | 0x10-fracV | fracV ] */
+				"#4\n\t movq      %%mm1, %%mm3"
+
+				"#C\n\t pmullw    %%mm6, %%mm4" /* mm4 = [ coef[0]|coef[1]|coef[2]|coef[3] ] */
+				"#5\n\t movq      %%mm4, %%mm5"
+
+				"#4\n\t punpcklbw %%mm7, %%mm1" /* mm1 = [ col[1] unpacked ] */
+				"#6\n\t punpckhwd %%mm4, %%mm4" /* mm4 = [ coef[1]|coef[1]|coef[0]|coef[0] ] */
+
+				"#3\n\t punpckhbw %%mm7, %%mm2" /* mm2 = [ col[2] unpacked ] */
+				"#5\n\t punpcklwd %%mm5, %%mm5" /* mm5 = [ coef[2]|coef[2]|coef[3]|coef[3] ] */
+
+				"#4\n\t punpckhbw %%mm7, %%mm3" /* mm3 = [ col[3] unpacked ] */
+				"#5\n\t movq      %%mm5, %%mm6"
+
+				"#6\n\t movq      %%mm4, %%mm7"
+				"#5\n\t punpcklwd %%mm6, %%mm6" /* mm6 = [ coef[3]|coef[3]|coef[3]|coef[3] ] */
+
+				"#6\n\t punpcklwd %%mm7, %%mm7" /* mm6 = [ coef[1]|coef[1]|coef[1]|coef[1] ] */
+				"#5\n\t pmullw    %%mm6, %%mm3" /* mm3 = [ coef[3] * col[3] unpacked ] */
+
+				"#5\n\t punpckhwd %%mm5, %%mm5" /* mm5 = [ coef[2]|coef[2]|coef[2]|coef[2] ] */
+				"#6\n\t pmullw    %%mm7, %%mm1" /* mm1 = [ coef[1] * col[1] unpacked ] */
+
+				"#5\n\t pmullw    %%mm5, %%mm2" /* mm2 = [ coef[2] * col[2] unpacked ] */
+				"#6\n\t punpckhwd %%mm4, %%mm4" /* mm4 = [ coef[0]|coef[0]|coef[0]|coef[0] ] */
+
+				"#6\n\t pmullw    %%mm4, %%mm0" /* mm0 = [ coef[0] * col[0] unpacked ] */
+				"#7\n\t paddw     %%mm2, %%mm3"
+				"#7\n\t paddw     %%mm1, %%mm0"
+
+				"#7\n\t paddw     %%mm3, %%mm0"
+				"#7\n\t psrlw     $8,    %%mm0"
+
+				/* Unpacking the resulting pixel */
+				"\n\t packuswb  %%mm7, %%mm0"
+				"\n\t movd    %%mm0, %[output]"
+
+				: [output]  "=m"(*dest_pixel)
+				: [pixel_u] "m"(src_pixel_rowu[u>>16])
+				, [pixel_l] "m"(src_pixel_rowl[u>>16])
+				, [fracu]   "g"(fracU)
+				, [fracv]   "g"(fracV)
+				: "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7");
+			
+			++dest_pixel;
+		}
+
+		memset (dest_pixel, 0, (dest->pitch - ((dest->width - 1) * 4)));
+		dest_pixel += (dest->pitch / 4) - ((dest->width - 1));
+
+	}
+
+	__asm__ __volatile__ ("\n\temms");
+
+	return VISUAL_OK;
+#else /* !VISUAL_ARCH_X86 */
+	return VISUAL_ERROR_CPU_INVALID_CODE;
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvisual/lvconfig.h	Mon Oct 24 23:13:56 2005 -0700
@@ -0,0 +1,39 @@
+/* lvconfig.h
+ *
+ * This is a generated file.  Please modify 'configure.ac'
+ */
+
+#ifndef __LV_CONFIG_H__
+#define __LV_CONFIG_H__
+
+#ifndef __cplusplus
+# define LV_HAVE_ISO_VARARGS	(1)
+#endif
+
+/* gcc-2.95.x supports both gnu style and ISO varargs, but if -ansi
+ * is passed ISO vararg support is turned off, and there is no work
+ * around to turn it on, so we unconditionally turn it off.
+ */
+#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
+#  undef LV_HAVE_ISO_VARARGS
+#endif
+
+#define LV_HAVE_GNUC_VARARGS	(1)
+
+#define VISUAL_BIG_ENDIAN	(0)
+#define VISUAL_LITTLE_ENDIAN	(1)
+
+typedef unsigned int visual_size_t;
+#define VISUAL_SIZE_T_FORMAT	"u"
+
+#define VISUAL_ARCH_X86
+
+#define VISUAL_OS_LINUX
+
+#define VISUAL_HAVE_THREADS
+
+#define VISUAL_THREAD_MODEL_POSIX
+
+
+#endif /* LV_CONFIG_H */
+