summaryrefslogtreecommitdiff
path: root/Source/DirectFB/lib/voodoo
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/lib/voodoo')
-rwxr-xr-xSource/DirectFB/lib/voodoo/Makefile.am82
-rwxr-xr-xSource/DirectFB/lib/voodoo/Makefile.in666
-rwxr-xr-xSource/DirectFB/lib/voodoo/app.h66
-rwxr-xr-xSource/DirectFB/lib/voodoo/build.h.in34
-rwxr-xr-xSource/DirectFB/lib/voodoo/client.c208
-rwxr-xr-xSource/DirectFB/lib/voodoo/client.h44
-rwxr-xr-xSource/DirectFB/lib/voodoo/compat.h8
-rwxr-xr-xSource/DirectFB/lib/voodoo/conf.c253
-rwxr-xr-xSource/DirectFB/lib/voodoo/conf.h58
-rwxr-xr-xSource/DirectFB/lib/voodoo/connection.cpp70
-rwxr-xr-xSource/DirectFB/lib/voodoo/connection.h60
-rwxr-xr-xSource/DirectFB/lib/voodoo/connection_link.cpp331
-rwxr-xr-xSource/DirectFB/lib/voodoo/connection_link.h106
-rwxr-xr-xSource/DirectFB/lib/voodoo/connection_packet.cpp368
-rwxr-xr-xSource/DirectFB/lib/voodoo/connection_packet.h61
-rwxr-xr-xSource/DirectFB/lib/voodoo/connection_packet_old.cpp433
-rwxr-xr-xSource/DirectFB/lib/voodoo/connection_packet_old.h87
-rwxr-xr-xSource/DirectFB/lib/voodoo/connection_raw.cpp341
-rwxr-xr-xSource/DirectFB/lib/voodoo/connection_raw.h60
-rwxr-xr-xSource/DirectFB/lib/voodoo/dispatcher.cpp231
-rwxr-xr-xSource/DirectFB/lib/voodoo/dispatcher.h71
-rwxr-xr-xSource/DirectFB/lib/voodoo/instance.cpp107
-rwxr-xr-xSource/DirectFB/lib/voodoo/instance.h61
-rwxr-xr-xSource/DirectFB/lib/voodoo/interface.c114
-rwxr-xr-xSource/DirectFB/lib/voodoo/interface.h52
-rwxr-xr-xSource/DirectFB/lib/voodoo/internal.h40
-rwxr-xr-xSource/DirectFB/lib/voodoo/ivoodooplayer.c247
-rwxr-xr-xSource/DirectFB/lib/voodoo/ivoodooplayer.h74
-rwxr-xr-xSource/DirectFB/lib/voodoo/ivoodooplayer_dispatcher.c359
-rwxr-xr-xSource/DirectFB/lib/voodoo/ivoodooplayer_dispatcher.h41
-rwxr-xr-xSource/DirectFB/lib/voodoo/ivoodooplayer_requestor.c330
-rwxr-xr-xSource/DirectFB/lib/voodoo/link.h78
-rwxr-xr-xSource/DirectFB/lib/voodoo/manager.cpp937
-rwxr-xr-xSource/DirectFB/lib/voodoo/manager.h279
-rwxr-xr-xSource/DirectFB/lib/voodoo/manager_c.cpp553
-rwxr-xr-xSource/DirectFB/lib/voodoo/message.h258
-rwxr-xr-xSource/DirectFB/lib/voodoo/mutex.c105
-rwxr-xr-xSource/DirectFB/lib/voodoo/mutex.h142
-rwxr-xr-xSource/DirectFB/lib/voodoo/packet.h285
-rwxr-xr-xSource/DirectFB/lib/voodoo/play.c935
-rwxr-xr-xSource/DirectFB/lib/voodoo/play.h146
-rwxr-xr-xSource/DirectFB/lib/voodoo/play_internal.h89
-rwxr-xr-xSource/DirectFB/lib/voodoo/play_server.c430
-rwxr-xr-xSource/DirectFB/lib/voodoo/play_server.h79
-rwxr-xr-xSource/DirectFB/lib/voodoo/server.c459
-rwxr-xr-xSource/DirectFB/lib/voodoo/server.h52
-rwxr-xr-xSource/DirectFB/lib/voodoo/types.h97
-rwxr-xr-xSource/DirectFB/lib/voodoo/unix/interfaces_unix.c237
-rwxr-xr-xSource/DirectFB/lib/voodoo/unix/link_unix.c567
-rwxr-xr-xSource/DirectFB/lib/voodoo/unix/link_unix_1408limit.c422
-rwxr-xr-xSource/DirectFB/lib/voodoo/voodoo.pc.in11
-rwxr-xr-xSource/DirectFB/lib/voodoo/waitqueue.h117
52 files changed, 11341 insertions, 0 deletions
diff --git a/Source/DirectFB/lib/voodoo/Makefile.am b/Source/DirectFB/lib/voodoo/Makefile.am
new file mode 100755
index 0000000..bf3c143
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/Makefile.am
@@ -0,0 +1,82 @@
+## Makefile.am for DirectFB/lib/voodoo
+
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib
+
+AM_CPPFLAGS = \
+ -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" \
+ -DMODULEDIR=\"${RUNTIME_SYSROOT}@MODULEDIR@\"
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = voodoo.pc
+
+
+# If the old location isn't cleared, builds of external modules fail
+install-exec-local:
+ rm -rf $(DESTDIR)$(INTERNALINCLUDEDIR)/voodoo
+
+
+includedir = @INCLUDEDIR@/voodoo
+
+include_HEADERS = \
+ build.h \
+ client.h \
+ conf.h \
+ interface.h \
+ manager.h \
+ message.h \
+ server.h \
+ play.h \
+ types.h
+
+
+lib_LTLIBRARIES = libvoodoo.la
+
+libvoodoo_la_SOURCES = \
+ client.c \
+ conf.c \
+ interface.c \
+ internal.h \
+ manager.c \
+ play.c \
+ server.c
+
+libvoodoo_la_LDFLAGS = \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -release $(LT_RELEASE) \
+ $(DFB_LDFLAGS)
+
+libvoodoo_la_LIBADD = ../direct/libdirect.la
+
+
+#
+## and now rebuild the static version with the *correct* object files
+#
+if BUILD_STATIC
+
+clean-local:
+ rm -f libvoodoo_fixed.a
+
+all-local: libvoodoo_fixed.a
+
+libvoodoo_fixed.a: .libs/libvoodoo.a
+ rm -f libvoodoo_fixed.a
+ ${AR} cru libvoodoo_fixed.a `find . -name "*.o"`
+ ${RANLIB} libvoodoo_fixed.a
+ cp -pf libvoodoo_fixed.a .libs/libvoodoo.a
+
+.libs/libvoodoo.a: libvoodoo.la
+
+else
+
+clean-local:
+
+all-local:
+
+endif
+
+
+include $(top_srcdir)/rules/nmfile.make
diff --git a/Source/DirectFB/lib/voodoo/Makefile.in b/Source/DirectFB/lib/voodoo/Makefile.in
new file mode 100755
index 0000000..4a4a5a2
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/Makefile.in
@@ -0,0 +1,666 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 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@
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+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@
+DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/build.h.in \
+ $(srcdir)/voodoo.pc.in $(top_srcdir)/rules/nmfile.make
+subdir = lib/voodoo
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = build.h voodoo.pc
+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)$(pkgconfigdir)" \
+ "$(DESTDIR)$(includedir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libvoodoo_la_DEPENDENCIES = ../direct/libdirect.la
+am_libvoodoo_la_OBJECTS = client.lo conf.lo interface.lo play.lo manager.lo \
+ server.lo
+libvoodoo_la_OBJECTS = $(am_libvoodoo_la_OBJECTS)
+libvoodoo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libvoodoo_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libvoodoo_la_SOURCES)
+DIST_SOURCES = $(libvoodoo_la_SOURCES)
+pkgconfigDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(pkgconfig_DATA)
+includeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(include_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+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@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @INCLUDEDIR@/voodoo
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib
+
+AM_CPPFLAGS = \
+ -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" \
+ -DMODULEDIR=\"${RUNTIME_SYSROOT}@MODULEDIR@\"
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = voodoo.pc
+include_HEADERS = \
+ build.h \
+ client.h \
+ conf.h \
+ interface.h \
+ manager.h \
+ message.h \
+ server.h \
+ play.h \
+ types.h
+
+lib_LTLIBRARIES = libvoodoo.la
+libvoodoo_la_SOURCES = \
+ client.c \
+ conf.c \
+ interface.c \
+ internal.h \
+ manager.c \
+ play.c \
+ server.c
+
+libvoodoo_la_LDFLAGS = \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -release $(LT_RELEASE) \
+ $(DFB_LDFLAGS)
+
+libvoodoo_la_LIBADD = ../direct/libdirect.la
+@BUILD_SHARED_TRUE@@ENABLE_TRACE_TRUE@LIBTONM = $(LTLIBRARIES:.la=-$(LT_RELEASE).so.$(LT_BINARY))
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/rules/nmfile.make $(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 lib/voodoo/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu lib/voodoo/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: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+build.h: $(top_builddir)/config.status $(srcdir)/build.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+voodoo.pc: $(top_builddir)/config.status $(srcdir)/voodoo.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+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) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --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
+libvoodoo.la: $(libvoodoo_la_OBJECTS) $(libvoodoo_la_DEPENDENCIES)
+ $(libvoodoo_la_LINK) -rpath $(libdir) $(libvoodoo_la_OBJECTS) $(libvoodoo_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/play.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@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@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@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@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@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
+install-pkgconfigDATA: $(pkgconfig_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
+ @list='$(pkgconfig_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(pkgconfigDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
+ $(pkgconfigDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgconfigdir)/$$f"; \
+ done
+
+uninstall-pkgconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfig_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pkgconfigdir)/$$f"; \
+ done
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
+ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(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; nonemtpy = 1; } \
+ END { if (nonempty) { 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; nonempty = 1; } \
+ END { if (nonempty) { 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=; \
+ 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; nonempty = 1; } \
+ END { if (nonempty) { 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)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ 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) $(DATA) $(HEADERS) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(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."
+@BUILD_SHARED_FALSE@install-data-local:
+@ENABLE_TRACE_FALSE@install-data-local:
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-includeHEADERS \
+ install-pkgconfigDATA
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-exec-local install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+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-includeHEADERS uninstall-libLTLIBRARIES \
+ uninstall-pkgconfigDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \
+ clean-generic clean-libLTLIBRARIES clean-libtool clean-local \
+ 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-data-local install-dvi install-dvi-am \
+ install-exec install-exec-am install-exec-local install-html \
+ install-html-am install-includeHEADERS install-info \
+ install-info-am install-libLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
+ 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-includeHEADERS uninstall-libLTLIBRARIES \
+ uninstall-pkgconfigDATA
+
+
+# If the old location isn't cleared, builds of external modules fail
+install-exec-local:
+ rm -rf $(DESTDIR)$(INTERNALINCLUDEDIR)/voodoo
+
+#
+#
+
+@BUILD_STATIC_TRUE@clean-local:
+@BUILD_STATIC_TRUE@ rm -f libvoodoo_fixed.a
+
+@BUILD_STATIC_TRUE@all-local: libvoodoo_fixed.a
+
+@BUILD_STATIC_TRUE@libvoodoo_fixed.a: .libs/libvoodoo.a
+@BUILD_STATIC_TRUE@ rm -f libvoodoo_fixed.a
+@BUILD_STATIC_TRUE@ ${AR} cru libvoodoo_fixed.a `find . -name "*.o"`
+@BUILD_STATIC_TRUE@ ${RANLIB} libvoodoo_fixed.a
+@BUILD_STATIC_TRUE@ cp -pf libvoodoo_fixed.a .libs/libvoodoo.a
+
+@BUILD_STATIC_TRUE@.libs/libvoodoo.a: libvoodoo.la
+
+@BUILD_STATIC_FALSE@clean-local:
+
+@BUILD_STATIC_FALSE@all-local:
+
+@BUILD_SHARED_TRUE@@ENABLE_TRACE_TRUE@install-data-local:
+@BUILD_SHARED_TRUE@@ENABLE_TRACE_TRUE@ mkdir -p -- "$(DESTDIR)$(libdir)"
+@BUILD_SHARED_TRUE@@ENABLE_TRACE_TRUE@ nm -n ".libs/$(LIBTONM)" > "$(DESTDIR)$(libdir)/nm-n.$(LIBTONM)"
+# 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:
diff --git a/Source/DirectFB/lib/voodoo/app.h b/Source/DirectFB/lib/voodoo/app.h
new file mode 100755
index 0000000..163edc6
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/app.h
@@ -0,0 +1,66 @@
+/*
+ (c) Copyright 2001-2010 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__APP_H__
+#define __VOODOO__APP_H__
+
+#include <voodoo/types.h>
+
+
+
+typedef enum {
+ VADESC_NONE = 0x00000000,
+
+ VADESC_NAME = 0x00000001,
+ VADESC_TEXT = 0x00000002,
+
+ VADESC_ALL = 0x00000003,
+} VoodooAppDescriptionFlags;
+
+
+#define VOODOO_APP_DESCRIPTION_NAME_LENGTH 128
+#define VOODOO_APP_DESCRIPTION_TEXT_LENGTH 1024
+
+typedef struct {
+ u8 uuid[16];
+ VoodooAppDescriptionFlags flags;
+
+ char name[VOODOO_APP_DESCRIPTION_NAME_LENGTH];
+ char text[VOODOO_APP_DESCRIPTION_TEXT_LENGTH];
+} VoodooAppDescription;
+
+typedef struct {
+ u8 uuid[16];
+
+ VoodooAppDescription app;
+ u8 player_uuid[16];
+} VoodooAppInstanceDescription;
+
+
+#endif
+
diff --git a/Source/DirectFB/lib/voodoo/build.h.in b/Source/DirectFB/lib/voodoo/build.h.in
new file mode 100755
index 0000000..c5553e2
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/build.h.in
@@ -0,0 +1,34 @@
+/*
+ (c) Copyright 2000-2002 convergence integrated media GmbH.
+ (c) Copyright 2002-2004 convergence GmbH.
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org> and
+ Ville Syrjälä <syrjala@sci.fi>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__BUILD_H__
+#define __VOODOO__BUILD_H__
+
+/* nothing yet */
+
+#endif
+
diff --git a/Source/DirectFB/lib/voodoo/client.c b/Source/DirectFB/lib/voodoo/client.c
new file mode 100755
index 0000000..66844e2
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/client.c
@@ -0,0 +1,208 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <voodoo/client.h>
+#include <voodoo/conf.h>
+#include <voodoo/internal.h>
+#include <voodoo/link.h>
+#include <voodoo/manager.h>
+#include <voodoo/play.h>
+
+/**********************************************************************************************************************/
+
+struct __V_VoodooClient {
+ DirectLink link;
+
+ int refs;
+
+ VoodooLink vl;
+ VoodooManager *manager;
+
+ char *host;
+ int port;
+};
+
+static DirectLink *m_clients; // FIXME: add lock
+
+/**********************************************************************************************************************/
+
+DirectResult
+voodoo_client_create( const char *host,
+ int port,
+ VoodooClient **ret_client )
+{
+ DirectResult ret;
+ VoodooClient *client;
+ VoodooPlayer *player;
+ int bc_num = 10;
+ int bc_wait = 4000;
+ char buf[100] = { 0 };
+ const char *hostname = host;
+ bool raw = true;
+
+ D_ASSERT( ret_client != NULL );
+
+ if (!port)
+ port = 2323;
+
+ direct_list_foreach (client, m_clients) {
+ if (!strcmp( client->host, host ) && client->port == port) {
+ D_INFO( "Voodoo/Client: Reconnecting to '%s', increasing ref count of existing connection!\n", host );
+
+ client->refs++;
+
+ *ret_client = client;
+
+ return DR_OK;
+ }
+ }
+
+
+ ret = voodoo_player_create( NULL, &player );
+ if (ret) {
+ D_DERROR( ret, "Voodoo/Client: Could not create the player!\n" );
+ return ret;
+ }
+
+ while (bc_num--) {
+ VoodooPlayInfo info;
+
+ // FIXME: resolve first, not late in voodoo_link_init_connect
+ if (hostname && hostname[0]) {
+ ret = voodoo_player_lookup_by_address( player, hostname, &info );
+ if (ret == DR_OK) {
+ if (info.flags & VPIF_LINK)
+ raw = false;
+
+ break;
+ }
+ }
+ else {
+ ret = voodoo_player_lookup( player, NULL, &info, buf, sizeof(buf) );
+ if (ret == DR_OK) {
+ if (info.flags & VPIF_LINK)
+ raw = false;
+
+ hostname = buf;
+
+ break;
+ }
+ }
+
+ voodoo_player_broadcast( player );
+
+ direct_thread_sleep( bc_wait );
+
+ bc_wait += bc_wait;
+ }
+
+ voodoo_player_destroy( player );
+
+ if (!hostname || !hostname[0]) {
+ D_ERROR( "Voodoo/Play: Did not find any other player!\n" );
+ return DR_ITEMNOTFOUND;
+ }
+
+
+ /* Allocate client structure. */
+ client = D_CALLOC( 1, sizeof(VoodooClient) );
+ if (!client)
+ return D_OOM();
+
+
+ /* Initialize client structure. */
+ ret = voodoo_link_init_connect( &client->vl, hostname, port,
+ !voodoo_config->link_packet && (voodoo_config->link_raw || raw) );
+ if (ret) {
+ D_DERROR( ret, "Voodoo/Client: Failed to initialize Voodoo Link!\n" );
+ D_FREE( client );
+ return ret;
+ }
+
+ /* Create the manager. */
+ ret = voodoo_manager_create( &client->vl, client, NULL, &client->manager );
+ if (ret) {
+ client->vl.Close( &client->vl );
+ D_FREE( client );
+ return ret;
+ }
+
+ client->refs = 1;
+ client->host = D_STRDUP( host );
+ client->port = port;
+
+ direct_list_prepend( &m_clients, &client->link );
+
+ /* Return the new client. */
+ *ret_client = client;
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_client_destroy( VoodooClient *client )
+{
+ D_ASSERT( client != NULL );
+
+ D_INFO( "Voodoo/Client: Decreasing ref count of connection...\n" );
+
+ if (! --(client->refs)) {
+ voodoo_manager_destroy( client->manager );
+
+ //client->vl.Close( &client->vl );
+
+ direct_list_remove( &m_clients, &client->link );
+
+ D_FREE( client->host );
+ D_FREE( client );
+ }
+
+ return DR_OK;
+}
+
+VoodooManager *
+voodoo_client_manager( const VoodooClient *client )
+{
+ D_ASSERT( client != NULL );
+
+ return client->manager;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/client.h b/Source/DirectFB/lib/voodoo/client.h
new file mode 100755
index 0000000..5905ef8
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/client.h
@@ -0,0 +1,44 @@
+/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__CLIENT_H__
+#define __VOODOO__CLIENT_H__
+
+#include <voodoo/types.h>
+
+
+DirectResult voodoo_client_create ( const char *host,
+ int session,
+ VoodooClient **ret_client );
+
+DirectResult voodoo_client_destroy( VoodooClient *client );
+
+
+VoodooManager *voodoo_client_manager( const VoodooClient *client );
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/compat.h b/Source/DirectFB/lib/voodoo/compat.h
new file mode 100755
index 0000000..e7b5a75
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/compat.h
@@ -0,0 +1,8 @@
+#include "mutex.h"
+#include "waitqueue.h"
+
+#define direct_thread_sleep usleep
+#define direct_snprintf snprintf
+#define direct_sscanf sscanf
+#define direct_getpid getpid
+
diff --git a/Source/DirectFB/lib/voodoo/conf.c b/Source/DirectFB/lib/voodoo/conf.c
new file mode 100755
index 0000000..456643d
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/conf.c
@@ -0,0 +1,253 @@
+/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <string.h>
+
+#include <direct/conf.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <voodoo/conf.h>
+
+
+static VoodooConfig config = {
+ .compression_min = 1
+};
+
+VoodooConfig *voodoo_config = &config;
+const char *voodoo_config_usage =
+ "libvoodoo options:\n"
+ " player-name=<name> Set player name\n"
+ " player-vendor=<name> Set player vendor\n"
+ " player-model=<name> Set player model\n"
+ " player-uuid=<name> Set player uuid\n"
+ " proxy-memory-max=<kB> Set maximum amount of memory per connection\n"
+ " proxy-surface-max=<kB> Set maximum amount of memory per surface\n"
+ " [no-]server-fork Fork a new process for each connection (default: no)\n"
+ " server-single=<interface> Enable single client mode for super interface, e.g. IDirectFB\n"
+ " compression-min=<bytes> Enable compression (if != 0) for packets with at least num bytes\n"
+ " [no-]link-raw Set link mode to 'raw'\n"
+ " [no-]link-packet Set link mode to 'packet'\n"
+ "\n";
+
+/**********************************************************************************************************************/
+
+DirectResult
+voodoo_config_set( const char *name, const char *value )
+{
+ if (strcmp (name, "player-name" ) == 0) {
+ if (value) {
+ direct_snputs( voodoo_config->play_info.name, value, VOODOO_PLAYER_NAME_LENGTH );
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "player-vendor" ) == 0) {
+ if (value) {
+ direct_snputs( voodoo_config->play_info.vendor, value, VOODOO_PLAYER_VENDOR_LENGTH );
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "player-model" ) == 0) {
+ if (value) {
+ direct_snputs( voodoo_config->play_info.model, value, VOODOO_PLAYER_MODEL_LENGTH );
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "player-uuid" ) == 0) {
+ if (value) {
+ sscanf( value, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ (unsigned int*)&voodoo_config->play_info.uuid[0], (unsigned int*)&voodoo_config->play_info.uuid[1], (unsigned int*)&voodoo_config->play_info.uuid[2], (unsigned int*)&voodoo_config->play_info.uuid[3], (unsigned int*)&voodoo_config->play_info.uuid[4],
+ (unsigned int*)&voodoo_config->play_info.uuid[5], (unsigned int*)&voodoo_config->play_info.uuid[6], (unsigned int*)&voodoo_config->play_info.uuid[7], (unsigned int*)&voodoo_config->play_info.uuid[8], (unsigned int*)&voodoo_config->play_info.uuid[9],
+ (unsigned int*)&voodoo_config->play_info.uuid[10], (unsigned int*)&voodoo_config->play_info.uuid[11], (unsigned int*)&voodoo_config->play_info.uuid[12], (unsigned int*)&voodoo_config->play_info.uuid[13], (unsigned int*)&voodoo_config->play_info.uuid[14],
+ (unsigned int*)&voodoo_config->play_info.uuid[15] );
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "proxy-memory-max" ) == 0) {
+ if (value) {
+ unsigned int max;
+
+ if (sscanf( value, "%u", &max ) != 1) {
+ D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
+ return DR_INVARG;
+ }
+
+ voodoo_config->memory_max = max * 1024;
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "proxy-surface-max" ) == 0) {
+ if (value) {
+ unsigned int max;
+
+ if (sscanf( value, "%u", &max ) != 1) {
+ D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
+ return DR_INVARG;
+ }
+
+ voodoo_config->surface_max = max * 1024;
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "proxy-layer-mask" ) == 0) {
+ if (value) {
+ unsigned int mask;
+
+ if (sscanf( value, "%u", &mask ) != 1) {
+ D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
+ return DR_INVARG;
+ }
+
+ voodoo_config->layer_mask = mask;
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "proxy-stacking-mask" ) == 0) {
+ if (value) {
+ unsigned int mask;
+
+ if (sscanf( value, "%u", &mask ) != 1) {
+ D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
+ return DR_INVARG;
+ }
+
+ voodoo_config->stacking_mask = mask;
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "proxy-resource-id" ) == 0) {
+ if (value) {
+ unsigned int resource_id;
+
+ if (sscanf( value, "%u", &resource_id ) != 1) {
+ D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
+ return DR_INVARG;
+ }
+
+ voodoo_config->resource_id = resource_id;
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "server-fork" ) == 0) {
+ voodoo_config->server_fork = true;
+ } else
+ if (strcmp (name, "no-server-fork" ) == 0) {
+ voodoo_config->server_fork = false;
+ } else
+ if (strcmp (name, "server-single" ) == 0) {
+ if (value) {
+ if (voodoo_config->server_single)
+ D_FREE( voodoo_config->server_single );
+
+ voodoo_config->server_single = D_STRDUP( value );
+ if (!voodoo_config->server_single)
+ D_OOM();
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "play-broadcast" ) == 0) {
+ if (value) {
+ if (voodoo_config->play_broadcast)
+ D_FREE( voodoo_config->play_broadcast );
+
+ voodoo_config->play_broadcast = D_STRDUP( value );
+ if (!voodoo_config->play_broadcast)
+ D_OOM();
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "compression-min" ) == 0) {
+ if (value) {
+ unsigned int min;
+
+ if (sscanf( value, "%u", &min ) != 1) {
+ D_ERROR( "Voodoo/Config '%s': Invalid value specified!\n", name );
+ return DR_INVARG;
+ }
+
+ voodoo_config->compression_min = min;
+ }
+ else {
+ D_ERROR( "Voodoo/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "link-raw" ) == 0) {
+ voodoo_config->link_raw = true;
+ } else
+ if (strcmp (name, "no-link-raw" ) == 0) {
+ voodoo_config->link_raw = false;
+ } else
+ if (strcmp (name, "link-packet" ) == 0) {
+ voodoo_config->link_packet = true;
+ } else
+ if (strcmp (name, "no-link-packet" ) == 0) {
+ voodoo_config->link_packet = false;
+ } else
+ if (direct_config_set( name, value ))
+ return DR_UNSUPPORTED;
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/conf.h b/Source/DirectFB/lib/voodoo/conf.h
new file mode 100755
index 0000000..57dac9a
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/conf.h
@@ -0,0 +1,58 @@
+/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__CONF_H__
+#define __VOODOO__CONF_H__
+
+#include <voodoo/play.h>
+
+
+struct __V_VoodooConfig {
+ VoodooPlayInfo play_info;
+ bool forward_nodes;
+ unsigned int memory_max;
+ unsigned int surface_max;
+ unsigned int layer_mask;
+ unsigned int stacking_mask;
+ unsigned int resource_id;
+ bool server_fork;
+ char *server_single;
+ char *play_broadcast;
+ unsigned int compression_min;
+ bool link_raw;
+ bool link_packet;
+};
+
+extern VoodooConfig *voodoo_config;
+
+
+DirectResult voodoo_config_set( const char *name, const char *value );
+
+
+#endif
+
diff --git a/Source/DirectFB/lib/voodoo/connection.cpp b/Source/DirectFB/lib/voodoo/connection.cpp
new file mode 100755
index 0000000..3bde3e1
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/connection.cpp
@@ -0,0 +1,70 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+extern "C" {
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <voodoo/link.h>
+}
+
+#include <voodoo/connection.h>
+
+
+D_DEBUG_DOMAIN( Voodoo_Connection, "Voodoo/Connection", "Voodoo Connection" );
+
+/**********************************************************************************************************************/
+
+VoodooConnection::VoodooConnection( VoodooManager *manager,
+ VoodooLink *link )
+ :
+ magic(0),
+ manager(manager),
+ link(link)
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnection::%s( %p )\n", __func__, this );
+
+ D_MAGIC_SET( this, VoodooConnection );
+}
+
+VoodooConnection::~VoodooConnection()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnection::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ link->Close( link );
+
+ D_MAGIC_CLEAR( this );
+}
+
diff --git a/Source/DirectFB/lib/voodoo/connection.h b/Source/DirectFB/lib/voodoo/connection.h
new file mode 100755
index 0000000..0e6521b
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/connection.h
@@ -0,0 +1,60 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__CONNECTION_H__
+#define __VOODOO__CONNECTION_H__
+
+extern "C" {
+#include <voodoo/types.h>
+}
+
+
+class VoodooConnection {
+protected:
+ int magic;
+
+ VoodooManager *manager;
+ VoodooLink *link;
+
+public:
+ VoodooConnection( VoodooManager *manager,
+ VoodooLink *link );
+
+ virtual ~VoodooConnection();
+
+ virtual void Start() = 0;
+ virtual void Stop() = 0;
+
+
+ virtual VoodooPacket *GetPacket( size_t length ) = 0;
+ virtual void PutPacket( VoodooPacket *packet,
+ bool flush ) = 0;
+};
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/connection_link.cpp b/Source/DirectFB/lib/voodoo/connection_link.cpp
new file mode 100755
index 0000000..b0ae138
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/connection_link.cpp
@@ -0,0 +1,331 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+
+extern "C" {
+#include <direct/clock.h>
+#include <direct/debug.h>
+#include <direct/fastlz.h>
+#include <direct/hash.h>
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <voodoo/conf.h>
+#include <voodoo/internal.h>
+#include <voodoo/link.h>
+}
+
+#include <voodoo/connection_link.h>
+#include <voodoo/manager.h>
+#include <voodoo/packet.h>
+
+
+#include <vector>
+
+
+//namespace Voodoo {
+
+D_DEBUG_DOMAIN( Voodoo_Connection, "Voodoo/Connection", "Voodoo Connection" );
+D_DEBUG_DOMAIN( Voodoo_Input, "Voodoo/Input", "Voodoo Input" );
+D_DEBUG_DOMAIN( Voodoo_Output, "Voodoo/Output", "Voodoo Output" );
+
+/**********************************************************************************************************************/
+
+VoodooConnectionLink::VoodooConnectionLink( VoodooManager *manager,
+ VoodooLink *link )
+ :
+ VoodooConnection( manager, link )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p )\n", __func__, this );
+
+ input.start = 0;
+ input.last = 0;
+ input.end = 0;
+ input.max = 0;
+
+ output.packets = NULL;
+ output.sending = NULL;
+
+ /* Initialize all locks. */
+ direct_mutex_init( &output.lock );
+
+ /* Initialize all wait conditions. */
+ direct_waitqueue_init( &output.wait );
+
+ /* Set default buffer limit. */
+ input.max = VOODOO_CONNECTION_LINK_INPUT_BUF_MAX;
+
+ /* Allocate buffers. */
+ size_t input_buffer_size = VOODOO_CONNECTION_LINK_INPUT_BUF_MAX + VOODOO_PACKET_MAX + sizeof(VoodooPacketHeader);
+
+ input.buffer = (u8*) D_MALLOC( input_buffer_size );
+
+ D_INFO( "VoodooConnection/Link: Allocated "_ZU" kB input buffer at %p\n", input_buffer_size/1024, input.buffer );
+
+ direct_tls_register( &output.tls, OutputTLS_Destructor );
+}
+
+VoodooConnectionLink::~VoodooConnectionLink()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ /* Acquire locks and wake up waiters. */
+ direct_mutex_lock( &output.lock );
+ direct_waitqueue_broadcast( &output.wait );
+ direct_mutex_unlock( &output.lock );
+
+ /* Destroy conditions. */
+ direct_waitqueue_deinit( &output.wait );
+
+ /* Destroy locks. */
+ direct_mutex_deinit( &output.lock );
+
+ /* Deallocate buffers. */
+ D_FREE( input.buffer );
+
+ direct_tls_unregister( &output.tls );
+}
+
+/**********************************************************************************************************************/
+
+VoodooPacket *
+VoodooConnectionLink::GetPacket( size_t length )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p, length "_ZU" )\n", __func__, this, length );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+ D_ASSERT( length >= (int) sizeof(VoodooMessageHeader) );
+ D_ASSUME( length <= MAX_MSG_SIZE );
+
+ if (length > MAX_MSG_SIZE) {
+ D_WARN( _ZU" exceeds maximum message size of %d", length, MAX_MSG_SIZE );
+ return NULL;
+ }
+
+ size_t aligned = VOODOO_MSG_ALIGN( length );
+
+
+ Packets *packets = (Packets*) direct_tls_get( output.tls );
+
+ if (!packets) {
+ packets = new Packets( this );
+
+ direct_tls_set( output.tls, packets );
+ }
+
+ VoodooPacket *packet = packets->active;
+
+ if (packet) {
+ if (packet->append( aligned ))
+ return packet;
+
+ Flush( packet );
+ }
+
+ packet = packets->Get();
+ if (packet) {
+ if (packet->sending) {
+ direct_mutex_lock( &output.lock );
+
+ while (packet->sending)
+ direct_waitqueue_wait( &output.wait, &output.lock );
+
+ direct_mutex_unlock( &output.lock );
+ }
+ packet->reset( aligned );
+ }
+
+ return packet;
+}
+
+void
+VoodooConnectionLink::PutPacket( VoodooPacket *packet, bool flush )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p, %sflush )\n", __func__, this, flush ? "" : "NO " );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ Packets *packets = (Packets*) direct_tls_get( output.tls );
+
+ D_ASSERT( packets != NULL );
+ D_ASSERT( packet == packets->active );
+
+ if (flush) {
+ Flush( packet );
+
+ packets->active = NULL;
+ }
+}
+
+void
+VoodooConnectionLink::Stop()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ direct_mutex_lock( &output.lock );
+
+ while (output.packets) {
+ VoodooPacket *packet = (VoodooPacket*) output.packets;
+
+ D_DEBUG_AT( Voodoo_Connection, " -> discarding output packet %p\n", packet );
+
+ D_ASSUME( packet->sending );
+
+ packet->sending = false;
+
+ direct_list_remove( &output.packets, &packet->link );
+ }
+
+ direct_mutex_unlock( &output.lock );
+
+ direct_waitqueue_broadcast( &output.wait );
+}
+
+void
+VoodooConnectionLink::Flush( VoodooPacket *packet )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p, packet %p )\n", __func__, this, packet );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ direct_mutex_lock( &output.lock );
+
+ D_ASSERT( !direct_list_contains_element_EXPENSIVE( output.packets, &packet->link ) );
+
+ D_ASSERT( !packet->sending );
+
+ packet->sending = true;
+
+ direct_list_append( &output.packets, &packet->link );
+
+ direct_mutex_unlock( &output.lock );
+
+ link->WakeUp( link );
+}
+
+void
+VoodooConnectionLink::OutputTLS_Destructor( void *ptr )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( ptr %p )\n", __func__, ptr );
+
+ Packets *packets = (Packets*) ptr;
+
+ delete packets;
+
+ D_DEBUG_AT( Voodoo_Connection, " -> OutputTLS_Destructor done\n" );
+}
+
+VoodooConnectionLink::Packets::Packets( VoodooConnectionLink* connection )
+ :
+ magic(0),
+ connection(connection),
+ next(0),
+ num(0),
+ active(NULL)
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::Packets::%s( %p )\n", __func__, this );
+
+ memset( packets, 0, sizeof(packets) );
+
+ D_MAGIC_SET( this, Packets );
+}
+
+VoodooConnectionLink::Packets::~Packets()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::Packets::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, Packets );
+
+ for (size_t i=0; i<num; i++) {
+ if (packets[i]) {
+ D_DEBUG_AT( Voodoo_Connection, " -> destroying output packet "_ZU" (%p)\n", i, packets[i] );
+
+ if (packets[i]->sending) {
+ direct_mutex_lock( &connection->output.lock );
+
+ while (packets[i]->sending) {
+ D_DEBUG_AT( Voodoo_Connection, " -> packet sending, waiting...\n" );
+
+ direct_waitqueue_wait( &connection->output.wait, &connection->output.lock );
+ }
+
+ direct_mutex_unlock( &connection->output.lock );
+ }
+
+ D_FREE( packets[i] );
+ }
+ }
+}
+
+VoodooPacket *
+VoodooConnectionLink::Packets::Get()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::Packets::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, Packets );
+
+ VoodooPacket *packet;
+
+ if (num < VOODOO_CONNECTION_PACKET_NUM_OUTPUT) {
+ packet = packets[num] = VoodooPacket::New( 0 );
+
+ D_DEBUG_AT( Voodoo_Connection, " -> new ["_ZU"] %p\n", num, packet );
+
+ num++;
+ }
+ else {
+ packet = packets[next];
+
+ next = (next+1) % VOODOO_CONNECTION_PACKET_NUM_OUTPUT;
+
+ D_DEBUG_AT( Voodoo_Connection, " -> reusing %p\n", packet );
+ }
+
+ active = packet;
+
+ return packet;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/connection_link.h b/Source/DirectFB/lib/voodoo/connection_link.h
new file mode 100755
index 0000000..328151c
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/connection_link.h
@@ -0,0 +1,106 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__CONNECTION_LINK_H__
+#define __VOODOO__CONNECTION_LINK_H__
+
+#include <voodoo/connection.h>
+
+extern "C" {
+#include <direct/thread.h>
+}
+
+#define VOODOO_CONNECTION_PACKET_NUM_OUTPUT 2
+#define VOODOO_CONNECTION_LINK_INPUT_BUF_MAX ((VOODOO_PACKET_MAX + sizeof(VoodooPacketHeader)) * 1)
+
+
+class VoodooConnectionLink : public VoodooConnection {
+protected:
+ struct {
+ u8 *buffer;
+ size_t start;
+ size_t last;
+ size_t end;
+ size_t max;
+ } input;
+
+ struct {
+ DirectMutex lock;
+ DirectWaitQueue wait;
+ DirectTLS tls;
+ DirectLink *packets;
+
+ VoodooPacket *sending;
+ size_t sent;
+ } output;
+
+public:
+ VoodooConnectionLink( VoodooManager *manager,
+ VoodooLink *link );
+
+ virtual ~VoodooConnectionLink();
+
+
+ virtual VoodooPacket *GetPacket( size_t length );
+ virtual void PutPacket( VoodooPacket *packet,
+ bool flush );
+
+ virtual void Stop ();
+
+
+private:
+ void Flush ( VoodooPacket *packet );
+
+ static void OutputTLS_Destructor( void *ptr );
+
+
+private:
+ friend class Packets;
+
+ class Packets {
+ private:
+ int magic;
+ VoodooConnectionLink *connection;
+ VoodooPacket *packets[VOODOO_CONNECTION_PACKET_NUM_OUTPUT];
+ size_t next;
+ size_t num;
+
+ public:
+ VoodooPacket *active;
+
+ public:
+ Packets( VoodooConnectionLink *connection );
+
+ ~Packets();
+
+ VoodooPacket *Get();
+ };
+};
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/connection_packet.cpp b/Source/DirectFB/lib/voodoo/connection_packet.cpp
new file mode 100755
index 0000000..1e8a77f
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/connection_packet.cpp
@@ -0,0 +1,368 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+extern "C" {
+#include <direct/debug.h>
+#include <direct/fastlz.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <voodoo/conf.h>
+#include <voodoo/link.h>
+}
+
+#include <voodoo/connection_packet.h>
+#include <voodoo/manager.h>
+#include <voodoo/packet.h>
+
+
+#include <vector>
+
+
+//namespace Voodoo {
+
+D_DEBUG_DOMAIN( Voodoo_Connection, "Voodoo/Connection", "Voodoo Connection" );
+D_DEBUG_DOMAIN( Voodoo_Input, "Voodoo/Input", "Voodoo Input" );
+D_DEBUG_DOMAIN( Voodoo_Output, "Voodoo/Output", "Voodoo Output" );
+
+/**********************************************************************************************************************/
+
+VoodooConnectionPacket::VoodooConnectionPacket( VoodooManager *manager,
+ VoodooLink *link )
+ :
+ VoodooConnectionLink( manager, link ),
+ stop( false ),
+ closed( false )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p )\n", __func__, this );
+}
+
+VoodooConnectionPacket::~VoodooConnectionPacket()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+}
+
+void
+VoodooConnectionPacket::Start()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ io = direct_thread_create( DTT_DEFAULT, io_loop_main, this, "Voodoo IO" );
+}
+
+void
+VoodooConnectionPacket::Stop()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ direct_mutex_lock( &output.lock );
+
+ while (!closed && output.packets) {
+ D_DEBUG_AT( Voodoo_Connection, " -> waiting for output packets to be sent...\n" );
+
+ direct_waitqueue_wait( &output.wait, &output.lock );
+ }
+
+ direct_mutex_unlock( &output.lock );
+
+ stop = true;
+
+ link->WakeUp( link );
+
+ /* Wait for manager threads exiting. */
+ direct_thread_join( io );
+ direct_thread_destroy( io );
+
+ VoodooConnectionLink::Stop();
+}
+
+/**********************************************************************************************************************/
+
+void *
+VoodooConnectionPacket::io_loop()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p )\n", __func__, this );
+
+ while (!stop) {
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ if (input.start == input.max) {
+ input.start = 0;
+ input.end = 0;
+ input.last = 0;
+ input.max = VOODOO_CONNECTION_LINK_INPUT_BUF_MAX;
+ }
+
+ if (!stop) {
+ DirectResult ret;
+ VoodooChunk chunks[2];
+ VoodooChunk *chunk_read = NULL;
+ VoodooChunk *chunk_write = NULL;
+ size_t last = input.last;
+ VoodooPacket *packet = NULL;
+
+ std::vector<VoodooChunk> chunks_write;
+ std::vector<VoodooChunk> chunks_read;
+
+ if (!output.sending) {
+ direct_mutex_lock( &output.lock );
+
+ if (output.packets) {
+ VoodooPacket *packet = (VoodooPacket*) output.packets;
+
+ D_ASSERT( packet->sending );
+
+ if (voodoo_config->compression_min && packet->size() >= voodoo_config->compression_min) {
+ output.sending = VoodooPacket::Compressed( packet );
+
+ if (output.sending->flags() & VPHF_COMPRESSED) {
+ D_DEBUG_AT( Voodoo_Output, " -> Compressed %u to %u bytes... (packet %p)\n",
+ output.sending->uncompressed(), output.sending->size(), packet );
+
+ output.sending->sending = true;
+
+ packet->sending = false;
+
+ direct_list_remove( &output.packets, &packet->link );
+
+ direct_waitqueue_broadcast( &output.wait );
+ }
+ }
+ else
+ output.sending = packet;
+
+ output.sent = 0;
+ }
+
+ direct_mutex_unlock( &output.lock );
+ }
+
+ if (output.sending) {
+ packet = output.sending;
+
+ D_ASSERT( packet->sending );
+
+ chunk_write = &chunks[1];
+
+ chunk_write->ptr = (char*) packet->data_header() + output.sent;
+ chunk_write->length = VOODOO_MSG_ALIGN(packet->size() + sizeof(VoodooPacketHeader)) - output.sent;
+ chunk_write->done = 0;
+
+ chunks_write.push_back( chunks[1] );
+
+ chunk_write = chunks_write.data();
+ }
+
+ if (input.end < input.max && manager->DispatchReady()) {
+ chunk_read = &chunks[0];
+
+ chunk_read->ptr = input.buffer + input.end;
+ chunk_read->length = input.max - input.end;
+ chunk_read->done = 0;
+
+ chunks_read.push_back( chunks[0] );
+
+ chunk_read = chunks_read.data();
+ }
+
+
+ ret = link->SendReceive( link,
+ chunks_write.data(), chunks_write.size(),
+ chunks_read.data(), chunks_read.size() );
+ switch (ret) {
+ case DR_OK:
+ if (chunk_write && chunk_write->done) {
+ D_DEBUG_AT( Voodoo_Output, " -> Sent "_ZD"/"_ZD" bytes... (packet %p)\n", chunk_write->done, chunk_write->length, packet );
+
+ output.sent += chunk_write->done;
+
+ if (output.sent == VOODOO_MSG_ALIGN(packet->size() + sizeof(VoodooPacketHeader))) {
+ output.sending = NULL;
+
+ if (packet->flags() & VPHF_COMPRESSED) {
+ packet->sending = false;
+
+ D_FREE( packet );
+ }
+ else {
+ direct_mutex_lock( &output.lock );
+
+ packet->sending = false;
+
+ direct_list_remove( &output.packets, &packet->link );
+
+ direct_mutex_unlock( &output.lock );
+
+ direct_waitqueue_broadcast( &output.wait );
+ }
+ }
+ }
+ break;
+
+ case DR_TIMEOUT:
+ //D_DEBUG_AT( Voodoo_Connection, " -> timeout\n" );
+ break;
+
+ case DR_INTERRUPTED:
+ D_DEBUG_AT( Voodoo_Connection, " -> interrupted\n" );
+ break;
+
+ default:
+ if (ret == DR_IO)
+ D_DEBUG_AT( Voodoo_Connection, " -> Connection closed!\n" );
+ else
+ {
+ D_DERROR( ret, "Voodoo/ConnectionPacket: Could not receive data!\n" );
+ exit(0);
+ }
+
+ goto disconnect;
+ }
+
+
+ if (chunk_read && chunk_read->done) {
+ D_DEBUG_AT( Voodoo_Input, " -> Received "_ZD" bytes...\n", chunk_read->done );
+
+ input.end += (size_t) chunk_read->done;
+
+ do {
+ VoodooPacketHeader *header;
+ size_t aligned;
+
+ /* Get the packet header. */
+ header = (VoodooPacketHeader *)(input.buffer + last);
+ aligned = VOODOO_MSG_ALIGN( header->size );
+
+ D_DEBUG_AT( Voodoo_Input, " -> Next packet has %u ("_ZU") -> %u bytes (flags 0x%04x)...\n",
+ header->size, aligned, header->uncompressed, header->flags );
+
+ if (input.end - last >= sizeof(VoodooPacketHeader)) {
+ if (header->uncompressed < (int) sizeof(VoodooMessageHeader)) {
+ D_DERROR( ret, "Voodoo/ConnectionPacket: Data error, uncompressed %d < min %zu!\n", header->uncompressed, sizeof(VoodooPacketHeader) );
+
+ goto disconnect;
+ }
+
+ if (header->uncompressed > VOODOO_PACKET_MAX) {
+ D_DERROR( ret, "Voodoo/ConnectionPacket: Data error, uncompressed %d > max %d!\n", header->uncompressed, VOODOO_PACKET_MAX );
+
+ goto disconnect;
+ }
+ }
+
+ if (sizeof(VoodooPacketHeader) + aligned > input.end - last) {
+ D_DEBUG_AT( Voodoo_Input, " -> ...fetching tail of message.\n" );
+
+ /* Extend the buffer if the message doesn't fit into the default boundary. */
+ if (sizeof(VoodooPacketHeader) + aligned > input.max - last)
+ input.max = last + sizeof(VoodooPacketHeader) + aligned;
+
+ break;
+ }
+
+ last += sizeof(VoodooPacketHeader) + aligned;
+ } while (last < input.end);
+
+ if (last != input.last) {
+ input.last = last;
+
+ D_DEBUG_AT( Voodoo_Input, " { START "_ZD", LAST "_ZD", END "_ZD", MAX "_ZD" }\n",
+ input.start, input.last, input.end, input.max );
+
+ while (input.start < input.last) {
+ /* Get the packet header. */
+ VoodooPacketHeader *header = (VoodooPacketHeader *)(input.buffer + input.start);
+
+ VoodooPacket *p;
+
+ D_ASSERT( header->uncompressed <= VOODOO_PACKET_MAX );
+
+ if (header->flags & VPHF_COMPRESSED) {
+ size_t uncompressed = direct_fastlz_decompress( header + 1, header->size, tmp, header->uncompressed );
+
+ D_DEBUG_AT( Voodoo_Input, " -> Uncompressed "_ZU" bytes (%u compressed)\n", uncompressed, header->size );
+
+ (void) uncompressed;
+
+ D_ASSERT( uncompressed == header->uncompressed );
+
+ // FIXME: don't copy, but read into packet directly, maybe call manager->GetPacket() at the top of this loop
+ p = VoodooPacket::Copy( header->uncompressed, VPHF_NONE,
+ header->uncompressed, tmp );
+ }
+ else {
+ // FIXME: don't copy, but read into packet directly, maybe call manager->GetPacket() at the top of this loop
+ p = VoodooPacket::Copy( header->uncompressed, VPHF_NONE,
+ header->uncompressed, header + 1 );
+ }
+
+ manager->DispatchPacket( p );
+
+ input.start += VOODOO_MSG_ALIGN(header->size) + sizeof(VoodooPacketHeader);
+ }
+ }
+ }
+ }
+ }
+
+ return NULL;
+
+
+disconnect:
+ closed = true;
+
+ manager->handle_disconnect();
+
+ return NULL;
+}
+
+/**********************************************************************************************************************/
+
+void *
+VoodooConnectionPacket::io_loop_main( DirectThread *thread, void *arg )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p, thread %p )\n", __func__, arg, thread );
+
+ VoodooConnectionPacket *connection = (VoodooConnectionPacket*) arg;
+
+ return connection->io_loop();
+}
+
diff --git a/Source/DirectFB/lib/voodoo/connection_packet.h b/Source/DirectFB/lib/voodoo/connection_packet.h
new file mode 100755
index 0000000..ec53e27
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/connection_packet.h
@@ -0,0 +1,61 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__CONNECTION_PACKET_H__
+#define __VOODOO__CONNECTION_PACKET_H__
+
+#include <voodoo/connection_link.h>
+
+
+class VoodooConnectionPacket : public VoodooConnectionLink {
+private:
+ char tmp[VOODOO_PACKET_MAX];
+ DirectThread *io;
+ bool stop;
+ bool closed;
+
+public:
+ VoodooConnectionPacket( VoodooManager *manager,
+ VoodooLink *link );
+
+ virtual ~VoodooConnectionPacket();
+
+ virtual void Start();
+ virtual void Stop();
+
+
+private:
+ void *io_loop();
+
+
+ static void *io_loop_main( DirectThread *thread,
+ void *arg );
+};
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/connection_packet_old.cpp b/Source/DirectFB/lib/voodoo/connection_packet_old.cpp
new file mode 100755
index 0000000..0efec4d
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/connection_packet_old.cpp
@@ -0,0 +1,433 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+
+extern "C" {
+#include <direct/clock.h>
+#include <direct/debug.h>
+#include <direct/fastlz.h>
+#include <direct/hash.h>
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <voodoo/conf.h>
+#include <voodoo/internal.h>
+#include <voodoo/link.h>
+}
+
+#include <voodoo/connection_packet.h>
+#include <voodoo/manager.h>
+#include <voodoo/packet.h>
+
+
+#include <vector>
+
+
+#define IN_BUF_MAX (640 * 1024)
+#define OUT_BUF_MAX (640 * 1024)
+
+
+//namespace Voodoo {
+
+D_DEBUG_DOMAIN( Voodoo_Connection, "Voodoo/Connection", "Voodoo Connection" );
+D_DEBUG_DOMAIN( Voodoo_Input, "Voodoo/Input", "Voodoo Input" );
+D_DEBUG_DOMAIN( Voodoo_Output, "Voodoo/Output", "Voodoo Output" );
+
+/**********************************************************************************************************************/
+
+VoodooConnectionPacket::VoodooConnectionPacket( VoodooManager *manager,
+ VoodooLink *link )
+ :
+ VoodooConnection( manager, link )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p )\n", __func__, this );
+
+ input.start = 0;
+ input.last = 0;
+ input.end = 0;
+ input.max = 0;
+
+ output.start = 0;
+ output.end = 0;
+
+ /* Initialize all locks. */
+ direct_recursive_mutex_init( &input.lock );
+ direct_recursive_mutex_init( &output.lock );
+
+ /* Initialize all wait conditions. */
+ direct_waitqueue_init( &input.wait );
+ direct_waitqueue_init( &output.wait );
+
+ /* Set default buffer limit. */
+ input.max = IN_BUF_MAX;
+
+ /* Allocate buffers. */
+ input.buffer = (u8*) D_MALLOC( IN_BUF_MAX + VOODOO_PACKET_MAX + sizeof(VoodooPacketHeader) );
+ output.buffer = (u8*) D_MALLOC( OUT_BUF_MAX );
+
+ io = direct_thread_create( DTT_DEFAULT, io_loop_main, this, "Voodoo IO" );
+}
+
+VoodooConnectionPacket::~VoodooConnectionPacket()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ link->WakeUp( link );
+
+ /* Acquire locks and wake up waiters. */
+ direct_mutex_lock( &input.lock );
+ direct_waitqueue_broadcast( &input.wait );
+ direct_mutex_unlock( &input.lock );
+
+ direct_mutex_lock( &output.lock );
+ direct_waitqueue_broadcast( &output.wait );
+ direct_mutex_unlock( &output.lock );
+
+ /* Wait for manager threads exiting. */
+ direct_thread_join( io );
+ direct_thread_destroy( io );
+
+ /* Destroy conditions. */
+ direct_waitqueue_deinit( &input.wait );
+ direct_waitqueue_deinit( &output.wait );
+
+ /* Destroy locks. */
+ direct_mutex_deinit( &input.lock );
+ direct_mutex_deinit( &output.lock );
+
+ /* Deallocate buffers. */
+ D_FREE( output.buffer );
+ D_FREE( input.buffer );
+}
+
+/**********************************************************************************************************************/
+
+void *
+VoodooConnectionPacket::io_loop_main( DirectThread *thread, void *arg )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p, thread %p )\n", __func__, arg, thread );
+
+ VoodooConnectionPacket *connection = (VoodooConnectionPacket*) arg;
+
+ return connection->io_loop();
+}
+
+void *
+VoodooConnectionPacket::io_loop()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p )\n", __func__, this );
+
+ while (!manager->is_quit) {
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+// direct_mutex_lock( &manager->input.lock );
+
+ if (input.start == input.max) {
+ input.start = 0;
+ input.end = 0;
+ input.last = 0;
+ input.max = IN_BUF_MAX;
+ }
+
+// direct_mutex_unlock( &input.lock );
+
+ if (!manager->is_quit) {
+ DirectResult ret;
+ VoodooChunk chunks[2];
+ VoodooChunk *chunk_read = NULL;
+ VoodooChunk *chunk_write = NULL;
+ size_t last = input.last;
+
+ std::vector<VoodooChunk> chunks_write;
+ std::vector<VoodooChunk> chunks_read;
+
+ direct_mutex_lock( &output.lock );
+
+ if (input.end < input.max) {
+ chunk_read = &chunks[0];
+
+ chunk_read->ptr = input.buffer + input.end;
+ chunk_read->length = input.max - input.end;
+ chunk_read->done = 0;
+
+ chunks_read.push_back( chunks[0] );
+
+ chunk_read = chunks_read.data();
+ }
+
+ if (output.end > output.start) {
+ chunk_write = &chunks[1];
+
+ chunk_write->ptr = output.buffer + output.start;
+ chunk_write->length = output.end - output.start;
+ chunk_write->done = 0;
+
+ if (chunk_write->length > 65536) {
+ chunk_write->length = 65536;
+ }
+
+ chunks_write.push_back( chunks[1] );
+
+ chunk_write = chunks_write.data();
+ }
+
+ if (!chunk_write)
+ direct_mutex_unlock( &output.lock );
+
+#if 0
+ if (chunk_write) {
+ char buf[chunk_write->length*4/3];
+
+ size_t comp = direct_fastlz_compress( chunk_write->ptr, chunk_write->length, buf );
+
+ D_DEBUG_AT( Voodoo_Output, " -> Compressed "_ZU"%% ("_ZU" -> "_ZU")\n",
+ comp * 100 / chunk_write->length, chunk_write->length, comp );
+ }
+#endif
+
+ ret = link->SendReceive( link,
+ chunks_write.data(), chunks_write.size(),
+ chunks_read.data(), chunks_read.size() );
+ switch (ret) {
+ case DR_OK:
+ if (chunk_write && chunk_write->done) {
+ D_DEBUG_AT( Voodoo_Output, " -> Sent "_ZD"/"_ZD" bytes...\n", chunk_write->done, chunk_write->length );
+
+ output.start += (size_t) chunk_write->done;
+
+ //direct_mutex_lock( &output.lock );
+
+ if (output.start == output.end) {
+ output.start = output.end = 0;
+
+ direct_waitqueue_broadcast( &output.wait );
+ }
+
+ //direct_mutex_unlock( &output.lock );
+ }
+ break;
+
+ case DR_TIMEOUT:
+ //D_WARN("timeout");
+ break;
+
+ case DR_INTERRUPTED:
+ //D_WARN("interrupted");
+ break;
+
+ default:
+ D_DERROR( ret, "Voodoo/Manager: Could not receive data!\n" );
+ manager->handle_disconnect();
+ break;
+ }
+
+ if (chunk_write)
+ direct_mutex_unlock( &output.lock );
+
+
+
+ if (chunk_read && chunk_read->done) {
+ D_DEBUG_AT( Voodoo_Input, " -> Received "_ZD" bytes...\n", chunk_read->done );
+
+ input.end += (size_t) chunk_read->done;
+
+ do {
+ VoodooPacketHeader *header;
+
+ /* Get the packet header. */
+ header = (VoodooPacketHeader *)(input.buffer + last);
+
+ D_DEBUG_AT( Voodoo_Input, " -> Next packet has %u bytes...\n", header->size );
+
+ D_ASSERT( header->size >= (int) sizeof(VoodooMessageHeader) );
+ D_ASSERT( header->size <= MAX_MSG_SIZE );
+
+ if (sizeof(VoodooPacketHeader) + header->size > input.end - last) {
+ D_DEBUG_AT( Voodoo_Input, " -> ...fetching tail of message.\n" );
+
+ /* Extend the buffer if the message doesn't fit into the default boundary. */
+ if (sizeof(VoodooPacketHeader) + header->size > input.max - last) {
+ D_ASSERT( input.max == IN_BUF_MAX );
+
+
+ input.max = last + sizeof(VoodooPacketHeader) + header->size;
+ }
+
+ break;
+ }
+
+ last += sizeof(VoodooPacketHeader) + header->size;
+ } while (last < input.end);
+
+ if (last != input.last) {
+
+ input.last = last;
+
+ D_DEBUG_AT( Voodoo_Input, " { START "_ZD", LAST "_ZD", END "_ZD", MAX "_ZD" }\n",
+ input.start, input.last, input.end, input.max );
+
+ while (input.start < input.last) {
+ /* Get the packet header. */
+ VoodooPacketHeader *header = (VoodooPacketHeader *)(input.buffer + input.start);
+
+ ProcessMessages( (VoodooMessageHeader *)(header + 1), header->uncompressed );
+
+ input.start += header->size + sizeof(VoodooPacketHeader);
+ }
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/**********************************************************************************************************************/
+
+DirectResult
+VoodooConnectionPacket::lock_output( int length,
+ void **ret_ptr )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p, length %d )\n", __func__, this, length );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+ D_ASSERT( length >= (int) sizeof(VoodooMessageHeader) );
+ D_ASSUME( length <= MAX_MSG_SIZE );
+ D_ASSERT( ret_ptr != NULL );
+
+ if (length > MAX_MSG_SIZE) {
+ D_WARN( "%d exceeds maximum message size of %d", length, MAX_MSG_SIZE );
+ return DR_LIMITEXCEEDED;
+ }
+
+ int aligned = VOODOO_MSG_ALIGN( length );
+
+ direct_mutex_lock( &output.lock );
+
+ while (output.end + aligned > OUT_BUF_MAX) {
+ link->WakeUp( link );
+
+ direct_waitqueue_wait( &output.wait, &output.lock );
+
+ if (manager->is_quit) {
+ direct_mutex_lock( &output.lock );
+ return DR_DESTROYED;
+ }
+ }
+
+ *ret_ptr = output.buffer + output.end;
+
+ D_DEBUG_AT( Voodoo_Output, " -> offset "_ZD", aligned length %d\n", output.end, aligned );
+
+ output.end += aligned;
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooConnectionPacket::unlock_output( bool flush )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p, %sflush )\n", __func__, this, flush ? "" : "NO " );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ direct_mutex_unlock( &output.lock );
+
+ if (flush)
+ link->WakeUp( link );
+
+ return DR_OK;
+}
+
+VoodooPacket *
+VoodooConnectionPacket::GetPacket( size_t length )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p, length "_ZU" )\n", __func__, this, length );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+ D_ASSERT( length >= (int) sizeof(VoodooMessageHeader) );
+ D_ASSUME( length <= MAX_MSG_SIZE );
+
+ if (length > MAX_MSG_SIZE) {
+ D_WARN( _ZU" exceeds maximum message size of %d", length, MAX_MSG_SIZE );
+ return NULL;
+ }
+
+ int aligned = sizeof(VoodooPacketHeader) + VOODOO_MSG_ALIGN( length );
+
+ direct_mutex_lock( &output.lock );
+
+ while (output.end + aligned > OUT_BUF_MAX) {
+ link->WakeUp( link );
+
+ direct_waitqueue_wait( &output.wait, &output.lock );
+
+ if (manager->is_quit) {
+ direct_mutex_lock( &output.lock );
+ return NULL;
+ }
+ }
+
+ D_DEBUG_AT( Voodoo_Output, " -> offset "_ZD", aligned length %d\n", output.end, aligned );
+
+ output.end += aligned;
+
+ return VoodooPacket::New( output.buffer + output.end - aligned, aligned - sizeof(VoodooPacketHeader) );
+}
+
+void
+VoodooConnectionPacket::PutPacket( VoodooPacket *packet, bool flush )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p, %sflush )\n", __func__, this, flush ? "" : "NO " );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ direct_mutex_unlock( &output.lock );
+
+ if (flush)
+ link->WakeUp( link );
+
+// delete packet;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/connection_packet_old.h b/Source/DirectFB/lib/voodoo/connection_packet_old.h
new file mode 100755
index 0000000..cfb10bf
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/connection_packet_old.h
@@ -0,0 +1,87 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__CONNECTION_PACKET_H__
+#define __VOODOO__CONNECTION_PACKET_H__
+
+#include <voodoo/connection.h>
+
+extern "C" {
+#include <direct/thread.h>
+}
+
+
+class VoodooConnectionPacket : public VoodooConnection {
+private:
+ DirectThread *io;
+
+ struct {
+ DirectMutex lock;
+ DirectWaitQueue wait;
+ u8 *buffer;
+ size_t start;
+ size_t last;
+ size_t end;
+ size_t max;
+ } input;
+
+ struct {
+ DirectMutex lock;
+ DirectWaitQueue wait;
+ u8 *buffer;
+ size_t start;
+ size_t end;
+ } output;
+
+public:
+ VoodooConnectionPacket( VoodooManager *manager,
+ VoodooLink *link );
+
+ virtual ~VoodooConnectionPacket();
+
+
+ virtual DirectResult lock_output ( int length,
+ void **ret_ptr );
+
+ virtual DirectResult unlock_output( bool flush );
+
+
+ virtual VoodooPacket *GetPacket( size_t length );
+ virtual void PutPacket( VoodooPacket *packet,
+ bool flush );
+
+
+private:
+ static void *io_loop_main ( DirectThread *thread,
+ void *arg );
+
+ void *io_loop ();
+};
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/connection_raw.cpp b/Source/DirectFB/lib/voodoo/connection_raw.cpp
new file mode 100755
index 0000000..c6ba56a
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/connection_raw.cpp
@@ -0,0 +1,341 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#ifdef VOODOO_CONNECTION_RAW_DUMP
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+extern "C" {
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <voodoo/conf.h>
+#include <voodoo/internal.h>
+#include <voodoo/link.h>
+}
+
+#include <voodoo/connection_raw.h>
+#include <voodoo/manager.h>
+#include <voodoo/packet.h>
+
+
+#include <vector>
+
+
+//namespace Voodoo {
+
+D_DEBUG_DOMAIN( Voodoo_Connection, "Voodoo/Connection", "Voodoo Connection" );
+D_DEBUG_DOMAIN( Voodoo_Input, "Voodoo/Input", "Voodoo Input" );
+D_DEBUG_DOMAIN( Voodoo_Output, "Voodoo/Output", "Voodoo Output" );
+
+/**********************************************************************************************************************/
+
+VoodooConnectionRaw::VoodooConnectionRaw( VoodooManager *manager,
+ VoodooLink *link )
+ :
+ VoodooConnectionLink( manager, link ),
+ stop( false ),
+ closed( false )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionRaw::%s( %p )\n", __func__, this );
+
+ if (link->code) {
+ input.end = 4;
+
+ memcpy( input.buffer, &link->code, sizeof(u32) );
+ }
+}
+
+VoodooConnectionRaw::~VoodooConnectionRaw()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionRaw::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+}
+
+void
+VoodooConnectionRaw::Start()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionRaw::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ io = direct_thread_create( DTT_DEFAULT, io_loop_main, this, "Voodoo IO" );
+}
+
+void
+VoodooConnectionRaw::Stop()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionRaw::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ direct_mutex_lock( &output.lock );
+
+ while (!closed && output.packets) {
+ D_DEBUG_AT( Voodoo_Connection, " -> waiting for output packets to be sent...\n" );
+
+ direct_waitqueue_wait( &output.wait, &output.lock );
+ }
+
+ direct_mutex_unlock( &output.lock );
+
+ stop = true;
+
+ link->WakeUp( link );
+
+ /* Wait for manager threads exiting. */
+ direct_thread_join( io );
+ direct_thread_destroy( io );
+
+ VoodooConnectionLink::Stop();
+}
+
+/**********************************************************************************************************************/
+
+void *
+VoodooConnectionRaw::io_loop()
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionRaw::%s( %p )\n", __func__, this );
+
+#ifdef VOODOO_CONNECTION_RAW_DUMP
+ int dump_fd = open("voodoo_write.raw", O_TRUNC|O_CREAT|O_WRONLY, 0660 );
+ int dump_read_fd = open("voodoo_read.raw", O_TRUNC|O_CREAT|O_WRONLY, 0660 );
+#endif
+
+ while (!stop) {
+ D_MAGIC_ASSERT( this, VoodooConnection );
+
+ if (input.start == input.max) {
+ input.start = 0;
+ input.end = 0;
+ input.last = 0;
+ input.max = VOODOO_CONNECTION_LINK_INPUT_BUF_MAX;
+ }
+
+ if (!stop) {
+ DirectResult ret;
+ VoodooChunk chunks[2];
+ VoodooChunk *chunk_read = NULL;
+ VoodooChunk *chunk_write = NULL;
+ size_t last = input.last;
+ VoodooPacket *packet = NULL;
+
+ std::vector<VoodooChunk> chunks_write;
+ std::vector<VoodooChunk> chunks_read;
+
+ if (!output.sending) {
+ direct_mutex_lock( &output.lock );
+
+ if (output.packets) {
+ VoodooPacket *packet = (VoodooPacket*) output.packets;
+
+ D_ASSERT( packet->sending );
+
+ output.sending = packet;
+ output.sent = 0;
+ }
+
+ direct_mutex_unlock( &output.lock );
+ }
+
+ if (output.sending) {
+ packet = output.sending;
+
+ D_ASSERT( packet->sending );
+
+ chunk_write = &chunks[1];
+
+ chunk_write->ptr = (char*) packet->data_start() + output.sent;
+ chunk_write->length = VOODOO_MSG_ALIGN(packet->size()) - output.sent;
+ chunk_write->done = 0;
+
+ chunks_write.push_back( chunks[1] );
+
+ chunk_write = chunks_write.data();
+ }
+
+ if (input.end < input.max && manager->DispatchReady()) {
+ chunk_read = &chunks[0];
+
+ chunk_read->ptr = input.buffer + input.end;
+ chunk_read->length = input.max - input.end;
+ chunk_read->done = 0;
+
+ chunks_read.push_back( chunks[0] );
+
+ chunk_read = chunks_read.data();
+ }
+
+
+ ret = link->SendReceive( link,
+ chunks_write.data(), chunks_write.size(),
+ chunks_read.data(), chunks_read.size() );
+ switch (ret) {
+ case DR_OK:
+ if (chunk_write && chunk_write->done) {
+ D_DEBUG_AT( Voodoo_Output, " -> Sent "_ZD"/"_ZD" bytes...\n", chunk_write->done, chunk_write->length );
+
+#ifdef VOODOO_CONNECTION_RAW_DUMP
+ write( dump_fd, chunk_write->ptr, chunk_write->done );
+#endif
+
+ output.sent += chunk_write->done;
+
+ if (output.sent == VOODOO_MSG_ALIGN(packet->size())) {
+ output.sending = NULL;
+
+ direct_mutex_lock( &output.lock );
+
+ packet->sending = false;
+
+ direct_list_remove( &output.packets, &packet->link );
+
+ direct_mutex_unlock( &output.lock );
+
+ direct_waitqueue_broadcast( &output.wait );
+ }
+ }
+ break;
+
+ case DR_TIMEOUT:
+ //D_DEBUG_AT( Voodoo_Connection, " -> timeout\n" );
+ break;
+
+ case DR_INTERRUPTED:
+ D_DEBUG_AT( Voodoo_Connection, " -> interrupted\n" );
+ break;
+
+ default:
+ if (ret == DR_IO)
+ D_DEBUG_AT( Voodoo_Connection, " -> Connection closed!\n" );
+ else
+ {
+ D_DERROR( ret, "Voodoo/ConnectionRaw: Could not receive data!\n" );
+ exit(0);
+ }
+
+ closed = true;
+
+ manager->handle_disconnect();
+
+ return NULL;
+ }
+
+
+ if (chunk_read && chunk_read->done) {
+ D_DEBUG_AT( Voodoo_Input, " -> Received "_ZD" bytes...\n", chunk_read->done );
+
+#ifdef VOODOO_CONNECTION_RAW_DUMP
+ write( dump_read_fd, chunk_read->ptr, chunk_read->done );
+#endif
+
+ input.end += (size_t) chunk_read->done;
+
+ do {
+ VoodooMessageHeader *header;
+ size_t aligned;
+
+ D_DEBUG_AT( Voodoo_Input, " { LAST "_ZD", INPUT LAST "_ZD" }\n", last, input.last );
+
+ if (input.end - last < 4) {
+ D_DEBUG_AT( Voodoo_Input, " -> ...only "_ZU" bytes left\n", input.end - last );
+ break;
+ }
+
+ /* Get the message header. */
+ header = (VoodooMessageHeader *)(input.buffer + last);
+ aligned = VOODOO_MSG_ALIGN( header->size );
+
+ D_DEBUG_AT( Voodoo_Input, " -> Next message has %d ("_ZD") bytes and is of type %d...\n",
+ header->size, aligned, header->type );
+
+ D_ASSERT( header->size >= (int) sizeof(VoodooMessageHeader) );
+ D_ASSERT( header->size <= MAX_MSG_SIZE );
+
+ if (aligned > input.end - last) {
+ D_DEBUG_AT( Voodoo_Input, " -> ...fetching tail of message.\n" );
+
+ /* Extend the buffer if the message doesn't fit into the default boundary. */
+ if (aligned > input.max - last)
+ input.max = last + aligned;
+
+ break;
+ }
+
+ last += aligned;
+ } while (last < input.end);
+
+ if (last != input.last) {
+ input.last = last;
+
+ D_DEBUG_AT( Voodoo_Input, " { START "_ZD", LAST "_ZD", END "_ZD", MAX "_ZD" }\n",
+ input.start, input.last, input.end, input.max );
+
+ // FIXME: don't copy, but read into packet directly, maybe call manager->GetPacket() at the top of this loop
+ VoodooPacket *p = VoodooPacket::Copy( input.last - input.start, VPHF_NONE,
+ input.last - input.start, input.buffer + input.start );
+
+ manager->DispatchPacket( p );
+
+ input.start = input.last;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/**********************************************************************************************************************/
+
+void *
+VoodooConnectionRaw::io_loop_main( DirectThread *thread, void *arg )
+{
+ D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionRaw::%s( %p, thread %p )\n", __func__, arg, thread );
+
+ VoodooConnectionRaw *connection = (VoodooConnectionRaw*) arg;
+
+ return connection->io_loop();
+}
+
diff --git a/Source/DirectFB/lib/voodoo/connection_raw.h b/Source/DirectFB/lib/voodoo/connection_raw.h
new file mode 100755
index 0000000..45ce4c5
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/connection_raw.h
@@ -0,0 +1,60 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__CONNECTION_RAW_H__
+#define __VOODOO__CONNECTION_RAW_H__
+
+#include <voodoo/connection_link.h>
+
+
+class VoodooConnectionRaw : public VoodooConnectionLink {
+private:
+ DirectThread *io;
+ bool stop;
+ bool closed;
+
+public:
+ VoodooConnectionRaw( VoodooManager *manager,
+ VoodooLink *link );
+
+ virtual ~VoodooConnectionRaw();
+
+ virtual void Start();
+ virtual void Stop();
+
+
+private:
+ void *io_loop();
+
+
+ static void *io_loop_main( DirectThread *thread,
+ void *arg );
+};
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/dispatcher.cpp b/Source/DirectFB/lib/voodoo/dispatcher.cpp
new file mode 100755
index 0000000..af98c0a
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/dispatcher.cpp
@@ -0,0 +1,231 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+extern "C" {
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <voodoo/link.h>
+#include <voodoo/message.h>
+}
+
+#include <voodoo/dispatcher.h>
+#include <voodoo/manager.h>
+#include <voodoo/packet.h>
+
+
+D_DEBUG_DOMAIN( Voodoo_Dispatcher, "Voodoo/Dispatcher", "Voodoo Dispatcher" );
+
+/**********************************************************************************************************************/
+
+VoodooDispatcher::VoodooDispatcher( VoodooManager *manager )
+ :
+ magic(0),
+ manager(manager),
+ packets(NULL)
+{
+ D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p )\n", __func__, this );
+
+ /* Initialize lock. */
+ direct_mutex_init( &lock );
+
+ /* Initialize wait queue. */
+ direct_waitqueue_init( &queue );
+
+ D_MAGIC_SET( this, VoodooDispatcher );
+
+
+ dispatch_loop = direct_thread_create( DTT_MESSAGING, DispatchLoopMain, this, "Voodoo Dispatch" );
+}
+
+VoodooDispatcher::~VoodooDispatcher()
+{
+ D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooDispatcher );
+
+ /* Acquire lock and wake up waiters. */
+ direct_mutex_lock( &lock );
+ direct_waitqueue_broadcast( &queue );
+ direct_mutex_unlock( &lock );
+
+ /* Wait for dispatcher loop exiting. */
+ direct_thread_join( dispatch_loop );
+ direct_thread_destroy( dispatch_loop );
+
+ /* Destroy queue. */
+ direct_waitqueue_deinit( &queue );
+
+ /* Destroy lock. */
+ direct_mutex_deinit( &lock );
+
+ D_MAGIC_CLEAR( this );
+}
+
+bool
+VoodooDispatcher::Ready()
+{
+ D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooDispatcher );
+
+ direct_mutex_lock( &lock );
+
+ bool ready = direct_list_count_elements_EXPENSIVE( packets ) < 3;
+
+ direct_mutex_unlock( &lock );
+
+ return ready;
+}
+
+void
+VoodooDispatcher::PutPacket( VoodooPacket *packet )
+{
+ D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p, packet %p )\n", __func__, this, packet );
+
+ D_MAGIC_ASSERT( this, VoodooDispatcher );
+
+ direct_mutex_lock( &lock );
+
+ direct_list_append( &packets, &packet->link );
+
+ direct_waitqueue_broadcast( &queue );
+
+ direct_mutex_unlock( &lock );
+}
+
+void
+VoodooDispatcher::ProcessMessages( VoodooMessageHeader *first,
+ size_t total_length )
+{
+ D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p, first %p, total_length "_ZU" )\n",
+ __func__, this, first, total_length );
+
+ D_MAGIC_ASSERT( this, VoodooDispatcher );
+
+ VoodooMessageHeader *header = first;
+ size_t offset = 0;
+ size_t aligned;
+
+ while (offset < total_length) {
+ /* Get the message header. */
+ header = (VoodooMessageHeader *)((char*) first + offset);
+ aligned = VOODOO_MSG_ALIGN( header->size );
+
+ D_DEBUG_AT( Voodoo_Dispatcher, " -> Next message has %d ("_ZU") bytes and is of type %d... (offset "_ZU"/"_ZU")\n",
+ header->size, aligned, header->type, offset, total_length );
+
+ D_ASSERT( header->size >= (int) sizeof(VoodooMessageHeader) );
+ D_ASSERT( header->size <= MAX_MSG_SIZE );
+
+ D_ASSERT( offset + aligned <= total_length );
+
+ switch (header->type) {
+ case VMSG_SUPER:
+ manager->handle_super( (VoodooSuperMessage*) header );
+ break;
+
+ case VMSG_REQUEST:
+ manager->handle_request( (VoodooRequestMessage*) header );
+ break;
+
+ case VMSG_RESPONSE:
+ manager->handle_response( (VoodooResponseMessage*) header );
+ break;
+
+ default:
+ D_BUG( "invalid message type %d", header->type );
+ break;
+ }
+
+ offset += aligned;
+ }
+
+ D_ASSERT( offset == total_length );
+}
+
+/**********************************************************************************************************************/
+
+void *
+VoodooDispatcher::DispatchLoop()
+{
+ D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p )\n", __func__, this );
+
+ direct_mutex_lock( &lock );
+
+ while (!manager->is_quit) {
+ VoodooPacket *packet;
+
+ D_MAGIC_ASSERT( this, VoodooDispatcher );
+
+ if (packets) {
+ packet = (VoodooPacket*) packets;
+
+ direct_list_remove( &packets, &packet->link );
+
+ manager->link->WakeUp( manager->link );
+ }
+ else {
+ direct_waitqueue_wait( &queue, &lock );
+
+ continue;
+ }
+
+
+ direct_mutex_unlock( &lock );
+
+ ProcessMessages( (VoodooMessageHeader*) packet->data_start(), packet->size() );
+
+ D_FREE( packet );
+
+ direct_mutex_lock( &lock );
+ }
+
+ direct_mutex_unlock( &lock );
+
+ return NULL;
+}
+
+void *
+VoodooDispatcher::DispatchLoopMain( DirectThread *thread, void *arg )
+{
+ D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p, thread %p )\n", __func__, arg, thread );
+
+ VoodooDispatcher *dispatcher = (VoodooDispatcher*) arg;
+
+ return dispatcher->DispatchLoop();
+}
+
diff --git a/Source/DirectFB/lib/voodoo/dispatcher.h b/Source/DirectFB/lib/voodoo/dispatcher.h
new file mode 100755
index 0000000..f0518db
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/dispatcher.h
@@ -0,0 +1,71 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__DISPATCHER_H__
+#define __VOODOO__DISPATCHER_H__
+
+extern "C" {
+#include <voodoo/types.h>
+}
+
+
+class VoodooDispatcher {
+private:
+ int magic;
+
+ VoodooManager *manager;
+
+ DirectMutex lock;
+ DirectWaitQueue queue;
+
+ DirectThread *dispatch_loop;
+
+ DirectLink *packets;
+
+
+public:
+ VoodooDispatcher( VoodooManager *manager );
+
+ ~VoodooDispatcher();
+
+ bool Ready ();
+ void PutPacket( VoodooPacket *packet );
+
+
+private:
+ void *DispatchLoop();
+
+ static void *DispatchLoopMain( DirectThread *thread,
+ void *arg );
+
+ void ProcessMessages ( VoodooMessageHeader *first,
+ size_t total_length );
+};
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/instance.cpp b/Source/DirectFB/lib/voodoo/instance.cpp
new file mode 100755
index 0000000..61bd20f
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/instance.cpp
@@ -0,0 +1,107 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+extern "C" {
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <voodoo/internal.h>
+}
+
+#include <voodoo/instance.h>
+#include <voodoo/manager.h>
+
+
+D_DEBUG_DOMAIN( Voodoo_Instance, "Voodoo/Instance", "Voodoo Instance" );
+
+/**********************************************************************************************************************/
+
+VoodooInstance::VoodooInstance()
+ :
+ magic(0),
+ refs(1)
+{
+ D_DEBUG_AT( Voodoo_Instance, "VoodooInstance::%s( %p )\n", __func__, this );
+
+ D_MAGIC_SET( this, VoodooInstance );
+}
+
+VoodooInstance::~VoodooInstance()
+{
+ D_DEBUG_AT( Voodoo_Instance, "VoodooInstance::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooInstance );
+
+
+ D_MAGIC_CLEAR( this );
+}
+
+void
+VoodooInstance::AddRef()
+{
+ D_DEBUG_AT( Voodoo_Instance, "VoodooInstance::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooInstance );
+
+ D_ASSERT( refs > 0 );
+
+ refs++;
+}
+
+void
+VoodooInstance::Release()
+{
+ D_DEBUG_AT( Voodoo_Instance, "VoodooInstance::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooInstance );
+
+ D_ASSERT( refs > 0 );
+
+ if (!--refs) {
+ D_DEBUG_AT( Voodoo_Instance, " -> zero refs, deleting instance...\n" );
+
+ delete this;
+ }
+}
+
+DirectResult
+VoodooInstance::Dispatch( VoodooManager *manager,
+ VoodooRequestMessage *msg )
+{
+ D_DEBUG_AT( Voodoo_Instance, "VoodooInstance::%s( %p, manager %p, msg %p )\n", __func__, this, manager, msg );
+
+ D_MAGIC_ASSERT( this, VoodooInstance );
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/instance.h b/Source/DirectFB/lib/voodoo/instance.h
new file mode 100755
index 0000000..a8b434c
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/instance.h
@@ -0,0 +1,61 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__INSTANCE_H__
+#define __VOODOO__INSTANCE_H__
+
+extern "C" {
+#include <voodoo/types.h>
+}
+
+
+class VoodooInstance {
+protected:
+ int magic;
+
+private:
+ unsigned int refs;
+
+public:
+ VoodooInstance();
+
+protected:
+ virtual ~VoodooInstance();
+
+public:
+ void AddRef();
+ void Release();
+
+
+public:
+ virtual DirectResult Dispatch( VoodooManager *manager,
+ VoodooRequestMessage *msg );
+};
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/interface.c b/Source/DirectFB/lib/voodoo/interface.c
new file mode 100755
index 0000000..4281cb6
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/interface.c
@@ -0,0 +1,114 @@
+/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/messages.h>
+
+#include <voodoo/interface.h>
+
+
+DirectResult
+voodoo_construct_requestor( VoodooManager *manager,
+ const char *name,
+ VoodooInstanceID instance,
+ void *arg,
+ void **ret_requestor )
+{
+ DirectResult ret;
+ DirectInterfaceFuncs *funcs;
+ void *requestor;
+
+ D_ASSERT( manager != NULL );
+ D_ASSERT( name != NULL );
+ D_ASSERT( instance != VOODOO_INSTANCE_NONE );
+ D_ASSERT( ret_requestor != NULL );
+
+ ret = DirectGetInterface( &funcs, name, "Requestor", NULL, NULL );
+ if (ret) {
+ D_ERROR( "Voodoo/Interface: Could not load 'Requestor' implementation of '%s'!\n", name );
+ return ret;
+ }
+
+ ret = funcs->Allocate( &requestor );
+ if (ret)
+ return ret;
+
+ ret = funcs->Construct( requestor, manager, instance, arg );
+ if (ret)
+ return ret;
+
+ *ret_requestor = requestor;
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_construct_dispatcher( VoodooManager *manager,
+ const char *name,
+ void *interface,
+ VoodooInstanceID super,
+ void *arg,
+ VoodooInstanceID *ret_instance,
+ void **ret_dispatcher )
+{
+ DirectResult ret;
+ DirectInterfaceFuncs *funcs;
+ void *dispatcher;
+ VoodooInstanceID instance;
+
+ D_ASSERT( manager != NULL );
+ D_ASSERT( name != NULL );
+ D_ASSERT( interface != NULL );
+ D_ASSERT( super != VOODOO_INSTANCE_NONE );
+ D_ASSERT( ret_instance != NULL );
+
+ ret = DirectGetInterface( &funcs, name, "Dispatcher", NULL, NULL );
+ if (ret) {
+ D_ERROR( "Voodoo/Interface: Could not load 'Dispatcher' implementation of '%s'!\n", name );
+ return ret;
+ }
+
+ ret = funcs->Allocate( &dispatcher );
+ if (ret)
+ return ret;
+
+ ret = funcs->Construct( dispatcher, interface, manager, super, arg, &instance );
+ if (ret)
+ return ret;
+
+ *ret_instance = instance;
+
+ if (ret_dispatcher)
+ *ret_dispatcher = dispatcher;
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/interface.h b/Source/DirectFB/lib/voodoo/interface.h
new file mode 100755
index 0000000..8b1a47b
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/interface.h
@@ -0,0 +1,52 @@
+/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__INTERFACE_H__
+#define __VOODOO__INTERFACE_H__
+
+#include <voodoo/types.h>
+
+
+DirectResult
+voodoo_construct_requestor( VoodooManager *manager,
+ const char *name,
+ VoodooInstanceID instance,
+ void *arg,
+ void **ret_interface );
+
+DirectResult
+voodoo_construct_dispatcher( VoodooManager *manager,
+ const char *name,
+ void *interface,
+ VoodooInstanceID super,
+ void *arg,
+ VoodooInstanceID *ret_instance,
+ void **ret_dispatcher );
+
+#endif
+
diff --git a/Source/DirectFB/lib/voodoo/internal.h b/Source/DirectFB/lib/voodoo/internal.h
new file mode 100755
index 0000000..4eae9b0
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/internal.h
@@ -0,0 +1,40 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__INTERNAL_H__
+#define __VOODOO__INTERNAL_H__
+
+#include <voodoo/types.h>
+
+
+DirectResult VOODOO_API voodoo_server_construct( VoodooServer *server,
+ VoodooManager *manager,
+ const char *name,
+ VoodooInstanceID *ret_instance );
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/ivoodooplayer.c b/Source/DirectFB/lib/voodoo/ivoodooplayer.c
new file mode 100755
index 0000000..2324667
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/ivoodooplayer.c
@@ -0,0 +1,247 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+
+#include <semaphore.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <directfb_version.h>
+
+#include <direct/clock.h>
+#include <direct/debug.h>
+#include <direct/direct.h>
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <misc/conf.h>
+
+#include <voodoo/conf.h>
+#include <voodoo/interface.h>
+#include <voodoo/internal.h>
+#include <voodoo/manager.h>
+#include <voodoo/play_server.h>
+#include <voodoo/ivoodooplayer.h>
+
+
+D_DEBUG_DOMAIN( IVoodooPlayer_, "IVoodooPlayer", "IVoodooPlayer" );
+
+/**********************************************************************************************************************/
+
+static DirectResult CreateRemote( const char *host, int session, IVoodooPlayer **ret_interface );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int ref;
+} IVoodooPlayer_data;
+
+static DirectResult
+IVoodooPlayer_AddRef( IVoodooPlayer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA( IVoodooPlayer );
+
+ data->ref++;
+
+ return DR_OK;
+}
+
+static DirectResult
+IVoodooPlayer_Release( IVoodooPlayer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA( IVoodooPlayer );
+
+ if (!--data->ref)
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+
+ return DR_OK;
+}
+
+static DirectResult
+IVoodooPlayer_GetApps( IVoodooPlayer *thiz,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppDescription *ret_applications )
+{
+ D_DEBUG_AT( IVoodooPlayer_, "%s()\n", __func__ );
+
+ if (!max_num || !ret_num || !ret_applications)
+ return DR_INVARG;
+
+ return voodoo_player_get_apps( voodoo_player, max_num, ret_num, ret_applications );
+}
+
+static DirectResult
+IVoodooPlayer_LaunchApp( IVoodooPlayer *thiz,
+ const u8 app_uuid[16],
+ const u8 player_uuid[16],
+ u8 ret_instance_uuid[16] )
+{
+ D_DEBUG_AT( IVoodooPlayer_, "%s()\n", __func__ );
+
+ if (!app_uuid || !player_uuid || !ret_instance_uuid)
+ return DR_INVARG;
+
+ return voodoo_player_launch_app( voodoo_player, app_uuid, player_uuid, ret_instance_uuid );
+}
+
+static DirectResult
+IVoodooPlayer_StopInstance( IVoodooPlayer *thiz,
+ const u8 instance_uuid[16] )
+{
+ D_DEBUG_AT( IVoodooPlayer_, "%s()\n", __func__ );
+
+ if (!instance_uuid)
+ return DR_INVARG;
+
+ return voodoo_player_stop_instance( voodoo_player, instance_uuid );
+}
+
+static DirectResult
+IVoodooPlayer_WaitInstance( IVoodooPlayer *thiz,
+ const u8 instance_uuid[16] )
+{
+ D_DEBUG_AT( IVoodooPlayer_, "%s()\n", __func__ );
+
+ if (!instance_uuid)
+ return DR_INVARG;
+
+ return voodoo_player_wait_instance( voodoo_player, instance_uuid );
+}
+
+static DirectResult
+IVoodooPlayer_GetInstances( IVoodooPlayer *thiz,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppInstanceDescription *ret_instances )
+{
+ D_DEBUG_AT( IVoodooPlayer_, "%s()\n", __func__ );
+
+ if (!max_num || !ret_num || !ret_instances)
+ return DR_INVARG;
+
+ return voodoo_player_get_instances( voodoo_player, max_num, ret_num, ret_instances );
+}
+
+static DirectResult
+IVoodooPlayer_Construct( IVoodooPlayer *thiz )
+{
+ DIRECT_ALLOCATE_INTERFACE_DATA( thiz, IVoodooPlayer );
+
+ data->ref = 1;
+
+ thiz->AddRef = IVoodooPlayer_AddRef;
+ thiz->Release = IVoodooPlayer_Release;
+ thiz->GetApps = IVoodooPlayer_GetApps;
+ thiz->LaunchApp = IVoodooPlayer_LaunchApp;
+ thiz->StopInstance = IVoodooPlayer_StopInstance;
+ thiz->WaitInstance = IVoodooPlayer_WaitInstance;
+ thiz->GetInstances = IVoodooPlayer_GetInstances;
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooPlayerCreate( IVoodooPlayer **ret_interface )
+{
+ DirectResult ret;
+ IVoodooPlayer *player;
+
+ if (!ret_interface)
+ return DR_INVARG;
+
+ if (dfb_config->remote.host)
+ return CreateRemote( dfb_config->remote.host, dfb_config->remote.session, ret_interface );
+
+ if (!voodoo_player)
+ return DR_NOSUCHINSTANCE;
+
+ DIRECT_ALLOCATE_INTERFACE( player, IVoodooPlayer );
+
+ ret = IVoodooPlayer_Construct( player );
+ if (ret)
+ return ret;
+
+ *ret_interface = player;
+
+ return DR_OK;
+}
+
+/**********************************************************************************************************************/
+
+static DirectResult
+CreateRemote( const char *host, int session, IVoodooPlayer **ret_interface )
+{
+ DFBResult ret;
+ DirectInterfaceFuncs *funcs;
+ void *interface;
+
+ D_ASSERT( host != NULL );
+ D_ASSERT( ret_interface != NULL );
+
+ ret = DirectGetInterface( &funcs, "IVoodooPlayer", "Requestor", NULL, NULL );
+ if (ret)
+ return ret;
+
+ ret = funcs->Allocate( &interface );
+ if (ret)
+ return ret;
+
+ ret = funcs->Construct( interface, host, session );
+ if (ret)
+ return ret;
+
+ *ret_interface = interface;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/ivoodooplayer.h b/Source/DirectFB/lib/voodoo/ivoodooplayer.h
new file mode 100755
index 0000000..ae1ef03
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/ivoodooplayer.h
@@ -0,0 +1,74 @@
+/*
+ (c) Copyright 2001-2010 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IVOODOOPLAYER_H__
+#define __IVOODOOPLAYER_H__
+
+#include <voodoo/app.h>
+
+
+DECLARE_INTERFACE( IVoodooPlayer );
+
+DEFINE_INTERFACE( IVoodooPlayer,
+
+ DirectResult (*GetApps)(
+ IVoodooPlayer *thiz,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppDescription *ret_applications
+ );
+
+ DirectResult (*LaunchApp)(
+ IVoodooPlayer *thiz,
+ const u8 app_uuid[16],
+ const u8 player_uuid[16],
+ u8 ret_instance_uuid[16]
+ );
+
+ DirectResult (*StopInstance)(
+ IVoodooPlayer *thiz,
+ const u8 instance_uuid[16]
+ );
+
+ DirectResult (*WaitInstance)(
+ IVoodooPlayer *thiz,
+ const u8 instance_uuid[16]
+ );
+
+ DirectResult (*GetInstances)(
+ IVoodooPlayer *thiz,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppInstanceDescription *ret_instances
+ );
+);
+
+
+DirectResult VoodooPlayerCreate( IVoodooPlayer **ret_interface );
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/ivoodooplayer_dispatcher.c b/Source/DirectFB/lib/voodoo/ivoodooplayer_dispatcher.c
new file mode 100755
index 0000000..bcf4711
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/ivoodooplayer_dispatcher.c
@@ -0,0 +1,359 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/messages.h>
+
+#include <voodoo/ivoodooplayer.h>
+
+#include <voodoo/interface.h>
+#include <voodoo/manager.h>
+#include <voodoo/message.h>
+
+#include "ivoodooplayer_dispatcher.h"
+
+static DirectResult Probe( void );
+static DirectResult Construct( IVoodooPlayer *thiz,
+ VoodooManager *manager,
+ VoodooInstanceID *ret_instance );
+
+#include <direct/interface_implementation.h>
+
+DIRECT_INTERFACE_IMPLEMENTATION( IVoodooPlayer, Dispatcher )
+
+
+/**************************************************************************************************/
+
+/*
+ * private data struct of IVoodooPlayer_Dispatcher
+ */
+typedef struct {
+ int ref; /* reference counter */
+
+ IVoodooPlayer *real;
+
+ VoodooInstanceID self; /* The instance of this dispatcher itself. */
+} IVoodooPlayer_Dispatcher_data;
+
+/**************************************************************************************************/
+
+static void
+IVoodooPlayer_Dispatcher_Destruct( IVoodooPlayer *thiz )
+{
+ D_DEBUG( "%s (%p)\n", __FUNCTION__, thiz );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+IVoodooPlayer_Dispatcher_AddRef( IVoodooPlayer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Dispatcher)
+
+ data->ref++;
+
+ return DR_OK;
+}
+
+static DirectResult
+IVoodooPlayer_Dispatcher_Release( IVoodooPlayer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Dispatcher)
+
+ if (--data->ref == 0)
+ IVoodooPlayer_Dispatcher_Destruct( thiz );
+
+ return DR_OK;
+}
+
+static DirectResult
+IVoodooPlayer_Dispatcher_GetApps( IVoodooPlayer *thiz,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppDescription *ret_applications )
+{
+ return DR_UNIMPLEMENTED;
+}
+
+static DirectResult
+IVoodooPlayer_Dispatcher_LaunchApp( IVoodooPlayer *thiz,
+ const u8 app_uuid[16],
+ const u8 player_uuid[16],
+ u8 ret_instance_uuid[16] )
+{
+ return DR_UNIMPLEMENTED;
+}
+
+static DirectResult
+IVoodooPlayer_Dispatcher_StopInstance( IVoodooPlayer *thiz,
+ const u8 instance_uuid[16] )
+{
+ return DR_UNIMPLEMENTED;
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+Dispatch_GetApps( IVoodooPlayer *thiz, IVoodooPlayer *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ unsigned int max_num;
+ VoodooMessageParser parser;
+ unsigned int num;
+ VoodooAppDescription *apps;
+
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_UINT( parser, max_num );
+ VOODOO_PARSER_END( parser );
+
+ if (max_num > 1000)
+ return DR_LIMITEXCEEDED;
+
+ apps = D_MALLOC( max_num * sizeof(VoodooAppDescription) );
+ if (!apps)
+ return D_OOM();
+
+ ret = real->GetApps( real, max_num, &num, apps );
+ if (ret == DR_OK) {
+ if (num > 0) {
+ ret = voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, VOODOO_INSTANCE_NONE,
+ VMBT_UINT, num,
+ VMBT_DATA, num * sizeof(VoodooAppDescription), apps,
+ VMBT_NONE );
+ }
+ else {
+ ret = voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, VOODOO_INSTANCE_NONE,
+ VMBT_UINT, num,
+ VMBT_NONE );
+ }
+ }
+
+ D_FREE( apps );
+
+ return ret;
+}
+
+static DirectResult
+Dispatch_LaunchApp( IVoodooPlayer *thiz, IVoodooPlayer *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ VoodooMessageParser parser;
+ const u8 *app_uuid;
+ const u8 *player_uuid;
+ u8 instance_uuid[16];
+
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_DATA( parser, app_uuid );
+ VOODOO_PARSER_GET_DATA( parser, player_uuid );
+ VOODOO_PARSER_END( parser );
+
+ ret = real->LaunchApp( real, app_uuid, player_uuid, instance_uuid );
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, VOODOO_INSTANCE_NONE,
+ VMBT_DATA, 16, instance_uuid,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_StopInstance( IVoodooPlayer *thiz, IVoodooPlayer *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ VoodooMessageParser parser;
+ const u8 *instance_uuid;
+
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_DATA( parser, instance_uuid );
+ VOODOO_PARSER_END( parser );
+
+ ret = real->StopInstance( real, instance_uuid );
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, VOODOO_INSTANCE_NONE,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_WaitInstance( IVoodooPlayer *thiz, IVoodooPlayer *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ VoodooMessageParser parser;
+ const u8 *instance_uuid;
+
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_DATA( parser, instance_uuid );
+ VOODOO_PARSER_END( parser );
+
+ ret = real->WaitInstance( real, instance_uuid );
+
+ return voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, VOODOO_INSTANCE_NONE,
+ VMBT_NONE );
+}
+
+static DirectResult
+Dispatch_GetInstances( IVoodooPlayer *thiz, IVoodooPlayer *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DirectResult ret;
+ unsigned int max_num;
+ VoodooMessageParser parser;
+ unsigned int num;
+ VoodooAppInstanceDescription *instances;
+
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_UINT( parser, max_num );
+ VOODOO_PARSER_END( parser );
+
+ if (max_num > 1000)
+ return DR_LIMITEXCEEDED;
+
+ instances = D_MALLOC( max_num * sizeof(VoodooAppInstanceDescription) );
+ if (!instances)
+ return D_OOM();
+
+ ret = real->GetInstances( real, max_num, &num, instances );
+ if (ret == DR_OK) {
+ if (num > 0) {
+ ret = voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, VOODOO_INSTANCE_NONE,
+ VMBT_UINT, num,
+ VMBT_DATA, num * sizeof(VoodooAppInstanceDescription), instances,
+ VMBT_NONE );
+ }
+ else {
+ ret = voodoo_manager_respond( manager, true, msg->header.serial,
+ ret, VOODOO_INSTANCE_NONE,
+ VMBT_UINT, num,
+ VMBT_NONE );
+ }
+ }
+
+ D_FREE( instances );
+
+ return ret;
+}
+
+static DirectResult
+Dispatch( void *dispatcher, void *real, VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ D_DEBUG( "IVoodooPlayer/Dispatcher: "
+ "Handling request for instance %u with method %u...\n", msg->instance, msg->method );
+
+ switch (msg->method) {
+ case IVOODOOPLAYER_METHOD_ID_GetApps:
+ return Dispatch_GetApps( dispatcher, real, manager, msg );
+
+ case IVOODOOPLAYER_METHOD_ID_LaunchApp:
+ return Dispatch_LaunchApp( dispatcher, real, manager, msg );
+
+ case IVOODOOPLAYER_METHOD_ID_StopInstance:
+ return Dispatch_StopInstance( dispatcher, real, manager, msg );
+
+ case IVOODOOPLAYER_METHOD_ID_WaitInstance:
+ return Dispatch_WaitInstance( dispatcher, real, manager, msg );
+
+ case IVOODOOPLAYER_METHOD_ID_GetInstances:
+ return Dispatch_GetInstances( dispatcher, real, manager, msg );
+ }
+
+ return DR_NOSUCHMETHOD;
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+Probe()
+{
+ /* This implementation has to be loaded explicitly. */
+ return DR_UNSUPPORTED;
+}
+
+/*
+ * Constructor
+ *
+ * Fills in function pointers and intializes data structure.
+ */
+static DirectResult
+Construct( IVoodooPlayer *thiz, VoodooManager *manager, VoodooInstanceID *ret_instance )
+{
+ DirectResult ret;
+ IVoodooPlayer *real;
+ VoodooInstanceID instance;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IVoodooPlayer_Dispatcher)
+
+ ret = VoodooPlayerCreate( &real );
+ if (ret) {
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ ret = voodoo_manager_register_local( manager, VOODOO_INSTANCE_NONE, thiz, real, Dispatch, &instance );
+ if (ret) {
+ real->Release( real );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ *ret_instance = instance;
+
+ data->ref = 1;
+ data->real = real;
+ data->self = instance;
+
+ thiz->AddRef = IVoodooPlayer_Dispatcher_AddRef;
+ thiz->Release = IVoodooPlayer_Dispatcher_Release;
+ thiz->GetApps = IVoodooPlayer_Dispatcher_GetApps;
+ thiz->LaunchApp = IVoodooPlayer_Dispatcher_LaunchApp;
+ thiz->StopInstance = IVoodooPlayer_Dispatcher_StopInstance;
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/ivoodooplayer_dispatcher.h b/Source/DirectFB/lib/voodoo/ivoodooplayer_dispatcher.h
new file mode 100755
index 0000000..a01d0d9
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/ivoodooplayer_dispatcher.h
@@ -0,0 +1,41 @@
+/*
+ (c) Copyright 2001-2010 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IVOODOOPLAYER_DISPATCHER_H__
+#define __IVOODOOPLAYER_DISPATCHER_H__
+
+#define IVOODOOPLAYER_METHOD_ID_AddRef 1
+#define IVOODOOPLAYER_METHOD_ID_Release 2
+#define IVOODOOPLAYER_METHOD_ID_GetApps 3
+#define IVOODOOPLAYER_METHOD_ID_LaunchApp 4
+#define IVOODOOPLAYER_METHOD_ID_StopInstance 5
+#define IVOODOOPLAYER_METHOD_ID_WaitInstance 6
+#define IVOODOOPLAYER_METHOD_ID_GetInstances 7
+
+#endif
+
diff --git a/Source/DirectFB/lib/voodoo/ivoodooplayer_requestor.c b/Source/DirectFB/lib/voodoo/ivoodooplayer_requestor.c
new file mode 100755
index 0000000..1ffdcf9
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/ivoodooplayer_requestor.c
@@ -0,0 +1,330 @@
+/*
+ (c) Copyright 2001-2010 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/messages.h>
+
+#include <voodoo/ivoodooplayer.h>
+
+#include <voodoo/client.h>
+#include <voodoo/interface.h>
+#include <voodoo/manager.h>
+#include <voodoo/message.h>
+
+#include "ivoodooplayer_dispatcher.h"
+
+
+static DirectResult Probe( void );
+static DirectResult Construct( IVoodooPlayer *thiz, const char *host, int session );
+
+#include <direct/interface_implementation.h>
+
+DIRECT_INTERFACE_IMPLEMENTATION( IVoodooPlayer, Requestor )
+
+
+/**************************************************************************************************/
+
+/*
+ * private data struct of IVoodooPlayer_Requestor
+ */
+typedef struct {
+ int ref; /* reference counter */
+
+ VoodooClient *client;
+ VoodooManager *manager;
+
+ VoodooInstanceID instance;
+} IVoodooPlayer_Requestor_data;
+
+/**************************************************************************************************/
+
+static void
+IVoodooPlayer_Requestor_Destruct( IVoodooPlayer *thiz )
+{
+ IVoodooPlayer_Requestor_data *data = thiz->priv;
+
+ D_DEBUG( "%s (%p)\n", __FUNCTION__, thiz );
+
+ voodoo_client_destroy( data->client );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+IVoodooPlayer_Requestor_AddRef( IVoodooPlayer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Requestor)
+
+ data->ref++;
+
+ return DR_OK;
+}
+
+static DirectResult
+IVoodooPlayer_Requestor_Release( IVoodooPlayer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Requestor)
+
+ if (--data->ref == 0)
+ IVoodooPlayer_Requestor_Destruct( thiz );
+
+ return DR_OK;
+}
+
+static DirectResult
+IVoodooPlayer_Requestor_GetApps( IVoodooPlayer *thiz,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppDescription *ret_applications )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+
+ if (!max_num || !ret_num || !ret_applications)
+ return DR_INVARG;
+
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Requestor)
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IVOODOOPLAYER_METHOD_ID_GetApps, VREQ_RESPOND, &response,
+ VMBT_UINT, max_num,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret == DR_OK) {
+ VoodooMessageParser parser;
+ unsigned int num;
+
+ VOODOO_PARSER_BEGIN( parser, response );
+ VOODOO_PARSER_GET_UINT( parser, num );
+
+ if (num > max_num)
+ num = max_num;
+
+ *ret_num = num;
+
+ if (num > 0)
+ VOODOO_PARSER_READ_DATA( parser, ret_applications, num * sizeof(VoodooAppDescription) );
+
+ VOODOO_PARSER_END( parser );
+ }
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ return ret;
+}
+
+static DirectResult
+IVoodooPlayer_Requestor_LaunchApp( IVoodooPlayer *thiz,
+ const u8 app_uuid[16],
+ const u8 player_uuid[16],
+ u8 ret_instance_uuid[16] )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+
+ if (!app_uuid || !player_uuid || !ret_instance_uuid)
+ return DR_INVARG;
+
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Requestor)
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IVOODOOPLAYER_METHOD_ID_LaunchApp, VREQ_RESPOND, &response,
+ VMBT_DATA, 16, app_uuid,
+ VMBT_DATA, 16, player_uuid,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret == DR_OK) {
+ VoodooMessageParser parser;
+
+ VOODOO_PARSER_BEGIN( parser, response );
+ VOODOO_PARSER_READ_DATA( parser, ret_instance_uuid, 16 );
+ VOODOO_PARSER_END( parser );
+ }
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ return ret;
+}
+
+static DirectResult
+IVoodooPlayer_Requestor_StopInstance( IVoodooPlayer *thiz,
+ const u8 instance_uuid[16] )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+
+ if (!instance_uuid)
+ return DR_INVARG;
+
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Requestor)
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IVOODOOPLAYER_METHOD_ID_StopInstance, VREQ_RESPOND, &response,
+ VMBT_DATA, 16, instance_uuid,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ return ret;
+}
+
+static DirectResult
+IVoodooPlayer_Requestor_WaitInstance( IVoodooPlayer *thiz,
+ const u8 instance_uuid[16] )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+
+ if (!instance_uuid)
+ return DR_INVARG;
+
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Requestor)
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IVOODOOPLAYER_METHOD_ID_WaitInstance, VREQ_RESPOND, &response,
+ VMBT_DATA, 16, instance_uuid,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ return ret;
+}
+
+static DirectResult
+IVoodooPlayer_Requestor_GetInstances( IVoodooPlayer *thiz,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppInstanceDescription *ret_instances )
+{
+ DirectResult ret;
+ VoodooResponseMessage *response;
+
+ if (!max_num || !ret_num || !ret_instances)
+ return DR_INVARG;
+
+ DIRECT_INTERFACE_GET_DATA(IVoodooPlayer_Requestor)
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IVOODOOPLAYER_METHOD_ID_GetInstances, VREQ_RESPOND, &response,
+ VMBT_UINT, max_num,
+ VMBT_NONE );
+ if (ret)
+ return ret;
+
+ ret = response->result;
+ if (ret == DR_OK) {
+ VoodooMessageParser parser;
+ unsigned int num;
+
+ VOODOO_PARSER_BEGIN( parser, response );
+ VOODOO_PARSER_GET_UINT( parser, num );
+
+ if (num > max_num)
+ num = max_num;
+
+ *ret_num = num;
+
+ if (num > 0)
+ VOODOO_PARSER_READ_DATA( parser, ret_instances, num * sizeof(VoodooAppInstanceDescription) );
+
+ VOODOO_PARSER_END( parser );
+ }
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ return ret;
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+Probe()
+{
+ /* This implementation has to be loaded explicitly. */
+ return DR_UNSUPPORTED;
+}
+
+/*
+ * Constructor
+ *
+ * Fills in function pointers and intializes data structure.
+ */
+static DirectResult
+Construct( IVoodooPlayer *thiz, const char *host, int session )
+{
+ DirectResult ret;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IVoodooPlayer_Requestor)
+
+ data->ref = 1;
+
+ ret = voodoo_client_create( host, session, &data->client );
+ if (ret) {
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ data->manager = voodoo_client_manager( data->client );
+
+ ret = voodoo_manager_super( data->manager, "IVoodooPlayer", &data->instance );
+ if (ret) {
+ voodoo_client_destroy( data->client );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ thiz->AddRef = IVoodooPlayer_Requestor_AddRef;
+ thiz->Release = IVoodooPlayer_Requestor_Release;
+ thiz->GetApps = IVoodooPlayer_Requestor_GetApps;
+ thiz->LaunchApp = IVoodooPlayer_Requestor_LaunchApp;
+ thiz->StopInstance = IVoodooPlayer_Requestor_StopInstance;
+ thiz->WaitInstance = IVoodooPlayer_Requestor_WaitInstance;
+ thiz->GetInstances = IVoodooPlayer_Requestor_GetInstances;
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/link.h b/Source/DirectFB/lib/voodoo/link.h
new file mode 100755
index 0000000..e54b1d4
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/link.h
@@ -0,0 +1,78 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__LINK_H__
+#define __VOODOO__LINK_H__
+
+#include <voodoo/types.h>
+
+
+typedef struct {
+ void *ptr;
+ size_t length;
+ size_t done;
+} VoodooChunk;
+
+
+struct __V_VoodooLink {
+ void *priv;
+ u32 code;
+
+ void (*Close)( VoodooLink *link );
+
+ /* See 'read(2)', blocking */
+ ssize_t (*Read) ( VoodooLink *link,
+ void *buffer,
+ size_t count );
+
+ /* See 'write(2)', blocking */
+ ssize_t (*Write)( VoodooLink *link,
+ const void *buffer,
+ size_t count );
+
+
+ /* For later... */
+ DirectResult (*SendReceive)( VoodooLink *link,
+ VoodooChunk *send,
+ size_t num_send,
+ VoodooChunk *recv,
+ size_t num_recv );
+
+ DirectResult (*WakeUp) ( VoodooLink *link );
+};
+
+
+DirectResult VOODOO_API voodoo_link_init_connect( VoodooLink *link,
+ const char *hostname,
+ int port,
+ bool raw );
+
+DirectResult VOODOO_API voodoo_link_init_fd ( VoodooLink *link,
+ int fd[2] );
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/manager.cpp b/Source/DirectFB/lib/voodoo/manager.cpp
new file mode 100755
index 0000000..3b2f70c
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/manager.cpp
@@ -0,0 +1,937 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#include <algorithm>
+
+extern "C" {
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <voodoo/conf.h>
+#include <voodoo/internal.h>
+#include <voodoo/link.h>
+}
+
+#include <voodoo/connection_packet.h>
+#include <voodoo/connection_raw.h>
+#include <voodoo/dispatcher.h>
+#include <voodoo/manager.h>
+#include <voodoo/packet.h>
+
+
+//namespace Voodoo {
+
+D_DEBUG_DOMAIN( Voodoo_Dispatch, "Voodoo/Dispatch", "Voodoo Dispatch" );
+D_DEBUG_DOMAIN( Voodoo_Manager, "Voodoo/Manager", "Voodoo Manager" );
+
+/**********************************************************************************************************************/
+
+VoodooManager::VoodooManager( VoodooLink *link,
+ VoodooContext *context )
+ :
+ magic(0),
+ is_quit(false),
+ msg_count(0),
+ msg_serial(0)
+{
+ D_ASSERT( link != NULL );
+
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ /* Store link and context */
+ this->link = link;
+ this->context = context;
+
+
+ instances.last = 0;
+
+ response.current = NULL;
+
+
+ /* Initialize all locks. */
+ direct_recursive_mutex_init( &instances.lock );
+ direct_recursive_mutex_init( &response.lock );
+
+ /* Initialize all wait conditions. */
+ direct_waitqueue_init( &response.wait_get );
+ direct_waitqueue_init( &response.wait_put );
+
+ D_MAGIC_SET( this, VoodooManager );
+
+
+ dispatcher = new VoodooDispatcher( this );
+
+
+ /* Add connection */
+ if ((link->code & 0x8000ffff) == 0x80008676) {
+ D_INFO( "Voodoo/Manager: Connection mode is PACKET\n" );
+
+ connection = new VoodooConnectionPacket( this, link );
+ }
+ else {
+ D_INFO( "Voodoo/Manager: Connection mode is RAW\n" );
+
+ connection = new VoodooConnectionRaw( this, link );
+
+ // FIXME: query manager dynamically for compression instead
+ voodoo_config->compression_min = 0;
+ }
+
+ connection->Start();
+}
+
+static void
+instance_iterator( std::pair<VoodooInstanceID,VoodooInstance*> pair )
+{
+ D_DEBUG_AT( Voodoo_Manager, "%s( id %u, instance %p )\n", __func__, pair.first, pair.second );
+
+ pair.second->Release();
+}
+
+VoodooManager::~VoodooManager()
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+
+ if (!is_quit)
+ quit();
+
+ connection->Stop();
+
+ /* Destroy dispatcher */
+ delete dispatcher;
+
+ /* Remove connection */
+ delete connection;
+
+ /* Destroy conditions. */
+ direct_waitqueue_deinit( &response.wait_get );
+ direct_waitqueue_deinit( &response.wait_put );
+
+ /* Destroy locks. */
+ direct_mutex_deinit( &instances.lock );
+ direct_mutex_deinit( &response.lock );
+
+ /* Release all remaining interfaces. */
+ std::for_each( instances.remote.begin(), instances.remote.end(), instance_iterator );
+ std::for_each( instances.local.begin(), instances.local.end(), instance_iterator );
+
+ D_MAGIC_CLEAR( this );
+}
+
+/**********************************************************************************************************************/
+
+void
+VoodooManager::DispatchPacket( VoodooPacket *packet )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p, packet %p )\n", __func__, this, packet );
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSUME( !is_quit );
+
+ if (is_quit)
+ return;
+
+ dispatcher->PutPacket( packet );
+}
+
+bool
+VoodooManager::DispatchReady()
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+// D_ASSUME( !is_quit );
+
+ if (is_quit)
+ return false;
+
+ return dispatcher->Ready();
+}
+
+/**********************************************************************************************************************/
+
+void
+VoodooManager::quit()
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSUME( !is_quit );
+
+ if (is_quit)
+ return;
+
+ /* Have all threads quit upon this. */
+ is_quit = true;
+
+ /* Acquire locks and wake up waiters. */
+ direct_mutex_lock( &response.lock );
+ direct_waitqueue_broadcast( &response.wait_get );
+ direct_waitqueue_broadcast( &response.wait_put );
+ direct_mutex_unlock( &response.lock );
+}
+
+void
+VoodooManager::handle_disconnect()
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Remote site disconnected from manager at %p!\n", this );
+
+ quit();
+}
+
+void
+VoodooManager::handle_super( VoodooSuperMessage *super )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ DirectResult ret;
+ const char *name;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( super != NULL );
+ D_ASSERT( super->header.size >= (int) sizeof(VoodooSuperMessage) );
+ D_ASSERT( super->header.type == VMSG_SUPER );
+
+ name = (const char *) (super + 1);
+
+ D_DEBUG_AT( Voodoo_Dispatch, " -> Handling SUPER message %llu for '%s' (%d bytes).\n",
+ (unsigned long long)super->header.serial, name, super->header.size );
+
+ VoodooInstanceID instance_id;
+
+ ret = context->HandleSuper( this, name, &instance_id );
+ if (ret)
+ do_respond( true, super->header.serial, ret );
+ else
+ do_respond( true, super->header.serial, DR_OK, instance_id );
+}
+
+typedef struct {
+ VoodooManager *manager;
+ VoodooInstance *instance;
+ VoodooRequestMessage *request;
+} DispatchAsyncContext;
+
+void *
+VoodooManager::dispatch_async_thread( DirectThread *thread,
+ void *arg )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, arg );
+
+ DirectResult ret;
+ DispatchAsyncContext *context = (DispatchAsyncContext*) arg;
+ VoodooManager *manager = context->manager;
+ VoodooInstance *instance = context->instance;
+ VoodooRequestMessage *request = context->request;
+
+ ret = instance->Dispatch( manager, request );
+
+ if (ret && (request->flags & VREQ_RESPOND))
+ manager->do_respond( true, request->header.serial, ret );
+
+ D_FREE( context );
+
+ return NULL;
+}
+
+void
+VoodooManager::handle_request( VoodooRequestMessage *request )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ DirectResult ret;
+ VoodooInstance *instance;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( request != NULL );
+ D_ASSERT( request->header.size >= (int) sizeof(VoodooRequestMessage) );
+ D_ASSERT( request->header.type == VMSG_REQUEST );
+
+ D_DEBUG_AT( Voodoo_Dispatch, " -> Handling REQUEST message %llu to %u::%u %s%s(%d bytes).\n",
+ (unsigned long long)request->header.serial, request->instance, request->method,
+ (request->flags & VREQ_RESPOND) ? "[RESPONDING] " : "",
+ (request->flags & VREQ_ASYNC) ? "[ASYNC] " : "",
+ request->header.size );
+
+ direct_mutex_lock( &instances.lock );
+
+ InstanceMap::iterator itr = instances.local.find( request->instance );
+
+ if (itr == instances.local.end()) {
+ direct_mutex_unlock( &instances.lock );
+
+ D_ERROR( "Voodoo/Dispatch: "
+ "Requested instance %u doesn't exist (anymore)!\n", request->instance );
+
+ if (request->flags & VREQ_RESPOND)
+ do_respond( true, request->header.serial, DR_NOSUCHINSTANCE );
+
+ return;
+ }
+
+ instance = (*itr).second;
+
+ if (request->flags & VREQ_ASYNC) {
+ DirectThread *thread;
+ DispatchAsyncContext *context;
+
+ context = (DispatchAsyncContext*) D_MALLOC( sizeof(DispatchAsyncContext) + request->header.size );
+ if (!context) {
+ D_WARN( "out of memory" );
+ direct_mutex_unlock( &instances.lock );
+ return;
+ }
+
+ context->manager = this;
+ context->instance = instance;
+ context->request = (VoodooRequestMessage*) (context + 1);
+
+ direct_memcpy( context->request, request, request->header.size );
+
+ thread = direct_thread_create( DTT_DEFAULT, dispatch_async_thread, context, "Voodoo Async" );
+ direct_thread_detach( thread );
+ // FIXME: free thread?
+ }
+ else {
+ ret = instance->Dispatch( this, request );
+
+ if (ret && (request->flags & VREQ_RESPOND))
+ do_respond( true, request->header.serial, ret );
+ }
+
+ direct_mutex_unlock( &instances.lock );
+}
+
+void
+VoodooManager::handle_response( VoodooResponseMessage *msg )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( msg != NULL );
+ D_ASSERT( msg->header.size >= (int) sizeof(VoodooResponseMessage) );
+ D_ASSERT( msg->header.type == VMSG_RESPONSE );
+ D_ASSERT( msg->request < msg_serial );
+
+ D_DEBUG_AT( Voodoo_Dispatch, " -> Handling RESPONSE message %llu (%s) with instance %u for request "
+ "%llu (%d bytes).\n", (unsigned long long)msg->header.serial, DirectResultString( msg->result ),
+ msg->instance, (unsigned long long)msg->request, msg->header.size );
+
+ direct_mutex_lock( &response.lock );
+
+ D_ASSERT( response.current == NULL );
+
+ response.current = msg;
+
+ direct_mutex_unlock( &response.lock );
+
+
+ direct_waitqueue_broadcast( &response.wait_get );
+
+ direct_mutex_lock( &response.lock );
+
+ while (response.current && !is_quit)
+ direct_waitqueue_wait( &response.wait_put, &response.lock );
+
+ direct_mutex_unlock( &response.lock );
+}
+
+/**************************************************************************************************/
+
+DirectResult
+VoodooManager::lock_response( VoodooMessageSerial request,
+ VoodooResponseMessage **ret_response )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ VoodooResponseMessage *msg = NULL;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( ret_response != NULL );
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Locking response to request %llu...\n", (unsigned long long)request );
+
+ direct_mutex_lock( &response.lock );
+
+ while (!is_quit) {
+ msg = response.current;
+ if (msg && msg->request == request)
+ break;
+
+ if (msg)
+ D_DEBUG_AT( Voodoo_Manager, " -> ...current response is for request %llu...\n", (unsigned long long)msg->request );
+
+ D_DEBUG_AT( Voodoo_Manager, " -> ...(still) waiting for response to request %llu...\n", (unsigned long long)request );
+
+ direct_waitqueue_wait( &response.wait_get, &response.lock );
+ }
+
+ if (is_quit) {
+ D_ERROR( "Voodoo/Manager: Quit while waiting for response!\n" );
+ direct_mutex_unlock( &response.lock );
+ return DR_DESTROYED;
+ }
+
+ D_DEBUG_AT( Voodoo_Manager, " -> ...locked response %llu to request %llu (%d bytes).\n",
+ (unsigned long long)msg->header.serial, (unsigned long long)request, msg->header.size );
+
+ *ret_response = msg;
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooManager::unlock_response( VoodooResponseMessage *msg )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( msg != NULL );
+ D_ASSERT( msg == response.current );
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Unlocking response %llu to request %llu (%d bytes)...\n",
+ (unsigned long long)msg->header.serial, (unsigned long long)msg->request, msg->header.size );
+
+ response.current = NULL;
+
+ direct_mutex_unlock( &response.lock );
+
+ direct_waitqueue_broadcast( &response.wait_put );
+
+ return DR_OK;
+}
+
+
+
+
+DirectResult
+VoodooManager::do_super( const char *name,
+ VoodooInstanceID *ret_instance )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ DirectResult ret;
+ int len;
+ int size;
+ VoodooPacket *packet;
+ VoodooMessageSerial serial;
+ VoodooSuperMessage *msg;
+ VoodooResponseMessage *response;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( name != NULL );
+ D_ASSERT( ret_instance != NULL );
+
+ if (is_quit) {
+ D_DEBUG_AT( Voodoo_Manager, " -> QUIT!\n" );
+ return DR_IO;
+ }
+
+ /* Calculate the total message size. */
+ len = strlen( name ) + 1;
+ size = sizeof(VoodooSuperMessage) + len;
+
+
+ /* Lock the output buffer for direct writing. */
+ packet = connection->GetPacket( size );
+ if (!packet)
+ return DR_FAILURE;
+
+ msg = (VoodooSuperMessage*) packet->data_raw();
+
+ serial = msg_serial++;
+
+ /* Fill message header. */
+ msg->header.size = size;
+ msg->header.serial = serial;
+ msg->header.type = VMSG_SUPER;
+
+ /* Append the name of the super interface to create. */
+ direct_memcpy( msg + 1, name, len );
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Sending SUPER message %llu for '%s' (%d bytes).\n", (unsigned long long)serial, name, size );
+
+ /* Unlock the output buffer. */
+ connection->PutPacket( packet, true );
+
+
+ /* Wait for and lock the response buffer. */
+ ret = lock_response( serial, &response );
+ if (ret) {
+ D_ERROR( "Voodoo/Manager: "
+ "Waiting for the response failed (%s)!\n", DirectResultString( ret ) );
+ return ret;
+ }
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Got response %llu (%s) with instance %u for request %llu "
+ "(%d bytes).\n", (unsigned long long)response->header.serial, DirectResultString( ret ),
+ response->instance, (unsigned long long)response->request, response->header.size );
+
+ ret = response->result;
+ if (ret) {
+ D_ERROR( "Voodoo/Manager: Could not create remote super interface '%s' (%s)!\n",
+ name, DirectResultString( ret ) );
+ unlock_response( response );
+ return ret;
+ }
+
+ D_INFO( "Voodoo/Manager: Created remote super interface '%s'.\n", name );
+
+ /* Return the new instance ID. */
+ *ret_instance = response->instance;
+
+ /* Unlock the response buffer. */
+ unlock_response( response );
+
+ return DR_OK;
+}
+
+void
+VoodooManager::write_blocks( void *dst,
+ const VoodooMessageBlock *blocks,
+ size_t num )
+{
+ size_t i;
+ u32 *d32 = (u32*) dst;
+
+ for (i=0; i<num; i++) {
+ /* Write block type and length. */
+ d32[0] = blocks[i].type;
+ d32[1] = blocks[i].len;
+
+ /* Write block content. */
+ if (blocks[i].ptr) {
+ u32 *s32 = (u32*) blocks[i].ptr;
+
+ switch (blocks[i].len) {
+ case 16:
+ d32[5] = s32[3];
+ case 12:
+ d32[4] = s32[2];
+ case 8:
+ d32[3] = s32[1];
+ case 4:
+ d32[2] = s32[0];
+ break;
+
+ default:
+ direct_memcpy( &d32[2], blocks[i].ptr, blocks[i].len );
+ }
+ }
+ else if (blocks[i].len) {
+ D_ASSERT( blocks[i].len == 4 );
+
+ d32[2] = blocks[i].val;
+ }
+
+ /* Advance message data pointer. */
+ d32 += 2 + (VOODOO_MSG_ALIGN(blocks[i].len) >> 2);
+ }
+
+ /* Write terminator. */
+ d32[0] = VMBT_NONE;
+}
+
+DirectResult
+VoodooManager::do_request( VoodooInstanceID instance,
+ VoodooMethodID method,
+ VoodooRequestFlags flags,
+ VoodooResponseMessage **ret_response,
+ VoodooMessageBlock *blocks,
+ size_t num_blocks,
+ size_t data_size )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ DirectResult ret;
+ size_t size;
+ VoodooPacket *packet;
+ VoodooMessageSerial serial;
+ VoodooRequestMessage *msg;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( instance != VOODOO_INSTANCE_NONE );
+ D_ASSERT( ret_response != NULL || !(flags & VREQ_RESPOND) );
+ D_ASSUME( (flags & (VREQ_RESPOND | VREQ_QUEUE)) != (VREQ_RESPOND | VREQ_QUEUE) );
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Instance %u, method %u, flags 0x%08x...\n", instance, method, flags );
+
+ if (is_quit) {
+ D_DEBUG_AT( Voodoo_Manager, " -> QUIT!\n" );
+ return DR_IO;
+ }
+
+ /* Calculate the total message size. */
+ size = sizeof(VoodooRequestMessage) + data_size;
+
+ D_DEBUG_AT( Voodoo_Manager, " -> complete message size: %d\n", size );
+
+ /* Lock the output buffer for direct writing. */
+ packet = connection->GetPacket( size );
+ if (!packet)
+ return DR_FAILURE;
+
+ msg = (VoodooRequestMessage*) packet->data_raw();
+
+ serial = msg_serial++;
+
+ /* Fill message header. */
+ msg->header.size = size;
+ msg->header.serial = serial;
+ msg->header.type = VMSG_REQUEST;
+
+ /* Fill message body. */
+ msg->instance = instance;
+ msg->method = method;
+ msg->flags = flags;
+
+ /* Append custom data. */
+ write_blocks( msg + 1, blocks, num_blocks );
+
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Sending REQUEST message %llu to %u::%u %s(%d bytes).\n",
+ (unsigned long long)serial, instance, method, (flags & VREQ_RESPOND) ? "[RESPONDING] " : "", size );
+
+ /* Unlock the output buffer. */
+ connection->PutPacket( packet, !(flags & VREQ_QUEUE) );
+
+ /* Wait for and lock the response buffer. */
+ if (flags & VREQ_RESPOND) {
+ VoodooResponseMessage *response;
+
+ ret = lock_response( serial, &response );
+ if (ret) {
+ D_ERROR( "Voodoo/Manager: "
+ "Waiting for the response failed (%s)!\n", DirectResultString( ret ) );
+ return ret;
+ }
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Got response %llu (%s) with instance %u for request %llu "
+ "(%d bytes).\n", (unsigned long long)response->header.serial, DirectResultString( response->result ),
+ response->instance, (unsigned long long)response->request, response->header.size );
+
+ *ret_response = response;
+ }
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooManager::next_response( VoodooResponseMessage *response,
+ VoodooResponseMessage **ret_response )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ DirectResult ret;
+ VoodooMessageSerial serial;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( response != NULL );
+
+ serial = response->request;
+
+ /* Unlock the response buffer. */
+ unlock_response( response );
+
+ ret = lock_response( serial, &response );
+ if (ret) {
+ D_ERROR( "Voodoo/Manager: "
+ "Waiting for the response failed (%s)!\n", DirectResultString( ret ) );
+ return ret;
+ }
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Got response %llu (%s) with instance %u for request %llu "
+ "(%d bytes).\n", (unsigned long long)response->header.serial, DirectResultString( response->result ),
+ response->instance, (unsigned long long)response->request, response->header.size );
+
+ *ret_response = response;
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooManager::finish_request( VoodooResponseMessage *response )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( response != NULL );
+
+ /* Unlock the response buffer. */
+ return unlock_response( response );
+}
+
+DirectResult
+VoodooManager::do_respond( bool flush,
+ VoodooMessageSerial request,
+ DirectResult result,
+ VoodooInstanceID instance,
+ VoodooMessageBlock *blocks,
+ size_t num_blocks,
+ size_t data_size )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ size_t size;
+ VoodooPacket *packet;
+ VoodooMessageSerial serial;
+ VoodooResponseMessage *msg;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Request %llu, result %d, instance %u...\n", (unsigned long long)request, result, instance );
+
+ if (is_quit) {
+ D_DEBUG_AT( Voodoo_Manager, " -> QUIT!\n" );
+ return DR_IO;
+ }
+
+ /* Calculate the total message size. */
+ size = sizeof(VoodooResponseMessage) + data_size;
+
+ D_DEBUG_AT( Voodoo_Manager, " -> complete message size: %d\n", size );
+
+
+ /* Lock the output buffer for direct writing. */
+ packet = connection->GetPacket( size );
+ if (!packet)
+ return DR_FAILURE;
+
+ msg = (VoodooResponseMessage*) packet->data_raw();
+
+ serial = msg_serial++;
+
+ /* Fill message header. */
+ msg->header.size = size;
+ msg->header.serial = serial;
+ msg->header.type = VMSG_RESPONSE;
+
+ /* Fill message body. */
+ msg->request = request;
+ msg->result = result;
+ msg->instance = instance;
+
+ /* Append custom data. */
+ write_blocks( msg + 1, blocks, num_blocks );
+
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Sending RESPONSE message %llu (%s) with instance %u for request %llu (%d bytes).\n",
+ (unsigned long long)serial, DirectResultString( result ), instance, (unsigned long long)request, size );
+
+ /* Unlock the output buffer. */
+ connection->PutPacket( packet, flush );
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooManager::register_local( VoodooInstance *instance,
+ VoodooInstanceID *ret_instance )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ VoodooInstanceID instance_id;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( instance != NULL );
+ D_ASSERT( ret_instance != NULL );
+
+ instance->AddRef();
+
+ direct_mutex_lock( &instances.lock );
+
+ instance_id = ++instances.last;
+
+ instances.local[instance_id] = instance;
+
+ direct_mutex_unlock( &instances.lock );
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Added local instance %u (%p)\n", instance_id, instance );
+
+ *ret_instance = instance_id;
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooManager::unregister_local( VoodooInstanceID instance_id )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ VoodooInstance *instance;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+
+ direct_mutex_lock( &instances.lock );
+
+ InstanceMap::iterator itr = instances.local.find( instance_id );
+
+ if (itr == instances.local.end()) {
+ direct_mutex_unlock( &instances.lock );
+ return DR_NOSUCHINSTANCE;
+ }
+
+ instance = (*itr).second;
+
+ instances.local.erase( itr );
+
+ direct_mutex_unlock( &instances.lock );
+
+ instance->Release();
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooManager::lookup_local( VoodooInstanceID instance_id,
+ VoodooInstance **ret_instance )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ VoodooInstance *instance;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( instance_id != VOODOO_INSTANCE_NONE );
+ D_ASSERT( ret_instance != NULL );
+
+ direct_mutex_lock( &instances.lock );
+
+ InstanceMap::iterator itr = instances.local.find( instance_id );
+
+ direct_mutex_unlock( &instances.lock );
+
+ if (itr == instances.local.end())
+ return DR_NOSUCHINSTANCE;
+
+ instance = (*itr).second;
+
+ // FIXME: addref?
+
+ *ret_instance = instance;
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooManager::register_remote( VoodooInstance *instance,
+ VoodooInstanceID instance_id )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( instance != NULL );
+ D_ASSERT( instance_id != VOODOO_INSTANCE_NONE );
+
+ instance->AddRef();
+
+ direct_mutex_lock( &instances.lock );
+
+ instances.remote[instance_id] = instance;
+
+ direct_mutex_unlock( &instances.lock );
+
+ D_DEBUG_AT( Voodoo_Manager, " -> Added remote instance %u (%p)\n", instance_id, instance );
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooManager::unregister_remote( VoodooInstanceID instance_id )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ VoodooInstance *instance;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+
+ direct_mutex_lock( &instances.lock );
+
+ InstanceMap::iterator itr = instances.remote.find( instance_id );
+
+ if (itr == instances.remote.end()) {
+ direct_mutex_unlock( &instances.lock );
+ return DR_NOSUCHINSTANCE;
+ }
+
+ instance = (*itr).second;
+
+ instances.remote.erase( itr );
+
+ direct_mutex_unlock( &instances.lock );
+
+ instance->Release();
+
+ return DR_OK;
+}
+
+DirectResult
+VoodooManager::lookup_remote( VoodooInstanceID instance_id,
+ VoodooInstance **ret_instance )
+{
+ D_DEBUG_AT( Voodoo_Manager, "VoodooManager::%s( %p )\n", __func__, this );
+
+ VoodooInstance *instance;
+
+ D_MAGIC_ASSERT( this, VoodooManager );
+ D_ASSERT( instance_id != VOODOO_INSTANCE_NONE );
+ D_ASSERT( ret_instance != NULL );
+
+ direct_mutex_lock( &instances.lock );
+
+ InstanceMap::iterator itr = instances.remote.find( instance_id );
+
+ direct_mutex_unlock( &instances.lock );
+
+ if (itr == instances.remote.end())
+ return DR_NOSUCHINSTANCE;
+
+ instance = (*itr).second;
+
+ // FIXME: addref?
+
+ *ret_instance = instance;
+
+ return DR_OK;
+}
+
+//}
+
diff --git a/Source/DirectFB/lib/voodoo/manager.h b/Source/DirectFB/lib/voodoo/manager.h
new file mode 100755
index 0000000..ae3189b
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/manager.h
@@ -0,0 +1,279 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__MANAGER_H__
+#define __VOODOO__MANAGER_H__
+
+#include <voodoo/types.h>
+#include <voodoo/message.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#include <direct/interface.h>
+#include <direct/thread.h>
+}
+
+#include <map>
+
+#include <voodoo/instance.h>
+
+
+typedef struct {
+ VoodooMessageBlockType type;
+ unsigned int len;
+ void *ptr;
+ u32 val;
+} VoodooMessageBlock;
+
+
+typedef std::map<VoodooInstanceID,VoodooInstance*> InstanceMap;
+
+
+class VoodooDispatcher;
+
+
+class VoodooContext {
+public:
+ virtual DirectResult HandleSuper( VoodooManager *manager,
+ const char *name,
+ VoodooInstanceID *ret_instance ) = 0;
+};
+
+
+class VoodooManager {
+public:
+ int magic;
+
+ bool is_quit;
+
+private:
+ friend class VoodooDispatcher;
+
+ VoodooLink *link;
+ VoodooConnection *connection;
+
+ VoodooContext *context;
+
+ size_t msg_count;
+ VoodooMessageSerial msg_serial;
+
+ struct {
+ DirectMutex lock;
+ InstanceMap local;
+ InstanceMap remote;
+ VoodooInstanceID last;
+ } instances;
+
+ struct {
+ DirectMutex lock;
+ DirectWaitQueue wait_get;
+ DirectWaitQueue wait_put;
+ VoodooResponseMessage *current;
+ } response;
+
+
+ VoodooDispatcher *dispatcher;
+
+
+
+public:
+ VoodooManager( VoodooLink *link,
+ VoodooContext *context );
+ ~VoodooManager();
+
+
+ /** New API **/
+
+ void DispatchPacket ( VoodooPacket *packet );
+ bool DispatchReady (); // FIXME: will be obsolete with GetPacket() method, called by connection code to read directly into packet
+
+
+
+ /** Old API **/
+
+ void quit ();
+
+
+ void handle_disconnect ();
+ void handle_super ( VoodooSuperMessage *super );
+
+ void handle_request ( VoodooRequestMessage *request );
+ void handle_response ( VoodooResponseMessage *response );
+
+
+private:
+ static void *dispatch_async_thread( DirectThread *thread,
+ void *arg );
+
+
+
+
+public:
+ DirectResult do_super ( const char *name,
+ VoodooInstanceID *ret_instance );
+
+ DirectResult do_request ( VoodooInstanceID instance,
+ VoodooMethodID method,
+ VoodooRequestFlags flags,
+ VoodooResponseMessage **ret_response,
+ VoodooMessageBlock *blocks = NULL,
+ size_t num_blocks = 0,
+ size_t data_size = 0 );
+
+ DirectResult next_response ( VoodooResponseMessage *response,
+ VoodooResponseMessage **ret_response );
+
+ DirectResult finish_request ( VoodooResponseMessage *response );
+
+ DirectResult do_respond ( bool flush,
+ VoodooMessageSerial request,
+ DirectResult result,
+ VoodooInstanceID instance = VOODOO_INSTANCE_NONE,
+ VoodooMessageBlock *blocks = NULL,
+ size_t num_blocks = 0,
+ size_t data_size = 0 );
+
+private:
+ inline void write_blocks ( void *dst,
+ const VoodooMessageBlock *blocks,
+ size_t num_blocks );
+
+ DirectResult lock_response ( VoodooMessageSerial request,
+ VoodooResponseMessage **ret_response );
+
+ DirectResult unlock_response ( VoodooResponseMessage *response );
+
+
+public:
+ DirectResult register_local ( VoodooInstance *instance,
+ VoodooInstanceID *ret_instance );
+
+ DirectResult unregister_local ( VoodooInstanceID instance_id );
+
+ DirectResult lookup_local ( VoodooInstanceID instance_id,
+ VoodooInstance **ret_instance );
+
+ DirectResult register_remote ( VoodooInstance *instance,
+ VoodooInstanceID instance_id );
+
+ DirectResult unregister_remote ( VoodooInstanceID instance_id );
+
+ DirectResult lookup_remote ( VoodooInstanceID instance_id,
+ VoodooInstance **ret_instance );
+};
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+DirectResult VOODOO_API voodoo_manager_create ( VoodooLink *link,
+ VoodooClient *client,
+ VoodooServer *server,
+ VoodooManager **ret_manager );
+
+DirectResult VOODOO_API voodoo_manager_quit ( VoodooManager *manager );
+
+bool VOODOO_API voodoo_manager_is_closed ( const VoodooManager *manager );
+
+DirectResult VOODOO_API voodoo_manager_destroy ( VoodooManager *manager );
+
+
+/* Super */
+
+DirectResult VOODOO_API voodoo_manager_super ( VoodooManager *manager,
+ const char *name,
+ VoodooInstanceID *ret_instance );
+
+
+/* Request */
+
+DirectResult VOODOO_API voodoo_manager_request ( VoodooManager *manager,
+ VoodooInstanceID instance,
+ VoodooMethodID method,
+ VoodooRequestFlags flags,
+ VoodooResponseMessage **ret_response, ... );
+
+DirectResult VOODOO_API voodoo_manager_next_response ( VoodooManager *manager,
+ VoodooResponseMessage *response,
+ VoodooResponseMessage **ret_response );
+
+DirectResult VOODOO_API voodoo_manager_finish_request ( VoodooManager *manager,
+ VoodooResponseMessage *response );
+
+
+/* Response */
+
+DirectResult VOODOO_API voodoo_manager_respond ( VoodooManager *manager,
+ bool flush,
+ VoodooMessageSerial request,
+ DirectResult result,
+ VoodooInstanceID instance, ... );
+
+
+/* Instances */
+
+DirectResult VOODOO_API voodoo_manager_register_local ( VoodooManager *manager,
+ VoodooInstanceID super,
+ void *dispatcher,
+ void *real,
+ VoodooDispatch dispatch,
+ VoodooInstanceID *ret_instance_id );
+
+DirectResult VOODOO_API voodoo_manager_unregister_local( VoodooManager *manager,
+ VoodooInstanceID instance_id );
+
+DirectResult VOODOO_API voodoo_manager_lookup_local ( VoodooManager *manager,
+ VoodooInstanceID instance,
+ void **ret_dispatcher,
+ void **ret_real );
+
+DirectResult VOODOO_API voodoo_manager_register_remote( VoodooManager *manager,
+ bool super,
+ void *requestor,
+ VoodooInstanceID instance );
+
+DirectResult VOODOO_API voodoo_manager_lookup_remote ( VoodooManager *manager,
+ VoodooInstanceID instance,
+ void **ret_requestor );
+
+
+/* Security */
+
+DirectResult VOODOO_API voodoo_manager_check_allocation( VoodooManager *manager,
+ unsigned int amount );
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/manager_c.cpp b/Source/DirectFB/lib/voodoo/manager_c.cpp
new file mode 100755
index 0000000..7019da8
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/manager_c.cpp
@@ -0,0 +1,553 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#include <list>
+
+#include <stdarg.h>
+
+extern "C" {
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <voodoo/conf.h>
+#include <voodoo/server.h>
+}
+
+#include <voodoo/manager.h>
+
+
+D_DEBUG_DOMAIN( Voodoo_Manager, "Voodoo/Manager", "Voodoo Manager" );
+
+/**********************************************************************************************************************/
+
+
+#define VOODOO_MANAGER_MESSAGE_BLOCKS_MAX 20
+
+static __inline__ int
+calc_blocks( va_list args,
+ VoodooMessageBlock *ret_blocks, size_t *ret_num )
+{
+ int size = 4; /* for the terminating VMBT_NONE */
+ size_t num = 0;
+ VoodooMessageBlockType type;
+
+ /* Fetch first block type. */
+ type = (VoodooMessageBlockType) va_arg( args, int );
+
+ while (type != VMBT_NONE) {
+ if (num == VOODOO_MANAGER_MESSAGE_BLOCKS_MAX) {
+ // FIXME: support more blocks?
+ D_UNIMPLEMENTED();
+ break;
+ }
+
+ /* Set message block type. */
+ ret_blocks[num].type = type;
+
+ switch (type) {
+ case VMBT_ID:
+ ret_blocks[num].len = 4;
+ ret_blocks[num].ptr = NULL;
+ ret_blocks[num].val = va_arg( args, u32 );
+
+ D_DEBUG( "Voodoo/Message: + ID %u\n", ret_blocks[num].val );
+ break;
+
+ case VMBT_INT:
+ ret_blocks[num].len = 4;
+ ret_blocks[num].ptr = NULL;
+ ret_blocks[num].val = va_arg( args, s32 );
+
+ D_DEBUG( "Voodoo/Message: + INT %d\n", ret_blocks[num].val );
+ break;
+
+ case VMBT_UINT:
+ ret_blocks[num].len = 4;
+ ret_blocks[num].ptr = NULL;
+ ret_blocks[num].val = va_arg( args, u32 );
+
+ D_DEBUG( "Voodoo/Message: + UINT %u\n", ret_blocks[num].val );
+ break;
+
+ case VMBT_DATA:
+ ret_blocks[num].len = va_arg( args, int );
+ ret_blocks[num].ptr = va_arg( args, void * );
+
+// D_ASSERT( ret_blocks[num].len > 0 );
+ D_ASSERT( ret_blocks[num].ptr != NULL );
+
+ D_DEBUG( "Voodoo/Message: + DATA at %p with length %d\n", ret_blocks[num].ptr, ret_blocks[num].len );
+ break;
+
+ case VMBT_ODATA:
+ ret_blocks[num].len = va_arg( args, int );
+ ret_blocks[num].ptr = va_arg( args, void * );
+
+ D_ASSERT( ret_blocks[num].len > 0 );
+
+ D_DEBUG( "Voodoo/Message: + ODATA at %p with length %d\n", ret_blocks[num].ptr, ret_blocks[num].len );
+
+ if (!ret_blocks[num].ptr)
+ ret_blocks[num].len = 0;
+ break;
+
+ case VMBT_STRING:
+ ret_blocks[num].ptr = va_arg( args, char * );
+ ret_blocks[num].len = strlen( (const char*) ret_blocks[num].ptr ) + 1;
+
+ D_ASSERT( ret_blocks[num].ptr != NULL );
+
+ D_DEBUG( "Voodoo/Message: + STRING '%s' at %p with length %d\n", (char*) ret_blocks[num].ptr, ret_blocks[num].ptr, ret_blocks[num].len );
+ break;
+
+ default:
+ D_BREAK( "unknown message block type" );
+ }
+
+ /* Fetch next block type. */
+ type = (VoodooMessageBlockType) va_arg( args, int );
+
+ size += 8 + VOODOO_MSG_ALIGN(ret_blocks[num].len);
+
+ num++;
+ }
+
+ *ret_num = num;
+
+ return size;
+}
+
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+/* Old C API
+ */
+
+/*
+
+
+register add refs proxy
+unregister releases proxy
+
+proxy destruct releases real
+
+*/
+
+class VoodooInstanceInterface : public VoodooInstance {
+public:
+ VoodooManager *manager;
+ VoodooInstance *super;
+ IAny *proxy;
+ IAny *real;
+ VoodooDispatch dispatch;
+
+
+ static std::list<VoodooInstanceInterface*> interfaces;
+
+
+public:
+ VoodooInstanceInterface( VoodooManager *manager,
+ VoodooInstance *super,
+ IAny *proxy,
+ IAny *real,
+ VoodooDispatch dispatch )
+ :
+ manager( manager ),
+ super( super ),
+ proxy( proxy ),
+ real( real ),
+ dispatch( dispatch )
+ {
+ D_DEBUG_AT( Voodoo_Manager, "VoodooInstanceInterface::%s( %p, manager %p, super %p, proxy %p, real %p, dispatch %p )\n",
+ __func__, this, manager, super, proxy, real, dispatch );
+
+ if (super)
+ super->AddRef();
+
+ interfaces.push_back( this );
+ }
+
+protected:
+ virtual ~VoodooInstanceInterface()
+ {
+ D_DEBUG_AT( Voodoo_Manager, "VoodooInstanceInterface::%s( %p )\n", __func__, this );
+
+ D_MAGIC_ASSERT( this, VoodooInstance );
+
+ if (proxy) {
+ D_DEBUG_AT( Voodoo_Manager, " -> releasing proxy interface\n" );
+
+ proxy->Release( proxy );
+ }
+
+
+ if (super) {
+ D_DEBUG_AT( Voodoo_Manager, " -> releasing super instance\n" );
+
+ super->Release();
+ }
+
+ interfaces.remove( this );
+ }
+
+public:
+ virtual DirectResult
+ Dispatch( VoodooManager *manager,
+ VoodooRequestMessage *msg )
+ {
+ D_DEBUG_AT( Voodoo_Manager, "VoodooInstanceInterface::%s( %p, manager %p, msg %p )\n", __func__, this, manager, msg );
+
+ D_MAGIC_ASSERT( this, VoodooInstance );
+
+ D_ASSERT( dispatch != NULL );
+
+ return dispatch( proxy, real, manager, msg );
+ }
+};
+
+std::list<VoodooInstanceInterface*> VoodooInstanceInterface::interfaces;
+
+/**********************************************************************************************************************/
+
+class VoodooContextClassic : public VoodooContext {
+private:
+ VoodooServer *server;
+
+public:
+ VoodooContextClassic( VoodooServer *server )
+ :
+ server( server )
+ {
+ }
+
+ virtual DirectResult
+ HandleSuper( VoodooManager *manager, const char *name, VoodooInstanceID *ret_instance )
+ {
+ return voodoo_server_construct( server, manager, name, ret_instance );
+ }
+};
+
+DirectResult
+voodoo_manager_create( VoodooLink *link,
+ VoodooClient *client,
+ VoodooServer *server,
+ VoodooManager **ret_manager )
+{
+ D_ASSERT( ret_manager != NULL );
+
+ *ret_manager = new VoodooManager( link, new VoodooContextClassic( server ) ); // FIXME: leak
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_manager_quit( VoodooManager *manager )
+{
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ manager->quit();
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_manager_destroy( VoodooManager *manager )
+{
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ delete manager;
+
+ for (std::list<VoodooInstanceInterface*>::const_iterator iter = VoodooInstanceInterface::interfaces.begin();
+ iter != VoodooInstanceInterface::interfaces.end(); iter++)
+ {
+ VoodooInstanceInterface *instance = *iter;
+
+ if (instance->manager == manager)
+ D_INFO( "Zombie: Instance %p, proxy %p, real %p, super %p\n", instance, instance->proxy, instance->real, instance->super );
+ }
+
+ return DR_OK;
+}
+
+bool
+voodoo_manager_is_closed( const VoodooManager *manager )
+{
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ return manager->is_quit;
+}
+
+/**************************************************************************************************/
+
+DirectResult
+voodoo_manager_super( VoodooManager *manager,
+ const char *name,
+ VoodooInstanceID *ret_instance )
+{
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ return manager->do_super( name, ret_instance );
+}
+
+DirectResult
+voodoo_manager_request( VoodooManager *manager,
+ VoodooInstanceID instance,
+ VoodooMethodID method,
+ VoodooRequestFlags flags,
+ VoodooResponseMessage **ret_response, ... )
+{
+ DirectResult ret;
+
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ va_list ap;
+
+ va_start( ap, ret_response );
+
+
+ VoodooMessageBlock blocks[VOODOO_MANAGER_MESSAGE_BLOCKS_MAX];
+ size_t num_blocks;
+ size_t data_size;
+
+ data_size = calc_blocks( ap, blocks, &num_blocks );
+
+
+ ret = manager->do_request( instance, method, flags, ret_response, blocks, num_blocks, data_size );
+
+ va_end( ap );
+
+ return ret;
+}
+
+DirectResult
+voodoo_manager_next_response( VoodooManager *manager,
+ VoodooResponseMessage *response,
+ VoodooResponseMessage **ret_response )
+{
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ return manager->next_response( response, ret_response );
+}
+
+DirectResult
+voodoo_manager_finish_request( VoodooManager *manager,
+ VoodooResponseMessage *response )
+{
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ return manager->finish_request( response );
+}
+
+DirectResult
+voodoo_manager_respond( VoodooManager *manager,
+ bool flush,
+ VoodooMessageSerial request,
+ DirectResult result,
+ VoodooInstanceID instance, ... )
+{
+ DirectResult ret;
+
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ va_list ap;
+
+ va_start( ap, instance );
+
+
+ VoodooMessageBlock blocks[VOODOO_MANAGER_MESSAGE_BLOCKS_MAX];
+ size_t num_blocks;
+ size_t data_size;
+
+ data_size = calc_blocks( ap, blocks, &num_blocks );
+
+
+ ret = manager->do_respond( flush, request, result, instance, blocks, num_blocks, data_size );
+
+ va_end( ap );
+
+ return ret;
+}
+
+DirectResult
+voodoo_manager_register_local( VoodooManager *manager,
+ VoodooInstanceID super,
+ void *dispatcher,
+ void *real,
+ VoodooDispatch dispatch,
+ VoodooInstanceID *ret_instance )
+{
+ DirectResult ret;
+ VoodooInstance *super_instance = NULL;
+
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ if (super != VOODOO_INSTANCE_NONE) {
+ ret = manager->lookup_local( super, &super_instance );
+ if (ret) {
+ D_DERROR( ret, "Voodoo/Manager: Could not lookup super instance %u!\n", super );
+ return ret;
+ }
+ }
+
+
+ VoodooInstanceInterface *instance = new VoodooInstanceInterface( manager, super_instance, (IAny*) dispatcher, (IAny*) real, dispatch );
+
+ ret = manager->register_local( instance, ret_instance );
+
+ instance->Release();
+
+ return ret;
+}
+
+DirectResult
+voodoo_manager_unregister_local( VoodooManager *manager,
+ VoodooInstanceID instance_id )
+{
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ return manager->unregister_local( instance_id );
+}
+
+DirectResult
+voodoo_manager_lookup_local( VoodooManager *manager,
+ VoodooInstanceID instance_id,
+ void **ret_dispatcher,
+ void **ret_real )
+{
+ DirectResult ret;
+ VoodooInstance *instance;
+
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ ret = manager->lookup_local( instance_id, &instance );
+ if (ret)
+ return ret;
+
+ if (ret_dispatcher)
+ *ret_dispatcher = ((VoodooInstanceInterface*) instance)->proxy;
+
+ if (ret_real)
+ *ret_real = ((VoodooInstanceInterface*) instance)->real;
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_manager_register_remote( VoodooManager *manager,
+ bool super,
+ void *requestor,
+ VoodooInstanceID instance_id )
+{
+ DirectResult ret;
+
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ VoodooInstanceInterface *instance = new VoodooInstanceInterface( manager, NULL, (IAny*) requestor, NULL, NULL);
+
+ ret = manager->register_remote( instance, instance_id );
+
+ instance->Release();
+
+ return ret;
+}
+
+
+DirectResult
+voodoo_manager_lookup_remote( VoodooManager *manager,
+ VoodooInstanceID instance_id,
+ void **ret_requestor )
+{
+ DirectResult ret;
+ VoodooInstance *instance;
+
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ ret = manager->lookup_remote( instance_id, &instance );
+ if (ret)
+ return ret;
+
+ if (ret_requestor)
+ *ret_requestor = ((VoodooInstanceInterface*) instance)->proxy;
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_manager_check_allocation( VoodooManager *manager,
+ unsigned int amount )
+{
+#ifndef WIN32
+ FILE *f;
+ char buf[2000];
+ int size;
+ char *p;
+ size_t bytes;
+
+ D_MAGIC_ASSERT( manager, VoodooManager );
+
+ if (!voodoo_config->memory_max)
+ return DR_OK;
+
+ direct_snprintf( buf, sizeof(buf), "/proc/%d/status", direct_getpid() );
+
+ f = fopen( buf, "r" );
+ if (!f) {
+ D_ERROR( "Could not open '%s'!\n", buf );
+ return DR_FAILURE;
+ }
+
+ bytes = fread( buf, 1, sizeof(buf)-1, f );
+
+ fclose( f );
+
+ if (bytes) {
+ buf[bytes] = 0;
+
+ p = strstr( buf, "VmRSS:" );
+ if (!p) {
+ D_ERROR( "Could not find memory information!\n" );
+ return DR_FAILURE;
+ }
+
+ sscanf( p + 6, " %u", &size );
+
+ D_INFO( "SIZE: %u kB (+%u kB)\n", size, amount / 1024 );
+
+ if (size * 1024 + amount > voodoo_config->memory_max)
+ return DR_LIMITEXCEEDED;
+ }
+#endif
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/message.h b/Source/DirectFB/lib/voodoo/message.h
new file mode 100755
index 0000000..514b3bc
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/message.h
@@ -0,0 +1,258 @@
+/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__MESSAGE_H__
+#define __VOODOO__MESSAGE_H__
+
+#include <voodoo/types.h>
+
+#include <direct/debug.h>
+#include <direct/memcpy.h>
+
+
+#define VOODOO_MSG_ALIGN(i) (((i) + 3) & ~3)
+
+typedef enum {
+ VMBT_NONE,
+ VMBT_ID,
+ VMBT_INT,
+ VMBT_UINT,
+ VMBT_DATA,
+ VMBT_ODATA,
+ VMBT_STRING
+} VoodooMessageBlockType;
+
+typedef enum {
+ VREQ_NONE = 0x00000000,
+ VREQ_RESPOND = 0x00000001,
+ VREQ_ASYNC = 0x00000002,
+ VREQ_QUEUE = 0x00000004
+} VoodooRequestFlags;
+
+typedef enum {
+ VMSG_SUPER,
+ VMSG_REQUEST,
+ VMSG_RESPONSE,
+
+ VMSG_DISCOVER, // temporary solution for compatibility
+ VMSG_SENDINFO, // temporary solution for compatibility
+} VoodooMessageType;
+
+
+struct __V_VoodooMessageHeader {
+ int size;
+ VoodooMessageSerial serial;
+ u32 type;
+};
+
+
+struct __V_VoodooSuperMessage {
+ VoodooMessageHeader header;
+};
+
+struct __V_VoodooRequestMessage {
+ VoodooMessageHeader header;
+
+ VoodooInstanceID instance;
+ VoodooMethodID method;
+
+ u32 flags;
+};
+
+struct __V_VoodooResponseMessage {
+ VoodooMessageHeader header;
+
+ VoodooMessageSerial request;
+ DirectResult result;
+
+ VoodooInstanceID instance;
+};
+
+
+typedef struct {
+ int magic;
+
+ const void *msg;
+ const void *ptr;
+} VoodooMessageParser;
+
+
+
+#define __VOODOO_PARSER_PROLOG( parser, req_type ) \
+ const void *_vp_ptr; \
+ VoodooMessageBlockType _vp_type; \
+ int _vp_length; \
+ \
+ D_MAGIC_ASSERT( &(parser), VoodooMessageParser ); \
+ \
+ _vp_ptr = (parser).ptr; \
+ \
+ /* Read message block type. */ \
+ _vp_type = *(const u32*) _vp_ptr; \
+ \
+ D_ASSERT( _vp_type == (req_type) ); \
+ \
+ /* Read data block length. */ \
+ _vp_length = *(const s32*) (_vp_ptr + 4)
+
+
+#define __VOODOO_PARSER_EPILOG( parser ) \
+ /* Advance message data pointer. */ \
+ (parser).ptr += 8 + VOODOO_MSG_ALIGN(_vp_length)
+
+
+#define VOODOO_PARSER_BEGIN( parser, message ) \
+ do { \
+ const VoodooMessageHeader *_vp_header = (const VoodooMessageHeader *) (message); \
+ \
+ D_ASSERT( (message) != NULL ); \
+ D_ASSERT( _vp_header->type == VMSG_REQUEST || _vp_header->type == VMSG_RESPONSE ); \
+ \
+ (parser).msg = (message); \
+ (parser).ptr = (parser).msg + (_vp_header->type == VMSG_REQUEST ? \
+ sizeof(VoodooRequestMessage) : sizeof(VoodooResponseMessage)); \
+ \
+ D_MAGIC_SET_ONLY( &(parser), VoodooMessageParser ); \
+ } while (0)
+
+
+#define VOODOO_PARSER_GET_ID( parser, ret_id ) \
+ do { \
+ __VOODOO_PARSER_PROLOG( parser, VMBT_ID ); \
+ \
+ D_ASSERT( _vp_length == 4 ); \
+ \
+ /* Read the ID. */ \
+ (ret_id) = *(const u32*) (_vp_ptr + 8); \
+ \
+ __VOODOO_PARSER_EPILOG( parser ); \
+ } while (0)
+
+#define VOODOO_PARSER_GET_INT( parser, ret_int ) \
+ do { \
+ __VOODOO_PARSER_PROLOG( parser, VMBT_INT ); \
+ \
+ D_ASSERT( _vp_length == 4 ); \
+ \
+ /* Read the integer. */ \
+ (ret_int) = *(const s32*) (_vp_ptr + 8); \
+ \
+ __VOODOO_PARSER_EPILOG( parser ); \
+ } while (0)
+
+#define VOODOO_PARSER_GET_UINT( parser, ret_uint ) \
+ do { \
+ __VOODOO_PARSER_PROLOG( parser, VMBT_UINT ); \
+ \
+ D_ASSERT( _vp_length == 4 ); \
+ \
+ /* Read the unsigned integer. */ \
+ (ret_uint) = *(const u32*) (_vp_ptr + 8); \
+ \
+ __VOODOO_PARSER_EPILOG( parser ); \
+ } while (0)
+
+#define VOODOO_PARSER_GET_DATA( parser, ret_data ) \
+ do { \
+ __VOODOO_PARSER_PROLOG( parser, VMBT_DATA ); \
+ \
+ D_ASSERT( _vp_length > 0 ); \
+ \
+ /* Return pointer to data. */ \
+ (ret_data) = _vp_ptr + 8; \
+ \
+ __VOODOO_PARSER_EPILOG( parser ); \
+ } while (0)
+
+#define VOODOO_PARSER_READ_DATA( parser, dst, max_len ) \
+ do { \
+ __VOODOO_PARSER_PROLOG( parser, VMBT_DATA ); \
+ \
+ D_ASSERT( _vp_length > 0 ); \
+ D_ASSERT( _vp_length <= max_len ); \
+ \
+ /* Copy data block. */ \
+ direct_memcpy( (dst), _vp_ptr + 8, _vp_length ); \
+ \
+ __VOODOO_PARSER_EPILOG( parser ); \
+ } while (0)
+
+#define VOODOO_PARSER_COPY_DATA( parser, ret_data ) \
+ do { \
+ __VOODOO_PARSER_PROLOG( parser, VMBT_DATA ); \
+ \
+ D_ASSERT( _vp_length > 0 ); \
+ \
+ /* Allocate memory on the stack. */ \
+ (ret_data) = alloca( _vp_length ); \
+ \
+ /* Copy data block. */ \
+ direct_memcpy( (ret_data), _vp_ptr + 8, _vp_length ); \
+ \
+ __VOODOO_PARSER_EPILOG( parser ); \
+ } while (0)
+
+#define VOODOO_PARSER_GET_ODATA( parser, ret_data ) \
+ do { \
+ __VOODOO_PARSER_PROLOG( parser, VMBT_ODATA ); \
+ \
+ D_ASSERT( _vp_length >= 0 ); \
+ \
+ /* Return pointer to data or NULL. */ \
+ if (_vp_length) \
+ (ret_data) = _vp_ptr + 8; \
+ else \
+ (ret_data) = NULL; \
+ \
+ __VOODOO_PARSER_EPILOG( parser ); \
+ } while (0)
+
+#define VOODOO_PARSER_GET_STRING( parser, ret_string ) \
+ do { \
+ __VOODOO_PARSER_PROLOG( parser, VMBT_STRING ); \
+ \
+ D_ASSERT( _vp_length > 0 ); \
+ \
+ /* Return pointer to string. */ \
+ (ret_string) = (const char*) (_vp_ptr + 8); \
+ \
+ __VOODOO_PARSER_EPILOG( parser ); \
+ } while (0)
+
+
+#define VOODOO_PARSER_END( parser ) \
+ do { \
+ D_MAGIC_ASSERT( &(parser), VoodooMessageParser ); \
+ \
+ D_ASSUME( *(const u32*) ((parser).ptr) == VMBT_NONE ); \
+ \
+ D_MAGIC_CLEAR( &(parser) ); \
+ } while (0)
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/mutex.c b/Source/DirectFB/lib/voodoo/mutex.c
new file mode 100755
index 0000000..dcc287d
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/mutex.c
@@ -0,0 +1,105 @@
+/*
+ (c) Copyright 2001-2008 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/util.h>
+
+#include "mutex.h"
+
+/**********************************************************************************************************************/
+
+DirectResult
+direct_mutex_init( DirectMutex *mutex )
+{
+ if (pthread_mutex_init( &mutex->lock, NULL ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+DirectResult
+direct_recursive_mutex_init( DirectMutex *mutex )
+{
+ DirectResult ret = DR_OK;
+ int result;
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init( &attr );
+#if HAVE_DECL_PTHREAD_MUTEX_RECURSIVE
+ pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
+#endif
+ result = pthread_mutex_init( &mutex->lock, &attr );
+ if (result) {
+ ret = errno2result( errno );
+ D_PERROR( "Direct/Mutex: Could not initialize recursive mutex!\n" );
+ }
+
+ pthread_mutexattr_destroy( &attr );
+
+ return (DirectResult) ret;
+}
+
+__attribute__((no_instrument_function))
+DirectResult
+direct_mutex_lock( DirectMutex *mutex )
+{
+ if (pthread_mutex_lock( &mutex->lock ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+__attribute__((no_instrument_function))
+DirectResult
+direct_mutex_unlock( DirectMutex *mutex )
+{
+ if (pthread_mutex_unlock( &mutex->lock ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+DirectResult
+direct_mutex_trylock( DirectMutex *mutex )
+{
+ if (pthread_mutex_trylock( &mutex->lock ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+DirectResult
+direct_mutex_deinit( DirectMutex *mutex )
+{
+ if (pthread_mutex_destroy( &mutex->lock ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/mutex.h b/Source/DirectFB/lib/voodoo/mutex.h
new file mode 100755
index 0000000..fa520fd
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/mutex.h
@@ -0,0 +1,142 @@
+/*
+ (c) Copyright 2001-2008 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DIRECT__OS__LINUX__GLIBC__MUTEX_H__
+#define __DIRECT__OS__LINUX__GLIBC__MUTEX_H__
+
+#include <pthread.h>
+
+#include <direct/util.h>
+
+
+#define _ZU "%zu"
+#define _ZD "%zd"
+
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ pthread_mutex_t lock;
+} DirectMutex;
+
+/**********************************************************************************************************************/
+
+#define DIRECT_MUTEX_INITIALIZER(name) { PTHREAD_MUTEX_INITIALIZER }
+#define DIRECT_RECURSIVE_MUTEX_INITIALIZER(name) { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP }
+
+
+DirectResult direct_mutex_init ( DirectMutex *mutex );
+
+DirectResult direct_recursive_mutex_init ( DirectMutex *mutex );
+
+DirectResult direct_mutex_lock ( DirectMutex *mutex );
+
+DirectResult direct_mutex_unlock ( DirectMutex *mutex );
+
+DirectResult direct_mutex_trylock ( DirectMutex *mutex );
+
+DirectResult direct_mutex_deinit ( DirectMutex *mutex );
+
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+typedef struct {
+ pthread_key_t key;
+} DirectTLS;
+
+/**********************************************************************************************************************/
+
+#define DIRECT_TLS_DATA( name ) \
+ static DirectTLS name = { (pthread_key_t) -1 }
+
+/**********************************************************************************************************************/
+
+__attribute__((no_instrument_function))
+static inline void *direct_tls_get__( DirectTLS *tls );
+
+__attribute__((no_instrument_function))
+static inline DirectResult direct_tls_set__( DirectTLS *tls,
+ void *value );
+
+__attribute__((no_instrument_function))
+static inline DirectResult direct_tls_register( DirectTLS *tls,
+ void (*destructor)( void* ) );
+
+__attribute__((no_instrument_function))
+static inline DirectResult direct_tls_unregister( DirectTLS *tls );
+
+/**********************************************************************************************************************/
+
+#define direct_tls_get( name ) direct_tls_get__( &name )
+#define direct_tls_set( name, v ) direct_tls_set__( &name, v )
+
+/**********************************************************************************************************************/
+
+static inline void *
+direct_tls_get__( DirectTLS *tls )
+{
+ void *value;
+
+ value = pthread_getspecific( tls->key );
+
+ return value;
+}
+
+static inline DirectResult
+direct_tls_set__( DirectTLS *tls,
+ void *value )
+{
+ if (pthread_setspecific( tls->key, value ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+static inline DirectResult
+direct_tls_register( DirectTLS *tls, void (*destructor)( void* ) )
+{
+ if (pthread_key_create( &tls->key, destructor ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+static inline DirectResult
+direct_tls_unregister( DirectTLS *tls )
+{
+ if (pthread_key_delete( tls->key ))
+ return errno2result( errno );
+
+ tls->key = (pthread_key_t) -1;
+
+ return DR_OK;
+}
+
+#endif
+
diff --git a/Source/DirectFB/lib/voodoo/packet.h b/Source/DirectFB/lib/voodoo/packet.h
new file mode 100755
index 0000000..3f97071
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/packet.h
@@ -0,0 +1,285 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__PACKET_H__
+#define __VOODOO__PACKET_H__
+
+extern "C" {
+#include <direct/fastlz.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+
+
+#include <voodoo/types.h>
+}
+
+
+typedef enum {
+ VPHF_NONE = 0x00000000,
+
+ VPHF_COMPRESSED = 0x00000001,
+
+ VPHF_ALL = 0x00000001
+} VoodooPacketHeaderFlags;
+
+
+typedef struct {
+ u32 size;
+ u32 flags;
+ u32 uncompressed;
+ u32 align;
+} VoodooPacketHeader;
+
+
+class VoodooPacket {
+public:
+ DirectLink link;
+ bool sending;
+
+private:
+ void *data;
+ void *current;
+ VoodooPacketHeader header;
+
+ VoodooPacket( u32 size,
+ void *data )
+ :
+ sending(false),
+ data(data),
+ current(data)
+ {
+ memset( &link, 0, sizeof(link) );
+
+ header.size = size;
+ header.flags = VPHF_NONE;
+ header.uncompressed = size;
+ }
+
+ VoodooPacket( u32 size,
+ u32 flags,
+ u32 uncompressed,
+ void *data )
+ :
+ sending(false),
+ data(data),
+ current(data)
+ {
+ memset( &link, 0, sizeof(link) );
+
+ header.size = size;
+ header.flags = VPHF_COMPRESSED;
+ header.uncompressed = uncompressed;
+ }
+
+ ~VoodooPacket() {};
+
+public:
+/*
+ static VoodooPacket *
+ New( u32 size )
+ {
+ VoodooPacket *packet = (VoodooPacket*) D_MALLOC( sizeof(VoodooPacket) + size );
+
+ if (!packet) {
+ D_OOM();
+ return NULL;
+ }
+
+ return new (packet) VoodooPacket( size, packet + 1 );
+
+
+ if (data)
+ this->data = data;
+ else
+ this->data = header + 1;
+ }
+*/
+ static VoodooPacket *
+ New( u32 size,
+ void *data )
+ {
+ return new VoodooPacket( size, data );
+ }
+
+ static VoodooPacket *
+ Reset( VoodooPacket *packet,
+ u32 size,
+ void *data )
+ {
+ return new (packet) VoodooPacket( size, data );
+ }
+
+ static VoodooPacket *
+ New( void *header,
+ u32 size )
+ {
+ VoodooPacketHeader *h = (VoodooPacketHeader*) header;
+
+ h->size = size;
+ h->flags = VPHF_NONE;
+ h->uncompressed = size;
+
+ return new VoodooPacket( size, (char*) header + sizeof(VoodooPacketHeader) );
+ }
+
+ static VoodooPacket *
+ New( u32 size )
+ {
+ VoodooPacket *p = (VoodooPacket*) D_MALLOC( sizeof(VoodooPacket) + VOODOO_PACKET_MAX );
+
+ if (!p) {
+ D_OOM();
+ return NULL;
+ }
+
+ return new (p) VoodooPacket( size, p + 1 );
+ }
+
+ static VoodooPacket *
+ Compressed( VoodooPacket *packet )
+ {
+ VoodooPacket *p = (VoodooPacket*) D_MALLOC( sizeof(VoodooPacket) + packet->header.size * 4 / 3 );
+
+ if (!p) {
+ D_OOM();
+ return NULL;
+ }
+
+ int compressed = direct_fastlz_compress( packet->data, packet->header.uncompressed, p + 1 );
+
+ if ((size_t) compressed < packet->header.uncompressed)
+ return new (p) VoodooPacket( compressed, VPHF_COMPRESSED, packet->header.uncompressed, p + 1 );
+
+ D_FREE( p );
+
+ return packet;
+ }
+
+ static VoodooPacket *
+ Copy( VoodooPacket *packet )
+ {
+ VoodooPacket *p = (VoodooPacket*) D_MALLOC( sizeof(VoodooPacket) + packet->header.size );
+
+ if (!p) {
+ D_OOM();
+ return NULL;
+ }
+
+ direct_memcpy( p + 1, packet->data_start(), packet->header.size );
+
+ return new (p) VoodooPacket( packet->header.size, packet->header.flags, packet->header.uncompressed, p + 1 );
+ }
+
+ static VoodooPacket *
+ Copy( u32 size,
+ u32 flags,
+ u32 uncompressed,
+ void *data )
+ {
+ VoodooPacket *p = (VoodooPacket*) D_MALLOC( sizeof(VoodooPacket) + size );
+
+ if (!p) {
+ D_OOM();
+ return NULL;
+ }
+
+ direct_memcpy( p + 1, data, size );
+
+ return new (p) VoodooPacket( size, flags, uncompressed, p + 1 );
+ }
+
+ inline u32
+ size() const
+ {
+ return header.size;
+ }
+
+ inline u32
+ flags() const
+ {
+ return header.flags;
+ }
+
+ inline u32
+ uncompressed() const
+ {
+ return header.uncompressed;
+ }
+
+ inline const void *
+ data_header() const
+ {
+ D_ASSERT( data == this + 1 );
+
+ return &header;
+ }
+
+ inline const void *
+ data_start() const
+ {
+ return data;
+ }
+
+ inline void *
+ data_raw() const
+ {
+ return current;
+ }
+
+
+ inline bool
+ append( size_t size )
+ {
+ D_ASSERT( data == this + 1 );
+
+ if (header.size + size > VOODOO_PACKET_MAX)
+ return false;
+
+ current = (char*) data + header.size;
+
+ header.size += size;
+ header.uncompressed += size;
+
+ return true;
+ }
+
+ inline void
+ reset( size_t size )
+ {
+ D_ASSERT( data == this + 1 );
+
+ current = (char*) data;
+
+ header.size = size;
+ header.uncompressed = size;
+ }
+};
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/play.c b/Source/DirectFB/lib/voodoo/play.c
new file mode 100755
index 0000000..a262472
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/play.c
@@ -0,0 +1,935 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+
+#include <directfb_version.h>
+
+#include <direct/clock.h>
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <voodoo/conf.h>
+#include <voodoo/internal.h>
+#include <voodoo/message.h>
+#include <voodoo/play.h>
+#include <voodoo/play_internal.h>
+
+#ifdef MACOS
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+D_DEBUG_DOMAIN( Voodoo_Play, "Voodoo/Play", "Voodoo Play" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ DirectLink link;
+
+ VoodooPlayVersion version;
+ VoodooPlayInfo info;
+
+ long long last_seen;
+ long long broadcast;
+
+ char addr[64];
+} PlayerNode;
+
+/**********************************************************************************************************************/
+
+static void player_send_info( VoodooPlayer *player,
+ const in_addr_t *in_addr,
+ bool discover );
+
+static void *player_main_loop( DirectThread *thread,
+ void *arg );
+
+/**********************************************************************************************************************/
+
+static const int one = 1;
+
+VoodooPlayVersion g_VoodooPlay_version;
+VoodooPlayInfo g_VoodooPlay_info;
+
+/**********************************************************************************************************************/
+
+static VoodooPlayer *g_VoodooPlayer;
+
+/**********************************************************************************************************************/
+
+/*
+ * FIXME
+ */
+static void
+generate_uuid( u8 *buf )
+{
+ int i;
+
+ srand( direct_clock_get_abs_micros() );
+
+ for (i=0; i<16; i++) {
+ buf[i] = rand();
+ }
+}
+
+/**********************************************************************************************************************/
+
+pthread_mutex_t gplayermut = PTHREAD_MUTEX_INITIALIZER;
+
+
+DirectResult createSocketForPlayer (int * retfd)
+{
+ int fd = -1;
+ *retfd = -1;
+ DirectResult ret;
+ struct sockaddr_in addr;
+ D_INFO("Voodoo/Player: Creating the Socket for player 0x%08x\n",(int) g_VoodooPlayer);
+ /* Create the player socket. */
+ fd = socket( PF_INET, SOCK_DGRAM, 0 );
+ if (fd < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Player: Could not create the socket via socket()!\n" );
+
+ return ret;
+ }
+
+ /* Allow reuse of local address. */
+ if (setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one) ) < 0)
+ D_PERROR( "Voodoo/Player: Could not set SO_REUSEADDR!\n" );
+
+ if (setsockopt( fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one) ) < 0)
+ D_PERROR( "Voodoo/Player: Could not set SO_BROADCAST!\n" );
+
+ /* Bind the socket to the local port. */
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr( "0.0.0.0" );
+ addr.sin_port = htons( 2323 );
+
+ if (bind( fd, (struct sockaddr*) &addr, sizeof(addr) )) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Player: Could not bind() the socket!\n" );
+ close( fd );
+
+ return ret;
+ }
+
+ *retfd = fd;
+ return DR_OK;
+
+
+}
+
+
+DirectResult
+voodoo_player_create( const VoodooPlayInfo *info,
+ VoodooPlayer **ret_player )
+{
+ DirectResult ret;
+ int fd;
+
+ VoodooPlayer *player;
+ pthread_mutex_lock(&gplayermut);
+ D_ASSERT( ret_player != NULL );
+
+ if (g_VoodooPlayer) {
+ *ret_player = g_VoodooPlayer;
+ pthread_mutex_unlock(&gplayermut);
+ return DR_OK;
+ }
+
+ ret = createSocketForPlayer(&fd);
+ if ( ret != DR_OK)
+ {
+ pthread_mutex_unlock(&gplayermut);
+ return ret;
+
+ }
+
+
+
+ /* Allocate player structure. */
+ player = D_CALLOC( 1, sizeof(VoodooPlayer) );
+ if (!player) {
+ D_WARN( "out of memory" );
+ close( fd );
+ pthread_mutex_unlock(&gplayermut);
+ return DR_NOLOCALMEMORY;
+ }
+
+ pthread_mutex_init( &player->lock, NULL );
+
+ /* Initialize player structure. */
+ player->fd = fd;
+
+ /* Fill version struct */
+ player->version.v[0] = VPVF_LITTLE_ENDIAN | VPVF_32BIT_SERIALS;
+ player->version.v[1] = DIRECTFB_MAJOR_VERSION;
+ player->version.v[2] = DIRECTFB_MINOR_VERSION;
+ player->version.v[3] = DIRECTFB_MICRO_VERSION;
+
+ /* Fill info struct */
+ direct_snputs( player->info.name, voodoo_config->play_info.name, VOODOO_PLAYER_NAME_LENGTH );
+ direct_snputs( player->info.vendor, voodoo_config->play_info.vendor, VOODOO_PLAYER_VENDOR_LENGTH );
+ direct_snputs( player->info.model, voodoo_config->play_info.model, VOODOO_PLAYER_MODEL_LENGTH );
+ direct_memcpy( player->info.uuid, voodoo_config->play_info.uuid, 16 );
+
+ if (info)
+ player->info = *info;
+
+ if (!player->info.name[0])
+ direct_snputs( player->info.name, "Unnamed Player", VOODOO_PLAYER_NAME_LENGTH );
+
+ if (!player->info.vendor[0])
+ direct_snputs( player->info.vendor, "Unknown Vendor", VOODOO_PLAYER_VENDOR_LENGTH );
+
+ if (!player->info.model[0])
+ direct_snputs( player->info.model, "Unknown Model", VOODOO_PLAYER_MODEL_LENGTH );
+
+ if (!player->info.uuid[0])
+ generate_uuid( player->info.uuid );
+
+ player->info.flags |= VPIF_LINK;
+
+ D_MAGIC_SET( player, VoodooPlayer );
+
+
+ g_VoodooPlay_version = player->version;
+ g_VoodooPlay_info = player->info;
+
+
+ char buf[33];
+
+ snprintf( buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ player->info.uuid[0], player->info.uuid[1], player->info.uuid[2], player->info.uuid[3], player->info.uuid[4],
+ player->info.uuid[5], player->info.uuid[6], player->info.uuid[7], player->info.uuid[8], player->info.uuid[9],
+ player->info.uuid[10], player->info.uuid[11], player->info.uuid[12], player->info.uuid[13], player->info.uuid[14],
+ player->info.uuid[15] );
+
+ D_INFO( "Running player '%s' with UUID %s!\n", player->info.name, buf );
+
+ /* Start messaging thread */
+ player->thread = direct_thread_create( DTT_DEFAULT, player_main_loop, player, "Voodoo/Player" );
+
+ /* Return the new player. */
+ *ret_player = player;
+
+ if (!g_VoodooPlayer)
+ g_VoodooPlayer = player;
+
+ pthread_mutex_unlock(&gplayermut);
+ return DR_OK;
+}
+
+DirectResult
+voodoo_player_destroy( VoodooPlayer *player )
+{
+ pthread_mutex_lock(&gplayermut);
+ D_MAGIC_ASSERT( player, VoodooPlayer );
+
+ if (g_VoodooPlayer == player)
+ {
+ pthread_mutex_unlock(&gplayermut);
+ return DR_OK;
+ }
+ D_INFO("Voodoo/Player: Destroying the player 0x%08x\n",(int) player);
+ player->quit = true;
+
+ direct_thread_join( player->thread );
+ direct_thread_destroy( player->thread );
+
+ close( player->fd );
+
+ pthread_mutex_destroy( &player->lock );
+
+ D_MAGIC_CLEAR( player );
+
+ D_FREE( player );
+ g_VoodooPlayer = NULL;
+ pthread_mutex_unlock(&gplayermut);
+ return DR_OK;
+}
+
+DirectResult
+voodoo_player_broadcast( VoodooPlayer *player )
+{
+#if !VOODOO_PLAY_FAKE
+ int ret;
+#ifdef MACOS
+ char *ptr, lastname[IFNAMSIZ];
+#else
+ int i;
+#endif
+ struct ifreq req[16];
+ struct ifconf conf;
+
+ D_MAGIC_ASSERT( player, VoodooPlayer );
+
+ player->broadcast++;
+
+ conf.ifc_buf = (char*) req;
+ conf.ifc_len = sizeof(req);
+
+ ret = ioctl( player->fd, SIOCGIFCONF, &conf );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFCONF ) failed!\n" );
+ return DR_FAILURE;
+ }
+
+#ifdef MACOS
+ // TIV: On iPhone (and I believe in general on BSD, you can't just plainly iterate on struct size)
+
+ lastname[0] = 0;
+
+ for (ptr = conf.ifc_buf; ptr < conf.ifc_buf + conf.ifc_len; )
+ {
+ char buf[100];
+ int len, flags;
+ struct ifreq ifrcopy, *ifr = (struct ifreq *)ptr;
+ struct sockaddr_in *addr = (struct sockaddr_in*) &ifr->ifr_broadaddr;
+
+ len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
+ ptr += sizeof(ifr->ifr_name) + len; // for next one in buffer
+
+ if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0)
+ {
+ continue; /* already processed this interface */
+ }
+
+ memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
+
+ ifrcopy = *ifr;
+ ioctl( player->fd, SIOCGIFFLAGS, &ifrcopy);
+ flags = ifrcopy.ifr_flags;
+ if ((flags & IFF_UP) == 0)
+ {
+ D_INFO( "Voodoo/Player: %-16s is not up.\n", ifrcopy.ifr_name );
+ continue; // ignore if interface not up
+ }
+
+ ret = ioctl( player->fd, SIOCGIFBRDADDR, ifr );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFBRDADDR ) %-16s failed!\n", ifr->ifr_name );
+ continue;
+ }
+
+ if (addr->sin_addr.s_addr) {
+ inet_ntop( AF_INET, &addr->sin_addr, buf, sizeof(buf) );
+
+ D_INFO( "Voodoo/Player: %-16s (%s)\n", ifr->ifr_name, buf );
+ }
+ else {
+ ret = ioctl( player->fd, SIOCGIFDSTADDR, ifr );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFDSTADDR ) failed!\n" );
+ continue;
+ }
+
+ inet_ntop( AF_INET, &addr->sin_addr, buf, sizeof(buf) );
+
+ D_INFO( "Voodoo/Player: %-16s (%s) (P-t-P)\n", ifr->ifr_name, buf );
+ }
+
+ player_send_info( player, &addr->sin_addr.s_addr, true );
+ }
+#else
+ D_INFO( "Voodoo/Player: Detected %d interfaces\n", conf.ifc_len/sizeof(req[0]) );
+
+ for (i=0; i<conf.ifc_len/sizeof(req[0]); i++) {
+ struct sockaddr_in *addr = (struct sockaddr_in*) &req[i].ifr_broadaddr;
+ char buf[100];
+
+ ret = ioctl( player->fd, SIOCGIFBRDADDR, &req[i] );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFBRDADDR ) failed!\n" );
+ continue;
+ }
+
+ if (addr->sin_addr.s_addr) {
+ inet_ntop( AF_INET, &addr->sin_addr, buf, sizeof(buf) );
+
+ D_INFO( "Voodoo/Player: %-16s (%s)\n", req[i].ifr_name, buf );
+ }
+ else {
+ ret = ioctl( player->fd, SIOCGIFDSTADDR, &req[i] );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFDSTADDR ) failed!\n" );
+ continue;
+ }
+
+ inet_ntop( AF_INET, &addr->sin_addr, buf, sizeof(buf) );
+
+ D_INFO( "Voodoo/Player: %-16s (%s) (P-t-P)\n", req[i].ifr_name, buf );
+ }
+
+ //addr->sin_addr.s_addr = inet_addr( "192.168.1.150" );
+ //addr->sin_addr.s_addr = inet_addr( "192.168.255.255" );
+
+ player_send_info( player, &addr->sin_addr.s_addr, true );
+ }
+#endif
+#endif
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_player_lookup( VoodooPlayer *player,
+ const u8 uuid[16],
+ VoodooPlayInfo *ret_info,
+ char *ret_addr,
+ int max_addr )
+{
+ PlayerNode *node;
+
+ D_MAGIC_ASSERT( player, VoodooPlayer );
+
+ pthread_mutex_lock( &player->lock );
+
+ direct_list_foreach (node, player->nodes) {
+ if (!uuid || !memcmp( node->info.uuid, uuid, 16 )) {
+ if (ret_info)
+ direct_memcpy( ret_info, &node->info, sizeof(VoodooPlayInfo) );
+
+ if (ret_addr)
+ direct_snputs( ret_addr, node->addr, max_addr );
+
+ pthread_mutex_unlock( &player->lock );
+ return DR_OK;
+ }
+ }
+
+ if (uuid && !memcmp( player->info.uuid, uuid, 16 )) {
+ if (ret_info)
+ direct_memcpy( ret_info, &player->info, sizeof(VoodooPlayInfo) );
+
+ if (ret_addr)
+ direct_snputs( ret_addr, "127.0.0.1", max_addr );
+
+ pthread_mutex_unlock( &player->lock );
+ return DR_OK;
+ }
+
+ pthread_mutex_unlock( &player->lock );
+
+ return DR_ITEMNOTFOUND;
+}
+
+DirectResult
+voodoo_player_lookup_by_address( VoodooPlayer *player,
+ const char *addr,
+ VoodooPlayInfo *ret_info )
+{
+ PlayerNode *node;
+
+ D_MAGIC_ASSERT( player, VoodooPlayer );
+
+ pthread_mutex_lock( &player->lock );
+
+ direct_list_foreach (node, player->nodes) {
+ if (!addr || !strcmp( node->addr, addr )) {
+ direct_memcpy( ret_info, &node->info, sizeof(VoodooPlayInfo) );
+
+ pthread_mutex_unlock( &player->lock );
+ return DR_OK;
+ }
+ }
+
+ if (addr && !strcmp( "127.0.0.1", addr )) {
+ direct_memcpy( ret_info, &player->info, sizeof(VoodooPlayInfo) );
+
+ pthread_mutex_unlock( &player->lock );
+ return DR_OK;
+ }
+
+ pthread_mutex_unlock( &player->lock );
+
+ return DR_ITEMNOTFOUND;
+}
+
+DirectResult
+voodoo_player_enumerate( VoodooPlayer *player,
+ VoodooPlayerCallback callback,
+ void *ctx )
+{
+ PlayerNode *node;
+ long long now = direct_clock_get_abs_millis();
+
+
+ D_MAGIC_ASSERT( player, VoodooPlayer );
+
+ pthread_mutex_lock( &player->lock );
+
+ direct_list_foreach (node, player->nodes) {
+ if (node->broadcast != player->broadcast && direct_clock_get_abs_millis() - node->last_seen > 1000)
+ continue;
+
+ if (callback( ctx, &node->info, &node->version,
+ node->addr, now - node->last_seen ) == DENUM_CANCEL)
+ break;
+ }
+
+ pthread_mutex_unlock( &player->lock );
+
+ return DR_OK;
+}
+
+/**********************************************************************************************************************/
+
+__attribute__((unused))
+static void
+player_send_info( VoodooPlayer *player,
+ const in_addr_t *in_addr,
+ bool discover )
+{
+ int ret;
+ struct sockaddr_in addr;
+ VoodooPlayMessage msg;
+ PlayerNode *node;
+
+ D_MAGIC_ASSERT( player, VoodooPlayer );
+
+ msg.version = player->version;
+ msg.type = discover ? VPMT_DISCOVER : VPMT_SENDINFO;
+ msg.info = player->info;
+
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = *in_addr;
+ addr.sin_port = htons( 2323 );
+
+ ret = sendto( player->fd, &msg, sizeof(msg), 0, (struct sockaddr*) &addr, sizeof(addr) );
+ if (ret < 0) {
+ D_PERROR( "Voodoo/Player: sendto() failed!\n" );
+ return;
+ }
+
+ if (!discover && voodoo_config->forward_nodes) {
+ direct_list_foreach (node, player->nodes) {
+ VoodooPlayInfo info = node->info;
+
+ info.flags |= VPIF_LEVEL2;
+
+ msg.version = node->version;
+ msg.type = discover ? VPMT_DISCOVER : VPMT_SENDINFO;
+ msg.info = info;
+
+ ret = sendto( player->fd, &msg, sizeof(msg), 0, (struct sockaddr*) &addr, sizeof(addr) );
+ if (ret < 0) {
+ D_PERROR( "Voodoo/Player: sendto() failed!\n" );
+ return;
+ }
+ }
+ }
+}
+
+static void
+player_save_info( VoodooPlayer *player,
+ const VoodooPlayMessage *msg,
+ const char *addr )
+{
+ PlayerNode *node;
+
+ D_MAGIC_ASSERT( player, VoodooPlayer );
+
+ direct_list_foreach (node, player->nodes) {
+ if (!memcmp( node->info.uuid, msg->info.uuid, 16 )) {
+ if (msg->info.flags & VPIF_LEVEL2 && !(node->info.flags & VPIF_LEVEL2)) {
+ node->version = msg->version;
+ node->info = msg->info;
+
+ direct_snputs( node->addr, addr, sizeof(node->addr) );
+ }
+ node->version = msg->version;
+ node->info = msg->info;
+
+ node->last_seen = direct_clock_get_abs_millis();
+ node->broadcast = player->broadcast;
+
+ direct_snputs( node->addr, addr, sizeof(node->addr) );
+
+ return;
+
+ }
+ }
+
+ node = D_CALLOC( 1, sizeof(PlayerNode) );
+ if (!node) {
+ D_OOM();
+ return;
+ }
+
+ node->version = msg->version;
+ node->info = msg->info;
+
+ node->last_seen = direct_clock_get_abs_millis();
+ node->broadcast = player->broadcast;
+
+ direct_snputs( node->addr, addr, sizeof(node->addr) );
+
+
+ direct_list_append( &player->nodes, &node->link );
+}
+
+#if !VOODOO_PLAY_FAKE
+static void *
+player_main_loop( DirectThread *thread, void *arg )
+{
+ VoodooPlayer *player = arg;
+ int ret;
+ struct sockaddr_in addr;
+ socklen_t addr_len = sizeof(addr);
+ VoodooPlayMessage msg;
+ char buf[100];
+
+ D_MAGIC_ASSERT( player, VoodooPlayer );
+
+ while (!player->quit) {
+ struct pollfd pf;
+
+ pf.fd = player->fd;
+ pf.events = POLLIN;
+
+ switch (poll( &pf, 1, 100 )) {
+ default:
+ ret = recvfrom( player->fd, &msg, sizeof(msg), 0, (struct sockaddr*) &addr, &addr_len );
+ if (ret < 0) {
+ D_PERROR( "Voodoo/Player: recvfrom() failed!\n" );
+ close(player->fd);
+ ret = createSocketForPlayer(&player->fd);
+
+ continue;
+ }
+
+ inet_ntop( AF_INET, &addr.sin_addr, buf, sizeof(buf) );
+
+ pthread_mutex_lock( &player->lock );
+
+ /* Send reply if message is not from ourself */
+ if (memcmp( msg.info.uuid, player->info.uuid, 16 )) {
+ switch (msg.type) {
+ case VPMT_DISCOVER:
+ D_INFO( "Voodoo/Player: Received DISCOVER from '%s' (%s)\n", msg.info.name, buf );
+ player_send_info( player, &addr.sin_addr.s_addr, false );
+ break;
+
+ case VPMT_SENDINFO:
+ D_INFO( "Voodoo/Player: Received SENDINFO from '%s' (%s)\n", msg.info.name, buf );
+ player_save_info( player, &msg, buf );
+ break;
+
+ default:
+ D_ERROR( "Voodoo/Player: Received unknown message (%s)\n", buf );
+ break;
+ }
+ }
+ else
+ D_INFO( "Voodoo/Player: Received message from ourself (%s)\n", buf );
+
+ pthread_mutex_unlock( &player->lock );
+ break;
+
+ case 0:
+ D_DEBUG( "Voodoo/Player: Timeout during poll()\n" );
+ break;
+
+ case -1:
+ if (errno != EINTR) {
+ D_PERROR( "Voodoo/Player: Could not poll() the socket!\n" );
+ close(player->fd);
+ ret = createSocketForPlayer(&player->fd);
+ // player->quit = true;
+ }
+ break;
+ }
+ }
+
+ return DR_OK;
+}
+#else
+
+static DirectResult
+send_discover_and_receive_info( int fd,
+ VoodooPlayVersion *ret_version,
+ VoodooPlayInfo *ret_info )
+{
+ int ret;
+ VoodooMessageHeader header;
+
+ D_INFO( "Voodoo/Player: Sending VMSG_DISCOVER message via Voodoo TCP port...\n" );
+
+ header.size = sizeof(VoodooMessageHeader);
+ header.serial = 0;
+ header.type = VMSG_DISCOVER;
+
+ ret = write( fd, &header, sizeof(header) );
+ if (ret < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Player: Failed to send VMSG_DISCOVER message via Voodoo TCP port!\n" );
+ return ret;
+ }
+
+
+
+ struct pollfd pfd;
+
+ pfd.events = POLL_IN;
+ pfd.fd = fd;
+
+ // wait for up to one second (old server will not reply anything, so we have to timeout)
+ ret = poll( &pfd, 1, 1000 );
+ if (ret < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Player: Failed to wait for reply after sending VMSG_DISCOVER message via Voodoo TCP port!\n" );
+ return ret;
+ }
+
+ if (ret == 0) {
+ D_INFO( "Voodoo/Player: Old Voodoo Server without VMSG_DISCOVER support (timeout waiting for reply)\n" );
+ return DR_UNSUPPORTED;
+ }
+
+ D_INFO( "Voodoo/Player: New Voodoo Server with VMSG_DISCOVER support, reading version/info (SENDINFO) reply...\n" );
+
+
+ struct {
+ VoodooMessageHeader header;
+ VoodooPlayVersion version;
+ VoodooPlayInfo info;
+ } msg;
+
+ size_t got = 0;
+
+ while (got < sizeof(msg)) {
+ ret = read( fd, (void*) &msg + got, sizeof(msg) - got );
+ if (ret < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Player: Failed to read after sending VMSG_DISCOVER message via Voodoo TCP port!\n" );
+ return ret;
+ }
+
+ got += ret;
+ }
+
+
+ if (msg.header.type != VMSG_SENDINFO) {
+ D_ERROR( "Voodoo/Player: Received message after sending VMSG_DISCOVER message via Voodoo TCP port is no VMSG_SENDINFO!\n");
+ return DR_INVARG;
+ }
+
+ *ret_version = msg.version;
+ *ret_info = msg.info;
+
+ D_INFO( "Voodoo/Player: Voodoo Server sent name '%s', version %d.%d.%d\n",
+ msg.info.name, msg.version.v[1], msg.version.v[2], msg.version.v[3] );
+
+ return DR_OK;
+}
+
+static void
+player_try_connect( VoodooPlayer *player,
+ u32 addr )
+{
+ DirectResult ret;
+ int fd, err;
+ struct in_addr sin_addr = { addr };
+
+ char buf[100];
+
+ inet_ntop( AF_INET, &sin_addr, buf, sizeof(buf) );
+
+
+ /* Create the client socket. */
+ fd = socket( AF_INET, SOCK_STREAM, 0 );
+ if (fd < 0) {
+ D_PERROR( "Voodoo/Player: Could not create the socket via socket( %d )!\n", AF_INET );
+ return;
+ }
+
+ struct sockaddr_in sock_addr;
+
+ sock_addr.sin_family = AF_INET;
+ sock_addr.sin_port = htons( 2323 );
+ sock_addr.sin_addr = sin_addr;
+
+ /* Connect to the server. */
+ err = connect( fd, (struct sockaddr*) &sock_addr, sizeof(sock_addr) );
+ if (err) {
+ D_PERROR( "Voodoo/Player: No Voodoo at '%s:2323'", buf );
+ close( fd );
+ return;
+ }
+
+ D_INFO( "Voodoo/Player: Found Voodoo at '%s'!\n", buf );
+
+
+ VoodooPlayMessage msg;
+
+
+ ret = send_discover_and_receive_info( fd, &msg.version, &msg.info );
+ if (ret) {
+ /* Fill version struct */
+ msg.version.v[0] = VPVF_LITTLE_ENDIAN | VPVF_32BIT_SERIALS;
+ msg.version.v[1] = DIRECTFB_MAJOR_VERSION;
+ msg.version.v[2] = DIRECTFB_MINOR_VERSION;
+ msg.version.v[3] = DIRECTFB_MICRO_VERSION;
+
+ msg.type = VPMT_SENDINFO;
+
+ /* Fill info struct */
+ direct_snputs( msg.info.name, "Unknown", VOODOO_PLAYER_NAME_LENGTH );
+ direct_snputs( msg.info.vendor, "Unknown", VOODOO_PLAYER_VENDOR_LENGTH );
+ direct_snputs( msg.info.model, "Unknown", VOODOO_PLAYER_MODEL_LENGTH );
+ generate_uuid( msg.info.uuid );
+ }
+
+
+ close( fd );
+
+
+ pthread_mutex_lock( &player->lock );
+
+ player_save_info( player, &msg, buf );
+
+ pthread_mutex_unlock( &player->lock );
+}
+
+typedef struct {
+ VoodooPlayer *player;
+ u32 addr;
+} PlayerTryContext;
+
+static void *
+player_try_thread( void *arg )
+{
+ PlayerTryContext *context = arg;
+
+ player_try_connect( context->player, context->addr );
+
+ D_FREE( context );
+
+ return NULL;
+}
+
+static void *
+player_main_loop( DirectThread *thread, void *arg )
+{
+ VoodooPlayer *player = arg;
+ int ret;
+ int i;
+ struct ifreq req[16];
+ struct ifconf conf;
+
+ D_MAGIC_ASSERT( player, VoodooPlayer );
+
+// while (!player->quit) {
+ conf.ifc_buf = (char*) req;
+ conf.ifc_len = sizeof(req);
+
+ ret = ioctl( player->fd, SIOCGIFCONF, &conf );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFCONF ) failed!\n" );
+ return NULL;
+ }
+
+ D_INFO( "Voodoo/Player: Detected %d interfaces\n", conf.ifc_len/sizeof(req[0]) );
+
+ for (i=0; i<conf.ifc_len/sizeof(req[0]); i++) {
+ struct sockaddr_in *addr = (struct sockaddr_in*) &req[i].ifr_broadaddr;
+ char buf[100];
+
+ ret = ioctl( player->fd, SIOCGIFBRDADDR, &req[i] );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFBRDADDR ) failed!\n" );
+ continue;
+ }
+
+ if (addr->sin_addr.s_addr) {
+ inet_ntop( AF_INET, &addr->sin_addr, buf, sizeof(buf) );
+
+ D_INFO( "Voodoo/Player: %-16s (%s) [0x%08x]\n", req[i].ifr_name, buf, addr->sin_addr.s_addr );
+
+ u32 _addr = htonl( addr->sin_addr.s_addr );
+ u32 a;
+
+ for (a = (_addr & ~0xff) + 1; a < (_addr | 0xff); a++) {
+ if (a == _addr)
+ continue;
+
+ PlayerTryContext *context = D_CALLOC( 1, sizeof(PlayerTryContext) );
+
+ context->player = player;
+ context->addr = ntohl(a);
+
+
+ pthread_t t;
+
+ pthread_create( &t, NULL, player_try_thread, context );
+ }
+ }
+ else {
+ ret = ioctl( player->fd, SIOCGIFDSTADDR, &req[i] );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFDSTADDR ) failed!\n" );
+ continue;
+ }
+
+ inet_ntop( AF_INET, &addr->sin_addr, buf, sizeof(buf) );
+
+ D_INFO( "Voodoo/Player: %-16s (%s) (P-t-P)\n", req[i].ifr_name, buf );
+ }
+ }
+// }
+
+ return DR_OK;
+}
+#endif
+
diff --git a/Source/DirectFB/lib/voodoo/play.h b/Source/DirectFB/lib/voodoo/play.h
new file mode 100755
index 0000000..1dc50df
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/play.h
@@ -0,0 +1,146 @@
+/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__PLAY_H__
+#define __VOODOO__PLAY_H__
+
+#include <voodoo/types.h>
+
+
+#define VOODOO_PLAY_VERSION_FIXED_SIZE 32
+
+#define VOODOO_PLAYER_NAME_LENGTH 96
+
+#define VOODOO_PLAYER_VENDOR_LENGTH 96
+#define VOODOO_PLAYER_MODEL_LENGTH 96
+
+
+#define VOODOO_LINK_PORT 8676 // 'V' 'L'
+
+
+typedef enum {
+ VPVF_NONE = 0x00000000,
+
+ VPVF_LITTLE_ENDIAN = 0x00000001, /* Always set, no big endian support for now */
+ VPVF_32BIT_SERIALS = 0x00000002, /* Using 32bit message serials, always set */
+
+ VPVF_ALL = 0x00000007
+} VoodooPlayVersionFlags;
+
+typedef struct {
+ u8 v[4]; /* flags, major, minor, micro */
+} VoodooPlayVersion;
+
+
+typedef enum {
+ VPIF_NONE = 0x00000000,
+
+ VPIF_LEVEL2 = 0x00000001,
+ VPIF_LINK = 0x00000002, /* Supports new VoodooLink protocol */
+
+ VPIF_ALL = 0x00000003
+} VoodooPlayInfoFlags;
+
+typedef struct {
+ VoodooPlayInfoFlags flags;
+
+ u8 uuid[16];
+
+ char name[VOODOO_PLAYER_NAME_LENGTH]; /* "My Philips TV" */
+
+ char vendor[VOODOO_PLAYER_VENDOR_LENGTH]; /* "Philips Consumer Lifestyle" */
+ char model[VOODOO_PLAYER_MODEL_LENGTH]; /* "32PFL9604H/10" */
+} VoodooPlayInfo;
+
+
+typedef enum {
+ VPMT_INVALID,
+
+ VPMT_DISCOVER,
+ VPMT_SENDINFO,
+} VoodooPlayMessageType;
+
+
+
+/*
+
+ One play message on a new connection from both sides.
+ Both sides having received the other side's info know if the connection is to be closed or can succeed.
+
+ Game about endianness conversion: both sides randomly send 0 or 1 as part of the info,
+ if both are equal, then server converts, otherwise client
+*/
+
+typedef struct {
+ /* Version information first in structure, fixed size (union!) */
+ union {
+ char __fixed[VOODOO_PLAY_VERSION_FIXED_SIZE];
+
+
+ VoodooPlayVersion version; /* (1.0, ...) */
+ };
+
+ VoodooPlayMessageType type;
+
+ union {
+ VoodooPlayInfo info; /* DISCOVER, SENDINFO */
+ };
+} VoodooPlayMessage;
+
+
+typedef DirectEnumerationResult (*VoodooPlayerCallback)( void *ctx,
+ const VoodooPlayInfo *info,
+ const VoodooPlayVersion *version,
+ const char *address,
+ unsigned int ms_since_last_seen );
+
+
+DirectResult voodoo_player_create ( const VoodooPlayInfo *info,
+ VoodooPlayer **ret_player );
+
+DirectResult voodoo_player_destroy ( VoodooPlayer *player );
+
+DirectResult voodoo_player_broadcast ( VoodooPlayer *player );
+
+DirectResult voodoo_player_lookup ( VoodooPlayer *player,
+ const u8 uuid[16],
+ VoodooPlayInfo *ret_info,
+ char *ret_addr,
+ int max_addr );
+
+DirectResult voodoo_player_lookup_by_address( VoodooPlayer *player,
+ const char *addr,
+ VoodooPlayInfo *ret_info );
+
+DirectResult voodoo_player_enumerate ( VoodooPlayer *player,
+ VoodooPlayerCallback callback,
+ void *ctx );
+
+
+#endif
+
diff --git a/Source/DirectFB/lib/voodoo/play_internal.h b/Source/DirectFB/lib/voodoo/play_internal.h
new file mode 100755
index 0000000..0aa0f91
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/play_internal.h
@@ -0,0 +1,89 @@
+/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__PLAY_INTERNAL_H__
+#define __VOODOO__PLAY_INTERNAL_H__
+
+#include <voodoo/app.h>
+#include <voodoo/play.h>
+#include <voodoo/play_server.h>
+
+#include <direct/list.h>
+#include <direct/thread.h>
+
+
+struct __V_VoodooPlayer {
+ int magic;
+
+ int fd;
+
+ pthread_mutex_t lock;
+
+ bool quit;
+
+ VoodooPlayVersion version;
+ VoodooPlayInfo info;
+
+ DirectThread *thread;
+
+ DirectLink *nodes;
+
+ long long broadcast;
+
+ VoodooServer *server;
+
+ const VoodooAppDescription *apps;
+ unsigned int num_apps;
+
+ VoodooPlayerLaunchFunc launch_func;
+ VoodooPlayerStopFunc stop_func;
+ void *ctx;
+
+ DirectLink *instances;
+ pthread_mutex_t instances_lock;
+ pthread_cond_t instances_cond;
+};
+
+
+typedef struct {
+ DirectLink link;
+
+ u8 uuid[16];
+
+ void *data;
+
+ VoodooAppDescription app;
+ u8 player_uuid[16];
+} VoodooAppInstance;
+
+
+extern VoodooPlayVersion g_VoodooPlay_version;
+extern VoodooPlayInfo g_VoodooPlay_info;
+
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/play_server.c b/Source/DirectFB/lib/voodoo/play_server.c
new file mode 100755
index 0000000..1e933f5
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/play_server.c
@@ -0,0 +1,430 @@
+/*
+ (c) Copyright 2001-2010 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+
+#include <directfb_version.h>
+
+#include <direct/clock.h>
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <voodoo/conf.h>
+#include <voodoo/internal.h>
+#include <voodoo/play_server.h>
+#include <voodoo/play_internal.h>
+#include <voodoo/server.h>
+
+D_DEBUG_DOMAIN( Voodoo_Play_Server, "Voodoo/Play/Server", "Voodoo Play Server" );
+
+/**********************************************************************************************************************/
+
+VoodooPlayer *voodoo_player;
+
+/**********************************************************************************************************************/
+/*
+ * FIXME
+ */
+static void
+generate_uuid( u8 *buf )
+{
+ int i;
+
+ for (i=0; i<16; i++) {
+ buf[i] = rand();
+ }
+}
+
+static DirectResult
+ConstructDispatcher( VoodooServer *server,
+ VoodooManager *manager,
+ const char *name,
+ void *ctx,
+ VoodooInstanceID *ret_instance )
+{
+ DirectResult ret;
+ DirectInterfaceFuncs *funcs;
+ void *interface;
+ VoodooInstanceID instance;
+
+ D_ASSERT( server != NULL );
+ D_ASSERT( manager != NULL );
+ D_ASSERT( name != NULL );
+ D_ASSERT( ret_instance != NULL );
+
+ ret = DirectGetInterface( &funcs, name, "Dispatcher", NULL, NULL );
+ if (ret)
+ return ret;
+
+ ret = funcs->Allocate( &interface );
+ if (ret)
+ return ret;
+
+ ret = funcs->Construct( interface, manager, &instance );
+ if (ret)
+ return ret;
+
+ *ret_instance = instance;
+
+ return DR_OK;
+}
+
+/**********************************************************************************************************************/
+
+DirectResult
+voodoo_player_run_server( VoodooPlayer *player,
+ const VoodooAppDescription *apps,
+ unsigned int num_apps,
+ VoodooPlayerLaunchFunc launch_func,
+ VoodooPlayerStopFunc stop_func,
+ void *ctx )
+{
+ DirectResult ret;
+ VoodooServer *server;
+
+ D_ASSERT( player != NULL );
+ D_ASSERT( apps != NULL );
+ D_ASSERT( num_apps > 0 );
+ D_ASSERT( launch_func != NULL );
+
+ if (voodoo_player) {
+ D_ERROR( "Voodoo/Play: Already running as a server!\n" );
+ return DR_BUSY;
+ }
+
+ ret = voodoo_server_create( &server );
+ if (ret)
+ return ret;
+
+ ret = voodoo_server_register( server, "IVoodooPlayer", ConstructDispatcher, NULL );
+ if (ret) {
+ D_ERROR( "Voodoo/Player: Could not register super interface 'IVoodooPlayer'!\n" );
+ voodoo_server_destroy( server );
+ return ret;
+ }
+
+ player->server = server;
+ player->apps = apps;
+ player->num_apps = num_apps;
+ player->launch_func = launch_func;
+ player->stop_func = stop_func;
+ player->ctx = ctx;
+
+ pthread_mutex_init( &player->instances_lock, NULL );
+ pthread_cond_init( &player->instances_cond, NULL );
+
+ voodoo_player = player;
+
+ ret = voodoo_server_run( server, false );
+ if (ret)
+ D_DERROR( ret, "Voodoo/Player: Server exiting!\n" );
+
+ voodoo_player = NULL;
+
+ player->server = NULL;
+ player->apps = NULL;
+ player->num_apps = 0;
+ player->launch_func = NULL;
+ player->stop_func = NULL;
+ player->ctx = NULL;
+ player->instances = NULL;
+
+ pthread_mutex_destroy( &player->instances_lock );
+ pthread_cond_destroy( &player->instances_cond );
+
+ voodoo_server_destroy( server );
+
+ return ret;
+}
+
+DirectResult
+voodoo_player_get_apps( VoodooPlayer *player,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppDescription *ret_apps )
+{
+ D_ASSERT( player != NULL );
+ D_ASSERT( ret_num != NULL );
+ D_ASSERT( ret_apps != NULL );
+
+ ///
+
+ unsigned int num = max_num;
+
+ if (num > player->num_apps)
+ num = player->num_apps;
+
+ *ret_num = num;
+
+ direct_memcpy( ret_apps, player->apps, sizeof(VoodooAppDescription) * num );
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_player_launch_app( VoodooPlayer *player,
+ const u8 app_uuid[16],
+ const u8 player_uuid[16],
+ u8 ret_instance_uuid[16] )
+{
+ DirectResult ret;
+ int i;
+
+ D_ASSERT( player != NULL );
+ D_ASSERT( app_uuid != NULL );
+ D_ASSERT( player_uuid != NULL );
+ D_ASSERT( ret_instance_uuid != NULL );
+
+
+ char buf1[33];
+ char buf2[33];
+
+ snprintf( buf1, sizeof(buf1), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ app_uuid[0], app_uuid[1], app_uuid[2], app_uuid[3], app_uuid[4],
+ app_uuid[5], app_uuid[6], app_uuid[7], app_uuid[8], app_uuid[9],
+ app_uuid[10], app_uuid[11], app_uuid[12], app_uuid[13], app_uuid[14],
+ app_uuid[15] );
+
+ snprintf( buf2, sizeof(buf2), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ player_uuid[0], player_uuid[1], player_uuid[2], player_uuid[3], player_uuid[4],
+ player_uuid[5], player_uuid[6], player_uuid[7], player_uuid[8], player_uuid[9],
+ player_uuid[10], player_uuid[11], player_uuid[12], player_uuid[13], player_uuid[14],
+ player_uuid[15] );
+
+ D_INFO( "Voodoo/Player: Launching application %s on %s...\n", buf1, buf2 );
+
+
+ const VoodooAppDescription *app = NULL;
+
+ for (i=0; i<player->num_apps; i++) {
+ if (!memcmp( app_uuid, player->apps[i].uuid, 16 )) {
+ app = &player->apps[i];
+ break;
+ }
+ }
+
+ if (!app) {
+ D_ERROR( "Voodoo/Player: Could not lookup application with UUID %s!\n", buf1 );
+ return DR_ITEMNOTFOUND;
+ }
+
+
+ VoodooPlayInfo info;
+ char addr[1000];
+
+
+ voodoo_player_broadcast( player );
+ sleep( 1 );
+
+ ret = voodoo_player_lookup( player, player_uuid, &info, addr, sizeof(addr) );
+ if (ret) {
+ if ( (player_uuid[0]==0xf0) && (player_uuid[1]==0xf0) && (player_uuid[2]==0xf0) && (player_uuid[3]==0xf0)
+ && (player_uuid[4]==0xf0) && (player_uuid[5]==0xf0) && (player_uuid[6]==0xf0) && (player_uuid[7]==0xf0)
+ && (player_uuid[8]==0xf0) && (player_uuid[9]==0xf0) && (player_uuid[10]==0xf0) && (player_uuid[11]==0xf0) )
+ {
+ sprintf(addr, "%d.%d.%d.%d", player_uuid[12], player_uuid[13], player_uuid[14], player_uuid[15]);
+ }
+ else
+ {
+ D_DERROR( ret, "Voodoo/Player: Could not lookup player with UUID %s!\n", buf2 );
+ return ret;
+ }
+ }
+
+
+ VoodooAppInstance *instance;
+
+ instance = D_CALLOC( 1, sizeof(VoodooAppInstance) );
+ if (!instance)
+ return D_OOM();
+
+ ret = player->launch_func( player, player->ctx, app, &info, addr, &instance->data );
+ if (ret) {
+ D_DERROR( ret, "Voodoo/Player: Could not launch application '%s'\n", app->name );
+ D_FREE( instance );
+ return ret;
+ }
+
+ generate_uuid( instance->uuid );
+
+ direct_memcpy( &instance->app, app, sizeof(VoodooAppDescription) );
+ direct_memcpy( instance->player_uuid, player_uuid, 16 );
+
+
+
+ pthread_mutex_lock( &player->instances_lock );
+
+ direct_list_append( &player->instances, &instance->link );
+
+ direct_memcpy( ret_instance_uuid, instance->uuid, 16 );
+
+ pthread_mutex_unlock( &player->instances_lock );
+
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_player_stop_instance( VoodooPlayer *player,
+ const u8 instance_uuid[16] )
+{
+ DirectResult ret;
+ char buf1[33];
+ VoodooAppInstance *instance;
+
+ snprintf( buf1, sizeof(buf1), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ instance_uuid[0], instance_uuid[1], instance_uuid[2], instance_uuid[3], instance_uuid[4],
+ instance_uuid[5], instance_uuid[6], instance_uuid[7], instance_uuid[8], instance_uuid[9],
+ instance_uuid[10], instance_uuid[11], instance_uuid[12], instance_uuid[13], instance_uuid[14],
+ instance_uuid[15] );
+
+ D_INFO( "Voodoo/Player: Stopping instance %s...\n", buf1 );
+
+ pthread_mutex_lock( &player->instances_lock );
+
+ direct_list_foreach (instance, player->instances) {
+ if (!memcmp( instance->uuid, instance_uuid, 16 ))
+ break;
+ }
+
+ if (!instance) {
+ D_ERROR( "Voodoo/Player: Could not find instance with UUID %s!\n", buf1 );
+ pthread_mutex_unlock( &player->instances_lock );
+ return DR_NOSUCHINSTANCE;
+ }
+
+ ret = player->stop_func( player, player->ctx, instance->data );
+ if (ret) {
+ D_DERROR( ret, "Voodoo/Player: Could not stop instance with UUID %s!\n", buf1 );
+ pthread_mutex_unlock( &player->instances_lock );
+ return ret;
+ }
+
+ direct_list_remove( &player->instances, &instance->link );
+
+ pthread_cond_broadcast( &player->instances_cond );
+
+ pthread_mutex_unlock( &player->instances_lock );
+
+ D_FREE( instance );
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_player_wait_instance( VoodooPlayer *player,
+ const u8 instance_uuid[16] )
+{
+ char buf1[33];
+ VoodooAppInstance *instance;
+
+ snprintf( buf1, sizeof(buf1), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ instance_uuid[0], instance_uuid[1], instance_uuid[2], instance_uuid[3], instance_uuid[4],
+ instance_uuid[5], instance_uuid[6], instance_uuid[7], instance_uuid[8], instance_uuid[9],
+ instance_uuid[10], instance_uuid[11], instance_uuid[12], instance_uuid[13], instance_uuid[14],
+ instance_uuid[15] );
+
+ D_INFO( "Voodoo/Player: Waiting for instance %s...\n", buf1 );
+
+
+ do {
+ pthread_mutex_lock( &player->instances_lock );
+
+ direct_list_foreach (instance, player->instances) {
+ if (!memcmp( instance->uuid, instance_uuid, 16 )) {
+ pthread_cond_wait( &player->instances_cond, &player->instances_lock );
+ break;
+ }
+ }
+
+ pthread_mutex_unlock( &player->instances_lock );
+ } while (instance);
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_player_get_instances( VoodooPlayer *player,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppInstanceDescription *ret_instances )
+{
+ VoodooAppInstance *instance;
+
+ D_ASSERT( player != NULL );
+ D_ASSERT( ret_num != NULL );
+ D_ASSERT( ret_instances != NULL );
+
+ ///
+
+ pthread_mutex_lock( &player->instances_lock );
+
+ unsigned int i = 0;
+
+ direct_list_foreach (instance, player->instances) {
+ if (i == max_num)
+ break;
+
+ direct_memcpy( ret_instances[i].uuid, instance->uuid, 16 );
+ direct_memcpy( &ret_instances[i].app, &instance->app, sizeof(VoodooAppDescription) );
+ direct_memcpy( ret_instances[i].player_uuid, instance->player_uuid, 16 );
+
+ i++;
+ }
+
+ *ret_num = i;
+
+ pthread_mutex_unlock( &player->instances_lock );
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/play_server.h b/Source/DirectFB/lib/voodoo/play_server.h
new file mode 100755
index 0000000..9677e7e
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/play_server.h
@@ -0,0 +1,79 @@
+/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__PLAY_SERVER_H__
+#define __VOODOO__PLAY_SERVER_H__
+
+#include <voodoo/app.h>
+#include <voodoo/play.h>
+
+
+typedef DirectResult (*VoodooPlayerLaunchFunc)( VoodooPlayer *player,
+ void *ctx,
+ const VoodooAppDescription *app,
+ const VoodooPlayInfo *player_info,
+ const char *player_addr,
+ void **ret_data );
+
+typedef DirectResult (*VoodooPlayerStopFunc) ( VoodooPlayer *player,
+ void *ctx,
+ void *data );
+
+
+DirectResult voodoo_player_run_server ( VoodooPlayer *player,
+ const VoodooAppDescription *apps,
+ unsigned int num_apps,
+ VoodooPlayerLaunchFunc launch_func,
+ VoodooPlayerStopFunc stop_func,
+ void *ctx );
+
+DirectResult voodoo_player_get_apps ( VoodooPlayer *player,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppDescription *ret_apps );
+
+DirectResult voodoo_player_launch_app ( VoodooPlayer *player,
+ const u8 app_uuid[16],
+ const u8 player_uuid[16],
+ u8 ret_instance_uuid[16] );
+
+DirectResult voodoo_player_stop_instance( VoodooPlayer *player,
+ const u8 instance_uuid[16] );
+
+DirectResult voodoo_player_wait_instance( VoodooPlayer *player,
+ const u8 instance_uuid[16] );
+
+DirectResult voodoo_player_get_instances( VoodooPlayer *player,
+ unsigned int max_num,
+ unsigned int *ret_num,
+ VoodooAppInstanceDescription *ret_instances );
+
+
+extern VoodooPlayer *voodoo_player;
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/server.c b/Source/DirectFB/lib/voodoo/server.c
new file mode 100755
index 0000000..0c543b6
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/server.c
@@ -0,0 +1,459 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/mman.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+
+#include <semaphore.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+
+#include <direct/clock.h>
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <voodoo/server.h>
+#include <voodoo/internal.h>
+#include <voodoo/link.h>
+#include <voodoo/manager.h>
+
+
+typedef struct {
+ sem_t sem;
+
+ pid_t gfxpid;
+} ServerShared;
+
+typedef struct {
+ DirectLink link;
+
+ VoodooLink vl;
+ VoodooManager *manager;
+} Connection;
+
+typedef struct {
+ const char *name;
+ VoodooSuperConstruct func;
+ void *ctx;
+
+ IAny *interface;
+} Super;
+
+#define MAX_SUPER 8
+
+struct __V_VoodooServer {
+ int fd;
+
+ bool quit;
+ DirectLink *connections;
+
+ int num_super;
+ Super supers[MAX_SUPER];
+
+ ServerShared *shared;
+};
+
+/**************************************************************************************************/
+
+static DirectResult accept_connection( VoodooServer *server, int fd );
+
+/**************************************************************************************************/
+
+static const int one = 1;
+
+/**************************************************************************************************/
+
+DirectResult
+voodoo_server_create( VoodooServer **ret_server )
+{
+ DirectResult ret;
+ struct sockaddr_in addr;
+ int fd = -1;
+ VoodooServer *server = NULL;
+
+ D_ASSERT( ret_server != NULL );
+
+ /* Create the server socket. */
+ fd = socket( PF_INET, SOCK_STREAM, 0 );
+ if (fd < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Server: Could not create the socket via socket()!\n" );
+ goto error;
+ }
+
+ /* Allow reuse of local address. */
+ if (setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one) ) < 0)
+ D_PERROR( "Voodoo/Server: Could not set SO_REUSEADDR!\n" );
+
+ /* Bind the socket to the local port. */
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr( "0.0.0.0" );
+ addr.sin_port = htons( 2323 );
+
+ if (bind( fd, &addr, sizeof(addr) )) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Server: Could not bind() the socket!\n" );
+ goto error;
+ }
+
+ /* Start listening. */
+ if (listen( fd, 4 )) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Server: Could not listen() to the socket!\n" );
+ goto error;
+ }
+
+ /* Allocate server structure. */
+ server = D_CALLOC( 1, sizeof(VoodooServer) );
+ if (!server) {
+ ret = D_OOM();
+ D_WARN( "out of memory" );
+ goto error;
+ }
+
+ /* Initialize server structure. */
+ server->fd = fd;
+
+ {
+ int zfd;
+
+ zfd = open( "/dev/zero", O_RDWR );
+ if (zfd < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Server: Failed to open /dev/zero!\n" );
+ goto error;
+ }
+
+ server->shared = mmap( NULL, sizeof(ServerShared), PROT_READ | PROT_WRITE, MAP_SHARED, zfd, 0 );
+
+ close( zfd );
+
+ if (server->shared == MAP_FAILED) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Server: Failed to mmap /dev/zero!\n" );
+ server->shared = NULL;
+ goto error;
+ }
+
+ if (sem_init( &server->shared->sem, 1, 1 )) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Server: Failed to create process shared semaphore!\n" );
+ goto error;
+ }
+ }
+
+ /* Return the new server. */
+ *ret_server = server;
+
+ return DR_OK;
+
+
+error:
+ if (server) {
+ if (server->shared)
+ munmap( server->shared, sizeof(ServerShared) );
+
+ D_FREE( server );
+ }
+
+ if (fd >= 0)
+ close( fd );
+
+ return ret;
+}
+
+DirectResult
+voodoo_server_register( VoodooServer *server,
+ const char *name,
+ VoodooSuperConstruct func,
+ void *ctx )
+{
+ Super *super;
+
+ D_ASSERT( server != NULL );
+ D_ASSERT( name != NULL );
+ D_ASSERT( func != NULL );
+
+ if (server->num_super == MAX_SUPER)
+ return DR_LIMITEXCEEDED;
+
+ super = &server->supers[server->num_super++];
+
+ super->name = name;
+ super->func = func;
+ super->ctx = ctx;
+
+ return DR_OK;
+}
+
+static inline Super *
+lookup_super( VoodooServer *server,
+ const char *name )
+{
+ int i;
+
+ D_ASSERT( server != NULL );
+ D_ASSERT( name != NULL );
+
+ for (i=0; i<server->num_super; i++) {
+ Super *super = &server->supers[i];
+
+ if (! strcmp( name, super->name ))
+ return super;
+ }
+
+ return NULL;
+}
+
+DirectResult
+voodoo_server_construct( VoodooServer *server,
+ VoodooManager *manager,
+ const char *name,
+ VoodooInstanceID *ret_instance )
+{
+ DirectResult ret;
+ Super *super;
+ VoodooInstanceID instance;
+
+ D_ASSERT( server != NULL );
+ D_ASSERT( manager != NULL );
+ D_ASSERT( name != NULL );
+ D_ASSERT( ret_instance != NULL );
+
+ super = lookup_super( server, name );
+ if (!super) {
+ D_ERROR( "Voodoo/Server: Super interface '%s' is not available!\n", name );
+ return DR_UNSUPPORTED;
+ }
+
+ if (!strcmp( name, "IDirectFB" )) {
+ sem_wait( &server->shared->sem );
+
+ if (server->shared->gfxpid) {
+ D_INFO( "Voodoo/Server: Killing previous graphics process with pid %d\n", server->shared->gfxpid );
+ kill( server->shared->gfxpid, SIGTERM );
+ }
+
+ server->shared->gfxpid = getpid();
+
+ D_INFO( "Voodoo/Server: New graphics process has pid %d\n", server->shared->gfxpid );
+
+ sem_post( &server->shared->sem );
+ }
+
+ ret = super->func( server, manager, name, super->ctx, &instance );
+ if (ret) {
+ D_ERROR( "Voodoo/Server: "
+ "Creating super interface '%s' failed (%s)!\n", name, DirectResultString(ret) );
+ return ret;
+ }
+
+ *ret_instance = instance;
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_server_run( VoodooServer *server,
+ bool forking )
+{
+ DirectLink *l, *n;
+ struct pollfd pf;
+ bool listener = true;
+
+ D_ASSERT( server != NULL );
+
+ while (!server->quit) {
+ /* Cleanup dead connections. */
+ direct_list_foreach_safe (l, n, server->connections) {
+ Connection *connection = (Connection*) l;
+
+ if (voodoo_manager_is_closed( connection->manager )) {
+ sem_wait( &server->shared->sem );
+
+ if (server->shared->gfxpid == getpid()) {
+ D_INFO( "Voodoo/Server: Closing graphics process with pid %d\n", server->shared->gfxpid );
+ server->shared->gfxpid = 0;
+ }
+
+ sem_post( &server->shared->sem );
+
+
+ voodoo_manager_destroy( connection->manager );
+
+ //connection->vl.Close( &connection->vl );
+
+ direct_list_remove( &server->connections, l );
+
+ D_INFO( "Voodoo/Server: Closed connection.\n" );
+
+ D_FREE( connection );
+
+ if (forking && !server->connections)
+ return DR_OK;
+ }
+ }
+
+ if (listener) {
+ int i;
+ int fd;
+ struct sockaddr addr;
+ socklen_t addrlen = sizeof(addr);
+
+ pf.fd = server->fd;
+ pf.events = POLLIN;
+
+ switch (poll( &pf, 1, 200 )) {
+ default:
+ fd = accept( server->fd, &addr, &addrlen );
+ if (fd < 0) {
+ D_PERROR( "Voodoo/Server: Could not accept() incoming connection!\n" );
+ break;
+ }
+
+ if (forking) {
+ switch (fork()) {
+ case 0:
+ listener = false;
+
+ for (i=3; i<65535; i++) {
+ if (i != fd)
+ close( i );
+ }
+
+ accept_connection( server, fd );
+ break;
+
+ case -1:
+ D_PERROR( "Voodoo/Server: Could not fork()!\n" );
+ break;
+
+ default:
+ close( fd );
+ break;
+ }
+ }
+ else {
+ accept_connection( server, fd );
+ }
+ break;
+
+ case 0:
+ waitpid( -1, NULL, WNOHANG );
+
+ D_DEBUG( "Voodoo/Server: Timeout during poll()\n" );
+ break;
+
+ case -1:
+ if (errno != EINTR) {
+ D_PERROR( "Voodoo/Server: Could not poll() the socket!\n" );
+ server->quit = true;
+ }
+ break;
+ }
+ }
+ else
+ usleep( 200000 );
+ }
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_server_destroy( VoodooServer *server )
+{
+ DirectLink *l;
+
+ D_ASSERT( server != NULL );
+
+ close( server->fd );
+
+ /* Close all connections. */
+ direct_list_foreach (l, server->connections) {
+ Connection *connection = (Connection*) l;
+
+ voodoo_manager_destroy( connection->manager );
+
+ //connection->vl.Close( &connection->vl );
+
+ D_FREE( connection );
+ }
+
+ D_FREE( server );
+
+ return DR_OK;
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+accept_connection( VoodooServer *server, int fd )
+{
+ DirectResult ret;
+ int fds[2] = { fd, fd };
+ Connection *connection;
+
+ connection = D_CALLOC( 1, sizeof(Connection) );
+ if (!connection) {
+ D_WARN( "out of memory" );
+ return DR_NOLOCALMEMORY;
+ }
+
+ voodoo_link_init_fd( &connection->vl, fds );
+
+ ret = voodoo_manager_create( &connection->vl, NULL, server, &connection->manager );
+ if (ret) {
+ connection->vl.Close( &connection->vl );
+ D_FREE( connection );
+ return ret;
+ }
+
+ direct_list_prepend( &server->connections, &connection->link );
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/server.h b/Source/DirectFB/lib/voodoo/server.h
new file mode 100755
index 0000000..e00329f
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/server.h
@@ -0,0 +1,52 @@
+/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__SERVER_H__
+#define __VOODOO__SERVER_H__
+
+#include <voodoo/types.h>
+
+
+DirectResult voodoo_server_create ( VoodooServer **ret_server );
+
+DirectResult voodoo_server_register( VoodooServer *server,
+ const char *name,
+ VoodooSuperConstruct func,
+ void *ctx );
+
+DirectResult voodoo_server_run ( VoodooServer *server,
+ bool forking );
+
+DirectResult voodoo_server_destroy ( VoodooServer *server );
+
+DirectResult voodoo_server_construct( VoodooServer *server,
+ VoodooManager *manager,
+ const char *name,
+ VoodooInstanceID *ret_instance );
+
+#endif
diff --git a/Source/DirectFB/lib/voodoo/types.h b/Source/DirectFB/lib/voodoo/types.h
new file mode 100755
index 0000000..ef9277c
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/types.h
@@ -0,0 +1,97 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __VOODOO__TYPES_H__
+#define __VOODOO__TYPES_H__
+
+#include <direct/types.h>
+
+#include "compat.h"
+
+#ifdef WIN32
+// The following ifdef block is the standard way of creating macros which make exporting
+// from a DLL simpler. All files within this DLL are compiled with the VOODOO_EXPORTS
+// symbol defined on the command line. This symbol should not be defined on any project
+// that uses this DLL. This way any other project whose source files include this file see
+// VOODOO_API functions as being imported from a DLL, whereas this DLL sees symbols
+// defined with this macro as being exported.
+#ifdef VOODOO_EXPORTS
+#define VOODOO_API __declspec(dllexport)
+#else
+#define VOODOO_API __declspec(dllimport)
+#endif
+#else
+#define VOODOO_API
+#endif
+
+
+typedef u32 VoodooInstanceID;
+typedef u32 VoodooMethodID;
+typedef u32 VoodooMessageSerial;
+
+#define VOODOO_INSTANCE_NONE ((VoodooInstanceID) 0)
+
+
+typedef struct __V_VoodooMessageHeader VoodooMessageHeader;
+typedef struct __V_VoodooSuperMessage VoodooSuperMessage;
+typedef struct __V_VoodooRequestMessage VoodooRequestMessage;
+typedef struct __V_VoodooResponseMessage VoodooResponseMessage;
+
+
+typedef struct __V_VoodooClient VoodooClient;
+typedef struct __V_VoodooConfig VoodooConfig;
+typedef struct __V_VoodooLink VoodooLink;
+typedef struct __V_VoodooPlayer VoodooPlayer;
+typedef struct __V_VoodooServer VoodooServer;
+
+#ifdef __cplusplus
+class VoodooConnection;
+class VoodooManager;
+class VoodooPacket;
+#else
+typedef void* VoodooManager;
+#endif
+
+
+typedef DirectResult (*VoodooSuperConstruct)( VoodooServer *server,
+ VoodooManager *manager,
+ const char *name,
+ void *ctx,
+ VoodooInstanceID *ret_instance );
+
+typedef DirectResult (*VoodooDispatch) ( void *dispatcher,
+ void *real,
+ VoodooManager *manager,
+ VoodooRequestMessage *msg );
+
+
+#define MAX_MSG_SIZE (17 * 1024)
+#define VOODOO_PACKET_MAX (MAX_MSG_SIZE)
+
+#endif
+
diff --git a/Source/DirectFB/lib/voodoo/unix/interfaces_unix.c b/Source/DirectFB/lib/voodoo/unix/interfaces_unix.c
new file mode 100755
index 0000000..5c3b1f8
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/unix/interfaces_unix.c
@@ -0,0 +1,237 @@
+/*
+ (c) Copyright 2001-2011 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/mem.h>
+
+#include <voodoo/play.h>
+
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <net/if.h>
+
+#include <sys/ioctl.h>
+
+
+
+DirectResult
+voodoo_play_get_broadcast( VoodooPlayAddress **ret_addr,
+ size_t *ret_num )
+{
+ size_t num = 0;
+ size_t i = 0;
+ VoodooPlayAddress *addr;
+
+ int ret;
+ int fd;
+ char *ptr, lastname[IFNAMSIZ];
+ struct ifreq req[16];
+ struct ifconf conf;
+
+ D_ASSERT( ret_addr != NULL );
+ D_ASSERT( ret_num != NULL );
+
+ conf.ifc_buf = (char*) req;
+ conf.ifc_len = sizeof(req);
+
+ fd = socket( AF_INET, SOCK_DGRAM, 0 );
+ if (fd < 0) {
+ D_PERROR( "Voodoo/Unix: socket( AF_INET, SOCK_DGRAM, 0 ) failed!\n" );
+ return DR_FAILURE;
+ }
+
+ ret = ioctl( fd, SIOCGIFCONF, &conf );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFCONF ) failed!\n" );
+ close( fd );
+ return DR_FAILURE;
+ }
+
+ lastname[0] = 0;
+
+ for (ptr = conf.ifc_buf; ptr < conf.ifc_buf + conf.ifc_len; ) {
+ struct ifreq ifrcopy, *ifr = (struct ifreq *)ptr;
+ struct sockaddr_in *saddr = (struct sockaddr_in*) &ifr->ifr_broadaddr;
+
+#ifdef MACOS
+ ptr += sizeof(ifr->ifr_name) + MAX(sizeof(struct sockaddr), ifr->ifr_addr.sa_len); // for next one in buffer
+#else
+ ptr += sizeof(req[0]);
+#endif
+
+ if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
+ continue; /* already processed this interface */
+ }
+
+ memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
+
+ ifrcopy = *ifr;
+ ioctl( fd, SIOCGIFFLAGS, &ifrcopy);
+ if ((ifrcopy.ifr_flags & IFF_UP) == 0)
+ continue; // ignore if interface not up
+
+ ret = ioctl( fd, SIOCGIFBRDADDR, ifr );
+ if (ret)
+ continue;
+
+ if (!saddr->sin_addr.s_addr) {
+ ret = ioctl( fd, SIOCGIFDSTADDR, ifr );
+ if (ret)
+ continue;
+ }
+
+ num++;
+ }
+
+
+ addr = D_CALLOC( num, sizeof(VoodooPlayAddress) );
+ if (!addr) {
+ close( fd );
+ return D_OOM();
+ }
+
+
+ for (ptr = conf.ifc_buf; ptr < conf.ifc_buf + conf.ifc_len; ) {
+ char buf[100];
+ struct ifreq ifrcopy, *ifr = (struct ifreq *)ptr;
+ struct sockaddr_in *saddr = (struct sockaddr_in*) &ifr->ifr_broadaddr;
+
+#ifdef MACOS
+ ptr += sizeof(ifr->ifr_name) + MAX(sizeof(struct sockaddr), ifr->ifr_addr.sa_len); // for next one in buffer
+#else
+ ptr += sizeof(req[0]);
+#endif
+
+ if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
+ continue; /* already processed this interface */
+ }
+
+ memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
+
+ ifrcopy = *ifr;
+ ioctl( fd, SIOCGIFFLAGS, &ifrcopy);
+ if ((ifrcopy.ifr_flags & IFF_UP) == 0) {
+ D_INFO( "Voodoo/Player: %-16s is not up.\n", ifrcopy.ifr_name );
+ continue; // ignore if interface not up
+ }
+
+ ret = ioctl( fd, SIOCGIFBRDADDR, ifr );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFBRDADDR ) %-16s failed!\n", ifr->ifr_name );
+ continue;
+ }
+
+ if (saddr->sin_addr.s_addr) {
+ inet_ntop( AF_INET, &saddr->sin_addr, buf, sizeof(buf) );
+
+ D_INFO( "Voodoo/Player: %-16s (%s)\n", ifr->ifr_name, buf );
+ }
+ else {
+ ret = ioctl( fd, SIOCGIFDSTADDR, ifr );
+ if (ret) {
+ D_PERROR( "Voodoo/Player: ioctl( SIOCGIFDSTADDR ) failed!\n" );
+ continue;
+ }
+
+ inet_ntop( AF_INET, &saddr->sin_addr, buf, sizeof(buf) );
+
+ D_INFO( "Voodoo/Player: %-16s (%s) (P-t-P)\n", ifr->ifr_name, buf );
+ }
+
+ voodoo_play_from_inet_addr( &addr[i++], saddr->sin_addr.s_addr );
+ }
+
+ close( fd );
+
+ *ret_addr = addr;
+ *ret_num = num;
+
+ return DR_OK;
+}
+
+
+
+#if 0
+
+DirectResult
+voodoo_play_get_broadcast( VoodooPlayAddress **ret_addr,
+ size_t *ret_num )
+{
+ DirectResult ret = DR_OK;
+ VoodooPlayAddress *addr;
+
+ // Get local host name
+ char szHostName[128] = "";
+
+ if (gethostname(szHostName, sizeof(szHostName))) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Win32: gethostname() failed!\n" );
+ return ret;
+ }
+
+ // Get local IP addresses
+ struct hostent *pHost = 0;
+
+ pHost = gethostbyname(szHostName);
+ if (!pHost) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Win32: gethostbyname('%s') failed!\n", szHostName );
+ return ret;
+ }
+
+
+ size_t iCnt, iTotal = 0;
+
+ for (iCnt = 0; pHost->h_addr_list[iCnt]; ++iCnt)
+ iTotal++;
+
+
+ addr = D_CALLOC( iTotal, sizeof(VoodooPlayAddress) );
+ if (!addr)
+ return D_OOM();
+
+ for (iCnt = 0; pHost->h_addr_list[iCnt]; ++iCnt) {
+ struct sockaddr_in SocketAddress;
+
+ memcpy(&SocketAddress.sin_addr, pHost->h_addr_list[iCnt], pHost->h_length);
+
+ voodoo_play_from_inet_addr( &addr[iCnt], SocketAddress.sin_addr.s_addr );
+ }
+
+ *ret_addr = addr;
+ *ret_num = iTotal;
+
+ return DR_OK;
+}
+
+#endif
+
diff --git a/Source/DirectFB/lib/voodoo/unix/link_unix.c b/Source/DirectFB/lib/voodoo/unix/link_unix.c
new file mode 100755
index 0000000..1b6690c
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/unix/link_unix.c
@@ -0,0 +1,567 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+//#include <aio.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <voodoo/client.h>
+#include <voodoo/conf.h>
+#include <voodoo/internal.h>
+#include <voodoo/link.h>
+#include <voodoo/manager.h>
+#include <voodoo/play.h>
+
+
+#define UNIX_PATH_MAX 108
+
+
+D_DEBUG_DOMAIN( Voodoo_Link, "Voodoo/Link", "Voodoo Link" );
+
+/**********************************************************************************************************************/
+
+#if !VOODOO_BUILD_NO_SETSOCKOPT
+static const int one = 1;
+static const int tos = IPTOS_LOWDELAY;
+#endif
+
+/**********************************************************************************************************************/
+
+#define DUMP_SOCKET_OPTION(fd,o) \
+do { \
+ int val = 0; \
+ unsigned int len = 4; \
+ \
+ if (getsockopt( fd, SOL_SOCKET, o, &val, &len )) \
+ D_PERROR( "Voodoo/Manager: getsockopt() for " #o " failed!\n" ); \
+ else \
+ D_DEBUG( "Voodoo/Manager: " #o " is %d\n", val ); \
+} while (0)
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int fd[2];
+ int wakeup_fds[2];
+} Link;
+
+static void
+Close( VoodooLink *link )
+{
+ Link *l = link->priv;
+
+ D_INFO( "Voodoo/Link: Closing connection.\n" );
+
+ close( l->fd[0] );
+
+ if (l->fd[1] != l->fd[0])
+ close( l->fd[1] );
+
+ close( l->wakeup_fds[0] );
+ close( l->wakeup_fds[1] );
+
+ D_FREE( link->priv );
+ link->priv = NULL;
+}
+
+static ssize_t
+Read( VoodooLink *link,
+ void *buffer,
+ size_t count )
+{
+ Link *l = link->priv;
+
+ return recv( l->fd[0], buffer, count, 0 );
+}
+
+static ssize_t
+Write( VoodooLink *link,
+ const void *buffer,
+ size_t count )
+{
+ Link *l = link->priv;
+
+ return send( l->fd[1], buffer, count, 0 );
+}
+
+
+// FIXME: refactor, optionally using lio_listio
+static DirectResult
+SendReceive( VoodooLink *link,
+ VoodooChunk *sends,
+ size_t num_send,
+ VoodooChunk *recvs,
+ size_t num_recv )
+{
+ Link *l = link->priv;
+ size_t i;
+ ssize_t ret;
+ int select_result;
+
+ D_DEBUG_AT( Voodoo_Link, "%s( link %p, sends %p, num_send %zu, recvs %p, num_recv %zu )\n",
+ __func__, link, sends, num_send, recvs, num_recv );
+
+ while (true) {
+ fd_set fds_read;
+ fd_set fds_write;
+ struct timeval tv;
+
+ FD_ZERO( &fds_read );
+ FD_ZERO( &fds_write );
+
+ if (num_recv)
+ FD_SET( l->fd[0], &fds_read );
+
+ if (num_send)
+ FD_SET( l->fd[1], &fds_write );
+
+ FD_SET( l->wakeup_fds[0], &fds_read );
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ D_DEBUG_AT( Voodoo_Link, " -> select( %s%s )...\n", num_recv ? "R" : " ", num_send ? "W" : " " );
+ select_result = select( MAX(MAX(l->wakeup_fds[0],l->fd[0]),l->fd[1])+1, &fds_read, &fds_write, NULL, &tv );
+ switch (select_result) {
+ default:
+ if (FD_ISSET( l->fd[1], &fds_write )) {
+ D_DEBUG_AT( Voodoo_Link, " => WRITE\n" );
+
+ for (i=0; i<num_send; i++) {
+ while (sends[i].done != sends[i].length) {
+#if 1
+ ret = send( l->fd[1], sends[i].ptr, sends[i].length, MSG_DONTWAIT );
+ if (ret < 0) {
+ D_PERROR( "Voodoo/Link: Failed to send() data!\n" );
+ return DR_IO;
+ }
+ else {
+ sends[i].done += ret;
+/*
+ if (sends[i].done != sends[i].length)
+ D_WARN( "partial send of %d/%d bytes", ret, sends[i].length );
+ else
+ D_WARN( "full send of %d bytes", ret, sends[i].length );
+*/
+ return DR_OK;
+ }
+#else
+ struct aiocb cb;
+
+ memset( &cb, 0, sizeof(struct aiocb) );
+
+ cb.aio_fildes = l->fd[1];
+ cb.aio_buf = sends[i].ptr;
+ cb.aio_nbytes = sends[i].length;
+ cb.aio_offset = (intptr_t)-1;
+ cb.aio_sigevent.sigev_notify = SIGEV_NONE;
+
+
+ ret = aio_write( &cb );
+ if (ret < 0) {
+ D_PERROR( "Voodoo/Link: aio_write() failed!\n" );
+ return DR_IO;
+ }
+ else {
+ do {
+ const struct aiocb *cbs[] = { &cb };
+
+ ret = aio_suspend( cbs, 1, NULL );
+ if (ret < 0) {
+ D_PERROR( "Voodoo/Link: aio_suspend() failed!\n" );
+ return DR_IO;
+ }
+
+ ret = aio_error( &cb );
+ } while (ret == EINPROGRESS);
+
+ switch (ret) {
+ case 0:
+ ret = aio_return( &cb );
+ if (ret < 0) {
+ D_ERROR( "Voodoo/Link: aio_return() failed!\n -> %s\n", strerror(ret) );
+ return DR_IO;
+ }
+ break;
+
+ default:
+ D_ERROR( "Voodoo/Link: aio_error() failed!\n -> %s\n", strerror(ret) );
+ return DR_IO;
+ }
+
+ sends[i].done += ret;
+/*
+ if (sends[i].done != sends[i].length)
+ D_WARN( "partial send of %d/%d bytes", ret, sends[i].length );
+ else
+ D_WARN( "full send of %d bytes", ret, sends[i].length );
+*/
+ return DR_OK;
+ }
+#endif
+ }
+ }
+ }
+
+ if (FD_ISSET( l->fd[0], &fds_read )) {
+ D_DEBUG_AT( Voodoo_Link, " => READ\n" );
+
+ for (i=0; i<num_recv; i++) {
+ ret = recv( l->fd[0], recvs[i].ptr, recvs[i].length, MSG_DONTWAIT );
+ if (ret < 0) {
+ if (errno == EAGAIN) {
+ break;
+ }
+ D_PERROR( "Voodoo/Link: Failed to recv() data!\n" );
+ return DR_FAILURE;
+ }
+
+ if (!ret)
+ return DR_IO;
+
+
+ recvs[i].done = ret;
+
+ if (recvs[i].done < recvs[i].length)
+ break;
+ }
+ }
+
+ if (FD_ISSET( l->wakeup_fds[0], &fds_read )) {
+ D_DEBUG_AT( Voodoo_Link, " => WAKE UP\n" );
+
+ static char buf[1000];
+ read( l->wakeup_fds[0], buf, sizeof(buf) );
+ if (!FD_ISSET( l->fd[0], &fds_read ) && !FD_ISSET( l->fd[0], &fds_write ))
+ return DR_INTERRUPTED;
+ }
+
+ return DR_OK;
+
+ case 0:
+ D_DEBUG_AT( Voodoo_Link, " => TIMEOUT\n" );
+ return DR_TIMEOUT;
+
+ case -1:
+ D_ERROR( "Voodoo/Link: select() failed!\n" );
+ return DR_FAILURE;
+ }
+ }
+
+ return DR_OK;
+}
+
+static DirectResult
+WakeUp( VoodooLink *link )
+{
+ Link *l = link->priv;
+ char c = 0;
+
+ write( l->wakeup_fds[1], &c, 1 );
+
+ return DR_OK;
+}
+
+/**********************************************************************************************************************/
+
+DirectResult
+voodoo_link_init_connect( VoodooLink *link,
+ const char *hostname,
+ int port,
+ bool raw )
+{
+ DirectResult ret;
+ int err;
+ struct addrinfo hints;
+ struct addrinfo *addr;
+ char portstr[10];
+ Link *l;
+
+
+ memset( &hints, 0, sizeof(hints) );
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = PF_UNSPEC;
+
+ D_INFO( "Voodoo/Link: Looking up host '%s'...\n", hostname );
+
+ snprintf( portstr, sizeof(portstr), "%d", port );
+
+ err = getaddrinfo( hostname, portstr, &hints, &addr );
+ if (err) {
+ switch (err) {
+ case EAI_FAMILY:
+ D_ERROR( "Direct/Log: Unsupported address family!\n" );
+ return DR_UNSUPPORTED;
+
+ case EAI_SOCKTYPE:
+ D_ERROR( "Direct/Log: Unsupported socket type!\n" );
+ return DR_UNSUPPORTED;
+
+ case EAI_NONAME:
+ D_ERROR( "Direct/Log: Host not found!\n" );
+ return DR_FAILURE;
+
+ case EAI_SERVICE:
+ D_ERROR( "Direct/Log: Service is unreachable!\n" );
+ return DR_FAILURE;
+
+#ifdef EAI_ADDRFAMILY
+ case EAI_ADDRFAMILY:
+#endif
+ case EAI_NODATA:
+ D_ERROR( "Direct/Log: Host found, but has no address!\n" );
+ return DR_FAILURE;
+
+ case EAI_MEMORY:
+ return D_OOM();
+
+ case EAI_FAIL:
+ D_ERROR( "Direct/Log: A non-recoverable name server error occurred!\n" );
+ return DR_FAILURE;
+
+ case EAI_AGAIN:
+ D_ERROR( "Direct/Log: Temporary error, try again!\n" );
+ return DR_TEMPUNAVAIL;
+
+ default:
+ D_ERROR( "Direct/Log: Unknown error occured!?\n" );
+ return DR_FAILURE;
+ }
+ }
+
+
+ l = D_CALLOC( 1, sizeof(Link) );
+ if (!l)
+ return D_OOM();
+
+ /* Create the client socket. */
+ l->fd[0] = socket( addr->ai_family, SOCK_STREAM, 0 );
+ if (l->fd[0] < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Link: Socket creation failed!\n" );
+ freeaddrinfo( addr );
+ D_FREE( l );
+ return ret;
+ }
+ l->fd[1] = l->fd[0];
+
+#if !VOODOO_BUILD_NO_SETSOCKOPT
+// if (setsockopt( l->fd[0], SOL_IP, IP_TOS, &tos, sizeof(tos) ) < 0)
+// D_PERROR( "Voodoo/Manager: Could not set IP_TOS!\n" );
+
+ if (setsockopt( l->fd[0], SOL_TCP, TCP_NODELAY, &one, sizeof(one) ) < 0)
+ D_PERROR( "Voodoo/Manager: Could not set TCP_NODELAY!\n" );
+#endif
+
+ D_INFO( "Voodoo/Link: Connecting to '%s:%d'...\n", addr->ai_canonname, port );
+
+ /* Connect to the server. */
+ err = connect( l->fd[0], addr->ai_addr, addr->ai_addrlen );
+ freeaddrinfo( addr );
+
+ if (err) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Link: Socket connect failed!\n" );
+ close( l->fd[0] );
+ D_FREE( l );
+ return ret;
+ }
+
+ D_INFO( "Voodoo/Link: Connected.\n" );
+
+ DUMP_SOCKET_OPTION( l->fd[0], SO_SNDLOWAT );
+ DUMP_SOCKET_OPTION( l->fd[0], SO_RCVLOWAT );
+ DUMP_SOCKET_OPTION( l->fd[0], SO_SNDBUF );
+ DUMP_SOCKET_OPTION( l->fd[0], SO_RCVBUF );
+
+ if (!raw) {
+ link->code = 0x80008676;
+
+ if (write( l->fd[1], &link->code, sizeof(link->code) ) != 4) {
+ D_ERROR( "Voodoo/Link: Coult not write initial four bytes!\n" );
+ close( l->fd[0] );
+ D_FREE( l );
+ return DR_IO;
+ }
+ }
+ D_INFO( "Voodoo/Link: Sent link code (%s).\n", raw ? "raw" : "packet" );
+
+ pipe( l->wakeup_fds );
+
+
+ link->priv = l;
+ link->Close = Close;
+ link->Read = Read;
+ link->Write = Write;
+ link->SendReceive = SendReceive;
+ link->WakeUp = WakeUp;
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_link_init_local( VoodooLink *link,
+ const char *path,
+ bool raw )
+{
+ DirectResult ret;
+ int err;
+ struct sockaddr_un addr;
+ Link *l;
+
+ D_ASSERT( link != NULL );
+ D_ASSERT( path != NULL );
+
+ l = D_CALLOC( 1, sizeof(Link) );
+ if (!l)
+ return D_OOM();
+
+ /* Create the client socket. */
+ l->fd[0] = socket( AF_LOCAL, SOCK_STREAM, 0 );
+ if (l->fd[0] < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Link: Socket creation failed!\n" );
+ D_FREE( l );
+ return ret;
+ }
+ l->fd[1] = l->fd[0];
+
+#if !VOODOO_BUILD_NO_SETSOCKOPT
+// if (setsockopt( l->fd[0], SOL_IP, IP_TOS, &tos, sizeof(tos) ) < 0)
+// D_PERROR( "Voodoo/Manager: Could not set IP_TOS!\n" );
+
+ if (setsockopt( l->fd[0], SOL_TCP, TCP_NODELAY, &one, sizeof(one) ) < 0)
+ D_PERROR( "Voodoo/Manager: Could not set TCP_NODELAY!\n" );
+#endif
+
+ D_INFO( "Voodoo/Link: Connecting to '%s'...\n", path );
+
+
+ memset( &addr, 0, sizeof(addr) );
+
+ /* Bind the socket to the local port. */
+ addr.sun_family = AF_UNIX;
+
+ snprintf( addr.sun_path + 1, UNIX_PATH_MAX - 1, "%s", path );
+
+ /* Connect to the server. */
+ err = connect( l->fd[0], (struct sockaddr*) &addr, strlen(addr.sun_path+1)+1 + sizeof(addr.sun_family) );
+ if (err) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Link: Socket connect failed!\n" );
+ close( l->fd[0] );
+ D_FREE( l );
+ return ret;
+ }
+
+ D_INFO( "Voodoo/Link: Connected.\n" );
+
+ DUMP_SOCKET_OPTION( l->fd[0], SO_SNDLOWAT );
+ DUMP_SOCKET_OPTION( l->fd[0], SO_RCVLOWAT );
+ DUMP_SOCKET_OPTION( l->fd[0], SO_SNDBUF );
+ DUMP_SOCKET_OPTION( l->fd[0], SO_RCVBUF );
+
+ if (!raw) {
+ link->code = 0x80008676;
+
+ if (write( l->fd[1], &link->code, sizeof(link->code) ) != 4) {
+ D_ERROR( "Voodoo/Link: Coult not write initial four bytes!\n" );
+ close( l->fd[0] );
+ D_FREE( l );
+ return DR_IO;
+ }
+ }
+ D_INFO( "Voodoo/Link: Sent link code (%s).\n", raw ? "raw" : "packet" );
+
+ pipe( l->wakeup_fds );
+
+
+ link->priv = l;
+ link->Close = Close;
+ link->Read = Read;
+ link->Write = Write;
+ link->SendReceive = SendReceive;
+ link->WakeUp = WakeUp;
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_link_init_fd( VoodooLink *link,
+ int fd[2] )
+{
+ Link *l;
+
+ if (read( fd[0], &link->code, sizeof(link->code) ) != 4) {
+ D_ERROR( "Voodoo/Link: Coult not read initial four bytes!\n" );
+ return DR_IO;
+ }
+
+ l = D_CALLOC( 1, sizeof(Link) );
+ if (!l)
+ return D_OOM();
+
+ l->fd[0] = fd[0];
+ l->fd[1] = fd[1];
+
+ pipe( l->wakeup_fds );
+
+ link->priv = l;
+ link->Close = Close;
+ link->Read = Read;
+ link->Write = Write;
+ link->SendReceive = SendReceive;
+ link->WakeUp = WakeUp;
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/unix/link_unix_1408limit.c b/Source/DirectFB/lib/voodoo/unix/link_unix_1408limit.c
new file mode 100755
index 0000000..790aa99
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/unix/link_unix_1408limit.c
@@ -0,0 +1,422 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <voodoo/client.h>
+#include <voodoo/conf.h>
+#include <voodoo/internal.h>
+#include <voodoo/link.h>
+#include <voodoo/manager.h>
+#include <voodoo/play.h>
+
+
+D_DEBUG_DOMAIN( Voodoo_Link, "Voodoo/Link", "Voodoo Link" );
+
+/**********************************************************************************************************************/
+
+#if !VOODOO_BUILD_NO_SETSOCKOPT
+static const int one = 1;
+static const int tos = IPTOS_LOWDELAY;
+#endif
+
+/**********************************************************************************************************************/
+
+#define DUMP_SOCKET_OPTION(fd,o) \
+do { \
+ int val = 0; \
+ unsigned int len = 4; \
+ \
+ if (getsockopt( fd, SOL_SOCKET, o, &val, &len )) \
+ D_PERROR( "Voodoo/Manager: getsockopt() for " #o " failed!\n" ); \
+ else \
+ D_DEBUG( "Voodoo/Manager: " #o " is %d\n", val ); \
+} while (0)
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int fd[2];
+ int wakeup_fds[2];
+} Link;
+
+static void
+Close( VoodooLink *link )
+{
+ Link *l = link->priv;
+
+ D_INFO( "Voodoo/Link: Closing connection.\n" );
+
+ close( l->fd[0] );
+
+ if (l->fd[1] != l->fd[0])
+ close( l->fd[1] );
+
+ D_FREE( link->priv );
+ link->priv = NULL;
+}
+
+static ssize_t
+Read( VoodooLink *link,
+ void *buffer,
+ size_t count )
+{
+ Link *l = link->priv;
+
+ return recv( l->fd[0], buffer, count, 0 );
+}
+
+static ssize_t
+Write( VoodooLink *link,
+ const void *buffer,
+ size_t count )
+{
+ Link *l = link->priv;
+
+ return send( l->fd[1], buffer, count, 0 );
+}
+
+
+// FIXME: refactor, optionally using lio_listio
+static DirectResult
+SendReceive( VoodooLink *link,
+ VoodooChunk *sends,
+ size_t num_send,
+ VoodooChunk *recvs,
+ size_t num_recv )
+{
+ Link *l = link->priv;
+ size_t i;
+ ssize_t ret;
+ int select_result;
+
+ D_DEBUG_AT( Voodoo_Link, "%s( link %p, sends %p, num_send %zu, recvs %p, num_recv %zu )\n",
+ __func__, link, sends, num_send, recvs, num_recv );
+
+ while (true) {
+ fd_set fds_read;
+ fd_set fds_write;
+ struct timeval tv;
+
+ FD_ZERO( &fds_read );
+ FD_ZERO( &fds_write );
+
+ if (num_recv)
+ FD_SET( l->fd[0], &fds_read );
+
+ if (num_send)
+ FD_SET( l->fd[1], &fds_write );
+
+ FD_SET( l->wakeup_fds[0], &fds_read );
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ D_DEBUG_AT( Voodoo_Link, " -> select( %s%s )...\n", num_recv ? "R" : " ", num_send ? "W" : " " );
+ select_result = select( MAX(MAX(l->wakeup_fds[0],l->fd[0]),l->fd[1])+1, &fds_read, &fds_write, NULL, &tv );
+ switch (select_result) {
+ default:
+ if (FD_ISSET( l->fd[1], &fds_write )) {
+ D_DEBUG_AT( Voodoo_Link, " => WRITE\n" );
+
+ for (i=0; i<num_send; i++) {
+ while (sends[i].done != sends[i].length) {
+ ret = send( l->fd[1], sends[i].ptr, sends[i].length, MSG_DONTWAIT );
+ if (ret < 0) {
+ //if (errno == EAGAIN) {
+ // break;
+ //}
+ D_PERROR( "Voodoo/Link: Failed to send() data!\n" );
+ return DR_FAILURE;
+ }
+ else {
+ sends[i].done += ret;
+/*
+ if (sends[i].done != sends[i].length)
+ D_WARN( "partial send of %d/%d bytes", ret, sends[i].length );
+ else
+ D_WARN( "full send of %d bytes", ret, sends[i].length );
+*/
+// return DR_OK;
+ break;
+ }
+ }
+ }
+ }
+
+ if (FD_ISSET( l->fd[0], &fds_read )) {
+ D_DEBUG_AT( Voodoo_Link, " => READ\n" );
+
+ for (i=0; i<num_recv; i++) {
+ ret = recv( l->fd[0], recvs[i].ptr, recvs[i].length, MSG_DONTWAIT );
+ if (ret < 0) {
+ if (errno == EAGAIN) {
+ break;
+ }
+ D_PERROR( "Voodoo/Link: Failed to recv() data!\n" );
+ return DR_FAILURE;
+ }
+
+ if (!ret)
+ return DR_IO;
+
+
+ recvs[i].done = ret;
+
+ if (recvs[i].done < recvs[i].length)
+ break;
+ }
+ }
+
+ if (FD_ISSET( l->wakeup_fds[0], &fds_read )) {
+ D_DEBUG_AT( Voodoo_Link, " => WAKE UP\n" );
+
+ static char buf[1000];
+ read( l->wakeup_fds[0], buf, sizeof(buf) );
+ if (!FD_ISSET( l->fd[0], &fds_read ) && !FD_ISSET( l->fd[0], &fds_write ))
+ return DR_INTERRUPTED;
+ }
+
+ return DR_OK;
+
+ case 0:
+ D_DEBUG_AT( Voodoo_Link, " => TIMEOUT\n" );
+ return DR_TIMEOUT;
+
+ case -1:
+ D_ERROR( "Voodoo/Link: select() failed!\n" );
+ return DR_FAILURE;
+ }
+ }
+
+ return DR_OK;
+}
+
+static DirectResult
+WakeUp( VoodooLink *link )
+{
+ Link *l = link->priv;
+ char c = 0;
+
+ write( l->wakeup_fds[1], &c, 1 );
+
+ return DR_OK;
+}
+
+/**********************************************************************************************************************/
+
+DirectResult
+voodoo_link_init_connect( VoodooLink *link,
+ const char *hostname,
+ int port,
+ bool raw )
+{
+ DirectResult ret;
+ int err;
+ struct addrinfo hints;
+ struct addrinfo *addr;
+ char portstr[10];
+ Link *l;
+
+
+ memset( &hints, 0, sizeof(hints) );
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = PF_UNSPEC;
+
+ D_INFO( "Voodoo/Link: Looking up host '%s'...\n", hostname );
+
+ snprintf( portstr, sizeof(portstr), "%d", port );
+
+ err = getaddrinfo( hostname, portstr, &hints, &addr );
+ if (err) {
+ switch (err) {
+ case EAI_FAMILY:
+ D_ERROR( "Direct/Log: Unsupported address family!\n" );
+ return DR_UNSUPPORTED;
+
+ case EAI_SOCKTYPE:
+ D_ERROR( "Direct/Log: Unsupported socket type!\n" );
+ return DR_UNSUPPORTED;
+
+ case EAI_NONAME:
+ D_ERROR( "Direct/Log: Host not found!\n" );
+ return DR_FAILURE;
+
+ case EAI_SERVICE:
+ D_ERROR( "Direct/Log: Service is unreachable!\n" );
+ return DR_FAILURE;
+
+#ifdef EAI_ADDRFAMILY
+ case EAI_ADDRFAMILY:
+#endif
+ case EAI_NODATA:
+ D_ERROR( "Direct/Log: Host found, but has no address!\n" );
+ return DR_FAILURE;
+
+ case EAI_MEMORY:
+ return D_OOM();
+
+ case EAI_FAIL:
+ D_ERROR( "Direct/Log: A non-recoverable name server error occurred!\n" );
+ return DR_FAILURE;
+
+ case EAI_AGAIN:
+ D_ERROR( "Direct/Log: Temporary error, try again!\n" );
+ return DR_TEMPUNAVAIL;
+
+ default:
+ D_ERROR( "Direct/Log: Unknown error occured!?\n" );
+ return DR_FAILURE;
+ }
+ }
+
+
+ l = D_CALLOC( 1, sizeof(Link) );
+ if (!l)
+ return D_OOM();
+
+ /* Create the client socket. */
+ l->fd[0] = socket( addr->ai_family, SOCK_STREAM, 0 );
+ if (l->fd[0] < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Link: Socket creation failed!\n" );
+ freeaddrinfo( addr );
+ D_FREE( l );
+ return ret;
+ }
+ l->fd[1] = l->fd[0];
+
+#if !VOODOO_BUILD_NO_SETSOCKOPT
+ if (setsockopt( l->fd[0], SOL_IP, IP_TOS, &tos, sizeof(tos) ) < 0)
+ D_PERROR( "Voodoo/Manager: Could not set IP_TOS!\n" );
+
+ if (setsockopt( l->fd[0], SOL_TCP, TCP_NODELAY, &one, sizeof(one) ) < 0)
+ D_PERROR( "Voodoo/Manager: Could not set TCP_NODELAY!\n" );
+#endif
+
+ D_INFO( "Voodoo/Link: Connecting to '%s:%d'...\n", addr->ai_canonname, port );
+
+ /* Connect to the server. */
+ err = connect( l->fd[0], addr->ai_addr, addr->ai_addrlen );
+ freeaddrinfo( addr );
+
+ if (err) {
+ ret = errno2result( errno );
+ D_PERROR( "Voodoo/Link: Socket connect failed!\n" );
+ close( l->fd[0] );
+ D_FREE( l );
+ return ret;
+ }
+
+ D_INFO( "Voodoo/Link: Connected.\n" );
+
+ DUMP_SOCKET_OPTION( l->fd[0], SO_SNDLOWAT );
+ DUMP_SOCKET_OPTION( l->fd[0], SO_RCVLOWAT );
+ DUMP_SOCKET_OPTION( l->fd[0], SO_SNDBUF );
+ DUMP_SOCKET_OPTION( l->fd[0], SO_RCVBUF );
+
+ if (!raw) {
+ link->code = 0x80008676;
+
+ if (write( l->fd[1], &link->code, sizeof(link->code) ) != 4) {
+ D_ERROR( "Voodoo/Link: Coult not write initial four bytes!\n" );
+ close( l->fd[0] );
+ D_FREE( l );
+ return DR_IO;
+ }
+ }
+ D_INFO( "Voodoo/Link: Sent link code (%s).\n", raw ? "raw" : "packet" );
+
+ pipe( l->wakeup_fds );
+
+
+ link->priv = l;
+ link->Close = Close;
+ link->Read = Read;
+ link->Write = Write;
+ link->SendReceive = SendReceive;
+ link->WakeUp = WakeUp;
+
+ return DR_OK;
+}
+
+DirectResult
+voodoo_link_init_fd( VoodooLink *link,
+ int fd[2] )
+{
+ Link *l;
+
+ if (read( fd[0], &link->code, sizeof(link->code) ) != 4) {
+ D_ERROR( "Voodoo/Link: Coult not read initial four bytes!\n" );
+ return DR_IO;
+ }
+
+ l = D_CALLOC( 1, sizeof(Link) );
+ if (!l)
+ return D_OOM();
+
+ l->fd[0] = fd[0];
+ l->fd[1] = fd[1];
+
+ pipe( l->wakeup_fds );
+
+ link->priv = l;
+ link->Close = Close;
+ link->Read = Read;
+ link->Write = Write;
+ link->SendReceive = SendReceive;
+ link->WakeUp = WakeUp;
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/voodoo/voodoo.pc.in b/Source/DirectFB/lib/voodoo/voodoo.pc.in
new file mode 100755
index 0000000..8e29024
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/voodoo.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Voodoo
+Description: Interface based network transparency (like CORBA)
+Version: @VERSION@
+Requires: direct
+Libs: -L${libdir} -lvoodoo
+Cflags: -I@INCLUDEDIR@
diff --git a/Source/DirectFB/lib/voodoo/waitqueue.h b/Source/DirectFB/lib/voodoo/waitqueue.h
new file mode 100755
index 0000000..ab163ce
--- /dev/null
+++ b/Source/DirectFB/lib/voodoo/waitqueue.h
@@ -0,0 +1,117 @@
+/*
+ (c) Copyright 2001-2008 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DIRECT__OS__LINUX__GLIBC__WAITQUEUE_H__
+#define __DIRECT__OS__LINUX__GLIBC__WAITQUEUE_H__
+
+#include <pthread.h>
+
+#include <direct/util.h>
+
+#include "mutex.h"
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ pthread_cond_t cond;
+} DirectWaitQueue;
+
+/**********************************************************************************************************************/
+
+#define DIRECT_WAITQUEUE_INITIALIZER(name) { PTHREAD_COND_INITIALIZER }
+
+/**********************************************************************************************************************/
+
+static inline DirectResult
+direct_waitqueue_init( DirectWaitQueue *queue )
+{
+ if (pthread_cond_init( &queue->cond, NULL ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+static inline DirectResult
+direct_waitqueue_wait( DirectWaitQueue *queue, DirectMutex *mutex )
+{
+ if (pthread_cond_wait( &queue->cond, &mutex->lock ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+static inline DirectResult
+direct_waitqueue_wait_timeout( DirectWaitQueue *queue, DirectMutex *mutex, unsigned long micros )
+{
+ struct timeval now;
+ struct timespec timeout;
+ long int nano_seconds = micros * 1000;
+
+ gettimeofday( &now, NULL );
+
+ timeout.tv_sec = now.tv_sec;
+ timeout.tv_nsec = (now.tv_usec * 1000) + nano_seconds;
+
+ timeout.tv_sec += timeout.tv_nsec / 1000000000;
+ timeout.tv_nsec %= 1000000000;
+
+ if (pthread_cond_timedwait( &queue->cond, &mutex->lock, &timeout ) == ETIMEDOUT)
+ return DR_TIMEOUT;
+
+ return DR_OK;
+}
+
+static inline DirectResult
+direct_waitqueue_signal( DirectWaitQueue *queue )
+{
+ if (pthread_cond_signal( &queue->cond ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+static inline DirectResult
+direct_waitqueue_broadcast( DirectWaitQueue *queue )
+{
+ if (pthread_cond_broadcast( &queue->cond ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+static inline DirectResult
+direct_waitqueue_deinit( DirectWaitQueue *queue )
+{
+ if (pthread_cond_destroy( &queue->cond ))
+ return errno2result( errno );
+
+ return DR_OK;
+}
+
+#endif
+