Mercurial > audlegacy
changeset 23:0db4a1dc75c4 trunk
[svn] libvisual.
P3 detection appears to be borked. I'll work on it later.
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 (¶mcontainer->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 (¶m->pal); + + visual_list_destroy_elements (¶m->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 (¶mcontainer->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 (¶mcontainer->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 (¶ms[i])); + visual_param_entry_set_from_param (pnew, ¶ms[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 (¶mcontainer->entries, &le)) != NULL) { + + if (strcmp (param->name, name) == 0) { + visual_list_delete (¶mcontainer->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 (¶mcontainer->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 (¶m->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 (¶m->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 (¶m->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 (¶m->callbacks, &le)) != NULL) { + + if (id == pcall->id) { + visual_list_delete (¶m->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 (¶m->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 (¶m->color, color) == FALSE) { + visual_color_copy (¶m->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 (¶m->pal); + + if (pal != NULL) { + visual_palette_allocate_colors (¶m->pal, pal->ncolors); + + visual_palette_copy (¶m->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 ¶m->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 ¶m->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, ¶mchoices[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 */ +