summaryrefslogtreecommitdiff
path: root/Source/DirectFB/src
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2013-01-15 08:46:13 +0100
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2013-01-15 08:46:13 +0100
commit7fe60435bce6595a9c58a9bfd8244d74b5320e96 (patch)
tree1ac714a916e02fc90901ddac8bc2a3c6d051d28c /Source/DirectFB/src
downloaddirectfb-voodoo-7fe60435bce6595a9c58a9bfd8244d74b5320e96.tar.gz
directfb-voodoo-7fe60435bce6595a9c58a9bfd8244d74b5320e96.tar.bz2
directfb-voodoo-7fe60435bce6595a9c58a9bfd8244d74b5320e96.zip
Import DirectFB141_2k11R3_beta5
Diffstat (limited to 'Source/DirectFB/src')
-rwxr-xr-xSource/DirectFB/src/Makefile.am73
-rwxr-xr-xSource/DirectFB/src/Makefile.in745
-rwxr-xr-xSource/DirectFB/src/core/Makefile.am84
-rwxr-xr-xSource/DirectFB/src/core/Makefile.in648
-rwxr-xr-xSource/DirectFB/src/core/clipboard.c298
-rwxr-xr-xSource/DirectFB/src/core/clipboard.h53
-rwxr-xr-xSource/DirectFB/src/core/colorhash.c366
-rwxr-xr-xSource/DirectFB/src/core/colorhash.h54
-rwxr-xr-xSource/DirectFB/src/core/core.c1160
-rwxr-xr-xSource/DirectFB/src/core/core.h162
-rwxr-xr-xSource/DirectFB/src/core/core_parts.c202
-rwxr-xr-xSource/DirectFB/src/core/core_parts.h131
-rwxr-xr-xSource/DirectFB/src/core/core_system.h141
-rwxr-xr-xSource/DirectFB/src/core/coredefs.h48
-rwxr-xr-xSource/DirectFB/src/core/coretypes.h89
-rwxr-xr-xSource/DirectFB/src/core/fonts.c660
-rwxr-xr-xSource/DirectFB/src/core/fonts.h250
-rwxr-xr-xSource/DirectFB/src/core/gfxcard.c2921
-rwxr-xr-xSource/DirectFB/src/core/gfxcard.h470
-rwxr-xr-xSource/DirectFB/src/core/graphics_driver.h86
-rwxr-xr-xSource/DirectFB/src/core/input.c2668
-rwxr-xr-xSource/DirectFB/src/core/input.h203
-rwxr-xr-xSource/DirectFB/src/core/input_driver.h103
-rwxr-xr-xSource/DirectFB/src/core/layer_context.c1947
-rwxr-xr-xSource/DirectFB/src/core/layer_context.h149
-rwxr-xr-xSource/DirectFB/src/core/layer_control.c589
-rwxr-xr-xSource/DirectFB/src/core/layer_control.h72
-rwxr-xr-xSource/DirectFB/src/core/layer_region.c1129
-rwxr-xr-xSource/DirectFB/src/core/layer_region.h100
-rwxr-xr-xSource/DirectFB/src/core/layers.c640
-rwxr-xr-xSource/DirectFB/src/core/layers.h359
-rwxr-xr-xSource/DirectFB/src/core/layers_internal.h196
-rwxr-xr-xSource/DirectFB/src/core/local_surface_pool.c313
-rwxr-xr-xSource/DirectFB/src/core/palette.c317
-rwxr-xr-xSource/DirectFB/src/core/palette.h106
-rwxr-xr-xSource/DirectFB/src/core/prealloc_surface_pool.c192
-rwxr-xr-xSource/DirectFB/src/core/screen.c540
-rwxr-xr-xSource/DirectFB/src/core/screen.h122
-rwxr-xr-xSource/DirectFB/src/core/screens.c591
-rwxr-xr-xSource/DirectFB/src/core/screens.h263
-rwxr-xr-xSource/DirectFB/src/core/screens_internal.h81
-rwxr-xr-xSource/DirectFB/src/core/shared_surface_pool.c227
-rwxr-xr-xSource/DirectFB/src/core/state.c416
-rwxr-xr-xSource/DirectFB/src/core/state.h362
-rwxr-xr-xSource/DirectFB/src/core/surface.c768
-rwxr-xr-xSource/DirectFB/src/core/surface.h446
-rwxr-xr-xSource/DirectFB/src/core/surface_buffer.c1206
-rwxr-xr-xSource/DirectFB/src/core/surface_buffer.h257
-rwxr-xr-xSource/DirectFB/src/core/surface_core.c214
-rwxr-xr-xSource/DirectFB/src/core/surface_pool.c1263
-rwxr-xr-xSource/DirectFB/src/core/surface_pool.h272
-rwxr-xr-xSource/DirectFB/src/core/surface_pool_bridge.c531
-rwxr-xr-xSource/DirectFB/src/core/surface_pool_bridge.h187
-rwxr-xr-xSource/DirectFB/src/core/system.c464
-rwxr-xr-xSource/DirectFB/src/core/system.h258
-rwxr-xr-xSource/DirectFB/src/core/windows.c1908
-rwxr-xr-xSource/DirectFB/src/core/windows.h316
-rwxr-xr-xSource/DirectFB/src/core/windows_internal.h211
-rwxr-xr-xSource/DirectFB/src/core/windowstack.c998
-rwxr-xr-xSource/DirectFB/src/core/windowstack.h105
-rwxr-xr-xSource/DirectFB/src/core/wm.c1440
-rwxr-xr-xSource/DirectFB/src/core/wm.h468
-rwxr-xr-xSource/DirectFB/src/core/wm_module.h274
-rwxr-xr-xSource/DirectFB/src/directfb.c311
-rwxr-xr-xSource/DirectFB/src/display/Makefile.am30
-rwxr-xr-xSource/DirectFB/src/display/Makefile.in570
-rwxr-xr-xSource/DirectFB/src/display/idirectfbdisplaylayer.c1076
-rwxr-xr-xSource/DirectFB/src/display/idirectfbdisplaylayer.h43
-rwxr-xr-xSource/DirectFB/src/display/idirectfbpalette.c365
-rwxr-xr-xSource/DirectFB/src/display/idirectfbpalette.h51
-rwxr-xr-xSource/DirectFB/src/display/idirectfbscreen.c722
-rwxr-xr-xSource/DirectFB/src/display/idirectfbscreen.h42
-rwxr-xr-xSource/DirectFB/src/display/idirectfbsurface.c2841
-rwxr-xr-xSource/DirectFB/src/display/idirectfbsurface.h123
-rwxr-xr-xSource/DirectFB/src/display/idirectfbsurface_layer.c244
-rwxr-xr-xSource/DirectFB/src/display/idirectfbsurface_layer.h57
-rwxr-xr-xSource/DirectFB/src/display/idirectfbsurface_window.c353
-rwxr-xr-xSource/DirectFB/src/display/idirectfbsurface_window.h48
-rwxr-xr-xSource/DirectFB/src/gfx/Makefile.am29
-rwxr-xr-xSource/DirectFB/src/gfx/Makefile.in676
-rwxr-xr-xSource/DirectFB/src/gfx/clip.c379
-rwxr-xr-xSource/DirectFB/src/gfx/clip.h125
-rwxr-xr-xSource/DirectFB/src/gfx/convert.c1427
-rwxr-xr-xSource/DirectFB/src/gfx/convert.h562
-rwxr-xr-xSource/DirectFB/src/gfx/generic/Makefile.am62
-rwxr-xr-xSource/DirectFB/src/gfx/generic/Makefile.in602
-rwxr-xr-xSource/DirectFB/src/gfx/generic/duffs_device.h89
-rwxr-xr-xSource/DirectFB/src/gfx/generic/generic.c9161
-rwxr-xr-xSource/DirectFB/src/gfx/generic/generic.h174
-rwxr-xr-xSource/DirectFB/src/gfx/generic/generic_64.h207
-rwxr-xr-xSource/DirectFB/src/gfx/generic/generic_dummy.c94
-rwxr-xr-xSource/DirectFB/src/gfx/generic/generic_mmx.h659
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_hvx_16.h469
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_hvx_32.h174
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_hvx_8.h149
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_hvx_88.h152
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_hvx_N.h121
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_up_down_16.h68
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_up_down_32.h68
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_up_down_32_indexed.h82
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_up_down_8.h72
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_up_down_88.h72
-rwxr-xr-xSource/DirectFB/src/gfx/generic/stretch_up_down_table.h59
-rwxr-xr-xSource/DirectFB/src/gfx/generic/template_acc_16.h382
-rwxr-xr-xSource/DirectFB/src/gfx/generic/template_acc_32.h261
-rwxr-xr-xSource/DirectFB/src/gfx/generic/template_colorkey_16.h369
-rwxr-xr-xSource/DirectFB/src/gfx/generic/template_colorkey_32.h206
-rwxr-xr-xSource/DirectFB/src/gfx/generic/yuvtbl-gen.c199
-rwxr-xr-xSource/DirectFB/src/gfx/generic/yuvtbl.h296
-rwxr-xr-xSource/DirectFB/src/gfx/util.c270
-rwxr-xr-xSource/DirectFB/src/gfx/util.h42
-rwxr-xr-xSource/DirectFB/src/idirectfb.c1965
-rwxr-xr-xSource/DirectFB/src/idirectfb.h89
-rwxr-xr-xSource/DirectFB/src/input/Makefile.am22
-rwxr-xr-xSource/DirectFB/src/input/Makefile.in556
-rwxr-xr-xSource/DirectFB/src/input/idirectfbinputbuffer.c1121
-rwxr-xr-xSource/DirectFB/src/input/idirectfbinputbuffer.h56
-rwxr-xr-xSource/DirectFB/src/input/idirectfbinputdevice.c446
-rwxr-xr-xSource/DirectFB/src/input/idirectfbinputdevice.h40
-rwxr-xr-xSource/DirectFB/src/media/Makefile.am29
-rwxr-xr-xSource/DirectFB/src/media/Makefile.in570
-rwxr-xr-xSource/DirectFB/src/media/idirectfbdatabuffer.c264
-rwxr-xr-xSource/DirectFB/src/media/idirectfbdatabuffer.h104
-rwxr-xr-xSource/DirectFB/src/media/idirectfbdatabuffer_file.c297
-rwxr-xr-xSource/DirectFB/src/media/idirectfbdatabuffer_memory.c266
-rwxr-xr-xSource/DirectFB/src/media/idirectfbdatabuffer_streamed.c529
-rwxr-xr-xSource/DirectFB/src/media/idirectfbfont.c965
-rwxr-xr-xSource/DirectFB/src/media/idirectfbfont.h82
-rwxr-xr-xSource/DirectFB/src/media/idirectfbimageprovider.c167
-rwxr-xr-xSource/DirectFB/src/media/idirectfbimageprovider.h48
-rwxr-xr-xSource/DirectFB/src/media/idirectfbvideoprovider.c387
-rwxr-xr-xSource/DirectFB/src/media/idirectfbvideoprovider.h54
-rwxr-xr-xSource/DirectFB/src/misc/Makefile.am29
-rwxr-xr-xSource/DirectFB/src/misc/Makefile.in564
-rwxr-xr-xSource/DirectFB/src/misc/conf.c1947
-rwxr-xr-xSource/DirectFB/src/misc/conf.h287
-rwxr-xr-xSource/DirectFB/src/misc/dither565.h211
-rwxr-xr-xSource/DirectFB/src/misc/gfx_util.c964
-rwxr-xr-xSource/DirectFB/src/misc/gfx_util.h48
-rwxr-xr-xSource/DirectFB/src/misc/util.c471
-rwxr-xr-xSource/DirectFB/src/misc/util.h34
-rwxr-xr-xSource/DirectFB/src/windows/Makefile.am20
-rwxr-xr-xSource/DirectFB/src/windows/Makefile.in552
-rwxr-xr-xSource/DirectFB/src/windows/idirectfbwindow.c1446
-rwxr-xr-xSource/DirectFB/src/windows/idirectfbwindow.h44
145 files changed, 71219 insertions, 0 deletions
diff --git a/Source/DirectFB/src/Makefile.am b/Source/DirectFB/src/Makefile.am
new file mode 100755
index 0000000..8f506e6
--- /dev/null
+++ b/Source/DirectFB/src/Makefile.am
@@ -0,0 +1,73 @@
+## Makefile.am for DirectFB/src
+
+SUBDIRS = core display gfx input media misc windows
+
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+AM_CPPFLAGS = \
+ -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" \
+ -DMODULEDIR=\"${RUNTIME_SYSROOT}@MODULEDIR@\"
+
+
+internalincludedir = $(INTERNALINCLUDEDIR)
+
+internalinclude_HEADERS = \
+ idirectfb.h
+
+
+lib_LTLIBRARIES = libdirectfb.la
+
+libdirectfb_la_SOURCES = \
+ directfb.c \
+ idirectfb.c
+
+libdirectfb_la_LDFLAGS = \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -release $(LT_RELEASE) \
+ $(DFB_LDFLAGS)
+
+libdirectfb_la_LIBADD = \
+ display/libdirectfb_display.la \
+ media/libdirectfb_media.la \
+ windows/libdirectfb_windows.la \
+ input/libdirectfb_input.la \
+ misc/libdirectfb_misc.la \
+ gfx/libdirectfb_gfx.la \
+ core/libdirectfb_core.la \
+ ../lib/direct/libdirect.la \
+ ../lib/fusion/libfusion.la
+
+
+#
+## and now rebuild the static version with the *correct* object files
+#
+if BUILD_STATIC
+
+clean-local:
+ rm -f libdirectfb_fixed.a
+
+all-local: libdirectfb_fixed.a
+
+libdirectfb_fixed.a: .libs/libdirectfb.a
+ rm -f libdirectfb_fixed.a
+ ${AR} cru libdirectfb_fixed.a `find . -name "*.o" | grep -v '.libs'`
+ ${RANLIB} libdirectfb_fixed.a
+ cp -pf libdirectfb_fixed.a .libs/libdirectfb.a
+
+.libs/libdirectfb.a: libdirectfb.la
+
+else
+
+clean-local:
+
+all-local:
+
+endif
+
+
+include $(top_srcdir)/rules/nmfile.make
diff --git a/Source/DirectFB/src/Makefile.in b/Source/DirectFB/src/Makefile.in
new file mode 100755
index 0000000..9fb3b04
--- /dev/null
+++ b/Source/DirectFB/src/Makefile.in
@@ -0,0 +1,745 @@
+# 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 = $(internalinclude_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(top_srcdir)/rules/nmfile.make
+subdir = src
+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)$(libdir)" \
+ "$(DESTDIR)$(internalincludedir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libdirectfb_la_DEPENDENCIES = display/libdirectfb_display.la \
+ media/libdirectfb_media.la windows/libdirectfb_windows.la \
+ input/libdirectfb_input.la misc/libdirectfb_misc.la \
+ gfx/libdirectfb_gfx.la core/libdirectfb_core.la \
+ ../lib/direct/libdirect.la ../lib/fusion/libfusion.la
+am_libdirectfb_la_OBJECTS = directfb.lo idirectfb.lo
+libdirectfb_la_OBJECTS = $(am_libdirectfb_la_OBJECTS)
+libdirectfb_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libdirectfb_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libdirectfb_la_SOURCES)
+DIST_SOURCES = $(libdirectfb_la_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
+internalincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(internalinclude_HEADERS)
+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 = core display gfx input media misc windows
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+AM_CPPFLAGS = \
+ -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" \
+ -DMODULEDIR=\"${RUNTIME_SYSROOT}@MODULEDIR@\"
+
+internalincludedir = $(INTERNALINCLUDEDIR)
+internalinclude_HEADERS = \
+ idirectfb.h
+
+lib_LTLIBRARIES = libdirectfb.la
+libdirectfb_la_SOURCES = \
+ directfb.c \
+ idirectfb.c
+
+libdirectfb_la_LDFLAGS = \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -release $(LT_RELEASE) \
+ $(DFB_LDFLAGS)
+
+libdirectfb_la_LIBADD = \
+ display/libdirectfb_display.la \
+ media/libdirectfb_media.la \
+ windows/libdirectfb_windows.la \
+ input/libdirectfb_input.la \
+ misc/libdirectfb_misc.la \
+ gfx/libdirectfb_gfx.la \
+ core/libdirectfb_core.la \
+ ../lib/direct/libdirect.la \
+ ../lib/fusion/libfusion.la
+
+@BUILD_SHARED_TRUE@@ENABLE_TRACE_TRUE@LIBTONM = $(LTLIBRARIES:.la=-$(LT_RELEASE).so.$(LT_BINARY))
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/rules/nmfile.make $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/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-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libdirectfb.la: $(libdirectfb_la_OBJECTS) $(libdirectfb_la_DEPENDENCIES)
+ $(libdirectfb_la_LINK) -rpath $(libdir) $(libdirectfb_la_OBJECTS) $(libdirectfb_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/directfb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfb.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-internalincludeHEADERS: $(internalinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(internalincludedir)" || $(MKDIR_P) "$(DESTDIR)$(internalincludedir)"
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(internalincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ $(internalincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+uninstall-internalincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+# 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 $(LTLIBRARIES) $(HEADERS) all-local
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(internalincludedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+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."
+@BUILD_SHARED_FALSE@install-data-local:
+@ENABLE_TRACE_FALSE@install-data-local:
+clean: clean-recursive
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-data-local install-internalincludeHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-exec-am: install-libLTLIBRARIES
+
+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 -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-internalincludeHEADERS \
+ uninstall-libLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
+ install-strip
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am all-local check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-local ctags \
+ ctags-recursive distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-local install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-internalincludeHEADERS \
+ install-libLTLIBRARIES 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-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am \
+ uninstall-internalincludeHEADERS uninstall-libLTLIBRARIES
+
+
+#
+#
+
+@BUILD_STATIC_TRUE@clean-local:
+@BUILD_STATIC_TRUE@ rm -f libdirectfb_fixed.a
+
+@BUILD_STATIC_TRUE@all-local: libdirectfb_fixed.a
+
+@BUILD_STATIC_TRUE@libdirectfb_fixed.a: .libs/libdirectfb.a
+@BUILD_STATIC_TRUE@ rm -f libdirectfb_fixed.a
+@BUILD_STATIC_TRUE@ ${AR} cru libdirectfb_fixed.a `find . -name "*.o" | grep -v '.libs'`
+@BUILD_STATIC_TRUE@ ${RANLIB} libdirectfb_fixed.a
+@BUILD_STATIC_TRUE@ cp -pf libdirectfb_fixed.a .libs/libdirectfb.a
+
+@BUILD_STATIC_TRUE@.libs/libdirectfb.a: libdirectfb.la
+
+@BUILD_STATIC_FALSE@clean-local:
+
+@BUILD_STATIC_FALSE@all-local:
+
+@BUILD_SHARED_TRUE@@ENABLE_TRACE_TRUE@install-data-local:
+@BUILD_SHARED_TRUE@@ENABLE_TRACE_TRUE@ mkdir -p -- "$(DESTDIR)$(libdir)"
+@BUILD_SHARED_TRUE@@ENABLE_TRACE_TRUE@ nm -n ".libs/$(LIBTONM)" > "$(DESTDIR)$(libdir)/nm-n.$(LIBTONM)"
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Source/DirectFB/src/core/Makefile.am b/Source/DirectFB/src/core/Makefile.am
new file mode 100755
index 0000000..e387345
--- /dev/null
+++ b/Source/DirectFB/src/core/Makefile.am
@@ -0,0 +1,84 @@
+## Makefile.am for DirectFB/src/core
+
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+AM_CPPFLAGS = \
+ -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" \
+ -DSOPATH=\"@SOPATH@\" \
+ -DMODULEDIR=\"${RUNTIME_SYSROOT}@MODULEDIR@\" \
+ "-DBUILDTIME=\"`date -u "+%Y-%m-%d %H:%M"`\""
+
+
+internalincludedir = $(INTERNALINCLUDEDIR)/core
+
+internalinclude_HEADERS = \
+ clipboard.h \
+ colorhash.h \
+ coredefs.h \
+ coretypes.h \
+ core_parts.h \
+ core_system.h \
+ core.h \
+ fonts.h \
+ gfxcard.h \
+ graphics_driver.h \
+ input.h \
+ input_driver.h \
+ layer_context.h \
+ layer_control.h \
+ layer_region.h \
+ layers.h \
+ layers_internal.h \
+ palette.h \
+ screen.h \
+ screens.h \
+ screens_internal.h \
+ state.h \
+ surface.h \
+ surface_buffer.h \
+ surface_pool.h \
+ surface_pool_bridge.h \
+ system.h \
+ windows.h \
+ windows_internal.h \
+ windowstack.h \
+ wm.h \
+ wm_module.h
+
+
+noinst_LTLIBRARIES = libdirectfb_core.la
+
+
+libdirectfb_core_la_SOURCES = \
+ clipboard.c \
+ colorhash.c \
+ core.c \
+ core_parts.c \
+ fonts.c \
+ gfxcard.c \
+ input.c \
+ layer_context.c \
+ layer_control.c \
+ layer_region.c \
+ layers.c \
+ local_surface_pool.c \
+ palette.c \
+ prealloc_surface_pool.c \
+ screen.c \
+ screens.c \
+ shared_surface_pool.c \
+ state.c \
+ surface.c \
+ surface_buffer.c \
+ surface_core.c \
+ surface_pool.c \
+ surface_pool_bridge.c \
+ system.c \
+ windows.c \
+ windowstack.c \
+ wm.c
diff --git a/Source/DirectFB/src/core/Makefile.in b/Source/DirectFB/src/core/Makefile.in
new file mode 100755
index 0000000..9955d0b
--- /dev/null
+++ b/Source/DirectFB/src/core/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@
+subdir = src/core
+DIST_COMMON = $(internalinclude_HEADERS) $(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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libdirectfb_core_la_LIBADD =
+am_libdirectfb_core_la_OBJECTS = clipboard.lo colorhash.lo core.lo \
+ core_parts.lo fonts.lo gfxcard.lo input.lo layer_context.lo \
+ layer_control.lo layer_region.lo layers.lo \
+ local_surface_pool.lo palette.lo prealloc_surface_pool.lo \
+ screen.lo screens.lo shared_surface_pool.lo state.lo \
+ surface.lo surface_buffer.lo surface_core.lo surface_pool.lo \
+ surface_pool_bridge.lo system.lo windows.lo windowstack.lo \
+ wm.lo
+libdirectfb_core_la_OBJECTS = $(am_libdirectfb_core_la_OBJECTS)
+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 = $(libdirectfb_core_la_SOURCES)
+DIST_SOURCES = $(libdirectfb_core_la_SOURCES)
+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)$(internalincludedir)"
+internalincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(internalinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+AM_CPPFLAGS = \
+ -DDATADIR=\"${RUNTIME_SYSROOT}@DATADIR@\" \
+ -DSOPATH=\"@SOPATH@\" \
+ -DMODULEDIR=\"${RUNTIME_SYSROOT}@MODULEDIR@\" \
+ "-DBUILDTIME=\"`date -u "+%Y-%m-%d %H:%M"`\""
+
+internalincludedir = $(INTERNALINCLUDEDIR)/core
+internalinclude_HEADERS = \
+ clipboard.h \
+ colorhash.h \
+ coredefs.h \
+ coretypes.h \
+ core_parts.h \
+ core_system.h \
+ core.h \
+ fonts.h \
+ gfxcard.h \
+ graphics_driver.h \
+ input.h \
+ input_driver.h \
+ layer_context.h \
+ layer_control.h \
+ layer_region.h \
+ layers.h \
+ layers_internal.h \
+ palette.h \
+ screen.h \
+ screens.h \
+ screens_internal.h \
+ state.h \
+ surface.h \
+ surface_buffer.h \
+ surface_pool.h \
+ surface_pool_bridge.h \
+ system.h \
+ windows.h \
+ windows_internal.h \
+ windowstack.h \
+ wm.h \
+ wm_module.h
+
+noinst_LTLIBRARIES = libdirectfb_core.la
+libdirectfb_core_la_SOURCES = \
+ clipboard.c \
+ colorhash.c \
+ core.c \
+ core_parts.c \
+ fonts.c \
+ gfxcard.c \
+ input.c \
+ layer_context.c \
+ layer_control.c \
+ layer_region.c \
+ layers.c \
+ local_surface_pool.c \
+ palette.c \
+ prealloc_surface_pool.c \
+ screen.c \
+ screens.c \
+ shared_surface_pool.c \
+ state.c \
+ surface.c \
+ surface_buffer.c \
+ surface_core.c \
+ surface_pool.c \
+ surface_pool_bridge.c \
+ system.c \
+ windows.c \
+ windowstack.c \
+ wm.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 src/core/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/core/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
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_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
+libdirectfb_core.la: $(libdirectfb_core_la_OBJECTS) $(libdirectfb_core_la_DEPENDENCIES)
+ $(LINK) $(libdirectfb_core_la_OBJECTS) $(libdirectfb_core_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clipboard.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/colorhash.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_parts.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fonts.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gfxcard.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/input.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layer_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layer_control.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layer_region.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/layers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local_surface_pool.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/palette.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prealloc_surface_pool.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screens.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shared_surface_pool.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surface_buffer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surface_core.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surface_pool.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surface_pool_bridge.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/windows.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/windowstack.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wm.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-internalincludeHEADERS: $(internalinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(internalincludedir)" || $(MKDIR_P) "$(DESTDIR)$(internalincludedir)"
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(internalincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ $(internalincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+uninstall-internalincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(internalincludedir)/$$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) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(internalincludedir)"; 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-libtool clean-noinstLTLIBRARIES \
+ 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-internalincludeHEADERS
+
+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-internalincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES 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-info install-info-am \
+ install-internalincludeHEADERS 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-internalincludeHEADERS
+
+# 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/src/core/clipboard.c b/Source/DirectFB/src/core/clipboard.c
new file mode 100755
index 0000000..53fde34
--- /dev/null
+++ b/Source/DirectFB/src/core/clipboard.c
@@ -0,0 +1,298 @@
+/*
+ (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 <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/memcpy.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/core_parts.h>
+#include <core/clipboard.h>
+
+
+D_DEBUG_DOMAIN( Core_Clipboard, "Core/Clipboard", "DirectFB Clipboard Core" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+ FusionSkirmish lock;
+ char *mime_type;
+ void *data;
+ unsigned int size;
+ struct timeval timestamp;
+
+ FusionSHMPoolShared *shmpool;
+} DFBClipboardCoreShared;
+
+struct __DFB_DFBClipboardCore {
+ int magic;
+
+ CoreDFB *core;
+
+ DFBClipboardCoreShared *shared;
+};
+
+
+DFB_CORE_PART( clipboard_core, ClipboardCore );
+
+/**********************************************************************************************************************/
+
+static DFBResult
+dfb_clipboard_core_initialize( CoreDFB *core,
+ DFBClipboardCore *data,
+ DFBClipboardCoreShared *shared )
+{
+ D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_initialize( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( shared != NULL );
+
+ data->core = core;
+ data->shared = shared;
+
+ shared->shmpool = dfb_core_shmpool( core );
+
+ fusion_skirmish_init( &shared->lock, "Clipboard Core", dfb_core_world(core) );
+
+ D_MAGIC_SET( data, DFBClipboardCore );
+ D_MAGIC_SET( shared, DFBClipboardCoreShared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_clipboard_core_join( CoreDFB *core,
+ DFBClipboardCore *data,
+ DFBClipboardCoreShared *shared )
+{
+ D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_join( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_MAGIC_ASSERT( shared, DFBClipboardCoreShared );
+
+ data->core = core;
+ data->shared = shared;
+
+ D_MAGIC_SET( data, DFBClipboardCore );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_clipboard_core_shutdown( DFBClipboardCore *data,
+ bool emergency )
+{
+ DFBClipboardCoreShared *shared;
+
+ D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBClipboardCore );
+
+ shared = data->shared;
+
+ D_MAGIC_ASSERT( shared, DFBClipboardCoreShared );
+
+ fusion_skirmish_destroy( &shared->lock );
+
+ if (shared->data)
+ SHFREE( shared->shmpool, shared->data );
+
+ if (shared->mime_type)
+ SHFREE( shared->shmpool, shared->mime_type );
+
+ D_MAGIC_CLEAR( data );
+ D_MAGIC_CLEAR( shared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_clipboard_core_leave( DFBClipboardCore *data,
+ bool emergency )
+{
+ D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBClipboardCore );
+ D_MAGIC_ASSERT( data->shared, DFBClipboardCoreShared );
+
+ D_MAGIC_CLEAR( data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_clipboard_core_suspend( DFBClipboardCore *data )
+{
+ D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_suspend( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBClipboardCore );
+ D_MAGIC_ASSERT( data->shared, DFBClipboardCoreShared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_clipboard_core_resume( DFBClipboardCore *data )
+{
+ D_DEBUG_AT( Core_Clipboard, "dfb_clipboard_core_resume( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBClipboardCore );
+ D_MAGIC_ASSERT( data->shared, DFBClipboardCoreShared );
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_clipboard_set( DFBClipboardCore *core,
+ const char *mime_type,
+ const void *data,
+ unsigned int size,
+ struct timeval *timestamp )
+{
+ DFBClipboardCoreShared *shared;
+
+ char *new_mime;
+ void *new_data;
+
+ D_MAGIC_ASSERT( core, DFBClipboardCore );
+ D_ASSERT( mime_type != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( size > 0 );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, DFBClipboardCoreShared );
+
+ new_mime = SHSTRDUP( shared->shmpool, mime_type );
+ if (!new_mime)
+ return D_OOSHM();
+
+ new_data = SHMALLOC( shared->shmpool, size );
+ if (!new_data) {
+ SHFREE( shared->shmpool, new_mime );
+ return D_OOSHM();
+ }
+
+ direct_memcpy( new_data, data, size );
+
+ if (fusion_skirmish_prevail( &shared->lock )) {
+ SHFREE( shared->shmpool, new_data );
+ SHFREE( shared->shmpool, new_mime );
+ return DFB_FUSION;
+ }
+
+ if (shared->data)
+ SHFREE( shared->shmpool, shared->data );
+
+ if (shared->mime_type)
+ SHFREE( shared->shmpool, shared->mime_type );
+
+ shared->mime_type = new_mime;
+ shared->data = new_data;
+ shared->size = size;
+
+ gettimeofday( &shared->timestamp, NULL );
+
+ if (timestamp)
+ *timestamp = shared->timestamp;
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_clipboard_get( DFBClipboardCore *core,
+ char **mime_type,
+ void **data,
+ unsigned int *size )
+{
+ DFBClipboardCoreShared *shared;
+
+ D_MAGIC_ASSERT( core, DFBClipboardCore );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, DFBClipboardCoreShared );
+
+ if (fusion_skirmish_prevail( &shared->lock ))
+ return DFB_FUSION;
+
+ if (!shared->mime_type || !shared->data) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_BUFFEREMPTY;
+ }
+
+ if (mime_type)
+ *mime_type = strdup( shared->mime_type );
+
+ if (data) {
+ *data = malloc( shared->size );
+ direct_memcpy( *data, shared->data, shared->size );
+ }
+
+ if (size)
+ *size = shared->size;
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_clipboard_get_timestamp( DFBClipboardCore *core,
+ struct timeval *timestamp )
+{
+ DFBClipboardCoreShared *shared;
+
+ D_MAGIC_ASSERT( core, DFBClipboardCore );
+ D_ASSERT( timestamp != NULL );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, DFBClipboardCoreShared );
+
+ if (fusion_skirmish_prevail( &shared->lock ))
+ return DFB_FUSION;
+
+ *timestamp = shared->timestamp;
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/core/clipboard.h b/Source/DirectFB/src/core/clipboard.h
new file mode 100755
index 0000000..ffb9c43
--- /dev/null
+++ b/Source/DirectFB/src/core/clipboard.h
@@ -0,0 +1,53 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__CLIPBOARD_H__
+#define __CORE__CLIPBOARD_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+
+DFBResult dfb_clipboard_set( DFBClipboardCore *core,
+ const char *mime_type,
+ const void *data,
+ unsigned int size,
+ struct timeval *timestamp );
+
+DFBResult dfb_clipboard_get( DFBClipboardCore *core,
+ char **mime_type,
+ void **data,
+ unsigned int *size );
+
+
+DFBResult dfb_clipboard_get_timestamp( DFBClipboardCore *core,
+ struct timeval *timestamp );
+
+#endif
+
diff --git a/Source/DirectFB/src/core/colorhash.c b/Source/DirectFB/src/core/colorhash.c
new file mode 100755
index 0000000..370697d
--- /dev/null
+++ b/Source/DirectFB/src/core/colorhash.c
@@ -0,0 +1,366 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/debug.h>
+#include <direct/memcpy.h>
+
+#include <fusion/arena.h>
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/core_parts.h>
+#include <core/palette.h>
+#include <core/colorhash.h>
+
+#include <misc/util.h>
+#include <gfx/convert.h>
+
+
+D_DEBUG_DOMAIN( Core_ColorHash, "Core/ColorHash", "DirectFB ColorHash Core" );
+
+
+#define HASH_SIZE 823
+
+typedef struct {
+ unsigned int pixel;
+ unsigned int index;
+ CorePalette *palette;
+} Colorhash;
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+ Colorhash *hash;
+ unsigned int hash_users;
+ FusionSkirmish hash_lock;
+
+ FusionSHMPoolShared *shmpool;
+} DFBColorHashCoreShared;
+
+struct __DFB_DFBColorHashCore {
+ int magic;
+
+ CoreDFB *core;
+
+ DFBColorHashCoreShared *shared;
+};
+
+DFB_CORE_PART( colorhash_core, ColorHashCore );
+
+/**********************************************************************************************************************/
+
+static DFBColorHashCore *core_colorhash; /* FIXME */
+
+
+static DFBResult
+dfb_colorhash_core_initialize( CoreDFB *core,
+ DFBColorHashCore *data,
+ DFBColorHashCoreShared *shared )
+{
+ D_DEBUG_AT( Core_ColorHash, "dfb_colorhash_core_initialize( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( shared != NULL );
+
+ core_colorhash = data; /* FIXME */
+
+ data->core = core;
+ data->shared = shared;
+
+ shared->shmpool = dfb_core_shmpool( core );
+
+ fusion_skirmish_init( &shared->hash_lock, "Colorhash Core", dfb_core_world(core) );
+
+ D_MAGIC_SET( data, DFBColorHashCore );
+ D_MAGIC_SET( shared, DFBColorHashCoreShared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_colorhash_core_join( CoreDFB *core,
+ DFBColorHashCore *data,
+ DFBColorHashCoreShared *shared )
+{
+ D_DEBUG_AT( Core_ColorHash, "dfb_colorhash_core_join( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_MAGIC_ASSERT( shared, DFBColorHashCoreShared );
+
+ core_colorhash = data; /* FIXME */
+
+ data->core = core;
+ data->shared = shared;
+
+ D_MAGIC_SET( data, DFBColorHashCore );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_colorhash_core_shutdown( DFBColorHashCore *data,
+ bool emergency )
+{
+ DFBColorHashCoreShared *shared;
+
+ D_DEBUG_AT( Core_ColorHash, "dfb_colorhash_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBColorHashCore );
+ D_MAGIC_ASSERT( data->shared, DFBColorHashCoreShared );
+
+ shared = data->shared;
+
+ fusion_skirmish_destroy( &shared->hash_lock );
+
+ D_MAGIC_CLEAR( data );
+ D_MAGIC_CLEAR( shared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_colorhash_core_leave( DFBColorHashCore *data,
+ bool emergency )
+{
+ DFBColorHashCoreShared *shared;
+
+ D_DEBUG_AT( Core_ColorHash, "dfb_colorhash_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBColorHashCore );
+ D_MAGIC_ASSERT( data->shared, DFBColorHashCoreShared );
+
+ shared = data->shared;
+
+ D_MAGIC_CLEAR( data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_colorhash_core_suspend( DFBColorHashCore *data )
+{
+ DFBColorHashCoreShared *shared;
+
+ D_DEBUG_AT( Core_ColorHash, "dfb_colorhash_core_suspend( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBColorHashCore );
+ D_MAGIC_ASSERT( data->shared, DFBColorHashCoreShared );
+
+ shared = data->shared;
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_colorhash_core_resume( DFBColorHashCore *data )
+{
+ DFBColorHashCoreShared *shared;
+
+ D_DEBUG_AT( Core_ColorHash, "dfb_colorhash_core_resume( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBColorHashCore );
+ D_MAGIC_ASSERT( data->shared, DFBColorHashCoreShared );
+
+ shared = data->shared;
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+void
+dfb_colorhash_attach( DFBColorHashCore *core,
+ CorePalette *palette )
+{
+ DFBColorHashCoreShared *shared;
+
+ D_ASSUME( core != NULL );
+
+ if (core) {
+ D_MAGIC_ASSERT( core, DFBColorHashCore );
+ D_MAGIC_ASSERT( core->shared, DFBColorHashCoreShared );
+ }
+ else
+ core = core_colorhash;
+
+ shared = core->shared;
+
+ fusion_skirmish_prevail( &shared->hash_lock );
+
+ if (!shared->hash) {
+ D_ASSERT( shared->hash_users == 0 );
+
+ shared->hash = SHCALLOC( shared->shmpool, HASH_SIZE, sizeof (Colorhash) );
+ }
+
+ shared->hash_users++;
+
+ fusion_skirmish_dismiss( &shared->hash_lock );
+}
+
+void
+dfb_colorhash_detach( DFBColorHashCore *core,
+ CorePalette *palette )
+{
+ DFBColorHashCoreShared *shared;
+
+ D_ASSUME( core != NULL );
+
+ if (core) {
+ D_MAGIC_ASSERT( core, DFBColorHashCore );
+ D_MAGIC_ASSERT( core->shared, DFBColorHashCoreShared );
+ }
+ else
+ core = core_colorhash;
+
+ shared = core->shared;
+
+ D_ASSERT( shared->hash_users > 0 );
+ D_ASSERT( shared->hash != NULL );
+
+ fusion_skirmish_prevail( &shared->hash_lock );
+
+ shared->hash_users--;
+
+ if (!shared->hash_users) {
+ /* no more users, free allocated resources */
+ SHFREE( shared->shmpool, shared->hash );
+ shared->hash = NULL;
+ }
+
+ fusion_skirmish_dismiss( &shared->hash_lock );
+}
+
+unsigned int
+dfb_colorhash_lookup( DFBColorHashCore *core,
+ CorePalette *palette,
+ u8 r,
+ u8 g,
+ u8 b,
+ u8 a )
+{
+ unsigned int pixel = PIXEL_ARGB(a, r, g, b);
+ unsigned int index = (pixel ^ (unsigned long) palette) % HASH_SIZE;
+ DFBColorHashCoreShared *shared;
+
+// D_ASSUME( core != NULL );
+
+ if (core) {
+ D_MAGIC_ASSERT( core, DFBColorHashCore );
+ D_MAGIC_ASSERT( core->shared, DFBColorHashCoreShared );
+ }
+ else
+ core = core_colorhash;
+
+ shared = core->shared;
+
+ D_ASSERT( shared->hash != NULL );
+
+ fusion_skirmish_prevail( &shared->hash_lock );
+
+ /* try a lookup in the hash table */
+ if (shared->hash[index].palette == palette && shared->hash[index].pixel == pixel) {
+ /* set the return value */
+ index = shared->hash[index].index;
+ } else { /* look for the closest match */
+ DFBColor *entries = palette->entries;
+ int min_diff = 0;
+ unsigned int i, min_index = 0;
+
+ for (i = 0; i < palette->num_entries; i++) {
+ int diff;
+
+ int r_diff = (int) entries[i].r - (int) r;
+ int g_diff = (int) entries[i].g - (int) g;
+ int b_diff = (int) entries[i].b - (int) b;
+ int a_diff = (int) entries[i].a - (int) a;
+
+ if (a)
+ diff = (r_diff * r_diff + g_diff * g_diff +
+ b_diff * b_diff + ((a_diff * a_diff) >> 6));
+ else
+ diff = (r_diff + g_diff + b_diff + (a_diff * a_diff));
+
+ if (i == 0 || diff < min_diff) {
+ min_diff = diff;
+ min_index = i;
+ }
+
+ if (!diff)
+ break;
+ }
+
+ /* store the matching entry in the hash table */
+ shared->hash[index].pixel = pixel;
+ shared->hash[index].index = min_index;
+ shared->hash[index].palette = palette;
+
+ /* set the return value */
+ index = min_index;
+ }
+
+ fusion_skirmish_dismiss( &shared->hash_lock );
+
+ return index;
+}
+
+void
+dfb_colorhash_invalidate( DFBColorHashCore *core,
+ CorePalette *palette )
+{
+ unsigned int index = HASH_SIZE - 1;
+ DFBColorHashCoreShared *shared;
+
+ D_ASSUME( core != NULL );
+
+ if (core) {
+ D_MAGIC_ASSERT( core, DFBColorHashCore );
+ D_MAGIC_ASSERT( core->shared, DFBColorHashCoreShared );
+ }
+ else
+ core = core_colorhash;
+
+ shared = core->shared;
+
+ D_ASSERT( shared->hash != NULL );
+
+ fusion_skirmish_prevail( &shared->hash_lock );
+
+ /* invalidate all entries owned by this palette */
+ do {
+ if (shared->hash[index].palette == palette)
+ shared->hash[index].palette = NULL;
+ } while (index--);
+
+ fusion_skirmish_dismiss( &shared->hash_lock );
+}
+
diff --git a/Source/DirectFB/src/core/colorhash.h b/Source/DirectFB/src/core/colorhash.h
new file mode 100755
index 0000000..d321000
--- /dev/null
+++ b/Source/DirectFB/src/core/colorhash.h
@@ -0,0 +1,54 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__COLORHASH_H__
+#define __CORE__COLORHASH_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+
+void dfb_colorhash_attach ( DFBColorHashCore *core,
+ CorePalette *palette );
+
+void dfb_colorhash_detach ( DFBColorHashCore *core,
+ CorePalette *palette );
+
+unsigned int dfb_colorhash_lookup ( DFBColorHashCore *core,
+ CorePalette *palette,
+ u8 r,
+ u8 g,
+ u8 b,
+ u8 a);
+
+void dfb_colorhash_invalidate( DFBColorHashCore *core,
+ CorePalette *palette );
+
+#endif
+
diff --git a/Source/DirectFB/src/core/core.c b/Source/DirectFB/src/core/core.c
new file mode 100755
index 0000000..ca20152
--- /dev/null
+++ b/Source/DirectFB/src/core/core.c
@@ -0,0 +1,1160 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <errno.h>
+
+#include <pthread.h>
+
+#include <fusion/fusion.h>
+#include <fusion/arena.h>
+#include <direct/list.h>
+#include <fusion/shmalloc.h>
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/core.h>
+#include <core/core_parts.h>
+#include <core/layer_context.h>
+#include <core/layer_region.h>
+#include <core/palette.h>
+#include <core/surface.h>
+#include <core/system.h>
+#include <core/windows.h>
+#include <core/windows_internal.h>
+
+#include <direct/build.h>
+#include <direct/debug.h>
+#include <direct/direct.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/signals.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <fusion/build.h>
+#include <fusion/conf.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+D_DEBUG_DOMAIN( DirectFB_Core, "DirectFB/Core", "DirectFB Core" );
+
+/******************************************************************************/
+
+extern CorePart dfb_clipboard_core;
+extern CorePart dfb_colorhash_core;
+extern CorePart dfb_graphics_core;
+extern CorePart dfb_input_core;
+extern CorePart dfb_layer_core;
+extern CorePart dfb_screen_core;
+extern CorePart dfb_surface_core;
+extern CorePart dfb_system_core;
+extern CorePart dfb_wm_core;
+
+static CorePart *core_parts[] = {
+ &dfb_clipboard_core,
+ &dfb_colorhash_core,
+ &dfb_surface_core,
+ &dfb_system_core,
+ &dfb_input_core,
+ &dfb_graphics_core,
+ &dfb_screen_core,
+ &dfb_layer_core,
+ &dfb_wm_core
+};
+
+void *
+dfb_core_get_part( CoreDFB *core,
+ DFBCorePartID part_id )
+{
+ switch (part_id) {
+ case DFCP_CLIPBOARD:
+ return dfb_clipboard_core.data_local;
+
+ case DFCP_COLORHASH:
+ return dfb_colorhash_core.data_local;
+
+ case DFCP_GRAPHICS:
+ return dfb_graphics_core.data_local;
+
+ case DFCP_INPUT:
+ return dfb_input_core.data_local;
+
+ case DFCP_LAYER:
+ return dfb_layer_core.data_local;
+
+ case DFCP_SCREEN:
+ return dfb_screen_core.data_local;
+
+ case DFCP_SURFACE:
+ return dfb_surface_core.data_local;
+
+ case DFCP_SYSTEM:
+ return dfb_system_core.data_local;
+
+ case DFCP_WM:
+ return dfb_wm_core.data_local;
+
+ default:
+ D_BUG( "unknown core part" );
+ }
+
+ return NULL;
+}
+
+/******************************************************************************/
+
+/*
+ * one entry in the cleanup stack
+ */
+struct _CoreCleanup {
+ DirectLink link;
+
+ CoreCleanupFunc func; /* the cleanup function to be called */
+ void *data; /* context of the cleanup function */
+ bool emergency; /* if true, cleanup is also done during
+ emergency shutdown (from signal hadler) */
+};
+
+/******************************************************************************/
+
+struct __DFB_CoreDFBShared {
+ int magic;
+
+ FusionSkirmish lock;
+ bool active;
+
+ FusionObjectPool *layer_context_pool;
+ FusionObjectPool *layer_region_pool;
+ FusionObjectPool *palette_pool;
+ FusionObjectPool *surface_pool;
+ FusionObjectPool *window_pool;
+
+ FusionSHMPoolShared *shmpool;
+ FusionSHMPoolShared *shmpool_data; /* for raw data, e.g. surface buffers */
+};
+
+struct __DFB_CoreDFB {
+ int magic;
+
+ int refs;
+
+ int fusion_id;
+
+ FusionWorld *world;
+ FusionArena *arena;
+
+ CoreDFBShared *shared;
+
+ bool master;
+ bool suspended;
+
+ DirectLink *cleanups;
+
+ DirectThreadInitHandler *init_handler;
+
+ DirectSignalHandler *signal_handler;
+
+ DirectCleanupHandler *cleanup_handler;
+};
+
+/******************************************************************************/
+
+/*
+ * ckecks if stack is clean, otherwise prints warning, then calls core_deinit()
+ */
+static void dfb_core_deinit_check( void *ctx );
+
+static void dfb_core_thread_init_handler( DirectThread *thread, void *arg );
+
+static void dfb_core_process_cleanups( CoreDFB *core, bool emergency );
+
+static DirectSignalHandlerResult dfb_core_signal_handler( int num,
+ void *addr,
+ void *ctx );
+
+/******************************************************************************/
+
+static int dfb_core_arena_initialize( FusionArena *arena,
+ void *ctx );
+static int dfb_core_arena_shutdown ( FusionArena *arena,
+ void *ctx,
+ bool emergency );
+static int dfb_core_arena_join ( FusionArena *arena,
+ void *ctx );
+static int dfb_core_arena_leave ( FusionArena *arena,
+ void *ctx,
+ bool emergency );
+
+/******************************************************************************/
+
+#if defined(DFB_DYNAMIC_LINKING) && defined(SOPATH)
+/*
+ * the library handle for dlopen'ing ourselves
+ */
+static void* dfb_lib_handle = NULL;
+#endif
+
+/******************************************************************************/
+
+static CoreDFB *core_dfb = NULL;
+static pthread_mutex_t core_dfb_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/******************************************************************************/
+
+DFBResult
+dfb_core_create( CoreDFB **ret_core )
+{
+ int ret;
+#if FUSION_BUILD_MULTI
+ char buf[16];
+#endif
+ CoreDFB *core = NULL;
+ CoreDFBShared *shared = NULL;
+
+ D_ASSERT( ret_core != NULL );
+ D_ASSERT( dfb_config != NULL );
+
+ D_DEBUG_AT( DirectFB_Core, "%s...\n", __FUNCTION__ );
+
+ pthread_mutex_lock( &core_dfb_lock );
+
+ D_ASSERT( core_dfb == NULL || core_dfb->refs > 0 );
+
+ if (core_dfb) {
+ D_MAGIC_ASSERT( core_dfb, CoreDFB );
+
+ core_dfb->refs++;
+
+ *ret_core = core_dfb;
+
+ pthread_mutex_unlock( &core_dfb_lock );
+
+ return DFB_OK;
+ }
+
+ direct_initialize();
+
+
+ D_INFO( "DirectFB/Core: %s Application Core. ("BUILDTIME") %s%s\n",
+ FUSION_BUILD_MULTI ? "Multi" : "Single",
+ DIRECT_BUILD_DEBUG ? "[ DEBUG ]" : "",
+ DIRECT_BUILD_TRACE ? "[ TRACE ]" : "" );
+
+
+#if defined(DFB_DYNAMIC_LINKING) && defined(SOPATH)
+ if (!dfb_lib_handle)
+#ifdef RTLD_GLOBAL
+ dfb_lib_handle = dlopen(SOPATH, RTLD_GLOBAL|RTLD_LAZY);
+#else
+ /* RTLD_GLOBAL is not defined on OpenBSD */
+ dfb_lib_handle = dlopen(SOPATH, RTLD_LAZY);
+#endif
+#endif
+
+ ret = dfb_system_lookup();
+ if (ret)
+ goto error;
+
+
+ /* Allocate local core structure. */
+ core = D_CALLOC( 1, sizeof(CoreDFB) );
+ if (!core) {
+ ret = D_OOM();
+ goto error;
+ }
+
+ core->refs = 1;
+
+ core->init_handler = direct_thread_add_init_handler( dfb_core_thread_init_handler, core );
+
+#if FUSION_BUILD_MULTI
+ dfb_system_thread_init();
+#endif
+
+ direct_find_best_memcpy();
+
+ D_MAGIC_SET( core, CoreDFB );
+
+ core_dfb = core;
+
+ ret = fusion_enter( dfb_config->session, DIRECTFB_CORE_ABI, FER_ANY, &core->world );
+ if (ret)
+ goto error;
+
+ core->fusion_id = fusion_id( core->world );
+
+#if FUSION_BUILD_MULTI
+ D_DEBUG_AT( DirectFB_Core, "world %d, fusion id %d\n", fusion_world_index(core->world), core->fusion_id );
+
+ snprintf( buf, sizeof(buf), "%d", fusion_world_index(core->world) );
+
+ setenv( "DIRECTFB_SESSION", buf, true );
+#endif
+
+ if (dfb_config->sync) {
+ D_INFO( "DirectFB/Core: calling sync()...\n" );
+ sync();
+ }
+
+ direct_signal_handler_add( DIRECT_SIGNAL_ANY, dfb_core_signal_handler, core, &core->signal_handler );
+
+ if (fusion_arena_enter( core->world, "DirectFB/Core",
+ dfb_core_arena_initialize, dfb_core_arena_join,
+ core, &core->arena, &ret ) || ret)
+ {
+ ret = ret ? ret : DFB_FUSION;
+ goto error;
+ }
+
+ shared = core->shared;
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+
+ if (dfb_config->block_all_signals)
+ direct_signals_block_all();
+
+ if (dfb_config->deinit_check)
+ direct_cleanup_handler_add( dfb_core_deinit_check, NULL, &core->cleanup_handler );
+
+
+ fusion_skirmish_prevail( &shared->lock );
+
+ if (!core->master) {
+ while (!shared->active)
+ fusion_skirmish_wait( &shared->lock, 0 );
+ }
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+
+ *ret_core = core;
+
+ pthread_mutex_unlock( &core_dfb_lock );
+
+ D_DEBUG_AT( DirectFB_Core, "Core successfully created.\n" );
+
+ return DFB_OK;
+
+
+error:
+ if (core) {
+ if (core->world)
+ fusion_exit( core->world, false );
+
+ if (core->init_handler)
+ direct_thread_remove_init_handler( core->init_handler );
+
+ if (core->signal_handler)
+ direct_signal_handler_remove( core->signal_handler );
+
+ D_MAGIC_CLEAR( core );
+
+ D_FREE( core );
+ core_dfb = NULL;
+ }
+
+ pthread_mutex_unlock( &core_dfb_lock );
+
+ direct_shutdown();
+
+ return ret;
+}
+
+DFBResult
+dfb_core_destroy( CoreDFB *core, bool emergency )
+{
+ D_MAGIC_ASSERT( core, CoreDFB );
+ D_ASSERT( core->refs > 0 );
+ D_ASSERT( core == core_dfb );
+
+ D_DEBUG_AT( DirectFB_Core, "%s...\n", __FUNCTION__ );
+
+ if (!emergency) {
+ pthread_mutex_lock( &core_dfb_lock );
+
+ if (--core->refs) {
+ pthread_mutex_unlock( &core_dfb_lock );
+ return DFB_OK;
+ }
+ }
+
+ direct_signal_handler_remove( core->signal_handler );
+
+ if (core->cleanup_handler)
+ direct_cleanup_handler_remove( core->cleanup_handler );
+
+ if (core->master) {
+ if (emergency) {
+ fusion_kill( core->world, 0, SIGKILL, 1000 );
+ }
+ else {
+ fusion_kill( core->world, 0, SIGTERM, 5000 );
+ fusion_kill( core->world, 0, SIGKILL, 2000 );
+ }
+ }
+
+ dfb_core_process_cleanups( core, emergency );
+
+ while (fusion_arena_exit( core->arena, dfb_core_arena_shutdown,
+ core->master ? NULL : dfb_core_arena_leave,
+ core, emergency, NULL ) == DFB_BUSY)
+ {
+ D_ONCE( "waiting for DirectFB slaves to terminate" );
+ usleep( 100000 );
+ }
+
+ fusion_exit( core->world, emergency );
+
+ if (!emergency)
+ direct_thread_remove_init_handler( core->init_handler );
+
+ D_MAGIC_CLEAR( core );
+
+ D_FREE( core );
+ core_dfb = NULL;
+
+ if (!emergency) {
+ pthread_mutex_unlock( &core_dfb_lock );
+
+ direct_shutdown();
+ }
+
+ return DFB_OK;
+}
+
+CoreLayerContext *
+dfb_core_create_layer_context( CoreDFB *core )
+{
+ CoreDFBShared *shared;
+
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+ D_ASSERT( shared->layer_context_pool != NULL );
+
+ return (CoreLayerContext*) fusion_object_create( shared->layer_context_pool, core->world );
+}
+
+CoreLayerRegion *
+dfb_core_create_layer_region( CoreDFB *core )
+{
+ CoreDFBShared *shared;
+
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+ D_ASSERT( core->shared->layer_region_pool != NULL );
+
+ return (CoreLayerRegion*) fusion_object_create( core->shared->layer_region_pool, core->world );
+}
+
+CorePalette *
+dfb_core_create_palette( CoreDFB *core )
+{
+ CoreDFBShared *shared;
+
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+ D_ASSERT( core->shared->palette_pool != NULL );
+
+ return (CorePalette*) fusion_object_create( core->shared->palette_pool, core->world );
+}
+
+CoreSurface *
+dfb_core_create_surface( CoreDFB *core )
+{
+ CoreDFBShared *shared;
+
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+ D_ASSERT( core->shared->surface_pool != NULL );
+
+ return (CoreSurface*) fusion_object_create( core->shared->surface_pool, core->world );
+}
+
+CoreWindow *
+dfb_core_create_window( CoreDFB *core )
+{
+ CoreDFBShared *shared;
+
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+ D_ASSERT( core->shared->window_pool != NULL );
+
+ return (CoreWindow*) fusion_object_create( core->shared->window_pool, core->world );
+}
+
+DirectResult
+dfb_core_enum_surfaces( CoreDFB *core,
+ FusionObjectCallback callback,
+ void *ctx )
+{
+ CoreDFBShared *shared;
+
+ D_ASSERT( core != NULL || core_dfb != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+
+ return fusion_object_pool_enum( shared->surface_pool, callback, ctx );
+}
+
+DirectResult
+dfb_core_enum_layer_contexts( CoreDFB *core,
+ FusionObjectCallback callback,
+ void *ctx )
+{
+ CoreDFBShared *shared;
+
+ D_ASSERT( core != NULL || core_dfb != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+
+ return fusion_object_pool_enum( shared->layer_context_pool, callback, ctx );
+}
+
+DirectResult
+dfb_core_enum_layer_regions( CoreDFB *core,
+ FusionObjectCallback callback,
+ void *ctx )
+{
+ CoreDFBShared *shared;
+
+ D_ASSERT( core != NULL || core_dfb != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+
+ return fusion_object_pool_enum( shared->layer_region_pool, callback, ctx );
+}
+
+bool
+dfb_core_is_master( CoreDFB *core )
+{
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ return core->master;
+}
+
+void
+dfb_core_activate( CoreDFB *core )
+{
+ CoreDFBShared *shared;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+
+ fusion_skirmish_prevail( &shared->lock );
+
+ shared->active = true;
+
+ fusion_skirmish_notify( &shared->lock );
+
+ fusion_skirmish_dismiss( &shared->lock );
+}
+
+FusionWorld *
+dfb_core_world( CoreDFB *core )
+{
+// D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ return core->world;
+}
+
+FusionArena *
+dfb_core_arena( CoreDFB *core )
+{
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ return core->arena;
+}
+
+FusionSHMPoolShared *
+dfb_core_shmpool( CoreDFB *core )
+{
+ CoreDFBShared *shared;
+
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+
+ return shared->shmpool;
+}
+
+FusionSHMPoolShared *
+dfb_core_shmpool_data( CoreDFB *core )
+{
+ CoreDFBShared *shared;
+
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+
+ return shared->shmpool_data;
+}
+
+DFBResult
+dfb_core_suspend( CoreDFB *core )
+{
+ DFBResult ret;
+
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ if (!core->master)
+ return DFB_ACCESSDENIED;
+
+ if (core->suspended)
+ return DFB_BUSY;
+
+ ret = dfb_input_core.Suspend( dfb_input_core.data_local );
+ if (ret)
+ goto error_input;
+
+ ret = dfb_layer_core.Suspend( dfb_layer_core.data_local );
+ if (ret)
+ goto error_layers;
+
+ ret = dfb_screen_core.Suspend( dfb_screen_core.data_local );
+ if (ret)
+ goto error_screens;
+
+ ret = dfb_graphics_core.Suspend( dfb_graphics_core.data_local );
+ if (ret)
+ goto error_graphics;
+
+ core->suspended = true;
+
+ return DFB_OK;
+
+error_graphics:
+ dfb_screen_core.Resume( dfb_screen_core.data_local );
+error_screens:
+ dfb_layer_core.Resume( dfb_layer_core.data_local );
+error_layers:
+ dfb_input_core.Resume( dfb_input_core.data_local );
+error_input:
+ return ret;
+}
+
+DFBResult
+dfb_core_resume( CoreDFB *core )
+{
+ DFBResult ret;
+
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ if (!core->master)
+ return DFB_ACCESSDENIED;
+
+ if (!core->suspended)
+ return DFB_BUSY;
+
+ ret = dfb_graphics_core.Resume( dfb_graphics_core.data_local );
+ if (ret)
+ goto error_graphics;
+
+ ret = dfb_screen_core.Resume( dfb_screen_core.data_local );
+ if (ret)
+ goto error_screens;
+
+ ret = dfb_layer_core.Resume( dfb_layer_core.data_local );
+ if (ret)
+ goto error_layers;
+
+ ret = dfb_input_core.Resume( dfb_input_core.data_local );
+ if (ret)
+ goto error_input;
+
+ core->suspended = false;
+
+ return DFB_OK;
+
+error_input:
+ dfb_layer_core.Suspend( dfb_layer_core.data_local );
+error_layers:
+ dfb_screen_core.Suspend( dfb_screen_core.data_local );
+error_screens:
+ dfb_graphics_core.Suspend( dfb_graphics_core.data_local );
+error_graphics:
+ return ret;
+}
+
+CoreCleanup *
+dfb_core_cleanup_add( CoreDFB *core,
+ CoreCleanupFunc func,
+ void *data,
+ bool emergency )
+{
+ CoreCleanup *cleanup;
+
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ cleanup = D_CALLOC( 1, sizeof(CoreCleanup) );
+
+ cleanup->func = func;
+ cleanup->data = data;
+ cleanup->emergency = emergency;
+
+ direct_list_prepend( &core->cleanups, &cleanup->link );
+
+ return cleanup;
+}
+
+void
+dfb_core_cleanup_remove( CoreDFB *core,
+ CoreCleanup *cleanup )
+{
+ D_ASSUME( core != NULL );
+
+ if (!core)
+ core = core_dfb;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ direct_list_remove( &core->cleanups, &cleanup->link );
+
+ D_FREE( cleanup );
+}
+
+/******************************************************************************/
+
+static void
+dfb_core_deinit_check( void *ctx )
+{
+ if (core_dfb && core_dfb->refs) {
+ D_WARN( "Application exited without deinitialization of DirectFB!" );
+ dfb_core_destroy( core_dfb, true );
+ }
+}
+
+static void
+dfb_core_thread_init_handler( DirectThread *thread, void *arg )
+{
+ dfb_system_thread_init();
+}
+
+static void
+dfb_core_process_cleanups( CoreDFB *core, bool emergency )
+{
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ while (core->cleanups) {
+ CoreCleanup *cleanup = (CoreCleanup*) core->cleanups;
+
+ core->cleanups = core->cleanups->next;
+
+ if (cleanup->emergency || !emergency)
+ cleanup->func( cleanup->data, emergency );
+
+ D_FREE( cleanup );
+ }
+}
+
+static DirectSignalHandlerResult
+dfb_core_signal_handler( int num,
+ void *addr,
+ void *ctx )
+{
+ CoreDFB *core = ctx;
+
+ D_ASSERT( core == core_dfb );
+
+ dfb_core_destroy( core, true );
+
+ return DSHR_OK;
+}
+
+/******************************************************************************/
+
+static int
+dfb_core_shutdown( CoreDFB *core, bool emergency )
+{
+ CoreDFBShared *shared;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+
+ /* Suspend input core to stop all input threads before shutting down. */
+ if (dfb_input_core.initialized)
+ dfb_input_core.Suspend( dfb_input_core.data_local );
+
+ fusion_stop_dispatcher( core->world, emergency );
+
+ /* Destroy window objects. */
+ fusion_object_pool_destroy( shared->window_pool, core->world );
+
+ /* Close window stacks. */
+ if (dfb_wm_core.initialized)
+ dfb_wm_close_all_stacks( dfb_wm_core.data_local );
+
+ /* Destroy layer context and region objects. */
+ fusion_object_pool_destroy( shared->layer_region_pool, core->world );
+ fusion_object_pool_destroy( shared->layer_context_pool, core->world );
+
+ /* Shutdown WM core. */
+ dfb_core_part_shutdown( core, &dfb_wm_core, emergency );
+
+ /* Shutdown layer core. */
+ dfb_core_part_shutdown( core, &dfb_layer_core, emergency );
+ dfb_core_part_shutdown( core, &dfb_screen_core, emergency );
+
+ /* Destroy surface and palette objects. */
+ fusion_object_pool_destroy( shared->surface_pool, core->world );
+ fusion_object_pool_destroy( shared->palette_pool, core->world );
+
+ /* Destroy remaining core parts. */
+ dfb_core_part_shutdown( core, &dfb_graphics_core, emergency );
+ dfb_core_part_shutdown( core, &dfb_surface_core, emergency );
+ dfb_core_part_shutdown( core, &dfb_input_core, emergency );
+ dfb_core_part_shutdown( core, &dfb_system_core, emergency );
+ dfb_core_part_shutdown( core, &dfb_colorhash_core, emergency );
+ dfb_core_part_shutdown( core, &dfb_clipboard_core, emergency );
+
+ /* Destroy shared memory pool for surface data. */
+ fusion_shm_pool_destroy( core->world, shared->shmpool_data );
+
+ return 0;
+}
+
+static DFBResult
+dfb_core_initialize( CoreDFB *core )
+{
+ int i;
+ DFBResult ret;
+ CoreDFBShared *shared;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+
+ ret = fusion_shm_pool_create( core->world, "DirectFB Data Pool", 0x1000000,
+ fusion_config->debugshm, &shared->shmpool_data );
+ if (ret)
+ return ret;
+
+ shared->layer_context_pool = dfb_layer_context_pool_create( core->world );
+ shared->layer_region_pool = dfb_layer_region_pool_create( core->world );
+ shared->palette_pool = dfb_palette_pool_create( core->world );
+ shared->surface_pool = dfb_surface_pool_create( core->world );
+ shared->window_pool = dfb_window_pool_create( core->world );
+
+ for (i=0; i<D_ARRAY_SIZE(core_parts); i++) {
+ DFBResult ret;
+
+ if ((ret = dfb_core_part_initialize( core, core_parts[i] ))) {
+ dfb_core_shutdown( core, true );
+ return ret;
+ }
+ }
+
+ return DFB_OK;
+}
+
+static int
+dfb_core_leave( CoreDFB *core, bool emergency )
+{
+ int i;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ for (i=D_ARRAY_SIZE(core_parts)-1; i>=0; i--)
+ dfb_core_part_leave( core, core_parts[i], emergency );
+
+ return DFB_OK;
+}
+
+static int
+dfb_core_join( CoreDFB *core )
+{
+ int i;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ for (i=0; i<D_ARRAY_SIZE(core_parts); i++) {
+ DFBResult ret;
+
+ if ((ret = dfb_core_part_join( core, core_parts[i] ))) {
+ dfb_core_leave( core, true );
+ return ret;
+ }
+ }
+
+ return DFB_OK;
+}
+
+/******************************************************************************/
+
+static int
+dfb_core_arena_initialize( FusionArena *arena,
+ void *ctx )
+{
+ DFBResult ret;
+ CoreDFB *core = ctx;
+ CoreDFBShared *shared;
+ FusionSHMPoolShared *pool;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ D_DEBUG_AT( DirectFB_Core, "Initializing...\n" );
+
+ /* Create the shared memory pool first! */
+ ret = fusion_shm_pool_create( core->world, "DirectFB Main Pool", 0x400000,
+ fusion_config->debugshm, &pool );
+ if (ret)
+ return ret;
+
+ /* Allocate shared structure in the new pool. */
+ shared = SHCALLOC( pool, 1, sizeof(CoreDFBShared) );
+ if (!shared) {
+ fusion_shm_pool_destroy( core->world, pool );
+ return D_OOSHM();
+ }
+
+ core->shared = shared;
+ core->master = true;
+
+ shared->shmpool = pool;
+
+ D_MAGIC_SET( shared, CoreDFBShared );
+
+ /* Initialize. */
+ ret = dfb_core_initialize( core );
+ if (ret) {
+ D_MAGIC_CLEAR( shared );
+ SHFREE( pool, shared );
+ fusion_shm_pool_destroy( core->world, pool );
+ return ret;
+ }
+
+ fusion_skirmish_init( &shared->lock, "DirectFB Core", core->world );
+
+ /* Register shared data. */
+ fusion_arena_add_shared_field( arena, "Core/Shared", shared );
+
+ return DFB_OK;
+}
+
+static int
+dfb_core_arena_shutdown( FusionArena *arena,
+ void *ctx,
+ bool emergency)
+{
+ DFBResult ret;
+ CoreDFB *core = ctx;
+ CoreDFBShared *shared;
+ FusionSHMPoolShared *pool;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ shared = core->shared;
+
+ D_MAGIC_ASSERT( shared, CoreDFBShared );
+
+ pool = shared->shmpool;
+
+ D_DEBUG_AT( DirectFB_Core, "Shutting down...\n" );
+
+ if (!core->master) {
+ D_WARN( "refusing shutdown in slave" );
+ return dfb_core_leave( core, emergency );
+ }
+
+ /* Shutdown. */
+ ret = dfb_core_shutdown( core, emergency );
+
+ fusion_skirmish_destroy( &shared->lock );
+
+ D_MAGIC_CLEAR( shared );
+
+ SHFREE( pool, shared );
+
+ fusion_shm_pool_destroy( core->world, pool );
+
+ return ret;
+}
+
+static int
+dfb_core_arena_join( FusionArena *arena,
+ void *ctx )
+{
+ DFBResult ret;
+ CoreDFB *core = ctx;
+ void *field;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ D_DEBUG_AT( DirectFB_Core, "Joining...\n" );
+
+ /* Get shared data. */
+ if (fusion_arena_get_shared_field( arena, "Core/Shared", &field ))
+ return DFB_FUSION;
+
+ core->shared = field;
+
+ /* Join. */
+ ret = dfb_core_join( core );
+ if (ret)
+ return ret;
+
+ return DFB_OK;
+}
+
+static int
+dfb_core_arena_leave( FusionArena *arena,
+ void *ctx,
+ bool emergency)
+{
+ DFBResult ret;
+ CoreDFB *core = ctx;
+
+ D_MAGIC_ASSERT( core, CoreDFB );
+
+ D_DEBUG_AT( DirectFB_Core, "Leaving...\n" );
+
+ /* Leave. */
+ ret = dfb_core_leave( core, emergency );
+ if (ret)
+ return ret;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/core/core.h b/Source/DirectFB/src/core/core.h
new file mode 100755
index 0000000..7116e8c
--- /dev/null
+++ b/Source/DirectFB/src/core/core.h
@@ -0,0 +1,162 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE_H__
+#define __CORE_H__
+
+#include <fusion/types.h>
+#include <fusion/lock.h>
+#include <fusion/object.h>
+
+#include <directfb.h>
+
+#include "coretypes.h"
+#include "coredefs.h"
+
+
+#define DIRECTFB_CORE_ABI 45
+
+
+typedef enum {
+ DFCP_CLIPBOARD,
+ DFCP_COLORHASH,
+ DFCP_GRAPHICS,
+ DFCP_INPUT,
+ DFCP_LAYER,
+ DFCP_SCREEN,
+ DFCP_SURFACE,
+ DFCP_SYSTEM,
+ DFCP_WM,
+
+ _DFCP_NUM
+} DFBCorePartID;
+
+
+/*
+ * Cleanup function, callback of a cleanup stack entry.
+ */
+typedef void (*CoreCleanupFunc)(void *data, int emergency);
+
+
+
+/*
+ * Core initialization and deinitialization
+ */
+DFBResult dfb_core_create ( CoreDFB **ret_core );
+
+DFBResult dfb_core_destroy ( CoreDFB *core,
+ bool emergency );
+
+void *dfb_core_get_part( CoreDFB *core,
+ DFBCorePartID part_id );
+
+
+#define DFB_CORE(core,PART) dfb_core_get_part( core, DFCP_##PART )
+
+
+/*
+ * Object creation
+ */
+CoreLayerContext *dfb_core_create_layer_context( CoreDFB *core );
+CoreLayerRegion *dfb_core_create_layer_region ( CoreDFB *core );
+CorePalette *dfb_core_create_palette ( CoreDFB *core );
+CoreSurface *dfb_core_create_surface ( CoreDFB *core );
+CoreWindow *dfb_core_create_window ( CoreDFB *core );
+
+/*
+ * Debug
+ */
+DirectResult dfb_core_enum_surfaces ( CoreDFB *core,
+ FusionObjectCallback callback,
+ void *ctx );
+DirectResult dfb_core_enum_layer_contexts( CoreDFB *core,
+ FusionObjectCallback callback,
+ void *ctx );
+DirectResult dfb_core_enum_layer_regions ( CoreDFB *core,
+ FusionObjectCallback callback,
+ void *ctx );
+
+
+/*
+ * Returns true if the calling process is the master fusionee,
+ * i.e. handles input drivers running their threads.
+ */
+bool dfb_core_is_master( CoreDFB *core );
+
+/*
+ * Allows other (blocking) Fusionees to enter the DirectFB session.
+ */
+void dfb_core_activate( CoreDFB *core );
+
+/*
+ * Returns the core's fusion world.
+ */
+FusionWorld *dfb_core_world( CoreDFB *core );
+
+/*
+ * Returns the core arena.
+ */
+FusionArena *dfb_core_arena( CoreDFB *core );
+
+/*
+ * Returns the shared memory pool of the core.
+ */
+FusionSHMPoolShared *dfb_core_shmpool( CoreDFB *core );
+
+/*
+ * Returns the shared memory pool for raw data, e.g. surface buffers.
+ */
+FusionSHMPoolShared *dfb_core_shmpool_data( CoreDFB *core );
+
+/*
+ * Suspends all core parts, stopping input threads, closing devices...
+ */
+DFBResult dfb_core_suspend( CoreDFB *core );
+
+/*
+ * Resumes all core parts, reopening devices, starting input threads...
+ */
+DFBResult dfb_core_resume( CoreDFB *core );
+
+/*
+ * Adds a function to the cleanup stack that is called during deinitialization.
+ * If emergency is true, the cleanup is even called by core_deinit_emergency().
+ */
+CoreCleanup *dfb_core_cleanup_add( CoreDFB *core,
+ CoreCleanupFunc func,
+ void *data,
+ bool emergency );
+
+/*
+ * Removes a function from the cleanup stack.
+ */
+void dfb_core_cleanup_remove( CoreDFB *core,
+ CoreCleanup *cleanup );
+
+#endif
+
diff --git a/Source/DirectFB/src/core/core_parts.c b/Source/DirectFB/src/core/core_parts.c
new file mode 100755
index 0000000..1b5f944
--- /dev/null
+++ b/Source/DirectFB/src/core/core_parts.c
@@ -0,0 +1,202 @@
+/*
+ (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 <fusion/arena.h>
+#include <fusion/shmalloc.h>
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/core.h>
+#include <core/core_parts.h>
+
+#include <direct/mem.h>
+#include <direct/messages.h>
+
+
+D_DEBUG_DOMAIN( Core_Parts, "Core/Parts", "DirectFB Core Parts" );
+
+
+DFBResult
+dfb_core_part_initialize( CoreDFB *core,
+ CorePart *core_part )
+{
+ DFBResult ret;
+ void *local = NULL;
+ void *shared = NULL;
+ FusionSHMPoolShared *pool;
+
+ pool = dfb_core_shmpool( core );
+
+ if (core_part->initialized) {
+ D_BUG( "%s already initialized", core_part->name );
+ return DFB_BUG;
+ }
+
+ D_DEBUG_AT( Core_Parts, "Going to initialize '%s' core...\n", core_part->name );
+
+ if (core_part->size_local)
+ local = D_CALLOC( 1, core_part->size_local );
+
+ if (core_part->size_shared)
+ shared = SHCALLOC( pool, 1, core_part->size_shared );
+
+ ret = core_part->Initialize( core, local, shared );
+ if (ret) {
+ D_ERROR( "DirectFB/Core: Could not initialize '%s' core!\n"
+ " --> %s\n", core_part->name,
+ DirectFBErrorString( ret ) );
+
+ if (shared)
+ SHFREE( pool, shared );
+
+ if (local)
+ D_FREE( local );
+
+ return ret;
+ }
+
+ if (shared)
+ fusion_arena_add_shared_field( dfb_core_arena( core ),
+ core_part->name, shared );
+
+ core_part->data_local = local;
+ core_part->data_shared = shared;
+ core_part->initialized = true;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_core_part_join( CoreDFB *core,
+ CorePart *core_part )
+{
+ DFBResult ret;
+ void *local = NULL;
+ void *shared = NULL;
+
+ if (core_part->initialized) {
+ D_BUG( "%s already joined", core_part->name );
+ return DFB_BUG;
+ }
+
+ D_DEBUG_AT( Core_Parts, "Going to join '%s' core...\n", core_part->name );
+
+ if (core_part->size_shared &&
+ fusion_arena_get_shared_field( dfb_core_arena( core ),
+ core_part->name, &shared ))
+ return DFB_FUSION;
+
+ if (core_part->size_local)
+ local = D_CALLOC( 1, core_part->size_local );
+
+ ret = core_part->Join( core, local, shared );
+ if (ret) {
+ D_ERROR( "DirectFB/Core: Could not join '%s' core!\n"
+ " --> %s\n", core_part->name,
+ DirectFBErrorString( ret ) );
+
+ if (local)
+ D_FREE( local );
+
+ return ret;
+ }
+
+ core_part->data_local = local;
+ core_part->data_shared = shared;
+ core_part->initialized = true;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_core_part_shutdown( CoreDFB *core,
+ CorePart *core_part,
+ bool emergency )
+{
+ DFBResult ret;
+ FusionSHMPoolShared *pool;
+
+ pool = dfb_core_shmpool( core );
+
+ if (!core_part->initialized)
+ return DFB_OK;
+
+ D_DEBUG_AT( Core_Parts, "Going to shutdown '%s' core...\n", core_part->name );
+
+ ret = core_part->Shutdown( core_part->data_local, emergency );
+ if (ret)
+ D_ERROR( "DirectFB/Core: Could not shutdown '%s' core!\n"
+ " --> %s\n", core_part->name,
+ DirectFBErrorString( ret ) );
+
+ if (core_part->data_shared)
+ SHFREE( pool, core_part->data_shared );
+
+ if (core_part->data_local)
+ D_FREE( core_part->data_local );
+
+ core_part->data_local = NULL;
+ core_part->data_shared = NULL;
+ core_part->initialized = false;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_core_part_leave( CoreDFB *core,
+ CorePart *core_part,
+ bool emergency )
+{
+ DFBResult ret;
+
+ if (!core_part->initialized)
+ return DFB_OK;
+
+ D_DEBUG_AT( Core_Parts, "Going to leave '%s' core...\n", core_part->name );
+
+ ret = core_part->Leave( core_part->data_local, emergency );
+ if (ret)
+ D_ERROR( "DirectFB/Core: Could not leave '%s' core!\n"
+ " --> %s\n", core_part->name,
+ DirectFBErrorString( ret ) );
+
+ if (core_part->data_local)
+ D_FREE( core_part->data_local );
+
+ core_part->data_local = NULL;
+ core_part->data_shared = NULL;
+ core_part->initialized = false;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/core/core_parts.h b/Source/DirectFB/src/core/core_parts.h
new file mode 100755
index 0000000..31b7563
--- /dev/null
+++ b/Source/DirectFB/src/core/core_parts.h
@@ -0,0 +1,131 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE_PARTS_H__
+#define __CORE_PARTS_H__
+
+#include <fusion/types.h>
+#include <fusion/lock.h>
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+#include <core/coredefs.h>
+
+
+typedef DFBResult (*CoreInitialize)( CoreDFB *core,
+ void *data_local,
+ void *data_shared );
+
+typedef DFBResult (*CoreJoin) ( CoreDFB *core,
+ void *data_local,
+ void *data_shared );
+
+typedef DFBResult (*CoreShutdown) ( void *data_local,
+ bool emergency );
+
+typedef DFBResult (*CoreLeave) ( void *data_local,
+ bool emergency );
+
+typedef DFBResult (*CoreSuspend) ( void *data_local );
+
+typedef DFBResult (*CoreResume) ( void *data_local );
+
+
+typedef struct {
+ const char *name;
+
+ int size_local;
+ int size_shared;
+
+ CoreInitialize Initialize;
+ CoreJoin Join;
+ CoreShutdown Shutdown;
+ CoreLeave Leave;
+ CoreSuspend Suspend;
+ CoreResume Resume;
+
+ void *data_local;
+ void *data_shared;
+
+ bool initialized;
+} CorePart;
+
+
+DFBResult dfb_core_part_initialize( CoreDFB *core,
+ CorePart *core_part );
+
+DFBResult dfb_core_part_join ( CoreDFB *core,
+ CorePart *core_part );
+
+DFBResult dfb_core_part_shutdown ( CoreDFB *core,
+ CorePart *core_part,
+ bool emergency );
+
+DFBResult dfb_core_part_leave ( CoreDFB *core,
+ CorePart *core_part,
+ bool emergency );
+
+
+#define DFB_CORE_PART(part,Type) \
+ \
+static DFBResult dfb_##part##_initialize( CoreDFB *core, \
+ DFB##Type *local, \
+ DFB##Type##Shared *shared ); \
+ \
+static DFBResult dfb_##part##_join ( CoreDFB *core, \
+ DFB##Type *local, \
+ DFB##Type##Shared *shared ); \
+ \
+static DFBResult dfb_##part##_shutdown ( DFB##Type *local, \
+ bool emergency ); \
+ \
+static DFBResult dfb_##part##_leave ( DFB##Type *local, \
+ bool emergency ); \
+ \
+static DFBResult dfb_##part##_suspend ( DFB##Type *local ); \
+ \
+static DFBResult dfb_##part##_resume ( DFB##Type *local ); \
+ \
+CorePart dfb_##part = { \
+ .name = #part, \
+ \
+ .size_local = sizeof(DFB##Type), \
+ .size_shared = sizeof(DFB##Type##Shared), \
+ \
+ .Initialize = (void*)dfb_##part##_initialize, \
+ .Join = (void*)dfb_##part##_join, \
+ .Shutdown = (void*)dfb_##part##_shutdown, \
+ .Leave = (void*)dfb_##part##_leave, \
+ .Suspend = (void*)dfb_##part##_suspend, \
+ .Resume = (void*)dfb_##part##_resume, \
+}
+
+
+#endif
+
diff --git a/Source/DirectFB/src/core/core_system.h b/Source/DirectFB/src/core/core_system.h
new file mode 100755
index 0000000..dfa2abc
--- /dev/null
+++ b/Source/DirectFB/src/core/core_system.h
@@ -0,0 +1,141 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DFB__CORE__CORE_SYSTEM_H__
+#define __DFB__CORE__CORE_SYSTEM_H__
+
+#include <core/system.h>
+
+static void
+system_get_info( CoreSystemInfo *info );
+
+static DFBResult
+system_initialize( CoreDFB *core, void **data );
+
+static DFBResult
+system_join( CoreDFB *core, void **data );
+
+static DFBResult
+system_shutdown( bool emergency );
+
+static DFBResult
+system_leave( bool emergency );
+
+static DFBResult
+system_suspend( void );
+
+static DFBResult
+system_resume( void );
+
+static VideoMode*
+system_get_modes( void );
+
+static VideoMode*
+system_get_current_mode( void );
+
+static DFBResult
+system_thread_init( void );
+
+static bool
+system_input_filter( CoreInputDevice *device,
+ DFBInputEvent *event );
+
+static volatile void*
+system_map_mmio( unsigned int offset,
+ int length );
+
+static void
+system_unmap_mmio( volatile void *addr,
+ int length );
+
+static int
+system_get_accelerator( void );
+
+static unsigned long
+system_video_memory_physical( unsigned int offset );
+
+static void*
+system_video_memory_virtual( unsigned int offset );
+
+static unsigned int
+system_videoram_length( void );
+
+static unsigned long
+system_aux_memory_physical( unsigned int offset );
+
+static void*
+system_aux_memory_virtual( unsigned int offset );
+
+static unsigned int
+system_auxram_length( void );
+
+static void
+system_get_busid( int *ret_bus, int *ret_dev, int *ret_func );
+
+static void
+system_get_deviceid( unsigned int *ret_vendor_id, unsigned int *ret_device_id );
+
+
+static CoreSystemFuncs system_funcs = {
+ .GetSystemInfo = system_get_info,
+ .Initialize = system_initialize,
+ .Join = system_join,
+ .Shutdown = system_shutdown,
+ .Leave = system_leave,
+ .Suspend = system_suspend,
+ .Resume = system_resume,
+ .GetModes = system_get_modes,
+ .GetCurrentMode = system_get_current_mode,
+ .ThreadInit = system_thread_init,
+ .InputFilter = system_input_filter,
+ .MapMMIO = system_map_mmio,
+ .UnmapMMIO = system_unmap_mmio,
+ .GetAccelerator = system_get_accelerator,
+ .VideoMemoryPhysical = system_video_memory_physical,
+ .VideoMemoryVirtual = system_video_memory_virtual,
+ .VideoRamLength = system_videoram_length,
+ .AuxMemoryPhysical = system_aux_memory_physical,
+ .AuxMemoryVirtual = system_aux_memory_virtual,
+ .AuxRamLength = system_auxram_length,
+ .GetBusID = system_get_busid,
+ .GetDeviceID = system_get_deviceid
+};
+
+#define DFB_CORE_SYSTEM(shortname) \
+__attribute__((constructor)) void directfb_##shortname( void ); \
+ \
+void \
+directfb_##shortname( void ) \
+{ \
+ direct_modules_register( &dfb_core_systems, \
+ DFB_CORE_SYSTEM_ABI_VERSION, \
+ #shortname, &system_funcs ); \
+}
+
+#endif
+
diff --git a/Source/DirectFB/src/core/coredefs.h b/Source/DirectFB/src/core/coredefs.h
new file mode 100755
index 0000000..3354cfa
--- /dev/null
+++ b/Source/DirectFB/src/core/coredefs.h
@@ -0,0 +1,48 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__COREDEFS_H__
+#define __CORE__COREDEFS_H__
+
+
+#ifdef PIC
+#define DFB_DYNAMIC_LINKING
+#endif
+
+#define MAX_INPUTDEVICES 64
+#define MAX_LAYERS 16
+#define MAX_SCREENS 4
+
+#define MAX_INPUT_GLOBALS 8
+
+#define MAX_SURFACE_BUFFERS 6
+#define MAX_SURFACE_POOLS 8
+#define MAX_SURFACE_POOL_BRIDGES 4
+
+#endif
+
diff --git a/Source/DirectFB/src/core/coretypes.h b/Source/DirectFB/src/core/coretypes.h
new file mode 100755
index 0000000..a5df62d
--- /dev/null
+++ b/Source/DirectFB/src/core/coretypes.h
@@ -0,0 +1,89 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORETYPES_H__
+#define __CORETYPES_H__
+
+#include <dfb_types.h>
+
+typedef struct __DFB_CoreDFB CoreDFB;
+typedef struct __DFB_CoreDFBShared CoreDFBShared;
+
+
+typedef struct __DFB_DFBClipboardCore DFBClipboardCore;
+typedef struct __DFB_DFBColorHashCore DFBColorHashCore;
+typedef struct __DFB_DFBGraphicsCore DFBGraphicsCore;
+typedef struct __DFB_DFBInputCore DFBInputCore;
+typedef struct __DFB_DFBLayerCore DFBLayerCore;
+typedef struct __DFB_DFBScreenCore DFBScreenCore;
+typedef struct __DFB_DFBSystemCore DFBSystemCore;
+typedef struct __DFB_DFBWMCore DFBWMCore;
+
+
+typedef struct __DFB_DFBGraphicsCore CoreGraphicsDevice; /* FIXME */
+
+
+typedef struct _CoreCleanup CoreCleanup;
+
+typedef struct _CoreFont CoreFont;
+typedef struct _CoreGlyphData CoreGlyphData;
+typedef struct _CorePalette CorePalette;
+
+typedef struct _CardState CardState;
+
+
+typedef struct __DFB_CoreGraphicsSerial CoreGraphicsSerial;
+
+typedef struct __DFB_CoreScreen CoreScreen;
+
+typedef struct __DFB_CoreInputDevice CoreInputDevice;
+
+typedef struct __DFB_CoreLayer CoreLayer;
+typedef struct __DFB_CoreLayerContext CoreLayerContext;
+typedef struct __DFB_CoreLayerRegion CoreLayerRegion;
+typedef struct __DFB_CoreLayerRegionConfig CoreLayerRegionConfig;
+
+typedef struct __DFB_CoreSurface CoreSurface;
+typedef struct __DFB_CoreSurfaceAccessor CoreSurfaceAccessor;
+typedef struct __DFB_CoreSurfaceAllocation CoreSurfaceAllocation;
+typedef struct __DFB_CoreSurfaceBuffer CoreSurfaceBuffer;
+typedef struct __DFB_CoreSurfaceBufferLock CoreSurfaceBufferLock;
+typedef struct __DFB_CoreSurfacePool CoreSurfacePool;
+typedef struct __DFB_CoreSurfacePoolBridge CoreSurfacePoolBridge;
+typedef struct __DFB_CoreSurfacePoolTransfer CoreSurfacePoolTransfer;
+
+typedef struct __DFB_CoreWindow CoreWindow;
+typedef struct __DFB_CoreWindowConfig CoreWindowConfig;
+typedef struct __DFB_CoreWindowStack CoreWindowStack;
+
+
+typedef unsigned int CoreSurfacePoolID;
+typedef unsigned int CoreSurfacePoolBridgeID;
+
+#endif
+
diff --git a/Source/DirectFB/src/core/fonts.c b/Source/DirectFB/src/core/fonts.c
new file mode 100755
index 0000000..2e6b599
--- /dev/null
+++ b/Source/DirectFB/src/core/fonts.c
@@ -0,0 +1,660 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <pthread.h>
+
+#include <directfb.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/fonts.h>
+#include <core/gfxcard.h>
+#include <core/surface.h>
+
+#include <direct/debug.h>
+#include <direct/hash.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/utf8.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+
+D_DEBUG_DOMAIN( Core_Font, "Core/Font", "DirectFB Core Font" );
+D_DEBUG_DOMAIN( Core_FontSurfaces, "Core/Font/Surf", "DirectFB Core Font Surfaces" );
+
+/**********************************************************************************************************************/
+
+static bool free_glyphs( DirectHash *hash,
+ unsigned long key,
+ void *value,
+ void *ctx );
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_font_create( CoreDFB *core,
+ const DFBFontDescription *description,
+ const char *url,
+ CoreFont **ret_font )
+{
+ DFBResult ret;
+ int i;
+ CoreFont *font;
+
+ D_DEBUG_AT( Core_Font, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( core != NULL );
+ D_ASSERT( ret_font != NULL );
+
+ font = D_CALLOC( 1, sizeof(CoreFont) );
+ if (!font)
+ return D_OOM();
+
+ for (i=0; i<DFB_FONT_MAX_LAYERS; i++) {
+ ret = direct_hash_create( 163, &font->layers[i].glyph_hash );
+ if (ret) {
+ while (i--)
+ direct_hash_destroy( font->layers[i].glyph_hash );
+
+ D_FREE( font );
+ return ret;
+ }
+ }
+
+ font->description = *description;
+ font->url = D_STRDUP( url );
+
+ font->core = core;
+ font->max_rows = 2;
+
+ direct_util_recursive_pthread_mutex_init( &font->lock );
+
+ /* the proposed pixel_format, may be changed by the font provider */
+ font->pixel_format = dfb_config->font_format ? : DSPF_A8;
+
+ if ((font->pixel_format == DSPF_ARGB || font->pixel_format == DSPF_ARGB4444) && dfb_config->font_premult)
+ font->surface_caps = DSCAPS_PREMULTIPLIED;
+
+ font->blittingflags = DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE;
+
+ D_MAGIC_SET( font, CoreFont );
+
+ *ret_font = font;
+
+ return DFB_OK;
+}
+
+void
+dfb_font_destroy( CoreFont *font )
+{
+ int i;
+
+ D_DEBUG_AT( Core_Font, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( font, CoreFont );
+
+ D_MAGIC_CLEAR( font );
+
+ D_FREE( font->url );
+
+ pthread_mutex_lock( &font->lock );
+
+ for (i=0; i<DFB_FONT_MAX_LAYERS; i++) {
+ direct_hash_iterate( font->layers[i].glyph_hash, free_glyphs, NULL );
+
+ direct_hash_destroy( font->layers[i].glyph_hash );
+ }
+
+ if (font->rows) {
+ for (i = 0; i < font->num_rows; i++) {
+ CoreFontCacheRow *row = font->rows[i];
+
+ D_MAGIC_ASSERT( row, CoreFontCacheRow );
+
+ dfb_surface_unref( row->surface );
+
+ D_MAGIC_CLEAR( row );
+
+ D_FREE( row );
+ }
+
+ D_FREE( font->rows );
+ }
+
+ D_ASSERT( font->encodings != NULL || !font->last_encoding );
+
+ for (i=DTEID_OTHER; i<=font->last_encoding; i++) {
+ CoreFontEncoding *encoding = font->encodings[i];
+
+ D_ASSERT( encoding != NULL );
+ D_ASSERT( encoding->name != NULL );
+
+ D_MAGIC_CLEAR( encoding );
+
+ D_FREE( encoding->name );
+ D_FREE( encoding );
+ }
+
+ if (font->encodings)
+ D_FREE( font->encodings );
+
+ pthread_mutex_unlock( &font->lock );
+ pthread_mutex_destroy( &font->lock );
+
+ D_FREE( font );
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_font_get_glyph_data( CoreFont *font,
+ unsigned int index,
+ unsigned int layer,
+ CoreGlyphData **ret_data )
+{
+ DFBResult ret;
+ CoreGlyphData *data;
+ int i;
+ int align;
+ CoreFontCacheRow *row = NULL;
+
+ D_DEBUG_AT( Core_Font, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( font, CoreFont );
+ D_ASSERT( ret_data != NULL );
+
+ D_ASSERT( layer < D_ARRAY_SIZE(font->layers) );
+ D_ASSERT( font->num_rows >= 0 );
+
+ if (font->num_rows) {
+ D_ASSERT( font->num_rows <= font->max_rows || font->max_rows < 0 );
+ D_ASSERT( font->active_row >= 0 );
+ D_ASSERT( font->active_row < font->num_rows );
+ }
+
+ if (index < 128 && font->layers[layer].glyph_data[index]) {
+ data = font->layers[layer].glyph_data[index];
+ if (data->failed)
+ goto retry;
+
+ *ret_data = font->layers[layer].glyph_data[index];
+ return DFB_OK;
+ }
+
+ data = direct_hash_lookup( font->layers[layer].glyph_hash, index );
+ if (data) {
+ D_MAGIC_ASSERT( data, CoreGlyphData );
+
+ if (font->rows) {
+ D_ASSERT( data->row >= 0 );
+ D_ASSERT( data->row < font->num_rows );
+
+ row = font->rows[data->row];
+
+ D_MAGIC_ASSERT( row, CoreFontCacheRow );
+
+ row->stamp = font->row_stamp++;
+ }
+
+ if (data->failed)
+ goto retry;
+
+ *ret_data = data;
+ return DFB_OK;
+ }
+
+ if (!font->GetGlyphData)
+ return DFB_UNSUPPORTED;
+
+ data = D_CALLOC( 1, sizeof(CoreGlyphData) );
+ if (!data)
+ return D_OOM();
+
+ D_MAGIC_SET( data, CoreGlyphData );
+
+ data->index = index;
+ data->layer = layer;
+
+retry:
+ data->failed = false;
+
+ ret = font->GetGlyphData( font, index, data );
+ if (ret) {
+ D_DERROR( ret, "Core/Font: Could not get glyph info for index %d!\n", index );
+ data->start = data->width = data->height = 0;
+ data->failed = true;
+ goto out;
+ }
+
+ if (data->width < 1 || data->height < 1) {
+ data->start = data->width = data->height = 0;
+ goto out;
+ }
+
+ if (font->rows) {
+ D_ASSERT( font->active_row >= 0 );
+ D_ASSERT( font->active_row < font->num_rows );
+
+ row = font->rows[font->active_row];
+
+ D_MAGIC_ASSERT( row, CoreFontCacheRow );
+ }
+ else {
+ /* Calculate row width? */
+ if (font->row_width == 0) {
+ int width = 2048 * font->height / 64;
+
+ if (width > 2048)
+ width = 2048;
+
+ if (width < font->maxadvance)
+ width = font->maxadvance;
+
+ font->row_width = (width + 7) & ~7;
+ }
+ }
+
+ /* Need another font surface? */
+ if (!row || (row->next_x + data->width > font->row_width)) {
+ D_ASSERT( font->max_rows != 0 );
+
+ /* Maximum number of rows reached? */
+ if (font->num_rows == font->max_rows) {
+ int best_row = -1;
+ unsigned int best_val = 0;
+
+ /* Check for trailing space first. */
+ for (i=0; i<font->num_rows; i++) {
+ row = font->rows[i];
+
+ D_MAGIC_ASSERT( row, CoreFontCacheRow );
+
+ if (row->next_x + data->width <= font->row_width) {
+ if (best_row == -1 || best_val < row->next_x) {
+ best_row = i;
+ best_val = row->next_x;
+ }
+ }
+ }
+
+ /* Found a row with enough trailing space? */
+ if (best_row != -1) {
+ font->active_row = best_row;
+ row = font->rows[best_row];
+
+ D_MAGIC_ASSERT( row, CoreFontCacheRow );
+
+ D_DEBUG_AT( Core_FontSurfaces, " -> using trailing space of row %d - %dx%d %s\n",
+ font->active_row, row->surface->config.size.w, row->surface->config.size.h,
+ dfb_pixelformat_name(row->surface->config.format) );
+ }
+ else {
+ CoreGlyphData *d, *n;
+
+ D_ASSERT( best_row == -1 );
+ D_ASSERT( best_val == 0 );
+
+ /* Reuse the least recently used row. */
+ for (i=0; i<font->num_rows; i++) {
+ row = font->rows[i];
+
+ D_MAGIC_ASSERT( row, CoreFontCacheRow );
+
+ if (best_row == -1 || best_val > row->stamp) {
+ best_row = i;
+ best_val = row->stamp;
+ }
+ }
+
+ D_ASSERT( best_row != -1 );
+
+ font->active_row = best_row;
+ row = font->rows[best_row];
+
+ D_MAGIC_ASSERT( row, CoreFontCacheRow );
+
+ D_DEBUG_AT( Core_FontSurfaces, " -> reusing row %d - %dx%d %s\n",
+ font->active_row, row->surface->config.size.w, row->surface->config.size.h,
+ dfb_pixelformat_name(row->surface->config.format) );
+
+ /* Kick out all glyphs. */
+ direct_list_foreach_safe (d, n, row->glyphs) {
+ D_MAGIC_ASSERT( d, CoreGlyphData );
+ D_ASSERT( d->layer < D_ARRAY_SIZE(font->layers) );
+
+ /*ret =*/ direct_hash_remove( font->layers[d->layer].glyph_hash, d->index );
+ //FIXME: use D_ASSERT( ret == DFB_OK );
+
+ if (d->index < 128)
+ font->layers[d->layer].glyph_data[d->index] = NULL;
+
+ D_MAGIC_CLEAR( d );
+ D_FREE( d );
+ }
+
+ /* Reset row. */
+ row->glyphs = NULL;
+ row->next_x = 0;
+ }
+ }
+ else {
+ /* Allocate new font cache row structure. */
+ row = D_CALLOC( 1, sizeof(CoreFontCacheRow) );
+ if (!row) {
+ ret = D_OOM();
+ goto error;
+ }
+
+ /* Create a new font surface. */
+ ret = dfb_surface_create_simple( font->core,
+ font->row_width,
+ MAX( font->height + 1, 8 ),
+ font->pixel_format,
+ font->surface_caps, CSTF_FONT,
+ 0 /* FIXME: no shared fonts, no font id */,
+ NULL, &row->surface );
+ if (ret) {
+ D_DERROR( ret, "Core/Font: Could not create font surface!\n" );
+ D_FREE( row );
+ goto error;
+ }
+
+ D_DEBUG_AT( Core_FontSurfaces, " -> new row %d - %dx%d %s\n", font->num_rows,
+ row->surface->config.size.w, row->surface->config.size.h,
+ dfb_pixelformat_name(row->surface->config.format) );
+
+ D_MAGIC_SET( row, CoreFontCacheRow );
+
+
+ /* Append to array. FIXME: Use vector to avoid realloc each time! */
+ font->rows = D_REALLOC( font->rows, sizeof(void*) * (font->num_rows + 1) );
+ D_ASSERT( font->rows != NULL );
+
+ font->rows[font->num_rows] = row;
+
+ /* Set new row to use. */
+ font->active_row = font->num_rows++;
+ }
+ }
+
+ D_MAGIC_ASSERT( row, CoreFontCacheRow );
+ D_ASSERT( font->num_rows > 0 );
+ D_ASSERT( font->num_rows <= font->max_rows || font->max_rows < 0 );
+ D_ASSERT( font->active_row >= 0 );
+ D_ASSERT( font->active_row < font->num_rows );
+ D_ASSERT( row == font->rows[font->active_row] );
+
+ D_DEBUG_AT( Core_FontSurfaces, " -> render %2d - %2dx%2d at %d:%03d font <%p>\n",
+ index, data->width, data->height, font->active_row, row->next_x, font );
+
+ data->row = font->active_row;
+ data->start = row->next_x;
+ data->surface = row->surface;
+
+ align = (8 / (DFB_BYTES_PER_PIXEL( font->pixel_format ) ? : 1)) *
+ (DFB_PIXELFORMAT_ALIGNMENT( font->pixel_format ) + 1) - 1;
+
+ row->next_x += (data->width + align) & ~align;
+
+ row->stamp = font->row_stamp++;
+
+ /* Render the glyph data into the surface. */
+ ret = font->RenderGlyph( font, index, data );
+ if (ret) {
+ data->start = data->width = data->height = 0;
+ data->failed = true;
+ goto out;
+ }
+
+ dfb_gfxcard_flush_texture_cache();
+
+
+out:
+ if (!data->inserted) {
+ if (row)
+ direct_list_append( &row->glyphs, &data->link );
+
+ direct_hash_insert( font->layers[layer].glyph_hash, index, data );
+
+ if (index < 128)
+ font->layers[layer].glyph_data[index] = data;
+
+ data->inserted = true;
+ }
+
+ *ret_data = data;
+
+ return DFB_OK;
+
+
+error:
+ D_MAGIC_CLEAR( data );
+ D_FREE( data );
+
+ return ret;
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_font_register_encoding( CoreFont *font,
+ const char *name,
+ const CoreFontEncodingFuncs *funcs,
+ DFBTextEncodingID encoding_id )
+{
+ CoreFontEncoding *encoding;
+ CoreFontEncoding **encodings;
+
+ D_DEBUG_AT( Core_Font, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( font, CoreFont );
+ D_ASSERT( encoding_id == DTEID_UTF8 || name != NULL );
+ D_ASSERT( funcs != NULL );
+
+ if (!funcs->GetCharacterIndex)
+ return DFB_INVARG;
+
+ /* Special case for default, native format. */
+ if (encoding_id == DTEID_UTF8) {
+ font->utf8 = funcs;
+
+ return DFB_OK;
+ }
+
+ if (!funcs->DecodeText)
+ return DFB_INVARG;
+
+ /* Setup new encoding information. */
+ encoding = D_CALLOC( 1, sizeof(CoreFontEncoding) );
+ if (!encoding)
+ return D_OOM();
+
+ encoding->encoding = font->last_encoding + 1;
+ encoding->funcs = funcs;
+ encoding->name = D_STRDUP( name );
+
+ if (!encoding->name) {
+ D_FREE( encoding );
+ return D_OOM();
+ }
+
+ /* Add to array. */
+ encodings = D_REALLOC( font->encodings,
+ (encoding->encoding + 1) * sizeof(CoreFontEncoding*) );
+ if (!encodings) {
+ D_FREE( encoding->name );
+ D_FREE( encoding );
+ return D_OOM();
+ }
+
+ font->encodings = encodings;
+
+ font->last_encoding++;
+
+ D_ASSERT( font->last_encoding == encoding->encoding );
+
+ encodings[encoding->encoding] = encoding;
+
+ D_MAGIC_SET( encoding, CoreFontEncoding );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_font_decode_text( CoreFont *font,
+ DFBTextEncodingID encoding,
+ const void *text,
+ int length,
+ unsigned int *ret_indices,
+ int *ret_num )
+{
+ int pos = 0, num = 0;
+ const u8 *bytes = text;
+
+ D_DEBUG_AT( Core_Font, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( font, CoreFont );
+ D_ASSERT( text != NULL );
+ D_ASSERT( length >= 0 ); /* TODO: handle -1 here? */
+ D_ASSERT( ret_indices != NULL );
+ D_ASSERT( ret_num != NULL );
+
+ if (encoding != DTEID_UTF8) {
+ if (encoding > font->last_encoding)
+ return DFB_IDNOTFOUND;
+
+ D_ASSERT( font->encodings[encoding] != NULL );
+ D_ASSERT( font->encodings[encoding]->funcs != NULL );
+ D_ASSERT( font->encodings[encoding]->funcs->DecodeText != NULL );
+
+ return font->encodings[encoding]->funcs->DecodeText( font, text, length,
+ ret_indices, ret_num );
+ }
+ else if (font->utf8) {
+ const CoreFontEncodingFuncs *funcs = font->utf8;
+
+ if (funcs->DecodeText)
+ return funcs->DecodeText( font, text, length, ret_indices, ret_num );
+
+ D_ASSERT( funcs->GetCharacterIndex != NULL );
+
+ 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 (funcs->GetCharacterIndex( font, c, &ret_indices[num] ) == DFB_OK)
+ num++;
+ }
+
+ }
+ else {
+ while (pos < length) {
+ if (bytes[pos] < 128)
+ ret_indices[num++] = bytes[pos++];
+ else {
+ ret_indices[num++] = DIRECT_UTF8_GET_CHAR( &bytes[pos] );
+ pos += DIRECT_UTF8_SKIP(bytes[pos]);
+ }
+ }
+ }
+
+ *ret_num = num;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_font_decode_character( CoreFont *font,
+ DFBTextEncodingID encoding,
+ u32 character,
+ unsigned int *ret_index )
+{
+ D_DEBUG_AT( Core_Font, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( font, CoreFont );
+ D_ASSERT( ret_index != NULL );
+
+ if (encoding > font->last_encoding)
+ return DFB_IDNOTFOUND;
+
+ if (encoding != DTEID_UTF8) {
+ D_ASSERT( font->encodings[encoding] != NULL );
+ D_ASSERT( font->encodings[encoding]->funcs != NULL );
+ D_ASSERT( font->encodings[encoding]->funcs->GetCharacterIndex != NULL );
+
+ return font->encodings[encoding]->funcs->GetCharacterIndex( font, character, ret_index );
+ }
+ else if (font->utf8) {
+ const CoreFontEncodingFuncs *funcs = font->utf8;
+
+ D_ASSERT( funcs->GetCharacterIndex != NULL );
+
+ return funcs->GetCharacterIndex( font, character, ret_index );
+ }
+ else
+ *ret_index = character;
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+static bool
+free_glyphs( DirectHash *hash,
+ unsigned long key,
+ void *value,
+ void *ctx )
+{
+ CoreGlyphData *data = value;
+
+ D_MAGIC_ASSERT( data, CoreGlyphData );
+
+ D_MAGIC_CLEAR( data );
+ D_FREE( data );
+
+ return true;
+}
+
diff --git a/Source/DirectFB/src/core/fonts.h b/Source/DirectFB/src/core/fonts.h
new file mode 100755
index 0000000..4dc04fa
--- /dev/null
+++ b/Source/DirectFB/src/core/fonts.h
@@ -0,0 +1,250 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __FONTS_H__
+#define __FONTS_H__
+
+#include <pthread.h>
+
+#include <fusion/lock.h>
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+#include <core/state.h>
+
+/*
+ * glyph struct
+ */
+struct _CoreGlyphData {
+ DirectLink link;
+
+ unsigned int index;
+ unsigned int layer;
+ unsigned int row;
+
+ CoreSurface *surface; /* contains bitmap of glyph */
+ int start; /* x offset of glyph in surface */
+ int width; /* width of the glyphs bitmap */
+ int height; /* height of the glyphs bitmap */
+ int left; /* x offset of the glyph */
+ int top; /* y offset of the glyph */
+ int xadvance; /* placement of next glyph */
+ int yadvance;
+
+ bool inserted;
+ bool failed;
+
+ int magic;
+};
+
+typedef struct {
+ DFBResult (* GetCharacterIndex) ( CoreFont *thiz,
+ unsigned int character,
+ unsigned int *ret_index );
+
+ DFBResult (* DecodeText) ( CoreFont *thiz,
+ const void *text,
+ int length,
+ unsigned int *ret_indices,
+ int *ret_num );
+} CoreFontEncodingFuncs;
+
+typedef struct {
+ DirectLink link;
+
+ DFBTextEncodingID encoding;
+ char *name;
+ const CoreFontEncodingFuncs *funcs;
+
+ int magic;
+} CoreFontEncoding;
+
+typedef struct {
+ unsigned int stamp;
+
+ CoreSurface *surface;
+ int next_x;
+
+ DirectLink *glyphs;
+
+ int magic;
+} CoreFontCacheRow;
+
+
+#define DFB_FONT_MAX_LAYERS 2
+
+/*
+ * font struct
+ */
+
+struct _CoreFont {
+ CoreDFB *core;
+
+ DFBFontDescription description; /* original description used to create the font */
+ char *url;
+
+ DFBSurfaceBlittingFlags blittingflags;
+ DFBSurfacePixelFormat pixel_format;
+ DFBSurfaceCapabilities surface_caps;
+ int row_width;
+ int max_rows;
+
+ DFBFontAttributes attributes;
+
+ CoreFontCacheRow **rows; /* contain bitmaps of loaded glyphs */
+ int num_rows;
+ int active_row;
+ unsigned int row_stamp;
+
+ struct {
+ DirectHash *glyph_hash; /* infos about loaded glyphs */
+ CoreGlyphData *glyph_data[128];
+ } layers[DFB_FONT_MAX_LAYERS];
+
+ int height; /* font height */
+
+ int ascender; /* a positive value, the distance
+ from the baseline to the top */
+ int descender; /* a negative value, the distance
+ from the baseline to the bottom */
+ int maxadvance; /* width of largest character */
+
+ float up_unit_x; /* unit vector pointing 'up' in for */
+ float up_unit_y; /* this font's rotation */
+
+ pthread_mutex_t lock; /* lock during access to the font */
+
+ const CoreFontEncodingFuncs *utf8; /* for default encoding, DTEID_UTF8 */
+ CoreFontEncoding **encodings; /* for other encodings */
+ DFBTextEncodingID last_encoding; /* dynamic allocation impl. helper */
+
+ void *impl_data; /* a pointer used by the impl. */
+
+ DFBResult (* GetGlyphData) ( CoreFont *thiz,
+ unsigned int index,
+ CoreGlyphData *data );
+
+ DFBResult (* RenderGlyph) ( CoreFont *thiz,
+ unsigned int index,
+ CoreGlyphData *data );
+
+ DFBResult (* GetKerning) ( CoreFont *thiz,
+ unsigned int prev,
+ unsigned int current,
+ int *ret_x,
+ int *ret_y );
+
+
+ int magic;
+};
+
+/*
+ * allocates and initializes a new font structure
+ */
+DFBResult dfb_font_create( CoreDFB *core,
+ const DFBFontDescription *description,
+ const char *url,
+ CoreFont **ret_font );
+
+/*
+ * destroy all data in the CoreFont struct
+ */
+void dfb_font_destroy( CoreFont *font );
+
+/*
+ * lock the font before accessing it
+ */
+static inline void
+dfb_font_lock( CoreFont *font )
+{
+ D_MAGIC_ASSERT( font, CoreFont );
+
+ pthread_mutex_lock( &font->lock );
+}
+
+/*
+ * unlock the font after access
+ */
+static inline void
+dfb_font_unlock( CoreFont *font )
+{
+ D_MAGIC_ASSERT( font, CoreFont );
+
+ pthread_mutex_unlock( &font->lock );
+}
+
+/*
+ * loads glyph data from font
+ */
+DFBResult dfb_font_get_glyph_data( CoreFont *font,
+ unsigned int index,
+ unsigned int layer,
+ CoreGlyphData **glyph_data );
+
+
+/*
+ * Called by font module to register encoding implementations.
+ *
+ * The encoding can be DTEID_UTF8 or DTEID_OTHER, where in the
+ * latter case the actual id will be allocated dynamically.
+ *
+ * In the case of DTEID_UTF8 it's allowed to only provide
+ * GetCharacterIndex() and let the core do the DecodeText(),
+ * but that would cause a GetCharacterIndex() call per decoded
+ * unicode character. So implementing both is advisable.
+ *
+ * If nothing is registered for DTEID_UTF8 at all, the core will
+ * pass the raw unicode characters to GetGlyphInfo(), RenderGlyph() etc.
+ * That's the old behaviour, fully compatible with old modules. It's
+ * also a good choice if you want to avoid the character translation,
+ * having an efficient font module which is based natively on unicode
+ * characters.
+ *
+ * For registering an encoding as DTEID_OTHER both GetCharacterIndex()
+ * and DecodeText() must be provided.
+ */
+DFBResult dfb_font_register_encoding( CoreFont *font,
+ const char *name,
+ const CoreFontEncodingFuncs *funcs,
+ DFBTextEncodingID encoding );
+
+DFBResult dfb_font_decode_text( CoreFont *font,
+ DFBTextEncodingID encoding,
+ const void *text,
+ int length,
+ unsigned int *ret_indices,
+ int *ret_num );
+
+DFBResult dfb_font_decode_character( CoreFont *font,
+ DFBTextEncodingID encoding,
+ u32 character,
+ unsigned int *ret_index );
+
+#endif
diff --git a/Source/DirectFB/src/core/gfxcard.c b/Source/DirectFB/src/core/gfxcard.c
new file mode 100755
index 0000000..84e725c
--- /dev/null
+++ b/Source/DirectFB/src/core/gfxcard.c
@@ -0,0 +1,2921 @@
+/*
+ (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 <limits.h>
+#include <string.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/memcpy.h>
+
+#include <fusion/fusion.h>
+#include <fusion/shmalloc.h>
+#include <fusion/arena.h>
+#include <fusion/property.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/core_parts.h>
+#include <core/gfxcard.h>
+#include <core/fonts.h>
+#include <core/state.h>
+#include <core/palette.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+#include <core/surface_pool.h>
+#include <core/system.h>
+
+#include <gfx/generic/generic.h>
+#include <gfx/clip.h>
+#include <gfx/util.h>
+
+#include <direct/hash.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/modules.h>
+#include <direct/utf8.h>
+#include <direct/util.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+
+D_DEBUG_DOMAIN( Core_Graphics, "Core/Graphics", "DirectFB Graphics Core" );
+D_DEBUG_DOMAIN( Core_GraphicsOps, "Core/GraphicsOps", "DirectFB Graphics Core Operations" );
+D_DEBUG_DOMAIN( Core_GfxState, "Core/GfxState", "DirectFB Graphics Core State" );
+
+
+DEFINE_MODULE_DIRECTORY( dfb_graphics_drivers, "gfxdrivers", DFB_GRAPHICS_DRIVER_ABI_VERSION );
+
+/**********************************************************************************************************************/
+
+static void dfb_gfxcard_find_driver( CoreDFB *core );
+static void dfb_gfxcard_load_driver( void );
+
+static void fill_tri( DFBTriangle *tri, CardState *state, bool accelerated );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+ /* amount of usable memory */
+ unsigned int videoram_length;
+ unsigned int auxram_length;
+ unsigned int auxram_offset;
+
+ char *module_name;
+
+ GraphicsDriverInfo driver_info;
+ GraphicsDeviceInfo device_info;
+ void *device_data;
+
+ FusionProperty lock;
+ GraphicsDeviceLockFlags lock_flags;
+
+ /*
+ * Points to the current state of the graphics card.
+ */
+ CardState *state;
+ FusionID holder; /* Fusion ID of state owner. */
+} DFBGraphicsCoreShared;
+
+struct __DFB_DFBGraphicsCore {
+ int magic;
+
+ CoreDFB *core;
+
+ DFBGraphicsCoreShared *shared;
+
+ DirectModuleEntry *module;
+ const GraphicsDriverFuncs *driver_funcs;
+
+ void *driver_data;
+ void *device_data; /* copy of shared->device_data */
+
+ CardCapabilities caps; /* local caps */
+ CardLimitations limits; /* local limits */
+
+ GraphicsDeviceFuncs funcs;
+};
+
+
+DFB_CORE_PART( graphics_core, GraphicsCore );
+
+/**********************************************************************************************************************/
+
+static CoreGraphicsDevice *card; /* FIXME */
+
+/* Hook for registering additional screen(s) and layer(s) in app or lib initializing DirectFB. */
+void (*__DFB_CoreRegisterHook)( CoreDFB *core, CoreGraphicsDevice *device, void *ctx ) = NULL;
+void *__DFB_CoreRegisterHookCtx = NULL;
+
+
+/** public **/
+
+static DFBResult
+dfb_graphics_core_initialize( CoreDFB *core,
+ DFBGraphicsCore *data,
+ DFBGraphicsCoreShared *shared )
+{
+ DFBResult ret;
+ int videoram_length;
+ int auxram_length;
+ FusionSHMPoolShared *pool = dfb_core_shmpool( core );
+
+ D_DEBUG_AT( Core_Graphics, "dfb_graphics_core_initialize( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( shared != NULL );
+
+
+ card = data; /* FIXME */
+
+ data->core = core;
+ data->shared = shared;
+
+
+ /* fill generic driver info */
+ gGetDriverInfo( &shared->driver_info );
+
+ /* fill generic device info */
+ gGetDeviceInfo( &shared->device_info );
+
+ if (!shared->device_info.limits.dst_max.w)
+ shared->device_info.limits.dst_max.w = INT_MAX;
+
+ if (!shared->device_info.limits.dst_max.h)
+ shared->device_info.limits.dst_max.h = INT_MAX;
+
+ /* Limit video ram length */
+ videoram_length = dfb_system_videoram_length();
+ if (videoram_length) {
+ if (dfb_config->videoram_limit > 0 &&
+ dfb_config->videoram_limit < videoram_length)
+ shared->videoram_length = dfb_config->videoram_limit;
+ else
+ shared->videoram_length = videoram_length;
+ }
+
+ /* Limit auxiliary memory length (currently only AGP) */
+ auxram_length = dfb_system_auxram_length();
+ if (auxram_length) {
+ if (dfb_config->agpmem_limit > 0 &&
+ dfb_config->agpmem_limit < auxram_length)
+ shared->auxram_length = dfb_config->agpmem_limit;
+ else
+ shared->auxram_length = auxram_length;
+ }
+
+ /* Build a list of available drivers. */
+ direct_modules_explore_directory( &dfb_graphics_drivers );
+
+ /* Load driver */
+ if (dfb_system_caps() & CSCAPS_ACCELERATION)
+ dfb_gfxcard_find_driver( core );
+
+ if (data->driver_funcs) {
+ const GraphicsDriverFuncs *funcs = data->driver_funcs;
+
+ data->driver_data = D_CALLOC( 1, shared->driver_info.driver_data_size );
+
+ card->device_data =
+ shared->device_data = SHCALLOC( pool, 1, shared->driver_info.device_data_size );
+
+ ret = funcs->InitDriver( card, &card->funcs,
+ card->driver_data, card->device_data, core );
+ if (ret) {
+ SHFREE( pool, shared->device_data );
+ SHFREE( pool, shared->module_name );
+ D_FREE( card->driver_data );
+ card = NULL;
+ return ret;
+ }
+
+ ret = funcs->InitDevice( data, &shared->device_info,
+ data->driver_data, data->device_data );
+ if (ret) {
+ funcs->CloseDriver( card, card->driver_data );
+ SHFREE( pool, shared->device_data );
+ SHFREE( pool, shared->module_name );
+ D_FREE( card->driver_data );
+ card = NULL;
+ return ret;
+ }
+
+ if (data->funcs.EngineReset)
+ data->funcs.EngineReset( data->driver_data, data->device_data );
+ }
+
+ D_INFO( "DirectFB/Graphics: %s %s %d.%d (%s)\n",
+ shared->device_info.vendor, shared->device_info.name,
+ shared->driver_info.version.major,
+ shared->driver_info.version.minor, shared->driver_info.vendor );
+
+ if (dfb_config->software_only) {
+ if (data->funcs.CheckState) {
+ data->funcs.CheckState = NULL;
+
+ D_INFO( "DirectFB/Graphics: Acceleration disabled (by 'no-hardware')\n" );
+ }
+ }
+ else {
+ data->caps = shared->device_info.caps;
+ data->limits = shared->device_info.limits;
+ }
+
+ fusion_property_init( &shared->lock, dfb_core_world(core) );
+
+ if (__DFB_CoreRegisterHook)
+ __DFB_CoreRegisterHook( core, card, __DFB_CoreRegisterHookCtx );
+
+ D_MAGIC_SET( data, DFBGraphicsCore );
+ D_MAGIC_SET( shared, DFBGraphicsCoreShared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_graphics_core_join( CoreDFB *core,
+ DFBGraphicsCore *data,
+ DFBGraphicsCoreShared *shared )
+{
+ DFBResult ret;
+ GraphicsDriverInfo driver_info;
+
+ D_DEBUG_AT( Core_Graphics, "dfb_graphics_core_join( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_MAGIC_ASSERT( shared, DFBGraphicsCoreShared );
+
+ card = data; /* FIXME */
+
+ data->core = core;
+ data->shared = shared;
+
+ /* Initialize software rasterizer. */
+ gGetDriverInfo( &driver_info );
+
+ /* Build a list of available drivers. */
+ direct_modules_explore_directory( &dfb_graphics_drivers );
+
+ /* Load driver. */
+ if (dfb_system_caps() & CSCAPS_ACCELERATION)
+ dfb_gfxcard_load_driver();
+
+ if (data->driver_funcs) {
+ const GraphicsDriverFuncs *funcs = data->driver_funcs;
+
+ data->driver_data = D_CALLOC( 1, shared->driver_info.driver_data_size );
+
+ data->device_data = shared->device_data;
+
+ ret = funcs->InitDriver( card, &card->funcs,
+ card->driver_data, card->device_data, core );
+ if (ret) {
+ D_FREE( data->driver_data );
+ data = NULL;
+ return ret;
+ }
+ }
+ else if (shared->module_name) {
+ D_ERROR( "DirectFB/Graphics: Could not load driver used by the running session!\n" );
+ data = NULL;
+ return DFB_UNSUPPORTED;
+ }
+
+
+ D_INFO( "DirectFB/Graphics: %s %s %d.%d (%s)\n",
+ shared->device_info.vendor, shared->device_info.name,
+ shared->driver_info.version.major,
+ shared->driver_info.version.minor, shared->driver_info.vendor );
+
+ if (dfb_config->software_only) {
+ if (data->funcs.CheckState) {
+ data->funcs.CheckState = NULL;
+
+ D_INFO( "DirectFB/Graphics: Acceleration disabled (by 'no-hardware')\n" );
+ }
+ }
+ else {
+ data->caps = shared->device_info.caps;
+ data->limits = shared->device_info.limits;
+ }
+
+ D_MAGIC_SET( data, DFBGraphicsCore );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_graphics_core_shutdown( DFBGraphicsCore *data,
+ bool emergency )
+{
+ DFBGraphicsCoreShared *shared;
+ FusionSHMPoolShared *pool = dfb_core_shmpool( data->core );
+
+ D_DEBUG_AT( Core_Graphics, "dfb_graphics_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBGraphicsCore );
+ D_MAGIC_ASSERT( data->shared, DFBGraphicsCoreShared );
+
+ shared = data->shared;
+
+
+ dfb_gfxcard_lock( GDLF_SYNC );
+
+ if (data->driver_funcs) {
+ const GraphicsDriverFuncs *funcs = data->driver_funcs;
+
+ funcs->CloseDevice( data, data->driver_data, data->device_data );
+ funcs->CloseDriver( data, data->driver_data );
+
+ direct_module_unref( data->module );
+
+ SHFREE( pool, card->device_data );
+ D_FREE( card->driver_data );
+ }
+
+ fusion_property_destroy( &shared->lock );
+
+ if (shared->module_name)
+ SHFREE( pool, shared->module_name );
+
+
+ D_MAGIC_CLEAR( data );
+ D_MAGIC_CLEAR( shared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_graphics_core_leave( DFBGraphicsCore *data,
+ bool emergency )
+{
+ DFBGraphicsCoreShared *shared;
+
+ D_DEBUG_AT( Core_Graphics, "dfb_graphics_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBGraphicsCore );
+ D_MAGIC_ASSERT( data->shared, DFBGraphicsCoreShared );
+
+ shared = data->shared;
+
+ if (data->driver_funcs) {
+ data->driver_funcs->CloseDriver( data, data->driver_data );
+
+ direct_module_unref( data->module );
+
+ D_FREE( data->driver_data );
+ }
+
+
+ D_MAGIC_CLEAR( data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_graphics_core_suspend( DFBGraphicsCore *data )
+{
+ DFBGraphicsCoreShared *shared;
+
+ D_DEBUG_AT( Core_Graphics, "dfb_graphics_core_suspend( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBGraphicsCore );
+ D_MAGIC_ASSERT( data->shared, DFBGraphicsCoreShared );
+
+ shared = data->shared;
+
+ dfb_gfxcard_lock( GDLF_WAIT | GDLF_SYNC | GDLF_RESET | GDLF_INVALIDATE );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_graphics_core_resume( DFBGraphicsCore *data )
+{
+ DFBGraphicsCoreShared *shared;
+
+ D_DEBUG_AT( Core_Graphics, "dfb_graphics_core_resume( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBGraphicsCore );
+ D_MAGIC_ASSERT( data->shared, DFBGraphicsCoreShared );
+
+ shared = data->shared;
+
+ dfb_gfxcard_unlock();
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_gfxcard_lock( GraphicsDeviceLockFlags flags )
+{
+ DFBResult ret;
+ DFBGraphicsCoreShared *shared;
+ GraphicsDeviceFuncs *funcs;
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+ shared = card->shared;
+ funcs = &card->funcs;
+
+ if ( ((flags & GDLF_WAIT) ?
+ fusion_property_purchase( &shared->lock ) :
+ fusion_property_lease( &shared->lock )) )
+ return DFB_FAILURE;
+
+ if ((flags & GDLF_SYNC) && funcs->EngineSync) {
+ ret = funcs->EngineSync( card->driver_data, card->device_data );
+ if (ret) {
+ if (funcs->EngineReset)
+ funcs->EngineReset( card->driver_data, card->device_data );
+
+ shared->state = NULL;
+
+ fusion_property_cede( &shared->lock );
+
+ return ret;
+ }
+ }
+
+ if ((shared->lock_flags & GDLF_RESET) && funcs->EngineReset)
+ funcs->EngineReset( card->driver_data, card->device_data );
+
+ if (shared->lock_flags & GDLF_INVALIDATE) {
+ if (funcs->InvalidateState)
+ funcs->InvalidateState( card->driver_data, card->device_data );
+ shared->state = NULL;
+ }
+
+ shared->lock_flags = flags;
+
+ return DFB_OK;
+}
+
+void
+dfb_gfxcard_unlock( void )
+{
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+ fusion_property_cede( &card->shared->lock );
+}
+
+void
+dfb_gfxcard_holdup( void )
+{
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+ fusion_property_holdup( &card->shared->lock );
+}
+
+/*
+ * Signal beginning of a sequence of operations using this state.
+ * Any number of states can be 'drawing'.
+ */
+void
+dfb_gfxcard_start_drawing( CoreGraphicsDevice *device, CardState *state )
+{
+ D_ASSERT( device != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+
+ if (device->funcs.StartDrawing)
+ device->funcs.StartDrawing( device->driver_data, device->device_data, state );
+}
+
+/*
+ * Signal end of sequence, i.e. destination surface is consistent again.
+ */
+void
+dfb_gfxcard_stop_drawing( CoreGraphicsDevice *device, CardState *state )
+{
+ D_ASSERT( device != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+
+ if (device->funcs.StopDrawing)
+ device->funcs.StopDrawing( device->driver_data, device->device_data, state );
+}
+
+/*
+ * This function returns non zero if acceleration is available
+ * for the specific function using the given state.
+ */
+bool
+dfb_gfxcard_state_check( CardState *state, DFBAccelerationMask accel )
+{
+ CoreSurface *dst;
+ CoreSurface *src;
+ CoreSurfaceBuffer *dst_buffer;
+ CoreSurfaceBuffer *src_buffer;
+
+ int cx2, cy2;
+
+ D_ASSERT( card != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_MAGIC_ASSERT_IF( state->destination, CoreSurface );
+ D_MAGIC_ASSERT_IF( state->source, CoreSurface );
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %p, 0x%08x ) [%d,%d - %d,%d]\n",
+ __FUNCTION__, state, accel, DFB_REGION_VALS( &state->clip ) );
+
+ D_ASSERT( state->clip.x2 >= state->clip.x1 );
+ D_ASSERT( state->clip.y2 >= state->clip.y1 );
+ D_ASSERT( state->clip.x1 >= 0 );
+ D_ASSERT( state->clip.y1 >= 0 );
+
+ if (DFB_BLITTING_FUNCTION(accel)) {
+ D_DEBUG_AT( Core_GfxState, "%s( %p, 0x%08x ) blitting %p -> %p\n", __FUNCTION__,
+ state, accel, state->source, state->destination );
+ }
+ else {
+ D_DEBUG_AT( Core_GfxState, "%s( %p, 0x%08x ) drawing -> %p\n", __FUNCTION__,
+ state, accel, state->destination );
+ }
+
+ if (state->clip.x1 < 0) {
+ state->clip.x1 = 0;
+ state->modified |= SMF_CLIP;
+ }
+
+ if (state->clip.y1 < 0) {
+ state->clip.y1 = 0;
+ state->modified |= SMF_CLIP;
+ }
+
+ D_DEBUG_AT( Core_GfxState, " <- checked 0x%08x, accel 0x%08x, modified 0x%08x, mod_hw 0x%08x\n",
+ state->checked, state->accel, state->modified, state->mod_hw );
+
+ dst = state->destination;
+ src = state->source;
+
+ /* Destination may have been destroyed. */
+ if (!dst) {
+ D_BUG( "no destination" );
+ return false;
+ }
+
+ /* Source may have been destroyed. */
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (!src) {
+ D_BUG( "no source" );
+ return false;
+ }
+
+ /* Mask may have been destroyed. */
+ if (state->blittingflags & (DSBLIT_SRC_MASK_ALPHA | DSBLIT_SRC_MASK_COLOR) && !state->source_mask) {
+ D_BUG( "no mask" );
+ return false;
+ }
+ }
+
+ dst_buffer = dfb_surface_get_buffer( dst, state->to );
+ D_MAGIC_ASSERT( dst_buffer, CoreSurfaceBuffer );
+
+ D_ASSUME( state->clip.x2 < dst->config.size.w );
+ D_ASSUME( state->clip.y2 < dst->config.size.h );
+
+ cx2 = state->destination->config.size.w - 1;
+ cy2 = state->destination->config.size.h - 1;
+
+ if (state->clip.x2 > cx2) {
+ state->clip.x2 = cx2;
+
+ if (state->clip.x1 > cx2)
+ state->clip.x1 = cx2;
+
+ state->modified |= SMF_CLIP;
+ }
+
+ if (state->clip.y2 > cy2) {
+ state->clip.y2 = cy2;
+
+ if (state->clip.y1 > cy2)
+ state->clip.y1 = cy2;
+
+ state->modified |= SMF_CLIP;
+ }
+
+
+ /*
+ * If there's no CheckState function there's no acceleration at all.
+ */
+ if (!card->funcs.CheckState)
+ return false;
+
+ /*
+ * Check if this function has been disabled temporarily.
+ */
+ if (state->disabled & accel)
+ return false;
+
+ /* If destination or blend functions have been changed... */
+ if (state->modified & (SMF_DESTINATION | SMF_SRC_BLEND | SMF_DST_BLEND | SMF_RENDER_OPTIONS)) {
+ /* ...force rechecking for all functions. */
+ state->checked = DFXL_NONE;
+ }
+ else {
+ /* If source/mask or blitting flags have been changed... */
+ if (state->modified & (SMF_SOURCE | SMF_BLITTING_FLAGS | SMF_SOURCE_MASK | SMF_SOURCE_MASK_VALS)) {
+ /* ...force rechecking for all blitting functions. */
+ state->checked &= ~DFXL_ALL_BLIT;
+ }
+
+ /* If drawing flags have been changed... */
+ if (state->modified & SMF_DRAWING_FLAGS) {
+ /* ...force rechecking for all drawing functions. */
+ state->checked &= ~DFXL_ALL_DRAW;
+ }
+ }
+
+ D_DEBUG_AT( Core_GfxState, " -> checked 0x%08x, accel 0x%08x, modified 0x%08x, mod_hw 0x%08x\n",
+ state->checked, state->accel, state->modified, state->mod_hw );
+
+ /* If the function needs to be checked... */
+ if (!(state->checked & accel)) {
+ /* Unset unchecked functions. */
+ state->accel &= state->checked;
+
+ /* Call driver to (re)set the bit if the function is supported. */
+ card->funcs.CheckState( card->driver_data, card->device_data, state, accel );
+
+ /* Add the function to 'checked functions'. */
+ state->checked |= accel;
+
+ /* Add additional functions the driver might have checked, too. */
+ state->checked |= state->accel;
+ }
+
+ D_DEBUG_AT( Core_GfxState, " -> checked 0x%08x, accel 0x%08x, modified 0x%08x, mod_hw 0x%08x\n",
+ state->checked, state->accel, state->modified, state->mod_hw );
+
+ /* Move modification flags to the set for drivers. */
+ state->mod_hw |= state->modified;
+ state->modified = 0;
+
+ /*
+ * If back_buffer policy is 'system only' there's no acceleration
+ * available.
+ */
+ if (dst_buffer->policy == CSP_SYSTEMONLY || /* Special check required if driver does not check itself. */
+ ( !(card->caps.flags & CCF_RENDEROPTS) &&
+ (state->render_options & DSRO_MATRIX) ))
+ {
+ /* Clear 'accelerated functions'. */
+ state->accel = DFXL_NONE;
+ state->checked = DFXL_ALL;
+ }
+ else if (DFB_BLITTING_FUNCTION( accel )) {
+ /*
+ * If the front buffer policy of the source is 'system only'
+ * no accelerated blitting is available.
+ */
+ src_buffer = dfb_surface_get_buffer( src, state->from );
+
+ D_MAGIC_ASSERT( src_buffer, CoreSurfaceBuffer );
+
+ if (src_buffer->policy == CSP_SYSTEMONLY && !(card->caps.flags & CCF_READSYSMEM)) {
+ /* Clear 'accelerated blitting functions'. */
+ state->accel &= ~DFXL_ALL_BLIT;
+ state->checked |= DFXL_ALL_BLIT;
+ }
+ }
+
+ D_DEBUG_AT( Core_GfxState, " => checked 0x%08x, accel 0x%08x, modified 0x%08x, mod_hw 0x%08x\n",
+ state->checked, state->accel, state->modified, state->mod_hw );
+
+ /* Return whether the function bit is set. */
+ return !!(state->accel & accel);
+}
+
+/*
+ * This function returns non zero after successful locking the surface(s)
+ * for access by hardware. Propagate state changes to driver.
+ */
+static bool
+dfb_gfxcard_state_acquire( CardState *state, DFBAccelerationMask accel )
+{
+ DFBResult ret;
+ CoreSurface *dst;
+ CoreSurface *src;
+ DFBGraphicsCoreShared *shared;
+ CoreSurfaceAccessFlags access = CSAF_WRITE;
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+ D_MAGIC_ASSERT( state, CardState );
+ D_MAGIC_ASSERT_IF( state->destination, CoreSurface );
+ D_MAGIC_ASSERT_IF( state->source, CoreSurface );
+
+ dst = state->destination;
+ src = state->source;
+ shared = card->shared;
+
+ /* find locking flags */
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL |
+ DSBLIT_BLEND_COLORALPHA |
+ DSBLIT_DST_COLORKEY))
+ access |= CSAF_READ;
+ }
+ else if (state->drawingflags & (DSDRAW_BLEND | DSDRAW_DST_COLORKEY))
+ access |= CSAF_READ;
+
+ if (DFB_BLITTING_FUNCTION(accel)) {
+ D_DEBUG_AT( Core_GfxState, "%s( %p, 0x%08x ) blitting %p -> %p\n", __FUNCTION__,
+ state, accel, state->source, state->destination );
+ }
+ else {
+ D_DEBUG_AT( Core_GfxState, "%s( %p, 0x%08x ) drawing -> %p\n", __FUNCTION__,
+ state, accel, state->destination );
+ }
+
+ /* lock destination */
+ ret = dfb_surface_lock_buffer( dst, state->to, CSAID_GPU, access, &state->dst );
+ if (ret) {
+ D_DEBUG_AT( Core_Graphics, "Could not lock destination for GPU access!\n" );
+ return false;
+ }
+
+ /* if blitting... */
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ /* ...lock source for reading */
+ ret = dfb_surface_lock_buffer( src, state->from, CSAID_GPU, CSAF_READ, &state->src );
+ if (ret) {
+ D_DEBUG_AT( Core_Graphics, "Could not lock source for GPU access!\n" );
+ dfb_surface_unlock_buffer( dst, &state->dst );
+ return false;
+ }
+
+ state->flags |= CSF_SOURCE_LOCKED;
+
+ /* if using a mask... */
+ if (state->blittingflags & (DSBLIT_SRC_MASK_ALPHA | DSBLIT_SRC_MASK_COLOR)) {
+ /* ...lock source mask for reading */
+ ret = dfb_surface_lock_buffer( state->source_mask, state->from, CSAID_GPU, CSAF_READ, &state->src_mask );
+ if (ret) {
+ D_DEBUG_AT( Core_Graphics, "Could not lock source mask for GPU access!\n" );
+ dfb_surface_unlock_buffer( src, &state->src );
+ dfb_surface_unlock_buffer( dst, &state->dst );
+ return false;
+ }
+
+ state->flags |= CSF_SOURCE_MASK_LOCKED;
+ }
+ }
+
+ /*
+ * Make sure that state setting with subsequent command execution
+ * isn't done by two processes simultaneously.
+ *
+ * This will timeout if the hardware is locked by another party with
+ * the first argument being true (e.g. DRI).
+ */
+ if (dfb_gfxcard_lock( GDLF_NONE )) {
+ D_DERROR( ret, "Core/Graphics: Could not lock GPU!\n" );
+
+ dfb_surface_unlock_buffer( dst, &state->dst );
+
+ if (state->flags & CSF_SOURCE_LOCKED) {
+ dfb_surface_unlock_buffer( src, &state->src );
+ state->flags &= ~CSF_SOURCE_LOCKED;
+ }
+
+ /* if source mask got locked this value is true */
+ if (state->flags & CSF_SOURCE_MASK_LOCKED) {
+ dfb_surface_unlock_buffer( state->source_mask, &state->src_mask );
+
+ state->flags &= ~CSF_SOURCE_MASK_LOCKED;
+ }
+
+ return false;
+ }
+
+ /* if we are switching to another state... */
+ if (state != shared->state || state->fusion_id != shared->holder) {
+ D_DEBUG_AT( Core_GfxState, " -> switch from %p [%lu] to %p [%lu]\n",
+ shared->state, shared->holder, state, state->fusion_id );
+
+ /* ...set all modification bits and clear 'set functions' */
+ state->mod_hw |= SMF_ALL;
+ state->set = 0;
+
+ shared->state = state;
+ shared->holder = state->fusion_id;
+ }
+
+ dfb_state_update( state, state->flags & (CSF_SOURCE_LOCKED | CSF_SOURCE_MASK_LOCKED) );
+
+ D_DEBUG_AT( Core_GfxState, " -> mod_hw 0x%08x, modified 0x%08x\n", state->mod_hw, state->modified );
+
+ /* Move modification flags to the set for drivers. */
+ state->mod_hw |= state->modified;
+ state->modified = SMF_ALL;
+
+ /*
+ * If function hasn't been set or state is modified,
+ * call the driver function to propagate the state changes.
+ */
+ D_DEBUG_AT( Core_GfxState, " -> mod_hw 0x%08x, set 0x%08x\n", state->mod_hw, state->set );
+ if (state->mod_hw || !(state->set & accel)) {
+ card->funcs.SetState( card->driver_data, card->device_data,
+ &card->funcs, state, accel );
+
+ D_DEBUG_AT( Core_GfxState, " => mod_hw 0x%08x, set 0x%08x\n", state->mod_hw, state->set );
+ }
+
+ if (state->modified != SMF_ALL)
+ D_ONCE( "USING OLD DRIVER! *** Use 'state->mod_hw' NOT 'modified'." );
+
+ state->modified = 0;
+
+ return true;
+}
+
+/*
+ * Unlock destination and possibly the source.
+ */
+static void
+dfb_gfxcard_state_release( CardState *state )
+{
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( state->destination != NULL );
+
+ /* start command processing if not already running */
+ if (card->funcs.EmitCommands)
+ card->funcs.EmitCommands( card->driver_data, card->device_data );
+
+ /* Store the serial of the operation. */
+#if FIXME_SC_2
+ if (card->funcs.GetSerial) {
+ card->funcs.GetSerial( card->driver_data, card->device_data, &state->serial );
+
+ state->destination->back_buffer->video.serial = state->serial;
+ }
+#endif
+
+ /* allow others to use the hardware */
+ dfb_gfxcard_unlock();
+
+ /* destination always gets locked during acquisition */
+ dfb_surface_unlock_buffer( state->destination, &state->dst );
+
+ /* if source got locked this value is true */
+ if (state->flags & CSF_SOURCE_LOCKED) {
+ dfb_surface_unlock_buffer( state->source, &state->src );
+
+ state->flags &= ~CSF_SOURCE_LOCKED;
+ }
+
+ /* if source mask got locked this value is true */
+ if (state->flags & CSF_SOURCE_MASK_LOCKED) {
+ dfb_surface_unlock_buffer( state->source_mask, &state->src_mask );
+
+ state->flags &= ~CSF_SOURCE_MASK_LOCKED;
+ }
+}
+
+/** DRAWING FUNCTIONS **/
+
+#define DFB_TRANSFORM(x, y, m, affine) \
+do { \
+ s32 _x, _y, _w; \
+ if (affine) { \
+ _x = ((x) * (m)[0] + (y) * (m)[1] + (m)[2] + 0x8000) >> 16; \
+ _y = ((x) * (m)[3] + (y) * (m)[4] + (m)[5] + 0x8000) >> 16; \
+ } \
+ else { \
+ _x = ((x) * (m)[0] + (y) * (m)[1] + (m)[2]); \
+ _y = ((x) * (m)[3] + (y) * (m)[4] + (m)[5]); \
+ _w = ((x) * (m)[6] + (y) * (m)[7] + (m)[8]); \
+ if (!_w) { \
+ _x = (_x < 0) ? -0x7fffffff : 0x7fffffff; \
+ _y = (_y < 0) ? -0x7fffffff : 0x7fffffff; \
+ } \
+ else { \
+ _x /= _w; \
+ _y /= _w; \
+ } \
+ } \
+ (x) = _x; \
+ (y) = _y; \
+} while (0)
+
+void
+dfb_gfxcard_fillrectangles( const DFBRectangle *rects, int num, CardState *state )
+{
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %p [%d], %p )\n", __FUNCTION__, rects, num, state );
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( rects != NULL );
+ D_ASSERT( num > 0 );
+
+ /* The state is locked during graphics operations. */
+ dfb_state_lock( state );
+
+ /* Signal beginning of sequence of operations if not already done. */
+ dfb_state_start_drawing( state, card );
+
+ if (!(state->render_options & DSRO_MATRIX)) {
+ while (num > 0) {
+ if (dfb_rectangle_region_intersects( rects, &state->clip ))
+ break;
+
+ rects++;
+ num--;
+ }
+ }
+
+ if (num > 0) {
+ int i = 0;
+ DFBRectangle rect;
+
+ /* Check for acceleration and setup execution. */
+ if (dfb_gfxcard_state_check( state, DFXL_FILLRECTANGLE ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_FILLRECTANGLE ))
+ {
+ /*
+ * Now everything is prepared for execution of the
+ * FillRectangle driver function.
+ */
+ for (; i<num; i++) {
+ if (!(state->render_options & DSRO_MATRIX) &&
+ !dfb_rectangle_region_intersects( &rects[i], &state->clip ))
+ continue;
+
+ rect = rects[i];
+
+ if (rect.w > card->limits.dst_max.w || rect.h > card->limits.dst_max.h) {
+ dfb_clip_rectangle( &state->clip, &rect );
+
+ if (rect.w > card->limits.dst_max.w || rect.h > card->limits.dst_max.h)
+ break;
+ }
+ else if (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) &&
+ !D_FLAGS_IS_SET( card->caps.clip, DFXL_FILLRECTANGLE ))
+ dfb_clip_rectangle( &state->clip, &rect );
+
+ if (!card->funcs.FillRectangle( card->driver_data,
+ card->device_data, &rect ))
+ break;
+ }
+
+ /* Release after state acquisition. */
+ dfb_gfxcard_state_release( state );
+ }
+
+ if (i < num) {
+ /* Use software fallback. */
+ if (gAcquire( state, DFXL_FILLRECTANGLE )) {
+ if (!(state->render_options & DSRO_MATRIX)) {
+ for (; i<num; i++) {
+ rect = rects[i];
+
+ if (dfb_clip_rectangle( &state->clip, &rect ))
+ gFillRectangle( state, &rect );
+ }
+ }
+ else if (state->matrix[1] == 0 && state->matrix[3] == 0) {
+ /* Scaled/Translated Rectangle. */
+ for (; i<num; i++) {
+ int x1, y1, x2, y2;
+
+ x1 = rects[i].x; y1 = rects[i].y;
+ x2 = x1+rects[i].w; y2 = y1+rects[i].h;
+ DFB_TRANSFORM(x1, y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(x2, y2, state->matrix, state->affine_matrix);
+
+ if (x1 < x2) {
+ rect.x = x1;
+ rect.w = x2-x1;
+ } else {
+ rect.x = x2;
+ rect.w = x1-x2;
+ }
+ if (y1 < y2) {
+ rect.y = y1;
+ rect.h = y2-y1;
+ }
+ else {
+ rect.y = y2;
+ rect.h = y1-y2;
+ }
+
+ if (dfb_clip_rectangle( &state->clip, &rect ))
+ gFillRectangle( state, &rect );
+ }
+ }
+ else {
+ /* Rotated rectangle. Split into triangles. */
+ for (; i<num; i++) {
+ DFBTriangle tri;
+
+ tri.x1 = rects[i].x; tri.y1 = rects[i].y;
+ tri.x2 = rects[i].x+rects[i].w; tri.y2 = rects[i].y;
+ tri.x3 = rects[i].x+rects[i].w; tri.y3 = rects[i].y+rects[i].h;
+ DFB_TRANSFORM(tri.x1, tri.y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(tri.x2, tri.y2, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(tri.x3, tri.y3, state->matrix, state->affine_matrix);
+
+ dfb_sort_triangle( &tri );
+ if (tri.y3 - tri.y1 > 0)
+ fill_tri( &tri, state, false );
+
+ tri.x1 = rects[i].x; tri.y1 = rects[i].y;
+ tri.x2 = rects[i].x+rects[i].w; tri.y2 = rects[i].y+rects[i].h;
+ tri.x3 = rects[i].x; tri.y3 = rects[i].y+rects[i].h;
+ DFB_TRANSFORM(tri.x1, tri.y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(tri.x2, tri.y2, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(tri.x3, tri.y3, state->matrix, state->affine_matrix);
+
+ dfb_sort_triangle( &tri );
+ if (tri.y3 - tri.y1 > 0)
+ fill_tri( &tri, state, false );
+ }
+ }
+
+ gRelease( state );
+ }
+ }
+ }
+
+ /* Unlock after execution. */
+ dfb_state_unlock( state );
+}
+
+static void
+build_clipped_rectangle_outlines( DFBRectangle *rect,
+ const DFBRegion *clip,
+ DFBRectangle *ret_outlines,
+ int *ret_num )
+{
+ DFBEdgeFlags edges = dfb_clip_edges( clip, rect );
+ int t = (edges & DFEF_TOP ? 1 : 0);
+ int tb = t + (edges & DFEF_BOTTOM ? 1 : 0);
+ int num = 0;
+
+ DFB_RECTANGLE_ASSERT( rect );
+
+ D_ASSERT( ret_outlines != NULL );
+ D_ASSERT( ret_num != NULL );
+
+ if (edges & DFEF_TOP) {
+ DFBRectangle *out = &ret_outlines[num++];
+
+ out->x = rect->x;
+ out->y = rect->y;
+ out->w = rect->w;
+ out->h = 1;
+ }
+
+ if (rect->h > t) {
+ if (edges & DFEF_BOTTOM) {
+ DFBRectangle *out = &ret_outlines[num++];
+
+ out->x = rect->x;
+ out->y = rect->y + rect->h - 1;
+ out->w = rect->w;
+ out->h = 1;
+ }
+
+ if (rect->h > tb) {
+ if (edges & DFEF_LEFT) {
+ DFBRectangle *out = &ret_outlines[num++];
+
+ out->x = rect->x;
+ out->y = rect->y + t;
+ out->w = 1;
+ out->h = rect->h - tb;
+ }
+
+ if (rect->w > 1 || !(edges & DFEF_LEFT)) {
+ if (edges & DFEF_RIGHT) {
+ DFBRectangle *out = &ret_outlines[num++];
+
+ out->x = rect->x + rect->w - 1;
+ out->y = rect->y + t;
+ out->w = 1;
+ out->h = rect->h - tb;
+ }
+ }
+ }
+ }
+
+ *ret_num = num;
+}
+
+void dfb_gfxcard_drawrectangle( DFBRectangle *rect, CardState *state )
+{
+ DFBRectangle rects[4];
+ bool hw = false;
+ int i = 0, num = 0;
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ DFB_RECTANGLE_ASSERT( rect );
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %d,%d - %dx%d, %p )\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect), state );
+
+ /* The state is locked during graphics operations. */
+ dfb_state_lock( state );
+
+ /* Signal beginning of sequence of operations if not already done. */
+ dfb_state_start_drawing( state, card );
+
+ if (!dfb_rectangle_region_intersects( rect, &state->clip )) {
+ dfb_state_unlock( state );
+ return;
+ }
+
+ if (D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) ||
+ D_FLAGS_IS_SET( card->caps.clip, DFXL_DRAWRECTANGLE ) ||
+ !dfb_clip_needed( &state->clip, rect ))
+ {
+ if (rect->w <= card->limits.dst_max.w && rect->h <= card->limits.dst_max.h &&
+ dfb_gfxcard_state_check( state, DFXL_DRAWRECTANGLE ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_DRAWRECTANGLE ))
+ {
+ hw = card->funcs.DrawRectangle( card->driver_data,
+ card->device_data, rect );
+
+ dfb_gfxcard_state_release( state );
+ }
+ }
+
+ if (!hw && !(state->render_options & DSRO_MATRIX)) {
+ build_clipped_rectangle_outlines( rect, &state->clip, rects, &num );
+
+ if (!num) {
+ dfb_state_unlock( state );
+ return;
+ }
+
+ if (dfb_gfxcard_state_check( state, DFXL_FILLRECTANGLE ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_FILLRECTANGLE ))
+ {
+ for (; i<num; i++) {
+ hw = rects[i].w <= card->limits.dst_max.w && rects[i].h <= card->limits.dst_max.h
+ && card->funcs.FillRectangle( card->driver_data,
+ card->device_data, &rects[i] );
+ if (!hw)
+ break;
+ }
+
+ dfb_gfxcard_state_release( state );
+ }
+ }
+
+ if (!hw) {
+ if (!(state->render_options & DSRO_MATRIX)) {
+ if (gAcquire( state, DFXL_FILLRECTANGLE )) {
+ for (; i<num; i++)
+ gFillRectangle( state, &rects[i] );
+
+ gRelease( state );
+ }
+ }
+ else {
+ if (gAcquire( state, DFXL_DRAWLINE )) {
+ DFBRegion line;
+ int x1, x2, x3, x4;
+ int y1, y2, y3, y4;
+
+ x1 = rect->x; y1 = rect->y;
+ x2 = rect->x+rect->w; y2 = rect->y;
+ x3 = rect->x+rect->w; y3 = rect->y+rect->h;
+ x4 = rect->x; y4 = rect->y+rect->h;
+ DFB_TRANSFORM(x1, y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(x2, y2, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(x3, y3, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(x4, y4, state->matrix, state->affine_matrix);
+
+ line = (DFBRegion) { x1, y1, x2, y2 };
+ if (dfb_clip_line( &state->clip, &line ))
+ gDrawLine( state, &line );
+
+ line = (DFBRegion) { x2, y2, x3, y3 };
+ if (dfb_clip_line( &state->clip, &line ))
+ gDrawLine( state, &line );
+
+ line = (DFBRegion) { x3, y3, x4, y4 };
+ if (dfb_clip_line( &state->clip, &line ))
+ gDrawLine( state, &line );
+
+ line = (DFBRegion) { x4, y4, x1, y1 };
+ if (dfb_clip_line( &state->clip, &line ))
+ gDrawLine( state, &line );
+
+ gRelease( state );
+ }
+ }
+ }
+
+ dfb_state_unlock( state );
+}
+
+void dfb_gfxcard_drawlines( DFBRegion *lines, int num_lines, CardState *state )
+{
+ int i = 0;
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %p [%d], %p )\n", __FUNCTION__, lines, num_lines, state );
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( lines != NULL );
+ D_ASSERT( num_lines > 0 );
+
+ /* The state is locked during graphics operations. */
+ dfb_state_lock( state );
+
+ /* Signal beginning of sequence of operations if not already done. */
+ dfb_state_start_drawing( state, card );
+
+ if (dfb_gfxcard_state_check( state, DFXL_DRAWLINE ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_DRAWLINE ))
+ {
+ for (; i<num_lines; i++) {
+ if (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) &&
+ !D_FLAGS_IS_SET( card->caps.clip, DFXL_DRAWLINE ) &&
+ !dfb_clip_line( &state->clip, &lines[i] ))
+ continue;
+
+ if (!card->funcs.DrawLine( card->driver_data,
+ card->device_data, &lines[i] ))
+ break;
+ }
+
+ dfb_gfxcard_state_release( state );
+ }
+
+ if (i < num_lines) {
+ if (gAcquire( state, DFXL_DRAWLINE )) {
+ for (; i<num_lines; i++) {
+ if (state->render_options & DSRO_MATRIX) {
+ DFB_TRANSFORM(lines[i].x1, lines[i].y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(lines[i].x2, lines[i].y2, state->matrix, state->affine_matrix);
+ }
+
+ if (dfb_clip_line( &state->clip, &lines[i] ))
+ gDrawLine( state, &lines[i] );
+ }
+
+ gRelease( state );
+ }
+ }
+
+ dfb_state_unlock( state );
+}
+
+void dfb_gfxcard_fillspans( int y, DFBSpan *spans, int num_spans, CardState *state )
+{
+ int i = 0;
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %d, %p [%d], %p )\n", __FUNCTION__, y, spans, num_spans, state );
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( spans != NULL );
+ D_ASSERT( num_spans > 0 );
+
+ /* The state is locked during graphics operations. */
+ dfb_state_lock( state );
+
+ /* Signal beginning of sequence of operations if not already done. */
+ dfb_state_start_drawing( state, card );
+
+ if (dfb_gfxcard_state_check( state, DFXL_FILLRECTANGLE ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_FILLRECTANGLE ))
+ {
+ for (; i<num_spans; i++) {
+ DFBRectangle rect = { spans[i].x, y + i, spans[i].w, 1 };
+
+ if (rect.w > card->limits.dst_max.w || rect.h > card->limits.dst_max.h) {
+ if (!dfb_clip_rectangle( &state->clip, &rect ))
+ continue;
+
+ if (rect.w > card->limits.dst_max.w || rect.h > card->limits.dst_max.h)
+ break;
+ }
+ else if (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) &&
+ !D_FLAGS_IS_SET( card->caps.clip, DFXL_FILLRECTANGLE ) &&
+ !dfb_clip_rectangle( &state->clip, &rect ))
+ continue;
+
+ if (!card->funcs.FillRectangle( card->driver_data,
+ card->device_data, &rect ))
+ break;
+ }
+
+ dfb_gfxcard_state_release( state );
+ }
+
+ if (i < num_spans) {
+ if (gAcquire( state, DFXL_FILLRECTANGLE )) {
+ for (; i<num_spans; i++) {
+ DFBRectangle rect = { spans[i].x, y + i, spans[i].w, 1 };
+
+ if (state->render_options & DSRO_MATRIX) {
+ if (state->matrix[1] == 0 && state->matrix[3] == 0) {
+ int x1, y1, x2, y2;
+
+ x1 = rect.x; y1 = rect.y;
+ x2 = x1+rect.w; y2 = y1+rect.h;
+ DFB_TRANSFORM(x1, y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(x2, y2, state->matrix, state->affine_matrix);
+
+ if (x1 < x2) {
+ rect.x = x1;
+ rect.w = x2-x1;
+ } else {
+ rect.x = x2;
+ rect.w = x1-x2;
+ }
+ if (y1 < y2) {
+ rect.y = y1;
+ rect.h = y2-y1;
+ }
+ else {
+ rect.y = y2;
+ rect.h = y1-y2;
+ }
+
+ if (dfb_clip_rectangle( &state->clip, &rect ))
+ gFillRectangle( state, &rect );
+ }
+ else {
+ DFBTriangle tri;
+
+ tri.x1 = rect.x; tri.y1 = rect.y;
+ tri.x2 = rect.x+rect.w; tri.y2 = rect.y;
+ tri.x3 = rect.x+rect.w; tri.y3 = rect.y+rect.h;
+ DFB_TRANSFORM(tri.x1, tri.y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(tri.x2, tri.y2, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(tri.x3, tri.y3, state->matrix, state->affine_matrix);
+
+ dfb_sort_triangle( &tri );
+ if (tri.y3 - tri.y1 > 0)
+ fill_tri( &tri, state, false );
+
+ tri.x1 = rect.x; tri.y1 = rect.y;
+ tri.x2 = rect.x+rect.w; tri.y2 = rect.y+rect.h;
+ tri.x3 = rect.x; tri.y3 = rect.y+rect.h;
+ DFB_TRANSFORM(tri.x1, tri.y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(tri.x2, tri.y2, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(tri.x3, tri.y3, state->matrix, state->affine_matrix);
+
+ dfb_sort_triangle( &tri );
+ if (tri.y3 - tri.y1 > 0)
+ fill_tri( &tri, state, false );
+ }
+ }
+ else {
+ if (dfb_clip_rectangle( &state->clip, &rect ))
+ gFillRectangle( state, &rect );
+ }
+ }
+
+ gRelease( state );
+ }
+ }
+
+ dfb_state_unlock( state );
+}
+
+
+typedef struct {
+ int xi;
+ int xf;
+ int mi;
+ int mf;
+ int _2dy;
+} DDA;
+
+#define SETUP_DDA(xs,ys,xe,ye,dda) \
+ do { \
+ int dx = xe - xs; \
+ int dy = ye - ys; \
+ dda.xi = xs; \
+ if (dy != 0) { \
+ dda.mi = dx / dy; \
+ dda.mf = 2*(dx % dy); \
+ dda.xf = -dy; \
+ dda._2dy = 2 * dy; \
+ if (dda.mf < 0) { \
+ dda.mf += 2 * ABS(dy); \
+ dda.mi--; \
+ } \
+ } \
+ else { \
+ dda.mi = 0; \
+ dda.mf = 0; \
+ dda.xf = 0; \
+ dda._2dy = 0; \
+ } \
+ } while (0)
+
+
+#define INC_DDA(dda) \
+ do { \
+ dda.xi += dda.mi; \
+ dda.xf += dda.mf; \
+ if (dda.xf > 0) { \
+ dda.xi++; \
+ dda.xf -= dda._2dy; \
+ } \
+ } while (0)
+
+
+/**
+ * render a triangle using two parallel DDA's
+ */
+static void
+fill_tri( DFBTriangle *tri, CardState *state, bool accelerated )
+{
+ int y, yend;
+ DDA dda1 = { .xi = 0 }, dda2 = { .xi = 0 };
+ int clip_x1 = state->clip.x1;
+ int clip_x2 = state->clip.x2;
+
+ D_MAGIC_ASSERT( state, CardState );
+
+ y = tri->y1;
+ yend = tri->y3;
+
+ if (yend > state->clip.y2)
+ yend = state->clip.y2;
+
+ SETUP_DDA(tri->x1, tri->y1, tri->x3, tri->y3, dda1);
+ SETUP_DDA(tri->x1, tri->y1, tri->x2, tri->y2, dda2);
+
+ while (y <= yend) {
+ DFBRectangle rect;
+
+ if (y == tri->y2) {
+ if (tri->y2 == tri->y3)
+ return;
+ SETUP_DDA(tri->x2, tri->y2, tri->x3, tri->y3, dda2);
+ }
+
+ rect.w = ABS(dda1.xi - dda2.xi);
+ rect.x = MIN(dda1.xi, dda2.xi);
+
+ if (clip_x2 < rect.x + rect.w)
+ rect.w = clip_x2 - rect.x + 1;
+
+ if (rect.w > 0) {
+ if (clip_x1 > rect.x) {
+ rect.w -= (clip_x1 - rect.x);
+ rect.x = clip_x1;
+ }
+ rect.y = y;
+ rect.h = 1;
+
+ if (rect.w > 0 && rect.y >= state->clip.y1) {
+ if (accelerated)
+ card->funcs.FillRectangle( card->driver_data,
+ card->device_data, &rect );
+ else
+ gFillRectangle( state, &rect );
+ }
+ }
+
+ INC_DDA(dda1);
+ INC_DDA(dda2);
+
+ y++;
+ }
+}
+
+
+void dfb_gfxcard_filltriangles( const DFBTriangle *tris, int num, CardState *state )
+{
+ bool hw = false;
+ int i = 0;
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( tris != NULL );
+ D_ASSERT( num > 0 );
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %p [%d], %p )\n", __FUNCTION__, tris, num, state );
+
+ /* The state is locked during graphics operations. */
+ dfb_state_lock( state );
+
+ /* Signal beginning of sequence of operations if not already done. */
+ dfb_state_start_drawing( state, card );
+
+ if (dfb_gfxcard_state_check( state, DFXL_FILLTRIANGLE ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_FILLTRIANGLE ))
+ {
+ if (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) &&
+ !D_FLAGS_IS_SET( card->caps.clip, DFXL_FILLTRIANGLE ))
+ {
+ DFBPoint p[6];
+ int n;
+
+ for (; i < num; i++) {
+ /* FIXME: DSRO_MATRIX. */
+ if (dfb_clip_triangle( &state->clip, &tris[i], p, &n )) {
+ DFBTriangle tri;
+ int j;
+
+ tri.x1 = p[0].x; tri.y1 = p[0].y;
+ tri.x2 = p[1].x; tri.y2 = p[1].y;
+ tri.x3 = p[2].x; tri.y3 = p[2].y;
+ hw = card->funcs.FillTriangle( card->driver_data,
+ card->device_data, &tri );
+ if (!hw)
+ break;
+
+ /* FIXME: return value. */
+ for (j = 3; j < n; j++) {
+ tri.x1 = p[0].x; tri.y1 = p[0].y;
+ tri.x2 = p[j-1].x; tri.y2 = p[j-1].y;
+ tri.x3 = p[j].x; tri.y3 = p[j].y;
+ card->funcs.FillTriangle( card->driver_data,
+ card->device_data, &tri );
+ }
+ }
+ }
+ }
+ else {
+ for (; i < num; i++) {
+ DFBTriangle tri = tris[i];
+
+ hw = card->funcs.FillTriangle( card->driver_data,
+ card->device_data, &tri );
+ if (!hw)
+ break;
+ }
+
+ }
+
+ dfb_gfxcard_state_release( state );
+ }
+
+ if (!hw && i < num) {
+ /* otherwise use the spanline rasterizer (fill_tri)
+ and fill the triangle using a rectangle for each spanline */
+
+ /* try hardware accelerated rectangle filling */
+ if (!(card->caps.flags & CCF_NOTRIEMU) &&
+ dfb_gfxcard_state_check( state, DFXL_FILLRECTANGLE ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_FILLRECTANGLE ))
+ {
+ for (; i < num; i++) {
+ DFBTriangle tri = tris[i];
+
+ dfb_sort_triangle( &tri );
+
+ if (tri.y3 - tri.y1 > 0)
+ fill_tri( &tri, state, true );
+ }
+
+ dfb_gfxcard_state_release( state );
+ }
+ else if (gAcquire( state, DFXL_FILLRECTANGLE )) {
+ for (; i < num; i++) {
+ DFBTriangle tri = tris[i];
+
+ if (state->render_options & DSRO_MATRIX) {
+ DFB_TRANSFORM(tri.x1, tri.y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(tri.x2, tri.y2, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(tri.x3, tri.y3, state->matrix, state->affine_matrix);
+ }
+
+ dfb_sort_triangle( &tri );
+
+ if (tri.y3 - tri.y1 > 0)
+ fill_tri( &tri, state, false );
+ }
+
+ gRelease( state );
+ }
+ }
+
+ dfb_state_unlock( state );
+}
+
+static void
+clip_blit_rotated( DFBRectangle *srect, DFBRectangle *drect, const DFBRegion *clip, DFBSurfaceBlittingFlags flags )
+{
+ DFBRegion dest = DFB_REGION_INIT_FROM_RECTANGLE( drect );
+ DFBRegion clipped = dest;
+
+ if (flags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270)) {
+ D_ASSERT( srect->w == drect->h );
+ D_ASSERT( srect->h == drect->w );
+ }
+ else {
+ D_ASSERT( srect->w == drect->w );
+ D_ASSERT( srect->h == drect->h );
+ }
+
+ dfb_region_region_intersect( &clipped, clip );
+ dfb_rectangle_from_region( drect, &clipped );
+
+ if (flags & DSBLIT_ROTATE90) {
+ srect->x += dest.y2 - clipped.y2;
+ srect->y += clipped.x1 - dest.x1;
+ srect->w = drect->h;
+ srect->h = drect->w;
+
+ D_DEBUG_AT( Core_GraphicsOps, " => %4d,%4d-%4dx%4d -> %4d,%4d-%4dx%4d (90°)\n",
+ DFB_RECTANGLE_VALS(srect), DFB_RECTANGLE_VALS(drect) );
+ }
+ else if (flags & DSBLIT_ROTATE180) {
+ srect->x += dest.x2 - clipped.x2;
+ srect->y += dest.y2 - clipped.y2;
+ srect->w = drect->w;
+ srect->h = drect->h;
+
+ D_DEBUG_AT( Core_GraphicsOps, " => %4d,%4d-%4dx%4d -> %4d,%4d-%4dx%4d (180°)\n",
+ DFB_RECTANGLE_VALS(srect), DFB_RECTANGLE_VALS(drect) );
+ }
+ else if (flags & DSBLIT_ROTATE270) {
+ srect->x += clipped.y1 - dest.y1;
+ srect->y += dest.x2 - clipped.x2;
+ srect->w = drect->h;
+ srect->h = drect->w;
+
+ D_DEBUG_AT( Core_GraphicsOps, " => %4d,%4d-%4dx%4d -> %4d,%4d-%4dx%4d (270°)\n",
+ DFB_RECTANGLE_VALS(srect), DFB_RECTANGLE_VALS(drect) );
+ }
+ else {
+ srect->x += clipped.x1 - dest.x1;
+ srect->y += clipped.y1 - dest.y1;
+ srect->w = drect->w;
+ srect->h = drect->h;
+
+ D_DEBUG_AT( Core_GraphicsOps, " => %4d,%4d-%4dx%4d -> %4d,%4d-%4dx%4d\n",
+ DFB_RECTANGLE_VALS(srect), DFB_RECTANGLE_VALS(drect) );
+ }
+}
+
+void dfb_gfxcard_blit( DFBRectangle *rect, int dx, int dy, CardState *state )
+{
+ bool hw = false;
+ DFBRectangle drect = { dx, dy, rect->w, rect->h };
+
+ if (state->blittingflags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270))
+ D_UTIL_SWAP( drect.w, drect.h );
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %4d,%4d-%4dx%4d -> %4d,%4d-%4dx%4d, %p )\n",
+ __FUNCTION__, DFB_RECTANGLE_VALS(rect), DFB_RECTANGLE_VALS(&drect), state );
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( state->source != NULL );
+ D_ASSERT( rect != NULL );
+ D_ASSERT( rect->x >= 0 );
+ D_ASSERT( rect->y >= 0 );
+ D_ASSERT( rect->x < state->source->config.size.w );
+ D_ASSERT( rect->y < state->source->config.size.h );
+ D_ASSERT( rect->x + rect->w - 1 < state->source->config.size.w );
+ D_ASSERT( rect->y + rect->h - 1 < state->source->config.size.h );
+
+ /* The state is locked during graphics operations. */
+ dfb_state_lock( state );
+
+ /* Signal beginning of sequence of operations if not already done. */
+ dfb_state_start_drawing( state, card );
+
+ if (!(state->render_options & DSRO_MATRIX) &&
+ !dfb_clip_blit_precheck( &state->clip, drect.w, drect.h, drect.x, drect.y ))
+ {
+ /* no work at all */
+ dfb_state_unlock( state );
+ return;
+ }
+
+ if (dfb_gfxcard_state_check( state, DFXL_BLIT ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_BLIT ))
+ {
+ if (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) &&
+ !D_FLAGS_IS_SET( card->caps.clip, DFXL_BLIT ))
+ clip_blit_rotated( rect, &drect, &state->clip, state->blittingflags );
+
+ hw = card->funcs.Blit( card->driver_data, card->device_data, rect, drect.x, drect.y );
+
+ dfb_gfxcard_state_release( state );
+ }
+
+ if (!hw) {
+ if (state->render_options & DSRO_MATRIX) {
+ if (state->matrix[0] < 0 || state->matrix[1] != 0 ||
+ state->matrix[3] != 0 || state->matrix[4] < 0 ||
+ state->matrix[6] != 0 || state->matrix[7] != 0) {
+ D_WARN( "rotation not yet implemented" );
+ dfb_state_unlock( state );
+ return;
+ }
+
+ if (gAcquire( state, DFXL_STRETCHBLIT )) {
+ DFBRectangle drect;
+ int x1, y1, x2, y2;
+
+ x1 = dx; y1 = dy;
+ x2 = dx+rect->w; y2 = dy+rect->h;
+ DFB_TRANSFORM(x1, y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(x2, y2, state->matrix, state->affine_matrix);
+
+ drect = (DFBRectangle) { x1, y1, x2-x1, y2-y1 };
+ if (dfb_clip_blit_precheck( &state->clip,
+ drect.w, drect.h, drect.x, drect.y ))
+ gStretchBlit( state, rect, &drect );
+
+ gRelease( state );
+ }
+ }
+ else {
+ if (gAcquire( state, DFXL_BLIT )) {
+ clip_blit_rotated( rect, &drect, &state->clip, state->blittingflags );
+
+ gBlit( state, rect, drect.x, drect.y );
+
+ gRelease( state );
+ }
+ }
+ }
+
+ dfb_state_unlock( state );
+}
+
+void dfb_gfxcard_batchblit( DFBRectangle *rects, DFBPoint *points,
+ int num, CardState *state )
+{
+ int i = 0;
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %p, %p [%d], %p )\n", __FUNCTION__, rects, points, num, state );
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( rects != NULL );
+ D_ASSERT( points != NULL );
+ D_ASSERT( num > 0 );
+
+ /* The state is locked during graphics operations. */
+ dfb_state_lock( state );
+
+ /* Signal beginning of sequence of operations if not already done. */
+ dfb_state_start_drawing( state, card );
+
+ if (dfb_gfxcard_state_check( state, DFXL_BLIT ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_BLIT ))
+ {
+ for (; i<num; i++) {
+ if ((state->render_options & DSRO_MATRIX) ||
+ dfb_clip_blit_precheck( &state->clip,
+ rects[i].w, rects[i].h,
+ points[i].x, points[i].y ))
+ {
+ if (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) &&
+ !D_FLAGS_IS_SET( card->caps.clip, DFXL_BLIT ))
+ dfb_clip_blit( &state->clip, &rects[i],
+ &points[i].x, &points[i].y );
+
+ if (!card->funcs.Blit( card->driver_data, card->device_data,
+ &rects[i], points[i].x, points[i].y ))
+ break;
+ }
+ }
+
+ dfb_gfxcard_state_release( state );
+ }
+
+ if (i < num) {
+ if (state->render_options & DSRO_MATRIX) {
+ if (state->matrix[0] < 0 || state->matrix[1] != 0 ||
+ state->matrix[3] != 0 || state->matrix[4] < 0 ||
+ state->matrix[6] != 0 || state->matrix[7] != 0) {
+ D_WARN( "rotation not yet implemented" );
+ dfb_state_unlock( state );
+ return;
+ }
+
+ if (gAcquire( state, DFXL_STRETCHBLIT )) {
+ for (; i<num; i++) {
+ DFBRectangle drect;
+ int x1, y1, x2, y2;
+
+ x1 = points[i].x; y1 = points[i].y;
+ x2 = x1+rects[i].w; y2 = y1+rects[i].h;
+ DFB_TRANSFORM(x1, y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(x2, y2, state->matrix, state->affine_matrix);
+
+ drect = (DFBRectangle) { x1, y1, x2-x1, y2-y1 };
+ if (dfb_clip_blit_precheck( &state->clip,
+ drect.w, drect.h, drect.x, drect.y ))
+ gStretchBlit( state, &rects[i], &drect );
+ }
+
+ gRelease( state );
+ }
+ }
+ else {
+ if (gAcquire( state, DFXL_BLIT )) {
+ for (; i<num; i++) {
+ if (dfb_clip_blit_precheck( &state->clip,
+ rects[i].w, rects[i].h,
+ points[i].x, points[i].y ))
+ {
+ dfb_clip_blit( &state->clip, &rects[i],
+ &points[i].x, &points[i].y );
+
+ gBlit( state, &rects[i], points[i].x, points[i].y );
+ }
+ }
+
+ gRelease( state );
+ }
+ }
+ }
+
+ dfb_state_unlock( state );
+}
+
+void dfb_gfxcard_tileblit( DFBRectangle *rect, int dx1, int dy1, int dx2, int dy2,
+ CardState *state )
+{
+ int x, y;
+ int odx;
+ DFBRectangle srect;
+ DFBRegion *clip;
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %d,%d - %d,%d, %p )\n", __FUNCTION__, dx1, dy1, dx2, dy2, state );
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( rect != NULL );
+
+ /* If called with an invalid rectangle, the algorithm goes into an
+ infinite loop. This should never happen but it's safer to check. */
+ D_ASSERT( rect->w >= 1 );
+ D_ASSERT( rect->h >= 1 );
+
+ /* The state is locked during graphics operations. */
+ dfb_state_lock( state );
+
+ /* Signal beginning of sequence of operations if not already done. */
+ dfb_state_start_drawing( state, card );
+
+ clip = &state->clip;
+
+ /* Check if anything is drawn at all. */
+ if (!(state->render_options & DSRO_MATRIX) &&
+ !dfb_clip_blit_precheck( clip, dx2-dx1+1, dy2-dy1+1, dx1, dy1 )) {
+ dfb_state_unlock( state );
+ return;
+ }
+
+ /* Remove clipped tiles. */
+ if (dx1 < clip->x1) {
+ int outer = clip->x1 - dx1;
+
+ dx1 += outer - (outer % rect->w);
+ }
+
+ if (dy1 < clip->y1) {
+ int outer = clip->y1 - dy1;
+
+ dy1 += outer - (outer % rect->h);
+ }
+
+ if (dx2 > clip->x2) {
+ int outer = clip->x2 - dx2;
+
+ dx2 -= outer - (outer % rect->w);
+ }
+
+ if (dy2 > clip->y2) {
+ int outer = clip->y2 - dy2;
+
+ dy2 -= outer - (outer % rect->h);
+ }
+
+ odx = dx1;
+
+ if (dfb_gfxcard_state_check( state, DFXL_BLIT ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_BLIT )) {
+ bool hw = true;
+
+ for (; dy1 < dy2; dy1 += rect->h) {
+ for (; dx1 < dx2; dx1 += rect->w) {
+
+ if (!dfb_clip_blit_precheck( clip, rect->w, rect->h, dx1, dy1 ))
+ continue;
+
+ x = dx1;
+ y = dy1;
+ srect = *rect;
+
+ if (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) &&
+ !D_FLAGS_IS_SET( card->caps.clip, DFXL_BLIT ))
+ dfb_clip_blit( clip, &srect, &x, &y );
+
+ hw = card->funcs.Blit( card->driver_data,
+ card->device_data, &srect, x, y );
+ if (!hw)
+ break;
+ }
+ if (!hw)
+ break;
+ dx1 = odx;
+ }
+
+ dfb_gfxcard_state_release( state );
+ }
+
+ if (dy1 < dy2) {
+ if (state->render_options & DSRO_MATRIX) {
+ if (state->matrix[0] < 0 || state->matrix[1] != 0 ||
+ state->matrix[3] != 0 || state->matrix[4] < 0 ||
+ state->matrix[6] != 0 || state->matrix[7] != 0) {
+ D_WARN( "rotation not yet implemented" );
+ dfb_state_unlock( state );
+ return;
+ }
+
+ if (gAcquire( state, DFXL_STRETCHBLIT )) {
+ for (; dy1 < dy2; dy1 += rect->h) {
+ for (; dx1 < dx2; dx1 += rect->w) {
+ DFBRectangle drect;
+ int x1, y1, x2, y2;
+
+ x1 = dx1; y1 = dy1;
+ x2 = dx1+rect->w; y2 = dy1+rect->h;
+ DFB_TRANSFORM(x1, y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(x2, y2, state->matrix, state->affine_matrix);
+
+ drect = (DFBRectangle) { x1, y1, x2-x1, y2-y1 };
+ if (dfb_clip_blit_precheck( &state->clip,
+ drect.w, drect.h, drect.x, drect.y ))
+ gStretchBlit( state, rect, &drect );
+ }
+ dx1 = odx;
+ }
+
+ gRelease( state );
+ }
+ }
+ else {
+ if (gAcquire( state, DFXL_BLIT )) {
+ for (; dy1 < dy2; dy1 += rect->h) {
+ for (; dx1 < dx2; dx1 += rect->w) {
+
+ if (!dfb_clip_blit_precheck( clip, rect->w, rect->h, dx1, dy1 ))
+ continue;
+
+ x = dx1;
+ y = dy1;
+ srect = *rect;
+
+ dfb_clip_blit( clip, &srect, &x, &y );
+
+ gBlit( state, &srect, x, y );
+ }
+ dx1 = odx;
+ }
+
+ gRelease( state );
+ }
+ }
+ }
+
+ dfb_state_unlock( state );
+}
+
+void dfb_gfxcard_stretchblit( DFBRectangle *srect, DFBRectangle *drect,
+ CardState *state )
+{
+ bool hw = false;
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( srect != NULL );
+ D_ASSERT( drect != NULL );
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %d,%d - %dx%d -> %d,%d - %dx%d, %p )\n",
+ __FUNCTION__, DFB_RECTANGLE_VALS(srect), DFB_RECTANGLE_VALS(drect), state );
+
+ if (state->blittingflags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270)) {
+ if (srect->w == drect->h && srect->h == drect->w) {
+ dfb_gfxcard_blit( srect, drect->x, drect->y, state );
+ return;
+ }
+ }
+ else {
+ if (srect->w == drect->w && srect->h == drect->h) {
+ dfb_gfxcard_blit( srect, drect->x, drect->y, state );
+ return;
+ }
+ }
+
+ /* The state is locked during graphics operations. */
+ dfb_state_lock( state );
+
+ /* Signal beginning of sequence of operations if not already done. */
+ dfb_state_start_drawing( state, card );
+
+ if (!(state->render_options & DSRO_MATRIX) &&
+ !dfb_clip_blit_precheck( &state->clip, drect->w, drect->h,
+ drect->x, drect->y ))
+ {
+ dfb_state_unlock( state );
+ return;
+ }
+
+ if (dfb_gfxcard_state_check( state, DFXL_STRETCHBLIT ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_STRETCHBLIT ))
+ {
+ if (!D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) &&
+ !D_FLAGS_IS_SET( card->caps.clip, DFXL_STRETCHBLIT ))
+ dfb_clip_stretchblit( &state->clip, srect, drect );
+
+ hw = card->funcs.StretchBlit( card->driver_data, card->device_data, srect, drect );
+
+ dfb_gfxcard_state_release( state );
+ }
+
+ if (!hw) {
+ if (state->render_options & DSRO_MATRIX) {
+ int x1, y1, x2, y2;
+
+ if (state->matrix[0] < 0 || state->matrix[1] != 0 ||
+ state->matrix[3] != 0 || state->matrix[4] < 0 ||
+ state->matrix[6] != 0 || state->matrix[7] != 0) {
+ D_WARN( "rotation not yet implemented" );
+ dfb_state_unlock( state );
+ return;
+ }
+
+ x1 = drect->x; y1 = drect->y;
+ x2 = x1+drect->w; y2 = y1+drect->h;
+ DFB_TRANSFORM(x1, y1, state->matrix, state->affine_matrix);
+ DFB_TRANSFORM(x2, y2, state->matrix, state->affine_matrix);
+ drect->x = x1; drect->y = y1;
+ drect->w = x2-x1; drect->h = y2-y1;
+
+ if (!dfb_clip_blit_precheck( &state->clip,
+ drect->w, drect->h, drect->x, drect->y )) {
+ dfb_state_unlock( state );
+ return;
+ }
+ }
+
+ if (gAcquire( state, DFXL_STRETCHBLIT )) {
+ /* Clipping is performed in the following function. */
+ gStretchBlit( state, srect, drect );
+ gRelease( state );
+ }
+ }
+
+ dfb_state_unlock( state );
+}
+
+void dfb_gfxcard_texture_triangles( DFBVertex *vertices, int num,
+ DFBTriangleFormation formation,
+ CardState *state )
+{
+ bool hw = false;
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %p [%d], %s, %p )\n", __FUNCTION__, vertices, num,
+ (formation == DTTF_LIST) ? "LIST" :
+ (formation == DTTF_STRIP) ? "STRIP" :
+ (formation == DTTF_FAN) ? "FAN" : "unknown formation", state );
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_ASSERT( vertices != NULL );
+ D_ASSERT( num >= 3 );
+ D_MAGIC_ASSERT( state, CardState );
+
+ /* The state is locked during graphics operations. */
+ dfb_state_lock( state );
+
+ /* Signal beginning of sequence of operations if not already done. */
+ dfb_state_start_drawing( state, card );
+
+ if ((D_FLAGS_IS_SET( card->caps.flags, CCF_CLIPPING ) || D_FLAGS_IS_SET( card->caps.clip, DFXL_TEXTRIANGLES )) &&
+ dfb_gfxcard_state_check( state, DFXL_TEXTRIANGLES ) &&
+ dfb_gfxcard_state_acquire( state, DFXL_TEXTRIANGLES ))
+ {
+ hw = card->funcs.TextureTriangles( card->driver_data,
+ card->device_data,
+ vertices, num, formation );
+
+ dfb_gfxcard_state_release( state );
+ }
+
+ if (!hw) {
+ if (gAcquire( state, DFXL_TEXTRIANGLES )) {
+ //dfb_clip_stretchblit( &state->clip, srect, drect );
+ //gStretchBlit( state, srect, drect );
+ gRelease( state );
+ }
+ }
+
+ dfb_state_unlock( state );
+}
+
+void
+dfb_gfxcard_drawstring( const u8 *text, int bytes,
+ DFBTextEncodingID encoding, int x, int y,
+ CoreFont *font, unsigned int layers, CardState *state )
+{
+ unsigned int prev = 0;
+ unsigned int indices[bytes];
+ int i, l, num;
+ int kern_x;
+ int kern_y;
+ CoreSurface *surface;
+ DFBSurfaceBlittingFlags orig_flags;
+ DFBSurfaceBlendFunction orig_srcblend;
+ DFBSurfaceBlendFunction orig_dstblend;
+ DFBPoint points[50];
+ DFBRectangle rects[50];
+ int num_blits = 0;
+ int ox = x;
+ int oy = y;
+
+ if (encoding == DTEID_UTF8)
+ D_DEBUG_AT( Core_GraphicsOps, "%s( '%s' [%d], %d,%d, %p, %p )\n",
+ __FUNCTION__, text, bytes, x, y, font, state );
+ else
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %p [%d], %d, %d,%d, %p, %p )\n",
+ __FUNCTION__, text, bytes, encoding, x, y, font, state );
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( text != NULL );
+ D_ASSERT( bytes > 0 );
+ D_ASSERT( font != NULL );
+
+ surface = state->destination;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ /* simple prechecks */
+ if (!(state->render_options & DSRO_MATRIX) &&
+ (x > state->clip.x2 || y > state->clip.y2 ||
+ y + font->ascender - font->descender <= state->clip.y1)) {
+ return;
+ }
+
+ dfb_font_lock( font );
+
+ /* Decode string to character indices. */
+ dfb_font_decode_text( font, encoding, text, bytes, indices, &num );
+
+ orig_flags = state->blittingflags;
+ orig_srcblend = state->src_blend;
+ orig_dstblend = state->dst_blend;
+
+ if (orig_flags != DSBLIT_INDEX_TRANSLATION) {
+ DFBSurfaceBlittingFlags flags = font->blittingflags;
+
+ /* additional blending? */
+ if ((state->drawingflags & DSDRAW_BLEND) && (state->color.a != 0xff))
+ flags |= DSBLIT_BLEND_COLORALPHA;
+
+ if (state->drawingflags & DSDRAW_DST_COLORKEY)
+ flags |= DSBLIT_DST_COLORKEY;
+
+ if (state->drawingflags & DSDRAW_XOR)
+ flags |= DSBLIT_XOR;
+
+ if (flags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ /* Porter/Duff SRC_OVER composition */
+ if ((DFB_PIXELFORMAT_HAS_ALPHA( surface->config.format ) && (surface->config.caps & DSCAPS_PREMULTIPLIED))
+ ||
+ (font->surface_caps & DSCAPS_PREMULTIPLIED))
+ {
+ if (font->surface_caps & DSCAPS_PREMULTIPLIED) {
+ if (flags & DSBLIT_BLEND_COLORALPHA)
+ flags |= DSBLIT_SRC_PREMULTCOLOR;
+ }
+ else
+ flags |= DSBLIT_SRC_PREMULTIPLY;
+
+ dfb_state_set_src_blend( state, DSBF_ONE );
+ }
+ else
+ dfb_state_set_src_blend( state, DSBF_SRCALPHA );
+
+ dfb_state_set_dst_blend( state, DSBF_INVSRCALPHA );
+ }
+
+ dfb_state_set_blitting_flags( state, flags );
+ }
+
+ for (l=layers-1; l>=0; l--) {
+ x = ox;
+ y = oy;
+
+ if (layers > 1) {
+ if (num_blits) {
+ dfb_gfxcard_batchblit( rects, points, num_blits, state );
+ num_blits = 0;
+ }
+
+ dfb_state_set_color( state, &state->colors[l] );
+ }
+
+ /* blit glyphs */
+ for (i=0; i<num; i++) {
+ DFBResult ret;
+ CoreGlyphData *glyph;
+ unsigned int current = indices[i];
+
+ ret = dfb_font_get_glyph_data( font, current, l, &glyph );
+ if (ret) {
+ D_DEBUG_AT( Core_GraphicsOps, " -> dfb_font_get_glyph_data() failed! [%s]\n", DirectFBErrorString( ret ) );
+ prev = current;
+ continue;
+ }
+
+ if (prev && font->GetKerning && font->GetKerning( font, prev, current, &kern_x, &kern_y) == DFB_OK) {
+ x += kern_x;
+ y += kern_y;
+ }
+
+ if (glyph->width) {
+ if (glyph->surface != state->source || num_blits == D_ARRAY_SIZE(rects)) {
+ if (num_blits) {
+ dfb_gfxcard_batchblit( rects, points, num_blits, state );
+ num_blits = 0;
+ }
+
+ if (glyph->surface != state->source)
+ dfb_state_set_source( state, glyph->surface );
+ }
+
+ points[num_blits] = (DFBPoint){ x + glyph->left, y + glyph->top };
+ rects[num_blits] = (DFBRectangle){ glyph->start, 0, glyph->width, glyph->height };
+
+ num_blits++;
+ }
+
+ x += glyph->xadvance;
+ y += glyph->yadvance;
+ prev = current;
+ }
+ }
+
+ if (num_blits) {
+ dfb_gfxcard_batchblit( rects, points, num_blits, state );
+ num_blits = 0;
+ }
+
+ dfb_font_unlock( font );
+
+
+ if (orig_flags != DSBLIT_INDEX_TRANSLATION) {
+ dfb_state_set_blitting_flags( state, orig_flags );
+ dfb_state_set_src_blend( state, orig_srcblend );
+ dfb_state_set_dst_blend( state, orig_dstblend );
+ }
+}
+
+void dfb_gfxcard_drawglyph( CoreGlyphData **glyph, int x, int y,
+ CoreFont *font, unsigned int layers, CardState *state )
+{
+ int l;
+ CoreSurface *surface;
+ DFBSurfaceBlittingFlags orig_flags;
+ DFBSurfaceBlendFunction orig_srcblend;
+ DFBSurfaceBlendFunction orig_dstblend;
+
+ D_DEBUG_AT( Core_GraphicsOps, "%s( %u, %d,%d, %p, %p )\n",
+ __FUNCTION__, index, x, y, font, state );
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( font != NULL );
+
+ surface = state->destination;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ orig_flags = state->blittingflags;
+ orig_srcblend = state->src_blend;
+ orig_dstblend = state->dst_blend;
+
+ if (orig_flags != DSBLIT_INDEX_TRANSLATION) {
+ DFBSurfaceBlittingFlags flags = font->blittingflags;
+
+ /* additional blending? */
+ if ((state->drawingflags & DSDRAW_BLEND) && (state->color.a != 0xff))
+ flags |= DSBLIT_BLEND_COLORALPHA;
+
+ if (state->drawingflags & DSDRAW_DST_COLORKEY)
+ flags |= DSBLIT_DST_COLORKEY;
+
+ if (state->drawingflags & DSDRAW_XOR)
+ flags |= DSBLIT_XOR;
+
+ if (flags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ /* Porter/Duff SRC_OVER composition */
+ if ((DFB_PIXELFORMAT_HAS_ALPHA( surface->config.format ) && (surface->config.caps & DSCAPS_PREMULTIPLIED))
+ ||
+ (font->surface_caps & DSCAPS_PREMULTIPLIED))
+ {
+ if (font->surface_caps & DSCAPS_PREMULTIPLIED) {
+ if (flags & DSBLIT_BLEND_COLORALPHA)
+ flags |= DSBLIT_SRC_PREMULTCOLOR;
+ }
+ else
+ flags |= DSBLIT_SRC_PREMULTIPLY;
+
+ dfb_state_set_src_blend( state, DSBF_ONE );
+ }
+ else
+ dfb_state_set_src_blend( state, DSBF_SRCALPHA );
+
+ dfb_state_set_dst_blend( state, DSBF_INVSRCALPHA );
+ }
+
+ dfb_state_set_blitting_flags( state, flags );
+ }
+
+ for (l=layers-1; l>=0; l--) {
+ if (layers > 1)
+ dfb_state_set_color( state, &state->colors[l] );
+
+ /* blit glyph */
+ if (glyph[l]->width) {
+ DFBRectangle rect = { glyph[l]->start, 0, glyph[l]->width, glyph[l]->height };
+
+ dfb_state_set_source( state, glyph[l]->surface );
+
+ dfb_gfxcard_blit( &rect, x + glyph[l]->left, y + glyph[l]->top, state );
+ }
+ }
+
+ if (orig_flags != DSBLIT_INDEX_TRANSLATION) {
+ dfb_state_set_blitting_flags( state, orig_flags );
+ dfb_state_set_src_blend( state, orig_srcblend );
+ dfb_state_set_dst_blend( state, orig_dstblend );
+ }
+}
+
+bool dfb_gfxcard_drawstring_check_state( CoreFont *font, CardState *state )
+{
+ int i;
+ bool result;
+ CoreSurface *surface;
+ DFBSurfaceBlittingFlags orig_flags;
+ DFBSurfaceBlendFunction orig_srcblend;
+ DFBSurfaceBlendFunction orig_dstblend;
+ CoreGlyphData *data = NULL;
+
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( font != NULL );
+
+ D_DEBUG_AT( Core_GfxState, "%s( %p, %p )\n", __FUNCTION__, font, state );
+
+ surface = state->destination;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ dfb_font_lock( font );
+
+ for (i=0; i<128; i++) {
+ if (dfb_font_get_glyph_data (font, i, 0, &data) == DFB_OK)
+ break;
+ }
+
+ if (!data) {
+ D_DEBUG_AT( Core_GfxState, " -> No font data!\n" );
+ dfb_font_unlock( font );
+ return;
+ }
+
+ orig_flags = state->blittingflags;
+ orig_srcblend = state->src_blend;
+ orig_dstblend = state->dst_blend;
+
+ if (orig_flags != DSBLIT_INDEX_TRANSLATION) {
+ DFBSurfaceBlittingFlags flags = font->blittingflags;
+
+ /* additional blending? */
+ if ((state->drawingflags & DSDRAW_BLEND) && (state->color.a != 0xff))
+ flags |= DSBLIT_BLEND_COLORALPHA;
+
+ if (state->drawingflags & DSDRAW_DST_COLORKEY)
+ flags |= DSBLIT_DST_COLORKEY;
+
+ if (state->drawingflags & DSDRAW_XOR)
+ flags |= DSBLIT_XOR;
+
+ if (flags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ /* Porter/Duff SRC_OVER composition */
+ if ((DFB_PIXELFORMAT_HAS_ALPHA( surface->config.format ) && (surface->config.caps & DSCAPS_PREMULTIPLIED))
+ ||
+ (font->surface_caps & DSCAPS_PREMULTIPLIED))
+ {
+ if (font->surface_caps & DSCAPS_PREMULTIPLIED) {
+ if (flags & DSBLIT_BLEND_COLORALPHA)
+ flags |= DSBLIT_SRC_PREMULTCOLOR;
+ }
+ else
+ flags |= DSBLIT_SRC_PREMULTIPLY;
+
+ dfb_state_set_src_blend( state, DSBF_ONE );
+ }
+ else
+ dfb_state_set_src_blend( state, DSBF_SRCALPHA );
+
+ dfb_state_set_dst_blend( state, DSBF_INVSRCALPHA );
+ }
+
+ dfb_state_set_blitting_flags( state, flags );
+ }
+
+ /* set the source */
+ dfb_state_set_source( state, data->surface );
+
+ dfb_state_lock( state );
+
+ /* check for blitting and report */
+ result = dfb_gfxcard_state_check( state, DFXL_BLIT );
+
+ dfb_state_unlock( state );
+
+ dfb_font_unlock( font );
+
+ if (orig_flags != DSBLIT_INDEX_TRANSLATION) {
+ dfb_state_set_blitting_flags( state, orig_flags );
+ dfb_state_set_src_blend( state, orig_srcblend );
+ dfb_state_set_dst_blend( state, orig_dstblend );
+ }
+
+ return result;
+}
+
+DFBResult dfb_gfxcard_sync( void )
+{
+ DFBResult ret;
+
+ D_ASSUME( card != NULL );
+
+ if (!card)
+ return DFB_OK;
+
+ ret = dfb_gfxcard_lock( GDLF_SYNC );
+ if (ret)
+ return ret;
+
+ dfb_gfxcard_unlock();
+
+ return DFB_OK;
+}
+
+void dfb_gfxcard_invalidate_state( void )
+{
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+ card->shared->state = NULL;
+}
+
+DFBResult dfb_gfxcard_wait_serial( const CoreGraphicsSerial *serial )
+{
+ DFBResult ret;
+
+ D_ASSERT( serial != NULL );
+ D_ASSUME( card != NULL );
+
+ if (!card)
+ return DFB_OK;
+
+ D_ASSERT( card->shared != NULL );
+
+ ret = dfb_gfxcard_lock( GDLF_NONE );
+ if (ret)
+ return ret;
+
+/* FIXME_SC_2 if (card->funcs.WaitSerial)
+ ret = card->funcs.WaitSerial( card->driver_data, card->device_data, serial );
+ else*/ if (card->funcs.EngineSync)
+ ret = card->funcs.EngineSync( card->driver_data, card->device_data );
+
+ if (ret) {
+ if (card->funcs.EngineReset)
+ card->funcs.EngineReset( card->driver_data, card->device_data );
+
+ card->shared->state = NULL;
+ }
+
+ dfb_gfxcard_unlock();
+
+ return ret;
+}
+
+void dfb_gfxcard_flush_texture_cache( void )
+{
+ D_ASSUME( card != NULL );
+
+ if (card && card->funcs.FlushTextureCache)
+ card->funcs.FlushTextureCache( card->driver_data, card->device_data );
+}
+
+void dfb_gfxcard_flush_read_cache( void )
+{
+ D_ASSUME( card != NULL );
+
+ if (card && card->funcs.FlushReadCache)
+ card->funcs.FlushReadCache( card->driver_data, card->device_data );
+}
+
+void dfb_gfxcard_after_set_var( void )
+{
+ D_ASSUME( card != NULL );
+
+ if (card && card->funcs.AfterSetVar)
+ card->funcs.AfterSetVar( card->driver_data, card->device_data );
+}
+
+void dfb_gfxcard_surface_enter( CoreSurfaceBuffer *buffer, DFBSurfaceLockFlags flags )
+{
+ D_ASSUME( card != NULL );
+
+ if (card && card->funcs.SurfaceEnter)
+ card->funcs.SurfaceEnter( card->driver_data, card->device_data, buffer, flags );
+}
+
+void dfb_gfxcard_surface_leave( CoreSurfaceBuffer *buffer )
+{
+ D_ASSUME( card != NULL );
+
+ if (card && card->funcs.SurfaceLeave)
+ card->funcs.SurfaceLeave( card->driver_data, card->device_data, buffer );
+}
+
+DFBResult
+dfb_gfxcard_adjust_heap_offset( int offset )
+{
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+//FIXME_SMAN return dfb_surfacemanager_adjust_heap_offset( card->shared->surface_manager, offset );
+ return DFB_OK;
+}
+
+void
+dfb_gfxcard_get_capabilities( CardCapabilities *ret_caps )
+{
+ D_ASSERT( card != NULL );
+
+ D_ASSERT( ret_caps != NULL );
+
+ *ret_caps = card->caps;
+}
+
+void
+dfb_gfxcard_get_device_info( GraphicsDeviceInfo *ret_info )
+{
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+ D_ASSERT( ret_info != NULL );
+
+ *ret_info = card->shared->device_info;
+}
+
+void
+dfb_gfxcard_get_driver_info( GraphicsDriverInfo *ret_info )
+{
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+ D_ASSERT( ret_info != NULL );
+
+ *ret_info = card->shared->driver_info;
+}
+
+
+int
+dfb_gfxcard_reserve_memory( CoreGraphicsDevice *device, unsigned int size )
+{
+ DFBGraphicsCoreShared *shared;
+
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ shared = device->shared;
+
+ if (shared->device_info.limits.surface_byteoffset_alignment) {
+ size += shared->device_info.limits.surface_byteoffset_alignment - 1;
+ size -= (size % shared->device_info.limits.surface_byteoffset_alignment);
+ }
+ else
+ D_WARN( "no alignment specified yet?" );
+
+ if (shared->videoram_length < size) {
+ D_WARN( "not enough video memory (%u < %u)", shared->videoram_length, size );
+ return -1;
+ }
+
+ shared->videoram_length -= size;
+
+ return shared->videoram_length;
+}
+
+int
+dfb_gfxcard_reserve_auxmemory( CoreGraphicsDevice *device, unsigned int size )
+{
+ DFBGraphicsCoreShared *shared;
+ int offset;
+
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ shared = device->shared;
+
+ /* Reserve memory at the beginning of the aperture
+ * to prevent overflows on DMA buffers. */
+
+ offset = shared->auxram_offset;
+
+ if (shared->auxram_length < (offset + size))
+ return -1;
+
+ shared->auxram_offset += size;
+
+ return offset;
+}
+
+unsigned int
+dfb_gfxcard_memory_length( void )
+{
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+ return card->shared->videoram_length;
+}
+
+unsigned int
+dfb_gfxcard_auxmemory_length( void )
+{
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+ return card->shared->auxram_length;
+}
+
+volatile void *
+dfb_gfxcard_map_mmio( CoreGraphicsDevice *device,
+ unsigned int offset,
+ int length )
+{
+ return dfb_system_map_mmio( offset, length );
+}
+
+void
+dfb_gfxcard_unmap_mmio( CoreGraphicsDevice *device,
+ volatile void *addr,
+ int length )
+{
+ dfb_system_unmap_mmio( addr, length );
+}
+
+int
+dfb_gfxcard_get_accelerator( CoreGraphicsDevice *device )
+{
+ return dfb_system_get_accelerator();
+}
+
+void
+dfb_gfxcard_get_limits( CoreGraphicsDevice *device,
+ CardLimitations *ret_limits )
+{
+ D_ASSERT( device != NULL );
+ D_ASSERT( ret_limits != NULL );
+
+ if (!device)
+ device = card;
+
+ *ret_limits = device->limits;
+}
+
+void
+dfb_gfxcard_calc_buffer_size( CoreGraphicsDevice *device,
+ CoreSurfaceBuffer *buffer,
+ int *ret_pitch,
+ int *ret_length )
+{
+ int pitch;
+ int length;
+ CoreSurface *surface;
+
+ D_ASSERT( device != NULL );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ /* calculate the required length depending on limitations */
+ pitch = MAX( surface->config.size.w, surface->config.min_size.w );
+
+ if (pitch < device->limits.surface_max_power_of_two_pixelpitch &&
+ surface->config.size.h < device->limits.surface_max_power_of_two_height)
+ pitch = 1 << direct_log2( pitch );
+
+ if (device->limits.surface_pixelpitch_alignment > 1) {
+ pitch += device->limits.surface_pixelpitch_alignment - 1;
+ pitch -= pitch % device->limits.surface_pixelpitch_alignment;
+ }
+
+ pitch = DFB_BYTES_PER_LINE( buffer->format, pitch );
+
+ if (pitch < device->limits.surface_max_power_of_two_bytepitch &&
+ surface->config.size.h < device->limits.surface_max_power_of_two_height)
+ pitch = 1 << direct_log2( pitch );
+
+ if (device->limits.surface_bytepitch_alignment > 1) {
+ pitch += device->limits.surface_bytepitch_alignment - 1;
+ pitch -= pitch % device->limits.surface_bytepitch_alignment;
+ }
+
+ length = DFB_PLANE_MULTIPLY( buffer->format,
+ MAX( surface->config.size.h, surface->config.min_size.h ) * pitch );
+
+ /* Add extra space for optimized routines which are now allowed to overrun, e.g. prefetching. */
+ length += 16;
+
+ if (device->limits.surface_byteoffset_alignment > 1) {
+ length += device->limits.surface_byteoffset_alignment - 1;
+ length -= length % device->limits.surface_byteoffset_alignment;
+ }
+
+ if (ret_pitch)
+ *ret_pitch = pitch;
+
+ if (ret_length)
+ *ret_length = length;
+}
+
+unsigned long
+dfb_gfxcard_memory_physical( CoreGraphicsDevice *device,
+ unsigned int offset )
+{
+ return dfb_system_video_memory_physical( offset );
+}
+
+void *
+dfb_gfxcard_memory_virtual( CoreGraphicsDevice *device,
+ unsigned int offset )
+{
+ return dfb_system_video_memory_virtual( offset );
+}
+
+unsigned long
+dfb_gfxcard_auxmemory_physical( CoreGraphicsDevice *device,
+ unsigned int offset )
+{
+ return dfb_system_aux_memory_physical( offset );
+}
+
+void *
+dfb_gfxcard_auxmemory_virtual( CoreGraphicsDevice *device,
+ unsigned int offset )
+{
+ return dfb_system_aux_memory_virtual( offset );
+}
+
+void *
+dfb_gfxcard_get_device_data( void )
+{
+ D_ASSERT( card != NULL );
+ D_ASSERT( card->shared != NULL );
+
+ return card->shared->device_data;
+}
+
+void *
+dfb_gfxcard_get_driver_data( void )
+{
+ D_ASSERT( card != NULL );
+
+ return card->driver_data;
+}
+
+CoreGraphicsDevice *
+dfb_gfxcard_get_primary( void )
+{
+ return card;
+}
+
+
+/** internal **/
+
+/*
+ * loads/probes/unloads one driver module after another until a suitable
+ * driver is found and returns its symlinked functions
+ */
+static void dfb_gfxcard_find_driver( CoreDFB *core )
+{
+ DirectLink *link;
+ FusionSHMPoolShared *pool = dfb_core_shmpool( core );
+
+ direct_list_foreach (link, dfb_graphics_drivers.entries) {
+ DirectModuleEntry *module = (DirectModuleEntry*) link;
+
+ const GraphicsDriverFuncs *funcs = direct_module_ref( module );
+
+ if (!funcs)
+ continue;
+
+ if (!card->module && funcs->Probe( card )) {
+ funcs->GetDriverInfo( card, &card->shared->driver_info );
+
+ card->module = module;
+ card->driver_funcs = funcs;
+
+ card->shared->module_name = SHSTRDUP( pool, module->name );
+ }
+ else
+ direct_module_unref( module );
+ }
+}
+
+/*
+ * loads the driver module used by the session
+ */
+static void dfb_gfxcard_load_driver( void )
+{
+ DirectLink *link;
+
+ if (!card->shared->module_name)
+ return;
+
+ direct_list_foreach (link, dfb_graphics_drivers.entries) {
+ DirectModuleEntry *module = (DirectModuleEntry*) link;
+
+ const GraphicsDriverFuncs *funcs = direct_module_ref( module );
+
+ if (!funcs)
+ continue;
+
+ if (!card->module &&
+ !strcmp( module->name, card->shared->module_name ))
+ {
+ card->module = module;
+ card->driver_funcs = funcs;
+ }
+ else
+ direct_module_unref( module );
+ }
+}
+
diff --git a/Source/DirectFB/src/core/gfxcard.h b/Source/DirectFB/src/core/gfxcard.h
new file mode 100755
index 0000000..6e723d0
--- /dev/null
+++ b/Source/DirectFB/src/core/gfxcard.h
@@ -0,0 +1,470 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __GFXCARD_H__
+#define __GFXCARD_H__
+
+#include <pthread.h>
+
+#include <direct/modules.h>
+
+#include <fusion/lock.h>
+
+#include <directfb.h>
+#include <core/coretypes.h>
+
+
+typedef enum {
+ CCF_CLIPPING = 0x00000001,
+ CCF_NOTRIEMU = 0x00000002,
+ CCF_READSYSMEM = 0x00000004,
+ /* CCF_WRITESYSMEM ?! */
+ CCF_AUXMEMORY = 0x00000010,
+ CCF_RENDEROPTS = 0x00000020
+} CardCapabilitiesFlags;
+
+struct __DFB_CoreGraphicsSerial {
+ unsigned int serial;
+ unsigned int generation;
+};
+
+typedef struct {
+ CardCapabilitiesFlags flags;
+
+ DFBAccelerationMask accel;
+ DFBSurfaceBlittingFlags blitting;
+ DFBSurfaceDrawingFlags drawing;
+ DFBAccelerationMask clip;
+} CardCapabilities;
+
+typedef struct {
+ unsigned int surface_byteoffset_alignment;
+ unsigned int surface_pixelpitch_alignment;
+ unsigned int surface_bytepitch_alignment;
+
+ unsigned int surface_max_power_of_two_pixelpitch;
+ unsigned int surface_max_power_of_two_bytepitch;
+ unsigned int surface_max_power_of_two_height;
+
+ DFBDimension dst_min;
+ DFBDimension dst_max;
+ DFBDimension src_min;
+ DFBDimension src_max;
+} CardLimitations;
+
+DECLARE_MODULE_DIRECTORY( dfb_graphics_drivers );
+
+/*
+ * Increase this number when changes result in binary incompatibility!
+ */
+#define DFB_GRAPHICS_DRIVER_ABI_VERSION 34
+
+#define DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH 40
+#define DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH 60
+#define DFB_GRAPHICS_DRIVER_INFO_URL_LENGTH 100
+#define DFB_GRAPHICS_DRIVER_INFO_LICENSE_LENGTH 40
+
+#define DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH 48
+#define DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH 64
+
+
+typedef struct {
+ int major; /* major version */
+ int minor; /* minor version */
+} GraphicsDriverVersion; /* major.minor, e.g. 0.1 */
+
+typedef struct {
+ GraphicsDriverVersion version;
+
+ char name[DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH];
+ /* Name of driver, e.g. 'Matrox Driver' */
+
+ char vendor[DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH];
+ /* Vendor (or author) of the driver,
+ e.g. 'directfb.org' or 'Denis Oliver Kropp' */
+
+ char url[DFB_GRAPHICS_DRIVER_INFO_URL_LENGTH];
+ /* URL for driver updates,
+ e.g. 'http://www.directfb.org/' */
+
+ char license[DFB_GRAPHICS_DRIVER_INFO_LICENSE_LENGTH];
+ /* License, e.g. 'LGPL' or 'proprietary' */
+
+ unsigned int driver_data_size;
+ unsigned int device_data_size;
+} GraphicsDriverInfo;
+
+typedef struct {
+ char name[DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH];
+ /* Device name, e.g. 'G400' */
+
+ char vendor[DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH];
+ /* Vendor of the device,
+ e.g. 'Matrox' or 'ATI' */
+
+ /* hardware acceleration capabilities */
+ CardCapabilities caps;
+
+ /* hardware limitations */
+ CardLimitations limits;
+} GraphicsDeviceInfo;
+
+typedef struct _GraphicsDeviceFuncs {
+ /*
+ * function that is called after variable screeninfo is changed
+ * (used for buggy fbdev drivers, that reinitialize something when
+ * calling FBIO_PUT_VSCREENINFO)
+ */
+ void (*AfterSetVar)( void *driver_data, void *device_data );
+
+ /*
+ * Called after driver->InitDevice() and during dfb_gfxcard_unlock( true ).
+ * The driver should do the one time initialization of the engine,
+ * e.g. writing some registers that are supposed to have a fixed value.
+ *
+ * This happens after mode switching or after returning from
+ * OpenGL state (e.g. DRI driver).
+ */
+ void (*EngineReset)( void *driver_data, void *device_data );
+
+ /*
+ * Makes sure that graphics hardware has finished all operations.
+ *
+ * This method is called before the CPU accesses a surface' buffer
+ * that had been written to by the hardware after this method has been
+ * called the last time.
+ *
+ * It's also called before entering the OpenGL state (e.g. DRI driver).
+ */
+ DFBResult (*EngineSync)( void *driver_data, void *device_data );
+
+ /*
+ * Called during dfb_gfxcard_lock() to notify the driver that
+ * the current rendering state is no longer valid.
+ */
+ void (*InvalidateState)( void *driver_data, void *device_data );
+
+ /*
+ * after the video memory has been written to by the CPU (e.g. modification
+ * of a texture) make sure the accelerator won't use cached texture data
+ */
+ void (*FlushTextureCache)( void *driver_data, void *device_data );
+
+ /*
+ * After the video memory has been written to by the accelerator
+ * make sure the CPU won't read back cached data.
+ */
+ void (*FlushReadCache)( void *driver_data, void *device_data );
+
+ /*
+ * Called before a software access to a video surface buffer.
+ */
+ void (*SurfaceEnter)( void *driver_data, void *device_data,
+ CoreSurfaceBuffer *buffer, DFBSurfaceLockFlags flags );
+
+ /*
+ * Called after a software access to a video surface buffer.
+ */
+ void (*SurfaceLeave)( void *driver_data, void *device_data, CoreSurfaceBuffer *buffer );
+
+ /*
+ * Return the serial of the last (queued) operation.
+ *
+ * The serial is used to wait for finishing a specific graphics
+ * operation instead of the whole engine being idle.
+ */
+ void (*GetSerial)( void *driver_data, void *device_data, CoreGraphicsSerial *serial );
+
+ /*
+ * Makes sure that graphics hardware has finished the specified operation.
+ */
+ DFBResult (*WaitSerial)( void *driver_data, void *device_data, const CoreGraphicsSerial *serial );
+
+ /*
+ * emit any buffered commands, i.e. trigger processing
+ */
+ void (*EmitCommands) ( void *driver_data, void *device_data );
+
+ /*
+ * Check if the function 'accel' can be accelerated with the 'state'.
+ * If that's true, the function sets the 'accel' bit in 'state->accel'.
+ * Otherwise the function just returns, no need to clear the bit.
+ */
+ void (*CheckState)( void *driver_data, void *device_data,
+ CardState *state, DFBAccelerationMask accel );
+
+ /*
+ * Program card for execution of the function 'accel' with the 'state'.
+ * 'state->modified' contains information about changed entries.
+ * This function has to set at least 'accel' in 'state->set'.
+ * The driver should remember 'state->modified' and clear it.
+ * The driver may modify 'funcs' depending on 'state' settings.
+ */
+ void (*SetState) ( void *driver_data, void *device_data,
+ struct _GraphicsDeviceFuncs *funcs,
+ CardState *state, DFBAccelerationMask accel );
+
+ /*
+ * drawing functions
+ */
+ bool (*FillRectangle) ( void *driver_data, void *device_data,
+ DFBRectangle *rect );
+
+ bool (*DrawRectangle) ( void *driver_data, void *device_data,
+ DFBRectangle *rect );
+
+ bool (*DrawLine) ( void *driver_data, void *device_data,
+ DFBRegion *line );
+
+ bool (*FillTriangle) ( void *driver_data, void *device_data,
+ DFBTriangle *tri );
+
+ /*
+ * blitting functions
+ */
+ bool (*Blit) ( void *driver_data, void *device_data,
+ DFBRectangle *rect, int dx, int dy );
+
+ bool (*StretchBlit) ( void *driver_data, void *device_data,
+ DFBRectangle *srect, DFBRectangle *drect );
+
+ bool (*TextureTriangles)( void *driver_data, void *device_data,
+ DFBVertex *vertices, int num,
+ DFBTriangleFormation formation );
+
+ /*
+ * Signal beginning of a sequence of operations using this state.
+ * Any number of states can be 'drawing'.
+ */
+ void (*StartDrawing)( void *driver_data, void *device_data, CardState *state );
+
+ /*
+ * Signal end of sequence, i.e. destination surface is consistent again.
+ */
+ void (*StopDrawing)( void *driver_data, void *device_data, CardState *state );
+} GraphicsDeviceFuncs;
+
+typedef struct {
+ int (*Probe) (CoreGraphicsDevice *device);
+ void (*GetDriverInfo) (CoreGraphicsDevice *device,
+ GraphicsDriverInfo *driver_info);
+
+ DFBResult (*InitDriver) (CoreGraphicsDevice *device,
+ GraphicsDeviceFuncs *funcs,
+ void *driver_data,
+ void *device_data,
+ CoreDFB *core);
+
+ DFBResult (*InitDevice) (CoreGraphicsDevice *device,
+ GraphicsDeviceInfo *device_info,
+ void *driver_data,
+ void *device_data);
+
+ void (*CloseDevice) (CoreGraphicsDevice *device,
+ void *driver_data,
+ void *device_data);
+ void (*CloseDriver) (CoreGraphicsDevice *device,
+ void *driver_data);
+} GraphicsDriverFuncs;
+
+typedef enum {
+ GDLF_NONE = 0x00000000,
+
+ GDLF_WAIT = 0x00000001,
+ GDLF_SYNC = 0x00000002,
+ GDLF_INVALIDATE = 0x00000004,
+ GDLF_RESET = 0x00000008
+} GraphicsDeviceLockFlags;
+
+DFBResult dfb_gfxcard_lock( GraphicsDeviceLockFlags flags );
+void dfb_gfxcard_unlock( void );
+void dfb_gfxcard_holdup( void );
+
+bool dfb_gfxcard_state_check( CardState *state, DFBAccelerationMask accel );
+
+/*
+ * Signal beginning of a sequence of operations using this state.
+ * Any number of states can be 'drawing'.
+ */
+void dfb_gfxcard_start_drawing( CoreGraphicsDevice *device,
+ CardState *state );
+
+/*
+ * Signal end of sequence, i.e. destination surface is consistent again.
+ */
+void dfb_gfxcard_stop_drawing ( CoreGraphicsDevice *device,
+ CardState *state );
+
+/*
+ * drawing functions, lock source and destination surfaces,
+ * handle clipping and drawing method (hardware/software)
+ */
+void dfb_gfxcard_fillrectangles ( const DFBRectangle *rects,
+ int num,
+ CardState *state );
+
+void dfb_gfxcard_drawrectangle ( DFBRectangle *rect,
+ CardState *state );
+
+void dfb_gfxcard_drawlines ( DFBRegion *lines,
+ int num_lines,
+ CardState *state );
+
+void dfb_gfxcard_fillspans ( int y,
+ DFBSpan *spans,
+ int num_spans,
+ CardState *state );
+
+void dfb_gfxcard_filltriangles ( const DFBTriangle *tris,
+ int num,
+ CardState *state );
+
+void dfb_gfxcard_blit ( DFBRectangle *rect,
+ int dx,
+ int dy,
+ CardState *state );
+
+void dfb_gfxcard_batchblit ( DFBRectangle *rects,
+ DFBPoint *points,
+ int num,
+ CardState *state );
+
+void dfb_gfxcard_tileblit ( DFBRectangle *rect,
+ int dx1,
+ int dy1,
+ int dx2,
+ int dy2,
+ CardState *state );
+
+void dfb_gfxcard_stretchblit ( DFBRectangle *srect,
+ DFBRectangle *drect,
+ CardState *state );
+
+void dfb_gfxcard_texture_triangles ( DFBVertex *vertices,
+ int num,
+ DFBTriangleFormation formation,
+ CardState *state );
+
+void dfb_gfxcard_drawstring ( const u8 *text,
+ int bytes,
+ DFBTextEncodingID encoding,
+ int x,
+ int y,
+ CoreFont *font,
+ unsigned int layers,
+ CardState *state );
+
+void dfb_gfxcard_drawglyph ( CoreGlyphData **glyph,
+ int x,
+ int y,
+ CoreFont *font,
+ unsigned int layers,
+ CardState *state );
+
+bool dfb_gfxcard_drawstring_check_state ( CoreFont *font,
+ CardState *state );
+
+DFBResult dfb_gfxcard_sync( void );
+void dfb_gfxcard_invalidate_state( void );
+DFBResult dfb_gfxcard_wait_serial( const CoreGraphicsSerial *serial );
+void dfb_gfxcard_flush_texture_cache( void );
+void dfb_gfxcard_flush_read_cache( void );
+void dfb_gfxcard_after_set_var( void );
+void dfb_gfxcard_surface_enter( CoreSurfaceBuffer *buffer, DFBSurfaceLockFlags flags );
+void dfb_gfxcard_surface_leave( CoreSurfaceBuffer *buffer );
+
+DFBResult dfb_gfxcard_adjust_heap_offset( int offset );
+
+void dfb_gfxcard_get_capabilities ( CardCapabilities *ret_caps );
+void dfb_gfxcard_get_device_info ( GraphicsDeviceInfo *ret_info );
+void dfb_gfxcard_get_driver_info ( GraphicsDriverInfo *ret_info );
+
+int dfb_gfxcard_reserve_memory ( CoreGraphicsDevice *device,
+ unsigned int size );
+int dfb_gfxcard_reserve_auxmemory ( CoreGraphicsDevice *device,
+ unsigned int size );
+
+unsigned int dfb_gfxcard_memory_length ( void );
+unsigned int dfb_gfxcard_auxmemory_length ( void );
+
+void *dfb_gfxcard_get_device_data ( void );
+void *dfb_gfxcard_get_driver_data ( void );
+
+CoreGraphicsDevice *dfb_gfxcard_get_primary ( void );
+
+/*
+ * Graphics drivers call this function to get access to MMIO regions.
+ *
+ * device: Graphics device to map
+ * offset: Offset from MMIO base (default offset is 0)
+ * length: Length of mapped region (-1 uses default length)
+ *
+ * Returns the virtual address or NULL if mapping failed.
+ */
+volatile void *dfb_gfxcard_map_mmio( CoreGraphicsDevice *device,
+ unsigned int offset,
+ int length );
+
+/*
+ * Graphics drivers call this function to unmap MMIO regions.
+ *
+ * addr: Virtual address returned by gfxcard_map_mmio
+ * length: Length of mapped region (-1 uses default length)
+ */
+void dfb_gfxcard_unmap_mmio( CoreGraphicsDevice *device,
+ volatile void *addr,
+ int length );
+
+int dfb_gfxcard_get_accelerator( CoreGraphicsDevice *device );
+
+void dfb_gfxcard_get_limits( CoreGraphicsDevice *device,
+ CardLimitations *ret_limits );
+
+void dfb_gfxcard_calc_buffer_size( CoreGraphicsDevice *device,
+ CoreSurfaceBuffer *buffer,
+ int *ret_pitch,
+ int *ret_length );
+
+unsigned long dfb_gfxcard_memory_physical ( CoreGraphicsDevice *device,
+ unsigned int offset );
+void *dfb_gfxcard_memory_virtual ( CoreGraphicsDevice *device,
+ unsigned int offset );
+
+unsigned long dfb_gfxcard_auxmemory_physical( CoreGraphicsDevice *device,
+ unsigned int offset );
+void *dfb_gfxcard_auxmemory_virtual ( CoreGraphicsDevice *device,
+ unsigned int offset );
+
+
+/* Hook for registering additional screen(s) and layer(s) in app or lib initializing DirectFB. */
+extern void (*__DFB_CoreRegisterHook)( CoreDFB *core, CoreGraphicsDevice *device, void *ctx );
+extern void *__DFB_CoreRegisterHookCtx;
+
+
+#endif
+
diff --git a/Source/DirectFB/src/core/graphics_driver.h b/Source/DirectFB/src/core/graphics_driver.h
new file mode 100755
index 0000000..de03234
--- /dev/null
+++ b/Source/DirectFB/src/core/graphics_driver.h
@@ -0,0 +1,86 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __GRAPHICS_DRIVER_H__
+#define __GRAPHICS_DRIVER_H__
+
+#include <direct/modules.h>
+
+#include <core/gfxcard.h>
+
+
+static int
+driver_probe( CoreGraphicsDevice *device );
+
+static void
+driver_get_info( CoreGraphicsDevice *device,
+ GraphicsDriverInfo *info );
+
+static DFBResult
+driver_init_driver( CoreGraphicsDevice *device,
+ GraphicsDeviceFuncs *funcs,
+ void *driver_data,
+ void *device_data,
+ CoreDFB *core );
+
+static DFBResult
+driver_init_device( CoreGraphicsDevice *device,
+ GraphicsDeviceInfo *device_info,
+ void *driver_data,
+ void *device_data );
+
+static void
+driver_close_device( CoreGraphicsDevice *device,
+ void *driver_data,
+ void *device_data );
+
+static void
+driver_close_driver( CoreGraphicsDevice *device,
+ void *driver_data );
+
+static GraphicsDriverFuncs driver_funcs = {
+ .Probe = driver_probe,
+ .GetDriverInfo = driver_get_info,
+ .InitDriver = driver_init_driver,
+ .InitDevice = driver_init_device,
+ .CloseDevice = driver_close_device,
+ .CloseDriver = driver_close_driver
+};
+
+#define DFB_GRAPHICS_DRIVER(shortname) \
+__attribute__((constructor)) void directfb_##shortname( void ); \
+ \
+void \
+directfb_##shortname( void ) \
+{ \
+ direct_modules_register( &dfb_graphics_drivers, \
+ DFB_GRAPHICS_DRIVER_ABI_VERSION, \
+ #shortname, &driver_funcs ); \
+}
+
+#endif
diff --git a/Source/DirectFB/src/core/input.c b/Source/DirectFB/src/core/input.c
new file mode 100755
index 0000000..c8eee18
--- /dev/null
+++ b/Source/DirectFB/src/core/input.c
@@ -0,0 +1,2668 @@
+/*
+ (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/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <directfb.h>
+#include <directfb_keynames.h>
+
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+
+#include <fusion/shmalloc.h>
+#include <fusion/reactor.h>
+#include <fusion/arena.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/core_parts.h>
+
+#include <core/gfxcard.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+#include <core/system.h>
+#include <core/layer_context.h>
+#include <core/layer_control.h>
+#include <core/layer_region.h>
+#include <core/layers.h>
+#include <core/input.h>
+#include <core/windows.h>
+#include <core/windows_internal.h>
+
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/modules.h>
+#include <direct/trace.h>
+
+#include <fusion/build.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+#include <gfx/convert.h>
+
+
+D_DEBUG_DOMAIN( Core_Input, "Core/Input", "DirectFB Input Core" );
+D_DEBUG_DOMAIN( Core_InputEvt, "Core/Input/Evt", "DirectFB Input Core Events & Dispatch" );
+
+
+DEFINE_MODULE_DIRECTORY( dfb_input_modules, "inputdrivers", DFB_INPUT_DRIVER_ABI_VERSION );
+
+/**********************************************************************************************************************/
+
+typedef enum {
+ CICC_RESCAN_DEVICES
+} CoreInputCoreCommand;
+
+typedef enum {
+ CIDC_RELOAD_KEYMAP,
+ CIDC_SET_SENSITIVITY
+} CoreInputDeviceCommand;
+
+
+typedef struct {
+ DirectLink link;
+
+ int magic;
+
+ DirectModuleEntry *module;
+
+ const InputDriverFuncs *funcs;
+
+ InputDriverInfo info;
+
+ int nr_devices;
+} InputDriver;
+
+typedef struct {
+ int min_keycode;
+ int max_keycode;
+ int num_entries;
+ DFBInputDeviceKeymapEntry *entries;
+} InputDeviceKeymap;
+
+typedef struct {
+ int magic;
+
+ DFBInputDeviceID id; /* unique device id */
+
+ int num;
+
+ InputDeviceInfo device_info;
+
+ InputDeviceKeymap keymap;
+
+ DFBInputDeviceModifierMask modifiers_l;
+ DFBInputDeviceModifierMask modifiers_r;
+ DFBInputDeviceLockState locks;
+ DFBInputDeviceButtonMask buttons;
+
+ DFBInputDeviceKeyIdentifier last_key; /* last key pressed */
+ DFBInputDeviceKeySymbol last_symbol; /* last symbol pressed */
+ bool first_press; /* first press of key */
+
+ FusionReactor *reactor; /* event dispatcher */
+ FusionSkirmish lock;
+
+ FusionCall call; /* driver call via master */
+
+ unsigned int axis_num;
+ DFBInputDeviceAxisInfo *axis_info;
+
+
+ DFBInputDeviceState state;
+} InputDeviceShared;
+
+struct __DFB_CoreInputDevice {
+ int magic;
+
+ InputDeviceShared *shared;
+
+ InputDriver *driver;
+ void *driver_data;
+
+ CoreDFB *core;
+};
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+ int num;
+ InputDeviceShared *devices[MAX_INPUTDEVICES];
+
+ FusionCall call;
+ FusionReactor *reactor;
+} DFBInputCoreShared;
+
+struct __DFB_DFBInputCore {
+ int magic;
+
+ CoreDFB *core;
+
+ DFBInputCoreShared *shared;
+
+ DirectLink *drivers;
+
+ int num;
+ CoreInputDevice *devices[MAX_INPUTDEVICES];
+
+ Reaction reaction;
+};
+
+
+DFB_CORE_PART( input_core, InputCore );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ DFBInputDeviceKeySymbol target;
+ DFBInputDeviceKeySymbol result;
+} DeadKeyCombo;
+
+typedef struct {
+ DFBInputDeviceKeySymbol deadkey;
+ const DeadKeyCombo *combos;
+} DeadKeyMap;
+
+/**********************************************************************************************************************/
+
+static const DeadKeyCombo combos_grave[] = {
+ { DIKS_SPACE, (unsigned char) '`' },
+ { DIKS_SMALL_A, (unsigned char) 'à' },
+ { DIKS_SMALL_E, (unsigned char) 'è' },
+ { DIKS_SMALL_I, (unsigned char) 'ì' },
+ { DIKS_SMALL_O, (unsigned char) 'ò' },
+ { DIKS_SMALL_U, (unsigned char) 'ù' },
+ { DIKS_CAPITAL_A, (unsigned char) 'À' },
+ { DIKS_CAPITAL_E, (unsigned char) 'È' },
+ { DIKS_CAPITAL_I, (unsigned char) 'Ì' },
+ { DIKS_CAPITAL_O, (unsigned char) 'Ò' },
+ { DIKS_CAPITAL_U, (unsigned char) 'Ù' },
+ { 0, 0 }
+};
+
+static const DeadKeyCombo combos_acute[] = {
+ { DIKS_SPACE, (unsigned char) '\'' },
+ { DIKS_SMALL_A, (unsigned char) 'á' },
+ { DIKS_SMALL_E, (unsigned char) 'é' },
+ { DIKS_SMALL_I, (unsigned char) 'í' },
+ { DIKS_SMALL_O, (unsigned char) 'ó' },
+ { DIKS_SMALL_U, (unsigned char) 'ú' },
+ { DIKS_SMALL_Y, (unsigned char) 'ý' },
+ { DIKS_CAPITAL_A, (unsigned char) 'Á' },
+ { DIKS_CAPITAL_E, (unsigned char) 'É' },
+ { DIKS_CAPITAL_I, (unsigned char) 'Í' },
+ { DIKS_CAPITAL_O, (unsigned char) 'Ó' },
+ { DIKS_CAPITAL_U, (unsigned char) 'Ú' },
+ { DIKS_CAPITAL_Y, (unsigned char) 'Ý' },
+ { 0, 0 }
+};
+
+static const DeadKeyCombo combos_circumflex[] = {
+ { DIKS_SPACE, (unsigned char) '^' },
+ { DIKS_SMALL_A, (unsigned char) 'â' },
+ { DIKS_SMALL_E, (unsigned char) 'ê' },
+ { DIKS_SMALL_I, (unsigned char) 'î' },
+ { DIKS_SMALL_O, (unsigned char) 'ô' },
+ { DIKS_SMALL_U, (unsigned char) 'û' },
+ { DIKS_CAPITAL_A, (unsigned char) 'Â' },
+ { DIKS_CAPITAL_E, (unsigned char) 'Ê' },
+ { DIKS_CAPITAL_I, (unsigned char) 'Î' },
+ { DIKS_CAPITAL_O, (unsigned char) 'Ô' },
+ { DIKS_CAPITAL_U, (unsigned char) 'Û' },
+ { 0, 0 }
+};
+
+static const DeadKeyCombo combos_diaeresis[] = {
+ { DIKS_SPACE, (unsigned char) '¨' },
+ { DIKS_SMALL_A, (unsigned char) 'ä' },
+ { DIKS_SMALL_E, (unsigned char) 'ë' },
+ { DIKS_SMALL_I, (unsigned char) 'ï' },
+ { DIKS_SMALL_O, (unsigned char) 'ö' },
+ { DIKS_SMALL_U, (unsigned char) 'ü' },
+ { DIKS_CAPITAL_A, (unsigned char) 'Ä' },
+ { DIKS_CAPITAL_E, (unsigned char) 'Ë' },
+ { DIKS_CAPITAL_I, (unsigned char) 'Ï' },
+ { DIKS_CAPITAL_O, (unsigned char) 'Ö' },
+ { DIKS_CAPITAL_U, (unsigned char) 'Ü' },
+ { 0, 0 }
+};
+
+static const DeadKeyCombo combos_tilde[] = {
+ { DIKS_SPACE, (unsigned char) '~' },
+ { DIKS_SMALL_A, (unsigned char) 'ã' },
+ { DIKS_SMALL_N, (unsigned char) 'ñ' },
+ { DIKS_SMALL_O, (unsigned char) 'õ' },
+ { DIKS_CAPITAL_A, (unsigned char) 'Ã' },
+ { DIKS_CAPITAL_N, (unsigned char) 'Ñ' },
+ { DIKS_CAPITAL_O, (unsigned char) 'Õ' },
+ { 0, 0 }
+};
+
+static const DeadKeyMap deadkey_maps[] = {
+ { DIKS_DEAD_GRAVE, combos_grave },
+ { DIKS_DEAD_ACUTE, combos_acute },
+ { DIKS_DEAD_CIRCUMFLEX, combos_circumflex },
+ { DIKS_DEAD_DIAERESIS, combos_diaeresis },
+ { DIKS_DEAD_TILDE, combos_tilde }
+};
+
+/* define a lookup table to go from key IDs to names.
+ * This is used to look up the names provided in a loaded key table */
+/* this table is roughly 4Kb in size */
+DirectFBKeySymbolNames(KeySymbolNames);
+DirectFBKeyIdentifierNames(KeyIdentifierNames);
+
+/**********************************************************************************************************************/
+
+static void init_drivers ( CoreDFB *core );
+static DFBResult rescan_devices( CoreDFB *core );
+
+static void allocate_device_keymap( CoreDFB *core, CoreInputDevice *device );
+
+static DFBInputDeviceKeymapEntry *get_keymap_entry( CoreInputDevice *device,
+ int code );
+
+static DFBResult set_keymap_entry( CoreInputDevice *device,
+ int code,
+ DFBInputDeviceKeymapEntry *entry );
+
+static DFBResult load_keymap( CoreInputDevice *device,
+ char *filename );
+
+static DFBInputDeviceKeySymbol lookup_keysymbol( char *symbolname );
+static DFBInputDeviceKeyIdentifier lookup_keyidentifier( char *identifiername );
+
+/**********************************************************************************************************************/
+
+static bool lookup_from_table( CoreInputDevice *device,
+ DFBInputEvent *event,
+ DFBInputEventFlags lookup );
+
+static void fixup_key_event ( CoreInputDevice *device,
+ DFBInputEvent *event );
+
+static void fixup_mouse_event( CoreInputDevice *device,
+ DFBInputEvent *event );
+
+static void flush_keys ( CoreInputDevice *device );
+
+static bool core_input_filter( CoreInputDevice *device,
+ DFBInputEvent *event );
+
+/**********************************************************************************************************************/
+
+static DFBInputDeviceKeyIdentifier symbol_to_id( DFBInputDeviceKeySymbol symbol );
+
+static DFBInputDeviceKeySymbol id_to_symbol( DFBInputDeviceKeyIdentifier id,
+ DFBInputDeviceModifierMask modifiers,
+ DFBInputDeviceLockState locks );
+
+/**********************************************************************************************************************/
+
+static ReactionFunc dfb_input_globals[MAX_INPUT_GLOBALS+1] = {
+/* 0 */ _dfb_windowstack_inputdevice_listener,
+ NULL
+};
+
+DFBResult
+dfb_input_add_global( ReactionFunc func,
+ int *ret_index )
+{
+ int i;
+
+ D_DEBUG_AT( Core_Input, "%s( %p, %p )\n", __FUNCTION__, func, ret_index );
+
+ D_ASSERT( func != NULL );
+ D_ASSERT( ret_index != NULL );
+
+ for (i=0; i<MAX_INPUT_GLOBALS; i++) {
+ if (!dfb_input_globals[i]) {
+ dfb_input_globals[i] = func;
+
+ D_DEBUG_AT( Core_Input, " -> index %d\n", i );
+
+ *ret_index = i;
+
+ return DFB_OK;
+ }
+ }
+
+ return DFB_LIMITEXCEEDED;
+}
+
+DFBResult
+dfb_input_set_global( ReactionFunc func,
+ int index )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p, %d )\n", __FUNCTION__, func, index );
+
+ D_ASSERT( func != NULL );
+ D_ASSERT( index >= 0 );
+ D_ASSERT( index < MAX_INPUT_GLOBALS );
+
+ D_ASSUME( dfb_input_globals[index] == NULL );
+
+ dfb_input_globals[index] = func;
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+static DFBInputCore *core_local; /* FIXME */
+static DFBInputCoreShared *core_input; /* FIXME */
+
+/**********************************************************************************************************************/
+
+static FusionCallHandlerResult
+core_input_call_handler( int caller, /* fusion id of the caller */
+ int call_arg, /* optional call parameter */
+ void *call_ptr, /* optional call parameter */
+ void *ctx, /* optional handler context */
+ unsigned int serial,
+ int *ret_val )
+{
+ CoreDFB *core = ctx;
+
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, core );
+
+ switch (call_arg) {
+ case CICC_RESCAN_DEVICES:
+ *ret_val = rescan_devices( core );
+ break;
+
+ default:
+ D_BUG( "unknown command %d", call_arg );
+ *ret_val = DFB_BUG;
+ }
+
+ return FCHR_RETURN;
+}
+
+/**********************************************************************************************************************/
+
+static DFBResult
+dfb_input_core_initialize( CoreDFB *core,
+ DFBInputCore *data,
+ DFBInputCoreShared *shared )
+{
+ D_DEBUG_AT( Core_Input, "dfb_input_core_initialize( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( shared != NULL );
+
+ core_local = data; /* FIXME */
+ core_input = shared; /* FIXME */
+
+ data->core = core;
+ data->shared = shared;
+
+
+ fusion_call_init( &core_input->call, core_input_call_handler, core, dfb_core_world( core ) );
+
+ core_input->reactor = fusion_reactor_new( sizeof(CoreInputCoreNotification), "Input Core", dfb_core_world( core ) );
+
+ fusion_reactor_direct( core_input->reactor, false );
+
+ direct_modules_explore_directory( &dfb_input_modules );
+
+ init_drivers( core );
+ rescan_devices( core );
+
+ D_MAGIC_SET( data, DFBInputCore );
+ D_MAGIC_SET( shared, DFBInputCoreShared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+rejoin_devices( CoreDFB *core )
+{
+ int i;
+
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, core );
+
+ D_ASSERT( core != NULL );
+ D_MAGIC_ASSERT( core_local, DFBInputCore );
+ D_ASSERT( core_input != NULL );
+
+ for (i=core_local->num; i<core_input->num; i++) {
+ CoreInputDevice *device;
+
+ D_DEBUG_AT( Core_Input, " -> adding %d (%s)\n",
+ core_input->devices[i]->id,
+ core_input->devices[i]->device_info.desc.name );
+
+ device = D_CALLOC( 1, sizeof(CoreInputDevice) );
+ if (!device) {
+ D_OOM();
+ continue;
+ }
+
+ device->shared = core_input->devices[i];
+
+ D_MAGIC_SET( device, CoreInputDevice );
+
+ /* add it to the list */
+ core_local->devices[core_local->num++] = device;
+ }
+
+ return DFB_OK;
+}
+
+static ReactionResult
+core_input_core_reaction( const void *msg_data,
+ void *ctx )
+{
+ const CoreInputCoreNotification *notification = msg_data;
+ CoreDFB *core = ctx;
+
+ if (notification->flags & CICNF_NEW_DEVICE)
+ rejoin_devices( core );
+
+ return RS_OK;
+}
+
+static DFBResult
+dfb_input_core_join( CoreDFB *core,
+ DFBInputCore *data,
+ DFBInputCoreShared *shared )
+{
+ D_DEBUG_AT( Core_Input, "dfb_input_core_join( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_MAGIC_ASSERT( shared, DFBInputCoreShared );
+
+ core_local = data; /* FIXME */
+ core_input = shared; /* FIXME */
+
+ data->core = core;
+ data->shared = shared;
+
+ D_MAGIC_SET( data, DFBInputCore );
+
+
+ rejoin_devices( core );
+
+ fusion_reactor_attach( core_input->reactor, core_input_core_reaction, core, &core_local->reaction );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_input_core_shutdown( DFBInputCore *data,
+ bool emergency )
+{
+ int i;
+ DFBInputCoreShared *shared;
+ FusionSHMPoolShared *pool = dfb_core_shmpool( data->core );
+
+ D_DEBUG_AT( Core_Input, "dfb_input_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBInputCore );
+ D_MAGIC_ASSERT( data->shared, DFBInputCoreShared );
+
+ shared = data->shared;
+
+
+ for (i=0; i<data->num; i++) {
+ CoreInputDevice *device = data->devices[i];
+ InputDriver *driver;
+ InputDeviceShared *devshared;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ driver = device->driver;
+ D_ASSERT( driver != NULL );
+
+ devshared = device->shared;
+ D_ASSERT( devshared != NULL );
+
+ fusion_call_destroy( &devshared->call );
+ fusion_skirmish_destroy( &devshared->lock );
+
+ if (device->driver_data != NULL) {
+ void *driver_data;
+
+ D_ASSERT( driver->funcs != NULL );
+ D_ASSERT( driver->funcs->CloseDevice != NULL );
+
+ D_DEBUG_AT( Core_Input, " -> closing '%s' (%d) %d.%d (%s)\n",
+ devshared->device_info.desc.name, devshared->num + 1,
+ driver->info.version.major,
+ driver->info.version.minor, driver->info.vendor );
+
+ driver_data = device->driver_data;
+ device->driver_data = NULL;
+ driver->funcs->CloseDevice( driver_data );
+ }
+
+ if (!--driver->nr_devices) {
+ direct_module_unref( driver->module );
+ D_FREE( driver );
+ }
+
+ fusion_reactor_free( devshared->reactor );
+
+ if (devshared->keymap.entries)
+ SHFREE( pool, devshared->keymap.entries );
+
+ if (devshared->axis_info)
+ SHFREE( pool, devshared->axis_info );
+
+ SHFREE( pool, devshared );
+
+ D_MAGIC_CLEAR( device );
+
+ D_FREE( device );
+ }
+
+ D_MAGIC_CLEAR( data );
+ D_MAGIC_CLEAR( shared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_input_core_leave( DFBInputCore *data,
+ bool emergency )
+{
+ int i;
+ DFBInputCoreShared *shared;
+
+ D_DEBUG_AT( Core_Input, "dfb_input_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBInputCore );
+ D_MAGIC_ASSERT( data->shared, DFBInputCoreShared );
+
+ shared = data->shared;
+
+
+ for (i=0; i<data->num; i++) {
+ CoreInputDevice *device = data->devices[i];
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_FREE( device );
+ }
+
+
+ D_MAGIC_CLEAR( data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_input_core_suspend( DFBInputCore *data )
+{
+ int i;
+ DFBInputCoreShared *shared;
+
+ D_DEBUG_AT( Core_Input, "dfb_input_core_suspend( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBInputCore );
+ D_MAGIC_ASSERT( data->shared, DFBInputCoreShared );
+
+ shared = data->shared;
+
+ D_DEBUG_AT( Core_Input, " -> suspending...\n" );
+
+ for (i=0; i<data->num; i++) {
+ CoreInputDevice *device = data->devices[i];
+ InputDriver *driver;
+ InputDeviceShared *devshared;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ driver = device->driver;
+ D_ASSERT( driver != NULL );
+
+ devshared = device->shared;
+ D_ASSERT( devshared != NULL );
+
+ if (device->driver_data != NULL) {
+ void *driver_data;
+
+ D_ASSERT( driver->funcs != NULL );
+ D_ASSERT( driver->funcs->CloseDevice != NULL );
+
+ D_DEBUG_AT( Core_Input, " -> closing '%s' (%d) %d.%d (%s)\n",
+ devshared->device_info.desc.name, devshared->num + 1,
+ driver->info.version.major,
+ driver->info.version.minor, driver->info.vendor );
+
+ driver_data = device->driver_data;
+ device->driver_data = NULL;
+ driver->funcs->CloseDevice( driver_data );
+ }
+
+ flush_keys( device );
+ }
+
+ D_DEBUG_AT( Core_Input, " -> suspended.\n" );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_input_core_resume( DFBInputCore *data )
+{
+ DFBInputCoreShared *shared;
+ DFBResult ret;
+ int i;
+
+ D_DEBUG_AT( Core_Input, "dfb_input_core_resume( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBInputCore );
+ D_MAGIC_ASSERT( data->shared, DFBInputCoreShared );
+
+ shared = data->shared;
+
+ D_DEBUG_AT( Core_Input, " -> resuming...\n" );
+
+ for (i=0; i<data->num; i++) {
+ CoreInputDevice *device = data->devices[i];
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_DEBUG_AT( Core_Input, " -> reopening '%s' (%d) %d.%d (%s)\n",
+ device->shared->device_info.desc.name, device->shared->num + 1,
+ device->driver->info.version.major,
+ device->driver->info.version.minor,
+ device->driver->info.vendor );
+
+ D_ASSERT( device->driver_data == NULL );
+
+ ret = device->driver->funcs->OpenDevice( device, device->shared->num,
+ &device->shared->device_info,
+ &device->driver_data );
+ if (ret) {
+ D_DERROR( ret, "DirectFB/Input: Failed reopening device "
+ "during resume (%s)!\n", device->shared->device_info.desc.name );
+ device->driver_data = NULL;
+ }
+ }
+
+ D_DEBUG_AT( Core_Input, " -> resumed.\n" );
+
+ return DFB_OK;
+}
+
+void
+dfb_input_enumerate_devices( InputDeviceCallback callback,
+ void *ctx,
+ DFBInputDeviceCapabilities caps )
+{
+ int i;
+
+ D_ASSERT( core_input != NULL );
+
+ for (i=0; i<core_local->num; i++) {
+ CoreInputDevice *device = core_local->devices[i];
+
+ DFBInputDeviceCapabilities dev_caps;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+ D_ASSERT( device->shared != NULL );
+
+ dev_caps = device->shared->device_info.desc.caps;
+
+ /* Always match if unclassified */
+ if (!dev_caps)
+ dev_caps = DICAPS_ALL;
+
+ if ((dev_caps & caps) && callback( device, ctx ) == DFENUM_CANCEL)
+ break;
+ }
+}
+
+DirectResult
+dfb_input_attach( CoreInputDevice *device,
+ ReactionFunc func,
+ void *ctx,
+ Reaction *reaction )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p, %p, %p, %p )\n", __FUNCTION__, device, func, ctx, reaction );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ return fusion_reactor_attach( device->shared->reactor, func, ctx, reaction );
+}
+
+DirectResult
+dfb_input_detach( CoreInputDevice *device,
+ Reaction *reaction )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p, %p )\n", __FUNCTION__, device, reaction );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ return fusion_reactor_detach( device->shared->reactor, reaction );
+}
+
+DirectResult
+dfb_input_attach_global( CoreInputDevice *device,
+ int index,
+ void *ctx,
+ GlobalReaction *reaction )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p, %d, %p, %p )\n", __FUNCTION__, device, index, ctx, reaction );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ return fusion_reactor_attach_global( device->shared->reactor, index, ctx, reaction );
+}
+
+DirectResult
+dfb_input_detach_global( CoreInputDevice *device,
+ GlobalReaction *reaction )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p, %p )\n", __FUNCTION__, device, reaction );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ return fusion_reactor_detach_global( device->shared->reactor, reaction );
+}
+
+const char *
+dfb_input_event_type_name( DFBInputEventType type )
+{
+ switch (type) {
+ case DIET_UNKNOWN:
+ return "UNKNOWN";
+
+ case DIET_KEYPRESS:
+ return "KEYPRESS";
+
+ case DIET_KEYRELEASE:
+ return "KEYRELEASE";
+
+ case DIET_BUTTONPRESS:
+ return "BUTTONPRESS";
+
+ case DIET_BUTTONRELEASE:
+ return "BUTTONRELEASE";
+
+ case DIET_AXISMOTION:
+ return "AXISMOTION";
+
+ default:
+ break;
+ }
+
+ return "<invalid>";
+}
+
+void
+dfb_input_dispatch( CoreInputDevice *device, DFBInputEvent *event )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p, %p )\n", __FUNCTION__, device, event );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( event != NULL );
+
+ D_ASSUME( device->shared != NULL );
+
+ /*
+ * 0. Sanity checks & debugging...
+ */
+ if (!device->shared) {
+ D_DEBUG_AT( Core_Input, " -> No shared data!\n" );
+ return;
+ }
+
+ D_ASSUME( device->shared->reactor != NULL );
+
+ if (!device->shared->reactor) {
+ D_DEBUG_AT( Core_Input, " -> No reactor!\n" );
+ return;
+ }
+
+ D_DEBUG_AT( Core_InputEvt, " -> (%02x) %s%s%s\n", event->type,
+ dfb_input_event_type_name( event->type ),
+ (event->flags & DIEF_FOLLOW) ? " [FOLLOW]" : "",
+ (event->flags & DIEF_REPEAT) ? " [REPEAT]" : "" );
+
+#if D_DEBUG_ENABLED
+ if (event->flags & DIEF_TIMESTAMP)
+ D_DEBUG_AT( Core_InputEvt, " -> TIMESTAMP %lu.%06lu\n", event->timestamp.tv_sec, event->timestamp.tv_usec );
+ if (event->flags & DIEF_AXISABS)
+ D_DEBUG_AT( Core_InputEvt, " -> AXISABS %d at %d\n", event->axis, event->axisabs );
+ if (event->flags & DIEF_AXISREL)
+ D_DEBUG_AT( Core_InputEvt, " -> AXISREL %d by %d\n", event->axis, event->axisrel );
+ if (event->flags & DIEF_KEYCODE)
+ D_DEBUG_AT( Core_InputEvt, " -> KEYCODE %d\n", event->key_code );
+ if (event->flags & DIEF_KEYID)
+ D_DEBUG_AT( Core_InputEvt, " -> KEYID 0x%04x\n", event->key_id );
+ if (event->flags & DIEF_KEYSYMBOL)
+ D_DEBUG_AT( Core_InputEvt, " -> KEYSYMBOL 0x%04x\n", event->key_symbol );
+ if (event->flags & DIEF_MODIFIERS)
+ D_DEBUG_AT( Core_InputEvt, " -> MODIFIERS 0x%04x\n", event->modifiers );
+ if (event->flags & DIEF_LOCKS)
+ D_DEBUG_AT( Core_InputEvt, " -> LOCKS 0x%04x\n", event->locks );
+ if (event->flags & DIEF_BUTTONS)
+ D_DEBUG_AT( Core_InputEvt, " -> BUTTONS 0x%04x\n", event->buttons );
+ if (event->flags & DIEF_GLOBAL)
+ D_DEBUG_AT( Core_InputEvt, " -> GLOBAL\n" );
+#endif
+
+ /*
+ * 1. Fixup event...
+ */
+ event->clazz = DFEC_INPUT;
+ event->device_id = device->shared->id;
+
+ if (!(event->flags & DIEF_TIMESTAMP)) {
+ gettimeofday( &event->timestamp, NULL );
+ event->flags |= DIEF_TIMESTAMP;
+ }
+
+ switch (event->type) {
+ case DIET_BUTTONPRESS:
+ case DIET_BUTTONRELEASE:
+ D_DEBUG_AT( Core_InputEvt, " -> BUTTON 0x%04x\n", event->button );
+
+ if (dfb_config->lefty) {
+ if (event->button == DIBI_LEFT)
+ event->button = DIBI_RIGHT;
+ else if (event->button == DIBI_RIGHT)
+ event->button = DIBI_LEFT;
+
+ D_DEBUG_AT( Core_InputEvt, " -> lefty! => 0x%04x <=\n", event->button );
+ }
+ /* fallthru */
+
+ case DIET_AXISMOTION:
+ fixup_mouse_event( device, event );
+ break;
+
+ case DIET_KEYPRESS:
+ case DIET_KEYRELEASE:
+ if (dfb_config->capslock_meta) {
+ if (device->shared->keymap.num_entries && (event->flags & DIEF_KEYCODE))
+ lookup_from_table( device, event, (DIEF_KEYID |
+ DIEF_KEYSYMBOL) & ~event->flags );
+
+ if (event->key_id == DIKI_CAPS_LOCK || event->key_symbol == DIKS_CAPS_LOCK) {
+ event->flags |= DIEF_KEYID | DIEF_KEYSYMBOL;
+ event->key_code = -1;
+ event->key_id = DIKI_META_L;
+ event->key_symbol = DIKS_META;
+ }
+ }
+
+ fixup_key_event( device, event );
+ break;
+
+ default:
+ ;
+ }
+
+#if D_DEBUG_ENABLED
+ if (event->flags & DIEF_TIMESTAMP)
+ D_DEBUG_AT( Core_InputEvt, " => TIMESTAMP %lu.%06lu\n", event->timestamp.tv_sec, event->timestamp.tv_usec );
+ if (event->flags & DIEF_AXISABS)
+ D_DEBUG_AT( Core_InputEvt, " => AXISABS %d at %d\n", event->axis, event->axisabs );
+ if (event->flags & DIEF_AXISREL)
+ D_DEBUG_AT( Core_InputEvt, " => AXISREL %d by %d\n", event->axis, event->axisrel );
+ if (event->flags & DIEF_KEYCODE)
+ D_DEBUG_AT( Core_InputEvt, " => KEYCODE %d\n", event->key_code );
+ if (event->flags & DIEF_KEYID)
+ D_DEBUG_AT( Core_InputEvt, " => KEYID 0x%04x\n", event->key_id );
+ if (event->flags & DIEF_KEYSYMBOL)
+ D_DEBUG_AT( Core_InputEvt, " => KEYSYMBOL 0x%04x\n", event->key_symbol );
+ if (event->flags & DIEF_MODIFIERS)
+ D_DEBUG_AT( Core_InputEvt, " => MODIFIERS 0x%04x\n", event->modifiers );
+ if (event->flags & DIEF_LOCKS)
+ D_DEBUG_AT( Core_InputEvt, " => LOCKS 0x%04x\n", event->locks );
+ if (event->flags & DIEF_BUTTONS)
+ D_DEBUG_AT( Core_InputEvt, " => BUTTONS 0x%04x\n", event->buttons );
+ if (event->flags & DIEF_GLOBAL)
+ D_DEBUG_AT( Core_InputEvt, " => GLOBAL\n" );
+#endif
+
+ if (core_input_filter( device, event ))
+ D_DEBUG_AT( Core_InputEvt, " ****>> FILTERED\n" );
+ else
+ fusion_reactor_dispatch( device->shared->reactor, event, true, dfb_input_globals );
+}
+
+DFBInputDeviceID
+dfb_input_device_id( const CoreInputDevice *device )
+{
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ return device->shared->id;
+}
+
+CoreInputDevice *
+dfb_input_device_at( DFBInputDeviceID id )
+{
+ int i;
+
+ D_ASSERT( core_input != NULL );
+
+ for (i=0; i<core_local->num; i++) {
+ CoreInputDevice *device = core_local->devices[i];
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ if (device->shared->id == id)
+ return device;
+ }
+
+ return NULL;
+}
+
+void
+dfb_input_device_description( const CoreInputDevice *device,
+ DFBInputDeviceDescription *desc )
+{
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ *desc = device->shared->device_info.desc;
+}
+
+DFBResult
+dfb_input_device_get_keymap_entry( CoreInputDevice *device,
+ int keycode,
+ DFBInputDeviceKeymapEntry *entry )
+{
+ DFBInputDeviceKeymapEntry *keymap_entry;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( entry != NULL );
+
+ keymap_entry = get_keymap_entry( device, keycode );
+ if (!keymap_entry)
+ return DFB_FAILURE;
+
+ *entry = *keymap_entry;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_input_device_set_keymap_entry( CoreInputDevice *device,
+ int keycode,
+ DFBInputDeviceKeymapEntry *entry )
+{
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( entry != NULL );
+
+ return set_keymap_entry( device, keycode, entry );
+}
+
+DFBResult
+dfb_input_device_load_keymap ( CoreInputDevice *device,
+ char *filename )
+{
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( filename != NULL );
+
+ return load_keymap( device, filename );
+}
+
+DFBResult
+dfb_input_device_reload_keymap( CoreInputDevice *device )
+{
+ int ret;
+ InputDeviceShared *shared;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ shared = device->shared;
+
+ D_ASSERT( shared != NULL );
+
+ D_INFO( "DirectFB/Input: Reloading keymap for '%s' [0x%02x]...\n",
+ shared->device_info.desc.name, shared->id );
+
+ if (fusion_call_execute( &shared->call, FCEF_NONE, CIDC_RELOAD_KEYMAP, NULL, &ret ))
+ return DFB_FUSION;
+
+ return ret;
+}
+
+DFBResult
+dfb_input_device_set_sensitivity( CoreInputDevice *device,
+ int sensitivity )
+{
+ int ret;
+ InputDeviceShared *shared;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ shared = device->shared;
+ D_ASSERT( shared != NULL );
+
+ if (fusion_call_execute( &shared->call, FCEF_NONE, CIDC_SET_SENSITIVITY, (void*)(long)sensitivity, &ret ))
+ return DFB_FUSION;
+
+ return ret;
+}
+
+DFBResult
+dfb_input_rescan_devices( CoreDFB *core )
+{
+ int ret;
+
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, core );
+
+ D_ASSERT( core_input != NULL );
+
+ if (fusion_call_execute( &core_input->call, FCEF_NODIRECT, CICC_RESCAN_DEVICES, NULL, &ret ))
+ return DFB_FUSION;
+
+ return ret;
+}
+
+DFBResult
+dfb_input_device_disconnected( CoreInputDevice *device )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, device );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( device->shared != NULL );
+
+ D_ASSUME( !(device->shared->state.flags & DISTATE_DISCONNECTED) );
+
+ device->shared->state.flags |= DISTATE_DISCONNECTED;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_input_device_reconnected( CoreInputDevice *device )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, device );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( device->shared != NULL );
+
+ D_ASSUME( device->shared->state.flags & DISTATE_DISCONNECTED );
+
+ device->shared->state.flags &= ~DISTATE_DISCONNECTED;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_input_device_get_state( const CoreInputDevice *device,
+ DFBInputDeviceState *ret_state )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, device );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( device->shared != NULL );
+
+ *ret_state = device->shared->state;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_input_core_attach( CoreDFB *core,
+ ReactionFunc func,
+ void *ctx,
+ Reaction *reaction )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, core );
+
+ D_ASSERT( core_input != NULL );
+
+ return fusion_reactor_attach( core_input->reactor, func, ctx, reaction );
+}
+
+DFBResult
+dfb_input_core_detach( CoreDFB *core,
+ Reaction *reaction )
+{
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, core );
+
+ D_ASSERT( core_input != NULL );
+
+ return fusion_reactor_detach( core_input->reactor, reaction );
+}
+
+/** internal **/
+
+static void
+input_add_device( CoreInputDevice *device )
+{
+ CoreInputCoreNotification notification;
+
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, device );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ if (core_input->num == MAX_INPUTDEVICES) {
+ D_ERROR( "DirectFB/Input: Maximum number of devices reached!\n" );
+ return;
+ }
+
+ core_local->devices[ core_local->num++ ] = device;
+
+ core_input->devices[ core_input->num++ ] = device->shared;
+
+ notification.flags = CICNF_NEW_DEVICE;
+ notification.device_id = device->shared->id;
+
+ fusion_reactor_dispatch( core_input->reactor, &notification, true, NULL );
+}
+
+static void
+allocate_device_keymap( CoreDFB *core, CoreInputDevice *device )
+{
+ int i;
+ DFBInputDeviceKeymapEntry *entries;
+ FusionSHMPoolShared *pool = dfb_core_shmpool( core );
+ InputDeviceShared *shared = device->shared;
+ DFBInputDeviceDescription *desc = &shared->device_info.desc;
+ int num_entries = desc->max_keycode -
+ desc->min_keycode + 1;
+
+ D_DEBUG_AT( Core_Input, "%s( %p, %p )\n", __FUNCTION__, core, device );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+
+ entries = SHCALLOC( pool, num_entries, sizeof(DFBInputDeviceKeymapEntry) );
+ if (!entries) {
+ D_OOSHM();
+ return;
+ }
+
+ /* write -1 indicating entry is not fetched yet from driver */
+ for (i=0; i<num_entries; i++)
+ entries[i].code = -1;
+
+ shared->keymap.min_keycode = desc->min_keycode;
+ shared->keymap.max_keycode = desc->max_keycode;
+ shared->keymap.num_entries = num_entries;
+ shared->keymap.entries = entries;
+
+#if FUSION_BUILD_MULTI
+ /* we need to fetch the whole map, otherwise a slave would try to */
+ for (i=desc->min_keycode; i<=desc->max_keycode; i++)
+ get_keymap_entry( device, i );
+#endif
+}
+
+static int
+make_id( DFBInputDeviceID prefered )
+{
+ int i;
+
+ D_DEBUG_AT( Core_Input, "%s( 0x%02x )\n", __FUNCTION__, prefered );
+
+ D_ASSERT( core_input != NULL );
+
+ for (i=0; i<core_local->num; i++) {
+ CoreInputDevice *device = core_local->devices[i];
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ if (device->shared->id == prefered)
+ return make_id( (prefered < DIDID_ANY) ? DIDID_ANY : (prefered + 1) );
+ }
+
+ return prefered;
+}
+
+static DFBResult
+reload_keymap( CoreInputDevice *device )
+{
+ int i;
+ InputDeviceShared *shared;
+
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, device );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ shared = device->shared;
+
+ D_ASSERT( shared != NULL );
+
+ if (shared->device_info.desc.min_keycode < 0 ||
+ shared->device_info.desc.max_keycode < 0)
+ return DFB_UNSUPPORTED;
+
+ /* write -1 indicating entry is not fetched yet from driver */
+ for (i=0; i<shared->keymap.num_entries; i++)
+ shared->keymap.entries[i].code = -1;
+
+ /* fetch the whole map */
+ for (i=shared->keymap.min_keycode; i<=shared->keymap.max_keycode; i++)
+ get_keymap_entry( device, i );
+
+ D_INFO( "DirectFB/Input: Reloaded keymap for '%s' [0x%02x]\n",
+ shared->device_info.desc.name, shared->id );
+
+ return DFB_OK;
+}
+
+static DFBResult
+set_sensitivity( CoreInputDevice *device,
+ int sensitivity )
+{
+ InputDriver *driver;
+
+ D_DEBUG_AT( Core_Input, "%s( %p, %d )\n", __FUNCTION__, device, sensitivity );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ driver = device->driver;
+ D_ASSERT( driver != NULL );
+
+ if (!driver->funcs->SetSensitivity)
+ return DFB_UNSUPPORTED;
+
+ return driver->funcs->SetSensitivity( device, device->driver_data, sensitivity );
+}
+
+static FusionCallHandlerResult
+input_device_call_handler( int caller, /* fusion id of the caller */
+ int call_arg, /* optional call parameter */
+ void *call_ptr, /* optional call parameter */
+ void *ctx, /* optional handler context */
+ unsigned int serial,
+ int *ret_val )
+{
+ CoreInputDeviceCommand command = call_arg;
+ CoreInputDevice *device = ctx;
+
+ D_DEBUG_AT( Core_Input, "%s( %d, %d, %p, %p )\n", __FUNCTION__, caller, call_arg, call_ptr, ctx );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ switch (command) {
+ case CIDC_RELOAD_KEYMAP:
+ *ret_val = reload_keymap( device );
+ break;
+
+ case CIDC_SET_SENSITIVITY:
+ *ret_val = set_sensitivity( device, (long) call_ptr );
+ break;
+
+ default:
+ D_BUG( "unknown Core Input Device Command '%d'", command );
+ *ret_val = DFB_BUG;
+ }
+
+ return FCHR_RETURN;
+}
+
+static DFBResult
+init_axes( CoreInputDevice *device )
+{
+ int i, num;
+ DFBResult ret;
+ InputDeviceShared *shared;
+ const InputDriverFuncs *funcs;
+
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, device );
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+ D_ASSERT( device->driver != NULL );
+
+ funcs = device->driver->funcs;
+ D_ASSERT( funcs != NULL );
+
+ shared = device->shared;
+ D_ASSERT( shared != NULL );
+
+ if (shared->device_info.desc.max_axis < 0)
+ return DFB_OK;
+
+ num = shared->device_info.desc.max_axis + 1;
+
+ shared->axis_info = SHCALLOC( dfb_core_shmpool(device->core), num, sizeof(DFBInputDeviceAxisInfo) );
+ if (!shared->axis_info)
+ return D_OOSHM();
+
+ shared->axis_num = num;
+
+ if (funcs->GetAxisInfo) {
+ for (i=0; i<num; i++) {
+ ret = funcs->GetAxisInfo( device, device->driver_data, i, &shared->axis_info[i] );
+ if (ret)
+ D_DERROR( ret, "Core/Input: GetAxisInfo() failed for '%s' [%d] on axis %d!\n",
+ shared->device_info.desc.name, shared->id, i );
+ }
+ }
+
+ return DFB_OK;
+}
+
+static void
+init_drivers( CoreDFB *core )
+{
+ DirectLink *next;
+ DirectModuleEntry *module;
+
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, core );
+
+ D_ASSERT( core_input != NULL );
+
+ direct_list_foreach_safe (module, next, dfb_input_modules.entries) {
+ InputDriver *driver;
+ const InputDriverFuncs *funcs;
+
+ funcs = direct_module_ref( module );
+ if (!funcs)
+ continue;
+
+ driver = D_CALLOC( 1, sizeof(InputDriver) );
+ if (!driver) {
+ D_OOM();
+ direct_module_unref( module );
+ continue;
+ }
+
+ D_ASSERT( funcs->GetDriverInfo != NULL );
+
+ funcs->GetDriverInfo( &driver->info );
+
+ driver->module = module;
+ driver->funcs = funcs;
+
+ direct_list_prepend( &core_local->drivers, &driver->link );
+ }
+}
+
+static DFBResult
+rescan_devices( CoreDFB *core )
+{
+ InputDriver *driver;
+ FusionSHMPoolShared *pool = dfb_core_shmpool( core );
+
+ D_DEBUG_AT( Core_Input, "%s( %p )\n", __FUNCTION__, core );
+
+ D_ASSERT( core_input != NULL );
+
+ direct_list_foreach (driver, core_local->drivers) {
+ int i, num;
+ const InputDriverFuncs *funcs = driver->funcs;
+
+ D_DEBUG_AT( Core_Input, " -> probing '%s'...\n", driver->info.name );
+
+ num = funcs->GetAvailable();
+
+ D_DEBUG_AT( Core_Input, " -> %d available device(s) provided by '%s'.\n", num, driver->info.name );
+
+
+ for (i=driver->nr_devices; i<num; i++) {
+ char buf[128];
+ CoreInputDevice *device;
+ InputDeviceInfo device_info;
+ InputDeviceShared *shared;
+ void *driver_data;
+
+ device = D_CALLOC( 1, sizeof(CoreInputDevice) );
+ if (!device) {
+ D_OOM();
+ continue;
+ }
+
+ shared = SHCALLOC( pool, 1, sizeof(InputDeviceShared) );
+ if (!shared) {
+ D_OOSHM();
+ D_FREE( device );
+ continue;
+ }
+
+ device->core = core;
+
+ memset( &device_info, 0, sizeof(InputDeviceInfo) );
+
+ device_info.desc.min_keycode = -1;
+ device_info.desc.max_keycode = -1;
+
+ D_MAGIC_SET( device, CoreInputDevice );
+
+ if (funcs->OpenDevice( device, i, &device_info, &driver_data )) {
+ SHFREE( pool, shared );
+ D_MAGIC_CLEAR( device );
+ D_FREE( device );
+ continue;
+ }
+
+ D_DEBUG_AT( Core_Input, " -> opened '%s' (%d) %d.%d (%s)\n",
+ device_info.desc.name, i + 1, driver->info.version.major,
+ driver->info.version.minor, driver->info.vendor );
+
+ if (num > 1)
+ snprintf( buf, sizeof(buf), "%s (%d)", device_info.desc.name, i+1 );
+ else
+ snprintf( buf, sizeof(buf), "%s", device_info.desc.name );
+
+ /* init skirmish */
+ fusion_skirmish_init( &shared->lock, buf, dfb_core_world(core) );
+
+ /* create reactor */
+ shared->reactor = fusion_reactor_new( sizeof(DFBInputEvent), buf, dfb_core_world(core) );
+
+ fusion_reactor_set_lock( shared->reactor, &shared->lock );
+
+ /* init call */
+ fusion_call_init( &shared->call, input_device_call_handler, device, dfb_core_world(core) );
+
+ /* initialize shared data */
+ shared->id = make_id(device_info.prefered_id);
+ shared->num = i;
+ shared->device_info = device_info;
+ shared->last_key = DIKI_UNKNOWN;
+ shared->first_press = true;
+
+ /* initialize local data */
+ device->shared = shared;
+ device->driver = driver;
+ device->driver_data = driver_data;
+
+ D_INFO( "DirectFB/Input: %s %d.%d (%s)\n",
+ buf, driver->info.version.major,
+ driver->info.version.minor, driver->info.vendor );
+
+ if (device_info.desc.min_keycode > device_info.desc.max_keycode) {
+ D_BUG("min_keycode > max_keycode");
+ device_info.desc.min_keycode = -1;
+ device_info.desc.max_keycode = -1;
+ }
+ else if (device_info.desc.min_keycode >= 0 &&
+ device_info.desc.max_keycode >= 0)
+ allocate_device_keymap( core, device );
+
+ init_axes( device );
+
+ /* add it to the list */
+ input_add_device( device );
+ }
+
+ driver->nr_devices = num;
+ }
+
+ return DFB_OK;
+}
+
+static DFBInputDeviceKeymapEntry *
+get_keymap_entry( CoreInputDevice *device,
+ int code )
+{
+ InputDeviceKeymap *map;
+ DFBInputDeviceKeymapEntry *entry;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ map = &device->shared->keymap;
+
+ /* safety check */
+ if (code < map->min_keycode || code > map->max_keycode)
+ return NULL;
+
+ /* point to right array index */
+ entry = &map->entries[code - map->min_keycode];
+
+ /* need to initialize? */
+ if (entry->code != code) {
+ DFBResult ret;
+ InputDriver *driver = device->driver;
+
+ if (!driver) {
+ D_BUG("seem to be a slave with an empty keymap");
+ return NULL;
+ }
+
+ /* write keycode to entry */
+ entry->code = code;
+
+ /* fetch entry from driver */
+ ret = driver->funcs->GetKeymapEntry( device,
+ device->driver_data, entry );
+ if (ret)
+ return NULL;
+
+ /* drivers may leave this blank */
+ if (entry->identifier == DIKI_UNKNOWN)
+ entry->identifier = symbol_to_id( entry->symbols[DIKSI_BASE] );
+
+ if (entry->symbols[DIKSI_BASE_SHIFT] == DIKS_NULL)
+ entry->symbols[DIKSI_BASE_SHIFT] = entry->symbols[DIKSI_BASE];
+
+ if (entry->symbols[DIKSI_ALT] == DIKS_NULL)
+ entry->symbols[DIKSI_ALT] = entry->symbols[DIKSI_BASE];
+
+ if (entry->symbols[DIKSI_ALT_SHIFT] == DIKS_NULL)
+ entry->symbols[DIKSI_ALT_SHIFT] = entry->symbols[DIKSI_ALT];
+ }
+
+ return entry;
+}
+
+/* replace a single keymap entry with the code-entry pair */
+static DFBResult
+set_keymap_entry( CoreInputDevice *device,
+ int code,
+ DFBInputDeviceKeymapEntry *entry )
+{
+ InputDeviceKeymap *map;
+
+ D_ASSERT( device->shared != NULL );
+ D_ASSERT( device->shared->keymap.entries != NULL );
+
+ map = &device->shared->keymap;
+
+ /* sanity check */
+ if (code < map->min_keycode || code > map->max_keycode)
+ return DFB_FAILURE;
+
+ /* copy the entry to the map */
+ map->entries[code - map->min_keycode] = *entry;
+
+ return DFB_OK;
+}
+
+/* replace the complete current keymap with a keymap from a file.
+ * the minimum-maximum keycodes of the driver are to be respected.
+ */
+static DFBResult
+load_keymap( CoreInputDevice *device,
+ char *filename )
+{
+ DFBResult ret = DFB_OK;
+ InputDeviceKeymap *map = 0;
+ FILE *file = 0;
+ DFBInputDeviceLockState lockstate = 0;
+
+ D_ASSERT( device->shared != NULL );
+ D_ASSERT( device->shared->keymap.entries != NULL );
+
+ map = &device->shared->keymap;
+
+ /* open the file */
+ file = fopen( filename, "r" );
+ if( !file )
+ {
+ return errno2result( errno );
+ }
+
+ /* read the file, line by line, and consume the mentioned scancodes */
+ while(1)
+ {
+ int i;
+ int dummy;
+ char buffer[201];
+ int keycode;
+ char diki[201];
+ char diks[4][201];
+ char *b;
+
+ DFBInputDeviceKeymapEntry entry = { .code = 0 };
+
+ b = fgets( buffer, 200, file );
+ if( !b ) {
+ if( feof(file) ) {
+ fclose(file);
+ return DFB_OK;
+ }
+ fclose(file);
+ return errno2result(errno);
+ }
+
+ /* comment or empty line */
+ if( buffer[0]=='#' || strcmp(buffer,"\n")==0 )
+ continue;
+
+ /* check for lock state change */
+ if( !strncmp(buffer,"capslock:",9) ) { lockstate |= DILS_CAPS; continue; }
+ if( !strncmp(buffer,":capslock",9) ) { lockstate &= ~DILS_CAPS; continue; }
+ if( !strncmp(buffer,"numlock:",8) ) { lockstate |= DILS_NUM; continue; }
+ if( !strncmp(buffer,":numlock",8) ) { lockstate &= ~DILS_NUM; continue; }
+
+ i = sscanf( buffer, " keycode %i = %s = %s %s %s %s %i\n",
+ &keycode, diki, diks[0], diks[1], diks[2], diks[3], &dummy );
+
+ if( i < 3 || i > 6 ) {
+ /* we want 1 to 4 key symbols */
+ D_INFO( "DirectFB/Input: skipped erroneous input line %s\n", buffer );
+ continue;
+ }
+
+ if( keycode > map->max_keycode || keycode < map->min_keycode ) {
+ D_INFO( "DirectFB/Input: skipped keycode %d out of range\n", keycode );
+ continue;
+ }
+
+ entry.code = keycode;
+ entry.locks = lockstate;
+ entry.identifier = lookup_keyidentifier( diki );
+
+ switch( i ) {
+ case 6: entry.symbols[3] = lookup_keysymbol( diks[3] );
+ case 5: entry.symbols[2] = lookup_keysymbol( diks[2] );
+ case 4: entry.symbols[1] = lookup_keysymbol( diks[1] );
+ case 3: entry.symbols[0] = lookup_keysymbol( diks[0] );
+
+ /* fall through */
+ }
+
+ switch( i ) {
+ case 3: entry.symbols[1] = entry.symbols[0];
+ case 4: entry.symbols[2] = entry.symbols[0];
+ case 5: entry.symbols[3] = entry.symbols[1];
+
+ /* fall through */
+ }
+
+ ret = set_keymap_entry( device, keycode, &entry );
+ if( ret )
+ return ret;
+ }
+}
+
+static DFBInputDeviceKeySymbol lookup_keysymbol( char *symbolname )
+{
+ int i;
+
+ /* we want uppercase */
+ for( i=0; i<strlen(symbolname); i++ )
+ if( symbolname[i] >= 'a' && symbolname[i] <= 'z' )
+ symbolname[i] = symbolname[i] - 'a' + 'A';
+
+ for( i=0; i < sizeof (KeySymbolNames) / sizeof (KeySymbolNames[0]); i++ ) {
+ if( strcmp( symbolname, KeySymbolNames[i].name ) == 0 )
+ return KeySymbolNames[i].symbol;
+ }
+
+ /* not found, maybe starting with 0x for raw conversion.
+ * We are already at uppercase.
+ */
+ if( symbolname[0]=='0' && symbolname[1]=='X' ) {
+ int code=0;
+ symbolname+=2;
+ while(*symbolname) {
+ if( *symbolname >= '0' && *symbolname <= '9' ) {
+ code = code*16 + *symbolname - '0';
+ } else if( *symbolname >= 'A' && *symbolname <= 'F' ) {
+ code = code*16 + *symbolname - 'A' + 10;
+ } else {
+ /* invalid character */
+ return DIKS_NULL;
+ }
+ symbolname++;
+ }
+ return code;
+ }
+
+ return DIKS_NULL;
+}
+
+static DFBInputDeviceKeyIdentifier lookup_keyidentifier( char *identifiername )
+{
+ int i;
+
+ /* we want uppercase */
+ for( i=0; i<strlen(identifiername); i++ )
+ if( identifiername[i] >= 'a' && identifiername[i] <= 'z' )
+ identifiername[i] = identifiername[i] - 'a' + 'A';
+
+ for( i=0; i < sizeof (KeyIdentifierNames) / sizeof (KeyIdentifierNames[0]); i++ ) {
+ if( strcmp( identifiername, KeyIdentifierNames[i].name ) == 0 )
+ return KeyIdentifierNames[i].identifier;
+ }
+
+ return DIKI_UNKNOWN;
+}
+
+static bool
+lookup_from_table( CoreInputDevice *device,
+ DFBInputEvent *event,
+ DFBInputEventFlags lookup )
+{
+ DFBInputDeviceKeymapEntry *entry;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+ D_ASSERT( event != NULL );
+
+ /* fetch the entry from the keymap, possibly calling the driver */
+ entry = get_keymap_entry( device, event->key_code );
+ if (!entry)
+ return false;
+
+ /* lookup identifier */
+ if (lookup & DIEF_KEYID)
+ event->key_id = entry->identifier;
+
+ /* lookup symbol */
+ if (lookup & DIEF_KEYSYMBOL) {
+ DFBInputDeviceKeymapSymbolIndex index =
+ (event->modifiers & DIMM_ALTGR) ? DIKSI_ALT : DIKSI_BASE;
+
+ if (!(event->modifiers & DIMM_SHIFT) ^ !(entry->locks & event->locks))
+ index++;
+
+ /* don't modify modifiers */
+ if (DFB_KEY_TYPE( entry->symbols[DIKSI_BASE] ) == DIKT_MODIFIER)
+ event->key_symbol = entry->symbols[DIKSI_BASE];
+ else
+ event->key_symbol = entry->symbols[index];
+ }
+
+ return true;
+}
+
+static int
+find_key_code_by_id( CoreInputDevice *device,
+ DFBInputDeviceKeyIdentifier id )
+{
+ int i;
+ InputDeviceKeymap *map;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ map = &device->shared->keymap;
+
+ for (i=0; i<map->num_entries; i++) {
+ DFBInputDeviceKeymapEntry *entry = &map->entries[i];
+
+ if (entry->identifier == id)
+ return entry->code;
+ }
+
+ return -1;
+}
+
+static int
+find_key_code_by_symbol( CoreInputDevice *device,
+ DFBInputDeviceKeySymbol symbol )
+{
+ int i;
+ InputDeviceKeymap *map;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ D_ASSERT( core_input != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( device->shared != NULL );
+
+ map = &device->shared->keymap;
+
+ for (i=0; i<map->num_entries; i++) {
+ int n;
+ DFBInputDeviceKeymapEntry *entry = &map->entries[i];
+
+ for (n=0; n<=DIKSI_LAST; n++)
+ if (entry->symbols[n] == symbol)
+ return entry->code;
+ }
+
+ return -1;
+}
+
+#define FIXUP_KEY_FIELDS (DIEF_MODIFIERS | DIEF_LOCKS | \
+ DIEF_KEYCODE | DIEF_KEYID | DIEF_KEYSYMBOL)
+
+/*
+ * Fill partially missing values for key_code, key_id and key_symbol by
+ * translating those that are set. Fix modifiers/locks before if not set.
+ *
+ *
+ * There are five valid constellations that give reasonable values.
+ * (not counting the constellation where everything is set)
+ *
+ * Device has no translation table
+ * 1. key_id is set, key_symbol not
+ * -> key_code defaults to -1, key_symbol from key_id (up-translation)
+ * 2. key_symbol is set, key_id not
+ * -> key_code defaults to -1, key_id from key_symbol (down-translation)
+ *
+ * Device has a translation table
+ * 3. key_code is set
+ * -> look up key_id and/or key_symbol (key_code being the index)
+ * 4. key_id is set
+ * -> look up key_code and possibly key_symbol (key_id being searched for)
+ * 5. key_symbol is set
+ * -> look up key_code and key_id (key_symbol being searched for)
+ *
+ * Fields remaining will be set to the default, e.g. key_code to -1.
+ */
+static void
+fixup_key_event( CoreInputDevice *device, DFBInputEvent *event )
+{
+ int i;
+ DFBInputEventFlags valid = event->flags & FIXUP_KEY_FIELDS;
+ DFBInputEventFlags missing = valid ^ FIXUP_KEY_FIELDS;
+ InputDeviceShared *shared = device->shared;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ /* Add missing flags */
+ event->flags |= missing;
+
+ /*
+ * Use cached values for modifiers/locks if they are missing.
+ */
+ if (missing & DIEF_MODIFIERS)
+ event->modifiers = shared->modifiers_l | shared->modifiers_r;
+
+ if (missing & DIEF_LOCKS)
+ event->locks = shared->locks;
+
+ /*
+ * With translation table
+ */
+ if (device->shared->keymap.num_entries) {
+ if (valid & DIEF_KEYCODE) {
+ lookup_from_table( device, event, missing );
+
+ missing &= ~(DIEF_KEYID | DIEF_KEYSYMBOL);
+ }
+ else if (valid & DIEF_KEYID) {
+ event->key_code = find_key_code_by_id( device, event->key_id );
+
+ if (event->key_code != -1) {
+ lookup_from_table( device, event, missing );
+
+ missing &= ~(DIEF_KEYCODE | DIEF_KEYSYMBOL);
+ }
+ else if (missing & DIEF_KEYSYMBOL) {
+ event->key_symbol = id_to_symbol( event->key_id,
+ event->modifiers,
+ event->locks );
+ missing &= ~DIEF_KEYSYMBOL;
+ }
+ }
+ else if (valid & DIEF_KEYSYMBOL) {
+ event->key_code = find_key_code_by_symbol( device,
+ event->key_symbol );
+
+ if (event->key_code != -1) {
+ lookup_from_table( device, event, missing );
+
+ missing &= ~(DIEF_KEYCODE | DIEF_KEYID);
+ }
+ else {
+ event->key_symbol = symbol_to_id( event->key_symbol );
+ missing &= ~DIEF_KEYSYMBOL;
+ }
+ }
+ }
+ else {
+ /*
+ * Without translation table
+ */
+ if (valid & DIEF_KEYID) {
+ if (missing & DIEF_KEYSYMBOL) {
+ event->key_symbol = id_to_symbol( event->key_id,
+ event->modifiers,
+ event->locks );
+ missing &= ~DIEF_KEYSYMBOL;
+ }
+ }
+ else if (valid & DIEF_KEYSYMBOL) {
+ event->key_id = symbol_to_id( event->key_symbol );
+ missing &= ~DIEF_KEYID;
+ }
+ }
+
+ /*
+ * Clear remaining fields.
+ */
+ if (missing & DIEF_KEYCODE)
+ event->key_code = -1;
+
+ if (missing & DIEF_KEYID)
+ event->key_id = DIKI_UNKNOWN;
+
+ if (missing & DIEF_KEYSYMBOL)
+ event->key_symbol = DIKS_NULL;
+
+ /*
+ * Update cached values for modifiers.
+ */
+ if (DFB_KEY_TYPE(event->key_symbol) == DIKT_MODIFIER) {
+ if (event->type == DIET_KEYPRESS) {
+ switch (event->key_id) {
+ case DIKI_SHIFT_L:
+ shared->modifiers_l |= DIMM_SHIFT;
+ break;
+ case DIKI_SHIFT_R:
+ shared->modifiers_r |= DIMM_SHIFT;
+ break;
+ case DIKI_CONTROL_L:
+ shared->modifiers_l |= DIMM_CONTROL;
+ break;
+ case DIKI_CONTROL_R:
+ shared->modifiers_r |= DIMM_CONTROL;
+ break;
+ case DIKI_ALT_L:
+ shared->modifiers_l |= DIMM_ALT;
+ break;
+ case DIKI_ALT_R:
+ shared->modifiers_r |= (event->key_symbol == DIKS_ALTGR) ? DIMM_ALTGR : DIMM_ALT;
+ break;
+ case DIKI_META_L:
+ shared->modifiers_l |= DIMM_META;
+ break;
+ case DIKI_META_R:
+ shared->modifiers_r |= DIMM_META;
+ break;
+ case DIKI_SUPER_L:
+ shared->modifiers_l |= DIMM_SUPER;
+ break;
+ case DIKI_SUPER_R:
+ shared->modifiers_r |= DIMM_SUPER;
+ break;
+ case DIKI_HYPER_L:
+ shared->modifiers_l |= DIMM_HYPER;
+ break;
+ case DIKI_HYPER_R:
+ shared->modifiers_r |= DIMM_HYPER;
+ break;
+ default:
+ ;
+ }
+ }
+ else {
+ switch (event->key_id) {
+ case DIKI_SHIFT_L:
+ shared->modifiers_l &= ~DIMM_SHIFT;
+ break;
+ case DIKI_SHIFT_R:
+ shared->modifiers_r &= ~DIMM_SHIFT;
+ break;
+ case DIKI_CONTROL_L:
+ shared->modifiers_l &= ~DIMM_CONTROL;
+ break;
+ case DIKI_CONTROL_R:
+ shared->modifiers_r &= ~DIMM_CONTROL;
+ break;
+ case DIKI_ALT_L:
+ shared->modifiers_l &= ~DIMM_ALT;
+ break;
+ case DIKI_ALT_R:
+ shared->modifiers_r &= (event->key_symbol == DIKS_ALTGR) ? ~DIMM_ALTGR : ~DIMM_ALT;
+ break;
+ case DIKI_META_L:
+ shared->modifiers_l &= ~DIMM_META;
+ break;
+ case DIKI_META_R:
+ shared->modifiers_r &= ~DIMM_META;
+ break;
+ case DIKI_SUPER_L:
+ shared->modifiers_l &= ~DIMM_SUPER;
+ break;
+ case DIKI_SUPER_R:
+ shared->modifiers_r &= ~DIMM_SUPER;
+ break;
+ case DIKI_HYPER_L:
+ shared->modifiers_l &= ~DIMM_HYPER;
+ break;
+ case DIKI_HYPER_R:
+ shared->modifiers_r &= ~DIMM_HYPER;
+ break;
+ default:
+ ;
+ }
+ }
+
+ /* write back to event */
+ if (missing & DIEF_MODIFIERS)
+ event->modifiers = shared->modifiers_l | shared->modifiers_r;
+ }
+
+ /*
+ * Update cached values for locks.
+ */
+ if (event->type == DIET_KEYPRESS) {
+
+ /* When we receive a new key press, toggle lock flags */
+ if (shared->first_press || shared->last_key != event->key_id) {
+ switch (event->key_id) {
+ case DIKI_CAPS_LOCK:
+ shared->locks ^= DILS_CAPS;
+ break;
+ case DIKI_NUM_LOCK:
+ shared->locks ^= DILS_NUM;
+ break;
+ case DIKI_SCROLL_LOCK:
+ shared->locks ^= DILS_SCROLL;
+ break;
+ default:
+ ;
+ }
+ }
+
+ /* write back to event */
+ if (missing & DIEF_LOCKS)
+ event->locks = shared->locks;
+
+ /* store last pressed key */
+ shared->last_key = event->key_id;
+ shared->first_press = false;
+ }
+ else if (event->type == DIET_KEYRELEASE) {
+
+ shared->first_press = true;
+ }
+
+ /* Handle dead keys. */
+ if (DFB_KEY_TYPE(shared->last_symbol) == DIKT_DEAD) {
+ for (i=0; i<D_ARRAY_SIZE(deadkey_maps); i++) {
+ const DeadKeyMap *map = &deadkey_maps[i];
+
+ if (map->deadkey == shared->last_symbol) {
+ for (i=0; map->combos[i].target; i++) {
+ if (map->combos[i].target == event->key_symbol) {
+ event->key_symbol = map->combos[i].result;
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ if (event->type == DIET_KEYRELEASE &&
+ DFB_KEY_TYPE(event->key_symbol) != DIKT_MODIFIER)
+ shared->last_symbol = event->key_symbol;
+ }
+ else
+ shared->last_symbol = event->key_symbol;
+}
+
+static void
+fixup_mouse_event( CoreInputDevice *device, DFBInputEvent *event )
+{
+ InputDeviceShared *shared = device->shared;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ if (event->flags & DIEF_BUTTONS) {
+ shared->buttons = event->buttons;
+ }
+ else {
+ switch (event->type) {
+ case DIET_BUTTONPRESS:
+ shared->buttons |= (1 << event->button);
+ break;
+ case DIET_BUTTONRELEASE:
+ shared->buttons &= ~(1 << event->button);
+ break;
+ default:
+ ;
+ }
+
+ /* Add missing flag */
+ event->flags |= DIEF_BUTTONS;
+
+ event->buttons = shared->buttons;
+ }
+
+ switch (event->type) {
+ case DIET_AXISMOTION:
+ if ((event->flags & DIEF_AXISABS) && event->axis >= 0 && event->axis < shared->axis_num) {
+ if (!(event->flags & DIEF_MIN) && (shared->axis_info[event->axis].flags & DIAIF_ABS_MIN)) {
+ event->min = shared->axis_info[event->axis].abs_min;
+
+ event->flags |= DIEF_MIN;
+ }
+
+ if (!(event->flags & DIEF_MAX) && (shared->axis_info[event->axis].flags & DIAIF_ABS_MAX)) {
+ event->max = shared->axis_info[event->axis].abs_max;
+
+ event->flags |= DIEF_MAX;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static DFBInputDeviceKeyIdentifier
+symbol_to_id( DFBInputDeviceKeySymbol symbol )
+{
+ if (symbol >= 'a' && symbol <= 'z')
+ return DIKI_A + symbol - 'a';
+
+ if (symbol >= 'A' && symbol <= 'Z')
+ return DIKI_A + symbol - 'A';
+
+ if (symbol >= '0' && symbol <= '9')
+ return DIKI_0 + symbol - '0';
+
+ if (symbol >= DIKS_F1 && symbol <= DIKS_F12)
+ return DIKI_F1 + symbol - DIKS_F1;
+
+ switch (symbol) {
+ case DIKS_ESCAPE:
+ return DIKI_ESCAPE;
+
+ case DIKS_CURSOR_LEFT:
+ return DIKI_LEFT;
+
+ case DIKS_CURSOR_RIGHT:
+ return DIKI_RIGHT;
+
+ case DIKS_CURSOR_UP:
+ return DIKI_UP;
+
+ case DIKS_CURSOR_DOWN:
+ return DIKI_DOWN;
+
+ case DIKS_ALTGR:
+ return DIKI_ALT_R;
+
+ case DIKS_CONTROL:
+ return DIKI_CONTROL_L;
+
+ case DIKS_SHIFT:
+ return DIKI_SHIFT_L;
+
+ case DIKS_ALT:
+ return DIKI_ALT_L;
+
+ case DIKS_META:
+ return DIKI_META_L;
+
+ case DIKS_SUPER:
+ return DIKI_SUPER_L;
+
+ case DIKS_HYPER:
+ return DIKI_HYPER_L;
+
+ case DIKS_TAB:
+ return DIKI_TAB;
+
+ case DIKS_ENTER:
+ return DIKI_ENTER;
+
+ case DIKS_SPACE:
+ return DIKI_SPACE;
+
+ case DIKS_BACKSPACE:
+ return DIKI_BACKSPACE;
+
+ case DIKS_INSERT:
+ return DIKI_INSERT;
+
+ case DIKS_DELETE:
+ return DIKI_DELETE;
+
+ case DIKS_HOME:
+ return DIKI_HOME;
+
+ case DIKS_END:
+ return DIKI_END;
+
+ case DIKS_PAGE_UP:
+ return DIKI_PAGE_UP;
+
+ case DIKS_PAGE_DOWN:
+ return DIKI_PAGE_DOWN;
+
+ case DIKS_CAPS_LOCK:
+ return DIKI_CAPS_LOCK;
+
+ case DIKS_NUM_LOCK:
+ return DIKI_NUM_LOCK;
+
+ case DIKS_SCROLL_LOCK:
+ return DIKI_SCROLL_LOCK;
+
+ case DIKS_PRINT:
+ return DIKI_PRINT;
+
+ case DIKS_PAUSE:
+ return DIKI_PAUSE;
+
+ case DIKS_BACKSLASH:
+ return DIKI_BACKSLASH;
+
+ case DIKS_PERIOD:
+ return DIKI_PERIOD;
+
+ case DIKS_COMMA:
+ return DIKI_COMMA;
+
+ default:
+ ;
+ }
+
+ return DIKI_UNKNOWN;
+}
+
+static DFBInputDeviceKeySymbol
+id_to_symbol( DFBInputDeviceKeyIdentifier id,
+ DFBInputDeviceModifierMask modifiers,
+ DFBInputDeviceLockState locks )
+{
+ bool shift = !(modifiers & DIMM_SHIFT) ^ !(locks & DILS_CAPS);
+
+ if (id >= DIKI_A && id <= DIKI_Z)
+ return (shift ? DIKS_CAPITAL_A : DIKS_SMALL_A) + id - DIKI_A;
+
+ if (id >= DIKI_0 && id <= DIKI_9)
+ return DIKS_0 + id - DIKI_0;
+
+ if (id >= DIKI_KP_0 && id <= DIKI_KP_9)
+ return DIKS_0 + id - DIKI_KP_0;
+
+ if (id >= DIKI_F1 && id <= DIKI_F12)
+ return DIKS_F1 + id - DIKI_F1;
+
+ switch (id) {
+ case DIKI_ESCAPE:
+ return DIKS_ESCAPE;
+
+ case DIKI_LEFT:
+ return DIKS_CURSOR_LEFT;
+
+ case DIKI_RIGHT:
+ return DIKS_CURSOR_RIGHT;
+
+ case DIKI_UP:
+ return DIKS_CURSOR_UP;
+
+ case DIKI_DOWN:
+ return DIKS_CURSOR_DOWN;
+
+ case DIKI_CONTROL_L:
+ case DIKI_CONTROL_R:
+ return DIKS_CONTROL;
+
+ case DIKI_SHIFT_L:
+ case DIKI_SHIFT_R:
+ return DIKS_SHIFT;
+
+ case DIKI_ALT_L:
+ case DIKI_ALT_R:
+ return DIKS_ALT;
+
+ case DIKI_META_L:
+ case DIKI_META_R:
+ return DIKS_META;
+
+ case DIKI_SUPER_L:
+ case DIKI_SUPER_R:
+ return DIKS_SUPER;
+
+ case DIKI_HYPER_L:
+ case DIKI_HYPER_R:
+ return DIKS_HYPER;
+
+ case DIKI_TAB:
+ return DIKS_TAB;
+
+ case DIKI_ENTER:
+ return DIKS_ENTER;
+
+ case DIKI_SPACE:
+ return DIKS_SPACE;
+
+ case DIKI_BACKSPACE:
+ return DIKS_BACKSPACE;
+
+ case DIKI_INSERT:
+ return DIKS_INSERT;
+
+ case DIKI_DELETE:
+ return DIKS_DELETE;
+
+ case DIKI_HOME:
+ return DIKS_HOME;
+
+ case DIKI_END:
+ return DIKS_END;
+
+ case DIKI_PAGE_UP:
+ return DIKS_PAGE_UP;
+
+ case DIKI_PAGE_DOWN:
+ return DIKS_PAGE_DOWN;
+
+ case DIKI_CAPS_LOCK:
+ return DIKS_CAPS_LOCK;
+
+ case DIKI_NUM_LOCK:
+ return DIKS_NUM_LOCK;
+
+ case DIKI_SCROLL_LOCK:
+ return DIKS_SCROLL_LOCK;
+
+ case DIKI_PRINT:
+ return DIKS_PRINT;
+
+ case DIKI_PAUSE:
+ return DIKS_PAUSE;
+
+ case DIKI_KP_DIV:
+ return DIKS_SLASH;
+
+ case DIKI_KP_MULT:
+ return DIKS_ASTERISK;
+
+ case DIKI_KP_MINUS:
+ return DIKS_MINUS_SIGN;
+
+ case DIKI_KP_PLUS:
+ return DIKS_PLUS_SIGN;
+
+ case DIKI_KP_ENTER:
+ return DIKS_ENTER;
+
+ case DIKI_KP_SPACE:
+ return DIKS_SPACE;
+
+ case DIKI_KP_TAB:
+ return DIKS_TAB;
+
+ case DIKI_KP_EQUAL:
+ return DIKS_EQUALS_SIGN;
+
+ case DIKI_KP_DECIMAL:
+ return DIKS_PERIOD;
+
+ case DIKI_KP_SEPARATOR:
+ return DIKS_COMMA;
+
+ case DIKI_BACKSLASH:
+ return DIKS_BACKSLASH;
+
+ case DIKI_EQUALS_SIGN:
+ return DIKS_EQUALS_SIGN;
+
+ case DIKI_LESS_SIGN:
+ return DIKS_LESS_THAN_SIGN;
+
+ case DIKI_MINUS_SIGN:
+ return DIKS_MINUS_SIGN;
+
+ case DIKI_PERIOD:
+ return DIKS_PERIOD;
+
+ case DIKI_QUOTE_LEFT:
+ case DIKI_QUOTE_RIGHT:
+ return DIKS_QUOTATION;
+
+ case DIKI_SEMICOLON:
+ return DIKS_SEMICOLON;
+
+ case DIKI_SLASH:
+ return DIKS_SLASH;
+
+ default:
+ ;
+ }
+
+ return DIKS_NULL;
+}
+
+static void
+release_key( CoreInputDevice *device, DFBInputDeviceKeyIdentifier id )
+{
+ DFBInputEvent evt;
+
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ evt.type = DIET_KEYRELEASE;
+
+ if (DFB_KEY_TYPE(id) == DIKT_IDENTIFIER) {
+ evt.flags = DIEF_KEYID;
+ evt.key_id = id;
+ }
+ else {
+ evt.flags = DIEF_KEYSYMBOL;
+ evt.key_symbol = id;
+ }
+
+ dfb_input_dispatch( device, &evt );
+}
+
+static void
+flush_keys( CoreInputDevice *device )
+{
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ if (device->shared->modifiers_l) {
+ if (device->shared->modifiers_l & DIMM_ALT)
+ release_key( device, DIKI_ALT_L );
+
+ if (device->shared->modifiers_l & DIMM_CONTROL)
+ release_key( device, DIKI_CONTROL_L );
+
+ if (device->shared->modifiers_l & DIMM_HYPER)
+ release_key( device, DIKI_HYPER_L );
+
+ if (device->shared->modifiers_l & DIMM_META)
+ release_key( device, DIKI_META_L );
+
+ if (device->shared->modifiers_l & DIMM_SHIFT)
+ release_key( device, DIKI_SHIFT_L );
+
+ if (device->shared->modifiers_l & DIMM_SUPER)
+ release_key( device, DIKI_SUPER_L );
+ }
+
+ if (device->shared->modifiers_r) {
+ if (device->shared->modifiers_r & DIMM_ALTGR)
+ release_key( device, DIKS_ALTGR );
+
+ if (device->shared->modifiers_r & DIMM_ALT)
+ release_key( device, DIKI_ALT_R );
+
+ if (device->shared->modifiers_r & DIMM_CONTROL)
+ release_key( device, DIKI_CONTROL_R );
+
+ if (device->shared->modifiers_r & DIMM_HYPER)
+ release_key( device, DIKI_HYPER_R );
+
+ if (device->shared->modifiers_r & DIMM_META)
+ release_key( device, DIKI_META_R );
+
+ if (device->shared->modifiers_r & DIMM_SHIFT)
+ release_key( device, DIKI_SHIFT_R );
+
+ if (device->shared->modifiers_r & DIMM_SUPER)
+ release_key( device, DIKI_SUPER_R );
+ }
+}
+
+static void
+dump_primary_layer_surface( CoreDFB *core )
+{
+ CoreLayer *layer = dfb_layer_at( DLID_PRIMARY );
+ CoreLayerContext *context;
+
+ /* Get the currently active context. */
+ if (dfb_layer_get_active_context( layer, &context ) == DFB_OK) {
+ CoreLayerRegion *region;
+
+ /* Get the first region. */
+ if (dfb_layer_context_get_primary_region( context,
+ false, &region ) == DFB_OK)
+ {
+ CoreSurface *surface;
+
+ /* Lock the region to avoid tearing due to concurrent updates. */
+ dfb_layer_region_lock( region );
+
+ /* Get the surface of the region. */
+ if (dfb_layer_region_get_surface( region, &surface ) == DFB_OK) {
+ /* Dump the surface contents. */
+ dfb_surface_dump_buffer( surface, CSBR_FRONT, dfb_config->screenshot_dir, "dfb" );
+
+ /* Release the surface. */
+ dfb_surface_unref( surface );
+ }
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ /* Release the region. */
+ dfb_layer_region_unref( region );
+ }
+
+ /* Release the context. */
+ dfb_layer_context_unref( context );
+ }
+}
+
+static bool
+core_input_filter( CoreInputDevice *device, DFBInputEvent *event )
+{
+ D_MAGIC_ASSERT( device, CoreInputDevice );
+
+ if (dfb_system_input_filter( device, event ))
+ return true;
+
+ if (event->type == DIET_KEYPRESS) {
+ switch (event->key_symbol) {
+ case DIKS_PRINT:
+ if (!event->modifiers && dfb_config->screenshot_dir) {
+ dump_primary_layer_surface( device->core );
+ return true;
+ }
+ break;
+
+ case DIKS_BACKSPACE:
+ if (event->modifiers == DIMM_META)
+ direct_trace_print_stacks();
+
+ break;
+
+ case DIKS_ESCAPE:
+ if (event->modifiers == DIMM_META) {
+#if FUSION_BUILD_MULTI
+ DFBResult ret;
+ CoreLayer *layer = dfb_layer_at( DLID_PRIMARY );
+ CoreLayerContext *context;
+
+ /* Get primary (shared) context. */
+ ret = dfb_layer_get_primary_context( layer,
+ false, &context );
+ if (ret)
+ return false;
+
+ /* Activate the context. */
+ dfb_layer_activate_context( layer, context );
+
+ /* Release the context. */
+ dfb_layer_context_unref( context );
+
+#else
+ kill( 0, SIGINT );
+#endif
+
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
diff --git a/Source/DirectFB/src/core/input.h b/Source/DirectFB/src/core/input.h
new file mode 100755
index 0000000..0e21e2c
--- /dev/null
+++ b/Source/DirectFB/src/core/input.h
@@ -0,0 +1,203 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __INPUT_H__
+#define __INPUT_H__
+
+#include <pthread.h>
+#include <directfb.h>
+
+#include <direct/modules.h>
+
+#include <fusion/reactor.h>
+
+#include <core/coretypes.h>
+
+
+
+DECLARE_MODULE_DIRECTORY( dfb_input_modules );
+
+
+/*
+ * Increase this number when changes result in binary incompatibility!
+ */
+#define DFB_INPUT_DRIVER_ABI_VERSION 7
+
+#define DFB_INPUT_DRIVER_INFO_NAME_LENGTH 48
+#define DFB_INPUT_DRIVER_INFO_VENDOR_LENGTH 64
+
+
+typedef struct {
+ int major; /* major version */
+ int minor; /* minor version */
+} InputDriverVersion; /* major.minor, e.g. 0.1 */
+
+typedef struct {
+ InputDriverVersion version;
+
+ char name[DFB_INPUT_DRIVER_INFO_NAME_LENGTH];
+ /* Name of driver,
+ e.g. 'Serial Mouse Driver' */
+
+ char vendor[DFB_INPUT_DRIVER_INFO_VENDOR_LENGTH];
+ /* Vendor (or author) of the driver,
+ e.g. 'directfb.org' or 'Sven Neumann' */
+} InputDriverInfo;
+
+typedef struct {
+ unsigned int prefered_id; /* Prefered predefined input device id,
+ e.g. DIDID_MOUSE */
+
+ DFBInputDeviceDescription desc; /* Capabilities, type, etc. */
+ DFBInputDeviceState state;
+} InputDeviceInfo;
+
+typedef struct {
+ int (*GetAvailable) (void);
+ void (*GetDriverInfo) (InputDriverInfo *driver_info);
+ DFBResult (*OpenDevice) (CoreInputDevice *device,
+ unsigned int number,
+ InputDeviceInfo *device_info,
+ void **driver_data);
+ DFBResult (*GetKeymapEntry) (CoreInputDevice *device,
+ void *driver_data,
+ DFBInputDeviceKeymapEntry *entry);
+ void (*CloseDevice) (void *driver_data);
+
+ DFBResult (*GetAxisInfo) (CoreInputDevice *device,
+ void *driver_data,
+ DFBInputDeviceAxisIdentifier axis,
+ DFBInputDeviceAxisInfo *ret_info);
+
+ DFBResult (*SetSensitivity) (CoreInputDevice *device,
+ void *driver_data,
+ int sensitivity );
+} InputDriverFuncs;
+
+
+typedef DFBEnumerationResult (*InputDeviceCallback) (CoreInputDevice *device,
+ void *ctx);
+
+void dfb_input_enumerate_devices( InputDeviceCallback callback,
+ void *ctx,
+ DFBInputDeviceCapabilities caps );
+
+
+DirectResult dfb_input_attach ( CoreInputDevice *device,
+ ReactionFunc func,
+ void *ctx,
+ Reaction *reaction );
+
+DirectResult dfb_input_detach ( CoreInputDevice *device,
+ Reaction *reaction );
+
+DirectResult dfb_input_attach_global( CoreInputDevice *device,
+ int index,
+ void *ctx,
+ GlobalReaction *reaction );
+
+DirectResult dfb_input_detach_global( CoreInputDevice *device,
+ GlobalReaction *reaction );
+
+
+DFBResult dfb_input_add_global ( ReactionFunc func,
+ int *ret_index );
+
+DFBResult dfb_input_set_global ( ReactionFunc func,
+ int index );
+
+
+void dfb_input_dispatch ( CoreInputDevice *device,
+ DFBInputEvent *event );
+
+
+
+void dfb_input_device_description( const CoreInputDevice *device,
+ DFBInputDeviceDescription *desc );
+
+DFBInputDeviceID dfb_input_device_id ( const CoreInputDevice *device );
+
+CoreInputDevice *dfb_input_device_at ( DFBInputDeviceID id );
+
+
+
+DFBResult dfb_input_device_get_keymap_entry( CoreInputDevice *device,
+ int keycode,
+ DFBInputDeviceKeymapEntry *entry );
+
+DFBResult dfb_input_device_set_keymap_entry( CoreInputDevice *device,
+ int keycode,
+ DFBInputDeviceKeymapEntry *entry );
+
+DFBResult dfb_input_device_load_keymap ( CoreInputDevice *device,
+ char *filename );
+
+DFBResult dfb_input_device_reload_keymap ( CoreInputDevice *device );
+
+DFBResult dfb_input_device_set_sensitivity( CoreInputDevice *device,
+ int sensitivity );
+
+DFBResult dfb_input_rescan_devices( CoreDFB *core );
+
+DFBResult dfb_input_device_disconnected( CoreInputDevice *device );
+DFBResult dfb_input_device_reconnected ( CoreInputDevice *device );
+
+DFBResult dfb_input_device_get_state( const CoreInputDevice *device,
+ DFBInputDeviceState *ret_state );
+
+
+
+typedef enum {
+ CICNF_NONE = 0x00000000,
+
+ CICNF_NEW_DEVICE = 0x00000001,
+
+ CICNF_ALL = 0x00000001,
+} CoreInputCoreNotificationFlags;
+
+typedef struct {
+ CoreInputCoreNotificationFlags flags;
+
+ DFBInputDeviceID device_id;
+} CoreInputCoreNotification;
+
+
+DFBResult dfb_input_core_attach( CoreDFB *core,
+ ReactionFunc func,
+ void *ctx,
+ Reaction *reaction );
+
+DFBResult dfb_input_core_detach( CoreDFB *core,
+ Reaction *reaction );
+/* global reactions */
+
+typedef enum {
+ DFB_WINDOWSTACK_INPUTDEVICE_LISTENER
+} DFB_INPUT_GLOBALS;
+
+#endif
diff --git a/Source/DirectFB/src/core/input_driver.h b/Source/DirectFB/src/core/input_driver.h
new file mode 100755
index 0000000..41c4e0e
--- /dev/null
+++ b/Source/DirectFB/src/core/input_driver.h
@@ -0,0 +1,103 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __INPUT_DRIVER_H__
+#define __INPUT_DRIVER_H__
+
+#include <core/input.h>
+
+
+static int
+driver_get_available( void );
+
+static void
+driver_get_info( InputDriverInfo *info );
+
+static DFBResult
+driver_open_device( CoreInputDevice *device,
+ unsigned int number,
+ InputDeviceInfo *info,
+ void **driver_data );
+
+static DFBResult
+driver_get_keymap_entry( CoreInputDevice *device,
+ void *driver_data,
+ DFBInputDeviceKeymapEntry *entry );
+
+#ifdef DFB_INPUTDRIVER_HAS_AXIS_INFO
+static DFBResult
+driver_get_axis_info( CoreInputDevice *device,
+ void *driver_data,
+ DFBInputDeviceAxisIdentifier axis,
+ DFBInputDeviceAxisInfo *ret_info );
+#endif
+
+static void
+driver_close_device( void *driver_data );
+
+#ifdef DFB_INPUTDRIVER_HAS_SENSITIVITY
+static DFBResult
+driver_set_sensitivity( CoreInputDevice *device,
+ void *driver_data,
+ int sensitivity );
+#endif
+
+static const InputDriverFuncs driver_funcs = {
+ .GetAvailable = driver_get_available,
+ .GetDriverInfo = driver_get_info,
+ .OpenDevice = driver_open_device,
+ .GetKeymapEntry = driver_get_keymap_entry,
+ .CloseDevice = driver_close_device,
+
+#ifdef DFB_INPUTDRIVER_HAS_AXIS_INFO
+ .GetAxisInfo = driver_get_axis_info,
+#endif
+
+#ifdef DFB_INPUTDRIVER_HAS_SENSITIVITY
+ .SetSensitivity = driver_set_sensitivity,
+#endif
+};
+
+#define DFB_INPUT_DRIVER(shortname) \
+__attribute__((constructor)) void directfb_##shortname##_ctor( void ); \
+__attribute__((destructor)) void directfb_##shortname##_dtor( void ); \
+ \
+void \
+directfb_##shortname##_ctor( void ) \
+{ \
+ direct_modules_register( &dfb_input_modules, DFB_INPUT_DRIVER_ABI_VERSION, \
+ #shortname, &driver_funcs ); \
+} \
+ \
+void \
+directfb_##shortname##_dtor( void ) \
+{ \
+ direct_modules_unregister( &dfb_input_modules, #shortname ); \
+}
+
+#endif
diff --git a/Source/DirectFB/src/core/layer_context.c b/Source/DirectFB/src/core/layer_context.c
new file mode 100755
index 0000000..1dcccc8
--- /dev/null
+++ b/Source/DirectFB/src/core/layer_context.c
@@ -0,0 +1,1947 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <string.h>
+
+#include <directfb.h>
+
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/core.h>
+#include <core/layer_context.h>
+#include <core/layer_control.h>
+#include <core/layer_region.h>
+#include <core/screen.h>
+#include <core/surface.h>
+#include <core/system.h>
+#include <core/windows.h>
+#include <core/windowstack.h>
+#include <core/wm.h>
+
+#include <core/layers_internal.h>
+#include <core/windows_internal.h>
+
+#include <fusion/shmalloc.h>
+
+
+D_DEBUG_DOMAIN( Core_LayerContext, "Core/LayerContext", "DirectFB Display Layer Context" );
+
+/**********************************************************************************************************************/
+
+static void init_region_config ( CoreLayerContext *context,
+ CoreLayerRegionConfig *config );
+
+static void build_updated_config( CoreLayer *layer,
+ CoreLayerContext *context,
+ const DFBDisplayLayerConfig *update,
+ CoreLayerRegionConfig *ret_config,
+ CoreLayerRegionConfigFlags *ret_flags );
+
+static DFBResult allocate_surface ( CoreLayer *layer,
+ CoreLayerRegion *region,
+ CoreLayerRegionConfig *config );
+
+static DFBResult reallocate_surface ( CoreLayer *layer,
+ CoreLayerRegion *region,
+ CoreLayerRegionConfig *config );
+
+static DFBResult deallocate_surface ( CoreLayer *layer,
+ CoreLayerRegion *region );
+
+static void screen_rectangle ( CoreLayerContext *context,
+ const DFBLocation *location,
+ DFBRectangle *rect );
+
+/**********************************************************************************************************************/
+
+static void
+context_destructor( FusionObject *object, bool zombie, void *ctx )
+{
+ CoreLayerContext *context = (CoreLayerContext*) object;
+ CoreLayer *layer = dfb_layer_at( context->layer_id );
+ CoreLayerShared *shared = layer->shared;
+
+ (void) shared;
+
+ D_DEBUG_AT( Core_LayerContext, "*~ destroying context %p (%s, %sactive%s)\n",
+ context, shared->description.name, context->active ? "" : "in",
+ zombie ? " - ZOMBIE" : "");
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ /* Remove the context from the layer's context stack. */
+ dfb_layer_remove_context( layer, context );
+
+ /*
+ * Detach input devices before taking the context lock to prevent a
+ * deadlock between windowstack destruction and input event processing.
+ */
+ if (context->stack)
+ dfb_windowstack_detach_devices( context->stack );
+
+ dfb_layer_context_lock( context );
+
+ /* Destroy the window stack. */
+ if (context->stack) {
+ dfb_windowstack_destroy( context->stack );
+ context->stack = NULL;
+ }
+
+ /* Destroy the region vector. */
+ fusion_vector_destroy( &context->regions );
+
+ /* Deinitialize the lock. */
+ fusion_skirmish_destroy( &context->lock );
+
+ /* Free clip regions. */
+ if (context->primary.config.clips)
+ SHFREE( context->shmpool, context->primary.config.clips );
+
+ D_MAGIC_CLEAR( context );
+
+ /* Destroy the object. */
+ fusion_object_destroy( object );
+}
+
+/**********************************************************************************************************************/
+
+FusionObjectPool *
+dfb_layer_context_pool_create( const FusionWorld *world )
+{
+ return fusion_object_pool_create( "Layer Context Pool",
+ sizeof(CoreLayerContext),
+ sizeof(CoreLayerContextNotification),
+ context_destructor, NULL, world );
+}
+
+/**********************************************************************************************************************/
+
+static void
+update_stack_geometry( CoreLayerContext *context )
+{
+ DFBDimension size;
+ int rotation;
+ CoreLayerRegion *region;
+ CoreSurface *surface;
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ rotation = context->rotation;
+
+ switch (rotation) {
+ default:
+ D_BUG( "invalid rotation %d", rotation );
+ case 0:
+ case 180:
+ size.w = context->config.width;
+ size.h = context->config.height;
+ break;
+
+ case 90:
+ case 270:
+ size.w = context->config.height;
+ size.h = context->config.width;
+ break;
+ }
+
+ region = context->primary.region;
+ if (region) {
+ surface = region->surface;
+ if (surface) {
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ rotation -= surface->rotation;
+ if (rotation < 0)
+ rotation += 360;
+ }
+ }
+
+ dfb_windowstack_resize( context->stack, size.w, size.h, rotation );
+}
+
+DFBResult
+dfb_layer_context_init( CoreLayerContext *context,
+ CoreLayer *layer )
+{
+ CoreLayerShared *shared;
+
+ D_ASSERT( context != NULL );
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+
+ shared = layer->shared;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p [%s] )\n", __FUNCTION__, context, layer, shared->description.name );
+
+ context->shmpool = shared->shmpool;
+
+ /* Initialize the lock. */
+ if (fusion_skirmish_init( &context->lock, "Layer Context", dfb_core_world(layer->core) )) {
+ fusion_object_destroy( &context->object );
+ return DFB_FUSION;
+ }
+
+ /* Initialize the region vector. */
+ fusion_vector_init( &context->regions, 4, context->shmpool );
+
+ /* Store layer ID, default configuration and default color adjustment. */
+ context->layer_id = shared->layer_id;
+ context->config = shared->default_config;
+ context->adjustment = shared->default_adjustment;
+ context->rotation = dfb_config->layers[dfb_layer_id_translated(layer)].rotate;
+
+ /* Initialize screen location. */
+ context->screen.location.x = 0.0f;
+ context->screen.location.y = 0.0f;
+ context->screen.location.w = 1.0f;
+ context->screen.location.h = 1.0f;
+
+ if (D_FLAGS_IS_SET( shared->description.caps, DLCAPS_SCREEN_LOCATION ))
+ context->screen.mode = CLLM_LOCATION;
+ else if (D_FLAGS_IS_SET( shared->description.caps, DLCAPS_SCREEN_POSITION ))
+ context->screen.mode = CLLM_CENTER;
+
+ /* Change global reaction lock. */
+ fusion_object_set_lock( &context->object, &context->lock );
+
+ D_MAGIC_SET( context, CoreLayerContext );
+
+ /* Initialize the primary region's configuration. */
+ init_region_config( context, &context->primary.config );
+
+ /* Activate the object. */
+ fusion_object_activate( &context->object );
+
+
+ dfb_layer_context_lock( context );
+
+ /* Create the window stack. */
+ context->stack = dfb_windowstack_create( context );
+ if (!context->stack) {
+ dfb_layer_context_unlock( context );
+ dfb_layer_context_unref( context );
+ return D_OOSHM();
+ }
+
+ /* Tell the window stack about its size. */
+ update_stack_geometry( context );
+
+ dfb_layer_context_unlock( context );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_context_activate( CoreLayerContext *context )
+{
+ DFBResult ret;
+ int index;
+ CoreLayer *layer;
+ CoreLayerRegion *region;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p )\n", __FUNCTION__, context );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ layer = dfb_layer_at( context->layer_id );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->funcs != NULL );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ D_ASSUME( !context->active );
+
+ if (context->active) {
+ dfb_layer_context_unlock( context );
+ return DFB_OK;
+ }
+
+ /* Iterate through all regions. */
+ fusion_vector_foreach (region, index, context->regions) {
+ /* Activate each region. */
+ if (dfb_layer_region_activate( region ))
+ D_WARN( "could not activate region!" );
+
+ if (region->surface && region->surface->num_buffers == 0) {
+ D_ASSERT( region->surface_lock.buffer == NULL );
+
+ ret = reallocate_surface( layer, region, &region->config );
+ if (ret)
+ D_DERROR( ret, "Core/Layers: Reallocation of layer surface failed!\n" );
+ }
+ }
+
+ context->active = true;
+
+ /* set new adjustment */
+ if (layer->funcs->SetColorAdjustment)
+ layer->funcs->SetColorAdjustment( layer, layer->driver_data,
+ layer->layer_data, &context->adjustment );
+
+ /* Resume window stack. */
+ if (context->stack) {
+ CoreWindowStack *stack = context->stack;
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ if (stack->flags & CWSF_INITIALIZED)
+ dfb_wm_set_active( stack, true );
+ }
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_context_deactivate( CoreLayerContext *context )
+{
+ int index;
+ CoreLayerRegion *region;
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p )\n", __FUNCTION__, context );
+
+ D_ASSUME( context->active );
+
+ if (!context->active) {
+ dfb_layer_context_unlock( context );
+ return DFB_OK;
+ }
+
+ /* Iterate through all regions. */
+ fusion_vector_foreach (region, index, context->regions) {
+ /* Deactivate each region. */
+ dfb_layer_region_deactivate( region );
+ }
+
+ context->active = false;
+
+ /* Suspend window stack. */
+ if (context->stack) {
+ CoreWindowStack *stack = context->stack;
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ if (stack->flags & CWSF_ACTIVATED)
+ dfb_wm_set_active( stack, false );
+ }
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_context_add_region( CoreLayerContext *context,
+ CoreLayerRegion *region )
+{
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p )\n", __FUNCTION__, context, region );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( region != NULL );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ D_ASSUME( ! fusion_vector_contains( &context->regions, region ) );
+
+ if (fusion_vector_contains( &context->regions, region )) {
+ dfb_layer_context_unlock( context );
+ return DFB_OK;
+ }
+
+ /* Add region to vector. */
+ if (fusion_vector_add( &context->regions, region )) {
+ dfb_layer_context_unlock( context );
+ return DFB_FUSION;
+ }
+
+ /* Inherit state from context. */
+ if (context->active)
+ region->state |= CLRSF_ACTIVE;
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_context_remove_region( CoreLayerContext *context,
+ CoreLayerRegion *region )
+{
+ int index;
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( region != NULL );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ D_ASSUME( fusion_vector_contains( &context->regions, region ) );
+
+ /* Lookup region. */
+ index = fusion_vector_index_of( &context->regions, region );
+ if (index < 0) {
+ dfb_layer_context_unlock( context );
+ return DFB_OK;
+ }
+
+ /* Remove region from vector. */
+ fusion_vector_remove( &context->regions, index );
+
+ /* Check if the primary region is removed. */
+ if (region == context->primary.region)
+ context->primary.region = NULL;
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_context_get_primary_region( CoreLayerContext *context,
+ bool create,
+ CoreLayerRegion **ret_region )
+{
+ DFBResult ret = DFB_OK;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %screate )\n", __FUNCTION__, context, create ? "" : "DON'T " );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( ret_region != NULL );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+restart:
+ while (context->primary.region) {
+ /* Increase the primary region's reference counter. */
+ ret = dfb_layer_region_ref( context->primary.region );
+ if (ret == DFB_OK)
+ break;
+
+ dfb_layer_context_unlock( context );
+
+ if (ret == DFB_LOCKED) {
+ //sched_yield();
+ usleep( 10000 );
+
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+ }
+ else
+ return DFB_FUSION;
+ }
+
+ if (!context->primary.region) {
+ if (create) {
+ CoreLayerRegion *region;
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ /* Create the primary region. */
+ ret = dfb_layer_region_create( context, &region );
+ if (ret) {
+ D_ERROR( "DirectFB/core/layers: Could not create primary region!\n" );
+ return ret;
+ }
+
+ /* Lock the context again. */
+ if (dfb_layer_context_lock( context )) {
+ dfb_layer_region_unref( region );
+ return DFB_FUSION;
+ }
+
+ /* Check for race. */
+ if (context->primary.region) {
+ dfb_layer_region_unref( region );
+ goto restart;
+ }
+
+ /* Set the region configuration. */
+ ret = dfb_layer_region_set_configuration( region,
+ &context->primary.config,
+ CLRCF_ALL );
+ if (ret) {
+ D_DERROR( ret, "DirectFB/core/layers: "
+ "Could not set primary region config!\n" );
+ dfb_layer_region_unref( region );
+ dfb_layer_context_unlock( context );
+ return ret;
+ }
+
+ /* Remember the primary region. */
+ context->primary.region = region;
+
+ /* Allocate surface, enable region etc. */
+ ret = dfb_layer_context_set_configuration( context, &context->config );
+ if (ret) {
+ D_DERROR( ret, "DirectFB/core/layers: "
+ "Could not set layer context config!\n" );
+ context->primary.region = NULL;
+ dfb_layer_region_unref( region );
+ dfb_layer_context_unlock( context );
+ return ret;
+ }
+ }
+ else {
+ dfb_layer_context_unlock( context );
+ return DFB_TEMPUNAVAIL;
+ }
+ }
+
+ /* Return region. */
+ *ret_region = context->primary.region;
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return DFB_OK;
+}
+
+/*
+ * configuration management
+ */
+DFBResult
+dfb_layer_context_test_configuration( CoreLayerContext *context,
+ const DFBDisplayLayerConfig *config,
+ DFBDisplayLayerConfigFlags *ret_failed )
+{
+ DFBResult ret = DFB_OK;
+ CoreLayer *layer;
+ CoreLayerRegionConfig region_config;
+ CoreLayerRegionConfigFlags failed;
+ const DisplayLayerFuncs *funcs;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p, %p )\n", __FUNCTION__, context, config, ret_failed );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( config != NULL );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ layer = dfb_layer_at( context->layer_id );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( layer->funcs->TestRegion != NULL );
+
+ funcs = layer->funcs;
+
+ /* Build a new region configuration with the changes. */
+ build_updated_config( layer, context, config, &region_config, NULL );
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+
+ /* Test the region configuration. */
+ if (region_config.buffermode == DLBM_WINDOWS) {
+ if (! D_FLAGS_IS_SET( layer->shared->description.caps, DLCAPS_WINDOWS )) {
+ failed = CLRCF_BUFFERMODE;
+ ret = DFB_UNSUPPORTED;
+ }
+ }
+ else {
+ /* Let the driver examine the modified configuration. */
+ ret = funcs->TestRegion( layer, layer->driver_data, layer->layer_data,
+ &region_config, &failed );
+ }
+
+ /* Return flags for failing entries. */
+ if (ret_failed) {
+ DFBDisplayLayerConfigFlags flags = DLCONF_NONE;
+
+ /* Translate flags. */
+ if (ret != DFB_OK) {
+ if (failed & CLRCF_WIDTH)
+ flags |= DLCONF_WIDTH;
+
+ if (failed & CLRCF_HEIGHT)
+ flags |= DLCONF_HEIGHT;
+
+ if (failed & CLRCF_FORMAT)
+ flags |= DLCONF_PIXELFORMAT;
+
+ if (failed & CLRCF_BUFFERMODE)
+ flags |= DLCONF_BUFFERMODE;
+
+ if (failed & CLRCF_OPTIONS)
+ flags |= DLCONF_OPTIONS;
+
+ if (failed & CLRCF_SOURCE_ID)
+ flags |= DLCONF_SOURCE;
+
+ if (failed & CLRCF_SURFACE_CAPS)
+ flags |= DLCONF_SURFACE_CAPS;
+ }
+
+ *ret_failed = flags;
+ }
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_context_set_configuration( CoreLayerContext *context,
+ const DFBDisplayLayerConfig *config )
+{
+ int i;
+ DFBResult ret;
+ CoreLayer *layer;
+ CoreLayerShared *shared;
+ CoreLayerRegionConfig region_config;
+ CoreLayerRegionConfigFlags flags;
+ const DisplayLayerFuncs *funcs;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p )\n", __FUNCTION__, context, config );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( config != NULL );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ layer = dfb_layer_at( context->layer_id );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( layer->funcs->TestRegion != NULL );
+
+ shared = layer->shared;
+ funcs = layer->funcs;
+
+ /* Build a new region configuration with the changes. */
+ build_updated_config( layer, context, config, &region_config, &flags );
+
+ /* Test the region configuration first. */
+ if (region_config.buffermode == DLBM_WINDOWS) {
+ if (! D_FLAGS_IS_SET( shared->description.caps, DLCAPS_WINDOWS )) {
+ dfb_layer_context_unlock( context );
+ return DFB_UNSUPPORTED;
+ }
+ }
+ else {
+ ret = funcs->TestRegion( layer, layer->driver_data, layer->layer_data,
+ &region_config, NULL );
+ if (ret) {
+ dfb_layer_context_unlock( context );
+ return ret;
+ }
+ }
+
+ /* Set the region configuration. */
+ if (context->primary.region) {
+ CoreLayerRegion *region = context->primary.region;
+
+ /* Add local reference. */
+ if (dfb_layer_region_ref( region )) {
+ dfb_layer_context_unlock( context );
+ return DFB_FUSION;
+ }
+
+ /* Lock the region. */
+ if (dfb_layer_region_lock( region )) {
+ dfb_layer_region_unref( region );
+ dfb_layer_context_unlock( context );
+ return DFB_FUSION;
+ }
+
+ /* Normal buffer mode? */
+ if (region_config.buffermode != DLBM_WINDOWS) {
+ bool surface = shared->description.caps & DLCAPS_SURFACE;
+ CoreLayerRegionStateFlags configured = region->state & CLRSF_CONFIGURED;
+
+ if (shared->description.caps & DLCAPS_SOURCES) {
+ for (i=0; i<shared->description.sources; i++) {
+ if (shared->sources[i].description.source_id == region_config.source_id)
+ break;
+ }
+
+ D_ASSERT( i < shared->description.sources );
+
+ surface = shared->sources[i].description.caps & DDLSCAPS_SURFACE;
+ }
+
+ D_FLAGS_CLEAR( region->state, CLRSF_CONFIGURED );
+
+ /* Unlock the region surface */
+ if (region->surface) {
+ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) {
+ if (!D_FLAGS_IS_SET( region->state, CLRSF_FROZEN ))
+ D_ASSUME( region->surface_lock.buffer != NULL );
+
+ if (region->surface_lock.buffer)
+ dfb_surface_unlock_buffer( region->surface, &region->surface_lock );
+ }
+ }
+
+ /* (Re)allocate the region's surface. */
+ if (surface) {
+ flags |= CLRCF_SURFACE | CLRCF_PALETTE;
+
+ if (region->surface) {
+ ret = reallocate_surface( layer, region, &region_config );
+ if (ret)
+ D_DERROR( ret, "Core/Layers: Reallocation of layer surface failed!\n" );
+ }
+ else {
+ ret = allocate_surface( layer, region, &region_config );
+ if (ret)
+ D_DERROR( ret, "Core/Layers: Allocation of layer surface failed!\n" );
+ }
+
+ if (ret) {
+ dfb_layer_region_unlock( region );
+ dfb_layer_region_unref( region );
+ dfb_layer_context_unlock( context );
+ return ret;
+ }
+ }
+ else if (region->surface)
+ deallocate_surface( layer, region );
+
+ region->state |= configured;
+
+ /* Set the new region configuration. */
+ dfb_layer_region_set_configuration( region, &region_config, flags );
+
+ /* Enable the primary region. */
+ if (! D_FLAGS_IS_SET( region->state, CLRSF_ENABLED ))
+ dfb_layer_region_enable( region );
+ }
+ else {
+ /* Disable and deallocate the primary region. */
+ if (D_FLAGS_IS_SET( region->state, CLRSF_ENABLED )) {
+ dfb_layer_region_disable( region );
+
+ if (region->surface)
+ deallocate_surface( layer, region );
+ }
+ }
+
+ /* Unlock the region and give up the local reference. */
+ dfb_layer_region_unlock( region );
+ dfb_layer_region_unref( region );
+ }
+
+ /* Remember new region config. */
+ context->primary.config = region_config;
+
+ /*
+ * Write back modified entries.
+ */
+ if (config->flags & DLCONF_WIDTH)
+ context->config.width = config->width;
+
+ if (config->flags & DLCONF_HEIGHT)
+ context->config.height = config->height;
+
+ if (config->flags & DLCONF_PIXELFORMAT)
+ context->config.pixelformat = config->pixelformat;
+
+ if (config->flags & DLCONF_BUFFERMODE)
+ context->config.buffermode = config->buffermode;
+
+ if (config->flags & DLCONF_OPTIONS)
+ context->config.options = config->options;
+
+ if (config->flags & DLCONF_SOURCE)
+ context->config.source = config->source;
+
+ if (config->flags & DLCONF_SURFACE_CAPS)
+ context->config.surface_caps = config->surface_caps;
+
+ /* Update the window stack. */
+ if (context->stack) {
+ CoreWindowStack *stack = context->stack;
+
+ /* Update hardware flag. */
+ stack->hw_mode = (region_config.buffermode == DLBM_WINDOWS);
+
+ /* Tell the windowing core about the new size. */
+ if (config->flags & (DLCONF_WIDTH | DLCONF_HEIGHT |
+ DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_SURFACE_CAPS))
+ {
+ update_stack_geometry( context );
+
+ /* FIXME: call only if really needed */
+ dfb_windowstack_repaint_all( stack );
+ }
+ }
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_context_get_configuration( CoreLayerContext *context,
+ DFBDisplayLayerConfig *config )
+{
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p )\n", __FUNCTION__, context, config );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( config != NULL );
+
+ *config = context->config;
+
+ return DFB_OK;
+}
+
+static DFBResult
+update_primary_region_config( CoreLayerContext *context,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags flags )
+{
+ DFBResult ret = DFB_OK;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p, 0x%08x )\n", __FUNCTION__, context, config, flags );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( config != NULL );
+
+ if (context->primary.region) {
+ /* Set the new configuration. */
+ ret = dfb_layer_region_set_configuration( context->primary.region, config, flags );
+ }
+ else {
+ CoreLayer *layer = dfb_layer_at( context->layer_id );
+
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( layer->funcs->TestRegion != NULL );
+
+ /* Just test the new configuration. */
+ ret = layer->funcs->TestRegion( layer, layer->driver_data,
+ layer->layer_data, config, NULL );
+ }
+
+ if (ret)
+ return ret;
+
+ /* Remember the configuration. */
+ context->primary.config = *config;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_context_set_src_colorkey( CoreLayerContext *context,
+ u8 r, u8 g, u8 b, int index )
+{
+ DFBResult ret;
+ CoreLayerRegionConfig config;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %02x %02x %02x - %d )\n", __FUNCTION__, context, r, g, b, index );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ /* Take the current configuration. */
+ config = context->primary.config;
+
+ /* Change the color key. */
+ config.src_key.r = r;
+ config.src_key.g = g;
+ config.src_key.b = b;
+
+ if (index >= 0)
+ config.src_key.index = index & 0xff;
+
+ /* Try to set the new configuration. */
+ ret = update_primary_region_config( context, &config, CLRCF_SRCKEY );
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_context_set_dst_colorkey( CoreLayerContext *context,
+ u8 r, u8 g, u8 b, int index )
+{
+ DFBResult ret;
+ CoreLayerRegionConfig config;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %02x %02x %02x - %d )\n", __FUNCTION__, context, r, g, b, index );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ /* Take the current configuration. */
+ config = context->primary.config;
+
+ /* Change the color key. */
+ config.dst_key.r = r;
+ config.dst_key.g = g;
+ config.dst_key.b = b;
+
+ if (index >= 0)
+ config.dst_key.index = index & 0xff;
+
+ /* Try to set the new configuration. */
+ ret = update_primary_region_config( context, &config, CLRCF_DSTKEY );
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_context_set_sourcerectangle( CoreLayerContext *context,
+ const DFBRectangle *source )
+{
+ DFBResult ret;
+ CoreLayerRegionConfig config;
+ CoreLayerRegionConfigFlags flags;
+ CoreLayer *layer;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p )\n", __FUNCTION__, context, source );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( source != NULL );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ /* Take the current configuration. */
+ config = context->primary.config;
+
+ /* Do nothing if the source rectangle didn't change. */
+ if (DFB_RECTANGLE_EQUAL( config.source, *source )) {
+ dfb_layer_context_unlock( context );
+ return DFB_OK;
+ }
+
+ /* Check if the new source rectangle is valid. */
+ if (source->x < 0 || source->y < 0 ||
+ source->x + source->w > config.width ||
+ source->y + source->h > config.height) {
+ dfb_layer_context_unlock( context );
+ return DFB_INVAREA;
+ }
+
+ /* Change the source rectangle. */
+ config.source = *source;
+
+ flags = CLRCF_SOURCE;
+ layer = dfb_layer_at( context->layer_id );
+
+ /* If the display layer does not support scaling and the destination
+ rectangle size is not the same as the source, change it to match. The
+ origin is left alone to allow the driver to handle it. */
+ if ( !D_FLAGS_IS_SET( layer->shared->description.caps, DLCAPS_SCREEN_SIZE ) &&
+ ( config.dest.w != config.source.w ||
+ config.dest.h != config.source.h ) )
+ {
+ config.dest.w = config.source.w;
+ config.dest.h = config.source.h;
+
+ flags |= CLRCF_DEST;
+ }
+
+ /* Try to set the new configuration. */
+ ret = update_primary_region_config( context, &config, flags );
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_context_set_screenlocation( CoreLayerContext *context,
+ const DFBLocation *location )
+{
+ DFBResult ret;
+ CoreLayerRegionConfig config;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p )\n", __FUNCTION__, context, location );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( location != NULL );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ /* Do nothing if the location didn't change. */
+/* if (context->screen.mode == CLLM_LOCATION &&
+ DFB_LOCATION_EQUAL( context->screen.location, *location ))
+ {
+ dfb_layer_context_unlock( context );
+ return DFB_OK;
+ }*/
+
+ /* Take the current configuration. */
+ config = context->primary.config;
+
+ /* Calculate new absolute screen coordinates. */
+ screen_rectangle( context, location, &config.dest );
+
+ /* Try to set the new configuration. */
+ ret = update_primary_region_config( context, &config, CLRCF_DEST );
+ if (ret == DFB_OK) {
+ context->screen.location = *location;
+ context->screen.rectangle = config.dest;
+ context->screen.mode = CLLM_LOCATION;
+ }
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_context_set_screenrectangle( CoreLayerContext *context,
+ const DFBRectangle *rectangle )
+{
+ DFBResult ret;
+ CoreLayerRegionConfig config;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p )\n", __FUNCTION__, context, rectangle );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ DFB_RECTANGLE_ASSERT( rectangle );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ /* Do nothing if the location didn't change. */
+/* if (context->screen.mode == CLLM_RECTANGLE &&
+ DFB_RECTANGLE_EQUAL( context->screen.rectangle, *rectangle ))
+ {
+ dfb_layer_context_unlock( context );
+ return DFB_OK;
+ }*/
+
+ /* Take the current configuration. */
+ config = context->primary.config;
+
+ /* Use supplied absolute screen coordinates. */
+ config.dest = *rectangle;
+
+ /* Try to set the new configuration. */
+ ret = update_primary_region_config( context, &config, CLRCF_DEST );
+ if (ret == DFB_OK) {
+ context->screen.rectangle = config.dest;
+ context->screen.mode = CLLM_RECTANGLE;
+ }
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_context_set_screenposition( CoreLayerContext *context,
+ int x,
+ int y )
+{
+ DFBResult ret;
+ CoreLayerRegionConfig config;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %4d,%4d )\n", __FUNCTION__, context, x, y );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ /* Do nothing if the location didn't change. */
+ if (context->primary.config.dest.x == x && context->primary.config.dest.y == y) {
+ dfb_layer_context_unlock( context );
+ return DFB_OK;
+ }
+
+ /* Take the current configuration. */
+ config = context->primary.config;
+
+ /* Set new absolute screen coordinates. */
+ config.dest.x = x;
+ config.dest.y = y;
+
+ /* Try to set the new configuration. */
+ ret = update_primary_region_config( context, &config, CLRCF_DEST );
+ if (ret == DFB_OK) {
+ context->screen.rectangle = config.dest;
+ context->screen.mode = CLLM_POSITION;
+ }
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_context_set_opacity( CoreLayerContext *context,
+ u8 opacity )
+{
+ DFBResult ret;
+ CoreLayerRegionConfig config;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %u )\n", __FUNCTION__, context, opacity );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ /* Do nothing if the opacity didn't change. */
+ if (context->primary.config.opacity == opacity) {
+ dfb_layer_context_unlock( context );
+ return DFB_OK;
+ }
+
+ /* Take the current configuration. */
+ config = context->primary.config;
+
+ /* Change the opacity. */
+ config.opacity = opacity;
+
+ /* Try to set the new configuration. */
+ ret = update_primary_region_config( context, &config, CLRCF_OPACITY );
+ if (ret == DFB_OK)
+ context->primary.config.opacity = opacity;
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_context_set_rotation( CoreLayerContext *context,
+ int rotation )
+{
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %d )\n", __FUNCTION__, context, rotation );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ /* Do nothing if the rotation didn't change. */
+ if (context->rotation != rotation) {
+ context->rotation = rotation;
+
+ update_stack_geometry( context );
+
+ dfb_windowstack_repaint_all( context->stack );
+ }
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_context_set_coloradjustment( CoreLayerContext *context,
+ const DFBColorAdjustment *adjustment )
+{
+ DFBResult ret;
+ DFBColorAdjustment adj;
+ CoreLayer *layer;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p )\n", __FUNCTION__, context, adjustment );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( adjustment != NULL );
+
+ layer = dfb_layer_at( context->layer_id );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->funcs != NULL );
+
+ adj = context->adjustment;
+
+ if (!layer->funcs->SetColorAdjustment)
+ return DFB_UNSUPPORTED;
+
+ /* if flags are set that are not in the default adjustment */
+ if (adjustment->flags & ~context->adjustment.flags)
+ return DFB_UNSUPPORTED;
+
+ /* take over changed values */
+ if (adjustment->flags & DCAF_BRIGHTNESS) adj.brightness = adjustment->brightness;
+ if (adjustment->flags & DCAF_CONTRAST) adj.contrast = adjustment->contrast;
+ if (adjustment->flags & DCAF_HUE) adj.hue = adjustment->hue;
+ if (adjustment->flags & DCAF_SATURATION) adj.saturation = adjustment->saturation;
+
+ /* set new adjustment */
+ ret = layer->funcs->SetColorAdjustment( layer, layer->driver_data,
+ layer->layer_data, &adj );
+ if (ret)
+ return ret;
+
+ /* keep new adjustment */
+ context->adjustment = adj;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_context_get_coloradjustment( CoreLayerContext *context,
+ DFBColorAdjustment *ret_adjustment )
+{
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p )\n", __FUNCTION__, context, ret_adjustment );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( ret_adjustment != NULL );
+
+ *ret_adjustment = context->adjustment;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_context_set_field_parity( CoreLayerContext *context,
+ int field )
+{
+ DFBResult ret;
+ CoreLayerRegionConfig config;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %d )\n", __FUNCTION__, context, field );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ /* Do nothing if the parity didn't change. */
+ if (context->primary.config.parity == field) {
+ dfb_layer_context_unlock( context );
+ return DFB_OK;
+ }
+
+ /* Take the current configuration. */
+ config = context->primary.config;
+
+ /* Change the parity. */
+ config.parity = field;
+
+ /* Try to set the new configuration. */
+ ret = update_primary_region_config( context, &config, CLRCF_PARITY );
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_context_set_clip_regions( CoreLayerContext *context,
+ const DFBRegion *regions,
+ int num_regions,
+ DFBBoolean positive )
+{
+ DFBResult ret;
+ CoreLayerRegionConfig config;
+ DFBRegion *clips;
+ DFBRegion *old_clips;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p [%d], %s )\n", __FUNCTION__,
+ context, regions, num_regions, positive ? "positive" : "negative" );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ clips = SHMALLOC( context->shmpool, sizeof(DFBRegion) * num_regions );
+ if (!clips)
+ return D_OOSHM();
+
+ direct_memcpy( clips, regions, sizeof(DFBRegion) * num_regions );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context )) {
+ SHFREE( context->shmpool, clips );
+ return DFB_FUSION;
+ }
+
+ /* Take the current configuration. */
+ config = context->primary.config;
+
+ /* Remember for freeing later on. */
+ old_clips = config.clips;
+
+ /* Change the clip regions. */
+ config.clips = clips;
+ config.num_clips = num_regions;
+ config.positive = positive;
+
+ /* Try to set the new configuration. */
+ ret = update_primary_region_config( context, &config, CLRCF_CLIPS );
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ if (ret)
+ SHFREE( context->shmpool, clips );
+ else if (old_clips)
+ SHFREE( context->shmpool, old_clips );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_context_create_window( CoreDFB *core,
+ CoreLayerContext *context,
+ const DFBWindowDescription *desc,
+ CoreWindow **ret_window )
+{
+ DFBResult ret;
+ CoreWindow *window;
+ CoreWindowStack *stack;
+ CoreLayer *layer;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p, %p, %p )\n", __FUNCTION__, core, context, desc, ret_window );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( context->stack != NULL );
+ D_ASSERT( desc != NULL );
+ D_ASSERT( ret_window != NULL );
+
+ layer = dfb_layer_at( context->layer_id );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->funcs != NULL );
+
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ stack = context->stack;
+
+ if (!stack->cursor.set) {
+ ret = dfb_windowstack_cursor_enable( core, stack, true );
+ if (ret) {
+ dfb_layer_context_unlock( context );
+ return ret;
+ }
+ }
+
+ ret = dfb_window_create( stack, desc, &window );
+ if (ret) {
+ dfb_layer_context_unlock( context );
+ return ret;
+ }
+
+ *ret_window = window;
+
+ dfb_layer_context_unlock( context );
+
+ return DFB_OK;
+}
+
+CoreWindow *
+dfb_layer_context_find_window( CoreLayerContext *context, DFBWindowID id )
+{
+ CoreWindowStack *stack;
+ CoreWindow *window;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %u )\n", __FUNCTION__, context, id );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( context->stack != NULL );
+
+ stack = context->stack;
+
+ if (dfb_layer_context_lock( context ))
+ return NULL;
+
+ if (dfb_wm_window_lookup( stack, id, &window ) || dfb_window_ref( window ))
+ window = NULL;
+
+ dfb_layer_context_unlock( context );
+
+ return window;
+}
+
+CoreWindowStack *
+dfb_layer_context_windowstack( const CoreLayerContext *context )
+{
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ return context->stack;
+}
+
+bool
+dfb_layer_context_active( const CoreLayerContext *context )
+{
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ return context->active;
+}
+
+DirectResult
+dfb_layer_context_lock( CoreLayerContext *context )
+{
+ DFBResult ret;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p )\n", __FUNCTION__, context );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ ret = fusion_skirmish_prevail( &context->lock );
+ if (ret == DFB_OK) {
+ int locked;
+
+ ret = fusion_skirmish_lock_count( &context->lock, &locked );
+ if (ret == DFB_OK)
+ D_DEBUG_AT( Core_LayerContext, " -> locked %dx now\n", locked );
+ }
+
+ return ret;
+}
+
+DirectResult
+dfb_layer_context_unlock( CoreLayerContext *context )
+{
+ D_DEBUG_AT( Core_LayerContext, "%s( %p )\n", __FUNCTION__, context );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ return fusion_skirmish_dismiss( &context->lock );
+}
+
+/**************************************************************************************************/
+
+/*
+ * region config construction
+ */
+static void
+init_region_config( CoreLayerContext *context,
+ CoreLayerRegionConfig *config )
+{
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p )\n", __FUNCTION__, context, config );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( config != NULL );
+
+ memset( config, 0, sizeof(CoreLayerRegionConfig) );
+
+ /* Initialize values from layer config. */
+ config->width = context->config.width;
+ config->height = context->config.height;
+ config->format = context->config.pixelformat;
+ config->buffermode = context->config.buffermode;
+ config->options = context->config.options;
+ config->source_id = context->config.source;
+ config->surface_caps = context->config.surface_caps;
+
+ /* Initialize source rectangle. */
+ config->source.x = 0;
+ config->source.y = 0;
+ config->source.w = config->width;
+ config->source.h = config->height;
+
+ /* Initialize screen rectangle. */
+ screen_rectangle( context, &context->screen.location, &config->dest );
+
+ /* Set default opacity. */
+ config->opacity = 0xff;
+
+ /* Set default alpha ramp. */
+ config->alpha_ramp[0] = 0x00;
+ config->alpha_ramp[1] = 0x55;
+ config->alpha_ramp[2] = 0xaa;
+ config->alpha_ramp[3] = 0xff;
+}
+
+static void
+build_updated_config( CoreLayer *layer,
+ CoreLayerContext *context,
+ const DFBDisplayLayerConfig *update,
+ CoreLayerRegionConfig *ret_config,
+ CoreLayerRegionConfigFlags *ret_flags )
+{
+ CoreLayerRegionConfigFlags flags = CLRCF_NONE;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p, %p, %p, %p )\n",
+ __FUNCTION__, layer, context, update, ret_config, ret_flags );
+
+ D_ASSERT( layer != NULL );
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( update != NULL );
+ D_ASSERT( ret_config != NULL );
+
+ /* Get the current region configuration. */
+ *ret_config = context->primary.config;
+
+ /* Change width. */
+ if (update->flags & DLCONF_WIDTH) {
+ flags |= CLRCF_WIDTH;
+ ret_config->width = update->width;
+ }
+
+ /* Change height. */
+ if (update->flags & DLCONF_HEIGHT) {
+ flags |= CLRCF_HEIGHT;
+ ret_config->height = update->height;
+ }
+
+ /* Update source and destination rectangle. */
+ if (update->flags & (DLCONF_WIDTH | DLCONF_HEIGHT)) {
+ int width, height;
+ DFBResult ret;
+
+ flags |= CLRCF_SOURCE | CLRCF_DEST;
+
+ ret_config->source.x = 0;
+ ret_config->source.y = 0;
+ ret_config->source.w = ret_config->width;
+ ret_config->source.h = ret_config->height;
+
+ switch (context->screen.mode) {
+ case CLLM_CENTER:
+ ret = dfb_screen_get_layer_dimension( layer->screen, layer, &width, &height );
+ if( ret == DFB_OK ) {
+ ret_config->dest.x = (width - ret_config->width) / 2;
+ ret_config->dest.y = (height - ret_config->height) / 2;
+ }
+ /* fall through */
+
+ case CLLM_POSITION:
+ ret_config->dest.w = ret_config->width;
+ ret_config->dest.h = ret_config->height;
+ break;
+
+ case CLLM_LOCATION:
+ case CLLM_RECTANGLE:
+ D_ASSERT( layer->shared != NULL );
+
+ /* If the display layer does not support scaling and the
+ destination rectangle size is not the same as the
+ source rectangle, change it to match. The origin is
+ left alone to allow the driver to handle it. */
+ if ( !D_FLAGS_IS_SET( layer->shared->description.caps, DLCAPS_SCREEN_SIZE )
+ && ( ret_config->dest.w != ret_config->source.w ||
+ ret_config->dest.h != ret_config->source.h ) )
+ {
+ ret_config->dest.w = ret_config->width;
+ ret_config->dest.h = ret_config->height;
+ }
+ break;
+
+ default:
+ D_BREAK( "invalid layout mode" );
+ }
+ }
+
+ /* Change pixel format. */
+ if (update->flags & DLCONF_PIXELFORMAT) {
+ flags |= CLRCF_FORMAT;
+ ret_config->format = update->pixelformat;
+ }
+
+ /* Change buffer mode. */
+ if (update->flags & DLCONF_BUFFERMODE) {
+ flags |= CLRCF_BUFFERMODE;
+ ret_config->buffermode = update->buffermode;
+ }
+
+ /* Change options. */
+ if (update->flags & DLCONF_OPTIONS) {
+ flags |= CLRCF_OPTIONS;
+ ret_config->options = update->options;
+ }
+
+ /* Change source id. */
+ if (update->flags & DLCONF_SOURCE) {
+ flags |= CLRCF_SOURCE_ID;
+ ret_config->source_id = update->source;
+ }
+
+ /* Change surface caps. */
+ if (update->flags & DLCONF_SURFACE_CAPS) {
+ flags |= CLRCF_SURFACE_CAPS;
+ ret_config->surface_caps = update->surface_caps;
+ }
+
+ /* Return translated flags. */
+ if (ret_flags)
+ *ret_flags = flags;
+}
+
+/*
+ * region surface (re/de)allocation
+ */
+static DFBResult
+allocate_surface( CoreLayer *layer,
+ CoreLayerRegion *region,
+ CoreLayerRegionConfig *config )
+{
+ DFBResult ret;
+ const DisplayLayerFuncs *funcs;
+ CoreLayerContext *context;
+ CoreSurface *surface = NULL;
+ DFBSurfaceCapabilities caps = DSCAPS_VIDEOONLY;
+ CoreSurfaceTypeFlags type = CSTF_LAYER;
+ CoreSurfaceConfig scon;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p, %p )\n", __FUNCTION__, layer, region, config );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( region != NULL );
+ D_ASSERT( region->surface == NULL );
+ D_ASSERT( config != NULL );
+ D_ASSERT( config->buffermode != DLBM_WINDOWS );
+
+ context = region->context;
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ funcs = layer->funcs;
+
+ /*
+ * Create a new surface for the region.
+ * Drivers may provide their own surface creation (unusual).
+ */
+ if (funcs->AllocateSurface) {
+ /* Let the driver create the surface. */
+ ret = funcs->AllocateSurface( layer, layer->driver_data,
+ layer->layer_data, region->region_data,
+ config, &surface );
+ if (ret) {
+ D_ERROR( "DirectFB/core/layers: AllocateSurface() failed!\n" );
+ return ret;
+ }
+ }
+ else {
+ CoreLayerShared *shared = layer->shared;
+
+ /* Choose surface capabilities depending on the buffer mode. */
+ switch (config->buffermode) {
+ case DLBM_FRONTONLY:
+ break;
+
+ case DLBM_BACKVIDEO:
+ case DLBM_BACKSYSTEM:
+ caps |= DSCAPS_DOUBLE;
+ break;
+
+ case DLBM_TRIPLE:
+ caps |= DSCAPS_TRIPLE;
+ break;
+
+ default:
+ D_BUG("unknown buffermode");
+ break;
+ }
+
+ if (context->rotation == 90 || context->rotation == 270)
+ caps |= DSCAPS_ROTATED;
+
+ /* FIXME: remove this? */
+ if (config->options & DLOP_DEINTERLACING)
+ caps |= DSCAPS_INTERLACED;
+
+ /* Add available surface capabilities. */
+ caps |= config->surface_caps & (DSCAPS_INTERLACED |
+ DSCAPS_SEPARATED |
+ DSCAPS_PREMULTIPLIED);
+
+ scon.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS;
+ scon.size.w = config->width;
+ scon.size.h = config->height;
+ scon.format = config->format;
+ scon.caps = caps;
+
+ if (shared->contexts.primary == region->context)
+ type |= CSTF_SHARED;
+
+ /* Use the default surface creation. */
+ ret = dfb_surface_create( layer->core, &scon, type, shared->layer_id, NULL, &surface );
+ if (ret) {
+ D_DERROR( ret, "Core/layers: Surface creation failed!\n" );
+ return ret;
+ }
+
+ if (config->buffermode == DLBM_BACKSYSTEM)
+ surface->buffers[1]->policy = CSP_SYSTEMONLY;
+ }
+
+ if (surface->config.caps & DSCAPS_ROTATED)
+ surface->rotation = context->rotation;
+ else
+ surface->rotation = (context->rotation == 180) ? 180 : 0;
+
+ /* Tell the region about its new surface (adds a global reference). */
+ ret = dfb_layer_region_set_surface( region, surface );
+
+ /* Remove local reference of dfb_surface_create(). */
+ dfb_surface_unref( surface );
+
+ return ret;
+}
+
+static DFBResult
+reallocate_surface( CoreLayer *layer,
+ CoreLayerRegion *region,
+ CoreLayerRegionConfig *config )
+{
+ DFBResult ret;
+ const DisplayLayerFuncs *funcs;
+ CoreLayerContext *context;
+ CoreSurface *surface;
+ CoreSurfaceConfig sconfig;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p, %p )\n", __FUNCTION__, layer, region, config );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( region != NULL );
+ D_ASSERT( region->surface != NULL );
+ D_ASSERT( config != NULL );
+ D_ASSERT( config->buffermode != DLBM_WINDOWS );
+
+ context = region->context;
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ funcs = layer->funcs;
+ surface = region->surface;
+
+ if (funcs->ReallocateSurface)
+ return funcs->ReallocateSurface( layer, layer->driver_data,
+ layer->layer_data,
+ region->region_data,
+ config, surface );
+
+ sconfig.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS;
+
+ sconfig.caps = surface->config.caps & ~(DSCAPS_FLIPPING | DSCAPS_INTERLACED |
+ DSCAPS_SEPARATED | DSCAPS_PREMULTIPLIED | DSCAPS_ROTATED);
+
+ switch (config->buffermode) {
+ case DLBM_TRIPLE:
+ sconfig.caps |= DSCAPS_TRIPLE;
+ break;
+
+ case DLBM_BACKVIDEO:
+ case DLBM_BACKSYSTEM:
+ sconfig.caps |= DSCAPS_DOUBLE;
+ break;
+
+ case DLBM_FRONTONLY:
+ break;
+
+ default:
+ D_BUG("unknown buffermode");
+ return DFB_BUG;
+ }
+
+ if (context->rotation == 90 || context->rotation == 270)
+ sconfig.caps |= DSCAPS_ROTATED;
+
+ /* Add available surface capabilities. */
+ sconfig.caps |= config->surface_caps & (DSCAPS_INTERLACED |
+ DSCAPS_SEPARATED |
+ DSCAPS_PREMULTIPLIED);
+
+ if (config->options & DLOP_DEINTERLACING)
+ sconfig.caps |= DSCAPS_INTERLACED;
+
+ sconfig.size.w = config->width;
+ sconfig.size.h = config->height;
+ sconfig.format = config->format;
+
+ ret = dfb_surface_lock( surface );
+ if (ret)
+ return ret;
+
+ ret = dfb_surface_reconfig( surface, &sconfig );
+ if (ret) {
+ dfb_surface_unlock( surface );
+ return ret;
+ }
+
+ if (DFB_PIXELFORMAT_IS_INDEXED(surface->config.format) && !surface->palette) {
+ ret = dfb_surface_init_palette( layer->core, surface );
+ if (ret)
+ D_DERROR( ret, "Core/Layers: Could not initialize palette while switching to indexed mode!\n" );
+ }
+
+ switch (config->buffermode) {
+ case DLBM_TRIPLE:
+ case DLBM_BACKVIDEO:
+ surface->buffers[1]->policy = CSP_VIDEOONLY;
+ break;
+
+ case DLBM_BACKSYSTEM:
+ surface->buffers[1]->policy = CSP_SYSTEMONLY;
+ break;
+
+ case DLBM_FRONTONLY:
+ break;
+
+ default:
+ D_BUG("unknown buffermode");
+ return DFB_BUG;
+ }
+
+ if (surface->config.caps & DSCAPS_ROTATED)
+ surface->rotation = context->rotation;
+ else
+ surface->rotation = (context->rotation == 180) ? 180 : 0;
+
+ dfb_surface_unlock( surface );
+
+ return DFB_OK;
+}
+
+static DFBResult
+deallocate_surface( CoreLayer *layer, CoreLayerRegion *region )
+{
+ DFBResult ret;
+ const DisplayLayerFuncs *funcs;
+ CoreSurface *surface;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p )\n", __FUNCTION__, layer, region );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( region != NULL );
+
+ D_ASSUME( region->surface != NULL );
+
+ funcs = layer->funcs;
+ surface = region->surface;
+
+ if (surface) {
+ /* Special deallocation by the driver. */
+ if (funcs->DeallocateSurface) {
+ ret = funcs->DeallocateSurface( layer, layer->driver_data,
+ layer->layer_data,
+ region->region_data, surface );
+ if (ret)
+ return ret;
+ }
+
+ /* Detach the global listener. */
+ dfb_surface_detach_global( surface, &region->surface_reaction );
+
+ /* Unlink from structure. */
+ dfb_surface_unlink( &region->surface );
+ }
+
+ return DFB_OK;
+}
+
+static void
+screen_rectangle( CoreLayerContext *context,
+ const DFBLocation *location,
+ DFBRectangle *rect )
+{
+ DFBResult ret;
+ int width;
+ int height;
+ CoreLayer *layer;
+
+ D_DEBUG_AT( Core_LayerContext, "%s( %p, %p, %p )\n", __FUNCTION__, context, location, rect );
+
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+ D_ASSERT( location != NULL );
+ D_ASSERT( rect != NULL );
+
+ D_DEBUG_AT( Core_LayerContext, " <- %4.2f,%4.2f-%4.2f,%4.2f\n",
+ location->x, location->y, location->w, location->h );
+
+ layer = dfb_layer_at( context->layer_id );
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->screen != NULL );
+
+ ret = dfb_screen_get_layer_dimension( layer->screen, layer, &width, &height );
+ if (ret) {
+ D_WARN( "could not determine mixer/screen dimension of layer %d", context->layer_id );
+
+ rect->x = location->x * 720;
+ rect->y = location->y * 576;
+ rect->w = location->w * 720;
+ rect->h = location->h * 576;
+ }
+ else {
+ rect->x = location->x * width;
+ rect->y = location->y * height;
+ rect->w = location->w * width;
+ rect->h = location->h * height;
+ }
+
+ D_DEBUG_AT( Core_LayerContext, " => %4d,%4d-%4d,%4d\n", DFB_RECTANGLE_VALS(rect) );
+}
+
diff --git a/Source/DirectFB/src/core/layer_context.h b/Source/DirectFB/src/core/layer_context.h
new file mode 100755
index 0000000..ab9d2fb
--- /dev/null
+++ b/Source/DirectFB/src/core/layer_context.h
@@ -0,0 +1,149 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__LAYER_CONTEXT_H__
+#define __CORE__LAYER_CONTEXT_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+#include <fusion/object.h>
+
+typedef enum {
+ CLCNF_ACTIVATED = 0x00000001,
+ CLCNF_DEACTIVATED = 0x00000002
+} CoreLayerContextNotificationFlags;
+
+typedef struct {
+ CoreLayerContextNotificationFlags flags;
+ CoreLayerContext *context;
+} CoreLayerContextNotification;
+
+/*
+ * Creates a pool of layer context objects.
+ */
+FusionObjectPool *dfb_layer_context_pool_create( const FusionWorld *world );
+
+/*
+ * Generates dfb_layer_context_ref(), dfb_layer_context_attach() etc.
+ */
+FUSION_OBJECT_METHODS( CoreLayerContext, dfb_layer_context )
+
+
+DFBResult dfb_layer_context_init( CoreLayerContext *context,
+ CoreLayer *layer );
+
+DFBResult dfb_layer_context_get_primary_region( CoreLayerContext *context,
+ bool create,
+ CoreLayerRegion **ret_region );
+
+/*
+ * configuration testing/setting/getting
+ */
+DFBResult dfb_layer_context_test_configuration ( CoreLayerContext *context,
+ const DFBDisplayLayerConfig *config,
+ DFBDisplayLayerConfigFlags *ret_failed );
+
+DFBResult dfb_layer_context_set_configuration ( CoreLayerContext *context,
+ const DFBDisplayLayerConfig *config );
+
+DFBResult dfb_layer_context_get_configuration ( CoreLayerContext *context,
+ DFBDisplayLayerConfig *ret_config );
+
+
+/*
+ * configuration details
+ */
+DFBResult dfb_layer_context_set_src_colorkey ( CoreLayerContext *context,
+ u8 r,
+ u8 g,
+ u8 b,
+ int index );
+
+DFBResult dfb_layer_context_set_dst_colorkey ( CoreLayerContext *context,
+ u8 r,
+ u8 g,
+ u8 b,
+ int index );
+
+DFBResult dfb_layer_context_set_sourcerectangle( CoreLayerContext *context,
+ const DFBRectangle *source );
+
+DFBResult dfb_layer_context_set_screenlocation ( CoreLayerContext *context,
+ const DFBLocation *location );
+
+DFBResult dfb_layer_context_set_screenrectangle( CoreLayerContext *context,
+ const DFBRectangle *rectangle );
+
+DFBResult dfb_layer_context_set_screenposition ( CoreLayerContext *context,
+ int x,
+ int y );
+
+DFBResult dfb_layer_context_set_opacity ( CoreLayerContext *context,
+ u8 opacity );
+
+DFBResult dfb_layer_context_set_rotation ( CoreLayerContext *context,
+ int rotation );
+
+DFBResult dfb_layer_context_set_coloradjustment( CoreLayerContext *context,
+ const DFBColorAdjustment *adjustment );
+
+DFBResult dfb_layer_context_get_coloradjustment( CoreLayerContext *context,
+ DFBColorAdjustment *ret_adjustment );
+
+DFBResult dfb_layer_context_set_field_parity ( CoreLayerContext *context,
+ int field );
+
+DFBResult dfb_layer_context_set_clip_regions ( CoreLayerContext *context,
+ const DFBRegion *regions,
+ int num_regions,
+ DFBBoolean positive );
+
+
+/*
+ * window control
+ */
+DFBResult dfb_layer_context_create_window( CoreDFB *core,
+ CoreLayerContext *context,
+ const DFBWindowDescription *desc,
+ CoreWindow **ret_window );
+
+CoreWindow *dfb_layer_context_find_window( CoreLayerContext *context,
+ DFBWindowID id );
+
+CoreWindowStack *dfb_layer_context_windowstack( const CoreLayerContext *context );
+
+bool dfb_layer_context_active ( const CoreLayerContext *context );
+
+/*
+ * Locking
+ */
+DirectResult dfb_layer_context_lock ( CoreLayerContext *context );
+DirectResult dfb_layer_context_unlock( CoreLayerContext *context );
+
+#endif
diff --git a/Source/DirectFB/src/core/layer_control.c b/Source/DirectFB/src/core/layer_control.c
new file mode 100755
index 0000000..b190cc5
--- /dev/null
+++ b/Source/DirectFB/src/core/layer_control.c
@@ -0,0 +1,589 @@
+/*
+ (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 <fusion/shmalloc.h>
+#include <fusion/arena.h>
+#include <fusion/property.h>
+
+#include <directfb.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/core_parts.h>
+
+#include <core/input.h>
+#include <core/gfxcard.h>
+#include <core/layer_context.h>
+#include <core/layer_control.h>
+#include <core/layer_region.h>
+#include <core/layers.h>
+#include <core/screen.h>
+#include <core/state.h>
+#include <core/palette.h>
+#include <core/system.h>
+#include <core/windows.h>
+
+#include <gfx/convert.h>
+#include <gfx/util.h>
+
+#include <misc/util.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+#include <core/layers_internal.h>
+
+
+D_DEBUG_DOMAIN( Core_Layers, "Core/Layers", "DirectFB Display Layer Core" );
+
+/** public **/
+
+DFBResult
+dfb_layer_suspend( CoreLayer *layer )
+{
+ CoreLayerShared *shared;
+ CoreLayerContexts *contexts;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+
+ shared = layer->shared;
+ contexts = &shared->contexts;
+
+ /* Lock the layer. */
+ if (fusion_skirmish_prevail( &shared->lock ))
+ return DFB_FUSION;
+
+ D_ASSUME( !shared->suspended );
+
+ if (shared->suspended) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_OK;
+ }
+
+ /* Deactivate current context. */
+ if (contexts->active >= 0) {
+ DFBResult ret;
+ CoreLayerContext *current = fusion_vector_at( &contexts->stack,
+ contexts->active );
+
+ ret = dfb_layer_context_deactivate( current );
+ if (ret) {
+ D_ERROR("DirectFB/Core/layer: "
+ "Could not deactivate current context of '%s'! (%s)\n",
+ shared->description.name, DirectFBErrorString( ret ));
+ }
+ }
+
+ shared->suspended = true;
+
+ /* Unlock the layer. */
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_resume( CoreLayer *layer )
+{
+ CoreLayerShared *shared;
+ CoreLayerContexts *contexts;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+
+ shared = layer->shared;
+ contexts = &shared->contexts;
+
+ /* Lock the layer. */
+ if (fusion_skirmish_prevail( &shared->lock ))
+ return DFB_FUSION;
+
+ D_ASSUME( shared->suspended );
+
+ if (!shared->suspended) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_OK;
+ }
+
+ /* (Re)Activate current context. */
+ if (contexts->active >= 0) {
+ DFBResult ret;
+ CoreLayerContext *current = fusion_vector_at( &contexts->stack,
+ contexts->active );
+
+ ret = dfb_layer_context_activate( current );
+ if (ret) {
+ D_ERROR("DirectFB/Core/layer: "
+ "Could not activate current context of '%s'! (%s)\n",
+ shared->description.name, DirectFBErrorString( ret ));
+ }
+ }
+
+ shared->suspended = false;
+
+ /* Unlock the layer. */
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_create_context( CoreLayer *layer,
+ CoreLayerContext **ret_context )
+{
+ DFBResult ret;
+ CoreLayerShared *shared;
+ CoreLayerContexts *contexts;
+ CoreLayerContext *context = NULL;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( ret_context != NULL );
+
+ shared = layer->shared;
+ contexts = &shared->contexts;
+
+ D_DEBUG_AT( Core_Layers, "%s (%s)\n", __FUNCTION__, shared->description.name );
+
+ /* Create the object. */
+ context = dfb_core_create_layer_context( layer->core );
+ if (!context)
+ return DFB_FUSION;
+
+ /* Lock the layer. */
+ if (fusion_skirmish_prevail( &shared->lock )) {
+ fusion_object_destroy( &context->object );
+ return DFB_FUSION;
+ }
+
+ /* Initialize the new context. */
+ ret = dfb_layer_context_init( context, layer );
+ if (ret) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return ret;
+ }
+
+ /* Add it to the context stack. */
+ if (fusion_vector_add( &contexts->stack, context )) {
+ dfb_layer_context_unref( context );
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_FUSION;
+ }
+
+ /* Unlock the layer. */
+ fusion_skirmish_dismiss( &shared->lock );
+
+ /* Return the context. */
+ *ret_context = context;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_get_active_context( CoreLayer *layer,
+ CoreLayerContext **ret_context )
+{
+ CoreLayerShared *shared;
+ CoreLayerContexts *contexts;
+ CoreLayerContext *context;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( ret_context != NULL );
+
+ shared = layer->shared;
+ contexts = &shared->contexts;
+
+ D_DEBUG_AT( Core_Layers, "%s (%s)\n", __FUNCTION__, shared->description.name );
+
+ /* Lock the layer. */
+ if (fusion_skirmish_prevail( &shared->lock ))
+ return DFB_FUSION;
+
+ /* Check for active context. */
+ if (contexts->active < 0) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_NOCONTEXT;
+ }
+
+ /* Fetch active context. */
+ context = fusion_vector_at( &contexts->stack, contexts->active );
+
+ /* Increase the context's reference counter. */
+ if (dfb_layer_context_ref( context )) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_FUSION;
+ }
+
+ D_DEBUG_AT( Core_Layers, " => %p [%4dx%4d %8s]\n", context,
+ context->config.width, context->config.height,
+ dfb_pixelformat_name( context->config.pixelformat ) );
+
+ /* Return the context. */
+ *ret_context = context;
+
+ /* Unlock the layer. */
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_get_primary_context( CoreLayer *layer,
+ bool activate,
+ CoreLayerContext **ret_context )
+{
+ DFBResult ret;
+ CoreLayerShared *shared;
+ CoreLayerContexts *contexts;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( ret_context != NULL );
+
+ shared = layer->shared;
+ contexts = &shared->contexts;
+
+ /* Lock the layer. */
+ if (fusion_skirmish_prevail( &shared->lock ))
+ return DFB_FUSION;
+
+ D_DEBUG_AT( Core_Layers, "%s (%s, %sactivate) <- active: %d\n",
+ __FUNCTION__, shared->description.name,
+ activate ? "" : "don't ", contexts->active );
+
+ /* Check for primary context. */
+ if (contexts->primary) {
+ /* Increase the context's reference counter. */
+ if (dfb_layer_context_ref( contexts->primary )) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_FUSION;
+ }
+ }
+ else {
+ CoreLayerContext *primary;
+
+ /* Unlock the layer. */
+ fusion_skirmish_dismiss( &shared->lock );
+
+ /* Create the primary (shared) context. */
+ ret = dfb_layer_create_context( layer, &primary );
+ if (ret)
+ return ret;
+
+ /* Lock the layer again. */
+ if (fusion_skirmish_prevail( &shared->lock )) {
+ dfb_layer_context_unref( primary );
+ return DFB_FUSION;
+ }
+
+ /* Check if there was a race. */
+ if (contexts->primary) {
+ /* Throw away ours, the other was faster. */
+ dfb_layer_context_unref( primary );
+
+ /* Increase the context's reference counter. */
+ if (dfb_layer_context_ref( contexts->primary )) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_FUSION;
+ }
+ }
+ else
+ contexts->primary = primary;
+ }
+
+ /* Activate if no context is active? */
+ if (contexts->active < 0 && activate) {
+ ret = dfb_layer_activate_context( layer, contexts->primary );
+ if (ret) {
+ dfb_layer_context_unref( contexts->primary );
+ fusion_skirmish_dismiss( &shared->lock );
+ return ret;
+ }
+ }
+
+ /* Return the context. */
+ *ret_context = contexts->primary;
+
+ /* Unlock the layer. */
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_activate_context( CoreLayer *layer,
+ CoreLayerContext *context )
+{
+ DFBResult ret = DFB_OK;
+ int index;
+ CoreLayerShared *shared;
+ CoreLayerContexts *ctxs;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( context != NULL );
+
+ shared = layer->shared;
+ ctxs = &shared->contexts;
+
+ /* Lock the layer. */
+ if (fusion_skirmish_prevail( &shared->lock ))
+ return DFB_FUSION;
+
+ D_DEBUG_AT( Core_Layers, "%s (%s, %p)\n", __FUNCTION__, shared->description.name, context );
+
+ D_ASSERT( fusion_vector_contains( &ctxs->stack, context ) );
+
+ /* Lookup the context in the context stack. */
+ index = fusion_vector_index_of( &ctxs->stack, context );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context )) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_FUSION;
+ }
+
+ /* Need to activate? */
+ if (ctxs->active != index) {
+ DFBResult ret;
+
+ /* Another context currently active? */
+ if (ctxs->active >= 0) {
+ CoreLayerContext *current = fusion_vector_at( &ctxs->stack,
+ ctxs->active );
+
+ /* Deactivate current context. */
+ if (!shared->suspended) {
+ ret = dfb_layer_context_deactivate( current );
+ if (ret)
+ goto error;
+ }
+
+ /* No active context. */
+ ctxs->active = -1;
+ }
+
+ /* Activate context now. */
+ if (!shared->suspended) {
+ ret = dfb_layer_context_activate( context );
+ if (ret)
+ goto error;
+ }
+
+ ctxs->active = index;
+ }
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ /* Unlock the layer. */
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DFB_OK;
+
+error:
+ dfb_layer_context_unlock( context );
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_remove_context( CoreLayer *layer,
+ CoreLayerContext *context )
+{
+ int index;
+ CoreLayerShared *shared;
+ CoreLayerContexts *ctxs;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( context != NULL );
+
+ shared = layer->shared;
+ ctxs = &shared->contexts;
+
+ /* Lock the layer. */
+ if (fusion_skirmish_prevail( &shared->lock ))
+ return DFB_FUSION;
+
+ D_DEBUG_AT( Core_Layers, "%s (%s, %p)\n", __FUNCTION__, shared->description.name, context );
+
+ D_ASSUME( fusion_vector_contains( &ctxs->stack, context ) );
+
+ /* Lookup the context in the context stack. */
+ index = fusion_vector_index_of( &ctxs->stack, context );
+ if (index < 0) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_OK;
+ }
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context )) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return DFB_FUSION;
+ }
+
+ /* Remove context from context stack. */
+ fusion_vector_remove( &ctxs->stack, index );
+
+ /* Check if the primary context is removed. */
+ if (context == ctxs->primary)
+ ctxs->primary = NULL;
+
+ /* Need to deactivate? */
+ if (ctxs->active == index) {
+ /* Deactivate the context. */
+ if (!shared->suspended)
+ dfb_layer_context_deactivate( context );
+
+ /* There's no active context anymore. */
+ ctxs->active = -1;
+
+ if (ctxs->primary)
+ D_ASSERT( fusion_vector_contains( &ctxs->stack, ctxs->primary ) );
+
+ if (fusion_vector_has_elements( &ctxs->stack )) {
+ CoreLayerContext *ctx;
+
+ /* Activate most recent context. */
+ index = fusion_vector_size( &ctxs->stack ) - 1;
+ ctx = fusion_vector_at( &ctxs->stack, index );
+
+ if (shared->suspended || dfb_layer_context_activate( ctx ) == DFB_OK)
+ ctxs->active = index;
+ }
+ }
+ else if (ctxs->active > index) {
+ /* Adjust index of active context due to the removed context. */
+ ctxs->active--;
+ }
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ /* Unlock the layer. */
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_get_current_output_field( CoreLayer *layer, int *field )
+{
+ DFBResult ret;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( field != NULL );
+
+ if (!layer->funcs->GetCurrentOutputField)
+ return DFB_UNSUPPORTED;
+
+ ret = layer->funcs->GetCurrentOutputField( layer, layer->driver_data,
+ layer->layer_data, field );
+ if (ret)
+ return ret;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_get_level( CoreLayer *layer, int *ret_level )
+{
+ const DisplayLayerFuncs *funcs;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( ret_level != NULL );
+
+ funcs = layer->funcs;
+
+ if (!funcs->GetLevel)
+ return DFB_UNSUPPORTED;
+
+ return funcs->GetLevel( layer, layer->driver_data,
+ layer->layer_data, ret_level );
+}
+
+DFBResult
+dfb_layer_set_level( CoreLayer *layer, int level )
+{
+ const DisplayLayerFuncs *funcs;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->funcs != NULL );
+
+ funcs = layer->funcs;
+
+ if (!funcs->SetLevel)
+ return DFB_UNSUPPORTED;
+
+ return funcs->SetLevel( layer, layer->driver_data,
+ layer->layer_data, level );
+}
+
+DFBResult
+dfb_layer_wait_vsync( CoreLayer *layer )
+{
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->screen != NULL );
+
+ return dfb_screen_wait_vsync( layer->screen );
+}
+
+DFBResult
+dfb_layer_get_source_info( CoreLayer *layer,
+ int source,
+ DFBDisplayLayerSourceDescription *ret_desc )
+{
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( source >= 0 );
+ D_ASSERT( source < layer->shared->description.sources );
+ D_ASSERT( ret_desc != NULL );
+
+ *ret_desc = layer->shared->sources[source].description;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/core/layer_control.h b/Source/DirectFB/src/core/layer_control.h
new file mode 100755
index 0000000..51b7ae2
--- /dev/null
+++ b/Source/DirectFB/src/core/layer_control.h
@@ -0,0 +1,72 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__LAYER_CONTROL_H__
+#define __CORE__LAYER_CONTROL_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+
+DFBResult dfb_layer_create_context ( CoreLayer *layer,
+ CoreLayerContext **ret_context );
+
+DFBResult dfb_layer_get_active_context ( CoreLayer *layer,
+ CoreLayerContext **ret_context );
+
+DFBResult dfb_layer_get_primary_context ( CoreLayer *layer,
+ bool activate,
+ CoreLayerContext **ret_context );
+
+DFBResult dfb_layer_activate_context ( CoreLayer *layer,
+ CoreLayerContext *context );
+
+DFBResult dfb_layer_remove_context ( CoreLayer *layer,
+ CoreLayerContext *context );
+
+DFBResult dfb_layer_suspend ( CoreLayer *layer );
+DFBResult dfb_layer_resume ( CoreLayer *layer );
+
+
+DFBResult dfb_layer_get_current_output_field( CoreLayer *layer,
+ int *field );
+
+DFBResult dfb_layer_get_level ( CoreLayer *layer,
+ int *ret_level );
+
+DFBResult dfb_layer_set_level ( CoreLayer *layer,
+ int level );
+
+DFBResult dfb_layer_wait_vsync ( CoreLayer *layer );
+
+DFBResult dfb_layer_get_source_info ( CoreLayer *layer,
+ int source,
+ DFBDisplayLayerSourceDescription *ret_desc );
+
+#endif
diff --git a/Source/DirectFB/src/core/layer_region.c b/Source/DirectFB/src/core/layer_region.c
new file mode 100755
index 0000000..b96e742
--- /dev/null
+++ b/Source/DirectFB/src/core/layer_region.c
@@ -0,0 +1,1129 @@
+/*
+ (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 <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/gfxcard.h>
+#include <core/layer_context.h>
+#include <core/layer_control.h>
+#include <core/layer_region.h>
+#include <core/layers_internal.h>
+#include <core/surface.h>
+
+#include <gfx/util.h>
+
+
+D_DEBUG_DOMAIN( Core_Layers, "Core/Layers", "DirectFB Display Layer Core" );
+
+
+static DFBResult region_buffer_lock( CoreLayerRegion *region,
+ CoreSurface *surface,
+ CoreSurfaceBufferRole role );
+
+static DFBResult set_region ( CoreLayerRegion *region,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags flags,
+ CoreSurface *surface );
+
+static DFBResult realize_region ( CoreLayerRegion *region );
+
+static DFBResult unrealize_region( CoreLayerRegion *region );
+
+/******************************************************************************/
+
+static void
+region_destructor( FusionObject *object, bool zombie, void *ctx )
+{
+ CoreLayerRegion *region = (CoreLayerRegion*) object;
+ CoreLayerContext *context = region->context;
+ CoreLayer *layer = dfb_layer_at( context->layer_id );
+ CoreLayerShared *shared = layer->shared;
+
+ D_DEBUG_AT( Core_Layers, "destroying region %p (%s, %dx%d, "
+ "%s, %s, %s, %s%s)\n", region, shared->description.name,
+ region->config.width, region->config.height,
+ D_FLAGS_IS_SET( region->state,
+ CLRSF_CONFIGURED ) ? "configured" : "unconfigured",
+ D_FLAGS_IS_SET( region->state,
+ CLRSF_ENABLED ) ? "enabled" : "disabled",
+ D_FLAGS_IS_SET( region->state,
+ CLRSF_ACTIVE ) ? "active" : "inactive",
+ D_FLAGS_IS_SET( region->state,
+ CLRSF_REALIZED ) ? "realized" : "not realized",
+ zombie ? " - ZOMBIE" : "" );
+
+ /* Hide region etc. */
+ if (D_FLAGS_IS_SET( region->state, CLRSF_ENABLED ))
+ dfb_layer_region_disable( region );
+
+ /* Remove the region from the context. */
+ dfb_layer_context_remove_region( region->context, region );
+
+ /* Throw away its surface. */
+ if (region->surface) {
+ /* Detach the global listener. */
+ dfb_surface_detach_global( region->surface,
+ &region->surface_reaction );
+
+ /* Unlink from structure. */
+ dfb_surface_unlink( &region->surface );
+ }
+
+ /* Unlink the context from the structure. */
+ dfb_layer_context_unlink( &region->context );
+
+ /* Free driver's region data. */
+ if (region->region_data)
+ SHFREE( shared->shmpool, region->region_data );
+
+ /* Deinitialize the lock. */
+ fusion_skirmish_destroy( &region->lock );
+
+ /* Destroy the object. */
+ fusion_object_destroy( object );
+}
+
+/******************************************************************************/
+
+FusionObjectPool *
+dfb_layer_region_pool_create( const FusionWorld *world )
+{
+ return fusion_object_pool_create( "Layer Region Pool",
+ sizeof(CoreLayerRegion),
+ sizeof(CoreLayerRegionNotification),
+ region_destructor, NULL, world );
+}
+
+/******************************************************************************/
+
+DFBResult
+dfb_layer_region_create( CoreLayerContext *context,
+ CoreLayerRegion **ret_region )
+{
+ CoreLayer *layer;
+ CoreLayerRegion *region;
+
+ D_ASSERT( context != NULL );
+ D_ASSERT( ret_region != NULL );
+
+ layer = dfb_layer_at( context->layer_id );
+
+ /* Create the object. */
+ region = dfb_core_create_layer_region( layer->core );
+ if (!region)
+ return DFB_FUSION;
+
+ /* Link the context into the structure. */
+ if (dfb_layer_context_link( &region->context, context )) {
+ fusion_object_destroy( &region->object );
+ return DFB_FUSION;
+ }
+
+ /* Initialize the lock. */
+ if (fusion_skirmish_init( &region->lock, "Layer Region", dfb_core_world(layer->core) )) {
+ dfb_layer_context_unlink( &region->context );
+ fusion_object_destroy( &region->object );
+ return DFB_FUSION;
+ }
+
+ /* Change global reaction lock. */
+ fusion_object_set_lock( &region->object, &region->lock );
+
+ region->state = CLRSF_FROZEN;
+
+ /* Activate the object. */
+ fusion_object_activate( &region->object );
+
+ /* Add the region to the context. */
+ dfb_layer_context_add_region( context, region );
+
+ /* Return the new region. */
+ *ret_region = region;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_region_activate( CoreLayerRegion *region )
+{
+ DFBResult ret;
+
+ D_ASSERT( region != NULL );
+
+ /* Lock the region. */
+ if (dfb_layer_region_lock( region ))
+ return DFB_FUSION;
+
+ D_ASSUME( ! D_FLAGS_IS_SET( region->state, CLRSF_ACTIVE ) );
+
+ if (D_FLAGS_IS_SET( region->state, CLRSF_ACTIVE )) {
+ dfb_layer_region_unlock( region );
+ return DFB_OK;
+ }
+
+ /* Realize the region if it's enabled. */
+ if (D_FLAGS_IS_SET( region->state, CLRSF_ENABLED )) {
+ ret = realize_region( region );
+ if (ret) {
+ dfb_layer_region_unlock( region );
+ return ret;
+ }
+ }
+
+ /* Update the region's state. */
+ D_FLAGS_SET( region->state, CLRSF_ACTIVE );
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_region_deactivate( CoreLayerRegion *region )
+{
+ DFBResult ret;
+
+ D_ASSERT( region != NULL );
+
+ /* Lock the region. */
+ if (dfb_layer_region_lock( region ))
+ return DFB_FUSION;
+
+ D_ASSUME( D_FLAGS_IS_SET( region->state, CLRSF_ACTIVE ) );
+
+ if (! D_FLAGS_IS_SET( region->state, CLRSF_ACTIVE )) {
+ dfb_layer_region_unlock( region );
+ return DFB_OK;
+ }
+
+ /* Unrealize the region? */
+ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) {
+ ret = unrealize_region( region );
+ if (ret)
+ return ret;
+ }
+
+ /* Update the region's state. */
+ D_FLAGS_CLEAR( region->state, CLRSF_ACTIVE );
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_region_enable( CoreLayerRegion *region )
+{
+ DFBResult ret;
+
+ D_ASSERT( region != NULL );
+ D_ASSERT( region->context != NULL );
+
+ /* Lock the region. */
+ if (dfb_layer_region_lock( region ))
+ return DFB_FUSION;
+
+ D_ASSUME( ! D_FLAGS_IS_SET( region->state, CLRSF_ENABLED ) );
+
+ if (D_FLAGS_IS_SET( region->state, CLRSF_ENABLED )) {
+ dfb_layer_region_unlock( region );
+ return DFB_OK;
+ }
+
+ /* Realize the region if it's active. */
+ if (D_FLAGS_IS_SET( region->state, CLRSF_ACTIVE )) {
+ ret = realize_region( region );
+ if (ret) {
+ dfb_layer_region_unlock( region );
+ return ret;
+ }
+ }
+
+ /* Update the region's state. */
+ D_FLAGS_SET( region->state, CLRSF_ENABLED );
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_region_disable( CoreLayerRegion *region )
+{
+ DFBResult ret;
+
+ D_ASSERT( region != NULL );
+
+ /* Lock the region. */
+ if (dfb_layer_region_lock( region ))
+ return DFB_FUSION;
+
+ D_ASSUME( D_FLAGS_IS_SET( region->state, CLRSF_ENABLED ) );
+
+ if (! D_FLAGS_IS_SET( region->state, CLRSF_ENABLED )) {
+ dfb_layer_region_unlock( region );
+ return DFB_OK;
+ }
+
+ /* Unrealize the region? */
+ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) {
+ ret = unrealize_region( region );
+ if (ret)
+ return ret;
+ }
+
+ /* Update the region's state. */
+ D_FLAGS_CLEAR( region->state, CLRSF_ENABLED );
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_region_set_surface( CoreLayerRegion *region,
+ CoreSurface *surface )
+{
+ DFBResult ret;
+
+ D_ASSERT( region != NULL );
+ D_ASSERT( surface != NULL );
+
+ /* Lock the region. */
+ if (dfb_layer_region_lock( region ))
+ return DFB_FUSION;
+
+ if (region->surface != surface) {
+ /* Setup hardware for the new surface if the region is realized. */
+ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) {
+ ret = set_region( region, &region->config, CLRCF_SURFACE | CLRCF_PALETTE, surface );
+ if (ret) {
+ dfb_layer_region_unlock( region );
+ return ret;
+ }
+ }
+
+ /* Throw away the old surface. */
+ if (region->surface) {
+ /* Detach the global listener. */
+ dfb_surface_detach_global( region->surface,
+ &region->surface_reaction );
+
+ /* Unlink surface from structure. */
+ dfb_surface_unlink( &region->surface );
+ }
+
+ /* Take the new surface. */
+ if (surface) {
+ /* Link surface into structure. */
+ if (dfb_surface_link( &region->surface, surface )) {
+ D_WARN( "region lost it's surface" );
+ dfb_layer_region_unlock( region );
+ return DFB_FUSION;
+ }
+
+ /* Attach the global listener. */
+ dfb_surface_attach_global( region->surface,
+ DFB_LAYER_REGION_SURFACE_LISTENER,
+ region, &region->surface_reaction );
+ }
+ }
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_region_get_surface( CoreLayerRegion *region,
+ CoreSurface **ret_surface )
+{
+ D_ASSERT( region != NULL );
+ D_ASSERT( ret_surface != NULL );
+
+ /* Lock the region. */
+ if (dfb_layer_region_lock( region ))
+ return DFB_FUSION;
+
+ D_ASSUME( region->surface != NULL );
+
+ /* Check for NULL surface. */
+ if (!region->surface) {
+ dfb_layer_region_unlock( region );
+ return DFB_UNSUPPORTED;
+ }
+
+ /* Increase the surface's reference counter. */
+ if (dfb_surface_ref( region->surface )) {
+ dfb_layer_region_unlock( region );
+ return DFB_FUSION;
+ }
+
+ /* Return the surface. */
+ *ret_surface = region->surface;
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_region_flip_update( CoreLayerRegion *region,
+ const DFBRegion *update,
+ DFBSurfaceFlipFlags flags )
+{
+ DFBResult ret = DFB_OK;
+ DFBRegion unrotated;
+ DFBRegion rotated;
+ CoreLayer *layer;
+ CoreLayerContext *context;
+ CoreSurface *surface;
+ const DisplayLayerFuncs *funcs;
+
+ if (update)
+ D_DEBUG_AT( Core_Layers,
+ "dfb_layer_region_flip_update( %p, %p, 0x%08x ) <- [%d, %d - %dx%d]\n",
+ region, update, flags, DFB_RECTANGLE_VALS_FROM_REGION( update ) );
+ else
+ D_DEBUG_AT( Core_Layers,
+ "dfb_layer_region_flip_update( %p, %p, 0x%08x )\n", region, update, flags );
+
+
+ D_ASSERT( region != NULL );
+ D_ASSERT( region->context != NULL );
+
+ /* Lock the region. */
+ if (dfb_layer_region_lock( region ))
+ return DFB_FUSION;
+
+ D_ASSUME( region->surface != NULL );
+
+ /* Check for NULL surface. */
+ if (!region->surface) {
+ D_DEBUG_AT( Core_Layers, " -> No surface => no update!\n" );
+ dfb_layer_region_unlock( region );
+ return DFB_UNSUPPORTED;
+ }
+
+ context = region->context;
+ surface = region->surface;
+ layer = dfb_layer_at( context->layer_id );
+
+ D_ASSERT( layer->funcs != NULL );
+
+ funcs = layer->funcs;
+
+ /* Unfreeze region? */
+ if (D_FLAGS_IS_SET( region->state, CLRSF_FROZEN )) {
+ D_FLAGS_CLEAR( region->state, CLRSF_FROZEN );
+
+ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) {
+ ret = set_region( region, &region->config, CLRCF_ALL, surface );
+ if (ret)
+ D_DERROR( ret, "Core/LayerRegion: set_region() in dfb_layer_region_flip_update() failed!\n" );
+ }
+ else if (D_FLAGS_ARE_SET( region->state, CLRSF_ENABLED | CLRSF_ACTIVE )) {
+ ret = realize_region( region );
+ if (ret)
+ D_DERROR( ret, "Core/LayerRegion: realize_region() in dfb_layer_region_flip_update() failed!\n" );
+ }
+
+ if (ret) {
+ dfb_layer_region_unlock( region );
+ return ret;
+ }
+ }
+
+ /* Depending on the buffer mode... */
+ switch (region->config.buffermode) {
+ case DLBM_TRIPLE:
+ case DLBM_BACKVIDEO:
+ /* Check if simply swapping the buffers is possible... */
+ if (!(flags & DSFLIP_BLIT) && !surface->rotation &&
+ (!update || (update->x1 == 0 &&
+ update->y1 == 0 &&
+ update->x2 == surface->config.size.w - 1 &&
+ update->y2 == surface->config.size.h - 1)))
+ {
+ D_DEBUG_AT( Core_Layers, " -> Going to swap buffers...\n" );
+
+ /* Use the driver's routine if the region is realized. */
+ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) {
+ D_ASSUME( funcs->FlipRegion != NULL );
+
+ ret = region_buffer_lock( region, surface, CSBR_BACK );
+ if (ret) {
+ dfb_layer_region_unlock( region );
+ return ret;
+ }
+
+ D_DEBUG_AT( Core_Layers, " -> Flipping region using driver...\n" );
+
+ if (funcs->FlipRegion)
+ ret = funcs->FlipRegion( layer,
+ layer->driver_data,
+ layer->layer_data,
+ region->region_data,
+ surface, flags, &region->surface_lock );
+
+ dfb_surface_unlock( surface );
+ }
+ else {
+ D_DEBUG_AT( Core_Layers, " -> Flipping region not using driver...\n" );
+
+ /* Just do the hardware independent work. */
+ dfb_surface_lock( surface );
+ dfb_surface_flip( surface, false );
+ dfb_surface_unlock( surface );
+ }
+ break;
+ }
+
+ /* fall through */
+
+ case DLBM_BACKSYSTEM:
+ D_DEBUG_AT( Core_Layers, " -> Going to copy portion...\n" );
+
+ if ((flags & DSFLIP_WAITFORSYNC) == DSFLIP_WAITFORSYNC) {
+ D_DEBUG_AT( Core_Layers, " -> Waiting for VSync...\n" );
+
+ dfb_layer_wait_vsync( layer );
+ }
+
+ D_DEBUG_AT( Core_Layers, " -> Copying content from back to front buffer...\n" );
+
+ /* ...or copy updated contents from back to front buffer. */
+ dfb_back_to_front_copy_rotation( surface, update, surface->rotation );
+
+ if ((flags & DSFLIP_WAITFORSYNC) == DSFLIP_WAIT) {
+ D_DEBUG_AT( Core_Layers, " -> Waiting for VSync...\n" );
+
+ dfb_layer_wait_vsync( layer );
+ }
+
+ /* fall through */
+
+ case DLBM_FRONTONLY:
+ /* Tell the driver about the update if the region is realized. */
+ if (funcs->UpdateRegion && D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) {
+ if (surface) {
+ CoreSurfaceAllocation *allocation;
+
+ allocation = region->surface_lock.allocation;
+ D_ASSERT( allocation != NULL );
+
+ /* If hardware has written or is writing... */
+ if (allocation->accessed[CSAID_GPU] & CSAF_WRITE) {
+ D_DEBUG_AT( Core_Layers, " -> Waiting for pending writes...\n" );
+
+ /* ...wait for the operation to finish. */
+ if (!(flags & DSFLIP_PIPELINE))
+ dfb_gfxcard_sync(); /* TODO: wait for serial instead */
+
+ allocation->accessed[CSAID_GPU] &= ~CSAF_WRITE;
+ }
+
+ dfb_surface_lock( surface );
+ dfb_surface_allocation_update( allocation, CSAF_READ );
+ dfb_surface_unlock( surface );
+ }
+
+ D_DEBUG_AT( Core_Layers, " -> Notifying driver about updated content...\n" );
+
+ if( !update ) {
+ unrotated = DFB_REGION_INIT_FROM_RECTANGLE_VALS( 0, 0,
+ region->config.width, region->config.height );
+ update = &unrotated;
+ }
+ dfb_region_from_rotated( &rotated, update, &surface->config.size, surface->rotation );
+
+ ret = funcs->UpdateRegion( layer,
+ layer->driver_data,
+ layer->layer_data,
+ region->region_data,
+ surface, &rotated, &region->surface_lock );
+ }
+ break;
+
+ default:
+ D_BUG("unknown buffer mode");
+ ret = DFB_BUG;
+ }
+
+ D_DEBUG_AT( Core_Layers, " -> done.\n" );
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ return ret;
+}
+
+DFBResult
+dfb_layer_region_set_configuration( CoreLayerRegion *region,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags flags )
+{
+ DFBResult ret;
+ CoreLayer *layer;
+ const DisplayLayerFuncs *funcs;
+ CoreLayerRegionConfig new_config;
+
+ D_ASSERT( region != NULL );
+ D_ASSERT( region->context != NULL );
+ D_ASSERT( config != NULL );
+ D_ASSERT( config->buffermode != DLBM_WINDOWS );
+ D_ASSERT( (flags == CLRCF_ALL) || (region->state & CLRSF_CONFIGURED) );
+
+ D_ASSUME( flags != CLRCF_NONE );
+ D_ASSUME( ! (flags & ~CLRCF_ALL) );
+
+ layer = dfb_layer_at( region->context->layer_id );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( layer->funcs->TestRegion != NULL );
+
+ funcs = layer->funcs;
+
+ /* Lock the region. */
+ if (dfb_layer_region_lock( region ))
+ return DFB_FUSION;
+
+ /* Full configuration supplied? */
+ if (flags == CLRCF_ALL) {
+ new_config = *config;
+ }
+ else {
+ /* Use the current configuration. */
+ new_config = region->config;
+
+ /* Update each modified entry. */
+ if (flags & CLRCF_WIDTH)
+ new_config.width = config->width;
+
+ if (flags & CLRCF_HEIGHT)
+ new_config.height = config->height;
+
+ if (flags & CLRCF_FORMAT)
+ new_config.format = config->format;
+
+ if (flags & CLRCF_SURFACE_CAPS)
+ new_config.surface_caps = config->surface_caps;
+
+ if (flags & CLRCF_BUFFERMODE)
+ new_config.buffermode = config->buffermode;
+
+ if (flags & CLRCF_OPTIONS)
+ new_config.options = config->options;
+
+ if (flags & CLRCF_SOURCE_ID)
+ new_config.source_id = config->source_id;
+
+ if (flags & CLRCF_SOURCE)
+ new_config.source = config->source;
+
+ if (flags & CLRCF_DEST)
+ new_config.dest = config->dest;
+
+ if (flags & CLRCF_OPACITY)
+ new_config.opacity = config->opacity;
+
+ if (flags & CLRCF_ALPHA_RAMP) {
+ new_config.alpha_ramp[0] = config->alpha_ramp[0];
+ new_config.alpha_ramp[1] = config->alpha_ramp[1];
+ new_config.alpha_ramp[2] = config->alpha_ramp[2];
+ new_config.alpha_ramp[3] = config->alpha_ramp[3];
+ }
+
+ if (flags & CLRCF_SRCKEY)
+ new_config.src_key = config->src_key;
+
+ if (flags & CLRCF_DSTKEY)
+ new_config.dst_key = config->dst_key;
+
+ if (flags & CLRCF_PARITY)
+ new_config.parity = config->parity;
+
+ if (flags & CLRCF_CLIPS) {
+ new_config.clips = config->clips;
+ new_config.num_clips = config->num_clips;
+ new_config.positive = config->positive;
+ }
+ }
+
+ /* Check if the new configuration is supported. */
+ ret = funcs->TestRegion( layer, layer->driver_data, layer->layer_data,
+ &new_config, NULL );
+ if (ret) {
+ dfb_layer_region_unlock( region );
+ return ret;
+ }
+
+ /* Check if the region should be frozen, thus requiring to apply changes explicitly. */
+ if (flags & CLRCF_FREEZE)
+ region->state |= CLRSF_FROZEN;
+
+ /* Propagate new configuration to the driver if the region is realized. */
+ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) {
+ ret = set_region( region, &new_config, flags, region->surface );
+ if (ret) {
+ dfb_layer_region_unlock( region );
+ return ret;
+ }
+ }
+
+ /* Update the region's current configuration. */
+ region->config = new_config;
+
+ /* Update the region's state. */
+ D_FLAGS_SET( region->state, CLRSF_CONFIGURED );
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_layer_region_get_configuration( CoreLayerRegion *region,
+ CoreLayerRegionConfig *config )
+{
+ D_ASSERT( region != NULL );
+ D_ASSERT( config != NULL );
+
+ D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_CONFIGURED ) );
+
+ /* Lock the region. */
+ if (dfb_layer_region_lock( region ))
+ return DFB_FUSION;
+
+ /* Return the current configuration. */
+ *config = region->config;
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ return DFB_OK;
+}
+
+DirectResult
+dfb_layer_region_lock( CoreLayerRegion *region )
+{
+ D_ASSERT( region != NULL );
+
+ return fusion_skirmish_prevail( &region->lock );
+}
+
+DirectResult
+dfb_layer_region_unlock( CoreLayerRegion *region )
+{
+ D_ASSERT( region != NULL );
+
+ return fusion_skirmish_dismiss( &region->lock );
+}
+
+/******************************************************************************/
+
+/*
+ * listen to the layer's surface
+ */
+ReactionResult
+_dfb_layer_region_surface_listener( const void *msg_data, void *ctx )
+{
+ CoreSurfaceNotificationFlags flags;
+ CoreSurface *surface;
+ CoreLayer *layer;
+ CoreLayerShared *shared;
+ const DisplayLayerFuncs *funcs;
+ const CoreSurfaceNotification *notification = msg_data;
+ CoreLayerRegion *region = ctx;
+
+ D_ASSERT( notification != NULL );
+ D_ASSERT( region != NULL );
+ D_ASSERT( region->context != NULL );
+
+ D_DEBUG_AT( Core_Layers, "_dfb_layer_region_surface_listener( %p, %p ) <- 0x%08x\n",
+ notification, region, notification->flags );
+
+ D_ASSERT( notification->surface != NULL );
+
+ D_ASSUME( notification->surface == region->surface );
+
+ if (notification->surface != region->surface)
+ return RS_OK;
+
+ layer = dfb_layer_at( region->context->layer_id );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( layer->funcs->SetRegion != NULL );
+ D_ASSERT( layer->shared != NULL );
+
+ funcs = layer->funcs;
+ shared = layer->shared;
+
+ flags = notification->flags;
+ surface = notification->surface;
+
+ if (flags & CSNF_DESTROY) {
+ D_WARN( "layer region surface destroyed" );
+ region->surface = NULL;
+ return RS_REMOVE;
+ }
+
+ if (dfb_layer_region_lock( region ))
+ return RS_OK;
+
+ if (D_FLAGS_ARE_SET( region->state, CLRSF_REALIZED | CLRSF_CONFIGURED ) &&
+ !D_FLAGS_IS_SET( region->state, CLRSF_FROZEN ))
+ {
+ if (D_FLAGS_IS_SET( flags, CSNF_PALETTE_CHANGE | CSNF_PALETTE_UPDATE )) {
+ if (surface->palette)
+ funcs->SetRegion( layer,
+ layer->driver_data, layer->layer_data,
+ region->region_data, &region->config,
+ CLRCF_PALETTE, surface, surface->palette,
+ &region->surface_lock );
+ }
+
+ if ((flags & CSNF_FIELD) && funcs->SetInputField)
+ funcs->SetInputField( layer,
+ layer->driver_data, layer->layer_data,
+ region->region_data, surface->field );
+
+ if ((flags & CSNF_ALPHA_RAMP) && (shared->description.caps & DLCAPS_ALPHA_RAMP)) {
+ region->config.alpha_ramp[0] = surface->alpha_ramp[0];
+ region->config.alpha_ramp[1] = surface->alpha_ramp[1];
+ region->config.alpha_ramp[2] = surface->alpha_ramp[2];
+ region->config.alpha_ramp[3] = surface->alpha_ramp[3];
+
+ funcs->SetRegion( layer,
+ layer->driver_data, layer->layer_data,
+ region->region_data, &region->config,
+ CLRCF_ALPHA_RAMP, surface, surface->palette,
+ &region->surface_lock );
+ }
+ }
+
+ dfb_layer_region_unlock( region );
+
+ return RS_OK;
+}
+
+/******************************************************************************/
+
+static DFBResult
+region_buffer_lock( CoreLayerRegion *region,
+ CoreSurface *surface,
+ CoreSurfaceBufferRole role )
+{
+ DFBResult ret;
+ CoreSurfaceBuffer *buffer;
+ CoreSurfaceAllocation *allocation;
+ CoreLayerContext *context;
+
+ D_ASSERT( region != NULL );
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ context = region->context;
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ /* First unlock any previously locked buffer. */
+ if (region->surface_lock.buffer) {
+ D_MAGIC_ASSERT( region->surface_lock.buffer, CoreSurfaceBuffer );
+
+ dfb_surface_unlock_buffer( region->surface_lock.buffer->surface, &region->surface_lock );
+ }
+
+ if (dfb_surface_lock( surface ))
+ return DFB_FUSION;
+
+ buffer = dfb_surface_get_buffer( surface, role );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ /* Lock the surface buffer. */
+ ret = dfb_surface_buffer_lock( buffer, CSAID_LAYER0 + context->layer_id, CSAF_READ, &region->surface_lock );
+ if (ret) {
+ D_DERROR( ret, "Core/LayerRegion: Could not lock region surface for SetRegion()!\n" );
+ dfb_surface_unlock( surface );
+ return ret;
+ }
+
+ allocation = region->surface_lock.allocation;
+ D_ASSERT( allocation != NULL );
+
+ /* If hardware has written or is writing... */
+ if (allocation->accessed[CSAID_GPU] & CSAF_WRITE) {
+ D_DEBUG_AT( Core_Layers, " -> Waiting for pending writes...\n" );
+
+ /* ...wait for the operation to finish. */
+ dfb_gfxcard_sync(); /* TODO: wait for serial instead */
+
+ allocation->accessed[CSAID_GPU] &= ~CSAF_WRITE;
+ }
+
+ /* surface is unlocked by caller */
+
+ return DFB_OK;
+}
+
+static DFBResult
+set_region( CoreLayerRegion *region,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags flags,
+ CoreSurface *surface )
+{
+ DFBResult ret;
+ CoreLayer *layer;
+ CoreLayerShared *shared;
+ const DisplayLayerFuncs *funcs;
+
+ D_DEBUG_AT( Core_Layers, "%s( %p, %p, 0x%08x, %p )\n", __FUNCTION__, region, config, flags, surface );
+
+ DFB_CORE_LAYER_REGION_CONFIG_DEBUG_AT( Core_Layers, config );
+
+ D_DEBUG_AT( Core_Layers, " -> state 0x%08x\n", region->state );
+
+ D_ASSERT( region != NULL );
+ D_ASSERT( region->context != NULL );
+ D_ASSERT( config != NULL );
+ D_ASSERT( config->buffermode != DLBM_WINDOWS );
+
+ D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) );
+
+ layer = dfb_layer_at( region->context->layer_id );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( layer->funcs != NULL );
+ D_ASSERT( layer->funcs->SetRegion != NULL );
+
+ if (region->state & CLRSF_FROZEN) {
+ D_DEBUG_AT( Core_Layers, " -> FROZEN!\n" );
+ return DFB_OK;
+ }
+
+ shared = layer->shared;
+ funcs = layer->funcs;
+
+ if (surface) {
+ if (flags & (CLRCF_SURFACE | CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_FORMAT)) {
+ ret = region_buffer_lock( region, surface, CSBR_FRONT );
+ if (ret)
+ return ret;
+
+ dfb_surface_unlock( surface );
+ }
+
+ D_ASSERT( region->surface_lock.buffer != NULL );
+ }
+ else if (region->surface_lock.buffer) {
+ D_MAGIC_ASSERT( region->surface_lock.buffer, CoreSurfaceBuffer );
+
+ dfb_surface_unlock_buffer( region->surface_lock.buffer->surface, &region->surface_lock );
+ }
+
+ D_DEBUG_AT( Core_Layers, " => setting region of '%s'\n", shared->description.name );
+
+ /* Setup hardware. */
+ return funcs->SetRegion( layer, layer->driver_data, layer->layer_data,
+ region->region_data, config, flags,
+ surface, surface ? surface->palette : NULL, &region->surface_lock );
+}
+
+static DFBResult
+realize_region( CoreLayerRegion *region )
+{
+ DFBResult ret;
+ CoreLayer *layer;
+ CoreLayerShared *shared;
+ const DisplayLayerFuncs *funcs;
+
+ D_DEBUG_AT( Core_Layers, "%s( %p )\n", __FUNCTION__, region );
+
+ D_ASSERT( region != NULL );
+
+ DFB_CORE_LAYER_REGION_CONFIG_DEBUG_AT( Core_Layers, &region->config );
+
+ D_DEBUG_AT( Core_Layers, " -> state 0x%08x\n", region->state );
+
+ D_ASSERT( region->context != NULL );
+ D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_CONFIGURED ) );
+ D_ASSERT( ! D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) );
+
+ layer = dfb_layer_at( region->context->layer_id );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( layer->funcs != NULL );
+
+ shared = layer->shared;
+ funcs = layer->funcs;
+
+ D_ASSERT( ! fusion_vector_contains( &shared->added_regions, region ) );
+
+ if (region->state & CLRSF_FROZEN) {
+ D_DEBUG_AT( Core_Layers, " -> FROZEN!\n" );
+ return DFB_OK;
+ }
+
+ /* Allocate the driver's region data. */
+ if (funcs->RegionDataSize) {
+ int size = funcs->RegionDataSize();
+
+ if (size > 0) {
+ region->region_data = SHCALLOC( shared->shmpool, 1, size );
+ if (!region->region_data)
+ return D_OOSHM();
+ }
+ }
+
+ D_DEBUG_AT( Core_Layers, " => adding region to '%s'\n", shared->description.name );
+
+ /* Add the region to the driver. */
+ if (funcs->AddRegion) {
+ ret = funcs->AddRegion( layer,
+ layer->driver_data, layer->layer_data,
+ region->region_data, &region->config );
+ if (ret) {
+ D_DERROR( ret, "Core/Layers: Could not add region!\n" );
+
+ if (region->region_data) {
+ SHFREE( shared->shmpool, region->region_data );
+ region->region_data = NULL;
+ }
+
+ return ret;
+ }
+ }
+
+ /* Add the region to the 'added' list. */
+ fusion_vector_add( &shared->added_regions, region );
+
+ /* Update the region's state. */
+ D_FLAGS_SET( region->state, CLRSF_REALIZED );
+
+ /* Initially setup hardware. */
+ ret = set_region( region, &region->config, CLRCF_ALL, region->surface );
+ if (ret) {
+ unrealize_region( region );
+ return ret;
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+unrealize_region( CoreLayerRegion *region )
+{
+ DFBResult ret;
+ int index;
+ CoreLayer *layer;
+ CoreLayerShared *shared;
+ const DisplayLayerFuncs *funcs;
+
+ D_DEBUG_AT( Core_Layers, "%s( %p )\n", __FUNCTION__, region );
+
+ D_ASSERT( region != NULL );
+
+ DFB_CORE_LAYER_REGION_CONFIG_DEBUG_AT( Core_Layers, &region->config );
+
+ D_DEBUG_AT( Core_Layers, " -> state 0x%08x\n", region->state );
+
+ D_ASSERT( region->context != NULL );
+ D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) );
+
+ layer = dfb_layer_at( region->context->layer_id );
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( layer->funcs != NULL );
+
+ shared = layer->shared;
+ funcs = layer->funcs;
+
+ D_ASSERT( fusion_vector_contains( &shared->added_regions, region ) );
+
+ index = fusion_vector_index_of( &shared->added_regions, region );
+
+ D_DEBUG_AT( Core_Layers, " => removing region from '%s'\n", shared->description.name );
+
+ /* Remove the region from hardware and driver. */
+ if (funcs->RemoveRegion) {
+ ret = funcs->RemoveRegion( layer, layer->driver_data,
+ layer->layer_data, region->region_data );
+ if (ret) {
+ D_DERROR( ret, "Core/Layers: Could not remove region!\n" );
+ return ret;
+ }
+ }
+
+ /* Remove the region from the 'added' list. */
+ fusion_vector_remove( &shared->added_regions, index );
+
+ /* Deallocate the driver's region data. */
+ if (region->region_data) {
+ SHFREE( shared->shmpool, region->region_data );
+ region->region_data = NULL;
+ }
+
+ /* Update the region's state. */
+ D_FLAGS_CLEAR( region->state, CLRSF_REALIZED );
+ D_FLAGS_SET( region->state, CLRSF_FROZEN );
+
+ if (region->surface && region->surface_lock.buffer) {
+ dfb_surface_unlock_buffer( region->surface, &region->surface_lock );
+ // PR brg36mgr#147044: [550r3cr1][CRASH][UI]set crashes when going through settings assistant
+ // This is because the YUV layer buffer is allocated in memory recuperated from the video flow
+ // and is only valid in the JPEG usecase.
+ // When the application destroys its window (on leaving the usecase),the layer buffer must
+ // also be removed.
+ dfb_surface_destroy_buffers( region->surface );
+ }
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/core/layer_region.h b/Source/DirectFB/src/core/layer_region.h
new file mode 100755
index 0000000..29221a9
--- /dev/null
+++ b/Source/DirectFB/src/core/layer_region.h
@@ -0,0 +1,100 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__LAYER_REGION_H__
+#define __CORE__LAYER_REGION_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+#include <core/layers.h>
+
+#include <fusion/object.h>
+
+
+typedef enum {
+ CLRNF_NONE = 0x00000000
+} CoreLayerRegionNotificationFlags;
+
+typedef struct {
+ CoreLayerRegionNotificationFlags flags;
+ CoreLayerRegion *region;
+} CoreLayerRegionNotification;
+
+/*
+ * Creates a pool of layer region objects.
+ */
+FusionObjectPool *dfb_layer_region_pool_create( const FusionWorld *world );
+
+/*
+ * Generates dfb_layer_region_ref(), dfb_layer_region_attach() etc.
+ */
+FUSION_OBJECT_METHODS( CoreLayerRegion, dfb_layer_region )
+
+
+DFBResult dfb_layer_region_create ( CoreLayerContext *context,
+ CoreLayerRegion **ret_region );
+
+DFBResult dfb_layer_region_activate ( CoreLayerRegion *region );
+
+DFBResult dfb_layer_region_deactivate ( CoreLayerRegion *region );
+
+DFBResult dfb_layer_region_enable ( CoreLayerRegion *region );
+
+DFBResult dfb_layer_region_disable ( CoreLayerRegion *region );
+
+DFBResult dfb_layer_region_set_surface ( CoreLayerRegion *region,
+ CoreSurface *surface );
+
+DFBResult dfb_layer_region_get_surface ( CoreLayerRegion *region,
+ CoreSurface **ret_surface );
+
+DFBResult dfb_layer_region_flip_update ( CoreLayerRegion *region,
+ const DFBRegion *update,
+ DFBSurfaceFlipFlags flags );
+
+
+/*
+ * Configuration
+ */
+DFBResult dfb_layer_region_set_configuration( CoreLayerRegion *region,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags flags );
+
+DFBResult dfb_layer_region_get_configuration( CoreLayerRegion *region,
+ CoreLayerRegionConfig *config );
+
+
+/*
+ * Locking
+ */
+DirectResult dfb_layer_region_lock ( CoreLayerRegion *region );
+DirectResult dfb_layer_region_unlock( CoreLayerRegion *region );
+
+#endif
+
diff --git a/Source/DirectFB/src/core/layers.c b/Source/DirectFB/src/core/layers.c
new file mode 100755
index 0000000..29c0de8
--- /dev/null
+++ b/Source/DirectFB/src/core/layers.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 <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+#include <fusion/shmalloc.h>
+#include <fusion/arena.h>
+#include <fusion/property.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/core_parts.h>
+
+#include <core/input.h>
+#include <core/gfxcard.h>
+#include <core/layer_context.h>
+#include <core/layer_control.h>
+#include <core/layer_region.h>
+#include <core/layers.h>
+#include <core/state.h>
+#include <core/palette.h>
+#include <core/system.h>
+#include <core/windows.h>
+
+#include <gfx/convert.h>
+#include <gfx/util.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+#include <core/layers_internal.h>
+#include <core/screens_internal.h>
+
+
+D_DEBUG_DOMAIN( Core_Layer, "Core/Layer", "DirectFB Display Layer Core" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+ int num;
+ CoreLayerShared *layers[MAX_LAYERS];
+} DFBLayerCoreShared;
+
+struct __DFB_DFBLayerCore {
+ int magic;
+
+ CoreDFB *core;
+
+ DFBLayerCoreShared *shared;
+};
+
+
+DFB_CORE_PART( layer_core, LayerCore );
+
+/**********************************************************************************************************************/
+
+static int dfb_num_layers;
+static CoreLayer *dfb_layers[MAX_LAYERS];
+
+/** FIXME: Add proper error paths! **/
+
+static DFBResult
+dfb_layer_core_initialize( CoreDFB *core,
+ DFBLayerCore *data,
+ DFBLayerCoreShared *shared )
+{
+ int i;
+ DFBResult ret;
+ FusionSHMPoolShared *pool;
+
+ D_DEBUG_AT( Core_Layer, "dfb_layer_core_initialize( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( shared != NULL );
+
+ data->core = core;
+ data->shared = shared;
+
+
+ pool = dfb_core_shmpool( core );
+
+ /* Initialize all registered layers. */
+ for (i=0; i<dfb_num_layers; i++) {
+ char buf[24];
+ CoreLayerShared *lshared;
+ CoreLayer *layer = dfb_layers[i];
+ const DisplayLayerFuncs *funcs = layer->funcs;
+
+ /* Allocate shared data. */
+ lshared = SHCALLOC( pool, 1, sizeof(CoreLayerShared) );
+
+ /* Assign ID (zero based index). */
+ lshared->layer_id = i;
+ lshared->shmpool = pool;
+
+ snprintf( buf, sizeof(buf), "Display Layer %d", i );
+
+ /* Initialize the lock. */
+ ret = fusion_skirmish_init( &lshared->lock, buf, dfb_core_world(core) );
+ if (ret)
+ return ret;
+
+ /* Allocate driver's layer data. */
+ if (funcs->LayerDataSize) {
+ int size = funcs->LayerDataSize();
+
+ if (size > 0) {
+ lshared->layer_data = SHCALLOC( pool, 1, size );
+ if (!lshared->layer_data)
+ return D_OOSHM();
+ }
+ }
+
+ /* Initialize the layer, get the layer description,
+ the default configuration and default color adjustment. */
+ ret = funcs->InitLayer( layer,
+ layer->driver_data,
+ lshared->layer_data,
+ &lshared->description,
+ &lshared->default_config,
+ &lshared->default_adjustment );
+ if (ret) {
+ D_DERROR( ret, "DirectFB/Core/layers: "
+ "Failed to initialize layer %d!\n", lshared->layer_id );
+ return ret;
+ }
+
+ if (lshared->description.caps & DLCAPS_SOURCES) {
+ int n;
+
+ lshared->sources = SHCALLOC( pool, lshared->description.sources, sizeof(CoreLayerSource) );
+ if (!lshared->sources)
+ return D_OOSHM();
+
+ for (n=0; n<lshared->description.sources; n++) {
+ CoreLayerSource *source = &lshared->sources[n];
+
+ source->index = n;
+
+ ret = funcs->InitSource( layer, layer->driver_data,
+ lshared->layer_data, n, &source->description );
+ if (ret) {
+ D_DERROR( ret, "DirectFB/Core/layers: Failed to initialize source %d "
+ "of layer %d!\n", n, lshared->layer_id );
+ return ret;
+ }
+ }
+ }
+
+ if (D_FLAGS_IS_SET( lshared->description.caps, DLCAPS_SCREEN_LOCATION ))
+ D_FLAGS_SET( lshared->description.caps, DLCAPS_SCREEN_POSITION | DLCAPS_SCREEN_SIZE );
+
+ if (D_FLAGS_ARE_SET( lshared->description.caps,
+ DLCAPS_SCREEN_POSITION | DLCAPS_SCREEN_SIZE ))
+ D_FLAGS_SET( lshared->description.caps, DLCAPS_SCREEN_LOCATION );
+
+ /* Initialize the vector for the contexts. */
+ fusion_vector_init( &lshared->contexts.stack, 4, pool );
+
+ /* Initialize the vector for realized (added) regions. */
+ fusion_vector_init( &lshared->added_regions, 4, pool );
+
+ /* No active context by default. */
+ lshared->contexts.active = -1;
+
+ /* Store layer data. */
+ layer->layer_data = lshared->layer_data;
+
+ /* Store pointer to shared data and core. */
+ layer->shared = lshared;
+ layer->core = core;
+
+ /* Add the layer to the shared list. */
+ shared->layers[ shared->num++ ] = lshared;
+ }
+
+
+ D_MAGIC_SET( data, DFBLayerCore );
+ D_MAGIC_SET( shared, DFBLayerCoreShared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_layer_core_join( CoreDFB *core,
+ DFBLayerCore *data,
+ DFBLayerCoreShared *shared )
+{
+ int i;
+
+ D_DEBUG_AT( Core_Layer, "dfb_layer_core_join( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_MAGIC_ASSERT( shared, DFBLayerCoreShared );
+
+ data->core = core;
+ data->shared = shared;
+
+
+ if (dfb_num_layers != shared->num) {
+ D_ERROR("DirectFB/core/layers: Number of layers does not match!\n");
+ return DFB_BUG;
+ }
+
+ for (i=0; i<dfb_num_layers; i++) {
+ CoreLayer *layer = dfb_layers[i];
+ CoreLayerShared *lshared = shared->layers[i];
+
+ /* make a copy for faster access */
+ layer->layer_data = lshared->layer_data;
+
+ /* store pointer to shared data and core */
+ layer->shared = lshared;
+ layer->core = core;
+ }
+
+
+ D_MAGIC_SET( data, DFBLayerCore );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_layer_core_shutdown( DFBLayerCore *data,
+ bool emergency )
+{
+ int i;
+ DFBResult ret;
+ DFBLayerCoreShared *shared;
+
+ D_DEBUG_AT( Core_Layer, "dfb_layer_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBLayerCore );
+ D_MAGIC_ASSERT( data->shared, DFBLayerCoreShared );
+
+ shared = data->shared;
+
+
+ /* Begin with the most recently added layer. */
+ for (i=dfb_num_layers-1; i>=0; i--) {
+ CoreLayer *layer = dfb_layers[i];
+ CoreLayerShared *shared = layer->shared;
+ const DisplayLayerFuncs *funcs = layer->funcs;
+
+ D_ASSUME( emergency || fusion_vector_is_empty( &shared->added_regions ) );
+
+ /* Remove all regions during emergency shutdown. */
+ if (emergency && funcs->RemoveRegion) {
+ int n;
+ CoreLayerRegion *region;
+
+ fusion_vector_foreach( region, n, shared->added_regions ) {
+ D_DEBUG_AT( Core_Layer, "Removing region (%d, %d - %dx%d) from '%s'.\n",
+ DFB_RECTANGLE_VALS( &region->config.dest ),
+ shared->description.name );
+
+ ret = funcs->RemoveRegion( layer, layer->driver_data,
+ layer->layer_data, region->region_data );
+ if (ret)
+ D_DERROR( ret, "Core/Layers: Could not remove region!\n" );
+ }
+ }
+
+ /* Deinitialize the lock. */
+ fusion_skirmish_destroy( &shared->lock );
+
+ /* Deinitialize the state for window stack repaints. */
+ dfb_state_destroy( &layer->state );
+
+ /* Deinitialize the vector for the contexts. */
+ fusion_vector_destroy( &shared->contexts.stack );
+
+ /* Deinitialize the vector for the realized (added) regions. */
+ fusion_vector_destroy( &shared->added_regions );
+
+ /* Free the driver's layer data. */
+ if (shared->layer_data)
+ SHFREE( shared->shmpool, shared->layer_data );
+
+ /* Free the shared layer data. */
+ SHFREE( shared->shmpool, shared );
+
+ /* Free the local layer data. */
+ D_FREE( layer );
+ }
+
+ dfb_num_layers = 0;
+
+
+ D_MAGIC_CLEAR( data );
+ D_MAGIC_CLEAR( shared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_layer_core_leave( DFBLayerCore *data,
+ bool emergency )
+{
+ int i;
+ DFBLayerCoreShared *shared;
+
+ D_DEBUG_AT( Core_Layer, "dfb_layer_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBLayerCore );
+ D_MAGIC_ASSERT( data->shared, DFBLayerCoreShared );
+
+ shared = data->shared;
+
+
+ /* Deinitialize all local stuff. */
+ for (i=0; i<dfb_num_layers; i++) {
+ CoreLayer *layer = dfb_layers[i];
+
+ /* Deinitialize the state for window stack repaints. */
+ dfb_state_destroy( &layer->state );
+
+ /* Free local layer data. */
+ D_FREE( layer );
+ }
+
+ dfb_num_layers = 0;
+
+
+ D_MAGIC_CLEAR( data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_layer_core_suspend( DFBLayerCore *data )
+{
+ int i;
+ DFBLayerCoreShared *shared;
+
+ D_DEBUG_AT( Core_Layer, "dfb_layer_core_suspend( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBLayerCore );
+ D_MAGIC_ASSERT( data->shared, DFBLayerCoreShared );
+
+ shared = data->shared;
+
+ for (i=dfb_num_layers-1; i>=0; i--)
+ dfb_layer_suspend( dfb_layers[i] );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_layer_core_resume( DFBLayerCore *data )
+{
+ int i;
+ DFBLayerCoreShared *shared;
+
+ D_DEBUG_AT( Core_Layer, "dfb_layer_core_resume( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBLayerCore );
+ D_MAGIC_ASSERT( data->shared, DFBLayerCoreShared );
+
+ shared = data->shared;
+
+ for (i=0; i<dfb_num_layers; i++)
+ dfb_layer_resume( dfb_layers[i] );
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+CoreLayer *
+dfb_layers_register( CoreScreen *screen,
+ void *driver_data,
+ const DisplayLayerFuncs *funcs )
+{
+ CoreLayer *layer;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( funcs != NULL );
+
+ if (dfb_num_layers == MAX_LAYERS) {
+ D_ERROR( "DirectFB/Core/Layers: "
+ "Maximum number of layers reached!\n" );
+ return NULL;
+ }
+
+ /* allocate local data */
+ layer = D_CALLOC( 1, sizeof(CoreLayer) );
+
+ /* assign local pointers */
+ layer->device = screen->device;
+ layer->screen = screen;
+ layer->driver_data = driver_data;
+ layer->funcs = funcs;
+
+ /* Initialize the state for window stack repaints */
+ dfb_state_init( &layer->state, NULL );
+
+ /* add it to the local list */
+ dfb_layers[dfb_num_layers++] = layer;
+
+ return layer;
+}
+
+typedef void (*AnyFunc)( void );
+
+CoreLayer *
+dfb_layers_hook_primary( CoreGraphicsDevice *device,
+ void *driver_data,
+ DisplayLayerFuncs *funcs,
+ DisplayLayerFuncs *primary_funcs,
+ void **primary_driver_data )
+{
+ int i;
+ int entries;
+ CoreLayer *primary = dfb_layers[0];
+
+ D_ASSERT( primary != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( funcs != NULL );
+
+ /* copy content of original function table */
+ if (primary_funcs)
+ direct_memcpy( primary_funcs, primary->funcs, sizeof(DisplayLayerFuncs) );
+
+ /* copy pointer to original driver data */
+ if (primary_driver_data)
+ *primary_driver_data = primary->driver_data;
+
+ /* replace all entries in the old table that aren't NULL in the new one */
+ entries = sizeof(DisplayLayerFuncs) / sizeof(void(*)( void ));
+ for (i=0; i<entries; i++) {
+ AnyFunc *newfuncs = (AnyFunc*) funcs;
+ AnyFunc *oldfuncs = (AnyFunc*) primary->funcs;
+
+ if (newfuncs[i])
+ oldfuncs[i] = newfuncs[i];
+ }
+
+ /* replace device and driver data pointer */
+ primary->device = device;
+ primary->driver_data = driver_data;
+
+ return primary;
+}
+
+CoreLayer *
+dfb_layers_replace_primary( CoreGraphicsDevice *device,
+ void *driver_data,
+ DisplayLayerFuncs *funcs )
+{
+ CoreLayer *primary = dfb_layers[0];
+
+ D_ASSERT( primary != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( funcs != NULL );
+
+ /* replace device, function table and driver data pointer */
+ primary->device = device;
+ primary->funcs = funcs;
+ primary->driver_data = driver_data;
+
+ return primary;
+}
+
+void
+dfb_layers_enumerate( DisplayLayerCallback callback,
+ void *ctx )
+{
+ int i;
+
+ D_ASSERT( callback != NULL );
+
+ for (i=0; i<dfb_num_layers; i++) {
+ if (callback( dfb_layers[i], ctx ) == DFENUM_CANCEL)
+ break;
+ }
+}
+
+int
+dfb_layer_num( void )
+{
+ return dfb_num_layers;
+}
+
+CoreLayer *
+dfb_layer_at( DFBDisplayLayerID id )
+{
+ D_ASSERT( id >= 0);
+ D_ASSERT( id < dfb_num_layers);
+
+ return dfb_layers[id];
+}
+
+CoreLayer *
+dfb_layer_at_translated( DFBDisplayLayerID id )
+{
+ D_ASSERT( id >= 0);
+ D_ASSERT( id < dfb_num_layers);
+ D_ASSERT( dfb_config != NULL );
+
+ if (dfb_config->primary_layer > 0 &&
+ dfb_config->primary_layer < dfb_num_layers)
+ {
+ if (id == DLID_PRIMARY)
+ return dfb_layer_at( dfb_config->primary_layer );
+
+ if (id == dfb_config->primary_layer)
+ return dfb_layer_at( DLID_PRIMARY );
+ }
+
+ return dfb_layer_at( id );
+}
+
+void
+dfb_layer_get_description( const CoreLayer *layer,
+ DFBDisplayLayerDescription *desc )
+{
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( desc != NULL );
+
+ *desc = layer->shared->description;
+}
+
+CoreScreen *
+dfb_layer_screen( const CoreLayer *layer )
+{
+ D_ASSERT( layer != NULL );
+
+ return layer->screen;
+}
+
+CardState *
+dfb_layer_state( CoreLayer *layer )
+{
+ D_ASSERT( layer != NULL );
+
+ return &layer->state;
+}
+
+DFBDisplayLayerID
+dfb_layer_id( const CoreLayer *layer )
+{
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+
+ return layer->shared->layer_id;
+}
+
+DFBDisplayLayerID
+dfb_layer_id_translated( const CoreLayer *layer )
+{
+ CoreLayerShared *shared;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+ D_ASSERT( dfb_config != NULL );
+
+ shared = layer->shared;
+
+ if (dfb_config->primary_layer > 0 &&
+ dfb_config->primary_layer < dfb_num_layers)
+ {
+ if (shared->layer_id == DLID_PRIMARY)
+ return dfb_config->primary_layer;
+
+ if (shared->layer_id == dfb_config->primary_layer)
+ return DLID_PRIMARY;
+ }
+
+ return shared->layer_id;
+}
+
+DFBSurfacePixelFormat
+dfb_primary_layer_pixelformat( void )
+{
+ CoreLayerShared *shared;
+ CoreLayerContext *context;
+ CoreLayer *layer = dfb_layer_at_translated(DLID_PRIMARY);
+ DFBSurfacePixelFormat format = DSPF_UNKNOWN;
+
+ D_ASSERT( layer != NULL );
+ D_ASSERT( layer->shared != NULL );
+
+ shared = layer->shared;
+
+ /* If no context is active, return the default format. */
+ if (dfb_layer_get_active_context( layer, &context ) != DFB_OK)
+ return shared->default_config.pixelformat;
+
+ /* Use the format from the current configuration. */
+ format = context->config.pixelformat;
+
+ /* Decrease the context's reference counter. */
+ dfb_layer_context_unref( context );
+
+ return format;
+}
+
diff --git a/Source/DirectFB/src/core/layers.h b/Source/DirectFB/src/core/layers.h
new file mode 100755
index 0000000..68a1d9e
--- /dev/null
+++ b/Source/DirectFB/src/core/layers.h
@@ -0,0 +1,359 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__LAYERS_H__
+#define __CORE__LAYERS_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+#include <core/gfxcard.h>
+#include <core/surface_buffer.h>
+
+
+struct __DFB_CoreLayerRegionConfig {
+ int width; /* width of the source in pixels */
+ int height; /* height of the source in pixels */
+ DFBSurfacePixelFormat format; /* pixel format of the source surface */
+ DFBSurfaceCapabilities surface_caps; /* capabilities of the source surface */
+ DFBDisplayLayerBufferMode buffermode; /* surface buffer configuration */
+
+ DFBDisplayLayerOptions options; /* various configuration options */
+
+ DFBDisplayLayerSourceID source_id; /* selected source */
+
+ DFBRectangle source; /* viewport within source (input) */
+ DFBRectangle dest; /* viewport on screen (output) */
+
+ u8 opacity; /* global region alpha */
+
+ DFBColorKey src_key; /* source color key */
+ DFBColorKey dst_key; /* destination color key */
+
+ int parity; /* field parity (for interlaced) */
+
+ u8 alpha_ramp[4]; /* alpha values for 1 or 2 bit lookup */
+
+ DFBRegion *clips; /* clip regions */
+ int num_clips; /* number of clip regions */
+ DFBBoolean positive; /* show or cut out regions */
+};
+
+#if D_DEBUG_ENABLED
+#define DFB_CORE_LAYER_REGION_CONFIG_DEBUG_AT( domain, config ) \
+ do { \
+ const CoreLayerRegionConfig *_config = config; \
+ \
+ D_DEBUG_AT( domain, " -> size %dx%d\n", _config->width, _config->height ); \
+ D_DEBUG_AT( domain, " -> format %s\n", dfb_pixelformat_name( _config->format ) ); \
+ D_DEBUG_AT( domain, " -> surf caps 0x%08x\n", _config->surface_caps ); \
+ D_DEBUG_AT( domain, " -> buffermode %d\n", _config->buffermode ); \
+ D_DEBUG_AT( domain, " -> options 0x%08x\n", _config->options ); \
+ D_DEBUG_AT( domain, " -> source %d,%d-%dx%d\n", DFB_RECTANGLE_VALS(&_config->source) ); \
+ D_DEBUG_AT( domain, " -> dest %d,%d-%dx%d\n", DFB_RECTANGLE_VALS(&_config->dest) ); \
+ D_DEBUG_AT( domain, " -> opacity %d\n", _config->opacity ); \
+ D_DEBUG_AT( domain, " -> src_key %02x%02x%02x (index %d)\n", DFB_COLORKEY_VALS(&_config->src_key) ); \
+ D_DEBUG_AT( domain, " -> dst_key %02x%02x%02x (index %d)\n", DFB_COLORKEY_VALS(&_config->dst_key) ); \
+ } while (0)
+#else
+#define DFB_CORE_LAYER_REGION_CONFIG_DEBUG_AT( domain, config ) \
+ do { \
+ } while (0)
+#endif
+
+typedef enum {
+ CLRCF_NONE = 0x00000000,
+
+ CLRCF_WIDTH = 0x00000001,
+ CLRCF_HEIGHT = 0x00000002,
+ CLRCF_FORMAT = 0x00000004,
+ CLRCF_SURFACE_CAPS = 0x00000008,
+
+ CLRCF_BUFFERMODE = 0x00000010,
+ CLRCF_OPTIONS = 0x00000020,
+ CLRCF_SOURCE_ID = 0x00000040,
+
+ CLRCF_SOURCE = 0x00000100,
+ CLRCF_DEST = 0x00000200,
+ CLRCF_CLIPS = 0x00000400,
+
+ CLRCF_OPACITY = 0x00001000,
+ CLRCF_ALPHA_RAMP = 0x00002000,
+
+ CLRCF_SRCKEY = 0x00010000,
+ CLRCF_DSTKEY = 0x00020000,
+
+ CLRCF_PARITY = 0x00100000,
+
+ CLRCF_SURFACE = 0x10000000,
+ CLRCF_PALETTE = 0x20000000,
+
+ CLRCF_FREEZE = 0x80000000,
+
+ CLRCF_ALL = 0xB013377F
+} CoreLayerRegionConfigFlags;
+
+typedef struct {
+ /** Driver Control **/
+
+ /*
+ * Return size of layer data (shared memory).
+ */
+ int (*LayerDataSize) ( void );
+
+ /*
+ * Return size of region data (shared memory).
+ */
+ int (*RegionDataSize)( void );
+
+ /*
+ * Called once by the master to initialize layer data and reset hardware.
+ * Return layer description, default configuration and color adjustment.
+ */
+ DFBResult (*InitLayer) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBDisplayLayerDescription *description,
+ DFBDisplayLayerConfig *config,
+ DFBColorAdjustment *adjustment );
+
+ /*
+ * Called once by the master for each source.
+ * Driver fills description.
+ */
+ DFBResult (*InitSource) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ int source,
+ DFBDisplayLayerSourceDescription *description );
+
+
+ /** Layer Control **/
+
+ /*
+ * Return the currently displayed field (interlaced only).
+ */
+ DFBResult (*GetCurrentOutputField)( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ int *field );
+
+ /*
+ * Return the z position of the layer.
+ */
+ DFBResult (*GetLevel) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ int *level );
+
+ /*
+ * Move the layer below or on top of others (z position).
+ */
+ DFBResult (*SetLevel) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ int level );
+
+
+ /** Configuration **/
+
+ /*
+ * Adjust brightness, contrast, saturation etc.
+ */
+ DFBResult (*SetColorAdjustment) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBColorAdjustment *adjustment );
+
+
+ /** Region Control **/
+
+ /*
+ * Check all parameters and return if this region is supported.
+ */
+ DFBResult (*TestRegion) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags *failed );
+
+ /*
+ * Add a new region to the layer, but don't program hardware, yet.
+ */
+ DFBResult (*AddRegion) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config );
+
+ /*
+ * Setup hardware, called once after AddRegion() or when parameters
+ * have changed. Surface and palette are only set if updated or new.
+ */
+ DFBResult (*SetRegion) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags updated,
+ CoreSurface *surface,
+ CorePalette *palette,
+ CoreSurfaceBufferLock *lock );
+
+ /*
+ * Remove a region from the layer.
+ */
+ DFBResult (*RemoveRegion) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data );
+
+ /*
+ * Flip the surface of the region.
+ */
+ DFBResult (*FlipRegion) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ DFBSurfaceFlipFlags flags,
+ CoreSurfaceBufferLock *lock );
+
+ /*
+ * Indicate updates to the front buffer content.
+ */
+ DFBResult (*UpdateRegion) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ const DFBRegion *update,
+ CoreSurfaceBufferLock *lock );
+
+ /*
+ * Control hardware deinterlacing.
+ */
+ DFBResult (*SetInputField)( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ int field );
+
+
+ /** Override defaults. Subject to change. **/
+
+ /*
+ * Allocate the surface of the region.
+ */
+ DFBResult (*AllocateSurface) ( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config,
+ CoreSurface **ret_surface );
+
+ /*
+ * Reallocate the surface of the region.
+ */
+ DFBResult (*ReallocateSurface)( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config,
+ CoreSurface *surface );
+
+ /*
+ * Deallocate the surface of the region.
+ */
+ DFBResult (*DeallocateSurface)( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface );
+} DisplayLayerFuncs;
+
+
+/*
+ * Add a layer to a graphics device by pointing to a table
+ * containing driver functions. The supplied driver data
+ * will be passed to these functions.
+ */
+CoreLayer *dfb_layers_register( CoreScreen *screen,
+ void *driver_data,
+ const DisplayLayerFuncs *funcs );
+
+/*
+ * Replace functions of the primary layer implementation by passing
+ * an alternative driver function table. All non-NULL functions in the new
+ * table replace the functions in the original function table.
+ * The original function table is written to 'primary_funcs' before to allow
+ * drivers to use existing functionality from the original implementation.
+ */
+CoreLayer *dfb_layers_hook_primary( CoreGraphicsDevice *device,
+ void *driver_data,
+ DisplayLayerFuncs *funcs,
+ DisplayLayerFuncs *primary_funcs,
+ void **primary_driver_data );
+
+/*
+ * Replace functions of the primary layer implementation completely by passing
+ * an alternative driver function table.
+ */
+CoreLayer *dfb_layers_replace_primary( CoreGraphicsDevice *device,
+ void *driver_data,
+ DisplayLayerFuncs *funcs );
+
+typedef DFBEnumerationResult (*DisplayLayerCallback) (CoreLayer *layer,
+ void *ctx);
+
+void dfb_layers_enumerate( DisplayLayerCallback callback,
+ void *ctx );
+
+
+int dfb_layer_num( void );
+
+CoreLayer *dfb_layer_at( DFBDisplayLayerID id );
+
+CoreLayer *dfb_layer_at_translated( DFBDisplayLayerID id );
+
+
+void dfb_layer_get_description( const CoreLayer *layer,
+ DFBDisplayLayerDescription *desc );
+
+CoreScreen *dfb_layer_screen( const CoreLayer *layer );
+
+CardState *dfb_layer_state( CoreLayer *layer );
+
+DFBDisplayLayerID dfb_layer_id( const CoreLayer *layer );
+
+DFBDisplayLayerID dfb_layer_id_translated( const CoreLayer *layer );
+
+DFBSurfacePixelFormat dfb_primary_layer_pixelformat( void );
+
+#endif
diff --git a/Source/DirectFB/src/core/layers_internal.h b/Source/DirectFB/src/core/layers_internal.h
new file mode 100755
index 0000000..c546a33
--- /dev/null
+++ b/Source/DirectFB/src/core/layers_internal.h
@@ -0,0 +1,196 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__LAYERS_INTERNAL_H__
+#define __CORE__LAYERS_INTERNAL_H__
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <fusion/object.h>
+#include <fusion/property.h>
+#include <fusion/vector.h>
+
+#include <core/layers.h>
+#include <core/layer_region.h>
+#include <core/state.h>
+
+typedef struct {
+ FusionVector stack;
+ int active;
+
+ CoreLayerContext *primary;
+} CoreLayerContexts;
+
+typedef struct {
+ int index;
+ DFBDisplayLayerSourceDescription description;
+} CoreLayerSource;
+
+typedef struct {
+ DFBDisplayLayerID layer_id;
+
+ DFBDisplayLayerDescription description;
+ DFBDisplayLayerConfig default_config;
+ DFBColorAdjustment default_adjustment;
+
+ CoreLayerSource *sources;
+
+ void *layer_data;
+
+ FusionSkirmish lock;
+
+ CoreLayerContexts contexts;
+
+ bool suspended;
+
+ FusionVector added_regions;
+
+ FusionSHMPoolShared *shmpool;
+} CoreLayerShared;
+
+struct __DFB_CoreLayer {
+ CoreLayerShared *shared;
+
+ CoreDFB *core;
+
+ CoreGraphicsDevice *device;
+
+ CoreScreen *screen;
+
+ void *driver_data;
+ void *layer_data; /* copy of shared->layer_data */
+
+ const DisplayLayerFuncs *funcs;
+
+ CardState state;
+};
+
+typedef enum {
+ CLLM_LOCATION, /* Keep normalized area. */
+ CLLM_CENTER, /* Center layer after resizing destination area. */
+ CLLM_POSITION, /* Keep pixel position, but resize area. */
+ CLLM_RECTANGLE /* Keep pixel based area. */
+} CoreLayerLayoutMode;
+
+struct __DFB_CoreLayerContext {
+ FusionObject object;
+
+ int magic;
+
+ DFBDisplayLayerID layer_id;
+
+ FusionSkirmish lock;
+
+ bool active; /* Is this the active context? */
+
+ DFBDisplayLayerConfig config; /* Current layer configuration. */
+ int rotation;
+
+ FusionVector regions; /* All regions created within
+ this context. */
+
+ struct {
+ CoreLayerRegion *region; /* Region of layer config if buffer
+ mode is not DLBM_WINDOWS. */
+ CoreLayerRegionConfig config; /* Region config used to implement
+ layer config and settings. */
+ } primary;
+
+ struct {
+ DFBLocation location; /* Normalized screen location. */
+ DFBRectangle rectangle; /* Pixel based position and size. */
+
+ CoreLayerLayoutMode mode; /* ...and how resizing influences them. */
+ } screen;
+
+ DFBColorAdjustment adjustment; /* Color adjustment of the layer.*/
+
+ CoreWindowStack *stack; /* Every layer has its own
+ windowstack as every layer has
+ its own pixel buffer. */
+
+ FusionSHMPoolShared *shmpool;
+};
+
+typedef enum {
+ CLRSF_NONE = 0x00000000,
+
+ CLRSF_CONFIGURED = 0x00000001,
+ CLRSF_ENABLED = 0x00000002,
+ CLRSF_ACTIVE = 0x00000004,
+ CLRSF_REALIZED = 0x00000008,
+
+ CLRSF_FROZEN = 0x00000010,
+
+ CLRSF_ALL = 0x0000001F
+} CoreLayerRegionStateFlags;
+
+struct __DFB_CoreLayerRegion {
+ FusionObject object;
+
+ CoreLayerContext *context;
+
+ FusionSkirmish lock;
+
+ CoreLayerRegionStateFlags state;
+
+ CoreLayerRegionConfig config;
+
+ CoreSurface *surface;
+ CoreSurfaceBufferLock surface_lock;
+ GlobalReaction surface_reaction;
+
+ void *region_data;
+};
+
+
+/* Called at the end of dfb_layer_region_create(). */
+DFBResult dfb_layer_context_add_region( CoreLayerContext *context,
+ CoreLayerRegion *region );
+
+/* Called early in the region_destructor(). */
+DFBResult dfb_layer_context_remove_region( CoreLayerContext *context,
+ CoreLayerRegion *region );
+
+/* Called by dfb_layer_activate_context(),
+ dfb_layer_remove_context() and dfb_layer_resume(). */
+DFBResult dfb_layer_context_activate ( CoreLayerContext *context );
+
+/* Called by dfb_layer_deactivate_context(),
+ dfb_layer_remove_context() and dfb_layer_suspend(). */
+DFBResult dfb_layer_context_deactivate( CoreLayerContext *context );
+
+/* global reactions */
+ReactionResult _dfb_layer_region_surface_listener( const void *msg_data,
+ void *ctx );
+
+#endif
+
diff --git a/Source/DirectFB/src/core/local_surface_pool.c b/Source/DirectFB/src/core/local_surface_pool.c
new file mode 100755
index 0000000..8da06de
--- /dev/null
+++ b/Source/DirectFB/src/core/local_surface_pool.c
@@ -0,0 +1,313 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+
+#include <fusion/fusion.h>
+
+#include <core/core.h>
+#include <core/surface_pool.h>
+
+
+/**********************************************************************************************************************/
+
+typedef struct {
+} LocalPoolData;
+
+typedef struct {
+ FusionCall call;
+} LocalPoolLocalData;
+
+typedef struct {
+ int magic;
+
+ void *addr;
+ int pitch;
+ int size;
+
+ FusionCall call;
+ FusionID fid;
+} LocalAllocationData;
+
+/**********************************************************************************************************************/
+
+static FusionCallHandlerResult
+local_surface_pool_call_handler( int caller,
+ int call_arg,
+ void *call_ptr,
+ void *ctx,
+ unsigned int serial,
+ int *ret_val )
+{
+ D_FREE( call_ptr );
+
+ *ret_val = 0;
+
+ return FCHR_RETURN;
+}
+
+/**********************************************************************************************************************/
+
+static int
+localPoolDataSize( void )
+{
+ return sizeof(LocalPoolData);
+}
+
+static int
+localPoolLocalDataSize( void )
+{
+ return sizeof(LocalPoolLocalData);
+}
+
+static int
+localAllocationDataSize( void )
+{
+ return sizeof(LocalAllocationData);
+}
+
+static DFBResult
+localInitPool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data,
+ CoreSurfacePoolDescription *ret_desc )
+{
+ LocalPoolLocalData *local = pool_local;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( pool_local != NULL );
+ D_ASSERT( ret_desc != NULL );
+
+ ret_desc->caps = CSPCAPS_NONE;
+ ret_desc->access[CSAID_CPU] = CSAF_READ | CSAF_WRITE;
+ ret_desc->types = CSTF_FONT | CSTF_INTERNAL;
+ ret_desc->priority = CSPP_PREFERED;
+
+ snprintf( ret_desc->name, DFB_SURFACE_POOL_DESC_NAME_LENGTH, "System Memory" );
+
+ fusion_call_init( &local->call, local_surface_pool_call_handler, local, dfb_core_world(core) );
+
+ return DFB_OK;
+}
+
+static DFBResult
+localJoinPool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data )
+{
+ LocalPoolLocalData *local = pool_local;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( pool_local != NULL );
+
+ return fusion_call_init( &local->call, local_surface_pool_call_handler, local, dfb_core_world(core) );
+}
+
+static DFBResult
+localDestroyPool( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local )
+{
+ CoreSurfaceAllocation *allocation;
+ LocalPoolLocalData *local = pool_local;
+ LocalAllocationData *data;
+ FusionID fid;
+
+ DFBResult res;
+ int i;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( pool_local != NULL );
+
+ res = fusion_call_destroy( &local->call );
+ fid = fusion_id( dfb_core_world(NULL) );
+
+ /* remove the local allocations */
+ fusion_vector_foreach (allocation, i, pool->allocs) {
+ data = allocation->data;
+ if( data->fid == fid )
+ D_FREE( data->addr );
+ }
+
+ return res;
+}
+
+static DFBResult
+localLeavePool( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local )
+{
+ CoreSurfaceAllocation *allocation;
+ LocalPoolLocalData *local = pool_local;
+ LocalAllocationData *data;
+ FusionID fid;
+
+ DFBResult res;
+ int i;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( pool_local != NULL );
+
+ res = fusion_call_destroy( &local->call );
+ fid = fusion_id( dfb_core_world(NULL) );
+
+ /* remove the local allocations */
+ fusion_vector_foreach (allocation, i, pool->allocs) {
+ data = allocation->data;
+ if( data->fid == fid )
+ D_FREE( data->addr );
+ }
+
+ return res;
+}
+
+static DFBResult
+localAllocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ CoreSurface *surface;
+ LocalPoolLocalData *local = pool_local;
+ LocalAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_ASSERT( alloc != NULL );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ dfb_surface_calc_buffer_size( surface, 8, 0, &alloc->pitch, &alloc->size );
+
+ alloc->addr = D_MALLOC( alloc->size );
+ if (!alloc->addr)
+ return D_OOM();
+
+ alloc->call = local->call;
+ alloc->fid = fusion_id( dfb_core_world(NULL) );
+
+ D_MAGIC_SET( alloc, LocalAllocationData );
+
+ allocation->flags = CSALF_VOLATILE;
+ allocation->size = alloc->size;
+
+ return DFB_OK;
+}
+
+static DFBResult
+localDeallocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ DFBResult ret;
+ LocalAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_MAGIC_ASSERT( alloc, LocalAllocationData );
+
+ ret = fusion_call_execute( &alloc->call, FCEF_ONEWAY, 0, alloc->addr, NULL );
+// if (ret)
+// D_DERROR( ret, "SurfPool/Local: Could not call buffer owner to free it there!\n" );
+
+ D_MAGIC_CLEAR( alloc );
+
+ return DFB_OK;
+}
+
+static DFBResult
+localLock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ LocalAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+ D_MAGIC_ASSERT( alloc, LocalAllocationData );
+
+ lock->addr = alloc->addr;
+ lock->pitch = alloc->pitch;
+
+ return DFB_OK;
+}
+
+static DFBResult
+localUnlock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ LocalAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+ D_MAGIC_ASSERT( alloc, LocalAllocationData );
+
+ (void) alloc;
+
+ return DFB_OK;
+}
+
+const SurfacePoolFuncs localSurfacePoolFuncs = {
+ .PoolDataSize = localPoolDataSize,
+ .PoolLocalDataSize = localPoolLocalDataSize,
+ .AllocationDataSize = localAllocationDataSize,
+
+ .InitPool = localInitPool,
+ .JoinPool = localJoinPool,
+ .DestroyPool = localDestroyPool,
+ .LeavePool = localLeavePool,
+
+ .AllocateBuffer = localAllocateBuffer,
+ .DeallocateBuffer = localDeallocateBuffer,
+
+ .Lock = localLock,
+ .Unlock = localUnlock,
+};
+
diff --git a/Source/DirectFB/src/core/palette.c b/Source/DirectFB/src/core/palette.c
new file mode 100755
index 0000000..3d66a54
--- /dev/null
+++ b/Source/DirectFB/src/core/palette.c
@@ -0,0 +1,317 @@
+/*
+ (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 <directfb.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/core.h>
+#include <core/surface.h>
+#include <core/gfxcard.h>
+#include <core/palette.h>
+#include <core/colorhash.h>
+
+#include <gfx/convert.h>
+
+#include <misc/util.h>
+
+D_DEBUG_DOMAIN( Core_Palette, "Core/Palette", "DirectFB Palette Core" );
+
+/**********************************************************************************************************************/
+
+static const u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff };
+static const u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff };
+
+static const ReactionFunc dfb_palette_globals[] = {
+/* 0 */ _dfb_surface_palette_listener,
+ NULL
+};
+
+/**********************************************************************************************************************/
+
+static void palette_destructor( FusionObject *object, bool zombie, void *ctx )
+{
+ CorePaletteNotification notification;
+ CorePalette *palette = (CorePalette*) object;
+
+ D_MAGIC_ASSERT( palette, CorePalette );
+
+ D_DEBUG_AT( Core_Palette, "destroying %p (%d)%s\n", palette,
+ palette->num_entries, zombie ? " (ZOMBIE)" : "");
+
+ D_ASSERT( palette->entries != NULL );
+ D_ASSERT( palette->entries_yuv != NULL );
+
+ notification.flags = CPNF_DESTROY;
+ notification.palette = palette;
+
+ dfb_palette_dispatch( palette, &notification, dfb_palette_globals );
+
+ if (palette->hash_attached) {
+ dfb_colorhash_invalidate( NULL, palette );
+ dfb_colorhash_detach( NULL, palette );
+ }
+
+ SHFREE( palette->shmpool, palette->entries_yuv );
+ SHFREE( palette->shmpool, palette->entries );
+
+ D_MAGIC_CLEAR( palette );
+
+ fusion_object_destroy( object );
+}
+
+FusionObjectPool *
+dfb_palette_pool_create( const FusionWorld *world )
+{
+ FusionObjectPool *pool;
+
+ pool = fusion_object_pool_create( "Palette Pool",
+ sizeof(CorePalette),
+ sizeof(CorePaletteNotification),
+ palette_destructor, NULL, world );
+
+ return pool;
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_palette_create( CoreDFB *core,
+ unsigned int size,
+ CorePalette **ret_palette )
+{
+ CorePalette *palette;
+
+ D_DEBUG_AT( Core_Palette, "%s( %d )\n", __FUNCTION__, size );
+
+ D_ASSERT( ret_palette );
+
+ palette = dfb_core_create_palette( core );
+ if (!palette)
+ return DFB_FUSION;
+
+ palette->shmpool = dfb_core_shmpool( core );
+
+ if (size) {
+ palette->entries = SHCALLOC( palette->shmpool, size, sizeof(DFBColor) );
+ if (!palette->entries) {
+ fusion_object_destroy( &palette->object );
+ return D_OOSHM();
+ }
+
+ palette->entries_yuv = SHCALLOC( palette->shmpool, size, sizeof(DFBColorYUV) );
+ if (!palette->entries_yuv) {
+ SHFREE( palette->shmpool, palette->entries );
+ fusion_object_destroy( &palette->object );
+ return D_OOSHM();
+ }
+ }
+
+ palette->num_entries = size;
+
+ /* reset cache */
+ palette->search_cache.index = -1;
+
+ D_MAGIC_SET( palette, CorePalette );
+
+ /* activate object */
+ fusion_object_activate( &palette->object );
+
+ /* return the new palette */
+ *ret_palette = palette;
+
+ D_DEBUG_AT( Core_Palette, " -> %p\n", palette );
+
+ return DFB_OK;
+}
+
+void
+dfb_palette_generate_rgb332_map( CorePalette *palette )
+{
+ unsigned int i;
+
+ D_DEBUG_AT( Core_Palette, "%s( %p )\n", __FUNCTION__, palette );
+
+ D_MAGIC_ASSERT( palette, CorePalette );
+
+ if (!palette->num_entries)
+ return;
+
+ for (i=0; i<palette->num_entries; i++) {
+ palette->entries[i].a = i ? 0xff : 0x00;
+ palette->entries[i].r = lookup3to8[ (i & 0xE0) >> 5 ];
+ palette->entries[i].g = lookup3to8[ (i & 0x1C) >> 2 ];
+ palette->entries[i].b = lookup2to8[ (i & 0x03) ];
+
+ palette->entries_yuv[i].a = palette->entries[i].a;
+
+ RGB_TO_YCBCR( palette->entries[i].r, palette->entries[i].g, palette->entries[i].b,
+ palette->entries_yuv[i].y, palette->entries_yuv[i].u, palette->entries_yuv[i].v );
+ }
+
+ dfb_palette_update( palette, 0, palette->num_entries - 1 );
+}
+
+void
+dfb_palette_generate_rgb121_map( CorePalette *palette )
+{
+ unsigned int i;
+
+ D_DEBUG_AT( Core_Palette, "%s( %p )\n", __FUNCTION__, palette );
+
+ D_MAGIC_ASSERT( palette, CorePalette );
+
+ if (!palette->num_entries)
+ return;
+
+ for (i=0; i<palette->num_entries; i++) {
+ palette->entries[i].a = i ? 0xff : 0x00;
+ palette->entries[i].r = (i & 0x8) ? 0xff : 0x00;
+ palette->entries[i].g = lookup2to8[ (i & 0x6) >> 1 ];
+ palette->entries[i].b = (i & 0x1) ? 0xff : 0x00;
+
+ palette->entries_yuv[i].a = palette->entries[i].a;
+
+ RGB_TO_YCBCR( palette->entries[i].r, palette->entries[i].g, palette->entries[i].b,
+ palette->entries_yuv[i].y, palette->entries_yuv[i].u, palette->entries_yuv[i].v );
+ }
+
+ dfb_palette_update( palette, 0, palette->num_entries - 1 );
+}
+
+unsigned int
+dfb_palette_search( CorePalette *palette,
+ u8 r,
+ u8 g,
+ u8 b,
+ u8 a )
+{
+ unsigned int index;
+
+ D_MAGIC_ASSERT( palette, CorePalette );
+
+ /* check local cache first */
+ if (palette->search_cache.index != -1 &&
+ palette->search_cache.color.a == a &&
+ palette->search_cache.color.r == r &&
+ palette->search_cache.color.g == g &&
+ palette->search_cache.color.b == b)
+ return palette->search_cache.index;
+
+ /* check the global color hash table, returns the closest match */
+ if (!palette->hash_attached) {
+ dfb_colorhash_attach( NULL, palette );
+ palette->hash_attached = true;
+ }
+
+ index = dfb_colorhash_lookup( NULL, palette, r, g, b, a );
+
+ /* write into local cache */
+ palette->search_cache.index = index;
+ palette->search_cache.color.a = a;
+ palette->search_cache.color.r = r;
+ palette->search_cache.color.g = g;
+ palette->search_cache.color.b = b;
+
+ return index;
+}
+
+void
+dfb_palette_update( CorePalette *palette, int first, int last )
+{
+ CorePaletteNotification notification;
+
+ D_DEBUG_AT( Core_Palette, "%s( %p, %d, %d )\n", __FUNCTION__, palette, first, last );
+
+ D_MAGIC_ASSERT( palette, CorePalette );
+ D_ASSERT( first >= 0 );
+ D_ASSERT( first < palette->num_entries );
+ D_ASSERT( last >= 0 );
+ D_ASSERT( last < palette->num_entries );
+ D_ASSERT( first <= last );
+
+ notification.flags = CPNF_ENTRIES;
+ notification.palette = palette;
+ notification.first = first;
+ notification.last = last;
+
+ /* reset cache */
+ if (palette->search_cache.index >= first &&
+ palette->search_cache.index <= last)
+ palette->search_cache.index = -1;
+
+ /* invalidate entries in colorhash */
+ if (palette->hash_attached)
+ dfb_colorhash_invalidate( NULL, palette );
+
+ /* post message about palette update */
+ dfb_palette_dispatch( palette, &notification, dfb_palette_globals );
+}
+
+bool
+dfb_palette_equal( CorePalette *palette1, CorePalette *palette2 )
+{
+ u32 *entries1;
+ u32 *entries2;
+ int i;
+
+ D_DEBUG_AT( Core_Palette, "%s( %p, %p )\n", __FUNCTION__, palette1, palette2 );
+
+ D_ASSERT( palette1 != NULL );
+ D_ASSERT( palette2 != NULL );
+
+ if (palette1 == palette2) {
+ D_DEBUG_AT( Core_Palette, " -> SAME\n" );
+ return true;
+ }
+
+ if (palette1->num_entries != palette2->num_entries) {
+ D_DEBUG_AT( Core_Palette, " -> NOT EQUAL (%d/%d)\n", palette1->num_entries, palette2->num_entries );
+ return false;
+ }
+
+ entries1 = (u32*)palette1->entries;
+ entries2 = (u32*)palette2->entries;
+
+ for (i = 0; i < palette1->num_entries; i++) {
+ if (entries1[i] != entries2[i]) {
+ D_DEBUG_AT( Core_Palette, " -> NOT EQUAL (%d)\n", i );
+ return false;
+ }
+ }
+
+ D_DEBUG_AT( Core_Palette, " -> EQUAL\n" );
+
+ return true;
+}
+
diff --git a/Source/DirectFB/src/core/palette.h b/Source/DirectFB/src/core/palette.h
new file mode 100755
index 0000000..10886be
--- /dev/null
+++ b/Source/DirectFB/src/core/palette.h
@@ -0,0 +1,106 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __PALETTE_H__
+#define __PALETTE_H__
+
+#include <directfb.h>
+#include <core/coretypes.h>
+#include <fusion/object.h>
+
+struct _CorePalette {
+ FusionObject object;
+ int magic;
+
+ unsigned int num_entries;
+ DFBColor *entries;
+ DFBColorYUV *entries_yuv;
+
+ struct {
+ int index;
+ DFBColor color;
+ } search_cache;
+
+ bool hash_attached;
+
+ FusionSHMPoolShared *shmpool;
+};
+
+typedef enum {
+ CPNF_ENTRIES = 0x00000001,
+ CPNF_DESTROY = 0x00000002
+} CorePaletteNotificationFlags;
+
+typedef struct {
+ CorePaletteNotificationFlags flags;
+ CorePalette *palette;
+ int first;
+ int last;
+} CorePaletteNotification;
+
+
+DFBResult dfb_palette_create ( CoreDFB *core,
+ unsigned int size,
+ CorePalette **ret_palette );
+
+void dfb_palette_generate_rgb332_map( CorePalette *palette );
+void dfb_palette_generate_rgb121_map( CorePalette *palette );
+
+unsigned int dfb_palette_search ( CorePalette *palette,
+ u8 r,
+ u8 g,
+ u8 b,
+ u8 a );
+
+void dfb_palette_update ( CorePalette *palette,
+ int first,
+ int last );
+
+bool dfb_palette_equal ( CorePalette *palette1,
+ CorePalette *palette2 );
+
+
+/*
+ * Creates a pool of palette objects.
+ */
+FusionObjectPool *dfb_palette_pool_create( const FusionWorld *world );
+
+/*
+ * Generates dfb_palette_ref(), dfb_palette_attach() etc.
+ */
+FUSION_OBJECT_METHODS( CorePalette, dfb_palette )
+
+
+/* global reactions */
+
+typedef enum {
+ DFB_SURFACE_PALETTE_LISTENER
+} DFB_PALETTE_GLOBALS;
+
+#endif
+
diff --git a/Source/DirectFB/src/core/prealloc_surface_pool.c b/Source/DirectFB/src/core/prealloc_surface_pool.c
new file mode 100755
index 0000000..f7d9051
--- /dev/null
+++ b/Source/DirectFB/src/core/prealloc_surface_pool.c
@@ -0,0 +1,192 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/debug.h>
+
+#include <fusion/conf.h>
+#include <fusion/shmalloc.h>
+#include <fusion/shm/pool.h>
+
+#include <core/core.h>
+#include <core/surface_pool.h>
+
+typedef struct {
+ void *addr;
+ int pitch;
+} PreallocAllocationData;
+
+/**********************************************************************************************************************/
+
+static int
+preallocAllocationDataSize( void )
+{
+ return sizeof(PreallocAllocationData);
+}
+
+static DFBResult
+preallocInitPool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data,
+ CoreSurfacePoolDescription *ret_desc )
+{
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( ret_desc != NULL );
+
+ ret_desc->caps = CSPCAPS_NONE;
+ ret_desc->access[CSAID_CPU] = CSAF_READ | CSAF_WRITE;
+ ret_desc->types = CSTF_PREALLOCATED | CSTF_INTERNAL;
+ ret_desc->priority = CSPP_DEFAULT;
+
+ snprintf( ret_desc->name, DFB_SURFACE_POOL_DESC_NAME_LENGTH, "Preallocated Memory" );
+
+ return DFB_OK;
+}
+
+static DFBResult
+preallocTestConfig( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ const CoreSurfaceConfig *config )
+{
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( config != NULL );
+
+ return (config->flags & CSCONF_PREALLOCATED) ? DFB_OK : DFB_UNSUPPORTED;
+}
+
+static DFBResult
+preallocAllocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ int index;
+ CoreSurface *surface;
+ PreallocAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ for (index=0; index<MAX_SURFACE_BUFFERS; index++) {
+ if (surface->buffers[index] == buffer)
+ break;
+ }
+
+ if (index == MAX_SURFACE_BUFFERS)
+ return DFB_BUG;
+
+ if (!(surface->config.flags & CSCONF_PREALLOCATED))
+ return DFB_BUG;
+
+ if (!surface->config.preallocated[index].addr ||
+ surface->config.preallocated[index].pitch < DFB_BYTES_PER_LINE(surface->config.format,
+ surface->config.size.w))
+ return DFB_INVARG;
+
+ alloc->addr = surface->config.preallocated[index].addr;
+ alloc->pitch = surface->config.preallocated[index].pitch;
+
+ allocation->flags = CSALF_PREALLOCATED | CSALF_VOLATILE;
+ allocation->size = surface->config.preallocated[index].pitch *
+ DFB_PLANE_MULTIPLY( surface->config.format, surface->config.size.h );
+
+ return DFB_OK;
+}
+
+static DFBResult
+preallocDeallocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+
+ return DFB_OK;
+}
+
+static DFBResult
+preallocLock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ PreallocAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ lock->addr = alloc->addr;
+ lock->pitch = alloc->pitch;
+
+ return DFB_OK;
+}
+
+static DFBResult
+preallocUnlock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ return DFB_OK;
+}
+
+const SurfacePoolFuncs preallocSurfacePoolFuncs = {
+ .AllocationDataSize = preallocAllocationDataSize,
+ .InitPool = preallocInitPool,
+
+ .TestConfig = preallocTestConfig,
+
+ .AllocateBuffer = preallocAllocateBuffer,
+ .DeallocateBuffer = preallocDeallocateBuffer,
+
+ .Lock = preallocLock,
+ .Unlock = preallocUnlock,
+};
+
diff --git a/Source/DirectFB/src/core/screen.c b/Source/DirectFB/src/core/screen.c
new file mode 100755
index 0000000..4b233e0
--- /dev/null
+++ b/Source/DirectFB/src/core/screen.c
@@ -0,0 +1,540 @@
+/*
+ (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 <directfb.h>
+
+#include <direct/debug.h>
+
+#include <core/layers.h>
+#include <core/screen.h>
+#include <core/screens_internal.h>
+
+
+DFBResult
+dfb_screen_get_info( CoreScreen *screen,
+ DFBScreenID *ret_id,
+ DFBScreenDescription *ret_desc )
+{
+ CoreScreenShared *shared;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+
+ shared = screen->shared;
+
+ if (ret_id)
+ *ret_id = shared->screen_id;
+
+ if (ret_desc)
+ *ret_desc = shared->description;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_screen_suspend( CoreScreen *screen )
+{
+ D_ASSERT( screen != NULL );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_screen_resume( CoreScreen *screen )
+{
+ D_ASSERT( screen != NULL );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_screen_set_powermode( CoreScreen *screen,
+ DFBScreenPowerMode mode )
+{
+ ScreenFuncs *funcs;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->funcs != NULL );
+
+ funcs = screen->funcs;
+
+ if (funcs->SetPowerMode)
+ return funcs->SetPowerMode( screen,
+ screen->driver_data,
+ screen->screen_data,
+ mode );
+
+ return DFB_UNSUPPORTED;
+}
+
+DFBResult
+dfb_screen_wait_vsync( CoreScreen *screen )
+{
+ ScreenFuncs *funcs;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->funcs != NULL );
+
+ funcs = screen->funcs;
+
+ if (funcs->WaitVSync)
+ return funcs->WaitVSync( screen,
+ screen->driver_data, screen->screen_data );
+
+ return DFB_UNSUPPORTED;
+}
+
+
+/*********************************** Mixers ***********************************/
+
+DFBResult
+dfb_screen_get_mixer_info( CoreScreen *screen,
+ int mixer,
+ DFBScreenMixerDescription *ret_desc )
+{
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( mixer >= 0 );
+ D_ASSERT( mixer < screen->shared->description.mixers );
+ D_ASSERT( ret_desc != NULL );
+
+ /* Return mixer description. */
+ *ret_desc = screen->shared->mixers[mixer].description;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_screen_get_mixer_config( CoreScreen *screen,
+ int mixer,
+ DFBScreenMixerConfig *ret_config )
+{
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( mixer >= 0 );
+ D_ASSERT( mixer < screen->shared->description.mixers );
+ D_ASSERT( ret_config != NULL );
+
+ /* Return current mixer configuration. */
+ *ret_config = screen->shared->mixers[mixer].configuration;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_screen_test_mixer_config( CoreScreen *screen,
+ int mixer,
+ const DFBScreenMixerConfig *config,
+ DFBScreenMixerConfigFlags *ret_failed )
+{
+ DFBResult ret;
+ DFBScreenMixerConfigFlags failed = DSMCONF_NONE;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( screen->funcs != NULL );
+ D_ASSERT( screen->funcs->TestMixerConfig != NULL );
+ D_ASSERT( mixer >= 0 );
+ D_ASSERT( mixer < screen->shared->description.mixers );
+ D_ASSERT( config != NULL );
+ D_ASSERT( config->flags == screen->shared->mixers[mixer].configuration.flags );
+
+ /* Test the mixer configuration. */
+ ret = screen->funcs->TestMixerConfig( screen,
+ screen->driver_data,
+ screen->screen_data,
+ mixer, config, &failed );
+
+ D_ASSUME( (ret == DFB_OK && !failed) || (ret != DFB_OK) );
+
+ if (ret_failed)
+ *ret_failed = failed;
+
+ return ret;
+}
+
+DFBResult
+dfb_screen_set_mixer_config( CoreScreen *screen,
+ int mixer,
+ const DFBScreenMixerConfig *config )
+{
+ DFBResult ret;
+ DFBScreenMixerConfigFlags failed = DSOCONF_NONE;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( screen->funcs != NULL );
+ D_ASSERT( screen->funcs->TestMixerConfig != NULL );
+ D_ASSERT( screen->funcs->SetMixerConfig != NULL );
+ D_ASSERT( mixer >= 0 );
+ D_ASSERT( mixer < screen->shared->description.mixers );
+ D_ASSERT( config != NULL );
+ D_ASSERT( config->flags == screen->shared->mixers[mixer].configuration.flags );
+
+ /* Test configuration first. */
+ ret = screen->funcs->TestMixerConfig( screen,
+ screen->driver_data,
+ screen->screen_data,
+ mixer, config, &failed );
+
+ D_ASSUME( (ret == DFB_OK && !failed) || (ret != DFB_OK && failed) );
+
+ if (ret)
+ return ret;
+
+ /* Set configuration afterwards. */
+ ret = screen->funcs->SetMixerConfig( screen,
+ screen->driver_data,
+ screen->screen_data,
+ mixer, config );
+ if (ret)
+ return ret;
+
+ /* Store current configuration. */
+ screen->shared->mixers[mixer].configuration = *config;
+
+ return DFB_OK;
+}
+
+
+/********************************** Encoders **********************************/
+
+DFBResult
+dfb_screen_get_encoder_info( CoreScreen *screen,
+ int encoder,
+ DFBScreenEncoderDescription *ret_desc )
+{
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( encoder >= 0 );
+ D_ASSERT( encoder < screen->shared->description.encoders );
+ D_ASSERT( ret_desc != NULL );
+
+ /* Return encoder description. */
+ *ret_desc = screen->shared->encoders[encoder].description;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_screen_get_encoder_config( CoreScreen *screen,
+ int encoder,
+ DFBScreenEncoderConfig *ret_config )
+{
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( encoder >= 0 );
+ D_ASSERT( encoder < screen->shared->description.encoders );
+ D_ASSERT( ret_config != NULL );
+
+ /* Return current encoder configuration. */
+ *ret_config = screen->shared->encoders[encoder].configuration;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_screen_test_encoder_config( CoreScreen *screen,
+ int encoder,
+ const DFBScreenEncoderConfig *config,
+ DFBScreenEncoderConfigFlags *ret_failed )
+{
+ DFBResult ret;
+ DFBScreenEncoderConfigFlags failed = DSECONF_NONE;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( screen->funcs != NULL );
+ D_ASSERT( screen->funcs->TestEncoderConfig != NULL );
+ D_ASSERT( encoder >= 0 );
+ D_ASSERT( encoder < screen->shared->description.encoders );
+ D_ASSERT( config != NULL );
+ D_ASSERT( config->flags == screen->shared->encoders[encoder].configuration.flags );
+
+ /* Test the encoder configuration. */
+ ret = screen->funcs->TestEncoderConfig( screen,
+ screen->driver_data,
+ screen->screen_data,
+ encoder, config, &failed );
+
+ D_ASSUME( (ret == DFB_OK && !failed) || (ret != DFB_OK && failed) );
+
+ if (ret_failed)
+ *ret_failed = failed;
+
+ return ret;
+}
+
+DFBResult
+dfb_screen_set_encoder_config( CoreScreen *screen,
+ int encoder,
+ const DFBScreenEncoderConfig *config )
+{
+ DFBResult ret;
+ DFBScreenEncoderConfigFlags failed = DSECONF_NONE;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( screen->funcs != NULL );
+ D_ASSERT( screen->funcs->TestEncoderConfig != NULL );
+ D_ASSERT( screen->funcs->SetEncoderConfig != NULL );
+ D_ASSERT( encoder >= 0 );
+ D_ASSERT( encoder < screen->shared->description.encoders );
+ D_ASSERT( config != NULL );
+ D_ASSERT( config->flags == screen->shared->encoders[encoder].configuration.flags );
+
+ /* Test configuration first. */
+ ret = screen->funcs->TestEncoderConfig( screen,
+ screen->driver_data,
+ screen->screen_data,
+ encoder, config, &failed );
+
+ D_ASSUME( (ret == DFB_OK && !failed) || (ret != DFB_OK && failed) );
+
+ if (ret)
+ return ret;
+
+ /* Set configuration afterwards. */
+ ret = screen->funcs->SetEncoderConfig( screen,
+ screen->driver_data,
+ screen->screen_data,
+ encoder, config );
+ if (ret)
+ return ret;
+
+ /* Store current configuration. */
+ screen->shared->encoders[encoder].configuration = *config;
+
+ return DFB_OK;
+}
+
+
+/********************************** Outputs ***********************************/
+
+DFBResult
+dfb_screen_get_output_info( CoreScreen *screen,
+ int output,
+ DFBScreenOutputDescription *ret_desc )
+{
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( output >= 0 );
+ D_ASSERT( output < screen->shared->description.outputs );
+ D_ASSERT( ret_desc != NULL );
+
+ /* Return output description. */
+ *ret_desc = screen->shared->outputs[output].description;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_screen_get_output_config( CoreScreen *screen,
+ int output,
+ DFBScreenOutputConfig *ret_config )
+{
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( output >= 0 );
+ D_ASSERT( output < screen->shared->description.outputs );
+ D_ASSERT( ret_config != NULL );
+
+ /* Return current output configuration. */
+ *ret_config = screen->shared->outputs[output].configuration;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_screen_test_output_config( CoreScreen *screen,
+ int output,
+ const DFBScreenOutputConfig *config,
+ DFBScreenOutputConfigFlags *ret_failed )
+{
+ DFBResult ret;
+ DFBScreenOutputConfigFlags failed = DSOCONF_NONE;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( screen->funcs != NULL );
+ D_ASSERT( screen->funcs->TestOutputConfig != NULL );
+ D_ASSERT( output >= 0 );
+ D_ASSERT( output < screen->shared->description.outputs );
+ D_ASSERT( config != NULL );
+ D_ASSERT( config->flags == screen->shared->outputs[output].configuration.flags );
+
+ /* Test the output configuration. */
+ ret = screen->funcs->TestOutputConfig( screen,
+ screen->driver_data,
+ screen->screen_data,
+ output, config, &failed );
+
+ D_ASSUME( (ret == DFB_OK && !failed) || (ret != DFB_OK && failed) );
+
+ if (ret_failed)
+ *ret_failed = failed;
+
+ return ret;
+}
+
+DFBResult
+dfb_screen_set_output_config( CoreScreen *screen,
+ int output,
+ const DFBScreenOutputConfig *config )
+{
+ DFBResult ret;
+ DFBScreenOutputConfigFlags failed = DSOCONF_NONE;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( screen->funcs != NULL );
+ D_ASSERT( screen->funcs->TestOutputConfig != NULL );
+ D_ASSERT( screen->funcs->SetOutputConfig != NULL );
+ D_ASSERT( output >= 0 );
+ D_ASSERT( output < screen->shared->description.outputs );
+ D_ASSERT( config != NULL );
+ D_ASSERT( config->flags == screen->shared->outputs[output].configuration.flags );
+
+ /* Test configuration first. */
+ ret = screen->funcs->TestOutputConfig( screen,
+ screen->driver_data,
+ screen->screen_data,
+ output, config, &failed );
+
+ D_ASSUME( (ret == DFB_OK && !failed) || (ret != DFB_OK && failed) );
+
+ if (ret)
+ return ret;
+
+ /* Set configuration afterwards. */
+ ret = screen->funcs->SetOutputConfig( screen,
+ screen->driver_data,
+ screen->screen_data,
+ output, config );
+ if (ret)
+ return ret;
+
+ /* Store current configuration. */
+ screen->shared->outputs[output].configuration = *config;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_screen_get_screen_size( CoreScreen *screen,
+ int *ret_width,
+ int *ret_height )
+{
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->funcs != NULL );
+ D_ASSERT( screen->funcs->GetScreenSize != NULL );
+ D_ASSERT( ret_width != NULL );
+ D_ASSERT( ret_height != NULL );
+
+ return screen->funcs->GetScreenSize( screen,
+ screen->driver_data, screen->screen_data,
+ ret_width, ret_height );
+}
+
+DFBResult
+dfb_screen_get_layer_dimension( CoreScreen *screen,
+ CoreLayer *layer,
+ int *ret_width,
+ int *ret_height )
+{
+ int i;
+ DFBResult ret = DFB_UNSUPPORTED;
+ CoreScreenShared *shared;
+ ScreenFuncs *funcs;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+ D_ASSERT( screen->funcs != NULL );
+ D_ASSERT( layer != NULL );
+ D_ASSERT( ret_width != NULL );
+ D_ASSERT( ret_height != NULL );
+
+ shared = screen->shared;
+ funcs = screen->funcs;
+
+ if (funcs->GetMixerState) {
+ for (i=0; i<shared->description.mixers; i++) {
+ const DFBScreenMixerConfig *config = &shared->mixers[i].configuration;
+
+ if ((config->flags & DSMCONF_LAYERS) &&
+ DFB_DISPLAYLAYER_IDS_HAVE( config->layers, dfb_layer_id(layer) ))
+ {
+ CoreMixerState state;
+
+ ret = funcs->GetMixerState( screen, screen->driver_data, screen->screen_data, i, &state );
+ if (ret == DFB_OK) {
+ if (state.flags & CMSF_DIMENSION) {
+ *ret_width = state.dimension.w;
+ *ret_height = state.dimension.h;
+
+ return DFB_OK;
+ }
+
+ ret = DFB_UNSUPPORTED;
+ }
+ }
+ }
+
+ for (i=0; i<shared->description.mixers; i++) {
+ const DFBScreenMixerDescription *desc = &shared->mixers[i].description;
+
+ if ((desc->caps & DSMCAPS_SUB_LAYERS) &&
+ DFB_DISPLAYLAYER_IDS_HAVE( desc->sub_layers, dfb_layer_id(layer) ))
+ {
+ CoreMixerState state;
+
+ ret = funcs->GetMixerState( screen, screen->driver_data, screen->screen_data, i, &state );
+ if (ret == DFB_OK) {
+ if (state.flags & CMSF_DIMENSION) {
+ *ret_width = state.dimension.w;
+ *ret_height = state.dimension.h;
+
+ return DFB_OK;
+ }
+
+ ret = DFB_UNSUPPORTED;
+ }
+ }
+ }
+ }
+
+ if (funcs->GetScreenSize)
+ ret = funcs->GetScreenSize( screen,
+ screen->driver_data, screen->screen_data,
+ ret_width, ret_height );
+
+ return ret;
+}
+
diff --git a/Source/DirectFB/src/core/screen.h b/Source/DirectFB/src/core/screen.h
new file mode 100755
index 0000000..b5491f4
--- /dev/null
+++ b/Source/DirectFB/src/core/screen.h
@@ -0,0 +1,122 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DFB__CORE__SCREEN_H__
+#define __DFB__CORE__SCREEN_H__
+
+#include <core/coretypes.h>
+
+DFBResult dfb_screen_get_info ( CoreScreen *screen,
+ DFBScreenID *ret_id,
+ DFBScreenDescription *ret_desc );
+
+
+/* Misc */
+
+DFBResult dfb_screen_suspend ( CoreScreen *screen );
+DFBResult dfb_screen_resume ( CoreScreen *screen );
+
+DFBResult dfb_screen_set_powermode ( CoreScreen *screen,
+ DFBScreenPowerMode mode );
+
+DFBResult dfb_screen_wait_vsync ( CoreScreen *screen );
+
+
+/* Mixers */
+
+DFBResult dfb_screen_get_mixer_info ( CoreScreen *screen,
+ int mixer,
+ DFBScreenMixerDescription *ret_desc );
+
+DFBResult dfb_screen_get_mixer_config ( CoreScreen *screen,
+ int mixer,
+ DFBScreenMixerConfig *ret_config );
+
+DFBResult dfb_screen_test_mixer_config( CoreScreen *screen,
+ int mixer,
+ const DFBScreenMixerConfig *config,
+ DFBScreenMixerConfigFlags *ret_failed );
+
+DFBResult dfb_screen_set_mixer_config ( CoreScreen *screen,
+ int mixer,
+ const DFBScreenMixerConfig *config );
+
+
+/* Encoders */
+
+DFBResult dfb_screen_get_encoder_info ( CoreScreen *screen,
+ int encoder,
+ DFBScreenEncoderDescription *ret_desc );
+
+DFBResult dfb_screen_get_encoder_config ( CoreScreen *screen,
+ int encoder,
+ DFBScreenEncoderConfig *ret_config );
+
+DFBResult dfb_screen_test_encoder_config( CoreScreen *screen,
+ int encoder,
+ const DFBScreenEncoderConfig *config,
+ DFBScreenEncoderConfigFlags *ret_failed );
+
+DFBResult dfb_screen_set_encoder_config ( CoreScreen *screen,
+ int encoder,
+ const DFBScreenEncoderConfig *config );
+
+
+/* Outputs */
+
+DFBResult dfb_screen_get_output_info ( CoreScreen *screen,
+ int output,
+ DFBScreenOutputDescription *ret_desc );
+
+DFBResult dfb_screen_get_output_config ( CoreScreen *screen,
+ int output,
+ DFBScreenOutputConfig *ret_config );
+
+DFBResult dfb_screen_test_output_config( CoreScreen *screen,
+ int output,
+ const DFBScreenOutputConfig *config,
+ DFBScreenOutputConfigFlags *ret_failed );
+
+DFBResult dfb_screen_set_output_config ( CoreScreen *screen,
+ int output,
+ const DFBScreenOutputConfig *config );
+
+
+/* Screen configuration */
+
+DFBResult dfb_screen_get_screen_size ( CoreScreen *screen,
+ int *ret_width,
+ int *ret_height );
+
+DFBResult dfb_screen_get_layer_dimension( CoreScreen *screen,
+ CoreLayer *layer,
+ int *ret_width,
+ int *ret_height );
+
+#endif
+
diff --git a/Source/DirectFB/src/core/screens.c b/Source/DirectFB/src/core/screens.c
new file mode 100755
index 0000000..708f5e8
--- /dev/null
+++ b/Source/DirectFB/src/core/screens.c
@@ -0,0 +1,591 @@
+/*
+ (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 <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/core_parts.h>
+
+#include <core/screen.h>
+#include <core/screens.h>
+#include <core/screens_internal.h>
+
+#include <core/layers.h>
+
+#include <misc/conf.h>
+
+
+D_DEBUG_DOMAIN( Core_Screen, "Core/Screen", "DirectFB Screen Core" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+
+ int num;
+ CoreScreenShared *screens[MAX_SCREENS];
+} DFBScreenCoreShared;
+
+struct __DFB_DFBScreenCore {
+ int magic;
+
+ CoreDFB *core;
+
+ DFBScreenCoreShared *shared;
+};
+
+
+DFB_CORE_PART( screen_core, ScreenCore );
+
+/**********************************************************************************************************************/
+
+static DFBScreenCoreShared *core_screens = NULL; /* FIXME */
+
+static int num_screens = 0; /* FIXME */
+static CoreScreen *screens[MAX_SCREENS] = { NULL }; /* FIXME */
+
+
+static DFBResult
+dfb_screen_core_initialize( CoreDFB *core,
+ DFBScreenCore *data,
+ DFBScreenCoreShared *shared )
+{
+ int i;
+ DFBResult ret;
+ FusionSHMPoolShared *pool;
+
+ D_DEBUG_AT( Core_Screen, "dfb_screen_core_initialize( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( shared != NULL );
+
+ data->core = core;
+ data->shared = shared;
+
+ core_screens = shared; /* FIXME */
+
+ pool = dfb_core_shmpool( core );
+
+ /* Initialize all registered screens. */
+ for (i=0; i<num_screens; i++) {
+ char buf[24];
+ CoreScreenShared *sshared;
+ CoreScreen *screen = screens[i];
+ ScreenFuncs *funcs = screen->funcs;
+ DFBScreenDescription desc = { .caps = DSCCAPS_NONE };
+
+ /* Allocate shared data. */
+ sshared = SHCALLOC( pool, 1, sizeof(CoreScreenShared) );
+
+ /* Assign ID (zero based index). */
+ sshared->screen_id = i;
+
+ snprintf( buf, sizeof(buf), "Screen %d", i );
+
+ /* Initialize the lock. */
+ if (fusion_skirmish_init( &sshared->lock, buf, dfb_core_world(core) )) {
+ SHFREE( pool, sshared );
+ return DFB_FUSION;
+ }
+
+ /* Allocate driver's screen data. */
+ if (funcs->ScreenDataSize) {
+ int size = funcs->ScreenDataSize();
+
+ if (size > 0) {
+ sshared->screen_data = SHCALLOC( pool, 1, size );
+ if (!sshared->screen_data) {
+ fusion_skirmish_destroy( &sshared->lock );
+ SHFREE( pool, sshared );
+ return D_OOSHM();
+ }
+ }
+ }
+
+ /* Initialize the screen and get the screen description. */
+ ret = funcs->InitScreen( screen,
+ screen->device,
+ screen->driver_data,
+ sshared->screen_data,
+ &desc );
+ if (ret) {
+ D_ERROR("DirectFB/Core/screens: "
+ "Failed to initialize screen %d!\n", sshared->screen_id);
+
+ fusion_skirmish_destroy( &sshared->lock );
+
+ if (sshared->screen_data)
+ SHFREE( pool, sshared->screen_data );
+
+ SHFREE( pool, sshared );
+
+ return ret;
+ }
+
+ D_ASSUME( desc.mixers > 0 || !(desc.caps & DSCCAPS_MIXERS) );
+ D_ASSUME( desc.mixers == 0 || (desc.caps & DSCCAPS_MIXERS) );
+
+ D_ASSUME( desc.encoders > 0 || !(desc.caps & DSCCAPS_ENCODERS) );
+ D_ASSUME( desc.encoders == 0 || (desc.caps & DSCCAPS_ENCODERS) );
+
+ D_ASSUME( desc.outputs > 0 || !(desc.caps & DSCCAPS_OUTPUTS) );
+ D_ASSUME( desc.outputs == 0 || (desc.caps & DSCCAPS_OUTPUTS) );
+
+ D_ASSERT( desc.mixers >= 0 );
+ D_ASSERT( desc.mixers <= 32 );
+ D_ASSERT( desc.encoders >= 0 );
+ D_ASSERT( desc.encoders <= 32 );
+ D_ASSERT( desc.outputs >= 0 );
+ D_ASSERT( desc.outputs <= 32 );
+
+ /* Store description in sshared memory. */
+ sshared->description = desc;
+
+ /* Initialize mixers. */
+ if (sshared->description.mixers) {
+ int i;
+
+ D_ASSERT( funcs->InitMixer != NULL );
+ D_ASSERT( funcs->SetMixerConfig != NULL );
+
+ sshared->mixers = SHCALLOC( pool, sshared->description.mixers,
+ sizeof(CoreScreenMixer) );
+ for (i=0; i<sshared->description.mixers; i++) {
+ funcs->InitMixer( screen,
+ screen->driver_data,
+ sshared->screen_data, i,
+ &sshared->mixers[i].description,
+ &sshared->mixers[i].configuration );
+ funcs->SetMixerConfig( screen,
+ screen->driver_data,
+ sshared->screen_data, i,
+ &sshared->mixers[i].configuration );
+ }
+ }
+
+ /* Initialize encoders. */
+ if (sshared->description.encoders) {
+ int i;
+
+ D_ASSERT( funcs->InitEncoder != NULL );
+ D_ASSERT( funcs->SetEncoderConfig != NULL );
+
+ sshared->encoders = SHCALLOC( pool, sshared->description.encoders,
+ sizeof(CoreScreenEncoder) );
+ for (i=0; i<sshared->description.encoders; i++) {
+ funcs->InitEncoder( screen,
+ screen->driver_data,
+ sshared->screen_data, i,
+ &sshared->encoders[i].description,
+ &sshared->encoders[i].configuration );
+ funcs->SetEncoderConfig( screen,
+ screen->driver_data,
+ sshared->screen_data, i,
+ &sshared->encoders[i].configuration );
+ }
+ }
+
+ /* Initialize outputs. */
+ if (sshared->description.outputs) {
+ int i;
+
+ D_ASSERT( funcs->InitOutput != NULL );
+ D_ASSERT( funcs->SetOutputConfig != NULL );
+
+ sshared->outputs = SHCALLOC( pool, sshared->description.outputs,
+ sizeof(CoreScreenOutput) );
+ for (i=0; i<sshared->description.outputs; i++) {
+ funcs->InitOutput( screen,
+ screen->driver_data,
+ sshared->screen_data, i,
+ &sshared->outputs[i].description,
+ &sshared->outputs[i].configuration );
+ funcs->SetOutputConfig( screen,
+ screen->driver_data,
+ sshared->screen_data, i,
+ &sshared->outputs[i].configuration );
+ }
+ }
+
+ /* Make a copy for faster access. */
+ screen->screen_data = sshared->screen_data;
+
+ /* Store pointer to sshared data and core. */
+ screen->shared = sshared;
+ screen->core = core;
+
+ /* Add the screen to the sshared list. */
+ core_screens->screens[ core_screens->num++ ] = sshared;
+ }
+
+
+ D_MAGIC_SET( data, DFBScreenCore );
+ D_MAGIC_SET( shared, DFBScreenCoreShared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_screen_core_join( CoreDFB *core,
+ DFBScreenCore *data,
+ DFBScreenCoreShared *shared )
+{
+ int i;
+
+ D_DEBUG_AT( Core_Screen, "dfb_screen_core_join( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_MAGIC_ASSERT( shared, DFBScreenCoreShared );
+
+ data->core = core;
+ data->shared = shared;
+
+ core_screens = shared; /* FIXME */
+
+ if (num_screens != core_screens->num) {
+ D_ERROR("DirectFB/core/screens: Number of screens does not match!\n");
+ return DFB_BUG;
+ }
+
+ for (i=0; i<num_screens; i++) {
+ CoreScreen *screen = screens[i];
+ CoreScreenShared *shared = core_screens->screens[i];
+
+ /* Make a copy for faster access. */
+ screen->screen_data = shared->screen_data;
+
+ /* Store pointer to shared data and core. */
+ screen->shared = shared;
+ screen->core = core;
+ }
+
+
+ D_MAGIC_SET( data, DFBScreenCore );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_screen_core_shutdown( DFBScreenCore *data,
+ bool emergency )
+{
+ int i;
+ FusionSHMPoolShared *pool;
+ DFBScreenCoreShared *shared;
+
+ D_DEBUG_AT( Core_Screen, "dfb_screen_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBScreenCore );
+ D_MAGIC_ASSERT( data->shared, DFBScreenCoreShared );
+
+ shared = data->shared;
+
+ pool = dfb_core_shmpool( data->core );
+
+ /* Begin with the most recently added screen. */
+ for (i=num_screens-1; i>=0; i--) {
+ CoreScreen *screen = screens[i];
+ CoreScreenShared *shared = screen->shared;
+
+ /* Deinitialize the lock. */
+ fusion_skirmish_destroy( &shared->lock );
+
+ /* Free the driver's screen data. */
+ if (shared->screen_data)
+ SHFREE( pool, shared->screen_data );
+
+ /* Free mixer data. */
+ if (shared->mixers)
+ SHFREE( pool, shared->mixers );
+
+ /* Free encoder data. */
+ if (shared->encoders)
+ SHFREE( pool, shared->encoders );
+
+ /* Free output data. */
+ if (shared->outputs)
+ SHFREE( pool, shared->outputs );
+
+ /* Free the shared screen data. */
+ SHFREE( pool, shared );
+
+ /* Free the local screen data. */
+ D_FREE( screen );
+ }
+
+ core_screens = NULL;
+ num_screens = 0;
+
+
+ D_MAGIC_CLEAR( data );
+ D_MAGIC_CLEAR( shared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_screen_core_leave( DFBScreenCore *data,
+ bool emergency )
+{
+ int i;
+ DFBScreenCoreShared *shared;
+
+ D_DEBUG_AT( Core_Screen, "dfb_screen_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBScreenCore );
+ D_MAGIC_ASSERT( data->shared, DFBScreenCoreShared );
+
+ shared = data->shared;
+
+
+ /* Deinitialize all local stuff only. */
+ for (i=0; i<num_screens; i++) {
+ CoreScreen *screen = screens[i];
+
+ /* Free local screen data. */
+ D_FREE( screen );
+ }
+
+ core_screens = NULL;
+ num_screens = 0;
+
+
+ D_MAGIC_CLEAR( data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_screen_core_suspend( DFBScreenCore *data )
+{
+ int i;
+ DFBScreenCoreShared *shared;
+
+ D_DEBUG_AT( Core_Screen, "dfb_screen_core_suspend( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBScreenCore );
+ D_MAGIC_ASSERT( data->shared, DFBScreenCoreShared );
+
+ shared = data->shared;
+
+ for (i=num_screens-1; i>=0; i--)
+ dfb_screen_suspend( screens[i] );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_screen_core_resume( DFBScreenCore *data )
+{
+ int i;
+ DFBScreenCoreShared *shared;
+
+ D_DEBUG_AT( Core_Screen, "dfb_screen_core_resume( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBScreenCore );
+ D_MAGIC_ASSERT( data->shared, DFBScreenCoreShared );
+
+ shared = data->shared;
+
+ for (i=0; i<num_screens; i++)
+ dfb_screen_resume( screens[i] );
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+CoreScreen *
+dfb_screens_register( CoreGraphicsDevice *device,
+ void *driver_data,
+ ScreenFuncs *funcs )
+{
+ CoreScreen *screen;
+
+ D_ASSERT( funcs != NULL );
+
+ if (num_screens == MAX_SCREENS) {
+ D_ERROR( "DirectFB/Core/screen: "
+ "Maximum number of screens reached!\n" );
+ return NULL;
+ }
+
+ /* allocate local data */
+ screen = D_CALLOC( 1, sizeof(CoreScreen) );
+
+ /* assign local pointers */
+ screen->device = device;
+ screen->driver_data = driver_data;
+ screen->funcs = funcs;
+
+ /* add it to the local list */
+ screens[num_screens++] = screen;
+
+ return screen;
+}
+
+typedef void (*AnyFunc)( void );
+
+CoreScreen *
+dfb_screens_hook_primary( CoreGraphicsDevice *device,
+ void *driver_data,
+ ScreenFuncs *funcs,
+ ScreenFuncs *primary_funcs,
+ void **primary_driver_data )
+{
+ int i;
+ int entries;
+ CoreScreen *primary = screens[0];
+
+ D_ASSERT( primary != NULL );
+ D_ASSERT( device != NULL );
+ D_ASSERT( funcs != NULL );
+
+ /* copy content of original function table */
+ if (primary_funcs)
+ direct_memcpy( primary_funcs, primary->funcs, sizeof(ScreenFuncs) );
+
+ /* copy pointer to original driver data */
+ if (primary_driver_data)
+ *primary_driver_data = primary->driver_data;
+
+ /* replace all entries in the old table that aren't NULL in the new one */
+ entries = sizeof(ScreenFuncs) / sizeof(void(*)( void ));
+ for (i=0; i<entries; i++) {
+ AnyFunc *newfuncs = (AnyFunc*) funcs;
+ AnyFunc *oldfuncs = (AnyFunc*) primary->funcs;
+
+ if (newfuncs[i])
+ oldfuncs[i] = newfuncs[i];
+ }
+
+ /* replace device and driver data pointer */
+ primary->device = device;
+ primary->driver_data = driver_data;
+
+ return primary;
+}
+
+CoreScreen *
+dfb_screens_register_primary( CoreGraphicsDevice *device,
+ void *driver_data,
+ ScreenFuncs *funcs )
+{
+ CoreScreen *primary = screens[0];
+
+ D_ASSERT( primary != NULL );
+ D_ASSERT( funcs != NULL );
+ D_ASSERT( num_screens > 0 );
+
+ /* replace device, function table and driver data pointer */
+ primary->device = device;
+ primary->funcs = funcs;
+ primary->driver_data = driver_data;
+
+ return primary;
+}
+
+void
+dfb_screens_enumerate( CoreScreenCallback callback,
+ void *ctx )
+{
+ int i;
+
+ D_ASSERT( core_screens != NULL );
+ D_ASSERT( callback != NULL );
+
+ for (i=0; i<num_screens; i++) {
+ if (callback( screens[i], ctx ) == DFENUM_CANCEL)
+ break;
+ }
+}
+
+CoreScreen *
+dfb_screens_at( DFBScreenID screen_id )
+{
+ D_ASSERT( screen_id >= 0);
+ D_ASSERT( screen_id < num_screens);
+
+ return screens[screen_id];
+}
+
+CoreScreen *
+dfb_screens_at_translated( DFBScreenID screen_id )
+{
+ CoreScreen *primary;
+
+ D_ASSERT( screen_id >= 0);
+ D_ASSERT( screen_id < num_screens);
+
+ if (dfb_config->primary_layer > 0) {
+ primary = dfb_layer_screen( dfb_layer_at_translated( DLID_PRIMARY ) );
+
+ if (screen_id == DSCID_PRIMARY)
+ return primary;
+
+ if (screen_id == primary->shared->screen_id)
+ return dfb_screens_at( DSCID_PRIMARY );
+ }
+
+ return dfb_screens_at( screen_id );
+}
+
+DFBScreenID
+dfb_screen_id_translated( CoreScreen *screen )
+{
+ CoreScreenShared *shared;
+ CoreScreen *primary;
+
+ D_ASSERT( screen != NULL );
+ D_ASSERT( screen->shared != NULL );
+
+ shared = screen->shared;
+
+ if (dfb_config->primary_layer > 0) {
+ primary = dfb_layer_screen( dfb_layer_at_translated( DLID_PRIMARY ) );
+
+ if (shared->screen_id == DSCID_PRIMARY)
+ return primary->shared->screen_id;
+
+ if (shared->screen_id == primary->shared->screen_id)
+ return DSCID_PRIMARY;
+ }
+
+ return shared->screen_id;
+}
+
diff --git a/Source/DirectFB/src/core/screens.h b/Source/DirectFB/src/core/screens.h
new file mode 100755
index 0000000..1ebaa4e
--- /dev/null
+++ b/Source/DirectFB/src/core/screens.h
@@ -0,0 +1,263 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DFB__CORE__SCREENS_H__
+#define __DFB__CORE__SCREENS_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+
+typedef DFBEnumerationResult (*CoreScreenCallback) (CoreScreen *screen,
+ void *ctx);
+
+typedef enum {
+ CMSF_NONE = 0x00000000, /* none of these */
+
+ CMSF_DIMENSION = 0x00000001, /* dimension is set */
+
+ CMSF_ALL = 0x00000001, /* all of these */
+} CoreMixerStateFlags;
+
+typedef struct {
+ CoreMixerStateFlags flags;
+
+ DFBDimension dimension;
+} CoreMixerState;
+
+typedef struct {
+ /** Driver Control **/
+
+ /*
+ * Return size of screen data (shared memory).
+ */
+ int (*ScreenDataSize)(void);
+
+ /*
+ * Called once by the master to initialize screen data and reset hardware.
+ * Driver has to fill the screen description.
+ */
+ DFBResult (*InitScreen) ( CoreScreen *screen,
+ CoreGraphicsDevice *device,
+ void *driver_data,
+ void *screen_data,
+ DFBScreenDescription *description );
+
+ /*
+ * Called once by the master for each mixer.
+ * Driver fills description and default config.
+ */
+ DFBResult (*InitMixer) ( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int mixer,
+ DFBScreenMixerDescription *description,
+ DFBScreenMixerConfig *config );
+
+ /*
+ * Called once by the master for each encoder.
+ * Driver fills description and default config.
+ */
+ DFBResult (*InitEncoder) ( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int encoder,
+ DFBScreenEncoderDescription *description,
+ DFBScreenEncoderConfig *config );
+
+ /*
+ * Called once by the master for each output.
+ * Driver fills description and default config.
+ */
+ DFBResult (*InitOutput) ( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int output,
+ DFBScreenOutputDescription *description,
+ DFBScreenOutputConfig *config );
+
+
+ /** Power management **/
+
+ /*
+ * Switch between "on", "standby", "suspend" and "off".
+ */
+ DFBResult (*SetPowerMode) ( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ DFBScreenPowerMode mode );
+
+
+ /** Synchronization **/
+
+ /*
+ * Wait for the vertical retrace.
+ */
+ DFBResult (*WaitVSync) ( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data );
+
+
+ /** Mixer configuration **/
+
+ /*
+ * Test if configuration is supported. Store failing fields in 'failed'.
+ */
+ DFBResult (*TestMixerConfig)( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int mixer,
+ const DFBScreenMixerConfig *config,
+ DFBScreenMixerConfigFlags *failed );
+
+ /*
+ * Set new configuration.
+ */
+ DFBResult (*SetMixerConfig) ( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int mixer,
+ const DFBScreenMixerConfig *config );
+
+
+ /** Encoder configuration **/
+
+ /*
+ * Test if configuration is supported. Store failing fields in 'failed'.
+ */
+ DFBResult (*TestEncoderConfig)( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int encoder,
+ const DFBScreenEncoderConfig *config,
+ DFBScreenEncoderConfigFlags *failed );
+
+ /*
+ * Set new configuration.
+ */
+ DFBResult (*SetEncoderConfig) ( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int encoder,
+ const DFBScreenEncoderConfig *config );
+
+
+ /** Output configuration **/
+
+ /*
+ * Test if configuration is supported. Store failing fields in 'failed'.
+ */
+ DFBResult (*TestOutputConfig)( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int output,
+ const DFBScreenOutputConfig *config,
+ DFBScreenOutputConfigFlags *failed );
+
+ /*
+ * Set new configuration.
+ */
+ DFBResult (*SetOutputConfig) ( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int output,
+ const DFBScreenOutputConfig *config );
+
+
+ /** Screen configuration **/
+
+ /*
+ * Return the screen size, e.g. as a basis for positioning a layer.
+ *
+ * This function might be replaced soon.
+ */
+ DFBResult (*GetScreenSize) ( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int *ret_width,
+ int *ret_height );
+
+
+ /** States **/
+
+ DFBResult (*GetMixerState) ( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int mixer,
+ CoreMixerState *ret_state );
+} ScreenFuncs;
+
+
+/*
+ * Add a screen to a graphics device by pointing to a table containing
+ * driver functions. The driver data will be passed to these functions.
+ */
+CoreScreen *dfb_screens_register( CoreGraphicsDevice *device,
+ void *driver_data,
+ ScreenFuncs *funcs );
+
+/*
+ * Replace functions of the primary screen implementation by passing
+ * an alternative driver function table. All non-NULL functions in the new
+ * table replace the functions in the original function table.
+ * The original function table is written to 'primary_funcs' before to allow
+ * drivers to use existing functionality from the original implementation.
+ */
+CoreScreen *dfb_screens_hook_primary( CoreGraphicsDevice *device,
+ void *driver_data,
+ ScreenFuncs *funcs,
+ ScreenFuncs *primary_funcs,
+ void **primary_driver_data );
+
+/*
+ * Replace the default implementation for the primary screen.
+ */
+CoreScreen *dfb_screens_register_primary( CoreGraphicsDevice *device,
+ void *driver_data,
+ ScreenFuncs *funcs );
+
+/*
+ * Enumerate all registered screens by invoking the callback for each screen.
+ */
+void dfb_screens_enumerate( CoreScreenCallback callback,
+ void *ctx );
+
+/*
+ * Returns the screen with the specified ID.
+ */
+CoreScreen *dfb_screens_at( DFBScreenID screen_id );
+
+CoreScreen *dfb_screens_at_translated( DFBScreenID screen_id );
+
+/*
+ * Return the (translated) ID of the specified screen.
+ */
+DFBScreenID dfb_screen_id_translated( CoreScreen *screen );
+
+#endif
diff --git a/Source/DirectFB/src/core/screens_internal.h b/Source/DirectFB/src/core/screens_internal.h
new file mode 100755
index 0000000..361b571
--- /dev/null
+++ b/Source/DirectFB/src/core/screens_internal.h
@@ -0,0 +1,81 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DFB__CORE__SCREENS_INTERNAL_H__
+#define __DFB__CORE__SCREENS_INTERNAL_H__
+
+#include <directfb.h>
+
+#include <fusion/lock.h>
+
+#include <core/coretypes.h>
+#include <core/screens.h>
+
+typedef struct {
+ DFBScreenMixerDescription description;
+ DFBScreenMixerConfig configuration;
+} CoreScreenMixer;
+
+typedef struct {
+ DFBScreenEncoderDescription description;
+ DFBScreenEncoderConfig configuration;
+} CoreScreenEncoder;
+
+typedef struct {
+ DFBScreenOutputDescription description;
+ DFBScreenOutputConfig configuration;
+} CoreScreenOutput;
+
+typedef struct {
+ FusionSkirmish lock;
+
+ DFBScreenID screen_id;
+
+ DFBScreenDescription description;
+
+ CoreScreenMixer *mixers;
+ CoreScreenEncoder *encoders;
+ CoreScreenOutput *outputs;
+
+ void *screen_data;
+} CoreScreenShared;
+
+struct __DFB_CoreScreen {
+ CoreScreenShared *shared;
+
+ CoreDFB *core;
+ CoreGraphicsDevice *device;
+
+ ScreenFuncs *funcs;
+
+ void *driver_data;
+ void *screen_data; /* copy of shared->screen_data */
+};
+
+#endif
+
diff --git a/Source/DirectFB/src/core/shared_surface_pool.c b/Source/DirectFB/src/core/shared_surface_pool.c
new file mode 100755
index 0000000..5199a84
--- /dev/null
+++ b/Source/DirectFB/src/core/shared_surface_pool.c
@@ -0,0 +1,227 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/debug.h>
+
+#include <fusion/conf.h>
+#include <fusion/shmalloc.h>
+#include <fusion/shm/pool.h>
+
+#include <core/core.h>
+#include <core/surface_pool.h>
+
+#include <misc/conf.h>
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ FusionSHMPoolShared *shmpool;
+} SharedPoolData;
+
+typedef struct {
+ CoreDFB *core;
+ FusionWorld *world;
+} SharedPoolLocalData;
+
+typedef struct {
+ void *addr;
+ int pitch;
+ int size;
+} SharedAllocationData;
+
+/**********************************************************************************************************************/
+
+static int
+sharedPoolDataSize( void )
+{
+ return sizeof(SharedPoolData);
+}
+
+static int
+sharedPoolLocalDataSize( void )
+{
+ return sizeof(SharedPoolLocalData);
+}
+
+static int
+sharedAllocationDataSize( void )
+{
+ return sizeof(SharedAllocationData);
+}
+
+static DFBResult
+sharedInitPool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data,
+ CoreSurfacePoolDescription *ret_desc )
+{
+ DFBResult ret;
+ SharedPoolData *data = pool_data;
+ SharedPoolLocalData *local = pool_local;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( ret_desc != NULL );
+
+ local->core = core;
+ local->world = dfb_core_world( core );
+
+ ret = fusion_shm_pool_create( local->world, "Surface Memory Pool", dfb_config->surface_shmpool_size,
+ fusion_config->debugshm, &data->shmpool );
+ if (ret)
+ return ret;
+
+ ret_desc->caps = CSPCAPS_NONE;
+ ret_desc->access[CSAID_CPU] = CSAF_READ | CSAF_WRITE | CSAF_SHARED;
+ ret_desc->access[CSAID_LAYER0] = CSAF_READ | CSAF_SHARED;
+ ret_desc->access[CSAID_LAYER1] = CSAF_READ | CSAF_SHARED;
+ ret_desc->types = CSTF_LAYER | CSTF_WINDOW | CSTF_CURSOR | CSTF_FONT | CSTF_SHARED | CSTF_INTERNAL;
+ ret_desc->priority = CSPP_DEFAULT;
+
+ snprintf( ret_desc->name, DFB_SURFACE_POOL_DESC_NAME_LENGTH, "Shared Memory" );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sharedDestroyPool( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local )
+{
+ SharedPoolData *data = pool_data;
+ SharedPoolLocalData *local = pool_local;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ fusion_shm_pool_destroy( local->world, data->shmpool );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sharedAllocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ CoreSurface *surface;
+ SharedPoolData *data = pool_data;
+ SharedAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ dfb_surface_calc_buffer_size( surface, 8, 0, &alloc->pitch, &alloc->size );
+
+ alloc->addr = SHMALLOC( data->shmpool, alloc->size );
+ if (!alloc->addr)
+ return D_OOSHM();
+
+ allocation->flags = CSALF_VOLATILE;
+ allocation->size = alloc->size;
+
+ return DFB_OK;
+}
+
+static DFBResult
+sharedDeallocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ SharedPoolData *data = pool_data;
+ SharedAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ SHFREE( data->shmpool, alloc->addr );
+
+ return DFB_OK;
+}
+
+static DFBResult
+sharedLock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ SharedAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ lock->addr = alloc->addr;
+ lock->pitch = alloc->pitch;
+
+ return DFB_OK;
+}
+
+static DFBResult
+sharedUnlock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ return DFB_OK;
+}
+
+const SurfacePoolFuncs sharedSurfacePoolFuncs = {
+ .PoolDataSize = sharedPoolDataSize,
+ .PoolLocalDataSize = sharedPoolLocalDataSize,
+ .AllocationDataSize = sharedAllocationDataSize,
+ .InitPool = sharedInitPool,
+ .DestroyPool = sharedDestroyPool,
+
+ .AllocateBuffer = sharedAllocateBuffer,
+ .DeallocateBuffer = sharedDeallocateBuffer,
+
+ .Lock = sharedLock,
+ .Unlock = sharedUnlock,
+};
+
diff --git a/Source/DirectFB/src/core/state.c b/Source/DirectFB/src/core/state.c
new file mode 100755
index 0000000..8ae97e0
--- /dev/null
+++ b/Source/DirectFB/src/core/state.c
@@ -0,0 +1,416 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <string.h>
+
+#include <pthread.h>
+
+#include <fusion/fusion.h>
+#include <fusion/reactor.h>
+
+#include <directfb.h>
+
+#include <core/core.h>
+#include <core/coretypes.h>
+
+#include <core/palette.h>
+#include <core/state.h>
+#include <core/surface.h>
+
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/util.h>
+
+#include <misc/conf.h>
+
+
+static inline void
+validate_clip( CardState *state,
+ int xmax,
+ int ymax,
+ bool warn )
+{
+ D_MAGIC_ASSERT( state, CardState );
+ DFB_REGION_ASSERT( &state->clip );
+
+ D_ASSERT( xmax >= 0 );
+ D_ASSERT( ymax >= 0 );
+ D_ASSERT( state->clip.x1 <= state->clip.x2 );
+ D_ASSERT( state->clip.y1 <= state->clip.y2 );
+
+ if (state->clip.x1 <= xmax &&
+ state->clip.y1 <= ymax &&
+ state->clip.x2 <= xmax &&
+ state->clip.y2 <= ymax)
+ return;
+
+ if (warn)
+ D_WARN( "Clip %d,%d-%dx%d invalid, adjusting to fit %dx%d",
+ DFB_RECTANGLE_VALS_FROM_REGION( &state->clip ), xmax+1, ymax+1 );
+
+ if (state->clip.x1 > xmax)
+ state->clip.x1 = xmax;
+
+ if (state->clip.y1 > ymax)
+ state->clip.y1 = ymax;
+
+ if (state->clip.x2 > xmax)
+ state->clip.x2 = xmax;
+
+ if (state->clip.y2 > ymax)
+ state->clip.y2 = ymax;
+
+ state->modified |= SMF_CLIP;
+}
+
+int
+dfb_state_init( CardState *state, CoreDFB *core )
+{
+ D_ASSERT( state != NULL );
+
+ memset( state, 0, sizeof(CardState) );
+
+ state->core = core;
+ state->fusion_id = fusion_id( dfb_core_world(core) );
+ state->modified = SMF_ALL;
+ state->src_blend = DSBF_SRCALPHA;
+ state->dst_blend = DSBF_INVSRCALPHA;
+ state->render_options = dfb_config->render_options;
+
+ state->matrix[0] = 0x10000;
+ state->matrix[1] = 0x00000;
+ state->matrix[2] = 0x00000;
+ state->matrix[3] = 0x00000;
+ state->matrix[4] = 0x10000;
+ state->matrix[5] = 0x00000;
+ state->matrix[6] = 0x00000;
+ state->matrix[7] = 0x00000;
+ state->matrix[8] = 0x10000;
+ state->affine_matrix = DFB_TRUE;
+
+ state->from = CSBR_FRONT;
+ state->to = CSBR_BACK;
+
+ direct_util_recursive_pthread_mutex_init( &state->lock );
+
+ direct_serial_init( &state->dst_serial );
+ direct_serial_init( &state->src_serial );
+ direct_serial_init( &state->src_mask_serial );
+
+ D_MAGIC_SET( state, CardState );
+
+ return 0;
+}
+
+void
+dfb_state_destroy( CardState *state )
+{
+ D_MAGIC_ASSERT( state, CardState );
+
+ D_ASSUME( !(state->flags & CSF_DRAWING) );
+
+ D_ASSERT( state->destination == NULL );
+ D_ASSERT( state->source == NULL );
+ D_ASSERT( state->source_mask == NULL );
+
+ D_MAGIC_CLEAR( state );
+
+ direct_serial_deinit( &state->dst_serial );
+ direct_serial_deinit( &state->src_serial );
+ direct_serial_deinit( &state->src_mask_serial );
+
+ if (state->gfxs) {
+ GenefxState *gfxs = state->gfxs;
+
+ if (gfxs->ABstart)
+ D_FREE( gfxs->ABstart );
+
+ D_FREE( gfxs );
+ }
+
+ if (state->num_translation) {
+ D_ASSERT( state->index_translation != NULL );
+
+ D_FREE( state->index_translation );
+ }
+ else
+ D_ASSERT( state->index_translation == NULL );
+
+ pthread_mutex_destroy( &state->lock );
+}
+
+DFBResult
+dfb_state_set_destination( CardState *state, CoreSurface *destination )
+{
+ D_MAGIC_ASSERT( state, CardState );
+
+ dfb_state_lock( state );
+
+ D_ASSUME( !(state->flags & CSF_DRAWING) );
+
+ if (state->destination != destination) {
+ if (destination) {
+ if (dfb_surface_ref( destination )) {
+ D_WARN( "could not ref() destination" );
+ dfb_state_unlock( state );
+ return DFB_DEAD;
+ }
+
+ validate_clip( state, destination->config.size.w - 1, destination->config.size.h - 1, false );
+ }
+
+ if (state->destination) {
+ D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_DESTINATION ) );
+ dfb_surface_unref( state->destination );
+ }
+
+ state->destination = destination;
+ state->modified |= SMF_DESTINATION;
+
+ if (destination) {
+ direct_serial_copy( &state->dst_serial, &destination->serial );
+
+ D_FLAGS_SET( state->flags, CSF_DESTINATION );
+ }
+ else
+ D_FLAGS_CLEAR( state->flags, CSF_DESTINATION );
+ }
+
+ dfb_state_unlock( state );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_state_set_source( CardState *state, CoreSurface *source )
+{
+ D_MAGIC_ASSERT( state, CardState );
+
+ dfb_state_lock( state );
+
+ if (state->source != source) {
+ if (source && dfb_surface_ref( source )) {
+ D_WARN( "could not ref() source" );
+ dfb_state_unlock( state );
+ return DFB_DEAD;
+ }
+
+ if (state->source) {
+ D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_SOURCE ) );
+ dfb_surface_unref( state->source );
+ }
+
+ state->source = source;
+ state->modified |= SMF_SOURCE;
+
+ if (source) {
+ direct_serial_copy( &state->src_serial, &source->serial );
+
+ D_FLAGS_SET( state->flags, CSF_SOURCE );
+ }
+ else
+ D_FLAGS_CLEAR( state->flags, CSF_SOURCE );
+ }
+
+ dfb_state_unlock( state );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_state_set_source_mask( CardState *state, CoreSurface *source_mask )
+{
+ D_MAGIC_ASSERT( state, CardState );
+
+ dfb_state_lock( state );
+
+ if (state->source_mask != source_mask) {
+ if (source_mask && dfb_surface_ref( source_mask )) {
+ D_WARN( "could not ref() source mask" );
+ dfb_state_unlock( state );
+ return DFB_DEAD;
+ }
+
+ if (state->source_mask) {
+ D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_SOURCE_MASK ) );
+ dfb_surface_unref( state->source_mask );
+ }
+
+ state->source_mask = source_mask;
+ state->modified |= SMF_SOURCE_MASK;
+
+ if (source_mask) {
+ direct_serial_copy( &state->src_mask_serial, &source_mask->serial );
+
+ D_FLAGS_SET( state->flags, CSF_SOURCE_MASK );
+ }
+ else
+ D_FLAGS_CLEAR( state->flags, CSF_SOURCE_MASK );
+ }
+
+ dfb_state_unlock( state );
+
+ return DFB_OK;
+}
+
+void
+dfb_state_update( CardState *state, bool update_sources )
+{
+ CoreSurface *destination;
+
+ D_MAGIC_ASSERT( state, CardState );
+ DFB_REGION_ASSERT( &state->clip );
+
+ destination = state->destination;
+
+ if (D_FLAGS_IS_SET( state->flags, CSF_DESTINATION )) {
+
+ D_ASSERT( destination != NULL );
+
+ if (direct_serial_update( &state->dst_serial, &destination->serial )) {
+ validate_clip( state, destination->config.size.w - 1, destination->config.size.h - 1, true );
+
+ state->modified |= SMF_DESTINATION;
+ }
+ }
+ else if (destination)
+ validate_clip( state, destination->config.size.w - 1, destination->config.size.h - 1, true );
+
+ if (update_sources && D_FLAGS_IS_SET( state->flags, CSF_SOURCE )) {
+ CoreSurface *source = state->source;
+
+ D_ASSERT( source != NULL );
+
+ if (direct_serial_update( &state->src_serial, &source->serial ))
+ state->modified |= SMF_SOURCE;
+ }
+
+ if (update_sources && D_FLAGS_IS_SET( state->flags, CSF_SOURCE_MASK )) {
+ CoreSurface *source_mask = state->source_mask;
+
+ D_ASSERT( source_mask != NULL );
+
+ if (direct_serial_update( &state->src_mask_serial, &source_mask->serial ))
+ state->modified |= SMF_SOURCE_MASK;
+ }
+}
+
+DFBResult
+dfb_state_set_index_translation( CardState *state,
+ const int *indices,
+ int num_indices )
+{
+ D_MAGIC_ASSERT( state, CardState );
+
+ D_ASSERT( indices != NULL || num_indices == 0 );
+
+ dfb_state_lock( state );
+
+ if (state->num_translation != num_indices) {
+ int *new_trans = D_REALLOC( state->index_translation,
+ num_indices * sizeof(int) );
+
+ D_ASSERT( num_indices || new_trans == NULL );
+
+ if (num_indices && !new_trans) {
+ dfb_state_unlock( state );
+ return D_OOM();
+ }
+
+ state->index_translation = new_trans;
+ state->num_translation = num_indices;
+ }
+
+ if (num_indices)
+ direct_memcpy( state->index_translation, indices, num_indices * sizeof(int) );
+
+ state->modified |= SMF_INDEX_TRANSLATION;
+
+ dfb_state_unlock( state );
+
+ return DFB_OK;
+}
+
+void
+dfb_state_set_matrix( CardState *state,
+ const s32 *matrix )
+{
+ D_MAGIC_ASSERT( state, CardState );
+
+ D_ASSERT( matrix != NULL );
+
+ if (memcmp( state->matrix, matrix, sizeof(state->matrix) )) {
+ direct_memcpy( state->matrix, matrix, sizeof(state->matrix) );
+
+ state->affine_matrix = (matrix[6] == 0x00000 &&
+ matrix[7] == 0x00000 &&
+ matrix[8] == 0x10000);
+
+ state->modified |= SMF_MATRIX;
+ }
+}
+
+void
+dfb_state_set_color_or_index( CardState *state,
+ const DFBColor *color,
+ int index )
+{
+ CoreSurface *destination;
+ CorePalette *palette = NULL;
+
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( color != NULL );
+
+ destination = state->destination;
+ if (destination)
+ palette = destination->palette;
+
+ if (index < 0) {
+ D_ASSERT( color != NULL );
+
+ if (palette)
+ dfb_state_set_color_index( state, dfb_palette_search( palette,
+ color->r, color->g,
+ color->b, color->a ) );
+
+ dfb_state_set_color( state, color );
+ }
+ else {
+ dfb_state_set_color_index( state, index );
+
+ if (palette) {
+ D_ASSERT( palette->num_entries > 0 );
+ D_ASSUME( palette->num_entries > index );
+
+ dfb_state_set_color( state, &palette->entries[index % palette->num_entries] );
+ }
+ }
+}
+
diff --git a/Source/DirectFB/src/core/state.h b/Source/DirectFB/src/core/state.h
new file mode 100755
index 0000000..7eb7667
--- /dev/null
+++ b/Source/DirectFB/src/core/state.h
@@ -0,0 +1,362 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__STATE_H__
+#define __CORE__STATE_H__
+
+#include <pthread.h>
+
+#include <directfb.h>
+
+#include <direct/serial.h>
+
+#include <fusion/reactor.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/gfxcard.h>
+#include <core/surface_buffer.h>
+
+#include <gfx/generic/generic.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+
+typedef enum {
+ SMF_DRAWING_FLAGS = 0x00000001,
+ SMF_BLITTING_FLAGS = 0x00000002,
+ SMF_CLIP = 0x00000004,
+ SMF_COLOR = 0x00000008,
+ SMF_SRC_BLEND = 0x00000010,
+ SMF_DST_BLEND = 0x00000020,
+ SMF_SRC_COLORKEY = 0x00000040,
+ SMF_DST_COLORKEY = 0x00000080,
+
+ SMF_DESTINATION = 0x00000100,
+ SMF_SOURCE = 0x00000200,
+ SMF_SOURCE_MASK = 0x00000400,
+ SMF_SOURCE_MASK_VALS = 0x00000800,
+
+ SMF_INDEX_TRANSLATION = 0x00001000,
+ SMF_COLORKEY = 0x00002000,
+
+ SMF_RENDER_OPTIONS = 0x00010000,
+ SMF_MATRIX = 0x00020000,
+
+ SMF_ALL = 0x00033FFF
+} StateModificationFlags;
+
+typedef enum {
+ CSF_NONE = 0x00000000,
+
+ CSF_DESTINATION = 0x00000001, /* destination is set using dfb_state_set_destination() */
+ CSF_SOURCE = 0x00000002, /* source is set using dfb_state_set_source() */
+ CSF_SOURCE_MASK = 0x00000008, /* source mask is set using dfb_state_set_source_mask() */
+
+ CSF_SOURCE_LOCKED = 0x00000010, /* source surface is locked */
+ CSF_SOURCE_MASK_LOCKED = 0x00000020, /* source mask surface is locked */
+
+ CSF_DRAWING = 0x00010000, /* something has been rendered with this state,
+ this is cleared by flushing the state, e.g. upon flip */
+
+ CSF_ALL = 0x0001003B
+} CardStateFlags;
+
+struct _CardState {
+ int magic;
+
+ CoreDFB *core;
+ CoreGraphicsDevice *device;
+ FusionID fusion_id;
+
+ pthread_mutex_t lock; /* lock for state handling */
+
+ CardStateFlags flags;
+
+ StateModificationFlags modified; /* indicate which fields have been
+ modified, these flags will be
+ cleared by the gfx drivers */
+ StateModificationFlags mod_hw;
+
+ /* values forming the state for graphics operations */
+
+ DFBSurfaceDrawingFlags drawingflags; /* drawing flags */
+ DFBSurfaceBlittingFlags blittingflags; /* blitting flags */
+
+ DFBRegion clip; /* clipping rectangle */
+ DFBColor color; /* color for drawing or modulation */
+ unsigned int color_index; /* index to color in palette */
+ DFBSurfaceBlendFunction src_blend; /* blend function for source */
+ DFBSurfaceBlendFunction dst_blend; /* blend function for destination */
+ u32 src_colorkey; /* colorkey for source */
+ u32 dst_colorkey; /* colorkey for destination */
+
+ CoreSurface *destination; /* destination surface */
+ CoreSurface *source; /* source surface */
+
+ DirectSerial dst_serial; /* last destination surface serial */
+ DirectSerial src_serial; /* last source surface serial */
+
+ int *index_translation;
+ int num_translation;
+
+ /* hardware abstraction and state handling helpers */
+
+ DFBAccelerationMask accel; /* remember checked commands if they are accelerated */
+ DFBAccelerationMask checked; /* commands for which a state has been checked */
+ DFBAccelerationMask set; /* commands for which a state is valid */
+ DFBAccelerationMask disabled; /* commands which are disabled temporarily */
+
+ CoreGraphicsSerial serial; /* hardware serial of the last operation */
+
+ /* from/to buffers */
+
+ CoreSurfaceBufferRole from; /* usually CSBR_FRONT */
+ CoreSurfaceBufferRole to; /* usually CSBR_BACK */
+
+ /* read/write locks during operation */
+
+ CoreSurfaceBufferLock dst;
+ CoreSurfaceBufferLock src;
+
+ /* software driver */
+
+ GenefxState *gfxs;
+
+
+ /* extended state */
+
+ DFBSurfaceRenderOptions render_options;
+
+ DFBColorKey colorkey; /* key for color key protection */
+
+ s32 matrix[9]; /* transformation matrix for DSRO_MATRIX (fixed 16.16) */
+ DFBBoolean affine_matrix;
+
+ CoreSurface *source_mask; /* source mask surface */
+ CoreSurfaceBufferLock src_mask; /* source mask surface lock */
+ DirectSerial src_mask_serial; /* last source mask surface serial */
+ DFBPoint src_mask_offset; /* relative or absolute coordinates */
+ DFBSurfaceMaskFlags src_mask_flags; /* controls coordinate mode and more */
+
+ DFBColor colors[DFB_COLOR_IDS_MAX]; /* colors for drawing or modulation */
+ unsigned int color_indices[DFB_COLOR_IDS_MAX]; /* indices to colors in palette */
+};
+
+int dfb_state_init( CardState *state, CoreDFB *core );
+void dfb_state_destroy( CardState *state );
+
+DFBResult dfb_state_set_destination( CardState *state, CoreSurface *destination );
+DFBResult dfb_state_set_source( CardState *state, CoreSurface *source );
+DFBResult dfb_state_set_source_mask( CardState *state, CoreSurface *source_mask );
+
+void dfb_state_update( CardState *state, bool update_source );
+
+DFBResult dfb_state_set_index_translation( CardState *state,
+ const int *indices,
+ int num_indices );
+
+void dfb_state_set_matrix( CardState *state,
+ const s32 *matrix );
+
+static inline void
+dfb_state_get_serial( const CardState *state, CoreGraphicsSerial *ret_serial )
+{
+ D_ASSERT( state != NULL );
+ D_ASSERT( ret_serial != NULL );
+
+ *ret_serial = state->serial;
+}
+
+static inline void
+dfb_state_lock( CardState *state )
+{
+ D_MAGIC_ASSERT( state, CardState );
+
+ DFB_REGION_ASSERT( &state->clip );
+
+ pthread_mutex_lock( &state->lock );
+}
+
+static inline void
+dfb_state_start_drawing( CardState *state, CoreGraphicsDevice *device )
+{
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( device != NULL );
+ D_ASSERT( state->destination != NULL );
+
+ if (dfb_config->startstop) {
+ if (state->flags & CSF_DRAWING)
+ D_ASSERT( state->device == device );
+ else {
+ dfb_gfxcard_start_drawing( device, state );
+
+ state->flags = (CardStateFlags)(state->flags | CSF_DRAWING);
+ state->device = device;
+ }
+ }
+}
+
+static inline void
+dfb_state_stop_drawing( CardState *state )
+{
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( state->destination != NULL );
+
+ if (dfb_config->startstop) {
+ if (state->flags & CSF_DRAWING) {
+ D_ASSERT( state->device != NULL );
+
+ dfb_gfxcard_stop_drawing( state->device, state );
+
+ state->flags = (CardStateFlags)(state->flags & ~CSF_DRAWING);
+ state->device = NULL;
+ }
+ else
+ D_ASSERT( state->device == NULL );
+ }
+}
+
+static inline void
+dfb_state_unlock( CardState *state )
+{
+ D_MAGIC_ASSERT( state, CardState );
+
+ DFB_REGION_ASSERT( &state->clip );
+
+ pthread_mutex_unlock( &state->lock );
+}
+
+
+#define _dfb_state_set_checked(member,flag,state,value) \
+do { \
+ D_MAGIC_ASSERT( state, CardState ); \
+ \
+ if ((value) != (state)->member) { \
+ (state)->member = (value); \
+ (state)->modified |= SMF_##flag; \
+ } \
+} while (0)
+
+
+#define dfb_state_set_blitting_flags(state,flags) _dfb_state_set_checked( blittingflags, \
+ BLITTING_FLAGS, \
+ state, flags )
+
+#define dfb_state_set_drawing_flags(state,flags) _dfb_state_set_checked( drawingflags, \
+ DRAWING_FLAGS, \
+ state, flags )
+
+#define dfb_state_set_color_index(state,index) _dfb_state_set_checked( color_index, \
+ COLOR, \
+ state, index )
+
+#define dfb_state_set_src_blend(state,blend) _dfb_state_set_checked( src_blend, \
+ SRC_BLEND, \
+ state, blend )
+
+#define dfb_state_set_dst_blend(state,blend) _dfb_state_set_checked( dst_blend, \
+ DST_BLEND, \
+ state, blend )
+
+#define dfb_state_set_src_colorkey(state,key) _dfb_state_set_checked( src_colorkey, \
+ SRC_COLORKEY, \
+ state, key )
+
+#define dfb_state_set_dst_colorkey(state,key) _dfb_state_set_checked( dst_colorkey, \
+ DST_COLORKEY, \
+ state, key )
+
+#define dfb_state_set_render_options(state,opts) _dfb_state_set_checked( render_options, \
+ RENDER_OPTIONS, \
+ state, opts )
+
+static inline void dfb_state_set_clip( CardState *state, const DFBRegion *clip )
+{
+ D_MAGIC_ASSERT( state, CardState );
+ DFB_REGION_ASSERT( clip );
+
+ if (! DFB_REGION_EQUAL( state->clip, *clip )) {
+ state->clip = *clip;
+ state->modified = (StateModificationFlags)( state->modified | SMF_CLIP );
+ }
+}
+
+static inline void dfb_state_set_color( CardState *state, const DFBColor *color )
+{
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( color != NULL );
+
+ if (! DFB_COLOR_EQUAL( state->color, *color )) {
+ state->color = *color;
+ state->modified = (StateModificationFlags)( state->modified | SMF_COLOR );
+ }
+}
+
+static inline void dfb_state_set_colorkey( CardState *state, const DFBColorKey *key )
+{
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( key != NULL );
+
+ if (! DFB_COLORKEY_EQUAL( state->colorkey, *key )) {
+ state->colorkey = *key;
+ state->modified = (StateModificationFlags)( state->modified | SMF_COLOR );
+ }
+}
+
+static inline void dfb_state_set_source_mask_vals( CardState *state,
+ const DFBPoint *offset,
+ DFBSurfaceMaskFlags flags )
+{
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( offset != NULL );
+ D_FLAGS_ASSERT( flags, DSMF_ALL );
+
+ if (! DFB_POINT_EQUAL( state->src_mask_offset, *offset ) || state->src_mask_flags != flags) {
+ state->src_mask_offset = *offset;
+ state->src_mask_flags = flags;
+
+ state->modified = (StateModificationFlags)( state->modified | SMF_SOURCE_MASK_VALS );
+ }
+}
+
+/*
+ * Multifunctional color configuration function.
+ *
+ * Always tries to set both color and index.
+ *
+ * If color index is -1, color is used and searched in palette of destination surface if present.
+ * If color index is valid the color is looked up in palette if present.
+ */
+void dfb_state_set_color_or_index( CardState *state,
+ const DFBColor *color,
+ int index );
+
+#endif
+
diff --git a/Source/DirectFB/src/core/surface.c b/Source/DirectFB/src/core/surface.c
new file mode 100755
index 0000000..7b8e4fc
--- /dev/null
+++ b/Source/DirectFB/src/core/surface.c
@@ -0,0 +1,768 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/debug.h>
+
+#include <core/core.h>
+#include <core/palette.h>
+#include <core/surface.h>
+
+#include <core/layers_internal.h>
+#include <core/windows_internal.h>
+
+#include <gfx/convert.h>
+
+
+D_DEBUG_DOMAIN( Core_Surface, "Core/Surface", "DirectFB Core Surface" );
+
+/**********************************************************************************************************************/
+
+static const ReactionFunc dfb_surface_globals[] = {
+/* 0 */ _dfb_layer_region_surface_listener,
+/* 1 */ _dfb_windowstack_background_image_listener,
+ NULL
+};
+
+static void
+surface_destructor( FusionObject *object, bool zombie, void *ctx )
+{
+ int i;
+ CoreSurface *surface = (CoreSurface*) object;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ D_DEBUG_AT( Core_Surface, "destroying %p (%dx%d%s)\n", surface,
+ surface->config.size.w, surface->config.size.h, zombie ? " ZOMBIE" : "");
+
+ dfb_surface_lock( surface );
+
+ surface->state |= CSSF_DESTROYED;
+
+ /* announce surface destruction */
+ dfb_surface_notify( surface, CSNF_DESTROY );
+
+ /* unlink palette */
+ if (surface->palette) {
+ dfb_palette_detach_global( surface->palette, &surface->palette_reaction );
+ dfb_palette_unlink( &surface->palette );
+ }
+
+ /* destroy buffers */
+ for (i=0; i<MAX_SURFACE_BUFFERS; i++) {
+ if (surface->buffers[i])
+ dfb_surface_buffer_destroy( surface->buffers[i] );
+ }
+
+ direct_serial_deinit( &surface->serial );
+
+ dfb_surface_unlock( surface );
+
+ fusion_skirmish_destroy( &surface->lock );
+
+ D_MAGIC_CLEAR( surface );
+
+ fusion_object_destroy( object );
+}
+
+FusionObjectPool *
+dfb_surface_pool_create( const FusionWorld *world )
+{
+ FusionObjectPool *pool;
+
+ pool = fusion_object_pool_create( "Surface Pool",
+ sizeof(CoreSurface),
+ sizeof(CoreSurfaceNotification),
+ surface_destructor, NULL, world );
+
+ return pool;
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_surface_create( CoreDFB *core,
+ const CoreSurfaceConfig *config,
+ CoreSurfaceTypeFlags type,
+ unsigned long resource_id,
+ CorePalette *palette,
+ CoreSurface **ret_surface )
+{
+ DFBResult ret = DFB_BUG;
+ int i;
+ int buffers;
+ CoreSurface *surface;
+ char buf[64];
+
+ D_ASSERT( core != NULL );
+ D_FLAGS_ASSERT( type, CSTF_ALL );
+ D_MAGIC_ASSERT_IF( palette, CorePalette );
+ D_ASSERT( ret_surface != NULL );
+
+ D_DEBUG_AT( Core_Surface, "dfb_surface_create( %p, %p, %p )\n", core, config, ret_surface );
+
+ surface = dfb_core_create_surface( core );
+ if (!surface)
+ return DFB_FUSION;
+
+ if (config) {
+ D_FLAGS_ASSERT( config->flags, CSCONF_ALL );
+
+ surface->config.flags = config->flags;
+
+ if (config->flags & CSCONF_SIZE) {
+ D_DEBUG_AT( Core_Surface, " -> %dx%d\n", config->size.w, config->size.h );
+
+ surface->config.size = config->size;
+ }
+
+ if (config->flags & CSCONF_FORMAT) {
+ D_DEBUG_AT( Core_Surface, " -> %s\n", dfb_pixelformat_name( config->format ) );
+
+ surface->config.format = config->format;
+ }
+
+ if (config->flags & CSCONF_CAPS) {
+ D_DEBUG_AT( Core_Surface, " -> caps 0x%08x\n", config->caps );
+
+ if (config->caps & DSCAPS_ROTATED)
+ D_UNIMPLEMENTED();
+
+ surface->config.caps = config->caps & ~DSCAPS_ROTATED;
+ }
+
+ if (config->flags & CSCONF_PREALLOCATED) {
+ D_DEBUG_AT( Core_Surface, " -> prealloc %p [%d]\n",
+ config->preallocated[0].addr,
+ config->preallocated[0].pitch );
+
+ direct_memcpy( surface->config.preallocated, config->preallocated, sizeof(config->preallocated) );
+
+ type |= CSTF_PREALLOCATED;
+ }
+ }
+
+ if (surface->config.caps & DSCAPS_SYSTEMONLY)
+ surface->type = (type & ~CSTF_EXTERNAL) | CSTF_INTERNAL;
+ else if (surface->config.caps & DSCAPS_VIDEOONLY)
+ surface->type = (type & ~CSTF_INTERNAL) | CSTF_EXTERNAL;
+ else
+ surface->type = type & ~(CSTF_INTERNAL | CSTF_EXTERNAL);
+
+ if (surface->config.caps & DSCAPS_SHARED)
+ surface->type |= CSTF_SHARED;
+
+ surface->resource_id = resource_id;
+
+ if (surface->config.caps & DSCAPS_TRIPLE)
+ buffers = 3;
+ else if (surface->config.caps & DSCAPS_DOUBLE)
+ buffers = 2;
+ else {
+ buffers = 1;
+
+ surface->config.caps &= ~DSCAPS_ROTATED;
+ }
+
+ surface->notifications = CSNF_ALL & ~CSNF_FLIP;
+
+ surface->alpha_ramp[0] = 0x00;
+ surface->alpha_ramp[1] = 0x55;
+ surface->alpha_ramp[2] = 0xaa;
+ surface->alpha_ramp[3] = 0xff;
+
+
+ if (surface->config.caps & DSCAPS_STATIC_ALLOC)
+ surface->config.min_size = surface->config.size;
+
+ surface->shmpool = dfb_core_shmpool( core );
+
+ direct_serial_init( &surface->serial );
+
+ snprintf( buf, sizeof(buf), "Surface %dx%d %s", surface->config.size.w,
+ surface->config.size.h, dfb_pixelformat_name(surface->config.format) );
+
+ fusion_ref_set_name( &surface->object.ref, buf );
+
+ fusion_skirmish_init( &surface->lock, buf, dfb_core_world(core) );
+
+ fusion_object_set_lock( &surface->object, &surface->lock );
+
+ D_MAGIC_SET( surface, CoreSurface );
+
+
+ if (dfb_config->warn.flags & DCWF_CREATE_SURFACE &&
+ dfb_config->warn.create_surface.min_size.w <= surface->config.size.w &&
+ dfb_config->warn.create_surface.min_size.h <= surface->config.size.h)
+ D_WARN( "create-surface %4dx%4d %6s, buffers %d, caps 0x%08x, type 0x%08x",
+ surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format),
+ buffers, surface->config.caps, surface->type );
+
+
+ if (palette) {
+ dfb_surface_set_palette( surface, palette );
+ }
+ else if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) {
+ ret = dfb_surface_init_palette( core, surface );
+ if (ret)
+ goto error;
+ }
+
+ /* Create the Surface Buffers. */
+ for (i=0; i<buffers; i++) {
+ CoreSurfaceBuffer *buffer;
+
+ ret = dfb_surface_buffer_new( surface, CSBF_NONE, &buffer );
+ if (ret) {
+ D_DERROR( ret, "Core/Surface: Error creating surface buffer!\n" );
+ goto error;
+ }
+
+ surface->buffers[surface->num_buffers++] = buffer;
+
+ switch (i) {
+ case 0:
+ surface->buffer_indices[CSBR_FRONT] = i;
+ case 1:
+ surface->buffer_indices[CSBR_BACK] = i;
+ case 2:
+ surface->buffer_indices[CSBR_IDLE] = i;
+ }
+ }
+
+ fusion_object_activate( &surface->object );
+
+ *ret_surface = surface;
+
+ return DFB_OK;
+
+error:
+ D_MAGIC_CLEAR( surface );
+
+ for (i=0; i<MAX_SURFACE_BUFFERS; i++) {
+ if (surface->buffers[i])
+ dfb_surface_buffer_destroy( surface->buffers[i] );
+ }
+
+ fusion_skirmish_destroy( &surface->lock );
+
+ direct_serial_deinit( &surface->serial );
+
+ fusion_object_destroy( &surface->object );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_create_simple ( CoreDFB *core,
+ int width,
+ int height,
+ DFBSurfacePixelFormat format,
+ DFBSurfaceCapabilities caps,
+ CoreSurfaceTypeFlags type,
+ unsigned long resource_id,
+ CorePalette *palette,
+ CoreSurface **ret_surface )
+{
+ CoreSurfaceConfig config;
+
+ D_DEBUG_AT( Core_Surface, "%s( %p, %dx%d %s, %p )\n", __FUNCTION__, core, width, height,
+ dfb_pixelformat_name( format ), ret_surface );
+
+ D_ASSERT( core != NULL );
+ D_ASSERT( ret_surface != NULL );
+
+ config.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS;
+ config.size.w = width;
+ config.size.h = height;
+ config.format = format;
+ config.caps = caps;
+
+ return dfb_surface_create( core, &config, type, resource_id, palette, ret_surface );
+}
+
+DFBResult
+dfb_surface_init_palette( CoreDFB *core,
+ CoreSurface *surface )
+{
+ DFBResult ret;
+ CorePalette *palette;
+
+ ret = dfb_palette_create( core,
+ 1 << DFB_COLOR_BITS_PER_PIXEL( surface->config.format ),
+ &palette );
+ if (ret) {
+ D_DERROR( ret, "Core/Surface: Error creating palette!\n" );
+ return ret;
+ }
+
+ switch (surface->config.format) {
+ case DSPF_LUT8:
+ dfb_palette_generate_rgb332_map( palette );
+ break;
+
+ case DSPF_ALUT44:
+ dfb_palette_generate_rgb121_map( palette );
+ break;
+
+ default:
+ break;
+ }
+
+ dfb_surface_set_palette( surface, palette );
+
+ dfb_palette_unref( palette );
+
+ return DFB_OK;
+}
+
+
+DFBResult
+dfb_surface_notify( CoreSurface *surface,
+ CoreSurfaceNotificationFlags flags)
+{
+ CoreSurfaceNotification notification;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+ D_FLAGS_ASSERT( flags, CSNF_ALL );
+
+ direct_serial_increase( &surface->serial );
+
+ if (!(surface->state & CSSF_DESTROYED)) {
+ if (!(surface->notifications & flags))
+ return DFB_OK;
+ }
+
+ notification.flags = flags;
+ notification.surface = surface;
+
+ return dfb_surface_dispatch( surface, &notification, dfb_surface_globals );
+}
+
+DFBResult
+dfb_surface_flip( CoreSurface *surface, bool swap )
+{
+ unsigned int back, front;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ back = (surface->flips + CSBR_BACK) % surface->num_buffers;
+ front = (surface->flips + CSBR_FRONT) % surface->num_buffers;
+
+ D_ASSERT( surface->buffer_indices[back] < surface->num_buffers );
+ D_ASSERT( surface->buffer_indices[front] < surface->num_buffers );
+
+ if (surface->buffers[surface->buffer_indices[back]]->policy !=
+ surface->buffers[surface->buffer_indices[front]]->policy || (surface->config.caps & DSCAPS_ROTATED))
+ return DFB_UNSUPPORTED;
+
+ if (swap) {
+ int tmp = surface->buffer_indices[back];
+ surface->buffer_indices[back] = surface->buffer_indices[front];
+ surface->buffer_indices[front] = tmp;
+ }
+ else
+ surface->flips++;
+
+ dfb_surface_notify( surface, CSNF_FLIP );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_reconfig( CoreSurface *surface,
+ const CoreSurfaceConfig *config )
+{
+ int i, buffers;
+ DFBResult ret;
+
+ D_DEBUG_AT( Core_Surface, "%s( %p, %dx%d %s -> %dx%d %s )\n", __FUNCTION__, surface,
+ surface->config.size.w, surface->config.size.h, dfb_pixelformat_name( surface->config.format ),
+ (config->flags & CSCONF_SIZE) ? config->size.w : surface->config.size.w,
+ (config->flags & CSCONF_SIZE) ? config->size.h : surface->config.size.h,
+ (config->flags & CSCONF_FORMAT) ? dfb_pixelformat_name( config->format ) :
+ dfb_pixelformat_name( surface->config.format ) );
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ D_ASSERT( config != NULL );
+
+ if (surface->type & CSTF_PREALLOCATED)
+ return DFB_UNSUPPORTED;
+
+ if (config->flags & CSCONF_PREALLOCATED)
+ return DFB_UNSUPPORTED;
+
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return DFB_FUSION;
+
+ if ( (config->flags == CSCONF_SIZE ||
+ ((config->flags == (CSCONF_SIZE | CSCONF_FORMAT)) && (config->format == surface->config.format))) &&
+ config->size.w <= surface->config.min_size.w &&
+ config->size.h <= surface->config.min_size.h)
+ {
+ surface->config.size = config->size;
+
+ fusion_skirmish_dismiss( &surface->lock );
+ return DFB_OK;
+ }
+
+#if 1
+ /* Precheck the Surface Buffers. */
+ for (i=0; i<surface->num_buffers; i++) {
+ if (surface->buffers[i]->locked) {
+ D_DEBUG_AT( Core_Surface, " -> surface is locked, cannot reconfigure!\n" );
+
+ fusion_skirmish_dismiss( &surface->lock );
+ return DFB_LOCKED;
+ }
+ }
+#endif
+
+ /* Destroy the Surface Buffers. */
+ for (i=0; i<surface->num_buffers; i++) {
+ dfb_surface_buffer_destroy( surface->buffers[i] );
+ surface->buffers[i] = NULL;
+ }
+
+ surface->num_buffers = 0;
+
+ if (config->flags & CSCONF_SIZE)
+ surface->config.size = config->size;
+
+ if (config->flags & CSCONF_FORMAT)
+ surface->config.format = config->format;
+
+ if (config->flags & CSCONF_CAPS) {
+ if (config->caps & DSCAPS_ROTATED)
+ D_UNIMPLEMENTED();
+
+ surface->config.caps = config->caps & ~DSCAPS_ROTATED;
+ }
+
+ if (surface->config.caps & DSCAPS_SYSTEMONLY)
+ surface->type = (surface->type & ~CSTF_EXTERNAL) | CSTF_INTERNAL;
+ else if (surface->config.caps & DSCAPS_VIDEOONLY)
+ surface->type = (surface->type & ~CSTF_INTERNAL) | CSTF_EXTERNAL;
+ else
+ surface->type = surface->type & ~(CSTF_INTERNAL | CSTF_EXTERNAL);
+
+ if (surface->config.caps & DSCAPS_TRIPLE)
+ buffers = 3;
+ else if (surface->config.caps & DSCAPS_DOUBLE)
+ buffers = 2;
+ else {
+ buffers = 1;
+
+ surface->config.caps &= ~DSCAPS_ROTATED;
+ }
+
+ /* Recreate the Surface Buffers. */
+ for (i=0; i<buffers; i++) {
+ CoreSurfaceBuffer *buffer;
+
+ ret = dfb_surface_buffer_new( surface, CSBF_NONE, &buffer );
+ if (ret) {
+ D_DERROR( ret, "Core/Surface: Error creating surface buffer!\n" );
+ goto error;
+ }
+
+ surface->buffers[surface->num_buffers++] = buffer;
+
+ switch (i) {
+ case 0:
+ surface->buffer_indices[CSBR_FRONT] = i;
+ case 1:
+ surface->buffer_indices[CSBR_BACK] = i;
+ case 2:
+ surface->buffer_indices[CSBR_IDLE] = i;
+ }
+ }
+
+ dfb_surface_notify( surface, CSNF_SIZEFORMAT );
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return DFB_OK;
+
+error:
+ D_UNIMPLEMENTED();
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_destroy_buffers( CoreSurface *surface )
+{
+ int i;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ if (surface->type & CSTF_PREALLOCATED)
+ return DFB_UNSUPPORTED;
+
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return DFB_FUSION;
+
+ /* Destroy the Surface Buffers. */
+ for (i=0; i<surface->num_buffers; i++) {
+ dfb_surface_buffer_destroy( surface->buffers[i] );
+ surface->buffers[i] = NULL;
+ }
+
+ surface->num_buffers = 0;
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_lock_buffer( CoreSurface *surface,
+ CoreSurfaceBufferRole role,
+ CoreSurfaceAccessorID accessor,
+ CoreSurfaceAccessFlags access,
+ CoreSurfaceBufferLock *ret_lock )
+{
+ DFBResult ret;
+ CoreSurfaceBuffer *buffer;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return DFB_FUSION;
+
+ buffer = dfb_surface_get_buffer( surface, role );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ ret = dfb_surface_buffer_lock( buffer, accessor, access, ret_lock );
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_unlock_buffer( CoreSurface *surface,
+ CoreSurfaceBufferLock *lock )
+{
+ DFBResult ret;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return DFB_FUSION;
+
+ ret = dfb_surface_buffer_unlock( lock );
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_read_buffer( CoreSurface *surface,
+ CoreSurfaceBufferRole role,
+ void *destination,
+ int pitch,
+ const DFBRectangle *rect )
+{
+ DFBResult ret;
+ CoreSurfaceBuffer *buffer;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ D_ASSERT( destination != NULL );
+ D_ASSERT( pitch > 0 );
+ DFB_RECTANGLE_ASSERT_IF( rect );
+
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return DFB_FUSION;
+
+ buffer = dfb_surface_get_buffer( surface, role );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ ret = dfb_surface_buffer_read( buffer, destination, pitch, rect );
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_write_buffer( CoreSurface *surface,
+ CoreSurfaceBufferRole role,
+ const void *source,
+ int pitch,
+ const DFBRectangle *rect )
+{
+ DFBResult ret;
+ CoreSurfaceBuffer *buffer;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ D_ASSERT( source != NULL );
+ D_ASSERT( pitch > 0 );
+ DFB_RECTANGLE_ASSERT_IF( rect );
+
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return DFB_FUSION;
+
+ buffer = dfb_surface_get_buffer( surface, role );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ ret = dfb_surface_buffer_write( buffer, source, pitch, rect );
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_dump_buffer( CoreSurface *surface,
+ CoreSurfaceBufferRole role,
+ const char *path,
+ const char *prefix )
+{
+ DFBResult ret;
+ CoreSurfaceBuffer *buffer;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ D_ASSERT( path != NULL );
+ D_ASSERT( prefix != NULL );
+
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return DFB_FUSION;
+
+ buffer = dfb_surface_get_buffer( surface, role );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ ret = dfb_surface_buffer_dump( buffer, path, prefix );
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_set_palette( CoreSurface *surface,
+ CorePalette *palette )
+{
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ D_MAGIC_ASSERT_IF( palette, CorePalette );
+
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return DFB_FUSION;
+
+ if (surface->palette != palette) {
+ if (surface->palette) {
+ dfb_palette_detach_global( surface->palette, &surface->palette_reaction );
+ dfb_palette_unlink( &surface->palette );
+ }
+
+ if (palette) {
+ dfb_palette_link( &surface->palette, palette );
+ dfb_palette_attach_global( palette, DFB_SURFACE_PALETTE_LISTENER,
+ surface, &surface->palette_reaction );
+ }
+
+ dfb_surface_notify( surface, CSNF_PALETTE_CHANGE );
+ }
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_set_field( CoreSurface *surface,
+ int field )
+{
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return DFB_FUSION;
+
+ surface->field = field;
+
+ dfb_surface_notify( surface, CSNF_FIELD );
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_set_alpha_ramp( CoreSurface *surface,
+ u8 a0,
+ u8 a1,
+ u8 a2,
+ u8 a3 )
+{
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return DFB_FUSION;
+
+ surface->alpha_ramp[0] = a0;
+ surface->alpha_ramp[1] = a1;
+ surface->alpha_ramp[2] = a2;
+ surface->alpha_ramp[3] = a3;
+
+ dfb_surface_notify( surface, CSNF_ALPHA_RAMP );
+
+ fusion_skirmish_dismiss( &surface->lock );
+
+ return DFB_OK;
+}
+
+ReactionResult
+_dfb_surface_palette_listener( const void *msg_data,
+ void *ctx )
+{
+ const CorePaletteNotification *notification = msg_data;
+ CoreSurface *surface = ctx;
+
+ if (notification->flags & CPNF_DESTROY)
+ return RS_REMOVE;
+
+ if (notification->flags & CPNF_ENTRIES) {
+ if (fusion_skirmish_prevail( &surface->lock ))
+ return RS_OK;
+
+ dfb_surface_notify( surface, CSNF_PALETTE_UPDATE );
+
+ fusion_skirmish_dismiss( &surface->lock );
+ }
+
+ return RS_OK;
+}
+
diff --git a/Source/DirectFB/src/core/surface.h b/Source/DirectFB/src/core/surface.h
new file mode 100755
index 0000000..1d2d452
--- /dev/null
+++ b/Source/DirectFB/src/core/surface.h
@@ -0,0 +1,446 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__SURFACE_H__
+#define __CORE__SURFACE_H__
+
+#include <directfb.h>
+
+#include <direct/list.h>
+#include <direct/serial.h>
+#include <direct/util.h>
+
+#include <fusion/object.h>
+#include <fusion/reactor.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+
+typedef enum {
+ CSNF_NONE = 0x00000000,
+
+ CSNF_SIZEFORMAT = 0x00000001, /* width, height, format */
+ CSNF_SYSTEM = 0x00000002, /* system instance information */
+ CSNF_VIDEO = 0x00000004, /* video instance information */
+ CSNF_DESTROY = 0x00000008, /* surface is about to be destroyed */
+ CSNF_FLIP = 0x00000010, /* surface buffer pointer swapped */
+ CSNF_FIELD = 0x00000020, /* active (displayed) field switched */
+ CSNF_PALETTE_CHANGE = 0x00000040, /* another palette has been set */
+ CSNF_PALETTE_UPDATE = 0x00000080, /* current palette has been altered */
+ CSNF_ALPHA_RAMP = 0x00000100, /* alpha ramp was modified */
+
+ CSNF_ALL = 0x000001FF
+} CoreSurfaceNotificationFlags;
+
+typedef struct {
+ CoreSurfaceNotificationFlags flags;
+ CoreSurface *surface;
+} CoreSurfaceNotification;
+
+
+typedef enum {
+ CSCONF_NONE = 0x00000000,
+
+ CSCONF_SIZE = 0x00000001,
+ CSCONF_FORMAT = 0x00000002,
+ CSCONF_CAPS = 0x00000004,
+
+ CSCONF_PREALLOCATED = 0x00000010,
+
+ CSCONF_ALL = 0x00000017
+} CoreSurfaceConfigFlags;
+
+typedef enum {
+ CSTF_NONE = 0x00000000,
+
+ CSTF_LAYER = 0x00000001, /* surface for layer */
+ CSTF_WINDOW = 0x00000002, /* surface for window */
+ CSTF_CURSOR = 0x00000004, /* surface for cursor */
+ CSTF_FONT = 0x00000008, /* surface for font */
+
+ CSTF_SHARED = 0x00000010, /* accessable by other processes */
+
+ CSTF_INTERNAL = 0x00000100, /* system memory */
+ CSTF_EXTERNAL = 0x00000200, /* video memory */
+
+ CSTF_PREALLOCATED = 0x00000400, /* preallocated memory */
+
+ CSTF_ALL = 0x0000071F
+} CoreSurfaceTypeFlags;
+
+typedef struct {
+ CoreSurfaceConfigFlags flags;
+
+ DFBDimension size;
+ DFBSurfacePixelFormat format;
+ DFBSurfaceCapabilities caps;
+
+ struct {
+ void *addr;
+ int pitch;
+ } preallocated[MAX_SURFACE_BUFFERS];
+
+ DFBDimension min_size;
+} CoreSurfaceConfig;
+
+typedef enum {
+ CSP_SYSTEMONLY = 0x00000000, /* never try to swap
+ into video memory */
+ CSP_VIDEOLOW = 0x00000001, /* try to store in video memory,
+ low priority */
+ CSP_VIDEOHIGH = 0x00000002, /* try to store in video memory,
+ high priority */
+ CSP_VIDEOONLY = 0x00000003 /* always and only
+ store in video memory */
+} CoreSurfacePolicy;
+
+typedef enum {
+ CSAF_NONE = 0x00000000,
+
+ CSAF_READ = 0x00000001, /* accessor may read */
+ CSAF_WRITE = 0x00000002, /* accessor may write */
+
+ CSAF_SHARED = 0x00000010, /* other processes can read/write at the same time (shared mapping) */
+
+ CSAF_ALL = 0x00000013
+} CoreSurfaceAccessFlags;
+
+typedef enum {
+ CSAID_NONE = 0x00000000, /* none or unknown accessor */
+
+ CSAID_CPU = 0x00000001, /* local processor, where DirectFB is running on, could be app or sw fallback */
+
+ CSAID_GPU = 0x00000002, /* primary accelerator, as in traditional 'gfxcard' core (ACCEL0) */
+
+ CSAID_ACCEL0 = 0x00000002, /* accelerators, decoders etc. (CSAID_ACCEL0 + accel_id<0-5>) */
+ CSAID_ACCEL1 = 0x00000003,
+ CSAID_ACCEL2 = 0x00000004,
+ CSAID_ACCEL3 = 0x00000005,
+ CSAID_ACCEL4 = 0x00000006,
+ CSAID_ACCEL5 = 0x00000007,
+
+ CSAID_LAYER0 = 0x00000008, /* display layers, registered by layer core (CSAID_LAYER0 + layer_id<0-7>) */
+ CSAID_LAYER1 = 0x00000009,
+ CSAID_LAYER2 = 0x0000000a,
+ CSAID_LAYER3 = 0x0000000b,
+ CSAID_LAYER4 = 0x0000000c,
+ CSAID_LAYER5 = 0x0000000d,
+ CSAID_LAYER6 = 0x0000000e,
+ CSAID_LAYER7 = 0x0000000f,
+
+ _CSAID_NUM = 0x00000010, /* number of statically assigned IDs for usage in static arrays */
+
+ CSAID_ANY = 0x00000100, /* any other accessor needs to be registered using IDs starting from here */
+} CoreSurfaceAccessorID;
+
+typedef enum {
+ CSBR_FRONT = 0,
+ CSBR_BACK = 1,
+ CSBR_IDLE = 2
+} CoreSurfaceBufferRole;
+
+typedef enum {
+ CSSF_NONE = 0x00000000,
+
+ CSSF_DESTROYED = 0x00000001, /* surface is being or has been destroyed */
+
+ CSSF_ALL = 0x00000001
+} CoreSurfaceStateFlags;
+
+struct __DFB_CoreSurface
+{
+ FusionObject object;
+ int magic;
+
+ FusionSkirmish lock;
+
+ CoreSurfaceStateFlags state;
+
+ CoreSurfaceConfig config;
+ CoreSurfaceTypeFlags type;
+ unsigned long resource_id; /* layer id, window id, or user specified */
+
+ int rotation;
+
+ CoreSurfaceNotificationFlags notifications;
+
+ DirectSerial serial;
+
+ int field;
+ u8 alpha_ramp[4];
+
+ CoreSurfaceBuffer *buffers[MAX_SURFACE_BUFFERS];
+ int num_buffers;
+
+ int buffer_indices[MAX_SURFACE_BUFFERS];
+
+ unsigned int flips;
+
+ CorePalette *palette;
+ GlobalReaction palette_reaction;
+
+ FusionSHMPoolShared *shmpool;
+};
+
+
+/*
+ * Creates a pool of surface objects.
+ */
+FusionObjectPool *dfb_surface_pool_create( const FusionWorld *world );
+
+/*
+ * Generates dfb_surface_ref(), dfb_surface_attach() etc.
+ */
+FUSION_OBJECT_METHODS( CoreSurface, dfb_surface )
+
+
+DFBResult dfb_surface_create ( CoreDFB *core,
+ const CoreSurfaceConfig *config,
+ CoreSurfaceTypeFlags type,
+ unsigned long resource_id,
+ CorePalette *palette,
+ CoreSurface **ret_surface );
+
+DFBResult dfb_surface_create_simple ( CoreDFB *core,
+ int width,
+ int height,
+ DFBSurfacePixelFormat format,
+ DFBSurfaceCapabilities caps,
+ CoreSurfaceTypeFlags type,
+ unsigned long resource_id,
+ CorePalette *palette,
+ CoreSurface **ret_surface );
+
+DFBResult dfb_surface_init_palette ( CoreDFB *core,
+ CoreSurface *surface );
+
+DFBResult dfb_surface_notify ( CoreSurface *surface,
+ CoreSurfaceNotificationFlags flags);
+
+DFBResult dfb_surface_flip ( CoreSurface *surface,
+ bool swap );
+
+DFBResult dfb_surface_reconfig ( CoreSurface *surface,
+ const CoreSurfaceConfig *config );
+
+DFBResult dfb_surface_destroy_buffers( CoreSurface *surface );
+
+DFBResult dfb_surface_lock_buffer ( CoreSurface *surface,
+ CoreSurfaceBufferRole role,
+ CoreSurfaceAccessorID accessor,
+ CoreSurfaceAccessFlags access,
+ CoreSurfaceBufferLock *ret_lock );
+
+DFBResult dfb_surface_unlock_buffer ( CoreSurface *surface,
+ CoreSurfaceBufferLock *lock );
+
+DFBResult dfb_surface_read_buffer ( CoreSurface *surface,
+ CoreSurfaceBufferRole role,
+ void *destination,
+ int pitch,
+ const DFBRectangle *rect );
+
+DFBResult dfb_surface_write_buffer ( CoreSurface *surface,
+ CoreSurfaceBufferRole role,
+ const void *source,
+ int pitch,
+ const DFBRectangle *rect );
+
+DFBResult dfb_surface_dump_buffer ( CoreSurface *surface,
+ CoreSurfaceBufferRole role,
+ const char *path,
+ const char *prefix );
+
+DFBResult dfb_surface_set_palette ( CoreSurface *surface,
+ CorePalette *palette );
+
+DFBResult dfb_surface_set_field ( CoreSurface *surface,
+ int field );
+
+DFBResult dfb_surface_set_alpha_ramp( CoreSurface *surface,
+ u8 a0,
+ u8 a1,
+ u8 a2,
+ u8 a3 );
+
+
+static inline DirectResult
+dfb_surface_lock( CoreSurface *surface )
+{
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ return fusion_skirmish_prevail( &surface->lock );
+}
+
+static inline DirectResult
+dfb_surface_trylock( CoreSurface *surface )
+{
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ return fusion_skirmish_swoop( &surface->lock );
+}
+
+static inline DirectResult
+dfb_surface_unlock( CoreSurface *surface )
+{
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ return fusion_skirmish_dismiss( &surface->lock );
+}
+
+static inline CoreSurfaceBuffer *
+dfb_surface_get_buffer( CoreSurface *surface,
+ CoreSurfaceBufferRole role )
+{
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ D_ASSERT( role == CSBR_FRONT || role == CSBR_BACK || role == CSBR_IDLE );
+
+ D_ASSERT( surface->num_buffers > 0 );
+
+ return surface->buffers[ surface->buffer_indices[(surface->flips + role) % surface->num_buffers] ];
+}
+
+static inline void *
+dfb_surface_data_offset( const CoreSurface *surface,
+ void *data,
+ int pitch,
+ int x,
+ int y )
+{
+ D_ASSERT( surface != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( pitch > 0 );
+ D_ASSERT( x >= 0 );
+ D_ASSERT( x < surface->config.size.w );
+ D_ASSERT( y >= 0 );
+ D_ASSERT( y < surface->config.size.h );
+
+ if (surface->config.caps & DSCAPS_SEPARATED) {
+ if (y & 1)
+ y += surface->config.size.h;
+
+ y >>= 1;
+ }
+
+ return (u8*)data + pitch * y + DFB_BYTES_PER_LINE( surface->config.format, x );
+}
+
+static inline void
+dfb_surface_calc_buffer_size( CoreSurface *surface,
+ int byte_align,
+ int pixel_align,
+ int *ret_pitch,
+ int *ret_size )
+{
+ DFBSurfacePixelFormat format;
+ int width;
+ int pitch;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ format = surface->config.format;
+
+ width = direct_util_align( surface->config.size.w, pixel_align );
+ pitch = direct_util_align( DFB_BYTES_PER_LINE( format, width ), byte_align );
+
+ if (ret_pitch)
+ *ret_pitch = pitch;
+
+ if (ret_size)
+ *ret_size = pitch * DFB_PLANE_MULTIPLY( format, surface->config.size.h );
+}
+
+static inline void
+dfb_surface_caps_apply_policy( CoreSurfacePolicy policy,
+ DFBSurfaceCapabilities *caps )
+{
+ switch (policy) {
+ case CSP_SYSTEMONLY:
+ *caps = (DFBSurfaceCapabilities)((*caps & ~DSCAPS_VIDEOONLY) | DSCAPS_SYSTEMONLY);
+ break;
+
+ case CSP_VIDEOONLY:
+ *caps = (DFBSurfaceCapabilities)((*caps & ~DSCAPS_SYSTEMONLY) | DSCAPS_VIDEOONLY);
+ break;
+
+ default:
+ *caps = (DFBSurfaceCapabilities)(*caps & ~(DSCAPS_SYSTEMONLY | DSCAPS_VIDEOONLY));
+ break;
+ }
+}
+
+static inline DFBResult
+dfb_surface_resize( CoreSurface *surface,
+ int width,
+ int height )
+{
+ CoreSurfaceConfig config;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ D_ASSERT( width > 0 );
+ D_ASSERT( height > 0 );
+
+ config.flags = CSCONF_SIZE;
+ config.size.w = width;
+ config.size.h = height;
+
+ return dfb_surface_reconfig( surface, &config );
+}
+
+static inline DFBResult
+dfb_surface_reformat( CoreSurface *surface,
+ int width,
+ int height,
+ DFBSurfacePixelFormat format )
+{
+ CoreSurfaceConfig config;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ D_ASSERT( width > 0 );
+ D_ASSERT( height > 0 );
+
+ config.flags = (CoreSurfaceConfigFlags)(CSCONF_SIZE | CSCONF_FORMAT);
+ config.size.w = width;
+ config.size.h = height;
+ config.format = format;
+
+ return dfb_surface_reconfig( surface, &config );
+}
+
+/* global reactions */
+ReactionResult _dfb_surface_palette_listener( const void *msg_data,
+ void *ctx );
+
+typedef enum {
+ DFB_LAYER_REGION_SURFACE_LISTENER,
+ DFB_WINDOWSTACK_BACKGROUND_IMAGE_LISTENER
+} DFB_SURFACE_GLOBALS;
+
+#endif
+
diff --git a/Source/DirectFB/src/core/surface_buffer.c b/Source/DirectFB/src/core/surface_buffer.c
new file mode 100755
index 0000000..da477df
--- /dev/null
+++ b/Source/DirectFB/src/core/surface_buffer.c
@@ -0,0 +1,1206 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef USE_ZLIB
+#include <zlib.h>
+#endif
+
+#include <directfb_util.h>
+
+#include <direct/debug.h>
+#include <direct/memcpy.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/gfxcard.h>
+#include <core/palette.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+#include <core/surface_pool.h>
+#include <core/surface_pool_bridge.h>
+
+#include <misc/conf.h>
+
+#include <gfx/convert.h>
+
+static const u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff };
+static const u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff };
+
+
+D_DEBUG_DOMAIN( Core_SurfBuffer, "Core/SurfBuffer", "DirectFB Core Surface Buffer" );
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_surface_buffer_new( CoreSurface *surface,
+ CoreSurfaceBufferFlags flags,
+ CoreSurfaceBuffer **ret_buffer )
+{
+ CoreSurfaceBuffer *buffer;
+
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ D_FLAGS_ASSERT( flags, CSBF_ALL );
+ D_ASSERT( ret_buffer != NULL );
+
+#if DIRECT_BUILD_DEBUG
+ D_DEBUG_AT( Core_SurfBuffer, "dfb_surface_buffer_new( %s )\n", dfb_pixelformat_name( surface->config.format ) );
+
+ if (flags & CSBF_STICKED)
+ D_DEBUG_AT( Core_SurfBuffer, " -> STICKED\n" );
+#endif
+
+ buffer = SHCALLOC( surface->shmpool, 1, sizeof(CoreSurfaceBuffer) );
+ if (!buffer)
+ return D_OOSHM();
+
+ direct_serial_init( &buffer->serial );
+ direct_serial_increase( &buffer->serial );
+
+ buffer->surface = surface;
+ buffer->flags = flags;
+ buffer->format = surface->config.format;
+
+ if (surface->config.caps & DSCAPS_VIDEOONLY)
+ buffer->policy = CSP_VIDEOONLY;
+ else if (surface->config.caps & DSCAPS_SYSTEMONLY)
+ buffer->policy = CSP_SYSTEMONLY;
+ else
+ buffer->policy = CSP_VIDEOLOW;
+
+ fusion_vector_init( &buffer->allocs, 2, surface->shmpool );
+
+ D_MAGIC_SET( buffer, CoreSurfaceBuffer );
+
+ *ret_buffer = buffer;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_buffer_destroy( CoreSurfaceBuffer *buffer )
+{
+ CoreSurface *surface;
+ CoreSurfaceAllocation *allocation;
+ int i;
+
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ D_DEBUG_AT( Core_SurfBuffer, "dfb_surface_buffer_destroy( %p [%dx%d] )\n",
+ buffer, surface->config.size.w, surface->config.size.h );
+
+ fusion_vector_foreach_reverse (allocation, i, buffer->allocs)
+ dfb_surface_pool_deallocate( allocation->pool, allocation );
+
+ fusion_vector_destroy( &buffer->allocs );
+
+ direct_serial_deinit( &buffer->serial );
+
+ D_MAGIC_CLEAR( buffer );
+
+ SHFREE( surface->shmpool, buffer );
+
+ return DFB_OK;
+}
+
+static CoreSurfaceAllocation *
+find_allocation( CoreSurfaceBuffer *buffer,
+ CoreSurfaceAccessorID accessor,
+ CoreSurfaceAccessFlags flags,
+ bool lock )
+{
+ int i;
+ CoreSurfaceAllocation *alloc;
+ CoreSurfaceAllocation *uptodate = NULL;
+ CoreSurfaceAllocation *outdated = NULL;
+
+ /* Prefer allocations which are up to date. */
+ fusion_vector_foreach (alloc, i, buffer->allocs) {
+ if (direct_serial_check( &alloc->serial, &buffer->serial )) {
+ /* Return immediately if up to date allocation has required flags. */
+ if (D_FLAGS_ARE_SET( alloc->access[accessor], flags ))
+ return alloc;
+
+ /* Remember up to date allocation in case none has supported flags. */
+ uptodate = alloc;
+ }
+ else if (D_FLAGS_ARE_SET( alloc->access[accessor], flags )) {
+ /* Remember outdated allocation which has supported flags though. */
+ outdated = alloc;
+ }
+ }
+
+ /* In case of a lock the flags are mandatory and the outdated allocation has to be used... */
+ if (lock)
+ return outdated;
+
+ /* ...otherwise we can still prefer the up to date allocation for Read/Write()! */
+ return uptodate ?: outdated;
+}
+
+DFBResult
+dfb_surface_buffer_lock( CoreSurfaceBuffer *buffer,
+ CoreSurfaceAccessorID accessor,
+ CoreSurfaceAccessFlags access,
+ CoreSurfaceBufferLock *lock )
+{
+ DFBResult ret;
+ CoreSurface *surface;
+ CoreSurfaceAllocation *allocation = NULL;
+ bool allocated = false;
+
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_FLAGS_ASSERT( access, CSAF_ALL );
+ D_ASSERT( lock != NULL );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ D_ASSERT( accessor >= CSAID_CPU );
+ D_ASSUME( accessor < _CSAID_NUM );
+ if (accessor >= CSAID_ANY) {
+ D_UNIMPLEMENTED();
+ return DFB_UNIMPLEMENTED;
+ }
+
+ if (accessor < 0 || accessor >= _CSAID_NUM)
+ return DFB_INVARG;
+
+#if DIRECT_BUILD_DEBUG
+ D_DEBUG_AT( Core_SurfBuffer, "dfb_surface_buffer_lock( %p, 0x%02x, %p ) <- %dx%d %s [%d]\n", buffer, access, lock,
+ surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(buffer->format),
+ dfb_surface_buffer_index(buffer) );
+
+ switch (accessor) {
+ case CSAID_CPU:
+ D_DEBUG_AT( Core_SurfBuffer, " -> CPU %s%s\n",
+ (access & CSAF_READ) ? "READ" : "", (access & CSAF_WRITE) ? "WRITE" : "" );
+ break;
+
+ case CSAID_GPU:
+ D_DEBUG_AT( Core_SurfBuffer, " -> GPU %s%s\n",
+ (access & CSAF_READ) ? "READ" : "", (access & CSAF_WRITE) ? "WRITE" : "" );
+ break;
+
+ case CSAID_LAYER0:
+ case CSAID_LAYER1:
+ case CSAID_LAYER2:
+ case CSAID_LAYER3:
+ case CSAID_LAYER4:
+ case CSAID_LAYER5:
+ case CSAID_LAYER6:
+ case CSAID_LAYER7:
+ D_DEBUG_AT( Core_SurfBuffer, " -> LAYER %d %s%s\n", accessor - CSAID_LAYER0,
+ (access & CSAF_READ) ? "READ" : "", (access & CSAF_WRITE) ? "WRITE" : "" );
+ break;
+
+ default:
+ D_DEBUG_AT( Core_SurfBuffer, " -> other\n" );
+ break;
+ }
+
+ if (access & CSAF_SHARED)
+ D_DEBUG_AT( Core_SurfBuffer, " -> SHARED\n" );
+#endif
+
+ /* Look for allocation with proper access. */
+ allocation = find_allocation( buffer, accessor, access, true );
+ if (!allocation) {
+ /* If no allocation exists, create one. */
+ ret = dfb_surface_pools_allocate( buffer, accessor, access, &allocation );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Buffer allocation failed!\n" );
+ return ret;
+ }
+
+ allocated = true;
+ }
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ /* Synchronize with other allocations. */
+ ret = dfb_surface_allocation_update( allocation, access );
+ if (ret) {
+ /* Destroy if newly created. */
+ if (allocated)
+ dfb_surface_pool_deallocate( allocation->pool, allocation );
+ return ret;
+ }
+
+ /* Lock the allocation. */
+ dfb_surface_buffer_lock_init( lock, accessor, access );
+
+ ret = dfb_surface_pool_lock( allocation->pool, allocation, lock );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n",
+ allocation->pool->desc.name );
+ dfb_surface_buffer_lock_deinit( lock );
+
+ /* Destroy if newly created. */
+ if (allocated)
+ dfb_surface_pool_deallocate( allocation->pool, allocation );
+
+ return ret;
+ }
+
+#if 1
+ /*
+ * Manage access interlocks.
+ *
+ * SOON FIXME: Clearing flags only when not locked yet. Otherwise nested GPU/CPU locks are a problem.
+ */
+ /* Software read/write access... */
+ if (accessor == CSAID_CPU) {
+ /* If hardware has written or is writing... */
+ if (allocation->accessed[CSAID_GPU] & CSAF_WRITE) {
+ /* ...wait for the operation to finish. */
+ dfb_gfxcard_sync(); /* TODO: wait for serial instead */
+
+ /* Software read access after hardware write requires flush of the (bus) read cache. */
+ dfb_gfxcard_flush_read_cache();
+
+ if (!buffer->locked) {
+ /* ...clear hardware write access. */
+ allocation->accessed[CSAID_GPU] &= ~CSAF_WRITE;
+
+ /* ...clear hardware read access (to avoid syncing twice). */
+ allocation->accessed[CSAID_GPU] &= ~CSAF_READ;
+ }
+ }
+
+ /* Software write access... */
+ if (access & CSAF_WRITE) {
+ /* ...if hardware has (to) read... */
+ if (allocation->accessed[CSAID_GPU] & CSAF_READ) {
+ /* ...wait for the operation to finish. */
+ dfb_gfxcard_sync(); /* TODO: wait for serial instead */
+
+ /* ...clear hardware read access. */
+ if (!buffer->locked)
+ allocation->accessed[CSAID_GPU] &= ~CSAF_READ;
+ }
+ }
+ }
+
+ /* Hardware read access... */
+ if (accessor == CSAID_GPU && access & CSAF_READ) {
+ /* ...if software has written before... */
+ if (allocation->accessed[CSAID_CPU] & CSAF_WRITE) {
+ /* ...flush texture cache. */
+ dfb_gfxcard_flush_texture_cache();
+
+ /* ...clear software write access. */
+ if (!buffer->locked)
+ allocation->accessed[CSAID_CPU] &= ~CSAF_WRITE;
+ }
+ }
+
+ if (! D_FLAGS_ARE_SET( allocation->accessed[accessor], access )) {
+ /* FIXME: surface_enter */
+ }
+#endif
+
+ /* Collect... */
+ allocation->accessed[accessor] |= access;
+
+#if 1
+ /* FIXME: don't use weak counter */
+ buffer->locked++;
+
+ D_DEBUG_AT( Core_SurfBuffer, " -> locked %dx now\n", buffer->locked );
+#endif
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_buffer_unlock( CoreSurfaceBufferLock *lock )
+{
+ DFBResult ret;
+ CoreSurfacePool *pool;
+ CoreSurfaceBuffer *buffer;
+ CoreSurfaceAllocation *allocation;
+
+ D_DEBUG_AT( Core_SurfBuffer, "dfb_surface_buffer_unlock( %p )\n", lock );
+
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ D_MAGIC_ASSERT( lock->buffer, CoreSurfaceBuffer );
+ D_MAGIC_ASSERT( lock->buffer->surface, CoreSurface );
+
+ FUSION_SKIRMISH_ASSERT( &lock->buffer->surface->lock );
+
+ allocation = lock->allocation;
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ buffer = lock->buffer;
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ pool = allocation->pool;
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ /*
+ * FIXME: This should fail with a nested GPU Lock during a CPU Lock and/or vice versa?
+ */
+// D_ASSUME( D_FLAGS_ARE_SET( allocation->accessed, lock->access ) );
+
+ ret = dfb_surface_pool_unlock( pool, lock->allocation, lock );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", pool->desc.name );
+ return ret;
+ }
+
+#if 1
+ buffer->locked--;
+#endif
+
+ dfb_surface_buffer_lock_reset( lock );
+
+ dfb_surface_buffer_lock_deinit( lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_buffer_read( CoreSurfaceBuffer *buffer,
+ void *destination,
+ int pitch,
+ const DFBRectangle *prect )
+{
+ DFBResult ret;
+ int y;
+ int bytes;
+ DFBRectangle rect;
+ CoreSurface *surface;
+ CoreSurfaceAllocation *allocation = NULL;
+ bool allocated = false;
+ DFBSurfacePixelFormat format;
+
+ D_DEBUG_AT( Core_SurfBuffer, "%s( %p, %p [%d] )\n", __FUNCTION__, buffer, destination, pitch );
+
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_ASSERT( destination != NULL );
+ D_ASSERT( pitch > 0 );
+ DFB_RECTANGLE_ASSERT_IF( prect );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ /* Determine area. */
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = surface->config.size.w;
+ rect.h = surface->config.size.h;
+
+ if (prect && (!dfb_rectangle_intersect( &rect, prect ) || !DFB_RECTANGLE_EQUAL( rect, *prect )))
+ return DFB_INVAREA;
+
+ /* Calculate bytes per read line. */
+ format = surface->config.format;
+ bytes = DFB_BYTES_PER_LINE( format, rect.w );
+
+ D_DEBUG_AT( Core_SurfBuffer, " -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect),
+ dfb_pixelformat_name( format ) );
+
+ /* If no allocations exists, simply clear the destination. */
+ if (fusion_vector_is_empty( &buffer->allocs )) {
+ for (y=0; y<rect.h; y++) {
+ memset( destination, 0, bytes );
+
+ destination += pitch;
+ }
+
+ return DFB_OK;
+ }
+
+ /* Use last written allocation if it's up to date... */
+ if (buffer->written && direct_serial_check( &buffer->written->serial, &buffer->serial ))
+ allocation = buffer->written;
+ else {
+ /* ...otherwise look for allocation with CPU access. */
+ allocation = find_allocation( buffer, CSAID_CPU, CSAF_READ, false );
+ if (!allocation) {
+ /* If no allocation exists, create one. */
+ ret = dfb_surface_pools_allocate( buffer, CSAID_CPU, CSAF_READ, &allocation );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Buffer allocation failed!\n" );
+ return ret;
+ }
+
+ allocated = true;
+ }
+ }
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ /* Synchronize with other allocations. */
+ ret = dfb_surface_allocation_update( allocation, CSAF_READ );
+ if (ret) {
+ /* Destroy if newly created. */
+ if (allocated)
+ dfb_surface_pool_deallocate( allocation->pool, allocation );
+ return ret;
+ }
+
+ /* Try reading from allocation directly... */
+ ret = dfb_surface_pool_read( allocation->pool, allocation, destination, pitch, &rect );
+ if (ret) {
+ /* ...otherwise use fallback method via locking if possible. */
+ if (allocation->access[CSAID_CPU] & CSAF_READ) {
+ CoreSurfaceBufferLock lock;
+
+ /* Lock the allocation. */
+ dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_READ );
+
+ ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n",
+ allocation->pool->desc.name );
+ dfb_surface_buffer_lock_deinit( &lock );
+ return ret;
+ }
+
+ /* Move to start of read. */
+ lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch;
+
+ /* Copy the data. */
+ for (y=0; y<rect.h; y++) {
+ direct_memcpy( destination, lock.addr, bytes );
+
+ destination += pitch;
+ lock.addr += lock.pitch;
+ }
+
+ /* Unlock the allocation. */
+ ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock );
+ if (ret)
+ D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name );
+
+ dfb_surface_buffer_lock_deinit( &lock );
+ }
+ }
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_buffer_write( CoreSurfaceBuffer *buffer,
+ const void *source,
+ int pitch,
+ const DFBRectangle *prect )
+{
+ DFBResult ret;
+ DFBRectangle rect;
+ CoreSurface *surface;
+ CoreSurfaceAllocation *allocation = NULL;
+ bool allocated = false;
+
+ D_DEBUG_AT( Core_SurfBuffer, "%s( %p, %p [%d] )\n", __FUNCTION__, buffer, source, pitch );
+
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_ASSERT( pitch > 0 || source == NULL );
+ DFB_RECTANGLE_ASSERT_IF( prect );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ /* Determine area. */
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = surface->config.size.w;
+ rect.h = surface->config.size.h;
+
+ if (prect && (!dfb_rectangle_intersect( &rect, prect ) || !DFB_RECTANGLE_EQUAL( rect, *prect )))
+ return DFB_INVAREA;
+
+ D_DEBUG_AT( Core_SurfBuffer, " -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect),
+ dfb_pixelformat_name( surface->config.format ) );
+
+ /* Use last read allocation if it's up to date... */
+ if (buffer->read && direct_serial_check( &buffer->read->serial, &buffer->serial ))
+ allocation = buffer->read;
+ else {
+ /* ...otherwise look for allocation with CPU access. */
+ allocation = find_allocation( buffer, CSAID_CPU, CSAF_WRITE, false );
+ if (!allocation) {
+ /* If no allocation exists, create one. */
+ ret = dfb_surface_pools_allocate( buffer, CSAID_CPU, CSAF_WRITE, &allocation );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Buffer allocation failed!\n" );
+ return ret;
+ }
+
+ allocated = true;
+ }
+ }
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ /* Synchronize with other allocations. */
+ ret = dfb_surface_allocation_update( allocation, CSAF_WRITE );
+ if (ret) {
+ /* Destroy if newly created. */
+ if (allocated)
+ dfb_surface_pool_deallocate( allocation->pool, allocation );
+ return ret;
+ }
+
+ /* Try writing to allocation directly... */
+ ret = source ? dfb_surface_pool_write( allocation->pool, allocation, source, pitch, &rect ) : DFB_UNSUPPORTED;
+ if (ret) {
+ /* ...otherwise use fallback method via locking if possible. */
+ if (allocation->access[CSAID_CPU] & CSAF_WRITE) {
+ int y;
+ int bytes;
+ DFBSurfacePixelFormat format;
+ CoreSurfaceBufferLock lock;
+
+ /* Calculate bytes per written line. */
+ format = surface->config.format;
+ bytes = DFB_BYTES_PER_LINE( format, rect.w );
+
+ /* Lock the allocation. */
+ dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_WRITE );
+
+ ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n",
+ allocation->pool->desc.name );
+ dfb_surface_buffer_lock_deinit( &lock );
+ return ret;
+ }
+
+ /* Move to start of write. */
+ lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch;
+
+ /* Copy the data. */
+ for (y=0; y<rect.h; y++) {
+ if (source) {
+ direct_memcpy( lock.addr, source, bytes );
+
+ source += pitch;
+ }
+ else
+ memset( lock.addr, 0, bytes );
+
+ lock.addr += lock.pitch;
+ }
+
+ /* Unlock the allocation. */
+ ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock );
+ if (ret)
+ D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name );
+
+ dfb_surface_buffer_lock_deinit( &lock );
+ }
+ }
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_buffer_dump( CoreSurfaceBuffer *buffer,
+ const char *directory,
+ const char *prefix )
+{
+ DFBResult ret;
+ int num = -1;
+ int fd_p = -1;
+ int fd_g = -1;
+ int i, n;
+ int len = (directory ? strlen(directory) : 0) + (prefix ? strlen(prefix) : 0) + 40;
+ char filename[len];
+ char head[30];
+ bool rgb = false;
+ bool alpha = false;
+#ifdef USE_ZLIB
+ gzFile gz_p = NULL, gz_g = NULL;
+ static const char *gz_ext = ".gz";
+#else
+ static const char *gz_ext = "";
+#endif
+ CoreSurface *surface;
+ CorePalette *palette = NULL;
+ CoreSurfaceBufferLock lock;
+
+ D_DEBUG_AT( Core_SurfBuffer, "%s( %p, %p, %p )\n", __FUNCTION__, buffer, directory, prefix );
+
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_ASSERT( directory != NULL );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ /* Check pixel format. */
+ switch (buffer->format) {
+ case DSPF_LUT8:
+ palette = surface->palette;
+
+ if (!palette) {
+ D_BUG( "no palette" );
+ return DFB_BUG;
+ }
+
+ if (dfb_palette_ref( palette ))
+ return DFB_FUSION;
+
+ rgb = true;
+
+ /* fall through */
+
+ case DSPF_A8:
+ alpha = true;
+ break;
+
+ case DSPF_ARGB:
+ case DSPF_ARGB1555:
+ case DSPF_ARGB2554:
+ case DSPF_ARGB4444:
+ case DSPF_AiRGB:
+ alpha = true;
+
+ /* fall through */
+
+ case DSPF_RGB332:
+ case DSPF_RGB16:
+ case DSPF_RGB24:
+ case DSPF_RGB32:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ case DSPF_NV16:
+ case DSPF_RGB444:
+ case DSPF_RGB555:
+ case DSPF_BGR555:
+ rgb = true;
+ break;
+
+
+ default:
+ D_ERROR( "DirectFB/core/surfaces: surface dump for format "
+ "'%s' is not implemented!\n",
+ dfb_pixelformat_name( buffer->format ) );
+ return DFB_UNSUPPORTED;
+ }
+
+ /* Lock the surface buffer, get the data pointer and pitch. */
+ ret = dfb_surface_buffer_lock( buffer, CSAID_CPU, CSAF_READ, &lock );
+ if (ret) {
+ if (palette)
+ dfb_palette_unref( palette );
+ return ret;
+ }
+
+ if (prefix) {
+ /* Find the lowest unused index. */
+ while (++num < 10000) {
+ snprintf( filename, len, "%s/%s_%04d.ppm%s",
+ directory, prefix, num, gz_ext );
+
+ if (access( filename, F_OK ) != 0) {
+ snprintf( filename, len, "%s/%s_%04d.pgm%s",
+ directory, prefix, num, gz_ext );
+
+ if (access( filename, F_OK ) != 0)
+ break;
+ }
+ }
+
+ if (num == 10000) {
+ D_ERROR( "DirectFB/core/surfaces: "
+ "couldn't find an unused index for surface dump!\n" );
+ dfb_surface_buffer_unlock( &lock );
+ if (palette)
+ dfb_palette_unref( palette );
+ return DFB_FAILURE;
+ }
+ }
+
+ /* Create a file with the found index. */
+ if (rgb) {
+ if (prefix)
+ snprintf( filename, len, "%s/%s_%04d.ppm%s", directory, prefix, num, gz_ext );
+ else
+ snprintf( filename, len, "%s.ppm%s", directory, gz_ext );
+
+ fd_p = open( filename, O_EXCL | O_CREAT | O_WRONLY, 0644 );
+ if (fd_p < 0) {
+ D_PERROR("DirectFB/core/surfaces: "
+ "could not open %s!\n", filename);
+ dfb_surface_buffer_unlock( &lock );
+ if (palette)
+ dfb_palette_unref( palette );
+ return DFB_IO;
+ }
+ }
+
+ /* Create a graymap for the alpha channel using the found index. */
+ if (alpha) {
+ if (prefix)
+ snprintf( filename, len, "%s/%s_%04d.pgm%s", directory, prefix, num, gz_ext );
+ else
+ snprintf( filename, len, "%s.pgm%s", directory, gz_ext );
+
+ fd_g = open( filename, O_EXCL | O_CREAT | O_WRONLY, 0644 );
+ if (fd_g < 0) {
+ D_PERROR("DirectFB/core/surfaces: "
+ "could not open %s!\n", filename);
+
+ dfb_surface_buffer_unlock( &lock );
+ if (palette)
+ dfb_palette_unref( palette );
+
+ if (rgb) {
+ close( fd_p );
+ snprintf( filename, len, "%s/%s_%04d.ppm%s",
+ directory, prefix, num, gz_ext );
+ unlink( filename );
+ }
+
+ return DFB_IO;
+ }
+ }
+
+#ifdef USE_ZLIB
+ if (rgb)
+ gz_p = gzdopen( fd_p, "wb" );
+
+ if (alpha)
+ gz_g = gzdopen( fd_g, "wb" );
+#endif
+
+ if (rgb) {
+ /* Write the pixmap header. */
+ snprintf( head, 30,
+ "P6\n%d %d\n255\n", surface->config.size.w, surface->config.size.h );
+#ifdef USE_ZLIB
+ gzwrite( gz_p, head, strlen(head) );
+#else
+ write( fd_p, head, strlen(head) );
+#endif
+ }
+
+ /* Write the graymap header. */
+ if (alpha) {
+ snprintf( head, 30,
+ "P5\n%d %d\n255\n", surface->config.size.w, surface->config.size.h );
+#ifdef USE_ZLIB
+ gzwrite( gz_g, head, strlen(head) );
+#else
+ write( fd_g, head, strlen(head) );
+#endif
+ }
+
+ /* Write the pixmap (and graymap) data. */
+ for (i=0; i<surface->config.size.h; i++) {
+ int n3;
+
+ /* Prepare one row. */
+ u8 *src8 = dfb_surface_data_offset( surface, lock.addr, lock.pitch, 0, i );
+
+ /* Write color buffer to pixmap file. */
+ if (rgb) {
+ u8 buf_p[surface->config.size.w * 3];
+
+ if (buffer->format == DSPF_LUT8) {
+ for (n=0, n3=0; n<surface->config.size.w; n++, n3+=3) {
+ buf_p[n3+0] = palette->entries[src8[n]].r;
+ buf_p[n3+1] = palette->entries[src8[n]].g;
+ buf_p[n3+2] = palette->entries[src8[n]].b;
+ }
+ }
+ else
+ dfb_convert_to_rgb24( buffer->format, src8, lock.pitch, surface->config.size.h,
+ buf_p, surface->config.size.w * 3, surface->config.size.w, 1 );
+#ifdef USE_ZLIB
+ gzwrite( gz_p, buf_p, surface->config.size.w * 3 );
+#else
+ write( fd_p, buf_p, surface->config.size.w * 3 );
+#endif
+ }
+
+ /* Write alpha buffer to graymap file. */
+ if (alpha) {
+ u8 buf_g[surface->config.size.w];
+
+ if (buffer->format == DSPF_LUT8) {
+ for (n=0; n<surface->config.size.w; n++)
+ buf_g[n] = palette->entries[src8[n]].a;
+ }
+ else
+ dfb_convert_to_a8( buffer->format, src8, lock.pitch, surface->config.size.h,
+ buf_g, surface->config.size.w, surface->config.size.w, 1 );
+#ifdef USE_ZLIB
+ gzwrite( gz_g, buf_g, surface->config.size.w );
+#else
+ write( fd_g, buf_g, surface->config.size.w );
+#endif
+ }
+ }
+
+ /* Unlock the surface buffer. */
+ dfb_surface_buffer_unlock( &lock );
+
+ /* Release the palette. */
+ if (palette)
+ dfb_palette_unref( palette );
+
+#ifdef USE_ZLIB
+ if (rgb)
+ gzclose( gz_p );
+
+ if (alpha)
+ gzclose( gz_g );
+#endif
+
+ /* Close pixmap file. */
+ if (rgb)
+ close( fd_p );
+
+ /* Close graymap file. */
+ if (alpha)
+ close( fd_g );
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+static void
+transfer_buffer( CoreSurfaceBuffer *buffer,
+ const void *src,
+ void *dst,
+ int srcpitch,
+ int dstpitch )
+{
+ int i;
+ CoreSurface *surface;
+
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ D_DEBUG_AT( Core_SurfBuffer, "%s( %p, %p [%d] -> %p [%d] ) * %d\n",
+ __FUNCTION__, buffer, src, srcpitch, dst, dstpitch, surface->config.size.h );
+
+ D_ASSERT( src != NULL );
+ D_ASSERT( dst != NULL );
+ D_ASSERT( srcpitch > 0 );
+ D_ASSERT( dstpitch > 0 );
+
+ D_ASSERT( srcpitch >= DFB_BYTES_PER_LINE( buffer->format, surface->config.size.w ) );
+ D_ASSERT( dstpitch >= DFB_BYTES_PER_LINE( buffer->format, surface->config.size.w ) );
+
+ for (i=0; i<surface->config.size.h; i++) {
+ direct_memcpy( dst, src, DFB_BYTES_PER_LINE( buffer->format, surface->config.size.w ) );
+
+ src += srcpitch;
+ dst += dstpitch;
+ }
+
+ switch (buffer->format) {
+ case DSPF_YV12:
+ case DSPF_I420:
+ for (i=0; i<surface->config.size.h; i++) {
+ direct_memcpy( dst, src,
+ DFB_BYTES_PER_LINE( buffer->format, surface->config.size.w / 2 ) );
+ src += srcpitch / 2;
+ dst += dstpitch / 2;
+ }
+ break;
+
+ case DSPF_NV12:
+ case DSPF_NV21:
+ for (i=0; i<surface->config.size.h/2; i++) {
+ direct_memcpy( dst, src,
+ DFB_BYTES_PER_LINE( buffer->format, surface->config.size.w ) );
+ src += srcpitch;
+ dst += dstpitch;
+ }
+ break;
+
+ case DSPF_NV16:
+ for (i=0; i<surface->config.size.h; i++) {
+ direct_memcpy( dst, src,
+ DFB_BYTES_PER_LINE( buffer->format, surface->config.size.w ) );
+ src += srcpitch;
+ dst += dstpitch;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static DFBResult
+allocation_update_copy( CoreSurfaceAllocation *allocation,
+ CoreSurfaceAllocation *source )
+{
+ DFBResult ret;
+ CoreSurfaceBufferLock src;
+ CoreSurfaceBufferLock dst;
+ CoreSurfaceBuffer *buffer;
+
+ D_DEBUG_AT( Core_SurfBuffer, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( allocation != source );
+
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( source, CoreSurfaceAllocation );
+
+ D_ASSERT( source->buffer == allocation->buffer );
+
+ buffer = allocation->buffer;
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ /* Lock the source allocation. */
+ dfb_surface_buffer_lock_init( &src, CSAID_CPU, CSAF_READ );
+
+ ret = dfb_surface_pool_lock( source->pool, source, &src );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Could not lock source for transfer!\n" );
+ dfb_surface_buffer_lock_deinit( &src );
+ return ret;
+ }
+
+ /* Lock the destination allocation. */
+ dfb_surface_buffer_lock_init( &dst, CSAID_CPU, CSAF_WRITE );
+
+ ret = dfb_surface_pool_lock( allocation->pool, allocation, &dst );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Could not lock destination for transfer!\n" );
+ dfb_surface_pool_unlock( source->pool, source, &src );
+ return ret;
+ }
+
+ transfer_buffer( buffer, src.addr, dst.addr, src.pitch, dst.pitch );
+
+ dfb_surface_pool_unlock( allocation->pool, allocation, &dst );
+ dfb_surface_pool_unlock( source->pool, source, &src );
+
+ dfb_surface_buffer_lock_deinit( &dst );
+ dfb_surface_buffer_lock_deinit( &src );
+
+ return DFB_OK;
+}
+
+static DFBResult
+allocation_update_write( CoreSurfaceAllocation *allocation,
+ CoreSurfaceAllocation *source )
+{
+ DFBResult ret;
+ CoreSurfaceBufferLock src;
+ CoreSurfaceBuffer *buffer;
+
+ D_DEBUG_AT( Core_SurfBuffer, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( allocation != source );
+
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( source, CoreSurfaceAllocation );
+
+ D_ASSERT( source->buffer == allocation->buffer );
+
+ buffer = allocation->buffer;
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ /* Lock the source allocation. */
+ dfb_surface_buffer_lock_init( &src, CSAID_CPU, CSAF_READ );
+
+ ret = dfb_surface_pool_lock( source->pool, source, &src );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Could not lock source for transfer!\n" );
+ dfb_surface_buffer_lock_deinit( &src );
+ return ret;
+ }
+
+ /* Write to the destination allocation. */
+ ret = dfb_surface_pool_write( allocation->pool, allocation, src.addr, src.pitch, NULL );
+ if (ret)
+ D_DERROR( ret, "Core/SurfBuffer: Could not write from destination allocation!\n" );
+
+ dfb_surface_pool_unlock( source->pool, source, &src );
+
+ dfb_surface_buffer_lock_deinit( &src );
+
+ return ret;
+}
+
+static DFBResult
+allocation_update_read( CoreSurfaceAllocation *allocation,
+ CoreSurfaceAllocation *source )
+{
+ DFBResult ret;
+ CoreSurfaceBufferLock dst;
+ CoreSurfaceBuffer *buffer;
+
+ D_DEBUG_AT( Core_SurfBuffer, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( allocation != source );
+
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( source, CoreSurfaceAllocation );
+
+ D_ASSERT( source->buffer == allocation->buffer );
+
+ buffer = allocation->buffer;
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ /* Lock the destination allocation. */
+ dfb_surface_buffer_lock_init( &dst, CSAID_CPU, CSAF_WRITE );
+
+ ret = dfb_surface_pool_lock( allocation->pool, allocation, &dst );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfBuffer: Could not lock destination for transfer!\n" );
+ dfb_surface_buffer_lock_deinit( &dst );
+ return ret;
+ }
+
+ /* Read from the source allocation. */
+ ret = dfb_surface_pool_read( source->pool, source, dst.addr, dst.pitch, NULL );
+ if (ret)
+ D_DERROR( ret, "Core/SurfBuffer: Could not read from source allocation!\n" );
+
+ dfb_surface_pool_unlock( allocation->pool, allocation, &dst );
+
+ dfb_surface_buffer_lock_deinit( &dst );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_allocation_update( CoreSurfaceAllocation *allocation,
+ CoreSurfaceAccessFlags access )
+{
+ DFBResult ret;
+ int i;
+ CoreSurfaceAllocation *alloc;
+ CoreSurfaceBuffer *buffer;
+
+ D_DEBUG_AT( Core_SurfBuffer, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_FLAGS_ASSERT( access, CSAF_ALL );
+
+ buffer = allocation->buffer;
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ if (direct_serial_update( &allocation->serial, &buffer->serial ) && buffer->written) {
+ CoreSurfaceAllocation *source = buffer->written;
+
+ D_ASSUME( allocation != source );
+
+ D_DEBUG_AT( Core_SurfBuffer, " -> updating allocation...\n" );
+
+ D_MAGIC_ASSERT( source, CoreSurfaceAllocation );
+ D_ASSERT( source->buffer == allocation->buffer );
+
+ ret = dfb_surface_pool_bridges_transfer( buffer, source, allocation, NULL, 0 );
+ if (ret) {
+ if ((source->access[CSAID_CPU] & CSAF_READ) && (allocation->access[CSAID_CPU] & CSAF_WRITE))
+ ret = allocation_update_copy( allocation, source );
+ else if (source->access[CSAID_CPU] & CSAF_READ)
+ ret = allocation_update_write( allocation, source );
+ else if (allocation->access[CSAID_CPU] & CSAF_WRITE)
+ ret = allocation_update_read( allocation, source );
+ else {
+ D_UNIMPLEMENTED();
+ ret = DFB_UNSUPPORTED;
+ }
+ }
+
+ if (ret) {
+ D_DERROR( ret, "Core/SurfaceBuffer: Updating allocation failed!\n" );
+ return ret;
+ }
+ }
+
+ if (access & CSAF_WRITE) {
+ D_DEBUG_AT( Core_SurfBuffer, " -> increasing serial...\n" );
+
+ direct_serial_increase( &buffer->serial );
+
+ direct_serial_copy( &allocation->serial, &buffer->serial );
+
+ buffer->written = allocation;
+ buffer->read = NULL;
+
+ /* Zap volatile allocations (freed when no longer up to date). */
+ fusion_vector_foreach (alloc, i, buffer->allocs) {
+ D_MAGIC_ASSERT( alloc, CoreSurfaceAllocation );
+
+ if (alloc != allocation && (alloc->flags & CSALF_VOLATILE)) {
+ dfb_surface_pool_deallocate( alloc->pool, alloc );
+ i--;
+ }
+ }
+ }
+ else
+ buffer->read = allocation;
+
+ /* Zap all other allocations? */
+ if (dfb_config->thrifty_surface_buffers) {
+ buffer->written = buffer->read = allocation;
+
+ fusion_vector_foreach (alloc, i, buffer->allocs) {
+ D_MAGIC_ASSERT( alloc, CoreSurfaceAllocation );
+
+ /* Don't zap preallocated which would not really free up memory, but just loose the handle. */
+ if (alloc != allocation && !(alloc->flags & (CSALF_PREALLOCATED | CSALF_MUCKOUT))) {
+ dfb_surface_pool_deallocate( alloc->pool, alloc );
+ i--;
+ }
+ }
+ }
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/core/surface_buffer.h b/Source/DirectFB/src/core/surface_buffer.h
new file mode 100755
index 0000000..4acf65a
--- /dev/null
+++ b/Source/DirectFB/src/core/surface_buffer.h
@@ -0,0 +1,257 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__SURFACE_BUFFER_H__
+#define __CORE__SURFACE_BUFFER_H__
+
+#include <direct/debug.h>
+#include <direct/list.h>
+
+#include <fusion/vector.h>
+
+#include <core/surface.h>
+
+#include <directfb.h>
+
+
+/*
+ * Configuration and State flags of a Surface Buffer
+ */
+typedef enum {
+ CSBF_NONE = 0x00000000, /* None of these. */
+
+ CSBF_STICKED = 0x00000001, /* Sticked to one Surface Pool, e.g. system only. */
+
+ CSBF_ALL = 0x00000001 /* All of these. */
+} CoreSurfaceBufferFlags;
+
+/*
+ * Configuration and State flags of a Surface Buffer Allocation
+ */
+typedef enum {
+ CSALF_NONE = 0x00000000, /* None of these. */
+
+ CSALF_ONEFORALL = 0x00000001, /* Only one allocation in pool for all buffers. */
+ CSALF_VOLATILE = 0x00000002, /* Allocation should be freed when no longer up to date. */
+ CSALF_PREALLOCATED = 0x00000004, /* Preallocated memory, don't zap when "thrifty-surface-buffers" is active. */
+
+ CSALF_MUCKOUT = 0x00001000, /* Indicates surface pool being in the progress of mucking out this and possibly
+ other allocations to have enough space for a new allocation to be made. */
+
+ CSALF_ALL = 0x00001007 /* All of these. */
+} CoreSurfaceAllocationFlags;
+
+/*
+ * An Allocation of a Surface Buffer
+ */
+struct __DFB_CoreSurfaceAllocation {
+ int magic;
+
+ DirectSerial serial; /* Equals serial of buffer if content is up to date. */
+
+ CoreSurfaceBuffer *buffer; /* Surface Buffer owning this allocation. */
+ CoreSurface *surface; /* Surface owning the Buffer of this allocation. */
+ CoreSurfacePool *pool; /* Surface Pool providing the allocation. */
+ void *data; /* Pool's private data for this allocation. */
+ int size; /* Amount of data used by this allocation. */
+ unsigned long offset; /* Offset within address range of pool if contiguous. */
+
+ CoreSurfaceAllocationFlags flags; /* Pool can return CSALF_ONEFORALL upon allocation of first buffer. */
+
+ const CoreSurfaceAccessFlags *access; /* Possible access flags (pointer to pool description). */
+ CoreSurfaceAccessFlags accessed[_CSAID_NUM]; /* Access since last synchronization. */
+};
+
+#define CORE_SURFACE_ALLOCATION_ASSERT(alloc) \
+ do { \
+ D_MAGIC_ASSERT( alloc, CoreSurfaceAllocation ); \
+ D_ASSUME( (alloc)->size > 0 ); \
+ D_ASSERT( (alloc)->size >= 0 ); \
+ D_ASSERT( (alloc)->offset + (alloc)->size <= ((alloc)->pool->desc.size ?:~0UL) ); \
+ D_FLAGS_ASSERT( (alloc)->access[CSAID_CPU], CSAF_ALL ); \
+ D_FLAGS_ASSERT( (alloc)->access[CSAID_GPU], CSAF_ALL ); \
+ D_FLAGS_ASSERT( (alloc)->flags, CSALF_ALL ); \
+ D_FLAGS_ASSERT( (alloc)->accessed[CSAID_CPU], CSAF_ALL ); \
+ D_FLAGS_ASSERT( (alloc)->accessed[CSAID_GPU], CSAF_ALL ); \
+ } while (0)
+
+/*
+ * A Lock on a Surface Buffer
+ */
+struct __DFB_CoreSurfaceBufferLock {
+ int magic; /* Must be valid before calling dfb_surface_pool_lock() */
+
+ CoreSurfaceAccessorID accessor; /* " */
+ CoreSurfaceAccessFlags access; /* " */
+
+ CoreSurfaceBuffer *buffer; /* Set by dfb_surface_pool_lock() */
+ CoreSurfaceAllocation *allocation; /* " */
+
+ void *addr; /* " */
+ unsigned long phys; /* " */
+ unsigned long offset; /* " */
+ unsigned int pitch; /* " */
+
+ void *handle; /* " */
+};
+
+static inline void
+dfb_surface_buffer_lock_reset( CoreSurfaceBufferLock *lock )
+{
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ lock->buffer = NULL;
+ lock->allocation = NULL;
+ lock->addr = NULL;
+ lock->phys = 0;
+ lock->offset = ~0;
+ lock->pitch = 0;
+ lock->handle = NULL;
+}
+
+static inline void
+dfb_surface_buffer_lock_init( CoreSurfaceBufferLock *lock, CoreSurfaceAccessorID accessor, CoreSurfaceAccessFlags access )
+{
+ D_MAGIC_SET( lock, CoreSurfaceBufferLock );
+
+ lock->accessor = accessor;
+ lock->access = access;
+
+ dfb_surface_buffer_lock_reset( lock );
+}
+
+static inline void
+dfb_surface_buffer_lock_deinit( CoreSurfaceBufferLock *lock )
+{
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ lock->accessor = CSAID_NONE;
+ lock->access = CSAF_NONE;
+
+ D_MAGIC_CLEAR( lock );
+}
+
+#define CORE_SURFACE_BUFFER_LOCK_ASSERT(lock) \
+ do { \
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock ); \
+ D_FLAGS_ASSERT( (lock)->access, CSAF_ALL ); \
+ if ((lock)->buffer) { \
+ D_ASSERT( (lock)->allocation != NULL ); \
+ D_ASSERT( (lock)->buffer == (lock)->allocation->buffer ); \
+ D_ASSUME( (lock)->addr != NULL || (lock)->phys != 0 || (lock)->offset != ~0 || (lock)->handle != NULL );\
+ D_ASSUME( (lock)->offset == (lock)->allocation->offset || (lock)->offset == ~0 ); \
+ D_ASSERT( (lock)->pitch > 0 || ((lock)->addr == NULL && (lock)->phys == 0) ); \
+ } \
+ else { \
+ D_ASSERT( (lock)->allocation == NULL ); \
+ D_ASSERT( (lock)->addr == NULL ); \
+ D_ASSERT( (lock)->phys == 0 ); \
+ D_ASSERT( (lock)->offset == ~0 ); \
+ D_ASSERT( (lock)->pitch == 0 ); \
+ D_ASSERT( (lock)->handle == NULL ); \
+ } \
+ } while (0)
+
+/*
+ * A Surface Buffer of a Surface
+ */
+struct __DFB_CoreSurfaceBuffer {
+ int magic;
+
+ DirectSerial serial; /* Increased when content is written. */
+ CoreSurfaceAllocation *written; /* Allocation with the last write access. */
+ CoreSurfaceAllocation *read; /* Allocation with the last read access. */
+
+ CoreSurface *surface; /* Surface owning this Surface Buffer. */
+ CoreSurfacePolicy policy;
+
+ CoreSurfaceBufferFlags flags; /* Configuration and State flags. */
+ DFBSurfacePixelFormat format; /* Pixel format of buffer data. */
+
+ FusionVector allocs; /* Allocations within Surface Pools. */
+
+#if 1
+ unsigned int locked; /* Lock count. FIXME: Add fail safe cleanup! */
+#endif
+};
+
+
+DFBResult dfb_surface_buffer_new ( CoreSurface *surface,
+ CoreSurfaceBufferFlags flags,
+ CoreSurfaceBuffer **ret_buffer );
+
+DFBResult dfb_surface_buffer_destroy( CoreSurfaceBuffer *buffer );
+
+
+DFBResult dfb_surface_buffer_lock ( CoreSurfaceBuffer *buffer,
+ CoreSurfaceAccessorID accessor,
+ CoreSurfaceAccessFlags access,
+ CoreSurfaceBufferLock *ret_lock );
+
+DFBResult dfb_surface_buffer_unlock ( CoreSurfaceBufferLock *lock );
+
+DFBResult dfb_surface_buffer_read ( CoreSurfaceBuffer *buffer,
+ void *destination,
+ int pitch,
+ const DFBRectangle *rect );
+
+DFBResult dfb_surface_buffer_write ( CoreSurfaceBuffer *buffer,
+ const void *source,
+ int pitch,
+ const DFBRectangle *rect );
+
+DFBResult dfb_surface_buffer_dump ( CoreSurfaceBuffer *buffer,
+ const char *directory,
+ const char *prefix );
+
+static inline int
+dfb_surface_buffer_index( CoreSurfaceBuffer *buffer )
+{
+ int index;
+ CoreSurface *surface;
+
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ for (index=0; index<MAX_SURFACE_BUFFERS; index++) {
+ if (surface->buffers[index] == buffer)
+ return index;
+ }
+
+ D_ASSERT( index<MAX_SURFACE_BUFFERS );
+
+ return 0;
+}
+
+DFBResult dfb_surface_allocation_update( CoreSurfaceAllocation *allocation,
+ CoreSurfaceAccessFlags access );
+
+#endif
+
diff --git a/Source/DirectFB/src/core/surface_core.c b/Source/DirectFB/src/core/surface_core.c
new file mode 100755
index 0000000..11aa286
--- /dev/null
+++ b/Source/DirectFB/src/core/surface_core.c
@@ -0,0 +1,214 @@
+/*
+ (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 <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/core_parts.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+#include <core/surface_pool.h>
+
+
+extern SurfacePoolFuncs localSurfacePoolFuncs;
+extern SurfacePoolFuncs sharedSurfacePoolFuncs;
+extern SurfacePoolFuncs preallocSurfacePoolFuncs;
+
+
+
+D_DEBUG_DOMAIN( Core_Surface, "Core/SurfaceCore", "DirectFB Surface Core" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+ CoreSurfacePool *local_pool;
+ CoreSurfacePool *shared_pool;
+ CoreSurfacePool *prealloc_pool;
+} DFBSurfaceCoreShared;
+
+typedef struct {
+ int magic;
+
+ CoreDFB *core;
+
+ DFBSurfaceCoreShared *shared;
+} DFBSurfaceCore;
+
+
+DFB_CORE_PART( surface_core, SurfaceCore );
+
+/**********************************************************************************************************************/
+
+static DFBResult
+dfb_surface_core_initialize( CoreDFB *core,
+ DFBSurfaceCore *data,
+ DFBSurfaceCoreShared *shared )
+{
+ DFBResult ret;
+
+ D_DEBUG_AT( Core_Surface, "dfb_surface_core_initialize( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( shared != NULL );
+
+ data->core = core;
+ data->shared = shared;
+
+ ret = dfb_surface_pool_initialize( core, &sharedSurfacePoolFuncs, &shared->shared_pool );
+ if (ret) {
+ D_DERROR( ret, "Core/Surface: Could not register 'shared' surface pool!\n" );
+ return ret;
+ }
+
+ ret = dfb_surface_pool_initialize( core, &localSurfacePoolFuncs, &shared->local_pool );
+ if (ret) {
+ D_DERROR( ret, "Core/Surface: Could not register 'local' surface pool!\n" );
+ dfb_surface_pool_destroy( shared->shared_pool );
+ return ret;
+ }
+
+ ret = dfb_surface_pool_initialize( core, &preallocSurfacePoolFuncs, &shared->prealloc_pool );
+ if (ret) {
+ D_DERROR( ret, "Core/Surface: Could not register 'prealloc' surface pool!\n" );
+ dfb_surface_pool_destroy( shared->local_pool );
+ dfb_surface_pool_destroy( shared->shared_pool );
+ return ret;
+ }
+
+ D_MAGIC_SET( data, DFBSurfaceCore );
+ D_MAGIC_SET( shared, DFBSurfaceCoreShared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_surface_core_join( CoreDFB *core,
+ DFBSurfaceCore *data,
+ DFBSurfaceCoreShared *shared )
+{
+ D_DEBUG_AT( Core_Surface, "dfb_surface_core_join( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_MAGIC_ASSERT( shared, DFBSurfaceCoreShared );
+
+ data->core = core;
+ data->shared = shared;
+
+ dfb_surface_pool_join( core, shared->shared_pool, &sharedSurfacePoolFuncs );
+ dfb_surface_pool_join( core, shared->local_pool, &localSurfacePoolFuncs );
+ dfb_surface_pool_join( core, shared->prealloc_pool, &preallocSurfacePoolFuncs );
+
+ D_MAGIC_SET( data, DFBSurfaceCore );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_surface_core_shutdown( DFBSurfaceCore *data,
+ bool emergency )
+{
+ DFBSurfaceCoreShared *shared;
+
+ D_DEBUG_AT( Core_Surface, "dfb_surface_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBSurfaceCore );
+ D_MAGIC_ASSERT( data->shared, DFBSurfaceCoreShared );
+
+ shared = data->shared;
+
+ dfb_surface_pool_destroy( shared->prealloc_pool );
+ dfb_surface_pool_destroy( shared->local_pool );
+ dfb_surface_pool_destroy( shared->shared_pool );
+
+ D_MAGIC_CLEAR( data );
+ D_MAGIC_CLEAR( shared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_surface_core_leave( DFBSurfaceCore *data,
+ bool emergency )
+{
+ DFBSurfaceCoreShared *shared;
+
+ D_DEBUG_AT( Core_Surface, "dfb_surface_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBSurfaceCore );
+ D_MAGIC_ASSERT( data->shared, DFBSurfaceCoreShared );
+
+ shared = data->shared;
+
+ dfb_surface_pool_leave( shared->shared_pool );
+ dfb_surface_pool_leave( shared->local_pool );
+ dfb_surface_pool_leave( shared->prealloc_pool );
+
+ D_MAGIC_CLEAR( data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_surface_core_suspend( DFBSurfaceCore *data )
+{
+ DFBSurfaceCoreShared *shared;
+
+ D_DEBUG_AT( Core_Surface, "dfb_surface_core_suspend( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBSurfaceCore );
+ D_MAGIC_ASSERT( data->shared, DFBSurfaceCoreShared );
+
+ shared = data->shared;
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_surface_core_resume( DFBSurfaceCore *data )
+{
+ DFBSurfaceCoreShared *shared;
+
+ D_DEBUG_AT( Core_Surface, "dfb_surface_core_resume( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBSurfaceCore );
+ D_MAGIC_ASSERT( data->shared, DFBSurfaceCoreShared );
+
+ shared = data->shared;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/core/surface_pool.c b/Source/DirectFB/src/core/surface_pool.c
new file mode 100755
index 0000000..0518df2
--- /dev/null
+++ b/Source/DirectFB/src/core/surface_pool.c
@@ -0,0 +1,1263 @@
+/*
+ (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 <directfb.h>
+#include <directfb_util.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+
+#include <core/surface_buffer.h>
+#include <core/surface_pool.h>
+#include <core/system.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+
+D_DEBUG_DOMAIN( Core_SurfacePool, "Core/SurfacePool", "DirectFB Core Surface Pool" );
+D_DEBUG_DOMAIN( Core_SurfPoolLock, "Core/SurfPoolLock", "DirectFB Core Surface Pool Lock" );
+
+/**********************************************************************************************************************/
+
+static const SurfacePoolFuncs *pool_funcs[MAX_SURFACE_POOLS];
+static void *pool_locals[MAX_SURFACE_POOLS];
+static int pool_count;
+static CoreSurfacePool *pool_array[MAX_SURFACE_POOLS];
+static unsigned int pool_order[MAX_SURFACE_POOLS];
+
+/**********************************************************************************************************************/
+
+static inline const SurfacePoolFuncs *
+get_funcs( const CoreSurfacePool *pool )
+{
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ D_ASSERT( pool->pool_id >= 0 );
+ D_ASSERT( pool->pool_id < MAX_SURFACE_POOLS );
+ D_ASSERT( pool_funcs[pool->pool_id] != NULL );
+
+ /* Return function table of the pool. */
+ return pool_funcs[pool->pool_id];
+}
+
+static inline void *
+get_local( const CoreSurfacePool *pool )
+{
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ D_ASSERT( pool->pool_id >= 0 );
+ D_ASSERT( pool->pool_id < MAX_SURFACE_POOLS );
+
+ /* Return local data of the pool. */
+ return pool_locals[pool->pool_id];
+}
+
+/**********************************************************************************************************************/
+
+static DFBResult init_pool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ const SurfacePoolFuncs *funcs );
+
+/**********************************************************************************************************************/
+
+static void insert_pool_local( CoreSurfacePool *pool );
+static void remove_pool_local( CoreSurfacePoolID pool_id );
+
+/**********************************************************************************************************************/
+
+static void remove_allocation( CoreSurfacePool *pool,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation );
+
+static DFBResult backup_allocation( CoreSurfacePool *pool,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation );
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_surface_pool_initialize( CoreDFB *core,
+ const SurfacePoolFuncs *funcs,
+ CoreSurfacePool **ret_pool )
+{
+ DFBResult ret;
+ CoreSurfacePool *pool;
+ FusionSHMPoolShared *shmpool;
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p )\n", __FUNCTION__, funcs );
+
+ D_ASSERT( core != NULL );
+ D_ASSERT( funcs != NULL );
+ D_ASSERT( ret_pool != NULL );
+
+ /* Check against pool limit. */
+ if (pool_count == MAX_SURFACE_POOLS) {
+ D_ERROR( "Core/SurfacePool: Maximum number of pools (%d) reached!\n", MAX_SURFACE_POOLS );
+ return DFB_LIMITEXCEEDED;
+ }
+
+ D_ASSERT( pool_funcs[pool_count] == NULL );
+
+ shmpool = dfb_core_shmpool( core );
+
+ /* Allocate pool structure. */
+ pool = SHCALLOC( shmpool, 1, sizeof(CoreSurfacePool) );
+ if (!pool)
+ return D_OOSHM();
+
+ /* Assign a pool ID. */
+ pool->pool_id = pool_count++;
+
+ /* Remember shared memory pool. */
+ pool->shmpool = shmpool;
+
+ /* Set function table of the pool. */
+ pool_funcs[pool->pool_id] = funcs;
+
+ /* Add to global pool list. */
+ pool_array[pool->pool_id] = pool;
+
+ D_MAGIC_SET( pool, CoreSurfacePool );
+
+ ret = init_pool( core, pool, funcs );
+ if (ret) {
+ pool_funcs[pool->pool_id] = NULL;
+ pool_array[pool->pool_id] = NULL;
+ pool_count--;
+ D_MAGIC_CLEAR( pool );
+ SHFREE( shmpool, pool );
+ return ret;
+ }
+
+ /* Set default backup pool being the shared memory surface pool */
+ if (!pool->backup && pool_count > 1)
+ pool->backup = pool_array[0];
+
+ /* Insert new pool into priority order */
+ insert_pool_local( pool );
+
+ /* Return the new pool. */
+ *ret_pool = pool;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_pool_join( CoreDFB *core,
+ CoreSurfacePool *pool,
+ const SurfacePoolFuncs *funcs )
+{
+ DFBResult ret;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p [%d], %p )\n", __FUNCTION__, pool, pool->pool_id, funcs );
+
+ D_ASSERT( core != NULL );
+ D_ASSERT( funcs != NULL );
+
+ D_ASSERT( pool->pool_id < MAX_SURFACE_POOLS );
+ D_ASSERT( pool->pool_id == pool_count );
+ D_ASSERT( pool_funcs[pool->pool_id] == NULL );
+
+ /* Enforce same order as initialization to be used during join. */
+ if (pool->pool_id != pool_count) {
+ D_ERROR( "Core/SurfacePool: Wrong order of joining pools, got %d, should be %d!\n",
+ pool->pool_id, pool_count );
+ return DFB_BUG;
+ }
+
+ /* Allocate local pool data. */
+ if (pool->pool_local_data_size &&
+ !(pool_locals[pool->pool_id] = D_CALLOC( 1, pool->pool_local_data_size )))
+ return D_OOM();
+
+ /* Set function table of the pool. */
+ pool_funcs[pool->pool_id] = funcs;
+
+ /* Add to global pool list. */
+ pool_array[pool->pool_id] = pool;
+
+ /* Adjust pool count. */
+ if (pool_count < pool->pool_id + 1)
+ pool_count = pool->pool_id + 1;
+
+ funcs = get_funcs( pool );
+
+ if (funcs->JoinPool) {
+ ret = funcs->JoinPool( core, pool, pool->data, get_local(pool), dfb_system_data() );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfacePool: Joining '%s' failed!\n", pool->desc.name );
+
+ if (pool_locals[pool->pool_id]) {
+ D_FREE( pool_locals[pool->pool_id] );
+ pool_locals[pool->pool_id] = NULL;
+ }
+
+ pool_count--;
+
+ return ret;
+ }
+ }
+
+ /* Insert new pool into priority order */
+ insert_pool_local( pool );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_pool_destroy( CoreSurfacePool *pool )
+{
+ CoreSurfacePoolID pool_id;
+ const SurfacePoolFuncs *funcs;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ pool_id = pool->pool_id;
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p, '%s' [%d] )\n", __FUNCTION__, pool, pool->desc.name, pool_id );
+
+ D_ASSERT( pool->pool_id >= 0 );
+ D_ASSERT( pool_id < MAX_SURFACE_POOLS );
+ D_ASSERT( pool_array[pool_id] == pool );
+
+ funcs = get_funcs( pool );
+
+ if (funcs->DestroyPool)
+ funcs->DestroyPool( pool, pool->data, get_local(pool) );
+
+ /* Free shared pool data. */
+ if (pool->data)
+ SHFREE( pool->shmpool, pool->data );
+
+ /* Free local pool data and remove from lists */
+ remove_pool_local( pool_id );
+
+ fusion_skirmish_destroy( &pool->lock );
+
+ fusion_vector_destroy( &pool->allocs );
+
+ D_MAGIC_CLEAR( pool );
+
+ SHFREE( pool->shmpool, pool );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_pool_leave( CoreSurfacePool *pool )
+{
+ CoreSurfacePoolID pool_id;
+ const SurfacePoolFuncs *funcs;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ pool_id = pool->pool_id;
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p, '%s' [%d] )\n", __FUNCTION__, pool, pool->desc.name, pool_id );
+
+ D_ASSERT( pool->pool_id >= 0 );
+ D_ASSERT( pool_id < MAX_SURFACE_POOLS );
+ D_ASSERT( pool_array[pool_id] == pool );
+
+ funcs = get_funcs( pool );
+
+ if (funcs->LeavePool)
+ funcs->LeavePool( pool, pool->data, get_local(pool) );
+
+ /* Free local pool data and remove from lists */
+ remove_pool_local( pool_id );
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_surface_pools_negotiate( CoreSurfaceBuffer *buffer,
+ CoreSurfaceAccessorID accessor,
+ CoreSurfaceAccessFlags access,
+ CoreSurfacePool **ret_pools,
+ unsigned int max_pools,
+ unsigned int *ret_num )
+{
+ DFBResult ret;
+ int i;
+ unsigned int num = 0;
+ CoreSurface *surface;
+ CoreSurfaceTypeFlags type;
+ unsigned int free_count = 0;
+ CoreSurfacePool *free_pools[pool_count];
+ unsigned int oom_count = 0;
+ CoreSurfacePool *oom_pools[pool_count];
+
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p [%s], 0x%02x, 0x%02x, max %d )\n", __FUNCTION__,
+ buffer, dfb_pixelformat_name( buffer->format ), accessor, access, max_pools );
+
+ D_ASSERT( ret_pools != NULL );
+ D_ASSERT( max_pools > 0 );
+ D_ASSERT( ret_num != NULL );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ D_ASSERT( accessor >= CSAID_CPU );
+ D_ASSUME( accessor < _CSAID_NUM );
+ if (accessor >= CSAID_ANY) {
+ D_UNIMPLEMENTED();
+ return DFB_UNIMPLEMENTED;
+ }
+
+ if (accessor < 0 || accessor >= _CSAID_NUM)
+ return DFB_INVARG;
+
+ type = surface->type & ~(CSTF_INTERNAL | CSTF_EXTERNAL);
+
+ switch (buffer->policy) {
+ case CSP_SYSTEMONLY:
+ type |= CSTF_INTERNAL;
+ break;
+
+ case CSP_VIDEOONLY:
+ type |= CSTF_EXTERNAL;
+ break;
+
+ default:
+ break;
+ }
+
+ D_DEBUG_AT( Core_SurfacePool, " -> 0x%02x 0x%03x required\n", access, type );
+
+ for (i=0; i<pool_count; i++) {
+ CoreSurfacePool *pool;
+
+ D_ASSERT( pool_order[i] >= 0 );
+ D_ASSERT( pool_order[i] < pool_count );
+
+ pool = pool_array[pool_order[i]];
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ if (D_FLAGS_ARE_SET( pool->desc.access[accessor], access ) &&
+ D_FLAGS_ARE_SET( pool->desc.types, type ))
+ {
+ const SurfacePoolFuncs *funcs;
+
+ D_DEBUG_AT( Core_SurfacePool, " -> [%d] 0x%02x 0x%03x (%d) [%s]\n", pool->pool_id,
+ pool->desc.caps, pool->desc.types, pool->desc.priority, pool->desc.name );
+
+ funcs = get_funcs( pool );
+
+ ret = funcs->TestConfig ? funcs->TestConfig( pool, pool->data, get_local(pool),
+ buffer, &surface->config ) : DFB_OK;
+ switch (ret) {
+ case DFB_OK:
+ D_DEBUG_AT( Core_SurfacePool, " => OK\n" );
+ free_pools[free_count++] = pool;
+ break;
+
+ case DFB_NOVIDEOMEMORY:
+ D_DEBUG_AT( Core_SurfacePool, " => OUT OF MEMORY\n" );
+ oom_pools[oom_count++] = pool;
+ break;
+
+ default:
+ continue;
+ }
+ }
+ }
+
+ D_DEBUG_AT( Core_SurfacePool, " => %d pools available\n", free_count );
+ D_DEBUG_AT( Core_SurfacePool, " => %d pools out of memory\n", oom_count );
+
+ for (i=0; i<free_count && num<max_pools; i++)
+ ret_pools[num++] = free_pools[i];
+
+ for (i=0; i<oom_count && num<max_pools; i++)
+ ret_pools[num++] = oom_pools[i];
+
+ *ret_num = num;
+
+ return free_count ? DFB_OK : oom_count ? DFB_NOVIDEOMEMORY : DFB_UNSUPPORTED;
+}
+
+DFBResult
+dfb_surface_pools_enumerate( CoreSurfacePoolCallback callback,
+ void *ctx )
+{
+ int i;
+
+ D_ASSERT( callback != NULL );
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p, %p )\n", __FUNCTION__, callback, ctx );
+
+ for (i=0; i<pool_count; i++) {
+ CoreSurfacePool *pool = pool_array[i];
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ if (callback( pool, ctx ) == DFENUM_CANCEL)
+ break;
+ }
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_pools_allocate( CoreSurfaceBuffer *buffer,
+ CoreSurfaceAccessorID accessor,
+ CoreSurfaceAccessFlags access,
+ CoreSurfaceAllocation **ret_allocation )
+{
+ DFBResult ret;
+ int i;
+ CoreSurface *surface;
+ CoreSurfaceAllocation *allocation = NULL;
+ CoreSurfacePool *pools[pool_count];
+ unsigned int num_pools;
+
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_FLAGS_ASSERT( access, CSAF_ALL );
+ D_ASSERT( ret_allocation != NULL );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p, 0x%x )\n", __FUNCTION__, buffer, access );
+
+ D_DEBUG_AT( Core_SurfacePool, " -> %dx%d %s - %s%s%s%s%s%s%s%s\n",
+ surface->config.size.w, surface->config.size.h,
+ dfb_pixelformat_name( surface->config.format ),
+ (surface->type & CSTF_SHARED) ? "SHARED" : "PRIVATE",
+ (surface->type & CSTF_LAYER) ? " LAYER" : "",
+ (surface->type & CSTF_WINDOW) ? " WINDOW" : "",
+ (surface->type & CSTF_CURSOR) ? " CURSOR" : "",
+ (surface->type & CSTF_FONT) ? " FONT" : "",
+ (surface->type & CSTF_INTERNAL) ? " INTERNAL" : "",
+ (surface->type & CSTF_EXTERNAL) ? " EXTERNAL" : "",
+ (surface->type & CSTF_PREALLOCATED) ? " PREALLOCATED" : "" );
+
+ D_ASSERT( accessor >= CSAID_CPU );
+ D_ASSUME( accessor < _CSAID_NUM );
+ if (accessor >= CSAID_ANY) {
+ D_UNIMPLEMENTED();
+ return DFB_UNIMPLEMENTED;
+ }
+
+ if (accessor < 0 || accessor >= _CSAID_NUM)
+ return DFB_INVARG;
+
+ /* Build a list of possible pools being free or out of memory */
+ ret = dfb_surface_pools_negotiate( buffer, accessor, access, pools, pool_count, &num_pools );
+ if (ret && ret != DFB_NOVIDEOMEMORY) {
+ D_DEBUG_AT( Core_SurfacePool, " -> NEGOTIATION FAILED! (%s)\n", DirectFBErrorString( ret ) );
+ return ret;
+ }
+
+ /* Try to do the allocation in one of the pools */
+ for (i=0; i<num_pools; i++) {
+ CoreSurfacePool *pool = pools[i];
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ ret = dfb_surface_pool_allocate( pool, buffer, &allocation );
+
+ if (ret == DFB_OK)
+ break;
+
+ /* When an error other than out of memory happens... */
+ if (ret != DFB_NOVIDEOMEMORY) {
+ D_DEBUG_AT( Core_SurfacePool, " -> Allocation in '%s' failed!\n", pool->desc.name );
+
+ /* ...forget about the pool for now */
+ pools[i] = NULL;
+ }
+ }
+
+ /* Check if none of the pools could do the allocation */
+ if (!allocation) {
+ /* Try to find a pool with "older" allocations to muck out */
+ for (i=0; i<num_pools; i++) {
+ CoreSurfacePool *pool = pools[i];
+
+ /* Pools with non-oom errors were sorted out above */
+ if (!pool)
+ continue;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ ret = dfb_surface_pool_displace( pool, buffer, &allocation );
+
+ if (ret == DFB_OK)
+ break;
+ }
+ }
+
+ /* Still no luck? */
+ if (!allocation) {
+ D_DEBUG_AT( Core_SurfacePool, " -> FAILED!\n" );
+ return DFB_FAILURE;
+ }
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ D_DEBUG_AT( Core_SurfacePool, " -> %p\n", allocation );
+
+ *ret_allocation = allocation;
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_surface_pool_allocate( CoreSurfacePool *pool,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation **ret_allocation )
+{
+ DFBResult ret;
+ int i;
+ CoreSurface *surface;
+ CoreSurfaceAllocation *allocation = NULL;
+ const SurfacePoolFuncs *funcs;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p [%d], %p )\n", __FUNCTION__, pool, pool->pool_id, buffer );
+
+ D_ASSERT( ret_allocation != NULL );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ funcs = get_funcs( pool );
+
+ D_ASSERT( funcs->AllocateBuffer != NULL );
+
+ allocation = SHCALLOC( pool->shmpool, 1, sizeof(CoreSurfaceAllocation) );
+ if (!allocation)
+ return D_OOSHM();
+
+ allocation->buffer = buffer;
+ allocation->surface = surface;
+ allocation->pool = pool;
+ allocation->access = pool->desc.access;
+
+ if (pool->alloc_data_size) {
+ allocation->data = SHCALLOC( pool->shmpool, 1, pool->alloc_data_size );
+ if (!allocation->data) {
+ ret = D_OOSHM();
+ goto error;
+ }
+ }
+
+ D_MAGIC_SET( allocation, CoreSurfaceAllocation );
+
+ if (fusion_skirmish_prevail( &pool->lock )) {
+ ret = DFB_FUSION;
+ goto error;
+ }
+
+ if (dfb_config->warn.flags & DCWF_ALLOCATE_BUFFER &&
+ dfb_config->warn.allocate_buffer.min_size.w <= surface->config.size.w &&
+ dfb_config->warn.allocate_buffer.min_size.h <= surface->config.size.h)
+ D_WARN( "allocate-buffer %4dx%4d %6s, surface-caps 0x%08x",
+ surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(buffer->format),
+ surface->config.caps );
+
+ ret = funcs->AllocateBuffer( pool, pool->data, get_local(pool), buffer, allocation, allocation->data );
+ if (ret) {
+ D_DEBUG_AT( Core_SurfacePool, " -> %s\n", DirectFBErrorString( ret ) );
+ D_MAGIC_CLEAR( allocation );
+ fusion_skirmish_dismiss( &pool->lock );
+ goto error;
+ }
+
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+
+ if (allocation->flags & CSALF_ONEFORALL) {
+ for (i=0; i<surface->num_buffers; i++) {
+ buffer = surface->buffers[i];
+
+ D_ASSUME( fusion_vector_is_empty( &buffer->allocs ) );
+
+ D_DEBUG_AT( Core_SurfacePool, " -> %p (%d)\n", allocation, i );
+ fusion_vector_add( &buffer->allocs, allocation );
+ fusion_vector_add( &pool->allocs, allocation );
+ }
+ }
+ else {
+ D_DEBUG_AT( Core_SurfacePool, " -> %p\n", allocation );
+ fusion_vector_add( &buffer->allocs, allocation );
+ fusion_vector_add( &pool->allocs, allocation );
+ }
+
+ direct_serial_init( &allocation->serial );
+
+ fusion_skirmish_dismiss( &pool->lock );
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ *ret_allocation = allocation;
+
+ return DFB_OK;
+
+error:
+ if (allocation->data)
+ SHFREE( pool->shmpool, allocation->data );
+
+ SHFREE( pool->shmpool, allocation );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_pool_deallocate( CoreSurfacePool *pool,
+ CoreSurfaceAllocation *allocation )
+{
+ DFBResult ret;
+ int i;
+ const SurfacePoolFuncs *funcs;
+ CoreSurfaceBuffer *buffer;
+ CoreSurface *surface;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p [%d], %p )\n", __FUNCTION__, pool, pool->pool_id, allocation );
+
+ D_ASSERT( pool == allocation->pool );
+
+ buffer = allocation->buffer;
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ funcs = get_funcs( pool );
+
+ D_ASSERT( funcs->DeallocateBuffer != NULL );
+
+ if (fusion_skirmish_prevail( &pool->lock ))
+ return DFB_FUSION;
+
+ ret = funcs->DeallocateBuffer( pool, pool->data, get_local(pool), allocation->buffer, allocation, allocation->data );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfacePool: Could not deallocate buffer!\n" );
+ fusion_skirmish_dismiss( &pool->lock );
+ return ret;
+ }
+
+ if (allocation->flags & CSALF_ONEFORALL) {
+ for (i=0; i<surface->num_buffers; i++)
+ remove_allocation( pool, surface->buffers[i], allocation );
+ }
+ else
+ remove_allocation( pool, buffer, allocation );
+
+ fusion_skirmish_dismiss( &pool->lock );
+
+ if (allocation->data)
+ SHFREE( pool->shmpool, allocation->data );
+
+ direct_serial_deinit( &allocation->serial );
+
+ D_MAGIC_CLEAR( allocation );
+
+ SHFREE( pool->shmpool, allocation );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_pool_displace( CoreSurfacePool *pool,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation **ret_allocation )
+{
+ DFBResult ret, ret_lock = DFB_OK;
+ int i, retries = 3;
+ CoreSurface *surface;
+ CoreSurfaceAllocation *allocation;
+ const SurfacePoolFuncs *funcs;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p [%d], %p )\n", __FUNCTION__, pool, pool->pool_id, buffer );
+
+ D_ASSERT( ret_allocation != NULL );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ funcs = get_funcs( pool );
+
+ if (fusion_skirmish_prevail( &pool->lock ))
+ return DFB_FUSION;
+
+ /* Check for integrated method to muck out "older" allocations for a new one */
+ if (funcs->MuckOut) {
+ ret = funcs->MuckOut( pool, pool->data, get_local(pool), buffer );
+ if (ret) {
+ fusion_skirmish_dismiss( &pool->lock );
+ return ret;
+ }
+ }
+ else {
+ /* Or take the generic approach via allocation list */
+ D_UNIMPLEMENTED();
+ }
+
+ /* FIXME: Solve potential dead lock, until then do a few retries... */
+fixme_retry:
+ fusion_vector_foreach (allocation, i, pool->allocs) {
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ if (allocation->flags & CSALF_MUCKOUT) {
+ CoreSurface *alloc_surface;
+ CoreSurfaceBuffer *alloc_buffer;
+
+ alloc_buffer = allocation->buffer;
+ D_MAGIC_ASSERT( alloc_buffer, CoreSurfaceBuffer );
+
+ alloc_surface = alloc_buffer->surface;
+ D_MAGIC_ASSERT( alloc_surface, CoreSurface );
+
+ D_DEBUG_AT( Core_SurfacePool, " <= %p %5dk, %lu\n",
+ allocation, allocation->size / 1024, allocation->offset );
+
+ /* FIXME: Solve potential dead lock, until then only try to lock... */
+ ret = dfb_surface_trylock( alloc_surface );
+ if (ret) {
+ D_WARN( "could not lock surface (%s)", DirectFBErrorString(ret) );
+ ret_lock = ret;
+ continue;
+ }
+
+ /* Ensure mucked out allocation is backed up in another pool */
+ ret = backup_allocation( pool, buffer, allocation );
+ if (ret) {
+ D_WARN( "could not backup allocation (%s)", DirectFBErrorString(ret) );
+ dfb_surface_unlock( alloc_surface );
+ goto error_cleanup;
+ }
+
+ /* Deallocate mucked out allocation */
+ dfb_surface_pool_deallocate( pool, allocation );
+ i--;
+
+ dfb_surface_unlock( alloc_surface );
+ }
+ }
+
+ /* FIXME: Solve potential dead lock, until then do a few retries... */
+ if (ret_lock) {
+ if (retries--)
+ goto fixme_retry;
+
+ ret = DFB_LOCKED;
+
+ goto error_cleanup;
+ }
+ else
+ ret = dfb_surface_pool_allocate( pool, buffer, ret_allocation );
+
+ fusion_skirmish_dismiss( &pool->lock );
+
+ return ret;
+
+
+error_cleanup:
+ fusion_vector_foreach (allocation, i, pool->allocs) {
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ if (allocation->flags & CSALF_MUCKOUT)
+ allocation->flags &= ~CSALF_MUCKOUT;
+ }
+
+ fusion_skirmish_dismiss( &pool->lock );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_pool_lock( CoreSurfacePool *pool,
+ CoreSurfaceAllocation *allocation,
+ CoreSurfaceBufferLock *lock )
+{
+ DFBResult ret;
+ const SurfacePoolFuncs *funcs;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ D_DEBUG_AT( Core_SurfPoolLock, "%s( %p [%d], %p )\n", __FUNCTION__, pool, pool->pool_id, allocation );
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+ CORE_SURFACE_BUFFER_LOCK_ASSERT( lock );
+ D_ASSERT( lock->buffer == NULL );
+
+ D_ASSERT( pool == allocation->pool );
+
+ funcs = get_funcs( pool );
+
+ D_ASSERT( funcs->Lock != NULL );
+
+ lock->allocation = allocation;
+ lock->buffer = allocation->buffer;
+
+ ret = funcs->Lock( pool, pool->data, get_local(pool), allocation, allocation->data, lock );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfacePool: Could not lock allocation!\n" );
+ dfb_surface_buffer_lock_reset( lock );
+ return ret;
+ }
+
+ CORE_SURFACE_BUFFER_LOCK_ASSERT( lock );
+ D_ASSERT( lock->buffer != NULL );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_pool_unlock( CoreSurfacePool *pool,
+ CoreSurfaceAllocation *allocation,
+ CoreSurfaceBufferLock *lock )
+{
+ DFBResult ret;
+ const SurfacePoolFuncs *funcs;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ D_DEBUG_AT( Core_SurfPoolLock, "%s( %p [%d], %p )\n", __FUNCTION__, pool, pool->pool_id, allocation );
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+ CORE_SURFACE_BUFFER_LOCK_ASSERT( lock );
+ D_ASSERT( lock->buffer != NULL );
+
+ D_ASSERT( pool == allocation->pool );
+
+ funcs = get_funcs( pool );
+
+ D_ASSERT( funcs->Unlock != NULL );
+
+ ret = funcs->Unlock( pool, pool->data, get_local(pool), allocation, allocation->data, lock );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfacePool: Could not unlock allocation!\n" );
+ return ret;
+ }
+
+ CORE_SURFACE_BUFFER_LOCK_ASSERT( lock );
+ D_ASSERT( lock->buffer != NULL );
+
+ dfb_surface_buffer_lock_reset( lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_pool_read( CoreSurfacePool *pool,
+ CoreSurfaceAllocation *allocation,
+ void *data,
+ int pitch,
+ const DFBRectangle *rect )
+{
+ DFBResult ret;
+ const SurfacePoolFuncs *funcs;
+ CoreSurface *surface;
+ DFBRectangle area;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ D_DEBUG_AT( Core_SurfPoolLock, "%s( %p [%d], %p )\n", __FUNCTION__, pool, pool->pool_id, allocation );
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+ D_ASSERT( data != NULL );
+ D_ASSERT( pitch >= 0 );
+ DFB_RECTANGLE_ASSERT_IF( rect );
+
+ D_ASSERT( pool == allocation->pool );
+
+ funcs = get_funcs( pool );
+ D_ASSERT( funcs != NULL );
+
+ if (!funcs->Read)
+ return DFB_UNSUPPORTED;
+
+ surface = allocation->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ area.x = 0;
+ area.y = 0;
+ area.w = surface->config.size.w;
+ area.h = surface->config.size.h;
+
+ if (rect && !dfb_rectangle_intersect( &area, rect ))
+ return DFB_INVAREA;
+
+ ret = funcs->Read( pool, pool->data, get_local(pool), allocation, allocation->data, data, pitch, &area );
+ if (ret)
+ D_DERROR( ret, "Core/SurfacePool: Could not read from allocation!\n" );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_pool_write( CoreSurfacePool *pool,
+ CoreSurfaceAllocation *allocation,
+ const void *data,
+ int pitch,
+ const DFBRectangle *rect )
+{
+ DFBResult ret;
+ const SurfacePoolFuncs *funcs;
+ CoreSurface *surface;
+ DFBRectangle area;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ D_DEBUG_AT( Core_SurfPoolLock, "%s( %p [%d], %p )\n", __FUNCTION__, pool, pool->pool_id, allocation );
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+ D_ASSERT( data != NULL );
+ D_ASSERT( pitch >= 0 );
+ DFB_RECTANGLE_ASSERT_IF( rect );
+
+ D_ASSERT( pool == allocation->pool );
+
+ funcs = get_funcs( pool );
+ D_ASSERT( funcs != NULL );
+
+ if (!funcs->Write)
+ return DFB_UNSUPPORTED;
+
+ surface = allocation->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ area.x = 0;
+ area.y = 0;
+ area.w = surface->config.size.w;
+ area.h = surface->config.size.h;
+
+ if (rect && !dfb_rectangle_intersect( &area, rect ))
+ return DFB_INVAREA;
+
+ ret = funcs->Write( pool, pool->data, get_local(pool), allocation, allocation->data, data, pitch, &area );
+ if (ret)
+ D_DERROR( ret, "Core/SurfacePool: Could not write to allocation!\n" );
+
+ return ret;
+}
+
+DFBResult
+dfb_surface_pool_enumerate ( CoreSurfacePool *pool,
+ CoreSurfaceAllocCallback callback,
+ void *ctx )
+{
+ int i;
+ CoreSurfaceAllocation *allocation;
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p, %p, %p )\n", __FUNCTION__, pool, callback, ctx );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( callback != NULL );
+
+ fusion_vector_foreach (allocation, i, pool->allocs) {
+ if (callback( allocation, ctx ) == DFENUM_CANCEL)
+ break;
+ }
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+static DFBResult
+init_pool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ const SurfacePoolFuncs *funcs )
+{
+ DFBResult ret;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( funcs != NULL );
+ D_ASSERT( funcs->InitPool != NULL );
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p, %p )\n", __FUNCTION__, pool, funcs );
+
+ if (funcs->PoolDataSize)
+ pool->pool_data_size = funcs->PoolDataSize();
+
+ if (funcs->PoolLocalDataSize)
+ pool->pool_local_data_size = funcs->PoolLocalDataSize();
+
+ if (funcs->AllocationDataSize)
+ pool->alloc_data_size = funcs->AllocationDataSize();
+
+ /* Allocate shared pool data. */
+ if (pool->pool_data_size) {
+ pool->data = SHCALLOC( pool->shmpool, 1, pool->pool_data_size );
+ if (!pool->data)
+ return D_OOSHM();
+ }
+
+ /* Allocate local pool data. */
+ if (pool->pool_local_data_size &&
+ !(pool_locals[pool->pool_id] = D_CALLOC( 1, pool->pool_local_data_size )))
+ {
+ SHFREE( pool->shmpool, pool->data );
+ return D_OOM();
+ }
+
+ fusion_vector_init( &pool->allocs, 4, pool->shmpool );
+
+ ret = funcs->InitPool( core, pool, pool->data, get_local(pool), dfb_system_data(), &pool->desc );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfacePool: Initializing '%s' failed!\n", pool->desc.name );
+
+ if (pool_locals[pool->pool_id]) {
+ D_FREE( pool_locals[pool->pool_id] );
+ pool_locals[pool->pool_id] = NULL;
+ }
+ if (pool->data) {
+ SHFREE( pool->shmpool, pool->data );
+ pool->data = NULL;
+ }
+ return ret;
+ }
+
+ fusion_skirmish_init( &pool->lock, pool->desc.name, dfb_core_world(core) );
+
+ return DFB_OK;
+}
+
+static void
+insert_pool_local( CoreSurfacePool *pool )
+{
+ int i, n;
+
+ for (i=0; i<pool_count-1; i++) {
+ D_ASSERT( pool_order[i] >= 0 );
+ D_ASSERT( pool_order[i] < pool_count-1 );
+
+ D_MAGIC_ASSERT( pool_array[pool_order[i]], CoreSurfacePool );
+
+ if (pool_array[pool_order[i]]->desc.priority < pool->desc.priority)
+ break;
+ }
+
+ for (n=pool_count-1; n>i; n--) {
+ D_ASSERT( pool_order[n-1] >= 0 );
+ D_ASSERT( pool_order[n-1] < pool_count-1 );
+
+ D_MAGIC_ASSERT( pool_array[pool_order[n-1]], CoreSurfacePool );
+
+ pool_order[n] = pool_order[n-1];
+ }
+
+ pool_order[n] = pool_count - 1;
+
+#if D_DEBUG_ENABLED
+ for (i=0; i<pool_count; i++) {
+ D_DEBUG_AT( Core_SurfacePool, " %c> [%d] %p - '%s' [%d] (%d), %p\n",
+ (i == n) ? '=' : '-', i, pool_array[pool_order[i]], pool_array[pool_order[i]]->desc.name,
+ pool_array[pool_order[i]]->pool_id, pool_array[pool_order[i]]->desc.priority,
+ pool_funcs[pool_order[i]] );
+ D_ASSERT( pool_order[i] == pool_array[pool_order[i]]->pool_id );
+ }
+#endif
+}
+
+static void
+remove_pool_local( CoreSurfacePoolID pool_id )
+{
+ int i;
+
+ /* Free local pool data. */
+ if (pool_locals[pool_id]) {
+ D_FREE( pool_locals[pool_id] );
+ pool_locals[pool_id] = NULL;
+ }
+
+ /* Erase entries of the pool. */
+ pool_array[pool_id] = NULL;
+ pool_funcs[pool_id] = NULL;
+
+ while (pool_count > 0 && !pool_array[pool_count-1]) {
+ pool_count--;
+
+ for (i=0; i<pool_count; i++) {
+ if (pool_order[i] == pool_count) {
+ direct_memmove( &pool_order[i], &pool_order[i+1], sizeof(pool_order[0]) * (pool_count - i) );
+ break;
+ }
+ }
+ }
+}
+
+/**********************************************************************************************************************/
+
+static void
+remove_allocation( CoreSurfacePool *pool,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation )
+{
+ int index_buffer;
+ int index_pool;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+ D_MAGIC_ASSERT( buffer->surface, CoreSurface );
+ FUSION_SKIRMISH_ASSERT( &buffer->surface->lock );
+ FUSION_SKIRMISH_ASSERT( &pool->lock );
+ D_ASSERT( pool == allocation->pool );
+
+ /* Lookup indices within vectors */
+ index_buffer = fusion_vector_index_of( &buffer->allocs, allocation );
+ index_pool = fusion_vector_index_of( &pool->allocs, allocation );
+
+ D_ASSERT( index_buffer >= 0 );
+ D_ASSERT( index_pool >= 0 );
+
+ /* Remove allocation from buffer and pool */
+ fusion_vector_remove( &buffer->allocs, index_buffer );
+ fusion_vector_remove( &pool->allocs, index_pool );
+
+ /* Update 'written' allocation pointer of buffer */
+ if (buffer->written == allocation) {
+ /* Reset pointer first */
+ buffer->written = NULL;
+
+ /* Iterate through remaining allocations */
+ fusion_vector_foreach (allocation, index_buffer, buffer->allocs) {
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ /* Check if allocation is up to date and set it as 'written' allocation */
+ if (direct_serial_check( &allocation->serial, &buffer->serial )) {
+ buffer->written = allocation;
+ break;
+ }
+ }
+ }
+
+ /* Reset 'read' allocation pointer of buffer */
+ if (buffer->read == allocation)
+ buffer->read = NULL;
+}
+
+static DFBResult
+backup_allocation( CoreSurfacePool *pool,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation )
+{
+ DFBResult ret = DFB_OK;
+ int i;
+ CoreSurfaceAllocation *backup = NULL;
+
+ D_DEBUG_AT( Core_SurfacePool, "%s( %p, %p )\n", __FUNCTION__, pool, allocation );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+ D_MAGIC_ASSERT( buffer->surface, CoreSurface );
+ FUSION_SKIRMISH_ASSERT( &buffer->surface->lock );
+ FUSION_SKIRMISH_ASSERT( &pool->lock );
+ D_ASSERT( pool == allocation->pool );
+
+ /* Check if allocation is the only up to date (requiring a backup) */
+ if (direct_serial_check( &allocation->serial, &buffer->serial )) {
+ CoreSurfacePool *backup_pool = pool->backup;
+
+ /* First check if any of the existing allocations is up to date */
+ fusion_vector_foreach (backup, i, buffer->allocs) {
+ D_MAGIC_ASSERT( backup, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( backup->pool, CoreSurfacePool );
+
+ if (backup->pool != pool && direct_serial_check( &backup->serial, &buffer->serial )) {
+ D_DEBUG_AT( Core_SurfacePool, " -> up to date in '%s'\n", backup->pool->desc.name );
+ return DFB_OK;
+ }
+ }
+
+ /* Try to update one of the existing allocations */
+ fusion_vector_foreach (backup, i, buffer->allocs) {
+ D_MAGIC_ASSERT( backup, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( backup->pool, CoreSurfacePool );
+
+ if (backup->pool != pool && dfb_surface_allocation_update( backup, CSAF_NONE ) == DFB_OK) {
+ D_DEBUG_AT( Core_SurfacePool, " -> updated in '%s'\n", backup->pool->desc.name );
+ return DFB_OK;
+ }
+ }
+
+ /* Try the designated backup pool and theirs if failing */
+ while (backup_pool) {
+ D_MAGIC_ASSERT( backup_pool, CoreSurfacePool );
+
+ D_DEBUG_AT( Core_SurfacePool, " -> allocating in '%s'\n", backup_pool->desc.name );
+
+ /* Allocate in backup pool */
+ ret = dfb_surface_pool_allocate( backup_pool, buffer, &backup );
+ if (ret == DFB_OK) {
+ /* Update new allocation */
+ ret = dfb_surface_allocation_update( backup, CSAF_NONE );
+ if (ret) {
+ D_DEBUG_AT( Core_SurfacePool, " -> update failed! (%s)\n", DirectFBErrorString(ret) );
+ dfb_surface_pool_deallocate( backup_pool, backup );
+ backup = NULL;
+ }
+ else
+ return DFB_OK;
+ }
+ else
+ D_DEBUG_AT( Core_SurfacePool, " -> allocation failed! (%s)\n", DirectFBErrorString(ret) );
+
+ backup_pool = backup_pool->backup;
+ }
+ }
+ else
+ D_DEBUG_AT( Core_SurfacePool, " -> not up to date anyhow\n" );
+
+ return ret;
+}
+
diff --git a/Source/DirectFB/src/core/surface_pool.h b/Source/DirectFB/src/core/surface_pool.h
new file mode 100755
index 0000000..fc049e0
--- /dev/null
+++ b/Source/DirectFB/src/core/surface_pool.h
@@ -0,0 +1,272 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__SURFACE_POOL_H__
+#define __CORE__SURFACE_POOL_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+
+
+typedef enum {
+ CSPCAPS_NONE = 0x00000000,
+
+ CSPCAPS_PHYSICAL = 0x00000001, /* pool provides physical address to buffer */
+ CSPCAPS_VIRTUAL = 0x00000002, /* pool provides virtual address to buffer */
+
+ CSPCAPS_ALL = 0x00000003
+} CoreSurfacePoolCapabilities;
+
+typedef enum {
+ CSPP_DEFAULT,
+ CSPP_PREFERED,
+ CSPP_ULTIMATE
+} CoreSurfacePoolPriority;
+
+/*
+ * Increase this number when changes result in binary incompatibility!
+ */
+#define DFB_SURFACE_POOL_ABI_VERSION 1
+
+#define DFB_SURFACE_POOL_DESC_NAME_LENGTH 44
+
+
+typedef struct {
+ CoreSurfacePoolCapabilities caps;
+ CoreSurfaceAccessFlags access[_CSAID_NUM];
+ CoreSurfaceTypeFlags types;
+ CoreSurfacePoolPriority priority;
+ char name[DFB_SURFACE_POOL_DESC_NAME_LENGTH];
+ unsigned long size;
+} CoreSurfacePoolDescription;
+
+
+typedef struct {
+ int (*PoolDataSize)( void );
+ int (*PoolLocalDataSize)( void );
+ int (*AllocationDataSize)( void );
+
+ /*
+ * Pool init/destroy
+ */
+ DFBResult (*InitPool) ( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data,
+ CoreSurfacePoolDescription *ret_desc );
+
+ DFBResult (*JoinPool) ( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data );
+
+ DFBResult (*DestroyPool)( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local );
+
+ DFBResult (*LeavePool) ( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local );
+
+
+
+ DFBResult (*TestConfig) ( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ const CoreSurfaceConfig *config );
+ /*
+ * Buffer management
+ */
+ DFBResult (*AllocateBuffer) ( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data );
+
+ DFBResult (*DeallocateBuffer)( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data );
+
+ /*
+ * Locking
+ */
+ DFBResult (*Lock) ( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock );
+
+ DFBResult (*Unlock)( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock );
+
+ /*
+ * Read/write
+ */
+ DFBResult (*Read) ( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ void *destination,
+ int pitch,
+ const DFBRectangle *rect );
+
+ DFBResult (*Write) ( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ const void *source,
+ int pitch,
+ const DFBRectangle *rect );
+
+ /*
+ * Muck out
+ */
+ DFBResult (*MuckOut) ( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer );
+} SurfacePoolFuncs;
+
+
+struct __DFB_CoreSurfacePool {
+ int magic;
+
+ FusionSkirmish lock;
+
+ CoreSurfacePoolID pool_id;
+
+ CoreSurfacePoolDescription desc;
+
+ int pool_data_size;
+ int pool_local_data_size;
+ int alloc_data_size;
+
+ void *data;
+
+ FusionVector allocs;
+
+ FusionSHMPoolShared *shmpool;
+
+ CoreSurfacePool *backup;
+};
+
+
+typedef DFBEnumerationResult (*CoreSurfacePoolCallback)( CoreSurfacePool *pool,
+ void *ctx );
+
+typedef DFBEnumerationResult (*CoreSurfaceAllocCallback)( CoreSurfaceAllocation *allocation,
+ void *ctx );
+
+
+
+DFBResult dfb_surface_pools_negotiate( CoreSurfaceBuffer *buffer,
+ CoreSurfaceAccessorID accessor,
+ CoreSurfaceAccessFlags access,
+ CoreSurfacePool **ret_pools,
+ unsigned int max_pools,
+ unsigned int *ret_num );
+
+DFBResult dfb_surface_pools_enumerate( CoreSurfacePoolCallback callback,
+ void *ctx );
+
+DFBResult dfb_surface_pools_allocate ( CoreSurfaceBuffer *buffer,
+ CoreSurfaceAccessorID accessor,
+ CoreSurfaceAccessFlags access,
+ CoreSurfaceAllocation **ret_allocation );
+
+
+DFBResult dfb_surface_pool_initialize( CoreDFB *core,
+ const SurfacePoolFuncs *funcs,
+ CoreSurfacePool **ret_pool );
+
+DFBResult dfb_surface_pool_join ( CoreDFB *core,
+ CoreSurfacePool *pool,
+ const SurfacePoolFuncs *funcs );
+
+DFBResult dfb_surface_pool_destroy ( CoreSurfacePool *pool );
+
+DFBResult dfb_surface_pool_leave ( CoreSurfacePool *pool );
+
+
+
+DFBResult dfb_surface_pool_allocate ( CoreSurfacePool *pool,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation **ret_allocation );
+
+DFBResult dfb_surface_pool_deallocate( CoreSurfacePool *pool,
+ CoreSurfaceAllocation *allocation );
+
+DFBResult dfb_surface_pool_displace ( CoreSurfacePool *pool,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation **ret_allocation );
+
+DFBResult dfb_surface_pool_lock ( CoreSurfacePool *pool,
+ CoreSurfaceAllocation *allocation,
+ CoreSurfaceBufferLock *lock );
+
+DFBResult dfb_surface_pool_unlock ( CoreSurfacePool *pool,
+ CoreSurfaceAllocation *allocation,
+ CoreSurfaceBufferLock *lock );
+
+DFBResult dfb_surface_pool_read ( CoreSurfacePool *pool,
+ CoreSurfaceAllocation *allocation,
+ void *data,
+ int pitch,
+ const DFBRectangle *rect );
+
+DFBResult dfb_surface_pool_write ( CoreSurfacePool *pool,
+ CoreSurfaceAllocation *allocation,
+ const void *data,
+ int pitch,
+ const DFBRectangle *rect );
+
+DFBResult dfb_surface_pool_enumerate ( CoreSurfacePool *pool,
+ CoreSurfaceAllocCallback callback,
+ void *ctx );
+
+
+#endif
+
diff --git a/Source/DirectFB/src/core/surface_pool_bridge.c b/Source/DirectFB/src/core/surface_pool_bridge.c
new file mode 100755
index 0000000..244ca2d
--- /dev/null
+++ b/Source/DirectFB/src/core/surface_pool_bridge.c
@@ -0,0 +1,531 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#include <directfb.h>
+#include <directfb_util.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+
+#include <core/surface_buffer.h>
+#include <core/surface_pool.h>
+#include <core/surface_pool_bridge.h>
+#include <core/system.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+
+D_DEBUG_DOMAIN( Core_SurfPoolBridge, "Core/SurfPoolBridge", "DirectFB Core Surface Pool Bridge" );
+
+/**********************************************************************************************************************/
+
+static const SurfacePoolBridgeFuncs *bridge_funcs[MAX_SURFACE_POOL_BRIDGES];
+static void *bridge_locals[MAX_SURFACE_POOL_BRIDGES];
+static int bridge_count;
+static CoreSurfacePoolBridge *bridge_array[MAX_SURFACE_POOL_BRIDGES];
+
+/**********************************************************************************************************************/
+
+static inline const SurfacePoolBridgeFuncs *
+get_funcs( const CoreSurfacePoolBridge *bridge )
+{
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ D_ASSERT( bridge->bridge_id >= 0 );
+ D_ASSERT( bridge->bridge_id < MAX_SURFACE_POOL_BRIDGES );
+ D_ASSERT( bridge_funcs[bridge->bridge_id] != NULL );
+
+ /* Return function table of the bridge. */
+ return bridge_funcs[bridge->bridge_id];
+}
+
+static inline void *
+get_local( const CoreSurfacePoolBridge *bridge )
+{
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ D_ASSERT( bridge->bridge_id >= 0 );
+ D_ASSERT( bridge->bridge_id < MAX_SURFACE_POOL_BRIDGES );
+
+ /* Return local data of the bridge. */
+ return bridge_locals[bridge->bridge_id];
+}
+
+/**********************************************************************************************************************/
+
+static DFBResult init_bridge( CoreDFB *core,
+ CoreSurfacePoolBridge *bridge,
+ const SurfacePoolBridgeFuncs *funcs,
+ void *context );
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_surface_pool_bridge_initialize( CoreDFB *core,
+ const SurfacePoolBridgeFuncs *funcs,
+ void *context,
+ CoreSurfacePoolBridge **ret_bridge )
+{
+ DFBResult ret;
+ CoreSurfacePoolBridge *bridge;
+ FusionSHMPoolShared *shmpool;
+
+ D_DEBUG_AT( Core_SurfPoolBridge, "%s( %p, %p )\n", __FUNCTION__, funcs, context );
+
+ D_ASSERT( core != NULL );
+ D_ASSERT( funcs != NULL );
+ D_ASSERT( ret_bridge != NULL );
+
+ /* Check against bridge limit. */
+ if (bridge_count == MAX_SURFACE_POOL_BRIDGES) {
+ D_ERROR( "Core/SurfacePoolBridge: Maximum number of bridges (%d) reached!\n", MAX_SURFACE_POOL_BRIDGES );
+ return DFB_LIMITEXCEEDED;
+ }
+
+ D_ASSERT( bridge_funcs[bridge_count] == NULL );
+
+ shmpool = dfb_core_shmpool( core );
+
+ /* Allocate bridge structure. */
+ bridge = SHCALLOC( shmpool, 1, sizeof(CoreSurfacePoolBridge) );
+ if (!bridge)
+ return D_OOSHM();
+
+ /* Assign a bridge ID. */
+ bridge->bridge_id = bridge_count++;
+
+ /* Remember shared memory pool. */
+ bridge->shmpool = shmpool;
+
+ /* Set function table of the bridge. */
+ bridge_funcs[bridge->bridge_id] = funcs;
+
+ /* Add to global bridge list. */
+ bridge_array[bridge->bridge_id] = bridge;
+
+ D_MAGIC_SET( bridge, CoreSurfacePoolBridge );
+
+ ret = init_bridge( core, bridge, funcs, context );
+ if (ret) {
+ bridge_count--;
+ D_MAGIC_CLEAR( bridge );
+ SHFREE( shmpool, bridge );
+ return ret;
+ }
+
+ /* Return the new bridge. */
+ *ret_bridge = bridge;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_pool_bridge_join( CoreDFB *core,
+ CoreSurfacePoolBridge *bridge,
+ const SurfacePoolBridgeFuncs *funcs,
+ void *context )
+{
+ DFBResult ret;
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ D_DEBUG_AT( Core_SurfPoolBridge, "%s( %p [%d], %p, %p )\n", __FUNCTION__, bridge, bridge->bridge_id, funcs, context );
+
+ D_ASSERT( core != NULL );
+ D_ASSERT( funcs != NULL );
+
+ D_ASSERT( bridge->bridge_id < MAX_SURFACE_POOL_BRIDGES );
+ D_ASSERT( bridge->bridge_id == bridge_count );
+ D_ASSERT( bridge_funcs[bridge->bridge_id] == NULL );
+
+ /* Enforce same order as initialization to be used during join. */
+ if (bridge->bridge_id != bridge_count) {
+ D_ERROR( "Core/SurfacePoolBridge: Wrong order of joining bridges, got %d, should be %d!\n",
+ bridge->bridge_id, bridge_count );
+ return DFB_BUG;
+ }
+
+ /* Allocate local bridge data. */
+ if (bridge->bridge_local_data_size &&
+ !(bridge_locals[bridge->bridge_id] = D_CALLOC( 1, bridge->bridge_local_data_size )))
+ return D_OOM();
+
+ /* Set function table of the bridge. */
+ bridge_funcs[bridge->bridge_id] = funcs;
+
+ /* Add to global bridge list. */
+ bridge_array[bridge->bridge_id] = bridge;
+
+ /* Adjust bridge count. */
+ if (bridge_count < bridge->bridge_id + 1)
+ bridge_count = bridge->bridge_id + 1;
+
+ funcs = get_funcs( bridge );
+
+ if (funcs->JoinPoolBridge) {
+ ret = funcs->JoinPoolBridge( core, bridge, bridge->data, get_local(bridge), context );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfacePoolBridge: Joining '%s' failed!\n", bridge->desc.name );
+
+ if (bridge_locals[bridge->bridge_id]) {
+ D_FREE( bridge_locals[bridge->bridge_id] );
+ bridge_locals[bridge->bridge_id] = NULL;
+ }
+
+ bridge_array[bridge->bridge_id] = NULL;
+ bridge_funcs[bridge->bridge_id] = NULL;
+
+ bridge_count--;
+
+ return ret;
+ }
+ }
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_pool_bridge_destroy( CoreSurfacePoolBridge *bridge )
+{
+ CoreSurfacePoolBridgeID bridge_id;
+ const SurfacePoolBridgeFuncs *funcs;
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ bridge_id = bridge->bridge_id;
+
+ D_DEBUG_AT( Core_SurfPoolBridge, "%s( %p, '%s' [%d] )\n", __FUNCTION__, bridge, bridge->desc.name, bridge_id );
+
+ D_ASSERT( bridge->bridge_id >= 0 );
+ D_ASSERT( bridge_id < MAX_SURFACE_POOL_BRIDGES );
+ D_ASSERT( bridge_array[bridge_id] == bridge );
+
+ funcs = get_funcs( bridge );
+
+ if (funcs->DestroyPoolBridge)
+ funcs->DestroyPoolBridge( bridge, bridge->data, get_local(bridge) );
+
+ /* Free shared bridge data. */
+ if (bridge->data)
+ SHFREE( bridge->shmpool, bridge->data );
+
+ /* Free local bridge data. */
+ if (bridge_locals[bridge_id])
+ D_FREE( bridge_locals[bridge_id] );
+
+ /* Remove from arrays. */
+ bridge_array[bridge_id] = NULL;
+ bridge_funcs[bridge_id] = NULL;
+ bridge_locals[bridge_id] = NULL;
+
+ fusion_skirmish_destroy( &bridge->lock );
+
+ D_MAGIC_CLEAR( bridge );
+
+ SHFREE( bridge->shmpool, bridge );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_surface_pool_bridge_leave( CoreSurfacePoolBridge *bridge )
+{
+ CoreSurfacePoolBridgeID bridge_id;
+ const SurfacePoolBridgeFuncs *funcs;
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ bridge_id = bridge->bridge_id;
+
+ D_DEBUG_AT( Core_SurfPoolBridge, "%s( %p, '%s' [%d] )\n", __FUNCTION__, bridge, bridge->desc.name, bridge_id );
+
+ D_ASSERT( bridge->bridge_id >= 0 );
+ D_ASSERT( bridge_id < MAX_SURFACE_POOL_BRIDGES );
+ D_ASSERT( bridge_array[bridge_id] == bridge );
+
+ funcs = get_funcs( bridge );
+
+ if (funcs->LeavePoolBridge)
+ funcs->LeavePoolBridge( bridge, bridge->data, get_local(bridge) );
+
+ /* Free local bridge data. */
+ if (bridge_locals[bridge_id])
+ D_FREE( bridge_locals[bridge_id] );
+
+ /* Remove from arrays. */
+ bridge_array[bridge_id] = NULL;
+ bridge_funcs[bridge_id] = NULL;
+ bridge_locals[bridge_id] = NULL;
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_surface_pool_bridges_enumerate( CoreSurfacePoolBridgeCallback callback,
+ void *ctx )
+{
+ int i;
+
+ D_ASSERT( callback != NULL );
+
+ D_DEBUG_AT( Core_SurfPoolBridge, "%s( %p, %p )\n", __FUNCTION__, callback, ctx );
+
+ for (i=0; i<bridge_count; i++) {
+ CoreSurfacePoolBridge *bridge = bridge_array[i];
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ if (callback( bridge, ctx ) == DFENUM_CANCEL)
+ break;
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+allocate_transfer( CoreSurfacePoolBridge *bridge,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *from,
+ CoreSurfaceAllocation *to,
+ const DFBRectangle *rects,
+ unsigned int num_rects,
+ CoreSurfacePoolTransfer **ret_transfer )
+{
+ CoreSurfacePoolTransfer *transfer;
+ unsigned int alloc_size;
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ CORE_SURFACE_ALLOCATION_ASSERT( from );
+ CORE_SURFACE_ALLOCATION_ASSERT( to );
+ D_ASSERT( rects != NULL );
+ D_ASSERT( num_rects > 0 );
+ D_ASSERT( ret_transfer != NULL );
+
+ alloc_size = sizeof(CoreSurfacePoolTransfer) + num_rects * sizeof(DFBRectangle) + bridge->transfer_data_size;
+
+ transfer = SHCALLOC( bridge->shmpool, 1, alloc_size );
+ if (!transfer)
+ return D_OOSHM();
+
+ transfer->bridge = bridge;
+ transfer->buffer = buffer;
+ transfer->from = from;
+ transfer->to = to;
+
+ transfer->rects = (DFBRectangle*)(transfer + 1);
+
+ if (bridge->transfer_data_size)
+ transfer->data = transfer->rects + num_rects;
+
+ transfer->num_rects = num_rects;
+
+ direct_memcpy( transfer->rects, rects, num_rects * sizeof(DFBRectangle) );
+
+ D_MAGIC_SET( transfer, CoreSurfacePoolTransfer );
+
+ *ret_transfer = transfer;
+
+ return DFB_OK;
+}
+
+static void
+deallocate_transfer( CoreSurfacePoolTransfer *transfer )
+{
+ CoreSurfacePoolBridge *bridge;
+
+ D_MAGIC_ASSERT( transfer, CoreSurfacePoolTransfer );
+
+ bridge = transfer->bridge;
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ D_MAGIC_CLEAR( transfer );
+
+ SHFREE( bridge->shmpool, transfer );
+}
+
+DFBResult
+dfb_surface_pool_bridges_transfer( CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *from,
+ CoreSurfaceAllocation *to,
+ const DFBRectangle *rects,
+ unsigned int num_rects )
+{
+ DFBResult ret;
+ int i;
+ DFBRectangle rect;
+ CoreSurface *surface;
+ CoreSurfacePoolBridge *bridge = NULL;
+ const SurfacePoolBridgeFuncs *funcs;
+ CoreSurfacePoolTransfer *transfer;
+
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ CORE_SURFACE_ALLOCATION_ASSERT( from );
+ CORE_SURFACE_ALLOCATION_ASSERT( to );
+ D_ASSERT( rects != NULL || num_rects == 0 );
+ D_ASSERT( num_rects > 0 || rects == NULL );
+
+ D_DEBUG_AT( Core_SurfPoolBridge, "%s( %p [%s], %p -> %p, %d rects )\n", __FUNCTION__,
+ buffer, dfb_pixelformat_name( buffer->format ), from, to, num_rects );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+ FUSION_SKIRMISH_ASSERT( &surface->lock );
+
+ if (!rects) {
+ rect.x = rect.y = 0;
+ rect.w = surface->config.size.w;
+ rect.h = surface->config.size.h;
+
+ rects = &rect;
+ num_rects = 1;
+ }
+
+ for (i=0; i<bridge_count; i++) {
+ bridge = bridge_array[i];
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ funcs = get_funcs( bridge );
+ D_ASSERT( funcs->CheckTransfer != NULL );
+
+ ret = funcs->CheckTransfer( bridge, bridge->data, get_local(bridge), buffer, from, to );
+ if (ret)
+ bridge = NULL;
+ else
+ break;
+ }
+
+ if (!bridge)
+ return DFB_UNSUPPORTED;
+
+ D_DEBUG_AT( Core_SurfPoolBridge, " -> using '%s'\n", bridge->desc.name );
+
+ ret = allocate_transfer( bridge, buffer, from, to, rects, num_rects, &transfer );
+ if (ret)
+ return ret;
+
+ D_ASSERT( funcs->StartTransfer != NULL );
+
+ D_DEBUG_AT( Core_SurfPoolBridge, " -> start...\n" );
+
+ ret = funcs->StartTransfer( bridge, bridge->data, get_local(bridge), transfer, transfer->data );
+ if (ret)
+ D_DERROR( ret, "Core/SurfacePoolBridge: Starting transfer via '%s' failed!\n", bridge->desc.name );
+ else if (funcs->FinishTransfer) {
+ D_DEBUG_AT( Core_SurfPoolBridge, " -> finish...\n" );
+
+ ret = funcs->FinishTransfer( bridge, bridge->data, get_local(bridge), transfer, transfer->data );
+ if (ret)
+ D_DERROR( ret, "Core/SurfacePoolBridge: Finishing transfer via '%s' failed!\n", bridge->desc.name );
+ }
+
+ D_DEBUG_AT( Core_SurfPoolBridge, " => %s\n", DirectResultString(ret) );
+
+ deallocate_transfer( transfer );
+
+ return ret;
+}
+
+/**********************************************************************************************************************/
+
+static DFBResult
+init_bridge( CoreDFB *core,
+ CoreSurfacePoolBridge *bridge,
+ const SurfacePoolBridgeFuncs *funcs,
+ void *context )
+{
+ DFBResult ret;
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+ D_ASSERT( funcs != NULL );
+ D_ASSERT( funcs->InitPoolBridge != NULL );
+
+ D_DEBUG_AT( Core_SurfPoolBridge, "%s( %p, %p )\n", __FUNCTION__, bridge, funcs );
+
+ if (funcs->PoolBridgeDataSize)
+ bridge->bridge_data_size = funcs->PoolBridgeDataSize();
+
+ if (funcs->PoolBridgeLocalDataSize)
+ bridge->bridge_local_data_size = funcs->PoolBridgeLocalDataSize();
+
+ if (funcs->PoolTransferDataSize)
+ bridge->transfer_data_size = funcs->PoolTransferDataSize();
+
+ /* Allocate shared bridge data. */
+ if (bridge->bridge_data_size) {
+ bridge->data = SHCALLOC( bridge->shmpool, 1, bridge->bridge_data_size );
+ if (!bridge->data)
+ return D_OOSHM();
+ }
+
+ /* Allocate local bridge data. */
+ if (bridge->bridge_local_data_size &&
+ !(bridge_locals[bridge->bridge_id] = D_CALLOC( 1, bridge->bridge_local_data_size )))
+ {
+ SHFREE( bridge->shmpool, bridge->data );
+ return D_OOM();
+ }
+
+ ret = funcs->InitPoolBridge( core, bridge, bridge->data, get_local(bridge), context, &bridge->desc );
+ if (ret) {
+ D_DERROR( ret, "Core/SurfacePoolBridge: Initializing '%s' failed!\n", bridge->desc.name );
+
+ if (bridge_locals[bridge->bridge_id]) {
+ D_FREE( bridge_locals[bridge->bridge_id] );
+ bridge_locals[bridge->bridge_id] = NULL;
+ }
+
+ if (bridge->data) {
+ SHFREE( bridge->shmpool, bridge->data );
+ bridge->data = NULL;
+ }
+
+ bridge_array[bridge->bridge_id] = NULL;
+ bridge_funcs[bridge->bridge_id] = NULL;
+
+ return ret;
+ }
+
+ fusion_skirmish_init( &bridge->lock, bridge->desc.name, dfb_core_world(core) );
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/core/surface_pool_bridge.h b/Source/DirectFB/src/core/surface_pool_bridge.h
new file mode 100755
index 0000000..8fb6dda
--- /dev/null
+++ b/Source/DirectFB/src/core/surface_pool_bridge.h
@@ -0,0 +1,187 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__SURFACE_POOL_BRIDGE_H__
+#define __CORE__SURFACE_POOL_BRIDGE_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+
+
+typedef enum {
+ CSPBCAPS_NONE = 0x00000000,
+
+ CSPBCAPS_ALL = 0x00000000
+} CoreSurfacePoolBridgeCapabilities;
+
+/*
+ * Increase this number when changes result in binary incompatibility!
+ */
+#define DFB_SURFACE_POOL_BRIDGE_ABI_VERSION 1
+
+#define DFB_SURFACE_POOL_BRIDGE_DESC_NAME_LENGTH 44
+
+
+typedef struct {
+ CoreSurfacePoolBridgeCapabilities caps;
+ char name[DFB_SURFACE_POOL_BRIDGE_DESC_NAME_LENGTH];
+} CoreSurfacePoolBridgeDescription;
+
+
+typedef struct {
+ int (*PoolBridgeDataSize)( void );
+ int (*PoolBridgeLocalDataSize)( void );
+
+ int (*PoolTransferDataSize)( void );
+
+ /*
+ * Bridge init/destroy
+ */
+ DFBResult (*InitPoolBridge) ( CoreDFB *core,
+ CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ void *context,
+ CoreSurfacePoolBridgeDescription *ret_desc );
+
+ DFBResult (*JoinPoolBridge) ( CoreDFB *core,
+ CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ void *context );
+
+ DFBResult (*DestroyPoolBridge)( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local );
+
+ DFBResult (*LeavePoolBridge) ( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local );
+
+
+ /*
+ * Probe
+ */
+ DFBResult (*CheckTransfer) ( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *from,
+ CoreSurfaceAllocation *to );
+
+ /*
+ * Transfer
+ */
+ DFBResult (*StartTransfer) ( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ CoreSurfacePoolTransfer *transfer,
+ void *transfer_data );
+
+ DFBResult (*FinishTransfer) ( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ CoreSurfacePoolTransfer *transfer,
+ void *transfer_data );
+} SurfacePoolBridgeFuncs;
+
+
+struct __DFB_CoreSurfacePoolBridge {
+ int magic;
+
+ FusionSkirmish lock;
+
+ CoreSurfacePoolBridgeID bridge_id;
+
+ CoreSurfacePoolBridgeDescription desc;
+
+ int bridge_data_size;
+ int bridge_local_data_size;
+ int transfer_data_size;
+
+ void *data;
+
+ FusionSHMPoolShared *shmpool;
+
+ DirectLink *transfers;
+};
+
+struct __DFB_CoreSurfacePoolTransfer {
+ DirectLink link;
+
+ int magic;
+
+ CoreSurfacePoolBridge *bridge;
+
+ CoreSurfaceBuffer *buffer;
+ CoreSurfaceAllocation *from;
+ CoreSurfaceAllocation *to;
+
+ DFBRectangle *rects;
+ unsigned int num_rects;
+
+ void *data;
+};
+
+
+typedef DFBEnumerationResult (*CoreSurfacePoolBridgeCallback)( CoreSurfacePoolBridge *bridge,
+ void *ctx );
+
+
+
+DFBResult dfb_surface_pool_bridges_enumerate( CoreSurfacePoolBridgeCallback callback,
+ void *ctx );
+
+DFBResult dfb_surface_pool_bridges_transfer ( CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *from,
+ CoreSurfaceAllocation *to,
+ const DFBRectangle *rects,
+ unsigned int num_rects );
+
+
+DFBResult dfb_surface_pool_bridge_initialize( CoreDFB *core,
+ const SurfacePoolBridgeFuncs *funcs,
+ void *context,
+ CoreSurfacePoolBridge **ret_bridge );
+
+DFBResult dfb_surface_pool_bridge_join ( CoreDFB *core,
+ CoreSurfacePoolBridge *pool,
+ const SurfacePoolBridgeFuncs *funcs,
+ void *context );
+
+DFBResult dfb_surface_pool_bridge_destroy ( CoreSurfacePoolBridge *bridge );
+
+DFBResult dfb_surface_pool_bridge_leave ( CoreSurfacePoolBridge *bridge );
+
+
+#endif
+
diff --git a/Source/DirectFB/src/core/system.c b/Source/DirectFB/src/core/system.c
new file mode 100755
index 0000000..6a78eb0
--- /dev/null
+++ b/Source/DirectFB/src/core/system.c
@@ -0,0 +1,464 @@
+/*
+ (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 <string.h>
+
+#include <directfb.h>
+
+#include <direct/list.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/core_parts.h>
+#include <core/layers.h>
+#include <core/palette.h>
+#include <core/surface.h>
+#include <core/system.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/modules.h>
+
+DEFINE_MODULE_DIRECTORY( dfb_core_systems, "systems", DFB_CORE_SYSTEM_ABI_VERSION );
+
+
+D_DEBUG_DOMAIN( Core_System, "Core/System", "DirectFB System Core" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+ CoreSystemInfo system_info;
+} DFBSystemCoreShared;
+
+struct __DFB_DFBSystemCore {
+ int magic;
+
+ CoreDFB *core;
+
+ DFBSystemCoreShared *shared;
+};
+
+
+DFB_CORE_PART( system_core, SystemCore );
+
+/**********************************************************************************************************************/
+
+static DFBSystemCoreShared *system_field = NULL; /* FIXME */
+
+static DirectModuleEntry *system_module = NULL; /* FIXME */
+static const CoreSystemFuncs *system_funcs = NULL; /* FIXME */
+static CoreSystemInfo system_info; /* FIXME */
+static void *system_data = NULL; /* FIXME */
+
+/**********************************************************************************************************************/
+
+static DFBResult
+dfb_system_core_initialize( CoreDFB *core,
+ DFBSystemCore *data,
+ DFBSystemCoreShared *shared )
+{
+ DFBResult ret;
+
+ D_DEBUG_AT( Core_System, "dfb_system_core_initialize( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( shared != NULL );
+
+ data->core = core;
+ data->shared = shared;
+
+
+ system_field = shared; /* FIXME */
+
+ system_field->system_info = system_info;
+
+ ret = system_funcs->Initialize( core, &system_data );
+ if (ret)
+ return ret;
+
+
+ D_MAGIC_SET( data, DFBSystemCore );
+ D_MAGIC_SET( shared, DFBSystemCoreShared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_system_core_join( CoreDFB *core,
+ DFBSystemCore *data,
+ DFBSystemCoreShared *shared )
+{
+ DFBResult ret;
+
+ D_DEBUG_AT( Core_System, "dfb_system_core_join( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_MAGIC_ASSERT( shared, DFBSystemCoreShared );
+
+ data->core = core;
+ data->shared = shared;
+
+
+ system_field = shared; /* FIXME */
+
+ if (system_field->system_info.type != system_info.type ||
+ strcmp( system_field->system_info.name, system_info.name ))
+ {
+ D_ERROR( "DirectFB/core/system: "
+ "running system '%s' doesn't match system '%s'!\n",
+ system_field->system_info.name, system_info.name );
+
+ system_field = NULL;
+
+ return DFB_UNSUPPORTED;
+ }
+
+ if (system_field->system_info.version.major != system_info.version.major ||
+ system_field->system_info.version.minor != system_info.version.minor)
+ {
+ D_ERROR( "DirectFB/core/system: running system version '%d.%d' "
+ "doesn't match version '%d.%d'!\n",
+ system_field->system_info.version.major,
+ system_field->system_info.version.minor,
+ system_info.version.major,
+ system_info.version.minor );
+
+ system_field = NULL;
+
+ return DFB_UNSUPPORTED;
+ }
+
+ ret = system_funcs->Join( core, &system_data );
+ if (ret)
+ return ret;
+
+
+ D_MAGIC_SET( data, DFBSystemCore );
+
+ return DFB_OK;
+}
+
+static DFBResult
+dfb_system_core_shutdown( DFBSystemCore *data,
+ bool emergency )
+{
+ DFBResult ret;
+ DFBSystemCoreShared *shared;
+
+ D_DEBUG_AT( Core_System, "dfb_system_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBSystemCore );
+ D_MAGIC_ASSERT( data->shared, DFBSystemCoreShared );
+
+ shared = data->shared;
+
+
+ ret = system_funcs->Shutdown( emergency );
+
+ direct_module_unref( system_module );
+
+ system_module = NULL;
+ system_funcs = NULL;
+ system_field = NULL;
+ system_data = NULL;
+
+
+ D_MAGIC_CLEAR( data );
+ D_MAGIC_CLEAR( shared );
+
+ return ret;
+}
+
+static DFBResult
+dfb_system_core_leave( DFBSystemCore *data,
+ bool emergency )
+{
+ DFBResult ret;
+ DFBSystemCoreShared *shared;
+
+ D_DEBUG_AT( Core_System, "dfb_system_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBSystemCore );
+ D_MAGIC_ASSERT( data->shared, DFBSystemCoreShared );
+
+ shared = data->shared;
+
+
+ ret = system_funcs->Leave( emergency );
+
+ direct_module_unref( system_module );
+
+ system_module = NULL;
+ system_funcs = NULL;
+ system_field = NULL;
+ system_data = NULL;
+
+
+ D_MAGIC_CLEAR( data );
+
+ return ret;
+}
+
+static DFBResult
+dfb_system_core_suspend( DFBSystemCore *data )
+{
+ DFBSystemCoreShared *shared;
+
+ D_DEBUG_AT( Core_System, "dfb_system_core_suspend( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBSystemCore );
+ D_MAGIC_ASSERT( data->shared, DFBSystemCoreShared );
+
+ shared = data->shared;
+
+ return system_funcs->Suspend();
+}
+
+static DFBResult
+dfb_system_core_resume( DFBSystemCore *data )
+{
+ DFBSystemCoreShared *shared;
+
+ D_DEBUG_AT( Core_System, "dfb_system_core_resume( %p )\n", data );
+
+ D_MAGIC_ASSERT( data, DFBSystemCore );
+ D_MAGIC_ASSERT( data->shared, DFBSystemCoreShared );
+
+ shared = data->shared;
+
+ return system_funcs->Resume();
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_system_lookup( void )
+{
+ DirectLink *l;
+
+ direct_modules_explore_directory( &dfb_core_systems );
+
+ direct_list_foreach( l, dfb_core_systems.entries ) {
+ DirectModuleEntry *module = (DirectModuleEntry*) l;
+ const CoreSystemFuncs *funcs;
+
+ funcs = direct_module_ref( module );
+ if (!funcs)
+ continue;
+
+ if (!system_module || (!dfb_config->system ||
+ !strcasecmp( dfb_config->system, module->name )))
+ {
+ if (system_module)
+ direct_module_unref( system_module );
+
+ system_module = module;
+ system_funcs = funcs;
+
+ funcs->GetSystemInfo( &system_info );
+ }
+ else
+ direct_module_unref( module );
+ }
+
+ if (!system_module) {
+ D_ERROR("DirectFB/core/system: No system found!\n");
+
+ return DFB_NOIMPL;
+ }
+
+ return DFB_OK;
+}
+
+CoreSystemType
+dfb_system_type( void )
+{
+ return system_info.type;
+}
+
+CoreSystemCapabilities
+dfb_system_caps( void )
+{
+ return system_info.caps;
+}
+
+void *
+dfb_system_data( void )
+{
+ return system_data;
+}
+
+volatile void *
+dfb_system_map_mmio( unsigned int offset,
+ int length )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->MapMMIO( offset, length );
+}
+
+void
+dfb_system_unmap_mmio( volatile void *addr,
+ int length )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ system_funcs->UnmapMMIO( addr, length );
+}
+
+int
+dfb_system_get_accelerator( void )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->GetAccelerator();
+}
+
+VideoMode *
+dfb_system_modes( void )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->GetModes();
+}
+
+VideoMode *
+dfb_system_current_mode( void )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->GetCurrentMode();
+}
+
+DFBResult
+dfb_system_thread_init( void )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->ThreadInit();
+}
+
+bool
+dfb_system_input_filter( CoreInputDevice *device,
+ DFBInputEvent *event )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->InputFilter( device, event );
+}
+
+unsigned long
+dfb_system_video_memory_physical( unsigned int offset )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->VideoMemoryPhysical( offset );
+}
+
+void *
+dfb_system_video_memory_virtual( unsigned int offset )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->VideoMemoryVirtual( offset );
+}
+
+unsigned int
+dfb_system_videoram_length( void )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->VideoRamLength();
+}
+
+unsigned long
+dfb_system_aux_memory_physical( unsigned int offset )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->AuxMemoryPhysical( offset );
+}
+
+void *
+dfb_system_aux_memory_virtual( unsigned int offset )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->AuxMemoryVirtual( offset );
+}
+
+unsigned int
+dfb_system_auxram_length( void )
+{
+ D_ASSERT( system_funcs != NULL );
+
+ return system_funcs->AuxRamLength();
+}
+
+void
+dfb_system_get_busid( int *ret_bus, int *ret_dev, int *ret_func )
+{
+ int bus = -1, dev = -1, func = -1;
+
+ D_ASSERT( system_funcs != NULL );
+
+ system_funcs->GetBusID( &bus, &dev, &func );
+
+ if (ret_bus)
+ *ret_bus = bus;
+ if (ret_dev)
+ *ret_dev = dev;
+ if (ret_func)
+ *ret_func = func;
+}
+
+void
+dfb_system_get_deviceid( unsigned int *ret_vendor_id,
+ unsigned int *ret_device_id )
+{
+ unsigned int vendor_id = 0, device_id = 0;
+
+ D_ASSERT( system_funcs != NULL );
+
+ system_funcs->GetDeviceID( &vendor_id, &device_id );
+
+ if (ret_vendor_id)
+ *ret_vendor_id = vendor_id;
+ if (ret_device_id)
+ *ret_device_id = device_id;
+}
+
diff --git a/Source/DirectFB/src/core/system.h b/Source/DirectFB/src/core/system.h
new file mode 100755
index 0000000..f6d4df1
--- /dev/null
+++ b/Source/DirectFB/src/core/system.h
@@ -0,0 +1,258 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DFB__CORE__SYSTEM_H__
+#define __DFB__CORE__SYSTEM_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+#include <direct/modules.h>
+
+#include <fusion/types.h>
+
+typedef enum {
+ CORE_ANY,
+ CORE_FBDEV,
+ CORE_X11,
+ CORE_OSX,
+ CORE_SDL,
+ CORE_VNC,
+ CORE_DEVMEM,
+ CORE_TI_CMEM
+} CoreSystemType;
+
+typedef enum {
+ CSCAPS_NONE = 0x00000000, /* None of these. */
+
+ CSCAPS_ACCELERATION = 0x00000001, /* HW acceleration supported, so probe graphics drivers. */
+
+ CSCAPS_ALL = 0x00000001 /* All of these. */
+} CoreSystemCapabilities;
+
+/*
+ * hold information of a Videomode read from /etc/fb.modes
+ * (to be replaced by DirectFB's own config system)
+ */
+typedef struct _VideoMode {
+ int xres;
+ int yres;
+ int bpp;
+
+ int priority;
+
+ int pixclock;
+ int left_margin;
+ int right_margin;
+ int upper_margin;
+ int lower_margin;
+ int hsync_len;
+ int vsync_len;
+ int hsync_high;
+ int vsync_high;
+ int csync_high;
+
+ int laced;
+ int doubled;
+
+ int sync_on_green;
+ int external_sync;
+ int broadcast;
+
+ struct _VideoMode *next;
+} VideoMode;
+
+DECLARE_MODULE_DIRECTORY( dfb_core_systems );
+
+/*
+ * Increase this number when changes result in binary incompatibility!
+ */
+#define DFB_CORE_SYSTEM_ABI_VERSION 9
+
+#define DFB_CORE_SYSTEM_INFO_NAME_LENGTH 60
+#define DFB_CORE_SYSTEM_INFO_VENDOR_LENGTH 80
+#define DFB_CORE_SYSTEM_INFO_URL_LENGTH 120
+#define DFB_CORE_SYSTEM_INFO_LICENSE_LENGTH 40
+
+
+typedef struct {
+ int major; /* major version */
+ int minor; /* minor version */
+} CoreSystemVersion; /* major.minor, e.g. 0.1 */
+
+typedef struct {
+ CoreSystemVersion version;
+
+ CoreSystemType type;
+ CoreSystemCapabilities caps;
+
+ char name[DFB_CORE_SYSTEM_INFO_NAME_LENGTH];
+ /* Name of system, e.g. 'FBDev' */
+
+ char vendor[DFB_CORE_SYSTEM_INFO_VENDOR_LENGTH];
+ /* Vendor (or author) of the driver,
+ e.g. 'directfb.org' or 'Denis Oliver Kropp' */
+
+ char url[DFB_CORE_SYSTEM_INFO_URL_LENGTH];
+ /* URL for driver updates,
+ e.g. 'http://www.directfb.org/' */
+
+ char license[DFB_CORE_SYSTEM_INFO_LICENSE_LENGTH];
+ /* License, e.g. 'LGPL' or 'proprietary' */
+} CoreSystemInfo;
+
+typedef struct {
+ void (*GetSystemInfo)( CoreSystemInfo *info );
+
+ DFBResult (*Initialize)( CoreDFB *core, void **data );
+ DFBResult (*Join)( CoreDFB *core, void **data );
+
+ DFBResult (*Shutdown)( bool emergency );
+ DFBResult (*Leave)( bool emergency );
+
+ DFBResult (*Suspend)( void );
+ DFBResult (*Resume)( void );
+
+ VideoMode* (*GetModes)( void );
+ VideoMode* (*GetCurrentMode)( void );
+
+ /*
+ * Called at the beginning of a new thread.
+ */
+ DFBResult (*ThreadInit)( void );
+
+ /*
+ * Called upon incoming input events.
+ * Return true to drop the event, e.g. after doing special handling of it.
+ */
+ bool (*InputFilter)( CoreInputDevice *device, DFBInputEvent *event );
+
+ /*
+ * Graphics drivers call this function to get access to MMIO regions.
+ *
+ * device: Graphics device to map
+ * offset: Offset from MMIO base (default offset is 0)
+ * length: Length of mapped region (-1 uses default length)
+ *
+ * Returns the virtual address or NULL if mapping failed.
+ */
+ volatile void* (*MapMMIO)( unsigned int offset,
+ int length );
+
+ /*
+ * Graphics drivers call this function to unmap MMIO regions.
+ *
+ * addr: Virtual address returned by gfxcard_map_mmio
+ * length: Length of mapped region (-1 uses default length)
+ */
+ void (*UnmapMMIO)( volatile void *addr,
+ int length );
+
+ int (*GetAccelerator)( void );
+
+ unsigned long (*VideoMemoryPhysical)( unsigned int offset );
+ void* (*VideoMemoryVirtual)( unsigned int offset );
+
+ unsigned int (*VideoRamLength)( void );
+
+ unsigned long (*AuxMemoryPhysical)( unsigned int offset );
+ void* (*AuxMemoryVirtual)( unsigned int offset );
+
+ unsigned int (*AuxRamLength)( void );
+
+ void (*GetBusID)( int *ret_bus, int *ret_dev, int *ret_func );
+ void (*GetDeviceID)( unsigned int *ret_vendor_id,
+ unsigned int *ret_device_id );
+} CoreSystemFuncs;
+
+
+
+DFBResult
+dfb_system_lookup( void );
+
+CoreSystemType
+dfb_system_type( void );
+
+CoreSystemCapabilities
+dfb_system_caps( void );
+
+void *
+dfb_system_data( void );
+
+volatile void *
+dfb_system_map_mmio( unsigned int offset,
+ int length );
+
+void
+dfb_system_unmap_mmio( volatile void *addr,
+ int length );
+
+int
+dfb_system_get_accelerator( void );
+
+VideoMode *
+dfb_system_modes( void );
+
+VideoMode *
+dfb_system_current_mode( void );
+
+DFBResult
+dfb_system_thread_init( void );
+
+bool
+dfb_system_input_filter( CoreInputDevice *device,
+ DFBInputEvent *event );
+
+unsigned long
+dfb_system_video_memory_physical( unsigned int offset );
+
+void *
+dfb_system_video_memory_virtual( unsigned int offset );
+
+unsigned int
+dfb_system_videoram_length( void );
+
+unsigned long
+dfb_system_aux_memory_physical( unsigned int offset );
+
+void *
+dfb_system_aux_memory_virtual( unsigned int offset );
+
+unsigned int
+dfb_system_auxram_length( void );
+
+void
+dfb_system_get_busid( int *ret_bus, int *ret_dev, int *ret_func );
+
+void
+dfb_system_get_deviceid( unsigned int *ret_vendor_id,
+ unsigned int *ret_device_id );
+
+#endif
+
diff --git a/Source/DirectFB/src/core/windows.c b/Source/DirectFB/src/core/windows.c
new file mode 100755
index 0000000..6d60925
--- /dev/null
+++ b/Source/DirectFB/src/core/windows.c
@@ -0,0 +1,1908 @@
+/*
+ (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 <pthread.h>
+
+#include <fusion/shmalloc.h>
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/core.h>
+#include <core/layers.h>
+#include <core/layer_context.h>
+#include <core/gfxcard.h>
+#include <core/input.h>
+#include <core/palette.h>
+#include <core/state.h>
+#include <core/system.h>
+#include <core/windows.h>
+#include <core/windowstack.h>
+#include <core/wm.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/trace.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+#include <gfx/util.h>
+
+#include <core/layers_internal.h>
+#include <core/windows_internal.h>
+
+
+D_DEBUG_DOMAIN( Core_Windows, "Core/Windows", "DirectFB Window Core" );
+
+
+typedef struct {
+ DirectLink link;
+
+ DFBInputDeviceID id;
+ GlobalReaction reaction;
+} StackDevice;
+
+/**************************************************************************************************/
+
+static bool
+core_window_filter( CoreWindow *window, const DFBWindowEvent *event );
+
+/**************************************************************************************************/
+
+static const ReactionFunc dfb_window_globals[] = {
+ NULL
+};
+
+/**************************************************************************************************/
+
+/*
+ * Window destructor.
+ */
+static void
+window_destructor( FusionObject *object, bool zombie, void *ctx )
+{
+ CoreWindow *window = (CoreWindow*) object;
+ CoreWindowStack *stack = window->stack;
+
+ D_DEBUG_AT( Core_Windows, "destroying %p (%d,%d - %dx%d%s)\n", window,
+ DFB_RECTANGLE_VALS( &window->config.bounds ), zombie ? " ZOMBIE" : "");
+
+ D_ASSUME( window->stack != NULL );
+
+ if (!stack) {
+ fusion_object_destroy( object );
+ return;
+ }
+
+ dfb_windowstack_lock( stack );
+
+ dfb_window_destroy( window );
+
+
+ if (window->cursor.surface)
+ dfb_surface_unlink( &window->cursor.surface );
+
+ if (window->caps & DWCAPS_SUBWINDOW) {
+ int index;
+ CoreWindow *toplevel;
+
+ toplevel = window->toplevel;
+ D_ASSERT( toplevel != NULL );
+
+ index = fusion_vector_index_of( &toplevel->subwindows, window );
+ D_ASSERT( index >= 0 );
+
+ fusion_vector_remove( &toplevel->subwindows, index );
+
+ dfb_window_unlink( &window->toplevel );
+ }
+ else {
+ D_ASSERT( fusion_vector_size(&window->subwindows) == 0 );
+
+ fusion_vector_destroy( &window->subwindows );
+ }
+
+ dfb_windowstack_unlock( stack );
+
+
+ /* Unlink the primary region of the context. */
+ if (window->primary_region)
+ dfb_layer_region_unlink( &window->primary_region );
+
+ D_MAGIC_CLEAR( window );
+
+ fusion_object_destroy( object );
+}
+
+FusionObjectPool *
+dfb_window_pool_create( const FusionWorld *world )
+{
+ return fusion_object_pool_create( "Window Pool",
+ sizeof(CoreWindow),
+ sizeof(DFBWindowEvent),
+ window_destructor, NULL, world );
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+create_region( CoreDFB *core,
+ CoreLayerContext *context,
+ CoreWindow *window,
+ DFBSurfacePixelFormat format,
+ DFBSurfaceCapabilities surface_caps,
+ CoreLayerRegion **ret_region,
+ CoreSurface **ret_surface )
+{
+ DFBResult ret;
+ CoreLayerRegionConfig config;
+ CoreLayerRegion *region;
+ CoreSurface *surface;
+ CoreSurfaceConfig scon;
+
+ D_ASSERT( core != NULL );
+ D_ASSERT( context != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( ret_region != NULL );
+ D_ASSERT( ret_surface != NULL );
+
+ memset( &config, 0, sizeof(CoreLayerRegionConfig) );
+
+ config.width = window->config.bounds.w;
+ config.height = window->config.bounds.h;
+ config.format = format;
+ config.options = context->config.options & DLOP_FLICKER_FILTERING;
+ config.source = (DFBRectangle) { 0, 0, config.width, config.height };
+ config.dest = window->config.bounds;
+ config.opacity = 0;
+ config.alpha_ramp[0] = 0x00;
+ config.alpha_ramp[1] = 0x55;
+ config.alpha_ramp[2] = 0xaa;
+ config.alpha_ramp[3] = 0xff;
+
+ if (surface_caps & DSCAPS_DOUBLE)
+ config.buffermode = DLBM_BACKVIDEO;
+ else if (surface_caps & DSCAPS_TRIPLE)
+ config.buffermode = DLBM_TRIPLE;
+ else
+ config.buffermode = DLBM_FRONTONLY;
+
+ if (((context->config.options & DLOP_ALPHACHANNEL) ||
+ (window->config.options & DWOP_ALPHACHANNEL)) && DFB_PIXELFORMAT_HAS_ALPHA(format))
+ config.options |= DLOP_ALPHACHANNEL;
+
+ config.options |= DLOP_OPACITY;
+
+ config.surface_caps = surface_caps & (DSCAPS_INTERLACED |
+ DSCAPS_SEPARATED |
+ DSCAPS_PREMULTIPLIED);
+
+ ret = dfb_layer_region_create( context, &region );
+ if (ret)
+ return ret;
+
+
+ do {
+ ret = dfb_layer_region_set_configuration( region, &config, CLRCF_ALL );
+ if (ret) {
+ if (config.options & DLOP_OPACITY)
+ config.options &= ~DLOP_OPACITY;
+ else if (config.options & DLOP_ALPHACHANNEL)
+ config.options = (config.options & ~DLOP_ALPHACHANNEL) | DLOP_OPACITY;
+ else {
+ D_DERROR( ret, "DirectFB/Core/Windows: Unable to set region configuration!\n" );
+ dfb_layer_region_unref( region );
+ return ret;
+ }
+ }
+ } while (ret);
+
+ scon.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS;
+ scon.size.w = config.width;
+ scon.size.h = config.height;
+ scon.format = format;
+ scon.caps = surface_caps | DSCAPS_VIDEOONLY;
+
+ ret = dfb_surface_create( core, &scon, CSTF_SHARED | CSTF_LAYER, context->layer_id, NULL, &surface );
+ if (ret) {
+ dfb_layer_region_unref( region );
+ return ret;
+ }
+
+ ret = dfb_layer_region_set_surface( region, surface );
+ if (ret) {
+ dfb_surface_unref( surface );
+ dfb_layer_region_unref( region );
+ return ret;
+ }
+
+ ret = dfb_layer_region_enable( region );
+ if (ret) {
+ dfb_surface_unref( surface );
+ dfb_layer_region_unref( region );
+ return ret;
+ }
+
+ *ret_region = region;
+ *ret_surface = surface;
+
+ return DFB_OK;
+}
+
+static DFBResult
+init_subwindow( CoreWindow *window,
+ CoreWindowStack *stack,
+ DFBWindowID toplevel_id )
+{
+ DFBResult ret;
+ CoreWindow *toplevel;
+
+ /* Lookup top level window */
+ ret = dfb_wm_window_lookup( stack, toplevel_id, &toplevel );
+ if (ret)
+ return ret;
+
+ /* Make sure chosen top level window is not a sub window */
+ if (toplevel->caps & DWCAPS_SUBWINDOW) {
+ D_ASSERT( toplevel->toplevel != NULL );
+ D_ASSERT( toplevel->toplevel_id != 0 );
+
+ return DFB_INVARG;
+ }
+ else {
+ D_ASSERT( toplevel->toplevel == NULL );
+ D_ASSERT( toplevel->toplevel_id == 0 );
+ }
+
+ /* Link top level window into sub window structure */
+ ret = dfb_window_link( &window->toplevel, toplevel );
+ if (ret)
+ return ret;
+
+ /* Add window to sub window list of top level window */
+ ret = fusion_vector_add( &toplevel->subwindows, window );
+ if (ret) {
+ dfb_window_unlink( &window->toplevel );
+ return ret;
+ }
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_window_create( CoreWindowStack *stack,
+ const DFBWindowDescription *desc,
+ CoreWindow **ret_window )
+{
+ DFBResult ret;
+ CoreSurface *surface;
+ CoreSurfacePolicy surface_policy = CSP_SYSTEMONLY;
+ CoreLayer *layer;
+ CoreLayerContext *context;
+ CoreWindow *window;
+ CardCapabilities card_caps;
+ CoreWindowConfig config;
+ DFBWindowCapabilities caps;
+ DFBSurfaceCapabilities surface_caps;
+ DFBSurfacePixelFormat pixelformat;
+ DFBWindowID toplevel_id;
+
+ D_DEBUG_AT( Core_Windows, "%s( %p )\n", __FUNCTION__, stack );
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( stack->context != NULL );
+ D_ASSERT( desc != NULL );
+ D_ASSERT( desc->width > 0 );
+ D_ASSERT( desc->height > 0 );
+ D_ASSERT( ret_window != NULL );
+
+ if (desc->width > 4096 || desc->height > 4096)
+ return DFB_LIMITEXCEEDED;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ context = stack->context;
+ layer = dfb_layer_at( context->layer_id );
+
+
+ caps = desc->caps;
+ pixelformat = desc->pixelformat;
+ surface_caps = desc->surface_caps & (DSCAPS_INTERLACED | DSCAPS_SEPARATED |
+ DSCAPS_PREMULTIPLIED | DSCAPS_DEPTH |
+ DSCAPS_STATIC_ALLOC | DSCAPS_SYSTEMONLY |
+ DSCAPS_VIDEOONLY);
+ toplevel_id = (desc->flags & DWDESC_TOPLEVEL_ID) ? desc->toplevel_id : 0;
+
+ if (toplevel_id != 0)
+ caps |= DWCAPS_SUBWINDOW;
+ else
+ caps &= ~DWCAPS_SUBWINDOW;
+
+
+ if (!dfb_config->translucent_windows) {
+ caps &= ~DWCAPS_ALPHACHANNEL;
+
+ /*if (DFB_PIXELFORMAT_HAS_ALPHA(pixelformat))
+ pixelformat = DSPF_UNKNOWN;*/
+ }
+
+ /* Choose pixel format. */
+ if (caps & DWCAPS_ALPHACHANNEL) {
+ if (pixelformat == DSPF_UNKNOWN) {
+ if (context->config.flags & DLCONF_PIXELFORMAT)
+ pixelformat = context->config.pixelformat;
+
+ if (! DFB_PIXELFORMAT_HAS_ALPHA(pixelformat))
+ pixelformat = DSPF_ARGB;
+ }
+ else if (! DFB_PIXELFORMAT_HAS_ALPHA(pixelformat)) {
+ dfb_windowstack_unlock( stack );
+ return DFB_INVARG;
+ }
+ }
+ else if (pixelformat == DSPF_UNKNOWN) {
+ if (context->config.flags & DLCONF_PIXELFORMAT)
+ pixelformat = context->config.pixelformat;
+ else {
+ D_WARN( "layer config has no pixel format, using RGB16" );
+
+ pixelformat = DSPF_RGB16;
+ }
+ }
+
+ /* Choose window surface policy */
+ if ((surface_caps & DSCAPS_VIDEOONLY) ||
+ (context->config.buffermode == DLBM_WINDOWS))
+ {
+ surface_policy = CSP_VIDEOONLY;
+ }
+ else if (!(surface_caps & DSCAPS_SYSTEMONLY) &&
+ context->config.buffermode != DLBM_BACKSYSTEM)
+ {
+ if (dfb_config->window_policy != -1) {
+ /* Use the explicitly specified policy. */
+ surface_policy = dfb_config->window_policy;
+ }
+ else {
+ /* Examine the hardware capabilities. */
+ dfb_gfxcard_get_capabilities( &card_caps );
+
+ if (card_caps.accel & DFXL_BLIT) {
+ if ((card_caps.blitting & DSBLIT_BLEND_ALPHACHANNEL) ||
+ !(caps & DWCAPS_ALPHACHANNEL))
+ surface_policy = CSP_VIDEOHIGH;
+ }
+ }
+ }
+
+ dfb_surface_caps_apply_policy( surface_policy, &surface_caps );
+
+ if (caps & DWCAPS_DOUBLEBUFFER)
+ surface_caps |= DSCAPS_DOUBLE;
+
+
+ memset( &config, 0, sizeof(CoreWindowConfig) );
+
+ config.bounds.x = desc->posx;
+ config.bounds.y = desc->posy;
+ config.bounds.w = desc->width;
+ config.bounds.h = desc->height;
+ config.stacking = (desc->flags & DWDESC_STACKING) ? desc->stacking : DWSC_MIDDLE;
+
+ config.events = DWET_ALL;
+
+ /* Auto enable blending for ARGB only, not indexed. */
+ if ((caps & DWCAPS_ALPHACHANNEL) &&
+ DFB_PIXELFORMAT_HAS_ALPHA (pixelformat) &&
+ !DFB_PIXELFORMAT_IS_INDEXED(pixelformat))
+ config.options |= DWOP_ALPHACHANNEL;
+
+ /* Override automatic settings. */
+ if (desc->flags & DWDESC_OPTIONS)
+ config.options = desc->options;
+
+ /* Create the window object. */
+ window = dfb_core_create_window( layer->core );
+
+ window->id = ++stack->id_pool;
+ window->caps = caps;
+ window->stack = stack;
+ window->config = config;
+ window->config.association = (desc->flags & DWDESC_PARENT) ? desc->parent_id : 0;
+ window->config.cursor_flags = dfb_config->default_cursor_flags;
+
+ /* Set toplevel window ID (new sub window feature) */
+ window->toplevel_id = toplevel_id;
+
+ if (desc->flags & DWDESC_RESOURCE_ID)
+ window->resource_id = desc->resource_id;
+
+ D_MAGIC_SET( window, CoreWindow );
+
+ ret = dfb_wm_preconfigure_window( stack, window );
+ if(ret) {
+ D_MAGIC_CLEAR( window );
+ fusion_object_destroy( &window->object );
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+
+ /* wm may have changed values */
+ config = window->config;
+ caps = window->caps;
+
+ /* Initialize sub window... */
+ if (caps & DWCAPS_SUBWINDOW) {
+ ret = init_subwindow( window, stack, toplevel_id );
+ if (ret) {
+ D_MAGIC_CLEAR( window );
+ fusion_object_destroy( &window->object );
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+ }
+ else {
+ /* ...or initialize top level window */
+ fusion_vector_init( &window->subwindows, 3, stack->shmpool );
+
+ /* In case WM forbids sub window request, clear the toplevel window ID */
+ window->toplevel_id = 0;
+ }
+
+ if (dfb_config->warn.flags & DCWF_CREATE_WINDOW)
+ D_WARN( "create-window %4dx%4d %6s, caps 0x%08x, surface-caps 0x%08x, ID %u",
+ window->config.bounds.w, window->config.bounds.h, dfb_pixelformat_name(pixelformat),
+ window->caps, surface_caps, window->id );
+
+ /* Create the window's surface using the layer's palette if possible. */
+ if (! (caps & (DWCAPS_INPUTONLY | DWCAPS_COLOR))) {
+ if (context->config.buffermode == DLBM_WINDOWS) {
+ CoreLayerRegion *region = NULL;
+
+ /* Create a region for the window. */
+ ret = create_region( layer->core, context, window,
+ pixelformat, surface_caps, &region, &surface );
+ if (ret) {
+ D_MAGIC_CLEAR( window );
+ fusion_object_destroy( &window->object );
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+
+ /* Link the region into the window structure. */
+ dfb_layer_region_link( &window->region, region );
+ dfb_layer_region_unref( region );
+
+ /* Link the surface into the window structure. */
+ dfb_surface_link( &window->surface, surface );
+ dfb_surface_unref( surface );
+ }
+ else {
+ CoreLayerRegion *region;
+
+ /* Get the primary region of the layer context. */
+ ret = dfb_layer_context_get_primary_region( context, true, &region );
+ if (ret) {
+ D_MAGIC_CLEAR( window );
+ fusion_object_destroy( &window->object );
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+
+ /* Link the primary region into the window structure. */
+ dfb_layer_region_link( &window->primary_region, region );
+ dfb_layer_region_unref( region );
+
+ D_DEBUG_AT( Core_Windows, " -> %dx%d %s %s\n",
+ window->config.bounds.w, window->config.bounds.h,
+ dfb_pixelformat_name(pixelformat),
+ (surface_policy == CSP_VIDEOONLY) ?
+ "VIDEOONLY" :
+ ((surface_policy == CSP_SYSTEMONLY) ?
+ "SYSTEM ONLY" :
+ "AUTO VIDEO") );
+
+ /* Give the WM a chance to provide its own surface. */
+ if (!window->surface) {
+ /* Create the surface for the window. */
+ ret = dfb_surface_create_simple( layer->core, config.bounds.w, config.bounds.h,
+ pixelformat, surface_caps, CSTF_SHARED | CSTF_WINDOW,
+ (desc->flags & DWDESC_RESOURCE_ID) ?
+ desc->resource_id : window->id,
+ region->surface ?
+ region->surface->palette : NULL, &surface );
+ if (ret) {
+ D_DERROR( ret, "Core/Windows: Failed to create window surface!\n" );
+ D_MAGIC_CLEAR( window );
+ dfb_layer_region_unlink( &window->primary_region );
+ fusion_object_destroy( &window->object );
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+
+ /* Link the surface into the window structure. */
+ dfb_surface_link( &window->surface, surface );
+ dfb_surface_unref( surface );
+ }
+ }
+ }
+ else
+ D_DEBUG_AT( Core_Windows, " -> %dx%d - INPUT ONLY!\n",
+ window->config.bounds.w, window->config.bounds.h );
+
+ D_DEBUG_AT( Core_Windows, " -> %p\n", window );
+
+ /* Pass the new window to the window manager. */
+ ret = dfb_wm_add_window( stack, window );
+ if (ret) {
+ D_DERROR( ret, "Core/Windows: Failed to add window to manager!\n" );
+
+ D_MAGIC_CLEAR( window );
+
+ if (window->surface)
+ dfb_surface_unlink( &window->surface );
+
+ if (window->primary_region)
+ dfb_layer_region_unlink( &window->primary_region );
+
+ if (window->region)
+ dfb_layer_region_unlink( &window->region );
+
+ fusion_object_destroy( &window->object );
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+
+ /* Indicate that initialization is complete. */
+ D_FLAGS_SET( window->flags, CWF_INITIALIZED );
+
+ /* Increase number of windows. */
+ stack->num++;
+
+ /* Finally activate the object. */
+ fusion_object_activate( &window->object );
+
+ fusion_reactor_direct( window->object.reactor, true );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ /* Return the new window. */
+ *ret_window = window;
+
+ return DFB_OK;;
+}
+
+void
+dfb_window_destroy( CoreWindow *window )
+{
+ int i;
+ DFBWindowEvent evt;
+ CoreWindowStack *stack;
+ BoundWindow *bound, *next;
+ CoreWindow *subwindow;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+ D_ASSERT( DFB_WINDOW_INITIALIZED( window ) );
+
+ D_DEBUG_AT( Core_Windows, "dfb_window_destroy (%p) [%4d,%4d - %4dx%4d]\n",
+ window, DFB_RECTANGLE_VALS( &window->config.bounds ) );
+
+ D_ASSUME( window->stack != NULL );
+
+ stack = window->stack;
+ if (!stack)
+ return;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return;
+
+ /* Destroy sub windows first. */
+ fusion_vector_foreach_reverse (subwindow, i, window->subwindows) {
+ D_ASSERT( subwindow != NULL );
+ D_ASSERT( DFB_WINDOW_INITIALIZED( subwindow ) );
+
+ dfb_window_destroy( subwindow );
+ }
+
+ /* Avoid multiple destructions. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ D_DEBUG_AT( Core_Windows, "%p already destroyed.\n", window );
+ dfb_windowstack_unlock( stack );
+ return;
+ }
+
+ /* Unbind bound windows. */
+ direct_list_foreach_safe (bound, next, window->bound_windows) {
+ direct_list_remove( &window->bound_windows, &bound->link );
+
+ bound->window->boundto = NULL;
+
+ SHFREE( stack->shmpool, bound );
+ }
+
+ /* Unbind this window. */
+ if (window->boundto)
+ dfb_window_unbind( window->boundto, window );
+
+ /* Make sure the window is no longer visible. */
+ dfb_window_set_opacity( window, 0 );
+
+ /* Stop managing the window. */
+ dfb_wm_remove_window( stack, window );
+
+ /* Indicate destruction. */
+ D_FLAGS_SET( window->flags, CWF_DESTROYED );
+
+ /* Hardware allocated? */
+ if (window->region) {
+ /* Disable region (removing it from hardware). */
+ dfb_layer_region_disable( window->region );
+
+ /* Unlink from structure. */
+ dfb_layer_region_unlink( &window->region );
+ }
+
+ /* Unlink the window's surface. */
+ if (window->surface) {
+ dfb_surface_unlink( &window->surface );
+ }
+
+ /* Decrease number of windows. */
+ stack->num--;
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+
+ /* Notify listeners. */
+ evt.type = DWET_DESTROYED;
+ dfb_window_post_event( window, &evt );
+}
+
+DFBResult
+dfb_window_change_stacking( CoreWindow *window,
+ DFBWindowStackingClass stacking )
+{
+ DFBResult ret;
+ CoreWindowStack *stack;
+ CoreWindowConfig config;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+ D_ASSERT( window->stack != NULL );
+
+ stack = window->stack;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ config.stacking = stacking;
+
+ /* Let the window manager do its work. */
+ ret = dfb_wm_set_window_config( window, &config, CWCF_STACKING );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_raise( CoreWindow *window )
+{
+ DFBResult ret;
+ CoreWindowStack *stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+ D_ASSERT( window->stack != NULL );
+
+ stack = window->stack;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ /* Let the window manager do its work. */
+ ret = dfb_wm_restack_window( window, window, 1 );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_lower( CoreWindow *window )
+{
+ DFBResult ret;
+ CoreWindowStack *stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+ D_ASSERT( window->stack != NULL );
+
+ stack = window->stack;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ /* Let the window manager do its work. */
+ ret = dfb_wm_restack_window( window, window, -1 );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_raisetotop( CoreWindow *window )
+{
+ DFBResult ret;
+ CoreWindowStack *stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+ D_ASSERT( window->stack != NULL );
+
+ stack = window->stack;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ /* Let the window manager do its work. */
+ ret = dfb_wm_restack_window( window, NULL, 1 );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_lowertobottom( CoreWindow *window )
+{
+ DFBResult ret;
+ CoreWindowStack *stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+ D_ASSERT( window->stack != NULL );
+
+ stack = window->stack;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ /* Let the window manager do its work. */
+ ret = dfb_wm_restack_window( window, NULL, 0 );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_putatop( CoreWindow *window,
+ CoreWindow *lower )
+{
+ DFBResult ret;
+ CoreWindowStack *stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+ D_ASSERT( window->stack != NULL );
+
+ stack = window->stack;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ /* Let the window manager do its work. */
+ ret = dfb_wm_restack_window( window, lower, 1 );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_putbelow( CoreWindow *window,
+ CoreWindow *upper )
+{
+ DFBResult ret;
+ CoreWindowStack *stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+ D_ASSERT( window->stack != NULL );
+
+ stack = window->stack;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ /* Let the window manager do its work. */
+ ret = dfb_wm_restack_window( window, upper, -1 );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_set_config( CoreWindow *window,
+ const CoreWindowConfig *config,
+ CoreWindowConfigFlags flags )
+{
+ DFBResult ret;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ ret = dfb_wm_set_window_config( window, config, flags );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_set_cursor_shape( CoreWindow *window,
+ CoreSurface *surface,
+ unsigned int hot_x,
+ unsigned int hot_y )
+{
+ DFBResult ret = DFB_OK;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ window->cursor.hot_x = hot_x;
+ window->cursor.hot_y = hot_y;
+
+ if (window->cursor.surface)
+ dfb_surface_unlink( &window->cursor.surface );
+
+ if (surface) {
+ ret = dfb_surface_link( &window->cursor.surface, surface );
+ if (ret == DFB_OK) {
+ if (window->flags & CWF_FOCUSED)
+ dfb_windowstack_cursor_set_shape( stack, surface, hot_x, hot_y );
+ }
+ }
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+static DFBResult
+move_window( CoreWindow *window,
+ int x,
+ int y )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+ BoundWindow *bound;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ config.bounds.x = x;
+ config.bounds.y = y;
+
+ ret = dfb_wm_set_window_config( window, &config, CWCF_POSITION );
+ if (ret)
+ return ret;
+
+ direct_list_foreach (bound, window->bound_windows) {
+ move_window( bound->window,
+ window->config.bounds.x + bound->x,
+ window->config.bounds.y + bound->y );
+ }
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_window_move( CoreWindow *window,
+ int x,
+ int y,
+ bool relative )
+{
+ DFBResult ret;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ if (window->boundto) {
+ dfb_windowstack_unlock( stack );
+ return DFB_UNSUPPORTED;
+ }
+
+ if (relative) {
+ x += window->config.bounds.x;
+ y += window->config.bounds.y;
+ }
+
+ if (x == window->config.bounds.x && y == window->config.bounds.y) {
+ dfb_windowstack_unlock( stack );
+ return DFB_OK;
+ }
+
+ ret = move_window( window, x, y );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_set_bounds( CoreWindow *window,
+ int x,
+ int y,
+ int width,
+ int height )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+ CoreWindowStack *stack = window->stack;
+ int old_x;
+ int old_y;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ old_x = window->config.bounds.x;
+ old_y = window->config.bounds.y;
+
+ if (window->boundto) {
+ if (old_x != x || old_y != y) {
+ dfb_windowstack_unlock( stack );
+ return DFB_UNSUPPORTED;
+ }
+ }
+
+ config.bounds.x = x;
+ config.bounds.y = y;
+ config.bounds.w = width;
+ config.bounds.h = height;
+
+ if (window->config.bounds.x == x &&
+ window->config.bounds.y == y &&
+ window->config.bounds.w == width &&
+ window->config.bounds.h == height)
+ {
+ dfb_windowstack_unlock( stack );
+ return DFB_OK;
+ }
+
+ ret = dfb_wm_set_window_config( window, &config, CWCF_POSITION | CWCF_SIZE );
+ if (ret) {
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+
+ if (old_x != x || old_y != y) {
+ BoundWindow *bound;
+
+ direct_list_foreach (bound, window->bound_windows) {
+ move_window( bound->window,
+ window->config.bounds.x + bound->x,
+ window->config.bounds.y + bound->y );
+ }
+ }
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_window_resize( CoreWindow *window,
+ int width,
+ int height )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ D_DEBUG_AT( Core_Windows, "dfb_window_resize (%p) [%4d,%4d - %4dx%4d -> %dx%d]\n",
+ window, DFB_RECTANGLE_VALS( &window->config.bounds ), width, height );
+
+ D_ASSERT( width > 0 );
+ D_ASSERT( height > 0 );
+
+ if (width > 4096 || height > 4096)
+ return DFB_LIMITEXCEEDED;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ if (window->config.bounds.w == width && window->config.bounds.h == height) {
+ dfb_windowstack_unlock( stack );
+ return DFB_OK;
+ }
+
+ config.bounds.w = width;
+ config.bounds.h = height;
+
+ ret = dfb_wm_set_window_config( window, &config, CWCF_SIZE );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_bind( CoreWindow *window,
+ CoreWindow *source,
+ int x,
+ int y )
+{
+ DFBResult ret;
+ CoreWindowStack *stack = window->stack;
+ BoundWindow *bound;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ if (window == source)
+ return DFB_UNSUPPORTED;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ if (DFB_WINDOW_DESTROYED( source )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ bound = SHCALLOC( stack->shmpool, 1, sizeof(BoundWindow) );
+ if (!bound) {
+ dfb_windowstack_unlock( stack );
+ return DFB_NOSHAREDMEMORY;
+ }
+
+ if (source->boundto)
+ dfb_window_unbind( source->boundto, source );
+
+ ret = move_window( source,
+ window->config.bounds.x + x,
+ window->config.bounds.y + y );
+ if (ret) {
+ SHFREE( stack->shmpool, bound );
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+
+ bound->window = source;
+ bound->x = x;
+ bound->y = y;
+
+ direct_list_append( &window->bound_windows, &bound->link );
+
+ source->boundto = window;
+
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_window_unbind( CoreWindow *window,
+ CoreWindow *source )
+{
+ CoreWindowStack *stack = window->stack;
+ BoundWindow *bound;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ if (DFB_WINDOW_DESTROYED( source )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ if (source->boundto != window) {
+ dfb_windowstack_unlock( stack );
+ return DFB_UNSUPPORTED;
+ }
+
+ direct_list_foreach (bound, window->bound_windows) {
+ if (bound->window == source) {
+ direct_list_remove( &window->bound_windows, &bound->link );
+
+ bound->window->boundto = NULL;
+
+ SHFREE( stack->shmpool, bound );
+
+ break;
+ }
+ }
+
+ if (!bound)
+ D_BUG( "window not found" );
+
+ dfb_windowstack_unlock( stack );
+
+ return bound ? DFB_OK : DFB_ITEMNOTFOUND;
+}
+
+/*
+ * sets the source color key
+ */
+DFBResult
+dfb_window_set_color( CoreWindow *window,
+ DFBColor color )
+{
+ DFBResult ret;
+ DFBColor cc;
+ CoreWindowConfig config;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ cc = window->config.color;
+ if ( (cc.a==color.a) && (cc.r==color.r) && (cc.g==color.g) && (cc.b==color.b) ) {
+ dfb_windowstack_unlock( stack );
+ return DFB_OK;
+ }
+
+ config.color = color;
+
+ ret = dfb_wm_set_window_config( window, &config, CWCF_COLOR );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_set_colorkey( CoreWindow *window,
+ u32 color_key )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ if (window->config.color_key == color_key) {
+ dfb_windowstack_unlock( stack );
+ return DFB_OK;
+ }
+
+ config.color_key = color_key;
+
+ ret = dfb_wm_set_window_config( window, &config, CWCF_COLOR_KEY );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_set_opacity( CoreWindow *window,
+ u8 opacity )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ if (window->config.opacity == opacity) {
+ dfb_windowstack_unlock( stack );
+ return DFB_OK;
+ }
+
+ config.opacity = opacity;
+
+ ret = dfb_wm_set_window_config( window, &config, CWCF_OPACITY );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_change_options( CoreWindow *window,
+ DFBWindowOptions disable,
+ DFBWindowOptions enable )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ D_ASSUME( disable | enable );
+
+ if (!disable && !enable)
+ return DFB_OK;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ config.options = (window->config.options & ~disable) | enable;
+
+ ret = dfb_wm_set_window_config( window, &config, CWCF_OPTIONS );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_set_opaque( CoreWindow *window,
+ const DFBRegion *region )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ DFB_REGION_ASSERT_IF( region );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ config.opaque.x1 = 0;
+ config.opaque.y1 = 0;
+ config.opaque.x2 = window->config.bounds.w - 1;
+ config.opaque.y2 = window->config.bounds.h - 1;
+
+ if (region && !dfb_region_region_intersect( &config.opaque, region ))
+ ret = DFB_INVAREA;
+ else
+ ret = dfb_wm_set_window_config( window, &config, CWCF_OPAQUE );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_change_events( CoreWindow *window,
+ DFBWindowEventType disable,
+ DFBWindowEventType enable )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ D_ASSUME( disable | enable );
+
+ if (!disable && !enable)
+ return DFB_OK;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ config.events = (window->config.events & ~disable) | enable;
+
+ ret = dfb_wm_set_window_config( window, &config, CWCF_EVENTS );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_set_key_selection( CoreWindow *window,
+ DFBWindowKeySelection selection,
+ const DFBInputDeviceKeySymbol *keys,
+ unsigned int num_keys )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ D_ASSERT( selection == DWKS_ALL || selection == DWKS_NONE || selection == DWKS_LIST );
+ D_ASSERT( keys != NULL || selection != DWKS_LIST );
+ D_ASSERT( num_keys > 0 || selection != DWKS_LIST );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ config.key_selection = selection;
+ config.keys = (DFBInputDeviceKeySymbol*) keys; /* FIXME */
+ config.num_keys = num_keys;
+
+ ret = dfb_wm_set_window_config( window, &config, CWCF_KEY_SELECTION );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_change_grab( CoreWindow *window,
+ CoreWMGrabTarget target,
+ bool grab )
+{
+ DFBResult ret;
+ CoreWMGrab wmgrab;
+ CoreWindowStack *stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ stack = window->stack;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ wmgrab.target = target;
+
+ if (grab)
+ ret = dfb_wm_grab( window, &wmgrab );
+ else
+ ret = dfb_wm_ungrab( window, &wmgrab );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_grab_key( CoreWindow *window,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers )
+{
+ DFBResult ret;
+ CoreWMGrab grab;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ grab.target = CWMGT_KEY;
+ grab.symbol = symbol;
+ grab.modifiers = modifiers;
+
+ ret = dfb_wm_grab( window, &grab );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_ungrab_key( CoreWindow *window,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers )
+{
+ DFBResult ret;
+ CoreWMGrab grab;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ grab.target = CWMGT_KEY;
+ grab.symbol = symbol;
+ grab.modifiers = modifiers;
+
+ ret = dfb_wm_ungrab( window, &grab );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBResult
+dfb_window_repaint( CoreWindow *window,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags )
+{
+ DFBResult ret;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+ D_ASSERT( window->stack != NULL );
+
+ DFB_REGION_ASSERT_IF( region );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ ret = dfb_wm_update_window( window, region, flags );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+const char *
+dfb_window_event_type_name( DFBWindowEventType type )
+{
+ switch (type) {
+ case DWET_POSITION:
+ return "POSITION";
+
+ case DWET_SIZE:
+ return "SIZE";
+
+ case DWET_CLOSE:
+ return "CLOSE";
+
+ case DWET_DESTROYED:
+ return "DESTROYED";
+
+ case DWET_GOTFOCUS:
+ return "GOTFOCUS";
+
+ case DWET_LOSTFOCUS:
+ return "LOSTFOCUS";
+
+ case DWET_KEYDOWN:
+ return "KEYDOWN";
+
+ case DWET_KEYUP:
+ return "KEYUP";
+
+ case DWET_BUTTONDOWN:
+ return "BUTTONDOWN";
+
+ case DWET_BUTTONUP:
+ return "BUTTONUP";
+
+ case DWET_MOTION:
+ return "MOTION";
+
+ case DWET_ENTER:
+ return "ENTER";
+
+ case DWET_LEAVE:
+ return "LEAVE";
+
+ case DWET_WHEEL:
+ return "WHEEL";
+
+ case DWET_POSITION_SIZE:
+ return "POSITION_SIZE";
+
+ default:
+ break;
+ }
+
+ return "<invalid>";
+}
+
+void
+dfb_window_post_event( CoreWindow *window,
+ DFBWindowEvent *event )
+{
+ D_MAGIC_ASSERT( window, CoreWindow );
+ D_ASSERT( event != NULL );
+
+ D_ASSUME( !DFB_WINDOW_DESTROYED( window ) || event->type == DWET_DESTROYED );
+
+ if (! (event->type & window->config.events))
+ return;
+
+ gettimeofday( &event->timestamp, NULL );
+
+ event->clazz = DFEC_WINDOW;
+ event->window_id = window->id;
+
+ D_ASSUME( window->stack != NULL );
+/*
+ if (window->stack) {
+ CoreWindowStack *stack = window->stack;
+
+ event->cx = stack->cursor.x;
+ event->cy = stack->cursor.y;
+ }
+*/
+ if (!core_window_filter( window, event ))
+ dfb_window_dispatch( window, event, dfb_window_globals );
+}
+
+DFBResult
+dfb_window_send_configuration( CoreWindow *window )
+{
+ DFBWindowEvent event;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ D_ASSUME( !DFB_WINDOW_DESTROYED( window ) );
+
+ event.type = DWET_POSITION_SIZE;
+ event.x = window->config.bounds.x;
+ event.y = window->config.bounds.y;
+ event.w = window->config.bounds.w;
+ event.h = window->config.bounds.h;
+
+ dfb_window_post_event( window, &event );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_window_request_focus( CoreWindow *window )
+{
+ DFBResult ret;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ ret = dfb_wm_request_focus( window );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+DFBWindowID
+dfb_window_id( const CoreWindow *window )
+{
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ return window->id;
+}
+
+/*
+ * Returns window surface.
+ * For windows with DWCAPS_COLOR this returns 0.
+ */
+CoreSurface *
+dfb_window_surface( const CoreWindow *window )
+{
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ return window->surface;
+}
+
+/******************************************************************************/
+
+static bool
+core_window_filter( CoreWindow *window, const DFBWindowEvent *event )
+{
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ switch (event->type) {
+ case DWET_GOTFOCUS:
+ D_FLAGS_SET( window->flags, CWF_FOCUSED );
+ break;
+
+ case DWET_LOSTFOCUS:
+ D_FLAGS_CLEAR( window->flags, CWF_FOCUSED );
+ break;
+
+ case DWET_ENTER:
+ D_FLAGS_SET( window->flags, CWF_ENTERED );
+ break;
+
+ case DWET_LEAVE:
+ D_FLAGS_CLEAR( window->flags, CWF_ENTERED );
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+DFBResult
+dfb_window_set_rotation( CoreWindow *window,
+ int rotation )
+{
+ DFBResult ret = DFB_OK;
+ CoreWindowStack *stack = window->stack;
+
+ D_MAGIC_ASSERT( window, CoreWindow );
+
+ stack = window->stack;
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* Never call WM after destroying the window. */
+ if (DFB_WINDOW_DESTROYED( window )) {
+ dfb_windowstack_unlock( stack );
+ return DFB_DESTROYED;
+ }
+
+ /* Do nothing if the rotation didn't change. */
+ if (window->config.rotation != rotation) {
+ CoreWindowConfig config;
+
+ switch (rotation) {
+ case 0:
+ case 90:
+ case 180:
+ case 270:
+ config.rotation = rotation;
+
+ dfb_wm_set_window_config( window, &config, CWCF_ROTATION );
+ break;
+
+ default:
+ ret = DFB_UNSUPPORTED;
+ }
+ }
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
diff --git a/Source/DirectFB/src/core/windows.h b/Source/DirectFB/src/core/windows.h
new file mode 100755
index 0000000..4b9e2a4
--- /dev/null
+++ b/Source/DirectFB/src/core/windows.h
@@ -0,0 +1,316 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __WINDOWS_H__
+#define __WINDOWS_H__
+
+#include <directfb.h>
+#include <directfb_windows.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <fusion/object.h>
+
+typedef enum {
+ CWMGT_KEYBOARD,
+ CWMGT_POINTER,
+ CWMGT_KEY,
+ CWMGT_UNSELECTED_KEYS,
+} CoreWMGrabTarget;
+
+
+#define CoreWindowConfigFlags DFBWindowConfigFlags
+
+#define CWCF_NONE DWCONF_NONE
+#define CWCF_POSITION DWCONF_POSITION
+#define CWCF_SIZE DWCONF_SIZE
+#define CWCF_OPACITY DWCONF_OPACITY
+#define CWCF_STACKING DWCONF_STACKING
+#define CWCF_OPTIONS DWCONF_OPTIONS
+#define CWCF_EVENTS DWCONF_EVENTS
+#define CWCF_ASSOCIATION DWCONF_ASSOCIATION
+#define CWCF_COLOR_KEY DWCONF_COLOR_KEY
+#define CWCF_OPAQUE DWCONF_OPAQUE
+#define CWCF_COLOR DWCONF_COLOR
+#define CWCF_KEY_SELECTION DWCONF_KEY_SELECTION
+#define CWCF_CURSOR_FLAGS DWCONF_CURSOR_FLAGS
+#define CWCF_CURSOR_RESOLUTION DWCONF_CURSOR_RESOLUTION
+#define CWCF_SRC_GEOMETRY DWCONF_SRC_GEOMETRY
+#define CWCF_DST_GEOMETRY DWCONF_DST_GEOMETRY
+#define CWCF_ROTATION DWCONF_ROTATION
+#define CWCF_ALL DWCONF_ALL
+
+
+
+struct __DFB_CoreWindowConfig {
+ DFBRectangle bounds; /* position and size */
+ int opacity; /* global alpha factor */
+ DFBWindowStackingClass stacking; /* level boundaries */
+ DFBWindowOptions options; /* flags for appearance/behaviour */
+ DFBWindowEventType events; /* mask of enabled events */
+ DFBColor color; /* color for DWCAPS_COLOR */
+ u32 color_key; /* transparent pixel */
+ DFBRegion opaque; /* region of the window forced to be opaque */
+
+ DFBWindowKeySelection key_selection; /* how to filter keys in focus */
+ DFBInputDeviceKeySymbol *keys; /* list of keys for DWKS_LIST */
+ unsigned int num_keys; /* number of entries in key array */
+
+ DFBWindowGeometry src_geometry; /* advanced source geometry */
+ DFBWindowGeometry dst_geometry; /* advanced destination geometry */
+
+ int rotation;
+
+ DFBWindowID association;
+
+ DFBWindowCursorFlags cursor_flags;
+ DFBDimension cursor_resolution;
+};
+
+
+#define TRANSLUCENT_WINDOW(w) ((w)->config.opacity < 0xff || \
+ (w)->config.options & (DWOP_ALPHACHANNEL | DWOP_COLORKEYING))
+
+#define VISIBLE_WINDOW(w) (!((w)->caps & DWCAPS_INPUTONLY) && \
+ (w)->config.opacity > 0 && !DFB_WINDOW_DESTROYED((w)))
+
+
+/*
+ * Creates a pool of window objects.
+ */
+FusionObjectPool *dfb_window_pool_create( const FusionWorld *world );
+
+/*
+ * Generates dfb_window_ref(), dfb_window_attach() etc.
+ */
+FUSION_OBJECT_METHODS( CoreWindow, dfb_window )
+
+/*
+ * creates a window on a given stack
+ */
+DFBResult
+dfb_window_create( CoreWindowStack *stack,
+ const DFBWindowDescription *desc,
+ CoreWindow **ret_window );
+
+/*
+ * deinitializes a window and removes it from the window stack
+ */
+void
+dfb_window_destroy( CoreWindow *window );
+
+/*
+ * moves a window relative to its current position
+ */
+DFBResult
+dfb_window_move( CoreWindow *window,
+ int x,
+ int y,
+ bool relative );
+
+/*
+ * set position and size
+ */
+DFBResult
+dfb_window_set_bounds( CoreWindow *window,
+ int x,
+ int y,
+ int width,
+ int height );
+
+/*
+ * resizes a window
+ */
+DFBResult
+dfb_window_resize( CoreWindow *window,
+ int width,
+ int height );
+
+/*
+ * binds a window to this window
+ */
+DFBResult
+dfb_window_bind( CoreWindow *window,
+ CoreWindow *source,
+ int x,
+ int y );
+
+/*
+ * unbinds a window from this window
+ */
+DFBResult
+dfb_window_unbind( CoreWindow *window,
+ CoreWindow *source );
+
+/*
+ * changes stacking class
+ */
+DFBResult
+dfb_window_change_stacking( CoreWindow *window,
+ DFBWindowStackingClass stacking );
+
+/*
+ * move a window up one step in window stack
+ */
+DFBResult
+dfb_window_raise( CoreWindow *window );
+
+/*
+ * move a window down one step in window stack
+ */
+DFBResult
+dfb_window_lower( CoreWindow *window );
+
+/*
+ * makes a window the first (topmost) window in the window stack
+ */
+DFBResult
+dfb_window_raisetotop( CoreWindow *window );
+
+/*
+ * makes a window the last (downmost) window in the window stack
+ */
+DFBResult
+dfb_window_lowertobottom( CoreWindow *window );
+
+/*
+ * stacks the window on top of another one
+ */
+DFBResult
+dfb_window_putatop( CoreWindow *window,
+ CoreWindow *lower );
+
+/*
+ * stacks the window below another one
+ */
+DFBResult
+dfb_window_putbelow( CoreWindow *window,
+ CoreWindow *upper );
+
+/*
+ * sets the source color key
+ */
+DFBResult
+dfb_window_set_color( CoreWindow *window,
+ DFBColor color );
+
+/*
+ * sets the source color key
+ */
+DFBResult
+dfb_window_set_colorkey( CoreWindow *window,
+ u32 color_key );
+
+/*
+ * change window configuration
+ */
+DFBResult
+dfb_window_set_config( CoreWindow *window,
+ const CoreWindowConfig *config,
+ CoreWindowConfigFlags flags );
+
+/*
+ * change window cursor
+ */
+DFBResult
+dfb_window_set_cursor_shape( CoreWindow *window,
+ CoreSurface *surface,
+ unsigned int hot_x,
+ unsigned int hot_y );
+
+/*
+ * sets the global alpha factor
+ */
+DFBResult
+dfb_window_set_opacity( CoreWindow *window,
+ u8 opacity );
+
+/*
+ * sets the window options
+ */
+DFBResult
+dfb_window_change_options( CoreWindow *window,
+ DFBWindowOptions disable,
+ DFBWindowOptions enable );
+
+/*
+ * sets the window options
+ */
+DFBResult
+dfb_window_set_opaque( CoreWindow *window,
+ const DFBRegion *region );
+
+/*
+ * manipulates the event mask
+ */
+DFBResult
+dfb_window_change_events( CoreWindow *window,
+ DFBWindowEventType disable,
+ DFBWindowEventType enable );
+
+/*
+ * repaints part of a window, if region is NULL the whole window is repainted
+ */
+DFBResult
+dfb_window_repaint( CoreWindow *window,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags );
+
+/*
+ * request a window to gain focus
+ */
+DFBResult
+dfb_window_request_focus( CoreWindow *window );
+
+DFBResult dfb_window_set_key_selection( CoreWindow *window,
+ DFBWindowKeySelection selection,
+ const DFBInputDeviceKeySymbol *keys,
+ unsigned int num_keys );
+
+DFBResult dfb_window_change_grab ( CoreWindow *window,
+ CoreWMGrabTarget target,
+ bool grab );
+DFBResult dfb_window_grab_key ( CoreWindow *window,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers );
+DFBResult dfb_window_ungrab_key ( CoreWindow *window,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers );
+
+void dfb_window_post_event( CoreWindow *window, DFBWindowEvent *event );
+
+DFBResult dfb_window_send_configuration( CoreWindow *window );
+
+DFBWindowID dfb_window_id( const CoreWindow *window );
+
+CoreSurface *dfb_window_surface( const CoreWindow *window );
+
+DFBResult
+dfb_window_set_rotation( CoreWindow *window, int rotation );
+#endif
diff --git a/Source/DirectFB/src/core/windows_internal.h b/Source/DirectFB/src/core/windows_internal.h
new file mode 100755
index 0000000..cededef
--- /dev/null
+++ b/Source/DirectFB/src/core/windows_internal.h
@@ -0,0 +1,211 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__WINDOWS_INTERNAL_H__
+#define __CORE__WINDOWS_INTERNAL_H__
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/gfxcard.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+#include <core/windows.h>
+
+#include <direct/list.h>
+#include <fusion/lock.h>
+#include <fusion/object.h>
+
+
+typedef enum {
+ CWF_NONE = 0x00000000,
+
+ CWF_INITIALIZED = 0x00000001,
+ CWF_FOCUSED = 0x00000002,
+ CWF_ENTERED = 0x00000004,
+ CWF_DESTROYED = 0x00000008,
+
+ CWF_INSERTED = 0x00000010,
+
+ CWF_ALL = 0x0000001F
+} CoreWindowFlags;
+
+#define DFB_WINDOW_INITIALIZED(w) ((w)->flags & CWF_INITIALIZED)
+#define DFB_WINDOW_FOCUSED(w) ((w)->flags & CWF_FOCUSED)
+#define DFB_WINDOW_ENTERED(w) ((w)->flags & CWF_ENTERED)
+#define DFB_WINDOW_DESTROYED(w) ((w)->flags & CWF_DESTROYED)
+
+typedef struct {
+ DirectLink link;
+
+ CoreWindow *window;
+ int x;
+ int y;
+} BoundWindow;
+
+/*
+ * Core data of a window.
+ */
+struct __DFB_CoreWindow {
+ FusionObject object;
+
+ int magic;
+
+ DFBWindowID id;
+
+ CoreWindowFlags flags;
+
+ DFBWindowCapabilities caps; /* window capabilities, to enable blending etc. */
+
+ CoreWindowConfig config;
+
+ CoreSurface *surface; /* backing store surface */
+ GlobalReaction surface_reaction;
+
+ CoreWindowStack *stack; /* window stack the window belongs */
+
+ CoreLayerRegion *primary_region; /* default region of context */
+
+ CoreLayerRegion *region; /* hardware allocated window */
+
+ void *window_data; /* private data of window manager */
+
+ CoreGraphicsSerial serial1;
+ CoreGraphicsSerial serial2;
+
+ DirectLink *bound_windows; /* list of bound windows */
+ CoreWindow *boundto; /* window to which this window is bound (window binding) */
+
+ DFBWindowID toplevel_id; /* in case of a sub window toplevel_id != 0 */
+ CoreWindow *toplevel; /* for top level windows this will be NULL */
+ FusionVector subwindows; /* list of sub windows (only valid for top level windows) */
+
+ CoreWindow *subfocus; /* which of the sub windows has the focus? */
+
+ unsigned long resource_id;
+
+ struct {
+ unsigned int hot_x;
+ unsigned int hot_y;
+ CoreSurface *surface;
+ } cursor;
+};
+
+typedef enum {
+ CWSF_NONE = 0x00000000,
+
+ CWSF_INITIALIZED = 0x00000001,
+ CWSF_ACTIVATED = 0x00000002,
+
+ CWSF_ALL = 0x00000003
+} CoreWindowStackFlags;
+
+/*
+ * Core data of a window stack.
+ */
+struct __DFB_CoreWindowStack {
+ DirectLink link;
+
+ int magic;
+
+ CoreLayerContext *context;
+
+ int width;
+ int height;
+
+ int rotation;
+
+ int rotated_width;
+ int rotated_height;
+ DFBSurfaceBlittingFlags rotated_blit;
+
+ DFBWindowID id_pool;
+
+ int num;
+
+ struct {
+ int enabled; /* is cursor enabled ? */
+ int x, y; /* cursor position */
+ DFBDimension size; /* cursor shape size */
+ DFBPoint hot; /* hot spot */
+ CoreSurface *surface; /* shape */
+ u8 opacity; /* cursor opacity */
+ DFBRegion region; /* cursor is clipped by this region */
+
+ int numerator; /* cursor acceleration */
+ int denominator;
+ int threshold;
+
+ bool set; /* cursor enable/disable has
+ been called at least one time */
+
+ CoreSurfacePolicy policy;
+ } cursor;
+
+ /* stores information on handling the background on exposure */
+ struct {
+ DFBDisplayLayerBackgroundMode mode;
+ /* background handling mode:
+ don't care, solid color or image */
+
+ DFBColor color; /* color for solid background mode */
+ int color_index;
+
+
+ CoreSurface *image; /* surface for background image mode */
+
+ GlobalReaction image_reaction;
+ } bg;
+
+ DirectLink *devices; /* input devices attached to the stack */
+
+ bool hw_mode; /* recompositing is done by hardware */
+
+ void *stack_data; /* private data of window manager */
+
+ FusionSHMPoolShared *shmpool;
+
+ CoreWindowStackFlags flags;
+
+ Reaction input_core_reaction;
+};
+
+
+DFBResult dfb_wm_close_all_stacks( void *data );
+
+
+/* global reactions */
+ReactionResult _dfb_windowstack_inputdevice_listener ( const void *msg_data,
+ void *ctx );
+
+ReactionResult _dfb_windowstack_background_image_listener( const void *msg_data,
+ void *ctx );
+
+#endif
diff --git a/Source/DirectFB/src/core/windowstack.c b/Source/DirectFB/src/core/windowstack.c
new file mode 100755
index 0000000..7a19f1c
--- /dev/null
+++ b/Source/DirectFB/src/core/windowstack.c
@@ -0,0 +1,998 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <string.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/messages.h>
+
+#include <fusion/reactor.h>
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/input.h>
+#include <core/layer_context.h>
+#include <core/layers_internal.h>
+#include <core/surface.h>
+#include <core/windows_internal.h>
+#include <core/windowstack.h>
+#include <core/wm.h>
+
+#include <misc/conf.h>
+
+#include <gfx/convert.h>
+#include <gfx/util.h>
+
+
+#define CURSORFILE DATADIR"/cursor.dat"
+
+
+D_DEBUG_DOMAIN( Core_WindowStack, "Core/WindowStack", "DirectFB Core WindowStack" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ DirectLink link;
+
+ DFBInputDeviceID id;
+ Reaction reaction;
+} StackDevice;
+
+typedef struct {
+ DirectLink link;
+
+ DFBInputDeviceKeySymbol symbol;
+ DFBInputDeviceModifierMask modifiers;
+
+ CoreWindow *owner;
+} GrabbedKey;
+
+/**********************************************************************************************************************/
+
+static DFBResult load_default_cursor ( CoreDFB *core,
+ CoreWindowStack *stack );
+static DFBResult create_cursor_surface( CoreWindowStack *stack,
+ int width,
+ int height );
+
+/**********************************************************************************************************************/
+
+static DFBEnumerationResult stack_attach_devices( CoreInputDevice *device,
+ void *ctx );
+
+static ReactionResult stack_input_core_listener( const void *msg_data,
+ void *ctx );
+
+/**********************************************************************************************************************/
+
+/*
+ * Allocates and initializes a window stack.
+ */
+CoreWindowStack*
+dfb_windowstack_create( CoreLayerContext *context )
+{
+ DFBResult ret;
+ CoreWindowStack *stack;
+ CoreSurfacePolicy policy = CSP_SYSTEMONLY;
+ CoreLayer *layer;
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p )\n", __FUNCTION__, context );
+
+ D_ASSERT( context != NULL );
+
+ layer = dfb_layer_at( context->layer_id );
+
+ /* Allocate window stack data (completely shared) */
+ stack = (CoreWindowStack*) SHCALLOC( context->shmpool, 1, sizeof(CoreWindowStack) );
+ if (!stack) {
+ D_OOSHM();
+ return NULL;
+ }
+
+ stack->shmpool = context->shmpool;
+
+ /* Store context which we belong to. */
+ stack->context = context;
+
+ /* Set default acceleration */
+ stack->cursor.numerator = 2;
+ stack->cursor.denominator = 1;
+ stack->cursor.threshold = 4;
+
+ /* Choose cursor surface policy. */
+ if (context->config.buffermode != DLBM_BACKSYSTEM) {
+ CardCapabilities card_caps;
+
+ /* Use the explicitly specified policy? */
+ if (dfb_config->window_policy != -1)
+ policy = dfb_config->window_policy;
+ else {
+ /* Examine the hardware capabilities. */
+ dfb_gfxcard_get_capabilities( &card_caps );
+
+ if (card_caps.accel & DFXL_BLIT && card_caps.blitting & DSBLIT_BLEND_ALPHACHANNEL)
+ policy = CSP_VIDEOHIGH;
+ }
+ }
+
+ stack->cursor.policy = policy;
+ stack->cursor.opacity = 0xFF;
+
+ /* Set default background mode. */
+ stack->bg.mode = DLBM_DONTCARE;
+ stack->bg.color_index = -1;
+
+ D_MAGIC_SET( stack, CoreWindowStack );
+
+ /* Initialize window manager */
+ ret = dfb_wm_init_stack( stack );
+ if (ret) {
+ D_MAGIC_CLEAR( stack );
+ SHFREE( context->shmpool, stack );
+ return NULL;
+ }
+
+ if (dfb_core_is_master( layer->core ))
+ dfb_input_core_attach( layer->core, stack_input_core_listener, stack, &stack->input_core_reaction );
+
+ /* Attach to all input devices */
+ dfb_input_enumerate_devices( stack_attach_devices, stack, DICAPS_ALL );
+
+ D_DEBUG_AT( Core_WindowStack, " -> %p\n", stack );
+
+ return stack;
+}
+
+void
+dfb_windowstack_detach_devices( CoreWindowStack *stack )
+{
+ DirectLink *l;
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p )\n", __FUNCTION__, stack );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Detach all input devices. */
+ l = stack->devices;
+ while (l) {
+ DirectLink *next = l->next;
+ StackDevice *device = (StackDevice*) l;
+
+ dfb_input_detach( dfb_input_device_at( device->id ),
+ &device->reaction );
+
+ SHFREE( stack->shmpool, device );
+
+ l = next;
+ }
+}
+
+void
+dfb_windowstack_destroy( CoreWindowStack *stack )
+{
+ D_DEBUG_AT( Core_WindowStack, "%s( %p )\n", __FUNCTION__, stack );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ if (stack->input_core_reaction.func)
+ dfb_input_core_detach( NULL, &stack->input_core_reaction );
+
+ /* Unlink cursor surface. */
+ if (stack->cursor.surface)
+ dfb_surface_unlink( &stack->cursor.surface );
+
+ /* Shutdown window manager? */
+ if (stack->flags & CWSF_INITIALIZED)
+ dfb_wm_close_stack( stack );
+
+ /* detach listener from background surface and unlink it */
+ if (stack->bg.image) {
+ dfb_surface_detach_global( stack->bg.image,
+ &stack->bg.image_reaction );
+
+ dfb_surface_unlink( &stack->bg.image );
+ }
+
+ /* Deallocate shared stack data. */
+ if (stack->stack_data) {
+ SHFREE( stack->shmpool, stack->stack_data );
+ stack->stack_data = NULL;
+ }
+
+ D_MAGIC_CLEAR( stack );
+
+ /* Free stack data. */
+ SHFREE( stack->shmpool, stack );
+}
+
+void
+dfb_windowstack_resize( CoreWindowStack *stack,
+ int width,
+ int height,
+ int rotation )
+{
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %dx%d, %d )\n", __FUNCTION__, stack, width, height, rotation );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return;
+
+ /* Store the width and height of the stack */
+ stack->width = width;
+ stack->height = height;
+ stack->rotation = rotation;
+
+ switch (stack->rotation) {
+ default:
+ D_BUG( "invalid rotation %d", stack->rotation );
+ case 0:
+ stack->rotated_blit = DSBLIT_NOFX;
+ stack->rotated_width = stack->width;
+ stack->rotated_height = stack->height;
+ break;
+
+ case 90:
+ stack->rotated_blit = DSBLIT_ROTATE90;
+ stack->rotated_width = stack->height;
+ stack->rotated_height = stack->width;
+ break;
+
+ case 180:
+ stack->rotated_blit = DSBLIT_ROTATE180;
+ stack->rotated_width = stack->width;
+ stack->rotated_height = stack->height;
+ break;
+
+ case 270:
+ stack->rotated_blit = DSBLIT_ROTATE270;
+ stack->rotated_width = stack->height;
+ stack->rotated_height = stack->width;
+ break;
+ }
+
+ /* Setup new cursor clipping region */
+ stack->cursor.region.x1 = 0;
+ stack->cursor.region.y1 = 0;
+ stack->cursor.region.x2 = width - 1;
+ stack->cursor.region.y2 = height - 1;
+
+ /* Notify the window manager. */
+ dfb_wm_resize_stack( stack, width, height );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+}
+
+/*
+ * Prohibit access to the window stack data.
+ * Waits until stack is accessible.
+ */
+DirectResult
+dfb_windowstack_lock( CoreWindowStack *stack )
+{
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->context != NULL );
+
+ return dfb_layer_context_lock( stack->context );
+}
+
+/*
+ * Allow access to the window stack data.
+ */
+DirectResult
+dfb_windowstack_unlock( CoreWindowStack *stack )
+{
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->context != NULL );
+
+ return dfb_layer_context_unlock( stack->context );
+}
+
+DFBResult
+dfb_windowstack_repaint_all( CoreWindowStack *stack )
+{
+ DFBResult ret;
+ DFBRegion region;
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p )\n", __FUNCTION__, stack );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ region.x1 = 0;
+ region.y1 = 0;
+ region.x2 = stack->rotated_width - 1;
+ region.y2 = stack->rotated_height - 1;
+
+ ret = dfb_wm_update_stack( stack, &region, 0 );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+}
+
+/**********************************************************************************************************************/
+
+/*
+ * background handling
+ */
+
+DFBResult
+dfb_windowstack_set_background_mode ( CoreWindowStack *stack,
+ DFBDisplayLayerBackgroundMode mode )
+{
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %d )\n", __FUNCTION__, stack, mode );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* nothing to do if mode is the same */
+ if (mode != stack->bg.mode) {
+ /* for these modes a surface is required */
+ if ((mode == DLBM_IMAGE || mode == DLBM_TILE) && !stack->bg.image) {
+ dfb_windowstack_unlock( stack );
+ return DFB_MISSINGIMAGE;
+ }
+
+ /* set new mode */
+ stack->bg.mode = mode;
+
+ /* force an update of the window stack */
+ if (mode != DLBM_DONTCARE)
+ dfb_windowstack_repaint_all( stack );
+ }
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_windowstack_set_background_image( CoreWindowStack *stack,
+ CoreSurface *image )
+{
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %p )\n", __FUNCTION__, stack, image );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( image != NULL );
+
+ if (!(image->type & CSTF_SHARED))
+ return DFB_INVARG;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* if the surface is changed */
+ if (stack->bg.image != image) {
+ /* detach listener from old surface and unlink it */
+ if (stack->bg.image) {
+ dfb_surface_detach_global( stack->bg.image,
+ &stack->bg.image_reaction );
+
+ dfb_surface_unlink( &stack->bg.image );
+ }
+
+ /* link surface object */
+ dfb_surface_link( &stack->bg.image, image );
+
+ /* attach listener to new surface */
+ dfb_surface_attach_global( image,
+ DFB_WINDOWSTACK_BACKGROUND_IMAGE_LISTENER,
+ stack, &stack->bg.image_reaction );
+ }
+
+ /* force an update of the window stack */
+ if (stack->bg.mode == DLBM_IMAGE || stack->bg.mode == DLBM_TILE)
+ dfb_windowstack_repaint_all( stack );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_windowstack_set_background_color( CoreWindowStack *stack,
+ const DFBColor *color )
+{
+ D_ASSERT( color != NULL );
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, 0x%08x )\n", __FUNCTION__, stack,
+ PIXEL_ARGB( color->a, color->r, color->g, color->b ) );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* do nothing if color didn't change */
+ if (!DFB_COLOR_EQUAL( stack->bg.color, *color )) {
+ /* set new color */
+ stack->bg.color = *color;
+
+ /* force an update of the window stack */
+ if (stack->bg.mode == DLBM_COLOR)
+ dfb_windowstack_repaint_all( stack );
+ }
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_windowstack_set_background_color_index( CoreWindowStack *stack,
+ int index )
+{
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %d )\n", __FUNCTION__, stack, index );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ /* do nothing if color didn't change */
+ if (stack->bg.color_index != index) {
+ /* set new color index */
+ stack->bg.color_index = index;
+
+ /* force an update of the window stack */
+ if (stack->bg.mode == DLBM_COLOR)
+ dfb_windowstack_repaint_all( stack );
+ }
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+/*
+ * cursor control
+ */
+
+DFBResult
+dfb_windowstack_cursor_enable( CoreDFB *core, CoreWindowStack *stack, bool enable )
+{
+ DFBResult ret;
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %s )\n", __FUNCTION__, stack, enable ? "enable" : "disable" );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ stack->cursor.set = true;
+
+ if (dfb_config->no_cursor || stack->cursor.enabled == enable) {
+ dfb_windowstack_unlock( stack );
+ return DFB_OK;
+ }
+
+ if (enable && !stack->cursor.surface) {
+ ret = load_default_cursor( core, stack );
+ if (ret) {
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+ }
+
+ /* Keep state. */
+ stack->cursor.enabled = enable;
+
+ /* Notify WM. */
+ dfb_wm_update_cursor( stack, enable ? CCUF_ENABLE : CCUF_DISABLE );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_windowstack_cursor_set_opacity( CoreWindowStack *stack, u8 opacity )
+{
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, 0x%02x )\n", __FUNCTION__, stack, opacity );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ if (stack->cursor.opacity != opacity) {
+ /* Set new opacity. */
+ stack->cursor.opacity = opacity;
+
+ /* Notify WM. */
+ if (stack->cursor.enabled)
+ dfb_wm_update_cursor( stack, CCUF_OPACITY );
+ }
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_windowstack_cursor_set_shape( CoreWindowStack *stack,
+ CoreSurface *shape,
+ int hot_x,
+ int hot_y )
+{
+ DFBResult ret;
+ CoreSurface *cursor;
+ CoreCursorUpdateFlags flags = CCUF_SHAPE;
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %p, hot %d, %d ) <- size %dx%d\n",
+ __FUNCTION__, stack, shape, hot_x, hot_y,
+ shape->config.size.w, shape->config.size.h );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( shape != NULL );
+
+ if (dfb_config->no_cursor)
+ return DFB_OK;
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ cursor = stack->cursor.surface;
+ if (!cursor) {
+ D_ASSUME( !stack->cursor.enabled );
+
+ /* Create the a surface for the shape. */
+ ret = create_cursor_surface( stack, shape->config.size.w, shape->config.size.h );
+ if (ret) {
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+
+ cursor = stack->cursor.surface;
+ }
+ else if (stack->cursor.size.w != shape->config.size.w || stack->cursor.size.h != shape->config.size.h) {
+ dfb_surface_unlink( &stack->cursor.surface );
+
+ /* Recreate the surface for the shape. */
+ ret = create_cursor_surface( stack, shape->config.size.w, shape->config.size.h );
+ if (ret) {
+ dfb_windowstack_unlock( stack );
+ return ret;
+ }
+
+ cursor = stack->cursor.surface;
+
+
+ stack->cursor.size.w = shape->config.size.w;
+ stack->cursor.size.h = shape->config.size.h;
+
+ /* Notify about new size/shape. */
+ flags |= CCUF_SIZE | CCUF_SHAPE;
+ }
+
+ if (stack->cursor.hot.x != hot_x || stack->cursor.hot.y != hot_y) {
+ stack->cursor.hot.x = hot_x;
+ stack->cursor.hot.y = hot_y;
+
+ /* Notify about new position. */
+ flags |= CCUF_POSITION;
+ }
+
+ /* Copy the content of the new shape. */
+ dfb_gfx_copy( shape, cursor, NULL );
+
+ cursor->config.caps = ((cursor->config.caps & ~DSCAPS_PREMULTIPLIED) | (shape->config.caps & DSCAPS_PREMULTIPLIED));
+
+ /* Notify the WM. */
+ if (stack->cursor.enabled)
+ dfb_wm_update_cursor( stack, flags );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_windowstack_cursor_warp( CoreWindowStack *stack, int x, int y )
+{
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %d, %d )\n", __FUNCTION__, stack, x, y );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ if (x < 0)
+ x = 0;
+ else if (x > stack->width - 1)
+ x = stack->width - 1;
+
+ if (y < 0)
+ y = 0;
+ else if (y > stack->height - 1)
+ y = stack->height - 1;
+
+ if (stack->cursor.x != x || stack->cursor.y != y) {
+ stack->cursor.x = x;
+ stack->cursor.y = y;
+
+ /* Notify the WM. */
+ if (stack->cursor.enabled)
+ dfb_wm_update_cursor( stack, CCUF_POSITION );
+ }
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_windowstack_cursor_set_acceleration( CoreWindowStack *stack,
+ int numerator,
+ int denominator,
+ int threshold )
+{
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %d, %d, %d )\n",
+ __FUNCTION__, stack, numerator, denominator, threshold );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ stack->cursor.numerator = numerator;
+ stack->cursor.denominator = denominator;
+ stack->cursor.threshold = threshold;
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_windowstack_get_cursor_position( CoreWindowStack *stack, int *ret_x, int *ret_y )
+{
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %p, %p )\n", __FUNCTION__, stack, ret_x, ret_y );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSUME( ret_x != NULL || ret_y != NULL );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return DFB_FUSION;
+
+ if (ret_x)
+ *ret_x = stack->cursor.x;
+
+ if (ret_y)
+ *ret_y = stack->cursor.y;
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+static ReactionResult
+stack_input_core_listener( const void *msg_data,
+ void *ctx )
+{
+ const CoreInputCoreNotification *notification = msg_data;
+ CoreWindowStack *stack = ctx;
+
+ (void) notification;
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %p, %d )\n", __FUNCTION__, msg_data, ctx, notification->device_id );
+
+ D_ASSERT( msg_data != NULL );
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return RS_REMOVE;
+
+ /* Attach to all input devices */
+ dfb_input_enumerate_devices( stack_attach_devices, stack, DICAPS_ALL );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return RS_OK;
+}
+
+ReactionResult
+_dfb_windowstack_inputdevice_listener( const void *msg_data,
+ void *ctx )
+{
+ const DFBInputEvent *event = msg_data;
+ CoreWindowStack *stack = ctx;
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %p )\n", __FUNCTION__, msg_data, ctx );
+
+ D_ASSERT( msg_data != NULL );
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ /* Lock the window stack. */
+ if (dfb_windowstack_lock( stack ))
+ return RS_REMOVE;
+
+ /* Call the window manager to dispatch the event. */
+ if (dfb_layer_context_active( stack->context ))
+ dfb_wm_process_input( stack, event );
+
+ /* Unlock the window stack. */
+ dfb_windowstack_unlock( stack );
+
+ return RS_OK;
+}
+
+/*
+ * listen to the background image
+ */
+ReactionResult
+_dfb_windowstack_background_image_listener( const void *msg_data,
+ void *ctx )
+{
+ const CoreSurfaceNotification *notification = msg_data;
+ CoreWindowStack *stack = ctx;
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %p )\n", __FUNCTION__, msg_data, ctx );
+
+ D_ASSERT( notification != NULL );
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ if (notification->flags & CSNF_DESTROY) {
+ if (stack->bg.image == notification->surface) {
+ D_ERROR( "Core/WindowStack: Surface for background vanished.\n" );
+
+ stack->bg.mode = DLBM_COLOR;
+ stack->bg.image = NULL;
+
+ dfb_windowstack_repaint_all( stack );
+ }
+
+ return RS_REMOVE;
+ }
+
+ if (notification->flags & (CSNF_FLIP | CSNF_SIZEFORMAT))
+ dfb_windowstack_repaint_all( stack );
+
+ return RS_OK;
+}
+
+/**********************************************************************************************************************/
+
+/*
+ * internals
+ */
+
+static DFBEnumerationResult
+stack_attach_devices( CoreInputDevice *device,
+ void *ctx )
+{
+ StackDevice *dev;
+ DFBInputDeviceID id = dfb_input_device_id( device );
+ CoreWindowStack *stack = (CoreWindowStack*) ctx;
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ direct_list_foreach (dev, stack->devices) {
+ if (dev->id == id)
+ return DFENUM_OK;
+ }
+
+ dev = SHCALLOC( stack->shmpool, 1, sizeof(StackDevice) );
+ if (!dev) {
+ D_ERROR( "Core/WindowStack: Could not allocate %zu bytes\n", sizeof(StackDevice) );
+ return DFENUM_CANCEL;
+ }
+
+ dev->id = id;
+
+ direct_list_prepend( &stack->devices, &dev->link );
+
+ dfb_input_attach( device, _dfb_windowstack_inputdevice_listener, ctx, &dev->reaction );
+
+ return DFENUM_OK;
+}
+
+/*
+ * internal function that installs the cursor window
+ * and fills it with data from 'cursor.dat'
+ */
+static DFBResult
+load_default_cursor( CoreDFB *core, CoreWindowStack *stack )
+{
+ DFBResult ret;
+ int i;
+ FILE *f;
+ CoreSurfaceBufferLock lock;
+ void *data;
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p )\n", __FUNCTION__, stack );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ if (!stack->cursor.surface) {
+ ret = create_cursor_surface( stack, 40, 40 );
+ if (ret)
+ return ret;
+ }
+ else {
+ stack->cursor.hot.x = 0;
+ stack->cursor.hot.y = 0;
+ stack->cursor.size.w = 40;
+ stack->cursor.size.h = 40;
+ }
+
+ /* lock the cursor surface */
+ ret = dfb_surface_lock_buffer( stack->cursor.surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock );
+ if (ret) {
+ D_ERROR( "Core/WindowStack: cannot lock the cursor surface!\n" );
+ return ret;
+ }
+
+ data = lock.addr;
+
+ /* initialize as empty cursor */
+ memset( data, 0, 40 * lock.pitch );
+
+ /* open the file containing the cursors image data */
+ f = fopen( CURSORFILE, "rb" );
+ if (!f) {
+ ret = errno2result( errno );
+
+ /* ignore a missing cursor file */
+ if (ret == DFB_FILENOTFOUND)
+ ret = DFB_OK;
+ else
+ D_PERROR( "Core/WindowStack: `" CURSORFILE "` could not be opened!\n" );
+
+ goto finish;
+ }
+
+ /* read from file directly into the cursor window surface */
+ for (i=0; i<40; i++) {
+ if (fread( data, MIN (40*4, lock.pitch), 1, f ) != 1) {
+ ret = errno2result( errno );
+
+ D_ERROR( "Core/WindowStack: unexpected end or read error of cursor data!\n" );
+
+ goto finish;
+ }
+#ifdef WORDS_BIGENDIAN
+ {
+ int i = MIN (40, lock.pitch/4);
+ u32 *tmp_data = data;
+
+ while (i--) {
+ *tmp_data = (*tmp_data & 0xFF000000) >> 24 |
+ (*tmp_data & 0x00FF0000) >> 8 |
+ (*tmp_data & 0x0000FF00) << 8 |
+ (*tmp_data & 0x000000FF) << 24;
+ ++tmp_data;
+ }
+ }
+#endif
+ data += lock.pitch;
+ }
+
+finish:
+ if (f)
+ fclose( f );
+
+ dfb_surface_unlock_buffer( stack->cursor.surface, &lock );
+
+ return ret;
+}
+
+static DFBResult
+create_cursor_surface( CoreWindowStack *stack,
+ int width,
+ int height )
+{
+ DFBResult ret;
+ CoreSurface *surface;
+ CoreLayer *layer;
+ CoreLayerContext *context;
+ DFBSurfaceCapabilities surface_caps = DSCAPS_NONE;
+
+ D_DEBUG_AT( Core_WindowStack, "%s( %p, %dx%d )\n", __FUNCTION__, stack, width, height );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->cursor.surface == NULL );
+
+ context = stack->context;
+
+ D_ASSERT( context != NULL );
+
+ layer = dfb_layer_at( context->layer_id );
+
+ D_ASSERT( layer != NULL );
+
+ stack->cursor.x = stack->width / 2;
+ stack->cursor.y = stack->height / 2;
+ stack->cursor.hot.x = 0;
+ stack->cursor.hot.y = 0;
+ stack->cursor.size.w = width;
+ stack->cursor.size.h = height;
+
+ if (context->config.buffermode == DLBM_WINDOWS)
+ D_WARN( "cursor not yet visible with DLBM_WINDOWS" );
+
+ dfb_surface_caps_apply_policy( stack->cursor.policy, &surface_caps );
+
+ /* Create the cursor surface. */
+ ret = dfb_surface_create_simple( layer->core, width, height, DSPF_ARGB,
+ surface_caps, CSTF_SHARED | CSTF_CURSOR,
+ 0, /* FIXME: no shared cursor objects, no cursor id */
+ NULL, &surface );
+ if (ret) {
+ D_ERROR( "Core/WindowStack: Failed creating a surface for software cursor!\n" );
+ return ret;
+ }
+
+ dfb_surface_globalize( surface );
+
+ stack->cursor.surface = surface;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/core/windowstack.h b/Source/DirectFB/src/core/windowstack.h
new file mode 100755
index 0000000..6d7bed5
--- /dev/null
+++ b/Source/DirectFB/src/core/windowstack.h
@@ -0,0 +1,105 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CORE__WINDOWSTACK_H__
+#define __CORE__WINDOWSTACK_H__
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <fusion/lock.h>
+
+/*
+ * allocates a WindowStack, initializes it, registers it for input events
+ */
+CoreWindowStack *dfb_windowstack_create ( CoreLayerContext *context );
+
+void dfb_windowstack_detach_devices( CoreWindowStack *stack );
+
+void dfb_windowstack_destroy( CoreWindowStack *stack );
+
+void dfb_windowstack_resize ( CoreWindowStack *stack,
+ int width,
+ int height,
+ int rotation );
+
+DirectResult dfb_windowstack_lock ( CoreWindowStack *stack );
+
+DirectResult dfb_windowstack_unlock ( CoreWindowStack *stack );
+
+/*
+ * repaints all window on a window stack
+ */
+DFBResult dfb_windowstack_repaint_all( CoreWindowStack *stack );
+
+/*
+ * background handling
+ */
+DFBResult dfb_windowstack_set_background_mode ( CoreWindowStack *stack,
+ DFBDisplayLayerBackgroundMode mode );
+
+DFBResult dfb_windowstack_set_background_image( CoreWindowStack *stack,
+ CoreSurface *image );
+
+DFBResult dfb_windowstack_set_background_color( CoreWindowStack *stack,
+ const DFBColor *color );
+
+DFBResult dfb_windowstack_set_background_color_index( CoreWindowStack *stack,
+ int index );
+
+
+/*
+ * cursor control
+ */
+DFBResult dfb_windowstack_cursor_enable( CoreDFB *core,
+ CoreWindowStack *stack,
+ bool enable );
+
+DFBResult dfb_windowstack_cursor_set_shape( CoreWindowStack *stack,
+ CoreSurface *shape,
+ int hot_x,
+ int hot_y );
+
+DFBResult dfb_windowstack_cursor_set_opacity( CoreWindowStack *stack,
+ u8 opacity );
+
+DFBResult dfb_windowstack_cursor_set_acceleration( CoreWindowStack *stack,
+ int numerator,
+ int denominator,
+ int threshold );
+
+DFBResult dfb_windowstack_cursor_warp( CoreWindowStack *stack,
+ int x,
+ int y );
+
+
+DFBResult dfb_windowstack_get_cursor_position (CoreWindowStack *stack,
+ int *x,
+ int *y);
+
+#endif
diff --git a/Source/DirectFB/src/core/wm.c b/Source/DirectFB/src/core/wm.c
new file mode 100755
index 0000000..fb9148c
--- /dev/null
+++ b/Source/DirectFB/src/core/wm.c
@@ -0,0 +1,1440 @@
+/*
+ (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 <string.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/modules.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/core_parts.h>
+#include <core/layer_context.h>
+#include <core/layers_internal.h>
+#include <core/windowstack.h>
+#include <core/windows_internal.h>
+#include <core/wm.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+
+DEFINE_MODULE_DIRECTORY( dfb_core_wm_modules, "wm", DFB_CORE_WM_ABI_VERSION );
+
+
+D_DEBUG_DOMAIN( Core_WM, "Core/WM", "DirectFB WM Core" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+ DirectLink *stacks;
+
+ int abi;
+
+ char *name;
+ CoreWMInfo info;
+ void *data;
+
+ FusionSHMPoolShared *shmpool;
+
+ FusionReactor *reactor;
+} DFBWMCoreShared;
+
+struct __DFB_DFBWMCore {
+ int magic;
+
+ CoreDFB *core;
+
+ DFBWMCoreShared *shared;
+
+
+ DirectModuleEntry *module;
+ const CoreWMFuncs *funcs;
+ void *data;
+};
+
+
+DFB_CORE_PART( wm_core, WMCore );
+
+/**********************************************************************************************************************/
+
+static DFBResult load_module( const char *name );
+
+/**********************************************************************************************************************/
+
+static DFBWMCore *wm_local = NULL; /* FIXME */
+static DFBWMCoreShared *wm_shared = NULL; /* FIXME */
+
+
+static DFBResult
+dfb_wm_core_initialize( CoreDFB *core,
+ DFBWMCore *data,
+ DFBWMCoreShared *shared )
+{
+ DFBResult ret;
+
+ D_DEBUG_AT( Core_WM, "dfb_wm_core_initialize( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( shared != NULL );
+
+ data->core = core;
+ data->shared = shared;
+
+
+ wm_local = data; /* FIXME */
+ wm_shared = shared; /* FIXME */
+
+ wm_shared->shmpool = dfb_core_shmpool( core );
+
+ /* Set ABI version for the session. */
+ wm_shared->abi = DFB_CORE_WM_ABI_VERSION;
+
+ /* Load the module. */
+ ret = load_module( dfb_config->wm );
+ if (ret)
+ goto error;
+
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->GetWMInfo != NULL );
+ D_ASSERT( wm_local->funcs->Initialize != NULL );
+
+ /* Query module information. */
+ wm_local->funcs->GetWMInfo( &wm_shared->info );
+
+ D_INFO( "DirectFB/Core/WM: %s %d.%d (%s)\n",
+ wm_shared->info.name, wm_shared->info.version.major,
+ wm_shared->info.version.minor, wm_shared->info.vendor );
+
+ ret = DFB_NOSHAREDMEMORY;
+
+ /* Store module name in shared memory. */
+ wm_shared->name = SHSTRDUP( wm_shared->shmpool, wm_local->module->name );
+ if (!wm_shared->name) {
+ D_OOSHM();
+ goto error;
+ }
+
+ /* Allocate shared window manager data. */
+ if (wm_shared->info.wm_shared_size) {
+ wm_shared->data = SHCALLOC( wm_shared->shmpool, 1, wm_shared->info.wm_shared_size );
+ if (!wm_shared->data) {
+ D_OOSHM();
+ goto error;
+ }
+ }
+
+ ret = DFB_NOSYSTEMMEMORY;
+
+ /* Allocate local window manager data. */
+ if (wm_shared->info.wm_data_size) {
+ wm_local->data = D_CALLOC( 1, wm_shared->info.wm_data_size );
+ if (!wm_local->data) {
+ D_OOM();
+ goto error;
+ }
+ }
+
+ wm_shared->reactor = fusion_reactor_new( 0, "WM", dfb_core_world(core) );
+
+ /* Initialize window manager. */
+ ret = wm_local->funcs->Initialize( core, wm_local->data, wm_shared->data );
+ if (ret) {
+ D_DERROR( ret, "DirectFB/Core/WM: Could not initialize window manager!\n" );
+ goto error;
+ }
+
+ D_MAGIC_SET( data, DFBWMCore );
+ D_MAGIC_SET( shared, DFBWMCoreShared );
+
+ return DFB_OK;
+
+error:
+ if (wm_local->data)
+ D_FREE( wm_local->data );
+
+ if (wm_shared->data)
+ SHFREE( wm_shared->shmpool, wm_shared->data );
+
+ if (wm_shared->name)
+ SHFREE( wm_shared->shmpool, wm_shared->name );
+
+ wm_local = NULL;
+ wm_shared = NULL;
+
+ return ret;
+}
+
+static DFBResult
+dfb_wm_core_join( CoreDFB *core,
+ DFBWMCore *data,
+ DFBWMCoreShared *shared )
+{
+ DFBResult ret;
+ CoreWMInfo info;
+
+ D_DEBUG_AT( Core_WM, "dfb_wm_core_join( %p, %p, %p )\n", core, data, shared );
+
+ D_ASSERT( data != NULL );
+ D_MAGIC_ASSERT( shared, DFBWMCoreShared );
+
+ data->core = core;
+ data->shared = shared;
+
+
+ wm_local = data; /* FIXME */
+ wm_shared = shared; /* FIXME */
+
+ /* Check binary version numbers. */
+ if (wm_shared->abi != DFB_CORE_WM_ABI_VERSION) {
+ D_ERROR( "DirectFB/Core/WM: ABI version of running core instance (%d) doesn't match %d!\n",
+ wm_shared->abi, DFB_CORE_WM_ABI_VERSION );
+ ret = DFB_VERSIONMISMATCH;
+ goto error;
+ }
+
+ /* Load the module that is used by the running session. */
+ ret = load_module( wm_shared->name );
+ if (ret)
+ goto error;
+
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->GetWMInfo != NULL );
+ D_ASSERT( wm_local->funcs->Join != NULL );
+
+ /* Query module information. */
+ wm_local->funcs->GetWMInfo( &info );
+
+ /* Check binary version numbers. */
+ if (info.version.binary != wm_shared->info.version.binary) {
+ D_ERROR( "DirectFB/Core/WM: ABI version of running module instance (%d) doesn't match %d!\n",
+ wm_shared->info.version.binary, info.version.binary );
+ ret = DFB_VERSIONMISMATCH;
+ goto error;
+ }
+
+ /* Allocate window manager data. */
+ if (wm_shared->info.wm_data_size) {
+ wm_local->data = D_CALLOC( 1, wm_shared->info.wm_data_size );
+ if (!wm_local->data) {
+ D_WARN( "out of memory" );
+ ret = DFB_NOSYSTEMMEMORY;
+ goto error;
+ }
+ }
+
+ /* Join window manager. */
+ ret = wm_local->funcs->Join( core, wm_local->data, wm_shared->data );
+ if (ret) {
+ D_DERROR( ret, "DirectFB/Core/WM: Could not join window manager!\n" );
+ goto error;
+ }
+
+ D_MAGIC_SET( data, DFBWMCore );
+
+ return DFB_OK;
+
+error:
+ if (wm_local->data)
+ D_FREE( wm_local->data );
+
+ wm_local = NULL;
+ wm_shared = NULL;
+
+ return ret;
+}
+
+static DFBResult
+dfb_wm_core_shutdown( DFBWMCore *data,
+ bool emergency )
+{
+ DFBResult ret;
+ DFBWMCoreShared *shared;
+
+ D_DEBUG_AT( Core_WM, "dfb_wm_core_shutdown( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBWMCore );
+ D_MAGIC_ASSERT( data->shared, DFBWMCoreShared );
+
+ shared = data->shared;
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->Shutdown != NULL );
+ D_ASSERT( wm_shared != NULL );
+
+ fusion_reactor_destroy( wm_shared->reactor );
+
+ /* Shutdown window manager. */
+ ret = wm_local->funcs->Shutdown( emergency, wm_local->data, wm_shared->data );
+
+ /* Unload the module. */
+ direct_module_unref( wm_local->module );
+
+ /* Deallocate local window manager data. */
+ if (wm_local->data)
+ D_FREE( wm_local->data );
+
+ /* Deallocate shared window manager data. */
+ if (wm_shared->data)
+ SHFREE( wm_shared->shmpool, wm_shared->data );
+
+ /* Free module name in shared memory. */
+ SHFREE( wm_shared->shmpool, wm_shared->name );
+
+ wm_local = NULL;
+ wm_shared = NULL;
+
+
+ D_MAGIC_CLEAR( data );
+ D_MAGIC_CLEAR( shared );
+
+ return ret;
+}
+
+static DFBResult
+dfb_wm_core_leave( DFBWMCore *data,
+ bool emergency )
+{
+ DFBResult ret;
+ DFBWMCoreShared *shared;
+
+ D_DEBUG_AT( Core_WM, "dfb_wm_core_leave( %p, %semergency )\n", data, emergency ? "" : "no " );
+
+ D_MAGIC_ASSERT( data, DFBWMCore );
+ D_MAGIC_ASSERT( data->shared, DFBWMCoreShared );
+
+ shared = data->shared;
+
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->Leave != NULL );
+ D_ASSERT( wm_shared != NULL );
+
+ /* Leave window manager. */
+ ret = wm_local->funcs->Leave( emergency, wm_local->data, wm_shared->data );
+
+ /* Unload the module. */
+ direct_module_unref( wm_local->module );
+
+ /* Deallocate local window manager data. */
+ if (wm_local->data)
+ D_FREE( wm_local->data );
+
+ wm_local = NULL;
+ wm_shared = NULL;
+
+
+ D_MAGIC_CLEAR( data );
+
+ return ret;
+}
+
+static DFBResult
+dfb_wm_core_suspend( DFBWMCore *data )
+{
+ DFBWMCoreShared *shared;
+
+ D_DEBUG_AT( Core_WM, "%s( %p )\n", __FUNCTION__, data );
+
+ D_MAGIC_ASSERT( data, DFBWMCore );
+ D_MAGIC_ASSERT( data->shared, DFBWMCoreShared );
+
+ shared = data->shared;
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->Suspend != NULL );
+ D_ASSERT( wm_shared != NULL );
+
+ return wm_local->funcs->Suspend( wm_local->data, wm_shared->data );
+}
+
+static DFBResult
+dfb_wm_core_resume( DFBWMCore *data )
+{
+ DFBWMCoreShared *shared;
+
+ D_DEBUG_AT( Core_WM, "%s( %p )\n", __FUNCTION__, data );
+
+ D_MAGIC_ASSERT( data, DFBWMCore );
+ D_MAGIC_ASSERT( data->shared, DFBWMCoreShared );
+
+ shared = data->shared;
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->Resume != NULL );
+ D_ASSERT( wm_shared != NULL );
+
+ return wm_local->funcs->Resume( wm_local->data, wm_shared->data );
+}
+
+DFBResult
+dfb_wm_close_all_stacks( void *data )
+{
+ CoreLayerContext *context;
+ CoreWindowStack *stack, *next;
+ DFBWMCore *local;
+ DFBWMCoreShared *shared;
+
+ D_DEBUG_AT( Core_WM, "%s( %p )\n", __FUNCTION__, data );
+
+ local = data;
+
+ D_MAGIC_ASSERT( local, DFBWMCore );
+ D_ASSERT( local->funcs != NULL );
+ D_ASSERT( local->funcs->CloseStack != NULL );
+
+ shared = local->shared;
+
+ D_MAGIC_ASSERT( shared, DFBWMCoreShared );
+
+ D_DEBUG_AT( Core_WM, " -> checking %d stacks...\n", direct_list_count_elements_EXPENSIVE(shared->stacks) );
+
+ direct_list_foreach_safe (stack, next, shared->stacks) {
+ D_DEBUG_AT( Core_WM, " -> checking %p...\n", stack );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ context = stack->context;
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ D_DEBUG_AT( Core_WM, " -> ref context %p...\n", context );
+
+ dfb_layer_context_ref( context );
+
+ dfb_layer_context_lock( context );
+
+ if (stack->flags & CWSF_INITIALIZED) {
+ D_DEBUG_AT( Core_WM, " => CLOSING %p\n", stack );
+ dfb_wm_close_stack( stack );
+ }
+
+ dfb_layer_context_unlock( context );
+
+ D_DEBUG_AT( Core_WM, " -> unref context %p...\n", context );
+
+ dfb_layer_context_unref( context );
+ }
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+load_module( const char *name )
+{
+ DirectLink *l;
+
+ D_ASSERT( wm_local != NULL );
+
+ direct_modules_explore_directory( &dfb_core_wm_modules );
+
+ direct_list_foreach( l, dfb_core_wm_modules.entries ) {
+ DirectModuleEntry *module = (DirectModuleEntry*) l;
+ const CoreWMFuncs *funcs;
+
+ funcs = direct_module_ref( module );
+ if (!funcs)
+ continue;
+
+ if (!name || !strcasecmp( name, module->name )) {
+ if (wm_local->module)
+ direct_module_unref( wm_local->module );
+
+ wm_local->module = module;
+ wm_local->funcs = funcs;
+ }
+ else
+ direct_module_unref( module );
+ }
+
+ if (!wm_local->module) {
+ if (name)
+ D_ERROR( "DirectFB/WM: Window manager module '%s' not found!\n", name );
+ else
+ D_ERROR( "DirectFB/WM: No window manager module found!\n" );
+
+ return DFB_NOIMPL;
+ }
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static void
+convert_config( DFBWindowConfig *config,
+ const CoreWindowConfig *from )
+{
+ config->bounds = from->bounds;
+ config->opacity = from->opacity;
+ config->stacking = from->stacking;
+ config->options = from->options;
+ config->events = from->events;
+ config->color = from->color;
+ config->color_key = from->color_key;
+ config->opaque = from->opaque;
+// config->key_selection = DWKS_ALL; // FIXME: implement
+// config->keys = NULL; // FIXME: implement
+// config->num_keys = 0; // FIXME: implement
+ config->association = from->association;
+ config->src_geometry = from->src_geometry;
+ config->dst_geometry = from->dst_geometry;
+ config->cursor_flags = from->cursor_flags;
+ config->cursor_resolution = from->cursor_resolution;
+}
+
+static void
+convert_state( DFBWindowState *state,
+ const CoreWindowFlags flags )
+{
+ state->flags = DWSTATE_NONE;
+
+ if (flags & CWF_INSERTED)
+ state->flags |= DWSTATE_INSERTED;
+
+ if (flags & CWF_FOCUSED)
+ state->flags |= DWSTATE_FOCUSED;
+
+ if (flags & CWF_ENTERED)
+ state->flags |= DWSTATE_ENTERED;
+}
+
+/**************************************************************************************************/
+
+typedef struct {
+ ReactionFunc func;
+ void *ctx;
+} AttachContext;
+
+static DFBEnumerationResult
+wm_window_attach_callback( CoreWindow *window,
+ void *ctx )
+{
+ AttachContext *context = ctx;
+
+ CoreWM_WindowAdd add;
+
+ add.info.window_id = window->id;
+ add.info.caps = window->caps;
+ add.info.resource_id = window->resource_id;
+
+ convert_config( &add.info.config, &window->config );
+
+ convert_state( &add.info.state, window->flags );
+
+ context->func( &add, context->ctx );
+
+ return DFENUM_OK;
+}
+
+DFBResult
+dfb_wm_attach( CoreDFB *core,
+ int channel,
+ ReactionFunc func,
+ void *ctx,
+ Reaction *reaction )
+{
+ D_ASSERT( wm_shared != NULL );
+
+ if (channel == CORE_WM_WINDOW_ADD) {
+ CoreWindowStack *stack = (CoreWindowStack *) wm_shared->stacks;
+
+ if (stack) {
+ DFBResult ret;
+ AttachContext context = { func, ctx };
+
+ dfb_windowstack_lock( stack );
+
+ ret = dfb_wm_enum_windows( stack, wm_window_attach_callback, &context );
+ if (ret)
+ D_WARN( "could not enumerate windows" );
+
+ ret = fusion_reactor_attach_channel( wm_shared->reactor, channel, func, ctx, reaction );
+
+ dfb_windowstack_unlock( stack );
+
+ return ret;
+ }
+ }
+
+ return fusion_reactor_attach_channel( wm_shared->reactor, channel, func, ctx, reaction );
+}
+
+DFBResult
+dfb_wm_detach( CoreDFB *core,
+ Reaction *reaction )
+{
+ D_ASSERT( wm_shared != NULL );
+
+ return fusion_reactor_detach( wm_shared->reactor, reaction );
+}
+
+DFBResult
+dfb_wm_dispatch( CoreDFB *core,
+ int channel,
+ const void *data,
+ int size )
+{
+ D_ASSERT( wm_shared != NULL );
+
+ return fusion_reactor_dispatch_channel( wm_shared->reactor, channel, data, size, true, NULL );
+}
+
+DFBResult
+dfb_wm_dispatch_WindowAdd( CoreDFB *core,
+ CoreWindow *window )
+{
+ CoreWM_WindowAdd add;
+
+ add.info.window_id = window->id;
+ add.info.caps = window->caps;
+ add.info.resource_id = window->resource_id;
+
+ convert_config( &add.info.config, &window->config );
+
+ convert_state( &add.info.state, window->flags );
+
+ return dfb_wm_dispatch( core, CORE_WM_WINDOW_ADD, &add, sizeof(add) );
+}
+
+DFBResult
+dfb_wm_dispatch_WindowRemove( CoreDFB *core,
+ CoreWindow *window )
+{
+ CoreWM_WindowRemove remove;
+
+ remove.window_id = window->id;
+
+ return dfb_wm_dispatch( core, CORE_WM_WINDOW_REMOVE, &remove, sizeof(remove) );
+}
+
+DFBResult
+dfb_wm_dispatch_WindowConfig( CoreDFB *core,
+ CoreWindow *window,
+ DFBWindowConfigFlags flags )
+{
+ CoreWM_WindowConfig config;
+
+ config.window_id = window->id;
+ config.flags = flags;
+
+ convert_config( &config.config, &window->config );
+
+ return dfb_wm_dispatch( core, CORE_WM_WINDOW_CONFIG, &config, sizeof(config) );
+}
+
+DFBResult
+dfb_wm_dispatch_WindowState( CoreDFB *core,
+ CoreWindow *window )
+{
+ CoreWM_WindowState state;
+
+ state.window_id = window->id;
+
+ convert_state( &state.state, window->flags );
+
+ return dfb_wm_dispatch( core, CORE_WM_WINDOW_STATE, &state, sizeof(state) );
+}
+
+DFBResult
+dfb_wm_dispatch_WindowRestack( CoreDFB *core,
+ CoreWindow *window,
+ unsigned int index )
+{
+ CoreWM_WindowRestack restack;
+
+ restack.window_id = window->id;
+ restack.index = index;
+
+ return dfb_wm_dispatch( core, CORE_WM_WINDOW_RESTACK, &restack, sizeof(restack) );
+}
+
+DFBResult
+dfb_wm_dispatch_WindowFocus( CoreDFB *core,
+ CoreWindow *window )
+{
+ CoreWM_WindowFocus focus;
+
+ focus.window_id = window->id;
+
+ return dfb_wm_dispatch( core, CORE_WM_WINDOW_FOCUS, &focus, sizeof(focus) );
+}
+
+/**************************************************************************************************/
+
+void
+dfb_wm_get_info( CoreWMInfo *info )
+{
+ D_ASSERT( wm_shared != NULL );
+
+ D_ASSERT( info != NULL );
+
+ *info = wm_shared->info;
+}
+
+DFBResult
+dfb_wm_post_init( CoreDFB *core )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->Resume != NULL );
+ D_ASSERT( wm_shared != NULL );
+
+ return wm_local->funcs->PostInit( wm_local->data, wm_shared->data );
+}
+
+/**************************************************************************************************/
+
+DFBResult
+dfb_wm_init_stack( CoreWindowStack *stack )
+{
+ DFBResult ret;
+
+ D_DEBUG_AT( Core_WM, "%s( %p )\n", __FUNCTION__, stack );
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->InitStack != NULL );
+ D_ASSERT( wm_shared != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( !(stack->flags & CWSF_INITIALIZED) );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ /* Allocate shared stack data. */
+ if (wm_shared->info.stack_data_size) {
+ if (stack->stack_data)
+ SHFREE( stack->shmpool, stack->stack_data );
+
+ stack->stack_data = SHCALLOC( stack->shmpool, 1, wm_shared->info.stack_data_size );
+ if (!stack->stack_data) {
+ D_WARN( "out of (shared) memory" );
+ return D_OOSHM();
+ }
+ }
+
+ /* Window manager specific initialization. */
+ ret = wm_local->funcs->InitStack( stack, wm_local->data, stack->stack_data );
+ if (ret) {
+ if (stack->stack_data) {
+ SHFREE( wm_shared->shmpool, stack->stack_data );
+ stack->stack_data = NULL;
+ }
+
+ return ret;
+ }
+
+ stack->flags |= CWSF_INITIALIZED;
+
+ /* Add window stack to list. */
+ direct_list_append( &wm_shared->stacks, &stack->link );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_wm_close_stack( CoreWindowStack *stack )
+{
+ D_DEBUG_AT( Core_WM, "%s( %p )\n", __FUNCTION__, stack );
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->CloseStack != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ D_ASSUME( stack->flags & CWSF_INITIALIZED );
+
+ if (!(stack->flags & CWSF_INITIALIZED)) {
+ D_ASSUME( !(stack->flags & CWSF_ACTIVATED) );
+ return DFB_OK;
+ }
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ /* Deactivate before deinitialization. */
+ if (stack->flags & CWSF_ACTIVATED)
+ dfb_wm_set_active( stack, false );
+
+ /*
+ * Clear flag and remove stack first, because
+ * CloseStack() may cause the stack to be destroyed!
+ */
+ stack->flags &= ~CWSF_INITIALIZED;
+
+ /* Remove window stack from list. */
+ direct_list_remove( &wm_shared->stacks, &stack->link );
+
+ /* Window manager specific deinitialization. */
+ return wm_local->funcs->CloseStack( stack, wm_local->data, stack->stack_data );
+}
+
+DFBResult
+dfb_wm_set_active( CoreWindowStack *stack,
+ bool active )
+{
+ DFBResult ret;
+
+ D_DEBUG_AT( Core_WM, "%s( %p, %sactive )\n", __FUNCTION__, stack, active ? "" : "in" );
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->SetActive != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ if (active) {
+ D_ASSUME( !(stack->flags & CWSF_ACTIVATED) );
+
+ if (stack->flags & CWSF_ACTIVATED)
+ return DFB_OK;
+
+ ret = wm_local->funcs->SetActive( stack, wm_local->data, stack->stack_data, true );
+
+ stack->flags |= CWSF_ACTIVATED;
+ }
+ else {
+ D_ASSUME( stack->flags & CWSF_ACTIVATED );
+
+ if (!(stack->flags & CWSF_ACTIVATED))
+ return DFB_OK;
+
+ ret = wm_local->funcs->SetActive( stack, wm_local->data, stack->stack_data, false );
+
+ stack->flags &= ~CWSF_ACTIVATED;
+ }
+
+ return ret;
+}
+
+DFBResult
+dfb_wm_resize_stack( CoreWindowStack *stack,
+ int width,
+ int height )
+{
+ D_DEBUG_AT( Core_WM, "%s( %p, %dx%d )\n", __FUNCTION__, stack, width, height );
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->ResizeStack != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ /* Notify window manager about the new size. */
+ return wm_local->funcs->ResizeStack( stack, wm_local->data, stack->stack_data, width, height );
+}
+
+DFBResult
+dfb_wm_process_input( CoreWindowStack *stack,
+ const DFBInputEvent *event )
+{
+ D_DEBUG_AT( Core_WM, "%s( %p, %p )\n", __FUNCTION__, stack, event );
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->ProcessInput != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_ASSERT( event != NULL );
+
+ /* Dispatch input event via window manager. */
+ return wm_local->funcs->ProcessInput( stack, wm_local->data, stack->stack_data, event );
+}
+
+DFBResult
+dfb_wm_flush_keys( CoreWindowStack *stack )
+{
+ D_DEBUG_AT( Core_WM, "%s( %p )\n", __FUNCTION__, stack );
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->FlushKeys != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ return wm_local->funcs->FlushKeys( stack, wm_local->data, stack->stack_data );
+}
+
+DFBResult
+dfb_wm_window_at( CoreWindowStack *stack,
+ int x,
+ int y,
+ CoreWindow **ret_window )
+{
+ D_DEBUG_AT( Core_WM, "%s( %p, %d,%d )\n", __FUNCTION__, stack, x, y );
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->WindowAt != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_ASSERT( ret_window != NULL );
+
+ return wm_local->funcs->WindowAt( stack, wm_local->data, stack->stack_data, x, y, ret_window );
+}
+
+DFBResult
+dfb_wm_window_lookup( CoreWindowStack *stack,
+ DFBWindowID window_id,
+ CoreWindow **ret_window )
+{
+ D_DEBUG_AT( Core_WM, "%s( %p, %u )\n", __FUNCTION__, stack, window_id );
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->WindowLookup != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_ASSERT( ret_window != NULL );
+
+ return wm_local->funcs->WindowLookup( stack, wm_local->data,
+ stack->stack_data, window_id, ret_window );
+}
+
+DFBResult
+dfb_wm_enum_windows( CoreWindowStack *stack,
+ CoreWMWindowCallback callback,
+ void *callback_ctx )
+{
+ D_DEBUG_AT( Core_WM, "%s( %p, %p, %p )\n", __FUNCTION__, stack, callback, callback_ctx );
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->EnumWindows != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_ASSERT( callback != NULL );
+
+ return wm_local->funcs->EnumWindows( stack, wm_local->data,
+ stack->stack_data, callback, callback_ctx );
+}
+
+/**
+ * Give the wm a chance to specifiy a border
+ */
+DFBResult
+dfb_wm_get_insets( CoreWindowStack *stack,
+ CoreWindow *window,
+ DFBInsets *insets)
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->GetInsets != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( insets != NULL );
+
+ return wm_local->funcs->GetInsets( stack, window, insets );
+}
+
+/**
+ * Give the wm a chance to override the windows configuration
+ */
+DFBResult
+dfb_wm_preconfigure_window( CoreWindowStack *stack,
+ CoreWindow *window )
+{
+ DFBResult ret;
+ void *window_data = NULL;
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_shared != NULL );
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_local->funcs->PreConfigureWindow != NULL );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_DEBUG_AT( Core_WM, "%s( %p, %p [%d,%d-%dx%d] )\n", __FUNCTION__,
+ stack, window, DFB_RECTANGLE_VALS(&window->config.bounds) );
+
+ /* Allocate shared window data. */
+ if (wm_shared->info.window_data_size) {
+ window_data = SHCALLOC( wm_shared->shmpool, 1, wm_shared->info.window_data_size );
+ if (!window_data) {
+ D_WARN( "out of (shared) memory" );
+ return D_OOSHM();
+ }
+ }
+
+ /* Keep shared window data. */
+ window->window_data = window_data;
+
+ /* Tell window manager about the new window. */
+ ret = wm_local->funcs->PreConfigureWindow( stack, wm_local->data,
+ stack->stack_data, window, window_data );
+ if (ret) {
+ if (window_data) {
+ SHFREE( wm_shared->shmpool, window_data );
+ window->window_data = NULL;
+ }
+
+ return ret;
+ }
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_wm_add_window( CoreWindowStack *stack,
+ CoreWindow *window )
+{
+ DFBResult ret;
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->AddWindow != NULL );
+ D_ASSERT( wm_shared != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_ASSERT( window != NULL );
+
+ D_DEBUG_AT( Core_WM, "%s( %p, %p [%d,%d-%dx%d] )\n", __FUNCTION__,
+ stack, window, DFB_RECTANGLE_VALS(&window->config.bounds) );
+
+ /* Tell window manager about the new window. */
+ ret = wm_local->funcs->AddWindow( stack, wm_local->data,
+ stack->stack_data, window, window->window_data );
+ if (ret) {
+ if (window->window_data)
+ SHFREE( wm_shared->shmpool, window->window_data );
+ return ret;
+ }
+ return DFB_OK;
+}
+
+DFBResult
+dfb_wm_remove_window( CoreWindowStack *stack,
+ CoreWindow *window )
+{
+ DFBResult ret;
+
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->RemoveWindow != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_ASSERT( window != NULL );
+
+ D_DEBUG_AT( Core_WM, "%s( %p, %p [%d,%d-%dx%d] )\n", __FUNCTION__,
+ stack, window, DFB_RECTANGLE_VALS(&window->config.bounds) );
+
+ /* Remove window from window manager. */
+ ret = wm_local->funcs->RemoveWindow( stack, wm_local->data,
+ stack->stack_data, window, window->window_data );
+
+ /* Deallocate shared stack data. */
+ if (window->window_data)
+ SHFREE( wm_shared->shmpool, window->window_data );
+
+ return ret;
+}
+
+/**
+ * Let the wm set a property on a window
+ */
+DFBResult
+dfb_wm_set_window_property( CoreWindowStack *stack,
+ CoreWindow *window,
+ const char *key,
+ void *value,
+ void **ret_old_value )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->SetWindowProperty != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( key != NULL );
+
+ D_DEBUG_AT( Core_WM, "%s( %p, %p [%d,%d-%dx%d], '%s' = %p )\n", __FUNCTION__,
+ stack, window, DFB_RECTANGLE_VALS(&window->config.bounds), key, value );
+
+ return wm_local->funcs->SetWindowProperty( stack, wm_local->data, stack->stack_data,
+ window, window->window_data,
+ key, value, ret_old_value );
+}
+
+/**
+ * get the wm property on a window
+ */
+DFBResult
+dfb_wm_get_window_property( CoreWindowStack *stack,
+ CoreWindow *window,
+ const char *key,
+ void **ret_value )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->GetWindowProperty != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( key != NULL );
+
+ D_DEBUG_AT( Core_WM, "%s( %p, %p [%d,%d-%dx%d], '%s' )\n", __FUNCTION__,
+ stack, window, DFB_RECTANGLE_VALS(&window->config.bounds), key );
+
+ return wm_local->funcs->GetWindowProperty( stack, wm_local->data, stack->stack_data,
+ window, window->window_data, key, ret_value );
+}
+
+/**
+ * remove th wm property on a window
+ */
+DFBResult
+dfb_wm_remove_window_property( CoreWindowStack *stack,
+ CoreWindow *window,
+ const char *key,
+ void **ret_value )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->RemoveWindowProperty != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( key != NULL );
+
+ D_DEBUG_AT( Core_WM, "%s( %p, %p [%d,%d-%dx%d], '%s' )\n", __FUNCTION__,
+ stack, window, DFB_RECTANGLE_VALS(&window->config.bounds), key );
+
+ return wm_local->funcs->RemoveWindowProperty( stack, wm_local->data, stack->stack_data,
+ window, window->window_data, key, ret_value );
+}
+
+DFBResult
+dfb_wm_set_window_config( CoreWindow *window,
+ const CoreWindowConfig *config,
+ CoreWindowConfigFlags flags )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->SetWindowConfig != NULL );
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( config != NULL );
+
+ D_MAGIC_ASSERT( window->stack, CoreWindowStack );
+ D_MAGIC_ASSERT( window->stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &window->stack->context->lock );
+
+ D_DEBUG_AT( Core_WM, "%s( %p [%d,%d-%dx%d], %p, 0x%x )\n", __FUNCTION__,
+ window, DFB_RECTANGLE_VALS(&window->config.bounds), config, flags );
+
+ return wm_local->funcs->SetWindowConfig( window, wm_local->data,
+ window->window_data, config, flags );
+}
+
+DFBResult
+dfb_wm_restack_window( CoreWindow *window,
+ CoreWindow *relative,
+ int relation )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->RestackWindow != NULL );
+
+ D_ASSERT( window != NULL );
+
+ D_MAGIC_ASSERT( window->stack, CoreWindowStack );
+ D_MAGIC_ASSERT( window->stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &window->stack->context->lock );
+
+ D_ASSERT( relative == NULL || relative == window || relation != 0);
+
+ D_DEBUG_AT( Core_WM, "%s( %p [%d,%d-%dx%d], %p, %d )\n", __FUNCTION__,
+ window, DFB_RECTANGLE_VALS(&window->config.bounds), relative, relation );
+
+ return wm_local->funcs->RestackWindow( window, wm_local->data, window->window_data, relative,
+ relative ? relative->window_data : NULL, relation );
+}
+
+DFBResult
+dfb_wm_grab( CoreWindow *window,
+ CoreWMGrab *grab )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->Grab != NULL );
+
+ D_ASSERT( window != NULL );
+
+ D_MAGIC_ASSERT( window->stack, CoreWindowStack );
+ D_MAGIC_ASSERT( window->stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &window->stack->context->lock );
+
+ D_ASSERT( grab != NULL );
+
+ D_DEBUG_AT( Core_WM, "%s( %p [%d,%d-%dx%d], %d )\n", __FUNCTION__,
+ window, DFB_RECTANGLE_VALS(&window->config.bounds), grab->target );
+
+ return wm_local->funcs->Grab( window, wm_local->data, window->window_data, grab );
+}
+
+DFBResult
+dfb_wm_ungrab( CoreWindow *window,
+ CoreWMGrab *grab )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->Ungrab != NULL );
+
+ D_ASSERT( window != NULL );
+
+ D_MAGIC_ASSERT( window->stack, CoreWindowStack );
+ D_MAGIC_ASSERT( window->stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &window->stack->context->lock );
+
+ D_ASSERT( grab != NULL );
+
+ D_DEBUG_AT( Core_WM, "%s( %p [%d,%d-%dx%d], %d )\n", __FUNCTION__,
+ window, DFB_RECTANGLE_VALS(&window->config.bounds), grab->target );
+
+ return wm_local->funcs->Ungrab( window, wm_local->data, window->window_data, grab );
+}
+
+DFBResult
+dfb_wm_request_focus( CoreWindow *window )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->RequestFocus != NULL );
+
+ D_ASSERT( window != NULL );
+
+ D_MAGIC_ASSERT( window->stack, CoreWindowStack );
+ D_MAGIC_ASSERT( window->stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &window->stack->context->lock );
+
+ D_DEBUG_AT( Core_WM, "%s( %p [%d,%d-%dx%d] )\n", __FUNCTION__,
+ window, DFB_RECTANGLE_VALS(&window->config.bounds) );
+
+ return wm_local->funcs->RequestFocus( window, wm_local->data, window->window_data );
+}
+
+DFBResult
+dfb_wm_begin_updates( CoreWindow *window,
+ const DFBRegion *update )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->RequestFocus != NULL );
+
+ D_ASSERT( window != NULL );
+
+ D_MAGIC_ASSERT( window->stack, CoreWindowStack );
+ D_MAGIC_ASSERT( window->stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &window->stack->context->lock );
+
+ D_DEBUG_AT( Core_WM, "%s( %p [%d,%d-%dx%d] )\n", __FUNCTION__,
+ window, DFB_RECTANGLE_VALS(&window->config.bounds) );
+
+ return wm_local->funcs->BeginUpdates( window, wm_local->data, window->window_data, update );
+}
+
+DFBResult
+dfb_wm_set_cursor_position( CoreWindow *window,
+ int x,
+ int y )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->SetCursorPosition != NULL );
+
+ D_ASSERT( window != NULL );
+
+ D_MAGIC_ASSERT( window->stack, CoreWindowStack );
+ D_MAGIC_ASSERT( window->stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &window->stack->context->lock );
+
+ D_DEBUG_AT( Core_WM, "%s( %p [%d,%d] )\n", __FUNCTION__, window, x, y );
+
+ return wm_local->funcs->SetCursorPosition( window, wm_local->data, window->window_data, x, y );
+}
+
+DFBResult
+dfb_wm_update_stack( CoreWindowStack *stack,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->UpdateStack != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ DFB_REGION_ASSERT( region );
+
+ D_DEBUG_AT( Core_WM, "%s( %p, [%d,%d-%dx%d], 0x%x )\n", __FUNCTION__,
+ stack, DFB_RECTANGLE_VALS_FROM_REGION(region), flags );
+
+ return wm_local->funcs->UpdateStack( stack, wm_local->data,
+ stack->stack_data, region, flags );
+}
+
+DFBResult
+dfb_wm_update_window( CoreWindow *window,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->UpdateWindow != NULL );
+
+ D_ASSERT( window != NULL );
+
+ D_MAGIC_ASSERT( window->stack, CoreWindowStack );
+ D_MAGIC_ASSERT( window->stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &window->stack->context->lock );
+
+ DFB_REGION_ASSERT_IF( region );
+
+ D_DEBUG_AT( Core_WM, "%s( %p [%d,%d-%dx%d], [%d,%d-%dx%d], 0x%x )\n", __FUNCTION__,
+ window, DFB_RECTANGLE_VALS(&window->config.bounds),
+ DFB_RECTANGLE_VALS_FROM_REGION(region), flags );
+
+ return wm_local->funcs->UpdateWindow( window, wm_local->data,
+ window->window_data, region, flags );
+}
+
+DFBResult
+dfb_wm_update_cursor( CoreWindowStack *stack,
+ CoreCursorUpdateFlags flags )
+{
+ D_ASSERT( wm_local != NULL );
+ D_ASSERT( wm_local->funcs != NULL );
+ D_ASSERT( wm_local->funcs->UpdateStack != NULL );
+
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+ D_ASSERT( stack->flags & CWSF_INITIALIZED );
+
+ D_MAGIC_ASSERT( stack->context, CoreLayerContext );
+ FUSION_SKIRMISH_ASSERT( &stack->context->lock );
+
+ D_FLAGS_ASSERT( flags, CCUF_ALL );
+
+ if (dfb_config->no_cursor_updates)
+ return DFB_OK;
+
+ return wm_local->funcs->UpdateCursor( stack, wm_local->data,
+ stack->stack_data, flags );
+}
+
diff --git a/Source/DirectFB/src/core/wm.h b/Source/DirectFB/src/core/wm.h
new file mode 100755
index 0000000..eea4fd9
--- /dev/null
+++ b/Source/DirectFB/src/core/wm.h
@@ -0,0 +1,468 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DFB__CORE__WM_H__
+#define __DFB__CORE__WM_H__
+
+#include <directfb.h>
+#include <directfb_windows.h>
+
+#include <direct/modules.h>
+
+#include <core/coretypes.h>
+#include <core/windows.h>
+
+
+DECLARE_MODULE_DIRECTORY( dfb_core_wm_modules );
+
+
+/*
+ * Increase this number when changes result in binary incompatibility!
+ */
+#define DFB_CORE_WM_ABI_VERSION 9
+
+#define DFB_CORE_WM_INFO_NAME_LENGTH 60
+#define DFB_CORE_WM_INFO_VENDOR_LENGTH 80
+#define DFB_CORE_WM_INFO_URL_LENGTH 120
+#define DFB_CORE_WM_INFO_LICENSE_LENGTH 40
+
+
+typedef struct {
+ int major;
+ int minor;
+
+ int binary;
+} CoreWMVersion;
+
+typedef struct {
+ CoreWMVersion version;
+
+ char name [DFB_CORE_WM_INFO_NAME_LENGTH];
+ char vendor [DFB_CORE_WM_INFO_VENDOR_LENGTH];
+ char url [DFB_CORE_WM_INFO_URL_LENGTH];
+ char license[DFB_CORE_WM_INFO_LICENSE_LENGTH];
+
+ unsigned int wm_data_size;
+ unsigned int wm_shared_size;
+ unsigned int stack_data_size;
+ unsigned int window_data_size;
+} CoreWMInfo;
+
+typedef struct {
+ CoreWMGrabTarget target;
+
+ /* Both for CWMGT_KEY only. */
+ DFBInputDeviceKeySymbol symbol;
+ DFBInputDeviceModifierMask modifiers;
+} CoreWMGrab;
+
+/* FIXME: move to cursor.h when it's there */
+typedef enum {
+ CCUF_NONE = 0x00000000,
+
+ CCUF_ENABLE = 0x00000001,
+ CCUF_DISABLE = 0x00000002,
+
+ CCUF_POSITION = 0x00000010,
+ CCUF_SIZE = 0x00000020,
+ CCUF_SHAPE = 0x00000040,
+ CCUF_OPACITY = 0x00000080,
+
+ CCUF_ALL = 0x000000F3
+} CoreCursorUpdateFlags;
+
+typedef DFBEnumerationResult (*CoreWMWindowCallback) (CoreWindow *window,
+ void *ctx);
+
+typedef struct {
+
+ /** Module **/
+
+ void (*GetWMInfo) ( CoreWMInfo *info );
+
+ DFBResult (*Initialize) ( CoreDFB *core,
+ void *wm_data,
+ void *shared_data );
+
+ DFBResult (*Join) ( CoreDFB *core,
+ void *wm_data,
+ void *shared_data );
+
+ DFBResult (*Shutdown) ( bool emergency,
+ void *wm_data,
+ void *shared_data );
+
+ DFBResult (*Leave) ( bool emergency,
+ void *wm_data,
+ void *shared_data );
+
+ DFBResult (*Suspend) ( void *wm_data,
+ void *shared_data );
+
+ DFBResult (*Resume) ( void *wm_data,
+ void *shared_data );
+
+ DFBResult (*PostInit) ( void *wm_data,
+ void *shared_data );
+
+
+ /** Stack **/
+
+ DFBResult (*InitStack) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data );
+
+ DFBResult (*CloseStack) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data );
+
+ DFBResult (*SetActive) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ bool active );
+
+ DFBResult (*ResizeStack) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ int width,
+ int height );
+
+ DFBResult (*ProcessInput) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ const DFBInputEvent *event );
+
+ DFBResult (*FlushKeys) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data );
+
+ DFBResult (*WindowAt) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ int x,
+ int y,
+ CoreWindow **ret_window );
+
+ DFBResult (*WindowLookup) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ DFBWindowID window_id,
+ CoreWindow **ret_window );
+
+ DFBResult (*EnumWindows) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWMWindowCallback callback,
+ void *callback_ctx );
+
+
+ /** Window **/
+ DFBResult (*SetWindowProperty)( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void *value,
+ void **old_value );
+
+ DFBResult (*GetWindowProperty)( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void **value);
+
+ DFBResult (*RemoveWindowProperty)( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void **value );
+
+ DFBResult (*GetInsets) ( CoreWindowStack *stack,
+ CoreWindow *window,
+ DFBInsets *insets );
+
+ DFBResult (*PreConfigureWindow)( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data );
+
+ DFBResult (*AddWindow) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data );
+
+ DFBResult (*RemoveWindow) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data );
+
+ DFBResult (*SetWindowConfig) ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const CoreWindowConfig *config,
+ CoreWindowConfigFlags flags );
+
+ DFBResult (*RestackWindow) ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWindow *relative,
+ void *relative_data,
+ int relation );
+
+ DFBResult (*Grab) ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWMGrab *grab );
+
+ DFBResult (*Ungrab) ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWMGrab *grab );
+
+ DFBResult (*RequestFocus) ( CoreWindow *window,
+ void *wm_data,
+ void *window_data );
+
+ DFBResult (*BeginUpdates) ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const DFBRegion *update );
+
+ DFBResult (*SetCursorPosition) ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ int x,
+ int y );
+
+
+ /** Updates **/
+
+ DFBResult (*UpdateStack) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags );
+
+ DFBResult (*UpdateWindow) ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags );
+
+ DFBResult (*UpdateCursor) ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreCursorUpdateFlags flags );
+} CoreWMFuncs;
+
+
+
+typedef enum {
+ CORE_WM_WINDOW_ADD = 1,
+ CORE_WM_WINDOW_REMOVE = 2,
+ CORE_WM_WINDOW_CONFIG = 3,
+ CORE_WM_WINDOW_STATE = 4,
+ CORE_WM_WINDOW_RESTACK = 5,
+ CORE_WM_WINDOW_FOCUS = 6,
+
+ _CORE_WM_NUM_CHANNELS
+} CoreWMChannels;
+
+typedef struct {
+ DFBWindowInfo info;
+} CoreWM_WindowAdd;
+
+typedef struct {
+ DFBWindowID window_id;
+} CoreWM_WindowRemove;
+
+typedef struct {
+ DFBWindowID window_id;
+ DFBWindowConfig config;
+ DFBWindowConfigFlags flags;
+} CoreWM_WindowConfig;
+
+typedef struct {
+ DFBWindowID window_id;
+ DFBWindowState state;
+} CoreWM_WindowState;
+
+typedef struct {
+ DFBWindowID window_id;
+ unsigned int index;
+} CoreWM_WindowRestack;
+
+typedef struct {
+ DFBWindowID window_id;
+} CoreWM_WindowFocus;
+
+
+DFBResult dfb_wm_attach ( CoreDFB *core,
+ int channel,
+ ReactionFunc func,
+ void *ctx,
+ Reaction *reaction );
+
+DFBResult dfb_wm_detach ( CoreDFB *core,
+ Reaction *reaction );
+
+DFBResult dfb_wm_dispatch( CoreDFB *core,
+ int channel,
+ const void *data,
+ int size );
+
+
+DFBResult dfb_wm_dispatch_WindowAdd ( CoreDFB *core,
+ CoreWindow *window );
+
+DFBResult dfb_wm_dispatch_WindowRemove ( CoreDFB *core,
+ CoreWindow *window );
+
+DFBResult dfb_wm_dispatch_WindowConfig ( CoreDFB *core,
+ CoreWindow *window,
+ DFBWindowConfigFlags flags );
+
+DFBResult dfb_wm_dispatch_WindowState ( CoreDFB *core,
+ CoreWindow *window );
+
+DFBResult dfb_wm_dispatch_WindowRestack( CoreDFB *core,
+ CoreWindow *window,
+ unsigned int index );
+
+DFBResult dfb_wm_dispatch_WindowFocus ( CoreDFB *core,
+ CoreWindow *window );
+
+
+
+void dfb_wm_get_info( CoreWMInfo *info );
+
+DFBResult dfb_wm_post_init ( CoreDFB *core );
+
+DFBResult dfb_wm_init_stack ( CoreWindowStack *stack );
+
+DFBResult dfb_wm_close_stack ( CoreWindowStack *stack );
+
+DFBResult dfb_wm_set_active ( CoreWindowStack *stack,
+ bool active );
+
+DFBResult dfb_wm_resize_stack ( CoreWindowStack *stack,
+ int width,
+ int height );
+
+DFBResult dfb_wm_process_input ( CoreWindowStack *stack,
+ const DFBInputEvent *event );
+
+DFBResult dfb_wm_flush_keys ( CoreWindowStack *stack );
+
+DFBResult dfb_wm_window_at ( CoreWindowStack *stack,
+ int x,
+ int y,
+ CoreWindow **ret_window );
+
+DFBResult dfb_wm_window_lookup ( CoreWindowStack *stack,
+ DFBWindowID window_id,
+ CoreWindow **ret_window );
+
+DFBResult dfb_wm_enum_windows ( CoreWindowStack *stack,
+ CoreWMWindowCallback callback,
+ void *callback_ctx );
+
+DFBResult dfb_wm_get_insets ( CoreWindowStack *stack,
+ CoreWindow *window,
+ DFBInsets *insets );
+
+DFBResult dfb_wm_set_window_property ( CoreWindowStack *stack,
+ CoreWindow *window,
+ const char *key,
+ void *value,
+ void **ret_old_value );
+
+DFBResult dfb_wm_get_window_property ( CoreWindowStack *stack,
+ CoreWindow *window,
+ const char *key,
+ void **ret_value );
+
+DFBResult dfb_wm_remove_window_property ( CoreWindowStack *stack,
+ CoreWindow *window,
+ const char *key,
+ void **ret_value );
+
+DFBResult dfb_wm_preconfigure_window ( CoreWindowStack *stack,
+ CoreWindow *window );
+
+
+DFBResult dfb_wm_add_window ( CoreWindowStack *stack,
+ CoreWindow *window );
+
+DFBResult dfb_wm_remove_window ( CoreWindowStack *stack,
+ CoreWindow *window );
+
+DFBResult dfb_wm_set_window_config ( CoreWindow *window,
+ const CoreWindowConfig *config,
+ CoreWindowConfigFlags flags );
+
+DFBResult dfb_wm_restack_window ( CoreWindow *window,
+ CoreWindow *relative,
+ int relation );
+
+DFBResult dfb_wm_grab ( CoreWindow *window,
+ CoreWMGrab *grab );
+
+DFBResult dfb_wm_ungrab ( CoreWindow *window,
+ CoreWMGrab *grab );
+
+DFBResult dfb_wm_request_focus ( CoreWindow *window );
+
+DFBResult dfb_wm_begin_updates ( CoreWindow *window,
+ const DFBRegion *update );
+
+DFBResult dfb_wm_set_cursor_position( CoreWindow *window,
+ int x,
+ int y );
+
+
+DFBResult dfb_wm_update_stack ( CoreWindowStack *stack,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags );
+
+DFBResult dfb_wm_update_window ( CoreWindow *window,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags );
+
+DFBResult dfb_wm_update_cursor ( CoreWindowStack *stack,
+ CoreCursorUpdateFlags flags );
+
+#endif
diff --git a/Source/DirectFB/src/core/wm_module.h b/Source/DirectFB/src/core/wm_module.h
new file mode 100755
index 0000000..b470ebd
--- /dev/null
+++ b/Source/DirectFB/src/core/wm_module.h
@@ -0,0 +1,274 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DFB__CORE__WM_MODULE_H__
+#define __DFB__CORE__WM_MODULE_H__
+
+#include <core/wm.h>
+
+
+/** Module **/
+
+static void wm_get_info ( CoreWMInfo *info );
+
+static DFBResult wm_initialize ( CoreDFB *core,
+ void *wm_data,
+ void *shared_data );
+
+static DFBResult wm_join ( CoreDFB *core,
+ void *wm_data,
+ void *shared_data );
+
+static DFBResult wm_shutdown ( bool emergency,
+ void *wm_data,
+ void *shared_data );
+
+static DFBResult wm_leave ( bool emergency,
+ void *wm_data,
+ void *shared_data );
+
+static DFBResult wm_suspend ( void *wm_data,
+ void *shared_data );
+
+static DFBResult wm_resume ( void *wm_data,
+ void *shared_data );
+
+static DFBResult wm_post_init ( void *wm_data,
+ void *shared_data );
+
+
+/** Stack **/
+
+static DFBResult wm_init_stack ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data );
+
+static DFBResult wm_close_stack ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data );
+
+static DFBResult wm_set_active ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ bool active );
+
+static DFBResult wm_resize_stack ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ int width,
+ int height );
+
+static DFBResult wm_process_input ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ const DFBInputEvent *event );
+
+static DFBResult wm_flush_keys ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data );
+
+static DFBResult wm_window_at ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ int x,
+ int y,
+ CoreWindow **ret_window );
+
+static DFBResult wm_window_lookup ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ DFBWindowID window_id,
+ CoreWindow **ret_window );
+
+static DFBResult wm_enum_windows ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWMWindowCallback callback,
+ void *callback_ctx );
+
+/** Window **/
+static DFBResult wm_get_insets ( CoreWindowStack *stack,
+ CoreWindow *window,
+ DFBInsets *insets );
+
+static DFBResult wm_preconfigure_window ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data );
+
+static DFBResult wm_set_window_property( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void *value,
+ void **ret_old_value );
+
+static DFBResult wm_get_window_property( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void **ret_value );
+
+static DFBResult wm_remove_window_property( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void **ret_value );
+
+static DFBResult wm_add_window ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data );
+
+static DFBResult wm_remove_window ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data );
+
+static DFBResult wm_set_window_config( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const CoreWindowConfig *config,
+ CoreWindowConfigFlags flags );
+
+static DFBResult wm_restack_window ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWindow *relative,
+ void *relative_data,
+ int relation );
+
+static DFBResult wm_grab ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWMGrab *grab );
+
+static DFBResult wm_ungrab ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWMGrab *grab );
+
+static DFBResult wm_request_focus ( CoreWindow *window,
+ void *wm_data,
+ void *window_data );
+
+static DFBResult wm_begin_updates ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const DFBRegion *update );
+
+static DFBResult wm_set_cursor_position( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ int x,
+ int y );
+
+/** Updates **/
+
+static DFBResult wm_update_stack ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags );
+
+static DFBResult wm_update_window ( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags );
+
+static DFBResult wm_update_cursor ( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreCursorUpdateFlags flags );
+
+
+static CoreWMFuncs wm_funcs = {
+ .GetWMInfo = wm_get_info,
+
+ .Initialize = wm_initialize,
+ .Join = wm_join,
+ .Shutdown = wm_shutdown,
+ .Leave = wm_leave,
+ .Suspend = wm_suspend,
+ .Resume = wm_resume,
+ .PostInit = wm_post_init,
+
+ .InitStack = wm_init_stack,
+ .CloseStack = wm_close_stack,
+ .SetActive = wm_set_active,
+ .ResizeStack = wm_resize_stack,
+ .ProcessInput = wm_process_input,
+ .FlushKeys = wm_flush_keys,
+ .WindowAt = wm_window_at,
+ .WindowLookup = wm_window_lookup,
+ .EnumWindows = wm_enum_windows,
+
+ .GetInsets = wm_get_insets,
+ .PreConfigureWindow = wm_preconfigure_window,
+ .SetWindowProperty = wm_set_window_property,
+ .GetWindowProperty = wm_get_window_property,
+ .RemoveWindowProperty = wm_remove_window_property,
+ .AddWindow = wm_add_window,
+ .RemoveWindow = wm_remove_window,
+ .SetWindowConfig = wm_set_window_config,
+ .RestackWindow = wm_restack_window,
+ .Grab = wm_grab,
+ .Ungrab = wm_ungrab,
+ .RequestFocus = wm_request_focus,
+ .BeginUpdates = wm_begin_updates,
+ .SetCursorPosition = wm_set_cursor_position,
+
+ .UpdateStack = wm_update_stack,
+ .UpdateWindow = wm_update_window,
+ .UpdateCursor = wm_update_cursor
+};
+
+
+#define DFB_WINDOW_MANAGER(shortname) \
+__attribute__((constructor)) void directfbwm_##shortname( void ); \
+ \
+void \
+directfbwm_##shortname( void ) \
+{ \
+ direct_modules_register( &dfb_core_wm_modules, \
+ DFB_CORE_WM_ABI_VERSION, \
+ #shortname, &wm_funcs ); \
+}
+
+#endif
+
diff --git a/Source/DirectFB/src/directfb.c b/Source/DirectFB/src/directfb.c
new file mode 100755
index 0000000..9562811
--- /dev/null
+++ b/Source/DirectFB/src/directfb.c
@@ -0,0 +1,311 @@
+/*
+ (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 <directfb.h>
+#include <directfb_version.h>
+
+#include <misc/conf.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/input.h>
+#include <core/layer_context.h>
+#include <core/layer_control.h>
+#include <core/layers.h>
+#include <core/state.h>
+#include <core/gfxcard.h>
+#include <core/surface.h>
+#include <core/windows.h>
+#include <core/windowstack.h>
+#include <core/wm.h>
+
+#include <gfx/convert.h>
+
+#include <direct/conf.h>
+#include <direct/direct.h>
+#include <direct/interface.h>
+#include <direct/log.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <display/idirectfbsurface.h>
+
+#include <idirectfb.h>
+
+
+IDirectFB *idirectfb_singleton = NULL;
+
+static DFBResult CreateRemote( const char *host, int session, IDirectFB **ret_interface );
+
+/*
+ * Version checking
+ */
+const unsigned int directfb_major_version = DIRECTFB_MAJOR_VERSION;
+const unsigned int directfb_minor_version = DIRECTFB_MINOR_VERSION;
+const unsigned int directfb_micro_version = DIRECTFB_MICRO_VERSION;
+const unsigned int directfb_binary_age = DIRECTFB_BINARY_AGE;
+const unsigned int directfb_interface_age = DIRECTFB_INTERFACE_AGE;
+
+const char *
+DirectFBCheckVersion( unsigned int required_major,
+ unsigned int required_minor,
+ unsigned int required_micro )
+{
+ if (required_major > DIRECTFB_MAJOR_VERSION)
+ return "DirectFB version too old (major mismatch)";
+ if (required_major < DIRECTFB_MAJOR_VERSION)
+ return "DirectFB version too new (major mismatch)";
+ if (required_minor > DIRECTFB_MINOR_VERSION)
+ return "DirectFB version too old (minor mismatch)";
+ if (required_minor < DIRECTFB_MINOR_VERSION)
+ return "DirectFB version too new (minor mismatch)";
+ if (required_micro < DIRECTFB_MICRO_VERSION - DIRECTFB_BINARY_AGE)
+ return "DirectFB version too new (micro mismatch)";
+ if (required_micro > DIRECTFB_MICRO_VERSION)
+ return "DirectFB version too old (micro mismatch)";
+
+ return NULL;
+}
+
+const char *
+DirectFBUsageString( void )
+{
+ return dfb_config_usage();
+}
+
+DFBResult
+DirectFBInit( int *argc, char *(*argv[]) )
+{
+ DFBResult ret;
+
+#ifdef DSLINUX
+ IDirectFBEventBuffer_Dispatcher_ctor();
+ IDirectFBDataBuffer_Dispatcher_ctor();
+ IDirectFBWindow_Requestor_ctor();
+ IDirectFBSurface_Requestor_ctor();
+ IDirectFBScreen_Requestor_ctor();
+ IDirectFBPalette_Requestor_ctor();
+ IDirectFBInputDevice_Requestor_ctor();
+ IDirectFBImageProvider_Requestor_ctor();
+ IDirectFBFont_Requestor_ctor();
+ IDirectFBDisplayLayer_Requestor_ctor();
+ IDirectFB_Requestor_ctor();
+#endif
+
+ ret = dfb_config_init( argc, argv );
+ if (ret)
+ return ret;
+
+ return DFB_OK;
+}
+
+DFBResult
+DirectFBSetOption( const char *name, const char *value )
+{
+ DFBResult ret;
+
+ if (dfb_config == NULL) {
+ D_ERROR( "DirectFBSetOption: DirectFBInit has to be "
+ "called before DirectFBSetOption!\n" );
+ return DFB_INIT;
+ }
+
+ if (idirectfb_singleton) {
+ D_ERROR( "DirectFBSetOption: DirectFBSetOption has to be "
+ "called before DirectFBCreate!\n" );
+ return DFB_INIT;
+ }
+
+ if (!name)
+ return DFB_INVARG;
+
+ ret = dfb_config_set( name, value );
+ if (ret)
+ return ret;
+
+ return DFB_OK;
+}
+
+/*
+ * Programs have to call this to get the super interface
+ * which is needed to access other functions
+ */
+DFBResult
+DirectFBCreate( IDirectFB **interface )
+{
+ DFBResult ret;
+ IDirectFB *dfb;
+ CoreDFB *core_dfb;
+
+ if (!dfb_config) {
+ /* don't use D_ERROR() here, it uses dfb_config */
+ direct_log_printf( NULL, "(!) DirectFBCreate: DirectFBInit "
+ "has to be called before DirectFBCreate!\n" );
+ return DFB_INIT;
+ }
+
+ if (!interface)
+ return DFB_INVARG;
+
+ if (idirectfb_singleton) {
+ idirectfb_singleton->AddRef( idirectfb_singleton );
+ *interface = idirectfb_singleton;
+ return DFB_OK;
+ }
+
+ direct_initialize();
+
+ if ( !(direct_config->quiet & DMT_BANNER) && dfb_config->banner) {
+ direct_log_printf( NULL,
+ "\n"
+ " ~~~~~~~~~~~~~~~~~~~~~~~~~~| DirectFB " DIRECTFB_VERSION " |~~~~~~~~~~~~~~\n"
+ " (c) 2001-2009 The world wide DirectFB Open Source Community\n"
+ " (c) 2000-2004 Convergence (integrated media) GmbH\n"
+ " ----------------------------------------------------------------\n"
+ "\n" );
+ }
+
+#ifndef DIRECTFB_PURE_VOODOO
+ if (dfb_config->remote.host)
+ return CreateRemote( dfb_config->remote.host, dfb_config->remote.session, interface );
+
+ ret = dfb_core_create( &core_dfb );
+ if (ret)
+ return ret;
+
+ DIRECT_ALLOCATE_INTERFACE( dfb, IDirectFB );
+
+ ret = IDirectFB_Construct( dfb, core_dfb );
+ if (ret) {
+ dfb_core_destroy( core_dfb, false );
+ return ret;
+ }
+
+ if (dfb_core_is_master( core_dfb )) {
+ /* not fatal */
+ ret = dfb_wm_post_init( core_dfb );
+ if (ret)
+ D_DERROR( ret, "DirectFBCreate: Post initialization of WM failed!\n" );
+
+ dfb_core_activate( core_dfb );
+ }
+
+ *interface = idirectfb_singleton = dfb;
+
+ return DFB_OK;
+#else
+ return CreateRemote( dfb_config->remote.host ?: "", dfb_config->remote.session, interface );
+#endif
+}
+
+DFBResult
+DirectFBError( const char *msg, DFBResult error )
+{
+ if (msg)
+ direct_log_printf( NULL, "(#) DirectFBError [%s]: %s\n", msg,
+ DirectFBErrorString( error ) );
+ else
+ direct_log_printf( NULL, "(#) DirectFBError: %s\n",
+ DirectFBErrorString( error ) );
+
+ return error;
+}
+
+const char *
+DirectFBErrorString( DFBResult error )
+{
+ if (D_RESULT_TYPE_IS( error, 'D','F','B' )) {
+ switch (error) {
+ case DFB_NOVIDEOMEMORY:
+ return "Out of video memory!";
+ case DFB_MISSINGFONT:
+ return "No font has been set!";
+ case DFB_MISSINGIMAGE:
+ return "No image has been set!";
+ default:
+ return "UKNOWN DIRECTFB RESULT!";
+ }
+ }
+
+ return DirectResultString( error );
+}
+
+DFBResult
+DirectFBErrorFatal( const char *msg, DFBResult error )
+{
+ DirectFBError( msg, error );
+
+ //if (idirectfb_singleton)
+ //IDirectFB_Destruct( idirectfb_singleton );
+
+ exit( error );
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+CreateRemote( const char *host, int session, IDirectFB **ret_interface )
+{
+ DFBResult ret;
+ DirectInterfaceFuncs *funcs;
+ void *interface;
+
+ D_ASSERT( host != NULL );
+ D_ASSERT( ret_interface != NULL );
+
+ ret = DirectGetInterface( &funcs, "IDirectFB", "Requestor", NULL, NULL );
+ if (ret)
+ return ret;
+
+ ret = funcs->Allocate( &interface );
+ if (ret)
+ return ret;
+
+ ret = funcs->Construct( interface, host, session );
+ if (ret)
+ return ret;
+
+#ifndef DIRECTFB_PURE_VOODOO
+ *ret_interface = idirectfb_singleton = interface;
+#else
+ *ret_interface = interface;
+#endif
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/display/Makefile.am b/Source/DirectFB/src/display/Makefile.am
new file mode 100755
index 0000000..ddb1456
--- /dev/null
+++ b/Source/DirectFB/src/display/Makefile.am
@@ -0,0 +1,30 @@
+## Makefile.am for DirectFB/src/display
+
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+
+internalincludedir = $(INTERNALINCLUDEDIR)/display
+
+internalinclude_HEADERS = \
+ idirectfbpalette.h \
+ idirectfbsurface.h \
+ idirectfbsurface_layer.h \
+ idirectfbsurface_window.h \
+ idirectfbdisplaylayer.h \
+ idirectfbscreen.h
+
+
+noinst_LTLIBRARIES = libdirectfb_display.la
+
+libdirectfb_display_la_SOURCES = \
+ idirectfbpalette.c \
+ idirectfbsurface.c \
+ idirectfbsurface_layer.c \
+ idirectfbsurface_window.c \
+ idirectfbdisplaylayer.c \
+ idirectfbscreen.c
diff --git a/Source/DirectFB/src/display/Makefile.in b/Source/DirectFB/src/display/Makefile.in
new file mode 100755
index 0000000..312b297
--- /dev/null
+++ b/Source/DirectFB/src/display/Makefile.in
@@ -0,0 +1,570 @@
+# 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 = src/display
+DIST_COMMON = $(internalinclude_HEADERS) $(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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libdirectfb_display_la_LIBADD =
+am_libdirectfb_display_la_OBJECTS = idirectfbpalette.lo \
+ idirectfbsurface.lo idirectfbsurface_layer.lo \
+ idirectfbsurface_window.lo idirectfbdisplaylayer.lo \
+ idirectfbscreen.lo
+libdirectfb_display_la_OBJECTS = $(am_libdirectfb_display_la_OBJECTS)
+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 = $(libdirectfb_display_la_SOURCES)
+DIST_SOURCES = $(libdirectfb_display_la_SOURCES)
+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)$(internalincludedir)"
+internalincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(internalinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+internalincludedir = $(INTERNALINCLUDEDIR)/display
+internalinclude_HEADERS = \
+ idirectfbpalette.h \
+ idirectfbsurface.h \
+ idirectfbsurface_layer.h \
+ idirectfbsurface_window.h \
+ idirectfbdisplaylayer.h \
+ idirectfbscreen.h
+
+noinst_LTLIBRARIES = libdirectfb_display.la
+libdirectfb_display_la_SOURCES = \
+ idirectfbpalette.c \
+ idirectfbsurface.c \
+ idirectfbsurface_layer.c \
+ idirectfbsurface_window.c \
+ idirectfbdisplaylayer.c \
+ idirectfbscreen.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 src/display/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/display/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
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_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
+libdirectfb_display.la: $(libdirectfb_display_la_OBJECTS) $(libdirectfb_display_la_DEPENDENCIES)
+ $(LINK) $(libdirectfb_display_la_OBJECTS) $(libdirectfb_display_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbdisplaylayer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbpalette.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbscreen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbsurface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbsurface_layer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbsurface_window.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-internalincludeHEADERS: $(internalinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(internalincludedir)" || $(MKDIR_P) "$(DESTDIR)$(internalincludedir)"
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(internalincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ $(internalincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+uninstall-internalincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(internalincludedir)/$$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) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(internalincludedir)"; 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-libtool clean-noinstLTLIBRARIES \
+ 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-internalincludeHEADERS
+
+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-internalincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES 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-info install-info-am \
+ install-internalincludeHEADERS 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-internalincludeHEADERS
+
+# 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/src/display/idirectfbdisplaylayer.c b/Source/DirectFB/src/display/idirectfbdisplaylayer.c
new file mode 100755
index 0000000..014848a
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbdisplaylayer.c
@@ -0,0 +1,1076 @@
+/*
+ (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 <directfb.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/surface.h>
+#include <core/gfxcard.h>
+#include <core/layers.h>
+#include <core/layers_internal.h>
+#include <core/layer_context.h>
+#include <core/layer_control.h>
+#include <core/layer_region.h>
+#include <core/state.h>
+#include <core/windows.h>
+#include <core/windows_internal.h>
+#include <core/windowstack.h>
+#include <core/wm.h>
+
+#include <windows/idirectfbwindow.h>
+
+#include <gfx/convert.h>
+
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+
+#include <display/idirectfbdisplaylayer.h>
+#include <display/idirectfbscreen.h>
+#include <display/idirectfbsurface.h>
+#include <display/idirectfbsurface_layer.h>
+
+
+D_DEBUG_DOMAIN( Layer, "IDirectFBDisplayLayer", "Display Layer Interface" );
+
+/*
+ * private data struct of IDirectFB
+ */
+typedef struct {
+ int ref; /* reference counter */
+ DFBDisplayLayerDescription desc; /* description of the layer's caps */
+ DFBDisplayLayerCooperativeLevel level; /* current cooperative level */
+ CoreScreen *screen; /* layer's screen */
+ CoreLayer *layer; /* core layer data */
+ CoreLayerContext *context; /* shared or exclusive context */
+ CoreLayerRegion *region; /* primary region of the context */
+ CoreWindowStack *stack; /* stack of shared context */
+ DFBBoolean switch_exclusive; /* switch to exclusive context after creation? */
+ CoreDFB *core;
+} IDirectFBDisplayLayer_data;
+
+
+
+static void
+IDirectFBDisplayLayer_Destruct( IDirectFBDisplayLayer *thiz )
+{
+ IDirectFBDisplayLayer_data *data = (IDirectFBDisplayLayer_data*)thiz->priv;
+
+ D_DEBUG_AT( Layer, "IDirectFBDisplayLayer_Destruct()\n" );
+
+ D_DEBUG_AT( Layer, " -> unref region...\n" );
+
+ dfb_layer_region_unref( data->region );
+
+ D_DEBUG_AT( Layer, " -> unref context...\n" );
+
+ dfb_layer_context_unref( data->context );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+
+ D_DEBUG_AT( Layer, " -> done.\n" );
+}
+
+static DirectResult
+IDirectFBDisplayLayer_AddRef( IDirectFBDisplayLayer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBDisplayLayer_Release( IDirectFBDisplayLayer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (--data->ref == 0)
+ IDirectFBDisplayLayer_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetID( IDirectFBDisplayLayer *thiz,
+ DFBDisplayLayerID *id )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!id)
+ return DFB_INVARG;
+
+ *id = dfb_layer_id_translated( data->layer );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetDescription( IDirectFBDisplayLayer *thiz,
+ DFBDisplayLayerDescription *desc )
+{
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!desc)
+ return DFB_INVARG;
+
+ *desc = data->desc;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetSurface( IDirectFBDisplayLayer *thiz,
+ IDirectFBSurface **interface )
+{
+ DFBResult ret;
+ CoreLayerRegion *region;
+ IDirectFBSurface *surface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!interface)
+ return DFB_INVARG;
+
+ if (data->level == DLSCL_SHARED) {
+ D_WARN( "letting unprivileged IDirectFBDisplayLayer::GetSurface() "
+ "call pass until cooperative level handling is finished" );
+ }
+
+ ret = dfb_layer_context_get_primary_region( data->context, true, &region );
+ if (ret)
+ return ret;
+
+ DIRECT_ALLOCATE_INTERFACE( surface, IDirectFBSurface );
+
+ ret = IDirectFBSurface_Layer_Construct( surface, NULL, NULL, NULL,
+ region, DSCAPS_NONE, data->core );
+
+ if (region->config.buffermode == DLBM_FRONTONLY && data->level == DLSCL_EXCLUSIVE) {
+ surface->Clear( surface, 0, 0, 0, 0 );
+ dfb_layer_region_flip_update( region, NULL, DSFLIP_NONE );
+ }
+
+ *interface = ret ? NULL : surface;
+
+ dfb_layer_region_unref( region );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetScreen( IDirectFBDisplayLayer *thiz,
+ IDirectFBScreen **interface )
+{
+ DFBResult ret;
+ IDirectFBScreen *screen;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!interface)
+ return DFB_INVARG;
+
+ DIRECT_ALLOCATE_INTERFACE( screen, IDirectFBScreen );
+
+ ret = IDirectFBScreen_Construct( screen, data->screen );
+
+ *interface = ret ? NULL : screen;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetCooperativeLevel( IDirectFBDisplayLayer *thiz,
+ DFBDisplayLayerCooperativeLevel level )
+{
+ DFBResult ret;
+ CoreLayerContext *context;
+ CoreLayerRegion *region;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level == level)
+ return DFB_OK;
+
+ switch (level) {
+ case DLSCL_SHARED:
+ case DLSCL_ADMINISTRATIVE:
+ if (data->level == DLSCL_EXCLUSIVE) {
+ ret = dfb_layer_get_primary_context( data->layer, false, &context );
+ if (ret)
+ return ret;
+
+ ret = dfb_layer_context_get_primary_region( context, true, &region );
+ if (ret) {
+ dfb_layer_context_unref( context );
+ return ret;
+ }
+
+ dfb_layer_region_unref( data->region );
+ dfb_layer_context_unref( data->context );
+
+ data->context = context;
+ data->region = region;
+ data->stack = dfb_layer_context_windowstack( data->context );
+ }
+
+ break;
+
+ case DLSCL_EXCLUSIVE:
+ ret = dfb_layer_create_context( data->layer, &context );
+ if (ret)
+ return ret;
+
+ if (data->switch_exclusive) {
+ ret = dfb_layer_activate_context( data->layer, context );
+ if (ret) {
+ dfb_layer_context_unref( context );
+ return ret;
+ }
+ }
+
+ ret = dfb_layer_context_get_primary_region( context, true, &region );
+ if (ret) {
+ dfb_layer_context_unref( context );
+ return ret;
+ }
+
+ dfb_layer_region_unref( data->region );
+ dfb_layer_context_unref( data->context );
+
+ data->context = context;
+ data->region = region;
+ data->stack = dfb_layer_context_windowstack( data->context );
+
+ break;
+
+ default:
+ return DFB_INVARG;
+ }
+
+ data->level = level;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetOpacity( IDirectFBDisplayLayer *thiz,
+ u8 opacity )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_context_set_opacity( data->context, opacity );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetCurrentOutputField( IDirectFBDisplayLayer *thiz, int *field )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ return dfb_layer_get_current_output_field( data->layer, field );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetFieldParity( IDirectFBDisplayLayer *thiz, int field )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level != DLSCL_EXCLUSIVE)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_context_set_field_parity( data->context, field );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetClipRegions( IDirectFBDisplayLayer *thiz,
+ const DFBRegion *regions,
+ int num_regions,
+ DFBBoolean positive )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!regions || num_regions < 1)
+ return DFB_INVARG;
+
+ if (num_regions > data->desc.clip_regions)
+ return DFB_UNSUPPORTED;
+
+ if (data->level != DLSCL_EXCLUSIVE)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_context_set_clip_regions( data->context, regions, num_regions, positive );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetSourceRectangle( IDirectFBDisplayLayer *thiz,
+ int x,
+ int y,
+ int width,
+ int height )
+{
+ DFBRectangle source = { x, y, width, height };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (x < 0 || y < 0 || width <= 0 || height <= 0)
+ return DFB_INVARG;
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_context_set_sourcerectangle( data->context, &source );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetScreenLocation( IDirectFBDisplayLayer *thiz,
+ float x,
+ float y,
+ float width,
+ float height )
+{
+ DFBLocation location = { x, y, width, height };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_SCREEN_LOCATION ))
+ return DFB_UNSUPPORTED;
+
+ if (width <= 0 || height <= 0)
+ return DFB_INVARG;
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_context_set_screenlocation( data->context, &location );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetScreenPosition( IDirectFBDisplayLayer *thiz,
+ int x,
+ int y )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_SCREEN_POSITION ))
+ return DFB_UNSUPPORTED;
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_context_set_screenposition( data->context, x, y );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetScreenRectangle( IDirectFBDisplayLayer *thiz,
+ int x,
+ int y,
+ int width,
+ int height )
+{
+ DFBRectangle rect = { x, y, width, height };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_SCREEN_LOCATION ))
+ return DFB_UNSUPPORTED;
+
+ if (width <= 0 || height <= 0)
+ return DFB_INVARG;
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_context_set_screenrectangle( data->context, &rect );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetSrcColorKey( IDirectFBDisplayLayer *thiz,
+ u8 r,
+ u8 g,
+ u8 b )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_context_set_src_colorkey( data->context, r, g, b, -1 );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetDstColorKey( IDirectFBDisplayLayer *thiz,
+ u8 r,
+ u8 g,
+ u8 b )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_context_set_dst_colorkey( data->context, r, g, b, -1 );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetLevel( IDirectFBDisplayLayer *thiz,
+ int *level )
+{
+ DFBResult ret;
+ int lvl;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!level)
+ return DFB_INVARG;
+
+ ret = dfb_layer_get_level( data->layer, &lvl );
+ if (ret)
+ return ret;
+
+ *level = lvl;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetLevel( IDirectFBDisplayLayer *thiz,
+ int level )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_LEVELS ))
+ return DFB_UNSUPPORTED;
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_set_level( data->layer, level );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetConfiguration( IDirectFBDisplayLayer *thiz,
+ DFBDisplayLayerConfig *config )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!config)
+ return DFB_INVARG;
+
+ return dfb_layer_context_get_configuration( data->context, config );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_TestConfiguration( IDirectFBDisplayLayer *thiz,
+ const DFBDisplayLayerConfig *config,
+ DFBDisplayLayerConfigFlags *failed )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!config)
+ return DFB_INVARG;
+
+ if (((config->flags & DLCONF_WIDTH) && (config->width < 0)) ||
+ ((config->flags & DLCONF_HEIGHT) && (config->height < 0)))
+ return DFB_INVARG;
+
+ return dfb_layer_context_test_configuration( data->context, config, failed );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetConfiguration( IDirectFBDisplayLayer *thiz,
+ const DFBDisplayLayerConfig *config )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!config)
+ return DFB_INVARG;
+
+ if (((config->flags & DLCONF_WIDTH) && (config->width < 0)) ||
+ ((config->flags & DLCONF_HEIGHT) && (config->height < 0)))
+ return DFB_INVARG;
+
+ switch (data->level) {
+ case DLSCL_EXCLUSIVE:
+ case DLSCL_ADMINISTRATIVE:
+ return dfb_layer_context_set_configuration( data->context, config );
+
+ default:
+ break;
+ }
+
+ return DFB_ACCESSDENIED;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetBackgroundMode( IDirectFBDisplayLayer *thiz,
+ DFBDisplayLayerBackgroundMode background_mode )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ switch (background_mode) {
+ case DLBM_DONTCARE:
+ case DLBM_COLOR:
+ case DLBM_IMAGE:
+ case DLBM_TILE:
+ break;
+
+ default:
+ return DFB_INVARG;
+ }
+
+ return dfb_windowstack_set_background_mode( data->stack, background_mode );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetBackgroundImage( IDirectFBDisplayLayer *thiz,
+ IDirectFBSurface *surface )
+{
+ IDirectFBSurface_data *surface_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+
+ if (!surface)
+ return DFB_INVARG;
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ surface_data = (IDirectFBSurface_data*)surface->priv;
+ if (!surface_data)
+ return DFB_DEAD;
+
+ if (!surface_data->surface)
+ return DFB_DESTROYED;
+
+ return dfb_windowstack_set_background_image( data->stack,
+ surface_data->surface );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetBackgroundColor( IDirectFBDisplayLayer *thiz,
+ u8 r, u8 g, u8 b, u8 a )
+{
+ DFBColor color = { a: a, r: r, g: g, b: b };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_windowstack_set_background_color( data->stack, &color );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_CreateWindow( IDirectFBDisplayLayer *thiz,
+ const DFBWindowDescription *desc,
+ IDirectFBWindow **window )
+{
+ CoreWindow *w;
+ DFBResult ret;
+ DFBWindowDescription wd;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ memset( &wd, 0, sizeof(wd) );
+
+ wd.flags = DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY |
+ DWDESC_PIXELFORMAT | DWDESC_SURFACE_CAPS | DWDESC_CAPS;
+
+ wd.width = (desc->flags & DWDESC_WIDTH) ? desc->width : 480;
+ wd.height = (desc->flags & DWDESC_HEIGHT) ? desc->height : 300;
+ wd.posx = (desc->flags & DWDESC_POSX) ? desc->posx : 100;
+ wd.posy = (desc->flags & DWDESC_POSY) ? desc->posy : 100;
+
+ D_DEBUG_AT( Layer, "CreateWindow() <- %d,%d - %dx%d )\n", wd.posx, wd.posy, wd.width, wd.height );
+
+ if (desc->flags & DWDESC_CAPS)
+ wd.caps = desc->caps;
+
+ wd.caps |= DWCAPS_NOFOCUS; //no focus patch PR brg36mgr#118432
+
+ if (desc->flags & DWDESC_PIXELFORMAT)
+ wd.pixelformat = desc->pixelformat;
+
+ if (desc->flags & DWDESC_SURFACE_CAPS)
+ wd.surface_caps = desc->surface_caps;
+
+ if (desc->flags & DWDESC_PARENT) {
+ wd.flags |= DWDESC_PARENT;
+ wd.parent_id = desc->parent_id;
+ }
+
+ if (desc->flags & DWDESC_OPTIONS) {
+ wd.flags |= DWDESC_OPTIONS;
+ wd.options = desc->options;
+ }
+
+ if (desc->flags & DWDESC_STACKING) {
+ wd.flags |= DWDESC_STACKING;
+ wd.stacking = desc->stacking;
+ }
+
+ if (desc->flags & DWDESC_RESOURCE_ID) {
+ wd.flags |= DWDESC_RESOURCE_ID;
+ wd.resource_id = desc->resource_id;
+ }
+
+ if (desc->flags & DWDESC_TOPLEVEL_ID) {
+ wd.flags |= DWDESC_TOPLEVEL_ID;
+ wd.toplevel_id = desc->toplevel_id;
+ }
+
+
+ if ((wd.caps & ~DWCAPS_ALL) || !window)
+ return DFB_INVARG;
+
+ if (wd.width < 1 || wd.width > 4096 || wd.height < 1 || wd.height > 4096)
+ return DFB_INVARG;
+
+ ret = dfb_layer_context_create_window( data->core, data->context, &wd, &w );
+ if (ret)
+ return ret;
+
+ DIRECT_ALLOCATE_INTERFACE( *window, IDirectFBWindow );
+
+ return IDirectFBWindow_Construct( *window, w, data->layer, data->core );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetWindow( IDirectFBDisplayLayer *thiz,
+ DFBWindowID id,
+ IDirectFBWindow **window )
+{
+ CoreWindow *w;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!window)
+ return DFB_INVARG;
+
+ //remove for now
+ //if (data->level == DLSCL_SHARED)
+ // return DFB_ACCESSDENIED;
+
+ w = dfb_layer_context_find_window( data->context, id );
+ if (!w)
+ return DFB_IDNOTFOUND;
+
+ DIRECT_ALLOCATE_INTERFACE( *window, IDirectFBWindow );
+
+ return IDirectFBWindow_Construct( *window, w, data->layer, data->core );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_EnableCursor( IDirectFBDisplayLayer *thiz, int enable )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_windowstack_cursor_enable( data->core, data->stack, enable );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetCursorPosition( IDirectFBDisplayLayer *thiz,
+ int *x, int *y )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!x && !y)
+ return DFB_INVARG;
+
+ return dfb_windowstack_get_cursor_position( data->stack, x, y );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_WarpCursor( IDirectFBDisplayLayer *thiz, int x, int y )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_windowstack_cursor_warp( data->stack, x, y );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetCursorAcceleration( IDirectFBDisplayLayer *thiz,
+ int numerator,
+ int denominator,
+ int threshold )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (numerator < 0 || denominator < 1 || threshold < 0)
+ return DFB_INVARG;
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_windowstack_cursor_set_acceleration( data->stack, numerator,
+ denominator, threshold );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetCursorShape( IDirectFBDisplayLayer *thiz,
+ IDirectFBSurface *shape,
+ int hot_x,
+ int hot_y )
+{
+ IDirectFBSurface_data *shape_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!shape)
+ return DFB_INVARG;
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ shape_data = (IDirectFBSurface_data*)shape->priv;
+
+ if (hot_x < 0 ||
+ hot_y < 0 ||
+ hot_x >= shape_data->surface->config.size.w ||
+ hot_y >= shape_data->surface->config.size.h)
+ return DFB_INVARG;
+
+ return dfb_windowstack_cursor_set_shape( data->stack,
+ shape_data->surface,
+ hot_x, hot_y );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetCursorOpacity( IDirectFBDisplayLayer *thiz,
+ u8 opacity )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_windowstack_cursor_set_opacity( data->stack, opacity );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetColorAdjustment( IDirectFBDisplayLayer *thiz,
+ DFBColorAdjustment *adj )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!adj)
+ return DFB_INVARG;
+
+ return dfb_layer_context_get_coloradjustment( data->context, adj );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetColorAdjustment( IDirectFBDisplayLayer *thiz,
+ const DFBColorAdjustment *adj )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!adj || (adj->flags & ~DCAF_ALL))
+ return DFB_INVARG;
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ if (!adj->flags)
+ return DFB_OK;
+
+ return dfb_layer_context_set_coloradjustment( data->context, adj );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_WaitForSync( IDirectFBDisplayLayer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ return dfb_layer_wait_vsync( data->layer );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetSourceDescriptions( IDirectFBDisplayLayer *thiz,
+ DFBDisplayLayerSourceDescription *ret_descriptions )
+{
+ int i;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!ret_descriptions)
+ return DFB_INVARG;
+
+ if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_SOURCES ))
+ return DFB_UNSUPPORTED;
+
+ for (i=0; i<data->desc.sources; i++)
+ dfb_layer_get_source_info( data->layer, i, &ret_descriptions[i] );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SwitchContext( IDirectFBDisplayLayer *thiz,
+ DFBBoolean exclusive )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!exclusive && data->level == DLSCL_EXCLUSIVE) {
+ DFBResult ret;
+ CoreLayerContext *context;
+
+ ret = dfb_layer_get_primary_context( data->layer, false, &context );
+ if (ret)
+ return ret;
+
+ dfb_layer_activate_context( data->layer, context );
+
+ dfb_layer_context_unref( context );
+ }
+ else
+ dfb_layer_activate_context( data->layer, data->context );
+
+ data->switch_exclusive = exclusive;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_SetRotation( IDirectFBDisplayLayer *thiz,
+ int rotation )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (data->level == DLSCL_SHARED)
+ return DFB_ACCESSDENIED;
+
+ return dfb_layer_context_set_rotation( data->context, rotation );
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetRotation( IDirectFBDisplayLayer *thiz,
+ int *ret_rotation )
+{
+ CoreLayerContext *context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!ret_rotation)
+ return DFB_INVARG;
+
+ context = data->context;
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ /* Lock the context. */
+ if (dfb_layer_context_lock( context ))
+ return DFB_FUSION;
+
+ *ret_rotation = context->rotation;
+
+ /* Unlock the context. */
+ dfb_layer_context_unlock( context );
+
+ return DFB_OK;
+}
+
+typedef struct {
+ unsigned long resource_id;
+ CoreWindow *window;
+} IDirectFBDisplayLayer_GetWindowByResourceID_Context;
+
+static DFBEnumerationResult
+IDirectFBDisplayLayer_GetWindowByResourceID_WindowCallback( CoreWindow *window,
+ void *_ctx )
+{
+ IDirectFBDisplayLayer_GetWindowByResourceID_Context *ctx = _ctx;
+
+ if (window->surface) {
+ if (window->surface->resource_id == ctx->resource_id) {
+ ctx->window = window;
+
+ return DFENUM_CANCEL;
+ }
+ }
+
+ return DFENUM_OK;
+}
+
+static DFBResult
+IDirectFBDisplayLayer_GetWindowByResourceID( IDirectFBDisplayLayer *thiz,
+ unsigned long resource_id,
+ IDirectFBWindow **ret_window )
+{
+ DFBResult ret;
+ CoreLayerContext *context;
+ CoreWindowStack *stack;
+ IDirectFBDisplayLayer_GetWindowByResourceID_Context ctx;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer)
+
+ if (!ret_window)
+ return DFB_INVARG;
+
+ context = data->context;
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ stack = context->stack;
+ D_ASSERT( stack != NULL );
+
+ ctx.resource_id = resource_id;
+ ctx.window = NULL;
+
+ ret = dfb_layer_context_lock( context );
+ if (ret)
+ return ret;
+
+ ret = dfb_wm_enum_windows( stack, IDirectFBDisplayLayer_GetWindowByResourceID_WindowCallback, &ctx );
+ if (ret == DFB_OK) {
+ if (ctx.window) {
+ IDirectFBWindow *window;
+
+ ret = dfb_window_ref( ctx.window );
+ if (ret == DFB_OK) {
+ DIRECT_ALLOCATE_INTERFACE( window, IDirectFBWindow );
+
+ ret = IDirectFBWindow_Construct( window, ctx.window, data->layer, data->core );
+ if (ret == DFB_OK)
+ *ret_window = window;
+ }
+ }
+ else
+ ret = DFB_IDNOTFOUND;
+ }
+
+ dfb_layer_context_unlock( context );
+
+ return ret;
+}
+
+DFBResult
+IDirectFBDisplayLayer_Construct( IDirectFBDisplayLayer *thiz,
+ CoreLayer *layer,
+ CoreDFB *core )
+{
+ DFBResult ret;
+ CoreLayerContext *context;
+ CoreLayerRegion *region;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBDisplayLayer)
+
+ ret = dfb_layer_get_primary_context( layer, true, &context );
+ if (ret) {
+ DIRECT_DEALLOCATE_INTERFACE( thiz )
+ return ret;
+ }
+
+ ret = dfb_layer_context_get_primary_region( context, true, &region );
+ if (ret) {
+ dfb_layer_context_unref( context );
+ DIRECT_DEALLOCATE_INTERFACE( thiz )
+ return ret;
+ }
+
+ data->ref = 1;
+ data->core = core;
+ data->screen = dfb_layer_screen( layer );
+ data->layer = layer;
+ data->context = context;
+ data->region = region;
+ data->stack = dfb_layer_context_windowstack( context );
+ data->switch_exclusive = DFB_TRUE;
+
+ dfb_layer_get_description( data->layer, &data->desc );
+
+ thiz->AddRef = IDirectFBDisplayLayer_AddRef;
+ thiz->Release = IDirectFBDisplayLayer_Release;
+ thiz->GetID = IDirectFBDisplayLayer_GetID;
+ thiz->GetDescription = IDirectFBDisplayLayer_GetDescription;
+ thiz->GetSurface = IDirectFBDisplayLayer_GetSurface;
+ thiz->GetScreen = IDirectFBDisplayLayer_GetScreen;
+ thiz->SetCooperativeLevel = IDirectFBDisplayLayer_SetCooperativeLevel;
+ thiz->SetOpacity = IDirectFBDisplayLayer_SetOpacity;
+ thiz->GetCurrentOutputField = IDirectFBDisplayLayer_GetCurrentOutputField;
+ thiz->SetSourceRectangle = IDirectFBDisplayLayer_SetSourceRectangle;
+ thiz->SetScreenLocation = IDirectFBDisplayLayer_SetScreenLocation;
+ thiz->SetSrcColorKey = IDirectFBDisplayLayer_SetSrcColorKey;
+ thiz->SetDstColorKey = IDirectFBDisplayLayer_SetDstColorKey;
+ thiz->GetLevel = IDirectFBDisplayLayer_GetLevel;
+ thiz->SetLevel = IDirectFBDisplayLayer_SetLevel;
+ thiz->GetConfiguration = IDirectFBDisplayLayer_GetConfiguration;
+ thiz->TestConfiguration = IDirectFBDisplayLayer_TestConfiguration;
+ thiz->SetConfiguration = IDirectFBDisplayLayer_SetConfiguration;
+ thiz->SetBackgroundMode = IDirectFBDisplayLayer_SetBackgroundMode;
+ thiz->SetBackgroundColor = IDirectFBDisplayLayer_SetBackgroundColor;
+ thiz->SetBackgroundImage = IDirectFBDisplayLayer_SetBackgroundImage;
+ thiz->GetColorAdjustment = IDirectFBDisplayLayer_GetColorAdjustment;
+ thiz->SetColorAdjustment = IDirectFBDisplayLayer_SetColorAdjustment;
+ thiz->CreateWindow = IDirectFBDisplayLayer_CreateWindow;
+ thiz->GetWindow = IDirectFBDisplayLayer_GetWindow;
+ thiz->WarpCursor = IDirectFBDisplayLayer_WarpCursor;
+ thiz->SetCursorAcceleration = IDirectFBDisplayLayer_SetCursorAcceleration;
+ thiz->EnableCursor = IDirectFBDisplayLayer_EnableCursor;
+ thiz->GetCursorPosition = IDirectFBDisplayLayer_GetCursorPosition;
+ thiz->SetCursorShape = IDirectFBDisplayLayer_SetCursorShape;
+ thiz->SetCursorOpacity = IDirectFBDisplayLayer_SetCursorOpacity;
+ thiz->SetFieldParity = IDirectFBDisplayLayer_SetFieldParity;
+ thiz->SetClipRegions = IDirectFBDisplayLayer_SetClipRegions;
+ thiz->WaitForSync = IDirectFBDisplayLayer_WaitForSync;
+ thiz->GetSourceDescriptions = IDirectFBDisplayLayer_GetSourceDescriptions;
+ thiz->SetScreenPosition = IDirectFBDisplayLayer_SetScreenPosition;
+ thiz->SetScreenRectangle = IDirectFBDisplayLayer_SetScreenRectangle;
+ thiz->SwitchContext = IDirectFBDisplayLayer_SwitchContext;
+ thiz->SetRotation = IDirectFBDisplayLayer_SetRotation;
+ thiz->GetRotation = IDirectFBDisplayLayer_GetRotation;
+ thiz->GetWindowByResourceID = IDirectFBDisplayLayer_GetWindowByResourceID;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/display/idirectfbdisplaylayer.h b/Source/DirectFB/src/display/idirectfbdisplaylayer.h
new file mode 100755
index 0000000..9b39468
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbdisplaylayer.h
@@ -0,0 +1,43 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBDISPLAYLAYER_H__
+#define __IDIRECTFBDISPLAYLAYER_H__
+
+#include <directfb.h>
+#include <core/coretypes.h>
+
+/*
+ * initializes interface struct and private data
+ */
+DFBResult IDirectFBDisplayLayer_Construct( IDirectFBDisplayLayer *thiz,
+ CoreLayer *layer,
+ CoreDFB *core );
+
+
+#endif
diff --git a/Source/DirectFB/src/display/idirectfbpalette.c b/Source/DirectFB/src/display/idirectfbpalette.c
new file mode 100755
index 0000000..213af4d
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbpalette.c
@@ -0,0 +1,365 @@
+/*
+ (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 <math.h>
+
+
+#include <directfb.h>
+
+#include <core/surface.h>
+#include <core/palette.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+#include <gfx/util.h>
+
+#include "idirectfbpalette.h"
+
+
+
+static void
+IDirectFBPalette_Destruct( IDirectFBPalette *thiz )
+{
+ IDirectFBPalette_data *data = (IDirectFBPalette_data*)thiz->priv;
+
+ if (data->palette)
+ dfb_palette_unref( data->palette );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+static DirectResult
+IDirectFBPalette_AddRef( IDirectFBPalette *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBPalette_Release( IDirectFBPalette *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ if (--data->ref == 0)
+ IDirectFBPalette_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBPalette_GetCapabilities( IDirectFBPalette *thiz,
+ DFBPaletteCapabilities *caps )
+{
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ palette = data->palette;
+ if (!palette)
+ return DFB_DESTROYED;
+
+ if (!caps)
+ return DFB_INVARG;
+
+ /* FIXME: no caps yet */
+ *caps = DPCAPS_NONE;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBPalette_GetSize( IDirectFBPalette *thiz,
+ unsigned int *size )
+{
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ palette = data->palette;
+ if (!palette)
+ return DFB_DESTROYED;
+
+ if (!size)
+ return DFB_INVARG;
+
+ *size = palette->num_entries;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBPalette_SetEntries( IDirectFBPalette *thiz,
+ const DFBColor *entries,
+ unsigned int num_entries,
+ unsigned int offset )
+{
+ int i;
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ palette = data->palette;
+ if (!palette)
+ return DFB_DESTROYED;
+
+ if (!entries || offset + num_entries > palette->num_entries)
+ return DFB_INVARG;
+
+ if (num_entries) {
+ direct_memcpy( palette->entries + offset, entries, num_entries * sizeof(DFBColor));
+
+ for (i=offset; i<offset+num_entries; i++) {
+ palette->entries_yuv[i].a = palette->entries[i].a;
+
+ RGB_TO_YCBCR( palette->entries[i].r, palette->entries[i].g, palette->entries[i].b,
+ palette->entries_yuv[i].y, palette->entries_yuv[i].u, palette->entries_yuv[i].v );
+ }
+
+ dfb_palette_update( palette, offset, offset + num_entries - 1 );
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBPalette_GetEntries( IDirectFBPalette *thiz,
+ DFBColor *entries,
+ unsigned int num_entries,
+ unsigned int offset )
+{
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ palette = data->palette;
+ if (!palette)
+ return DFB_DESTROYED;
+
+ if (!entries || offset + num_entries > palette->num_entries)
+ return DFB_INVARG;
+
+ direct_memcpy( entries, palette->entries + offset, num_entries * sizeof(DFBColor));
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBPalette_FindBestMatch( IDirectFBPalette *thiz,
+ u8 r,
+ u8 g,
+ u8 b,
+ u8 a,
+ unsigned int *index )
+{
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ if (!index)
+ return DFB_INVARG;
+
+ palette = data->palette;
+ if (!palette)
+ return DFB_DESTROYED;
+
+ *index = dfb_palette_search( palette, r, g, b, a );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBPalette_CreateCopy( IDirectFBPalette *thiz,
+ IDirectFBPalette **interface )
+{
+ DFBResult ret;
+ IDirectFBPalette *iface;
+ CorePalette *palette = NULL;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ if (!data->palette)
+ return DFB_DESTROYED;
+
+ if (!interface)
+ return DFB_INVARG;
+
+ ret = dfb_palette_create( NULL, /* FIXME */
+ data->palette->num_entries, &palette );
+ if (ret)
+ return ret;
+
+ direct_memcpy( palette->entries, data->palette->entries,
+ palette->num_entries * sizeof(DFBColor));
+
+ dfb_palette_update( palette, 0, palette->num_entries - 1 );
+
+
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBPalette );
+
+ ret = IDirectFBPalette_Construct( iface, palette );
+
+ dfb_palette_unref( palette );
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBPalette_SetEntriesYUV( IDirectFBPalette *thiz,
+ const DFBColorYUV *entries,
+ unsigned int num_entries,
+ unsigned int offset )
+{
+ int i;
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ palette = data->palette;
+ if (!palette)
+ return DFB_DESTROYED;
+
+ if (!entries || offset + num_entries > palette->num_entries)
+ return DFB_INVARG;
+
+ if (num_entries) {
+ direct_memcpy( palette->entries_yuv + offset, entries, num_entries * sizeof(DFBColorYUV));
+
+ for (i=offset; i<offset+num_entries; i++) {
+ palette->entries[i].a = palette->entries_yuv[i].a;
+
+ YCBCR_TO_RGB( palette->entries_yuv[i].y, palette->entries_yuv[i].u, palette->entries_yuv[i].v,
+ palette->entries[i].r, palette->entries[i].g, palette->entries[i].b );
+ }
+
+ dfb_palette_update( palette, offset, offset + num_entries - 1 );
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBPalette_GetEntriesYUV( IDirectFBPalette *thiz,
+ DFBColorYUV *ret_entries,
+ unsigned int num_entries,
+ unsigned int offset )
+{
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ palette = data->palette;
+ if (!palette)
+ return DFB_DESTROYED;
+
+ if (!ret_entries || offset + num_entries > palette->num_entries)
+ return DFB_INVARG;
+
+ direct_memcpy( ret_entries, palette->entries_yuv + offset, num_entries * sizeof(DFBColorYUV));
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBPalette_FindBestMatchYUV( IDirectFBPalette *thiz,
+ u8 y,
+ u8 u,
+ u8 v,
+ u8 a,
+ unsigned int *ret_index )
+{
+ int r, g, b;
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBPalette)
+
+ if (!ret_index)
+ return DFB_INVARG;
+
+ palette = data->palette;
+ if (!palette)
+ return DFB_DESTROYED;
+
+ YCBCR_TO_RGB( y, u, v, r, g, b );
+
+ *ret_index = dfb_palette_search( palette, r, g, b, a );
+
+ return DFB_OK;
+}
+
+/******/
+
+DFBResult IDirectFBPalette_Construct( IDirectFBPalette *thiz,
+ CorePalette *palette )
+{
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBPalette)
+
+ if (dfb_palette_ref( palette )) {
+ DIRECT_DEALLOCATE_INTERFACE(thiz);
+ return DFB_FAILURE;
+ }
+
+ data->ref = 1;
+ data->palette = palette;
+
+
+ thiz->AddRef = IDirectFBPalette_AddRef;
+ thiz->Release = IDirectFBPalette_Release;
+
+ thiz->GetCapabilities = IDirectFBPalette_GetCapabilities;
+ thiz->GetSize = IDirectFBPalette_GetSize;
+
+ thiz->SetEntries = IDirectFBPalette_SetEntries;
+ thiz->GetEntries = IDirectFBPalette_GetEntries;
+ thiz->FindBestMatch = IDirectFBPalette_FindBestMatch;
+
+ thiz->CreateCopy = IDirectFBPalette_CreateCopy;
+
+ thiz->SetEntriesYUV = IDirectFBPalette_SetEntriesYUV;
+ thiz->GetEntriesYUV = IDirectFBPalette_GetEntriesYUV;
+ thiz->FindBestMatchYUV = IDirectFBPalette_FindBestMatchYUV;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/display/idirectfbpalette.h b/Source/DirectFB/src/display/idirectfbpalette.h
new file mode 100755
index 0000000..2bedfa2
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbpalette.h
@@ -0,0 +1,51 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBPALETTE_H__
+#define __IDIRECTFBPALETTE_H__
+
+#include <directfb.h>
+#include <core/coretypes.h>
+
+/*
+ * private data struct of IDirectFBPalette
+ */
+typedef struct {
+ int ref; /* reference counter */
+
+ CorePalette *palette; /* the palette object */
+} IDirectFBPalette_data;
+
+/*
+ * initializes interface struct and private data
+ */
+DFBResult IDirectFBPalette_Construct( IDirectFBPalette *thiz,
+ CorePalette *palette );
+
+
+#endif
diff --git a/Source/DirectFB/src/display/idirectfbscreen.c b/Source/DirectFB/src/display/idirectfbscreen.c
new file mode 100755
index 0000000..9fcebdc
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbscreen.c
@@ -0,0 +1,722 @@
+/*
+ (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 <directfb.h>
+
+#include <core/layers.h>
+#include <core/screen.h>
+#include <core/screens.h>
+
+#include <misc/conf.h>
+
+#include <direct/interface.h>
+
+#include "idirectfbscreen.h"
+
+/*
+ * private data struct of IDirectFBScreen
+ */
+typedef struct {
+ int ref; /* reference counter */
+
+ CoreScreen *screen;
+
+ DFBScreenID id;
+ DFBScreenDescription description;
+} IDirectFBScreen_data;
+
+/******************************************************************************/
+
+static DFBResult PatchMixerConfig ( DFBScreenMixerConfig *patched,
+ const DFBScreenMixerConfig *patch );
+static DFBResult PatchEncoderConfig( DFBScreenEncoderConfig *patched,
+ const DFBScreenEncoderConfig *patch );
+static DFBResult PatchOutputConfig ( DFBScreenOutputConfig *patched,
+ const DFBScreenOutputConfig *patch );
+
+/******************************************************************************/
+
+typedef struct {
+ CoreScreen *screen;
+
+ DFBDisplayLayerCallback callback;
+ void *callback_ctx;
+} EnumDisplayLayers_Context;
+
+static DFBEnumerationResult EnumDisplayLayers_Callback( CoreLayer *layer,
+ void *ctx );
+
+/******************************************************************************/
+
+static void
+IDirectFBScreen_Destruct( IDirectFBScreen *thiz )
+{
+// IDirectFBScreen_data *data = (IDirectFBScreen_data*)thiz->priv;
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+static DirectResult
+IDirectFBScreen_AddRef( IDirectFBScreen *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBScreen_Release( IDirectFBScreen *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (--data->ref == 0)
+ IDirectFBScreen_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBScreen_GetID( IDirectFBScreen *thiz,
+ DFBScreenID *id )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!id)
+ return DFB_INVARG;
+
+ *id = data->id;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBScreen_GetDescription( IDirectFBScreen *thiz,
+ DFBScreenDescription *desc )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!desc)
+ return DFB_INVARG;
+
+ *desc = data->description;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBScreen_GetSize( IDirectFBScreen *thiz,
+ int *ret_width,
+ int *ret_height )
+{
+ DFBResult ret;
+ int width = 0;
+ int height = 0;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!ret_width && !ret_height)
+ return DFB_INVARG;
+
+ ret = dfb_screen_get_screen_size( data->screen, &width, &height );
+
+ if (ret_width)
+ *ret_width = width;
+
+ if (ret_height)
+ *ret_height = height;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBScreen_EnumDisplayLayers( IDirectFBScreen *thiz,
+ DFBDisplayLayerCallback callbackfunc,
+ void *callbackdata )
+{
+ EnumDisplayLayers_Context context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+ context.screen = data->screen;
+ context.callback = callbackfunc;
+ context.callback_ctx = callbackdata;
+
+ dfb_layers_enumerate( EnumDisplayLayers_Callback, &context );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBScreen_SetPowerMode( IDirectFBScreen *thiz,
+ DFBScreenPowerMode mode )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ switch (mode) {
+ case DSPM_ON:
+ case DSPM_STANDBY:
+ case DSPM_SUSPEND:
+ case DSPM_OFF:
+ break;
+
+ default:
+ return DFB_INVARG;
+ }
+
+ return dfb_screen_set_powermode( data->screen, mode );
+}
+
+static DFBResult
+IDirectFBScreen_WaitForSync( IDirectFBScreen *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ return dfb_screen_wait_vsync( data->screen );
+}
+
+static DFBResult
+IDirectFBScreen_GetMixerDescriptions( IDirectFBScreen *thiz,
+ DFBScreenMixerDescription *descriptions )
+{
+ int i;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!descriptions)
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_MIXERS))
+ return DFB_UNSUPPORTED;
+
+ for (i=0; i<data->description.mixers; i++)
+ dfb_screen_get_mixer_info( data->screen, i, &descriptions[i] );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBScreen_GetMixerConfiguration( IDirectFBScreen *thiz,
+ int mixer,
+ DFBScreenMixerConfig *config )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!config)
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_MIXERS))
+ return DFB_UNSUPPORTED;
+
+ if (mixer < 0 || mixer >= data->description.mixers)
+ return DFB_INVARG;
+
+ return dfb_screen_get_mixer_config( data->screen, mixer, config );
+}
+
+static DFBResult
+IDirectFBScreen_TestMixerConfiguration( IDirectFBScreen *thiz,
+ int mixer,
+ const DFBScreenMixerConfig *config,
+ DFBScreenMixerConfigFlags *failed )
+{
+ DFBResult ret;
+ DFBScreenMixerConfig patched;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!config || (config->flags & ~DSMCONF_ALL))
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_MIXERS))
+ return DFB_UNSUPPORTED;
+
+ if (mixer < 0 || mixer >= data->description.mixers)
+ return DFB_INVARG;
+
+ /* Get the current configuration. */
+ ret = dfb_screen_get_mixer_config( data->screen, mixer, &patched );
+ if (ret)
+ return ret;
+
+ /* Patch the configuration. */
+ ret = PatchMixerConfig( &patched, config );
+ if (ret)
+ return ret;
+
+ /* Test the patched configuration. */
+ return dfb_screen_test_mixer_config( data->screen,
+ mixer, &patched, failed );
+}
+
+static DFBResult
+IDirectFBScreen_SetMixerConfiguration( IDirectFBScreen *thiz,
+ int mixer,
+ const DFBScreenMixerConfig *config )
+{
+ DFBResult ret;
+ DFBScreenMixerConfig patched;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!config || (config->flags & ~DSMCONF_ALL))
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_MIXERS))
+ return DFB_UNSUPPORTED;
+
+ if (mixer < 0 || mixer >= data->description.mixers)
+ return DFB_INVARG;
+
+ /* Get the current configuration. */
+ ret = dfb_screen_get_mixer_config( data->screen, mixer, &patched );
+ if (ret)
+ return ret;
+
+ /* Patch the configuration. */
+ ret = PatchMixerConfig( &patched, config );
+ if (ret)
+ return ret;
+
+ /* Set the patched configuration. */
+ return dfb_screen_set_mixer_config( data->screen, mixer, &patched );
+}
+
+static DFBResult
+IDirectFBScreen_GetEncoderDescriptions( IDirectFBScreen *thiz,
+ DFBScreenEncoderDescription *descriptions )
+{
+ int i;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!descriptions)
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_ENCODERS))
+ return DFB_UNSUPPORTED;
+
+ for (i=0; i<data->description.encoders; i++)
+ dfb_screen_get_encoder_info( data->screen, i, &descriptions[i] );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBScreen_GetEncoderConfiguration( IDirectFBScreen *thiz,
+ int encoder,
+ DFBScreenEncoderConfig *config )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!config)
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_ENCODERS))
+ return DFB_UNSUPPORTED;
+
+ if (encoder < 0 || encoder >= data->description.encoders)
+ return DFB_INVARG;
+
+ return dfb_screen_get_encoder_config( data->screen, encoder, config );
+}
+
+static DFBResult
+IDirectFBScreen_TestEncoderConfiguration( IDirectFBScreen *thiz,
+ int encoder,
+ const DFBScreenEncoderConfig *config,
+ DFBScreenEncoderConfigFlags *failed )
+{
+ DFBResult ret;
+ DFBScreenEncoderConfig patched;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!config || (config->flags & ~DSECONF_ALL))
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_ENCODERS))
+ return DFB_UNSUPPORTED;
+
+ if (encoder < 0 || encoder >= data->description.encoders)
+ return DFB_INVARG;
+
+ /* Get the current configuration. */
+ ret = dfb_screen_get_encoder_config( data->screen, encoder, &patched );
+ if (ret)
+ return ret;
+
+ /* Patch the configuration. */
+ ret = PatchEncoderConfig( &patched, config );
+ if (ret)
+ return ret;
+
+ /* Test the patched configuration. */
+ return dfb_screen_test_encoder_config( data->screen,
+ encoder, &patched, failed );
+}
+
+static DFBResult
+IDirectFBScreen_SetEncoderConfiguration( IDirectFBScreen *thiz,
+ int encoder,
+ const DFBScreenEncoderConfig *config )
+{
+ DFBResult ret;
+ DFBScreenEncoderConfig patched;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!config || (config->flags & ~DSECONF_ALL))
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_ENCODERS))
+ return DFB_UNSUPPORTED;
+
+ if (encoder < 0 || encoder >= data->description.encoders)
+ return DFB_INVARG;
+
+ /* Get the current configuration. */
+ ret = dfb_screen_get_encoder_config( data->screen, encoder, &patched );
+ if (ret)
+ return ret;
+
+ /* Patch the configuration. */
+ ret = PatchEncoderConfig( &patched, config );
+ if (ret)
+ return ret;
+
+ /* Set the patched configuration. */
+ return dfb_screen_set_encoder_config( data->screen, encoder, &patched );
+}
+
+static DFBResult
+IDirectFBScreen_GetOutputDescriptions( IDirectFBScreen *thiz,
+ DFBScreenOutputDescription *descriptions )
+{
+ int i;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!descriptions)
+ return DFB_INVARG;
+
+ if (!data->description.caps & DSCCAPS_OUTPUTS)
+ return DFB_UNSUPPORTED;
+
+ for (i=0; i<data->description.outputs; i++)
+ dfb_screen_get_output_info( data->screen, i, &descriptions[i] );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBScreen_GetOutputConfiguration( IDirectFBScreen *thiz,
+ int output,
+ DFBScreenOutputConfig *config )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!config)
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_OUTPUTS))
+ return DFB_UNSUPPORTED;
+
+ if (output < 0 || output >= data->description.outputs)
+ return DFB_INVARG;
+
+ return dfb_screen_get_output_config( data->screen, output, config );
+}
+
+static DFBResult
+IDirectFBScreen_TestOutputConfiguration( IDirectFBScreen *thiz,
+ int output,
+ const DFBScreenOutputConfig *config,
+ DFBScreenOutputConfigFlags *failed )
+{
+ DFBResult ret;
+ DFBScreenOutputConfig patched;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!config || (config->flags & ~DSOCONF_ALL))
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_OUTPUTS))
+ return DFB_UNSUPPORTED;
+
+ if (output < 0 || output >= data->description.outputs)
+ return DFB_INVARG;
+
+ /* Get the current configuration. */
+ ret = dfb_screen_get_output_config( data->screen, output, &patched );
+ if (ret)
+ return ret;
+
+ /* Patch the configuration. */
+ ret = PatchOutputConfig( &patched, config );
+ if (ret)
+ return ret;
+
+ /* Test the patched configuration. */
+ return dfb_screen_test_output_config( data->screen,
+ output, &patched, failed );
+}
+
+static DFBResult
+IDirectFBScreen_SetOutputConfiguration( IDirectFBScreen *thiz,
+ int output,
+ const DFBScreenOutputConfig *config )
+{
+ DFBResult ret;
+ DFBScreenOutputConfig patched;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBScreen)
+
+ if (!config || (config->flags & ~DSOCONF_ALL))
+ return DFB_INVARG;
+
+ if (! (data->description.caps & DSCCAPS_OUTPUTS))
+ return DFB_UNSUPPORTED;
+
+ if (output < 0 || output >= data->description.outputs)
+ return DFB_INVARG;
+
+ /* Get the current configuration. */
+ ret = dfb_screen_get_output_config( data->screen, output, &patched );
+ if (ret)
+ return ret;
+
+ /* Patch the configuration. */
+ ret = PatchOutputConfig( &patched, config );
+ if (ret)
+ return ret;
+
+ /* Set the patched configuration. */
+ return dfb_screen_set_output_config( data->screen, output, &patched );
+}
+
+/******************************************************************************/
+
+DFBResult
+IDirectFBScreen_Construct( IDirectFBScreen *thiz,
+ CoreScreen *screen )
+{
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBScreen)
+
+ data->ref = 1;
+ data->screen = screen;
+
+ dfb_screen_get_info( screen, NULL, &data->description );
+ data->id = dfb_screen_id_translated( data->screen );
+
+ thiz->AddRef = IDirectFBScreen_AddRef;
+ thiz->Release = IDirectFBScreen_Release;
+ thiz->GetID = IDirectFBScreen_GetID;
+ thiz->GetDescription = IDirectFBScreen_GetDescription;
+ thiz->GetSize = IDirectFBScreen_GetSize;
+ thiz->EnumDisplayLayers = IDirectFBScreen_EnumDisplayLayers;
+ thiz->SetPowerMode = IDirectFBScreen_SetPowerMode;
+ thiz->WaitForSync = IDirectFBScreen_WaitForSync;
+ thiz->GetMixerDescriptions = IDirectFBScreen_GetMixerDescriptions;
+ thiz->GetMixerConfiguration = IDirectFBScreen_GetMixerConfiguration;
+ thiz->TestMixerConfiguration = IDirectFBScreen_TestMixerConfiguration;
+ thiz->SetMixerConfiguration = IDirectFBScreen_SetMixerConfiguration;
+ thiz->GetEncoderDescriptions = IDirectFBScreen_GetEncoderDescriptions;
+ thiz->GetEncoderConfiguration = IDirectFBScreen_GetEncoderConfiguration;
+ thiz->TestEncoderConfiguration = IDirectFBScreen_TestEncoderConfiguration;
+ thiz->SetEncoderConfiguration = IDirectFBScreen_SetEncoderConfiguration;
+ thiz->GetOutputDescriptions = IDirectFBScreen_GetOutputDescriptions;
+ thiz->GetOutputConfiguration = IDirectFBScreen_GetOutputConfiguration;
+ thiz->TestOutputConfiguration = IDirectFBScreen_TestOutputConfiguration;
+ thiz->SetOutputConfiguration = IDirectFBScreen_SetOutputConfiguration;
+
+ return DFB_OK;
+}
+
+/******************************************************************************/
+
+static DFBResult
+PatchMixerConfig( DFBScreenMixerConfig *patched,
+ const DFBScreenMixerConfig *patch )
+{
+ /* Check for unsupported flags. */
+ if (patch->flags & ~patched->flags)
+ return DFB_UNSUPPORTED;
+
+ if (patch->flags & DSMCONF_TREE)
+ patched->tree = patch->tree;
+
+ if (patch->flags & DSMCONF_LEVEL)
+ patched->level = patch->level;
+
+ if (patch->flags & DSMCONF_LAYERS)
+ patched->layers = patch->layers;
+
+ if (patch->flags & DSMCONF_BACKGROUND)
+ patched->background = patch->background;
+
+ return DFB_OK;
+}
+
+static DFBResult
+PatchEncoderConfig( DFBScreenEncoderConfig *patched,
+ const DFBScreenEncoderConfig *patch )
+{
+ /* Check for unsupported flags. */
+ if (patch->flags & ~patched->flags)
+ return DFB_UNSUPPORTED;
+
+ if (patch->flags & DSECONF_RESOLUTION)
+ patched->resolution = patch->resolution;
+
+ if (patch->flags & DSECONF_FREQUENCY)
+ patched->frequency = patch->frequency;
+
+ /**
+ * Need to be backwards compatible with these so that
+ * they specify resolution and frequency as well.
+ * If you have set a TV_STANDARD
+ * (and set the flag) it will override the resolution and
+ * frequency chosen above.*/
+ if (patch->flags & DSECONF_TV_STANDARD) {
+ patched->tv_standard = patch->tv_standard;
+ switch (patched->tv_standard) {
+ case DSETV_PAL:
+ case DSETV_PAL_BG:
+ case DSETV_PAL_I:
+ case DSETV_PAL_N:
+ case DSETV_PAL_NC:
+ patched->resolution = DSOR_720_576;
+ patched->frequency = DSEF_50HZ;
+ break;
+
+ case DSETV_PAL_60:
+ case DSETV_PAL_M:
+ patched->resolution = DSOR_720_480;
+ patched->frequency = DSEF_60HZ;
+ break;
+
+ case DSETV_SECAM:
+ patched->resolution = DSOR_720_576;
+ patched->frequency = DSEF_50HZ;
+ break;
+
+ case DSETV_NTSC:
+ case DSETV_NTSC_M_JPN:
+ case DSETV_NTSC_443:
+ patched->resolution = DSOR_720_480;
+ patched->frequency = DSEF_60HZ;
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (patch->flags & DSECONF_TEST_PICTURE)
+ patched->test_picture = patch->test_picture;
+
+ if (patch->flags & DSECONF_MIXER)
+ patched->mixer = patch->mixer;
+
+ if (patch->flags & DSECONF_OUT_SIGNALS)
+ patched->out_signals = patch->out_signals;
+
+ if (patch->flags & DSECONF_SCANMODE)
+ patched->scanmode = patch->scanmode;
+
+ if (patch->flags & DSECONF_ADJUSTMENT)
+ patched->adjustment = patch->adjustment;
+
+ if (patch->flags & DSECONF_CONNECTORS)
+ patched->out_connectors = patch->out_connectors;
+
+ if (patch->flags & DSECONF_SLOW_BLANKING)
+ patched->slow_blanking = patch->slow_blanking;
+
+ return DFB_OK;
+}
+
+static DFBResult
+PatchOutputConfig( DFBScreenOutputConfig *patched,
+ const DFBScreenOutputConfig *patch )
+{
+ /* Check for unsupported flags. */
+ if (patch->flags & ~patched->flags)
+ return DFB_UNSUPPORTED;
+
+ if (patch->flags & DSOCONF_RESOLUTION)
+ patched->resolution = patch->resolution;
+
+ if (patch->flags & DSOCONF_ENCODER)
+ patched->encoder = patch->encoder;
+
+ if (patch->flags & DSOCONF_SIGNALS)
+ patched->out_signals = patch->out_signals;
+
+ if (patch->flags & DSOCONF_CONNECTORS)
+ patched->out_connectors = patch->out_connectors;
+
+ if (patch->flags & DSOCONF_SLOW_BLANKING)
+ patched->slow_blanking = patch->slow_blanking;
+
+ return DFB_OK;
+}
+
+static DFBEnumerationResult
+EnumDisplayLayers_Callback( CoreLayer *layer, void *ctx )
+{
+ DFBDisplayLayerDescription desc;
+ DFBDisplayLayerID id;
+ EnumDisplayLayers_Context *context = (EnumDisplayLayers_Context*) ctx;
+
+ if (dfb_layer_screen( layer ) != context->screen)
+ return DFENUM_OK;
+
+ id = dfb_layer_id_translated( layer );
+
+ if (dfb_config->primary_only && id != DLID_PRIMARY)
+ return DFENUM_OK;
+
+ dfb_layer_get_description( layer, &desc );
+
+ return context->callback( id, desc, context->callback_ctx );
+}
+
diff --git a/Source/DirectFB/src/display/idirectfbscreen.h b/Source/DirectFB/src/display/idirectfbscreen.h
new file mode 100755
index 0000000..682ee8b
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbscreen.h
@@ -0,0 +1,42 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBSCREEN_H__
+#define __IDIRECTFBSCREEN_H__
+
+#include <directfb.h>
+#include <core/coretypes.h>
+
+/*
+ * initializes interface struct and private data
+ */
+DFBResult IDirectFBScreen_Construct( IDirectFBScreen *thiz,
+ CoreScreen *screen );
+
+
+#endif
diff --git a/Source/DirectFB/src/display/idirectfbsurface.c b/Source/DirectFB/src/display/idirectfbsurface.c
new file mode 100755
index 0000000..bd23975
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbsurface.c
@@ -0,0 +1,2841 @@
+/*
+ (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 <alloca.h>
+
+#include <math.h>
+
+
+#include <directfb.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/gfxcard.h>
+#include <core/fonts.h>
+#include <core/state.h>
+#include <core/palette.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+
+#include <media/idirectfbfont.h>
+
+#include <display/idirectfbsurface.h>
+#include <display/idirectfbpalette.h>
+
+#include <misc/util.h>
+
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+#include <gfx/util.h>
+
+
+D_DEBUG_DOMAIN( Surface, "IDirectFBSurface", "IDirectFBSurface Interface" );
+
+/**********************************************************************************************************************/
+
+static ReactionResult IDirectFBSurface_listener( const void *msg_data, void *ctx );
+
+/**********************************************************************************************************************/
+
+void
+IDirectFBSurface_Destruct( IDirectFBSurface *thiz )
+{
+ IDirectFBSurface_data *data;
+ IDirectFBSurface *parent;
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ D_ASSERT( thiz != NULL );
+
+ data = thiz->priv;
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( data->children_data == NULL );
+
+ parent = data->parent;
+ if (parent) {
+ IDirectFBSurface_data *parent_data;
+
+ D_MAGIC_ASSERT( (IAny*) parent, DirectInterface );
+
+ parent_data = parent->priv;
+ D_ASSERT( parent_data != NULL );
+
+ pthread_mutex_lock( &parent_data->children_lock );
+
+ direct_list_remove( &parent_data->children_data, &data->link );
+
+ pthread_mutex_unlock( &parent_data->children_lock );
+ }
+
+ if (data->surface)
+ dfb_surface_detach( data->surface, &data->reaction );
+
+ dfb_state_stop_drawing( &data->state );
+
+ dfb_state_set_destination( &data->state, NULL );
+ dfb_state_set_source( &data->state, NULL );
+ dfb_state_set_source_mask( &data->state, NULL );
+
+ dfb_state_destroy( &data->state );
+
+ if (data->font)
+ data->font->Release( data->font );
+
+ if (data->surface) {
+ if (data->locked)
+ dfb_surface_unlock_buffer( data->surface, &data->lock );
+
+ dfb_surface_unref( data->surface );
+ }
+
+ pthread_mutex_destroy( &data->children_lock );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+
+ if (parent)
+ parent->Release( parent );
+}
+
+static DirectResult
+IDirectFBSurface_AddRef( IDirectFBSurface *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBSurface_Release( IDirectFBSurface *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (--data->ref == 0)
+ IDirectFBSurface_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+
+static DFBResult
+IDirectFBSurface_GetPixelFormat( IDirectFBSurface *thiz,
+ DFBSurfacePixelFormat *format )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (!format)
+ return DFB_INVARG;
+
+ *format = data->surface->config.format;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetAccelerationMask( IDirectFBSurface *thiz,
+ IDirectFBSurface *source,
+ DFBAccelerationMask *ret_mask )
+{
+ DFBAccelerationMask mask = DFXL_NONE;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (!ret_mask)
+ return DFB_INVARG;
+
+ dfb_state_lock( &data->state );
+
+ /* Check drawing functions */
+ if (dfb_gfxcard_state_check( &data->state, DFXL_FILLRECTANGLE ))
+ mask |= DFXL_FILLRECTANGLE;
+
+ if (dfb_gfxcard_state_check( &data->state, DFXL_DRAWRECTANGLE ))
+ mask |= DFXL_DRAWRECTANGLE;
+
+ if (dfb_gfxcard_state_check( &data->state, DFXL_DRAWLINE ))
+ mask |= DFXL_DRAWLINE;
+
+ if (dfb_gfxcard_state_check( &data->state, DFXL_FILLTRIANGLE ))
+ mask |= DFXL_FILLTRIANGLE;
+
+ dfb_state_unlock( &data->state );
+
+ /* Check blitting functions */
+ if (source) {
+ IDirectFBSurface_data *src_data = source->priv;
+
+ dfb_state_set_source( &data->state, src_data->surface );
+
+ dfb_state_lock( &data->state );
+
+ if (dfb_gfxcard_state_check( &data->state, DFXL_BLIT ))
+ mask |= DFXL_BLIT;
+
+ if (dfb_gfxcard_state_check( &data->state, DFXL_STRETCHBLIT ))
+ mask |= DFXL_STRETCHBLIT;
+
+ if (dfb_gfxcard_state_check( &data->state, DFXL_TEXTRIANGLES ))
+ mask |= DFXL_TEXTRIANGLES;
+
+ dfb_state_unlock( &data->state );
+ }
+
+ /* Check text rendering function */
+ if (data->font) {
+ IDirectFBFont_data *font_data = data->font->priv;
+
+ if (dfb_gfxcard_drawstring_check_state( font_data->font, &data->state ))
+ mask |= DFXL_DRAWSTRING;
+ }
+
+ *ret_mask = mask;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetPosition( IDirectFBSurface *thiz,
+ int *x,
+ int *y )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!x && !y)
+ return DFB_INVARG;
+
+ if (x)
+ *x = data->area.wanted.x;
+
+ if (y)
+ *y = data->area.wanted.y;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetSize( IDirectFBSurface *thiz,
+ int *width,
+ int *height )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!width && !height)
+ return DFB_INVARG;
+
+ if (width)
+ *width = data->area.wanted.w;
+
+ if (height)
+ *height = data->area.wanted.h;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetVisibleRectangle( IDirectFBSurface *thiz,
+ DFBRectangle *rect )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!rect)
+ return DFB_INVARG;
+
+ rect->x = data->area.current.x - data->area.wanted.x;
+ rect->y = data->area.current.y - data->area.wanted.y;
+ rect->w = data->area.current.w;
+ rect->h = data->area.current.h;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetCapabilities( IDirectFBSurface *thiz,
+ DFBSurfaceCapabilities *caps )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!caps)
+ return DFB_INVARG;
+
+ *caps = data->caps;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetPalette( IDirectFBSurface *thiz,
+ IDirectFBPalette **interface )
+{
+ DFBResult ret;
+ CoreSurface *surface;
+ IDirectFBPalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ if (!surface->palette)
+ return DFB_UNSUPPORTED;
+
+ if (!interface)
+ return DFB_INVARG;
+
+ DIRECT_ALLOCATE_INTERFACE( palette, IDirectFBPalette );
+
+ ret = IDirectFBPalette_Construct( palette, surface->palette );
+ if (ret)
+ return ret;
+
+ *interface = palette;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetPalette( IDirectFBSurface *thiz,
+ IDirectFBPalette *palette )
+{
+ CoreSurface *surface;
+ IDirectFBPalette_data *palette_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ if (!palette)
+ return DFB_INVARG;
+
+ if (! DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ return DFB_UNSUPPORTED;
+
+ palette_data = (IDirectFBPalette_data*) palette->priv;
+ if (!palette_data)
+ return DFB_DEAD;
+
+ if (!palette_data->palette)
+ return DFB_DESTROYED;
+
+ dfb_surface_set_palette( surface, palette_data->palette );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetAlphaRamp( IDirectFBSurface *thiz,
+ u8 a0,
+ u8 a1,
+ u8 a2,
+ u8 a3 )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ dfb_surface_set_alpha_ramp( data->surface, a0, a1, a2, a3 );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_Lock( IDirectFBSurface *thiz,
+ DFBSurfaceLockFlags flags,
+ void **ret_ptr, int *ret_pitch )
+{
+ DFBResult ret;
+ CoreSurfaceBufferRole role = CSBR_FRONT;
+ CoreSurfaceAccessFlags access = CSAF_NONE;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!flags || !ret_ptr || !ret_pitch)
+ return DFB_INVARG;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (flags & DSLF_READ)
+ access |= CSAF_READ;
+
+ if (flags & DSLF_WRITE) {
+ access |= CSAF_WRITE;
+ role = CSBR_BACK;
+ }
+
+ ret = dfb_surface_lock_buffer( data->surface, role, CSAID_CPU, access, &data->lock );
+ if (ret)
+ return ret;
+
+ data->locked = true;
+
+ *ret_ptr = data->lock.addr + data->lock.pitch * data->area.current.y +
+ DFB_BYTES_PER_LINE( data->surface->config.format, data->area.current.x );
+ *ret_pitch = data->lock.pitch;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetFramebufferOffset( IDirectFBSurface *thiz,
+ int *offset )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (!offset)
+ return DFB_INVARG;
+
+ if (!data->locked)
+ return DFB_ACCESSDENIED;
+
+ if (!data->lock.phys) {
+ /* The surface is probably in a system buffer if there's no physical address. */
+ return DFB_UNSUPPORTED;
+ }
+
+ *offset = data->lock.offset;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_Unlock( IDirectFBSurface *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (data->locked) {
+ dfb_surface_unlock_buffer( data->surface, &data->lock );
+
+ data->locked = false;
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_Write( IDirectFBSurface *thiz,
+ const DFBRectangle *rect,
+ const void *ptr,
+ int pitch )
+{
+ CoreSurface *surface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p, %p [%d] )\n", __FUNCTION__, thiz, rect, ptr, pitch );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ if (!rect || !ptr || pitch < DFB_BYTES_PER_LINE(surface->config.format,rect->w ) )
+ return DFB_INVARG;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ D_DEBUG_AT( Surface, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( rect ) );
+
+ //FIXME: check rectangle
+
+ return dfb_surface_write_buffer( data->surface, CSBR_BACK, ptr, pitch, rect );
+}
+
+static DFBResult
+IDirectFBSurface_Read( IDirectFBSurface *thiz,
+ const DFBRectangle *rect,
+ void *ptr,
+ int pitch )
+{
+ CoreSurface *surface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p, %p [%d] )\n", __FUNCTION__, thiz, rect, ptr, pitch );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ if (!rect || !ptr || pitch < DFB_BYTES_PER_LINE(surface->config.format,rect->w ) )
+ return DFB_INVARG;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ D_DEBUG_AT( Surface, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( rect ) );
+
+ //FIXME: check rectangle
+
+ return dfb_surface_read_buffer( data->surface, CSBR_FRONT, ptr, pitch, rect );
+}
+
+static DFBResult
+IDirectFBSurface_Flip( IDirectFBSurface *thiz,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags )
+{
+ DFBResult ret;
+ DFBRegion reg;
+ CoreSurface *surface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p, 0x%08x )\n", __FUNCTION__, thiz, region, flags );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!(surface->config.caps & DSCAPS_FLIPPING))
+ return DFB_UNSUPPORTED;
+
+ if (!data->area.current.w || !data->area.current.h ||
+ (region && (region->x1 > region->x2 || region->y1 > region->y2)))
+ return DFB_INVAREA;
+
+ IDirectFBSurface_StopAll( data );
+
+ /* FIXME: This is a temporary workaround for LiTE. */
+ if (data->parent) {
+ IDirectFBSurface_data *parent_data;
+
+ DIRECT_INTERFACE_GET_DATA_FROM( data->parent, parent_data, IDirectFBSurface );
+
+ /* Signal end of sequence of operations. */
+ dfb_state_lock( &parent_data->state );
+ dfb_state_stop_drawing( &parent_data->state );
+ dfb_state_unlock( &parent_data->state );
+ }
+
+ dfb_region_from_rectangle( &reg, &data->area.current );
+
+ if (region) {
+ DFBRegion clip = DFB_REGION_INIT_TRANSLATED( region,
+ data->area.wanted.x,
+ data->area.wanted.y );
+
+ if (!dfb_region_region_intersect( &reg, &clip ))
+ return DFB_INVAREA;
+ }
+
+ D_DEBUG_AT( Surface, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION( &reg ) );
+
+ if (!(flags & DSFLIP_BLIT) && reg.x1 == 0 && reg.y1 == 0 &&
+ reg.x2 == surface->config.size.w - 1 && reg.y2 == surface->config.size.h - 1)
+ {
+ ret = dfb_surface_lock( data->surface );
+ if (ret)
+ return ret;
+
+ dfb_surface_flip( data->surface, false );
+
+ dfb_surface_unlock( data->surface );
+ }
+ else
+ dfb_back_to_front_copy( data->surface, &reg );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetField( IDirectFBSurface *thiz,
+ int field )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (!(data->surface->config.caps & DSCAPS_INTERLACED))
+ return DFB_UNSUPPORTED;
+
+ if (field < 0 || field > 1)
+ return DFB_INVARG;
+
+ dfb_surface_set_field( data->surface, field );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_Clear( IDirectFBSurface *thiz,
+ u8 r, u8 g, u8 b, u8 a )
+{
+ DFBColor old_color;
+ unsigned int old_index;
+ DFBSurfaceDrawingFlags old_flags;
+ DFBSurfaceRenderOptions old_options;
+ CoreSurface *surface;
+ DFBColor color = { a, r, g, b };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, 0x%08x )\n", __FUNCTION__, thiz, PIXEL_ARGB(a,r,g,b) );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ /* save current color and drawing flags */
+ old_color = data->state.color;
+ old_index = data->state.color_index;
+ old_flags = data->state.drawingflags;
+ old_options = data->state.render_options;
+
+ /* set drawing flags */
+ dfb_state_set_drawing_flags( &data->state, DSDRAW_NOFX );
+
+ /* set render options */
+ dfb_state_set_render_options( &data->state, DSRO_NONE );
+
+ /* set color */
+ if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ dfb_state_set_color_index( &data->state,
+ dfb_palette_search( surface->palette, r, g, b, a ) );
+
+ dfb_state_set_color( &data->state, &color );
+
+ /* fill the visible rectangle */
+ dfb_gfxcard_fillrectangles( &data->area.current, 1, &data->state );
+
+ /* clear the depth buffer */
+ if (data->caps & DSCAPS_DEPTH)
+ dfb_clear_depth( data->surface, &data->state.clip );
+
+ /* restore drawing flags */
+ dfb_state_set_drawing_flags( &data->state, old_flags );
+
+ /* restore render options */
+ dfb_state_set_render_options( &data->state, old_options );
+
+ /* restore color */
+ if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ dfb_state_set_color_index( &data->state, old_index );
+
+ dfb_state_set_color( &data->state, &old_color );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetClip( IDirectFBSurface *thiz, const DFBRegion *clip )
+{
+ DFBRegion newclip;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p )\n", __FUNCTION__, thiz, clip );
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (clip) {
+ newclip = DFB_REGION_INIT_TRANSLATED( clip, data->area.wanted.x, data->area.wanted.y );
+
+ D_DEBUG_AT( Surface, " <- %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION(&newclip) );
+
+ if (!dfb_unsafe_region_rectangle_intersect( &newclip,
+ &data->area.wanted ))
+ return DFB_INVARG;
+
+ D_DEBUG_AT( Surface, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION(&newclip) );
+
+ data->clip_set = true;
+ data->clip_wanted = newclip;
+
+ if (!dfb_region_rectangle_intersect( &newclip, &data->area.current ))
+ return DFB_INVAREA;
+ }
+ else {
+ dfb_region_from_rectangle( &newclip, &data->area.current );
+ data->clip_set = false;
+ }
+
+ D_DEBUG_AT( Surface, " => CLIP %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION(&newclip) );
+
+ dfb_state_set_clip( &data->state, &newclip );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetClip( IDirectFBSurface *thiz, DFBRegion *ret_clip )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!ret_clip)
+ return DFB_INVARG;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ *ret_clip = DFB_REGION_INIT_TRANSLATED( &data->state.clip, -data->area.wanted.x, -data->area.wanted.y );
+
+ D_DEBUG_AT( Surface, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION(ret_clip) );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetColor( IDirectFBSurface *thiz,
+ u8 r, u8 g, u8 b, u8 a )
+{
+ CoreSurface *surface;
+ DFBColor color = { a, r, g, b };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, COLOR 0x%08x )\n", __FUNCTION__, thiz, PIXEL_ARGB(a, r, g, b) );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ dfb_state_set_color( &data->state, &color );
+
+ if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ dfb_state_set_color_index( &data->state,
+ dfb_palette_search( surface->palette, r, g, b, a ) );
+
+ data->state.colors[0] = data->state.color;
+ data->state.color_indices[0] = data->state.color_index;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetColors( IDirectFBSurface *thiz,
+ const DFBColorID *ids,
+ const DFBColor *colors,
+ unsigned int num )
+{
+ unsigned int i;
+ CoreSurface *surface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p, %p, %u )\n", __FUNCTION__, thiz, ids, colors, num );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ for (i=0; i<num; i++) {
+ D_DEBUG_AT( Surface, " -> [%d] id %d = %02x %02x %02x %02x\n",
+ i, ids[i], colors[i].a, colors[i].r, colors[i].g, colors[i].b );
+
+ if (ids[i] >= DFB_COLOR_IDS_MAX)
+ return DFB_INVARG;
+
+ data->state.colors[ids[i]] = colors[i];
+
+ if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ data->state.color_indices[ids[i]] = dfb_palette_search( surface->palette,
+ colors[i].r, colors[i].g, colors[i].b, colors[i].a );
+ }
+
+ dfb_state_set_color( &data->state, &data->state.colors[0] );
+ dfb_state_set_color_index( &data->state, data->state.color_indices[0] );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetColorIndex( IDirectFBSurface *thiz,
+ unsigned int index )
+{
+ CoreSurface *surface;
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, COLOR INDEX %3u )\n", __FUNCTION__, thiz, index );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ if (! DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ return DFB_UNSUPPORTED;
+
+ palette = surface->palette;
+ if (!palette)
+ return DFB_UNSUPPORTED;
+
+ if (index > palette->num_entries)
+ return DFB_INVARG;
+
+ dfb_state_set_color( &data->state, &palette->entries[index] );
+
+ dfb_state_set_color_index( &data->state, index );
+
+ data->state.colors[0] = data->state.color;
+ data->state.color_indices[0] = data->state.color_index;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetSrcBlendFunction( IDirectFBSurface *thiz,
+ DFBSurfaceBlendFunction src )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %d )\n", __FUNCTION__, thiz, src );
+
+ switch (src) {
+ case DSBF_ZERO:
+ case DSBF_ONE:
+ case DSBF_SRCCOLOR:
+ case DSBF_INVSRCCOLOR:
+ case DSBF_SRCALPHA:
+ case DSBF_INVSRCALPHA:
+ case DSBF_DESTALPHA:
+ case DSBF_INVDESTALPHA:
+ case DSBF_DESTCOLOR:
+ case DSBF_INVDESTCOLOR:
+ case DSBF_SRCALPHASAT:
+ dfb_state_set_src_blend( &data->state, src );
+ return DFB_OK;
+
+ default:
+ break;
+ }
+
+ return DFB_INVARG;
+}
+
+static DFBResult
+IDirectFBSurface_SetDstBlendFunction( IDirectFBSurface *thiz,
+ DFBSurfaceBlendFunction dst )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %d )\n", __FUNCTION__, thiz, dst );
+
+ switch (dst) {
+ case DSBF_ZERO:
+ case DSBF_ONE:
+ case DSBF_SRCCOLOR:
+ case DSBF_INVSRCCOLOR:
+ case DSBF_SRCALPHA:
+ case DSBF_INVSRCALPHA:
+ case DSBF_DESTALPHA:
+ case DSBF_INVDESTALPHA:
+ case DSBF_DESTCOLOR:
+ case DSBF_INVDESTCOLOR:
+ case DSBF_SRCALPHASAT:
+ dfb_state_set_dst_blend( &data->state, dst );
+ return DFB_OK;
+
+ default:
+ break;
+ }
+
+ return DFB_INVARG;
+}
+
+static DFBResult
+IDirectFBSurface_SetPorterDuff( IDirectFBSurface *thiz,
+ DFBSurfacePorterDuffRule rule )
+{
+ DFBSurfaceBlendFunction src;
+ DFBSurfaceBlendFunction dst;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %d )\n", __FUNCTION__, thiz, rule );
+
+
+ switch (rule) {
+ case DSPD_NONE:
+ src = DSBF_SRCALPHA;
+ dst = DSBF_INVSRCALPHA;
+ break;
+ case DSPD_CLEAR:
+ src = DSBF_ZERO;
+ dst = DSBF_ZERO;
+ break;
+ case DSPD_SRC:
+ src = DSBF_ONE;
+ dst = DSBF_ZERO;
+ break;
+ case DSPD_SRC_OVER:
+ src = DSBF_ONE;
+ dst = DSBF_INVSRCALPHA;
+ break;
+ case DSPD_DST_OVER:
+ src = DSBF_INVDESTALPHA;
+ dst = DSBF_ONE;
+ break;
+ case DSPD_SRC_IN:
+ src = DSBF_DESTALPHA;
+ dst = DSBF_ZERO;
+ break;
+ case DSPD_DST_IN:
+ src = DSBF_ZERO;
+ dst = DSBF_SRCALPHA;
+ break;
+ case DSPD_SRC_OUT:
+ src = DSBF_INVDESTALPHA;
+ dst = DSBF_ZERO;
+ break;
+ case DSPD_DST_OUT:
+ src = DSBF_ZERO;
+ dst = DSBF_INVSRCALPHA;
+ break;
+ case DSPD_SRC_ATOP:
+ src = DSBF_DESTALPHA;
+ dst = DSBF_INVSRCALPHA;
+ break;
+ case DSPD_DST_ATOP:
+ src = DSBF_INVDESTALPHA;
+ dst = DSBF_SRCALPHA;
+ break;
+ case DSPD_ADD:
+ src = DSBF_ONE;
+ dst = DSBF_ONE;
+ break;
+ case DSPD_XOR:
+ src = DSBF_INVDESTALPHA;
+ dst = DSBF_INVSRCALPHA;
+ break;
+ default:
+ return DFB_INVARG;
+ }
+
+ dfb_state_set_src_blend( &data->state, src );
+ dfb_state_set_dst_blend( &data->state, dst );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetSrcColorKey( IDirectFBSurface *thiz,
+ u8 r,
+ u8 g,
+ u8 b )
+{
+ CoreSurface *surface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ data->src_key.r = r;
+ data->src_key.g = g;
+ data->src_key.b = b;
+
+ if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ data->src_key.value = dfb_palette_search( surface->palette,
+ r, g, b, 0x80 );
+ else
+ data->src_key.value = dfb_color_to_pixel( surface->config.format, r, g, b );
+
+ /* The new key won't be applied to this surface's state.
+ The key will be taken by the destination surface to apply it
+ to its state when source color keying is used. */
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetSrcColorKeyIndex( IDirectFBSurface *thiz,
+ unsigned int index )
+{
+ CoreSurface *surface;
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ if (! DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ return DFB_UNSUPPORTED;
+
+ palette = surface->palette;
+ if (!palette)
+ return DFB_UNSUPPORTED;
+
+ if (index > palette->num_entries)
+ return DFB_INVARG;
+
+ data->src_key.r = palette->entries[index].r;
+ data->src_key.g = palette->entries[index].g;
+ data->src_key.b = palette->entries[index].b;
+
+ data->src_key.value = index;
+
+ /* The new key won't be applied to this surface's state.
+ The key will be taken by the destination surface to apply it
+ to its state when source color keying is used. */
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetDstColorKey( IDirectFBSurface *thiz,
+ u8 r,
+ u8 g,
+ u8 b )
+{
+ CoreSurface *surface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ data->dst_key.r = r;
+ data->dst_key.g = g;
+ data->dst_key.b = b;
+
+ if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ data->dst_key.value = dfb_palette_search( surface->palette,
+ r, g, b, 0x80 );
+ else
+ data->dst_key.value = dfb_color_to_pixel( surface->config.format, r, g, b );
+
+ dfb_state_set_dst_colorkey( &data->state, data->dst_key.value );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetDstColorKeyIndex( IDirectFBSurface *thiz,
+ unsigned int index )
+{
+ CoreSurface *surface;
+ CorePalette *palette;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ if (! DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ return DFB_UNSUPPORTED;
+
+ palette = surface->palette;
+ if (!palette)
+ return DFB_UNSUPPORTED;
+
+ if (index > palette->num_entries)
+ return DFB_INVARG;
+
+ data->dst_key.r = palette->entries[index].r;
+ data->dst_key.g = palette->entries[index].g;
+ data->dst_key.b = palette->entries[index].b;
+
+ data->dst_key.value = index;
+
+ dfb_state_set_dst_colorkey( &data->state, data->dst_key.value );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetIndexTranslation( IDirectFBSurface *thiz,
+ const int *indices,
+ int num_indices )
+{
+ CoreSurface *surface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ if (! DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ return DFB_UNSUPPORTED;
+
+ if (!indices && num_indices > 0)
+ return DFB_INVAREA;
+
+ if (num_indices < 0 || num_indices > 256)
+ return DFB_INVARG;
+
+ return dfb_state_set_index_translation( &data->state, indices, num_indices );
+}
+
+static DFBResult
+IDirectFBSurface_SetFont( IDirectFBSurface *thiz,
+ IDirectFBFont *font )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p )\n", __FUNCTION__, thiz, font );
+
+ if (data->font != font) {
+ if (font) {
+ IDirectFBFont_data *font_data;
+
+ ret = font->AddRef( font );
+ if (ret)
+ return ret;
+
+ DIRECT_INTERFACE_GET_DATA_FROM( font, font_data, IDirectFBFont );
+
+ data->encoding = font_data->encoding;
+ }
+
+ if (data->font)
+ data->font->Release( data->font );
+
+ data->font = font;
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetFont( IDirectFBSurface *thiz,
+ IDirectFBFont **ret_font )
+{
+ DFBResult ret;
+ IDirectFBFont *font;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!ret_font)
+ return DFB_INVARG;
+
+ font = data->font;
+ if (!font) {
+ *ret_font = NULL;
+ return DFB_MISSINGFONT;
+ }
+
+ ret = font->AddRef( font );
+ if (ret)
+ return ret;
+
+ *ret_font = font;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetDrawingFlags( IDirectFBSurface *thiz,
+ DFBSurfaceDrawingFlags flags )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, 0x%08x )\n", __FUNCTION__, thiz, flags );
+
+ dfb_state_set_drawing_flags( &data->state, flags );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_FillRectangle( IDirectFBSurface *thiz,
+ int x, int y, int w, int h )
+{
+ DFBRectangle rect = { x, y, w, h };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+ D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4dx%4d\n", 0, x, y, w, h );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (w<=0 || h<=0)
+ return DFB_INVARG;
+
+ rect.x += data->area.wanted.x;
+ rect.y += data->area.wanted.y;
+
+ dfb_gfxcard_fillrectangles( &rect, 1, &data->state );
+
+ return DFB_OK;
+}
+
+
+static DFBResult
+IDirectFBSurface_DrawLine( IDirectFBSurface *thiz,
+ int x1, int y1, int x2, int y2 )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+ D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4d,%4d\n", 0, x1, y1, x2, y2 );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if ((x1 == x2 || y1 == y2) && !(data->state.render_options & DSRO_MATRIX)) {
+ DFBRectangle rect;
+
+ if (x1 <= x2) {
+ rect.x = x1;
+ rect.w = x2 - x1 + 1;
+ }
+ else {
+ rect.x = x2;
+ rect.w = x1 - x2 + 1;
+ }
+
+ if (y1 <= y2) {
+ rect.y = y1;
+ rect.h = y2 - y1 + 1;
+ }
+ else {
+ rect.y = y2;
+ rect.h = y1 - y2 + 1;
+ }
+
+ rect.x += data->area.wanted.x;
+ rect.y += data->area.wanted.y;
+
+ dfb_gfxcard_fillrectangles( &rect, 1, &data->state );
+ }
+ else {
+ DFBRegion line = { x1, y1, x2, y2 };
+
+ line.x1 += data->area.wanted.x;
+ line.x2 += data->area.wanted.x;
+ line.y1 += data->area.wanted.y;
+ line.y2 += data->area.wanted.y;
+
+ dfb_gfxcard_drawlines( &line, 1, &data->state );
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_DrawLines( IDirectFBSurface *thiz,
+ const DFBRegion *lines,
+ unsigned int num_lines )
+{
+ unsigned int i;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, thiz, lines, num_lines );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!lines || !num_lines)
+ return DFB_INVARG;
+
+ /* Check if all lines are either horizontal or vertical */
+ for (i=0; i<num_lines; i++) {
+ if (lines[i].x1 != lines[i].x2 && lines[i].y1 != lines[i].y2)
+ break;
+ }
+
+ /* Use real line drawing? */
+ if (i < num_lines) {
+ DFBRegion *local_lines = alloca(sizeof(DFBRegion) * num_lines);
+
+ if (data->area.wanted.x || data->area.wanted.y) {
+ for (i=0; i<num_lines; i++) {
+ local_lines[i].x1 = lines[i].x1 + data->area.wanted.x;
+ local_lines[i].x2 = lines[i].x2 + data->area.wanted.x;
+ local_lines[i].y1 = lines[i].y1 + data->area.wanted.y;
+ local_lines[i].y2 = lines[i].y2 + data->area.wanted.y;
+ }
+ }
+ else
+ /* clipping may modify lines, so we copy them */
+ direct_memcpy( local_lines, lines, sizeof(DFBRegion) * num_lines );
+
+ dfb_gfxcard_drawlines( local_lines, num_lines, &data->state );
+ }
+ /* Optimized rectangle drawing */
+ else {
+ DFBRectangle *local_rects = alloca(sizeof(DFBRectangle) * num_lines);
+
+ for (i=0; i<num_lines; i++) {
+ /* Vertical line? */
+ if (lines[i].x1 == lines[i].x2) {
+ local_rects[i].x = data->area.wanted.x + lines[i].x1;
+ local_rects[i].y = data->area.wanted.y + MIN( lines[i].y1, lines[i].y2 );
+ local_rects[i].w = 1;
+ local_rects[i].h = ABS( lines[i].y2 - lines[i].y1 ) + 1;
+ }
+ /* Horizontal line */
+ else {
+ local_rects[i].x = data->area.wanted.x + MIN( lines[i].x1, lines[i].x2 );
+ local_rects[i].y = data->area.wanted.y + lines[i].y1;
+ local_rects[i].w = ABS( lines[i].x2 - lines[i].x1 ) + 1;
+ local_rects[i].h = 1;
+ }
+ }
+
+ dfb_gfxcard_fillrectangles( local_rects, num_lines, &data->state );
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_DrawRectangle( IDirectFBSurface *thiz,
+ int x, int y, int w, int h )
+{
+ DFBRectangle rect = { x, y, w, h };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+ D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4dx%4d\n", 0, x, y, w, h );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (w<=0 || h<=0)
+ return DFB_INVARG;
+
+ rect.x += data->area.wanted.x;
+ rect.y += data->area.wanted.y;
+
+ dfb_gfxcard_drawrectangle( &rect, &data->state );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_FillTriangle( IDirectFBSurface *thiz,
+ int x1, int y1,
+ int x2, int y2,
+ int x3, int y3 )
+{
+ DFBTriangle tri = { x1, y1, x2, y2, x3, y3 };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+ D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4d,%4d-%4d,%4d\n", 0, x1, y1, x2, y2, x3, y3 );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ tri.x1 += data->area.wanted.x;
+ tri.y1 += data->area.wanted.y;
+ tri.x2 += data->area.wanted.x;
+ tri.y2 += data->area.wanted.y;
+ tri.x3 += data->area.wanted.x;
+ tri.y3 += data->area.wanted.y;
+
+ dfb_gfxcard_filltriangles( &tri, 1, &data->state );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_FillRectangles( IDirectFBSurface *thiz,
+ const DFBRectangle *rects,
+ unsigned int num_rects )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, thiz, rects, num_rects );
+
+ DFB_RECTANGLES_DEBUG_AT( Surface, rects, num_rects );
+
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!rects || !num_rects)
+ return DFB_INVARG;
+
+ if (data->area.wanted.x || data->area.wanted.y) {
+ unsigned int i;
+ DFBRectangle *local_rects;
+ bool malloced = (num_rects > 256);
+
+ if (malloced)
+ local_rects = D_MALLOC( sizeof(DFBRectangle) * num_rects );
+ else
+ local_rects = alloca( sizeof(DFBRectangle) * num_rects );
+
+ for (i=0; i<num_rects; i++) {
+ local_rects[i].x = rects[i].x + data->area.wanted.x;
+ local_rects[i].y = rects[i].y + data->area.wanted.y;
+ local_rects[i].w = rects[i].w;
+ local_rects[i].h = rects[i].h;
+ }
+
+ dfb_gfxcard_fillrectangles( local_rects, num_rects, &data->state );
+
+ if (malloced)
+ D_FREE( local_rects );
+ }
+ else
+ dfb_gfxcard_fillrectangles( rects, num_rects, &data->state );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_FillSpans( IDirectFBSurface *thiz,
+ int y,
+ const DFBSpan *spans,
+ unsigned int num_spans )
+{
+ DFBSpan *local_spans = alloca(sizeof(DFBSpan) * num_spans);
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!spans || !num_spans)
+ return DFB_INVARG;
+
+ if (data->area.wanted.x || data->area.wanted.y) {
+ unsigned int i;
+
+ for (i=0; i<num_spans; i++) {
+ local_spans[i].x = spans[i].x + data->area.wanted.x;
+ local_spans[i].w = spans[i].w;
+ }
+ }
+ else
+ /* clipping may modify spans, so we copy them */
+ direct_memcpy( local_spans, spans, sizeof(DFBSpan) * num_spans );
+
+ dfb_gfxcard_fillspans( y + data->area.wanted.y, local_spans, num_spans, &data->state );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_FillTriangles( IDirectFBSurface *thiz,
+ const DFBTriangle *tris,
+ unsigned int num_tris )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!tris || !num_tris)
+ return DFB_INVARG;
+
+ if (data->area.wanted.x || data->area.wanted.y) {
+ unsigned int i;
+ DFBTriangle *local_tris;
+ bool malloced = (num_tris > 170);
+
+ if (malloced)
+ local_tris = D_MALLOC( sizeof(DFBTriangle) * num_tris );
+ else
+ local_tris = alloca( sizeof(DFBTriangle) * num_tris );
+
+ for (i=0; i<num_tris; i++) {
+ local_tris[i].x1 = tris[i].x1 + data->area.wanted.x;
+ local_tris[i].y1 = tris[i].y1 + data->area.wanted.y;
+ local_tris[i].x2 = tris[i].x2 + data->area.wanted.x;
+ local_tris[i].y2 = tris[i].y2 + data->area.wanted.y;
+ local_tris[i].x3 = tris[i].x3 + data->area.wanted.x;
+ local_tris[i].y3 = tris[i].y3 + data->area.wanted.y;
+ }
+
+ dfb_gfxcard_filltriangles( local_tris, num_tris, &data->state );
+
+ if (malloced)
+ D_FREE( local_tris );
+ }
+ else
+ dfb_gfxcard_filltriangles( tris, num_tris, &data->state );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetBlittingFlags( IDirectFBSurface *thiz,
+ DFBSurfaceBlittingFlags flags )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ dfb_state_set_blitting_flags( &data->state, flags );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_Blit( IDirectFBSurface *thiz,
+ IDirectFBSurface *source,
+ const DFBRectangle *sr,
+ int dx, int dy )
+{
+ DFBRectangle srect;
+ IDirectFBSurface_data *src_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (sr)
+ D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4dx%4d <- %4d,%4d\n", 0, dx, dy, sr->w, sr->h, sr->x, sr->y );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (!source)
+ return DFB_INVARG;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+
+ src_data = (IDirectFBSurface_data*)source->priv;
+
+ if (!src_data->area.current.w || !src_data->area.current.h)
+ return DFB_INVAREA;
+
+ if (sr) {
+ if (sr->w < 1 || sr->h < 1)
+ return DFB_OK;
+
+ srect = *sr;
+
+ srect.x += src_data->area.wanted.x;
+ srect.y += src_data->area.wanted.y;
+
+ if (!dfb_rectangle_intersect( &srect, &src_data->area.current ))
+ return DFB_INVAREA;
+
+ dx += srect.x - (sr->x + src_data->area.wanted.x);
+ dy += srect.y - (sr->y + src_data->area.wanted.y);
+ }
+ else {
+ srect = src_data->area.current;
+
+ dx += srect.x - src_data->area.wanted.x;
+ dy += srect.y - src_data->area.wanted.y;
+ }
+
+ dfb_state_set_source( &data->state, src_data->surface );
+
+ /* fetch the source color key from the source if necessary */
+ if (data->state.blittingflags & DSBLIT_SRC_COLORKEY)
+ dfb_state_set_src_colorkey( &data->state, src_data->src_key.value );
+
+ dfb_gfxcard_blit( &srect,
+ data->area.wanted.x + dx,
+ data->area.wanted.y + dy, &data->state );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_TileBlit( IDirectFBSurface *thiz,
+ IDirectFBSurface *source,
+ const DFBRectangle *sr,
+ int dx, int dy )
+{
+ DFBRectangle srect;
+ IDirectFBSurface_data *src_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (sr)
+ D_DEBUG_AT( Surface, " -> [%2d] %4d,%4d-%4dx%4d <- %4d,%4d\n", 0, dx, dy, sr->w, sr->h, sr->x, sr->y );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!source)
+ return DFB_INVARG;
+
+
+ src_data = (IDirectFBSurface_data*)source->priv;
+
+ if (!src_data->area.current.w || !src_data->area.current.h)
+ return DFB_INVAREA;
+
+
+ if (sr) {
+ if (sr->w < 1 || sr->h < 1)
+ return DFB_OK;
+
+ srect = *sr;
+
+ srect.x += src_data->area.wanted.x;
+ srect.y += src_data->area.wanted.y;
+
+ if (!dfb_rectangle_intersect( &srect, &src_data->area.current ))
+ return DFB_INVAREA;
+
+ dx += srect.x - (sr->x + src_data->area.wanted.x);
+ dy += srect.y - (sr->y + src_data->area.wanted.y);
+ }
+ else {
+ srect = src_data->area.current;
+
+ dx += srect.x - src_data->area.wanted.x;
+ dy += srect.y - src_data->area.wanted.y;
+ }
+
+ dfb_state_set_source( &data->state, src_data->surface );
+
+ /* fetch the source color key from the source if necessary */
+ if (data->state.blittingflags & DSBLIT_SRC_COLORKEY)
+ dfb_state_set_src_colorkey( &data->state, src_data->src_key.value );
+
+ dx %= srect.w;
+ if (dx > 0)
+ dx -= srect.w;
+
+ dy %= srect.h;
+ if (dy > 0)
+ dy -= srect.h;
+
+ dx += data->area.wanted.x;
+ dy += data->area.wanted.y;
+
+ dfb_gfxcard_tileblit( &srect, dx, dy,
+ dx + data->area.wanted.w + srect.w - 1,
+ dy + data->area.wanted.h + srect.h - 1, &data->state );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_BatchBlit( IDirectFBSurface *thiz,
+ IDirectFBSurface *source,
+ const DFBRectangle *source_rects,
+ const DFBPoint *dest_points,
+ int num )
+{
+ int i, dx, dy, sx, sy;
+ DFBRectangle *rects;
+ DFBPoint *points;
+ IDirectFBSurface_data *src_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (!source || !source_rects || !dest_points || num < 1)
+ return DFB_INVARG;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+
+ src_data = (IDirectFBSurface_data*)source->priv;
+
+ if (!src_data->area.current.w || !src_data->area.current.h)
+ return DFB_INVAREA;
+
+ dx = data->area.wanted.x;
+ dy = data->area.wanted.y;
+
+ sx = src_data->area.wanted.x;
+ sy = src_data->area.wanted.y;
+
+ rects = alloca( sizeof(DFBRectangle) * num );
+ points = alloca( sizeof(DFBPoint) * num );
+
+ direct_memcpy( rects, source_rects, sizeof(DFBRectangle) * num );
+ direct_memcpy( points, dest_points, sizeof(DFBPoint) * num );
+
+ for (i=0; i<num; i++) {
+ rects[i].x += sx;
+ rects[i].y += sy;
+
+ points[i].x += dx;
+ points[i].y += dy;
+
+ if (!dfb_rectangle_intersect( &rects[i], &src_data->area.current ))
+ rects[i].w = rects[i].h = 0;
+
+ points[i].x += rects[i].x - (source_rects[i].x + sx);
+ points[i].y += rects[i].y - (source_rects[i].y + sy);
+ }
+
+ dfb_state_set_source( &data->state, src_data->surface );
+
+ /* fetch the source color key from the source if necessary */
+ if (data->state.blittingflags & DSBLIT_SRC_COLORKEY)
+ dfb_state_set_src_colorkey( &data->state, src_data->src_key.value );
+
+ dfb_gfxcard_batchblit( rects, points, num, &data->state );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_StretchBlit( IDirectFBSurface *thiz,
+ IDirectFBSurface *source,
+ const DFBRectangle *source_rect,
+ const DFBRectangle *destination_rect )
+{
+ DFBRectangle srect, drect;
+ IDirectFBSurface_data *src_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!source)
+ return DFB_INVARG;
+
+
+ src_data = (IDirectFBSurface_data*)source->priv;
+
+ if (!src_data->area.current.w || !src_data->area.current.h)
+ return DFB_INVAREA;
+
+
+ /* do destination rectangle */
+ if (destination_rect) {
+ if (destination_rect->w < 1 || destination_rect->h < 1)
+ return DFB_INVARG;
+
+ drect = *destination_rect;
+
+ drect.x += data->area.wanted.x;
+ drect.y += data->area.wanted.y;
+ }
+ else
+ drect = data->area.wanted;
+
+ /* do source rectangle */
+ if (source_rect) {
+ if (source_rect->w < 1 || source_rect->h < 1)
+ return DFB_INVARG;
+
+ srect = *source_rect;
+
+ srect.x += src_data->area.wanted.x;
+ srect.y += src_data->area.wanted.y;
+ }
+ else
+ srect = src_data->area.wanted;
+
+
+ /* clipping of the source rectangle must be applied to the destination */
+ {
+ DFBRectangle orig_src = srect;
+
+ if (!dfb_rectangle_intersect( &srect, &src_data->area.current ))
+ return DFB_INVAREA;
+
+ if (srect.x != orig_src.x)
+ drect.x += (int)( (srect.x - orig_src.x) *
+ (drect.w / (float)orig_src.w) + 0.5f);
+
+ if (srect.y != orig_src.y)
+ drect.y += (int)( (srect.y - orig_src.y) *
+ (drect.h / (float)orig_src.h) + 0.5f);
+
+ if (srect.w != orig_src.w)
+ drect.w = D_ICEIL(drect.w * (srect.w / (float)orig_src.w));
+ if (srect.h != orig_src.h)
+ drect.h = D_ICEIL(drect.h * (srect.h / (float)orig_src.h));
+ }
+
+ dfb_state_set_source( &data->state, src_data->surface );
+
+ /* fetch the source color key from the source if necessary */
+ if (data->state.blittingflags & DSBLIT_SRC_COLORKEY)
+ dfb_state_set_src_colorkey( &data->state, src_data->src_key.value );
+
+ dfb_gfxcard_stretchblit( &srect, &drect, &data->state );
+
+ return DFB_OK;
+}
+
+#define SET_VERTEX(v,X,Y,Z,W,S,T) \
+ do { \
+ (v)->x = X; \
+ (v)->y = Y; \
+ (v)->z = Z; \
+ (v)->w = W; \
+ (v)->s = S; \
+ (v)->t = T; \
+ } while (0)
+
+static DFBResult
+IDirectFBSurface_TextureTriangles( IDirectFBSurface *thiz,
+ IDirectFBSurface *source,
+ const DFBVertex *vertices,
+ const int *indices,
+ int num,
+ DFBTriangleFormation formation )
+{
+ int i;
+ DFBVertex *translated;
+ IDirectFBSurface_data *src_data;
+ bool src_sub;
+ float x0 = 0;
+ float y0 = 0;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!source || !vertices || num < 3)
+ return DFB_INVARG;
+
+ src_data = (IDirectFBSurface_data*)source->priv;
+
+ if ((src_sub = (src_data->caps & DSCAPS_SUBSURFACE))) {
+ D_ONCE( "sub surface texture not fully working with 'repeated' mapping" );
+
+ x0 = data->area.wanted.x;
+ y0 = data->area.wanted.y;
+ }
+
+ switch (formation) {
+ case DTTF_LIST:
+ if (num % 3)
+ return DFB_INVARG;
+ break;
+
+ case DTTF_STRIP:
+ case DTTF_FAN:
+ break;
+
+ default:
+ return DFB_INVARG;
+ }
+
+ translated = alloca( num * sizeof(DFBVertex) );
+ if (!translated)
+ return DFB_NOSYSTEMMEMORY;
+
+ /* TODO: pass indices through to driver */
+ if (src_sub) {
+ float oowidth = 1.0f / src_data->surface->config.size.w;
+ float ooheight = 1.0f / src_data->surface->config.size.h;
+
+ float s0 = src_data->area.wanted.x * oowidth;
+ float t0 = src_data->area.wanted.y * ooheight;
+
+ float fs = src_data->area.wanted.w * oowidth;
+ float ft = src_data->area.wanted.h * ooheight;
+
+ for (i=0; i<num; i++) {
+ const DFBVertex *in = &vertices[ indices ? indices[i] : i ];
+ DFBVertex *out = &translated[i];
+
+ SET_VERTEX( out, x0 + in->x, y0 + in->y, in->z, in->w,
+ s0 + fs * in->s, t0 + ft * in->t );
+ }
+ }
+ else {
+ if (indices) {
+ for (i=0; i<num; i++) {
+ const DFBVertex *in = &vertices[ indices[i] ];
+ DFBVertex *out = &translated[i];
+
+ SET_VERTEX( out, x0 + in->x, y0 + in->y, in->z, in->w, in->s, in->t );
+ }
+ }
+ else {
+ direct_memcpy( translated, vertices, num * sizeof(DFBVertex) );
+
+ for (i=0; i<num; i++) {
+ translated[i].x += x0;
+ translated[i].y += y0;
+ }
+ }
+ }
+
+ dfb_state_set_source( &data->state, src_data->surface );
+
+ /* fetch the source color key from the source if necessary */
+ if (data->state.blittingflags & DSBLIT_SRC_COLORKEY)
+ dfb_state_set_src_colorkey( &data->state, src_data->src_key.value );
+
+ dfb_gfxcard_texture_triangles( translated, num, formation, &data->state );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_DrawString( IDirectFBSurface *thiz,
+ const char *text, int bytes,
+ int x, int y,
+ DFBSurfaceTextFlags flags )
+{
+ DFBResult ret;
+ IDirectFBFont *font;
+ IDirectFBFont_data *font_data;
+ CoreFont *core_font;
+ unsigned int layers = 1;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (!text)
+ return DFB_INVARG;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!data->font)
+ return DFB_MISSINGFONT;
+
+ if (bytes < 0)
+ bytes = strlen (text);
+
+ if (bytes == 0)
+ return DFB_OK;
+
+ font = data->font;
+
+ DIRECT_INTERFACE_GET_DATA_FROM( font, font_data, IDirectFBFont );
+
+ core_font = font_data->font;
+
+ if (flags & DSTF_OUTLINE) {
+ if (!(core_font->attributes & DFFA_OUTLINED))
+ return DFB_UNSUPPORTED;
+
+ layers = 2;
+ }
+
+ if (!(flags & DSTF_TOP)) {
+ x += core_font->ascender * core_font->up_unit_x;
+ y += core_font->ascender * core_font->up_unit_y;
+
+ if (flags & DSTF_BOTTOM) {
+ x -= core_font->descender * core_font->up_unit_x;
+ y -= core_font->descender * core_font->up_unit_y;
+ }
+ }
+
+ if (flags & (DSTF_RIGHT | DSTF_CENTER)) {
+ int i, num, kx, ky;
+ int xsize = 0;
+ int ysize = 0;
+ unsigned int prev = 0;
+ unsigned int indices[bytes];
+
+ /* FIXME: Avoid double locking and decoding. */
+ dfb_font_lock( core_font );
+
+ /* Decode string to character indices. */
+ ret = dfb_font_decode_text( core_font, data->encoding, text, bytes, indices, &num );
+ if (ret) {
+ dfb_font_unlock( core_font );
+ return ret;
+ }
+
+ /* Calculate string width. */
+ for (i=0; i<num; i++) {
+ unsigned int current = indices[i];
+ CoreGlyphData *glyph;
+
+ if (dfb_font_get_glyph_data( core_font, current, 0, &glyph ) == DFB_OK) {
+ xsize += glyph->xadvance;
+ ysize += glyph->yadvance;
+
+ if (prev && core_font->GetKerning &&
+ core_font->GetKerning( core_font, prev, current, &kx, &ky ) == DFB_OK) {
+ xsize += kx;
+ ysize += ky;
+ }
+ }
+
+ prev = current;
+ }
+
+ dfb_font_unlock( core_font );
+
+ /* Justify. */
+ if (flags & DSTF_RIGHT) {
+ x -= xsize;
+ y -= ysize;
+ }
+ else if (flags & DSTF_CENTER) {
+ x -= xsize >> 1;
+ y -= ysize >> 1;
+ }
+ }
+
+ dfb_gfxcard_drawstring( (const unsigned char*) text, bytes, data->encoding,
+ data->area.wanted.x + x, data->area.wanted.y + y,
+ core_font, layers, &data->state );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_DrawGlyph( IDirectFBSurface *thiz,
+ unsigned int character, int x, int y,
+ DFBSurfaceTextFlags flags )
+{
+ DFBResult ret;
+ int l;
+ IDirectFBFont *font;
+ IDirectFBFont_data *font_data;
+ CoreFont *core_font;
+ CoreGlyphData *glyph[DFB_FONT_MAX_LAYERS];
+ unsigned int index;
+ unsigned int layers = 1;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, 0x%x, %d,%d, 0x%x )\n",
+ __FUNCTION__, thiz, character, x, y, flags );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (!character)
+ return DFB_INVARG;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->locked)
+ return DFB_LOCKED;
+
+ if (!data->font)
+ return DFB_MISSINGFONT;
+
+ font = data->font;
+
+ DIRECT_INTERFACE_GET_DATA_FROM( font, font_data, IDirectFBFont );
+
+ core_font = font_data->font;
+
+ if (flags & DSTF_OUTLINE) {
+ if (!(core_font->attributes & DFFA_OUTLINED))
+ return DFB_UNSUPPORTED;
+
+ layers = 2;
+ }
+
+ dfb_font_lock( core_font );
+
+ ret = dfb_font_decode_character( core_font, data->encoding, character, &index );
+ if (ret) {
+ dfb_font_unlock( core_font );
+ return ret;
+ }
+
+ for (l=0; l<layers; l++) {
+ ret = dfb_font_get_glyph_data( core_font, index, l, &glyph[l] );
+ if (ret) {
+ dfb_font_unlock( core_font );
+ return ret;
+ }
+ }
+
+ if (!(flags & DSTF_TOP)) {
+ x += core_font->ascender * core_font->up_unit_x;
+ y += core_font->ascender * core_font->up_unit_y;
+
+ if (flags & DSTF_BOTTOM) {
+ x -= core_font->descender * core_font->up_unit_x;
+ y -= core_font->descender * core_font->up_unit_y;
+ }
+ }
+
+ if (flags & (DSTF_RIGHT | DSTF_CENTER)) {
+ if (flags & DSTF_RIGHT) {
+ x -= glyph[0]->xadvance;
+ y -= glyph[0]->yadvance;
+ }
+ else if (flags & DSTF_CENTER) {
+ x -= glyph[0]->xadvance >> 1;
+ y -= glyph[0]->yadvance >> 1;
+ }
+ }
+
+ dfb_gfxcard_drawglyph( glyph,
+ data->area.wanted.x + x, data->area.wanted.y + y,
+ core_font, layers, &data->state );
+
+ dfb_font_unlock( core_font );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetEncoding( IDirectFBSurface *thiz,
+ DFBTextEncodingID encoding )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %d )\n", __FUNCTION__, thiz, encoding );
+
+ /* TODO: check for support or fail later? */
+ data->encoding = encoding;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetSubSurface( IDirectFBSurface *thiz,
+ const DFBRectangle *rect,
+ IDirectFBSurface **surface )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ /* Check arguments */
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (!surface)
+ return DFB_INVARG;
+
+ /* Allocate interface */
+ DIRECT_ALLOCATE_INTERFACE( *surface, IDirectFBSurface );
+
+ if (rect || data->limit_set) {
+ DFBRectangle wanted, granted;
+
+ /* Compute wanted rectangle */
+ if (rect) {
+ wanted = *rect;
+
+ wanted.x += data->area.wanted.x;
+ wanted.y += data->area.wanted.y;
+
+ if (wanted.w <= 0 || wanted.h <= 0) {
+ wanted.w = 0;
+ wanted.h = 0;
+ }
+ }
+ else {
+ wanted = data->area.wanted;
+ }
+
+ /* Compute granted rectangle */
+ granted = wanted;
+
+ dfb_rectangle_intersect( &granted, &data->area.granted );
+
+ /* Construct */
+ ret = IDirectFBSurface_Construct( *surface, thiz,
+ &wanted, &granted, &data->area.insets,
+ data->surface,
+ data->caps | DSCAPS_SUBSURFACE, data->core );
+ }
+ else {
+ /* Construct */
+ ret = IDirectFBSurface_Construct( *surface, thiz,
+ NULL, NULL, &data->area.insets,
+ data->surface,
+ data->caps | DSCAPS_SUBSURFACE, data->core );
+ }
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBSurface_MakeSubSurface( IDirectFBSurface *thiz,
+ IDirectFBSurface *from,
+ const DFBRectangle *rect )
+{
+ CoreSurface *surface;
+ DFBRectangle wanted, granted;
+ DFBRectangle full_rect;
+ IDirectFBSurface_data *from_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ /* Check arguments */
+ if (!from)
+ return DFB_INVARG;
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ DIRECT_INTERFACE_GET_DATA_FROM(from, from_data, IDirectFBSurface);
+
+ /* Check if CoreSurface is the same */
+ if (from_data->surface != surface)
+ return DFB_UNSUPPORTED;
+
+
+ full_rect.x = 0;
+ full_rect.y = 0;
+ full_rect.w = surface->config.size.w;
+ full_rect.h = surface->config.size.h;
+
+ if (rect || from_data->limit_set) {
+ /* Compute wanted rectangle */
+ if (rect) {
+ wanted = *rect;
+
+ wanted.x += from_data->area.wanted.x;
+ wanted.y += from_data->area.wanted.y;
+
+ if (wanted.w <= 0 || wanted.h <= 0) {
+ wanted.w = 0;
+ wanted.h = 0;
+ }
+ }
+ else {
+ wanted = from_data->area.wanted;
+ }
+
+ /* Compute granted rectangle */
+ granted = wanted;
+
+ dfb_rectangle_intersect( &granted, &from_data->area.granted );
+ }
+ else {
+ wanted = full_rect;
+ granted = full_rect;
+ }
+
+
+ data->caps |= DSCAPS_SUBSURFACE;
+
+
+ data->area.wanted = wanted;
+ data->area.granted = granted;
+
+ data->area.current = data->area.granted;
+ dfb_rectangle_intersect( &data->area.current, &full_rect );
+
+
+ data->state.clip.x1 = data->area.current.x;
+ data->state.clip.y1 = data->area.current.y;
+ data->state.clip.x2 = data->area.current.x + (data->area.current.w ? : 1) - 1;
+ data->state.clip.y2 = data->area.current.y + (data->area.current.h ? : 1) - 1;
+
+ data->state.modified |= SMF_CLIP;
+
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_GetGL( IDirectFBSurface *thiz,
+ IDirectFBGL **interface )
+{
+ DFBResult ret;
+ DirectInterfaceFuncs *funcs = NULL;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!data->surface)
+ return DFB_DESTROYED;
+
+ if (!interface)
+ return DFB_INVARG;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+
+ ret = DirectGetInterface( &funcs, "IDirectFBGL", NULL, DirectProbeInterface, thiz );
+ if (ret)
+ return ret;
+
+ ret = funcs->Allocate( (void**)interface );
+ if (ret)
+ return ret;
+
+ ret = funcs->Construct( *interface, thiz );
+ if (ret)
+ *interface = NULL;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBSurface_Dump( IDirectFBSurface *thiz,
+ const char *directory,
+ const char *prefix )
+{
+ CoreSurface *surface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!directory)
+ return DFB_INVARG;
+
+ if (!data->area.current.w || !data->area.current.h)
+ return DFB_INVAREA;
+
+ if (data->caps & DSCAPS_SUBSURFACE) {
+ D_ONCE( "sub surface dumping not supported yet" );
+ return DFB_UNSUPPORTED;
+ }
+
+ surface = data->surface;
+ if (!surface)
+ return DFB_DESTROYED;
+
+ return dfb_surface_dump_buffer( surface, CSBR_FRONT, directory, prefix );
+}
+
+static DFBResult
+IDirectFBSurface_DisableAcceleration( IDirectFBSurface *thiz,
+ DFBAccelerationMask mask )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (D_FLAGS_INVALID( mask, DFXL_ALL ))
+ return DFB_INVARG;
+
+ data->state.disabled = mask;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_ReleaseSource( IDirectFBSurface *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ dfb_state_set_source( &data->state, NULL );
+ dfb_state_set_source_mask( &data->state, NULL );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetRenderOptions( IDirectFBSurface *thiz,
+ DFBSurfaceRenderOptions options )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ dfb_state_set_render_options( &data->state, options );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetMatrix( IDirectFBSurface *thiz,
+ const s32 *matrix )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p )\n", __FUNCTION__, thiz, matrix );
+
+ if (!matrix)
+ return DFB_INVARG;
+
+ dfb_state_set_matrix( &data->state, matrix );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_SetSourceMask( IDirectFBSurface *thiz,
+ IDirectFBSurface *mask,
+ int x,
+ int y,
+ DFBSurfaceMaskFlags flags )
+{
+ DFBResult ret;
+ DFBPoint offset = { x, y };
+ IDirectFBSurface_data *mask_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p, %d,%d, 0x%04x )\n", __FUNCTION__, thiz, mask, x, y, flags );
+
+ if (!mask || flags & ~DSMF_ALL)
+ return DFB_INVARG;
+
+ DIRECT_INTERFACE_GET_DATA_FROM(mask, mask_data, IDirectFBSurface);
+
+ if (!mask_data->surface)
+ return DFB_DESTROYED;
+
+ ret = dfb_state_set_source_mask( &data->state, mask_data->surface );
+ if (ret)
+ return ret;
+
+ dfb_state_set_source_mask_vals( &data->state, &offset, flags );
+
+ return DFB_OK;
+}
+
+/******/
+
+DFBResult IDirectFBSurface_Construct( IDirectFBSurface *thiz,
+ IDirectFBSurface *parent,
+ DFBRectangle *wanted,
+ DFBRectangle *granted,
+ DFBInsets *insets,
+ CoreSurface *surface,
+ DFBSurfaceCapabilities caps,
+ CoreDFB *core )
+{
+ DFBRectangle rect = { 0, 0, surface->config.size.w, surface->config.size.h };
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBSurface)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ data->ref = 1;
+ data->caps = caps | surface->config.caps;
+ data->core = core;
+
+ if (dfb_surface_ref( surface )) {
+ DIRECT_DEALLOCATE_INTERFACE(thiz);
+ return DFB_FAILURE;
+ }
+
+ if (parent && dfb_config->startstop) {
+ IDirectFBSurface_data *parent_data;
+
+ if (parent->AddRef( parent )) {
+ dfb_surface_unref( surface );
+ DIRECT_DEALLOCATE_INTERFACE(thiz);
+ return DFB_FAILURE;
+ }
+
+ DIRECT_INTERFACE_GET_DATA_FROM( parent, parent_data, IDirectFBSurface );
+
+ pthread_mutex_lock( &parent_data->children_lock );
+
+ direct_list_append( &parent_data->children_data, &data->link );
+
+ pthread_mutex_unlock( &parent_data->children_lock );
+
+ data->parent = parent;
+ }
+
+ pthread_mutex_init( &data->children_lock, NULL );
+
+ /* The area insets */
+ if (insets) {
+ data->area.insets = *insets;
+ dfb_rectangle_subtract( &rect, insets );
+ }
+
+ /* The area that was requested */
+ if (wanted)
+ data->area.wanted = *wanted;
+ else
+ data->area.wanted = rect;
+
+ /* The area that will never be exceeded */
+ if (granted)
+ data->area.granted = *granted;
+ else
+ data->area.granted = data->area.wanted;
+
+ /* The currently accessible rectangle */
+ data->area.current = data->area.granted;
+ dfb_rectangle_intersect( &data->area.current, &rect );
+
+ /* Whether granted rectangle is meaningful */
+ data->limit_set = (granted != NULL);
+
+ data->surface = surface;
+
+ dfb_state_init( &data->state, NULL );
+ dfb_state_set_destination( &data->state, surface );
+
+ data->state.clip.x1 = data->area.current.x;
+ data->state.clip.y1 = data->area.current.y;
+ data->state.clip.x2 = data->area.current.x + (data->area.current.w ? : 1) - 1;
+ data->state.clip.y2 = data->area.current.y + (data->area.current.h ? : 1) - 1;
+
+ data->state.modified = SMF_ALL;
+
+ thiz->AddRef = IDirectFBSurface_AddRef;
+ thiz->Release = IDirectFBSurface_Release;
+
+ thiz->GetCapabilities = IDirectFBSurface_GetCapabilities;
+ thiz->GetPosition = IDirectFBSurface_GetPosition;
+ thiz->GetSize = IDirectFBSurface_GetSize;
+ thiz->GetVisibleRectangle = IDirectFBSurface_GetVisibleRectangle;
+ thiz->GetPixelFormat = IDirectFBSurface_GetPixelFormat;
+ thiz->GetAccelerationMask = IDirectFBSurface_GetAccelerationMask;
+
+ thiz->GetPalette = IDirectFBSurface_GetPalette;
+ thiz->SetPalette = IDirectFBSurface_SetPalette;
+ thiz->SetAlphaRamp = IDirectFBSurface_SetAlphaRamp;
+
+ thiz->Lock = IDirectFBSurface_Lock;
+ thiz->GetFramebufferOffset = IDirectFBSurface_GetFramebufferOffset;
+ thiz->Unlock = IDirectFBSurface_Unlock;
+ thiz->Flip = IDirectFBSurface_Flip;
+ thiz->SetField = IDirectFBSurface_SetField;
+ thiz->Clear = IDirectFBSurface_Clear;
+
+ thiz->SetClip = IDirectFBSurface_SetClip;
+ thiz->GetClip = IDirectFBSurface_GetClip;
+ thiz->SetColor = IDirectFBSurface_SetColor;
+ thiz->SetColorIndex = IDirectFBSurface_SetColorIndex;
+ thiz->SetSrcBlendFunction = IDirectFBSurface_SetSrcBlendFunction;
+ thiz->SetDstBlendFunction = IDirectFBSurface_SetDstBlendFunction;
+ thiz->SetPorterDuff = IDirectFBSurface_SetPorterDuff;
+ thiz->SetSrcColorKey = IDirectFBSurface_SetSrcColorKey;
+ thiz->SetSrcColorKeyIndex = IDirectFBSurface_SetSrcColorKeyIndex;
+ thiz->SetDstColorKey = IDirectFBSurface_SetDstColorKey;
+ thiz->SetDstColorKeyIndex = IDirectFBSurface_SetDstColorKeyIndex;
+ thiz->SetIndexTranslation = IDirectFBSurface_SetIndexTranslation;
+
+ thiz->SetBlittingFlags = IDirectFBSurface_SetBlittingFlags;
+ thiz->Blit = IDirectFBSurface_Blit;
+ thiz->TileBlit = IDirectFBSurface_TileBlit;
+ thiz->BatchBlit = IDirectFBSurface_BatchBlit;
+ thiz->StretchBlit = IDirectFBSurface_StretchBlit;
+ thiz->TextureTriangles = IDirectFBSurface_TextureTriangles;
+
+ thiz->SetDrawingFlags = IDirectFBSurface_SetDrawingFlags;
+ thiz->FillRectangle = IDirectFBSurface_FillRectangle;
+ thiz->DrawLine = IDirectFBSurface_DrawLine;
+ thiz->DrawLines = IDirectFBSurface_DrawLines;
+ thiz->DrawRectangle = IDirectFBSurface_DrawRectangle;
+ thiz->FillTriangle = IDirectFBSurface_FillTriangle;
+ thiz->FillRectangles = IDirectFBSurface_FillRectangles;
+ thiz->FillSpans = IDirectFBSurface_FillSpans;
+ thiz->FillTriangles = IDirectFBSurface_FillTriangles;
+
+ thiz->SetFont = IDirectFBSurface_SetFont;
+ thiz->GetFont = IDirectFBSurface_GetFont;
+ thiz->DrawString = IDirectFBSurface_DrawString;
+ thiz->DrawGlyph = IDirectFBSurface_DrawGlyph;
+ thiz->SetEncoding = IDirectFBSurface_SetEncoding;
+
+ thiz->GetSubSurface = IDirectFBSurface_GetSubSurface;
+
+ thiz->GetGL = IDirectFBSurface_GetGL;
+
+ thiz->Dump = IDirectFBSurface_Dump;
+ thiz->DisableAcceleration = IDirectFBSurface_DisableAcceleration;
+ thiz->ReleaseSource = IDirectFBSurface_ReleaseSource;
+
+ thiz->SetRenderOptions = IDirectFBSurface_SetRenderOptions;
+ thiz->SetMatrix = IDirectFBSurface_SetMatrix;
+ thiz->SetSourceMask = IDirectFBSurface_SetSourceMask;
+
+ thiz->MakeSubSurface = IDirectFBSurface_MakeSubSurface;
+
+ thiz->Write = IDirectFBSurface_Write;
+ thiz->Read = IDirectFBSurface_Read;
+
+ thiz->SetColors = IDirectFBSurface_SetColors;
+
+ dfb_surface_attach( surface,
+ IDirectFBSurface_listener, thiz, &data->reaction );
+
+ return DFB_OK;
+}
+
+
+/* internal */
+
+static ReactionResult
+IDirectFBSurface_listener( const void *msg_data, void *ctx )
+{
+ const CoreSurfaceNotification *notification = msg_data;
+ IDirectFBSurface *thiz = ctx;
+ IDirectFBSurface_data *data = thiz->priv;
+ CoreSurface *surface = data->surface;
+
+ D_DEBUG_AT( Surface, "%s( %p, %p )\n", __FUNCTION__, msg_data, ctx );
+
+ if (notification->flags & CSNF_DESTROY) {
+ if (data->surface) {
+ data->surface = NULL;
+ dfb_surface_unref( surface );
+ }
+ return RS_REMOVE;
+ }
+
+ if (notification->flags & CSNF_SIZEFORMAT) {
+ DFBRectangle rect = { 0, 0, surface->config.size.w, surface->config.size.h };
+
+ dfb_rectangle_subtract( &rect, &data->area.insets );
+
+ if (data->limit_set) {
+ data->area.current = data->area.granted;
+
+ dfb_rectangle_intersect( &data->area.current, &rect );
+ }
+ else
+ data->area.wanted = data->area.granted = data->area.current = rect;
+
+ /* Reset clip to avoid crashes caused by drawing out of bounds. */
+ if (data->clip_set)
+ thiz->SetClip( thiz, &data->clip_wanted );
+ else
+ thiz->SetClip( thiz, NULL );
+ }
+
+ return RS_OK;
+}
+
+void
+IDirectFBSurface_StopAll( IDirectFBSurface_data *data )
+{
+ if (!dfb_config->startstop)
+ return;
+
+ if (data->children_data) {
+ IDirectFBSurface_data *child;
+
+ pthread_mutex_lock( &data->children_lock );
+
+ direct_list_foreach (child, data->children_data)
+ IDirectFBSurface_StopAll( child );
+
+ pthread_mutex_unlock( &data->children_lock );
+ }
+
+ /* Signal end of sequence of operations. */
+ dfb_state_lock( &data->state );
+ dfb_state_stop_drawing( &data->state );
+ dfb_state_unlock( &data->state );
+}
+
diff --git a/Source/DirectFB/src/display/idirectfbsurface.h b/Source/DirectFB/src/display/idirectfbsurface.h
new file mode 100755
index 0000000..a350054
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbsurface.h
@@ -0,0 +1,123 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBSURFACE_H__
+#define __IDIRECTFBSURFACE_H__
+
+#include <directfb.h>
+
+#include <direct/types.h>
+
+#include <fusion/reactor.h>
+
+#include <core/coretypes.h>
+#include <core/state.h>
+
+
+/*
+ * private data struct of IDirectFBSurface
+ */
+typedef struct {
+ DirectLink link;
+
+ int ref; /* reference counter */
+
+ DFBSurfaceCapabilities caps; /* capabilities */
+
+ struct {
+ DFBRectangle wanted; /* passed to GetSubSurface */
+ DFBRectangle granted; /* clipped by parent on creation */
+ DFBRectangle current; /* currently available area */
+ DFBInsets insets; /* actually set by the window manager */
+ } area;
+
+ bool limit_set; /* greanted rectangle set?
+ (GetSubSurface called with rect != NULL) */
+
+ bool clip_set; /* fixed clip set? (SetClip called
+ with clip != NULL) */
+ DFBRegion clip_wanted; /* last region passed to SetClip
+ intersected by wanted area,
+ only valid if clip_set != 0 */
+
+ CoreSurface *surface; /* buffer to show */
+ bool locked; /* which buffer is locked? */
+ CoreSurfaceBufferLock lock;
+
+ IDirectFBFont *font; /* font to use */
+ CardState state; /* render state to use */
+ DFBTextEncodingID encoding; /* text encoding */
+
+ struct {
+ u8 r; /* red component */
+ u8 g; /* green component */
+ u8 b; /* blue component */
+ u32 value; /* r/g/b in surface's format */
+ } src_key; /* src key for blitting from
+ this surface */
+
+ struct {
+ u8 r; /* red component */
+ u8 g; /* green component */
+ u8 b; /* blue component */
+ u32 value; /* r/g/b in surface's format */
+ } dst_key; /* dst key for blitting to
+ this surface */
+
+ Reaction reaction;
+
+ CoreDFB *core;
+
+ IDirectFBSurface *parent;
+ DirectLink *children_data;
+ pthread_mutex_t children_lock;
+} IDirectFBSurface_data;
+
+/*
+ * initializes interface struct and private data
+ */
+DFBResult IDirectFBSurface_Construct( IDirectFBSurface *thiz,
+ IDirectFBSurface *parent,
+ DFBRectangle *req_rect,
+ DFBRectangle *clip_rect,
+ DFBInsets *insets,
+ CoreSurface *surface,
+ DFBSurfaceCapabilities caps,
+ CoreDFB *core );
+
+/*
+ * destroys surface(s) and frees private data
+ */
+void IDirectFBSurface_Destruct( IDirectFBSurface *thiz );
+
+/*
+ * internal
+ */
+void IDirectFBSurface_StopAll( IDirectFBSurface_data *data );
+
+#endif
diff --git a/Source/DirectFB/src/display/idirectfbsurface_layer.c b/Source/DirectFB/src/display/idirectfbsurface_layer.c
new file mode 100755
index 0000000..4507a56
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbsurface_layer.c
@@ -0,0 +1,244 @@
+/*
+ (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 <directfb.h>
+
+#include <core/core.h>
+#include <core/coretypes.h>
+
+#include <core/gfxcard.h>
+#include <core/state.h>
+#include <core/layers.h>
+#include <core/layer_region.h>
+#include <core/surface.h>
+#include <core/system.h>
+
+#include "idirectfbsurface.h"
+#include "idirectfbsurface_layer.h"
+
+#include <misc/util.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+
+#include <gfx/util.h>
+
+
+D_DEBUG_DOMAIN( Surface, "IDirectFBSurfaceL", "IDirectFBSurface_Layer Interface" );
+
+/**********************************************************************************************************************/
+
+static void
+IDirectFBSurface_Layer_Destruct( IDirectFBSurface *thiz )
+{
+ IDirectFBSurface_Layer_data *data = (IDirectFBSurface_Layer_data*) thiz->priv;
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ dfb_layer_region_unref( data->region );
+ IDirectFBSurface_Destruct( thiz );
+}
+
+static DirectResult
+IDirectFBSurface_Layer_Release( IDirectFBSurface *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Layer)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (--data->base.ref == 0)
+ IDirectFBSurface_Layer_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_Layer_Flip( IDirectFBSurface *thiz,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags )
+{
+ DFBRegion reg;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Layer)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p, 0x%08x )\n", __FUNCTION__, thiz, region, flags );
+
+ if (!data->base.surface)
+ return DFB_DESTROYED;
+
+ if (data->base.locked)
+ return DFB_LOCKED;
+
+ if (!data->base.area.current.w || !data->base.area.current.h ||
+ (region && (region->x1 > region->x2 || region->y1 > region->y2)))
+ return DFB_INVAREA;
+
+
+ IDirectFBSurface_StopAll( &data->base );
+
+ if (data->base.parent) {
+ IDirectFBSurface_data *parent_data;
+
+ DIRECT_INTERFACE_GET_DATA_FROM( data->base.parent, parent_data, IDirectFBSurface );
+
+ /* Signal end of sequence of operations. */
+ dfb_state_lock( &parent_data->state );
+ dfb_state_stop_drawing( &parent_data->state );
+ dfb_state_unlock( &parent_data->state );
+ }
+
+
+ dfb_region_from_rectangle( &reg, &data->base.area.current );
+
+ if (region) {
+ DFBRegion clip = DFB_REGION_INIT_TRANSLATED( region,
+ data->base.area.wanted.x,
+ data->base.area.wanted.y );
+
+ if (!dfb_region_region_intersect( &reg, &clip ))
+ return DFB_INVAREA;
+ }
+
+ D_DEBUG_AT( Surface, " -> FLIP %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION( &reg ) );
+
+ return dfb_layer_region_flip_update( data->region, &reg, flags );
+}
+
+static DFBResult
+IDirectFBSurface_Layer_GetSubSurface( IDirectFBSurface *thiz,
+ const DFBRectangle *rect,
+ IDirectFBSurface **surface )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Layer)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ /* Check arguments */
+ if (!data->base.surface)
+ return DFB_DESTROYED;
+
+ if (!surface)
+ return DFB_INVARG;
+
+ /* Allocate interface */
+ DIRECT_ALLOCATE_INTERFACE( *surface, IDirectFBSurface );
+
+ if (rect || data->base.limit_set) {
+ DFBRectangle wanted, granted;
+
+ /* Compute wanted rectangle */
+ if (rect) {
+ wanted = *rect;
+
+ wanted.x += data->base.area.wanted.x;
+ wanted.y += data->base.area.wanted.y;
+
+ if (wanted.w <= 0 || wanted.h <= 0) {
+ wanted.w = 0;
+ wanted.h = 0;
+ }
+ }
+ else {
+ wanted = data->base.area.wanted;
+ }
+
+ /* Compute granted rectangle */
+ granted = wanted;
+
+ dfb_rectangle_intersect( &granted, &data->base.area.granted );
+
+ /* Construct */
+ ret = IDirectFBSurface_Layer_Construct( *surface, thiz, &wanted, &granted,
+ data->region, data->base.caps |
+ DSCAPS_SUBSURFACE, data->base.core );
+ }
+ else {
+ /* Construct */
+ ret = IDirectFBSurface_Layer_Construct( *surface, thiz, NULL, NULL,
+ data->region, data->base.caps |
+ DSCAPS_SUBSURFACE, data->base.core );
+ }
+
+ return ret;
+}
+
+DFBResult
+IDirectFBSurface_Layer_Construct( IDirectFBSurface *thiz,
+ IDirectFBSurface *parent,
+ DFBRectangle *wanted,
+ DFBRectangle *granted,
+ CoreLayerRegion *region,
+ DFBSurfaceCapabilities caps,
+ CoreDFB *core )
+{
+ DFBResult ret;
+ CoreSurface *surface;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBSurface_Layer);
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (dfb_layer_region_ref( region ))
+ return DFB_FUSION;
+
+ ret = dfb_layer_region_get_surface( region, &surface );
+ if (ret) {
+ dfb_layer_region_unref( region );
+ DIRECT_DEALLOCATE_INTERFACE(thiz);
+ return ret;
+ }
+
+ ret = IDirectFBSurface_Construct( thiz, parent, wanted, granted, NULL,
+ surface, surface->config.caps | caps, core );
+ if (ret) {
+ dfb_surface_unref( surface );
+ dfb_layer_region_unref( region );
+ return ret;
+ }
+
+ dfb_surface_unref( surface );
+
+ data->region = region;
+
+ thiz->Release = IDirectFBSurface_Layer_Release;
+ thiz->Flip = IDirectFBSurface_Layer_Flip;
+ thiz->GetSubSurface = IDirectFBSurface_Layer_GetSubSurface;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/display/idirectfbsurface_layer.h b/Source/DirectFB/src/display/idirectfbsurface_layer.h
new file mode 100755
index 0000000..c2ddb8c
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbsurface_layer.h
@@ -0,0 +1,57 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DIRECTFBSURFACE_LAYER_H__
+#define __DIRECTFBSURFACE_LAYER_H__
+
+#include <directfb.h>
+#include <core/coretypes.h>
+
+/*
+ * private data struct of IDirectFBSurface_Layer
+ */
+typedef struct {
+ IDirectFBSurface_data base; /* base Surface implementation */
+
+ CoreLayerRegion *region; /* the region this surface belongs to */
+} IDirectFBSurface_Layer_data;
+
+/*
+ * sets buffer mode according to capabilities, calls base classes
+ * IDirectFBSurface_Construct, reallocates private data and
+ * overloads functions of the interface
+ */
+DFBResult IDirectFBSurface_Layer_Construct( IDirectFBSurface *thiz,
+ IDirectFBSurface *parent,
+ DFBRectangle *req_rect,
+ DFBRectangle *clip_rect,
+ CoreLayerRegion *region,
+ DFBSurfaceCapabilities caps,
+ CoreDFB *core );
+
+#endif
diff --git a/Source/DirectFB/src/display/idirectfbsurface_window.c b/Source/DirectFB/src/display/idirectfbsurface_window.c
new file mode 100755
index 0000000..c76eb3d
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbsurface_window.c
@@ -0,0 +1,353 @@
+/*
+ (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 <directfb.h>
+
+#include <core/core.h>
+#include <core/coretypes.h>
+
+#include <core/fonts.h>
+#include <core/gfxcard.h>
+#include <core/layer_context.h>
+#include <core/layer_region.h>
+#include <core/state.h>
+#include <core/surface.h>
+#include <core/windows.h>
+#include <core/windows_internal.h> /* FIXME */
+#include <core/wm.h>
+
+#include <display/idirectfbsurface.h>
+#include <display/idirectfbsurface_window.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <misc/util.h>
+
+#include <gfx/util.h>
+
+
+D_DEBUG_DOMAIN( Surface, "IDirectFBSurfaceW", "IDirectFBSurface_Window Interface" );
+
+/**********************************************************************************************************************/
+
+/*
+ * private data struct of IDirectFBSurface_Window
+ */
+typedef struct {
+ IDirectFBSurface_data base; /* base Surface implementation */
+
+ CoreWindow *window; /* pointer to core data */
+
+ pthread_t flip_thread; /* thread for non-flipping primary
+ surfaces, to make changes visible */
+
+// CoreGraphicsSerial serial;
+} IDirectFBSurface_Window_data;
+
+/**********************************************************************************************************************/
+
+static void *Flipping_Thread( void *arg );
+
+/**********************************************************************************************************************/
+
+static void
+IDirectFBSurface_Window_Destruct( IDirectFBSurface *thiz )
+{
+ IDirectFBSurface_Window_data *data;
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ D_ASSERT( thiz != NULL );
+
+ data = thiz->priv;
+
+ if ((int) data->flip_thread != -1) {
+ pthread_cancel( data->flip_thread );
+ pthread_join( data->flip_thread, NULL );
+ }
+
+ dfb_window_unref( data->window );
+
+ IDirectFBSurface_Destruct( thiz );
+}
+
+static DirectResult
+IDirectFBSurface_Window_Release( IDirectFBSurface *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Window)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (--data->base.ref == 0)
+ IDirectFBSurface_Window_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_Window_Flip( IDirectFBSurface *thiz,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags )
+{
+ DFBResult ret;
+ DFBRegion reg;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Window)
+
+ D_DEBUG_AT( Surface, "%s( %p, %p, 0x%08x )\n", __FUNCTION__, thiz, region, flags );
+
+ if (!data->base.surface)
+ return DFB_DESTROYED;
+
+ if (data->base.locked)
+ return DFB_LOCKED;
+
+ if (!data->base.area.current.w || !data->base.area.current.h ||
+ (region && (region->x1 > region->x2 || region->y1 > region->y2)))
+ return DFB_INVAREA;
+
+
+ IDirectFBSurface_StopAll( &data->base );
+
+ if (data->base.parent) {
+ IDirectFBSurface_data *parent_data;
+
+ DIRECT_INTERFACE_GET_DATA_FROM( data->base.parent, parent_data, IDirectFBSurface );
+
+ /* Signal end of sequence of operations. */
+ dfb_state_lock( &parent_data->state );
+ dfb_state_stop_drawing( &parent_data->state );
+ dfb_state_unlock( &parent_data->state );
+ }
+
+
+
+ dfb_region_from_rectangle( &reg, &data->base.area.current );
+
+ if (region) {
+ DFBRegion clip = DFB_REGION_INIT_TRANSLATED( region,
+ data->base.area.wanted.x,
+ data->base.area.wanted.y );
+
+ if (!dfb_region_region_intersect( &reg, &clip ))
+ return DFB_INVAREA;
+ }
+
+ D_DEBUG_AT( Surface, " -> FLIP %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION( &reg ) );
+
+
+ if (flags & DSFLIP_PIPELINE) {
+ dfb_gfxcard_wait_serial( &data->window->serial2 );
+
+ data->window->serial2 = data->window->serial1;
+
+ dfb_state_get_serial( &data->base.state, &data->window->serial1 );
+ }
+
+
+ if (data->window->region) {
+ dfb_layer_region_flip_update( data->window->region, &reg, flags );
+ }
+ else {
+ if (data->base.surface->config.caps & DSCAPS_FLIPPING) {
+ if (!(flags & DSFLIP_BLIT) && reg.x1 == 0 && reg.y1 == 0 &&
+ reg.x2 == data->base.surface->config.size.w - 1 &&
+ reg.y2 == data->base.surface->config.size.h - 1)
+ {
+ ret = dfb_surface_lock( data->base.surface );
+ if (ret)
+ return ret;
+
+ dfb_surface_flip( data->base.surface, false );
+
+ dfb_surface_unlock( data->base.surface );
+ }
+ else
+ dfb_back_to_front_copy( data->base.surface, &reg );
+ }
+
+ dfb_window_repaint( data->window, &reg, flags );
+ }
+
+ if (!data->window->config.opacity && data->base.caps & DSCAPS_PRIMARY)
+ dfb_window_set_opacity( data->window, 0xff );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBSurface_Window_GetSubSurface( IDirectFBSurface *thiz,
+ const DFBRectangle *rect,
+ IDirectFBSurface **surface )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Window)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ /* Check arguments */
+ if (!data->base.surface || !data->window || !data->window->surface)
+ return DFB_DESTROYED;
+
+ if (!surface)
+ return DFB_INVARG;
+
+ /* Allocate interface */
+ DIRECT_ALLOCATE_INTERFACE( *surface, IDirectFBSurface );
+
+ if (rect || data->base.limit_set) {
+ DFBRectangle wanted, granted;
+
+ /* Compute wanted rectangle */
+ if (rect) {
+ wanted = *rect;
+
+ wanted.x += data->base.area.wanted.x;
+ wanted.y += data->base.area.wanted.y;
+
+ if (wanted.w <= 0 || wanted.h <= 0) {
+ wanted.w = 0;
+ wanted.h = 0;
+ }
+ }
+ else {
+ wanted = data->base.area.wanted;
+ }
+
+ /* Compute granted rectangle */
+ granted = wanted;
+
+ dfb_rectangle_intersect( &granted, &data->base.area.granted );
+
+ /* Construct */
+ ret = IDirectFBSurface_Window_Construct( *surface, thiz, &wanted, &granted,
+ data->window, data->base.caps |
+ DSCAPS_SUBSURFACE, data->base.core );
+ }
+ else {
+ /* Construct */
+ ret = IDirectFBSurface_Window_Construct( *surface, thiz, NULL, NULL,
+ data->window, data->base.caps |
+ DSCAPS_SUBSURFACE, data->base.core );
+ }
+
+ return ret;
+}
+
+DFBResult
+IDirectFBSurface_Window_Construct( IDirectFBSurface *thiz,
+ IDirectFBSurface *parent,
+ DFBRectangle *wanted,
+ DFBRectangle *granted,
+ CoreWindow *window,
+ DFBSurfaceCapabilities caps,
+ CoreDFB *core )
+{
+ DFBResult ret;
+ DFBInsets insets;
+ CoreWindowStack *stack;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBSurface_Window)
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ stack = window->stack;
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ dfb_layer_context_lock( stack->context );
+
+ dfb_wm_get_insets( stack, window, &insets );
+
+ dfb_layer_context_unlock( stack->context );
+
+ ret = IDirectFBSurface_Construct( thiz, parent, wanted, granted, &insets,
+ window->surface, caps, core );
+ if (ret)
+ return ret;
+
+ if (dfb_window_ref( window )) {
+ IDirectFBSurface_Destruct( thiz );
+ return DFB_FAILURE;
+ }
+
+ data->window = window;
+ data->flip_thread = (pthread_t) -1;
+
+ /*
+ * Create an auto flipping thread if the application
+ * requested a (primary) surface that doesn't need to be flipped.
+ * Window surfaces even need to be flipped when they are single buffered.
+ */
+ if (!(caps & DSCAPS_FLIPPING) && !(caps & DSCAPS_SUBSURFACE)) {
+ if (dfb_config->autoflip_window)
+ pthread_create( &data->flip_thread, NULL, Flipping_Thread, thiz );
+ else
+ D_WARN( "Non-flipping window surface and no 'autoflip-window' option used" );
+ }
+
+ thiz->Release = IDirectFBSurface_Window_Release;
+ thiz->Flip = IDirectFBSurface_Window_Flip;
+ thiz->GetSubSurface = IDirectFBSurface_Window_GetSubSurface;
+
+ return DFB_OK;
+}
+
+
+/* file internal */
+
+static void *
+Flipping_Thread( void *arg )
+{
+ IDirectFBSurface *thiz = (IDirectFBSurface*) arg;
+ IDirectFBSurface_Window_data *data = (IDirectFBSurface_Window_data*) thiz->priv;
+
+ D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );
+
+ while (data->base.surface && data->window->surface) {
+ pthread_testcancel();
+
+ /*
+ * OPTIMIZE: only call if surface has been touched in the meantime
+ */
+ thiz->Flip( thiz, NULL, 0 );
+
+ usleep(40000);
+ }
+
+ return NULL;
+}
+
diff --git a/Source/DirectFB/src/display/idirectfbsurface_window.h b/Source/DirectFB/src/display/idirectfbsurface_window.h
new file mode 100755
index 0000000..92ca56e
--- /dev/null
+++ b/Source/DirectFB/src/display/idirectfbsurface_window.h
@@ -0,0 +1,48 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DIRECTFBSURFACE_WINDOW_H__
+#define __DIRECTFBSURFACE_WINDOW_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+/*
+ * calls base classes IDirectFBSurface_Construct,
+ * reallocates private data and overloads functions of the interface
+ */
+DFBResult IDirectFBSurface_Window_Construct( IDirectFBSurface *thiz,
+ IDirectFBSurface *parent,
+ DFBRectangle *req_rect,
+ DFBRectangle *clip_rect,
+ CoreWindow *window,
+ DFBSurfaceCapabilities caps,
+ CoreDFB *core );
+
+#endif
diff --git a/Source/DirectFB/src/gfx/Makefile.am b/Source/DirectFB/src/gfx/Makefile.am
new file mode 100755
index 0000000..8cbd6b9
--- /dev/null
+++ b/Source/DirectFB/src/gfx/Makefile.am
@@ -0,0 +1,29 @@
+## Makefile.am for DirectFB/src/misc
+
+SUBDIRS = generic
+
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+
+internalincludedir = $(INTERNALINCLUDEDIR)/gfx
+
+internalinclude_HEADERS = \
+ clip.h \
+ convert.h \
+ util.h
+
+
+noinst_LTLIBRARIES = libdirectfb_gfx.la
+
+libdirectfb_gfx_la_SOURCES = \
+ clip.c \
+ convert.c \
+ util.c
+
+libdirectfb_gfx_la_LIBADD = \
+ generic/libdirectfb_generic.la
diff --git a/Source/DirectFB/src/gfx/Makefile.in b/Source/DirectFB/src/gfx/Makefile.in
new file mode 100755
index 0000000..db7dfa4
--- /dev/null
+++ b/Source/DirectFB/src/gfx/Makefile.in
@@ -0,0 +1,676 @@
+# 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 = src/gfx
+DIST_COMMON = $(internalinclude_HEADERS) $(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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libdirectfb_gfx_la_DEPENDENCIES = generic/libdirectfb_generic.la
+am_libdirectfb_gfx_la_OBJECTS = clip.lo convert.lo util.lo
+libdirectfb_gfx_la_OBJECTS = $(am_libdirectfb_gfx_la_OBJECTS)
+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 = $(libdirectfb_gfx_la_SOURCES)
+DIST_SOURCES = $(libdirectfb_gfx_la_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
+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)$(internalincludedir)"
+internalincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(internalinclude_HEADERS)
+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 = generic
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+internalincludedir = $(INTERNALINCLUDEDIR)/gfx
+internalinclude_HEADERS = \
+ clip.h \
+ convert.h \
+ util.h
+
+noinst_LTLIBRARIES = libdirectfb_gfx.la
+libdirectfb_gfx_la_SOURCES = \
+ clip.c \
+ convert.c \
+ util.c
+
+libdirectfb_gfx_la_LIBADD = \
+ generic/libdirectfb_generic.la
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 src/gfx/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/gfx/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
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_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
+libdirectfb_gfx.la: $(libdirectfb_gfx_la_OBJECTS) $(libdirectfb_gfx_la_DEPENDENCIES)
+ $(LINK) $(libdirectfb_gfx_la_OBJECTS) $(libdirectfb_gfx_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clip.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.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-internalincludeHEADERS: $(internalinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(internalincludedir)" || $(MKDIR_P) "$(DESTDIR)$(internalincludedir)"
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(internalincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ $(internalincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+uninstall-internalincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+# 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 $(LTLIBRARIES) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(internalincludedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+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 clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-internalincludeHEADERS
+
+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 -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-internalincludeHEADERS
+
+.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 \
+ clean-noinstLTLIBRARIES ctags ctags-recursive 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-info install-info-am \
+ install-internalincludeHEADERS 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-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-internalincludeHEADERS
+
+# 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/src/gfx/clip.c b/Source/DirectFB/src/gfx/clip.c
new file mode 100755
index 0000000..195dc73
--- /dev/null
+++ b/Source/DirectFB/src/gfx/clip.c
@@ -0,0 +1,379 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <string.h>
+
+#include <directfb.h>
+
+#include <direct/util.h>
+
+#include <misc/util.h>
+
+#include <gfx/clip.h>
+
+#define REGION_CODE(x,y,cx1,cx2,cy1,cy2) ( ( (y) > (cy2) ? 8 : 0) | \
+ ( (y) < (cy1) ? 4 : 0) | \
+ ( (x) > (cx2) ? 2 : 0) | \
+ ( (x) < (cx1) ? 1 : 0) )
+
+
+DFBBoolean
+dfb_clip_line( const DFBRegion *clip, DFBRegion *line )
+{
+ unsigned char region_code1 = REGION_CODE( line->x1, line->y1,
+ clip->x1,
+ clip->x2,
+ clip->y1,
+ clip->y2 );
+
+ unsigned char region_code2 = REGION_CODE( line->x2, line->y2,
+ clip->x1,
+ clip->x2,
+ clip->y1,
+ clip->y2 );
+
+ while (region_code1 | region_code2) {
+ /* line completely outside the clipping rectangle */
+ if (region_code1 & region_code2)
+ return DFB_FALSE;
+
+
+ if (region_code1) {
+ if (region_code1 & 8) { /* divide line at bottom*/
+ line->x1 = line->x1 +(line->x2-line->x1) * (clip->y2 - line->y1) / (line->y2-line->y1);
+ line->y1 = clip->y2;
+ }
+ else
+ if (region_code1 & 4) { /* divide line at top*/
+ line->x1 = line->x1 +(line->x2-line->x1) * (clip->y1 - line->y1) / (line->y2-line->y1);
+ line->y1 = clip->y1;
+ }
+ else
+ if (region_code1 & 2) { /* divide line at right*/
+ line->y1 = line->y1 +(line->y2-line->y1) * (clip->x2 - line->x1) / (line->x2-line->x1);
+ line->x1 = clip->x2;
+ }
+ else
+ if (region_code1 & 1) { /* divide line at right*/
+ line->y1 = line->y1 +(line->y2-line->y1) * (clip->x1 - line->x1) / (line->x2-line->x1);
+ line->x1 = clip->x1;
+ }
+ region_code1 = REGION_CODE( line->x1, line->y1,
+ clip->x1,
+ clip->x2,
+ clip->y1,
+ clip->y2 );
+ }
+ else {
+ if (region_code2 & 8) { /* divide line at bottom*/
+ line->x2 = line->x1 +(line->x2-line->x1) * (clip->y2 - line->y1) / (line->y2-line->y1);
+ line->y2 = clip->y2;
+ }
+ else
+ if (region_code2 & 4) { /* divide line at top*/
+ line->x2 = line->x1 +(line->x2-line->x1) * (clip->y1 - line->y1) / (line->y2-line->y1);
+ line->y2 = clip->y1;
+ }
+ else
+ if (region_code2 & 2) { /* divide line at right*/
+ line->y2 = line->y1 +(line->y2-line->y1) * (clip->x2 - line->x1) / (line->x2-line->x1);
+ line->x2 = clip->x2;
+ }
+ else
+ if (region_code2 & 1) { /* divide line at right*/
+ line->y2 = line->y1 +(line->y2-line->y1) * (clip->x1 - line->x1) / (line->x2-line->x1);
+ line->x2 = clip->x1;
+ }
+ region_code2 = REGION_CODE( line->x2, line->y2, clip->x1,
+ clip->x2,
+ clip->y1,
+ clip->y2 );
+ }
+ }
+
+ /* successfully clipped or clipping not neccessary */
+ return DFB_TRUE;
+}
+
+DFBEdgeFlags
+dfb_clip_edges( const DFBRegion *clip, DFBRectangle *rect )
+{
+ DFBEdgeFlags flags = DFEF_ALL;
+
+ if ((clip->x1 >= rect->x + rect->w) ||
+ (clip->x2 < rect->x) ||
+ (clip->y1 >= rect->y + rect->h) ||
+ (clip->y2 < rect->y))
+ return DFEF_NONE;
+
+ if (clip->x1 > rect->x) {
+ rect->w += rect->x - clip->x1;
+ rect->x = clip->x1;
+
+ flags &= ~DFEF_LEFT;
+ }
+
+ if (clip->y1 > rect->y) {
+ rect->h += rect->y - clip->y1;
+ rect->y = clip->y1;
+
+ flags &= ~DFEF_TOP;
+ }
+
+ if (clip->x2 < rect->x + rect->w - 1) {
+ rect->w = clip->x2 - rect->x + 1;
+
+ flags &= ~DFEF_RIGHT;
+ }
+
+ if (clip->y2 < rect->y + rect->h - 1) {
+ rect->h = clip->y2 - rect->y + 1;
+
+ flags &= ~DFEF_BOTTOM;
+ }
+
+ return flags;
+}
+
+DFBBoolean
+dfb_clip_rectangle( const DFBRegion *clip, DFBRectangle *rect )
+{
+ if ((clip->x1 >= rect->x + rect->w) ||
+ (clip->x2 < rect->x) ||
+ (clip->y1 >= rect->y + rect->h) ||
+ (clip->y2 < rect->y))
+ return DFB_FALSE;
+
+ if (clip->x1 > rect->x) {
+ rect->w += rect->x - clip->x1;
+ rect->x = clip->x1;
+ }
+
+ if (clip->y1 > rect->y) {
+ rect->h += rect->y - clip->y1;
+ rect->y = clip->y1;
+ }
+
+ if (clip->x2 < rect->x + rect->w - 1)
+ rect->w = clip->x2 - rect->x + 1;
+
+ if (clip->y2 < rect->y + rect->h - 1)
+ rect->h = clip->y2 - rect->y + 1;
+
+ return DFB_TRUE;
+}
+
+DFBBoolean
+dfb_clip_triangle_precheck( const DFBRegion *clip, const DFBTriangle *tri )
+{
+ int x, y, w, h;
+
+ x = MIN (MIN (tri->x1, tri->x2), tri->x3);
+ y = MIN (MIN (tri->y1, tri->y2), tri->y3);
+ w = MAX (MAX (tri->x1, tri->x2), tri->x3) - x;
+ h = MAX (MAX (tri->y1, tri->y2), tri->y3) - y;
+
+ if (clip->x1 > x ||
+ clip->x2 < x + w ||
+ clip->y1 > y ||
+ clip->y2 < y + h)
+ return DFB_FALSE;
+
+ return DFB_TRUE;
+}
+
+DFBBoolean
+dfb_clip_triangle( const DFBRegion *clip, const DFBTriangle *tri, DFBPoint p[6], int *num )
+{
+ DFBRegion edges[3];
+ int num_edges;
+ int i, n;
+ DFBPoint p1 = {0, 0}, p2 = {0, 0};
+
+ /* Initialize edges. */
+ edges[0].x1 = tri->x1; edges[0].y1 = tri->y1;
+ edges[0].x2 = tri->x2; edges[0].y2 = tri->y2;
+ edges[1].x1 = tri->x2; edges[1].y1 = tri->y2;
+ edges[1].x2 = tri->x3; edges[1].y2 = tri->y3;
+ edges[2].x1 = tri->x3; edges[2].y1 = tri->y3;
+ edges[2].x2 = tri->x1; edges[2].y2 = tri->y1;
+ num_edges = 3;
+
+ for (i = 0; i < num_edges; i++) {
+ DFBRegion *reg = &edges[i];
+ DFBRegion line;
+ bool i1, i2;
+
+ /* Clip the edge to the clipping region. */
+ line = *reg;
+ if (dfb_clip_line( clip, &line )) {
+ *reg = line;
+ continue;
+ }
+
+ /* If the edge doesn't intersect clipping region, then
+ * intersect the edge with the diagonals of the clipping
+ * rectangle. If intersection point exits, add the nearest
+ * corner of the clipping region to the list of vertices.
+ */
+
+ /* Diagonal (x1,y1) (x2,y2). */
+ line = (DFBRegion) { clip->x1, clip->y1, clip->x2, clip->y2 };
+ i1 = dfb_line_segment_intersect( &line, reg, &p1.x, &p1.y );
+ if (i1) {
+ /* Get nearest corner. */
+ if (p1.x <= clip->x1 || p1.y <= clip->y1) {
+ p1.x = clip->x1;
+ p1.y = clip->y1;
+ } else {
+ p1.x = clip->x2;
+ p1.y = clip->y2;
+ }
+ }
+
+ /* Diagonal (x2,y1) (x1,y2). */
+ line = (DFBRegion) { clip->x2, clip->y1, clip->x1, clip->y2 };
+ i2 = dfb_line_segment_intersect( &line, reg, &p2.x, &p2.y );
+ if (i2) {
+ /* Get nearest corner. */
+ if (p2.x >= clip->x2 || p2.y <= clip->y1) {
+ p2.x = clip->x2;
+ p2.y = clip->y1;
+ } else {
+ p2.x = clip->x1;
+ p2.y = clip->y2;
+ }
+ }
+
+ if (i1 && i2) {
+ reg->x1 = p1.x;
+ reg->y1 = p1.y;
+ reg->x2 = p2.x;
+ reg->y2 = p2.y;
+ }
+ else if (i1) {
+ reg->x1 = reg->x2 = p1.x;
+ reg->y1 = reg->y2 = p1.y;
+ }
+ else if (i2) {
+ reg->x1 = reg->x2 = p2.x;
+ reg->y1 = reg->y2 = p2.y;
+ }
+ else {
+ /* Redudant edge. Remote it. */
+ memmove( reg, &edges[i+1], (num_edges-i-1) * sizeof(DFBRegion) );
+ num_edges--;
+ i--;
+ }
+ }
+
+ if (num_edges < 1) {
+ *num = 0;
+ return DFB_FALSE;
+ }
+
+ /* Get vertices from edges. */
+ p[0].x = edges[0].x1; p[0].y = edges[0].y1;
+ n = 1;
+ if (edges[0].x2 != edges[0].x1 || edges[0].y2 != edges[0].y1) {
+ p[1].x = edges[0].x2; p[1].y = edges[0].y2;
+ n++;
+ }
+
+ for (i = 1; i < num_edges; i++) {
+ if (edges[i].x1 != p[n-1].x || edges[i].y1 != p[n-1].y) {
+ p[n].x = edges[i].x1; p[n].y = edges[i].y1;
+ n++;
+ }
+ if (edges[i].x2 != p[n-1].x || edges[i].y2 != p[n-1].y) {
+ p[n].x = edges[i].x2; p[n].y = edges[i].y2;
+ n++;
+ }
+ }
+
+ if (p[n-1].x == p[0].x && p[n-1].y == p[0].y)
+ n--;
+
+ *num = n;
+
+ /* Actually fail if the number of vertices is below 3. */
+ return (n >= 3);
+}
+
+
+void
+dfb_clip_blit( const DFBRegion *clip,
+ DFBRectangle *srect, int *dx, int *dy )
+{
+ if (clip->x1 > *dx ) {
+ srect->w = MIN( (clip->x2 - clip->x1) + 1,
+ (*dx + srect->w) - clip->x1);
+
+ srect->x+= clip->x1 - *dx;
+ *dx = clip->x1;
+ }
+ else if (clip->x2 < *dx + srect->w - 1) {
+ srect->w = clip->x2 - *dx + 1;
+ }
+
+ if (clip->y1 > *dy ) {
+ srect->h = MIN( (clip->y2 - clip->y1) + 1,
+ (*dy + srect->h) - clip->y1);
+ srect->y+= clip->y1 - *dy;
+ *dy = clip->y1;
+ }
+ else if (clip->y2 < *dy + srect->h - 1) {
+ srect->h = clip->y2 - *dy + 1;
+ }
+}
+
+void
+dfb_clip_stretchblit( const DFBRegion *clip,
+ DFBRectangle *srect, DFBRectangle *drect )
+{
+ DFBRectangle orig_dst = *drect;
+
+ dfb_clip_rectangle( clip, drect );
+
+ if (drect->x != orig_dst.x)
+ srect->x += (int)( (drect->x - orig_dst.x) *
+ (srect->w / (float)orig_dst.w) );
+
+ if (drect->y != orig_dst.y)
+ srect->y += (int)( (drect->y - orig_dst.y) *
+ (srect->h / (float)orig_dst.h) );
+
+ if (drect->w != orig_dst.w)
+ srect->w = (int)( srect->w * (drect->w / (float)orig_dst.w) );
+
+ if (drect->h != orig_dst.h)
+ srect->h = (int)( srect->h * (drect->h / (float)orig_dst.h) );
+}
+
diff --git a/Source/DirectFB/src/gfx/clip.h b/Source/DirectFB/src/gfx/clip.h
new file mode 100755
index 0000000..e1ea261
--- /dev/null
+++ b/Source/DirectFB/src/gfx/clip.h
@@ -0,0 +1,125 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __GFX__CLIP_H__
+#define __GFX__CLIP_H__
+
+#include <directfb.h>
+
+typedef enum {
+ DFEF_NONE = 0x00000000,
+
+ DFEF_LEFT = 0x00000001,
+ DFEF_RIGHT = 0x00000002,
+ DFEF_TOP = 0x00000004,
+ DFEF_BOTTOM = 0x00000008,
+
+ DFEF_ALL = 0x0000000F
+} DFBEdgeFlags;
+
+/*
+ * Clips the line to the clipping region.
+ * Returns DFB_TRUE if at least one pixel of the line resides in the region.
+ */
+DFBBoolean dfb_clip_line( const DFBRegion *clip, DFBRegion *line );
+
+/*
+ * Clips the rectangle to the clipping region.
+ * Returns true if there was an intersection with the clipping region.
+ */
+DFBBoolean dfb_clip_rectangle( const DFBRegion *clip, DFBRectangle *rect );
+
+/*
+ * Clips the rectangle to the clipping region.
+ * Returns a flag for each edge that wasn't cut off.
+ */
+DFBEdgeFlags dfb_clip_edges( const DFBRegion *clip, DFBRectangle *rect );
+
+static inline DFBBoolean
+dfb_clip_needed( const DFBRegion *clip, DFBRectangle *rect )
+{
+ return ((clip->x1 > rect->x) ||
+ (clip->y1 > rect->y) ||
+ (clip->x2 < rect->x + rect->w - 1) ||
+ (clip->y2 < rect->y + rect->h - 1));
+}
+
+/*
+ * Simple check if triangle lies outside the clipping region.
+ * Returns true if the triangle may be visible within the region.
+ */
+DFBBoolean dfb_clip_triangle_precheck( const DFBRegion *clip,
+ const DFBTriangle *tri );
+
+/*
+ * Clips the triangle to the clipping region.
+ * Returns true if the triangle if visible within the region.
+ * The vertices of the polygon resulting from intersection are returned in buf.
+ * The number of vertices is at least 3.
+ */
+DFBBoolean dfb_clip_triangle( const DFBRegion *clip,
+ const DFBTriangle *tri,
+ DFBPoint buf[6],
+ int *num );
+
+/*
+ * Simple check if requested blitting lies outside of the clipping region.
+ * Returns true if blitting may need to be performed.
+ */
+static inline DFBBoolean
+dfb_clip_blit_precheck( const DFBRegion *clip,
+ int w, int h, int dx, int dy )
+{
+ if (w < 1 || h < 1 ||
+ (clip->x1 >= dx + w) ||
+ (clip->x2 < dx) ||
+ (clip->y1 >= dy + h) ||
+ (clip->y2 < dy))
+ return DFB_FALSE;
+
+ return DFB_TRUE;
+}
+
+/*
+ * Clips the blitting request to the clipping region.
+ * This includes adjustment of source AND destination coordinates.
+ */
+void dfb_clip_blit( const DFBRegion *clip,
+ DFBRectangle *srect, int *dx, int *dy );
+
+/*
+ * Clips the stretch blit request to the clipping region.
+ * This includes adjustment of source AND destination coordinates
+ * based on the scaling factor.
+ */
+void dfb_clip_stretchblit( const DFBRegion *clip,
+ DFBRectangle *srect,
+ DFBRectangle *drect );
+
+#endif
+
diff --git a/Source/DirectFB/src/gfx/convert.c b/Source/DirectFB/src/gfx/convert.c
new file mode 100755
index 0000000..484f5a6
--- /dev/null
+++ b/Source/DirectFB/src/gfx/convert.c
@@ -0,0 +1,1427 @@
+/*
+ (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 <directfb.h>
+#include <directfb_util.h>
+
+#include "convert.h"
+
+/* lookup tables for 2/3bit to 8bit color conversion */
+static const u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff};
+static const u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff};
+
+#define EXPAND_1to8(v) ((v) ? 0xff : 0x00)
+#define EXPAND_2to8(v) (lookup2to8[v])
+#define EXPAND_3to8(v) (lookup3to8[v])
+#define EXPAND_4to8(v) (((v) << 4) | ((v) ))
+#define EXPAND_5to8(v) (((v) << 3) | ((v) >> 2))
+#define EXPAND_6to8(v) (((v) << 2) | ((v) >> 4))
+#define EXPAND_7to8(v) (((v) << 1) | ((v) >> 6))
+
+
+DFBSurfacePixelFormat
+dfb_pixelformat_for_depth( int depth )
+{
+ switch (depth) {
+ case 2:
+ return DSPF_LUT2;
+ case 8:
+ return DSPF_LUT8;
+ case 12:
+ return DSPF_ARGB4444;
+ case 14:
+ return DSPF_ARGB2554;
+ case 15:
+ return DSPF_ARGB1555;
+ case 16:
+ return DSPF_RGB16;
+ case 18:
+ return DSPF_RGB18;
+ case 24:
+ return DSPF_RGB24;
+ case 32:
+ return DSPF_RGB32;
+ }
+
+ return DSPF_UNKNOWN;
+}
+
+void
+dfb_pixel_to_color( DFBSurfacePixelFormat format,
+ unsigned long pixel,
+ DFBColor *ret_color )
+{
+ ret_color->a = 0xff;
+
+ switch (format) {
+ case DSPF_RGB332:
+ ret_color->r = EXPAND_3to8( (pixel & 0xe0) >> 5 );
+ ret_color->g = EXPAND_3to8( (pixel & 0x1c) >> 2 );
+ ret_color->b = EXPAND_2to8( (pixel & 0x03) );
+ break;
+
+ case DSPF_ARGB1555:
+ ret_color->a = EXPAND_1to8( pixel >> 15 );
+ case DSPF_RGB555:
+ ret_color->r = EXPAND_5to8( (pixel & 0x7c00) >> 10 );
+ ret_color->g = EXPAND_5to8( (pixel & 0x03e0) >> 5 );
+ ret_color->b = EXPAND_5to8( (pixel & 0x001f) );
+ break;
+
+ case DSPF_BGR555:
+ ret_color->r = EXPAND_5to8( (pixel & 0x001f) );
+ ret_color->g = EXPAND_5to8( (pixel & 0x03e0) >> 5 );
+ ret_color->b = EXPAND_5to8( (pixel & 0x7c00) >> 10 );
+ break;
+
+ case DSPF_ARGB2554:
+ ret_color->a = EXPAND_2to8( pixel >> 14 );
+ ret_color->r = EXPAND_5to8( (pixel & 0x3e00) >> 9 );
+ ret_color->g = EXPAND_5to8( (pixel & 0x01f0) >> 4 );
+ ret_color->b = EXPAND_4to8( (pixel & 0x000f) );
+ break;
+
+ case DSPF_ARGB4444:
+ ret_color->a = EXPAND_4to8( pixel >> 12 );
+ case DSPF_RGB444:
+ ret_color->r = EXPAND_4to8( (pixel & 0x0f00) >> 8 );
+ ret_color->g = EXPAND_4to8( (pixel & 0x00f0) >> 4 );
+ ret_color->b = EXPAND_4to8( (pixel & 0x000f) );
+ break;
+
+ case DSPF_RGBA4444:
+ ret_color->r = EXPAND_4to8( (pixel ) >> 12 );
+ ret_color->g = EXPAND_4to8( (pixel & 0x0f00) >> 8 );
+ ret_color->b = EXPAND_4to8( (pixel & 0x00f0) >> 4 );
+ ret_color->a = EXPAND_4to8( (pixel & 0x000f) );
+ break;
+
+ case DSPF_RGB16:
+ ret_color->r = EXPAND_5to8( (pixel & 0xf800) >> 11 );
+ ret_color->g = EXPAND_6to8( (pixel & 0x07e0) >> 5 );
+ ret_color->b = EXPAND_5to8( (pixel & 0x001f) );
+ break;
+
+ case DSPF_ARGB:
+ ret_color->a = pixel >> 24;
+ case DSPF_RGB24:
+ case DSPF_RGB32:
+ ret_color->r = (pixel & 0xff0000) >> 16;
+ ret_color->g = (pixel & 0x00ff00) >> 8;
+ ret_color->b = (pixel & 0x0000ff);
+ break;
+
+ case DSPF_AiRGB:
+ ret_color->a = (pixel >> 24) ^ 0xff;
+ ret_color->r = (pixel & 0xff0000) >> 16;
+ ret_color->g = (pixel & 0x00ff00) >> 8;
+ ret_color->b = (pixel & 0x0000ff);
+ break;
+
+ default:
+ ret_color->r = 0;
+ ret_color->g = 0;
+ ret_color->b = 0;
+ }
+}
+
+unsigned long
+dfb_pixel_from_color( DFBSurfacePixelFormat format,
+ const DFBColor *color )
+{
+ u32 y, cb, cr;
+
+ switch (format) {
+ case DSPF_RGB332:
+ return PIXEL_RGB332( color->r, color->g, color->b );
+
+ case DSPF_ARGB1555:
+ return PIXEL_ARGB1555( color->a, color->r, color->g, color->b );
+
+ case DSPF_RGB555:
+ return PIXEL_RGB555( color->r, color->g, color->b );
+
+ case DSPF_BGR555:
+ return PIXEL_BGR555( color->r, color->g, color->b );
+
+ case DSPF_ARGB2554:
+ return PIXEL_ARGB2554( color->a, color->r, color->g, color->b );
+
+ case DSPF_ARGB4444:
+ return PIXEL_ARGB4444( color->a, color->r, color->g, color->b );
+
+ case DSPF_RGBA4444:
+ return PIXEL_RGBA4444( color->a, color->r, color->g, color->b );
+
+ case DSPF_RGB444:
+ return PIXEL_RGB444( color->r, color->g, color->b );
+
+ case DSPF_RGB16:
+ return PIXEL_RGB16( color->r, color->g, color->b );
+
+ case DSPF_RGB18:
+ return PIXEL_RGB18( color->r, color->g, color->b );
+
+ case DSPF_ARGB1666:
+ return PIXEL_ARGB1666( color->a, color->r, color->g, color->b );
+
+ case DSPF_ARGB6666:
+ return PIXEL_ARGB6666( color->a, color->r, color->g, color->b );
+
+ case DSPF_RGB24:
+ return PIXEL_RGB32( color->r, color->g, color->b );
+
+ case DSPF_RGB32:
+ return PIXEL_RGB32( color->r, color->g, color->b );
+
+ case DSPF_ARGB:
+ return PIXEL_ARGB( color->a, color->r, color->g, color->b );
+
+ case DSPF_AiRGB:
+ return PIXEL_AiRGB( color->a, color->r, color->g, color->b );
+
+ case DSPF_AYUV:
+ RGB_TO_YCBCR( color->r, color->g, color->b, y, cb, cr );
+ return PIXEL_AYUV( color->a, y, cb, cr );
+
+ case DSPF_YUY2:
+ RGB_TO_YCBCR( color->r, color->g, color->b, y, cb, cr );
+ return PIXEL_YUY2( y, cb, cr );
+
+ case DSPF_UYVY:
+ RGB_TO_YCBCR( color->r, color->g, color->b, y, cb, cr );
+ return PIXEL_UYVY( y, cb, cr );
+
+ case DSPF_I420:
+ case DSPF_YV12:
+ RGB_TO_YCBCR( color->r, color->g, color->b, y, cb, cr );
+ return y | (cb << 8) | (cr << 16);
+
+ default:
+ D_WARN( "unknown format 0x%08x", format );
+ }
+
+ return 0x55555555;
+}
+
+const char *
+dfb_pixelformat_name( DFBSurfacePixelFormat format )
+{
+ int i = 0;
+
+ do {
+ if (format == dfb_pixelformat_names[i].format)
+ return dfb_pixelformat_names[i].name;
+ } while (dfb_pixelformat_names[i++].format != DSPF_UNKNOWN);
+
+ return "<invalid>";
+}
+
+void
+dfb_convert_to_rgb16( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u16 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp2 = dpitch / 2;
+ int x;
+
+ switch (format) {
+ case DSPF_RGB16:
+ while (height--) {
+ direct_memcpy( dst, src, width * 2 );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_NV16:
+ while (height--) {
+ const u8 *src8 = src;
+ const u16 *src16 = src + surface_height * spitch;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+#ifdef WORDS_BIGENDIAN
+ YCBCR_TO_RGB( src8[x], src16[x>>1] >> 8, src16[x>>1] & 0xff, r, g, b );
+#else
+ YCBCR_TO_RGB( src8[x], src16[x>>1] & 0xff, src16[x>>1] >> 8, r, g, b );
+#endif
+
+ dst[x] = PIXEL_RGB16( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB16( EXPAND_4to8( (src16[x] & 0x0f00) >> 8 ),
+ EXPAND_4to8( (src16[x] & 0x00f0) >> 4 ),
+ EXPAND_4to8( (src16[x] & 0x000f) ) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB16( EXPAND_4to8( (src16[x] & 0xf000) >> 12 ),
+ EXPAND_4to8( (src16[x] & 0x0f00) >> 8 ),
+ EXPAND_4to8( (src16[x] & 0x00f0) >> 4 ) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ((src16[x] & 0x7c00) << 1) | ((src16[x] & 0x03e0) << 1) | (src16[x] & 0x003f);
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_BGR555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ((src16[x] & 0x7c00) >> 10) | ((src16[x] & 0x03e0) << 1) | ((src16[x] & 0x001f) << 11 );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB16( (src32[x] & 0xff0000) >> 16,
+ (src32[x] & 0x00ff00) >> 8,
+ (src32[x] & 0x0000ff) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_AYUV:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+ YCBCR_TO_RGB( (src32[x] >> 16) & 0xff, (src32[x] >> 8) & 0xff, src32[x] & 0xff, r, g, b );
+
+ dst[x] = PIXEL_RGB16( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_rgb555( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u16 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp2 = dpitch / 2;
+ int x;
+
+ switch (format) {
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ while (height--) {
+ direct_memcpy( dst, src, width * 2 );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_NV16:
+ while (height--) {
+ const u8 *src8 = src;
+ const u16 *src16 = src + surface_height * spitch;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+#ifdef WORDS_BIGENDIAN
+ YCBCR_TO_RGB( src8[x], src16[x>>1] >> 8, src16[x>>1] & 0xff, r, g, b );
+#else
+ YCBCR_TO_RGB( src8[x], src16[x>>1] & 0xff, src16[x>>1] >> 8, r, g, b );
+#endif
+
+ dst[x] = PIXEL_RGB555( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB555( EXPAND_4to8( (src16[x] & 0x0f00) >> 8 ),
+ EXPAND_4to8( (src16[x] & 0x00f0) >> 4 ),
+ EXPAND_4to8( (src16[x] & 0x000f) ) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB555( EXPAND_4to8( (src16[x] & 0xf000) >> 12 ),
+ EXPAND_4to8( (src16[x] & 0x0f00) >> 8 ),
+ EXPAND_4to8( (src16[x] & 0x00f0) >> 4 ) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB16:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ((src16[x] & 0xffc0) >> 1) | (src16[x] & 0x001f);
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_BGR555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ((src16[x] & 0x7c00) >> 10) | (src16[x] & 0x03e0) | ((src16[x] & 0x001f) << 10 );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB555( (src32[x] & 0xff0000) >> 16,
+ (src32[x] & 0x00ff00) >> 8,
+ (src32[x] & 0x0000ff) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_AYUV:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+ YCBCR_TO_RGB( (src32[x] >> 16) & 0xff, (src32[x] >> 8) & 0xff, src32[x] & 0xff, r, g, b );
+
+ dst[x] = PIXEL_RGB555( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_rgb32( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp4 = dpitch / 4;
+ int x;
+
+ switch (format) {
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ while (height--) {
+ direct_memcpy( dst, src, width * 4 );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB24:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (x=0; x<width; x++)
+#ifdef WORDS_BIGENDIAN
+ dst[x] = ( src8[x*3+0] << 16 ) |
+ ( src8[x*3+1] << 8 ) |
+ ( src8[x*3+2] );
+#else
+ dst[x] = ( src8[x*3+2] << 16 ) |
+ ( src8[x*3+1] << 8 ) |
+ ( src8[x*3+0] );
+#endif
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_AYUV:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+ YCBCR_TO_RGB( (src32[x] >> 16) & 0xff, (src32[x] >> 8) & 0xff, src32[x] & 0xff, r, g, b );
+
+ dst[x] = PIXEL_RGB32( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_NV16:
+ while (height--) {
+ const u8 *src8 = src;
+ const u16 *src16 = src + surface_height * spitch;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+#ifdef WORDS_BIGENDIAN
+ YCBCR_TO_RGB( src8[x], src16[x>>1] >> 8, src16[x>>1] & 0xff, r, g, b );
+#else
+ YCBCR_TO_RGB( src8[x], src16[x>>1] & 0xff, src16[x>>1] >> 8, r, g, b );
+#endif
+
+ dst[x] = PIXEL_RGB32( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ARGB4444_TO_RGB32( src16[x] );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = RGBA4444_TO_RGB32( src16[x] );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB32( ((src16[x] & 0x7c00) >> 7) | ((src16[x] & 0x7000) >> 12),
+ ((src16[x] & 0x03e0) >> 2) | ((src16[x] & 0x0380) >> 7),
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_BGR555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB32( ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2),
+ ((src16[x] & 0x03e0) >> 2) | ((src16[x] & 0x0380) >> 7),
+ ((src16[x] & 0x7c00) >> 7) | ((src16[x] & 0x7000) >> 12) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB16:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB32( ((src16[x] & 0xf800) >> 8) | ((src16[x] & 0xe000) >> 13),
+ ((src16[x] & 0x07e0) >> 3) | ((src16[x] & 0x0300) >> 8),
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_argb( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp4 = dpitch / 4;
+ int x;
+
+ switch (format) {
+ case DSPF_ARGB:
+ while (height--) {
+ direct_memcpy( dst, src, width * 4 );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB32:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = src32[x] | 0xff000000;
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB24:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (x=0; x<width; x++)
+#ifdef WORDS_BIGENDIAN
+ dst[x] = ( src8[x*3+0] << 16 ) |
+ ( src8[x*3+1] << 8 ) |
+ ( src8[x*3+2] ) | 0xff000000;
+#else
+ dst[x] = ( src8[x*3+2] << 16 ) |
+ ( src8[x*3+1] << 8 ) |
+ ( src8[x*3+0] ) | 0xff000000;
+#endif
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_AYUV:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+ YCBCR_TO_RGB( (src32[x] >> 16) & 0xff, (src32[x] >> 8) & 0xff, src32[x] & 0xff, r, g, b );
+
+ dst[x] = PIXEL_ARGB( src32[x] >> 24, r, g, b );
+ }
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_NV16:
+ while (height--) {
+ const u8 *src8 = src;
+ const u16 *src16 = src + surface_height * spitch;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+#ifdef WORDS_BIGENDIAN
+ YCBCR_TO_RGB( src8[x], src16[x>>1] >> 8, src16[x>>1] & 0xff, r, g, b );
+#else
+ YCBCR_TO_RGB( src8[x], src16[x>>1] & 0xff, src16[x>>1] >> 8, r, g, b );
+#endif
+
+ dst[x] = PIXEL_ARGB( 0xff, r, g, b );
+ }
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ARGB4444_TO_ARGB( src16[x] );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = RGBA4444_TO_ARGB( src16[x] );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_ARGB( 0xff,
+ ((src16[x] & 0x0f00) >> 4) | ((src16[x] & 0x0f00) >> 8),
+ ((src16[x] & 0x00f0) ) | ((src16[x] & 0x00f0) >> 4),
+ ((src16[x] & 0x000f) << 4) | ((src16[x] & 0x000f) ) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_ARGB( (src16[x] & 0x8000) ? 0xff : 0x00,
+ ((src16[x] & 0x7c00) >> 7) | ((src16[x] & 0x7000) >> 12),
+ ((src16[x] & 0x03e0) >> 2) | ((src16[x] & 0x0380) >> 7),
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_ARGB( 0xff,
+ ((src16[x] & 0x7c00) >> 7) | ((src16[x] & 0x7000) >> 12),
+ ((src16[x] & 0x03e0) >> 2) | ((src16[x] & 0x0380) >> 7),
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_BGR555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_ARGB( 0xff,
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2),
+ ((src16[x] & 0x03e0) >> 2) | ((src16[x] & 0x0380) >> 7),
+ ((src16[x] & 0x7c00) >> 7) | ((src16[x] & 0x7000) >> 12) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB16:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_ARGB( 0xff,
+ ((src16[x] & 0xf800) >> 8) | ((src16[x] & 0xe000) >> 13),
+ ((src16[x] & 0x07e0) >> 3) | ((src16[x] & 0x0300) >> 8),
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_rgb24( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u8 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ int n, n3;
+
+ switch (format) {
+ case DSPF_A8:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = src8[n];
+ dst[n3+1] = src8[n];
+ dst[n3+2] = src8[n];
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_AiRGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src32[n] & 0xFF0000) >> 16;
+ dst[n3+1] = (src32[n] & 0x00FF00) >> 8;
+ dst[n3+2] = (src32[n] & 0x0000FF);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src32[n] & 0xFF0000) >> 16;
+ dst[n3+1] = (src32[n] & 0x00FF00) >> 8;
+ dst[n3+2] = (src32[n] & 0x0000FF);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0x7C00) >> 7;
+ dst[n3+1] = (src16[n] & 0x03E0) >> 2;
+ dst[n3+2] = (src16[n] & 0x001F) << 3;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0x7C00) >> 7;
+ dst[n3+1] = (src16[n] & 0x03E0) >> 2;
+ dst[n3+2] = (src16[n] & 0x001F) << 3;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_BGR555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+2] = (src16[n] & 0x7C00) >> 7;
+ dst[n3+1] = (src16[n] & 0x03E0) >> 2;
+ dst[n3+0] = (src16[n] & 0x001F) << 3;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_ARGB2554:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0x3E00) >> 6;
+ dst[n3+1] = (src16[n] & 0x01F0) >> 1;
+ dst[n3+2] = (src16[n] & 0x000F) << 4;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0x0F00) >> 4;
+ dst[n3+1] = (src16[n] & 0x00F0);
+ dst[n3+2] = (src16[n] & 0x000F) << 4;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0xF000) >> 8;
+ dst[n3+1] = (src16[n] & 0x0F00) >> 4;
+ dst[n3+2] = (src16[n] & 0x00F0);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0x0F00) >> 4;
+ dst[n3+1] = (src16[n] & 0x00F0);
+ dst[n3+2] = (src16[n] & 0x000F) << 4;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB332:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = lookup3to8[ (src8[n] >> 5) ];
+ dst[n3+1] = lookup3to8[ (src8[n] >> 2) & 0x07 ];
+ dst[n3+2] = lookup2to8[ (src8[n] ) & 0x03 ];
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB16:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0xF800) >> 8;
+ dst[n3+1] = (src16[n] & 0x07E0) >> 3;
+ dst[n3+2] = (src16[n] & 0x001F) << 3;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB24:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+#ifdef WORDS_BIGENDIAN
+ dst[n3+0] = src8[n3+0];
+ dst[n3+1] = src8[n3+1];
+ dst[n3+2] = src8[n3+2];
+#else
+ dst[n3+0] = src8[n3+2];
+ dst[n3+1] = src8[n3+1];
+ dst[n3+2] = src8[n3+0];
+#endif
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB32:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src32[n] & 0xFF0000) >> 16;
+ dst[n3+1] = (src32[n] & 0x00FF00) >> 8;
+ dst[n3+2] = (src32[n] & 0x0000FF);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_YUY2:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0, n3=0; n<width/2; n++, n3+=6) {
+ register u32 y0, cb, y1, cr;
+ y0 = (src32[n] & 0x000000FF);
+ cb = (src32[n] & 0x0000FF00) >> 8;
+ y1 = (src32[n] & 0x00FF0000) >> 16;
+ cr = (src32[n] & 0xFF000000) >> 24;
+ YCBCR_TO_RGB( y0, cb, cr,
+ dst[n3+0], dst[n3+1], dst[n3+2] );
+ YCBCR_TO_RGB( y1, cb, cr,
+ dst[n3+3], dst[n3+4], dst[n3+5] );
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_UYVY:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0, n3=0; n<width/2; n++, n3+=6) {
+ register u32 y0, cb, y1, cr;
+ cb = (src32[n] & 0x000000FF);
+ y0 = (src32[n] & 0x0000FF00) >> 8;
+ cr = (src32[n] & 0x00FF0000) >> 16;
+ y1 = (src32[n] & 0xFF000000) >> 24;
+ YCBCR_TO_RGB( y0, cb, cr,
+ dst[n3+0], dst[n3+1], dst[n3+2] );
+ YCBCR_TO_RGB( y1, cb, cr,
+ dst[n3+3], dst[n3+4], dst[n3+5] );
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_NV16: {
+ while (height--) {
+ const u16 *cbcr = src + surface_height * spitch;
+ const u8 *src8 = src;
+
+ for (n=0, n3=0; n<width/2; n++, n3+=6) {
+#ifdef WORDS_BIGENDIAN
+ YCBCR_TO_RGB( src8[n*2+0], cbcr[n] >> 8, cbcr[n] & 0xff,
+ dst[n3+0], dst[n3+1], dst[n3+2] );
+
+ YCBCR_TO_RGB( src8[n*2+1], cbcr[n] >> 8, cbcr[n] & 0xff,
+ dst[n3+3], dst[n3+4], dst[n3+5] );
+#else
+ YCBCR_TO_RGB( src8[n*2+0], cbcr[n] & 0xff, cbcr[n] >> 8,
+ dst[n3+0], dst[n3+1], dst[n3+2] );
+
+ YCBCR_TO_RGB( src8[n*2+1], cbcr[n] & 0xff, cbcr[n] >> 8,
+ dst[n3+3], dst[n3+4], dst[n3+5] );
+#endif
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ }
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_a8( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u8 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ int n;
+
+ switch (format) {
+ case DSPF_A8:
+ while (height--) {
+ const u8 *src8 = src;
+
+ direct_memcpy( dst, src8, width );
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_AiRGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0; n<width; n++) {
+ dst[n] = ~(src32[n] >> 24);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0; n<width; n++) {
+ dst[n] = src32[n] >> 24;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0; n<width; n++) {
+ dst[n] = (src16[n] & 0x8000) ? 0xff : 0x00;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB2554:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0; n<width; n++) {
+ switch (src16[n] >> 14) {
+ case 0:
+ dst[n] = 0x00;
+ break;
+ case 1:
+ dst[n] = 0x55;
+ break;
+ case 2:
+ dst[n] = 0xAA;
+ break;
+ case 3:
+ dst[n] = 0xFF;
+ break;
+ }
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0; n<width; n++) {
+ dst[n] = (src16[n] >> 12);
+ dst[n] |= dst[n] << 4;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0; n<width; n++) {
+ dst[n] = EXPAND_4to8(src16[n] & 0xf);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_RGB332:
+ case DSPF_RGB444:
+ case DSPF_RGB555:
+ case DSPF_BGR555:
+ case DSPF_RGB16:
+ case DSPF_RGB24:
+ case DSPF_RGB32:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ case DSPF_NV16:
+ while (height--) {
+ memset( dst, 0xff, width );
+
+ dst += dpitch;
+ }
+ break;
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_a4( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u8 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int w2 = width / 2;
+ int x, n;
+
+ D_ASSUME( (width & 1) == 0 );
+
+ switch (format) {
+ case DSPF_A8:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (x=0, n=0; x<w2; x++, n+=2)
+ dst[x] = (src8[n] & 0xf0) | ((src8[n+1] & 0xf0) >> 4);
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0, n=0; x<w2; x++, n+=2)
+ dst[x] = ((src16[n] & 0xf000) >> 8) | (src16[n+1] >> 12);
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0, n=0; x<w2; x++, n+=2)
+ dst[x] = ((src16[n] & 0x000f) << 4) | (src16[n+1] & 0x000f);
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0, n=0; x<w2; x++, n+=2)
+ dst[x] = ((src16[n] & 0x8000) ? 0xf0 : 0) | ((src16[n+1] & 0x8000) ? 0x0f : 0);
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_ARGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0, n=0; x<w2; x++, n+=2)
+ dst[x] = ((src32[n] & 0xf0000000) >> 24) | ((src32[n+1] & 0xf0000000) >> 28);
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ default:
+ if (DFB_PIXELFORMAT_HAS_ALPHA( format ))
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_yuy2( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp4 = dpitch / 4;
+
+ switch (format) {
+ case DSPF_YUY2:
+ while (height--) {
+ direct_memcpy( dst, src, width * 2 );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_uyvy( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp4 = dpitch / 4;
+
+ switch (format) {
+ case DSPF_UYVY:
+ while (height--) {
+ direct_memcpy( dst, src, width * 2 );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
diff --git a/Source/DirectFB/src/gfx/convert.h b/Source/DirectFB/src/gfx/convert.h
new file mode 100755
index 0000000..a831d8c
--- /dev/null
+++ b/Source/DirectFB/src/gfx/convert.h
@@ -0,0 +1,562 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __GFX__CONVERT_H__
+#define __GFX__CONVERT_H__
+
+#include <directfb.h>
+
+#include <direct/memcpy.h>
+#include <direct/util.h>
+
+
+/* pixel packing */
+
+#define PIXEL_RGB332(r,g,b) ( (((r)&0xE0) ) | \
+ (((g)&0xE0) >> 3) | \
+ (((b)&0xC0) >> 6) )
+
+#define PIXEL_ARGB1555(a,r,g,b)( (((a)&0x80) << 8) | \
+ (((r)&0xF8) << 7) | \
+ (((g)&0xF8) << 2) | \
+ (((b)&0xF8) >> 3) )
+
+#define PIXEL_RGB555(r,g,b) ( (((r)&0xF8) << 7) | \
+ (((g)&0xF8) << 2) | \
+ (((b)&0xF8) >> 3) )
+
+#define PIXEL_BGR555(r,g,b) ( (((b)&0xF8) << 7) | \
+ (((g)&0xF8) << 2) | \
+ (((r)&0xF8) >> 3) )
+
+#define PIXEL_ARGB2554(a,r,g,b)( (((a)&0xC0) << 8) | \
+ (((r)&0xF8) << 6) | \
+ (((g)&0xF8) << 1) | \
+ (((b)&0xF0) >> 4) )
+
+#define PIXEL_ARGB4444(a,r,g,b)( (((a)&0xF0) << 8) | \
+ (((r)&0xF0) << 4) | \
+ (((g)&0xF0) ) | \
+ (((b)&0xF0) >> 4) )
+
+#define PIXEL_RGBA4444(a,r,g,b)( (((r)&0xF0) << 8) | \
+ (((g)&0xF0) << 4) | \
+ (((b)&0xF0) ) | \
+ (((a)&0xF0) >> 4) )
+
+#define PIXEL_RGB444(r,g,b) ( (((r)&0xF0) << 4) | \
+ (((g)&0xF0) ) | \
+ (((b)&0xF0) >> 4) )
+
+#define PIXEL_RGB16(r,g,b) ( (((r)&0xF8) << 8) | \
+ (((g)&0xFC) << 3) | \
+ (((b)&0xF8) >> 3) )
+
+#define PIXEL_RGB18(r,g,b) ( (((r)&0xFC) << 10) | \
+ (((g)&0xFC) << 4) | \
+ (((b)&0xFC) >> 2) )
+
+#define PIXEL_RGB32(r,g,b) ( ((r) << 16) | \
+ ((g) << 8) | \
+ (b) )
+
+#define PIXEL_ARGB(a,r,g,b) ( ((a) << 24) | \
+ ((r) << 16) | \
+ ((g) << 8) | \
+ (b) )
+
+#define PIXEL_ARGB1666(a,r,g,b) ( (((a)&0x80) << 11) | \
+ (((r)&0xFC) << 10) | \
+ (((g)&0xFC) << 4) | \
+ (((b)&0xFC) >> 2) )
+
+#define PIXEL_ARGB6666(a,r,g,b) ( (((a)&0xFC) << 16) | \
+ (((r)&0xFC) << 10) | \
+ (((g)&0xFC) << 4) | \
+ (((b)&0xFC) >> 2) )
+
+#define PIXEL_AYUV(a,y,u,v) ( ((a) << 24) | \
+ ((y) << 16) | \
+ ((u) << 8) | \
+ (v) )
+
+#define PIXEL_AiRGB(a,r,g,b) ( (((a) ^ 0xff) << 24) | \
+ ((r) << 16) | \
+ ((g) << 8) | \
+ (b) )
+
+#ifdef WORDS_BIGENDIAN
+
+#define PIXEL_YUY2(y,u,v) ( ((u) << 24) | \
+ ((y) << 16) | \
+ ((v) << 8) | \
+ (y) )
+
+#define PIXEL_UYVY(y,u,v) ( ((y) << 24) | \
+ ((u) << 16) | \
+ ((y) << 8) | \
+ (v) )
+#else /* little endian */
+
+#define PIXEL_YUY2(y,u,v) ( ((v) << 24) | \
+ ((y) << 16) | \
+ ((u) << 8) | \
+ (y) )
+
+#define PIXEL_UYVY(y,u,v) ( ((y) << 24) | \
+ ((v) << 16) | \
+ ((y) << 8) | \
+ (u) )
+
+#endif
+
+
+/* packed pixel conversions */
+
+#define ARGB1555_TO_RGB332(pixel) ( (((pixel) & 0x7000) >> 7) | \
+ (((pixel) & 0x0380) >> 5) | \
+ (((pixel) & 0x0018) >> 3) )
+
+#define ARGB1555_TO_ARGB2554(pixel) ( (((pixel) & 0x8000) ) | \
+ (((pixel) & 0x7FFF) >> 1) )
+
+#define ARGB1555_TO_ARGB4444(pixel) ( (((pixel) & 0x8000) ? 0xf000 : 0 ) | \
+ (((pixel) & 0x7800) >> 3) | \
+ (((pixel) & 0x03C0) >> 2) | \
+ (((pixel) & 0x0018) >> 1) )
+
+#define ARGB1555_TO_RGBA4444(pixel) ( (((pixel) & 0x8000) ? 0x000f : 0 ) | \
+ (((pixel) & 0x7800) << 1) | \
+ (((pixel) & 0x03C0) << 2) | \
+ (((pixel) & 0x0018) << 3) )
+
+#define ARGB1555_TO_RGB16(pixel) ( (((pixel) & 0x7C00) << 1) | \
+ (((pixel) & 0x03E0) << 1) | \
+ (((pixel) & 0x001F)) )
+
+#define ARGB1555_TO_RGB32(pixel) ( (((pixel) & 0x7C00) << 9) | \
+ (((pixel) & 0x03E0) << 6) | \
+ (((pixel) & 0x001F) << 3) )
+
+#define ARGB1555_TO_ARGB(pixel) ( (((pixel) & 0x8000) ? 0xFF000000 : 0) | \
+ (((pixel) & 0x7C00) << 9) | \
+ (((pixel) & 0x03E0) << 6) | \
+ (((pixel) & 0x001F) << 3) )
+
+#define ARGB1555_TO_RGB555(pixel) ( (((pixel) & 0x7C00) << 9) | \
+ (((pixel) & 0x03E0) << 6) | \
+ (((pixel) & 0x001F) << 3) )
+
+#define ARGB1555_TO_RGB444(pixel) ( (((pixel) & 0x7800) >> 3) | \
+ (((pixel) & 0x03C0) >> 2) | \
+ (((pixel) & 0x001E) >> 1) )
+
+/* xRGB to xxRRGGBB, so xRxx left 3, xRGx left 2, xxGB left 1, xxxB */
+#define ARGB4444_TO_RGB32(pixel) ( (((pixel) & 0x0F00) << 12) | \
+ (((pixel) & 0x0FF0) << 8) | \
+ (((pixel) & 0x00FF) << 4) | \
+ (((pixel) & 0x000F) ) )
+
+/* RGBx to xxRRGGBB, so Rxxx left 2, RGxx left 1, xGBx, xxBx right 1 */
+#define RGBA4444_TO_RGB32(pixel) ( (((pixel) & 0xF000) << 8) | \
+ (((pixel) & 0xFF00) << 4) | \
+ (((pixel) & 0x0FF0) ) | \
+ (((pixel) & 0x00F0) >> 4) )
+
+/* ARGB to AARRGGBB, so Axxx left 4, ARxx left 3, xRGx left 2, xxGB left 1, xxxB */
+#define ARGB4444_TO_ARGB(pixel) ( (((pixel) & 0xF000) << 16) | \
+ (((pixel) & 0xFF00) << 12) | \
+ (((pixel) & 0x0FF0) << 8) | \
+ (((pixel) & 0x00FF) << 4) | \
+ (((pixel) & 0x000F) ) )
+
+/* RGBA to AARRGGBB, so Rxxx left 2, RGxx left 1, xGBx, xxBx right 1, A to the left */
+#define RGBA4444_TO_ARGB(pixel) ( (((pixel) & 0x000F) << 28) | \
+ (((pixel) & 0x000F) << 24) | \
+ (((pixel) & 0xF000) << 8) | \
+ (((pixel) & 0xFF00) << 4) | \
+ (((pixel) & 0x0FF0) ) | \
+ (((pixel) & 0x00F0) >> 4) )
+
+#define RGB16_TO_RGB332(pixel) ( (((pixel) & 0xE000) >> 8) | \
+ (((pixel) & 0x0700) >> 6) | \
+ (((pixel) & 0x0018) >> 3) )
+
+#define RGB16_TO_ARGB1555(pixel) ( 0x8000 | \
+ (((pixel) & 0xF800) >> 1) | \
+ (((pixel) & 0x07C0) >> 1) | \
+ (((pixel) & 0x001F)) )
+
+#define RGB16_TO_ARGB2554(pixel) ( 0xC000 | \
+ (((pixel) & 0xF800) >> 2) | \
+ (((pixel) & 0x07C0) >> 2) | \
+ (((pixel) & 0x001F) >> 1) )
+
+#define RGB16_TO_ARGB4444(pixel) ( 0xF000 | \
+ (((pixel) & 0xF000) >> 4) | \
+ (((pixel) & 0x0780) >> 3) | \
+ (((pixel) & 0x001E) >> 1) )
+
+#define RGB16_TO_RGBA4444(pixel) ( 0x000F | \
+ (((pixel) & 0xF000) ) | \
+ (((pixel) & 0x0780) << 1) | \
+ (((pixel) & 0x001E) << 3) )
+
+
+#define RGB16_TO_RGB32(pixel) ( (((pixel) & 0xF800) << 8) | \
+ (((pixel) & 0x07E0) << 5) | \
+ (((pixel) & 0x001F) << 3) )
+
+#define RGB16_TO_ARGB(pixel) ( 0xFF000000 | \
+ (((pixel) & 0xF800) << 8) | \
+ (((pixel) & 0x07E0) << 5) | \
+ (((pixel) & 0x001F) << 3) )
+
+#define RGB16_TO_RGB555(pixel) ( (((pixel) & 0xF800) >> 1) | \
+ (((pixel) & 0x07C0) >> 1) | \
+ (((pixel) & 0x001F)) )
+
+#define RGB16_TO_BGR555(pixel) ( (((pixel) & 0xF800) >> 12) | \
+ (((pixel) & 0x07C0) >> 1) | \
+ (((pixel) & 0x001F) << 10 ) )
+
+#define RGB16_TO_RGB444(pixel) ( (((pixel) & 0xF000) >> 4) | \
+ (((pixel) & 0x0780) >> 3) | \
+ (((pixel) & 0x001F) >> 1) )
+
+#define RGB18_TO_ARGB(pixel) ( 0xFF000000 | \
+ (((pixel) & 0xFC00) << 10) | \
+ (((pixel) & 0x3F00) << 4) | \
+ (((pixel) & 0x00FC) << 2) )
+
+#define RGB32_TO_RGB332(pixel) ( (((pixel) & 0xE00000) >> 16) | \
+ (((pixel) & 0x00E000) >> 11) | \
+ (((pixel) & 0x0000C0) >> 6) )
+
+#define RGB32_TO_ARGB1555(pixel) ( 0x8000 | \
+ (((pixel) & 0xF80000) >> 9) | \
+ (((pixel) & 0x00F800) >> 6) | \
+ (((pixel) & 0x0000F8) >> 3) )
+
+#define RGB32_TO_ARGB2554(pixel) ( 0xC000 | \
+ (((pixel) & 0xF80000) >> 10) | \
+ (((pixel) & 0x00F800) >> 7) | \
+ (((pixel) & 0x0000F0) >> 4) )
+
+#define RGB32_TO_ARGB4444(pixel) ( 0xF000 | \
+ (((pixel) & 0xF00000) >> 12) | \
+ (((pixel) & 0x00F000) >> 8) | \
+ (((pixel) & 0x0000F0) >> 4) )
+
+#define RGB32_TO_RGBA4444(pixel) ( 0x000F | \
+ (((pixel) & 0xF00000) >> 8) | \
+ (((pixel) & 0x00F000) >> 4) | \
+ (((pixel) & 0x0000F0) ) )
+
+#define RGB32_TO_RGB16(pixel) ( (((pixel) & 0xF80000) >> 8) | \
+ (((pixel) & 0x00FC00) >> 5) | \
+ (((pixel) & 0x0000F8) >> 3) )
+
+#define RGB32_TO_ARGB1555(pixel) ( 0x8000 | \
+ (((pixel) & 0xF80000) >> 9) | \
+ (((pixel) & 0x00F800) >> 6) | \
+ (((pixel) & 0x0000F8) >> 3) )
+
+#define RGB32_TO_ARGB(pixel) ( 0xFF000000 | (pixel) )
+
+
+#define RGB32_TO_RGB555(pixel) ( (((pixel) & 0xF80000) >> 9) | \
+ (((pixel) & 0x00F800) >> 6) | \
+ (((pixel) & 0x0000F8) >> 3) )
+
+#define RGB32_TO_BGR555(pixel) ( (((pixel) & 0xF80000) >> 19) | \
+ (((pixel) & 0x00F800) >> 6) | \
+ (((pixel) & 0x0000F8) << 7) )
+
+#define RGB32_TO_RGB444(pixel) ( (((pixel) & 0xF00000) >> 12) | \
+ (((pixel) & 0x00F000) >> 8) | \
+ (((pixel) & 0x0000F0) >> 4) )
+
+#define ARGB_TO_ARGB1555(pixel) ( (((pixel) & 0x80000000) >> 16) | \
+ (((pixel) & 0x00F80000) >> 9) | \
+ (((pixel) & 0x0000F800) >> 6) | \
+ (((pixel) & 0x000000F8) >> 3) )
+
+#define ARGB_TO_ARGB2554(pixel) ( (((pixel) & 0xC0000000) >> 16) | \
+ (((pixel) & 0x00F80000) >> 10) | \
+ (((pixel) & 0x0000F800) >> 7) | \
+ (((pixel) & 0x000000F0) >> 4) )
+
+#define ARGB_TO_ARGB4444(pixel) ( (((pixel) & 0xF0000000) >> 16) | \
+ (((pixel) & 0x00F00000) >> 12) | \
+ (((pixel) & 0x0000F000) >> 8) | \
+ (((pixel) & 0x000000F0) >> 4) )
+
+#define ARGB_TO_RGBA4444(pixel) ( (((pixel) & 0xF0000000) >> 28) | \
+ (((pixel) & 0x00F00000) >> 8) | \
+ (((pixel) & 0x0000F000) >> 4) | \
+ (((pixel) & 0x000000F0) ) )
+
+#define ARGB_TO_RGB444(pixel) ( (((pixel) & 0x00F00000) >> 12) | \
+ (((pixel) & 0x0000F000) >> 8) | \
+ (((pixel) & 0x000000F0) >> 4) )
+
+#define ARGB_TO_RGB555(pixel) ( (((pixel) & 0x00F80000) >> 9) | \
+ (((pixel) & 0x0000F800) >> 6) | \
+ (((pixel) & 0x000000F8) >> 3) )
+
+#define ARGB_TO_BGR555(pixel) ( (((pixel) & 0x00F80000) >> 19) | \
+ (((pixel) & 0x0000F800) >> 6) | \
+ (((pixel) & 0x000000F8) << 7) )
+
+/* RGB <-> YCbCr conversion */
+
+#define YCBCR_TO_RGB( y, cb, cr, r, g, b ) \
+do { \
+ int _y = (y) - 16; \
+ int _cb = (cb) - 128; \
+ int _cr = (cr) - 128; \
+ \
+ int _r = (298 * _y + 409 * _cr + 128) >> 8; \
+ int _g = (298 * _y - 100 * _cb - 208 * _cr + 128) >> 8; \
+ int _b = (298 * _y + 516 * _cb + 128) >> 8; \
+ \
+ (r) = CLAMP( _r, 0, 255 ); \
+ (g) = CLAMP( _g, 0, 255 ); \
+ (b) = CLAMP( _b, 0, 255 ); \
+} while (0)
+
+#define RGB_TO_YCBCR( r, g, b, y, cb, cr ) \
+do { \
+ int _r = (r), _g = (g), _b = (b); \
+ \
+ (y) = ( 66 * _r + 129 * _g + 25 * _b + 16*256 + 128) >> 8; \
+ (cb) = ( - 38 * _r - 74 * _g + 112 * _b + 128*256 + 128) >> 8; \
+ (cr) = ( 112 * _r - 94 * _g - 18 * _b + 128*256 + 128) >> 8; \
+} while (0)
+
+
+DFBSurfacePixelFormat dfb_pixelformat_for_depth( int depth );
+
+
+void dfb_pixel_to_color ( DFBSurfacePixelFormat format,
+ unsigned long pixel,
+ DFBColor *ret_color );
+
+unsigned long dfb_pixel_from_color( DFBSurfacePixelFormat format,
+ const DFBColor *color );
+
+
+static inline u32
+dfb_color_to_pixel( DFBSurfacePixelFormat format,
+ u8 r, u8 g, u8 b )
+{
+ const DFBColor color = { 0, r, g, b };
+
+ return dfb_pixel_from_color( format, &color );
+}
+
+static inline u32
+dfb_color_to_argb( const DFBColor *color )
+{
+ return (color->a << 24) | (color->r << 16) | (color->g << 8) | color->b;
+}
+
+static inline u32
+dfb_color_to_aycbcr( const DFBColor *color )
+{
+ u32 y = ( 66 * color->r + 129 * color->g + 25 * color->b + 16*256 + 128) >> 8;
+ u32 cb = ( - 38 * color->r - 74 * color->g + 112 * color->b + 128*256 + 128) >> 8;
+ u32 cr = ( 112 * color->r - 94 * color->g - 18 * color->b + 128*256 + 128) >> 8;
+
+ return (color->a << 24) | (y << 16) | (cb << 8) | cr;
+}
+
+static inline void
+dfb_argb_to_rgb332( const u32 *src, u8 *dst, int len )
+{
+ int i;
+
+ for (i=0; i<len; i++) {
+ register u32 argb = src[i];
+
+ dst[i] = RGB32_TO_RGB332( argb );
+ }
+}
+
+static inline void
+dfb_argb_to_argb1555( const u32 *src, u16 *dst, int len )
+{
+ int i;
+
+ for (i=0; i<len; i++) {
+ register u32 argb = src[i];
+
+ dst[i] = ARGB_TO_ARGB1555( argb );
+ }
+}
+
+static inline void
+dfb_argb_to_argb2554( const u32 *src, u16 *dst, int len )
+{
+ int i;
+
+ for (i=0; i<len; i++) {
+ register u32 argb = src[i];
+
+ dst[i] = ARGB_TO_ARGB2554( argb );
+ }
+}
+
+static inline void
+dfb_argb_to_argb4444( const u32 *src, u16 *dst, int len )
+{
+ int i;
+
+ for (i=0; i<len; i++) {
+ register u32 argb = src[i];
+
+ dst[i] = ARGB_TO_ARGB4444( argb );
+ }
+}
+
+static inline void
+dfb_argb_to_rgba4444( const u32 *src, u16 *dst, int len )
+{
+ int i;
+
+ for (i=0; i<len; i++) {
+ register u32 rgba = src[i];
+
+ dst[i] = ARGB_TO_RGBA4444( rgba );
+ }
+}
+
+static inline void
+dfb_argb_to_rgb16( const u32 *src, u16 *dst, int len )
+{
+ int i;
+
+ for (i=0; i<len; i++) {
+ register u32 argb = src[i];
+
+ dst[i] = RGB32_TO_RGB16( argb );
+ }
+}
+
+static inline void
+dfb_argb_to_a8( const u32 *src, u8 *dst, int len )
+{
+ int i;
+
+ for (i=0; i<len; i++)
+ dst[i] = src[i] >> 24;
+}
+
+void dfb_convert_to_rgb16( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u16 *dst,
+ int dpitch,
+ int width,
+ int height );
+
+void dfb_convert_to_rgb555( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u16 *dst,
+ int dpitch,
+ int width,
+ int height );
+
+void dfb_convert_to_argb( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height );
+
+void dfb_convert_to_rgb32( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height );
+
+void dfb_convert_to_rgb24( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u8 *dst,
+ int dpitch,
+ int width,
+ int height );
+
+void dfb_convert_to_a8( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u8 *dst,
+ int dpitch,
+ int width,
+ int height );
+
+void dfb_convert_to_a4( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u8 *dst,
+ int dpitch,
+ int width,
+ int height );
+
+void dfb_convert_to_yuy2( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height );
+
+void dfb_convert_to_uyvy( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height );
+
+#endif
diff --git a/Source/DirectFB/src/gfx/generic/Makefile.am b/Source/DirectFB/src/gfx/generic/Makefile.am
new file mode 100755
index 0000000..6d80484
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/Makefile.am
@@ -0,0 +1,62 @@
+## Makefile.am for DirectFB/src/gfx/generic
+
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+AM_CFLAGS = $(DFB_CFLAGS_OMIT_FRAME_POINTER)
+
+EXTRA_DIST = \
+ yuvtbl-gen.c
+
+internalincludedir = $(INTERNALINCLUDEDIR)/gfx/generic
+
+internalinclude_HEADERS = \
+ generic.h
+
+noinst_LTLIBRARIES = libdirectfb_generic.la
+
+if SOFTWARE_RENDERING
+GENERIC_C = generic.c
+else
+GENERIC_C = generic_dummy.c
+endif
+
+libdirectfb_generic_la_SOURCES = \
+ duffs_device.h \
+ $(GENERIC_C) \
+ generic.h \
+ generic_mmx.h \
+ generic_64.h \
+ stretch_hvx_N.h \
+ stretch_hvx_16.h \
+ stretch_hvx_32.h \
+ stretch_hvx_8.h \
+ stretch_hvx_88.h \
+ stretch_up_down_16.h \
+ stretch_up_down_32.h \
+ stretch_up_down_32_indexed.h \
+ stretch_up_down_8.h \
+ stretch_up_down_88.h \
+ stretch_up_down_table.h \
+ template_acc_16.h \
+ template_acc_32.h \
+ template_colorkey_16.h \
+ template_colorkey_32.h \
+ yuvtbl.h
+
+generic.c: yuvtbl.h
+generic_dummy.c: yuvtbl.h
+
+yuvtbl-gen: yuvtbl-gen.c
+ $(CC) -O2 yuvtbl-gen.c -o yuvtbl-gen
+
+#yuvtbl.h: yuvtbl-gen
+# ./yuvtbl-gen > $(srcdir)/yuvtbl.h
+
+clean-local:
+ rm -f yuvtbl-gen
+
diff --git a/Source/DirectFB/src/gfx/generic/Makefile.in b/Source/DirectFB/src/gfx/generic/Makefile.in
new file mode 100755
index 0000000..94695ac
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/Makefile.in
@@ -0,0 +1,602 @@
+# 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 = src/gfx/generic
+DIST_COMMON = $(internalinclude_HEADERS) $(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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libdirectfb_generic_la_LIBADD =
+am__libdirectfb_generic_la_SOURCES_DIST = duffs_device.h \
+ generic_dummy.c generic.c generic.h generic_mmx.h generic_64.h \
+ stretch_hvx_N.h stretch_hvx_16.h stretch_hvx_32.h \
+ stretch_hvx_8.h stretch_hvx_88.h stretch_up_down_16.h \
+ stretch_up_down_32.h stretch_up_down_32_indexed.h \
+ stretch_up_down_8.h stretch_up_down_88.h \
+ stretch_up_down_table.h template_acc_16.h template_acc_32.h \
+ template_colorkey_16.h template_colorkey_32.h yuvtbl.h
+@SOFTWARE_RENDERING_FALSE@am__objects_1 = generic_dummy.lo
+@SOFTWARE_RENDERING_TRUE@am__objects_1 = generic.lo
+am_libdirectfb_generic_la_OBJECTS = $(am__objects_1)
+libdirectfb_generic_la_OBJECTS = $(am_libdirectfb_generic_la_OBJECTS)
+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 = $(libdirectfb_generic_la_SOURCES)
+DIST_SOURCES = $(am__libdirectfb_generic_la_SOURCES_DIST)
+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)$(internalincludedir)"
+internalincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(internalinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+AM_CFLAGS = $(DFB_CFLAGS_OMIT_FRAME_POINTER)
+EXTRA_DIST = \
+ yuvtbl-gen.c
+
+internalincludedir = $(INTERNALINCLUDEDIR)/gfx/generic
+internalinclude_HEADERS = \
+ generic.h
+
+noinst_LTLIBRARIES = libdirectfb_generic.la
+@SOFTWARE_RENDERING_FALSE@GENERIC_C = generic_dummy.c
+@SOFTWARE_RENDERING_TRUE@GENERIC_C = generic.c
+libdirectfb_generic_la_SOURCES = \
+ duffs_device.h \
+ $(GENERIC_C) \
+ generic.h \
+ generic_mmx.h \
+ generic_64.h \
+ stretch_hvx_N.h \
+ stretch_hvx_16.h \
+ stretch_hvx_32.h \
+ stretch_hvx_8.h \
+ stretch_hvx_88.h \
+ stretch_up_down_16.h \
+ stretch_up_down_32.h \
+ stretch_up_down_32_indexed.h \
+ stretch_up_down_8.h \
+ stretch_up_down_88.h \
+ stretch_up_down_table.h \
+ template_acc_16.h \
+ template_acc_32.h \
+ template_colorkey_16.h \
+ template_colorkey_32.h \
+ yuvtbl.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 src/gfx/generic/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/gfx/generic/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
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_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
+libdirectfb_generic.la: $(libdirectfb_generic_la_OBJECTS) $(libdirectfb_generic_la_DEPENDENCIES)
+ $(LINK) $(libdirectfb_generic_la_OBJECTS) $(libdirectfb_generic_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generic_dummy.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-internalincludeHEADERS: $(internalinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(internalincludedir)" || $(MKDIR_P) "$(DESTDIR)$(internalincludedir)"
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(internalincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ $(internalincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+uninstall-internalincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(internalincludedir)/$$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) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(internalincludedir)"; 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-libtool clean-local \
+ clean-noinstLTLIBRARIES 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-internalincludeHEADERS
+
+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-internalincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-local clean-noinstLTLIBRARIES 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-info \
+ install-info-am install-internalincludeHEADERS 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-internalincludeHEADERS
+
+
+generic.c: yuvtbl.h
+generic_dummy.c: yuvtbl.h
+
+yuvtbl-gen: yuvtbl-gen.c
+ $(CC) -O2 yuvtbl-gen.c -o yuvtbl-gen
+
+#yuvtbl.h: yuvtbl-gen
+# ./yuvtbl-gen > $(srcdir)/yuvtbl.h
+
+clean-local:
+ rm -f yuvtbl-gen
+# 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/src/gfx/generic/duffs_device.h b/Source/DirectFB/src/gfx/generic/duffs_device.h
new file mode 100755
index 0000000..4e31089
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/duffs_device.h
@@ -0,0 +1,89 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DUFFS_DEVICE_H__
+#define __DUFFS_DEVICE_H__
+
+#define DUFF_1() \
+ case 1:\
+ SET_PIXEL( D[0], S[0] );
+
+#define DUFF_2() \
+ case 3:\
+ SET_PIXEL( D[2], S[2] );\
+ case 2:\
+ SET_PIXEL( D[1], S[1] );\
+ DUFF_1()
+
+#define DUFF_3() \
+ case 7:\
+ SET_PIXEL( D[6], S[6] );\
+ case 6:\
+ SET_PIXEL( D[5], S[5] );\
+ case 5:\
+ SET_PIXEL( D[4], S[4] );\
+ case 4:\
+ SET_PIXEL( D[3], S[3] );\
+ DUFF_2()
+
+#define DUFF_4() \
+ case 15:\
+ SET_PIXEL( D[14], S[14] );\
+ case 14:\
+ SET_PIXEL( D[13], S[13] );\
+ case 13:\
+ SET_PIXEL( D[12], S[12] );\
+ case 12:\
+ SET_PIXEL( D[11], S[11] );\
+ case 11:\
+ SET_PIXEL( D[10], S[10] );\
+ case 10:\
+ SET_PIXEL( D[9], S[9] );\
+ case 9:\
+ SET_PIXEL( D[8], S[8] );\
+ case 8:\
+ SET_PIXEL( D[7], S[7] );\
+ DUFF_3()
+
+#define SET_PIXEL_DUFFS_DEVICE_N( D, S, w, n ) \
+do {\
+ while (w) {\
+ register int l = w & ((1 << n) - 1);\
+ switch (l) {\
+ default:\
+ l = (1 << n);\
+ SET_PIXEL( D[(1 << n)-1], S[(1 << n)-1] );\
+ DUFF_##n()\
+ }\
+ D += l;\
+ S += l;\
+ w -= l;\
+ }\
+} while(0)
+
+#endif
diff --git a/Source/DirectFB/src/gfx/generic/generic.c b/Source/DirectFB/src/gfx/generic/generic.c
new file mode 100755
index 0000000..9b7cdeb
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/generic.c
@@ -0,0 +1,9161 @@
+/*
+ (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 <dfb_types.h>
+
+#include <pthread.h>
+
+#include <directfb.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/gfxcard.h>
+#include <core/state.h>
+#include <core/palette.h>
+
+#include <misc/gfx_util.h>
+#include <misc/util.h>
+#include <misc/conf.h>
+
+#include <direct/clock.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+#include <gfx/util.h>
+
+#include "generic.h"
+#include "duffs_device.h"
+
+
+/* lookup tables for 2/3bit to 8bit color conversion */
+static const u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff};
+static const u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff};
+
+#define EXPAND_1to8(v) ((v) ? 0xff : 0x00)
+#define EXPAND_2to8(v) (lookup2to8[v])
+#define EXPAND_3to8(v) (lookup3to8[v])
+#define EXPAND_4to8(v) (((v) << 4) | ((v) ))
+#define EXPAND_5to8(v) (((v) << 3) | ((v) >> 2))
+#define EXPAND_6to8(v) (((v) << 2) | ((v) >> 4))
+#define EXPAND_7to8(v) (((v) << 1) | ((v) >> 6))
+
+
+static int use_mmx = 0;
+
+#ifdef USE_MMX
+static void gInit_MMX( void );
+#endif
+
+#if SIZEOF_LONG == 8
+static void gInit_64bit( void );
+#endif
+
+/* RGB16 */
+#define RGB_MASK 0xffff
+#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_16
+#define Bop_PFI_OP_Aop_PFI( op ) Bop_16_##op##_Aop
+#include "template_colorkey_16.h"
+
+/* ARGB1555 / RGB555 / BGR555 */
+#define RGB_MASK 0x7fff
+#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_15
+#define Bop_PFI_OP_Aop_PFI( op ) Bop_15_##op##_Aop
+#include "template_colorkey_16.h"
+
+/* ARGB2554 */
+#define RGB_MASK 0x3fff
+#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_14
+#define Bop_PFI_OP_Aop_PFI( op ) Bop_14_##op##_Aop
+#include "template_colorkey_16.h"
+
+/* ARGB4444 / RGB444*/
+#define RGB_MASK 0x0fff
+#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_12
+#define Bop_PFI_OP_Aop_PFI( op ) Bop_12_##op##_Aop
+#include "template_colorkey_16.h"
+
+/* RGBA4444 */
+#define RGB_MASK 0xfff0
+#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_12vv
+#define Bop_PFI_OP_Aop_PFI( op ) Bop_12vv_##op##_Aop
+#include "template_colorkey_16.h"
+
+/* ARGB/RGB32/AiRGB */
+#define RGB_MASK 0x00ffffff
+#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_32
+#define Bop_PFI_OP_Aop_PFI( op ) Bop_32_##op##_Aop
+#include "template_colorkey_32.h"
+
+/* RGB16 */
+#define EXPAND_Ato8( a ) 0xFF
+#define EXPAND_Rto8( r ) EXPAND_5to8( r )
+#define EXPAND_Gto8( g ) EXPAND_6to8( g )
+#define EXPAND_Bto8( b ) EXPAND_5to8( b )
+#define PIXEL_OUT( a, r, g, b ) PIXEL_RGB16( r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_rgb16_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_rgb16
+#define A_SHIFT 0
+#define R_SHIFT 11
+#define G_SHIFT 5
+#define B_SHIFT 0
+#define A_MASK 0
+#define R_MASK 0xf800
+#define G_MASK 0x07e0
+#define B_MASK 0x001f
+#include "template_acc_16.h"
+
+/* ARGB1555 */
+#define EXPAND_Ato8( a ) EXPAND_1to8( a )
+#define EXPAND_Rto8( r ) EXPAND_5to8( r )
+#define EXPAND_Gto8( g ) EXPAND_5to8( g )
+#define EXPAND_Bto8( b ) EXPAND_5to8( b )
+#define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB1555( a, r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_argb1555_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb1555
+#define A_SHIFT 15
+#define R_SHIFT 10
+#define G_SHIFT 5
+#define B_SHIFT 0
+#define A_MASK 0x8000
+#define R_MASK 0x7c00
+#define G_MASK 0x03e0
+#define B_MASK 0x001f
+#include "template_acc_16.h"
+
+/* RGB555 */
+#define EXPAND_Ato8( a ) 0xFF
+#define EXPAND_Rto8( r ) EXPAND_5to8( r )
+#define EXPAND_Gto8( g ) EXPAND_5to8( g )
+#define EXPAND_Bto8( b ) EXPAND_5to8( b )
+#define PIXEL_OUT( a, r, g, b ) PIXEL_RGB555( r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_xrgb1555_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_xrgb1555
+#define A_SHIFT 0
+#define R_SHIFT 10
+#define G_SHIFT 5
+#define B_SHIFT 0
+#define A_MASK 0
+#define R_MASK 0x7c00
+#define G_MASK 0x03e0
+#define B_MASK 0x001f
+#include "template_acc_16.h"
+
+/* BGR555 */
+#define EXPAND_Ato8( a ) 0xFF
+#define EXPAND_Rto8( r ) EXPAND_5to8( r )
+#define EXPAND_Gto8( g ) EXPAND_5to8( g )
+#define EXPAND_Bto8( b ) EXPAND_5to8( b )
+#define PIXEL_OUT( a, r, g, b ) PIXEL_BGR555( r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_xbgr1555_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_xbgr1555
+#define A_SHIFT 0
+#define B_SHIFT 10
+#define G_SHIFT 5
+#define R_SHIFT 0
+#define A_MASK 0
+#define B_MASK 0x7c00
+#define G_MASK 0x03e0
+#define R_MASK 0x001f
+#include "template_acc_16.h"
+
+/* ARGB2554 */
+#define EXPAND_Ato8( a ) EXPAND_2to8( a )
+#define EXPAND_Rto8( r ) EXPAND_5to8( r )
+#define EXPAND_Gto8( g ) EXPAND_5to8( g )
+#define EXPAND_Bto8( b ) EXPAND_4to8( b )
+#define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB2554( a, r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_argb2554_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb2554
+#define A_SHIFT 14
+#define R_SHIFT 9
+#define G_SHIFT 4
+#define B_SHIFT 0
+#define A_MASK 0xc000
+#define R_MASK 0x3e00
+#define G_MASK 0x01f0
+#define B_MASK 0x000f
+#include "template_acc_16.h"
+
+/* ARGB4444 */
+#define EXPAND_Ato8( a ) EXPAND_4to8( a )
+#define EXPAND_Rto8( r ) EXPAND_4to8( r )
+#define EXPAND_Gto8( g ) EXPAND_4to8( g )
+#define EXPAND_Bto8( b ) EXPAND_4to8( b )
+#define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB4444( a, r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_argb4444_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb4444
+#define A_SHIFT 12
+#define R_SHIFT 8
+#define G_SHIFT 4
+#define B_SHIFT 0
+#define A_MASK 0xf000
+#define R_MASK 0x0f00
+#define G_MASK 0x00f0
+#define B_MASK 0x000f
+#include "template_acc_16.h"
+
+/* ARGB4444 */
+#define EXPAND_Ato8( a ) EXPAND_4to8( a )
+#define EXPAND_Rto8( r ) EXPAND_4to8( r )
+#define EXPAND_Gto8( g ) EXPAND_4to8( g )
+#define EXPAND_Bto8( b ) EXPAND_4to8( b )
+#define PIXEL_OUT( a, r, g, b ) PIXEL_RGBA4444( a, r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_rgba4444_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_rgba4444
+#define A_SHIFT 0
+#define R_SHIFT 12
+#define G_SHIFT 8
+#define B_SHIFT 4
+#define A_MASK 0x000f
+#define R_MASK 0xf000
+#define G_MASK 0x0f00
+#define B_MASK 0x00f0
+#include "template_acc_16.h"
+
+/* RGB444 */
+#define EXPAND_Ato8( a ) 0xFF
+#define EXPAND_Rto8( r ) EXPAND_4to8( r )
+#define EXPAND_Gto8( g ) EXPAND_4to8( g )
+#define EXPAND_Bto8( b ) EXPAND_4to8( b )
+#define PIXEL_OUT( a, r, g, b ) PIXEL_RGB444( r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_xrgb4444_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_xrgb4444
+#define A_SHIFT 0
+#define R_SHIFT 8
+#define G_SHIFT 4
+#define B_SHIFT 0
+#define A_MASK 0
+#define R_MASK 0x0f00
+#define G_MASK 0x00f0
+#define B_MASK 0x000f
+#include "template_acc_16.h"
+
+/* ARGB */
+#define EXPAND_Ato8( a ) (a)
+#define EXPAND_Rto8( r ) (r)
+#define EXPAND_Gto8( g ) (g)
+#define EXPAND_Bto8( b ) (b)
+#define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB( a, r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_argb_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb
+#define A_SHIFT 24
+#define R_SHIFT 16
+#define G_SHIFT 8
+#define B_SHIFT 0
+#define A_MASK 0xff000000
+#define R_MASK 0x00ff0000
+#define G_MASK 0x0000ff00
+#define B_MASK 0x000000ff
+#include "template_acc_32.h"
+
+/* RGB32 */
+#define EXPAND_Ato8( a ) 0xFF
+#define EXPAND_Rto8( r ) (r)
+#define EXPAND_Gto8( g ) (g)
+#define EXPAND_Bto8( b ) (b)
+#define PIXEL_OUT( a, r, g, b ) PIXEL_RGB32( r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_rgb32_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_rgb32
+#define A_SHIFT 0
+#define R_SHIFT 16
+#define G_SHIFT 8
+#define B_SHIFT 0
+#define A_MASK 0
+#define R_MASK 0x00ff0000
+#define G_MASK 0x0000ff00
+#define B_MASK 0x000000ff
+#include "template_acc_32.h"
+
+/* AiRGB */
+#define EXPAND_Ato8( a ) ((a) ^ 0xff)
+#define EXPAND_Rto8( r ) (r)
+#define EXPAND_Gto8( g ) (g)
+#define EXPAND_Bto8( b ) (b)
+#define PIXEL_OUT( a, r, g, b ) PIXEL_AiRGB( a, r, g, b )
+#define Sop_PFI_OP_Dacc( op ) Sop_airgb_##op##_Dacc
+#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_airgb
+#define A_SHIFT 24
+#define R_SHIFT 16
+#define G_SHIFT 8
+#define B_SHIFT 0
+#define A_MASK 0xff000000
+#define R_MASK 0x00ff0000
+#define G_MASK 0x0000ff00
+#define B_MASK 0x000000ff
+#include "template_acc_32.h"
+
+/********************************* Cop_to_Aop_PFI *****************************/
+
+static void Cop_to_Aop_8( GenefxState *gfxs )
+{
+ memset( gfxs->Aop[0], gfxs->Cop, gfxs->length );
+}
+
+static void Cop_to_Aop_16( GenefxState *gfxs )
+{
+ int w;
+ int l = gfxs->length;
+ u32 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+
+ u32 DCop = ((Cop << 16) | Cop);
+
+ if (((long)D)&2) { /* align */
+ u16* tmp = (u16*) D;
+ --l;
+ *tmp = Cop;
+ D = (u32*)(tmp+1);
+ }
+
+ w = (l >> 1);
+ while (w) {
+ *D = DCop;
+ --w;
+ ++D;
+ }
+
+ if (l & 1) /* do the last ential pixel */
+ *((u16*)D) = (u16)Cop;
+}
+
+static void Cop_to_Aop_18( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+
+ while (w) {
+ D[0] = Cop;
+ D[1] = Cop >> 8;
+ D[2] = Cop >> 16;
+ D += 3;
+ --w;
+ }
+}
+
+static void Cop_to_Aop_24( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+
+ while (w) {
+ D[0] = gfxs->color.b;
+ D[1] = gfxs->color.g;
+ D[2] = gfxs->color.r;
+
+ D += 3;
+ --w;
+ }
+}
+
+static void Cop_to_Aop_32( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u32 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+
+ while (w--)
+ *D++ = Cop;
+}
+
+static void Cop_to_Aop_yuv422( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ u16 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+
+ if ((long)D & 2) {
+#ifdef WORDS_BIGENDIAN
+ *D++ = Cop & 0xffff;
+#else
+ *D++ = Cop >> 16;
+#endif
+ w--;
+ }
+
+ for (l = w>>1; l--;) {
+ *((u32*)D) = Cop;
+ D += 2;
+ }
+
+ if (w & 1) {
+#ifdef WORDS_BIGENDIAN
+ *D = Cop >> 16;
+#else
+ *D = Cop & 0xffff;
+#endif
+ }
+}
+
+static void Cop_to_Aop_i420( GenefxState *gfxs )
+{
+ memset( gfxs->Aop[0], gfxs->YCop, gfxs->length );
+ if (gfxs->AopY & 1) {
+ memset( gfxs->Aop[1], gfxs->CbCop, gfxs->length>>1 );
+ memset( gfxs->Aop[2], gfxs->CrCop, gfxs->length>>1 );
+ }
+}
+
+static void Cop_to_Aop_nv12( GenefxState *gfxs )
+{
+ memset( gfxs->Aop[0], gfxs->YCop, gfxs->length );
+
+ if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) {
+ u16 *D = gfxs->Aop[1];
+ int w = gfxs->length>>1;
+ u16 Cop = gfxs->CbCop | (gfxs->CrCop << 8);
+
+ while (w--)
+ *D++ = Cop;
+ }
+}
+
+static void Cop_to_Aop_nv21( GenefxState *gfxs )
+{
+ memset( gfxs->Aop[0], gfxs->YCop, gfxs->length );
+
+ if (gfxs->AopY & 1) {
+ u16 *D = gfxs->Aop[1];
+ int w = gfxs->length>>1;
+ u16 Cop = gfxs->CrCop | (gfxs->CbCop << 8);
+
+ while (w--)
+ *D++ = Cop;
+ }
+}
+
+static GenefxFunc Cop_to_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Cop_to_Aop_16, /* DSPF_ARGB1555 */
+ Cop_to_Aop_16, /* DSPF_RGB16 */
+ Cop_to_Aop_24, /* DSPF_RGB24 */
+ Cop_to_Aop_32, /* DSPF_RGB32 */
+ Cop_to_Aop_32, /* DSPF_ARGB */
+ Cop_to_Aop_8, /* DSPF_A8 */
+ Cop_to_Aop_yuv422, /* DSPF_YUY2 */
+ Cop_to_Aop_8, /* DSPF_RGB332 */
+ Cop_to_Aop_yuv422, /* DSPF_UYVY */
+ Cop_to_Aop_i420, /* DSPF_I420 */
+ Cop_to_Aop_i420, /* DSPF_YV12 */
+ Cop_to_Aop_8, /* DSPF_LUT8 */
+ Cop_to_Aop_8, /* DSPF_ALUT44 */
+ Cop_to_Aop_32, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ Cop_to_Aop_nv12, /* DSPF_NV12 */
+ Cop_to_Aop_nv12, /* DSPF_NV16 */
+ Cop_to_Aop_16, /* DSPF_ARGB2554 */
+ Cop_to_Aop_16, /* DSPF_ARGB4444 */
+ Cop_to_Aop_16, /* DSPF_RGBA4444 */
+ Cop_to_Aop_nv21, /* DSPF_NV21 */
+ Cop_to_Aop_32, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Cop_to_Aop_18, /* DSPF_ARGB1666 */
+ Cop_to_Aop_18, /* DSPF_ARGB6666 */
+ Cop_to_Aop_18, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Cop_to_Aop_16, /* DSPF_RGB444 */
+ Cop_to_Aop_16, /* DSPF_RGB555 */
+ Cop_to_Aop_16 /* DSPF_BGR555 */
+};
+
+/********************************* Cop_toK_Aop_PFI ****************************/
+
+static void Cop_toK_Aop_8( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+ u32 Dkey = gfxs->Dkey;
+
+ while (w--) {
+ if (Dkey == *D)
+ *D = Cop;
+
+ D++;
+ }
+}
+
+static void Cop_toK_Aop_18( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+ u32 Cop = gfxs->Cop;
+
+ while (w) {
+ if (Dkey == ((u32)(D[2]<<16 | D[1]<<8 | D[0]) & 0x3FFFF)) {
+ D[0] = Cop;
+ D[1] = Cop >> 8;
+ D[2] = Cop >> 16;
+ }
+ D += 3;
+ --w;
+ }
+
+}
+
+static void Cop_toK_Aop_24( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+ u8 Dkr = (gfxs->Dkey & 0xff0000) >> 16;
+ u8 Dkg = (gfxs->Dkey & 0x00ff00) >> 8;
+ u8 Dkb = (gfxs->Dkey & 0x0000ff);
+
+ while (w--) {
+ if (D[0] == Dkb && D[1] == Dkg && D[2] == Dkr) {
+ D[0] = gfxs->color.b;
+ D[1] = gfxs->color.g;
+ D[2] = gfxs->color.r;
+ }
+
+ D += 3;
+ }
+}
+
+static void Cop_toK_Aop_yuv422( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ u16 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+ u32 Dkey = gfxs->Dkey;
+
+ if ((long)D & 2) {
+#ifdef WORDS_BIGENDIAN
+ if (*D == (Dkey & 0xffff))
+ *D = Cop & 0xffff;
+#else
+ if (*D == (Dkey >> 16))
+ *D = Cop >> 16;
+#endif
+ D++;
+ w--;
+ }
+
+ for (l = w>>1; l--;) {
+ if (*((u32*)D) == Dkey)
+ *((u32*)D) = Cop;
+ D += 2;
+ }
+
+ if (w & 1) {
+#ifdef WORDS_BIGENDIAN
+ if (*D == (Dkey >> 16))
+ *D = Cop >> 16;
+#else
+ if (*D == (Dkey & 0xffff))
+ *D = Cop & 0xffff;
+#endif
+ }
+}
+
+static void Cop_toK_Aop_alut44( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+ u32 Dkey = gfxs->Dkey;
+
+ while (w--) {
+ if (Dkey == (*D & 0x0F))
+ *D = Cop;
+
+ D++;
+ }
+}
+
+static GenefxFunc Cop_toK_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Cop_toK_Aop_15, /* DSPF_ARGB1555 */
+ Cop_toK_Aop_16, /* DSPF_RGB16 */
+ Cop_toK_Aop_24, /* DSPF_RGB24 */
+ Cop_toK_Aop_32, /* DSPF_RGB32 */
+ Cop_toK_Aop_32, /* DSPF_ARGB */
+ Cop_toK_Aop_8, /* DSPF_A8 */
+ Cop_toK_Aop_yuv422, /* DSPF_YUY2 */
+ Cop_toK_Aop_8, /* DSPF_RGB332 */
+ Cop_toK_Aop_yuv422, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ Cop_toK_Aop_8, /* DSPF_LUT8 */
+ Cop_toK_Aop_alut44, /* DSPF_ALUT44 */
+ Cop_toK_Aop_32, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Cop_toK_Aop_14, /* DSPF_ARGB2554 */
+ Cop_toK_Aop_12, /* DSPF_ARGB4444 */
+ Cop_toK_Aop_12vv, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ Cop_toK_Aop_32, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Cop_toK_Aop_18, /* DSPF_ARGB1666 */
+ Cop_toK_Aop_18, /* DSPF_ARGB6666 */
+ Cop_toK_Aop_18, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Cop_toK_Aop_12, /* DSPF_RGB444 */
+ Cop_toK_Aop_15, /* DSPF_RGB555 */
+ Cop_toK_Aop_15 /* DSPF_BGR555 */
+};
+
+/********************************* Bop_PFI_to_Aop_PFI *************************/
+
+static void Bop_4_to_Aop( GenefxState *gfxs )
+{
+ direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length>>1 );
+}
+
+static void Bop_8_to_Aop( GenefxState *gfxs )
+{
+ direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length );
+}
+
+static void Bop_16_to_Aop( GenefxState *gfxs )
+{
+ direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length*2 );
+}
+
+static void Bop_24_to_Aop( GenefxState *gfxs )
+{
+ direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length*3 );
+}
+
+static void Bop_32_to_Aop( GenefxState *gfxs )
+{
+ direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length*4 );
+}
+
+static void Bop_i420_to_Aop( GenefxState *gfxs )
+{
+ direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length );
+ if (gfxs->AopY & 1) {
+ direct_memmove( gfxs->Aop[1], gfxs->Bop[1], gfxs->length>>1 );
+ direct_memmove( gfxs->Aop[2], gfxs->Bop[2], gfxs->length>>1 );
+ }
+}
+
+static void Bop_NV_to_Aop( GenefxState *gfxs )
+{
+ direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length );
+ if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1)
+ direct_memmove( gfxs->Aop[1], gfxs->Bop[1], gfxs->length&~1 );
+}
+
+static GenefxFunc Bop_PFI_to_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_16_to_Aop, /* DSPF_ARGB1555 */
+ Bop_16_to_Aop, /* DSPF_RGB16 */
+ Bop_24_to_Aop, /* DSPF_RGB24 */
+ Bop_32_to_Aop, /* DSPF_RGB32 */
+ Bop_32_to_Aop, /* DSPF_ARGB */
+ Bop_8_to_Aop, /* DSPF_A8 */
+ Bop_16_to_Aop, /* DSPF_YUY2 */
+ Bop_8_to_Aop, /* DSPF_RGB332 */
+ Bop_16_to_Aop, /* DSPF_UYVY */
+ Bop_i420_to_Aop, /* DSPF_I420 */
+ Bop_i420_to_Aop, /* DSPF_YV12 */
+ Bop_8_to_Aop, /* DSPF_LUT8 */
+ Bop_8_to_Aop, /* DSPF_ALUT44 */
+ Bop_32_to_Aop, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ Bop_NV_to_Aop, /* DSPF_NV12 */
+ Bop_NV_to_Aop, /* DSPF_NV16 */
+ Bop_16_to_Aop, /* DSPF_ARGB2554 */
+ Bop_16_to_Aop, /* DSPF_ARGB4444 */
+ Bop_16_to_Aop, /* DSPF_RGBA4444 */
+ Bop_NV_to_Aop, /* DSPF_NV21 */
+ Bop_32_to_Aop, /* DSPF_AYUV */
+ Bop_4_to_Aop, /* DSPF_A4 */
+ Bop_24_to_Aop, /* DSPF_ARGB1666 */
+ Bop_24_to_Aop, /* DSPF_ARGB6666 */
+ Bop_24_to_Aop, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Bop_16_to_Aop, /* DSPF_RGB444 */
+ Bop_16_to_Aop, /* DSPF_RGB555 */
+ Bop_16_to_Aop /* DSPF_BGR555 */
+};
+
+/********************************* Bop_PFI_toR_Aop_PFI *************************/
+
+static void Bop_4_toR_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ int Dstep = gfxs->Astep;
+ u8 * S = gfxs->Bop[0];
+ u8 * D = gfxs->Aop[0];
+ while(w--)
+ {
+ *D = *S;
+ D += Dstep;
+ S++;
+ }
+}
+
+static void Bop_8_toR_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int Dstep = gfxs->Astep;
+ u8 * S = gfxs->Bop[0];
+ u8 * D = gfxs->Aop[0];
+ while(w--)
+ {
+ *D = *S;
+ D += Dstep;
+ S++;
+ }
+}
+
+static void Bop_16_toR_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int Dstep = gfxs->Astep;
+ u16 * S = gfxs->Bop[0];
+ u16 * D = gfxs->Aop[0];
+ while(w--)
+ {
+ *D = *S;
+ D += Dstep;
+ S++;
+ }
+}
+
+static void Bop_24_toR_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int Dstep = gfxs->Astep;
+ u8 * S = gfxs->Bop[0];
+ u8 * D = gfxs->Aop[0];
+ while(w--)
+ {
+ D[0] = S[0];
+ D[1] = S[1];
+ D[2] = S[2];
+
+ D += Dstep * 3;
+ S += 3;
+ }
+}
+
+static void Bop_32_toR_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int Dstep = gfxs->Astep;
+ u32 * S = gfxs->Bop[0];
+ u32 * D = gfxs->Aop[0];
+ while(w--)
+ {
+ *D = *S;
+ D += Dstep;
+ S++;
+ }
+}
+
+static void Bop_i420_toR_Aop( GenefxState *gfxs )
+{
+ Bop_8_toR_Aop( gfxs );
+ if (gfxs->AopY & 1) {
+ int w = gfxs->length>>1;
+ int Dstep = gfxs->Astep>>1;
+ u8 * S1 = gfxs->Bop[1];
+ u8 * D1 = gfxs->Aop[1];
+ u8 * S2 = gfxs->Bop[2];
+ u8 * D2 = gfxs->Aop[2];
+ while(w--)
+ {
+ *D1 = *S1++;
+ *D2 = *S2++;
+ D1 += Dstep;
+ D2 += Dstep;
+ }
+ }
+}
+
+static void Bop_NV_toR_Aop( GenefxState *gfxs )
+{
+ Bop_8_toR_Aop( gfxs );
+ if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) {
+ int w = gfxs->length&~1;
+ int Dstep = gfxs->Astep;
+ u8 * S = gfxs->Bop[1];
+ u8 * D = gfxs->Aop[1];
+ while(w--)
+ {
+ *D = *S++;
+ D += Dstep;
+ }
+ }
+}
+
+static GenefxFunc Bop_PFI_toR_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_16_toR_Aop, /* DSPF_ARGB1555 */
+ Bop_16_toR_Aop, /* DSPF_RGB16 */
+ Bop_24_toR_Aop, /* DSPF_RGB24 */
+ Bop_32_toR_Aop, /* DSPF_RGB32 */
+ Bop_32_toR_Aop, /* DSPF_ARGB */
+ Bop_8_toR_Aop, /* DSPF_A8 */
+ Bop_16_toR_Aop, /* DSPF_YUY2 */
+ Bop_8_toR_Aop, /* DSPF_RGB332 */
+ Bop_16_toR_Aop, /* DSPF_UYVY */
+ Bop_i420_toR_Aop, /* DSPF_I420 */
+ Bop_i420_toR_Aop, /* DSPF_YV12 */
+ Bop_8_toR_Aop, /* DSPF_LUT8 */
+ Bop_8_toR_Aop, /* DSPF_ALUT44 */
+ Bop_32_toR_Aop, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ Bop_NV_toR_Aop, /* DSPF_NV12 */
+ Bop_NV_toR_Aop, /* DSPF_NV16 */
+ Bop_16_toR_Aop, /* DSPF_ARGB2554 */
+ Bop_16_toR_Aop, /* DSPF_ARGB4444 */
+ Bop_16_toR_Aop, /* DSPF_RGBA4444 */
+ Bop_NV_toR_Aop, /* DSPF_NV21 */
+ Bop_32_toR_Aop, /* DSPF_AYUV */
+ Bop_4_toR_Aop, /* DSPF_A4 */
+ Bop_24_toR_Aop, /* DSPF_ARGB1666 */
+ Bop_24_toR_Aop, /* DSPF_ARGB6666 */
+ Bop_24_toR_Aop, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Bop_16_toR_Aop, /* DSPF_RGB444 */
+ Bop_16_toR_Aop, /* DSPF_RGB555 */
+ Bop_16_toR_Aop /* DSPF_BGR555 */
+};
+
+/********************************* Bop_PFI_Kto_Aop_PFI ************************/
+
+static void Bop_rgb18_Kto_Aop( GenefxState *gfxs )
+{
+
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+ int Ostep = gfxs->Ostep;
+
+ if (Ostep < 0) {
+ D += (gfxs->length - 1) * 3;
+ S += (gfxs->length - 1) * 3;
+ }
+
+ while (w--) {
+ u8 s0 = S[0];
+ u8 s1 = S[1];
+ u8 s2 = S[2];
+
+ if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) {
+ D[0] = s0;
+ D[1] = s1;
+ D[2] = s2;
+ }
+
+ S += Ostep * 3;
+ D += Ostep * 3;
+ }
+}
+
+static void Bop_rgb24_Kto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+ int Ostep = gfxs->Ostep;
+
+ if (Ostep < 0) {
+ D += (gfxs->length - 1) * 3;
+ S += (gfxs->length - 1) * 3;
+ }
+
+ while (w--) {
+ u8 b = *S;
+ u8 g = *(S+1);
+ u8 r = *(S+2);
+
+ if (Skey != (u32)(r<<16 | g<<8 | b)) {
+ *D = b;
+ *(D+1) = g;
+ *(D+2) = r;
+ }
+
+ S += Ostep * 3;
+ D += Ostep * 3;
+ }
+}
+
+static void Bop_a8_Kto_Aop( GenefxState *gfxs )
+{
+ /* no color to key */
+ direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length );
+}
+
+static void Bop_yuv422_Kto_Aop( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ u16 *D = gfxs->Aop[0];
+ u16 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+ int Ostep = gfxs->Ostep;
+
+ if (Ostep < 0) {
+ D += gfxs->length - 1;
+ S += gfxs->length - 1;
+ }
+
+ if ((long)D & 2) {
+ u16 s = *S;
+#ifdef WORDS_BIGENDIAN
+ if (s != (Skey >> 16))
+ *D = s;
+#else
+ if (s != (Skey & 0xffff))
+ *D = s;
+#endif
+ S += Ostep;
+ D += Ostep;
+ w--;
+ }
+
+ if (Ostep < 0) {
+ S--;
+ D--;
+ }
+
+ for (l = w>>1; l--;) {
+ u32 s = *((u32*)S);
+
+ if (s != Skey)
+ *((u32*)D) = s;
+
+ S += Ostep << 1;
+ D += Ostep << 1;
+ }
+
+ if (w & 1) {
+ u16 s = *S;
+#ifdef WORDS_BIGENDIAN
+ if (s != (Skey & 0xffff))
+ *D = s;
+#else
+ if (s != (Skey >> 16))
+ *D = s;
+#endif
+ }
+}
+
+
+/* change the last value to adjust the size of the device (1-4) */
+#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \
+ SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 4 )
+
+#define SET_PIXEL( D, S ) \
+ do { \
+ register u32 s = S; \
+ \
+ if (s != Skey) \
+ D = s; \
+ } while (0)
+
+static void Bop_8_Kto_Aop( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+
+ if (gfxs->Ostep > 0) {
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+ }
+ else {
+ for (i=w-1; i>=0; i--)
+ if (S[i] != Skey)
+ D[i] = S[i];
+ }
+}
+
+#undef SET_PIXEL_DUFFS_DEVICE
+#undef SET_PIXEL
+
+static void Bop_alut44_Kto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+ int Ostep = gfxs->Ostep;
+
+ if (Ostep < 0) {
+ D += gfxs->length - 1;
+ S += gfxs->length - 1;
+ }
+
+ while (w--) {
+ u8 spixel = *S;
+
+ if ((spixel & 0x0F) != Skey)
+ *D = spixel;
+
+ S += Ostep;
+ D += Ostep;
+ }
+}
+
+static GenefxFunc Bop_PFI_Kto_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_15_Kto_Aop, /* DSPF_ARGB1555 */
+ Bop_16_Kto_Aop, /* DSPF_RGB16 */
+ Bop_rgb24_Kto_Aop, /* DSPF_RGB24 */
+ Bop_32_Kto_Aop, /* DSPF_RGB32 */
+ Bop_32_Kto_Aop, /* DSPF_ARGB */
+ Bop_a8_Kto_Aop, /* DSPF_A8 */
+ Bop_yuv422_Kto_Aop, /* DSPF_YUY2 */
+ Bop_8_Kto_Aop, /* DSPF_RGB332 */
+ Bop_yuv422_Kto_Aop, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ Bop_8_Kto_Aop, /* DSPF_LUT8 */
+ Bop_alut44_Kto_Aop, /* DSPF_ALUT44 */
+ Bop_32_Kto_Aop, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Bop_14_Kto_Aop, /* DSPF_ARGB2554 */
+ Bop_12_Kto_Aop, /* DSPF_ARGB4444 */
+ Bop_12vv_Kto_Aop, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ Bop_32_Kto_Aop, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Bop_rgb18_Kto_Aop, /* DSPF_ARGB1666 */
+ Bop_rgb18_Kto_Aop, /* DSPF_ARGB6666 */
+ Bop_rgb18_Kto_Aop, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Bop_12_Kto_Aop, /* DSPF_RGB444 */
+ Bop_15_Kto_Aop, /* DSPF_RGB555 */
+ Bop_15_Kto_Aop /* DSPF_BGR555 */
+};
+
+/********************************* Bop_PFI_toK_Aop_PFI ************************/
+
+static void Bop_rgb18_toK_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ u32 Dkey = gfxs->Dkey;
+
+ while (w--) {
+ if (Dkey == ((u32)(D[2]<<16 | D[1]<<8 | D[0]) & 0x3FFFF)) {
+ D[0] = S[0];
+ D[1] = S[1];
+ D[2] = S[2];
+ }
+ S += 3;
+ D += 3;
+ }
+}
+
+static void Bop_rgb24_toK_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ u8 Dkr = (gfxs->Dkey & 0xff0000) >> 16;
+ u8 Dkg = (gfxs->Dkey & 0x00ff00) >> 8;
+ u8 Dkb = (gfxs->Dkey & 0x0000ff);
+
+ while (w--) {
+ if (D[0] == Dkb && D[1] == Dkg && D[2] == Dkr) {
+ D[0] = S[0];
+ D[1] = S[1];
+ D[2] = S[2];
+ }
+ S += 3;
+ D += 3;
+ }
+}
+
+static void Bop_yuv422_toK_Aop( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ u16 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+ int Ostep = gfxs->Ostep;
+
+ if (Ostep < 0) {
+ D += gfxs->length - 1;
+ S += gfxs->length - 1;
+ }
+
+ if ((long)D & 2) {
+#ifdef WORDS_BIGENDIAN
+ if (*D == (Dkey & 0xffff))
+ *D = *S;
+#else
+ if (*D == (Dkey >> 16))
+ *D = *S;
+#endif
+ D += Ostep;
+ S += Ostep;
+ w--;
+ }
+
+ if (Ostep < 0) {
+ S--;
+ D--;
+ }
+
+ for (l = w>>1; l--;) {
+ if (*D == Dkey)
+ *D = *S;
+ D += Ostep << 1;
+ S += Ostep << 1;
+ }
+
+ if (w & 1) {
+#ifdef WORDS_BIGENDIAN
+ if (*D == (Dkey >> 16))
+ *D = *S;
+#else
+ if (*D == (Dkey & 0xffff))
+ *D = *S;
+#endif
+ }
+}
+
+static void Bop_rgb332_toK_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ u8 Dkey = gfxs->Dkey;
+
+ while (w--) {
+ if (*D == Dkey) {
+ *D = *S;
+ }
+ D++;
+ S++;
+ }
+}
+
+static GenefxFunc Bop_PFI_toK_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_15_toK_Aop, /* DSPF_ARGB1555 */
+ Bop_16_toK_Aop, /* DSPF_RGB16 */
+ Bop_rgb24_toK_Aop, /* DSPF_RGB24 */
+ Bop_32_toK_Aop, /* DSPF_RGB32 */
+ Bop_32_toK_Aop, /* DSPF_ARGB */
+ NULL, /* DSPF_A8 */
+ Bop_yuv422_toK_Aop, /* DSPF_YUY2 */
+ Bop_rgb332_toK_Aop, /* DSPF_RGB332 */
+ Bop_yuv422_toK_Aop, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ NULL, /* DSPF_LUT8 */
+ NULL, /* DSPF_ALUT44 */
+ Bop_32_toK_Aop, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Bop_14_toK_Aop, /* DSPF_ARGB2554 */
+ Bop_12_toK_Aop, /* DSPF_ARGB4444 */
+ Bop_12vv_toK_Aop, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ Bop_32_toK_Aop, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Bop_rgb18_toK_Aop, /* DSPF_ARGB1666 */
+ Bop_rgb18_toK_Aop, /* DSPF_ARGB6666 */
+ Bop_rgb18_toK_Aop, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Bop_12_toK_Aop, /* DSPF_RGB444 */
+ Bop_15_toK_Aop, /* DSPF_RGB555 */
+ Bop_15_toK_Aop /* DSPF_BGR555 */
+};
+
+/********************************* Bop_PFI_KtoK_Aop_PFI ***********************/
+
+static GenefxFunc Bop_PFI_KtoK_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_15_KtoK_Aop, /* DSPF_ARGB1555 */
+ Bop_16_KtoK_Aop, /* DSPF_RGB16 */
+ NULL, /* DSPF_RGB24 */
+ Bop_32_KtoK_Aop, /* DSPF_RGB32 */
+ Bop_32_KtoK_Aop, /* DSPF_ARGB */
+ NULL, /* DSPF_A8 */
+ NULL, /* DSPF_YUY2 */
+ NULL, /* DSPF_RGB332 */
+ NULL, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ NULL, /* DSPF_LUT8 */
+ NULL, /* DSPF_ALUT44 */
+ Bop_32_KtoK_Aop, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Bop_14_KtoK_Aop, /* DSPF_ARGB2554 */
+ Bop_12_KtoK_Aop, /* DSPF_ARGB4444 */
+ Bop_12vv_KtoK_Aop, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ NULL, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ NULL, /* DSPF_ARGB1666 */
+ NULL, /* DSPF_ARGB6666 */
+ NULL, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Bop_12_KtoK_Aop, /* DSPF_RGB444 */
+ Bop_15_KtoK_Aop, /* DSPF_RGB555 */
+ Bop_15_KtoK_Aop /* DSPF_BGR555 */
+};
+
+/********************************* Bop_PFI_Sto_Aop_PFI ************************/
+
+static void Bop_16_Sto_Aop( GenefxState *gfxs )
+{
+ int w2;
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u32 *D = gfxs->Aop[0];
+ u16 *S = gfxs->Bop[0];
+ int SperD = gfxs->SperD;
+ int SperD2 = SperD << 1;
+
+ if (((long)D)&2) {
+ *(u16*)D = *S;
+ i += SperD;
+ w--;
+ D = gfxs->Aop[0] + 2;
+ }
+
+ w2 = (w >> 1);
+ while (w2--) {
+#ifdef WORDS_BIGENDIAN
+ *D++ = S[i>>16] << 16 | S[(i+SperD)>>16];
+#else
+ *D++ = (S[(i+SperD)>>16] << 16) | S[i>>16];
+#endif
+ i += SperD2;
+ }
+ if (w&1) {
+ *(u16*)D = S[i>>16];
+ }
+}
+
+static void Bop_24_Sto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ *D++ = S[pixelstart+0];
+ *D++ = S[pixelstart+1];
+ *D++ = S[pixelstart+2];
+
+ i += SperD;
+ }
+}
+
+static void Bop_32_Sto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u32 *D = gfxs->Aop[0];
+ u32 *S = gfxs->Bop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ *D++ = S[i>>16];
+
+ i += SperD;
+ }
+}
+
+static void Bop_yuy2_Sto_Aop( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u16 *D = gfxs->Aop[0];
+ u16 *S = gfxs->Bop[0];
+ int SperD = gfxs->SperD;
+
+ if ((long)D & 2) {
+ *D++ = *S;
+ i = SperD;
+ w--;
+ }
+
+ for (l = w>>1; l--;) {
+ register u32 d;
+
+ d = ((u32*)S)[i>>17] & 0xff00ff00;
+#ifdef WORDS_BIGENDIAN
+ d |= (S[i>>16] & 0x00ff) << 16;
+ d |= (S[(i+SperD)>>16] & 0x00ff);
+#else
+ d |= (S[i>>16] & 0x00ff);
+ d |= (S[(i+SperD)>>16] & 0x00ff) << 16;
+#endif
+ *((u32*)D) = d;
+ D += 2;
+
+ i += SperD << 1;
+ }
+
+ if (w & 1)
+ *D = S[i>>16];
+}
+
+static void Bop_8_Sto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ *D++ = S[i>>16];
+
+ i += SperD;
+ }
+}
+
+static void Bop_uyvy_Sto_Aop( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u16 *D = gfxs->Aop[0];
+ u16 *S = gfxs->Bop[0];
+ int SperD = gfxs->SperD;
+
+ if ((long)D & 2) {
+ *D++ = *S;
+ i = SperD;
+ w--;
+ }
+
+ for (l = w>>1; l--;) {
+ register u32 d;
+
+ d = ((u32*)S)[i>>17] & 0x00ff00ff;
+#ifdef WORDS_BIGENDIAN
+ d |= (S[i>>16] & 0xff00) << 16;
+ d |= (S[(i+SperD)>>16] & 0xff00);
+#else
+ d |= (S[i>>16] & 0xff00);
+ d |= (S[(i+SperD)>>16] & 0xff00) << 16;
+#endif
+ *((u32*)D) = d;
+ D += 2;
+
+ i += SperD << 1;
+ }
+
+ if (w & 1)
+ *D = S[i>>16];
+}
+
+static void Bop_i420_Sto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u8 *Dy = gfxs->Aop[0];
+ u8 *Sy = gfxs->Bop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ *Dy++ = Sy[i>>16];
+
+ i += SperD;
+ }
+
+ if (gfxs->AopY & 1) {
+ u8 *Du = gfxs->Aop[1];
+ u8 *Dv = gfxs->Aop[2];
+ u8 *Su = gfxs->Bop[1];
+ u8 *Sv = gfxs->Bop[2];
+
+ for (w = gfxs->length>>1, i = 0; w--;) {
+ *Du++ = Su[i>>16];
+
+ i += SperD;
+ }
+
+ for (w = gfxs->length>>1, i = 0; w--;) {
+ *Dv++ = Sv[i>>16];
+
+ i += SperD;
+ }
+ }
+}
+
+static void Bop_NV_Sto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u8 *Dy = gfxs->Aop[0];
+ u8 *Sy = gfxs->Bop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ *Dy++ = Sy[i>>16];
+
+ i += SperD;
+ }
+
+ if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) {
+ u16 *Duv = gfxs->Aop[1];
+ u16 *Suv = gfxs->Bop[1];
+
+ for (w = gfxs->length>>1, i = 0; w--;) {
+ *Duv++ = Suv[i>>16];
+
+ i += SperD;
+ }
+ }
+}
+
+static GenefxFunc Bop_PFI_Sto_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_16_Sto_Aop, /* DSPF_ARGB1555 */
+ Bop_16_Sto_Aop, /* DSPF_RGB16 */
+ Bop_24_Sto_Aop, /* DSPF_RGB24 */
+ Bop_32_Sto_Aop, /* DSPF_RGB32 */
+ Bop_32_Sto_Aop, /* DSPF_ARGB */
+ Bop_8_Sto_Aop, /* DSPF_A8 */
+ Bop_yuy2_Sto_Aop, /* DSPF_YUY2 */
+ Bop_8_Sto_Aop, /* DSPF_RGB332 */
+ Bop_uyvy_Sto_Aop, /* DSPF_UYVY */
+ Bop_i420_Sto_Aop, /* DSPF_I420 */
+ Bop_i420_Sto_Aop, /* DSPF_YV12 */
+ Bop_8_Sto_Aop, /* DSPF_LUT8 */
+ Bop_8_Sto_Aop, /* DSPF_ALUT44 */
+ Bop_32_Sto_Aop, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ Bop_NV_Sto_Aop, /* DSPF_NV12 */
+ Bop_NV_Sto_Aop, /* DSPF_NV16 */
+ Bop_16_Sto_Aop, /* DSPF_ARGB2554 */
+ Bop_16_Sto_Aop, /* DSPF_ARGB4444 */
+ Bop_16_Sto_Aop, /* DSPF_RGBA4444 */
+ Bop_NV_Sto_Aop, /* DSPF_NV21 */
+ Bop_32_Sto_Aop, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Bop_24_Sto_Aop, /* DSPF_ARGB1666 */
+ Bop_24_Sto_Aop, /* DSPF_ARGB6666 */
+ Bop_24_Sto_Aop, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Bop_16_Sto_Aop, /* DSPF_ARGB4444 */
+ Bop_16_Sto_Aop, /* DSPF_ARGB1555 */
+ Bop_16_Sto_Aop /* DSPF_ARGB1555 */
+};
+
+/********************************* Bop_PFI_SKto_Aop_PFI ***********************/
+
+static void Bop_rgb18_SKto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ u8 s0 = S[pixelstart+0];
+ u8 s1 = S[pixelstart+1];
+ u8 s2 = S[pixelstart+2];
+
+ if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) {
+ D[0] = s0;
+ D[1] = s1;
+ D[2] = s2;
+ }
+ i += SperD;
+ D += 3;
+ }
+}
+
+static void Bop_rgb24_SKto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ u8 b = S[pixelstart+0];
+ u8 g = S[pixelstart+1];
+ u8 r = S[pixelstart+2];
+
+ if (Skey != (u32)(r<<16 | g<<8 | b)) {
+ *D = b;
+ *(D+1) = g;
+ *(D+2) = r;
+ }
+
+ D += 3;
+ i += SperD;
+ }
+}
+
+static void Bop_a8_SKto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ int SperD = gfxs->SperD;
+
+ /* no color to key */
+ while (w--) {
+ *D++ = S[i>>16];
+
+ i += SperD;
+ }
+}
+
+static void Bop_yuy2_SKto_Aop( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u16 *D = gfxs->Aop[0];
+ u16 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+#ifdef WORDS_BIGENDIAN
+ u16 Skey0 = gfxs->Skey >> 16;
+ u16 Skey1 = gfxs->Skey & 0xffff;
+#else
+ u16 Skey0 = gfxs->Skey & 0xffff;
+ u16 Skey1 = gfxs->Skey >> 16;
+#endif
+ int SperD = gfxs->SperD;
+
+ if ((long)D & 2) {
+ u16 s = *S;
+ if (s != Skey0)
+ *D = s;
+ D++;
+ i = SperD;
+ w--;
+ }
+
+ for (l = w>>1; l--;) {
+ register u32 s;
+
+ s = ((u32*)S)[i>>17] & 0xff00ff00;
+#ifdef WORDS_BIGENDIAN
+ s |= (S[i>>16] & 0x00ff) << 16;
+ s |= (S[(i+SperD)>>16] & 0x00ff);
+#else
+ s |= (S[i>>16] & 0x00ff);
+ s |= (S[(i+SperD)>>16] & 0x00ff) << 16;
+#endif
+ if (s != Skey)
+ *((u32*)D) = s;
+ D += 2;
+
+ i += SperD << 1;
+ }
+
+ if (w & 1) {
+ u16 s = S[i>>16];
+ if (i & 0x20000) {
+ if (s != Skey1)
+ *D = s;
+ } else {
+ if (s != Skey0)
+ *D = s;
+ }
+ }
+}
+
+static void Bop_8_SKto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ u8 s = S[i>>16];
+
+ if (s != Skey)
+ *D = s;
+
+ D++;
+ i += SperD;
+ }
+}
+
+static void Bop_uyvy_SKto_Aop( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u16 *D = gfxs->Aop[0];
+ u16 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+#ifdef WORDS_BIGENDIAN
+ u16 Skey0 = gfxs->Skey >> 16;
+ u16 Skey1 = gfxs->Skey & 0xffff;
+#else
+ u16 Skey0 = gfxs->Skey & 0xffff;
+ u16 Skey1 = gfxs->Skey >> 16;
+#endif
+ int SperD = gfxs->SperD;
+
+ if ((long)D & 2) {
+ u16 s = *S;
+ if (s != Skey0)
+ *D = s;
+ D++;
+ i = SperD;
+ w--;
+ }
+
+ for (l = w>>1; l--;) {
+ register u32 s;
+
+ s = ((u32*)S)[i>>17] & 0x00ff00ff;
+#ifdef WORDS_BIGENDIAN
+ s |= (S[i>>16] & 0xff00) << 16;
+ s |= (S[(i+SperD)>>16] & 0xff00);
+#else
+ s |= (S[i>>16] & 0xff00);
+ s |= (S[(i+SperD)>>16] & 0xff00) << 16;
+#endif
+ if (s != Skey)
+ *((u32*)D) = s;
+ D += 2;
+
+ i += SperD << 1;
+ }
+
+ if (w & 1) {
+ u16 s = S[i>>16];
+ if (i & 0x20000) {
+ if (s != Skey1)
+ *D = s;
+ } else {
+ if (s != Skey0)
+ *D = s;
+ }
+ }
+}
+
+static void Bop_alut44_SKto_Aop( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ u8 *D = gfxs->Aop[0];
+ u8 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ u8 s = S[i>>16];
+
+ if ((s & 0x0f) != Skey)
+ *D = s;
+
+ D++;
+ i += SperD;
+ }
+}
+
+static GenefxFunc Bop_PFI_SKto_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_15_SKto_Aop, /* DSPF_ARGB1555 */
+ Bop_16_SKto_Aop, /* DSPF_RGB16 */
+ Bop_rgb24_SKto_Aop, /* DSPF_RGB24 */
+ Bop_32_SKto_Aop, /* DSPF_RGB32 */
+ Bop_32_SKto_Aop, /* DSPF_ARGB */
+ Bop_a8_SKto_Aop, /* DSPF_A8 */
+ Bop_yuy2_SKto_Aop, /* DSPF_YUY2 */
+ Bop_8_SKto_Aop, /* DSPF_RGB332 */
+ Bop_uyvy_SKto_Aop, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ Bop_8_SKto_Aop, /* DSPF_LUT8 */
+ Bop_alut44_SKto_Aop, /* DSPF_ALUT44 */
+ Bop_32_SKto_Aop, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Bop_14_SKto_Aop, /* DSPF_ARGB2554 */
+ Bop_12_SKto_Aop, /* DSPF_ARGB4444 */
+ Bop_12vv_SKto_Aop, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ Bop_32_SKto_Aop, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Bop_rgb18_SKto_Aop, /* DSPF_ARGB1666 */
+ Bop_rgb18_SKto_Aop, /* DSPF_ARGB6666 */
+ Bop_rgb18_SKto_Aop, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Bop_12_SKto_Aop, /* DSPF_RGB444 */
+ Bop_15_SKto_Aop, /* DSPF_RGB555 */
+ Bop_15_SKto_Aop /* DSPF_BGR555 */
+};
+
+/********************************* Bop_PFI_StoK_Aop_PFI ***********************/
+
+static GenefxFunc Bop_PFI_StoK_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_15_StoK_Aop, /* DSPF_ARGB1555 */
+ Bop_16_StoK_Aop, /* DSPF_RGB16 */
+ NULL, /* DSPF_RGB24 */
+ Bop_32_StoK_Aop, /* DSPF_RGB32 */
+ Bop_32_StoK_Aop, /* DSPF_ARGB */
+ NULL, /* DSPF_A8 */
+ NULL, /* DSPF_YUY2 */
+ NULL, /* DSPF_RGB332 */
+ NULL, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ NULL, /* DSPF_LUT8 */
+ NULL, /* DSPF_ALUT44 */
+ Bop_32_StoK_Aop, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Bop_14_StoK_Aop, /* DSPF_ARGB2554 */
+ Bop_12_StoK_Aop, /* DSPF_ARGB4444 */
+ Bop_12vv_StoK_Aop, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ NULL, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ NULL, /* DSPF_ARGB1666 */
+ NULL, /* DSPF_ARGB6666 */
+ NULL, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Bop_12_StoK_Aop, /* DSPF_RGB444 */
+ Bop_15_StoK_Aop, /* DSPF_RGB555 */
+ Bop_15_StoK_Aop /* DSPF_BGR555 */
+};
+
+/********************************* Bop_PFI_SKtoK_Aop_PFI **********************/
+
+static GenefxFunc Bop_PFI_SKtoK_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_15_SKtoK_Aop, /* DSPF_ARGB1555 */
+ Bop_16_SKtoK_Aop, /* DSPF_RGB16 */
+ NULL, /* DSPF_RGB24 */
+ Bop_32_SKtoK_Aop, /* DSPF_RGB32 */
+ Bop_32_SKtoK_Aop, /* DSPF_ARGB */
+ NULL, /* DSPF_A8 */
+ NULL, /* DSPF_YUY2 */
+ NULL, /* DSPF_RGB332 */
+ NULL, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ NULL, /* DSPF_LUT8 */
+ NULL, /* DSPF_ALUT44 */
+ Bop_32_SKtoK_Aop, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Bop_14_SKtoK_Aop, /* DSPF_ARGB2554 */
+ Bop_12_SKtoK_Aop, /* DSPF_ARGB4444 */
+ Bop_12vv_SKtoK_Aop, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ NULL, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ NULL, /* DSPF_ARGB1666 */
+ NULL, /* DSPF_ARGB6666 */
+ NULL, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Bop_12_SKtoK_Aop, /* DSPF_RGB444 */
+ Bop_15_SKtoK_Aop, /* DSPF_RGB555 */
+ Bop_15_SKtoK_Aop /* DSPF_BGR555 */
+};
+
+/********************************* Sop_PFI_Sto_Dacc ***************************/
+
+static void Sop_argb6666_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ u8 b = S[pixelstart+0] & 0x3F;
+ u8 g = ((S[pixelstart+0] & 0xC0) >> 6) | ((S[pixelstart+1] & 0x0F) << 2);
+ u8 r = ((S[pixelstart+1] & 0xF0) >> 4) | ((S[pixelstart+2] & 0x03) << 4);
+ u8 a = (S[pixelstart+2] & 0xFC) >> 2;
+
+ D->RGB.a = EXPAND_6to8( a );
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+ i += SperD;
+ D++;
+ }
+}
+
+static void Sop_argb1666_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ u8 b = S[pixelstart+0] & 0x3F;
+ u8 g = ((S[pixelstart+0] & 0xC0) >> 6) | ((S[pixelstart+1] & 0x0F) << 2);
+ u8 r = ((S[pixelstart+1] & 0xF0) >> 4) | ((S[pixelstart+2] & 0x03) << 4);
+ u8 a = (S[pixelstart+2] & 0x04) >> 2;
+
+ D->RGB.a = EXPAND_1to8( a );
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+ i += SperD;
+ D++;
+ }
+}
+
+static void Sop_rgb18_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ u8 b = S[pixelstart+0] & 0x3F;
+ u8 g = ((S[pixelstart+0] & 0xC0) >> 6) | ((S[pixelstart+1] & 0x0F) << 2);
+ u8 r = ((S[pixelstart+1] & 0xF0) >> 4) | ((S[pixelstart+2] & 0x03) << 4);
+
+ D->RGB.a = 0xFF;
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+ i += SperD;
+ D++;
+ }
+}
+
+static void Sop_rgb24_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ D->RGB.a = 0xFF;
+ D->RGB.r = S[pixelstart+2];
+ D->RGB.g = S[pixelstart+1];
+ D->RGB.b = S[pixelstart+0];
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_a8_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u8 s = S[i>>16];
+
+ D->RGB.a = s;
+ D->RGB.r = 0xFF;
+ D->RGB.g = 0xFF;
+ D->RGB.b = 0xFF;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_yuy2_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u32 s = S[i>>17];
+
+ D[0].YUV.a = D[1].YUV.a = 0xFF;
+#ifdef WORDS_BIGENDIAN
+ D[0].YUV.u = D[1].YUV.u = (s & 0xFF000000) >> 24;
+ D[0].YUV.v = D[1].YUV.v = (s & 0x0000FF00) >> 8;
+#else
+ D[0].YUV.u = D[1].YUV.u = (s & 0x0000FF00) >> 8;
+ D[0].YUV.v = D[1].YUV.v = (s & 0xFF000000) >> 24;
+#endif
+ D[0].YUV.y = ((u16*)S)[i>>16] & 0x00FF;
+ D[1].YUV.y = ((u16*)S)[(i+SperD)>>16] & 0x00FF;
+
+ D += 2;
+ i += SperD << 1;
+ }
+
+ if (gfxs->length & 1) {
+ u16 s = ((u16*)S)[i>>17];
+
+ D->YUV.a = 0xFF;
+ D->YUV.y = s & 0xFF;
+ D->YUV.u = s >> 8;
+ D->YUV.v = 0x00;
+ }
+}
+
+static void Sop_rgb332_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u8 s = S[i>>16];
+
+ D->RGB.a = 0xFF;
+ D->RGB.r = EXPAND_3to8(s >> 5);
+ D->RGB.g = EXPAND_3to8((s & 0x1C) >> 2);
+ D->RGB.b = EXPAND_2to8(s & 0x03);
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_uyvy_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u32 s = S[i>>17];
+
+ D[0].YUV.a = D[1].YUV.a = 0xFF;
+#ifdef WORDS_BIGENDIAN
+ D[0].YUV.u = D[1].YUV.u = (s & 0x00FF0000) >> 16;
+ D[0].YUV.v = D[1].YUV.v = (s & 0x000000FF);
+#else
+ D[0].YUV.u = D[1].YUV.u = (s & 0x000000FF);
+ D[0].YUV.v = D[1].YUV.v = (s & 0x00FF0000) >> 16;
+#endif
+ D[0].YUV.y = (((u16*)S)[i>>16] & 0xFF00) >> 8;
+ D[1].YUV.y = (((u16*)S)[(i+SperD)>>16] & 0xFF00) >> 8;
+
+ D += 2;
+ i += SperD << 1;
+ }
+
+ if (gfxs->length & 1) {
+ u16 s = ((u16*)S)[i>>16];
+
+ D->YUV.a = 0xFF;
+ D->YUV.y = s >> 8;
+ D->YUV.u = s & 0xFF;
+ D->YUV.v = 0x00;
+ }
+}
+
+static void Sop_lut8_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ DFBColor *entries = gfxs->Slut->entries;
+
+ while (w--) {
+ u8 s = S[i>>16];
+
+ D->RGB.a = entries[s].a;
+ D->RGB.r = entries[s].r;
+ D->RGB.g = entries[s].g;
+ D->RGB.b = entries[s].b;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_alut44_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ DFBColor *entries = gfxs->Slut->entries;
+
+ while (w--) {
+ u8 s = S[i>>16];
+
+ D->RGB.a = s & 0xF0;
+ s &= 0x0F;
+ D->RGB.r = entries[s].r;
+ D->RGB.g = entries[s].g;
+ D->RGB.b = entries[s].b;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_i420_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *Sy = gfxs->Sop[0];
+ u8 *Su = gfxs->Sop[1];
+ u8 *Sv = gfxs->Sop[2];
+
+ while (w--) {
+ D->YUV.a = 0xFF;
+ D->YUV.y = Sy[i>>16];
+ D->YUV.u = Su[i>>17];
+ D->YUV.v = Sv[i>>17];
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_nv12_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *Sy = gfxs->Sop[0];
+ u16 *Suv = gfxs->Sop[1];
+
+ while (w--) {
+ D->YUV.a = 0xFF;
+ D->YUV.y = Sy[i>>16];
+ D->YUV.u = Suv[i>>17] & 0xFF;
+ D->YUV.v = Suv[i>>17] >> 8;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_nv21_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *Sy = gfxs->Sop[0];
+ u16 *Svu = gfxs->Sop[1];
+
+ while (w--) {
+ D->YUV.a = 0xFF;
+ D->YUV.y = Sy[i>>16];
+ D->YUV.u = Svu[i>>17] >> 8;
+ D->YUV.v = Svu[i>>17] & 0xFF;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_ayuv_Sto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u32 s = S[i>>16];
+
+ D->YUV.a = (s >> 24);
+ D->YUV.y = (s >> 16) & 0xff;
+ D->YUV.u = (s >> 8) & 0xff;
+ D->YUV.v = (s ) & 0xff;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static GenefxFunc Sop_PFI_Sto_Dacc[DFB_NUM_PIXELFORMATS] = {
+ Sop_argb1555_Sto_Dacc, /* DSPF_ARGB1555 */
+ Sop_rgb16_Sto_Dacc, /* DSPF_RGB16 */
+ Sop_rgb24_Sto_Dacc, /* DSPF_RGB24 */
+ Sop_rgb32_Sto_Dacc, /* DSPF_RGB32 */
+ Sop_argb_Sto_Dacc, /* DSPF_ARGB */
+ Sop_a8_Sto_Dacc, /* DSPF_A8 */
+ Sop_yuy2_Sto_Dacc, /* DSPF_YUY2 */
+ Sop_rgb332_Sto_Dacc, /* DSPF_RGB332 */
+ Sop_uyvy_Sto_Dacc, /* DSPF_UYVY */
+ Sop_i420_Sto_Dacc, /* DSPF_I420 */
+ Sop_i420_Sto_Dacc, /* DSPF_YV12 */
+ Sop_lut8_Sto_Dacc, /* DSPF_LUT8 */
+ Sop_alut44_Sto_Dacc, /* DSPF_ALUT44 */
+ Sop_airgb_Sto_Dacc, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ Sop_nv12_Sto_Dacc, /* DSPF_NV12 */
+ Sop_nv12_Sto_Dacc, /* DSPF_NV16 */
+ Sop_argb2554_Sto_Dacc, /* DSPF_ARGB2554 */
+ Sop_argb4444_Sto_Dacc, /* DSPF_ARGB4444 */
+ Sop_rgba4444_Sto_Dacc, /* DSPF_RGBA4444 */
+ Sop_nv21_Sto_Dacc, /* DSPF_NV21 */
+ Sop_ayuv_Sto_Dacc, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Sop_argb1666_Sto_Dacc, /* DSPF_ARGB1666 */
+ Sop_argb6666_Sto_Dacc, /* DSPF_ARGB6666 */
+ Sop_rgb18_Sto_Dacc, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Sop_xrgb4444_Sto_Dacc, /* DSPF_RGB444 */
+ Sop_xrgb1555_Sto_Dacc, /* DSPF_RGB555 */
+ Sop_xbgr1555_Sto_Dacc /* DSPF_BGR555 */
+};
+
+/********************************* Sop_PFI_SKto_Dacc **************************/
+
+static void Sop_argb6666_SKto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u32 Skey = gfxs->Skey;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ u8 s0 = S[pixelstart+0];
+ u8 s1 = S[pixelstart+1];
+ u8 s2 = S[pixelstart+2];
+
+ if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) {
+ u8 b = s0 & 0x3F;
+ u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2);
+ u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4);
+ u8 a = (s2 & 0xFC) >> 2;
+
+ D->RGB.a = EXPAND_6to8( a );
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+ }
+ else
+ D->RGB.a = 0xFF00;
+
+ i += SperD;
+ D++;
+ }
+}
+
+static void Sop_argb1666_SKto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ u8 s0 = S[pixelstart+0];
+ u8 s1 = S[pixelstart+1];
+ u8 s2 = S[pixelstart+2];
+
+ if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) {
+ u8 b = s0 & 0x3F;
+ u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2);
+ u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4);
+ u8 a = (s2 & 0x04) >> 2;
+
+ D->RGB.a = EXPAND_1to8( a );
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+ }
+ else
+ D->RGB.a = 0xFF00;
+ i += SperD;
+ D++;
+ }
+}
+
+static void Sop_rgb18_SKto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u32 Skey = gfxs->Skey;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ u8 s0 = S[pixelstart+0];
+ u8 s1 = S[pixelstart+1];
+ u8 s2 = S[pixelstart+2];
+
+ if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) {
+ u8 b = s0 & 0x3F;
+ u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2);
+ u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4);
+
+ D->RGB.a = 0xFF;
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+ }
+ else
+ D->RGB.a = 0xFF00;
+
+ i += SperD;
+ D++;
+ }
+}
+
+static void Sop_rgb24_SKto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ while (w--) {
+ int pixelstart = (i>>16)*3;
+
+ u8 b = S[pixelstart+0];
+ u8 g = S[pixelstart+1];
+ u8 r = S[pixelstart+2];
+
+ if (Skey != (u32)(r<<16 | g<<8 | b)) {
+ D->RGB.a = 0xFF;
+ D->RGB.r = r;
+ D->RGB.g = g;
+ D->RGB.b = b;
+ }
+ else
+ D->RGB.a = 0xFF00;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_a8_SKto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ /* no color to key */
+ while (w--) {
+ u8 s = S[i>>16];
+
+ D->RGB.a = s;
+ D->RGB.r = 0xFF;
+ D->RGB.g = 0xFF;
+ D->RGB.b = 0xFF;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_lut8_SKto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ DFBColor *entries = gfxs->Slut->entries;
+
+ while (w--) {
+ u8 s = S[i>>16];
+
+ if (s != Skey) {
+ D->RGB.a = entries[s].a;
+ D->RGB.r = entries[s].r;
+ D->RGB.g = entries[s].g;
+ D->RGB.b = entries[s].b;
+ }
+ else
+ D->RGB.a = 0xF000;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_alut44_SKto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ DFBColor *entries = gfxs->Slut->entries;
+
+ while (w--) {
+ u8 s = S[i>>16];
+
+ if ((s & 0x0F) != Skey) {
+ D->RGB.a = ((s & 0xF0) >> 4) | (s & 0xF0);
+ s &= 0x0F;
+ D->RGB.r = entries[s].r;
+ D->RGB.g = entries[s].g;
+ D->RGB.b = entries[s].b;
+ }
+ else
+ D->RGB.a = 0xF000;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_yuy2_SKto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u32 Ky = (gfxs->Skey & 0x000000FF);
+#ifdef WORDS_BIGENDIAN
+ u32 Kcb = (gfxs->Skey & 0xFF000000) >> 24;
+ u32 Kcr = (gfxs->Skey & 0x0000FF00) >> 8;
+#else
+ u32 Kcb = (gfxs->Skey & 0x0000FF00) >> 8;
+ u32 Kcr = (gfxs->Skey & 0xFF000000) >> 24;
+#endif
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u32 s = S[i>>17];
+ u32 y0, cb, y1, cr;
+
+#ifdef WORDS_BIGENDIAN
+ cb = (s & 0xFF000000) >> 24;
+ cr = (s & 0x0000FF00) >> 8;
+#else
+ cb = (s & 0x0000FF00) >> 8;
+ cr = (s & 0xFF000000) >> 24;
+#endif
+ y0 = ((u16*)S)[i>>16] & 0x00FF;
+ y1 = ((u16*)S)[(i+SperD)>>16] & 0x00FF;
+
+ if (y0 != Ky || cb != Kcb || cr != Kcr) {
+ D[0].YUV.a = 0xFF;
+ D[0].YUV.y = y0;
+ D[0].YUV.u = cb;
+ D[0].YUV.v = cr;
+ }
+ else
+ D[0].YUV.a = 0xF000;
+
+ if (y0 != Ky || cb != Kcb || cr != Kcr) {
+ D[1].YUV.a = 0xFF;
+ D[1].YUV.y = y1;
+ D[1].YUV.u = cb;
+ D[1].YUV.v = cr;
+ }
+ else
+ D[1].YUV.a = 0xF000;
+
+ D += 2;
+ i += SperD << 1;
+ }
+
+ if (gfxs->length & 1) {
+ u16 s = ((u16*)S)[i>>16];
+
+ if (s != (Ky | (Kcb << 8))) {
+ D->YUV.a = 0xFF;
+ D->YUV.y = s & 0xFF;
+ D->YUV.u = s >> 8;
+ D->YUV.v = 0x00;
+ }
+ else
+ D->YUV.a = 0xF000;
+ }
+}
+
+static void Sop_rgb332_SKto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u8 Skey = gfxs->Skey;
+
+ while (w--) {
+ u8 s = S[i>>16];
+
+ if (s != Skey) {
+ D->RGB.a = 0xFF;
+ D->RGB.r = EXPAND_3to8(s >> 5);
+ D->RGB.g = EXPAND_3to8((s & 0x1C) >> 2);
+ D->RGB.b = EXPAND_2to8(s & 0x03);
+ }
+ else
+ D->RGB.a = 0xF000;
+
+ i += SperD;
+
+ D++;
+ }
+}
+
+static void Sop_uyvy_SKto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u32 Ky = (gfxs->Skey & 0x0000FF00) >> 8;
+#ifdef WORDS_BIGENDIAN
+ u32 Kcb = (gfxs->Skey & 0x00FF0000) >> 16;
+ u32 Kcr = (gfxs->Skey & 0x000000FF);
+#else
+ u32 Kcb = (gfxs->Skey & 0x000000FF);
+ u32 Kcr = (gfxs->Skey & 0x00FF0000) >> 16;
+#endif
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u32 s = S[i>>17];
+ u32 cb, y0, cr, y1;
+
+#ifdef WORDS_BIGENDIAN
+ cb = (s & 0x00FF0000) >> 16;
+ cr = (s & 0x000000FF);
+#else
+ cb = (s & 0x000000FF);
+ cr = (s & 0x00FF0000) >> 16;
+#endif
+ y0 = (((u16*)S)[i>>16] & 0xFF00) >> 8;
+ y1 = (((u16*)S)[(i+SperD)>>16] & 0xFF00) >> 8;
+
+ if (y0 != Ky || cb != Kcb || cr != Kcr) {
+ D[0].YUV.a = 0xFF;
+ D[0].YUV.y = y0;
+ D[0].YUV.u = cb;
+ D[0].YUV.v = cr;
+ }
+ else
+ D[0].YUV.a = 0xF000;
+
+ if (y0 != Ky || cb != Kcb || cr != Kcr) {
+ D[1].YUV.a = 0xFF;
+ D[1].YUV.y = y1;
+ D[1].YUV.u = cb;
+ D[1].YUV.v = cr;
+ }
+ else
+ D[1].YUV.a = 0xF000;
+
+ D += 2;
+ i += SperD << 1;
+ }
+
+ if (gfxs->length & 1) {
+ u16 s = ((u16*)S)[i>>16];
+
+ if (s != (Kcb | (Ky << 8))) {
+ D->YUV.a = 0xFF;
+ D->YUV.y = s >> 8;
+ D->YUV.u = s & 0xFF;
+ D->YUV.v = 0x00;
+ }
+ else
+ D->YUV.a = 0xF000;
+ }
+}
+
+static GenefxFunc Sop_PFI_SKto_Dacc[DFB_NUM_PIXELFORMATS] = {
+ Sop_argb1555_SKto_Dacc, /* DSPF_ARGB1555 */
+ Sop_rgb16_SKto_Dacc, /* DSPF_RGB16 */
+ Sop_rgb24_SKto_Dacc, /* DSPF_RGB24 */
+ Sop_rgb32_SKto_Dacc, /* DSPF_RGB32 */
+ Sop_argb_SKto_Dacc, /* DSPF_ARGB */
+ Sop_a8_SKto_Dacc, /* DSPF_A8 */
+ Sop_yuy2_SKto_Dacc, /* DSPF_YUY2 */
+ Sop_rgb332_SKto_Dacc, /* DSPF_RGB332 */
+ Sop_uyvy_SKto_Dacc, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ Sop_lut8_SKto_Dacc, /* DSPF_LUT8 */
+ Sop_alut44_SKto_Dacc, /* DSPF_ALUT44 */
+ Sop_airgb_SKto_Dacc, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Sop_argb2554_SKto_Dacc, /* DSPF_ARGB2554 */
+ Sop_argb4444_SKto_Dacc, /* DSPF_ARGB4444 */
+ Sop_rgba4444_SKto_Dacc, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ NULL, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Sop_argb1666_SKto_Dacc, /* DSPF_ARGB1666 */
+ Sop_argb6666_SKto_Dacc, /* DSPF_ARGB6666 */
+ Sop_rgb18_SKto_Dacc, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Sop_xrgb4444_SKto_Dacc, /* DSPF_RGB444 */
+ Sop_xrgb1555_SKto_Dacc, /* DSPF_RGB555 */
+ Sop_xbgr1555_SKto_Dacc /* DSPF_BGR555 */
+};
+
+/********************************* Sop_PFI_to_Dacc ****************************/
+
+static void Sop_argb6666_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u8 b = S[0] & 0x3F;
+ u8 g = ((S[0] & 0xC0) >> 6) | ((S[1] & 0x0F) << 2);
+ u8 r = ((S[1] & 0xF0) >> 4) | ((S[2] & 0x03) << 4);
+ u8 a = (S[2] & 0xFC) >> 2;
+
+ D->RGB.a = EXPAND_6to8( a );
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+
+ S +=3;
+ D++;
+ }
+}
+
+static void Sop_argb1666_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u8 b = S[0] & 0x3F;
+ u8 g = ((S[0] & 0xC0) >> 6) | ((S[1] & 0x0F) << 2);
+ u8 r = ((S[1] & 0xF0) >> 4) | ((S[2] & 0x03) << 4);
+ u8 a = (S[2] & 0x04) >> 2;
+
+ D->RGB.a = EXPAND_1to8( a );
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+
+ S +=3;
+ D++;
+ }
+}
+
+static void Sop_rgb18_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u8 b = S[0] & 0x3F;
+ u8 g = ((S[0] & 0xC0) >> 6) | ((S[1] & 0x0F) << 2);
+ u8 r = ((S[1] & 0xF0) >> 4) | ((S[2] & 0x03) << 4);
+
+ D->RGB.a = 0xFF;
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+
+ S +=3;
+ D++;
+ }
+}
+
+static void Sop_rgb24_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ D->RGB.a = 0xFF;
+ D->RGB.b = *S++;
+ D->RGB.g = *S++;
+ D->RGB.r = *S++;
+
+ D++;
+ }
+}
+
+static void Sop_a8_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ D->RGB.a = *S++;
+ D->RGB.r = 0xFF;
+ D->RGB.g = 0xFF;
+ D->RGB.b = 0xFF;
+
+ D++;
+ }
+}
+
+static void Sop_a4_to_Dacc( GenefxState *gfxs )
+{
+ int i, n;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ for (i=0, n=0; i<gfxs->length; i+=2, n++) {
+ register int left = S[n] & 0xF0;
+ register int right = S[n] & 0x0F;
+
+ D[i].RGB.a = left | (left >> 4);
+ D[i].RGB.r = 0xFF;
+ D[i].RGB.g = 0xFF;
+ D[i].RGB.b = 0xFF;
+
+ D[i+1].RGB.a = right | (right << 4);
+ D[i+1].RGB.r = 0xFF;
+ D[i+1].RGB.g = 0xFF;
+ D[i+1].RGB.b = 0xFF;
+ }
+}
+
+static void Sop_yuy2_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u32 s = *S++;
+
+ D[0].YUV.a = D[1].YUV.a = 0xFF;
+#ifdef WORDS_BIGENDIAN
+ D[0].YUV.y = (s & 0x00FF0000) >> 16;
+ D[1].YUV.y = (s & 0x000000FF);
+ D[0].YUV.u = D[1].YUV.u = (s & 0xFF000000) >> 24;
+ D[0].YUV.v = D[1].YUV.v = (s & 0x0000FF00) >> 8;
+#else
+ D[0].YUV.y = (s & 0x000000FF);
+ D[1].YUV.y = (s & 0x00FF0000) >> 16;
+ D[0].YUV.u = D[1].YUV.u = (s & 0x0000FF00) >> 8;
+ D[0].YUV.v = D[1].YUV.v = (s & 0xFF000000) >> 24;
+#endif
+
+ D += 2;
+ }
+
+ if (gfxs->length & 1) {
+ u16 s = *((u16*)S);
+
+ D->YUV.a = 0xFF;
+ D->YUV.y = s & 0xFF;
+ D->YUV.u = s >> 8;
+ D->YUV.v = 0x00;
+ }
+}
+
+static void Sop_rgb332_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u8 s = *S++;
+
+ D->RGB.a = 0xFF;
+ D->RGB.r = EXPAND_3to8(s >> 5);
+ D->RGB.g = EXPAND_3to8((s & 0x1C) >> 2);
+ D->RGB.b = EXPAND_2to8(s & 0x03);
+
+ D++;
+ }
+}
+
+static void Sop_uyvy_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u32 s = *S++;
+
+ D[0].YUV.a = D[1].YUV.a = 0xFF;
+#ifdef WORDS_BIGENDIAN
+ D[0].YUV.y = (s & 0xFF000000) >> 24;
+ D[1].YUV.y = (s & 0x0000FF00) >> 8;
+ D[0].YUV.u = D[1].YUV.u = (s & 0x00FF0000) >> 16;
+ D[0].YUV.v = D[1].YUV.v = (s & 0x000000FF);
+#else
+ D[0].YUV.y = (s & 0x0000FF00) >> 8;
+ D[1].YUV.y = (s & 0xFF000000) >> 24;
+ D[0].YUV.u = D[1].YUV.u = (s & 0x000000FF);
+ D[0].YUV.v = D[1].YUV.v = (s & 0x00FF0000) >> 16;
+#endif
+
+ D += 2;
+ }
+
+ if (gfxs->length & 1) {
+ u16 s = *((u16*)S);
+
+ D->YUV.a = 0xFF;
+ D->YUV.y = s >> 8;
+ D->YUV.u = s & 0xFF;
+ D->YUV.v = 0x00;
+ }
+}
+
+static void Sop_lut8_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ DFBColor *entries = gfxs->Slut->entries;
+
+ while (w--) {
+ u8 s = *S++;
+
+ D->RGB.a = entries[s].a;
+ D->RGB.r = entries[s].r;
+ D->RGB.g = entries[s].g;
+ D->RGB.b = entries[s].b;
+
+ D++;
+ }
+}
+
+static void Sop_alut44_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ DFBColor *entries = gfxs->Slut->entries;
+
+ while (w--) {
+ u8 s = *S++;
+
+ D->RGB.a = s & 0xF0;
+ s &= 0x0F;
+ D->RGB.r = entries[s].r;
+ D->RGB.g = entries[s].g;
+ D->RGB.b = entries[s].b;
+
+ D++;
+ }
+}
+
+static void Sop_i420_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *Sy = gfxs->Sop[0];
+ u8 *Su = gfxs->Sop[1];
+ u8 *Sv = gfxs->Sop[2];
+
+ while (w--) {
+ D[1].YUV.a = D[0].YUV.a = 0xFF;
+ D[0].YUV.y = Sy[0];
+ D[1].YUV.y = Sy[1];
+ D[1].YUV.u = D[0].YUV.u = Su[0];
+ D[1].YUV.v = D[0].YUV.v = Sv[0];
+
+ Sy += 2;
+ Su++;
+ Sv++;
+
+ D += 2;
+ }
+}
+
+static void Sop_nv12_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *Sy = gfxs->Sop[0];
+ u16 *Suv = gfxs->Sop[1];
+
+ while (w--) {
+ D[1].YUV.a = D[0].YUV.a = 0xFF;
+ D[0].YUV.y = Sy[0];
+ D[1].YUV.y = Sy[1];
+ D[1].YUV.u = D[0].YUV.u = Suv[0] & 0xFF;
+ D[1].YUV.v = D[0].YUV.v = Suv[0] >> 8;
+
+ Sy += 2;
+ Suv++;
+
+ D += 2;
+ }
+}
+
+static void Sop_nv21_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *Sy = gfxs->Sop[0];
+ u16 *Svu = gfxs->Sop[1];
+
+ while (w--) {
+ D[1].YUV.a = D[0].YUV.a = 0xFF;
+ D[0].YUV.y = Sy[0];
+ D[1].YUV.y = Sy[1];
+ D[1].YUV.u = D[0].YUV.u = Svu[0] >> 8;
+ D[1].YUV.v = D[0].YUV.v = Svu[0] & 0xFF;
+
+ Sy += 2;
+ Svu++;
+
+ D += 2;
+ }
+}
+
+static void Sop_ayuv_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 *S = gfxs->Sop[0];
+
+ while (w--) {
+ u32 s = *S++;
+
+ D->YUV.a = (s >> 24);
+ D->YUV.y = (s >> 16) & 0xff;
+ D->YUV.u = (s >> 8) & 0xff;
+ D->YUV.v = (s ) & 0xff;
+
+ D++;
+ }
+}
+
+static GenefxFunc Sop_PFI_to_Dacc[DFB_NUM_PIXELFORMATS] = {
+ Sop_argb1555_to_Dacc, /* DSPF_ARGB1555 */
+ Sop_rgb16_to_Dacc, /* DSPF_RGB16 */
+ Sop_rgb24_to_Dacc, /* DSPF_RGB24 */
+ Sop_rgb32_to_Dacc, /* DSPF_RGB32 */
+ Sop_argb_to_Dacc, /* DSPF_ARGB */
+ Sop_a8_to_Dacc, /* DSPF_A8 */
+ Sop_yuy2_to_Dacc, /* DSPF_YUY2 */
+ Sop_rgb332_to_Dacc, /* DSPF_RGB332 */
+ Sop_uyvy_to_Dacc, /* DSPF_UYVY */
+ Sop_i420_to_Dacc, /* DSPF_I420 */
+ Sop_i420_to_Dacc, /* DSPF_YV12 */
+ Sop_lut8_to_Dacc, /* DSPF_LUT8 */
+ Sop_alut44_to_Dacc, /* DSPF_ALUT44 */
+ Sop_airgb_to_Dacc, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ Sop_nv12_to_Dacc, /* DSPF_NV12 */
+ Sop_nv12_to_Dacc, /* DSPF_NV16 */
+ Sop_argb2554_to_Dacc, /* DSPF_ARGB2554 */
+ Sop_argb4444_to_Dacc, /* DSPF_ARGB4444 */
+ Sop_rgba4444_to_Dacc, /* DSPF_RGBA4444 */
+ Sop_nv21_to_Dacc, /* DSPF_NV21 */
+ Sop_ayuv_to_Dacc, /* DSPF_AYUV */
+ Sop_a4_to_Dacc, /* DSPF_A4 */
+ Sop_argb1666_to_Dacc, /* DSPF_ARGB1666 */
+ Sop_argb6666_to_Dacc, /* DSPF_ARGB6666 */
+ Sop_rgb18_to_Dacc, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Sop_xrgb4444_to_Dacc, /* DSPF_RGB444 */
+ Sop_xrgb1555_to_Dacc, /* DSPF_RGB555 */
+ Sop_xbgr1555_to_Dacc, /* DSPF_BGR555 */
+};
+
+/********************************* Sop_PFI_Kto_Dacc ***************************/
+
+static void Sop_argb6666_Kto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ while (w--) {
+ u8 s0 = S[0];
+ u8 s1 = S[1];
+ u8 s2 = S[2];
+
+ if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) {
+ u8 b = s0 & 0x3F;
+ u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2);
+ u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4);
+ u8 a = (s2 & 0xFC) >> 2;
+
+ D->RGB.a = EXPAND_6to8( a );
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+ }
+ else
+ D->RGB.a = 0xF000;
+
+ S += 3;
+ D++;
+ }
+}
+
+static void Sop_argb1666_Kto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ while (w--) {
+ u8 s0 = S[0];
+ u8 s1 = S[1];
+ u8 s2 = S[2];
+
+ if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) {
+ u8 b = s0 & 0x3F;
+ u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2);
+ u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4);
+ u8 a = (s2 & 0x04) >> 2;
+
+ D->RGB.a = EXPAND_1to8( a );
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+ }
+ else
+ D->RGB.a = 0xF000;
+
+ S += 3;
+ D++;
+ }
+}
+
+static void Sop_rgb18_Kto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ while (w--) {
+ u8 s0 = S[0];
+ u8 s1 = S[1];
+ u8 s2 = S[2];
+
+ if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3ffff)) {
+ u8 b = s0 & 0x3F;
+ u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2);
+ u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4);
+
+ D->RGB.a = 0xFF;
+ D->RGB.r = EXPAND_6to8( r );
+ D->RGB.g = EXPAND_6to8( g );
+ D->RGB.b = EXPAND_6to8( b );
+ }
+ else
+ D->RGB.a = 0xF000;
+
+ S += 3;
+ D++;
+ }
+}
+
+static void Sop_rgb24_Kto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ while (w--) {
+ u8 b = *S++;
+ u8 g = *S++;
+ u8 r = *S++;
+
+ if (Skey != (u32)(r<<16 | g<<8 | b)) {
+ D->RGB.a = 0xFF;
+ D->RGB.r = r;
+ D->RGB.g = g;
+ D->RGB.b = b;
+ }
+ else
+ D->RGB.a = 0xF000;
+
+ D++;
+ }
+}
+
+static void Sop_a8_Kto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+
+ /* no color to key */
+ while (w--) {
+ D->RGB.a = *S++;
+ D->RGB.r = 0xFF;
+ D->RGB.g = 0xFF;
+ D->RGB.b = 0xFF;
+
+ D++;
+ }
+}
+
+static void Sop_yuy2_Kto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+ u32 Skey0 = gfxs->Skey & 0xFF00FFFF;
+ u32 Skey1 = gfxs->Skey & 0xFFFFFF00;
+
+#ifdef WORDS_BIGENDIAN
+#define S0_MASK 0xFFFFFF00
+#define S1_MASK 0xFF00FFFF
+#else
+#define S0_MASK 0xFF00FFFF
+#define S1_MASK 0xFFFFFF00
+#endif
+
+ while (w--) {
+ u32 s = *S++;
+
+ if (s != Skey) {
+ u32 cb, cr;
+
+#ifdef WORDS_BIGENDIAN
+ cb = (s & 0xFF000000) >> 24;
+ cr = (s & 0x0000FF00) >> 8;
+#else
+ cb = (s & 0x0000FF00) >> 8;
+ cr = (s & 0xFF000000) >> 24;
+#endif
+
+ if ((s & S0_MASK) != Skey0) {
+ D[0].YUV.a = 0xFF;
+#ifdef WORDS_BIGENDIAN
+ D[0].YUV.y = (s & 0x00FF0000) >> 16;
+#else
+ D[0].YUV.y = (s & 0x000000FF);
+#endif
+ D[0].YUV.u = cb;
+ D[0].YUV.v = cr;
+ }
+ else
+ D[0].YUV.a = 0xF000;
+
+ if ((s & S1_MASK) != Skey1) {
+ D[1].YUV.a = 0xFF;
+#ifdef WORDS_BIGENDIAN
+ D[1].YUV.y = (s & 0x000000FF);
+#else
+ D[1].YUV.y = (s & 0x00FF0000) >> 16;
+#endif
+ D[1].YUV.u = cb;
+ D[1].YUV.v = cr;
+ }
+ else
+ D[1].YUV.a = 0xF000;
+ }
+
+ D += 2;
+ }
+
+ if (gfxs->length & 1) {
+ u16 s = *((u16*)S);
+
+ if (s != Skey0) {
+ D->YUV.a = 0xFF;
+ D->YUV.y = s & 0xFF;
+ D->YUV.u = s >> 8;
+ D->YUV.v = 0x00;
+ }
+ else
+ D->YUV.a = 0xF000;
+ }
+#undef S0_MASK
+#undef S1_MASK
+}
+
+static void Sop_rgb332_Kto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ while (w--) {
+ u8 s = *S++;
+
+ if (s != Skey) {
+ D->RGB.a = 0xFF;
+ D->RGB.r = EXPAND_3to8(s >> 5);
+ D->RGB.g = EXPAND_3to8((s & 0x1C) >> 2);
+ D->RGB.b = EXPAND_2to8(s & 0x03);
+ }
+ else
+ D->RGB.a = 0xF000;
+
+ D++;
+ }
+}
+
+static void Sop_uyvy_Kto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+ u32 Skey0 = gfxs->Skey & 0x00FFFFFF;
+ u32 Skey1 = gfxs->Skey & 0xFFFF00FF;
+
+#ifdef WORDS_BIGENDIAN
+#define S0_MASK 0xFFFF00FF
+#define S1_MASK 0x00FFFFFF
+#else
+#define S0_MASK 0x00FFFFFF
+#define S1_MASK 0xFFFF00FF
+#endif
+
+ while (w--) {
+ u32 s = *S++;
+
+ if (s != Skey) {
+ u32 cb, cr;
+
+#ifdef WORDS_BIGENDIAN
+ cb = (s & 0x00FF0000) >> 16;
+ cr = (s & 0x000000FF);
+#else
+ cb = (s & 0x000000FF);
+ cr = (s & 0x00FF0000) >> 16;
+#endif
+
+ if ((s & S0_MASK) != Skey0) {
+ D[0].YUV.a = 0xFF;
+#ifdef WORDS_BIGENDIAN
+ D[0].YUV.y = (s & 0xFF000000) >> 24;
+#else
+ D[0].YUV.y = (s & 0x0000FF00) >> 8;
+#endif
+ D[0].YUV.u = cb;
+ D[0].YUV.v = cr;
+ }
+ else
+ D[0].YUV.a = 0xF000;
+
+ if ((s & S1_MASK) != Skey1) {
+ D[1].YUV.a = 0xFF;
+#ifdef WORDS_BIGENDIAN
+ D[1].YUV.y = (s & 0x0000FF00) >> 8;
+#else
+ D[1].YUV.y = (s & 0xFF000000) >>24;
+#endif
+ D[1].YUV.u = cb;
+ D[1].YUV.v = cr;
+ }
+ else
+ D[1].YUV.a = 0xF000;
+ }
+
+ D += 2;
+ }
+
+ if (gfxs->length & 1) {
+ u16 s = *((u16*)S);
+
+ if (s != Skey0) {
+ D->YUV.a = 0xFF;
+ D->YUV.y = s >> 8;
+ D->YUV.u = s & 0xFF;
+ D->YUV.v = 0x00;
+ }
+ else
+ D->YUV.a = 0xF000;
+ }
+#undef S0_MASK
+#undef S1_MASK
+}
+
+static void Sop_lut8_Kto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ DFBColor *entries = gfxs->Slut->entries;
+
+ while (w--) {
+ u8 s = *S++;
+
+ if (s != Skey) {
+ D->RGB.a = entries[s].a;
+ D->RGB.r = entries[s].r;
+ D->RGB.g = entries[s].g;
+ D->RGB.b = entries[s].b;
+ }
+ else
+ D->RGB.a = 0xF000;
+
+ D++;
+ }
+}
+
+static void Sop_alut44_Kto_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u8 *S = gfxs->Sop[0];
+ u32 Skey = gfxs->Skey;
+
+ DFBColor *entries = gfxs->Slut->entries;
+
+ while (w--) {
+ u8 s = *S++;
+
+ if ((s & 0x0F) != Skey) {
+ D->RGB.a = ((s & 0xF0) >> 4) | (s & 0xF0);
+ s &= 0x0F;
+ D->RGB.r = entries[s].r;
+ D->RGB.g = entries[s].g;
+ D->RGB.b = entries[s].b;
+ }
+ else
+ D->RGB.a = 0xF000;
+
+ D++;
+ }
+}
+
+static GenefxFunc Sop_PFI_Kto_Dacc[DFB_NUM_PIXELFORMATS] = {
+ Sop_argb1555_Kto_Dacc, /* DSPF_ARGB1555 */
+ Sop_rgb16_Kto_Dacc, /* DSPF_RGB16 */
+ Sop_rgb24_Kto_Dacc, /* DSPF_RGB24 */
+ Sop_rgb32_Kto_Dacc, /* DSPF_RGB32 */
+ Sop_argb_Kto_Dacc, /* DSPF_ARGB */
+ Sop_a8_Kto_Dacc, /* DSPF_A8 */
+ Sop_yuy2_Kto_Dacc, /* DSPF_YUY2 */
+ Sop_rgb332_Kto_Dacc, /* DSPF_RGB332 */
+ Sop_uyvy_Kto_Dacc, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ Sop_lut8_Kto_Dacc, /* DSPF_LUT8 */
+ Sop_alut44_Kto_Dacc, /* DSPF_ALUT44 */
+ Sop_airgb_Kto_Dacc, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Sop_argb2554_Kto_Dacc, /* DSPF_ARGB2554 */
+ Sop_argb4444_Kto_Dacc, /* DSPF_ARGB4444 */
+ Sop_rgba4444_Kto_Dacc, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ NULL, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Sop_argb6666_Kto_Dacc, /* DSPF_ARGB1666 */
+ Sop_argb1666_Kto_Dacc, /* DSPF_ARGB6666 */
+ Sop_rgb18_Kto_Dacc, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Sop_xrgb4444_Kto_Dacc, /* DSPF_RGB444 */
+ Sop_xrgb1555_Kto_Dacc, /* DSPF_RGB555 */
+ Sop_xbgr1555_Kto_Dacc, /* DSPF_BGR555 */
+};
+
+/********************************* Sacc_to_Aop_PFI ****************************/
+
+static void Sacc_to_Aop_argb6666( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000)) {
+ u32 pixel = PIXEL_ARGB6666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D +=3;
+ S++;
+ }
+}
+
+static void Sacc_to_Aop_argb1666( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000)) {
+ u32 pixel = PIXEL_ARGB1666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D +=3;
+ S++;
+ }
+}
+
+static void Sacc_to_Aop_rgb18( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000)) {
+ u32 pixel = PIXEL_RGB18( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D +=3;
+ S++;
+ }
+}
+
+static void Sacc_to_Aop_rgb24( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000)) {
+ *D++ = (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b;
+ *D++ = (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g;
+ *D++ = (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r;
+ }
+ else
+ D += 3;
+
+ S++;
+ }
+}
+
+static void Sacc_to_Aop_a8( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000))
+ *D = (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a;
+
+ D++;
+ S++;
+ }
+}
+
+static void Sacc_to_Aop_yuy2( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u16 *D = gfxs->Aop[0];
+
+ if ((long)D & 2) {
+ if (!(S->YUV.a & 0xF00)) {
+ *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) |
+ ((S->YUV.v & 0xFF00) ? 0XFF00 : (S->YUV.v<<8));
+ }
+ S++;
+ D++;
+ w--;
+ }
+
+ for (l = w>>1; l--;) {
+ if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) {
+ u32 y0, cb, y1, cr;
+
+ y0 = (S[0].YUV.y & 0xFF00) ? 0xFF : S[0].YUV.y;
+ y1 = (S[1].YUV.y & 0xFF00) ? 0xFF : S[1].YUV.y;
+
+ cb = (S[0].YUV.u + S[1].YUV.u) >> 1;
+ if (cb & 0xFF00)
+ cb = 0xFF;
+
+ cr = (S[0].YUV.v + S[1].YUV.v) >> 1;
+ if (cr & 0xFF00)
+ cr = 0xFF;
+
+#ifdef WORDS_BIGENDIAN
+ *((u32*)D) = y1 | (cr << 8) | (y0 << 16) | (cb << 24);
+#else
+ *((u32*)D) = y0 | (cb << 8) | (y1 << 16) | (cr << 24);
+#endif
+ }
+ else if (!(S[0].YUV.a & 0xF000)) {
+ D[0] = ((S[0].YUV.y & 0xFF00) ? 0x00FF : S[0].YUV.y) |
+ ((S[0].YUV.u & 0xFF00) ? 0xFF00 : (S[0].YUV.u<<8));
+ }
+ else if (!(S[1].YUV.a & 0xF000)) {
+ D[1] = ((S[1].YUV.y & 0xFF00) ? 0x00FF : S[1].YUV.y) |
+ ((S[1].YUV.v & 0xFF00) ? 0xFF00 : (S[1].YUV.v<<8));
+ }
+
+ D += 2;
+ S += 2;
+ }
+
+ if (w & 1) {
+ if (!(S->YUV.a & 0xF00)) {
+ *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) |
+ ((S->YUV.u & 0xFF00) ? 0xFF00 : (S->YUV.u<<8));
+ }
+ }
+}
+
+static void Sacc_to_Aop_rgb332( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000)) {
+ *D = PIXEL_RGB332( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+ }
+
+ D++;
+ S++;
+ }
+}
+
+static void Sacc_to_Aop_uyvy( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u16 *D = gfxs->Aop[0];
+
+ if ((long)D & 2) {
+ if (!(S->YUV.a & 0xF00)) {
+ *D = ((S->YUV.v & 0xFF00) ? 0x00FF : S->YUV.v) |
+ ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8));
+ }
+ S++;
+ D++;
+ w--;
+ }
+
+ for (l = w>>1; l--;) {
+ if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) {
+ u32 cb, y0, cr, y1;
+
+ y0 = (S[0].YUV.y & 0xFF00) ? 0xFF : S[0].YUV.y;
+ y1 = (S[1].YUV.y & 0xFF00) ? 0xFF : S[1].YUV.y;
+
+ cb = (S[0].YUV.u + S[1].YUV.u) >> 1;
+ if (cb & 0xFF00)
+ cb = 0xFF;
+
+ cr = (S[0].YUV.v + S[1].YUV.v) >> 1;
+ if (cr & 0xFF00)
+ cr = 0xFF;
+
+#ifdef WORDS_BIGENDIAN
+ *((u32*)D) = cr | (y1 << 8) | (cb << 16) | (y0 << 24);
+#else
+ *((u32*)D) = cb | (y0 << 8) | (cr << 16) | (y1 << 24);
+#endif
+ }
+ else if (!(S[0].YUV.a & 0xF000)) {
+ D[0] = ((S[0].YUV.u & 0xFF00) ? 0x00FF : S[0].YUV.u) |
+ ((S[0].YUV.y & 0xFF00) ? 0xFF00 : (S[0].YUV.y<<8));
+ }
+ else if (!(S[1].YUV.a & 0xF000)) {
+ D[1] = ((S[1].YUV.v & 0xFF00) ? 0x00FF : S[1].YUV.v) |
+ ((S[1].YUV.y & 0xFF00) ? 0xFF00 : (S[1].YUV.y<<8));
+ }
+
+ D += 2;
+ S += 2;
+ }
+
+ if (w & 1) {
+ if (!(S->YUV.a & 0xF00)) {
+ *D = ((S->YUV.u & 0xFF00) ? 0x00FF : S->YUV.u) |
+ ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8));
+ }
+ }
+}
+
+static void Sacc_to_Aop_lut8( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000)) {
+ *D = dfb_palette_search( gfxs->Alut,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b,
+ (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a );
+ }
+
+ D++;
+ S++;
+ }
+}
+
+static void Sacc_to_Aop_alut44( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000)) {
+ *D = (S->RGB.a & 0xFF00) ? 0xF0 : (S->RGB.a & 0xF0) +
+ dfb_palette_search( gfxs->Alut,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b,
+ 0x80 );
+ }
+
+ D++;
+ S++;
+ }
+}
+
+static void Sacc_to_Aop_i420( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *Dy = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->YUV.a & 0xF000))
+ *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y;
+
+ S++;
+ Dy++;
+ }
+
+ if (gfxs->AopY & 1) {
+ u8 *Du = gfxs->Aop[1];
+ u8 *Dv = gfxs->Aop[2];
+
+ w = gfxs->length>>1;
+ S = gfxs->Sacc;
+
+ while (w--) {
+ if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) {
+ u32 tmp;
+
+ tmp = (S[0].YUV.u + S[1].YUV.u) >> 1;
+ if (tmp & 0xFF00)
+ tmp = 0xFF;
+ *Du = tmp;
+
+ tmp = (S[0].YUV.v + S[1].YUV.v) >> 1;
+ if (tmp & 0xFF00)
+ tmp = 0xFF;
+ *Dv = tmp;
+
+ }
+ else if (!(S[0].YUV.a & 0xF000)) {
+ *Du = (*Du + ((S[0].YUV.u & 0xFF00) ? 0xFF : S[0].YUV.u)) >> 1;
+ *Dv = (*Dv + ((S[0].YUV.v & 0xFF00) ? 0xFF : S[0].YUV.v)) >> 1;
+ }
+ else if (!(S[1].YUV.a & 0xF000)) {
+ *Du = (*Du + ((S[1].YUV.u & 0xFF00) ? 0xFF : S[1].YUV.u)) >> 1;
+ *Dv = (*Dv + ((S[1].YUV.v & 0xFF00) ? 0xFF : S[1].YUV.v)) >> 1;
+ }
+
+ S += 2;
+ Du++;
+ Dv++;
+ }
+ }
+}
+
+static void Sacc_to_Aop_nv12( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *Dy = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->YUV.a & 0xF000))
+ *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y;
+
+ S++;
+ Dy++;
+ }
+
+ if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) {
+ u16 *Duv = gfxs->Aop[1];
+
+ w = gfxs->length>>1;
+ S = gfxs->Sacc;
+
+ while (w--) {
+ u32 cb, cr;
+
+ if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) {
+ cb = (S[0].YUV.u + S[1].YUV.u) >> 1;
+ if (cb & 0xFF00)
+ cb = 0xFF;
+
+ cr = (S[0].YUV.v + S[1].YUV.v) >> 1;
+ if (cr & 0xFF00)
+ cr = 0xFF;
+
+#ifdef WORDS_BIGENDIAN
+ *Duv = cr | (cb << 8);
+ }
+ else if (!(S[0].YUV.a & 0xF000)) {
+ cb = ((*Duv >> 8) + ((S[0].YUV.u & 0xFF00) ? 0xFF : S[0].YUV.u)) >> 1;
+ cr = ((*Duv & 0xFF) + ((S[0].YUV.v & 0xFF00) ? 0xFF : S[0].YUV.v)) >> 1;
+ *Duv = cr | (cb << 8);
+ }
+ else if (!(S[1].YUV.a & 0xF000)) {
+ cb = ((*Duv >> 8) + ((S[1].YUV.u & 0xFF00) ? 0xFF : S[1].YUV.u)) >> 1;
+ cr = ((*Duv & 0xFF) + ((S[1].YUV.v & 0xFF00) ? 0xFF : S[1].YUV.v)) >> 1;
+ *Duv = cr | (cb << 8);
+ }
+#else
+ *Duv = cb | (cr << 8);
+ }
+ else if (!(S[0].YUV.a & 0xF000)) {
+ cb = ((*Duv & 0xFF) + ((S[0].YUV.u & 0xFF00) ? 0xFF : S[0].YUV.u)) >> 1;
+ cr = ((*Duv >> 8) + ((S[0].YUV.v & 0xFF00) ? 0xFF : S[0].YUV.v)) >> 1;
+ *Duv = cb | (cr << 8);
+ }
+ else if (!(S[1].YUV.a & 0xF000)) {
+ cb = ((*Duv & 0xFF) + ((S[1].YUV.u & 0xFF00) ? 0xFF : S[1].YUV.u)) >> 1;
+ cr = ((*Duv >> 8) + ((S[1].YUV.v & 0xFF00) ? 0xFF : S[1].YUV.v)) >> 1;
+ *Duv = cb | (cr << 8);
+ }
+#endif
+
+ S += 2;
+ Duv++;
+ }
+ }
+}
+
+static void Sacc_to_Aop_nv21( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *Dy = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->YUV.a & 0xF000))
+ *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y;
+
+ S++;
+ Dy++;
+ }
+
+ if (gfxs->AopY & 1) {
+ u16 *Dvu = gfxs->Aop[1];
+
+ w = gfxs->length>>1;
+ S = gfxs->Sacc;
+
+ while (w--) {
+ u32 cb, cr;
+
+ if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) {
+ cb = (S[0].YUV.u + S[1].YUV.u) >> 1;
+ if (cb & 0xFF00)
+ cb = 0xFF;
+
+ cr = (S[0].YUV.v + S[1].YUV.v) >> 1;
+ if (cr & 0xFF00)
+ cr = 0xFF;
+
+ *Dvu = cr | (cb << 8);
+ }
+ else if (!(S[0].YUV.a & 0xF000)) {
+ cb = ((*Dvu >> 8) + ((S[0].YUV.u & 0xFF00) ? 0xFF : S[0].YUV.u)) >> 1;
+ cr = ((*Dvu & 0xFF) + ((S[0].YUV.v & 0xFF00) ? 0xFF : S[0].YUV.v)) >> 1;
+ *Dvu = cr | (cb << 8);
+ }
+ else if (!(S[1].YUV.a & 0xF000)) {
+ cb = ((*Dvu >> 8) + ((S[1].YUV.u & 0xFF00) ? 0xFF : S[1].YUV.u)) >> 1;
+ cr = ((*Dvu & 0xFF) + ((S[1].YUV.v & 0xFF00) ? 0xFF : S[1].YUV.v)) >> 1;
+ *Dvu = cr | (cb << 8);
+ }
+
+ S += 2;
+ Dvu++;
+ }
+ }
+}
+
+static void Sacc_to_Aop_ayuv( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u32 *D = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S->YUV.a & 0xF000)) {
+ *D = PIXEL_AYUV( (S->YUV.a & 0xFF00) ? 0xFF : S->YUV.a,
+ (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y,
+ (S->YUV.u & 0xFF00) ? 0xFF : S->YUV.u,
+ (S->YUV.v & 0xFF00) ? 0xFF : S->YUV.v );
+ }
+
+ D++;
+ S++;
+ }
+}
+
+static void Sacc_to_Aop_a4( GenefxState *gfxs )
+{
+ int w = gfxs->length>>1;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+
+ while (w--) {
+ if (!(S[0].RGB.a & 0xF000) && !(S[1].RGB.a & 0xF000)) {
+ *D = ((S[0].RGB.a & 0xFF00) ? 0xF0 : (S[0].RGB.a & 0xF0)) |
+ ((S[1].RGB.a & 0XFF00) ? 0x0F : (S[1].RGB.a >> 4));
+ }
+ else if (!(S[0].RGB.a & 0xF000)) {
+ *D = (*D & 0x0F) | ((S[0].RGB.a & 0xFF00) ? 0xF0 : (S[0].RGB.a & 0xF0));
+ }
+ else if (!(S[1].RGB.a & 0xF000)) {
+ *D = (*D & 0xF0) | ((S[1].RGB.a & 0XFF00) ? 0x0F : (S[1].RGB.a >> 4));
+ }
+
+ D++;
+ S += 2;
+ }
+
+ if (gfxs->length & 1) {
+ if (!(S->RGB.a & 0xF000))
+ *D = (*D & 0x0F) | ((S->RGB.a & 0xFF00) ? 0xF0 : (S->RGB.a & 0xF0));
+ }
+}
+
+static GenefxFunc Sacc_to_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Sacc_to_Aop_argb1555, /* DSPF_ARGB1555 */
+ Sacc_to_Aop_rgb16, /* DSPF_RGB16 */
+ Sacc_to_Aop_rgb24, /* DSPF_RGB24 */
+ Sacc_to_Aop_rgb32, /* DSPF_RGB32 */
+ Sacc_to_Aop_argb, /* DSPF_ARGB */
+ Sacc_to_Aop_a8, /* DSPF_A8 */
+ Sacc_to_Aop_yuy2, /* DSPF_YUY2 */
+ Sacc_to_Aop_rgb332, /* DSPF_RGB332 */
+ Sacc_to_Aop_uyvy, /* DSPF_UYVY */
+ Sacc_to_Aop_i420, /* DSPF_I420 */
+ Sacc_to_Aop_i420, /* DSPF_YV12 */
+ Sacc_to_Aop_lut8, /* DSPF_LUT8 */
+ Sacc_to_Aop_alut44, /* DSPF_ALUT44 */
+ Sacc_to_Aop_airgb, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ Sacc_to_Aop_nv12, /* DSPF_NV12 */
+ Sacc_to_Aop_nv12, /* DSPF_NV16 */
+ Sacc_to_Aop_argb2554, /* DSPF_ARGB2554 */
+ Sacc_to_Aop_argb4444, /* DSPF_ARGB4444 */
+ Sacc_to_Aop_rgba4444, /* DSPF_RGBA4444 */
+ Sacc_to_Aop_nv21, /* DSPF_NV21 */
+ Sacc_to_Aop_ayuv, /* DSPF_AYUV */
+ Sacc_to_Aop_a4, /* DSPF_A4 */
+ Sacc_to_Aop_argb1666, /* DSPF_ARGB1666 */
+ Sacc_to_Aop_argb6666, /* DSPF_ARGB6666 */
+ Sacc_to_Aop_rgb18, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Sacc_to_Aop_xrgb4444, /* DSPF_RGB444 */
+ Sacc_to_Aop_xrgb1555, /* DSPF_RGB555 */
+ Sacc_to_Aop_xbgr1555, /* DSPF_BGR555 */
+};
+
+/********************************* Sacc_Sto_Aop_PFI ***************************/
+
+static void Sacc_Sto_Aop_argb6666( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000)) {
+ u32 pixel = PIXEL_ARGB6666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D +=3;
+ i += SperD;
+ }
+}
+
+static void Sacc_Sto_Aop_argb1666( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000)) {
+ u32 pixel = PIXEL_ARGB1666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D +=3;
+ i += SperD;
+ }
+}
+
+static void Sacc_Sto_Aop_rgb18( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000)) {
+ u32 pixel = PIXEL_RGB18( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D +=3;
+ i += SperD;
+ }
+}
+
+static void Sacc_Sto_Aop_rgb24( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000)) {
+ *D++ = (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b;
+ *D++ = (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g;
+ *D++ = (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r;
+ }
+ else
+ D += 3;
+
+ i += SperD;
+ }
+}
+
+static void Sacc_Sto_Aop_a8( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000))
+ *D = (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a;
+
+ D++;
+ i += SperD;
+ }
+}
+
+static void Sacc_Sto_Aop_yuy2( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u16 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+ int SperD2 = gfxs->SperD << 1;
+
+ if ((long)D & 2) {
+ GenefxAccumulator *S = Sacc;
+ if (!(S->YUV.a & 0xF00)) {
+ *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) |
+ ((S->YUV.v & 0xFF00) ? 0XFF00 : (S->YUV.v<<8));
+ }
+ D++;
+ w--;
+ i = SperD;
+ }
+
+ for (l = w>>1; l--;) {
+ GenefxAccumulator *S0 = &Sacc[i>>16];
+ GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16];
+
+ if (!(S0->YUV.a & 0xF000) && !(S1->YUV.a & 0xF000)) {
+ u32 y0, cb, y1, cr;
+
+ y0 = (S0->YUV.y & 0xFF00) ? 0xFF : S0->YUV.y;
+ y1 = (S1->YUV.y & 0xFF00) ? 0xFF : S1->YUV.y;
+
+ cb = (S0->YUV.u + S1->YUV.u) >> 1;
+ if (cb & 0xFF00)
+ cb = 0xFF;
+
+ cr = (S0->YUV.v + S1->YUV.v) >> 1;
+ if (cr & 0xFF00)
+ cr = 0xFF;
+
+#ifdef WORDS_BIGENDIAN
+ *((u32*)D) = y1 | (cr << 8) | (y0 << 16) | (cb << 24);
+#else
+ *((u32*)D) = y0 | (cb << 8) | (y1 << 16) | (cr << 24);
+#endif
+ }
+ else if (!(S0->YUV.a & 0xF000)) {
+ D[0] = ((S0->YUV.y & 0xFF00) ? 0x00FF : S0->YUV.y) |
+ ((S0->YUV.u & 0xFF00) ? 0xFF00 : (S0->YUV.u<<8));
+ }
+ else if (!(S1->YUV.a & 0xF000)) {
+ D[1] = ((S1->YUV.y & 0xFF00) ? 0x00FF : S1->YUV.y) |
+ ((S1->YUV.v & 0xFF00) ? 0xFF00 : (S1->YUV.v<<8));
+ }
+
+ D += 2;
+ i += SperD2;
+ }
+
+ if (w & 1) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+ if (!(S->YUV.a & 0xF00)) {
+ *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) |
+ ((S->YUV.u & 0xFF00) ? 0xFF00 : (S->YUV.u<<8));
+ }
+ }
+}
+
+static void Sacc_Sto_Aop_rgb332( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000)) {
+ *D = PIXEL_RGB332( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+ }
+
+ D++;
+ i += SperD;
+ }
+}
+
+static void Sacc_Sto_Aop_uyvy( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u16 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+ int SperD2 = gfxs->SperD << 1;
+
+ if ((long)D & 2) {
+ GenefxAccumulator *S = Sacc;
+ if (!(S->YUV.a & 0xF00)) {
+ *D = ((S->YUV.v & 0xFF00) ? 0x00FF : S->YUV.v) |
+ ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8));
+ }
+ D++;
+ w--;
+ i = SperD;
+ }
+
+ for (l = w>>1; l--;) {
+ GenefxAccumulator *S0 = &Sacc[i>>16];
+ GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16];
+
+ if (!(S0->YUV.a & 0xF000) && !(S1->YUV.a & 0xF000)) {
+ u32 cb, y0, cr, y1;
+
+ y0 = (S0->YUV.y & 0xFF00) ? 0xFF : S0->YUV.y;
+ y1 = (S1->YUV.y & 0xFF00) ? 0xFF : S1->YUV.y;
+
+ cb = (S0->YUV.u + S1->YUV.u) >> 1;
+ if (cb & 0xFF00)
+ cb = 0xFF;
+
+ cr = (S0->YUV.v + S1->YUV.v) >> 1;
+ if (cr & 0xFF00)
+ cr = 0xFF;
+
+#ifdef WORDS_BIGENDIAN
+ *((u32*)D) = cr | (y1 << 8) | (cb << 16) | (y0 << 24);
+#else
+ *((u32*)D) = cb | (y0 << 8) | (cr << 16) | (y1 << 24);
+#endif
+ }
+ else if (!(S0->YUV.a & 0xF000)) {
+ D[0] = ((S0->YUV.u & 0xFF00) ? 0x00FF : S0->YUV.u) |
+ ((S0->YUV.y & 0xFF00) ? 0xFF00 : (S0->YUV.y<<8));
+ }
+ else if (!(S1->YUV.a & 0xF000)) {
+ D[1] = ((S1->YUV.v & 0xFF00) ? 0x00FF : S1->YUV.v) |
+ ((S1->YUV.y & 0xFF00) ? 0xFF00 : (S1->YUV.y<<8));
+ }
+
+ D += 2;
+ i += SperD2;
+ }
+
+ if (w & 1) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+ if (!(S->YUV.a & 0xF00)) {
+ *D = ((S->YUV.u & 0xFF00) ? 0x00FF : S->YUV.u) |
+ ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8));
+ }
+ }
+}
+
+static void Sacc_Sto_Aop_lut8( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000)) {
+ *D = dfb_palette_search( gfxs->Alut,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b,
+ (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a );
+ }
+
+ D++;
+ i += SperD;
+ }
+}
+
+static void Sacc_Sto_Aop_alut44( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000)) {
+ *D = (S->RGB.a & 0xFF00) ? 0xF0 : (S->RGB.a & 0xF0) +
+ dfb_palette_search( gfxs->Alut,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b,
+ 0x80 );
+ }
+
+ D++;
+ i += SperD;
+ }
+}
+
+static void Sacc_Sto_Aop_i420( GenefxState *gfxs )
+{
+ int i = gfxs->Xphase;
+ int w = gfxs->length;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *Dy = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->YUV.a & 0xF000))
+ *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y;
+
+ Dy++;
+ i += SperD;
+ }
+
+ if (gfxs->AopY & 1) {
+ u8 *Du = gfxs->Aop[1];
+ u8 *Dv = gfxs->Aop[2];
+
+ w = gfxs->length>>1;
+ i = gfxs->Xphase>>1;
+
+ while (w--) {
+ GenefxAccumulator *S0 = &Sacc[i>>16];
+ GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16];
+
+ if (!(S0->YUV.a & 0xF000) && !(S1->YUV.a & 0xF000)) {
+ u32 tmp;
+
+ tmp = (S0->YUV.u + S1->YUV.u) >> 1;
+ if (tmp & 0xFF00)
+ tmp = 0xFF;
+ *Du = tmp;
+
+ tmp = (S0->YUV.v + S1->YUV.v) >> 1;
+ if (tmp & 0xFF00)
+ tmp = 0xFF;
+ *Dv = tmp;
+
+ }
+ else if (!(S0->YUV.a & 0xF000)) {
+ *Du = (*Du + ((S0->YUV.u & 0xFF00) ? 0xFF : S0->YUV.u)) >> 1;
+ *Dv = (*Dv + ((S0->YUV.v & 0xFF00) ? 0xFF : S0->YUV.v)) >> 1;
+ }
+ else if (!(S1->YUV.a & 0xF000)) {
+ *Du = (*Du + ((S1->YUV.u & 0xFF00) ? 0xFF : S1->YUV.u)) >> 1;
+ *Dv = (*Dv + ((S1->YUV.v & 0xFF00) ? 0xFF : S1->YUV.v)) >> 1;
+ }
+
+ Du++;
+ Dv++;
+ i += SperD << 1;
+ }
+ }
+}
+
+static void Sacc_Sto_Aop_nv12( GenefxState *gfxs )
+{
+ int i = gfxs->Xphase;
+ int w = gfxs->length;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *Dy = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->YUV.a & 0xF000))
+ *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y;
+
+ Dy++;
+ i += SperD;
+ }
+
+ if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) {
+ u16 *Duv = gfxs->Aop[1];
+
+ w = gfxs->length>>1;
+ i = gfxs->Xphase>>1;
+
+ while (w--) {
+ GenefxAccumulator *S0 = &Sacc[i>>16];
+ GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16];
+ u32 cb, cr;
+
+ if (!(S0->YUV.a & 0xF000) && !(S1->YUV.a & 0xF000)) {
+ cb = (S0->YUV.u + S1->YUV.u) >> 1;
+ if (cb & 0xFF00)
+ cb = 0xFF;
+
+ cr = (S0->YUV.v + S1->YUV.v) >> 1;
+ if (cr & 0xFF00)
+ cr = 0xFF;
+
+#ifdef WORDS_BIGENDIAN
+ *Duv = cr | (cb << 8);
+ }
+ else if (!(S0->YUV.a & 0xF000)) {
+ cb = ((*Duv >> 8) + ((S0->YUV.u & 0xFF00) ? 0xFF : S0->YUV.u)) >> 1;
+ cr = ((*Duv & 0xFF) + ((S0->YUV.v & 0xFF00) ? 0xFF : S0->YUV.v)) >> 1;
+ *Duv = cr | (cb << 8);
+ }
+ else if (!(S1->YUV.a & 0xF000)) {
+ cb = ((*Duv >> 8) + ((S1->YUV.u & 0xFF00) ? 0xFF : S1->YUV.u)) >> 1;
+ cr = ((*Duv & 0xFF) + ((S1->YUV.v & 0xFF00) ? 0xFF : S1->YUV.v)) >> 1;
+ *Duv = cr | (cb << 8);
+ }
+#else
+ *Duv = cb | (cr << 8);
+ }
+ else if (!(S0->YUV.a & 0xF000)) {
+ cb = ((*Duv & 0xFF) + ((S0->YUV.u & 0xFF00) ? 0xFF : S0->YUV.u)) >> 1;
+ cr = ((*Duv >> 8) + ((S0->YUV.v & 0xFF00) ? 0xFF : S0->YUV.v)) >> 1;
+ *Duv = cb | (cr << 8);
+ }
+ else if (!(S1->YUV.a & 0xF000)) {
+ cb = ((*Duv & 0xFF) + ((S1->YUV.u & 0xFF00) ? 0xFF : S1->YUV.u)) >> 1;
+ cr = ((*Duv >> 8) + ((S1->YUV.v & 0xFF00) ? 0xFF : S1->YUV.v)) >> 1;
+ *Duv = cb | (cr << 8);
+ }
+#endif
+
+ Duv++;
+
+ i += SperD << 1;
+ }
+ }
+}
+
+static void Sacc_Sto_Aop_nv21( GenefxState *gfxs )
+{
+ int i = gfxs->Xphase;
+ int w = gfxs->length;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u8 *Dy = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->YUV.a & 0xF000))
+ *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y;
+
+ Dy++;
+ i += SperD;
+ }
+
+ if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) {
+ u16 *Dvu = gfxs->Aop[1];
+
+ w = gfxs->length>>1;
+ i = gfxs->Xphase>>1;
+
+ while (w--) {
+ GenefxAccumulator *S0 = &Sacc[i>>16];
+ GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16];
+ u32 cb, cr;
+
+ if (!(S0->YUV.a & 0xF000) && !(S1->YUV.a & 0xF000)) {
+ cb = (S0->YUV.u + S1->YUV.u) >> 1;
+ if (cb & 0xFF00)
+ cb = 0xFF;
+
+ cr = (S0->YUV.v + S1->YUV.v) >> 1;
+ if (cr & 0xFF00)
+ cr = 0xFF;
+
+#ifdef WORDS_BIGENDIAN
+ *Dvu = cb | (cr << 8);
+ }
+ else if (!(S0->YUV.a & 0xF000)) {
+ cb = ((*Dvu & 0xFF) + ((S0->YUV.u & 0xFF00) ? 0xFF : S0->YUV.u)) >> 1;
+ cr = ((*Dvu >> 8) + ((S0->YUV.v & 0xFF00) ? 0xFF : S0->YUV.v)) >> 1;
+ *Dvu = cb | (cr << 8);
+ }
+ else if (!(S1->YUV.a & 0xF000)) {
+ cb = ((*Dvu & 0xFF) + ((S1->YUV.u & 0xFF00) ? 0xFF : S1->YUV.u)) >> 1;
+ cr = ((*Dvu >> 8) + ((S1->YUV.v & 0xFF00) ? 0xFF : S1->YUV.v)) >> 1;
+ *Dvu = cb | (cr << 8);
+ }
+#else
+ *Dvu = cr | (cb << 8);
+ }
+ else if (!(S0->YUV.a & 0xF000)) {
+ cb = ((*Dvu >> 8) + ((S0->YUV.u & 0xFF00) ? 0xFF : S0->YUV.u)) >> 1;
+ cr = ((*Dvu & 0xFF) + ((S0->YUV.v & 0xFF00) ? 0xFF : S0->YUV.v)) >> 1;
+ *Dvu = cr | (cb << 8);
+ }
+ else if (!(S1->YUV.a & 0xF000)) {
+ cb = ((*Dvu >> 8) + ((S1->YUV.u & 0xFF00) ? 0xFF : S1->YUV.u)) >> 1;
+ cr = ((*Dvu & 0xFF) + ((S1->YUV.v & 0xFF00) ? 0xFF : S1->YUV.v)) >> 1;
+ *Dvu = cr | (cb << 8);
+ }
+#endif
+
+ Dvu++;
+
+ i += SperD << 1;
+ }
+ }
+}
+
+static void Sacc_Sto_Aop_ayuv( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int i = gfxs->Xphase;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u32 *D = gfxs->Aop[0];
+ int SperD = gfxs->SperD;
+
+ while (w--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->YUV.a & 0xF000)) {
+ *D = PIXEL_AYUV( (S->YUV.a & 0xFF00) ? 0xFF : S->YUV.a,
+ (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y,
+ (S->YUV.u & 0xFF00) ? 0xFF : S->YUV.u,
+ (S->YUV.v & 0xFF00) ? 0xFF : S->YUV.v );
+ }
+
+ D++;
+ i += SperD;
+ }
+}
+
+
+static GenefxFunc Sacc_Sto_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Sacc_Sto_Aop_argb1555, /* DSPF_ARGB1555 */
+ Sacc_Sto_Aop_rgb16, /* DSPF_RGB16 */
+ Sacc_Sto_Aop_rgb24, /* DSPF_RGB24 */
+ Sacc_Sto_Aop_rgb32, /* DSPF_RGB32 */
+ Sacc_Sto_Aop_argb, /* DSPF_ARGB */
+ Sacc_Sto_Aop_a8, /* DSPF_A8 */
+ Sacc_Sto_Aop_yuy2, /* DSPF_YUY2 */
+ Sacc_Sto_Aop_rgb332, /* DSPF_RGB332 */
+ Sacc_Sto_Aop_uyvy, /* DSPF_UYVY */
+ Sacc_Sto_Aop_i420, /* DSPF_I420 */
+ Sacc_Sto_Aop_i420, /* DSPF_YV12 */
+ Sacc_Sto_Aop_lut8, /* DSPF_LUT8 */
+ Sacc_Sto_Aop_alut44, /* DSPF_ALUT44 */
+ Sacc_Sto_Aop_airgb, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ Sacc_Sto_Aop_nv12, /* DSPF_NV12 */
+ Sacc_Sto_Aop_nv12, /* DSPF_NV16 */
+ Sacc_Sto_Aop_argb2554, /* DSPF_ARGB2554 */
+ Sacc_Sto_Aop_argb4444, /* DSPF_ARGB4444 */
+ Sacc_Sto_Aop_rgba4444, /* DSPF_RGBA4444 */
+ Sacc_Sto_Aop_nv21, /* DSPF_NV21 */
+ Sacc_Sto_Aop_ayuv, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Sacc_Sto_Aop_argb1666, /* DSPF_ARGB1666 */
+ Sacc_Sto_Aop_argb6666, /* DSPF_ARGB6666 */
+ Sacc_Sto_Aop_rgb18, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Sacc_Sto_Aop_xrgb4444, /* DSPF_RGB444 */
+ Sacc_Sto_Aop_xrgb1555, /* DSPF_RGB555 */
+ Sacc_Sto_Aop_xbgr1555, /* DSPF_BGR555 */
+};
+
+/********************************* Sacc_toK_Aop_PFI ***************************/
+
+static void Sacc_toK_Aop_argb6666( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000) && Dkey == ((u32)(D[2]<<16 | D[1]<<8 | D[0]) & 0x3FFFF)) {
+ u32 pixel = PIXEL_ARGB6666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D +=3;
+ S++;
+ }
+}
+
+static void Sacc_toK_Aop_argb1666( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000) && Dkey == ((u32)(D[2]<<16 | D[1]<<8 | D[0]) & 0x3FFFF)) {
+ u32 pixel = PIXEL_ARGB1666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D +=3;
+ S++;
+ }
+}
+
+static void Sacc_toK_Aop_rgb18( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000) && Dkey == ((u32)(D[2]<<16 | D[1]<<8 | D[0]) & 0x3FFFF)) {
+ u32 pixel = PIXEL_RGB18( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D +=3;
+ S++;
+ }
+}
+
+static void Sacc_toK_Aop_rgb24( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ u8 r = (gfxs->Dkey >> 16);
+ u8 g = (gfxs->Dkey >> 8) & 0xff;
+ u8 b = (gfxs->Dkey ) & 0xff;
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000) && D[0] == b && D[1] == g && D[2] == r) {
+ *D++ = (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b;
+ *D++ = (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g;
+ *D++ = (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r;
+ }
+ else
+ D += 3;
+
+ S++;
+ }
+}
+
+static void Sacc_toK_Aop_a8( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+
+ /* FIXME: do all or do none? */
+ while (w--) {
+ if (!(S->RGB.a & 0xF000))
+ *D = (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a;
+
+ D++;
+ S++;
+ }
+}
+
+static void Sacc_toK_Aop_yuy2( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u16 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+#ifdef WORDS_BIGENDIAN
+ u16 Dkey0 = gfxs->Dkey >> 16;
+ u16 Dkey1 = gfxs->Dkey & 0xFFFF;
+#else
+ u16 Dkey0 = gfxs->Dkey & 0xFFFF;
+ u16 Dkey1 = gfxs->Dkey >> 16;
+#endif
+
+ if ((long)D & 2) {
+ if (!(S->YUV.a & 0xF000) && (*D == Dkey1)) {
+ *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) |
+ ((S->YUV.v & 0xFF00) ? 0xFF00 : (S->YUV.v<<8));
+ }
+ S++;
+ D++;
+ w--;
+ }
+
+ for (l = w>>1; l--;) {
+ if (*D == Dkey) {
+ if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) {
+ u32 y0, cb, y1, cr;
+
+ y0 = (S[0].YUV.y & 0xFF00) ? 0xFF : S[0].YUV.y;
+ y1 = (S[1].YUV.y & 0xFF00) ? 0xFF : S[1].YUV.y;
+
+ cb = (S[0].YUV.u + S[1].YUV.u) >> 1;
+ if (cb & 0xFF00)
+ cb = 0xFF;
+
+ cr = (S[0].YUV.v + S[1].YUV.v) >> 1;
+ if (cr & 0xFF00)
+ cr = 0xFF;
+
+#ifdef WORDS_BIGENDIAN
+ *((u32*)D) = y1 | (cr << 8) | (y0 << 16) | (cb << 24);
+#else
+ *((u32*)D) = y0 | (cb << 8) | (y1 << 16) | (cr << 24);
+#endif
+ }
+ else if (!(S[0].YUV.a & 0xF000)) {
+ D[0] = ((S[0].YUV.y & 0xFF00) ? 0x00FF : S[0].YUV.y) |
+ ((S[0].YUV.u & 0xFF00) ? 0xFF00 : (S[0].YUV.u<<8));
+ }
+ else if (!(S[1].YUV.a & 0xF000)) {
+ D[1] = ((S[1].YUV.y & 0xFF00) ? 0x00FF : S[1].YUV.y) |
+ ((S[1].YUV.v & 0xFF00) ? 0xFF00 : (S[1].YUV.v<<8));
+ }
+ }
+
+ D += 2;
+ S += 2;
+ }
+
+ if (w & 1) {
+ if (!(S->YUV.a & 0xF000) && (*D == Dkey0)) {
+ *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) |
+ ((S->YUV.u & 0xFF00) ? 0xFF00 : (S->YUV.u<<8));
+ }
+ }
+}
+
+static void Sacc_toK_Aop_rgb332( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000) && (*D == Dkey)) {
+ *D = PIXEL_RGB332( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b );
+ }
+
+ D++;
+ S++;
+ }
+}
+
+static void Sacc_toK_Aop_uyvy( GenefxState *gfxs )
+{
+ int l;
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u16 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+#ifdef WORDS_BIGENDIAN
+ u16 Dkey0 = gfxs->Dkey >> 16;
+ u16 Dkey1 = gfxs->Dkey & 0xFFFF;
+#else
+ u16 Dkey0 = gfxs->Dkey & 0xFFFF;
+ u16 Dkey1 = gfxs->Dkey >> 16;
+#endif
+
+ if ((long)D & 2) {
+ if (!(S->YUV.a & 0xF000) && (*D == Dkey1)) {
+ *D = ((S->YUV.v & 0xFF00) ? 0x00FF : S->YUV.v) |
+ ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8));
+ }
+ S++;
+ D++;
+ w--;
+ }
+
+ for (l = w>>1; l--;) {
+ if (*D == Dkey) {
+ if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) {
+ u32 cb, y0, cr, y1;
+
+ y0 = (S[0].YUV.y & 0xFF00) ? 0xFF : S[0].YUV.y;
+ y1 = (S[1].YUV.y & 0xFF00) ? 0xFF : S[1].YUV.y;
+
+ cb = (S[0].YUV.u + S[1].YUV.u) >> 1;
+ if (cb & 0xFF00)
+ cb = 0xFF;
+
+ cr = (S[0].YUV.v + S[1].YUV.v) >> 1;
+ if (cr & 0xFF00)
+ cr = 0xFF;
+
+#ifdef WORDS_BIGENDIAN
+ *((u32*)D) = cr | (y1 << 8) | (cb << 16) | (y0 << 24);
+#else
+ *((u32*)D) = cb | (y0 << 8) | (cr << 16) | (y1 << 24);
+#endif
+ }
+ else if (!(S[0].YUV.a & 0xF000)) {
+ D[0] = ((S[0].YUV.u & 0xFF00) ? 0x00FF : S[0].YUV.u) |
+ ((S[0].YUV.y & 0xFF00) ? 0xFF00 : (S[0].YUV.y<<8));
+ }
+ else if (!(S[1].YUV.a & 0xF000)) {
+ D[1] = ((S[1].YUV.v & 0xFF00) ? 0x00FF : S[1].YUV.v) |
+ ((S[1].YUV.y & 0xFF00) ? 0xFF00 : (S[1].YUV.y<<8));
+ }
+ }
+
+ D += 2;
+ S += 2;
+ }
+
+ if (w & 1) {
+ if (!(S->YUV.a & 0xF000) && (*D == Dkey0)) {
+ *D = ((S->YUV.u & 0xFF00) ? 0x00FF : S->YUV.u) |
+ ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8));
+ }
+ }
+}
+
+static void Sacc_toK_Aop_lut8( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000) && (*D == Dkey)) {
+ *D = dfb_palette_search( gfxs->Alut,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b,
+ (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a );
+ }
+
+ D++;
+ S++;
+ }
+}
+
+static void Sacc_toK_Aop_alut44( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u8 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+
+ while (w--) {
+ if (!(S->RGB.a & 0xF000) && ((*D & 0x0F) == Dkey)) {
+ *D = (S->RGB.a & 0xFF00) ? 0xF0 : (S->RGB.a & 0xF0) +
+ dfb_palette_search( gfxs->Alut,
+ (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r,
+ (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g,
+ (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b,
+ 0x80 );
+ }
+
+ D++;
+ S++;
+ }
+}
+
+static GenefxFunc Sacc_toK_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Sacc_toK_Aop_argb1555, /* DSPF_ARGB1555 */
+ Sacc_toK_Aop_rgb16, /* DSPF_RGB16 */
+ Sacc_toK_Aop_rgb24, /* DSPF_RGB24 */
+ Sacc_toK_Aop_rgb32, /* DSPF_RGB32 */
+ Sacc_toK_Aop_argb, /* DSPF_ARGB */
+ Sacc_toK_Aop_a8, /* DSPF_A8 */
+ Sacc_toK_Aop_yuy2, /* DSPF_YUY2 */
+ Sacc_toK_Aop_rgb332, /* DSPF_RGB332 */
+ Sacc_toK_Aop_uyvy, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ Sacc_toK_Aop_lut8, /* DSPF_LUT8 */
+ Sacc_toK_Aop_alut44, /* DSPF_ALUT44 */
+ Sacc_toK_Aop_airgb, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Sacc_toK_Aop_argb2554, /* DSPF_ARGB2554 */
+ Sacc_toK_Aop_argb4444, /* DSPF_ARGB4444 */
+ Sacc_toK_Aop_rgba4444, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ NULL, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Sacc_toK_Aop_argb1666, /* DSPF_ARGB1666 */
+ Sacc_toK_Aop_argb6666, /* DSPF_ARGB6666 */
+ Sacc_toK_Aop_rgb18, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Sacc_toK_Aop_xrgb4444, /* DSPF_RGB444 */
+ Sacc_toK_Aop_xrgb1555, /* DSPF_RGB555 */
+ Sacc_toK_Aop_xbgr1555, /* DSPF_BGR555 */
+};
+
+/********************************* Sacc_StoK_Aop_PFI **************************/
+
+static GenefxFunc Sacc_StoK_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Sacc_StoK_Aop_argb1555, /* DSPF_ARGB1555 */
+ Sacc_StoK_Aop_rgb16, /* DSPF_RGB16 */
+ NULL, /* DSPF_RGB24 */
+ Sacc_StoK_Aop_rgb32, /* DSPF_RGB32 */
+ Sacc_StoK_Aop_argb, /* DSPF_ARGB */
+ NULL, /* DSPF_A8 */
+ NULL, /* DSPF_YUY2 */
+ NULL, /* DSPF_RGB332 */
+ NULL, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ NULL, /* DSPF_LUT8 */
+ NULL, /* DSPF_ALUT44 */
+ Sacc_StoK_Aop_airgb, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Sacc_StoK_Aop_argb2554, /* DSPF_ARGB2554 */
+ Sacc_StoK_Aop_argb4444, /* DSPF_ARGB4444 */
+ Sacc_StoK_Aop_rgba4444, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ NULL, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ NULL, /* DSPF_ARGB1666 */
+ NULL, /* DSPF_ARGB6666 */
+ NULL, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ Sacc_StoK_Aop_xrgb4444, /* DSPF_RGB444 */
+ Sacc_StoK_Aop_xrgb1555, /* DSPF_RGB555 */
+ Sacc_StoK_Aop_xbgr1555, /* DSPF_BGR555 */
+};
+
+/************** Bop_a8_set_alphapixel_Aop_PFI *********************************/
+
+/* change the last value to adjust the size of the device (1-4) */
+#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \
+ SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 3 )
+
+
+static void Bop_a8_set_alphapixel_Aop_argb1555( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+ u32 rb = Cop & 0x7c1f;
+ u32 g = Cop & 0x03e0;
+
+#define SET_PIXEL(d,a) \
+ switch (a) {\
+ case 0xff: d = Cop;\
+ case 0: break;\
+ default: {\
+ register u32 s = (a>>3)+1;\
+ register u32 t1 = (d & 0x7c1f);\
+ register u32 t2 = (d & 0x03e0);\
+ d = ((d) & 0x8000) | ((a & 0x80) << 8) | \
+ ((((rb-t1)*s+(t1<<5)) & 0x000f83e0) + \
+ ((( g-t2)*s+(t2<<5)) & 0x00007c00)) >> 5;\
+ }\
+ }
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+
+static void Bop_a8_set_alphapixel_Aop_rgb16( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+ u32 rb = Cop & 0xf81f;
+ u32 g = Cop & 0x07e0;
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff: d = Cop;\
+ case 0: break;\
+ default: {\
+ register u32 s = (a>>2)+1;\
+ register u32 t1 = (d & 0xf81f);\
+ register u32 t2 = (d & 0x07e0);\
+ d = ((((rb-t1)*s+(t1<<6)) & 0x003e07c0) + \
+ ((( g-t2)*s+(t2<<6)) & 0x0001f800)) >> 6;\
+ }\
+ }
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+static void Bop_a8_set_alphapixel_Aop_argb6666( GenefxState *gfxs )
+{
+
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+
+ u32 Cop = gfxs->Cop;
+ u32 rb = Cop & 0x3f03f;
+ u32 g = Cop & 0xfc0;
+
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff: d = Cop;\
+ case 0: break;\
+ default: {\
+ register u32 s = (a>>2)+1;\
+ register u32 t1 = (d & 0x3f03f);\
+ register u32 t2 = (d & 0xfc0);\
+ d = ((((rb-t1)*s+(t1<<6)) & 0xfc0fc0) + \
+ ((( g-t2)*s+(t2<<6)) & 0xfc000)) >> 6;\
+ }\
+ }
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+
+}
+
+static void Bop_a8_set_alphapixel_Aop_argb1666( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+
+ u32 Cop = gfxs->Cop;
+ u32 rb = Cop & 0x3f03f;
+ u32 g = Cop & 0xfc0;
+
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff: d = Cop;\
+ case 0: break;\
+ default: {\
+ register u32 s = (a>>2)+1;\
+ register u32 t1 = (d & 0x3f03f);\
+ register u32 t2 = (d & 0xfc0);\
+ d = ((((rb-t1)*s+(t1<<6)) & 0xfc0fc0) + \
+ ((( g-t2)*s+(t2<<6)) & 0xfc000)) >> 6;\
+ }\
+ }
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+static void Bop_a8_set_alphapixel_Aop_rgb18( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+
+ u32 Cop = gfxs->Cop;
+ u32 rb = Cop & 0x3f03f;
+ u32 g = Cop & 0xfc0;
+
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff: d = Cop;\
+ case 0: break;\
+ default: {\
+ register u32 s = (a>>2)+1;\
+ register u32 t1 = (d & 0x3f03f);\
+ register u32 t2 = (d & 0xfc0);\
+ d = ((((rb-t1)*s+(t1<<6)) & 0xfc0fc0) + \
+ ((( g-t2)*s+(t2<<6)) & 0xfc000)) >> 6;\
+ }\
+ }
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+
+}
+
+static void Bop_a8_set_alphapixel_Aop_rgb24( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ DFBColor color = gfxs->color;
+
+#define SET_PIXEL(d,r,g,b,a)\
+ switch (a) {\
+ case 0xff:\
+ d[0] = b;\
+ d[1] = g;\
+ d[2] = r;\
+ case 0: break;\
+ default: {\
+ register u16 s = a+1;\
+ d[0] = ((b-d[0]) * s + (d[0] << 8)) >> 8;\
+ d[1] = ((g-d[1]) * s + (d[1] << 8)) >> 8;\
+ d[2] = ((r-d[2]) * s + (d[2] << 8)) >> 8;\
+ }\
+ }
+
+ while (w>4) {
+ SET_PIXEL( D, color.r, color.g, color.b, *S ); D+=3; S++;
+ SET_PIXEL( D, color.r, color.g, color.b, *S ); D+=3; S++;
+ SET_PIXEL( D, color.r, color.g, color.b, *S ); D+=3; S++;
+ SET_PIXEL( D, color.r, color.g, color.b, *S ); D+=3; S++;
+ w-=4;
+ }
+ while (w--) {
+ SET_PIXEL( D, color.r, color.g, color.b, *S ); D+=3, S++;
+ }
+
+#undef SET_PIXEL
+}
+
+static void Bop_a8_set_alphapixel_Aop_rgb32( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+ u32 rb = Cop & 0xff00ff;
+ u32 g = Cop & 0x00ff00;
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff: d = Cop;\
+ case 0: break;\
+ default: {\
+ register u32 s = a+1;\
+ register u32 t1 = (d & 0x00ff00ff);\
+ register u32 t2 = (d & 0x0000ff00);\
+ d = ((((rb-t1)*s+(t1<<8)) & 0xff00ff00) + \
+ ((( g-t2)*s+(t2<<8)) & 0x00ff0000)) >> 8;\
+ }\
+ }
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+
+/* saturating alpha blend */
+
+static void Bop_a8_set_alphapixel_Aop_argb( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop | 0xff000000;
+ u32 rb = Cop & 0x00ff00ff;
+ u32 g = gfxs->color.g;
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff: d = Cop;\
+ case 0: break;\
+ default: {\
+ register u32 s = a+1;\
+ register u32 s1 = 256-a;\
+ register u32 sa = (((d >> 24) * s1) >> 8) + a;\
+ d = (sa << 24) + \
+ (((((d & 0x00ff00ff) * s1) + (rb * s)) >> 8) & 0x00ff00ff) + \
+ (((((d & 0x0000ff00) >> 8) * s1) + ((g) * s)) & 0x0000ff00); \
+ }\
+ }
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+static void Bop_a8_set_alphapixel_Aop_airgb( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+ u32 rb = Cop & 0x00ff00ff;
+ u32 g = gfxs->color.g;
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff: d = Cop;\
+ case 0: break;\
+ default: {\
+ register u32 s = a+1;\
+ register u32 s1 = 256-s;\
+ register s32 sa = (d >> 24) - a;\
+ if (sa < 0) sa = 0;\
+ d = (sa << 24) + \
+ (((((d & 0x00ff00ff) * s1) + (rb * s)) >> 8) & 0x00ff00ff) + \
+ (((((d & 0x0000ff00) >> 8) * s1) + ((g) * s)) & 0x0000ff00); \
+ }\
+ }
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+static void Bop_a8_set_alphapixel_Aop_a8( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff: d = 0xff;\
+ case 0: break; \
+ default: {\
+ register u16 s1 = 255-a;\
+ d = ((d * s1) >> 8) + a;\
+ }\
+ }
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+static void Bop_a8_set_alphapixel_Aop_yuy2( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u32 y = gfxs->YCop;
+ u32 u = gfxs->CbCop;
+ u32 v = gfxs->CrCop;
+
+#ifdef WORDS_BIGENDIAN
+ u16 Cop0 = u | (y << 8);
+ u16 Cop1 = v | (y << 8);
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff:\
+ d = ((long)&(d) & 2) ? Cop1 : Cop0;\
+ case 0x00: break;\
+ default: {\
+ register u32 s = a+1;\
+ register u32 t1 = d & 0xff;\
+ register u32 t2 = d >> 8;\
+ if ((long)&(d) & 2)\
+ d = (((v-t1)*s+(t1<<8)) >> 8) |\
+ (((y-t2)*s+(t2<<8)) & 0xff00);\
+ else\
+ d = (((u-t1)*s+(t1<<8)) >> 8) |\
+ (((y-t2)*s+(t2<<8)) & 0xff00);\
+ } break;\
+ }
+#else
+ u16 Cop0 = y | (u << 8);
+ u16 Cop1 = y | (v << 8);
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff:\
+ d = ((long)&(d) & 2) ? Cop1 : Cop0;\
+ case 0x00: break;\
+ default: {\
+ register u32 s = a+1;\
+ register u32 t1 = d & 0xff;\
+ register u32 t2 = d >> 8;\
+ if ((long)&(d) & 2)\
+ d = (((y-t1)*s+(t1<<8)) >> 8) |\
+ (((v-t2)*s+(t2<<8)) & 0xff00);\
+ else\
+ d = (((y-t1)*s+(t1<<8)) >> 8) |\
+ (((u-t2)*s+(t2<<8)) & 0xff00);\
+ } break;\
+ }
+#endif
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+static void Bop_a8_set_alphapixel_Aop_rgb332( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+ u32 rgb = ((Cop & 0xe0) << 16) | ((Cop & 0x1c) << 8) | (Cop & 0x03);
+
+#define SET_PIXEL(d,a) \
+ switch (a) {\
+ case 0xff: d = Cop;\
+ case 0: break;\
+ default: {\
+ register u32 s = a + 1;\
+ register u32 t = ((d & 0xe0) << 16) | ((d & 0x1c) << 8) | (d & 0x03);\
+ register u32 c = ((rgb-t)*s + (t<<8)) & 0xe01c0300;\
+ d = (c >> 24) | ((c >> 16) & 0xff) | ((c >> 8) & 0xff);\
+ }\
+ }
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+static void Bop_a8_set_alphapixel_Aop_uyvy( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u32 y = gfxs->YCop;
+ u32 u = gfxs->CbCop;
+ u32 v = gfxs->CrCop;
+ u16 Cop0 = u | (y << 8);
+ u16 Cop1 = v | (y << 8);
+
+#define SET_PIXEL(d,a)\
+ switch (a) {\
+ case 0xff: d = ((long)&(d) & 2) ? Cop1 : Cop0;\
+ case 0x00: break;\
+ default: {\
+ register u32 s = a+1;\
+ register u32 t1 = d & 0xff;\
+ register u32 t2 = d >> 8;\
+ if ((long)&(d) & 2)\
+ d = (((v-t1)*s+(t1<<8)) >> 8) |\
+ (((y-t2)*s+(t2<<8)) & 0xff00);\
+ else\
+ d = (((u-t1)*s+(t1<<8)) >> 8) |\
+ (((y-t2)*s+(t2<<8)) & 0xff00);\
+ } break;\
+ }
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+static void Bop_a8_set_alphapixel_Aop_lut8( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+
+#if 0
+ DFBColor color = gfxs->color;
+ DFBColor *entries = gfxs->Alut->entries;
+
+# define SET_PIXEL(d,alpha) \
+ switch (alpha) {\
+ case 0xff: d = Cop;\
+ case 0: break; \
+ default: {\
+ register u16 s = alpha+1;\
+ DFBColor dc = entries[d];\
+ u16 sa = alpha + dc.a;\
+ dc.r = ((color.r - dc.r) * s + (dc.r << 8)) >> 8;\
+ dc.g = ((color.g - dc.g) * s + (dc.g << 8)) >> 8;\
+ dc.b = ((color.b - dc.b) * s + (dc.b << 8)) >> 8;\
+ d = dfb_palette_search( gfxs->Alut, dc.r, dc.g, dc.b,\
+ sa & 0xff00 ? 0xff : sa );\
+ }\
+ }
+#else
+# define SET_PIXEL(d,a) \
+ if (a & 0x80) \
+ d = Cop;
+#endif
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+
+#undef SET_PIXEL
+}
+
+static void Bop_a8_set_alphapixel_Aop_alut44( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+
+ DFBColor color = gfxs->color;
+ DFBColor *entries = gfxs->Alut->entries;
+
+#define SET_PIXEL(d,alpha) \
+ switch (alpha) {\
+ case 0xff: d = Cop;\
+ case 0: break; \
+ default: {\
+ register u16 s = alpha+1;\
+ DFBColor dc = entries[d & 0x0f];\
+ u16 sa = (d & 0xf0) + alpha;\
+ dc.r = ((color.r - dc.r) * s + (dc.r << 8)) >> 8;\
+ dc.g = ((color.g - dc.g) * s + (dc.g << 8)) >> 8;\
+ dc.b = ((color.b - dc.b) * s + (dc.b << 8)) >> 8;\
+ if (sa & 0xff00) sa = 0xf0;\
+ d = (sa & 0xf0) + \
+ dfb_palette_search( gfxs->Alut, dc.r, dc.g, dc.b, 0x80 );\
+ }\
+ }
+
+ while (w--) {
+ SET_PIXEL( *D, *S );
+ D++, S++;
+ }
+
+#undef SET_PIXEL
+}
+
+#undef SET_PIXEL_DUFFS_DEVICE
+
+static GenefxFunc Bop_a8_set_alphapixel_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_a8_set_alphapixel_Aop_argb1555, /* DSPF_ARGB1555 */
+ Bop_a8_set_alphapixel_Aop_rgb16, /* DSPF_RGB16 */
+ Bop_a8_set_alphapixel_Aop_rgb24, /* DSPF_RGB24 */
+ Bop_a8_set_alphapixel_Aop_rgb32, /* DSPF_RGB32 */
+ Bop_a8_set_alphapixel_Aop_argb, /* DSPF_ARGB */
+ Bop_a8_set_alphapixel_Aop_a8, /* DSPF_A8 */
+ Bop_a8_set_alphapixel_Aop_yuy2, /* DSPF_YUY2 */
+ Bop_a8_set_alphapixel_Aop_rgb332, /* DSPF_RGB332 */
+ Bop_a8_set_alphapixel_Aop_uyvy, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ Bop_a8_set_alphapixel_Aop_lut8, /* DSPF_LUT8 */
+ Bop_a8_set_alphapixel_Aop_alut44, /* DSPF_ALUT44 */
+ Bop_a8_set_alphapixel_Aop_airgb, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ NULL, /* DSPF_ARGB2554 */
+ NULL, /* DSPF_ARGB4444 */
+ NULL, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ Bop_a8_set_alphapixel_Aop_argb, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Bop_a8_set_alphapixel_Aop_argb1666, /* DSPF_ARGB1666 */
+ Bop_a8_set_alphapixel_Aop_argb6666, /* DSPF_ARGB6666 */
+ Bop_a8_set_alphapixel_Aop_rgb18, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ NULL, /* DSPF_ARGB4444 */
+ NULL, /* DSPF_ARGB1555 */
+ NULL /* DSPF_ARGB1555 */
+};
+
+/************** Bop_a1_set_alphapixel_Aop_PFI *********************************/
+
+static void Bop_a1_set_alphapixel_Aop_argb1555( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Cop = gfxs->Cop | 0x8000;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_rgb16( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Cop = gfxs->Cop;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_argb6666( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ DFBColor color = gfxs->color;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7))) {
+ u32 pixel = PIXEL_ARGB6666( color.a, color.r, color.g, color.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D += 3;
+ }
+
+}
+
+static void Bop_a1_set_alphapixel_Aop_argb1666( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ DFBColor color = gfxs->color;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7))) {
+ u32 pixel = PIXEL_ARGB1666( color.a, color.r, color.g, color.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D += 3;
+ }
+
+}
+
+static void Bop_a1_set_alphapixel_Aop_rgb18( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ DFBColor color = gfxs->color;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7))) {
+ u32 pixel = PIXEL_RGB18( color.r, color.g, color.b );
+
+ D[0] = pixel;
+ D[1] = pixel >> 8;
+ D[2] = pixel >> 16;
+ }
+ D += 3;
+ }
+
+}
+
+static void Bop_a1_set_alphapixel_Aop_rgb24( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ DFBColor color = gfxs->color;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7))) {
+ D[0] = color.b;
+ D[1] = color.g;
+ D[2] = color.r;
+ }
+
+ D += 3;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_rgb32( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_argb( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop | 0xFF000000;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_airgb( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop & 0x00FFFFFF;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_a8( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = 0xff;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_yuy2( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Cop0 = gfxs->YCop | (gfxs->CbCop << 8);
+ u16 Cop1 = gfxs->YCop | (gfxs->CrCop << 8);
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7))) {
+ D[i] = ((long)&D[i] & 2) ? Cop1 : Cop0;
+ }
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_rgb332( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ u8 Cop = gfxs->Cop;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_uyvy( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Cop0 = gfxs->CbCop | (gfxs->YCop << 8);
+ u16 Cop1 = gfxs->CrCop | (gfxs->YCop << 8);
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7))) {
+ D[i] = ((long)&D[i] & 2) ? Cop1 : Cop0;
+ }
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_lut8( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ u8 Cop = gfxs->Cop;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_alut44( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+ u8 Cop = gfxs->Cop;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_argb2554( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Cop = gfxs->Cop | 0xC000;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_argb4444( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Cop = gfxs->Cop | 0xF000;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static void Bop_a1_set_alphapixel_Aop_rgba4444( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Cop = gfxs->Cop | 0x000F;
+
+ for (i=0; i<w; i++) {
+ if (S[i>>3] & (0x80 >> (i&7)))
+ D[i] = Cop;
+ }
+}
+
+static GenefxFunc Bop_a1_set_alphapixel_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ Bop_a1_set_alphapixel_Aop_argb1555, /* DSPF_ARGB1555 */
+ Bop_a1_set_alphapixel_Aop_rgb16, /* DSPF_RGB16 */
+ Bop_a1_set_alphapixel_Aop_rgb24, /* DSPF_RGB24 */
+ Bop_a1_set_alphapixel_Aop_rgb32, /* DSPF_RGB32 */
+ Bop_a1_set_alphapixel_Aop_argb, /* DSPF_ARGB */
+ Bop_a1_set_alphapixel_Aop_a8, /* DSPF_A8 */
+ Bop_a1_set_alphapixel_Aop_yuy2, /* DSPF_YUY2 */
+ Bop_a1_set_alphapixel_Aop_rgb332, /* DSPF_RGB332 */
+ Bop_a1_set_alphapixel_Aop_uyvy, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ Bop_a1_set_alphapixel_Aop_lut8, /* DSPF_LUT8 */
+ Bop_a1_set_alphapixel_Aop_alut44, /* DSPF_ALUT44 */
+ Bop_a1_set_alphapixel_Aop_airgb, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ Bop_a1_set_alphapixel_Aop_argb2554, /* DSPF_ARGB2554 */
+ Bop_a1_set_alphapixel_Aop_argb4444, /* DSPF_ARGB4444 */
+ Bop_a1_set_alphapixel_Aop_rgba4444, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ Bop_a1_set_alphapixel_Aop_argb, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ Bop_a1_set_alphapixel_Aop_argb1666, /* DSPF_ARGB1666 */
+ Bop_a1_set_alphapixel_Aop_argb6666, /* DSPF_ARGB6666 */
+ Bop_a1_set_alphapixel_Aop_rgb18, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ NULL, /* DSPF_RGB444 */
+ NULL, /* DSPF_RGB555 */
+ NULL, /* DSPF_BGR555 */
+};
+
+
+/**************************** Bop_translate_to_Aop ****************************/
+
+static void Bop_lut2_translate_to_Aop_lut8( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ int W = (w + 3) / 4;
+ u8 *S = gfxs->Bop[0];
+ u8 *D = gfxs->Aop[0];
+
+ for (i=0; i<W; i++, D+=4, w-=4) {
+ u8 index;
+ u8 pixels = S[i];
+
+ switch (w) {
+ default:
+ index = (pixels & 3);
+ if (index < gfxs->num_trans && gfxs->trans[index] >= 0)
+ D[3] = gfxs->trans[index];
+
+ case 3:
+ index = (pixels >> 2) & 3;
+ if (index < gfxs->num_trans && gfxs->trans[index] >= 0)
+ D[2] = gfxs->trans[index];
+
+ case 2:
+ index = (pixels >> 4) & 3;
+ if (index < gfxs->num_trans && gfxs->trans[index] >= 0)
+ D[1] = gfxs->trans[index];
+
+ case 1:
+ index = (pixels >> 6);
+ if (index < gfxs->num_trans && gfxs->trans[index] >= 0)
+ D[0] = gfxs->trans[index];
+ }
+ }
+}
+
+/********************************* Xacc_blend *********************************/
+
+static void Xacc_blend_zero( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+
+ for (i=0; i<w; i++) {
+ if (!(Y[i].RGB.a & 0xF000))
+ X[i].RGB.a = X[i].RGB.r = X[i].RGB.g = X[i].RGB.b = 0;
+ else
+ X[i] = Y[i];
+ }
+}
+
+static void Xacc_blend_one( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+
+ for (i=0; i<w; i++) {
+ X[i] = Y[i];
+ }
+}
+
+static void Xacc_blend_srccolor( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+
+ if (gfxs->Sacc) {
+ GenefxAccumulator *S = gfxs->Sacc;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ X->RGB.r = ((S->RGB.r + 1) * Y->RGB.r) >> 8;
+ X->RGB.g = ((S->RGB.g + 1) * Y->RGB.g) >> 8;
+ X->RGB.b = ((S->RGB.b + 1) * Y->RGB.b) >> 8;
+ X->RGB.a = ((S->RGB.a + 1) * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ S++;
+ }
+ }
+ else {
+ GenefxAccumulator Cacc = gfxs->Cacc;
+ Cacc.RGB.r = Cacc.RGB.r + 1;
+ Cacc.RGB.g = Cacc.RGB.g + 1;
+ Cacc.RGB.b = Cacc.RGB.b + 1;
+ Cacc.RGB.a = Cacc.RGB.a + 1;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ X->RGB.r = (Cacc.RGB.r * Y->RGB.r) >> 8;
+ X->RGB.g = (Cacc.RGB.g * Y->RGB.g) >> 8;
+ X->RGB.b = (Cacc.RGB.b * Y->RGB.b) >> 8;
+ X->RGB.a = (Cacc.RGB.a * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ }
+ }
+}
+
+static void Xacc_blend_invsrccolor( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+
+ if (gfxs->Sacc) {
+ GenefxAccumulator *S = gfxs->Sacc;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ X->RGB.r = ((0x100 - S->RGB.r) * Y->RGB.r) >> 8;
+ X->RGB.g = ((0x100 - S->RGB.g) * Y->RGB.g) >> 8;
+ X->RGB.b = ((0x100 - S->RGB.b) * Y->RGB.b) >> 8;
+ X->RGB.a = ((0x100 - S->RGB.a) * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ S++;
+ }
+ }
+ else {
+ GenefxAccumulator Cacc = gfxs->Cacc;
+ Cacc.RGB.r = 0x100 - Cacc.RGB.r;
+ Cacc.RGB.g = 0x100 - Cacc.RGB.g;
+ Cacc.RGB.b = 0x100 - Cacc.RGB.b;
+ Cacc.RGB.a = 0x100 - Cacc.RGB.a;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ X->RGB.r = (Cacc.RGB.r * Y->RGB.r) >> 8;
+ X->RGB.g = (Cacc.RGB.g * Y->RGB.g) >> 8;
+ X->RGB.b = (Cacc.RGB.b * Y->RGB.b) >> 8;
+ X->RGB.a = (Cacc.RGB.a * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ }
+ }
+}
+
+static void Xacc_blend_srcalpha( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+
+ if (gfxs->Sacc) {
+ GenefxAccumulator *S = gfxs->Sacc;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ register u16 Sa = S->RGB.a + 1;
+
+ X->RGB.r = (Sa * Y->RGB.r) >> 8;
+ X->RGB.g = (Sa * Y->RGB.g) >> 8;
+ X->RGB.b = (Sa * Y->RGB.b) >> 8;
+ X->RGB.a = (Sa * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ S++;
+ }
+ }
+ else {
+ register u16 Sa = gfxs->color.a + 1;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ X->RGB.r = (Sa * Y->RGB.r) >> 8;
+ X->RGB.g = (Sa * Y->RGB.g) >> 8;
+ X->RGB.b = (Sa * Y->RGB.b) >> 8;
+ X->RGB.a = (Sa * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ }
+ }
+}
+
+static void Xacc_blend_invsrcalpha( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+
+ if (gfxs->Sacc) {
+ GenefxAccumulator *S = gfxs->Sacc;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ register u16 Sa = 0x100 - S->RGB.a;
+
+ X->RGB.r = (Sa * Y->RGB.r) >> 8;
+ X->RGB.g = (Sa * Y->RGB.g) >> 8;
+ X->RGB.b = (Sa * Y->RGB.b) >> 8;
+ X->RGB.a = (Sa * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ S++;
+ }
+ }
+ else {
+ register u16 Sa = 0x100 - gfxs->color.a;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ X->RGB.a = (Sa * Y->RGB.a) >> 8;
+ X->RGB.r = (Sa * Y->RGB.r) >> 8;
+ X->RGB.g = (Sa * Y->RGB.g) >> 8;
+ X->RGB.b = (Sa * Y->RGB.b) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ }
+ }
+}
+
+static void Xacc_blend_dstalpha( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ register u16 Da = D->RGB.a + 1;
+
+ X->RGB.r = (Da * Y->RGB.r) >> 8;
+ X->RGB.g = (Da * Y->RGB.g) >> 8;
+ X->RGB.b = (Da * Y->RGB.b) >> 8;
+ X->RGB.a = (Da * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ D++;
+ }
+}
+
+static void Xacc_blend_invdstalpha( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ register u16 Da = 0x100 - D->RGB.a;
+
+ X->RGB.r = (Da * Y->RGB.r) >> 8;
+ X->RGB.g = (Da * Y->RGB.g) >> 8;
+ X->RGB.b = (Da * Y->RGB.b) >> 8;
+ X->RGB.a = (Da * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ D++;
+ }
+}
+
+static void Xacc_blend_destcolor( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ X->RGB.r = ((D->RGB.r + 1) * Y->RGB.r) >> 8;
+ X->RGB.g = ((D->RGB.g + 1) * Y->RGB.g) >> 8;
+ X->RGB.b = ((D->RGB.b + 1) * Y->RGB.b) >> 8;
+ X->RGB.a = ((D->RGB.a + 1) * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ D++;
+ }
+}
+
+static void Xacc_blend_invdestcolor( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ X->RGB.r = ((0x100 - D->RGB.r) * Y->RGB.r) >> 8;
+ X->RGB.g = ((0x100 - D->RGB.g) * Y->RGB.g) >> 8;
+ X->RGB.b = ((0x100 - D->RGB.b) * Y->RGB.b) >> 8;
+ X->RGB.a = ((0x100 - D->RGB.a) * Y->RGB.a) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ D++;
+ }
+}
+
+static void Xacc_blend_srcalphasat( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ if (gfxs->Sacc) {
+ GenefxAccumulator *S = gfxs->Sacc;
+
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ register u16 Sa = MIN( S->RGB.a + 1, 0x100 - D->RGB.a );
+
+ X->RGB.a = Y->RGB.a;
+ X->RGB.r = (Sa * Y->RGB.r) >> 8;
+ X->RGB.g = (Sa * Y->RGB.g) >> 8;
+ X->RGB.b = (Sa * Y->RGB.b) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ D++;
+ S++;
+ }
+ }
+ else {
+ while (w--) {
+ if (!(Y->RGB.a & 0xF000)) {
+ register u16 Sa = MIN( gfxs->color.a + 1, 0x100 - D->RGB.a );
+
+ X->RGB.a = Y->RGB.a;
+ X->RGB.r = (Sa * Y->RGB.r) >> 8;
+ X->RGB.g = (Sa * Y->RGB.g) >> 8;
+ X->RGB.b = (Sa * Y->RGB.b) >> 8;
+ } else
+ *X = *Y;
+
+ X++;
+ Y++;
+ D++;
+ }
+ }
+}
+
+static GenefxFunc Xacc_blend[] = {
+ Xacc_blend_zero, /* DSBF_ZERO */
+ Xacc_blend_one, /* DSBF_ONE */
+ Xacc_blend_srccolor, /* DSBF_SRCCOLOR */
+ Xacc_blend_invsrccolor, /* DSBF_INVSRCCOLOR */
+ Xacc_blend_srcalpha, /* DSBF_SRCALPHA */
+ Xacc_blend_invsrcalpha, /* DSBF_INVSRCALPHA */
+ Xacc_blend_dstalpha, /* DSBF_DESTALPHA */
+ Xacc_blend_invdstalpha, /* DSBF_INVDESTALPHA */
+ Xacc_blend_destcolor, /* DSBF_DESTCOLOR */
+ Xacc_blend_invdestcolor, /* DSBF_INVDESTCOLOR */
+ Xacc_blend_srcalphasat /* DSBF_SRCALPHASAT */
+};
+
+/********************************* Dacc_modulation ****************************/
+
+static void Dacc_set_alpha( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ int a = gfxs->color.a;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->RGB.a = a;
+ }
+
+ D++;
+ }
+}
+
+static void Dacc_modulate_alpha( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ int a = gfxs->Cacc.RGB.a;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->RGB.a = (a * D->RGB.a) >> 8;
+ }
+
+ D++;
+ }
+}
+
+static void Dacc_modulate_rgb( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ GenefxAccumulator Cacc = gfxs->Cacc;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->RGB.r = (Cacc.RGB.r * D->RGB.r) >> 8;
+ D->RGB.g = (Cacc.RGB.g * D->RGB.g) >> 8;
+ D->RGB.b = (Cacc.RGB.b * D->RGB.b) >> 8;
+ }
+
+ D++;
+ }
+}
+
+static void Dacc_modulate_rgb_set_alpha( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ GenefxAccumulator Cacc = gfxs->Cacc;
+ int a = gfxs->color.a;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->RGB.a = a;
+ D->RGB.r = (Cacc.RGB.r * D->RGB.r) >> 8;
+ D->RGB.g = (Cacc.RGB.g * D->RGB.g) >> 8;
+ D->RGB.b = (Cacc.RGB.b * D->RGB.b) >> 8;
+ }
+
+ D++;
+ }
+}
+
+static void Dacc_modulate_argb( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ GenefxAccumulator Cacc = gfxs->Cacc;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->RGB.a = (Cacc.RGB.a * D->RGB.a) >> 8;
+ D->RGB.r = (Cacc.RGB.r * D->RGB.r) >> 8;
+ D->RGB.g = (Cacc.RGB.g * D->RGB.g) >> 8;
+ D->RGB.b = (Cacc.RGB.b * D->RGB.b) >> 8;
+ }
+
+ D++;
+ }
+}
+
+static GenefxFunc Dacc_modulation[] = {
+ NULL,
+ NULL,
+ Dacc_set_alpha,
+ Dacc_modulate_alpha,
+ Dacc_modulate_rgb,
+ Dacc_modulate_rgb,
+ Dacc_modulate_rgb_set_alpha,
+ Dacc_modulate_argb
+};
+
+/********************************* misc accumulator operations ****************/
+
+static void Dacc_premultiply( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ register u16 Da = D->RGB.a + 1;
+
+ D->RGB.r = (Da * D->RGB.r) >> 8;
+ D->RGB.g = (Da * D->RGB.g) >> 8;
+ D->RGB.b = (Da * D->RGB.b) >> 8;
+ }
+
+ D++;
+ }
+}
+
+static void Dacc_premultiply_color_alpha( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ register u16 Ca = gfxs->Cacc.RGB.a;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->RGB.r = (Ca * D->RGB.r) >> 8;
+ D->RGB.g = (Ca * D->RGB.g) >> 8;
+ D->RGB.b = (Ca * D->RGB.b) >> 8;
+ }
+
+ D++;
+ }
+}
+
+static void Dacc_demultiply( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ register u16 Da = D->RGB.a + 1;
+
+ D->RGB.r = (D->RGB.r << 8) / Da;
+ D->RGB.g = (D->RGB.g << 8) / Da;
+ D->RGB.b = (D->RGB.b << 8) / Da;
+ }
+
+ D++;
+ }
+}
+
+static void Dacc_xor_C( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ DFBColor color = gfxs->color;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->RGB.a ^= color.a;
+ D->RGB.r ^= color.r;
+ D->RGB.g ^= color.g;
+ D->RGB.b ^= color.b;
+ }
+
+ D++;
+ }
+}
+
+static GenefxFunc Dacc_xor = Dacc_xor_C;
+
+static void Sacc_xor_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->RGB.a ^= S->RGB.a;
+ D->RGB.r ^= S->RGB.r;
+ D->RGB.g ^= S->RGB.g;
+ D->RGB.b ^= S->RGB.b;
+ }
+ D++;
+ S++;
+ }
+}
+
+static void Cacc_to_Dacc( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ GenefxAccumulator Cacc = gfxs->Cacc;
+
+ while (w--)
+ *D++ = Cacc;
+}
+
+static void SCacc_add_to_Dacc_C( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ GenefxAccumulator SCacc = gfxs->SCacc;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->RGB.a += SCacc.RGB.a;
+ D->RGB.r += SCacc.RGB.r;
+ D->RGB.g += SCacc.RGB.g;
+ D->RGB.b += SCacc.RGB.b;
+ }
+ D++;
+ }
+}
+
+static GenefxFunc SCacc_add_to_Dacc = SCacc_add_to_Dacc_C;
+
+static void Sacc_add_to_Dacc_C( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->RGB.a += S->RGB.a;
+ D->RGB.r += S->RGB.r;
+ D->RGB.g += S->RGB.g;
+ D->RGB.b += S->RGB.b;
+ }
+ D++;
+ S++;
+ }
+}
+
+static GenefxFunc Sacc_add_to_Dacc = Sacc_add_to_Dacc_C;
+
+/**********************************************************************************************************************/
+
+/* change the last value to adjust the size of the device (1-4) */
+#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \
+ SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 3 )
+
+#define SET_PIXEL( D, S ) \
+ if (!(S.RGB.a & 0xF000)) { \
+ RGB_TO_YCBCR( S.RGB.r, S.RGB.g, S.RGB.b, \
+ D.YUV.y, D.YUV.u, D.YUV.v ); \
+ }
+
+static void Dacc_RGB_to_YCbCr_C( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ GenefxAccumulator *S = gfxs->Dacc;
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+}
+
+#undef SET_PIXEL_DUFFS_DEVICE
+#undef SET_PIXEL
+
+static GenefxFunc Dacc_RGB_to_YCbCr = Dacc_RGB_to_YCbCr_C;
+
+/**********************************************************************************************************************/
+
+/* change the last value to adjust the size of the device (1-4) */
+#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \
+ SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 2 )
+
+#define SET_PIXEL( D, S ) \
+ if (!(S.YUV.a & 0xF000)) { \
+ YCBCR_TO_RGB( S.YUV.y, S.YUV.u, S.YUV.v, \
+ D.RGB.r, D.RGB.g, D.RGB.b ); \
+ }
+
+static void Dacc_YCbCr_to_RGB_C( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+ GenefxAccumulator *S = gfxs->Dacc;
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+}
+
+#undef SET_PIXEL_DUFFS_DEVICE
+#undef SET_PIXEL
+
+static GenefxFunc Dacc_YCbCr_to_RGB = Dacc_YCbCr_to_RGB_C;
+
+/**********************************************************************************************************************/
+
+/* change the last value to adjust the size of the device (1-4) */
+#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \
+ SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 3 )
+
+#define SET_PIXEL( D, S ) \
+ switch (S >> 26) { \
+ case 0: \
+ break; \
+ case 0x3f: \
+ D = RGB32_TO_RGB16( S ); \
+ break; \
+ default: \
+ D = (((( (((S>>8) & 0xf800) | ((S>>3) & 0x001f)) \
+ - (D & 0xf81f)) * ((S>>26)+1) + ((D & 0xf81f)<<6)) & 0x003e07c0) \
+ + \
+ ((( ((S>>5) & 0x07e0) \
+ - (D & 0x07e0)) * ((S>>26)+1) + ((D & 0x07e0)<<6)) & 0x0001f800)) >> 6; \
+ } while (0)
+
+static void Bop_argb_blend_alphachannel_src_invsrc_Aop_rgb16( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u32 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+}
+
+#undef SET_PIXEL_DUFFS_DEVICE
+#undef SET_PIXEL
+
+static void Bop_argb_blend_alphachannel_src_invsrc_Aop_rgb32( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ int Dstep = gfxs->Astep;
+ u32 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+
+ while (w--) {
+ u32 dp32 = *D;
+ u32 sp32 = *S++;
+ int salpha = (sp32 >> 25) + 1;
+
+#define rb (sp32 & 0xff00ff)
+#define g (sp32 & 0x00ff00)
+
+ *D = ((((rb-(dp32 & 0xff00ff))*salpha+((dp32 & 0xff00ff)<<7)) & 0x7f807f80) +
+ ((( g-(dp32 & 0x00ff00))*salpha+((dp32 & 0x00ff00)<<7)) & 0x007f8000)) >> 7;
+ D += Dstep;
+
+#undef rb
+#undef g
+ }
+}
+
+static GenefxFunc Bop_argb_blend_alphachannel_src_invsrc_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ NULL, /* DSPF_ARGB1555 */
+ Bop_argb_blend_alphachannel_src_invsrc_Aop_rgb16, /* DSPF_RGB16 */
+ NULL, /* DSPF_RGB24 */
+ Bop_argb_blend_alphachannel_src_invsrc_Aop_rgb32, /* DSPF_RGB32 */
+ NULL, /* DSPF_ARGB */
+ NULL, /* DSPF_A8 */
+ NULL, /* DSPF_YUY2 */
+ NULL, /* DSPF_RGB332 */
+ NULL, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ NULL, /* DSPF_LUT8 */
+ NULL, /* DSPF_ALUT44 */
+ NULL, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ NULL, /* DSPF_ARGB2554 */
+ NULL, /* DSPF_ARGB4444 */
+ NULL, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ NULL, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ NULL, /* DSPF_ARGB1666 */
+ NULL, /* DSPF_ARGB6666 */
+ NULL, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ NULL, /* DSPF_RGB444 */
+ NULL, /* DSPF_RGB555 */
+ NULL /* DSPF_BGR555 */
+};
+
+/**********************************************************************************************************************/
+
+/* change the last value to adjust the size of the device (1-4) */
+#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \
+ SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 3 )
+
+#define SET_PIXEL( D, S ) \
+do { \
+ int invsrc = 256 - (S >> 24); \
+ \
+ u32 Drb = ((D & 0x00ff00ff) * invsrc) >> 8; \
+ u32 Dag = ((D & 0xff00ff00) >> 8) * invsrc; \
+ \
+ D = S + (Drb & 0x00ff00ff) + (Dag & 0xff00ff00); \
+} while (0)
+
+static void Bop_argb_blend_alphachannel_one_invsrc_Aop_argb( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u32 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+
+ SET_PIXEL_DUFFS_DEVICE( D, S, w );
+}
+
+#undef SET_PIXEL_DUFFS_DEVICE
+#undef SET_PIXEL
+
+static GenefxFunc Bop_argb_blend_alphachannel_one_invsrc_Aop_PFI[DFB_NUM_PIXELFORMATS] = {
+ NULL, /* DSPF_ARGB1555 */
+ NULL, /* DSPF_RGB16 */
+ NULL, /* DSPF_RGB24 */
+ Bop_argb_blend_alphachannel_one_invsrc_Aop_argb, /* DSPF_RGB32 */
+ Bop_argb_blend_alphachannel_one_invsrc_Aop_argb, /* DSPF_ARGB */
+ NULL, /* DSPF_A8 */
+ NULL, /* DSPF_YUY2 */
+ NULL, /* DSPF_RGB332 */
+ NULL, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ NULL, /* DSPF_LUT8 */
+ NULL, /* DSPF_ALUT44 */
+ NULL, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ NULL, /* DSPF_ARGB2554 */
+ NULL, /* DSPF_ARGB4444 */
+ NULL, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ NULL, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ NULL, /* DSPF_ARGB1666 */
+ NULL, /* DSPF_ARGB6666 */
+ NULL, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ NULL, /* DSPF_RGB444 */
+ NULL, /* DSPF_RGB555 */
+ NULL /* DSPF_BGR555 */
+};
+
+/**********************************************************************************************************************/
+
+/* A8/A1 to YCbCr */
+static void Dacc_Alpha_to_YCbCr( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ while (w--) {
+ if (!(D->RGB.a & 0xF000)) {
+ D->YUV.y = 235;
+ D->YUV.u = 128;
+ D->YUV.v = 128;
+ }
+
+ D++;
+ }
+}
+
+/**********************************************************************************************************************/
+
+static void Sop_is_Aop( GenefxState *gfxs ) { gfxs->Sop = gfxs->Aop; gfxs->Ostep = gfxs->Astep; }
+static void Sop_is_Bop( GenefxState *gfxs ) { gfxs->Sop = gfxs->Bop; gfxs->Ostep = gfxs->Bstep; }
+
+static void Slut_is_Alut( GenefxState *gfxs ) { gfxs->Slut = gfxs->Alut;}
+static void Slut_is_Blut( GenefxState *gfxs ) { gfxs->Slut = gfxs->Blut;}
+
+static void Sacc_is_NULL( GenefxState *gfxs ) { gfxs->Sacc = NULL;}
+static void Sacc_is_Aacc( GenefxState *gfxs ) { gfxs->Sacc = gfxs->Aacc;}
+static void Sacc_is_Bacc( GenefxState *gfxs ) { gfxs->Sacc = gfxs->Bacc;}
+static void Sacc_is_Tacc( GenefxState *gfxs ) { gfxs->Sacc = gfxs->Tacc;}
+
+static void Dacc_is_Aacc( GenefxState *gfxs ) { gfxs->Dacc = gfxs->Aacc;}
+static void Dacc_is_Bacc( GenefxState *gfxs ) { gfxs->Dacc = gfxs->Bacc;}
+
+static void Xacc_is_Aacc( GenefxState *gfxs ) { gfxs->Xacc = gfxs->Aacc;}
+static void Xacc_is_Bacc( GenefxState *gfxs ) { gfxs->Xacc = gfxs->Bacc;}
+static void Xacc_is_Tacc( GenefxState *gfxs ) { gfxs->Xacc = gfxs->Tacc;}
+
+static void Yacc_is_Aacc( GenefxState *gfxs ) { gfxs->Yacc = gfxs->Aacc;}
+static void Yacc_is_Bacc( GenefxState *gfxs ) { gfxs->Yacc = gfxs->Bacc;}
+
+static void Len_is_Slen( GenefxState *gfxs ) { gfxs->length = gfxs->Slen;}
+static void Len_is_Dlen( GenefxState *gfxs ) { gfxs->length = gfxs->Dlen;}
+
+/******************************************************************************/
+
+#ifdef USE_MMX
+static bool has_mmx( void )
+{
+#ifdef ARCH_X86_64
+ return true;
+#else
+ u32 a, b, c, d;
+
+ asm( "pushfl \n"
+ "pushfl \n"
+ "popl %0 \n"
+ "movl %0, %1 \n"
+ "xorl $0x200000, %0 \n"
+ "pushl %0 \n"
+ "popfl \n"
+ "pushfl \n"
+ "popl %0 \n"
+ "popfl"
+ : "=a" (a), "=r" (b)
+ :
+ : "cc" );
+
+ if (a == b)
+ return false;
+
+ asm( "pushl %%ebx \n"
+ "cpuid \n"
+ "movl %%ebx, %1 \n"
+ "popl %%ebx"
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d)
+ : "a" (0)
+ : "cc" );
+
+ if (!a)
+ return false;
+
+ asm( "pushl %%ebx \n"
+ "cpuid \n"
+ "movl %%ebx, %1 \n"
+ "popl %%ebx"
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d)
+ : "a" (1)
+ : "cc" );
+
+ return (d & 0x800000) ? true : false;
+#endif /* !ARCH_X86_64 */
+}
+#endif
+
+void gGetDriverInfo( GraphicsDriverInfo *info )
+{
+ snprintf( info->name,
+ DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH, "Software Driver" );
+
+#if SIZEOF_LONG == 8
+ gInit_64bit();
+#endif
+
+#ifdef USE_MMX
+ if (has_mmx()) {
+ if (!dfb_config->mmx) {
+ D_INFO( "DirectFB/Genefx: MMX detected, but disabled by option 'no-mmx'\n");
+ }
+ else {
+ gInit_MMX();
+
+ snprintf( info->name, DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH,
+ "MMX Software Driver" );
+
+ D_INFO( "DirectFB/Genefx: MMX detected and enabled\n");
+ }
+ }
+ else {
+ D_INFO( "DirectFB/Genefx: No MMX detected\n" );
+ }
+#endif
+
+ snprintf( info->vendor, DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH, "directfb.org" );
+
+ info->version.major = 0;
+ info->version.minor = 6;
+}
+
+void gGetDeviceInfo( GraphicsDeviceInfo *info )
+{
+ snprintf( info->name, DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH,
+ "Software Rasterizer" );
+
+ snprintf( info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH,
+ use_mmx ? "MMX" : "Generic" );
+
+ info->caps.accel = DFXL_NONE;
+ info->caps.flags = 0;
+ info->caps.drawing = DSDRAW_NOFX;
+ info->caps.blitting = DSBLIT_NOFX;
+}
+
+#define MODULATION_FLAGS (DSBLIT_BLEND_ALPHACHANNEL | \
+ DSBLIT_BLEND_COLORALPHA | \
+ DSBLIT_COLORIZE | \
+ DSBLIT_DST_PREMULTIPLY | \
+ DSBLIT_SRC_PREMULTIPLY | \
+ DSBLIT_SRC_PREMULTCOLOR | \
+ DSBLIT_DEMULTIPLY | \
+ DSBLIT_XOR)
+
+#ifndef WORDS_BIGENDIAN
+#define BGR_TO_RGB16(pixel) ( (((pixel) << 8) & 0xF800) | \
+ (((pixel) >> 5) & 0x07E0) | \
+ (((pixel) >> 19) & 0x001F) )
+
+/*
+ * Fast RGB24 to RGB16 conversion.
+ */
+static void
+Bop_rgb24_to_Aop_rgb16_LE( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u8 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+
+ while ((unsigned long)S & 3) {
+ *D++ = PIXEL_RGB16( S[0], S[1], S[2] );
+
+ S += 3;
+ w -= 1;
+ }
+
+ if ((unsigned long)D & 2) {
+ *D++ = PIXEL_RGB16( S[0], S[1], S[2] );
+
+ w -= 1;
+ S += 3;
+
+ while (w > 1) {
+ *(u32*)D = PIXEL_RGB16( S[0], S[1], S[2] ) | (PIXEL_RGB16( S[3], S[4], S[5] ) << 16);
+
+ w -= 2;
+ D += 2;
+ S += 6;
+ }
+ }
+ else {
+ u32 *S32 = (u32*)S;
+ u32 *D32 = (u32*)D;
+
+ while (w > 3) {
+ D32[0] = BGR_TO_RGB16( S32[0] ) | (BGR_TO_RGB16( (S32[0] >> 24) | (S32[1] << 8) ) << 16);
+ D32[1] = BGR_TO_RGB16( (S32[1] >> 16) | (S32[2] << 16) ) | (BGR_TO_RGB16( S32[2] >> 8 ) << 16);
+
+ D32 += 2;
+ S32 += 3;
+ w -= 4;
+ }
+
+ S = (u8*) S32;
+ D = (u16*) D32;
+ }
+
+ while (w > 0) {
+ *D++ = PIXEL_RGB16( S[0], S[1], S[2] );
+
+ w -= 1;
+ S += 3;
+ }
+}
+
+/*
+ * Fast RGB32 to RGB16 conversion.
+ */
+static void
+Bop_rgb32_to_Aop_rgb16_LE( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u32 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+
+ if ((unsigned long)D & 2) {
+ u16 *d = (u16*)D;
+
+ d[0] = RGB32_TO_RGB16( S[0] );
+
+ w--;
+ S++;
+
+ D = (u32*)(d+1);
+ }
+
+ while (w > 1) {
+ D[0] = RGB32_TO_RGB16( S[0] ) | (RGB32_TO_RGB16( S[1] ) << 16);
+
+ w -= 2;
+ S += 2;
+ D += 1;
+ }
+
+ if (w > 0) {
+ u16 *d = (u16*)D;
+
+ d[0] = RGB32_TO_RGB16( S[0] );
+ }
+}
+#endif /* #ifndef WORDS_BIGENDIAN */
+
+bool gAcquire( CardState *state, DFBAccelerationMask accel )
+{
+ DFBResult ret;
+ GenefxState *gfxs;
+ GenefxFunc *funcs;
+ int dst_pfi;
+ int src_pfi = 0;
+ CoreSurface *destination = state->destination;
+ CoreSurface *source = state->source;
+ DFBColor color = state->color;
+ bool src_ycbcr = false;
+ bool dst_ycbcr = false;
+
+ CoreSurfaceAccessFlags access = CSAF_WRITE;
+
+ if (dfb_config->hardware_only) {
+ if (dfb_config->software_warn) {
+ if (DFB_BLITTING_FUNCTION( accel ))
+ D_WARN( "Ignoring blit (%x) from %s to %s, flags 0x%08x, funcs %d %d", accel,
+ source ? dfb_pixelformat_name(source->config.format) : "NULL SOURCE",
+ destination ? dfb_pixelformat_name(destination->config.format) : "NULL DESTINATION",
+ state->blittingflags, state->src_blend, state->dst_blend );
+ else
+ D_WARN( "Ignoring draw (%x) to %s, flags 0x%08x", accel,
+ destination ? dfb_pixelformat_name(destination->config.format) : "NULL DESTINATION",
+ state->drawingflags );
+ }
+
+ return false;
+ }
+
+ if (!state->gfxs) {
+ gfxs = D_CALLOC( 1, sizeof(GenefxState) );
+ if (!gfxs) {
+ D_ERROR( "DirectFB/Genefx: Couldn't allocate state struct!\n" );
+ return false;
+ }
+
+ state->gfxs = gfxs;
+ }
+
+ gfxs = state->gfxs;
+ funcs = gfxs->funcs;
+
+ /* Destination may have been destroyed. */
+ if (!destination)
+ return false;
+
+ /* Source may have been destroyed. */
+ if (DFB_BLITTING_FUNCTION( accel ) && !source)
+ return false;
+
+ /*
+ * Destination setup
+ */
+
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL |
+ DSBLIT_BLEND_COLORALPHA |
+ DSBLIT_DST_COLORKEY))
+ access |= CSAF_READ;
+ }
+ else if (state->drawingflags & (DSDRAW_BLEND | DSDRAW_DST_COLORKEY))
+ access |= CSAF_READ;
+
+ /* Lock destination */
+ ret = dfb_surface_lock_buffer( destination, state->to, CSAID_CPU, access, &state->dst );
+ if (ret) {
+ D_DERROR( ret, "DirectFB/Genefx: Could not lock destination!\n" );
+ return false;
+ }
+
+ gfxs->dst_caps = destination->config.caps;
+ gfxs->dst_height = destination->config.size.h;
+ gfxs->dst_format = destination->config.format;
+ gfxs->dst_bpp = DFB_BYTES_PER_PIXEL( gfxs->dst_format );
+ dst_pfi = DFB_PIXELFORMAT_INDEX( gfxs->dst_format );
+
+ gfxs->dst_org[0] = state->dst.addr;
+ gfxs->dst_pitch = state->dst.pitch;
+
+ switch (gfxs->dst_format) {
+ case DSPF_I420:
+ gfxs->dst_org[1] = gfxs->dst_org[0] + gfxs->dst_height * gfxs->dst_pitch;
+ gfxs->dst_org[2] = gfxs->dst_org[1] + gfxs->dst_height/2 * gfxs->dst_pitch/2;
+ break;
+ case DSPF_YV12:
+ gfxs->dst_org[2] = gfxs->dst_org[0] + gfxs->dst_height * gfxs->dst_pitch;
+ gfxs->dst_org[1] = gfxs->dst_org[2] + gfxs->dst_height/2 * gfxs->dst_pitch/2;
+ break;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ case DSPF_NV16:
+ gfxs->dst_org[1] = gfxs->dst_org[0] + gfxs->dst_height * gfxs->dst_pitch;
+ break;
+ default:
+ break;
+ }
+
+ gfxs->dst_field_offset = gfxs->dst_height/2 * gfxs->dst_pitch;
+
+
+ /*
+ * Source setup
+ */
+
+ if (DFB_BLITTING_FUNCTION( accel )) {
+#if FIXME_SC_3
+ DFBSurfaceLockFlags flags = DSLF_READ;
+
+ if (accel == DFXL_STRETCHBLIT)
+ flags |= CSLF_FORCE;
+#endif
+
+ /* Lock source */
+ ret = dfb_surface_lock_buffer( source, state->from, CSAID_CPU, CSAF_READ, &state->src );
+ if (ret) {
+ D_DERROR( ret, "DirectFB/Genefx: Could not lock source!\n" );
+ dfb_surface_unlock_buffer( destination, &state->dst );
+ return false;
+ }
+
+ gfxs->src_caps = source->config.caps;
+ gfxs->src_height = source->config.size.h;
+ gfxs->src_format = source->config.format;
+ gfxs->src_bpp = DFB_BYTES_PER_PIXEL( gfxs->src_format );
+ src_pfi = DFB_PIXELFORMAT_INDEX( gfxs->src_format );
+
+ gfxs->src_org[0] = state->src.addr;
+ gfxs->src_pitch = state->src.pitch;
+
+ switch (gfxs->src_format) {
+ case DSPF_I420:
+ gfxs->src_org[1] = gfxs->src_org[0] + gfxs->src_height * gfxs->src_pitch;
+ gfxs->src_org[2] = gfxs->src_org[1] + gfxs->src_height/2 * gfxs->src_pitch/2;
+ break;
+ case DSPF_YV12:
+ gfxs->src_org[2] = gfxs->src_org[0] + gfxs->src_height * gfxs->src_pitch;
+ gfxs->src_org[1] = gfxs->src_org[2] + gfxs->src_height/2 * gfxs->src_pitch/2;
+ break;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ case DSPF_NV16:
+ gfxs->src_org[1] = gfxs->src_org[0] + gfxs->src_height * gfxs->src_pitch;
+ break;
+ default:
+ break;
+ }
+
+ gfxs->src_field_offset = gfxs->src_height/2 * gfxs->src_pitch;
+
+ state->flags |= CSF_SOURCE_LOCKED;
+ }
+
+
+ /* premultiply source (color) */
+ if (DFB_DRAWING_FUNCTION(accel) && (state->drawingflags & DSDRAW_SRC_PREMULTIPLY)) {
+ u16 ca = color.a + 1;
+
+ color.r = (color.r * ca) >> 8;
+ color.g = (color.g * ca) >> 8;
+ color.b = (color.b * ca) >> 8;
+ }
+
+
+ gfxs->color = color;
+
+
+ switch (gfxs->dst_format) {
+ case DSPF_ARGB1555:
+ gfxs->Cop = PIXEL_ARGB1555( color.a, color.r, color.g, color.b );
+ break;
+ case DSPF_RGB16:
+ gfxs->Cop = PIXEL_RGB16( color.r, color.g, color.b );
+ break;
+ case DSPF_RGB18:
+ gfxs->Cop = PIXEL_RGB18( color.r, color.g, color.b );
+ break;
+ case DSPF_RGB24:
+ gfxs->Cop = PIXEL_RGB32( color.r, color.g, color.b );
+ break;
+ case DSPF_RGB32:
+ gfxs->Cop = PIXEL_RGB32( color.r, color.g, color.b );
+ break;
+ case DSPF_ARGB:
+ gfxs->Cop = PIXEL_ARGB( color.a, color.r, color.g, color.b );
+ break;
+ case DSPF_AiRGB:
+ gfxs->Cop = PIXEL_AiRGB( color.a, color.r, color.g, color.b );
+ break;
+ case DSPF_ARGB6666:
+ gfxs->Cop = PIXEL_ARGB6666( color.a, color.r, color.g, color.b );
+ break;
+ case DSPF_ARGB1666:
+ gfxs->Cop = PIXEL_ARGB1666( color.a, color.r, color.g, color.b );
+ break;
+ case DSPF_A1:
+ gfxs->Cop = color.a >> 7;
+ break;
+ case DSPF_A4:
+ gfxs->Cop = color.a >> 4;
+ break;
+ case DSPF_A8:
+ gfxs->Cop = color.a;
+ break;
+ case DSPF_YUY2:
+ RGB_TO_YCBCR( color.r, color.g, color.b,
+ gfxs->YCop, gfxs->CbCop, gfxs->CrCop );
+ gfxs->Cop = PIXEL_YUY2( gfxs->YCop, gfxs->CbCop, gfxs->CrCop );
+ dst_ycbcr = true;
+ break;
+ case DSPF_RGB332:
+ gfxs->Cop = PIXEL_RGB332( color.r, color.g, color.b );
+ break;
+ case DSPF_UYVY:
+ RGB_TO_YCBCR( color.r, color.g, color.b,
+ gfxs->YCop, gfxs->CbCop, gfxs->CrCop );
+ gfxs->Cop = PIXEL_UYVY( gfxs->YCop, gfxs->CbCop, gfxs->CrCop );
+ dst_ycbcr = true;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ case DSPF_NV12:
+ case DSPF_NV16:
+ RGB_TO_YCBCR( color.r, color.g, color.b,
+ gfxs->YCop, gfxs->CbCop, gfxs->CrCop );
+ gfxs->Cop = gfxs->YCop;
+ dst_ycbcr = true;
+ break;
+ case DSPF_NV21:
+ RGB_TO_YCBCR( color.r, color.g, color.b,
+ gfxs->YCop, gfxs->CrCop, gfxs->CbCop );
+ gfxs->Cop = gfxs->YCop;
+ dst_ycbcr = true;
+ break;
+ case DSPF_LUT2:
+ case DSPF_LUT8:
+ gfxs->Cop = state->color_index;
+ gfxs->Alut = destination->palette;
+ break;
+ case DSPF_ALUT44:
+ gfxs->Cop = (color.a & 0xF0) + state->color_index;
+ gfxs->Alut = destination->palette;
+ break;
+ case DSPF_ARGB2554:
+ gfxs->Cop = PIXEL_ARGB2554( color.a, color.r, color.g, color.b );
+ break;
+ case DSPF_ARGB4444:
+ gfxs->Cop = PIXEL_ARGB4444( color.a, color.r, color.g, color.b );
+ break;
+ case DSPF_RGBA4444:
+ gfxs->Cop = PIXEL_RGBA4444( color.a, color.r, color.g, color.b );
+ break;
+ case DSPF_AYUV:
+ RGB_TO_YCBCR( color.r, color.g, color.b,
+ gfxs->YCop, gfxs->CbCop, gfxs->CrCop );
+ gfxs->Cop = PIXEL_AYUV( color.a, gfxs->YCop, gfxs->CbCop, gfxs->CrCop );
+ dst_ycbcr = true;
+ break;
+ case DSPF_RGB444:
+ gfxs->Cop = PIXEL_RGB444( color.r, color.g, color.b );
+ break;
+ case DSPF_RGB555:
+ gfxs->Cop = PIXEL_RGB555( color.r, color.g, color.b );
+ break;
+ case DSPF_BGR555:
+ gfxs->Cop = PIXEL_BGR555( color.r, color.g, color.b );
+ break;
+ default:
+ D_ONCE("unsupported destination format");
+ return false;
+ }
+
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ switch (gfxs->src_format) {
+ case DSPF_LUT2:
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ gfxs->Blut = source->palette;
+ case DSPF_ARGB1555:
+ case DSPF_ARGB2554:
+ case DSPF_ARGB4444:
+ case DSPF_RGBA4444:
+ case DSPF_ARGB1666:
+ case DSPF_ARGB6666:
+ case DSPF_RGB16:
+ case DSPF_RGB18:
+ case DSPF_RGB24:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ case DSPF_AiRGB:
+ case DSPF_RGB332:
+ case DSPF_RGB444:
+ case DSPF_RGB555:
+ case DSPF_BGR555:
+ if (dst_ycbcr &&
+ state->blittingflags & (DSBLIT_COLORIZE |
+ DSBLIT_SRC_PREMULTCOLOR))
+ return false;
+ case DSPF_A1:
+ case DSPF_A4:
+ case DSPF_A8:
+ if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format) &&
+ state->blittingflags & DSBLIT_DST_COLORKEY)
+ return false;
+ break;
+ case DSPF_I420:
+ case DSPF_YV12:
+ case DSPF_NV12:
+ case DSPF_NV21:
+ case DSPF_NV16:
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY)
+ return false;
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ case DSPF_AYUV:
+ if (dst_ycbcr) {
+ if (state->blittingflags & (DSBLIT_COLORIZE |
+ DSBLIT_SRC_PREMULTCOLOR))
+ return false;
+
+ if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format) &&
+ state->blittingflags & DSBLIT_DST_COLORKEY)
+ return false;
+ }
+ src_ycbcr = true;
+ break;
+ default:
+ D_ONCE("unsupported source format");
+ return false;
+ }
+ }
+
+ gfxs->need_accumulator = true;
+
+ /* Initialization */
+ gfxs->Astep = gfxs->Bstep = gfxs->Ostep = 1;
+
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ case DFXL_DRAWRECTANGLE:
+ case DFXL_DRAWLINE:
+ case DFXL_FILLTRIANGLE:
+ if (state->drawingflags & ~(DSDRAW_DST_COLORKEY | DSDRAW_SRC_PREMULTIPLY)) {
+ GenefxAccumulator Cacc, SCacc;
+
+ /* not yet completed optimizing checks */
+ if (state->drawingflags & DSDRAW_BLEND) {
+ if (state->src_blend == DSBF_ZERO) {
+ if (state->dst_blend == DSBF_ZERO) {
+ gfxs->Cop = 0;
+ if (state->drawingflags & DSDRAW_DST_COLORKEY) {
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Cop_toK_Aop_PFI[dst_pfi];
+ }
+ else
+ *funcs++ = Cop_to_Aop_PFI[dst_pfi];
+ break;
+ }
+ else if (state->dst_blend == DSBF_ONE) {
+ break;
+ }
+ }
+ else if (state->src_blend == DSBF_ONE && state->dst_blend == DSBF_ZERO) {
+ if (state->drawingflags & DSDRAW_DST_COLORKEY) {
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Cop_toK_Aop_PFI[dst_pfi];
+ }
+ else
+ *funcs++ = Cop_to_Aop_PFI[dst_pfi];
+ break;
+ }
+ }
+
+ /* load from destination */
+ *funcs++ = Sop_is_Aop;
+ if (DFB_PIXELFORMAT_IS_INDEXED(gfxs->dst_format))
+ *funcs++ = Slut_is_Alut;
+ *funcs++ = Dacc_is_Aacc;
+ *funcs++ = Sop_PFI_to_Dacc[dst_pfi];
+
+ /* premultiply destination */
+ if (state->drawingflags & DSDRAW_DST_PREMULTIPLY)
+ *funcs++ = Dacc_premultiply;
+
+ /* xor destination */
+ if (state->drawingflags & DSDRAW_XOR)
+ *funcs++ = Dacc_xor;
+
+ /* load source (color) */
+ Cacc.RGB.a = color.a;
+ if (!dst_ycbcr) {
+ Cacc.RGB.r = color.r;
+ Cacc.RGB.g = color.g;
+ Cacc.RGB.b = color.b;
+ } else {
+ Cacc.YUV.y = gfxs->YCop;
+ Cacc.YUV.u = gfxs->CbCop;
+ Cacc.YUV.v = gfxs->CrCop;
+ }
+
+ /* premultiply source (color) */
+ /*if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) {
+ u16 ca = color.a + 1;
+
+ Cacc.r = (Cacc.r * ca) >> 8;
+ Cacc.g = (Cacc.g * ca) >> 8;
+ Cacc.b = (Cacc.b * ca) >> 8;
+ }*/
+
+ if (state->drawingflags & DSDRAW_BLEND) {
+ /* source blending */
+ switch (state->src_blend) {
+ case DSBF_ZERO:
+ break;
+ case DSBF_ONE:
+ SCacc = Cacc;
+ break;
+ case DSBF_SRCCOLOR:
+ SCacc.RGB.a = (Cacc.RGB.a * (Cacc.RGB.a + 1)) >> 8;
+ SCacc.RGB.r = (Cacc.RGB.r * (Cacc.RGB.r + 1)) >> 8;
+ SCacc.RGB.g = (Cacc.RGB.g * (Cacc.RGB.g + 1)) >> 8;
+ SCacc.RGB.b = (Cacc.RGB.b * (Cacc.RGB.b + 1)) >> 8;
+ break;
+ case DSBF_INVSRCCOLOR:
+ SCacc.RGB.a = (Cacc.RGB.a * (0x100 - Cacc.RGB.a)) >> 8;
+ SCacc.RGB.r = (Cacc.RGB.r * (0x100 - Cacc.RGB.r)) >> 8;
+ SCacc.RGB.g = (Cacc.RGB.g * (0x100 - Cacc.RGB.g)) >> 8;
+ SCacc.RGB.b = (Cacc.RGB.b * (0x100 - Cacc.RGB.b)) >> 8;
+ break;
+ case DSBF_SRCALPHA: {
+ u16 ca = color.a + 1;
+
+ SCacc.RGB.a = (Cacc.RGB.a * ca) >> 8;
+ SCacc.RGB.r = (Cacc.RGB.r * ca) >> 8;
+ SCacc.RGB.g = (Cacc.RGB.g * ca) >> 8;
+ SCacc.RGB.b = (Cacc.RGB.b * ca) >> 8;
+ break;
+ }
+ case DSBF_INVSRCALPHA: {
+ u16 ca = 0x100 - color.a;
+
+ SCacc.RGB.a = (Cacc.RGB.a * ca) >> 8;
+ SCacc.RGB.r = (Cacc.RGB.r * ca) >> 8;
+ SCacc.RGB.g = (Cacc.RGB.g * ca) >> 8;
+ SCacc.RGB.b = (Cacc.RGB.b * ca) >> 8;
+ break;
+ }
+ case DSBF_SRCALPHASAT:
+ *funcs++ = Sacc_is_NULL;
+ case DSBF_DESTALPHA:
+ case DSBF_INVDESTALPHA:
+ case DSBF_DESTCOLOR:
+ case DSBF_INVDESTCOLOR:
+ *funcs++ = Dacc_is_Bacc;
+ *funcs++ = Cacc_to_Dacc;
+
+ *funcs++ = Dacc_is_Aacc;
+ *funcs++ = Xacc_is_Bacc;
+ *funcs++ = Yacc_is_Bacc;
+ *funcs++ = Xacc_blend[state->src_blend - 1];
+
+ break;
+
+ default:
+ D_BUG( "unknown src_blend %d", state->src_blend );
+ }
+
+
+ /* destination blending */
+ *funcs++ = Sacc_is_NULL;
+ *funcs++ = Xacc_is_Aacc;
+ *funcs++ = Yacc_is_Aacc;
+
+ if (state->dst_blend > D_ARRAY_SIZE(Xacc_blend) || state->dst_blend < 1)
+ D_BUG( "unknown dst_blend %d", state->dst_blend );
+ else
+ *funcs++ = Xacc_blend[state->dst_blend - 1];
+
+ /* add source to destination accumulator */
+ switch (state->src_blend) {
+ case DSBF_ZERO:
+ break;
+ case DSBF_ONE:
+ case DSBF_SRCCOLOR:
+ case DSBF_INVSRCCOLOR:
+ case DSBF_SRCALPHA:
+ case DSBF_INVSRCALPHA:
+ if (SCacc.RGB.a || SCacc.RGB.r ||
+ SCacc.RGB.g || SCacc.RGB.b)
+ *funcs++ = SCacc_add_to_Dacc;
+ break;
+ case DSBF_DESTALPHA:
+ case DSBF_INVDESTALPHA:
+ case DSBF_DESTCOLOR:
+ case DSBF_INVDESTCOLOR:
+ case DSBF_SRCALPHASAT:
+ *funcs++ = Sacc_is_Bacc;
+ *funcs++ = Sacc_add_to_Dacc;
+ break;
+
+ default:
+ D_BUG( "unknown src_blend %d", state->src_blend );
+ }
+ }
+
+ /* demultiply result */
+ if (state->drawingflags & DSDRAW_DEMULTIPLY)
+ *funcs++ = Dacc_demultiply;
+
+ /* write to destination */
+ *funcs++ = Sacc_is_Aacc;
+ if (state->drawingflags & DSDRAW_DST_COLORKEY) {
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Sacc_toK_Aop_PFI[dst_pfi];
+ }
+ else
+ *funcs++ = Sacc_to_Aop_PFI[dst_pfi];
+
+ /* store computed Cacc */
+ gfxs->Cacc = Cacc;
+ gfxs->SCacc = SCacc;
+ }
+ else {
+ gfxs->need_accumulator = false;
+
+ if (state->drawingflags & DSDRAW_DST_COLORKEY) {
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Cop_toK_Aop_PFI[dst_pfi];
+ }
+ else
+ *funcs++ = Cop_to_Aop_PFI[dst_pfi];
+ }
+ break;
+ case DFXL_BLIT:
+ if (state->blittingflags == DSBLIT_BLEND_ALPHACHANNEL &&
+ state->src_blend == DSBF_SRCALPHA &&
+ state->dst_blend == DSBF_INVSRCALPHA)
+ {
+ if (gfxs->src_format == DSPF_ARGB &&
+ Bop_argb_blend_alphachannel_src_invsrc_Aop_PFI[dst_pfi])
+ {
+ *funcs++ = Bop_argb_blend_alphachannel_src_invsrc_Aop_PFI[dst_pfi];
+ break;
+ }
+ }
+ if (state->blittingflags == DSBLIT_BLEND_ALPHACHANNEL &&
+ state->src_blend == DSBF_ONE &&
+ state->dst_blend == DSBF_INVSRCALPHA)
+ {
+ if (gfxs->src_format == DSPF_ARGB &&
+ Bop_argb_blend_alphachannel_one_invsrc_Aop_PFI[dst_pfi])
+ {
+ *funcs++ = Bop_argb_blend_alphachannel_one_invsrc_Aop_PFI[dst_pfi];
+ break;
+ }
+ }
+ if (((state->blittingflags == (DSBLIT_COLORIZE | DSBLIT_BLEND_ALPHACHANNEL |
+ DSBLIT_SRC_PREMULTIPLY) &&
+ state->src_blend == DSBF_ONE)
+ ||
+ (state->blittingflags == (DSBLIT_COLORIZE | DSBLIT_BLEND_ALPHACHANNEL) &&
+ state->src_blend == DSBF_SRCALPHA))
+ &&
+ state->dst_blend == DSBF_INVSRCALPHA)
+ {
+ if (gfxs->src_format == DSPF_A8 && Bop_a8_set_alphapixel_Aop_PFI[dst_pfi]) {
+ *funcs++ = Bop_a8_set_alphapixel_Aop_PFI[dst_pfi];
+ break;
+ }
+ if (gfxs->src_format == DSPF_A1 && Bop_a1_set_alphapixel_Aop_PFI[dst_pfi]) {
+ *funcs++ = Bop_a1_set_alphapixel_Aop_PFI[dst_pfi];
+ break;
+ }
+ }
+#ifndef WORDS_BIGENDIAN
+ if (state->blittingflags == DSBLIT_NOFX &&
+ source->config.format == DSPF_RGB24 &&
+ destination->config.format == DSPF_RGB16)
+ {
+ *funcs++ = Bop_rgb24_to_Aop_rgb16_LE;
+ break;
+ }
+ if (state->blittingflags == DSBLIT_NOFX &&
+ (source->config.format == DSPF_RGB32 || source->config.format == DSPF_ARGB) &&
+ destination->config.format == DSPF_RGB16)
+ {
+ *funcs++ = Bop_rgb32_to_Aop_rgb16_LE;
+ break;
+ }
+#endif
+ /* fallthru */
+ case DFXL_STRETCHBLIT: {
+ int modulation = state->blittingflags & MODULATION_FLAGS;
+
+ if (modulation) {
+ bool read_destination = false;
+ bool source_needs_destination = false;
+ bool scale_from_accumulator;
+
+ /* check if destination has to be read */
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL |
+ DSBLIT_BLEND_COLORALPHA)) {
+ switch (state->src_blend) {
+ case DSBF_DESTALPHA:
+ case DSBF_DESTCOLOR:
+ case DSBF_INVDESTALPHA:
+ case DSBF_INVDESTCOLOR:
+ case DSBF_SRCALPHASAT:
+ source_needs_destination = true;
+ default:
+ ;
+ }
+
+ read_destination = source_needs_destination ||
+ (state->dst_blend != DSBF_ZERO) ||
+ (state->blittingflags & DSBLIT_XOR);
+ }
+ else if (state->blittingflags & DSBLIT_XOR) {
+ read_destination = true;
+ }
+
+ scale_from_accumulator = !read_destination &&
+ (accel == DFXL_STRETCHBLIT);
+
+ /* read the destination if needed */
+ if (read_destination) {
+ *funcs++ = Sop_is_Aop;
+ if (DFB_PIXELFORMAT_IS_INDEXED(gfxs->dst_format))
+ *funcs++ = Slut_is_Alut;
+ *funcs++ = Dacc_is_Aacc;
+ *funcs++ = Sop_PFI_to_Dacc[dst_pfi];
+
+ if (state->blittingflags & DSBLIT_DST_PREMULTIPLY)
+ *funcs++ = Dacc_premultiply;
+ }
+ else if (scale_from_accumulator) {
+ *funcs++ = Len_is_Slen;
+ }
+
+ /* read the source */
+ *funcs++ = Sop_is_Bop;
+ if (DFB_PIXELFORMAT_IS_INDEXED(gfxs->src_format))
+ *funcs++ = Slut_is_Blut;
+ *funcs++ = Dacc_is_Bacc;
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
+ gfxs->Skey = state->src_colorkey;
+ if (accel == DFXL_BLIT || scale_from_accumulator)
+ *funcs++ = Sop_PFI_Kto_Dacc[src_pfi];
+ else
+ *funcs++ = Sop_PFI_SKto_Dacc[src_pfi];
+ }
+ else {
+ if (accel == DFXL_BLIT || scale_from_accumulator)
+ *funcs++ = Sop_PFI_to_Dacc[src_pfi];
+ else
+ *funcs++ = Sop_PFI_Sto_Dacc[src_pfi];
+ }
+
+ if (!src_ycbcr && dst_ycbcr) {
+ if (DFB_COLOR_BITS_PER_PIXEL(gfxs->src_format))
+ *funcs++ = Dacc_RGB_to_YCbCr;
+ /*else
+ *funcs++ = Dacc_Alpha_to_YCbCr;*/
+ }
+ else if (src_ycbcr && !dst_ycbcr) {
+ if (DFB_COLOR_BITS_PER_PIXEL(gfxs->dst_format))
+ *funcs++ = Dacc_YCbCr_to_RGB;
+ }
+
+ /* Premultiply color alpha? */
+ if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) {
+ gfxs->Cacc.RGB.a = color.a + 1;
+ *funcs++ = Dacc_premultiply_color_alpha;
+ }
+
+ /* modulate the source if requested */
+ if (Dacc_modulation[modulation & 0x7]) {
+ /* modulation source */
+ gfxs->Cacc.RGB.a = color.a + 1;
+ if (!dst_ycbcr) {
+ gfxs->Cacc.RGB.r = color.r + 1;
+ gfxs->Cacc.RGB.g = color.g + 1;
+ gfxs->Cacc.RGB.b = color.b + 1;
+ } else {
+ gfxs->Cacc.YUV.y = gfxs->YCop + 1;
+ gfxs->Cacc.YUV.u = gfxs->CbCop + 1;
+ gfxs->Cacc.YUV.v = gfxs->CrCop + 1;
+ }
+
+ *funcs++ = Dacc_modulation[modulation & 0x7];
+ }
+
+ /* Premultiply (modulated) source alpha? */
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY)
+ *funcs++ = Dacc_premultiply;
+
+ /* Xor source with destination */
+ if (state->blittingflags & DSBLIT_XOR) {
+ *funcs++ = Sacc_is_Aacc;
+ *funcs++ = Dacc_is_Bacc;
+ *funcs++ = Sacc_xor_Dacc;
+ }
+
+ /* do blend functions and combine both accumulators */
+ if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ /* Xacc will be blended and written to while
+ Sacc and Dacc point to the SRC and DST
+ as referenced by the blending functions */
+ *funcs++ = Sacc_is_Bacc;
+ *funcs++ = Dacc_is_Aacc;
+
+ if (source_needs_destination &&
+ state->dst_blend != DSBF_ONE) {
+ /* blend the destination */
+ *funcs++ = Yacc_is_Aacc;
+ *funcs++ = Xacc_is_Tacc;
+ *funcs++ = Xacc_blend[state->dst_blend - 1];
+
+ /* blend the source */
+ *funcs++ = Xacc_is_Bacc;
+ *funcs++ = Yacc_is_Bacc;
+ *funcs++ = Xacc_blend[state->src_blend - 1];
+ }
+ else {
+ /* blend the destination if needed */
+ if (read_destination) {
+ *funcs++ = Yacc_is_Aacc;
+ *funcs++ = Xacc_is_Tacc;
+ *funcs++ = Xacc_blend[state->dst_blend - 1];
+ }
+
+ /* blend the source */
+ *funcs++ = Xacc_is_Bacc;
+ *funcs++ = Yacc_is_Bacc;
+ *funcs++ = Xacc_blend[state->src_blend - 1];
+ }
+
+ /* add the destination to the source */
+ if (read_destination) {
+ *funcs++ = Sacc_is_Tacc;
+ *funcs++ = Dacc_is_Bacc;
+ *funcs++ = Sacc_add_to_Dacc;
+ }
+ }
+
+ if (state->blittingflags & DSBLIT_DEMULTIPLY) {
+ *funcs++ = Dacc_is_Bacc;
+ *funcs++ = Dacc_demultiply;
+ }
+
+ /* write source to destination */
+ *funcs++ = Sacc_is_Bacc;
+ if (scale_from_accumulator) {
+ *funcs++ = Len_is_Dlen;
+ if (state->blittingflags & DSBLIT_DST_COLORKEY ) {
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Sacc_StoK_Aop_PFI[dst_pfi];
+ } else
+ *funcs++ = Sacc_Sto_Aop_PFI[dst_pfi];
+ } else {
+ if (state->blittingflags & DSBLIT_DST_COLORKEY ) {
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Sacc_toK_Aop_PFI[dst_pfi];
+ } else
+ *funcs++ = Sacc_to_Aop_PFI[dst_pfi];
+ }
+ }
+ else if (state->blittingflags == DSBLIT_INDEX_TRANSLATION &&
+ DFB_PIXELFORMAT_IS_INDEXED(gfxs->src_format) &&
+ DFB_PIXELFORMAT_IS_INDEXED(gfxs->dst_format))
+ {
+ gfxs->trans = state->index_translation;
+ gfxs->num_trans = state->num_translation;
+
+ switch (gfxs->src_format) {
+ case DSPF_LUT2:
+ switch (gfxs->dst_format) {
+ case DSPF_LUT8:
+ *funcs++ = Bop_lut2_translate_to_Aop_lut8;
+ break;
+
+ default:
+ D_ONCE( "no index translation to %s implemented",
+ dfb_pixelformat_name( gfxs->dst_format ) );
+ break;
+ }
+ break;
+
+ default:
+ D_ONCE( "no index translation from %s implemented",
+ dfb_pixelformat_name( gfxs->src_format ) );
+ break;
+ }
+ }
+ else if ((gfxs->src_format == gfxs->dst_format &&
+ (!DFB_PIXELFORMAT_IS_INDEXED(gfxs->src_format) ||
+ dfb_palette_equal( gfxs->Alut, gfxs->Blut ))) ||
+ ((gfxs->src_format == DSPF_I420 || gfxs->src_format == DSPF_YV12) &&
+ (gfxs->dst_format == DSPF_I420 || gfxs->dst_format == DSPF_YV12)))
+ {
+ gfxs->need_accumulator = false;
+
+ if (accel == DFXL_BLIT) {
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY &&
+ state->blittingflags & DSBLIT_DST_COLORKEY) {
+ gfxs->Skey = state->src_colorkey;
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Bop_PFI_KtoK_Aop_PFI[dst_pfi];
+ } else if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
+ gfxs->Skey = state->src_colorkey;
+ *funcs++ = Bop_PFI_Kto_Aop_PFI[dst_pfi];
+ } else if (state->blittingflags & DSBLIT_DST_COLORKEY) {
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Bop_PFI_toK_Aop_PFI[dst_pfi];
+ } else if (state->blittingflags & (DSBLIT_ROTATE90 |
+ DSBLIT_ROTATE180 |
+ DSBLIT_ROTATE270)) {
+ *funcs++ = Bop_PFI_toR_Aop_PFI[dst_pfi];
+ } else
+ *funcs++ = Bop_PFI_to_Aop_PFI[dst_pfi];
+ }
+ else {
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY &&
+ state->blittingflags & DSBLIT_DST_COLORKEY) {
+ gfxs->Skey = state->src_colorkey;
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Bop_PFI_SKtoK_Aop_PFI[dst_pfi];
+ } else if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
+ gfxs->Skey = state->src_colorkey;
+ *funcs++ = Bop_PFI_SKto_Aop_PFI[dst_pfi];
+ } else if (state->blittingflags & DSBLIT_DST_COLORKEY) {
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Bop_PFI_StoK_Aop_PFI[dst_pfi];
+ } else
+ *funcs++ = Bop_PFI_Sto_Aop_PFI[dst_pfi];
+ }
+ }
+ else {
+ bool scale_from_accumulator = (src_ycbcr != dst_ycbcr) &&
+ (accel == DFXL_STRETCHBLIT);
+
+ if (scale_from_accumulator)
+ *funcs++ = Len_is_Slen;
+
+ gfxs->Sop = gfxs->Bop;
+
+ if (DFB_PIXELFORMAT_IS_INDEXED(gfxs->src_format))
+ *funcs++ = Slut_is_Blut;
+
+ if (accel == DFXL_BLIT || scale_from_accumulator) {
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY ) {
+ gfxs->Skey = state->src_colorkey;
+ *funcs++ = Sop_PFI_Kto_Dacc[src_pfi];
+ }
+ else
+ *funcs++ = Sop_PFI_to_Dacc[src_pfi];
+ }
+ else { /* DFXL_STRETCHBLIT */
+
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY ) {
+ gfxs->Skey = state->src_colorkey;
+ *funcs++ = Sop_PFI_SKto_Dacc[src_pfi];
+ }
+ else
+ *funcs++ = Sop_PFI_Sto_Dacc[src_pfi];
+
+ }
+
+ if (!src_ycbcr && dst_ycbcr) {
+ if (DFB_COLOR_BITS_PER_PIXEL(gfxs->src_format))
+ *funcs++ = Dacc_RGB_to_YCbCr;
+ else
+ *funcs++ = Dacc_Alpha_to_YCbCr;
+ }
+ else if (src_ycbcr && !dst_ycbcr) {
+ if (DFB_COLOR_BITS_PER_PIXEL(gfxs->dst_format))
+ *funcs++ = Dacc_YCbCr_to_RGB;
+ }
+
+ if (scale_from_accumulator) {
+ *funcs++ = Len_is_Dlen;
+ if (state->blittingflags & DSBLIT_DST_COLORKEY ) {
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Sacc_StoK_Aop_PFI[dst_pfi];
+ } else
+ *funcs++ = Sacc_Sto_Aop_PFI[dst_pfi];
+ } else {
+ if (state->blittingflags & DSBLIT_DST_COLORKEY ) {
+ gfxs->Dkey = state->dst_colorkey;
+ *funcs++ = Sacc_toK_Aop_PFI[dst_pfi];
+ } else
+ *funcs++ = Sacc_to_Aop_PFI[dst_pfi];
+ }
+ }
+ break;
+ }
+ default:
+ D_ONCE("unimplemented drawing/blitting function");
+ gRelease( state );
+ return false;
+ }
+
+ *funcs = NULL;
+
+ dfb_state_update( state, state->flags & CSF_SOURCE_LOCKED );
+
+ return true;
+}
+
+void gRelease( CardState *state )
+{
+ dfb_surface_unlock_buffer( state->destination, &state->dst );
+
+ if (state->flags & CSF_SOURCE_LOCKED) {
+ dfb_surface_unlock_buffer( state->source, &state->src );
+ state->flags &= ~CSF_SOURCE_LOCKED;
+ }
+}
+
+#define CHECK_PIPELINE() \
+ { \
+ if (!gfxs->funcs[0]) \
+ return; \
+ \
+ if (dfb_config->software_trace) { \
+ int i; \
+ GenefxFunc *funcs = gfxs->funcs; \
+ \
+ direct_log_lock( NULL ); \
+ direct_log_printf( NULL, " Software Fallback Pipeline:\n" ); \
+ \
+ for (i=0; funcs[i]; ++i) \
+ direct_log_printf( NULL, " [%2d] %s\n", i, \
+ direct_trace_lookup_symbol_at( funcs[i] ) ); \
+ \
+ direct_log_printf( NULL, "\n" ); \
+ direct_log_unlock( NULL ); \
+ } \
+ }
+
+#define RUN_PIPELINE() \
+ { \
+ int i; \
+ GenefxFunc *funcs = gfxs->funcs; \
+ \
+ for (i=0; funcs[i]; ++i) \
+ funcs[i]( gfxs ); \
+ }
+
+
+static inline void Aop_xy( GenefxState *gfxs, int x, int y )
+{
+ int pitch = gfxs->dst_pitch;
+
+ gfxs->Aop[0] = gfxs->dst_org[0];
+ gfxs->AopY = y;
+
+ if (gfxs->dst_caps & DSCAPS_SEPARATED) {
+ gfxs->Aop_field = y & 1;
+ if (gfxs->Aop_field)
+ gfxs->Aop[0] += gfxs->dst_field_offset;
+
+ y /= 2;
+ }
+
+ D_ASSUME( !(x & DFB_PIXELFORMAT_ALIGNMENT(gfxs->dst_format)) );
+
+ gfxs->Aop[0] += y * pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, x );
+
+ if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format)) {
+ int dst_field_offset = gfxs->dst_field_offset;
+
+ switch (gfxs->dst_format) {
+ case DSPF_YV12:
+ case DSPF_I420:
+ dst_field_offset /= 4;
+ pitch /= 2;
+ y /= 2;
+ x /= 2;
+ break;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ dst_field_offset /= 2;
+ y /= 2;
+ case DSPF_NV16:
+ x &= ~1;
+ break;
+ default:
+ break;
+ }
+
+ gfxs->Aop[1] = gfxs->dst_org[1];
+ gfxs->Aop[2] = gfxs->dst_org[2];
+
+ if (gfxs->dst_caps & DSCAPS_SEPARATED && gfxs->Aop_field) {
+ gfxs->Aop[1] += dst_field_offset;
+ gfxs->Aop[2] += dst_field_offset;
+ }
+
+ gfxs->Aop[1] += y * pitch + x;
+ gfxs->Aop[2] += y * pitch + x;
+ }
+}
+
+static inline void Aop_crab( GenefxState *gfxs )
+{
+ gfxs->Aop[0] += gfxs->dst_bpp;
+ gfxs->AopY++;
+}
+
+static inline void Aop_next( GenefxState *gfxs )
+{
+ int pitch = gfxs->dst_pitch;
+
+ if (gfxs->dst_caps & DSCAPS_SEPARATED) {
+ gfxs->Aop_field++;
+
+ if (gfxs->Aop_field & 1)
+ gfxs->Aop[0] += gfxs->dst_field_offset;
+ else
+ gfxs->Aop[0] += pitch - gfxs->dst_field_offset;
+ }
+ else
+ gfxs->Aop[0] += pitch;
+
+ if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format)) {
+ if (gfxs->dst_format == DSPF_YV12 || gfxs->dst_format == DSPF_I420) {
+ if (gfxs->AopY & 1) {
+ if (gfxs->dst_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Aop_field & 2) {
+ gfxs->Aop[1] += gfxs->dst_field_offset/4;
+ gfxs->Aop[2] += gfxs->dst_field_offset/4;
+ }
+ else {
+ gfxs->Aop[1] += pitch/2 - gfxs->dst_field_offset/4;
+ gfxs->Aop[2] += pitch/2 - gfxs->dst_field_offset/4;
+ }
+ }
+ else {
+ gfxs->Aop[1] += pitch/2;
+ gfxs->Aop[2] += pitch/2;
+ }
+ }
+ }
+ else if (gfxs->dst_format == DSPF_NV12 || gfxs->dst_format == DSPF_NV21) {
+ if (gfxs->AopY & 1) {
+ if (gfxs->dst_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Aop_field & 2)
+ gfxs->Aop[1] += gfxs->dst_field_offset/2;
+ else
+ gfxs->Aop[1] += pitch - gfxs->dst_field_offset/2;
+ }
+ else {
+ gfxs->Aop[1] += pitch;
+ }
+ }
+ }
+ else { /* NV16 */
+ if (gfxs->dst_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Aop_field & 1)
+ gfxs->Aop[1] += gfxs->dst_field_offset;
+ else
+ gfxs->Aop[1] += pitch - gfxs->dst_field_offset;
+ }
+ else {
+ gfxs->Aop[1] += pitch;
+ }
+ }
+ }
+
+ gfxs->AopY++;
+}
+
+static inline void Aop_prev( GenefxState *gfxs )
+{
+ int pitch = gfxs->dst_pitch;
+
+ if (gfxs->dst_caps & DSCAPS_SEPARATED) {
+ gfxs->Aop_field++;
+
+ if (gfxs->Aop_field & 1)
+ gfxs->Aop[0] += gfxs->dst_field_offset - pitch;
+ else
+ gfxs->Aop[0] -= gfxs->dst_field_offset;
+ }
+ else
+ gfxs->Aop[0] -= pitch;
+
+ if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format)) {
+ if (gfxs->dst_format == DSPF_YV12 || gfxs->dst_format == DSPF_I420) {
+ if (gfxs->AopY & 1) {
+ if (gfxs->dst_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Aop_field & 2) {
+ gfxs->Aop[1] += gfxs->dst_field_offset/4 - pitch/2;
+ gfxs->Aop[2] += gfxs->dst_field_offset/4 - pitch/2;
+ }
+ else {
+ gfxs->Aop[1] -= gfxs->dst_field_offset/4;
+ gfxs->Aop[2] -= gfxs->dst_field_offset/4;
+ }
+ }
+ else {
+ gfxs->Aop[1] -= pitch/2;
+ gfxs->Aop[2] -= pitch/2;
+ }
+ }
+ }
+ else if (gfxs->dst_format == DSPF_NV12 || gfxs->dst_format == DSPF_NV21) {
+ if (gfxs->AopY & 1) {
+ if (gfxs->dst_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Aop_field & 2)
+ gfxs->Aop[1] += gfxs->dst_field_offset/2 - pitch;
+ else
+ gfxs->Aop[1] -= gfxs->dst_field_offset/2;
+ }
+ else {
+ gfxs->Aop[1] -= pitch;
+ }
+ }
+ }
+ else { /* NV16 */
+ if (gfxs->dst_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Aop_field & 1)
+ gfxs->Aop[1] += gfxs->dst_field_offset - pitch;
+ else
+ gfxs->Aop[1] -= gfxs->dst_field_offset;
+ }
+ else {
+ gfxs->Aop[1] -= pitch;
+ }
+ }
+ }
+
+ gfxs->AopY--;
+}
+
+
+static inline void Bop_xy( GenefxState *gfxs, int x, int y )
+{
+ int pitch = gfxs->src_pitch;
+
+ gfxs->Bop[0] = gfxs->src_org[0];
+ gfxs->BopY = y;
+
+ if (gfxs->src_caps & DSCAPS_SEPARATED) {
+ gfxs->Bop_field = y & 1;
+ if (gfxs->Bop_field)
+ gfxs->Bop[0] += gfxs->src_field_offset;
+
+ y /= 2;
+ }
+
+ D_ASSUME( !(x & DFB_PIXELFORMAT_ALIGNMENT(gfxs->src_format)) );
+
+ gfxs->Bop[0] += y * pitch + DFB_BYTES_PER_LINE( gfxs->src_format, x );
+
+ if (DFB_PLANAR_PIXELFORMAT(gfxs->src_format)) {
+ int src_field_offset = gfxs->src_field_offset;
+
+ switch (gfxs->src_format) {
+ case DSPF_YV12:
+ case DSPF_I420:
+ src_field_offset /= 4;
+ pitch /= 2;
+ y /= 2;
+ x /= 2;
+ break;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ src_field_offset /= 2;
+ y /= 2;
+ case DSPF_NV16:
+ x &= ~1;
+ break;
+ default:
+ break;
+ }
+
+ gfxs->Bop[1] = gfxs->src_org[1];
+ gfxs->Bop[2] = gfxs->src_org[2];
+
+ if (gfxs->src_caps & DSCAPS_SEPARATED && gfxs->Bop_field) {
+ gfxs->Bop[1] += src_field_offset;
+ gfxs->Bop[2] += src_field_offset;
+ }
+
+ gfxs->Bop[1] += y * pitch + x;
+ gfxs->Bop[2] += y * pitch + x;
+ }
+}
+
+static inline void Bop_next( GenefxState *gfxs )
+{
+ int pitch = gfxs->src_pitch;
+
+ if (gfxs->src_caps & DSCAPS_SEPARATED) {
+ gfxs->Bop_field++;
+
+ if (gfxs->Bop_field & 1)
+ gfxs->Bop[0] += gfxs->src_field_offset;
+ else
+ gfxs->Bop[0] += pitch - gfxs->src_field_offset;
+ }
+ else
+ gfxs->Bop[0] += pitch;
+
+ if (DFB_PLANAR_PIXELFORMAT(gfxs->src_format)) {
+ if (gfxs->src_format == DSPF_YV12 || gfxs->src_format == DSPF_I420) {
+ if (gfxs->BopY & 1) {
+ if (gfxs->src_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Bop_field & 2) {
+ gfxs->Bop[1] += gfxs->src_field_offset/4;
+ gfxs->Bop[2] += gfxs->src_field_offset/4;
+ }
+ else {
+ gfxs->Bop[1] += pitch/2 - gfxs->src_field_offset/4;
+ gfxs->Bop[2] += pitch/2 - gfxs->src_field_offset/4;
+ }
+ }
+ else {
+ gfxs->Bop[1] += pitch/2;
+ gfxs->Bop[2] += pitch/2;
+ }
+ }
+ }
+ else if (gfxs->src_format == DSPF_NV12 || gfxs->src_format == DSPF_NV21) {
+ if (gfxs->BopY & 1) {
+ if (gfxs->src_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Bop_field & 2)
+ gfxs->Bop[1] += gfxs->src_field_offset/2;
+ else
+ gfxs->Bop[1] += pitch - gfxs->src_field_offset/2;
+ }
+ else {
+ gfxs->Bop[1] += pitch;
+ }
+ }
+ }
+ else { /* NV16 */
+ if (gfxs->src_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Bop_field & 1)
+ gfxs->Bop[1] += gfxs->src_field_offset;
+ else
+ gfxs->Bop[1] += pitch - gfxs->src_field_offset;
+ }
+ else {
+ gfxs->Bop[1] += pitch;
+ }
+ }
+ }
+
+ gfxs->BopY++;
+}
+
+static inline void Bop_prev( GenefxState *gfxs )
+{
+ int pitch = gfxs->src_pitch;
+
+ if (gfxs->src_caps & DSCAPS_SEPARATED) {
+ gfxs->Bop_field++;
+
+ if (gfxs->Bop_field & 1)
+ gfxs->Bop[0] += gfxs->src_field_offset - pitch;
+ else
+ gfxs->Bop[0] -= gfxs->src_field_offset;
+ }
+ else
+ gfxs->Bop[0] -= pitch;
+
+ if (DFB_PLANAR_PIXELFORMAT(gfxs->src_format)) {
+ if (gfxs->src_format == DSPF_YV12 || gfxs->src_format == DSPF_I420) {
+ if (gfxs->BopY & 1) {
+ if (gfxs->src_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Bop_field & 2) {
+ gfxs->Bop[1] += gfxs->src_field_offset/4 - pitch/2;
+ gfxs->Bop[2] += gfxs->src_field_offset/4 - pitch/2;
+ }
+ else {
+ gfxs->Bop[1] -= gfxs->src_field_offset/4;
+ gfxs->Bop[2] -= gfxs->src_field_offset/4;
+ }
+ }
+ else {
+ gfxs->Bop[1] -= pitch/2;
+ gfxs->Bop[2] -= pitch/2;
+ }
+ }
+ }
+ else if (gfxs->src_format == DSPF_NV12 || gfxs->src_format == DSPF_NV21) {
+ if (gfxs->BopY & 1) {
+ if (gfxs->src_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Bop_field & 2)
+ gfxs->Bop[1] += gfxs->src_field_offset/2 - pitch;
+ else
+ gfxs->Bop[1] -= gfxs->src_field_offset/2;
+ }
+ else {
+ gfxs->Bop[1] -= pitch;
+ }
+ }
+ }
+ else { /* NV16 */
+ if (gfxs->src_caps & DSCAPS_SEPARATED) {
+ if (gfxs->Bop_field & 1)
+ gfxs->Bop[1] += gfxs->src_field_offset - pitch;
+ else
+ gfxs->Bop[1] -= gfxs->src_field_offset;
+ }
+ else {
+ gfxs->Bop[1] -= pitch;
+ }
+ }
+ }
+
+ gfxs->BopY--;
+}
+
+static bool
+ABacc_prepare( GenefxState *gfxs, int width )
+{
+ int size;
+
+ if (!gfxs->need_accumulator)
+ return true;
+
+ size = (width + 31) & ~31;
+
+ if (gfxs->ABsize < size) {
+ void *ABstart = D_MALLOC( size * sizeof(GenefxAccumulator) * 3 + 31 );
+
+ if (!ABstart) {
+ D_WARN( "out of memory" );
+ return false;
+ }
+
+ if (gfxs->ABstart)
+ D_FREE( gfxs->ABstart );
+
+ gfxs->ABstart = ABstart;
+ gfxs->ABsize = size;
+ gfxs->Aacc = (GenefxAccumulator*) (((unsigned long)ABstart+31) & ~31);
+ gfxs->Bacc = gfxs->Aacc + size;
+ gfxs->Tacc = gfxs->Aacc + size + size;
+ }
+
+ gfxs->Sacc = gfxs->Dacc = gfxs->Aacc;
+
+ return true;
+}
+
+static void
+ABacc_flush( GenefxState *gfxs )
+{
+ if (dfb_config->keep_accumulators >= 0 && gfxs->ABsize > dfb_config->keep_accumulators) {
+ D_FREE( gfxs->ABstart );
+
+ gfxs->ABsize = 0;
+ gfxs->ABstart = NULL;
+ gfxs->Aacc = NULL;
+ gfxs->Bacc = NULL;
+ gfxs->Sacc = NULL;
+ gfxs->Dacc = NULL;
+ }
+}
+
+void gFillRectangle( CardState *state, DFBRectangle *rect )
+{
+ int h;
+ GenefxState *gfxs = state->gfxs;
+
+ D_ASSERT( gfxs != NULL );
+
+ if (dfb_config->software_warn) {
+ D_WARN( "FillRectangle (%4d,%4d-%4dx%4d) %6s, flags 0x%08x, color 0x%02x%02x%02x%02x",
+ DFB_RECTANGLE_VALS(rect), dfb_pixelformat_name(gfxs->dst_format), state->drawingflags,
+ state->color.a, state->color.r, state->color.g, state->color.b );
+ }
+
+ D_ASSERT( state->clip.x1 <= rect->x );
+ D_ASSERT( state->clip.y1 <= rect->y );
+ D_ASSERT( state->clip.x2 >= (rect->x + rect->w - 1) );
+ D_ASSERT( state->clip.y2 >= (rect->y + rect->h - 1) );
+
+ CHECK_PIPELINE();
+
+ if (!ABacc_prepare( gfxs, rect->w ))
+ return;
+
+ gfxs->length = rect->w;
+
+ Aop_xy( gfxs, rect->x, rect->y );
+
+ h = rect->h;
+ while (h--) {
+ RUN_PIPELINE();
+
+ Aop_next( gfxs );
+ }
+
+ ABacc_flush( gfxs );
+}
+
+void gDrawLine( CardState *state, DFBRegion *line )
+{
+ GenefxState *gfxs = state->gfxs;
+
+ int i,dx,dy,sdy,dxabs,dyabs,x,y,px,py;
+
+ D_ASSERT( gfxs != NULL );
+
+ CHECK_PIPELINE();
+
+ /* the horizontal distance of the line */
+ dx = line->x2 - line->x1;
+ dxabs = abs(dx);
+
+ if (!ABacc_prepare( gfxs, dxabs ))
+ return;
+
+ /* the vertical distance of the line */
+ dy = line->y2 - line->y1;
+ dyabs = abs(dy);
+
+ if (!dx || !dy) { /* draw horizontal/vertical line */
+ DFBRectangle rect = {
+ MIN (line->x1, line->x2),
+ MIN (line->y1, line->y2),
+ dxabs + 1, dyabs + 1};
+
+ gFillRectangle( state, &rect );
+ return;
+ }
+
+ if (dfb_config->software_warn) {
+ D_WARN( "DrawLine (%4d,%4d-%4d,%4d) %6s, flags 0x%08x, color 0x%02x%02x%02x%02x",
+ DFB_RECTANGLE_VALS_FROM_REGION(line), dfb_pixelformat_name(gfxs->dst_format), state->drawingflags,
+ state->color.a, state->color.r, state->color.g, state->color.b );
+ }
+
+ sdy = SIGN(dy) * SIGN(dx);
+ x = dyabs >> 1;
+ y = dxabs >> 1;
+
+ if (dx > 0) {
+ px = line->x1;
+ py = line->y1;
+ }
+ else {
+ px = line->x2;
+ py = line->y2;
+ }
+
+ if (dxabs >= dyabs) { /* the line is more horizontal than vertical */
+
+ for (i=0, gfxs->length=1; i<dxabs; i++, gfxs->length++) {
+ y += dyabs;
+ if (y >= dxabs) {
+ Aop_xy( gfxs, px, py );
+ RUN_PIPELINE();
+ px += gfxs->length;
+ gfxs->length = 0;
+ y -= dxabs;
+ py += sdy;
+ }
+ }
+ Aop_xy( gfxs, px, py );
+ RUN_PIPELINE();
+ }
+ else { /* the line is more vertical than horizontal */
+
+ gfxs->length = 1;
+ Aop_xy( gfxs, px, py );
+ RUN_PIPELINE();
+
+ for (i=0; i<dyabs; i++) {
+ x += dxabs;
+ if (x >= dyabs) {
+ x -= dyabs;
+ px++;
+ }
+ py += sdy;
+
+ Aop_xy( gfxs, px, py );
+ RUN_PIPELINE();
+ }
+ }
+
+ ABacc_flush( gfxs );
+}
+
+void gBlit( CardState *state, DFBRectangle *rect, int dx, int dy )
+{
+ GenefxState *gfxs = state->gfxs;
+ int x, h;
+
+ D_ASSERT( gfxs != NULL );
+
+ if (dfb_config->software_warn) {
+ D_WARN( "Blit (%4d,%4d-%4dx%4d) %6s, flags 0x%08x, funcs %d/%d, color 0x%02x%02x%02x%02x, source (%4d,%4d) %6s",
+ dx, dy, rect->w, rect->h, dfb_pixelformat_name(gfxs->dst_format), state->blittingflags,
+ state->src_blend, state->dst_blend,
+ state->color.a, state->color.r, state->color.g, state->color.b, rect->x, rect->y,
+ dfb_pixelformat_name(gfxs->src_format) );
+ }
+
+ D_ASSERT( state->clip.x1 <= dx );
+ D_ASSERT( state->clip.y1 <= dy );
+ D_ASSERT( (state->blittingflags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270)) || state->clip.x2 >= (dx + rect->w - 1) );
+ D_ASSERT( (state->blittingflags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270)) || state->clip.y2 >= (dy + rect->h - 1) );
+ D_ASSERT( !(state->blittingflags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270)) || state->clip.x2 >= (dx + rect->h - 1) );
+ D_ASSERT( !(state->blittingflags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270)) || state->clip.y2 >= (dy + rect->w - 1) );
+
+ CHECK_PIPELINE();
+
+ if (!ABacc_prepare( gfxs, rect->w ))
+ return;
+
+ if (gfxs->src_org[0] == gfxs->dst_org[0] && dy == rect->y && dx > rect->x)
+ /* we must blit from right to left */
+ gfxs->Astep = gfxs->Bstep = -1;
+ else
+ /* we must blit from left to right*/
+ gfxs->Astep = gfxs->Bstep = 1;
+
+ if (state->blittingflags & DSBLIT_ROTATE90)
+ gfxs->Astep *= -gfxs->dst_pitch / gfxs->dst_bpp;
+ else if (state->blittingflags & DSBLIT_ROTATE180)
+ gfxs->Astep *= -1;
+ else if (state->blittingflags & DSBLIT_ROTATE270)
+ gfxs->Astep *= gfxs->dst_pitch / gfxs->dst_bpp;
+
+ switch (gfxs->src_format) {
+ case DSPF_A4:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ rect->x &= ~1;
+ break;
+ default:
+ break;
+ }
+
+ switch (gfxs->dst_format) {
+ case DSPF_A4:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ dx &= ~1;
+ break;
+ default:
+ break;
+ }
+
+ gfxs->length = rect->w;
+
+ if (state->blittingflags == DSBLIT_ROTATE180 && gfxs->src_format == gfxs->dst_format) {
+ Aop_xy( gfxs, dx, dy );
+ Bop_xy( gfxs, rect->x + rect->w - 1, rect->y + rect->h - 1 );
+
+ switch (DFB_BYTES_PER_PIXEL(gfxs->dst_format)) {
+ case 4: {
+ for (h = rect->h; h; h--) {
+ u32 *src = gfxs->Bop[0];
+ u32 *dst = gfxs->Aop[0];
+
+ for (x=0; x<rect->w; x++)
+ dst[x] = src[-x];
+
+ Aop_next( gfxs );
+ Bop_prev( gfxs );
+ }
+ return;
+ }
+ case 2: {
+ for (h = rect->h; h; h--) {
+ u16 *src = gfxs->Bop[0];
+ u16 *dst = gfxs->Aop[0];
+
+ for (x=0; x<rect->w; x++)
+ dst[x] = src[-x];
+
+ Aop_next( gfxs );
+ Bop_prev( gfxs );
+ }
+ return;
+ }
+ case 1: {
+ for (h = rect->h; h; h--) {
+ u8 *src = gfxs->Bop[0];
+ u8 *dst = gfxs->Aop[0];
+
+ for (x=0; x<rect->w; x++)
+ dst[x] = src[-x];
+
+ Aop_next( gfxs );
+ Bop_prev( gfxs );
+ }
+ return;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ if (state->blittingflags & DSBLIT_ROTATE180) {
+ Aop_xy( gfxs, dx + rect->w - 1, dy );
+ Bop_xy( gfxs, rect->x, rect->y + rect->h - 1 );
+
+ for (h = rect->h; h; h--) {
+ RUN_PIPELINE();
+
+ Aop_next( gfxs );
+ Bop_prev( gfxs );
+ }
+ return;
+ }
+ else if( state->blittingflags & DSBLIT_ROTATE270 )
+ {
+ Aop_xy( gfxs, dx, dy );
+ Bop_xy( gfxs, rect->x, rect->y + rect->h - 1 );
+
+ for( h = rect->h; h; h-- )
+ {
+ RUN_PIPELINE();
+
+ Aop_crab( gfxs );
+ Bop_prev( gfxs );
+ }
+ return;
+ }
+ else if( state->blittingflags & DSBLIT_ROTATE90 )
+ {
+ Aop_xy( gfxs, dx, dy + rect->w - 1 );
+ Bop_xy( gfxs, rect->x, rect->y );
+
+ for( h = rect->h; h; h-- )
+ {
+ RUN_PIPELINE();
+
+ Aop_crab( gfxs );
+ Bop_next( gfxs );
+ }
+ return;
+ }
+
+ if (gfxs->src_org[0] == gfxs->dst_org[0] && dy > rect->y &&
+ !(state->blittingflags & DSBLIT_DEINTERLACE)) {
+ /* we must blit from bottom to top */
+ Aop_xy( gfxs, dx, dy + rect->h - 1 );
+ Bop_xy( gfxs, rect->x, rect->y + rect->h - 1 );
+
+ for (h = rect->h; h; h--) {
+ RUN_PIPELINE();
+
+ Aop_prev( gfxs );
+ Bop_prev( gfxs );
+ }
+ }
+ else {
+ /* we must blit from top to bottom */
+ Aop_xy( gfxs, dx, dy );
+ Bop_xy( gfxs, rect->x, rect->y );
+
+ if (state->blittingflags & DSBLIT_DEINTERLACE) {
+ if (state->source->field) {
+ Aop_next( gfxs );
+ Bop_next( gfxs );
+ rect->h--;
+ }
+
+ for (h = rect->h/2; h; h--) {
+ RUN_PIPELINE();
+
+ Aop_next( gfxs );
+
+ RUN_PIPELINE();
+
+ Aop_next( gfxs );
+
+ Bop_next( gfxs );
+ Bop_next( gfxs );
+ }
+ } /* ! DSBLIT_DEINTERLACE */
+ else {
+ for (h = rect->h; h; h--) {
+ RUN_PIPELINE();
+
+ Aop_next( gfxs );
+ Bop_next( gfxs );
+ }
+ }
+ }
+
+ ABacc_flush( gfxs );
+}
+
+/**********************************************************************************************************************/
+/********* **************************************************************************************************/
+/*** Smooth scaling routines ******************************************************************************************/
+/********* **************************************************************************************************/
+/**********************************************************************************************************************/
+
+#if DFB_SMOOTH_SCALING
+
+typedef struct {
+ DFBRegion clip;
+ const void *colors;
+ ulong protect;
+ ulong key;
+} StretchCtx;
+
+typedef void (*StretchHVx)( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx );
+
+#define STRETCH_NONE 0
+#define STRETCH_SRCKEY 1
+#define STRETCH_PROTECT 2
+#define STRETCH_SRCKEY_PROTECT 3
+#define STRETCH_NUM 4
+
+typedef struct {
+ struct {
+ StretchHVx up[STRETCH_NUM];
+ StretchHVx down[STRETCH_NUM];
+ } f[DFB_NUM_PIXELFORMATS];
+} StretchFunctionTable;
+
+/**********************************************************************************************************************/
+/*** 16 bit RGB 565 scalers *******************************************************************************************/
+/**********************************************************************************************************************/
+
+#define DST_FORMAT DSPF_RGB16
+#define TABLE_NAME stretch_hvx_RGB16
+#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_RGB16_ ## UPDOWN ## _ ## K ## P ## _ ## F
+#define SHIFT_R5 5
+#define SHIFT_R6 6
+#define X_F81F 0xf81f
+#define X_07E0 0x07e0
+#define MASK_RGB 0xffff
+
+#define FORMAT_RGB16
+#include "stretch_up_down_16.h"
+#undef FORMAT_RGB16
+
+#undef DST_FORMAT
+#undef TABLE_NAME
+#undef FUNC_NAME
+#undef SHIFT_R5
+#undef SHIFT_R6
+#undef X_F81F
+#undef X_07E0
+#undef MASK_RGB
+
+/**********************************************************************************************************************/
+/*** 16 bit ARGB 4444 scalers *****************************************************************************************/
+/**********************************************************************************************************************/
+
+#define DST_FORMAT DSPF_ARGB4444
+#define TABLE_NAME stretch_hvx_ARGB4444
+#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_ARGB4444_ ## UPDOWN ## _ ## K ## P ## _ ## F
+#define SHIFT_R5 4
+#define SHIFT_R6 4
+#define X_F81F 0x0f0f
+#define X_07E0 0xf0f0
+#define MASK_RGB 0x0fff
+#define HAS_ALPHA
+
+#define FORMAT_ARGB4444
+#include "stretch_up_down_16.h"
+#undef FORMAT_ARGB4444
+
+#undef DST_FORMAT
+#undef TABLE_NAME
+#undef FUNC_NAME
+#undef SHIFT_R5
+#undef SHIFT_R6
+#undef X_F81F
+#undef X_07E0
+#undef MASK_RGB
+#undef HAS_ALPHA
+
+/**********************************************************************************************************************/
+/*** 16 bit RGBA 4444 scalers *****************************************************************************************/
+/**********************************************************************************************************************/
+
+#define DST_FORMAT DSPF_RGBA4444
+#define TABLE_NAME stretch_hvx_RGBA4444
+#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_RGBA4444_ ## UPDOWN ## _ ## K ## P ## _ ## F
+#define SHIFT_R5 4
+#define SHIFT_R6 4
+#define X_F81F 0x0f0f
+#define X_07E0 0xf0f0
+#define MASK_RGB 0xfff0
+#define HAS_ALPHA
+
+#define FORMAT_RGBA4444
+#include "stretch_up_down_16.h"
+#undef FORMAT_RGBA4444
+
+#undef DST_FORMAT
+#undef TABLE_NAME
+#undef FUNC_NAME
+#undef SHIFT_R5
+#undef SHIFT_R6
+#undef X_F81F
+#undef X_07E0
+#undef MASK_RGB
+#undef HAS_ALPHA
+
+/**********************************************************************************************************************/
+/*** 32 bit ARGB 8888 scalers *****************************************************************************************/
+/**********************************************************************************************************************/
+
+#define DST_FORMAT DSPF_ARGB
+#define TABLE_NAME stretch_hvx_ARGB
+#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_ARGB_ ## UPDOWN ## _ ## K ## P ## _ ## F
+#define SHIFT_R8 8
+#define SHIFT_L8 8
+#define X_00FF00FF 0x00ff00ff
+#define X_FF00FF00 0xff00ff00
+#define MASK_RGB 0x00ffffff
+#define HAS_ALPHA
+
+#include "stretch_up_down_32.h"
+
+#undef DST_FORMAT
+#undef TABLE_NAME
+#undef FUNC_NAME
+#undef SHIFT_R8
+#undef SHIFT_L8
+#undef X_00FF00FF
+#undef X_FF00FF00
+#undef MASK_RGB
+#undef HAS_ALPHA
+
+/**********************************************************************************************************************/
+/*** 32 bit RGB 888 scalers *******************************************************************************************/
+/**********************************************************************************************************************/
+
+#define DST_FORMAT DSPF_RGB32
+#define TABLE_NAME stretch_hvx_RGB32
+#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_RGB32_ ## UPDOWN ## _ ## K ## P ## _ ## F
+#define SHIFT_R8 8
+#define SHIFT_L8 8
+#define X_00FF00FF 0x00ff00ff
+#define X_FF00FF00 0x0000ff00
+#define MASK_RGB 0x00ffffff
+
+#include "stretch_up_down_32.h"
+
+#undef DST_FORMAT
+#undef TABLE_NAME
+#undef FUNC_NAME
+#undef SHIFT_R8
+#undef SHIFT_L8
+#undef X_00FF00FF
+#undef X_FF00FF00
+#undef MASK_RGB
+
+#if 0
+/**********************************************************************************************************************/
+/*** 16 bit YUV 422 scalers *******************************************************************************************/
+/**********************************************************************************************************************/
+
+#define FUNC_NAME(UPDOWN) stretch_hvx_nv16_ ## UPDOWN
+
+#include "stretch_up_down_8.h"
+
+#undef FUNC_NAME
+
+/**********************************************************************************************************************/
+
+#define FUNC_NAME(UPDOWN) stretch_hvx_nv16_uv_ ## UPDOWN
+
+#include "stretch_up_down_88.h"
+
+#undef FUNC_NAME
+
+#endif
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+static const StretchFunctionTable *stretch_tables[DFB_NUM_PIXELFORMATS] = {
+ NULL, /* DSPF_ARGB1555 */
+ &stretch_hvx_RGB16, /* DSPF_RGB16 */
+ NULL, /* DSPF_RGB24 */
+ &stretch_hvx_RGB32, /* DSPF_RGB32 */
+ &stretch_hvx_ARGB, /* DSPF_ARGB */
+ NULL, /* DSPF_A8 */
+ NULL, /* DSPF_YUY2 */
+ NULL, /* DSPF_RGB332 */
+ NULL, /* DSPF_UYVY */
+ NULL, /* DSPF_I420 */
+ NULL, /* DSPF_YV12 */
+ NULL, /* DSPF_LUT8 */
+ NULL, /* DSPF_ALUT44 */
+ NULL, /* DSPF_AiRGB */
+ NULL, /* DSPF_A1 */
+ NULL, /* DSPF_NV12 */
+ NULL, /* DSPF_NV16 */
+ NULL, /* DSPF_ARGB2554 */
+ &stretch_hvx_ARGB4444, /* DSPF_ARGB4444 */
+ &stretch_hvx_RGBA4444, /* DSPF_RGBA4444 */
+ NULL, /* DSPF_NV21 */
+ NULL, /* DSPF_AYUV */
+ NULL, /* DSPF_A4 */
+ NULL, /* DSPF_ARGB1666 */
+ NULL, /* DSPF_ARGB6666 */
+ NULL, /* DSPF_RGB18 */
+ NULL, /* DSPF_LUT2 */
+ NULL, /* DSPF_RGB444 */
+ NULL, /* DSPF_RGB555 */
+ NULL /* DSPF_BGR555 */
+};
+
+/**********************************************************************************************************************/
+
+__attribute__((noinline))
+static bool
+stretch_hvx( CardState *state, DFBRectangle *srect, DFBRectangle *drect )
+{
+ GenefxState *gfxs;
+ const StretchFunctionTable *table;
+ StretchHVx stretch;
+ bool down = false;
+ void *dst;
+ void *src;
+ StretchCtx ctx;
+ int idx = STRETCH_NONE;
+ u32 colors[256];
+
+ D_ASSERT( state != NULL );
+ DFB_RECTANGLE_ASSERT( srect );
+ DFB_RECTANGLE_ASSERT( drect );
+
+ gfxs = state->gfxs;
+
+ if (state->blittingflags & ~(DSBLIT_COLORKEY_PROTECT | DSBLIT_SRC_COLORKEY | DSBLIT_SRC_PREMULTIPLY))
+ return false;
+
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY && !DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format ))
+ return false;
+
+ if (DFB_PIXELFORMAT_INDEX(gfxs->dst_format) >= D_ARRAY_SIZE(stretch_tables))
+ return false;
+
+ if (DFB_PIXELFORMAT_INDEX(gfxs->src_format) >= D_ARRAY_SIZE((stretch_tables[0])->f))
+ return false;
+
+ table = stretch_tables[DFB_PIXELFORMAT_INDEX(gfxs->dst_format)];
+ if (!table)
+ return false;
+
+ if (srect->w > drect->w && srect->h > drect->h)
+ down = true;
+
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY)
+ idx |= STRETCH_SRCKEY;
+
+ if (state->blittingflags & DSBLIT_COLORKEY_PROTECT)
+ idx |= STRETCH_PROTECT;
+
+ if (down) {
+ if (!(state->render_options & DSRO_SMOOTH_DOWNSCALE))
+ return false;
+
+ stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].down[idx];
+ }
+ else {
+ if (!(state->render_options & DSRO_SMOOTH_UPSCALE))
+ return false;
+
+ stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].up[idx];
+ }
+
+ if (!stretch)
+ return false;
+
+ ctx.clip = state->clip;
+
+ if (!dfb_region_rectangle_intersect( &ctx.clip, drect ))
+ return false;
+
+ dfb_region_translate( &ctx.clip, - drect->x, - drect->y );
+
+ if (DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format )) {
+ int i;
+ const DFBColor *entries;
+ u16 *colors16 = (void*) colors;
+
+ D_ASSERT( gfxs->Blut != NULL );
+
+ entries = gfxs->Blut->entries;
+
+ switch (gfxs->dst_format) {
+ case DSPF_ARGB:
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) {
+ for (i=0; i<gfxs->Blut->num_entries; i++) {
+ int alpha = entries[i].a + 1;
+
+ switch (alpha) {
+ case 0:
+ colors[i] = 0;
+ break;
+
+ case 255:
+ colors[i] = PIXEL_ARGB( entries[i].a,
+ entries[i].r,
+ entries[i].g,
+ entries[i].b );
+ break;
+
+ default:
+ colors[i] = PIXEL_ARGB( entries[i].a,
+ (alpha * entries[i].r) >> 8,
+ (alpha * entries[i].g) >> 8,
+ (alpha * entries[i].b) >> 8 );
+ }
+ }
+ }
+ else {
+ for (i=0; i<gfxs->Blut->num_entries; i++)
+ colors[i] = PIXEL_ARGB( entries[i].a, entries[i].r, entries[i].g, entries[i].b );
+ }
+ break;
+
+ case DSPF_RGB32:
+ for (i=0; i<gfxs->Blut->num_entries; i++)
+ colors[i] = PIXEL_RGB32( entries[i].r, entries[i].g, entries[i].b );
+ break;
+
+ case DSPF_RGB16:
+ for (i=0; i<gfxs->Blut->num_entries; i++)
+ colors16[i] = PIXEL_RGB16( entries[i].r, entries[i].g, entries[i].b );
+ break;
+
+ case DSPF_ARGB4444:
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) {
+ for (i=0; i<gfxs->Blut->num_entries; i++) {
+ int alpha = entries[i].a + 1;
+
+ switch (alpha) {
+ case 0:
+ colors16[i] = 0;
+ break;
+
+ case 255:
+ colors16[i] = PIXEL_ARGB4444( entries[i].a,
+ entries[i].r,
+ entries[i].g,
+ entries[i].b );
+ break;
+
+ default:
+ colors16[i] = PIXEL_ARGB4444( entries[i].a,
+ (alpha * entries[i].r) >> 8,
+ (alpha * entries[i].g) >> 8,
+ (alpha * entries[i].b) >> 8 );
+ }
+ }
+ }
+ else {
+ for (i=0; i<gfxs->Blut->num_entries; i++)
+ colors16[i] = PIXEL_ARGB4444( entries[i].a, entries[i].r, entries[i].g, entries[i].b );
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) {
+ for (i=0; i<gfxs->Blut->num_entries; i++) {
+ int alpha = entries[i].a + 1;
+
+ switch (alpha) {
+ case 0:
+ colors16[i] = 0;
+ break;
+
+ case 255:
+ colors16[i] = PIXEL_RGBA4444( entries[i].a,
+ entries[i].r,
+ entries[i].g,
+ entries[i].b );
+ break;
+
+ default:
+ colors16[i] = PIXEL_RGBA4444( entries[i].a,
+ (alpha * entries[i].r) >> 8,
+ (alpha * entries[i].g) >> 8,
+ (alpha * entries[i].b) >> 8 );
+ }
+ }
+ }
+ else {
+ for (i=0; i<gfxs->Blut->num_entries; i++)
+ colors16[i] = PIXEL_RGBA4444( entries[i].a, entries[i].r, entries[i].g, entries[i].b );
+ }
+ break;
+
+ case DSPF_RGB444:
+ for (i=0; i<gfxs->Blut->num_entries; i++)
+ colors16[i] = PIXEL_RGB444( entries[i].r, entries[i].g, entries[i].b );
+ break;
+
+ default:
+ D_UNIMPLEMENTED();
+ }
+
+ ctx.colors = colors;
+
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
+ if (DFB_PIXELFORMAT_IS_INDEXED( gfxs->dst_format ))
+ ctx.key = state->src_colorkey;
+ else {
+ const DFBColor *color = &entries[state->src_colorkey % gfxs->Blut->num_entries];
+
+ ctx.key = dfb_color_to_pixel( gfxs->dst_format, color->r, color->g, color->b );
+ }
+ }
+ }
+ else {
+ ctx.colors = NULL;
+
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
+ DFBColor color;
+
+ dfb_pixel_to_color( gfxs->src_format, state->src_colorkey, &color );
+
+ ctx.key = dfb_color_to_pixel( gfxs->dst_format, color.r, color.g, color.b );
+ }
+ }
+
+ if (state->blittingflags & DSBLIT_COLORKEY_PROTECT) {
+ if (DFB_PIXELFORMAT_IS_INDEXED( gfxs->dst_format ))
+ ctx.protect = state->colorkey.index;
+ else
+ ctx.protect = dfb_color_to_pixel( gfxs->dst_format,
+ state->colorkey.r,
+ state->colorkey.g,
+ state->colorkey.b );
+ }
+
+ dst = gfxs->dst_org[0] + drect->y * gfxs->dst_pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, drect->x );
+ src = gfxs->src_org[0] + srect->y * gfxs->src_pitch + DFB_BYTES_PER_LINE( gfxs->src_format, srect->x );
+
+ stretch( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
+ srect->w, srect->h, drect->w, drect->h, &ctx );
+
+#if 0 /* FIXME: repair */
+ switch (gfxs->dst_format) {
+ case DSPF_NV16:
+ ctx.clip.x1 /= 2;
+ ctx.clip.x2 /= 2;
+ if (srect->w < drect->w || srect->h < drect->h) {
+ stretch_hvx_nv16_uv_up( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
+ srect->w/2, srect->h, drect->w/2, drect->h, &ctx );
+ }
+ else {
+ stretch_hvx_nv16_uv_down( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
+ srect->w/2, srect->h, drect->w/2, drect->h, &ctx );
+ }
+ break;
+
+ default:
+ break;
+ }
+#endif
+
+ return true;
+}
+#endif /* DFB_SMOOTH_SCALING */
+
+void gStretchBlit( CardState *state, DFBRectangle *srect, DFBRectangle *drect )
+{
+ GenefxState *gfxs = state->gfxs;
+ DFBRectangle orect = *drect;
+
+ int fx, fy;
+ int ix, iy;
+ int h;
+
+ D_ASSERT( gfxs != NULL );
+
+ if (dfb_config->software_warn) {
+ D_WARN( "StretchBlit (%4d,%4d-%4dx%4d) %6s, flags 0x%08x, color 0x%02x%02x%02x%02x, source (%4d,%4d-%4dx%4d) %6s",
+ drect->x, drect->y, drect->w, drect->h, dfb_pixelformat_name(gfxs->dst_format), state->blittingflags,
+ state->color.a, state->color.r, state->color.g, state->color.b, srect->x, srect->y, srect->w, srect->h,
+ dfb_pixelformat_name(gfxs->src_format) );
+ }
+
+ CHECK_PIPELINE();
+
+#if DFB_SMOOTH_SCALING
+ if (state->render_options & (DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE) &&
+ stretch_hvx( state, srect, drect ))
+ return;
+#endif
+
+ /* Clip destination rectangle. */
+ if (!dfb_rectangle_intersect_by_region( drect, &state->clip ))
+ return;
+
+ /* Calculate fractions. */
+ fx = (srect->w << 16) / orect.w;
+ fy = (srect->h << 16) / orect.h;
+
+ /* Calculate horizontal phase and offset. */
+ ix = fx * (drect->x - orect.x);
+ srect->x += ix >> 16;
+ ix &= 0xFFFF;
+
+ /* Calculate vertical phase and offset. */
+ iy = fy * (drect->y - orect.y);
+ srect->y += iy >> 16;
+ iy &= 0xFFFF;
+
+ /* Adjust source size. */
+ srect->w = ((drect->w * fx + ix) + 0xFFFF) >> 16;
+ srect->h = ((drect->h * fy + iy) + 0xFFFF) >> 16;
+
+ D_ASSERT( srect->x + srect->w <= state->source->config.size.w );
+ D_ASSERT( srect->y + srect->h <= state->source->config.size.h );
+ D_ASSERT( drect->x + drect->w <= state->clip.x2 + 1 );
+ D_ASSERT( drect->y + drect->h <= state->clip.y2 + 1 );
+
+
+ if (!ABacc_prepare( gfxs, MAX( srect->w, drect->w ) ))
+ return;
+
+
+ switch (gfxs->src_format) {
+ case DSPF_A4:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ srect->x &= ~1;
+ break;
+ default:
+ break;
+ }
+
+ switch (gfxs->dst_format) {
+ case DSPF_A4:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ drect->x &= ~1;
+ break;
+ default:
+ break;
+ }
+
+ gfxs->Slen = srect->w;
+ gfxs->Dlen = drect->w;
+ gfxs->length = gfxs->Dlen;
+ gfxs->SperD = fx;
+ gfxs->Xphase = ix;
+
+ h = drect->h;
+
+ Aop_xy( gfxs, drect->x, drect->y );
+ Bop_xy( gfxs, srect->x, srect->y );
+
+ while (h--) {
+ RUN_PIPELINE();
+
+ Aop_next( gfxs );
+
+ iy += fy;
+
+ while (iy > 0xFFFF) {
+ iy -= 0x10000;
+ Bop_next( gfxs );
+ }
+ }
+
+ ABacc_flush( gfxs );
+}
+
+
+#ifdef USE_MMX
+
+#include "generic_mmx.h"
+
+/*
+ * patches function pointers to MMX functions
+ */
+static void gInit_MMX( void )
+{
+ use_mmx = 1;
+
+/********************************* Sop_PFI_Sto_Dacc ***************************/
+// Sop_PFI_Sto_Dacc[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = Sop_argb_Sto_Dacc_MMX;
+/********************************* Sop_PFI_to_Dacc ****************************/
+// Sop_PFI_to_Dacc[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)] = Sop_rgb16_to_Dacc_MMX;
+// Sop_PFI_to_Dacc[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Sop_rgb32_to_Dacc_MMX;
+// Sop_PFI_to_Dacc[DFB_PIXELFORMAT_INDEX(DSPF_ARGB )] = Sop_argb_to_Dacc_MMX;
+/********************************* Sacc_to_Aop_PFI ****************************/
+// Sacc_to_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)] = Sacc_to_Aop_rgb16_MMX;
+// Sacc_to_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Sacc_to_Aop_rgb32_MMX;
+/********************************* Xacc_blend *********************************/
+ Xacc_blend[DSBF_SRCALPHA-1] = Xacc_blend_srcalpha_MMX;
+ Xacc_blend[DSBF_INVSRCALPHA-1] = Xacc_blend_invsrcalpha_MMX;
+/********************************* Dacc_modulation ****************************/
+ Dacc_modulation[DSBLIT_BLEND_ALPHACHANNEL |
+ DSBLIT_BLEND_COLORALPHA |
+ DSBLIT_COLORIZE] = Dacc_modulate_argb_MMX;
+/********************************* misc accumulator operations ****************/
+ SCacc_add_to_Dacc = SCacc_add_to_Dacc_MMX;
+ Sacc_add_to_Dacc = Sacc_add_to_Dacc_MMX;
+ Dacc_YCbCr_to_RGB = Dacc_YCbCr_to_RGB_MMX;
+ Dacc_RGB_to_YCbCr = Dacc_RGB_to_YCbCr_MMX;
+}
+
+#endif
+
+
+#if SIZEOF_LONG == 8
+
+#include "generic_64.h"
+
+/*
+ * patches function pointers to 64bit functions
+ */
+static void gInit_64bit( void )
+{
+/********************************* Cop_to_Aop_PFI ********************************/
+ Cop_to_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Cop_to_Aop_32_64;
+ Cop_to_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = Cop_to_Aop_32_64;
+ Cop_to_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_AiRGB)] = Cop_to_Aop_32_64;
+/********************************* Bop_PFI_Kto_Aop_PFI ***************************/
+ Bop_PFI_Kto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Bop_rgb32_Kto_Aop_64;
+ Bop_PFI_Kto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = Bop_rgb32_Kto_Aop_64;
+ Bop_PFI_Kto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_AiRGB)] = Bop_rgb32_Kto_Aop_64;
+/********************************* Bop_PFI_tKo_Aop_PFI ***************************/
+ Bop_PFI_toK_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Bop_rgb32_toK_Aop_64;
+ Bop_PFI_toK_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = Bop_rgb32_toK_Aop_64;
+ Bop_PFI_toK_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_AiRGB)] = Bop_rgb32_toK_Aop_64;
+/********************************* Bop_PFI_Sto_Aop_PFI ***************************/
+ Bop_PFI_Sto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Bop_32_Sto_Aop_64;
+ Bop_PFI_Sto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = Bop_32_Sto_Aop_64;
+ Bop_PFI_Sto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_AiRGB)] = Bop_32_Sto_Aop_64;
+/********************************* misc accumulator operations *******************/
+ Dacc_xor = Dacc_xor_64;
+}
+
+#endif
diff --git a/Source/DirectFB/src/gfx/generic/generic.h b/Source/DirectFB/src/gfx/generic/generic.h
new file mode 100755
index 0000000..7c73c40
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/generic.h
@@ -0,0 +1,174 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __GENERIC_H__
+#define __GENERIC_H__
+
+#include <dfb_types.h>
+
+#include <directfb.h>
+#include <core/coretypes.h>
+#include <core/gfxcard.h>
+
+/* this order is required for Intel with MMX, how about bigendian? */
+
+typedef union {
+ struct {
+ u16 b;
+ u16 g;
+ u16 r;
+ u16 a;
+ } RGB;
+ struct {
+ u16 u;
+ u16 v;
+ u16 y;
+ u16 a;
+ } YUV;
+} GenefxAccumulator;
+
+
+typedef struct _GenefxState GenefxState;
+
+typedef void (*GenefxFunc)(GenefxState *gfxs);
+
+/*
+ * State of the virtual graphics processing unit "Genefx" (pron. 'genie facts').
+ */
+struct _GenefxState {
+ GenefxFunc funcs[32];
+
+ int length; /* span length */
+ int Slen; /* span length (source) */
+ int Dlen; /* span length (destination) */
+
+ /*
+ * state values
+ */
+ void *dst_org[3];
+ void *src_org[3];
+ int dst_pitch;
+ int src_pitch;
+
+ int dst_bpp;
+ int src_bpp;
+
+ DFBSurfaceCapabilities dst_caps;
+ DFBSurfaceCapabilities src_caps;
+
+ DFBSurfacePixelFormat src_format;
+ DFBSurfacePixelFormat dst_format;
+
+ int dst_height;
+ int src_height;
+
+ int dst_field_offset;
+ int src_field_offset;
+
+ DFBColor color;
+
+ /*
+ * operands
+ */
+ void *Aop[3];
+ void *Bop[3];
+ u32 Cop;
+
+ int Astep;
+ int Bstep;
+
+ u8 YCop;
+ u8 CbCop;
+ u8 CrCop;
+
+ int Aop_field;
+ int Bop_field;
+
+ int AopY;
+ int BopY;
+
+ /*
+ * color keys
+ */
+ u32 Dkey;
+ u32 Skey;
+
+ /*
+ * color lookup tables
+ */
+ CorePalette *Alut;
+ CorePalette *Blut;
+
+ /*
+ * accumulators
+ */
+ void *ABstart;
+ int ABsize;
+ GenefxAccumulator *Aacc;
+ GenefxAccumulator *Bacc;
+ GenefxAccumulator *Tacc; /* for simultaneous S+D blending */
+ GenefxAccumulator Cacc;
+ GenefxAccumulator SCacc;
+
+ /*
+ * dataflow control
+ */
+ GenefxAccumulator *Xacc; /* writing pointer for blending */
+ GenefxAccumulator *Yacc; /* input pointer for blending */
+ GenefxAccumulator *Dacc;
+ GenefxAccumulator *Sacc;
+
+ void **Sop;
+ CorePalette *Slut;
+
+ int Ostep; /* controls horizontal blitting direction */
+
+ int SperD; /* for scaled routines only */
+ int Xphase; /* initial value for fractional steps (zero if not clipped) */
+
+ bool need_accumulator;
+
+ int *trans;
+ int num_trans;
+};
+
+
+void gGetDriverInfo( GraphicsDriverInfo *info );
+void gGetDeviceInfo( GraphicsDeviceInfo *info );
+
+bool gAcquire ( CardState *state, DFBAccelerationMask accel );
+void gRelease ( CardState *state );
+
+void gFillRectangle ( CardState *state, DFBRectangle *rect );
+void gDrawLine ( CardState *state, DFBRegion *line );
+
+void gBlit ( CardState *state, DFBRectangle *rect, int dx, int dy );
+void gStretchBlit ( CardState *state, DFBRectangle *srect, DFBRectangle *drect );
+
+
+#endif
diff --git a/Source/DirectFB/src/gfx/generic/generic_64.h b/Source/DirectFB/src/gfx/generic/generic_64.h
new file mode 100755
index 0000000..b0079ce
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/generic_64.h
@@ -0,0 +1,207 @@
+/*
+ (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.
+*/
+
+
+static void Cop_to_Aop_32_64( GenefxState *gfxs )
+{
+ int w, l = gfxs->length;
+ u32 *D = gfxs->Aop[0];
+ u32 Cop = gfxs->Cop;
+ u64 DCop = ((u64)Cop << 32) | Cop;
+
+ if ((long)D & 4) {
+ *D++ = Cop;
+ l--;
+ }
+
+ for (w = l >> 1; w; w--) {
+ *((u64*)D) = DCop;
+ D += 2;
+ }
+
+ if (l & 1)
+ *D = Cop;
+}
+
+static void Bop_rgb32_Kto_Aop_64( GenefxState *gfxs )
+{
+ int w, l = gfxs->length;
+ u32 *D = gfxs->Aop[0];
+ u32 *S = gfxs->Bop[0];
+ u32 Skey = gfxs->Skey;
+ u64 DSkey = ((u64)Skey << 32) | Skey;
+
+ if ((long)D & 4) {
+ if ((*S & 0x00ffffff) != Skey)
+ *D = *S;
+ D++;
+ S++;
+ l--;
+ }
+
+ for (w = l >> 1; w; w--) {
+ u64 s = *((u64*)S);
+
+ if ((s & 0x00ffffff00ffffffull) != DSkey) {
+ if ((s & 0x00ffffff00000000ull) !=
+ (DSkey & 0x00ffffff00000000ull)) {
+ if ((s & 0x0000000000ffffffull) !=
+ (DSkey & 0x0000000000ffffffull)) {
+ *((u64*)D) = s;
+ }
+ else {
+#ifdef WORDS_BIGENDIAN
+ D[0] = (u32)(s >> 32);
+#else
+ D[1] = (u32)(s >> 32);
+#endif
+ }
+ }
+ else {
+#ifdef WORDS_BIGENDIAN
+ D[1] = (u32)s;
+#else
+ D[0] = (u32)s;
+#endif
+ }
+ }
+ S += 2;
+ D += 2;
+ }
+
+ if (l & 1) { /* do the last potential pixel */
+ if ((*S & 0x00ffffff) != Skey)
+ *D = *S;
+ }
+}
+
+static void Bop_rgb32_toK_Aop_64( GenefxState *gfxs )
+{
+ int w, l = gfxs->length;
+ u32 *D = gfxs->Aop[0];
+ u32 *S = gfxs->Bop[0];
+ u32 Dkey = gfxs->Dkey;
+ u64 DDkey = ((u64)Dkey << 32) | Dkey;
+
+ if ((long)D & 4) {
+ if ((*D & 0x00ffffff) == Dkey)
+ *D = *S;
+ D++;
+ S++;
+ l--;
+ }
+
+ for (w = l >> 1; w; w--) {
+ u64 d = *((u64*)D);
+
+ if ((d & 0x00ffffff00ffffffull) != DDkey) {
+ if ((d & 0x00ffffff00000000ull) ==
+ (DDkey & 0x00ffffff00000000ull)) {
+ if ((d & 0x0000000000ffffffull) ==
+ (DDkey & 0x0000000000ffffffull)) {
+ *((u64*)D) = *((u64*)S);
+ }
+ else {
+#ifdef WORDS_BIGENDIAN
+ D[0] = S[0];
+#else
+ D[1] = S[1];
+#endif
+ }
+ }
+ else {
+#ifdef WORDS_BIGENDIAN
+ D[1] = S[1];
+#else
+ D[0] = S[0];
+#endif
+ }
+ }
+ S += 2;
+ D += 2;
+ }
+
+ if (l & 1) { /* do the last potential pixel */
+ if ((*D & 0x00ffffff) == Dkey)
+ *D = *S;
+ }
+}
+
+static void Bop_32_Sto_Aop_64( GenefxState *gfxs )
+{
+ int w, l = gfxs->length;
+ int i = 0;
+ u32 *D = gfxs->Aop[0];
+ u32 *S = gfxs->Bop[0];
+ int SperD = gfxs->SperD;
+ int SperD2 = SperD << 1;
+
+ if ((long)D & 4) {
+ *D++ = *S;
+ i += SperD;
+ l--;
+ }
+
+ for (w = l >> 1; w; w--) {
+#ifdef WORDS_BIGENDIAN
+ *((u64*)D) = ((u64)S[i>>16] << 32) | S[(i+SperD)>>16];
+#else
+ *((u64*)D) = ((u64)S[(i+SperD)>>16] << 32) | S[i>>16];
+#endif
+ D += 2;
+ i += SperD2;
+ }
+
+ if (l & 1)
+ *D = S[i>>16];
+}
+
+static void Dacc_xor_64( GenefxState *gfxs )
+{
+ int w = gfxs->length;
+ u64 *D = (u64*)gfxs->Dacc;
+ u64 color;
+
+#ifdef WORDS_BIGENDIAN
+ color = ((u64)gfxs->color.b << 48) |
+ ((u64)gfxs->color.g << 32) |
+ ((u64)gfxs->color.r << 16) |
+ ((u64)gfxs->color.a);
+#else
+ color = ((u64)gfxs->color.a << 48) |
+ ((u64)gfxs->color.r << 32) |
+ ((u64)gfxs->color.g << 16) |
+ ((u64)gfxs->color.b);
+#endif
+
+ for (; w; w--) {
+ *D ^= color;
+ D++;
+ }
+}
+
diff --git a/Source/DirectFB/src/gfx/generic/generic_dummy.c b/Source/DirectFB/src/gfx/generic/generic_dummy.c
new file mode 100755
index 0000000..00032a7
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/generic_dummy.c
@@ -0,0 +1,94 @@
+/*
+ (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 <directfb.h>
+
+#include <core/gfxcard.h>
+
+#include <direct/messages.h>
+
+
+void
+gGetDriverInfo( GraphicsDriverInfo *info )
+{
+ D_INFO( "DirectFB/Genefx: No software fallbacks supported\n" );
+
+ snprintf( info->name, DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH, "Software Driver" );
+ snprintf( info->vendor, DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH, "directfb.org" );
+
+ info->version.major = 0;
+ info->version.minor = 0;
+}
+
+void
+gGetDeviceInfo( GraphicsDeviceInfo *info )
+{
+ snprintf( info->name, DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "Software Rasterizer" );
+ snprintf( info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Dummy" );
+
+ info->caps.accel = DFXL_NONE;
+ info->caps.flags = 0;
+ info->caps.drawing = DSDRAW_NOFX;
+ info->caps.blitting = DSBLIT_NOFX;
+}
+
+bool
+gAcquire( CardState *state, DFBAccelerationMask accel )
+{
+ return false;
+}
+
+void
+gRelease( CardState *state )
+{
+}
+
+void
+gFillRectangle( CardState *state, DFBRectangle *rect )
+{
+}
+
+void
+gDrawLine( CardState *state, DFBRegion *line )
+{
+}
+
+void
+gBlit( CardState *state, DFBRectangle *rect, int dx, int dy )
+{
+}
+
+void
+gStretchBlit( CardState *state, DFBRectangle *srect, DFBRectangle *drect )
+{
+}
+
diff --git a/Source/DirectFB/src/gfx/generic/generic_mmx.h b/Source/DirectFB/src/gfx/generic/generic_mmx.h
new file mode 100755
index 0000000..57757f3
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/generic_mmx.h
@@ -0,0 +1,659 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+
+#define __aligned( n ) __attribute__ ((aligned((n))))
+
+
+static void SCacc_add_to_Dacc_MMX( GenefxState *gfxs )
+{
+ __asm__ __volatile__ (
+ " movq %2, %%mm0\n"
+ ".align 16\n"
+ "1:\n"
+ " movq (%0), %%mm1\n"
+ " paddw %%mm0, %%mm1\n"
+ " movq %%mm1, (%0)\n"
+ " add $8, %0\n"
+ " dec %1\n"
+ " jnz 1b\n"
+ " emms"
+ : /* no outputs */
+ : "D" (gfxs->Dacc), "c" (gfxs->length), "m" (gfxs->SCacc)
+ : "%st", "memory");
+}
+
+static void Dacc_modulate_argb_MMX( GenefxState *gfxs )
+{
+ __asm__ __volatile__ (
+ "movq %2, %%mm0\n\t"
+ ".align 16\n"
+ "1:\n\t"
+ "testw $0xF000, 6(%0)\n\t"
+ "jnz 2f\n\t"
+ "movq (%0), %%mm1\n\t"
+ "pmullw %%mm0, %%mm1\n\t"
+ "psrlw $8, %%mm1\n\t"
+ "movq %%mm1, (%0)\n"
+ ".align 16\n"
+ "2:\n\t"
+ "add $8, %0\n\t"
+ "dec %1\n\t"
+ "jnz 1b\n\t"
+ "emms"
+ : /* no outputs */
+ : "D" (gfxs->Dacc), "c" (gfxs->length), "m" (gfxs->Cacc)
+ : "%st", "memory");
+}
+
+static void Sacc_add_to_Dacc_MMX( GenefxState *gfxs )
+{
+ __asm__ __volatile__ (
+ ".align 16\n"
+ "1:\n\t"
+ "movq (%2), %%mm0\n\t"
+ "movq (%0), %%mm1\n\t"
+ "paddw %%mm1, %%mm0\n\t"
+ "movq %%mm0, (%0)\n\t"
+ "add $8, %0\n\t"
+ "add $8, %2\n\t"
+ "dec %1\n\t"
+ "jnz 1b\n\t"
+ "emms"
+ : /* no outputs */
+ : "D" (gfxs->Dacc), "c" (gfxs->length), "S" (gfxs->Sacc)
+ : "%st", "memory");
+}
+
+static void Sacc_to_Aop_rgb16_MMX( GenefxState *gfxs )
+{
+ static const u32 preload[] = { 0xFF00FF00, 0x0000FF00 };
+ static const u32 mask[] = { 0x00FC00F8, 0x000000F8 };
+ static const u32 pm[] = { 0x01000004, 0x00000004 };
+
+ __asm__ __volatile__ (
+ "movq %3, %%mm7\n\t"
+ "movq %4, %%mm5\n\t"
+ "movq %5, %%mm4\n\t"
+ ".align 16\n"
+ "1:\n\t"
+ "testw $0xF000, 6(%2)\n\t"
+ "jnz 2f\n\t"
+ "movq (%2), %%mm0\n\t"
+ "paddusw %%mm7, %%mm0\n\t"
+ "pand %%mm5, %%mm0\n\t"
+ "pmaddwd %%mm4, %%mm0\n\t"
+ "psrlq $5, %%mm0\n\t"
+ "movq %%mm0, %%mm1\n\t"
+ "psrlq $21, %%mm0\n\t"
+ "por %%mm1, %%mm0\n\t"
+ "movd %%mm0, %%eax\n\t"
+ "movw %%ax, (%0)\n\t"
+ ".align 16\n"
+ "2:\n\t"
+ "add $8, %2\n\t"
+ "add $2, %0\n\t"
+ "dec %1\n\t"
+ "jnz 1b\n\t"
+ "emms"
+ : /* no outputs */
+ : "D" (gfxs->Aop[0]), "c" (gfxs->length), "S" (gfxs->Sacc),
+ "m" (*preload), "m" (*mask), "m" (*pm)
+ : "%eax", "%st", "memory");
+}
+
+static void Sacc_to_Aop_rgb32_MMX( GenefxState *gfxs )
+{
+ static const u32 preload[] = { 0xFF00FF00, 0x0000FF00 };
+ static const u32 postload[] = { 0x00FF00FF, 0x000000FF };
+ static const u32 pm[] = { 0x01000001, 0x00000001 };
+
+ __asm__ __volatile__ (
+ "movq %3, %%mm1\n\t"
+ "movq %4, %%mm2\n\t"
+ "movq %5, %%mm3\n\t"
+ ".align 16\n"
+ "1:\n\t"
+ "testw $0xF000, 6(%2)\n\t"
+ "jnz 2f\n\t"
+ "movq (%2), %%mm0\n\t"
+ "paddusw %%mm1, %%mm0\n\t"
+ "pand %%mm2, %%mm0\n\t"
+ "pmaddwd %%mm3, %%mm0\n\t"
+ "movq %%mm0, %%mm4\n\t"
+ "psrlq $16, %%mm0\n\t"
+ "por %%mm0, %%mm4\n\t"
+ "movd %%mm4, (%0)\n\t"
+ ".align 16\n"
+ "2:\n\t"
+ "add $8, %2\n\t"
+ "add $4, %0\n\t"
+ "dec %1\n\t"
+ "jnz 1b\n\t"
+ "emms"
+ : /* no outputs */
+ : "D" (gfxs->Aop[0]), "c" (gfxs->length), "S" (gfxs->Sacc),
+ "m" (*preload), "m" (*postload), "m" (*pm)
+ : "%st", "memory");
+}
+
+__attribute__((no_instrument_function))
+static void Sop_argb_Sto_Dacc_MMX( GenefxState *gfxs )
+{
+ static const u32 zeros[] = { 0, 0 };
+ int i = 0;
+
+ __asm__ __volatile__ (
+ "movq %5, %%mm0\n\t"
+ ".align 16\n"
+ "1:\n\t"
+ "movd (%3), %%mm1\n\t"
+ "punpcklbw %%mm0, %%mm1\n\t"
+ ".align 16\n"
+ "2:\n\t"
+ "movq %%mm1, (%1)\n\t"
+ "dec %2\n\t"
+ "jz 3f\n\t"
+ "add $8, %1\n\t"
+ "add %4, %0\n\t"
+ "testl $0xFFFF0000, %0\n\t"
+ "jz 2b\n\t"
+ "movl %0, %%edx\n\t"
+ "andl $0xFFFF0000, %%edx\n\t"
+ "shrl $14, %%edx\n\t"
+#ifdef ARCH_X86_64
+ "addq %%rdx, %3\n\t"
+#else
+ "addl %%edx, %3\n\t"
+#endif
+ "andl $0xFFFF, %0\n\t"
+ "jmp 1b\n"
+ "3:\n\t"
+ "emms"
+ : "=r" (i)
+ : "D" (gfxs->Dacc), "c" (gfxs->length), "S" (gfxs->Sop[0]),
+ "a" (gfxs->SperD), "m" (*zeros), "0" (i)
+ : "%edx", "%st", "memory");
+}
+
+static void Sop_argb_to_Dacc_MMX( GenefxState *gfxs )
+{
+ static const u32 zeros[] = { 0, 0 };
+
+ __asm__ __volatile__ (
+ "movq %3, %%mm0\n\t"
+ ".align 16\n"
+ "1:\n\t"
+ "movd (%2), %%mm1\n\t"
+ "punpcklbw %%mm0, %%mm1\n\t"
+ "movq %%mm1, (%0)\n\t"
+ "add $4, %2\n\t"
+ "add $8, %0\n\t"
+ "dec %1\n\t"
+ "jnz 1b\n\t"
+ "emms"
+ : /* no outputs */
+ : "D" (gfxs->Dacc), "c" (gfxs->length),
+ "S" (gfxs->Sop[0]), "m" (*zeros)
+ : "%st", "memory");
+}
+
+static void Sop_rgb16_to_Dacc_MMX( GenefxState *gfxs )
+{
+ static const u32 mask[] = { 0x07E0001F, 0x0000F800 };
+ static const u32 smul[] = { 0x00200800, 0x00000001 };
+ static const u32 alpha[] = { 0x00000000, 0x00FF0000 };
+
+ __asm__ __volatile__ (
+ "movq %3, %%mm4\n\t"
+ "movq %4, %%mm5\n\t"
+ "movq %5, %%mm7\n\t"
+ ".align 16\n"
+ "1:\n\t"
+ "movq (%2), %%mm0\n\t"
+ /* 1. Konvertierung nach 24 bit interleaved */
+ "movq %%mm0, %%mm3\n\t"
+ "punpcklwd %%mm3, %%mm3\n\t"
+ "punpckldq %%mm3, %%mm3\n\t"
+ "pand %%mm4, %%mm3\n\t"
+ "pmullw %%mm5, %%mm3\n\t"
+ "psrlw $8, %%mm3\n\t"
+ /* mm3 enthaelt jetzt: 0000 00rr 00gg 00bb des alten pixels */
+ "por %%mm7, %%mm3\n\t"
+ "movq %%mm3, (%0)\n\t"
+ "dec %1\n\t"
+ "jz 2f\n\t"
+ "psrlq $16, %%mm0\n\t"
+ "add $8, %0\n\t"
+ /* 2. Konvertierung nach 24 bit interleaved */
+ "movq %%mm0, %%mm3\n\t"
+ "punpcklwd %%mm3, %%mm3\n\t"
+ "punpckldq %%mm3, %%mm3\n\t"
+ "pand %%mm4, %%mm3\n\t"
+ "pmullw %%mm5, %%mm3\n\t"
+ "psrlw $8, %%mm3\n\t"
+ /* mm3 enthaelt jetzt: 0000 00rr 00gg 00bb des alten pixels */
+ "por %%mm7, %%mm3\n\t"
+ "movq %%mm3, (%0)\n\t"
+ "dec %1\n\t"
+ "jz 2f\n\t"
+ "psrlq $16, %%mm0\n\t"
+ "add $8, %0\n\t"
+ /* 3. Konvertierung nach 24 bit interleaved */
+ "movq %%mm0, %%mm3\n\t"
+ "punpcklwd %%mm3, %%mm3\n\t"
+ "punpckldq %%mm3, %%mm3\n\t"
+ "pand %%mm4, %%mm3\n\t"
+ "pmullw %%mm5, %%mm3\n\t"
+ "psrlw $8, %%mm3\n\t"
+ /* mm3 enthaelt jetzt: 0000 00rr 00gg 00bb des alten pixels */
+ "por %%mm7, %%mm3\n\t"
+ "movq %%mm3, (%0)\n\t"
+ "dec %1\n\t"
+ "jz 2f\n\t"
+ "psrlq $16, %%mm0\n\t"
+ "add $8, %0\n\t"
+ /* 4. Konvertierung nach 24 bit interleaved */
+ "movq %%mm0, %%mm3\n\t"
+ "punpcklwd %%mm3, %%mm3\n\t"
+ "punpckldq %%mm3, %%mm3\n\t"
+ "pand %%mm4, %%mm3\n\t"
+ "pmullw %%mm5, %%mm3\n\t"
+ "psrlw $8, %%mm3\n\t"
+ /* mm3 enthaelt jetzt: 0000 00rr 00gg 00bb des alten pixels */
+ "por %%mm7, %%mm3\n\t"
+ "movq %%mm3, (%0)\n\t"
+ "dec %1\n\t"
+ "jz 2f\n\t"
+ "add $8, %0\n\t"
+ "add $8, %2\n\t"
+ "jmp 1b\n"
+ "2:\n\t"
+ "emms"
+ : /* no outputs */
+ : "D" (gfxs->Dacc), "c" (gfxs->length), "S" (gfxs->Sop[0]),
+ "m" (*mask), "m" (*smul), "m" (*alpha)
+ : "%st", "memory");
+}
+
+static void Sop_rgb32_to_Dacc_MMX( GenefxState *gfxs )
+{
+ static const u32 alpha[] = { 0, 0x00FF0000 };
+ static const u32 zeros[] = { 0, 0 };
+
+ __asm__ __volatile__ (
+ "movq %3, %%mm7\n\t"
+ "movq %4, %%mm6\n\t"
+ ".align 16\n"
+ "1:\n\t"
+ "movd (%2), %%mm0\n\t"
+ "punpcklbw %%mm6, %%mm0\n\t"
+ "por %%mm7, %%mm0\n\t"
+ "movq %%mm0, (%0)\n\t"
+ "add $4, %2\n\t"
+ "add $8, %0\n\t"
+ "dec %1\n\t"
+ "jnz 1b\n\t"
+ "emms"
+ : /* no outputs */
+ : "D" (gfxs->Dacc), "c" (gfxs->length), "S" (gfxs->Sop[0]),
+ "m" (*alpha), "m" (*zeros)
+ : "%st", "memory");
+}
+
+static void Xacc_blend_invsrcalpha_MMX( GenefxState *gfxs )
+{
+ static const u32 einser[] = { 0x01000100, 0x01000100 };
+ static const u32 zeros[] = { 0, 0 };
+
+ __asm__ __volatile__ (
+ "movq %3, %%mm7\n\t"
+ "cmp $0, %2\n\t"
+ "jne 1f\n\t"
+ "movq %4, %%mm6\n\t"
+ "movd %5, %%mm0\n\t"
+ "punpcklbw %%mm6, %%mm0\n\t" /* mm0 = 00aa 00rr 00gg 00bb */
+ "punpcklwd %%mm0, %%mm0\n\t" /* mm0 = 00aa 00aa xxxx xxxx */
+ "movq %%mm7, %%mm1\n\t"
+ "punpckldq %%mm0, %%mm0\n\t" /* mm0 = 00aa 00aa 00aa 00aa */
+ "psubw %%mm0, %%mm1\n\t"
+
+ ".align 16\n"
+ "2:\n\t" /* blend from color */
+ "testw $0xF000, 6(%0)\n\t"
+ "jnz 3f\n\t"
+ "movq (%0), %%mm0\n\t"
+ "pmullw %%mm1, %%mm0\n\t"
+ "psrlw $8, %%mm0\n\t"
+ "movq %%mm0, (%6)\n\t"
+ "jmp 4f\n\t"
+ "3:\n\t"
+ "movq (%0), %%mm0\n\t"
+ "movq %%mm0, (%6)\n\t"
+ "4:\n\t"
+ "add $8, %0\n\t"
+ "add $8, %6\n\t"
+ "dec %1\n\t"
+ "jnz 2b\n\t"
+ "jmp 9f\n\t"
+
+ ".align 16\n"
+ "1:\n\t" /* blend from Sacc */
+ "testw $0xF000, 6(%0)\n\t"
+ "jnz 5f\n\t"
+ "movq (%2), %%mm2\n\t"
+ "movq (%0), %%mm0\n\t"
+ "punpckhwd %%mm2, %%mm2\n\t" /* mm2 = 00aa 00aa xxxx xxxx */
+ "movq %%mm7, %%mm1\n\t"
+ "punpckhdq %%mm2, %%mm2\n\t" /* mm2 = 00aa 00aa 00aa 00aa */
+ "psubw %%mm2, %%mm1\n\t"
+ "pmullw %%mm1, %%mm0\n\t"
+ "psrlw $8, %%mm0\n\t"
+ "movq %%mm0, (%6)\n\t"
+ "jmp 6f\n\t"
+ "5:\n\t"
+ "movq (%0), %%mm0\n\t"
+ "movq %%mm0, (%6)\n\t"
+ "6:\n\t"
+ "add $8, %2\n\t"
+ "add $8, %0\n\t"
+ "add $8, %6\n\t"
+ "dec %1\n\t"
+ "jnz 1b\n\t"
+ "9:\n\t"
+ "emms"
+ : /* no outputs */
+ : "D" (gfxs->Yacc), "c" (gfxs->length), "S" (gfxs->Sacc),
+ "m" (*einser), "m" (*zeros), "m" (gfxs->color), "r" (gfxs->Xacc)
+ : "%st", "memory");
+}
+
+static void Xacc_blend_srcalpha_MMX( GenefxState *gfxs )
+{
+ static const u32 ones[] = { 0x00010001, 0x00010001 };
+ static const u32 zeros[] = { 0, 0 };
+
+ __asm__ __volatile__ (
+ "movq %3, %%mm7\n\t"
+ "cmp $0, %2\n\t"
+ "jne 3f\n\t"
+ "movq %4, %%mm6\n\t"
+ "movd %5, %%mm0\n\t"
+ "punpcklbw %%mm6, %%mm0\n\t" /* mm0 = 00aa 00rr 00gg 00bb */
+ "punpcklwd %%mm0, %%mm0\n\t" /* mm0 = 00aa 00aa xxxx xxxx */
+ "punpckldq %%mm0, %%mm0\n\t" /* mm0 = 00aa 00aa 00aa 00aa */
+ "paddw %%mm7, %%mm0\n\t"
+
+ ".align 16\n\t"
+ "4:\n\t" /* blend from color */
+ "testw $0xF000, 6(%0)\n\t"
+ "jnz 6f\n\t"
+ "movq (%0), %%mm1\n\t"
+ "pmullw %%mm0, %%mm1\n\t"
+ "psrlw $8, %%mm1\n\t"
+ "movq %%mm1, (%6)\n\t"
+ "jmp 1f\n\t"
+ "6:\n\t"
+ "movq (%0), %%mm1\n\t"
+ "movq %%mm1, (%6)\n\t"
+ "1:\n\t"
+ "add $8, %0\n\t"
+ "add $8, %6\n\t"
+ "dec %1\n\t"
+ "jnz 4b\n\t"
+ "jmp 2f\n\t"
+
+ ".align 16\n\t"
+ "3:\n\t" /* blend from Sacc */
+ "testw $0xF000, 6(%0)\n\t"
+ "jnz 5f\n\t"
+ "movq (%2), %%mm0\n\t"
+ "movq (%0), %%mm1\n\t"
+ "punpckhwd %%mm0, %%mm0\n\t" /* mm2 = 00aa 00aa xxxx xxxx */
+ "punpckhdq %%mm0, %%mm0\n\t" /* mm2 = 00aa 00aa 00aa 00aa */
+ "paddw %%mm7, %%mm0\n\t"
+ "pmullw %%mm0, %%mm1\n\t"
+ "psrlw $8, %%mm1\n\t"
+ "movq %%mm1, (%6)\n\t"
+ "jmp 7f\n\t"
+ "5:\n\t"
+ "movq (%0), %%mm1\n\t"
+ "movq %%mm1, (%6)\n\t"
+ "7:\n\t"
+ "add $8, %2\n\t"
+ "add $8, %0\n\t"
+ "add $8, %6\n\t"
+ "dec %1\n\t"
+ "jnz 3b\n\t"
+ "2:\n\t"
+ "emms"
+ : /* no outputs */
+ : "D" (gfxs->Yacc), "c" (gfxs->length), "S" (gfxs->Sacc),
+ "m" (*ones), "m" (*zeros), "m" (gfxs->color), "r" (gfxs->Xacc)
+ : "%st", "memory");
+}
+
+static void Dacc_YCbCr_to_RGB_MMX( GenefxState *gfxs )
+{
+ static const u16 __aligned(8) sub0[4] = { 16, 16, 16, 16 };
+ static const u16 __aligned(8) sub1[4] = { 128, 128, 128, 128 };
+ static const s16 __aligned(8) mul[20] = {
+ 0x253F, 0x253F, 0x253F, 0x253F, // Y Coeff.
+ 0x3312, 0x3312, 0x3312, 0x3312, // V Red Coeff.
+ 0x4093, 0x4093, 0x4093, 0x4093, // U Blue Coeff.
+ -0x1A04, -0x1A04, -0x1A04, -0x1A04, // V Green Coeff.
+ -0x0C83, -0x0C83, -0x0C83, -0x0C83 // U Green Coeff.
+ };
+
+ int w = gfxs->length & 3;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ __asm__ __volatile__ (
+ "shrl $2, %1\n\t"
+ "jz 2f\n\t"
+ "pxor %%mm7, %%mm7\n\t"
+ ".align 16\n"
+ "1:\n\t"
+ "movq (%0), %%mm0\n\t" // 00 a0 00 y0 00 v0 00 u0
+ "movq 8(%0), %%mm1\n\t" // 00 a1 00 y1 00 v1 00 u1
+ "movq 16(%0), %%mm2\n\t" // 00 a2 00 y2 00 v2 00 u2
+ "movq 24(%0), %%mm3\n\t" // 00 a3 00 y3 00 v3 00 u3
+ "movq %%mm0, %%mm4\n\t" // 00 a0 00 y0 00 v0 00 u0
+ "movq %%mm2, %%mm5\n\t" // 00 a2 00 y2 00 v2 00 u2
+ "punpcklwd %%mm1, %%mm0\n\t" // 00 v1 00 v0 00 u1 00 u0
+ "punpcklwd %%mm3, %%mm2\n\t" // 00 v3 00 v2 00 u3 00 u2
+ "punpckhwd %%mm1, %%mm4\n\t" // 00 a1 00 a0 00 y1 00 y0
+ "punpckhwd %%mm3, %%mm5\n\t" // 00 a3 00 a2 00 y3 00 y2
+ "movq %%mm0, %%mm1\n\t" // 00 v1 00 v1 00 u1 00 u0
+ "movq %%mm4, %%mm3\n\t" // 00 a1 00 a0 00 y1 00 y0
+ "punpckldq %%mm2, %%mm0\n\t" // 00 u3 00 u2 00 u1 00 u0
+ "punpckldq %%mm5, %%mm3\n\t" // 00 y3 00 y2 00 y1 00 y0
+ "punpckhdq %%mm2, %%mm1\n\t" // 00 v3 00 v2 00 v1 00 v0
+ "punpckhdq %%mm5, %%mm4\n\t" // 00 a3 00 a2 00 a1 00 a0
+ /* mm0 = u, mm1 = v, mm3 = y, mm4 = a */
+ "psubw %2, %%mm3\n\t" // y -= 16
+ "psllw $3, %%mm3\n\t" // precision
+ "pmulhw (%4), %%mm3\n\t"
+ "psubw %3, %%mm1\n\t" // v -= 128
+ "psllw $3, %%mm1\n\t" // precision
+ "movq %%mm1, %%mm2\n\t" // 00 v3 00 v2 00 v1 00 v0
+ "pmulhw 8(%4), %%mm2\n\t" // vr
+ "psubw %3, %%mm0\n\t" // u -= 128
+ "psllw $3, %%mm0\n\t" // precision
+ "movq %%mm0, %%mm5\n\t" // 00 u3 00 u2 00 u1 00 u0
+ "pmulhw 16(%4), %%mm5\n\t" // ub
+ "paddw %%mm3, %%mm2\n\t" // 00 r3 00 r2 00 r1 00 r0
+ "paddw %%mm3, %%mm5\n\t" // 00 b3 00 b2 00 b1 00 b0
+ "pmulhw 24(%4), %%mm1\n\t" // vg
+ "packuswb %%mm2, %%mm2\n\t" // r3 r2 r1 r0 r3 r2 r1 r0
+ "packuswb %%mm5, %%mm5\n\t" // b3 b2 b1 b0 b3 b2 b1 b0
+ "pmulhw 32(%4), %%mm0\n\t" // ug
+ "punpcklbw %%mm7, %%mm2\n\t" // 00 r3 00 r2 00 r1 00 r0
+ "punpcklbw %%mm7, %%mm5\n\t" // 00 b3 00 b2 00 b1 00 b0
+ "paddw %%mm1, %%mm3\n\t" // y + vg
+ "paddw %%mm0, %%mm3\n\t" // 00 g3 00 g2 00 g1 00 g0
+ "packuswb %%mm3, %%mm3\n\t" // g3 g2 g1 g0 g3 g2 g1 g0
+ "punpcklbw %%mm7, %%mm3\n\t" // 00 g3 00 g2 00 g1 00 g0
+ /* mm5 = b, mm3 = g, mm2 = r, mm4 = a */
+ "movq %%mm5, %%mm0\n\t" // 00 b3 00 b2 00 b1 00 b0
+ "movq %%mm3, %%mm1\n\t" // 00 g3 00 g2 00 g1 00 g0
+ "punpcklwd %%mm2, %%mm0\n\t" // 00 r1 00 b1 00 r0 00 b0
+ "punpcklwd %%mm4, %%mm1\n\t" // 00 a1 00 g1 00 a0 00 g0
+ "punpckhwd %%mm2, %%mm5\n\t" // 00 r3 00 b3 00 r2 00 b2
+ "punpckhwd %%mm4, %%mm3\n\t" // 00 a3 00 g3 00 a2 00 g2
+ "movq %%mm0, %%mm2\n\t" // 00 r1 00 b1 00 r0 00 b0
+ "movq %%mm5, %%mm4\n\t" // 00 r3 00 b3 00 r2 00 b2
+ "punpcklwd %%mm1, %%mm0\n\t" // 00 a0 00 r0 00 g0 00 b0
+ "punpcklwd %%mm3, %%mm5\n\t" // 00 a2 00 r2 00 g2 00 b2
+ "punpckhwd %%mm1, %%mm2\n\t" // 00 a1 00 r1 00 g1 00 b1
+ "punpckhwd %%mm3, %%mm4\n\t" // 00 a3 00 r3 00 g3 00 b3
+ "movq %%mm0, (%0)\n\t"
+ "movq %%mm2, 8(%0)\n\t"
+ "movq %%mm5,16(%0)\n\t"
+ "movq %%mm4,24(%0)\n\t"
+ "add $32, %0\n\t"
+ "decl %1\n\t"
+ "jnz 1b\n\t"
+ "emms\n\t"
+ "2:"
+ : "=&D" (D)
+ : "c" (gfxs->length), "m" (*sub0), "m" (*sub1), "r" (mul), "0" (D)
+ : "memory" );
+
+ while (w) {
+ if (!(D->YUV.a & 0xF000))
+ YCBCR_TO_RGB( D->YUV.y, D->YUV.u, D->YUV.v,
+ D->RGB.r, D->RGB.g, D->RGB.b );
+
+ D++;
+ w--;
+ }
+}
+
+static void Dacc_RGB_to_YCbCr_MMX( GenefxState *gfxs )
+{
+ static const u16 __aligned(8) add0[4] = { 128, 128, 128, 128 };
+ static const u16 __aligned(8) add1[4] = { 16, 16, 16, 16 };
+ static const u16 __aligned(8) mul[24] = {
+ 0x03A5, 0x03A5, 0x03A5, 0x03A5, // Eb
+ 0x12C8, 0x12C8, 0x12C8, 0x12C8, // Eg
+ 0x0991, 0x0991, 0x0991, 0x0991, // Er
+ 0x0FE1, 0x0FE1, 0x0FE1, 0x0FE1, // Cb
+ 0x140A, 0x140A, 0x140A, 0x140A, // Cr
+ 0x1B7B, 0x1B7B, 0x1B7B, 0x1B7B // Y
+ };
+
+ int w = gfxs->length & 3;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ __asm__ __volatile__(
+ "shrl $2, %1\n\t"
+ "jz 2f\n\t"
+ "pxor %%mm7, %%mm7\n\t"
+ ".align 16\n"
+ "1:\n\t"
+ "movq (%0), %%mm0\n\t" // 00 a0 00 r0 00 g0 00 b0
+ "movq 8(%0), %%mm1\n\t" // 00 a1 00 r1 00 g1 00 b1
+ "movq 16(%0), %%mm2\n\t" // 00 a2 00 r2 00 g2 00 b2
+ "movq 24(%0), %%mm3\n\t" // 00 a3 00 r3 00 g3 00 b3
+ "movq %%mm0, %%mm4\n\t" // 00 a0 00 r0 00 g0 00 b0
+ "movq %%mm2, %%mm6\n\t" // 00 a2 00 r2 00 g2 00 b2
+ "punpcklwd %%mm1, %%mm0\n\t" // 00 g1 00 g0 00 b1 00 b0
+ "punpcklwd %%mm3, %%mm2\n\t" // 00 g3 00 g2 00 b3 00 b2
+ "movq %%mm0, %%mm5\n\t" // 00 g1 00 g0 00 b1 00 b0
+ "punpckldq %%mm2, %%mm0\n\t" // 00 b3 00 b2 00 b1 00 b0
+ "punpckhdq %%mm2, %%mm5\n\t" // 00 g3 00 g2 00 g1 00 g0
+ "punpckhwd %%mm1, %%mm4\n\t" // 00 a1 00 a0 00 r1 00 r0
+ "punpckhwd %%mm3, %%mm6\n\t" // 00 a3 00 a2 00 r3 00 r2
+ "movq %%mm4, %%mm3\n\t" // 00 a1 00 a0 00 r1 00 r0
+ "punpckldq %%mm6, %%mm4\n\t" // 00 r3 00 r2 00 r1 00 r0
+ "punpckhdq %%mm6, %%mm3\n\t" // 00 a3 00 a2 00 a1 00 a0
+ /* mm0 = b, mm5 = g, mm4 = r, mm3 = a */
+ "movq %%mm0, %%mm1\n\t" // save b
+ "psllw $3, %%mm0\n\t"
+ "pmulhw (%2), %%mm0\n\t"
+ "movq %%mm4, %%mm2\n\t" // save r
+ "psllw $3, %%mm5\n\t"
+ "pmulhw 8(%2), %%mm5\n\t"
+ "psllw $3, %%mm4\n\t"
+ "pmulhw 16(%2), %%mm4\n\t"
+ "paddw %%mm5, %%mm0\n\t"
+ "paddw %%mm4, %%mm0\n\t" // ey
+ "psubw %%mm0, %%mm1\n\t" // b - ey
+ "psllw $3, %%mm1\n\t"
+ "pmulhw 24(%2), %%mm1\n\t" // 00 u3 00 u2 00 u1 00 u0
+ "psubw %%mm0, %%mm2\n\t" // r - ey
+ "psllw $3, %%mm2\n\t"
+ "pmulhw 32(%2), %%mm2\n\t" // 00 v3 00 v2 00 v1 00 v0
+ "paddw %3, %%mm1\n\t" // Cb + 128
+ "packuswb %%mm1, %%mm1\n\t" // u3 u2 u1 u0 u3 u2 u1 u0
+ "psllw $3, %%mm0\n\t"
+ "pmulhw 40(%2), %%mm0\n\t" // 00 y3 00 y2 00 y1 00 y0
+ "paddw %3, %%mm2\n\t" // Cr + 128
+ "packuswb %%mm2, %%mm2\n\t" // v3 v2 v1 v0 v3 v2 v1 v0
+ "paddw %4, %%mm0\n\t" // Y + 16
+ "packuswb %%mm0, %%mm0\n\t" // y3 y2 y1 y0 y3 y2 y1 y0
+ "punpcklbw %%mm7, %%mm2\n\t" // 00 v3 00 v2 00 v1 00 v0
+ "punpcklbw %%mm7, %%mm1\n\t" // 00 u3 00 y2 00 u1 00 u0
+ "punpcklbw %%mm7, %%mm0\n\t" // 00 y3 00 y2 00 y1 00 y0
+ /* mm1 = u, mm2 = v, mm0 = y, mm3 = a */
+ "movq %%mm2, %%mm4\n\t" // 00 v3 00 v2 00 v1 00 v0
+ "movq %%mm1, %%mm5\n\t" // 00 u3 00 y2 00 u1 00 u0
+ "punpcklwd %%mm3, %%mm2\n\t" // 00 a1 00 v1 00 a0 00 v0
+ "punpcklwd %%mm0, %%mm1\n\t" // 00 y1 00 u1 00 y0 00 u0
+ "punpckhwd %%mm3, %%mm4\n\t" // 00 a3 00 v3 00 a2 00 v2
+ "punpckhwd %%mm0, %%mm5\n\t" // 00 y3 00 u3 00 y2 00 u2
+ "movq %%mm1, %%mm3\n\t" // 00 y1 00 u1 00 y0 00 u0
+ "movq %%mm5, %%mm6\n\t" // 00 y3 00 u3 00 y2 00 u2
+ "punpcklwd %%mm2, %%mm1\n\t" // 00 a0 00 y0 00 v0 00 u0
+ "punpcklwd %%mm4, %%mm5\n\t" // 00 a2 00 y2 00 v2 00 u2
+ "punpckhwd %%mm2, %%mm3\n\t" // 00 a1 00 y1 00 v1 00 u1
+ "punpckhwd %%mm4, %%mm6\n\t" // 00 a3 00 y3 00 v3 00 u3
+ "movq %%mm1, (%0)\n\t"
+ "movq %%mm3, 8(%0)\n\t"
+ "movq %%mm5,16(%0)\n\t"
+ "movq %%mm6,24(%0)\n\t"
+ "add $32, %0\n\t"
+ "decl %1\n\t"
+ "jnz 1b\n\t"
+ "emms\n\t"
+ "2:"
+ : "=&D" (D)
+ : "c" (gfxs->length), "r" (mul), "m" (*add0), "m" (*add1), "0" (D)
+ : "memory" );
+
+ while (w) {
+ if (!(D->RGB.a & 0xF000))
+ RGB_TO_YCBCR( D->RGB.r, D->RGB.g, D->RGB.b,
+ D->YUV.y, D->YUV.u, D->YUV.v );
+
+ D++;
+ w--;
+ }
+}
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_hvx_16.h b/Source/DirectFB/src/gfx/generic/stretch_hvx_16.h
new file mode 100755
index 0000000..01cf41f
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_hvx_16.h
@@ -0,0 +1,469 @@
+#ifndef SOURCE_LOOKUP
+#define SOURCE_LOOKUP(x) (x)
+#define SOURCE_LOOKUP_AUTO
+#endif
+
+#ifndef SOURCE_TYPE
+#define SOURCE_TYPE u16
+#define SOURCE_TYPE_AUTO
+#endif
+
+
+#define SHIFT_L5 SHIFT_R5
+#define SHIFT_L6 SHIFT_R6
+#define SHIFT_L10 (16-SHIFT_L6)
+
+#define X_003F (X_07E0>>SHIFT_R5)
+
+#define X_003E07C0 (X_F81F<<SHIFT_L6)
+#define X_0001F800 (X_07E0<<SHIFT_L6)
+
+#define X_07E0F81F ((X_07E0<<16) | X_F81F)
+#define X_F81F07E0 ((X_F81F<<16) | X_07E0)
+
+#define X_F81FF81F ((X_F81F<<16) | X_F81F)
+#define X_07E007E0 ((X_07E0<<16) | X_07E0)
+
+#define X_07C0F83F (X_F81F07E0>>SHIFT_R5)
+
+#if 0
+#define HVX_DEBUG(x...) direct_log_printf( NULL, x )
+#else
+#define HVX_DEBUG(x...) do {} while (0)
+#endif
+
+/* stretch_hvx_up/down_16_KPI */( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y, r = 0;
+ long head = ((((ulong) dst) & 2) >> 1) ^ (ctx->clip.x1 & 1);
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long tail = (cw - head) & 1;
+ long w2 = (cw - head) / 2;
+ long hfraq = ((long)(width - MINUS_1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - MINUS_1) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = POINT_0 + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = LINE_0 + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+ u32 dt;
+ u16 l_, h_;
+#endif
+
+ u32 _lbT[w2+8];
+ u32 _lbB[w2+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((ulong)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((ulong)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = POINT_TO_RATIO( point, hfraq );
+
+ point += hfraq;
+ }
+
+ HVX_DEBUG(" %s %dx%d -> %dx%d (0x%lx, 0x%lx) prot %lx, key %lx\n",
+ __FUNCTION__, width, height, dst_width, dst_height, hfraq, vfraq, ctx->protect, ctx->key );
+
+ dst += ctx->clip.x1 * 2 + ctx->clip.y1 * dpitch;
+
+ dst32 = dst;
+
+ if (head) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = dst;
+
+ point = point0;
+
+ for (y=0; y<ch; y++) {
+ long X = LINE_TO_RATIO( line, vfraq );
+
+ const SOURCE_TYPE *srcT = src + spitch * LINE_T( line, vfraq );
+ const SOURCE_TYPE *srcB = src + spitch * LINE_B( line, vfraq );
+
+ /*
+ * Horizontal interpolation
+ */
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("h,%ld %lu (%lu/%lu) 0x%x 0x%x\n", y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ dpT = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800)) >> SHIFT_R6;
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800)) >> SHIFT_R6;
+
+ /*
+ * Vertical interpolation
+ */
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+ l_ = ((((((dpB & X_F81F) - (dpT & X_F81F))*X) >> SHIFT_R5) + (dpT & X_F81F)) & X_F81F) +
+ ((((((dpB>>SHIFT_R5) & X_003F) - ((dpT>>SHIFT_R5) & X_003F))*X) + (dpT & X_07E0)) & X_07E0);
+#ifdef COLOR_KEY
+ if ((l_ & MASK_RGB) != (COLOR_KEY))
+#endif
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ dst16[0] = ((l_ & MASK_RGB) == KEY_PROTECT) ? l_^1 : l_;
+#else
+ /* Write to destination without color key protection */
+ dst16[0] = l_;
+#endif
+#else
+ /* Write to destination without color key protection */
+ dst16[0] = ((((((dpB & X_F81F) - (dpT & X_F81F))*X) >> SHIFT_R5) + (dpT & X_F81F)) & X_F81F) +
+ ((((((dpB>>SHIFT_R5) & X_003F) - ((dpT>>SHIFT_R5) & X_003F))*X) + (dpT & X_07E0)) & X_07E0);
+#endif
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+
+ /* Adjust */
+ point0 += hfraq;
+ dst32 = dst + 2;
+
+ /* Reset */
+ line = LINE_0 + ctx->clip.y1 * vfraq;
+ }
+
+ /*
+ * Scale line by line.
+ */
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = LINE_T( line, vfraq );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+ /*
+ * Fill line buffer(s) ?
+ */
+ if (nlT != lineT) {
+ u32 L, R, dpT, dpB;
+ const SOURCE_TYPE *srcT = src + spitch * nlT;
+ const SOURCE_TYPE *srcB = src + spitch * (nlT + 1);
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+ /*
+ * Two output pixels per step.
+ */
+ for (x=0, r=head, point=point0; x<w2; x++) {
+ /*
+ * Horizontal interpolation
+ */
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ dpT = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ << SHIFT_L10;
+#else
+ >> SHIFT_R6;
+#endif
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ << SHIFT_L10;
+#else
+ >> SHIFT_R6;
+#endif
+
+ point += hfraq;
+ r++;
+
+
+ pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ dpT |= (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ >> SHIFT_R6;
+#else
+ << SHIFT_L10;
+#endif
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB |= (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ >> SHIFT_R6;
+#else
+ << SHIFT_L10;
+#endif
+
+ point += hfraq;
+ r++;
+
+ /* Store */
+ lbT[x] = dpT;
+ lbB[x] = dpB;
+ }
+ }
+ else {
+ /* Swap */
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+ /*
+ * Two output pixels per step.
+ */
+ for (x=0, r=head, point=point0; x<w2; x++) {
+ /*
+ * Horizontal interpolation
+ */
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ << SHIFT_L10;
+#else
+ >> SHIFT_R6;
+#endif
+
+ point += hfraq;
+ r++;
+
+
+ pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB |= (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800))
+#ifdef WORDS_BIGENDIAN
+ >> SHIFT_R6;
+#else
+ << SHIFT_L10;
+#endif
+
+ point += hfraq;
+ r++;
+
+ /* Store */
+ lbB[x] = dpB;
+ }
+ }
+
+ lineT = nlT;
+ }
+
+ /*
+ * Vertical interpolation
+ */
+ X = LINE_TO_RATIO( line, vfraq );
+
+ for (x=0; x<w2; x++) {
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+#ifdef HAS_ALPHA
+ dt = ((((((lbB[x] & X_F81FF81F) - (lbT[x] & X_F81FF81F))*X) >> SHIFT_R5) + (lbT[x] & X_F81FF81F)) & X_F81FF81F) +
+ ((((((lbB[x]>>SHIFT_R5) & X_F81FF81F) - ((lbT[x]>>SHIFT_R5) & X_F81FF81F))*X) + (lbT[x] & X_07E007E0)) & X_07E007E0);
+#else
+ dt = ((((((lbB[x] & X_07E0F81F) - (lbT[x] & X_07E0F81F))*X) >> SHIFT_R5) + (lbT[x] & X_07E0F81F)) & X_07E0F81F) +
+ ((((((lbB[x]>>SHIFT_R5) & X_07C0F83F) - ((lbT[x]>>SHIFT_R5) & X_07C0F83F))*X) + (lbT[x] & X_F81F07E0)) & X_F81F07E0);
+#endif
+
+ /* Get two new pixels. */
+ l_ = dt;
+ h_ = dt >> 16;
+
+#ifdef COLOR_KEY
+ if ((l_ & MASK_RGB) != (COLOR_KEY)) {
+ if ((h_ & MASK_RGB) != (COLOR_KEY)) {
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ dst32[x] = ((((h_ & MASK_RGB) == KEY_PROTECT) ? h_^1 : h_) << 16) | (((l_ & MASK_RGB) == KEY_PROTECT) ? l_^1 : l_);
+#else
+ /* Write to destination without color key protection */
+ dst32[x] = dt;
+#endif
+ }
+ else {
+ u16 *_dst16 = (u16*) &dst32[x];
+
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ *_dst16 = (((l_ & MASK_RGB) == KEY_PROTECT) ? l_^1 : l_);
+#else
+ /* Write to destination without color key protection */
+ *_dst16 = l_;
+#endif
+ }
+ }
+ else if ((h_ & MASK_RGB) != (COLOR_KEY)) {
+ u16 *_dst16 = ((u16*) &dst32[x]) + 1;
+
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ *_dst16 = (((h_ & MASK_RGB) == KEY_PROTECT) ? h_^1 : h_);
+#else
+ /* Write to destination without color key protection */
+ *_dst16 = h_;
+#endif
+ }
+#else
+ /* Write to destination with color key protection */
+ dst32[x] = ((((h_ & MASK_RGB) == KEY_PROTECT) ? h_^1 : h_) << 16) | (((l_ & MASK_RGB) == KEY_PROTECT) ? l_^1 : l_);
+#endif
+#else
+#ifdef HAS_ALPHA
+ dst32[x] = ((((((lbB[x] & X_F81FF81F) - (lbT[x] & X_F81FF81F))*X) >> SHIFT_R5) + (lbT[x] & X_F81FF81F)) & X_F81FF81F) +
+ ((((((lbB[x]>>SHIFT_R5) & X_F81FF81F) - ((lbT[x]>>SHIFT_R5) & X_F81FF81F))*X) + (lbT[x] & X_07E007E0)) & X_07E007E0);
+#else
+ dst32[x] = ((((((lbB[x] & X_07E0F81F) - (lbT[x] & X_07E0F81F))*X) >> SHIFT_R5) + (lbT[x] & X_07E0F81F)) & X_07E0F81F) +
+ ((((((lbB[x]>>SHIFT_R5) & X_07C0F83F) - ((lbT[x]>>SHIFT_R5) & X_07C0F83F))*X) + (lbT[x] & X_F81F07E0)) & X_F81F07E0);
+#endif
+#endif
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+
+ if (tail) {
+ u32 dpT, dpB, L, R;
+
+ u16 *dst16 = dst + cw * 2 - 2;
+
+ /* Reset */
+ line = LINE_0 + ctx->clip.y1 * vfraq;
+
+ for (y=0; y<ch; y++) {
+ long X = LINE_TO_RATIO( line, vfraq );
+
+ const SOURCE_TYPE *srcT = src + spitch * LINE_T( line, vfraq );
+ const SOURCE_TYPE *srcB = src + spitch * LINE_B( line, vfraq );
+
+ /*
+ * Horizontal interpolation
+ */
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("t,%ld %lu (%lu/%lu) 0x%x 0x%x\n", y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ dpT = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800)) >> SHIFT_R6;
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ dpB = (((((R & X_F81F)-(L & X_F81F))*ratios[r] + ((L & X_F81F)<<SHIFT_L6)) & X_003E07C0) +
+ ((((R & X_07E0)-(L & X_07E0))*ratios[r] + ((L & X_07E0)<<SHIFT_L6)) & X_0001F800)) >> SHIFT_R6;
+
+ /*
+ * Vertical interpolation
+ */
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+ l_ = ((((((dpB & X_F81F) - (dpT & X_F81F))*X) >> SHIFT_R5) + (dpT & X_F81F)) & X_F81F) +
+ ((((((dpB>>SHIFT_R5) & X_003F) - ((dpT>>SHIFT_R5) & X_003F))*X) + (dpT & X_07E0)) & X_07E0);
+
+#ifdef COLOR_KEY
+ if ((l_ & MASK_RGB) != (COLOR_KEY))
+#endif
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ dst16[0] = ((l_ & MASK_RGB) == KEY_PROTECT) ? l_^1 : l_;
+#else
+ /* Write to destination without color key protection */
+ dst16[0] = l_;
+#endif
+#else
+ /* Write to destination without color key protection */
+ dst16[0] = ((((((dpB & X_F81F) - (dpT & X_F81F))*X) >> SHIFT_R5) + (dpT & X_F81F)) & X_F81F) +
+ ((((((dpB>>SHIFT_R5) & X_003F) - ((dpT>>SHIFT_R5) & X_003F))*X) + (dpT & X_07E0)) & X_07E0);
+#endif
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+ }
+}
+
+
+#undef SHIFT_L6
+#undef SHIFT_L10
+
+#undef X_003F
+
+#undef X_003E07C0
+#undef X_0001F800
+
+#undef X_07E0F81F
+#undef X_F81F07E0
+
+#undef X_07C0F83F
+
+
+
+#ifdef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP
+#endif
+
+#ifdef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE
+#endif
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_hvx_32.h b/Source/DirectFB/src/gfx/generic/stretch_hvx_32.h
new file mode 100755
index 0000000..289ff2c
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_hvx_32.h
@@ -0,0 +1,174 @@
+#ifndef SOURCE_LOOKUP
+#define SOURCE_LOOKUP(x) (x)
+#define SOURCE_LOOKUP_AUTO
+#endif
+
+#ifndef SOURCE_TYPE
+#define SOURCE_TYPE u32
+#define SOURCE_TYPE_AUTO
+#endif
+
+#if 0
+#define HVX_DEBUG(x...) direct_log_printf( NULL, x )
+#else
+#define HVX_DEBUG(x...) do {} while (0)
+#endif
+
+/* stretch_hvx_up/down_32_KPI */( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ const StretchCtx *ctx )
+{
+ long x, y = 0;
+ long cw = ctx->clip.x2 - ctx->clip.x1 + 1;
+ long ch = ctx->clip.y2 - ctx->clip.y1 + 1;
+ long hfraq = ((long)(width - MINUS_1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - MINUS_1) << 18) / (long)(dst_height);
+ long dp4 = dpitch / 4;
+ long point0 = POINT_0 + ctx->clip.x1 * hfraq;
+ long point = point0;
+ long line = LINE_0 + ctx->clip.y1 * vfraq;
+ long ratios[cw];
+ u32 *dst32;
+
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+ u32 dt;
+#endif
+
+ u32 _lbT[cw+8];
+ u32 _lbB[cw+8];
+
+ u32 *lbX;
+ u32 *lbT = (u32*)((((ulong)(&_lbT[0])) + 31) & ~31);
+ u32 *lbB = (u32*)((((ulong)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = POINT_TO_RATIO( point, hfraq );
+
+ point += hfraq;
+ }
+
+ HVX_DEBUG("%dx%d -> %dx%d (0x%x, 0x%x)\n", width, height, dst_width, dst_height, hfraq, vfraq );
+
+ dst += ctx->clip.x1 * 4 + ctx->clip.y1 * dpitch;
+
+ dst32 = dst;
+
+ /*
+ * Scale line by line.
+ */
+ for (y=0; y<ch; y++) {
+ long X;
+ long nlT = LINE_T( line, vfraq );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+ /*
+ * Fill line buffer(s) ?
+ */
+ if (nlT != lineT) {
+ u32 L, R;
+ const SOURCE_TYPE *srcT = src + spitch * nlT;
+ const SOURCE_TYPE *srcB = src + spitch * (nlT + 1);
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+ /*
+ * Horizontal interpolation
+ */
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ lbT[x]= ((((((R & X_00FF00FF) - (L & X_00FF00FF))*ratios[x]) >> SHIFT_R8) + (L & X_00FF00FF)) & X_00FF00FF) +
+ ((((((R>>SHIFT_R8) & X_00FF00FF) - ((L>>SHIFT_R8) & X_00FF00FF))*ratios[x]) + (L & X_FF00FF00)) & X_FF00FF00);
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ lbB[x] = ((((((R & X_00FF00FF) - (L & X_00FF00FF))*ratios[x]) >> SHIFT_R8) + (L & X_00FF00FF)) & X_00FF00FF) +
+ ((((((R>>SHIFT_R8) & X_00FF00FF) - ((L>>SHIFT_R8) & X_00FF00FF))*ratios[x]) + (L & X_FF00FF00)) & X_FF00FF00);
+ }
+ }
+ else {
+ /* Swap */
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+ /*
+ * Horizontal interpolation
+ */
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ lbB[x] = ((((((R & X_00FF00FF) - (L & X_00FF00FF))*ratios[x]) >> SHIFT_R8) + (L & X_00FF00FF)) & X_00FF00FF) +
+ ((((((R>>SHIFT_R8) & X_00FF00FF) - ((L>>SHIFT_R8) & X_00FF00FF))*ratios[x]) + (L & X_FF00FF00)) & X_FF00FF00);
+ }
+ }
+
+ lineT = nlT;
+ }
+
+ /*
+ * Vertical interpolation
+ */
+ X = LINE_TO_RATIO( line, vfraq );
+
+ for (x=0; x<cw; x++) {
+#if defined (COLOR_KEY) || defined (KEY_PROTECT)
+ dt = ((((((lbB[x] & X_00FF00FF) - (lbT[x] & X_00FF00FF))*X) >> SHIFT_R8) + (lbT[x] & X_00FF00FF)) & X_00FF00FF) +
+ ((((((lbB[x]>>SHIFT_R8) & X_00FF00FF) - ((lbT[x]>>SHIFT_R8) & X_00FF00FF))*X) + (lbT[x] & X_FF00FF00)) & X_FF00FF00);
+#ifdef COLOR_KEY
+ if (dt != (COLOR_KEY))
+#endif
+#ifdef KEY_PROTECT
+ /* Write to destination with color key protection */
+ dst32[x] = ((dt & MASK_RGB) == KEY_PROTECT) ? dt^1 : dt;
+#else
+ /* Write to destination without color key protection */
+ dst32[x] = dt;
+#endif
+#else
+ /* Write to destination without color key protection */
+ dst32[x] = ((((((lbB[x] & X_00FF00FF) - (lbT[x] & X_00FF00FF))*X) >> SHIFT_R8) + (lbT[x] & X_00FF00FF)) & X_00FF00FF) +
+ ((((((lbB[x]>>SHIFT_R8) & X_00FF00FF) - ((lbT[x]>>SHIFT_R8) & X_00FF00FF))*X) + (lbT[x] & X_FF00FF00)) & X_FF00FF00);
+#endif
+ }
+
+ dst32 += dp4;
+ line += vfraq;
+ }
+}
+
+#ifdef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP
+#endif
+
+#ifdef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE
+#endif
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_hvx_8.h b/Source/DirectFB/src/gfx/generic/stretch_hvx_8.h
new file mode 100755
index 0000000..e809304
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_hvx_8.h
@@ -0,0 +1,149 @@
+#ifndef SOURCE_LOOKUP
+#define SOURCE_LOOKUP(x) (x)
+#define SOURCE_LOOKUP_AUTO
+#endif
+
+#ifndef SOURCE_TYPE
+#define SOURCE_TYPE u8
+#define SOURCE_TYPE_AUTO
+#endif
+
+#if 0
+#define HVX_DEBUG(x...) direct_log_printf( NULL, x )
+#else
+#define HVX_DEBUG(x...) do {} while (0)
+#endif
+
+/*** OPTIMIZE by doing four pixels at once (vertically) with a 32 bit line buffer ***/
+
+/*static void STRETCH_HVX_YV12( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ DFBRegion *clip )*/
+{
+ long x, y = 0;
+ long cw = clip->x2 - clip->x1 + 1;
+ long ch = clip->y2 - clip->y1 + 1;
+ long hfraq = ((long)(width - MINUS_1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - MINUS_1) << 18) / (long)(dst_height);
+ long point0 = POINT_0 + clip->x1 * hfraq;
+ long point = point0;
+ long line = LINE_0 + clip->y1 * vfraq;
+ long ratios[cw];
+ u8 *dst8;
+
+ u8 _lbT[cw+32];
+ u8 _lbB[cw+32];
+
+ u8 *lbX;
+ u8 *lbT = (u8*)((((ulong)(&_lbT[0])) + 31) & ~31);
+ u8 *lbB = (u8*)((((ulong)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = POINT_TO_RATIO( point, hfraq );
+
+ point += hfraq;
+ }
+
+ HVX_DEBUG("%dx%d -> %dx%d (0x%x, 0x%x)\n", width, height, dst_width, dst_height, hfraq, vfraq );
+
+ dst += clip->x1 + clip->y1 * dpitch;
+
+ dst8 = dst;
+
+ /*
+ * Scale line by line.
+ */
+ for (y=0; y<ch; y++) {
+ long nlT = LINE_T( line, vfraq );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+ /*
+ * Fill line buffer(s) ?
+ */
+ if (nlT != lineT) {
+ u8 L, R;
+ const SOURCE_TYPE *srcT = src + spitch * nlT;
+ const SOURCE_TYPE *srcB = src + spitch * (nlT + 1);
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+ /*
+ * Horizontal interpolation
+ */
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ lbT[x] = (((R - L) * ratios[x]) >> 8) + L;
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ lbB[x] = (((R - L) * ratios[x]) >> 8) + L;
+ }
+ }
+ else {
+ /* Swap */
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+ /*
+ * Horizontal interpolation
+ */
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ lbB[x] = (((R - L) * ratios[x]) >> 8) + L;
+ }
+ }
+
+ lineT = nlT;
+ }
+
+ /*
+ * Vertical interpolation
+ */
+ long X = LINE_TO_RATIO( line, vfraq );
+
+ for (x=0; x<cw; x++)
+ dst8[x] = (((lbB[x] - lbT[x]) * X) >> 8) + lbT[x];
+
+ dst8 += dpitch;
+ line += vfraq;
+ }
+}
+
+#ifdef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP
+#endif
+
+#ifdef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE
+#endif
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_hvx_88.h b/Source/DirectFB/src/gfx/generic/stretch_hvx_88.h
new file mode 100755
index 0000000..6394b5b
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_hvx_88.h
@@ -0,0 +1,152 @@
+#ifndef SOURCE_LOOKUP
+#define SOURCE_LOOKUP(x) (x)
+#define SOURCE_LOOKUP_AUTO
+#endif
+
+#ifndef SOURCE_TYPE
+#define SOURCE_TYPE u16
+#define SOURCE_TYPE_AUTO
+#endif
+
+#if 0
+#define HVX_DEBUG(x...) direct_log_printf( NULL, x )
+#else
+#define HVX_DEBUG(x...) do {} while (0)
+#endif
+
+
+/*** OPTIMIZE by doing two pixels at once (vertically) with a 32 bit line buffer ***/
+
+/*static void STRETCH_HVX_NV16( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ DFBRegion *clip )*/
+{
+ long x, y = 0;
+ long cw = clip->x2 - clip->x1 + 1;
+ long ch = clip->y2 - clip->y1 + 1;
+ long hfraq = ((long)(width - MINUS_1) << 18) / (long)(dst_width);
+ long vfraq = ((long)(height - MINUS_1) << 18) / (long)(dst_height);
+ long point0 = POINT_0 + clip->x1 * hfraq;
+ long point = point0;
+ long line = LINE_0 + clip->y1 * vfraq;
+ long ratios[cw];
+ u16 *dst16;
+
+ u16 _lbT[cw+16];
+ u16 _lbB[cw+16];
+
+ u16 *lbX;
+ u16 *lbT = (u16*)((((ulong)(&_lbT[0])) + 31) & ~31);
+ u16 *lbB = (u16*)((((ulong)(&_lbB[0])) + 31) & ~31);
+
+ long lineT = -2000;
+
+ for (x=0; x<cw; x++) {
+ ratios[x] = POINT_TO_RATIO( point, hfraq );
+
+ point += hfraq;
+ }
+
+ dst += clip->x1 * 2 + clip->y1 * dpitch;
+
+ dst16 = dst;
+
+ /*
+ * Scale line by line.
+ */
+ for (y=0; y<ch; y++) {
+ long nlT = LINE_T( line, vfraq );
+
+ D_ASSERT( nlT >= 0 );
+ D_ASSERT( nlT < height-1 );
+
+ /*
+ * Fill line buffer(s) ?
+ */
+ if (nlT != lineT) {
+ u16 L, R;
+ const SOURCE_TYPE *srcT = src + spitch * nlT;
+ const SOURCE_TYPE *srcB = src + spitch * (nlT + 1);
+ long diff = nlT - lineT;
+
+ if (diff > 1) {
+ /*
+ * Horizontal interpolation
+ */
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcT[pl]);
+ R = SOURCE_LOOKUP(srcT[pl+1]);
+
+ lbT[x] = (((((R & 0x00ff)-(L & 0x00ff))*ratios[x] + ((L & 0x00ff)<<8)) & 0x00ff00) +
+ ((((R & 0xff00)-(L & 0xff00))*ratios[x] + ((L & 0xff00)<<8)) & 0xff0000)) >> 8;
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ lbB[x] = (((((R & 0x00ff)-(L & 0x00ff))*ratios[x] + ((L & 0x00ff)<<8)) & 0x00ff00) +
+ ((((R & 0xff00)-(L & 0xff00))*ratios[x] + ((L & 0xff00)<<8)) & 0xff0000)) >> 8;
+ }
+ }
+ else {
+ /* Swap */
+ lbX = lbT;
+ lbT = lbB;
+ lbB = lbX;
+
+ /*
+ * Horizontal interpolation
+ */
+ for (x=0, point=point0; x<cw; x++, point += hfraq) {
+ long pl = POINT_L( point, hfraq );
+ HVX_DEBUG("%ld,%ld %lu (%lu/%lu) 0x%x 0x%x\n", x, y, pl,
+ POINT_L( point, hfraq ), POINT_R( point, hfraq ), point, ratios[r] );
+ D_ASSERT( pl >= 0 );
+ D_ASSERT( pl < width-1 );
+
+ L = SOURCE_LOOKUP(srcB[pl]);
+ R = SOURCE_LOOKUP(srcB[pl+1]);
+
+ lbB[x] = (((((R & 0x00ff)-(L & 0x00ff))*ratios[x] + ((L & 0x00ff)<<8)) & 0x00ff00) +
+ ((((R & 0xff00)-(L & 0xff00))*ratios[x] + ((L & 0xff00)<<8)) & 0xff0000)) >> 8;
+ }
+ }
+
+ lineT = nlT;
+ }
+
+ /*
+ * Vertical interpolation
+ */
+ long X = LINE_TO_RATIO( line, vfraq );
+
+ for (x=0; x<cw; x++)
+ dst16[x] = (((((lbB[x] & 0x00ff)-(lbT[x] & 0x00ff))*X + ((lbT[x] & 0x00ff)<<8)) & 0x00ff00) +
+ ((((lbB[x] & 0xff00)-(lbT[x] & 0xff00))*X + ((lbT[x] & 0xff00)<<8)) & 0xff0000)) >> 8;
+
+ dst16 += dpitch / 2;
+ line += vfraq;
+ }
+}
+
+#ifdef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP_AUTO
+#undef SOURCE_LOOKUP
+#endif
+
+#ifdef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE_AUTO
+#undef SOURCE_TYPE
+#endif
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_hvx_N.h b/Source/DirectFB/src/gfx/generic/stretch_hvx_N.h
new file mode 100755
index 0000000..c4922e1
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_hvx_N.h
@@ -0,0 +1,121 @@
+#if UPDOWN == 1
+#define FUNC_NAME_(K,P,F) FUNC_NAME(up,K,P,F)
+#else
+#define FUNC_NAME_(K,P,F) FUNC_NAME(down,K,P,F)
+#endif
+
+
+/* NONE */
+static void FUNC_NAME_(_,_,DST_FORMAT)
+#include STRETCH_HVX_N_H
+
+/* SRCKEY */
+#define COLOR_KEY ctx->key
+static void FUNC_NAME_(K,_,DST_FORMAT)
+#include STRETCH_HVX_N_H
+#undef COLOR_KEY
+
+/* PROTECT */
+#define KEY_PROTECT ctx->protect
+static void FUNC_NAME_(_,P,DST_FORMAT)
+#include STRETCH_HVX_N_H
+
+/* PROTECT SRCKEY */
+#define COLOR_KEY ctx->key
+static void FUNC_NAME_(K,P,DST_FORMAT)
+#include STRETCH_HVX_N_H
+#undef COLOR_KEY
+#undef KEY_PROTECT
+
+
+/* INDEXED */
+#define SOURCE_LOOKUP(x) ((const uN*)ctx->colors)[x]
+#define SOURCE_TYPE u8
+static void FUNC_NAME_(_,_,DSPF_LUT8)
+#include STRETCH_HVX_N_H
+
+/* INDEXED SRCKEY */
+#define COLOR_KEY ctx->key
+static void FUNC_NAME_(K,_,DSPF_LUT8)
+#include STRETCH_HVX_N_H
+#undef COLOR_KEY
+
+/* INDEXED PROTECT */
+#define KEY_PROTECT ctx->protect
+static void FUNC_NAME_(_,P,DSPF_LUT8)
+#include STRETCH_HVX_N_H
+
+/* INDEXED PROTECT SRCKEY */
+#define COLOR_KEY ctx->key
+static void FUNC_NAME_(K,P,DSPF_LUT8)
+#include STRETCH_HVX_N_H
+#undef COLOR_KEY
+#undef KEY_PROTECT
+#undef SOURCE_LOOKUP
+#undef SOURCE_TYPE
+
+
+/* FIXME: DST_FORMAT == DSPF_RGB16 doesn't work */
+#ifdef FORMAT_RGB16
+/* ARGB4444 */
+#define SOURCE_LOOKUP(x) PIXEL_RGB16( (((x) & 0x0f00) >> 4) | (((x) & 0x0f00) >> 8), \
+ (((x) & 0x00f0) ) | (((x) & 0x00f0) >> 4), \
+ (((x) & 0x000f) << 4) | (((x) & 0x000f) ) )
+static void FUNC_NAME_(_,_,DSPF_ARGB4444)
+#include STRETCH_HVX_N_H
+
+/* ARGB4444 SRCKEY */
+#define COLOR_KEY ctx->key
+static void FUNC_NAME_(K,_,DSPF_ARGB4444)
+#include STRETCH_HVX_N_H
+#undef COLOR_KEY
+
+/* ARGB4444 PROTECT */
+#define KEY_PROTECT ctx->protect
+static void FUNC_NAME_(_,P,DSPF_ARGB4444)
+#include STRETCH_HVX_N_H
+
+/* ARGB4444 PROTECT SRCKEY */
+#define COLOR_KEY ctx->key
+static void FUNC_NAME_(K,P,DSPF_ARGB4444)
+#include STRETCH_HVX_N_H
+#undef COLOR_KEY
+#undef KEY_PROTECT
+#undef SOURCE_LOOKUP
+#undef SOURCE_TYPE
+#endif
+
+
+/* FIXME: DST_FORMAT == DSPF_ARGB4444 doesn't work */
+#ifdef FORMAT_ARGB4444
+/* RGB16 */
+#define SOURCE_LOOKUP(x) PIXEL_ARGB4444( 0xff, \
+ (((x) & 0xf800) >> 8), \
+ (((x) & 0x07e0) >> 3), \
+ (((x) & 0x001f) << 3) )
+static void FUNC_NAME_(_,_,DSPF_RGB16)
+#include STRETCH_HVX_N_H
+
+/* RGB16 SRCKEY */
+#define COLOR_KEY ctx->key
+static void FUNC_NAME_(K,_,DSPF_RGB16)
+#include STRETCH_HVX_N_H
+#undef COLOR_KEY
+
+/* RGB16 PROTECT */
+#define KEY_PROTECT ctx->protect
+static void FUNC_NAME_(_,P,DSPF_RGB16)
+#include STRETCH_HVX_N_H
+
+/* RGB16 PROTECT SRCKEY */
+#define COLOR_KEY ctx->key
+static void FUNC_NAME_(K,P,DSPF_RGB16)
+#include STRETCH_HVX_N_H
+#undef COLOR_KEY
+#undef KEY_PROTECT
+#undef SOURCE_LOOKUP
+#undef SOURCE_TYPE
+#endif
+
+#undef FUNC_NAME_
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_up_down_16.h b/Source/DirectFB/src/gfx/generic/stretch_up_down_16.h
new file mode 100755
index 0000000..c6e4391
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_up_down_16.h
@@ -0,0 +1,68 @@
+#define STRETCH_HVX_N_H "stretch_hvx_16.h"
+#define uN u16
+
+/**********************************************************************************************************************/
+/* Upscaling */
+
+#define POINT_0 0
+#define LINE_0 0
+#define MINUS_1 1
+#define POINT_TO_RATIO(p,ps) ( ((p) & 0x3ffff) >> (18-SHIFT_L6) )
+#define LINE_TO_RATIO(l,ls) ( ((l) & 0x3ffff) >> (18-SHIFT_L5) )
+
+#define POINT_L(p,ps) ( (((p)) >> 18) )
+#define POINT_R(p,ps) ( (((p)) >> 18) + 1 )
+
+#define LINE_T(l,ls) ( (((l)) >> 18) )
+#define LINE_B(l,ls) ( (((l)) >> 18) + 1 )
+
+#define UPDOWN 1
+#include "stretch_hvx_N.h"
+#undef UPDOWN
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+/* Downscaling */
+
+#define POINT_0 hfraq
+#define LINE_0 vfraq
+#define MINUS_1 0
+#define POINT_TO_RATIO(p,ps) ( (((((p)) & 0x3ffff) ? : 0x40000) << SHIFT_L6) / (ps) )
+#define LINE_TO_RATIO(l,ls) ( (((((l)) & 0x3ffff) ? : 0x40000) << SHIFT_L5) / (ls) )
+
+#define POINT_L(p,ps) ( (((p)-1) >> 18) - 1 )
+#define POINT_R(p,ps) ( (((p)-1) >> 18) )
+
+#define LINE_T(l,ls) ( (((l)-1) >> 18) - 1 )
+#define LINE_B(l,ls) ( (((l)-1) >> 18) )
+
+#define UPDOWN 0
+#include "stretch_hvx_N.h"
+#undef UPDOWN
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+
+#undef STRETCH_HVX_N_H
+#undef uN
+
+#include "stretch_up_down_table.h"
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_up_down_32.h b/Source/DirectFB/src/gfx/generic/stretch_up_down_32.h
new file mode 100755
index 0000000..3fca697
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_up_down_32.h
@@ -0,0 +1,68 @@
+#define STRETCH_HVX_N_H "stretch_hvx_32.h"
+#define uN u32
+
+/**********************************************************************************************************************/
+/* Upscaling */
+
+#define POINT_0 0
+#define LINE_0 0
+#define MINUS_1 1
+#define POINT_TO_RATIO(p,ps) ( ((p) & 0x3ffff) >> (18-SHIFT_L8) )
+#define LINE_TO_RATIO(l,ls) ( ((l) & 0x3ffff) >> (18-SHIFT_L8) )
+
+#define POINT_L(p,ps) ( (((p)) >> 18) )
+#define POINT_R(p,ps) ( (((p)) >> 18) + 1 )
+
+#define LINE_T(l,ls) ( (((l)) >> 18) )
+#define LINE_B(l,ls) ( (((l)) >> 18) + 1 )
+
+#define UPDOWN 1
+#include "stretch_hvx_N.h"
+#undef UPDOWN
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+/* Downscaling */
+
+#define POINT_0 hfraq
+#define LINE_0 vfraq
+#define MINUS_1 0
+#define POINT_TO_RATIO(p,ps) ( (((((p)) & 0x3ffff) ? : 0x40000) << SHIFT_L8) / (ps) )
+#define LINE_TO_RATIO(l,ls) ( (((((l)) & 0x3ffff) ? : 0x40000) << SHIFT_L8) / (ls) )
+
+#define POINT_L(p,ps) ( (((p)-1) >> 18) - 1 )
+#define POINT_R(p,ps) ( (((p)-1) >> 18) )
+
+#define LINE_T(l,ls) ( (((l)-1) >> 18) - 1 )
+#define LINE_B(l,ls) ( (((l)-1) >> 18) )
+
+#define UPDOWN 0
+#include "stretch_hvx_N.h"
+#undef UPDOWN
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+
+#undef STRETCH_HVX_N_H
+#undef uN
+
+#include "stretch_up_down_table.h"
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_up_down_32_indexed.h b/Source/DirectFB/src/gfx/generic/stretch_up_down_32_indexed.h
new file mode 100755
index 0000000..655bf98
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_up_down_32_indexed.h
@@ -0,0 +1,82 @@
+#define SOURCE_LOOKUP(x) (((const u32*)colors)[x])
+#define SOURCE_TYPE u8
+
+
+#define POINT_0 hfraq
+#define LINE_0 vfraq
+#define MINUS_1 0
+#define POINT_TO_RATIO(p,ps) ( (((((p)) & 0x3ffff) ? : 0x40000) << SHIFT_L8) / (ps) )
+#define LINE_TO_RATIO(l,ls) ( (((((l)) & 0x3ffff) ? : 0x40000) << SHIFT_L8) / (ls) )
+
+#define POINT_L(p,ps) ( (((p)-1) >> 18) - 1 )
+#define POINT_R(p,ps) ( (((p)-1) >> 18) )
+
+#define LINE_T(l,ls) ( (((l)-1) >> 18) - 1 )
+#define LINE_B(l,ls) ( (((l)-1) >> 18) )
+
+static void FUNC_NAME(down)( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ DFBRegion *clip,
+ const void *colors )
+{
+#include "stretch_hvx_32.h"
+}
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+
+#define POINT_0 0
+#define LINE_0 0
+#define MINUS_1 1
+#define POINT_TO_RATIO(p,ps) ( ((p) & 0x3ffff) >> (18-SHIFT_L8) )
+#define LINE_TO_RATIO(l,ls) ( ((l) & 0x3ffff) >> (18-SHIFT_L8) )
+
+#define POINT_L(p,ps) ( (((p)) >> 18) )
+#define POINT_R(p,ps) ( (((p)) >> 18) + 1 )
+
+#define LINE_T(l,ls) ( (((l)) >> 18) )
+#define LINE_B(l,ls) ( (((l)) >> 18) + 1 )
+
+static void FUNC_NAME(up)( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ DFBRegion *clip,
+ const void *colors )
+{
+#include "stretch_hvx_32.h"
+}
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+
+#undef SOURCE_LOOKUP
+#undef SOURCE_TYPE
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_up_down_8.h b/Source/DirectFB/src/gfx/generic/stretch_up_down_8.h
new file mode 100755
index 0000000..5b43df9
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_up_down_8.h
@@ -0,0 +1,72 @@
+#define POINT_0 hfraq
+#define LINE_0 vfraq
+#define MINUS_1 0
+#define POINT_TO_RATIO(p,ps) ( (((((p)) & 0x3ffff) ? : 0x40000) << 8) / (ps) )
+#define LINE_TO_RATIO(l,ls) ( (((((l)) & 0x3ffff) ? : 0x40000) << 8) / (ls) )
+
+#define POINT_L(p,ps) ( (((p)-1) >> 18) - 1 )
+#define POINT_R(p,ps) ( (((p)-1) >> 18) )
+
+#define LINE_T(l,ls) ( (((l)-1) >> 18) - 1 )
+#define LINE_B(l,ls) ( (((l)-1) >> 18) )
+
+static void FUNC_NAME(down)( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ DFBRegion *clip )
+{
+#include "stretch_hvx_8.h"
+}
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+
+#define POINT_0 0
+#define LINE_0 0
+#define MINUS_1 1
+#define POINT_TO_RATIO(p,ps) ( ((p) & 0x3ffff) >> (18-8) )
+#define LINE_TO_RATIO(l,ls) ( ((l) & 0x3ffff) >> (18-8) )
+
+#define POINT_L(p,ps) ( (((p)) >> 18) )
+#define POINT_R(p,ps) ( (((p)) >> 18) + 1 )
+
+#define LINE_T(l,ls) ( (((l)) >> 18) )
+#define LINE_B(l,ls) ( (((l)) >> 18) + 1 )
+
+static void FUNC_NAME(up)( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ DFBRegion *clip )
+{
+#include "stretch_hvx_8.h"
+}
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_up_down_88.h b/Source/DirectFB/src/gfx/generic/stretch_up_down_88.h
new file mode 100755
index 0000000..a91b6c9
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_up_down_88.h
@@ -0,0 +1,72 @@
+#define POINT_0 hfraq
+#define LINE_0 vfraq
+#define MINUS_1 0
+#define POINT_TO_RATIO(p,ps) ( (((((p)) & 0x3ffff) ? : 0x40000) << 8) / (ps) )
+#define LINE_TO_RATIO(l,ls) ( (((((l)) & 0x3ffff) ? : 0x40000) << 8) / (ls) )
+
+#define POINT_L(p,ps) ( (((p)-1) >> 18) - 1 )
+#define POINT_R(p,ps) ( (((p)-1) >> 18) )
+
+#define LINE_T(l,ls) ( (((l)-1) >> 18) - 1 )
+#define LINE_B(l,ls) ( (((l)-1) >> 18) )
+
+static void FUNC_NAME(down)( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ DFBRegion *clip )
+{
+#include "stretch_hvx_88.h"
+}
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
+/**********************************************************************************************************************/
+
+#define POINT_0 0
+#define LINE_0 0
+#define MINUS_1 1
+#define POINT_TO_RATIO(p,ps) ( ((p) & 0x3ffff) >> (18-8) )
+#define LINE_TO_RATIO(l,ls) ( ((l) & 0x3ffff) >> (18-8) )
+
+#define POINT_L(p,ps) ( (((p)) >> 18) )
+#define POINT_R(p,ps) ( (((p)) >> 18) + 1 )
+
+#define LINE_T(l,ls) ( (((l)) >> 18) )
+#define LINE_B(l,ls) ( (((l)) >> 18) + 1 )
+
+static void FUNC_NAME(up)( void *dst,
+ int dpitch,
+ const void *src,
+ int spitch,
+ int width,
+ int height,
+ int dst_width,
+ int dst_height,
+ DFBRegion *clip )
+{
+#include "stretch_hvx_88.h"
+}
+
+#undef POINT_0
+#undef LINE_0
+#undef MINUS_1
+#undef POINT_TO_RATIO
+#undef LINE_TO_RATIO
+#undef POINT_L
+#undef POINT_R
+#undef LINE_T
+#undef LINE_B
+
diff --git a/Source/DirectFB/src/gfx/generic/stretch_up_down_table.h b/Source/DirectFB/src/gfx/generic/stretch_up_down_table.h
new file mode 100755
index 0000000..32f208b
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/stretch_up_down_table.h
@@ -0,0 +1,59 @@
+/**********************************************************************************************************************/
+/* Function table */
+
+static const StretchFunctionTable TABLE_NAME = {
+#define FUNC_NAME_(K,P,F) FUNC_NAME(up,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].up[STRETCH_NONE] = FUNC_NAME_(_,_,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].up[STRETCH_PROTECT] = FUNC_NAME_(_,P,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].up[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].up[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].up[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].up[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].up[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].up[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_LUT8),
+#undef FUNC_NAME_
+
+#define FUNC_NAME_(K,P,F) FUNC_NAME(down,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].down[STRETCH_NONE] = FUNC_NAME_(_,_,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].down[STRETCH_PROTECT] = FUNC_NAME_(_,P,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].down[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DST_FORMAT)].down[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DST_FORMAT),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].down[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].down[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].down[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_LUT8),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_LUT8)].down[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_LUT8),
+#undef FUNC_NAME_
+
+/* FIXME: DST_FORMAT == DSPF_RGB16 doesn't work */
+#ifdef FORMAT_RGB16
+#define FUNC_NAME_(K,P,F) FUNC_NAME(up,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].up[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].up[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].up[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].up[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_ARGB4444),
+#undef FUNC_NAME_
+#define FUNC_NAME_(K,P,F) FUNC_NAME(down,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].down[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].down[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].down[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_ARGB4444),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)].down[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_ARGB4444),
+#undef FUNC_NAME_
+#endif
+
+/* FIXME: DST_FORMAT == DSPF_ARGB4444 doesn't work */
+#ifdef FORMAT_ARGB4444
+#define FUNC_NAME_(K,P,F) FUNC_NAME(up,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].up[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].up[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].up[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].up[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_RGB16),
+#undef FUNC_NAME_
+#define FUNC_NAME_(K,P,F) FUNC_NAME(down,K,P,F)
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].down[STRETCH_NONE] = FUNC_NAME_(_,_,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].down[STRETCH_PROTECT] = FUNC_NAME_(_,P,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].down[STRETCH_SRCKEY] = FUNC_NAME_(K,_,DSPF_RGB16),
+ .f[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)].down[STRETCH_SRCKEY_PROTECT] = FUNC_NAME_(K,P,DSPF_RGB16),
+#undef FUNC_NAME_
+#endif
+};
+
diff --git a/Source/DirectFB/src/gfx/generic/template_acc_16.h b/Source/DirectFB/src/gfx/generic/template_acc_16.h
new file mode 100755
index 0000000..05cea6d
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/template_acc_16.h
@@ -0,0 +1,382 @@
+/*
+ (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.
+*/
+
+/*
+ * Example:
+ * #define A_SHIFT 15
+ * #define R_SHIFT 10
+ * #define G_SHIFT 5
+ * #define B_SHIFT 0
+ * #define A_MASK 0x8000
+ * #define R_MASK 0x7c00
+ * #define G_MASK 0x03e0
+ * #define B_MASK 0x001f
+ * #define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB1555( a, r, g, b )
+ * #define EXPAND_Ato8( a ) EXPAND_1to8( a )
+ * #define EXPAND_Rto8( r ) EXPAND_5to8( r )
+ * #define EXPAND_Gto8( g ) EXPAND_5to8( g )
+ * #define EXPAND_Bto8( b ) EXPAND_5to8( b )
+ * #define Sop_PFI_OP_Dacc( op ) Sop_argb1555_##op##_Dacc
+ * #define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb1555
+ * #include "template_acc_16.h"
+ */
+
+#define RGB_MASK (R_MASK | G_MASK | B_MASK)
+
+#if RGB_MASK == 0xffff
+#define MASK_RGB( p ) (p)
+#else
+#define MASK_RGB( p ) ((p) & RGB_MASK)
+#endif
+
+#define PIXEL( x ) PIXEL_OUT( ((x).RGB.a & 0xFF00) ? 0xFF : (x).RGB.a, \
+ ((x).RGB.r & 0xFF00) ? 0xFF : (x).RGB.r, \
+ ((x).RGB.g & 0xFF00) ? 0xFF : (x).RGB.g, \
+ ((x).RGB.b & 0xFF00) ? 0xFF : (x).RGB.b )
+
+#define EXPAND( d, s ) do { \
+ (d).RGB.a = EXPAND_Ato8( (s & A_MASK) >> A_SHIFT ); \
+ (d).RGB.r = EXPAND_Rto8( (s & R_MASK) >> R_SHIFT ); \
+ (d).RGB.g = EXPAND_Gto8( (s & G_MASK) >> G_SHIFT ); \
+ (d).RGB.b = EXPAND_Bto8( (s & B_MASK) >> B_SHIFT ); \
+} while (0)
+
+/********************************* Sop_PFI_Sto_Dacc ***************************/
+
+static void Sop_PFI_OP_Dacc(Sto)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u16 *S = gfxs->Sop[0];
+ int Ostep = gfxs->Ostep;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ if (Ostep != 1)
+ D_UNIMPLEMENTED();
+
+ while (l--) {
+ u16 s = S[i>>16];
+
+ EXPAND( *D, s );
+
+ D++;
+ i += SperD;
+ }
+}
+
+/********************************* Sop_PFI_SKto_Dacc **************************/
+
+static void Sop_PFI_OP_Dacc(SKto)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u16 *S = gfxs->Sop[0];
+ int Ostep = gfxs->Ostep;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u16 Skey = gfxs->Skey;
+
+ if (Ostep != 1)
+ D_UNIMPLEMENTED();
+
+ while (l--) {
+ u16 s = S[i>>16];
+
+ if (MASK_RGB( s ) != Skey)
+ EXPAND( *D, s );
+ else
+ D->RGB.a = 0xF000;
+
+ D++;
+ i += SperD;
+ }
+}
+
+/********************************* Sop_PFI_to_Dacc ****************************/
+
+static void Sop_PFI_OP_Dacc(to)( GenefxState *gfxs )
+{
+ int w, l = gfxs->length;
+ u16 *S = gfxs->Sop[0];
+ GenefxAccumulator *D = gfxs->Dacc;
+ int Ostep = gfxs->Ostep;
+
+ if (Ostep != 1) {
+ while (l--) {
+ u16 s = *S;
+
+ EXPAND( *D, s );
+
+ S += Ostep;
+
+ D++;
+ }
+ return;
+ }
+
+ if ((long)S & 2) {
+ u16 s = *S++;
+
+ EXPAND( *D, s );
+
+ D++;
+ l--;
+ }
+
+ w = l >> 1;
+ while (w--) {
+ u32 s = *(u32 *) S;
+
+#ifdef WORDS_BIGENDIAN
+ EXPAND( D[0], s >> 16 );
+ EXPAND( D[1], s );
+#else
+ EXPAND( D[0], s );
+ EXPAND( D[1], s >> 16);
+#endif
+
+ S += 2;
+ D += 2;
+ }
+
+ if (l & 1) {
+ u16 s = *S;
+
+ EXPAND( *D, s );
+ }
+}
+
+/********************************* Sop_PFI_Kto_Dacc ***************************/
+
+static void Sop_PFI_OP_Dacc(Kto)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ u16 *S = gfxs->Sop[0];
+ GenefxAccumulator *D = gfxs->Dacc;
+ u16 Skey = gfxs->Skey;
+ int Ostep = gfxs->Ostep;
+
+ while (l--) {
+ u16 s = *S;
+
+ if (MASK_RGB( s ) != Skey)
+ EXPAND( *D, s );
+ else
+ D->RGB.a = 0xF000;
+
+ S += Ostep;
+ D++;
+ }
+}
+
+/********************************* Sacc_to_Aop_PFI ****************************/
+
+static void Sacc_OP_Aop_PFI(to)( GenefxState *gfxs )
+{
+ int w, l = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u16 *D = gfxs->Aop[0];
+ int Dstep = gfxs->Astep;
+
+ if (Dstep != 1) {
+ while (l--) {
+ if (!(S->RGB.a & 0xF000))
+ *D = PIXEL( *S );
+
+ S++;
+ D += Dstep;
+ }
+ return;
+ }
+
+ if ((long)D & 2) {
+ if (!(S->RGB.a & 0xF000))
+ *D = PIXEL( *S );
+
+ S++;
+ D++;
+ l--;
+ }
+
+ w = l >> 1;
+ while (w--) {
+ u32 *D2 = (u32 *) D;
+
+ if (!(S[0].RGB.a & 0xF000) && !(S[1].RGB.a & 0xF000)) {
+#ifdef WORDS_BIGENDIAN
+ *D2 = PIXEL( S[1] ) | PIXEL( S[0] ) << 16;
+#else
+ *D2 = PIXEL( S[0] ) | PIXEL( S[1] ) << 16;
+#endif
+ } else {
+ if (!(S[0].RGB.a & 0xF000))
+ D[0] = PIXEL( S[0] );
+ else if (!(S[1].RGB.a & 0xF000))
+ D[1] = PIXEL( S[1] );
+ }
+
+ S += 2;
+ D += 2;
+ }
+
+ if (l & 1) {
+ if (!(S->RGB.a & 0xF000))
+ *D = PIXEL( *S );
+ }
+}
+
+/********************************* Sacc_Sto_Aop_PFI ***************************/
+
+static void Sacc_OP_Aop_PFI(Sto)( GenefxState *gfxs )
+{
+ int w, l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u16 *D = gfxs->Aop[0];
+ int Dstep = gfxs->Astep;
+
+ if (Dstep != 1) {
+ while (l--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000))
+ *D = PIXEL( *S );
+
+ D += Dstep;
+ i += SperD;
+ }
+ return;
+ }
+ if ((long)D & 2) {
+ GenefxAccumulator *S = Sacc;
+
+ if (!(S->RGB.a & 0xF000))
+ *D = PIXEL( *S );
+
+ D++;
+ l--;
+ i += SperD;
+ }
+
+ w = l >> 1;
+ while (w--) {
+ GenefxAccumulator *S0 = &Sacc[i>>16];
+ GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16];
+ u32 *D2 = (u32 *) D;
+
+ if (!(S0->RGB.a & 0xF000) && !(S1->RGB.a & 0xF000)) {
+#ifdef WORDS_BIGENDIAN
+ *D2 = PIXEL( *S1 ) | PIXEL( *S0 ) << 16;
+#else
+ *D2 = PIXEL( *S0 ) | PIXEL( *S1 ) << 16;
+#endif
+ } else {
+ if (!(S0->RGB.a & 0xF000))
+ D[0] = PIXEL( *S0 );
+ else if (!(S1->RGB.a & 0xF000))
+ D[1] = PIXEL( *S1 );
+ }
+
+ D += 2;
+ i += SperD << 1;
+ }
+
+ if (l & 1) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000))
+ *D = PIXEL( *S );
+ }
+}
+
+/********************************* Sacc_toK_Aop_PFI ***************************/
+
+static void Sacc_OP_Aop_PFI(toK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u16 *D = gfxs->Aop[0];
+ u16 Dkey = gfxs->Dkey;
+ int Dstep = gfxs->Astep;
+
+ while (l--) {
+ if (!(S->RGB.a & 0xF000) && MASK_RGB( *D ) == Dkey)
+ *D = PIXEL( *S );
+
+ S++;
+ D += Dstep;
+ }
+}
+
+/********************************* Sacc_StoK_Aop_PFI **************************/
+
+static void Sacc_OP_Aop_PFI(StoK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u16 *D = gfxs->Aop[0];
+ u16 Dkey = gfxs->Dkey;
+ int Dstep = gfxs->Astep;
+
+ while (l--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000) && MASK_RGB( *D ) == Dkey)
+ *D = PIXEL( *S );
+
+ D += Dstep;
+ i += SperD;
+ }
+}
+
+/******************************************************************************/
+
+#undef RGB_MASK
+#undef MASK_RGB
+#undef PIXEL
+#undef EXPAND
+
+#undef A_SHIFT
+#undef R_SHIFT
+#undef G_SHIFT
+#undef B_SHIFT
+#undef A_MASK
+#undef R_MASK
+#undef G_MASK
+#undef B_MASK
+#undef PIXEL_OUT
+#undef EXPAND_Ato8
+#undef EXPAND_Rto8
+#undef EXPAND_Gto8
+#undef EXPAND_Bto8
+#undef Sop_PFI_OP_Dacc
+#undef Sacc_OP_Aop_PFI
diff --git a/Source/DirectFB/src/gfx/generic/template_acc_32.h b/Source/DirectFB/src/gfx/generic/template_acc_32.h
new file mode 100755
index 0000000..313d568
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/template_acc_32.h
@@ -0,0 +1,261 @@
+/*
+ (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.
+*/
+
+/*
+ * Example:
+ * #define A_SHIFT 24
+ * #define R_SHIFT 16
+ * #define G_SHIFT 8
+ * #define B_SHIFT 0
+ * #define A_MASK 0xff000000
+ * #define R_MASK 0x00ff0000
+ * #define G_MASK 0x0000ff00
+ * #define B_MASK 0x000000ff
+ * #define PIXEL_OUT( a, r, g, b ) PIXEL_AiRGB( a, r, g, b )
+ * #define EXPAND_Ato8( a ) ((a) ^ 0xff)
+ * #define EXPAND_Rto8( r ) (r)
+ * #define EXPAND_Gto8( g ) (g)
+ * #define EXPAND_Bto8( b ) (b)
+ * #define Sop_PFI_OP_Dacc( op ) Sop_airgb_##op##_Dacc
+ * #define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_airgb
+ * #include "template_acc_32.h"
+ */
+
+#define RGB_MASK (R_MASK | G_MASK | B_MASK)
+
+#define PIXEL( s ) PIXEL_OUT( ((s).RGB.a & 0xFF00) ? 0xFF : (s).RGB.a, \
+ ((s).RGB.r & 0xFF00) ? 0xFF : (s).RGB.r, \
+ ((s).RGB.g & 0xFF00) ? 0xFF : (s).RGB.g, \
+ ((s).RGB.b & 0xFF00) ? 0xFF : (s).RGB.b )
+
+#define EXPAND( d, s ) \
+do { \
+ (d).RGB.a = EXPAND_Ato8( (s & A_MASK) >> A_SHIFT ); \
+ (d).RGB.r = EXPAND_Rto8( (s & R_MASK) >> R_SHIFT ); \
+ (d).RGB.g = EXPAND_Gto8( (s & G_MASK) >> G_SHIFT ); \
+ (d).RGB.b = EXPAND_Bto8( (s & B_MASK) >> B_SHIFT ); \
+} while (0)
+
+/********************************* Sop_PFI_Sto_Dacc ***************************/
+
+static void Sop_PFI_OP_Dacc(Sto)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u32 *S = gfxs->Sop[0];
+ int Ostep = gfxs->Ostep;
+ GenefxAccumulator *D = gfxs->Dacc;
+
+ if (Ostep != 1)
+ D_UNIMPLEMENTED();
+
+ while (l--) {
+ u32 s = S[i>>16];
+
+ EXPAND( *D, s );
+
+ D++;
+ i += SperD;
+ }
+}
+
+/********************************* Sop_PFI_SKto_Dacc **************************/
+
+static void Sop_PFI_OP_Dacc(SKto)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u32 *S = gfxs->Sop[0];
+ int Ostep = gfxs->Ostep;
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 Skey = gfxs->Skey;
+
+ if (Ostep != 1)
+ D_UNIMPLEMENTED();
+
+ while (l--) {
+ u32 s = S[i>>16];
+
+ if ((s & RGB_MASK) != Skey)
+ EXPAND( *D, s );
+ else
+ D->RGB.a = 0xF000;
+
+ D++;
+ i += SperD;
+ }
+}
+
+/********************************* Sop_PFI_to_Dacc ****************************/
+
+static void Sop_PFI_OP_Dacc(to)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ u32 *S = gfxs->Sop[0];
+ GenefxAccumulator *D = gfxs->Dacc;
+ int Ostep = gfxs->Ostep;
+
+ while (l--) {
+ u32 s = *S;
+
+ EXPAND( *D, s );
+
+ S += Ostep;
+
+ D++;
+ }
+}
+
+/********************************* Sop_PFI_Kto_Dacc ***************************/
+
+static void Sop_PFI_OP_Dacc(Kto)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ u32 *S = gfxs->Sop[0];
+ GenefxAccumulator *D = gfxs->Dacc;
+ u32 Skey = gfxs->Skey;
+ int Ostep = gfxs->Ostep;
+
+ while (l--) {
+ u32 s = *S;
+
+ if ((s & RGB_MASK) != Skey)
+ EXPAND( *D, s );
+ else
+ D->RGB.a = 0xF000;
+
+ S += Ostep;
+ D++;
+ }
+}
+
+/********************************* Sacc_to_Aop_PFI ****************************/
+
+static void Sacc_OP_Aop_PFI(to)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u32 *D = gfxs->Aop[0];
+ int Dstep = gfxs->Astep;
+
+ while (l--) {
+ if (!(S->RGB.a & 0xF000))
+ *D = PIXEL( *S );
+
+ S++;
+ D += Dstep;
+ }
+}
+
+/********************************* Sacc_Sto_Aop_PFI ***************************/
+
+static void Sacc_OP_Aop_PFI(Sto)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u32 *D = gfxs->Aop[0];
+ int Dstep = gfxs->Astep;
+
+ while (l--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000))
+ *D = PIXEL( *S );
+
+ D += Dstep;
+ i += SperD;
+ }
+}
+
+/********************************* Sacc_toK_Aop_PFI ***************************/
+
+static void Sacc_OP_Aop_PFI(toK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ GenefxAccumulator *S = gfxs->Sacc;
+ u32 *D = gfxs->Aop[0];
+ int Dstep = gfxs->Astep;
+ u32 Dkey = gfxs->Dkey;
+
+ while (l--) {
+ if (!(S->RGB.a & 0xF000) && (*D & RGB_MASK) == Dkey)
+ *D = PIXEL( *S );
+
+ S++;
+ D += Dstep;
+ }
+}
+
+/********************************* Sacc_StoK_Aop_PFI **************************/
+
+static void Sacc_OP_Aop_PFI(StoK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ GenefxAccumulator *Sacc = gfxs->Sacc;
+ u32 *D = gfxs->Aop[0];
+ int Dstep = gfxs->Astep;
+ u32 Dkey = gfxs->Dkey;
+
+ while (l--) {
+ GenefxAccumulator *S = &Sacc[i>>16];
+
+ if (!(S->RGB.a & 0xF000) && (*D & RGB_MASK) == Dkey)
+ *D = PIXEL( *S );
+
+ D += Dstep;
+ i += SperD;
+ }
+}
+
+/******************************************************************************/
+
+#undef RGB_MASK
+#undef PIXEL
+#undef EXPAND
+
+#undef A_SHIFT
+#undef R_SHIFT
+#undef G_SHIFT
+#undef B_SHIFT
+#undef A_MASK
+#undef R_MASK
+#undef G_MASK
+#undef B_MASK
+#undef PIXEL_OUT
+#undef EXPAND_Ato8
+#undef EXPAND_Rto8
+#undef EXPAND_Gto8
+#undef EXPAND_Bto8
+#undef Sop_PFI_OP_Dacc
+#undef Sacc_OP_Aop_PFI
diff --git a/Source/DirectFB/src/gfx/generic/template_colorkey_16.h b/Source/DirectFB/src/gfx/generic/template_colorkey_16.h
new file mode 100755
index 0000000..542dad2
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/template_colorkey_16.h
@@ -0,0 +1,369 @@
+/*
+ (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.
+*/
+
+/*
+ * Example:
+ * #define RGB_MASK 0x7fff
+ * #define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_15
+ * #define Bop_PFI_OP_Aop_PFI( op ) Bop_15_##op##_Aop_15
+ * #include "template_ckey_16.h"
+ */
+
+#if RGB_MASK == 0xffff
+#define MASK_RGB( p ) (p)
+#else
+#define MASK_RGB( p ) ((p) & RGB_MASK)
+#endif
+
+#define MASK_RGB_L( p ) ((p) & RGB_MASK)
+#define MASK_RGB_H( p ) ((p) & (RGB_MASK << 16))
+#define MASK_RGB_32( p ) ((p) & (RGB_MASK << 16 | RGB_MASK))
+
+/********************************* Cop_toK_Aop_PFI ****************************/
+
+static void Cop_OP_Aop_PFI(toK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ u16 *D = gfxs->Aop[0];
+ u16 Dkey = gfxs->Dkey;
+ u16 Cop = gfxs->Cop;
+
+ while (l--) {
+ if (MASK_RGB( *D ) == Dkey)
+ *D = Cop;
+
+ D++;
+ }
+}
+
+/********************************* Bop_PFI_Kto_Aop_PFI ************************/
+
+static void Bop_PFI_OP_Aop_PFI(Kto)( GenefxState *gfxs )
+{
+ int w, l = gfxs->length;
+ int Ostep = gfxs->Ostep;
+ u16 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Skey = gfxs->Skey;
+ u32 SkeyH = gfxs->Skey << 16;
+
+ /* blit direction */
+ if (Ostep < 0) {
+ S += gfxs->length - 1;
+ D += gfxs->length - 1;
+ }
+
+ if (((long)S & 2) != ((long)D & 2)) {
+ /* source and destination misaligned */
+ while (l--) {
+ u16 s = *S;
+
+ if (MASK_RGB( s ) != Skey)
+ *D = s;
+
+ S += Ostep;
+ D += Ostep;
+ }
+
+ return;
+ }
+
+ /* fix alignment */
+ if (Ostep > 0) {
+ if ((long)D & 2) {
+ /* align / leftmost pixel */
+ u16 s = *S;
+
+ if (MASK_RGB( s ) != Skey)
+ *D = s;
+
+ S++;
+ D++;
+ l--;
+ }
+ } else { /* Ostep < 0 */
+ if ((long)D & 2) {
+ /* align */
+ S--;
+ D--;
+ } else {
+ /* rightmost pixel */
+ u16 s = *S;
+
+ if (MASK_RGB( s ) != Skey)
+ *D = s;
+
+ S -= 2;
+ D -= 2;
+ l--;
+ }
+ }
+
+ /* blit */
+ Ostep <<= 1;
+ w = l >> 1;
+ while (w--) {
+ u32 s = *(u32 *) S;
+
+ if (MASK_RGB_L( s ) != Skey) {
+ if (MASK_RGB_H( s ) != SkeyH) {
+ *(u32 *) D = s;
+ } else {
+#ifdef WORDS_BIGENDIAN
+ D[1] = (u16) s;
+#else
+ D[0] = (u16) s;
+#endif
+ }
+ } else if (MASK_RGB_H( s ) != SkeyH) {
+#ifdef WORDS_BIGENDIAN
+ D[0] = (u16) (s >> 16);
+#else
+ D[1] = (u16) (s >> 16);
+#endif
+ }
+
+ S += Ostep;
+ D += Ostep;
+ }
+
+ /* last potential pixel */
+ if (l & 1) {
+ u16 s;
+
+ if (Ostep < 0) {
+ S++;
+ D++;
+ }
+
+ s = *S;
+ if (MASK_RGB( s ) != Skey)
+ *D = s;
+ }
+}
+
+/********************************* Bop_PFI_toK_Aop_PFI ************************/
+
+static void Bop_PFI_OP_Aop_PFI(toK)( GenefxState *gfxs )
+{
+ int w, l = gfxs->length;
+ int Ostep = gfxs->Ostep;
+ u16 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Dkey = gfxs->Dkey;
+ u32 DkeyH = gfxs->Dkey << 16;
+
+ /* blit direction */
+ if (Ostep < 0) {
+ S += gfxs->length - 1;
+ D += gfxs->length - 1;
+ }
+
+ if (((long)S & 2) != ((long)D & 2)) {
+ /* source and destination misaligned */
+ while (l--) {
+ if (MASK_RGB( *D ) == Dkey)
+ *D = *S;
+
+ S += Ostep;
+ D += Ostep;
+ }
+
+ return;
+ }
+
+ /* fix alignment */
+ if ((Ostep > 0)) {
+ if ((long)D & 2) {
+ /* align / leftmost pixel */
+ if (MASK_RGB( *D ) == Dkey)
+ *D = *S;
+
+ S++;
+ D++;
+ l--;
+ }
+ } else { /* Ostep < 0 */
+ if ((long)D & 2) {
+ /* align */
+ S--;
+ D--;
+ } else {
+ /* rightmost pixel */
+ if (MASK_RGB( *D ) == Dkey)
+ *D = *S;
+
+ S -= 2;
+ D -= 2;
+ l--;
+ }
+ }
+
+ /* blit */
+ Ostep <<= 1;
+ w = l >> 1;
+ while (w--) {
+ u32 d = *(u32 *) D;
+
+ if (MASK_RGB_32( d ) == (DkeyH | Dkey)) {
+ *(u32 *) D = *(u32 *) S;
+ } else {
+ if (MASK_RGB_L( d ) == Dkey) {
+#ifdef WORDS_BIGENDIAN
+ D[0] = S[0];
+#else
+ D[1] = S[1];
+#endif
+ } else
+ if (MASK_RGB_H( d ) == DkeyH) {
+#ifdef WORDS_BIGENDIAN
+ D[1] = S[1];
+#else
+ D[0] = S[0];
+#endif
+ }
+ }
+
+ S += Ostep;
+ D += Ostep;
+ }
+
+ /* last potential pixel */
+ if (l & 1) {
+ if (Ostep < 0) {
+ S++;
+ D++;
+ }
+
+ if (MASK_RGB( *D ) == Dkey)
+ *D = *S;
+ }
+}
+
+/********************************* Bop_PFI_KtoK_Aop_PFI ***********************/
+
+static void Bop_PFI_OP_Aop_PFI(KtoK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int Ostep = gfxs->Ostep;
+ u16 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Skey = gfxs->Skey;
+ u16 Dkey = gfxs->Dkey;
+
+ if (Ostep < 0) {
+ S += gfxs->length - 1;
+ D += gfxs->length - 1;
+ }
+
+ while (l--) {
+ u16 s = *S;
+
+ if (MASK_RGB( s ) != Skey && MASK_RGB( *D ) == Dkey)
+ *D = s;
+
+ S += Ostep;
+ D += Ostep;
+ }
+}
+
+/********************************* Bop_PFI_SKto_Aop_PFI ***********************/
+
+static void Bop_PFI_OP_Aop_PFI(SKto)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u16 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Skey = gfxs->Skey;
+
+ while (l--) {
+ u16 s = S[i>>16];
+
+ if (MASK_RGB( s ) != Skey)
+ *D = s;
+
+ D++;
+ i += SperD;
+ }
+}
+
+/********************************* Bop_PFI_StoK_Aop_PFI ***********************/
+
+static void Bop_PFI_OP_Aop_PFI(StoK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u16 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Dkey = gfxs->Dkey;
+
+ while (l--) {
+ if (MASK_RGB( *D ) != Dkey)
+ *D = S[i>>16];
+
+ D++;
+ i += SperD;
+ }
+}
+
+/********************************* Bop_PFI_SKtoK_Aop_PFI **********************/
+
+static void Bop_PFI_OP_Aop_PFI(SKtoK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u16 *S = gfxs->Bop[0];
+ u16 *D = gfxs->Aop[0];
+ u16 Skey = gfxs->Skey;
+ u16 Dkey = gfxs->Dkey;
+
+ while (l--) {
+ u16 s = S[i>>16];
+
+ if (MASK_RGB( s ) != Skey && MASK_RGB( *D ) == Dkey)
+ *D = s;
+
+ D++;
+ i += SperD;
+ }
+}
+
+/******************************************************************************/
+
+#undef MASK_RGB
+#undef MASK_RGB_L
+#undef MASK_RGB_H
+#undef MASK_RGB_32
+
+#undef RGB_MASK
+#undef Cop_OP_Aop_PFI
+#undef Bop_PFI_OP_Aop_PFI
diff --git a/Source/DirectFB/src/gfx/generic/template_colorkey_32.h b/Source/DirectFB/src/gfx/generic/template_colorkey_32.h
new file mode 100755
index 0000000..7771d43
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/template_colorkey_32.h
@@ -0,0 +1,206 @@
+/*
+ (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.
+*/
+
+/*
+ * Example:
+ * #define RGB_MASK 0x00ffffff
+ * #define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_32
+ * #define Bop_PFI_OP_Aop_PFI( op ) Bop_32_##op##_Aop_32
+ * #include "template_colorkey_32.h"
+ */
+
+/********************************* Cop_toK_Aop_PFI ****************************/
+
+static void Cop_OP_Aop_PFI(toK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ u32 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+ u32 Cop = gfxs->Cop;
+
+ while (l--) {
+ if ((*D & RGB_MASK) == Dkey)
+ *D = Cop;
+
+ D++;
+ }
+}
+
+/********************************* Bop_PFI_Kto_Aop_PFI ************************/
+
+static void Bop_PFI_OP_Aop_PFI(Kto)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int Sstep = gfxs->Bstep;
+ int Dstep = gfxs->Astep;
+ u32 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Skey = gfxs->Skey;
+
+ if (Sstep < 0) {
+ S += gfxs->length - 1;
+ D += (gfxs->length - 1) * gfxs->Astep;
+ }
+
+ while (l--) {
+ u32 s = *S;
+
+ if ((s & RGB_MASK) != Skey)
+ *D = s;
+
+ S += Sstep;
+ D += Dstep;
+ }
+}
+
+/********************************* Bop_PFI_toK_Aop_PFI ************************/
+
+static void Bop_PFI_OP_Aop_PFI(toK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int Sstep = gfxs->Bstep;
+ int Dstep = gfxs->Astep;
+ u32 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+
+ if (Sstep < 0) {
+ S += gfxs->length - 1;
+ D += (gfxs->length - 1) * gfxs->Astep;
+ }
+
+ while (l--) {
+ if ((*D & RGB_MASK) == Dkey)
+ *D = *S;
+
+ S += Sstep;
+ D += Dstep;
+ }
+}
+
+/********************************* Bop_PFI_KtoK_Aop_PFI ***********************/
+
+static void Bop_PFI_OP_Aop_PFI(KtoK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int Sstep = gfxs->Bstep;
+ int Dstep = gfxs->Astep;
+ u32 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Skey = gfxs->Skey;
+ u32 Dkey = gfxs->Dkey;
+
+ if (Sstep < 0) {
+ S += gfxs->length - 1;
+ D += (gfxs->length - 1) * gfxs->Astep;
+ }
+
+ while (l--) {
+ u32 s = *S;
+
+ if ((s & RGB_MASK) != Skey && (*D & RGB_MASK) == Dkey)
+ *D = s;
+
+ S += Sstep;
+ D += Dstep;
+ }
+}
+
+/********************************* Bop_PFI_SKto_Aop_PFI ***********************/
+
+static void Bop_PFI_OP_Aop_PFI(SKto)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u32 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ int Dstep = gfxs->Astep;
+ u32 Skey = gfxs->Skey;
+
+ while (l--) {
+ u32 s = S[i>>16];
+
+ if ((s & RGB_MASK) != Skey)
+ *D = s;
+
+ D += Dstep;
+ i += SperD;
+ }
+}
+
+/********************************* Bop_PFI_StoK_Aop_PFI ***********************/
+
+static void Bop_PFI_OP_Aop_PFI(StoK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u32 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Dkey = gfxs->Dkey;
+ int Dstep = gfxs->Astep;
+
+ while (l--) {
+ if ((*D & RGB_MASK) != Dkey)
+ *D = S[i>>16];
+
+ D += Dstep;
+ i += SperD;
+ }
+}
+
+/********************************* Bop_PFI_SKtoK_Aop_PFI **********************/
+
+static void Bop_PFI_OP_Aop_PFI(SKtoK)( GenefxState *gfxs )
+{
+ int l = gfxs->length;
+ int i = gfxs->Xphase;
+ int SperD = gfxs->SperD;
+ u32 *S = gfxs->Bop[0];
+ u32 *D = gfxs->Aop[0];
+ u32 Skey = gfxs->Skey;
+ u32 Dkey = gfxs->Dkey;
+ int Dstep = gfxs->Astep;
+
+ while (l--) {
+ u32 s = S[i>>16];
+
+ if ((s & RGB_MASK) != Skey && (*D & RGB_MASK) == Dkey)
+ *D = s;
+
+ D += Dstep;
+ i += SperD;
+ }
+}
+
+/******************************************************************************/
+
+#undef RGB_MASK
+#undef Cop_OP_Aop_PFI
+#undef Bop_PFI_OP_Aop_PFI
diff --git a/Source/DirectFB/src/gfx/generic/yuvtbl-gen.c b/Source/DirectFB/src/gfx/generic/yuvtbl-gen.c
new file mode 100755
index 0000000..43a487d
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/yuvtbl-gen.c
@@ -0,0 +1,199 @@
+/*
+ (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 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* YCbCr->RGB:
+ * Standard ITU Rec. BT.601 derived coefficients.
+ */
+#define Y_FACTOR 1.16400
+#define VR_FACTOR 1.59600
+#define VG_FACTOR -0.81300
+#define UG_FACTOR -0.39100
+#define UB_FACTOR 2.01800
+
+/* RGB->YCbCr:
+ * ITU Rec. BT.601 defines the following formula for EyEcbEcr:
+ *
+ * Ey = 0.299 * R + 0.587 * G + 0.114 * B
+ * Ecb = (B - Ey) * 0.564
+ * Ecr = (R - Ey) * 0.713
+ *
+ * Relationship between EyEcbEcr and YCbCr:
+ *
+ * Y = Ey * 219 / 255 + 16
+ * Cb = Ecb * 224 / 255 + 128
+ * Cr = Ecr * 224 / 255 + 128
+ *
+ * Therefore, to convert RGB to YCbCr, we compute Ey from R G B,
+ * then we derive Y Cb Cr from Ey using 3 lookup tables.
+ */
+#define ECB_FACTOR 0.56400
+#define ECR_FACTOR 0.71300
+
+
+typedef struct {
+ const char *type;
+ const char *name;
+ int size;
+ struct {
+ int min;
+ int max;
+ } range;
+ struct {
+ int min;
+ int max;
+ } clamp;
+ float sub;
+ float mul;
+ float add;
+} GenTable;
+
+
+#define N_PER_LINE 10
+
+static void
+dump_table( GenTable *gt )
+{
+ int i, n;
+
+ printf( "\n%s %s[%i] = {\n", gt->type, gt->name, gt->size );
+
+ for (i = 0, n = 0; i < gt->size; i++) {
+ float num;
+
+ num = (i < gt->range.min)
+ ? gt->range.min
+ : ((i > gt->range.max) ? gt->range.max : i);
+ num = ((num - gt->sub) * gt->mul) + gt->add;
+ num = (num < gt->clamp.min)
+ ? gt->clamp.min
+ : ((num > gt->clamp.max) ? gt->clamp.max : num);
+
+ if (n == 0)
+ printf( " " );
+
+ printf( "%4i", (int) num );
+
+ if (i < (gt->size-1)) {
+ if (++n == N_PER_LINE) {
+ printf( ",\n" );
+ n = 0;
+ } else
+ printf( ", " );
+ } else
+ printf( "\n" );
+ }
+
+ printf( "};\n\n" );
+}
+
+int
+main( int argc, char **argv )
+{
+ GenTable gt = {
+ .size = 256,
+ .range.min = 16,
+ .clamp.min = -1000,
+ .clamp.max = +1000,
+ };
+
+ /* headers */
+ puts( "#ifndef __YUV_TABLES_H__" );
+ puts( "#define __YUV_TABLES_H__" );
+ puts( "" );
+
+/* YUV->RGB */
+ /* luma */
+ gt.type = "const u16";
+ gt.name = "y_for_rgb";
+ gt.range.max = 235;
+ gt.sub = 16;
+ gt.mul = Y_FACTOR;
+ gt.add = 0;
+ dump_table( &gt );
+
+ /* chroma */
+ gt.type = "const s16";
+ gt.range.max = 240;
+ gt.sub = 128;
+
+ gt.name = "cr_for_r";
+ gt.mul = VR_FACTOR;
+ dump_table( &gt );
+
+ gt.name = "cr_for_g";
+ gt.mul = VG_FACTOR;
+ dump_table( &gt );
+
+ gt.name = "cb_for_g";
+ gt.mul = UG_FACTOR;
+ dump_table( &gt );
+
+ gt.name = "cb_for_b";
+ gt.mul = UB_FACTOR;
+ dump_table( &gt );
+
+/* RGB->YUV */
+ gt.size = 256;
+ gt.range.min = 0;
+ gt.range.max = 255;
+ gt.clamp.min = 16;
+ gt.sub = 0;
+
+ /* luma */
+ gt.type = "const u16";
+ gt.name = "y_from_ey";
+ gt.clamp.max = 235;
+ gt.mul = 219.0/255.0;
+ gt.add = 16;
+ dump_table( &gt );
+
+ /* chroma */
+ gt.size = 512;
+ gt.range.max = 511;
+ gt.clamp.max = 240;
+ gt.sub = 255;
+ gt.add = 128;
+
+ /* cb */
+ gt.type = "const u16";
+ gt.name = "cb_from_bey";
+ gt.mul = ECB_FACTOR * 224.0 / 255.0;
+ dump_table( &gt );
+
+ /* cr */
+ gt.type = "const u16";
+ gt.name = "cr_from_rey";
+ gt.mul = ECR_FACTOR * 224.0 / 255.0;
+ dump_table( &gt );
+
+ /* end headers */
+ puts( "#endif /* __YUV_TABLES_H__ */" );
+
+ return 0;
+ }
diff --git a/Source/DirectFB/src/gfx/generic/yuvtbl.h b/Source/DirectFB/src/gfx/generic/yuvtbl.h
new file mode 100755
index 0000000..3769a35
--- /dev/null
+++ b/Source/DirectFB/src/gfx/generic/yuvtbl.h
@@ -0,0 +1,296 @@
+#ifndef __YUV_TABLES_H__
+#define __YUV_TABLES_H__
+
+
+const u16 y_for_rgb[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 2, 3,
+ 4, 5, 6, 8, 9, 10, 11, 12, 13, 15,
+ 16, 17, 18, 19, 20, 22, 23, 24, 25, 26,
+ 27, 29, 30, 31, 32, 33, 34, 36, 37, 38,
+ 39, 40, 41, 43, 44, 45, 46, 47, 48, 50,
+ 51, 52, 53, 54, 55, 57, 58, 59, 60, 61,
+ 62, 64, 65, 66, 67, 68, 69, 71, 72, 73,
+ 74, 75, 76, 77, 79, 80, 81, 82, 83, 84,
+ 86, 87, 88, 89, 90, 91, 93, 94, 95, 96,
+ 97, 98, 100, 101, 102, 103, 104, 105, 107, 108,
+ 109, 110, 111, 112, 114, 115, 116, 117, 118, 119,
+ 121, 122, 123, 124, 125, 126, 128, 129, 130, 131,
+ 132, 133, 135, 136, 137, 138, 139, 140, 142, 143,
+ 144, 145, 146, 147, 148, 150, 151, 152, 153, 154,
+ 155, 157, 158, 159, 160, 161, 162, 164, 165, 166,
+ 167, 168, 169, 171, 172, 173, 174, 175, 176, 178,
+ 179, 180, 181, 182, 183, 185, 186, 187, 188, 189,
+ 190, 192, 193, 194, 195, 196, 197, 199, 200, 201,
+ 202, 203, 204, 206, 207, 208, 209, 210, 211, 213,
+ 214, 215, 216, 217, 218, 219, 221, 222, 223, 224,
+ 225, 226, 228, 229, 230, 231, 232, 233, 235, 236,
+ 237, 238, 239, 240, 242, 243, 244, 245, 246, 247,
+ 249, 250, 251, 252, 253, 254, 254, 254, 254, 254,
+ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
+ 254, 254, 254, 254, 254, 254
+};
+
+
+const s16 cr_for_r[256] = {
+ -178, -178, -178, -178, -178, -178, -178, -178, -178, -178,
+ -178, -178, -178, -178, -178, -178, -178, -177, -175, -173,
+ -172, -170, -169, -167, -165, -164, -162, -161, -159, -158,
+ -156, -154, -153, -151, -150, -148, -146, -145, -143, -142,
+ -140, -138, -137, -135, -134, -132, -130, -129, -127, -126,
+ -124, -122, -121, -119, -118, -116, -114, -113, -111, -110,
+ -108, -106, -105, -103, -102, -100, -98, -97, -95, -94,
+ -92, -90, -89, -87, -86, -84, -82, -81, -79, -78,
+ -76, -75, -73, -71, -70, -68, -67, -65, -63, -62,
+ -60, -59, -57, -55, -54, -52, -51, -49, -47, -46,
+ -44, -43, -41, -39, -38, -36, -35, -33, -31, -30,
+ -28, -27, -25, -23, -22, -20, -19, -17, -15, -14,
+ -12, -11, -9, -7, -6, -4, -3, -1, 0, 1,
+ 3, 4, 6, 7, 9, 11, 12, 14, 15, 17,
+ 19, 20, 22, 23, 25, 27, 28, 30, 31, 33,
+ 35, 36, 38, 39, 41, 43, 44, 46, 47, 49,
+ 51, 52, 54, 55, 57, 59, 60, 62, 63, 65,
+ 67, 68, 70, 71, 73, 75, 76, 78, 79, 81,
+ 82, 84, 86, 87, 89, 90, 92, 94, 95, 97,
+ 98, 100, 102, 103, 105, 106, 108, 110, 111, 113,
+ 114, 116, 118, 119, 121, 122, 124, 126, 127, 129,
+ 130, 132, 134, 135, 137, 138, 140, 142, 143, 145,
+ 146, 148, 150, 151, 153, 154, 156, 158, 159, 161,
+ 162, 164, 165, 167, 169, 170, 172, 173, 175, 177,
+ 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
+ 178, 178, 178, 178, 178, 178
+};
+
+
+const s16 cr_for_g[256] = {
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 90, 89, 88,
+ 87, 86, 86, 85, 84, 83, 82, 82, 81, 80,
+ 79, 78, 78, 77, 76, 75, 74, 73, 73, 72,
+ 71, 70, 69, 69, 68, 67, 66, 65, 65, 64,
+ 63, 62, 61, 60, 60, 59, 58, 57, 56, 56,
+ 55, 54, 53, 52, 52, 51, 50, 49, 48, 47,
+ 47, 46, 45, 44, 43, 43, 42, 41, 40, 39,
+ 39, 38, 37, 36, 35, 34, 34, 33, 32, 31,
+ 30, 30, 29, 28, 27, 26, 26, 25, 24, 23,
+ 22, 21, 21, 20, 19, 18, 17, 17, 16, 15,
+ 14, 13, 13, 12, 11, 10, 9, 8, 8, 7,
+ 6, 5, 4, 4, 3, 2, 1, 0, 0, 0,
+ -1, -2, -3, -4, -4, -5, -6, -7, -8, -8,
+ -9, -10, -11, -12, -13, -13, -14, -15, -16, -17,
+ -17, -18, -19, -20, -21, -21, -22, -23, -24, -25,
+ -26, -26, -27, -28, -29, -30, -30, -31, -32, -33,
+ -34, -34, -35, -36, -37, -38, -39, -39, -40, -41,
+ -42, -43, -43, -44, -45, -46, -47, -47, -48, -49,
+ -50, -51, -52, -52, -53, -54, -55, -56, -56, -57,
+ -58, -59, -60, -60, -61, -62, -63, -64, -65, -65,
+ -66, -67, -68, -69, -69, -70, -71, -72, -73, -73,
+ -74, -75, -76, -77, -78, -78, -79, -80, -81, -82,
+ -82, -83, -84, -85, -86, -86, -87, -88, -89, -90,
+ -91, -91, -91, -91, -91, -91, -91, -91, -91, -91,
+ -91, -91, -91, -91, -91, -91
+};
+
+
+const s16 cb_for_g[256] = {
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 42,
+ 42, 41, 41, 41, 40, 40, 39, 39, 39, 38,
+ 38, 37, 37, 37, 36, 36, 35, 35, 35, 34,
+ 34, 34, 33, 33, 32, 32, 32, 31, 31, 30,
+ 30, 30, 29, 29, 28, 28, 28, 27, 27, 26,
+ 26, 26, 25, 25, 25, 24, 24, 23, 23, 23,
+ 22, 22, 21, 21, 21, 20, 20, 19, 19, 19,
+ 18, 18, 17, 17, 17, 16, 16, 16, 15, 15,
+ 14, 14, 14, 13, 13, 12, 12, 12, 11, 11,
+ 10, 10, 10, 9, 9, 8, 8, 8, 7, 7,
+ 7, 6, 6, 5, 5, 5, 4, 4, 3, 3,
+ 3, 2, 2, 1, 1, 1, 0, 0, 0, 0,
+ 0, -1, -1, -1, -2, -2, -3, -3, -3, -4,
+ -4, -5, -5, -5, -6, -6, -7, -7, -7, -8,
+ -8, -8, -9, -9, -10, -10, -10, -11, -11, -12,
+ -12, -12, -13, -13, -14, -14, -14, -15, -15, -16,
+ -16, -16, -17, -17, -17, -18, -18, -19, -19, -19,
+ -20, -20, -21, -21, -21, -22, -22, -23, -23, -23,
+ -24, -24, -25, -25, -25, -26, -26, -26, -27, -27,
+ -28, -28, -28, -29, -29, -30, -30, -30, -31, -31,
+ -32, -32, -32, -33, -33, -34, -34, -34, -35, -35,
+ -35, -36, -36, -37, -37, -37, -38, -38, -39, -39,
+ -39, -40, -40, -41, -41, -41, -42, -42, -43, -43,
+ -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
+ -43, -43, -43, -43, -43, -43
+};
+
+
+const s16 cb_for_b[256] = {
+ -226, -226, -226, -226, -226, -226, -226, -226, -226, -226,
+ -226, -226, -226, -226, -226, -226, -226, -223, -221, -219,
+ -217, -215, -213, -211, -209, -207, -205, -203, -201, -199,
+ -197, -195, -193, -191, -189, -187, -185, -183, -181, -179,
+ -177, -175, -173, -171, -169, -167, -165, -163, -161, -159,
+ -157, -155, -153, -151, -149, -147, -145, -143, -141, -139,
+ -137, -135, -133, -131, -129, -127, -125, -123, -121, -119,
+ -117, -115, -113, -110, -108, -106, -104, -102, -100, -98,
+ -96, -94, -92, -90, -88, -86, -84, -82, -80, -78,
+ -76, -74, -72, -70, -68, -66, -64, -62, -60, -58,
+ -56, -54, -52, -50, -48, -46, -44, -42, -40, -38,
+ -36, -34, -32, -30, -28, -26, -24, -22, -20, -18,
+ -16, -14, -12, -10, -8, -6, -4, -2, 0, 2,
+ 4, 6, 8, 10, 12, 14, 16, 18, 20, 22,
+ 24, 26, 28, 30, 32, 34, 36, 38, 40, 42,
+ 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
+ 64, 66, 68, 70, 72, 74, 76, 78, 80, 82,
+ 84, 86, 88, 90, 92, 94, 96, 98, 100, 102,
+ 104, 106, 108, 110, 113, 115, 117, 119, 121, 123,
+ 125, 127, 129, 131, 133, 135, 137, 139, 141, 143,
+ 145, 147, 149, 151, 153, 155, 157, 159, 161, 163,
+ 165, 167, 169, 171, 173, 175, 177, 179, 181, 183,
+ 185, 187, 189, 191, 193, 195, 197, 199, 201, 203,
+ 205, 207, 209, 211, 213, 215, 217, 219, 221, 223,
+ 226, 226, 226, 226, 226, 226, 226, 226, 226, 226,
+ 226, 226, 226, 226, 226, 226
+};
+
+
+const u16 y_from_ey[256] = {
+ 16, 16, 17, 18, 19, 20, 21, 22, 22, 23,
+ 24, 25, 26, 27, 28, 28, 29, 30, 31, 32,
+ 33, 34, 34, 35, 36, 37, 38, 39, 40, 40,
+ 41, 42, 43, 44, 45, 46, 46, 47, 48, 49,
+ 50, 51, 52, 52, 53, 54, 55, 56, 57, 58,
+ 58, 59, 60, 61, 62, 63, 64, 64, 65, 66,
+ 67, 68, 69, 70, 70, 71, 72, 73, 74, 75,
+ 76, 76, 77, 78, 79, 80, 81, 82, 82, 83,
+ 84, 85, 86, 87, 88, 89, 89, 90, 91, 92,
+ 93, 94, 95, 95, 96, 97, 98, 99, 100, 101,
+ 101, 102, 103, 104, 105, 106, 107, 107, 108, 109,
+ 110, 111, 112, 113, 113, 114, 115, 116, 117, 118,
+ 119, 119, 120, 121, 122, 123, 124, 125, 125, 126,
+ 127, 128, 129, 130, 131, 131, 132, 133, 134, 135,
+ 136, 137, 137, 138, 139, 140, 141, 142, 143, 143,
+ 144, 145, 146, 147, 148, 149, 149, 150, 151, 152,
+ 153, 154, 155, 155, 156, 157, 158, 159, 160, 161,
+ 162, 162, 163, 164, 165, 166, 167, 168, 168, 169,
+ 170, 171, 172, 173, 174, 174, 175, 176, 177, 178,
+ 179, 180, 180, 181, 182, 183, 184, 185, 186, 186,
+ 187, 188, 189, 190, 191, 192, 192, 193, 194, 195,
+ 196, 197, 198, 198, 199, 200, 201, 202, 203, 204,
+ 204, 205, 206, 207, 208, 209, 210, 210, 211, 212,
+ 213, 214, 215, 216, 216, 217, 218, 219, 220, 221,
+ 222, 222, 223, 224, 225, 226, 227, 228, 228, 229,
+ 230, 231, 232, 233, 234, 235
+};
+
+
+const u16 cb_from_bey[512] = {
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 17, 17, 18, 18, 19, 19, 19, 20, 20,
+ 21, 21, 22, 22, 23, 23, 24, 24, 25, 25,
+ 26, 26, 27, 27, 28, 28, 29, 29, 30, 30,
+ 31, 31, 32, 32, 33, 33, 34, 34, 35, 35,
+ 36, 36, 37, 37, 38, 38, 39, 39, 40, 40,
+ 41, 41, 42, 42, 43, 43, 44, 44, 45, 45,
+ 46, 46, 47, 47, 48, 48, 49, 49, 50, 50,
+ 51, 51, 52, 52, 53, 53, 54, 54, 55, 55,
+ 56, 56, 57, 57, 58, 58, 59, 59, 60, 60,
+ 61, 61, 62, 62, 63, 63, 64, 64, 65, 65,
+ 66, 66, 67, 67, 68, 68, 69, 69, 70, 70,
+ 71, 71, 72, 72, 73, 73, 73, 74, 74, 75,
+ 75, 76, 76, 77, 77, 78, 78, 79, 79, 80,
+ 80, 81, 81, 82, 82, 83, 83, 84, 84, 85,
+ 85, 86, 86, 87, 87, 88, 88, 89, 89, 90,
+ 90, 91, 91, 92, 92, 93, 93, 94, 94, 95,
+ 95, 96, 96, 97, 97, 98, 98, 99, 99, 100,
+ 100, 101, 101, 102, 102, 103, 103, 104, 104, 105,
+ 105, 106, 106, 107, 107, 108, 108, 109, 109, 110,
+ 110, 111, 111, 112, 112, 113, 113, 114, 114, 115,
+ 115, 116, 116, 117, 117, 118, 118, 119, 119, 120,
+ 120, 121, 121, 122, 122, 123, 123, 124, 124, 125,
+ 125, 126, 126, 127, 127, 128, 128, 128, 129, 129,
+ 130, 130, 131, 131, 132, 132, 133, 133, 134, 134,
+ 135, 135, 136, 136, 137, 137, 138, 138, 139, 139,
+ 140, 140, 141, 141, 142, 142, 143, 143, 144, 144,
+ 145, 145, 146, 146, 147, 147, 148, 148, 149, 149,
+ 150, 150, 151, 151, 152, 152, 153, 153, 154, 154,
+ 155, 155, 156, 156, 157, 157, 158, 158, 159, 159,
+ 160, 160, 161, 161, 162, 162, 163, 163, 164, 164,
+ 165, 165, 166, 166, 167, 167, 168, 168, 169, 169,
+ 170, 170, 171, 171, 172, 172, 173, 173, 174, 174,
+ 175, 175, 176, 176, 177, 177, 178, 178, 179, 179,
+ 180, 180, 181, 181, 182, 182, 182, 183, 183, 184,
+ 184, 185, 185, 186, 186, 187, 187, 188, 188, 189,
+ 189, 190, 190, 191, 191, 192, 192, 193, 193, 194,
+ 194, 195, 195, 196, 196, 197, 197, 198, 198, 199,
+ 199, 200, 200, 201, 201, 202, 202, 203, 203, 204,
+ 204, 205, 205, 206, 206, 207, 207, 208, 208, 209,
+ 209, 210, 210, 211, 211, 212, 212, 213, 213, 214,
+ 214, 215, 215, 216, 216, 217, 217, 218, 218, 219,
+ 219, 220, 220, 221, 221, 222, 222, 223, 223, 224,
+ 224, 225, 225, 226, 226, 227, 227, 228, 228, 229,
+ 229, 230, 230, 231, 231, 232, 232, 233, 233, 234,
+ 234, 235, 235, 236, 236, 236, 237, 237, 238, 238,
+ 239, 239, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240
+};
+
+
+const u16 cr_from_rey[512] = {
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17,
+ 18, 19, 19, 20, 20, 21, 22, 22, 23, 24,
+ 24, 25, 25, 26, 27, 27, 28, 29, 29, 30,
+ 30, 31, 32, 32, 33, 34, 34, 35, 35, 36,
+ 37, 37, 38, 39, 39, 40, 40, 41, 42, 42,
+ 43, 44, 44, 45, 45, 46, 47, 47, 48, 49,
+ 49, 50, 50, 51, 52, 52, 53, 54, 54, 55,
+ 55, 56, 57, 57, 58, 59, 59, 60, 60, 61,
+ 62, 62, 63, 64, 64, 65, 65, 66, 67, 67,
+ 68, 69, 69, 70, 71, 71, 72, 72, 73, 74,
+ 74, 75, 76, 76, 77, 77, 78, 79, 79, 80,
+ 81, 81, 82, 82, 83, 84, 84, 85, 86, 86,
+ 87, 87, 88, 89, 89, 90, 91, 91, 92, 92,
+ 93, 94, 94, 95, 96, 96, 97, 97, 98, 99,
+ 99, 100, 101, 101, 102, 102, 103, 104, 104, 105,
+ 106, 106, 107, 107, 108, 109, 109, 110, 111, 111,
+ 112, 112, 113, 114, 114, 115, 116, 116, 117, 117,
+ 118, 119, 119, 120, 121, 121, 122, 122, 123, 124,
+ 124, 125, 126, 126, 127, 128, 128, 129, 129, 130,
+ 131, 131, 132, 133, 133, 134, 134, 135, 136, 136,
+ 137, 138, 138, 139, 139, 140, 141, 141, 142, 143,
+ 143, 144, 144, 145, 146, 146, 147, 148, 148, 149,
+ 149, 150, 151, 151, 152, 153, 153, 154, 154, 155,
+ 156, 156, 157, 158, 158, 159, 159, 160, 161, 161,
+ 162, 163, 163, 164, 164, 165, 166, 166, 167, 168,
+ 168, 169, 169, 170, 171, 171, 172, 173, 173, 174,
+ 174, 175, 176, 176, 177, 178, 178, 179, 179, 180,
+ 181, 181, 182, 183, 183, 184, 184, 185, 186, 186,
+ 187, 188, 188, 189, 190, 190, 191, 191, 192, 193,
+ 193, 194, 195, 195, 196, 196, 197, 198, 198, 199,
+ 200, 200, 201, 201, 202, 203, 203, 204, 205, 205,
+ 206, 206, 207, 208, 208, 209, 210, 210, 211, 211,
+ 212, 213, 213, 214, 215, 215, 216, 216, 217, 218,
+ 218, 219, 220, 220, 221, 221, 222, 223, 223, 224,
+ 225, 225, 226, 226, 227, 228, 228, 229, 230, 230,
+ 231, 231, 232, 233, 233, 234, 235, 235, 236, 236,
+ 237, 238, 238, 239, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
+ 240, 240
+};
+
+#endif /* __YUV_TABLES_H__ */
diff --git a/Source/DirectFB/src/gfx/util.c b/Source/DirectFB/src/gfx/util.c
new file mode 100755
index 0000000..9e59b84
--- /dev/null
+++ b/Source/DirectFB/src/gfx/util.c
@@ -0,0 +1,270 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <pthread.h>
+
+#include <directfb.h>
+
+#include <direct/util.h>
+
+#include <core/coretypes.h>
+
+#include <core/state.h>
+#include <core/gfxcard.h>
+
+#include <gfx/util.h>
+
+#include <misc/util.h>
+
+
+static bool copy_state_inited;
+static CardState copy_state;
+
+static bool btf_state_inited;
+static CardState btf_state;
+
+#if FIXME_SC_3
+static bool cd_state_inited;
+static CardState cd_state;
+#endif
+
+static pthread_mutex_t copy_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t btf_lock = PTHREAD_MUTEX_INITIALIZER;
+#if FIXME_SC_3
+static pthread_mutex_t cd_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+
+void
+dfb_gfx_copy( CoreSurface *source, CoreSurface *destination, const DFBRectangle *rect )
+{
+ dfb_gfx_copy_to( source, destination, rect, rect ? rect->x : 0, rect ? rect->y : 0, false );
+}
+
+void
+dfb_gfx_copy_to( CoreSurface *source, CoreSurface *destination, const DFBRectangle *rect, int x, int y, bool from_back )
+{
+ DFBRectangle sourcerect = { 0, 0, source->config.size.w, source->config.size.h };
+
+ pthread_mutex_lock( &copy_lock );
+
+ if (!copy_state_inited) {
+ dfb_state_init( &copy_state, NULL );
+ copy_state_inited = true;
+ }
+
+ copy_state.modified |= SMF_CLIP | SMF_SOURCE | SMF_DESTINATION;
+
+ copy_state.clip.x2 = destination->config.size.w - 1;
+ copy_state.clip.y2 = destination->config.size.h - 1;
+ copy_state.source = source;
+ copy_state.destination = destination;
+ copy_state.from = from_back ? CSBR_BACK : CSBR_FRONT;
+
+ if (rect) {
+ if (dfb_rectangle_intersect( &sourcerect, rect ))
+ dfb_gfxcard_blit( &sourcerect,
+ x + sourcerect.x - rect->x,
+ y + sourcerect.y - rect->y, &copy_state );
+ }
+ else
+ dfb_gfxcard_blit( &sourcerect, x, y, &copy_state );
+
+ /* Signal end of sequence. */
+ dfb_state_stop_drawing( &copy_state );
+
+ pthread_mutex_unlock( &copy_lock );
+}
+
+static void
+back_to_front_copy( CoreSurface *surface, const DFBRegion *region, DFBSurfaceBlittingFlags flags, int rotation)
+{
+ DFBRectangle rect;
+ int dx, dy;
+
+ if (region) {
+ rect.x = region->x1;
+ rect.y = region->y1;
+ rect.w = region->x2 - region->x1 + 1;
+ rect.h = region->y2 - region->y1 + 1;
+ }
+ else {
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = surface->config.size.w;
+ rect.h = surface->config.size.h;
+ }
+
+ dx = rect.x;
+ dy = rect.y;
+
+ pthread_mutex_lock( &btf_lock );
+
+ if (!btf_state_inited) {
+ dfb_state_init( &btf_state, NULL );
+
+ btf_state.from = CSBR_BACK;
+ btf_state.to = CSBR_FRONT;
+
+ btf_state_inited = true;
+ }
+
+ btf_state.modified |= SMF_CLIP | SMF_SOURCE | SMF_DESTINATION;
+
+ btf_state.clip.x2 = surface->config.size.w - 1;
+ btf_state.clip.y2 = surface->config.size.h - 1;
+ btf_state.source = surface;
+ btf_state.destination = surface;
+
+
+ if (rotation == 90) {
+ dx = rect.y;
+ dy = surface->config.size.w - rect.w - rect.x;
+
+ flags |= DSBLIT_ROTATE90;
+ }
+ else if (rotation == 180) {
+ dx = surface->config.size.w - rect.w - rect.x;
+ dy = surface->config.size.h - rect.h - rect.y;
+
+ flags |= DSBLIT_ROTATE180;
+ }
+ else if (rotation == 270) {
+ dx = surface->config.size.h - rect.h - rect.y;
+ dy = rect.x;
+
+ flags |= DSBLIT_ROTATE270;
+ }
+
+
+ dfb_state_set_blitting_flags( &btf_state, flags );
+
+ dfb_gfxcard_blit( &rect, dx, dy, &btf_state );
+
+ /* Signal end of sequence. */
+ dfb_state_stop_drawing( &btf_state );
+
+ pthread_mutex_unlock( &btf_lock );
+}
+
+void
+dfb_back_to_front_copy( CoreSurface *surface, const DFBRegion *region )
+{
+ back_to_front_copy( surface, region, DSBLIT_NOFX, 0);
+}
+
+void
+dfb_back_to_front_copy_rotation( CoreSurface *surface, const DFBRegion *region, int rotation )
+{
+ back_to_front_copy( surface, region, DSBLIT_NOFX, rotation );
+}
+
+void
+dfb_clear_depth( CoreSurface *surface, const DFBRegion *region )
+{
+#if FIXME_SC_3
+ SurfaceBuffer *tmp;
+ DFBRectangle rect = { 0, 0, surface->config.size.w - 1, surface->config.size.h - 1 };
+
+ if (region && !dfb_rectangle_intersect_by_region( &rect, region ))
+ return;
+
+ pthread_mutex_lock( &cd_lock );
+
+ if (!cd_state_inited) {
+ dfb_state_init( &cd_state, NULL );
+
+ cd_state.color.r = 0xff;
+ cd_state.color.g = 0xff;
+ cd_state.color.b = 0xff;
+
+ cd_state_inited = true;
+ }
+
+ cd_state.modified |= SMF_CLIP | SMF_DESTINATION;
+
+ cd_state.clip.x2 = surface->config.size.w - 1;
+ cd_state.clip.y2 = surface->config.size.h - 1;
+ cd_state.destination = surface;
+
+ dfb_surfacemanager_lock( surface->manager );
+
+ tmp = surface->back_buffer;
+ surface->back_buffer = surface->depth_buffer;
+
+ dfb_gfxcard_fillrectangles( &rect, 1, &cd_state );
+
+ surface->back_buffer = tmp;
+
+ dfb_surfacemanager_unlock( surface->manager );
+
+ /* Signal end of sequence. */
+ dfb_state_stop_drawing( &cd_state );
+
+ pthread_mutex_unlock( &cd_lock );
+#endif
+}
+
+
+void dfb_sort_triangle( DFBTriangle *tri )
+{
+ int temp;
+
+ if (tri->y1 > tri->y2) {
+ temp = tri->x1;
+ tri->x1 = tri->x2;
+ tri->x2 = temp;
+
+ temp = tri->y1;
+ tri->y1 = tri->y2;
+ tri->y2 = temp;
+ }
+
+ if (tri->y2 > tri->y3) {
+ temp = tri->x2;
+ tri->x2 = tri->x3;
+ tri->x3 = temp;
+
+ temp = tri->y2;
+ tri->y2 = tri->y3;
+ tri->y3 = temp;
+ }
+
+ if (tri->y1 > tri->y2) {
+ temp = tri->x1;
+ tri->x1 = tri->x2;
+ tri->x2 = temp;
+
+ temp = tri->y1;
+ tri->y1 = tri->y2;
+ tri->y2 = temp;
+ }
+}
+
diff --git a/Source/DirectFB/src/gfx/util.h b/Source/DirectFB/src/gfx/util.h
new file mode 100755
index 0000000..79cbd6d
--- /dev/null
+++ b/Source/DirectFB/src/gfx/util.h
@@ -0,0 +1,42 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __GFX__UTIL_H__
+#define __GFX__UTIL_H__
+
+#include <core/surface.h>
+
+void dfb_gfx_copy( CoreSurface *source, CoreSurface *destination, const DFBRectangle *rect );
+void dfb_gfx_copy_to( CoreSurface *source, CoreSurface *destination, const DFBRectangle *rect, int x, int y, bool from_back );
+void dfb_back_to_front_copy( CoreSurface *surface, const DFBRegion *region );
+void dfb_back_to_front_copy_rotation( CoreSurface *surface, const DFBRegion *region, int rotation );
+void dfb_clear_depth( CoreSurface *surface, const DFBRegion *region );
+
+void dfb_sort_triangle( DFBTriangle *tri );
+
+#endif
diff --git a/Source/DirectFB/src/idirectfb.c b/Source/DirectFB/src/idirectfb.c
new file mode 100755
index 0000000..144eaad
--- /dev/null
+++ b/Source/DirectFB/src/idirectfb.c
@@ -0,0 +1,1965 @@
+/*
+ (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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <string.h>
+
+#include <directfb.h>
+#include <directfb_version.h>
+
+#include <core/core.h>
+#include <core/coretypes.h>
+
+#include <core/clipboard.h>
+#include <core/state.h>
+#include <core/gfxcard.h>
+#include <core/input.h>
+#include <core/layer_context.h>
+#include <core/layer_control.h>
+#include <core/layer_region.h>
+#include <core/layers.h>
+#include <core/palette.h>
+#include <core/screen.h>
+#include <core/screens.h>
+#include <core/surface.h>
+#include <core/system.h>
+#include <core/windows.h>
+#include <core/windows_internal.h> /* FIXME */
+#include <core/windowstack.h>
+
+#include <display/idirectfbpalette.h>
+#include <display/idirectfbscreen.h>
+#include <display/idirectfbsurface.h>
+#include <display/idirectfbsurface_layer.h>
+#include <display/idirectfbsurface_window.h>
+#include <display/idirectfbdisplaylayer.h>
+#include <input/idirectfbinputbuffer.h>
+#include <input/idirectfbinputdevice.h>
+#include <media/idirectfbfont.h>
+#include <media/idirectfbimageprovider.h>
+#include <media/idirectfbvideoprovider.h>
+#include <media/idirectfbdatabuffer.h>
+
+#include <idirectfb.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+#include <direct/direct.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <misc/util.h>
+
+D_DEBUG_DOMAIN( IDFB, "IDirectFB", "DirectFB Main Interface" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ DFBScreenCallback callback;
+ void *callback_ctx;
+} EnumScreens_Context;
+
+typedef struct {
+ IDirectFBScreen **interface;
+ DFBScreenID id;
+ DFBResult ret;
+} GetScreen_Context;
+
+typedef struct {
+ DFBDisplayLayerCallback callback;
+ void *callback_ctx;
+} EnumDisplayLayers_Context;
+
+typedef struct {
+ IDirectFBDisplayLayer **interface;
+ DFBDisplayLayerID id;
+ DFBResult ret;
+ CoreDFB *core;
+} GetDisplayLayer_Context;
+
+typedef struct {
+ DFBInputDeviceCallback callback;
+ void *callback_ctx;
+} EnumInputDevices_Context;
+
+typedef struct {
+ IDirectFBInputDevice **interface;
+ DFBInputDeviceID id;
+ DFBResult ret;
+} GetInputDevice_Context;
+
+typedef struct {
+ IDirectFBEventBuffer **interface;
+ DFBInputDeviceCapabilities caps;
+} CreateEventBuffer_Context;
+
+/**********************************************************************************************************************/
+
+static DFBEnumerationResult EnumScreens_Callback ( CoreScreen *screen,
+ void *ctx );
+static DFBEnumerationResult GetScreen_Callback ( CoreScreen *screen,
+ void *ctx );
+
+static DFBEnumerationResult EnumDisplayLayers_Callback( CoreLayer *layer,
+ void *ctx );
+static DFBEnumerationResult GetDisplayLayer_Callback ( CoreLayer *layer,
+ void *ctx );
+
+static DFBEnumerationResult EnumInputDevices_Callback ( CoreInputDevice *device,
+ void *ctx );
+static DFBEnumerationResult GetInputDevice_Callback ( CoreInputDevice *device,
+ void *ctx );
+
+static DFBEnumerationResult CreateEventBuffer_Callback( CoreInputDevice *device,
+ void *ctx );
+
+static ReactionResult focus_listener( const void *msg_data,
+ void *ctx );
+
+static bool input_filter_local( DFBEvent *evt,
+ void *ctx );
+
+static bool input_filter_global( DFBEvent *evt,
+ void *ctx );
+
+static void drop_window( IDirectFB_data *data );
+
+/**********************************************************************************************************************/
+
+/*
+ * Destructor
+ *
+ * Free data structure and set the pointer to NULL,
+ * to indicate the dead interface.
+ */
+void
+IDirectFB_Destruct( IDirectFB *thiz )
+{
+ int i;
+ IDirectFB_data *data = (IDirectFB_data*)thiz->priv;
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ drop_window( data );
+
+ if (data->primary.context)
+ dfb_layer_context_unref( data->primary.context );
+
+ dfb_layer_context_unref( data->context );
+
+ for (i=0; i<MAX_LAYERS; i++) {
+ if (data->layers[i].context) {
+ if (data->layers[i].palette)
+ dfb_palette_unref( data->layers[i].palette );
+
+ dfb_surface_unref( data->layers[i].surface );
+ dfb_layer_region_unref( data->layers[i].region );
+ dfb_layer_context_unref( data->layers[i].context );
+ }
+ }
+
+ dfb_core_destroy( data->core, false );
+
+ idirectfb_singleton = NULL;
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+
+ direct_shutdown();
+}
+
+
+static DirectResult
+IDirectFB_AddRef( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFB_Release( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (--data->ref == 0)
+ IDirectFB_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_SetCooperativeLevel( IDirectFB *thiz,
+ DFBCooperativeLevel level )
+{
+ DFBResult ret;
+ CoreLayerContext *context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, %d )\n", __FUNCTION__, thiz, level );
+
+ if (level == data->level)
+ return DFB_OK;
+
+ switch (level) {
+ case DFSCL_NORMAL:
+ data->primary.focused = false;
+
+ dfb_layer_context_unref( data->primary.context );
+
+ data->primary.context = NULL;
+ break;
+
+ case DFSCL_FULLSCREEN:
+ case DFSCL_EXCLUSIVE:
+ if (dfb_config->force_windowed || dfb_config->force_desktop)
+ return DFB_ACCESSDENIED;
+
+ if (data->level == DFSCL_NORMAL) {
+ ret = dfb_layer_create_context( data->layer, &context );
+ if (ret)
+ return ret;
+
+ ret = dfb_layer_activate_context( data->layer, context );
+ if (ret) {
+ dfb_layer_context_unref( context );
+ return ret;
+ }
+
+ drop_window( data );
+
+ data->primary.context = context;
+ }
+
+ data->primary.focused = true;
+ break;
+
+ default:
+ return DFB_INVARG;
+ }
+
+ data->level = level;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_GetDeviceDescription( IDirectFB *thiz,
+ DFBGraphicsDeviceDescription *ret_desc )
+{
+ GraphicsDeviceInfo device_info;
+ GraphicsDriverInfo driver_info;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!ret_desc)
+ return DFB_INVARG;
+
+ dfb_gfxcard_get_device_info( &device_info );
+ dfb_gfxcard_get_driver_info( &driver_info );
+
+ ret_desc->acceleration_mask = device_info.caps.accel;
+ ret_desc->blitting_flags = device_info.caps.blitting;
+ ret_desc->drawing_flags = device_info.caps.drawing;
+ ret_desc->video_memory = dfb_gfxcard_memory_length();
+
+ snprintf( ret_desc->name, DFB_GRAPHICS_DEVICE_DESC_NAME_LENGTH, device_info.name );
+ snprintf( ret_desc->vendor, DFB_GRAPHICS_DEVICE_DESC_NAME_LENGTH, device_info.vendor );
+
+ ret_desc->driver.major = driver_info.version.major;
+ ret_desc->driver.minor = driver_info.version.minor;
+
+ snprintf( ret_desc->driver.name, DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH, driver_info.name );
+ snprintf( ret_desc->driver.vendor, DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH, driver_info.vendor );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_EnumVideoModes( IDirectFB *thiz,
+ DFBVideoModeCallback callbackfunc,
+ void *callbackdata )
+{
+ VideoMode *m;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, %p, %p )\n", __FUNCTION__, thiz, callbackfunc, callbackdata );
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+ m = dfb_system_modes();
+ while (m) {
+ if (callbackfunc( m->xres, m->yres,
+ m->bpp, callbackdata ) == DFENUM_CANCEL)
+ break;
+
+ m = m->next;
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_SetVideoMode( IDirectFB *thiz,
+ int width,
+ int height,
+ int bpp )
+{
+ DFBResult ret;
+ DFBSurfacePixelFormat format;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, %dx%d %dbit )\n", __FUNCTION__, thiz, width, height, bpp );
+
+ if (width < 1 || height < 1 || bpp < 1)
+ return DFB_INVARG;
+
+ format = dfb_pixelformat_for_depth( bpp );
+ if (format == DSPF_UNKNOWN)
+ return DFB_INVARG;
+
+ switch (data->level) {
+ case DFSCL_NORMAL:
+ if (data->primary.window) {
+ ret = dfb_window_resize( data->primary.window, width, height );
+ if (ret)
+ return ret;
+ }
+ break;
+
+ case DFSCL_FULLSCREEN:
+ case DFSCL_EXCLUSIVE: {
+ DFBResult ret;
+ DFBDisplayLayerConfig config;
+
+ config.flags = DLCONF_WIDTH | DLCONF_HEIGHT |
+ DLCONF_PIXELFORMAT;
+ config.width = width;
+ config.height = height;
+ config.pixelformat = format;
+
+ ret = dfb_layer_context_set_configuration( data->primary.context,
+ &config );
+ if (ret)
+ return ret;
+
+ break;
+ }
+ }
+
+ data->primary.width = width;
+ data->primary.height = height;
+ data->primary.format = format;
+
+ return DFB_OK;
+}
+
+static void
+init_palette( CoreSurface *surface, const DFBSurfaceDescription *desc )
+{
+ int num;
+ CorePalette *palette = surface->palette;
+
+ if (!palette || !(desc->flags & DSDESC_PALETTE))
+ return;
+
+ num = MIN( desc->palette.size, palette->num_entries );
+
+ direct_memcpy( palette->entries, desc->palette.entries, num * sizeof(DFBColor));
+
+ dfb_palette_update( palette, 0, num - 1 );
+}
+
+static DFBResult
+IDirectFB_CreateSurface( IDirectFB *thiz,
+ const DFBSurfaceDescription *desc,
+ IDirectFBSurface **interface )
+{
+ IDirectFBSurface *iface;
+ DFBResult ret;
+ int width = 256;
+ int height = 256;
+ DFBSurfacePixelFormat format;
+ DFBSurfaceCapabilities caps = DSCAPS_NONE;
+ CoreSurface *surface = NULL;
+ unsigned long resource_id = 0;
+ DFBDisplayLayerConfig config;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (data->primary.context)
+ dfb_layer_context_get_configuration( data->primary.context, &config );
+ else
+ dfb_layer_context_get_configuration( data->context, &config );
+
+ if (desc->flags & DSDESC_HINTS && desc->hints & DSHF_FONT) {
+ format = dfb_config->font_format;
+
+ if (dfb_config->font_premult)
+ caps = DSCAPS_PREMULTIPLIED;
+ }
+ else
+ format = config.pixelformat;
+
+ if (!desc || !interface)
+ return DFB_INVARG;
+
+ D_DEBUG_AT( IDFB, " -> flags 0x%08x\n", desc->flags );
+
+ if (desc->flags & DSDESC_WIDTH) {
+ D_DEBUG_AT( IDFB, " -> width %d\n", desc->width );
+
+ width = desc->width;
+ if (width < 1 || width > 20480)
+ return DFB_INVARG;
+ }
+
+ if (desc->flags & DSDESC_HEIGHT) {
+ D_DEBUG_AT( IDFB, " -> height %d\n", desc->height );
+
+ height = desc->height;
+ if (height < 1 || height > 20480)
+ return DFB_INVARG;
+ }
+
+ if (desc->flags & DSDESC_PALETTE)
+ if (!desc->palette.entries || !desc->palette.size)
+ return DFB_INVARG;
+
+ if (desc->flags & DSDESC_CAPS) {
+ D_DEBUG_AT( IDFB, " -> caps 0x%08x\n", desc->caps );
+
+ caps = desc->caps;
+ }
+
+ if (desc->flags & DSDESC_PIXELFORMAT) {
+ D_DEBUG_AT( IDFB, " -> format %s\n", dfb_pixelformat_name(desc->pixelformat) );
+
+ format = desc->pixelformat;
+ }
+
+ if (desc->flags & DSDESC_RESOURCE_ID)
+ resource_id = desc->resource_id;
+
+ switch (format) {
+ case DSPF_A1:
+ case DSPF_A4:
+ case DSPF_A8:
+ case DSPF_ARGB:
+ case DSPF_ARGB1555:
+ case DSPF_ARGB1666:
+ case DSPF_ARGB6666:
+ case DSPF_ARGB2554:
+ case DSPF_ARGB4444:
+ case DSPF_RGBA4444:
+ case DSPF_AYUV:
+ case DSPF_AiRGB:
+ case DSPF_I420:
+ case DSPF_LUT2:
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ case DSPF_RGB16:
+ case DSPF_RGB18:
+ case DSPF_RGB24:
+ case DSPF_RGB32:
+ case DSPF_RGB332:
+ case DSPF_UYVY:
+ case DSPF_YUY2:
+ case DSPF_YV12:
+ case DSPF_NV12:
+ case DSPF_NV21:
+ case DSPF_NV16:
+ case DSPF_RGB444:
+ case DSPF_RGB555:
+ case DSPF_BGR555:
+ break;
+
+ default:
+ return DFB_INVARG;
+ }
+
+ if (caps & DSCAPS_PRIMARY) {
+ if (desc->flags & DSDESC_PREALLOCATED)
+ return DFB_INVARG;
+
+ if (desc->flags & DSDESC_PIXELFORMAT)
+ format = desc->pixelformat;
+ else if (data->primary.format)
+ format = data->primary.format;
+ else if (dfb_config->mode.format)
+ format = dfb_config->mode.format;
+ else
+ format = config.pixelformat;
+
+ if (desc->flags & DSDESC_WIDTH)
+ width = desc->width;
+ else if (data->primary.width)
+ width = data->primary.width;
+ else if (dfb_config->mode.width)
+ width = dfb_config->mode.width;
+ else
+ width = config.width;
+
+ if (desc->flags & DSDESC_HEIGHT)
+ height = desc->height;
+ else if (data->primary.height)
+ height = data->primary.height;
+ else if (dfb_config->mode.height)
+ height = dfb_config->mode.height;
+ else
+ height = config.height;
+
+ /* FIXME: should we allow to create more primaries in windowed mode?
+ should the primary surface be a singleton?
+ or should we return an error? */
+ switch (data->level) {
+ case DFSCL_NORMAL:
+ if (dfb_config->force_desktop) {
+ CoreSurface *surface;
+
+ /* Source compatibility with older programs */
+ if ((caps & DSCAPS_FLIPPING) == DSCAPS_FLIPPING)
+ caps &= ~DSCAPS_TRIPLE;
+
+ ret = dfb_surface_create_simple( data->core,
+ width, height,
+ format, caps,
+ CSTF_SHARED, resource_id,
+ NULL, &surface );
+ if (ret)
+ return ret;
+
+ surface->notifications |= CSNF_FLIP;
+
+ init_palette( surface, desc );
+
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBSurface );
+
+ ret = IDirectFBSurface_Construct( iface, NULL,
+ NULL, NULL, NULL, surface, caps, data->core );
+ if (ret == DFB_OK) {
+ dfb_windowstack_set_background_image( data->stack, surface );
+ dfb_windowstack_set_background_mode( data->stack, DLBM_IMAGE );
+ }
+
+ dfb_surface_unref( surface );
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+ }
+ else {
+ CoreWindow *window;
+ DFBWindowDescription wd;
+
+ if ((caps & DSCAPS_FLIPPING) == DSCAPS_TRIPLE)
+ return DFB_UNSUPPORTED;
+
+ memset( &wd, 0, sizeof(wd) );
+
+ wd.flags = DWDESC_POSX | DWDESC_POSY | DWDESC_WIDTH | DWDESC_HEIGHT |
+ DWDESC_PIXELFORMAT | DWDESC_SURFACE_CAPS | DWDESC_CAPS | DWDESC_RESOURCE_ID;
+
+ if (dfb_config->scaled.width && dfb_config->scaled.height) {
+ wd.posx = (config.width - dfb_config->scaled.width) / 2;
+ wd.posy = (config.height - dfb_config->scaled.height) / 2;
+ }
+ else {
+ wd.posx = (config.width - width) / 2;
+ wd.posy = (config.height - height) / 2;
+ }
+
+ wd.width = width;
+ wd.height = height;
+ wd.pixelformat = format;
+ wd.surface_caps = caps & ~DSCAPS_FLIPPING;
+ wd.resource_id = resource_id;
+
+ switch (format) {
+ case DSPF_ARGB4444:
+ case DSPF_RGBA4444:
+ case DSPF_ARGB2554:
+ case DSPF_ARGB1555:
+ case DSPF_ARGB:
+ case DSPF_AYUV:
+ case DSPF_AiRGB:
+ wd.caps |= DWCAPS_ALPHACHANNEL;
+ break;
+
+ default:
+ break;
+ }
+
+ if ((caps & DSCAPS_FLIPPING) == DSCAPS_DOUBLE)
+ wd.caps |= DWCAPS_DOUBLEBUFFER;
+
+ ret = dfb_layer_context_create_window( data->core, data->context, &wd, &window );
+ if (ret)
+ return ret;
+
+ drop_window( data );
+
+ data->primary.window = window;
+
+ dfb_window_attach( window, focus_listener,
+ data, &data->primary.reaction );
+
+ dfb_window_change_options( window, DWOP_NONE, DWOP_SCALE );
+ if (dfb_config->scaled.width && dfb_config->scaled.height)
+ dfb_window_resize( window, dfb_config->scaled.width,
+ dfb_config->scaled.height );
+
+ init_palette( window->surface, desc );
+
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBSurface );
+
+ ret = IDirectFBSurface_Window_Construct( iface, NULL,
+ NULL, NULL, window,
+ caps, data->core );
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+ }
+ case DFSCL_FULLSCREEN:
+ case DFSCL_EXCLUSIVE: {
+ CoreLayerRegion *region;
+ CoreLayerContext *context = data->primary.context;
+
+ config.flags |= DLCONF_BUFFERMODE | DLCONF_PIXELFORMAT |
+ DLCONF_WIDTH | DLCONF_HEIGHT;
+
+ /* Source compatibility with older programs */
+ if ((caps & DSCAPS_FLIPPING) == DSCAPS_FLIPPING)
+ caps &= ~DSCAPS_TRIPLE;
+
+ if (caps & DSCAPS_PREMULTIPLIED) {
+ config.flags |= DLCONF_SURFACE_CAPS;
+ config.surface_caps = DSCAPS_PREMULTIPLIED;
+ }
+
+ if (caps & DSCAPS_TRIPLE) {
+ if (caps & DSCAPS_SYSTEMONLY)
+ return DFB_UNSUPPORTED;
+ config.buffermode = DLBM_TRIPLE;
+ } else if (caps & DSCAPS_DOUBLE) {
+ if (caps & DSCAPS_SYSTEMONLY)
+ config.buffermode = DLBM_BACKSYSTEM;
+ else
+ config.buffermode = DLBM_BACKVIDEO;
+ }
+ else
+ config.buffermode = DLBM_FRONTONLY;
+
+ config.pixelformat = format;
+ config.width = width;
+ config.height = height;
+
+ ret = dfb_layer_context_set_configuration( context, &config );
+ if (ret) {
+ if (!(caps & (DSCAPS_SYSTEMONLY | DSCAPS_VIDEOONLY)) &&
+ config.buffermode == DLBM_BACKVIDEO) {
+ config.buffermode = DLBM_BACKSYSTEM;
+
+ ret = dfb_layer_context_set_configuration( context, &config );
+ if (ret)
+ return ret;
+ }
+ else
+ return ret;
+ }
+
+ ret = dfb_layer_context_get_primary_region( context, true,
+ &region );
+ if (ret)
+ return ret;
+
+ ret = dfb_layer_region_get_surface( region, &surface );
+ if (ret) {
+ dfb_layer_region_unref( region );
+ return ret;
+ }
+
+/* FIXME_SC_3 if ((caps & DSCAPS_DEPTH) && !(surface->config.caps & DSCAPS_DEPTH)) {
+ ret = dfb_surface_allocate_depth( surface );
+ if (ret) {
+ dfb_surface_unref( surface );
+ dfb_layer_region_unref( region );
+ return ret;
+ }
+ }
+ else if (!(caps & DSCAPS_DEPTH) && (surface->config.caps & DSCAPS_DEPTH)) {
+ dfb_surface_deallocate_depth( surface );
+ }
+*/
+
+ init_palette( surface, desc );
+
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBSurface );
+
+ ret = IDirectFBSurface_Layer_Construct( iface, NULL,
+ NULL, NULL, region, caps, data->core );
+
+ dfb_surface_unref( surface );
+ dfb_layer_region_unref( region );
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+ }
+ }
+ }
+
+ /* Source compatibility with older programs */
+ if ((caps & DSCAPS_FLIPPING) == DSCAPS_FLIPPING)
+ caps &= ~DSCAPS_TRIPLE;
+
+ if (caps & DSCAPS_TRIPLE)
+ return DFB_UNSUPPORTED;
+
+ if (desc->flags & DSDESC_PREALLOCATED) {
+ int min_pitch;
+ CoreSurfaceConfig config;
+
+ if (caps & DSCAPS_VIDEOONLY)
+ return DFB_INVARG;
+
+ min_pitch = DFB_BYTES_PER_LINE(format, width);
+
+ if (!desc->preallocated[0].data ||
+ desc->preallocated[0].pitch < min_pitch)
+ {
+ return DFB_INVARG;
+ }
+
+ if ((caps & DSCAPS_DOUBLE) &&
+ (!desc->preallocated[1].data ||
+ desc->preallocated[1].pitch < min_pitch))
+ {
+ return DFB_INVARG;
+ }
+
+ config.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS | CSCONF_PREALLOCATED;
+ config.size.w = width;
+ config.size.h = height;
+ config.format = format;
+ config.caps = caps;
+
+ config.preallocated[0].addr = desc->preallocated[0].data;
+ config.preallocated[0].pitch = desc->preallocated[0].pitch;
+
+ config.preallocated[1].addr = desc->preallocated[1].data;
+ config.preallocated[1].pitch = desc->preallocated[1].pitch;
+
+ ret = dfb_surface_create( data->core, &config, CSTF_PREALLOCATED, resource_id, NULL, &surface );
+ if (ret)
+ return ret;
+ }
+ else {
+ CoreSurfaceConfig config;
+
+ config.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS;
+ config.size.w = width;
+ config.size.h = height;
+ config.format = format;
+ config.caps = caps;
+
+ ret = dfb_surface_create( data->core, &config, CSTF_NONE, resource_id, NULL, &surface );
+ if (ret)
+ return ret;
+ }
+
+ init_palette( surface, desc );
+
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBSurface );
+
+ ret = IDirectFBSurface_Construct( iface, NULL,
+ NULL, NULL, NULL, surface, caps, data->core );
+
+ dfb_surface_unref( surface );
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_CreatePalette( IDirectFB *thiz,
+ const DFBPaletteDescription *desc,
+ IDirectFBPalette **interface )
+{
+ DFBResult ret;
+ IDirectFBPalette *iface;
+ unsigned int size = 256;
+ CorePalette *palette = NULL;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!interface)
+ return DFB_INVARG;
+
+ if (desc && desc->flags & DPDESC_SIZE) {
+ if (!desc->size)
+ return DFB_INVARG;
+
+ size = desc->size;
+ }
+
+ ret = dfb_palette_create( data->core, size, &palette );
+ if (ret)
+ return ret;
+
+ if (desc && desc->flags & DPDESC_ENTRIES) {
+ direct_memcpy( palette->entries, desc->entries, size * sizeof(DFBColor));
+
+ dfb_palette_update( palette, 0, size - 1 );
+ }
+ else
+ dfb_palette_generate_rgb332_map( palette );
+
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBPalette );
+
+ ret = IDirectFBPalette_Construct( iface, palette );
+
+ dfb_palette_unref( palette );
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_EnumScreens( IDirectFB *thiz,
+ DFBScreenCallback callbackfunc,
+ void *callbackdata )
+{
+ EnumScreens_Context context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+ context.callback = callbackfunc;
+ context.callback_ctx = callbackdata;
+
+ dfb_screens_enumerate( EnumScreens_Callback, &context );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_GetScreen( IDirectFB *thiz,
+ DFBScreenID id,
+ IDirectFBScreen **interface )
+{
+ IDirectFBScreen *iface;
+ GetScreen_Context context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, %d )\n", __FUNCTION__, thiz, id );
+
+ if (!interface)
+ return DFB_INVARG;
+
+ if (dfb_config->primary_only && id != DLID_PRIMARY)
+ return DFB_IDNOTFOUND;
+
+ context.interface = &iface;
+ context.id = id;
+ context.ret = DFB_IDNOTFOUND;
+
+ dfb_screens_enumerate( GetScreen_Callback, &context );
+
+ if (!context.ret)
+ *interface = iface;
+
+ return context.ret;
+}
+
+static DFBResult
+IDirectFB_EnumDisplayLayers( IDirectFB *thiz,
+ DFBDisplayLayerCallback callbackfunc,
+ void *callbackdata )
+{
+ EnumDisplayLayers_Context context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+ context.callback = callbackfunc;
+ context.callback_ctx = callbackdata;
+
+ dfb_layers_enumerate( EnumDisplayLayers_Callback, &context );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_GetDisplayLayer( IDirectFB *thiz,
+ DFBDisplayLayerID id,
+ IDirectFBDisplayLayer **interface )
+{
+ IDirectFBDisplayLayer *iface;
+ GetDisplayLayer_Context context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, %d )\n", __FUNCTION__, thiz, id );
+
+ if (!interface)
+ return DFB_INVARG;
+
+ if (dfb_config->primary_only && id != DLID_PRIMARY)
+ return DFB_IDNOTFOUND;
+
+ context.interface = &iface;
+ context.id = id;
+ context.ret = DFB_IDNOTFOUND;
+ context.core = data->core;
+
+ dfb_layers_enumerate( GetDisplayLayer_Callback, &context );
+
+ if (!context.ret)
+ *interface = iface;
+
+ return context.ret;
+}
+
+static DFBResult
+IDirectFB_EnumInputDevices( IDirectFB *thiz,
+ DFBInputDeviceCallback callbackfunc,
+ void *callbackdata )
+{
+ EnumInputDevices_Context context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!callbackfunc)
+ return DFB_INVARG;
+
+ context.callback = callbackfunc;
+ context.callback_ctx = callbackdata;
+
+ dfb_input_enumerate_devices( EnumInputDevices_Callback, &context, DICAPS_ALL );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_GetInputDevice( IDirectFB *thiz,
+ DFBInputDeviceID id,
+ IDirectFBInputDevice **interface )
+{
+ IDirectFBInputDevice *iface;
+ GetInputDevice_Context context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, %d )\n", __FUNCTION__, thiz, id );
+
+ if (!interface)
+ return DFB_INVARG;
+
+ context.interface = &iface;
+ context.id = id;
+ context.ret = DFB_IDNOTFOUND;
+
+ dfb_input_enumerate_devices( GetInputDevice_Callback, &context, DICAPS_ALL );
+
+ if (!context.ret)
+ *interface = iface;
+
+ return context.ret;
+}
+
+static DFBResult
+IDirectFB_CreateEventBuffer( IDirectFB *thiz,
+ IDirectFBEventBuffer **interface)
+{
+ DFBResult ret;
+ IDirectFBEventBuffer *iface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!interface)
+ return DFB_INVARG;
+
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBEventBuffer );
+
+ ret = IDirectFBEventBuffer_Construct( iface, NULL, NULL );
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_CreateInputEventBuffer( IDirectFB *thiz,
+ DFBInputDeviceCapabilities caps,
+ DFBBoolean global,
+ IDirectFBEventBuffer **interface)
+{
+ DFBResult ret;
+ IDirectFBEventBuffer *iface;
+ CreateEventBuffer_Context context;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!interface)
+ return DFB_INVARG;
+
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBEventBuffer );
+
+ ret = IDirectFBEventBuffer_Construct( iface, global ? input_filter_global :
+ input_filter_local, data );
+ if (ret)
+ return ret;
+
+ context.caps = caps;
+ context.interface = &iface;
+
+ dfb_input_enumerate_devices( CreateEventBuffer_Callback, &context, caps );
+
+ *interface = iface;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_CreateImageProvider( IDirectFB *thiz,
+ const char *filename,
+ IDirectFBImageProvider **interface )
+{
+ DFBResult ret;
+ DFBDataBufferDescription desc;
+ IDirectFBDataBuffer *databuffer;
+ IDirectFBImageProvider *iface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, '%s' )\n", __FUNCTION__, thiz, filename );
+
+ /* Check arguments */
+ if (!filename || !interface)
+ return DFB_INVARG;
+
+ /* Create a data buffer. */
+ desc.flags = DBDESC_FILE;
+ desc.file = filename;
+
+ ret = thiz->CreateDataBuffer( thiz, &desc, &databuffer );
+ if (ret)
+ return ret;
+
+ /* Create (probing) the image provider. */
+ ret = IDirectFBImageProvider_CreateFromBuffer( databuffer, data->core, &iface );
+
+ /* We don't need it anymore, image provider has its own reference. */
+ databuffer->Release( databuffer );
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_CreateVideoProvider( IDirectFB *thiz,
+ const char *filename,
+ IDirectFBVideoProvider **interface )
+{
+ DFBResult ret;
+ DFBDataBufferDescription desc;
+ IDirectFBDataBuffer *databuffer;
+ IDirectFBVideoProvider *iface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, '%s' )\n", __FUNCTION__, thiz, filename );
+
+ /* Check arguments */
+ if (!interface || !filename)
+ return DFB_INVARG;
+
+ /* Create a data buffer. */
+ desc.flags = DBDESC_FILE;
+ desc.file = filename;
+
+ ret = thiz->CreateDataBuffer( thiz, &desc, &databuffer );
+ if (ret)
+ return ret;
+
+ /* Create (probing) the video provider. */
+ ret = IDirectFBVideoProvider_CreateFromBuffer( databuffer, data->core, &iface );
+
+ /* We don't need it anymore, video provider has its own reference. */
+ databuffer->Release( databuffer );
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_CreateFont( IDirectFB *thiz,
+ const char *filename,
+ const DFBFontDescription *desc,
+ IDirectFBFont **interface )
+{
+ DFBResult ret;
+ DFBDataBufferDescription dbdesc;
+ IDirectFBDataBuffer *databuffer;
+ IDirectFBFont *font;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, '%s' )\n", __FUNCTION__, thiz, filename );
+
+ /* Check arguments */
+ if (!interface)
+ return DFB_INVARG;
+
+ if (desc) {
+ if ((desc->flags & DFDESC_HEIGHT) && desc->height < 1)
+ return DFB_INVARG;
+
+ if ((desc->flags & DFDESC_WIDTH) && desc->width < 1)
+ return DFB_INVARG;
+ }
+
+ if (filename) {
+ if (!desc)
+ return DFB_INVARG;
+
+ if (access( filename, R_OK ) != 0)
+ return errno2result( errno );
+ }
+
+ /* Create a data buffer. */
+ dbdesc.flags = DBDESC_FILE;
+ dbdesc.file = filename;
+
+ ret = thiz->CreateDataBuffer( thiz, &dbdesc, &databuffer );
+ if (ret)
+ return ret;
+
+ /* Create (probing) the font. */
+ ret = IDirectFBFont_CreateFromBuffer( databuffer, data->core, desc, &font );
+
+ /* We don't need it anymore, font has its own reference. */
+ databuffer->Release( databuffer );
+
+ if (!ret)
+ *interface = font;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_CreateDataBuffer( IDirectFB *thiz,
+ const DFBDataBufferDescription *desc,
+ IDirectFBDataBuffer **interface )
+{
+ DFBResult ret = DFB_INVARG;
+ IDirectFBDataBuffer *iface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!interface)
+ return DFB_INVARG;
+
+ if (!desc) {
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBDataBuffer );
+
+ ret = IDirectFBDataBuffer_Streamed_Construct( iface, data->core );
+ }
+ else if (desc->flags & DBDESC_FILE) {
+ if (!desc->file)
+ return DFB_INVARG;
+
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBDataBuffer );
+
+ ret = IDirectFBDataBuffer_File_Construct( iface, desc->file, data->core );
+ }
+ else if (desc->flags & DBDESC_MEMORY) {
+ if (!desc->memory.data || !desc->memory.length)
+ return DFB_INVARG;
+
+ DIRECT_ALLOCATE_INTERFACE( iface, IDirectFBDataBuffer );
+
+ ret = IDirectFBDataBuffer_Memory_Construct( iface,
+ desc->memory.data,
+ desc->memory.length,
+ data->core );
+ }
+ else
+ return DFB_INVARG;
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_SetClipboardData( IDirectFB *thiz,
+ const char *mime_type,
+ const void *clip_data,
+ unsigned int size,
+ struct timeval *timestamp )
+{
+ DFBClipboardCore *clip_core;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!mime_type || !data || !size)
+ return DFB_INVARG;
+
+ clip_core = DFB_CORE( data->core, CLIPBOARD );
+ if (!clip_core)
+ return DFB_NOCORE;
+
+ return dfb_clipboard_set( clip_core, mime_type, clip_data, size, timestamp );
+}
+
+static DFBResult
+IDirectFB_GetClipboardData( IDirectFB *thiz,
+ char **mime_type,
+ void **clip_data,
+ unsigned int *size )
+{
+ DFBClipboardCore *clip_core;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!mime_type && !data && !size)
+ return DFB_INVARG;
+
+ clip_core = DFB_CORE( data->core, CLIPBOARD );
+ if (!clip_core)
+ return DFB_NOCORE;
+
+ return dfb_clipboard_get( clip_core, mime_type, clip_data, size );
+}
+
+static DFBResult
+IDirectFB_GetClipboardTimeStamp( IDirectFB *thiz,
+ struct timeval *timestamp )
+{
+ DFBClipboardCore *clip_core;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!timestamp)
+ return DFB_INVARG;
+
+ clip_core = DFB_CORE( data->core, CLIPBOARD );
+ if (!clip_core)
+ return DFB_NOCORE;
+
+ return dfb_clipboard_get_timestamp( clip_core, timestamp );
+}
+
+static DFBResult
+IDirectFB_Suspend( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ return dfb_core_suspend( data->core );
+}
+
+static DFBResult
+IDirectFB_Resume( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ return dfb_core_resume( data->core );
+}
+
+static DFBResult
+IDirectFB_WaitIdle( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ dfb_gfxcard_sync();
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_WaitForSync( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ dfb_layer_wait_vsync( data->layer );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFB_GetInterface( IDirectFB *thiz,
+ const char *type,
+ const char *implementation,
+ void *arg,
+ void **interface )
+{
+ DFBResult ret;
+ DirectInterfaceFuncs *funcs = NULL;
+ void *iface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, '%s' )\n", __FUNCTION__, thiz, type );
+
+ if (!type || !interface)
+ return DFB_INVARG;
+
+ ret = DirectGetInterface( &funcs, type, implementation, DirectProbeInterface, arg );
+ if (ret)
+ return ret;
+
+ ret = funcs->Allocate( &iface );
+ if (ret)
+ return ret;
+
+ ret = funcs->Construct( iface, arg, data->core );
+
+ if (!ret)
+ *interface = iface;
+
+ return ret;
+}
+
+static DFBResult
+IDirectFB_RescanInputDevices( IDirectFB *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p )\n", __FUNCTION__, thiz );
+
+ return dfb_input_rescan_devices( data->core );
+}
+
+static void
+LoadBackgroundImage( IDirectFB *dfb,
+ CoreWindowStack *stack,
+ DFBConfigLayer *conf )
+{
+ DFBResult ret;
+ DFBSurfaceDescription desc;
+ IDirectFBImageProvider *provider;
+ IDirectFBSurface *image;
+ IDirectFBSurface_data *image_data;
+
+ ret = dfb->CreateImageProvider( dfb, conf->background.filename, &provider );
+ if (ret) {
+ D_DERROR( ret, "Failed loading background image '%s'!\n", conf->background.filename );
+ return;
+ }
+
+ if (conf->background.mode == DLBM_IMAGE) {
+ desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT;
+ desc.width = conf->config.width;
+ desc.height = conf->config.height;
+ }
+ else {
+ provider->GetSurfaceDescription( provider, &desc );
+ }
+
+ desc.flags |= DSDESC_CAPS | DSDESC_PIXELFORMAT;
+ desc.caps = DSCAPS_SHARED;
+ desc.pixelformat = conf->config.pixelformat;
+
+ ret = dfb->CreateSurface( dfb, &desc, &image );
+ if (ret) {
+ DirectFBError( "Failed creating surface for background image", ret );
+ provider->Release( provider );
+ return;
+ }
+
+ ret = provider->RenderTo( provider, image, NULL );
+ if (ret) {
+ DirectFBError( "Failed loading background image", ret );
+ image->Release( image );
+ provider->Release( provider );
+ return;
+ }
+
+ provider->Release( provider );
+
+ image_data = (IDirectFBSurface_data*) image->priv;
+
+ dfb_windowstack_set_background_image( stack, image_data->surface );
+
+ image->Release( image );
+}
+
+static DFBResult
+InitLayerPalette( IDirectFB_data *data,
+ DFBConfigLayer *conf,
+ CoreSurface *surface,
+ CorePalette **ret_palette )
+{
+ DFBResult ret;
+ CorePalette *palette;
+
+ ret = dfb_palette_create( data->core, 256, &palette );
+ if (ret) {
+ D_DERROR( ret, "InitLayerPalette: Could not create palette!\n" );
+ return ret;
+ }
+
+ direct_memcpy( palette->entries, conf->palette, sizeof(DFBColor) * 256 );
+
+ ret = dfb_surface_set_palette( surface, palette );
+ if (ret) {
+ D_DERROR( ret, "InitLayerPalette: Could not set palette!\n" );
+ dfb_palette_unref( palette );
+ return ret;
+ }
+
+ *ret_palette = palette;
+
+ return DFB_OK;
+}
+
+static DFBResult
+InitLayers( IDirectFB *dfb,
+ IDirectFB_data *data )
+{
+ DFBResult ret;
+ int i;
+ int num = dfb_layer_num();
+
+ for (i=0; i<num; i++) {
+ CoreLayer *layer = dfb_layer_at_translated( i );
+ DFBConfigLayer *conf = &dfb_config->layers[i];
+
+ if (conf->init) {
+ CoreLayerContext *context;
+ CoreWindowStack *stack;
+ CardCapabilities caps;
+ DFBDisplayLayerConfigFlags fail;
+
+ ret = dfb_layer_get_primary_context( layer, false, &context );
+ if (ret) {
+ D_DERROR( ret, "InitLayers: Could not get context of layer %d!\n", i );
+ goto error;
+ }
+
+ stack = dfb_layer_context_windowstack( context );
+ D_ASSERT( stack != NULL );
+
+
+ /* set default desktop configuration */
+ if (!(conf->config.flags & DLCONF_BUFFERMODE)) {
+ dfb_gfxcard_get_capabilities( &caps );
+
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ conf->config.buffermode = (caps.accel & DFXL_BLIT) ? DLBM_BACKVIDEO : DLBM_BACKSYSTEM;
+ }
+
+ if (dfb_layer_context_test_configuration( context, &conf->config, &fail )) {
+ if (fail & (DLCONF_WIDTH | DLCONF_HEIGHT)) {
+ D_ERROR( "DirectFB/DirectFBCreate: "
+ "Setting desktop resolution to %dx%d failed!\n"
+ " -> Using default resolution.\n",
+ conf->config.width, conf->config.height );
+
+ conf->config.flags &= ~(DLCONF_WIDTH | DLCONF_HEIGHT);
+ }
+
+ if (fail & DLCONF_PIXELFORMAT) {
+ D_ERROR( "DirectFB/DirectFBCreate: "
+ "Setting desktop format failed!\n"
+ " -> Using default format.\n" );
+
+ conf->config.flags &= ~DLCONF_PIXELFORMAT;
+ }
+
+ if (fail & DLCONF_BUFFERMODE) {
+ D_ERROR( "DirectFB/DirectFBCreate: "
+ "Setting desktop buffer mode failed!\n"
+ " -> No virtual resolution support or not enough memory?\n"
+ " Falling back to system back buffer.\n" );
+
+ conf->config.buffermode = DLBM_BACKSYSTEM;
+
+ if (dfb_layer_context_test_configuration( context, &conf->config, &fail )) {
+ D_ERROR( "DirectFB/DirectFBCreate: "
+ "Setting system memory desktop back buffer failed!\n"
+ " -> Using front buffer only mode.\n" );
+
+ conf->config.flags &= ~DLCONF_BUFFERMODE;
+ }
+ }
+ }
+
+ if (conf->config.flags) {
+ ret = dfb_layer_context_set_configuration( context, &conf->config );
+ if (ret) {
+ D_DERROR( ret, "InitLayers: Could not set configuration for layer %d!\n", i );
+ dfb_layer_context_unref( context );
+ goto error;
+ }
+ }
+
+ ret = dfb_layer_context_get_configuration( context, &conf->config );
+ D_ASSERT( ret == DFB_OK );
+
+ ret = dfb_layer_context_get_primary_region( context, true, &data->layers[i].region );
+ if (ret) {
+ D_DERROR( ret, "InitLayers: Could not get primary region of layer %d!\n", i );
+ dfb_layer_context_unref( context );
+ goto error;
+ }
+
+ ret = dfb_layer_region_get_surface( data->layers[i].region, &data->layers[i].surface );
+ if (ret) {
+ D_DERROR( ret, "InitLayers: Could not get surface of primary region of layer %d!\n", i );
+ dfb_layer_region_unref( data->layers[i].region );
+ dfb_layer_context_unref( context );
+ goto error;
+ }
+
+ if (conf->palette_set)
+ InitLayerPalette( data, conf, data->layers[i].surface, &data->layers[i].palette );
+
+ if (conf->src_key_index >= 0 && conf->src_key_index < D_ARRAY_SIZE(conf->palette)) {
+ dfb_layer_context_set_src_colorkey( context,
+ conf->palette[conf->src_key_index].r,
+ conf->palette[conf->src_key_index].g,
+ conf->palette[conf->src_key_index].b,
+ conf->src_key_index );
+ }
+ else
+ dfb_layer_context_set_src_colorkey( context, conf->src_key.r, conf->src_key.g, conf->src_key.b, -1 );
+
+ switch (conf->background.mode) {
+ case DLBM_COLOR:
+ dfb_windowstack_set_background_color( stack, &conf->background.color );
+ dfb_windowstack_set_background_color_index( stack, conf->background.color_index );
+ break;
+
+ case DLBM_IMAGE:
+ case DLBM_TILE:
+ LoadBackgroundImage( dfb, stack, conf );
+ break;
+
+ default:
+ break;
+ }
+
+ dfb_windowstack_set_background_mode( stack, conf->background.mode );
+
+ data->layers[i].context = context;
+ }
+
+ data->layers[i].layer = layer;
+ }
+
+ for (i=0; i<num; i++) {
+ if (data->layers[i].context)
+ dfb_layer_activate_context( data->layers[i].layer, data->layers[i].context );
+ }
+
+ return DFB_OK;
+
+error:
+ for (i=num-1; i>=0; i--) {
+ if (data->layers[i].context) {
+ if (data->layers[i].palette)
+ dfb_palette_unref( data->layers[i].palette );
+
+ dfb_surface_unref( data->layers[i].surface );
+ dfb_layer_region_unref( data->layers[i].region );
+ dfb_layer_context_unref( data->layers[i].context );
+
+ data->layers[i].context = NULL;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Constructor
+ *
+ * Fills in function pointers and intializes data structure.
+ */
+DFBResult
+IDirectFB_Construct( IDirectFB *thiz, CoreDFB *core )
+{
+ DFBResult ret;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, %p )\n", __FUNCTION__, thiz, core );
+
+ data->ref = 1;
+ data->core = core;
+ data->level = DFSCL_NORMAL;
+
+ if (dfb_layer_num() < 1) {
+ D_ERROR( "%s: No layers available! Missing driver?\n", __FUNCTION__ );
+ return DFB_UNSUPPORTED;
+ }
+
+ data->layer = dfb_layer_at_translated( DLID_PRIMARY );
+
+ ret = dfb_layer_get_primary_context( data->layer, true, &data->context );
+ if (ret) {
+ D_ERROR( "%s: Could not get default context of primary layer!\n", __FUNCTION__ );
+ DIRECT_DEALLOCATE_INTERFACE(thiz);
+ return ret;
+ }
+
+ data->stack = dfb_layer_context_windowstack( data->context );
+
+ thiz->AddRef = IDirectFB_AddRef;
+ thiz->Release = IDirectFB_Release;
+ thiz->SetCooperativeLevel = IDirectFB_SetCooperativeLevel;
+ thiz->GetDeviceDescription = IDirectFB_GetDeviceDescription;
+ thiz->EnumVideoModes = IDirectFB_EnumVideoModes;
+ thiz->SetVideoMode = IDirectFB_SetVideoMode;
+ thiz->CreateSurface = IDirectFB_CreateSurface;
+ thiz->CreatePalette = IDirectFB_CreatePalette;
+ thiz->EnumScreens = IDirectFB_EnumScreens;
+ thiz->GetScreen = IDirectFB_GetScreen;
+ thiz->EnumDisplayLayers = IDirectFB_EnumDisplayLayers;
+ thiz->GetDisplayLayer = IDirectFB_GetDisplayLayer;
+ thiz->EnumInputDevices = IDirectFB_EnumInputDevices;
+ thiz->GetInputDevice = IDirectFB_GetInputDevice;
+ thiz->CreateEventBuffer = IDirectFB_CreateEventBuffer;
+ thiz->CreateInputEventBuffer = IDirectFB_CreateInputEventBuffer;
+ thiz->CreateImageProvider = IDirectFB_CreateImageProvider;
+ thiz->CreateVideoProvider = IDirectFB_CreateVideoProvider;
+ thiz->CreateFont = IDirectFB_CreateFont;
+ thiz->CreateDataBuffer = IDirectFB_CreateDataBuffer;
+ thiz->SetClipboardData = IDirectFB_SetClipboardData;
+ thiz->GetClipboardData = IDirectFB_GetClipboardData;
+ thiz->GetClipboardTimeStamp = IDirectFB_GetClipboardTimeStamp;
+ thiz->Suspend = IDirectFB_Suspend;
+ thiz->Resume = IDirectFB_Resume;
+ thiz->WaitIdle = IDirectFB_WaitIdle;
+ thiz->WaitForSync = IDirectFB_WaitForSync;
+ thiz->GetInterface = IDirectFB_GetInterface;
+ thiz->RescanInputDevices = IDirectFB_RescanInputDevices;
+
+ if (dfb_core_is_master( core )) {
+ ret = InitLayers( thiz, data );
+ if (ret) {
+ dfb_layer_context_unref( data->context );
+ DIRECT_DEALLOCATE_INTERFACE(thiz);
+ return ret;
+ }
+ }
+
+ return DFB_OK;
+}
+
+DFBResult
+IDirectFB_SetAppFocus( IDirectFB *thiz, DFBBoolean focused )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFB)
+
+ D_DEBUG_AT( IDFB, "%s( %p, %s )\n", __FUNCTION__, thiz, focused ? "true" : "false" );
+
+ data->app_focus = focused;
+
+ return DFB_OK;
+}
+
+/*
+ * internal functions
+ */
+
+static DFBEnumerationResult
+EnumScreens_Callback( CoreScreen *screen, void *ctx )
+{
+ DFBScreenDescription desc;
+ DFBScreenID id;
+ EnumScreens_Context *context = (EnumScreens_Context*) ctx;
+
+ id = dfb_screen_id_translated( screen );
+
+ if (dfb_config->primary_only && id != DSCID_PRIMARY)
+ return DFENUM_OK;
+
+ dfb_screen_get_info( screen, NULL, &desc );
+
+ return context->callback( id, desc, context->callback_ctx );
+}
+
+static DFBEnumerationResult
+GetScreen_Callback( CoreScreen *screen, void *ctx )
+{
+ GetScreen_Context *context = (GetScreen_Context*) ctx;
+
+ if (dfb_screen_id_translated( screen ) != context->id)
+ return DFENUM_OK;
+
+ DIRECT_ALLOCATE_INTERFACE( *context->interface, IDirectFBScreen );
+
+ context->ret = IDirectFBScreen_Construct( *context->interface, screen );
+
+ return DFENUM_CANCEL;
+}
+
+static DFBEnumerationResult
+EnumDisplayLayers_Callback( CoreLayer *layer, void *ctx )
+{
+ DFBDisplayLayerDescription desc;
+ DFBDisplayLayerID id;
+ EnumDisplayLayers_Context *context = (EnumDisplayLayers_Context*) ctx;
+
+ id = dfb_layer_id_translated( layer );
+
+ if (dfb_config->primary_only && id != DLID_PRIMARY)
+ return DFENUM_OK;
+
+ dfb_layer_get_description( layer, &desc );
+
+ return context->callback( id, desc, context->callback_ctx );
+}
+
+static DFBEnumerationResult
+GetDisplayLayer_Callback( CoreLayer *layer, void *ctx )
+{
+ GetDisplayLayer_Context *context = (GetDisplayLayer_Context*) ctx;
+
+ if (dfb_layer_id_translated( layer ) != context->id)
+ return DFENUM_OK;
+
+ DIRECT_ALLOCATE_INTERFACE( *context->interface, IDirectFBDisplayLayer );
+
+ context->ret = IDirectFBDisplayLayer_Construct( *context->interface,
+ layer, context->core );
+
+ return DFENUM_CANCEL;
+}
+
+static DFBEnumerationResult
+EnumInputDevices_Callback( CoreInputDevice *device, void *ctx )
+{
+ DFBInputDeviceDescription desc;
+ EnumInputDevices_Context *context = (EnumInputDevices_Context*) ctx;
+
+ dfb_input_device_description( device, &desc );
+
+ return context->callback( dfb_input_device_id( device ), desc,
+ context->callback_ctx );
+}
+
+static DFBEnumerationResult
+GetInputDevice_Callback( CoreInputDevice *device, void *ctx )
+{
+ GetInputDevice_Context *context = (GetInputDevice_Context*) ctx;
+
+ if (dfb_input_device_id( device ) != context->id)
+ return DFENUM_OK;
+
+ DIRECT_ALLOCATE_INTERFACE( *context->interface, IDirectFBInputDevice );
+
+ context->ret = IDirectFBInputDevice_Construct( *context->interface, device );
+
+ return DFENUM_CANCEL;
+}
+
+static DFBEnumerationResult
+CreateEventBuffer_Callback( CoreInputDevice *device, void *ctx )
+{
+ DFBInputDeviceDescription desc;
+ CreateEventBuffer_Context *context = (CreateEventBuffer_Context*) ctx;
+
+ dfb_input_device_description( device, &desc );
+
+ IDirectFBEventBuffer_AttachInputDevice( *context->interface, device );
+
+ return DFENUM_OK;
+}
+
+static ReactionResult
+focus_listener( const void *msg_data,
+ void *ctx )
+{
+ const DFBWindowEvent *evt = msg_data;
+ IDirectFB_data *data = ctx;
+
+ switch (evt->type) {
+ case DWET_DESTROYED:
+ dfb_window_unref( data->primary.window );
+ data->primary.window = NULL;
+ data->primary.focused = false;
+ return RS_REMOVE;
+
+ case DWET_GOTFOCUS:
+ data->primary.focused = true;
+ break;
+
+ case DWET_LOSTFOCUS:
+ data->primary.focused = false;
+ break;
+
+ default:
+ break;
+ }
+
+ return RS_OK;
+}
+
+static bool
+input_filter_local( DFBEvent *evt,
+ void *ctx )
+{
+ IDirectFB_data *data = (IDirectFB_data*) ctx;
+
+ if (evt->clazz == DFEC_INPUT) {
+ DFBInputEvent *event = &evt->input;
+
+ if (!data->primary.focused && !data->app_focus)
+ return true;
+
+ switch (event->type) {
+ case DIET_BUTTONPRESS:
+ if (data->primary.window)
+ dfb_windowstack_cursor_enable( data->core, data->stack, false );
+ break;
+ case DIET_KEYPRESS:
+ if (data->primary.window)
+ dfb_windowstack_cursor_enable( data->core, data->stack,
+ (event->key_symbol ==
+ DIKS_ESCAPE) ||
+ (event->modifiers &
+ DIMM_META) );
+ break;
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+static bool
+input_filter_global( DFBEvent *evt,
+ void *ctx )
+{
+ IDirectFB_data *data = (IDirectFB_data*) ctx;
+
+ if (evt->clazz == DFEC_INPUT) {
+ DFBInputEvent *event = &evt->input;
+
+ if (!data->primary.focused && !data->app_focus)
+ event->flags |= DIEF_GLOBAL;
+ }
+
+ return false;
+}
+
+static void
+drop_window( IDirectFB_data *data )
+{
+ if (!data->primary.window)
+ return;
+
+ dfb_window_detach( data->primary.window, &data->primary.reaction );
+ dfb_window_unref( data->primary.window );
+
+ data->primary.window = NULL;
+ data->primary.focused = false;
+
+ dfb_windowstack_cursor_enable( data->core, data->stack, true );
+}
+
diff --git a/Source/DirectFB/src/idirectfb.h b/Source/DirectFB/src/idirectfb.h
new file mode 100755
index 0000000..0d5f4d8
--- /dev/null
+++ b/Source/DirectFB/src/idirectfb.h
@@ -0,0 +1,89 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFB_H__
+#define __IDIRECTFB_H__
+
+#include <directfb.h>
+
+#include <fusion/reactor.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+/*
+ * private data struct of IDirectFB
+ */
+typedef struct {
+ int ref; /* reference counter */
+ CoreDFB *core;
+
+ DFBCooperativeLevel level; /* current cooperative level */
+
+ CoreLayer *layer; /* primary display layer */
+ CoreLayerContext *context; /* shared context of primary layer */
+ CoreWindowStack *stack; /* window stack of primary layer */
+
+ struct {
+ int width; /* IDirectFB stores window width */
+ int height; /* and height and the pixel depth */
+ DFBSurfacePixelFormat format; /* from SetVideoMode() parameters. */
+
+ CoreWindow *window; /* implicitly created window */
+ Reaction reaction; /* for the focus listener */
+ bool focused; /* primary's window has the focus */
+
+ CoreLayerContext *context; /* context for fullscreen primary */
+ } primary; /* Used for DFSCL_NORMAL's primary. */
+
+ bool app_focus;
+
+ struct {
+ CoreLayer *layer;
+ CoreLayerContext *context;
+ CoreLayerRegion *region;
+ CoreSurface *surface;
+ CorePalette *palette;
+ } layers[MAX_LAYERS];
+} IDirectFB_data;
+
+/*
+ * IDirectFB constructor/destructor
+ */
+DFBResult IDirectFB_Construct ( IDirectFB *thiz,
+ CoreDFB *core );
+
+void IDirectFB_Destruct ( IDirectFB *thiz );
+
+DFBResult IDirectFB_SetAppFocus( IDirectFB *thiz,
+ DFBBoolean focused );
+
+
+extern IDirectFB *idirectfb_singleton;
+
+#endif
diff --git a/Source/DirectFB/src/input/Makefile.am b/Source/DirectFB/src/input/Makefile.am
new file mode 100755
index 0000000..b80f078
--- /dev/null
+++ b/Source/DirectFB/src/input/Makefile.am
@@ -0,0 +1,22 @@
+## Makefile.am for DirectFB/src/input
+
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+
+internalincludedir = $(INTERNALINCLUDEDIR)/input
+
+internalinclude_HEADERS = \
+ idirectfbinputdevice.h \
+ idirectfbinputbuffer.h
+
+
+noinst_LTLIBRARIES = libdirectfb_input.la
+
+libdirectfb_input_la_SOURCES = \
+ idirectfbinputdevice.c \
+ idirectfbinputbuffer.c
diff --git a/Source/DirectFB/src/input/Makefile.in b/Source/DirectFB/src/input/Makefile.in
new file mode 100755
index 0000000..2873417
--- /dev/null
+++ b/Source/DirectFB/src/input/Makefile.in
@@ -0,0 +1,556 @@
+# 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 = src/input
+DIST_COMMON = $(internalinclude_HEADERS) $(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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libdirectfb_input_la_LIBADD =
+am_libdirectfb_input_la_OBJECTS = idirectfbinputdevice.lo \
+ idirectfbinputbuffer.lo
+libdirectfb_input_la_OBJECTS = $(am_libdirectfb_input_la_OBJECTS)
+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 = $(libdirectfb_input_la_SOURCES)
+DIST_SOURCES = $(libdirectfb_input_la_SOURCES)
+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)$(internalincludedir)"
+internalincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(internalinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+internalincludedir = $(INTERNALINCLUDEDIR)/input
+internalinclude_HEADERS = \
+ idirectfbinputdevice.h \
+ idirectfbinputbuffer.h
+
+noinst_LTLIBRARIES = libdirectfb_input.la
+libdirectfb_input_la_SOURCES = \
+ idirectfbinputdevice.c \
+ idirectfbinputbuffer.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 src/input/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/input/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
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_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
+libdirectfb_input.la: $(libdirectfb_input_la_OBJECTS) $(libdirectfb_input_la_DEPENDENCIES)
+ $(LINK) $(libdirectfb_input_la_OBJECTS) $(libdirectfb_input_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbinputbuffer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbinputdevice.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-internalincludeHEADERS: $(internalinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(internalincludedir)" || $(MKDIR_P) "$(DESTDIR)$(internalincludedir)"
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(internalincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ $(internalincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+uninstall-internalincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(internalincludedir)/$$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) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(internalincludedir)"; 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-libtool clean-noinstLTLIBRARIES \
+ 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-internalincludeHEADERS
+
+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-internalincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES 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-info install-info-am \
+ install-internalincludeHEADERS 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-internalincludeHEADERS
+
+# 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/src/input/idirectfbinputbuffer.c b/Source/DirectFB/src/input/idirectfbinputbuffer.c
new file mode 100755
index 0000000..6a4cf08
--- /dev/null
+++ b/Source/DirectFB/src/input/idirectfbinputbuffer.c
@@ -0,0 +1,1121 @@
+/*
+ (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 <sys/time.h>
+#include <sys/socket.h>
+
+#include <pthread.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/interface.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/thread.h>
+#include <direct/util.h>
+
+#include <fusion/reactor.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/input.h>
+#include <core/windows.h>
+#include <core/windows_internal.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+#include "idirectfbinputbuffer.h"
+
+
+D_DEBUG_DOMAIN( IDFBEvBuf, "IDFBEventBuffer", "IDirectFBEventBuffer Interface" );
+
+
+typedef struct {
+ DirectLink link;
+ DFBEvent evt;
+} EventBufferItem;
+
+typedef struct {
+ DirectLink link;
+
+ CoreInputDevice *device; /* pointer to input core device struct */
+ Reaction reaction;
+
+ DFBInputDeviceDescription desc;
+} AttachedDevice;
+
+typedef struct {
+ DirectLink link;
+
+ CoreWindow *window; /* pointer to core window struct */
+ Reaction reaction;
+} AttachedWindow;
+
+/*
+ * private data struct of IDirectFBInputDevice
+ */
+typedef struct {
+ int ref; /* reference counter */
+
+ EventBufferFilterCallback filter;
+ void *filter_ctx;
+
+ DirectLink *devices; /* attached devices */
+
+ DirectLink *windows; /* attached windows */
+
+ DirectLink *events; /* linked list containing events */
+
+ pthread_mutex_t events_mutex; /* mutex lock for accessing the event queue */
+
+ pthread_cond_t wait_condition; /* condition for idle wait in WaitForEvent() */
+
+ bool pipe; /* file descriptor mode? */
+ int pipe_fds[2]; /* read & write file descriptor */
+
+ DirectThread *pipe_thread; /* thread feeding the pipe */
+
+ DFBEventBufferStats stats;
+ bool stats_enabled;
+} IDirectFBEventBuffer_data;
+
+/*
+ * adds an event to the event queue
+ */
+static void IDirectFBEventBuffer_AddItem( IDirectFBEventBuffer_data *data,
+ EventBufferItem *item );
+
+#ifndef DIRECTFB_PURE_VOODOO
+static ReactionResult IDirectFBEventBuffer_InputReact( const void *msg_data,
+ void *ctx );
+
+static ReactionResult IDirectFBEventBuffer_WindowReact( const void *msg_data,
+ void *ctx );
+#endif
+
+static void *IDirectFBEventBuffer_Feed( DirectThread *thread, void *arg );
+
+static void CollectEventStatistics( DFBEventBufferStats *stats,
+ const DFBEvent *event,
+ int incdec );
+
+
+static void
+IDirectFBEventBuffer_Destruct( IDirectFBEventBuffer *thiz )
+{
+ IDirectFBEventBuffer_data *data = thiz->priv;
+ AttachedDevice *device;
+ AttachedWindow *window;
+ EventBufferItem *item;
+ DirectLink *n;
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p )\n", __FUNCTION__, thiz );
+
+ pthread_mutex_lock( &data->events_mutex );
+
+ if (data->pipe) {
+ data->pipe = false;
+
+ pthread_cond_broadcast( &data->wait_condition );
+
+ pthread_mutex_unlock( &data->events_mutex );
+
+ direct_thread_join( data->pipe_thread );
+ direct_thread_destroy( data->pipe_thread );
+
+ pthread_mutex_lock( &data->events_mutex );
+
+ close( data->pipe_fds[0] );
+ close( data->pipe_fds[1] );
+ }
+
+#ifndef DIRECTFB_PURE_VOODOO
+ direct_list_foreach_safe (device, n, data->devices) {
+ dfb_input_detach( device->device, &device->reaction );
+
+ D_FREE( device );
+ }
+
+ direct_list_foreach_safe (window, n, data->windows) {
+ if (window->window) {
+ dfb_window_detach( window->window, &window->reaction );
+ dfb_window_unref( window->window );
+ }
+
+ D_FREE( window );
+ }
+#endif
+
+ direct_list_foreach_safe (item, n, data->events)
+ D_FREE( item );
+
+ pthread_cond_destroy( &data->wait_condition );
+ pthread_mutex_destroy( &data->events_mutex );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+static DirectResult
+IDirectFBEventBuffer_AddRef( IDirectFBEventBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p )\n", __FUNCTION__, thiz );
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBEventBuffer_Release( IDirectFBEventBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (--data->ref == 0)
+ IDirectFBEventBuffer_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBEventBuffer_Reset( IDirectFBEventBuffer *thiz )
+{
+ EventBufferItem *item;
+ DirectLink *n;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (data->pipe)
+ return DFB_UNSUPPORTED;
+
+ pthread_mutex_lock( &data->events_mutex );
+
+ direct_list_foreach_safe (item, n, data->events)
+ D_FREE( item );
+
+ data->events = NULL;
+
+ pthread_mutex_unlock( &data->events_mutex );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBEventBuffer_WaitForEvent( IDirectFBEventBuffer *thiz )
+{
+ DFBResult ret = DFB_OK;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (data->pipe)
+ return DFB_UNSUPPORTED;
+
+ pthread_mutex_lock( &data->events_mutex );
+
+ if (!data->events)
+ pthread_cond_wait( &data->wait_condition, &data->events_mutex );
+ if (!data->events)
+ ret = DFB_INTERRUPTED;
+
+ pthread_mutex_unlock( &data->events_mutex );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBEventBuffer_WaitForEventWithTimeout( IDirectFBEventBuffer *thiz,
+ unsigned int seconds,
+ unsigned int milli_seconds )
+{
+ struct timespec timeout;
+ DFBResult ret = DFB_OK;
+ int locked = 0;
+ long int nano_seconds = milli_seconds * 1000000;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %u, %u )\n", __FUNCTION__, thiz, seconds, milli_seconds );
+
+ if (data->pipe)
+ return DFB_UNSUPPORTED;
+
+ if (pthread_mutex_trylock( &data->events_mutex ) == 0) {
+ if (data->events) {
+ pthread_mutex_unlock ( &data->events_mutex );
+ return ret;
+ }
+ locked = 1;
+ }
+
+ direct_util_get_monotonic_pthread_timeout(&timeout, seconds, nano_seconds);
+
+ if (!locked)
+ pthread_mutex_lock( &data->events_mutex );
+
+ if (!data->events) {
+ if (pthread_cond_timedwait( &data->wait_condition,
+ &data->events_mutex,
+ &timeout ) == ETIMEDOUT)
+ ret = DFB_TIMEOUT;
+ else if (!data->events)
+ ret = DFB_INTERRUPTED;
+ }
+
+ pthread_mutex_unlock( &data->events_mutex );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBEventBuffer_WakeUp( IDirectFBEventBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (data->pipe)
+ return DFB_UNSUPPORTED;
+
+ pthread_cond_broadcast( &data->wait_condition );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBEventBuffer_GetEvent( IDirectFBEventBuffer *thiz,
+ DFBEvent *event )
+{
+ EventBufferItem *item;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %p )\n", __FUNCTION__, thiz, event );
+
+ if (data->pipe)
+ return DFB_UNSUPPORTED;
+
+ pthread_mutex_lock( &data->events_mutex );
+
+ if (!data->events) {
+ pthread_mutex_unlock( &data->events_mutex );
+ return DFB_BUFFEREMPTY;
+ }
+
+ item = (EventBufferItem*) data->events;
+
+ switch (item->evt.clazz) {
+ case DFEC_INPUT:
+ event->input = item->evt.input;
+ break;
+
+ case DFEC_WINDOW:
+ event->window = item->evt.window;
+ break;
+
+ case DFEC_USER:
+ event->user = item->evt.user;
+ break;
+
+ case DFEC_VIDEOPROVIDER:
+ event->videoprovider = item->evt.videoprovider;
+ break;
+
+ case DFEC_UNIVERSAL:
+ direct_memcpy( event, &item->evt, item->evt.universal.size );
+ break;
+
+ default:
+ D_BUG("unknown event class");
+ }
+
+ if (data->stats_enabled)
+ CollectEventStatistics( &data->stats, &item->evt, -1 );
+
+ direct_list_remove( &data->events, &item->link );
+
+ D_FREE( item );
+
+ pthread_mutex_unlock( &data->events_mutex );
+
+ D_DEBUG_AT( IDFBEvBuf, " -> class %d, type/size %d, data/id %p\n", event->clazz, event->user.type, event->user.data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBEventBuffer_PeekEvent( IDirectFBEventBuffer *thiz,
+ DFBEvent *event )
+{
+ EventBufferItem *item;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %p )\n", __FUNCTION__, thiz, event );
+
+ if (data->pipe)
+ return DFB_UNSUPPORTED;
+
+ pthread_mutex_lock( &data->events_mutex );
+
+ if (!data->events) {
+ pthread_mutex_unlock( &data->events_mutex );
+ return DFB_BUFFEREMPTY;
+ }
+
+ item = (EventBufferItem*) data->events;
+
+ switch (item->evt.clazz) {
+ case DFEC_INPUT:
+ event->input = item->evt.input;
+ break;
+
+ case DFEC_WINDOW:
+ event->window = item->evt.window;
+ break;
+
+ case DFEC_USER:
+ event->user = item->evt.user;
+ break;
+
+ case DFEC_VIDEOPROVIDER:
+ event->videoprovider = item->evt.videoprovider;
+ break;
+
+ case DFEC_UNIVERSAL:
+ direct_memcpy( event, &item->evt, item->evt.universal.size );
+ break;
+
+ default:
+ D_BUG("unknown event class");
+ }
+
+ pthread_mutex_unlock( &data->events_mutex );
+
+ D_DEBUG_AT( IDFBEvBuf, " -> class %d, type/size %d, data/id %p\n", event->clazz, event->user.type, event->user.data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBEventBuffer_HasEvent( IDirectFBEventBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p ) <- events: %p, pipe: %d\n", __FUNCTION__, thiz, data->events, data->pipe );
+
+ if (data->pipe)
+ return DFB_UNSUPPORTED;
+
+ return (data->events ? DFB_OK : DFB_BUFFEREMPTY);
+}
+
+static DFBResult
+IDirectFBEventBuffer_PostEvent( IDirectFBEventBuffer *thiz,
+ const DFBEvent *event )
+{
+ EventBufferItem *item;
+ int size;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %p [class %d, type/size %d, data/id %p] )\n", __FUNCTION__,
+ thiz, event, event->clazz, event->user.type, event->user.data );
+
+ switch (event->clazz) {
+ case DFEC_INPUT:
+ case DFEC_WINDOW:
+ case DFEC_USER:
+ case DFEC_VIDEOPROVIDER:
+ size = sizeof(EventBufferItem);
+ break;
+
+ case DFEC_UNIVERSAL:
+ size = event->universal.size;
+ if (size < sizeof(DFBUniversalEvent))
+ return DFB_INVARG;
+ /* We must not exceed the union to avoid crashes in generic code (reading DFBEvents)
+ * and to support pipe mode where each written block has to have a fixed size. */
+ if (size > sizeof(DFBEvent))
+ return DFB_INVARG;
+ size += sizeof(DirectLink);
+ break;
+
+ default:
+ return DFB_INVARG;
+ }
+
+ item = D_CALLOC( 1, size );
+ if (!item)
+ return D_OOM();
+
+ switch (event->clazz) {
+ case DFEC_INPUT:
+ item->evt.input = event->input;
+ break;
+
+ case DFEC_WINDOW:
+ item->evt.window = event->window;
+ break;
+
+ case DFEC_USER:
+ item->evt.user = event->user;
+ break;
+
+ case DFEC_VIDEOPROVIDER:
+ item->evt.videoprovider = event->videoprovider;
+ break;
+
+ case DFEC_UNIVERSAL:
+ direct_memcpy( &item->evt, event, event->universal.size );
+ break;
+
+ default:
+ D_BUG("unexpected event class");
+ }
+
+ IDirectFBEventBuffer_AddItem( data, item );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBEventBuffer_CreateFileDescriptor( IDirectFBEventBuffer *thiz,
+ int *ret_fd )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p )\n", __FUNCTION__, thiz );
+
+ /* Check arguments. */
+ if (!ret_fd)
+ return DFB_INVARG;
+
+ /* Lock the event queue. */
+ pthread_mutex_lock( &data->events_mutex );
+
+ /* Already in pipe mode? */
+ if (data->pipe) {
+ pthread_mutex_unlock( &data->events_mutex );
+ return DFB_BUSY;
+ }
+
+ /* Create the file descriptor(s). */
+ if (socketpair( PF_LOCAL, SOCK_STREAM, 0, data->pipe_fds )) {
+ D_PERROR( "%s(): socketpair( PF_LOCAL, SOCK_STREAM, 0, fds ) failed!\n", __FUNCTION__ );
+ pthread_mutex_unlock( &data->events_mutex );
+ return errno2result( errno );
+ }
+
+ D_DEBUG_AT( IDFBEvBuf, " -> entering pipe mode\n" );
+
+ /* Enter pipe mode. */
+ data->pipe = true;
+
+ /* Signal any waiting processes. */
+ pthread_cond_broadcast( &data->wait_condition );
+
+ /* Create the feeding thread. */
+ data->pipe_thread = direct_thread_create( DTT_MESSAGING,
+ IDirectFBEventBuffer_Feed, data,
+ "EventBufferFeed" );
+
+ /* Unlock the event queue. */
+ pthread_mutex_unlock( &data->events_mutex );
+
+ /* Return the file descriptor for reading. */
+ *ret_fd = data->pipe_fds[0];
+
+ D_DEBUG_AT( IDFBEvBuf, " -> fd %d/%d\n", data->pipe_fds[0], data->pipe_fds[1] );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBEventBuffer_EnableStatistics( IDirectFBEventBuffer *thiz,
+ DFBBoolean enable )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %sable )\n", __FUNCTION__, thiz, enable ? "en" : "dis" );
+
+ /* Lock the event queue. */
+ pthread_mutex_lock( &data->events_mutex );
+
+ /* Already enabled/disabled? */
+ if (data->stats_enabled == !!enable) {
+ pthread_mutex_unlock( &data->events_mutex );
+ return DFB_OK;
+ }
+
+ if (enable) {
+ EventBufferItem *item;
+
+ /* Collect statistics for events already in the queue. */
+ direct_list_foreach (item, data->events)
+ CollectEventStatistics( &data->stats, &item->evt, 1 );
+ }
+ else {
+ /* Clear statistics. */
+ memset( &data->stats, 0, sizeof(DFBEventBufferStats) );
+ }
+
+ /* Remember state. */
+ data->stats_enabled = !!enable;
+
+ /* Unlock the event queue. */
+ pthread_mutex_unlock( &data->events_mutex );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBEventBuffer_GetStatistics( IDirectFBEventBuffer *thiz,
+ DFBEventBufferStats *ret_stats )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %p )\n", __FUNCTION__, thiz, ret_stats );
+
+ if (!ret_stats)
+ return DFB_INVARG;
+
+ /* Lock the event queue. */
+ pthread_mutex_lock( &data->events_mutex );
+
+ /* Not enabled? */
+ if (!data->stats_enabled) {
+ pthread_mutex_unlock( &data->events_mutex );
+ return DFB_UNSUPPORTED;
+ }
+
+ /* Return current stats. */
+ *ret_stats = data->stats;
+
+ /* Unlock the event queue. */
+ pthread_mutex_unlock( &data->events_mutex );
+
+ return DFB_OK;
+}
+
+DFBResult
+IDirectFBEventBuffer_Construct( IDirectFBEventBuffer *thiz,
+ EventBufferFilterCallback filter,
+ void *filter_ctx )
+{
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBEventBuffer)
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, filter %p, ctx %p )\n", __FUNCTION__, thiz, filter, filter_ctx );
+
+ data->ref = 1;
+ data->filter = filter;
+ data->filter_ctx = filter_ctx;
+
+ direct_util_recursive_pthread_mutex_init( &data->events_mutex );
+ direct_util_monotonic_pthread_cond_init( &data->wait_condition );
+
+ thiz->AddRef = IDirectFBEventBuffer_AddRef;
+ thiz->Release = IDirectFBEventBuffer_Release;
+ thiz->Reset = IDirectFBEventBuffer_Reset;
+ thiz->WaitForEvent = IDirectFBEventBuffer_WaitForEvent;
+ thiz->WaitForEventWithTimeout = IDirectFBEventBuffer_WaitForEventWithTimeout;
+ thiz->GetEvent = IDirectFBEventBuffer_GetEvent;
+ thiz->PeekEvent = IDirectFBEventBuffer_PeekEvent;
+ thiz->HasEvent = IDirectFBEventBuffer_HasEvent;
+ thiz->PostEvent = IDirectFBEventBuffer_PostEvent;
+ thiz->WakeUp = IDirectFBEventBuffer_WakeUp;
+ thiz->CreateFileDescriptor = IDirectFBEventBuffer_CreateFileDescriptor;
+ thiz->EnableStatistics = IDirectFBEventBuffer_EnableStatistics;
+ thiz->GetStatistics = IDirectFBEventBuffer_GetStatistics;
+
+ D_DEBUG_AT( IDFBEvBuf, " -> %p [%p]\n", thiz, thiz->priv );
+
+ return DFB_OK;
+}
+
+/* directfb internals */
+
+#ifndef DIRECTFB_PURE_VOODOO
+DFBResult IDirectFBEventBuffer_AttachInputDevice( IDirectFBEventBuffer *thiz,
+ CoreInputDevice *device )
+{
+ AttachedDevice *attached;
+ DFBInputDeviceDescription desc;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_ASSERT( device != NULL );
+
+ dfb_input_device_description( device, &desc );
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %p [%02u - %s] )\n", __FUNCTION__, thiz, device,
+ dfb_input_device_id(device), desc.name );
+
+ attached = D_CALLOC( 1, sizeof(AttachedDevice) );
+ attached->device = device;
+ attached->desc = desc;
+
+ direct_list_prepend( &data->devices, &attached->link );
+
+ dfb_input_attach( device, IDirectFBEventBuffer_InputReact,
+ data, &attached->reaction );
+
+ return DFB_OK;
+}
+
+DFBResult IDirectFBEventBuffer_DetachInputDevice( IDirectFBEventBuffer *thiz,
+ CoreInputDevice *device )
+{
+ AttachedDevice *attached;
+ DirectLink *link;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_ASSERT( device != NULL );
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %p [%02u] )\n", __FUNCTION__, thiz, device,
+ dfb_input_device_id(device) );
+
+ direct_list_foreach_safe (attached, link, data->devices) {
+ if (attached->device == device) {
+ direct_list_remove( &data->devices, &attached->link );
+
+ dfb_input_detach( attached->device, &attached->reaction );
+
+ D_FREE( attached );
+
+ return DFB_OK;
+ }
+ }
+
+ return DFB_ITEMNOTFOUND;
+}
+
+DFBResult IDirectFBEventBuffer_AttachWindow( IDirectFBEventBuffer *thiz,
+ CoreWindow *window )
+{
+ AttachedWindow *attached;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_ASSERT( window != NULL );
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %p [%02u - %d,%d-%dx%d] )\n", __FUNCTION__, thiz,
+ window, window->id, window->config.bounds.x, window->config.bounds.y,
+ window->config.bounds.w, window->config.bounds.h );
+
+ attached = D_CALLOC( 1, sizeof(AttachedWindow) );
+ attached->window = window;
+
+ window->caps &= ~DWCAPS_NOFOCUS; //no focus patch PR brg36mgr#118432
+
+ dfb_window_ref( window );
+
+ direct_list_prepend( &data->windows, &attached->link );
+
+ dfb_window_attach( window, IDirectFBEventBuffer_WindowReact,
+ data, &attached->reaction );
+
+ return DFB_OK;
+}
+
+DFBResult IDirectFBEventBuffer_DetachWindow( IDirectFBEventBuffer *thiz,
+ CoreWindow *window )
+{
+ AttachedWindow *attached;
+ DirectLink *link;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBEventBuffer)
+
+ D_ASSERT( window != NULL );
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %p [%02u - %d,%d-%dx%d] )\n", __FUNCTION__, thiz,
+ window, window->id, window->config.bounds.x, window->config.bounds.y,
+ window->config.bounds.w, window->config.bounds.h );
+
+ direct_list_foreach_safe (attached, link, data->windows) {
+ if (!attached->window || attached->window == window) {
+ direct_list_remove( &data->windows, &attached->link );
+
+ if (attached->window) {
+ dfb_window_detach( attached->window, &attached->reaction );
+ dfb_window_unref( attached->window );
+ }
+
+ D_FREE( attached );
+ }
+ }
+
+ return DFB_OK;
+}
+#endif
+
+/* file internals */
+
+static void IDirectFBEventBuffer_AddItem( IDirectFBEventBuffer_data *data,
+ EventBufferItem *item )
+{
+ if (data->filter && data->filter( &item->evt, data->filter_ctx )) {
+ D_FREE( item );
+ return;
+ }
+
+ pthread_mutex_lock( &data->events_mutex );
+
+ if (data->stats_enabled)
+ CollectEventStatistics( &data->stats, &item->evt, 1 );
+
+ direct_list_append( &data->events, &item->link );
+
+ pthread_cond_broadcast( &data->wait_condition );
+
+ pthread_mutex_unlock( &data->events_mutex );
+}
+
+#ifndef DIRECTFB_PURE_VOODOO
+static ReactionResult IDirectFBEventBuffer_InputReact( const void *msg_data,
+ void *ctx )
+{
+ const DFBInputEvent *evt = msg_data;
+ IDirectFBEventBuffer_data *data = ctx;
+ EventBufferItem *item;
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %p ) <- type %06x\n", __FUNCTION__, evt, data, evt->type );
+
+ if (dfb_config->discard_repeat_events && (evt->flags & DIEF_REPEAT)) {
+ D_DEBUG_AT( IDFBEvBuf, " -> discarding repeat event!\n" );
+ return DFB_OK;
+ }
+
+ item = D_CALLOC( 1, sizeof(EventBufferItem) );
+
+ item->evt.input = *evt;
+ item->evt.clazz = DFEC_INPUT;
+
+ IDirectFBEventBuffer_AddItem( data, item );
+
+ return RS_OK;
+}
+
+static ReactionResult IDirectFBEventBuffer_WindowReact( const void *msg_data,
+ void *ctx )
+{
+ const DFBWindowEvent *evt = msg_data;
+ IDirectFBEventBuffer_data *data = ctx;
+ EventBufferItem *item;
+
+ D_DEBUG_AT( IDFBEvBuf, "%s( %p, %p ) <- type %06x\n", __FUNCTION__, evt, data, evt->type );
+
+ if (dfb_config->discard_repeat_events && (evt->flags & DWEF_REPEAT)) {
+ D_DEBUG_AT( IDFBEvBuf, " -> discarding repeat event!\n" );
+ return DFB_OK;
+ }
+
+ item = D_CALLOC( 1, sizeof(EventBufferItem) );
+
+ item->evt.window = *evt;
+ item->evt.clazz = DFEC_WINDOW;
+
+ IDirectFBEventBuffer_AddItem( data, item );
+
+ if (evt->type == DWET_DESTROYED) {
+ AttachedWindow *window;
+
+ direct_list_foreach (window, data->windows) {
+ if (!window->window)
+ continue;
+
+ if (dfb_window_id( window->window ) == evt->window_id) {
+ /* FIXME: free memory later, because reactor writes to it
+ after we return RS_REMOVE */
+ dfb_window_unref( window->window );
+ window->window = NULL;
+ }
+ }
+
+ return RS_REMOVE;
+ }
+
+ return RS_OK;
+}
+#endif
+
+static void *
+IDirectFBEventBuffer_Feed( DirectThread *thread, void *arg )
+{
+ IDirectFBEventBuffer_data *data = arg;
+
+ pthread_mutex_lock( &data->events_mutex );
+
+ while (data->pipe) {
+ while (data->events && data->pipe) {
+ int ret;
+ EventBufferItem *item = (EventBufferItem*) data->events;
+
+ if (data->stats_enabled)
+ CollectEventStatistics( &data->stats, &item->evt, -1 );
+
+ direct_list_remove( &data->events, &item->link );
+
+ if (item->evt.clazz == DFEC_UNIVERSAL) {
+ D_WARN( "universal events not supported in pipe mode" );
+ continue;
+ }
+
+ pthread_mutex_unlock( &data->events_mutex );
+
+ D_DEBUG_AT( IDFBEvBuf, "Going to write %zu bytes to file descriptor %d...\n",
+ sizeof(DFBEvent), data->pipe_fds[1] );
+
+ ret = write( data->pipe_fds[1], &item->evt, sizeof(DFBEvent) );
+
+ D_DEBUG_AT( IDFBEvBuf, "...wrote %d bytes to file descriptor %d.\n",
+ ret, data->pipe_fds[1] );
+
+ D_FREE( item );
+
+ pthread_mutex_lock( &data->events_mutex );
+ }
+
+ if (data->pipe)
+ pthread_cond_wait( &data->wait_condition, &data->events_mutex );
+ }
+
+ pthread_mutex_unlock( &data->events_mutex );
+
+ return NULL;
+}
+
+static void
+CollectEventStatistics( DFBEventBufferStats *stats,
+ const DFBEvent *event,
+ int incdec )
+{
+ stats->num_events += incdec;
+
+ switch (event->clazz) {
+ case DFEC_INPUT:
+ stats->DFEC_INPUT += incdec;
+
+ switch (event->input.type) {
+ case DIET_KEYPRESS:
+ stats->DIET_KEYPRESS += incdec;
+ break;
+
+ case DIET_KEYRELEASE:
+ stats->DIET_KEYRELEASE += incdec;
+ break;
+
+ case DIET_BUTTONPRESS:
+ stats->DIET_BUTTONPRESS += incdec;
+ break;
+
+ case DIET_BUTTONRELEASE:
+ stats->DIET_BUTTONRELEASE += incdec;
+ break;
+
+ case DIET_AXISMOTION:
+ stats->DIET_AXISMOTION += incdec;
+ break;
+
+ default:
+ D_BUG( "unknown input event type 0x%08x\n", event->input.type );
+ }
+ break;
+
+ case DFEC_WINDOW:
+ stats->DFEC_WINDOW += incdec;
+
+ switch (event->window.type) {
+ case DWET_POSITION:
+ stats->DWET_POSITION += incdec;
+ break;
+
+ case DWET_SIZE:
+ stats->DWET_SIZE += incdec;
+ break;
+
+ case DWET_CLOSE:
+ stats->DWET_CLOSE += incdec;
+ break;
+
+ case DWET_DESTROYED:
+ stats->DWET_DESTROYED += incdec;
+ break;
+
+ case DWET_GOTFOCUS:
+ stats->DWET_GOTFOCUS += incdec;
+ break;
+
+ case DWET_LOSTFOCUS:
+ stats->DWET_LOSTFOCUS += incdec;
+ break;
+
+ case DWET_KEYDOWN:
+ stats->DWET_KEYDOWN += incdec;
+ break;
+
+ case DWET_KEYUP:
+ stats->DWET_KEYUP += incdec;
+ break;
+
+ case DWET_BUTTONDOWN:
+ stats->DWET_BUTTONDOWN += incdec;
+ break;
+
+ case DWET_BUTTONUP:
+ stats->DWET_BUTTONUP += incdec;
+ break;
+
+ case DWET_MOTION:
+ stats->DWET_MOTION += incdec;
+ break;
+
+ case DWET_ENTER:
+ stats->DWET_ENTER += incdec;
+ break;
+
+ case DWET_LEAVE:
+ stats->DWET_LEAVE += incdec;
+ break;
+
+ case DWET_WHEEL:
+ stats->DWET_WHEEL += incdec;
+ break;
+
+ case DWET_POSITION_SIZE:
+ stats->DWET_POSITION_SIZE += incdec;
+ break;
+
+ default:
+ D_BUG( "unknown window event type 0x%08x\n", event->window.type );
+ }
+ break;
+
+ case DFEC_USER:
+ stats->DFEC_USER += incdec;
+ break;
+
+ case DFEC_VIDEOPROVIDER:
+ stats->DFEC_VIDEOPROVIDER +=incdec;
+
+ switch (event->videoprovider.type) {
+ case DVPET_STARTED:
+ stats->DVPET_STARTED += incdec;
+ break;
+
+ case DVPET_STOPPED:
+ stats->DVPET_STOPPED += incdec;
+ break;
+
+ case DVPET_SPEEDCHANGE:
+ stats->DVPET_SPEEDCHANGE += incdec;
+ break;
+
+ case DVPET_STREAMCHANGE:
+ stats->DVPET_STREAMCHANGE += incdec;
+ break;
+
+ case DVPET_FATALERROR:
+ stats->DVPET_FATALERROR += incdec;
+ break;
+
+ case DVPET_FINISHED:
+ stats->DVPET_FINISHED += incdec;
+ break;
+
+ case DVPET_SURFACECHANGE:
+ stats->DVPET_SURFACECHANGE += incdec;
+ break;
+
+ case DVPET_FRAMEDECODED:
+ stats->DVPET_FRAMEDECODED += incdec;
+ break;
+
+ case DVPET_FRAMEDISPLAYED:
+ stats->DVPET_FRAMEDISPLAYED += incdec;
+ break;
+
+ case DVPET_DATAEXHAUSTED:
+ stats->DVPET_DATAEXHAUSTED += incdec;
+ break;
+
+ case DVPET_VIDEOACTION:
+ stats->DVPET_VIDEOACTION += incdec;
+ break;
+
+ case DVPET_DATALOW:
+ stats->DVPET_DATALOW += incdec;
+ break;
+
+ case DVPET_DATAHIGH:
+ stats->DVPET_DATAHIGH += incdec;
+ break;
+
+ case DVPET_BUFFERTIMELOW:
+ stats->DVPET_BUFFERTIMELOW += incdec;
+ break;
+
+ case DVPET_BUFFERTIMEHIGH:
+ stats->DVPET_BUFFERTIMEHIGH += incdec;
+ break;
+
+ default:
+ D_BUG( "unknown video provider event type 0x%08x\n", event->videoprovider.type );
+ }
+ break;
+
+ case DFEC_UNIVERSAL:
+ stats->DFEC_UNIVERSAL += incdec;
+ break;
+
+ default:
+ D_BUG( "unknown event class 0x%08x\n", event->clazz );
+ }
+}
+
diff --git a/Source/DirectFB/src/input/idirectfbinputbuffer.h b/Source/DirectFB/src/input/idirectfbinputbuffer.h
new file mode 100755
index 0000000..53b263b
--- /dev/null
+++ b/Source/DirectFB/src/input/idirectfbinputbuffer.h
@@ -0,0 +1,56 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBEVENTBUFFER_H__
+#define __IDIRECTFBEVENTBUFFER_H__
+
+#include <fusion/types.h>
+#include <core/input.h>
+
+typedef bool (*EventBufferFilterCallback)( DFBEvent *evt,
+ void *ctx );
+
+/*
+ * initializes event buffer, adds it to input listeners and initializes mutexes
+ */
+DFBResult IDirectFBEventBuffer_Construct( IDirectFBEventBuffer *thiz,
+ EventBufferFilterCallback filter,
+ void *filter_ctx );
+
+DFBResult IDirectFBEventBuffer_AttachInputDevice( IDirectFBEventBuffer *thiz,
+ CoreInputDevice *device );
+DFBResult IDirectFBEventBuffer_DetachInputDevice( IDirectFBEventBuffer *thiz,
+ CoreInputDevice *device );
+
+DFBResult IDirectFBEventBuffer_AttachWindow( IDirectFBEventBuffer *thiz,
+ CoreWindow *window );
+DFBResult IDirectFBEventBuffer_DetachWindow( IDirectFBEventBuffer *thiz,
+ CoreWindow *window );
+
+
+#endif
diff --git a/Source/DirectFB/src/input/idirectfbinputdevice.c b/Source/DirectFB/src/input/idirectfbinputdevice.c
new file mode 100755
index 0000000..f00af8e
--- /dev/null
+++ b/Source/DirectFB/src/input/idirectfbinputdevice.c
@@ -0,0 +1,446 @@
+/*
+ (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 <fusion/reactor.h>
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/input.h>
+
+#include <misc/util.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+
+#include "idirectfbinputdevice.h"
+#include "idirectfbinputbuffer.h"
+
+
+/*
+ * processes an event, updates device state
+ * (funcion is added to the event listeners)
+ */
+static ReactionResult
+IDirectFBInputDevice_React( const void *msg_data,
+ void *ctx );
+
+/*
+ * private data struct of IDirectFBInputDevice
+ */
+typedef struct {
+ int ref; /* reference counter */
+ CoreInputDevice *device; /* pointer to input core
+ device struct*/
+
+ int axis[DIAI_LAST+1]; /* position of all axes */
+ DFBInputDeviceKeyState keystates[DIKI_NUMBER_OF_KEYS];
+ /* state of all keys */
+ DFBInputDeviceModifierMask modifiers; /* bitmask reflecting the
+ state of the modifier
+ keys */
+ DFBInputDeviceLockState locks; /* bitmask reflecting the
+ state of the key locks */
+ DFBInputDeviceButtonMask buttonmask; /* bitmask reflecting the
+ state of the buttons */
+
+ DFBInputDeviceDescription desc; /* device description */
+
+ Reaction reaction;
+} IDirectFBInputDevice_data;
+
+
+
+static void
+IDirectFBInputDevice_Destruct( IDirectFBInputDevice *thiz )
+{
+ IDirectFBInputDevice_data *data = (IDirectFBInputDevice_data*)thiz->priv;
+
+ dfb_input_detach( data->device, &data->reaction );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+static DirectResult
+IDirectFBInputDevice_AddRef( IDirectFBInputDevice *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBInputDevice_Release( IDirectFBInputDevice *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (--data->ref == 0)
+ IDirectFBInputDevice_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_GetID( IDirectFBInputDevice *thiz,
+ DFBInputDeviceID *id )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!id)
+ return DFB_INVARG;
+
+ *id = dfb_input_device_id( data->device );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_CreateEventBuffer( IDirectFBInputDevice *thiz,
+ IDirectFBEventBuffer **buffer )
+{
+ IDirectFBEventBuffer *b;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ DIRECT_ALLOCATE_INTERFACE( b, IDirectFBEventBuffer );
+
+ IDirectFBEventBuffer_Construct( b, NULL, NULL );
+
+ IDirectFBEventBuffer_AttachInputDevice( b, data->device );
+
+ *buffer = b;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_AttachEventBuffer( IDirectFBInputDevice *thiz,
+ IDirectFBEventBuffer *buffer )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ return IDirectFBEventBuffer_AttachInputDevice( buffer, data->device );
+}
+
+static DFBResult
+IDirectFBInputDevice_DetachEventBuffer( IDirectFBInputDevice *thiz,
+ IDirectFBEventBuffer *buffer )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ return IDirectFBEventBuffer_DetachInputDevice( buffer, data->device );
+}
+
+static DFBResult
+IDirectFBInputDevice_GetDescription( IDirectFBInputDevice *thiz,
+ DFBInputDeviceDescription *desc )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!desc)
+ return DFB_INVARG;
+
+ *desc = data->desc;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_GetKeymapEntry( IDirectFBInputDevice *thiz,
+ int keycode,
+ DFBInputDeviceKeymapEntry *entry )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!entry)
+ return DFB_INVARG;
+
+ if (data->desc.min_keycode < 0 || data->desc.max_keycode < 0)
+ return DFB_UNSUPPORTED;
+
+ if (keycode < data->desc.min_keycode ||
+ keycode > data->desc.max_keycode)
+ return DFB_INVARG;
+
+ return dfb_input_device_get_keymap_entry( data->device, keycode, entry );
+}
+
+static DFBResult
+IDirectFBInputDevice_SetKeymapEntry( IDirectFBInputDevice *thiz,
+ int keycode,
+ DFBInputDeviceKeymapEntry *entry )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!entry)
+ return DFB_INVARG;
+
+ if (data->desc.min_keycode < 0 || data->desc.max_keycode < 0)
+ return DFB_UNSUPPORTED;
+
+ if (keycode < data->desc.min_keycode ||
+ keycode > data->desc.max_keycode)
+ return DFB_INVARG;
+
+ return dfb_input_device_set_keymap_entry( data->device, keycode, entry );
+}
+
+static DFBResult
+IDirectFBInputDevice_LoadKeymap ( IDirectFBInputDevice *thiz,
+ char *filename )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!filename)
+ return DFB_INVARG;
+
+ return dfb_input_device_load_keymap( data->device, filename );
+}
+
+static DFBResult
+IDirectFBInputDevice_GetKeyState( IDirectFBInputDevice *thiz,
+ DFBInputDeviceKeyIdentifier key_id,
+ DFBInputDeviceKeyState *state )
+{
+ unsigned int index = key_id - DFB_KEY(IDENTIFIER, 0);
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!state || index >= DIKI_NUMBER_OF_KEYS)
+ return DFB_INVARG;
+
+ *state = data->keystates[index];
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_GetModifiers( IDirectFBInputDevice *thiz,
+ DFBInputDeviceModifierMask *modifiers )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!modifiers)
+ return DFB_INVARG;
+
+ *modifiers = data->modifiers;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_GetLockState( IDirectFBInputDevice *thiz,
+ DFBInputDeviceLockState *locks )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!locks)
+ return DFB_INVARG;
+
+ *locks = data->locks;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_GetButtons( IDirectFBInputDevice *thiz,
+ DFBInputDeviceButtonMask *buttons )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!buttons)
+ return DFB_INVARG;
+
+ *buttons = data->buttonmask;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_GetButtonState( IDirectFBInputDevice *thiz,
+ DFBInputDeviceButtonIdentifier button,
+ DFBInputDeviceButtonState *state)
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!state || (int)button < DIBI_FIRST || button > DIBI_LAST)
+ return DFB_INVARG;
+
+ *state = (data->buttonmask & (1 << button)) ? DIBS_DOWN : DIBS_UP;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_GetAxis( IDirectFBInputDevice *thiz,
+ DFBInputDeviceAxisIdentifier axis,
+ int *pos )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!pos || (int)axis < DIAI_FIRST || axis > DIAI_LAST)
+ return DFB_INVARG;
+
+ *pos = data->axis[axis];
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_GetXY( IDirectFBInputDevice *thiz,
+ int *x,
+ int *y )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!x && !y)
+ return DFB_INVARG;
+
+ if (x)
+ *x = data->axis[DIAI_X];
+
+ if (y)
+ *y = data->axis[DIAI_Y];
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBInputDevice_SetSensitivity( IDirectFBInputDevice *thiz,
+ int sensitivity )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ return dfb_input_device_set_sensitivity( data->device, sensitivity );
+}
+
+static DFBResult
+IDirectFBInputDevice_GetState( IDirectFBInputDevice *thiz,
+ DFBInputDeviceState *state )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBInputDevice)
+
+ if (!state)
+ return DFB_INVARG;
+
+ return dfb_input_device_get_state( data->device, state );
+}
+
+
+DFBResult
+IDirectFBInputDevice_Construct( IDirectFBInputDevice *thiz,
+ CoreInputDevice *device )
+{
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBInputDevice)
+
+ data->ref = 1;
+ data->device = device;
+
+ dfb_input_device_description( device, &data->desc );
+
+ dfb_input_attach( data->device, IDirectFBInputDevice_React,
+ data, &data->reaction );
+
+ thiz->AddRef = IDirectFBInputDevice_AddRef;
+ thiz->Release = IDirectFBInputDevice_Release;
+ thiz->GetID = IDirectFBInputDevice_GetID;
+ thiz->GetDescription = IDirectFBInputDevice_GetDescription;
+ thiz->GetKeymapEntry = IDirectFBInputDevice_GetKeymapEntry;
+ thiz->SetKeymapEntry = IDirectFBInputDevice_SetKeymapEntry;
+ thiz->LoadKeymap = IDirectFBInputDevice_LoadKeymap;
+ thiz->CreateEventBuffer = IDirectFBInputDevice_CreateEventBuffer;
+ thiz->AttachEventBuffer = IDirectFBInputDevice_AttachEventBuffer;
+ thiz->DetachEventBuffer = IDirectFBInputDevice_DetachEventBuffer;
+ thiz->GetKeyState = IDirectFBInputDevice_GetKeyState;
+ thiz->GetModifiers = IDirectFBInputDevice_GetModifiers;
+ thiz->GetLockState = IDirectFBInputDevice_GetLockState;
+ thiz->GetButtons = IDirectFBInputDevice_GetButtons;
+ thiz->GetButtonState = IDirectFBInputDevice_GetButtonState;
+ thiz->GetAxis = IDirectFBInputDevice_GetAxis;
+ thiz->GetXY = IDirectFBInputDevice_GetXY;
+ thiz->SetSensitivity = IDirectFBInputDevice_SetSensitivity;
+ thiz->GetState = IDirectFBInputDevice_GetState;
+
+ return DFB_OK;
+}
+
+
+/* internals */
+
+static ReactionResult
+IDirectFBInputDevice_React( const void *msg_data,
+ void *ctx )
+{
+ const DFBInputEvent *evt = msg_data;
+ IDirectFBInputDevice_data *data = ctx;
+ unsigned int index;
+
+ if (evt->flags & DIEF_MODIFIERS)
+ data->modifiers = evt->modifiers;
+ if (evt->flags & DIEF_LOCKS)
+ data->locks = evt->locks;
+ if (evt->flags & DIEF_BUTTONS)
+ data->buttonmask = evt->buttons;
+
+ switch (evt->type) {
+ case DIET_KEYPRESS:
+ index = evt->key_id - DFB_KEY(IDENTIFIER, 0);
+ if (index < DIKI_NUMBER_OF_KEYS)
+ data->keystates[index] = DIKS_DOWN;
+ break;
+
+ case DIET_KEYRELEASE:
+ index = evt->key_id - DFB_KEY(IDENTIFIER, 0);
+ if (index < DIKI_NUMBER_OF_KEYS)
+ data->keystates[index] = DIKS_UP;
+ break;
+
+ case DIET_AXISMOTION:
+ if (evt->flags & DIEF_AXISREL)
+ data->axis[evt->axis] += evt->axisrel;
+ if (evt->flags & DIEF_AXISABS)
+ data->axis[evt->axis] = evt->axisabs;
+ break;
+
+ default:
+ D_DEBUG( "DirectFB/IDirectFBInputDevice: Unknown event type detected (0x%x), skipping!\n", evt->type );
+ }
+
+ return RS_OK;
+}
+
diff --git a/Source/DirectFB/src/input/idirectfbinputdevice.h b/Source/DirectFB/src/input/idirectfbinputdevice.h
new file mode 100755
index 0000000..65bdc23
--- /dev/null
+++ b/Source/DirectFB/src/input/idirectfbinputdevice.h
@@ -0,0 +1,40 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBINPUTDEVICE_H__
+#define __IDIRECTFBINPUTDEVICE_H__
+
+#include <core/input.h>
+
+/*
+ * initializes input device, adds it to input listeners and initializes mutexes
+ */
+DFBResult IDirectFBInputDevice_Construct( IDirectFBInputDevice *thiz,
+ CoreInputDevice *device );
+
+#endif
diff --git a/Source/DirectFB/src/media/Makefile.am b/Source/DirectFB/src/media/Makefile.am
new file mode 100755
index 0000000..cb2ae12
--- /dev/null
+++ b/Source/DirectFB/src/media/Makefile.am
@@ -0,0 +1,29 @@
+## Makefile.am for DirectFB/src/media
+
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+
+internalincludedir = $(INTERNALINCLUDEDIR)/media
+
+internalinclude_HEADERS = \
+ idirectfbdatabuffer.h \
+ idirectfbfont.h \
+ idirectfbimageprovider.h \
+ idirectfbvideoprovider.h
+
+
+noinst_LTLIBRARIES = libdirectfb_media.la
+
+libdirectfb_media_la_SOURCES = \
+ idirectfbdatabuffer.c \
+ idirectfbdatabuffer_file.c \
+ idirectfbdatabuffer_memory.c \
+ idirectfbdatabuffer_streamed.c \
+ idirectfbfont.c \
+ idirectfbimageprovider.c \
+ idirectfbvideoprovider.c
diff --git a/Source/DirectFB/src/media/Makefile.in b/Source/DirectFB/src/media/Makefile.in
new file mode 100755
index 0000000..930fe11
--- /dev/null
+++ b/Source/DirectFB/src/media/Makefile.in
@@ -0,0 +1,570 @@
+# 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 = src/media
+DIST_COMMON = $(internalinclude_HEADERS) $(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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libdirectfb_media_la_LIBADD =
+am_libdirectfb_media_la_OBJECTS = idirectfbdatabuffer.lo \
+ idirectfbdatabuffer_file.lo idirectfbdatabuffer_memory.lo \
+ idirectfbdatabuffer_streamed.lo idirectfbfont.lo \
+ idirectfbimageprovider.lo idirectfbvideoprovider.lo
+libdirectfb_media_la_OBJECTS = $(am_libdirectfb_media_la_OBJECTS)
+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 = $(libdirectfb_media_la_SOURCES)
+DIST_SOURCES = $(libdirectfb_media_la_SOURCES)
+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)$(internalincludedir)"
+internalincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(internalinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+internalincludedir = $(INTERNALINCLUDEDIR)/media
+internalinclude_HEADERS = \
+ idirectfbdatabuffer.h \
+ idirectfbfont.h \
+ idirectfbimageprovider.h \
+ idirectfbvideoprovider.h
+
+noinst_LTLIBRARIES = libdirectfb_media.la
+libdirectfb_media_la_SOURCES = \
+ idirectfbdatabuffer.c \
+ idirectfbdatabuffer_file.c \
+ idirectfbdatabuffer_memory.c \
+ idirectfbdatabuffer_streamed.c \
+ idirectfbfont.c \
+ idirectfbimageprovider.c \
+ idirectfbvideoprovider.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 src/media/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/media/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
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_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
+libdirectfb_media.la: $(libdirectfb_media_la_OBJECTS) $(libdirectfb_media_la_DEPENDENCIES)
+ $(LINK) $(libdirectfb_media_la_OBJECTS) $(libdirectfb_media_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbdatabuffer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbdatabuffer_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbdatabuffer_memory.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbdatabuffer_streamed.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbfont.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbimageprovider.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbvideoprovider.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-internalincludeHEADERS: $(internalinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(internalincludedir)" || $(MKDIR_P) "$(DESTDIR)$(internalincludedir)"
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(internalincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ $(internalincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+uninstall-internalincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(internalincludedir)/$$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) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(internalincludedir)"; 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-libtool clean-noinstLTLIBRARIES \
+ 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-internalincludeHEADERS
+
+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-internalincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES 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-info install-info-am \
+ install-internalincludeHEADERS 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-internalincludeHEADERS
+
+# 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/src/media/idirectfbdatabuffer.c b/Source/DirectFB/src/media/idirectfbdatabuffer.c
new file mode 100755
index 0000000..68ccc4e
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbdatabuffer.c
@@ -0,0 +1,264 @@
+/*
+ (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 <sys/time.h>
+
+#include <pthread.h>
+
+#include <fusion/reactor.h>
+#include <direct/list.h>
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/input.h>
+#include <core/windows.h>
+
+#include <misc/util.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+
+#include <media/idirectfbdatabuffer.h>
+#include <media/idirectfbfont.h>
+#include <media/idirectfbimageprovider.h>
+#include <media/idirectfbvideoprovider.h>
+
+
+void
+IDirectFBDataBuffer_Destruct( IDirectFBDataBuffer *thiz )
+{
+ IDirectFBDataBuffer_data *data = (IDirectFBDataBuffer_data*) thiz->priv;
+
+ if (data->filename)
+ D_FREE( data->filename );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+static DirectResult
+IDirectFBDataBuffer_AddRef( IDirectFBDataBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer)
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBDataBuffer_Release( IDirectFBDataBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer)
+
+ if (--data->ref == 0)
+ IDirectFBDataBuffer_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Flush( IDirectFBDataBuffer *thiz )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Finish( IDirectFBDataBuffer *thiz )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_SeekTo( IDirectFBDataBuffer *thiz,
+ unsigned int offset )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_GetPosition( IDirectFBDataBuffer *thiz,
+ unsigned int *offset )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_GetLength( IDirectFBDataBuffer *thiz,
+ unsigned int *length )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_WaitForData( IDirectFBDataBuffer *thiz,
+ unsigned int length )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_WaitForDataWithTimeout( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ unsigned int seconds,
+ unsigned int milli_seconds )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_GetData( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ void *data,
+ unsigned int *read )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_PeekData( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ int offset,
+ void *data,
+ unsigned int *read )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_HasData( IDirectFBDataBuffer *thiz )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_PutData( IDirectFBDataBuffer *thiz,
+ const void *data,
+ unsigned int length )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_CreateImageProvider( IDirectFBDataBuffer *thiz,
+ IDirectFBImageProvider **interface )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer)
+
+ /* Check arguments */
+ if (!interface)
+ return DFB_INVARG;
+
+#ifndef DIRECTFB_PURE_VOODOO
+ return IDirectFBImageProvider_CreateFromBuffer( thiz, data->core, interface );
+#else
+ D_BUG( "%s in pure Voodoo build", __FUNCTION__ );
+ return DFB_BUG;
+#endif
+}
+
+static DFBResult
+IDirectFBDataBuffer_CreateVideoProvider( IDirectFBDataBuffer *thiz,
+ IDirectFBVideoProvider **interface )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer)
+
+ /* Check arguments */
+ if (!interface)
+ return DFB_INVARG;
+
+#ifndef DIRECTFB_PURE_VOODOO
+ return IDirectFBVideoProvider_CreateFromBuffer( thiz, data->core, interface );
+#else
+ D_BUG( "%s in pure Voodoo build", __FUNCTION__ );
+ return DFB_BUG;
+#endif
+}
+
+static DFBResult
+IDirectFBDataBuffer_CreateFont( IDirectFBDataBuffer *thiz,
+ const DFBFontDescription *desc,
+ IDirectFBFont **interface )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer)
+
+ /* Check arguments */
+ if (!interface || !desc)
+ return DFB_INVARG;
+
+#ifndef DIRECTFB_PURE_VOODOO
+ return IDirectFBFont_CreateFromBuffer( thiz, data->core, desc, interface );
+#else
+ D_BUG( "%s in pure Voodoo build", __FUNCTION__ );
+ return DFB_BUG;
+#endif
+}
+
+DFBResult
+IDirectFBDataBuffer_Construct( IDirectFBDataBuffer *thiz,
+ const char *filename,
+ CoreDFB *core )
+{
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBDataBuffer)
+
+ data->ref = 1;
+ data->core = core;
+
+ if (filename)
+ data->filename = D_STRDUP( filename );
+
+ thiz->AddRef = IDirectFBDataBuffer_AddRef;
+ thiz->Release = IDirectFBDataBuffer_Release;
+ thiz->Flush = IDirectFBDataBuffer_Flush;
+ thiz->Finish = IDirectFBDataBuffer_Finish;
+ thiz->SeekTo = IDirectFBDataBuffer_SeekTo;
+ thiz->GetPosition = IDirectFBDataBuffer_GetPosition;
+ thiz->GetLength = IDirectFBDataBuffer_GetLength;
+ thiz->WaitForData = IDirectFBDataBuffer_WaitForData;
+ thiz->WaitForDataWithTimeout = IDirectFBDataBuffer_WaitForDataWithTimeout;
+ thiz->GetData = IDirectFBDataBuffer_GetData;
+ thiz->PeekData = IDirectFBDataBuffer_PeekData;
+ thiz->HasData = IDirectFBDataBuffer_HasData;
+ thiz->PutData = IDirectFBDataBuffer_PutData;
+ thiz->CreateImageProvider = IDirectFBDataBuffer_CreateImageProvider;
+ thiz->CreateVideoProvider = IDirectFBDataBuffer_CreateVideoProvider;
+ thiz->CreateFont = IDirectFBDataBuffer_CreateFont;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/media/idirectfbdatabuffer.h b/Source/DirectFB/src/media/idirectfbdatabuffer.h
new file mode 100755
index 0000000..4b19eb0
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbdatabuffer.h
@@ -0,0 +1,104 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBDATABUFFER_H__
+#define __IDIRECTFBDATABUFFER_H__
+
+#include <core/core.h>
+
+/*
+ * private data struct of IDirectFBDataBuffer
+ */
+typedef struct {
+ int ref; /* reference counter */
+ char *filename; /* Only set if databuffer is created from file. */
+
+ CoreDFB *core;
+
+ bool is_memory;
+} IDirectFBDataBuffer_data;
+
+/*
+ * private data struct of IDirectFBDataBuffer_File
+ */
+typedef struct {
+ IDirectFBDataBuffer_data base;
+
+ DirectStream *stream;
+ pthread_mutex_t mutex;
+} IDirectFBDataBuffer_File_data;
+
+/*
+ * private data struct of IDirectFBDataBuffer_Memory
+ */
+typedef struct {
+ IDirectFBDataBuffer_data base;
+
+ const void *buffer;
+ unsigned int length;
+
+ unsigned int pos;
+} IDirectFBDataBuffer_Memory_data;
+
+/*
+ * base constructor
+ *
+ * If the databuffer is created for a file, the filename can be provided
+ * for fallbacks.
+ */
+DFBResult IDirectFBDataBuffer_Construct( IDirectFBDataBuffer *thiz,
+ const char *filename,
+ CoreDFB *core );
+
+/*
+ * base destructor
+ */
+void IDirectFBDataBuffer_Destruct( IDirectFBDataBuffer *thiz );
+
+/*
+ * generic streamed data buffer
+ */
+DFBResult IDirectFBDataBuffer_Streamed_Construct( IDirectFBDataBuffer *thiz,
+ CoreDFB *core );
+
+/*
+ * file based static data buffer
+ */
+DFBResult IDirectFBDataBuffer_File_Construct( IDirectFBDataBuffer *thiz,
+ const char *filename,
+ CoreDFB *core );
+
+/*
+ * memory based static data buffer
+ */
+DFBResult IDirectFBDataBuffer_Memory_Construct( IDirectFBDataBuffer *thiz,
+ const void *data,
+ unsigned int length,
+ CoreDFB *core );
+
+#endif
diff --git a/Source/DirectFB/src/media/idirectfbdatabuffer_file.c b/Source/DirectFB/src/media/idirectfbdatabuffer_file.c
new file mode 100755
index 0000000..245ce02
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbdatabuffer_file.c
@@ -0,0 +1,297 @@
+/*
+ (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 <time.h>
+#include <string.h>
+#include <errno.h>
+
+#include <pthread.h>
+
+#include <fusion/reactor.h>
+#include <direct/list.h>
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/input.h>
+#include <core/windows.h>
+
+#include <misc/util.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/stream.h>
+#include <direct/util.h>
+
+#include <media/idirectfbdatabuffer.h>
+
+
+
+static void
+IDirectFBDataBuffer_File_Destruct( IDirectFBDataBuffer *thiz )
+{
+ IDirectFBDataBuffer_File_data *data =
+ (IDirectFBDataBuffer_File_data*) thiz->priv;
+
+ direct_stream_destroy( data->stream );
+
+ pthread_mutex_destroy( &data->mutex );
+
+ IDirectFBDataBuffer_Destruct( thiz );
+}
+
+static DirectResult
+IDirectFBDataBuffer_File_Release( IDirectFBDataBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer)
+
+ if (--data->ref == 0)
+ IDirectFBDataBuffer_File_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_Flush( IDirectFBDataBuffer *thiz )
+{
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_Finish( IDirectFBDataBuffer *thiz )
+{
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_SeekTo( IDirectFBDataBuffer *thiz,
+ unsigned int offset )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_File)
+
+ if (!direct_stream_seekable( data->stream ))
+ return DFB_UNSUPPORTED;
+
+ pthread_mutex_lock( &data->mutex );
+ ret = direct_stream_seek( data->stream, offset );
+ pthread_mutex_unlock( &data->mutex );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_GetPosition( IDirectFBDataBuffer *thiz,
+ unsigned int *offset )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_File)
+
+ if (!offset)
+ return DFB_INVARG;
+
+ *offset = direct_stream_offset( data->stream );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_GetLength( IDirectFBDataBuffer *thiz,
+ unsigned int *length )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_File)
+
+ if (!length)
+ return DFB_INVARG;
+
+ *length = direct_stream_length( data->stream );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_WaitForData( IDirectFBDataBuffer *thiz,
+ unsigned int length )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_File)
+
+ pthread_mutex_lock( &data->mutex );
+ ret = direct_stream_wait( data->stream, length, NULL );
+ pthread_mutex_unlock( &data->mutex );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_WaitForDataWithTimeout( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ unsigned int seconds,
+ unsigned int milli_seconds )
+{
+ DFBResult ret;
+ struct timeval tv;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_File)
+
+ tv.tv_sec = seconds;
+ tv.tv_usec = milli_seconds*1000;
+
+ while (pthread_mutex_trylock( &data->mutex )) {
+ struct timespec t, r;
+
+ if (errno != EBUSY)
+ return errno2result( errno );
+
+ t.tv_sec = 0;
+ t.tv_nsec = 10000;
+ nanosleep( &t, &r );
+
+ tv.tv_usec -= (t.tv_nsec - r.tv_nsec + 500) / 1000;
+ if (tv.tv_usec < 0) {
+ if (tv.tv_sec < 1)
+ return DFB_TIMEOUT;
+
+ tv.tv_sec--;
+ tv.tv_usec += 999999;
+ }
+ }
+
+ ret = direct_stream_wait( data->stream, length, &tv );
+
+ pthread_mutex_unlock( &data->mutex );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_GetData( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ void *data_buffer,
+ unsigned int *read_out )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_File)
+
+ if (!data_buffer || !length)
+ return DFB_INVARG;
+
+ pthread_mutex_lock( &data->mutex );
+ ret = direct_stream_read( data->stream, length, data_buffer, read_out );
+ pthread_mutex_unlock( &data->mutex );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_PeekData( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ int offset,
+ void *data_buffer,
+ unsigned int *read_out )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_File)
+
+ if (!data_buffer || !length)
+ return DFB_INVARG;
+
+ pthread_mutex_lock( &data->mutex );
+ ret = direct_stream_peek( data->stream, length,
+ offset, data_buffer, read_out );
+ pthread_mutex_unlock( &data->mutex );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_HasData( IDirectFBDataBuffer *thiz )
+{
+ struct timeval tv = {0,0};
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_File)
+
+ return direct_stream_wait( data->stream, 1, &tv );
+}
+
+static DFBResult
+IDirectFBDataBuffer_File_PutData( IDirectFBDataBuffer *thiz,
+ const void *data_buffer,
+ unsigned int length )
+{
+ return DFB_UNSUPPORTED;
+}
+
+DFBResult
+IDirectFBDataBuffer_File_Construct( IDirectFBDataBuffer *thiz,
+ const char *filename,
+ CoreDFB *core )
+{
+ DFBResult ret;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBDataBuffer_File)
+
+ ret = IDirectFBDataBuffer_Construct( thiz, filename, core );
+ if (ret)
+ return ret;
+
+ ret = direct_stream_create( filename, &data->stream );
+ if (ret) {
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+ return ret;
+ }
+
+ direct_util_recursive_pthread_mutex_init( &data->mutex );
+
+ thiz->Release = IDirectFBDataBuffer_File_Release;
+ thiz->Flush = IDirectFBDataBuffer_File_Flush;
+ thiz->Finish = IDirectFBDataBuffer_File_Finish;
+ thiz->SeekTo = IDirectFBDataBuffer_File_SeekTo;
+ thiz->GetPosition = IDirectFBDataBuffer_File_GetPosition;
+ thiz->GetLength = IDirectFBDataBuffer_File_GetLength;
+ thiz->WaitForData = IDirectFBDataBuffer_File_WaitForData;
+ thiz->WaitForDataWithTimeout = IDirectFBDataBuffer_File_WaitForDataWithTimeout;
+ thiz->GetData = IDirectFBDataBuffer_File_GetData;
+ thiz->PeekData = IDirectFBDataBuffer_File_PeekData;
+ thiz->HasData = IDirectFBDataBuffer_File_HasData;
+ thiz->PutData = IDirectFBDataBuffer_File_PutData;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/media/idirectfbdatabuffer_memory.c b/Source/DirectFB/src/media/idirectfbdatabuffer_memory.c
new file mode 100755
index 0000000..233e4b4
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbdatabuffer_memory.c
@@ -0,0 +1,266 @@
+/*
+ (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 <sys/time.h>
+
+#include <pthread.h>
+
+#include <fusion/reactor.h>
+#include <direct/list.h>
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/input.h>
+#include <core/windows.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/util.h>
+
+#include <media/idirectfbdatabuffer.h>
+
+
+static void
+IDirectFBDataBuffer_Memory_Destruct( IDirectFBDataBuffer *thiz )
+{
+ IDirectFBDataBuffer_Destruct( thiz );
+}
+
+static DirectResult
+IDirectFBDataBuffer_Memory_Release( IDirectFBDataBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer)
+
+ if (--data->ref == 0)
+ IDirectFBDataBuffer_Memory_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_Flush( IDirectFBDataBuffer *thiz )
+{
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_Finish( IDirectFBDataBuffer *thiz )
+{
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_SeekTo( IDirectFBDataBuffer *thiz,
+ unsigned int offset )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Memory)
+
+ if (offset >= data->length)
+ return DFB_INVARG;
+
+ data->pos = offset;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_GetPosition( IDirectFBDataBuffer *thiz,
+ unsigned int *offset )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Memory)
+
+ if (!offset)
+ return DFB_INVARG;
+
+ *offset = data->pos;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_GetLength( IDirectFBDataBuffer *thiz,
+ unsigned int *length )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Memory)
+
+ if (!length)
+ return DFB_INVARG;
+
+ *length = data->length;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_WaitForData( IDirectFBDataBuffer *thiz,
+ unsigned int length )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Memory)
+
+ if (data->pos + length > data->length)
+ return DFB_EOF;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_WaitForDataWithTimeout( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ unsigned int seconds,
+ unsigned int milli_seconds )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Memory)
+
+ if (data->pos + length > data->length)
+ return DFB_EOF;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_GetData( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ void *data_buffer,
+ unsigned int *read_out )
+{
+ unsigned int size;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Memory)
+
+ if (!data_buffer || !length)
+ return DFB_INVARG;
+
+ if (data->pos >= data->length)
+ return DFB_EOF;
+
+ size = MIN( length, data->length - data->pos );
+
+ direct_memcpy( data_buffer, data->buffer + data->pos, size );
+
+ data->pos += size;
+
+ if (read_out)
+ *read_out = size;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_PeekData( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ int offset,
+ void *data_buffer,
+ unsigned int *read_out )
+{
+ unsigned int size;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Memory)
+
+ if (!data_buffer || !length)
+ return DFB_INVARG;
+
+ if (data->pos + offset >= data->length)
+ return DFB_EOF;
+
+ size = MIN( length, data->length - data->pos - offset );
+
+ direct_memcpy( data_buffer, data->buffer + data->pos + offset, size );
+
+ if (read_out)
+ *read_out = size;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_HasData( IDirectFBDataBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Memory)
+
+ if (data->pos >= data->length)
+ return DFB_EOF;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Memory_PutData( IDirectFBDataBuffer *thiz,
+ const void *data_buffer,
+ unsigned int length )
+{
+ return DFB_UNSUPPORTED;
+}
+
+DFBResult
+IDirectFBDataBuffer_Memory_Construct( IDirectFBDataBuffer *thiz,
+ const void *data_buffer,
+ unsigned int length,
+ CoreDFB *core )
+{
+ DFBResult ret;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBDataBuffer_Memory)
+
+ ret = IDirectFBDataBuffer_Construct( thiz, NULL, core );
+ if (ret)
+ return ret;
+
+ data->buffer = data_buffer;
+ data->length = length;
+
+ data->base.is_memory = true;
+
+ thiz->Release = IDirectFBDataBuffer_Memory_Release;
+ thiz->Flush = IDirectFBDataBuffer_Memory_Flush;
+ thiz->Finish = IDirectFBDataBuffer_Memory_Finish;
+ thiz->SeekTo = IDirectFBDataBuffer_Memory_SeekTo;
+ thiz->GetPosition = IDirectFBDataBuffer_Memory_GetPosition;
+ thiz->GetLength = IDirectFBDataBuffer_Memory_GetLength;
+ thiz->WaitForData = IDirectFBDataBuffer_Memory_WaitForData;
+ thiz->WaitForDataWithTimeout = IDirectFBDataBuffer_Memory_WaitForDataWithTimeout;
+ thiz->GetData = IDirectFBDataBuffer_Memory_GetData;
+ thiz->PeekData = IDirectFBDataBuffer_Memory_PeekData;
+ thiz->HasData = IDirectFBDataBuffer_Memory_HasData;
+ thiz->PutData = IDirectFBDataBuffer_Memory_PutData;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/media/idirectfbdatabuffer_streamed.c b/Source/DirectFB/src/media/idirectfbdatabuffer_streamed.c
new file mode 100755
index 0000000..5ce1168
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbdatabuffer_streamed.c
@@ -0,0 +1,529 @@
+/*
+ (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 <sys/time.h>
+
+#include <pthread.h>
+
+#include <fusion/reactor.h>
+#include <direct/list.h>
+#include <fusion/lock.h>
+
+#include <directfb.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/util.h>
+
+#include <media/idirectfbdatabuffer.h>
+
+typedef struct {
+ DirectLink link;
+
+ void *data; /* actual data hold */
+ unsigned int length; /* length of chunk */
+
+ unsigned int done; /* number of bytes already consumed */
+} DataChunk;
+
+static DataChunk *
+create_chunk( const void *data, int length );
+
+static void
+destroy_chunk( DataChunk *chunk );
+
+/*
+ * private data struct of IDirectFBDataBuffer_Streamed
+ */
+typedef struct {
+ IDirectFBDataBuffer_data base;
+
+ DirectLink *chunks; /* data chunks */
+
+ unsigned int length; /* total length of all chunks */
+
+ bool finished; /* whether Finish() has been called */
+
+ pthread_mutex_t chunks_mutex; /* mutex lock for accessing
+ the chunk list */
+
+ pthread_cond_t wait_condition; /* condition used for idle
+ wait in WaitForEvent() */
+} IDirectFBDataBuffer_Streamed_data;
+
+static void
+DestroyAllChunks( IDirectFBDataBuffer_Streamed_data *data );
+
+static void
+ReadChunkData( IDirectFBDataBuffer_Streamed_data *data,
+ void *buffer,
+ unsigned int offset,
+ unsigned int length,
+ bool flush );
+
+
+static void
+IDirectFBDataBuffer_Streamed_Destruct( IDirectFBDataBuffer *thiz )
+{
+ IDirectFBDataBuffer_Streamed_data *data =
+ (IDirectFBDataBuffer_Streamed_data*) thiz->priv;
+
+ pthread_cond_destroy( &data->wait_condition );
+ pthread_mutex_destroy( &data->chunks_mutex );
+
+ IDirectFBDataBuffer_Destruct( thiz );
+}
+
+static DirectResult
+IDirectFBDataBuffer_Streamed_Release( IDirectFBDataBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer)
+
+ if (--data->ref == 0)
+ IDirectFBDataBuffer_Streamed_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_Flush( IDirectFBDataBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Streamed)
+
+ pthread_mutex_lock( &data->chunks_mutex );
+
+ DestroyAllChunks( data );
+
+ pthread_mutex_unlock( &data->chunks_mutex );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_Finish( IDirectFBDataBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Streamed)
+
+ if (!data->finished) {
+ data->finished = true;
+
+ pthread_mutex_lock( &data->chunks_mutex );
+ pthread_cond_broadcast( &data->wait_condition );
+ pthread_mutex_unlock( &data->chunks_mutex );
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_SeekTo( IDirectFBDataBuffer *thiz,
+ unsigned int offset )
+{
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_GetPosition( IDirectFBDataBuffer *thiz,
+ unsigned int *offset )
+{
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_GetLength( IDirectFBDataBuffer *thiz,
+ unsigned int *length )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Streamed)
+
+ /* Check arguments. */
+ if (!length)
+ return DFB_INVARG;
+
+ /* Return total length of all chunks. */
+ *length = data->length;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_WaitForData( IDirectFBDataBuffer *thiz,
+ unsigned int length )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Streamed)
+
+ if (data->finished && !data->chunks)
+ return DFB_EOF;
+
+ pthread_mutex_lock( &data->chunks_mutex );
+
+ while (data->length < length && !data->finished)
+ pthread_cond_wait( &data->wait_condition, &data->chunks_mutex );
+
+ pthread_mutex_unlock( &data->chunks_mutex );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_WaitForDataWithTimeout( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ unsigned int seconds,
+ unsigned int milli_seconds )
+{
+ struct timespec timeout;
+ DFBResult ret = DFB_OK;
+ bool locked = false;
+ long int nano_seconds = milli_seconds * 1000000;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Streamed)
+
+ if (data->finished && !data->chunks)
+ return DFB_EOF;
+
+ if (pthread_mutex_trylock( &data->chunks_mutex ) == 0) {
+ if (data->length >= length) {
+ pthread_mutex_unlock( &data->chunks_mutex );
+
+ return DFB_OK;
+ }
+
+ locked = true;
+ }
+
+ direct_util_get_monotonic_pthread_timeout(&timeout, seconds, nano_seconds);
+
+ if (!locked)
+ pthread_mutex_lock( &data->chunks_mutex );
+
+ while (data->length < length && !data->finished) {
+ if (pthread_cond_timedwait( &data->wait_condition,
+ &data->chunks_mutex,
+ &timeout ) == ETIMEDOUT)
+ {
+ ret = DFB_TIMEOUT;
+ break;
+ }
+ }
+
+ pthread_mutex_unlock( &data->chunks_mutex );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_GetData( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ void *data_buffer,
+ unsigned int *read_out )
+{
+ unsigned int len;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Streamed)
+
+ if (!data_buffer || !length)
+ return DFB_INVARG;
+
+ pthread_mutex_lock( &data->chunks_mutex );
+
+ if (!data->chunks) {
+ pthread_mutex_unlock( &data->chunks_mutex );
+ return data->finished ? DFB_EOF : DFB_BUFFEREMPTY;
+ }
+
+ /* Calculate maximum number of bytes to be read. */
+ len = MIN( length, data->length );
+
+ /* Read data from chunks (destructive). */
+ ReadChunkData( data, data_buffer, 0, len, true );
+
+ /* Decrease total number of bytes. */
+ data->length -= len;
+
+ /* Return number of bytes read. */
+ if (read_out)
+ *read_out = len;
+
+ pthread_mutex_unlock( &data->chunks_mutex );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_PeekData( IDirectFBDataBuffer *thiz,
+ unsigned int length,
+ int offset,
+ void *data_buffer,
+ unsigned int *read_out )
+{
+ unsigned int len;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Streamed)
+
+ if (!data_buffer || !length || offset < 0)
+ return DFB_INVARG;
+
+ pthread_mutex_lock( &data->chunks_mutex );
+
+ if (!data->chunks || (unsigned int) offset >= data->length) {
+ pthread_mutex_unlock( &data->chunks_mutex );
+ return data->finished ? DFB_EOF : DFB_BUFFEREMPTY;
+ }
+
+ /* Calculate maximum number of bytes to be read. */
+ len = MIN( length, data->length - offset );
+
+ /* Read data from chunks (non-destructive). */
+ ReadChunkData( data, data_buffer, offset, len, false );
+
+ /* Return number of bytes read. */
+ if (read_out)
+ *read_out = len;
+
+ pthread_mutex_unlock( &data->chunks_mutex );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_HasData( IDirectFBDataBuffer *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Streamed)
+
+ /* If there's no chunk there's no data. */
+ if (!data->chunks)
+ return data->finished ? DFB_EOF : DFB_BUFFEREMPTY;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBDataBuffer_Streamed_PutData( IDirectFBDataBuffer *thiz,
+ const void *data_buffer,
+ unsigned int length )
+{
+ DataChunk *chunk;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBDataBuffer_Streamed)
+
+ /* Check arguments. */
+ if (!data_buffer || !length)
+ return DFB_INVARG;
+
+ /* Fail if Finish() has been called. */
+ if (data->finished)
+ return DFB_UNSUPPORTED;
+
+ /* Create a chunk containing a copy of the provided data. */
+ chunk = create_chunk( data_buffer, length );
+ if (!chunk)
+ return DFB_NOSYSTEMMEMORY;
+
+ pthread_mutex_lock( &data->chunks_mutex );
+
+ /* Append new chunk. */
+ direct_list_append( &data->chunks, &chunk->link );
+
+ /* Increase total length. */
+ data->length += length;
+
+ pthread_cond_broadcast( &data->wait_condition );
+
+ pthread_mutex_unlock( &data->chunks_mutex );
+
+ return DFB_OK;
+}
+
+DFBResult
+IDirectFBDataBuffer_Streamed_Construct( IDirectFBDataBuffer *thiz,
+ CoreDFB *core )
+{
+ DFBResult ret;
+
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBDataBuffer_Streamed)
+
+ ret = IDirectFBDataBuffer_Construct( thiz, NULL, core );
+ if (ret)
+ return ret;
+
+ direct_util_recursive_pthread_mutex_init( &data->chunks_mutex );
+ direct_util_monotonic_pthread_cond_init( &data->wait_condition );
+
+ thiz->Release = IDirectFBDataBuffer_Streamed_Release;
+ thiz->Flush = IDirectFBDataBuffer_Streamed_Flush;
+ thiz->Finish = IDirectFBDataBuffer_Streamed_Finish;
+ thiz->SeekTo = IDirectFBDataBuffer_Streamed_SeekTo;
+ thiz->GetPosition = IDirectFBDataBuffer_Streamed_GetPosition;
+ thiz->GetLength = IDirectFBDataBuffer_Streamed_GetLength;
+ thiz->WaitForData = IDirectFBDataBuffer_Streamed_WaitForData;
+ thiz->WaitForDataWithTimeout = IDirectFBDataBuffer_Streamed_WaitForDataWithTimeout;
+ thiz->GetData = IDirectFBDataBuffer_Streamed_GetData;
+ thiz->PeekData = IDirectFBDataBuffer_Streamed_PeekData;
+ thiz->HasData = IDirectFBDataBuffer_Streamed_HasData;
+ thiz->PutData = IDirectFBDataBuffer_Streamed_PutData;
+
+ return DFB_OK;
+}
+
+/******************************************************************************/
+
+static void
+DestroyAllChunks( IDirectFBDataBuffer_Streamed_data *data )
+{
+ DirectLink *l, *n;
+
+ D_ASSERT( data != NULL );
+
+ /* Loop through list. */
+ direct_list_foreach_safe (l, n, data->chunks) {
+ /* Deallocate chunk. */
+ destroy_chunk( (DataChunk*) l );
+ }
+
+ /* Clear lists. */
+ data->chunks = NULL;
+}
+
+static void
+ReadChunkData( IDirectFBDataBuffer_Streamed_data *data,
+ void *buffer,
+ unsigned int offset,
+ unsigned int length,
+ bool flush )
+{
+ DirectLink *l, *n;
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( buffer != NULL );
+
+ /* Loop through links. */
+ direct_list_foreach_safe (l, n, data->chunks) {
+ unsigned int len;
+ unsigned int off = 0;
+ DataChunk *chunk = (DataChunk*) l;
+
+ /* Is there data to be skipped? */
+ if (offset) {
+ /* Calculate number of bytes to be skipped from this chunk. */
+ off = MIN( offset, chunk->length - chunk->done );
+
+ /* Decrease number of bytes to skipped. */
+ offset -= off;
+ }
+
+ /* Calculate number of bytes to be read from this chunk. */
+ len = MIN( length, chunk->length - chunk->done - off );
+
+ /* Can we read from this chunk? */
+ if (len) {
+ /* Copy as many bytes as possible. */
+ direct_memcpy( buffer, chunk->data + chunk->done + off, len );
+
+ /* Increase write pointer. */
+ buffer += len;
+
+ /* Decrease number of bytes to read. */
+ length -= len;
+ }
+
+ /* Destructive read? */
+ if (flush) {
+ /* Increase number of consumed bytes. */
+ chunk->done += len + off;
+
+ /* Completely consumed? */
+ if (chunk->done == chunk->length) {
+ /* Remove the chunk from the list. */
+ direct_list_remove( &data->chunks, l );
+
+ /* Deallocate chunk. */
+ destroy_chunk( chunk );
+ }
+ }
+ }
+
+ D_ASSERT( length == 0 );
+ D_ASSERT( offset == 0 );
+}
+
+/******************************************************************************/
+
+static DataChunk *
+create_chunk( const void *data, int length )
+{
+ DataChunk *chunk;
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( length > 0 );
+
+ /* Allocate chunk information. */
+ chunk = D_CALLOC( 1, sizeof(DataChunk) );
+ if (!chunk)
+ return NULL;
+
+ /* Allocate chunk data. */
+ chunk->data = D_MALLOC( length );
+ if (!chunk->data) {
+ D_FREE( chunk );
+ return NULL;
+ }
+
+ /* Fill chunk data. */
+ direct_memcpy( chunk->data, data, length );
+
+ /* Remember chunk length. */
+ chunk->length = length;
+
+ return chunk;
+}
+
+static void
+destroy_chunk( DataChunk *chunk )
+{
+ D_ASSERT( chunk != NULL );
+ D_ASSERT( chunk->data != NULL );
+
+ /* Deallocate chunk data. */
+ D_FREE( chunk->data );
+
+ /* Deallocate chunk information. */
+ D_FREE( chunk );
+}
+
diff --git a/Source/DirectFB/src/media/idirectfbfont.c b/Source/DirectFB/src/media/idirectfbfont.c
new file mode 100755
index 0000000..4ce0946
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbfont.c
@@ -0,0 +1,965 @@
+/*
+ (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 <math.h>
+
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include "directfb.h"
+
+#include "core/coretypes.h"
+
+#include "core/fonts.h"
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+#include <direct/tree.h>
+#include <direct/utf8.h>
+
+#include <media/idirectfbfont.h>
+#include <media/idirectfbdatabuffer.h>
+
+#include "misc/util.h"
+
+
+D_DEBUG_DOMAIN( Font, "IDirectFBFont", "DirectFB Font Interface" );
+
+/**********************************************************************************************************************/
+
+void
+IDirectFBFont_Destruct( IDirectFBFont *thiz )
+{
+ IDirectFBFont_data *data = (IDirectFBFont_data*)thiz->priv;
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ dfb_font_destroy (data->font);
+
+ /* release memory, if any */
+ if (data->content) {
+ if (data->content_mapped)
+ munmap( data->content, data->content_size );
+ else
+ D_FREE( data->content );
+ }
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+/**********************************************************************************************************************/
+
+/*
+ * increments reference count of font
+ */
+static DirectResult
+IDirectFBFont_AddRef( IDirectFBFont *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+/*
+ * decrements reference count, destructs interface data if reference count is 0
+ */
+static DirectResult
+IDirectFBFont_Release( IDirectFBFont *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (--data->ref == 0)
+ IDirectFBFont_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+/*
+ * Get the distance from the baseline to the top.
+ */
+static DFBResult
+IDirectFBFont_GetAscender( IDirectFBFont *thiz, int *ascender )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!ascender)
+ return DFB_INVARG;
+
+ *ascender = data->font->ascender;
+
+ return DFB_OK;
+}
+
+/*
+ * Get the distance from the baseline to the bottom.
+ * This is a negative value!
+ */
+static DFBResult
+IDirectFBFont_GetDescender( IDirectFBFont *thiz, int *descender )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!descender)
+ return DFB_INVARG;
+
+ *descender = data->font->descender;
+
+ return DFB_OK;
+}
+
+/*
+ * Get the height of this font.
+ */
+static DFBResult
+IDirectFBFont_GetHeight( IDirectFBFont *thiz, int *height )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!height)
+ return DFB_INVARG;
+
+ *height = data->font->height;
+
+ return DFB_OK;
+}
+
+/*
+ * Get the line spacing vector of this font.
+ */
+static DFBResult
+IDirectFBFont_GetLineSpacingVector( IDirectFBFont *thiz, int *xspacing, int *yspacing )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!xspacing && !yspacing)
+ return DFB_INVARG;
+
+ if (xspacing) {
+ *xspacing = - data->font->height * data->font->up_unit_x;
+ }
+
+ if (yspacing) {
+ *yspacing = - data->font->height * data->font->up_unit_y;
+ }
+
+ return DFB_OK;
+}
+
+/*
+ * Get the maximum character width.
+ */
+static DFBResult
+IDirectFBFont_GetMaxAdvance( IDirectFBFont *thiz, int *maxadvance )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!maxadvance)
+ return DFB_INVARG;
+
+ *maxadvance = data->font->maxadvance;
+
+ return DFB_OK;
+}
+
+/*
+ * Get the kerning to apply between two glyphs.
+ */
+static DFBResult
+IDirectFBFont_GetKerning( IDirectFBFont *thiz,
+ unsigned int prev, unsigned int current,
+ int *kern_x, int *kern_y)
+{
+ DFBResult ret;
+ CoreFont *font;
+ int x = 0, y = 0;
+ unsigned int prev_index, current_index;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!kern_x && !kern_y)
+ return DFB_INVARG;
+
+ font = data->font;
+
+ dfb_font_lock( font );
+
+ if (font->GetKerning) {
+ ret = dfb_font_decode_character( font, data->encoding, prev, &prev_index );
+ if (ret)
+ goto error;
+
+ ret = dfb_font_decode_character( font, data->encoding, current, &current_index );
+ if (ret)
+ goto error;
+
+ ret = font->GetKerning (font, prev_index, current_index, &x, &y);
+ if (ret)
+ goto error;
+ }
+
+ dfb_font_unlock( font );
+
+ if (kern_x)
+ *kern_x = x;
+ if (kern_y)
+ *kern_y = y;
+
+ return DFB_OK;
+
+
+error:
+ dfb_font_unlock( font );
+
+ return ret;
+}
+
+/*
+ * Get the logical and ink extents of the specified string.
+ */
+static DFBResult
+IDirectFBFont_GetStringExtents( IDirectFBFont *thiz,
+ const char *text, int bytes,
+ DFBRectangle *logical_rect,
+ DFBRectangle *ink_rect )
+{
+ DFBResult ret;
+ CoreFont *font;
+ int xbaseline = 0;
+ int ybaseline = 0;
+
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+
+ if (!text)
+ return DFB_INVARG;
+
+ if (!logical_rect && !ink_rect)
+ return DFB_INVARG;
+
+ if (bytes < 0)
+ bytes = strlen (text);
+
+ if (ink_rect)
+ memset (ink_rect, 0, sizeof (DFBRectangle));
+
+ font = data->font;
+
+ dfb_font_lock( font );
+
+ if (bytes > 0) {
+ int i, num;
+ unsigned int prev = 0;
+ unsigned int indices[bytes];
+
+ /* Decode string to character indices. */
+ ret = dfb_font_decode_text( font, data->encoding, text, bytes, indices, &num );
+ if (ret) {
+ dfb_font_unlock( font );
+ return ret;
+ }
+
+ for (i=0; i<num; i++) {
+ unsigned int current = indices[i];
+ CoreGlyphData *glyph;
+
+ if (dfb_font_get_glyph_data( font, current, 0, &glyph ) == DFB_OK) { // FIXME: support font layers
+ int kx, ky = 0;
+
+ if (prev && font->GetKerning &&
+ font->GetKerning( font, prev, current, &kx, &ky ) == DFB_OK) {
+ xbaseline += kx;
+ ybaseline += ky;
+ }
+
+ if (ink_rect) {
+ DFBRectangle glyph_rect = { xbaseline + glyph->left,
+ ybaseline + glyph->top,
+ glyph->width, glyph->height};
+ dfb_rectangle_union (ink_rect, &glyph_rect);
+ }
+
+ xbaseline += glyph->xadvance;
+ ybaseline += glyph->yadvance;
+ }
+
+ prev = current;
+ }
+ }
+
+ if (logical_rect) {
+ // We already have the text baseline vector in (xbaseline,ybaseline).
+ // Now find the ascender and descender vectors:
+ int xascender = font->ascender * font->up_unit_x;
+ int yascender = font->ascender * font->up_unit_y;
+ int xdescender = font->descender * font->up_unit_x;
+ int ydescender = font->descender * font->up_unit_y;
+
+ // Now find top/bottom left/right points relative to the text:
+ int top_left_x = xascender;
+ int top_left_y = yascender;
+ int bottom_left_x = xdescender;
+ int bottom_left_y = ydescender;
+ int top_right_x = top_left_x + xbaseline;
+ int top_right_y = top_left_y + ybaseline;
+ int bottom_right_x = bottom_left_x + xbaseline;
+ int bottom_right_y = bottom_left_y + ybaseline;
+
+ // The logical rectangle is the bounding-box of these points:
+#define MIN4(a,b,c,d) (MIN(MIN((a),(b)),MIN((c),(d))))
+#define MAX4(a,b,c,d) (MAX(MAX((a),(b)),MAX((c),(d))))
+ logical_rect->x = MIN4(top_left_x, bottom_left_x, top_right_x, bottom_right_x);
+ logical_rect->y = MIN4(top_left_y, bottom_left_y, top_right_y, bottom_right_y);
+ logical_rect->w = MAX4(top_left_x, bottom_left_x, top_right_x, bottom_right_x) - logical_rect->x;
+ logical_rect->h = MAX4(top_left_y, bottom_left_y, top_right_y, bottom_right_y) - logical_rect->y;
+ }
+
+ if (ink_rect) {
+ if (ink_rect->w < 0) { /* PBE FIXME what is this doing? */
+ ink_rect->x += ink_rect->w;
+ ink_rect->w = -ink_rect->w;
+ }
+ ink_rect->x += font->ascender * font->up_unit_x;
+ ink_rect->y += font->ascender * font->up_unit_y;
+ }
+
+ dfb_font_unlock( font );
+
+ return DFB_OK;
+}
+
+/*
+ * Get the logical width of the specified string.
+ */
+static DFBResult
+IDirectFBFont_GetStringWidth( IDirectFBFont *thiz,
+ const char *text,
+ int bytes,
+ int *ret_width )
+{
+ DFBResult ret;
+ int xsize = 0;
+ int ysize = 0;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!text || !ret_width)
+ return DFB_INVARG;
+
+ if (bytes < 0)
+ bytes = strlen (text);
+
+ if (bytes > 0) {
+ int i, num, kx, ky;
+ unsigned int prev = 0;
+ unsigned int indices[bytes];
+ CoreFont *font = data->font;
+
+ dfb_font_lock( font );
+
+ /* Decode string to character indices. */
+ ret = dfb_font_decode_text( font, data->encoding, text, bytes, indices, &num );
+ if (ret) {
+ dfb_font_unlock( font );
+ return ret;
+ }
+
+ /* Calculate string width. */
+ for (i=0; i<num; i++) {
+ unsigned int current = indices[i];
+ CoreGlyphData *glyph;
+
+ if (dfb_font_get_glyph_data( font, current, 0, &glyph ) == DFB_OK) { // FIXME: support font layers
+ xsize += glyph->xadvance;
+ ysize += glyph->yadvance;
+
+ if (prev && font->GetKerning &&
+ font->GetKerning( font, prev, current, &kx, &ky ) == DFB_OK) {
+ xsize += kx;
+ ysize += ky;
+ }
+ }
+
+ prev = current;
+ }
+
+ dfb_font_unlock( font );
+ }
+
+ if (!ysize) {
+ *ret_width = xsize;
+ }
+ else if (!xsize) {
+ *ret_width = ysize;
+ }
+ else {
+ *ret_width = sqrt(xsize*xsize + ysize*ysize);
+ }
+
+ return DFB_OK;
+}
+
+/*
+ * Get the extents of the specified glyph.
+ */
+static DFBResult
+IDirectFBFont_GetGlyphExtents( IDirectFBFont *thiz,
+ unsigned int character,
+ DFBRectangle *rect,
+ int *advance )
+{
+ DFBResult ret;
+ CoreFont *font;
+ CoreGlyphData *glyph;
+ unsigned int index;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!rect && !advance)
+ return DFB_INVARG;
+
+ font = data->font;
+
+ dfb_font_lock( font );
+
+ ret = dfb_font_decode_character( font, data->encoding, character, &index );
+ if (ret) {
+ dfb_font_unlock( font );
+ return ret;
+ }
+
+ if (dfb_font_get_glyph_data (font, index, 0, &glyph) != DFB_OK) { // FIXME: support font layers
+ if (rect)
+ rect->x = rect->y = rect->w = rect->h = 0;
+
+ if (advance)
+ *advance = 0;
+ }
+ else {
+ if (rect) {
+ rect->x = glyph->left;
+ rect->y = glyph->top - font->ascender;
+ rect->w = glyph->width;
+ rect->h = glyph->height;
+ }
+
+ if (advance)
+ *advance = glyph->xadvance;
+ }
+
+ dfb_font_unlock( font );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBFont_GetStringBreak( IDirectFBFont *thiz,
+ const char *text,
+ int bytes,
+ int max_width,
+ int *ret_width,
+ int *ret_str_length,
+ const char **ret_next_line)
+{
+ DFBResult ret;
+ CoreFont *font;
+ const u8 *string;
+ const u8 *end;
+ CoreGlyphData *glyph;
+ int kern_x;
+ int kern_y;
+ int length = 0;
+ int xsize = 0;
+ int ysize = 0;
+ int width = 0;
+ unichar current;
+ unsigned int index;
+ unsigned int prev = 0;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ if (!text || !ret_next_line || !ret_str_length || !ret_width)
+ return DFB_INVARG;
+
+ /* FIXME: Try to change the font module API *slightly* to support this. */
+ if (data->encoding != DTEID_UTF8)
+ return DFB_UNSUPPORTED;
+
+ if (bytes < 0)
+ bytes = strlen (text);
+
+ if (!bytes) {
+ *ret_next_line = NULL;
+ *ret_str_length = 0;
+ *ret_width = 0;
+
+ return DFB_OK;
+ }
+
+ font = data->font;
+ string = (const u8*) text;
+ end = string + bytes;
+ *ret_next_line = NULL;
+
+ dfb_font_lock( font );
+
+ do {
+ *ret_width = width;
+ length ++;
+
+ current = DIRECT_UTF8_GET_CHAR( string );
+
+ string += DIRECT_UTF8_SKIP( string[0] );
+
+ if (current == ' ' || current == 0x0a) {
+ *ret_next_line = (const char*) string;
+ *ret_str_length = length;
+ *ret_width = width;
+ }
+
+ ret = dfb_font_decode_character( font, data->encoding, current, &index );
+ if (ret)
+ continue;
+
+ ret = dfb_font_get_glyph_data( font, index, 0, &glyph ); // FIXME: support font layers
+ if (ret)
+ continue;
+
+ xsize += glyph->xadvance;
+ ysize += glyph->yadvance;
+
+ if (prev && font->GetKerning && font->GetKerning( font, prev, index, &kern_x, &kern_y) == DFB_OK) {
+ xsize += kern_x;
+ ysize += kern_y;
+ }
+
+ if (!ysize) {
+ width = xsize;
+ }
+ else if (!xsize) {
+ width = ysize;
+ }
+ else {
+ width = sqrt(xsize*xsize + ysize*ysize);
+ }
+
+ prev = index;
+ } while (width < max_width && string < end && current != 0x0a);
+
+ dfb_font_unlock( font );
+
+ if (width<max_width && string >= end) {
+ *ret_next_line = NULL;
+ *ret_str_length = length;
+ *ret_width = width;
+
+ return DFB_OK;
+ }
+
+ if (*ret_next_line == NULL) {
+ if (length == 1) {
+ *ret_str_length = length;
+ *ret_next_line = (const char*) string;
+ *ret_width = width;
+ } else {
+ *ret_str_length = length-1;
+ *ret_next_line = (const char*) string-1;
+ /* ret_width already set in the loop */
+ }
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBFont_SetEncoding( IDirectFBFont *thiz,
+ DFBTextEncodingID encoding )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p, %d )\n", __FUNCTION__, thiz, encoding );
+
+ if (encoding > data->font->last_encoding)
+ return DFB_IDNOTFOUND;
+
+ data->encoding = encoding;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBFont_EnumEncodings( IDirectFBFont *thiz,
+ DFBTextEncodingCallback callback,
+ void *context )
+{
+ int i;
+ CoreFont *font;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ if (!callback)
+ return DFB_INVARG;
+
+ D_DEBUG_AT( Font, "%s( %p, %p, %p )\n", __FUNCTION__, thiz, callback, context );
+
+ font = data->font;
+
+ if (callback( DTEID_UTF8, "UTF8", context ) == DFENUM_OK) {
+ for (i=DTEID_OTHER; i<=font->last_encoding; i++) {
+ if (callback( i, font->encodings[i]->name, context ) != DFENUM_OK)
+ break;
+ }
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBFont_FindEncoding( IDirectFBFont *thiz,
+ const char *name,
+ DFBTextEncodingID *ret_id )
+{
+ int i;
+ CoreFont *font;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ if (!name || !ret_id)
+ return DFB_INVARG;
+
+ D_DEBUG_AT( Font, "%s( %p, '%s', %p )\n", __FUNCTION__, thiz, name, ret_id );
+
+ if (!strcasecmp( name, "UTF8" )) {
+ *ret_id = DTEID_UTF8;
+ return DFB_OK;
+ }
+
+ font = data->font;
+
+ for (i=DTEID_OTHER; i<=font->last_encoding; i++) {
+ if (!strcasecmp( name, font->encodings[i]->name )) {
+ *ret_id = i;
+ return DFB_OK;
+ }
+ }
+
+ return DFB_IDNOTFOUND;
+}
+
+/*
+ * Get the extents of the specified glyph.
+ */
+static DFBResult
+IDirectFBFont_GetGlyphExtentsXY( IDirectFBFont *thiz,
+ unsigned int character,
+ DFBRectangle *rect,
+ int *xadvance,
+ int *yadvance )
+{
+ DFBResult ret;
+ CoreFont *font;
+ CoreGlyphData *glyph;
+ unsigned int index;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!rect && !xadvance && !yadvance)
+ return DFB_INVARG;
+
+ font = data->font;
+
+ dfb_font_lock( font );
+
+ ret = dfb_font_decode_character( font, data->encoding, character, &index );
+ if (ret) {
+ dfb_font_unlock( font );
+ return ret;
+ }
+
+ if (dfb_font_get_glyph_data (font, index, 0, &glyph) != DFB_OK) { // FIXME: support font layers
+ if (rect)
+ rect->x = rect->y = rect->w = rect->h = 0;
+
+ if (xadvance)
+ *xadvance = 0;
+
+ if (yadvance)
+ *yadvance = 0;
+ }
+ else {
+ if (rect) {
+ rect->x = glyph->left + font->ascender * font->up_unit_x;
+ rect->y = glyph->top + font->ascender * font->up_unit_y;
+ rect->w = glyph->width;
+ rect->h = glyph->height;
+ }
+
+ if (xadvance)
+ *xadvance = glyph->xadvance;
+
+ if (yadvance)
+ *yadvance = glyph->yadvance;
+ }
+
+ dfb_font_unlock( font );
+
+ return DFB_OK;
+}
+
+/*
+ * Get the description of the font.
+ */
+static DFBResult
+IDirectFBFont_GetDescription( IDirectFBFont *thiz,
+ DFBFontDescription *ret_description )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBFont)
+
+ D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );
+
+ if (!ret_description)
+ return DFB_INVARG;
+
+ *ret_description = data->font->description;
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+IDirectFBFont_Construct( IDirectFBFont *thiz, CoreFont *font )
+{
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBFont)
+
+ data->ref = 1;
+ data->font = font;
+
+ thiz->AddRef = IDirectFBFont_AddRef;
+ thiz->Release = IDirectFBFont_Release;
+ thiz->GetAscender = IDirectFBFont_GetAscender;
+ thiz->GetDescender = IDirectFBFont_GetDescender;
+ thiz->GetHeight = IDirectFBFont_GetHeight;
+ thiz->GetMaxAdvance = IDirectFBFont_GetMaxAdvance;
+ thiz->GetKerning = IDirectFBFont_GetKerning;
+ thiz->GetStringWidth = IDirectFBFont_GetStringWidth;
+ thiz->GetStringExtents = IDirectFBFont_GetStringExtents;
+ thiz->GetGlyphExtents = IDirectFBFont_GetGlyphExtents;
+ thiz->GetStringBreak = IDirectFBFont_GetStringBreak;
+ thiz->SetEncoding = IDirectFBFont_SetEncoding;
+ thiz->EnumEncodings = IDirectFBFont_EnumEncodings;
+ thiz->FindEncoding = IDirectFBFont_FindEncoding;
+ thiz->GetLineSpacingVector = IDirectFBFont_GetLineSpacingVector;
+ thiz->GetGlyphExtentsXY = IDirectFBFont_GetGlyphExtentsXY;
+ thiz->GetDescription = IDirectFBFont_GetDescription;
+
+ return DFB_OK;
+}
+
+static DFBResult
+try_map_file( IDirectFBDataBuffer_data *buffer_data,
+ IDirectFBFont_ProbeContext *ctx )
+{
+ /* try to map the "file" content first */
+ if (!access( buffer_data->filename, O_RDONLY )) {
+ int fd;
+ struct stat st;
+
+ fd = open( buffer_data->filename, O_RDONLY );
+ if (fd < 0) {
+ D_PERROR( "IDirectFBFont: Could not open '%s'\n", buffer_data->filename );
+ return DFB_IO;
+ }
+
+ if (fstat( fd, &st )) {
+ D_PERROR( "IDirectFBFont: Could not stat '%s'\n", buffer_data->filename );
+ close( fd );
+ return DFB_IO;
+ }
+
+ ctx->content = mmap( NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0 );
+ if (ctx->content == MAP_FAILED) {
+ D_PERROR( "IDirectFBFont: Could not mmap '%s'\n", buffer_data->filename );
+ close( fd );
+ return DFB_IO;
+ }
+
+ ctx->content_size = st.st_size;
+ ctx->content_mapped = true;
+
+ close( fd );
+
+ return DFB_OK;
+ }
+
+ return DFB_UNSUPPORTED;
+}
+
+static void
+unmap_or_free( IDirectFBFont_ProbeContext *ctx )
+{
+ if (ctx->content) {
+ if (ctx->content_mapped)
+ munmap( ctx->content, ctx->content_size );
+ else
+ D_FREE( ctx->content );
+ }
+}
+
+DFBResult
+IDirectFBFont_CreateFromBuffer( IDirectFBDataBuffer *buffer,
+ CoreDFB *core,
+ const DFBFontDescription *desc,
+ IDirectFBFont **interface )
+{
+ DFBResult ret;
+ DirectInterfaceFuncs *funcs = NULL;
+ IDirectFBDataBuffer_data *buffer_data;
+ IDirectFBFont *ifont;
+ IDirectFBFont_ProbeContext ctx = {0};
+
+ /* Get the private information of the data buffer. */
+ buffer_data = (IDirectFBDataBuffer_data*) buffer->priv;
+ if (!buffer_data)
+ return DFB_DEAD;
+
+ /* Provide a fallback for image providers without data buffer support. */
+ ctx.filename = buffer_data->filename;
+
+ /* try to map the "file" content first */
+ if (try_map_file( buffer_data, &ctx ) != DFB_OK) {
+ /* try to load the "file" content from the buffer */
+
+ /* we need to be able to seek (this implies non-streamed,
+ so we also know the size) so we can reuse the buffer */
+ if (buffer->SeekTo( buffer, 0 ) == DFB_OK) {
+ unsigned int size, got;
+
+ /* get the "file" length */
+ buffer->GetLength( buffer, &size );
+
+ ctx.content = D_MALLOC( size );
+ if (!ctx.content)
+ return DR_NOLOCALMEMORY;
+
+ ctx.content_size = 0;
+
+ while (ctx.content_size < size) {
+ unsigned int get = size - ctx.content_size;
+
+ if (get > 8192)
+ get = 8192;
+
+ ret = buffer->WaitForData( buffer, get );
+ if (ret) {
+ D_DERROR( ret, "%s: WaitForData failed!\n", __FUNCTION__ );
+ break;
+ }
+
+ ret = buffer->GetData( buffer, get, ctx.content + ctx.content_size, &got );
+ if (ret) {
+ D_DERROR( ret, "%s: GetData failed!\n", __FUNCTION__ );
+ break;
+ }
+
+ if (!got)
+ break;
+
+ ctx.content_size += got;
+ }
+
+ if (ctx.content_size != size) {
+ D_ERROR( "%s: Got size %u differs from supposed %u!\n", __FUNCTION__, ctx.content_size, size );
+ D_FREE( ctx.content );
+ return DFB_FAILURE;
+ }
+ }
+ }
+
+ /* Find a suitable implementation. */
+ ret = DirectGetInterface( &funcs, "IDirectFBFont", NULL, DirectProbeInterface, &ctx );
+ if (ret) {
+ unmap_or_free( &ctx );
+ return ret;
+ }
+
+ DIRECT_ALLOCATE_INTERFACE( ifont, IDirectFBFont );
+
+ /* Construct the interface. */
+ ret = funcs->Construct( ifont, core, &ctx, desc );
+ if (ret) {
+ unmap_or_free( &ctx );
+ return ret;
+ }
+
+ /* store pointer for deletion at destroy */
+ {
+ IDirectFBFont_data *data = (IDirectFBFont_data*)(ifont->priv);
+ data->content = ctx.content;
+ data->content_size = ctx.content_size;
+ data->content_mapped = ctx.content_mapped;
+ }
+
+ *interface = ifont;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/media/idirectfbfont.h b/Source/DirectFB/src/media/idirectfbfont.h
new file mode 100755
index 0000000..85bdb0c
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbfont.h
@@ -0,0 +1,82 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBFONT_H__
+#define __IDIRECTFBFONT_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+/*
+ * probing context
+ */
+typedef struct {
+ /* Only set if databuffer is created from file.
+ deprecated - use memory location below. */
+ const char *filename;
+
+ /* if !=NULL, pointer to the file content */
+ unsigned char *content;
+ unsigned int content_size;
+ bool content_mapped;
+} IDirectFBFont_ProbeContext;
+
+DFBResult
+IDirectFBFont_CreateFromBuffer( IDirectFBDataBuffer *buffer,
+ CoreDFB *core,
+ const DFBFontDescription *desc,
+ IDirectFBFont **interface );
+
+/**********************************************************************************************************************/
+
+/*
+ * private data struct of IDirectFBFont
+ * used by implementors of IDirectFBFont
+ */
+typedef struct {
+ int ref; /* reference counter */
+ CoreFont *font; /* pointer to core font */
+ unsigned char *content; /* possible allocation, free at intf. close */
+ unsigned int content_size;
+ bool content_mapped;
+
+ DFBTextEncodingID encoding; /* text encoding */
+} IDirectFBFont_data;
+
+/*
+ * common code to construct the interface (internal usage only)
+ */
+DFBResult IDirectFBFont_Construct( IDirectFBFont *thiz, CoreFont *font );
+
+/*
+ * deinitialize font and its surfaces
+ */
+void IDirectFBFont_Destruct( IDirectFBFont *thiz );
+
+#endif
diff --git a/Source/DirectFB/src/media/idirectfbimageprovider.c b/Source/DirectFB/src/media/idirectfbimageprovider.c
new file mode 100755
index 0000000..f54319c
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbimageprovider.c
@@ -0,0 +1,167 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#include <directfb.h>
+
+#include <core/core.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+
+#include <media/idirectfbimageprovider.h>
+#include <media/idirectfbdatabuffer.h>
+
+
+static DirectResult
+IDirectFBImageProvider_AddRef( IDirectFBImageProvider *thiz )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DirectResult
+IDirectFBImageProvider_Release( IDirectFBImageProvider *thiz )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBImageProvider_GetSurfaceDescription( IDirectFBImageProvider *thiz,
+ DFBSurfaceDescription *ret_dsc )
+{
+ if (!ret_dsc)
+ return DFB_INVARG;
+
+ ret_dsc->flags = DSDESC_NONE;
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBImageProvider_GetImageDescription( IDirectFBImageProvider *thiz,
+ DFBImageDescription *ret_dsc )
+{
+ if (!ret_dsc)
+ return DFB_INVARG;
+
+ ret_dsc->caps = DICAPS_NONE;
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBImageProvider_RenderTo( IDirectFBImageProvider *thiz,
+ IDirectFBSurface *destination,
+ const DFBRectangle *destination_rect )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBImageProvider_SetRenderCallback( IDirectFBImageProvider *thiz,
+ DIRenderCallback callback,
+ void *callback_data )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBImageProvider_WriteBack( IDirectFBImageProvider *thiz,
+ IDirectFBSurface *surface,
+ const DFBRectangle *src_rect,
+ const char *filename )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static void
+IDirectFBImageProvider_Construct( IDirectFBImageProvider *thiz )
+{
+ thiz->AddRef = IDirectFBImageProvider_AddRef;
+ thiz->Release = IDirectFBImageProvider_Release;
+ thiz->GetSurfaceDescription = IDirectFBImageProvider_GetSurfaceDescription;
+ thiz->GetImageDescription = IDirectFBImageProvider_GetImageDescription;
+ thiz->RenderTo = IDirectFBImageProvider_RenderTo;
+ thiz->SetRenderCallback = IDirectFBImageProvider_SetRenderCallback;
+ thiz->WriteBack = IDirectFBImageProvider_WriteBack;
+}
+
+DFBResult
+IDirectFBImageProvider_CreateFromBuffer( IDirectFBDataBuffer *buffer,
+ CoreDFB *core,
+ IDirectFBImageProvider **interface )
+{
+ DFBResult ret;
+ DirectInterfaceFuncs *funcs = NULL;
+ IDirectFBDataBuffer_data *buffer_data;
+ IDirectFBImageProvider *imageprovider;
+ IDirectFBImageProvider_ProbeContext ctx;
+
+ /* Get the private information of the data buffer. */
+ buffer_data = (IDirectFBDataBuffer_data*) buffer->priv;
+ if (!buffer_data)
+ return DFB_DEAD;
+
+ /* Clear for safety, especially header data. */
+ memset( &ctx, 0, sizeof(ctx) );
+
+ /* Provide a fallback for image providers without data buffer support. */
+ ctx.filename = buffer_data->filename;
+
+ /* Wait until 32 bytes are available. */
+ ret = buffer->WaitForData( buffer, 32 );
+ if (ret)
+ return ret;
+
+ /* Read the first 32 bytes. */
+ buffer->PeekData( buffer, 32, 0, ctx.header, NULL );
+
+ /* Find a suitable implementation. */
+ ret = DirectGetInterface( &funcs, "IDirectFBImageProvider", NULL, DirectProbeInterface, &ctx );
+ if (ret)
+ return ret;
+
+ DIRECT_ALLOCATE_INTERFACE( imageprovider, IDirectFBImageProvider );
+
+ /* Initialize interface pointers. */
+ IDirectFBImageProvider_Construct( imageprovider );
+
+ /* Construct the interface. */
+ ret = funcs->Construct( imageprovider, buffer, core );
+ if (ret)
+ return ret;
+
+ *interface = imageprovider;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/media/idirectfbimageprovider.h b/Source/DirectFB/src/media/idirectfbimageprovider.h
new file mode 100755
index 0000000..afbd613
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbimageprovider.h
@@ -0,0 +1,48 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBIMAGEPROVIDER_H__
+#define __IDIRECTFBIMAGEPROVIDER_H__
+
+#include <core/coretypes.h>
+
+/*
+ * probing context
+ */
+typedef struct {
+ unsigned char header[32];
+
+ const char *filename; /* Only set if databuffer is created from file. */
+} IDirectFBImageProvider_ProbeContext;
+
+DFBResult
+IDirectFBImageProvider_CreateFromBuffer( IDirectFBDataBuffer *buffer,
+ CoreDFB *core,
+ IDirectFBImageProvider **interface );
+
+#endif
diff --git a/Source/DirectFB/src/media/idirectfbvideoprovider.c b/Source/DirectFB/src/media/idirectfbvideoprovider.c
new file mode 100755
index 0000000..fcea1ba
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbvideoprovider.c
@@ -0,0 +1,387 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#include <directfb.h>
+
+#include <direct/interface.h>
+#include <direct/mem.h>
+
+#include <media/idirectfbvideoprovider.h>
+#include <media/idirectfbdatabuffer.h>
+
+
+static DirectResult
+IDirectFBVideoProvider_AddRef( IDirectFBVideoProvider *thiz )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DirectResult
+IDirectFBVideoProvider_Release( IDirectFBVideoProvider *thiz )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetCapabilities( IDirectFBVideoProvider *thiz,
+ DFBVideoProviderCapabilities *ret_caps )
+{
+ if (!ret_caps)
+ return DFB_INVARG;
+
+ *ret_caps = 0;
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetSurfaceDescription( IDirectFBVideoProvider *thiz,
+ DFBSurfaceDescription *ret_dsc )
+{
+ if (!ret_dsc)
+ return DFB_INVARG;
+
+ ret_dsc->flags = DSDESC_NONE;
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetStreamDescription( IDirectFBVideoProvider *thiz,
+ DFBStreamDescription *ret_dsc )
+{
+ if (!ret_dsc)
+ return DFB_INVARG;
+
+ memset( ret_dsc, 0, sizeof(DFBStreamDescription) );
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetBufferOccupancy( IDirectFBVideoProvider *thiz,
+ DFBBufferOccupancy *ret_occ )
+{
+ if (!ret_occ)
+ return DFB_INVARG;
+
+ memset( ret_occ, 0, sizeof(DFBBufferOccupancy) );
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetBufferThresholds( IDirectFBVideoProvider *thiz,
+ DFBBufferThresholds *ret_thresh )
+{
+ if (!ret_thresh)
+ return DFB_INVARG;
+
+ memset( ret_thresh, 0, sizeof(DFBBufferThresholds) );
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_SetBufferThresholds( IDirectFBVideoProvider *thiz,
+ DFBBufferThresholds thresh )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_PlayTo( IDirectFBVideoProvider *thiz,
+ IDirectFBSurface *destination,
+ const DFBRectangle *destination_rect,
+ DVFrameCallback callback,
+ void *ctx )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_Stop( IDirectFBVideoProvider *thiz )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetStatus( IDirectFBVideoProvider *thiz,
+ DFBVideoProviderStatus *ret_status )
+{
+ if (!ret_status)
+ return DFB_INVARG;
+
+ *ret_status = DVSTATE_UNKNOWN;
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_SeekTo( IDirectFBVideoProvider *thiz,
+ double seconds )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetPos( IDirectFBVideoProvider *thiz,
+ double *ret_seconds )
+{
+ if (!ret_seconds)
+ return DFB_INVARG;
+
+ *ret_seconds = 0.0;
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetLength( IDirectFBVideoProvider *thiz,
+ double *ret_seconds )
+{
+ if (!ret_seconds)
+ return DFB_INVARG;
+
+ *ret_seconds = 0.0;
+
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetColorAdjustment( IDirectFBVideoProvider *thiz,
+ DFBColorAdjustment *ret_adj )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_SetColorAdjustment( IDirectFBVideoProvider *thiz,
+ const DFBColorAdjustment *adj )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_SendEvent( IDirectFBVideoProvider *thiz,
+ const DFBEvent *event )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_SetPlaybackFlags( IDirectFBVideoProvider *thiz,
+ DFBVideoProviderPlaybackFlags flags )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_SetSpeed( IDirectFBVideoProvider *thiz,
+ double multiplier )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetSpeed( IDirectFBVideoProvider *thiz,
+ double *ret_multiplier )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_SetVolume( IDirectFBVideoProvider *thiz,
+ float level )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetVolume( IDirectFBVideoProvider *thiz,
+ float *ret_level )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_SetStreamAttributes(IDirectFBVideoProvider *thiz,
+ DFBStreamAttributes attr)
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_SetAudioOutputs(IDirectFBVideoProvider *thiz,
+ DFBVideoProviderAudioUnits* audioUnits)
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_GetAudioOutputs(IDirectFBVideoProvider *thiz,
+ DFBVideoProviderAudioUnits* audioUnits)
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_SetAudioDelay( IDirectFBVideoProvider *thiz,
+ long delay )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_CreateEventBuffer( IDirectFBVideoProvider *thiz,
+ IDirectFBEventBuffer **buffer )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_AttachEventBuffer( IDirectFBVideoProvider *thiz,
+ IDirectFBEventBuffer *buffer )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_EnableEvents(IDirectFBVideoProvider *thiz,
+ DFBVideoProviderEventType mask )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_DisableEvents(IDirectFBVideoProvider *thiz,
+ DFBVideoProviderEventType mask )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+IDirectFBVideoProvider_DetachEventBuffer( IDirectFBVideoProvider *thiz,
+ IDirectFBEventBuffer *buffer )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static void
+IDirectFBVideoProvider_Construct( IDirectFBVideoProvider *thiz )
+{
+ thiz->AddRef = IDirectFBVideoProvider_AddRef;
+ thiz->Release = IDirectFBVideoProvider_Release;
+ thiz->GetCapabilities = IDirectFBVideoProvider_GetCapabilities;
+ thiz->GetSurfaceDescription = IDirectFBVideoProvider_GetSurfaceDescription;
+ thiz->GetStreamDescription = IDirectFBVideoProvider_GetStreamDescription;
+ thiz->GetBufferOccupancy = IDirectFBVideoProvider_GetBufferOccupancy;
+ thiz->SetBufferThresholds = IDirectFBVideoProvider_SetBufferThresholds;
+ thiz->GetBufferThresholds = IDirectFBVideoProvider_GetBufferThresholds;
+ thiz->PlayTo = IDirectFBVideoProvider_PlayTo;
+ thiz->Stop = IDirectFBVideoProvider_Stop;
+ thiz->GetStatus = IDirectFBVideoProvider_GetStatus;
+ thiz->SeekTo = IDirectFBVideoProvider_SeekTo;
+ thiz->GetPos = IDirectFBVideoProvider_GetPos;
+ thiz->GetLength = IDirectFBVideoProvider_GetLength;
+ thiz->GetColorAdjustment = IDirectFBVideoProvider_GetColorAdjustment;
+ thiz->SetColorAdjustment = IDirectFBVideoProvider_SetColorAdjustment;
+ thiz->SendEvent = IDirectFBVideoProvider_SendEvent;
+ thiz->SetPlaybackFlags = IDirectFBVideoProvider_SetPlaybackFlags;
+ thiz->SetSpeed = IDirectFBVideoProvider_SetSpeed;
+ thiz->GetSpeed = IDirectFBVideoProvider_GetSpeed;
+ thiz->SetVolume = IDirectFBVideoProvider_SetVolume;
+ thiz->GetVolume = IDirectFBVideoProvider_GetVolume;
+ thiz->SetStreamAttributes = IDirectFBVideoProvider_SetStreamAttributes;
+ thiz->SetAudioOutputs = IDirectFBVideoProvider_SetAudioOutputs;
+ thiz->GetAudioOutputs = IDirectFBVideoProvider_GetAudioOutputs;
+ thiz->CreateEventBuffer = IDirectFBVideoProvider_CreateEventBuffer;
+ thiz->AttachEventBuffer = IDirectFBVideoProvider_AttachEventBuffer;
+ thiz->EnableEvents = IDirectFBVideoProvider_EnableEvents;
+ thiz->DisableEvents = IDirectFBVideoProvider_DisableEvents;
+ thiz->DetachEventBuffer = IDirectFBVideoProvider_DetachEventBuffer;
+ thiz->SetAudioDelay = IDirectFBVideoProvider_SetAudioDelay;
+}
+
+
+DFBResult
+IDirectFBVideoProvider_CreateFromBuffer( IDirectFBDataBuffer *buffer,
+ CoreDFB *core,
+ IDirectFBVideoProvider **interface )
+{
+ DFBResult ret;
+ DirectInterfaceFuncs *funcs = NULL;
+ IDirectFBDataBuffer_data *buffer_data;
+ IDirectFBVideoProvider *videoprovider;
+ IDirectFBVideoProvider_ProbeContext ctx;
+
+ /* Get the private information of the data buffer. */
+ buffer_data = (IDirectFBDataBuffer_data*) buffer->priv;
+ if (!buffer_data)
+ return DFB_DEAD;
+
+ /* Provide a fallback for video providers without data buffer support. */
+ ctx.filename = buffer_data->filename;
+ ctx.buffer = buffer;
+
+ /* Wait until 64 bytes are available. */
+ ret = buffer->WaitForData( buffer, sizeof(ctx.header) );
+ if (ret)
+ return ret;
+
+ /* Clear context header. */
+ memset( ctx.header, 0, sizeof(ctx.header) );
+
+ /* Read the first 64 bytes. */
+ buffer->PeekData( buffer, sizeof(ctx.header), 0, ctx.header, NULL );
+
+ /* Find a suitable implementation. */
+ ret = DirectGetInterface( &funcs, "IDirectFBVideoProvider", NULL, DirectProbeInterface, &ctx );
+ if (ret)
+ return ret;
+
+ DIRECT_ALLOCATE_INTERFACE( videoprovider, IDirectFBVideoProvider );
+
+ /* Initialize interface pointers. */
+ IDirectFBVideoProvider_Construct( videoprovider );
+
+ /* Construct the interface. */
+ ret = funcs->Construct( videoprovider, buffer, core );
+ if (ret)
+ return ret;
+
+ *interface = videoprovider;
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/src/media/idirectfbvideoprovider.h b/Source/DirectFB/src/media/idirectfbvideoprovider.h
new file mode 100755
index 0000000..24e9ea1
--- /dev/null
+++ b/Source/DirectFB/src/media/idirectfbvideoprovider.h
@@ -0,0 +1,54 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBVIDEOPROVIDER_H__
+#define __IDIRECTFBVIDEOPROVIDER_H__
+
+#include <core/coretypes.h>
+
+/*
+ * probing context
+ */
+typedef struct {
+ unsigned char header[64];
+
+ /* Only set if databuffer is created from file. */
+ const char *filename;
+
+ /* Usefull if provider needs more data for probing. */
+ IDirectFBDataBuffer *buffer;
+} IDirectFBVideoProvider_ProbeContext;
+
+
+DFBResult
+IDirectFBVideoProvider_CreateFromBuffer( IDirectFBDataBuffer *buffer,
+ CoreDFB *core,
+ IDirectFBVideoProvider **interface );
+
+#endif
+
diff --git a/Source/DirectFB/src/misc/Makefile.am b/Source/DirectFB/src/misc/Makefile.am
new file mode 100755
index 0000000..d1e77b7
--- /dev/null
+++ b/Source/DirectFB/src/misc/Makefile.am
@@ -0,0 +1,29 @@
+## Makefile.am for DirectFB/src/misc
+
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+AM_CPPFLAGS = \
+ -DMODULEDIR=\"@MODULEDIR@\" \
+ -DSOPATH=\"@SOPATH@\" \
+ -DSYSCONFDIR=\"@sysconfdir@\"
+
+internalincludedir = $(INTERNALINCLUDEDIR)/misc
+
+internalinclude_HEADERS = \
+ conf.h \
+ gfx_util.h \
+ util.h
+
+
+noinst_LTLIBRARIES = libdirectfb_misc.la
+
+libdirectfb_misc_la_SOURCES = \
+ conf.c \
+ dither565.h \
+ gfx_util.c \
+ util.c
diff --git a/Source/DirectFB/src/misc/Makefile.in b/Source/DirectFB/src/misc/Makefile.in
new file mode 100755
index 0000000..ce04ff7
--- /dev/null
+++ b/Source/DirectFB/src/misc/Makefile.in
@@ -0,0 +1,564 @@
+# 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 = src/misc
+DIST_COMMON = $(internalinclude_HEADERS) $(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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libdirectfb_misc_la_LIBADD =
+am_libdirectfb_misc_la_OBJECTS = conf.lo gfx_util.lo util.lo
+libdirectfb_misc_la_OBJECTS = $(am_libdirectfb_misc_la_OBJECTS)
+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 = $(libdirectfb_misc_la_SOURCES)
+DIST_SOURCES = $(libdirectfb_misc_la_SOURCES)
+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)$(internalincludedir)"
+internalincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(internalinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+AM_CPPFLAGS = \
+ -DMODULEDIR=\"@MODULEDIR@\" \
+ -DSOPATH=\"@SOPATH@\" \
+ -DSYSCONFDIR=\"@sysconfdir@\"
+
+internalincludedir = $(INTERNALINCLUDEDIR)/misc
+internalinclude_HEADERS = \
+ conf.h \
+ gfx_util.h \
+ util.h
+
+noinst_LTLIBRARIES = libdirectfb_misc.la
+libdirectfb_misc_la_SOURCES = \
+ conf.c \
+ dither565.h \
+ gfx_util.c \
+ util.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 src/misc/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/misc/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
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_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
+libdirectfb_misc.la: $(libdirectfb_misc_la_OBJECTS) $(libdirectfb_misc_la_DEPENDENCIES)
+ $(LINK) $(libdirectfb_misc_la_OBJECTS) $(libdirectfb_misc_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gfx_util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.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-internalincludeHEADERS: $(internalinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(internalincludedir)" || $(MKDIR_P) "$(DESTDIR)$(internalincludedir)"
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(internalincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ $(internalincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+uninstall-internalincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(internalincludedir)/$$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) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(internalincludedir)"; 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-libtool clean-noinstLTLIBRARIES \
+ 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-internalincludeHEADERS
+
+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-internalincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES 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-info install-info-am \
+ install-internalincludeHEADERS 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-internalincludeHEADERS
+
+# 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/src/misc/conf.c b/Source/DirectFB/src/misc/conf.c
new file mode 100755
index 0000000..5772ba9
--- /dev/null
+++ b/Source/DirectFB/src/misc/conf.c
@@ -0,0 +1,1947 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <directfb.h>
+#include <directfb_util.h>
+
+#include <direct/conf.h>
+#include <direct/log.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <fusion/conf.h>
+#include <fusion/vector.h>
+
+#include <voodoo/conf.h>
+
+#include <core/coretypes.h>
+#include <core/surface.h>
+#include <core/layers.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+D_DEBUG_DOMAIN( DirectFB_Config, "DirectFB/Config", "Runtime configuration options for DirectFB" );
+
+DFBConfig *dfb_config = NULL;
+
+static const char *config_usage =
+ "DirectFB version " DIRECTFB_VERSION "\n"
+ "\n"
+ " --dfb-help Output DirectFB usage information and exit\n"
+ " --dfb:<option>[,<option>]... Pass options to DirectFB (see below)\n"
+ "\n"
+ "DirectFB options:\n"
+ "\n"
+ " system=<system> Specify the system (FBDev, SDL, etc.)\n"
+ " fbdev=<device> Open <device> instead of /dev/fb0\n"
+ " busid=<id> Specify the bus location of the graphics card (default 1:0:0)\n"
+ " mode=<width>x<height> Set the default resolution\n"
+ " scaled=<width>x<height> Scale the window to this size for 'force-windowed' apps\n"
+ " depth=<pixeldepth> Set the default pixel depth\n"
+ " pixelformat=<pixelformat> Set the default pixel format\n"
+ " surface-shmpool-size=<kb> Set the size of the shared memory pool used\n"
+ " for shared system memory surfaces.\n"
+ " session=<num> Select multi app world (zero based, -1 = new)\n"
+ " remote=<host>[:<session>] Select remote session to connect to\n"
+ " primary-layer=<id> Select an alternative primary layer\n"
+ " primary-only Tell application only about the primary layer\n"
+ " [no-]banner Show DirectFB Banner on startup\n"
+ " [no-]surface-sentinel Enable surface sentinels at the end of chunks in video memory\n"
+ " force-windowed Primary surface always is a window\n"
+ " force-desktop Primary surface is the desktop background\n"
+ " [no-]hardware Enable/disable hardware acceleration\n"
+ " [no-]software Enable/disable software fallbacks\n"
+ " [no-]software-warn Show warnings when doing/dropping software operations\n"
+ " [no-]software-trace Show every stage of the software rendering pipeline\n"
+ " [no-]dma Enable DMA acceleration\n"
+ " [no-]sync Do `sync()' (default=no)\n"
+#ifdef USE_MMX
+ " [no-]mmx Enable mmx support\n"
+#endif
+ " [no-]agp[=<mode>] Enable AGP support\n"
+ " [no-]thrifty-surface-buffers Free sysmem instance on xfer to video memory\n"
+ " font-format=<pixelformat> Set the preferred font format\n"
+ " [no-]font-premult Enable/disable premultiplied glyph images in ARGB format\n"
+ " [no-]deinit-check Enable deinit check at exit\n"
+ " block-all-signals Block all signals\n"
+ " [no-]vt-switch Allocate/switch to a new VT\n"
+ " vt-num=<num> Use given VT instead of current/new one\n"
+ " [no-]vt-switching Allow Ctrl+Alt+<F?> (EXPERIMENTAL)\n"
+ " [no-]graphics-vt Put terminal into graphics mode\n"
+ " [no-]vt Use VT handling code at all?\n"
+ " mouse-source=<device> Mouse device for serial mouse\n"
+ " [no-]mouse-gpm-source Enable mouse input repeated by GPM\n"
+ " [no-]motion-compression Mouse motion event compression\n"
+ " mouse-protocol=<protocol> Mouse protocol\n"
+ " [no-]lefty Swap left and right mouse buttons\n"
+ " [no-]capslock-meta Map the CapsLock key to Meta\n"
+ " linux-input-ir-only Ignore all non-IR Linux Input devices\n"
+ " [no-]linux-input-grab Grab Linux Input devices?\n"
+ " [no-]cursor Never create a cursor or handle it\n"
+ " [no-]cursor-updates Never show a cursor, but still handle it\n"
+ " wm=<wm> Window manager module ('default' or 'unique')\n"
+ " init-layer=<id> Initialize layer with ID (following layer- options apply)\n"
+ " layer-size=<width>x<height> Set the pixel resolution\n"
+ " layer-format=<pixelformat> Set the pixel format\n"
+ " layer-depth=<pixeldepth> Set the pixel depth\n"
+ " layer-buffer-mode=(auto|triple|backvideo|backsystem|frontonly|windows)\n"
+ " layer-bg-none Disable background clear\n"
+ " layer-bg-color=AARRGGBB Use background color (hex)\n"
+ " layer-bg-color-index=<index> Use background color index (decimal)\n"
+ " layer-bg-image=<filename> Use background image\n"
+ " layer-bg-tile=<filename> Use tiled background image\n"
+ " layer-src-key=AARRGGBB Enable color keying (hex)\n"
+ " layer-palette-<index>=AARRGGBB Set palette entry at index (hex)\n"
+ " layer-rotate=<degree> Set the layer rotation for double buffer mode (0,90,180,270)\n"
+ " [no-]smooth-upscale Enable/disable smooth upscaling per default\n"
+ " [no-]smooth-downscale Enable/disable smooth downscaling per default\n"
+ " [no-]translucent-windows Allow translucent windows\n"
+ " [no-]decorations Enable window decorations (if supported by wm)\n"
+ " [no-]startstop Issue StartDrawing/StopDrawing to driver\n"
+ " [no-]autoflip-window Auto flip non-flipping windowed primary surfaces\n"
+ " [no-]discard-repeat-events Discard repeat events (option per application)\n"
+ " videoram-limit=<amount> Limit amount of Video RAM in kb\n"
+ " agpmem-limit=<amount> Limit amount of AGP memory in kb\n"
+ " screenshot-dir=<directory> Dump screen content on <Print> key presses\n"
+ " video-phys=<hexaddress> Physical start of video memory (devmem system)\n"
+ " video-length=<bytes> Length of video memory (devmem system)\n"
+ " mmio-phys=<hexaddress> Physical start of MMIO area (devmem system)\n"
+ " mmio-length=<bytes> Length of MMIO area (devmem system)\n"
+ " accelerator=<id> Accelerator ID selecting graphics driver (devmem system)\n"
+ "\n"
+ " [no-]matrox-sgram Use Matrox SGRAM features\n"
+ " [no-]matrox-crtc2 Experimental Matrox CRTC2 support\n"
+ " matrox-tv-standard=(pal|ntsc|pal-60)\n"
+ " Matrox TV standard (default=pal)\n"
+ " matrox-cable-type=(composite|scart-rgb|scart-composite)\n"
+ " Matrox cable type (default=composite)\n"
+ " h3600-device=<device> Use this device for the H3600 TS driver\n"
+ " mut-device=<device> Use this device for the MuTouch driver\n"
+ " zytronic-device=<device> Use this device for the Zytronic driver\n"
+ " elo-device=<device> Use this device for the Elo driver\n"
+ " penmount-device=<device> Use this device for the PenMount driver\n"
+ " linux-input-devices=<device>[[,<device>]...]\n"
+ " Use these devices for the Linux Input driver\n"
+ " tslib-devices=<device>[[,<device>]...]\n"
+ " Use these devices for the tslib driver\n"
+ " unichrome-revision=<rev> Override unichrome hardware revision\n"
+ " i8xx_overlay_pipe_b Redirect videolayer to pixelpipe B\n"
+ " include=<config file> Include the specified file, relative to the current file\n"
+ " flip-notify-max-latency=<ms> Set maximum FlipNotify latency (ms from Flip til Notify)\n"
+ "\n"
+ " Window surface swapping policy:\n"
+ " window-surface-policy=(auto|videohigh|videolow|systemonly|videoonly)\n"
+ " auto: DirectFB decides depending on hardware.\n"
+ " videohigh: Swapping system/video with high priority.\n"
+ " videolow: Swapping system/video with low priority.\n"
+ " systemonly: Window surface is always stored in system memory.\n"
+ " videoonly: Window surface is always stored in video memory.\n"
+ "\n"
+ " Desktop buffer mode:\n"
+ " desktop-buffer-mode=(auto|triple|backvideo|backsystem|frontonly|windows)\n"
+ " auto: DirectFB decides depending on hardware.\n"
+ " triple: Triple buffering (video only).\n"
+ " backvideo: Front and back buffer are video only.\n"
+ " backsystem: Back buffer is system only.\n"
+ " frontonly: There is no back buffer.\n"
+ " windows: Special mode with window buffers directly displayed.\n"
+ "\n"
+ " Force synchronization of vertical retrace:\n"
+ " vsync-after: Wait for the vertical retrace after flipping.\n"
+ " vsync-none: disable polling for vertical retrace.\n"
+ "\n";
+
+/**********************************************************************************************************************/
+
+/* serial mouse device names */
+#define DEV_NAME "/dev/mouse"
+#define DEV_NAME_GPM "/dev/gpmdata"
+
+/**********************************************************************************************************************/
+
+DFBSurfacePixelFormat
+dfb_config_parse_pixelformat( const char *format )
+{
+ int i;
+ size_t length = strlen(format);
+
+ for (i=0; dfb_pixelformat_names[i].format != DSPF_UNKNOWN; i++) {
+ if (!strcasecmp( format, dfb_pixelformat_names[i].name ))
+ return dfb_pixelformat_names[i].format;
+ }
+
+ for (i=0; dfb_pixelformat_names[i].format != DSPF_UNKNOWN; i++) {
+ if (!strncasecmp( format, dfb_pixelformat_names[i].name, length ))
+ return dfb_pixelformat_names[i].format;
+ }
+
+ return DSPF_UNKNOWN;
+}
+
+/**********************************************************************************************************************/
+
+static void
+print_config_usage( void )
+{
+ fprintf( stderr, "%s%s%s", config_usage, fusion_config_usage, direct_config_usage );
+}
+
+static DFBResult
+parse_args( const char *args )
+{
+ char *buf = alloca( strlen(args) + 1 );
+
+ strcpy( buf, args );
+
+ while (buf && buf[0]) {
+ DFBResult ret;
+ char *value;
+ char *next;
+
+ if ((next = strchr( buf, ',' )) != NULL)
+ *next++ = '\0';
+
+ if (strcmp (buf, "help") == 0) {
+ print_config_usage();
+ exit(1);
+ }
+
+ if (strcmp (buf, "memcpy=help") == 0) {
+ direct_print_memcpy_routines();
+ exit(1);
+ }
+
+ if ((value = strchr( buf, '=' )) != NULL)
+ *value++ = '\0';
+
+ ret = dfb_config_set( buf, value );
+ switch (ret) {
+ case DFB_OK:
+ break;
+ case DFB_UNSUPPORTED:
+ D_ERROR( "DirectFB/Config: Unknown option '%s'!\n", buf );
+ break;
+ default:
+ return ret;
+ }
+
+ buf = next;
+ }
+
+ return DFB_OK;
+}
+
+static void config_values_parse( FusionVector *vector, const char *arg )
+{
+ char *values = D_STRDUP( arg );
+ char *s = values;
+ char *r, *p = NULL;
+
+ if (!values) {
+ D_OOM();
+ return;
+ }
+
+ while ((r = strtok_r( s, ",", &p ))) {
+ direct_trim( &r );
+
+ r = D_STRDUP( r );
+ if (!r)
+ D_OOM();
+ else
+ fusion_vector_add( vector, r );
+
+ s = NULL;
+ }
+
+ D_FREE( values );
+}
+
+static void config_values_free( FusionVector *vector )
+{
+ char *value;
+ int i;
+
+ fusion_vector_foreach (value, i, *vector)
+ D_FREE( value );
+
+ fusion_vector_destroy( vector );
+ fusion_vector_init( vector, 2, NULL );
+}
+
+static int config_read_cmdline( char *cmdbuf, int size, FILE *f )
+{
+ int ret = 0;
+ int len = 0;
+
+ ret = fread( cmdbuf, 1, 1, f );
+
+ /* empty dividing 0 */
+ if( ret==1 && *cmdbuf==0 ) {
+ ret = fread( cmdbuf, 1, 1, f );
+ }
+
+ while(ret==1 && len<(size-1)) {
+ len++;
+ ret = fread( ++cmdbuf, 1, 1, f );
+ if( *cmdbuf == 0 )
+ break;
+ }
+
+ if( len ) {
+ cmdbuf[len]=0;
+ }
+
+ return len != 0;
+}
+
+/*
+ * The following function isn't used because the configuration should
+ * only go away if the application is completely terminated. In that case
+ * the memory is freed anyway.
+ */
+
+#if 0
+static void config_cleanup( void )
+{
+ if (!dfb_config) {
+ D_BUG("config_cleanup() called with no config allocated!");
+ return;
+ }
+
+ if (dfb_config->fb_device)
+ D_FREE( dfb_config->fb_device );
+
+ if (dfb_config->layer_bg_filename)
+ D_FREE( dfb_config->layer_bg_filename );
+
+ D_FREE( dfb_config );
+ dfb_config = NULL;
+}
+#endif
+
+/*
+ * allocates config and fills it with defaults
+ */
+static void config_allocate( void )
+{
+ int i;
+
+ if (dfb_config)
+ return;
+
+ dfb_config = (DFBConfig*) calloc( 1, sizeof(DFBConfig) );
+
+ for (i=0; i<D_ARRAY_SIZE(dfb_config->layers); i++) {
+ dfb_config->layers[i].src_key_index = -1;
+
+ dfb_config->layers[i].background.color.a = 0;
+ dfb_config->layers[i].background.color.r = 0;
+ dfb_config->layers[i].background.color.g = 0;
+ dfb_config->layers[i].background.color.b = 0;
+ dfb_config->layers[i].background.color_index = -1;
+ dfb_config->layers[i].background.mode = DLBM_COLOR;
+ }
+
+ dfb_config->layers[0].init = true;
+ dfb_config->layers[0].background.color.a = 0xff;
+ dfb_config->layers[0].background.color.r = 0xc0;
+ dfb_config->layers[0].background.color.g = 0xb0;
+ dfb_config->layers[0].background.color.b = 0x90;
+ dfb_config->layers[0].stacking = (1 << DWSC_UPPER) |
+ (1 << DWSC_MIDDLE) |
+ (1 << DWSC_LOWER);
+
+
+ dfb_config->pci.bus = 1;
+ dfb_config->pci.dev = 0;
+ dfb_config->pci.func = 0;
+
+ dfb_config->banner = true;
+ dfb_config->deinit_check = true;
+ dfb_config->mmx = true;
+ dfb_config->vt = true;
+ dfb_config->vt_switch = true;
+ dfb_config->vt_num = -1;
+ dfb_config->vt_switching = true;
+ dfb_config->kd_graphics = true;
+ dfb_config->translucent_windows = true;
+ dfb_config->font_premult = true;
+ dfb_config->mouse_motion_compression = false;
+ dfb_config->mouse_gpm_source = false;
+ dfb_config->mouse_source = D_STRDUP( DEV_NAME );
+ dfb_config->linux_input_grab = false;
+ dfb_config->window_policy = -1;
+ dfb_config->buffer_mode = -1;
+ dfb_config->wm = D_STRDUP( "default" );
+ dfb_config->decorations = true;
+ dfb_config->unichrome_revision = -1;
+ dfb_config->dma = false;
+ dfb_config->agp = 0;
+ dfb_config->matrox_tv_std = DSETV_PAL;
+ dfb_config->i8xx_overlay_pipe_b = false;
+ dfb_config->surface_shmpool_size = 64 * 1024 * 1024;
+ dfb_config->keep_accumulators = 1024;
+ dfb_config->font_format = DSPF_A8;
+ dfb_config->flip_notify_max_latency = 0;
+
+ /* default to fbdev */
+ dfb_config->system = D_STRDUP( "FBDev" );
+
+ /* default to no-vt-switch if we don't have root privileges */
+ if (geteuid())
+ dfb_config->vt_switch = false;
+
+ fusion_vector_init( &dfb_config->linux_input_devices, 2, NULL );
+ fusion_vector_init( &dfb_config->tslib_devices, 2, NULL );
+}
+
+const char *dfb_config_usage( void )
+{
+ return config_usage;
+}
+
+DFBResult dfb_config_set( const char *name, const char *value )
+{
+ if (strcmp (name, "system" ) == 0) {
+ if (value) {
+ if (dfb_config->system)
+ D_FREE( dfb_config->system );
+ dfb_config->system = D_STRDUP( value );
+ }
+ else {
+ D_ERROR("DirectFB/Config 'system': No system specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "wm" ) == 0) {
+ if (value) {
+ if (dfb_config->wm)
+ D_FREE( dfb_config->wm );
+ dfb_config->wm = D_STRDUP( value );
+ }
+ else {
+ D_ERROR("DirectFB/Config 'wm': No window manager specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "fbdev" ) == 0) {
+ if (value) {
+ if (dfb_config->fb_device)
+ D_FREE( dfb_config->fb_device );
+ dfb_config->fb_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR("DirectFB/Config 'fbdev': No device name specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "busid") == 0 || strcmp (name, "pci-id") == 0) {
+ if (value) {
+ int bus, dev, func;
+
+ if (sscanf( value, "%d:%d:%d", &bus, &dev, &func ) != 3) {
+ D_ERROR( "DirectFB/Config 'busid': Could not parse busid!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->pci.bus = bus;
+ dfb_config->pci.dev = dev;
+ dfb_config->pci.func = func;
+ }
+ } else
+ if (strcmp (name, "screenshot-dir" ) == 0) {
+ if (value) {
+ if (dfb_config->screenshot_dir)
+ D_FREE( dfb_config->screenshot_dir );
+ dfb_config->screenshot_dir = D_STRDUP( value );
+ }
+ else {
+ D_ERROR("DirectFB/Config 'screenshot-dir': No directory name specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "scaled" ) == 0) {
+ if (value) {
+ int width, height;
+
+ if (sscanf( value, "%dx%d", &width, &height ) < 2) {
+ D_ERROR("DirectFB/Config 'scaled': Could not parse size!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->scaled.width = width;
+ dfb_config->scaled.height = height;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'scaled': No size specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "primary-layer" ) == 0) {
+ if (value) {
+ int id;
+
+ if (sscanf( value, "%d", &id ) < 1) {
+ D_ERROR("DirectFB/Config 'primary-layer': Could not parse id!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->primary_layer = id;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'primary-layer': No id specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "primary-only" ) == 0) {
+ dfb_config->primary_only = true;
+ } else
+ if (strcmp (name, "font-format" ) == 0) {
+ if (value) {
+ DFBSurfacePixelFormat format;
+
+ format = dfb_config_parse_pixelformat( value );
+ if (format == DSPF_UNKNOWN) {
+ D_ERROR("DirectFB/Config 'font-format': Could not parse format!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->font_format = format;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'font-format': No format specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "font-premult" ) == 0) {
+ dfb_config->font_premult = true;
+ } else
+ if (strcmp (name, "no-font-premult" ) == 0) {
+ dfb_config->font_premult = false;
+ } else
+ if (!strcmp( name, "surface-shmpool-size" )) {
+ if (value) {
+ int size_kb;
+
+ if (sscanf( value, "%d", &size_kb ) < 1) {
+ D_ERROR( "DirectFB/Config '%s': Could not parse value!\n", name);
+ return DFB_INVARG;
+ }
+
+ dfb_config->surface_shmpool_size = size_kb * 1024;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "session" ) == 0) {
+ if (value) {
+ int session;
+
+ if (sscanf( value, "%d", &session ) < 1) {
+ D_ERROR("DirectFB/Config 'session': Could not parse value!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->session = session;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'session': No value specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "remote" ) == 0) {
+ if (value) {
+ char *colon;
+
+ colon = strchr( value, ':' );
+ if (colon) {
+ int len = (long) colon - (long) value;
+ int port = 0;
+
+ if (direct_sscanf( colon + 1, "%d", &port ) < 1) {
+ D_ERROR("DirectFB/Config 'remote': "
+ "Could not parse value (format is <host>[:<port>])!\n");
+ return DFB_INVARG;
+ }
+
+ if (dfb_config->remote.host)
+ D_FREE( dfb_config->remote.host );
+
+ dfb_config->remote.host = D_MALLOC( len+1 );
+ dfb_config->remote.session = port;
+
+ direct_snputs( dfb_config->remote.host, value, len+1 );
+ }
+ else {
+ if (dfb_config->remote.host)
+ D_FREE( dfb_config->remote.host );
+
+ dfb_config->remote.host = D_STRDUP( value );
+ dfb_config->remote.session = 0;
+ }
+ }
+ else {
+ if (dfb_config->remote.host)
+ D_FREE( dfb_config->remote.host );
+
+ dfb_config->remote.host = D_STRDUP( "" );
+ dfb_config->remote.session = 0;
+ }
+ } else
+ if (strcmp (name, "videoram-limit" ) == 0) {
+ if (value) {
+ int limit;
+
+ if (sscanf( value, "%d", &limit ) < 1) {
+ D_ERROR("DirectFB/Config 'videoram-limit': Could not parse value!\n");
+ return DFB_INVARG;
+ }
+
+ if (limit < 0)
+ limit = 0;
+
+ dfb_config->videoram_limit = limit << 10;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'videoram-limit': No value specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "keep-accumulators" ) == 0) {
+ if (value) {
+ int limit;
+
+ if (sscanf( value, "%d", &limit ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse value!\n", name);
+ return DFB_INVARG;
+ }
+
+ dfb_config->keep_accumulators = limit;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No value specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "banner" ) == 0) {
+ dfb_config->banner = true;
+ } else
+ if (strcmp (name, "no-banner" ) == 0) {
+ dfb_config->banner = false;
+ } else
+ if (strcmp (name, "surface-sentinel" ) == 0) {
+ dfb_config->surface_sentinel = true;
+ } else
+ if (strcmp (name, "no-surface-sentinel" ) == 0) {
+ dfb_config->surface_sentinel = false;
+ } else
+ if (strcmp (name, "force-windowed" ) == 0) {
+ dfb_config->force_windowed = true;
+ } else
+ if (strcmp (name, "force-desktop" ) == 0) {
+ dfb_config->force_desktop = true;
+ } else
+ if (strcmp (name, "hardware" ) == 0) {
+ dfb_config->software_only = false;
+ } else
+ if (strcmp (name, "no-hardware" ) == 0) {
+ dfb_config->software_only = true;
+ } else
+ if (strcmp (name, "software" ) == 0) {
+ dfb_config->hardware_only = false;
+ } else
+ if (strcmp (name, "no-software" ) == 0) {
+ dfb_config->hardware_only = true;
+ } else
+ if (strcmp (name, "software-warn" ) == 0) {
+ dfb_config->software_warn = true;
+ } else
+ if (strcmp (name, "no-software-warn" ) == 0) {
+ dfb_config->software_warn = false;
+ } else
+ if (strcmp (name, "software-trace" ) == 0) {
+ dfb_config->software_trace = true;
+ } else
+ if (strcmp (name, "no-software-trace" ) == 0) {
+ dfb_config->software_trace = false;
+ } else
+ if (strcmp (name, "warn" ) == 0 || strcmp (name, "no-warn" ) == 0) {
+ /* Enable/disable all at once by default. */
+ DFBConfigWarnFlags flags = DMT_ALL;
+
+ /* Find out the specific message type being configured. */
+ if (value) {
+ char *opt = strchr( value, ':' );
+
+ if (opt)
+ opt++;
+
+ if (!strncmp( value, "create-surface", 14 )) {
+ flags = DCWF_CREATE_SURFACE;
+
+ if (opt)
+ sscanf( opt, "%dx%d",
+ &dfb_config->warn.create_surface.min_size.w,
+ &dfb_config->warn.create_surface.min_size.h );
+ } else
+ if (!strncmp( value, "create-window", 13 )) {
+ flags = DCWF_CREATE_WINDOW;
+ } else
+ if (!strncmp( value, "allocate-buffer", 15 )) {
+ flags = DCWF_ALLOCATE_BUFFER;
+
+ if (opt)
+ sscanf( opt, "%dx%d",
+ &dfb_config->warn.allocate_buffer.min_size.w,
+ &dfb_config->warn.allocate_buffer.min_size.h );
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': Unknown warning type '%s'!\n", name, value );
+ return DFB_INVARG;
+ }
+ }
+
+ /* Set/clear the corresponding flag in the configuration. */
+ if (name[0] == 'w')
+ dfb_config->warn.flags |= flags;
+ else
+ dfb_config->warn.flags &= ~flags;
+ } else
+ if (strcmp (name, "dma" ) == 0) {
+ dfb_config->dma = true;
+ } else
+ if (strcmp (name, "no-dma" ) == 0) {
+ dfb_config->dma = false;
+ } else
+ if (strcmp (name, "mmx" ) == 0) {
+ dfb_config->mmx = true;
+ } else
+ if (strcmp (name, "no-mmx" ) == 0) {
+ dfb_config->mmx = false;
+ } else
+ if (strcmp (name, "agp" ) == 0) {
+ if (value) {
+ int mode;
+
+ if (sscanf( value, "%d", &mode ) < 1 || mode < 0 || mode > 8) {
+ D_ERROR( "DirectFB/Config 'agp': "
+ "invalid agp mode '%s'!\n", value );
+ return DFB_INVARG;
+ }
+
+ dfb_config->agp = mode;
+ }
+ else {
+ dfb_config->agp = 8; /* maximum possible */
+ }
+ } else
+ if (strcmp (name, "thrifty-surface-buffers" ) == 0) {
+ dfb_config->thrifty_surface_buffers = true;
+ } else
+ if (strcmp (name, "no-thrifty-surface-buffers" ) == 0) {
+ dfb_config->thrifty_surface_buffers = false;
+ } else
+ if (strcmp (name, "no-agp" ) == 0) {
+ dfb_config->agp = 0;
+ } else
+ if (strcmp (name, "agpmem-limit" ) == 0) {
+ if (value) {
+ int limit;
+
+ if (sscanf( value, "%d", &limit ) < 1) {
+ D_ERROR( "DirectFB/Config 'agpmem-limit': "
+ "Could not parse value!\n" );
+ return DFB_INVARG;
+ }
+
+ if (limit < 0)
+ limit = 0;
+
+ dfb_config->agpmem_limit = limit << 10;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'agpmem-limit': No value specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "vt" ) == 0) {
+ dfb_config->vt = true;
+ } else
+ if (strcmp (name, "no-vt" ) == 0) {
+ dfb_config->vt = false;
+ } else
+ if (strcmp (name, "block-all-signals" ) == 0) {
+ dfb_config->block_all_signals = true;
+ } else
+ if (strcmp (name, "deinit-check" ) == 0) {
+ dfb_config->deinit_check = true;
+ } else
+ if (strcmp (name, "no-deinit-check" ) == 0) {
+ dfb_config->deinit_check = false;
+ } else
+ if (strcmp (name, "cursor" ) == 0) {
+ dfb_config->no_cursor = false;
+ } else
+ if (strcmp (name, "no-cursor" ) == 0) {
+ dfb_config->no_cursor = true;
+ } else
+ if (strcmp (name, "cursor-updates" ) == 0) {
+ dfb_config->no_cursor_updates = false;
+ } else
+ if (strcmp (name, "no-cursor-updates" ) == 0) {
+ dfb_config->no_cursor_updates = true;
+ } else
+ if (strcmp (name, "linux-input-ir-only" ) == 0) {
+ dfb_config->linux_input_ir_only = true;
+ } else
+ if (strcmp (name, "linux-input-grab" ) == 0) {
+ dfb_config->linux_input_grab = true;
+ } else
+ if (strcmp (name, "no-linux-input-grab" ) == 0) {
+ dfb_config->linux_input_grab = false;
+ } else
+ if (strcmp (name, "motion-compression" ) == 0) {
+ dfb_config->mouse_motion_compression = true;
+ } else
+ if (strcmp (name, "no-motion-compression" ) == 0) {
+ dfb_config->mouse_motion_compression = false;
+ } else
+ if (strcmp (name, "mouse-protocol" ) == 0) {
+ if (value) {
+ dfb_config->mouse_protocol = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No mouse protocol specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "mouse-source" ) == 0) {
+ if (value) {
+ D_FREE( dfb_config->mouse_source );
+ dfb_config->mouse_source = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No mouse source specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "mouse-gpm-source" ) == 0) {
+ dfb_config->mouse_gpm_source = true;
+ D_FREE( dfb_config->mouse_source );
+ dfb_config->mouse_source = D_STRDUP( DEV_NAME_GPM );
+ } else
+ if (strcmp (name, "no-mouse-gpm-source" ) == 0) {
+ dfb_config->mouse_gpm_source = false;
+ D_FREE( dfb_config->mouse_source );
+ dfb_config->mouse_source = D_STRDUP( DEV_NAME );
+ } else
+ if (strcmp (name, "smooth-upscale" ) == 0) {
+ dfb_config->render_options |= DSRO_SMOOTH_UPSCALE;
+ } else
+ if (strcmp (name, "no-smooth-upscale" ) == 0) {
+ dfb_config->render_options &= ~DSRO_SMOOTH_UPSCALE;
+ } else
+ if (strcmp (name, "smooth-downscale" ) == 0) {
+ dfb_config->render_options |= DSRO_SMOOTH_DOWNSCALE;
+ } else
+ if (strcmp (name, "no-smooth-downscale" ) == 0) {
+ dfb_config->render_options &= ~DSRO_SMOOTH_DOWNSCALE;
+ } else
+ if (strcmp (name, "translucent-windows" ) == 0) {
+ dfb_config->translucent_windows = true;
+ } else
+ if (strcmp (name, "no-translucent-windows" ) == 0) {
+ dfb_config->translucent_windows = false;
+ } else
+ if (strcmp (name, "decorations" ) == 0) {
+ dfb_config->decorations = true;
+ } else
+ if (strcmp (name, "no-decorations" ) == 0) {
+ dfb_config->decorations = false;
+ } else
+ if (strcmp (name, "startstop" ) == 0) {
+ dfb_config->startstop = true;
+ } else
+ if (strcmp (name, "no-startstop" ) == 0) {
+ dfb_config->startstop = false;
+ } else
+ if (strcmp (name, "autoflip-window" ) == 0) {
+ dfb_config->autoflip_window = true;
+ } else
+ if (strcmp (name, "no-autoflip-window" ) == 0) {
+ dfb_config->autoflip_window = false;
+ } else
+ if (strcmp (name, "discard-repeat-events" ) == 0) {
+ dfb_config->discard_repeat_events = true;
+ } else
+ if (strcmp (name, "no-discard-repeat-events" ) == 0) {
+ dfb_config->discard_repeat_events = false;
+ } else
+ if (strcmp (name, "vsync-none" ) == 0) {
+ dfb_config->pollvsync_none = true;
+ } else
+ if (strcmp (name, "vsync-after" ) == 0) {
+ dfb_config->pollvsync_after = true;
+ } else
+ if (strcmp (name, "vt-switch" ) == 0) {
+ dfb_config->vt_switch = true;
+ } else
+ if (strcmp (name, "no-vt-switch" ) == 0) {
+ dfb_config->vt_switch = false;
+ } else
+ if (strcmp (name, "vt-num" ) == 0) {
+ if (value) {
+ int vt_num;
+
+ if (sscanf( value, "%d", &vt_num ) < 1) {
+ D_ERROR("DirectFB/Config 'vt-num': Could not parse value!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->vt_num = vt_num;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'vt-num': No value specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "vt-switching" ) == 0) {
+ dfb_config->vt_switching = true;
+ } else
+ if (strcmp (name, "no-vt-switching" ) == 0) {
+ dfb_config->vt_switching = false;
+ } else
+ if (strcmp (name, "graphics-vt" ) == 0) {
+ dfb_config->kd_graphics = true;
+ } else
+ if (strcmp (name, "no-graphics-vt" ) == 0) {
+ dfb_config->kd_graphics = false;
+ } else
+ if (strcmp (name, "window-surface-policy" ) == 0) {
+ if (value) {
+ if (strcmp( value, "auto" ) == 0) {
+ dfb_config->window_policy = -1;
+ } else
+ if (strcmp( value, "videohigh" ) == 0) {
+ dfb_config->window_policy = CSP_VIDEOHIGH;
+ } else
+ if (strcmp( value, "videolow" ) == 0) {
+ dfb_config->window_policy = CSP_VIDEOLOW;
+ } else
+ if (strcmp( value, "systemonly" ) == 0) {
+ dfb_config->window_policy = CSP_SYSTEMONLY;
+ } else
+ if (strcmp( value, "videoonly" ) == 0) {
+ dfb_config->window_policy = CSP_VIDEOONLY;
+ }
+ else {
+ D_ERROR( "DirectFB/Config: "
+ "Unknown window surface policy `%s'!\n", value );
+ return DFB_INVARG;
+ }
+ }
+ else {
+ D_ERROR( "DirectFB/Config: "
+ "No window surface policy specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "init-layer" ) == 0) {
+ if (value) {
+ int id;
+
+ if (sscanf( value, "%d", &id ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse id!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (id < 0 || id > D_ARRAY_SIZE(dfb_config->layers)) {
+ D_ERROR("DirectFB/Config '%s': ID %d out of bounds!\n", name, id);
+ return DFB_INVARG;
+ }
+
+ dfb_config->layers[id].init = true;
+
+ dfb_config->config_layer = &dfb_config->layers[id];
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No id specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "no-init-layer" ) == 0) {
+ if (value) {
+ int id;
+
+ if (sscanf( value, "%d", &id ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse id!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (id < 0 || id > D_ARRAY_SIZE(dfb_config->layers)) {
+ D_ERROR("DirectFB/Config '%s': ID %d out of bounds!\n", name, id);
+ return DFB_INVARG;
+ }
+
+ dfb_config->layers[id].init = false;
+
+ dfb_config->config_layer = &dfb_config->layers[id];
+ }
+ else
+ dfb_config->layers[0].init = false;
+ } else
+ if (strcmp (name, "mode" ) == 0 || strcmp (name, "layer-size" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ int width, height;
+
+ if (sscanf( value, "%dx%d", &width, &height ) < 2) {
+ D_ERROR("DirectFB/Config '%s': Could not parse width and height!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (conf == &dfb_config->layers[0]) {
+ dfb_config->mode.width = width;
+ dfb_config->mode.height = height;
+ }
+
+ conf->config.width = width;
+ conf->config.height = height;
+
+ conf->config.flags |= DLCONF_WIDTH | DLCONF_HEIGHT;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No width and height specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "depth" ) == 0 || strcmp (name, "layer-depth" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ int depth;
+
+ if (sscanf( value, "%d", &depth ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse value!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (conf == &dfb_config->layers[0]) {
+ dfb_config->mode.depth = depth;
+ }
+
+ conf->config.pixelformat = dfb_pixelformat_for_depth( depth );
+ conf->config.flags |= DLCONF_PIXELFORMAT;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No value specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "pixelformat" ) == 0 || strcmp (name, "layer-format" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ DFBSurfacePixelFormat format;
+
+ format = dfb_config_parse_pixelformat( value );
+ if (format == DSPF_UNKNOWN) {
+ D_ERROR("DirectFB/Config '%s': Could not parse format!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (conf == &dfb_config->layers[0])
+ dfb_config->mode.format = format;
+
+ conf->config.pixelformat = format;
+ conf->config.flags |= DLCONF_PIXELFORMAT;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No format specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "desktop-buffer-mode" ) == 0 || strcmp (name, "layer-buffer-mode" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ if (strcmp( value, "auto" ) == 0) {
+ conf->config.flags &= ~DLCONF_BUFFERMODE;
+ } else
+ if (strcmp( value, "triple" ) == 0) {
+ conf->config.buffermode = DLBM_TRIPLE;
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ } else
+ if (strcmp( value, "backvideo" ) == 0) {
+ conf->config.buffermode = DLBM_BACKVIDEO;
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ } else
+ if (strcmp( value, "backsystem" ) == 0) {
+ conf->config.buffermode = DLBM_BACKSYSTEM;
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ } else
+ if (strcmp( value, "frontonly" ) == 0) {
+ conf->config.buffermode = DLBM_FRONTONLY;
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ } else
+ if (strcmp( value, "windows" ) == 0) {
+ conf->config.buffermode = DLBM_WINDOWS;
+ conf->config.flags |= DLCONF_BUFFERMODE;
+ } else {
+ D_ERROR( "DirectFB/Config '%s': Unknown mode '%s'!\n", name, value );
+ return DFB_INVARG;
+ }
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No buffer mode specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "layer-src-key" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ char *error;
+ u32 argb;
+
+ argb = strtoul( value, &error, 16 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in color '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ conf->src_key.b = argb & 0xFF;
+ argb >>= 8;
+ conf->src_key.g = argb & 0xFF;
+ argb >>= 8;
+ conf->src_key.r = argb & 0xFF;
+ argb >>= 8;
+ conf->src_key.a = argb & 0xFF;
+
+ conf->config.options |= DLOP_SRC_COLORKEY;
+ conf->config.flags |= DLCONF_OPTIONS;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No color specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "layer-src-key-index" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ char *error;
+ u32 index;
+
+ index = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in index '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ conf->src_key_index = index;
+ conf->config.options |= DLOP_SRC_COLORKEY;
+ conf->config.flags |= DLCONF_OPTIONS;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No index specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "bg-none" ) == 0 || strcmp (name, "layer-bg-none" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ conf->background.mode = DLBM_DONTCARE;
+ } else
+ if (strcmp (name, "bg-image" ) == 0 || strcmp (name, "bg-tile" ) == 0 ||
+ strcmp (name, "layer-bg-image" ) == 0 || strcmp (name, "layer-bg-tile" ) == 0)
+ {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ if (conf->background.filename)
+ D_FREE( conf->background.filename );
+
+ conf->background.filename = D_STRDUP( value );
+ conf->background.mode = strcmp (name, "bg-tile" ) ? DLBM_IMAGE : DLBM_TILE;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No filename specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "bg-color" ) == 0 || strcmp (name, "layer-bg-color" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ char *error;
+ u32 argb;
+
+ argb = strtoul( value, &error, 16 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in color '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ conf->background.color.b = argb & 0xFF;
+ argb >>= 8;
+ conf->background.color.g = argb & 0xFF;
+ argb >>= 8;
+ conf->background.color.r = argb & 0xFF;
+ argb >>= 8;
+ conf->background.color.a = argb & 0xFF;
+
+ conf->background.color_index = -1;
+ conf->background.mode = DLBM_COLOR;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No color specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "layer-bg-color-index" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ char *error;
+ u32 index;
+
+ index = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in index '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ conf->background.color_index = index;
+ conf->background.mode = DLBM_COLOR;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No index specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "layer-stacking" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ char *stackings = D_STRDUP( value );
+ char *p = NULL, *r, *s = stackings;
+
+ conf->stacking = 0;
+
+ while ((r = strtok_r( s, ",", &p ))) {
+ direct_trim( &r );
+
+ if (!strcmp( r, "lower" ))
+ conf->stacking |= (1 << DWSC_LOWER);
+ else if (!strcmp( r, "middle" ))
+ conf->stacking |= (1 << DWSC_MIDDLE);
+ else if (!strcmp( r, "upper" ))
+ conf->stacking |= (1 << DWSC_UPPER);
+ else {
+ D_ERROR( "DirectFB/Config '%s': Unknown class '%s'!\n", name, r );
+ D_FREE( stackings );
+ return DFB_INVARG;
+ }
+
+ s = NULL;
+ }
+
+ D_FREE( stackings );
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': Missing value!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strncmp (name, "layer-palette-", 14 ) == 0) {
+ int index;
+ char *error;
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ index = strtoul( name + 14, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in index '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ if (index < 0 || index > 255) {
+ D_ERROR("DirectFB/Config '%s': Index %d out of bounds!\n", name, index);
+ return DFB_INVARG;
+ }
+
+ if (value) {
+ char *error;
+ u32 argb;
+
+ argb = strtoul( value, &error, 16 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in color '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ if (!conf->palette) {
+ conf->palette = D_CALLOC( 256, sizeof(DFBColor) );
+ if (!conf->palette)
+ return D_OOM();
+ }
+
+ conf->palette[index].a = (argb & 0xFF000000) >> 24;
+ conf->palette[index].r = (argb & 0xFF0000) >> 16;
+ conf->palette[index].g = (argb & 0xFF00) >> 8;
+ conf->palette[index].b = (argb & 0xFF);
+
+ conf->palette_set = true;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No color specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "layer-rotate" ) == 0) {
+ DFBConfigLayer *conf = dfb_config->config_layer;
+
+ if (value) {
+ int rotate;
+
+ if (sscanf( value, "%d", &rotate ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse value!\n", name);
+ return DFB_INVARG;
+ }
+
+ if (rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
+ D_ERROR("DirectFB/Config '%s': Only 0, 90, 180 or 270 supported!\n", name);
+ return DFB_UNSUPPORTED;
+ }
+
+ conf->rotate = rotate;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No value specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "video-phys" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long phys;
+
+ phys = strtoul( value, &error, 16 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in hex value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->video_phys = phys;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "video-length" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long length;
+
+ length = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->video_length = length;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "mmio-phys" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long phys;
+
+ phys = strtoul( value, &error, 16 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in hex value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->mmio_phys = phys;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "mmio-length" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long length;
+
+ length = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->mmio_length = length;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "accelerator" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long accel;
+
+ accel = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->accelerator = accel;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "matrox-tv-standard" ) == 0) {
+ if (value) {
+ if (strcmp( value, "pal-60" ) == 0) {
+ dfb_config->matrox_tv_std = DSETV_PAL_60;
+ } else
+ if (strcmp( value, "pal" ) == 0) {
+ dfb_config->matrox_tv_std = DSETV_PAL;
+ } else
+ if (strcmp( value, "ntsc" ) == 0) {
+ dfb_config->matrox_tv_std = DSETV_NTSC;
+ } else {
+ D_ERROR( "DirectFB/Config: Unknown TV standard "
+ "'%s'!\n", value );
+ return DFB_INVARG;
+ }
+ }
+ else {
+ D_ERROR( "DirectFB/Config: "
+ "No TV standard specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "matrox-cable-type" ) == 0) {
+ if (value) {
+ if (strcmp( value, "composite" ) == 0) {
+ dfb_config->matrox_cable = 0;
+ } else
+ if (strcmp( value, "scart-rgb" ) == 0) {
+ dfb_config->matrox_cable = 1;
+ } else
+ if (strcmp( value, "scart-composite" ) == 0) {
+ dfb_config->matrox_cable = 2;
+ } else {
+ D_ERROR( "DirectFB/Config: Unknown cable type "
+ "'%s'!\n", value );
+ return DFB_INVARG;
+ }
+ }
+ else {
+ D_ERROR( "DirectFB/Config: "
+ "No cable type specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "matrox-sgram" ) == 0) {
+ dfb_config->matrox_sgram = true;
+ } else
+ if (strcmp (name, "matrox-crtc2" ) == 0) {
+ dfb_config->matrox_crtc2 = true;
+ } else
+ if (strcmp (name, "no-matrox-sgram" ) == 0) {
+ dfb_config->matrox_sgram = false;
+ } else
+ if (strcmp (name, "sync" ) == 0) {
+ dfb_config->sync = true;
+ } else
+ if (strcmp (name, "no-sync" ) == 0) {
+ dfb_config->sync = false;
+ } else
+ if (strcmp (name, "lefty" ) == 0) {
+ dfb_config->lefty = true;
+ } else
+ if (strcmp (name, "no-lefty" ) == 0) {
+ dfb_config->lefty = false;
+ } else
+ if (strcmp (name, "capslock-meta" ) == 0) {
+ dfb_config->capslock_meta = true;
+ } else
+ if (strcmp (name, "no-capslock-meta" ) == 0) {
+ dfb_config->capslock_meta = false;
+ } else
+ if (strcmp (name, "h3600-device" ) == 0) {
+ if (value) {
+ if (dfb_config->h3600_device)
+ D_FREE( dfb_config->h3600_device );
+
+ dfb_config->h3600_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No H3600 TS device specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "mut-device" ) == 0) {
+ if (value) {
+ if (dfb_config->mut_device)
+ D_FREE( dfb_config->mut_device );
+
+ dfb_config->mut_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No MuTouch device specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "zytronic-device" ) == 0) {
+ if (value) {
+ if (dfb_config->zytronic_device)
+ D_FREE( dfb_config->zytronic_device );
+
+ dfb_config->zytronic_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No Zytronic device specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "elo-device" ) == 0) {
+ if (value) {
+ if (dfb_config->elo_device)
+ D_FREE( dfb_config->elo_device );
+
+ dfb_config->elo_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No Elo device specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "penmount-device" ) == 0) {
+ if (value) {
+ if (dfb_config->penmount_device)
+ D_FREE( dfb_config->penmount_device );
+
+ dfb_config->penmount_device = D_STRDUP( value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: No PenMount device specified!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "linux-input-devices" ) == 0) {
+ if (value) {
+ config_values_free( &dfb_config->linux_input_devices );
+ config_values_parse( &dfb_config->linux_input_devices, value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: Missing value for linux-input-devices!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "tslib-devices" ) == 0) {
+ if (value) {
+ config_values_free( &dfb_config->tslib_devices );
+ config_values_parse( &dfb_config->tslib_devices, value );
+ }
+ else {
+ D_ERROR( "DirectFB/Config: Missing value for tslib-devices!\n" );
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "unichrome-revision" ) == 0) {
+ if (value) {
+ int rev;
+
+ if (sscanf( value, "%d", &rev ) < 1) {
+ D_ERROR("DirectFB/Config 'unichrome-revision': Could not parse revision!\n");
+ return DFB_INVARG;
+ }
+
+ dfb_config->unichrome_revision = rev;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'unichrome-revision': No revision specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "i8xx_overlay_pipe_b") == 0) {
+ dfb_config->i8xx_overlay_pipe_b = true;
+ } else
+ if (strcmp (name, "window-cursor-invisible") == 0) {
+ dfb_config->default_cursor_flags = DWCF_INVISIBLE;
+ } else
+ if (strcmp (name, "max-axis-rate" ) == 0) {
+ if (value) {
+ unsigned int rate;
+
+ if (sscanf( value, "%u", &rate ) < 1) {
+ D_ERROR("DirectFB/Config '%s': Could not parse value!\n", name);
+ return DFB_INVARG;
+ }
+
+ dfb_config->max_axis_rate = rate;
+ }
+ else {
+ D_ERROR("DirectFB/Config '%s': No value specified!\n", name);
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "include") == 0) {
+ if( value ) {
+ DFBResult ret;
+ ret = dfb_config_read( value );
+ if( ret )
+ return ret;
+ }
+ else {
+ D_ERROR("DirectFB/Config 'include': No include file specified!\n");
+ return DFB_INVARG;
+ }
+ } else
+ if (strcmp (name, "flip-notify-max-latency" ) == 0) {
+ if (value) {
+ char *error;
+ unsigned long latency;
+
+ latency = strtoul( value, &error, 10 );
+
+ if (*error) {
+ D_ERROR( "DirectFB/Config '%s': Error in value '%s'!\n", name, error );
+ return DFB_INVARG;
+ }
+
+ dfb_config->flip_notify_max_latency = latency;
+ }
+ else {
+ D_ERROR( "DirectFB/Config '%s': No value specified!\n", name );
+ return DFB_INVARG;
+ }
+ } else
+ if (voodoo_config_set( name, value ) && fusion_config_set( name, value ) && direct_config_set( name, value ))
+ return DFB_UNSUPPORTED;
+
+ return DFB_OK;
+}
+
+DFBResult dfb_config_init( int *argc, char *(*argv[]) )
+{
+ DFBResult ret;
+ int i;
+ char *home = getenv( "HOME" );
+ char *prog = NULL;
+ char *session;
+ char *dfbargs;
+ char cmdbuf[1024];
+
+ if (dfb_config)
+ return DFB_OK;
+
+ config_allocate();
+
+ /* Read system settings. */
+ ret = dfb_config_read( SYSCONFDIR"/directfbrc" );
+ if (ret && ret != DFB_IO)
+ return ret;
+
+ /* Read user settings. */
+ if (home) {
+ int len = strlen(home) + strlen("/.directfbrc") + 1;
+ char buf[len];
+
+ snprintf( buf, len, "%s/.directfbrc", home );
+
+ ret = dfb_config_read( buf );
+ if (ret && ret != DFB_IO)
+ return ret;
+ }
+
+ /* Get application name. */
+ if (argc && *argc && argv && *argv) {
+ prog = strrchr( (*argv)[0], '/' );
+
+ if (prog)
+ prog++;
+ else
+ prog = (*argv)[0];
+ }
+ else {
+ /* if we didn't receive argc/argv we try the proc system */
+ FILE *f;
+ int len;
+
+ f = fopen( "/proc/self/cmdline", "r" );
+ if (f) {
+ len = fread( cmdbuf, 1, 1023, f );
+ if (len) {
+ cmdbuf[len] = 0; /* in case of no arguments, or long program name */
+ prog = strrchr( cmdbuf, '/' );
+ if (prog)
+ prog++;
+ else
+ prog = cmdbuf;
+ }
+ fprintf(stderr,"commandline read: %s\n", prog );
+ fclose( f );
+ }
+ }
+
+ /* Strip lt- prefix. */
+ if (prog) {
+ if (prog[0] == 'l' && prog[1] == 't' && prog[2] == '-')
+ prog += 3;
+ }
+
+ /* Read global application settings. */
+ if (prog && prog[0]) {
+ int len = strlen( SYSCONFDIR"/directfbrc." ) + strlen(prog) + 1;
+ char buf[len];
+
+ snprintf( buf, len, SYSCONFDIR"/directfbrc.%s", prog );
+
+ ret = dfb_config_read( buf );
+ if (ret && ret != DFB_IO)
+ return ret;
+ }
+
+ /* Read user application settings. */
+ if (home && prog && prog[0]) {
+ int len = strlen(home) + strlen("/.directfbrc.") + strlen(prog) + 1;
+ char buf[len];
+
+ snprintf( buf, len, "%s/.directfbrc.%s", home, prog );
+
+ ret = dfb_config_read( buf );
+ if (ret && ret != DFB_IO)
+ return ret;
+ }
+
+ /* Read settings from environment variable. */
+ dfbargs = getenv( "DFBARGS" );
+ if (dfbargs) {
+ ret = parse_args( dfbargs );
+ if (ret)
+ return ret;
+ }
+
+ /* Active session is used if present, only command line can override. */
+ session = getenv( "DIRECTFB_SESSION" );
+ if (session)
+ dfb_config_set( "session", session );
+
+ /* Read settings from command line. */
+ if (argc && argv) {
+ for (i = 1; i < *argc; i++) {
+
+ if (strcmp ((*argv)[i], "--dfb-help") == 0) {
+ print_config_usage();
+ exit(1);
+ }
+
+ if (strncmp ((*argv)[i], "--dfb:", 6) == 0) {
+ ret = parse_args( (*argv)[i] + 6 );
+ if (ret)
+ return ret;
+
+ (*argv)[i] = NULL;
+ }
+ }
+
+ for (i = 1; i < *argc; i++) {
+ int k;
+
+ for (k = i; k < *argc; k++)
+ if ((*argv)[k] != NULL)
+ break;
+
+ if (k > i) {
+ int j;
+
+ k -= i;
+
+ for (j = i + k; j < *argc; j++)
+ (*argv)[j-k] = (*argv)[j];
+
+ *argc -= k;
+ }
+ }
+ }
+ else if (prog) {
+ /* we have prog, so we try again the proc filesystem */
+ FILE *f;
+ int len;
+
+ len = strlen( cmdbuf );
+ f = fopen( "/proc/self/cmdline", "r" );
+ if (f) {
+ len = fread( cmdbuf, 1, len, f ); /* skip arg 0 */
+ while( config_read_cmdline( cmdbuf, 1024, f ) ) {
+ fprintf(stderr,"commandline read: %s\n", cmdbuf );
+ if (strcmp (cmdbuf, "--dfb-help") == 0) {
+ print_config_usage();
+ exit(1);
+ }
+
+ if (strncmp (cmdbuf, "--dfb:", 6) == 0) {
+ ret = parse_args( cmdbuf + 6 );
+ if (ret) {
+ fclose( f );
+ return ret;
+ }
+ }
+ }
+ fclose( f );
+ }
+ }
+
+ if (!dfb_config->vt_switch)
+ dfb_config->kd_graphics = true;
+
+ return DFB_OK;
+}
+
+DFBResult dfb_config_read( const char *filename )
+{
+ DFBResult ret = DFB_OK;
+ char line[400];
+ FILE *f;
+
+ char *slash = 0;
+ char *cwd = 0;
+
+ config_allocate();
+
+ dfb_config->config_layer = &dfb_config->layers[0];
+
+ f = fopen( filename, "r" );
+ if (!f) {
+ D_DEBUG_AT( DirectFB_Config, "Unable to open config file `%s'!\n", filename );
+ return DFB_IO;
+ } else {
+ D_DEBUG_AT( DirectFB_Config, "Parsing config file '%s'.\n", filename );
+ }
+
+ /* store/restore the cwd (needed for the "include" command */
+ slash = strrchr( filename, '/' );
+ if( slash ) {
+ cwd = getcwd(0,0);
+ if( !cwd )
+ return D_OOM();
+
+ /* must copy filename for path, due to const'ness */
+ char nwd[strlen(filename)];
+ strcpy( nwd, filename );
+ nwd[slash-filename] = 0;
+ chdir( nwd );
+
+ D_DEBUG_AT( DirectFB_Config, "changing configuration lookup directory to '%s'.\n", nwd );
+ }
+
+ while (fgets( line, 400, f )) {
+ char *name = line;
+ char *comment = strchr( line, '#');
+ char *value;
+
+ if (comment) {
+ *comment = 0;
+ }
+
+ value = strchr( line, '=' );
+
+ if (value) {
+ *value++ = 0;
+ direct_trim( &value );
+ }
+
+ direct_trim( &name );
+
+ if (!*name || *name == '#')
+ continue;
+
+ ret = dfb_config_set( name, value );
+ if (ret) {
+ if (ret == DFB_UNSUPPORTED) {
+ D_ERROR( "DirectFB/Config: *********** In config file `%s': "
+ "Invalid option `%s'! ***********\n", filename, name );
+ ret = DFB_OK;
+ continue;
+ }
+ break;
+ }
+ }
+
+ fclose( f );
+
+ /* restore original cwd */
+ if( cwd ) {
+ chdir( cwd );
+ free( cwd );
+ }
+
+ return ret;
+}
+
diff --git a/Source/DirectFB/src/misc/conf.h b/Source/DirectFB/src/misc/conf.h
new file mode 100755
index 0000000..49b5e9a
--- /dev/null
+++ b/Source/DirectFB/src/misc/conf.h
@@ -0,0 +1,287 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __CONF_H__
+#define __CONF_H__
+
+#include <signal.h>
+
+#include <directfb.h>
+#include <fusion/types.h>
+#include <fusion/vector.h>
+
+#include <core/coredefs.h>
+
+
+typedef struct {
+ bool init;
+
+ DFBDisplayLayerConfig config;
+ DFBColor src_key;
+ int src_key_index;
+
+ struct {
+ DFBDisplayLayerBackgroundMode mode;
+ DFBColor color;
+ int color_index;
+ char *filename;
+ } background;
+
+ DFBWindowStackingClass stacking;
+
+ DFBColor *palette;
+ bool palette_set;
+
+ int rotate;
+} DFBConfigLayer;
+
+typedef enum {
+ DCWF_NONE = 0x00000000,
+
+ DCWF_CREATE_SURFACE = 0x00000001,
+ DCWF_CREATE_WINDOW = 0x00000002,
+
+ DCWF_ALLOCATE_BUFFER = 0x00000010,
+
+ DCWF_ALL = 0x00000013,
+} DFBConfigWarnFlags;
+
+typedef struct
+{
+ bool mouse_motion_compression; /* use motion compression? */
+ char *mouse_protocol; /* mouse protocol */
+ char *mouse_source; /* mouse source device name */
+ bool mouse_gpm_source; /* mouse source is gpm? */
+
+ int window_policy; /* swapping policy for the
+ surface of a window */
+ int buffer_mode; /* default buffer mode for
+ primary layer */
+
+ bool pollvsync_after;
+ bool pollvsync_none;
+
+ bool software_only; /* disable hardware acceleration */
+ bool hardware_only; /* disable software fallbacks */
+
+ bool mmx; /* mmx support */
+
+ bool banner; /* startup banner */
+
+ bool force_windowed; /* prohibit exclusive modes */
+
+ bool deinit_check;
+
+ bool vt_switch; /* allocate a new VT */
+ int vt_num; /* number of TTY to use or -1
+ if the default */
+ bool kd_graphics; /* put terminal into graphics
+ mode */
+
+ DFBScreenEncoderTVStandards matrox_tv_std; /* Matrox TV standard */
+ int matrox_cable; /* Matrox cable type */
+ bool matrox_sgram; /* Use Matrox SGRAM features */
+ bool matrox_crtc2; /* Experimental CRTC2 stuff */
+
+ bool sync; /* Do sync() in core_init() */
+ bool vt_switching; /* Allow VT switching by
+ pressing Ctrl+Alt+<F?> */
+
+ char *fb_device; /* Used framebuffer device,
+ e.g. "/dev/fb0" */
+
+ struct {
+ int bus; /* PCI Bus */
+ int dev; /* PCI Device */
+ int func; /* PCI Function */
+ } pci;
+
+ bool lefty; /* Left handed mouse, swaps
+ left/right mouse buttons */
+ bool no_cursor; /* Never create a cursor */
+ bool translucent_windows; /* Allow translucent
+ windows */
+
+ struct {
+ int width; /* primary layer width */
+ int height; /* primary layer height */
+ int depth; /* primary layer depth */
+ DFBSurfacePixelFormat format; /* primary layer format */
+ } mode;
+
+ struct {
+ int width; /* scaled window width */
+ int height; /* scaled window height */
+ } scaled;
+
+ int videoram_limit; /* limit amount of video
+ memory used by DirectFB */
+
+ char *screenshot_dir; /* dump screen content into
+ this directory */
+
+ char *system; /* FBDev, SDL, etc. */
+
+ bool capslock_meta; /* map CapsLock -> Meta */
+
+ bool block_all_signals; /* block all signals */
+
+ int session; /* select multi app world */
+
+ int primary_layer; /* select alternative primary
+ display layer */
+
+ bool force_desktop; /* Desktop background is
+ the primary surface. */
+
+ bool linux_input_ir_only; /* Ignore non-IR devices. */
+
+ struct {
+ char *host; /* Remote host to connect to. */
+ int session; /* Remote session number. */
+ } remote;
+
+ char *wm; /* Window manager to use. */
+
+ bool vt; /* Use VT stuff at all? */
+
+ bool decorations; /* Enable window decorations. */
+
+ DFBSurfacePixelFormat font_format; /* Preferred font format. */
+
+ char *h3600_device; /* H3600 Touchscreen Device */
+
+ char *mut_device; /* MuTouch Device */
+
+ char *penmount_device; /* PenMount Device */
+
+ char *zytronic_device; /* Zytronic Device */
+
+ char *elo_device; /* elo Device */
+
+ int unichrome_revision; /* Unichrome hardware
+ revision number override */
+
+ bool dma; /* Enable DMA */
+
+ int agp; /* AGP mode */
+ int agpmem_limit; /* Limit of AGP memory
+ used by DirectFB */
+ bool i8xx_overlay_pipe_b; /* video overlay output via pixel pipe B */
+ bool primary_only; /* tell application only about primary layer */
+
+ bool thrifty_surface_buffers; /* don't keep system instance while video instance is alive */
+ bool surface_sentinel;
+
+ DFBConfigLayer layers[MAX_LAYERS];
+ DFBConfigLayer *config_layer;
+
+ DFBSurfaceRenderOptions render_options; /* default render options */
+
+ bool startstop; /* Issue StartDrawing/StopDrawing to driver */
+
+ unsigned long video_phys; /* Physical base address of video memory */
+ unsigned int video_length; /* Size of video memory */
+ unsigned long mmio_phys; /* Physical base address of MMIO area */
+ unsigned int mmio_length; /* Size of MMIO area */
+ int accelerator; /* Accelerator ID */
+
+ bool font_premult; /* Use premultiplied data in case of ARGB glyph images */
+
+ FusionVector linux_input_devices;
+ FusionVector tslib_devices;
+
+ bool thread_block_signals; /* Call direct_signals_block_all() in direct_thread_main() startup. */
+
+ bool linux_input_grab; /* Grab input devices. */
+
+ bool autoflip_window; /* If primary surface is non-flipping, but windowed, flip automatically. */
+ bool software_warn; /* Show warnings when doing/dropping software operations. */
+
+ int surface_shmpool_size; /* Set the size of the shared memory pool used for
+ shared system memory surfaces. */
+
+ bool no_cursor_updates; /* Never show the cursor etc. */
+
+ struct {
+ DFBConfigWarnFlags flags; /* Warn on various actions as window/surface creation. */
+
+ struct {
+ DFBDimension min_size;
+ } create_surface;
+
+ struct {
+ DFBDimension min_size;
+ } allocate_buffer;
+ } warn;
+
+ int keep_accumulators; /* Free accumulators above this limit */
+
+ bool software_trace;
+
+ unsigned int max_axis_rate;
+
+ unsigned int flip_notify_max_latency;
+
+ DFBWindowCursorFlags default_cursor_flags;
+
+ bool discard_repeat_events;
+} DFBConfig;
+
+extern DFBConfig *dfb_config;
+
+/*
+ * Allocate Config struct, fill with defaults and parse command line options
+ * for overrides. Options identified as DirectFB options are stripped out
+ * of the array.
+ */
+DFBResult dfb_config_init( int *argc, char *(*argv[]) );
+
+/*
+ * Read configuration options from file. Called by config_init().
+ *
+ * Returns DFB_IO if config file could not be opened.
+ * Returns DFB_UNSUPPORTED if file contains an invalid option.
+ * Returns DFB_INVARG if an invalid option assignment is done,
+ * e.g. "--desktop-buffer-mode=somethingwrong".
+ */
+DFBResult dfb_config_read( const char *filename );
+
+
+/*
+ * Set indiviual option. Used by config_init(), config_read() and
+ * DirectFBSetOption()
+ */
+DFBResult dfb_config_set( const char *name, const char *value );
+
+const char *dfb_config_usage( void );
+
+DFBSurfacePixelFormat dfb_config_parse_pixelformat( const char *format );
+
+#endif
+
diff --git a/Source/DirectFB/src/misc/dither565.h b/Source/DirectFB/src/misc/dither565.h
new file mode 100755
index 0000000..5231aee
--- /dev/null
+++ b/Source/DirectFB/src/misc/dither565.h
@@ -0,0 +1,211 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __DITHER565_H__
+#define __DITHER565_H__
+
+
+#ifndef DIRECTFB_VERSION
+#error config.h must be included prior to dither565.h
+#endif
+
+
+/* Dither matrices
+ * ---------------
+ *
+ * Preprocessed matrices for 5-6-5 RGB displays, taken from GdkRGB.
+ */
+
+
+#if (DFB_DITHER565 == DFB_DITHER_ADVANCED)
+
+/* This dither table was generated by Raph Levien using patented
+ * technology (US Patent 5,276,535). The dither table itself is in the
+ * public domain.
+ */
+
+#define DM_WIDTH 128
+#define DM_HEIGHT 128
+#define DM_WIDTH_SHIFT 7
+
+static const u32 DM_565[DM_WIDTH * DM_HEIGHT] =
+{
+ 3072, 5243909, 2099202, 3072, 2099202, 4195332, 3072, 1051649, 7340039, 2099202, 5243909, 6291462, 3147779, 5243909, 1051649, 4195332, 6291462, 3147779, 7340039, 3147779, 3072, 7340039, 3147779, 6291462, 4195332, 3072, 5243909, 7340039, 2099202, 4195332, 1051649, 5243909, 3147779, 7340039, 5243909, 4195332, 2099202, 5243909, 4195332, 1051649, 4195332, 3147779, 6291462, 1051649, 7340039, 3072, 5243909, 1051649, 4195332, 1051649, 7340039, 2099202, 3072, 5243909, 1051649, 4195332, 3072, 7340039, 1051649, 5243909, 3072, 6291462, 4195332, 2099202, 4195332, 7340039, 1051649, 6291462, 4195332, 7340039, 1051649, 3147779, 2099202, 1051649, 7340039, 2099202, 5243909, 6291462, 3072, 2099202, 6291462, 1051649, 2099202, 6291462, 4195332, 2099202, 2099202, 4195332, 1051649, 6291462, 2099202, 7340039, 3147779, 1051649, 4195332, 3147779, 6291462, 1051649, 2099202, 5243909, 2099202, 3147779, 3072, 2099202, 6291462, 3147779, 6291462, 2099202, 3072, 4195332, 7340039, 5243909, 3147779, 4195332, 1051649, 6291462, 2099202, 5243909, 3072, 6291462, 1051649, 5243909, 4195332, 6291462, 2099202, 5243909, 1051649, 7340039,
+ 3147779, 7340039, 4195332, 6291462, 5243909, 4195332, 6291462, 3147779, 5243909, 3072, 3147779, 3072, 2099202, 4195332, 7340039, 1051649, 5243909, 3072, 2099202, 6291462, 4195332, 2099202, 5243909, 1051649, 3147779, 5243909, 1051649, 4195332, 3072, 6291462, 3147779, 7340039, 1051649, 3147779, 3072, 2099202, 6291462, 1051649, 7340039, 3147779, 5243909, 3072, 4195332, 3147779, 5243909, 2099202, 5243909, 3147779, 7340039, 4195332, 1051649, 4195332, 6291462, 2099202, 7340039, 3147779, 6291462, 2099202, 4195332, 3147779, 6291462, 2099202, 3072, 6291462, 2099202, 1051649, 3147779, 5243909, 3072, 4195332, 5243909, 2099202, 6291462, 5243909, 4195332, 2099202, 3147779, 1051649, 5243909, 3147779, 4195332, 7340039, 3072, 4195332, 1051649, 5243909, 7340039, 3147779, 7340039, 1051649, 5243909, 1051649, 5243909, 3072, 7340039, 3072, 2099202, 6291462, 7340039, 1051649, 6291462, 1051649, 5243909, 7340039, 1051649, 3147779, 3072, 6291462, 5243909, 3147779, 1051649, 6291462, 2099202, 7340039, 5243909, 3072, 4195332, 7340039, 4195332, 2099202, 7340039, 3147779, 2099202, 3072, 7340039, 4195332, 3147779, 4195332,
+ 2099202, 1051649, 2099202, 4195332, 3072, 3147779, 1051649, 7340039, 2099202, 5243909, 7340039, 4195332, 6291462, 2099202, 3072, 5243909, 2099202, 4195332, 7340039, 3072, 6291462, 1051649, 7340039, 3072, 7340039, 2099202, 6291462, 3147779, 5243909, 2099202, 3072, 6291462, 1051649, 6291462, 5243909, 6291462, 3147779, 4195332, 3072, 6291462, 2099202, 7340039, 1051649, 6291462, 3072, 4195332, 1051649, 6291462, 2099202, 3147779, 6291462, 1051649, 3147779, 6291462, 3072, 4195332, 1051649, 5243909, 3072, 6291462, 1051649, 4195332, 7340039, 3147779, 7340039, 4195332, 6291462, 1051649, 7340039, 2099202, 3072, 7340039, 3072, 3147779, 3072, 6291462, 7340039, 4195332, 1051649, 7340039, 3072, 3147779, 5243909, 3147779, 6291462, 1051649, 3072, 5243909, 3072, 4195332, 4195332, 6291462, 3147779, 6291462, 4195332, 5243909, 7340039, 3072, 3147779, 4195332, 2099202, 7340039, 3072, 4195332, 5243909, 7340039, 4195332, 2099202, 7340039, 3072, 6291462, 3147779, 3072, 4195332, 2099202, 6291462, 3147779, 1051649, 5243909, 6291462, 1051649, 3072, 7340039, 4195332, 2099202, 6291462, 3072, 5243909,
+ 6291462, 6291462, 5243909, 1051649, 5243909, 7340039, 3147779, 4195332, 1051649, 4195332, 2099202, 3072, 3147779, 5243909, 3147779, 7340039, 3072, 6291462, 1051649, 4195332, 3147779, 2099202, 4195332, 4195332, 2099202, 5243909, 3072, 6291462, 1051649, 7340039, 3147779, 4195332, 2099202, 4195332, 2099202, 2099202, 3072, 5243909, 4195332, 2099202, 1051649, 5243909, 3147779, 3147779, 7340039, 2099202, 7340039, 3072, 5243909, 3072, 5243909, 7340039, 3072, 3147779, 5243909, 2099202, 7340039, 3147779, 7340039, 2099202, 4195332, 5243909, 1051649, 5243909, 3072, 4195332, 3072, 4195332, 1051649, 5243909, 6291462, 4195332, 2099202, 6291462, 5243909, 1051649, 2099202, 3072, 6291462, 2099202, 6291462, 5243909, 1051649, 7340039, 2099202, 6291462, 3147779, 6291462, 2099202, 7340039, 1051649, 3072, 7340039, 2099202, 1051649, 2099202, 4195332, 4195332, 2099202, 5243909, 3072, 6291462, 3147779, 4195332, 2099202, 3072, 6291462, 1051649, 3147779, 5243909, 4195332, 2099202, 7340039, 1051649, 5243909, 1051649, 6291462, 2099202, 3072, 4195332, 3147779, 5243909, 3147779, 3072, 6291462, 1051649, 7340039, 3072,
+ 2099202, 3147779, 3072, 7340039, 2099202, 1051649, 6291462, 3072, 5243909, 6291462, 1051649, 7340039, 1051649, 6291462, 1051649, 4195332, 2099202, 3147779, 5243909, 1051649, 6291462, 3147779, 5243909, 3072, 6291462, 1051649, 7340039, 1051649, 4195332, 1051649, 6291462, 1051649, 7340039, 3072, 7340039, 5243909, 7340039, 1051649, 6291462, 3147779, 7340039, 4195332, 1051649, 6291462, 3072, 5243909, 3147779, 4195332, 6291462, 2099202, 4195332, 1051649, 6291462, 4195332, 1051649, 6291462, 3072, 2099202, 1051649, 5243909, 3072, 7340039, 1051649, 2099202, 6291462, 2099202, 6291462, 3147779, 7340039, 2099202, 3147779, 1051649, 5243909, 1051649, 3147779, 7340039, 5243909, 4195332, 3147779, 4195332, 1051649, 3147779, 2099202, 4195332, 3072, 5243909, 4195332, 1051649, 6291462, 4195332, 2099202, 5243909, 3147779, 5243909, 3147779, 6291462, 3072, 5243909, 6291462, 1051649, 7340039, 3147779, 1051649, 6291462, 2099202, 5243909, 4195332, 2099202, 4195332, 3072, 6291462, 1051649, 5243909, 4195332, 3072, 7340039, 3147779, 5243909, 7340039, 2099202, 1051649, 7340039, 4195332, 5243909, 1051649, 4195332, 3147779, 4195332,
+ 6291462, 4195332, 7340039, 3147779, 4195332, 5243909, 2099202, 7340039, 3072, 4195332, 5243909, 3147779, 5243909, 4195332, 3072, 6291462, 6291462, 1051649, 7340039, 2099202, 5243909, 3072, 7340039, 3147779, 2099202, 5243909, 4195332, 3147779, 7340039, 5243909, 2099202, 4195332, 4195332, 3147779, 5243909, 1051649, 3147779, 2099202, 3072, 5243909, 1051649, 6291462, 3072, 4195332, 2099202, 6291462, 1051649, 2099202, 3072, 7340039, 2099202, 3147779, 6291462, 2099202, 7340039, 3147779, 5243909, 4195332, 7340039, 1051649, 6291462, 4195332, 3147779, 5243909, 2099202, 7340039, 3147779, 1051649, 5243909, 3072, 4195332, 7340039, 1051649, 7340039, 3147779, 3072, 6291462, 1051649, 7340039, 3072, 5243909, 7340039, 3072, 7340039, 3147779, 2099202, 3072, 7340039, 3147779, 1051649, 7340039, 2099202, 5243909, 3072, 7340039, 4195332, 3147779, 1051649, 3147779, 4195332, 1051649, 5243909, 6291462, 3072, 6291462, 1051649, 7340039, 3072, 7340039, 1051649, 3147779, 7340039, 2099202, 6291462, 4195332, 2099202, 4195332, 1051649, 3147779, 6291462, 5243909, 2099202, 3072, 3147779, 7340039, 2099202, 6291462, 1051649,
+ 3147779, 3072, 3147779, 1051649, 6291462, 3072, 4195332, 3147779, 2099202, 6291462, 2099202, 7340039, 3072, 7340039, 3147779, 2099202, 3072, 4195332, 3147779, 3072, 6291462, 4195332, 1051649, 6291462, 3147779, 6291462, 2099202, 5243909, 3072, 3147779, 7340039, 3072, 6291462, 1051649, 3147779, 3072, 6291462, 5243909, 7340039, 3147779, 4195332, 1051649, 7340039, 2099202, 5243909, 1051649, 7340039, 4195332, 5243909, 3147779, 5243909, 5243909, 3072, 4195332, 1051649, 5243909, 2099202, 3072, 5243909, 3147779, 3147779, 2099202, 7340039, 3072, 4195332, 3072, 5243909, 4195332, 3147779, 6291462, 2099202, 3147779, 6291462, 3072, 4195332, 7340039, 2099202, 4195332, 2099202, 6291462, 1051649, 5243909, 3147779, 4195332, 1051649, 6291462, 5243909, 3147779, 2099202, 5243909, 4195332, 3072, 6291462, 2099202, 1051649, 1051649, 6291462, 7340039, 3072, 7340039, 5243909, 2099202, 1051649, 3147779, 7340039, 3147779, 3147779, 5243909, 3147779, 6291462, 4195332, 2099202, 5243909, 3072, 3147779, 6291462, 3072, 7340039, 3072, 4195332, 3072, 7340039, 6291462, 5243909, 1051649, 5243909, 3072, 5243909,
+ 2099202, 7340039, 5243909, 3072, 7340039, 3147779, 7340039, 1051649, 6291462, 1051649, 4195332, 1051649, 3147779, 5243909, 2099202, 5243909, 7340039, 3147779, 6291462, 4195332, 1051649, 7340039, 2099202, 4195332, 3072, 5243909, 3072, 7340039, 4195332, 2099202, 5243909, 1051649, 5243909, 2099202, 7340039, 5243909, 2099202, 1051649, 4195332, 2099202, 6291462, 4195332, 2099202, 7340039, 3147779, 6291462, 3147779, 3072, 2099202, 6291462, 3072, 7340039, 2099202, 7340039, 3147779, 3072, 7340039, 4195332, 2099202, 7340039, 3072, 6291462, 3072, 5243909, 3147779, 7340039, 1051649, 6291462, 1051649, 7340039, 3072, 2099202, 4195332, 2099202, 5243909, 1051649, 5243909, 3072, 5243909, 3147779, 4195332, 2099202, 6291462, 2099202, 6291462, 5243909, 1051649, 7340039, 3072, 6291462, 1051649, 6291462, 3147779, 4195332, 7340039, 2099202, 5243909, 2099202, 4195332, 3147779, 3072, 6291462, 4195332, 4195332, 3072, 5243909, 1051649, 5243909, 1051649, 2099202, 3072, 6291462, 1051649, 4195332, 7340039, 1051649, 5243909, 2099202, 6291462, 3147779, 5243909, 2099202, 3147779, 1051649, 7340039, 2099202, 4195332, 7340039,
+ 6291462, 4195332, 1051649, 5243909, 3147779, 2099202, 5243909, 3072, 4195332, 7340039, 3147779, 5243909, 6291462, 3072, 7340039, 1051649, 5243909, 2099202, 3072, 7340039, 2099202, 1051649, 5243909, 1051649, 7340039, 4195332, 1051649, 3147779, 3072, 6291462, 2099202, 7340039, 4195332, 6291462, 3072, 4195332, 6291462, 3147779, 7340039, 3072, 5243909, 3072, 5243909, 3072, 5243909, 3072, 6291462, 4195332, 7340039, 1051649, 4195332, 1051649, 5243909, 1051649, 4195332, 6291462, 3147779, 6291462, 1051649, 5243909, 2099202, 4195332, 7340039, 1051649, 2099202, 6291462, 4195332, 3072, 5243909, 3147779, 5243909, 6291462, 3072, 6291462, 1051649, 7340039, 3147779, 6291462, 1051649, 7340039, 3072, 6291462, 3072, 7340039, 3072, 4195332, 2099202, 4195332, 5243909, 3147779, 3147779, 7340039, 3072, 1051649, 5243909, 4195332, 3072, 6291462, 1051649, 7340039, 2099202, 5243909, 1051649, 7340039, 2099202, 7340039, 3072, 6291462, 3147779, 7340039, 5243909, 3147779, 6291462, 2099202, 5243909, 3147779, 7340039, 4195332, 2099202, 5243909, 1051649, 4195332, 3072, 6291462, 4195332, 6291462, 2099202, 1051649,
+ 3072, 2099202, 5243909, 2099202, 6291462, 1051649, 4195332, 6291462, 2099202, 5243909, 3072, 2099202, 3147779, 4195332, 4195332, 2099202, 3147779, 7340039, 1051649, 4195332, 5243909, 3147779, 7340039, 5243909, 3147779, 2099202, 7340039, 6291462, 5243909, 3147779, 3072, 4195332, 3072, 3147779, 2099202, 7340039, 3072, 1051649, 5243909, 3147779, 6291462, 2099202, 3147779, 6291462, 1051649, 4195332, 2099202, 1051649, 5243909, 3147779, 2099202, 6291462, 3147779, 5243909, 6291462, 1051649, 4195332, 3072, 6291462, 3147779, 6291462, 1051649, 4195332, 3147779, 5243909, 1051649, 2099202, 3147779, 7340039, 1051649, 4195332, 6291462, 2099202, 4195332, 3147779, 3072, 5243909, 2099202, 4195332, 2099202, 3147779, 5243909, 3147779, 4195332, 2099202, 6291462, 3147779, 3072, 7340039, 1051649, 5243909, 2099202, 3147779, 6291462, 2099202, 7340039, 3147779, 4195332, 5243909, 2099202, 6291462, 3147779, 3147779, 1051649, 5243909, 2099202, 4195332, 2099202, 4195332, 3072, 4195332, 1051649, 1051649, 7340039, 3072, 2099202, 1051649, 3072, 7340039, 1051649, 6291462, 3147779, 5243909, 3147779, 1051649, 3072, 3147779, 6291462,
+ 5243909, 3147779, 7340039, 3072, 4195332, 7340039, 3147779, 1051649, 7340039, 1051649, 6291462, 7340039, 1051649, 6291462, 1051649, 6291462, 3072, 5243909, 3147779, 6291462, 3072, 4195332, 2099202, 3072, 6291462, 4195332, 3072, 2099202, 1051649, 7340039, 6291462, 1051649, 6291462, 6291462, 5243909, 3147779, 4195332, 7340039, 1051649, 4195332, 1051649, 7340039, 4195332, 1051649, 7340039, 3147779, 7340039, 5243909, 1051649, 6291462, 5243909, 3072, 4195332, 2099202, 3072, 2099202, 7340039, 3147779, 1051649, 5243909, 3072, 6291462, 5243909, 3072, 6291462, 4195332, 6291462, 7340039, 3072, 5243909, 2099202, 3072, 7340039, 3147779, 6291462, 4195332, 7340039, 1051649, 7340039, 3147779, 5243909, 1051649, 7340039, 3072, 5243909, 1051649, 7340039, 5243909, 3147779, 4195332, 3072, 7340039, 5243909, 1051649, 4195332, 3072, 6291462, 1051649, 7340039, 3072, 4195332, 1051649, 5243909, 6291462, 3072, 6291462, 3147779, 3072, 7340039, 6291462, 3147779, 7340039, 5243909, 3147779, 4195332, 5243909, 6291462, 3147779, 5243909, 4195332, 2099202, 7340039, 3072, 7340039, 5243909, 4195332, 7340039, 2099202,
+ 3072, 6291462, 1051649, 6291462, 2099202, 5243909, 3072, 5243909, 3147779, 2099202, 5243909, 4195332, 3072, 5243909, 2099202, 3147779, 7340039, 1051649, 4195332, 2099202, 5243909, 6291462, 3147779, 7340039, 1051649, 6291462, 3147779, 5243909, 4195332, 2099202, 2099202, 4195332, 3147779, 1051649, 2099202, 3072, 6291462, 2099202, 4195332, 2099202, 6291462, 3072, 3147779, 5243909, 2099202, 4195332, 3072, 3147779, 4195332, 3072, 7340039, 1051649, 7340039, 4195332, 7340039, 3147779, 5243909, 2099202, 4195332, 7340039, 3147779, 2099202, 1051649, 7340039, 2099202, 3072, 2099202, 2099202, 4195332, 1051649, 7340039, 3147779, 5243909, 1051649, 1051649, 5243909, 2099202, 4195332, 3072, 6291462, 3072, 4195332, 1051649, 6291462, 3147779, 4195332, 2099202, 3072, 6291462, 1051649, 6291462, 4195332, 3147779, 3072, 7340039, 5243909, 1051649, 4195332, 2099202, 6291462, 2099202, 7340039, 3072, 4195332, 4195332, 1051649, 7340039, 5243909, 2099202, 1051649, 5243909, 3072, 4195332, 3072, 6291462, 1051649, 2099202, 6291462, 1051649, 5243909, 3072, 4195332, 2099202, 4195332, 3072, 3147779, 1051649, 4195332,
+ 6291462, 4195332, 3147779, 1051649, 6291462, 1051649, 4195332, 6291462, 3072, 7340039, 3072, 2099202, 6291462, 4195332, 7340039, 1051649, 5243909, 3147779, 7340039, 1051649, 6291462, 3072, 3147779, 4195332, 2099202, 5243909, 3072, 7340039, 3072, 4195332, 7340039, 3072, 5243909, 7340039, 4195332, 5243909, 3147779, 5243909, 3072, 7340039, 2099202, 5243909, 6291462, 3072, 4195332, 7340039, 6291462, 2099202, 7340039, 2099202, 5243909, 3147779, 4195332, 3072, 2099202, 5243909, 3072, 6291462, 2099202, 3072, 5243909, 4195332, 6291462, 3147779, 4195332, 7340039, 5243909, 3147779, 6291462, 4195332, 3072, 6291462, 3147779, 5243909, 7340039, 3072, 6291462, 2099202, 5243909, 3147779, 7340039, 2099202, 6291462, 2099202, 7340039, 1051649, 4195332, 7340039, 2099202, 4195332, 2099202, 3072, 6291462, 5243909, 3147779, 2099202, 3147779, 6291462, 3072, 3147779, 5243909, 2099202, 4195332, 7340039, 2099202, 5243909, 3147779, 1051649, 6291462, 4195332, 2099202, 6291462, 3147779, 7340039, 3147779, 7340039, 4195332, 3072, 7340039, 2099202, 6291462, 7340039, 1051649, 6291462, 2099202, 7340039, 5243909, 2099202,
+ 2099202, 3072, 7340039, 5243909, 3147779, 7340039, 3072, 2099202, 5243909, 3147779, 4195332, 7340039, 1051649, 3147779, 3072, 6291462, 1051649, 6291462, 3072, 4195332, 2099202, 7340039, 1051649, 5243909, 1051649, 6291462, 2099202, 3147779, 6291462, 3147779, 1051649, 6291462, 2099202, 3072, 6291462, 1051649, 7340039, 1051649, 6291462, 3147779, 4195332, 3072, 3147779, 7340039, 1051649, 2099202, 1051649, 5243909, 3147779, 3072, 4195332, 1051649, 6291462, 6291462, 1051649, 7340039, 1051649, 4195332, 7340039, 4195332, 1051649, 7340039, 3072, 3147779, 2099202, 3072, 5243909, 1051649, 1051649, 5243909, 2099202, 4195332, 1051649, 2099202, 3147779, 4195332, 1051649, 6291462, 3147779, 1051649, 2099202, 5243909, 3072, 4195332, 3072, 5243909, 3147779, 1051649, 6291462, 3072, 7340039, 5243909, 2099202, 4195332, 3072, 7340039, 5243909, 1051649, 4195332, 7340039, 3072, 6291462, 3147779, 3072, 2099202, 6291462, 3072, 7340039, 4195332, 3072, 7340039, 1051649, 2099202, 1051649, 1051649, 4195332, 3147779, 5243909, 4195332, 3072, 3147779, 1051649, 5243909, 3147779, 6291462, 1051649, 3147779, 7340039,
+ 6291462, 4195332, 2099202, 4195332, 3072, 5243909, 6291462, 4195332, 6291462, 1051649, 3147779, 6291462, 3147779, 7340039, 4195332, 2099202, 5243909, 2099202, 4195332, 7340039, 2099202, 5243909, 3147779, 3072, 7340039, 4195332, 3147779, 5243909, 1051649, 2099202, 6291462, 4195332, 5243909, 1051649, 3147779, 4195332, 1051649, 3147779, 5243909, 3072, 5243909, 6291462, 2099202, 5243909, 3147779, 5243909, 6291462, 1051649, 7340039, 6291462, 2099202, 7340039, 3072, 3147779, 5243909, 2099202, 4195332, 3147779, 1051649, 6291462, 2099202, 5243909, 1051649, 6291462, 6291462, 4195332, 7340039, 3147779, 7340039, 3147779, 7340039, 3072, 5243909, 7340039, 4195332, 7340039, 2099202, 5243909, 3072, 7340039, 6291462, 1051649, 7340039, 4195332, 6291462, 2099202, 6291462, 3147779, 4195332, 5243909, 1051649, 3147779, 6291462, 1051649, 6291462, 4195332, 2099202, 7340039, 3147779, 1051649, 5243909, 4195332, 2099202, 6291462, 4195332, 3147779, 5243909, 1051649, 3147779, 6291462, 3147779, 4195332, 5243909, 6291462, 7340039, 3072, 6291462, 1051649, 7340039, 2099202, 6291462, 6291462, 3072, 4195332, 1051649, 5243909, 3147779, 3072,
+ 5243909, 1051649, 7340039, 3147779, 2099202, 3147779, 2099202, 1051649, 4195332, 3072, 5243909, 1051649, 3072, 5243909, 1051649, 5243909, 3072, 6291462, 3147779, 3072, 4195332, 1051649, 6291462, 4195332, 2099202, 1051649, 6291462, 3072, 5243909, 7340039, 1051649, 3147779, 3072, 7340039, 2099202, 5243909, 3147779, 6291462, 2099202, 7340039, 2099202, 1051649, 7340039, 3072, 6291462, 3072, 4195332, 3147779, 3072, 2099202, 4195332, 5243909, 2099202, 6291462, 3147779, 3072, 6291462, 7340039, 3147779, 4195332, 3072, 7340039, 3147779, 5243909, 3072, 2099202, 1051649, 4195332, 3072, 6291462, 1051649, 5243909, 2099202, 1051649, 3072, 3147779, 6291462, 2099202, 4195332, 4195332, 3072, 5243909, 3147779, 1051649, 1051649, 5243909, 3072, 5243909, 3072, 3147779, 7340039, 3072, 3147779, 7340039, 2099202, 1051649, 3072, 5243909, 2099202, 6291462, 3147779, 3072, 7340039, 1051649, 5243909, 3072, 3147779, 7340039, 3072, 5243909, 2099202, 7340039, 3072, 4195332, 2099202, 3147779, 5243909, 2099202, 3147779, 5243909, 1051649, 3147779, 7340039, 2099202, 6291462, 1051649, 7340039, 3147779,
+ 2099202, 6291462, 1051649, 5243909, 7340039, 3072, 7340039, 6291462, 2099202, 7340039, 2099202, 4195332, 7340039, 2099202, 6291462, 3147779, 4195332, 7340039, 1051649, 6291462, 7340039, 5243909, 3147779, 3072, 6291462, 3147779, 7340039, 2099202, 4195332, 3072, 4195332, 7340039, 6291462, 4195332, 5243909, 3072, 7340039, 3072, 4195332, 1051649, 5243909, 4195332, 2099202, 4195332, 3147779, 1051649, 7340039, 3147779, 5243909, 4195332, 1051649, 6291462, 3072, 4195332, 1051649, 7340039, 2099202, 3072, 5243909, 2099202, 5243909, 1051649, 4195332, 2099202, 7340039, 5243909, 3147779, 6291462, 5243909, 1051649, 4195332, 3147779, 7340039, 4195332, 6291462, 3072, 5243909, 1051649, 3147779, 6291462, 3147779, 2099202, 7340039, 5243909, 3147779, 4195332, 7340039, 2099202, 7340039, 2099202, 2099202, 6291462, 4195332, 1051649, 5243909, 7340039, 3147779, 4195332, 6291462, 3072, 4195332, 7340039, 1051649, 6291462, 2099202, 7340039, 1051649, 4195332, 6291462, 3147779, 1051649, 5243909, 1051649, 3147779, 3072, 7340039, 1051649, 6291462, 3072, 7340039, 4195332, 4195332, 2099202, 5243909, 3072, 4195332, 3072, 5243909,
+ 3072, 7340039, 2099202, 4195332, 1051649, 5243909, 1051649, 4195332, 3072, 3147779, 6291462, 3147779, 3072, 4195332, 1051649, 7340039, 2099202, 3072, 4195332, 3147779, 2099202, 3072, 6291462, 4195332, 5243909, 1051649, 4195332, 2099202, 7340039, 5243909, 3147779, 1051649, 2099202, 1051649, 7340039, 3147779, 2099202, 6291462, 4195332, 7340039, 3072, 7340039, 1051649, 5243909, 7340039, 5243909, 1051649, 2099202, 6291462, 3072, 7340039, 1051649, 7340039, 3147779, 5243909, 2099202, 4195332, 6291462, 1051649, 7340039, 3147779, 3147779, 6291462, 3072, 4195332, 1051649, 7340039, 3072, 2099202, 7340039, 3072, 6291462, 3072, 2099202, 5243909, 3147779, 7340039, 4195332, 7340039, 1051649, 4195332, 6291462, 2099202, 3072, 7340039, 1051649, 4195332, 3147779, 1051649, 6291462, 5243909, 1051649, 5243909, 2099202, 3147779, 6291462, 3072, 4195332, 1051649, 7340039, 2099202, 5243909, 3147779, 1051649, 5243909, 3147779, 6291462, 2099202, 1051649, 4195332, 6291462, 2099202, 4195332, 6291462, 5243909, 2099202, 4195332, 3147779, 6291462, 2099202, 3072, 5243909, 3072, 6291462, 4195332, 7340039, 3147779, 4195332,
+ 5243909, 3147779, 3072, 4195332, 6291462, 3147779, 4195332, 7340039, 3147779, 5243909, 1051649, 5243909, 6291462, 3147779, 6291462, 3072, 5243909, 4195332, 7340039, 1051649, 3147779, 7340039, 2099202, 5243909, 1051649, 7340039, 3072, 5243909, 3072, 2099202, 5243909, 3072, 7340039, 4195332, 1051649, 6291462, 4195332, 3072, 1051649, 3147779, 2099202, 6291462, 3147779, 2099202, 3072, 3147779, 6291462, 5243909, 3147779, 2099202, 5243909, 3147779, 3147779, 5243909, 1051649, 6291462, 4195332, 3072, 5243909, 2099202, 3072, 5243909, 1051649, 6291462, 3147779, 5243909, 2099202, 4195332, 5243909, 3147779, 5243909, 2099202, 3147779, 7340039, 1051649, 6291462, 3072, 1051649, 5243909, 3072, 7340039, 3072, 5243909, 3147779, 6291462, 3072, 6291462, 2099202, 5243909, 4195332, 3072, 3147779, 6291462, 3072, 7340039, 1051649, 5243909, 2099202, 5243909, 3147779, 5243909, 3072, 4195332, 6291462, 3072, 6291462, 3072, 4195332, 5243909, 2099202, 3072, 7340039, 5243909, 3072, 2099202, 7340039, 3072, 5243909, 1051649, 4195332, 6291462, 2099202, 7340039, 1051649, 3147779, 2099202, 6291462, 1051649,
+ 7340039, 3147779, 6291462, 2099202, 3072, 7340039, 2099202, 3072, 6291462, 1051649, 6291462, 2099202, 4195332, 1051649, 2099202, 6291462, 3147779, 2099202, 3072, 5243909, 5243909, 3147779, 1051649, 7340039, 2099202, 3147779, 6291462, 4195332, 3147779, 6291462, 3147779, 6291462, 2099202, 3147779, 5243909, 3072, 3147779, 7340039, 5243909, 6291462, 5243909, 3072, 4195332, 7340039, 6291462, 2099202, 4195332, 3072, 6291462, 4195332, 6291462, 1051649, 6291462, 3072, 7340039, 3072, 3147779, 7340039, 3147779, 4195332, 6291462, 3147779, 7340039, 2099202, 6291462, 3072, 4195332, 7340039, 1051649, 6291462, 3072, 7340039, 1051649, 5243909, 4195332, 2099202, 4195332, 6291462, 2099202, 6291462, 3147779, 2099202, 7340039, 4195332, 1051649, 4195332, 5243909, 3072, 7340039, 1051649, 6291462, 7340039, 2099202, 5243909, 3147779, 4195332, 2099202, 7340039, 3072, 6291462, 1051649, 3147779, 7340039, 2099202, 3147779, 5243909, 2099202, 7340039, 3147779, 6291462, 3147779, 4195332, 1051649, 7340039, 1051649, 4195332, 6291462, 3147779, 7340039, 3147779, 1051649, 5243909, 3147779, 4195332, 6291462, 1051649, 5243909, 2099202,
+ 1051649, 5243909, 1051649, 6291462, 3147779, 5243909, 1051649, 5243909, 3147779, 3072, 4195332, 7340039, 3072, 7340039, 5243909, 3072, 7340039, 3147779, 6291462, 2099202, 1051649, 6291462, 4195332, 4195332, 3072, 5243909, 1051649, 1051649, 7340039, 3072, 1051649, 4195332, 7340039, 1051649, 2099202, 6291462, 2099202, 1051649, 3147779, 3072, 1051649, 6291462, 2099202, 1051649, 4195332, 1051649, 5243909, 7340039, 1051649, 2099202, 3072, 7340039, 4195332, 2099202, 3147779, 4195332, 5243909, 1051649, 3072, 7340039, 1051649, 4195332, 3072, 4195332, 2099202, 7340039, 3147779, 1051649, 2099202, 6291462, 4195332, 2099202, 5243909, 3147779, 3072, 7340039, 3147779, 1051649, 3147779, 5243909, 1051649, 4195332, 3072, 6291462, 2099202, 7340039, 2099202, 4195332, 1051649, 5243909, 3147779, 3072, 4195332, 1051649, 7340039, 3072, 6291462, 4195332, 3147779, 2099202, 7340039, 6291462, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 5243909, 3072, 7340039, 1051649, 4195332, 3147779, 5243909, 2099202, 3072, 2099202, 3072, 6291462, 3147779, 7340039, 2099202, 3072, 7340039, 3147779, 3072, 6291462,
+ 4195332, 3072, 4195332, 1051649, 3147779, 4195332, 6291462, 2099202, 7340039, 5243909, 3147779, 1051649, 3147779, 5243909, 2099202, 4195332, 1051649, 5243909, 1051649, 4195332, 6291462, 3072, 2099202, 6291462, 2099202, 3147779, 6291462, 4195332, 2099202, 5243909, 6291462, 3147779, 3072, 5243909, 5243909, 4195332, 7340039, 4195332, 6291462, 4195332, 7340039, 3147779, 4195332, 5243909, 3147779, 7340039, 3072, 3147779, 4195332, 7340039, 2099202, 5243909, 1051649, 5243909, 7340039, 1051649, 6291462, 3147779, 5243909, 2099202, 1051649, 6291462, 5243909, 1051649, 3147779, 6291462, 3072, 5243909, 4195332, 3072, 3147779, 6291462, 1051649, 6291462, 2099202, 5243909, 3072, 7340039, 5243909, 3072, 7340039, 3147779, 5243909, 1051649, 4195332, 3072, 6291462, 3147779, 7340039, 2099202, 4195332, 6291462, 3147779, 5243909, 2099202, 4195332, 1051649, 1051649, 5243909, 4195332, 3072, 4195332, 3147779, 5243909, 3072, 6291462, 1051649, 7340039, 3147779, 2099202, 5243909, 2099202, 5243909, 6291462, 3072, 7340039, 5243909, 7340039, 4195332, 5243909, 1051649, 3072, 6291462, 4195332, 1051649, 7340039, 5243909, 2099202,
+ 7340039, 5243909, 4195332, 7340039, 6291462, 3072, 1051649, 4195332, 1051649, 5243909, 2099202, 6291462, 4195332, 1051649, 7340039, 3147779, 6291462, 3147779, 7340039, 3072, 3147779, 5243909, 7340039, 1051649, 5243909, 7340039, 3072, 7340039, 3147779, 1051649, 4195332, 6291462, 2099202, 7340039, 2099202, 3072, 3147779, 3072, 2099202, 5243909, 1051649, 5243909, 3072, 7340039, 3072, 3147779, 6291462, 1051649, 6291462, 1051649, 3147779, 4195332, 6291462, 3072, 2099202, 4195332, 2099202, 6291462, 3072, 5243909, 7340039, 2099202, 3147779, 7340039, 5243909, 1051649, 3147779, 6291462, 2099202, 7340039, 1051649, 3147779, 4195332, 1051649, 7340039, 1051649, 5243909, 2099202, 2099202, 5243909, 4195332, 1051649, 3147779, 7340039, 5243909, 3147779, 6291462, 3072, 3147779, 7340039, 3072, 1051649, 6291462, 3072, 7340039, 3147779, 6291462, 3147779, 7340039, 1051649, 7340039, 3072, 6291462, 1051649, 5243909, 2099202, 3147779, 5243909, 1051649, 7340039, 1051649, 6291462, 3072, 2099202, 4195332, 4195332, 1051649, 1051649, 3147779, 2099202, 5243909, 4195332, 2099202, 5243909, 3147779, 1051649, 4195332, 2099202,
+ 3072, 3147779, 2099202, 3072, 2099202, 6291462, 5243909, 7340039, 2099202, 3072, 7340039, 1051649, 6291462, 2099202, 4195332, 3072, 2099202, 3072, 5243909, 2099202, 6291462, 1051649, 3147779, 4195332, 3072, 2099202, 5243909, 1051649, 5243909, 7340039, 2099202, 3072, 5243909, 1051649, 4195332, 6291462, 3147779, 5243909, 7340039, 2099202, 6291462, 3147779, 2099202, 5243909, 2099202, 5243909, 4195332, 3072, 5243909, 3147779, 7340039, 3072, 2099202, 5243909, 7340039, 3072, 5243909, 1051649, 6291462, 4195332, 3072, 4195332, 5243909, 3072, 2099202, 6291462, 4195332, 3072, 5243909, 4195332, 5243909, 7340039, 3072, 6291462, 4195332, 3147779, 6291462, 4195332, 6291462, 1051649, 6291462, 2099202, 6291462, 3072, 2099202, 3147779, 1051649, 4195332, 6291462, 2099202, 5243909, 3147779, 5243909, 2099202, 4195332, 3072, 2099202, 5243909, 1051649, 4195332, 2099202, 6291462, 2099202, 4195332, 3072, 7340039, 4195332, 3072, 6291462, 4195332, 6291462, 4195332, 3147779, 7340039, 1051649, 6291462, 3147779, 6291462, 7340039, 3072, 7340039, 3147779, 6291462, 3072, 7340039, 3072, 5243909, 7340039,
+ 1051649, 6291462, 5243909, 5243909, 7340039, 3147779, 3072, 2099202, 4195332, 6291462, 4195332, 3147779, 5243909, 3072, 5243909, 7340039, 5243909, 6291462, 4195332, 7340039, 3147779, 3072, 5243909, 5243909, 7340039, 4195332, 2099202, 6291462, 3147779, 3072, 4195332, 7340039, 3147779, 6291462, 2099202, 1051649, 5243909, 1051649, 3072, 4195332, 3072, 6291462, 1051649, 7340039, 3147779, 1051649, 6291462, 2099202, 7340039, 1051649, 2099202, 4195332, 6291462, 1051649, 3147779, 4195332, 7340039, 3147779, 2099202, 7340039, 1051649, 7340039, 1051649, 6291462, 3147779, 7340039, 1051649, 7340039, 3147779, 1051649, 5243909, 2099202, 2099202, 4195332, 6291462, 3072, 3147779, 3072, 3147779, 3072, 3147779, 5243909, 4195332, 2099202, 6291462, 7340039, 5243909, 3072, 4195332, 1051649, 3147779, 7340039, 1051649, 6291462, 2099202, 6291462, 5243909, 3072, 6291462, 5243909, 3072, 3147779, 5243909, 7340039, 3147779, 2099202, 6291462, 2099202, 3147779, 1051649, 2099202, 3072, 7340039, 3147779, 5243909, 2099202, 3072, 4195332, 2099202, 4195332, 3147779, 1051649, 5243909, 2099202, 4195332, 6291462, 2099202, 2099202,
+ 6291462, 4195332, 3072, 3147779, 1051649, 4195332, 7340039, 5243909, 3147779, 3072, 7340039, 3072, 3147779, 6291462, 2099202, 1051649, 1051649, 4195332, 2099202, 1051649, 4195332, 7340039, 2099202, 1051649, 1051649, 3147779, 6291462, 3072, 5243909, 6291462, 2099202, 1051649, 4195332, 3072, 6291462, 7340039, 3147779, 6291462, 4195332, 7340039, 3147779, 2099202, 6291462, 3072, 4195332, 7340039, 3147779, 3072, 4195332, 6291462, 5243909, 3072, 7340039, 4195332, 6291462, 1051649, 2099202, 6291462, 3072, 3147779, 5243909, 3147779, 4195332, 2099202, 3072, 4195332, 2099202, 5243909, 1051649, 7340039, 3072, 4195332, 7340039, 1051649, 1051649, 7340039, 2099202, 6291462, 7340039, 4195332, 7340039, 1051649, 3072, 7340039, 1051649, 4195332, 2099202, 7340039, 5243909, 3147779, 6291462, 1051649, 4195332, 3072, 7340039, 3147779, 1051649, 4195332, 3147779, 2099202, 7340039, 5243909, 1051649, 1051649, 6291462, 4195332, 3072, 5243909, 7340039, 3147779, 5243909, 4195332, 1051649, 5243909, 3072, 6291462, 3147779, 5243909, 1051649, 6291462, 1051649, 7340039, 3147779, 5243909, 4195332, 3072, 6291462, 3147779,
+ 1051649, 4195332, 1051649, 7340039, 6291462, 4195332, 3072, 2099202, 6291462, 1051649, 5243909, 2099202, 5243909, 2099202, 4195332, 7340039, 3147779, 7340039, 3072, 5243909, 6291462, 3072, 4195332, 6291462, 6291462, 3072, 7340039, 4195332, 2099202, 1051649, 7340039, 3147779, 7340039, 2099202, 4195332, 3072, 5243909, 2099202, 3147779, 1051649, 5243909, 4195332, 3147779, 6291462, 2099202, 1051649, 5243909, 7340039, 3147779, 3072, 2099202, 5243909, 2099202, 3147779, 3072, 5243909, 2099202, 4195332, 5243909, 1051649, 6291462, 1051649, 6291462, 3147779, 7340039, 4195332, 6291462, 3072, 4195332, 3147779, 6291462, 2099202, 3147779, 5243909, 2099202, 4195332, 5243909, 2099202, 1051649, 4195332, 2099202, 6291462, 5243909, 3147779, 5243909, 3072, 5243909, 2099202, 1051649, 6291462, 3072, 5243909, 3147779, 5243909, 2099202, 5243909, 7340039, 2099202, 6291462, 1051649, 3147779, 3072, 7340039, 4195332, 5243909, 2099202, 7340039, 4195332, 1051649, 6291462, 3072, 6291462, 3147779, 2099202, 7340039, 2099202, 6291462, 1051649, 7340039, 3072, 4195332, 5243909, 2099202, 3072, 7340039, 3147779, 1051649, 5243909,
+ 7340039, 3147779, 5243909, 3147779, 1051649, 2099202, 6291462, 1051649, 7340039, 3147779, 4195332, 7340039, 3072, 6291462, 3147779, 3072, 6291462, 2099202, 4195332, 1051649, 3147779, 3147779, 5243909, 2099202, 3147779, 4195332, 1051649, 3147779, 7340039, 5243909, 1051649, 4195332, 3072, 5243909, 1051649, 4195332, 7340039, 3072, 6291462, 7340039, 3072, 7340039, 1051649, 4195332, 7340039, 2099202, 4195332, 1051649, 6291462, 3147779, 7340039, 1051649, 6291462, 6291462, 4195332, 3147779, 7340039, 3072, 7340039, 3147779, 2099202, 7340039, 4195332, 3072, 5243909, 1051649, 2099202, 5243909, 3072, 7340039, 1051649, 5243909, 3072, 6291462, 4195332, 3072, 7340039, 3147779, 5243909, 6291462, 3072, 4195332, 2099202, 1051649, 7340039, 2099202, 4195332, 7340039, 3072, 3147779, 4195332, 2099202, 7340039, 1051649, 4195332, 3072, 6291462, 3072, 7340039, 4195332, 6291462, 2099202, 4195332, 2099202, 3072, 6291462, 1051649, 5243909, 3072, 2099202, 5243909, 1051649, 7340039, 4195332, 1051649, 5243909, 3072, 4195332, 3147779, 3147779, 7340039, 3072, 4195332, 6291462, 2099202, 5243909, 7340039, 2099202,
+ 3072, 6291462, 3072, 4195332, 5243909, 7340039, 2099202, 5243909, 4195332, 1051649, 6291462, 1051649, 4195332, 1051649, 2099202, 5243909, 2099202, 5243909, 3147779, 7340039, 6291462, 1051649, 7340039, 3072, 6291462, 2099202, 5243909, 6291462, 3072, 3147779, 5243909, 2099202, 6291462, 3147779, 7340039, 1051649, 6291462, 2099202, 4195332, 3147779, 2099202, 5243909, 1051649, 5243909, 3072, 5243909, 4195332, 3072, 5243909, 2099202, 4195332, 3147779, 2099202, 3072, 1051649, 6291462, 3147779, 4195332, 2099202, 5243909, 3072, 5243909, 1051649, 7340039, 2099202, 6291462, 3147779, 2099202, 6291462, 3147779, 3147779, 4195332, 7340039, 1051649, 6291462, 3147779, 1051649, 6291462, 3072, 2099202, 4195332, 7340039, 3072, 6291462, 3147779, 5243909, 1051649, 4195332, 6291462, 2099202, 7340039, 4195332, 3072, 7340039, 6291462, 2099202, 4195332, 3147779, 1051649, 4195332, 3072, 3147779, 6291462, 1051649, 6291462, 3147779, 3147779, 7340039, 4195332, 5243909, 1051649, 6291462, 4195332, 3072, 5243909, 3147779, 7340039, 2099202, 6291462, 1051649, 5243909, 2099202, 6291462, 1051649, 4195332, 3072, 3147779, 4195332,
+ 5243909, 2099202, 7340039, 2099202, 1051649, 4195332, 3147779, 3072, 3147779, 7340039, 3072, 5243909, 3147779, 7340039, 6291462, 3072, 7340039, 4195332, 3072, 2099202, 4195332, 2099202, 4195332, 5243909, 7340039, 3072, 4195332, 2099202, 5243909, 2099202, 7340039, 3072, 3147779, 5243909, 3072, 4195332, 3147779, 5243909, 1051649, 5243909, 1051649, 3147779, 6291462, 2099202, 6291462, 3147779, 3147779, 6291462, 1051649, 7340039, 3072, 6291462, 3147779, 7340039, 5243909, 3072, 6291462, 1051649, 4195332, 1051649, 6291462, 4195332, 2099202, 3147779, 5243909, 3072, 7340039, 5243909, 1051649, 6291462, 3072, 6291462, 3072, 4195332, 2099202, 5243909, 7340039, 4195332, 2099202, 7340039, 1051649, 2099202, 5243909, 4195332, 3072, 2099202, 7340039, 3072, 5243909, 1051649, 1051649, 3147779, 5243909, 1051649, 3147779, 5243909, 1051649, 6291462, 5243909, 2099202, 5243909, 7340039, 1051649, 5243909, 4195332, 1051649, 5243909, 3072, 2099202, 7340039, 2099202, 3147779, 3072, 6291462, 3147779, 6291462, 1051649, 5243909, 3072, 6291462, 2099202, 7340039, 1051649, 3147779, 6291462, 3147779, 7340039, 2099202,
+ 1051649, 4195332, 3147779, 6291462, 4195332, 3072, 7340039, 5243909, 2099202, 6291462, 2099202, 5243909, 1051649, 4195332, 1051649, 5243909, 3147779, 1051649, 7340039, 6291462, 3072, 7340039, 3072, 1051649, 3147779, 3147779, 6291462, 1051649, 7340039, 4195332, 4195332, 2099202, 6291462, 1051649, 7340039, 4195332, 3072, 7340039, 2099202, 4195332, 7340039, 5243909, 3072, 4195332, 1051649, 7340039, 3072, 7340039, 4195332, 2099202, 5243909, 1051649, 4195332, 3072, 4195332, 3147779, 1051649, 7340039, 2099202, 7340039, 3147779, 3072, 6291462, 1051649, 6291462, 2099202, 4195332, 3072, 4195332, 2099202, 5243909, 2099202, 5243909, 3147779, 7340039, 3072, 3147779, 1051649, 4195332, 5243909, 3147779, 6291462, 3147779, 1051649, 7340039, 5243909, 3147779, 6291462, 3147779, 6291462, 5243909, 2099202, 6291462, 2099202, 4195332, 3072, 7340039, 3147779, 1051649, 7340039, 3072, 3147779, 4195332, 3072, 3147779, 7340039, 2099202, 6291462, 3147779, 3072, 7340039, 4195332, 3147779, 7340039, 1051649, 2099202, 4195332, 2099202, 7340039, 1051649, 4195332, 3072, 4195332, 6291462, 1051649, 5243909, 3072, 6291462,
+ 5243909, 1051649, 6291462, 3072, 3147779, 7340039, 1051649, 4195332, 1051649, 3147779, 6291462, 2099202, 7340039, 3072, 3147779, 6291462, 3072, 6291462, 3147779, 2099202, 3147779, 4195332, 6291462, 5243909, 3072, 7340039, 1051649, 4195332, 3072, 6291462, 1051649, 5243909, 3072, 5243909, 2099202, 3147779, 6291462, 2099202, 6291462, 3072, 2099202, 3147779, 7340039, 4195332, 1051649, 5243909, 2099202, 4195332, 3072, 6291462, 1051649, 7340039, 2099202, 5243909, 2099202, 7340039, 5243909, 3147779, 4195332, 3072, 6291462, 1051649, 4195332, 5243909, 3072, 6291462, 3147779, 7340039, 1051649, 7340039, 2099202, 7340039, 1051649, 2099202, 5243909, 1051649, 6291462, 6291462, 3072, 5243909, 3072, 7340039, 3072, 6291462, 3147779, 6291462, 1051649, 2099202, 4195332, 3072, 4195332, 7340039, 3072, 5243909, 7340039, 3147779, 3072, 5243909, 3147779, 2099202, 6291462, 4195332, 7340039, 2099202, 6291462, 3072, 5243909, 1051649, 6291462, 4195332, 2099202, 5243909, 3072, 5243909, 4195332, 7340039, 3072, 6291462, 3147779, 3147779, 7340039, 5243909, 3147779, 3072, 7340039, 1051649, 4195332, 3147779,
+ 3072, 7340039, 2099202, 5243909, 5243909, 2099202, 6291462, 2099202, 7340039, 4195332, 3072, 5243909, 3147779, 4195332, 6291462, 2099202, 5243909, 4195332, 1051649, 5243909, 6291462, 1051649, 2099202, 4195332, 4195332, 2099202, 6291462, 3147779, 6291462, 3147779, 2099202, 7340039, 3147779, 4195332, 1051649, 6291462, 3072, 4195332, 3147779, 5243909, 6291462, 3072, 2099202, 6291462, 3147779, 7340039, 1051649, 5243909, 3147779, 5243909, 4195332, 3147779, 7340039, 3072, 6291462, 2099202, 3072, 6291462, 2099202, 5243909, 4195332, 3147779, 7340039, 2099202, 7340039, 2099202, 5243909, 1051649, 4195332, 5243909, 3072, 3147779, 4195332, 7340039, 3072, 3147779, 4195332, 2099202, 7340039, 3147779, 1051649, 5243909, 2099202, 4195332, 1051649, 3072, 4195332, 7340039, 2099202, 7340039, 3147779, 1051649, 6291462, 3147779, 1051649, 7340039, 5243909, 2099202, 4195332, 7340039, 4195332, 3072, 2099202, 5243909, 1051649, 4195332, 7340039, 3147779, 3072, 6291462, 3147779, 1051649, 7340039, 2099202, 3072, 5243909, 4195332, 1051649, 5243909, 3072, 3147779, 2099202, 5243909, 4195332, 2099202, 6291462, 2099202, 7340039,
+ 5243909, 3147779, 1051649, 7340039, 3072, 4195332, 3072, 5243909, 3072, 5243909, 1051649, 7340039, 3072, 5243909, 1051649, 2099202, 7340039, 1051649, 7340039, 3147779, 3072, 5243909, 7340039, 3072, 7340039, 1051649, 5243909, 2099202, 1051649, 5243909, 1051649, 3072, 6291462, 2099202, 7340039, 3147779, 6291462, 1051649, 7340039, 1051649, 1051649, 7340039, 5243909, 3072, 2099202, 4195332, 6291462, 1051649, 6291462, 3072, 2099202, 6291462, 1051649, 4195332, 1051649, 4195332, 7340039, 1051649, 2099202, 7340039, 1051649, 5243909, 3072, 3147779, 4195332, 1051649, 3147779, 6291462, 2099202, 4195332, 3147779, 6291462, 3072, 3147779, 6291462, 5243909, 3072, 4195332, 1051649, 6291462, 4195332, 6291462, 1051649, 3147779, 5243909, 7340039, 3147779, 3072, 5243909, 1051649, 4195332, 6291462, 2099202, 4195332, 3072, 2099202, 4195332, 1051649, 6291462, 3072, 1051649, 5243909, 6291462, 3147779, 7340039, 3147779, 2099202, 6291462, 4195332, 2099202, 7340039, 3147779, 4195332, 6291462, 4195332, 2099202, 3147779, 6291462, 3072, 6291462, 4195332, 7340039, 1051649, 6291462, 3072, 5243909, 2099202, 4195332,
+ 3147779, 3072, 6291462, 1051649, 3147779, 5243909, 6291462, 3147779, 7340039, 3147779, 6291462, 2099202, 4195332, 2099202, 7340039, 3147779, 3072, 5243909, 3147779, 6291462, 2099202, 4195332, 1051649, 3147779, 5243909, 4195332, 3072, 6291462, 3147779, 7340039, 4195332, 6291462, 3147779, 5243909, 3072, 5243909, 1051649, 4195332, 2099202, 4195332, 5243909, 3147779, 1051649, 6291462, 6291462, 3072, 2099202, 5243909, 3147779, 7340039, 4195332, 3072, 7340039, 3147779, 2099202, 5243909, 3147779, 5243909, 6291462, 3072, 3147779, 5243909, 6291462, 1051649, 5243909, 3147779, 7340039, 3072, 6291462, 2099202, 7340039, 1051649, 5243909, 2099202, 1051649, 7340039, 2099202, 7340039, 2099202, 5243909, 3072, 3147779, 7340039, 6291462, 3072, 2099202, 5243909, 6291462, 2099202, 4195332, 5243909, 3072, 3147779, 7340039, 5243909, 6291462, 1051649, 7340039, 2099202, 5243909, 7340039, 3147779, 3072, 6291462, 3072, 5243909, 1051649, 5243909, 3072, 6291462, 1051649, 6291462, 1051649, 3072, 6291462, 1051649, 7340039, 4195332, 2099202, 5243909, 1051649, 3072, 5243909, 2099202, 6291462, 3147779, 7340039, 1051649,
+ 5243909, 7340039, 3147779, 4195332, 6291462, 2099202, 1051649, 4195332, 2099202, 5243909, 3072, 4195332, 6291462, 6291462, 1051649, 4195332, 6291462, 2099202, 1051649, 3072, 7340039, 3147779, 5243909, 7340039, 2099202, 2099202, 6291462, 1051649, 5243909, 3072, 3147779, 1051649, 6291462, 2099202, 2099202, 7340039, 3147779, 3072, 5243909, 6291462, 3072, 7340039, 4195332, 2099202, 4195332, 3147779, 7340039, 2099202, 6291462, 1051649, 3147779, 5243909, 1051649, 5243909, 6291462, 3072, 7340039, 3072, 4195332, 6291462, 4195332, 2099202, 2099202, 7340039, 3072, 6291462, 1051649, 4195332, 5243909, 3072, 5243909, 1051649, 4195332, 6291462, 4195332, 2099202, 3147779, 5243909, 3072, 3147779, 7340039, 2099202, 4195332, 2099202, 6291462, 4195332, 1051649, 1051649, 7340039, 3072, 6291462, 2099202, 6291462, 1051649, 2099202, 3072, 6291462, 4195332, 3147779, 1051649, 4195332, 2099202, 4195332, 2099202, 4195332, 2099202, 7340039, 1051649, 3147779, 5243909, 4195332, 2099202, 5243909, 5243909, 3147779, 5243909, 2099202, 3072, 7340039, 3147779, 6291462, 4195332, 3147779, 7340039, 1051649, 4195332, 3072, 6291462,
+ 2099202, 4195332, 1051649, 7340039, 3072, 6291462, 3147779, 7340039, 3072, 3147779, 7340039, 1051649, 3072, 3147779, 5243909, 3072, 4195332, 6291462, 7340039, 4195332, 5243909, 1051649, 4195332, 3072, 3147779, 7340039, 4195332, 7340039, 2099202, 7340039, 4195332, 5243909, 3072, 7340039, 4195332, 3072, 5243909, 7340039, 3147779, 2099202, 5243909, 3147779, 1051649, 6291462, 3072, 4195332, 3072, 5243909, 3072, 4195332, 6291462, 2099202, 7340039, 2099202, 1051649, 5243909, 3147779, 2099202, 5243909, 1051649, 3072, 7340039, 1051649, 4195332, 4195332, 2099202, 7340039, 3147779, 1051649, 6291462, 3147779, 7340039, 3147779, 3072, 7340039, 1051649, 6291462, 4195332, 1051649, 6291462, 1051649, 5243909, 3072, 5243909, 1051649, 3147779, 7340039, 5243909, 3147779, 4195332, 2099202, 5243909, 1051649, 7340039, 4195332, 5243909, 3147779, 3072, 5243909, 6291462, 3072, 7340039, 1051649, 6291462, 7340039, 1051649, 3147779, 7340039, 4195332, 2099202, 3072, 7340039, 3147779, 2099202, 7340039, 1051649, 5243909, 3147779, 5243909, 1051649, 2099202, 6291462, 2099202, 3072, 4195332, 3147779, 7340039, 2099202,
+ 1051649, 5243909, 3147779, 2099202, 5243909, 4195332, 3072, 6291462, 2099202, 5243909, 1051649, 5243909, 3147779, 7340039, 2099202, 7340039, 3147779, 1051649, 3072, 3147779, 6291462, 1051649, 2099202, 6291462, 5243909, 3072, 3147779, 3072, 5243909, 1051649, 6291462, 1051649, 4195332, 3147779, 2099202, 6291462, 1051649, 4195332, 3072, 7340039, 1051649, 2099202, 5243909, 3147779, 7340039, 1051649, 6291462, 3147779, 7340039, 1051649, 2099202, 3072, 4195332, 6291462, 3147779, 4195332, 3072, 7340039, 1051649, 3147779, 6291462, 5243909, 3147779, 6291462, 1051649, 6291462, 3072, 4195332, 7340039, 4195332, 1051649, 4195332, 6291462, 2099202, 5243909, 3147779, 3072, 4195332, 7340039, 3147779, 6291462, 4195332, 7340039, 2099202, 4195332, 6291462, 3072, 2099202, 6291462, 3072, 7340039, 3147779, 5243909, 2099202, 4195332, 1051649, 6291462, 2099202, 7340039, 2099202, 5243909, 4195332, 3147779, 5243909, 3072, 4195332, 6291462, 3072, 1051649, 5243909, 7340039, 3147779, 3072, 6291462, 3072, 4195332, 6291462, 2099202, 7340039, 4195332, 7340039, 3072, 5243909, 7340039, 1051649, 6291462, 3072, 5243909,
+ 4195332, 3072, 6291462, 2099202, 7340039, 1051649, 2099202, 6291462, 3147779, 1051649, 7340039, 3147779, 6291462, 1051649, 5243909, 1051649, 6291462, 5243909, 5243909, 2099202, 3072, 4195332, 7340039, 1051649, 6291462, 2099202, 6291462, 4195332, 3147779, 3072, 3147779, 5243909, 2099202, 7340039, 1051649, 3147779, 6291462, 2099202, 6291462, 3147779, 4195332, 7340039, 4195332, 1051649, 5243909, 3147779, 5243909, 1051649, 4195332, 5243909, 7340039, 3147779, 5243909, 3072, 7340039, 2099202, 6291462, 3147779, 6291462, 4195332, 3147779, 3072, 7340039, 2099202, 5243909, 3147779, 2099202, 5243909, 3072, 2099202, 6291462, 3072, 1051649, 6291462, 2099202, 7340039, 5243909, 2099202, 3072, 5243909, 1051649, 3072, 3147779, 6291462, 1051649, 3147779, 5243909, 3147779, 5243909, 3147779, 1051649, 6291462, 3072, 5243909, 3072, 7340039, 3147779, 5243909, 1051649, 3147779, 1051649, 3072, 6291462, 2099202, 3147779, 5243909, 2099202, 4195332, 6291462, 4195332, 1051649, 5243909, 6291462, 1051649, 7340039, 2099202, 3072, 4195332, 3072, 1051649, 5243909, 3147779, 1051649, 4195332, 5243909, 2099202, 3147779, 6291462,
+ 7340039, 4195332, 1051649, 4195332, 3072, 5243909, 4195332, 1051649, 7340039, 4195332, 4195332, 3072, 4195332, 2099202, 6291462, 3072, 3147779, 2099202, 4195332, 7340039, 4195332, 6291462, 3072, 3147779, 4195332, 3072, 5243909, 1051649, 2099202, 6291462, 7340039, 3072, 6291462, 3072, 4195332, 6291462, 3072, 5243909, 1051649, 5243909, 3072, 5243909, 2099202, 6291462, 3072, 7340039, 2099202, 7340039, 2099202, 3072, 4195332, 2099202, 6291462, 1051649, 4195332, 1051649, 5243909, 2099202, 3072, 7340039, 2099202, 5243909, 1051649, 4195332, 3072, 7340039, 1051649, 6291462, 3147779, 7340039, 2099202, 5243909, 7340039, 3147779, 3072, 4195332, 1051649, 6291462, 7340039, 3147779, 5243909, 4195332, 5243909, 1051649, 7340039, 2099202, 7340039, 3072, 4195332, 1051649, 7340039, 4195332, 2099202, 6291462, 4195332, 2099202, 3072, 7340039, 2099202, 6291462, 4195332, 7340039, 3147779, 6291462, 3072, 1051649, 7340039, 3147779, 3072, 7340039, 2099202, 1051649, 4195332, 3147779, 4195332, 6291462, 3147779, 6291462, 2099202, 6291462, 3147779, 4195332, 1051649, 7340039, 3072, 4195332, 7340039, 1051649,
+ 2099202, 3147779, 5243909, 6291462, 3147779, 7340039, 1051649, 6291462, 3072, 2099202, 1051649, 5243909, 7340039, 4195332, 2099202, 4195332, 7340039, 3072, 6291462, 1051649, 2099202, 3147779, 7340039, 5243909, 2099202, 7340039, 3147779, 7340039, 5243909, 1051649, 4195332, 2099202, 4195332, 5243909, 2099202, 7340039, 3147779, 4195332, 1051649, 6291462, 3147779, 3072, 7340039, 2099202, 4195332, 3072, 5243909, 1051649, 6291462, 3147779, 6291462, 1051649, 4195332, 3147779, 6291462, 7340039, 2099202, 6291462, 5243909, 1051649, 4195332, 7340039, 2099202, 6291462, 3147779, 4195332, 5243909, 2099202, 4195332, 3072, 5243909, 3147779, 3072, 4195332, 3147779, 6291462, 2099202, 4195332, 2099202, 3072, 7340039, 1051649, 2099202, 6291462, 3147779, 3072, 4195332, 1051649, 7340039, 5243909, 2099202, 1051649, 7340039, 1051649, 7340039, 3147779, 6291462, 4195332, 4195332, 3072, 6291462, 3072, 5243909, 1051649, 7340039, 4195332, 1051649, 6291462, 3147779, 2099202, 6291462, 3147779, 5243909, 3072, 5243909, 1051649, 3072, 7340039, 3147779, 6291462, 3072, 7340039, 5243909, 2099202, 6291462, 3147779, 1051649, 5243909,
+ 3072, 7340039, 2099202, 3072, 3147779, 2099202, 4195332, 3147779, 6291462, 5243909, 6291462, 3147779, 2099202, 3072, 7340039, 3147779, 1051649, 5243909, 3147779, 5243909, 6291462, 2099202, 1051649, 5243909, 1051649, 4195332, 1051649, 4195332, 2099202, 7340039, 3147779, 7340039, 1051649, 3147779, 5243909, 1051649, 2099202, 7340039, 3147779, 2099202, 7340039, 4195332, 1051649, 5243909, 6291462, 3147779, 4195332, 4195332, 3072, 3147779, 7340039, 2099202, 7340039, 3072, 2099202, 4195332, 1051649, 4195332, 3072, 6291462, 3147779, 3072, 3147779, 5243909, 1051649, 7340039, 3072, 3147779, 6291462, 2099202, 1051649, 5243909, 7340039, 2099202, 5243909, 3072, 6291462, 3072, 5243909, 3147779, 2099202, 7340039, 5243909, 3072, 4195332, 6291462, 3147779, 6291462, 2099202, 3072, 6291462, 4195332, 3147779, 3147779, 3072, 5243909, 1051649, 1051649, 5243909, 2099202, 3147779, 5243909, 2099202, 3147779, 5243909, 2099202, 5243909, 3072, 4195332, 5243909, 3072, 7340039, 1051649, 6291462, 2099202, 7340039, 2099202, 5243909, 1051649, 1051649, 5243909, 2099202, 1051649, 4195332, 3072, 5243909, 3147779, 6291462,
+ 4195332, 1051649, 6291462, 4195332, 5243909, 6291462, 3072, 5243909, 2099202, 1051649, 4195332, 3072, 6291462, 5243909, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 4195332, 3072, 7340039, 3147779, 6291462, 2099202, 6291462, 3072, 6291462, 4195332, 3072, 5243909, 6291462, 3072, 5243909, 3147779, 5243909, 3072, 6291462, 5243909, 1051649, 6291462, 3147779, 2099202, 3072, 7340039, 1051649, 3147779, 6291462, 4195332, 3072, 5243909, 3147779, 5243909, 1051649, 7340039, 3147779, 6291462, 3147779, 4195332, 1051649, 7340039, 5243909, 3072, 4195332, 1051649, 5243909, 7340039, 3072, 4195332, 6291462, 3147779, 1051649, 3147779, 7340039, 2099202, 5243909, 7340039, 1051649, 6291462, 4195332, 3072, 4195332, 1051649, 7340039, 2099202, 3072, 3147779, 5243909, 4195332, 3147779, 1051649, 6291462, 5243909, 2099202, 7340039, 3147779, 6291462, 2099202, 7340039, 4195332, 3072, 7340039, 6291462, 3072, 7340039, 2099202, 3147779, 7340039, 1051649, 6291462, 2099202, 4195332, 2099202, 5243909, 1051649, 4195332, 3147779, 7340039, 5243909, 3147779, 3147779, 6291462, 2099202, 6291462, 1051649, 7340039, 2099202,
+ 3147779, 7340039, 2099202, 7340039, 3072, 2099202, 4195332, 1051649, 7340039, 3072, 7340039, 5243909, 1051649, 3147779, 6291462, 3072, 4195332, 6291462, 1051649, 7340039, 2099202, 5243909, 4195332, 3147779, 3072, 6291462, 3147779, 5243909, 1051649, 2099202, 5243909, 1051649, 2099202, 6291462, 1051649, 7340039, 2099202, 4195332, 1051649, 4195332, 2099202, 3072, 5243909, 7340039, 3147779, 5243909, 2099202, 6291462, 2099202, 5243909, 2099202, 6291462, 1051649, 4195332, 5243909, 3072, 5243909, 2099202, 3072, 6291462, 2099202, 5243909, 2099202, 7340039, 3147779, 6291462, 1051649, 4195332, 5243909, 1051649, 6291462, 3072, 7340039, 4195332, 1051649, 4195332, 1051649, 3147779, 4195332, 2099202, 3147779, 7340039, 3147779, 6291462, 2099202, 5243909, 7340039, 1051649, 6291462, 3072, 7340039, 6291462, 3072, 1051649, 5243909, 3072, 4195332, 3072, 5243909, 1051649, 6291462, 3147779, 4195332, 1051649, 4195332, 1051649, 6291462, 5243909, 3072, 4195332, 3147779, 5243909, 3072, 4195332, 7340039, 3147779, 5243909, 3072, 4195332, 1051649, 7340039, 5243909, 3072, 7340039, 3147779, 5243909, 3072, 4195332,
+ 3072, 5243909, 1051649, 3147779, 4195332, 7340039, 3147779, 5243909, 2099202, 6291462, 3147779, 2099202, 7340039, 2099202, 2099202, 5243909, 3147779, 3072, 5243909, 2099202, 6291462, 1051649, 1051649, 6291462, 5243909, 1051649, 7340039, 3072, 4195332, 7340039, 2099202, 7340039, 3147779, 6291462, 4195332, 3072, 6291462, 2099202, 7340039, 3072, 7340039, 4195332, 2099202, 4195332, 1051649, 3147779, 6291462, 3072, 4195332, 7340039, 3072, 3147779, 7340039, 3072, 3147779, 6291462, 1051649, 7340039, 5243909, 2099202, 7340039, 3072, 4195332, 2099202, 6291462, 3072, 7340039, 2099202, 2099202, 7340039, 2099202, 3147779, 5243909, 1051649, 6291462, 5243909, 3147779, 6291462, 3072, 6291462, 5243909, 3072, 4195332, 1051649, 4195332, 3072, 4195332, 7340039, 2099202, 5243909, 2099202, 4195332, 3147779, 7340039, 3147779, 6291462, 2099202, 7340039, 4195332, 3147779, 1051649, 3072, 6291462, 2099202, 7340039, 5243909, 3147779, 1051649, 3147779, 7340039, 1051649, 7340039, 6291462, 2099202, 3072, 6291462, 1051649, 6291462, 2099202, 6291462, 3072, 2099202, 4195332, 1051649, 4195332, 7340039, 2099202, 6291462,
+ 6291462, 3147779, 5243909, 6291462, 1051649, 6291462, 1051649, 7340039, 4195332, 3072, 4195332, 5243909, 3072, 4195332, 6291462, 1051649, 7340039, 3147779, 7340039, 3072, 3147779, 7340039, 6291462, 1051649, 3147779, 4195332, 2099202, 5243909, 3147779, 4195332, 1051649, 4195332, 3072, 2099202, 3147779, 7340039, 1051649, 4195332, 3147779, 5243909, 2099202, 6291462, 3072, 7340039, 1051649, 7340039, 3072, 5243909, 1051649, 4195332, 1051649, 6291462, 5243909, 2099202, 7340039, 4195332, 3147779, 4195332, 1051649, 6291462, 3147779, 1051649, 6291462, 1051649, 3147779, 5243909, 2099202, 4195332, 6291462, 1051649, 4195332, 7340039, 3072, 4195332, 2099202, 3072, 7340039, 1051649, 5243909, 2099202, 1051649, 5243909, 6291462, 2099202, 7340039, 3147779, 5243909, 3072, 4195332, 3147779, 1051649, 7340039, 5243909, 3072, 4195332, 1051649, 4195332, 2099202, 3072, 6291462, 5243909, 7340039, 2099202, 4195332, 2099202, 3072, 3147779, 7340039, 5243909, 2099202, 5243909, 3147779, 1051649, 7340039, 4195332, 3147779, 2099202, 4195332, 3147779, 4195332, 2099202, 6291462, 5243909, 2099202, 6291462, 3072, 4195332, 1051649,
+ 1051649, 4195332, 3072, 2099202, 5243909, 3072, 3147779, 3072, 4195332, 7340039, 3147779, 1051649, 7340039, 3147779, 5243909, 2099202, 5243909, 1051649, 4195332, 5243909, 4195332, 3072, 2099202, 7340039, 5243909, 3072, 6291462, 1051649, 7340039, 3072, 6291462, 3147779, 5243909, 3147779, 5243909, 3072, 5243909, 6291462, 3072, 6291462, 1051649, 3147779, 5243909, 3147779, 6291462, 2099202, 5243909, 4195332, 7340039, 2099202, 5243909, 3147779, 1051649, 5243909, 3072, 2099202, 6291462, 3072, 7340039, 3072, 4195332, 5243909, 3147779, 5243909, 1051649, 6291462, 3072, 6291462, 3072, 5243909, 3072, 3147779, 6291462, 2099202, 7340039, 4195332, 2099202, 7340039, 4195332, 2099202, 7340039, 3147779, 1051649, 6291462, 1051649, 5243909, 1051649, 6291462, 2099202, 6291462, 4195332, 1051649, 2099202, 6291462, 2099202, 7340039, 5243909, 3147779, 5243909, 2099202, 4195332, 1051649, 5243909, 3072, 6291462, 4195332, 6291462, 3072, 2099202, 6291462, 3072, 4195332, 4195332, 1051649, 5243909, 3072, 7340039, 1051649, 7340039, 3072, 7340039, 3147779, 3072, 7340039, 1051649, 5243909, 2099202, 7340039,
+ 1051649, 5243909, 7340039, 2099202, 6291462, 3147779, 6291462, 5243909, 2099202, 5243909, 3072, 6291462, 3147779, 3072, 1051649, 6291462, 3072, 6291462, 3147779, 1051649, 7340039, 2099202, 4195332, 3072, 2099202, 7340039, 4195332, 3147779, 1051649, 6291462, 2099202, 7340039, 3072, 7340039, 1051649, 6291462, 3147779, 2099202, 4195332, 3147779, 6291462, 1051649, 1051649, 4195332, 1051649, 3147779, 7340039, 2099202, 3072, 6291462, 1051649, 7340039, 2099202, 7340039, 3147779, 5243909, 2099202, 5243909, 3147779, 2099202, 7340039, 3072, 4195332, 7340039, 3072, 4195332, 3147779, 4195332, 2099202, 7340039, 5243909, 1051649, 6291462, 3147779, 1051649, 5243909, 3147779, 3072, 3147779, 6291462, 3072, 6291462, 5243909, 3147779, 4195332, 3072, 7340039, 3147779, 6291462, 3072, 3147779, 6291462, 4195332, 3072, 5243909, 1051649, 3072, 7340039, 1051649, 7340039, 3072, 6291462, 3147779, 4195332, 7340039, 1051649, 2099202, 6291462, 4195332, 4195332, 2099202, 6291462, 3072, 7340039, 3147779, 6291462, 4195332, 5243909, 2099202, 4195332, 5243909, 1051649, 3147779, 4195332, 6291462, 3147779, 3147779, 5243909,
+ 7340039, 3147779, 3072, 4195332, 1051649, 4195332, 2099202, 1051649, 6291462, 1051649, 4195332, 2099202, 4195332, 7340039, 5243909, 4195332, 3147779, 2099202, 7340039, 3147779, 2099202, 5243909, 6291462, 3147779, 5243909, 1051649, 3072, 6291462, 5243909, 2099202, 4195332, 1051649, 5243909, 2099202, 4195332, 4195332, 1051649, 7340039, 3072, 7340039, 4195332, 5243909, 7340039, 3072, 6291462, 5243909, 1051649, 3147779, 6291462, 2099202, 4195332, 3072, 4195332, 1051649, 4195332, 3072, 7340039, 1051649, 4195332, 6291462, 1051649, 5243909, 1051649, 2099202, 4195332, 7340039, 2099202, 7340039, 3147779, 1051649, 4195332, 4195332, 3072, 5243909, 1051649, 6291462, 5243909, 6291462, 5243909, 1051649, 4195332, 2099202, 3072, 2099202, 7340039, 4195332, 2099202, 3072, 5243909, 2099202, 7340039, 1051649, 3147779, 7340039, 3147779, 6291462, 3147779, 6291462, 4195332, 3147779, 6291462, 2099202, 7340039, 1051649, 2099202, 5243909, 3147779, 1051649, 7340039, 1051649, 5243909, 2099202, 4195332, 5243909, 3072, 2099202, 3072, 2099202, 6291462, 1051649, 3072, 6291462, 7340039, 3072, 2099202, 6291462, 3072, 3147779,
+ 3072, 5243909, 2099202, 6291462, 7340039, 3072, 7340039, 5243909, 3147779, 6291462, 2099202, 7340039, 5243909, 1051649, 2099202, 3072, 7340039, 4195332, 3072, 6291462, 3072, 5243909, 1051649, 7340039, 3147779, 6291462, 5243909, 2099202, 3072, 5243909, 3072, 7340039, 4195332, 6291462, 3072, 7340039, 2099202, 4195332, 5243909, 2099202, 3072, 2099202, 6291462, 4195332, 2099202, 3072, 6291462, 4195332, 1051649, 5243909, 3147779, 6291462, 3147779, 7340039, 2099202, 6291462, 3147779, 5243909, 3072, 4195332, 3147779, 7340039, 3147779, 6291462, 3147779, 1051649, 6291462, 3072, 5243909, 3147779, 6291462, 2099202, 7340039, 3147779, 7340039, 3072, 3147779, 2099202, 1051649, 7340039, 3147779, 7340039, 4195332, 5243909, 1051649, 3147779, 6291462, 3147779, 4195332, 5243909, 2099202, 5243909, 3072, 6291462, 1051649, 5243909, 1051649, 2099202, 3072, 5243909, 1051649, 5243909, 3072, 3147779, 6291462, 3072, 7340039, 5243909, 3072, 6291462, 3147779, 7340039, 1051649, 6291462, 3147779, 7340039, 5243909, 6291462, 3147779, 5243909, 7340039, 2099202, 4195332, 3147779, 5243909, 1051649, 7340039, 4195332,
+ 2099202, 6291462, 3147779, 1051649, 3147779, 2099202, 5243909, 2099202, 3072, 7340039, 1051649, 3147779, 3072, 6291462, 4195332, 6291462, 3147779, 1051649, 5243909, 2099202, 7340039, 1051649, 4195332, 3072, 4195332, 1051649, 3147779, 7340039, 4195332, 3147779, 6291462, 2099202, 3147779, 1051649, 3147779, 5243909, 3072, 6291462, 1051649, 7340039, 3147779, 5243909, 3072, 3147779, 7340039, 5243909, 2099202, 3147779, 7340039, 3072, 5243909, 1051649, 6291462, 1051649, 5243909, 3072, 2099202, 4195332, 7340039, 1051649, 6291462, 3072, 5243909, 1051649, 5243909, 4195332, 2099202, 4195332, 1051649, 7340039, 3072, 2099202, 5243909, 3072, 2099202, 4195332, 1051649, 7340039, 6291462, 1051649, 4195332, 2099202, 1051649, 6291462, 3072, 7340039, 1051649, 7340039, 1051649, 3072, 7340039, 3147779, 4195332, 2099202, 7340039, 3147779, 7340039, 4195332, 2099202, 7340039, 3147779, 4195332, 6291462, 1051649, 5243909, 3147779, 2099202, 4195332, 3147779, 4195332, 3072, 5243909, 1051649, 3147779, 2099202, 4195332, 1051649, 3147779, 3072, 2099202, 3147779, 5243909, 1051649, 7340039, 2099202, 5243909, 1051649, 4195332,
+ 6291462, 3072, 7340039, 4195332, 6291462, 4195332, 3072, 7340039, 4195332, 4195332, 1051649, 6291462, 3147779, 7340039, 2099202, 1051649, 6291462, 5243909, 3147779, 4195332, 3147779, 6291462, 3147779, 6291462, 2099202, 7340039, 4195332, 3072, 7340039, 1051649, 5243909, 3072, 6291462, 7340039, 4195332, 2099202, 7340039, 3147779, 5243909, 6291462, 1051649, 2099202, 6291462, 4195332, 1051649, 3147779, 7340039, 3072, 4195332, 5243909, 2099202, 6291462, 3072, 3147779, 4195332, 7340039, 6291462, 1051649, 4195332, 2099202, 5243909, 2099202, 6291462, 3072, 7340039, 3072, 6291462, 2099202, 5243909, 4195332, 6291462, 3147779, 6291462, 4195332, 6291462, 5243909, 3072, 3147779, 4195332, 5243909, 3072, 6291462, 4195332, 5243909, 3147779, 4195332, 5243909, 2099202, 4195332, 6291462, 2099202, 5243909, 1051649, 6291462, 2099202, 3072, 5243909, 2099202, 6291462, 3147779, 1051649, 5243909, 2099202, 7340039, 1051649, 6291462, 4195332, 1051649, 6291462, 1051649, 7340039, 2099202, 7340039, 5243909, 6291462, 3072, 6291462, 7340039, 4195332, 7340039, 3072, 4195332, 1051649, 6291462, 3072, 4195332, 7340039, 2099202,
+ 4195332, 5243909, 1051649, 5243909, 3072, 3147779, 5243909, 1051649, 6291462, 2099202, 5243909, 2099202, 5243909, 3072, 4195332, 5243909, 2099202, 3072, 7340039, 1051649, 6291462, 3072, 5243909, 1051649, 2099202, 5243909, 1051649, 5243909, 2099202, 4195332, 3147779, 7340039, 2099202, 3072, 3147779, 5243909, 1051649, 4195332, 2099202, 3072, 4195332, 7340039, 4195332, 1051649, 5243909, 3072, 4195332, 6291462, 2099202, 7340039, 1051649, 4195332, 5243909, 7340039, 2099202, 3072, 5243909, 3147779, 6291462, 1051649, 7340039, 4195332, 3147779, 3147779, 2099202, 5243909, 3147779, 7340039, 3072, 3147779, 1051649, 5243909, 3072, 2099202, 1051649, 6291462, 2099202, 7340039, 3072, 3147779, 7340039, 3072, 3147779, 2099202, 6291462, 3072, 1051649, 7340039, 3072, 3147779, 1051649, 7340039, 3072, 5243909, 3147779, 5243909, 3072, 7340039, 3072, 4195332, 7340039, 3072, 4195332, 3147779, 4195332, 3072, 3147779, 7340039, 3072, 5243909, 3147779, 3072, 4195332, 3072, 3147779, 7340039, 2099202, 1051649, 4195332, 1051649, 6291462, 3147779, 6291462, 3147779, 2099202, 6291462, 1051649, 3147779,
+ 3072, 3147779, 2099202, 7340039, 2099202, 6291462, 3072, 4195332, 1051649, 7340039, 3072, 3147779, 7340039, 3147779, 7340039, 3072, 3147779, 5243909, 2099202, 4195332, 2099202, 3147779, 7340039, 4195332, 6291462, 3072, 7340039, 3147779, 3072, 6291462, 1051649, 1051649, 5243909, 4195332, 1051649, 6291462, 6291462, 3072, 7340039, 3147779, 5243909, 1051649, 3072, 7340039, 3147779, 6291462, 3147779, 1051649, 5243909, 3147779, 6291462, 2099202, 1051649, 3147779, 4195332, 6291462, 2099202, 1051649, 6291462, 3072, 3147779, 3072, 6291462, 7340039, 1051649, 6291462, 1051649, 2099202, 6291462, 1051649, 7340039, 4195332, 5243909, 7340039, 4195332, 3072, 5243909, 2099202, 6291462, 4195332, 2099202, 5243909, 7340039, 3072, 4195332, 7340039, 5243909, 3147779, 4195332, 6291462, 2099202, 4195332, 4195332, 1051649, 7340039, 2099202, 4195332, 5243909, 3147779, 1051649, 6291462, 2099202, 5243909, 3072, 6291462, 2099202, 5243909, 2099202, 4195332, 2099202, 6291462, 2099202, 6291462, 3147779, 5243909, 1051649, 4195332, 5243909, 6291462, 5243909, 3072, 4195332, 1051649, 5243909, 7340039, 3072, 5243909, 6291462,
+ 7340039, 5243909, 4195332, 1051649, 5243909, 3147779, 7340039, 3147779, 5243909, 3147779, 4195332, 6291462, 1051649, 4195332, 1051649, 5243909, 6291462, 1051649, 7340039, 3072, 6291462, 5243909, 3072, 2099202, 3147779, 4195332, 2099202, 6291462, 3147779, 4195332, 7340039, 5243909, 2099202, 7340039, 4195332, 2099202, 2099202, 4195332, 1051649, 6291462, 3147779, 5243909, 2099202, 5243909, 2099202, 1051649, 5243909, 7340039, 3072, 4195332, 3072, 7340039, 3147779, 6291462, 3072, 3147779, 7340039, 4195332, 5243909, 2099202, 7340039, 4195332, 1051649, 3147779, 4195332, 2099202, 4195332, 5243909, 3147779, 5243909, 2099202, 3072, 3147779, 1051649, 3147779, 7340039, 3147779, 5243909, 1051649, 5243909, 1051649, 6291462, 2099202, 5243909, 2099202, 3147779, 1051649, 5243909, 1051649, 6291462, 3072, 7340039, 3147779, 6291462, 3147779, 3072, 6291462, 2099202, 6291462, 1051649, 4195332, 5243909, 2099202, 7340039, 1051649, 7340039, 3147779, 3072, 7340039, 5243909, 1051649, 5243909, 1051649, 7340039, 2099202, 6291462, 3072, 3147779, 1051649, 2099202, 7340039, 5243909, 3072, 3147779, 1051649, 5243909, 3147779, 2099202,
+ 3072, 6291462, 1051649, 6291462, 4195332, 2099202, 1051649, 6291462, 3072, 6291462, 2099202, 3072, 5243909, 6291462, 2099202, 7340039, 3072, 3147779, 4195332, 5243909, 1051649, 3147779, 5243909, 7340039, 1051649, 6291462, 4195332, 3072, 7340039, 1051649, 3147779, 3072, 3147779, 1051649, 6291462, 3072, 5243909, 3147779, 5243909, 2099202, 3072, 7340039, 1051649, 6291462, 4195332, 6291462, 2099202, 1051649, 4195332, 7340039, 2099202, 5243909, 3072, 5243909, 2099202, 5243909, 3072, 6291462, 1051649, 3147779, 5243909, 2099202, 6291462, 3072, 7340039, 3147779, 7340039, 3072, 7340039, 3072, 4195332, 7340039, 6291462, 6291462, 1051649, 4195332, 3072, 2099202, 3147779, 7340039, 3072, 4195332, 1051649, 4195332, 3072, 6291462, 6291462, 3072, 7340039, 1051649, 3147779, 5243909, 2099202, 1051649, 4195332, 7340039, 1051649, 7340039, 3072, 3147779, 7340039, 3072, 6291462, 3147779, 4195332, 1051649, 5243909, 6291462, 3147779, 1051649, 7340039, 4195332, 4195332, 3072, 4195332, 3147779, 7340039, 4195332, 7340039, 3072, 3147779, 2099202, 6291462, 4195332, 7340039, 3147779, 1051649, 5243909,
+ 2099202, 3147779, 7340039, 2099202, 3072, 6291462, 4195332, 3147779, 5243909, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 3147779, 4195332, 7340039, 1051649, 2099202, 6291462, 2099202, 3072, 5243909, 3147779, 1051649, 6291462, 5243909, 2099202, 5243909, 6291462, 3147779, 6291462, 5243909, 3147779, 7340039, 3072, 7340039, 1051649, 6291462, 3147779, 4195332, 3147779, 7340039, 3072, 3147779, 5243909, 3147779, 6291462, 2099202, 5243909, 1051649, 4195332, 1051649, 7340039, 3147779, 1051649, 2099202, 7340039, 4195332, 3072, 7340039, 1051649, 4195332, 5243909, 3072, 5243909, 1051649, 3147779, 5243909, 2099202, 1051649, 3072, 4195332, 2099202, 5243909, 7340039, 6291462, 4195332, 3147779, 6291462, 2099202, 7340039, 3147779, 7340039, 1051649, 3147779, 4195332, 2099202, 6291462, 4195332, 3072, 5243909, 6291462, 3072, 4195332, 2099202, 4195332, 3147779, 5243909, 2099202, 4195332, 3147779, 1051649, 6291462, 5243909, 2099202, 4195332, 3072, 6291462, 3147779, 3072, 7340039, 2099202, 6291462, 1051649, 2099202, 3072, 5243909, 3147779, 7340039, 5243909, 1051649, 6291462, 2099202, 3072, 4195332, 7340039,
+ 6291462, 3072, 4195332, 3147779, 5243909, 1051649, 7340039, 3072, 7340039, 5243909, 3147779, 3072, 5243909, 1051649, 6291462, 5243909, 1051649, 3147779, 6291462, 5243909, 4195332, 7340039, 4195332, 2099202, 4195332, 7340039, 3072, 2099202, 4195332, 3072, 4195332, 1051649, 5243909, 3072, 2099202, 5243909, 2099202, 3147779, 4195332, 2099202, 7340039, 3072, 5243909, 2099202, 4195332, 7340039, 3072, 4195332, 1051649, 3072, 6291462, 3147779, 7340039, 4195332, 1051649, 6291462, 5243909, 4195332, 2099202, 6291462, 1051649, 4195332, 5243909, 2099202, 6291462, 1051649, 4195332, 6291462, 2099202, 4195332, 6291462, 7340039, 4195332, 3147779, 7340039, 3072, 3147779, 1051649, 3072, 6291462, 1051649, 5243909, 3072, 6291462, 2099202, 5243909, 6291462, 2099202, 5243909, 3072, 3147779, 7340039, 2099202, 4195332, 6291462, 2099202, 5243909, 1051649, 6291462, 1051649, 7340039, 5243909, 3072, 7340039, 3147779, 3072, 7340039, 1051649, 5243909, 4195332, 2099202, 5243909, 1051649, 5243909, 2099202, 5243909, 4195332, 6291462, 4195332, 1051649, 2099202, 4195332, 2099202, 3072, 5243909, 6291462, 4195332, 1051649,
+ 4195332, 1051649, 5243909, 1051649, 7340039, 4195332, 2099202, 3147779, 2099202, 4195332, 2099202, 7340039, 3147779, 5243909, 2099202, 7340039, 2099202, 6291462, 3072, 2099202, 3072, 3147779, 1051649, 7340039, 3072, 5243909, 3147779, 7340039, 1051649, 6291462, 2099202, 7340039, 1051649, 7340039, 4195332, 7340039, 1051649, 6291462, 3072, 5243909, 4195332, 1051649, 6291462, 3072, 3147779, 1051649, 6291462, 2099202, 7340039, 5243909, 3147779, 3072, 3147779, 6291462, 2099202, 4195332, 3072, 7340039, 3072, 3147779, 3147779, 1051649, 7340039, 3072, 3147779, 7340039, 3147779, 2099202, 6291462, 3072, 3147779, 1051649, 2099202, 5243909, 1051649, 5243909, 2099202, 4195332, 5243909, 2099202, 7340039, 3147779, 5243909, 1051649, 4195332, 3072, 3147779, 5243909, 3072, 7340039, 4195332, 1051649, 5243909, 1051649, 3147779, 7340039, 3072, 6291462, 2099202, 4195332, 3072, 3147779, 5243909, 4195332, 2099202, 5243909, 3147779, 6291462, 2099202, 1051649, 6291462, 3147779, 7340039, 3072, 6291462, 3072, 7340039, 2099202, 1051649, 5243909, 6291462, 3072, 7340039, 4195332, 3147779, 1051649, 7340039, 3147779,
+ 7340039, 6291462, 3147779, 7340039, 2099202, 3072, 5243909, 6291462, 3072, 6291462, 1051649, 6291462, 3072, 2099202, 4195332, 3072, 4195332, 1051649, 7340039, 4195332, 7340039, 6291462, 5243909, 1051649, 6291462, 2099202, 6291462, 1051649, 5243909, 4195332, 3072, 3147779, 6291462, 2099202, 4195332, 3072, 4195332, 4195332, 2099202, 6291462, 1051649, 4195332, 3147779, 6291462, 7340039, 4195332, 2099202, 6291462, 3072, 6291462, 1051649, 7340039, 4195332, 3072, 5243909, 7340039, 1051649, 3147779, 5243909, 6291462, 5243909, 4195332, 2099202, 6291462, 1051649, 5243909, 3072, 7340039, 1051649, 5243909, 6291462, 5243909, 6291462, 1051649, 7340039, 3147779, 6291462, 3072, 7340039, 2099202, 4195332, 1051649, 6291462, 3147779, 7340039, 5243909, 1051649, 7340039, 2099202, 5243909, 2099202, 6291462, 3072, 7340039, 4195332, 3147779, 5243909, 3147779, 1051649, 7340039, 6291462, 2099202, 7340039, 1051649, 7340039, 4195332, 1051649, 3072, 4195332, 7340039, 5243909, 3072, 3147779, 2099202, 4195332, 5243909, 1051649, 3147779, 7340039, 3072, 3147779, 6291462, 4195332, 3072, 7340039, 2099202, 5243909, 3072,
+ 2099202, 3072, 5243909, 1051649, 4195332, 6291462, 3147779, 1051649, 7340039, 3147779, 5243909, 3147779, 1051649, 7340039, 6291462, 3147779, 6291462, 5243909, 1051649, 4195332, 2099202, 3072, 3147779, 7340039, 4195332, 3072, 3147779, 5243909, 2099202, 7340039, 3147779, 6291462, 1051649, 5243909, 2099202, 6291462, 1051649, 7340039, 3072, 3147779, 7340039, 5243909, 3072, 5243909, 2099202, 3072, 5243909, 3147779, 4195332, 4195332, 2099202, 5243909, 2099202, 6291462, 1051649, 2099202, 4195332, 6291462, 1051649, 2099202, 3072, 7340039, 2099202, 3147779, 6291462, 2099202, 5243909, 4195332, 4195332, 1051649, 2099202, 3072, 7340039, 4195332, 3072, 6291462, 3147779, 4195332, 1051649, 5243909, 3072, 7340039, 1051649, 4195332, 3072, 3147779, 2099202, 6291462, 4195332, 1051649, 7340039, 3147779, 4195332, 2099202, 3072, 6291462, 1051649, 6291462, 3072, 4195332, 1051649, 5243909, 2099202, 4195332, 3072, 2099202, 6291462, 3147779, 6291462, 3072, 2099202, 7340039, 4195332, 6291462, 2099202, 7340039, 3147779, 5243909, 2099202, 6291462, 5243909, 1051649, 2099202, 5243909, 4195332, 2099202, 6291462, 3147779,
+ 7340039, 2099202, 4195332, 6291462, 2099202, 3072, 6291462, 4195332, 2099202, 5243909, 3072, 7340039, 4195332, 3147779, 1051649, 4195332, 3072, 5243909, 1051649, 3147779, 6291462, 2099202, 5243909, 1051649, 3147779, 4195332, 7340039, 3072, 4195332, 1051649, 5243909, 1051649, 4195332, 6291462, 3072, 1051649, 5243909, 3147779, 6291462, 5243909, 2099202, 1051649, 7340039, 1051649, 6291462, 3147779, 7340039, 1051649, 7340039, 1051649, 6291462, 3072, 7340039, 4195332, 3147779, 7340039, 3072, 3147779, 5243909, 7340039, 4195332, 1051649, 5243909, 3072, 4195332, 7340039, 3072, 2099202, 7340039, 3147779, 6291462, 3147779, 2099202, 3147779, 5243909, 2099202, 1051649, 7340039, 3147779, 4195332, 2099202, 5243909, 3147779, 7340039, 2099202, 6291462, 4195332, 3072, 3147779, 5243909, 3072, 5243909, 1051649, 6291462, 5243909, 2099202, 7340039, 2099202, 4195332, 7340039, 3147779, 6291462, 3072, 6291462, 3147779, 7340039, 1051649, 5243909, 2099202, 4195332, 5243909, 3147779, 1051649, 3072, 5243909, 1051649, 6291462, 3072, 4195332, 3147779, 3072, 7340039, 6291462, 3147779, 1051649, 6291462, 3072, 5243909,
+ 1051649, 3147779, 7340039, 3072, 5243909, 7340039, 2099202, 4195332, 1051649, 7340039, 4195332, 1051649, 6291462, 3072, 6291462, 2099202, 7340039, 3147779, 7340039, 3072, 5243909, 4195332, 1051649, 7340039, 5243909, 1051649, 6291462, 3147779, 6291462, 2099202, 4195332, 3147779, 7340039, 2099202, 7340039, 3147779, 6291462, 3072, 3147779, 2099202, 4195332, 6291462, 3147779, 4195332, 3072, 5243909, 1051649, 5243909, 3147779, 7340039, 2099202, 4195332, 3147779, 3072, 6291462, 1051649, 3147779, 5243909, 3072, 2099202, 3147779, 6291462, 2099202, 7340039, 3147779, 1051649, 4195332, 6291462, 3072, 5243909, 1051649, 7340039, 5243909, 3072, 6291462, 4195332, 5243909, 3072, 6291462, 1051649, 7340039, 2099202, 3072, 6291462, 1051649, 5243909, 2099202, 7340039, 4195332, 3147779, 6291462, 2099202, 7340039, 3072, 3147779, 4195332, 1051649, 5243909, 3072, 5243909, 3072, 3147779, 5243909, 1051649, 5243909, 4195332, 2099202, 6291462, 3072, 7340039, 1051649, 3147779, 7340039, 4195332, 3147779, 6291462, 2099202, 4195332, 1051649, 6291462, 2099202, 4195332, 1051649, 3072, 5243909, 3147779, 1051649, 5243909,
+ 4195332, 1051649, 4195332, 2099202, 3147779, 1051649, 7340039, 3072, 3147779, 6291462, 2099202, 5243909, 2099202, 5243909, 1051649, 5243909, 3072, 6291462, 2099202, 4195332, 2099202, 6291462, 3147779, 4195332, 3072, 6291462, 2099202, 2099202, 3072, 7340039, 3072, 6291462, 3072, 3147779, 4195332, 5243909, 1051649, 4195332, 7340039, 3072, 7340039, 3072, 2099202, 7340039, 2099202, 4195332, 6291462, 2099202, 3072, 5243909, 1051649, 1051649, 6291462, 2099202, 5243909, 4195332, 6291462, 2099202, 7340039, 4195332, 6291462, 3072, 4195332, 5243909, 3072, 6291462, 5243909, 3147779, 2099202, 6291462, 4195332, 2099202, 4195332, 3147779, 1051649, 7340039, 2099202, 4195332, 3147779, 5243909, 3072, 5243909, 6291462, 2099202, 4195332, 3072, 6291462, 1051649, 1051649, 6291462, 1051649, 4195332, 3147779, 5243909, 1051649, 7340039, 3072, 6291462, 3147779, 2099202, 6291462, 6291462, 1051649, 3147779, 7340039, 3072, 6291462, 4195332, 2099202, 5243909, 1051649, 5243909, 3072, 6291462, 2099202, 3072, 6291462, 1051649, 7340039, 5243909, 3072, 5243909, 7340039, 4195332, 7340039, 2099202, 6291462, 3147779,
+ 3072, 6291462, 2099202, 5243909, 6291462, 4195332, 3147779, 5243909, 6291462, 3072, 4195332, 1051649, 7340039, 3147779, 4195332, 7340039, 2099202, 3147779, 3072, 7340039, 3147779, 3072, 6291462, 2099202, 7340039, 3147779, 4195332, 7340039, 5243909, 3147779, 4195332, 1051649, 5243909, 7340039, 2099202, 3072, 5243909, 2099202, 6291462, 2099202, 3147779, 5243909, 6291462, 1051649, 5243909, 3072, 7340039, 2099202, 4195332, 7340039, 3147779, 5243909, 3147779, 7340039, 3072, 2099202, 1051649, 5243909, 3072, 4195332, 1051649, 7340039, 3147779, 6291462, 1051649, 3147779, 1051649, 7340039, 4195332, 2099202, 3072, 7340039, 3072, 5243909, 6291462, 3072, 3147779, 1051649, 7340039, 2099202, 6291462, 3147779, 1051649, 5243909, 7340039, 3147779, 4195332, 7340039, 5243909, 2099202, 7340039, 3072, 7340039, 4195332, 6291462, 3147779, 2099202, 4195332, 2099202, 7340039, 3147779, 3072, 4195332, 5243909, 1051649, 4195332, 3147779, 1051649, 7340039, 3147779, 6291462, 2099202, 4195332, 3147779, 7340039, 4195332, 3147779, 4195332, 3147779, 3147779, 7340039, 2099202, 1051649, 3147779, 3072, 4195332, 1051649, 7340039,
+ 5243909, 4195332, 7340039, 3072, 2099202, 1051649, 5243909, 3072, 3147779, 7340039, 5243909, 1051649, 4195332, 3072, 4195332, 1051649, 3147779, 6291462, 5243909, 1051649, 4195332, 7340039, 3072, 5243909, 1051649, 6291462, 3072, 5243909, 1051649, 2099202, 6291462, 2099202, 5243909, 1051649, 4195332, 6291462, 3147779, 7340039, 1051649, 5243909, 1051649, 5243909, 1051649, 4195332, 4195332, 3147779, 1051649, 5243909, 3072, 4195332, 3072, 6291462, 1051649, 2099202, 5243909, 6291462, 7340039, 3147779, 7340039, 2099202, 3147779, 5243909, 1051649, 2099202, 5243909, 7340039, 2099202, 4195332, 3072, 6291462, 5243909, 2099202, 6291462, 1051649, 2099202, 5243909, 6291462, 5243909, 3072, 4195332, 1051649, 4195332, 7340039, 3072, 3147779, 1051649, 5243909, 3072, 3147779, 1051649, 5243909, 3147779, 2099202, 3072, 2099202, 6291462, 5243909, 7340039, 3072, 4195332, 1051649, 7340039, 1051649, 6291462, 3147779, 7340039, 2099202, 5243909, 3072, 4195332, 3072, 7340039, 5243909, 1051649, 5243909, 2099202, 7340039, 3072, 6291462, 1051649, 3072, 6291462, 4195332, 6291462, 2099202, 7340039, 5243909, 2099202,
+ 1051649, 3072, 3147779, 4195332, 7340039, 6291462, 2099202, 7340039, 2099202, 1051649, 2099202, 6291462, 3147779, 7340039, 2099202, 6291462, 5243909, 1051649, 4195332, 6291462, 2099202, 3147779, 5243909, 2099202, 4195332, 1051649, 7340039, 2099202, 4195332, 5243909, 3072, 7340039, 2099202, 3147779, 7340039, 1051649, 5243909, 3147779, 1051649, 7340039, 4195332, 2099202, 3147779, 7340039, 2099202, 6291462, 3147779, 4195332, 6291462, 2099202, 5243909, 2099202, 4195332, 7340039, 3147779, 3072, 1051649, 4195332, 1051649, 6291462, 3072, 4195332, 7340039, 4195332, 3072, 6291462, 3072, 7340039, 3147779, 4195332, 1051649, 3147779, 4195332, 3147779, 7340039, 1051649, 3147779, 2099202, 7340039, 4195332, 6291462, 3072, 2099202, 4195332, 6291462, 2099202, 7340039, 2099202, 6291462, 4195332, 3072, 5243909, 6291462, 2099202, 5243909, 3072, 3147779, 1051649, 5243909, 3147779, 5243909, 2099202, 6291462, 2099202, 2099202, 3072, 6291462, 3147779, 7340039, 1051649, 5243909, 3147779, 3072, 7340039, 1051649, 6291462, 3072, 5243909, 2099202, 5243909, 4195332, 2099202, 1051649, 3147779, 5243909, 3147779, 3072, 6291462,
+ 3147779, 7340039, 5243909, 3072, 3147779, 1051649, 4195332, 3072, 5243909, 6291462, 4195332, 3072, 7340039, 1051649, 5243909, 3147779, 3072, 7340039, 2099202, 3072, 7340039, 1051649, 7340039, 3072, 6291462, 4195332, 3147779, 6291462, 3072, 7340039, 3147779, 5243909, 3072, 6291462, 2099202, 4195332, 3072, 6291462, 3147779, 3072, 6291462, 3072, 6291462, 3147779, 3072, 6291462, 3072, 7340039, 1051649, 3147779, 6291462, 3072, 6291462, 1051649, 5243909, 4195332, 6291462, 3147779, 5243909, 2099202, 6291462, 3147779, 3072, 6291462, 3147779, 4195332, 2099202, 5243909, 1051649, 7340039, 6291462, 1051649, 7340039, 3072, 4195332, 3147779, 7340039, 3072, 4195332, 1051649, 2099202, 7340039, 3147779, 6291462, 3072, 2099202, 4195332, 3072, 7340039, 1051649, 6291462, 3147779, 1051649, 6291462, 4195332, 7340039, 3147779, 6291462, 1051649, 7340039, 1051649, 4195332, 3072, 4195332, 7340039, 4195332, 5243909, 1051649, 4195332, 6291462, 2099202, 2099202, 6291462, 4195332, 3147779, 4195332, 2099202, 7340039, 4195332, 1051649, 7340039, 3147779, 7340039, 3072, 6291462, 1051649, 7340039, 4195332,
+ 1051649, 4195332, 2099202, 6291462, 3147779, 5243909, 6291462, 4195332, 3147779, 1051649, 6291462, 4195332, 2099202, 5243909, 3072, 4195332, 6291462, 2099202, 4195332, 3147779, 5243909, 1051649, 3147779, 5243909, 2099202, 3072, 5243909, 1051649, 5243909, 3147779, 1051649, 6291462, 4195332, 3072, 7340039, 2099202, 6291462, 2099202, 7340039, 4195332, 3147779, 5243909, 1051649, 6291462, 5243909, 2099202, 3147779, 1051649, 4195332, 7340039, 3147779, 4195332, 3147779, 3072, 7340039, 2099202, 3072, 7340039, 3072, 5243909, 1051649, 5243909, 2099202, 6291462, 1051649, 7340039, 3147779, 1051649, 5243909, 3072, 2099202, 5243909, 2099202, 5243909, 1051649, 5243909, 1051649, 6291462, 3147779, 6291462, 5243909, 3147779, 1051649, 5243909, 4195332, 7340039, 3147779, 5243909, 3147779, 4195332, 2099202, 7340039, 4195332, 3072, 2099202, 1051649, 5243909, 3072, 4195332, 2099202, 5243909, 6291462, 3147779, 7340039, 1051649, 3072, 6291462, 2099202, 7340039, 3072, 4195332, 6291462, 1051649, 2099202, 7340039, 3072, 5243909, 1051649, 3147779, 6291462, 3072, 3147779, 5243909, 4195332, 2099202, 5243909, 2099202, 6291462,
+ 7340039, 2099202, 6291462, 1051649, 1051649, 7340039, 2099202, 1051649, 7340039, 5243909, 3072, 3147779, 6291462, 2099202, 6291462, 3147779, 1051649, 5243909, 3072, 7340039, 2099202, 5243909, 6291462, 1051649, 7340039, 4195332, 3147779, 6291462, 2099202, 7340039, 2099202, 4195332, 1051649, 3147779, 5243909, 1051649, 4195332, 5243909, 3072, 2099202, 1051649, 7340039, 4195332, 3072, 4195332, 1051649, 7340039, 5243909, 3072, 5243909, 1051649, 7340039, 6291462, 2099202, 5243909, 3147779, 4195332, 2099202, 5243909, 2099202, 4195332, 7340039, 2099202, 4195332, 5243909, 3072, 5243909, 2099202, 6291462, 4195332, 3147779, 7340039, 4195332, 3072, 6291462, 2099202, 7340039, 2099202, 5243909, 1051649, 3072, 5243909, 7340039, 1051649, 6291462, 3072, 5243909, 1051649, 6291462, 3072, 5243909, 1051649, 4195332, 6291462, 7340039, 3147779, 4195332, 2099202, 7340039, 5243909, 3072, 3147779, 1051649, 5243909, 3147779, 3147779, 7340039, 1051649, 3147779, 5243909, 1051649, 3147779, 5243909, 6291462, 1051649, 5243909, 2099202, 7340039, 5243909, 2099202, 5243909, 6291462, 1051649, 2099202, 7340039, 3147779, 4195332, 3072,
+ 4195332, 3072, 3147779, 5243909, 5243909, 3072, 3147779, 6291462, 3072, 2099202, 7340039, 3147779, 1051649, 7340039, 1051649, 3147779, 7340039, 3147779, 6291462, 2099202, 4195332, 3072, 4195332, 4195332, 2099202, 1051649, 7340039, 3072, 4195332, 1051649, 5243909, 3072, 7340039, 6291462, 3147779, 7340039, 3072, 3147779, 4195332, 6291462, 5243909, 3147779, 1051649, 7340039, 3147779, 5243909, 3147779, 2099202, 6291462, 1051649, 5243909, 3072, 2099202, 4195332, 6291462, 3072, 6291462, 1051649, 3147779, 7340039, 3147779, 3072, 6291462, 3072, 7340039, 3147779, 2099202, 7340039, 3147779, 1051649, 7340039, 1051649, 4195332, 7340039, 3147779, 5243909, 3072, 4195332, 3072, 6291462, 3147779, 4195332, 2099202, 4195332, 1051649, 2099202, 7340039, 2099202, 4195332, 6291462, 1051649, 7340039, 2099202, 3147779, 1051649, 5243909, 7340039, 3072, 3147779, 1051649, 7340039, 2099202, 6291462, 2099202, 6291462, 5243909, 3072, 4195332, 5243909, 2099202, 7340039, 4195332, 3072, 4195332, 3147779, 6291462, 3147779, 3072, 4195332, 1051649, 7340039, 3072, 4195332, 5243909, 3072, 6291462, 1051649, 5243909,
+ 2099202, 7340039, 6291462, 3072, 3147779, 7340039, 5243909, 2099202, 4195332, 6291462, 1051649, 5243909, 5243909, 3072, 4195332, 5243909, 3072, 4195332, 1051649, 6291462, 3147779, 6291462, 1051649, 7340039, 3072, 5243909, 2099202, 4195332, 6291462, 1051649, 6291462, 3147779, 5243909, 2099202, 1051649, 4195332, 6291462, 1051649, 5243909, 2099202, 3072, 7340039, 2099202, 4195332, 3072, 6291462, 1051649, 7340039, 3147779, 4195332, 3147779, 7340039, 5243909, 3147779, 1051649, 5243909, 1051649, 7340039, 4195332, 3072, 6291462, 1051649, 4195332, 3147779, 1051649, 6291462, 4195332, 3072, 4195332, 6291462, 3072, 5243909, 2099202, 3072, 4195332, 1051649, 6291462, 4195332, 7340039, 2099202, 7340039, 3072, 6291462, 3147779, 6291462, 4195332, 3147779, 3072, 5243909, 2099202, 3147779, 5243909, 3072, 6291462, 4195332, 3072, 2099202, 3147779, 6291462, 4195332, 2099202, 6291462, 3072, 4195332, 3072, 4195332, 2099202, 6291462, 3072, 6291462, 3147779, 1051649, 7340039, 1051649, 6291462, 3072, 7340039, 4195332, 6291462, 3072, 3147779, 6291462, 3147779, 1051649, 7340039, 2099202, 6291462, 3147779,
+ 5243909, 2099202, 1051649, 6291462, 4195332, 2099202, 3072, 7340039, 1051649, 4195332, 3072, 4195332, 2099202, 7340039, 4195332, 2099202, 7340039, 2099202, 5243909, 3072, 4195332, 1051649, 5243909, 3147779, 5243909, 3147779, 6291462, 3147779, 3072, 4195332, 3147779, 6291462, 3072, 7340039, 1051649, 6291462, 2099202, 7340039, 3072, 7340039, 4195332, 1051649, 5243909, 6291462, 2099202, 4195332, 2099202, 5243909, 3072, 7340039, 1051649, 2099202, 3072, 7340039, 2099202, 4195332, 6291462, 3147779, 1051649, 5243909, 2099202, 7340039, 2099202, 6291462, 3147779, 3072, 5243909, 6291462, 1051649, 2099202, 5243909, 3147779, 6291462, 3147779, 6291462, 4195332, 2099202, 3147779, 1051649, 5243909, 1051649, 5243909, 3147779, 5243909, 3072, 1051649, 7340039, 3147779, 6291462, 3072, 7340039, 3147779, 5243909, 2099202, 7340039, 4195332, 7340039, 6291462, 1051649, 5243909, 3072, 4195332, 5243909, 3147779, 7340039, 1051649, 7340039, 2099202, 7340039, 2099202, 3072, 5243909, 2099202, 4195332, 2099202, 5243909, 1051649, 2099202, 3147779, 6291462, 2099202, 3072, 7340039, 4195332, 5243909, 3072, 3147779, 1051649,
+ 3072, 7340039, 4195332, 3147779, 1051649, 6291462, 3147779, 5243909, 3147779, 5243909, 7340039, 1051649, 6291462, 3147779, 1051649, 6291462, 3072, 6291462, 4195332, 7340039, 6291462, 2099202, 7340039, 2099202, 1051649, 7340039, 3072, 2099202, 5243909, 7340039, 1051649, 2099202, 4195332, 4195332, 5243909, 3072, 4195332, 2099202, 5243909, 3147779, 3147779, 6291462, 3072, 2099202, 7340039, 3147779, 6291462, 1051649, 4195332, 2099202, 5243909, 6291462, 4195332, 6291462, 3072, 7340039, 2099202, 3072, 7340039, 5243909, 1051649, 4195332, 5243909, 1051649, 7340039, 4195332, 3147779, 1051649, 6291462, 4195332, 1051649, 7340039, 3072, 5243909, 1051649, 7340039, 3072, 6291462, 3147779, 6291462, 2099202, 4195332, 1051649, 2099202, 7340039, 5243909, 4195332, 3072, 6291462, 4195332, 1051649, 6291462, 3072, 4195332, 1051649, 3147779, 3072, 2099202, 4195332, 1051649, 3147779, 7340039, 2099202, 1051649, 2099202, 5243909, 4195332, 1051649, 3147779, 4195332, 5243909, 3147779, 6291462, 3072, 7340039, 3147779, 4195332, 7340039, 3072, 5243909, 4195332, 3147779, 5243909, 1051649, 2099202, 6291462, 4195332, 7340039,
+ 5243909, 3147779, 1051649, 7340039, 5243909, 2099202, 4195332, 3072, 7340039, 2099202, 1051649, 6291462, 3147779, 3072, 7340039, 3147779, 2099202, 5243909, 1051649, 3147779, 2099202, 5243909, 3072, 4195332, 6291462, 2099202, 4195332, 7340039, 1051649, 3147779, 6291462, 3072, 7340039, 2099202, 1051649, 6291462, 3147779, 1051649, 6291462, 3072, 6291462, 2099202, 4195332, 5243909, 1051649, 5243909, 3072, 3147779, 6291462, 7340039, 1051649, 3147779, 2099202, 1051649, 4195332, 1051649, 4195332, 5243909, 3147779, 2099202, 6291462, 3147779, 3072, 4195332, 2099202, 5243909, 2099202, 7340039, 3072, 6291462, 2099202, 4195332, 3147779, 2099202, 5243909, 1051649, 2099202, 5243909, 3072, 7340039, 3072, 4195332, 7340039, 5243909, 3147779, 1051649, 2099202, 5243909, 1051649, 2099202, 5243909, 2099202, 7340039, 5243909, 3147779, 6291462, 5243909, 1051649, 7340039, 6291462, 5243909, 1051649, 6291462, 4195332, 7340039, 3072, 3147779, 5243909, 6291462, 3072, 7340039, 1051649, 2099202, 5243909, 3147779, 1051649, 6291462, 4195332, 1051649, 7340039, 1051649, 6291462, 2099202, 7340039, 4195332, 3072, 3147779, 2099202,
+ 6291462, 3072, 5243909, 2099202, 3072, 6291462, 1051649, 6291462, 2099202, 4195332, 5243909, 2099202, 4195332, 5243909, 2099202, 5243909, 3072, 7340039, 1051649, 5243909, 3072, 3147779, 7340039, 4195332, 3072, 5243909, 1051649, 5243909, 3147779, 5243909, 1051649, 4195332, 5243909, 3147779, 6291462, 3147779, 7340039, 4195332, 2099202, 5243909, 1051649, 5243909, 3147779, 3072, 6291462, 1051649, 7340039, 4195332, 3072, 4195332, 3072, 5243909, 4195332, 7340039, 3147779, 6291462, 3072, 7340039, 3072, 4195332, 1051649, 5243909, 7340039, 3147779, 6291462, 3072, 3147779, 2099202, 5243909, 1051649, 7340039, 3072, 7340039, 1051649, 4195332, 7340039, 4195332, 6291462, 3147779, 1051649, 3147779, 6291462, 2099202, 3072, 7340039, 5243909, 6291462, 3147779, 4195332, 7340039, 3072, 6291462, 1051649, 3072, 6291462, 2099202, 4195332, 5243909, 3072, 3147779, 3072, 5243909, 3147779, 3072, 4195332, 6291462, 2099202, 7340039, 1051649, 4195332, 2099202, 5243909, 6291462, 3147779, 1051649, 7340039, 3072, 2099202, 5243909, 2099202, 4195332, 3147779, 6291462, 3072, 3147779, 6291462, 5243909, 1051649,
+ 4195332, 3147779, 4195332, 7340039, 4195332, 2099202, 5243909, 3072, 7340039, 3147779, 6291462, 3072, 7340039, 1051649, 6291462, 3147779, 4195332, 2099202, 6291462, 4195332, 7340039, 6291462, 1051649, 2099202, 6291462, 3147779, 7340039, 2099202, 3072, 7340039, 3147779, 7340039, 3072, 4195332, 3072, 5243909, 3072, 2099202, 6291462, 3147779, 7340039, 1051649, 7340039, 4195332, 2099202, 4195332, 5243909, 2099202, 6291462, 3147779, 7340039, 1051649, 6291462, 3072, 2099202, 5243909, 2099202, 3147779, 6291462, 2099202, 7340039, 4195332, 1051649, 3072, 5243909, 7340039, 5243909, 1051649, 6291462, 4195332, 3147779, 5243909, 2099202, 6291462, 3147779, 3072, 4195332, 1051649, 5243909, 4195332, 7340039, 1051649, 6291462, 4195332, 2099202, 3147779, 3072, 7340039, 1051649, 4195332, 2099202, 3147779, 4195332, 6291462, 2099202, 1051649, 7340039, 3147779, 6291462, 2099202, 7340039, 2099202, 6291462, 3147779, 5243909, 1051649, 4195332, 3072, 5243909, 3147779, 7340039, 3072, 4195332, 3072, 5243909, 4195332, 6291462, 3147779, 7340039, 3147779, 3072, 7340039, 2099202, 4195332, 7340039, 1051649, 2099202, 7340039,
+ 3072, 6291462, 1051649, 1051649, 3147779, 7340039, 3147779, 5243909, 3147779, 3072, 1051649, 5243909, 3147779, 4195332, 2099202, 7340039, 3072, 6291462, 3147779, 3072, 1051649, 3147779, 5243909, 6291462, 1051649, 4195332, 3072, 6291462, 4195332, 2099202, 5243909, 1051649, 4195332, 2099202, 7340039, 1051649, 4195332, 7340039, 1051649, 4195332, 3072, 5243909, 2099202, 5243909, 6291462, 3072, 3147779, 7340039, 1051649, 2099202, 4195332, 3147779, 5243909, 2099202, 6291462, 1051649, 7340039, 4195332, 1051649, 6291462, 3072, 7340039, 3147779, 6291462, 2099202, 3147779, 3072, 4195332, 2099202, 7340039, 3072, 3147779, 5243909, 3072, 6291462, 2099202, 7340039, 2099202, 6291462, 3072, 3147779, 5243909, 2099202, 3072, 6291462, 1051649, 4195332, 6291462, 1051649, 6291462, 4195332, 7340039, 3072, 3147779, 4195332, 5243909, 3072, 3147779, 1051649, 5243909, 4195332, 7340039, 3072, 7340039, 2099202, 6291462, 3147779, 7340039, 2099202, 6291462, 1051649, 4195332, 6291462, 1051649, 7340039, 2099202, 3072, 5243909, 1051649, 5243909, 6291462, 1051649, 5243909, 1051649, 4195332, 4195332, 5243909, 2099202,
+ 6291462, 4195332, 2099202, 6291462, 5243909, 3072, 4195332, 1051649, 6291462, 2099202, 4195332, 7340039, 2099202, 3072, 5243909, 1051649, 3147779, 5243909, 1051649, 5243909, 7340039, 3147779, 3072, 4195332, 2099202, 6291462, 3147779, 2099202, 5243909, 3072, 6291462, 3147779, 6291462, 2099202, 5243909, 3147779, 5243909, 2099202, 6291462, 3147779, 7340039, 1051649, 6291462, 3072, 3147779, 7340039, 1051649, 4195332, 5243909, 6291462, 3072, 7340039, 3072, 5243909, 3147779, 3147779, 5243909, 3072, 5243909, 3147779, 4195332, 2099202, 4195332, 1051649, 6291462, 3147779, 4195332, 6291462, 3072, 3147779, 6291462, 1051649, 7340039, 4195332, 2099202, 5243909, 3147779, 3072, 2099202, 6291462, 4195332, 1051649, 7340039, 4195332, 5243909, 7340039, 2099202, 3147779, 3147779, 5243909, 3072, 5243909, 2099202, 7340039, 1051649, 4195332, 7340039, 4195332, 7340039, 3072, 2099202, 1051649, 5243909, 3147779, 1051649, 3072, 5243909, 1051649, 3072, 4195332, 7340039, 2099202, 3147779, 5243909, 1051649, 4195332, 6291462, 2099202, 6291462, 3072, 2099202, 6291462, 3147779, 7340039, 3072, 7340039, 3072, 3147779,
+ 1051649, 2099202, 7340039, 3072, 4195332, 7340039, 2099202, 7340039, 4195332, 1051649, 6291462, 3072, 3147779, 7340039, 4195332, 6291462, 3072, 7340039, 2099202, 4195332, 2099202, 5243909, 7340039, 3072, 7340039, 1051649, 6291462, 3072, 7340039, 3147779, 1051649, 5243909, 3072, 6291462, 3072, 7340039, 3072, 4195332, 1051649, 5243909, 3072, 4195332, 3147779, 7340039, 1051649, 4195332, 3147779, 6291462, 3072, 2099202, 5243909, 4195332, 2099202, 7340039, 1051649, 6291462, 1051649, 3147779, 7340039, 1051649, 6291462, 3072, 7340039, 5243909, 3072, 7340039, 1051649, 2099202, 7340039, 4195332, 5243909, 2099202, 4195332, 3072, 6291462, 1051649, 6291462, 3147779, 7340039, 4195332, 3072, 6291462, 1051649, 3147779, 3072, 2099202, 6291462, 3072, 7340039, 1051649, 7340039, 1051649, 5243909, 1051649, 6291462, 2099202, 3072, 2099202, 5243909, 3147779, 6291462, 4195332, 3072, 6291462, 4195332, 7340039, 3147779, 5243909, 6291462, 3147779, 1051649, 6291462, 3072, 7340039, 4195332, 3072, 2099202, 4195332, 3147779, 5243909, 4195332, 3072, 2099202, 5243909, 3147779, 1051649, 6291462, 5243909,
+ 7340039, 4195332, 1051649, 6291462, 3147779, 3072, 5243909, 1051649, 3147779, 7340039, 2099202, 5243909, 6291462, 1051649, 1051649, 4195332, 3147779, 6291462, 4195332, 3072, 6291462, 1051649, 3147779, 4195332, 5243909, 3147779, 5243909, 4195332, 3147779, 1051649, 7340039, 2099202, 7340039, 4195332, 3147779, 2099202, 6291462, 3147779, 2099202, 7340039, 3147779, 6291462, 3072, 5243909, 2099202, 5243909, 1051649, 2099202, 7340039, 5243909, 2099202, 3147779, 6291462, 2099202, 4195332, 3072, 6291462, 4195332, 2099202, 5243909, 2099202, 5243909, 2099202, 4195332, 3147779, 5243909, 1051649, 5243909, 1051649, 5243909, 3072, 6291462, 7340039, 2099202, 3147779, 7340039, 3072, 5243909, 1051649, 5243909, 3147779, 2099202, 5243909, 5243909, 7340039, 4195332, 1051649, 5243909, 4195332, 3147779, 2099202, 4195332, 6291462, 3072, 3147779, 5243909, 3147779, 6291462, 1051649, 4195332, 1051649, 7340039, 3147779, 1051649, 2099202, 4195332, 1051649, 7340039, 2099202, 1051649, 5243909, 3147779, 5243909, 2099202, 4195332, 6291462, 7340039, 3072, 7340039, 1051649, 7340039, 3147779, 5243909, 1051649, 4195332, 5243909, 2099202, 3147779,
+ 3072, 4195332, 5243909, 2099202, 5243909, 2099202, 4195332, 6291462, 3072, 4195332, 1051649, 3147779, 3072, 3147779, 7340039, 2099202, 6291462, 1051649, 2099202, 7340039, 4195332, 2099202, 6291462, 1051649, 7340039, 3072, 1051649, 2099202, 6291462, 4195332, 5243909, 3072, 4195332, 1051649, 4195332, 5243909, 1051649, 7340039, 5243909, 2099202, 1051649, 3147779, 6291462, 2099202, 7340039, 3072, 4195332, 7340039, 3147779, 1051649, 6291462, 1051649, 3072, 7340039, 4195332, 5243909, 2099202, 7340039, 4195332, 3072, 7340039, 3147779, 3072, 6291462, 1051649, 6291462, 4195332, 3147779, 2099202, 7340039, 2099202, 3147779, 1051649, 5243909, 4195332, 1051649, 5243909, 2099202, 7340039, 3147779, 1051649, 7340039, 3072, 3147779, 1051649, 4195332, 3072, 7340039, 3072, 6291462, 5243909, 3072, 4195332, 3147779, 6291462, 3072, 7340039, 2099202, 5243909, 3072, 5243909, 2099202, 6291462, 5243909, 6291462, 3072, 5243909, 2099202, 4195332, 6291462, 2099202, 7340039, 3072, 3147779, 6291462, 2099202, 1051649, 5243909, 3147779, 2099202, 3072, 6291462, 1051649, 7340039, 3072, 6291462, 1051649, 5243909,
+ 2099202, 3147779, 3072, 7340039, 1051649, 6291462, 3072, 2099202, 6291462, 5243909, 7340039, 5243909, 4195332, 6291462, 5243909, 3072, 3147779, 5243909, 3147779, 5243909, 1051649, 5243909, 3072, 6291462, 2099202, 4195332, 7340039, 3147779, 3072, 7340039, 2099202, 3147779, 6291462, 2099202, 7340039, 1051649, 3147779, 4195332, 3072, 5243909, 7340039, 4195332, 1051649, 4195332, 2099202, 6291462, 3147779, 3072, 1051649, 5243909, 3147779, 7340039, 4195332, 3147779, 2099202, 1051649, 6291462, 3072, 3147779, 6291462, 1051649, 5243909, 1051649, 7340039, 4195332, 2099202, 3072, 7340039, 3072, 4195332, 5243909, 7340039, 3147779, 3072, 7340039, 2099202, 4195332, 6291462, 3072, 6291462, 5243909, 4195332, 2099202, 6291462, 7340039, 3147779, 6291462, 2099202, 3147779, 5243909, 2099202, 6291462, 2099202, 7340039, 2099202, 4195332, 1051649, 6291462, 4195332, 7340039, 3147779, 4195332, 3072, 3147779, 2099202, 7340039, 4195332, 1051649, 7340039, 3072, 4195332, 1051649, 6291462, 5243909, 1051649, 3147779, 5243909, 3072, 6291462, 5243909, 6291462, 3147779, 4195332, 3147779, 7340039, 3147779, 4195332, 6291462,
+ 7340039, 5243909, 6291462, 1051649, 5243909, 3147779, 7340039, 4195332, 2099202, 2099202, 3147779, 1051649, 7340039, 1051649, 2099202, 7340039, 4195332, 1051649, 7340039, 3072, 7340039, 2099202, 5243909, 3147779, 3072, 5243909, 2099202, 4195332, 5243909, 1051649, 4195332, 6291462, 1051649, 5243909, 3072, 4195332, 6291462, 1051649, 7340039, 2099202, 3072, 5243909, 6291462, 3072, 6291462, 3147779, 4195332, 7340039, 4195332, 5243909, 3072, 1051649, 5243909, 3072, 7340039, 5243909, 3147779, 1051649, 5243909, 2099202, 4195332, 3147779, 6291462, 1051649, 3147779, 5243909, 6291462, 3147779, 6291462, 2099202, 3072, 1051649, 6291462, 4195332, 2099202, 7340039, 3072, 3147779, 1051649, 3147779, 3072, 7340039, 2099202, 4195332, 3072, 5243909, 2099202, 6291462, 1051649, 7340039, 1051649, 3147779, 7340039, 3072, 4195332, 3147779, 7340039, 2099202, 3072, 3147779, 1051649, 6291462, 4195332, 7340039, 1051649, 3147779, 3072, 6291462, 3147779, 3147779, 7340039, 3147779, 4195332, 3072, 7340039, 4195332, 7340039, 3147779, 4195332, 1051649, 2099202, 5243909, 3072, 6291462, 2099202, 3072, 5243909, 1051649,
+ 2099202, 3072, 3147779, 4195332, 7340039, 3072, 4195332, 1051649, 6291462, 3072, 5243909, 3072, 2099202, 5243909, 4195332, 3072, 3147779, 6291462, 2099202, 3147779, 4195332, 3147779, 7340039, 1051649, 6291462, 3147779, 6291462, 3072, 7340039, 2099202, 7340039, 3072, 6291462, 2099202, 7340039, 3147779, 3072, 5243909, 1051649, 4195332, 6291462, 1051649, 3147779, 5243909, 2099202, 3072, 5243909, 1051649, 2099202, 7340039, 3147779, 6291462, 2099202, 4195332, 6291462, 1051649, 6291462, 3147779, 5243909, 3072, 7340039, 3072, 7340039, 2099202, 4195332, 3072, 2099202, 1051649, 4195332, 5243909, 6291462, 5243909, 2099202, 3072, 6291462, 1051649, 5243909, 6291462, 4195332, 6291462, 4195332, 1051649, 5243909, 1051649, 3147779, 6291462, 3072, 5243909, 3147779, 3147779, 4195332, 6291462, 1051649, 5243909, 1051649, 5243909, 3072, 5243909, 6291462, 4195332, 7340039, 1051649, 5243909, 3072, 5243909, 6291462, 3147779, 5243909, 2099202, 6291462, 3072, 5243909, 2099202, 5243909, 2099202, 1051649, 3072, 5243909, 1051649, 7340039, 4195332, 2099202, 7340039, 1051649, 4195332, 7340039, 2099202, 6291462,
+ 5243909, 4195332, 7340039, 3072, 2099202, 5243909, 3147779, 6291462, 4195332, 3147779, 7340039, 4195332, 6291462, 3072, 6291462, 5243909, 6291462, 3072, 5243909, 1051649, 6291462, 3072, 2099202, 5243909, 4195332, 1051649, 2099202, 5243909, 3147779, 4195332, 1051649, 3147779, 5243909, 4195332, 1051649, 6291462, 4195332, 3147779, 7340039, 2099202, 3072, 7340039, 2099202, 7340039, 3147779, 6291462, 2099202, 4195332, 6291462, 3072, 5243909, 1051649, 6291462, 3072, 2099202, 4195332, 1051649, 7340039, 3072, 6291462, 5243909, 2099202, 4195332, 5243909, 1051649, 7340039, 5243909, 7340039, 1051649, 3147779, 3147779, 1051649, 7340039, 4195332, 3147779, 5243909, 3147779, 2099202, 1051649, 5243909, 2099202, 6291462, 3147779, 7340039, 4195332, 1051649, 4195332, 7340039, 3072, 7340039, 3072, 2099202, 6291462, 3147779, 7340039, 2099202, 4195332, 3147779, 2099202, 3072, 2099202, 5243909, 3147779, 2099202, 4195332, 1051649, 2099202, 6291462, 3072, 5243909, 2099202, 6291462, 1051649, 7340039, 3147779, 6291462, 4195332, 2099202, 7340039, 3147779, 3072, 6291462, 1051649, 5243909, 2099202, 4195332, 1051649, 3147779,
+ 1051649, 3072, 5243909, 3147779, 6291462, 1051649, 2099202, 1051649, 6291462, 1051649, 5243909, 2099202, 3147779, 7340039, 2099202, 1051649, 2099202, 4195332, 3147779, 7340039, 2099202, 4195332, 6291462, 1051649, 3147779, 7340039, 4195332, 6291462, 3072, 6291462, 2099202, 5243909, 3072, 3147779, 7340039, 3147779, 2099202, 6291462, 3072, 5243909, 3147779, 4195332, 5243909, 3072, 1051649, 6291462, 3072, 7340039, 2099202, 4195332, 3147779, 6291462, 2099202, 7340039, 5243909, 3147779, 5243909, 2099202, 4195332, 3147779, 1051649, 3147779, 6291462, 3072, 6291462, 3147779, 1051649, 4195332, 6291462, 3072, 4195332, 6291462, 2099202, 5243909, 1051649, 7340039, 1051649, 4195332, 7340039, 3072, 7340039, 1051649, 4195332, 2099202, 3072, 6291462, 1051649, 4195332, 2099202, 5243909, 3147779, 5243909, 1051649, 4195332, 3072, 6291462, 1051649, 7340039, 3147779, 7340039, 5243909, 3072, 6291462, 2099202, 7340039, 4195332, 7340039, 1051649, 4195332, 7340039, 1051649, 3147779, 4195332, 3072, 6291462, 1051649, 5243909, 3147779, 3072, 6291462, 5243909, 3147779, 4195332, 7340039, 3072, 6291462, 3147779, 7340039,
+ 7340039, 4195332, 1051649, 7340039, 3072, 4195332, 7340039, 5243909, 3147779, 3072, 5243909, 1051649, 5243909, 3072, 4195332, 7340039, 3147779, 5243909, 1051649, 4195332, 3072, 7340039, 3147779, 7340039, 3072, 6291462, 3072, 5243909, 1051649, 2099202, 7340039, 4195332, 6291462, 1051649, 5243909, 3072, 6291462, 1051649, 5243909, 1051649, 6291462, 3072, 3147779, 6291462, 4195332, 3147779, 5243909, 1051649, 5243909, 1051649, 7340039, 1051649, 4195332, 2099202, 3072, 6291462, 3072, 7340039, 2099202, 5243909, 7340039, 1051649, 2099202, 7340039, 3147779, 3072, 7340039, 3147779, 2099202, 5243909, 7340039, 1051649, 3147779, 3072, 6291462, 3072, 6291462, 3147779, 2099202, 5243909, 3147779, 3072, 5243909, 2099202, 7340039, 3147779, 5243909, 2099202, 6291462, 1051649, 7340039, 2099202, 6291462, 5243909, 2099202, 4195332, 5243909, 3072, 6291462, 1051649, 4195332, 7340039, 2099202, 6291462, 3072, 3147779, 3072, 5243909, 3147779, 2099202, 5243909, 3072, 7340039, 4195332, 2099202, 7340039, 1051649, 6291462, 4195332, 2099202, 1051649, 6291462, 3072, 2099202, 5243909, 1051649, 4195332, 2099202,
+ 3072, 3147779, 6291462, 2099202, 5243909, 3147779, 3072, 2099202, 4195332, 7340039, 3147779, 7340039, 2099202, 4195332, 1051649, 1051649, 6291462, 3072, 6291462, 2099202, 5243909, 2099202, 3072, 5243909, 2099202, 4195332, 2099202, 3147779, 7340039, 3147779, 5243909, 3072, 1051649, 6291462, 2099202, 7340039, 2099202, 4195332, 4195332, 7340039, 2099202, 6291462, 4195332, 1051649, 7340039, 2099202, 3072, 7340039, 3147779, 6291462, 3147779, 3072, 7340039, 4195332, 2099202, 5243909, 4195332, 4195332, 1051649, 6291462, 3072, 4195332, 5243909, 2099202, 4195332, 5243909, 2099202, 3072, 6291462, 3147779, 3072, 4195332, 7340039, 4195332, 2099202, 5243909, 4195332, 3072, 6291462, 2099202, 4195332, 6291462, 4195332, 6291462, 3072, 5243909, 1051649, 5243909, 3072, 4195332, 3147779, 3072, 1051649, 7340039, 1051649, 6291462, 1051649, 5243909, 2099202, 5243909, 3147779, 1051649, 4195332, 1051649, 5243909, 5243909, 6291462, 4195332, 3072, 6291462, 2099202, 7340039, 1051649, 3147779, 5243909, 3072, 4195332, 1051649, 7340039, 3147779, 7340039, 2099202, 5243909, 6291462, 2099202, 7340039, 3147779, 5243909,
+ 2099202, 6291462, 1051649, 7340039, 4195332, 1051649, 7340039, 3147779, 6291462, 1051649, 6291462, 3072, 7340039, 5243909, 6291462, 4195332, 2099202, 7340039, 3147779, 6291462, 1051649, 4195332, 5243909, 1051649, 6291462, 1051649, 7340039, 4195332, 3072, 5243909, 2099202, 6291462, 3147779, 4195332, 3072, 4195332, 3147779, 1051649, 6291462, 3072, 3147779, 4195332, 2099202, 7340039, 2099202, 5243909, 6291462, 4195332, 3072, 2099202, 5243909, 3147779, 5243909, 1051649, 7340039, 1051649, 3147779, 6291462, 3072, 4195332, 3147779, 6291462, 4195332, 3072, 6291462, 1051649, 5243909, 7340039, 4195332, 1051649, 7340039, 2099202, 5243909, 2099202, 6291462, 3147779, 2099202, 7340039, 5243909, 1051649, 7340039, 3072, 1051649, 3147779, 7340039, 2099202, 7340039, 3147779, 6291462, 2099202, 6291462, 7340039, 3147779, 5243909, 2099202, 3147779, 7340039, 3147779, 4195332, 3072, 6291462, 4195332, 3072, 7340039, 3147779, 2099202, 2099202, 1051649, 7340039, 4195332, 1051649, 3147779, 5243909, 3072, 6291462, 3147779, 7340039, 5243909, 2099202, 3072, 4195332, 5243909, 3072, 3147779, 1051649, 4195332, 3072, 6291462,
+ 5243909, 1051649, 4195332, 3147779, 2099202, 6291462, 5243909, 3072, 2099202, 4195332, 2099202, 4195332, 3147779, 3072, 2099202, 7340039, 4195332, 1051649, 4195332, 3072, 7340039, 3147779, 3147779, 7340039, 3072, 5243909, 3147779, 1051649, 7340039, 3072, 4195332, 5243909, 2099202, 7340039, 5243909, 1051649, 5243909, 7340039, 2099202, 3147779, 7340039, 1051649, 5243909, 3072, 4195332, 3147779, 1051649, 4195332, 7340039, 4195332, 1051649, 6291462, 2099202, 4195332, 5243909, 6291462, 1051649, 3147779, 7340039, 2099202, 5243909, 1051649, 3147779, 7340039, 2099202, 7340039, 1051649, 2099202, 4195332, 5243909, 1051649, 6291462, 3072, 5243909, 3072, 1051649, 5243909, 3072, 2099202, 3147779, 5243909, 3147779, 7340039, 5243909, 4195332, 1051649, 4195332, 1051649, 4195332, 3072, 4195332, 1051649, 4195332, 3072, 4195332, 6291462, 3072, 1051649, 7340039, 3147779, 6291462, 1051649, 6291462, 3147779, 3072, 4195332, 7340039, 3147779, 4195332, 2099202, 6291462, 2099202, 4195332, 7340039, 2099202, 4195332, 3072, 1051649, 6291462, 3147779, 6291462, 1051649, 7340039, 3147779, 6291462, 6291462, 1051649, 3147779,
+ 3072, 7340039, 5243909, 3072, 6291462, 1051649, 3147779, 5243909, 7340039, 3072, 6291462, 4195332, 6291462, 1051649, 5243909, 3072, 3147779, 6291462, 2099202, 5243909, 2099202, 6291462, 3072, 4195332, 3147779, 3072, 6291462, 5243909, 2099202, 6291462, 3147779, 1051649, 7340039, 3072, 3147779, 7340039, 3072, 2099202, 4195332, 6291462, 3072, 5243909, 3147779, 6291462, 5243909, 2099202, 6291462, 3072, 2099202, 7340039, 5243909, 3072, 7340039, 3072, 2099202, 3147779, 7340039, 3072, 5243909, 3147779, 3072, 6291462, 5243909, 3072, 3147779, 4195332, 3147779, 6291462, 3072, 2099202, 5243909, 3147779, 7340039, 3147779, 7340039, 6291462, 3147779, 7340039, 4195332, 7340039, 3072, 4195332, 2099202, 3072, 3147779, 6291462, 3072, 6291462, 7340039, 2099202, 7340039, 5243909, 2099202, 6291462, 1051649, 5243909, 3147779, 6291462, 2099202, 5243909, 1051649, 4195332, 2099202, 5243909, 7340039, 1051649, 6291462, 3072, 7340039, 3072, 5243909, 7340039, 3072, 3147779, 1051649, 6291462, 3147779, 5243909, 4195332, 5243909, 1051649, 4195332, 2099202, 4195332, 3072, 5243909, 3147779, 7340039,
+ 4195332, 3147779, 2099202, 5243909, 4195332, 7340039, 4195332, 1051649, 2099202, 5243909, 3072, 3147779, 1051649, 5243909, 3147779, 6291462, 1051649, 5243909, 4195332, 7340039, 1051649, 4195332, 1051649, 6291462, 4195332, 7340039, 2099202, 3147779, 5243909, 1051649, 3147779, 6291462, 2099202, 5243909, 1051649, 4195332, 6291462, 6291462, 1051649, 5243909, 2099202, 7340039, 1051649, 2099202, 1051649, 7340039, 1051649, 6291462, 5243909, 3072, 3147779, 4195332, 2099202, 5243909, 7340039, 3072, 4195332, 2099202, 6291462, 1051649, 7340039, 1051649, 2099202, 5243909, 7340039, 3072, 6291462, 1051649, 4195332, 7340039, 3147779, 3072, 4195332, 2099202, 4195332, 3072, 4195332, 1051649, 3147779, 1051649, 6291462, 2099202, 4195332, 6291462, 5243909, 2099202, 5243909, 3147779, 1051649, 5243909, 3072, 2099202, 7340039, 3147779, 6291462, 3072, 7340039, 4195332, 3072, 4195332, 7340039, 3072, 7340039, 1051649, 3147779, 6291462, 1051649, 5243909, 2099202, 5243909, 1051649, 3147779, 5243909, 4195332, 6291462, 2099202, 1051649, 7340039, 2099202, 3072, 7340039, 3147779, 6291462, 1051649, 7340039, 1051649, 5243909, 2099202,
+ 3072, 6291462, 1051649, 7340039, 2099202, 3072, 3147779, 6291462, 7340039, 2099202, 6291462, 2099202, 7340039, 3147779, 7340039, 1051649, 7340039, 3147779, 3072, 2099202, 4195332, 7340039, 5243909, 2099202, 1051649, 5243909, 1051649, 6291462, 3072, 4195332, 7340039, 3072, 6291462, 3147779, 6291462, 3072, 2099202, 3147779, 3072, 4195332, 6291462, 3072, 4195332, 6291462, 5243909, 3147779, 3072, 3147779, 4195332, 3147779, 6291462, 1051649, 6291462, 3147779, 1051649, 6291462, 3147779, 7340039, 2099202, 5243909, 4195332, 3147779, 6291462, 4195332, 1051649, 5243909, 2099202, 3147779, 6291462, 1051649, 5243909, 2099202, 6291462, 3072, 5243909, 2099202, 7340039, 6291462, 3072, 6291462, 3147779, 7340039, 1051649, 2099202, 3072, 7340039, 2099202, 3072, 6291462, 2099202, 5243909, 4195332, 3072, 4195332, 2099202, 3147779, 1051649, 2099202, 6291462, 2099202, 3147779, 5243909, 3147779, 5243909, 4195332, 3072, 5243909, 4195332, 6291462, 3147779, 6291462, 2099202, 1051649, 7340039, 3072, 4195332, 6291462, 3072, 4195332, 6291462, 3147779, 3072, 5243909, 2099202, 5243909, 4195332, 3072, 6291462,
+ 2099202, 5243909, 4195332, 3072, 3147779, 6291462, 4195332, 3072, 4195332, 1051649, 3147779, 5243909, 3072, 4195332, 3072, 2099202, 5243909, 2099202, 5243909, 7340039, 1051649, 3072, 3147779, 6291462, 2099202, 7340039, 4195332, 3147779, 7340039, 2099202, 1051649, 5243909, 2099202, 4195332, 1051649, 5243909, 7340039, 4195332, 7340039, 2099202, 1051649, 5243909, 3147779, 1051649, 3072, 4195332, 7340039, 2099202, 7340039, 1051649, 5243909, 3072, 7340039, 1051649, 6291462, 4195332, 3072, 4195332, 1051649, 5243909, 1051649, 7340039, 3072, 2099202, 6291462, 4195332, 7340039, 4195332, 3072, 7340039, 1051649, 6291462, 1051649, 7340039, 3147779, 5243909, 1051649, 3147779, 5243909, 2099202, 5243909, 1051649, 6291462, 4195332, 5243909, 1051649, 4195332, 6291462, 3147779, 3147779, 7340039, 1051649, 3147779, 5243909, 3147779, 7340039, 6291462, 5243909, 1051649, 7340039, 1051649, 6291462, 3072, 2099202, 6291462, 2099202, 7340039, 2099202, 3072, 1051649, 4195332, 6291462, 4195332, 2099202, 5243909, 3147779, 4195332, 7340039, 2099202, 1051649, 4195332, 6291462, 2099202, 6291462, 3072, 3147779, 7340039, 4195332,
+ 7340039, 1051649, 3147779, 6291462, 5243909, 1051649, 7340039, 2099202, 6291462, 5243909, 3072, 6291462, 3147779, 6291462, 4195332, 7340039, 3072, 6291462, 1051649, 3147779, 6291462, 3147779, 5243909, 3072, 4195332, 1051649, 3072, 6291462, 2099202, 5243909, 3147779, 7340039, 3072, 3147779, 6291462, 4195332, 2099202, 1051649, 3147779, 5243909, 7340039, 3147779, 7340039, 4195332, 6291462, 2099202, 3147779, 5243909, 3072, 6291462, 3147779, 2099202, 4195332, 4195332, 1051649, 5243909, 2099202, 6291462, 3147779, 7340039, 3072, 4195332, 3147779, 6291462, 3072, 2099202, 3072, 5243909, 3147779, 4195332, 2099202, 5243909, 4195332, 2099202, 4195332, 3072, 6291462, 4195332, 1051649, 7340039, 3072, 5243909, 3147779, 1051649, 7340039, 3147779, 7340039, 1051649, 5243909, 3072, 4195332, 6291462, 2099202, 7340039, 1051649, 4195332, 3072, 3147779, 5243909, 3072, 4195332, 2099202, 7340039, 4195332, 3072, 4195332, 1051649, 3147779, 7340039, 5243909, 3072, 7340039, 3072, 5243909, 1051649, 7340039, 1051649, 2099202, 5243909, 3147779, 7340039, 1051649, 4195332, 1051649, 7340039, 4195332, 1051649, 2099202,
+ 3072, 4195332, 1051649, 5243909, 2099202, 3072, 5243909, 3147779, 1051649, 3147779, 7340039, 2099202, 5243909, 1051649, 4195332, 2099202, 5243909, 4195332, 3072, 5243909, 2099202, 7340039, 1051649, 6291462, 4195332, 7340039, 5243909, 3147779, 4195332, 3072, 6291462, 1051649, 4195332, 7340039, 2099202, 3072, 6291462, 2099202, 7340039, 3072, 4195332, 1051649, 4195332, 3072, 2099202, 6291462, 1051649, 4195332, 5243909, 1051649, 4195332, 7340039, 3147779, 3072, 6291462, 2099202, 7340039, 4195332, 1051649, 3147779, 6291462, 2099202, 7340039, 1051649, 5243909, 3147779, 7340039, 1051649, 6291462, 1051649, 7340039, 3147779, 3072, 6291462, 1051649, 7340039, 1051649, 2099202, 5243909, 3147779, 4195332, 2099202, 6291462, 3072, 5243909, 3072, 4195332, 2099202, 7340039, 3147779, 7340039, 1051649, 5243909, 3072, 6291462, 2099202, 7340039, 4195332, 2099202, 7340039, 3147779, 5243909, 1051649, 5243909, 7340039, 3147779, 6291462, 5243909, 2099202, 4195332, 3147779, 1051649, 6291462, 2099202, 5243909, 3072, 3147779, 6291462, 3072, 6291462, 2099202, 3147779, 7340039, 4195332, 3072, 6291462, 3147779, 5243909,
+ 7340039, 5243909, 7340039, 3072, 3147779, 7340039, 2099202, 7340039, 4195332, 4195332, 1051649, 6291462, 3072, 7340039, 1051649, 6291462, 2099202, 7340039, 3147779, 6291462, 3072, 4195332, 3147779, 1051649, 3147779, 3072, 2099202, 7340039, 1051649, 6291462, 2099202, 4195332, 5243909, 3072, 5243909, 3147779, 6291462, 4195332, 1051649, 5243909, 2099202, 6291462, 2099202, 5243909, 7340039, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 6291462, 2099202, 7340039, 3147779, 5243909, 3072, 2099202, 6291462, 4195332, 1051649, 5243909, 3072, 4195332, 5243909, 1051649, 4195332, 6291462, 2099202, 5243909, 3072, 2099202, 7340039, 3147779, 6291462, 3147779, 4195332, 7340039, 2099202, 6291462, 1051649, 7340039, 2099202, 6291462, 3147779, 4195332, 2099202, 6291462, 1051649, 4195332, 3072, 5243909, 3147779, 4195332, 1051649, 5243909, 3147779, 3072, 6291462, 4195332, 3072, 6291462, 4195332, 2099202, 1051649, 5243909, 1051649, 3072, 7340039, 1051649, 5243909, 4195332, 3147779, 7340039, 1051649, 7340039, 2099202, 5243909, 2099202, 4195332, 3072, 5243909, 2099202, 5243909, 3147779, 2099202, 6291462, 1051649,
+ 3147779, 1051649, 2099202, 6291462, 4195332, 1051649, 5243909, 1051649, 3072, 6291462, 2099202, 3147779, 5243909, 1051649, 5243909, 3147779, 3072, 3147779, 1051649, 5243909, 2099202, 7340039, 2099202, 6291462, 6291462, 4195332, 5243909, 1051649, 5243909, 3147779, 7340039, 3072, 2099202, 4195332, 1051649, 7340039, 1051649, 3072, 6291462, 3147779, 5243909, 2099202, 6291462, 3072, 3147779, 5243909, 2099202, 3072, 7340039, 3147779, 6291462, 1051649, 5243909, 3147779, 3072, 7340039, 1051649, 6291462, 5243909, 3072, 7340039, 3147779, 3147779, 6291462, 2099202, 7340039, 2099202, 3072, 4195332, 3147779, 6291462, 5243909, 4195332, 1051649, 5243909, 3072, 5243909, 3072, 4195332, 3072, 4195332, 5243909, 3072, 4195332, 1051649, 7340039, 3072, 6291462, 5243909, 2099202, 7340039, 1051649, 6291462, 2099202, 7340039, 1051649, 6291462, 5243909, 1051649, 3147779, 2099202, 1051649, 7340039, 2099202, 6291462, 3147779, 7340039, 3147779, 6291462, 2099202, 4195332, 3072, 6291462, 3072, 3147779, 4195332, 3147779, 6291462, 1051649, 7340039, 5243909, 1051649, 6291462, 3072, 7340039, 5243909, 3072, 4195332,
+ 6291462, 3147779, 4195332, 2099202, 6291462, 2099202, 3147779, 6291462, 5243909, 2099202, 7340039, 4195332, 3147779, 7340039, 2099202, 6291462, 4195332, 7340039, 5243909, 4195332, 1051649, 5243909, 3072, 4195332, 3072, 3147779, 1051649, 7340039, 4195332, 3072, 3147779, 5243909, 7340039, 3147779, 6291462, 3147779, 5243909, 7340039, 4195332, 1051649, 7340039, 3072, 3147779, 7340039, 5243909, 3072, 6291462, 5243909, 1051649, 6291462, 2099202, 4195332, 1051649, 5243909, 2099202, 4195332, 5243909, 1051649, 3147779, 5243909, 2099202, 1051649, 7340039, 3072, 6291462, 3147779, 1051649, 5243909, 7340039, 1051649, 3147779, 3072, 2099202, 7340039, 2099202, 4195332, 3147779, 7340039, 2099202, 6291462, 1051649, 6291462, 3147779, 7340039, 4195332, 2099202, 5243909, 3147779, 3072, 5243909, 3147779, 4195332, 3072, 5243909, 2099202, 3147779, 4195332, 2099202, 1051649, 7340039, 5243909, 6291462, 3072, 5243909, 4195332, 3072, 5243909, 2099202, 3147779, 6291462, 1051649, 7340039, 2099202, 5243909, 1051649, 6291462, 3072, 7340039, 4195332, 1051649, 3147779, 7340039, 2099202, 4195332, 1051649, 3147779, 6291462, 2099202,
+ 5243909, 3072, 7340039, 1051649, 5243909, 3072, 6291462, 3072, 3147779, 5243909, 3072, 6291462, 3072, 4195332, 4195332, 3072, 1051649, 2099202, 4195332, 3072, 6291462, 3147779, 7340039, 2099202, 5243909, 7340039, 4195332, 2099202, 6291462, 2099202, 6291462, 2099202, 1051649, 5243909, 3072, 4195332, 3072, 3147779, 2099202, 6291462, 1051649, 5243909, 4195332, 1051649, 2099202, 7340039, 3147779, 1051649, 4195332, 3147779, 5243909, 3072, 7340039, 3147779, 6291462, 1051649, 4195332, 2099202, 7340039, 3072, 4195332, 5243909, 2099202, 4195332, 3147779, 3072, 6291462, 3147779, 2099202, 4195332, 7340039, 4195332, 6291462, 1051649, 6291462, 1051649, 5243909, 3072, 5243909, 3147779, 7340039, 3147779, 2099202, 4195332, 3072, 7340039, 2099202, 6291462, 4195332, 3072, 6291462, 1051649, 7340039, 4195332, 3072, 7340039, 3072, 3147779, 6291462, 3072, 2099202, 3147779, 4195332, 3147779, 2099202, 7340039, 4195332, 3072, 7340039, 3072, 5243909, 3147779, 7340039, 4195332, 5243909, 2099202, 4195332, 3072, 3147779, 6291462, 4195332, 3072, 3147779, 5243909, 6291462, 2099202, 7340039, 3072,
+ 2099202, 7340039, 3147779, 4195332, 2099202, 7340039, 4195332, 6291462, 1051649, 4195332, 1051649, 7340039, 5243909, 2099202, 6291462, 3147779, 7340039, 6291462, 1051649, 6291462, 2099202, 5243909, 1051649, 6291462, 1051649, 2099202, 6291462, 3072, 3147779, 5243909, 3072, 6291462, 1051649, 4195332, 6291462, 2099202, 5243909, 7340039, 3072, 4195332, 3147779, 1051649, 7340039, 3147779, 6291462, 1051649, 4195332, 6291462, 7340039, 3072, 3147779, 7340039, 2099202, 2099202, 3072, 5243909, 7340039, 3072, 6291462, 2099202, 7340039, 1051649, 6291462, 3072, 5243909, 7340039, 2099202, 6291462, 3072, 6291462, 3072, 2099202, 5243909, 3147779, 3072, 6291462, 2099202, 7340039, 1051649, 3147779, 3072, 5243909, 6291462, 3072, 5243909, 3147779, 1051649, 1051649, 2099202, 7340039, 4195332, 3147779, 5243909, 1051649, 6291462, 2099202, 5243909, 6291462, 4195332, 7340039, 5243909, 3072, 7340039, 1051649, 6291462, 3072, 3147779, 6291462, 2099202, 5243909, 6291462, 1051649, 3147779, 3072, 2099202, 7340039, 3147779, 6291462, 5243909, 3072, 2099202, 6291462, 7340039, 1051649, 4195332, 3072, 5243909, 3147779,
+ 4195332, 3072, 5243909, 1051649, 5243909, 3147779, 1051649, 4195332, 3147779, 7340039, 3147779, 2099202, 1051649, 6291462, 1051649, 5243909, 3072, 3147779, 4195332, 3147779, 7340039, 3072, 4195332, 3147779, 7340039, 5243909, 1051649, 7340039, 4195332, 1051649, 5243909, 3147779, 4195332, 7340039, 1051649, 7340039, 2099202, 5243909, 2099202, 7340039, 3147779, 6291462, 2099202, 4195332, 3072, 5243909, 2099202, 3072, 2099202, 6291462, 5243909, 1051649, 6291462, 4195332, 7340039, 2099202, 3147779, 5243909, 3147779, 4195332, 3072, 5243909, 3147779, 7340039, 2099202, 4195332, 1051649, 4195332, 5243909, 2099202, 4195332, 7340039, 1051649, 4195332, 7340039, 2099202, 4195332, 1051649, 6291462, 4195332, 7340039, 1051649, 2099202, 6291462, 1051649, 5243909, 7340039, 5243909, 6291462, 1051649, 6291462, 2099202, 3072, 3147779, 4195332, 7340039, 1051649, 3147779, 3072, 2099202, 6291462, 4195332, 1051649, 5243909, 2099202, 5243909, 4195332, 1051649, 4195332, 3147779, 1051649, 4195332, 7340039, 4195332, 6291462, 1051649, 5243909, 1051649, 2099202, 7340039, 4195332, 2099202, 3072, 5243909, 6291462, 3147779, 1051649, 7340039,
+ 6291462, 2099202, 3147779, 6291462, 1051649, 7340039, 3072, 7340039, 2099202, 5243909, 3072, 5243909, 7340039, 4195332, 1051649, 5243909, 2099202, 7340039, 2099202, 4195332, 1051649, 5243909, 2099202, 6291462, 3072, 3147779, 1051649, 5243909, 3147779, 7340039, 2099202, 7340039, 3072, 2099202, 3147779, 4195332, 1051649, 3147779, 4195332, 3072, 5243909, 3072, 5243909, 4195332, 7340039, 2099202, 7340039, 5243909, 3147779, 4195332, 3072, 4195332, 1051649, 5243909, 1051649, 3147779, 6291462, 1051649, 7340039, 1051649, 3147779, 6291462, 1051649, 4195332, 3072, 5243909, 1051649, 7340039, 2099202, 7340039, 1051649, 3147779, 6291462, 3147779, 3072, 3147779, 5243909, 6291462, 3147779, 3072, 2099202, 5243909, 3147779, 4195332, 7340039, 3072, 4195332, 3147779, 3072, 4195332, 2099202, 7340039, 5243909, 6291462, 2099202, 3072, 5243909, 5243909, 6291462, 3147779, 1051649, 7340039, 4195332, 3072, 7340039, 1051649, 6291462, 6291462, 3072, 7340039, 2099202, 5243909, 2099202, 3072, 6291462, 3147779, 3072, 7340039, 4195332, 1051649, 5243909, 3147779, 4195332, 2099202, 3072, 7340039, 4195332, 1051649,
+ 2099202, 4195332, 7340039, 3072, 4195332, 3147779, 6291462, 3147779, 3072, 4195332, 6291462, 2099202, 3072, 3147779, 7340039, 3072, 6291462, 1051649, 5243909, 3072, 7340039, 3147779, 6291462, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 6291462, 3072, 4195332, 5243909, 6291462, 3072, 4195332, 6291462, 1051649, 7340039, 6291462, 2099202, 6291462, 2099202, 3072, 1051649, 3147779, 4195332, 1051649, 6291462, 2099202, 7340039, 3147779, 6291462, 3072, 4195332, 6291462, 3072, 4195332, 2099202, 6291462, 4195332, 3072, 6291462, 3147779, 7340039, 3147779, 5243909, 3072, 5243909, 3147779, 6291462, 5243909, 3072, 7340039, 5243909, 1051649, 4195332, 3072, 2099202, 5243909, 6291462, 1051649, 7340039, 3072, 3147779, 4195332, 2099202, 5243909, 2099202, 7340039, 3147779, 3072, 4195332, 1051649, 5243909, 7340039, 3147779, 1051649, 3072, 4195332, 5243909, 2099202, 3147779, 5243909, 3147779, 4195332, 3072, 3147779, 5243909, 1051649, 6291462, 3072, 5243909, 3147779, 3147779, 4195332, 5243909, 2099202, 4195332, 7340039, 3072, 6291462, 7340039, 1051649, 5243909, 2099202, 3147779, 6291462,
+ 3072, 3147779, 1051649, 5243909, 6291462, 1051649, 2099202, 6291462, 2099202, 5243909, 1051649, 6291462, 3147779, 5243909, 2099202, 4195332, 4195332, 3147779, 7340039, 4195332, 1051649, 5243909, 3072, 3147779, 5243909, 3072, 6291462, 2099202, 7340039, 2099202, 3147779, 5243909, 1051649, 3147779, 5243909, 2099202, 6291462, 3072, 3147779, 4195332, 1051649, 3147779, 6291462, 4195332, 7340039, 5243909, 3072, 7340039, 3072, 5243909, 1051649, 5243909, 4195332, 3147779, 7340039, 2099202, 2099202, 5243909, 5243909, 3072, 7340039, 4195332, 2099202, 5243909, 2099202, 1051649, 7340039, 3147779, 1051649, 4195332, 3072, 2099202, 4195332, 2099202, 4195332, 7340039, 2099202, 3147779, 7340039, 1051649, 4195332, 5243909, 2099202, 5243909, 7340039, 1051649, 6291462, 1051649, 7340039, 1051649, 6291462, 3147779, 2099202, 7340039, 3147779, 1051649, 4195332, 6291462, 6291462, 2099202, 7340039, 3072, 2099202, 6291462, 1051649, 7340039, 5243909, 2099202, 7340039, 1051649, 4195332, 5243909, 2099202, 7340039, 3072, 7340039, 1051649, 6291462, 3072, 3147779, 5243909, 2099202, 1051649, 6291462, 4195332, 5243909, 3072, 5243909,
+ 7340039, 4195332, 7340039, 4195332, 2099202, 4195332, 5243909, 3072, 7340039, 1051649, 4195332, 3072, 6291462, 1051649, 7340039, 3072, 6291462, 2099202, 3072, 3147779, 6291462, 2099202, 7340039, 3147779, 6291462, 3147779, 5243909, 1051649, 5243909, 3072, 7340039, 1051649, 4195332, 6291462, 1051649, 7340039, 3147779, 5243909, 6291462, 1051649, 5243909, 7340039, 3072, 5243909, 2099202, 1051649, 6291462, 3147779, 4195332, 2099202, 7340039, 3072, 2099202, 5243909, 3072, 4195332, 7340039, 3147779, 1051649, 6291462, 2099202, 1051649, 7340039, 3072, 6291462, 4195332, 2099202, 6291462, 6291462, 1051649, 7340039, 5243909, 1051649, 6291462, 3072, 3147779, 5243909, 7340039, 1051649, 6291462, 3072, 3147779, 6291462, 3072, 2099202, 6291462, 4195332, 5243909, 2099202, 5243909, 3072, 5243909, 1051649, 4195332, 2099202, 7340039, 3072, 4195332, 2099202, 1051649, 5243909, 3147779, 7340039, 4195332, 3072, 2099202, 4195332, 1051649, 3147779, 6291462, 3147779, 7340039, 1051649, 6291462, 1051649, 6291462, 3147779, 2099202, 5243909, 3147779, 1051649, 6291462, 4195332, 3072, 3147779, 1051649, 7340039, 1051649,
+ 5243909, 2099202, 3072, 6291462, 3072, 7340039, 2099202, 6291462, 3147779, 4195332, 7340039, 3147779, 2099202, 5243909, 3147779, 1051649, 2099202, 5243909, 4195332, 6291462, 2099202, 5243909, 1051649, 4195332, 3072, 2099202, 4195332, 7340039, 2099202, 4195332, 3147779, 6291462, 3072, 2099202, 5243909, 3072, 2099202, 1051649, 7340039, 3147779, 2099202, 4195332, 3147779, 1051649, 6291462, 5243909, 2099202, 1051649, 6291462, 4195332, 1051649, 3147779, 6291462, 1051649, 6291462, 3147779, 3072, 5243909, 6291462, 2099202, 4195332, 5243909, 1051649, 3147779, 3147779, 5243909, 3072, 4195332, 3072, 4195332, 3147779, 3072, 5243909, 5243909, 3147779, 6291462, 3072, 2099202, 4195332, 6291462, 3147779, 7340039, 1051649, 3147779, 6291462, 2099202, 3072, 3147779, 6291462, 3147779, 3147779, 7340039, 2099202, 6291462, 3072, 4195332, 6291462, 1051649, 7340039, 4195332, 6291462, 3072, 2099202, 4195332, 6291462, 7340039, 2099202, 6291462, 4195332, 3072, 4195332, 3072, 4195332, 3147779, 5243909, 2099202, 3072, 7340039, 1051649, 6291462, 4195332, 2099202, 5243909, 7340039, 5243909, 6291462, 3147779, 2099202,
+ 3072, 4195332, 6291462, 3147779, 5243909, 1051649, 5243909, 3072, 5243909, 1051649, 2099202, 5243909, 7340039, 3072, 4195332, 5243909, 7340039, 3072, 7340039, 1051649, 6291462, 3072, 6291462, 1051649, 7340039, 5243909, 4195332, 3072, 6291462, 1051649, 7340039, 1051649, 5243909, 3147779, 6291462, 4195332, 7340039, 4195332, 3072, 5243909, 7340039, 3072, 5243909, 7340039, 3072, 3147779, 4195332, 7340039, 3072, 5243909, 3147779, 7340039, 5243909, 1051649, 4195332, 7340039, 2099202, 4195332, 1051649, 3147779, 7340039, 3072, 6291462, 5243909, 1051649, 7340039, 2099202, 7340039, 3147779, 5243909, 7340039, 3147779, 2099202, 1051649, 7340039, 1051649, 4195332, 6291462, 3072, 2099202, 4195332, 1051649, 5243909, 4195332, 1051649, 7340039, 3147779, 6291462, 3072, 7340039, 4195332, 3072, 5243909, 3147779, 6291462, 2099202, 5243909, 3147779, 3072, 3147779, 1051649, 5243909, 6291462, 3147779, 3072, 1051649, 5243909, 3072, 2099202, 6291462, 2099202, 6291462, 2099202, 7340039, 3072, 5243909, 4195332, 5243909, 3072, 4195332, 7340039, 3072, 3147779, 1051649, 2099202, 3072, 4195332, 6291462,
+ 3147779, 7340039, 2099202, 1051649, 3147779, 6291462, 3147779, 7340039, 2099202, 4195332, 6291462, 3072, 4195332, 3147779, 7340039, 3147779, 1051649, 4195332, 2099202, 4195332, 3147779, 7340039, 2099202, 5243909, 3147779, 2099202, 1051649, 7340039, 3147779, 2099202, 5243909, 4195332, 1051649, 7340039, 3072, 2099202, 1051649, 6291462, 3147779, 2099202, 1051649, 4195332, 1051649, 4195332, 2099202, 7340039, 3072, 3147779, 2099202, 3147779, 6291462, 3072, 2099202, 7340039, 3147779, 3072, 6291462, 5243909, 3072, 5243909, 2099202, 4195332, 3147779, 2099202, 6291462, 3072, 4195332, 2099202, 6291462, 1051649, 3072, 6291462, 7340039, 2099202, 4195332, 6291462, 1051649, 5243909, 3147779, 4195332, 7340039, 3072, 7340039, 3147779, 4195332, 2099202, 5243909, 1051649, 4195332, 1051649, 5243909, 2099202, 6291462, 3072, 4195332, 1051649, 7340039, 2099202, 6291462, 5243909, 7340039, 3147779, 1051649, 5243909, 7340039, 3147779, 5243909, 3147779, 7340039, 3147779, 5243909, 3147779, 1051649, 5243909, 2099202, 7340039, 1051649, 3147779, 6291462, 1051649, 2099202, 5243909, 3147779, 7340039, 4195332, 7340039, 1051649, 5243909,
+ 3147779, 3072, 5243909, 7340039, 4195332, 3072, 2099202, 4195332, 1051649, 7340039, 1051649, 3147779, 6291462, 1051649, 3072, 6291462, 5243909, 2099202, 6291462, 3072, 5243909, 1051649, 4195332, 3072, 6291462, 3147779, 6291462, 4195332, 3072, 6291462, 3072, 6291462, 3147779, 3147779, 4195332, 5243909, 7340039, 3072, 3147779, 7340039, 5243909, 6291462, 3147779, 7340039, 3147779, 5243909, 6291462, 1051649, 6291462, 4195332, 1051649, 4195332, 5243909, 3072, 4195332, 6291462, 1051649, 7340039, 3147779, 6291462, 1051649, 7340039, 3072, 7340039, 4195332, 3147779, 6291462, 3072, 4195332, 5243909, 2099202, 4195332, 1051649, 4195332, 3072, 7340039, 2099202, 5243909, 1051649, 7340039, 2099202, 5243909, 1051649, 6291462, 3072, 7340039, 1051649, 5243909, 2099202, 7340039, 3072, 5243909, 3147779, 1051649, 7340039, 2099202, 4195332, 1051649, 5243909, 2099202, 3072, 4195332, 7340039, 3072, 2099202, 4195332, 3072, 7340039, 1051649, 4195332, 3072, 7340039, 6291462, 4195332, 1051649, 4195332, 6291462, 2099202, 7340039, 3147779, 7340039, 3072, 6291462, 2099202, 3072, 3147779, 5243909, 2099202,
+ 4195332, 6291462, 1051649, 6291462, 3072, 5243909, 6291462, 3147779, 5243909, 2099202, 4195332, 7340039, 2099202, 6291462, 5243909, 2099202, 3072, 7340039, 3147779, 7340039, 2099202, 7340039, 3147779, 5243909, 1051649, 6291462, 3072, 2099202, 7340039, 4195332, 2099202, 5243909, 3072, 6291462, 4195332, 1051649, 3147779, 4195332, 6291462, 3072, 2099202, 4195332, 3072, 5243909, 1051649, 3072, 2099202, 5243909, 3072, 7340039, 2099202, 7340039, 2099202, 2099202, 6291462, 2099202, 4195332, 1051649, 3147779, 4195332, 2099202, 4195332, 5243909, 2099202, 3072, 6291462, 1051649, 6291462, 3147779, 1051649, 6291462, 2099202, 6291462, 3147779, 5243909, 2099202, 3072, 6291462, 3147779, 6291462, 3072, 3147779, 5243909, 2099202, 3147779, 6291462, 4195332, 3072, 6291462, 3147779, 4195332, 1051649, 7340039, 4195332, 3147779, 6291462, 3072, 7340039, 3147779, 3147779, 6291462, 2099202, 5243909, 3147779, 6291462, 1051649, 5243909, 2099202, 5243909, 1051649, 6291462, 2099202, 3072, 7340039, 3147779, 6291462, 3072, 5243909, 3072, 4195332, 1051649, 5243909, 2099202, 5243909, 4195332, 6291462, 3072, 7340039,
+ 5243909, 1051649, 4195332, 3147779, 2099202, 7340039, 1051649, 4195332, 3072, 6291462, 1051649, 5243909, 3072, 3147779, 1051649, 5243909, 4195332, 5243909, 1051649, 3147779, 3072, 4195332, 1051649, 7340039, 3147779, 2099202, 4195332, 5243909, 1051649, 5243909, 3147779, 7340039, 2099202, 7340039, 1051649, 5243909, 2099202, 7340039, 1051649, 4195332, 1051649, 6291462, 2099202, 3147779, 6291462, 4195332, 6291462, 2099202, 7340039, 3147779, 4195332, 1051649, 6291462, 5243909, 1051649, 3147779, 3072, 7340039, 5243909, 3072, 7340039, 1051649, 1051649, 5243909, 5243909, 3147779, 7340039, 1051649, 4195332, 7340039, 3147779, 5243909, 3072, 7340039, 1051649, 6291462, 4195332, 4195332, 1051649, 1051649, 4195332, 6291462, 3072, 7340039, 2099202, 3072, 3147779, 7340039, 2099202, 1051649, 5243909, 6291462, 2099202, 3072, 6291462, 4195332, 3147779, 5243909, 1051649, 7340039, 3072, 6291462, 1051649, 1051649, 4195332, 7340039, 3147779, 1051649, 7340039, 3147779, 4195332, 2099202, 5243909, 3147779, 1051649, 2099202, 4195332, 3147779, 7340039, 2099202, 6291462, 3147779, 1051649, 6291462, 1051649, 2099202, 5243909, 2099202,
+ 3072, 7340039, 1051649, 6291462, 1051649, 3147779, 7340039, 2099202, 6291462, 3147779, 7340039, 2099202, 4195332, 7340039, 3147779, 7340039, 3072, 2099202, 4195332, 6291462, 5243909, 2099202, 5243909, 3072, 5243909, 7340039, 3147779, 3072, 7340039, 1051649, 4195332, 3072, 5243909, 1051649, 3147779, 6291462, 3072, 2099202, 6291462, 5243909, 7340039, 3147779, 6291462, 3072, 7340039, 1051649, 4195332, 3072, 5243909, 1051649, 5243909, 4195332, 3072, 3147779, 5243909, 7340039, 6291462, 4195332, 3072, 6291462, 3147779, 6291462, 3147779, 7340039, 1051649, 2099202, 2099202, 4195332, 5243909, 3072, 3147779, 5243909, 2099202, 4195332, 3147779, 2099202, 7340039, 3072, 5243909, 7340039, 3147779, 2099202, 4195332, 4195332, 5243909, 6291462, 5243909, 2099202, 4195332, 7340039, 3147779, 3072, 4195332, 6291462, 1051649, 1051649, 5243909, 3072, 6291462, 2099202, 4195332, 3147779, 5243909, 6291462, 2099202, 3072, 5243909, 6291462, 3072, 6291462, 3072, 6291462, 1051649, 5243909, 7340039, 4195332, 6291462, 1051649, 3147779, 6291462, 3072, 7340039, 4195332, 2099202, 7340039, 4195332, 1051649, 7340039,
+ 4195332, 3147779, 7340039, 2099202, 4195332, 5243909, 3072, 5243909, 3147779, 3072, 4195332, 1051649, 5243909, 3072, 6291462, 2099202, 4195332, 6291462, 3072, 1051649, 3147779, 7340039, 3147779, 6291462, 2099202, 1051649, 4195332, 6291462, 3147779, 5243909, 2099202, 6291462, 3147779, 7340039, 3072, 4195332, 4195332, 5243909, 3072, 2099202, 3147779, 1051649, 4195332, 2099202, 5243909, 1051649, 7340039, 4195332, 3147779, 6291462, 3072, 7340039, 2099202, 7340039, 1051649, 3072, 2099202, 5243909, 2099202, 4195332, 2099202, 4195332, 3072, 3147779, 4195332, 5243909, 7340039, 3072, 6291462, 2099202, 7340039, 1051649, 6291462, 3072, 6291462, 1051649, 5243909, 2099202, 5243909, 3072, 6291462, 1051649, 7340039, 1051649, 3072, 4195332, 1051649, 6291462, 3072, 4195332, 1051649, 6291462, 2099202, 3147779, 5243909, 7340039, 2099202, 7340039, 4195332, 5243909, 2099202, 7340039, 1051649, 4195332, 7340039, 4195332, 1051649, 4195332, 3147779, 4195332, 2099202, 7340039, 4195332, 3072, 2099202, 3072, 3147779, 5243909, 1051649, 2099202, 5243909, 1051649, 6291462, 3072, 3147779, 5243909, 3072, 3147779,
+ 3147779, 2099202, 5243909, 3072, 6291462, 1051649, 6291462, 2099202, 4195332, 5243909, 3147779, 6291462, 2099202, 6291462, 3147779, 5243909, 1051649, 2099202, 7340039, 4195332, 6291462, 3072, 4195332, 1051649, 5243909, 6291462, 1051649, 2099202, 7340039, 3072, 6291462, 3147779, 1051649, 5243909, 2099202, 7340039, 1051649, 3147779, 7340039, 4195332, 6291462, 3072, 5243909, 2099202, 6291462, 3147779, 1051649, 5243909, 2099202, 3147779, 4195332, 3147779, 1051649, 6291462, 3147779, 6291462, 3147779, 7340039, 1051649, 5243909, 6291462, 1051649, 7340039, 2099202, 6291462, 3072, 4195332, 1051649, 5243909, 3147779, 4195332, 1051649, 4195332, 3147779, 5243909, 3072, 3147779, 7340039, 4195332, 2099202, 5243909, 3147779, 5243909, 3147779, 7340039, 2099202, 7340039, 1051649, 3147779, 6291462, 3072, 5243909, 7340039, 1051649, 4195332, 3072, 4195332, 1051649, 2099202, 3072, 4195332, 3072, 6291462, 2099202, 3072, 3147779, 7340039, 2099202, 5243909, 1051649, 6291462, 3147779, 1051649, 4195332, 6291462, 4195332, 6291462, 3072, 7340039, 4195332, 2099202, 5243909, 3147779, 4195332, 6291462, 1051649, 6291462, 5243909,
+ 6291462, 3072, 5243909, 4195332, 3147779, 7340039, 1051649, 7340039, 3072, 6291462, 3072, 7340039, 1051649, 4195332, 1051649, 3072, 7340039, 3147779, 2099202, 5243909, 1051649, 2099202, 6291462, 7340039, 3072, 3147779, 6291462, 4195332, 2099202, 2099202, 4195332, 3072, 7340039, 3147779, 6291462, 1051649, 6291462, 2099202, 5243909, 3072, 2099202, 7340039, 3147779, 7340039, 3072, 4195332, 6291462, 3072, 7340039, 3072, 7340039, 5243909, 5243909, 2099202, 4195332, 1051649, 5243909, 3072, 4195332, 3147779, 3072, 5243909, 4195332, 6291462, 1051649, 3147779, 7340039, 2099202, 6291462, 3072, 7340039, 6291462, 2099202, 7340039, 1051649, 4195332, 7340039, 3072, 3147779, 7340039, 1051649, 6291462, 3072, 5243909, 2099202, 3147779, 5243909, 2099202, 5243909, 2099202, 7340039, 3147779, 2099202, 5243909, 2099202, 6291462, 3147779, 5243909, 6291462, 7340039, 3147779, 6291462, 3147779, 1051649, 5243909, 6291462, 2099202, 6291462, 3072, 7340039, 3072, 5243909, 1051649, 7340039, 2099202, 5243909, 1051649, 3147779, 6291462, 4195332, 3072, 6291462, 3072, 7340039, 2099202, 5243909, 2099202, 1051649,
+ 3147779, 7340039, 2099202, 6291462, 3072, 2099202, 4195332, 3147779, 6291462, 3147779, 1051649, 4195332, 3147779, 5243909, 7340039, 3147779, 4195332, 5243909, 3072, 4195332, 7340039, 5243909, 1051649, 3147779, 4195332, 5243909, 1051649, 3072, 6291462, 4195332, 7340039, 5243909, 2099202, 4195332, 3072, 5243909, 3147779, 3072, 4195332, 6291462, 5243909, 3147779, 1051649, 2099202, 4195332, 7340039, 2099202, 3147779, 4195332, 2099202, 2099202, 1051649, 1051649, 6291462, 3072, 7340039, 2099202, 4195332, 7340039, 2099202, 7340039, 2099202, 3072, 5243909, 2099202, 6291462, 3072, 5243909, 1051649, 3147779, 5243909, 2099202, 3072, 3147779, 6291462, 2099202, 4195332, 2099202, 6291462, 1051649, 4195332, 3147779, 4195332, 6291462, 3072, 6291462, 3072, 7340039, 1051649, 5243909, 3147779, 3072, 6291462, 1051649, 5243909, 3072, 7340039, 1051649, 3072, 3147779, 1051649, 5243909, 2099202, 7340039, 4195332, 1051649, 4195332, 2099202, 4195332, 3147779, 3147779, 7340039, 2099202, 5243909, 3072, 3147779, 7340039, 5243909, 1051649, 2099202, 7340039, 3147779, 5243909, 1051649, 4195332, 3072, 7340039, 4195332,
+ 3072, 4195332, 1051649, 4195332, 6291462, 5243909, 3072, 2099202, 1051649, 5243909, 7340039, 2099202, 5243909, 3072, 2099202, 6291462, 1051649, 6291462, 1051649, 7340039, 3147779, 3072, 6291462, 1051649, 7340039, 2099202, 4195332, 7340039, 5243909, 3072, 3147779, 1051649, 4195332, 7340039, 4195332, 2099202, 5243909, 7340039, 1051649, 2099202, 3072, 6291462, 5243909, 1051649, 6291462, 3072, 5243909, 1051649, 6291462, 6291462, 4195332, 7340039, 3147779, 5243909, 4195332, 3147779, 3072, 6291462, 1051649, 6291462, 3147779, 1051649, 5243909, 3147779, 7340039, 4195332, 2099202, 4195332, 4195332, 7340039, 1051649, 4195332, 7340039, 5243909, 1051649, 5243909, 3072, 6291462, 3147779, 5243909, 3072, 7340039, 2099202, 1051649, 4195332, 3147779, 6291462, 4195332, 3072, 4195332, 1051649, 5243909, 4195332, 7340039, 3147779, 2099202, 4195332, 3147779, 5243909, 4195332, 7340039, 1051649, 6291462, 3072, 3147779, 7340039, 3072, 6291462, 1051649, 5243909, 2099202, 5243909, 3072, 4195332, 6291462, 1051649, 4195332, 3072, 7340039, 3147779, 4195332, 1051649, 2099202, 6291462, 7340039, 3147779, 1051649, 6291462,
+ 7340039, 3147779, 6291462, 2099202, 1051649, 3147779, 7340039, 4195332, 7340039, 3072, 2099202, 6291462, 1051649, 7340039, 4195332, 3072, 4195332, 3147779, 5243909, 1051649, 5243909, 2099202, 4195332, 5243909, 3147779, 3072, 6291462, 1051649, 3147779, 2099202, 6291462, 1051649, 6291462, 3072, 3147779, 7340039, 1051649, 3147779, 6291462, 7340039, 4195332, 3072, 4195332, 7340039, 3147779, 2099202, 4195332, 7340039, 3072, 1051649, 5243909, 3072, 6291462, 3072, 2099202, 6291462, 5243909, 2099202, 5243909, 3072, 7340039, 4195332, 6291462, 1051649, 5243909, 3072, 7340039, 1051649, 6291462, 3072, 5243909, 3147779, 3072, 2099202, 6291462, 3147779, 7340039, 1051649, 2099202, 7340039, 4195332, 2099202, 6291462, 3147779, 7340039, 1051649, 1051649, 3147779, 7340039, 3147779, 7340039, 6291462, 2099202, 3072, 5243909, 1051649, 6291462, 3072, 7340039, 2099202, 5243909, 2099202, 4195332, 5243909, 4195332, 2099202, 5243909, 3147779, 7340039, 3072, 6291462, 1051649, 7340039, 2099202, 3147779, 7340039, 2099202, 5243909, 3147779, 6291462, 3072, 7340039, 4195332, 3147779, 1051649, 5243909, 4195332, 2099202,
+ 1051649, 5243909, 3072, 7340039, 3147779, 5243909, 1051649, 2099202, 6291462, 4195332, 5243909, 3072, 4195332, 3147779, 6291462, 5243909, 7340039, 3072, 2099202, 6291462, 4195332, 1051649, 6291462, 3072, 7340039, 5243909, 3147779, 4195332, 7340039, 1051649, 4195332, 5243909, 2099202, 6291462, 3072, 6291462, 2099202, 5243909, 3072, 3147779, 1051649, 6291462, 3147779, 1051649, 5243909, 6291462, 1051649, 3147779, 5243909, 7340039, 3147779, 3147779, 2099202, 4195332, 7340039, 1051649, 3072, 4195332, 3147779, 5243909, 2099202, 3072, 2099202, 7340039, 3147779, 1051649, 3147779, 6291462, 2099202, 3147779, 5243909, 2099202, 7340039, 4195332, 7340039, 1051649, 3147779, 5243909, 3072, 6291462, 1051649, 5243909, 3072, 5243909, 2099202, 7340039, 4195332, 6291462, 1051649, 5243909, 2099202, 3072, 4195332, 6291462, 3147779, 7340039, 2099202, 4195332, 1051649, 5243909, 3072, 6291462, 3147779, 1051649, 3072, 7340039, 1051649, 5243909, 2099202, 4195332, 3147779, 5243909, 4195332, 6291462, 3072, 5243909, 3072, 6291462, 1051649, 2099202, 6291462, 3147779, 3072, 5243909, 1051649, 7340039, 2099202, 6291462,
+ 4195332, 3147779, 6291462, 4195332, 3072, 2099202, 6291462, 5243909, 1051649, 2099202, 3147779, 7340039, 1051649, 7340039, 3072, 2099202, 2099202, 6291462, 3147779, 3072, 2099202, 7340039, 3147779, 2099202, 4195332, 2099202, 3072, 5243909, 1051649, 6291462, 3072, 3147779, 5243909, 2099202, 5243909, 1051649, 4195332, 6291462, 2099202, 7340039, 4195332, 5243909, 2099202, 6291462, 3072, 4195332, 6291462, 2099202, 3072, 4195332, 1051649, 7340039, 6291462, 1051649, 5243909, 3147779, 5243909, 3147779, 7340039, 1051649, 6291462, 4195332, 6291462, 4195332, 3072, 5243909, 6291462, 1051649, 5243909, 7340039, 3072, 6291462, 3147779, 1051649, 4195332, 2099202, 6291462, 4195332, 2099202, 4195332, 1051649, 3147779, 6291462, 4195332, 3072, 5243909, 2099202, 3072, 6291462, 1051649, 6291462, 3147779, 7340039, 1051649, 4195332, 3072, 4195332, 6291462, 2099202, 3147779, 6291462, 1051649, 7340039, 5243909, 3147779, 6291462, 4195332, 3147779, 3072, 6291462, 3072, 2099202, 1051649, 3147779, 7340039, 2099202, 4195332, 3147779, 4195332, 5243909, 1051649, 5243909, 2099202, 7340039, 4195332, 3072, 4195332, 3072,
+ 7340039, 2099202, 1051649, 5243909, 7340039, 4195332, 1051649, 3147779, 5243909, 7340039, 3072, 6291462, 4195332, 1051649, 3147779, 6291462, 4195332, 1051649, 5243909, 7340039, 4195332, 3072, 5243909, 6291462, 1051649, 6291462, 7340039, 3147779, 2099202, 5243909, 3147779, 7340039, 1051649, 4195332, 3147779, 7340039, 4195332, 3072, 5243909, 1051649, 4195332, 3072, 7340039, 3147779, 5243909, 2099202, 3072, 6291462, 5243909, 3147779, 5243909, 3072, 2099202, 4195332, 1051649, 7340039, 1051649, 6291462, 3072, 7340039, 1051649, 3147779, 1051649, 4195332, 7340039, 3147779, 2099202, 4195332, 3072, 3147779, 4195332, 3072, 5243909, 6291462, 3072, 5243909, 3147779, 3072, 7340039, 2099202, 7340039, 5243909, 3072, 3147779, 7340039, 2099202, 4195332, 7340039, 3147779, 4195332, 3072, 3147779, 5243909, 2099202, 7340039, 1051649, 6291462, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 7340039, 2099202, 3072, 1051649, 7340039, 6291462, 4195332, 7340039, 5243909, 6291462, 3072, 5243909, 2099202, 6291462, 3072, 7340039, 3072, 7340039, 2099202, 6291462, 1051649, 3147779, 7340039, 5243909, 2099202,
+ 1051649, 7340039, 5243909, 3072, 2099202, 5243909, 7340039, 3072, 4195332, 2099202, 4195332, 3147779, 2099202, 5243909, 6291462, 1051649, 5243909, 7340039, 2099202, 3147779, 1051649, 6291462, 3147779, 3072, 4195332, 4195332, 3147779, 3072, 7340039, 6291462, 3072, 2099202, 7340039, 3072, 5243909, 1051649, 2099202, 6291462, 3147779, 3147779, 7340039, 2099202, 4195332, 1051649, 7340039, 5243909, 2099202, 4195332, 1051649, 7340039, 2099202, 7340039, 5243909, 3147779, 6291462, 4195332, 2099202, 5243909, 3147779, 2099202, 3147779, 7340039, 5243909, 2099202, 3072, 5243909, 1051649, 6291462, 2099202, 6291462, 2099202, 7340039, 3147779, 2099202, 7340039, 1051649, 6291462, 5243909, 1051649, 5243909, 3072, 2099202, 6291462, 4195332, 1051649, 5243909, 1051649, 4195332, 3072, 7340039, 5243909, 2099202, 3072, 6291462, 3147779, 5243909, 2099202, 5243909, 3072, 3147779, 6291462, 2099202, 4195332, 2099202, 5243909, 3147779, 5243909, 1051649, 4195332, 2099202, 1051649, 2099202, 3147779, 6291462, 1051649, 7340039, 1051649, 6291462, 3147779, 4195332, 1051649, 4195332, 3072, 5243909, 4195332, 1051649, 3072, 5243909,
+ 4195332, 3072, 4195332, 3147779, 6291462, 1051649, 2099202, 6291462, 5243909, 1051649, 6291462, 3072, 7340039, 3147779, 2099202, 4195332, 3072, 3147779, 5243909, 1051649, 7340039, 4195332, 2099202, 7340039, 6291462, 3072, 1051649, 5243909, 4195332, 1051649, 7340039, 4195332, 3147779, 6291462, 2099202, 7340039, 4195332, 1051649, 7340039, 3072, 5243909, 1051649, 6291462, 3147779, 3072, 3147779, 7340039, 5243909, 2099202, 4195332, 3072, 3147779, 1051649, 6291462, 3072, 2099202, 6291462, 3072, 5243909, 4195332, 6291462, 3072, 2099202, 6291462, 4195332, 1051649, 7340039, 3147779, 7340039, 1051649, 5243909, 1051649, 5243909, 1051649, 4195332, 4195332, 3072, 3147779, 2099202, 6291462, 4195332, 7340039, 3147779, 3072, 7340039, 3147779, 6291462, 2099202, 6291462, 2099202, 3147779, 6291462, 4195332, 1051649, 5243909, 3072, 7340039, 3147779, 7340039, 5243909, 3072, 5243909, 1051649, 6291462, 1051649, 7340039, 3147779, 7340039, 3072, 3147779, 5243909, 7340039, 4195332, 3072, 4195332, 3147779, 5243909, 3147779, 2099202, 5243909, 2099202, 5243909, 3147779, 7340039, 3072, 6291462, 6291462, 3147779,
+ 7340039, 3147779, 6291462, 1051649, 4195332, 3147779, 7340039, 3147779, 3072, 7340039, 3147779, 5243909, 1051649, 5243909, 3072, 7340039, 3147779, 6291462, 3072, 4195332, 3147779, 3072, 5243909, 1051649, 2099202, 5243909, 7340039, 3147779, 1051649, 4195332, 2099202, 5243909, 3072, 1051649, 5243909, 3072, 5243909, 1051649, 5243909, 5243909, 2099202, 4195332, 3072, 7340039, 4195332, 1051649, 4195332, 3072, 7340039, 1051649, 6291462, 4195332, 6291462, 2099202, 4195332, 7340039, 4195332, 3147779, 7340039, 3072, 2099202, 7340039, 3147779, 3072, 6291462, 3147779, 5243909, 3072, 2099202, 4195332, 3147779, 6291462, 3072, 6291462, 2099202, 7340039, 3147779, 7340039, 4195332, 3072, 3147779, 1051649, 6291462, 4195332, 2099202, 5243909, 3072, 5243909, 4195332, 3072, 6291462, 1051649, 7340039, 4195332, 2099202, 6291462, 4195332, 1051649, 3147779, 1051649, 7340039, 3147779, 6291462, 4195332, 1051649, 5243909, 3072, 4195332, 5243909, 6291462, 1051649, 2099202, 1051649, 6291462, 7340039, 2099202, 5243909, 3072, 6291462, 3072, 7340039, 1051649, 6291462, 2099202, 3147779, 2099202, 4195332, 2099202,
+ 2099202, 5243909, 1051649, 6291462, 3072, 5243909, 1051649, 4195332, 6291462, 2099202, 4195332, 2099202, 6291462, 4195332, 6291462, 1051649, 4195332, 2099202, 7340039, 2099202, 6291462, 2099202, 7340039, 3147779, 6291462, 1051649, 4195332, 6291462, 2099202, 6291462, 3072, 6291462, 4195332, 6291462, 2099202, 3147779, 7340039, 3147779, 3147779, 1051649, 6291462, 2099202, 6291462, 3147779, 5243909, 1051649, 6291462, 2099202, 3147779, 6291462, 2099202, 3072, 4195332, 3072, 5243909, 1051649, 5243909, 1051649, 1051649, 5243909, 1051649, 5243909, 4195332, 6291462, 2099202, 7340039, 3072, 6291462, 4195332, 7340039, 3072, 2099202, 4195332, 4195332, 5243909, 1051649, 5243909, 1051649, 6291462, 2099202, 5243909, 5243909, 1051649, 3147779, 6291462, 1051649, 3147779, 7340039, 1051649, 7340039, 2099202, 5243909, 3147779, 3072, 7340039, 1051649, 5243909, 2099202, 6291462, 4195332, 3147779, 3072, 2099202, 3147779, 7340039, 2099202, 6291462, 2099202, 3147779, 3072, 4195332, 7340039, 5243909, 3147779, 3072, 4195332, 1051649, 7340039, 4195332, 6291462, 2099202, 4195332, 1051649, 5243909, 7340039, 1051649, 6291462, 3072,
+ 6291462, 1051649, 7340039, 3147779, 7340039, 2099202, 6291462, 3147779, 3072, 6291462, 1051649, 7340039, 3072, 3147779, 2099202, 7340039, 3072, 5243909, 1051649, 5243909, 5243909, 1051649, 4195332, 3072, 2099202, 7340039, 3147779, 3072, 5243909, 3147779, 7340039, 2099202, 3072, 4195332, 1051649, 7340039, 3072, 6291462, 3072, 7340039, 2099202, 7340039, 3072, 4195332, 2099202, 6291462, 3147779, 7340039, 3072, 5243909, 3147779, 5243909, 7340039, 3147779, 7340039, 2099202, 3147779, 6291462, 4195332, 3147779, 7340039, 3147779, 1051649, 5243909, 3072, 3147779, 5243909, 2099202, 1051649, 3147779, 5243909, 6291462, 7340039, 3072, 3147779, 6291462, 3072, 4195332, 3147779, 7340039, 3072, 4195332, 7340039, 2099202, 3072, 7340039, 5243909, 3072, 5243909, 3147779, 4195332, 3072, 6291462, 2099202, 5243909, 3147779, 3072, 7340039, 4195332, 3072, 6291462, 5243909, 7340039, 4195332, 3072, 5243909, 1051649, 4195332, 7340039, 5243909, 1051649, 2099202, 3072, 6291462, 2099202, 7340039, 3147779, 1051649, 3147779, 3147779, 5243909, 3072, 7340039, 3147779, 3072, 5243909, 3147779, 4195332,
+};
+
+
+#elif (DFB_DITHER565 == DFB_DITHER_SIMPLE)
+
+
+#define DM_WIDTH 8
+#define DM_HEIGHT 8
+#define DM_WIDTH_SHIFT 3
+
+static const u32 DM_565[DM_WIDTH * DM_HEIGHT] =
+{
+ 3072, 4195332, 1051649, 5243909, 3072, 4195332, 1051649, 5243909,
+ 6291462, 2099202, 7340039, 3147779, 6291462, 2099202, 7340039, 3147779,
+ 1051649, 5243909, 3072, 4195332, 1051649, 5243909, 3072, 4195332,
+ 7340039, 3147779, 6291462, 2099202, 7340039, 3147779, 6291462, 2099202,
+ 3072, 4195332, 1051649, 5243909, 3072, 4195332, 1051649, 5243909,
+ 6291462, 2099202, 7340039, 3147779, 6291462, 2099202, 7340039, 3147779,
+ 1051649, 5243909, 3072, 4195332, 1051649, 5243909, 3072, 4195332,
+ 7340039, 3147779, 6291462, 2099202, 7340039, 3147779, 6291462, 2099202,
+};
+
+#endif
+
+
+#endif /* __DITHER565_H__ */
diff --git a/Source/DirectFB/src/misc/gfx_util.c b/Source/DirectFB/src/misc/gfx_util.c
new file mode 100755
index 0000000..1165112
--- /dev/null
+++ b/Source/DirectFB/src/misc/gfx_util.c
@@ -0,0 +1,964 @@
+/*
+ (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>.
+
+ Scaling routines ported from gdk_pixbuf by Sven Neumann
+ <sven@convergence.de>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <pthread.h>
+
+#include <directfb.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/palette.h>
+#include <core/surface.h>
+
+#include <direct/memcpy.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <misc/util.h>
+#include <misc/dither565.h>
+#include <misc/gfx_util.h>
+
+#include <gfx/clip.h>
+#include <gfx/convert.h>
+
+
+#define SUBSAMPLE_BITS 4
+#define SUBSAMPLE (1 << SUBSAMPLE_BITS)
+#define SUBSAMPLE_MASK ((1 << SUBSAMPLE_BITS)-1)
+#define SCALE_SHIFT 16
+
+
+typedef struct _PixopsFilter PixopsFilter;
+
+struct _PixopsFilter {
+ int *weights;
+ int n_x;
+ int n_y;
+ float x_offset;
+ float y_offset;
+};
+
+
+static void write_argb_span (u32 *src, u8 *dst[], int len,
+ int dx, int dy, CoreSurface *dst_surface)
+{
+ CorePalette *palette = dst_surface->palette;
+ u8 *d = dst[0];
+ u8 *d1,*d2;
+ int i, j;
+
+ if (dst_surface->config.caps & DSCAPS_PREMULTIPLIED) {
+ for (i = 0; i < len; i++) {
+ const u32 s = src[i];
+ const u32 a = (s >> 24) + 1;
+
+ src[i] = ((((s & 0x00ff00ff) * a) >> 8) & 0x00ff00ff) |
+ ((((s & 0x0000ff00) * a) >> 8) & 0x0000ff00) |
+ ((((s & 0xff000000) ) ) );
+ }
+ }
+
+ switch (dst_surface->config.format) {
+ case DSPF_A1:
+ for (i = 0; i < len; i++) {
+ if (i & 7)
+ d[i>>3] |= (src[i] >> 31) << (7-(i&7));
+ else
+ d[i>>3] = (src[i] >> 24) & 0x80;
+ }
+ break;
+
+ case DSPF_A4:
+ for (i = 0, j = 0; i < len; i += 2, j++)
+ d[j] = ((src[i] >> 24) & 0xF0) | (src[i+1] >> 28);
+ break;
+
+ case DSPF_A8:
+ for (i = 0; i < len; i++)
+ d[i] = src[i] >> 24;
+ break;
+
+ case DSPF_RGB332:
+ for (i = 0; i < len; i++)
+ d[i] = RGB32_TO_RGB332( src[i] );
+ break;
+
+ case DSPF_ARGB1555:
+ for (i = 0; i < len; i++)
+ ((u16*)d)[i] = ARGB_TO_ARGB1555( src[i] );
+ break;
+
+ case DSPF_ARGB2554:
+ for (i = 0; i < len; i++)
+ ((u16*)d)[i] = ARGB_TO_ARGB2554( src[i] );
+ break;
+
+ case DSPF_ARGB4444:
+ for (i = 0; i < len; i++)
+ ((u16*)d)[i] = ARGB_TO_ARGB4444( src[i] );
+ break;
+
+ case DSPF_RGBA4444:
+ for (i = 0; i < len; i++)
+ ((u16*)d)[i] = ARGB_TO_RGBA4444( src[i] );
+ break;
+
+ case DSPF_RGB16:
+#ifdef DFB_DITHER565
+ /* use a pre-generated dither matrix to improve the appearance of the result */
+ {
+ const u32 *dm = DM_565 + ((dy & (DM_HEIGHT - 1)) << DM_WIDTH_SHIFT);
+
+ for (i = 0; i < len; i++) {
+ u32 rgb = ((src[i] & 0xFF) |
+ (src[i] & 0xFF00) << 2 |
+ (src[i] & 0xFF0000) << 4);
+
+ rgb += dm[(dx + i) & (DM_WIDTH - 1)];
+ rgb += (0x10040100
+ - ((rgb & 0x1e0001e0) >> 5)
+ - ((rgb & 0x00070000) >> 6));
+
+ ((u16*)d)[i] = (((rgb & 0x0f800000) >> 12) |
+ ((rgb & 0x0003f000) >> 7) |
+ ((rgb & 0x000000f8) >> 3));
+ }
+ }
+#else
+ for (i = 0; i < len; i++)
+ ((u16*)d)[i] = RGB32_TO_RGB16( src[i] );
+#endif
+ break;
+
+ case DSPF_ARGB1666:
+ for (i = 0; i < len; i++) {
+ const u32 pixel = PIXEL_ARGB1666( src[i] >> 24,
+ src[i] >> 16,
+ src[i] >> 8,
+ src[i] );
+
+ *d++ = pixel;
+ *d++ = pixel >> 8;
+ *d++ = pixel >> 16;
+ }
+ break;
+
+ case DSPF_ARGB6666:
+ for (i = 0; i < len; i++) {
+ const u32 pixel = PIXEL_ARGB6666( src[i] >> 24,
+ src[i] >> 16,
+ src[i] >> 8,
+ src[i] );
+
+ *d++ = pixel;
+ *d++ = pixel >> 8;
+ *d++ = pixel >> 16;
+ }
+ break;
+
+ case DSPF_RGB18:
+ for (i = 0; i < len; i++) {
+ const u32 pixel = PIXEL_RGB18( src[i] >> 16,
+ src[i] >> 8,
+ src[i] );
+
+ *d++ = pixel;
+ *d++ = pixel >> 8;
+ *d++ = pixel >> 16;
+ }
+ break;
+
+ case DSPF_RGB24:
+ for (i = 0; i < len; i++) {
+#ifdef WORDS_BIGENDIAN
+ *d++ = src[i] >> 16;
+ *d++ = src[i] >> 8;
+ *d++ = src[i];
+#else
+ *d++ = src[i];
+ *d++ = src[i] >> 8;
+ *d++ = src[i] >> 16;
+#endif
+ }
+ break;
+
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ direct_memcpy( d, src, len*4 );
+ break;
+
+ case DSPF_AiRGB:
+ for (i = 0; i < len; i++)
+ ((u32*)d)[i] = src[i] ^ 0xff000000;
+ break;
+
+ case DSPF_LUT8:
+ if (palette) {
+ for (i = 0; i < len; i++) {
+ d[i] = dfb_palette_search( palette,
+ (src[i] >> 16) & 0xff,
+ (src[i] >> 8) & 0xff,
+ (src[i] ) & 0xff,
+ (src[i] >> 24) & 0xff );
+ }
+ }
+ break;
+
+ case DSPF_ALUT44:
+ if (palette) {
+ for (i = 0; i < len; i++) {
+ d[i] = ((src[i] >> 24) & 0xf0) +
+ dfb_palette_search( palette,
+ (src[i] >> 16) & 0xff,
+ (src[i] >> 8) & 0xff,
+ (src[i] ) & 0xff, 0x80 );
+ }
+ }
+ break;
+
+ case DSPF_YUY2:
+ if (dx & 1) {
+ u32 y, u, v;
+
+ RGB_TO_YCBCR( (src[0] >> 16) & 0xff,
+ (src[0] >> 8) & 0xff,
+ (src[0] ) & 0xff, y, u, v );
+ *((u16*)d) = y | (v << 8);
+ d += 2;
+ src++;
+ len--;
+ }
+ for (i = 0; i < (len-1); i += 2) {
+ u32 y0, u, v;
+ u32 y1, u1, v1;
+
+ RGB_TO_YCBCR( (src[i+0] >> 16) & 0xff,
+ (src[i+0] >> 8) & 0xff,
+ (src[i+0] ) & 0xff, y0, u, v );
+ RGB_TO_YCBCR( (src[i+1] >> 16) & 0xff,
+ (src[i+1] >> 8) & 0xff,
+ (src[i+1] ) & 0xff, y1, u1, v1 );
+
+ u = (u + u1) >> 1;
+ v = (v + v1) >> 1;
+
+ ((u16*)d)[i+0] = y0 | (u << 8);
+ ((u16*)d)[i+1] = y1 | (v << 8);
+ }
+ if (len & 1) {
+ u32 y, u, v;
+
+ src += len-1;
+ d += (len-1) * 2;
+
+ RGB_TO_YCBCR( (*src >> 16) & 0xff,
+ (*src >> 8) & 0xff,
+ (*src ) & 0xff, y, u, v );
+ *((u16*)d) = y | (u << 8);
+ }
+ break;
+
+ case DSPF_UYVY:
+ if (dx & 1) {
+ u32 y, u, v;
+
+ RGB_TO_YCBCR( (src[0] >> 16) & 0xff,
+ (src[0] >> 8) & 0xff,
+ (src[0] ) & 0xff, y, u, v );
+ *((u16*)d) = v | (y << 8);
+ d += 2;
+ src++;
+ len--;
+ }
+ for (i = 0; i < (len-1); i += 2) {
+ u32 y0, u, v;
+ u32 y1, u1, v1;
+
+ RGB_TO_YCBCR( (src[i+0] >> 16) & 0xff,
+ (src[i+0] >> 8) & 0xff,
+ (src[i+0] ) & 0xff, y0, u, v );
+ RGB_TO_YCBCR( (src[i+1] >> 16) & 0xff,
+ (src[i+1] >> 8) & 0xff,
+ (src[i+1] ) & 0xff, y1, u1, v1 );
+
+ u = (u + u1) >> 1;
+ v = (v + v1) >> 1;
+
+ ((u16*)d)[i+0] = u | (y0 << 8);
+ ((u16*)d)[i+1] = v | (y1 << 8);
+ }
+ if (len & 1) {
+ u32 y, u, v;
+
+ src += len-1;
+ d += (len-1) * 2;
+
+ RGB_TO_YCBCR( (*src >> 16) & 0xff,
+ (*src >> 8) & 0xff,
+ (*src ) & 0xff, y, u, v );
+ *((u16*)d) = u | (y << 8);
+ }
+ break;
+
+ case DSPF_AYUV:
+ for (i = 0; i < len; i++) {
+ u32 a, y, u, v;
+
+ RGB_TO_YCBCR( (src[i] >> 16) & 0xff,
+ (src[i] >> 8) & 0xff,
+ (src[i] ) & 0xff, y, u, v );
+ a = (src[i] >> 24) & 0xff;
+
+ ((u32*)d)[i] = PIXEL_AYUV( a, y, u, v );
+ }
+ break;
+
+ case DSPF_YV12:
+ case DSPF_I420:
+ d1 = dst[1];
+ d2 = dst[2];
+ for (i = 0; i < (len-1); i += 2) {
+ u32 y0, u0, v0;
+ u32 y1, u1, v1;
+
+ RGB_TO_YCBCR( (src[i+0] >> 16) & 0xff,
+ (src[i+0] >> 8) & 0xff,
+ (src[i+0] ) & 0xff, y0, u0, v0 );
+ RGB_TO_YCBCR( (src[i+1] >> 16) & 0xff,
+ (src[i+1] >> 8) & 0xff,
+ (src[i+1] ) & 0xff, y1, u1, v1 );
+
+ d[i+0] = y0;
+ d[i+1] = y1;
+
+ if (dy & 1) {
+ d1[i>>1] = (u0 + u1) >> 1;
+ d2[i>>1] = (v0 + v1) >> 1;
+ }
+ }
+ if (len & 1) {
+ u32 y, u, v;
+
+ i = len-1;
+
+ RGB_TO_YCBCR( (src[i] >> 16) & 0xff,
+ (src[i] >> 8) & 0xff,
+ (src[i] ) & 0xff, y, u, v );
+
+ d[i] = y;
+ if (dy & 1) {
+ d1[i>>1] = u;
+ d2[i>>1] = v;
+ }
+ }
+ break;
+
+ case DSPF_NV12:
+ case DSPF_NV16:
+ d1 = dst[1];
+ for (i = 0; i < (len-1); i += 2) {
+ u32 y0, u0, v0;
+ u32 y1, u1, v1;
+
+ RGB_TO_YCBCR( (src[i+0] >> 16) & 0xff,
+ (src[i+0] >> 8) & 0xff,
+ (src[i+0] ) & 0xff, y0, u0, v0 );
+ RGB_TO_YCBCR( (src[i+1] >> 16) & 0xff,
+ (src[i+1] >> 8) & 0xff,
+ (src[i+1] ) & 0xff, y1, u1, v1 );
+
+ d[i+0] = y0;
+ d[i+1] = y1;
+
+ if (dst_surface->config.format == DSPF_NV16 || dy & 1) {
+#ifdef WORDS_BIGENDIAN
+ ((u16*)d1)[i>>1] = ((v0 + v1) >> 1) |
+ (((u0 + u1) >> 1) << 8);
+#else
+ ((u16*)d1)[i>>1] = ((u0 + u1) >> 1) |
+ (((v0 + v1) >> 1) << 8);
+#endif
+ }
+ }
+ if (len & 1) {
+ u32 y, u, v;
+
+ i = len-1;
+
+ RGB_TO_YCBCR( (src[i] >> 16) & 0xff,
+ (src[i] >> 8) & 0xff,
+ (src[i] ) & 0xff, y, u, v );
+
+ d[i] = y;
+ if (dst_surface->config.format == DSPF_NV16 || dy & 1)
+#ifdef WORDS_BIGENDIAN
+ ((u16*)d1)[i>>1] = v | (u << 8);
+#else
+ ((u16*)d1)[i>>1] = u | (v << 8);
+#endif
+ }
+ break;
+
+ case DSPF_NV21:
+ d1 = dst[1];
+ for (i = 0; i < (len-1); i += 2) {
+ u32 y0, u0, v0;
+ u32 y1, u1, v1;
+
+ RGB_TO_YCBCR( (src[i+0] >> 16) & 0xff,
+ (src[i+0] >> 8) & 0xff,
+ (src[i+0] ) & 0xff, y0, u0, v0 );
+ RGB_TO_YCBCR( (src[i+1] >> 16) & 0xff,
+ (src[i+1] >> 8) & 0xff,
+ (src[i+1] ) & 0xff, y1, u1, v1 );
+
+ d[i+0] = y0;
+ d[i+1] = y1;
+
+ if (dy & 1) {
+#ifdef WORDS_BIGENDIAN
+ ((u16*)d1)[i>>1] = ((u0 + u1) >> 1) |
+ (((v0 + v1) >> 1) << 8);
+#else
+ ((u16*)d1)[i>>1] = ((v0 + v1) >> 1) |
+ (((u0 + u1) >> 1) << 8);
+#endif
+ }
+ }
+ if (len & 1) {
+ u32 y, u, v;
+
+ i = len-1;
+
+ RGB_TO_YCBCR( (src[i] >> 16) & 0xff,
+ (src[i] >> 8) & 0xff,
+ (src[i] ) & 0xff, y, u, v );
+
+ d[i] = y;
+ if (dy & 1)
+#ifdef WORDS_BIGENDIAN
+ ((u16*)d1)[i>>1] = u | (v << 8);
+#else
+ ((u16*)d1)[i>>1] = v | (u << 8);
+#endif
+ }
+ break;
+
+ case DSPF_RGB555:
+ for (i = 0; i < len; i++)
+ ((u16*)d)[i] = ARGB_TO_RGB555( src[i] );
+ break;
+
+ case DSPF_BGR555:
+ for (i = 0; i < len; i++)
+ ((u16*)d)[i] = ARGB_TO_BGR555( src[i] );
+ break;
+
+ case DSPF_RGB444:
+ for (i = 0; i < len; i++)
+ ((u16*)d)[i] = ARGB_TO_RGB444( src[i] );
+ break;
+
+ default:
+ D_ONCE( "unimplemented destination format (0x%08x)", dst_surface->config.format );
+ break;
+ }
+}
+
+#define LINE_PTR(dst,caps,y,h,pitch) \
+ ((caps & DSCAPS_SEPARATED) \
+ ? (((u8*)(dst)) + (y)/2 * (pitch) + (((y)%2) ? (h)/2 * (pitch) : 0)) \
+ : (((u8*)(dst)) + (y) * (pitch)))
+
+void dfb_copy_buffer_32( u32 *src,
+ void *dst, int dpitch, DFBRectangle *drect,
+ CoreSurface *dst_surface, const DFBRegion *dst_clip )
+{
+ void *dst1, *dst2;
+ int sw = drect->w;
+ int y, x;
+
+ if (dst_clip) {
+ int sx = 0, sy = 0;
+
+ if (drect->x < dst_clip->x1) {
+ sx = dst_clip->x1 - drect->x;
+ drect->w -= sx;
+ drect->x += sx;
+ }
+ if (drect->y < dst_clip->y1) {
+ sy = dst_clip->y1 - drect->y;
+ drect->h -= sy;
+ drect->y += sy;
+ }
+ if ((drect->x + drect->w - 1) > dst_clip->x2) {
+ drect->w -= drect->x + drect->w - 1 - dst_clip->x2;
+ }
+ if ((drect->y + drect->h - 1) > dst_clip->y2) {
+ drect->h -= drect->y + drect-> h - 1 - dst_clip->y2;
+ }
+
+ src += sy * sw + sx;
+ }
+
+ if (drect->w < 1 || drect->h < 1)
+ return;
+ x = drect->x;
+
+ switch (dst_surface->config.format) {
+ case DSPF_YV12:
+ case DSPF_I420:
+ if (dst_surface->config.format == DSPF_I420) {
+ dst1 = dst + dpitch * dst_surface->config.size.h;
+ dst2 = dst1 + dpitch/2 * dst_surface->config.size.h/2;
+ } else {
+ dst2 = dst + dpitch * dst_surface->config.size.h;
+ dst1 = dst2 + dpitch/2 * dst_surface->config.size.h/2;
+ }
+
+ for (y = drect->y; y < drect->y + drect->h; y++) {
+ u8 *d[3];
+
+ d[0] = LINE_PTR( dst, dst_surface->config.caps, y,
+ dst_surface->config.size.h, dpitch ) + x;
+ d[1] = LINE_PTR( dst1, dst_surface->config.caps, y/2,
+ dst_surface->config.size.h/2, dpitch/2 ) + x/2;
+ d[2] = LINE_PTR( dst2, dst_surface->config.caps, y/2,
+ dst_surface->config.size.h/2, dpitch/2 ) + x/2;
+
+ write_argb_span( src, d, drect->w, x, y, dst_surface );
+
+ src += sw;
+ }
+ break;
+
+ case DSPF_NV12:
+ case DSPF_NV21:
+ dst1 = dst + dpitch * dst_surface->config.size.h;
+
+ for (y = drect->y; y < drect->y + drect->h; y++) {
+ u8 *d[2];
+
+ d[0] = LINE_PTR( dst, dst_surface->config.caps, y,
+ dst_surface->config.size.h, dpitch ) + x;
+ d[1] = LINE_PTR( dst1, dst_surface->config.caps, y/2,
+ dst_surface->config.size.h/2, dpitch ) + (x&~1);
+
+ write_argb_span( src, d, drect->w, x, y, dst_surface );
+
+ src += sw;
+ }
+ break;
+
+ case DSPF_NV16:
+ dst1 = dst + dpitch * dst_surface->config.size.h;
+
+ for (y = drect->y; y < drect->y + drect->h; y++) {
+ u8 *d[2];
+
+ d[0] = LINE_PTR( dst, dst_surface->config.caps, y,
+ dst_surface->config.size.h, dpitch ) + x;
+ d[1] = LINE_PTR( dst1, dst_surface->config.caps, y,
+ dst_surface->config.size.h, dpitch ) + (x&~1);
+
+ write_argb_span( src, d, drect->w, x, y, dst_surface );
+
+ src += sw;
+ }
+ break;
+
+ default:
+ for (y = drect->y; y < drect->y + drect->h; y++) {
+ u8 *d[1];
+
+ d[0] = LINE_PTR( dst, dst_surface->config.caps,
+ y, dst_surface->config.size.h, dpitch ) +
+ DFB_BYTES_PER_LINE( dst_surface->config.format, x );
+
+ write_argb_span( src, d, drect->w, x, y, dst_surface );
+
+ src += sw;
+ }
+ break;
+ }
+}
+
+static int bilinear_make_fast_weights( PixopsFilter *filter,
+ const float x_scale, const float y_scale )
+{
+ int i_offset, j_offset;
+ float *x_weights, *y_weights;
+ int n_x, n_y;
+
+ if (x_scale > 1.0) { /* Bilinear */
+ n_x = 2;
+ filter->x_offset = 0.5 * (1.0 / x_scale - 1);
+ }
+ else { /* Tile */
+ n_x = D_ICEIL (1.0 + 1.0 / x_scale);
+ filter->x_offset = 0.0;
+ }
+
+ if (y_scale > 1.0) { /* Bilinear */
+ n_y = 2;
+ filter->y_offset = 0.5 * (1.0 / y_scale - 1);
+ }
+ else { /* Tile */
+ n_y = D_ICEIL (1.0 + 1.0 / y_scale);
+ filter->y_offset = 0.0;
+ }
+
+ if (n_x > 64)
+ n_x = 64;
+
+ if (n_y > 64)
+ n_y = 64;
+
+ filter->n_y = n_y;
+ filter->n_x = n_x;
+ filter->weights = (int *) D_MALLOC( SUBSAMPLE * SUBSAMPLE * n_x * n_y *
+ sizeof (int) );
+ if (!filter->weights) {
+ D_WARN ("couldn't allocate memory for scaling");
+ return 0;
+ }
+
+ x_weights = (float *) alloca (n_x * sizeof (float));
+ y_weights = (float *) alloca (n_y * sizeof (float));
+
+ if (!x_weights || !y_weights) {
+ D_FREE( filter->weights );
+
+ D_WARN ("couldn't allocate memory for scaling");
+ return 0;
+ }
+
+ for (i_offset = 0; i_offset < SUBSAMPLE; i_offset++)
+ for (j_offset = 0; j_offset < SUBSAMPLE; j_offset++) {
+ int *pixel_weights = filter->weights
+ + ((i_offset * SUBSAMPLE) + j_offset)
+ * n_x * n_y;
+
+ float x = (float)j_offset / 16;
+ float y = (float)i_offset / 16;
+ int i, j;
+
+ if (x_scale > 1.0) { /* Bilinear */
+ for (i = 0; i < n_x; i++) {
+ x_weights[i] = ((i == 0) ? (1 - x) : x) / x_scale;
+ }
+ }
+ else { /* Tile */
+ for (i = 0; i < n_x; i++) {
+ if (i < x) {
+ if (i + 1 > x)
+ x_weights[i] = MIN( i + 1, x + 1.0 / x_scale ) -x;
+ else
+ x_weights[i] = 0;
+ }
+ else {
+ if (x + 1/x_scale > i)
+ x_weights[i] = MIN( i + 1, x + 1.0 / x_scale ) -i;
+ else
+ x_weights[i] = 0;
+ }
+ }
+ }
+
+ if (y_scale > 1.0) { /* Bilinear */
+ for (i = 0; i < n_y; i++) {
+ y_weights[i] = ((i == 0) ? (1 - y) : y) / y_scale;
+ }
+ }
+ else { /* Tile */
+ for (i = 0; i < n_y; i++) {
+ if (i < y) {
+ if (i + 1 > y)
+ y_weights[i] = MIN( i + 1, y + 1.0 / y_scale ) -y;
+ else
+ y_weights[i] = 0;
+ }
+ else {
+ if (y + 1/y_scale > i)
+ y_weights[i] = MIN( i + 1, y + 1.0 / y_scale ) -i;
+ else
+ y_weights[i] = 0;
+ }
+ }
+ }
+
+ for (i = 0; i < n_y; i++) {
+ for (j = 0; j < n_x; j++) {
+ pixel_weights[n_x * i + j] =
+ 65536.0 * x_weights[j] * x_scale
+ * y_weights[i] * y_scale;
+ }
+ }
+ }
+
+ return 1;
+}
+
+static void scale_pixel( const int *weights, int n_x, int n_y,
+ u32 *dst, const u32 **src, int x, int sw )
+{
+ u32 r = 0, g = 0, b = 0, a = 0;
+ int i, j;
+
+ for (i = 0; i < n_y; i++) {
+ const int *pixel_weights = weights + n_x * i;
+
+ for (j = 0; j < n_x; j++) {
+ const u32 *q;
+
+ if (x + j < 0)
+ q = src[i];
+ else if (x + j < sw)
+ q = src[i] + x + j;
+ else
+ q = src[i] + sw - 1;
+
+ {
+ const u32 ta = ((*q & 0xFF000000) >> 24) * pixel_weights[j];
+
+ b += ta * (((*q & 0xFF)) + 1);
+ g += ta * (((*q & 0xFF00) >> 8) + 1);
+ r += ta * (((*q & 0xFF0000) >> 16) + 1);
+ a += ta;
+ }
+ }
+ }
+
+ r = (r >> 24) == 0xFF ? 0xFF : (r + 0x800000) >> 24;
+ g = (g >> 24) == 0xFF ? 0xFF : (g + 0x800000) >> 24;
+ b = (b >> 24) == 0xFF ? 0xFF : (b + 0x800000) >> 24;
+ a = (a >> 16) == 0xFF ? 0xFF : (a + 0x8000) >> 16;
+
+ *dst = (a << 24) | (r << 16) | (g << 8) | b;
+}
+
+static u32* scale_line( const int *weights, int n_x, int n_y,
+ u32 *dst, u32 *dst_end,
+ const u32 **src, int x, int x_step, int sw )
+{
+ while (dst < dst_end) {
+ const int x_scaled = x >> SCALE_SHIFT;
+ const int *pixel_weights = weights + ((x >> (SCALE_SHIFT -
+ SUBSAMPLE_BITS))
+ & SUBSAMPLE_MASK) * n_x * n_y;
+ u32 r = 0, g = 0, b = 0, a = 0;
+ int i, j;
+
+ for (i = 0; i < n_y; i++) {
+ const int *line_weights = pixel_weights + n_x * i;
+ const u32 *q = src[i] + x_scaled;
+
+ for (j = 0; j < n_x; j++) {
+ const u32 ta = ((*q & 0xFF000000) >> 24) * line_weights[j];
+
+ b += ta * (((*q & 0xFF)) + 1);
+ g += ta * (((*q & 0xFF00) >> 8) + 1);
+ r += ta * (((*q & 0xFF0000) >> 16) + 1);
+ a += ta;
+
+ q++;
+ }
+ }
+
+ r = (r >> 24) == 0xFF ? 0xFF : (r + 0x800000) >> 24;
+ g = (g >> 24) == 0xFF ? 0xFF : (g + 0x800000) >> 24;
+ b = (b >> 24) == 0xFF ? 0xFF : (b + 0x800000) >> 24;
+ a = (a >> 16) == 0xFF ? 0xFF : (a + 0x8000) >> 16;
+
+ *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
+
+ x += x_step;
+ }
+
+ return dst;
+}
+
+void dfb_scale_linear_32( u32 *src, int sw, int sh,
+ void *dst, int dpitch, DFBRectangle *drect,
+ CoreSurface *dst_surface, const DFBRegion *dst_clip )
+{
+ DFBRectangle srect = { 0, 0, sw, sh };
+ float scale_x, scale_y;
+ int i, j;
+ int sx, sy;
+ int x_step, y_step;
+ int scaled_x_offset;
+ PixopsFilter filter;
+ void *dst1 = NULL, *dst2 = NULL;
+ u32 *buf;
+
+ if (drect->w == sw && drect->h == sh) {
+ dfb_copy_buffer_32( src, dst, dpitch, drect, dst_surface, dst_clip );
+ return;
+ }
+
+ if (dst_clip)
+ dfb_clip_stretchblit( dst_clip, &srect, drect );
+
+ if (srect.w < 1 || srect.h < 1 || drect->w < 1 || drect->h < 1)
+ return;
+
+ src += srect.y * sw + srect.x;
+
+ scale_x = (float)drect->w / srect.w;
+ scale_y = (float)drect->h / srect.h;
+
+ x_step = (1 << SCALE_SHIFT) / scale_x;
+ y_step = (1 << SCALE_SHIFT) / scale_y;
+
+ if (! bilinear_make_fast_weights( &filter, scale_x, scale_y ))
+ return;
+
+ scaled_x_offset = D_IFLOOR( filter.x_offset * (1 << SCALE_SHIFT) );
+ sy = D_IFLOOR( filter.y_offset * (1 << SCALE_SHIFT) );
+
+ switch (dst_surface->config.format) {
+ case DSPF_I420:
+ dst1 = dst + dpitch * dst_surface->config.size.h;
+ dst2 = dst1 + dpitch/2 * dst_surface->config.size.h/2;
+ break;
+ case DSPF_YV12:
+ dst2 = dst + dpitch * dst_surface->config.size.h;
+ dst1 = dst2 + dpitch/2 * dst_surface->config.size.h/2;
+ break;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ case DSPF_NV16:
+ dst1 = dst + dpitch * dst_surface->config.size.h;
+ break;
+ default:
+ break;
+ }
+
+ buf = (u32*) alloca( drect->w * 4 );
+
+ for (i = drect->y; i < drect->y + drect->h; i++) {
+ int x_start;
+ int y_start;
+ const int *run_weights;
+ u32 *outbuf = buf;
+ u32 *outbuf_end = buf + drect->w;
+ u32 *new_outbuf;
+ const u32 **line_bufs;
+ u8 *d[3];
+
+ y_start = sy >> SCALE_SHIFT;
+
+ run_weights = filter.weights + ((sy >> (SCALE_SHIFT - SUBSAMPLE_BITS))
+ & SUBSAMPLE_MASK) * filter.n_x * filter.n_y * SUBSAMPLE;
+
+ line_bufs = (const u32 **) alloca( filter.n_y * sizeof (void *) );
+
+ for (j = 0; j < filter.n_y; j++) {
+ if (y_start < 0)
+ line_bufs[j] = src;
+ else if (y_start < sh)
+ line_bufs[j] = src + sw * y_start;
+ else
+ line_bufs[j] = src + sw * (sh - 1);
+
+ y_start++;
+ }
+
+ sx = scaled_x_offset;
+ x_start = sx >> SCALE_SHIFT;
+
+ while (x_start < 0 && outbuf < outbuf_end) {
+ scale_pixel( run_weights + ((sx >> (SCALE_SHIFT - SUBSAMPLE_BITS))
+ & SUBSAMPLE_MASK) * (filter.n_x * filter.n_y),
+ filter.n_x, filter.n_y,
+ outbuf, line_bufs, sx >> SCALE_SHIFT, sw );
+ sx += x_step;
+ x_start = sx >> SCALE_SHIFT;
+ outbuf++;
+ }
+
+ new_outbuf = scale_line( run_weights, filter.n_x, filter.n_y,
+ outbuf, outbuf_end, line_bufs,
+ sx >> SCALE_SHIFT, x_step, sw );
+ sx = ((outbuf_end - outbuf) >> 2) * x_step + scaled_x_offset;
+ outbuf = new_outbuf;
+
+ while (outbuf < outbuf_end) {
+ scale_pixel( run_weights + ((sx >> (SCALE_SHIFT - SUBSAMPLE_BITS))
+ & SUBSAMPLE_MASK) * (filter.n_x * filter.n_y),
+ filter.n_x, filter.n_y,
+ outbuf, line_bufs, sx >> SCALE_SHIFT, sw );
+ sx += x_step;
+ outbuf++;
+ }
+
+ sy += y_step;
+
+ d[0] = LINE_PTR( dst, dst_surface->config.caps,
+ i, dst_surface->config.size.h, dpitch ) +
+ DFB_BYTES_PER_LINE( dst_surface->config.format, drect->x );
+
+ switch (dst_surface->config.format) {
+ case DSPF_I420:
+ case DSPF_YV12:
+ d[1] = LINE_PTR( dst1, dst_surface->config.caps, i/2,
+ dst_surface->config.size.h/2, dpitch/2 ) + drect->x/2;
+ d[2] = LINE_PTR( dst2, dst_surface->config.caps, i/2,
+ dst_surface->config.size.h/2, dpitch/2 ) + drect->x/2;
+ break;
+ case DSPF_NV12:
+ case DSPF_NV21:
+ d[1] = LINE_PTR( dst1, dst_surface->config.caps, i/2,
+ dst_surface->config.size.h/2, dpitch ) + (drect->x&~1);
+ break;
+ case DSPF_NV16:
+ d[1] = LINE_PTR( dst1, dst_surface->config.caps, i,
+ dst_surface->config.size.h, dpitch ) + (drect->x&~1);
+ break;
+ default:
+ break;
+ }
+
+ write_argb_span( buf, d, drect->w, drect->x, i, dst_surface );
+ }
+
+ D_FREE(filter.weights);
+}
+
diff --git a/Source/DirectFB/src/misc/gfx_util.h b/Source/DirectFB/src/misc/gfx_util.h
new file mode 100755
index 0000000..56b7944
--- /dev/null
+++ b/Source/DirectFB/src/misc/gfx_util.h
@@ -0,0 +1,48 @@
+/*
+ (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>.
+
+ Scaling routines ported from gdk_pixbuf by Sven Neumann
+ <sven@convergence.de>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __GFX_UTIL_H__
+#define __GFX_UTIL_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+void dfb_copy_buffer_32( u32 *src,
+ void *dst, int dpitch, DFBRectangle *drect,
+ CoreSurface *dst_surface, const DFBRegion *dst_clip );
+
+void dfb_scale_linear_32( u32 *src, int sw, int sh,
+ void *dst, int dpitch, DFBRectangle *drect,
+ CoreSurface *dst_surface, const DFBRegion *dst_clip );
+
+
+#endif
diff --git a/Source/DirectFB/src/misc/util.c b/Source/DirectFB/src/misc/util.c
new file mode 100755
index 0000000..7a80eec
--- /dev/null
+++ b/Source/DirectFB/src/misc/util.c
@@ -0,0 +1,471 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <misc/util.h>
+
+
+D_DEBUG_DOMAIN( DFB_Updates, "DirectFB/Updates", "DirectFB Updates" );
+
+/**********************************************************************************************************************/
+
+const DirectFBPixelFormatNames( dfb_pixelformat_names );
+
+/**********************************************************************************************************************/
+
+bool
+dfb_region_intersect( DFBRegion *region,
+ int x1, int y1, int x2, int y2 )
+{
+ if (region->x2 < x1 ||
+ region->y2 < y1 ||
+ region->x1 > x2 ||
+ region->y1 > y2)
+ return false;
+
+ if (region->x1 < x1)
+ region->x1 = x1;
+
+ if (region->y1 < y1)
+ region->y1 = y1;
+
+ if (region->x2 > x2)
+ region->x2 = x2;
+
+ if (region->y2 > y2)
+ region->y2 = y2;
+
+ return true;
+}
+
+bool
+dfb_region_region_intersect( DFBRegion *region,
+ const DFBRegion *clip )
+{
+ if (region->x2 < clip->x1 ||
+ region->y2 < clip->y1 ||
+ region->x1 > clip->x2 ||
+ region->y1 > clip->y2)
+ return false;
+
+ if (region->x1 < clip->x1)
+ region->x1 = clip->x1;
+
+ if (region->y1 < clip->y1)
+ region->y1 = clip->y1;
+
+ if (region->x2 > clip->x2)
+ region->x2 = clip->x2;
+
+ if (region->y2 > clip->y2)
+ region->y2 = clip->y2;
+
+ return true;
+}
+
+bool
+dfb_region_rectangle_intersect( DFBRegion *region,
+ const DFBRectangle *rect )
+{
+ int x2 = rect->x + rect->w - 1;
+ int y2 = rect->y + rect->h - 1;
+
+ if (region->x2 < rect->x ||
+ region->y2 < rect->y ||
+ region->x1 > x2 ||
+ region->y1 > y2)
+ return false;
+
+ if (region->x1 < rect->x)
+ region->x1 = rect->x;
+
+ if (region->y1 < rect->y)
+ region->y1 = rect->y;
+
+ if (region->x2 > x2)
+ region->x2 = x2;
+
+ if (region->y2 > y2)
+ region->y2 = y2;
+
+ return true;
+}
+
+bool
+dfb_unsafe_region_intersect( DFBRegion *region,
+ int x1, int y1, int x2, int y2 )
+{
+ if (region->x1 > region->x2) {
+ int temp = region->x1;
+ region->x1 = region->x2;
+ region->x2 = temp;
+ }
+
+ if (region->y1 > region->y2) {
+ int temp = region->y1;
+ region->y1 = region->y2;
+ region->y2 = temp;
+ }
+
+ return dfb_region_intersect( region, x1, y1, x2, y2 );
+}
+
+bool
+dfb_unsafe_region_rectangle_intersect( DFBRegion *region,
+ const DFBRectangle *rect )
+{
+ if (region->x1 > region->x2) {
+ int temp = region->x1;
+ region->x1 = region->x2;
+ region->x2 = temp;
+ }
+
+ if (region->y1 > region->y2) {
+ int temp = region->y1;
+ region->y1 = region->y2;
+ region->y2 = temp;
+ }
+
+ return dfb_region_rectangle_intersect( region, rect );
+}
+
+bool
+dfb_rectangle_intersect_by_unsafe_region( DFBRectangle *rectangle,
+ DFBRegion *region )
+{
+ /* validate region */
+ if (region->x1 > region->x2) {
+ int temp = region->x1;
+ region->x1 = region->x2;
+ region->x2 = temp;
+ }
+
+ if (region->y1 > region->y2) {
+ int temp = region->y1;
+ region->y1 = region->y2;
+ region->y2 = temp;
+ }
+
+ /* adjust position */
+ if (region->x1 > rectangle->x) {
+ rectangle->w -= region->x1 - rectangle->x;
+ rectangle->x = region->x1;
+ }
+
+ if (region->y1 > rectangle->y) {
+ rectangle->h -= region->y1 - rectangle->y;
+ rectangle->y = region->y1;
+ }
+
+ /* adjust size */
+ if (region->x2 < rectangle->x + rectangle->w - 1)
+ rectangle->w = region->x2 - rectangle->x + 1;
+
+ if (region->y2 < rectangle->y + rectangle->h - 1)
+ rectangle->h = region->y2 - rectangle->y + 1;
+
+ /* set size to zero if there's no intersection */
+ if (rectangle->w <= 0 || rectangle->h <= 0) {
+ rectangle->w = 0;
+ rectangle->h = 0;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool
+dfb_rectangle_intersect_by_region( DFBRectangle *rectangle,
+ const DFBRegion *region )
+{
+ /* adjust position */
+ if (region->x1 > rectangle->x) {
+ rectangle->w -= region->x1 - rectangle->x;
+ rectangle->x = region->x1;
+ }
+
+ if (region->y1 > rectangle->y) {
+ rectangle->h -= region->y1 - rectangle->y;
+ rectangle->y = region->y1;
+ }
+
+ /* adjust size */
+ if (region->x2 < rectangle->x + rectangle->w - 1)
+ rectangle->w = region->x2 - rectangle->x + 1;
+
+ if (region->y2 < rectangle->y + rectangle->h - 1)
+ rectangle->h = region->y2 - rectangle->y + 1;
+
+ /* set size to zero if there's no intersection */
+ if (rectangle->w <= 0 || rectangle->h <= 0) {
+ rectangle->w = 0;
+ rectangle->h = 0;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool dfb_rectangle_intersect( DFBRectangle *rectangle,
+ const DFBRectangle *clip )
+{
+ DFBRegion region = { clip->x, clip->y,
+ clip->x + clip->w - 1, clip->y + clip->h - 1 };
+
+ /* adjust position */
+ if (region.x1 > rectangle->x) {
+ rectangle->w -= region.x1 - rectangle->x;
+ rectangle->x = region.x1;
+ }
+
+ if (region.y1 > rectangle->y) {
+ rectangle->h -= region.y1 - rectangle->y;
+ rectangle->y = region.y1;
+ }
+
+ /* adjust size */
+ if (region.x2 < rectangle->x + rectangle->w - 1)
+ rectangle->w = region.x2 - rectangle->x + 1;
+
+ if (region.y2 < rectangle->y + rectangle->h - 1)
+ rectangle->h = region.y2 - rectangle->y + 1;
+
+ /* set size to zero if there's no intersection */
+ if (rectangle->w <= 0 || rectangle->h <= 0) {
+ rectangle->w = 0;
+ rectangle->h = 0;
+
+ return false;
+ }
+
+ return true;
+}
+
+void dfb_rectangle_union ( DFBRectangle *rect1,
+ const DFBRectangle *rect2 )
+{
+ if (!rect2->w || !rect2->h)
+ return;
+
+ /* FIXME: OPTIMIZE */
+
+ if (rect1->w) {
+ int temp = MIN (rect1->x, rect2->x);
+ rect1->w = MAX (rect1->x + rect1->w, rect2->x + rect2->w) - temp;
+ rect1->x = temp;
+ }
+ else {
+ rect1->x = rect2->x;
+ rect1->w = rect2->w;
+ }
+
+ if (rect1->h) {
+ int temp = MIN (rect1->y, rect2->y);
+ rect1->h = MAX (rect1->y + rect1->h, rect2->y + rect2->h) - temp;
+ rect1->y = temp;
+ }
+ else {
+ rect1->y = rect2->y;
+ rect1->h = rect2->h;
+ }
+}
+
+void
+dfb_updates_init( DFBUpdates *updates,
+ DFBRegion *regions,
+ int max_regions )
+{
+ D_ASSERT( updates != NULL );
+ D_ASSERT( regions != NULL );
+ D_ASSERT( max_regions > 0 );
+
+ updates->regions = regions;
+ updates->max_regions = max_regions;
+ updates->num_regions = 0;
+
+ D_MAGIC_SET( updates, DFBUpdates );
+}
+
+void
+dfb_updates_add( DFBUpdates *updates,
+ const DFBRegion *region )
+{
+ int i;
+
+ D_MAGIC_ASSERT( updates, DFBUpdates );
+ DFB_REGION_ASSERT( region );
+ D_ASSERT( updates->regions != NULL );
+ D_ASSERT( updates->num_regions >= 0 );
+ D_ASSERT( updates->num_regions <= updates->max_regions );
+
+ D_DEBUG_AT( DFB_Updates, "%s( %p, %4d,%4d-%4dx%4d )\n", __FUNCTION__, updates,
+ DFB_RECTANGLE_VALS_FROM_REGION(region) );
+
+ if (updates->num_regions == 0) {
+ D_DEBUG_AT( DFB_Updates, " -> added as first\n" );
+
+ updates->regions[0] = updates->bounding = *region;
+ updates->num_regions = 1;
+
+ return;
+ }
+
+ for (i=0; i<updates->num_regions; i++) {
+ if (dfb_region_region_extends( &updates->regions[i], region ) ||
+ dfb_region_region_intersects( &updates->regions[i], region ))
+ {
+ D_DEBUG_AT( DFB_Updates, " -> combined with [%d] %4d,%4d-%4dx%4d\n", i,
+ DFB_RECTANGLE_VALS_FROM_REGION(&updates->regions[i]) );
+
+ dfb_region_region_union( &updates->regions[i], region );
+
+ dfb_region_region_union( &updates->bounding, region );
+
+ D_DEBUG_AT( DFB_Updates, " -> resulting in [%d] %4d,%4d-%4dx%4d\n", i,
+ DFB_RECTANGLE_VALS_FROM_REGION(&updates->regions[i]) );
+
+ return;
+ }
+ }
+
+ if (updates->num_regions == updates->max_regions) {
+ dfb_region_region_union( &updates->bounding, region );
+
+ updates->regions[0] = updates->bounding;
+ updates->num_regions = 1;
+
+ D_DEBUG_AT( DFB_Updates, " -> collapsing to [0] %4d,%4d-%4dx%4d\n",
+ DFB_RECTANGLE_VALS_FROM_REGION(&updates->regions[0]) );
+ }
+ else {
+ updates->regions[updates->num_regions++] = *region;
+
+ dfb_region_region_union( &updates->bounding, region );
+
+ D_DEBUG_AT( DFB_Updates, " -> added as [%d] %4d,%4d-%4dx%4d\n", updates->num_regions - 1,
+ DFB_RECTANGLE_VALS_FROM_REGION(&updates->regions[updates->num_regions - 1]) );
+ }
+}
+
+void
+dfb_updates_stat( DFBUpdates *updates,
+ int *ret_total,
+ int *ret_bounding )
+{
+ int i;
+
+ D_MAGIC_ASSERT( updates, DFBUpdates );
+ D_ASSERT( updates->regions != NULL );
+ D_ASSERT( updates->num_regions >= 0 );
+ D_ASSERT( updates->num_regions <= updates->max_regions );
+
+ if (updates->num_regions == 0) {
+ if (ret_total)
+ *ret_total = 0;
+
+ if (ret_bounding)
+ *ret_bounding = 0;
+
+ return;
+ }
+
+ if (ret_total) {
+ int total = 0;
+
+ for (i=0; i<updates->num_regions; i++) {
+ const DFBRegion *r = &updates->regions[i];
+
+ total += (r->x2 - r->x1 + 1) * (r->y2 - r->y1 + 1);
+ }
+
+ *ret_total = total;
+ }
+
+ if (ret_bounding)
+ *ret_bounding = (updates->bounding.x2 - updates->bounding.x1 + 1) *
+ (updates->bounding.y2 - updates->bounding.y1 + 1);
+}
+
+void
+dfb_updates_get_rectangles( DFBUpdates *updates,
+ DFBRectangle *ret_rects,
+ int *ret_num )
+{
+ D_MAGIC_ASSERT( updates, DFBUpdates );
+ D_ASSERT( updates->regions != NULL );
+ D_ASSERT( updates->num_regions >= 0 );
+ D_ASSERT( updates->num_regions <= updates->max_regions );
+
+ switch (updates->num_regions) {
+ case 0:
+ *ret_num = 0;
+ break;
+
+ default: {
+ int n, d, total, bounding;
+
+ dfb_updates_stat( updates, &total, &bounding );
+
+ n = updates->max_regions - updates->num_regions + 1;
+ d = n + 1;
+
+ /* Try to optimize updates. Use individual regions only if not too much overhead. */
+ if (total < bounding * n / d) {
+ *ret_num = updates->num_regions;
+
+ for (n=0; n<updates->num_regions; n++)
+ ret_rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( &updates->regions[n] );
+
+ break;
+ }
+ }
+ /* fall through */
+
+ case 1:
+ *ret_num = 1;
+ *ret_rects = DFB_RECTANGLE_INIT_FROM_REGION( &updates->bounding );
+ break;
+ }
+}
diff --git a/Source/DirectFB/src/misc/util.h b/Source/DirectFB/src/misc/util.h
new file mode 100755
index 0000000..3d2d8e6
--- /dev/null
+++ b/Source/DirectFB/src/misc/util.h
@@ -0,0 +1,34 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __MISC__UTIL_H__
+#define __MISC__UTIL_H__
+
+#include <directfb_util.h>
+
+#endif
diff --git a/Source/DirectFB/src/windows/Makefile.am b/Source/DirectFB/src/windows/Makefile.am
new file mode 100755
index 0000000..572dc27
--- /dev/null
+++ b/Source/DirectFB/src/windows/Makefile.am
@@ -0,0 +1,20 @@
+## Makefile.am for DirectFB/src/windows
+
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+
+internalincludedir = $(INTERNALINCLUDEDIR)/windows
+
+internalinclude_HEADERS = \
+ idirectfbwindow.h
+
+
+noinst_LTLIBRARIES = libdirectfb_windows.la
+
+libdirectfb_windows_la_SOURCES = \
+ idirectfbwindow.c
diff --git a/Source/DirectFB/src/windows/Makefile.in b/Source/DirectFB/src/windows/Makefile.in
new file mode 100755
index 0000000..23e44b9
--- /dev/null
+++ b/Source/DirectFB/src/windows/Makefile.in
@@ -0,0 +1,552 @@
+# 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 = src/windows
+DIST_COMMON = $(internalinclude_HEADERS) $(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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libdirectfb_windows_la_LIBADD =
+am_libdirectfb_windows_la_OBJECTS = idirectfbwindow.lo
+libdirectfb_windows_la_OBJECTS = $(am_libdirectfb_windows_la_OBJECTS)
+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 = $(libdirectfb_windows_la_SOURCES)
+DIST_SOURCES = $(libdirectfb_windows_la_SOURCES)
+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)$(internalincludedir)"
+internalincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(internalinclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+internalincludedir = $(INTERNALINCLUDEDIR)/windows
+internalinclude_HEADERS = \
+ idirectfbwindow.h
+
+noinst_LTLIBRARIES = libdirectfb_windows.la
+libdirectfb_windows_la_SOURCES = \
+ idirectfbwindow.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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 src/windows/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/windows/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
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_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
+libdirectfb_windows.la: $(libdirectfb_windows_la_OBJECTS) $(libdirectfb_windows_la_DEPENDENCIES)
+ $(LINK) $(libdirectfb_windows_la_OBJECTS) $(libdirectfb_windows_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idirectfbwindow.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-internalincludeHEADERS: $(internalinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(internalincludedir)" || $(MKDIR_P) "$(DESTDIR)$(internalincludedir)"
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(internalincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ $(internalincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(internalincludedir)/$$f"; \
+ done
+
+uninstall-internalincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(internalinclude_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(internalincludedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(internalincludedir)/$$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) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(internalincludedir)"; 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-libtool clean-noinstLTLIBRARIES \
+ 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-internalincludeHEADERS
+
+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-internalincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES 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-info install-info-am \
+ install-internalincludeHEADERS 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-internalincludeHEADERS
+
+# 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/src/windows/idirectfbwindow.c b/Source/DirectFB/src/windows/idirectfbwindow.c
new file mode 100755
index 0000000..d3fb281
--- /dev/null
+++ b/Source/DirectFB/src/windows/idirectfbwindow.c
@@ -0,0 +1,1446 @@
+/*
+ (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 <sched.h>
+
+#include <sys/time.h>
+#include <errno.h>
+
+#include <pthread.h>
+
+#include <directfb.h>
+
+#include <idirectfb.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/layers.h>
+#include <core/palette.h>
+#include <core/state.h>
+#include <core/surface.h>
+#include <core/windows.h>
+#include <core/wm.h>
+#include <core/windowstack.h>
+#include <core/windows_internal.h> /* FIXME */
+
+#include <display/idirectfbsurface.h>
+#include <display/idirectfbsurface_window.h>
+
+#include <input/idirectfbinputbuffer.h>
+
+#include <misc/util.h>
+#include <direct/interface.h>
+#include <direct/mem.h>
+
+#include <gfx/convert.h>
+
+#include <windows/idirectfbwindow.h>
+
+
+D_DEBUG_DOMAIN( IDirectFB_Window, "IDirectFBWindow", "DirectFB Window Interface" );
+
+
+/*
+ * adds an window event to the event queue
+ */
+static ReactionResult IDirectFBWindow_React( const void *msg_data,
+ void *ctx );
+
+
+
+typedef struct {
+ int ref;
+ CoreWindow *window;
+ CoreLayer *layer;
+
+ IDirectFBSurface *surface;
+
+ Reaction reaction;
+
+ bool detached;
+ bool destroyed;
+
+ CoreDFB *core;
+} IDirectFBWindow_data;
+
+
+static void
+IDirectFBWindow_Destruct( IDirectFBWindow *thiz )
+{
+ IDirectFBWindow_data *data = (IDirectFBWindow_data*)thiz->priv;
+
+ D_DEBUG_AT( IDirectFB_Window, "IDirectFBWindow_Destruct()\n" );
+
+ if (!data->detached) {
+ D_DEBUG_AT( IDirectFB_Window, " -> detaching...\n" );
+
+ dfb_window_detach( data->window, &data->reaction );
+ }
+
+ /* this will destroy the fusion object and (eventually) the window */
+ D_DEBUG_AT( IDirectFB_Window, " -> unrefing...\n" );
+
+ dfb_window_unref( data->window );
+
+ D_DEBUG_AT( IDirectFB_Window, " -> releasing surface...\n" );
+
+ if (data->surface)
+ data->surface->Release( data->surface );
+
+ D_DEBUG_AT( IDirectFB_Window, " -> done.\n" );
+
+ DIRECT_DEALLOCATE_INTERFACE( thiz );
+}
+
+static DirectResult
+IDirectFBWindow_AddRef( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ data->ref++;
+
+ return DFB_OK;
+}
+
+static DirectResult
+IDirectFBWindow_Release( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (--data->ref == 0)
+ IDirectFBWindow_Destruct( thiz );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_CreateEventBuffer( IDirectFBWindow *thiz,
+ IDirectFBEventBuffer **buffer )
+{
+ IDirectFBEventBuffer *b;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ DIRECT_ALLOCATE_INTERFACE( b, IDirectFBEventBuffer );
+
+ IDirectFBEventBuffer_Construct( b, NULL, NULL );
+
+ IDirectFBEventBuffer_AttachWindow( b, data->window );
+
+ dfb_window_send_configuration( data->window );
+
+ *buffer = b;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_AttachEventBuffer( IDirectFBWindow *thiz,
+ IDirectFBEventBuffer *buffer )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ IDirectFBEventBuffer_AttachWindow( buffer, data->window );
+
+ dfb_window_send_configuration( data->window );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_DetachEventBuffer( IDirectFBWindow *thiz,
+ IDirectFBEventBuffer *buffer )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ return IDirectFBEventBuffer_DetachWindow( buffer, data->window );
+}
+
+static DFBResult
+IDirectFBWindow_EnableEvents( IDirectFBWindow *thiz,
+ DFBWindowEventType mask )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (mask & ~DWET_ALL)
+ return DFB_INVARG;
+
+ return dfb_window_change_events( data->window, DWET_NONE, mask );
+}
+
+static DFBResult
+IDirectFBWindow_DisableEvents( IDirectFBWindow *thiz,
+ DFBWindowEventType mask )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (mask & ~DWET_ALL)
+ return DFB_INVARG;
+
+ return dfb_window_change_events( data->window, mask, DWET_NONE );
+}
+
+static DFBResult
+IDirectFBWindow_GetID( IDirectFBWindow *thiz,
+ DFBWindowID *id )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!id)
+ return DFB_INVARG;
+
+ *id = data->window->id;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_GetPosition( IDirectFBWindow *thiz,
+ int *x,
+ int *y )
+{
+ DFBInsets insets;
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!x && !y)
+ return DFB_INVARG;
+
+ dfb_windowstack_lock( data->window->stack );
+ dfb_wm_get_insets( data->window->stack, data->window, &insets );
+ dfb_windowstack_unlock( data->window->stack );
+
+ if (x)
+ *x = data->window->config.bounds.x-insets.l;
+
+ if (y)
+ *y = data->window->config.bounds.y-insets.t;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_GetSize( IDirectFBWindow *thiz,
+ int *width,
+ int *height )
+{
+ DFBInsets insets;
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!width && !height)
+ return DFB_INVARG;
+
+ dfb_windowstack_lock( data->window->stack );
+ dfb_wm_get_insets( data->window->stack, data->window, &insets );
+ dfb_windowstack_unlock( data->window->stack );
+
+ if (width)
+ *width = data->window->config.bounds.w-insets.l-insets.r;
+
+ if (height)
+ *height = data->window->config.bounds.h-insets.t-insets.b;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_GetSurface( IDirectFBWindow *thiz,
+ IDirectFBSurface **surface )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!surface)
+ return DFB_INVARG;
+
+ if (data->window->caps & (DWCAPS_INPUTONLY | DWCAPS_COLOR))
+ return DFB_UNSUPPORTED;
+
+ if (!data->surface) {
+ DFBResult ret;
+
+ DIRECT_ALLOCATE_INTERFACE( *surface, IDirectFBSurface );
+
+ ret = IDirectFBSurface_Window_Construct( *surface, NULL,
+ NULL, NULL, data->window,
+ DSCAPS_DOUBLE, data->core );
+ if (ret)
+ return ret;
+
+ data->surface = *surface;
+ }
+ else
+ *surface = data->surface;
+
+ data->surface->AddRef( data->surface );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_SetProperty( IDirectFBWindow *thiz,
+ const char *key,
+ void *value,
+ void **old_value )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ /* Check arguments */
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!key)
+ return DFB_INVARG;
+
+ dfb_windowstack_lock( data->window->stack );
+ ret = dfb_wm_set_window_property( data->window->stack, data->window, key, value, old_value );
+ dfb_windowstack_unlock( data->window->stack );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBWindow_GetProperty( IDirectFBWindow *thiz,
+ const char *key,
+ void **ret_value )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!key)
+ return DFB_INVARG;
+
+ if (!ret_value)
+ return DFB_INVARG;
+
+ dfb_windowstack_lock( data->window->stack );
+ ret = dfb_wm_get_window_property( data->window->stack, data->window, key, ret_value );
+ dfb_windowstack_unlock( data->window->stack );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBWindow_RemoveProperty( IDirectFBWindow *thiz,
+ const char *key,
+ void **ret_value )
+{
+ DFBResult ret;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!key)
+ return DFB_INVARG;
+
+ dfb_windowstack_lock( data->window->stack );
+ ret = dfb_wm_remove_window_property( data->window->stack, data->window, key, ret_value );
+ dfb_windowstack_unlock( data->window->stack );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBWindow_SetOptions( IDirectFBWindow *thiz,
+ DFBWindowOptions options )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ /* Check arguments */
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (options & ~DWOP_ALL)
+ return DFB_INVARG;
+
+ if (!(data->window->caps & DWCAPS_ALPHACHANNEL))
+ options &= ~DWOP_ALPHACHANNEL;
+
+ /* Set new options */
+ return dfb_window_change_options( data->window, DWOP_ALL, options );
+}
+
+static DFBResult
+IDirectFBWindow_GetOptions( IDirectFBWindow *thiz,
+ DFBWindowOptions *ret_options )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!ret_options)
+ return DFB_INVARG;
+
+ *ret_options = data->window->config.options;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_SetColor( IDirectFBWindow *thiz,
+ u8 r,
+ u8 g,
+ u8 b,
+ u8 a )
+{
+ DFBColor color = { a: a, r: r, g: g, b: b };
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!(data->window->caps & DWCAPS_COLOR))
+ return DFB_UNSUPPORTED;
+
+ dfb_window_set_color( data->window, color );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_SetColorKey( IDirectFBWindow *thiz,
+ u8 r,
+ u8 g,
+ u8 b )
+{
+ u32 key;
+ CoreSurface *surface;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (data->window->caps & DWCAPS_INPUTONLY)
+ return DFB_UNSUPPORTED;
+
+ surface = data->window->surface;
+
+ if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ key = dfb_palette_search( surface->palette, r, g, b, 0x80 );
+ else
+ key = dfb_color_to_pixel( surface->config.format, r, g, b );
+
+ return dfb_window_set_colorkey( data->window, key );
+}
+
+static DFBResult
+IDirectFBWindow_SetColorKeyIndex( IDirectFBWindow *thiz,
+ unsigned int index )
+{
+ u32 key = index;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (data->window->caps & DWCAPS_INPUTONLY)
+ return DFB_UNSUPPORTED;
+
+ return dfb_window_set_colorkey( data->window, key );
+}
+
+static DFBResult
+IDirectFBWindow_SetOpaqueRegion( IDirectFBWindow *thiz,
+ int x1,
+ int y1,
+ int x2,
+ int y2 )
+{
+ DFBRegion region;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (x1 > x2 || y1 > y2)
+ return DFB_INVAREA;
+
+ region = (DFBRegion) { x1, y1, x2, y2 };
+
+ return dfb_window_set_opaque( data->window, &region );
+}
+
+static DFBResult
+IDirectFBWindow_SetOpacity( IDirectFBWindow *thiz,
+ u8 opacity )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_set_opacity( data->window, opacity );
+}
+
+static DFBResult
+IDirectFBWindow_GetOpacity( IDirectFBWindow *thiz,
+ u8 *opacity )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!opacity)
+ return DFB_INVARG;
+
+ *opacity = data->window->config.opacity;
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_SetCursorShape( IDirectFBWindow *thiz,
+ IDirectFBSurface *shape,
+ int hot_x,
+ int hot_y )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (shape) {
+ IDirectFBSurface_data *shape_data;
+ CoreSurface *shape_surface;
+
+ shape_data = (IDirectFBSurface_data*) shape->priv;
+ if (!shape_data)
+ return DFB_DEAD;
+
+ shape_surface = shape_data->surface;
+ if (!shape_surface)
+ return DFB_DESTROYED;
+
+ return dfb_window_set_cursor_shape( data->window, shape_surface, hot_x, hot_y );
+ }
+
+ return dfb_window_set_cursor_shape( data->window, NULL, 0, 0 );
+}
+
+static DFBResult
+IDirectFBWindow_RequestFocus( IDirectFBWindow *thiz )
+{
+ CoreWindow *window;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ window = data->window;
+
+ if (window->config.options & DWOP_GHOST)
+ return DFB_UNSUPPORTED;
+
+ if (!window->config.opacity && !(window->caps & DWCAPS_INPUTONLY))
+ return DFB_UNSUPPORTED;
+
+ return dfb_window_request_focus( window );
+}
+
+static DFBResult
+IDirectFBWindow_GrabKeyboard( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_change_grab( data->window, CWMGT_KEYBOARD, true );
+}
+
+static DFBResult
+IDirectFBWindow_UngrabKeyboard( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_change_grab( data->window, CWMGT_KEYBOARD, false );
+}
+
+static DFBResult
+IDirectFBWindow_GrabPointer( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_change_grab( data->window, CWMGT_POINTER, true );
+}
+
+static DFBResult
+IDirectFBWindow_UngrabPointer( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_change_grab( data->window, CWMGT_POINTER, false );
+}
+
+static DFBResult
+IDirectFBWindow_GrabKey( IDirectFBWindow *thiz,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_grab_key( data->window, symbol, modifiers );
+}
+
+static DFBResult
+IDirectFBWindow_UngrabKey( IDirectFBWindow *thiz,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_ungrab_key( data->window, symbol, modifiers );
+}
+
+static DFBResult
+IDirectFBWindow_Move( IDirectFBWindow *thiz, int dx, int dy )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (dx == 0 && dy == 0)
+ return DFB_OK;
+
+ return dfb_window_move( data->window, dx, dy, true );
+}
+
+static DFBResult
+IDirectFBWindow_MoveTo( IDirectFBWindow *thiz, int x, int y )
+{
+ DFBResult ret;
+ DFBInsets insets;
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ dfb_windowstack_lock( data->window->stack );
+
+ dfb_wm_get_insets( data->window->stack, data->window, &insets );
+ x += insets.l;
+ y += insets.t;
+
+ ret = dfb_window_move( data->window, x, y, false );
+
+ dfb_windowstack_unlock( data->window->stack );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBWindow_Resize( IDirectFBWindow *thiz,
+ int width,
+ int height )
+{
+ DFBResult ret;
+ DFBInsets insets;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (width < 1 || width > 4096 || height < 1 || height > 4096)
+ return DFB_INVARG;
+
+ dfb_windowstack_lock( data->window->stack );
+
+ dfb_wm_get_insets( data->window->stack, data->window, &insets );
+ width += insets.l+insets.r;
+ height += insets.t+insets.b;
+
+ ret = dfb_window_resize( data->window, width, height );
+
+ dfb_windowstack_unlock( data->window->stack );
+
+ return ret;
+}
+
+static DFBResult
+IDirectFBWindow_Raise( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_raise( data->window );
+}
+
+static DFBResult
+IDirectFBWindow_SetStackingClass( IDirectFBWindow *thiz,
+ DFBWindowStackingClass stacking_class )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ switch (stacking_class) {
+ case DWSC_MIDDLE:
+ case DWSC_UPPER:
+ case DWSC_LOWER:
+ break;
+ default:
+ return DFB_INVARG;
+ }
+
+ return dfb_window_change_stacking( data->window, stacking_class );
+}
+
+static DFBResult
+IDirectFBWindow_Lower( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_lower( data->window );
+}
+
+static DFBResult
+IDirectFBWindow_RaiseToTop( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_raisetotop( data->window );
+}
+
+static DFBResult
+IDirectFBWindow_LowerToBottom( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_lowertobottom( data->window );
+}
+
+static DFBResult
+IDirectFBWindow_PutAtop( IDirectFBWindow *thiz,
+ IDirectFBWindow *lower )
+{
+ IDirectFBWindow_data *lower_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!lower)
+ return DFB_INVARG;
+
+ lower_data = (IDirectFBWindow_data*) lower->priv;
+ if (!lower_data)
+ return DFB_DEAD;
+
+ if (!lower_data->window)
+ return DFB_DESTROYED;
+
+ return dfb_window_putatop( data->window, lower_data->window );
+}
+
+static DFBResult
+IDirectFBWindow_PutBelow( IDirectFBWindow *thiz,
+ IDirectFBWindow *upper )
+{
+ IDirectFBWindow_data *upper_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (!upper)
+ return DFB_INVARG;
+
+ upper_data = (IDirectFBWindow_data*) upper->priv;
+ if (!upper_data)
+ return DFB_DEAD;
+
+ if (!upper_data->window)
+ return DFB_DESTROYED;
+
+ return dfb_window_putbelow( data->window, upper_data->window );
+}
+
+static DFBResult
+IDirectFBWindow_Close( IDirectFBWindow *thiz )
+{
+ DFBWindowEvent evt;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ evt.type = DWET_CLOSE;
+
+ dfb_window_post_event( data->window, &evt );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_Destroy( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ D_DEBUG_AT( IDirectFB_Window, "IDirectFBWindow_Destroy()\n" );
+
+ dfb_window_destroy( data->window );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_SetBounds( IDirectFBWindow *thiz,
+ int x,
+ int y,
+ int width,
+ int height )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ D_DEBUG_AT( IDirectFB_Window, "IDirectFBWindow_SetBounds( %d, %d - %dx%d )\n", x, y, width, height );
+
+ return dfb_window_set_bounds( data->window, x, y, width, height );
+}
+
+static DFBResult
+IDirectFBWindow_ResizeSurface( IDirectFBWindow *thiz,
+ int width,
+ int height )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (width < 1 || width > 4096 || height < 1 || height > 4096)
+ return DFB_INVARG;
+
+ return dfb_surface_reformat( data->window->surface, width, height, data->window->surface->config.format );
+}
+
+static DFBResult
+IDirectFBWindow_SetKeySelection( IDirectFBWindow *thiz,
+ DFBWindowKeySelection selection,
+ const DFBInputDeviceKeySymbol *keys,
+ unsigned int num_keys )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ /* What a lovely switch */
+ switch (selection) {
+ case DWKS_ALL:
+ case DWKS_NONE:
+ break;
+ case DWKS_LIST:
+ if (!keys || num_keys == 0)
+ default:
+ return DFB_INVARG;
+ }
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_set_key_selection( data->window, selection, keys, num_keys );
+}
+
+static DFBResult
+IDirectFBWindow_GrabUnselectedKeys( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_change_grab( data->window, CWMGT_UNSELECTED_KEYS, true );
+}
+
+static DFBResult
+IDirectFBWindow_UngrabUnselectedKeys( IDirectFBWindow *thiz )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_change_grab( data->window, CWMGT_UNSELECTED_KEYS, false );
+}
+
+static DFBResult
+IDirectFBWindow_Bind( IDirectFBWindow *thiz,
+ IDirectFBWindow *source,
+ int x,
+ int y )
+{
+ IDirectFBWindow_data *source_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ DIRECT_INTERFACE_GET_DATA_FROM(source, source_data, IDirectFBWindow);
+
+ if (source_data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_bind( data->window, source_data->window, x, y );
+}
+
+static DFBResult
+IDirectFBWindow_Unbind( IDirectFBWindow *thiz,
+ IDirectFBWindow *source )
+{
+ IDirectFBWindow_data *source_data;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ DIRECT_INTERFACE_GET_DATA_FROM(source, source_data, IDirectFBWindow);
+
+ if (source_data->destroyed)
+ return DFB_DESTROYED;
+
+ return dfb_window_unbind( data->window, source_data->window );
+}
+
+static DFBResult
+CheckGeometry( const DFBWindowGeometry *geometry )
+{
+ if (!geometry)
+ return DFB_INVARG;
+
+ switch (geometry->mode) {
+ case DWGM_DEFAULT:
+ case DWGM_FOLLOW:
+ break;
+
+ case DWGM_RECTANGLE:
+ if (geometry->rectangle.x < 0 ||
+ geometry->rectangle.y < 0 ||
+ geometry->rectangle.w < 1 ||
+ geometry->rectangle.h < 1)
+ return DFB_INVARG;
+ break;
+
+ case DWGM_LOCATION:
+ if (geometry->location.x < 0.0f ||
+ geometry->location.y < 0.0f ||
+ geometry->location.w > 1.0f ||
+ geometry->location.h > 1.0f ||
+ geometry->location.w <= 0.0f ||
+ geometry->location.h <= 0.0f ||
+ geometry->location.x + geometry->location.w > 1.0f ||
+ geometry->location.y + geometry->location.h > 1.0f)
+ return DFB_INVARG;
+ break;
+
+ default:
+ return DFB_INVARG;
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_SetSrcGeometry( IDirectFBWindow *thiz,
+ const DFBWindowGeometry *geometry )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ ret = CheckGeometry( geometry );
+ if (ret)
+ return ret;
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ config.src_geometry = *geometry;
+
+ return dfb_window_set_config( data->window, &config, CWCF_SRC_GEOMETRY );
+}
+
+static DFBResult
+IDirectFBWindow_SetDstGeometry( IDirectFBWindow *thiz,
+ const DFBWindowGeometry *geometry )
+{
+ DFBResult ret;
+ CoreWindowConfig config;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ ret = CheckGeometry( geometry );
+ if (ret)
+ return ret;
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ config.dst_geometry = *geometry;
+
+ return dfb_window_set_config( data->window, &config, CWCF_DST_GEOMETRY );
+}
+
+static DFBResult
+IDirectFBWindow_SetRotation(IDirectFBWindow *thiz,
+ int rotation)
+{
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ return dfb_window_set_rotation( data->window, rotation % 360 );
+}
+
+static DFBResult
+IDirectFBWindow_SetAssociation( IDirectFBWindow *thiz,
+ DFBWindowID window_id )
+{
+ CoreWindowConfig config;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ config.association = window_id;
+
+ return dfb_window_set_config( data->window, &config, CWCF_ASSOCIATION );
+}
+
+static DFBResult
+IDirectFBWindow_BeginUpdates( IDirectFBWindow *thiz,
+ const DFBRegion *update )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ dfb_windowstack_lock( data->window->stack );
+
+ dfb_wm_begin_updates( data->window, update );
+
+ dfb_windowstack_unlock( data->window->stack );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_SendEvent( IDirectFBWindow *thiz,
+ const DFBWindowEvent *event )
+{
+ DFBWindowEvent evt;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s\n", __FUNCTION__ );
+
+ if (!event)
+ return DFB_INVARG;
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ evt = *event;
+
+ dfb_window_post_event( data->window, &evt );
+
+ return DFB_OK;
+}
+
+static DFBResult
+IDirectFBWindow_SetCursorFlags( IDirectFBWindow *thiz,
+ DFBWindowCursorFlags flags )
+{
+ CoreWindowConfig config;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s( 0x%04x )\n", __FUNCTION__, flags );
+
+ if (flags & ~DWCF_ALL)
+ return DFB_INVARG;
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ config.cursor_flags = flags;
+
+ return dfb_window_set_config( data->window, &config, CWCF_CURSOR_FLAGS );
+}
+
+static DFBResult
+IDirectFBWindow_SetCursorResolution( IDirectFBWindow *thiz,
+ const DFBDimension *resolution )
+{
+ CoreWindowConfig config;
+
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ if (resolution)
+ D_DEBUG_AT( IDirectFB_Window, "%s( %dx%d )\n", __FUNCTION__, resolution->w, resolution->h );
+ else
+ D_DEBUG_AT( IDirectFB_Window, "%s( NULL )\n", __FUNCTION__ );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ if (resolution)
+ config.cursor_resolution = *resolution;
+ else {
+ config.cursor_resolution.w = 0;
+ config.cursor_resolution.h = 0;
+ }
+
+ return dfb_window_set_config( data->window, &config, CWCF_CURSOR_RESOLUTION );
+}
+
+static DFBResult
+IDirectFBWindow_SetCursorPosition( IDirectFBWindow *thiz,
+ int x,
+ int y )
+{
+ DIRECT_INTERFACE_GET_DATA(IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "%s( %d,%d )\n", __FUNCTION__, x, y );
+
+ if (data->destroyed)
+ return DFB_DESTROYED;
+
+ dfb_windowstack_lock( data->window->stack );
+
+ dfb_wm_set_cursor_position( data->window, x, y );
+
+ dfb_windowstack_unlock( data->window->stack );
+
+ return DFB_OK;
+}
+
+DFBResult
+IDirectFBWindow_Construct( IDirectFBWindow *thiz,
+ CoreWindow *window,
+ CoreLayer *layer,
+ CoreDFB *core )
+{
+ DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBWindow)
+
+ D_DEBUG_AT( IDirectFB_Window, "IDirectFBWindow_Construct() <- %d, %d - %dx%d\n",
+ DFB_RECTANGLE_VALS( &window->config.bounds ) );
+
+ data->ref = 1;
+ data->window = window;
+ data->layer = layer;
+ data->core = core;
+
+ dfb_window_attach( window, IDirectFBWindow_React, data, &data->reaction );
+
+ thiz->AddRef = IDirectFBWindow_AddRef;
+ thiz->Release = IDirectFBWindow_Release;
+ thiz->CreateEventBuffer = IDirectFBWindow_CreateEventBuffer;
+ thiz->AttachEventBuffer = IDirectFBWindow_AttachEventBuffer;
+ thiz->DetachEventBuffer = IDirectFBWindow_DetachEventBuffer;
+ thiz->EnableEvents = IDirectFBWindow_EnableEvents;
+ thiz->DisableEvents = IDirectFBWindow_DisableEvents;
+ thiz->GetID = IDirectFBWindow_GetID;
+ thiz->GetPosition = IDirectFBWindow_GetPosition;
+ thiz->GetSize = IDirectFBWindow_GetSize;
+ thiz->GetSurface = IDirectFBWindow_GetSurface;
+ thiz->SetProperty = IDirectFBWindow_SetProperty;
+ thiz->GetProperty = IDirectFBWindow_GetProperty;
+ thiz->RemoveProperty = IDirectFBWindow_RemoveProperty;
+ thiz->SetOptions = IDirectFBWindow_SetOptions;
+ thiz->GetOptions = IDirectFBWindow_GetOptions;
+ thiz->SetColor = IDirectFBWindow_SetColor;
+ thiz->SetColorKey = IDirectFBWindow_SetColorKey;
+ thiz->SetColorKeyIndex = IDirectFBWindow_SetColorKeyIndex;
+ thiz->SetOpaqueRegion = IDirectFBWindow_SetOpaqueRegion;
+ thiz->SetOpacity = IDirectFBWindow_SetOpacity;
+ thiz->GetOpacity = IDirectFBWindow_GetOpacity;
+ thiz->SetCursorShape = IDirectFBWindow_SetCursorShape;
+ thiz->RequestFocus = IDirectFBWindow_RequestFocus;
+ thiz->GrabKeyboard = IDirectFBWindow_GrabKeyboard;
+ thiz->UngrabKeyboard = IDirectFBWindow_UngrabKeyboard;
+ thiz->GrabPointer = IDirectFBWindow_GrabPointer;
+ thiz->UngrabPointer = IDirectFBWindow_UngrabPointer;
+ thiz->GrabKey = IDirectFBWindow_GrabKey;
+ thiz->UngrabKey = IDirectFBWindow_UngrabKey;
+ thiz->Move = IDirectFBWindow_Move;
+ thiz->MoveTo = IDirectFBWindow_MoveTo;
+ thiz->Resize = IDirectFBWindow_Resize;
+ thiz->SetStackingClass = IDirectFBWindow_SetStackingClass;
+ thiz->Raise = IDirectFBWindow_Raise;
+ thiz->Lower = IDirectFBWindow_Lower;
+ thiz->RaiseToTop = IDirectFBWindow_RaiseToTop;
+ thiz->LowerToBottom = IDirectFBWindow_LowerToBottom;
+ thiz->PutAtop = IDirectFBWindow_PutAtop;
+ thiz->PutBelow = IDirectFBWindow_PutBelow;
+ thiz->Close = IDirectFBWindow_Close;
+ thiz->Destroy = IDirectFBWindow_Destroy;
+ thiz->SetBounds = IDirectFBWindow_SetBounds;
+ thiz->ResizeSurface = IDirectFBWindow_ResizeSurface;
+ thiz->Bind = IDirectFBWindow_Bind;
+ thiz->Unbind = IDirectFBWindow_Unbind;
+ thiz->SetKeySelection = IDirectFBWindow_SetKeySelection;
+ thiz->GrabUnselectedKeys = IDirectFBWindow_GrabUnselectedKeys;
+ thiz->UngrabUnselectedKeys = IDirectFBWindow_UngrabUnselectedKeys;
+ thiz->SetSrcGeometry = IDirectFBWindow_SetSrcGeometry;
+ thiz->SetDstGeometry = IDirectFBWindow_SetDstGeometry;
+ thiz->SetRotation = IDirectFBWindow_SetRotation;
+ thiz->SetAssociation = IDirectFBWindow_SetAssociation;
+ thiz->BeginUpdates = IDirectFBWindow_BeginUpdates;
+ thiz->SendEvent = IDirectFBWindow_SendEvent;
+ thiz->SetCursorFlags = IDirectFBWindow_SetCursorFlags;
+ thiz->SetCursorResolution = IDirectFBWindow_SetCursorResolution;
+ thiz->SetCursorPosition = IDirectFBWindow_SetCursorPosition;
+
+ return DFB_OK;
+}
+
+
+/* internals */
+
+static ReactionResult
+IDirectFBWindow_React( const void *msg_data,
+ void *ctx )
+{
+ const DFBWindowEvent *evt = msg_data;
+ IDirectFBWindow_data *data = ctx;
+
+ D_DEBUG_AT( IDirectFB_Window, "%s()\n", __FUNCTION__ );
+
+ switch (evt->type) {
+ case DWET_DESTROYED:
+ D_DEBUG_AT( IDirectFB_Window, " -> window destroyed\n" );
+
+ data->detached = true;
+ data->destroyed = true;
+
+ return RS_REMOVE;
+
+ case DWET_GOTFOCUS:
+ case DWET_LOSTFOCUS:
+ IDirectFB_SetAppFocus( idirectfb_singleton,
+ evt->type == DWET_GOTFOCUS );
+
+ default:
+ break;
+ }
+
+ return RS_OK;
+}
+
diff --git a/Source/DirectFB/src/windows/idirectfbwindow.h b/Source/DirectFB/src/windows/idirectfbwindow.h
new file mode 100755
index 0000000..29c9e6a
--- /dev/null
+++ b/Source/DirectFB/src/windows/idirectfbwindow.h
@@ -0,0 +1,44 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __IDIRECTFBWINDOW_H__
+#define __IDIRECTFBWINDOW_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+/*
+ * initializes a new window and constructs interface
+ */
+DFBResult IDirectFBWindow_Construct( IDirectFBWindow *thiz,
+ CoreWindow *window,
+ CoreLayer *layer,
+ CoreDFB *core );
+
+#endif