summaryrefslogtreecommitdiff
path: root/Source/DirectFB/lib/direct
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/lib/direct')
-rwxr-xr-xSource/DirectFB/lib/direct/Makefile.am138
-rwxr-xr-xSource/DirectFB/lib/direct/Makefile.in769
-rwxr-xr-xSource/DirectFB/lib/direct/armasm_memcpy.S421
-rwxr-xr-xSource/DirectFB/lib/direct/armasm_memcpy.h32
-rwxr-xr-xSource/DirectFB/lib/direct/build.h.in51
-rwxr-xr-xSource/DirectFB/lib/direct/clock.c135
-rwxr-xr-xSource/DirectFB/lib/direct/clock.h45
-rwxr-xr-xSource/DirectFB/lib/direct/conf.c348
-rwxr-xr-xSource/DirectFB/lib/direct/conf.h92
-rwxr-xr-xSource/DirectFB/lib/direct/debug.c430
-rwxr-xr-xSource/DirectFB/lib/direct/debug.h287
-rwxr-xr-xSource/DirectFB/lib/direct/direct.c197
-rwxr-xr-xSource/DirectFB/lib/direct/direct.h49
-rwxr-xr-xSource/DirectFB/lib/direct/direct.pc.in13
-rwxr-xr-xSource/DirectFB/lib/direct/fastlz.c97
-rwxr-xr-xSource/DirectFB/lib/direct/fastlz.h52
-rwxr-xr-xSource/DirectFB/lib/direct/flz.c555
-rwxr-xr-xSource/DirectFB/lib/direct/flz.h100
-rwxr-xr-xSource/DirectFB/lib/direct/hash.c268
-rwxr-xr-xSource/DirectFB/lib/direct/hash.h61
-rwxr-xr-xSource/DirectFB/lib/direct/interface.c474
-rwxr-xr-xSource/DirectFB/lib/direct/interface.h215
-rwxr-xr-xSource/DirectFB/lib/direct/interface_implementation.h91
-rwxr-xr-xSource/DirectFB/lib/direct/list.c35
-rwxr-xr-xSource/DirectFB/lib/direct/list.h224
-rwxr-xr-xSource/DirectFB/lib/direct/log.c414
-rwxr-xr-xSource/DirectFB/lib/direct/log.h89
-rwxr-xr-xSource/DirectFB/lib/direct/mem.c350
-rwxr-xr-xSource/DirectFB/lib/direct/mem.h84
-rwxr-xr-xSource/DirectFB/lib/direct/memcpy.c265
-rwxr-xr-xSource/DirectFB/lib/direct/memcpy.h51
-rwxr-xr-xSource/DirectFB/lib/direct/messages.c215
-rwxr-xr-xSource/DirectFB/lib/direct/messages.h173
-rwxr-xr-xSource/DirectFB/lib/direct/modules.c463
-rwxr-xr-xSource/DirectFB/lib/direct/modules.h95
-rwxr-xr-xSource/DirectFB/lib/direct/ppc_asm.h115
-rwxr-xr-xSource/DirectFB/lib/direct/ppcasm_memcpy.S77
-rwxr-xr-xSource/DirectFB/lib/direct/ppcasm_memcpy.h7
-rwxr-xr-xSource/DirectFB/lib/direct/ppcasm_memcpy_cachable.S180
-rwxr-xr-xSource/DirectFB/lib/direct/serial.h118
-rwxr-xr-xSource/DirectFB/lib/direct/signals.c480
-rwxr-xr-xSource/DirectFB/lib/direct/signals.h70
-rwxr-xr-xSource/DirectFB/lib/direct/stream.c2286
-rwxr-xr-xSource/DirectFB/lib/direct/stream.h129
-rwxr-xr-xSource/DirectFB/lib/direct/system.c68
-rwxr-xr-xSource/DirectFB/lib/direct/system.h40
-rwxr-xr-xSource/DirectFB/lib/direct/thread.c795
-rwxr-xr-xSource/DirectFB/lib/direct/thread.h168
-rwxr-xr-xSource/DirectFB/lib/direct/trace.c676
-rwxr-xr-xSource/DirectFB/lib/direct/trace.h98
-rwxr-xr-xSource/DirectFB/lib/direct/tree.c307
-rwxr-xr-xSource/DirectFB/lib/direct/tree.h67
-rwxr-xr-xSource/DirectFB/lib/direct/types.h169
-rwxr-xr-xSource/DirectFB/lib/direct/utf8.c36
-rwxr-xr-xSource/DirectFB/lib/direct/utf8.h80
-rwxr-xr-xSource/DirectFB/lib/direct/util.c519
-rwxr-xr-xSource/DirectFB/lib/direct/util.h330
57 files changed, 14193 insertions, 0 deletions
diff --git a/Source/DirectFB/lib/direct/Makefile.am b/Source/DirectFB/lib/direct/Makefile.am
new file mode 100755
index 0000000..c7604cd
--- /dev/null
+++ b/Source/DirectFB/lib/direct/Makefile.am
@@ -0,0 +1,138 @@
+## Makefile.am for DirectFB/lib/direct
+
+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 = direct.pc
+
+EXTRA_DIST = \
+ armasm_memcpy.S \
+ armasm_memcpy.h \
+ ppcasm_memcpy.S \
+ ppcasm_memcpy_cachable.S \
+ ppcasm_memcpy.h \
+ ppc_asm.h
+
+if BUILDPPCASM
+if HAVE_LINUX
+ppcasm_sources = ppcasm_memcpy.S ppcasm_memcpy_cachable.S
+else
+ppcasm_sources = ppcasm_memcpy.S
+endif
+
+ppcasm_headers = ppcasm_memcpy.h ppc_asm.h
+endif
+
+if BUILDARMASM
+armasm_sources = armasm_memcpy.S
+armasm_header = armasm_memcpy.h
+endif
+
+# If the old location isn't cleared, builds of external modules fail
+install-exec-local:
+ rm -rf $(DESTDIR)$(INTERNALINCLUDEDIR)/direct
+
+
+includedir = @INCLUDEDIR@/direct
+
+include_HEADERS = \
+ $(ppcasm_headers) \
+ $(armasm_headers) \
+ build.h \
+ clock.h \
+ conf.h \
+ debug.h \
+ direct.h \
+ hash.h \
+ interface.h \
+ interface_implementation.h \
+ list.h \
+ log.h \
+ mem.h \
+ memcpy.h \
+ messages.h \
+ modules.h \
+ serial.h \
+ signals.h \
+ stream.h \
+ system.h \
+ thread.h \
+ trace.h \
+ tree.h \
+ types.h \
+ utf8.h \
+ fastlz.h \
+ flz.h \
+ util.h
+
+
+lib_LTLIBRARIES = libdirect.la
+
+libdirect_la_SOURCES = \
+ $(ppcasm_sources) \
+ $(armasm_sources) \
+ clock.c \
+ conf.c \
+ debug.c \
+ direct.c \
+ hash.c \
+ interface.c \
+ list.c \
+ log.c \
+ mem.c \
+ memcpy.c \
+ messages.c \
+ modules.c \
+ signals.c \
+ stream.c \
+ system.c \
+ trace.c \
+ tree.c \
+ thread.c \
+ utf8.c \
+ fastlz.c \
+ flz.c \
+ util.c
+
+libdirect_la_LDFLAGS = \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -release $(LT_RELEASE) \
+ $(DFB_LDFLAGS)
+
+
+#
+## and now rebuild the static version with the *correct* object files
+#
+if BUILD_STATIC
+
+clean-local:
+ rm -f libdirect_fixed.a
+
+all-local: libdirect_fixed.a
+
+libdirect_fixed.a: .libs/libdirect.a
+ rm -f libdirect_fixed.a
+ ${AR} cru libdirect_fixed.a `find . -name "*.o" | grep -v '.libs' | grep -v dtest`
+ ${RANLIB} libdirect_fixed.a
+ cp -pf libdirect_fixed.a .libs/libdirect.a
+
+.libs/libdirect.a: libdirect.la
+
+else
+
+clean-local:
+
+all-local:
+
+endif
+
+
+include $(top_srcdir)/rules/nmfile.make
diff --git a/Source/DirectFB/lib/direct/Makefile.in b/Source/DirectFB/lib/direct/Makefile.in
new file mode 100755
index 0000000..efb1a74
--- /dev/null
+++ b/Source/DirectFB/lib/direct/Makefile.in
@@ -0,0 +1,769 @@
+# 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 = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/build.h.in \
+ $(srcdir)/direct.pc.in $(top_srcdir)/rules/nmfile.make
+subdir = lib/direct
+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 direct.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)
+libdirect_la_LIBADD =
+am__libdirect_la_SOURCES_DIST = ppcasm_memcpy.S \
+ ppcasm_memcpy_cachable.S armasm_memcpy.S clock.c conf.c \
+ debug.c direct.c hash.c interface.c list.c log.c mem.c \
+ memcpy.c messages.c modules.c signals.c stream.c system.c \
+ trace.c tree.c thread.c utf8.c util.c
+@BUILDPPCASM_TRUE@@HAVE_LINUX_FALSE@am__objects_1 = ppcasm_memcpy.lo
+@BUILDPPCASM_TRUE@@HAVE_LINUX_TRUE@am__objects_1 = ppcasm_memcpy.lo \
+@BUILDPPCASM_TRUE@@HAVE_LINUX_TRUE@ ppcasm_memcpy_cachable.lo
+@BUILDARMASM_TRUE@am__objects_2 = armasm_memcpy.lo
+am_libdirect_la_OBJECTS = $(am__objects_1) $(am__objects_2) clock.lo \
+ conf.lo debug.lo direct.lo hash.lo interface.lo list.lo log.lo \
+ mem.lo memcpy.lo messages.lo modules.lo signals.lo stream.lo \
+ system.lo trace.lo tree.lo thread.lo utf8.lo util.lo
+libdirect_la_OBJECTS = $(am_libdirect_la_OBJECTS)
+libdirect_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libdirect_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+LTCPPASCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+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 = $(libdirect_la_SOURCES)
+DIST_SOURCES = $(am__libdirect_la_SOURCES_DIST)
+pkgconfigDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(pkgconfig_DATA)
+am__include_HEADERS_DIST = ppcasm_memcpy.h ppc_asm.h build.h clock.h \
+ conf.h debug.h direct.h hash.h interface.h \
+ interface_implementation.h list.h log.h mem.h memcpy.h \
+ messages.h modules.h serial.h signals.h stream.h system.h \
+ thread.h trace.h tree.h types.h utf8.h util.h
+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@/direct
+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 = direct.pc
+EXTRA_DIST = \
+ armasm_memcpy.S \
+ armasm_memcpy.h \
+ ppcasm_memcpy.S \
+ ppcasm_memcpy_cachable.S \
+ ppcasm_memcpy.h \
+ ppc_asm.h
+
+@BUILDPPCASM_TRUE@@HAVE_LINUX_FALSE@ppcasm_sources = ppcasm_memcpy.S
+@BUILDPPCASM_TRUE@@HAVE_LINUX_TRUE@ppcasm_sources = ppcasm_memcpy.S ppcasm_memcpy_cachable.S
+@BUILDPPCASM_TRUE@ppcasm_headers = ppcasm_memcpy.h ppc_asm.h
+@BUILDARMASM_TRUE@armasm_sources = armasm_memcpy.S
+@BUILDARMASM_TRUE@armasm_header = armasm_memcpy.h
+include_HEADERS = \
+ $(ppcasm_headers) \
+ $(armasm_headers) \
+ build.h \
+ clock.h \
+ conf.h \
+ debug.h \
+ direct.h \
+ hash.h \
+ interface.h \
+ interface_implementation.h \
+ list.h \
+ log.h \
+ mem.h \
+ memcpy.h \
+ messages.h \
+ modules.h \
+ serial.h \
+ signals.h \
+ stream.h \
+ system.h \
+ thread.h \
+ trace.h \
+ tree.h \
+ types.h \
+ utf8.h \
+ util.h
+
+lib_LTLIBRARIES = libdirect.la
+libdirect_la_SOURCES = \
+ $(ppcasm_sources) \
+ $(armasm_sources) \
+ clock.c \
+ conf.c \
+ debug.c \
+ direct.c \
+ hash.c \
+ interface.c \
+ list.c \
+ log.c \
+ mem.c \
+ memcpy.c \
+ messages.c \
+ modules.c \
+ signals.c \
+ stream.c \
+ system.c \
+ trace.c \
+ tree.c \
+ thread.c \
+ utf8.c \
+ util.c
+
+libdirect_la_LDFLAGS = \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -release $(LT_RELEASE) \
+ $(DFB_LDFLAGS)
+
+@BUILD_SHARED_TRUE@@ENABLE_TRACE_TRUE@LIBTONM = $(LTLIBRARIES:.la=-$(LT_RELEASE).so.$(LT_BINARY))
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .S .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/direct/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu lib/direct/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)/$@
+direct.pc: $(top_builddir)/config.status $(srcdir)/direct.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
+libdirect.la: $(libdirect_la_OBJECTS) $(libdirect_la_DEPENDENCIES)
+ $(libdirect_la_LINK) -rpath $(libdir) $(libdirect_la_OBJECTS) $(libdirect_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/armasm_memcpy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clock.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/direct.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memcpy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/messages.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modules.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppcasm_memcpy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ppcasm_memcpy_cachable.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signals.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tree.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utf8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@
+
+.S.o:
+@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(CPPASCOMPILE) -c -o $@ $<
+
+.S.obj:
+@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCCAS_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.S.lo:
+@am__fastdepCCAS_TRUE@ $(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(LTCPPASCOMPILE) -c -o $@ $<
+
+.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)/direct
+
+#
+#
+
+@BUILD_STATIC_TRUE@clean-local:
+@BUILD_STATIC_TRUE@ rm -f libdirect_fixed.a
+
+@BUILD_STATIC_TRUE@all-local: libdirect_fixed.a
+
+@BUILD_STATIC_TRUE@libdirect_fixed.a: .libs/libdirect.a
+@BUILD_STATIC_TRUE@ rm -f libdirect_fixed.a
+@BUILD_STATIC_TRUE@ ${AR} cru libdirect_fixed.a `find . -name "*.o" | grep -v '.libs' | grep -v dtest`
+@BUILD_STATIC_TRUE@ ${RANLIB} libdirect_fixed.a
+@BUILD_STATIC_TRUE@ cp -pf libdirect_fixed.a .libs/libdirect.a
+
+@BUILD_STATIC_TRUE@.libs/libdirect.a: libdirect.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/direct/armasm_memcpy.S b/Source/DirectFB/lib/direct/armasm_memcpy.S
new file mode 100755
index 0000000..e422168
--- /dev/null
+++ b/Source/DirectFB/lib/direct/armasm_memcpy.S
@@ -0,0 +1,421 @@
+/*
+ * ARM memcpy asm replacement.
+ *
+ * Copyright (C) 2009 Bluush Dev Team.
+ *
+ * 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>
+
+#if USE_ARMASM && !WORDS_BIGENDIAN
+
+#define _LABEL(f) f :
+
+.global direct_armasm_memcpy
+
+ .code 32
+
+_LABEL(direct_armasm_memcpy)
+ cmp r1, r0
+ bcc Lmemcpy_backwards
+
+ moveq r0, #0
+ moveq pc, lr
+
+ stmdb sp!, {r0, lr}
+ subs r2, r2, #4
+ blt Lmemcpy_fl4
+ ands r12, r0, #3
+ bne Lmemcpy_fdestul
+ ands r12, r1, #3
+ bne Lmemcpy_fsrcul
+
+_LABEL(Lmemcpy_ft8)
+ subs r2, r2, #8
+ blt Lmemcpy_fl12
+ subs r2, r2, #0x14
+ blt Lmemcpy_fl32
+ stmdb sp!, {r4}
+
+_LABEL(Lmemcpy_floop32)
+ ldmia r1!, {r3, r4, r12, lr}
+ stmia r0!, {r3, r4, r12, lr}
+ ldmia r1!, {r3, r4, r12, lr}
+ stmia r0!, {r3, r4, r12, lr}
+ subs r2, r2, #0x20
+ bge Lmemcpy_floop32
+
+ cmn r2, #0x10
+ ldmgeia r1!, {r3, r4, r12, lr}
+ stmgeia r0!, {r3, r4, r12, lr}
+ subge r2, r2, #0x10
+ ldmia sp!, {r4}
+
+_LABEL(Lmemcpy_fl32)
+ adds r2, r2, #0x14
+
+
+_LABEL(Lmemcpy_floop12)
+ ldmgeia r1!, {r3, r12, lr}
+ stmgeia r0!, {r3, r12, lr}
+ subges r2, r2, #0x0c
+ bge Lmemcpy_floop12
+
+_LABEL(Lmemcpy_fl12)
+ adds r2, r2, #8
+ blt Lmemcpy_fl4
+
+ subs r2, r2, #4
+ ldrlt r3, [r1], #4
+ strlt r3, [r0], #4
+ ldmgeia r1!, {r3, r12}
+ stmgeia r0!, {r3, r12}
+ subge r2, r2, #4
+
+_LABEL(Lmemcpy_fl4)
+ adds r2, r2, #4
+ ldmeqia sp!, {r0, pc}
+
+ cmp r2, #2
+ ldrb r3, [r1], #1
+ strb r3, [r0], #1
+ ldrgeb r3, [r1], #1
+ strgeb r3, [r0], #1
+ ldrgtb r3, [r1], #1
+ strgtb r3, [r0], #1
+ ldmia sp!, {r0, pc}
+
+
+_LABEL(Lmemcpy_fdestul)
+ rsb r12, r12, #4
+ cmp r12, #2
+
+ ldrb r3, [r1], #1
+ strb r3, [r0], #1
+ ldrgeb r3, [r1], #1
+ strgeb r3, [r0], #1
+ ldrgtb r3, [r1], #1
+ strgtb r3, [r0], #1
+ subs r2, r2, r12
+ blt Lmemcpy_fl4
+
+ ands r12, r1, #3
+ beq Lmemcpy_ft8
+
+
+_LABEL(Lmemcpy_fsrcul)
+ bic r1, r1, #3
+ ldr lr, [r1], #4
+ cmp r12, #2
+ bgt Lmemcpy_fsrcul3
+ beq Lmemcpy_fsrcul2
+ cmp r2, #0x0c
+ blt Lmemcpy_fsrcul1loop4
+ sub r2, r2, #0x0c
+ stmdb sp!, {r4, r5}
+
+_LABEL(Lmemcpy_fsrcul1loop16)
+ mov r3, lr, lsr #8
+ ldmia r1!, {r4, r5, r12, lr}
+ orr r3, r3, r4, lsl #24
+ mov r4, r4, lsr #8
+ orr r4, r4, r5, lsl #24
+ mov r5, r5, lsr #8
+ orr r5, r5, r12, lsl #24
+ mov r12, r12, lsr #8
+ orr r12, r12, lr, lsl #24
+ stmia r0!, {r3-r5, r12}
+ subs r2, r2, #0x10
+ bge Lmemcpy_fsrcul1loop16
+ ldmia sp!, {r4, r5}
+ adds r2, r2, #0x0c
+ blt Lmemcpy_fsrcul1l4
+
+_LABEL(Lmemcpy_fsrcul1loop4)
+ mov r12, lr, lsr #8
+ ldr lr, [r1], #4
+ orr r12, r12, lr, lsl #24
+ str r12, [r0], #4
+ subs r2, r2, #4
+ bge Lmemcpy_fsrcul1loop4
+
+_LABEL(Lmemcpy_fsrcul1l4)
+ sub r1, r1, #3
+ b Lmemcpy_fl4
+
+_LABEL(Lmemcpy_fsrcul2)
+ cmp r2, #0x0c
+ blt Lmemcpy_fsrcul2loop4
+ sub r2, r2, #0x0c
+ stmdb sp!, {r4, r5}
+
+_LABEL(Lmemcpy_fsrcul2loop16)
+ mov r3, lr, lsr #16
+ ldmia r1!, {r4, r5, r12, lr}
+ orr r3, r3, r4, lsl #16
+ mov r4, r4, lsr #16
+ orr r4, r4, r5, lsl #16
+ mov r5, r5, lsr #16
+ orr r5, r5, r12, lsl #16
+ mov r12, r12, lsr #16
+ orr r12, r12, lr, lsl #16
+ stmia r0!, {r3-r5, r12}
+ subs r2, r2, #0x10
+ bge Lmemcpy_fsrcul2loop16
+ ldmia sp!, {r4, r5}
+ adds r2, r2, #0x0c
+ blt Lmemcpy_fsrcul2l4
+
+_LABEL(Lmemcpy_fsrcul2loop4)
+ mov r12, lr, lsr #16
+ ldr lr, [r1], #4
+ orr r12, r12, lr, lsl #16
+ str r12, [r0], #4
+ subs r2, r2, #4
+ bge Lmemcpy_fsrcul2loop4
+
+_LABEL(Lmemcpy_fsrcul2l4)
+ sub r1, r1, #2
+ b Lmemcpy_fl4
+
+_LABEL(Lmemcpy_fsrcul3)
+ cmp r2, #0x0c
+ blt Lmemcpy_fsrcul3loop4
+ sub r2, r2, #0x0c
+ stmdb sp!, {r4, r5}
+
+_LABEL(Lmemcpy_fsrcul3loop16)
+ mov r3, lr, lsr #24
+ ldmia r1!, {r4, r5, r12, lr}
+ orr r3, r3, r4, lsl #8
+ mov r4, r4, lsr #24
+ orr r4, r4, r5, lsl #8
+ mov r5, r5, lsr #24
+ orr r5, r5, r12, lsl #8
+ mov r12, r12, lsr #24
+ orr r12, r12, lr, lsl #8
+ stmia r0!, {r3-r5, r12}
+ subs r2, r2, #0x10
+ bge Lmemcpy_fsrcul3loop16
+ ldmia sp!, {r4, r5}
+ adds r2, r2, #0x0c
+ blt Lmemcpy_fsrcul3l4
+
+_LABEL(Lmemcpy_fsrcul3loop4)
+ mov r12, lr, lsr #24
+ ldr lr, [r1], #4
+ orr r12, r12, lr, lsl #8
+ str r12, [r0], #4
+ subs r2, r2, #4
+ bge Lmemcpy_fsrcul3loop4
+
+_LABEL(Lmemcpy_fsrcul3l4)
+ sub r1, r1, #1
+ b Lmemcpy_fl4
+
+_LABEL(Lmemcpy_backwards)
+ add r1, r1, r2
+ add r0, r0, r2
+ subs r2, r2, #4
+ blt Lmemcpy_bl4
+ ands r12, r0, #3
+ bne Lmemcpy_bdestul
+ ands r12, r1, #3
+ bne Lmemcpy_bsrcul
+
+_LABEL(Lmemcpy_bt8)
+ subs r2, r2, #8
+ blt Lmemcpy_bl12
+ stmdb sp!, {r4, lr}
+ subs r2, r2, #0x14
+ blt Lmemcpy_bl32
+
+
+_LABEL(Lmemcpy_bloop32)
+ ldmdb r1!, {r3, r4, r12, lr}
+ stmdb r0!, {r3, r4, r12, lr}
+ ldmdb r1!, {r3, r4, r12, lr}
+ stmdb r0!, {r3, r4, r12, lr}
+ subs r2, r2, #0x20
+ bge Lmemcpy_bloop32
+
+_LABEL(Lmemcpy_bl32)
+ cmn r2, #0x10
+ ldmgedb r1!, {r3, r4, r12, lr}
+ stmgedb r0!, {r3, r4, r12, lr}
+ subge r2, r2, #0x10
+ adds r2, r2, #0x14
+ ldmgedb r1!, {r3, r12, lr}
+ stmgedb r0!, {r3, r12, lr}
+ subge r2, r2, #0x0c
+ ldmia sp!, {r4, lr}
+
+_LABEL(Lmemcpy_bl12)
+ adds r2, r2, #8
+ blt Lmemcpy_bl4
+ subs r2, r2, #4
+ ldrlt r3, [r1, #-4]!
+ strlt r3, [r0, #-4]!
+ ldmgedb r1!, {r3, r12}
+ stmgedb r0!, {r3, r12}
+ subge r2, r2, #4
+
+_LABEL(Lmemcpy_bl4)
+ adds r2, r2, #4
+ moveq pc, lr
+
+ cmp r2, #2
+ ldrb r3, [r1, #-1]!
+ strb r3, [r0, #-1]!
+ ldrgeb r3, [r1, #-1]!
+ strgeb r3, [r0, #-1]!
+ ldrgtb r3, [r1, #-1]!
+ strgtb r3, [r0, #-1]!
+ mov pc, lr
+
+
+_LABEL(Lmemcpy_bdestul)
+ cmp r12, #2
+
+ ldrb r3, [r1, #-1]!
+ strb r3, [r0, #-1]!
+ ldrgeb r3, [r1, #-1]!
+ strgeb r3, [r0, #-1]!
+ ldrgtb r3, [r1, #-1]!
+ strgtb r3, [r0, #-1]!
+ subs r2, r2, r12
+ blt Lmemcpy_bl4
+ ands r12, r1, #3
+ beq Lmemcpy_bt8
+
+
+_LABEL(Lmemcpy_bsrcul)
+ bic r1, r1, #3
+ ldr r3, [r1, #0]
+ cmp r12, #2
+ blt Lmemcpy_bsrcul1
+ beq Lmemcpy_bsrcul2
+ cmp r2, #0x0c
+ blt Lmemcpy_bsrcul3loop4
+ sub r2, r2, #0x0c
+ stmdb sp!, {r4, r5, lr}
+
+_LABEL(Lmemcpy_bsrcul3loop16)
+ mov lr, r3, lsl #8
+ ldmdb r1!, {r3-r5, r12}
+ orr lr, lr, r12, lsr #24
+ mov r12, r12, lsl #8
+ orr r12, r12, r5, lsr #24
+ mov r5, r5, lsl #8
+ orr r5, r5, r4, lsr #24
+ mov r4, r4, lsl #8
+ orr r4, r4, r3, lsr #24
+ stmdb r0!, {r4, r5, r12, lr}
+ subs r2, r2, #0x10
+ bge Lmemcpy_bsrcul3loop16
+ ldmia sp!, {r4, r5, lr}
+ adds r2, r2, #0x0c
+ blt Lmemcpy_bsrcul3l4
+
+_LABEL(Lmemcpy_bsrcul3loop4)
+ mov r12, r3, lsl #8
+ ldr r3, [r1, #-4]!
+ orr r12, r12, r3, lsr #24
+ str r12, [r0, #-4]!
+ subs r2, r2, #4
+ bge Lmemcpy_bsrcul3loop4
+
+_LABEL(Lmemcpy_bsrcul3l4)
+ add r1, r1, #3
+ b Lmemcpy_bl4
+
+_LABEL(Lmemcpy_bsrcul2)
+ cmp r2, #0x0c
+ blt Lmemcpy_bsrcul2loop4
+ sub r2, r2, #0x0c
+ stmdb sp!, {r4, r5, lr}
+
+_LABEL(Lmemcpy_bsrcul2loop16)
+ mov lr, r3, lsl #16
+ ldmdb r1!, {r3-r5, r12}
+ orr lr, lr, r12, lsr #16
+ mov r12, r12, lsl #16
+ orr r12, r12, r5, lsr #16
+ mov r5, r5, lsl #16
+ orr r5, r5, r4, lsr #16
+ mov r4, r4, lsl #16
+ orr r4, r4, r3, lsr #16
+ stmdb r0!, {r4, r5, r12, lr}
+ subs r2, r2, #0x10
+ bge Lmemcpy_bsrcul2loop16
+ ldmia sp!, {r4, r5, lr}
+ adds r2, r2, #0x0c
+ blt Lmemcpy_bsrcul2l4
+
+_LABEL(Lmemcpy_bsrcul2loop4)
+ mov r12, r3, lsl #16
+ ldr r3, [r1, #-4]!
+ orr r12, r12, r3, lsr #16
+ str r12, [r0, #-4]!
+ subs r2, r2, #4
+ bge Lmemcpy_bsrcul2loop4
+
+_LABEL(Lmemcpy_bsrcul2l4)
+ add r1, r1, #2
+ b Lmemcpy_bl4
+
+_LABEL(Lmemcpy_bsrcul1)
+ cmp r2, #0x0c
+ blt Lmemcpy_bsrcul1loop4
+ sub r2, r2, #0x0c
+ stmdb sp!, {r4, r5, lr}
+
+_LABEL(Lmemcpy_bsrcul1loop32)
+ mov lr, r3, lsl #24
+ ldmdb r1!, {r3-r5, r12}
+ orr lr, lr, r12, lsr #8
+ mov r12, r12, lsl #24
+ orr r12, r12, r5, lsr #8
+ mov r5, r5, lsl #24
+ orr r5, r5, r4, lsr #8
+ mov r4, r4, lsl #24
+ orr r4, r4, r3, lsr #8
+ stmdb r0!, {r4, r5, r12, lr}
+ subs r2, r2, #0x10
+ bge Lmemcpy_bsrcul1loop32
+ ldmia sp!, {r4, r5, lr}
+ adds r2, r2, #0x0c
+ blt Lmemcpy_bsrcul1l4
+
+_LABEL(Lmemcpy_bsrcul1loop4)
+ mov r12, r3, lsl #24
+ ldr r3, [r1, #-4]!
+ orr r12, r12, r3, lsr #8
+ str r12, [r0, #-4]!
+ subs r2, r2, #4
+ bge Lmemcpy_bsrcul1loop4
+
+_LABEL(Lmemcpy_bsrcul1l4)
+ add r1, r1, #1
+ b Lmemcpy_bl4
+
+
+ .ltorg
+
+#endif /* USE_ARMASM && !WORDS_BIGENDIAN */
+
+
diff --git a/Source/DirectFB/lib/direct/armasm_memcpy.h b/Source/DirectFB/lib/direct/armasm_memcpy.h
new file mode 100755
index 0000000..27138ab
--- /dev/null
+++ b/Source/DirectFB/lib/direct/armasm_memcpy.h
@@ -0,0 +1,32 @@
+/*
+ * ARM memcpy asm replacement.
+ *
+ * Copyright (C) 2009 Bluush Dev Team.
+ *
+ * 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 __ARMASM_MEMCPY_H__
+#define __ARMASM_MEMCPY_H__
+
+#if USE_ARMASM && !WORDS_BIGENDIAN
+
+void *direct_armasm_memcpy ( void *dest, const void *src, size_t n);
+
+#endif /* USE_ARMASM && !WORDS_BIGENDIAN */
+
+#endif /* __ARMASM_MEMCPY_H__ */
+
diff --git a/Source/DirectFB/lib/direct/build.h.in b/Source/DirectFB/lib/direct/build.h.in
new file mode 100755
index 0000000..926cea5
--- /dev/null
+++ b/Source/DirectFB/lib/direct/build.h.in
@@ -0,0 +1,51 @@
+/*
+ (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 __DIRECT__BUILD_H__
+#define __DIRECT__BUILD_H__
+
+#define DIRECT_BUILD_DEBUG (@DIRECT_BUILD_DEBUG@)
+#define DIRECT_BUILD_DEBUGS (@DIRECT_BUILD_DEBUGS@)
+#define DIRECT_BUILD_TRACE (@DIRECT_BUILD_TRACE@)
+#define DIRECT_BUILD_TEXT (@DIRECT_BUILD_TEXT@)
+#define DIRECT_BUILD_GETTID (@DIRECT_BUILD_GETTID@)
+#define DIRECT_BUILD_NETWORK (@DIRECT_BUILD_NETWORK@)
+#define DIRECT_BUILD_STDBOOL (@DIRECT_BUILD_STDBOOL@)
+
+
+#if !DIRECT_BUILD_DEBUGS
+#if defined(DIRECT_ENABLE_DEBUG) || defined(DIRECT_FORCE_DEBUG)
+#define DIRECT_MINI_DEBUG
+#endif
+#undef DIRECT_ENABLE_DEBUG
+#ifdef DIRECT_FORCE_DEBUG
+#warning DIRECT_FORCE_DEBUG used with 'pure release' library headers.
+#undef DIRECT_FORCE_DEBUG
+#endif
+#endif
+
+#endif
diff --git a/Source/DirectFB/lib/direct/clock.c b/Source/DirectFB/lib/direct/clock.c
new file mode 100755
index 0000000..e77bfe2
--- /dev/null
+++ b/Source/DirectFB/lib/direct/clock.c
@@ -0,0 +1,135 @@
+/*
+ (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/clock.h>
+#include <direct/debug.h>
+#include <direct/util.h>
+
+#ifdef CLOCK_MONOTONIC
+#include <sys/syscall.h>
+#endif
+#include <sys/time.h>
+#include <time.h>
+
+D_DEBUG_DOMAIN( Direct_Clock, "Direct/Clock", "Time measurement etc." );
+
+static struct timeval start_time = { 0, 0 };
+
+/* libc has incredibly messy way of doing this,
+ * typically requiring -lrt. We just skip all this mess */
+struct timeval*
+direct_monotonic_gettimeofday( struct timeval *tv )
+{
+ struct timespec ts;
+
+#ifdef CLOCK_MONOTONIC
+ /* No locking or atomic ops for no_monotonic here */
+ static int no_monotonic = 0;
+
+ if (!no_monotonic)
+ if(syscall( __NR_clock_gettime, CLOCK_MONOTONIC, &ts ))
+ no_monotonic = 1;
+
+ if (no_monotonic)
+ if(syscall(__NR_clock_gettime, CLOCK_REALTIME, &ts))
+#endif
+ {
+ gettimeofday( tv, NULL );
+ return tv;
+ }
+
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+
+ return tv;
+}
+
+long long
+direct_clock_get_micros( void )
+{
+ struct timeval tv;
+ long long ret;
+
+ if (start_time.tv_sec == 0) {
+ direct_monotonic_gettimeofday( &start_time );
+ return 0;
+ }
+
+ direct_monotonic_gettimeofday( &tv );
+
+ ret = (long long)(tv.tv_sec - start_time.tv_sec) * 1000000LL +
+ (long long)(tv.tv_usec - start_time.tv_usec);
+ if (ret < 0) {
+ D_DEBUG_AT( Direct_Clock, "Clock skew detected (%lld in the past)!\n", -ret );
+ start_time = tv;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+long long
+direct_clock_get_millis( void )
+{
+ return direct_clock_get_micros() / 1000LL;
+}
+
+void
+direct_clock_set_start( const struct timeval *start )
+{
+ long long diff;
+
+ D_ASSERT( start != NULL );
+
+ diff = (long long)(start->tv_sec - start_time.tv_sec) * 1000LL +
+ (long long)(start->tv_usec - start_time.tv_usec) / 1000LL;
+
+ D_DEBUG_AT( Direct_Clock, "Adjusting start time "
+ "(%lld.%lld seconds diff)\n", diff / 1000LL, ABS(diff) % 1000LL );
+
+ start_time = *start;
+}
+
+long long
+direct_clock_get_abs_micros( void )
+{
+ struct timeval tv;
+
+ direct_monotonic_gettimeofday( &tv );
+
+ return (long long)(tv.tv_sec) * 1000000LL + (long long)(tv.tv_usec);
+}
+
+long long
+direct_clock_get_abs_millis( void )
+{
+ return direct_clock_get_abs_micros() / 1000LL;
+}
+
diff --git a/Source/DirectFB/lib/direct/clock.h b/Source/DirectFB/lib/direct/clock.h
new file mode 100755
index 0000000..dca6ea9
--- /dev/null
+++ b/Source/DirectFB/lib/direct/clock.h
@@ -0,0 +1,45 @@
+/*
+ (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 __DIRECT__CLOCK_H__
+#define __DIRECT__CLOCK_H__
+
+#include <sys/time.h>
+
+struct timeval* direct_monotonic_gettimeofday( struct timeval *tv );
+
+long long direct_clock_get_micros( void );
+long long direct_clock_get_millis( void );
+
+void direct_clock_set_start( const struct timeval *start );
+
+long long direct_clock_get_abs_micros( void );
+long long direct_clock_get_abs_millis( void );
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/conf.c b/Source/DirectFB/lib/direct/conf.c
new file mode 100755
index 0000000..8be92af
--- /dev/null
+++ b/Source/DirectFB/lib/direct/conf.c
@@ -0,0 +1,348 @@
+/*
+ (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 <stdlib.h>
+#include <string.h>
+
+#include <direct/conf.h>
+#include <direct/mem.h>
+#include <direct/util.h>
+
+
+static DirectConfig config = {
+ .debug = false,
+ .trace = true,
+ .sighandler = true,
+
+ .fatal = DCFL_ASSERT,
+ .fatal_break = true,
+ .thread_block_signals = true,
+ .thread_priority_scale = 100,
+};
+
+DirectConfig *direct_config = &config;
+const char *direct_config_usage =
+ "libdirect options:\n"
+ " memcpy=<method> Skip memcpy() probing (help = show list)\n"
+ " [no-]quiet Disable text output except debug messages or direct logs\n"
+ " [no-]quiet=<type> Only quiet certain types (cumulative with 'quiet')\n"
+ " [ info | warning | error | once | unimplemented ]\n"
+ " [no-]debug Enable debug output\n"
+ " [no-]debugmem Enable memory allocation tracking\n"
+ " [no-]trace Enable stack trace support\n"
+ " log-file=<name> Write all messages to a file\n"
+ " log-udp=<host>:<port> Send all messages via UDP to host:port\n"
+ " fatal-level=<level> Abort on NONE, ASSERT (default) or ASSUME (incl. assert)\n"
+ " [no-]fatal-break Abort on BREAK (default)\n"
+ " dont-catch=<num>[[,<num>]...] Don't catch these signals\n"
+ " [no-]sighandler Enable signal handler\n"
+ " [no-]thread-block-signals Block all signals in new threads?\n"
+ " disable-module=<module_name> suppress loading this module\n"
+ " module-dir=<directory> Override default module search directory (default = $libdir/directfb-x.y-z)\n"
+ " thread-priority-scale=<100th> Apply scaling factor on thread type based priorities\n"
+ "\n";
+
+/**********************************************************************************************************************/
+
+DirectResult
+direct_config_set( const char *name, const char *value )
+{
+ if (strcmp (name, "disable-module" ) == 0) {
+ if (value) {
+ int n = 0;
+
+ while (direct_config->disable_module &&
+ direct_config->disable_module[n])
+ n++;
+
+ direct_config->disable_module = D_REALLOC( direct_config->disable_module,
+ sizeof(char*) * (n + 2) );
+
+ direct_config->disable_module[n] = D_STRDUP( value );
+ direct_config->disable_module[n+1] = NULL;
+ }
+ else {
+ D_ERROR("Direct/Config '%s': No module name specified!\n", name);
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "module-dir" ) == 0) {
+ if (value) {
+ if (direct_config->module_dir)
+ D_FREE( direct_config->module_dir );
+ direct_config->module_dir = D_STRDUP( value );
+ }
+ else {
+ D_ERROR("Direct/Config 'module-dir': No directory name specified!\n");
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "memcpy" ) == 0) {
+ if (value) {
+ if (direct_config->memcpy)
+ D_FREE( direct_config->memcpy );
+ direct_config->memcpy = D_STRDUP( value );
+ }
+ else {
+ D_ERROR("Direct/Config '%s': No method specified!\n", name);
+ return DR_INVARG;
+ }
+ }
+ else
+ if (strcmp (name, "quiet" ) == 0 || strcmp (name, "no-quiet" ) == 0) {
+ /* Enable/disable all at once by default. */
+ DirectMessageType type = DMT_ALL;
+
+ /* Find out the specific message type being configured. */
+ if (value) {
+ if (!strcmp( value, "info" )) type = DMT_INFO; else
+ if (!strcmp( value, "warning" )) type = DMT_WARNING; else
+ if (!strcmp( value, "error" )) type = DMT_ERROR; else
+ if (!strcmp( value, "once" )) type = DMT_ONCE; else
+ if (!strcmp( value, "unimplemented" )) type = DMT_UNIMPLEMENTED;
+ else {
+ D_ERROR( "DirectFB/Config '%s': Unknown message type '%s'!\n", name, value );
+ return DR_INVARG;
+ }
+ }
+
+ /* Set/clear the corresponding flag in the configuration. */
+ if (name[0] == 'q')
+ direct_config->quiet |= type;
+ else
+ direct_config->quiet &= ~type;
+ }
+ else
+ if (strcmp (name, "no-quiet" ) == 0) {
+ direct_config->quiet = false;
+ }
+ else
+ if (strcmp (name, "debug" ) == 0) {
+ if (value)
+ direct_debug_config_domain( value, true );
+ else
+ direct_config->debug = true;
+ }
+ else
+ if (strcmp (name, "no-debug" ) == 0) {
+ if (value)
+ direct_debug_config_domain( value, false );
+ else
+ direct_config->debug = false;
+ }
+ else
+ if (strcmp (name, "debugmem" ) == 0) {
+ direct_config->debugmem = true;
+ }
+ else
+ if (strcmp (name, "no-debugmem" ) == 0) {
+ direct_config->debugmem = false;
+ }
+ else
+ if (strcmp (name, "trace" ) == 0) {
+ direct_config->trace = true;
+ }
+ else
+ if (strcmp (name, "no-trace" ) == 0) {
+ direct_config->trace = false;
+ }
+ else
+ if (strcmp (name, "log-file" ) == 0 || strcmp (name, "log-udp" ) == 0) {
+ if (value) {
+ DirectResult ret;
+ DirectLog *log;
+
+ ret = direct_log_create( strcmp(name,"log-udp") ? DLT_FILE : DLT_UDP, value, &log );
+ if (ret)
+ return ret;
+
+ if (direct_config->log)
+ direct_log_destroy( direct_config->log );
+
+ direct_config->log = log;
+
+ direct_log_set_default( log );
+ }
+ else {
+ if (strcmp(name,"log-udp"))
+ D_ERROR("Direct/Config '%s': No file name specified!\n", name);
+ else
+ D_ERROR("Direct/Config '%s': No host and port specified!\n", name);
+ return DR_INVARG;
+ }
+ }
+ else
+ if (strcmp (name, "fatal-level" ) == 0) {
+ if (strcasecmp (value, "none" ) == 0) {
+ direct_config->fatal = DCFL_NONE;
+ }
+ else
+ if (strcasecmp (value, "assert" ) == 0) {
+ direct_config->fatal = DCFL_ASSERT;
+ }
+ else
+ if (strcasecmp (value, "assume" ) == 0) {
+ direct_config->fatal = DCFL_ASSUME;
+ }
+ else {
+ D_ERROR("Direct/Config '%s': Unknown level specified (use 'none', 'assert', 'assume')!\n", name);
+ return DR_INVARG;
+ }
+ }
+ else
+ if (strcmp (name, "fatal-break" ) == 0) {
+ direct_config->fatal_break = true;
+ }
+ else
+ if (strcmp (name, "no-fatal-break" ) == 0) {
+ direct_config->fatal_break = false;
+ }
+ else
+ if (strcmp (name, "sighandler" ) == 0) {
+ direct_config->sighandler = true;
+ }
+ else
+ if (strcmp (name, "no-sighandler" ) == 0) {
+ direct_config->sighandler = false;
+ }
+ else
+ if (strcmp (name, "dont-catch" ) == 0) {
+ if (value) {
+ char *signals = D_STRDUP( value );
+ char *p = NULL, *r, *s = signals;
+
+ while ((r = strtok_r( s, ",", &p ))) {
+ char *error;
+ unsigned long signum;
+
+ direct_trim( &r );
+
+ signum = strtoul( r, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "Direct/Config '%s': Error in number at '%s'!\n", name, error );
+ D_FREE( signals );
+ return DR_INVARG;
+ }
+
+ sigaddset( &direct_config->dont_catch, signum );
+
+ s = NULL;
+ }
+
+ D_FREE( signals );
+ }
+ else {
+ D_ERROR("Direct/Config '%s': No signals specified!\n", name);
+ return DR_INVARG;
+ }
+ }
+ else
+ if (strcmp (name, "thread_block_signals") == 0) {
+ direct_config->thread_block_signals = true;
+ }
+ else
+ if (strcmp (name, "no-thread_block_signals") == 0) {
+ direct_config->thread_block_signals = false;
+ } else
+ if (strcmp (name, "thread-priority-scale" ) == 0) {
+ if (value) {
+ int scale;
+
+ if (sscanf( value, "%d", &scale ) < 1) {
+ D_ERROR("Direct/Config '%s': Could not parse value!\n", name);
+ return DR_INVARG;
+ }
+
+ direct_config->thread_priority_scale = scale;
+ }
+ else {
+ D_ERROR("Direct/Config '%s': No value specified!\n", name);
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "thread-priority" ) == 0) { /* Must be moved to lib/direct/conf.c in trunk! */
+ if (value) {
+ int priority;
+
+ if (sscanf( value, "%d", &priority ) < 1) {
+ D_ERROR("Direct/Config '%s': Could not parse value!\n", name);
+ return DR_INVARG;
+ }
+
+ direct_config->thread_priority = priority;
+ }
+ else {
+ D_ERROR("Direct/Config '%s': No value specified!\n", name);
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "thread-scheduler" ) == 0) { /* Must be moved to lib/direct/conf.c in trunk! */
+ if (value) {
+ if (strcmp( value, "other" ) == 0) {
+ direct_config->thread_scheduler = DCTS_OTHER;
+ } else
+ if (strcmp( value, "fifo" ) == 0) {
+ direct_config->thread_scheduler = DCTS_FIFO;
+ } else
+ if (strcmp( value, "rr" ) == 0) {
+ direct_config->thread_scheduler = DCTS_RR;
+ } else {
+ D_ERROR( "Direct/Config '%s': Unknown scheduler '%s'!\n", name, value );
+ return DR_INVARG;
+ }
+ }
+ else {
+ D_ERROR( "Direct/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ } else
+ if (strcmp (name, "thread-stacksize" ) == 0) { /* Must be moved to lib/direct/conf.c in trunk! */
+ if (value) {
+ int size;
+
+ if (sscanf( value, "%d", &size ) < 1) {
+ D_ERROR( "Direct/Config '%s': Could not parse value!\n", name );
+ return DR_INVARG;
+ }
+
+ direct_config->thread_stack_size = size;
+ }
+ else {
+ D_ERROR( "Direct/Config '%s': No value specified!\n", name );
+ return DR_INVARG;
+ }
+ }
+ else
+ return DR_UNSUPPORTED;
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/direct/conf.h b/Source/DirectFB/lib/direct/conf.h
new file mode 100755
index 0000000..ef1230e
--- /dev/null
+++ b/Source/DirectFB/lib/direct/conf.h
@@ -0,0 +1,92 @@
+/*
+ (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 __DIRECT__CONF_H__
+#define __DIRECT__CONF_H__
+
+
+#include <direct/messages.h>
+
+#if HAVE_SIGNAL_H
+#include <signal.h>
+#else
+#include <sys/signal.h>
+#endif
+
+typedef enum {
+ DCFL_NONE, /* None is fatal. */
+ DCFL_ASSERT, /* ASSERT is fatal. */
+ DCFL_ASSUME /* ASSERT and ASSUME are fatal. */
+} DirectConfigFatalLevel;
+
+typedef enum {
+ DCTS_OTHER,
+ DCTS_FIFO,
+ DCTS_RR
+} DirectConfigThreadScheduler;
+
+struct __D_DirectConfig {
+ DirectMessageType quiet;
+ bool debug;
+ bool trace;
+
+ char *memcpy; /* Don't probe for memcpy routines to save a lot of
+ startup time. Use this one instead if it's set. */
+
+ char **disable_module; /* Never load these modules. */
+ char *module_dir; /* module dir override */
+
+ bool sighandler;
+ sigset_t dont_catch; /* don't catch these signals */
+
+ DirectLog *log;
+
+ DirectConfigFatalLevel fatal;
+
+ bool debugmem;
+
+ bool thread_block_signals;
+
+ bool fatal_break; /* Should D_BREAK() cause a trap? */
+
+ int thread_priority;
+ DirectConfigThreadScheduler thread_scheduler;
+ int thread_stack_size;
+ int thread_priority_scale;
+};
+
+extern DirectConfig *direct_config;
+
+extern const char *direct_config_usage;
+
+
+DirectResult direct_config_set( const char *name, const char *value );
+
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/debug.c b/Source/DirectFB/lib/direct/debug.c
new file mode 100755
index 0000000..6aad0a1
--- /dev/null
+++ b/Source/DirectFB/lib/direct/debug.c
@@ -0,0 +1,430 @@
+/*
+ (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/build.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <direct/clock.h>
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/log.h>
+#include <direct/thread.h>
+#include <direct/trace.h>
+#include <direct/util.h>
+
+
+#if DIRECT_BUILD_TEXT
+
+#if DIRECT_BUILD_DEBUGS /* Build with debug support? */
+
+typedef struct {
+ DirectLink link;
+ char *name;
+ bool enabled;
+} DebugDomainEntry;
+
+/**************************************************************************************************/
+
+static pthread_mutex_t domains_lock = PTHREAD_MUTEX_INITIALIZER;
+static unsigned int domains_age = 1;
+static DirectLink *domains = NULL;
+
+/**************************************************************************************************/
+
+__attribute__((no_instrument_function))
+static inline DebugDomainEntry *
+lookup_domain( const char *name, bool sub )
+{
+ DebugDomainEntry *entry;
+
+ direct_list_foreach (entry, domains) {
+ if (! strcasecmp( entry->name, name ))
+ return entry;
+ }
+
+ /*
+ * If the domain being registered contains a slash, but didn't exactly match an entry
+ * in directfbrc, check to see if the domain is descended from an entry in directfbrc
+ * (e.g. 'ui/field/messages' matches 'ui' or 'ui/field')
+ */
+ if (sub && strchr(name, '/')) {
+ int passed_name_len = strlen( name );
+
+ direct_list_foreach (entry, domains) {
+ int entry_len = strlen( entry->name );
+ if ((passed_name_len > entry_len) &&
+ (name[entry_len] == '/') &&
+ (! strncasecmp( entry->name, name, entry_len))) {
+ return entry;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+__attribute__((no_instrument_function))
+static inline bool
+check_domain( DirectDebugDomain *domain )
+{
+ if (domain->age != domains_age) {
+ DebugDomainEntry *entry = lookup_domain( domain->name, true );
+
+ domain->age = domains_age;
+
+ if (entry) {
+ domain->registered = true;
+ domain->enabled = entry->enabled;
+ }
+ }
+
+ return domain->registered ? domain->enabled : direct_config->debug;
+}
+
+#endif /* DIRECT_BUILD_DEBUGS */
+
+/**************************************************************************************************/
+
+void
+direct_debug_config_domain( const char *name, bool enable )
+{
+#if DIRECT_BUILD_DEBUGS /* Build with debug support? */
+ DebugDomainEntry *entry;
+
+ pthread_mutex_lock( &domains_lock );
+
+ entry = lookup_domain( name, false );
+ if (!entry) {
+ entry = calloc( 1, sizeof(DebugDomainEntry) );
+ if (!entry) {
+ D_WARN( "out of memory" );
+ pthread_mutex_unlock( &domains_lock );
+ return;
+ }
+
+ entry->name = strdup( name );
+
+ direct_list_prepend( &domains, &entry->link );
+ }
+
+ entry->enabled = enable;
+
+ if (! ++domains_age)
+ domains_age++;
+
+ pthread_mutex_unlock( &domains_lock );
+#endif /* DIRECT_BUILD_DEBUGS */
+}
+
+/**************************************************************************************************/
+
+__attribute__((no_instrument_function))
+static inline void
+debug_domain_vprintf( const char *name,
+ int name_len,
+ const char *format,
+ va_list ap )
+{
+ char buf[512];
+ long long millis = direct_clock_get_millis();
+ const char *thread = direct_thread_self_name();
+ int indent = direct_trace_debug_indent() * 4;
+
+ /* Prepare user message. */
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ /* Fill up domain name column after the colon, prepending remaining space (excl. ': ') to indent. */
+ indent += (name_len < 20 ? 20 : 36) - name_len - 2;
+
+ /* Print full message. */
+ direct_log_printf( NULL, "(-) [%-15s %3lld.%03lld] (%5d) %s: %*s%s", thread ? thread : " NO NAME",
+ millis / 1000LL, millis % 1000LL, direct_gettid(), name, indent, "", buf );
+}
+
+#if DIRECT_BUILD_DEBUGS /* Build with debug support? */
+
+__attribute__((no_instrument_function))
+void
+direct_debug( const char *format, ... )
+{
+ va_list ap;
+
+ va_start( ap, format );
+
+ debug_domain_vprintf( "- - ", 4, format, ap );
+
+ va_end( ap );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_debug_at( DirectDebugDomain *domain,
+ const char *format, ... )
+{
+ bool enabled;
+
+ pthread_mutex_lock( &domains_lock );
+
+ enabled = check_domain( domain );
+
+ pthread_mutex_unlock( &domains_lock );
+
+ if (enabled) {
+ va_list ap;
+
+ va_start( ap, format );
+
+ debug_domain_vprintf( domain->name, domain->name_len, format, ap );
+
+ va_end( ap );
+ }
+}
+
+#endif /* DIRECT_BUILD_DEBUGS */
+
+__attribute__((no_instrument_function))
+void
+direct_debug_at_always( DirectDebugDomain *domain,
+ const char *format, ... )
+{
+ va_list ap;
+
+ va_start( ap, format );
+
+ debug_domain_vprintf( domain->name, domain->name_len, format, ap );
+
+ va_end( ap );
+}
+
+#if DIRECT_BUILD_DEBUGS /* Build with debug support? */
+
+__attribute__((no_instrument_function))
+void
+direct_debug_enter( DirectDebugDomain *domain,
+ const char *func,
+ const char *file,
+ int line,
+ const char *format, ... )
+{
+ bool enabled;
+
+ pthread_mutex_lock( &domains_lock );
+
+ enabled = check_domain( domain );
+
+ pthread_mutex_unlock( &domains_lock );
+
+ if (enabled) {
+ int len;
+ char dom[48];
+ char fmt[128];
+ char buf[512];
+ long long millis = direct_clock_get_millis();
+ const char *name = direct_thread_self_name();
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+
+ len = snprintf( dom, sizeof(dom), "%s:", domain->name );
+
+ if (len < 18)
+ len = 18;
+ else
+ len = 28;
+
+ len += direct_trace_debug_indent() * 4;
+
+ snprintf( fmt, sizeof(fmt), "(>) [%%-15s %%3lld.%%03lld] (%%5d) %%-%ds Entering %%s%%s [%%s:%%d]\n", len );
+
+ direct_log_printf( NULL, fmt, name ? name : " NO NAME ",
+ millis / 1000LL, millis % 1000LL, direct_gettid(), dom,
+ func, buf, file, line );
+ }
+}
+
+__attribute__((no_instrument_function))
+void
+direct_debug_exit( DirectDebugDomain *domain,
+ const char *func,
+ const char *file,
+ int line,
+ const char *format, ... )
+{
+ bool enabled;
+
+ pthread_mutex_lock( &domains_lock );
+
+ enabled = check_domain( domain );
+
+ pthread_mutex_unlock( &domains_lock );
+
+ if (enabled) {
+ int len;
+ char dom[48];
+ char fmt[128];
+ char buf[512];
+ long long millis = direct_clock_get_millis();
+ const char *name = direct_thread_self_name();
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+
+ len = snprintf( dom, sizeof(dom), "%s:", domain->name );
+
+ if (len < 18)
+ len = 18;
+ else
+ len = 28;
+
+ len += direct_trace_debug_indent() * 4;
+
+ snprintf( fmt, sizeof(fmt), "(<) [%%-15s %%3lld.%%03lld] (%%5d) %%-%ds Returning from %%s%%s [%%s:%%d]\n", len );
+
+ direct_log_printf( NULL, fmt, name ? name : " NO NAME ",
+ millis / 1000LL, millis % 1000LL, direct_gettid(), dom,
+ func, buf, file, line );
+ }
+}
+
+__attribute__((no_instrument_function))
+static void
+trap( const char *domain )
+{
+ D_DEBUG( "Direct/%s: Raising SIGTRAP...\n", domain );
+
+ raise( SIGTRAP );
+
+ D_DEBUG( "Direct/%s: ...didn't catch signal on my own, calling killpg().\n", domain );
+
+ kill( direct_gettid(), SIGTRAP );
+
+ D_DEBUG( "Direct/%s: ...still running, calling pthread_exit().\n", domain );
+
+ pthread_exit( NULL );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_break( const char *func,
+ const char *file,
+ int line,
+ const char *format, ... )
+{
+ char buf[512];
+ long long millis = direct_clock_get_millis();
+ const char *name = direct_thread_self_name();
+
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+ direct_log_printf( NULL,
+ "(!) [%-15s %3lld.%03lld] (%5d) *** Break [%s] *** [%s:%d in %s()]\n",
+ name ? name : " NO NAME ", millis / 1000LL, millis % 1000LL,
+ direct_gettid(), buf, file, line, func );
+
+ direct_trace_print_stack( NULL );
+
+ if (direct_config->fatal_break)
+ trap( "Break" );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_assertion( const char *exp,
+ const char *func,
+ const char *file,
+ int line )
+{
+ long long millis = direct_clock_get_millis();
+ const char *name = direct_thread_self_name();
+
+ direct_log_printf( NULL,
+ "(!) [%-15s %3lld.%03lld] (%5d) *** Assertion [%s] failed *** [%s:%d in %s()]\n",
+ name ? name : " NO NAME ", millis / 1000LL, millis % 1000LL,
+ direct_gettid(), exp, file, line, func );
+
+ direct_trace_print_stack( NULL );
+
+ if (direct_config->fatal >= DCFL_ASSERT)
+ trap( "Assertion" );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_assumption( const char *exp,
+ const char *func,
+ const char *file,
+ int line )
+{
+ long long millis = direct_clock_get_millis();
+ const char *name = direct_thread_self_name();
+
+ direct_log_printf( NULL,
+ "(!) [%-15s %3lld.%03lld] (%5d) *** Assumption [%s] failed *** [%s:%d in %s()]\n",
+ name ? name : " NO NAME ", millis / 1000LL, millis % 1000LL,
+ direct_gettid(), exp, file, line, func );
+
+ direct_trace_print_stack( NULL );
+
+ if (direct_config->fatal >= DCFL_ASSUME)
+ trap( "Assumption" );
+}
+
+#endif /* DIRECT_BUILD_DEBUGS */
+
+#else
+
+void
+direct_debug_config_domain( const char *name, bool enable )
+{
+}
+
+#endif /* DIRECT_BUILD_TEXT */
+
diff --git a/Source/DirectFB/lib/direct/debug.h b/Source/DirectFB/lib/direct/debug.h
new file mode 100755
index 0000000..1232716
--- /dev/null
+++ b/Source/DirectFB/lib/direct/debug.h
@@ -0,0 +1,287 @@
+/*
+ (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 __DIRECT__DEBUG_H__
+#define __DIRECT__DEBUG_H__
+
+#include <direct/build.h>
+
+#include <stdio.h>
+#include <errno.h>
+
+#include <direct/clock.h>
+#include <direct/conf.h>
+#include <direct/log.h>
+#include <direct/messages.h>
+#include <direct/system.h>
+#include <direct/thread.h>
+#include <direct/trace.h>
+#include <direct/types.h>
+
+
+typedef struct {
+ unsigned int age;
+ bool enabled;
+ bool registered;
+
+ const char *name;
+ const char *description;
+
+ int name_len;
+} DirectDebugDomain;
+
+void direct_debug_config_domain( const char *name, bool enable );
+
+
+#if DIRECT_BUILD_TEXT
+
+#define D_DEBUG_DOMAIN(identifier,name,description) \
+ static DirectDebugDomain identifier __attribute__((unused)) \
+ = { 0, false, false, name, description, sizeof(name) - 1 }
+
+void direct_debug_at_always( DirectDebugDomain *domain,
+ const char *format, ... ) D_FORMAT_PRINTF(2);
+
+#define d_debug_at( domain, x... ) direct_debug_at_always( &domain, x )
+
+
+#if DIRECT_BUILD_DEBUGS
+
+void direct_debug( const char *format, ... ) D_FORMAT_PRINTF(1);
+
+void direct_debug_at( DirectDebugDomain *domain,
+ const char *format, ... ) D_FORMAT_PRINTF(2);
+
+void direct_debug_enter( DirectDebugDomain *domain,
+ const char *func,
+ const char *file,
+ int line,
+ const char *format, ... ) D_FORMAT_PRINTF(5);
+
+void direct_debug_exit( DirectDebugDomain *domain,
+ const char *func,
+ const char *file,
+ int line,
+ const char *format, ... ) D_FORMAT_PRINTF(5);
+
+void direct_break( const char *func,
+ const char *file,
+ int line,
+ const char *format, ... ) D_FORMAT_PRINTF(4);
+
+void direct_assertion( const char *exp,
+ const char *func,
+ const char *file,
+ int line );
+
+void direct_assumption( const char *exp,
+ const char *func,
+ const char *file,
+ int line );
+#endif
+
+#if DIRECT_BUILD_DEBUG || defined(DIRECT_ENABLE_DEBUG) || defined(DIRECT_FORCE_DEBUG)
+
+#define D_DEBUG_ENABLED (1)
+
+#define D_DEBUG(x...) \
+ do { \
+ if (!direct_config || direct_config->debug) \
+ direct_debug( x ); \
+ } while (0)
+
+
+#define D_DEBUG_AT(d,x...) \
+ do { \
+ direct_debug_at( &d, x ); \
+ } while (0)
+
+#define D_DEBUG_ENTER(d,x...) \
+ do { \
+ direct_debug_enter( &d, __FUNCTION__, __FILE__, __LINE__, x ); \
+ } while (0)
+
+#define D_DEBUG_EXIT(d,x...) \
+ do { \
+ direct_debug_exit( &d, __FUNCTION__, __FILE__, __LINE__, x ); \
+ } while (0)
+
+#define D_ASSERT(exp) \
+ do { \
+ if (!(exp)) \
+ direct_assertion( #exp, __FUNCTION__, __FILE__, __LINE__ ); \
+ } while (0)
+
+
+#define D_ASSUME(exp) \
+ do { \
+ if (!(exp)) \
+ direct_assumption( #exp, __FUNCTION__, __FILE__, __LINE__ ); \
+ } while (0)
+
+
+#define D_BREAK(x...) \
+ do { \
+ direct_break( __FUNCTION__, __FILE__, __LINE__, x ); \
+ } while (0)
+
+#elif defined(DIRECT_MINI_DEBUG)
+
+/*
+ * Mini debug mode, only D_DEBUG_AT, no domain filters, simple assertion
+ */
+
+#define D_DEBUG_ENABLED (2)
+
+#define D_DEBUG_AT(d,x...) \
+ do { \
+ if (direct_config->debug) direct_debug_at_always( &d, x ); \
+ } while (0)
+
+#define D_CHECK(exp, aa) \
+ do { \
+ if (!(exp)) { \
+ long long millis = direct_clock_get_millis(); \
+ const char *name = direct_thread_self_name(); \
+ \
+ direct_log_printf( NULL, \
+ "(!) [%-15s %3lld.%03lld] (%5d) *** " #aa " [%s] failed *** [%s:%d in %s()]\n", \
+ name ? name : " NO NAME ", millis / 1000LL, millis % 1000LL, \
+ direct_gettid(), #exp, __FILE__, __LINE__, __FUNCTION__ ); \
+ \
+ direct_trace_print_stack( NULL ); \
+ } \
+ } while (0)
+
+#define D_ASSERT(exp) D_CHECK(exp, Assertion)
+#define D_ASSUME(exp) D_CHECK(exp, Assumption)
+
+#endif /* MINI_DEBUG / DIRECT_BUILD_DEBUG || DIRECT_ENABLE_DEBUG || DIRECT_FORCE_DEBUG */
+
+#endif /* DIRECT_BUILD_TEXT */
+
+
+/*
+ * Fallback definitions, e.g. without DIRECT_BUILD_TEXT or DIRECT_ENABLE_DEBUG
+ */
+
+#ifndef D_DEBUG_ENABLED
+#define D_DEBUG_ENABLED (0)
+#endif
+
+#ifndef D_DEBUG
+#define D_DEBUG(x...) do {} while (0)
+#endif
+
+#ifndef D_DEBUG_AT
+#define D_DEBUG_AT(d,x...) do {} while (0)
+#endif
+
+#ifndef D_DEBUG_ENTER
+#define D_DEBUG_ENTER(d,x...) do {} while (0)
+#endif
+
+#ifndef D_DEBUG_EXIT
+#define D_DEBUG_EXIT(d,x...) do {} while (0)
+#endif
+
+#ifndef D_ASSERT
+#define D_ASSERT(exp) do {} while (0)
+#endif
+
+#ifndef D_ASSUME
+#define D_ASSUME(exp) do {} while (0)
+#endif
+
+#ifndef D_BREAK
+#define D_BREAK(x...) do {} while (0)
+#endif
+
+#ifndef d_debug_at
+#define d_debug_at( domain, x... ) do {} while (0)
+#endif
+
+#ifndef D_DEBUG_DOMAIN
+#define D_DEBUG_DOMAIN(i,n,d)
+#endif
+
+
+
+/*
+ * Magic Assertions & Utilities
+ */
+
+#define D_MAGIC(spell) ( (((spell)[sizeof(spell)*8/9] << 24) | \
+ ((spell)[sizeof(spell)*7/9] << 16) | \
+ ((spell)[sizeof(spell)*6/9] << 8) | \
+ ((spell)[sizeof(spell)*5/9] )) ^ \
+ (((spell)[sizeof(spell)*4/9] << 24) | \
+ ((spell)[sizeof(spell)*3/9] << 16) | \
+ ((spell)[sizeof(spell)*2/9] << 8) | \
+ ((spell)[sizeof(spell)*1/9] )) )
+
+
+#define D_MAGIC_SET(o,m) do { \
+ D_ASSERT( (o) != NULL ); \
+ D_ASSUME( (o)->magic != D_MAGIC(#m) ); \
+ \
+ (o)->magic = D_MAGIC(#m); \
+ } while (0)
+
+#define D_MAGIC_SET_ONLY(o,m) do { \
+ D_ASSERT( (o) != NULL ); \
+ \
+ (o)->magic = D_MAGIC(#m); \
+ } while (0)
+
+#define D_MAGIC_ASSERT(o,m) do { \
+ D_ASSERT( (o) != NULL ); \
+ D_ASSERT( (o)->magic == D_MAGIC(#m) ); \
+ } while (0)
+
+#define D_MAGIC_ASSUME(o,m) do { \
+ D_ASSUME( (o) != NULL ); \
+ if (o) \
+ D_ASSUME( (o)->magic == D_MAGIC(#m) ); \
+ } while (0)
+
+#define D_MAGIC_ASSERT_IF(o,m) do { \
+ if (o) \
+ D_ASSERT( (o)->magic == D_MAGIC(#m) ); \
+ } while (0)
+
+#define D_MAGIC_CLEAR(o) do { \
+ D_ASSERT( (o) != NULL ); \
+ D_ASSUME( (o)->magic != 0 ); \
+ \
+ (o)->magic = 0; \
+ } while (0)
+
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/direct.c b/Source/DirectFB/lib/direct/direct.c
new file mode 100755
index 0000000..38b930f
--- /dev/null
+++ b/Source/DirectFB/lib/direct/direct.c
@@ -0,0 +1,197 @@
+/*
+ (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 <stdlib.h>
+
+#include <pthread.h>
+
+#include <direct/debug.h>
+#include <direct/direct.h>
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/log.h>
+#include <direct/mem.h>
+#include <direct/signals.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+D_DEBUG_DOMAIN( Direct_Main, "Direct/Main", "Initialization and shutdown of libdirect" );
+
+/**************************************************************************************************/
+
+struct __D_DirectCleanupHandler {
+ DirectLink link;
+
+ int magic;
+
+ DirectCleanupHandlerFunc func;
+ void *ctx;
+};
+
+/**************************************************************************************************/
+
+static int refs = 0;
+static DirectLink *handlers = NULL;
+static pthread_mutex_t main_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/**************************************************************************************************/
+
+static void
+direct_cleanup( void )
+{
+ DirectCleanupHandler *handler, *temp;
+
+ if (!refs)
+ return;
+
+ direct_list_foreach_safe (handler, temp, handlers) {
+ D_DEBUG_AT( Direct_Main, "Calling cleanup func %p...\n", handler->func );
+
+ handler->func( handler->ctx );
+
+ /*direct_list_remove( &handlers, &handler->link );
+
+ D_MAGIC_CLEAR( handler );
+
+ D_FREE( handler );*/
+ }
+
+ direct_print_memleaks();
+
+ direct_print_interface_leaks();
+}
+
+/**************************************************************************************************/
+
+DirectResult
+direct_cleanup_handler_add( DirectCleanupHandlerFunc func,
+ void *ctx,
+ DirectCleanupHandler **ret_handler )
+{
+ DirectCleanupHandler *handler;
+
+ D_ASSERT( func != NULL );
+ D_ASSERT( ret_handler != NULL );
+
+ D_DEBUG_AT( Direct_Main,
+ "Adding cleanup handler %p with context %p...\n", func, ctx );
+
+ handler = D_CALLOC( 1, sizeof(DirectCleanupHandler) );
+ if (!handler) {
+ D_WARN( "out of memory" );
+ return DR_NOLOCALMEMORY;
+ }
+
+ handler->func = func;
+ handler->ctx = ctx;
+
+ D_MAGIC_SET( handler, DirectCleanupHandler );
+
+ pthread_mutex_lock( &main_lock );
+
+ if (handlers == NULL)
+ atexit( direct_cleanup );
+
+ direct_list_append( &handlers, &handler->link );
+
+ pthread_mutex_unlock( &main_lock );
+
+ *ret_handler = handler;
+
+ return DR_OK;
+}
+
+DirectResult
+direct_cleanup_handler_remove( DirectCleanupHandler *handler )
+{
+ D_ASSERT( handler != NULL );
+
+ D_MAGIC_ASSERT( handler, DirectCleanupHandler );
+
+ D_DEBUG_AT( Direct_Main, "Removing cleanup handler %p with context %p...\n",
+ handler->func, handler->ctx );
+
+ pthread_mutex_lock( &main_lock );
+ direct_list_remove( &handlers, &handler->link );
+ pthread_mutex_unlock( &main_lock );
+
+ D_MAGIC_CLEAR( handler );
+
+ D_FREE( handler );
+
+ return DR_OK;
+}
+
+DirectResult
+direct_initialize( void )
+{
+ pthread_mutex_lock( &main_lock );
+
+ D_DEBUG_AT( Direct_Main, "direct_initialize() called...\n" );
+
+ if (refs++) {
+ D_DEBUG_AT( Direct_Main, "...%d references now.\n", refs );
+ pthread_mutex_unlock( &main_lock );
+ return DR_OK;
+ }
+ else if (!direct_thread_self_name())
+ direct_thread_set_name( "Main Thread" );
+
+ D_DEBUG_AT( Direct_Main, "...initializing now.\n" );
+
+ direct_signals_initialize();
+
+ pthread_mutex_unlock( &main_lock );
+
+ return DR_OK;
+}
+
+DirectResult
+direct_shutdown( void )
+{
+ pthread_mutex_lock( &main_lock );
+
+ D_DEBUG_AT( Direct_Main, "direct_shutdown() called...\n" );
+
+ if (--refs) {
+ D_DEBUG_AT( Direct_Main, "...%d references left.\n", refs );
+ pthread_mutex_unlock( &main_lock );
+ return DR_OK;
+ }
+
+ D_DEBUG_AT( Direct_Main, "...shutting down now.\n" );
+
+ direct_signals_shutdown();
+
+ pthread_mutex_unlock( &main_lock );
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/direct/direct.h b/Source/DirectFB/lib/direct/direct.h
new file mode 100755
index 0000000..b94e999
--- /dev/null
+++ b/Source/DirectFB/lib/direct/direct.h
@@ -0,0 +1,49 @@
+/*
+ (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 __DIRECT__DIRECT_H__
+#define __DIRECT__DIRECT_H__
+
+#include <direct/types.h>
+
+DirectResult direct_initialize( void );
+DirectResult direct_shutdown( void );
+
+
+typedef void (*DirectCleanupHandlerFunc)( void *ctx );
+
+
+DirectResult direct_cleanup_handler_add( DirectCleanupHandlerFunc func,
+ void *ctx,
+ DirectCleanupHandler **ret_handler );
+
+DirectResult direct_cleanup_handler_remove( DirectCleanupHandler *handler );
+
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/direct.pc.in b/Source/DirectFB/lib/direct/direct.pc.in
new file mode 100755
index 0000000..fa6e663
--- /dev/null
+++ b/Source/DirectFB/lib/direct/direct.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+moduledir=@MODULEDIR@
+moduledirname=@MODULEDIRNAME@
+includedir=@includedir@
+
+Name: Direct
+Description: DirectFB base development library
+Version: @VERSION@
+Libs: -L${libdir} -ldirect @THREADLIB@
+Libs.private: -L${libdir} @DYNLIB@
+Cflags: @THREADFLAGS@ -I@INCLUDEDIR@
diff --git a/Source/DirectFB/lib/direct/fastlz.c b/Source/DirectFB/lib/direct/fastlz.c
new file mode 100755
index 0000000..60bf3ca
--- /dev/null
+++ b/Source/DirectFB/lib/direct/fastlz.c
@@ -0,0 +1,97 @@
+/*
+ (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 <stdlib.h>
+#include <string.h>
+
+#include <direct/fastlz.h>
+#include <direct/messages.h>
+
+#include "flz.h"
+
+
+int
+direct_fastlz_compress( const void *input,
+ int length,
+ void *output )
+{
+ return fastlz_compress_level( 2, input, length, output );
+}
+
+int
+direct_fastlz_decompress( const void *input,
+ int length,
+ void *output,
+ int maxout )
+{
+ return fastlz_decompress( input, length, output, maxout );
+}
+
+int
+direct_fastlz_compress_multi( const void **inputs,
+ int *lengths,
+ unsigned int num,
+ void *output )
+{
+ // FIXME: Optimize by modifying fastlz compressor to take an array of buffers directly
+
+ unsigned int i;
+ int total = 0;
+ int offset = 0;
+ void *buffer;
+ int result;
+
+ if (num == 0)
+ return 0;
+
+ if (num == 1)
+ return direct_fastlz_compress( inputs[0], lengths[0], output );
+
+ for (i=0; i<num; i++)
+ total += lengths[i];
+
+ buffer = malloc( total );
+ if (!buffer) {
+ D_OOM();
+ return 0;
+ }
+
+ for (i=0; i<num; i++) {
+ memcpy( (char*) buffer + offset, inputs[i], lengths[i] );
+
+ offset += lengths[i];
+ }
+
+ result = direct_fastlz_compress( buffer, total, output );
+
+ free( buffer );
+
+ return result;
+}
diff --git a/Source/DirectFB/lib/direct/fastlz.h b/Source/DirectFB/lib/direct/fastlz.h
new file mode 100755
index 0000000..3a8750d
--- /dev/null
+++ b/Source/DirectFB/lib/direct/fastlz.h
@@ -0,0 +1,52 @@
+/*
+ (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 __DIRECT__FASTLZ_H__
+#define __DIRECT__FASTLZ_H__
+
+#include <direct/types.h>
+
+/**********************************************************************************************************************/
+
+int direct_fastlz_compress ( const void *input,
+ int length,
+ void *output );
+
+int direct_fastlz_decompress ( const void *input,
+ int length,
+ void *output,
+ int maxout );
+
+
+int direct_fastlz_compress_multi( const void **inputs,
+ int *lengths,
+ unsigned int num,
+ void *output );
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/flz.c b/Source/DirectFB/lib/direct/flz.c
new file mode 100755
index 0000000..070bbe2
--- /dev/null
+++ b/Source/DirectFB/lib/direct/flz.c
@@ -0,0 +1,555 @@
+/*
+ FastLZ - lightning-fast lossless compression library
+
+ Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
+ Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
+
+/*
+ * Always check for bound when decompressing.
+ * Generally it is best to leave it defined.
+ */
+#define FASTLZ_SAFE
+
+/*
+ * Give hints to the compiler for branch prediction optimization.
+ */
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
+#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
+#else
+#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
+#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
+#endif
+
+/*
+ * Use inlined functions for supported systems.
+ */
+#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
+#define FASTLZ_INLINE inline
+#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
+#define FASTLZ_INLINE __inline
+#else
+#define FASTLZ_INLINE
+#endif
+
+/*
+ * Prevent accessing more than 8-bit at once, except on x86 architectures.
+ */
+#if !defined(FASTLZ_STRICT_ALIGN)
+#define FASTLZ_STRICT_ALIGN
+
+#if 0
+#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
+#undef FASTLZ_STRICT_ALIGN
+#elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */
+#undef FASTLZ_STRICT_ALIGN
+#elif defined(_M_IX86) /* Intel, MSVC */
+#undef FASTLZ_STRICT_ALIGN
+#elif defined(__386)
+#undef FASTLZ_STRICT_ALIGN
+#elif defined(_X86_) /* MinGW */
+#undef FASTLZ_STRICT_ALIGN
+#elif defined(__I86__) /* Digital Mars */
+#undef FASTLZ_STRICT_ALIGN
+#endif
+#endif
+
+#endif
+
+/*
+ * FIXME: use preprocessor magic to set this on different platforms!
+ */
+typedef unsigned char flzuint8;
+typedef unsigned short flzuint16;
+typedef unsigned int flzuint32;
+
+/* prototypes */
+int fastlz_compress(const void* input, int length, void* output);
+int fastlz_compress_level(int level, const void* input, int length, void* output);
+int fastlz_decompress(const void* input, int length, void* output, int maxout);
+
+#define MAX_COPY 32
+#define MAX_LEN 264 /* 256 + 8 */
+#define MAX_DISTANCE 8192
+
+#if !defined(FASTLZ_STRICT_ALIGN)
+#define FASTLZ_READU16(p) *((const flzuint16*)(p))
+#else
+#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
+#endif
+
+#define HASH_LOG 13
+#define HASH_SIZE (1<< HASH_LOG)
+#define HASH_MASK (HASH_SIZE-1)
+#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
+
+#undef FASTLZ_LEVEL
+#define FASTLZ_LEVEL 1
+
+#undef FASTLZ_COMPRESSOR
+#undef FASTLZ_DECOMPRESSOR
+#define FASTLZ_COMPRESSOR fastlz1_compress
+#define FASTLZ_DECOMPRESSOR fastlz1_decompress
+static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
+static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
+#include "flz.c"
+
+#undef FASTLZ_LEVEL
+#define FASTLZ_LEVEL 2
+
+#undef MAX_DISTANCE
+#define MAX_DISTANCE 8191
+#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
+
+#undef FASTLZ_COMPRESSOR
+#undef FASTLZ_DECOMPRESSOR
+#define FASTLZ_COMPRESSOR fastlz2_compress
+#define FASTLZ_DECOMPRESSOR fastlz2_decompress
+static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
+static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
+#include "flz.c"
+
+int fastlz_compress(const void* input, int length, void* output)
+{
+ /* for short block, choose fastlz1 */
+ if(length < 65536)
+ return fastlz1_compress(input, length, output);
+
+ /* else... */
+ return fastlz2_compress(input, length, output);
+}
+
+int fastlz_decompress(const void* input, int length, void* output, int maxout)
+{
+ /* magic identifier for compression level */
+ int level = ((*(const flzuint8*)input) >> 5) + 1;
+
+ if(level == 1)
+ return fastlz1_decompress(input, length, output, maxout);
+ if(level == 2)
+ return fastlz2_decompress(input, length, output, maxout);
+
+ /* unknown level, trigger error */
+ return 0;
+}
+
+int fastlz_compress_level(int level, const void* input, int length, void* output)
+{
+ if(level == 1)
+ return fastlz1_compress(input, length, output);
+ if(level == 2)
+ return fastlz2_compress(input, length, output);
+
+ return 0;
+}
+
+#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
+
+static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
+{
+ const flzuint8* ip = (const flzuint8*) input;
+ const flzuint8* ip_bound = ip + length - 2;
+ const flzuint8* ip_limit = ip + length - 12;
+ flzuint8* op = (flzuint8*) output;
+
+ const flzuint8* htab[HASH_SIZE];
+ const flzuint8** hslot;
+ flzuint32 hval;
+
+ flzuint32 copy;
+
+ /* sanity check */
+ if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
+ {
+ if(length)
+ {
+ /* create literal copy only */
+ *op++ = length-1;
+ ip_bound++;
+ while(ip <= ip_bound)
+ *op++ = *ip++;
+ return length+1;
+ }
+ else
+ return 0;
+ }
+
+ /* initializes hash table */
+ for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
+ *hslot = ip;
+
+ /* we start with literal copy */
+ copy = 2;
+ *op++ = MAX_COPY-1;
+ *op++ = *ip++;
+ *op++ = *ip++;
+
+ /* main loop */
+ while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
+ {
+ const flzuint8* ref;
+ flzuint32 distance;
+
+ /* minimum match length */
+ flzuint32 len = 3;
+
+ /* comparison starting-point */
+ const flzuint8* anchor = ip;
+
+ /* check for a run */
+#if FASTLZ_LEVEL==2
+ if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
+ {
+ distance = 1;
+ ip += 3;
+ ref = anchor - 1 + 3;
+ goto match;
+ }
+#endif
+
+ /* find potential match */
+ HASH_FUNCTION(hval,ip);
+ hslot = htab + hval;
+ ref = htab[hval];
+
+ /* calculate distance to the match */
+ distance = anchor - ref;
+
+ /* update hash table */
+ *hslot = anchor;
+
+ /* is this a match? check the first 3 bytes */
+ if(distance==0 ||
+#if FASTLZ_LEVEL==1
+ (distance >= MAX_DISTANCE) ||
+#else
+ (distance >= MAX_FARDISTANCE) ||
+#endif
+ *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
+ goto literal;
+
+#if FASTLZ_LEVEL==2
+ /* far, needs at least 5-byte match */
+ if(distance >= MAX_DISTANCE)
+ {
+ if(*ip++ != *ref++ || *ip++!= *ref++)
+ goto literal;
+ len += 2;
+ }
+
+ match:
+#endif
+
+ /* last matched byte */
+ ip = anchor + len;
+
+ /* distance is biased */
+ distance--;
+
+ if(!distance)
+ {
+ /* zero distance means a run */
+ flzuint8 x = ip[-1];
+ while(ip < ip_bound)
+ if(*ref++ != x) break; else ip++;
+ }
+ else
+ for(;;)
+ {
+ /* safe because the outer check against ip limit */
+ if(*ref++ != *ip++) break;
+ if(*ref++ != *ip++) break;
+ if(*ref++ != *ip++) break;
+ if(*ref++ != *ip++) break;
+ if(*ref++ != *ip++) break;
+ if(*ref++ != *ip++) break;
+ if(*ref++ != *ip++) break;
+ if(*ref++ != *ip++) break;
+ while(ip < ip_bound)
+ if(*ref++ != *ip++) break;
+ break;
+ }
+
+ /* if we have copied something, adjust the copy count */
+ if(copy)
+ /* copy is biased, '0' means 1 byte copy */
+ *(op-copy-1) = copy-1;
+ else
+ /* back, to overwrite the copy count */
+ op--;
+
+ /* reset literal counter */
+ copy = 0;
+
+ /* length is biased, '1' means a match of 3 bytes */
+ ip -= 3;
+ len = ip - anchor;
+
+ /* encode the match */
+#if FASTLZ_LEVEL==2
+ if(distance < MAX_DISTANCE)
+ {
+ if(len < 7)
+ {
+ *op++ = (len << 5) + (distance >> 8);
+ *op++ = (distance & 255);
+ }
+ else
+ {
+ *op++ = (7 << 5) + (distance >> 8);
+ for(len-=7; len >= 255; len-= 255)
+ *op++ = 255;
+ *op++ = len;
+ *op++ = (distance & 255);
+ }
+ }
+ else
+ {
+ /* far away, but not yet in the another galaxy... */
+ if(len < 7)
+ {
+ distance -= MAX_DISTANCE;
+ *op++ = (len << 5) + 31;
+ *op++ = 255;
+ *op++ = distance >> 8;
+ *op++ = distance & 255;
+ }
+ else
+ {
+ distance -= MAX_DISTANCE;
+ *op++ = (7 << 5) + 31;
+ for(len-=7; len >= 255; len-= 255)
+ *op++ = 255;
+ *op++ = len;
+ *op++ = 255;
+ *op++ = distance >> 8;
+ *op++ = distance & 255;
+ }
+ }
+#else
+
+ if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
+ while(len > MAX_LEN-2)
+ {
+ *op++ = (7 << 5) + (distance >> 8);
+ *op++ = MAX_LEN - 2 - 7 -2;
+ *op++ = (distance & 255);
+ len -= MAX_LEN-2;
+ }
+
+ if(len < 7)
+ {
+ *op++ = (len << 5) + (distance >> 8);
+ *op++ = (distance & 255);
+ }
+ else
+ {
+ *op++ = (7 << 5) + (distance >> 8);
+ *op++ = len - 7;
+ *op++ = (distance & 255);
+ }
+#endif
+
+ /* update the hash at match boundary */
+ HASH_FUNCTION(hval,ip);
+ htab[hval] = ip++;
+ HASH_FUNCTION(hval,ip);
+ htab[hval] = ip++;
+
+ /* assuming literal copy */
+ *op++ = MAX_COPY-1;
+
+ continue;
+
+ literal:
+ *op++ = *anchor++;
+ ip = anchor;
+ copy++;
+ if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
+ {
+ copy = 0;
+ *op++ = MAX_COPY-1;
+ }
+ }
+
+ /* left-over as literal copy */
+ ip_bound++;
+ while(ip <= ip_bound)
+ {
+ *op++ = *ip++;
+ copy++;
+ if(copy == MAX_COPY)
+ {
+ copy = 0;
+ *op++ = MAX_COPY-1;
+ }
+ }
+
+ /* if we have copied something, adjust the copy length */
+ if(copy)
+ *(op-copy-1) = copy-1;
+ else
+ op--;
+
+#if FASTLZ_LEVEL==2
+ /* marker for fastlz2 */
+ *(flzuint8*)output |= (1 << 5);
+#endif
+
+ return op - (flzuint8*)output;
+}
+
+static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
+{
+ const flzuint8* ip = (const flzuint8*) input;
+ const flzuint8* ip_limit = ip + length;
+ flzuint8* op = (flzuint8*) output;
+ flzuint8* op_limit = op + maxout;
+ flzuint32 ctrl = (*ip++) & 31;
+ int loop = 1;
+
+ do
+ {
+ const flzuint8* ref = op;
+ flzuint32 len = ctrl >> 5;
+ flzuint32 ofs = (ctrl & 31) << 8;
+
+ if(ctrl >= 32)
+ {
+#if FASTLZ_LEVEL==2
+ flzuint8 code;
+#endif
+ len--;
+ ref -= ofs;
+ if (len == 7-1)
+#if FASTLZ_LEVEL==1
+ len += *ip++;
+ ref -= *ip++;
+#else
+ do
+ {
+ code = *ip++;
+ len += code;
+ } while (code==255);
+ code = *ip++;
+ ref -= code;
+
+ /* match from 16-bit distance */
+ if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
+ if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
+ {
+ ofs = (*ip++) << 8;
+ ofs += *ip++;
+ ref = op - ofs - MAX_DISTANCE;
+ }
+#endif
+
+#ifdef FASTLZ_SAFE
+ if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
+ return 0;
+
+ if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
+ return 0;
+#endif
+
+ if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
+ ctrl = *ip++;
+ else
+ loop = 0;
+
+ if(ref == op)
+ {
+ /* optimize copy for a run */
+ flzuint8 b = ref[-1];
+ *op++ = b;
+ *op++ = b;
+ *op++ = b;
+ for(; len; --len)
+ *op++ = b;
+ }
+ else
+ {
+#if !defined(FASTLZ_STRICT_ALIGN)
+ const flzuint16* p;
+ flzuint16* q;
+#endif
+ /* copy from reference */
+ ref--;
+ *op++ = *ref++;
+ *op++ = *ref++;
+ *op++ = *ref++;
+
+#if !defined(FASTLZ_STRICT_ALIGN)
+ /* copy a byte, so that now it's word aligned */
+ if(len & 1)
+ {
+ *op++ = *ref++;
+ len--;
+ }
+
+ /* copy 16-bit at once */
+ q = (flzuint16*) op;
+ op += len;
+ p = (const flzuint16*) ref;
+ for(len>>=1; len > 4; len-=4)
+ {
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = *p++;
+ }
+ for(; len; --len)
+ *q++ = *p++;
+#else
+ for(; len; --len)
+ *op++ = *ref++;
+#endif
+ }
+ }
+ else
+ {
+ ctrl++;
+#ifdef FASTLZ_SAFE
+ if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
+ return 0;
+ if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
+ return 0;
+#endif
+
+ *op++ = *ip++;
+ for(--ctrl; ctrl; ctrl--)
+ *op++ = *ip++;
+
+ loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
+ if(loop)
+ ctrl = *ip++;
+ }
+ }
+ while(FASTLZ_EXPECT_CONDITIONAL(loop));
+
+ return op - (flzuint8*)output;
+}
+
+#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
diff --git a/Source/DirectFB/lib/direct/flz.h b/Source/DirectFB/lib/direct/flz.h
new file mode 100755
index 0000000..f87bc7b
--- /dev/null
+++ b/Source/DirectFB/lib/direct/flz.h
@@ -0,0 +1,100 @@
+/*
+ FastLZ - lightning-fast lossless compression library
+
+ Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
+ Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef FASTLZ_H
+#define FASTLZ_H
+
+#define FASTLZ_VERSION 0x000100
+
+#define FASTLZ_VERSION_MAJOR 0
+#define FASTLZ_VERSION_MINOR 0
+#define FASTLZ_VERSION_REVISION 0
+
+#define FASTLZ_VERSION_STRING "0.1.0"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/**
+ Compress a block of data in the input buffer and returns the size of
+ compressed block. The size of input buffer is specified by length. The
+ minimum input buffer size is 16.
+
+ The output buffer must be at least 5% larger than the input buffer
+ and can not be smaller than 66 bytes.
+
+ If the input is not compressible, the return value might be larger than
+ length (input buffer size).
+
+ The input buffer and the output buffer can not overlap.
+*/
+
+int fastlz_compress(const void* input, int length, void* output);
+
+/**
+ Decompress a block of compressed data and returns the size of the
+ decompressed block. If error occurs, e.g. the compressed data is
+ corrupted or the output buffer is not large enough, then 0 (zero)
+ will be returned instead.
+
+ The input buffer and the output buffer can not overlap.
+
+ Decompression is memory safe and guaranteed not to write the output buffer
+ more than what is specified in maxout.
+ */
+
+int fastlz_decompress(const void* input, int length, void* output, int maxout);
+
+/**
+ Compress a block of data in the input buffer and returns the size of
+ compressed block. The size of input buffer is specified by length. The
+ minimum input buffer size is 16.
+
+ The output buffer must be at least 5% larger than the input buffer
+ and can not be smaller than 66 bytes.
+
+ If the input is not compressible, the return value might be larger than
+ length (input buffer size).
+
+ The input buffer and the output buffer can not overlap.
+
+ Compression level can be specified in parameter level. At the moment,
+ only level 1 and level 2 are supported.
+ Level 1 is the fastest compression and generally useful for short data.
+ Level 2 is slightly slower but it gives better compression ratio.
+
+ Note that the compressed data, regardless of the level, can always be
+ decompressed using the function fastlz_decompress above.
+*/
+
+int fastlz_compress_level(int level, const void* input, int length, void* output);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* FASTLZ_H */
diff --git a/Source/DirectFB/lib/direct/hash.c b/Source/DirectFB/lib/direct/hash.c
new file mode 100755
index 0000000..729e866
--- /dev/null
+++ b/Source/DirectFB/lib/direct/hash.c
@@ -0,0 +1,268 @@
+/*
+ (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 <stdlib.h>
+
+#include <direct/debug.h>
+#include <direct/hash.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+
+
+D_DEBUG_DOMAIN( Direct_Hash, "Direct/Hash", "Hash table implementation" );
+
+
+#define REMOVED ((void *) -1)
+
+typedef struct {
+ unsigned long key;
+ void *value;
+} Element;
+
+struct __D_DirectHash {
+ int magic;
+
+ int size;
+
+ int count;
+ int removed;
+
+ Element *elements;
+};
+
+/**************************************************************************************************/
+
+static inline int
+locate_key( const DirectHash *hash, unsigned long key )
+{
+ int pos;
+ const Element *element;
+
+ pos = key % hash->size;
+
+ element = &hash->elements[pos];
+
+ while (element->value) {
+ if (element->value != REMOVED && element->key == key)
+ return pos;
+
+ if (++pos == hash->size)
+ pos = 0;
+
+ element = &hash->elements[pos];
+ }
+
+ return -1;
+}
+
+/**************************************************************************************************/
+
+DirectResult
+direct_hash_create( int size,
+ DirectHash **ret_hash )
+{
+ DirectHash *hash;
+
+ if (size < 17)
+ size = 17;
+
+ D_DEBUG_AT( Direct_Hash, "Creating hash table with initial capacity of %d...\n", size );
+
+ hash = D_CALLOC( 1, sizeof (DirectHash) );
+ if (!hash) {
+ D_WARN( "out of memory" );
+ return DR_NOLOCALMEMORY;
+ }
+
+ hash->size = size;
+ hash->elements = D_CALLOC( size, sizeof(Element) );
+
+ if (!hash->elements) {
+ D_WARN( "out of memory" );
+ D_FREE( hash );
+ return DR_NOLOCALMEMORY;
+ }
+
+ D_MAGIC_SET( hash, DirectHash );
+
+ *ret_hash = hash;
+
+ return DR_OK;
+}
+
+void
+direct_hash_destroy( DirectHash *hash )
+{
+ D_MAGIC_ASSERT( hash, DirectHash );
+
+ D_MAGIC_CLEAR( hash );
+
+ D_FREE( hash->elements );
+ D_FREE( hash );
+}
+
+DirectResult
+direct_hash_insert( DirectHash *hash,
+ unsigned long key,
+ void *value )
+{
+ int pos;
+ Element *element;
+
+ D_MAGIC_ASSERT( hash, DirectHash );
+ D_ASSERT( value != NULL );
+
+ /* Need to resize the hash table? */
+ if ((hash->count + hash->removed) > hash->size / 4) {
+ int i, size = hash->size * 3;
+ Element *elements;
+
+ D_DEBUG_AT( Direct_Hash, "Resizing from %d to %d... (count %d, removed %d)\n",
+ hash->size, size, hash->count, hash->removed );
+
+ elements = D_CALLOC( size, sizeof(Element) );
+ if (!elements) {
+ D_WARN( "out of memory" );
+ return DR_NOLOCALMEMORY;
+ }
+
+ for (i=0; i<hash->size; i++) {
+ Element *element = &hash->elements[i];
+ Element *insertElement;
+
+ if (element->value && element->value != REMOVED) {
+ pos = element->key % size;
+
+ insertElement = &elements[pos];
+ while (insertElement->value && insertElement->value != REMOVED) {
+ if (++pos == size)
+ pos = 0;
+ insertElement = &elements[pos];
+ }
+
+ elements[pos] = *element;
+ }
+ }
+
+ D_FREE( hash->elements );
+
+ hash->size = size;
+ hash->elements = elements;
+ hash->removed = 0;
+ }
+
+ pos = key % hash->size;
+
+ D_DEBUG_AT( Direct_Hash, "Attempting to insert key 0x%08lx at position %d...\n", key, pos );
+
+ element = &hash->elements[pos];
+
+ while (element->value && element->value != REMOVED) {
+ if (element->key == key) {
+ D_BUG( "key already exists" );
+ return DR_BUG;
+ }
+
+ if (++pos == hash->size)
+ pos = 0;
+
+ element = &hash->elements[pos];
+ }
+
+ if (element->value == REMOVED)
+ hash->removed--;
+
+ element->key = key;
+ element->value = value;
+
+ hash->count++;
+
+ D_DEBUG_AT( Direct_Hash, "...inserted at %d, new count = %d, removed = %d, size = %d, key = 0x%08lx.\n",
+ pos, hash->count, hash->removed, hash->size, key );
+
+ return DR_OK;
+}
+
+void
+direct_hash_remove( DirectHash *hash,
+ unsigned long key )
+{
+ int pos;
+
+ D_MAGIC_ASSERT( hash, DirectHash );
+
+ pos = locate_key( hash, key );
+ if (pos == -1) {
+ D_WARN( "key not found" );
+ return;
+ }
+
+ hash->elements[pos].value = REMOVED;
+
+ hash->count--;
+ hash->removed++;
+
+ D_DEBUG_AT( Direct_Hash, "Removed key 0x%08lx at %d, new count = %d, removed = %d, size = %d.\n",
+ key, pos, hash->count, hash->removed, hash->size );
+}
+
+void *
+direct_hash_lookup( DirectHash *hash,
+ unsigned long key )
+{
+ int pos;
+
+ D_MAGIC_ASSERT( hash, DirectHash );
+
+ pos = locate_key( hash, key );
+
+ return (pos != -1) ? hash->elements[pos].value : NULL;
+}
+
+void
+direct_hash_iterate( DirectHash *hash,
+ DirectHashIteratorFunc func,
+ void *ctx )
+{
+ int i;
+
+ D_MAGIC_ASSERT( hash, DirectHash );
+
+ for (i=0; i<hash->size; i++) {
+ Element *element = &hash->elements[i];
+
+ if (!element->value || element->value == REMOVED)
+ continue;
+
+ if (!func( hash, element->key, element->value, ctx ) )
+ return;
+ }
+}
+
diff --git a/Source/DirectFB/lib/direct/hash.h b/Source/DirectFB/lib/direct/hash.h
new file mode 100755
index 0000000..6b487d9
--- /dev/null
+++ b/Source/DirectFB/lib/direct/hash.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 __DIRECT__HASH_H__
+#define __DIRECT__HASH_H__
+
+#include <direct/types.h>
+
+
+typedef bool (*DirectHashIteratorFunc)( DirectHash *hash,
+ unsigned long key,
+ void *value,
+ void *ctx );
+
+
+DirectResult direct_hash_create ( int size,
+ DirectHash **ret_hash );
+
+void direct_hash_destroy( DirectHash *hash );
+
+DirectResult direct_hash_insert ( DirectHash *hash,
+ unsigned long key,
+ void *value );
+
+void direct_hash_remove ( DirectHash *hash,
+ unsigned long key );
+
+void *direct_hash_lookup ( DirectHash *hash,
+ unsigned long key );
+
+void direct_hash_iterate( DirectHash *hash,
+ DirectHashIteratorFunc func,
+ void *ctx );
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/interface.c b/Source/DirectFB/lib/direct/interface.c
new file mode 100755
index 0000000..1247412
--- /dev/null
+++ b/Source/DirectFB/lib/direct/interface.c
@@ -0,0 +1,474 @@
+/*
+ (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 <pthread.h>
+#include <dirent.h>
+#ifndef USE_KOS
+#include <dlfcn.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <alloca.h>
+
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/trace.h>
+#include <direct/util.h>
+
+#ifdef PIC
+#define DYNAMIC_LINKING
+#endif
+
+
+D_DEBUG_DOMAIN( Direct_Interface, "Direct/Interface", "Direct Interface" );
+
+
+typedef struct {
+ DirectLink link;
+
+ int magic;
+
+ char *filename;
+ void *module_handle;
+
+ DirectInterfaceFuncs *funcs;
+
+ const char *type;
+ const char *implementation;
+
+ int references;
+} DirectInterfaceImplementation;
+
+
+#ifdef PTHREADMINIT
+static pthread_mutex_t implementations_mutex = PTHREAD_MUTEX_INITIALIZER;
+#else
+static pthread_mutex_t implementations_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+#endif
+static DirectLink *implementations = NULL;
+
+/**************************************************************************************************/
+
+void
+DirectRegisterInterface( DirectInterfaceFuncs *funcs )
+{
+ DirectInterfaceImplementation *impl;
+
+ D_DEBUG_AT( Direct_Interface, "%s( %p )\n", __FUNCTION__, funcs );
+
+ impl = D_CALLOC( 1, sizeof(DirectInterfaceImplementation) );
+
+ impl->funcs = funcs;
+ impl->type = funcs->GetType();
+ impl->implementation = funcs->GetImplementation();
+
+ D_MAGIC_SET( impl, DirectInterfaceImplementation );
+
+ D_DEBUG_AT( Direct_Interface, " -> %s | %s\n", impl->type, impl->implementation );
+
+ pthread_mutex_lock( &implementations_mutex );
+ direct_list_prepend( &implementations, &impl->link );
+ pthread_mutex_unlock( &implementations_mutex );
+}
+
+void
+DirectUnregisterInterface( DirectInterfaceFuncs *funcs )
+{
+ DirectInterfaceImplementation *impl;
+
+ pthread_mutex_lock( &implementations_mutex );
+
+ direct_list_foreach (impl, implementations) {
+ D_MAGIC_ASSERT( impl, DirectInterfaceImplementation );
+
+ if (impl->funcs == funcs) {
+ direct_list_remove( &implementations, &impl->link );
+
+ break;
+ }
+ }
+
+ pthread_mutex_unlock( &implementations_mutex );
+
+ if (!impl) {
+ D_BUG( "implementation not found" );
+ return;
+ }
+
+ D_MAGIC_CLEAR( impl );
+
+ D_FREE( impl );
+}
+
+DirectResult
+DirectProbeInterface( DirectInterfaceFuncs *funcs, void *ctx )
+{
+ return (funcs->Probe( ctx ) == DR_OK);
+}
+
+DirectResult
+DirectGetInterface( DirectInterfaceFuncs **funcs,
+ const char *type,
+ const char *implementation,
+ DirectInterfaceProbeFunc probe,
+ void *probe_ctx )
+{
+#ifdef DYNAMIC_LINKING
+ int len;
+ DIR *dir;
+ char *interface_dir;
+ struct dirent *entry = NULL;
+ struct dirent tmp;
+ const char *path;
+#endif
+
+ DirectLink *link;
+
+ D_DEBUG_AT( Direct_Interface, "%s( %p, '%s', '%s', %p, %p )\n", __FUNCTION__,
+ funcs, type, implementation, probe, probe_ctx );
+
+ pthread_mutex_lock( &implementations_mutex );
+
+ /*
+ * Check existing implementations first.
+ */
+ direct_list_foreach( link, implementations ) {
+ DirectInterfaceImplementation *impl = (DirectInterfaceImplementation*) link;
+
+ if (type && strcmp( type, impl->type ))
+ continue;
+
+ if (implementation && strcmp( implementation, impl->implementation ))
+ continue;
+
+ D_DEBUG_AT( Direct_Interface, " -> Probing '%s'...\n", impl->implementation );
+
+ if (probe && !probe( impl->funcs, probe_ctx ))
+ continue;
+ else {
+ if (!impl->references) {
+ D_INFO( "Direct/Interface: Using '%s' implementation of '%s'.\n",
+ impl->implementation, impl->type );
+ }
+
+ *funcs = impl->funcs;
+ impl->references++;
+
+ pthread_mutex_unlock( &implementations_mutex );
+
+ return DR_OK;
+ }
+ }
+
+#ifdef DYNAMIC_LINKING
+ /*
+ * Try to load it dynamically.
+ */
+
+ /* NULL type means we can't find plugin, so stop immediately */
+ if (type == NULL) {
+ pthread_mutex_unlock( &implementations_mutex );
+ return DR_NOIMPL;
+ }
+
+ path = direct_config->module_dir;
+ if(!path)
+ path = MODULEDIR;
+
+ len = strlen(path) + strlen("/interfaces/") + strlen(type) + 1;
+ interface_dir = alloca( len );
+ snprintf( interface_dir, len, "%s%sinterfaces/%s", path, (path[strlen(path)-1]=='/') ? "" : "/", type );
+
+ dir = opendir( interface_dir );
+ if (!dir) {
+ D_DEBUG( "Could not open interface directory `%s'!\n", interface_dir );
+ pthread_mutex_unlock( &implementations_mutex );
+ return errno2result( errno );
+ }
+
+ /*
+ * Iterate directory.
+ */
+ while (readdir_r( dir, &tmp, &entry ) == 0 && entry) {
+ void *handle = NULL;
+ char buf[4096];
+
+ DirectInterfaceImplementation *old_impl = (DirectInterfaceImplementation*) implementations;
+
+ if (strlen(entry->d_name) < 4 ||
+ entry->d_name[strlen(entry->d_name)-1] != 'o' ||
+ entry->d_name[strlen(entry->d_name)-2] != 's')
+ continue;
+
+ snprintf( buf, 4096, "%s/%s", interface_dir, entry->d_name );
+
+ /*
+ * Check if it got already loaded.
+ */
+ direct_list_foreach( link, implementations ) {
+ DirectInterfaceImplementation *impl = (DirectInterfaceImplementation*) link;
+
+ if (impl->filename && !strcmp( impl->filename, buf )) {
+ handle = impl->module_handle;
+ break;
+ }
+ }
+
+ /*
+ * If already loaded take the next one.
+ */
+ if (handle)
+ continue;
+
+ /*
+ * Open it and check.
+ */
+ handle = dlopen( buf, RTLD_NOW );
+ if (handle) {
+ DirectInterfaceImplementation *impl = (DirectInterfaceImplementation*) implementations;
+
+ /*
+ * Check if it registered itself.
+ */
+ if (impl == old_impl) {
+ dlclose( handle );
+ continue;
+ }
+
+ /*
+ * Keep filename and module handle.
+ */
+ impl->filename = D_STRDUP( buf );
+ impl->module_handle = handle;
+
+ /*
+ * Almost the same stuff like above, TODO: make function.
+ */
+ if (strcmp( type, impl->type ))
+ continue;
+
+ if (implementation && strcmp( implementation,
+ impl->implementation ))
+ continue;
+
+ if (probe && !probe( impl->funcs, probe_ctx )) {
+ continue;
+ }
+ else {
+ D_INFO( "Direct/Interface: Loaded '%s' implementation of '%s'.\n",
+ impl->implementation, impl->type );
+
+ *funcs = impl->funcs;
+ impl->references++;
+
+ closedir( dir );
+
+ pthread_mutex_unlock( &implementations_mutex );
+
+ return DR_OK;
+ }
+ }
+ else
+ D_DLERROR( "Direct/Interface: Unable to dlopen `%s'!\n", buf );
+ }
+
+ closedir( dir );
+
+ pthread_mutex_unlock( &implementations_mutex );
+#endif
+
+ return DR_NOIMPL;
+}
+
+/**************************************************************************************************/
+
+#if DIRECT_BUILD_DEBUGS /* Build with debug support? */
+
+typedef struct {
+ const void *interface;
+ char *name;
+ char *what;
+
+ const char *func;
+ const char *file;
+ int line;
+
+ DirectTraceBuffer *trace;
+} InterfaceDesc;
+
+static int alloc_count = 0;
+static int alloc_capacity = 0;
+static InterfaceDesc *alloc_list = NULL;
+static pthread_mutex_t alloc_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/**************************************************************************************************/
+
+void
+direct_print_interface_leaks( void )
+{
+ unsigned int i;
+
+ pthread_mutex_lock( &alloc_lock );
+
+ if (alloc_count /*&& (!direct_config || direct_config->debug)*/) {
+ direct_log_printf( NULL, "Interface instances remaining (%d): \n", alloc_count );
+
+ for (i=0; i<alloc_count; i++) {
+ InterfaceDesc *desc = &alloc_list[i];
+
+ direct_log_printf( NULL, " - '%s' at %p (%s) allocated in %s (%s: %u)\n", desc->name,
+ desc->interface, desc->what, desc->func, desc->file, desc->line );
+
+ if (desc->trace)
+ direct_trace_print_stack( desc->trace );
+ }
+ }
+
+ pthread_mutex_unlock( &alloc_lock );
+}
+
+/**************************************************************************************************/
+
+static InterfaceDesc *
+allocate_interface_desc( void )
+{
+ int cap = alloc_capacity;
+
+ if (!cap)
+ cap = 64;
+ else if (cap == alloc_count)
+ cap <<= 1;
+
+ if (cap != alloc_capacity) {
+ alloc_capacity = cap;
+ alloc_list = realloc( alloc_list, sizeof(InterfaceDesc) * cap );
+
+ D_ASSERT( alloc_list != NULL );
+ }
+
+ return &alloc_list[alloc_count++];
+}
+
+static inline void
+fill_interface_desc( InterfaceDesc *desc,
+ const void *interface,
+ const char *name,
+ const char *func,
+ const char *file,
+ int line,
+ const char *what,
+ DirectTraceBuffer *trace )
+{
+ desc->interface = interface;
+ desc->name = strdup( name );
+ desc->what = strdup( what );
+ desc->func = func;
+ desc->file = file;
+ desc->line = line;
+ desc->trace = trace;
+}
+
+/**************************************************************************************************/
+
+__attribute__((no_instrument_function))
+void
+direct_dbg_interface_add( const char *func,
+ const char *file,
+ int line,
+ const char *what,
+ const void *interface,
+ const char *name )
+{
+ InterfaceDesc *desc;
+
+ pthread_mutex_lock( &alloc_lock );
+
+ desc = allocate_interface_desc();
+
+ fill_interface_desc( desc, interface, name,
+ func, file, line, what, direct_trace_copy_buffer(NULL) );
+
+ pthread_mutex_unlock( &alloc_lock );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_dbg_interface_remove( const char *func,
+ const char *file,
+ int line,
+ const char *what,
+ const void *interface )
+{
+ unsigned int i;
+
+ pthread_mutex_lock( &alloc_lock );
+
+ for (i=0; i<alloc_count; i++) {
+ InterfaceDesc *desc = &alloc_list[i];
+
+ if (desc->interface == interface) {
+ if (desc->trace)
+ direct_trace_free_buffer( desc->trace );
+
+ free( desc->what );
+ free( desc->name );
+
+ if (i < --alloc_count)
+ direct_memmove( desc, desc + 1, (alloc_count - i) * sizeof(InterfaceDesc) );
+
+ pthread_mutex_unlock( &alloc_lock );
+
+ return;
+ }
+ }
+
+ pthread_mutex_unlock( &alloc_lock );
+
+ D_ERROR( "Direct/Interface: unknown instance %p (%s) from [%s:%d in %s()]\n",
+ interface, what, file, line, func );
+ D_BREAK( "unknown instance" );
+}
+
+#else /* DIRECT_BUILD_DEBUG */
+
+void
+direct_print_interface_leaks( void )
+{
+}
+
+#endif /* DIRECT_BUILD_DEBUG */
+
diff --git a/Source/DirectFB/lib/direct/interface.h b/Source/DirectFB/lib/direct/interface.h
new file mode 100755
index 0000000..5e6200d
--- /dev/null
+++ b/Source/DirectFB/lib/direct/interface.h
@@ -0,0 +1,215 @@
+/*
+ (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 __DIRECT__INTERFACE_H__
+#define __DIRECT__INTERFACE_H__
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+
+/*
+ * Forward declaration macro for interfaces.
+ */
+#define DECLARE_INTERFACE( IFACE ) \
+ typedef struct _##IFACE IFACE;
+
+/*
+ * Macro for an interface definition.
+ */
+#define DEFINE_INTERFACE( IFACE, IDATA... ) \
+ struct _##IFACE { \
+ void *priv; \
+ int magic; \
+ \
+ DirectResult (*AddRef)( IFACE *thiz ); \
+ DirectResult (*Release)( IFACE *thiz ); \
+ \
+ IDATA \
+ };
+
+/*
+ * Declare base interface
+ */
+DECLARE_INTERFACE( IAny )
+
+/*
+ * Define base interface
+ */
+DEFINE_INTERFACE( IAny, )
+
+/*
+ * Function type for probing of interface implementations
+ */
+typedef DirectResult (*DirectInterfaceGenericProbeFunc)( void *ctx, ... );
+
+/*
+ * Function type for initialization of interface instances
+ */
+typedef DirectResult (*DirectInterfaceGenericConstructFunc)( void *interface, ... );
+
+/*
+ * Function table for interface implementations
+ */
+typedef struct {
+ const char * (*GetType)(void);
+ const char * (*GetImplementation)(void);
+ DirectResult (*Allocate)( void **interface );
+
+ DirectInterfaceGenericProbeFunc Probe;
+ DirectInterfaceGenericConstructFunc Construct;
+} DirectInterfaceFuncs;
+
+/*
+ * Callback type for user probing interface implementations
+ */
+typedef DirectResult (*DirectInterfaceProbeFunc)( DirectInterfaceFuncs *impl, void *ctx );
+
+/*
+ * Loads an interface of a specific 'type'.
+ * Optionally an 'implementation' can be chosen.
+ * A 'probe' function can be used to check available implementations.
+ *
+ * After success 'funcs' is set.
+ */
+DirectResult DirectGetInterface( DirectInterfaceFuncs **funcs,
+ const char *type,
+ const char *implementation,
+ DirectInterfaceProbeFunc probe,
+ void *probe_ctx );
+
+/*
+ * Default probe function. Calls "funcs->Probe(ctx)".
+ * Can be used as the 'probe' argument to DirectGetInterface.
+ * 'probe_ctx' should then be set to the interface specific probe context.
+ */
+DirectResult DirectProbeInterface( DirectInterfaceFuncs *funcs, void *ctx );
+
+/*
+ * Called by implementation modules during 'dlopen'ing or at startup if linked
+ * into the executable.
+ */
+void DirectRegisterInterface( DirectInterfaceFuncs *funcs );
+
+void DirectUnregisterInterface( DirectInterfaceFuncs *funcs );
+
+void direct_print_interface_leaks(void);
+
+#if DIRECT_BUILD_DEBUGS
+void direct_dbg_interface_add ( const char *func,
+ const char *file,
+ int line,
+ const char *what,
+ const void *interface,
+ const char *name );
+
+void direct_dbg_interface_remove( const char *func,
+ const char *file,
+ int line,
+ const char *what,
+ const void *interface );
+#endif
+
+#if DIRECT_BUILD_DEBUG || defined(DIRECT_ENABLE_DEBUG) || defined(DIRECT_FORCE_DEBUG)
+
+#if !DIRECT_BUILD_DEBUGS
+#error Building with debug, but library headers suggest that debug is not supported.
+#endif
+
+#define DIRECT_DBG_INTERFACE_ADD direct_dbg_interface_add
+#define DIRECT_DBG_INTERFACE_REMOVE direct_dbg_interface_remove
+
+#else
+
+#define DIRECT_DBG_INTERFACE_ADD(func,file,line,what,interface,name) do {} while (0)
+#define DIRECT_DBG_INTERFACE_REMOVE(func,file,line,what,interface) do {} while (0)
+
+#endif
+
+
+
+#define DIRECT_ALLOCATE_INTERFACE(p,i) \
+ do { \
+ (p) = (__typeof__(p))D_CALLOC( 1, sizeof(i) ); \
+ \
+ D_MAGIC_SET( (IAny*)(p), DirectInterface ); \
+ \
+ DIRECT_DBG_INTERFACE_ADD( __FUNCTION__, __FILE__, __LINE__, #p, p, #i ); \
+ } while (0)
+
+
+#define DIRECT_ALLOCATE_INTERFACE_DATA(p,i) \
+ i##_data *data; \
+ \
+ D_MAGIC_ASSERT( (IAny*)(p), DirectInterface ); \
+ \
+ if (!(p)->priv) \
+ (p)->priv = D_CALLOC( 1, sizeof(i##_data) ); \
+ \
+ data = (i##_data*)((p)->priv);
+
+
+#define DIRECT_DEALLOCATE_INTERFACE(p) \
+ DIRECT_DBG_INTERFACE_REMOVE( __FUNCTION__, __FILE__, __LINE__, #p, p ); \
+ \
+ if ((p)->priv) { \
+ D_FREE( (p)->priv ); \
+ (p)->priv = NULL; \
+ } \
+ \
+ D_MAGIC_CLEAR( (IAny*)(p) ); \
+ \
+ D_FREE( (p) );
+
+
+#define DIRECT_INTERFACE_GET_DATA(i) \
+ i##_data *data; \
+ \
+ if (!thiz) \
+ return DR_THIZNULL; \
+ \
+ D_MAGIC_ASSERT( (IAny*)thiz, DirectInterface ); \
+ \
+ data = (i##_data*) thiz->priv; \
+ \
+ if (!data) \
+ return DR_DEAD;
+
+
+#define DIRECT_INTERFACE_GET_DATA_FROM(interface,data,prefix) \
+ do { \
+ D_MAGIC_ASSERT( (IAny*)(interface), DirectInterface ); \
+ \
+ (data) = (prefix##_data*) (interface)->priv; \
+ \
+ if (!(data)) \
+ return DR_DEAD; \
+ } while (0)
+
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/interface_implementation.h b/Source/DirectFB/lib/direct/interface_implementation.h
new file mode 100755
index 0000000..7951b59
--- /dev/null
+++ b/Source/DirectFB/lib/direct/interface_implementation.h
@@ -0,0 +1,91 @@
+/*
+ (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 __DIRECT__INTERFACE_IMPLEMENTATION_H__
+#define __DIRECT__INTERFACE_IMPLEMENTATION_H__
+
+#include <direct/interface.h>
+
+
+static const char *GetType( void );
+static const char *GetImplementation( void );
+static DirectResult Allocate( void **interface );
+
+static DirectInterfaceFuncs interface_funcs = {
+ .GetType = GetType,
+ .GetImplementation = GetImplementation,
+ .Allocate = Allocate,
+ .Probe = (DirectInterfaceGenericProbeFunc) Probe,
+ .Construct = (DirectInterfaceGenericConstructFunc) Construct
+};
+
+#define DIRECT_INTERFACE_IMPLEMENTATION(type, impl) \
+ \
+static const char * \
+GetType( void ) \
+{ \
+ return #type; \
+} \
+ \
+static const char * \
+GetImplementation( void ) \
+{ \
+ return #impl; \
+} \
+ \
+static DirectResult \
+Allocate( void **interface ) \
+{ \
+ DIRECT_ALLOCATE_INTERFACE( *interface, type ); \
+ return DR_OK; \
+} \
+ \
+__attribute__((constructor)) \
+void \
+type##_##impl##_ctor(void); \
+ \
+__attribute__((constructor)) \
+void \
+type##_##impl##_ctor(void) \
+{ \
+ DirectRegisterInterface( &interface_funcs ); \
+} \
+ \
+__attribute__((destructor)) \
+void \
+type##_##impl##_dtor(void); \
+ \
+__attribute__((destructor)) \
+void \
+type##_##impl##_dtor(void) \
+{ \
+ DirectUnregisterInterface( &interface_funcs ); \
+}
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/list.c b/Source/DirectFB/lib/direct/list.c
new file mode 100755
index 0000000..8a82bfa
--- /dev/null
+++ b/Source/DirectFB/lib/direct/list.c
@@ -0,0 +1,35 @@
+/*
+ (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 <stddef.h>
+
+#include <direct/list.h>
+
+
diff --git a/Source/DirectFB/lib/direct/list.h b/Source/DirectFB/lib/direct/list.h
new file mode 100755
index 0000000..25ecdf8
--- /dev/null
+++ b/Source/DirectFB/lib/direct/list.h
@@ -0,0 +1,224 @@
+/*
+ (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 __DIRECT__LIST_H__
+#define __DIRECT__LIST_H__
+
+#include <direct/types.h>
+#include <direct/debug.h>
+
+
+struct __D_DirectLink {
+ int magic;
+
+ DirectLink *next;
+ DirectLink *prev; /* The 'prev' pointer of the first element always points
+ to the last element of the list, for fast appending ;-) */
+};
+
+static __inline__ void
+direct_list_prepend( DirectLink **list, DirectLink *link )
+{
+ DirectLink *first = *list;
+
+ link->next = first;
+
+ if (first) {
+ D_MAGIC_ASSERT( first, DirectLink );
+
+ link->prev = first->prev;
+
+ first->prev = link;
+ }
+ else
+ link->prev = link;
+
+ *list = link;
+
+ D_MAGIC_SET( link, DirectLink );
+}
+
+static __inline__ void
+direct_list_append( DirectLink **list, DirectLink *link )
+{
+ DirectLink *first = *list;
+
+ link->next = NULL;
+
+ if (first) {
+ DirectLink *last = first->prev;
+
+ D_MAGIC_ASSERT( first, DirectLink );
+ D_MAGIC_ASSERT( last, DirectLink );
+
+ link->prev = last;
+
+ last->next = first->prev = link;
+ }
+ else
+ *list = link->prev = link;
+
+ D_MAGIC_SET( link, DirectLink );
+}
+
+static __inline__ bool
+direct_list_contains_element_EXPENSIVE( DirectLink *list, DirectLink *link )
+{
+ D_MAGIC_ASSERT_IF( list, DirectLink );
+
+ while (list) {
+ if (list == link)
+ return true;
+
+ list = list->next;
+ }
+
+ return false;
+}
+
+static __inline__ int
+direct_list_count_elements_EXPENSIVE( DirectLink *list )
+{
+ int count = 0;
+
+ while (list) {
+ D_MAGIC_ASSERT( list, DirectLink );
+
+ count++;
+
+ list = list->next;
+ }
+
+ return count;
+}
+
+static __inline__ void
+direct_list_remove( DirectLink **list, DirectLink *link )
+{
+ DirectLink *next;
+ DirectLink *prev;
+
+ D_ASSERT( list != NULL );
+
+ D_ASSERT( direct_list_contains_element_EXPENSIVE( *list, link ) );
+
+ D_MAGIC_ASSERT( *list, DirectLink );
+ D_MAGIC_ASSERT( link, DirectLink );
+
+ next = link->next;
+ prev = link->prev;
+
+ if (next) {
+ D_MAGIC_ASSERT( next, DirectLink );
+
+ next->prev = prev;
+ }
+ else
+ (*list)->prev = prev;
+
+ if (link == *list)
+ *list = next;
+ else {
+ D_MAGIC_ASSERT( prev, DirectLink );
+
+ prev->next = next;
+ }
+
+ link->next = link->prev = NULL;
+
+ D_MAGIC_CLEAR( link );
+}
+
+static __inline__ void
+direct_list_move_to_front( DirectLink **list, DirectLink *link )
+{
+ DirectLink *next;
+ DirectLink *prev;
+ DirectLink *first;
+
+ D_ASSERT( list != NULL );
+
+ first = *list;
+
+ D_ASSERT( direct_list_contains_element_EXPENSIVE( first, link ) );
+
+ D_MAGIC_ASSERT( first, DirectLink );
+ D_MAGIC_ASSERT( link, DirectLink );
+
+ if (first == link)
+ return;
+
+ next = link->next;
+ prev = link->prev;
+
+ D_MAGIC_ASSERT_IF( next, DirectLink );
+ D_MAGIC_ASSERT( prev, DirectLink );
+
+ if (next) {
+ next->prev = prev;
+
+ link->prev = first->prev;
+ }
+ else
+ link->prev = prev;
+
+ prev->next = next;
+
+ link->next = first;
+
+ first->prev = link;
+
+ *list = link;
+}
+
+static __inline__ bool
+direct_list_check_link( const DirectLink *link )
+{
+ D_MAGIC_ASSERT_IF( link, DirectLink );
+
+ return link != NULL;
+}
+
+
+#define direct_list_foreach(elem, list) \
+ for (elem = (__typeof__(elem))(list); \
+ direct_list_check_link( (DirectLink*)(elem) ); \
+ elem = (__typeof__(elem))(((DirectLink*)(elem))->next))
+
+#define direct_list_foreach_reverse(elem, list) \
+ for (elem = (__typeof__(elem))((list) ? (list)->prev : NULL); \
+ direct_list_check_link( (DirectLink*)(elem) ); \
+ elem = (__typeof__(elem))((((DirectLink*)(elem))->prev->next) ? ((DirectLink*)(elem))->prev : NULL))
+
+#define direct_list_foreach_safe(elem, temp, list) \
+ for (elem = (__typeof__(elem))(list), temp = ((__typeof__(temp))(elem) ? (__typeof__(temp))(((DirectLink*)(elem))->next) : NULL); \
+ direct_list_check_link( (DirectLink*)(elem) ); \
+ elem = (__typeof__(elem))(temp), temp = ((__typeof__(temp))(elem) ? (__typeof__(temp))(((DirectLink*)(elem))->next) : NULL))
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/log.c b/Source/DirectFB/lib/direct/log.c
new file mode 100755
index 0000000..774b7a5
--- /dev/null
+++ b/Source/DirectFB/lib/direct/log.c
@@ -0,0 +1,414 @@
+/*
+ (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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <netdb.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/log.h>
+#include <direct/util.h>
+
+
+struct __D_DirectLog {
+ int magic;
+
+ DirectLogType type;
+
+ int fd;
+
+ pthread_mutex_t lock;
+};
+
+/**********************************************************************************************************************/
+
+/* Statically allocated to avoid endless loops between D_CALLOC() and D_DEBUG(), while the latter would only
+ * call the allocation once, if there wouldn't be the loopback...
+ */
+static DirectLog fallback_log;
+
+static DirectLog *default_log = NULL;
+static pthread_once_t init_fallback = PTHREAD_ONCE_INIT;
+
+/**********************************************************************************************************************/
+
+static DirectResult init_stderr( DirectLog *log );
+
+static DirectResult init_file ( DirectLog *log,
+ const char *filename );
+
+static DirectResult init_udp ( DirectLog *log,
+ const char *hostport );
+
+/**********************************************************************************************************************/
+
+DirectResult
+direct_log_create( DirectLogType type,
+ const char *param,
+ DirectLog **ret_log )
+{
+ DirectResult ret = DR_INVARG;
+ DirectLog *log;
+
+ log = D_CALLOC( 1, sizeof(DirectLog) );
+ if (!log)
+ return D_OOM();
+
+ log->type = type;
+
+ switch (type) {
+ case DLT_STDERR:
+ ret = init_stderr( log );
+ break;
+
+ case DLT_FILE:
+ ret = init_file( log, param );
+ break;
+
+ case DLT_UDP:
+ ret = init_udp( log, param );
+ break;
+ }
+
+ if (ret)
+ D_FREE( log );
+ else {
+ direct_util_recursive_pthread_mutex_init( &log->lock );
+
+ D_MAGIC_SET( log, DirectLog );
+
+ *ret_log = log;
+ }
+
+ return ret;
+}
+
+DirectResult
+direct_log_destroy( DirectLog *log )
+{
+ D_MAGIC_ASSERT( log, DirectLog );
+
+ D_ASSERT( &fallback_log != log );
+
+ if (log == default_log)
+ default_log = NULL;
+
+ close( log->fd );
+
+ D_MAGIC_CLEAR( log );
+
+ D_FREE( log );
+
+ return DR_OK;
+}
+
+__attribute__((no_instrument_function))
+DirectResult
+direct_log_printf( DirectLog *log,
+ const char *format, ... )
+{
+ va_list args;
+
+ /*
+ * Don't use D_MAGIC_ASSERT or any other
+ * macros/functions that might cause an endless loop.
+ */
+
+ va_start( args, format );
+
+ /* Use the default log if passed log is invalid. */
+ if (!log || log->magic != D_MAGIC("DirectLog"))
+ log = direct_log_default();
+
+ /* Write to stderr as a fallback if default is invalid, too. */
+ if (!log || log->magic != D_MAGIC("DirectLog")) {
+
+ printf(format,args);
+
+
+
+ //vfprintf( stderr, format, args );
+
+
+
+
+ fflush( stderr );
+ }
+ else {
+ int len;
+ char buf[512];
+
+ len = vsnprintf( buf, sizeof(buf), format, args );
+
+ pthread_mutex_lock( &log->lock );
+
+
+
+
+ // write( log->fd, buf, len );
+ printf("%s\n",buf);
+
+
+
+
+ pthread_mutex_unlock( &log->lock );
+ }
+
+ va_end( args );
+
+ return DR_OK;
+}
+
+DirectResult
+direct_log_set_default( DirectLog *log )
+{
+ D_MAGIC_ASSERT( log, DirectLog );
+
+ default_log = log;
+
+ return DR_OK;
+}
+
+__attribute__((no_instrument_function))
+void
+direct_log_lock( DirectLog *log )
+{
+ D_MAGIC_ASSERT_IF( log, DirectLog );
+
+ if (!log)
+ log = direct_log_default();
+
+ D_MAGIC_ASSERT( log, DirectLog );
+
+ pthread_mutex_lock( &log->lock );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_log_unlock( DirectLog *log )
+{
+ D_MAGIC_ASSERT_IF( log, DirectLog );
+
+ if (!log)
+ log = direct_log_default();
+
+ D_MAGIC_ASSERT( log, DirectLog );
+
+ pthread_mutex_unlock( &log->lock );
+}
+
+__attribute__((no_instrument_function))
+static void
+init_fallback_log( void )
+{
+ fallback_log.type = DLT_STDERR;
+ fallback_log.fd = fileno( stderr );
+
+ direct_util_recursive_pthread_mutex_init( &fallback_log.lock );
+
+ D_MAGIC_SET( &fallback_log, DirectLog );
+}
+
+__attribute__((no_instrument_function))
+DirectLog *
+direct_log_default( void )
+{
+ pthread_once( &init_fallback, init_fallback_log );
+
+ if (!default_log)
+ default_log = &fallback_log;
+
+ D_MAGIC_ASSERT( default_log, DirectLog );
+
+ return default_log;
+}
+
+/**********************************************************************************************************************/
+
+static DirectResult
+init_stderr( DirectLog *log )
+{
+ log->fd = dup( fileno( stderr ) );
+
+ return DR_OK;
+}
+
+static DirectResult
+init_file( DirectLog *log,
+ const char *filename )
+{
+ DirectResult ret;
+ int fd;
+
+ fd = open( filename, O_WRONLY | O_CREAT | O_APPEND, 0664 );
+ if (fd < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Direct/Log: Could not open '%s' for writing!\n", filename );
+ return ret;
+ }
+
+ log->fd = fd;
+
+ return DR_OK;
+}
+
+static DirectResult
+parse_host_addr( const char *hostport,
+ struct addrinfo **ret_addr )
+{
+ int i, ret;
+
+ int size = strlen( hostport ) + 1;
+ char buf[size];
+
+ char *hoststr = buf;
+ char *portstr = NULL;
+ char *end;
+
+ struct addrinfo hints;
+
+ memcpy( buf, hostport, size );
+
+ for (i=0; i<size; i++) {
+ if (buf[i] == ':') {
+ buf[i] = 0;
+ portstr = &buf[i+1];
+
+ break;
+ }
+ }
+
+ if (!portstr) {
+ D_ERROR( "Direct/Log: Parse error in '%s' that should be '<host>:<port>'!\n", hostport );
+ return DR_INVARG;
+ }
+
+ strtoul( portstr, &end, 10 );
+ if (end && *end) {
+ D_ERROR( "Direct/Log: Parse error in port number '%s'!\n", portstr );
+ return DR_INVARG;
+ }
+
+ memset( &hints, 0, sizeof(hints) );
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_family = PF_UNSPEC;
+
+ ret = getaddrinfo( hoststr, portstr, &hints, ret_addr );
+ if (ret) {
+ switch (ret) {
+ 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: Port %s is unreachable!\n", portstr );
+ 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;
+ }
+ }
+
+ return DR_OK;
+}
+
+static DirectResult
+init_udp( DirectLog *log,
+ const char *hostport )
+{
+ DirectResult ret;
+ int fd;
+ struct addrinfo *addr;
+
+ ret = parse_host_addr( hostport, &addr );
+ if (ret)
+ return ret;
+
+ fd = socket( addr->ai_family, SOCK_DGRAM, 0 );
+ if (fd < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Direct/Log: Could not create a UDP socket!\n" );
+ freeaddrinfo( addr );
+ return ret;
+ }
+
+ ret = connect( fd, addr->ai_addr, addr->ai_addrlen );
+ freeaddrinfo( addr );
+
+ if (ret) {
+ ret = errno2result( errno );
+ D_PERROR( "Direct/Log: Could not connect UDP socket to '%s'!\n", hostport );
+ close( fd );
+ return ret;
+ }
+
+ log->fd = fd;
+
+ return DR_OK;
+}
diff --git a/Source/DirectFB/lib/direct/log.h b/Source/DirectFB/lib/direct/log.h
new file mode 100755
index 0000000..68eeccb
--- /dev/null
+++ b/Source/DirectFB/lib/direct/log.h
@@ -0,0 +1,89 @@
+/*
+ (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 __DIRECT__LOG_H__
+#define __DIRECT__LOG_H__
+
+#include <direct/types.h>
+#include <direct/messages.h>
+
+
+typedef enum {
+ DLT_STDERR, /* Simply print out log on stderr. */
+ DLT_FILE, /* Write log into a file. */
+ DLT_UDP /* Send out log via UDP. */
+} DirectLogType;
+
+
+/*
+ * Creates a logging facility.
+ *
+ * For each 'type' the 'param' has a different meaning:
+ * DLT_STDERR ignored (leave NULL)
+ * DLT_FILE file name
+ * DLT_UDP <ip>:<port>
+ */
+DirectResult direct_log_create ( DirectLogType type,
+ const char *param,
+ DirectLog **ret_log );
+
+/*
+ * Destroys a logging facility.
+ */
+DirectResult direct_log_destroy ( DirectLog *log );
+
+/*
+ * Write to the log in a printf fashion.
+ *
+ * If log is NULL, the default log is used if it's valid,
+ * otherwise stderr is used a fallback until now.
+ */
+DirectResult direct_log_printf ( DirectLog *log,
+ const char *format, ... ) D_FORMAT_PRINTF(2);
+
+/*
+ * Set the default log that's used when no valid log is passed.
+ */
+DirectResult direct_log_set_default( DirectLog *log );
+
+/*
+ * Locks a logging facility for non-intermixed output of multiple calls in multiple threads. Not mandatory.
+ */
+void direct_log_lock ( DirectLog *log );
+
+/*
+ * Unlocks a logging facility.
+ */
+void direct_log_unlock ( DirectLog *log );
+
+/*
+ * Returns the default log.
+ */
+DirectLog *direct_log_default( void );
+
+#endif
diff --git a/Source/DirectFB/lib/direct/mem.c b/Source/DirectFB/lib/direct/mem.c
new file mode 100755
index 0000000..7b65a32
--- /dev/null
+++ b/Source/DirectFB/lib/direct/mem.c
@@ -0,0 +1,350 @@
+/*
+ (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/build.h>
+
+
+#if DIRECT_BUILD_DEBUGS /* Build with debug support? */
+
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/trace.h>
+#include <direct/util.h>
+
+
+D_DEBUG_DOMAIN( Direct_Mem, "Direct/Mem", "libdirect memory allocation (debugging)" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ const void *mem;
+ size_t bytes;
+ const char *func;
+ const char *file;
+ int line;
+ DirectTraceBuffer *trace;
+} MemDesc;
+
+/**********************************************************************************************************************/
+
+static int alloc_count = 0;
+static int alloc_capacity = 0;
+static MemDesc *alloc_list = NULL;
+static pthread_mutex_t alloc_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/**********************************************************************************************************************/
+
+void
+direct_print_memleaks( void )
+{
+ unsigned int i;
+
+ /* Debug only. */
+ pthread_mutex_lock( &alloc_lock );
+
+ if (alloc_count && (!direct_config || direct_config->debugmem)) {
+ direct_log_printf( NULL, "Local memory allocations remaining (%d): \n", alloc_count );
+
+ for (i=0; i<alloc_count; i++) {
+ MemDesc *desc = &alloc_list[i];
+
+ direct_log_printf( NULL, "%7zu bytes at %p allocated in %s (%s: %u)\n",
+ desc->bytes, desc->mem, desc->func, desc->file, desc->line );
+
+ if (desc->trace)
+ direct_trace_print_stack( desc->trace );
+ }
+ }
+
+ pthread_mutex_unlock( &alloc_lock );
+}
+
+/**********************************************************************************************************************/
+
+/* FIXME: Replace array by linked list, or at least avoid the memmove on free of an item. */
+
+static MemDesc *
+allocate_mem_desc( void )
+{
+ int cap = alloc_capacity;
+
+ if (!cap)
+ cap = 64;
+ else if (cap == alloc_count)
+ cap <<= 1;
+
+ if (cap != alloc_capacity) {
+ void *new_list = malloc( sizeof(MemDesc) * cap );
+
+ if (!new_list) {
+ D_WARN( "could not allocate more descriptors (%d->%d)", alloc_capacity, cap );
+ return NULL;
+ }
+
+ direct_memcpy( new_list, alloc_list, sizeof(MemDesc) * alloc_count );
+
+ free( alloc_list );
+
+ alloc_capacity = cap;
+ alloc_list = new_list;
+ }
+
+ return &alloc_list[alloc_count++];
+}
+
+static inline void
+fill_mem_desc( MemDesc *desc, const void *mem, int bytes,
+ const char *func, const char *file, int line, DirectTraceBuffer *trace )
+{
+ desc->mem = mem;
+ desc->bytes = bytes;
+ desc->func = func;
+ desc->file = file;
+ desc->line = line;
+ desc->trace = trace;
+}
+
+/**********************************************************************************************************************/
+
+void *
+direct_malloc( const char* file, int line, const char *func, size_t bytes )
+{
+ void *mem;
+ MemDesc *desc;
+
+ D_DEBUG_AT( Direct_Mem, " +%6zu bytes [%s:%d in %s()]\n", bytes, file, line, func );
+
+ mem = malloc( bytes );
+ if (!mem)
+ return NULL;
+
+ if (!direct_config->debugmem)
+ return mem;
+
+
+ /* Debug only. */
+ pthread_mutex_lock( &alloc_lock );
+ desc = allocate_mem_desc();
+ pthread_mutex_unlock( &alloc_lock );
+
+ if (desc)
+ fill_mem_desc( desc, mem, bytes, func, file, line, direct_trace_copy_buffer(NULL) );
+
+ return mem;
+}
+
+void *
+direct_calloc( const char* file, int line, const char *func, size_t count, size_t bytes )
+{
+ void *mem;
+ MemDesc *desc;
+
+ D_DEBUG_AT( Direct_Mem, " +%6zu bytes [%s:%d in %s()]\n", count * bytes, file, line, func );
+
+ mem = calloc( count, bytes );
+ if (!mem)
+ return NULL;
+
+ if (!direct_config->debugmem)
+ return mem;
+
+
+ /* Debug only. */
+ pthread_mutex_lock( &alloc_lock );
+ desc = allocate_mem_desc();
+ pthread_mutex_unlock( &alloc_lock );
+
+ if (desc)
+ fill_mem_desc( desc, mem, count * bytes, func, file, line, direct_trace_copy_buffer(NULL) );
+
+ return mem;
+}
+
+void *
+direct_realloc( const char *file, int line, const char *func, const char *what, void *mem, size_t bytes )
+{
+ int i;
+
+ if (!mem)
+ return direct_malloc( file, line, func, bytes );
+
+ if (!bytes) {
+ direct_free( file, line, func, what, mem );
+ return NULL;
+ }
+
+ if (!direct_config->debugmem) {
+ D_DEBUG_AT( Direct_Mem, " *%6zu bytes [%s:%d in %s()] '%s'\n", bytes, file, line, func, what );
+ return realloc( mem, bytes );
+ }
+
+
+ /* Debug only. */
+ pthread_mutex_lock( &alloc_lock );
+
+ for (i=0; i<alloc_count; i++) {
+ MemDesc *desc = &alloc_list[i];
+
+ if (desc->mem == mem) {
+ void *new_mem = realloc( mem, bytes );
+
+ D_DEBUG_AT( Direct_Mem, " %c%6zu bytes [%s:%d in %s()] (%s%zu) <- %p -> %p '%s'\n",
+ (bytes > desc->bytes) ? '>' : '<', bytes, file, line, func,
+ (bytes > desc->bytes) ? "+" : "", bytes - desc->bytes, mem, new_mem, what);
+
+ if (desc->trace) {
+ direct_trace_free_buffer( desc->trace );
+ desc->trace = NULL;
+ }
+
+ if (!new_mem) {
+ D_WARN( "could not reallocate memory (%p: %zu->%zu)", mem, desc->bytes, bytes );
+
+ alloc_count--;
+
+ /* FIXME: This can be very slow. */
+ if (i < alloc_count)
+ direct_memmove( desc, desc + 1, (alloc_count - i) * sizeof(MemDesc) );
+ }
+ else
+ fill_mem_desc( desc, new_mem, bytes, func, file, line, direct_trace_copy_buffer(NULL) );
+
+ pthread_mutex_unlock( &alloc_lock );
+
+ return new_mem;
+ }
+ }
+
+ pthread_mutex_unlock( &alloc_lock );
+
+ D_ERROR( "Direct/Mem: Not reallocating unknown %p (%s) from [%s:%d in %s()] - corrupt/incomplete list?\n",
+ mem, what, file, line, func );
+
+ return direct_malloc( file, line, func, bytes );
+}
+
+void
+direct_free( const char *file, int line, const char *func, const char *what, void *mem )
+{
+ unsigned int i;
+
+ if (!mem) {
+ D_WARN( "%s (NULL) called", __FUNCTION__ );
+ return;
+ }
+
+ if (!direct_config->debugmem) {
+ D_DEBUG_AT( Direct_Mem, " - number of bytes of %s [%s:%d in %s()] -> %p\n", what, file, line, func, mem );
+ free( mem );
+ return;
+ }
+
+
+ /* Debug only. */
+ pthread_mutex_lock( &alloc_lock );
+
+ for (i=0; i<alloc_count; i++) {
+ MemDesc *desc = &alloc_list[i];
+
+ if (desc->mem == mem) {
+ free( mem );
+
+ D_DEBUG_AT( Direct_Mem, " -%6zu bytes [%s:%d in %s()] -> %p '%s'\n",
+ desc->bytes, file, line, func, mem, what );
+
+ if (desc->trace)
+ direct_trace_free_buffer( desc->trace );
+
+ alloc_count--;
+
+ /* FIXME: This can be very slow. */
+ if (i < alloc_count)
+ direct_memmove( desc, desc + 1, (alloc_count - i) * sizeof(MemDesc) );
+
+ pthread_mutex_unlock( &alloc_lock );
+
+ return;
+ }
+ }
+
+ pthread_mutex_unlock( &alloc_lock );
+
+ D_ERROR( "Direct/Mem: Not freeing unknown %p (%s) from [%s:%d in %s()] - corrupt/incomplete list?\n",
+ mem, what, file, line, func );
+}
+
+char *
+direct_strdup( const char* file, int line, const char *func, const char *string )
+{
+ void *mem;
+ MemDesc *desc;
+ size_t length = strlen( string ) + 1;
+
+ mem = malloc( length );
+ D_DEBUG_AT( Direct_Mem, " +%6zu bytes [%s:%d in %s()] -> %p \"%30s\"\n", length, file, line, func, mem, string );
+ if (!mem)
+ return NULL;
+
+ direct_memcpy( mem, string, length );
+
+ if (!direct_config->debugmem)
+ return mem;
+
+
+ /* Debug only. */
+ pthread_mutex_lock( &alloc_lock );
+ desc = allocate_mem_desc();
+ pthread_mutex_unlock( &alloc_lock );
+
+ if (desc)
+ fill_mem_desc( desc, mem, length, func, file, line, direct_trace_copy_buffer(NULL) );
+
+ return mem;
+}
+
+/**********************************************************************************************************************/
+
+#else
+
+void
+direct_print_memleaks( void )
+{
+}
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/mem.h b/Source/DirectFB/lib/direct/mem.h
new file mode 100755
index 0000000..2366e26
--- /dev/null
+++ b/Source/DirectFB/lib/direct/mem.h
@@ -0,0 +1,84 @@
+/*
+ (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 __DIRECT__MEM_H__
+#define __DIRECT__MEM_H__
+
+#include <stddef.h>
+
+#include <direct/build.h>
+
+void direct_print_memleaks( void );
+
+
+void direct_free ( const char *file, int line,
+ const char *func, const char *what, void *mem );
+
+void *direct_malloc ( const char *file, int line,
+ const char *func, size_t bytes );
+
+void *direct_calloc ( const char *file, int line,
+ const char *func, size_t count, size_t bytes);
+
+void *direct_realloc( const char *file, int line,
+ const char *func, const char *what, void *mem,
+ size_t bytes );
+
+char *direct_strdup ( const char *file, int line,
+ const char *func, const char *string );
+
+
+#if DIRECT_BUILD_DEBUG || defined(DIRECT_ENABLE_DEBUG) || defined(DIRECT_FORCE_DEBUG)
+
+#if !DIRECT_BUILD_DEBUGS
+#warning Building with debug, but library headers suggest that debug is not supported.
+#endif
+
+
+#define D_FREE(mem) direct_free( __FILE__, __LINE__, __FUNCTION__, #mem, mem )
+#define D_MALLOC(bytes) direct_malloc( __FILE__, __LINE__, __FUNCTION__, bytes )
+#define D_CALLOC(count,bytes) direct_calloc( __FILE__, __LINE__, __FUNCTION__, count, bytes )
+#define D_REALLOC(mem,bytes) direct_realloc( __FILE__, __LINE__, __FUNCTION__, #mem, mem, bytes )
+#define D_STRDUP(string) direct_strdup( __FILE__, __LINE__, __FUNCTION__, string )
+
+#else
+
+#include <stdlib.h>
+#include <string.h>
+
+#define D_FREE free
+#define D_MALLOC malloc
+#define D_CALLOC calloc
+#define D_REALLOC realloc
+#define D_STRDUP strdup
+
+#endif
+
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/memcpy.c b/Source/DirectFB/lib/direct/memcpy.c
new file mode 100755
index 0000000..918853f
--- /dev/null
+++ b/Source/DirectFB/lib/direct/memcpy.c
@@ -0,0 +1,265 @@
+/*
+ (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>.
+
+ Fast memcpy code was taken from xine (see below).
+
+ 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 <sys/time.h>
+#include <time.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <dfb_types.h>
+
+#include <direct/conf.h>
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+#if defined (ARCH_PPC) || defined (ARCH_ARM) || (SIZEOF_LONG == 8)
+# define RUN_BENCHMARK 1
+#else
+# define RUN_BENCHMARK 0
+#endif
+
+#if RUN_BENCHMARK
+D_DEBUG_DOMAIN( Direct_Memcpy, "Direct/Memcpy", "Direct's Memcpy Routines" );
+#endif
+
+#ifdef USE_PPCASM
+#include "ppcasm_memcpy.h"
+#endif
+
+#if defined(USE_ARMASM) && !defined(WORDS_BIGENDIAN)
+#include "armasm_memcpy.h"
+#endif
+
+
+#if SIZEOF_LONG == 8
+
+static void * generic64_memcpy( void * to, const void * from, size_t len )
+{
+ register u8 *d = (u8*)to;
+ register const u8 *s = (const u8*)from;
+ size_t n;
+
+ if (len >= 128) {
+ unsigned long delta;
+
+ /* Align destination to 8-byte boundary */
+ delta = (unsigned long)d & 7;
+ if (delta) {
+ len -= 8 - delta;
+
+ if ((unsigned long)d & 1) {
+ *d++ = *s++;
+ }
+ if ((unsigned long)d & 2) {
+ *((u16*)d) = *((const u16*)s);
+ d += 2; s += 2;
+ }
+ if ((unsigned long)d & 4) {
+ *((u32*)d) = *((const u32*)s);
+ d += 4; s += 4;
+ }
+ }
+
+ n = len >> 6;
+ len &= 63;
+
+ for (; n; n--) {
+ ((u64*)d)[0] = ((const u64*)s)[0];
+ ((u64*)d)[1] = ((const u64*)s)[1];
+ ((u64*)d)[2] = ((const u64*)s)[2];
+ ((u64*)d)[3] = ((const u64*)s)[3];
+ ((u64*)d)[4] = ((const u64*)s)[4];
+ ((u64*)d)[5] = ((const u64*)s)[5];
+ ((u64*)d)[6] = ((const u64*)s)[6];
+ ((u64*)d)[7] = ((const u64*)s)[7];
+ d += 64; s += 64;
+ }
+ }
+ /*
+ * Now do the tail of the block
+ */
+ if (len) {
+ n = len >> 3;
+
+ for (; n; n--) {
+ *((u64*)d) = *((const u64*)s);
+ d += 8; s += 8;
+ }
+ if (len & 4) {
+ *((u32*)d) = *((const u32*)s);
+ d += 4; s += 4;
+ }
+ if (len & 2) {
+ *((u16*)d) = *((const u16*)s);
+ d += 2; s += 2;
+ }
+ if (len & 1)
+ *d = *s;
+ }
+
+ return to;
+}
+
+#endif /* SIZEOF_LONG == 8 */
+
+
+typedef void* (*memcpy_func)(void *to, const void *from, size_t len);
+
+static struct {
+ char *name;
+ char *desc;
+ memcpy_func function;
+ unsigned long long time;
+ u32 cpu_require;
+} memcpy_method[] =
+{
+ { NULL, NULL, NULL, 0, 0},
+ { "libc", "libc memcpy()", (memcpy_func) memcpy, 0, 0},
+#if SIZEOF_LONG == 8
+ { "generic64","Generic 64bit memcpy()", generic64_memcpy, 0, 0},
+#endif /* SIZEOF_LONG == 8 */
+#ifdef USE_PPCASM
+ { "ppc", "ppcasm_memcpy()", direct_ppcasm_memcpy, 0, 0},
+#ifdef __LINUX__
+ { "ppccache", "ppcasm_cacheable_memcpy()", direct_ppcasm_cacheable_memcpy, 0, 0},
+#endif /* __LINUX__ */
+#endif /* USE_PPCASM */
+#if defined(USE_ARMASM) && !defined(WORDS_BIGENDIAN)
+ { "arm", "armasm_memcpy()", direct_armasm_memcpy, 0, 0},
+#endif
+ { NULL, NULL, NULL, 0, 0}
+};
+
+
+static inline unsigned long long int rdtsc( void )
+{
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+ return (tv.tv_sec * 1000000 + tv.tv_usec);
+}
+
+
+memcpy_func direct_memcpy = (memcpy_func) memcpy;
+
+#define BUFSIZE 1024
+
+void
+direct_find_best_memcpy( void )
+{
+ /* Save library size and startup time
+ on platforms without a special memcpy() implementation. */
+#if RUN_BENCHMARK
+ unsigned long long t;
+ char *buf1, *buf2;
+ int i, j, best = 0;
+ u32 config_flags = 0;
+
+ if (direct_config->memcpy) {
+ for (i=1; memcpy_method[i].name; i++) {
+ if (!strcmp( direct_config->memcpy, memcpy_method[i].name )) {
+ if (memcpy_method[i].cpu_require & ~config_flags)
+ break;
+
+ direct_memcpy = memcpy_method[i].function;
+
+ D_INFO( "Direct/Memcpy: Forced to use %s\n", memcpy_method[i].desc );
+
+ return;
+ }
+ }
+ }
+
+ if (!(buf1 = D_MALLOC( BUFSIZE * 500 )))
+ return;
+
+ if (!(buf2 = D_MALLOC( BUFSIZE * 500 ))) {
+ D_FREE( buf1 );
+ return;
+ }
+
+ D_DEBUG_AT( Direct_Memcpy, "Benchmarking memcpy methods (smaller is better):\n");
+
+ /* make sure buffers are present on physical memory */
+ memcpy( buf1, buf2, BUFSIZE * 500 );
+ memcpy( buf2, buf1, BUFSIZE * 500 );
+
+ for (i=1; memcpy_method[i].name; i++) {
+ if (memcpy_method[i].cpu_require & ~config_flags)
+ continue;
+
+ t = rdtsc();
+
+ for (j=0; j<500; j++)
+ memcpy_method[i].function( buf1 + j*BUFSIZE, buf2 + j*BUFSIZE, BUFSIZE );
+
+ t = rdtsc() - t;
+ memcpy_method[i].time = t;
+
+ D_DEBUG_AT( Direct_Memcpy, "\t%-10s %20lld\n", memcpy_method[i].name, t );
+
+ if (best == 0 || t < memcpy_method[best].time)
+ best = i;
+ }
+
+ if (best) {
+ direct_memcpy = memcpy_method[best].function;
+
+ D_INFO( "Direct/Memcpy: Using %s\n", memcpy_method[best].desc );
+ }
+
+ D_FREE( buf1 );
+ D_FREE( buf2 );
+#endif
+}
+
+void
+direct_print_memcpy_routines( void )
+{
+ int i;
+ u32 config_flags = 0;
+
+ direct_log_printf( NULL, "\nPossible values for memcpy option are:\n\n" );
+
+ for (i=1; memcpy_method[i].name; i++) {
+ bool unsupported = (memcpy_method[i].cpu_require & ~config_flags);
+
+ direct_log_printf( NULL, " %-10s %-27s %s\n", memcpy_method[i].name,
+ memcpy_method[i].desc, unsupported ? "" : "supported" );
+ }
+
+ direct_log_printf( NULL, "\n" );
+}
+
diff --git a/Source/DirectFB/lib/direct/memcpy.h b/Source/DirectFB/lib/direct/memcpy.h
new file mode 100755
index 0000000..374bc54
--- /dev/null
+++ b/Source/DirectFB/lib/direct/memcpy.h
@@ -0,0 +1,51 @@
+/*
+ (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 __DIRECT__MEMCPY_H__
+#define __DIRECT__MEMCPY_H__
+
+#include <stdlib.h>
+#include <string.h>
+
+
+void direct_find_best_memcpy( void );
+void direct_print_memcpy_routines( void );
+
+extern void *(*direct_memcpy)( void *to, const void *from, size_t len );
+
+static __inline__ void *direct_memmove( void *to, const void *from, size_t len )
+{
+ if ((from < to && ((const char*) from + len) < ((char*) to)) ||
+ (((char*) to + len) < ((const char*) from)))
+ return direct_memcpy( to, from, len );
+ else
+ return memmove( to, from, len );
+}
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/messages.c b/Source/DirectFB/lib/direct/messages.c
new file mode 100755
index 0000000..21b5978
--- /dev/null
+++ b/Source/DirectFB/lib/direct/messages.c
@@ -0,0 +1,215 @@
+/*
+ (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 <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <direct/build.h>
+#include <direct/log.h>
+#include <direct/messages.h>
+#include <direct/trace.h>
+#include <direct/util.h>
+
+
+#if DIRECT_BUILD_TEXT
+
+__attribute__((no_instrument_function))
+void
+direct_messages_info( const char *format, ... )
+{
+ char buf[512];
+
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+ direct_log_printf( NULL, "(*) %s", buf );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_messages_error( const char *format, ... )
+{
+ char buf[512];
+
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+ direct_log_printf( NULL, "(!) %s", buf );
+
+ direct_trace_print_stack( NULL );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_messages_derror( DirectResult result, const char *format, ... )
+{
+ char buf[512];
+
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+ direct_log_printf( NULL, "(!) %s --> %s\n", buf, DirectResultString( result ) );
+
+ direct_trace_print_stack( NULL );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_messages_perror( int erno, const char *format, ... )
+{
+ char buf[512];
+
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+ direct_log_printf( NULL, "(!) %s --> %s\n", buf, strerror( erno ) );
+
+ direct_trace_print_stack( NULL );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_messages_dlerror( const char *dlerr, const char *format, ... )
+{
+ char buf[512];
+
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+ direct_log_printf( NULL, "(!) %s --> %s\n", buf, dlerr );
+
+ direct_trace_print_stack( NULL );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_messages_once( const char *func,
+ const char *file,
+ int line,
+ const char *format, ... )
+{
+ char buf[512];
+
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+ direct_log_printf( NULL, " (!!!) *** ONCE [%s] *** [%s:%d in %s()]\n", buf, file, line, func );
+
+ direct_trace_print_stack( NULL );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_messages_unimplemented( const char *func,
+ const char *file,
+ int line )
+{
+ direct_log_printf( NULL, " (!!!) *** UNIMPLEMENTED [%s] *** [%s:%d]\n", func, file, line );
+
+ direct_trace_print_stack( NULL );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_messages_bug( const char *func,
+ const char *file,
+ int line,
+ const char *format, ... )
+{
+ char buf[512];
+
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+ direct_log_printf( NULL, " (!?!) *** BUG [%s] *** [%s:%d in %s()]\n", buf, file, line, func );
+
+ direct_trace_print_stack( NULL );
+}
+
+__attribute__((no_instrument_function))
+void
+direct_messages_warn( const char *func,
+ const char *file,
+ int line,
+ const char *format, ... )
+{
+ char buf[512];
+
+ va_list ap;
+
+ va_start( ap, format );
+
+ vsnprintf( buf, sizeof(buf), format, ap );
+
+ va_end( ap );
+
+ direct_log_printf( NULL, " (!!!) *** WARNING [%s] *** [%s:%d in %s()]\n", buf, file, line, func );
+
+ direct_trace_print_stack( NULL );
+}
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/messages.h b/Source/DirectFB/lib/direct/messages.h
new file mode 100755
index 0000000..bafce88
--- /dev/null
+++ b/Source/DirectFB/lib/direct/messages.h
@@ -0,0 +1,173 @@
+/*
+ (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 __DIRECT__MESSAGES_H__
+#define __DIRECT__MESSAGES_H__
+
+#include <direct/build.h>
+#include <direct/types.h>
+
+
+#if __GNUC__ >= 3
+#define D_FORMAT_PRINTF(n) __attribute__((__format__ (__printf__, n, n+1)))
+#else
+#define D_FORMAT_PRINTF(n)
+#endif
+
+typedef enum {
+ DMT_NONE = 0x00000000, /* No message type. */
+
+ DMT_BANNER = 0x00000001, /* Startup banner. */
+ DMT_INFO = 0x00000002, /* Info messages. */
+ DMT_WARNING = 0x00000004, /* Warnings. */
+ DMT_ERROR = 0x00000008, /* Error messages: regular, with DFBResult, bugs,
+ system call errors, dlopen errors */
+ DMT_UNIMPLEMENTED = 0x00000010, /* Messages notifying unimplemented functionality. */
+ DMT_ONCE = 0x00000020, /* One-shot messages .*/
+
+ DMT_ALL = 0x0000003f /* All types. */
+} DirectMessageType;
+
+#if DIRECT_BUILD_TEXT
+
+#include <errno.h>
+
+#include <direct/conf.h>
+
+
+void direct_messages_info ( const char *format, ... ) D_FORMAT_PRINTF(1);
+
+void direct_messages_error ( const char *format, ... ) D_FORMAT_PRINTF(1);
+
+void direct_messages_derror ( DirectResult result,
+ const char *format, ... ) D_FORMAT_PRINTF(2);
+
+void direct_messages_perror ( int erno,
+ const char *format, ... ) D_FORMAT_PRINTF(2);
+
+void direct_messages_dlerror ( const char *dlerr,
+ const char *format, ... ) D_FORMAT_PRINTF(2);
+
+void direct_messages_once ( const char *func,
+ const char *file,
+ int line,
+ const char *format, ... ) D_FORMAT_PRINTF(4);
+
+void direct_messages_unimplemented( const char *func,
+ const char *file,
+ int line );
+
+void direct_messages_bug ( const char *func,
+ const char *file,
+ int line,
+ const char *format, ... ) D_FORMAT_PRINTF(4);
+
+void direct_messages_warn ( const char *func,
+ const char *file,
+ int line,
+ const char *format, ... ) D_FORMAT_PRINTF(4);
+
+
+#define D_INFO(x...) do { \
+ if (!(direct_config->quiet & DMT_INFO)) \
+ direct_messages_info( x ); \
+ } while (0)
+
+#define D_ERROR(x...) do { \
+ if (!(direct_config->quiet & DMT_ERROR)) \
+ direct_messages_error( x ); \
+ } while (0)
+
+#define D_DERROR(r,x...) do { \
+ if (!(direct_config->quiet & DMT_ERROR)) \
+ direct_messages_derror( r, x ); \
+ } while (0)
+
+#define D_PERROR(x...) do { \
+ if (!(direct_config->quiet & DMT_ERROR)) \
+ direct_messages_perror( errno, x ); \
+ } while (0)
+
+#define D_DLERROR(x...) do { \
+ if (!(direct_config->quiet & DMT_ERROR)) \
+ direct_messages_dlerror( dlerror(), x ); \
+ } while (0)
+
+
+#define D_ONCE(x...) do { \
+ if (!(direct_config->quiet & DMT_ONCE)) { \
+ static bool first = true; \
+ if (first) { \
+ direct_messages_once( __FUNCTION__, \
+ __FILE__, __LINE__, x ); \
+ first = false; \
+ } \
+ } \
+ } while (0)
+
+#define D_UNIMPLEMENTED() do { \
+ if (!(direct_config->quiet & DMT_UNIMPLEMENTED)) { \
+ static bool first = true; \
+ if (first) { \
+ direct_messages_unimplemented( __FUNCTION__, \
+ __FILE__, __LINE__ ); \
+ first = false; \
+ } \
+ } \
+ } while (0)
+
+#define D_BUG(x...) do { \
+ if (!(direct_config->quiet & DMT_ERROR)) \
+ direct_messages_bug( __FUNCTION__, __FILE__, __LINE__, x ); \
+ } while (0)
+
+#define D_WARN(x...) do { \
+ if (!(direct_config->quiet & DMT_WARNING)) \
+ direct_messages_warn( __FUNCTION__, __FILE__, __LINE__, x );\
+ } while (0)
+
+#define D_OOM() (direct_messages_warn( __FUNCTION__, __FILE__, __LINE__, \
+ "out of memory" ), DR_NOLOCALMEMORY)
+
+
+#else
+ #define D_INFO(x...) do { } while (0)
+ #define D_ERROR(x...) do { } while (0)
+ #define D_DERROR(x...) do { } while (0)
+ #define D_PERROR(x...) do { } while (0)
+ #define D_DLERROR(x...) do { } while (0)
+ #define D_ONCE(x...) do { } while (0)
+ #define D_UNIMPLEMENTED() do { } while (0)
+ #define D_BUG(x...) do { } while (0)
+ #define D_WARN(x...) do { } while (0)
+ #define D_OOM() (printf("out of memory\n"), DR_NOLOCALMEMORY)
+#endif
+
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/modules.c b/Source/DirectFB/lib/direct/modules.c
new file mode 100755
index 0000000..ba3d59b
--- /dev/null
+++ b/Source/DirectFB/lib/direct/modules.c
@@ -0,0 +1,463 @@
+/*
+ (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 <sys/types.h>
+#include <alloca.h>
+#include <dirent.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <direct/conf.h>
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/modules.h>
+
+#ifdef PIC
+#define DYNAMIC_LINKING
+#endif
+
+#ifdef DYNAMIC_LINKING
+#include <dlfcn.h>
+#endif
+
+D_DEBUG_DOMAIN( Direct_Modules, "Direct/Modules", "Module loading and registration" );
+
+/******************************************************************************/
+
+#ifdef DYNAMIC_LINKING
+
+static DirectModuleEntry *lookup_by_name( const DirectModuleDir *directory,
+ const char *name );
+
+static DirectModuleEntry *lookup_by_file( const DirectModuleDir *directory,
+ const char *file );
+
+static void *open_module ( DirectModuleEntry *module );
+static bool load_module ( DirectModuleEntry *module );
+static void unload_module( DirectModuleEntry *module );
+
+#endif
+
+/******************************************************************************/
+
+static int
+suppress_module (const char *name)
+{
+ int i = 0;
+
+ if (!direct_config || !direct_config->disable_module)
+ return 0;
+
+ while (direct_config->disable_module[i]) {
+ if (strcmp (direct_config->disable_module[i], name) == 0) {
+ D_INFO( "Direct/Modules: suppress module '%s'\n", direct_config->disable_module[i] );
+ return 1;
+ }
+
+ i++;
+ }
+
+ return 0;
+}
+
+void
+direct_modules_register( DirectModuleDir *directory,
+ unsigned int abi_version,
+ const char *name,
+ const void *funcs )
+{
+ DirectModuleEntry *entry;
+
+ D_ASSERT( directory != NULL );
+ D_ASSERT( name != NULL );
+ D_ASSERT( funcs != NULL );
+
+ D_DEBUG_AT( Direct_Modules, "Registering '%s' ('%s')...\n", name, directory->path );
+
+#ifdef DYNAMIC_LINKING
+ if ((entry = lookup_by_name( directory, name )) != NULL) {
+ D_MAGIC_ASSERT( entry, DirectModuleEntry );
+
+ entry->loaded = true;
+ entry->funcs = funcs;
+
+ return;
+ }
+#endif
+
+ if (directory->loading) {
+ entry = directory->loading;
+ D_MAGIC_ASSERT( entry, DirectModuleEntry );
+
+ directory->loading = NULL;
+ }
+ else {
+ entry = D_CALLOC( 1, sizeof(DirectModuleEntry) );
+ if (!entry) {
+ D_OOM();
+ return;
+ }
+
+ D_MAGIC_SET( entry, DirectModuleEntry );
+ }
+
+ entry->directory = directory;
+ entry->loaded = true;
+ entry->name = D_STRDUP( name );
+ entry->funcs = funcs;
+
+ entry->disabled = suppress_module( name );
+
+ if (abi_version != directory->abi_version) {
+ D_ERROR( "Direct/Modules: ABI version of '%s' (%d) does not match %d!\n",
+ entry->file ? entry->file : entry->name,
+ abi_version, directory->abi_version );
+
+ entry->disabled = true;
+ }
+
+ direct_list_prepend( &directory->entries, &entry->link );
+
+ D_DEBUG_AT( Direct_Modules, "...registered.\n" );
+}
+
+void
+direct_modules_unregister( DirectModuleDir *directory,
+ const char *name )
+{
+ DirectModuleEntry *entry;
+
+ D_DEBUG_AT( Direct_Modules, "Unregistering '%s' ('%s')...\n", name, directory->path );
+
+#ifdef DYNAMIC_LINKING
+ entry = lookup_by_name( directory, name );
+ if (!entry) {
+ D_ERROR( "Direct/Modules: Unregister failed, could not find '%s' module!\n", name );
+ return;
+ }
+
+ D_MAGIC_ASSERT( entry, DirectModuleEntry );
+
+ D_FREE( entry->name );
+
+ direct_list_remove( &directory->entries, &entry->link );
+
+ D_MAGIC_CLEAR( entry );
+
+ D_FREE( entry );
+#endif
+
+ D_DEBUG_AT( Direct_Modules, "...unregistered.\n" );
+}
+
+int
+direct_modules_explore_directory( DirectModuleDir *directory )
+{
+#ifdef DYNAMIC_LINKING
+ DIR *dir;
+ struct dirent *entry = NULL;
+ struct dirent tmp;
+ int count = 0;
+ const char *pathfront = "";
+ const char *path;
+ char *buf;
+
+ D_ASSERT( directory != NULL );
+ D_ASSERT( directory->path != NULL );
+
+ D_DEBUG_AT( Direct_Modules, "%s( '%s' )\n", __FUNCTION__, directory->path );
+
+ path = directory->path;
+
+ if (path[0] != '/') {
+ pathfront = direct_config->module_dir;
+ if (!pathfront)
+ pathfront = MODULEDIR;
+ }
+
+ buf = alloca( strlen(pathfront) + 1 + strlen(path) + 1 ); /* pre, slash, post, 0 */
+ sprintf( buf, "%s/%s", pathfront, path );
+
+ dir = opendir( buf );
+ if (!dir) {
+ D_DEBUG_AT( Direct_Modules, " -> ERROR opening directory: %s!\n", strerror(errno) );
+ return 0;
+ }
+
+ while (readdir_r( dir, &tmp, &entry ) == 0 && entry) {
+ void *handle;
+ DirectModuleEntry *module;
+ int entry_len = strlen(entry->d_name);
+
+ if (entry_len < 4 ||
+ entry->d_name[entry_len-1] != 'o' ||
+ entry->d_name[entry_len-2] != 's')
+ continue;
+
+ if (lookup_by_file( directory, entry->d_name ))
+ continue;
+
+
+ module = D_CALLOC( 1, sizeof(DirectModuleEntry) );
+ if (!module)
+ continue;
+
+ D_MAGIC_SET( module, DirectModuleEntry );
+
+ module->directory = directory;
+ module->dynamic = true;
+ module->file = D_STRDUP( entry->d_name );
+ if (!module->file) {
+ D_MAGIC_CLEAR( module );
+ D_FREE( module );
+ continue;
+ }
+
+ directory->loading = module;
+
+ if ((handle = open_module( module )) != NULL) {
+ if (!module->loaded) {
+ int len;
+ void (*func)( void );
+
+ D_ERROR( "Direct/Modules: Module '%s' did not register itself after loading! "
+ "Trying default module constructor...\n", entry->d_name );
+
+ len = strlen( entry->d_name );
+
+ entry->d_name[len-3] = 0;
+
+ func = dlsym( handle, entry->d_name + 3 );
+ if (func) {
+ func();
+
+ if (!module->loaded) {
+ D_ERROR( "Direct/Modules: ... even did not register after "
+ "explicitly calling the module constructor!\n" );
+ }
+ }
+ else {
+ D_ERROR( "Direct/Modules: ... default contructor not found!\n" );
+ }
+
+ if (!module->loaded) {
+ module->disabled = true;
+
+ direct_list_prepend( &directory->entries,
+ &module->link );
+ }
+ }
+
+ if (module->disabled) {
+ module->loaded = false;
+
+ /* may call direct_modules_unregister() */
+ dlclose( handle );
+ }
+ else {
+ module->handle = handle;
+
+ count++;
+ }
+ }
+ else {
+ module->disabled = true;
+
+ direct_list_prepend( &directory->entries, &module->link );
+ }
+
+ directory->loading = NULL;
+ }
+
+ closedir( dir );
+
+ return count;
+#else
+ return 0;
+#endif
+}
+
+const void *
+direct_module_ref( DirectModuleEntry *module )
+{
+ D_MAGIC_ASSERT( module, DirectModuleEntry );
+
+ if (module->disabled)
+ return NULL;
+
+#ifdef DYNAMIC_LINKING
+ if (!module->loaded && !load_module( module ))
+ return NULL;
+#endif
+
+ module->refs++;
+
+ return module->funcs;
+}
+
+void
+direct_module_unref( DirectModuleEntry *module )
+{
+ D_MAGIC_ASSERT( module, DirectModuleEntry );
+ D_ASSERT( module->refs > 0 );
+
+ if (--module->refs)
+ return;
+
+#ifdef DYNAMIC_LINKING
+ if (module->dynamic)
+ unload_module( module );
+#endif
+}
+
+/******************************************************************************/
+
+#ifdef DYNAMIC_LINKING
+
+static DirectModuleEntry *
+lookup_by_name( const DirectModuleDir *directory,
+ const char *name )
+{
+ DirectLink *l;
+
+ D_ASSERT( directory != NULL );
+ D_ASSERT( name != NULL );
+
+ direct_list_foreach (l, directory->entries) {
+ DirectModuleEntry *entry = (DirectModuleEntry*) l;
+
+ D_MAGIC_ASSERT( entry, DirectModuleEntry );
+
+ if (!entry->name)
+ continue;
+
+ if (!strcmp( entry->name, name ))
+ return entry;
+ }
+
+ return NULL;
+}
+
+static DirectModuleEntry *
+lookup_by_file( const DirectModuleDir *directory,
+ const char *file )
+{
+ DirectLink *l;
+
+ D_ASSERT( directory != NULL );
+ D_ASSERT( file != NULL );
+
+ direct_list_foreach (l, directory->entries) {
+ DirectModuleEntry *entry = (DirectModuleEntry*) l;
+
+ D_MAGIC_ASSERT( entry, DirectModuleEntry );
+
+ if (!entry->file)
+ continue;
+
+ if (!strcmp( entry->file, file ))
+ return entry;
+ }
+
+ return NULL;
+}
+
+static bool
+load_module( DirectModuleEntry *module )
+{
+ D_MAGIC_ASSERT( module, DirectModuleEntry );
+ D_ASSERT( module->dynamic == true );
+ D_ASSERT( module->file != NULL );
+ D_ASSERT( module->loaded == false );
+ D_ASSERT( module->disabled == false );
+
+ module->handle = open_module( module );
+
+ return module->loaded;
+}
+
+static void
+unload_module( DirectModuleEntry *module )
+{
+ void *handle;
+
+ D_MAGIC_ASSERT( module, DirectModuleEntry );
+ D_ASSERT( module->dynamic == true );
+ D_ASSERT( module->handle != NULL );
+ D_ASSERT( module->loaded == true );
+
+ handle = module->handle;
+
+ module->handle = NULL;
+ module->loaded = false;
+
+ /* may call direct_modules_unregister() */
+ dlclose( handle );
+}
+
+static void *
+open_module( DirectModuleEntry *module )
+{
+ DirectModuleDir *directory;
+ const char *pathfront = "";
+ const char *path;
+ char *buf;
+ void *handle;
+
+ D_MAGIC_ASSERT( module, DirectModuleEntry );
+
+ D_ASSERT( module->file != NULL );
+ D_ASSERT( module->directory != NULL );
+ D_ASSERT( module->directory->path != NULL );
+
+ directory = module->directory;
+ path = directory->path;
+
+ if (path[0] != '/') {
+ pathfront = direct_config->module_dir;
+ if (!pathfront)
+ pathfront = MODULEDIR;
+ }
+
+ buf = alloca( strlen( pathfront ) + 1 + strlen( path ) + 1 + strlen( module->file ) + 1 );
+ sprintf( buf, "%s/%s/%s", pathfront, path, module->file );
+
+ D_DEBUG_AT( Direct_Modules, "Loading '%s'...\n", buf );
+
+ handle = dlopen( buf, RTLD_NOW );
+ if (!handle)
+ D_DLERROR( "Direct/Modules: Unable to dlopen `%s'!\n", buf );
+
+ return handle;
+}
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/modules.h b/Source/DirectFB/lib/direct/modules.h
new file mode 100755
index 0000000..ba11b83
--- /dev/null
+++ b/Source/DirectFB/lib/direct/modules.h
@@ -0,0 +1,95 @@
+/*
+ (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 __DIRECT__MODULES_H__
+#define __DIRECT__MODULES_H__
+
+#include <pthread.h>
+
+#include <direct/types.h>
+#include <direct/list.h>
+#include <direct/util.h>
+
+
+struct __D_DirectModuleEntry {
+ DirectLink link;
+
+ int magic;
+
+ DirectModuleDir *directory;
+
+ bool loaded;
+ bool dynamic;
+ bool disabled;
+
+ char *name;
+ const void *funcs;
+
+ int refs;
+ char *file;
+ void *handle;
+};
+
+struct __D_DirectModuleDir {
+ pthread_mutex_t lock;
+
+ const char *path;
+ unsigned int abi_version;
+
+ DirectLink *entries;
+
+ DirectModuleEntry *loading;
+};
+
+#define DECLARE_MODULE_DIRECTORY(d) \
+ extern DirectModuleDir d
+
+#define DEFINE_MODULE_DIRECTORY(d,p,n) \
+ DirectModuleDir d = { \
+ .lock = PTHREAD_MUTEX_INITIALIZER, \
+ .path = p, \
+ .abi_version = n, \
+ .entries = NULL, \
+ .loading = NULL, \
+ }
+
+int direct_modules_explore_directory( DirectModuleDir *directory );
+
+void direct_modules_register( DirectModuleDir *directory,
+ unsigned int abi_version,
+ const char *name,
+ const void *funcs );
+
+void direct_modules_unregister( DirectModuleDir *directory,
+ const char *name );
+
+const void *direct_module_ref ( DirectModuleEntry *module );
+void direct_module_unref( DirectModuleEntry *module );
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/ppc_asm.h b/Source/DirectFB/lib/direct/ppc_asm.h
new file mode 100755
index 0000000..c35192b
--- /dev/null
+++ b/Source/DirectFB/lib/direct/ppc_asm.h
@@ -0,0 +1,115 @@
+/* Condition Register Bit Fields */
+
+#define cr0 0
+#define cr1 1
+#define cr2 2
+#define cr3 3
+#define cr4 4
+#define cr5 5
+#define cr6 6
+#define cr7 7
+
+
+/* General Purpose Registers (GPRs) */
+
+#define r0 0
+#define r1 1
+#define r2 2
+#define r3 3
+#define r4 4
+#define r5 5
+#define r6 6
+#define r7 7
+#define r8 8
+#define r9 9
+#define r10 10
+#define r11 11
+#define r12 12
+#define r13 13
+#define r14 14
+#define r15 15
+#define r16 16
+#define r17 17
+#define r18 18
+#define r19 19
+#define r20 20
+#define r21 21
+#define r22 22
+#define r23 23
+#define r24 24
+#define r25 25
+#define r26 26
+#define r27 27
+#define r28 28
+#define r29 29
+#define r30 30
+#define r31 31
+
+
+/* Floating Point Registers (FPRs) */
+
+#define fr0 0
+#define fr1 1
+#define fr2 2
+#define fr3 3
+#define fr4 4
+#define fr5 5
+#define fr6 6
+#define fr7 7
+#define fr8 8
+#define fr9 9
+#define fr10 10
+#define fr11 11
+#define fr12 12
+#define fr13 13
+#define fr14 14
+#define fr15 15
+#define fr16 16
+#define fr17 17
+#define fr18 18
+#define fr19 19
+#define fr20 20
+#define fr21 21
+#define fr22 22
+#define fr23 23
+#define fr24 24
+#define fr25 25
+#define fr26 26
+#define fr27 27
+#define fr28 28
+#define fr29 29
+#define fr30 30
+#define fr31 31
+
+#define vr0 0
+#define vr1 1
+#define vr2 2
+#define vr3 3
+#define vr4 4
+#define vr5 5
+#define vr6 6
+#define vr7 7
+#define vr8 8
+#define vr9 9
+#define vr10 10
+#define vr11 11
+#define vr12 12
+#define vr13 13
+#define vr14 14
+#define vr15 15
+#define vr16 16
+#define vr17 17
+#define vr18 18
+#define vr19 19
+#define vr20 20
+#define vr21 21
+#define vr22 22
+#define vr23 23
+#define vr24 24
+#define vr25 25
+#define vr26 26
+#define vr27 27
+#define vr28 28
+#define vr29 29
+#define vr30 30
+#define vr31 31
diff --git a/Source/DirectFB/lib/direct/ppcasm_memcpy.S b/Source/DirectFB/lib/direct/ppcasm_memcpy.S
new file mode 100755
index 0000000..04b695b
--- /dev/null
+++ b/Source/DirectFB/lib/direct/ppcasm_memcpy.S
@@ -0,0 +1,77 @@
+/*
+ * String handling functions for PowerPC.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ *
+ * In a mail from Paul on 23.10.2006 05:47:
+ *
+ * You may put an LGPL permission statement on that code, replacing the
+ * GPL permission statement. From a technical point of view, I'm not
+ * sure that the code in ppcasm_memcpy_cachable.S is the best thing to
+ * use in userspace, though; for one thing, it has a cache line size
+ * assumption encoded into it. Why don't you just use the glibc memcpy?
+ * It's pretty well optimized these days, AFAIK.
+ *
+ * Paul.
+ *
+ *
+ * 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 "ppc_asm.h"
+
+ .globl direct_ppcasm_memcpy
+direct_ppcasm_memcpy:
+ srwi. r7,r5,3
+ addi r6,r3,-4
+ addi r4,r4,-4
+ beq 2f /* if less than 8 bytes to do */
+ andi. r0,r6,3 /* get dest word aligned */
+ mtctr r7
+ bne 5f
+1: lwz r7,4(r4)
+ lwzu r8,8(r4)
+ stw r7,4(r6)
+ stwu r8,8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,4(r4)
+ addi r5,r5,-4
+ stwu r0,4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r4,r4,3
+ addi r6,r6,3
+4: lbzu r0,1(r4)
+ stbu r0,1(r6)
+ bdnz 4b
+ blr
+5: subfic r0,r0,4
+ mtctr r0
+6: lbz r7,4(r4)
+ addi r4,r4,1
+ stb r7,4(r6)
+ addi r6,r6,1
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
diff --git a/Source/DirectFB/lib/direct/ppcasm_memcpy.h b/Source/DirectFB/lib/direct/ppcasm_memcpy.h
new file mode 100755
index 0000000..4e7edaf
--- /dev/null
+++ b/Source/DirectFB/lib/direct/ppcasm_memcpy.h
@@ -0,0 +1,7 @@
+#ifndef __DIRECT__PPCASM_MEMCPY_H__
+#define __DIRECT__PPCASM_MEMCPY_H__
+
+void *direct_ppcasm_cacheable_memcpy( void *dest, const void *src, size_t n);
+void *direct_ppcasm_memcpy ( void *dest, const void *src, size_t n);
+
+#endif
diff --git a/Source/DirectFB/lib/direct/ppcasm_memcpy_cachable.S b/Source/DirectFB/lib/direct/ppcasm_memcpy_cachable.S
new file mode 100755
index 0000000..920dea2
--- /dev/null
+++ b/Source/DirectFB/lib/direct/ppcasm_memcpy_cachable.S
@@ -0,0 +1,180 @@
+/*
+ * String handling functions for PowerPC.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ *
+ * In a mail from Paul on 23.10.2006 05:47:
+ *
+ * You may put an LGPL permission statement on that code, replacing the
+ * GPL permission statement. From a technical point of view, I'm not
+ * sure that the code in ppcasm_memcpy_cachable.S is the best thing to
+ * use in userspace, though; for one thing, it has a cache line size
+ * assumption encoded into it. Why don't you just use the glibc memcpy?
+ * It's pretty well optimized these days, AFAIK.
+ *
+ * Paul.
+ *
+ *
+ * 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 __ASSEMBLY__
+
+#include <linux/config.h>
+
+#if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
+#define L1_CACHE_LINE_SIZE 16
+#define LG_L1_CACHE_LINE_SIZE 4
+#elif defined(CONFIG_PPC64BRIDGE)
+#define L1_CACHE_LINE_SIZE 128
+#define LG_L1_CACHE_LINE_SIZE 7
+#else
+#define L1_CACHE_LINE_SIZE 32
+#define LG_L1_CACHE_LINE_SIZE 5
+#endif
+
+#include "ppc_asm.h"
+
+#define COPY_16_BYTES \
+ lwz r7,4(r4); \
+ lwz r8,8(r4); \
+ lwz r9,12(r4); \
+ lwzu r10,16(r4); \
+ stw r7,4(r6); \
+ stw r8,8(r6); \
+ stw r9,12(r6); \
+ stwu r10,16(r6)
+
+#define COPY_16_BYTES_WITHEX(n) \
+8 ## n ## 0: \
+ lwz r7,4(r4); \
+8 ## n ## 1: \
+ lwz r8,8(r4); \
+8 ## n ## 2: \
+ lwz r9,12(r4); \
+8 ## n ## 3: \
+ lwzu r10,16(r4); \
+8 ## n ## 4: \
+ stw r7,4(r6); \
+8 ## n ## 5: \
+ stw r8,8(r6); \
+8 ## n ## 6: \
+ stw r9,12(r6); \
+8 ## n ## 7: \
+ stwu r10,16(r6)
+
+#define COPY_16_BYTES_EXCODE(n) \
+9 ## n ## 0: \
+ addi r5,r5,-(16 * n); \
+ b 104f; \
+9 ## n ## 1: \
+ addi r5,r5,-(16 * n); \
+ b 105f; \
+.section __ex_table,"a"; \
+ .align 2; \
+ .long 8 ## n ## 0b,9 ## n ## 0b; \
+ .long 8 ## n ## 1b,9 ## n ## 0b; \
+ .long 8 ## n ## 2b,9 ## n ## 0b; \
+ .long 8 ## n ## 3b,9 ## n ## 0b; \
+ .long 8 ## n ## 4b,9 ## n ## 1b; \
+ .long 8 ## n ## 5b,9 ## n ## 1b; \
+ .long 8 ## n ## 6b,9 ## n ## 1b; \
+ .long 8 ## n ## 7b,9 ## n ## 1b; \
+ .text
+
+ .text
+
+
+CACHELINE_MASK = (L1_CACHE_LINE_SIZE - 1)
+
+ .global direct_ppcasm_cacheable_memcpy
+direct_ppcasm_cacheable_memcpy:
+#if 0 /* this part causes "error loading shared library: unexpected reloc type
+ 0x0b (???) */
+ add r7,r3,r5 /* test if the src & dst overlap */
+ add r8,r4,r5
+ cmplw 0,r4,r7
+ cmplw 1,r3,r8
+ crand 0,0,4 /* cr0.lt &= cr1.lt */
+ blt ppcasm_memcpy /* if regions overlap */
+#endif
+ addi r4,r4,-4
+ addi r6,r3,-4
+ neg r0,r3
+ andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */
+ beq 58f
+
+ cmplw 0,r5,r0 /* is this more than total to do? */
+ blt 63f /* if not much to do */
+ andi. r8,r0,3 /* get it word-aligned first */
+ subf r5,r0,r5
+ mtctr r8
+ beq+ 61f
+70: lbz r9,4(r4) /* do some bytes */
+ stb r9,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 70b
+61: srwi. r0,r0,2
+ mtctr r0
+ beq 58f
+72: lwzu r9,4(r4) /* do some words */
+ stwu r9,4(r6)
+ bdnz 72b
+
+58: srwi. r0,r5,LG_L1_CACHE_LINE_SIZE /* complete cachelines */
+ clrlwi r5,r5,32-LG_L1_CACHE_LINE_SIZE
+ li r11,4
+ mtctr r0
+ beq 63f
+53:
+#if !defined(CONFIG_8xx)
+ dcbz r11,r6
+#endif
+ COPY_16_BYTES
+#if L1_CACHE_LINE_SIZE >= 32
+ COPY_16_BYTES
+#if L1_CACHE_LINE_SIZE >= 64
+ COPY_16_BYTES
+ COPY_16_BYTES
+#if L1_CACHE_LINE_SIZE >= 128
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+#endif
+#endif
+#endif
+ bdnz 53b
+
+63: srwi. r0,r5,2
+ mtctr r0
+ beq 64f
+30: lwzu r0,4(r4)
+ stwu r0,4(r6)
+ bdnz 30b
+
+64: andi. r0,r5,3
+ mtctr r0
+ beq+ 65f
+40: lbz r0,4(r4)
+ stb r0,4(r6)
+ addi r4,r4,1
+ addi r6,r6,1
+ bdnz 40b
+65: blr
+
diff --git a/Source/DirectFB/lib/direct/serial.h b/Source/DirectFB/lib/direct/serial.h
new file mode 100755
index 0000000..d201708
--- /dev/null
+++ b/Source/DirectFB/lib/direct/serial.h
@@ -0,0 +1,118 @@
+/*
+ (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 __DIRECT__SERIAL_H__
+#define __DIRECT__SERIAL_H__
+
+#include <direct/types.h>
+#include <direct/debug.h>
+
+struct __D_DirectSerial {
+ int magic;
+
+ u32 value;
+ u32 overflow;
+};
+
+static __inline__ void
+direct_serial_init( DirectSerial *serial )
+{
+ D_ASSERT( serial != NULL );
+
+ serial->value = 0;
+ serial->overflow = 0;
+
+ D_MAGIC_SET( serial, DirectSerial );
+}
+
+static __inline__ void
+direct_serial_deinit( DirectSerial *serial )
+{
+ D_MAGIC_CLEAR( serial );
+}
+
+static __inline__ void
+direct_serial_increase( DirectSerial *serial )
+{
+ D_MAGIC_ASSERT( serial, DirectSerial );
+
+ if (! ++serial->value)
+ serial->overflow++;
+}
+
+static __inline__ void
+direct_serial_copy( DirectSerial *serial, const DirectSerial *source )
+{
+ D_MAGIC_ASSERT( serial, DirectSerial );
+ D_MAGIC_ASSERT( source, DirectSerial );
+
+ serial->value = source->value;
+ serial->overflow = source->overflow;
+}
+
+static __inline__ bool
+direct_serial_check( DirectSerial *serial, const DirectSerial *source )
+{
+ D_MAGIC_ASSERT( serial, DirectSerial );
+ D_MAGIC_ASSERT( source, DirectSerial );
+
+ if (serial->overflow < source->overflow)
+ return false;
+ else if (serial->overflow == source->overflow && serial->value < source->value)
+ return false;
+
+ D_ASSUME( serial->value == source->value );
+
+ return true;
+}
+
+static __inline__ bool
+direct_serial_update( DirectSerial *serial, const DirectSerial *source )
+{
+ D_MAGIC_ASSERT( serial, DirectSerial );
+ D_MAGIC_ASSERT( source, DirectSerial );
+
+ if (serial->overflow < source->overflow) {
+ serial->overflow = source->overflow;
+ serial->value = source->value;
+
+ return true;
+ }
+ else if (serial->overflow == source->overflow && serial->value < source->value) {
+ serial->value = source->value;
+
+ return true;
+ }
+
+ D_ASSUME( serial->value == source->value );
+
+ return false;
+}
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/signals.c b/Source/DirectFB/lib/direct/signals.c
new file mode 100755
index 0000000..5b0310a
--- /dev/null
+++ b/Source/DirectFB/lib/direct/signals.c
@@ -0,0 +1,480 @@
+/*
+ (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 <pthread.h>
+
+#include <signal.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <direct/clock.h>
+#include <direct/conf.h>
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/signals.h>
+#include <direct/system.h>
+#include <direct/trace.h>
+#include <direct/util.h>
+
+D_DEBUG_DOMAIN( Direct_Signals, "Direct/Signals", "Signal handling" );
+
+
+struct __D_DirectSignalHandler {
+ DirectLink link;
+
+ int magic;
+
+ int num;
+ DirectSignalHandlerFunc func;
+ void *ctx;
+};
+
+/**************************************************************************************************/
+
+typedef struct {
+ int signum;
+ struct sigaction old_action;
+} SigHandled;
+
+static int sigs_to_handle[] = { /*SIGALRM,*/ SIGHUP, SIGINT, /*SIGPIPE,*/ /*SIGPOLL,*/
+ SIGTERM, /*SIGUSR1, SIGUSR2,*/ /*SIGVTALRM,*/
+ /*SIGSTKFLT,*/ SIGABRT, SIGFPE, SIGILL, SIGQUIT,
+ SIGSEGV, SIGTRAP, /*SIGSYS, SIGEMT,*/ SIGBUS,
+ SIGXCPU, SIGXFSZ };
+
+#define NUM_SIGS_TO_HANDLE ((int)D_ARRAY_SIZE( sigs_to_handle ))
+
+static SigHandled sigs_handled[NUM_SIGS_TO_HANDLE];
+
+static DirectLink *handlers = NULL;
+static pthread_mutex_t handlers_lock;
+
+/**************************************************************************************************/
+
+static void install_handlers( void );
+static void remove_handlers( void );
+
+/**************************************************************************************************/
+
+DirectResult
+direct_signals_initialize( void )
+{
+ D_DEBUG_AT( Direct_Signals, "Initializing...\n" );
+
+ direct_util_recursive_pthread_mutex_init( &handlers_lock );
+
+ install_handlers();
+
+ return DR_OK;
+}
+
+DirectResult
+direct_signals_shutdown( void )
+{
+ D_DEBUG_AT( Direct_Signals, "Shutting down...\n" );
+
+ remove_handlers();
+
+ pthread_mutex_destroy( &handlers_lock );
+
+ return DR_OK;
+}
+
+void
+direct_signals_block_all( void )
+{
+ sigset_t signals;
+
+ D_DEBUG_AT( Direct_Signals, "Blocking all signals from now on!\n" );
+
+ sigfillset( &signals );
+
+ if (pthread_sigmask( SIG_BLOCK, &signals, NULL ))
+ D_PERROR( "Direct/Signals: Setting signal mask failed!\n" );
+}
+
+DirectResult
+direct_signal_handler_add( int num,
+ DirectSignalHandlerFunc func,
+ void *ctx,
+ DirectSignalHandler **ret_handler )
+{
+ DirectSignalHandler *handler;
+
+ D_ASSERT( func != NULL );
+ D_ASSERT( ret_handler != NULL );
+
+ D_DEBUG_AT( Direct_Signals,
+ "Adding handler %p for signal %d with context %p...\n", func, num, ctx );
+
+ handler = D_CALLOC( 1, sizeof(DirectSignalHandler) );
+ if (!handler) {
+ D_WARN( "out of memory" );
+ return DR_NOLOCALMEMORY;
+ }
+
+ handler->num = num;
+ handler->func = func;
+ handler->ctx = ctx;
+
+ D_MAGIC_SET( handler, DirectSignalHandler );
+
+ pthread_mutex_lock( &handlers_lock );
+ direct_list_append( &handlers, &handler->link );
+ pthread_mutex_unlock( &handlers_lock );
+
+ *ret_handler = handler;
+
+ return DR_OK;
+}
+
+DirectResult
+direct_signal_handler_remove( DirectSignalHandler *handler )
+{
+ D_MAGIC_ASSERT( handler, DirectSignalHandler );
+
+ D_DEBUG_AT( Direct_Signals, "Removing handler %p for signal %d with context %p...\n",
+ handler->func, handler->num, handler->ctx );
+
+ pthread_mutex_lock( &handlers_lock );
+ direct_list_remove( &handlers, &handler->link );
+ pthread_mutex_unlock( &handlers_lock );
+
+ D_MAGIC_CLEAR( handler );
+
+ D_FREE( handler );
+
+ return DR_OK;
+}
+
+/**************************************************************************************************/
+
+static bool
+show_segv( const siginfo_t *info )
+{
+ switch (info->si_code) {
+#ifdef SEGV_MAPERR
+ case SEGV_MAPERR:
+ direct_log_printf( NULL, " (at %p, invalid address) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef SEGV_ACCERR
+ case SEGV_ACCERR:
+ direct_log_printf( NULL, " (at %p, invalid permissions) <--\n", info->si_addr );
+ return true;
+#endif
+ }
+ return false;
+}
+
+static bool
+show_bus( const siginfo_t *info )
+{
+ switch (info->si_code) {
+#ifdef BUG_ADRALN
+ case BUS_ADRALN:
+ direct_log_printf( NULL, " (at %p, invalid address alignment) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef BUS_ADRERR
+ case BUS_ADRERR:
+ direct_log_printf( NULL, " (at %p, non-existent physical address) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef BUS_OBJERR
+ case BUS_OBJERR:
+ direct_log_printf( NULL, " (at %p, object specific hardware error) <--\n", info->si_addr );
+ return true;
+#endif
+ }
+
+ return false;
+}
+
+static bool
+show_ill( const siginfo_t *info )
+{
+ switch (info->si_code) {
+#ifdef ILL_ILLOPC
+ case ILL_ILLOPC:
+ direct_log_printf( NULL, " (at %p, illegal opcode) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef ILL_ILLOPN
+ case ILL_ILLOPN:
+ direct_log_printf( NULL, " (at %p, illegal operand) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef ILL_ILLADR
+ case ILL_ILLADR:
+ direct_log_printf( NULL, " (at %p, illegal addressing mode) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef ILL_ILLTRP
+ case ILL_ILLTRP:
+ direct_log_printf( NULL, " (at %p, illegal trap) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef ILL_PRVOPC
+ case ILL_PRVOPC:
+ direct_log_printf( NULL, " (at %p, privileged opcode) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef ILL_PRVREG
+ case ILL_PRVREG:
+ direct_log_printf( NULL, " (at %p, privileged register) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef ILL_COPROC
+ case ILL_COPROC:
+ direct_log_printf( NULL, " (at %p, coprocessor error) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef ILL_BADSTK
+ case ILL_BADSTK:
+ direct_log_printf( NULL, " (at %p, internal stack error) <--\n", info->si_addr );
+ return true;
+#endif
+ }
+
+ return false;
+}
+
+static bool
+show_fpe( const siginfo_t *info )
+{
+ switch (info->si_code) {
+#ifdef FPE_INTDIV
+ case FPE_INTDIV:
+ direct_log_printf( NULL, " (at %p, integer divide by zero) <--\n", info->si_addr );
+ return true;
+#endif
+#ifdef FPE_FLTDIV
+ case FPE_FLTDIV:
+ direct_log_printf( NULL, " (at %p, floating point divide by zero) <--\n", info->si_addr );
+ return true;
+#endif
+ }
+
+ direct_log_printf( NULL, " (at %p) <--\n", info->si_addr );
+
+ return true;
+}
+
+static bool
+show_any( const siginfo_t *info )
+{
+ switch (info->si_code) {
+#ifdef SI_USER
+ case SI_USER:
+ direct_log_printf( NULL, " (sent by pid %d, uid %d) <--\n", info->si_pid, info->si_uid );
+ return true;
+#endif
+#ifdef SI_KERNEL
+ case SI_KERNEL:
+ direct_log_printf( NULL, " (sent by the kernel) <--\n" );
+ return true;
+#endif
+ }
+ return false;
+}
+
+static void
+#ifdef SA_SIGINFO
+signal_handler( int num, siginfo_t *info, void *foo )
+#else
+signal_handler( int num )
+#endif
+{
+ DirectLink *l, *n;
+ void *addr = NULL;
+ int pid = direct_gettid();
+ long long millis = direct_clock_get_millis();
+
+ fflush(stdout);
+ fflush(stderr);
+
+ direct_log_printf( NULL, "(!) [%5d: %4lld.%03lld] --> Caught signal %d",
+ pid, millis/1000, millis%1000, num );
+
+#ifdef SA_SIGINFO
+ if (info && info > (siginfo_t*) 0x100) {
+ bool shown = false;
+
+ if (info->si_code > 0 && info->si_code < 0x80) {
+ addr = info->si_addr;
+
+ switch (num) {
+ case SIGSEGV:
+ shown = show_segv( info );
+ break;
+
+ case SIGBUS:
+ shown = show_bus( info );
+ break;
+
+ case SIGILL:
+ shown = show_ill( info );
+ break;
+
+ case SIGFPE:
+ shown = show_fpe( info );
+ break;
+
+ default:
+ direct_log_printf( NULL, " <--\n" );
+ addr = NULL;
+ shown = true;
+ break;
+ }
+ }
+ else
+ shown = show_any( info );
+
+ if (!shown)
+ direct_log_printf( NULL, " (unknown origin) <--\n" );
+ }
+ else
+#endif
+ direct_log_printf( NULL, ", no siginfo available <--\n" );
+
+ direct_trace_print_stacks();
+
+ /* Loop through all handlers. */
+ pthread_mutex_lock( &handlers_lock );
+
+ direct_list_foreach_safe (l, n, handlers) {
+ DirectSignalHandler *handler = (DirectSignalHandler*) l;
+
+ if (handler->num != num && handler->num != DIRECT_SIGNAL_ANY)
+ continue;
+
+ switch (handler->func( num, addr, handler->ctx )) {
+ case DSHR_OK:
+ break;
+
+ case DSHR_REMOVE:
+ direct_list_remove( &handlers, &handler->link );
+ D_MAGIC_CLEAR( handler );
+ D_FREE( handler );
+ break;
+
+ case DSHR_RESUME:
+ millis = direct_clock_get_millis();
+
+ direct_log_printf( NULL, "(!) [%5d: %4lld.%03lld] -> cured!\n",
+ pid, millis / 1000, millis % 1000 );
+ pthread_mutex_unlock( &handlers_lock );
+ return;
+
+ default:
+ D_BUG( "unknown result" );
+ break;
+ }
+ }
+
+ pthread_mutex_unlock( &handlers_lock );
+
+
+// sleep(100);
+
+
+ remove_handlers();
+
+ raise( num );
+
+ abort();
+
+ exit( -num );
+}
+
+/**************************************************************************************************/
+
+static void
+install_handlers( void )
+{
+ int i;
+
+ for (i=0; i<NUM_SIGS_TO_HANDLE; i++) {
+ sigs_handled[i].signum = -1;
+
+ if (direct_config->sighandler && !sigismember( &direct_config->dont_catch,
+ sigs_to_handle[i] ))
+ {
+ struct sigaction action;
+ int signum = sigs_to_handle[i];
+
+#ifdef SA_SIGINFO
+ action.sa_sigaction = signal_handler;
+ action.sa_flags = SA_SIGINFO;
+#else
+ action.sa_handler = signal_handler;
+ action.sa_flags = 0;
+#endif
+
+ if (signum != SIGSEGV)
+ action.sa_flags |= SA_NODEFER;
+
+ sigemptyset( &action.sa_mask );
+
+ if (sigaction( signum, &action, &sigs_handled[i].old_action )) {
+ D_PERROR( "Direct/Signals: "
+ "Unable to install signal handler for signal %d!\n", signum );
+ continue;
+ }
+
+ sigs_handled[i].signum = signum;
+ }
+ }
+}
+
+static void
+remove_handlers( void )
+{
+ int i;
+
+ for (i=0; i<NUM_SIGS_TO_HANDLE; i++) {
+ if (sigs_handled[i].signum != -1) {
+ int signum = sigs_handled[i].signum;
+
+ if (sigaction( signum, &sigs_handled[i].old_action, NULL )) {
+ D_PERROR( "Direct/Signals: "
+ "Unable to restore previous handler for signal %d!\n", signum );
+ }
+
+ sigs_handled[i].signum = -1;
+ }
+ }
+}
+
diff --git a/Source/DirectFB/lib/direct/signals.h b/Source/DirectFB/lib/direct/signals.h
new file mode 100755
index 0000000..8765fe1
--- /dev/null
+++ b/Source/DirectFB/lib/direct/signals.h
@@ -0,0 +1,70 @@
+/*
+ (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 __DIRECT__SIGNALS_H__
+#define __DIRECT__SIGNALS_H__
+
+#include <direct/types.h>
+
+
+typedef enum {
+ DSHR_OK,
+ DSHR_REMOVE,
+ DSHR_RESUME
+} DirectSignalHandlerResult;
+
+typedef DirectSignalHandlerResult (*DirectSignalHandlerFunc)( int num,
+ void *addr,
+ void *ctx );
+
+
+DirectResult direct_signals_initialize( void );
+DirectResult direct_signals_shutdown( void );
+
+/*
+ * Modifies the current thread's signal mask to block everything.
+ * Should be called by input threads once to avoid killing themselves
+ * in the signal handler by deinitializing all input drivers.
+ */
+void direct_signals_block_all( void );
+
+/*
+ * Signal number to use when registering a handler for any interrupt.
+ */
+#define DIRECT_SIGNAL_ANY -1
+
+
+DirectResult direct_signal_handler_add ( int num,
+ DirectSignalHandlerFunc func,
+ void *ctx,
+ DirectSignalHandler **ret_handler );
+
+DirectResult direct_signal_handler_remove( DirectSignalHandler *handler );
+
+
+#endif
diff --git a/Source/DirectFB/lib/direct/stream.c b/Source/DirectFB/lib/direct/stream.c
new file mode 100755
index 0000000..1e531d9
--- /dev/null
+++ b/Source/DirectFB/lib/direct/stream.c
@@ -0,0 +1,2286 @@
+/*
+ (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 <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <direct/build.h>
+#include <direct/types.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/debug.h>
+#include <direct/util.h>
+
+#include <direct/stream.h>
+
+
+struct __D_DirectStream {
+ int magic;
+ int ref;
+
+ int fd;
+ unsigned int offset;
+ int length;
+
+ char *mime;
+
+ /* cache for piped streams */
+ void *cache;
+ unsigned int cache_size;
+
+#if DIRECT_BUILD_NETWORK
+ /* remote streams data */
+ struct {
+ int sd;
+
+ char *host;
+ int port;
+ struct addrinfo *addr;
+
+ char *user;
+ char *pass;
+ char *auth;
+
+ char *path;
+
+ int redirects;
+
+ void *data;
+
+ bool real_rtsp;
+ bool real_pack;
+ } remote;
+#endif
+
+ DirectResult (*wait) ( DirectStream *stream,
+ unsigned int length,
+ struct timeval *tv );
+ DirectResult (*peek) ( DirectStream *stream,
+ unsigned int length,
+ int offset,
+ void *buf,
+ unsigned int *read_out );
+ DirectResult (*read) ( DirectStream *stream,
+ unsigned int length,
+ void *buf,
+ unsigned int *read_out );
+ DirectResult (*seek) ( DirectStream *stream,
+ unsigned int offset );
+};
+
+
+static void direct_stream_close( DirectStream *stream );
+
+
+#if DIRECT_BUILD_NETWORK
+D_DEBUG_DOMAIN( Direct_Stream, "Direct/Stream", "Stream wrapper" );
+#endif
+
+/************************** Begin Network Support ***************************/
+
+#if DIRECT_BUILD_NETWORK
+
+#define NET_TIMEOUT 15
+#define HTTP_PORT 80
+#define FTP_PORT 21
+#define RTSP_PORT 554
+#define HTTP_MAX_REDIRECTS 15
+
+static DirectResult http_open( DirectStream *stream, const char *filename );
+static DirectResult ftp_open ( DirectStream *stream, const char *filename );
+static DirectResult rtsp_open( DirectStream *stream, const char *filename );
+
+
+static inline char* trim( char *s )
+{
+ char *e;
+
+#define space( c ) ((c) == ' ' || (c) == '\t' || \
+ (c) == '\r' || (c) == '\n' || \
+ (c) == '"' || (c) == '\'')
+
+ for (; space(*s); s++);
+
+ e = s + strlen(s) - 1;
+ for (; e > s && space(*e); *e-- = '\0');
+
+#undef space
+
+ return s;
+}
+
+static void
+parse_url( const char *url, char **ret_host, int *ret_port,
+ char **ret_user, char **ret_pass, char **ret_path )
+{
+ char *host = NULL;
+ int port = 0;
+ char *user = NULL;
+ char *pass = NULL;
+ char *path;
+ char *tmp;
+
+ tmp = strchr( url, '/' );
+ if (tmp) {
+ host = alloca( tmp - url + 1 );
+ memcpy( host, url, tmp - url );
+ host[tmp-url] = '\0';
+ path = tmp;
+ } else {
+ host = alloca( strlen( url ) + 1 );
+ memcpy( host, url, strlen( url ) + 1 );
+ path = "/";
+ }
+
+ tmp = strrchr( host, '@' );
+ if (tmp) {
+ *tmp = '\0';
+ pass = strchr( host, ':' );
+ if (pass) {
+ *pass = '\0';
+ pass++;
+ }
+ user = host;
+ host = tmp + 1;
+ }
+
+ tmp = strchr( host, ':' );
+ if (tmp) {
+ port = strtol( tmp+1, NULL, 10 );
+ *tmp = '\0';
+ }
+
+ /* IPv6 variant (host within brackets) */
+ if (*host == '[') {
+ host++;
+ tmp = strchr( host, ']' );
+ if (tmp)
+ *tmp = '\0';
+ }
+
+ if (ret_host)
+ *ret_host = D_STRDUP( host );
+
+ if (ret_port && port)
+ *ret_port = port;
+
+ if (ret_user && user)
+ *ret_user = D_STRDUP( user );
+
+ if (ret_pass && pass)
+ *ret_pass = D_STRDUP( pass );
+
+ if (ret_path)
+ *ret_path = D_STRDUP( path );
+}
+
+/*****************************************************************************/
+
+static int
+net_response( DirectStream *stream, char *buf, size_t size )
+{
+ fd_set set;
+ struct timeval tv;
+ int i;
+
+ FD_ZERO( &set );
+ FD_SET( stream->remote.sd, &set );
+
+ for (i = 0; i < size-1; i++) {
+ tv.tv_sec = NET_TIMEOUT;
+ tv.tv_usec = 0;
+ select( stream->remote.sd+1, &set, NULL, NULL, &tv );
+
+ if (recv( stream->remote.sd, buf+i, 1, 0 ) != 1)
+ break;
+
+ if (buf[i] == '\n') {
+ if (i > 0 && buf[i-1] == '\r')
+ i--;
+ break;
+ }
+ }
+
+ buf[i] = '\0';
+
+ D_DEBUG_AT( Direct_Stream, "got [%s].\n", buf );
+
+ return i;
+}
+
+static int
+net_command( DirectStream *stream, char *buf, size_t size )
+{
+ fd_set s;
+ struct timeval t;
+ int status;
+ int version;
+ char space;
+
+ FD_ZERO( &s );
+ FD_SET( stream->remote.sd, &s );
+
+ t.tv_sec = NET_TIMEOUT;
+ t.tv_usec = 0;
+
+ switch (select( stream->remote.sd+1, NULL, &s, NULL, &t )) {
+ case 0:
+ D_DEBUG_AT( Direct_Stream, "Timeout!\n" );
+ case -1:
+ return -1;
+ }
+
+ send( stream->remote.sd, buf, strlen(buf), 0 );
+ send( stream->remote.sd, "\r\n", 2, 0 );
+
+ D_DEBUG_AT( Direct_Stream, "sent [%s].\n", buf );
+
+ while (net_response( stream, buf, size ) > 0) {
+ status = 0;
+ if (sscanf( buf, "HTTP/1.%d %3d", &version, &status ) == 2 ||
+ sscanf( buf, "RTSP/1.%d %3d", &version, &status ) == 2 ||
+ sscanf( buf, "ICY %3d", &status ) == 1 ||
+ sscanf( buf, "%3d%[ ]", &status, &space ) == 2)
+ return status;
+ }
+
+ return 0;
+}
+
+static DirectResult
+net_wait( DirectStream *stream,
+ unsigned int length,
+ struct timeval *tv )
+{
+ fd_set s;
+
+ if (stream->cache_size >= length)
+ return DR_OK;
+
+ if (stream->fd == -1)
+ return DR_EOF;
+
+ FD_ZERO( &s );
+ FD_SET( stream->fd, &s );
+
+ switch (select( stream->fd+1, &s, NULL, NULL, tv )) {
+ case 0:
+ if (!tv && !stream->cache_size)
+ return DR_EOF;
+ return DR_TIMEOUT;
+ case -1:
+ return errno2result( errno );
+ }
+
+ return DR_OK;
+}
+
+static DirectResult
+net_peek( DirectStream *stream,
+ unsigned int length,
+ int offset,
+ void *buf,
+ unsigned int *read_out )
+{
+ char *tmp;
+ int size;
+
+ if (offset < 0)
+ return DR_UNSUPPORTED;
+
+ tmp = alloca( length + offset );
+
+ size = recv( stream->fd, tmp, length+offset, MSG_PEEK );
+ switch (size) {
+ case 0:
+ return DR_EOF;
+ case -1:
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ return DR_BUFFEREMPTY;
+ return errno2result( errno );
+ default:
+ if (size < offset)
+ return DR_BUFFEREMPTY;
+ size -= offset;
+ break;
+ }
+
+ direct_memcpy( buf, tmp+offset, size );
+
+ if (read_out)
+ *read_out = size;
+
+ return DR_OK;
+}
+
+static DirectResult
+net_read( DirectStream *stream,
+ unsigned int length,
+ void *buf,
+ unsigned int *read_out )
+{
+ int size;
+
+ size = recv( stream->fd, buf, length, 0 );
+ switch (size) {
+ case 0:
+ return DR_EOF;
+ case -1:
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ return DR_BUFFEREMPTY;
+ return errno2result( errno );
+ }
+
+ stream->offset += size;
+
+ if (read_out)
+ *read_out = size;
+
+ return DR_OK;
+}
+
+static DirectResult
+net_connect( struct addrinfo *addr, int sock, int proto, int *ret_fd )
+{
+ DirectResult ret = DR_OK;
+ int fd = -1;
+ struct addrinfo *tmp;
+
+ D_ASSERT( addr != NULL );
+ D_ASSERT( ret_fd != NULL );
+
+ for (tmp = addr; tmp; tmp = tmp->ai_next) {
+ int err;
+
+ fd = socket( tmp->ai_family, sock, proto );
+ if (fd < 0) {
+ ret = errno2result( errno );
+ D_DEBUG_AT( Direct_Stream,
+ "failed to create socket!\n\t->%s",
+ strerror(errno) );
+ continue;
+ }
+
+ fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK );
+
+ D_DEBUG_AT( Direct_Stream,
+ "connecting to %s...\n", tmp->ai_canonname );
+
+ if (proto == IPPROTO_UDP)
+ err = bind( fd, tmp->ai_addr, tmp->ai_addrlen );
+ else
+ err = connect( fd, tmp->ai_addr, tmp->ai_addrlen );
+
+ if (err == 0 || errno == EINPROGRESS) {
+ struct timeval t = { NET_TIMEOUT, 0 };
+ fd_set s;
+
+ /* Join multicast group? */
+ if (tmp->ai_addr->sa_family == AF_INET) {
+ struct sockaddr_in *saddr = (struct sockaddr_in *) tmp->ai_addr;
+
+ if (IN_MULTICAST( ntohl(saddr->sin_addr.s_addr) )) {
+ struct ip_mreq req;
+
+ D_DEBUG_AT( Direct_Stream,
+ "joining multicast group (%u.%u.%u.%u)...\n",
+ (u8)tmp->ai_addr->sa_data[2], (u8)tmp->ai_addr->sa_data[3],
+ (u8)tmp->ai_addr->sa_data[4], (u8)tmp->ai_addr->sa_data[5] );
+
+ req.imr_multiaddr.s_addr = saddr->sin_addr.s_addr;
+ req.imr_interface.s_addr = 0;
+
+ err = setsockopt( fd, SOL_IP, IP_ADD_MEMBERSHIP, &req, sizeof(req) );
+ if (err < 0) {
+ ret = errno2result( errno );
+ D_PERROR( "Direct/Stream: Could not join multicast group (%u.%u.%u.%u)!\n",
+ (u8)tmp->ai_addr->sa_data[2], (u8)tmp->ai_addr->sa_data[3],
+ (u8)tmp->ai_addr->sa_data[4], (u8)tmp->ai_addr->sa_data[5] );
+ close( fd );
+ continue;
+ }
+
+ setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, saddr, sizeof(*saddr) );
+ }
+ }
+
+ FD_ZERO( &s );
+ FD_SET( fd, &s );
+
+ err = select( fd+1, NULL, &s, NULL, &t );
+ if (err < 1) {
+ D_DEBUG_AT( Direct_Stream, "...connection failed.\n" );
+
+ close( fd );
+ fd = -1;
+
+ if (err == 0) {
+ ret = DR_TIMEOUT;
+ continue;
+ } else {
+ ret = errno2result( errno );
+ break;
+ }
+ }
+
+ D_DEBUG_AT( Direct_Stream, "...connected.\n" );
+
+ ret = DR_OK;
+ break;
+ }
+ }
+
+ *ret_fd = fd;
+
+ return ret;
+}
+
+static DirectResult
+net_open( DirectStream *stream, const char *filename, int proto )
+{
+ DirectResult ret = DR_OK;
+ int sock = (proto == IPPROTO_TCP) ? SOCK_STREAM : SOCK_DGRAM;
+ struct addrinfo hints;
+ char port[16];
+
+ parse_url( filename,
+ &stream->remote.host,
+ &stream->remote.port,
+ &stream->remote.user,
+ &stream->remote.pass,
+ &stream->remote.path );
+
+ snprintf( port, sizeof(port), "%d", stream->remote.port );
+
+ memset( &hints, 0, sizeof(hints) );
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_socktype = sock;
+ hints.ai_family = PF_UNSPEC;
+
+ if (getaddrinfo( stream->remote.host, port,
+ &hints, &stream->remote.addr )) {
+ D_ERROR( "Direct/Stream: "
+ "failed to resolve host '%s'!\n", stream->remote.host );
+ return DR_FAILURE;
+ }
+
+ ret = net_connect( stream->remote.addr, sock, proto, &stream->remote.sd );
+ if (ret)
+ return ret;
+
+ stream->fd = stream->remote.sd;
+ stream->length = -1;
+ stream->wait = net_wait;
+ stream->peek = net_peek;
+ stream->read = net_read;
+
+ return ret;
+}
+
+/*****************************************************************************/
+
+static DirectResult
+http_seek( DirectStream *stream, unsigned int offset )
+{
+ DirectResult ret;
+ char buf[1280];
+ int status, len;
+
+ close( stream->remote.sd );
+ stream->remote.sd = -1;
+
+ ret = net_connect( stream->remote.addr,
+ SOCK_STREAM, IPPROTO_TCP, &stream->remote.sd );
+ if (ret)
+ return ret;
+
+ stream->fd = stream->remote.sd;
+
+ len = snprintf( buf, sizeof(buf),
+ "GET %s HTTP/1.0\r\n"
+ "Host: %s:%d\r\n",
+ stream->remote.path,
+ stream->remote.host,
+ stream->remote.port );
+ if (stream->remote.auth) {
+ len += snprintf( buf+len, sizeof(buf)-len,
+ "Authorization: Basic %s\r\n",
+ stream->remote.auth );
+ }
+ snprintf( buf+len, sizeof(buf)-len,
+ "User-Agent: DirectFB/%s\r\n"
+ "Accept: */*\r\n"
+ "Range: bytes=%d-\r\n"
+ "Connection: Close\r\n",
+ DIRECTFB_VERSION, offset );
+
+ status = net_command( stream, buf, sizeof(buf) );
+ switch (status) {
+ case 200 ... 299:
+ stream->offset = offset;
+ break;
+ default:
+ if (status)
+ D_DEBUG_AT( Direct_Stream,
+ "server returned status %d.\n", status );
+ return DR_FAILURE;
+ }
+
+ /* discard remaining headers */
+ while (net_response( stream, buf, sizeof(buf) ) > 0);
+
+ return DR_OK;
+}
+
+static DirectResult
+http_open( DirectStream *stream, const char *filename )
+{
+ DirectResult ret;
+ char buf[1280];
+ int status, len;
+
+ stream->remote.port = HTTP_PORT;
+
+ ret = net_open( stream, filename, IPPROTO_TCP );
+ if (ret)
+ return ret;
+
+ if (stream->remote.user) {
+ char *tmp;
+
+ if (stream->remote.pass) {
+ tmp = alloca( strlen( stream->remote.user ) +
+ strlen( stream->remote.pass ) + 2 );
+ len = sprintf( tmp, "%s:%s",
+ stream->remote.user, stream->remote.pass );
+ } else {
+ tmp = alloca( strlen( stream->remote.user ) + 2 );
+ len = sprintf( tmp, "%s:", stream->remote.user );
+ }
+
+ stream->remote.auth = direct_base64_encode( tmp, len );
+ }
+
+ len = snprintf( buf, sizeof(buf),
+ "GET %s HTTP/1.0\r\n"
+ "Host: %s:%d\r\n",
+ stream->remote.path,
+ stream->remote.host,
+ stream->remote.port );
+ if (stream->remote.auth) {
+ len += snprintf( buf+len, sizeof(buf)-len,
+ "Authorization: Basic %s\r\n",
+ stream->remote.auth );
+ }
+ snprintf( buf+len, sizeof(buf)-len,
+ "User-Agent: DirectFB/%s\r\n"
+ "Accept: */*\r\n"
+ "Connection: Close\r\n",
+ DIRECTFB_VERSION );
+
+ status = net_command( stream, buf, sizeof(buf) );
+
+ while (net_response( stream, buf, sizeof(buf) ) > 0) {
+ if (!strncasecmp( buf, "Accept-Ranges:", 14 )) {
+ if (strcmp( trim( buf+14 ), "none" ))
+ stream->seek = http_seek;
+ }
+ else if (!strncasecmp( buf, "Content-Type:", 13 )) {
+ char *mime = trim( buf+13 );
+ char *tmp = strchr( mime, ';' );
+ if (tmp)
+ *tmp = '\0';
+ if (stream->mime)
+ D_FREE( stream->mime );
+ stream->mime = D_STRDUP( mime );
+ }
+ else if (!strncasecmp( buf, "Content-Length:", 15 )) {
+ char *tmp = trim( buf+15 );
+ if (sscanf( tmp, "%d", &stream->length ) < 1)
+ sscanf( tmp, "bytes=%d", &stream->length );
+ }
+ else if (!strncasecmp( buf, "Location:", 9 )) {
+ direct_stream_close( stream );
+ stream->seek = NULL;
+
+ if (++stream->remote.redirects > HTTP_MAX_REDIRECTS) {
+ D_ERROR( "Direct/Stream: "
+ "reached maximum number of redirects (%d).\n",
+ HTTP_MAX_REDIRECTS );
+ return DR_LIMITEXCEEDED;
+ }
+
+ filename = trim( buf+9 );
+ if (!strncmp( filename, "http://", 7 ))
+ return http_open( stream, filename+7 );
+ if (!strncmp( filename, "ftp://", 6 ))
+ return ftp_open( stream, filename+6 );
+ if (!strncmp( filename, "rtsp://", 7 ))
+ return rtsp_open( stream, filename+7 );
+
+ return DR_UNSUPPORTED;
+ }
+ }
+
+ switch (status) {
+ case 200 ... 299:
+ break;
+ default:
+ if (status)
+ D_DEBUG_AT( Direct_Stream,
+ "server returned status %d.\n", status );
+ return (status == 404) ? DR_FILENOTFOUND : DR_FAILURE;
+ }
+
+ return DR_OK;
+}
+
+/*****************************************************************************/
+
+static DirectResult
+ftp_open_pasv( DirectStream *stream, char *buf, size_t size )
+{
+ DirectResult ret;
+ int i, len;
+
+ snprintf( buf, size, "PASV" );
+ if (net_command( stream, buf, size ) != 227)
+ return DR_FAILURE;
+
+ /* parse IP and port for passive mode */
+ for (i = 4; buf[i]; i++) {
+ unsigned int d[6];
+
+ if (sscanf( &buf[i], "%u,%u,%u,%u,%u,%u",
+ &d[0], &d[1], &d[2], &d[3], &d[4], &d[5] ) == 6)
+ {
+ struct addrinfo hints, *addr;
+
+ /* address */
+ len = snprintf( buf, size,
+ "%u.%u.%u.%u",
+ d[0], d[1], d[2], d[3] );
+ /* port */
+ snprintf( buf+len+1, size-len-1,
+ "%u", ((d[4] & 0xff) << 8) | (d[5] & 0xff) );
+
+ memset( &hints, 0, sizeof(hints) );
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = PF_UNSPEC;
+
+ if (getaddrinfo( buf, buf+len+1, &hints, &addr )) {
+ D_DEBUG_AT( Direct_Stream,
+ "failed to resolve host '%s'.\n", buf );
+ return DR_FAILURE;
+ }
+
+ ret = net_connect( addr, SOCK_STREAM, IPPROTO_TCP, &stream->fd );
+
+ freeaddrinfo( addr );
+
+ return ret;
+ }
+ }
+
+ return DR_FAILURE;
+}
+
+static DirectResult
+ftp_seek( DirectStream *stream, unsigned int offset )
+{
+ DirectResult ret = DR_OK;
+ char buf[512];
+
+ if (stream->fd > 0) {
+ int status;
+
+ close( stream->fd );
+ stream->fd = -1;
+
+ /* ignore response */
+ while (net_response( stream, buf, sizeof(buf) ) > 0) {
+ if (sscanf( buf, "%3d%[ ]", &status, buf ) == 2)
+ break;
+ }
+ }
+
+ ret = ftp_open_pasv( stream, buf, sizeof(buf) );
+ if (ret)
+ return ret;
+
+ snprintf( buf, sizeof(buf), "REST %d", offset );
+ if (net_command( stream, buf, sizeof(buf) ) != 350)
+ goto error;
+
+ snprintf( buf, sizeof(buf), "RETR %s", stream->remote.path );
+ switch (net_command( stream, buf, sizeof(buf) )) {
+ case 150:
+ case 125:
+ break;
+ default:
+ goto error;
+ }
+
+ stream->offset = offset;
+
+ return DR_OK;
+
+error:
+ close( stream->fd );
+ stream->fd = -1;
+
+ return DR_FAILURE;
+}
+
+static DirectResult
+ftp_open( DirectStream *stream, const char *filename )
+{
+ DirectResult ret;
+ int status = 0;
+ char buf[512];
+
+ stream->remote.port = FTP_PORT;
+
+ ret = net_open( stream, filename, IPPROTO_TCP );
+ if (ret)
+ return ret;
+
+ while (net_response( stream, buf, sizeof(buf) ) > 0) {
+ if (sscanf( buf, "%3d%[ ]", &status, buf ) == 2)
+ break;
+ }
+ if (status != 220)
+ return DR_FAILURE;
+
+ /* login */
+ snprintf( buf, sizeof(buf), "USER %s", stream->remote.user ? : "anonymous" );
+ switch (net_command( stream, buf, sizeof(buf) )) {
+ case 230:
+ case 331:
+ break;
+ default:
+ return DR_FAILURE;
+ }
+
+ if (stream->remote.pass) {
+ snprintf( buf, sizeof(buf), "PASS %s", stream->remote.pass );
+ if (net_command( stream, buf, sizeof(buf) ) != 230)
+ return DR_FAILURE;
+ }
+
+ /* enter binary mode */
+ snprintf( buf, sizeof(buf), "TYPE I" );
+ if (net_command( stream, buf, sizeof(buf) ) != 200)
+ return DR_FAILURE;
+
+ /* get file size */
+ snprintf( buf, sizeof(buf), "SIZE %s", stream->remote.path );
+ if (net_command( stream, buf, sizeof(buf) ) == 213)
+ stream->length = strtol( buf+4, NULL, 10 );
+
+ /* enter passive mode by default */
+ ret = ftp_open_pasv( stream, buf, sizeof(buf) );
+ if (ret)
+ return ret;
+
+ /* retrieve file */
+ snprintf( buf, sizeof(buf), "RETR %s", stream->remote.path );
+ switch (net_command( stream, buf, sizeof(buf) )) {
+ case 125:
+ case 150:
+ break;
+ default:
+ return DR_FAILURE;
+ }
+
+ stream->seek = ftp_seek;
+
+ return DR_OK;
+}
+
+/*****************************************************************************/
+
+typedef struct {
+ s8 pt; // payload type (-1: dymanic)
+ u8 type; // codec type
+ const char *name;
+ const char *mime;
+ u32 fcc;
+} RTPPayload;
+
+typedef struct {
+ char *control;
+
+ int pt;
+ const RTPPayload *payload;
+
+ int dur; // duration
+ int abr; // avg bitrate
+ int mbr; // max bitrate
+ int aps; // avg packet size
+ int mps; // max packet size
+ int str; // start time
+ int prl; // preroll
+
+ char *mime;
+ int mime_size;
+
+ void *data;
+ int data_size;
+} SDPStreamDesc;
+
+#define PAYLOAD_VIDEO 1
+#define PAYLOAD_AUDIO 2
+
+#define FCC( a, b, c, d ) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24))
+
+static const RTPPayload payloads[] = {
+ { 31, PAYLOAD_VIDEO, "H261", "video/h261", FCC('H','2','6','1') },
+ { 34, PAYLOAD_VIDEO, "H263", "video/h263", FCC('H','2','6','3') },
+ //{ -1, PAYLOAD_VIDEO, "H264", "video/h264", FCC('H','2','6','4') },
+ { 32, PAYLOAD_VIDEO, "MPV", "video/mpeg", FCC('M','P','E','G') },
+ { 33, 0, "MP2T", "video/mpegts", 0 },
+ { -1, PAYLOAD_VIDEO, "MP4V-ES", "video/mpeg4", FCC('M','P','4','S') },
+ { 14, PAYLOAD_AUDIO, "MPA", "audio/mpeg", 0x0055 },
+ //{ -1, PAYLOAD_AUDIO, "mpeg4-generic", "audio/aac", 0x00ff },
+};
+
+#define NUM_PAYLOADS D_ARRAY_SIZE( payloads )
+
+static DirectResult
+sdp_parse( DirectStream *stream, int length, SDPStreamDesc **ret_streams, int *ret_num )
+{
+ char *buf, *tmp;
+ SDPStreamDesc *desc = NULL;
+ int num = 0;
+ fd_set set;
+ struct timeval tv;
+ int i;
+
+ buf = D_CALLOC( 1, length+1 );
+ if (!buf)
+ return D_OOM();
+
+ FD_ZERO( &set );
+ FD_SET( stream->remote.sd, &set );
+
+ for (tmp = buf; length;) {
+ int size;
+
+ tv.tv_sec = NET_TIMEOUT;
+ tv.tv_usec = 0;
+ select( stream->remote.sd+1, &set, NULL, NULL, &tv );
+
+ size = recv( stream->remote.sd, tmp, length, MSG_WAITALL );
+ if (size < 1)
+ break;
+ tmp += size;
+ length -= size;
+ }
+
+ for (tmp = buf; tmp && *tmp;) {
+ char *end;
+
+ end = strchr( tmp, '\n' );
+ if (end) {
+ if (end > tmp && *(end-1) == '\r')
+ *(end-1) = '\0';
+ *end = '\0';
+ }
+
+ D_DEBUG_AT( Direct_Stream, "SDP [%s]\n", tmp );
+
+ switch (*tmp) {
+ case 'm':
+ /* media */
+ if (*(tmp+1) == '=') {
+ desc = D_REALLOC( desc, ++num*sizeof(SDPStreamDesc) );
+ memset( &desc[num-1], 0, sizeof(SDPStreamDesc) );
+
+ tmp += 2;
+ if (sscanf( tmp, "audio %d RTP/AVP %d", &i, &desc[num-1].pt ) == 2 ||
+ sscanf( tmp, "video %d RTP/AVP %d", &i, &desc[num-1].pt ) == 2) {
+ for (i = 0; i < NUM_PAYLOADS; i++) {
+ if (desc[num-1].pt == payloads[i].pt) {
+ desc[num-1].payload = &payloads[i];
+ desc[num-1].mime = D_STRDUP( payloads[i].mime );
+ desc[num-1].mime_size = strlen( payloads[i].mime );
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case 'a':
+ /* attribute */
+ if (*(tmp+1) == '=' && num) {
+ tmp += 2;
+ if (!strncmp( tmp, "control:", 8 )) {
+ desc[num-1].control = D_STRDUP( trim( tmp+8 ) );
+ }
+ else if (!strncmp( tmp, "rtpmap:", 7 )) {
+ if (!desc[num-1].payload && desc[num-1].pt) {
+ char *sep;
+
+ tmp = strchr( trim( tmp+7 ), ' ' );
+ if (!tmp) break;
+ sep = strchr( ++tmp, '/' );
+ if (sep) *sep = '\0';
+
+ for (i = 0; i < NUM_PAYLOADS; i++) {
+ if (strcmp( tmp, payloads[i].name ))
+ continue;
+ desc[num-1].payload = &payloads[i];
+ desc[num-1].mime = D_STRDUP( payloads[i].mime );
+ desc[num-1].mime_size = strlen( payloads[i].mime );
+ break;
+ }
+ }
+ }
+ else if (!strncmp( tmp, "length:npt=", 11 )) {
+ double val = atof( tmp+11 );
+ desc[num-1].dur = val * 1000.0;
+ }
+ else if (!strncmp( tmp, "mimetype:string;", 16 )) {
+ if (desc[num-1].mime)
+ D_FREE( desc[num-1].mime );
+ desc[num-1].mime = D_STRDUP( trim( tmp+16 ) );
+ desc[num-1].mime_size = strlen( desc[num-1].mime );
+ }
+ else if (!strncmp( tmp, "AvgBitRate:", 11 )) {
+ sscanf( tmp+11, "integer;%d", &desc[num-1].abr );
+ }
+ else if (!strncmp( tmp, "MaxBitRate:", 11 )) {
+ sscanf( tmp+11, "integer;%d", &desc[num-1].mbr );
+ }
+ else if (!strncmp( tmp, "AvgPacketSize:", 14 )) {
+ sscanf( tmp+14, "integer;%d", &desc[num-1].aps );
+ }
+ else if (!strncmp( tmp, "MaxPacketSize:", 14 )) {
+ sscanf( tmp+14, "integer;%d", &desc[num-1].mps );
+ }
+ else if (!strncmp( tmp, "StartTime:", 10 )) {
+ sscanf( tmp+10, "integer;%d", &desc[num-1].str );
+ }
+ else if (!strncmp( tmp, "Preroll:", 8 )) {
+ sscanf( tmp+8, "integer;%d", &desc[num-1].prl );
+ }
+ else if (!strncmp( tmp, "OpaqueData:buffer;", 18 )) {
+ desc[num-1].data =
+ direct_base64_decode( trim( tmp+18 ),
+ &desc[num-1].data_size );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ tmp = end;
+ if (tmp) tmp++;
+ }
+
+ D_FREE( buf );
+
+ *ret_streams = desc;
+ *ret_num = num;
+
+ return desc ? DR_OK : DR_EOF;
+}
+
+static void
+sdp_free( SDPStreamDesc *streams, int num )
+{
+ int i;
+
+ for (i = 0; i < num; i++) {
+ if (streams[i].control)
+ D_FREE( streams[i].control );
+ if (streams[i].mime)
+ D_FREE( streams[i].mime );
+ if (streams[i].data)
+ D_FREE( streams[i].data );
+ }
+ D_FREE( streams );
+}
+
+static DirectResult
+rmf_write_header( SDPStreamDesc *streams, int n_streams, void **ret_buf, unsigned int *ret_size )
+{
+ unsigned char *dst, *tmp;
+ int abr = 0;
+ int mbr = 0;
+ int aps = 0;
+ int mps = 0;
+ int str = 0;
+ int prl = 0;
+ int dur = 0;
+ int i, len;
+
+ len = 86 + n_streams*46;
+ for (i = 0; i < n_streams; i++) {
+ abr += streams[i].abr;
+ aps += streams[i].aps;
+ if (mbr < streams[i].mbr)
+ mbr = streams[i].mbr;
+ if (mps < streams[i].mps)
+ mps = streams[i].mps;
+ if (dur < streams[i].dur)
+ dur = streams[i].dur;
+ if (streams[i].mime)
+ len += streams[i].mime_size;
+ if (streams[i].data)
+ len += streams[i].data_size;
+ else if (streams[i].payload)
+ len += 74;
+ }
+
+ *ret_buf = dst = D_MALLOC( len );
+ if (!dst)
+ return D_OOM();
+ *ret_size = len;
+
+ /* RMF */
+ dst[0] = '.'; dst[1] = 'R', dst[2] = 'M'; dst[3] = 'F';
+ dst[4] = dst[5] = dst[6] = 0; dst[7] = 18; // size
+ dst[8] = dst[9] = 0; // version
+ dst[10] = dst[11] = dst[12] = dst[13] = 0; // ??
+ dst[14] = dst[15] = dst[16] = 0; dst[17] = 4+n_streams; // num streams
+ dst += 18;
+
+ /* PROP */
+ dst[0] = 'P'; dst[1] = 'R'; dst[2] = 'O'; dst[3] = 'P';
+ dst[4] = dst[5] = dst[6] = 0; dst[7] = 50;
+ dst[8] = dst[9] = 0;
+ dst[10] = mbr>>24; dst[11] = mbr>>16; dst[12] = mbr>>8; dst[13] = mbr;
+ dst[14] = abr>>24; dst[15] = abr>>16; dst[16] = abr>>8; dst[17] = abr;
+ dst[18] = mps>>24; dst[19] = mps>>16; dst[20] = mps>>8; dst[21] = mps;
+ dst[22] = aps>>24; dst[23] = aps>>16; dst[24] = aps>>8; dst[25] = aps;
+ dst[26] = dst[27] = dst[28] = dst[29] = 0; // num packets
+ dst[30] = dur>>24; dst[31] = dur>>16; dst[32] = dur>>8; dst[33] = dur;
+ dst[34] = dst[35] = dst[36] = dst[37] = 0; // preroll
+ dst[38] = dst[39] = dst[40] = dst[41] = 0; // index offset
+ dst[42] = len>>24; dst[43] = len>>16; dst[44] = len>>8; dst[45] = len;
+ dst[46] = 0; dst[47] = n_streams; // num streams
+ dst[48] = 0; dst[49] = 7; // flags
+ dst += 50;
+
+ for (i = 0; i < n_streams; i++) {
+ len = 46 + streams[i].mime_size;
+ if (streams[i].data)
+ len += streams[i].data_size;
+ else if (streams[i].payload)
+ len += 74;
+
+ abr = streams[i].abr;
+ mbr = streams[i].mbr;
+ aps = streams[i].aps;
+ mps = streams[i].mps;
+ str = streams[i].str;
+ prl = streams[i].prl;
+ dur = streams[i].dur;
+
+ /* MDPR */
+ dst[0] = 'M'; dst[1] = 'D'; dst[2] = 'P'; dst[3] = 'R';
+ dst[4] = len>>24; dst[5] = len>>16; dst[6] = len>>8; dst[7] = len;
+ dst[8] = dst[9] = 0;
+ dst[10] = 0; dst[11] = i;
+ dst[12] = mbr>>24; dst[13] = mbr>>16; dst[14] = mbr>>8; dst[15] = mbr;
+ dst[16] = abr>>24; dst[17] = abr>>16; dst[18] = abr>>8; dst[19] = abr;
+ dst[20] = mps>>24; dst[21] = mps>>16; dst[22] = mps>>8; dst[23] = mps;
+ dst[24] = aps>>24; dst[25] = aps>>16; dst[26] = aps>>8; dst[27] = aps;
+ dst[28] = str>>24; dst[29] = str>>16; dst[30] = str>>8; dst[31] = str;
+ dst[32] = prl>>24; dst[33] = prl>>16; dst[34] = prl>>8; dst[35] = prl;
+ dst[36] = dur>>24; dst[37] = dur>>16; dst[38] = dur>>8; dst[39] = dur;
+ dst += 40;
+
+ /* description */
+ *dst++ = 0;
+ /* mimetype */
+ *dst++ = streams[i].mime_size;
+ for (tmp = (unsigned char*)streams[i].mime; tmp && *tmp;)
+ *dst++ = *tmp++;
+
+ /* codec data */
+ if (streams[i].data) {
+ len = streams[i].data_size;
+ dst[0] = len>>24; dst[1] = len>>16; dst[2] = len>>8; dst[3] = len;
+ direct_memcpy( dst+4, streams[i].data, streams[i].data_size );
+ dst += len+4;
+ }
+ else if (streams[i].payload) {
+ u32 fcc = streams[i].payload->fcc;
+
+ dst[0] = dst[1] = dst[2] = 0; dst[3] = 74;
+ dst += 4;
+ memset( dst, 0, 74 );
+
+ if (streams[i].payload->type == PAYLOAD_AUDIO) {
+ dst[0] = '.'; dst[1] = 'r'; dst[2] = 'a'; dst[3] = 0xfd;
+ dst[4] = 0; dst[5] = 5; // version
+ dst[66] = fcc; dst[67] = fcc>>8; dst[68] = fcc>>16; dst[69] = fcc>>24;
+ }
+ else {
+ dst[0] = dst[1] = dst[2] = 0; dst[3] = 34;
+ dst[4] = 'V'; dst[5] = 'I'; dst[6] = 'D'; dst[7] = 'O';
+ dst[8] = fcc; dst[9] = fcc>>8; dst[10] = fcc>>16; dst[11] = fcc>>24;
+ dst[30] = 0x10;
+ }
+ dst += 74;
+ }
+ else {
+ dst[0] = dst[1] = dst[2] = dst[3] = 0;
+ dst += 4;
+ }
+ }
+
+ /* DATA */
+ dst[0] = 'D'; dst[1] = 'A'; dst[2] = 'T'; dst[3] = 'A';
+ dst[4] = dst[5] = dst[6] = 0; dst[7] = 18; // size
+ dst[8] = dst[9] = 0; // version
+ dst[10] = dst[11] = dst[12] = dst[13] = 0; // num packets
+ dst[14] = dst[15] = dst[16] = dst[17] = 0; // next data
+
+ return DR_OK;
+}
+
+static int
+rmf_write_pheader( unsigned char *dst, int id, int sz, unsigned int ts )
+{
+ /* version */
+ dst[0] = dst[1] = 0;
+ /* length */
+ dst[2] = (sz+12)>>8; dst[3] = sz+12;
+ /* indentifier */
+ dst[4] = id>>8; dst[5] = id;
+ /* timestamp */
+ dst[6] = ts>>24; dst[7] = ts>>16; dst[8] = ts>>8; dst[9] = ts;
+ /* reserved */
+ dst[10] = 0;
+ /* flags */
+ dst[11] = 0;
+
+ return 12;
+}
+
+static void
+real_calc_challenge2( char response[64], char checksum[32], char *challenge )
+{
+ const unsigned char xor_table[37] = {
+ 0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53,
+ 0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70,
+ 0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09,
+ 0x63, 0x11, 0x03, 0x71, 0x08, 0x08, 0x70, 0x02,
+ 0x10, 0x57, 0x05, 0x18, 0x54
+ };
+ char buf[128];
+ char md5[16];
+ int len;
+ int i;
+
+ memset( response, 0, 64 );
+ memset( checksum, 0, 32 );
+
+ buf[0] = 0xa1; buf[1] = 0xe9; buf[2] = 0x14; buf[3] = 0x9d;
+ buf[4] = 0x0e; buf[5] = 0x6b; buf[6] = 0x3b; buf[7] = 0x59;
+ memset( buf+8, 0, 120 );
+
+ len = strlen( challenge );
+ if (len == 40) {
+ challenge[32] = '\0';
+ len = 32;
+ }
+ memcpy( buf+8, challenge, MAX(len,56) );
+
+ for (i = 0; i < 37; i++)
+ buf[8+i] ^= xor_table[i];
+
+ /* compute response */
+ direct_md5_sum( md5, buf, 64 );
+ /* convert to ascii */
+ for (i = 0; i < 16; i++) {
+ char a, b;
+ a = (md5[i] >> 4) & 15;
+ b = md5[i] & 15;
+ response[i*2+0] = ((a < 10) ? (a + 48) : (a + 87)) & 255;
+ response[i*2+1] = ((b < 10) ? (b + 48) : (b + 87)) & 255;
+ }
+ /* tail */
+ len = strlen( response );
+ direct_snputs( &response[len], "01d0a8e3", 64-len );
+
+ /* compute checksum */
+ for (i = 0; i < len/4; i++)
+ checksum[i] = response[i*4];
+}
+
+static DirectResult
+rtsp_session_open( DirectStream *stream )
+{
+ DirectResult ret;
+ int status;
+ int cseq = 0;
+ SDPStreamDesc *streams = NULL;
+ int n_streams = 0;
+ char session[32] = {0, };
+ char challen[64] = {0, };
+ char buf[1280];
+ int i, len;
+
+ snprintf( buf, sizeof(buf),
+ "OPTIONS rtsp://%s:%d RTSP/1.0\r\n"
+ "CSeq: %d\r\n"
+ "User-Agent: DirectFB/%s\r\n"
+ "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
+ "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
+ "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
+ "GUID: 00000000-0000-0000-0000-000000000000\r\n"
+ "RegionData: 0\r\n",
+ stream->remote.host,
+ stream->remote.port,
+ ++cseq, DIRECTFB_VERSION );
+
+ if (net_command( stream, buf, sizeof(buf) ) != 200)
+ return DR_FAILURE;
+
+ while (net_response( stream, buf, sizeof(buf) ) > 0) {
+ if (!strncmp( buf, "RealChallenge1:", 15 )) {
+ snprintf( challen, sizeof(challen), "%s", trim( buf+15 ) );
+ stream->remote.real_rtsp = true;
+ }
+ }
+
+ len = snprintf( buf, sizeof(buf),
+ "DESCRIBE rtsp://%s:%d%s RTSP/1.0\r\n"
+ "CSeq: %d\r\n"
+ "Accept: application/sdp\r\n"
+ "Bandwidth: 10485800\r\n",
+ stream->remote.host,
+ stream->remote.port,
+ stream->remote.path,
+ ++cseq );
+ if (stream->remote.real_rtsp) {
+ snprintf( buf+len, sizeof(buf)-len,
+ "GUID: 00000000-0000-0000-0000-000000000000\r\n"
+ "RegionData: 0\r\n"
+ "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586\r\n"
+ "SupportsMaximumASMBandwidth: 1\r\n"
+ "Require: com.real.retain-entity-for-setup\r\n" );
+ }
+
+ status = net_command( stream, buf, sizeof(buf) );
+ if (status != 200)
+ return (status == 404) ? DR_FILENOTFOUND : DR_FAILURE;
+
+ len = 0;
+ while (net_response( stream, buf, sizeof(buf) ) > 0) {
+ if (!strncasecmp( buf, "ETag:", 5 )) {
+ snprintf( session, sizeof(session), "%s", trim( buf+5 ) );
+ }
+ else if (!strncasecmp( buf, "Content-Length:", 15 )) {
+ char *tmp = trim( buf+15 );
+ if (sscanf( tmp, "%d", &len ) != 1)
+ sscanf( tmp, "bytes=%d", &len );
+ }
+ }
+
+ if (!len) {
+ D_DEBUG_AT( Direct_Stream, "Couldn't get sdp length!\n" );
+ return DR_FAILURE;
+ }
+
+ ret = sdp_parse( stream, len, &streams, &n_streams );
+ if (ret)
+ return ret;
+
+ for (i = 0; i < n_streams; i++) {
+ /* skip unhandled payload types */
+ if (!stream->remote.real_rtsp && !streams[i].payload)
+ continue;
+
+ len = snprintf( buf, sizeof(buf),
+ "SETUP rtsp://%s:%d%s/%s RTSP/1.0\r\n"
+ "CSeq: %d\r\n",
+ stream->remote.host,
+ stream->remote.port,
+ stream->remote.path,
+ streams[i].control, ++cseq );
+ if (*session) {
+ if (*challen) {
+ char response[64];
+ char checksum[32];
+
+ real_calc_challenge2( response, checksum, challen );
+ len += snprintf( buf+len, sizeof(buf)-len,
+ "RealChallenge2: %s, sd=%s\r\n",
+ response, checksum );
+ *challen = '\0';
+ }
+ len += snprintf( buf+len, sizeof(buf)-len,
+ "%s: %s\r\n",
+ i ? "Session" : "If-Match", session );
+ }
+ snprintf( buf+len, sizeof(buf)-len,
+ "Transport: %s\r\n",
+ stream->remote.real_rtsp
+ ? "x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"
+ : "RTP/AVP/TCP;unicast" );
+
+ if (net_command( stream, buf, sizeof(buf) ) != 200) {
+ sdp_free( streams, n_streams );
+ return DR_FAILURE;
+ }
+
+ while (net_response( stream, buf, sizeof(buf) ) > 0) {
+ if (!strncmp( buf, "Session:", 8 ))
+ snprintf( session, sizeof(session), "%s", trim( buf+8 ) );
+ }
+ }
+
+ len = snprintf( buf, sizeof(buf),
+ "PLAY rtsp://%s:%d%s RTSP/1.0\r\n"
+ "CSeq: %d\r\n",
+ stream->remote.host,
+ stream->remote.port,
+ stream->remote.path,
+ ++cseq );
+ if (*session) {
+ len += snprintf( buf+len, sizeof(buf)-len,
+ "Session: %s\r\n", session );
+ }
+ snprintf( buf+len, sizeof(buf)-len,
+ "Range: npt=0-\r\n"
+ "Connection: Close\r\n" );
+
+ if (net_command( stream, buf, sizeof(buf) ) != 200) {
+ sdp_free( streams, n_streams );
+ return DR_FAILURE;
+ }
+
+ /* discard remaining headers */
+ while (net_response( stream, buf, sizeof(buf) ) > 0);
+
+ /* revert to blocking mode */
+ fcntl( stream->fd, F_SETFL,
+ fcntl( stream->fd, F_GETFL ) & ~O_NONBLOCK );
+
+ if (!stream->remote.real_rtsp) {
+ RTPPayload *p;
+
+ stream->remote.data = D_CALLOC( 1, (n_streams+1)*sizeof(RTPPayload) );
+ if (!stream->remote.data) {
+ sdp_free( streams, n_streams );
+ return D_OOM();
+ }
+
+ p = (RTPPayload*) stream->remote.data;
+ for (i = 0; i < n_streams; i++) {
+ if (streams[i].payload) {
+ *p = *(streams[i].payload);
+ p->pt = streams[i].pt;
+ p++;
+ }
+ }
+ }
+
+ stream->remote.real_pack = true;
+ if (n_streams == 1 && streams[0].mime) {
+ if (!strcmp( streams[0].mime, "audio/mpeg" ) ||
+ !strcmp( streams[0].mime, "audio/aac" ) ||
+ !strcmp( streams[0].mime, "video/mpeg" ) ||
+ !strcmp( streams[0].mime, "video/mpegts" ))
+ {
+ stream->mime = D_STRDUP( streams[0].mime );
+ stream->remote.real_pack = false;
+ }
+ }
+ if (stream->remote.real_pack) {
+ ret = rmf_write_header( streams, n_streams,
+ &stream->cache, &stream->cache_size );
+ if (ret) {
+ sdp_free( streams, n_streams );
+ return ret;
+ }
+ stream->mime = D_STRDUP( "application/vnd.rn-realmedia" );
+ }
+
+ sdp_free( streams, n_streams );
+
+ return DR_OK;
+}
+
+static DirectResult
+rvp_read_packet( DirectStream *stream )
+{
+ unsigned char buf[9];
+ int size;
+ int len;
+ unsigned char id;
+ unsigned int ts;
+
+ while (1) {
+ do {
+ size = recv( stream->fd, buf, 1, MSG_WAITALL );
+ if (size < 1)
+ return DR_EOF;
+ } while (buf[0] != '$');
+
+ size = recv( stream->fd, buf, 7, MSG_WAITALL );
+ if (size < 7)
+ return DR_EOF;
+
+ len = (buf[0] << 16) + (buf[1] << 8) + buf[2];
+ id = buf[3];
+ if (id != 0x40 && id != 0x42) {
+ if (buf[5] == 0x06) // EOS
+ return DR_EOF;
+ size = recv( stream->fd, buf, 9, MSG_WAITALL );
+ if (size < 9)
+ return DR_EOF;
+ id = buf[5];
+ len -= 9;
+ }
+ id = (id >> 1) & 1;
+
+ size = recv( stream->fd, buf, 6, MSG_WAITALL );
+ if (size < 6)
+ return DR_EOF;
+ ts = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+
+ len -= 10;
+ if (len > 0) {
+ unsigned char *dst;
+
+ size = len + 12;
+ stream->cache = D_REALLOC( stream->cache, stream->cache_size+size );
+ if (!stream->cache)
+ return D_OOM();
+ dst = stream->cache+stream->cache_size;
+ stream->cache_size += size;
+
+ dst += rmf_write_pheader( dst, id, len, ts );
+
+ while (len) {
+ size = recv( stream->fd, dst, len, MSG_WAITALL );
+ if (size < 1)
+ return DR_EOF;
+ dst += size;
+ len -= size;
+ }
+ break;
+ }
+ }
+
+ return DR_OK;
+}
+
+static DirectResult
+rtp_read_packet( DirectStream *stream )
+{
+ RTPPayload *payloads = (RTPPayload*)stream->remote.data;
+ unsigned char buf[12];
+ int size;
+ int len;
+ unsigned char id;
+ unsigned short seq;
+ unsigned int ts;
+ int skip;
+
+ while (1) {
+ RTPPayload *p;
+
+ do {
+ size = recv( stream->fd, buf, 1, MSG_WAITALL );
+ if (size < 1)
+ return DR_EOF;
+ } while (buf[0] != '$');
+
+ size = recv( stream->fd, buf, 3, MSG_WAITALL );
+ if (size < 3)
+ return DR_EOF;
+
+ id = buf[0];
+ len = (buf[1] << 8) | buf[2];
+ if (len < 12)
+ continue;
+
+ size = recv( stream->fd, buf, 12, MSG_WAITALL );
+ if (size < 12)
+ return DR_EOF;
+ len -= 12;
+
+ if ((buf[0] & 0xc0) != (2 << 6))
+ D_DEBUG_AT( Direct_Stream, "Bad RTP version %d!\n", buf[0] );
+ seq = (buf[2] << 8) | buf[3];
+ ts = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
+
+ for (p = payloads; p->pt; p++) {
+ if (p->pt == (buf[1] & 0x7f))
+ break;
+ }
+
+ switch (p->pt) {
+ case 0: // Unhandled
+ skip = len;
+ break;
+ case 14: // MPEG Audio
+ skip = 4;
+ break;
+ case 32: // MPEG Video
+ size = recv( stream->fd, buf, 1, MSG_WAITALL );
+ if (size < 1)
+ return DR_EOF;
+ len--;
+ skip = 3;
+ if (buf[0] & (1 << 2))
+ skip += 4;
+ break;
+ case 34: // H263
+ size = recv( stream->fd, buf, 1, MSG_WAITALL );
+ if (size < 1)
+ return DR_EOF;
+ len--;
+ skip = 3;
+ if (buf[0] & (1 << 7))
+ skip += 4;
+ if (buf[0] & (1 << 6))
+ skip += 4;
+ break;
+ default:
+ skip = 0;
+ break;
+ }
+
+ while (skip) {
+ size = recv( stream->fd, buf, MIN(skip,12), MSG_WAITALL );
+ if (size < 1)
+ return DR_EOF;
+ len -= size;
+ skip -= size;
+ }
+
+ if (len > 0) {
+ unsigned char *dst;
+
+ size = len;
+ if (stream->remote.real_pack) {
+ size += 12;
+ if (p->type == PAYLOAD_VIDEO)
+ size += 7;
+ }
+
+ stream->cache = D_REALLOC( stream->cache, stream->cache_size+size );
+ if (!stream->cache)
+ return D_OOM();
+ dst = stream->cache+stream->cache_size;
+ stream->cache_size += size;
+
+ if (stream->remote.real_pack) {
+ if (p->type == PAYLOAD_VIDEO) {
+ dst += rmf_write_pheader( dst, id, len+7, ts );
+ dst[0] = 0x81;
+ dst[1] = 0x01;
+ dst[2] = (len | 0x4000)>>8; dst[3] = len;
+ dst[4] = (len | 0x4000)>>8; dst[5] = len;
+ dst[6] = seq;
+ dst += 7;
+ } else {
+ dst += rmf_write_pheader( dst, id, len, ts );
+ }
+ }
+
+ while (len) {
+ size = recv( stream->fd, dst, len, MSG_WAITALL );
+ if (size < 1)
+ return DR_EOF;
+ dst += size;
+ len -= size;
+ }
+ break;
+ }
+ }
+
+ return DR_OK;
+}
+
+static DirectResult
+rtsp_peek( DirectStream *stream,
+ unsigned int length,
+ int offset,
+ void *buf,
+ unsigned int *read_out )
+{
+ DirectResult ret;
+ unsigned int len;
+
+ if (offset < 0)
+ return DR_UNSUPPORTED;
+
+ len = length + offset;
+ while (len > stream->cache_size) {
+ ret = (stream->remote.real_rtsp)
+ ? rvp_read_packet( stream )
+ : rtp_read_packet( stream );
+ if (ret) {
+ if (stream->cache_size < offset)
+ return ret;
+ break;
+ }
+ }
+
+ len = MIN( stream->cache_size-offset, length );
+ direct_memcpy( buf, stream->cache+offset, len );
+
+ if (read_out)
+ *read_out = len;
+
+ return DR_OK;
+}
+
+static DirectResult
+rtsp_read( DirectStream *stream,
+ unsigned int length,
+ void *buf,
+ unsigned int *read_out )
+{
+ DirectResult ret;
+ unsigned int size = 0;
+
+ while (size < length) {
+ if (stream->cache_size) {
+ unsigned int len = MIN( stream->cache_size, length-size );
+
+ direct_memcpy( buf+size, stream->cache, len );
+ size += len;
+ stream->cache_size -= len;
+
+ if (stream->cache_size) {
+ direct_memcpy( stream->cache,
+ stream->cache+len, stream->cache_size );
+ } else {
+ D_FREE( stream->cache );
+ stream->cache = NULL;
+ }
+ }
+
+ if (size < length) {
+ ret = (stream->remote.real_rtsp)
+ ? rvp_read_packet( stream )
+ : rtp_read_packet( stream );
+ if (ret) {
+ if (!size)
+ return ret;
+ break;
+ }
+ }
+ }
+
+ stream->offset += size;
+
+ if (read_out)
+ *read_out = size;
+
+ return DR_OK;
+}
+
+static DirectResult
+rtsp_open( DirectStream *stream, const char *filename )
+{
+ DirectResult ret;
+
+ stream->remote.port = RTSP_PORT;
+
+ ret = net_open( stream, filename, IPPROTO_TCP );
+ if (ret)
+ return ret;
+
+ ret = rtsp_session_open( stream );
+ if (ret) {
+ close( stream->remote.sd );
+ return ret;
+ }
+
+ stream->peek = rtsp_peek;
+ stream->read = rtsp_read;
+
+ return DR_OK;
+}
+
+#endif /* DIRECT_BUILD_NETWORK */
+
+/************************** End of Network Support ***************************/
+
+static DirectResult
+pipe_wait( DirectStream *stream,
+ unsigned int length,
+ struct timeval *tv )
+{
+ fd_set s;
+
+ if (stream->cache_size >= length)
+ return DR_OK;
+
+ FD_ZERO( &s );
+ FD_SET( stream->fd, &s );
+
+ switch (select( stream->fd+1, &s, NULL, NULL, tv )) {
+ case 0:
+ if (!tv && !stream->cache_size)
+ return DR_EOF;
+ return DR_TIMEOUT;
+ case -1:
+ return errno2result( errno );
+ }
+
+ return DR_OK;
+}
+
+static DirectResult
+pipe_peek( DirectStream *stream,
+ unsigned int length,
+ int offset,
+ void *buf,
+ unsigned int *read_out )
+{
+ unsigned int size = length;
+ int len;
+
+ if (offset < 0)
+ return DR_UNSUPPORTED;
+
+ len = length + offset;
+ if (len > stream->cache_size) {
+ ssize_t s;
+
+ stream->cache = D_REALLOC( stream->cache, len );
+ if (!stream->cache) {
+ stream->cache_size = 0;
+ return D_OOM();
+ }
+
+ s = read( stream->fd,
+ stream->cache + stream->cache_size,
+ len - stream->cache_size );
+ if (s < 0) {
+ if (errno != EAGAIN || stream->cache_size == 0)
+ return errno2result( errno );
+ s = 0;
+ }
+
+ stream->cache_size += s;
+ if (stream->cache_size <= offset)
+ return DR_BUFFEREMPTY;
+
+ size = stream->cache_size - offset;
+ }
+
+ direct_memcpy( buf, stream->cache+offset, size );
+
+ if (read_out)
+ *read_out = size;
+
+ return DR_OK;
+}
+
+static DirectResult
+pipe_read( DirectStream *stream,
+ unsigned int length,
+ void *buf,
+ unsigned int *read_out )
+{
+ unsigned int size = 0;
+
+ if (stream->cache_size) {
+ size = MIN( stream->cache_size, length );
+
+ direct_memcpy( buf, stream->cache, size );
+
+ length -= size;
+ stream->cache_size -= size;
+
+ if (stream->cache_size) {
+ direct_memcpy( stream->cache,
+ stream->cache+size, stream->cache_size );
+ } else {
+ D_FREE( stream->cache );
+ stream->cache = NULL;
+ }
+ }
+
+ if (length) {
+ ssize_t s;
+
+ s = read( stream->fd, buf+size, length-size );
+ switch (s) {
+ case 0:
+ if (!size)
+ return DR_EOF;
+ break;
+ case -1:
+ if (!size) {
+ return (errno == EAGAIN)
+ ? DR_BUFFEREMPTY
+ : errno2result( errno );
+ }
+ break;
+ default:
+ size += s;
+ break;
+ }
+ }
+
+ stream->offset += size;
+
+ if (read_out)
+ *read_out = size;
+
+ return DR_OK;
+}
+
+/*****************************************************************************/
+
+static DirectResult
+file_peek( DirectStream *stream,
+ unsigned int length,
+ int offset,
+ void *buf,
+ unsigned int *read_out )
+{
+ DirectResult ret = DR_OK;
+ ssize_t size;
+
+ if (lseek( stream->fd, offset, SEEK_CUR ) < 0)
+ return DR_FAILURE;
+
+ size = read( stream->fd, buf, length );
+ switch (size) {
+ case 0:
+ ret = DR_EOF;
+ break;
+ case -1:
+ ret = (errno == EAGAIN)
+ ? DR_BUFFEREMPTY
+ : errno2result( errno );
+ size = 0;
+ break;
+ }
+
+ if (lseek( stream->fd, - offset - size, SEEK_CUR ) < 0)
+ return DR_FAILURE;
+
+ if (read_out)
+ *read_out = size;
+
+ return ret;
+}
+
+static DirectResult
+file_read( DirectStream *stream,
+ unsigned int length,
+ void *buf,
+ unsigned int *read_out )
+{
+ ssize_t size;
+
+ size = read( stream->fd, buf, length );
+ switch (size) {
+ case 0:
+ return DR_EOF;
+ case -1:
+ if (errno == EAGAIN)
+ return DR_BUFFEREMPTY;
+ return errno2result( errno );
+ }
+
+ stream->offset += size;
+
+ if (read_out)
+ *read_out = size;
+
+ return DR_OK;
+}
+
+static DirectResult
+file_seek( DirectStream *stream, unsigned int offset )
+{
+ off_t off;
+
+ off = lseek( stream->fd, offset, SEEK_SET );
+ if (off < 0)
+ return DR_FAILURE;
+
+ stream->offset = off;
+
+ return DR_OK;
+}
+
+static DirectResult
+file_open( DirectStream *stream, const char *filename, int fileno )
+{
+ if (filename)
+ stream->fd = open( filename, O_RDONLY | O_NONBLOCK );
+ else
+ stream->fd = dup( fileno );
+
+ if (stream->fd < 0)
+ return errno2result( errno );
+
+ fcntl( stream->fd, F_SETFL,
+ fcntl( stream->fd, F_GETFL ) | O_NONBLOCK );
+
+ if (lseek( stream->fd, 0, SEEK_CUR ) < 0 && errno == ESPIPE) {
+ stream->length = -1;
+ stream->wait = pipe_wait;
+ stream->peek = pipe_peek;
+ stream->read = pipe_read;
+ }
+ else {
+ struct stat s;
+
+ if (fstat( stream->fd, &s ) < 0)
+ return errno2result( errno );
+
+ stream->length = s.st_size;
+ stream->peek = file_peek;
+ stream->read = file_read;
+ stream->seek = file_seek;
+ }
+
+ return DR_OK;
+}
+
+/*****************************************************************************/
+
+DirectResult
+direct_stream_create( const char *filename,
+ DirectStream **ret_stream )
+{
+ DirectStream *stream;
+ DirectResult ret;
+
+ D_ASSERT( filename != NULL );
+ D_ASSERT( ret_stream != NULL );
+
+ stream = D_CALLOC( 1, sizeof(DirectStream) );
+ if (!stream)
+ return D_OOM();
+
+ D_MAGIC_SET( stream, DirectStream );
+
+ stream->ref = 1;
+ stream->fd = -1;
+
+ if (!strncmp( filename, "stdin:/", 7 )) {
+ ret = file_open( stream, NULL, STDIN_FILENO );
+ }
+ else if (!strncmp( filename, "file:/", 6 )) {
+ ret = file_open( stream, filename+6, -1 );
+ }
+ else if (!strncmp( filename, "fd:/", 4 )) {
+ ret = (filename[4] >= '0' && filename[4] <= '9')
+ ? file_open( stream, NULL, atoi(filename+4) ) : DR_INVARG;
+ }
+#if DIRECT_BUILD_NETWORK
+ else if (!strncmp( filename, "http://", 7 ) ||
+ !strncmp( filename, "unsv://", 7 )) {
+ ret = http_open( stream, filename+7 );
+ }
+ else if (!strncmp( filename, "ftp://", 6 )) {
+ ret = ftp_open( stream, filename+6 );
+ }
+ else if (!strncmp( filename, "rtsp://", 7 )) {
+ ret = rtsp_open( stream, filename+7 );
+ }
+ else if (!strncmp( filename, "tcp://", 6 )) {
+ ret = net_open( stream, filename+6, IPPROTO_TCP );
+ }
+ else if (!strncmp( filename, "udp://", 6 )) {
+ ret = net_open( stream, filename+6, IPPROTO_UDP );
+ }
+#endif
+ else {
+ ret = file_open( stream, filename, -1 );
+ }
+
+ if (ret) {
+ direct_stream_close( stream );
+ D_FREE( stream );
+ return ret;
+ }
+
+ *ret_stream = stream;
+
+ return DR_OK;
+}
+
+DirectStream*
+direct_stream_dup( DirectStream *stream )
+{
+ D_ASSERT( stream != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ stream->ref++;
+
+ return stream;
+}
+
+int
+direct_stream_fileno( DirectStream *stream )
+{
+ D_ASSERT( stream != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ return stream->fd;
+}
+
+bool
+direct_stream_seekable( DirectStream *stream )
+{
+ D_ASSERT( stream != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ return stream->seek ? true : false;
+}
+
+bool
+direct_stream_remote( DirectStream *stream )
+{
+ D_ASSERT( stream != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+#if DIRECT_BUILD_NETWORK
+ if (stream->remote.host)
+ return true;
+#endif
+ return false;
+}
+
+const char*
+direct_stream_mime( DirectStream *stream )
+{
+ D_ASSERT( stream != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ return stream->mime;
+}
+
+unsigned int
+direct_stream_offset( DirectStream *stream )
+{
+ D_ASSERT( stream != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ return stream->offset;
+}
+
+unsigned int
+direct_stream_length( DirectStream *stream )
+{
+ D_ASSERT( stream != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ return (stream->length >= 0) ? stream->length : stream->offset;
+}
+
+DirectResult
+direct_stream_wait( DirectStream *stream,
+ unsigned int length,
+ struct timeval *tv )
+{
+ D_ASSERT( stream != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ if (length && stream->wait)
+ return stream->wait( stream, length, tv );
+
+ return DR_OK;
+}
+
+DirectResult
+direct_stream_peek( DirectStream *stream,
+ unsigned int length,
+ int offset,
+ void *buf,
+ unsigned int *read_out )
+{
+ D_ASSERT( stream != NULL );
+ D_ASSERT( length != 0 );
+ D_ASSERT( buf != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ if (stream->length >= 0 && (stream->offset + offset) >= stream->length)
+ return DR_EOF;
+
+ if (stream->peek)
+ return stream->peek( stream, length, offset, buf, read_out );
+
+ return DR_UNSUPPORTED;
+}
+
+DirectResult
+direct_stream_read( DirectStream *stream,
+ unsigned int length,
+ void *buf,
+ unsigned int *read_out )
+{
+ D_ASSERT( stream != NULL );
+ D_ASSERT( length != 0 );
+ D_ASSERT( buf != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ if (stream->length >= 0 && stream->offset >= stream->length)
+ return DR_EOF;
+
+ if (stream->read)
+ return stream->read( stream, length, buf, read_out );
+
+ return DR_UNSUPPORTED;
+}
+
+DirectResult
+direct_stream_seek( DirectStream *stream,
+ unsigned int offset )
+{
+ D_ASSERT( stream != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ if (stream->offset == offset)
+ return DR_OK;
+
+ if (stream->length >= 0 && offset > stream->length)
+ offset = stream->length;
+
+ if (stream->seek)
+ return stream->seek( stream, offset );
+
+ return DR_UNSUPPORTED;
+}
+
+static void
+direct_stream_close( DirectStream *stream )
+{
+#if DIRECT_BUILD_NETWORK
+ if (stream->remote.host) {
+ D_FREE( stream->remote.host );
+ stream->remote.host = NULL;
+ }
+
+ if (stream->remote.user) {
+ D_FREE( stream->remote.user );
+ stream->remote.user = NULL;
+ }
+
+ if (stream->remote.pass) {
+ D_FREE( stream->remote.pass );
+ stream->remote.pass = NULL;
+ }
+
+ if (stream->remote.auth) {
+ D_FREE( stream->remote.auth );
+ stream->remote.auth = NULL;
+ }
+
+ if (stream->remote.path) {
+ D_FREE( stream->remote.path );
+ stream->remote.path = NULL;
+ }
+
+ if (stream->remote.addr) {
+ freeaddrinfo( stream->remote.addr );
+ stream->remote.addr = NULL;
+ }
+
+ if (stream->remote.data) {
+ D_FREE( stream->remote.data );
+ stream->remote.data = NULL;
+ }
+
+ if (stream->remote.sd > 0) {
+ close( stream->remote.sd );
+ stream->remote.sd = -1;
+ }
+#endif
+
+ if (stream->mime) {
+ D_FREE( stream->mime );
+ stream->mime = NULL;
+ }
+
+ if (stream->cache) {
+ D_FREE( stream->cache );
+ stream->cache = NULL;
+ stream->cache_size = 0;
+ }
+
+ if (stream->fd >= 0) {
+ fcntl( stream->fd, F_SETFL,
+ fcntl( stream->fd, F_GETFL ) & ~O_NONBLOCK );
+ close( stream->fd );
+ stream->fd = -1;
+ }
+}
+
+void
+direct_stream_destroy( DirectStream *stream )
+{
+ D_ASSERT( stream != NULL );
+
+ D_MAGIC_ASSERT( stream, DirectStream );
+
+ if (--stream->ref == 0) {
+ direct_stream_close( stream );
+
+ D_FREE( stream );
+ }
+}
diff --git a/Source/DirectFB/lib/direct/stream.h b/Source/DirectFB/lib/direct/stream.h
new file mode 100755
index 0000000..6b77690
--- /dev/null
+++ b/Source/DirectFB/lib/direct/stream.h
@@ -0,0 +1,129 @@
+/*
+ (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 __DIRECT__STREAM_H__
+#define __DIRECT__STREAM_H__
+
+#include <stdio.h>
+#include <sys/time.h>
+
+#include <direct/types.h>
+
+/*
+ * Create a stream wrapper.
+ *
+ * 'filename' can be a plain file name or one of the following:
+ * http://<host>[:<port>]/<path>
+ * unsv://<host>[:<port>]/<path>
+ * ftp://<host>[:<port>]/<path>
+ * rtsp://<host>[:<port>]/<path>
+ * tcp://<host>:<port>
+ * udp://<host>:<port>
+ * file:/<path>
+ * fd:/<fileno>
+ * stdin:/
+ */
+DirectResult direct_stream_create ( const char *filename,
+ DirectStream **ret_stream );
+
+/*
+ * Duplicate the stream (never fails).
+ */
+DirectStream *direct_stream_dup ( DirectStream *stream );
+
+/*
+ * Return the file descriptor associated to the stream.
+ */
+int direct_stream_fileno ( DirectStream *stream );
+
+/*
+ * True if stream is seekable.
+ */
+bool direct_stream_seekable( DirectStream *stream );
+
+/*
+ * True if stream originates from a remote host.
+ */
+bool direct_stream_remote ( DirectStream *stream );
+
+/*
+ * Get the mime description of the stream.
+ * Returns NULL if the information is not available.
+ */
+const char* direct_stream_mime ( DirectStream *stream );
+
+/*
+ * Get stream length.
+ */
+unsigned int direct_stream_length ( DirectStream *stream );
+
+/*
+ * Get stream position.
+ */
+unsigned int direct_stream_offset ( DirectStream *stream );
+
+/*
+ * Wait for data to be available.
+ * If 'timeout' is NULL, the function blocks indefinitely.
+ * Set the 'timeout' to 0 to make the function return immediatly.
+ */
+DirectResult direct_stream_wait ( DirectStream *stream,
+ unsigned int length,
+ struct timeval *timeout );
+
+/*
+ * Peek 'length' bytes of data at offset 'offset' from the stream.
+ */
+DirectResult direct_stream_peek ( DirectStream *stream,
+ unsigned int length,
+ int offset,
+ void *buf,
+ unsigned int *read_out );
+
+/*
+ * Fetch 'length' bytes of data from the stream.
+ */
+DirectResult direct_stream_read ( DirectStream *stream,
+ unsigned int length,
+ void *buf,
+ unsigned int *read_out );
+
+/*
+ * Seek to the specified absolute offset within the stream.
+ */
+DirectResult direct_stream_seek ( DirectStream *stream,
+ unsigned int offset );
+
+/*
+ * Destroy the stream wrapper.
+ */
+void direct_stream_destroy ( DirectStream *stream );
+
+
+#endif /* __DIRECT__STREAM_H__ */
+
diff --git a/Source/DirectFB/lib/direct/system.c b/Source/DirectFB/lib/direct/system.c
new file mode 100755
index 0000000..b4b5b29
--- /dev/null
+++ b/Source/DirectFB/lib/direct/system.c
@@ -0,0 +1,68 @@
+/*
+ (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 <errno.h>
+#include <unistd.h>
+
+#include <direct/build.h>
+#include <direct/system.h>
+
+#if DIRECT_BUILD_GETTID && defined(HAVE_LINUX_UNISTD_H)
+#include <linux/unistd.h>
+#endif
+
+__attribute__((no_instrument_function))
+pid_t
+direct_gettid( void )
+{
+ pid_t tid = -1;
+#if DIRECT_BUILD_GETTID && defined(__NR_gettid) /* present on linux >= 2.4.20 */
+ tid = syscall(__NR_gettid);
+#endif
+ if (tid < 0)
+ tid = getpid();
+
+ return tid;
+}
+
+long
+direct_pagesize( void )
+{
+ return sysconf( _SC_PAGESIZE );
+}
+
+unsigned long
+direct_page_align( unsigned long value )
+{
+ unsigned long mask = sysconf( _SC_PAGESIZE ) - 1;
+
+ return (value + mask) & ~mask;
+}
+
diff --git a/Source/DirectFB/lib/direct/system.h b/Source/DirectFB/lib/direct/system.h
new file mode 100755
index 0000000..5cfe74e
--- /dev/null
+++ b/Source/DirectFB/lib/direct/system.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 __DIRECT__SYSTEM_H__
+#define __DIRECT__SYSTEM_H__
+
+#include <sys/types.h>
+
+pid_t direct_gettid( void );
+long direct_pagesize( void );
+
+unsigned long direct_page_align( unsigned long value );
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/thread.c b/Source/DirectFB/lib/direct/thread.c
new file mode 100755
index 0000000..91c66fc
--- /dev/null
+++ b/Source/DirectFB/lib/direct/thread.c
@@ -0,0 +1,795 @@
+/*
+ (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 <pthread.h>
+#include <signal.h>
+#include <sched.h>
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/signals.h>
+#include <direct/system.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+D_DEBUG_DOMAIN( Direct_Thread, "Direct/Thread", "Thread management" );
+D_DEBUG_DOMAIN( Direct_ThreadInit, "Direct/Thread/Init", "Thread initialization" );
+
+
+/* FIXME: DIRECT_THREAD_WAIT_INIT is required, but should be optional. */
+#define DIRECT_THREAD_WAIT_INIT
+
+
+struct __D_DirectThread {
+ int magic;
+
+ pthread_t thread; /* The pthread thread identifier. */
+ pid_t tid;
+
+ char *name;
+
+ DirectThreadType type; /* The thread's type, e.g. input thread. */
+ DirectThreadMainFunc main; /* The thread's main routine (or entry point). */
+ void *arg; /* Custom argument passed to the main routine. */
+
+ bool canceled; /* Set when direct_thread_cancel() is called. */
+ bool joining; /* Set when direct_thread_join() is called. */
+ bool joined; /* Set when direct_thread_join() has finished. */
+ bool detached; /* Set when direct_thread_detach() is called. */
+ bool terminated; /* Set when direct_thread_terminate() is called. */
+
+#ifdef DIRECT_THREAD_WAIT_INIT
+ bool init; /* Set to true before calling the main routine. */
+#endif
+
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+
+ unsigned int counter;
+};
+
+struct __D_DirectThreadInitHandler {
+ DirectLink link;
+
+ int magic;
+
+ DirectThreadInitFunc func;
+ void *arg;
+};
+
+/******************************************************************************/
+
+/*
+ * Wrapper around pthread's main routine to pass additional arguments
+ * and setup things like signal masks and scheduling priorities.
+ */
+static void *direct_thread_main( void *arg );
+
+/******************************************************************************/
+
+static pthread_mutex_t handler_lock = PTHREAD_MUTEX_INITIALIZER;
+static DirectLink *handlers = NULL;
+
+/******************************************************************************/
+
+DirectThreadInitHandler *
+direct_thread_add_init_handler( DirectThreadInitFunc func,
+ void *arg )
+{
+ DirectThreadInitHandler *handler;
+
+ handler = D_CALLOC( 1, sizeof(DirectThreadInitHandler) );
+ if (!handler) {
+ D_WARN( "out of memory" );
+ return NULL;
+ }
+
+ handler->func = func;
+ handler->arg = arg;
+
+ D_MAGIC_SET( handler, DirectThreadInitHandler );
+
+ pthread_mutex_lock( &handler_lock );
+
+ direct_list_append( &handlers, &handler->link );
+
+ pthread_mutex_unlock( &handler_lock );
+
+ return handler;
+}
+
+void
+direct_thread_remove_init_handler( DirectThreadInitHandler *handler )
+{
+ D_MAGIC_ASSERT( handler, DirectThreadInitHandler );
+
+ pthread_mutex_lock( &handler_lock );
+
+ direct_list_remove( &handlers, &handler->link );
+
+ pthread_mutex_unlock( &handler_lock );
+
+ D_MAGIC_CLEAR( handler );
+
+ D_FREE( handler );
+}
+
+/******************************************************************************/
+
+static pthread_mutex_t key_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_key_t thread_key = -1;
+
+/******************************************************************************/
+
+DirectThread *
+direct_thread_create( DirectThreadType thread_type,
+ DirectThreadMainFunc thread_main,
+ void *arg,
+ const char *name )
+{
+ DirectThread *thread;
+ pthread_attr_t attr;
+ struct sched_param param;
+ int policy;
+ int priority;
+ size_t stack_size;
+
+ D_ASSERT( thread_main != NULL );
+ D_ASSERT( name != NULL );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %s, %p(%p), '%s' )\n", __FUNCTION__,
+ direct_thread_type_name(thread_type), thread_main, arg, name );
+
+ /* Create the key for the TSD (thread specific data). */
+ pthread_mutex_lock( &key_lock );
+
+ if (thread_key == -1)
+ pthread_key_create( &thread_key, NULL );
+
+ pthread_mutex_unlock( &key_lock );
+
+ /* Allocate thread structure. */
+ thread = D_CALLOC( 1, sizeof(DirectThread) );
+ if (!thread) {
+ D_OOM();
+ return NULL;
+ }
+
+ /* Write thread information to structure. */
+ thread->name = D_STRDUP( name );
+ thread->type = thread_type;
+ thread->main = thread_main;
+ thread->arg = arg;
+
+ /* Initialize to -1 for synchronization. */
+ thread->thread = (pthread_t) -1;
+ thread->tid = (pid_t) -1;
+
+ /* Initialize mutex and condition. */
+ direct_util_recursive_pthread_mutex_init( &thread->lock );
+ pthread_cond_init( &thread->cond, NULL );
+
+ D_MAGIC_SET( thread, DirectThread );
+
+ /* Initialize scheduling and other parameters. */
+ pthread_attr_init( &attr );
+
+#ifdef PTHREAD_EXPLICIT_SCHED
+ pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
+#endif
+
+ /* Select scheduler. */
+ switch (direct_config->thread_scheduler) {
+ case DCTS_FIFO:
+ policy = SCHED_FIFO;
+ break;
+
+ case DCTS_RR:
+ policy = SCHED_RR;
+ break;
+
+ default:
+ policy = SCHED_OTHER;
+ break;
+ }
+
+ if (pthread_attr_setschedpolicy( &attr, policy ))
+ D_PERROR( "Direct/Thread: Could not set scheduling policy to %s!\n", direct_thread_policy_name(policy) );
+
+ /* Read (back) value. */
+ pthread_attr_getschedpolicy( &attr, &policy );
+
+ /* Select priority. */
+ switch (thread->type) {
+ case DTT_CLEANUP:
+ case DTT_INPUT:
+ case DTT_OUTPUT:
+ case DTT_MESSAGING:
+ case DTT_CRITICAL:
+ priority = thread->type * direct_config->thread_priority_scale / 100;
+ break;
+
+ default:
+ priority = direct_config->thread_priority;
+ break;
+ }
+
+ D_DEBUG_AT( Direct_ThreadInit, " -> %s (%d) [%d;%d]\n", direct_thread_policy_name(policy), priority,
+ sched_get_priority_min( policy ), sched_get_priority_max( policy ) );
+
+ if (priority < sched_get_priority_min( policy ))
+ priority = sched_get_priority_min( policy );
+
+ if (priority > sched_get_priority_max( policy ))
+ priority = sched_get_priority_max( policy );
+
+ param.sched_priority = priority;
+
+ if (pthread_attr_setschedparam( &attr, &param ))
+ D_PERROR( "Direct/Thread: Could not set scheduling priority to %d!\n", priority );
+
+ /* Select stack size? */
+ if (direct_config->thread_stack_size > 0) {
+ if (pthread_attr_setstacksize( &attr, direct_config->thread_stack_size ))
+ D_PERROR( "Direct/Thread: Could not set stack size to %d!\n", direct_config->thread_stack_size );
+ }
+
+ /* Read (back) value. */
+ pthread_attr_getstacksize( &attr, &stack_size );
+
+ /* Lock the thread mutex. */
+ D_DEBUG_AT( Direct_ThreadInit, " -> locking...\n" );
+ pthread_mutex_lock( &thread->lock );
+
+ /* Create and run the thread. */
+ D_DEBUG_AT( Direct_ThreadInit, " -> creating...\n" );
+ pthread_create( &thread->thread, &attr, direct_thread_main, thread );
+
+ pthread_attr_destroy( &attr );
+
+ pthread_getschedparam( thread->thread, &policy, &param );
+
+ D_INFO( "Direct/Thread: Started '%s' (%d) [%s %s/%s %d/%d] <%zu>...\n",
+ name, thread->tid, direct_thread_type_name(thread_type),
+ direct_thread_policy_name(policy), direct_thread_scheduler_name(direct_config->thread_scheduler),
+ param.sched_priority, priority, stack_size );
+
+#ifdef DIRECT_THREAD_WAIT_INIT
+ /* Wait for completion of the thread's initialization. */
+ while (!thread->init) {
+ D_DEBUG_AT( Direct_ThreadInit, " -> waiting...\n" );
+ pthread_cond_wait( &thread->cond, &thread->lock );
+ }
+
+ D_DEBUG_AT( Direct_ThreadInit, " -> ...thread is running.\n" );
+#endif
+
+ /* Unlock the thread mutex. */
+ D_DEBUG_AT( Direct_ThreadInit, " -> unlocking...\n" );
+ pthread_mutex_unlock( &thread->lock );
+
+ D_DEBUG_AT( Direct_ThreadInit, " -> returning %p\n", thread );
+
+ return thread;
+}
+
+DirectThread *
+direct_thread_self( void )
+{
+ DirectThread *thread = pthread_getspecific( thread_key );
+
+ if (thread)
+ D_MAGIC_ASSERT( thread, DirectThread );
+
+ return thread;
+}
+
+const char *
+direct_thread_get_name( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSERT( thread->name != NULL );
+
+ return thread->name;
+}
+
+pid_t
+direct_thread_get_tid( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+
+ return thread->tid;
+}
+
+__attribute__((no_instrument_function))
+const char *
+direct_thread_self_name( void )
+{
+ DirectThread *thread = pthread_getspecific( thread_key );
+
+ /*
+ * This function is called by debugging functions, e.g. debug messages, assertions etc.
+ * Therefore no assertions are made here, because they would loop forever if they fail.
+ */
+
+#ifndef MACOS
+ return thread ? thread->name : NULL;
+#else
+ return "debug";
+#endif
+}
+
+void
+direct_thread_set_name( const char *name )
+{
+ char *copy;
+ DirectThread *thread = pthread_getspecific( thread_key );
+
+ D_DEBUG_AT( Direct_Thread, "%s( '%s' )\n", __FUNCTION__, name );
+
+ /* Support this function for non-direct threads. */
+ if (!thread) {
+ D_DEBUG_AT( Direct_Thread, " -> attaching unknown thread %d\n", direct_gettid() );
+
+ /* Create the key for the TSD (thread specific data). */
+ pthread_mutex_lock( &key_lock );
+
+ if (thread_key == -1)
+ pthread_key_create( &thread_key, NULL );
+
+ pthread_mutex_unlock( &key_lock );
+
+
+ thread = D_CALLOC( 1, sizeof(DirectThread) );
+ if (!thread) {
+ D_OOM();
+ return;
+ }
+
+ thread->thread = pthread_self();
+ thread->tid = direct_gettid();
+
+ D_MAGIC_SET( thread, DirectThread );
+
+ pthread_setspecific( thread_key, thread );
+ }
+ else
+ D_DEBUG_AT( Direct_Thread, " -> was '%s' (%d)\n", thread->name, direct_gettid() );
+
+ /* Duplicate string. */
+ copy = D_STRDUP( name );
+ if (!copy) {
+ D_OOM();
+ return;
+ }
+
+ /* Free old string. */
+ if (thread->name)
+ D_FREE( thread->name );
+
+ /* Keep the copy. */
+ thread->name = copy;
+}
+
+DirectResult
+direct_thread_wait( DirectThread *thread, int timeout_ms )
+{
+ unsigned int old_counter = thread->counter;
+
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSERT( thread->thread != -1 );
+
+ D_ASSUME( !thread->canceled );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %p, '%s' %d, %dms )\n", __FUNCTION__,
+ thread->main, thread->name, thread->tid, timeout_ms );
+
+ while (old_counter == thread->counter && !thread->terminated)
+ pthread_cond_wait( &thread->cond, &thread->lock );
+
+ if (thread->terminated)
+ return DR_DEAD;
+
+ return DR_OK;
+}
+
+void
+direct_thread_notify( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSERT( thread->thread != -1 );
+
+ D_ASSUME( !thread->canceled );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %p, '%s' %d )\n", __FUNCTION__, thread->main, thread->name, thread->tid );
+
+ pthread_mutex_lock( &thread->lock );
+
+ thread->counter++;
+
+ pthread_mutex_unlock( &thread->lock );
+
+ pthread_cond_broadcast( &thread->cond );
+}
+
+void
+direct_thread_lock( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSERT( thread->thread != -1 );
+
+ D_ASSUME( !thread->canceled );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %p, '%s' %d )\n", __FUNCTION__, thread->main, thread->name, thread->tid );
+
+ pthread_mutex_lock( &thread->lock );
+}
+
+void
+direct_thread_unlock( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSERT( thread->thread != -1 );
+
+ D_ASSUME( !thread->canceled );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %p, '%s' %d )\n", __FUNCTION__, thread->main, thread->name, thread->tid );
+
+ pthread_mutex_unlock( &thread->lock );
+}
+
+void
+direct_thread_terminate( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSERT( thread->thread != -1 );
+ D_ASSUME( !pthread_equal( thread->thread, pthread_self() ) );
+
+ D_ASSUME( !thread->canceled );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %p, '%s' %d )\n", __FUNCTION__, thread->main, thread->name, thread->tid );
+
+ thread->terminated = true;
+
+ direct_thread_notify( thread );
+}
+
+void
+direct_thread_cancel( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSERT( thread->thread != -1 );
+ D_ASSERT( !pthread_equal( thread->thread, pthread_self() ) );
+
+ D_ASSUME( !thread->canceled );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %p, '%s' %d )\n", __FUNCTION__, thread->main, thread->name, thread->tid );
+
+ thread->canceled = true;
+
+#if DIRECT_BUILD_NO_PTHREAD_CANCEL
+ D_UNIMPLEMENTED();
+#else
+ pthread_cancel( thread->thread );
+#endif
+}
+
+bool
+direct_thread_is_canceled( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+
+ return thread->canceled;
+}
+
+void
+direct_thread_detach( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSERT( thread->thread != -1 );
+ D_ASSERT( !pthread_equal( thread->thread, pthread_self() ) );
+
+ D_ASSUME( !thread->canceled );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %p, '%s' %d )\n", __FUNCTION__, thread->main, thread->name, thread->tid );
+
+ thread->detached = true;
+
+ pthread_detach( thread->thread );
+}
+
+bool
+direct_thread_is_detached( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+
+ return thread->detached;
+}
+
+void
+direct_thread_testcancel( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSERT( thread->thread != -1 );
+ D_ASSERT( pthread_equal( thread->thread, pthread_self() ) );
+
+#if DIRECT_BUILD_NO_PTHREAD_CANCEL
+ D_UNIMPLEMENTED();
+#else
+ /* Quick check before calling the pthread function. */
+ if (thread->canceled)
+ pthread_testcancel();
+#endif
+}
+
+void
+direct_thread_join( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSERT( thread->thread != -1 );
+
+ D_ASSUME( !pthread_equal( thread->thread, pthread_self() ) );
+ D_ASSUME( !thread->joining );
+ D_ASSUME( !thread->joined );
+ D_ASSUME( !thread->detached );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %p, '%s' %d )\n", __FUNCTION__, thread->main, thread->name, thread->tid );
+
+ if (thread->detached) {
+ D_DEBUG_AT( Direct_Thread, " -> DETACHED!\n" );
+ return;
+ }
+
+ if (!thread->joining && !pthread_equal( thread->thread, pthread_self() )) {
+ thread->joining = true;
+
+ D_DEBUG_AT( Direct_Thread, " -> joining...\n" );
+
+ pthread_join( thread->thread, NULL );
+
+ thread->joined = true;
+
+ D_DEBUG_AT( Direct_Thread, " -> joined.\n" );
+ }
+}
+
+bool
+direct_thread_is_joined( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+
+ return thread->joined;
+}
+
+void
+direct_thread_destroy( DirectThread *thread )
+{
+ D_MAGIC_ASSERT( thread, DirectThread );
+ D_ASSUME( !pthread_equal( thread->thread, pthread_self() ) );
+ D_ASSUME( !thread->detached );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %p, '%s' %d )\n", __FUNCTION__, thread->main, thread->name, thread->tid );
+
+ if (thread->detached) {
+ D_DEBUG_AT( Direct_Thread, " -> DETACHED!\n" );
+ return;
+ }
+
+ if (!thread->joined && !pthread_equal( thread->thread, pthread_self() )) {
+ if (thread->canceled)
+ D_DEBUG_AT( Direct_Thread, " -> cancled but not joined!\n" );
+ else {
+ D_DEBUG_AT( Direct_Thread, " -> still running!\n" );
+
+ if (thread->name)
+ D_ERROR( "Direct/Thread: Canceling '%s' (%d)!\n", thread->name, thread->tid );
+ else
+ D_ERROR( "Direct/Thread: Canceling %d!\n", thread->tid );
+
+ thread->detached = true;
+
+ pthread_detach( thread->thread );
+
+ direct_thread_cancel( thread );
+
+ return;
+ }
+ }
+
+ D_MAGIC_CLEAR( thread );
+
+ D_FREE( thread->name );
+ D_FREE( thread );
+}
+
+/******************************************************************************/
+
+#if DIRECT_BUILD_TEXT
+const char *
+direct_thread_type_name( DirectThreadType type )
+{
+ switch (type) {
+ case DTT_DEFAULT:
+ return "DEFAULT";
+
+ case DTT_CLEANUP:
+ return "CLEANUP";
+
+ case DTT_INPUT:
+ return "INPUT";
+
+ case DTT_OUTPUT:
+ return "OUTPUT";
+
+ case DTT_MESSAGING:
+ return "MESSAGING";
+
+ case DTT_CRITICAL:
+ return "CRITICAL";
+ }
+
+ return "<unknown>";
+}
+
+const char *
+direct_thread_scheduler_name( DirectConfigThreadScheduler scheduler )
+{
+ switch (scheduler) {
+ case DCTS_OTHER:
+ return "OTHER";
+
+ case DCTS_FIFO:
+ return "FIFO";
+
+ case DCTS_RR:
+ return "RR";
+ }
+
+ return "<unknown>";
+}
+
+const char *
+direct_thread_policy_name( int policy )
+{
+ switch (policy) {
+ case SCHED_OTHER:
+ return "OTHER";
+
+ case SCHED_FIFO:
+ return "FIFO";
+
+ case SCHED_RR:
+ return "RR";
+ }
+
+ return "<unknown>";
+}
+#endif
+
+/******************************************************************************/
+
+static void
+direct_thread_cleanup( void *arg )
+{
+ DirectThread *thread = arg;
+
+ D_MAGIC_ASSERT( thread, DirectThread );
+
+ D_DEBUG_AT( Direct_Thread, "%s( %p, '%s' %d )\n", __FUNCTION__, thread->main, thread->name, thread->tid );
+
+ if (thread->detached) {
+ D_MAGIC_CLEAR( thread );
+
+ D_FREE( thread->name );
+ D_FREE( thread );
+ }
+}
+
+/******************************************************************************/
+
+static void *
+direct_thread_main( void *arg )
+{
+ void *ret;
+ DirectThread *thread = arg;
+ DirectThreadInitHandler *handler;
+ pid_t tid;
+
+ tid = direct_gettid();
+
+ D_DEBUG_AT( Direct_ThreadInit, "%s( %p ) <- tid %d\n", __FUNCTION__, arg, tid );
+
+ D_DEBUG_AT( Direct_ThreadInit, " -> starting...\n" );
+
+ D_MAGIC_ASSERT( thread, DirectThread );
+
+ pthread_cleanup_push( direct_thread_cleanup, thread );
+
+
+ pthread_setspecific( thread_key, thread );
+
+ thread->tid = tid;
+
+
+ /* Call all init handlers. */
+ pthread_mutex_lock( &handler_lock );
+
+ direct_list_foreach (handler, handlers)
+ handler->func( thread, handler->arg );
+
+ pthread_mutex_unlock( &handler_lock );
+
+
+ /* Have all signals handled by the main thread. */
+ if (direct_config->thread_block_signals)
+ direct_signals_block_all();
+
+ /* Lock the thread mutex. */
+ D_DEBUG_AT( Direct_ThreadInit, " -> locking...\n" );
+ pthread_mutex_lock( &thread->lock );
+
+ /* Indicate that our initialization has completed. */
+ thread->init = true;
+
+#ifdef DIRECT_THREAD_WAIT_INIT
+ D_DEBUG_AT( Direct_ThreadInit, " -> signalling...\n" );
+ pthread_cond_signal( &thread->cond );
+#endif
+
+ /* Unlock the thread mutex. */
+ D_DEBUG_AT( Direct_ThreadInit, " -> unlocking...\n" );
+ pthread_mutex_unlock( &thread->lock );
+
+ if (thread->joining) {
+ D_DEBUG_AT( Direct_Thread, " -> Being joined before entering main routine!\n" );
+ return NULL;
+ }
+
+ D_MAGIC_ASSERT( thread, DirectThread );
+
+ /* Call main routine. */
+ D_DEBUG_AT( Direct_ThreadInit, " -> running...\n" );
+ ret = thread->main( thread, thread->arg );
+
+ D_DEBUG_AT( Direct_Thread, " -> Returning %p from '%s' (%s, %d)...\n",
+ ret, thread->name, direct_thread_type_name(thread->type), thread->tid );
+
+ D_MAGIC_ASSERT( thread, DirectThread );
+
+ pthread_cleanup_pop( 1 );
+
+ return ret;
+}
+
diff --git a/Source/DirectFB/lib/direct/thread.h b/Source/DirectFB/lib/direct/thread.h
new file mode 100755
index 0000000..18205c4
--- /dev/null
+++ b/Source/DirectFB/lib/direct/thread.h
@@ -0,0 +1,168 @@
+/*
+ (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 __DIRECT__THREAD_H__
+#define __DIRECT__THREAD_H__
+
+#include <sys/types.h>
+
+#include <direct/types.h>
+#include <direct/conf.h>
+
+typedef enum {
+ DTT_DEFAULT = 0,
+ DTT_CLEANUP = -5,
+ DTT_INPUT = -10,
+ DTT_OUTPUT = -12,
+ DTT_MESSAGING = -15,
+ DTT_CRITICAL = -20
+} DirectThreadType;
+
+typedef void * (*DirectThreadMainFunc)( DirectThread *thread, void *arg );
+
+typedef void (*DirectThreadInitFunc)( DirectThread *thread, void *arg );
+
+
+/*
+ * Add a handler being called at the beginning of new threads.
+ */
+DirectThreadInitHandler *direct_thread_add_init_handler ( DirectThreadInitFunc func,
+ void *arg );
+
+/*
+ * Remove the specified handler.
+ */
+void direct_thread_remove_init_handler( DirectThreadInitHandler *handler );
+
+/*
+ * Create a new thread and start it.
+ * The thread type is relevant for the scheduling priority.
+ */
+DirectThread *direct_thread_create ( DirectThreadType thread_type,
+ DirectThreadMainFunc thread_main,
+ void *arg,
+ const char *name );
+
+/*
+ * Returns the thread of the caller.
+ */
+DirectThread *direct_thread_self ( void );
+
+/*
+ * Returns the name of the specified thread.
+ */
+const char *direct_thread_get_name ( DirectThread *thread );
+
+/*
+ * Returns the thread ID of the specified thread.
+ */
+pid_t direct_thread_get_tid ( DirectThread *thread );
+
+/*
+ * Returns the name of the calling thread.
+ */
+const char *direct_thread_self_name ( void );
+
+/*
+ * Changes the name of the calling thread.
+ */
+void direct_thread_set_name ( const char *name );
+
+/*
+ * Wait on the thread object to be notified via direct_thread_notify().
+ */
+DirectResult direct_thread_wait ( DirectThread *thread,
+ int timeout_ms );
+
+/*
+ * Notify the thread object waking up callers of direct_thread_wait().
+ */
+void direct_thread_notify ( DirectThread *thread );
+
+void direct_thread_lock ( DirectThread *thread );
+void direct_thread_unlock ( DirectThread *thread );
+
+/*
+ * Kindly ask the thread to terminate (for joining without thread cancellation).
+ */
+void direct_thread_terminate ( DirectThread *thread );
+
+/*
+ * Cancel a running thread.
+ */
+void direct_thread_cancel ( DirectThread *thread );
+
+/*
+ * Returns true if the specified thread has been canceled.
+ */
+bool direct_thread_is_canceled( DirectThread *thread );
+
+/*
+ * Detach a thread.
+ */
+void direct_thread_detach ( DirectThread *thread );
+
+/*
+ * Returns true if the specified thread has been detached.
+ */
+bool direct_thread_is_detached( DirectThread *thread );
+
+/*
+ * Check if the calling thread is canceled.
+ * Must not be called by other threads than 'thread'.
+ * This function won't return if the thread is canceled.
+ */
+void direct_thread_testcancel ( DirectThread *thread );
+
+/*
+ * Wait until a running thread is terminated.
+ */
+void direct_thread_join ( DirectThread *thread );
+
+/*
+ * Returns true if the specified thread has been join.
+ */
+bool direct_thread_is_joined ( DirectThread *thread );
+
+/*
+ * Free resources allocated by direct_thread_create.
+ * If the thread is still running it will be killed.
+ */
+void direct_thread_destroy ( DirectThread *thread );
+
+/*
+ * Utilities for stringification.
+ */
+#if DIRECT_BUILD_TEXT
+const char *direct_thread_type_name ( DirectThreadType type );
+const char *direct_thread_scheduler_name( DirectConfigThreadScheduler scheduler );
+const char *direct_thread_policy_name ( int policy );
+#endif
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/trace.c b/Source/DirectFB/lib/direct/trace.c
new file mode 100755
index 0000000..d895333
--- /dev/null
+++ b/Source/DirectFB/lib/direct/trace.c
@@ -0,0 +1,676 @@
+/*
+ (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 <pthread.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <direct/build.h>
+#include <direct/list.h>
+#include <direct/log.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/system.h>
+#include <direct/thread.h>
+#include <direct/trace.h>
+#include <direct/util.h>
+
+
+#ifdef PIC
+#define DYNAMIC_LINKING
+#endif
+
+
+#if DIRECT_BUILD_TRACE
+
+#ifdef DYNAMIC_LINKING
+#include <dlfcn.h>
+#endif
+
+#define MAX_BUFFERS 200
+#define MAX_LEVEL 200
+
+#define NAME_LEN 92
+
+
+typedef enum {
+ TF_NONE = 0x00000000,
+
+ TF_DEBUG = 0x00000001
+} TraceFlags;
+
+typedef struct {
+ void *addr;
+ TraceFlags flags;
+} Trace;
+
+struct __D_DirectTraceBuffer {
+ pid_t tid;
+ char *name;
+ int level;
+ bool in_trace;
+ Trace trace[MAX_LEVEL];
+};
+
+/**************************************************************************************************/
+
+static DirectTraceBuffer *buffers[MAX_BUFFERS];
+static int buffers_num = 0;
+static pthread_mutex_t buffers_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_key_t trace_key = -1;
+
+/**************************************************************************************************/
+
+__attribute__((no_instrument_function))
+static void
+buffer_destroy( void *arg )
+{
+ int i;
+ DirectTraceBuffer *buffer = arg;
+
+ pthread_mutex_lock( &buffers_lock );
+
+ /* Remove from list. */
+ for (i=0; i<buffers_num; i++) {
+ if (buffers[i] == buffer)
+ break;
+ }
+
+ for (; i<buffers_num-1; i++)
+ buffers[i] = buffers[i+1];
+
+ buffers_num--;
+
+ /* Deallocate the buffer. */
+ direct_trace_free_buffer( buffer );
+
+ pthread_mutex_unlock( &buffers_lock );
+}
+
+__attribute__((no_instrument_function))
+static inline DirectTraceBuffer *
+get_trace_buffer( void )
+{
+ DirectTraceBuffer *buffer;
+
+ buffer = pthread_getspecific( trace_key );
+ if (!buffer) {
+ const char *name = direct_thread_self_name();
+
+ pthread_mutex_lock( &buffers_lock );
+
+ if (!buffers_num)
+ pthread_key_create( &trace_key, buffer_destroy );
+ else if (buffers_num == MAX_BUFFERS) {
+ D_ERROR( "Direct/Trace: Maximum number of threads (%d) reached!\n", MAX_BUFFERS );
+ pthread_mutex_unlock( &buffers_lock );
+ return NULL;
+ }
+
+ pthread_setspecific( trace_key,
+ buffer = calloc( 1, sizeof(DirectTraceBuffer) ) );
+
+ buffer->tid = direct_gettid();
+ buffer->name = name ? strdup( name ) : NULL;
+
+ buffers[buffers_num++] = buffer;
+
+ pthread_mutex_unlock( &buffers_lock );
+ }
+
+ return buffer;
+}
+
+/**************************************************************************************************/
+
+typedef struct {
+ long offset;
+ char name[NAME_LEN];
+} Symbol;
+
+typedef struct {
+ DirectLink link;
+
+ char *filename;
+ Symbol *symbols;
+ int capacity;
+ int num_symbols;
+} SymbolTable;
+
+static DirectLink *tables = NULL;
+static pthread_mutex_t tables_lock = PTHREAD_MUTEX_INITIALIZER;
+
+
+__attribute__((no_instrument_function))
+static void
+add_symbol( SymbolTable *table, long offset, const char *name )
+{
+ Symbol *symbol;
+
+ if (table->num_symbols == table->capacity) {
+ Symbol *symbols;
+ int capacity = table->capacity * 2;
+
+ if (!capacity)
+ capacity = 256;
+
+ symbols = malloc( capacity * sizeof(Symbol) );
+ if (!symbols) {
+ D_WARN( "out of memory" );
+ return;
+ }
+
+ direct_memcpy( symbols, table->symbols, table->num_symbols * sizeof(Symbol) );
+
+ free( table->symbols );
+
+ table->symbols = symbols;
+ table->capacity = capacity;
+ }
+
+ symbol = &table->symbols[ table->num_symbols++ ];
+
+ symbol->offset = offset;
+
+ direct_snputs( symbol->name, name, NAME_LEN );
+}
+
+__attribute__((no_instrument_function))
+static SymbolTable *
+load_symbols( const char *filename )
+{
+ SymbolTable *table;
+ FILE *fp = NULL;
+ bool is_pipe = false;
+ char file[1024];
+ char line[1024];
+ int command_len;
+ char *command;
+ const char *full_path = filename;
+ char *tmp;
+
+ if (filename) {
+ if (access( filename, R_OK ) < 0 && errno == ENOENT) {
+ int len;
+
+ if ((len = readlink( "/proc/self/exe", file, sizeof(file) - 1 )) < 0) {
+ D_PERROR( "Direct/Trace: readlink( \"/proc/self/exe\" ) failed!\n" );
+ return NULL;
+ }
+
+ file[len] = 0;
+
+
+ tmp = strrchr( file, '/' );
+ if (!tmp)
+ return NULL;
+
+ if (strcmp( filename, tmp + 1 ))
+ return NULL;
+
+ full_path = file;
+ }
+ }
+ else {
+ int len;
+
+ if ((len = readlink( "/proc/self/exe", file, sizeof(file) - 1 )) < 0) {
+ D_PERROR( "Direct/Trace: readlink( \"/proc/self/exe\" ) failed!\n" );
+ return NULL;
+ }
+
+ file[len] = 0;
+
+ full_path = file;
+ }
+
+ command_len = strlen( full_path ) + 32;
+ command = alloca( command_len );
+
+ /* First check if there's an "nm-n" file. */
+ tmp = strrchr( full_path, '/' );
+ if (!tmp)
+ return NULL;
+
+ *tmp = 0;
+ snprintf( command, command_len, "%s/nm-n.%s", full_path, tmp + 1 );
+ *tmp = '/';
+
+ if (access( command, R_OK ) == 0) {
+ fp = fopen( command, "r" );
+ if (!fp)
+ D_PERROR( "Direct/Trace: fopen( \"%s\", \"r\" ) failed!\n", command );
+ }
+ else {
+ snprintf( command, command_len, "%s.nm", full_path );
+ if (access( command, R_OK ) == 0) {
+ fp = fopen( command, "r" );
+ if (!fp)
+ D_PERROR( "Direct/Trace: fopen( \"%s\", \"r\" ) failed!\n", command );
+ }
+ }
+
+ /* Fallback to live mode. */
+ if (!fp) {
+ snprintf( command, command_len, "nm -n %s", full_path );
+
+ fp = popen( command, "r" );
+ if (!fp) {
+ D_PERROR( "Direct/Trace: popen( \"%s\", \"r\" ) failed!\n", command );
+ return NULL;
+ }
+
+ is_pipe = true;
+ }
+
+ table = calloc( 1, sizeof(SymbolTable) );
+ if (!table) {
+ D_OOM();
+ goto out;
+ }
+
+ if (filename)
+ table->filename = strdup( filename );
+
+ while (fgets( line, sizeof(line), fp )) {
+ int n;
+ int digits = sizeof(long) * 2;
+ long offset = 0;
+ int length = strlen(line);
+
+ if (line[0] == ' ' || length < (digits + 5) || line[length-1] != '\n')
+ continue;
+
+ if (line[digits + 1] != 't' && line[digits + 1] != 'T' && line[digits + 1] != 'W')
+ continue;
+
+ if (line[digits] != ' ' || line[digits + 2] != ' ' || line[digits + 3] == '.')
+ continue;
+
+ for (n=0; n<digits; n++) {
+ char c = line[n];
+
+ offset <<= 4;
+
+ if (c >= '0' && c <= '9')
+ offset |= c - '0';
+ else
+ offset |= c - 'a' + 10;
+ }
+
+ line[length-1] = 0;
+
+ add_symbol( table, offset, line + digits + 3 );
+ }
+
+out:
+ if (is_pipe)
+ pclose( fp );
+ else
+ fclose( fp );
+
+ return table;
+}
+
+__attribute__((no_instrument_function))
+static int
+compare_symbols(const void *x, const void *y)
+{
+ return *((const long*) x) - *((const long*) y);
+}
+
+__attribute__((no_instrument_function))
+static SymbolTable *
+find_table( const char *filename )
+{
+ SymbolTable *table;
+
+ if (filename) {
+ direct_list_foreach (table, tables) {
+ if (table->filename && !strcmp( filename, table->filename ))
+ return table;
+ }
+ }
+ else {
+ direct_list_foreach (table, tables) {
+ if (!table->filename)
+ return table;
+ }
+ }
+
+ return NULL;
+}
+
+/**************************************************************************************************/
+
+__attribute__((no_instrument_function))
+const char *
+direct_trace_lookup_symbol( const char *filename, long offset )
+{
+ Symbol *symbol;
+ SymbolTable *table;
+
+ pthread_mutex_lock( &tables_lock );
+
+ table = find_table( filename );
+ if (!table) {
+ table = load_symbols( filename );
+ if (!table) {
+ pthread_mutex_unlock( &tables_lock );
+ return false;
+ }
+
+ direct_list_prepend( &tables, &table->link );
+ }
+
+ pthread_mutex_unlock( &tables_lock );
+
+ symbol = bsearch( &offset, table->symbols, table->num_symbols,
+ sizeof(Symbol), compare_symbols );
+
+ return symbol ? symbol->name : NULL;
+}
+
+__attribute__((no_instrument_function))
+const char *
+direct_trace_lookup_file( void *address, void **ret_base )
+{
+#ifdef DYNAMIC_LINKING
+ Dl_info info;
+
+ if (dladdr( address, &info )) {
+ if (ret_base)
+ *ret_base = info.dli_fbase;
+
+ return info.dli_fname;
+ }
+ else
+#endif
+ {
+ if (ret_base)
+ *ret_base = NULL;
+ }
+
+ return NULL;
+}
+
+__attribute__((no_instrument_function))
+void
+direct_trace_print_stack( DirectTraceBuffer *buffer )
+{
+#ifdef DYNAMIC_LINKING
+ Dl_info info;
+#endif
+ int i;
+ int level;
+
+ if (!direct_config->trace)
+ return;
+
+ if (!buffer)
+ buffer = get_trace_buffer();
+
+ if (buffer->in_trace)
+ return;
+
+ buffer->in_trace = true;
+
+
+ level = buffer->level;
+ if (level > MAX_LEVEL) {
+ D_WARN( "only showing %d of %d items", MAX_LEVEL, level );
+ level = MAX_LEVEL;
+ }
+ else if (level == 0) {
+ buffer->in_trace = false;
+ return;
+ }
+
+ direct_log_lock( NULL );
+
+ if (buffer->name)
+ direct_log_printf( NULL, "(-) [%5d: -STACK- '%s']\n", buffer->tid, buffer->name );
+ else
+ direct_log_printf( NULL, "(-) [%5d: -STACK- ]\n", buffer->tid );
+
+ for (i=level-1; i>=0; i--) {
+ void *fn = buffer->trace[i].addr;
+
+#ifdef DYNAMIC_LINKING
+ if (dladdr( fn, &info )) {
+ if (info.dli_fname) {
+ const char *symbol = NULL;//info.dli_sname;
+
+ if (!symbol) {
+ symbol = direct_trace_lookup_symbol(info.dli_fname, (long)(fn - info.dli_fbase));
+ if (!symbol) {
+ symbol = direct_trace_lookup_symbol(info.dli_fname, (long)(fn));
+ if (!symbol) {
+ if (info.dli_sname)
+ symbol = info.dli_sname;
+ else
+ symbol = "??";
+ }
+ }
+ }
+
+ direct_log_printf( NULL, " #%-2d 0x%08lx in %s () from %s [%p]\n",
+ level - i - 1, (unsigned long) fn, symbol, info.dli_fname, info.dli_fbase );
+ }
+ else if (info.dli_sname) {
+ direct_log_printf( NULL, " #%-2d 0x%08lx in %s ()\n",
+ level - i - 1, (unsigned long) fn, info.dli_sname );
+ }
+ else
+ direct_log_printf( NULL, " #%-2d 0x%08lx in ?? ()\n",
+ level - i - 1, (unsigned long) fn );
+ }
+ else
+#endif
+ {
+ const char *symbol = direct_trace_lookup_symbol(NULL, (long)(fn));
+ direct_log_printf( NULL, " #%-2d 0x%08lx in %s ()\n",
+ level - i - 1, (unsigned long) fn, symbol ? symbol : "??" );
+ }
+ }
+
+ direct_log_printf( NULL, "\n" );
+ direct_log_unlock( NULL );
+
+ buffer->in_trace = false;
+}
+
+__attribute__((no_instrument_function))
+void
+direct_trace_print_stacks( void )
+{
+ int i;
+ DirectTraceBuffer *buffer = get_trace_buffer();
+
+ if (buffer->level)
+ direct_trace_print_stack( buffer );
+
+ pthread_mutex_lock( &buffers_lock );
+
+ for (i=0; i<buffers_num; i++) {
+ if (buffers[i] != buffer && buffers[i]->level)
+ direct_trace_print_stack( buffers[i] );
+ }
+
+ pthread_mutex_unlock( &buffers_lock );
+}
+
+__attribute__((no_instrument_function))
+int
+direct_trace_debug_indent( void )
+{
+ int in;
+ DirectTraceBuffer *buffer = get_trace_buffer();
+ int level = buffer->level - 1;
+
+ if (level < 0)
+ return 0;
+
+ buffer->trace[level--].flags |= TF_DEBUG;
+
+ for (in=0; level>=0; level--) {
+ if (buffer->trace[level].flags & TF_DEBUG)
+ in++;
+ }
+
+ return in;
+}
+
+__attribute__((no_instrument_function))
+DirectTraceBuffer *
+direct_trace_copy_buffer( DirectTraceBuffer *buffer )
+{
+ int level;
+ DirectTraceBuffer *copy;
+
+ if (!buffer)
+ buffer = get_trace_buffer();
+
+ level = buffer->level;
+ if (level > MAX_LEVEL) {
+ D_WARN( "only copying %d of %d items", MAX_LEVEL, level );
+ level = MAX_LEVEL;
+ }
+
+ copy = calloc( 1, sizeof(*buffer) - sizeof(buffer->trace) + sizeof(buffer->trace[0]) * level );
+ if (!copy)
+ return NULL;
+
+ if (buffer->name)
+ copy->name = strdup( buffer->name );
+
+ copy->tid = buffer->tid;
+ copy->level = buffer->level;
+
+ direct_memcpy( copy->trace, buffer->trace, level * sizeof(buffer->trace[0]) );
+
+ return copy;
+}
+
+__attribute__((no_instrument_function))
+void
+direct_trace_free_buffer( DirectTraceBuffer *buffer )
+{
+ if (buffer->name)
+ free( buffer->name );
+
+ free( buffer );
+}
+
+/**************************************************************************************************/
+
+__attribute__((no_instrument_function))
+void
+__cyg_profile_func_enter (void *this_fn,
+ void *call_site)
+{
+ if (direct_config->trace) {
+ DirectTraceBuffer *buffer = get_trace_buffer();
+ int level = buffer->level++;
+ Trace *trace = &buffer->trace[level];
+
+ if (level < MAX_LEVEL) {
+ trace->addr = this_fn;
+ trace->flags = TF_NONE;
+ }
+ }
+}
+
+__attribute__((no_instrument_function))
+void
+__cyg_profile_func_exit (void *this_fn,
+ void *call_site)
+{
+ if (direct_config->trace) {
+ DirectTraceBuffer *buffer = get_trace_buffer();
+
+ if (buffer->level > 0)
+ buffer->level--;
+ }
+}
+
+#else
+
+const char *
+direct_trace_lookup_symbol( const char *filename, long offset )
+{
+ return NULL;
+}
+
+const char *
+direct_trace_lookup_file( void *address, void **ret_base )
+{
+ if (ret_base)
+ *ret_base = NULL;
+
+ return NULL;
+}
+
+void
+direct_trace_print_stack( DirectTraceBuffer *buffer )
+{
+}
+
+void
+direct_trace_print_stacks( void )
+{
+}
+
+int
+direct_trace_debug_indent( void )
+{
+ return 0;
+}
+
+DirectTraceBuffer *
+direct_trace_copy_buffer( DirectTraceBuffer *buffer )
+{
+ return NULL;
+}
+
+void
+direct_trace_free_buffer( DirectTraceBuffer *buffer )
+{
+}
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/trace.h b/Source/DirectFB/lib/direct/trace.h
new file mode 100755
index 0000000..2975522
--- /dev/null
+++ b/Source/DirectFB/lib/direct/trace.h
@@ -0,0 +1,98 @@
+/*
+ (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 __DIRECT__TRACE_H__
+#define __DIRECT__TRACE_H__
+
+#include <direct/types.h>
+
+/***********************************************************************************************************************
+** Symbols
+*/
+
+/*
+ * Returns filename on success or NULL.
+ *
+ * Stores load address of object in 'ret_base' on success.
+ */
+const char *direct_trace_lookup_file ( void *address,
+ void **ret_base );
+
+/*
+ * Look up a symbol by filename and offset.
+ *
+ * Returns symbol name on success or NULL.
+ */
+const char *direct_trace_lookup_symbol( const char *filename,
+ long offset );
+
+/*
+ * Convenience function combining direct_trace_lookup_file() and direct_trace_lookup_symbol().
+ */
+static inline const char *
+direct_trace_lookup_symbol_at( void *address )
+{
+ void *base;
+ const char *filename;
+
+ filename = direct_trace_lookup_file( address, &base );
+
+ return direct_trace_lookup_symbol( filename, (unsigned long) address - (unsigned long) base );
+}
+
+/***********************************************************************************************************************
+** Stacks
+*/
+
+/*
+ * Print stack in 'buffer' or current if NULL.
+ */
+void direct_trace_print_stack( DirectTraceBuffer *buffer );
+
+/*
+ * Print stack of each known thread.
+ */
+void direct_trace_print_stacks( void );
+
+/*
+ * Returns indent level for debug output.
+ */
+int direct_trace_debug_indent( void );
+
+/*
+ * Create a copy of a stack in 'buffer' or of current if NULL.
+ */
+DirectTraceBuffer *direct_trace_copy_buffer( DirectTraceBuffer *buffer );
+
+/*
+ * Free a (copied) stack buffer.
+ */
+void direct_trace_free_buffer( DirectTraceBuffer *buffer );
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/tree.c b/Source/DirectFB/lib/direct/tree.c
new file mode 100755
index 0000000..38aac17
--- /dev/null
+++ b/Source/DirectFB/lib/direct/tree.c
@@ -0,0 +1,307 @@
+/*
+ (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>.
+
+ Balanced binary tree ported from glib-2.0.
+
+ 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 <stdlib.h>
+
+#include <direct/mem.h>
+#include <direct/tree.h>
+
+
+static DirectNode *tree_node_new ( DirectTree *tree,
+ void *key,
+ void *value );
+
+static void tree_node_destroy ( DirectTree *tree,
+ DirectNode *node );
+
+static DirectNode *tree_node_insert ( DirectTree *tree,
+ DirectNode *node,
+ void *key,
+ void *value,
+ int *inserted );
+
+static DirectNode *tree_node_lookup ( DirectNode *node,
+ void *key );
+
+static DirectNode *tree_node_balance ( DirectNode *node );
+
+static DirectNode *tree_node_rotate_left ( DirectNode *node );
+
+static DirectNode *tree_node_rotate_right( DirectNode *node );
+
+
+DirectTree *
+direct_tree_new( void )
+{
+ return D_CALLOC( 1, sizeof (DirectTree) );
+}
+
+void
+direct_tree_destroy( DirectTree *tree )
+{
+ unsigned int i;
+
+ for (i = 0; i < 128; i++) {
+ if (tree->fast_keys[i])
+ D_FREE( tree->fast_keys[i] );
+ }
+
+ tree_node_destroy( tree, tree->root );
+
+ D_FREE( tree );
+}
+
+void
+direct_tree_insert( DirectTree *tree,
+ void *key,
+ void *value )
+{
+ int inserted = 0;
+ unsigned long fast_key = (unsigned long) key;
+
+ if (fast_key < 128)
+ tree->fast_keys[fast_key] = value;
+ else
+ tree->root = tree_node_insert( tree, tree->root, key, value, &inserted );
+}
+
+void *
+direct_tree_lookup( DirectTree *tree,
+ void *key )
+{
+ DirectNode *node;
+ unsigned long fast_key = (unsigned long) key;
+
+ if (fast_key < 128)
+ return tree->fast_keys[fast_key];
+
+ node = tree_node_lookup( tree->root, key );
+
+ return node ? node->value : NULL;
+}
+
+static DirectNode *
+tree_node_new( DirectTree *tree,
+ void *key,
+ void *value )
+{
+ DirectNode *node;
+
+ node = D_MALLOC(sizeof (DirectNode));
+
+ node->balance = 0;
+ node->left = NULL;
+ node->right = NULL;
+ node->key = key;
+ node->value = value;
+
+ return node;
+}
+
+static void
+tree_node_destroy (DirectTree *tree,
+ DirectNode *node)
+{
+ if (node) {
+ tree_node_destroy (tree, node->left);
+ tree_node_destroy (tree, node->right);
+
+ if (node->value)
+ D_FREE(node->value);
+
+ D_FREE(node);
+ }
+}
+
+static DirectNode *
+tree_node_insert (DirectTree *tree,
+ DirectNode *node,
+ void *key,
+ void *value,
+ int *inserted)
+{
+ int cmp;
+ int old_balance;
+
+ if (!node) {
+ *inserted = 1;
+ return tree_node_new (tree, key, value);
+ }
+
+ cmp = key - node->key;
+ if (cmp == 0) {
+ node->value = value;
+ return node;
+ }
+
+ if (cmp < 0) {
+ if (node->left) {
+ old_balance = node->left->balance;
+ node->left = tree_node_insert (tree, node->left,
+ key, value, inserted);
+
+ if ((old_balance != node->left->balance) && node->left->balance)
+ node->balance -= 1;
+ }
+ else {
+ *inserted = 1;
+ node->left = tree_node_new (tree, key, value);
+ node->balance -= 1;
+ }
+ }
+ else if (cmp > 0) {
+ if (node->right) {
+ old_balance = node->right->balance;
+ node->right = tree_node_insert (tree, node->right,
+ key, value, inserted);
+
+ if ((old_balance != node->right->balance) && node->right->balance)
+ node->balance += 1;
+ }
+ else {
+ *inserted = 1;
+ node->right = tree_node_new (tree, key, value);
+ node->balance += 1;
+ }
+ }
+
+ if (*inserted && (node->balance < -1 || node->balance > 1))
+ node = tree_node_balance (node);
+
+ return node;
+}
+
+static DirectNode *
+tree_node_lookup (DirectNode *node,
+ void *key)
+{
+ int cmp;
+
+ if (!node)
+ return NULL;
+
+ cmp = key - node->key;
+ if (cmp == 0)
+ return node;
+
+ if (cmp < 0 && node->left) {
+ return tree_node_lookup (node->left, key);
+ }
+ else if (cmp > 0 && node->right) {
+ return tree_node_lookup (node->right, key);
+ }
+
+ return NULL;
+}
+
+static DirectNode *
+tree_node_balance (DirectNode *node)
+{
+ if (node->balance < -1) {
+ if (node->left->balance > 0)
+ node->left = tree_node_rotate_left (node->left);
+ node = tree_node_rotate_right (node);
+ }
+ else if (node->balance > 1) {
+ if (node->right->balance < 0)
+ node->right = tree_node_rotate_right (node->right);
+ node = tree_node_rotate_left (node);
+ }
+
+ return node;
+}
+
+static DirectNode *
+tree_node_rotate_left (DirectNode *node)
+{
+ DirectNode *right;
+ int a_bal;
+ int b_bal;
+
+ right = node->right;
+
+ node->right = right->left;
+ right->left = node;
+
+ a_bal = node->balance;
+ b_bal = right->balance;
+
+ if (b_bal <= 0) {
+ if (a_bal >= 1)
+ right->balance = b_bal - 1;
+ else
+ right->balance = a_bal + b_bal - 2;
+ node->balance = a_bal - 1;
+ }
+ else {
+ if (a_bal <= b_bal)
+ right->balance = a_bal - 2;
+ else
+ right->balance = b_bal - 1;
+ node->balance = a_bal - b_bal - 1;
+ }
+
+ return right;
+}
+
+static DirectNode *
+tree_node_rotate_right (DirectNode *node)
+{
+ DirectNode *left;
+ int a_bal;
+ int b_bal;
+
+ left = node->left;
+
+ node->left = left->right;
+ left->right = node;
+
+ a_bal = node->balance;
+ b_bal = left->balance;
+
+ if (b_bal <= 0) {
+ if (b_bal > a_bal)
+ left->balance = b_bal + 1;
+ else
+ left->balance = a_bal + 2;
+ node->balance = a_bal - b_bal + 1;
+ }
+ else {
+ if (a_bal <= -1)
+ left->balance = b_bal + 1;
+ else
+ left->balance = a_bal + b_bal + 2;
+ node->balance = a_bal + 1;
+ }
+
+ return left;
+}
diff --git a/Source/DirectFB/lib/direct/tree.h b/Source/DirectFB/lib/direct/tree.h
new file mode 100755
index 0000000..165ed1c
--- /dev/null
+++ b/Source/DirectFB/lib/direct/tree.h
@@ -0,0 +1,67 @@
+/*
+ (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>.
+
+ Balanced binary tree ported from glib by Sven Neumann
+ <sven@convergence.de>.
+
+ 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__TREE_H__
+#define __DIRECT__TREE_H__
+
+#include <direct/types.h>
+
+
+typedef struct __D_DirectNode DirectNode;
+
+struct __D_DirectTree
+{
+ DirectNode *root;
+ void *fast_keys[128];
+};
+
+struct __D_DirectNode
+{
+ int balance;
+ DirectNode *left;
+ DirectNode *right;
+ void *key;
+ void *value;
+};
+
+
+DirectTree *direct_tree_new ( void );
+
+void direct_tree_destroy( DirectTree *tree );
+
+void direct_tree_insert ( DirectTree *tree,
+ void *key,
+ void *value );
+
+void *direct_tree_lookup ( DirectTree *tree,
+ void *key );
+
+#endif
diff --git a/Source/DirectFB/lib/direct/types.h b/Source/DirectFB/lib/direct/types.h
new file mode 100755
index 0000000..2677e00
--- /dev/null
+++ b/Source/DirectFB/lib/direct/types.h
@@ -0,0 +1,169 @@
+/*
+ (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 __DIRECT__TYPES_H__
+#define __DIRECT__TYPES_H__
+
+#include <direct/build.h>
+
+/*
+ * Define the bool type by including stdbool.h (preferably)...
+ */
+#if DIRECT_BUILD_STDBOOL
+# include <stdbool.h>
+/*
+ * ...or defining it ourself, if not using C++ or another definition
+ */
+#elif !defined(__cplusplus) && !defined(__bool_true_false_are_defined)
+# warning Fallback definition of bool using u8! Checking for 'flags & 0x100' or higher bits will be false :(
+ typedef u8 bool;
+# ifndef false
+# define false (0)
+# endif
+# ifndef true
+# define true (!false)
+# endif
+#endif /* DIRECT_BUILD_STDBOOL */
+
+
+#ifdef USE_KOS
+
+#include <sys/types.h>
+
+typedef uint8 u8;
+typedef uint16 u16;
+typedef uint32 u32;
+typedef uint64 u64;
+
+typedef sint8 s8;
+typedef sint16 s16;
+typedef sint32 s32;
+typedef sint64 s64;
+
+#else
+
+#include <stdint.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+#endif
+
+
+typedef enum {
+ DR_OK = 0x00000000, /* No error occured. */
+ DR_FAILURE, /* A general or unknown error occured. */
+ DR_INIT, /* A general initialization error occured. */
+ DR_BUG, /* Internal bug or inconsistency has been detected. */
+ DR_DEAD, /* Interface has a zero reference counter (available in debug mode). */
+ DR_UNSUPPORTED, /* The requested operation or an argument is (currently) not supported. */
+ DR_UNIMPLEMENTED, /* The requested operation is not implemented, yet. */
+ DR_ACCESSDENIED, /* Access to the resource is denied. */
+ DR_INVAREA, /* An invalid area has been specified or detected. */
+ DR_INVARG, /* An invalid argument has been specified. */
+ DR_NOLOCALMEMORY, /* There's not enough local system memory. */
+ DR_NOSHAREDMEMORY, /* There's not enough shared system memory. */
+ DR_LOCKED, /* The resource is (already) locked. */
+ DR_BUFFEREMPTY, /* The buffer is empty. */
+ DR_FILENOTFOUND, /* The specified file has not been found. */
+ DR_IO, /* A general I/O error occured. */
+ DR_BUSY, /* The resource or device is busy. */
+ DR_NOIMPL, /* No implementation for this interface or content type has been found. */
+ DR_TIMEOUT, /* The operation timed out. */
+ DR_THIZNULL, /* 'thiz' pointer is NULL. */
+ DR_IDNOTFOUND, /* No resource has been found by the specified id. */
+ DR_DESTROYED, /* The requested object has been destroyed. */
+ DR_FUSION, /* Internal fusion error detected, most likely related to IPC resources. */
+ DR_BUFFERTOOLARGE, /* Buffer is too large. */
+ DR_INTERRUPTED, /* The operation has been interrupted. */
+ DR_NOCONTEXT, /* No context available. */
+ DR_TEMPUNAVAIL, /* Temporarily unavailable. */
+ DR_LIMITEXCEEDED, /* Attempted to exceed limit, i.e. any kind of maximum size, count etc. */
+ DR_NOSUCHMETHOD, /* Requested method is not known. */
+ DR_NOSUCHINSTANCE, /* Requested instance is not known. */
+ DR_ITEMNOTFOUND, /* No such item found. */
+ DR_VERSIONMISMATCH, /* Some versions didn't match. */
+ DR_EOF, /* Reached end of file. */
+ DR_SUSPENDED, /* The requested object is suspended. */
+ DR_INCOMPLETE, /* The operation has been executed, but not completely. */
+ DR_NOCORE /* Core part not available. */
+} DirectResult;
+
+/*
+ * Generate result code base for API 'A','B','C', e.g. 'D','F','B'.
+ */
+#define D_RESULT_TYPE_BASE( a,b,c ) ((((unsigned)(a)&0x7f) * 0x02000000) + \
+ (((unsigned)(b)&0x7f) * 0x00040000) + \
+ (((unsigned)(c)&0x7f) * 0x00000800))
+
+/*
+ * Generate result code maximum for API 'A','B','C', e.g. 'D','F','B'.
+ */
+#define D_RESULT_TYPE_MAX( a,b,c ) (D_RESULT_TYPE_BASE(a,b,c) + 0x7ff)
+
+/*
+ * Check if given result code belongs to API 'A','B','C', e.g. 'D','F','B'.
+ */
+#define D_RESULT_TYPE_IS( code,a,b,c ) ((code) >= D_RESULT_TYPE_BASE(a,b,c) && (code) <= D_RESULT_TYPE_MAX(a,b,c))
+
+
+/*
+ * Return value of enumeration callbacks
+ */
+typedef enum {
+ DENUM_OK = 0x00000000, /* Proceed with enumeration */
+ DENUM_CANCEL = 0x00000001 /* Cancel enumeration */
+} DirectEnumerationResult;
+
+
+typedef u32 unichar;
+
+typedef struct __D_DirectCleanupHandler DirectCleanupHandler;
+typedef struct __D_DirectConfig DirectConfig;
+typedef struct __D_DirectHash DirectHash;
+typedef struct __D_DirectLink DirectLink;
+typedef struct __D_DirectLog DirectLog;
+typedef struct __D_DirectModuleDir DirectModuleDir;
+typedef struct __D_DirectModuleEntry DirectModuleEntry;
+typedef struct __D_DirectSerial DirectSerial;
+typedef struct __D_DirectSignalHandler DirectSignalHandler;
+typedef struct __D_DirectStream DirectStream;
+typedef struct __D_DirectTraceBuffer DirectTraceBuffer;
+typedef struct __D_DirectTree DirectTree;
+typedef struct __D_DirectThread DirectThread;
+typedef struct __D_DirectThreadInitHandler DirectThreadInitHandler;
+
+#endif
+
diff --git a/Source/DirectFB/lib/direct/utf8.c b/Source/DirectFB/lib/direct/utf8.c
new file mode 100755
index 0000000..75896da
--- /dev/null
+++ b/Source/DirectFB/lib/direct/utf8.c
@@ -0,0 +1,36 @@
+/*
+ (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>.
+
+ UTF8 routines ported from glib-2.0 and optimized
+
+ 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/utf8.h>
+
+
+
diff --git a/Source/DirectFB/lib/direct/utf8.h b/Source/DirectFB/lib/direct/utf8.h
new file mode 100755
index 0000000..a073c65
--- /dev/null
+++ b/Source/DirectFB/lib/direct/utf8.h
@@ -0,0 +1,80 @@
+/*
+ (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>.
+
+ UTF8 routines ported from glib-2.0 and optimized
+
+ 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__UTF8_H__
+#define __DIRECT__UTF8_H__
+
+#include <direct/types.h>
+
+
+#define DIRECT_UTF8_SKIP(c) (((u8)(c) < 0xc0) ? 1 : __direct_utf8_skip[(u8)(c)&0x3f])
+
+#define DIRECT_UTF8_GET_CHAR(p) (*(const u8*)(p) < 0xc0 ? \
+ *(const u8*)(p) : __direct_utf8_get_char((const u8*)(p)))
+
+
+/*
+ * Actually the last two fields used to be zero since they indicate an
+ * invalid UTF-8 string. Changed it to 1 to avoid endless looping on
+ * invalid input.
+ */
+static const char __direct_utf8_skip[64] = {
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
+};
+
+static __inline__ unichar __direct_utf8_get_char( const u8 *p )
+{
+ int len;
+ register unichar result = p[0];
+
+ if (result < 0xc0)
+ return result;
+
+ if (result > 0xfd)
+ return (unichar) -1;
+
+ len = __direct_utf8_skip[result & 0x3f];
+
+ result &= 0x7c >> len;
+
+ while (--len) {
+ int c = *(++p);
+
+ if ((c & 0xc0) != 0x80)
+ return (unichar) -1;
+
+ result = (result << 6) | (c & 0x3f);
+ }
+
+ return result;
+}
+
+#endif
diff --git a/Source/DirectFB/lib/direct/util.c b/Source/DirectFB/lib/direct/util.c
new file mode 100755
index 0000000..9e7a03a
--- /dev/null
+++ b/Source/DirectFB/lib/direct/util.c
@@ -0,0 +1,519 @@
+/*
+ (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 <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+#include <direct/clock.h>
+
+#ifdef CLOCK_MONOTONIC
+#include <sys/syscall.h>
+#endif
+
+static int no_monotonic_pthread_clock;
+
+/*
+ * translates errno to DirectResult
+ */
+DirectResult
+errno2result( int erno )
+{
+ switch (erno) {
+ case 0:
+ return DR_OK;
+ case ENOENT:
+ return DR_FILENOTFOUND;
+ case EACCES:
+ case EPERM:
+ return DR_ACCESSDENIED;
+ case EBUSY:
+ case EAGAIN:
+ return DR_BUSY;
+ case ECONNREFUSED:
+ return DR_ACCESSDENIED;
+ case ENODEV:
+ case ENXIO:
+#ifdef ENOTSUP
+ /* ENOTSUP is not defined on NetBSD */
+ case ENOTSUP:
+#endif
+ return DR_UNSUPPORTED;
+ }
+
+ return DR_FAILURE;
+}
+
+const char *
+DirectResultString( DirectResult result )
+{
+ if (!D_RESULT_TYPE_IS( result, 0, 0, 0 ))
+ return "UNKNOWN RESULT CODE TYPE!";
+
+ switch (result) {
+ case DR_OK:
+ return "OK";
+ case DR_FAILURE:
+ return "General failure!";
+ case DR_INIT:
+ return "Initialization error!";
+ case DR_BUG:
+ return "Internal bug!";
+ case DR_DEAD:
+ return "Interface was released!";
+ case DR_UNSUPPORTED:
+ return "Not supported!";
+ case DR_UNIMPLEMENTED:
+ return "Not implemented!";
+ case DR_ACCESSDENIED:
+ return "Access denied!";
+ case DR_INVARG:
+ return "Invalid argument!";
+ case DR_NOLOCALMEMORY:
+ return "Out of memory!";
+ case DR_LOCKED:
+ return "Resource is locked!";
+ case DR_BUFFEREMPTY:
+ return "Buffer is empty!";
+ case DR_FILENOTFOUND:
+ return "File not found!";
+ case DR_IO:
+ return "General I/O error!";
+ case DR_NOIMPL:
+ return "No (suitable) implementation found!";
+ case DR_TIMEOUT:
+ return "Operation timed out!";
+ case DR_BUSY:
+ return "Resource is busy!";
+ case DR_THIZNULL:
+ return "'thiz' argument is NULL!";
+ case DR_IDNOTFOUND:
+ return "Requested ID not found!";
+ case DR_INVAREA:
+ return "Invalid area present!";
+ case DR_DESTROYED:
+ return "Resource was destroyed!";
+ case DR_FUSION:
+ return "Fusion IPC error detected!";
+ case DR_BUFFERTOOLARGE:
+ return "Buffer is too large!";
+ case DR_INTERRUPTED:
+ return "Operation has been interrupted!";
+ case DR_NOCONTEXT:
+ return "No context available!";
+ case DR_TEMPUNAVAIL:
+ return "Resource temporarily unavailable!";
+ case DR_LIMITEXCEEDED:
+ return "Limit has been exceeded!";
+ case DR_NOSUCHMETHOD:
+ return "No such (remote) method!";
+ case DR_NOSUCHINSTANCE:
+ return "No such (remote) instance!";
+ case DR_ITEMNOTFOUND:
+ return "Appropriate item not found!";
+ case DR_VERSIONMISMATCH:
+ return "Some versions didn't match!";
+ case DR_NOSHAREDMEMORY:
+ return "Out of shared memory!";
+ case DR_EOF:
+ return "End of file!";
+ case DR_SUSPENDED:
+ return "Object is suspended!";
+ case DR_INCOMPLETE:
+ return "Operation incomplete!";
+ case DR_NOCORE:
+ return "No core (loaded)!";
+ default:
+ break;
+ }
+
+ return "UNKNOWN RESULT CODE!";
+}
+
+int
+direct_safe_dup( int fd )
+{
+ int n = 0;
+ int fc[3];
+
+ while (fd >= 0 && fd <= 2) {
+ fc[n++] = fd;
+ fd = dup (fd);
+ }
+
+ while (n)
+ close (fc[--n]);
+
+ return fd;
+}
+
+int
+direct_try_open( const char *name1, const char *name2, int flags, bool error_msg )
+{
+ int fd;
+
+ fd = open (name1, flags);
+ if (fd >= 0)
+ return direct_safe_dup (fd);
+
+ if (errno != ENOENT) {
+ if (error_msg)
+ D_PERROR( "Direct/Util: opening '%s' failed\n", name1 );
+ return -1;
+ }
+
+ fd = open (name2, flags);
+ if (fd >= 0)
+ return direct_safe_dup (fd);
+
+ if (error_msg) {
+ if (errno == ENOENT)
+ D_PERROR( "Direct/Util: opening '%s' and '%s' failed\n", name1, name2 );
+ else
+ D_PERROR( "Direct/Util: opening '%s' failed\n", name2 );
+ }
+
+ return -1;
+}
+
+void
+direct_trim( char **s )
+{
+ int i;
+ int len = strlen( *s );
+
+ for (i = len-1; i >= 0; i--)
+ if ((*s)[i] <= ' ')
+ (*s)[i] = 0;
+ else
+ break;
+
+ while (**s)
+ if (**s <= ' ')
+ (*s)++;
+ else
+ return;
+}
+
+/*
+ * Utility function to initialize recursive mutexes.
+ */
+int
+direct_util_recursive_pthread_mutex_init( pthread_mutex_t *mutex )
+{
+ int ret;
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init( &attr );
+#if HAVE_DECL_PTHREAD_MUTEX_RECURSIVE
+ pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
+#endif
+ ret = pthread_mutex_init( mutex, &attr );
+ if (ret)
+ D_PERROR( "Direct/Lock: Could not initialize recursive mutex!\n" );
+
+ pthread_mutexattr_destroy( &attr );
+
+ return ret;
+}
+
+/*
+ * Utility function to initialize monotonic condition.
+ */
+int
+direct_util_monotonic_pthread_cond_init( pthread_cond_t *cond )
+{
+#if defined(CLOCK_MONOTONIC) && !defined(DIRECT_BUILD_NO_PTHREAD_CONDATTR)
+ int ret;
+ pthread_condattr_t attr;
+
+ struct timespec dummy;
+ pthread_condattr_init( &attr );
+
+ if(!no_monotonic_pthread_clock) {
+ if((syscall( __NR_clock_getres, CLOCK_MONOTONIC, &dummy ) == 0) &&
+ (pthread_condattr_setclock( &attr, CLOCK_MONOTONIC ) == 0))
+ ;
+ else
+ no_monotonic_pthread_clock = 1;
+ }
+
+ ret = pthread_cond_init( cond, &attr );
+ if (ret)
+ D_PERROR( "Direct/Lock: Could not initialize monotonic condition!\n" );
+
+ pthread_condattr_destroy( &attr );
+
+ return ret;
+#else
+ pthread_cond_init( cond, NULL );
+
+ return 0;
+#endif
+}
+
+/*
+ * Utility function to calibrate timeout for monotonic condition.
+ */
+void
+direct_util_get_monotonic_pthread_timeout( struct timespec *timeout,
+ int seconds,
+ int nano_seconds )
+{
+ struct timeval now;
+
+ if(no_monotonic_pthread_clock)
+ gettimeofday( &now, NULL );
+ else
+ direct_monotonic_gettimeofday( &now );
+
+ timeout->tv_sec = now.tv_sec + seconds;
+ timeout->tv_nsec = (now.tv_usec * 1000) + nano_seconds;
+
+ timeout->tv_sec += timeout->tv_nsec / 1000000000;
+ timeout->tv_nsec %= 1000000000;
+}
+
+/*
+ * Encode/Decode Base-64.
+ */
+char*
+direct_base64_encode( const void *data, int size )
+{
+ static const char *enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/=";
+ const unsigned char *src = (const unsigned char*)data;
+ char *ret;
+ char *buf;
+
+ D_ASSERT( data != NULL );
+
+ buf = ret = D_MALLOC( (size + 2) / 3 * 4 + 1 );
+ if (!ret)
+ return NULL;
+
+ for (; size >= 3; size -= 3) {
+ buf[0] = enc[((src[0] & 0xfc) >> 2)];
+ buf[1] = enc[((src[0] & 0x03) << 4) | ((src[1] & 0xf0) >> 4)];
+ buf[2] = enc[((src[1] & 0x0f) << 2) | ((src[2] & 0xc0) >> 6)];
+ buf[3] = enc[((src[2] & 0x3f))];
+ buf += 4;
+ src += 3;
+ }
+
+ if (size > 0) {
+ buf[0] = enc[(src[0] & 0xfc) >> 2];
+
+ if (size > 1) {
+ buf[1] = enc[((src[0] & 0x03) << 4) | ((src[1] & 0xf0) >> 4)];
+ buf[2] = enc[((src[1] & 0x0f) << 2)];
+ } else {
+ buf[1] = enc[(src[0] & 0x03) << 4];
+ buf[2] = '=';
+ }
+
+ buf[3] = '=';
+ buf += 4;
+ }
+
+ *buf = '\0';
+
+ return ret;
+}
+
+void*
+direct_base64_decode( const char *string, int *ret_size )
+{
+ unsigned char dec[256];
+ unsigned char *ret;
+ unsigned char *buf;
+ int len;
+ int i, j;
+
+ D_ASSERT( string != NULL );
+
+ len = strlen( string );
+ buf = ret = D_MALLOC( len * 3 / 4 + 3 );
+ if (!ret)
+ return NULL;
+
+ /* generate decode table */
+ for (i = 0; i < 255; i++)
+ dec[i] = 0x80;
+ for (i = 'A'; i <= 'Z'; i++)
+ dec[i] = 0 + (i - 'A');
+ for (i = 'a'; i <= 'z'; i++)
+ dec[i] = 26 + (i - 'a');
+ for (i = '0'; i <= '9'; i++)
+ dec[i] = 52 + (i - '0');
+ dec['+'] = 62;
+ dec['/'] = 63;
+ dec['='] = 0;
+
+ /* decode */
+ for (j = 0; j < len; j += 4) {
+ unsigned char a[4], b[4];
+
+ for (i = 0; i < 4; i++) {
+ int c = string[i+j];
+ a[i] = c;
+ b[i] = dec[c];
+ }
+
+ *buf++ = (b[0] << 2) | (b[1] >> 4);
+ *buf++ = (b[1] << 4) | (b[2] >> 2);
+ *buf++ = (b[2] << 6) | (b[3] );
+ if (a[2] == '=' || a[3] == '=')
+ break;
+ }
+
+ *buf = '\0';
+
+ if (ret_size)
+ *ret_size = buf - ret;
+
+ return ret;
+}
+
+/*
+ * Compute MD5 sum.
+ */
+static const u8 S[4][4] = {
+ { 7, 12, 17, 22 }, /* Round 1 */
+ { 5, 9, 14, 20 }, /* Round 2 */
+ { 4, 11, 16, 23 }, /* Round 3 */
+ { 6, 10, 15, 21 } /* Round 4 */
+};
+
+static const u32 T[64] = {
+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* Round 1 */
+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+
+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* Round 2 */
+ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, /* Round 3 */
+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+
+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, /* Round 4 */
+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
+};
+
+static void
+md5_hash( u32 ABCD[4], u32 X[16] )
+{
+ u32 a = ABCD[3];
+ u32 b = ABCD[2];
+ u32 c = ABCD[1];
+ u32 d = ABCD[0];
+ int t;
+ int i;
+
+#ifdef WORDS_BIGENDIAN
+ for (i = 0; i < 16; i++)
+ X[i] = BSWAP32(X[i]);
+#endif
+
+ for (i = 0; i < 64; i++) {
+ t = S[i>>4][i&3];
+ a += T[i];
+ switch (i>>4) {
+ case 0: a += (d ^ (b&(c^d))) + X[ i &15]; break;
+ case 1: a += (c ^ (d&(c^b))) + X[(1+5*i)&15]; break;
+ case 2: a += (b^c^d) + X[(5+3*i)&15]; break;
+ case 3: a += (c^(b|~d)) + X[( 7*i)&15]; break;
+ }
+ a = b + ((a << t) | (a >> (32 - t)));
+ t = d; d = c; c = b; b = a; a = t;
+ }
+
+ ABCD[0] += d;
+ ABCD[1] += c;
+ ABCD[2] += b;
+ ABCD[3] += a;
+}
+
+void
+direct_md5_sum( void *dst, const void *src, const int len )
+{
+ u8 block[64];
+ u32 ABCD[4];
+ int i, j;
+
+ D_ASSERT( dst != NULL );
+ D_ASSERT( src != NULL );
+
+ ABCD[0] = 0x10325476;
+ ABCD[1] = 0x98badcfe;
+ ABCD[2] = 0xefcdab89;
+ ABCD[3] = 0x67452301;
+
+ for (i = 0, j = 0; i < len; i++) {
+ block[j++] = ((const u8*)src)[i];
+ if (j == 64) {
+ md5_hash( ABCD, (u32*)block );
+ j = 0;
+ }
+ }
+
+ block[j++] = 0x80;
+ memset( &block[j], 0, 64-j );
+
+ if (j > 56) {
+ md5_hash( ABCD, (u32*)block );
+ memset( block, 0, 64 );
+ }
+
+ for (i = 0; i < 8; i++)
+ block[56+i] = ((u64)len << 3) >> (i << 3);
+
+ md5_hash( ABCD, (u32*)block );
+
+ for (i = 0; i < 4; i++)
+#ifdef WORDS_BIGENDIAN
+ ((u32*)dst)[i] = BSWAP32(ABCD[3-i]);
+#else
+ ((u32*)dst)[i] = ABCD[3-i];
+#endif
+}
diff --git a/Source/DirectFB/lib/direct/util.h b/Source/DirectFB/lib/direct/util.h
new file mode 100755
index 0000000..b93359e
--- /dev/null
+++ b/Source/DirectFB/lib/direct/util.h
@@ -0,0 +1,330 @@
+/*
+ (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 __DIRECT__UTIL_H__
+#define __DIRECT__UTIL_H__
+
+#include <unistd.h>
+
+#ifdef _POSIX_PRIORITY_SCHEDULING
+#include <sched.h>
+#endif
+
+#include <pthread.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef SIGN
+#define SIGN(x) (((x) < 0) ? -1 : (((x) > 0) ? 1 : 0))
+#endif
+
+#ifndef ABS
+#define ABS(x) ((x) > 0 ? (x) : -(x))
+#endif
+
+#ifndef CLAMP
+#define CLAMP(x,min,max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x))
+#endif
+
+#ifndef BSWAP16
+#define BSWAP16(x) (((u16)(x)>>8) | ((u16)(x)<<8))
+#endif
+
+#ifndef BSWAP32
+#define BSWAP32(x) ((((u32)(x)>>24) & 0x000000ff) | (((u32)(x)>> 8) & 0x0000ff00) | \
+ (((u32)(x)<< 8) & 0x00ff0000) | (((u32)(x)<<24) & 0xff000000))
+#endif
+
+
+#define D_FLAGS_SET(flags,f) do { (flags) |= (f); } while (0)
+#define D_FLAGS_CLEAR(flags,f) do { (flags) &= ~(f); } while (0)
+#define D_FLAGS_IS_SET(flags,f) (((flags) & (f)) != 0)
+#define D_FLAGS_ARE_SET(flags,f) (((flags) & (f)) == (f))
+#define D_FLAGS_ARE_IN(flags,f) (((flags) & ~(f)) == 0)
+#define D_FLAGS_INVALID(flags,f) (((flags) & ~(f)) != 0)
+
+#define D_FLAGS_ASSERT(flags,f) D_ASSERT( D_FLAGS_ARE_IN(flags,f) )
+
+#define D_ARRAY_SIZE(array) ((int)(sizeof(array) / sizeof((array)[0])))
+
+#define D_UTIL_SWAP(a,b) \
+ do { \
+ const typeof(a) x = (a); (a) = (b); (b) = x; \
+ } while (0)
+
+
+#if __GNUC__ >= 3
+#define D_CONST_FUNC __attribute__((const))
+#else
+#define D_CONST_FUNC
+#endif
+
+
+#define D_BITn32(f) (((f) & 0x00000001) ? 0 : \
+ ((f) & 0x00000002) ? 1 : \
+ ((f) & 0x00000004) ? 2 : \
+ ((f) & 0x00000008) ? 3 : \
+ ((f) & 0x00000010) ? 4 : \
+ ((f) & 0x00000020) ? 5 : \
+ ((f) & 0x00000040) ? 6 : \
+ ((f) & 0x00000080) ? 7 : \
+ ((f) & 0x00000100) ? 8 : \
+ ((f) & 0x00000200) ? 9 : \
+ ((f) & 0x00000400) ? 10 : \
+ ((f) & 0x00000800) ? 11 : \
+ ((f) & 0x00001000) ? 12 : \
+ ((f) & 0x00002000) ? 13 : \
+ ((f) & 0x00004000) ? 14 : \
+ ((f) & 0x00008000) ? 15 : \
+ ((f) & 0x00010000) ? 16 : \
+ ((f) & 0x00020000) ? 17 : \
+ ((f) & 0x00040000) ? 18 : \
+ ((f) & 0x00080000) ? 19 : \
+ ((f) & 0x00100000) ? 20 : \
+ ((f) & 0x00200000) ? 21 : \
+ ((f) & 0x00400000) ? 22 : \
+ ((f) & 0x00800000) ? 23 : \
+ ((f) & 0x01000000) ? 24 : \
+ ((f) & 0x02000000) ? 25 : \
+ ((f) & 0x04000000) ? 26 : \
+ ((f) & 0x08000000) ? 27 : \
+ ((f) & 0x10000000) ? 28 : \
+ ((f) & 0x20000000) ? 29 : \
+ ((f) & 0x40000000) ? 30 : \
+ ((f) & 0x80000000) ? 31 : -1)
+
+
+/*
+ * portable sched_yield() implementation
+ */
+#ifdef _POSIX_PRIORITY_SCHEDULING
+#define direct_sched_yield() sched_yield()
+#else
+#define direct_sched_yield() usleep(1)
+#endif
+
+/*
+ * translates errno to DirectResult
+ */
+DirectResult errno2result( int erno );
+
+const char *DirectResultString( DirectResult result );
+
+/*
+ * duplicates a file descriptor as needed to ensure it's not stdin, stdout, or stderr
+ */
+int direct_safe_dup( int fd );
+
+int direct_try_open( const char *name1, const char *name2, int flags, bool error_msg );
+
+void direct_trim( char **s );
+
+/*
+ * Set a string with a maximum size including the zero termination.
+ *
+ * This acts like a strncpy(d,s,n), but always terminates the string like snprintf(d,n,"%s",s).
+ *
+ * Returns dest or NULL if n is zero.
+ */
+static __inline__ char *
+direct_snputs( char *dest,
+ const char *src,
+ size_t n )
+{
+ char *start = dest;
+
+ D_ASSERT( dest != NULL );
+ D_ASSERT( src != NULL );
+
+ if (!n)
+ return NULL;
+
+ for (; n>1 && *src; n--)
+ *dest++ = *src++;
+
+ *dest = 0;
+
+ return start;
+}
+
+/*
+ * Encode/Decode Base-64 strings.
+ */
+char *direct_base64_encode( const void *data, int size );
+void *direct_base64_decode( const char *string, int *ret_size );
+
+/*
+ * Compute MD5 sum (store 16-bytes long result in "dst").
+ */
+void direct_md5_sum( void *dst, const void *src, const int len );
+
+/*
+ * Slow implementation, but quite fast if only low bits are set.
+ */
+static __inline__ int
+direct_util_count_bits( unsigned int mask )
+{
+ register int ret = 0;
+
+ while (mask) {
+ ret += mask & 1;
+ mask >>= 1;
+ }
+
+ return ret;
+}
+
+/*
+ * Generic alignment routine.
+ */
+static __inline__ int
+direct_util_align( int value,
+ int alignment )
+{
+ if (alignment > 1) {
+ int tail = value % alignment;
+
+ if (tail)
+ value += alignment - tail;
+ }
+
+ return value;
+}
+
+/*
+ * Utility function to initialize recursive mutexes.
+ */
+int direct_util_recursive_pthread_mutex_init( pthread_mutex_t *mutex );
+
+/*
+ * Utility function to calibrate timeout for monotonic condition.
+ */
+void direct_util_get_monotonic_pthread_timeout( struct timespec *timeout,
+ int seconds,
+ int nano_seconds );
+
+/*
+ * Utility function to initialize monotonic condition.
+ */
+int direct_util_monotonic_pthread_cond_init( pthread_cond_t *cond );
+
+/* floor and ceil implementation to get rid of libm */
+
+/*
+ IEEE floor for computers that round to nearest or even.
+
+ 'f' must be between -4194304 and 4194303.
+
+ This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1",
+ but uses some IEEE specific tricks for better speed.
+*/
+static __inline__ int
+D_IFLOOR(float f)
+{
+ int ai, bi;
+ double af, bf;
+
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+
+#if defined(__GNUC__) && defined(__i386__)
+ /*
+ GCC generates an extra fstp/fld without this.
+ */
+ __asm__ __volatile__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
+ __asm__ __volatile__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
+#else
+ {
+ union { int i; float f; } u;
+ u.f = af; ai = u.i;
+ u.f = bf; bi = u.i;
+ }
+#endif
+
+ return (ai - bi) >> 1;
+}
+
+
+/*
+ IEEE ceil for computers that round to nearest or even.
+
+ 'f' must be between -4194304 and 4194303.
+
+ This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1",
+ but uses some IEEE specific tricks for better speed.
+*/
+static __inline__ int
+D_ICEIL(float f)
+{
+ int ai, bi;
+ double af, bf;
+
+ af = (3 << 22) + 0.5 + (double)f;
+ bf = (3 << 22) + 0.5 - (double)f;
+
+#if defined(__GNUC__) && defined(__i386__)
+ /*
+ GCC generates an extra fstp/fld without this.
+ */
+ __asm__ __volatile__ ("fstps %0" : "=m" (ai) : "t" (af) : "st");
+ __asm__ __volatile__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st");
+#else
+ {
+ union { int i; float f; } u;
+ u.f = af; ai = u.i;
+ u.f = bf; bi = u.i;
+ }
+#endif
+
+ return (ai - bi + 1) >> 1;
+}
+
+static __inline__ int
+direct_log2( int val )
+{
+ register int ret = 0;
+
+ while (val >> ++ret);
+
+ if ((1 << --ret) < val)
+ ret++;
+
+ return ret;
+}
+
+
+#endif