diff options
Diffstat (limited to 'Source/DirectFB/lib/voodoo')
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 + |