diff options
author | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2013-01-15 08:46:13 +0100 |
---|---|---|
committer | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2013-01-15 08:46:13 +0100 |
commit | 7fe60435bce6595a9c58a9bfd8244d74b5320e96 (patch) | |
tree | 1ac714a916e02fc90901ddac8bc2a3c6d051d28c /Source/DirectFB/interfaces | |
download | directfb-voodoo-7fe60435bce6595a9c58a9bfd8244d74b5320e96.tar.gz directfb-voodoo-7fe60435bce6595a9c58a9bfd8244d74b5320e96.tar.bz2 directfb-voodoo-7fe60435bce6595a9c58a9bfd8244d74b5320e96.zip |
Import DirectFB141_2k11R3_beta5
Diffstat (limited to 'Source/DirectFB/interfaces')
27 files changed, 14174 insertions, 0 deletions
diff --git a/Source/DirectFB/interfaces/IDirectFBFont/Makefile.am b/Source/DirectFB/interfaces/IDirectFBFont/Makefile.am new file mode 100755 index 0000000..c133da5 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBFont/Makefile.am @@ -0,0 +1,77 @@ +## Makefile.am for DirectFB/interfaces/IDirectFBFont + +idirectfbfontdir = $(MODULEDIR)/interfaces/IDirectFBFont + +if FREETYPE_PROVIDER +FREETYPE_PROVIDER_LTLIB = libidirectfbfont_ft2.la +else +FREETYPE_PROVIDER_LTLIB = +endif + +if LINOTYPE_PROVIDER +LINOTYPE_PROVIDER_LTLIB = libidirectfbfont_lino.la +else +LINOTYPE_PROVIDER_LTLIB = +endif + +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src \ + -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" + +AM_CFLAGS = $(FREETYPE_CFLAGS) $(LINOTYPE_CFLAGS) + +idirectfbfont_LTLIBRARIES = \ + libidirectfbfont_default.la \ + $(FREETYPE_PROVIDER_LTLIB) \ + $(LINOTYPE_PROVIDER_LTLIB) \ + libidirectfbfont_dgiff.la + +if BUILD_STATIC +idirectfbfont_DATA = $(idirectfbfont_LTLIBRARIES:.la=.o) +endif + + +libidirectfbfont_default_la_SOURCES = idirectfbfont_default.c default_font.h + +libidirectfbfont_default_la_LDFLAGS = -avoid-version -module + +libidirectfbfont_default_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + + +libidirectfbfont_dgiff_la_SOURCES = idirectfbfont_dgiff.c + +libidirectfbfont_dgiff_la_LDFLAGS = -avoid-version -module + +libidirectfbfont_dgiff_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la + + +libidirectfbfont_ft2_la_SOURCES = idirectfbfont_ft2.c + +libidirectfbfont_ft2_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(FREETYPE_LIBS) + +libidirectfbfont_ft2_la_LDFLAGS = -avoid-version -module + + +libidirectfbfont_lino_la_SOURCES = idirectfbfont_lino.c + +libidirectfbfont_lino_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(LINOTYPE_LIBS) + +libidirectfbfont_lino_la_LDFLAGS = -avoid-version -module + + +include $(top_srcdir)/rules/libobject.make diff --git a/Source/DirectFB/interfaces/IDirectFBFont/Makefile.in b/Source/DirectFB/interfaces/IDirectFBFont/Makefile.in new file mode 100755 index 0000000..a124d84 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBFont/Makefile.in @@ -0,0 +1,648 @@ +# 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 = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/rules/libobject.make +subdir = interfaces/IDirectFBFont +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 = +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)$(idirectfbfontdir)" \ + "$(DESTDIR)$(idirectfbfontdir)" +idirectfbfontLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(idirectfbfont_LTLIBRARIES) +libidirectfbfont_default_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la +am_libidirectfbfont_default_la_OBJECTS = idirectfbfont_default.lo +libidirectfbfont_default_la_OBJECTS = \ + $(am_libidirectfbfont_default_la_OBJECTS) +libidirectfbfont_default_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libidirectfbfont_default_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +libidirectfbfont_dgiff_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la +am_libidirectfbfont_dgiff_la_OBJECTS = idirectfbfont_dgiff.lo +libidirectfbfont_dgiff_la_OBJECTS = \ + $(am_libidirectfbfont_dgiff_la_OBJECTS) +libidirectfbfont_dgiff_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libidirectfbfont_dgiff_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__DEPENDENCIES_1 = +libidirectfbfont_ft2_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la $(am__DEPENDENCIES_1) +am_libidirectfbfont_ft2_la_OBJECTS = idirectfbfont_ft2.lo +libidirectfbfont_ft2_la_OBJECTS = \ + $(am_libidirectfbfont_ft2_la_OBJECTS) +libidirectfbfont_ft2_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbfont_ft2_la_LDFLAGS) $(LDFLAGS) -o $@ +@FREETYPE_PROVIDER_TRUE@am_libidirectfbfont_ft2_la_rpath = -rpath \ +@FREETYPE_PROVIDER_TRUE@ $(idirectfbfontdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libidirectfbfont_default_la_SOURCES) \ + $(libidirectfbfont_dgiff_la_SOURCES) \ + $(libidirectfbfont_ft2_la_SOURCES) +DIST_SOURCES = $(libidirectfbfont_default_la_SOURCES) \ + $(libidirectfbfont_dgiff_la_SOURCES) \ + $(libidirectfbfont_ft2_la_SOURCES) +idirectfbfontDATA_INSTALL = $(INSTALL_DATA) +DATA = $(idirectfbfont_DATA) +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@ +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@ +idirectfbfontdir = $(MODULEDIR)/interfaces/IDirectFBFont +@FREETYPE_PROVIDER_FALSE@FREETYPE_PROVIDER_LTLIB = +@FREETYPE_PROVIDER_TRUE@FREETYPE_PROVIDER_LTLIB = libidirectfbfont_ft2.la +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src \ + -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" + +AM_CFLAGS = $(FREETYPE_CFLAGS) +idirectfbfont_LTLIBRARIES = \ + libidirectfbfont_default.la \ + $(FREETYPE_PROVIDER_LTLIB) \ + libidirectfbfont_dgiff.la + +@BUILD_STATIC_TRUE@idirectfbfont_DATA = $(idirectfbfont_LTLIBRARIES:.la=.o) +libidirectfbfont_default_la_SOURCES = idirectfbfont_default.c default_font.h +libidirectfbfont_default_la_LDFLAGS = -avoid-version -module +libidirectfbfont_default_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbfont_dgiff_la_SOURCES = idirectfbfont_dgiff.c +libidirectfbfont_dgiff_la_LDFLAGS = -avoid-version -module +libidirectfbfont_dgiff_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbfont_ft2_la_SOURCES = idirectfbfont_ft2.c +libidirectfbfont_ft2_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(FREETYPE_LIBS) + +libidirectfbfont_ft2_la_LDFLAGS = -avoid-version -module +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/rules/libobject.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 interfaces/IDirectFBFont/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu interfaces/IDirectFBFont/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 +install-idirectfbfontLTLIBRARIES: $(idirectfbfont_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(idirectfbfontdir)" || $(MKDIR_P) "$(DESTDIR)$(idirectfbfontdir)" + @list='$(idirectfbfont_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(idirectfbfontLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(idirectfbfontdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(idirectfbfontLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(idirectfbfontdir)/$$f"; \ + else :; fi; \ + done + +uninstall-idirectfbfontLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(idirectfbfont_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(idirectfbfontdir)/$$p'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(idirectfbfontdir)/$$p"; \ + done + +clean-idirectfbfontLTLIBRARIES: + -test -z "$(idirectfbfont_LTLIBRARIES)" || rm -f $(idirectfbfont_LTLIBRARIES) + @list='$(idirectfbfont_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 +libidirectfbfont_default.la: $(libidirectfbfont_default_la_OBJECTS) $(libidirectfbfont_default_la_DEPENDENCIES) + $(libidirectfbfont_default_la_LINK) -rpath $(idirectfbfontdir) $(libidirectfbfont_default_la_OBJECTS) $(libidirectfbfont_default_la_LIBADD) $(LIBS) +libidirectfbfont_dgiff.la: $(libidirectfbfont_dgiff_la_OBJECTS) $(libidirectfbfont_dgiff_la_DEPENDENCIES) + $(libidirectfbfont_dgiff_la_LINK) -rpath $(idirectfbfontdir) $(libidirectfbfont_dgiff_la_OBJECTS) $(libidirectfbfont_dgiff_la_LIBADD) $(LIBS) +libidirectfbfont_ft2.la: $(libidirectfbfont_ft2_la_OBJECTS) $(libidirectfbfont_ft2_la_DEPENDENCIES) + $(libidirectfbfont_ft2_la_LINK) $(am_libidirectfbfont_ft2_la_rpath) $(libidirectfbfont_ft2_la_OBJECTS) $(libidirectfbfont_ft2_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbfont_default.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbfont_dgiff.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbfont_ft2.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-idirectfbfontDATA: $(idirectfbfont_DATA) + @$(NORMAL_INSTALL) + test -z "$(idirectfbfontdir)" || $(MKDIR_P) "$(DESTDIR)$(idirectfbfontdir)" + @list='$(idirectfbfont_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(idirectfbfontDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(idirectfbfontdir)/$$f'"; \ + $(idirectfbfontDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(idirectfbfontdir)/$$f"; \ + done + +uninstall-idirectfbfontDATA: + @$(NORMAL_UNINSTALL) + @list='$(idirectfbfont_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(idirectfbfontdir)/$$f'"; \ + rm -f "$(DESTDIR)$(idirectfbfontdir)/$$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) +installdirs: + for dir in "$(DESTDIR)$(idirectfbfontdir)" "$(DESTDIR)$(idirectfbfontdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-idirectfbfontLTLIBRARIES clean-libtool \ + 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-idirectfbfontDATA \ + install-idirectfbfontLTLIBRARIES + +install-dvi: install-dvi-am + +install-exec-am: + +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-idirectfbfontDATA \ + uninstall-idirectfbfontLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-idirectfbfontLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-idirectfbfontDATA \ + install-idirectfbfontLTLIBRARIES install-info install-info-am \ + install-man install-pdf install-pdf-am 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-idirectfbfontDATA \ + uninstall-idirectfbfontLTLIBRARIES + +%.o: .libs/%.a %.la + rm -f $<.tmp/*.o + if test -d $<.tmp; then rmdir $<.tmp; fi + mkdir $<.tmp + (cd $<.tmp && $(AR) x ../../$<) + $(LD) -o $@ -r $<.tmp/*.o + rm -f $<.tmp/*.o && rmdir $<.tmp + +.PHONY: $(LTLIBRARIES:%.la=.libs/%.a) +# 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/interfaces/IDirectFBFont/default_font.h b/Source/DirectFB/interfaces/IDirectFBFont/default_font.h new file mode 100755 index 0000000..a0c953d --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBFont/default_font.h @@ -0,0 +1,623 @@ +/* DirectFB surface dump created by directfb-csource 0.9.17 */ + +static unsigned char font_data[] = + "\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\377" + "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0" + "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\377\0\0\0\0\0\377" + "\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\377\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0" + "\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0" + "\0\377\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0" + "\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\377\0\0" + "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\377\0\0\0" + "\0\0\0\0\0\377\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377" + "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0\377" + "\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\377\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377" + "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\377\0\0\0\0\0\0\377\0\0\0\0\0\377\0" + "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0" + "\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\377\0\0\0\0\0\0\0" + "\0\377\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0" + "\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377" + "\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0" + "\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\377\0\0\0\0\377" + "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\377\0\0\0\0\0\0" + "\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377\0\0\0\0\377\0" + "\0\0\0\377\0\0\377\0\0\0\0\377\0\0\0\377\0\0\0\0\377\0\0\0\0\0\0\0\0" + "\0\0\377\0\0\0\0\0\0\377\0\0\0\0\377\0\0\0\0\377\0\0\0\0\0\0\377\0\0" + "\0\0\0\0\377\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\377" + "\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\377\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""8U8\0\34UUU\34\34" + "UUU\34""8U\34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0""8U\34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0UU\0\0\0\0" + "\0\0\0\0\0\0\0\0""8U8\0\0\0\0\0\0\0\0\0\0""8U\34\0\0\0\0\0\0\0""88\0" + "\0\0\34U\0\0\0UU\0\0\0\0\0\0\34U8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\34U8\0UU\0\0\0\0\0\0\377\252\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\34U\34\0\0qU\0\0" + "\215U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\34U8\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377U\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0q\377\377\252\0U" + "\377\377\377UU\377\377\377U\252\377\3778\0\0\0""8U\0\0\0\0\0\0\2158\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""8U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\34U8\0\0\0\0""8\252\2528\0\0\0\0\0q\252\252\252" + "\252\2528\0\0\0\0\0\0""8\215\252\252U\0\0""8\252\252\252\252\2158\0\0" + "\0\0""8\252\252\252\252\252\252q\0\0q\252\252\252\252\252\252\0\0\0\0" + "8\215\252\252q\34\0\0\0\252\252\0\0\0\0q\2528\0\0""8\252q\0\0\0\252\252" + "\0\0\0q\2528\0\0\34\252\2528\0q\2528\0\0\0\0\0\0\252\252q\0\0\0\0q\252" + "\252\0\0\0""8\252\252U\0\0\0""8\252q\0\0\0\0U\252\252\2158\0\0\0\0""8" + "\252\252\252\252\215\34\0\0\0\0\0U\252\252\2158\0\0\0\0""8\252\252\252" + "\252\252U\0\0\0\0\0\34\215\252\252q\34\0q\252\252\252\252\252\252\252" + "\252\0q\2528\0\0\0\0\252\252\0\0\252\2528\0\0\0\0""8\252q\0\252\2528" + "\0\0\0\252\252\215\0\0\0U\252q\0\252\252U\0\0\0\0\215\25288\252\252\34" + "\0\0\0""8\252\252\0q\252\252\252\252\252\252q\0\0\0\0\0\0\0\0\0\0\0\252" + "\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\0\0\0\0\0\0\0\0" + "\0\0\215\377\377\377U\0\0\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\0""8\377\377" + "8\0\0\342\377\215\0\0\377\377\0\0\0\0\0\0U\377\252\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0UU\34\0\0\0\0\0\0\0\0\0\0\0\0\34UU\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0U\377\252\0\0U\377\252\0\377\377\0\0\0\0\0\34\377" + "\306\34\0\0\0\0\0\0UU\0\0\0\0\0\342\252\0\0\0\0\0\0\0\0\0U\252\252q\0" + "\0\0\0\0\0\0\0\0q\3778\0\34\377\252\0\0\342\306\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\34\215\342\377\342U\0\0\0\0\0\0\306\377\342\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377U8\0U\377\215U\34\34" + "U\215\377U8q\377\252\0\0\0\252\377\34\0\0\0\0""8\377\377\215\34\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\252\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\252U\0\34\2528\0\0U\377\252\0\0\0\0\252\377\377\252\0\0\0\0\0\252\377" + "\377\377\377\377\377\252\0\0\0\0\252\377\377\377\377\377\34\0U\377\377" + "\377\377\377\377\252\0\0\0U\377\377\377\377\377\377\252\0\0\252\377\377" + "\377\377\377\377\0\0\0\252\377\377\377\377\377\377\0\0\0\377\377\0\0" + "\0\0\252\377U\0\0U\377\252\0\0\0\377\377\0\0\0\252\377U\0\0\306\377\306" + "\0\0\252\377U\0\0\0\0\0\0\377\377\342\0\0\0\0\342\377\377\0\0\0U\377" + "\377\342\0\0\0U\377\252\0\0\0\252\377\377\377\377\377U\0\0\0U\377\377" + "\377\377\377\377U\0\0\0\252\377\377\377\377\377U\0\0\0U\377\377\377\377" + "\377\377\342\0\0\0U\377\377\377\377\377\215\0\252\377\377\377\377\377" + "\377\377\377\0\252\377U\0\0\0\0\377\377\0\0\306\377\215\0\0\0\0\215\377" + "\252\0\342\377U\0\0""8\377\377\377\0\0\0\252\377q\0q\377\377\34\0\0q" + "\377\342\0\0\342\377\215\0\0\0\252\377\252\0\252\377\377\377\377\377" + "\377\252\0\0\0\0\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\377\377\0\0\0\0\0\0\0\0\0\0\0\377\377q\215\34\0\0\0\0\0\0\0" + "\0\0\252\377U\0\0\0\0\0\0""8\377\3778\0\0\342\377\215\0\0\377\377\0\0" + "\0\0\0\0U\377\252\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0U\252\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377\377\377\377\0\0\0\0\0\0" + "\0\0\0\0\0\215\377\377\377\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0U\377\252\0\0""8\377\252\0\377\342\0\0\0\34\306\377\377\377\377\342" + "\0\0\0\34\342\377\377\342\34\0\0""8\377\215\0\0\0\0\0\0\0\0\252\377\377" + "\377\377\252\0\0\0\0\0\0\0\0\306\377\0\0\215\377U\0\0\215\3778\0\0\0" + "\0\0\0\0\0\0\0\0\0\0""8\377\342\252\377\3778\0\0\0\0""8\377\342\377q" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377U\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\252\0\0" + "\0U\377U\0\0\0\0U\377U\0\0\377\252\0\0\0U\377q\0\0\0\0\0U\306\377\342" + "8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0U\377q\0U\377U\0\0""8\377\252\0\0\0\0\377\342\377\377\0\0\0\0\0\252" + "\377U\0\0U\377\377\34\0\0\215\377\3068\0""8q\0\0U\377\252\0\0""8\342" + "\377q\0\0U\377\252\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\0\215\377\3068\0" + "\34qq\0\0\0\377\377\0\0\0\0\252\377U\0\0U\377\252\0\0\0\377\377\0\0\0" + "\252\377U\0q\377\342\34\0\0\252\377U\0\0\0\0\0\34\377\377\377\34\0\0" + "\34\377\377\3778\0\0U\377\342\377U\0\0U\377\252\0\0q\377\252\34\0U\377" + "\377\34\0\0U\377\252\0\0U\377\377\0\0q\377\252\34\0U\377\377\34\0\0U" + "\377\252\0\0\34\342\377q\0\34\377\3778\0\34q8\0\0\0\0U\377\252\0\0\0" + "\0\252\377U\0\0\0\0\377\377\0\0q\377\306\0\0\0\0\306\377U\0\252\377\252" + "\0\0U\377\306\3778\0\0\306\377U\0\0\342\377\215\0\0\342\3778\0\0q\377" + "\342\0\0\0\377\3778\0\0\0\0\0\0q\377U\0\0\0\0\0\0\0\0\0\0\0\252\377U" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\0\0\0\0\0\0\0\0\0\0" + "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\0\0""88\0\0\0\34" + "U\0\0\0\377\377\0\0\0\0\0\0U\377\252\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""8U8\0\0\0\0\0\0\0""8\0\0\0\0""8U8\0" + "\0\0\0\0""8UU\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377\342" + "qq\215\0\0\0\0\0\0\0\0\0\0q\377\342Uq\377\377\34\0\0\0\0UU\34\0\0\0\0" + "\0\0UU\34\0\0\0\0U\377\252\0\0\0\377\252\0\377\252\0\0\0\342\377\306" + "\377\342\252\377\0\0\0\215\377qq\377\252\0\0\215\3778\0\0\0\0\0\0\0""8" + "\377\342\34\34\342\3778\0\0\0\0\0\0\0\377\252\0\0\342\377\0\0\0U\377" + "\215\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\34\0q\377\252\0\0\0\0\306\3778\377" + "\342\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377U\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\252" + "\0\0\0U\377U\0\0\0\0U\377U\0\0\377\252\0\0\0\0\377\252\0\0\0\0\0\0\0" + "8\252\0\0\0\0\0\0\0\0\0\0\0\0\215\342\215\306\377\215\342\215\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0U\377U\0U\377\34\0\0\0\377\252\0\0\0""8\377\252\252" + "\377U\0\0\0\0\252\377U\0\0\0\252\377U\0\34\377\377\34\0\0\0\0\0\0U\377" + "\252\0\0\0""8\377\342\0\0U\377\252\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\34" + "\377\377\34\0\0\0\0\0\0\0\0\377\377\0\0\0\0\252\377U\0\0U\377\252\0\0" + "\0\377\377\0\0\0\252\377U\34\342\377U\0\0\0\252\377U\0\0\0\0\0U\377\306" + "\377U\0\0U\377\342\377U\0\0U\377\252\377\306\0\0U\377\252\0\0\342\377" + "\34\0\0\0q\377\215\0\0U\377\252\0\0\0\306\377U\0\342\377\34\0\0\0q\377" + "\215\0\0U\377\252\0\0\0U\377\252\0U\377\252\0\0\0\0\0\0\0\0\0U\377\252" + "\0\0\0\0\252\377U\0\0\0\0\377\377\0\0""8\377\377\0\0\0\0\377\377\0\0" + "\215\377\252\0\0\252\377q\377U\0\0\377\377\34\0\0U\377\377\34q\377\306" + "\0\0\0\34\377\3778\0q\377\306\0\0\0\0\0\0\34\377\306\0\0\0\0\0\0\0\0" + "\0\0\0\0\252\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\0\0" + "\0\0\0\0\0\0\0\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\377\377\0\0\0\0\0\0U\377\252\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\377\377\377\306\34\0" + "\0\34q\342\252\0\0U\342\377\377\377\306\34\0""8\342\377\377\377\342U" + "\0\0\0\0""8\377\252\0\0\0\0U\377\377\377\377\377\252\0\0\0\342\377\34" + "\0\0\0\0U\377\377\377\377\377\377\3778\252\377U\0\0\306\377U\0\0U\377" + "\377\377\377\215\0\0\0\34\342\377\377\377\215\0\0\0U\377\252\0\0\0\377" + "\252\0\377\252\0\0U\377\306\0\377\252\0\0\0\0\0\377\306\0\0\306\377\0" + "\0\306\377\0\0\0\0\0\0\0\0U\377\252\0\0\252\377U\0\0\0\0\0\0U\377U\0" + "\34\377\252\0\0\0\0\377\342\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0q\377\252" + "\0\0\0""8\377\215\0\215\377q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0U\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\377\252\0\0\0U\377U\0\0\0\0U\377U\0\0\377\252\0\0\0\0" + "\306\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""8\215\342\377\377" + "\306q\34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\215\3778\0\252\377\0\0\0\0\377\252" + "\0\0\0\215\377Uq\377\215\0\0\0\0\252\377U\0\0\0\252\3778\0U\377\252\0" + "\0\0\0\0\0\0U\377\252\0\0\0\0\377\377\34\0U\377\252\0\0\0\0\0\0\0\252" + "\377U\0\0\0\0\0U\377\252\0\0\0\0\0\0\0\0\0\377\377\0\0\0\0\252\377U\0" + "\0U\377\252\0\0\0\377\377\0\0\0\252\377U\252\377\252\0\0\0\0\252\377" + "U\0\0\0\0\0U\377\252\377\252\0\0\252\377\252\377U\0\0U\377\252\306\377" + "\34\0U\377\252\0\34\377\342\0\0\0\0""8\377\306\0\0U\377\252\0\0\0\252" + "\377U\34\377\342\0\0\0\0""8\377\306\0\0U\377\252\0\0\0q\377\215\0U\377" + "\342\34\0\0\0\0\0\0\0\0U\377\252\0\0\0\0\252\377U\0\0\0\0\377\377\0\0" + "\0\342\377U\0\0U\377\306\0\0U\377\342\0\0\306\3778\377\215\0\0\377\377" + "\0\0\0\0\306\377\215\342\377\34\0\0\0\0\215\377\252\0\306\3778\0\0\0" + "\0\0\0\306\3778\0\0\0""8\306\377\377\342U\0\0\0\252\377q\306\377\306" + "8\0\0\0\34\252\377\377\306\0\0\34\252\377\342U\377\377\0\0\0q\342\377" + "\342U\0U\377\377\377\377\377\0\0q\342\377\377\377\377\215\0\252\377q" + "\215\377\377U\0\0\0\377\377\0\0\0\252\377U\0\0\377\377\0\0\342\377\215" + "\0U\377\252\0\0U\377Uq\377\377\215\34\306\377\342U\0\0U\377Uq\342\377" + "\252\0\0\0\0q\342\377\342q\0\0\0\252\377\34\306\377\342U\0\0\0U\342\377" + "\306\34\377\252\0\0\377\252U\342\3778\0\215\377\377\342qU\377\377\377" + "\377\252\0U\377\252\0\0U\377\252\0\252\377\215\0\0\34\377\377U\377\342" + "\0\0""8\377\377U\0\0\252\377U\215\377\306\0\0U\377\342\0\377\3778\0\0" + "8\377\306\0\377\377\377\377\377\377\0\0\215\377\306U\252\377\215\0q\377" + "\377\377\252\0\0q\377\215U\306\377\215\0\34\377\215U\215\377\342\0\0" + "\0\0\215\3778\0\0\0\0U\377\306\252\252\252q\0\0""8\377\252\0\0\0\0\0" + "8\252\252\252\252\252\377\377\0\252\377q\0\0\306\377U\0\34\377\377qU" + "\342\3778\0\0\342\377\215U\342\3778\0\0""8\377\252\0\0\0\0\0\0\0\0\0" + "\0U\377\252\0\377\252\0\0\0\0\0\377\252\0\0\252\377\0\34\377\252\0\0" + "\0\0\0\0\0\0""8\377\342\0\0\342\377\34\0\0\0\0\0\0\252\377\34\0U\377" + "\252\0\0\0\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\342\377q\0\0\0" + "\306\377\34\0\34\377\342\0\0\0\0\0\0\0\0""8\252\252\0U\3068\0\0\0\0\0" + "\0\0U\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\377\252\0\0\0U\377U\0\0\0\0U\377U\0\0\377\252\0\0\0\0" + "q\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\34U\34\0\0\0\0\0\0q\377\377U\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\252\377\377\377\377\377\377\377\377\377\0\0\0\0" + "\0\0\0\306\37788\377\342\0\0\0\0\252\377U\0\0U\377\252\0\0\252\377U\0" + "\0\0\0\0\0\0U\377\252\0\0\0\0\252\377U\0U\377\306UUUU\0\0\0\252\377U" + "\0\0\0\0\0\252\377U\0\0\0\0\0\0\0\0\0\377\377UUUU\306\377U\0\0U\377\252" + "\0\0\0\377\377\0\0\0\252\377\252\377\342\34\0\0\0\0\252\377U\0\0\0\0" + "\0U\377\252\306\342\0\0\342\342\252\377U\0\0U\377\252U\377\215\0U\377" + "\252\0U\377\252\0\0\0\0\0\377\377\0\0U\377\252\0\0\0\342\3778U\377\252" + "\0\0\0\0\0\377\377\0\0U\377\252\0\0""8\342\3778\0\0\342\377\342q\0\0" + "\0\0\0\0\0U\377\252\0\0\0\0\252\377U\0\0\0\0\377\377\0\0\0\252\377\215" + "\0\0\215\377q\0\0""8\377\377\0\0\377\252\0\377\252\0U\377\252\0\0\0\0" + "8\377\377\377\215\0\0\0\0\0\34\377\377\34\377\306\0\0\0\0\0\0U\377\215" + "\0\0\0\0q\377\252\252\377\3778\0\0\252\377\377\306\306\377\342\0\0\34" + "\342\377\306\306\342\0\0\215\377\342\252\377\377\377\0\0q\377\342\252" + "\377\37788\252\377\377\252\252\0q\377\342\252\306\377\342U\0\252\377" + "\377\306\252\377\3778\0\0\377\377\0\0\0\252\377U\0\0\377\377\0q\377\306" + "\0\0U\377\252\0\0U\377\377\342\252\377\377\342\306\306\377\342\0\0U\377" + "\377\342\252\342\377\215\0\0q\377\342\252\342\377\215\0\0\252\377\377" + "\306\306\377\342\34\0\34\342\377\306\306\377\377\252\0\0\377\377\342" + "\306\377\34q\377\342\252\342\2158\252\377\377\252q\0U\377\252\0\0U\377" + "\252\0U\377\306\0\0U\377\252\0\377\377\0\0q\377\377\215\0\0\377\377\0" + "\34\342\3778\0\342\3778\0\252\377q\0\0q\377\215\0\252\252\252\252\377" + "\377\0\0\377\377\34\0\34\377\377\0q\342\252\377\252\0\0\0""8\0\0\34\377" + "\377\0\0\34\0\0\0\306\377U\0\0\0\377\306\0\0\0\0\0U\377U\0\0\0\0\0\0" + "q\377\215\306\377\342U\0\0\0\0\0\0U\377\252\0""8\377\342\34U\377\342" + "\0\0\215\377\215\0\0U\377\252\0U\377\306\0\0q\377\252\0\0\0\377\252\0" + "\0\0\0\0\0\0\0\0\0\34\377\377q\377\252\0\0\0\0\0\377\252\0\0\252\377" + "\0U\377U\0\34UU\0\0\0\0\0\252\377\252\252\377\252\0\0\0\0\0\0\0\342\306" + "\0\0\215\377U\0\0\0\0\252\377U\0""8\252\252\252\252\252\252\252\252\252" + "\0\0\0\0q\377\342\34\0\0""8\377\215\0\0\0\215\377q\0\0\0\0\0""8\306\377" + "\377q\0""8\342\377\342q\0\0\0\0\0U\377U\0\0\0\0\0\0\252\377U\0\0\0\0" + "\0\252\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""8\377\252\0\0\0U\377" + "U\0\0\0\0U\377U\0\0\377\342\0\0\0\0""8\377\215\0\0\0\0\0\0\0\0\0\0\0" + "\0\0U\377U\0\0\0\0\0""8\377q\215\377\34\0\0\0\0\0\0\0\0\0\0\0\0\0q\252" + "\377\377\252\252\377\342\252q\0\0\0\0\0\0\34\377\377\0\0\377\3778\0\0" + "\0\252\377\377\377\377\377\306\0\0\0\252\377U\0\0\0\0\0\0\0U\377\252" + "\0\0\0\0\252\377U\0U\377\377\377\377\377\377U\0\0\252\377\377\377\377" + "\377\252\0\252\377U\0U\377\377\377\377\0\0\0\377\377\377\377\377\377" + "\377\377U\0\0U\377\252\0\0\0\377\377\0\0\0\252\377\377\377\215\0\0\0" + "\0\0\252\377U\0\0\0\0\0q\377\215\215\377\34\34\377\252\215\377q\0\0U" + "\377\252\0\342\342\0U\377\252\0U\377\252\0\0\0\0\0\377\377\0\0U\377\306" + "UU\306\377\306\0U\377\252\0\0\0\0\0\377\377\0\0U\377\377\377\377\377" + "\3068\0\0\0U\342\377\377\342q\0\0\0\0\0U\377\252\0\0\0\0\252\377U\0\0" + "\0\0\377\377\0\0\0U\377\306\0\0\306\3778\0\0\0\377\377\34""8\377\215" + "\0\306\377\0U\377\252\0\0\0\0\0\252\377\377\34\0\0\0\0\0\0\215\377\252" + "\3778\0\0\0\0\0\0\342\377\34\0\0\0\0\0\0\0\0q\377\252\0\0\252\377\306" + "\0\0\306\377U\0\215\377\215\0\0\0\0\0\377\377\34\0q\377\377\0\0\377\377" + "\34\0q\377\252\0\0\377\377\0\0\0\342\377\34\0\0\342\377\34\0\252\377" + "\306\0\0\252\377U\0\0\377\377\0\0\0\252\377U\0\0\377\377\34\377\377\34" + "\0\0U\377\252\0\0U\377\306\0\0\252\377\306\0\0\377\377\0\0U\377\377\34" + "\0U\377\252\0\0\377\377\34\0\34\377\377\0\0\252\377\306\0\0\306\377U" + "\0U\377\306\0\0\306\377\252\0\0\377\377U\0U\0\252\377U\0\0\0\0\0\377" + "\377\0\0\0U\377\252\0\0U\377\252\0\0\377\377\0\0\252\377q\0\342\3778" + "\0\252\377\342\306\0\0\377\306\0\0U\377\306q\377\215\0\0U\377\306\0\0" + "\252\377U\0\0\0\0q\377\215\0""8\377\306\0\0\0\306\377U\0\0U\377\252\0" + "\0\0\0\0\0\0\377\377\0\0\0\0\0\0\306\377U\0\0q\377q\0\0\0\0\0\252\377" + "U\0\0\0\0\0\0\252\377\377\306\306\377\342\34\0\0\0\0\0\252\377U\0\0U" + "\377\377\377\342\34\0\0\252\377U\0\0\0\377\342\0\215\377q\0\0\34\377" + "\377\0\0\0\377\252\0\0\0\0\0\0\0\0\0\0\0U\377\377\377\342q\0\0\0\0\252" + "\377\34\34\377\306\0\252\377\34U\377\377\377\342\34\0\0\0""8\377\377" + "\377\215\0\0\0\0\0\0\0""8\377\215\0\0\252\377U\0\0\0\0\252\377U\0U\377" + "\377\377\377\377\377\377\377\377\0\0\0\34\342\377U\0\0\0\306\377\34\0" + "\0\0\0\342\342\0\0\0""8\306\377\342q\34\0\0\0\0q\306\377\342q\0\0\0U" + "\377U\0\0\0\0\0\0\377\377\252\0\0\0\0\0\377\377\252\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0""8\342\3778\0\0\0U\377U\0\0\0\0U\377U\0\0q\377\3068" + "\0\0\0\342\342\0\0\0\0\0\0\0\0\0\0\0\0\0U\377U\0\0\0\0\0U\306\0\0\306" + "8\0\0\0""8\252\2158\0\0\0""8\0\0\0\0\377\252\0\0\377\252\0\0\0\0\0\0" + "\0\0U\377\252\0\0\252\377q\0\0\0\252\377\306\252\252\342\377\342\34\0" + "\252\377U\0\0\0\0\0\0\0U\377\252\0\0\0\0\252\377U\0U\377\306UUUU\0\0" + "\0\252\377\306\252\252\252q\0\252\377U\0""8\252\252\377\377\0\0\0\377" + "\377UUUU\306\377U\0\0U\377\252\0\0\0\377\377\0\0\0\252\377\215\377\377" + "\34\0\0\0\0\252\377U\0\0\0\0\0\252\377UU\377UU\377UU\377\252\0\0U\377" + "\252\0q\377UU\377\252\0U\377\252\0\0\0\0\0\377\377\0\0U\377\377\377\377" + "\377\306\34\0U\377\252\0\0\0\0\0\377\377\0\0U\377\342\252\342\377\252" + "\0\0\0\0\0\34\215\342\377\377\252\0\0\0\0U\377\252\0\0\0\0\252\377U\0" + "\0\0\0\377\377\0\0\0\0\377\377\0\0\377\342\0\0\0\0\342\377UU\377U\0\252" + "\377\34\215\377U\0\0\0\0\0\342\377\377q\0\0\0\0\0\0\34\377\377\306\0" + "\0\0\0\0\0q\377q\0\0\0\0\0\0\0""8U\215\377\252\0\0\252\377q\0\0q\377" + "\252\0\342\377\34\0\0\0\0U\377\306\0\0\34\377\377\0U\377\252\0\0\0\377" + "\342\0\0\377\377\0\0\0\377\377\0\0\0\252\377U\0\252\377U\0\0\252\377" + "U\0\0\377\377\0\0\0\252\377U\0\0\377\377\252\377U\0\0\0U\377\252\0\0" + "U\377U\0\0\252\377U\0\0\377\377\0\0U\377\252\0\0U\377\252\0U\377\306" + "\0\0\0\306\377U\0\252\377U\0\0q\377\252\0\252\377U\0\0q\377\252\0\0\377" + "\377\0\0\0\0\215\377\3428\0\0\0\0\377\377\0\0\0U\377\252\0\0U\377\252" + "\0\0\306\377U\0\306\377\34\0\252\377U\0\342\306\252\377\0U\377\252\0" + "\0\0\306\377\342\342\0\0\0\0\377\377\0\0\377\377\0\0\0\0\34\377\342\0" + "\0U\377\252\0\0\0\252\377U\0\0U\377\252\0\0\0\0\0\0q\377\306\0\0\0\0" + "\34q\377\342\0\0\0\306\377\0""8\3778\0\0\252\377\215\252\252q\0\0\0\252" + "\377\306\0\0\306\377q\0\0\0\0\34\377\377\0\0\34\342\377\306\342\377\252" + "\0\0\252\377U\0\0\0\377\377\0\252\377U\0\0\0\377\377\0\0\0\377\252\0" + "\0\0\0\0\0\0\0\0\0\0\0""8\252\377\377\377\342\34\0\0""8\377\377\377\377" + "8\0\377\306\0\342\342Uq\377\252\0\0\34\342\377\377\377\34\0U\377U\0\0" + "\0q\3778\0\0\252\377U\0\0\0\0\252\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0q\377" + "\306\0\0\0""8\377\215\0\0\0\0\0q\377U\0\215\377\306U\0\0\0\0\0\0\0\0" + "\0""8\252\377\342\0\0U\377U\0\0\0\0\0\0U\252\34\0\0\0\0\0U\252\34\0""8" + "UUU8\0\0\0\0\0\0\0\0\0\0\0\252\377\306\0\0\0\0U\377U\0\0\0\0U\377U\0" + "\0\34\306\377\252\0\0\0\215\377\34\0\0\0\0\0\0\0\0\0\0\0\0U\377U\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\215\377\377\377\377\306U\252\377\0\0\0\0\377\252" + "\0""8\377q\0\0\0\0\0\0\0\0\252\377\252UU\252\377\306\0\0\0\252\377U\0" + "\0\0\215\377\306\0\252\377U\0\0\0\0\0\0\0U\377\252\0\0\0\0\252\377U\0" + "U\377\252\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\252\377U\0\0\0\0\377\377\0" + "\0\0\377\377\0\0\0\0\252\377U\0\0U\377\252\0\0\0\377\377\0\0\0\252\377" + "U\306\377\306\0\0\0\0\252\377U\0\0\0\0\0\252\377U\0\377\252\252\377\34" + "U\377\252\0\0U\377\252\0\34\377\306U\377\252\0U\377\252\0\0\0\0\0\377" + "\377\0\0U\377\306UU8\0\0\0U\377\252\0\0\0\0\0\377\377\0\0U\377\252\0" + "\34\342\377\215\0\0\0\0\0\0\0\252\377\377\34\0\0\0U\377\252\0\0\0\0\252" + "\377U\0\0\0\0\377\377\0\0\0\0\306\377UU\377\252\0\0\0\0\252\377U\252" + "\377\34\0U\377U\252\377U\0\0\0\0\215\377\306\377\377\34\0\0\0\0\0\0\306" + "\377U\0\0\0\0\0\34\377\342\0\0\0\0\0\0U\377\377\377\377\377\252\0\0\252" + "\377U\0\0U\377\252\0\377\377\0\0\0\0\0U\377\252\0\0\0\377\377\0U\377" + "\377\377\377\377\377\377\0\0\377\377\0\0\0\342\3778\0\0\342\3778\0\252" + "\377U\0\0\252\377U\0\0\377\377\0\0\0\252\377U\0\0\377\377\377\377\34" + "\0\0\0U\377\252\0\0U\377U\0\0\252\377U\0\0\377\377\0\0U\377\252\0\0U" + "\377\252\0U\377\252\0\0\0\252\377U\0\252\377U\0\0U\377\252\0\252\377" + "U\0\0U\377\252\0\0\377\377\0\0\0\0\0\252\377\377\252\34\0\0\377\377\0" + "\0\0U\377\252\0\0U\377\252\0\0q\377q\0\377\342\0\0U\377\252\34\377\252" + "\215\3778q\377U\0\0\0""8\377\377q\0\0\0\0\306\377U8\377\306\0\0\0\0\252" + "\3778\0\0U\377\252\0\0\0\252\377U\0\0U\377\252\0\0\0\0\0\34\342\377q" + "\0\0\0\252\377\377\342\34\0\0\34\377\252\0U\377U\0\0\252\377\377\377" + "\377\377\215\0\0\252\377U\0\0U\377\252\0\0\0\0q\377\252\0\0\252\377q" + "\0\34\342\377q\0\215\377\252\0\0""8\377\377\0\252\377U\0\0\0\377\377" + "\0\0\0\377\252\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\306\342\377\252\0\0\0" + "8\252\2528\0""8\377\215U\377q\0\0\306\377\0\0\215\377\252U\377\342\34" + "U\377U\0\0\0\306\377\0\0\0\252\377U\0\0\0\0\252\377U\0\34UUUUUUUUU\0" + "\0\0\252\377U\0\0\0\0""8\34\0\0\0\0\0\0U\0\0q\377\377\306U\0\0\0\0\0" + "\0\0""8\215\342\377\306\0\0U\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\252\377\377\377\252\0\0\0\0\0\0\0\0\0\0\0\0\252\377q\0\0\0U\377U\0\0" + "\0\0U\377U\0\0\306\377q\0\0\0\0U\377q\0\0\0\0\0\0\0\0\0\252\377\377\377" + "\377\377\377\377\252\0\0\0\0\0\0\0\0\0\0Uq\0""8\306\377\377\377U\0""8" + "\377\377\377\377\377\377\377\377\377U\0\0\0\0\0\0\377\377\377\377\377" + "\377\377\377\34\0\0\252\377U\0\0\0\0\377\377\0U\377\252\0\0\0\0\0\0\0" + "U\377\252\0\0\0\0\342\377\34\0U\377\252\0\0\0\0\0\0\0\252\377U\0\0\0" + "\0\0q\377\252\0\0\0\0\377\377\0\0\0\377\377\0\0\0\0\252\377U\0\0U\377" + "\252\0\0\0\377\377\0\0\0\252\377U\34\377\377q\0\0\0\252\377U\0\0\0\0" + "\0\252\377U\0\306\342\306\306\0U\377\252\0\0U\377\252\0\0\252\377q\377" + "\252\0\34\377\342\0\0\0\0""8\377\306\0\0U\377\252\0\0\0\0\0\0\34\377" + "\342\0\0\0\0""8\377\306\0\0U\377\252\0\0""8\377\377\34\0\0\0\0\0\0\0" + "\306\377U\0\0\0U\377\252\0\0\0\0\252\377U\0\0\0\0\377\377\0\0\0\0q\377" + "\215\215\377U\0\0\0\0q\377\252\306\377\0\0""8\377q\342\377\0\0\0\0\34" + "\377\377\34\306\377\252\0\0\0\0\0\0\252\377U\0\0\0\0\0\252\3778\0\0\0" + "\0\0\34\377\377\215U\215\377\252\0\0\252\377U\0\0U\377\252\0\377\377" + "\0\0\0\0\0U\377\252\0\0\0\377\377\0U\377\342\252\252\252\252\252\0\0" + "\377\377\0\0\0q\377\342\252\306\377\306\0\0\252\377U\0\0\252\377U\0\0" + "\377\377\0\0\0\252\377U\0\0\377\377\215\377\306\0\0\0U\377\252\0\0U\377" + "U\0\0\252\377U\0\0\377\377\0\0U\377\252\0\0U\377\252\0U\377\252\0\0\0" + "\252\377U\0\252\377U\0\0U\377\252\0\252\377U\0\0U\377\252\0\0\377\377" + "\0\0\0\0\0\0""8\342\377\342\0\0\377\377\0\0\0U\377\252\0\0U\377\252\0" + "\0""8\377\252U\377\215\0\0\34\377\252U\377UU\377q\252\3778\0\0\0\215" + "\377\377\342\0\0\0\0q\377\215q\377\215\0\0\0U\377\252\0\0\0U\377\252" + "\0\0\0\252\377U\0\0U\377\252\0\0\0\0\34\342\377\252\0\0\0\0q\252\377" + "\377\252\0\0\215\3778\0\215\377U\0\0U\377\215\0""8\377\377\34\0\252\377" + "U\0\0U\377\252\0\0\0\0\306\377U\0\0\377\377\0\0\0U\377\252\0""8\377\377" + "qU\342\377\377\0\252\377U\0\0\0\377\377\0\0\0\215U\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\377\252\34\377\377\0\0\0\0\0\0\0\0\215\3778U\377U\0\0\252" + "\377\0\0\377\377\0\0U\377\342\342\377\34\0\0\0\377\252\0\0\0\252\377" + "U\0\0\0\0\252\377U\0U\377\377\377\377\377\377\377\377\377\0\0\0U\252" + "8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\34q\342\377\377\2528\0\34\215\342\377" + "\377\2158\0\0\0U\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""8UUU8\0\0" + "\0\0\0\0\0\0\0\0\0\0\34\377\252\0\0\0U\377U\0\0\0\0U\377U\0\0\377\306" + "\0\0\0\0\0\0\377\306\0\0\0\0\0\0\0\0\0q\252\252\306\377\306\252\252q" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\34U\34\0\0""8\252\306\377\306\252\342" + "\377\252\252\34\0\0\0\0\0""8\377\377UUUU\342\377q\0\0\252\377U\0\0\0" + "\34\377\377\0\34\377\377\34\0\0\0\0\0\0U\377\252\0\0\0""8\377\342\0\0" + "U\377\252\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\34\377\377\34\0\0\0\377\377" + "\0\0\0\377\377\0\0\0\0\252\377U\0\0U\377\252\0\0\0\377\377\0\0\0\252" + "\377U\0\215\377\342\34\0\0\252\377U\0\0\0\0\0\252\377U\0\215\377\377" + "\215\0U\377\252\0\0U\377\252\0\0""8\377\306\377\252\0\0\342\377\34\0" + "\0\0q\377\215\0\0U\377\252\0\0\0\0\0\0\0\342\377\34\0\0\0q\377\215\0" + "\0U\377\252\0\0\0\306\377q\0\0\0\0\0\0\0\252\377U\0\0\0U\377\252\0\0" + "\0\0\252\377q\0\0\0\34\377\377\0\0\0\0\34\377\252\252\377\0\0\0\0\0U" + "\377\252\377\252\0\0\0\377\252\377\377\0\0\0\0\306\377\215\0""8\377\377" + "8\0\0\0\0\0\252\377U\0\0\0\0""8\377\306\0\0\0\0\0\0U\377\252\0\0U\377" + "\252\0\0\252\377q\0\0q\377\215\0\306\3778\0\0\0\0""8\377\306\0\0\34\377" + "\377\0\34\377\306\0\0\0\0\0\0\0\377\377\0\0\0\0\342\377\377\377\215\34" + "\0\0\252\377U\0\0\252\377U\0\0\377\377\0\0\0\252\377U\0\0\377\377\0\342" + "\377q\0\0U\377\252\0\0U\377U\0\0\252\377U\0\0\377\377\0\0U\377\252\0" + "\0U\377\252\0\34\377\342\0\0\0\342\377\34\0\252\377\215\0\0q\377\215" + "\0\215\377q\0\0\215\377\252\0\0\377\377\0\0\0\0\0\0\0\0\306\377U\0\377" + "\377\0\0\0U\377\252\0\0q\377\252\0\0\0\342\377q\377U\0\0\0\342\377\215" + "\377\34\0\377\252\306\377\0\0\0""8\377\306\306\377\215\0\0\0\34\377\306" + "\252\3778\0\0\0\342\342\34\0\0\0\34\377\377\0\0\0\377\377\0\0\0U\377" + "\252\0\0\0\34\342\377\252\0\0\0\0\0\0\0\34\342\377q\0\342\342\0\0\252" + "\377U\0\0\0\0\0\0\0\252\377U\0q\377q\0\0q\377\215\0\0\0\34\377\377\0" + "\0\0\377\377\0\0\0U\377\252\0\0U\377\377\377\252\377\377\0q\377\252\0" + "\0U\377\252\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\252\0\377\377\0" + "\0\0\0\0\0\0\0\306\342\0U\377U\0\0\252\377\0\0\377\377\0\0\0U\377\377" + "\306\0\0\0U\377U\0\0\0U\377\252\0\0\0\0\342\377\0\0\34UUUUUUUUU\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""8\252\377\252\0U\377\306" + "q\0\0\0\0\0\0U\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\377\252\0\0\0U\377U\0\0\0\0U\377U\0\0\377\252" + "\0\0\0\0\0\0\252\377\0\0\0\0\0\0\0\0\0\0\0\0U\377U\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\215\377\34\0\252\377\0\0\0\0\0\0\0\0" + "\215\377\252\0\0\0\0\252\377\252\0\0\252\377U\0\0\34\252\377\306\0\0" + "\215\377\3068\0\34U\0\0U\377\252\0\0""8\342\377q\0\0U\377\252\0\0\0\0" + "\0\0\0\252\377U\0\0\0\0\0\0\252\377\3068\0\0\377\377\0\0\0\377\377\0" + "\0\0\0\252\377U\0\0U\377\252\0\0\0\377\377\0\0\0\252\377U\0\34\342\377" + "\215\0\0\252\377U\0\0\0\0\0\377\377\0\0U\377\377U\0\0\377\377\0\0U\377" + "\252\0\0\0\342\342\377\252\0\0q\377\342\34\0U\377\377\34\0\0U\377\252" + "\0\0\0\0\0\0\0q\377\342\34\0U\377\377\34\0\0U\377\252\0\0\0q\377\342" + "\0\0\252U\0\0q\377\342\0\0\0\0U\377\252\0\0\0\0U\377\3428\0\34\252\377" + "\215\0\0\0\0\0\342\377\377\306\0\0\0\0\0\34\377\252\377\215\0\0\0\306" + "\252\377\252\0\0\0""8\377\342\34\0\0\306\377\306\0\0\0\0\0\252\377U\0" + "\0\0\0\306\3778\0\0\0\0\0\0U\377\306\0\34\342\377\252\0\0\252\377\342" + "\34\34\342\377U\0q\377\306\34\0\34\0\0\377\377U\0\252\377\377\0\0\342" + "\377q\0\0U\34\0\0\377\377\0\0\0""8\377q\0\0\0\0\0\0\252\377U\0\0\252" + "\377U\0\0\377\377\0\0\0\252\377U\0\0\377\377\0q\377\342\34\0U\377\252" + "\0\0U\377U\0\0\252\377U\0\0\377\377\0\0U\377\252\0\0U\377\252\0\0\306" + "\377U\0U\377\342\0\0\252\377\342\34\34\342\377U\0U\377\342\34\34\342" + "\377\252\0\0\377\377\0\0\0\0UU\0\0\306\377U\0\377\377\34\0\0U\377\306" + "\0\34\342\377\252\0\0\0\252\377\252\377\0\0\0\0\252\377\252\377\0\0\306" + "\306\377\252\0\0\0\342\3778\34\377\377\34\0\0\0\306\377\342\377\0\0\0" + "\215\377q\0\0\0\0\0\306\377q\0\215\377\306\0\0\0U\377\252\0\0U\377\377" + "\252\0\0\0\0\0\0\0\0\0U\377\252U\377\342\252\252\342\377\306q\0\0\0\0" + "\0\0\252\377U\0\34\377\342\34\34\342\3778\0\0\0q\377\252\0\0\0\306\377" + "\215\0\34\306\377q\0\0\0\34U8\34\377\306\0\34\377\377\34\34\306\377q" + "\0\0U\377\252\0\0\0\0\0\0\0\0\0\0\0\215U\0\377\306\252\377\252\0\0\0" + "\0\0\0\0\34\377\252\0\0\377\306\0\34\377\306\0\0\306\377\252\34\0U\342" + "\377\252\0\0\0\252\377\34\0\0\0""8\377\252\0\0\0\0\377\342\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\34""8\0\34\34\0\0\0\0\0\0\0\0U\377U\0\34\342\342\34\0\252\377U\34" + "\342\342\34\0\252\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\252" + "\0\0\0U\377U\0\0\0\0U\377U\0\0\377\252\0\0\0\0\0\0q\377U\0\0\0\0\0\0" + "\0\0\0\0\0U\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252" + "\377\0\0\306\342\0\0\0\0\0\0\0\0\306\377U\0\0\0\0U\377\377\0\0\252\377" + "\377\377\377\377\377\342\34\0\0\0\252\377\377\377\377\377\34\0U\377\377" + "\377\377\377\377\252\0\0\0U\377\377\377\377\377\377\342\0\0\252\377U" + "\0\0\0\0\0\0\34\306\377\377\377\377\377\377\0\0\0\377\377\0\0\0\0\252" + "\377U\0\0U\377\252\0\0\0\377\377\0\0\0\252\377U\0\0q\377\3778\0\252\377" + "\377\377\377\377\377\0\377\377\0\0\0UU\0\0\0\377\377\0\0U\377\252\0\0" + "\0q\377\377\252\0\0\0\252\377\377\377\377\377U\0\0\0U\377\252\0\0\0\0" + "\0\0\0\0\252\377\377\377\377\377\3428\0\0U\377\252\0\0\0""8\377\3778" + "U\377\377\377\377\377\377U\0\0\0\0U\377\252\0\0\0\0\0\252\377\377\377" + "\377\377\342\34\0\0\0\0\0\215\377\377q\0\0\0\0\0\0\377\377\377U\0\0\0" + "\252\377\377\252\0\0\0\342\377q\0\0\0\34\377\377q\0\0\0\0\252\377U\0" + "\0\0\0\377\377\377\377\377\377\377\377\0\0\342\377\377\377\342\377\252" + "\0\0\252\377\306\377\377\377\342\0\0\0\342\377\377\377\377\34\0\215\377" + "\377\377\342\342\377\0\0""8\377\377\377\377\377\215\0\0\377\377\0\0\0" + "8\377\377\377\377\377\306\34\0\252\377U\0\0\252\377U\0\0\377\377\0\0" + "\0\252\377U\0\0\377\377\0\0\306\377\252\0""8\377\377\377UU\377U\0\0\252" + "\377U\0\0\377\377\0\0U\377\252\0\0U\377\252\0\0""8\377\377\377\377\377" + "8\0\0\252\377\377\377\377\377\306\0\0\0\306\377\377\377\377\377\252\0" + "\0\377\377\0\0\0\0\377\377\377\377\377\306\0\0\342\377\377\342\0\34\377" + "\377\377\377\306\377\252\0\0\0U\377\377\252\0\0\0\0q\377\342\252\0\0" + "\252\377\377\215\0\0q\377\252\0\0\215\377\306\0\0\0q\377\377\252\0\0" + "\0\377\377\377\377\377\377U\0""8\377\377\377\377\342\34\0U\377\377\377" + "\377\377\0\252\377\377\377\377\377\377U\0\0\0\0\0U\377\252U\377\377\377" + "\377\377\377\377\252\0\0\0\0\0\0\306\3778\0\0\215\377\377\377\377\252" + "\0\0\0\0\306\377U\0\0\0""8\342\377\377\377\377\342\0\0\0\0\0\0\0q\377" + "\215\0\0\215\377\377\377\377\252\0\0\0\252\377\377\0\0\0\0\0\0\0\0\0" + "\0U\377\377\377\377\377\377\342\34\0\0\0\0\0\0\0U\377U\0\0\215\377\377" + "\377\3778\0\0\34\342\377\377\377\377\377\306\377\252\0\0\342\306\0\0" + "\0\0\0\377\377\0\0\0""8\377\252\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377" + "\252\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0U\377U\0U\377\377U\0\377\377\252U\377\377U\0\377\377\252\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\252\0\0\0U\377U\0\0\0\0U\377U\0\0" + "\377\252\0\0\0\0\0\0\34\377\252\0\0\0\0\0\0\0\0\0\0\0U\377U\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\306\342\0\0\377\252\0\0\0\0" + "\0\0\0\0\252\252\34\0\0\0\0\0\252\252\34\0q\252\252\252\252\252q\34\0" + "\0\0\0\0""8\252\252\252U\0\0""8\252\252\252\252\2528\0\0\0\0""8\252\252" + "\252\252\252\252\215\0\0U\252\34\0\0\0\0\0\0\0\0U\252\252\252q\34\0\0" + "\0\252\252\0\0\0\0q\2528\0\0""8\252q\0\0\0\377\377\0\0\0q\2528\0\0\0" + "\215\252q\0q\252\252\252\252\252\252\0\252\252\0\0\0\0\0\0\0\0\252\252" + "\0\0""8\252q\0\0\0\34\252\252q\0\0\0\0U\252\252\2158\0\0\0\0""8\252q" + "\0\0\0\0\0\0\0\0\0U\252\252\215q\377\377\252\0""8\252q\0\0\0\0\215\252" + "8\0U\215\252\252\215\34\0\0\0\0\0""8\252q\0\0\0\0\0\0U\252\252\252q\0" + "\0\0\0\0\0\0""8\252\252\34\0\0\0\0\0\0\215\252\252\34\0\0\0U\252\252" + "8\0\0""8\252\252\0\0\0\0\0q\252q\0\0\0\0q\2528\0\0\0\0\252\252\252\252" + "\252\252\252\252\0\0\34\215\252q\34\252\252\0\0q\252\0\215\252\215\34" + "\0\0\0\0q\252\252\215\34\0\0q\252\252\34q\252\0\0\0\34\215\252\252q\34" + "\0\0\252\252\0\0\0\0q\252\252\252\306\377\306\0q\2528\0\0q\2528\0\0\252" + "\252\0\0\0\252\377U\0\0\252\252\0\0""8\252\252\0\0q\252\252\34""8\252" + "8\0\0q\2528\0\0\252\252\0\0""8\252q\0\0""8\252q\0\0\0\34\215\252\215" + "\34\0\0\0\252\377U\215\252\215\34\0\0\0\34\215\252\215U\377\252\0\0\252" + "\252\0\0\0\0""8\215\252\252q\0\0\0\34\252\252\215\0\0""8\252\252U\0\252" + "q\0\0\0\0\252\252U\0\0\0\0\34\252\252U\0\0""8\252\2528\0\0\252\252\34" + "\0\0\34\252\252\34\0\0\0q\377q\0\0\0\252\252\252\252\252\2528\0\0\34" + "\215\252\215\34\0\0""8\252\252\252\252\252\0q\252\252\252\252\252\252" + "8\0\0\0\0\0\306\377q\0\0\0\0\0\252\377U\0\0\0\0\0\0""8\377\342\0\0\0" + "\0U\252\252q\0\0\0\0\34\377\377\0\0\0\0\0\34\215\252\252q\0\0\0\0\0\0" + "\0\0\342\3778\0\0\0""8\252\252q\0\0\0\0\34\252U\0\0\0\0\0\0\0\0\0\0\0" + "U\252\252\377\342q\0\0\0\0\0\0\0\0\0\252\377\0\0\0\0q\252\2528\0\0\0" + "\0\34q\252\252q\34\0\342\215\0""8\377\215\0\0\0\0\0\252\3778\0\0q\377" + "U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\252\34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377U\0\0\306\3778\0q\377\215" + "\0\215\215\0\0U\252\34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\252" + "\0\0\0U\377U\0\0\0\0U\377U\0\0\377\252\0\0\0\0\0\0\0\342\342\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\252q\0\0\252U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377\342\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\252" + "\0\0\0\0\306\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\0\0\0\0\0\0U\377\252\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\306\3778\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\306\377" + "\342\0\0\0\0\0\0\252\377U\0\0\0\0\34q\377\377U\0\0\0\0\0\0\0\0\0\0\0" + "\0q\377\306\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\342\377\252\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\252\0\0\0\0\0\0\0" + "\0\0\0\252\215\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0q\3778\0\0" + "\0\0\0""8\377\215\0\0\306\342\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377" + "U\0\34\377\252\0\0\306\342\34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\377\342\0\0\0U\377U\0\0\0\0U\377U\0""8\377\252\0\0\0\0" + "\0\0\0\215\3778\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0q\377\342\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\34""8\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\342\377\215\0\0""8\342\342\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\34" + "\342\3778\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\0\0\0\0\0\0U" + "\377\252\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0q\377" + "\306\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0U\377\377\377\377\306\34\0\0\0\0\0\0\252\377U\0\0\252\377\377\377" + "\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\252\377q\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\252\377\377\377\252\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\252q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0q\252\0\0\0\0\0\0\0\252\215\0\0\342q\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0U\377U\0\34\215\0\0\0\215\34\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0U\377\377\377\377\377\377\377\377\377U\0\0\252\377\377\252" + "\0U\377\377\377UU\377\377\377U\252\377\377q\0\0\0\0\0\0\0""8\2528\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0""8\377\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377\377" + "\377\377\377\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\342\377\252\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\252\377U\0\0\0\0\0\0\0\0\0\0\0U\377\252\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0q\377\3778\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\34\252\252" + "q8\0\0\0\0\0\0\0\0""8U\34\0\0U\252\252U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0q\252q8\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0U\377U\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\34UUUUUUUUU\34\0\0\34\215\252q\0""8\252\252\252" + "88\252\252\2528q\252\215\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2158\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""8\215\252\252q\34\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0Uq\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0q\2528\0\0\0" + "\0\0\0\0\0\0\0\0""8\252q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\34\252\34\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0U\377U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + +static DFBSurfaceDescription font_desc = { + flags : DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | + DSDESC_PREALLOCATED, + width : 824, + height : 21, + pixelformat : DSPF_A8, + preallocated : {{ data : (void *) font_data, + pitch : 824 }} +}; + diff --git a/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_default.c b/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_default.c new file mode 100755 index 0000000..323d61a --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_default.c @@ -0,0 +1,322 @@ +/* + (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 <directfb.h> + +#include <core/fonts.h> +#include <core/gfxcard.h> +#include <core/surface.h> +#include <core/surface_buffer.h> + +#include <gfx/convert.h> + +#include <media/idirectfbfont.h> + +#include <direct/hash.h> + +#include <direct/interface.h> +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <direct/utf8.h> + +#include "default_font.h" + +#define DEFAULT_FONT_HEIGHT 24 +#define DEFAULT_FONT_ASCENDER 16 +#define DEFAULT_FONT_DESCENDER -4 + + +static DFBResult +Probe( IDirectFBFont_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBFont *thiz,
+ CoreDFB *core,
+ IDirectFBFont_ProbeContext *ctx,
+ DFBFontDescription *desc );
+ +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBFont, Default ) + + +static DFBResult +Probe( IDirectFBFont_ProbeContext *ctx ) +{ + /* default font is created with a NULL filename */ + if (ctx->filename) + return DFB_UNSUPPORTED; + + return DFB_OK; +} + +static DFBResult +Construct( IDirectFBFont *thiz,
+ CoreDFB *core,
+ IDirectFBFont_ProbeContext *ctx,
+ DFBFontDescription *desc )
+{ + DFBResult ret; + CoreFont *font; + CoreSurface *surface; + CoreFontCacheRow *row; + u8 *pixels; + int i; + + CoreSurfaceConfig config; + + D_DEBUG( "DirectFB/FontDefault: Construct default font"); + + if (desc->flags & DFDESC_ROTATION) { + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_UNSUPPORTED; + } + + ret = dfb_font_create( core, desc, "", &font ); + if (ret) { + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return ret; + } + + D_ASSERT( font->pixel_format == DSPF_ARGB || + font->pixel_format == DSPF_AiRGB || + font->pixel_format == DSPF_ARGB4444 || + font->pixel_format == DSPF_RGBA4444 || + font->pixel_format == DSPF_ARGB2554 || + font->pixel_format == DSPF_ARGB1555 || + font->pixel_format == DSPF_A8 || + font->pixel_format == DSPF_A4 || + font->pixel_format == DSPF_A1 ); + + font->height = DEFAULT_FONT_HEIGHT; + font->ascender = DEFAULT_FONT_ASCENDER; + font->descender = DEFAULT_FONT_DESCENDER; + font->up_unit_x = 0.0; + font->up_unit_y = -1.0; + + row = D_CALLOC( 1, sizeof(CoreFontCacheRow) ); + if (!row) { + D_OOM(); + dfb_font_destroy( font ); + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_NOSYSTEMMEMORY; + } + + config.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS; + config.size.w = font_desc.width; + config.size.h = font_desc.height; + config.format = font->pixel_format; + config.caps = font->surface_caps; + + ret = dfb_surface_create( core, &config, CSTF_FONT, 0, NULL, &surface ); + if (ret) { + dfb_font_destroy( font ); + return ret; + } + + font->num_rows = 1; + font->row_width = font_desc.width; + font->rows = D_MALLOC(sizeof (void *)); + font->rows[0] = row; + + row->surface = surface; + + D_MAGIC_SET( row, CoreFontCacheRow ); + + pixels = font_data; + + { + CoreGlyphData *data; + int use_unicode; + int start = 0; + int index = 0; + int key; + const char *glyphs = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "01234567890!\"$%&/()=?^<>" // FIXME: '0' is repeated! + "|,;.:-_{[]}\\`+*~#'"; + + if (desc && (desc->flags & DFDESC_ATTRIBUTES) && + (desc->attributes & DFFA_NOCHARMAP)) + use_unicode = 0; + else + use_unicode = 1; + + for (i = 0; i < font_desc.width; i++) { + if (pixels[i] == 0xFF) { + if (use_unicode) + key = glyphs[index]; + else + key = index; + + if (!direct_hash_lookup( font->layers[0].glyph_hash, key )) { + data = D_CALLOC( 1, sizeof(CoreGlyphData) ); + data->surface = surface; + data->start = start; + data->width = i - start + 1; + data->height = font_desc.height - 1; + data->left = 0; + data->top = 0; + data->xadvance = ((desc && (desc->flags & + DFDESC_FIXEDADVANCE)) ? + desc->fixed_advance : + data->width + 1); + data->yadvance = 0; + + D_DEBUG( "DirectFB/core/fonts: " + "glyph '%c' at %d, width %d\n", + glyphs[index], start, i-start ); + + D_MAGIC_SET( data, CoreGlyphData ); + + if (font->maxadvance < data->xadvance) + font->maxadvance = data->xadvance; + + direct_hash_insert( font->layers[0].glyph_hash, key, data ); + } + + start = i + 1; + index++; + } + if (glyphs[index] == '\0') + break; + } + + /* space */ + data = D_CALLOC( 1, sizeof(CoreGlyphData) ); + data->xadvance = 5; + data->yadvance = 0; + + D_MAGIC_SET( data, CoreGlyphData ); + + if (use_unicode) + key = 32; + else + key = index; + + direct_hash_insert( font->layers[0].glyph_hash, key, data ); + } + + { + CoreSurfaceBufferLock lock; + + ret = dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); + if (ret) { + D_DERROR( ret, "IDirectFBFont_Default: Could not lock surface buffer!\n" ); + } + else { + for (i = 1; i < font_desc.height; i++) { + int i, j, n; + u8 *dst8 = lock.addr; + u16 *dst16 = lock.addr; + u32 *dst32 = lock.addr; + + pixels += font_desc.preallocated[0].pitch; + switch (surface->config.format) { + case DSPF_ARGB: + if (surface->config.caps & DSCAPS_PREMULTIPLIED) { + for (i=0; i<font_desc.width; i++) + dst32[i] = pixels[i] * 0x01010101; + } + else + for (i=0; i<font_desc.width; i++) + dst32[i] = (pixels[i] << 24) | 0xFFFFFF; + break; + case DSPF_AiRGB: + for (i=0; i<font_desc.width; i++) + dst32[i] = ((pixels[i] ^ 0xFF) << 24) | 0xFFFFFF; + break; + case DSPF_ARGB4444: + case DSPF_RGBA4444: + if (surface->config.caps & DSCAPS_PREMULTIPLIED) { + for (i=0; i<font_desc.width; i++) + dst16[i] = (pixels[i] >> 4) * 0x1111; + } + else { + if( surface->config.format == DSPF_ARGB4444 ) { + for (i=0; i<font_desc.width; i++) + dst16[i] = (pixels[i] << 8) | 0x0FFF; + } else { + for (i=0; i<font_desc.width; i++) + dst16[i] = (pixels[i] >> 4) | 0xFFF0; + } + } + break; + case DSPF_ARGB2554: + for (i=0; i<font_desc.width; i++) + dst16[i] = (pixels[i] << 8) | 0x3FFF; + break; + case DSPF_ARGB1555: + for (i=0; i<font_desc.width; i++) + dst16[i] = (pixels[i] << 8) | 0x7FFF; + break; + case DSPF_A8: + direct_memcpy( lock.addr, pixels, font_desc.width ); + break; + case DSPF_A4: + for (i=0, j=0; i<font_desc.width; i+=2, j++) + dst8[j] = (pixels[i] & 0xF0) | (pixels[i+1] >> 4); + break; + case DSPF_A1: + for (i=0, j=0; i < font_desc.width; ++j) { + register u8 p = 0; + + for (n=0; n<8 && i<font_desc.width; ++i, ++n) + p |= (pixels[i] & 0x80) >> n; + + dst8[j] = p; + } + break; + case DSPF_LUT2: + for (i=0, j=0; i < font_desc.width; ++j) { + register u8 p = 0; + + for (n=0; n<8 && i<font_desc.width; ++i, n+=2) + p |= (pixels[i] & 0xC0) >> n; + + dst8[j] = p; + } + break; + default: + D_UNIMPLEMENTED(); + break; + } + + lock.addr += lock.pitch; + } + + dfb_surface_unlock_buffer( surface, &lock ); + } + } + + return IDirectFBFont_Construct (thiz, font); +} diff --git a/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_dgiff.c b/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_dgiff.c new file mode 100755 index 0000000..5e1977c --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_dgiff.c @@ -0,0 +1,364 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp <dok@directfb.org>, + Andreas Hundt <andi@fischlustig.de>, + Sven Neumann <neo@directfb.org>, + Ville Syrjälä <syrjala@sci.fi> and + Claudio Ciccani <klan@users.sf.net>. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> + +#include <fcntl.h> +#include <unistd.h> + +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <directfb.h> + +#include <core/fonts.h> +#include <core/gfxcard.h> +#include <core/surface.h> +#include <core/surface_buffer.h> + +#include <gfx/convert.h> + +#include <media/idirectfbfont.h> + +#include <direct/hash.h> + +#include <direct/interface.h> +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <direct/utf8.h> + +#include <dgiff.h> + +/**********************************************************************************************************************/ + +static DFBResult +Probe( IDirectFBFont_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBFont *thiz,
+ CoreDFB *core,
+ IDirectFBFont_ProbeContext *ctx,
+ DFBFontDescription *desc );
+ +/**********************************************************************************************************************/ + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBFont, DGIFF ) + +/**********************************************************************************************************************/ + +typedef struct { + void *map; /* Memory map of the file. */ + int size; /* Size of the memory map. */ +} DGIFFImplData; + +/**********************************************************************************************************************/ + +static void +IDirectFBFont_DGIFF_Destruct( IDirectFBFont *thiz ) +{ + IDirectFBFont_data *data = thiz->priv; + CoreFont *font = data->font; + DGIFFImplData *impl = font->impl_data; + + munmap( impl->map, impl->size ); + + D_FREE( impl ); + + IDirectFBFont_Destruct( thiz ); +} + + +static DirectResult +IDirectFBFont_DGIFF_Release( IDirectFBFont *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBFont) + + if (--data->ref == 0) { + IDirectFBFont_DGIFF_Destruct( thiz ); + } + + return DFB_OK; +} + +static DFBResult +Probe( IDirectFBFont_ProbeContext *ctx ) +{ + DFBResult ret = DFB_OK; + int fd; + DGIFFHeader header; + + if (!ctx->filename) + return DFB_UNSUPPORTED; + + /* Open the file. */ + fd = open( ctx->filename, O_RDONLY ); + if (fd < 0) { + ret = errno2result( errno ); + D_PERROR( "Font/DGIFF: Failure during open() of '%s'!\n", ctx->filename ); + goto out; + } + + /* Read the header. */ + if (read( fd, &header, sizeof(header) ) != sizeof(header)) { + ret = errno2result( errno ); + D_PERROR( "Font/DGIFF: Failure reading %zu bytes from '%s'!\n", sizeof(header), ctx->filename ); + goto out; + } + + /* Check the magic. */ + if (strncmp( (char*) header.magic, "DGIFF", 5 )) + ret = DFB_UNSUPPORTED; + +out: + if (fd >= 0) + close( fd ); + + return ret; +} + +static DFBResult +Construct( IDirectFBFont *thiz,
+ CoreDFB *core,
+ IDirectFBFont_ProbeContext *ctx,
+ DFBFontDescription *desc )
+{ + DFBResult ret; + int i; + int fd; + struct stat stat; + void *ptr = MAP_FAILED; + CoreFont *font = NULL; + DGIFFHeader *header; + DGIFFFaceHeader *face; + DGIFFGlyphInfo *glyphs; + DGIFFGlyphRow *row; + DGIFFImplData *data; + char *filename;
+ CoreSurfaceConfig config; + +// if (desc->flags & (DFDESC_WIDTH | DFDESC_ATTRIBUTES | DFDESC_FIXEDADVANCE)) + // return DFB_UNSUPPORTED; + /* use the filename for backwards compatibility */
+ filename = ctx->filename;
+ + if (desc->flags & DFDESC_ROTATION) + return DFB_UNSUPPORTED; + + /* Open the file. */ + fd = open( filename, O_RDONLY ); + if (fd < 0) { + ret = errno2result( errno ); + D_PERROR( "Font/DGIFF: Failure during open() of '%s'!\n", filename ); + return ret; + } + + /* Query file size etc. */ + if (fstat( fd, &stat ) < 0) { + ret = errno2result( errno ); + D_PERROR( "Font/DGIFF: Failure during fstat() of '%s'!\n", filename ); + goto error; + } + + /* Memory map the file. */ + ptr = mmap( NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0 ); + if (ptr == MAP_FAILED) { + ret = errno2result( errno ); + D_PERROR( "Font/DGIFF: Failure during mmap() of '%s'!\n", filename ); + goto error; + } + + /* Keep entry pointers for main header and face. */ + header = ptr; + face = ptr + sizeof(DGIFFHeader); + + /* Lookup requested face, otherwise use first if nothing requested or show error if not found. */ + if (desc->flags & DFDESC_HEIGHT) { + for (i=0; i<header->num_faces; i++) { + if (face->size == desc->height) + break; + + face = ((void*) face) + face->next_face; + } + + if (i == header->num_faces) { + ret = DFB_UNSUPPORTED; + D_ERROR( "Font/DGIFF: Requested size %d not found in '%s'!\n", desc->height, filename ); + goto error; + } + } + + glyphs = (void*)(face + 1); + row = (void*)(glyphs + face->num_glyphs); + + /* Create the core object. */ + ret = dfb_font_create( core, desc, filename, &font ); + if (ret) + goto error; + + /* Fill font information. */ + font->ascender = face->ascender; + font->descender = face->descender; + font->height = face->height; + font->up_unit_x = 0.0; + font->up_unit_y = -1.0; + + font->maxadvance = face->max_advance; + font->pixel_format = face->pixelformat; + font->surface_caps = DSCAPS_NONE; + + font->num_rows = face->num_rows; + + if (face->blittingflags) + font->blittingflags = face->blittingflags; + + /* Allocate array for glyph cache rows. */ + font->rows = D_CALLOC( face->num_rows, sizeof(void*) ); + if (!font->rows) { + ret = D_OOM(); + goto error; + } + + /* Build glyph cache rows. */ + + config.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_PREALLOCATED; + config.format = face->pixelformat; + config.preallocated[1].addr = NULL; + config.preallocated[1].pitch = 0; + + for (i=0; i<face->num_rows; i++) { + font->rows[i] = D_CALLOC( 1, sizeof(CoreFontCacheRow) ); + if (!font->rows[i]) { + ret = D_OOM(); + goto error; + } + + config.size.w = row->width; + config.size.h = row->height; + config.preallocated[0].addr = (void*)(row+1); + config.preallocated[0].pitch = row->pitch; + + ret = dfb_surface_create( core, &config, CSTF_PREALLOCATED, 0, NULL, + &font->rows[i]->surface ); + + if (ret) { + D_DERROR( ret, "DGIFF/Font: Could not create preallocated %s %dx%d glyph row surface!\n", + dfb_pixelformat_name(face->pixelformat), row->width, row->height ); + goto error; + } + + D_MAGIC_SET( font->rows[i], CoreFontCacheRow ); + + /* Jump to next row. */ + row = (void*)(row + 1) + row->pitch * row->height; + } + + /* Build glyph infos. */ + for (i=0; i<face->num_glyphs; i++) { + CoreGlyphData *data; + DGIFFGlyphInfo *glyph = &glyphs[i]; + + data = D_CALLOC( 1, sizeof(CoreGlyphData) ); + if (!data) { + ret = D_OOM(); + goto error; + } + + data->surface = font->rows[glyph->row]->surface; + + data->start = glyph->offset; + data->width = glyph->width; + data->height = glyph->height; + data->left = glyph->left; + data->top = glyph->top; + data->xadvance = glyph->advance; + data->yadvance = 0; + + D_MAGIC_SET( data, CoreGlyphData ); + + direct_hash_insert( font->layers[0].glyph_hash, glyph->unicode, data ); + + if (glyph->unicode < 128) + font->layers[0].glyph_data[glyph->unicode] = data; + } + + + data = D_CALLOC( 1, sizeof(DGIFFImplData) ); + if (!data) { + ret = D_OOM(); + goto error; + } + + data->map = ptr; + data->size = stat.st_size; + + font->impl_data = data; + + /* Already close, we still have the map. */ + close( fd ); + + ret = IDirectFBFont_Construct( thiz, font ); + D_ASSERT( ret == DFB_OK ); + + thiz->Release = IDirectFBFont_DGIFF_Release; + + return DFB_OK; + + +error: + if (font) { + if (font->rows) { + for (i=0; i<font->num_rows; i++) { + if (font->rows[i]) { + if (font->rows[i]->surface) + dfb_surface_unref( font->rows[i]->surface ); + + D_FREE( font->rows[i] ); + } + } + + D_FREE( font->rows ); + + font->rows = NULL; + } + + dfb_font_destroy( font ); + } + + if (ptr != MAP_FAILED) + munmap( ptr, stat.st_size ); + + close( fd ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); + + return ret; +} + diff --git a/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_ft2.c b/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_ft2.c new file mode 100755 index 0000000..b5dc666 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_ft2.c @@ -0,0 +1,949 @@ +/* + (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 <unistd.h> +#include <stdarg.h> +#include <math.h> + +#include <directfb.h> + +#include <core/fonts.h> +#include <core/gfxcard.h> +#include <core/surface.h> +#include <core/surface_buffer.h> + +#include <gfx/convert.h> + +#include <media/idirectfbfont.h> + +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <direct/messages.h> +#include <direct/utf8.h> +#include <direct/util.h> + +#include <misc/conf.h> +#include <misc/util.h> + +#undef SIZEOF_LONG +#include <ft2build.h> +#include FT_GLYPH_H + +#ifndef FT_LOAD_TARGET_MONO + /* FT_LOAD_TARGET_MONO was added in FreeType-2.1.3, we have to use (less good) + FT_LOAD_MONOCHROME with older versions. Make it an alias for code simplicity. */ + #define FT_LOAD_TARGET_MONO FT_LOAD_MONOCHROME +#endif + + +static DFBResult +Probe( IDirectFBFont_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBFont *thiz,
+ CoreDFB *core,
+ IDirectFBFont_ProbeContext *ctx,
+ DFBFontDescription *desc );
+ +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBFont, FT2 ) + +static FT_Library library = NULL; +static int library_ref_count = 0; +static pthread_mutex_t library_mutex = PTHREAD_MUTEX_INITIALIZER; + +#define KERNING_CACHE_MIN 0 +#define KERNING_CACHE_MAX 127 +#define KERNING_CACHE_SIZE (KERNING_CACHE_MAX - KERNING_CACHE_MIN + 1) + +#define KERNING_DO_CACHE(a,b) ((a) >= KERNING_CACHE_MIN && \ + (a) <= KERNING_CACHE_MAX && \ + (b) >= KERNING_CACHE_MIN && \ + (b) <= KERNING_CACHE_MAX) + +#define KERNING_CACHE_ENTRY(a,b) \ + (data->kerning[(a)-KERNING_CACHE_MIN][(b)-KERNING_CACHE_MIN]) + +#define CHAR_INDEX(c) (((c) < 256) ? data->indices[c] : FT_Get_Char_Index( data->face, c )) + +typedef struct { + FT_Face face; + int disable_charmap; + int fixed_advance; + bool fixed_clip; + unsigned int indices[256]; +} FT2ImplData; + +typedef struct { + signed char x; + signed char y; +} KerningCacheEntry; + +typedef struct { + FT2ImplData base; + + KerningCacheEntry kerning[KERNING_CACHE_SIZE][KERNING_CACHE_SIZE]; +} FT2ImplKerningData; + +/**********************************************************************************************************************/ + +static DFBResult +ft2UTF8GetCharacterIndex( CoreFont *thiz, + unsigned int character, + unsigned int *ret_index ) +{ + FT2ImplData *data = thiz->impl_data; + + D_MAGIC_ASSERT( thiz, CoreFont ); + + if (data->disable_charmap) + *ret_index = character; + else { + pthread_mutex_lock ( &library_mutex ); + + *ret_index = CHAR_INDEX( character ); + + pthread_mutex_unlock ( &library_mutex ); + } + + return DFB_OK; +} + +static DFBResult +ft2UTF8DecodeText( CoreFont *thiz, + const void *text, + int length, + unsigned int *ret_indices, + int *ret_num ) +{ + int pos = 0, num = 0; + const u8 *bytes = text; + FT2ImplData *data = thiz->impl_data; + + D_MAGIC_ASSERT( thiz, CoreFont ); + D_ASSERT( text != NULL ); + D_ASSERT( length >= 0 ); + D_ASSERT( ret_indices != NULL ); + D_ASSERT( ret_num != NULL ); + + pthread_mutex_lock ( &library_mutex ); + + while (pos < length) { + unsigned int c; + + if (bytes[pos] < 128) + c = bytes[pos++]; + else { + c = DIRECT_UTF8_GET_CHAR( &bytes[pos] ); + pos += DIRECT_UTF8_SKIP(bytes[pos]); + } + + if (data->disable_charmap) + ret_indices[num++] = c; + else + ret_indices[num++] = CHAR_INDEX( c ); + } + + pthread_mutex_unlock ( &library_mutex ); + + *ret_num = num; + + return DFB_OK; +} + +static const CoreFontEncodingFuncs ft2UTF8Funcs = { + .GetCharacterIndex = ft2UTF8GetCharacterIndex, + .DecodeText = ft2UTF8DecodeText, +}; + +/**********************************************************************************************************************/ + +static DFBResult +ft2Latin1GetCharacterIndex( CoreFont *thiz, + unsigned int character, + unsigned int *ret_index ) +{ + FT2ImplData *data = thiz->impl_data; + + D_MAGIC_ASSERT( thiz, CoreFont ); + + if (data->disable_charmap) + *ret_index = character; + else + *ret_index = data->indices[character]; + + return DFB_OK; +} + +static DFBResult +ft2Latin1DecodeText( CoreFont *thiz, + const void *text, + int length, + unsigned int *ret_indices, + int *ret_num ) +{ + int i; + const u8 *bytes = text; + FT2ImplData *data = thiz->impl_data; + + D_MAGIC_ASSERT( thiz, CoreFont ); + D_ASSERT( text != NULL ); + D_ASSERT( length >= 0 ); + D_ASSERT( ret_indices != NULL ); + D_ASSERT( ret_num != NULL ); + + if (data->disable_charmap) { + for (i=0; i<length; i++) + ret_indices[i] = bytes[i]; + } + else { + for (i=0; i<length; i++) + ret_indices[i] = data->indices[bytes[i]]; + } + + *ret_num = length; + + return DFB_OK; +} + +static const CoreFontEncodingFuncs ft2Latin1Funcs = { + .GetCharacterIndex = ft2Latin1GetCharacterIndex, + .DecodeText = ft2Latin1DecodeText, +}; + +/**********************************************************************************************************************/ + +static DFBResult +render_glyph( CoreFont *thiz, + unsigned int index, + CoreGlyphData *info ) +{ + FT_Error err; + FT_Face face; + FT_Int load_flags; + u8 *src; + int y; + FT2ImplData *data = thiz->impl_data; + CoreSurface *surface = info->surface; + CoreSurfaceBufferLock lock; + + pthread_mutex_lock ( &library_mutex ); + + face = data->face; + + load_flags = (unsigned long) face->generic.data; + load_flags |= FT_LOAD_RENDER; + + if ((err = FT_Load_Glyph( face, index, load_flags ))) { + D_DEBUG( "DirectFB/FontFT2: Could not render glyph for character index #%d!\n", index ); + pthread_mutex_unlock ( &library_mutex ); + return DFB_FAILURE; + } + + pthread_mutex_unlock ( &library_mutex ); + + err = dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); + if (err) { + D_DERROR( err, "DirectFB/FontFT2: Unable to lock surface!\n" ); + return err; + } + + info->width = face->glyph->bitmap.width; + if (info->width + info->start > surface->config.size.w) + info->width = surface->config.size.w - info->start; + + info->height = face->glyph->bitmap.rows; + if (info->height > surface->config.size.h) + info->height = surface->config.size.h; + + /* bitmap_left and bitmap_top are relative to the glyph's origin on the + baseline. info->left and info->top are relative to the top-left of the + character cell. */ + info->left = face->glyph->bitmap_left - thiz->ascender*thiz->up_unit_x; + info->top = - face->glyph->bitmap_top - thiz->ascender*thiz->up_unit_y; + + if (data->fixed_clip) { + while (info->left + info->width > data->fixed_advance) + info->left--; + + if (info->left < 0) + info->left = 0; + + if (info->width > data->fixed_advance) + info->width = data->fixed_advance; + } + + src = face->glyph->bitmap.buffer; + lock.addr += DFB_BYTES_PER_LINE(surface->config.format, info->start); + + for (y=0; y < info->height; y++) { + int i, j, n; + u8 *dst8 = lock.addr; + u16 *dst16 = lock.addr; + u32 *dst32 = lock.addr; + + switch (face->glyph->bitmap.pixel_mode) { + case ft_pixel_mode_grays: + switch (surface->config.format) { + case DSPF_ARGB: + if (thiz->surface_caps & DSCAPS_PREMULTIPLIED) { + for (i=0; i<info->width; i++) + dst32[i] = src[i] * 0x01010101; + } + else + for (i=0; i<info->width; i++) + dst32[i] = (src[i] << 24) | 0xFFFFFF; + break; + case DSPF_AiRGB: + for (i=0; i<info->width; i++) + dst32[i] = ((src[i] ^ 0xFF) << 24) | 0xFFFFFF; + break; + case DSPF_ARGB4444: + case DSPF_RGBA4444: + if (thiz->surface_caps & DSCAPS_PREMULTIPLIED) { + for (i=0; i<info->width; i++) + dst16[i] = (src[i] >> 4) * 0x1111; + } + else { + if( surface->config.format == DSPF_ARGB4444 ) { + for (i=0; i<info->width; i++) + dst16[i] = (src[i] << 8) | 0x0FFF; + } else { + for (i=0; i<info->width; i++) + dst16[i] = (src[i] >> 4) | 0xFFF0; + } + } + break; + case DSPF_ARGB2554: + for (i=0; i<info->width; i++) + dst16[i] = (src[i] << 8) | 0x3FFF; + break; + case DSPF_ARGB1555: + for (i=0; i<info->width; i++) + dst16[i] = (src[i] << 8) | 0x7FFF; + break; + case DSPF_A8: + direct_memcpy( lock.addr, src, info->width ); + break; + case DSPF_A4: + for (i=0, j=0; i<info->width; i+=2, j++) + dst8[j] = (src[i] & 0xF0) | (src[i+1] >> 4); + break; + case DSPF_A1: + for (i=0, j=0; i < info->width; ++j) { + register u8 p = 0; + + for (n=0; n<8 && i<info->width; ++i, ++n) + p |= (src[i] & 0x80) >> n; + + dst8[j] = p; + } + break; + case DSPF_LUT2: + for (i=0, j=0; i < info->width; ++j) { + register u8 p = 0; + + for (n=0; n<8 && i<info->width; ++i, n+=2) + p |= (src[i] & 0xC0) >> n; + + dst8[j] = p; + } + break; + default: + D_UNIMPLEMENTED(); + break; + } + break; + + case ft_pixel_mode_mono: + switch (surface->config.format) { + case DSPF_ARGB: + for (i=0; i<info->width; i++) + dst32[i] = (((src[i>>3] & (1<<(7-(i%8)))) ? + 0xFF : 0x00) << 24) | 0xFFFFFF; + break; + case DSPF_AiRGB: + for (i=0; i<info->width; i++) + dst32[i] = (((src[i>>3] & (1<<(7-(i%8)))) ? + 0x00 : 0xFF) << 24) | 0xFFFFFF; + break; + case DSPF_ARGB4444: + for (i=0; i<info->width; i++) + dst16[i] = (((src[i>>3] & (1<<(7-(i%8)))) ? + 0xF : 0x0) << 12) | 0xFFF; + break; + case DSPF_RGBA4444: + for (i=0; i<info->width; i++) + dst16[i] = (((src[i>>3] & (1<<(7-(i%8)))) ? + 0xF : 0x0) ) | 0xFFF0; + break; + case DSPF_ARGB2554: + for (i=0; i<info->width; i++) + dst16[i] = (((src[i>>3] & (1<<(7-(i%8)))) ? + 0x3 : 0x0) << 14) | 0x3FFF; + break; + case DSPF_ARGB1555: + for (i=0; i<info->width; i++) + dst16[i] = (((src[i>>3] & (1<<(7-(i%8)))) ? + 0x1 : 0x0) << 15) | 0x7FFF; + break; + case DSPF_A8: + for (i=0; i<info->width; i++) + dst8[i] = (src[i>>3] & + (1<<(7-(i%8)))) ? 0xFF : 0x00; + break; + case DSPF_A4: + for (i=0, j=0; i<info->width; i+=2, j++) + dst8[j] = ((src[i>>3] & + (1<<(7-(i%8)))) ? 0xF0 : 0x00) | + ((src[(i+1)>>3] & + (1<<(7-((i+1)%8)))) ? 0x0F : 0x00); + break; + case DSPF_A1: + direct_memcpy( lock.addr, src, DFB_BYTES_PER_LINE(DSPF_A1, info->width) ); + break; + default: + D_UNIMPLEMENTED(); + break; + } + break; + + default: + break; + + } + + src += face->glyph->bitmap.pitch; + + lock.addr += lock.pitch; + } + + dfb_surface_unlock_buffer( surface, &lock ); + + return DFB_OK; +} + + +static DFBResult +get_glyph_info( CoreFont *thiz, + unsigned int index, + CoreGlyphData *info ) +{ + FT_Error err; + FT_Face face; + FT_Int load_flags; + FT2ImplData *data = (FT2ImplData*) thiz->impl_data; + + pthread_mutex_lock ( &library_mutex ); + + face = data->face; + + load_flags = (unsigned long) face->generic.data; + + if ((err = FT_Load_Glyph( face, index, load_flags ))) { + D_DEBUG( "DirectFB/FontFT2: Could not load glyph for character index #%d!\n", index ); + + pthread_mutex_unlock ( &library_mutex ); + + return DFB_FAILURE; + } + + if (face->glyph->format != ft_glyph_format_bitmap) { + err = FT_Render_Glyph( face->glyph, + (load_flags & FT_LOAD_TARGET_MONO) ? ft_render_mode_mono : ft_render_mode_normal ); + if (err) { + D_ERROR( "DirectFB/FontFT2: Could not render glyph for character index #%d!\n", index ); + + pthread_mutex_unlock ( &library_mutex ); + + return DFB_FAILURE; + } + } + + pthread_mutex_unlock ( &library_mutex ); + + info->width = face->glyph->bitmap.width; + info->height = face->glyph->bitmap.rows; + + if (data->fixed_advance) { + info->xadvance = - data->fixed_advance * thiz->up_unit_y; + info->yadvance = data->fixed_advance * thiz->up_unit_x; + } + else { + info->xadvance = face->glyph->advance.x >> 6; + info->yadvance = - face->glyph->advance.y >> 6; + } + + if (data->fixed_clip && info->width > data->fixed_advance) + info->width = data->fixed_advance; + + return DFB_OK; +} + + +static DFBResult +get_kerning( CoreFont *thiz, + unsigned int prev, + unsigned int current, + int *kern_x, + int *kern_y) +{ + FT_Vector vector; + + FT2ImplKerningData *data = thiz->impl_data; + KerningCacheEntry *cache = NULL; + + D_ASSUME( (kern_x != NULL) || (kern_y != NULL) ); + + /* + * Use cached values if characters are in the + * cachable range and the cache entry is already filled. + */ + if (KERNING_DO_CACHE (prev, current)) { + cache = &KERNING_CACHE_ENTRY (prev, current); + + if (kern_x) + *kern_x = (int) cache->x; + + if (kern_y) + *kern_y = (int) cache->y; + + return DFB_OK; + } + + pthread_mutex_lock ( &library_mutex ); + + /* Lookup kerning values for the character pair. */ + /* The vector returned by FreeType does not allow for any rotation. */ + FT_Get_Kerning( data->base.face, + prev, current, ft_kerning_default, &vector ); + + pthread_mutex_unlock ( &library_mutex ); + + /* Convert to integer. */ + if (kern_x) + *kern_x = (int)(- vector.x*thiz->up_unit_y + vector.y*thiz->up_unit_x) >> 6; + + if (kern_y) + *kern_y = (int)( vector.y*thiz->up_unit_y + vector.x*thiz->up_unit_x) >> 6; + + return DFB_OK; +} + +static void +init_kerning_cache( FT2ImplKerningData *data, float up_unit_x, float up_unit_y ) +{ + int a, b; + + pthread_mutex_lock ( &library_mutex ); + + for (a=KERNING_CACHE_MIN; a<=KERNING_CACHE_MAX; a++) { + for (b=KERNING_CACHE_MIN; b<=KERNING_CACHE_MAX; b++) { + FT_Vector vector; + KerningCacheEntry *cache = &KERNING_CACHE_ENTRY( a, b ); + + /* Lookup kerning values for the character pair. */ + FT_Get_Kerning( data->base.face, + a, b, ft_kerning_default, &vector ); + + cache->x = (signed char) ((int)(- vector.x*up_unit_y + vector.y*up_unit_x) >> 6); + cache->y = (signed char) ((int)( vector.y*up_unit_y + vector.x*up_unit_x) >> 6); + } + } + + pthread_mutex_unlock ( &library_mutex ); +} + +static DFBResult +init_freetype( void ) +{ + FT_Error err; + + pthread_mutex_lock ( &library_mutex ); + + if (!library) { + D_DEBUG( "DirectFB/FontFT2: Initializing the FreeType2 library.\n" ); + err = FT_Init_FreeType( &library ); + if (err) { + D_ERROR( "DirectFB/FontFT2: " + "Initialization of the FreeType2 library failed!\n" ); + library = NULL; + pthread_mutex_unlock( &library_mutex ); + return DFB_FAILURE; + } + } + + library_ref_count++; + pthread_mutex_unlock( &library_mutex ); + + return DFB_OK; +} + + +static void +release_freetype( void ) +{ + pthread_mutex_lock( &library_mutex ); + + if (library && --library_ref_count == 0) { + D_DEBUG( "DirectFB/FontFT2: Releasing the FreeType2 library.\n" ); + FT_Done_FreeType( library ); + library = NULL; + } + + pthread_mutex_unlock( &library_mutex ); +} + + +static void +IDirectFBFont_FT2_Destruct( IDirectFBFont *thiz ) +{ + IDirectFBFont_data *data = (IDirectFBFont_data*)thiz->priv; + + if (data->font->impl_data) { + FT2ImplData *impl_data = (FT2ImplData*) data->font->impl_data; + + pthread_mutex_lock ( &library_mutex ); + FT_Done_Face( impl_data->face ); + pthread_mutex_unlock ( &library_mutex ); + + D_FREE( impl_data ); + + data->font->impl_data = NULL; + } + + IDirectFBFont_Destruct( thiz ); + + release_freetype(); +} + + +static DirectResult +IDirectFBFont_FT2_Release( IDirectFBFont *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBFont) + + if (--data->ref == 0) { + IDirectFBFont_FT2_Destruct( thiz ); + } + + return DFB_OK; +} + + +static DFBResult +Probe( IDirectFBFont_ProbeContext *ctx ) +{ + FT_Error err; + FT_Face face; + + D_DEBUG( "DirectFB/FontFT2: Probe font `%s'.\n", ctx->filename ); + + if (!ctx->content)
+ return DFB_UNSUPPORTED; + + if (init_freetype() != DFB_OK) { + return DFB_FAILURE; + } + + pthread_mutex_lock ( &library_mutex );
+ + /* + * This should be + * err = FT_New...Face( library, ctx->filename, -1, NULL );
+ * but due to freetype bugs it doesn't work. + */ + err = FT_New_Memory_Face( library, ctx->content, ctx->content_size, 0, &face );
+ if (!err) + FT_Done_Face( face ); + pthread_mutex_unlock ( &library_mutex ); + + release_freetype(); + + return err ? DFB_UNSUPPORTED : DFB_OK; +} + + +static DFBResult +Construct( IDirectFBFont *thiz,
+ CoreDFB *core,
+ IDirectFBFont_ProbeContext *ctx,
+ DFBFontDescription *desc )
+{ + int i; + DFBResult ret; + CoreFont *font; + FT_Face face; + FT_Error err; + FT_Int load_flags = FT_LOAD_DEFAULT; + FT2ImplData *data; + bool disable_charmap = false; + bool disable_kerning = false; + bool load_mono = false; + u32 mask = 0; + unsigned int size = 0, size_read = 0;
+ char *filename = ctx->filename; /* intended for printf only */
+ + float sin_rot = 0.0; + float cos_rot = 1.0; + + D_DEBUG( "DirectFB/FontFT2: " + "Construct font from file `%s' (index %d) at pixel size %d x %d and rotation %d.\n", + filename, + (desc->flags & DFDESC_INDEX) ? desc->index : 0, + (desc->flags & DFDESC_WIDTH) ? desc->width : 0, + (desc->flags & DFDESC_HEIGHT) ? desc->height : 0, + (desc->flags & DFDESC_ROTATION) ? desc->rotation : 0 ); + + if (init_freetype() != DFB_OK) { + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_FAILURE; + } + + pthread_mutex_lock ( &library_mutex ); + err = FT_New_Memory_Face( library, ctx->content, ctx->content_size,
+ (desc->flags & DFDESC_INDEX) ? desc->index : 0,
+ &face );
+ pthread_mutex_unlock ( &library_mutex ); + if (err) { + switch (err) { + case FT_Err_Unknown_File_Format: + D_ERROR( "DirectFB/FontFT2: " + "Unsupported font format in file `%s'!\n", filename ); + break; + default: + D_ERROR( "DirectFB/FontFT2: " + "Failed loading face %d from font file `%s'!\n", + (desc->flags & DFDESC_INDEX) ? desc->index : 0, + filename ); + break; + } + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_FAILURE; + } + + if ((desc->flags & DFDESC_ROTATION) && desc->rotation) { + if (!FT_IS_SCALABLE(face)) { + D_ERROR( "DirectFB/FontFT2: " + "Face %d from font file `%s' is not scalable so cannot be rotated\n", + (desc->flags & DFDESC_INDEX) ? desc->index : 0, + filename ); + pthread_mutex_lock ( &library_mutex ); + FT_Done_Face( face ); + pthread_mutex_unlock ( &library_mutex ); + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_UNSUPPORTED; + } + + float rot_radians = 2.0 * M_PI * desc->rotation / (1<<24); + sin_rot = sin(rot_radians); + cos_rot = cos(rot_radians); + + int sin_rot_fx = (int)(sin_rot*65536.0); + int cos_rot_fx = (int)(cos_rot*65536.0); + FT_Matrix matrix; + matrix.xx = cos_rot_fx; + matrix.xy = -sin_rot_fx; + matrix.yx = sin_rot_fx; + matrix.yy = cos_rot_fx; + + pthread_mutex_lock ( &library_mutex ); + FT_Set_Transform( face, &matrix, NULL ); + /* FreeType docs suggest FT_Set_Transform returns an error code, but it seems + that this is not the case. */ + pthread_mutex_unlock ( &library_mutex ); + } + + if (dfb_config->font_format == DSPF_A1 || dfb_config->font_format == DSPF_ARGB1555) + load_mono = true; + + if (desc->flags & DFDESC_ATTRIBUTES) { + if (desc->attributes & DFFA_NOHINTING) + load_flags |= FT_LOAD_NO_HINTING; + if (desc->attributes & DFFA_NOBITMAP) + load_flags |= FT_LOAD_NO_BITMAP; + if (desc->attributes & DFFA_NOCHARMAP) + disable_charmap = true; + if (desc->attributes & DFFA_NOKERNING) + disable_kerning = true; + if (desc->attributes & DFFA_MONOCHROME) + load_mono = true; + } + + if (load_mono) + load_flags |= FT_LOAD_TARGET_MONO; + + if (!disable_charmap) { + pthread_mutex_lock ( &library_mutex ); + err = FT_Select_Charmap( face, ft_encoding_unicode ); + pthread_mutex_unlock ( &library_mutex ); + +#if FREETYPE_MINOR > 0 + + /* ft_encoding_latin_1 has been introduced in freetype-2.1 */ + if (err) { + D_DEBUG( "DirectFB/FontFT2: " + "Couldn't select Unicode encoding, " + "falling back to Latin1.\n"); + pthread_mutex_lock ( &library_mutex ); + err = FT_Select_Charmap( face, ft_encoding_latin_1 ); + pthread_mutex_unlock ( &library_mutex ); + } +#endif + if (err) { + D_DEBUG( "DirectFB/FontFT2: " + "Couldn't select Unicode/Latin1 encoding, " + "trying Symbol.\n"); + pthread_mutex_lock ( &library_mutex ); + err = FT_Select_Charmap( face, ft_encoding_symbol ); + pthread_mutex_unlock ( &library_mutex ); + + if (!err) + mask = 0xf000; + } + } + +#if 0 + if (err) { + D_ERROR( "DirectFB/FontFT2: " + "Couldn't select a suitable encoding for face %d from font file `%s'!\n", (desc->flags & DFDESC_INDEX) ? desc->index : 0, filename ); + pthread_mutex_lock ( &library_mutex ); + FT_Done_Face( face ); + pthread_mutex_unlock ( &library_mutex ); + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_FAILURE; + } +#endif + + if (desc->flags & (DFDESC_HEIGHT | DFDESC_WIDTH | + DFDESC_FRACT_HEIGHT | DFDESC_FRACT_WIDTH)) + { + int fw = 0, fh = 0; + + if (desc->flags & DFDESC_FRACT_HEIGHT) + fh = desc->fract_height; + else if (desc->flags & DFDESC_HEIGHT) + fh = desc->height << 6; + + if (desc->flags & DFDESC_FRACT_WIDTH) + fw = desc->fract_width; + else if (desc->flags & DFDESC_WIDTH) + fw = desc->width << 6; + + pthread_mutex_lock ( &library_mutex ); + err = FT_Set_Char_Size( face, fw, fh, 0, 0 ); + pthread_mutex_unlock ( &library_mutex ); + if (err) { + D_ERROR( "DirectB/FontFT2: " + "Could not set pixel size to %d x %d!\n", + (desc->flags & DFDESC_WIDTH) ? desc->width : 0, + (desc->flags & DFDESC_HEIGHT) ? desc->height : 0 ); + pthread_mutex_lock ( &library_mutex ); + FT_Done_Face( face ); + pthread_mutex_unlock ( &library_mutex ); + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_FAILURE; + } + } + + face->generic.data = (void *)(unsigned long) load_flags; + face->generic.finalizer = NULL; + + ret = dfb_font_create( core, desc, filename, &font ); + if (ret) { + pthread_mutex_lock ( &library_mutex ); + FT_Done_Face( face ); + pthread_mutex_unlock ( &library_mutex ); + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return ret; + } + + D_ASSERT( font->pixel_format == DSPF_ARGB || + font->pixel_format == DSPF_AiRGB || + font->pixel_format == DSPF_ARGB4444 || + font->pixel_format == DSPF_RGBA4444 || + font->pixel_format == DSPF_ARGB2554 || + font->pixel_format == DSPF_ARGB1555 || + font->pixel_format == DSPF_A8 || + font->pixel_format == DSPF_A4 || + font->pixel_format == DSPF_A1 ); + + font->ascender = face->size->metrics.ascender >> 6; + font->descender = face->size->metrics.descender >> 6; + font->height = font->ascender + ABS(font->descender) + 1; + font->maxadvance = face->size->metrics.max_advance >> 6; + + font->up_unit_x = -sin_rot; + font->up_unit_y = -cos_rot; + + D_DEBUG( "DirectFB/FontFT2: height = %d, ascender = %d, descender = %d, maxadvance = %d, up unit: %5.2f,%5.2f\n", + font->height, font->ascender, font->descender, font->maxadvance, font->up_unit_x, font->up_unit_y ); + + font->GetGlyphData = get_glyph_info; + font->RenderGlyph = render_glyph; + + if (FT_HAS_KERNING(face) && !disable_kerning) { + font->GetKerning = get_kerning; + data = D_CALLOC( 1, sizeof(FT2ImplKerningData) ); + } + else + data = D_CALLOC( 1, sizeof(FT2ImplData) ); + + data->face = face; + data->disable_charmap = disable_charmap; + + if (FT_HAS_KERNING(face) && !disable_kerning) + init_kerning_cache( (FT2ImplKerningData*) data, font->up_unit_x, font->up_unit_y); + + if (desc->flags & DFDESC_FIXEDADVANCE) { + data->fixed_advance = desc->fixed_advance; + font->maxadvance = desc->fixed_advance; + + if ((desc->flags & DFDESC_ATTRIBUTES) && (desc->attributes & DFFA_FIXEDCLIP)) + data->fixed_clip = true; + } + + for (i=0; i<256; i++) + data->indices[i] = FT_Get_Char_Index( face, i | mask ); + + font->impl_data = data; + + dfb_font_register_encoding( font, "UTF8", &ft2UTF8Funcs, DTEID_UTF8 ); + dfb_font_register_encoding( font, "Latin1", &ft2Latin1Funcs, DTEID_OTHER ); + + IDirectFBFont_Construct( thiz, font ); + + thiz->Release = IDirectFBFont_FT2_Release; + + return DFB_OK; +} diff --git a/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_lino.c b/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_lino.c new file mode 100755 index 0000000..4d03e7f --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBFont/idirectfbfont_lino.c @@ -0,0 +1,1324 @@ +/*
+ (c) Copyright 2001-2008 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <math.h>
+
+#include <directfb.h>
+
+#include <core/fonts.h>
+#include <core/gfxcard.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+
+#include <gfx/convert.h>
+
+#include <media/idirectfbfont.h>
+
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/utf8.h>
+#include <direct/util.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+#undef SIZEOF_LONG
+/*
+#include <ft2build.h>
+#include FT_GLYPH_H
+*/
+/*#ifndef FT_LOAD_TARGET_MONO DZ*/
+/* FT_LOAD_TARGET_MONO was added in FreeType-2.1.3, we have to use (less good)
+ FT_LOAD_MONOCHROME with older versions. Make it an alias for code simplicity. */
+/* #define FT_LOAD_TARGET_MONO FT_LOAD_MONOCHROME
+#endif
+*/
+#include <fs_itype.h>
+#include <adfinittermsystem.h>
+
+#ifdef NOT_BIG_ENOUGH_FOR_GULIM_AC3
+#define THE_HEAP_SIZE 327680
+#else
+// Increase the heap size to 1.5MB to avoid the missing character problem (running out of heap)
+#define THE_HEAP_SIZE (1*1024*1024 + 512*1024)
+#endif
+static FS_BOOLEAN state_init = false;
+static FS_STATE state_global;
+static bool load_mono = false;
+
+static DFBResult
+Probe( IDirectFBFont_ProbeContext *ctx );
+
+static DFBResult
+Construct( IDirectFBFont *thiz,
+ CoreDFB *core,
+ IDirectFBFont_ProbeContext *ctx,
+ DFBFontDescription *desc );
+
+#include <direct/interface_implementation.h>
+
+DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBFont, Lino )
+
+
+D_DEBUG_DOMAIN( Font_Itype, "Font/Itype", "Itype" );
+
+/*
+static FT_Library library = NULL;
+*/
+static int library_ref_count = 0;
+static pthread_mutex_t library_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+#define KERNING_CACHE_MIN 0
+#define KERNING_CACHE_MAX 127
+#define KERNING_CACHE_SIZE (KERNING_CACHE_MAX - KERNING_CACHE_MIN + 1)
+
+#define KERNING_DO_CACHE(a,b) ((a) >= KERNING_CACHE_MIN && \
+ (a) <= KERNING_CACHE_MAX && \
+ (b) >= KERNING_CACHE_MIN && \
+ (b) <= KERNING_CACHE_MAX)
+
+#define KERNING_CACHE_ENTRY(a,b) \
+ (data->kerning[(a)-KERNING_CACHE_MIN][(b)-KERNING_CACHE_MIN])
+/*
+#define CHAR_INDEX(c) (((c) < 256) ? data->indices[c] : FT_Get_Char_Index( data->face, c ))
+*/
+#define CHAR_INDEX(c) (((c) < 256) ? data->indices[c] : FS_map_char( data->state, c ))
+
+typedef struct {
+ /*FT_Face face;*/
+ FS_STATE *state;
+ int disable_charmap;
+ int fixed_advance;
+ bool fixed_clip;
+ unsigned int indices[256];
+} ITImplData;
+
+typedef struct {
+ signed char x;
+ signed char y;
+} KerningCacheEntry;
+
+typedef struct {
+ ITImplData base;
+
+ KerningCacheEntry kerning[KERNING_CACHE_SIZE][KERNING_CACHE_SIZE];
+} ITImplKerningData;
+
+/**********************************************************************************************************************/
+
+static DFBResult
+UTF8GetCharacterIndex( CoreFont *thiz,
+ unsigned int character,
+ unsigned int *ret_index )
+{
+ ITImplData *data = thiz->impl_data;
+
+ D_MAGIC_ASSERT( thiz, CoreFont );
+
+ if (data->disable_charmap)
+ *ret_index = character;
+ else {
+ pthread_mutex_lock ( &library_mutex );
+
+ *ret_index = CHAR_INDEX( character );
+
+ pthread_mutex_unlock ( &library_mutex );
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+UTF8DecodeText( CoreFont *thiz,
+ const void *text,
+ int length,
+ unsigned int *ret_indices,
+ int *ret_num )
+{
+ int pos = 0, num = 0;
+ const u8 *bytes = text;
+ ITImplData *data = thiz->impl_data;
+
+ D_MAGIC_ASSERT( thiz, CoreFont );
+ D_ASSERT( text != NULL );
+ D_ASSERT( length >= 0 );
+ D_ASSERT( ret_indices != NULL );
+ D_ASSERT( ret_num != NULL );
+
+ pthread_mutex_lock ( &library_mutex );
+
+ while (pos < length) {
+ unsigned int c;
+
+ if (bytes[pos] < 128)
+ c = bytes[pos++];
+ else {
+ c = DIRECT_UTF8_GET_CHAR( &bytes[pos] );
+ pos += DIRECT_UTF8_SKIP(bytes[pos]);
+ }
+
+ if (data->disable_charmap)
+ ret_indices[num++] = c;
+ else
+ ret_indices[num++] = CHAR_INDEX( c );
+ }
+
+ pthread_mutex_unlock ( &library_mutex );
+
+ *ret_num = num;
+
+ return DFB_OK;
+}
+
+static const CoreFontEncodingFuncs UTF8Funcs = {
+ .GetCharacterIndex = UTF8GetCharacterIndex,
+ .DecodeText = UTF8DecodeText,
+};
+
+/**********************************************************************************************************************/
+
+static DFBResult
+UTF16GetCharacterIndex( CoreFont *thiz,
+ unsigned int character,
+ unsigned int *ret_index )
+{
+ ITImplData *data = thiz->impl_data;
+
+ D_MAGIC_ASSERT( thiz, CoreFont );
+
+ if (data->disable_charmap)
+ *ret_index = character;
+ else {
+ pthread_mutex_lock ( &library_mutex );
+
+ *ret_index = CHAR_INDEX( character );
+
+ pthread_mutex_unlock ( &library_mutex );
+ }
+
+ return DFB_OK;
+}
+
+#define SURROGATE_VALUE(h,l) (((h) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000)
+
+static DFBResult
+UTF16DecodeText( CoreFont *thiz,
+ const void *text,
+ int length,
+ unsigned int *ret_indices,
+ int *ret_num )
+{
+ int pos = 0, num = 0;
+ unsigned int high_surrogate = 0;
+ const u16 *shorts = text;
+ ITImplData *data = thiz->impl_data;
+
+ D_MAGIC_ASSERT( thiz, CoreFont );
+ D_ASSERT( text != NULL );
+ D_ASSERT( length >= 0 );
+ D_ASSERT( ret_indices != NULL );
+ D_ASSERT( ret_num != NULL );
+
+ pthread_mutex_lock ( &library_mutex );
+
+ while (pos < length/2) {
+ unsigned int c = shorts[pos++];
+
+ if (c >= 0xdc00 && c < 0xe000) { /* low surrogate */
+ c = SURROGATE_VALUE (high_surrogate, c);
+ high_surrogate = 0;
+ }
+ else if (c >= 0xd800 && c < 0xdc00) { /* high surrogate */
+ high_surrogate = c;
+ continue;
+ }
+
+ if (data->disable_charmap)
+ ret_indices[num++] = c;
+ else
+ ret_indices[num++] = CHAR_INDEX( c );
+ }
+
+ pthread_mutex_unlock ( &library_mutex );
+
+ *ret_num = num;
+
+ return DFB_OK;
+}
+
+static const CoreFontEncodingFuncs UTF16Funcs = {
+ .GetCharacterIndex = UTF16GetCharacterIndex,
+ .DecodeText = UTF16DecodeText,
+};
+
+/**********************************************************************************************************************/
+
+static DFBResult
+Latin1GetCharacterIndex( CoreFont *thiz,
+ unsigned int character,
+ unsigned int *ret_index )
+{
+ ITImplData *data = thiz->impl_data;
+
+ D_MAGIC_ASSERT( thiz, CoreFont );
+
+ if (data->disable_charmap)
+ *ret_index = character;
+ else
+ *ret_index = data->indices[character];
+
+ return DFB_OK;
+}
+
+static DFBResult
+Latin1DecodeText( CoreFont *thiz,
+ const void *text,
+ int length,
+ unsigned int *ret_indices,
+ int *ret_num )
+{
+ int i;
+ const u8 *bytes = text;
+ ITImplData *data = thiz->impl_data;
+
+ D_MAGIC_ASSERT( thiz, CoreFont );
+ D_ASSERT( text != NULL );
+ D_ASSERT( length >= 0 );
+ D_ASSERT( ret_indices != NULL );
+ D_ASSERT( ret_num != NULL );
+
+ if (data->disable_charmap) {
+ for (i=0; i<length; i++)
+ ret_indices[i] = bytes[i];
+ }
+ else {
+ for (i=0; i<length; i++)
+ ret_indices[i] = data->indices[bytes[i]];
+ }
+
+ *ret_num = length;
+
+ return DFB_OK;
+}
+
+static const CoreFontEncodingFuncs Latin1Funcs = {
+ .GetCharacterIndex = Latin1GetCharacterIndex,
+ .DecodeText = Latin1DecodeText,
+};
+
+/**********************************************************************************************************************/
+
+static DFBResult
+render_glyph( CoreFont *thiz,
+ unsigned int index,
+ CoreGlyphData *info )
+{
+ /* FT_Error err;
+ FT_Face face;
+ FT_Int load_flags;*/
+ u8 *src;
+ int y;
+ FS_LONG err;
+ FS_LONG load_flags;
+ ITImplData *data = (ITImplData*) thiz->impl_data;
+ FS_GLYPHMAP *glyph_map;
+
+ CoreSurface *surface = info->surface;
+ CoreSurfaceBufferLock lock;
+
+ pthread_mutex_lock ( &library_mutex );
+
+ /* face = data->face;
+
+ load_flags = (unsigned long) face->generic.data;
+ load_flags |= FT_LOAD_RENDER;
+
+ if ((err = FT_Load_Glyph( face, index, load_flags ))) {
+ D_DEBUG( "DirectFB/FontFT2: Could not render glyph for character index #%d!\n", index );
+ pthread_mutex_unlock ( &library_mutex );
+ return DFB_FAILURE;
+ }
+ */
+
+ switch (info->layer) {
+ case 0:
+ err = FS_set_flags( data->state, FLAGS_NO_EFFECT );
+ if (err) {
+ D_ERROR( "DirectFB/FontItype: Failed setting FLAGS_NO_EFFECT!\n" );
+
+ pthread_mutex_unlock ( &library_mutex );
+ return DFB_FAILURE;
+ }
+ break;
+
+ case 1:
+ err = FS_set_flags( data->state, FLAGS_OUTLINED_SOFT );
+ if (err) {
+ D_ERROR( "DirectFB/FontItype: Failed setting FLAGS_OUTLINED_SOFT!\n" );
+
+ pthread_mutex_unlock ( &library_mutex );
+ return DFB_FAILURE;
+ }
+ break;
+
+ default:
+ return DFB_UNSUPPORTED;
+ }
+
+ if (load_mono)
+ glyph_map = FS_get_glyphmap( data->state, index, FS_MAP_BITMAP );
+ else
+ glyph_map = FS_get_glyphmap( data->state, index, FS_MAP_EDGE_GRAYMAP8 | FS_MAP_GRAYMAP8);
+ if (!glyph_map) {
+ /* glyph_map->err = FS_error(&state);*/
+ D_DEBUG( "DirectFB/FontItype: Could not load glyph for character index #%d!\n", index );
+
+ pthread_mutex_unlock ( &library_mutex );
+
+ return DFB_FAILURE;
+ }
+ pthread_mutex_unlock ( &library_mutex );
+
+ err = dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock );
+ if (err) {
+ D_DERROR( err, "DirectFB/FontItype: Unable to lock surface!\n" );
+ return err;
+ }
+
+ info->width = glyph_map->width;
+ if (info->width + info->start > surface->config.size.w)
+ info->width = surface->config.size.w - info->start;
+
+ info->height = glyph_map->height;
+ if (info->height > surface->config.size.h)
+ info->height = surface->config.size.h;
+
+ /* bitmap_left and bitmap_top are relative to the glyph's origin on the
+ baseline. info->left and info->top are relative to the top-left of the
+ character cell. */
+ info->left = glyph_map->lo_x - thiz->ascender*thiz->up_unit_x;
+ info->top = - glyph_map->hi_y - thiz->ascender*thiz->up_unit_y;
+
+ if (data->fixed_clip) {
+ while (info->left + info->width > data->fixed_advance)
+ info->left--;
+
+ if (info->left < 0)
+ info->left = 0;
+
+ if (info->width > data->fixed_advance)
+ info->width = data->fixed_advance;
+ }
+
+ /*src = face->glyph->bitmap.buffer;*/
+ src = glyph_map->bits;
+ lock.addr += DFB_BYTES_PER_LINE(surface->config.format, info->start);
+
+ for (y=0; y < info->height; y++) {
+ int i, j, n;
+ u8 *dst8 = lock.addr;
+ u16 *dst16 = lock.addr;
+ u32 *dst32 = lock.addr;
+
+ /*switch (face->glyph->bitmap.pixel_mode) {*/
+ switch (load_mono) {
+ /* case ft_pixel_mode_grays:*/
+ case false:
+ switch (surface->config.format) {
+ case DSPF_ARGB:
+ if (thiz->surface_caps & DSCAPS_PREMULTIPLIED) {
+ for (i=0; i<info->width; i++)
+ dst32[i] = src[i] * 0x01010101;
+ }
+ else
+ for (i=0; i<info->width; i++)
+ dst32[i] = (src[i] << 24) | 0xFFFFFF;
+ break;
+ case DSPF_AiRGB:
+ for (i=0; i<info->width; i++)
+ dst32[i] = ((src[i] ^ 0xFF) << 24) | 0xFFFFFF;
+ break;
+ case DSPF_ARGB4444:
+ if (thiz->surface_caps & DSCAPS_PREMULTIPLIED) {
+ for (i=0; i<info->width; i++)
+ dst16[i] = (src[i] >> 4) * 0x1111;
+ }
+ else {
+ for (i=0; i<info->width; i++)
+ dst16[i] = (src[i] << 8) | 0xFFF;
+ }
+ break;
+ case DSPF_ARGB2554:
+ for (i=0; i<info->width; i++)
+ dst16[i] = (src[i] << 8) | 0x3FFF;
+ break;
+ case DSPF_ARGB1555:
+ for (i=0; i<info->width; i++)
+ dst16[i] = (src[i] << 8) | 0x7FFF;
+ break;
+ case DSPF_A8:
+ direct_memcpy( lock.addr, src, info->width );
+ break;
+ case DSPF_A4:
+ for (i=0, j=0; i<info->width; i+=2, j++)
+ dst8[j] = (src[i] & 0xF0) | (src[i+1] >> 4);
+ break;
+ case DSPF_A1:
+ for (i=0, j=0; i < info->width; ++j) {
+ register u8 p = 0;
+
+ for (n=0; n<8 && i<info->width; ++i, ++n)
+ p |= (src[i] & 0x80) >> n;
+
+ dst8[j] = p;
+ }
+ break;
+ case DSPF_LUT2:
+ for (i=0, j=0; i < info->width; ++j) {
+ register u8 p = 0;
+
+ for (n=0; n<8 && i<info->width; ++i, n+=2)
+ p |= (src[i] & 0xC0) >> n;
+
+ dst8[j] = p;
+ }
+ break;
+ default:
+ D_UNIMPLEMENTED();
+ break;
+ }
+ break;
+
+ /* case ft_pixel_mode_mono: */
+ case true:
+ switch (surface->config.format) {
+ case DSPF_ARGB:
+ for (i=0; i<info->width; i++)
+ dst32[i] = (((src[i>>3] & (1<<(7-(i%8)))) ?
+ 0xFF : 0x00) << 24) | 0xFFFFFF;
+ break;
+ case DSPF_AiRGB:
+ for (i=0; i<info->width; i++)
+ dst32[i] = (((src[i>>3] & (1<<(7-(i%8)))) ?
+ 0x00 : 0xFF) << 24) | 0xFFFFFF;
+ break;
+ case DSPF_ARGB4444:
+ for (i=0; i<info->width; i++)
+ dst16[i] = (((src[i>>3] & (1<<(7-(i%8)))) ?
+ 0xF : 0x0) << 12) | 0xFFF;
+ break;
+ case DSPF_ARGB2554:
+ for (i=0; i<info->width; i++)
+ dst16[i] = (((src[i>>3] & (1<<(7-(i%8)))) ?
+ 0x3 : 0x0) << 14) | 0x3FFF;
+ break;
+ case DSPF_ARGB1555:
+ for (i=0; i<info->width; i++)
+ dst16[i] = (((src[i>>3] & (1<<(7-(i%8)))) ?
+ 0x1 : 0x0) << 15) | 0x7FFF;
+ break;
+ case DSPF_A8:
+ for (i=0; i<info->width; i++)
+ dst8[i] = (src[i>>3] &
+ (1<<(7-(i%8)))) ? 0xFF : 0x00;
+ break;
+ case DSPF_A4:
+ for (i=0, j=0; i<info->width; i+=2, j++)
+ dst8[j] = ((src[i>>3] &
+ (1<<(7-(i%8)))) ? 0xF0 : 0x00) |
+ ((src[(i+1)>>3] &
+ (1<<(7-((i+1)%8)))) ? 0x0F : 0x00);
+ break;
+ case DSPF_A1:
+ direct_memcpy( lock.addr, src, DFB_BYTES_PER_LINE(DSPF_A1, info->width) );
+ break;
+ default:
+ D_UNIMPLEMENTED();
+ break;
+ }
+ break;
+
+ default:
+ break;
+
+ }
+
+ /*src += face->glyph->bitmap.pitch; */
+ src += glyph_map->bpl;
+
+ lock.addr += lock.pitch;
+ }
+
+ dfb_surface_unlock_buffer( surface, &lock );
+ FS_free_char(data->state,glyph_map);
+ return DFB_OK;
+}
+
+
+static DFBResult
+get_glyph_info( CoreFont *thiz,
+ unsigned int index,
+ CoreGlyphData *info )
+{
+ FS_LONG err;
+ /* FT_Face face;
+ FT_Int load_flags;*/
+ ITImplData *data = (ITImplData*) thiz->impl_data;
+ FS_GLYPHMAP *glyph_map;
+
+ pthread_mutex_lock ( &library_mutex );
+
+ /* face = data->face;
+
+ load_flags = (unsigned long) face->generic.data;
+ */
+
+ switch (info->layer) {
+ case 0:
+ err = FS_set_flags( data->state, FLAGS_NO_EFFECT );
+ if (err) {
+ D_ERROR( "DirectFB/FontItype: Failed setting FLAGS_NO_EFFECT!\n" );
+
+ pthread_mutex_unlock ( &library_mutex );
+ return DFB_FAILURE;
+ }
+ break;
+
+ case 1:
+ err = FS_set_flags( data->state, FLAGS_OUTLINED_SOFT );
+ if (err) {
+ D_ERROR( "DirectFB/FontItype: Failed setting FLAGS_OUTLINED_SOFT!\n" );
+
+ pthread_mutex_unlock ( &library_mutex );
+ return DFB_FAILURE;
+ }
+ break;
+
+ default:
+ return DFB_UNSUPPORTED;
+ }
+
+ if (load_mono)
+ glyph_map = FS_get_glyphmap( data->state, index, FS_MAP_BITMAP );
+ else
+ glyph_map = FS_get_glyphmap( data->state, index, FS_MAP_EDGE_GRAYMAP8 | FS_MAP_GRAYMAP8);
+ if (!glyph_map) {
+ /*glyph_map->err = FS_error(&state);*/
+ D_DEBUG( "DirectFB/FontItype: Could not load glyph for character index #%d!\n", index );
+
+ pthread_mutex_unlock ( &library_mutex );
+
+ return DFB_FAILURE;
+ }
+
+ /* if ((err = FT_Load_Glyph( face, index, load_flags ))) {
+ D_DEBUG( "DirectFB/FontFT2: Could not load glyph for character index #%d!\n", index );
+
+ pthread_mutex_unlock ( &library_mutex );
+
+ return DFB_FAILURE;
+ }
+
+ if (face->glyph->format != ft_glyph_format_bitmap) {
+ err = FT_Render_Glyph( face->glyph,
+ (load_flags & FT_LOAD_TARGET_MONO) ? ft_render_mode_mono : ft_render_mode_normal );
+ if (err) {
+ D_ERROR( "DirectFB/FontFT2: Could not render glyph for character index #%d!\n", index );
+
+ pthread_mutex_unlock ( &library_mutex );
+
+ return DFB_FAILURE;
+ }
+ }
+ */
+ pthread_mutex_unlock ( &library_mutex );
+
+ info->width = glyph_map->width;
+ info->height = glyph_map->height;
+// info->advance = data->fixed_advance ?
+// data->fixed_advance : (glyph_map->dx >> 16);
+ if (data->fixed_advance) {
+ info->xadvance = - data->fixed_advance * thiz->up_unit_y;
+ info->yadvance = data->fixed_advance * thiz->up_unit_x;
+ }
+ else {
+ info->xadvance = glyph_map->dx >> 16;
+ info->yadvance = - glyph_map->dy >> 16;
+ }
+
+ if (data->fixed_clip && info->width > data->fixed_advance)
+ info->width = data->fixed_advance;
+ FS_free_char(data->state,glyph_map);
+ return DFB_OK;
+}
+
+
+static DFBResult
+get_kerning( CoreFont *thiz,
+ unsigned int prev,
+ unsigned int current,
+ int *kern_x,
+ int *kern_y)
+{
+ /* FT_Vector vector;
+
+ FT2ImplKerningData *data = thiz->impl_data;
+ KerningCacheEntry *cache = NULL;
+
+ D_ASSUME( (kern_x != NULL) || (kern_y != NULL) );
+ */
+ /*
+ * Use cached values if characters are in the
+ * cachable range and the cache entry is already filled.
+ */
+ /* if (KERNING_DO_CACHE (prev, current)) {
+ cache = &KERNING_CACHE_ENTRY (prev, current);
+
+ if (kern_x)
+ *kern_x = (int) cache->x;
+
+ if (kern_y)
+ *kern_y = (int) cache->y;
+
+ return DFB_OK;
+ }
+
+ pthread_mutex_lock ( &library_mutex );
+ */
+ /* Lookup kerning values for the character pair. */
+/* FT_Get_Kerning( data->base.face,
+ prev, current, ft_kerning_default, &vector );
+
+ pthread_mutex_unlock ( &library_mutex );
+*/
+ /* Convert to integer. */
+/* if (kern_x)
+ *kern_x = vector.x >> 6;
+
+ if (kern_y)
+ *kern_y = vector.y >> 6;
+*/
+ if (kern_x)
+ *kern_x = 0;
+ if (kern_y)
+ *kern_y = 0;
+ return DFB_OK;
+}
+
+static void
+init_kerning_cache( ITImplKerningData *data )
+{
+ /* int a, b;
+
+ pthread_mutex_lock ( &library_mutex );
+
+ for (a=KERNING_CACHE_MIN; a<=KERNING_CACHE_MAX; a++) {
+ for (b=KERNING_CACHE_MIN; b<=KERNING_CACHE_MAX; b++) {
+ FT_Vector vector;
+ KerningCacheEntry *cache = &KERNING_CACHE_ENTRY( a, b );
+ */
+ /* Lookup kerning values for the character pair. */
+/* FT_Get_Kerning( data->base.face,
+ a, b, ft_kerning_default, &vector );
+
+ cache->x = (signed char) (vector.x >> 6);
+ cache->y = (signed char) (vector.y >> 6);
+ }
+ }
+
+ pthread_mutex_unlock ( &library_mutex );
+ */
+}
+
+/*static DFBResult
+init_freetype( void )
+{
+ FT_Error err;
+
+ pthread_mutex_lock ( &library_mutex );
+
+ if (!library) {
+ D_DEBUG( "DirectFB/FontFT2: Initializing the FreeType2 library.\n" );
+ err = FT_Init_FreeType( &library );
+ if (err) {
+ D_ERROR( "DirectFB/FontFT2: "
+ "Initialization of the FreeType2 library failed!\n" );
+ library = NULL;
+ pthread_mutex_unlock( &library_mutex );
+ return DFB_FAILURE;
+ }
+ }
+
+ library_ref_count++;
+ pthread_mutex_unlock( &library_mutex );
+
+ return DFB_OK;
+}
+
+
+static void
+release_freetype( void )
+{
+ pthread_mutex_lock( &library_mutex );
+
+ if (library && --library_ref_count == 0) {
+ D_DEBUG( "DirectFB/FontFT2: Releasing the FreeType2 library.\n" );
+ FT_Done_FreeType( library );
+ library = NULL;
+ }
+
+ pthread_mutex_unlock( &library_mutex );
+}
+
+*/
+FS_STATE *
+init_itype( )
+{
+ FS_LONG err;
+ FS_STATE *state=NULL;
+
+ pthread_mutex_lock ( &library_mutex );
+ if (!state_init) {
+ D_DEBUG( "DirectFB/FontItype: Initializing the Itype library.\n" );
+ memset(&state_global, 0, sizeof(FS_STATE));
+
+ err = FS_init(&state_global, THE_HEAP_SIZE);
+ if (err) {
+ D_ERROR( "DirectFB/FontItype: "
+ "Initialization of the Itype library failed!\n" );
+ pthread_mutex_unlock( &library_mutex );
+ return state;
+ }
+ state_init = true;
+ state =&state_global;
+ }
+ else {
+ state=FS_new_client(&state_global,0);
+ if (state==NULL) {
+ D_ERROR( "DirectFB/FontItype: "
+ "Add new client failed!\n" );
+ pthread_mutex_unlock( &library_mutex );
+ return state;
+ }
+ }
+ library_ref_count++;
+ pthread_mutex_unlock( &library_mutex );
+
+ return state;
+}
+
+
+static void
+release_itype( void )
+{
+ pthread_mutex_lock( &library_mutex );
+
+ if (state_init && --library_ref_count == 0) {
+ D_DEBUG( "DirectFB/FontItype: Releasing the Itype library.\n" );
+ /* FT_Done_FreeType( library );
+ library = NULL;
+ */
+
+ FS_exit(&state_global);
+ state_init = false;
+ }
+
+ pthread_mutex_unlock( &library_mutex );
+}
+
+static void
+IDirectFBFont_IT_Destruct( IDirectFBFont *thiz )
+{
+ IDirectFBFont_data *data = (IDirectFBFont_data*)thiz->priv;
+
+ if (data->font->impl_data) {
+ ITImplData *impl_data = (ITImplData*) data->font->impl_data;
+
+ pthread_mutex_lock ( &library_mutex );
+ /* FT_Done_Face( impl_data->face ); */
+ if (library_ref_count>1)
+ FS_end_client(impl_data->state);
+ pthread_mutex_unlock ( &library_mutex );
+
+ D_FREE( impl_data );
+
+ data->font->impl_data = NULL;
+ }
+
+ IDirectFBFont_Destruct( thiz );
+
+ release_itype();
+}
+
+
+static DirectResult
+IDirectFBFont_IT_Release( IDirectFBFont *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ if (--data->ref == 0) {
+ IDirectFBFont_IT_Destruct( thiz );
+ }
+
+ return DFB_OK;
+}
+
+
+static DFBResult
+Probe( IDirectFBFont_ProbeContext *ctx )
+{
+ /* FT_Error err;
+ FT_Face face;
+ */
+ FS_LONG err;
+ FILECHAR font_name[MAX_FONT_NAME_LEN];
+ FS_STATE *state_tp;
+
+ D_DEBUG_AT( Font_Itype, "Probe font `%s'.\n", ctx->filename );
+
+ if (!ctx->content)
+ return DFB_UNSUPPORTED;
+
+ if (ctx->filename && strchr (ctx->filename, '.' ) &&
+ (!strcasecmp ( strchr (ctx->filename, '.' ), ".ttf" ) == 0 &&
+ !strcasecmp ( strchr (ctx->filename, '.' ), ".otf" ) == 0 &&
+ !strcasecmp ( strchr (ctx->filename, '.' ), ".ltt") == 0))
+ return DFB_UNSUPPORTED;
+
+ state_tp = init_itype();
+ if (state_tp == NULL)
+ return DFB_FAILURE;
+
+ pthread_mutex_lock ( &library_mutex );
+ /*
+ * This should be
+ * err = FT_New_Face( library, ctx->filename, -1, NULL );
+ * but due to freetype bugs it doesn't work.
+ */
+ /* err = FT_New_Face( library, ctx->filename, 0, &face );
+ if (!err)
+ FT_Done_Face( face );
+ */
+ if (library_ref_count > 1)
+ FS_end_client(state_tp);
+ pthread_mutex_unlock ( &library_mutex );
+
+ release_itype();
+
+ return DFB_OK;
+}
+
+static bool disable_kerning = false;
+static DFBResult
+Construct( IDirectFBFont *thiz,
+ CoreDFB *core,
+ IDirectFBFont_ProbeContext *ctx,
+ DFBFontDescription *desc )
+{
+ int i;
+ DFBResult ret;
+ CoreFont *font;
+ /* FT_Face face;
+ FT_Error err;
+ FT_Int load_flags = FT_LOAD_DEFAULT; */
+ ITImplData *data;
+ bool disable_charmap = false;
+
+ u32 mask = 0;
+ FS_ULONG flags;
+
+ FS_LONG err;
+
+ FS_ULONG load_flags;
+
+
+ FILECHAR fontName[MAX_FONT_NAME_LEN];
+ FS_STATE *state;
+ float sin_rot = 0.0;
+ float cos_rot = 1.0;
+
+ D_DEBUG( "DirectFB/FontItype: "
+ "Construct font from file `%s' (index %d) at pixel size %d x %d.\n",
+ ctx->filename,
+ (desc->flags & DFDESC_INDEX) ? desc->index : 0,
+ (desc->flags & DFDESC_WIDTH) ? desc->width : 0,
+ (desc->flags & DFDESC_HEIGHT) ? desc->height : 0,
+ (desc->flags & DFDESC_ROTATION) ? desc->rotation : 0 );
+
+ state = init_itype();
+ if (state == NULL) {
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return DFB_FAILURE;
+ }
+ pthread_mutex_lock ( &library_mutex );
+ err = FS_load_font(state, NULL, ctx->content,0, MAX_FONT_NAME_LEN, fontName);
+
+ if (err) {
+ D_ERROR( "DirectFB/FontItype: "
+ "Failed loading face %d from font file `%s' (error %lu)!\n",
+ (desc->flags & DFDESC_INDEX) ? desc->index : 0,
+ ctx->filename, state->error );
+ pthread_mutex_unlock ( &library_mutex );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return DFB_FAILURE;
+ }
+
+ err = FS_set_font(state, fontName);
+ if (err) {
+ D_ERROR( "DirectFB/FontItype: "
+ "Failed seting font `%s'!\n", fontName );
+ FS_delete_font(state, fontName);
+
+ pthread_mutex_unlock ( &library_mutex );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return DFB_FAILURE;
+ }
+
+ err = FS_set_cmap(state, 3,1 );
+ if (err) {
+ D_ERROR( "DirectFB/FontItype: "
+ "Failed seting cmap `%s'!\n", fontName );
+ FS_delete_font(state, fontName);
+
+ pthread_mutex_unlock ( &library_mutex );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return DFB_FAILURE;
+ }
+
+
+ err = FS_set_flags( state, FLAGS_CMAP_OFF );
+ if (err) {
+ D_ERROR( "DirectFB/FontItype: "
+ "Failed setting FLAGS_CMAP_OFF for `%s'!\n", fontName );
+ FS_delete_font(state, fontName);
+
+ pthread_mutex_unlock ( &library_mutex );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return DFB_FAILURE;
+ }
+
+ if (desc->flags & DFDESC_ATTRIBUTES && desc->attributes & DFFA_OUTLINED) {
+ if (desc->flags & DFDESC_OUTLINE_WIDTH)
+ FS_set_outline_width( state, desc->outline_width >> 16 );
+ else
+ FS_set_outline_width( state, 1 );
+
+ if (desc->flags & DFDESC_OUTLINE_OPACITY)
+ FS_set_outline_opacity( state, desc->outline_opacity );
+ else
+ FS_set_outline_opacity( state, 0x10000 );
+ }
+
+ pthread_mutex_unlock ( &library_mutex );
+ /*
+ if (init_freetype() != DFB_OK) {
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return DFB_FAILURE;
+ }
+
+ pthread_mutex_lock ( &library_mutex );
+ err = FT_New_Face( library, filename,
+ (desc->flags & DFDESC_INDEX) ? desc->index : 0,
+ &face );
+ pthread_mutex_unlock ( &library_mutex );
+ if (err) {
+ switch (err) {
+ case FT_Err_Unknown_File_Format:
+ D_ERROR( "DirectFB/FontFT2: "
+ "Unsupported font format in file `%s'!\n", filename );
+ break;
+ default:
+ D_ERROR( "DirectFB/FontFT2: "
+ "Failed loading face %d from font file `%s'!\n",
+ (desc->flags & DFDESC_INDEX) ? desc->index : 0,
+ filename );
+ break;
+ }
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return DFB_FAILURE;
+ }
+*/
+ if (dfb_config->font_format == DSPF_A1 || dfb_config->font_format == DSPF_ARGB1555)
+ load_mono = true;
+
+
+
+
+/*
+ if (desc->flags & DFDESC_ATTRIBUTES) {
+ if (desc->attributes & DFFA_NOHINTING)
+ load_flags |= FT_LOAD_NO_HINTING;
+ if (desc->attributes & DFFA_NOCHARMAP)
+ disable_charmap = true;
+ if (desc->attributes & DFFA_NOKERNING)
+ disable_kerning = true;
+ if (desc->attributes & DFFA_MONOCHROME)
+ load_mono = true;
+ }
+*/
+ if (desc->flags & DFDESC_ATTRIBUTES) {
+ if (desc->attributes & DFFA_NOHINTING)
+ load_flags |= FLAGS_HINTS_OFF;
+ if (desc->attributes & DFFA_NOCHARMAP) {
+ load_flags |= FLAGS_CMAP_OFF ;
+ disable_charmap = true;
+ }
+ if (desc->attributes & DFFA_NOKERNING)
+ disable_kerning = true;
+ if (desc->attributes & DFFA_MONOCHROME)
+ load_mono = true;
+ }
+/* if (load_mono)
+ load_flags |= FT_LOAD_TARGET_MONO;
+
+ if (!disable_charmap) {
+ pthread_mutex_lock ( &library_mutex );
+ err = FT_Select_Charmap( face, ft_encoding_unicode );
+ pthread_mutex_unlock ( &library_mutex );
+ */
+ if (!disable_charmap) {
+ pthread_mutex_lock ( &library_mutex );
+ err = FS_set_cmap( state, 3,1 ); /* Microsoft platform, Unicode */
+ pthread_mutex_unlock ( &library_mutex );
+
+
+/* #if FREETYPE_MINOR > 0*/
+
+ /* ft_encoding_latin_1 has been introduced in freetype-2.1 */
+ if (err) {
+ D_DEBUG( "DirectFB/FontItype: "
+ "Couldn't select Unicode encoding, "
+ "falling back to Latin1.\n");
+ pthread_mutex_lock ( &library_mutex );
+ err = FS_set_cmap( state, 3,0 );
+ pthread_mutex_unlock ( &library_mutex );
+ }
+/*#endif */
+ /* if (err) {
+ D_DEBUG( "DirectFB/Itype: "
+ "Couldn't select Unicode/Latin1 encoding, "
+ "trying Symbol.\n");
+ pthread_mutex_lock ( &library_mutex );
+ err = FS_set_cmap( &state, 3,3 );
+ pthread_mutex_unlock ( &library_mutex );
+
+ if (!err)
+ mask = 0xf000;
+ } */
+
+ }
+
+/*#if 0 */
+ if (err) {
+ D_ERROR( "DirectFB/Itype: "
+ "Couldn't select a suitable encoding for face %d from font file `%s'!\n", (desc->flags & DFDESC_INDEX) ? desc->index : 0, ctx->filename );
+ pthread_mutex_lock ( &library_mutex );
+ /*FT_Done_Face( face );*/
+ FS_delete_font(state, fontName);
+ pthread_mutex_unlock ( &library_mutex );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return DFB_FAILURE;
+ }
+/* #endif */
+
+ if (desc->flags & (DFDESC_HEIGHT | DFDESC_WIDTH |
+ DFDESC_FRACT_HEIGHT | DFDESC_FRACT_WIDTH)) {
+ int fw = 0, fh = 0;
+
+ if (desc->flags & DFDESC_FRACT_HEIGHT)
+ fh = desc->fract_height;
+ else if (desc->flags & DFDESC_HEIGHT)
+ fh = desc->height << 16;
+
+ if (desc->flags & DFDESC_FRACT_WIDTH)
+ fw = desc->fract_width;
+ else if (desc->flags & DFDESC_WIDTH)
+ fw = desc->width << 16;
+
+ pthread_mutex_lock ( &library_mutex );
+ // CR brg36mgr#105644: [extginga]Lintotype to support new font styles
+ // Previously the fw and fh were always made equal to each other:
+ // Now they can be set differently.
+/*
+ if ( fw != fh && fh != 0)
+ fw=fh;
+ else
+ fh=fw;*/
+ // Replaced by the following to ensure that fw and fh is different from 0
+ // unless they are both 0, then no font will be shown.
+ if ( fw == 0 )
+ {
+ fw = fh;
+ }
+ if ( fh == 0 )
+ {
+ fh = fw;
+ }
+
+ if ((desc->flags & DFDESC_ROTATION) && desc->rotation) {
+//JMH if (!FT_IS_SCALABLE(face)) {
+//JMH D_ERROR( "DirectFB/FontFT2: "
+//JMH "Face %d from font file `%s' is not scalable so cannot be rotated\n",
+//JMH (desc->flags & DFDESC_INDEX) ? desc->index : 0,
+//JMH filename );
+//JMH pthread_mutex_lock ( &library_mutex );
+//JMH FT_Done_Face( face );
+//JMH pthread_mutex_unlock ( &library_mutex );
+//JMH DIRECT_DEALLOCATE_INTERFACE( thiz );
+//JMH return DFB_UNSUPPORTED;
+//JMH }
+ float rot_radians = 2.0 * M_PI * desc->rotation / (1<<24);
+ sin_rot = sin(rot_radians);
+ cos_rot = cos(rot_radians);
+ err = FS_set_scale (state, fw*cos_rot, -fh*sin_rot, fw*sin_rot, fh*cos_rot );
+ }
+ else
+ {
+ err = FS_set_scale( state, fw, 0, 0, fh);
+ }
+
+ pthread_mutex_unlock ( &library_mutex );
+ if (err) {
+ D_ERROR( "DirectB/Itype: "
+ "Could not set pixel size to %d x %d!\n",
+ (desc->flags & DFDESC_WIDTH) ? desc->width : 0,
+ (desc->flags & DFDESC_HEIGHT) ? desc->height : 0 );
+ pthread_mutex_lock ( &library_mutex );
+ /* FT_Done_Face( face ); */
+ FS_delete_font(state, fontName);
+ pthread_mutex_unlock ( &library_mutex );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return DFB_FAILURE;
+ }
+ }
+
+ /* face->generic.data = (void *)(unsigned long) load_flags;
+ face->generic.finalizer = NULL;
+ */
+ ret = dfb_font_create( core, desc, ctx->filename, &font );
+ if (ret) {
+ pthread_mutex_lock ( &library_mutex );
+ /* FT_Done_Face( face ); */
+ FS_delete_font(state, fontName);
+ pthread_mutex_unlock ( &library_mutex );
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ font->attributes = desc->attributes;
+
+ D_ASSERT( font->pixel_format == DSPF_ARGB ||
+ font->pixel_format == DSPF_AiRGB ||
+ font->pixel_format == DSPF_ARGB4444 ||
+ font->pixel_format == DSPF_ARGB2554 ||
+ font->pixel_format == DSPF_ARGB1555 ||
+ font->pixel_format == DSPF_A8 ||
+ font->pixel_format == DSPF_A4 ||
+ font->pixel_format == DSPF_A1 );
+
+ /*
+ font->ascender = face->size->metrics.ascender >> 6;
+ font->descender = face->size->metrics.descender >> 6;
+ font->height = font->ascender + ABS(font->descender) + 1;
+ font->maxadvance = face->size->metrics.max_advance >> 6;
+ */
+ FS_FIXED ascender;
+ FS_FIXED descender;
+ FS_FIXED leading;
+ FsAscDescLeadSource *source;
+ source = D_CALLOC( 1, sizeof(FsAscDescLeadSource) );
+ pthread_mutex_lock ( &library_mutex );
+ err = FS_get_ascender_descender_leading(state, &ascender,&descender,&leading,source);
+ pthread_mutex_unlock ( &library_mutex );
+
+ font->ascender = (ascender >> 16) + 1;
+ font->descender = 0 - (descender >> 16) - 1;
+ font->height = font->ascender + ABS(font->descender) + 1;
+ font->maxadvance = font->height + (leading >> 16);
+
+ font->up_unit_x = -sin_rot;
+ font->up_unit_y = -cos_rot;
+
+ D_FREE(source);
+ D_DEBUG( "DirectFB/Itype: height = %d, ascender = %d, descender = %d, maxadvance = %d, up unit: %5.2f,%5.2f\n",
+ font->height, font->ascender, font->descender, font->maxadvance, font->up_unit_x, font->up_unit_y );
+
+ font->GetGlyphData = get_glyph_info;
+ font->RenderGlyph = render_glyph;
+/*
+ if (FT_HAS_KERNING(face) && !disable_kerning) {
+ font->GetKerning = get_kerning;
+ data = D_CALLOC( 1, sizeof(FT2ImplKerningData) );
+ }
+ else
+ data = D_CALLOC( 1, sizeof(FT2ImplData) );
+*/
+ if (!disable_kerning) {
+ font->GetKerning = get_kerning;
+ data = D_CALLOC( 1, sizeof(ITImplKerningData) );
+ }
+ else
+ data = D_CALLOC( 1, sizeof(ITImplData) );
+
+ data->state = state;
+ data->disable_charmap = disable_charmap;
+
+ if (/*FT_HAS_KERNING(face) && */!disable_kerning)
+ init_kerning_cache( (ITImplKerningData*) data );
+
+ if (desc->flags & DFDESC_FIXEDADVANCE) {
+ data->fixed_advance = desc->fixed_advance;
+ font->maxadvance = desc->fixed_advance;
+
+ if ((desc->flags & DFDESC_ATTRIBUTES) && (desc->attributes & DFFA_FIXEDCLIP))
+ data->fixed_clip = true;
+ }
+
+ for (i=0; i<256; i++)
+ /* data->indices[i] = FT_Get_Char_Index( face, i | mask );*/
+ data->indices[i] = FS_map_char( state, i | mask );
+
+ font->impl_data = data;
+
+ dfb_font_register_encoding( font, "UTF8", &UTF8Funcs, DTEID_UTF8 );
+ dfb_font_register_encoding( font, "UTF16", &UTF16Funcs, DTEID_OTHER );
+ dfb_font_register_encoding( font, "Latin1", &Latin1Funcs, DTEID_OTHER );
+
+ IDirectFBFont_Construct( thiz, font );
+
+ thiz->Release = IDirectFBFont_IT_Release;
+
+ return DFB_OK;
+}
diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.am b/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.am new file mode 100755 index 0000000..f512afd --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.am @@ -0,0 +1,82 @@ +## Makefile.am for DirectFB/interfaces/IDirectFBImageProvider + +idirectfbimageproviderdir = $(MODULEDIR)/interfaces/IDirectFBImageProvider + +if GIF_PROVIDER +GIF_PROVIDER_LTLIB = libidirectfbimageprovider_gif.la +else +GIF_PROVIDER_LTLIB = +endif + +if JPEG_PROVIDER +JPEG_PROVIDER_LTLIB = libidirectfbimageprovider_jpeg.la +else +JPEG_PROVIDER_LTLIB = +endif + +if PNG_PROVIDER +PNG_PROVIDER_LTLIB = libidirectfbimageprovider_png.la +else +PNG_PROVIDER_LTLIB = +endif + + +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src + +AM_CPPFLAGS = -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" + +idirectfbimageprovider_LTLIBRARIES = \ + libidirectfbimageprovider_dfiff.la \ + $(GIF_PROVIDER_LTLIB) \ + $(JPEG_PROVIDER_LTLIB) \ + $(PNG_PROVIDER_LTLIB) + +if BUILD_STATIC +idirectfbimageprovider_DATA = $(idirectfbimageprovider_LTLIBRARIES:.la=.o) +endif + + +libidirectfbimageprovider_png_la_SOURCES = idirectfbimageprovider_png.c + +libidirectfbimageprovider_png_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(LIBPNG) + +libidirectfbimageprovider_png_la_LDFLAGS = -avoid-version -module + + +libidirectfbimageprovider_dfiff_la_SOURCES = idirectfbimageprovider_dfiff.c + +libidirectfbimageprovider_dfiff_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbimageprovider_dfiff_la_LDFLAGS = -avoid-version -module + + +libidirectfbimageprovider_gif_la_SOURCES = idirectfbimageprovider_gif.c + +libidirectfbimageprovider_gif_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbimageprovider_gif_la_LDFLAGS = -avoid-version -module + + +libidirectfbimageprovider_jpeg_la_SOURCES = idirectfbimageprovider_jpeg.c + +libidirectfbimageprovider_jpeg_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(LIBJPEG) + +libidirectfbimageprovider_jpeg_la_LDFLAGS = -avoid-version -module + + +include $(top_srcdir)/rules/libobject.make diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.in b/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.in new file mode 100755 index 0000000..4f7e8d2 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/Makefile.in @@ -0,0 +1,683 @@ +# 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 = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/rules/libobject.make +subdir = interfaces/IDirectFBImageProvider +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 = +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)$(idirectfbimageproviderdir)" \ + "$(DESTDIR)$(idirectfbimageproviderdir)" +idirectfbimageproviderLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(idirectfbimageprovider_LTLIBRARIES) +libidirectfbimageprovider_dfiff_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la +am_libidirectfbimageprovider_dfiff_la_OBJECTS = \ + idirectfbimageprovider_dfiff.lo +libidirectfbimageprovider_dfiff_la_OBJECTS = \ + $(am_libidirectfbimageprovider_dfiff_la_OBJECTS) +libidirectfbimageprovider_dfiff_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbimageprovider_dfiff_la_LDFLAGS) $(LDFLAGS) -o $@ +libidirectfbimageprovider_gif_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la +am_libidirectfbimageprovider_gif_la_OBJECTS = \ + idirectfbimageprovider_gif.lo +libidirectfbimageprovider_gif_la_OBJECTS = \ + $(am_libidirectfbimageprovider_gif_la_OBJECTS) +libidirectfbimageprovider_gif_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbimageprovider_gif_la_LDFLAGS) $(LDFLAGS) -o $@ +@GIF_PROVIDER_TRUE@am_libidirectfbimageprovider_gif_la_rpath = -rpath \ +@GIF_PROVIDER_TRUE@ $(idirectfbimageproviderdir) +am__DEPENDENCIES_1 = +libidirectfbimageprovider_jpeg_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la $(am__DEPENDENCIES_1) +am_libidirectfbimageprovider_jpeg_la_OBJECTS = \ + idirectfbimageprovider_jpeg.lo +libidirectfbimageprovider_jpeg_la_OBJECTS = \ + $(am_libidirectfbimageprovider_jpeg_la_OBJECTS) +libidirectfbimageprovider_jpeg_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbimageprovider_jpeg_la_LDFLAGS) $(LDFLAGS) -o $@ +@JPEG_PROVIDER_TRUE@am_libidirectfbimageprovider_jpeg_la_rpath = \ +@JPEG_PROVIDER_TRUE@ -rpath $(idirectfbimageproviderdir) +libidirectfbimageprovider_png_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la $(am__DEPENDENCIES_1) +am_libidirectfbimageprovider_png_la_OBJECTS = \ + idirectfbimageprovider_png.lo +libidirectfbimageprovider_png_la_OBJECTS = \ + $(am_libidirectfbimageprovider_png_la_OBJECTS) +libidirectfbimageprovider_png_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbimageprovider_png_la_LDFLAGS) $(LDFLAGS) -o $@ +@PNG_PROVIDER_TRUE@am_libidirectfbimageprovider_png_la_rpath = -rpath \ +@PNG_PROVIDER_TRUE@ $(idirectfbimageproviderdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libidirectfbimageprovider_dfiff_la_SOURCES) \ + $(libidirectfbimageprovider_gif_la_SOURCES) \ + $(libidirectfbimageprovider_jpeg_la_SOURCES) \ + $(libidirectfbimageprovider_png_la_SOURCES) +DIST_SOURCES = $(libidirectfbimageprovider_dfiff_la_SOURCES) \ + $(libidirectfbimageprovider_gif_la_SOURCES) \ + $(libidirectfbimageprovider_jpeg_la_SOURCES) \ + $(libidirectfbimageprovider_png_la_SOURCES) +idirectfbimageproviderDATA_INSTALL = $(INSTALL_DATA) +DATA = $(idirectfbimageprovider_DATA) +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@ +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@ +idirectfbimageproviderdir = $(MODULEDIR)/interfaces/IDirectFBImageProvider +@GIF_PROVIDER_FALSE@GIF_PROVIDER_LTLIB = +@GIF_PROVIDER_TRUE@GIF_PROVIDER_LTLIB = libidirectfbimageprovider_gif.la +@JPEG_PROVIDER_FALSE@JPEG_PROVIDER_LTLIB = +@JPEG_PROVIDER_TRUE@JPEG_PROVIDER_LTLIB = libidirectfbimageprovider_jpeg.la +@PNG_PROVIDER_FALSE@PNG_PROVIDER_LTLIB = +@PNG_PROVIDER_TRUE@PNG_PROVIDER_LTLIB = libidirectfbimageprovider_png.la +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src + +AM_CPPFLAGS = -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" +idirectfbimageprovider_LTLIBRARIES = \ + libidirectfbimageprovider_dfiff.la \ + $(GIF_PROVIDER_LTLIB) \ + $(JPEG_PROVIDER_LTLIB) \ + $(PNG_PROVIDER_LTLIB) + +@BUILD_STATIC_TRUE@idirectfbimageprovider_DATA = $(idirectfbimageprovider_LTLIBRARIES:.la=.o) +libidirectfbimageprovider_png_la_SOURCES = idirectfbimageprovider_png.c +libidirectfbimageprovider_png_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(LIBPNG) + +libidirectfbimageprovider_png_la_LDFLAGS = -avoid-version -module +libidirectfbimageprovider_dfiff_la_SOURCES = idirectfbimageprovider_dfiff.c +libidirectfbimageprovider_dfiff_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbimageprovider_dfiff_la_LDFLAGS = -avoid-version -module +libidirectfbimageprovider_gif_la_SOURCES = idirectfbimageprovider_gif.c +libidirectfbimageprovider_gif_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbimageprovider_gif_la_LDFLAGS = -avoid-version -module +libidirectfbimageprovider_jpeg_la_SOURCES = idirectfbimageprovider_jpeg.c +libidirectfbimageprovider_jpeg_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/src/libdirectfb.la \ + $(LIBJPEG) + +libidirectfbimageprovider_jpeg_la_LDFLAGS = -avoid-version -module +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/rules/libobject.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 interfaces/IDirectFBImageProvider/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu interfaces/IDirectFBImageProvider/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 +install-idirectfbimageproviderLTLIBRARIES: $(idirectfbimageprovider_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(idirectfbimageproviderdir)" || $(MKDIR_P) "$(DESTDIR)$(idirectfbimageproviderdir)" + @list='$(idirectfbimageprovider_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(idirectfbimageproviderLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(idirectfbimageproviderdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(idirectfbimageproviderLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(idirectfbimageproviderdir)/$$f"; \ + else :; fi; \ + done + +uninstall-idirectfbimageproviderLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(idirectfbimageprovider_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(idirectfbimageproviderdir)/$$p'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(idirectfbimageproviderdir)/$$p"; \ + done + +clean-idirectfbimageproviderLTLIBRARIES: + -test -z "$(idirectfbimageprovider_LTLIBRARIES)" || rm -f $(idirectfbimageprovider_LTLIBRARIES) + @list='$(idirectfbimageprovider_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 +libidirectfbimageprovider_dfiff.la: $(libidirectfbimageprovider_dfiff_la_OBJECTS) $(libidirectfbimageprovider_dfiff_la_DEPENDENCIES) + $(libidirectfbimageprovider_dfiff_la_LINK) -rpath $(idirectfbimageproviderdir) $(libidirectfbimageprovider_dfiff_la_OBJECTS) $(libidirectfbimageprovider_dfiff_la_LIBADD) $(LIBS) +libidirectfbimageprovider_gif.la: $(libidirectfbimageprovider_gif_la_OBJECTS) $(libidirectfbimageprovider_gif_la_DEPENDENCIES) + $(libidirectfbimageprovider_gif_la_LINK) $(am_libidirectfbimageprovider_gif_la_rpath) $(libidirectfbimageprovider_gif_la_OBJECTS) $(libidirectfbimageprovider_gif_la_LIBADD) $(LIBS) +libidirectfbimageprovider_jpeg.la: $(libidirectfbimageprovider_jpeg_la_OBJECTS) $(libidirectfbimageprovider_jpeg_la_DEPENDENCIES) + $(libidirectfbimageprovider_jpeg_la_LINK) $(am_libidirectfbimageprovider_jpeg_la_rpath) $(libidirectfbimageprovider_jpeg_la_OBJECTS) $(libidirectfbimageprovider_jpeg_la_LIBADD) $(LIBS) +libidirectfbimageprovider_png.la: $(libidirectfbimageprovider_png_la_OBJECTS) $(libidirectfbimageprovider_png_la_DEPENDENCIES) + $(libidirectfbimageprovider_png_la_LINK) $(am_libidirectfbimageprovider_png_la_rpath) $(libidirectfbimageprovider_png_la_OBJECTS) $(libidirectfbimageprovider_png_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbimageprovider_dfiff.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbimageprovider_gif.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbimageprovider_jpeg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbimageprovider_png.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-idirectfbimageproviderDATA: $(idirectfbimageprovider_DATA) + @$(NORMAL_INSTALL) + test -z "$(idirectfbimageproviderdir)" || $(MKDIR_P) "$(DESTDIR)$(idirectfbimageproviderdir)" + @list='$(idirectfbimageprovider_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(idirectfbimageproviderDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(idirectfbimageproviderdir)/$$f'"; \ + $(idirectfbimageproviderDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(idirectfbimageproviderdir)/$$f"; \ + done + +uninstall-idirectfbimageproviderDATA: + @$(NORMAL_UNINSTALL) + @list='$(idirectfbimageprovider_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(idirectfbimageproviderdir)/$$f'"; \ + rm -f "$(DESTDIR)$(idirectfbimageproviderdir)/$$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) +installdirs: + for dir in "$(DESTDIR)$(idirectfbimageproviderdir)" "$(DESTDIR)$(idirectfbimageproviderdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-idirectfbimageproviderLTLIBRARIES \ + clean-libtool 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-idirectfbimageproviderDATA \ + install-idirectfbimageproviderLTLIBRARIES + +install-dvi: install-dvi-am + +install-exec-am: + +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-idirectfbimageproviderDATA \ + uninstall-idirectfbimageproviderLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-idirectfbimageproviderLTLIBRARIES clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am \ + install-idirectfbimageproviderDATA \ + install-idirectfbimageproviderLTLIBRARIES install-info \ + install-info-am install-man install-pdf install-pdf-am \ + 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-idirectfbimageproviderDATA \ + uninstall-idirectfbimageproviderLTLIBRARIES + +%.o: .libs/%.a %.la + rm -f $<.tmp/*.o + if test -d $<.tmp; then rmdir $<.tmp; fi + mkdir $<.tmp + (cd $<.tmp && $(AR) x ../../$<) + $(LD) -o $@ -r $<.tmp/*.o + rm -f $<.tmp/*.o && rmdir $<.tmp + +.PHONY: $(LTLIBRARIES:%.la=.libs/%.a) +# 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/interfaces/IDirectFBImageProvider/idirectfbimageprovider_dfiff.c b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_dfiff.c new file mode 100755 index 0000000..56207e4 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_dfiff.c @@ -0,0 +1,374 @@ +/* + (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>. + + All rights reserved. + + This file is subject to the terms and conditions of the MIT License: + + 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. +*/ + +#include <config.h> + +#include <errno.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <string.h> +#include <unistd.h> +#include <stdarg.h> + +#include <directfb.h> + +#include <direct/debug.h> +#include <direct/interface.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include <idirectfb.h> + +#include <display/idirectfbsurface.h> + +#include <misc/gfx_util.h> + +#include <media/idirectfbdatabuffer.h> +#include <media/idirectfbimageprovider.h> + +#include <dfiff.h> + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ); + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, DFIFF ) + + +/* + * private data struct of IDirectFBImageProvider_DFIFF + */ +typedef struct { + int ref; /* reference counter */ + + void *ptr; /* pointer to raw file data (mapped) */ + int len; /* data length, i.e. file size */ + + DIRenderCallback render_callback; + void *render_callback_context; + + CoreDFB *core; +} IDirectFBImageProvider_DFIFF_data; + + + + + +static void +IDirectFBImageProvider_DFIFF_Destruct( IDirectFBImageProvider *thiz ) +{ + IDirectFBImageProvider_DFIFF_data *data = thiz->priv; + + munmap( data->ptr, data->len ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBImageProvider_DFIFF_AddRef( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_DFIFF) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBImageProvider_DFIFF_Release( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_DFIFF) + + if (--data->ref == 0) { + IDirectFBImageProvider_DFIFF_Destruct( thiz ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_DFIFF_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect ) +{ + DFBResult ret; + IDirectFBSurface_data *dst_data; + CoreSurface *dst_surface; + const DFIFFHeader *header; + DFBRectangle rect; + DFBRectangle clipped; + + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_DFIFF) + + if (!destination) + return DFB_INVARG; + + DIRECT_INTERFACE_GET_DATA_FROM (destination, dst_data, IDirectFBSurface); + + dst_surface = dst_data->surface; + if (!dst_surface) + return DFB_DEAD; + + if (dest_rect) { + rect.x = dest_rect->x + dst_data->area.wanted.x; + rect.y = dest_rect->y + dst_data->area.wanted.y; + rect.w = dest_rect->w; + rect.h = dest_rect->h; + } + else + rect = dst_data->area.wanted; + + if (rect.w < 1 || rect.h < 1) + return DFB_INVAREA; + + clipped = rect; + + if (!dfb_rectangle_intersect( &clipped, &dst_data->area.current )) + return DFB_INVAREA; + + header = data->ptr; + + if (DFB_RECTANGLE_EQUAL( rect, clipped ) && + rect.w == header->width && rect.h == header->height && + dst_surface->config.format == header->format) + { + ret = dfb_surface_write_buffer( dst_surface, CSBR_BACK, + data->ptr + sizeof(DFIFFHeader), header->pitch, &rect ); + if (ret) + return ret; + } + else { + IDirectFBSurface *source; + DFBSurfaceDescription desc; + DFBSurfaceCapabilities caps; + DFBRegion clip = DFB_REGION_INIT_FROM_RECTANGLE( &clipped ); + DFBRegion old_clip; + + thiz->GetSurfaceDescription( thiz, &desc ); + + desc.flags |= DSDESC_PREALLOCATED; + desc.preallocated[0].data = data->ptr + sizeof(DFIFFHeader); + desc.preallocated[0].pitch = header->pitch; + + ret = idirectfb_singleton->CreateSurface( idirectfb_singleton, &desc, &source ); + if (ret) + return ret; + + destination->GetCapabilities( destination, &caps ); + + if (caps & DSCAPS_PREMULTIPLIED && DFB_PIXELFORMAT_HAS_ALPHA(desc.pixelformat)) + destination->SetBlittingFlags( destination, DSBLIT_SRC_PREMULTIPLY ); + else + destination->SetBlittingFlags( destination, DSBLIT_NOFX ); + + destination->GetClip( destination, &old_clip ); + destination->SetClip( destination, &clip ); + + destination->StretchBlit( destination, source, NULL, &rect ); + + destination->SetClip( destination, &old_clip ); + + destination->SetBlittingFlags( destination, DSBLIT_NOFX ); + + destination->ReleaseSource( destination ); + + source->Release( source ); + } + + if (data->render_callback) { + DFBRectangle rect = { 0, 0, clipped.w, clipped.h }; + data->render_callback( &rect, data->render_callback_context ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_DFIFF_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_DFIFF) + + data->render_callback = callback; + data->render_callback_context = context; + + return DFB_OK; +} + +/* Loading routines */ + +static DFBResult +IDirectFBImageProvider_DFIFF_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ) +{ + const DFIFFHeader *header; + + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_DFIFF) + + header = data->ptr; + + dsc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + dsc->width = header->width; + dsc->height = header->height; + dsc->pixelformat = header->format; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_DFIFF_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *desc ) +{ + const DFIFFHeader *header; + + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_DFIFF) + + if (!desc) + return DFB_INVARG; + + header = data->ptr; + + desc->caps = DICAPS_NONE; + + if (DFB_PIXELFORMAT_HAS_ALPHA( header->format )) + desc->caps |= DICAPS_ALPHACHANNEL; + + return DFB_OK; +} + + + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ) +{ + if (!strncmp( (const char*) ctx->header, "DFIFF", 5 )) + return DFB_OK; + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ) +{ + DFBResult ret; + struct stat stat; + void *ptr; + int fd = -1; + IDirectFBDataBuffer_data *buffer_data; + + IDirectFBDataBuffer *buffer; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_DFIFF) + + va_start( tag, thiz ); + buffer = va_arg( tag, IDirectFBDataBuffer * ); + core = va_arg( tag, CoreDFB * ); + va_end( tag ); + + D_MAGIC_ASSERT( (IAny*) buffer, DirectInterface ); + + /* Get the buffer's private data. */ + buffer_data = buffer->priv; + if (!buffer_data) { + ret = DFB_DEAD; + goto error; + } + + /* Check for valid filename. */ + if (!buffer_data->filename) { + ret = DFB_UNSUPPORTED; + goto error; + } + + /* Open the file. */ + fd = open( buffer_data->filename, O_RDONLY ); + if (fd < 0) { + ret = errno2result( errno ); + D_PERROR( "ImageProvider/DFIFF: Failure during open() of '%s'!\n", buffer_data->filename ); + goto error; + } + + /* Query file size etc. */ + if (fstat( fd, &stat ) < 0) { + ret = errno2result( errno ); + D_PERROR( "ImageProvider/DFIFF: Failure during fstat() of '%s'!\n", buffer_data->filename ); + goto error; + } + + /* Memory map the file. */ + ptr = mmap( NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0 ); + if (ptr == MAP_FAILED) { + ret = errno2result( errno ); + D_PERROR( "ImageProvider/DFIFF: Failure during mmap() of '%s'!\n", buffer_data->filename ); + goto error; + } + + /* Already close, we still have the map. */ + close( fd ); + + data->ref = 1; + data->ptr = ptr; + data->len = stat.st_size; + data->core = core; + + thiz->AddRef = IDirectFBImageProvider_DFIFF_AddRef; + thiz->Release = IDirectFBImageProvider_DFIFF_Release; + thiz->RenderTo = IDirectFBImageProvider_DFIFF_RenderTo; + thiz->SetRenderCallback = IDirectFBImageProvider_DFIFF_SetRenderCallback; + thiz->GetImageDescription = IDirectFBImageProvider_DFIFF_GetImageDescription; + thiz->GetSurfaceDescription = IDirectFBImageProvider_DFIFF_GetSurfaceDescription; + + return DFB_OK; + +error: + if (fd != -1) + close( fd ); + + DIRECT_DEALLOCATE_INTERFACE(thiz); + + return ret; +} + diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_gif.c b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_gif.c new file mode 100755 index 0000000..f9e8229 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_gif.c @@ -0,0 +1,924 @@ +/* + (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 <unistd.h> +#include <string.h> +#include <errno.h> +#include <stdarg.h> + +#include <directfb.h> + +#include <display/idirectfbsurface.h> + +#include <media/idirectfbimageprovider.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> + +#include <core/layers.h> +#include <core/surface.h> + +#include <misc/gfx_util.h> +#include <direct/interface.h> +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <misc/util.h> + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ); + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, GIF ) + + +#ifndef NODEBUG +#define GIFERRORMSG(x...) { fprintf( stderr, "(GIFLOADER) "x ); \ + fprintf( stderr, "\n" ); } +#else +#define GIFERRORMSG(x...) +#endif + +#define MAXCOLORMAPSIZE 256 + +#define CM_RED 0 +#define CM_GREEN 1 +#define CM_BLUE 2 + +#define MAX_LWZ_BITS 12 + +#define INTERLACE 0x40 +#define LOCALCOLORMAP 0x80 + +#define BitSet(byte, bit) (((byte) & (bit)) == (bit)) + +#define LM_to_uint(a,b) (((b)<<8)|(a)) + +/* + * private data struct of IDirectFBImageProvider_GIF + */ +typedef struct { + int ref; /* reference counter */ + + IDirectFBDataBuffer *buffer; + + u32 *image; + int image_width; + int image_height; + bool image_transparency; + u32 image_colorkey; + + unsigned int Width; + unsigned int Height; + u8 ColorMap[3][MAXCOLORMAPSIZE]; + unsigned int BitPixel; + unsigned int ColorResolution; + u32 Background; + unsigned int AspectRatio; + + + int GrayScale; + int transparent; + int delayTime; + int inputFlag; + int disposal; + + + u8 buf[280]; + int curbit, lastbit, done, last_byte; + + + int fresh; + int code_size, set_code_size; + int max_code, max_code_size; + int firstcode, oldcode; + int clear_code, end_code; + int table[2][(1<< MAX_LWZ_BITS)]; + int stack[(1<<(MAX_LWZ_BITS))*2], *sp; + + DIRenderCallback render_callback; + void *render_callback_ctx; + + CoreDFB *core; +} IDirectFBImageProvider_GIF_data; + +static bool verbose = false; +static bool showComment = false; +static bool ZeroDataBlock = false; + +static u32* ReadGIF( IDirectFBImageProvider_GIF_data *data, int imageNumber, + int *width, int *height, bool *transparency, + u32 *key_rgb, bool alpha, bool headeronly); + +static bool ReadOK( IDirectFBDataBuffer *buffer, void *data, unsigned int len ); + + +static DirectResult +IDirectFBImageProvider_GIF_AddRef ( IDirectFBImageProvider *thiz ); + +static DirectResult +IDirectFBImageProvider_GIF_Release ( IDirectFBImageProvider *thiz ); + +static DFBResult +IDirectFBImageProvider_GIF_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *destination_rect ); + +static DFBResult +IDirectFBImageProvider_GIF_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ); + +static DFBResult +IDirectFBImageProvider_GIF_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ); + +static DFBResult +IDirectFBImageProvider_GIF_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ); + + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ) +{ + if (strncmp ((char*) ctx->header, "GIF8", 4) == 0) + return DFB_OK; + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ) +{ + IDirectFBDataBuffer *buffer; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_GIF) + + va_start( tag, thiz ); + buffer = va_arg( tag, IDirectFBDataBuffer * ); + core = va_arg( tag, CoreDFB * ); + va_end( tag ); + + data->ref = 1; + + data->GrayScale = -1; + data->transparent = -1; + data->delayTime = -1; + + data->core = core; + data->buffer = buffer; + buffer->AddRef( buffer ); + + data->image = ReadGIF( data, 1, &data->image_width, &data->image_height, + &data->image_transparency, &data->image_colorkey, + true, false ); + + buffer->Release( buffer ); + data->buffer = NULL; + + if (!data->image) { + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_FAILURE; + } + + thiz->AddRef = IDirectFBImageProvider_GIF_AddRef; + thiz->Release = IDirectFBImageProvider_GIF_Release; + thiz->RenderTo = IDirectFBImageProvider_GIF_RenderTo; + thiz->SetRenderCallback = IDirectFBImageProvider_GIF_SetRenderCallback; + thiz->GetImageDescription = IDirectFBImageProvider_GIF_GetImageDescription; + thiz->GetSurfaceDescription = + IDirectFBImageProvider_GIF_GetSurfaceDescription; + + return DFB_OK; +} + +static void +IDirectFBImageProvider_GIF_Destruct( IDirectFBImageProvider *thiz ) +{ + IDirectFBImageProvider_GIF_data *data = + (IDirectFBImageProvider_GIF_data*)thiz->priv; + + if (data->image) + D_FREE( data->image ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBImageProvider_GIF_AddRef( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_GIF) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBImageProvider_GIF_Release( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_GIF) + + if (--data->ref == 0) { + IDirectFBImageProvider_GIF_Destruct( thiz ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_GIF_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect ) +{ + DFBResult ret; + DFBRegion clip; + DFBRectangle rect; + DFBSurfacePixelFormat format; + IDirectFBSurface_data *dst_data; + CoreSurface *dst_surface; + + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_GIF) + + dst_data = (IDirectFBSurface_data*) destination->priv; + if (!dst_data) + return DFB_DEAD; + + dst_surface = dst_data->surface; + if (!dst_surface) + return DFB_DESTROYED; + + dfb_region_from_rectangle( &clip, &dst_data->area.current ); + + if (dest_rect) { + if (dest_rect->w < 1 || dest_rect->h < 1) + return DFB_INVARG; + rect = *dest_rect; + rect.x += dst_data->area.wanted.x; + rect.y += dst_data->area.wanted.y; + } + else { + rect = dst_data->area.wanted; + } + + ret = destination->GetPixelFormat( destination, &format ); + if (ret) + return ret; + + /* actual loading and rendering */ + if (dfb_rectangle_region_intersects( &rect, &clip )) { + CoreSurfaceBufferLock lock; + + ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); + if (ret) + return ret; + + dfb_scale_linear_32( data->image, data->image_width, data->image_height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + + dfb_surface_unlock_buffer( dst_surface, &lock ); + + if (data->render_callback) { + DIRenderCallbackResult r; + + rect.x = 0; + rect.y = 0; + rect.w = data->image_width; + rect.h = data->image_height; + + r = data->render_callback( &rect, data->render_callback_ctx ); + + if (r != DIRCR_OK) + return DFB_INTERRUPTED; + } + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_GIF_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_GIF) + + data->render_callback = callback; + data->render_callback_ctx = context; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_GIF_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_GIF) + + dsc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + dsc->width = data->image_width; + dsc->height = data->image_height; + dsc->pixelformat = dfb_primary_layer_pixelformat(); + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_GIF_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_GIF) + + if (data->image_transparency) { + dsc->caps = DICAPS_COLORKEY; + + dsc->colorkey_r = (data->image_colorkey & 0xff0000) >> 16; + dsc->colorkey_g = (data->image_colorkey & 0x00ff00) >> 8; + dsc->colorkey_b = (data->image_colorkey & 0x0000ff); + } + else + dsc->caps = DICAPS_NONE; + + return DFB_OK; +} + + +/********************************** + GIF Loader Code + **********************************/ + +static int ReadColorMap( IDirectFBDataBuffer *buffer, int number, + u8 buf[3][MAXCOLORMAPSIZE] ) +{ + int i; + u8 rgb[3]; + + for (i = 0; i < number; ++i) { + if (! ReadOK( buffer, rgb, sizeof(rgb) )) { + GIFERRORMSG("bad colormap" ); + return true; + } + + buf[CM_RED][i] = rgb[0] ; + buf[CM_GREEN][i] = rgb[1] ; + buf[CM_BLUE][i] = rgb[2] ; + } + return false; +} + +static int GetDataBlock(IDirectFBDataBuffer *buffer, u8 *buf) +{ + unsigned char count; + + if (! ReadOK( buffer, &count, 1 )) { + GIFERRORMSG("error in getting DataBlock size" ); + return -1; + } + ZeroDataBlock = count == 0; + + if ((count != 0) && (! ReadOK( buffer, buf, count ))) { + GIFERRORMSG("error in reading DataBlock" ); + return -1; + } + + return count; +} + +static int GetCode(IDirectFBImageProvider_GIF_data *data, int code_size, int flag) +{ + int i, j, ret; + unsigned char count; + + if (flag) { + data->curbit = 0; + data->lastbit = 0; + data->done = false; + return 0; + } + + if ( (data->curbit+code_size) >= data->lastbit) { + if (data->done) { + if (data->curbit >= data->lastbit) { + GIFERRORMSG("ran off the end of my bits" ); + } + return -1; + } + data->buf[0] = data->buf[data->last_byte-2]; + data->buf[1] = data->buf[data->last_byte-1]; + + if ((count = GetDataBlock( data->buffer, &data->buf[2] )) == 0) { + data->done = true; + } + + data->last_byte = 2 + count; + data->curbit = (data->curbit - data->lastbit) + 16; + data->lastbit = (2+count) * 8; + } + + ret = 0; + for (i = data->curbit, j = 0; j < code_size; ++i, ++j) { + ret |= ((data->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; + } + data->curbit += code_size; + + return ret; +} + +static int DoExtension( IDirectFBImageProvider_GIF_data *data, int label ) +{ + unsigned char buf[256] = { 0 }; + char *str; + + switch (label) { + case 0x01: /* Plain Text Extension */ + str = "Plain Text Extension"; + break; + case 0xff: /* Application Extension */ + str = "Application Extension"; + break; + case 0xfe: /* Comment Extension */ + str = "Comment Extension"; + while (GetDataBlock( data->buffer, (u8*) buf ) != 0) { + if (showComment) + GIFERRORMSG("gif comment: %s", buf ); + } + return false; + case 0xf9: /* Graphic Control Extension */ + str = "Graphic Control Extension"; + (void) GetDataBlock( data->buffer, (u8*) buf ); + data->disposal = (buf[0] >> 2) & 0x7; + data->inputFlag = (buf[0] >> 1) & 0x1; + data->delayTime = LM_to_uint( buf[1], buf[2] ); + if ((buf[0] & 0x1) != 0) { + data->transparent = buf[3]; + } + while (GetDataBlock( data->buffer, (u8*) buf ) != 0) + ; + return false; + default: + str = (char*) buf; + snprintf(str, 256, "UNKNOWN (0x%02x)", label); + break; + } + + if (verbose) + GIFERRORMSG("got a '%s' extension", str ); + + while (GetDataBlock( data->buffer, (u8*) buf ) != 0) + ; + + return false; +} + +static int LWZReadByte( IDirectFBImageProvider_GIF_data *data, int flag, int input_code_size ) +{ + int code, incode; + int i; + + if (flag) { + data->set_code_size = input_code_size; + data->code_size = data->set_code_size+1; + data->clear_code = 1 << data->set_code_size ; + data->end_code = data->clear_code + 1; + data->max_code_size = 2*data->clear_code; + data->max_code = data->clear_code+2; + + GetCode(data, 0, true); + + data->fresh = true; + + for (i = 0; i < data->clear_code; ++i) { + data->table[0][i] = 0; + data->table[1][i] = i; + } + for (; i < (1<<MAX_LWZ_BITS); ++i) { + data->table[0][i] = data->table[1][0] = 0; + } + data->sp = data->stack; + + return 0; + } + else if (data->fresh) { + data->fresh = false; + do { + data->firstcode = data->oldcode = GetCode( data, data->code_size, false ); + } while (data->firstcode == data->clear_code); + + return data->firstcode; + } + + if (data->sp > data->stack) { + return *--data->sp; + } + + while ((code = GetCode( data, data->code_size, false )) >= 0) { + if (code == data->clear_code) { + for (i = 0; i < data->clear_code; ++i) { + data->table[0][i] = 0; + data->table[1][i] = i; + } + for (; i < (1<<MAX_LWZ_BITS); ++i) { + data->table[0][i] = data->table[1][i] = 0; + } + data->code_size = data->set_code_size+1; + data->max_code_size = 2*data->clear_code; + data->max_code = data->clear_code+2; + data->sp = data->stack; + data->firstcode = data->oldcode = GetCode( data, data->code_size, false ); + + return data->firstcode; + } + else if (code == data->end_code) { + int count; + u8 buf[260]; + + if (ZeroDataBlock) { + return -2; + } + + while ((count = GetDataBlock( data->buffer, buf )) > 0) + ; + + if (count != 0) + GIFERRORMSG("missing EOD in data stream " + "(common occurence)"); + + return -2; + } + + incode = code; + + if (code >= data->max_code) { + *data->sp++ = data->firstcode; + code = data->oldcode; + } + + while (code >= data->clear_code) { + *data->sp++ = data->table[1][code]; + if (code == data->table[0][code]) { + GIFERRORMSG("circular table entry BIG ERROR"); + } + code = data->table[0][code]; + } + + *data->sp++ = data->firstcode = data->table[1][code]; + + if ((code = data->max_code) <(1<<MAX_LWZ_BITS)) { + data->table[0][code] = data->oldcode; + data->table[1][code] = data->firstcode; + ++data->max_code; + if ((data->max_code >= data->max_code_size) + && (data->max_code_size < (1<<MAX_LWZ_BITS))) + { + data->max_code_size *= 2; + ++data->code_size; + } + } + + data->oldcode = incode; + + if (data->sp > data->stack) { + return *--data->sp; + } + } + return code; +} + +static int SortColors (const void *a, const void *b) +{ + return (*((const u8 *) a) - *((const u8 *) b)); +} + +/* looks for a color that is not in the colormap and ideally not + even close to the colors used in the colormap */ +static u32 FindColorKey( int n_colors, u8 cmap[3][MAXCOLORMAPSIZE] ) +{ + u32 color = 0xFF000000; + u8 csort[MAXCOLORMAPSIZE]; + int i, j, index, d; + + if (n_colors < 1) + return color; + + D_ASSERT( n_colors <= MAXCOLORMAPSIZE ); + + for (i = 0; i < 3; i++) { + direct_memcpy( csort, cmap[i], n_colors ); + qsort( csort, n_colors, 1, SortColors ); + + for (j = 1, index = 0, d = 0; j < n_colors; j++) { + if (csort[j] - csort[j-1] > d) { + d = csort[j] - csort[j-1]; + index = j; + } + } + if ((csort[0] - 0x0) > d) { + d = csort[0] - 0x0; + index = n_colors; + } + if (0xFF - (csort[n_colors - 1]) > d) { + index = n_colors + 1; + } + + if (index < n_colors) + csort[0] = csort[index] - (d/2); + else if (index == n_colors) + csort[0] = 0x0; + else + csort[0] = 0xFF; + + color |= (csort[0] << (8 * (2 - i))); + } + + return color; +} + +static u32* ReadImage( IDirectFBImageProvider_GIF_data *data, int width, int height, + u8 cmap[3][MAXCOLORMAPSIZE], u32 key_rgb, + bool interlace, bool ignore ) +{ + u8 c; + int v; + int xpos = 0, ypos = 0, pass = 0; + u32 *image; + + /* + ** Initialize the decompression routines + */ + if (! ReadOK( data->buffer, &c, 1 )) + GIFERRORMSG("EOF / read error on image data" ); + + if (LWZReadByte( data, true, c ) < 0) + GIFERRORMSG("error reading image" ); + + /* + ** If this is an "uninteresting picture" ignore it. + */ + if (ignore) { + if (verbose) + GIFERRORMSG("skipping image..." ); + + while (LWZReadByte( data, false, c ) >= 0) + ; + return NULL; + } + + // FIXME: allocates four additional bytes because the scaling functions + // in src/misc/gfx_util.c have an off-by-one bug which causes + // segfaults on darwin/osx (not on linux) + if ((image = D_MALLOC(width * height * 4 + 4)) == NULL) { + GIFERRORMSG("couldn't alloc space for image" ); + } + + if (verbose) { + GIFERRORMSG("reading %d by %d%s GIF image", width, height, + interlace ? " interlaced" : "" ); + } + + while ((v = LWZReadByte( data, false, c )) >= 0 ) { + u32 *dst = image + (ypos * width + xpos); + + if (v == data->transparent) { + *dst++ = key_rgb; + } + else { + *dst++ = (0xFF000000 | + cmap[CM_RED][v] << 16 | + cmap[CM_GREEN][v] << 8 | + cmap[CM_BLUE][v]); + } + + ++xpos; + if (xpos == width) { + xpos = 0; + if (interlace) { + switch (pass) { + case 0: + case 1: + ypos += 8; + break; + case 2: + ypos += 4; + break; + case 3: + ypos += 2; + break; + } + + if (ypos >= height) { + ++pass; + switch (pass) { + case 1: + ypos = 4; + break; + case 2: + ypos = 2; + break; + case 3: + ypos = 1; + break; + default: + goto fini; + } + } + } + else { + ++ypos; + } + } + if (ypos >= height) { + break; + } + } + +fini: + + if (LWZReadByte( data, false, c ) >= 0) { + GIFERRORMSG("too much input data, ignoring extra..."); + } + return image; +} + + +static u32* ReadGIF( IDirectFBImageProvider_GIF_data *data, int imageNumber, + int *width, int *height, bool *transparency, + u32 *key_rgb, bool alpha, bool headeronly) +{ + u8 buf[16]; + u8 c; + u8 localColorMap[3][MAXCOLORMAPSIZE]; + u32 colorKey = 0; + bool useGlobalColormap; + int bitPixel; + int imageCount = 0; + char version[4]; + + if (! ReadOK( data->buffer, buf, 6 )) { + GIFERRORMSG("error reading magic number" ); + } + + if (strncmp( (char *)buf, "GIF", 3 ) != 0) { + GIFERRORMSG("not a GIF file" ); + } + + direct_snputs( version, (char *)buf + 3, 4 ); + + if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) { + GIFERRORMSG("bad version number, not '87a' or '89a'" ); + } + + if (! ReadOK(data->buffer,buf,7)) { + GIFERRORMSG("failed to read screen descriptor" ); + } + + data->Width = LM_to_uint( buf[0], buf[1] ); + data->Height = LM_to_uint( buf[2], buf[3] ); + data->BitPixel = 2 << (buf[4] & 0x07); + data->ColorResolution = (((buf[4] & 0x70) >> 3) + 1); + data->Background = buf[5]; + data->AspectRatio = buf[6]; + + if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ + if (ReadColorMap( data->buffer, data->BitPixel, data->ColorMap )) { + GIFERRORMSG("error reading global colormap" ); + } + } + + if (data->AspectRatio != 0 && data->AspectRatio != 49) { + /* float r = ( (float) data->AspectRatio + 15.0 ) / 64.0; */ + GIFERRORMSG("warning - non-square pixels"); + } + + data->transparent = -1; + data->delayTime = -1; + data->inputFlag = -1; + data->disposal = 0; + + for (;;) { + if (! ReadOK( data->buffer, &c, 1)) { + GIFERRORMSG("EOF / read error on image data" ); + } + + if (c == ';') { /* GIF terminator */ + if (imageCount < imageNumber) { + GIFERRORMSG("only %d image%s found in file", + imageCount, imageCount>1?"s":"" ); + } + return NULL; + } + + if (c == '!') { /* Extension */ + if (! ReadOK( data->buffer, &c, 1)) { + GIFERRORMSG("OF / read error on extention function code"); + } + DoExtension( data, c ); + continue; + } + + if (c != ',') { /* Not a valid start character */ + GIFERRORMSG("bogus character 0x%02x, ignoring", (int) c ); + continue; + } + + ++imageCount; + + if (! ReadOK( data->buffer, buf, 9 )) { + GIFERRORMSG("couldn't read left/top/width/height"); + } + + *width = LM_to_uint( buf[4], buf[5] ); + *height = LM_to_uint( buf[6], buf[7] ); + *transparency = (data->transparent != -1); + + if (headeronly && !(*transparency && key_rgb)) + return NULL; + + useGlobalColormap = ! BitSet( buf[8], LOCALCOLORMAP ); + + if (useGlobalColormap) { + if (*transparency && (key_rgb || !headeronly)) + colorKey = FindColorKey( data->BitPixel, + data->ColorMap ); + } + else { + bitPixel = 2 << (buf[8] & 0x07); + if (ReadColorMap( data->buffer, bitPixel, localColorMap )) + GIFERRORMSG("error reading local colormap" ); + + if (*transparency && (key_rgb || !headeronly)) + colorKey = FindColorKey( bitPixel, localColorMap ); + } + + if (key_rgb) + *key_rgb = colorKey; + + if (headeronly) + return NULL; + + if (alpha) + colorKey &= 0x00FFFFFF; + + return ReadImage( data, *width, *height, + (useGlobalColormap ? + data->ColorMap : localColorMap), colorKey, + BitSet( buf[8], INTERLACE ), + imageCount != imageNumber); + } +} + +static bool +ReadOK( IDirectFBDataBuffer *buffer, void *data, unsigned int len ) +{ + DFBResult ret; + + ret = buffer->WaitForData( buffer, len ); + if (ret) { + DirectFBError( "(DirectFB/ImageProvider_GIF) WaitForData failed", ret ); + return false; + } + + ret = buffer->GetData( buffer, len, data, NULL ); + if (ret) { + DirectFBError( "(DirectFB/ImageProvider_GIF) GetData failed", ret ); + return false; + } + + return true; +} + diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_jpeg.c b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_jpeg.c new file mode 100755 index 0000000..e67da17 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_jpeg.c @@ -0,0 +1,640 @@ +/* + (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 <unistd.h> +#include <errno.h> +#include <string.h> +#include <stdarg.h> + +#include <directfb.h> + +#include <display/idirectfbsurface.h> + +#include <media/idirectfbimageprovider.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> + +#include <core/layers.h> +#include <core/surface.h> + +#include <misc/gfx_util.h> +#include <misc/util.h> +#include <direct/interface.h> +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <direct/messages.h> + +#include <setjmp.h> +#include <math.h> + +#undef HAVE_STDLIB_H +#include <jpeglib.h> + + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ); + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, JPEG ) + +/* + * private data struct of IDirectFBImageProvider_JPEG + */ +typedef struct { + int ref; /* reference counter */ + + IDirectFBDataBuffer *buffer; + + DIRenderCallback render_callback; + void *render_callback_context; + + u32 *image; + int width; + int height; + + CoreDFB *core; +} IDirectFBImageProvider_JPEG_data; + +static DirectResult +IDirectFBImageProvider_JPEG_AddRef ( IDirectFBImageProvider *thiz ); + +static DirectResult +IDirectFBImageProvider_JPEG_Release ( IDirectFBImageProvider *thiz ); + +static DFBResult +IDirectFBImageProvider_JPEG_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *destination_rect ); + +static DFBResult +IDirectFBImageProvider_JPEG_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ); + +static DFBResult +IDirectFBImageProvider_JPEG_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc); + +static DFBResult +IDirectFBImageProvider_JPEG_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ); + + +#define JPEG_PROG_BUF_SIZE 0x10000 + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + JOCTET *data; /* start of buffer */ + + IDirectFBDataBuffer *buffer; + + int peekonly; + int peekoffset; +} buffer_source_mgr; + +typedef buffer_source_mgr * buffer_src_ptr; + +static void +buffer_init_source (j_decompress_ptr cinfo) +{ + buffer_src_ptr src = (buffer_src_ptr) cinfo->src; + IDirectFBDataBuffer *buffer = src->buffer; + + buffer->SeekTo( buffer, 0 ); /* ignore return value */ +} + +static boolean +buffer_fill_input_buffer (j_decompress_ptr cinfo) +{ + DFBResult ret; + unsigned int nbytes = 0; + buffer_src_ptr src = (buffer_src_ptr) cinfo->src; + IDirectFBDataBuffer *buffer = src->buffer; + + buffer->WaitForDataWithTimeout( buffer, JPEG_PROG_BUF_SIZE, 1, 0 ); + + if (src->peekonly) { + ret = buffer->PeekData( buffer, JPEG_PROG_BUF_SIZE, + src->peekoffset, src->data, &nbytes ); + src->peekoffset += MAX( nbytes, 0 ); + } + else { + ret = buffer->GetData( buffer, JPEG_PROG_BUF_SIZE, src->data, &nbytes ); + } + + if (ret || nbytes <= 0) { + /* Insert a fake EOI marker */ + src->data[0] = (JOCTET) 0xFF; + src->data[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + + if (ret && ret != DFB_EOF) + DirectFBError( "(DirectFB/ImageProvider_JPEG) GetData failed", ret ); + } + + src->pub.next_input_byte = src->data; + src->pub.bytes_in_buffer = nbytes; + + return TRUE; +} + +static void +buffer_skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + buffer_src_ptr src = (buffer_src_ptr) cinfo->src; + + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void)buffer_fill_input_buffer(cinfo); + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + +static void +buffer_term_source (j_decompress_ptr cinfo) +{ +} + +static void +jpeg_buffer_src (j_decompress_ptr cinfo, IDirectFBDataBuffer *buffer, int peekonly) +{ + buffer_src_ptr src; + + cinfo->src = (struct jpeg_source_mgr *) + cinfo->mem->alloc_small ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof (buffer_source_mgr)); + + src = (buffer_src_ptr) cinfo->src; + + src->data = (JOCTET *) + cinfo->mem->alloc_small ((j_common_ptr) cinfo, JPOOL_PERMANENT, + JPEG_PROG_BUF_SIZE * sizeof (JOCTET)); + + src->buffer = buffer; + src->peekonly = peekonly; + src->peekoffset = 0; + + src->pub.init_source = buffer_init_source; + src->pub.fill_input_buffer = buffer_fill_input_buffer; + src->pub.skip_input_data = buffer_skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = buffer_term_source; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} + +struct my_error_mgr { + struct jpeg_error_mgr pub; /* "public" fields */ + jmp_buf setjmp_buffer; /* for return to caller */ +}; + +static void +jpeglib_panic(j_common_ptr cinfo) +{ + struct my_error_mgr *myerr = (struct my_error_mgr*) cinfo->err; + longjmp(myerr->setjmp_buffer, 1); +} + +static inline void +copy_line32( u32 *argb, const u8 *rgb, int width ) +{ + while (width--) { + *argb++ = 0xFF000000 | (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; + + rgb += 3; + } +} + +static inline void +copy_line_nv16( u16 *yy, u16 *cbcr, const u8 *src_ycbcr, int width ) +{ + int x; + + for (x=0; x<width/2; x++) { +#ifdef WORDS_BIGENDIAN + yy[x] = (src_ycbcr[0] << 8) | src_ycbcr[3]; + + cbcr[x] = (((src_ycbcr[1] + src_ycbcr[4]) << 7) & 0xff00) | + ((src_ycbcr[2] + src_ycbcr[5]) >> 1); +#else + yy[x] = (src_ycbcr[3] << 8) | src_ycbcr[0]; + + cbcr[x] = (((src_ycbcr[2] + src_ycbcr[5]) << 7) & 0xff00) | + ((src_ycbcr[1] + src_ycbcr[4]) >> 1); +#endif + + src_ycbcr += 6; + } + + if (width & 1) { + u8 *y = (u8*) yy; + + y[width-1] = src_ycbcr[0]; + +#ifdef WORDS_BIGENDIAN + cbcr[x] = (src_ycbcr[1] << 8) | src_ycbcr[2]; +#else + cbcr[x] = (src_ycbcr[2] << 8) | src_ycbcr[1]; +#endif + } +} + + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ) +{ + if (ctx->header[0] == 0xff && ctx->header[1] == 0xd8) { + if (strncmp ((char*) ctx->header + 6, "JFIF", 4) == 0 || + strncmp ((char*) ctx->header + 6, "Exif", 4) == 0) + return DFB_OK; + + if (ctx->filename && strchr (ctx->filename, '.' ) && + (strcasecmp ( strchr (ctx->filename, '.' ), ".jpg" ) == 0 || + strcasecmp ( strchr (ctx->filename, '.' ), ".jpeg") == 0)) + return DFB_OK; + } + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ) +{ + struct jpeg_decompress_struct cinfo; + struct my_error_mgr jerr; + + IDirectFBDataBuffer *buffer; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_JPEG) + + va_start( tag, thiz ); + buffer = va_arg( tag, IDirectFBDataBuffer * ); + core = va_arg( tag, CoreDFB * ); + va_end( tag ); + + data->ref = 1; + data->buffer = buffer; + data->core = core; + + buffer->AddRef( buffer ); + + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = jpeglib_panic; + + if (setjmp(jerr.setjmp_buffer)) { + D_ERROR( "ImageProvider/JPEG: Error while reading headers!\n" ); + + jpeg_destroy_decompress(&cinfo); + buffer->Release( buffer ); + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return DFB_FAILURE; + } + + jpeg_create_decompress(&cinfo); + jpeg_buffer_src(&cinfo, buffer, 1); + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); + + data->width = cinfo.output_width; + data->height = cinfo.output_height; + + jpeg_abort_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + + thiz->AddRef = IDirectFBImageProvider_JPEG_AddRef; + thiz->Release = IDirectFBImageProvider_JPEG_Release; + thiz->RenderTo = IDirectFBImageProvider_JPEG_RenderTo; + thiz->SetRenderCallback = IDirectFBImageProvider_JPEG_SetRenderCallback; + thiz->GetImageDescription =IDirectFBImageProvider_JPEG_GetImageDescription; + thiz->GetSurfaceDescription = + IDirectFBImageProvider_JPEG_GetSurfaceDescription; + + return DFB_OK; +} + +static void +IDirectFBImageProvider_JPEG_Destruct( IDirectFBImageProvider *thiz ) +{ + IDirectFBImageProvider_JPEG_data *data = + (IDirectFBImageProvider_JPEG_data*)thiz->priv; + + data->buffer->Release( data->buffer ); + + if (data->image) + D_FREE( data->image ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBImageProvider_JPEG_AddRef( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBImageProvider_JPEG_Release( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) + + if (--data->ref == 0) { + IDirectFBImageProvider_JPEG_Destruct( thiz ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_JPEG_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect ) +{ + DFBResult ret; + bool direct = false; + DFBRegion clip; + DFBRectangle rect; + DFBSurfacePixelFormat format; + IDirectFBSurface_data *dst_data; + CoreSurface *dst_surface; + CoreSurfaceBufferLock lock; + DIRenderCallbackResult cb_result = DIRCR_OK; + + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) + + dst_data = (IDirectFBSurface_data*) destination->priv; + if (!dst_data) + return DFB_DEAD; + + dst_surface = dst_data->surface; + if (!dst_surface) + return DFB_DESTROYED; + + ret = destination->GetPixelFormat( destination, &format ); + if (ret) + return ret; + + dfb_region_from_rectangle( &clip, &dst_data->area.current ); + + if (dest_rect) { + if (dest_rect->w < 1 || dest_rect->h < 1) + return DFB_INVARG; + + rect = *dest_rect; + rect.x += dst_data->area.wanted.x; + rect.y += dst_data->area.wanted.y; + + if (!dfb_rectangle_region_intersects( &rect, &clip )) + return DFB_OK; + } + else { + rect = dst_data->area.wanted; + } + + ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); + if (ret) + return ret; + + /* actual loading and rendering */ + if (!data->image) { + struct jpeg_decompress_struct cinfo; + struct my_error_mgr jerr; + JSAMPARRAY buffer; /* Output row buffer */ + int row_stride; /* physical row width in output buffer */ + u32 *row_ptr; + int y = 0; + int uv_offset = 0; + + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = jpeglib_panic; + + if (setjmp(jerr.setjmp_buffer)) { + D_ERROR( "ImageProvider/JPEG: Error during decoding!\n" ); + + jpeg_destroy_decompress(&cinfo); + + if (data->image) { + dfb_scale_linear_32( data->image, data->width, data->height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + dfb_surface_unlock_buffer( dst_surface, &lock ); + if (data->render_callback) { + DFBRectangle r = { 0, 0, data->width, data->height }; + + if (data->render_callback( &r, data->render_callback_context ) != DIRCR_OK) + return DFB_INTERRUPTED; + } + + return DFB_INCOMPLETE; + } + else + dfb_surface_unlock_buffer( dst_surface, &lock ); + + return DFB_FAILURE; + } + + jpeg_create_decompress(&cinfo); + jpeg_buffer_src(&cinfo, data->buffer, 0); + jpeg_read_header(&cinfo, TRUE); + jpeg_calc_output_dimensions(&cinfo); + + if (cinfo.output_width == rect.w && cinfo.output_height == rect.h) + direct = true; + + cinfo.output_components = 3; + + switch (dst_surface->config.format) { + case DSPF_NV16: + uv_offset = dst_surface->config.size.h * lock.pitch; + + if (direct && !rect.x && !rect.y) { + D_INFO( "JPEG: Using YCbCr color space directly! (%dx%d)\n", + cinfo.output_width, cinfo.output_height ); + cinfo.out_color_space = JCS_YCbCr; + break; + } + D_INFO( "JPEG: Going through RGB color space! (%dx%d -> %dx%d @%d,%d)\n", + cinfo.output_width, cinfo.output_height, rect.w, rect.h, rect.x, rect.y ); + + default: + cinfo.out_color_space = JCS_RGB; + break; + } + + jpeg_start_decompress(&cinfo); + + data->width = cinfo.output_width; + data->height = cinfo.output_height; + + row_stride = cinfo.output_width * 3; + + buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, + JPOOL_IMAGE, row_stride, 1); + + data->image = D_CALLOC( data->height, data->width * 4 ); + if (!data->image) { + dfb_surface_unlock_buffer( dst_surface, &lock ); + return D_OOM(); + } + row_ptr = data->image; + + while (cinfo.output_scanline < cinfo.output_height && cb_result == DIRCR_OK) { + jpeg_read_scanlines(&cinfo, buffer, 1); + + switch (dst_surface->config.format) { + case DSPF_NV16: + if (direct) { + copy_line_nv16( lock.addr, lock.addr + uv_offset, *buffer, rect.w ); + + lock.addr += lock.pitch; + + if (data->render_callback) { + DFBRectangle r = { 0, y, data->width, 1 }; + + cb_result = data->render_callback( &r, + data->render_callback_context ); + } + break; + } + + default: + copy_line32( row_ptr, *buffer, data->width); + + if (direct) { + DFBRectangle r = { rect.x, rect.y+y, rect.w, 1 }; + dfb_copy_buffer_32( row_ptr, lock.addr, lock.pitch, + &r, dst_surface, &clip ); + if (data->render_callback) { + r = (DFBRectangle){ 0, y, data->width, 1 }; + cb_result = data->render_callback( &r, + data->render_callback_context ); + } + } + break; + } + + row_ptr += data->width; + y++; + } + + if (!direct) { + dfb_scale_linear_32( data->image, data->width, data->height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + if (data->render_callback) { + DFBRectangle r = { 0, 0, data->width, data->height }; + cb_result = data->render_callback( &r, data->render_callback_context ); + } + } + + if (cb_result != DIRCR_OK) { + jpeg_abort_decompress(&cinfo); + D_FREE( data->image ); + data->image = NULL; + } + else { + jpeg_finish_decompress(&cinfo); + } + jpeg_destroy_decompress(&cinfo); + } + else { + dfb_scale_linear_32( data->image, data->width, data->height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + if (data->render_callback) { + DFBRectangle r = { 0, 0, data->width, data->height }; + data->render_callback( &r, data->render_callback_context ); + } + } + + dfb_surface_unlock_buffer( dst_surface, &lock ); + + if (cb_result != DIRCR_OK) + return DFB_INTERRUPTED; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_JPEG_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_JPEG) + + data->render_callback = callback; + data->render_callback_context = context; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_JPEG_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) + + dsc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + dsc->height = data->height; + dsc->width = data->width; + dsc->pixelformat = dfb_primary_layer_pixelformat(); + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_JPEG_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_JPEG) + + if (!dsc) + return DFB_INVARG; + + dsc->caps = DICAPS_NONE; + + return DFB_OK; +} + diff --git a/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c new file mode 100755 index 0000000..3e7769d --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c @@ -0,0 +1,868 @@ +/* + (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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <png.h> +#include <string.h> +#include <stdarg.h> + +#include <directfb.h> + +#include <display/idirectfbsurface.h> + +#include <media/idirectfbimageprovider.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> + +#include <core/layers.h> +#include <core/palette.h> +#include <core/surface.h> + +#include <misc/gfx_util.h> +#include <misc/util.h> + +#include <gfx/clip.h> +#include <gfx/convert.h> + +#include <direct/interface.h> +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <direct/messages.h> +#include <direct/util.h> + +#include "config.h" + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ); + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBImageProvider, PNG ) + + +enum { + STAGE_ABORT = -2, + STAGE_ERROR = -1, + STAGE_START = 0, + STAGE_INFO, + STAGE_IMAGE, + STAGE_END +}; + +/* + * private data struct of IDirectFBImageProvider_PNG + */ +typedef struct { + int ref; /* reference counter */ + IDirectFBDataBuffer *buffer; + + int stage; + int rows; + + png_structp png_ptr; + png_infop info_ptr; + + png_uint_32 width; + png_uint_32 height; + int bpp; + int color_type; + png_uint_32 color_key; + bool color_keyed; + + void *image; + int pitch; + u32 palette[256]; + DFBColor colors[256]; + + DIRenderCallback render_callback; + void *render_callback_context; + + CoreDFB *core; +} IDirectFBImageProvider_PNG_data; + +static DirectResult +IDirectFBImageProvider_PNG_AddRef ( IDirectFBImageProvider *thiz ); + +static DirectResult +IDirectFBImageProvider_PNG_Release ( IDirectFBImageProvider *thiz ); + +static DFBResult +IDirectFBImageProvider_PNG_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *destination_rect ); + +static DFBResult +IDirectFBImageProvider_PNG_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ); + +static DFBResult +IDirectFBImageProvider_PNG_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ); + +static DFBResult +IDirectFBImageProvider_PNG_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ); + +/* Called at the start of the progressive load, once we have image info */ +static void +png_info_callback (png_structp png_read_ptr, + png_infop png_info_ptr); + +/* Called for each row; note that you will get duplicate row numbers + for interlaced PNGs */ +static void +png_row_callback (png_structp png_read_ptr, + png_bytep new_row, + png_uint_32 row_num, + int pass_num); + +/* Called after reading the entire image */ +static void +png_end_callback (png_structp png_read_ptr, + png_infop png_info_ptr); + +/* Pipes data into libpng until stage is different from the one specified. */ +static DFBResult +push_data_until_stage (IDirectFBImageProvider_PNG_data *data, + int stage, + int buffer_size); + +/**********************************************************************************************************************/ + +static DFBResult +Probe( IDirectFBImageProvider_ProbeContext *ctx ) +{ + if (png_check_sig( ctx->header, 8 )) + return DFB_OK; + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBImageProvider *thiz, + ... ) +{ + DFBResult ret = DFB_FAILURE; + + IDirectFBDataBuffer *buffer; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_PNG) + + va_start( tag, thiz ); + buffer = va_arg( tag, IDirectFBDataBuffer * ); + core = va_arg( tag, CoreDFB * ); + va_end( tag ); + + data->ref = 1; + data->buffer = buffer; + data->core = core; + + /* Increase the data buffer reference counter. */ + buffer->AddRef( buffer ); + + /* Create the PNG read handle. */ + data->png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, + NULL, NULL, NULL ); + if (!data->png_ptr) + goto error; + + if (setjmp( data->png_ptr->jmpbuf )) { + D_ERROR( "ImageProvider/PNG: Error reading header!\n" ); + goto error; + } + + /* Create the PNG info handle. */ + data->info_ptr = png_create_info_struct( data->png_ptr ); + if (!data->info_ptr) + goto error; + + /* Setup progressive image loading. */ + png_set_progressive_read_fn( data->png_ptr, data, + png_info_callback, + png_row_callback, + png_end_callback ); + + + /* Read until info callback is called. */ + ret = push_data_until_stage( data, STAGE_INFO, 64 ); + if (ret) + goto error; + + thiz->AddRef = IDirectFBImageProvider_PNG_AddRef; + thiz->Release = IDirectFBImageProvider_PNG_Release; + thiz->RenderTo = IDirectFBImageProvider_PNG_RenderTo; + thiz->SetRenderCallback = IDirectFBImageProvider_PNG_SetRenderCallback; + thiz->GetImageDescription = IDirectFBImageProvider_PNG_GetImageDescription; + thiz->GetSurfaceDescription = IDirectFBImageProvider_PNG_GetSurfaceDescription; + + return DFB_OK; + +error: + if (data->png_ptr) + png_destroy_read_struct( &data->png_ptr, &data->info_ptr, NULL ); + + buffer->Release( buffer ); + + if (data->image) + D_FREE( data->image ); + + DIRECT_DEALLOCATE_INTERFACE(thiz); + + return ret; +} + +/**********************************************************************************************************************/ + +static void +IDirectFBImageProvider_PNG_Destruct( IDirectFBImageProvider *thiz ) +{ + IDirectFBImageProvider_PNG_data *data = + (IDirectFBImageProvider_PNG_data*)thiz->priv; + + png_destroy_read_struct( &data->png_ptr, &data->info_ptr, NULL ); + + /* Decrease the data buffer reference counter. */ + data->buffer->Release( data->buffer ); + + /* Deallocate image data. */ + if (data->image) + D_FREE( data->image ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBImageProvider_PNG_AddRef( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBImageProvider_PNG_Release( IDirectFBImageProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG) + + if (--data->ref == 0) { + IDirectFBImageProvider_PNG_Destruct( thiz ); + } + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +static DFBResult +IDirectFBImageProvider_PNG_RenderTo( IDirectFBImageProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect ) +{ + DFBResult ret = DFB_OK; + IDirectFBSurface_data *dst_data; + CoreSurface *dst_surface; + DFBRegion clip; + DFBRectangle rect; + png_infop info; + int x, y; + DFBRectangle clipped; + + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG) + + info = data->info_ptr; + + dst_data = (IDirectFBSurface_data*) destination->priv; + if (!dst_data) + return DFB_DEAD; + + dst_surface = dst_data->surface; + if (!dst_surface) + return DFB_DESTROYED; + + dfb_region_from_rectangle( &clip, &dst_data->area.current ); + + if (dest_rect) { + if (dest_rect->w < 1 || dest_rect->h < 1) + return DFB_INVARG; + rect = *dest_rect; + rect.x += dst_data->area.wanted.x; + rect.y += dst_data->area.wanted.y; + } + else { + rect = dst_data->area.wanted; + } + + if (setjmp( data->png_ptr->jmpbuf )) { + D_ERROR( "ImageProvider/PNG: Error during decoding!\n" ); + + if (data->stage < STAGE_IMAGE) + return DFB_FAILURE; + + data->stage = STAGE_ERROR; + } + + /* Read until image is completely decoded. */ + if (data->stage != STAGE_ERROR) { + ret = push_data_until_stage( data, STAGE_END, 16384 ); + if (ret) + return ret; + } + + clipped = rect; + + if (!dfb_rectangle_intersect_by_region( &clipped, &clip )) + return DFB_INVAREA; + + /* actual rendering */ + if (rect.w == data->width && rect.h == data->height && + (data->color_type == PNG_COLOR_TYPE_RGB || data->color_type == PNG_COLOR_TYPE_RGBA) && + (dst_surface->config.format == DSPF_RGB32 || dst_surface->config.format == DSPF_ARGB)) + { + ret = dfb_surface_write_buffer( dst_surface, CSBR_BACK, + data->image + + (clipped.x - rect.x) * 4 + + (clipped.y - rect.y) * data->width * 4, + data->width * 4, &clipped ); + } + else { + CoreSurfaceBufferLock lock; + + ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); + if (ret) + return ret; + + switch (data->color_type) { + case PNG_COLOR_TYPE_PALETTE: + if (dst_surface->config.format == DSPF_LUT8 && data->info_ptr->bit_depth == 8) { + /* + * Special indexed PNG to LUT8 loading. + */ + + /* FIXME: Limitation for LUT8 is to load complete surface only. */ + dfb_clip_rectangle( &clip, &rect ); + if (rect.x == 0 && rect.y == 0 && + rect.w == dst_surface->config.size.w && + rect.h == dst_surface->config.size.h && + rect.w == data->width && + rect.h == data->height) + { + for (y=0; y<data->height; y++) + direct_memcpy( lock.addr + lock.pitch * y, + data->image + data->pitch * y, + data->width ); + + break; + } + } + /* fall through */ + + case PNG_COLOR_TYPE_GRAY: { + /* + * Convert to ARGB and use generic loading code. + */ + + // FIXME: allocates four additional bytes because the scaling functions + // in src/misc/gfx_util.c have an off-by-one bug which causes + // segfaults on darwin/osx (not on linux) + int size = data->width * data->height * 4 + 4; + + /* allocate image data */ + void *image_argb = D_MALLOC( size ); + + if (!image_argb) { + D_ERROR( "DirectFB/ImageProvider_PNG: Could not " + "allocate %d bytes of system memory!\n", size ); + ret = DFB_NOSYSTEMMEMORY; + } + else { + if (data->color_type == PNG_COLOR_TYPE_GRAY) { + int num = 1 << data->info_ptr->bit_depth; + + for (x=0; x<num; x++) { + int value = x * 255 / (num - 1); + + data->palette[x] = 0xff000000 | (value << 16) | (value << 8) | value; + } + } + + switch (data->info_ptr->bit_depth) { + case 8: + for (y=0; y<data->height; y++) { + u8 *S = data->image + data->pitch * y; + u32 *D = image_argb + data->width * y * 4; + + for (x=0; x<data->width; x++) + D[x] = data->palette[ S[x] ]; + } + break; + + case 4: + for (y=0; y<data->height; y++) { + u8 *S = data->image + data->pitch * y; + u32 *D = image_argb + data->width * y * 4; + + for (x=0; x<data->width; x++) { + if (x & 1) + D[x] = data->palette[ S[x>>1] & 0xf ]; + else + D[x] = data->palette[ S[x>>1] >> 4 ]; + } + } + break; + + case 2: + for (y=0; y<data->height; y++) { + int n = 6; + u8 *S = data->image + data->pitch * y; + u32 *D = image_argb + data->width * y * 4; + + for (x=0; x<data->width; x++) { + D[x] = data->palette[ (S[x>>2] >> n) & 3 ]; + + n = (n ? n - 2 : 6); + } + } + break; + + case 1: + for (y=0; y<data->height; y++) { + int n = 7; + u8 *S = data->image + data->pitch * y; + u32 *D = image_argb + data->width * y * 4; + + for (x=0; x<data->width; x++) { + D[x] = data->palette[ (S[x>>3] >> n) & 1 ]; + + n = (n ? n - 1 : 7); + } + } + break; + + default: + D_ERROR( "ImageProvider/PNG: Unsupported indexed bit depth %d!\n", + data->info_ptr->bit_depth ); + } + + dfb_scale_linear_32( image_argb, data->width, data->height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + + D_FREE( image_argb ); + } + break; + } + default: + /* + * Generic loading code. + */ + dfb_scale_linear_32( data->image, data->width, data->height, + lock.addr, lock.pitch, &rect, dst_surface, &clip ); + break; + } + + dfb_surface_unlock_buffer( dst_surface, &lock ); + } + + if (data->stage != STAGE_END) + ret = DFB_INCOMPLETE; + + return ret; +} + +static DFBResult +IDirectFBImageProvider_PNG_SetRenderCallback( IDirectFBImageProvider *thiz, + DIRenderCallback callback, + void *context ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG) + + data->render_callback = callback; + data->render_callback_context = context; + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_PNG_GetSurfaceDescription( IDirectFBImageProvider *thiz, + DFBSurfaceDescription *dsc ) +{ + DFBSurfacePixelFormat primary_format = dfb_primary_layer_pixelformat(); + + DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_PNG) + + dsc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + dsc->width = data->width; + dsc->height = data->height; + + if (data->color_type & PNG_COLOR_MASK_ALPHA) + dsc->pixelformat = DFB_PIXELFORMAT_HAS_ALPHA(primary_format) ? primary_format : DSPF_ARGB; + else + dsc->pixelformat = primary_format; + + if (data->color_type == PNG_COLOR_TYPE_PALETTE) { + dsc->flags |= DSDESC_PALETTE; + + dsc->palette.entries = data->colors; /* FIXME */ + dsc->palette.size = 256; + } + + return DFB_OK; +} + +static DFBResult +IDirectFBImageProvider_PNG_GetImageDescription( IDirectFBImageProvider *thiz, + DFBImageDescription *dsc ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_PNG) + + if (!dsc) + return DFB_INVARG; + + dsc->caps = DICAPS_NONE; + + if (data->color_type & PNG_COLOR_MASK_ALPHA) + dsc->caps |= DICAPS_ALPHACHANNEL; + + if (data->color_keyed) { + dsc->caps |= DICAPS_COLORKEY; + + dsc->colorkey_r = (data->color_key & 0xff0000) >> 16; + dsc->colorkey_g = (data->color_key & 0x00ff00) >> 8; + dsc->colorkey_b = (data->color_key & 0x0000ff); + } + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +#define MAXCOLORMAPSIZE 256 + +static int SortColors (const void *a, const void *b) +{ + return (*((const u8 *) a) - *((const u8 *) b)); +} + +/* looks for a color that is not in the colormap and ideally not + even close to the colors used in the colormap */ +static u32 FindColorKey( int n_colors, u8 *cmap ) +{ + u32 color = 0xFF000000; + u8 csort[n_colors]; + int i, j, index, d; + + if (n_colors < 1) + return color; + + for (i = 0; i < 3; i++) { + direct_memcpy( csort, cmap + (n_colors * i), n_colors ); + qsort( csort, n_colors, 1, SortColors ); + + for (j = 1, index = 0, d = 0; j < n_colors; j++) { + if (csort[j] - csort[j-1] > d) { + d = csort[j] - csort[j-1]; + index = j; + } + } + if ((csort[0] - 0x0) > d) { + d = csort[0] - 0x0; + index = n_colors; + } + if (0xFF - (csort[n_colors - 1]) > d) { + index = n_colors + 1; + } + + if (index < n_colors) + csort[0] = csort[index] - (d/2); + else if (index == n_colors) + csort[0] = 0x0; + else + csort[0] = 0xFF; + + color |= (csort[0] << (8 * (2 - i))); + } + + return color; +} + +/* Called at the start of the progressive load, once we have image info */ +static void +png_info_callback( png_structp png_read_ptr, + png_infop png_info_ptr ) +{ + int i; + IDirectFBImageProvider_PNG_data *data; + + data = png_get_progressive_ptr( png_read_ptr ); + + /* error stage? */ + if (data->stage < 0) + return; + + /* set info stage */ + data->stage = STAGE_INFO; + + png_get_IHDR( data->png_ptr, data->info_ptr, + &data->width, &data->height, &data->bpp, &data->color_type, + NULL, NULL, NULL ); + + if (png_get_valid( data->png_ptr, data->info_ptr, PNG_INFO_tRNS )) { + data->color_keyed = true; + + /* generate color key based on palette... */ + if (data->color_type == PNG_COLOR_TYPE_PALETTE) { + u32 key; + png_colorp palette = data->info_ptr->palette; + png_bytep trans = data->info_ptr->trans; + int num_colors = MIN( MAXCOLORMAPSIZE, + data->info_ptr->num_palette ); + u8 cmap[3][num_colors]; + + for (i=0; i<num_colors; i++) { + cmap[0][i] = palette[i].red; + cmap[1][i] = palette[i].green; + cmap[2][i] = palette[i].blue; + } + + key = FindColorKey( num_colors, &cmap[0][0] ); + + for (i=0; i<data->info_ptr->num_trans; i++) { + if (!trans[i]) { + palette[i].red = (key & 0xff0000) >> 16; + palette[i].green = (key & 0x00ff00) >> 8; + palette[i].blue = (key & 0x0000ff); + } + } + + data->color_key = key; + } + else { + /* ...or based on trans rgb value */ + png_color_16p trans = &data->info_ptr->trans_values; + + data->color_key = (((trans->red & 0xff00) << 8) | + ((trans->green & 0xff00)) | + ((trans->blue & 0xff00) >> 8)); + } + } + + switch (data->color_type) { + case PNG_COLOR_TYPE_PALETTE: { + png_colorp palette = data->info_ptr->palette; + png_bytep trans = data->info_ptr->trans; + int num_trans = data->info_ptr->num_trans; + int num_colors = MIN( MAXCOLORMAPSIZE, data->info_ptr->num_palette ); + + for (i=0; i<num_colors; i++) { + data->colors[i].a = (i < num_trans) ? trans[i] : 0xff; + data->colors[i].r = palette[i].red; + data->colors[i].g = palette[i].green; + data->colors[i].b = palette[i].blue; + + data->palette[i] = PIXEL_ARGB( data->colors[i].a, + data->colors[i].r, + data->colors[i].g, + data->colors[i].b ); + } + + data->pitch = (data->width + 7) & ~7; + break; + } + + case PNG_COLOR_TYPE_GRAY: + data->pitch = data->width; + + if (data->bpp == 16) + png_set_strip_16( data->png_ptr ); + + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + png_set_gray_to_rgb( data->png_ptr ); + /* fall through */ + + default: + data->pitch = data->width * 4; + + if (data->bpp == 16) + png_set_strip_16( data->png_ptr ); + +#ifdef WORDS_BIGENDIAN + if (!(data->color_type & PNG_COLOR_MASK_ALPHA)) + png_set_filler( data->png_ptr, 0xFF, PNG_FILLER_BEFORE ); + + png_set_swap_alpha( data->png_ptr ); +#else + if (!(data->color_type & PNG_COLOR_MASK_ALPHA)) + png_set_filler( data->png_ptr, 0xFF, PNG_FILLER_AFTER ); + + png_set_bgr( data->png_ptr ); +#endif + break; + } + + png_set_interlace_handling( data->png_ptr ); + + /* Update the info to reflect our transformations */ + png_read_update_info( data->png_ptr, data->info_ptr ); +} + +/* Called for each row; note that you will get duplicate row numbers + for interlaced PNGs */ +static void +png_row_callback( png_structp png_read_ptr, + png_bytep new_row, + png_uint_32 row_num, + int pass_num ) +{ + IDirectFBImageProvider_PNG_data *data; + + data = png_get_progressive_ptr( png_read_ptr ); + + /* error stage? */ + if (data->stage < 0) + return; + + /* set image decoding stage */ + data->stage = STAGE_IMAGE; + + /* check image data pointer */ + if (!data->image) { + // FIXME: allocates four additional bytes because the scaling functions + // in src/misc/gfx_util.c have an off-by-one bug which causes + // segfaults on darwin/osx (not on linux) + int size = data->pitch * data->height + 4; + + /* allocate image data */ + data->image = D_CALLOC( 1, size ); + if (!data->image) { + D_ERROR("DirectFB/ImageProvider_PNG: Could not " + "allocate %d bytes of system memory!\n", size); + + /* set error stage */ + data->stage = STAGE_ERROR; + + return; + } + } + + /* write to image data */ + png_progressive_combine_row( data->png_ptr, (png_bytep) (data->image + + row_num * data->pitch), new_row ); + + /* increase row counter, FIXME: interlaced? */ + data->rows++; + + if (data->render_callback) { + DIRenderCallbackResult r; + DFBRectangle rect = { 0, row_num, data->width, 1 }; + + r = data->render_callback( &rect, data->render_callback_context ); + if (r != DIRCR_OK) + data->stage = STAGE_ABORT; + } +} + +/* Called after reading the entire image */ +static void +png_end_callback (png_structp png_read_ptr, + png_infop png_info_ptr) +{ + IDirectFBImageProvider_PNG_data *data; + + data = png_get_progressive_ptr( png_read_ptr ); + + /* error stage? */ + if (data->stage < 0) + return; + + /* set end stage */ + data->stage = STAGE_END; +} + +/* Pipes data into libpng until stage is different from the one specified. */ +static DFBResult +push_data_until_stage (IDirectFBImageProvider_PNG_data *data, + int stage, + int buffer_size) +{ + DFBResult ret; + IDirectFBDataBuffer *buffer = data->buffer; + + while (data->stage < stage) { + unsigned int len; + unsigned char buf[buffer_size]; + + if (data->stage < 0) + return DFB_FAILURE; + + while (buffer->HasData( buffer ) == DFB_OK) { + D_DEBUG( "ImageProvider/PNG: Retrieving data (up to %d bytes)...\n", buffer_size ); + + ret = buffer->GetData( buffer, buffer_size, buf, &len ); + if (ret) + return ret; + + D_DEBUG( "ImageProvider/PNG: Got %d bytes...\n", len ); + + png_process_data( data->png_ptr, data->info_ptr, buf, len ); + + D_DEBUG( "ImageProvider/PNG: ...processed %d bytes.\n", len ); + + /* are we there yet? */ + if (data->stage < 0 || data->stage >= stage) { + switch (data->stage) { + case STAGE_ABORT: return DFB_INTERRUPTED; + case STAGE_ERROR: return DFB_FAILURE; + default: return DFB_OK; + } + } + } + + D_DEBUG( "ImageProvider/PNG: Waiting for data...\n" ); + + if (buffer->WaitForData( buffer, 1 ) == DFB_EOF) + return DFB_FAILURE; + } + + return DFB_OK; +} diff --git a/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.am b/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.am new file mode 100755 index 0000000..affe5ef --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.am @@ -0,0 +1,57 @@ +## Makefile.am for DirectFB/interfaces/IDirectFBVideoProvider + +idirectfbvideoproviderdir = $(MODULEDIR)/interfaces/IDirectFBVideoProvider + +EXTRA_DIST = videodev.h videodev2.h + +if V4L_PROVIDER +V4L_PROVIDER_LTLIB = libidirectfbvideoprovider_v4l.la +else +V4L_PROVIDER_LTLIB = +endif + +if GIF_PROVIDER +GIF_PROVIDER_LTLIB = libidirectfbvideoprovider_gif.la +else +GIF_PROVIDER_LTLIB = +endif + +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src \ + -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" + + +idirectfbvideoprovider_LTLIBRARIES = \ + $(GIF_PROVIDER_LTLIB) \ + $(V4L_PROVIDER_LTLIB) + +if BUILD_STATIC +idirectfbvideoprovider_DATA = $(idirectfbvideoprovider_LTLIBRARIES:.la=.o) +endif + + +libidirectfbvideoprovider_v4l_la_SOURCES = idirectfbvideoprovider_v4l.c + +libidirectfbvideoprovider_v4l_la_LDFLAGS = -avoid-version -module + +libidirectfbvideoprovider_v4l_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la + + +libidirectfbvideoprovider_gif_la_SOURCES = idirectfbvideoprovider_gif.c + +libidirectfbvideoprovider_gif_la_LDFLAGS = -avoid-version -module + +libidirectfbvideoprovider_gif_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la + + +include $(top_srcdir)/rules/libobject.make diff --git a/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.in b/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.in new file mode 100755 index 0000000..33f8f5e --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/Makefile.in @@ -0,0 +1,635 @@ +# 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 = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/rules/libobject.make +subdir = interfaces/IDirectFBVideoProvider +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 = +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)$(idirectfbvideoproviderdir)" \ + "$(DESTDIR)$(idirectfbvideoproviderdir)" +idirectfbvideoproviderLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(idirectfbvideoprovider_LTLIBRARIES) +libidirectfbvideoprovider_gif_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la +am_libidirectfbvideoprovider_gif_la_OBJECTS = \ + idirectfbvideoprovider_gif.lo +libidirectfbvideoprovider_gif_la_OBJECTS = \ + $(am_libidirectfbvideoprovider_gif_la_OBJECTS) +libidirectfbvideoprovider_gif_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbvideoprovider_gif_la_LDFLAGS) $(LDFLAGS) -o $@ +@GIF_PROVIDER_TRUE@am_libidirectfbvideoprovider_gif_la_rpath = -rpath \ +@GIF_PROVIDER_TRUE@ $(idirectfbvideoproviderdir) +libidirectfbvideoprovider_v4l_la_DEPENDENCIES = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la +am_libidirectfbvideoprovider_v4l_la_OBJECTS = \ + idirectfbvideoprovider_v4l.lo +libidirectfbvideoprovider_v4l_la_OBJECTS = \ + $(am_libidirectfbvideoprovider_v4l_la_OBJECTS) +libidirectfbvideoprovider_v4l_la_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libidirectfbvideoprovider_v4l_la_LDFLAGS) $(LDFLAGS) -o $@ +@V4L_PROVIDER_TRUE@am_libidirectfbvideoprovider_v4l_la_rpath = -rpath \ +@V4L_PROVIDER_TRUE@ $(idirectfbvideoproviderdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libidirectfbvideoprovider_gif_la_SOURCES) \ + $(libidirectfbvideoprovider_v4l_la_SOURCES) +DIST_SOURCES = $(libidirectfbvideoprovider_gif_la_SOURCES) \ + $(libidirectfbvideoprovider_v4l_la_SOURCES) +idirectfbvideoproviderDATA_INSTALL = $(INSTALL_DATA) +DATA = $(idirectfbvideoprovider_DATA) +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@ +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@ +idirectfbvideoproviderdir = $(MODULEDIR)/interfaces/IDirectFBVideoProvider +EXTRA_DIST = videodev.h videodev2.h +@V4L_PROVIDER_FALSE@V4L_PROVIDER_LTLIB = +@V4L_PROVIDER_TRUE@V4L_PROVIDER_LTLIB = libidirectfbvideoprovider_v4l.la +@GIF_PROVIDER_FALSE@GIF_PROVIDER_LTLIB = +@GIF_PROVIDER_TRUE@GIF_PROVIDER_LTLIB = libidirectfbvideoprovider_gif.la +INCLUDES = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/src \ + -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" + +idirectfbvideoprovider_LTLIBRARIES = \ + $(GIF_PROVIDER_LTLIB) \ + $(V4L_PROVIDER_LTLIB) + +@BUILD_STATIC_TRUE@idirectfbvideoprovider_DATA = $(idirectfbvideoprovider_LTLIBRARIES:.la=.o) +libidirectfbvideoprovider_v4l_la_SOURCES = idirectfbvideoprovider_v4l.c +libidirectfbvideoprovider_v4l_la_LDFLAGS = -avoid-version -module +libidirectfbvideoprovider_v4l_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la + +libidirectfbvideoprovider_gif_la_SOURCES = idirectfbvideoprovider_gif.c +libidirectfbvideoprovider_gif_la_LDFLAGS = -avoid-version -module +libidirectfbvideoprovider_gif_la_LIBADD = \ + $(top_builddir)/lib/direct/libdirect.la \ + $(top_builddir)/lib/fusion/libfusion.la \ + $(top_builddir)/src/libdirectfb.la + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/rules/libobject.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 interfaces/IDirectFBVideoProvider/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu interfaces/IDirectFBVideoProvider/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 +install-idirectfbvideoproviderLTLIBRARIES: $(idirectfbvideoprovider_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(idirectfbvideoproviderdir)" || $(MKDIR_P) "$(DESTDIR)$(idirectfbvideoproviderdir)" + @list='$(idirectfbvideoprovider_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(idirectfbvideoproviderLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(idirectfbvideoproviderdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(idirectfbvideoproviderLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(idirectfbvideoproviderdir)/$$f"; \ + else :; fi; \ + done + +uninstall-idirectfbvideoproviderLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(idirectfbvideoprovider_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(idirectfbvideoproviderdir)/$$p'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(idirectfbvideoproviderdir)/$$p"; \ + done + +clean-idirectfbvideoproviderLTLIBRARIES: + -test -z "$(idirectfbvideoprovider_LTLIBRARIES)" || rm -f $(idirectfbvideoprovider_LTLIBRARIES) + @list='$(idirectfbvideoprovider_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 +libidirectfbvideoprovider_gif.la: $(libidirectfbvideoprovider_gif_la_OBJECTS) $(libidirectfbvideoprovider_gif_la_DEPENDENCIES) + $(libidirectfbvideoprovider_gif_la_LINK) $(am_libidirectfbvideoprovider_gif_la_rpath) $(libidirectfbvideoprovider_gif_la_OBJECTS) $(libidirectfbvideoprovider_gif_la_LIBADD) $(LIBS) +libidirectfbvideoprovider_v4l.la: $(libidirectfbvideoprovider_v4l_la_OBJECTS) $(libidirectfbvideoprovider_v4l_la_DEPENDENCIES) + $(libidirectfbvideoprovider_v4l_la_LINK) $(am_libidirectfbvideoprovider_v4l_la_rpath) $(libidirectfbvideoprovider_v4l_la_OBJECTS) $(libidirectfbvideoprovider_v4l_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbvideoprovider_gif.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbvideoprovider_v4l.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-idirectfbvideoproviderDATA: $(idirectfbvideoprovider_DATA) + @$(NORMAL_INSTALL) + test -z "$(idirectfbvideoproviderdir)" || $(MKDIR_P) "$(DESTDIR)$(idirectfbvideoproviderdir)" + @list='$(idirectfbvideoprovider_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(idirectfbvideoproviderDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(idirectfbvideoproviderdir)/$$f'"; \ + $(idirectfbvideoproviderDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(idirectfbvideoproviderdir)/$$f"; \ + done + +uninstall-idirectfbvideoproviderDATA: + @$(NORMAL_UNINSTALL) + @list='$(idirectfbvideoprovider_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(idirectfbvideoproviderdir)/$$f'"; \ + rm -f "$(DESTDIR)$(idirectfbvideoproviderdir)/$$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) +installdirs: + for dir in "$(DESTDIR)$(idirectfbvideoproviderdir)" "$(DESTDIR)$(idirectfbvideoproviderdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-idirectfbvideoproviderLTLIBRARIES \ + clean-libtool 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-idirectfbvideoproviderDATA \ + install-idirectfbvideoproviderLTLIBRARIES + +install-dvi: install-dvi-am + +install-exec-am: + +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-idirectfbvideoproviderDATA \ + uninstall-idirectfbvideoproviderLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-idirectfbvideoproviderLTLIBRARIES clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am \ + install-idirectfbvideoproviderDATA \ + install-idirectfbvideoproviderLTLIBRARIES install-info \ + install-info-am install-man install-pdf install-pdf-am \ + 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-idirectfbvideoproviderDATA \ + uninstall-idirectfbvideoproviderLTLIBRARIES + +%.o: .libs/%.a %.la + rm -f $<.tmp/*.o + if test -d $<.tmp; then rmdir $<.tmp; fi + mkdir $<.tmp + (cd $<.tmp && $(AR) x ../../$<) + $(LD) -o $@ -r $<.tmp/*.o + rm -f $<.tmp/*.o && rmdir $<.tmp + +.PHONY: $(LTLIBRARIES:%.la=.libs/%.a) +# 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/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_gif.c b/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_gif.c new file mode 100755 index 0000000..65f3fbb --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_gif.c @@ -0,0 +1,1075 @@ +/* + (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 <unistd.h> +#include <sys/time.h> + +#include <pthread.h> + +#include <directfb.h> + +#include <direct/types.h> +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <direct/messages.h> +#include <direct/thread.h> +#include <direct/util.h> + +#include <idirectfb.h> + +#include <core/surface.h> + +#include <display/idirectfbsurface.h> + +#include <media/idirectfbdatabuffer.h> +#include <media/idirectfbvideoprovider.h> + +#include <misc/gfx_util.h> + + +static DFBResult Probe( IDirectFBVideoProvider_ProbeContext *ctx ); + +static DFBResult Construct( IDirectFBVideoProvider *thiz, + IDirectFBDataBuffer *buffer ); + + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBVideoProvider, Gif ) + +/*****************************************************************************/ + +#define MAXCOLORMAPSIZE 256 + +#define CM_RED 0 +#define CM_GREEN 1 +#define CM_BLUE 2 + +#define MAX_LWZ_BITS 12 + +#define INTERLACE 0x40 +#define LOCALCOLORMAP 0x80 + +#define BitSet(byte, bit) (((byte) & (bit)) == (bit)) + +#define LM_to_uint(a,b) (((b)<<8)|(a)) + +typedef struct { + int ref; /* reference counter */ + + IDirectFBDataBuffer *buffer; + DFBBoolean seekable; + + IDirectFBSurface *destination; + IDirectFBSurface_data *dst_data; + DFBRectangle dst_rect; + + u32 *image; + + DirectThread *thread; + pthread_mutex_t lock; + pthread_cond_t cond; + + DFBVideoProviderStatus status; + DFBVideoProviderPlaybackFlags flags; + double speed; + + unsigned int start_pos; + + char Version[4]; + unsigned int Width; + unsigned int Height; + u8 ColorMap[3][MAXCOLORMAPSIZE]; + unsigned int BitPixel; + unsigned int ColorResolution; + u32 Background; + unsigned int AspectRatio; + + int transparent; + unsigned int delayTime; + int inputFlag; + int disposal; + + u8 buf[280]; + int curbit, lastbit, done, last_byte; + + int fresh; + int code_size, set_code_size; + int max_code, max_code_size; + int firstcode, oldcode; + int clear_code, end_code; + int table[2][(1<< MAX_LWZ_BITS)]; + int stack[(1<<(MAX_LWZ_BITS))*2], *sp; + + DVFrameCallback callback; + void *callback_ctx; +} IDirectFBVideoProvider_GIF_data; + +#define GIFERRORMSG(x, ...) \ + D_ERROR( "IDirectFBVideoProvider_GIF: " #x "!\n", ## __VA_ARGS__ ) + +#define GIFDEBUGMSG(x, ...) \ + D_DEBUG( "IDirectFBVideoProvider_GIF: " #x "!\n", ## __VA_ARGS__ ) + +/*****************************************************************************/ + +static int ZeroDataBlock = 0; + +static DFBResult +FetchData( IDirectFBDataBuffer *buffer, void *data, unsigned int len ) +{ + DFBResult ret = DFB_OK; + + do { + unsigned int read = 0; + + ret = buffer->WaitForData( buffer, len ); + if (ret == DFB_OK) + ret = buffer->GetData( buffer, len, data, &read ); + if (ret) + break; + + data += read; + len -= read; + } while (len); + + return ret; +} + +static int ReadColorMap( IDirectFBDataBuffer *buffer, int number, + u8 buf[3][MAXCOLORMAPSIZE] ) +{ + int i; + u8 rgb[3*number]; + + if (FetchData( buffer, rgb, sizeof(rgb) )) { + GIFERRORMSG("bad colormap"); + return -1; + } + + for (i = 0; i < number; ++i) { + buf[CM_RED][i] = rgb[i*3+0]; + buf[CM_GREEN][i] = rgb[i*3+1]; + buf[CM_BLUE][i] = rgb[i*3+2]; + } + + return 0; +} + +static int GetDataBlock(IDirectFBDataBuffer *buffer, u8 *buf) +{ + unsigned char count; + + if (FetchData( buffer, &count, 1 )) { + GIFERRORMSG("error in getting DataBlock size"); + return -1; + } + ZeroDataBlock = (count == 0); + + if ((count != 0) && FetchData( buffer, buf, count )) { + GIFERRORMSG("error in reading DataBlock"); + return -1; + } + + return count; +} + +static int GetCode(IDirectFBVideoProvider_GIF_data *data, int code_size, int flag) +{ + int i, j, ret; + unsigned char count; + + if (flag) { + data->curbit = 0; + data->lastbit = 0; + data->done = false; + return 0; + } + + if ( (data->curbit+code_size) >= data->lastbit) { + if (data->done) { + if (data->curbit >= data->lastbit) { + GIFERRORMSG("ran off the end of my bits"); + } + return -1; + } + data->buf[0] = data->buf[data->last_byte-2]; + data->buf[1] = data->buf[data->last_byte-1]; + + if ((count = GetDataBlock( data->buffer, &data->buf[2] )) == 0) { + data->done = true; + } + + data->last_byte = 2 + count; + data->curbit = (data->curbit - data->lastbit) + 16; + data->lastbit = (2+count) * 8; + } + + ret = 0; + for (i = data->curbit, j = 0; j < code_size; ++i, ++j) { + ret |= ((data->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; + } + data->curbit += code_size; + + return ret; +} + +static int DoExtension( IDirectFBVideoProvider_GIF_data *data, int label ) +{ + unsigned char buf[256] = { 0 }; + char *str; + + switch (label) { + case 0x01: /* Plain Text Extension */ + str = "Plain Text Extension"; + break; + case 0xff: /* Application Extension */ + str = "Application Extension"; + break; + case 0xfe: /* Comment Extension */ + str = "Comment Extension"; + while (GetDataBlock( data->buffer, (u8*) buf ) != 0) + GIFDEBUGMSG("gif comment: %s", buf); + return false; + case 0xf9: /* Graphic Control Extension */ + str = "Graphic Control Extension"; + (void) GetDataBlock( data->buffer, (u8*) buf ); + data->disposal = (buf[0] >> 2) & 0x7; + data->inputFlag = (buf[0] >> 1) & 0x1; + if (LM_to_uint( buf[1], buf[2] )) + data->delayTime = LM_to_uint( buf[1], buf[2] ) * 10000; + if ((buf[0] & 0x1) != 0) + data->transparent = buf[3]; + else + data->transparent = -1; + while (GetDataBlock( data->buffer, (u8*) buf ) != 0) + ; + return false; + default: + str = (char*) buf; + snprintf(str, 256, "UNKNOWN (0x%02x)", label); + break; + } + + GIFDEBUGMSG("got a '%s' extension", str ); + + while (GetDataBlock( data->buffer, (u8*) buf ) != 0); + + return 0; +} + +static int LWZReadByte( IDirectFBVideoProvider_GIF_data *data, int flag, int input_code_size ) +{ + int code, incode; + int i; + + if (flag) { + data->set_code_size = input_code_size; + data->code_size = data->set_code_size+1; + data->clear_code = 1 << data->set_code_size ; + data->end_code = data->clear_code + 1; + data->max_code_size = 2*data->clear_code; + data->max_code = data->clear_code+2; + + GetCode(data, 0, true); + + data->fresh = true; + + for (i = 0; i < data->clear_code; ++i) { + data->table[0][i] = 0; + data->table[1][i] = i; + } + for (; i < (1<<MAX_LWZ_BITS); ++i) { + data->table[0][i] = data->table[1][0] = 0; + } + data->sp = data->stack; + + return 0; + } + else if (data->fresh) { + data->fresh = false; + do { + data->firstcode = data->oldcode = GetCode( data, data->code_size, false ); + } while (data->firstcode == data->clear_code); + + return data->firstcode; + } + + if (data->sp > data->stack) { + return *--data->sp; + } + + while ((code = GetCode( data, data->code_size, false )) >= 0) { + if (code == data->clear_code) { + for (i = 0; i < data->clear_code; ++i) { + data->table[0][i] = 0; + data->table[1][i] = i; + } + for (; i < (1<<MAX_LWZ_BITS); ++i) { + data->table[0][i] = data->table[1][i] = 0; + } + data->code_size = data->set_code_size+1; + data->max_code_size = 2*data->clear_code; + data->max_code = data->clear_code+2; + data->sp = data->stack; + data->firstcode = data->oldcode = GetCode( data, data->code_size, false ); + + return data->firstcode; + } + else if (code == data->end_code) { + int count; + u8 buf[260]; + + if (ZeroDataBlock) { + return -2; + } + + while ((count = GetDataBlock( data->buffer, buf )) > 0) + ; + + if (count != 0) + GIFERRORMSG("missing EOD in data stream (common occurence)"); + + return -2; + } + + incode = code; + + if (code >= data->max_code) { + *data->sp++ = data->firstcode; + code = data->oldcode; + } + + while (code >= data->clear_code) { + *data->sp++ = data->table[1][code]; + if (code == data->table[0][code]) { + GIFERRORMSG("circular table entry BIG ERROR"); + } + code = data->table[0][code]; + } + + *data->sp++ = data->firstcode = data->table[1][code]; + + if ((code = data->max_code) <(1<<MAX_LWZ_BITS)) { + data->table[0][code] = data->oldcode; + data->table[1][code] = data->firstcode; + ++data->max_code; + if ((data->max_code >= data->max_code_size) + && (data->max_code_size < (1<<MAX_LWZ_BITS))) + { + data->max_code_size *= 2; + ++data->code_size; + } + } + + data->oldcode = incode; + + if (data->sp > data->stack) { + return *--data->sp; + } + } + return code; +} + +static int ReadImage( IDirectFBVideoProvider_GIF_data *data, + int left, int top, int width, int height, + u8 cmap[3][MAXCOLORMAPSIZE], bool interlace, bool ignore ) +{ + u8 c; + int v; + int xpos = 0, ypos = 0, pass = 0; + u32 *image, *dst; + + /* + ** Initialize the decompression routines + */ + if (FetchData( data->buffer, &c, 1 )) + GIFERRORMSG("EOF / read error on image data"); + + if (LWZReadByte( data, true, c ) < 0) + GIFERRORMSG("error reading image"); + + /* + ** If this is an "uninteresting picture" ignore it. + */ + if (ignore) { + GIFDEBUGMSG("skipping image..."); + + while (LWZReadByte( data, false, c ) >= 0) + ; + return 0; + } + + switch (data->disposal) { + case 2: + GIFDEBUGMSG("restoring to background color..."); + memset( data->image, 0, data->Width * data->Height * 4 ); + break; + case 3: + GIFERRORMSG("restoring to previous frame is unsupported"); + break; + default: + break; + } + + dst = image = data->image + (top * data->Width + left); + + GIFDEBUGMSG("reading %dx%d at %dx%d %sGIF image", + width, height, left, top, interlace ? " interlaced " : "" ); + + while ((v = LWZReadByte( data, false, c )) >= 0 ) { + if (v != data->transparent) { + dst[xpos] = (0xFF000000 | + cmap[CM_RED][v] << 16 | + cmap[CM_GREEN][v] << 8 | + cmap[CM_BLUE][v]); + } + + ++xpos; + if (xpos == width) { + xpos = 0; + if (interlace) { + switch (pass) { + case 0: + case 1: + ypos += 8; + break; + case 2: + ypos += 4; + break; + case 3: + ypos += 2; + break; + } + + if (ypos >= height) { + ++pass; + switch (pass) { + case 1: + ypos = 4; + break; + case 2: + ypos = 2; + break; + case 3: + ypos = 1; + break; + default: + goto fini; + } + } + } + else { + ++ypos; + } + dst = image + ypos * data->Width; + } + if (ypos >= height) { + break; + } + } + +fini: + + if (LWZReadByte( data, false, c ) >= 0) { + GIFERRORMSG("too much input data, ignoring extra..."); + //while (LWZReadByte( data, false, c ) >= 0); + } + + return 0; +} + +static void GIFReset( IDirectFBVideoProvider_GIF_data *data ) +{ + data->transparent = -1; + data->delayTime = 1000000; /* default: 1s */ + data->inputFlag = -1; + data->disposal = 0; + + if (data->image) + memset( data->image, 0, data->Width*data->Height*4 ); +} + +static DFBResult GIFReadHeader( IDirectFBVideoProvider_GIF_data *data ) +{ + DFBResult ret; + u8 buf[7]; + + ret = FetchData( data->buffer, buf, 6 ); + if (ret) { + GIFERRORMSG("error reading header"); + return ret; + } + + if (memcmp( buf, "GIF", 3 )) { + GIFERRORMSG("bad magic"); + return DFB_UNSUPPORTED; + } + + memcpy( data->Version, &buf[3], 3 ); + data->Version[3] = '\0'; + + ret = FetchData( data->buffer, buf, 7 ); + if (ret) { + GIFERRORMSG("error reading screen descriptor"); + return ret; + } + + data->Width = LM_to_uint( buf[0], buf[1] ); + data->Height = LM_to_uint( buf[2], buf[3] ); + data->BitPixel = 2 << (buf[4] & 0x07); + data->ColorResolution = (((buf[4] & 0x70) >> 3) + 1); + data->Background = buf[5]; + data->AspectRatio = buf[6]; + if (data->AspectRatio) + data->AspectRatio = ((data->AspectRatio + 15) << 8) >> 6; + else + data->AspectRatio = (data->Width << 8) / data->Height; + + if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ + if (ReadColorMap( data->buffer, data->BitPixel, data->ColorMap )) { + GIFERRORMSG("error reading global colormap"); + return DFB_FAILURE; + } + } + + return DFB_OK; +} + +static DFBResult GIFReadFrame( IDirectFBVideoProvider_GIF_data *data ) +{ + u8 buf[16], c; + int top, left; + int width, height; + u8 localColorMap[3][MAXCOLORMAPSIZE]; + bool useGlobalColormap; + + data->curbit = data->lastbit = data->done = data->last_byte = 0; + + data->fresh = + data->code_size = data->set_code_size = + data->max_code = data->max_code_size = + data->firstcode = data->oldcode = + data->clear_code = data->end_code = 0; + + for (;;) { + DFBResult ret; + + ret = FetchData( data->buffer, &c, 1); + if (ret) { + GIFERRORMSG("EOF / read error on image data" ); + return DFB_EOF; + } + + if (c == ';') /* GIF terminator */ + return DFB_EOF; + + if (c == '!') { /* Extension */ + if (FetchData( data->buffer, &c, 1)) { + GIFERRORMSG("EOF / read error on extention function code"); + return DFB_EOF; + } + DoExtension( data, c ); + continue; + } + + if (c != ',') { /* Not a valid start character */ + GIFERRORMSG("bogus character 0x%02x, ignoring", (int) c ); + continue; + } + + ret = FetchData( data->buffer, buf, 9 ); + if (ret) { + GIFERRORMSG("couldn't read left/top/width/height"); + return ret; + } + + left = LM_to_uint( buf[0], buf[1] ); + top = LM_to_uint( buf[2], buf[3] ); + width = LM_to_uint( buf[4], buf[5] ); + height = LM_to_uint( buf[6], buf[7] ); + + useGlobalColormap = !BitSet( buf[8], LOCALCOLORMAP ); + + if (!useGlobalColormap) { + int bitPixel = 2 << (buf[8] & 0x07); + if (ReadColorMap( data->buffer, bitPixel, localColorMap )) + GIFERRORMSG("error reading local colormap"); + } + + if (ReadImage( data, left, top, width, height, + (useGlobalColormap ? + data->ColorMap : localColorMap), + BitSet( buf[8], INTERLACE ), 0 )) { + GIFERRORMSG("error reading image"); + return DFB_FAILURE; + } + + break; + } + + return DFB_OK; +} + +/*****************************************************************************/ + +static void +IDirectFBVideoProvider_GIF_Destruct( IDirectFBVideoProvider *thiz ) +{ + IDirectFBVideoProvider_GIF_data *data = thiz->priv; + + thiz->Stop( thiz ); + + if (data->image) + D_FREE( data->image ); + + if (data->buffer) + data->buffer->Release( data->buffer ); + + pthread_cond_destroy( &data->cond ); + pthread_mutex_destroy( &data->lock ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBVideoProvider_GIF_AddRef( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBVideoProvider_GIF_Release( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (--data->ref == 0) + IDirectFBVideoProvider_GIF_Destruct( thiz ); + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetCapabilities( IDirectFBVideoProvider *thiz, + DFBVideoProviderCapabilities *caps ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!caps) + return DFB_INVARG; + + *caps = DVCAPS_BASIC | DVCAPS_SCALE | DVCAPS_SPEED; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetSurfaceDescription( IDirectFBVideoProvider *thiz, + DFBSurfaceDescription *desc ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!desc) + return DFB_INVARG; + + desc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + desc->width = data->Width; + desc->height = data->Height; + desc->pixelformat = DSPF_ARGB; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetStreamDescription( IDirectFBVideoProvider *thiz, + DFBStreamDescription *desc ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!desc) + return DFB_INVARG; + + desc->caps = DVSCAPS_VIDEO; + + snprintf( desc->video.encoding, + DFB_STREAM_DESC_ENCODING_LENGTH, "GIF %s", data->Version ); + desc->video.framerate = 0; + desc->video.aspect = (double)data->AspectRatio/256.0; + desc->video.bitrate = 0; + + desc->title[0] = desc->author[0] = + desc->album[0] = desc->genre[0] = desc->comment[0] = 0; + desc->year = 0; + + return DFB_OK; +} + +static void* +GIFVideo( DirectThread *self, void *arg ) +{ + IDirectFBVideoProvider_GIF_data *data = arg; + + pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, NULL ); + + while (!direct_thread_is_canceled( self )) { + DFBResult ret; + DFBRectangle rect; + DFBRegion clip; + CoreSurface *surface; + CoreSurfaceBufferLock lock; + + pthread_mutex_lock( &data->lock ); + + if (direct_thread_is_canceled( self )) { + pthread_mutex_unlock( &data->lock ); + break; + } + + ret = GIFReadFrame( data ); + if (ret) { + if (ret == DFB_EOF) { + GIFReset( data ); + if (data->flags & DVPLAY_LOOPING) { + data->buffer->SeekTo( data->buffer, data->start_pos ); + } + else { + data->status = DVSTATE_FINISHED; + pthread_mutex_unlock( &data->lock ); + break; + } + } + pthread_mutex_unlock( &data->lock ); + continue; + } + + rect = (data->dst_rect.w == 0) + ? data->dst_data->area.wanted : data->dst_rect; + dfb_region_from_rectangle( &clip, &data->dst_data->area.current ); + + surface = data->dst_data->surface; + D_MAGIC_ASSERT( surface, CoreSurface ); + + if (dfb_rectangle_region_intersects( &rect, &clip ) && + dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ) == DFB_OK) + { + dfb_scale_linear_32( data->image, data->Width, data->Height, + lock.addr, lock.pitch, &rect, data->dst_data->surface, &clip ); + + dfb_surface_unlock_buffer( surface, &lock ); + + if (data->callback) + data->callback( data->callback_ctx ); + } + + if (!data->speed) { + pthread_cond_wait( &data->cond, &data->lock ); + } + else { + struct timespec ts; + unsigned long us; + + us = data->delayTime; + if (data->speed != 1.0) + us = ((double)us / data->speed + .5); + + direct_util_get_monotonic_pthread_timeout(&ts, + us/1000000, + (us%1000000) * 1000); + + pthread_cond_timedwait( &data->cond, &data->lock, &ts ); + } + + pthread_mutex_unlock( &data->lock ); + } + + return (void*)0; +} + +static DFBResult +IDirectFBVideoProvider_GIF_PlayTo( IDirectFBVideoProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dest_rect, + DVFrameCallback callback, + void *ctx ) +{ + IDirectFBSurface_data *dst_data; + DFBRectangle rect = { 0, 0, 0, 0 }; + DFBResult ret; + + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!destination) + return DFB_INVARG; + + dst_data = destination->priv; + if (!dst_data || !dst_data->surface) + return DFB_DESTROYED; + + if (dest_rect) { + if (dest_rect->w < 1 || dest_rect->h < 1) + return DFB_INVARG; + + rect = *dest_rect; + rect.x += dst_data->area.wanted.x; + rect.y += dst_data->area.wanted.y; + } + + pthread_mutex_lock( &data->lock ); + + if (data->status == DVSTATE_FINISHED) { + ret = data->buffer->SeekTo( data->buffer, data->start_pos ); + if (ret) { + pthread_mutex_unlock( &data->lock ); + return ret; + } + } + data->status = DVSTATE_PLAY; + + if (!data->image) { + data->image = D_CALLOC( 4, data->Width * data->Height ); + if (!data->image) { + pthread_mutex_unlock( &data->lock ); + return D_OOM(); + } + } + + if (data->destination) + data->destination->Release( data->destination ); + + destination->AddRef( destination ); + data->destination = destination; + data->dst_data = dst_data; + data->dst_rect = rect; + + data->callback = callback; + data->callback_ctx = ctx; + + if (!data->thread) { + data->thread = direct_thread_create( DTT_DEFAULT, GIFVideo, + (void*)data, "GIF Video" ); + } + + pthread_mutex_unlock( &data->lock ); + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_Stop( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (data->thread) { + direct_thread_cancel( data->thread ); + pthread_mutex_lock( &data->lock ); + pthread_cond_signal( &data->cond ); + pthread_mutex_unlock( &data->lock ); + direct_thread_join( data->thread ); + direct_thread_destroy( data->thread ); + data->thread = NULL; + } + + if (data->destination) { + data->destination->Release( data->destination ); + data->destination = NULL; + data->dst_data = NULL; + } + + data->status = DVSTATE_STOP; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetStatus( IDirectFBVideoProvider *thiz, + DFBVideoProviderStatus *status ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!status) + return DFB_INVARG; + + *status = data->status; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_SeekTo( IDirectFBVideoProvider *thiz, + double seconds ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (seconds < 0.0) + return DFB_INVARG; + + return DFB_UNSUPPORTED; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetPos( IDirectFBVideoProvider *thiz, + double *seconds ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!seconds) + return DFB_INVARG; + + *seconds = 0.0; + + return DFB_UNSUPPORTED; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetLength( IDirectFBVideoProvider *thiz, + double *seconds ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!seconds) + return DFB_INVARG; + + *seconds = 0.0; + + return DFB_UNSUPPORTED; +} + +static DFBResult +IDirectFBVideoProvider_GIF_SetPlaybackFlags( IDirectFBVideoProvider *thiz, + DFBVideoProviderPlaybackFlags flags ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (flags & ~DVPLAY_LOOPING) + return DFB_UNSUPPORTED; + + if (flags & DVPLAY_LOOPING && !data->seekable) + return DFB_UNSUPPORTED; + + data->flags = flags; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_SetSpeed( IDirectFBVideoProvider *thiz, + double multiplier ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (multiplier < 0.0) + return DFB_INVARG; + + if (data->speed != multiplier) { + pthread_mutex_lock( &data->lock ); + data->speed = multiplier; + pthread_cond_signal( &data->cond ); + pthread_mutex_unlock( &data->lock ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_GIF_GetSpeed( IDirectFBVideoProvider *thiz, + double *multiplier ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBVideoProvider_GIF ) + + if (!multiplier) + return DFB_INVARG; + + *multiplier = data->speed; + + return DFB_OK; +} + +/* exported symbols */ +static DFBResult +Probe( IDirectFBVideoProvider_ProbeContext *ctx ) +{ + if (!memcmp( ctx->header, "GIF89", 5 )) + return DFB_OK; + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBVideoProvider *thiz, + IDirectFBDataBuffer *buffer ) +{ + DFBResult ret; + + DIRECT_ALLOCATE_INTERFACE_DATA( thiz, IDirectFBVideoProvider_GIF ) + + data->ref = 1; + data->status = DVSTATE_STOP; + data->buffer = buffer; + data->speed = 1.0; + + buffer->AddRef( buffer ); + data->seekable = (buffer->SeekTo( buffer, 0 ) == DFB_OK); + + GIFReset( data ); + ret = GIFReadHeader( data ); + if (ret) { + IDirectFBVideoProvider_GIF_Destruct( thiz ); + return ret; + } + + data->buffer->GetPosition( data->buffer, &data->start_pos ); + + direct_util_recursive_pthread_mutex_init( &data->lock ); + direct_util_monotonic_pthread_cond_init( &data->cond ); + + thiz->AddRef = IDirectFBVideoProvider_GIF_AddRef; + thiz->Release = IDirectFBVideoProvider_GIF_Release; + thiz->GetCapabilities = IDirectFBVideoProvider_GIF_GetCapabilities; + thiz->GetSurfaceDescription = IDirectFBVideoProvider_GIF_GetSurfaceDescription; + thiz->GetStreamDescription = IDirectFBVideoProvider_GIF_GetStreamDescription; + thiz->PlayTo = IDirectFBVideoProvider_GIF_PlayTo; + thiz->Stop = IDirectFBVideoProvider_GIF_Stop; + thiz->GetStatus = IDirectFBVideoProvider_GIF_GetStatus; + thiz->SeekTo = IDirectFBVideoProvider_GIF_SeekTo; + thiz->GetPos = IDirectFBVideoProvider_GIF_GetPos; + thiz->GetLength = IDirectFBVideoProvider_GIF_GetLength; + thiz->SetPlaybackFlags = IDirectFBVideoProvider_GIF_SetPlaybackFlags; + thiz->SetSpeed = IDirectFBVideoProvider_GIF_SetSpeed; + thiz->GetSpeed = IDirectFBVideoProvider_GIF_GetSpeed; + + return DFB_OK; +} diff --git a/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c b/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c new file mode 100755 index 0000000..6d7df13 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c @@ -0,0 +1,1523 @@ +/* + (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. +*/ + +#if defined(__dietlibc__) && !defined(_BSD_SOURCE) +#define _BSD_SOURCE +#endif + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdarg.h> + +#include <string.h> + +#include <sys/time.h> +#include <sys/types.h> +#include <sys/select.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <sys/ioctl.h> + +#ifdef HAVE_LINUX_COMPILER_H +#include <linux/compiler.h> +#endif +#include "videodev.h" + +#include <directfb.h> + +#include <media/idirectfbvideoprovider.h> +#include <media/idirectfbdatabuffer.h> + +#include <core/core.h> +#include <core/coredefs.h> +#include <core/coretypes.h> + +#include <core/state.h> +#include <core/gfxcard.h> +#include <core/layers.h> +#include <core/layer_control.h> +#include <core/surface.h> + +#include <display/idirectfbsurface.h> + +#include <misc/util.h> + +#include <direct/interface.h> +#include <direct/mem.h> +#include <direct/memcpy.h> +#include <direct/messages.h> +#include <direct/thread.h> +#include <direct/util.h> + +#ifdef DFB_HAVE_V4L2 +#include "videodev2.h" +#endif + +static DFBResult +Probe( IDirectFBVideoProvider_ProbeContext *ctx ); + +static DFBResult +Construct( IDirectFBVideoProvider *thiz, ... ); + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBVideoProvider, V4L ) + +/* + * private data struct of IDirectFBVideoProvider + */ +typedef struct { + int ref; /* reference counter */ + + char *filename; + int fd; +#ifdef DFB_HAVE_V4L2 +#define NUMBER_OF_BUFFERS 2 + bool is_v4l2; + + struct v4l2_format fmt; + struct v4l2_capability caps; + + struct v4l2_queryctrl brightness; + struct v4l2_queryctrl contrast; + struct v4l2_queryctrl saturation; + struct v4l2_queryctrl hue; + + struct v4l2_requestbuffers req; + struct v4l2_buffer vidbuf[NUMBER_OF_BUFFERS]; + char *ptr[NUMBER_OF_BUFFERS]; /* only used for capture to system memory */ + bool framebuffer_or_system; +#endif + struct video_capability vcap; + struct video_mmap vmmap; + struct video_mbuf vmbuf; + void *buffer; + bool grab_mode; + + DirectThread *thread; + CoreSurface *destination; + CoreSurfaceBufferLock destinationlock; + DVFrameCallback callback; + void *ctx; + + CoreCleanup *cleanup; + + bool running; + pthread_mutex_t lock; + + Reaction reaction; /* for the destination listener */ + + CoreDFB *core; +} IDirectFBVideoProvider_V4L_data; + +static const unsigned int zero = 0; +static const unsigned int one = 1; + +static void* OverlayThread( DirectThread *thread, void *context ); +static void* GrabThread( DirectThread *thread, void *context ); +static ReactionResult v4l_videosurface_listener( const void *msg_data, void *ctx ); +static ReactionResult v4l_systemsurface_listener( const void *msg_data, void *ctx ); +static DFBResult v4l_to_surface_overlay( CoreSurface *surface, DFBRectangle *rect, + IDirectFBVideoProvider_V4L_data *data ); +static DFBResult v4l_to_surface_grab( CoreSurface *surface, DFBRectangle *rect, + IDirectFBVideoProvider_V4L_data *data ); +static DFBResult v4l_stop( IDirectFBVideoProvider_V4L_data *data, bool detach ); +static void v4l_deinit( IDirectFBVideoProvider_V4L_data *data ); +static void v4l_cleanup( void *data, int emergency ); + +#ifdef DFB_HAVE_V4L2 +static DFBResult v4l2_playto( CoreSurface *surface, DFBRectangle *rect, IDirectFBVideoProvider_V4L_data *data ); +#endif + +static void +IDirectFBVideoProvider_V4L_Destruct( IDirectFBVideoProvider *thiz ) +{ + IDirectFBVideoProvider_V4L_data *data = + (IDirectFBVideoProvider_V4L_data*)thiz->priv; + + if (data->cleanup) + dfb_core_cleanup_remove( NULL, data->cleanup ); + + v4l_deinit( data ); + + D_FREE( data->filename ); + + pthread_mutex_destroy( &data->lock ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBVideoProvider_V4L_AddRef( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBVideoProvider_V4L_Release( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (--data->ref == 0) { + IDirectFBVideoProvider_V4L_Destruct( thiz ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetCapabilities( IDirectFBVideoProvider *thiz, + DFBVideoProviderCapabilities *caps ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!caps) + return DFB_INVARG; + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + *caps = 0; + + data->saturation.id = V4L2_CID_SATURATION; + if (ioctl( data->fd, VIDIOC_G_CTRL, &data->saturation )) { + *caps |= DVCAPS_SATURATION; + } + else { + data->saturation.id = 0; + } + data->brightness.id = V4L2_CID_BRIGHTNESS; + if (ioctl( data->fd, VIDIOC_G_CTRL, &data->brightness )) { + *caps |= DVCAPS_BRIGHTNESS; + } + else { + data->brightness.id = 0; + } + data->contrast.id = V4L2_CID_CONTRAST; + if (ioctl( data->fd, VIDIOC_G_CTRL, &data->contrast )) { + *caps |= DVCAPS_CONTRAST; + } + else { + data->contrast.id = 0; + } + data->hue.id = V4L2_CID_HUE; + if (ioctl( data->fd, VIDIOC_G_CTRL, &data->hue )) { + *caps |= DVCAPS_HUE; + } + else { + data->hue.id = 0; + } + /* fixme: interlaced might not be true for field capture */ + *caps |= DVCAPS_BASIC | DVCAPS_SCALE | DVCAPS_INTERLACED; + } + else +#endif + { + *caps = ( DVCAPS_BASIC | + DVCAPS_BRIGHTNESS | + DVCAPS_CONTRAST | + DVCAPS_HUE | + DVCAPS_SATURATION | + DVCAPS_INTERLACED ); + + if (data->vcap.type & VID_TYPE_SCALES) + *caps |= DVCAPS_SCALE; + } + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetSurfaceDescription( IDirectFBVideoProvider *thiz, + DFBSurfaceDescription *desc ) +{ + IDirectFBVideoProvider_V4L_data *data; + + if (!thiz || !desc) + return DFB_INVARG; + + data = (IDirectFBVideoProvider_V4L_data*)thiz->priv; + + if (!data) + return DFB_DEAD; + + desc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + desc->width = 720; /* fimxe: depends on the selected standard: query standard and set accordingly */ + desc->height = 576; + } + else +#endif + { + desc->width = data->vcap.maxwidth; + desc->height = data->vcap.maxheight; + } + desc->pixelformat = dfb_primary_layer_pixelformat(); + desc->caps = DSCAPS_INTERLACED; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetStreamDescription( IDirectFBVideoProvider *thiz, + DFBStreamDescription *desc ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!desc) + return DFB_INVARG; + + desc->caps = DVSCAPS_VIDEO; + + desc->video.encoding[0] = 0; + desc->video.framerate = 10; // assume 10fps +#ifdef DFB_HAVE_V4L2 + desc->video.aspect = 720.0/576.0; +#else + desc->video.aspect = (double)data->vcap.maxwidth / + (double)data->vcap.maxheight; +#endif + desc->video.bitrate = 0; + + desc->title[0] = desc->author[0] = desc->album[0] = + desc->year = desc->genre[0] = desc->comment[0] = 0; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_PlayTo( IDirectFBVideoProvider *thiz, + IDirectFBSurface *destination, + const DFBRectangle *dstrect, + DVFrameCallback callback, + void *ctx ) +{ + DFBRectangle rect; + IDirectFBSurface_data *dst_data; + CoreSurface *surface = 0; + DFBResult ret; + + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!destination) + return DFB_INVARG; + + dst_data = (IDirectFBSurface_data*)destination->priv; + + if (!dst_data) + return DFB_DEAD; + + if (!dst_data->area.current.w || !dst_data->area.current.h) + return DFB_INVAREA; + + if (dstrect) { + if (dstrect->w < 1 || dstrect->h < 1) + return DFB_INVARG; + + rect = *dstrect; + + rect.x += dst_data->area.wanted.x; + rect.y += dst_data->area.wanted.y; + } + else + rect = dst_data->area.wanted; + + if (!dfb_rectangle_intersect( &rect, &dst_data->area.current )) + return DFB_INVAREA; + + v4l_stop( data, true ); + + pthread_mutex_lock( &data->lock ); + + data->callback = callback; + data->ctx = ctx; + + surface = dst_data->surface; + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + ret = v4l2_playto( surface, &rect, data ); + } + else +#endif + { + data->grab_mode = false; + if (getenv( "DFB_V4L_GRAB" ) || + (surface->config.caps & DSCAPS_SYSTEMONLY) || + (surface->config.caps & DSCAPS_FLIPPING) || + !(VID_TYPE_OVERLAY & data->vcap.type)) + data->grab_mode = true; + else { + /* + * Because we're constantly writing to the surface we + * permanently lock it. + */ + ret = dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_GPU, + CSAF_WRITE, &data->destinationlock ); + + if (ret) { + pthread_mutex_unlock( &data->lock ); + return ret; + } + } + + if (data->grab_mode) + ret = v4l_to_surface_grab( surface, &rect, data ); + else + ret = v4l_to_surface_overlay( surface, &rect, data ); + } + if (ret && !data->grab_mode) + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + + pthread_mutex_unlock( &data->lock ); + + return ret; +} + +static DFBResult +IDirectFBVideoProvider_V4L_Stop( IDirectFBVideoProvider *thiz ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + return v4l_stop( data, true ); +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetStatus( IDirectFBVideoProvider *thiz, + DFBVideoProviderStatus *status ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!status) + return DFB_INVARG; + + *status = data->running ? DVSTATE_PLAY : DVSTATE_STOP; + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_SeekTo( IDirectFBVideoProvider *thiz, + double seconds ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + return DFB_UNIMPLEMENTED; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetPos( IDirectFBVideoProvider *thiz, + double *seconds ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + return DFB_UNSUPPORTED; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetLength( IDirectFBVideoProvider *thiz, + double *seconds ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + return DFB_UNSUPPORTED; +} + +static DFBResult +IDirectFBVideoProvider_V4L_GetColorAdjustment( IDirectFBVideoProvider *thiz, + DFBColorAdjustment *adj ) +{ + struct video_picture pic; + + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!adj) + return DFB_INVARG; + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + struct v4l2_control ctrl; + + if (data->brightness.id) { + ctrl.id = data->brightness.id; + if (!ioctl( data->fd, VIDIOC_G_CTRL, &ctrl )) { + adj->flags |= DCAF_BRIGHTNESS; + adj->brightness = 0xffff * ctrl.value / (data->brightness.maximum - data->brightness.minimum); + } + } + if (data->contrast.id) { + ctrl.id = data->contrast.id; + if (!ioctl( data->fd, VIDIOC_G_CTRL, &ctrl )) { + adj->flags |= DCAF_CONTRAST; + adj->contrast = 0xffff * ctrl.value / (data->contrast.maximum - data->contrast.minimum); + } + } + if (data->hue.id) { + ctrl.id = data->hue.id; + if (!ioctl( data->fd, VIDIOC_G_CTRL, &ctrl )) { + adj->flags |= DCAF_HUE; + adj->hue = 0xffff * ctrl.value / (data->hue.maximum - data->hue.minimum); + } + } + if (data->saturation.id) { + ctrl.id = data->saturation.id; + if (!ioctl( data->fd, VIDIOC_G_CTRL, &ctrl )) { + adj->flags |= DCAF_SATURATION; + adj->saturation = 0xffff * ctrl.value / (data->saturation.maximum - data->saturation.minimum); + } + } + } + else +#endif + { + ioctl( data->fd, VIDIOCGPICT, &pic ); + + adj->flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | DCAF_HUE | DCAF_SATURATION; + + adj->brightness = pic.brightness; + adj->contrast = pic.contrast; + adj->hue = pic.hue; + adj->saturation = pic.colour; + } + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_SetColorAdjustment( IDirectFBVideoProvider *thiz, + const DFBColorAdjustment *adj ) +{ + struct video_picture pic; + + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + if (!adj) + return DFB_INVARG; + + if (adj->flags == DCAF_NONE) + return DFB_OK; + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + struct v4l2_control ctrl; + if ((adj->flags & DCAF_BRIGHTNESS) && data->brightness.id) { + ctrl.id = data->brightness.id; + ctrl.value = (adj->brightness * (data->brightness.maximum - data->brightness.minimum)) / 0xfff; + ioctl( data->fd, VIDIOC_S_CTRL, &ctrl ); + } + if ((adj->flags & DCAF_CONTRAST) && data->contrast.id) { + ctrl.id = data->contrast.id; + ctrl.value = (adj->contrast * (data->contrast.maximum - data->contrast.minimum)) / 0xfff; + ioctl( data->fd, VIDIOC_S_CTRL, &ctrl ); + } + if ((adj->flags & DCAF_HUE) && data->hue.id) { + ctrl.id = data->hue.id; + ctrl.value = (adj->hue * (data->hue.maximum - data->hue.minimum)) / 0xfff; + ioctl( data->fd, VIDIOC_S_CTRL, &ctrl ); + } + if ((adj->flags & DCAF_SATURATION) && data->saturation.id) { + ctrl.id = data->saturation.id; + ctrl.value = (adj->saturation * (data->saturation.maximum - data->saturation.minimum)) / 0xfff; + ioctl( data->fd, VIDIOC_S_CTRL, &ctrl ); + } + } + else +#endif + { + if (ioctl( data->fd, VIDIOCGPICT, &pic ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCGPICT failed!\n" ); + + return ret; + } + + if (adj->flags & DCAF_BRIGHTNESS) pic.brightness = adj->brightness; + if (adj->flags & DCAF_CONTRAST) pic.contrast = adj->contrast; + if (adj->flags & DCAF_HUE) pic.hue = adj->hue; + if (adj->flags & DCAF_SATURATION) pic.colour = adj->saturation; + + if (ioctl( data->fd, VIDIOCSPICT, &pic ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCSPICT failed!\n" ); + + return ret; + } + } + + return DFB_OK; +} + +static DFBResult +IDirectFBVideoProvider_V4L_SendEvent( IDirectFBVideoProvider *thiz, + const DFBEvent *evt ) +{ + DIRECT_INTERFACE_GET_DATA (IDirectFBVideoProvider_V4L) + + return DFB_UNSUPPORTED; +} + + +/* exported symbols */ + +static DFBResult +Probe( IDirectFBVideoProvider_ProbeContext *ctx ) +{ + if (ctx->filename) { + if (strncmp( ctx->filename, "/dev/video", 10 ) == 0) + return DFB_OK; + + if (strncmp( ctx->filename, "/dev/v4l/video", 14 ) == 0) + return DFB_OK; + } + + return DFB_UNSUPPORTED; +} + +static DFBResult +Construct( IDirectFBVideoProvider *thiz, ... ) +{ + int fd; + IDirectFBDataBuffer *buffer; + IDirectFBDataBuffer_data *buffer_data; + CoreDFB *core; + va_list tag; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBVideoProvider_V4L) + + va_start( tag, thiz ); + buffer = va_arg( tag, IDirectFBDataBuffer * ); + core = va_arg( tag, CoreDFB * ); + va_end( tag ); + + + data->ref = 1; + data->core = core; + + buffer_data = (IDirectFBDataBuffer_data*) buffer->priv; + + fd = open( buffer_data->filename, O_RDWR ); + if (fd < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: Cannot open `%s'!\n", + buffer_data->filename ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); + return ret; + } + + direct_util_recursive_pthread_mutex_init( &data->lock ); + +#ifdef DFB_HAVE_V4L2 + data->is_v4l2 = 0; + + /* look if the device is a v4l2 device */ + if (!ioctl( fd, VIDIOC_QUERYCAP, &data->caps )) { + D_INFO( "DirectFB/Video4Linux: This is a Video4Linux-2 device.\n" ); + data->is_v4l2 = 1; + } + + if (data->is_v4l2) { + /* hmm, anything to do here? */ + } + else +#endif + { + D_INFO( "DirectFB/Video4Linux: This is a Video4Linux-1 device.\n" ); + + ioctl( fd, VIDIOCGCAP, &data->vcap ); + ioctl( fd, VIDIOCCAPTURE, &zero ); + + ioctl( fd, VIDIOCGMBUF, &data->vmbuf ); + + data->buffer = mmap( NULL, data->vmbuf.size, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); + } + + data->filename = D_STRDUP( buffer_data->filename ); + data->fd = fd; + + thiz->AddRef = IDirectFBVideoProvider_V4L_AddRef; + thiz->Release = IDirectFBVideoProvider_V4L_Release; + thiz->GetCapabilities = IDirectFBVideoProvider_V4L_GetCapabilities; + thiz->GetSurfaceDescription = IDirectFBVideoProvider_V4L_GetSurfaceDescription; + thiz->GetStreamDescription = IDirectFBVideoProvider_V4L_GetStreamDescription; + thiz->PlayTo = IDirectFBVideoProvider_V4L_PlayTo; + thiz->Stop = IDirectFBVideoProvider_V4L_Stop; + thiz->GetStatus = IDirectFBVideoProvider_V4L_GetStatus; + thiz->SeekTo = IDirectFBVideoProvider_V4L_SeekTo; + thiz->GetPos = IDirectFBVideoProvider_V4L_GetPos; + thiz->GetLength = IDirectFBVideoProvider_V4L_GetLength; + thiz->GetColorAdjustment = IDirectFBVideoProvider_V4L_GetColorAdjustment; + thiz->SetColorAdjustment = IDirectFBVideoProvider_V4L_SetColorAdjustment; + thiz->SendEvent = IDirectFBVideoProvider_V4L_SendEvent; + + return DFB_OK; +} + + +/*****************/ + +/* + * bogus thread to generate callback, + * because video4linux does not support syncing in overlay mode + */ +static void * +OverlayThread( DirectThread *thread, void *ctx ) +{ + IDirectFBVideoProvider_V4L_data *data = (IDirectFBVideoProvider_V4L_data*)ctx; + + int field = 0; + struct timeval tv; + + while (data->running) { + tv.tv_sec = 0; + tv.tv_usec = 20000; + select( 0, 0, 0, 0, &tv ); + + if (!data->running) + break; + + if (data->destination && + (data->destination->config.caps & DSCAPS_INTERLACED)) { + dfb_surface_set_field( data->destination, field ); + + field = !field; + } + + if (!data->running) + break; + + if (data->callback) + data->callback( data->ctx ); + } + + return NULL; +} + +/* + * thread to capture data from v4l buffers and generate callback + */ +static void * +GrabThread( DirectThread *thread, void *ctx ) +{ + IDirectFBVideoProvider_V4L_data *data = (IDirectFBVideoProvider_V4L_data*)ctx; + CoreSurface *surface = data->destination; + void *src, *dst; + int dst_pitch, src_pitch, h; + int frame = 0; + + D_DEBUG( "DirectFB/Video4Linux: %s started.\n", __FUNCTION__ ); + + src_pitch = DFB_BYTES_PER_LINE( surface->config.format, surface->config.size.w ); + + while (frame < data->vmbuf.frames) { + data->vmmap.frame = frame; + ioctl( data->fd, VIDIOCMCAPTURE, &data->vmmap ); + frame++; + } + + if (dfb_surface_ref( surface )) { + D_ERROR( "DirectFB/Video4Linux: dfb_surface_ref() failed!\n" ); + return NULL; + } + + frame = 0; + while (data->running) { + ioctl( data->fd, VIDIOCSYNC, &frame ); + + if (!data->running) + break; + + h = surface->config.size.h; + src = data->buffer + data->vmbuf.offsets[frame]; + + dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, + CSAF_WRITE, &data->destinationlock ); + dst = data->destinationlock.addr; + dst_pitch = data->destinationlock.pitch; + + while (h--) { + direct_memcpy( dst, src, src_pitch ); + dst += dst_pitch; + src += src_pitch; + } + if (surface->config.format == DSPF_I420) { + h = surface->config.size.h; + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + } + else if (surface->config.format == DSPF_YV12) { + h = surface->config.size.h >> 1; + src += h * (src_pitch >> 1); + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + h = surface->config.size.h >> 1; + src -= 2 * h * (src_pitch >> 1); + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + } + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + + data->vmmap.frame = frame; + ioctl( data->fd, VIDIOCMCAPTURE, &data->vmmap ); + + if (!data->running) + break; + + if (surface->config.caps & DSCAPS_INTERLACED) + dfb_surface_set_field( surface, 0 ); + + if (data->callback) + data->callback( data->ctx ); + + if (!data->running) + break; + + sched_yield(); + + if (surface->config.caps & DSCAPS_INTERLACED) { + if (!data->running) + break; + + dfb_surface_set_field( surface, 1 ); + + if (data->callback) + data->callback( data->ctx ); + + if (!data->running) + break; + + sched_yield(); + } + + if (++frame == data->vmbuf.frames) + frame = 0; + } + + dfb_surface_unref( surface ); + + return NULL; +} + +static ReactionResult +v4l_videosurface_listener( const void *msg_data, void *ctx ) +{ +// const CoreSurfaceNotification *notification = msg_data; +// IDirectFBVideoProvider_V4L_data *data = ctx; +// CoreSurface *surface = notification->surface; + + /* + if ((notification->flags & CSNF_SIZEFORMAT) || + (surface->back_buffer->video.health != CSH_STORED)) { + v4l_stop( data, false ); + return RS_REMOVE; + } + */ + + return RS_OK; +} + +static ReactionResult +v4l_systemsurface_listener( const void *msg_data, void *ctx ) +{ +// const CoreSurfaceNotification *notification = msg_data; +// IDirectFBVideoProvider_V4L_data *data = ctx; +// CoreSurface *surface = notification->surface; + + /* + if ((notification->flags & CSNF_SIZEFORMAT) || + (surface->back_buffer->system.health != CSH_STORED && + surface->back_buffer->video.health != CSH_STORED)) { + v4l_stop( data, false ); + return RS_REMOVE; + } + */ + + return RS_OK; +} + + +/************/ + +static DFBResult +v4l_to_surface_overlay( CoreSurface *surface, DFBRectangle *rect, + IDirectFBVideoProvider_V4L_data *data ) +{ + int bpp, palette; + + D_DEBUG( "DirectFB/Video4Linux: %s (%p, %d,%d - %dx%d)\n", __FUNCTION__, + surface, rect->x, rect->y, rect->w, rect->h ); + + /* + * Sanity check. Overlay to system surface isn't possible. + */ + if (surface->config.caps & DSCAPS_SYSTEMONLY) + return DFB_UNSUPPORTED; + + switch (surface->config.format) { + case DSPF_YUY2: + bpp = 16; + palette = VIDEO_PALETTE_YUYV; + break; + case DSPF_UYVY: + bpp = 16; + palette = VIDEO_PALETTE_UYVY; + break; + case DSPF_I420: + bpp = 8; + palette = VIDEO_PALETTE_YUV420P; + break; + case DSPF_ARGB1555: + bpp = 15; + palette = VIDEO_PALETTE_RGB555; + break; + case DSPF_RGB16: + bpp = 16; + palette = VIDEO_PALETTE_RGB565; + break; + case DSPF_RGB24: + bpp = 24; + palette = VIDEO_PALETTE_RGB24; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_RGB32: + bpp = 32; + palette = VIDEO_PALETTE_RGB32; + break; + default: + return DFB_UNSUPPORTED; + } + + { + struct video_buffer b; + + /* in overlay mode, the destinationlock is already taken + * and pointing to the back buffer */ + CoreSurfaceBufferLock *lock = &data->destinationlock; + + b.base = (void*)dfb_gfxcard_memory_physical( NULL, lock->offset ); + b.width = lock->pitch / ((bpp + 7) / 8); + b.height = surface->config.size.h; + b.depth = bpp; + b.bytesperline = lock->pitch; + + if (ioctl( data->fd, VIDIOCSFBUF, &b ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCSFBUF failed, must run being root!\n" ); + + return ret; + } + } + { + struct video_picture p; + + if (ioctl( data->fd, VIDIOCGPICT, &p ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCGPICT failed!\n" ); + + return ret; + } + + p.depth = bpp; + p.palette = palette; + + if (ioctl( data->fd, VIDIOCSPICT, &p ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCSPICT failed!\n" ); + + return ret; + } + } + { + struct video_window win; + + win.width = rect->w; + win.height = rect->h; + win.x = rect->x; + win.y = rect->y; + win.flags = 0; + win.clips = NULL; + win.clipcount = 0; + win.chromakey = 0; + + if (ioctl( data->fd, VIDIOCSWIN, &win ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: VIDIOCSWIN failed!\n" ); + + return ret; + } + } + + if (!data->cleanup) + data->cleanup = dfb_core_cleanup_add( NULL, v4l_cleanup, data, true ); + + if (ioctl( data->fd, VIDIOCCAPTURE, &one ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: Could not start capturing (VIDIOCCAPTURE failed)!\n" ); + + return ret; + } + + data->destination = surface; + + dfb_surface_attach( surface, v4l_videosurface_listener, + data, &data->reaction ); + + data->running = true; + + if (data->callback || (surface->config.caps & DSCAPS_INTERLACED)) + data->thread = direct_thread_create( DTT_CRITICAL, OverlayThread, data, "V4L Overlay" ); + + return DFB_OK; +} + +static DFBResult +v4l_to_surface_grab( CoreSurface *surface, DFBRectangle *rect, + IDirectFBVideoProvider_V4L_data *data ) +{ + int palette; + + D_DEBUG( "DirectFB/Video4Linux: %s...\n", __FUNCTION__ ); + + if (!data->vmbuf.frames) + return DFB_UNSUPPORTED; + + switch (surface->config.format) { + case DSPF_YUY2: + palette = VIDEO_PALETTE_YUYV; + break; + case DSPF_UYVY: + palette = VIDEO_PALETTE_UYVY; + break; + case DSPF_I420: + case DSPF_YV12: + palette = VIDEO_PALETTE_YUV420P; + break; + case DSPF_ARGB1555: + palette = VIDEO_PALETTE_RGB555; + break; + case DSPF_RGB16: + palette = VIDEO_PALETTE_RGB565; + break; + case DSPF_RGB24: + palette = VIDEO_PALETTE_RGB24; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_RGB32: + palette = VIDEO_PALETTE_RGB32; + break; + default: + return DFB_UNSUPPORTED; + } + + data->vmmap.width = surface->config.size.w; + data->vmmap.height = surface->config.size.h; + data->vmmap.format = palette; + data->vmmap.frame = 0; + if (ioctl( data->fd, VIDIOCMCAPTURE, &data->vmmap ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux: Could not start capturing (VIDIOCMCAPTURE failed)!\n" ); + + return ret; + } + + if (!data->cleanup) + data->cleanup = dfb_core_cleanup_add( NULL, v4l_cleanup, data, true ); + + data->destination = surface; + + dfb_surface_attach( surface, v4l_systemsurface_listener, + data, &data->reaction ); + + data->running = true; + + data->thread = direct_thread_create( DTT_INPUT, GrabThread, data, "V4L Grabber" ); + + return DFB_OK; +} + +static DFBResult +v4l_stop( IDirectFBVideoProvider_V4L_data *data, bool detach ) +{ + CoreSurface *destination; + + D_DEBUG( "DirectFB/Video4Linux: %s...\n", __FUNCTION__ ); + + pthread_mutex_lock( &data->lock ); + + if (!data->running) { + pthread_mutex_unlock( &data->lock ); + return DFB_OK; + } + + if (data->thread) { + data->running = false; + direct_thread_join( data->thread ); + direct_thread_destroy( data->thread ); + data->thread = NULL; + } + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + /* turn off streaming */ + int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + int err = ioctl( data->fd, VIDIOC_STREAMOFF, &type ); + if (err) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_STREAMOFF.\n" ); + /* don't quit here */ + } + } + else +#endif + { + if (!data->grab_mode) { + if (ioctl( data->fd, VIDIOCCAPTURE, &zero ) < 0) + D_PERROR( "DirectFB/Video4Linux: " + "Could not stop capturing (VIDIOCCAPTURE failed)!\n" ); + } + } + + destination = data->destination; + + if (!destination) { + pthread_mutex_unlock( &data->lock ); + return DFB_OK; + } + +#ifdef DFB_HAVE_V4L2 + if (data->is_v4l2) { + /* unmap all buffers, if necessary */ + if (data->framebuffer_or_system) { + int i; + for (i = 0; i < data->req.count; i++) { + struct v4l2_buffer *vidbuf = &data->vidbuf[i]; + D_DEBUG( "DirectFB/Video4Linux2: %d => 0x%08x, len:%d\n", i, (u32) data->ptr[i], vidbuf->length ); + if (munmap( data->ptr[i], vidbuf->length )) { + D_PERROR( "DirectFB/Video4Linux2: munmap().\n" ); + } + } + } + else { + dfb_surface_unlock_buffer( destination, &data->destinationlock ); + } + } + else +#endif + { + if (!data->grab_mode) + dfb_surface_unlock_buffer( destination, &data->destinationlock ); + } + + data->destination = NULL; + + pthread_mutex_unlock( &data->lock ); + + if (detach) + dfb_surface_detach( destination, &data->reaction ); + + return DFB_OK; +} + +static void +v4l_deinit( IDirectFBVideoProvider_V4L_data *data ) +{ + if (data->fd == -1) { + D_BUG( "v4l_deinit with 'fd == -1'" ); + return; + } + + v4l_stop( data, true ); + + munmap( data->buffer, data->vmbuf.size ); + close( data->fd ); + data->fd = -1; +} + +static void +v4l_cleanup( void *ctx, int emergency ) +{ + IDirectFBVideoProvider_V4L_data *data = + (IDirectFBVideoProvider_V4L_data*)ctx; + + if (emergency) + v4l_stop( data, false ); + else + v4l_deinit( data ); +} + +/* v4l2 specific stuff */ +#ifdef DFB_HAVE_V4L2 +static int +wait_for_buffer( int vid, struct v4l2_buffer *cur ) +{ + fd_set rdset; + struct timeval timeout; + int n, err; + +// D_DEBUG("DirectFB/Video4Linux2: %s...\n", __FUNCTION__); + + cur->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + FD_ZERO( &rdset ); + FD_SET( vid, &rdset ); + + timeout.tv_sec = 5; + timeout.tv_usec = 0; + + n = select( vid + 1, &rdset, NULL, NULL, &timeout ); + if (n == -1) { + D_PERROR( "DirectFB/Video4Linux2: select().\n" ); + return -1; /* fixme */ + } + else if (n == 0) { + D_PERROR( "DirectFB/Video4Linux2: select(), timeout.\n" ); + return -1; /* fixme */ + } + else if (FD_ISSET( vid, &rdset )) { + err = ioctl( vid, VIDIOC_DQBUF, cur ); + if (err) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_DQBUF.\n" ); + return -1; /* fixme */ + } + } + return 0; +} + +static void * +V4L2_Thread( DirectThread *thread, void *ctx ) +{ + int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + int i, err; + + IDirectFBVideoProvider_V4L_data *data = (IDirectFBVideoProvider_V4L_data *) ctx; + CoreSurface *surface = data->destination; + void *src, *dst; + int dst_pitch, src_pitch, h; + + D_DEBUG( "DirectFB/Video4Linux2: %s started.\n", __FUNCTION__ ); + + src_pitch = DFB_BYTES_PER_LINE( surface->config.format, surface->config.size.w ); + + /* Queue all buffers */ + for (i = 0; i < data->req.count; i++) { + struct v4l2_buffer *vidbuf = &data->vidbuf[i]; + + if (!data->framebuffer_or_system) { + vidbuf->m.offset = data->destinationlock.offset; + } + + err = ioctl( data->fd, VIDIOC_QBUF, vidbuf ); + if (err) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_QBUF.\n" ); + return NULL; + } + } + + /* start streaming */ + if (ioctl( data->fd, VIDIOC_STREAMON, &type )) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_STREAMON.\n" ); + return NULL; /* fixme */ + } + + while (data->running) { + + struct v4l2_buffer cur; + + if (wait_for_buffer( data->fd, &cur )) { + return NULL; + } + + if (data->framebuffer_or_system) { + CoreSurfaceBufferLock lock; + + D_DEBUG( "DirectFB/Video4Linux2: index:%d, to system memory.\n", cur.index ); + + h = surface->config.size.h; + src = data->ptr[cur.index]; + + dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); + dst = lock.addr; + dst_pitch = lock.pitch; + while (h--) { + direct_memcpy( dst, src, src_pitch ); + dst += dst_pitch; + src += src_pitch; + } + if (surface->config.format == DSPF_I420) { + h = surface->config.size.h; + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + } + else if (surface->config.format == DSPF_YV12) { + h = surface->config.size.h >> 1; + src += h * (src_pitch >> 1); + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + h = surface->config.size.h >> 1; + src -= 2 * h * (src_pitch >> 1); + while (h--) { + direct_memcpy( dst, src, src_pitch >> 1 ); + dst += dst_pitch >> 1; + src += src_pitch >> 1; + } + } + else if (surface->config.format == DSPF_NV12 || + surface->config.format == DSPF_NV21) { + h = surface->config.size.h >> 1; + while (h--) { + direct_memcpy( dst, src, src_pitch ); + dst += dst_pitch; + src += src_pitch; + } + } + dfb_surface_unlock_buffer( surface, &lock ); + } + else { + D_DEBUG( "DirectFB/Video4Linux2: index:%d, to overlay surface\n", cur.index ); + } + + if (data->callback) + data->callback( data->ctx ); + + if (ioctl( data->fd, VIDIOC_QBUF, &cur )) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_QBUF.\n" ); + return NULL; + } + } + + return NULL; +} + +static DFBResult +v4l2_playto( CoreSurface *surface, DFBRectangle *rect, IDirectFBVideoProvider_V4L_data *data ) +{ + int palette; + + int err; + int i; + + D_DEBUG( "DirectFB/Video4Linux2: %s...\n", __FUNCTION__ ); + + switch (surface->config.format) { + case DSPF_YUY2: + palette = V4L2_PIX_FMT_YUYV; + break; + case DSPF_UYVY: + palette = V4L2_PIX_FMT_UYVY; + break; + case DSPF_I420: + palette = V4L2_PIX_FMT_YUV420; + break; + case DSPF_YV12: + palette = V4L2_PIX_FMT_YVU420; + break; + case DSPF_NV12: + palette = V4L2_PIX_FMT_NV12; + break; + case DSPF_NV21: + palette = V4L2_PIX_FMT_NV21; + break; + case DSPF_RGB332: + palette = V4L2_PIX_FMT_RGB332; + break; + case DSPF_ARGB1555: + palette = V4L2_PIX_FMT_RGB555; + break; + case DSPF_RGB16: + palette = V4L2_PIX_FMT_RGB565; + break; + case DSPF_RGB24: + palette = V4L2_PIX_FMT_BGR24; + break; + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_RGB32: + palette = V4L2_PIX_FMT_BGR32; + break; + default: + return DFB_UNSUPPORTED; + } + + err = dfb_surface_lock_buffer( surface, CSBR_BACK, CSAID_GPU, CSAF_WRITE, &data->destinationlock ); + if (err) + return err; + + data->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + data->fmt.fmt.pix.width = surface->config.size.w; + data->fmt.fmt.pix.height = surface->config.size.h; + data->fmt.fmt.pix.pixelformat = palette; + data->fmt.fmt.pix.bytesperline = data->destinationlock.pitch; + data->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; /* fixme: we can do field based capture, too */ + + D_DEBUG( "DirectFB/Video4Linux2: surface->config.size.w:%d, surface->config.size.h:%d.\n", surface->config.size.w, surface->config.size.h ); + + err = ioctl( data->fd, VIDIOC_S_FMT, &data->fmt ); + if (err) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_S_FMT.\n" ); + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return err; + } + + if (data->fmt.fmt.pix.width != surface->config.size.w || data->fmt.fmt.pix.height != surface->config.size.h) { + D_PERROR( "DirectFB/Video4Linux2: driver cannot fulfill application request.\n" ); + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return DFB_UNSUPPORTED; /* fixme */ + } + + if (data->brightness.id) { + ioctl( data->fd, VIDIOC_G_CTRL, &data->brightness ); + } + if (data->contrast.id) { + ioctl( data->fd, VIDIOC_G_CTRL, &data->contrast ); + } + if (data->saturation.id) { + ioctl( data->fd, VIDIOC_G_CTRL, &data->saturation ); + } + if (data->hue.id) { + ioctl( data->fd, VIDIOC_G_CTRL, &data->hue ); + } + + if (surface->config.caps & DSCAPS_SYSTEMONLY) { + data->framebuffer_or_system = 1; + data->req.memory = V4L2_MEMORY_MMAP; + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + } + else { + struct v4l2_framebuffer fb; + + data->framebuffer_or_system = 0; + data->req.memory = V4L2_MEMORY_OVERLAY; + + fb.base = (void *) dfb_gfxcard_memory_physical( NULL, 0 ); + fb.fmt.width = surface->config.size.w; + fb.fmt.height = surface->config.size.h; + fb.fmt.pixelformat = palette; + + D_DEBUG( "w:%d, h:%d, bpl:%d, base:0x%08lx\n", + fb.fmt.width, fb.fmt.height, fb.fmt.bytesperline, (unsigned long)fb.base ); + + if (ioctl( data->fd, VIDIOC_S_FBUF, &fb ) < 0) { + DFBResult ret = errno2result( errno ); + + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_S_FBUF failed, must run being root!\n" ); + + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return ret; + } + } + + /* Ask Video Device for Buffers */ + data->req.count = NUMBER_OF_BUFFERS; + data->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + err = ioctl( data->fd, VIDIOC_REQBUFS, &data->req ); + if (err < 0 || data->req.count < NUMBER_OF_BUFFERS) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_REQBUFS: %d, %d.\n", err, data->req.count ); + if (!data->framebuffer_or_system) + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return err; + } + + /* Query each buffer and map it to the video device if necessary */ + for (i = 0; i < data->req.count; i++) { + struct v4l2_buffer *vidbuf = &data->vidbuf[i]; + + vidbuf->index = i; + vidbuf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + err = ioctl( data->fd, VIDIOC_QUERYBUF, vidbuf ); + if (err < 0) { + D_PERROR( "DirectFB/Video4Linux2: VIDIOC_QUERYBUF.\n" ); + if (!data->framebuffer_or_system) + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return err; + } + +/* + if (vidbuf->length == 0) { + D_PERROR( "DirectFB/Video4Linux2: length is zero!\n" ); + return -EINVAL; + } +*/ + if (data->framebuffer_or_system) { + data->ptr[i] = mmap( 0, vidbuf->length, PROT_READ | PROT_WRITE, MAP_SHARED, data->fd, vidbuf->m.offset ); + if (data->ptr[i] == MAP_FAILED) { + D_PERROR( "DirectFB/Video4Linux2: mmap().\n" ); + if (!data->framebuffer_or_system) + dfb_surface_unlock_buffer( surface, &data->destinationlock ); + return err; + } + } + D_DEBUG( "DirectFB/Video4Linux2: len:0x%08x, %d => 0x%08x\n", vidbuf->length, i, (u32) data->ptr[i] ); + } + + if (!data->cleanup) + data->cleanup = dfb_core_cleanup_add( NULL, v4l_cleanup, data, true ); + + data->destination = surface; + + dfb_surface_attach( surface, v4l_systemsurface_listener, data, &data->reaction ); + + data->running = true; + + data->thread = direct_thread_create( DTT_DEFAULT, V4L2_Thread, data, "Video4Linux 2" ); + + return DFB_OK; +} +#endif diff --git a/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev.h b/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev.h new file mode 100755 index 0000000..c5ad64f --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev.h @@ -0,0 +1,353 @@ +#ifndef __LINUX_VIDEODEV_H +#define __LINUX_VIDEODEV_H + +#include <linux/types.h> +#include <linux/version.h> + +#define HAVE_V4L2 1 +#include "videodev2.h" + +#define VID_TYPE_CAPTURE 1 /* Can capture */ +#define VID_TYPE_TUNER 2 /* Can tune */ +#define VID_TYPE_TELETEXT 4 /* Does teletext */ +#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ +#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ +#define VID_TYPE_CLIPPING 32 /* Can clip */ +#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ +#define VID_TYPE_SCALES 128 /* Scalable */ +#define VID_TYPE_MONOCHROME 256 /* Monochrome only */ +#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ +#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ +#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ +#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ +#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ + +struct video_capability +{ + char name[32]; + int type; + int channels; /* Num channels */ + int audios; /* Num audio devices */ + int maxwidth; /* Supported width */ + int maxheight; /* And height */ + int minwidth; /* Supported width */ + int minheight; /* And height */ +}; + + +struct video_channel +{ + int channel; + char name[32]; + int tuners; + __u32 flags; +#define VIDEO_VC_TUNER 1 /* Channel has a tuner */ +#define VIDEO_VC_AUDIO 2 /* Channel has audio */ + __u16 type; +#define VIDEO_TYPE_TV 1 +#define VIDEO_TYPE_CAMERA 2 + __u16 norm; /* Norm set by channel */ +}; + +struct video_tuner +{ + int tuner; + char name[32]; + unsigned long rangelow, rangehigh; /* Tuner range */ + __u32 flags; +#define VIDEO_TUNER_PAL 1 +#define VIDEO_TUNER_NTSC 2 +#define VIDEO_TUNER_SECAM 4 +#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */ +#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */ +#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */ +#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */ +#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */ + __u16 mode; /* PAL/NTSC/SECAM/OTHER */ +#define VIDEO_MODE_PAL 0 +#define VIDEO_MODE_NTSC 1 +#define VIDEO_MODE_SECAM 2 +#define VIDEO_MODE_AUTO 3 + __u16 signal; /* Signal strength 16bit scale */ +}; + +struct video_picture +{ + __u16 brightness; + __u16 hue; + __u16 colour; + __u16 contrast; + __u16 whiteness; /* Black and white only */ + __u16 depth; /* Capture depth */ + __u16 palette; /* Palette in use */ +#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ +#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ +#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ +#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ +#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ +#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ +#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ +#define VIDEO_PALETTE_YUYV 8 +#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ +#define VIDEO_PALETTE_YUV420 10 +#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ +#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ +#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ +#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ +#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ +#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ +#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ +#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ +}; + +struct video_audio +{ + int audio; /* Audio channel */ + __u16 volume; /* If settable */ + __u16 bass, treble; + __u32 flags; +#define VIDEO_AUDIO_MUTE 1 +#define VIDEO_AUDIO_MUTABLE 2 +#define VIDEO_AUDIO_VOLUME 4 +#define VIDEO_AUDIO_BASS 8 +#define VIDEO_AUDIO_TREBLE 16 +#define VIDEO_AUDIO_BALANCE 32 + char name[16]; +#define VIDEO_SOUND_MONO 1 +#define VIDEO_SOUND_STEREO 2 +#define VIDEO_SOUND_LANG1 4 +#define VIDEO_SOUND_LANG2 8 + __u16 mode; + __u16 balance; /* Stereo balance */ + __u16 step; /* Step actual volume uses */ +}; + +struct video_clip +{ + __s32 x,y; + __s32 width, height; + struct video_clip *next; /* For user use/driver use only */ +}; + +struct video_window +{ + __u32 x,y; /* Position of window */ + __u32 width,height; /* Its size */ + __u32 chromakey; + __u32 flags; + struct video_clip *clips; /* Set only */ + int clipcount; +#define VIDEO_WINDOW_INTERLACE 1 +#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */ +#define VIDEO_CLIP_BITMAP -1 +/* bitmap is 1024x625, a '1' bit represents a clipped pixel */ +#define VIDEO_CLIPMAP_SIZE (128 * 625) +}; + +struct video_capture +{ + __u32 x,y; /* Offsets into image */ + __u32 width, height; /* Area to capture */ + __u16 decimation; /* Decimation divider */ + __u16 flags; /* Flags for capture */ +#define VIDEO_CAPTURE_ODD 0 /* Temporal */ +#define VIDEO_CAPTURE_EVEN 1 +}; + +struct video_buffer +{ + void *base; + int height,width; + int depth; + int bytesperline; +}; + +struct video_mmap +{ + unsigned int frame; /* Frame (0 - n) for double buffer */ + int height,width; + unsigned int format; /* should be VIDEO_PALETTE_* */ +}; + +struct video_key +{ + __u8 key[8]; + __u32 flags; +}; + + +#define VIDEO_MAX_FRAME 32 + +struct video_mbuf +{ + int size; /* Total memory to map */ + int frames; /* Frames */ + int offsets[VIDEO_MAX_FRAME]; +}; + + +#define VIDEO_NO_UNIT (-1) + + +struct video_unit +{ + int video; /* Video minor */ + int vbi; /* VBI minor */ + int radio; /* Radio minor */ + int audio; /* Audio minor */ + int teletext; /* Teletext minor */ +}; + +struct vbi_format { + __u32 sampling_rate; /* in Hz */ + __u32 samples_per_line; + __u32 sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */ + __s32 start[2]; /* starting line for each frame */ + __u32 count[2]; /* count of lines for each frame */ + __u32 flags; +#define VBI_UNSYNC 1 /* can distingues between top/bottom field */ +#define VBI_INTERLACED 2 /* lines are interlaced */ +}; + +/* video_info is biased towards hardware mpeg encode/decode */ +/* but it could apply generically to any hardware compressor/decompressor */ +struct video_info +{ + __u32 frame_count; /* frames output since decode/encode began */ + __u32 h_size; /* current unscaled horizontal size */ + __u32 v_size; /* current unscaled veritcal size */ + __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */ + __u32 picture_type; /* current picture type */ + __u32 temporal_reference; /* current temporal reference */ + __u8 user_data[256]; /* user data last found in compressed stream */ + /* user_data[0] contains user data flags, user_data[1] has count */ +}; + +/* generic structure for setting playback modes */ +struct video_play_mode +{ + int mode; + int p1; + int p2; +}; + +/* for loading microcode / fpga programming */ +struct video_code +{ + char loadwhat[16]; /* name or tag of file being passed */ + int datasize; + __u8 *data; +}; + +#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ +#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ +#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ +#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */ +#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */ +#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */ +#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */ +#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */ +#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */ +#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */ +#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */ +#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */ +#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */ +#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */ +#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */ +#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */ +#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */ +#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */ +#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */ +#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */ +#define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */ +#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */ +#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */ +#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */ +#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */ +#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */ +#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */ +#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */ +#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */ + + +#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ + +/* VIDIOCSWRITEMODE */ +#define VID_WRITE_MPEG_AUD 0 +#define VID_WRITE_MPEG_VID 1 +#define VID_WRITE_OSD 2 +#define VID_WRITE_TTX 3 +#define VID_WRITE_CC 4 +#define VID_WRITE_MJPEG 5 + +/* VIDIOCSPLAYMODE */ +#define VID_PLAY_VID_OUT_MODE 0 + /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */ +#define VID_PLAY_GENLOCK 1 + /* p1: 0 = OFF, 1 = ON */ + /* p2: GENLOCK FINE DELAY value */ +#define VID_PLAY_NORMAL 2 +#define VID_PLAY_PAUSE 3 +#define VID_PLAY_SINGLE_FRAME 4 +#define VID_PLAY_FAST_FORWARD 5 +#define VID_PLAY_SLOW_MOTION 6 +#define VID_PLAY_IMMEDIATE_NORMAL 7 +#define VID_PLAY_SWITCH_CHANNELS 8 +#define VID_PLAY_FREEZE_FRAME 9 +#define VID_PLAY_STILL_MODE 10 +#define VID_PLAY_MASTER_MODE 11 + /* p1: see below */ +#define VID_PLAY_MASTER_NONE 1 +#define VID_PLAY_MASTER_VIDEO 2 +#define VID_PLAY_MASTER_AUDIO 3 +#define VID_PLAY_ACTIVE_SCANLINES 12 + /* p1 = first active; p2 = last active */ +#define VID_PLAY_RESET 13 +#define VID_PLAY_END_MARK 14 + + + +#define VID_HARDWARE_BT848 1 +#define VID_HARDWARE_QCAM_BW 2 +#define VID_HARDWARE_PMS 3 +#define VID_HARDWARE_QCAM_C 4 +#define VID_HARDWARE_PSEUDO 5 +#define VID_HARDWARE_SAA5249 6 +#define VID_HARDWARE_AZTECH 7 +#define VID_HARDWARE_SF16MI 8 +#define VID_HARDWARE_RTRACK 9 +#define VID_HARDWARE_ZOLTRIX 10 +#define VID_HARDWARE_SAA7146 11 +#define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */ +#define VID_HARDWARE_RTRACK2 13 +#define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */ +#define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */ +#define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */ +#define VID_HARDWARE_BROADWAY 17 /* Broadway project */ +#define VID_HARDWARE_GEMTEK 18 +#define VID_HARDWARE_TYPHOON 19 +#define VID_HARDWARE_VINO 20 /* SGI Indy Vino */ +#define VID_HARDWARE_CADET 21 /* Cadet radio */ +#define VID_HARDWARE_TRUST 22 /* Trust FM Radio */ +#define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */ +#define VID_HARDWARE_CPIA 24 +#define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */ +#define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */ +#define VID_HARDWARE_OV511 27 +#define VID_HARDWARE_ZR356700 28 /* Zoran 36700 series */ +#define VID_HARDWARE_W9966 29 +#define VID_HARDWARE_SE401 30 /* SE401 USB webcams */ +#define VID_HARDWARE_PWC 31 /* Philips webcams */ +#define VID_HARDWARE_MEYE 32 /* Sony Vaio MotionEye cameras */ +#define VID_HARDWARE_CPIA2 33 +#define VID_HARDWARE_VICAM 34 +#define VID_HARDWARE_SF16FMR2 35 +#define VID_HARDWARE_W9968CF 36 +#define VID_HARDWARE_SAA7114H 37 +#endif /* __LINUX_VIDEODEV_H */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev2.h b/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev2.h new file mode 100755 index 0000000..026b836 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBVideoProvider/videodev2.h @@ -0,0 +1,897 @@ +#ifndef __LINUX_VIDEODEV2_H +#define __LINUX_VIDEODEV2_H +/* + * Video for Linux Two + * + * Header file for v4l or V4L2 drivers and applications, for + * Linux kernels 2.2.x or 2.4.x. + * + * See http://bytesex.org/v4l/ for API specs and other + * v4l2 documentation. + * + * Author: Bill Dirks <bdirks@pacbell.net> + * Justin Schoeman + * et al. + */ + +/* + * M I S C E L L A N E O U S + */ + +/* Four-character-code (FOURCC) */ +#define v4l2_fourcc(a,b,c,d)\ + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) + +/* + * E N U M S + */ +enum v4l2_field { + V4L2_FIELD_ANY = 0, /* driver can choose from none, + top, bottom, interlaced + depending on whatever it thinks + is approximate ... */ + V4L2_FIELD_NONE = 1, /* this device has no fields ... */ + V4L2_FIELD_TOP = 2, /* top field only */ + V4L2_FIELD_BOTTOM = 3, /* bottom field only */ + V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ + V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one + buffer, top-bottom order */ + V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ + V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into + separate buffers */ +}; +#define V4L2_FIELD_HAS_TOP(field) \ + ((field) == V4L2_FIELD_TOP ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTTOM(field) \ + ((field) == V4L2_FIELD_BOTTOM ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTH(field) \ + ((field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) + +enum v4l2_buf_type { + V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, + V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, + V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, + V4L2_BUF_TYPE_VBI_CAPTURE = 4, + V4L2_BUF_TYPE_VBI_OUTPUT = 5, + V4L2_BUF_TYPE_PRIVATE = 0x80, +}; + +enum v4l2_ctrl_type { + V4L2_CTRL_TYPE_INTEGER = 1, + V4L2_CTRL_TYPE_BOOLEAN = 2, + V4L2_CTRL_TYPE_MENU = 3, + V4L2_CTRL_TYPE_BUTTON = 4, +}; + +enum v4l2_tuner_type { + V4L2_TUNER_RADIO = 1, + V4L2_TUNER_ANALOG_TV = 2, +}; + +enum v4l2_memory { + V4L2_MEMORY_MMAP = 1, + V4L2_MEMORY_USERPTR = 2, + V4L2_MEMORY_OVERLAY = 3, +}; + +/* see also http://vektor.theorem.ca/graphics/ycbcr/ */ +enum v4l2_colorspace { + /* ITU-R 601 -- broadcast NTSC/PAL */ + V4L2_COLORSPACE_SMPTE170M = 1, + + /* 1125-Line (US) HDTV */ + V4L2_COLORSPACE_SMPTE240M = 2, + + /* HD and modern captures. */ + V4L2_COLORSPACE_REC709 = 3, + + /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ + V4L2_COLORSPACE_BT878 = 4, + + /* These should be useful. Assume 601 extents. */ + V4L2_COLORSPACE_470_SYSTEM_M = 5, + V4L2_COLORSPACE_470_SYSTEM_BG = 6, + + /* I know there will be cameras that send this. So, this is + * unspecified chromaticities and full 0-255 on each of the + * Y'CbCr components + */ + V4L2_COLORSPACE_JPEG = 7, + + /* For RGB colourspaces, this is probably a good start. */ + V4L2_COLORSPACE_SRGB = 8, +}; + +enum v4l2_priority { + V4L2_PRIORITY_UNSET = 0, /* not initialized */ + V4L2_PRIORITY_BACKGROUND = 1, + V4L2_PRIORITY_INTERACTIVE = 2, + V4L2_PRIORITY_RECORD = 3, + V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE, +}; + +struct v4l2_rect { + __s32 left; + __s32 top; + __s32 width; + __s32 height; +}; + +struct v4l2_fract { + __u32 numerator; + __u32 denominator; +}; + +/* + * D R I V E R C A P A B I L I T I E S + */ +struct v4l2_capability +{ + __u8 driver[16]; /* i.e. "bttv" */ + __u8 card[32]; /* i.e. "Hauppauge WinTV" */ + __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ + __u32 version; /* should use KERNEL_VERSION() */ + __u32 capabilities; /* Device capabilities */ + __u32 reserved[4]; +}; + +/* Values for 'capabilities' field */ +#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ +#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ +#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ +#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a VBI capture device */ +#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a VBI output device */ +#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ + +#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ +#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ +#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ + +#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ +#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ +#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ + +/* + * V I D E O I M A G E F O R M A T + */ + +struct v4l2_pix_format +{ + __u32 width; + __u32 height; + __u32 pixelformat; + enum v4l2_field field; + __u32 bytesperline; /* for padding, zero if unused */ + __u32 sizeimage; + enum v4l2_colorspace colorspace; + __u32 priv; /* private data, depends on pixelformat */ +}; + +/* Pixel format FOURCC depth Description */ +#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1') /* 8 RGB-3-3-2 */ +#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O') /* 16 RGB-5-5-5 */ +#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P') /* 16 RGB-5-6-5 */ +#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16 RGB-5-5-5 BE */ +#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16 RGB-5-6-5 BE */ +#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3') /* 24 BGR-8-8-8 */ +#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3') /* 24 RGB-8-8-8 */ +#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */ +#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */ +#define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ +#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ +#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16 YVU422 planar */ +#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16 YVU411 planar */ +#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P') /* 12 YUV 4:1:1 */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1') /* 12 Y/CrCb 4:2:0 */ + +/* The following formats are not defined in the V4L2 specification */ +#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */ +#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */ +#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4') /* 8 8-bit color */ + +/* compressed formats */ +#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */ +#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G') /* JFIF JPEG */ +#define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d') /* 1394 */ +#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G') /* MPEG */ + +/* Vendor-specific formats */ +#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */ + +/* + * F O R M A T E N U M E R A T I O N + */ +struct v4l2_fmtdesc +{ + __u32 index; /* Format number */ + enum v4l2_buf_type type; /* buffer type */ + __u32 flags; + __u8 description[32]; /* Description string */ + __u32 pixelformat; /* Format fourcc */ + __u32 reserved[4]; +}; + +#define V4L2_FMT_FLAG_COMPRESSED 0x0001 + + +/* + * T I M E C O D E + */ +struct v4l2_timecode +{ + __u32 type; + __u32 flags; + __u8 frames; + __u8 seconds; + __u8 minutes; + __u8 hours; + __u8 userbits[4]; +}; + +/* Type */ +#define V4L2_TC_TYPE_24FPS 1 +#define V4L2_TC_TYPE_25FPS 2 +#define V4L2_TC_TYPE_30FPS 3 +#define V4L2_TC_TYPE_50FPS 4 +#define V4L2_TC_TYPE_60FPS 5 + +/* Flags */ +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ +#define V4L2_TC_FLAG_COLORFRAME 0x0002 +#define V4L2_TC_USERBITS_field 0x000C +#define V4L2_TC_USERBITS_USERDEFINED 0x0000 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008 +/* The above is based on SMPTE timecodes */ + + +/* + * C O M P R E S S I O N P A R A M E T E R S + */ +#if 0 +/* ### generic compression settings don't work, there is too much + * ### codec-specific stuff. Maybe reuse that for MPEG codec settings + * ### later ... */ +struct v4l2_compression +{ + __u32 quality; + __u32 keyframerate; + __u32 pframerate; + __u32 reserved[5]; + +/* what we'll need for MPEG, extracted from some postings on + the v4l list (Gert Vervoort, PlasmaJohn). + +system stream: + - type: elementary stream(ES), packatised elementary stream(s) (PES) + program stream(PS), transport stream(TS) + - system bitrate + - PS packet size (DVD: 2048 bytes, VCD: 2324 bytes) + - TS video PID + - TS audio PID + - TS PCR PID + - TS system information tables (PAT, PMT, CAT, NIT and SIT) + - (MPEG-1 systems stream vs. MPEG-2 program stream (TS not supported + by MPEG-1 systems) + +audio: + - type: MPEG (+Layer I,II,III), AC-3, LPCM + - bitrate + - sampling frequency (DVD: 48 Khz, VCD: 44.1 KHz, 32 kHz) + - Trick Modes? (ff, rew) + - Copyright + - Inverse Telecine + +video: + - picturesize (SIF, 1/2 D1, 2/3 D1, D1) and PAL/NTSC norm can be set + through excisting V4L2 controls + - noise reduction, parameters encoder specific? + - MPEG video version: MPEG-1, MPEG-2 + - GOP (Group Of Pictures) definition: + - N: number of frames per GOP + - M: distance between reference (I,P) frames + - open/closed GOP + - quantiser matrix: inter Q matrix (64 bytes) and intra Q matrix (64 bytes) + - quantiser scale: linear or logarithmic + - scanning: alternate or zigzag + - bitrate mode: CBR (constant bitrate) or VBR (variable bitrate). + - target video bitrate for CBR + - target video bitrate for VBR + - maximum video bitrate for VBR - min. quantiser value for VBR + - max. quantiser value for VBR + - adaptive quantisation value + - return the number of bytes per GOP or bitrate for bitrate monitoring + +*/ +}; +#endif + +struct v4l2_jpegcompression +{ + int quality; + + int APPn; /* Number of APP segment to be written, + * must be 0..15 */ + int APP_len; /* Length of data in JPEG APPn segment */ + char APP_data[60]; /* Data in the JPEG APPn segment. */ + + int COM_len; /* Length of data in JPEG COM segment */ + char COM_data[60]; /* Data in JPEG COM segment */ + + __u32 jpeg_markers; /* Which markers should go into the JPEG + * output. Unless you exactly know what + * you do, leave them untouched. + * Inluding less markers will make the + * resulting code smaller, but there will + * be fewer aplications which can read it. + * The presence of the APP and COM marker + * is influenced by APP_len and COM_len + * ONLY, not by this property! */ + +#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ +#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ +#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ +#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ +#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will + * allways use APP0 */ +}; + + +/* + * M E M O R Y - M A P P I N G B U F F E R S + */ +struct v4l2_requestbuffers +{ + __u32 count; + enum v4l2_buf_type type; + enum v4l2_memory memory; + __u32 reserved[2]; +}; + +struct v4l2_buffer +{ + __u32 index; + enum v4l2_buf_type type; + __u32 bytesused; + __u32 flags; + enum v4l2_field field; + struct timeval timestamp; + struct v4l2_timecode timecode; + __u32 sequence; + + /* memory location */ + enum v4l2_memory memory; + union { + __u32 offset; + unsigned long userptr; + } m; + __u32 length; + + __u32 reserved[2]; +}; + +/* Flags for 'flags' field */ +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ + +/* + * O V E R L A Y P R E V I E W + */ +struct v4l2_framebuffer +{ + __u32 capability; + __u32 flags; +/* FIXME: in theory we should pass something like PCI device + memory + * region + offset instead of some physical address */ + void* base; + struct v4l2_pix_format fmt; +}; +/* Flags for the 'capability' field. Read only */ +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 +#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 +/* Flags for the 'flags' field. */ +#define V4L2_FBUF_FLAG_PRIMARY 0x0001 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 + +struct v4l2_clip +{ + struct v4l2_rect c; + struct v4l2_clip *next; +}; + +struct v4l2_window +{ + struct v4l2_rect w; + enum v4l2_field field; + __u32 chromakey; + struct v4l2_clip *clips; + __u32 clipcount; + void *bitmap; +}; + + +/* + * C A P T U R E P A R A M E T E R S + */ +struct v4l2_captureparm +{ + __u32 capability; /* Supported modes */ + __u32 capturemode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in .1us units */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 readbuffers; /* # of buffers for read */ + __u32 reserved[4]; +}; +/* Flags for 'capability' and 'capturemode' fields */ +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ + +struct v4l2_outputparm +{ + __u32 capability; /* Supported modes */ + __u32 outputmode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in seconds */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 writebuffers; /* # of buffers for write */ + __u32 reserved[4]; +}; + +/* + * I N P U T I M A G E C R O P P I N G + */ + +struct v4l2_cropcap { + enum v4l2_buf_type type; + struct v4l2_rect bounds; + struct v4l2_rect defrect; + struct v4l2_fract pixelaspect; +}; + +struct v4l2_crop { + enum v4l2_buf_type type; + struct v4l2_rect c; +}; + +/* + * A N A L O G V I D E O S T A N D A R D + */ + +typedef __u64 v4l2_std_id; + +/* one bit for each */ +#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) +#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) +#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) +#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) +#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) +#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) +#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) +#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) + +#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) +#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) +#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) +#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) + +#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) +#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) + +#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) +#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) +#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) +#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) +#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) +#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) +#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) + +/* ATSC/HDTV */ +#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) +#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) + +/* some common needed stuff */ +#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_PAL_G) +#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ + V4L2_STD_PAL_D1 |\ + V4L2_STD_PAL_K) +#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ + V4L2_STD_PAL_DK |\ + V4L2_STD_PAL_H |\ + V4L2_STD_PAL_I) +#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ + V4L2_STD_NTSC_M_JP) +#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ + V4L2_STD_SECAM_D |\ + V4L2_STD_SECAM_G |\ + V4L2_STD_SECAM_H |\ + V4L2_STD_SECAM_K |\ + V4L2_STD_SECAM_K1 |\ + V4L2_STD_SECAM_L) + +#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_60 |\ + V4L2_STD_NTSC) +#define V4L2_STD_625_50 (V4L2_STD_PAL |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_SECAM) + +#define V4L2_STD_UNKNOWN 0 +#define V4L2_STD_ALL (V4L2_STD_525_60 |\ + V4L2_STD_625_50) + +struct v4l2_standard +{ + __u32 index; + v4l2_std_id id; + __u8 name[24]; + struct v4l2_fract frameperiod; /* Frames, not fields */ + __u32 framelines; + __u32 reserved[4]; +}; + + +/* + * V I D E O I N P U T S + */ +struct v4l2_input +{ + __u32 index; /* Which input */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of input */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 tuner; /* Associated tuner */ + v4l2_std_id std; + __u32 status; + __u32 reserved[4]; +}; +/* Values for the 'type' field */ +#define V4L2_INPUT_TYPE_TUNER 1 +#define V4L2_INPUT_TYPE_CAMERA 2 + +/* field 'status' - general */ +#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ +#define V4L2_IN_ST_NO_SIGNAL 0x00000002 +#define V4L2_IN_ST_NO_COLOR 0x00000004 + +/* field 'status' - analog */ +#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ +#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ + +/* field 'status' - digital */ +#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ +#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ +#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ + +/* field 'status' - VCR and set-top box */ +#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ +#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ +#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ + +/* + * V I D E O O U T P U T S + */ +struct v4l2_output +{ + __u32 index; /* Which output */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of output */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 modulator; /* Associated modulator */ + v4l2_std_id std; + __u32 reserved[4]; +}; +/* Values for the 'type' field */ +#define V4L2_OUTPUT_TYPE_MODULATOR 1 +#define V4L2_OUTPUT_TYPE_ANALOG 2 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 + +/* + * C O N T R O L S + */ +struct v4l2_control +{ + __u32 id; + __s32 value; +}; + +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ +struct v4l2_queryctrl +{ + __u32 id; + enum v4l2_ctrl_type type; + __u8 name[32]; /* Whatever */ + __s32 minimum; /* Note signedness */ + __s32 maximum; + __s32 step; + __s32 default_value; + __u32 flags; + __u32 reserved[2]; +}; + +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ +struct v4l2_querymenu +{ + __u32 id; + __u32 index; + __u8 name[32]; /* Whatever */ + __u32 reserved; +}; + +/* Control flags */ +#define V4L2_CTRL_FLAG_DISABLED 0x0001 +#define V4L2_CTRL_FLAG_GRABBED 0x0002 + +/* Control IDs defined by V4L2 */ +#define V4L2_CID_BASE 0x00980900 +/* IDs reserved for driver specific controls */ +#define V4L2_CID_PRIVATE_BASE 0x08000000 + +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) +#define V4L2_CID_HUE (V4L2_CID_BASE+3) +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) +#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */ +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) +#define V4L2_CID_GAIN (V4L2_CID_BASE+19) +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) +#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) +#define V4L2_CID_VCENTER (V4L2_CID_BASE+23) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */ + +/* + * T U N I N G + */ +struct v4l2_tuner +{ + __u32 index; + __u8 name[32]; + enum v4l2_tuner_type type; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 rxsubchans; + __u32 audmode; + __s32 signal; + __s32 afc; + __u32 reserved[4]; +}; + +struct v4l2_modulator +{ + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 txsubchans; + __u32 reserved[4]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_TUNER_CAP_LOW 0x0001 +#define V4L2_TUNER_CAP_NORM 0x0002 +#define V4L2_TUNER_CAP_STEREO 0x0010 +#define V4L2_TUNER_CAP_LANG2 0x0020 +#define V4L2_TUNER_CAP_SAP 0x0020 +#define V4L2_TUNER_CAP_LANG1 0x0040 + +/* Flags for the 'rxsubchans' field */ +#define V4L2_TUNER_SUB_MONO 0x0001 +#define V4L2_TUNER_SUB_STEREO 0x0002 +#define V4L2_TUNER_SUB_LANG2 0x0004 +#define V4L2_TUNER_SUB_SAP 0x0004 +#define V4L2_TUNER_SUB_LANG1 0x0008 + +/* Values for the 'audmode' field */ +#define V4L2_TUNER_MODE_MONO 0x0000 +#define V4L2_TUNER_MODE_STEREO 0x0001 +#define V4L2_TUNER_MODE_LANG2 0x0002 +#define V4L2_TUNER_MODE_SAP 0x0002 +#define V4L2_TUNER_MODE_LANG1 0x0003 + +struct v4l2_frequency +{ + __u32 tuner; + enum v4l2_tuner_type type; + __u32 frequency; + __u32 reserved[8]; +}; + +/* + * A U D I O + */ +struct v4l2_audio +{ + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; +/* Flags for the 'capability' field */ +#define V4L2_AUDCAP_STEREO 0x00001 +#define V4L2_AUDCAP_AVL 0x00002 + +/* Flags for the 'mode' field */ +#define V4L2_AUDMODE_AVL 0x00001 + +struct v4l2_audioout +{ + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* + * D A T A S E R V I C E S ( V B I ) + * + * Data services API by Michael Schimek + */ + +struct v4l2_vbi_format +{ + __u32 sampling_rate; /* in 1 Hz */ + __u32 offset; + __u32 samples_per_line; + __u32 sample_format; /* V4L2_PIX_FMT_* */ + __s32 start[2]; + __u32 count[2]; + __u32 flags; /* V4L2_VBI_* */ + __u32 reserved[2]; /* must be zero */ +}; + +/* VBI flags */ +#define V4L2_VBI_UNSYNC (1<< 0) +#define V4L2_VBI_INTERLACED (1<< 1) + + +/* + * A G G R E G A T E S T R U C T U R E S + */ + +/* Stream data format + */ +struct v4l2_format +{ + enum v4l2_buf_type type; + union + { + struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE + struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY + struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE + __u8 raw_data[200]; // user-defined + } fmt; +}; + + +/* Stream type-dependent parameters + */ +struct v4l2_streamparm +{ + enum v4l2_buf_type type; + union + { + struct v4l2_captureparm capture; + struct v4l2_outputparm output; + __u8 raw_data[200]; /* user-defined */ + } parm; +}; + + + +/* + * I O C T L C O D E S F O R V I D E O D E V I C E S + * + */ +#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability) +#define VIDIOC_RESERVED _IO ('V', 1) +#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc) +#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format) +#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format) +#if 0 +#define VIDIOC_G_COMP _IOR ('V', 6, struct v4l2_compression) +#define VIDIOC_S_COMP _IOW ('V', 7, struct v4l2_compression) +#endif +#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers) +#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer) +#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer) +#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer) +#define VIDIOC_OVERLAY _IOW ('V', 14, int) +#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer) +#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer) +#define VIDIOC_STREAMON _IOW ('V', 18, int) +#define VIDIOC_STREAMOFF _IOW ('V', 19, int) +#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm) +#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm) +#define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id) +#define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id) +#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard) +#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input) +#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control) +#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control) +#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner) +#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner) +#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio) +#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio) +#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl) +#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu) +#define VIDIOC_G_INPUT _IOR ('V', 38, int) +#define VIDIOC_S_INPUT _IOWR ('V', 39, int) +#define VIDIOC_G_OUTPUT _IOR ('V', 46, int) +#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int) +#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output) +#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout) +#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout) +#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator) +#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator) +#define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency) +#define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency) +#define VIDIOC_CROPCAP _IOWR ('V', 58, struct v4l2_cropcap) +#define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop) +#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop) +#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression) +#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression) +#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id) +#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format) +#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio) +#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout) +#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority) +#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority) + +/* for compatibility, will go away some day */ +#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int) +#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm) +#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control) +#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio) +#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout) +#define VIDIOC_CROPCAP_OLD _IOR ('V', 58, struct v4l2_cropcap) + +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ + +#endif /* __LINUX_VIDEODEV2_H */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_default.c b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_default.c new file mode 100755 index 0000000..98b6d1a --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_default.c @@ -0,0 +1,339 @@ +/* + (c) Copyright 2001-2008 The DirectFB Organization (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp <dok@directfb.org>, + Andreas Hundt <andi@fischlustig.de>, + Sven Neumann <neo@directfb.org>, + Ville Syrjälä <syrjala@sci.fi> and + Claudio Ciccani <klan@users.sf.net>. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +//#define DIRECT_ENABLE_DEBUG + +#include <config.h> + +#include <stdarg.h> + +#include <directfb.h> +#include <directfb_windows.h> + +#include <direct/debug.h> +#include <direct/interface.h> +#include <direct/list.h> +#include <direct/memcpy.h> + +#include <fusion/reactor.h> + +#include <core/wm.h> + +#include "idirectfbwindows_default.h" + + +D_DEBUG_DOMAIN( IDirectFBWindows_default, "IDirectFBWindows/default", "IDirectFBWindows Interface default Implementation" ); + +/**********************************************************************************************************************/ + +static DirectResult +Probe( void *ctx, ... ); + +static DirectResult +Construct( void *interface, ... ); + +#include <direct/interface_implementation.h> + +DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBWindows, default ) + +/**********************************************************************************************************************/ + +typedef struct { + DirectLink link; + + DFBWindowsWatcher watcher; + void *context; + + Reaction reactions[_CORE_WM_NUM_CHANNELS]; +} RegisteredWatcher; + +/**********************************************************************************************************************/ + +static void +IDirectFBWindows_Destruct( IDirectFBWindows *thiz ) +{ + IDirectFBWindows_data *data; + + D_DEBUG_AT( IDirectFBWindows_default, "%s( %p )\n", __FUNCTION__, thiz ); + + D_ASSERT( thiz != NULL ); + + data = thiz->priv; +} + +static DirectResult +IDirectFBWindows_AddRef( IDirectFBWindows *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBWindows) + + D_DEBUG_AT( IDirectFBWindows_default, "%s( %p )\n", __FUNCTION__, thiz ); + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBWindows_Release( IDirectFBWindows *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBWindows) + + D_DEBUG_AT( IDirectFBWindows_default, "%s( %p )\n", __FUNCTION__, thiz ); + + if (--data->ref == 0) + IDirectFBWindows_Destruct( thiz ); + + return DFB_OK; +} + +/**********************************************************************************************************************/ + +static ReactionResult +IDirectFBWindows_WM_Reaction_WindowAdd( const void *msg_data, + void *ctx ) +{ + const CoreWM_WindowAdd *add = msg_data; + RegisteredWatcher *registered = ctx; + + D_DEBUG_AT( IDirectFBWindows_default, "%s( msg %p, ctx %p )\n", __FUNCTION__, msg_data, ctx ); + + D_ASSERT( registered->watcher.WindowAdd != NULL ); + + registered->watcher.WindowAdd( registered->context, &add->info ); + + return RS_OK; +} + +static ReactionResult +IDirectFBWindows_WM_Reaction_WindowRemove( const void *msg_data, + void *ctx ) +{ + const CoreWM_WindowRemove *remove = msg_data; + RegisteredWatcher *registered = ctx; + + D_DEBUG_AT( IDirectFBWindows_default, "%s( msg %p, ctx %p )\n", __FUNCTION__, msg_data, ctx ); + + D_ASSERT( registered->watcher.WindowRemove != NULL ); + + registered->watcher.WindowRemove( registered->context, remove->window_id ); + + return RS_OK; +} + +static ReactionResult +IDirectFBWindows_WM_Reaction_WindowConfig( const void *msg_data, + void *ctx ) +{ + const CoreWM_WindowConfig *config = msg_data; + RegisteredWatcher *registered = ctx; + + D_DEBUG_AT( IDirectFBWindows_default, "%s( msg %p, ctx %p )\n", __FUNCTION__, msg_data, ctx ); + + D_ASSERT( registered->watcher.WindowConfig != NULL ); + + registered->watcher.WindowConfig( registered->context, config->window_id, &config->config, config->flags ); + + return RS_OK; +} + +static ReactionResult +IDirectFBWindows_WM_Reaction_WindowState( const void *msg_data, + void *ctx ) +{ + const CoreWM_WindowState *state = msg_data; + RegisteredWatcher *registered = ctx; + + D_DEBUG_AT( IDirectFBWindows_default, "%s( msg %p, ctx %p )\n", __FUNCTION__, msg_data, ctx ); + + D_ASSERT( registered->watcher.WindowState != NULL ); + + registered->watcher.WindowState( registered->context, state->window_id, &state->state ); + + return RS_OK; +} + +static ReactionResult +IDirectFBWindows_WM_Reaction_WindowRestack( const void *msg_data, + void *ctx ) +{ + const CoreWM_WindowRestack *restack = msg_data; + RegisteredWatcher *registered = ctx; + + D_DEBUG_AT( IDirectFBWindows_default, "%s( msg %p, ctx %p )\n", __FUNCTION__, msg_data, ctx ); + + D_ASSERT( registered->watcher.WindowRestack != NULL ); + + registered->watcher.WindowRestack( registered->context, restack->window_id, restack->index ); + + return RS_OK; +} + +static ReactionResult +IDirectFBWindows_WM_Reaction_WindowFocus( const void *msg_data, + void *ctx ) +{ + const CoreWM_WindowFocus *focus = msg_data; + RegisteredWatcher *registered = ctx; + + D_DEBUG_AT( IDirectFBWindows_default, "%s( msg %p, ctx %p )\n", __FUNCTION__, msg_data, ctx ); + + D_ASSERT( registered->watcher.WindowFocus != NULL ); + + registered->watcher.WindowFocus( registered->context, focus->window_id ); + + return RS_OK; +} + +#define WM_ATTACH( Func, CHANNEL ) \ + do { \ + if (watcher->Func) { \ + ret = dfb_wm_attach( data->core, CORE_WM_##CHANNEL, \ + IDirectFBWindows_WM_Reaction_##Func, registered, \ + ®istered->reactions[CORE_WM_##CHANNEL] ); \ + if (ret) { \ + D_DERROR( ret, "IDirectFBWindows_RegisterWatcher: " \ + "dfb_wm_attach( 'CORE_WM_" #CHANNEL "' ) failed!\n" ); \ + goto error; \ + } \ + } \ + } while (0) + +/**********************************************************************************************************************/ + +static DirectResult +IDirectFBWindows_RegisterWatcher( IDirectFBWindows *thiz, + const DFBWindowsWatcher *watcher, + void *context ) +{ + DFBResult ret; + int i; + RegisteredWatcher *registered; + + DIRECT_INTERFACE_GET_DATA(IDirectFBWindows) + + D_DEBUG_AT( IDirectFBWindows_default, "%s( %p )\n", __FUNCTION__, thiz ); + + if (!watcher) + return DFB_INVARG; + + if (!watcher->WindowAdd && + !watcher->WindowRemove && + !watcher->WindowConfig && + !watcher->WindowState && + !watcher->WindowRestack && + !watcher->WindowFocus) + return DFB_INVARG; + + registered = D_CALLOC( 1, sizeof(RegisteredWatcher) ); + if (!registered) + return D_OOM(); + + registered->watcher = *watcher; + registered->context = context; + + WM_ATTACH( WindowAdd, WINDOW_ADD ); + WM_ATTACH( WindowRemove, WINDOW_REMOVE ); + WM_ATTACH( WindowConfig, WINDOW_CONFIG ); + WM_ATTACH( WindowState, WINDOW_STATE ); + WM_ATTACH( WindowRestack, WINDOW_RESTACK ); + WM_ATTACH( WindowFocus, WINDOW_FOCUS ); + + direct_list_append( &data->watchers, ®istered->link ); + + return DFB_OK; + + +error: + for (i=_CORE_WM_NUM_CHANNELS-1; i>=0; i--) { + if (registered->reactions[i].func) + dfb_wm_detach( data->core, ®istered->reactions[i] ); + } + + D_FREE( registered ); + + return ret; +} + +/**********************************************************************************************************************/ + +static DirectResult +Probe( void *ctx, ... ) +{ + D_DEBUG_AT( IDirectFBWindows_default, "%s()\n", __FUNCTION__ ); + + (void) ctx; + + /* ... */ + + return DFB_OK; +} + +static DirectResult +Construct( void *interface, ... ) +{ + DFBResult ret = DFB_INVARG; + IDirectFB *dfb; + IDirectFBWindows *thiz = interface; + CoreDFB *core; + + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBWindows) + + D_DEBUG_AT( IDirectFBWindows_default, "%s( %p )\n", __FUNCTION__, thiz ); + + va_list tag; + va_start(tag, interface); + dfb = va_arg(tag, IDirectFB *); + core = va_arg(tag, CoreDFB *); + va_end( tag ); + + /* Check arguments. */ + if (!thiz) + goto error; + + /* Initialize interface data. */ + data->ref = 1; + data->core = core; + data->idirectfb = dfb; + + + /* Initialize function pointer table. */ + thiz->AddRef = IDirectFBWindows_AddRef; + thiz->Release = IDirectFBWindows_Release; + + thiz->RegisterWatcher = IDirectFBWindows_RegisterWatcher; + + + return DFB_OK; + + +error: + DIRECT_DEALLOCATE_INTERFACE(thiz); + + return ret; +} + diff --git a/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_default.h b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_default.h new file mode 100755 index 0000000..ec6c8fb --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_default.h @@ -0,0 +1,50 @@ +/* + (c) Copyright 2001-2008 The DirectFB Organization (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp <dok@directfb.org>, + Andreas Hundt <andi@fischlustig.de>, + Sven Neumann <neo@directfb.org>, + Ville Syrjälä <syrjala@sci.fi> and + Claudio Ciccani <klan@users.sf.net>. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __IDIRECTFBWINDOWS_DEFAULT_H__ +#define __IIDIRECTFBWINDOWS_DEFAULT_H__ + +#include <directfb.h> + +#include <core/coretypes.h> + + +/* + * private data struct of IDirectFBWindows + */ +typedef struct { + int ref; /* reference counter */ + + CoreDFB *core; + IDirectFB *idirectfb; + + DirectLink *watchers; +} IDirectFBWindows_data; + + +#endif diff --git a/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_dispatcher.c b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_dispatcher.c new file mode 100755 index 0000000..29549f0 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_dispatcher.c @@ -0,0 +1,325 @@ +/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <voodoo/interface.h>
+#include <voodoo/manager.h>
+
+#include "idirectfbwindows_requestor.h"
+
+#include "idirectfbwindows_dispatcher.h"
+
+
+static DFBResult Probe();
+static DFBResult Construct( IDirectFBWindows *thiz,
+ IDirectFBWindows *real,
+ VoodooManager *manager,
+ VoodooInstanceID super,
+ void *arg,
+ VoodooInstanceID *ret_instance );
+
+#include <direct/interface_implementation.h>
+
+DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBWindows, Dispatcher )
+
+
+/**************************************************************************************************/
+
+static void
+IDirectFBWindows_Dispatcher_Destruct( IDirectFBWindows *thiz )
+{
+ D_DEBUG( "%s (%p)\n", __FUNCTION__, thiz );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+IDirectFBWindows_Dispatcher_AddRef( IDirectFBWindows *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindows_Dispatcher)
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBWindows_Dispatcher_Release( IDirectFBWindows *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindows_Dispatcher)
+
+ if (--data->ref == 0)
+ IDirectFBWindows_Dispatcher_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindows_Dispatcher_RegisterWatcher( IDirectFBWindows *thiz,
+ const DFBWindowsWatcher *watcher,
+ void *context )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindows_Dispatcher)
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
+/**************************************************************************************************/
+
+static DirectResult
+Dispatch_Release( IDirectFBWindows *thiz, IDirectFBWindows *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindows_Dispatcher)
+
+ return thiz->Release( thiz );
+}
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ VoodooManager *manager;
+
+ VoodooInstanceID instance;
+} WatcherContext;
+
+static void
+IDirectFBWindows_Dispatcher_WindowAdd( void *context,
+ const DFBWindowInfo *info )
+{
+ WatcherContext *ctx = context;
+
+ voodoo_manager_request( ctx->manager, ctx->instance,
+ IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowAdd, VREQ_NONE, NULL,
+ VMBT_DATA, sizeof(DFBWindowInfo), info,
+ VMBT_NONE );
+}
+
+static void
+IDirectFBWindows_Dispatcher_WindowRemove( void *context,
+ DFBWindowID window_id )
+{
+ WatcherContext *ctx = context;
+
+ voodoo_manager_request( ctx->manager, ctx->instance,
+ IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowRemove, VREQ_NONE, NULL,
+ VMBT_ID, window_id,
+ VMBT_NONE );
+}
+
+static void
+IDirectFBWindows_Dispatcher_WindowConfig( void *context,
+ DFBWindowID window_id,
+ const DFBWindowConfig *config,
+ DFBWindowConfigFlags flags )
+{
+ WatcherContext *ctx = context;
+
+ voodoo_manager_request( ctx->manager, ctx->instance,
+ IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowConfig, VREQ_NONE, NULL,
+ VMBT_ID, window_id,
+ VMBT_DATA, sizeof(DFBWindowConfig), config,
+ VMBT_INT, flags,
+ VMBT_NONE );
+}
+
+static void
+IDirectFBWindows_Dispatcher_WindowState( void *context,
+ DFBWindowID window_id,
+ const DFBWindowState *state )
+{
+ WatcherContext *ctx = context;
+
+ voodoo_manager_request( ctx->manager, ctx->instance,
+ IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowState, VREQ_NONE, NULL,
+ VMBT_ID, window_id,
+ VMBT_DATA, sizeof(DFBWindowState), state,
+ VMBT_NONE );
+}
+
+static void
+IDirectFBWindows_Dispatcher_WindowRestack( void *context,
+ DFBWindowID window_id,
+ unsigned int index )
+{
+ WatcherContext *ctx = context;
+
+ voodoo_manager_request( ctx->manager, ctx->instance,
+ IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowRestack, VREQ_NONE, NULL,
+ VMBT_ID, window_id,
+ VMBT_UINT, index,
+ VMBT_NONE );
+}
+
+static void
+IDirectFBWindows_Dispatcher_WindowFocus( void *context,
+ DFBWindowID window_id )
+{
+ WatcherContext *ctx = context;
+
+ voodoo_manager_request( ctx->manager, ctx->instance,
+ IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowFocus, VREQ_NONE, NULL,
+ VMBT_ID, window_id,
+ VMBT_NONE );
+}
+
+/**********************************************************************************************************************/
+
+static DirectResult
+Dispatch_RegisterWatcher( IDirectFBWindows *thiz, IDirectFBWindows *real,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ DFBResult ret;
+ VoodooMessageParser parser;
+ VoodooInstanceID instance;
+ unsigned int mask;
+ DFBWindowsWatcher watcher;
+ WatcherContext *context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindows_Dispatcher)
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, instance );
+ VOODOO_PARSER_GET_UINT( parser, mask );
+ VOODOO_PARSER_END( parser );
+
+ memset( &watcher, 0, sizeof(watcher) );
+
+ if (mask & (1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowAdd))
+ watcher.WindowAdd = IDirectFBWindows_Dispatcher_WindowAdd;
+
+ if (mask & (1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowRemove))
+ watcher.WindowRemove = IDirectFBWindows_Dispatcher_WindowRemove;
+
+ if (mask & (1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowConfig))
+ watcher.WindowConfig = IDirectFBWindows_Dispatcher_WindowConfig;
+
+ if (mask & (1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowState))
+ watcher.WindowState = IDirectFBWindows_Dispatcher_WindowState;
+
+ if (mask & (1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowRestack))
+ watcher.WindowRestack = IDirectFBWindows_Dispatcher_WindowRestack;
+
+ if (mask & (1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowFocus))
+ watcher.WindowFocus = IDirectFBWindows_Dispatcher_WindowFocus;
+
+ context = D_CALLOC( 1, sizeof(WatcherContext) );
+ if (!context)
+ return D_OOM();
+
+ context->manager = manager;
+ context->instance = instance;
+
+ ret = real->RegisterWatcher( real, &watcher, context );
+ if (ret)
+ return ret;
+
+ return voodoo_manager_respond( manager, true, msg->header.serial, DR_OK, VOODOO_INSTANCE_NONE, VMBT_NONE );
+}
+
+static DirectResult
+Dispatch( void *dispatcher, void *real, VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ D_DEBUG( "IDirectFBWindows/Dispatcher: "
+ "Handling request for instance %u with method %u...\n", msg->instance, msg->method );
+
+ switch (msg->method) {
+ case IDIRECTFBWINDOWS_METHOD_ID_Release:
+ return Dispatch_Release( dispatcher, real, manager, msg );
+
+ case IDIRECTFBWINDOWS_METHOD_ID_RegisterWatcher:
+ return Dispatch_RegisterWatcher( dispatcher, real, manager, msg );
+ }
+
+ return DFB_NOSUCHMETHOD;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+Probe()
+{
+ /* This implementation has to be loaded explicitly. */
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+Construct( IDirectFBWindows *thiz, /* Dispatcher interface */
+ IDirectFBWindows *real, /* Real interface implementation */
+ VoodooManager *manager, /* Manager of the Voodoo framework */
+ VoodooInstanceID super, /* Instance ID of the super interface */
+ void *arg, /* Optional arguments to constructor */
+ VoodooInstanceID *ret_instance )
+{
+ DFBResult ret;
+ VoodooInstanceID instance;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBWindows_Dispatcher)
+
+ D_ASSERT( real != NULL );
+ D_ASSERT( manager != NULL );
+ D_ASSERT( super != VOODOO_INSTANCE_NONE );
+ D_ASSERT( ret_instance != NULL );
+
+ /* Register the dispatcher, getting a new instance ID that refers to it. */
+ ret = voodoo_manager_register_local( manager, false, thiz, real, Dispatch, &instance );
+ if (ret) {
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ /* Return the new instance. */
+ *ret_instance = instance;
+
+ /* Initialize interface data. */
+ data->ref = 1;
+ data->real = real;
+ data->self = instance;
+ data->super = super;
+
+ /* Initialize interface methods. */
+ thiz->AddRef = IDirectFBWindows_Dispatcher_AddRef;
+ thiz->Release = IDirectFBWindows_Dispatcher_Release;
+ thiz->RegisterWatcher = IDirectFBWindows_Dispatcher_RegisterWatcher;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_dispatcher.h b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_dispatcher.h new file mode 100755 index 0000000..a1b39e1 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_dispatcher.h @@ -0,0 +1,53 @@ +/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBWINDOWS_DISPATCHER_H__
+#define __IDIRECTFBWINDOWS_DISPATCHER_H__
+
+#include <directfb_windows.h>
+
+
+#define IDIRECTFBWINDOWS_METHOD_ID_AddRef 1
+#define IDIRECTFBWINDOWS_METHOD_ID_Release 2
+#define IDIRECTFBWINDOWS_METHOD_ID_RegisterWatcher 3
+
+/*
+ * private data struct of IDirectFBWindows_Dispatcher
+ */
+typedef struct {
+ int ref; /* reference counter */
+
+ IDirectFBWindows *real;
+
+ VoodooInstanceID self;
+ VoodooInstanceID super;
+
+ VoodooInstanceID remote;
+} IDirectFBWindows_Dispatcher_data;
+
+#endif
diff --git a/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_requestor.c b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_requestor.c new file mode 100755 index 0000000..16c7286 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_requestor.c @@ -0,0 +1,365 @@ +/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <voodoo/client.h>
+#include <voodoo/interface.h>
+#include <voodoo/manager.h>
+
+#include "idirectfbwindows_dispatcher.h"
+
+#include "idirectfbwindows_requestor.h"
+
+
+static DFBResult Probe();
+static DFBResult Construct( IDirectFBWindows *thiz,
+ VoodooManager *manager,
+ VoodooInstanceID instance,
+ void *arg );
+
+#include <direct/interface_implementation.h>
+
+DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBWindows, Requestor )
+
+
+/**********************************************************************************************************************/
+
+static void
+IDirectFBWindows_Requestor_Destruct( IDirectFBWindows *thiz )
+{
+ D_DEBUG( "%s (%p)\n", __FUNCTION__, thiz );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+/**********************************************************************************************************************/
+
+static DirectResult
+IDirectFBWindows_Requestor_AddRef( IDirectFBWindows *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindows_Requestor)
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBWindows_Requestor_Release( IDirectFBWindows *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindows_Requestor)
+
+ if (--data->ref == 0)
+ IDirectFBWindows_Requestor_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ DirectLink link;
+
+ DFBWindowsWatcher watcher;
+ void *context;
+
+ VoodooInstanceID instance;
+} RegisteredWatcher;
+
+static DirectResult
+IDirectFBWindows_Requestor_DispatchWatcher_WindowAdd( IDirectFBWindows *thiz, RegisteredWatcher *registered,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ VoodooMessageParser parser;
+ const DFBWindowInfo *info;
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_DATA( parser, info );
+ VOODOO_PARSER_END( parser );
+
+ D_ASSERT( registered->watcher.WindowAdd != NULL );
+
+ registered->watcher.WindowAdd( registered->context, info );
+
+ return DR_OK;
+}
+
+static DirectResult
+IDirectFBWindows_Requestor_DispatchWatcher_WindowRemove( IDirectFBWindows *thiz, RegisteredWatcher *registered,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ VoodooMessageParser parser;
+ VoodooInstanceID window_id;
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, window_id );
+ VOODOO_PARSER_END( parser );
+
+ D_ASSERT( registered->watcher.WindowRemove != NULL );
+
+ registered->watcher.WindowRemove( registered->context, window_id );
+
+ return DR_OK;
+}
+
+static DirectResult
+IDirectFBWindows_Requestor_DispatchWatcher_WindowConfig( IDirectFBWindows *thiz, RegisteredWatcher *registered,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ VoodooMessageParser parser;
+ VoodooInstanceID window_id;
+ const DFBWindowConfig *config;
+ DFBWindowConfigFlags flags;
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, window_id );
+ VOODOO_PARSER_GET_DATA( parser, config );
+ VOODOO_PARSER_GET_INT( parser, flags );
+ VOODOO_PARSER_END( parser );
+
+ D_ASSERT( registered->watcher.WindowConfig != NULL );
+
+ registered->watcher.WindowConfig( registered->context, window_id, config, flags );
+
+ return DR_OK;
+}
+
+static DirectResult
+IDirectFBWindows_Requestor_DispatchWatcher_WindowState( IDirectFBWindows *thiz, RegisteredWatcher *registered,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ VoodooMessageParser parser;
+ VoodooInstanceID window_id;
+ const DFBWindowState *state;
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, window_id );
+ VOODOO_PARSER_GET_DATA( parser, state );
+ VOODOO_PARSER_END( parser );
+
+ D_ASSERT( registered->watcher.WindowState != NULL );
+
+ registered->watcher.WindowState( registered->context, window_id, state );
+
+ return DR_OK;
+}
+
+static DirectResult
+IDirectFBWindows_Requestor_DispatchWatcher_WindowRestack( IDirectFBWindows *thiz, RegisteredWatcher *registered,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ VoodooMessageParser parser;
+ VoodooInstanceID window_id;
+ unsigned int index;
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, window_id );
+ VOODOO_PARSER_GET_UINT( parser, index );
+ VOODOO_PARSER_END( parser );
+
+ D_ASSERT( registered->watcher.WindowRestack != NULL );
+
+ registered->watcher.WindowRestack( registered->context, window_id, index );
+
+ return DR_OK;
+}
+
+static DirectResult
+IDirectFBWindows_Requestor_DispatchWatcher_WindowFocus( IDirectFBWindows *thiz, RegisteredWatcher *registered,
+ VoodooManager *manager, VoodooRequestMessage *msg )
+{
+ VoodooMessageParser parser;
+ VoodooInstanceID window_id;
+
+ VOODOO_PARSER_BEGIN( parser, msg );
+ VOODOO_PARSER_GET_ID( parser, window_id );
+ VOODOO_PARSER_END( parser );
+
+ D_ASSERT( registered->watcher.WindowFocus != NULL );
+
+ registered->watcher.WindowFocus( registered->context, window_id );
+
+ return DR_OK;
+}
+
+static DirectResult
+IDirectFBWindows_Requestor_DispatchWatcher( void *dispatcher,
+ void *real,
+ VoodooManager *manager,
+ VoodooRequestMessage *msg )
+{
+ D_DEBUG( "IDirectFBWindows_Requestor/DispatchWatcher: "
+ "Handling request for instance %u with method %u...\n", msg->instance, msg->method );
+
+ switch (msg->method) {
+ case IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowAdd:
+ return IDirectFBWindows_Requestor_DispatchWatcher_WindowAdd( dispatcher, real, manager, msg );
+
+ case IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowRemove:
+ return IDirectFBWindows_Requestor_DispatchWatcher_WindowRemove( dispatcher, real, manager, msg );
+
+ case IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowConfig:
+ return IDirectFBWindows_Requestor_DispatchWatcher_WindowConfig( dispatcher, real, manager, msg );
+
+ case IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowState:
+ return IDirectFBWindows_Requestor_DispatchWatcher_WindowState( dispatcher, real, manager, msg );
+
+ case IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowRestack:
+ return IDirectFBWindows_Requestor_DispatchWatcher_WindowRestack( dispatcher, real, manager, msg );
+
+ case IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowFocus:
+ return IDirectFBWindows_Requestor_DispatchWatcher_WindowFocus( dispatcher, real, manager, msg );
+ }
+
+ return DFB_NOSUCHMETHOD;
+}
+
+/**********************************************************************************************************************/
+
+static DFBResult
+IDirectFBWindows_Requestor_RegisterWatcher( IDirectFBWindows *thiz,
+ const DFBWindowsWatcher *watcher,
+ void *context )
+{
+ DFBResult ret;
+ RegisteredWatcher *registered;
+ VoodooResponseMessage *response;
+ unsigned int mask = 0;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindows_Requestor)
+
+ if (!watcher)
+ return DFB_INVARG;
+
+ if (watcher->WindowAdd)
+ mask |= 1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowAdd;
+
+ if (watcher->WindowRemove)
+ mask |= 1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowRemove;
+
+ if (watcher->WindowConfig)
+ mask |= 1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowConfig;
+
+ if (watcher->WindowState)
+ mask |= 1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowState;
+
+ if (watcher->WindowRestack)
+ mask |= 1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowRestack;
+
+ if (watcher->WindowFocus)
+ mask |= 1 << IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowFocus;
+
+ if (!mask)
+ return DFB_INVARG;
+
+
+ registered = D_CALLOC( 1, sizeof(RegisteredWatcher) );
+ if (!registered)
+ return D_OOM();
+
+ registered->watcher = *watcher;
+ registered->context = context;
+
+ ret = voodoo_manager_register_local( data->manager, false, thiz, registered,
+ IDirectFBWindows_Requestor_DispatchWatcher, ®istered->instance );
+ if (ret) {
+ D_DERROR( ret, "IDirectFBWindows_Requestor_RegisterWatcher: Could not register local instance!\n" );
+ goto error;
+ }
+
+ ret = voodoo_manager_request( data->manager, data->instance,
+ IDIRECTFBWINDOWS_METHOD_ID_RegisterWatcher, VREQ_RESPOND, &response,
+ VMBT_ID, registered->instance,
+ VMBT_UINT, mask,
+ VMBT_NONE );
+ if (ret) {
+ voodoo_manager_finish_request( data->manager, response );
+ goto error;
+ }
+
+ ret = response->result;
+
+ voodoo_manager_finish_request( data->manager, response );
+
+ if (ret)
+ goto error;
+
+
+ direct_list_append( &data->watchers, ®istered->link );
+
+ return DFB_OK;
+
+
+error:
+ if (registered->instance)
+ voodoo_manager_unregister_local( data->manager, registered->instance );
+
+ D_FREE( registered );
+
+ return ret;
+}
+
+/**********************************************************************************************************************/
+
+static DFBResult
+Probe()
+{
+ /* This implementation has to be loaded explicitly. */
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+Construct( IDirectFBWindows *thiz,
+ VoodooManager *manager,
+ VoodooInstanceID instance,
+ void *arg )
+{
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBWindows_Requestor)
+
+ data->ref = 1;
+ data->manager = manager;
+ data->instance = instance;
+ data->idirectfb = arg;
+
+ thiz->AddRef = IDirectFBWindows_Requestor_AddRef;
+ thiz->Release = IDirectFBWindows_Requestor_Release;
+ thiz->RegisterWatcher = IDirectFBWindows_Requestor_RegisterWatcher;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_requestor.h b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_requestor.h new file mode 100755 index 0000000..2d61e81 --- /dev/null +++ b/Source/DirectFB/interfaces/IDirectFBWindows/idirectfbwindows_requestor.h @@ -0,0 +1,58 @@ +/*
+ (c) Copyright 2001-2007 The DirectFB Organization (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBWINDOWS_REQUESTOR_H__
+#define __IDIRECTFBWINDOWS_REQUESTOR_H__
+
+#include <directfb.h>
+
+#include <voodoo/manager.h>
+
+#define IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowAdd 1
+#define IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowRemove 2
+#define IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowConfig 3
+#define IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowState 4
+#define IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowRestack 5
+#define IDIRECTFBWINDOWS_REQUESTOR_METHOD_ID_DispatchWatcher_WindowFocus 6
+
+/*
+ * private data struct of IDirectFBWindows_Requestor
+ */
+typedef struct {
+ int ref; /* reference counter */
+
+ IDirectFB *idirectfb;
+
+ VoodooManager *manager;
+ VoodooInstanceID instance;
+
+ DirectLink *watchers;
+} IDirectFBWindows_Requestor_data;
+
+#endif
+
diff --git a/Source/DirectFB/interfaces/Makefile.am b/Source/DirectFB/interfaces/Makefile.am new file mode 100755 index 0000000..6a3d7b1 --- /dev/null +++ b/Source/DirectFB/interfaces/Makefile.am @@ -0,0 +1,6 @@ +## Makefile.am for DirectFB/interfaces + +SUBDIRS = \ + IDirectFBFont \ + IDirectFBImageProvider \ + IDirectFBVideoProvider diff --git a/Source/DirectFB/interfaces/Makefile.in b/Source/DirectFB/interfaces/Makefile.in new file mode 100755 index 0000000..4d34421 --- /dev/null +++ b/Source/DirectFB/interfaces/Makefile.in @@ -0,0 +1,560 @@ +# 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@ +subdir = interfaces +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +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 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +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@ +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@ +SUBDIRS = \ + IDirectFBFont \ + IDirectFBImageProvider \ + IDirectFBVideoProvider + +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interfaces/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu interfaces/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 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + 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: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + 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: ctags-recursive $(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 + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-exec-am: + +install-html: install-html-recursive + +install-info: install-info-recursive + +install-man: + +install-pdf: install-pdf-recursive + +install-ps: install-ps-recursive + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ + install-strip + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive distclean 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-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + +# 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: |