summaryrefslogtreecommitdiff
path: root/Source/DirectFB/systems/x11
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/systems/x11')
-rwxr-xr-xSource/DirectFB/systems/x11/Makefile.am63
-rwxr-xr-xSource/DirectFB/systems/x11/Makefile.in624
-rwxr-xr-xSource/DirectFB/systems/x11/README11
-rwxr-xr-xSource/DirectFB/systems/x11/glx_surface_pool.c838
-rwxr-xr-xSource/DirectFB/systems/x11/glx_surface_pool.h79
-rwxr-xr-xSource/DirectFB/systems/x11/primary.c664
-rwxr-xr-xSource/DirectFB/systems/x11/primary.h39
-rwxr-xr-xSource/DirectFB/systems/x11/surfacemanager.c559
-rwxr-xr-xSource/DirectFB/systems/x11/surfacemanager.h110
-rwxr-xr-xSource/DirectFB/systems/x11/vpsmem_surface_pool.c421
-rwxr-xr-xSource/DirectFB/systems/x11/vpsmem_surface_pool.h37
-rwxr-xr-xSource/DirectFB/systems/x11/x11.c570
-rwxr-xr-xSource/DirectFB/systems/x11/x11.h116
-rwxr-xr-xSource/DirectFB/systems/x11/x11_surface_pool.c369
-rwxr-xr-xSource/DirectFB/systems/x11/x11_surface_pool.h47
-rwxr-xr-xSource/DirectFB/systems/x11/x11_surface_pool_bridge.c331
-rwxr-xr-xSource/DirectFB/systems/x11/x11_surface_pool_bridge.h37
-rwxr-xr-xSource/DirectFB/systems/x11/x11image.c231
-rwxr-xr-xSource/DirectFB/systems/x11/x11image.h76
-rwxr-xr-xSource/DirectFB/systems/x11/x11input.c768
-rwxr-xr-xSource/DirectFB/systems/x11/x11types.h35
-rwxr-xr-xSource/DirectFB/systems/x11/xwindow.c294
-rwxr-xr-xSource/DirectFB/systems/x11/xwindow.h77
23 files changed, 6396 insertions, 0 deletions
diff --git a/Source/DirectFB/systems/x11/Makefile.am b/Source/DirectFB/systems/x11/Makefile.am
new file mode 100755
index 0000000..23c0b88
--- /dev/null
+++ b/Source/DirectFB/systems/x11/Makefile.am
@@ -0,0 +1,63 @@
+# Makefile.am for DirectFB/systems/x11
+
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/gfxdrivers \
+ $(X11_CFLAGS)
+
+
+systemsdir = $(MODULEDIR)/systems
+
+if BUILD_STATIC
+systems_DATA = libdirectfb_x11.o
+endif
+
+systems_LTLIBRARIES = libdirectfb_x11.la
+
+libdirectfb_x11_la_LDFLAGS = \
+ $(X11_LIBS) \
+ -avoid-version \
+ -module
+
+if GFX_GLX
+libdirectfb_x11_la_LDFLAGS += -lGL
+endif
+
+libdirectfb_x11_la_SOURCES = \
+ primary.c \
+ primary.h \
+ surfacemanager.c \
+ surfacemanager.h \
+ vpsmem_surface_pool.c \
+ vpsmem_surface_pool.h \
+ x11.c \
+ x11.h \
+ x11image.c \
+ x11image.h \
+ x11input.c \
+ x11_surface_pool.c \
+ x11_surface_pool.h \
+ x11types.h \
+ xwindow.h \
+ xwindow.c
+
+if GFX_GLX
+libdirectfb_x11_la_SOURCES += \
+ glx_surface_pool.c \
+ glx_surface_pool.h \
+ x11_surface_pool_bridge.c \
+ x11_surface_pool_bridge.h
+endif
+
+libdirectfb_x11_la_LIBADD = \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+
+include $(top_srcdir)/rules/libobject.make
+
diff --git a/Source/DirectFB/systems/x11/Makefile.in b/Source/DirectFB/systems/x11/Makefile.in
new file mode 100755
index 0000000..e25aa5b
--- /dev/null
+++ b/Source/DirectFB/systems/x11/Makefile.in
@@ -0,0 +1,624 @@
+# 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@
+
+# Makefile.am for DirectFB/systems/x11
+
+
+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@
+@GFX_GLX_TRUE@am__append_1 = -lGL
+@GFX_GLX_TRUE@am__append_2 = \
+@GFX_GLX_TRUE@ glx_surface_pool.c \
+@GFX_GLX_TRUE@ glx_surface_pool.h \
+@GFX_GLX_TRUE@ x11_surface_pool_bridge.c \
+@GFX_GLX_TRUE@ x11_surface_pool_bridge.h
+
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/rules/libobject.make
+subdir = systems/x11
+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)$(systemsdir)" "$(DESTDIR)$(systemsdir)"
+systemsLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(systems_LTLIBRARIES)
+libdirectfb_x11_la_DEPENDENCIES = \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+am__libdirectfb_x11_la_SOURCES_DIST = primary.c primary.h \
+ surfacemanager.c surfacemanager.h vpsmem_surface_pool.c \
+ vpsmem_surface_pool.h x11.c x11.h x11image.c x11image.h \
+ x11input.c x11_surface_pool.c x11_surface_pool.h x11types.h \
+ xwindow.h xwindow.c glx_surface_pool.c glx_surface_pool.h \
+ x11_surface_pool_bridge.c x11_surface_pool_bridge.h
+@GFX_GLX_TRUE@am__objects_1 = glx_surface_pool.lo \
+@GFX_GLX_TRUE@ x11_surface_pool_bridge.lo
+am_libdirectfb_x11_la_OBJECTS = primary.lo surfacemanager.lo \
+ vpsmem_surface_pool.lo x11.lo x11image.lo x11input.lo \
+ x11_surface_pool.lo xwindow.lo $(am__objects_1)
+libdirectfb_x11_la_OBJECTS = $(am_libdirectfb_x11_la_OBJECTS)
+libdirectfb_x11_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libdirectfb_x11_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_x11_la_SOURCES)
+DIST_SOURCES = $(am__libdirectfb_x11_la_SOURCES_DIST)
+systemsDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(systems_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/gfxdrivers \
+ $(X11_CFLAGS)
+
+systemsdir = $(MODULEDIR)/systems
+@BUILD_STATIC_TRUE@systems_DATA = libdirectfb_x11.o
+systems_LTLIBRARIES = libdirectfb_x11.la
+libdirectfb_x11_la_LDFLAGS = $(X11_LIBS) -avoid-version -module \
+ $(am__append_1)
+libdirectfb_x11_la_SOURCES = primary.c primary.h surfacemanager.c \
+ surfacemanager.h vpsmem_surface_pool.c vpsmem_surface_pool.h \
+ x11.c x11.h x11image.c x11image.h x11input.c \
+ x11_surface_pool.c x11_surface_pool.h x11types.h xwindow.h \
+ xwindow.c $(am__append_2)
+libdirectfb_x11_la_LIBADD = \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/rules/libobject.make $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu systems/x11/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu systems/x11/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-systemsLTLIBRARIES: $(systems_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(systemsdir)" || $(MKDIR_P) "$(DESTDIR)$(systemsdir)"
+ @list='$(systems_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(systemsLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(systemsdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(systemsLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(systemsdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-systemsLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(systems_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(systemsdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(systemsdir)/$$p"; \
+ done
+
+clean-systemsLTLIBRARIES:
+ -test -z "$(systems_LTLIBRARIES)" || rm -f $(systems_LTLIBRARIES)
+ @list='$(systems_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_x11.la: $(libdirectfb_x11_la_OBJECTS) $(libdirectfb_x11_la_DEPENDENCIES)
+ $(libdirectfb_x11_la_LINK) -rpath $(systemsdir) $(libdirectfb_x11_la_OBJECTS) $(libdirectfb_x11_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glx_surface_pool.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/primary.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surfacemanager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vpsmem_surface_pool.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x11.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x11_surface_pool.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x11_surface_pool_bridge.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x11image.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x11input.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xwindow.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-systemsDATA: $(systems_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(systemsdir)" || $(MKDIR_P) "$(DESTDIR)$(systemsdir)"
+ @list='$(systems_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(systemsDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(systemsdir)/$$f'"; \
+ $(systemsDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(systemsdir)/$$f"; \
+ done
+
+uninstall-systemsDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(systems_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(systemsdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(systemsdir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(systemsdir)" "$(DESTDIR)$(systemsdir)"; 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-systemsLTLIBRARIES \
+ 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-systemsDATA install-systemsLTLIBRARIES
+
+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-systemsDATA uninstall-systemsLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-systemsLTLIBRARIES 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-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-systemsDATA install-systemsLTLIBRARIES \
+ 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-systemsDATA \
+ uninstall-systemsLTLIBRARIES
+
+%.o: .libs/%.a %.la
+ rm -f $<.tmp/*.o
+ if test -d $<.tmp; then rmdir $<.tmp; fi
+ mkdir $<.tmp
+ (cd $<.tmp && $(AR) x ../../$<)
+ $(LD) -o $@ -r $<.tmp/*.o
+ rm -f $<.tmp/*.o && rmdir $<.tmp
+
+.PHONY: $(LTLIBRARIES:%.la=.libs/%.a)
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Source/DirectFB/systems/x11/README b/Source/DirectFB/systems/x11/README
new file mode 100755
index 0000000..7258175
--- /dev/null
+++ b/Source/DirectFB/systems/x11/README
@@ -0,0 +1,11 @@
+This is an X11 system in very early stages, it is not really usable yet.
+Tested with RGB16, ARGB1555 and ARGB mode.
+
+BUGS
+- occasional segfault during startup
+- does not work with multi-application core
+
+TODO
+- support for RGB32
+- test RGB24, RGB332, and palette mode
+- code cleanup
diff --git a/Source/DirectFB/systems/x11/glx_surface_pool.c b/Source/DirectFB/systems/x11/glx_surface_pool.c
new file mode 100755
index 0000000..98b909d
--- /dev/null
+++ b/Source/DirectFB/systems/x11/glx_surface_pool.c
@@ -0,0 +1,838 @@
+/*
+ (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_util.h>
+
+#include <direct/debug.h>
+#include <direct/hash.h>
+#include <direct/mem.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/surface_pool.h>
+
+#include <GL/glx.h>
+#include <GL/glxext.h>
+
+#include "x11.h"
+
+#include "glx_surface_pool.h"
+#include "x11_surface_pool.h"
+
+D_DEBUG_DOMAIN( GLX_Surfaces, "GLX/Surfaces", "GLX Surface Pool" );
+D_DEBUG_DOMAIN( GLX_Pixmaps, "GLX/Pixmaps", "GLX Surface Pool Pixmaps" );
+
+/**********************************************************************************************************************/
+
+typedef void (*GLXBindTexImageEXTProc) ( Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list );
+typedef void (*GLXReleaseTexImageEXTProc)( Display *dpy, GLXDrawable drawable, int buffer );
+
+typedef struct {
+ int magic;
+
+ Display *display;
+
+ GLXFBConfig *configs;
+ int num_configs;
+
+ GLXFBConfig config24;
+ Visual *visual24;
+
+ GLXFBConfig config32;
+ Visual *visual32;
+
+ GLXBindTexImageEXTProc BindTexImageEXT;
+ GLXReleaseTexImageEXTProc ReleaseTexImageEXT;
+
+ DirectHash *pixmaps;
+
+ /* Every thread needs its own context! */
+ pthread_key_t context_key;
+ pthread_key_t context_key2;
+} glxPoolLocalData;
+
+typedef struct {
+} glxPoolData;
+
+/**********************************************************************************************************************/
+
+static void
+destroy_context( void *arg )
+{
+ ThreadContext *ctx = arg;
+
+ XLockDisplay( ctx->display );
+
+ glXDestroyContext( ctx->display, ctx->context );
+
+ XUnlockDisplay( ctx->display );
+
+ D_FREE( ctx );
+}
+
+/**********************************************************************************************************************/
+
+static DFBResult
+InitLocal( glxPoolLocalData *local,
+ DFBX11 *x11 )
+{
+ DFBResult ret;
+
+ int i;
+ int attribs[] = {
+ GLX_DOUBLEBUFFER,
+ False,
+
+ GLX_DRAWABLE_TYPE,
+ GLX_PIXMAP_BIT,
+
+ GLX_X_RENDERABLE,
+ True,
+
+ GLX_RED_SIZE,
+ 8,
+
+ GLX_GREEN_SIZE,
+ 8,
+
+ GLX_BLUE_SIZE,
+ 8,
+
+ GLX_ALPHA_SIZE,
+ 8,
+
+ GLX_DEPTH_SIZE,
+ 8,
+
+ GLX_X_VISUAL_TYPE,
+ GLX_TRUE_COLOR,
+
+ None
+ };
+
+
+ local->display = x11->display;
+
+ local->BindTexImageEXT = (GLXBindTexImageEXTProc) glXGetProcAddress( (unsigned char*) "glXBindTexImageEXT" );
+ if (!local->BindTexImageEXT) {
+ D_ERROR( "glXGetProcAddress( 'glXBindTexImageEXT' ) failed!\n" );
+ return DFB_UNSUPPORTED;
+ }
+
+ local->ReleaseTexImageEXT = (GLXReleaseTexImageEXTProc) glXGetProcAddress( (unsigned char*) "glXReleaseTexImageEXT" );
+ if (!local->ReleaseTexImageEXT) {
+ D_ERROR( "glXGetProcAddress( 'glXReleaseTexImageEXT' ) failed!\n" );
+ return DFB_UNSUPPORTED;
+ }
+
+
+ ret = direct_hash_create( 7, &local->pixmaps );
+ if (ret)
+ return ret;
+
+
+ XLockDisplay( local->display );
+
+
+ local->configs = glXChooseFBConfig( local->display, DefaultScreen(local->display), attribs, &local->num_configs );
+
+ D_DEBUG_AT( GLX_Surfaces, " -> found %d configs\n", local->num_configs );
+
+ for (i=0; i<local->num_configs; i++) {
+ int depth;
+ XVisualInfo *info = glXGetVisualFromFBConfig( local->display, local->configs[i] );
+
+ glXGetFBConfigAttrib( local->display, local->configs[i], GLX_DEPTH_SIZE, &depth );
+
+ D_DEBUG_AT( GLX_Surfaces, " [%2d] ID 0x%02lx, depth %d, RGB 0x%06lx/0x%06lx/0x%06lx {%d}, class %d, z %d\n",
+ i, info->visualid, info->depth,
+ info->red_mask, info->green_mask, info->blue_mask,
+ info->bits_per_rgb, info->class, depth );
+
+ if (depth >= 8 && info->class == TrueColor) {
+ switch (info->depth) {
+ case 32:
+ local->config32 = local->configs[i];
+ local->visual32 = info->visual;
+ break;
+
+ case 24:
+ local->config24 = local->configs[i];
+ local->visual24 = info->visual;
+ break;
+ }
+ }
+ }
+
+ if (!local->config24 || !local->config32) {
+ D_ERROR( "GLX/Surfaces: Could not find useful visuals!\n" );
+ direct_hash_destroy( local->pixmaps );
+ XUnlockDisplay( local->display );
+ return DFB_UNSUPPORTED;
+ }
+
+ XVisualInfo *info24 = glXGetVisualFromFBConfig( local->display, local->config24 );
+ XVisualInfo *info32 = glXGetVisualFromFBConfig( local->display, local->config32 );
+
+ D_INFO( "GLX/Surfaces: Using visual 0x%02lx (24bit) and 0x%02lx (32bit)\n", info24->visualid, info32->visualid );
+
+ XUnlockDisplay( local->display );
+
+
+ pthread_key_create( &local->context_key, destroy_context );
+ pthread_key_create( &local->context_key2, destroy_context );
+
+ D_MAGIC_SET( local, glxPoolLocalData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+GetLocalPixmap( glxPoolLocalData *local,
+ glxAllocationData *alloc,
+ CoreSurfaceAllocation *allocation,
+ LocalPixmap **ret_pixmap )
+{
+ LocalPixmap *pixmap;
+ CoreSurface *surface;
+ CoreSurfaceBuffer *buffer;
+
+ surface = allocation->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ buffer = allocation->buffer;
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ pixmap = direct_hash_lookup( local->pixmaps, alloc->pixmap );
+ if (!pixmap) {
+ pixmap = D_CALLOC( 1, sizeof(LocalPixmap) );
+ if (!pixmap)
+ return D_OOM();
+
+ pixmap->pixmap = alloc->pixmap;
+ pixmap->config = (alloc->depth == 24) ? local->config24 : local->config32;
+
+ /*
+ * Create a GLXPixmap
+ */
+ int attribs[] = {
+ GLX_TEXTURE_FORMAT_EXT, (alloc->depth == 24) ? GLX_TEXTURE_FORMAT_RGB_EXT : GLX_TEXTURE_FORMAT_RGBA_EXT,
+ GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_RECTANGLE_EXT,
+ None
+ };
+
+
+ XLockDisplay( local->display );
+
+ pixmap->drawable = glXCreatePixmap( local->display, pixmap->config, alloc->pixmap, attribs );
+ if (!pixmap->drawable) {
+ D_ERROR( "GLX/Surfaces: Could not create %dx%d (depth %d) GLXPixmap!\n",
+ surface->config.size.w, surface->config.size.h, alloc->depth );
+ XUnlockDisplay( local->display );
+ D_FREE( pixmap );
+ return DFB_FAILURE;
+ }
+
+ D_DEBUG_AT( GLX_Surfaces, " -> drawable 0x%lx\n", pixmap->drawable );
+
+ /*
+ * Create a GC (for writing to pixmap)
+ */
+ pixmap->gc = XCreateGC( local->display, alloc->pixmap, 0, NULL );
+
+ D_DEBUG_AT( GLX_Surfaces, " -> gc 0x%lx\n", pixmap->drawable );
+
+ XUnlockDisplay( local->display );
+
+
+ /*
+ * Create a texture object
+ */
+ glGenTextures( 1, &pixmap->buffer.texture );
+
+
+ D_DEBUG_AT( GLX_Pixmaps, " NEW GLXPixmap 0x%lx for 0x%lx [%4dx%4d] %-10s\n", pixmap->drawable, alloc->pixmap,
+ surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(buffer->format) );
+ D_DEBUG_AT( GLX_Surfaces, " -> GLXPixmap 0x%lx [%4dx%4d] %-10s (%u)\n", pixmap->drawable,
+ surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(buffer->format),
+ pixmap->buffer.texture );
+
+ D_MAGIC_SET( pixmap, LocalPixmap );
+ D_MAGIC_SET( &pixmap->buffer, GLBufferData );
+
+ direct_hash_insert( local->pixmaps, alloc->pixmap, pixmap );
+ }
+ else
+ D_MAGIC_ASSERT( pixmap, LocalPixmap );
+
+ *ret_pixmap = pixmap;
+
+ return DFB_OK;
+}
+
+static void
+ReleasePixmap( glxPoolLocalData *local,
+ LocalPixmap *pixmap )
+{
+ D_MAGIC_ASSERT( local, glxPoolLocalData );
+ D_MAGIC_ASSERT( pixmap, LocalPixmap );
+
+ if (pixmap->bound) {
+ D_DEBUG_AT( GLX_Pixmaps, " RELEASE 0x%08lx from %p\n", pixmap->drawable, pixmap->bound );
+
+ local->ReleaseTexImageEXT( local->display, pixmap->drawable, GLX_FRONT_EXT );
+
+ pixmap->bound = NULL;
+ }
+}
+
+static void
+DestroyPixmap( glxPoolLocalData *local,
+ LocalPixmap *pixmap )
+{
+ D_MAGIC_ASSERT( local, glxPoolLocalData );
+ D_MAGIC_ASSERT( pixmap, LocalPixmap );
+
+ D_DEBUG_AT( GLX_Pixmaps, " DESTROY 0x%08lx (%d)\n", pixmap->drawable, pixmap->buffer.texture );
+
+ glXWaitGL();
+
+ ReleasePixmap( local, pixmap );
+
+ glXWaitX();
+
+ glDeleteTextures( 1, &pixmap->buffer.texture );
+
+ XFreeGC( local->display, pixmap->gc );
+
+ glXDestroyPixmap( local->display, pixmap->drawable );
+
+ direct_hash_remove( local->pixmaps, pixmap->pixmap );
+
+ D_MAGIC_CLEAR( pixmap );
+ D_MAGIC_CLEAR( &pixmap->buffer );
+
+ D_FREE( pixmap );
+}
+
+/**********************************************************************************************************************/
+
+static int
+glxPoolDataSize( void )
+{
+ return sizeof(glxPoolData);
+}
+
+static int
+glxPoolLocalDataSize( void )
+{
+ return sizeof(glxPoolLocalData);
+}
+
+static int
+glxAllocationDataSize( void )
+{
+ return sizeof(glxAllocationData);
+}
+
+static DFBResult
+glxInitPool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data,
+ CoreSurfacePoolDescription *ret_desc )
+{
+ glxPoolLocalData *local = pool_local;
+ DFBX11 *x11 = system_data;
+
+ D_DEBUG_AT( GLX_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( ret_desc != NULL );
+
+ ret_desc->caps = CSPCAPS_NONE;
+ ret_desc->access[CSAID_GPU] = CSAF_READ | CSAF_WRITE;
+ ret_desc->types = CSTF_LAYER | CSTF_WINDOW | CSTF_CURSOR | CSTF_FONT | CSTF_SHARED | CSTF_EXTERNAL;
+ ret_desc->priority = CSPP_DEFAULT;
+
+ /* For showing our X11 window */
+ ret_desc->access[CSAID_LAYER0] = CSAF_READ;
+
+ /* For user contexts via DirectFBGL */
+ ret_desc->access[CSAID_ACCEL1] = CSAF_READ | CSAF_WRITE;
+
+ snprintf( ret_desc->name, DFB_SURFACE_POOL_DESC_NAME_LENGTH, "GLX Drawables" );
+
+
+ return InitLocal( local, x11 );
+}
+
+static DFBResult
+glxJoinPool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data )
+{
+ glxPoolLocalData *local = pool_local;
+ DFBX11 *x11 = system_data;
+
+ D_DEBUG_AT( GLX_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+
+ return InitLocal( local, x11 );
+}
+
+static DFBResult
+glxDestroyPool( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local )
+{
+ D_DEBUG_AT( GLX_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ return DFB_OK;
+}
+
+static DFBResult
+glxLeavePool( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local )
+{
+ D_DEBUG_AT( GLX_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ return DFB_OK;
+}
+
+static DFBResult
+glxTestConfig( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ const CoreSurfaceConfig *config )
+{
+ glxPoolLocalData *local = pool_local;
+
+ D_MAGIC_ASSERT( local, glxPoolLocalData );
+
+ if (!local->configs)
+ return DFB_UNSUPPORTED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+glxAllocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ CoreSurface *surface;
+ glxPoolLocalData *local = pool_local;
+ glxAllocationData *alloc = alloc_data;
+
+ D_DEBUG_AT( GLX_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( local, glxPoolLocalData );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ XLockDisplay( local->display );
+
+ alloc->depth = DFB_COLOR_BITS_PER_PIXEL( buffer->format ) + DFB_ALPHA_BITS_PER_PIXEL( buffer->format );
+
+ /*
+ * Create a pixmap
+ */
+ alloc->pixmap = XCreatePixmap( local->display, DefaultRootWindow( local->display ),
+ surface->config.size.w, surface->config.size.h, alloc->depth );
+ if (!alloc->pixmap) {
+ D_ERROR( "GLX/Surfaces: Could not create %dx%d (depth %d) pixmap!\n",
+ surface->config.size.w, surface->config.size.h, alloc->depth );
+
+ XUnlockDisplay( local->display );
+
+ return DFB_FAILURE;
+ }
+
+ D_DEBUG_AT( GLX_Surfaces, " -> pixmap 0x%lx\n", alloc->pixmap );
+
+ D_DEBUG_AT( GLX_Pixmaps, " NEW Pixmap 0x%lx [%4dx%4d] %-10s\n", alloc->pixmap,
+ surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(buffer->format) );
+
+ XUnlockDisplay( local->display );
+
+
+ /* Pseudo calculation */
+ dfb_surface_calc_buffer_size( surface, 8, 2, NULL, &allocation->size );
+
+ D_MAGIC_SET( alloc, glxAllocationData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+glxDeallocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ LocalPixmap *pixmap;
+ glxPoolLocalData *local = pool_local;
+ glxAllocationData *alloc = alloc_data;
+
+ D_DEBUG_AT( GLX_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( local, glxPoolLocalData );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_MAGIC_ASSERT( alloc, glxAllocationData );
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ XLockDisplay( local->display );
+
+ pixmap = direct_hash_lookup( local->pixmaps, alloc->pixmap );
+ if (pixmap)
+ DestroyPixmap( local, pixmap );
+
+ XFreePixmap( local->display, alloc->pixmap );
+
+ XUnlockDisplay( local->display );
+
+ D_MAGIC_CLEAR( alloc );
+
+ return DFB_OK;
+}
+
+static DFBResult
+glxLock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ DFBResult ret;
+ LocalPixmap *pixmap;
+ glxPoolLocalData *local = pool_local;
+ glxAllocationData *alloc = alloc_data;
+
+ D_DEBUG_AT( GLX_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( local, glxPoolLocalData );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( alloc, glxAllocationData );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ ret = GetLocalPixmap( local, alloc, allocation, &pixmap );
+ if (ret)
+ return ret;
+
+ if (lock->accessor == CSAID_GPU || lock->accessor == CSAID_ACCEL1) {
+ ThreadContext *ctx;
+
+ ctx = pthread_getspecific( (lock->accessor == CSAID_GPU) ? local->context_key : local->context_key2 );
+ if (!ctx) {
+ ctx = D_CALLOC( 1, sizeof(ThreadContext) );
+ if (!ctx)
+ return D_OOM();
+
+ ctx->display = local->display;
+
+ XLockDisplay( local->display );
+
+ ctx->context = glXCreateNewContext( local->display, pixmap->config, GLX_RGBA_TYPE, NULL, GL_TRUE );
+ if (!ctx->context) {
+ D_ERROR( "GLX: Could not create GLXContext!\n" );
+ XUnlockDisplay( local->display );
+ D_FREE( ctx );
+ return DFB_FAILURE;
+ }
+
+ XUnlockDisplay( local->display );
+
+ pthread_setspecific( (lock->accessor == CSAID_GPU) ? local->context_key : local->context_key2, ctx );
+
+ D_DEBUG_AT( GLX_Surfaces, " -> NEW CONTEXT %p\n", ctx->context );
+ }
+
+ if (lock->access & CSAF_WRITE) {
+ if (ctx->context != glXGetCurrentContext() || ctx->drawable != pixmap->drawable) {
+ D_DEBUG_AT( GLX_Surfaces, " -> MAKE CURRENT 0x%08lx <- 0x%08lx\n", pixmap->drawable, glXGetCurrentDrawable() );
+
+ if (ctx->drawable != pixmap->drawable) {
+ ctx->drawable = pixmap->drawable;
+
+ pixmap->buffer.flags |= GLBF_UPDATE_TARGET;
+ }
+
+ XLockDisplay( local->display );
+
+ glXMakeContextCurrent( local->display, pixmap->drawable, pixmap->drawable, ctx->context );
+ pixmap->current = ctx->context;
+
+ ReleasePixmap( local, pixmap );
+
+ XUnlockDisplay( local->display );
+ }
+ }
+ else {
+ if (pixmap->bound != ctx->context) {
+ D_DEBUG_AT( GLX_Surfaces, " -> BIND TEXTURE 0x%08lx (%d)\n", pixmap->drawable, pixmap->buffer.texture );
+
+ XLockDisplay( local->display );
+
+ ReleasePixmap( local, pixmap );
+
+ glEnable( GL_TEXTURE_RECTANGLE_ARB );
+ glBindTexture( GL_TEXTURE_RECTANGLE_ARB, pixmap->buffer.texture );
+
+ local->BindTexImageEXT( local->display, pixmap->drawable, GLX_FRONT_EXT, NULL );
+ pixmap->bound = ctx->context;
+
+ XUnlockDisplay( local->display );
+
+ pixmap->buffer.flags |= GLBF_UPDATE_TEXTURE;
+ }
+ }
+
+ lock->handle = &pixmap->buffer;
+ }
+ else
+ lock->handle = pixmap;
+
+ return DFB_OK;
+}
+
+static DFBResult
+glxUnlock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+#if 0
+ DFBResult ret;
+ LocalPixmap *pixmap;
+ glxPoolLocalData *local = pool_local;
+ glxAllocationData *alloc = alloc_data;
+
+ D_DEBUG_AT( GLX_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( local, glxPoolLocalData );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( alloc, glxAllocationData );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ ret = GetLocalPixmap( local, alloc, allocation, &pixmap );
+ if (ret)
+ return ret;
+
+ if (lock->accessor == CSAID_GPU) {
+ XLockDisplay( local->display );
+
+ if (lock->access & CSAF_WRITE) {
+// D_DEBUG_AT( GLX_Surfaces, " -> UNMAKE CURRENT 0x%08lx <- 0x%08lx\n", pixmap->drawable, glXGetCurrentDrawable() );
+
+// glXMakeContextCurrent( local->display, None, None, NULL );
+// pixmap->current = NULL;
+ }
+ else {
+ D_DEBUG_AT( GLX_Surfaces, " -> UNBIND TEXTURE 0x%08lx (%d)\n", pixmap->drawable, pixmap->buffer.texture );
+
+ ReleasePixmap( local, pixmap );
+ }
+
+ XUnlockDisplay( local->display );
+ }
+
+#endif
+ return DFB_OK;
+}
+
+static DFBResult
+glxRead( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ void *destination,
+ int pitch,
+ const DFBRectangle *rect )
+{
+ XImage *image;
+ XImage *sub;
+ glxPoolLocalData *local = pool_local;
+ glxAllocationData *alloc = alloc_data;
+
+ D_DEBUG_AT( GLX_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( local, glxPoolLocalData );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( alloc, glxAllocationData );
+ D_ASSERT( destination != NULL );
+ D_ASSERT( pitch >= 0 );
+ DFB_RECTANGLE_ASSERT( rect );
+
+ D_DEBUG_AT( GLX_Surfaces, " => %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->pixmap, DFB_RECTANGLE_VALS(rect) );
+
+ XLockDisplay( local->display );
+
+ image = XCreateImage( local->display, (alloc->depth == 24) ? local->visual24 : local->visual32,
+ alloc->depth, ZPixmap, 0, destination, rect->w, rect->h, 32, pitch );
+ if (!image) {
+ D_ERROR( "GLX/Surfaces: XCreateImage( %dx%d, depth %d ) failed!\n", rect->w, rect->h, alloc->depth );
+ XUnlockDisplay( local->display );
+ return DFB_FAILURE;
+ }
+
+ glXWaitGL();
+
+ sub = XGetSubImage( local->display, alloc->pixmap, rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap, image, 0, 0 );
+
+ glXWaitX();
+
+ /* FIXME: Why the X-hell is XDestroyImage() freeing *MY* data? */
+ image->data = NULL;
+ XDestroyImage( image );
+
+ XUnlockDisplay( local->display );
+
+ if (!sub) {
+ D_ERROR( "GLX/Surfaces: XGetSubImage( %d,%d-%dx%d ) failed!\n", DFB_RECTANGLE_VALS(rect) );
+ return DFB_FAILURE;
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+glxWrite( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ const void *source,
+ int pitch,
+ const DFBRectangle *rect )
+{
+ DFBResult ret;
+ LocalPixmap *pixmap;
+ CoreSurface *surface;
+ XImage *image;
+ glxPoolLocalData *local = pool_local;
+ glxAllocationData *alloc = alloc_data;
+
+ D_DEBUG_AT( GLX_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( local, glxPoolLocalData );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( alloc, glxAllocationData );
+ D_ASSERT( source != NULL );
+ D_ASSERT( pitch >= 0 );
+ DFB_RECTANGLE_ASSERT( rect );
+
+ D_DEBUG_AT( GLX_Surfaces, " <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->pixmap, DFB_RECTANGLE_VALS(rect) );
+
+ surface = allocation->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ ret = GetLocalPixmap( local, alloc, allocation, &pixmap );
+ if (ret)
+ return ret;
+
+ XLockDisplay( local->display );
+
+ image = XCreateImage( local->display, (alloc->depth == 24) ? local->visual24 : local->visual32,
+ alloc->depth, ZPixmap, 0, (void*) source, rect->w, rect->h, 32, pitch );
+ if (!image) {
+ D_ERROR( "GLX/Surfaces: XCreateImage( %dx%d, depth %d ) failed!\n", rect->w, rect->h, alloc->depth );
+ XUnlockDisplay( local->display );
+ return DFB_FAILURE;
+ }
+
+ glXWaitGL();
+
+ XPutImage( local->display, alloc->pixmap, pixmap->gc, image, 0, 0, rect->x, rect->y, rect->w, rect->h );
+
+ glXWaitX();
+
+ /* FIXME: Why the X-hell is XDestroyImage() freeing *MY* data? */
+ image->data = NULL;
+ XDestroyImage( image );
+
+ XUnlockDisplay( local->display );
+
+ return DFB_OK;
+}
+
+const SurfacePoolFuncs glxSurfacePoolFuncs = {
+ .PoolDataSize = glxPoolDataSize,
+ .PoolLocalDataSize = glxPoolLocalDataSize,
+ .AllocationDataSize = glxAllocationDataSize,
+
+ .InitPool = glxInitPool,
+ .JoinPool = glxJoinPool,
+ .DestroyPool = glxDestroyPool,
+ .LeavePool = glxLeavePool,
+
+ .TestConfig = glxTestConfig,
+
+ .AllocateBuffer = glxAllocateBuffer,
+ .DeallocateBuffer = glxDeallocateBuffer,
+
+ .Lock = glxLock,
+ .Unlock = glxUnlock,
+
+ .Read = glxRead,
+ .Write = glxWrite,
+};
+
diff --git a/Source/DirectFB/systems/x11/glx_surface_pool.h b/Source/DirectFB/systems/x11/glx_surface_pool.h
new file mode 100755
index 0000000..d244526
--- /dev/null
+++ b/Source/DirectFB/systems/x11/glx_surface_pool.h
@@ -0,0 +1,79 @@
+/*
+ (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 __X11SYSTEM__GLX_SURFACE_POOL_H__
+#define __X11SYSTEM__GLX_SURFACE_POOL_H__
+
+
+#include <GL/glx.h>
+
+#include <gl/gl_gfxdriver.h>
+
+#include <core/surface_pool.h>
+
+extern const SurfacePoolFuncs glxSurfacePoolFuncs;
+
+
+typedef struct {
+ int magic;
+
+ /* Shared resource */
+ Pixmap pixmap;
+ int depth;
+} glxAllocationData;
+
+typedef struct {
+ int magic;
+
+ GLBufferData buffer;
+
+ /* Shared resource */
+ Pixmap pixmap;
+
+ /* Process local data */
+ GC gc;
+
+ GLXFBConfig config;
+ GLXDrawable drawable;
+
+ /* Bound to a thread's context? */
+ GLXContext current;
+ GLXContext bound;
+} LocalPixmap;
+
+typedef struct {
+ Display *display;
+
+ /* Thread local data */
+ GLXContext context;
+
+ GLXDrawable drawable;
+} ThreadContext;
+
+#endif
+
diff --git a/Source/DirectFB/systems/x11/primary.c b/Source/DirectFB/systems/x11/primary.c
new file mode 100755
index 0000000..2e12d8a
--- /dev/null
+++ b/Source/DirectFB/systems/x11/primary.c
@@ -0,0 +1,664 @@
+/*
+ (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 <fusion/types.h>
+
+#include <stdio.h>
+
+#include <directfb.h>
+#include <directfb_util.h>
+
+#include <fusion/fusion.h>
+#include <fusion/shmalloc.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+#include <core/layers.h>
+#include <core/palette.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+#include <core/system.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef USE_GLX
+#include <GL/glx.h>
+#include "glx_surface_pool.h"
+#endif
+
+#include "xwindow.h"
+#include "x11.h"
+#include "primary.h"
+
+
+D_DEBUG_DOMAIN( X11_Layer, "X11/Layer", "X11 Layer" );
+D_DEBUG_DOMAIN( X11_Update, "X11/Update", "X11 Update" );
+
+/**********************************************************************************************************************/
+
+static DFBResult
+dfb_x11_create_window( DFBX11 *x11, const CoreLayerRegionConfig *config )
+{
+ int ret;
+ DFBX11Shared *shared = x11->shared;
+
+ D_ASSERT( config != NULL );
+
+ shared->setmode.config = *config;
+
+ if (fusion_call_execute( &shared->call, FCEF_NONE, X11_CREATE_WINDOW, &shared->setmode, &ret ))
+ return DFB_FUSION;
+
+ return ret;
+}
+
+static DFBResult
+dfb_x11_destroy_window( DFBX11 *x11 )
+{
+ int ret;
+ DFBX11Shared *shared = x11->shared;
+
+ if (fusion_call_execute( &shared->call, FCEF_NONE, X11_DESTROY_WINDOW, NULL, &ret ))
+ return DFB_FUSION;
+
+ return ret;
+}
+
+static DFBResult
+dfb_x11_update_screen( DFBX11 *x11, const DFBRegion *region, CoreSurfaceBufferLock *lock )
+{
+ int ret;
+ DFBX11Shared *shared = x11->shared;
+
+ DFB_REGION_ASSERT( region );
+ D_ASSERT( lock != NULL );
+
+ /* FIXME: Just a hot fix! */
+ while (shared->update.lock)
+ usleep( 10000 );
+
+ shared->update.region = *region;
+ shared->update.lock = lock;
+
+ if (fusion_call_execute( &shared->call, FCEF_NODIRECT, X11_UPDATE_SCREEN, &shared->update, &ret ))
+ return DFB_FUSION;
+
+ return ret;
+}
+
+static DFBResult
+dfb_x11_set_palette( DFBX11 *x11, CorePalette *palette )
+{
+ int ret;
+ DFBX11Shared *shared = x11->shared;
+
+ D_ASSERT( palette != NULL );
+
+ if (fusion_call_execute( &shared->call, FCEF_NONE, X11_SET_PALETTE, palette, &ret ))
+ return DFB_FUSION;
+
+ return ret;
+}
+
+/**********************************************************************************************************************/
+
+static DFBResult
+primaryInitScreen( CoreScreen *screen,
+ CoreGraphicsDevice *device,
+ void *driver_data,
+ void *screen_data,
+ DFBScreenDescription *description )
+{
+ D_DEBUG_AT( X11_Layer, "%s()\n", __FUNCTION__ );
+
+ /* Set the screen capabilities. */
+ description->caps = DSCCAPS_NONE;
+
+ /* Set the screen name. */
+ snprintf( description->name,
+ DFB_SCREEN_DESC_NAME_LENGTH, "X11 Primary Screen" );
+
+ return DFB_OK;
+}
+
+static DFBResult
+primaryGetScreenSize( CoreScreen *screen,
+ void *driver_data,
+ void *screen_data,
+ int *ret_width,
+ int *ret_height )
+{
+ DFBX11 *x11 = driver_data;
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Layer, "%s()\n", __FUNCTION__ );
+
+ *ret_width = shared->screen_size.w;
+ *ret_height = shared->screen_size.h;
+
+ return DFB_OK;
+}
+
+ScreenFuncs x11PrimaryScreenFuncs = {
+ .InitScreen = primaryInitScreen,
+ .GetScreenSize = primaryGetScreenSize,
+};
+
+/******************************************************************************/
+
+static int
+primaryLayerDataSize( void )
+{
+ return 0;
+}
+
+static int
+primaryRegionDataSize( void )
+{
+ return 0;
+}
+
+static DFBResult
+primaryInitLayer( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ DFBDisplayLayerDescription *description,
+ DFBDisplayLayerConfig *config,
+ DFBColorAdjustment *adjustment )
+{
+ DFBX11 *x11 = driver_data;
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Layer, "%s()\n", __FUNCTION__ );
+
+ /* set capabilities and type */
+ description->caps = DLCAPS_SURFACE;
+ description->type = DLTF_GRAPHICS;
+
+ /* set name */
+ snprintf( description->name,
+ DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "X11 Primary Layer" );
+
+ /* fill out the default configuration */
+ config->flags = DLCONF_WIDTH | DLCONF_HEIGHT |
+ DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
+ config->buffermode = DLBM_FRONTONLY;
+
+ if (dfb_config->mode.width)
+ config->width = dfb_config->mode.width;
+ else
+ config->width = shared->screen_size.w;
+
+ if (dfb_config->mode.height)
+ config->height = dfb_config->mode.height;
+ else
+ config->height = shared->screen_size.h;
+
+ if (dfb_config->mode.format != DSPF_UNKNOWN)
+ config->pixelformat = dfb_config->mode.format;
+ else if (dfb_config->mode.depth > 0)
+ config->pixelformat = dfb_pixelformat_for_depth( dfb_config->mode.depth );
+ else {
+ int depth = DefaultDepthOfScreen( x11->screenptr );
+
+ switch (depth) {
+ case 15:
+ config->pixelformat = DSPF_RGB555;
+ break;
+ case 16:
+ config->pixelformat = DSPF_RGB16;
+ break;
+ case 24:
+ config->pixelformat = DSPF_RGB32;
+ break;
+ case 32:
+ config->pixelformat = DSPF_ARGB;
+ break;
+ default:
+ printf(" Unsupported X11 screen depth %d \n",depth);
+ return DFB_UNSUPPORTED;
+ }
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+primaryTestRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags *failed )
+{
+ CoreLayerRegionConfigFlags fail = 0;
+
+ D_DEBUG_AT( X11_Layer, "%s()\n", __FUNCTION__ );
+
+ switch (config->buffermode) {
+ case DLBM_FRONTONLY:
+ case DLBM_BACKSYSTEM:
+ case DLBM_BACKVIDEO:
+ case DLBM_TRIPLE:
+ break;
+
+ default:
+ fail |= CLRCF_BUFFERMODE;
+ break;
+ }
+
+ switch (config->format) {
+ case DSPF_RGB16:
+ case DSPF_NV16:
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ case DSPF_RGBA4444:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_BGR555:
+ case DSPF_RGB24:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ case DSPF_AYUV:
+ break;
+
+ default:
+ fail |= CLRCF_FORMAT;
+ break;
+ }
+
+ if (config->options)
+ fail |= CLRCF_OPTIONS;
+
+ if (failed)
+ *failed = fail;
+
+ if (fail)
+ return DFB_UNSUPPORTED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+primaryAddRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config )
+{
+ return DFB_OK;
+}
+
+static DFBResult
+primarySetRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreLayerRegionConfig *config,
+ CoreLayerRegionConfigFlags updated,
+ CoreSurface *surface,
+ CorePalette *palette,
+ CoreSurfaceBufferLock *lock )
+{
+ DFBResult ret;
+ DFBX11 *x11 = driver_data;
+
+ D_DEBUG_AT( X11_Layer, "%s()\n", __FUNCTION__ );
+
+ ret = dfb_x11_create_window( x11, config );
+ if (ret)
+ return ret;
+
+ if (palette)
+ dfb_x11_set_palette( x11, palette );
+
+ return DFB_OK;
+}
+
+static DFBResult
+primaryRemoveRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data )
+{
+ DFBX11 *x11 = driver_data;
+
+ D_DEBUG_AT( X11_Layer, "%s()\n", __FUNCTION__ );
+
+ dfb_x11_destroy_window( x11 );
+
+ return DFB_OK;
+}
+
+static DFBResult
+primaryFlipRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ DFBSurfaceFlipFlags flags,
+ CoreSurfaceBufferLock *lock )
+{
+ DFBX11 *x11 = driver_data;
+ DFBRegion region = DFB_REGION_INIT_FROM_DIMENSION( &surface->config.size );
+
+ D_DEBUG_AT( X11_Layer, "%s()\n", __FUNCTION__ );
+
+ dfb_surface_flip( surface, false );
+
+ return dfb_x11_update_screen( x11, &region, lock );
+}
+
+static DFBResult
+primaryUpdateRegion( CoreLayer *layer,
+ void *driver_data,
+ void *layer_data,
+ void *region_data,
+ CoreSurface *surface,
+ const DFBRegion *update,
+ CoreSurfaceBufferLock *lock )
+{
+ DFBX11 *x11 = driver_data;
+ DFBRegion region = DFB_REGION_INIT_FROM_DIMENSION( &surface->config.size );
+
+ D_DEBUG_AT( X11_Layer, "%s()\n", __FUNCTION__ );
+
+ if (update && !dfb_region_region_intersect( &region, update ))
+ return DFB_OK;
+
+ return dfb_x11_update_screen( x11, &region, lock );
+}
+
+DisplayLayerFuncs x11PrimaryLayerFuncs = {
+ .LayerDataSize = primaryLayerDataSize,
+ .RegionDataSize = primaryRegionDataSize,
+ .InitLayer = primaryInitLayer,
+
+ .TestRegion = primaryTestRegion,
+ .AddRegion = primaryAddRegion,
+ .SetRegion = primarySetRegion,
+ .RemoveRegion = primaryRemoveRegion,
+ .FlipRegion = primaryFlipRegion,
+ .UpdateRegion = primaryUpdateRegion,
+};
+
+/******************************************************************************/
+
+static DFBResult
+update_screen( DFBX11 *x11, const DFBRectangle *clip, CoreSurfaceBufferLock *lock )
+{
+ void *dst;
+ void *src;
+ unsigned int offset = 0;
+ XWindow *xw;
+ XImage *ximage;
+ CoreSurface *surface;
+ CoreSurfaceAllocation *allocation;
+ DFBX11Shared *shared;
+ DFBRectangle rect;
+ bool direct = false;
+
+ D_ASSERT( x11 != NULL );
+ DFB_RECTANGLE_ASSERT( clip );
+
+ D_DEBUG_AT( X11_Update, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( clip ) );
+
+ CORE_SURFACE_BUFFER_LOCK_ASSERT( lock );
+
+ shared = x11->shared;
+ D_ASSERT( shared != NULL );
+
+ XLockDisplay( x11->display );
+
+ xw = shared->xw;
+ if (!xw) {
+ XUnlockDisplay( x11->display );
+ return DFB_OK;
+ }
+
+ allocation = lock->allocation;
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ surface = allocation->surface;
+ D_ASSERT( surface != NULL );
+
+
+ rect.x = rect.y = 0;
+ rect.w = xw->width;
+ rect.h = xw->height;
+
+ if (!dfb_rectangle_intersect( &rect, clip )) {
+ XUnlockDisplay( x11->display );
+ return DFB_OK;
+ }
+
+ D_DEBUG_AT( X11_Update, " -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( &rect ) );
+
+#ifdef USE_GLX
+ /* Check for GLX allocation... */
+ if (allocation->pool == shared->glx_pool && lock->handle) {
+ LocalPixmap *pixmap = lock->handle;
+
+ D_MAGIC_ASSERT( pixmap, LocalPixmap );
+
+ /* ...and just call SwapBuffers... */
+ //D_DEBUG_AT( X11_Update, " -> Calling glXSwapBuffers( 0x%lx )...\n", alloc->drawable );
+ //glXSwapBuffers( x11->display, alloc->drawable );
+
+
+ D_DEBUG_AT( X11_Update, " -> Copying from GLXPixmap...\n" );
+
+ glXWaitGL();
+
+ XCopyArea( x11->display, pixmap->pixmap, xw->window, xw->gc,
+ rect.x, rect.y, rect.w, rect.h, rect.x, rect.y );
+
+ glXWaitX();
+
+ XUnlockDisplay( x11->display );
+
+ return DFB_OK;
+ }
+#endif
+
+ /* Check for our special native allocation... */
+ if (allocation->pool == shared->x11image_pool && lock->handle) {
+ x11Image *image = lock->handle;
+
+ D_MAGIC_ASSERT( image, x11Image );
+
+ /* ...and directly XShmPutImage from that. */
+ ximage = image->ximage;
+
+ direct = true;
+ }
+ else {
+ /* ...or copy or convert into XShmImage or XImage allocated with the XWindow. */
+ ximage = xw->ximage;
+ offset = xw->ximage_offset;
+
+ xw->ximage_offset = (offset ? 0 : ximage->height / 2);
+
+ dst = xw->virtualscreen + rect.x * xw->bpp + (rect.y + offset) * ximage->bytes_per_line;
+ src = lock->addr + DFB_BYTES_PER_LINE( surface->config.format, rect.x ) + rect.y * lock->pitch;
+
+ switch (xw->depth) {
+ case 32:
+ dfb_convert_to_argb( surface->config.format, src, lock->pitch,
+ surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
+ break;
+
+ case 24:
+ dfb_convert_to_rgb32( surface->config.format, src, lock->pitch,
+ surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
+ break;
+
+ case 16:
+ dfb_convert_to_rgb16( surface->config.format, src, lock->pitch,
+ surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
+ break;
+
+ case 15:
+ dfb_convert_to_rgb555( surface->config.format, src, lock->pitch,
+ surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
+ break;
+
+ default:
+ D_ONCE( "unsupported depth %d", xw->depth );
+ }
+ }
+
+ D_ASSERT( ximage != NULL );
+
+
+ /* Wait for previous data to be processed... */
+ XSync( x11->display, False );
+
+ /* ...and immediately queue or send the next! */
+ if (x11->use_shm) {
+ /* Just queue the command, it's XShm :) */
+ XShmPutImage( xw->display, xw->window, xw->gc, ximage,
+ rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h, False );
+
+ /* Make sure the queue has really happened! */
+ XFlush( x11->display );
+ }
+ else
+ /* Initiate transfer of buffer... */
+ XPutImage( xw->display, xw->window, xw->gc, ximage,
+ rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h );
+
+ /* Wait for display if single buffered and not converted... */
+ if (direct && !(surface->config.caps & DSCAPS_FLIPPING))
+ XSync( x11->display, False );
+
+ XUnlockDisplay( x11->display );
+
+ return DFB_OK;
+}
+
+/******************************************************************************/
+
+DFBResult
+dfb_x11_create_window_handler( DFBX11 *x11, CoreLayerRegionConfig *config )
+{
+ XWindow *xw;
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Layer, "%s( %p )\n", __FUNCTION__, config );
+
+ D_DEBUG_AT( X11_Layer, " -> %4dx%4d %s\n", config->width, config->height, dfb_pixelformat_name(config->format) );
+
+ XLockDisplay( x11->display );
+
+ xw = shared->xw;
+ if (xw != NULL) {
+ if (xw->width == config->width && xw->height == config->height) {
+ XUnlockDisplay( x11->display );
+ return DFB_OK;
+ }
+
+ shared->xw = NULL;
+ dfb_x11_close_window( x11, xw );
+ }
+
+ bool bSucces = dfb_x11_open_window( x11, &xw, 0, 0, config->width, config->height, config->format );
+
+ /* Set video mode */
+ if ( !bSucces ) {
+ D_ERROR( "DirectFB/X11: Couldn't open %dx%d window!\n", config->width, config->height );
+
+ XUnlockDisplay( x11->display );
+ return DFB_FAILURE;
+ }
+ else
+ shared->xw = xw;
+
+ XUnlockDisplay( x11->display );
+ return DFB_OK;
+}
+
+DFBResult
+dfb_x11_destroy_window_handler( DFBX11 *x11 )
+{
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Layer, "%s()\n", __FUNCTION__ );
+
+ XLockDisplay( x11->display );
+
+ if (shared->xw) {
+ XWindow *xw = shared->xw;
+
+ shared->xw = NULL;
+
+ dfb_x11_close_window( x11, xw );
+ }
+
+ XSync( x11->display, False );
+
+ XUnlockDisplay( x11->display );
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_x11_update_screen_handler( DFBX11 *x11, UpdateScreenData *data )
+{
+ DFBRectangle rect;
+
+ D_DEBUG_AT( X11_Update, "%s( %p )\n", __FUNCTION__, data );
+
+ rect = DFB_RECTANGLE_INIT_FROM_REGION( &data->region );
+
+ if (data->lock)
+ update_screen( x11, &rect, data->lock );
+
+ data->lock = NULL;
+
+ return DFB_OK;
+}
+
+DFBResult
+dfb_x11_set_palette_handler( DFBX11 *x11, CorePalette *palette )
+{
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/systems/x11/primary.h b/Source/DirectFB/systems/x11/primary.h
new file mode 100755
index 0000000..a145d83
--- /dev/null
+++ b/Source/DirectFB/systems/x11/primary.h
@@ -0,0 +1,39 @@
+/*
+ (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 __X11__PRIMARY_H__
+#define __X11__PRIMARY_H__
+
+#include <core/layers.h>
+#include <core/screens.h>
+
+extern ScreenFuncs x11PrimaryScreenFuncs;
+extern DisplayLayerFuncs x11PrimaryLayerFuncs;
+
+#endif // __X11__PRIMARY_H__
+
diff --git a/Source/DirectFB/systems/x11/surfacemanager.c b/Source/DirectFB/systems/x11/surfacemanager.c
new file mode 100755
index 0000000..e9f697a
--- /dev/null
+++ b/Source/DirectFB/systems/x11/surfacemanager.c
@@ -0,0 +1,559 @@
+/*
+ (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/shmalloc.h>
+
+#include <directfb.h>
+#include <directfb_util.h>
+
+#include <core/core.h>
+
+#include <core/gfxcard.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+
+#include "surfacemanager.h"
+
+D_DEBUG_DOMAIN( SurfMan, "SurfaceManager", "DirectFB Surface Manager" );
+
+
+static Chunk *split_chunk ( SurfaceManager *manager,
+ Chunk *chunk,
+ int length );
+
+static Chunk *free_chunk ( SurfaceManager *manager,
+ Chunk *chunk );
+
+static Chunk *occupy_chunk( SurfaceManager *manager,
+ Chunk *chunk,
+ CoreSurfaceAllocation *allocation,
+ int length,
+ int pitch );
+
+
+DFBResult
+dfb_surfacemanager_create( CoreDFB *core,
+ unsigned int length,
+ SurfaceManager **ret_manager )
+{
+ FusionSHMPoolShared *pool;
+ SurfaceManager *manager;
+ Chunk *chunk;
+
+ D_DEBUG_AT( SurfMan, "%s( %p, %d )\n", __FUNCTION__, core, length );
+
+ D_ASSERT( core != NULL );
+ D_ASSERT( ret_manager != NULL );
+
+ pool = dfb_core_shmpool( core );
+
+ manager = SHCALLOC( pool, 1, sizeof(SurfaceManager) );
+ if (!manager)
+ return D_OOSHM();
+
+ chunk = SHCALLOC( pool, 1, sizeof(Chunk) );
+ if (!chunk) {
+ D_OOSHM();
+ SHFREE( pool, manager );
+ return DFB_NOSHAREDMEMORY;
+ }
+
+ manager->shmpool = pool;
+ manager->chunks = chunk;
+ manager->offset = 0;
+ manager->length = length;
+ manager->avail = manager->length - manager->offset;
+
+ D_MAGIC_SET( manager, SurfaceManager );
+
+ chunk->offset = manager->offset;
+ chunk->length = manager->avail;
+
+ D_MAGIC_SET( chunk, Chunk );
+
+ D_DEBUG_AT( SurfMan, " -> %p\n", manager );
+
+ *ret_manager = manager;
+
+ return DFB_OK;
+}
+
+void
+dfb_surfacemanager_destroy( SurfaceManager *manager )
+{
+ Chunk *chunk;
+ void *next;
+
+ D_DEBUG_AT( SurfMan, "%s( %p )\n", __FUNCTION__, manager );
+
+ D_MAGIC_ASSERT( manager, SurfaceManager );
+
+ /* Deallocate all video chunks. */
+ chunk = manager->chunks;
+ while (chunk) {
+ next = chunk->next;
+
+ D_MAGIC_CLEAR( chunk );
+
+ SHFREE( manager->shmpool, chunk );
+
+ chunk = next;
+ }
+
+ D_MAGIC_CLEAR( manager );
+
+ /* Deallocate manager struct. */
+ SHFREE( manager->shmpool, manager );
+}
+
+/** public functions NOT locking the surfacemanger theirself,
+ to be called between lock/unlock of surfacemanager **/
+
+DFBResult dfb_surfacemanager_allocate( CoreDFB *core,
+ SurfaceManager *manager,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ Chunk **ret_chunk )
+{
+ int pitch;
+ int length;
+ Chunk *c;
+ CoreGraphicsDevice *device;
+
+ Chunk *best_free = NULL;
+
+ D_MAGIC_ASSERT( manager, SurfaceManager );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_MAGIC_ASSERT( buffer->surface, CoreSurface );
+
+ if (ret_chunk)
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ else
+ D_ASSUME( allocation == NULL );
+
+ D_DEBUG_AT( SurfMan, "%s( %p ) <- %dx%d %s\n", __FUNCTION__, buffer,
+ buffer->surface->config.size.w, buffer->surface->config.size.h,
+ dfb_pixelformat_name( buffer->surface->config.format ) );
+
+ if (manager->suspended)
+ return DFB_SUSPENDED;
+
+ /* FIXME: Only one global device at the moment. */
+ device = dfb_core_get_part( core, DFCP_GRAPHICS );
+ D_ASSERT( device != NULL );
+
+ dfb_gfxcard_calc_buffer_size( device, buffer, &pitch, &length );
+
+ D_DEBUG_AT( SurfMan, " -> pitch %d, length %d\n", pitch, length );
+
+ if (manager->avail < length)
+ return DFB_TEMPUNAVAIL;
+
+ /* examine chunks */
+ c = manager->chunks;
+ D_MAGIC_ASSERT( c, Chunk );
+
+ while (c) {
+ D_MAGIC_ASSERT( c, Chunk );
+
+ if (!c->buffer && c->length >= length) {
+ /* NULL means check only. */
+ if (!ret_chunk)
+ return DFB_OK;
+
+ /* found a nice place to chill */
+ if (!best_free || best_free->length > c->length)
+ /* first found or better one? */
+ best_free = c;
+
+ if (c->length == length)
+ break;
+ }
+
+ c = c->next;
+ }
+
+ /* if we found a place */
+ if (best_free) {
+ D_DEBUG_AT( SurfMan, " -> found free (%d)\n", best_free->length );
+
+ /* NULL means check only. */
+ if (ret_chunk)
+ *ret_chunk = occupy_chunk( manager, best_free, allocation, length, pitch );
+
+ return DFB_OK;
+ }
+
+ D_DEBUG_AT( SurfMan, " -> failed (%d/%d avail)\n", manager->avail, manager->length );
+
+ /* no luck */
+ return DFB_NOVIDEOMEMORY;
+}
+
+DFBResult dfb_surfacemanager_displace( CoreDFB *core,
+ SurfaceManager *manager,
+ CoreSurfaceBuffer *buffer )
+{
+ int length;
+ Chunk *multi_start = NULL;
+ int multi_size = 0;
+ int multi_tsize = 0;
+ int multi_count = 0;
+ Chunk *bestm_start = NULL;
+ int bestm_count = 0;
+ int bestm_size = 0;
+ int min_toleration;
+ Chunk *chunk;
+ CoreGraphicsDevice *device;
+ CoreSurfaceAllocation *smallest = NULL;
+
+ D_MAGIC_ASSERT( manager, SurfaceManager );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_MAGIC_ASSERT( buffer->surface, CoreSurface );
+
+ D_DEBUG_AT( SurfMan, "%s( %p ) <- %dx%d %s\n", __FUNCTION__, buffer,
+ buffer->surface->config.size.w, buffer->surface->config.size.h,
+ dfb_pixelformat_name( buffer->surface->config.format ) );
+
+ /* FIXME: Only one global device at the moment. */
+ device = dfb_core_get_part( core, DFCP_GRAPHICS );
+ D_ASSERT( device != NULL );
+
+ dfb_gfxcard_calc_buffer_size( dfb_core_get_part( core, DFCP_GRAPHICS ), buffer, NULL, &length );
+
+ min_toleration = manager->min_toleration/8 + 2;
+
+ D_DEBUG_AT( SurfMan, " -> %7d required, min toleration %d\n", length, min_toleration );
+
+ chunk = manager->chunks;
+ while (chunk) {
+ CoreSurfaceAllocation *allocation;
+
+ D_MAGIC_ASSERT( chunk, Chunk );
+
+ allocation = chunk->allocation;
+ if (allocation) {
+ CoreSurfaceBuffer *other;
+ int size;
+
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_ASSERT( chunk->buffer == allocation->buffer );
+ D_ASSERT( chunk->length >= allocation->size );
+
+ other = allocation->buffer;
+ D_MAGIC_ASSERT( other, CoreSurfaceBuffer );
+
+ if (other->locked) {
+ D_DEBUG_AT( SurfMan, " ++ %7d locked %dx\n", allocation->size, other->locked );
+ goto next_reset;
+ }
+
+ if (other->policy > buffer->policy) {
+ D_DEBUG_AT( SurfMan, " ++ %7d policy %d > %d\n", allocation->size, other->policy, buffer->policy );
+ goto next_reset;
+ }
+
+ if (other->policy == CSP_VIDEOONLY) {
+ D_DEBUG_AT( SurfMan, " ++ %7d policy videoonly\n", allocation->size );
+ goto next_reset;
+ }
+
+ chunk->tolerations++;
+ if (chunk->tolerations > 0xff)
+ chunk->tolerations = 0xff;
+
+ if (other->policy == buffer->policy && chunk->tolerations < min_toleration) {
+ D_DEBUG_AT( SurfMan, " ++ %7d tolerations %d/%d\n",
+ allocation->size, chunk->tolerations, min_toleration );
+ goto next_reset;
+ }
+
+ size = allocation->size;
+
+ if (chunk->prev && !chunk->prev->allocation)
+ size += chunk->prev->length;
+
+ if (chunk->next && !chunk->next->allocation)
+ size += chunk->next->length;
+
+ if (size >= length) {
+ if (!smallest || smallest->size > allocation->size) {
+ D_DEBUG_AT( SurfMan, " => %7d [%d] < %d, tolerations %d\n",
+ allocation->size, size, smallest ? smallest->size : 0, chunk->tolerations );
+
+ smallest = allocation;
+ }
+ else
+ D_DEBUG_AT( SurfMan, " -> %7d [%d] > %d\n", allocation->size, size, smallest->size );
+ }
+ else
+ D_DEBUG_AT( SurfMan, " -> %7d [%d]\n", allocation->size, size );
+ }
+ else
+ D_DEBUG_AT( SurfMan, " - %7d free\n", chunk->length );
+
+
+ if (!smallest) {
+ if (!multi_start) {
+ multi_start = chunk;
+ multi_tsize = chunk->length;
+ multi_size = chunk->allocation ? chunk->length : 0;
+ multi_count = chunk->allocation ? 1 : 0;
+ }
+ else {
+ multi_tsize += chunk->length;
+ multi_size += chunk->allocation ? chunk->length : 0;
+ multi_count += chunk->allocation ? 1 : 0;
+
+ while (multi_tsize >= length && multi_count > 1) {
+ if (!bestm_start || bestm_size > multi_size * multi_count / bestm_count) {
+ D_DEBUG_AT( SurfMan, " =====> %7d, %7d %2d used [%7d %2d]\n",
+ multi_tsize, multi_size, multi_count, bestm_size, bestm_count );
+
+ bestm_size = multi_size;
+ bestm_start = multi_start;
+ bestm_count = multi_count;
+ }
+ else
+ D_DEBUG_AT( SurfMan, " -----> %7d, %7d %2d used\n",
+ multi_tsize, multi_size, multi_count );
+
+ if (multi_count <= 2)
+ break;
+
+ if (!multi_start->allocation) {
+ multi_tsize -= multi_start->length;
+ multi_start = multi_start->next;
+ }
+
+ D_ASSUME( multi_start->allocation != NULL );
+
+ multi_tsize -= multi_start->length;
+ multi_size -= multi_start->allocation ? multi_start->length : 0;
+ multi_count -= multi_start->allocation ? 1 : 0;
+ multi_start = multi_start->next;
+ }
+ }
+ }
+
+ chunk = chunk->next;
+
+ continue;
+
+
+next_reset:
+ multi_start = NULL;
+
+ chunk = chunk->next;
+ }
+
+ if (smallest) {
+ D_MAGIC_ASSERT( smallest, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( smallest->buffer, CoreSurfaceBuffer );
+
+ smallest->flags |= CSALF_MUCKOUT;
+
+ D_DEBUG_AT( SurfMan, " -> offset %lu, size %d\n", smallest->offset, smallest->size );
+
+ return DFB_OK;
+ }
+
+ if (bestm_start) {
+ chunk = bestm_start;
+
+ while (bestm_count) {
+ CoreSurfaceAllocation *allocation = chunk->allocation;
+
+ if (allocation) {
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( allocation->buffer, CoreSurfaceBuffer );
+
+ allocation->flags |= CSALF_MUCKOUT;
+
+ bestm_count--;
+ }
+
+ D_DEBUG_AT( SurfMan, " ---> offset %d, length %d\n", chunk->offset, chunk->length );
+
+ chunk = chunk->next;
+ }
+
+ return DFB_OK;
+ }
+
+ return DFB_NOVIDEOMEMORY;
+}
+
+DFBResult dfb_surfacemanager_deallocate( SurfaceManager *manager,
+ Chunk *chunk )
+{
+ CoreSurfaceBuffer *buffer;
+
+ D_MAGIC_ASSERT( manager, SurfaceManager );
+ D_MAGIC_ASSERT( chunk, Chunk );
+
+ buffer = chunk->buffer;
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_MAGIC_ASSERT( buffer->surface, CoreSurface );
+
+ D_DEBUG_AT( SurfMan, "%s( %p ) <- %dx%d %s\n", __FUNCTION__, buffer,
+ buffer->surface->config.size.w, buffer->surface->config.size.h,
+ dfb_pixelformat_name( buffer->surface->config.format ) );
+
+ free_chunk( manager, chunk );
+
+ return DFB_OK;
+}
+
+/** internal functions NOT locking the surfacemanager **/
+
+static Chunk *
+split_chunk( SurfaceManager *manager, Chunk *c, int length )
+{
+ Chunk *newchunk;
+
+ D_MAGIC_ASSERT( c, Chunk );
+
+ if (c->length == length) /* does not need be splitted */
+ return c;
+
+ newchunk = (Chunk*) SHCALLOC( manager->shmpool, 1, sizeof(Chunk) );
+ if (!newchunk) {
+ D_OOSHM();
+ return NULL;
+ }
+
+ /* calculate offsets and lengths of resulting chunks */
+ newchunk->offset = c->offset + c->length - length;
+ newchunk->length = length;
+ c->length -= newchunk->length;
+
+ /* insert newchunk after chunk c */
+ newchunk->prev = c;
+ newchunk->next = c->next;
+ if (c->next)
+ c->next->prev = newchunk;
+ c->next = newchunk;
+
+ D_MAGIC_SET( newchunk, Chunk );
+
+ return newchunk;
+}
+
+static Chunk *
+free_chunk( SurfaceManager *manager, Chunk *chunk )
+{
+ D_MAGIC_ASSERT( manager, SurfaceManager );
+ D_MAGIC_ASSERT( chunk, Chunk );
+
+ if (!chunk->buffer) {
+ D_BUG( "freeing free chunk" );
+ return chunk;
+ }
+ else {
+ D_DEBUG_AT( SurfMan, "Deallocating %d bytes at offset %d.\n", chunk->length, chunk->offset );
+ }
+
+ if (chunk->buffer->policy == CSP_VIDEOONLY)
+ manager->avail += chunk->length;
+
+ chunk->allocation = NULL;
+ chunk->buffer = NULL;
+
+ manager->min_toleration--;
+
+ if (chunk->prev && !chunk->prev->buffer) {
+ Chunk *prev = chunk->prev;
+
+ //D_DEBUG_AT( SurfMan, " -> merging with previous chunk at %d\n", prev->offset );
+
+ prev->length += chunk->length;
+
+ prev->next = chunk->next;
+ if (prev->next)
+ prev->next->prev = prev;
+
+ //D_DEBUG_AT( SurfMan, " -> freeing %p (prev %p, next %p)\n", chunk, chunk->prev, chunk->next);
+
+ D_MAGIC_CLEAR( chunk );
+
+ SHFREE( manager->shmpool, chunk );
+ chunk = prev;
+ }
+
+ if (chunk->next && !chunk->next->buffer) {
+ Chunk *next = chunk->next;
+
+ //D_DEBUG_AT( SurfMan, " -> merging with next chunk at %d\n", next->offset );
+
+ chunk->length += next->length;
+
+ chunk->next = next->next;
+ if (chunk->next)
+ chunk->next->prev = chunk;
+
+ D_MAGIC_CLEAR( next );
+
+ SHFREE( manager->shmpool, next );
+ }
+
+ return chunk;
+}
+
+static Chunk *
+occupy_chunk( SurfaceManager *manager, Chunk *chunk, CoreSurfaceAllocation *allocation, int length, int pitch )
+{
+ D_MAGIC_ASSERT( manager, SurfaceManager );
+ D_MAGIC_ASSERT( chunk, Chunk );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( allocation->buffer, CoreSurfaceBuffer );
+
+ if (allocation->buffer->policy == CSP_VIDEOONLY)
+ manager->avail -= length;
+
+ chunk = split_chunk( manager, chunk, length );
+
+ D_DEBUG_AT( SurfMan, "Allocating %d bytes at offset %d.\n", chunk->length, chunk->offset );
+
+ chunk->allocation = allocation;
+ chunk->buffer = allocation->buffer;
+ chunk->pitch = pitch;
+
+ manager->min_toleration++;
+
+ return chunk;
+}
+
diff --git a/Source/DirectFB/systems/x11/surfacemanager.h b/Source/DirectFB/systems/x11/surfacemanager.h
new file mode 100755
index 0000000..e6136c5
--- /dev/null
+++ b/Source/DirectFB/systems/x11/surfacemanager.h
@@ -0,0 +1,110 @@
+/*
+ (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 __SURFACEMANAGER_H__
+#define __SURFACEMANAGER_H__
+
+#include <directfb.h>
+
+#include <core/coretypes.h>
+
+typedef struct _SurfaceManager SurfaceManager;
+typedef struct _Chunk Chunk;
+
+/*
+ * initially there is one big free chunk,
+ * chunks are splitted into a free and an occupied chunk if memory is allocated,
+ * two chunks are merged to one free chunk if memory is deallocated
+ */
+struct _Chunk {
+ int magic;
+
+ int offset; /* offset in memory,
+ is greater or equal to the heap offset */
+ int length; /* length of this chunk in bytes */
+
+ int pitch;
+
+ CoreSurfaceBuffer *buffer; /* pointer to surface buffer occupying
+ this chunk, or NULL if chunk is free */
+ CoreSurfaceAllocation *allocation;
+
+ int tolerations; /* number of times this chunk was scanned
+ occupied, resetted in assure_video */
+
+ Chunk *prev;
+ Chunk *next;
+};
+
+struct _SurfaceManager {
+ int magic;
+
+ FusionSHMPoolShared *shmpool;
+
+ Chunk *chunks;
+
+ int offset;
+ int length; /* length of the heap in bytes */
+ int avail; /* amount of available memory in bytes */
+
+ int min_toleration;
+
+ bool suspended;
+};
+
+
+DFBResult dfb_surfacemanager_create ( CoreDFB *core,
+ unsigned int length,
+ SurfaceManager **ret_manager );
+
+void dfb_surfacemanager_destroy( SurfaceManager *manager );
+
+/*
+ * finds and allocates one for the surface or fails,
+ * after success the video health is CSH_RESTORE.
+ * NOTE: this does not notify the listeners
+ */
+DFBResult dfb_surfacemanager_allocate( CoreDFB *core,
+ SurfaceManager *manager,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ Chunk **ret_chunk );
+
+DFBResult dfb_surfacemanager_displace( CoreDFB *core,
+ SurfaceManager *manager,
+ CoreSurfaceBuffer *buffer );
+
+/*
+ * sets the video health to CSH_INVALID frees the chunk and
+ * notifies the listeners
+ */
+DFBResult dfb_surfacemanager_deallocate( SurfaceManager *manager,
+ Chunk *chunk );
+
+#endif
+
diff --git a/Source/DirectFB/systems/x11/vpsmem_surface_pool.c b/Source/DirectFB/systems/x11/vpsmem_surface_pool.c
new file mode 100755
index 0000000..0cf505d
--- /dev/null
+++ b/Source/DirectFB/systems/x11/vpsmem_surface_pool.c
@@ -0,0 +1,421 @@
+/*
+ (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/shmalloc.h>
+
+#include <core/core.h>
+#include <core/surface_pool.h>
+
+#include <gfx/convert.h>
+
+#include <misc/conf.h>
+
+#include "x11.h"
+#include "surfacemanager.h"
+
+D_DEBUG_DOMAIN( VPSMem_Surfaces, "VPSMem/Surfaces", "VPSMem Framebuffer Surface Pool" );
+D_DEBUG_DOMAIN( VPSMem_SurfLock, "VPSMem/SurfLock", "VPSMem Framebuffer Surface Pool Locks" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+ SurfaceManager *manager;
+
+ void *mem;
+ unsigned int length;
+} VPSMemPoolData;
+
+typedef struct {
+ int magic;
+
+ CoreDFB *core;
+} VPSMemPoolLocalData;
+
+typedef struct {
+ int magic;
+
+ int offset;
+ int pitch;
+ int size;
+
+ Chunk *chunk;
+} VPSMemAllocationData;
+
+/**********************************************************************************************************************/
+
+static int
+vpsmemPoolDataSize( void )
+{
+ return sizeof(VPSMemPoolData);
+}
+
+static int
+vpsmemPoolLocalDataSize( void )
+{
+ return sizeof(VPSMemPoolLocalData);
+}
+
+static int
+vpsmemAllocationDataSize( void )
+{
+ return sizeof(VPSMemAllocationData);
+}
+
+static DFBResult
+vpsmemInitPool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data,
+ CoreSurfacePoolDescription *ret_desc )
+{
+ DFBResult ret;
+ VPSMemPoolData *data = pool_data;
+ VPSMemPoolLocalData *local = pool_local;
+ DFBX11 *x11 = system_data;
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( VPSMem_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( core != NULL );
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( data != NULL );
+ D_ASSERT( local != NULL );
+ D_ASSERT( ret_desc != NULL );
+
+ data->mem = SHMALLOC( shared->data_shmpool, shared->vpsmem_length );
+ if (!data->mem) {
+ shared->vpsmem_length = 0;
+ return D_OOSHM();
+ }
+
+ data->length = shared->vpsmem_length;
+
+ ret = dfb_surfacemanager_create( core, data->length, &data->manager );
+ if (ret)
+ return ret;
+
+ ret_desc->caps = CSPCAPS_PHYSICAL | CSPCAPS_VIRTUAL;
+ ret_desc->access[CSAID_CPU] = CSAF_READ | CSAF_WRITE | CSAF_SHARED;
+ ret_desc->types = CSTF_LAYER | CSTF_WINDOW | CSTF_CURSOR | CSTF_FONT | CSTF_SHARED | CSTF_EXTERNAL;
+ ret_desc->priority = CSPP_DEFAULT;
+ ret_desc->size = data->length;
+
+ /* For testing... */
+ ret_desc->access[CSAID_ACCEL1] = CSAF_READ | CSAF_WRITE | CSAF_SHARED;
+ ret_desc->access[CSAID_ACCEL2] = CSAF_READ | CSAF_WRITE | CSAF_SHARED;
+ ret_desc->access[CSAID_ACCEL3] = CSAF_READ | CSAF_WRITE | CSAF_SHARED;
+ ret_desc->access[CSAID_ACCEL4] = CSAF_READ | CSAF_WRITE | CSAF_SHARED;
+
+ snprintf( ret_desc->name, DFB_SURFACE_POOL_DESC_NAME_LENGTH, "Virtual Physical" );
+
+ local->core = core;
+
+ D_MAGIC_SET( data, VPSMemPoolData );
+ D_MAGIC_SET( local, VPSMemPoolLocalData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+vpsmemJoinPool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data )
+{
+ VPSMemPoolData *data = pool_data;
+ VPSMemPoolLocalData *local = pool_local;
+
+ D_DEBUG_AT( VPSMem_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_ASSERT( core != NULL );
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( data, VPSMemPoolData );
+ D_ASSERT( local != NULL );
+
+ (void) data;
+
+ local->core = core;
+
+ D_MAGIC_SET( local, VPSMemPoolLocalData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+vpsmemDestroyPool( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local )
+{
+ VPSMemPoolData *data = pool_data;
+ VPSMemPoolLocalData *local = pool_local;
+
+ D_DEBUG_AT( VPSMem_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( data, VPSMemPoolData );
+ D_MAGIC_ASSERT( local, VPSMemPoolLocalData );
+
+ dfb_surfacemanager_destroy( data->manager );
+
+ D_MAGIC_CLEAR( data );
+ D_MAGIC_CLEAR( local );
+
+ return DFB_OK;
+}
+
+static DFBResult
+vpsmemLeavePool( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local )
+{
+ VPSMemPoolData *data = pool_data;
+ VPSMemPoolLocalData *local = pool_local;
+
+ D_DEBUG_AT( VPSMem_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( data, VPSMemPoolData );
+ D_MAGIC_ASSERT( local, VPSMemPoolLocalData );
+
+ (void) data;
+
+ D_MAGIC_CLEAR( local );
+
+ return DFB_OK;
+}
+
+static DFBResult
+vpsmemTestConfig( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ const CoreSurfaceConfig *config )
+{
+ DFBResult ret;
+ CoreSurface *surface;
+ VPSMemPoolData *data = pool_data;
+ VPSMemPoolLocalData *local = pool_local;
+
+ D_DEBUG_AT( VPSMem_Surfaces, "%s( %p )\n", __FUNCTION__, buffer );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( data, VPSMemPoolData );
+ D_MAGIC_ASSERT( local, VPSMemPoolLocalData );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ ret = dfb_surfacemanager_allocate( local->core, data->manager, buffer, NULL, NULL );
+
+ D_DEBUG_AT( VPSMem_Surfaces, " -> %s\n", DirectFBErrorString(ret) );
+
+ return ret;
+}
+
+static DFBResult
+vpsmemAllocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ DFBResult ret;
+ Chunk *chunk;
+ CoreSurface *surface;
+ VPSMemPoolData *data = pool_data;
+ VPSMemPoolLocalData *local = pool_local;
+ VPSMemAllocationData *alloc = alloc_data;
+
+ D_DEBUG_AT( VPSMem_Surfaces, "%s( %p )\n", __FUNCTION__, buffer );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( data, VPSMemPoolData );
+ D_MAGIC_ASSERT( local, VPSMemPoolLocalData );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ ret = dfb_surfacemanager_allocate( local->core, data->manager, buffer, allocation, &chunk );
+ if (ret)
+ return ret;
+
+ D_MAGIC_ASSERT( chunk, Chunk );
+
+ alloc->offset = chunk->offset;
+ alloc->pitch = chunk->pitch;
+ alloc->size = surface->config.size.h * alloc->pitch;
+
+ alloc->chunk = chunk;
+
+ D_DEBUG_AT( VPSMem_Surfaces, " -> offset %d, pitch %d, size %d (%d)\n",
+ alloc->offset, alloc->pitch, alloc->size, chunk->length );
+
+ D_ASSERT( chunk->length >= alloc->size );
+
+ alloc->size = chunk->length;
+
+ allocation->size = alloc->size;
+ allocation->offset = alloc->offset;
+
+ D_MAGIC_SET( alloc, VPSMemAllocationData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+vpsmemDeallocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ VPSMemPoolData *data = pool_data;
+ VPSMemAllocationData *alloc = alloc_data;
+
+ D_DEBUG_AT( VPSMem_Surfaces, "%s( %p )\n", __FUNCTION__, buffer );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( data, VPSMemPoolData );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+ D_MAGIC_ASSERT( alloc, VPSMemAllocationData );
+
+ dfb_surfacemanager_deallocate( data->manager, alloc->chunk );
+
+ D_MAGIC_CLEAR( alloc );
+
+ return DFB_OK;
+}
+
+static DFBResult
+vpsmemMuckOut( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer )
+{
+ CoreSurface *surface;
+ VPSMemPoolData *data = pool_data;
+ VPSMemPoolLocalData *local = pool_local;
+
+ D_DEBUG_AT( VPSMem_Surfaces, "%s( %p )\n", __FUNCTION__, buffer );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( data, VPSMemPoolData );
+ D_MAGIC_ASSERT( local, VPSMemPoolLocalData );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ return dfb_surfacemanager_displace( local->core, data->manager, buffer );
+}
+
+static DFBResult
+vpsmemLock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ VPSMemPoolData *data = pool_data;
+ VPSMemAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( data, VPSMemPoolData );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( alloc, VPSMemAllocationData );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ D_DEBUG_AT( VPSMem_SurfLock, "%s( %p )\n", __FUNCTION__, lock->buffer );
+
+ lock->pitch = alloc->pitch;
+ lock->offset = alloc->offset;
+ lock->addr = data->mem + alloc->offset;
+ lock->phys = dfb_config->video_phys + alloc->offset;
+
+ D_DEBUG_AT( VPSMem_SurfLock, " -> offset %lu, pitch %d, addr %p, phys 0x%08lx\n",
+ lock->offset, lock->pitch, lock->addr, lock->phys );
+
+ return DFB_OK;
+}
+
+static DFBResult
+vpsmemUnlock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ VPSMemAllocationData *alloc = alloc_data;
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( alloc, VPSMemAllocationData );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ D_DEBUG_AT( VPSMem_SurfLock, "%s( %p )\n", __FUNCTION__, lock->buffer );
+
+ (void) alloc;
+
+ return DFB_OK;
+}
+
+const SurfacePoolFuncs vpsmemSurfacePoolFuncs = {
+ .PoolDataSize = vpsmemPoolDataSize,
+ .PoolLocalDataSize = vpsmemPoolLocalDataSize,
+ .AllocationDataSize = vpsmemAllocationDataSize,
+
+ .InitPool = vpsmemInitPool,
+ .JoinPool = vpsmemJoinPool,
+ .DestroyPool = vpsmemDestroyPool,
+ .LeavePool = vpsmemLeavePool,
+
+ .TestConfig = vpsmemTestConfig,
+ .AllocateBuffer = vpsmemAllocateBuffer,
+ .DeallocateBuffer = vpsmemDeallocateBuffer,
+
+ .MuckOut = vpsmemMuckOut,
+
+ .Lock = vpsmemLock,
+ .Unlock = vpsmemUnlock,
+};
+
diff --git a/Source/DirectFB/systems/x11/vpsmem_surface_pool.h b/Source/DirectFB/systems/x11/vpsmem_surface_pool.h
new file mode 100755
index 0000000..915469b
--- /dev/null
+++ b/Source/DirectFB/systems/x11/vpsmem_surface_pool.h
@@ -0,0 +1,37 @@
+/*
+ (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 __X11SYSTEM__VPSMEM_SURFACE_POOL_H__
+#define __X11SYSTEM__VPSMEM_SURFACE_POOL_H__
+
+#include <core/surface_pool.h>
+
+extern const SurfacePoolFuncs vpsmemSurfacePoolFuncs;
+
+#endif
+
diff --git a/Source/DirectFB/systems/x11/x11.c b/Source/DirectFB/systems/x11/x11.c
new file mode 100755
index 0000000..62d329c
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11.c
@@ -0,0 +1,570 @@
+/*
+ (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/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <directfb.h>
+
+#include <fusion/arena.h>
+#include <fusion/shmalloc.h>
+#include <fusion/lock.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.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/messages.h>
+
+
+#include "primary.h"
+#include "xwindow.h"
+#include "x11.h"
+#include "x11_surface_pool.h"
+#include "x11_surface_pool_bridge.h"
+
+#ifdef USE_GLX
+#include "glx_surface_pool.h"
+#endif
+
+#include "vpsmem_surface_pool.h"
+
+#include <core/core_system.h>
+
+D_DEBUG_DOMAIN( X11_Core, "X11/Core", "Main X11 system functions" );
+
+DFB_CORE_SYSTEM( x11 )
+
+
+static VideoMode modes[] = {
+ { .xres = 320, .yres = 200 },
+ { .xres = 320, .yres = 240 },
+ { .xres = 512, .yres = 384 },
+ { .xres = 640, .yres = 480 },
+ { .xres = 768, .yres = 576 },
+
+ { .xres = 1024, .yres = 576 }, // 16:9
+ { .xres = 1024, .yres = 600 }, // Where does that mode come from? :-)
+ { .xres = 1024, .yres = 768 }, // 4:3
+
+ { .xres = 1280, .yres = 720 }, // 16:9
+ { .xres = 1280, .yres = 960 }, // 4:3
+ { .xres = 1280, .yres = 1024 }, // 5:4
+
+ { .xres = 1440, .yres = 810 }, // 16:9
+ { .xres = 1440, .yres = 1080 }, // 4:3
+
+ { .xres = 1600, .yres = 900 }, // 16:9, obviously :)
+ { .xres = 1600, .yres = 1200 }, // 4:3
+
+ { .xres = 1920, .yres = 1080 }, // 16:9
+ { .xres = 1920, .yres = 1200 }, // 16:10
+
+ { .xres = 0, .yres = 0 }
+};
+
+/**********************************************************************************************************************/
+
+static FusionCallHandlerResult call_handler( int caller,
+ int call_arg,
+ void *call_ptr,
+ void *ctx,
+ unsigned int serial,
+ int *ret_val );
+
+/**********************************************************************************************************************/
+
+static DFBResult
+InitLocal( DFBX11 *x11, DFBX11Shared *shared, CoreDFB *core )
+{
+ int i, n;
+
+ XInitThreads();
+
+ x11->shared = shared;
+ x11->core = core;
+
+ x11->display = XOpenDisplay(getenv("DISPLAY"));
+ if (!x11->display) {
+ D_ERROR("X11: Error in XOpenDisplay for '%s'\n", getenv("DISPLAY"));
+ return DFB_INIT;
+ }
+
+ x11->screenptr = DefaultScreenOfDisplay(x11->display);
+ x11->screennum = DefaultScreen(x11->display);
+
+ for (i=0; i<x11->screenptr->ndepths; i++) {
+ const Depth *depth = &x11->screenptr->depths[i];
+
+ for (n=0; n<depth->nvisuals; n++) {
+ Visual *visual = &depth->visuals[n];
+
+ D_DEBUG_AT( X11_Core, "[Visual %d] ID 0x%02lx, depth %d, RGB 0x%06lx/0x%06lx/0x%06lx, %d bpRGB, %d entr.\n",
+ n, visual->visualid, depth->depth,
+ visual->red_mask, visual->green_mask, visual->blue_mask,
+ visual->bits_per_rgb, visual->map_entries );
+
+ switch (depth->depth) {
+ case 32:
+ if (visual->red_mask == 0xff0000 &&
+ visual->green_mask == 0x00ff00 &&
+ visual->blue_mask == 0x0000ff &&
+ !x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)])
+ x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = visual;
+ break;
+
+ case 24:
+ if (visual->red_mask == 0xff0000 &&
+ visual->green_mask == 0x00ff00 &&
+ visual->blue_mask == 0x0000ff &&
+ !x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)])
+ x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = visual;
+ break;
+
+ case 16:
+ if (visual->red_mask == 0xf800 &&
+ visual->green_mask == 0x07e0 &&
+ visual->blue_mask == 0x001f &&
+ !x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)])
+ x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)] = visual;
+ break;
+
+ case 15:
+ if (visual->red_mask == 0x7c00 &&
+ visual->green_mask == 0x03e0 &&
+ visual->blue_mask == 0x001f &&
+ !x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB555)])
+ x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB555)] = visual;
+ break;
+ }
+ }
+ }
+
+ if (XShmQueryExtension( x11->display ))
+ XShmQueryVersion( x11->display, &x11->xshm_major, &x11->xshm_minor, &x11->use_shm );
+
+
+ x11->screen = dfb_screens_register( NULL, x11, &x11PrimaryScreenFuncs );
+
+ dfb_layers_register( x11->screen, x11, &x11PrimaryLayerFuncs );
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+static void
+system_get_info( CoreSystemInfo *info )
+{
+ info->type = CORE_X11;
+ info->caps = CSCAPS_ACCELERATION;
+
+ D_DEBUG_AT( X11_Core, "%s()\n", __FUNCTION__ );
+
+ snprintf( info->name, DFB_CORE_SYSTEM_INFO_NAME_LENGTH, "X11" );
+}
+
+DFBX11 *dfb_x11 = NULL;
+
+static DFBResult
+system_initialize( CoreDFB *core, void **data )
+{
+ DFBResult ret;
+ DFBX11 *x11;
+ DFBX11Shared *shared;
+
+ D_DEBUG_AT( X11_Core, "%s()\n", __FUNCTION__ );
+
+ x11 = D_CALLOC( 1, sizeof(DFBX11) );
+ if (!x11)
+ return D_OOM();
+
+ shared = SHCALLOC( dfb_core_shmpool( core ), 1, sizeof(DFBX11Shared) );
+ if (!shared) {
+ D_FREE( x11 );
+ return D_OOSHM();
+ }
+
+
+ /*
+ * Local init (master and slave)
+ */
+ ret = InitLocal( x11, shared, core );
+ if (ret) {
+ SHFREE( dfb_core_shmpool( core ), shared );
+ D_FREE( x11 );
+ return ret;
+ }
+
+
+ /*
+ * Shared init (master only)
+ */
+ shared->data_shmpool = dfb_core_shmpool_data( core );
+
+ shared->screen_size.w = x11->screenptr->width;
+ shared->screen_size.h = x11->screenptr->height;
+
+ fusion_skirmish_init( &shared->lock, "X11 System", dfb_core_world(core) );
+
+ fusion_call_init( &shared->call, call_handler, x11, dfb_core_world(core) );
+
+
+ /*
+ * Must be set before initializing the pools!
+ */
+ *data = x11;
+
+ dfb_x11 = x11;
+
+ /*
+ * Master init
+ */
+ dfb_surface_pool_initialize( core, &x11SurfacePoolFuncs, &shared->x11image_pool );
+
+#ifdef USE_GLX
+ dfb_surface_pool_initialize( core, &glxSurfacePoolFuncs, &shared->glx_pool );
+#endif
+
+ if (dfb_config->video_length) {
+ shared->vpsmem_length = dfb_config->video_length;
+
+ dfb_surface_pool_initialize( core, &vpsmemSurfacePoolFuncs, &shared->vpsmem_pool );
+ }
+
+#ifdef USE_GLX
+ dfb_surface_pool_bridge_initialize( core, &x11SurfacePoolBridgeFuncs, x11, &shared->x11_pool_bridge );
+#endif
+
+ fusion_arena_add_shared_field( dfb_core_arena( core ), "x11", shared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+system_join( CoreDFB *core, void **data )
+{
+ DFBResult ret;
+ void *ptr;
+ DFBX11 *x11;
+ DFBX11Shared *shared;
+
+ D_DEBUG_AT( X11_Core, "%s()\n", __FUNCTION__ );
+
+ x11 = D_CALLOC( 1, sizeof(DFBX11) );
+ if (!x11)
+ return D_OOM();
+
+ fusion_arena_get_shared_field( dfb_core_arena( core ), "x11", &ptr );
+ shared = ptr;
+
+
+ /*
+ * Local init (master and slave)
+ */
+ ret = InitLocal( x11, shared, core );
+ if (ret) {
+ D_FREE( x11 );
+ return ret;
+ }
+
+
+ /*
+ * Must be set before joining the pools!
+ */
+ *data = x11;
+
+
+ /*
+ * Slave init
+ */
+ if (shared->x11image_pool)
+ dfb_surface_pool_join( core, shared->x11image_pool, &x11SurfacePoolFuncs );
+
+#ifdef USE_GLX
+ if (shared->glx_pool)
+ dfb_surface_pool_join( core, shared->glx_pool, &glxSurfacePoolFuncs );
+#endif
+
+ if (shared->vpsmem_pool)
+ dfb_surface_pool_join( core, shared->vpsmem_pool, &vpsmemSurfacePoolFuncs );
+
+#ifdef USE_GLX
+ if (shared->x11_pool_bridge)
+ dfb_surface_pool_bridge_join( core, shared->x11_pool_bridge, &x11SurfacePoolBridgeFuncs, x11 );
+#endif
+
+ return DFB_OK;
+}
+
+static DFBResult
+system_shutdown( bool emergency )
+{
+ DFBX11 *x11 = dfb_system_data();
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Core, "%s()\n", __FUNCTION__ );
+
+ /*
+ * Master deinit
+ */
+ if (shared->x11_pool_bridge)
+ dfb_surface_pool_bridge_destroy( shared->x11_pool_bridge );
+
+ if (shared->vpsmem_pool)
+ dfb_surface_pool_destroy( shared->vpsmem_pool );
+
+ if (shared->glx_pool)
+ dfb_surface_pool_destroy( shared->glx_pool );
+
+ if (shared->x11image_pool)
+ dfb_surface_pool_destroy( shared->x11image_pool );
+
+
+ /*
+ * Shared deinit (master only)
+ */
+ fusion_call_destroy( &shared->call );
+
+ fusion_skirmish_prevail( &shared->lock );
+
+ if (shared->xw)
+ dfb_x11_close_window( x11, shared->xw );
+
+ fusion_skirmish_destroy( &shared->lock );
+
+
+ SHFREE( dfb_core_shmpool( x11->core ), shared );
+
+
+ /*
+ * Local deinit (master and slave)
+ */
+ if (x11->display)
+ XCloseDisplay( x11->display );
+
+ D_FREE( x11 );
+
+ return DFB_OK;
+}
+
+static DFBResult
+system_leave( bool emergency )
+{
+ DFBX11 *x11 = dfb_system_data();
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Core, "%s()\n", __FUNCTION__ );
+
+ /*
+ * Slave deinit
+ */
+ if (shared->x11_pool_bridge)
+ dfb_surface_pool_bridge_leave( shared->x11_pool_bridge );
+
+ if (shared->vpsmem_pool)
+ dfb_surface_pool_leave( shared->vpsmem_pool );
+
+ if (shared->glx_pool)
+ dfb_surface_pool_leave( shared->glx_pool );
+
+ if (shared->x11image_pool)
+ dfb_surface_pool_leave( shared->x11image_pool );
+
+
+ /*
+ * Local deinit (master and slave)
+ */
+ if (x11->display)
+ XCloseDisplay( x11->display );
+
+ D_FREE( x11 );
+
+ return DFB_OK;
+}
+
+static DFBResult
+system_suspend( void )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static DFBResult
+system_resume( void )
+{
+ return DFB_UNIMPLEMENTED;
+}
+
+static volatile void *
+system_map_mmio( unsigned int offset,
+ int length )
+{
+ return NULL;
+}
+
+static void
+system_unmap_mmio( volatile void *addr,
+ int length )
+{
+}
+
+static int
+system_get_accelerator( void )
+{
+ return dfb_config->accelerator;
+}
+
+static VideoMode *
+system_get_modes( void )
+{
+ return modes;
+}
+
+static VideoMode *
+system_get_current_mode( void )
+{
+ return &modes[0]; /* FIXME */
+}
+
+static DFBResult
+system_thread_init( void )
+{
+ return DFB_OK;
+}
+
+static bool
+system_input_filter( CoreInputDevice *device,
+ DFBInputEvent *event )
+{
+ return false;
+}
+
+static unsigned long
+system_video_memory_physical( unsigned int offset )
+{
+ return 0;
+}
+
+static void *
+system_video_memory_virtual( unsigned int offset )
+{
+ return NULL;
+}
+
+static unsigned int
+system_videoram_length( void )
+{
+ return 0;
+}
+
+static unsigned long
+system_aux_memory_physical( unsigned int offset )
+{
+ return 0;
+}
+
+static void *
+system_aux_memory_virtual( unsigned int offset )
+{
+ return NULL;
+}
+
+static unsigned int
+system_auxram_length( void )
+{
+ return 0;
+}
+
+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 FusionCallHandlerResult
+call_handler( int caller,
+ int call_arg,
+ void *call_ptr,
+ void *ctx,
+ unsigned int serial,
+ int *ret_val )
+{
+ DFBX11 *x11 = ctx;
+
+ switch (call_arg) {
+ case X11_CREATE_WINDOW:
+ *ret_val = dfb_x11_create_window_handler( x11, call_ptr );
+ break;
+
+ case X11_DESTROY_WINDOW:
+ *ret_val = dfb_x11_destroy_window_handler( x11 );
+ break;
+
+ case X11_UPDATE_SCREEN:
+ *ret_val = dfb_x11_update_screen_handler( x11, call_ptr );
+ break;
+
+ case X11_SET_PALETTE:
+ *ret_val = dfb_x11_set_palette_handler( x11, call_ptr );
+ break;
+
+ case X11_IMAGE_INIT:
+ *ret_val = dfb_x11_image_init_handler( x11, call_ptr );
+ break;
+
+ case X11_IMAGE_DESTROY:
+ *ret_val = dfb_x11_image_destroy_handler( x11, call_ptr );
+ break;
+
+ default:
+ D_BUG( "unknown call" );
+ *ret_val = DFB_BUG;
+ break;
+ }
+
+ return FCHR_RETURN;
+}
+
diff --git a/Source/DirectFB/systems/x11/x11.h b/Source/DirectFB/systems/x11/x11.h
new file mode 100755
index 0000000..4743f1a
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11.h
@@ -0,0 +1,116 @@
+/*
+ (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 __X11SYSTEM__X11_H__
+#define __X11SYSTEM__X11_H__
+
+#include <fusion/call.h>
+#include <fusion/lock.h>
+#include <core/layers.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+#include <core/surface_pool.h>
+
+#include "x11image.h"
+#include "xwindow.h"
+
+typedef struct {
+ CoreLayerRegionConfig config;
+} SetModeData;
+
+typedef struct {
+ DFBRegion region;
+
+ CoreSurfaceBufferLock *lock;
+} UpdateScreenData;
+
+
+typedef struct {
+ UpdateScreenData update;
+ SetModeData setmode;
+
+ FusionSkirmish lock;
+ FusionCall call;
+
+ FusionSHMPoolShared *data_shmpool;
+
+ CoreSurfacePool *x11image_pool;
+
+ CoreSurfacePool *glx_pool; /* only used for GL */
+
+ CoreSurfacePool *vpsmem_pool;
+ unsigned int vpsmem_length;
+
+ CoreSurfacePoolBridge *x11_pool_bridge;
+
+// CoreSurface *primary;
+ DFBDimension screen_size;
+
+ XWindow *xw;
+} DFBX11Shared;
+
+struct __DFB_X11 {
+ DFBX11Shared *shared;
+
+ CoreDFB *core;
+ CoreScreen *screen;
+
+ Bool use_shm;
+ int xshm_major;
+ int xshm_minor;
+
+ Display *display;
+ Screen *screenptr;
+ int screennum;
+
+ Visual *visuals[DFB_NUM_PIXELFORMATS];
+};
+
+typedef enum {
+ X11_CREATE_WINDOW,
+ X11_UPDATE_SCREEN,
+ X11_SET_PALETTE,
+ X11_IMAGE_INIT,
+ X11_IMAGE_DESTROY,
+ X11_DESTROY_WINDOW,
+} DFBX11Call;
+
+
+
+DFBResult dfb_x11_create_window_handler ( DFBX11 *x11, CoreLayerRegionConfig *config );
+DFBResult dfb_x11_destroy_window_handler( DFBX11 *x11 );
+
+DFBResult dfb_x11_update_screen_handler ( DFBX11 *x11, UpdateScreenData *data );
+DFBResult dfb_x11_set_palette_handler ( DFBX11 *x11, CorePalette *palette );
+
+DFBResult dfb_x11_image_init_handler ( DFBX11 *x11, x11Image *image );
+DFBResult dfb_x11_image_destroy_handler ( DFBX11 *x11, x11Image *image );
+
+
+#endif //__X11SYSTEM__X11_H__
+
diff --git a/Source/DirectFB/systems/x11/x11_surface_pool.c b/Source/DirectFB/systems/x11/x11_surface_pool.c
new file mode 100755
index 0000000..4936f2a
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11_surface_pool.c
@@ -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.
+*/
+
+//#define DIRECT_ENABLE_DEBUG
+
+#include <config.h>
+
+#include <direct/debug.h>
+#include <direct/hash.h>
+#include <direct/mem.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/surface_pool.h>
+
+#include "x11.h"
+#include "x11image.h"
+#include "x11_surface_pool.h"
+
+D_DEBUG_DOMAIN( X11_Surfaces, "X11/Surfaces", "X11 System Surface Pool" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+} x11PoolData;
+
+typedef struct {
+ pthread_mutex_t lock;
+ DirectHash *hash;
+
+ DFBX11 *x11;
+} x11PoolLocalData;
+
+/**********************************************************************************************************************/
+
+static int
+x11PoolDataSize( void )
+{
+ return sizeof(x11PoolData);
+}
+
+static int
+x11PoolLocalDataSize( void )
+{
+ return sizeof(x11PoolLocalData);
+}
+
+static int
+x11AllocationDataSize( void )
+{
+ return sizeof(x11AllocationData);
+}
+
+static DFBResult
+x11InitPool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data,
+ CoreSurfacePoolDescription *ret_desc )
+{
+ DFBResult ret;
+ x11PoolLocalData *local = pool_local;
+ DFBX11 *x11 = system_data;
+
+ D_DEBUG_AT( X11_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_ASSERT( ret_desc != NULL );
+
+ local->x11 = x11;
+
+ ret_desc->caps = CSPCAPS_VIRTUAL;
+ ret_desc->access[CSAID_CPU] = CSAF_READ | CSAF_WRITE | CSAF_SHARED;
+ ret_desc->types = CSTF_LAYER | CSTF_WINDOW | CSTF_CURSOR | CSTF_FONT | CSTF_SHARED | CSTF_EXTERNAL;
+ ret_desc->priority = CSPP_ULTIMATE;
+
+ /* For showing our X11 window */
+ ret_desc->access[CSAID_LAYER0] = CSAF_READ;
+
+ snprintf( ret_desc->name, DFB_SURFACE_POOL_DESC_NAME_LENGTH, "X11 Shm Images" );
+
+ ret = direct_hash_create( 7, &local->hash );
+ if (ret) {
+ D_DERROR( ret, "X11/Surfaces: Could not create local hash table!\n" );
+ return ret;
+ }
+
+ pthread_mutex_init( &local->lock, NULL );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11JoinPool( CoreDFB *core,
+ CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ void *system_data )
+{
+ DFBResult ret;
+ x11PoolLocalData *local = pool_local;
+ DFBX11 *x11 = system_data;
+
+ D_DEBUG_AT( X11_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ local->x11 = x11;
+
+ ret = direct_hash_create( 7, &local->hash );
+ if (ret) {
+ D_DERROR( ret, "X11/Surfaces: Could not create local hash table!\n" );
+ return ret;
+ }
+
+ pthread_mutex_init( &local->lock, NULL );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11DestroyPool( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local )
+{
+ x11PoolLocalData *local = pool_local;
+
+ D_DEBUG_AT( X11_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ pthread_mutex_destroy( &local->lock );
+
+ direct_hash_destroy( local->hash );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11LeavePool( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local )
+{
+ x11PoolLocalData *local = pool_local;
+
+ D_DEBUG_AT( X11_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+
+ pthread_mutex_destroy( &local->lock );
+
+ direct_hash_destroy( local->hash );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11TestConfig( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ const CoreSurfaceConfig *config )
+{
+ x11PoolLocalData *local = pool_local;
+ DFBX11 *x11 = local->x11;
+ DFBX11Shared *shared = x11->shared;
+
+ /* Provide a fallback only if no virtual physical pool is allocated... */
+ if (!shared->vpsmem_length)
+ return DFB_OK;
+
+ /* Pass NULL image for probing */
+ return x11ImageInit( x11, NULL, config->size.w, config->size.h, config->format );
+}
+
+static DFBResult
+x11AllocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ CoreSurface *surface;
+ x11AllocationData *alloc = alloc_data;
+ x11PoolLocalData *local = pool_local;
+ DFBX11 *x11 = local->x11;
+
+ D_DEBUG_AT( X11_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ if (x11ImageInit( x11, &alloc->image, surface->config.size.w, surface->config.size.h, surface->config.format ) == DFB_OK) {
+ alloc->real = true;
+ alloc->pitch = alloc->image.pitch;
+
+ allocation->size = surface->config.size.h * alloc->image.pitch;
+ }
+ else
+ dfb_surface_calc_buffer_size( surface, 8, 2, &alloc->pitch, &allocation->size );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11DeallocateBuffer( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data )
+{
+ x11AllocationData *alloc = alloc_data;
+ x11PoolLocalData *local = pool_local;
+ DFBX11 *x11 = local->x11;
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Surfaces, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ CORE_SURFACE_ALLOCATION_ASSERT( allocation );
+
+ if (alloc->real)
+ return x11ImageDestroy( x11, &alloc->image );
+
+ if (alloc->ptr)
+ SHFREE( shared->data_shmpool, alloc->ptr );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11Lock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ DFBResult ret;
+ x11PoolLocalData *local = pool_local;
+ x11AllocationData *alloc = alloc_data;
+ DFBX11 *x11 = local->x11;
+ DFBX11Shared *shared = x11->shared;
+ CoreSurfaceBuffer *buffer;
+ CoreSurface *surface;
+
+ D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ buffer = allocation->buffer;
+ D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );
+
+ surface = buffer->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ D_ASSERT( local->hash != NULL );
+
+ pthread_mutex_lock( &local->lock );
+
+ if (alloc->real) {
+ void *addr = direct_hash_lookup( local->hash, alloc->image.seginfo.shmid );
+
+ if (!addr) {
+ ret = x11ImageAttach( &alloc->image, &addr );
+ if (ret) {
+ D_DERROR( ret, "X11/Surfaces: x11ImageAttach() failed!\n" );
+ pthread_mutex_unlock( &local->lock );
+ return ret;
+ }
+
+ direct_hash_insert( local->hash, alloc->image.seginfo.shmid, addr );
+
+ /* FIXME: When to remove/detach? */
+ }
+
+ lock->addr = addr;
+ lock->handle = &alloc->image;
+ }
+ else {
+ if (!alloc->ptr) {
+ alloc->ptr = SHCALLOC( shared->data_shmpool, 1, allocation->size );
+ if (!alloc->ptr)
+ return D_OOSHM();
+ }
+
+ lock->addr = alloc->ptr;
+ }
+
+ lock->pitch = alloc->pitch;
+
+ pthread_mutex_unlock( &local->lock );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11Unlock( CoreSurfacePool *pool,
+ void *pool_data,
+ void *pool_local,
+ CoreSurfaceAllocation *allocation,
+ void *alloc_data,
+ CoreSurfaceBufferLock *lock )
+{
+ D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );
+
+ D_MAGIC_ASSERT( pool, CoreSurfacePool );
+ D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
+ D_MAGIC_ASSERT( lock, CoreSurfaceBufferLock );
+
+ /* FIXME: Check overhead of attach/detach per lock/unlock. */
+
+ return DFB_OK;
+}
+
+const SurfacePoolFuncs x11SurfacePoolFuncs = {
+ .PoolDataSize = x11PoolDataSize,
+ .PoolLocalDataSize = x11PoolLocalDataSize,
+ .AllocationDataSize = x11AllocationDataSize,
+
+ .InitPool = x11InitPool,
+ .JoinPool = x11JoinPool,
+ .DestroyPool = x11DestroyPool,
+ .LeavePool = x11LeavePool,
+
+ .TestConfig = x11TestConfig,
+
+ .AllocateBuffer = x11AllocateBuffer,
+ .DeallocateBuffer = x11DeallocateBuffer,
+
+ .Lock = x11Lock,
+ .Unlock = x11Unlock,
+};
+
diff --git a/Source/DirectFB/systems/x11/x11_surface_pool.h b/Source/DirectFB/systems/x11/x11_surface_pool.h
new file mode 100755
index 0000000..b660931
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11_surface_pool.h
@@ -0,0 +1,47 @@
+/*
+ (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 __X11SYSTEM__X11_SURFACE_POOL_H__
+#define __X11SYSTEM__X11_SURFACE_POOL_H__
+
+#include <core/surface_pool.h>
+
+#include "x11image.h"
+
+extern const SurfacePoolFuncs x11SurfacePoolFuncs;
+
+typedef struct {
+ bool real;
+ x11Image image;
+
+ void *ptr;
+ int pitch;
+} x11AllocationData;
+
+#endif
+
diff --git a/Source/DirectFB/systems/x11/x11_surface_pool_bridge.c b/Source/DirectFB/systems/x11/x11_surface_pool_bridge.c
new file mode 100755
index 0000000..ce2537e
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11_surface_pool_bridge.c
@@ -0,0 +1,331 @@
+/*
+ (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 <direct/debug.h>
+#include <direct/hash.h>
+#include <direct/mem.h>
+
+#include <fusion/shmalloc.h>
+
+#include <core/surface_pool_bridge.h>
+
+#include "x11.h"
+#include "x11image.h"
+#include "glx_surface_pool.h"
+#include "x11_surface_pool.h"
+
+D_DEBUG_DOMAIN( X11_Bridge, "X11/Bridge", "X11 System Surface Pool Bridge" );
+
+/**********************************************************************************************************************/
+
+typedef struct {
+} x11PoolBridgeData;
+
+typedef struct {
+ DFBX11 *x11;
+ Display *display;
+} x11PoolBridgeLocalData;
+
+typedef struct {
+} x11PoolTransferData;
+
+/**********************************************************************************************************************/
+
+static int
+x11PoolBridgeDataSize( void )
+{
+ return sizeof(x11PoolBridgeData);
+}
+
+static int
+x11PoolBridgeLocalDataSize( void )
+{
+ return sizeof(x11PoolBridgeLocalData);
+}
+
+static int
+x11PoolTransferDataSize( void )
+{
+ return sizeof(x11PoolTransferData);
+}
+
+static DFBResult
+x11InitPoolBridge( CoreDFB *core,
+ CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ void *context,
+ CoreSurfacePoolBridgeDescription *ret_desc )
+{
+ x11PoolBridgeLocalData *local = bridge_local;
+ DFBX11 *x11 = context;
+
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+ D_ASSERT( bridge_local != NULL );
+ D_ASSERT( context != NULL );
+ D_ASSERT( ret_desc != NULL );
+
+ local->x11 = x11;
+ local->display = x11->display;
+
+ ret_desc->caps = CSPBCAPS_NONE;
+
+ snprintf( ret_desc->name, DFB_SURFACE_POOL_BRIDGE_DESC_NAME_LENGTH, "X11 Pool Bridge" );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11JoinPoolBridge( CoreDFB *core,
+ CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ void *context )
+{
+ x11PoolBridgeLocalData *local = bridge_local;
+ DFBX11 *x11 = context;
+
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+ D_ASSERT( bridge_local != NULL );
+ D_ASSERT( context != NULL );
+
+ local->x11 = x11;
+ local->display = x11->display;
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11DestroyPoolBridge( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local )
+{
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11LeavePoolBridge( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local )
+{
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge );
+
+ return DFB_OK;
+}
+
+static DFBResult
+x11CheckTransfer( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ CoreSurfaceBuffer *buffer,
+ CoreSurfaceAllocation *from,
+ CoreSurfaceAllocation *to )
+{
+ x11PoolBridgeLocalData *local = bridge_local;
+ DFBX11 *x11 = local->x11;
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ if (from->pool == shared->x11image_pool && to->pool == shared->glx_pool) {
+ x11AllocationData *alloc = from->data;
+
+ if (alloc->real) {
+ /* ARGB does not work (BadMatch) */
+ if (buffer->format == DSPF_RGB32)
+ return DFB_OK;
+ }
+ }
+ else if (from->pool == shared->glx_pool && to->pool == shared->x11image_pool) {
+ x11AllocationData *alloc = to->data;
+
+ if (alloc->real) {
+ /* ARGB does not work (BadMatch) */
+ if (buffer->format == DSPF_RGB32)
+ return DFB_OK;
+ }
+ }
+
+ return DFB_UNSUPPORTED;
+}
+
+static DFBResult
+x11StartTransfer( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ CoreSurfacePoolTransfer *transfer,
+ void *transfer_data )
+{
+ DFBResult ret;
+ int i;
+ CoreSurfaceBufferLock lock;
+ LocalPixmap *pixmap;
+ x11PoolBridgeLocalData *local = bridge_local;
+ DFBX11 *x11 = local->x11;
+ DFBX11Shared *shared = x11->shared;
+ CoreSurfaceAllocation *from = transfer->from;
+ CoreSurfaceAllocation *to = transfer->to;
+
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ if (from->pool == shared->x11image_pool && to->pool == shared->glx_pool) {
+ x11AllocationData *alloc = from->data;
+
+ D_ASSERT( alloc->real );
+
+ dfb_surface_buffer_lock_init( &lock, CSAID_ANY, CSAF_WRITE );
+
+ ret = dfb_surface_pool_lock( to->pool, to, &lock );
+ if (ret) {
+ dfb_surface_buffer_lock_deinit( &lock );
+ return ret;
+ }
+
+ pixmap = lock.handle;
+ D_MAGIC_ASSERT( pixmap, LocalPixmap );
+
+
+ XLockDisplay( local->display );
+
+ for (i=0; i<transfer->num_rects; i++) {
+ const DFBRectangle *rect = &transfer->rects[i];
+
+ D_DEBUG_AT( X11_Bridge, " -> XCopyArea( %4d,%4d-%4dx%4d )\n", rect->x, rect->y, rect->w, rect->h );
+
+ XCopyArea( local->display, alloc->image.pixmap, pixmap->pixmap, pixmap->gc,
+ rect->x, rect->y, rect->w, rect->h, rect->x, rect->y );
+ }
+
+ XFlush( local->display );
+
+ XUnlockDisplay( local->display );
+
+
+ dfb_surface_pool_unlock( to->pool, to, &lock );
+
+ dfb_surface_buffer_lock_deinit( &lock );
+
+ return DFB_OK;
+ }
+
+ if (from->pool == shared->glx_pool && to->pool == shared->x11image_pool) {
+ x11AllocationData *alloc = to->data;
+
+ D_ASSERT( alloc->real );
+
+ dfb_surface_buffer_lock_init( &lock, CSAID_ANY, CSAF_READ );
+
+ ret = dfb_surface_pool_lock( from->pool, from, &lock );
+ if (ret) {
+ dfb_surface_buffer_lock_deinit( &lock );
+ return ret;
+ }
+
+ pixmap = lock.handle;
+ D_MAGIC_ASSERT( pixmap, LocalPixmap );
+
+
+ XLockDisplay( local->display );
+
+ glFinish();
+
+ for (i=0; i<transfer->num_rects; i++) {
+ const DFBRectangle *rect = &transfer->rects[i];
+
+ D_DEBUG_AT( X11_Bridge, " -> XCopyArea( %4d,%4d-%4dx%4d )\n", rect->x, rect->y, rect->w, rect->h );
+
+ XCopyArea( local->display, pixmap->pixmap, alloc->image.pixmap, alloc->image.gc,
+ rect->x, rect->y, rect->w, rect->h, rect->x, rect->y );
+ }
+
+ XFlush( local->display );
+
+ XUnlockDisplay( local->display );
+
+
+ dfb_surface_pool_unlock( from->pool, from, &lock );
+
+ dfb_surface_buffer_lock_deinit( &lock );
+
+ return DFB_OK;
+ }
+
+ return DFB_BUG;
+}
+
+static DFBResult
+x11FinishTransfer( CoreSurfacePoolBridge *bridge,
+ void *bridge_data,
+ void *bridge_local,
+ CoreSurfacePoolTransfer *transfer,
+ void *transfer_data )
+{
+ x11PoolBridgeLocalData *local = bridge_local;
+
+ D_DEBUG_AT( X11_Bridge, "%s()\n", __FUNCTION__ );
+
+ XLockDisplay( local->display );
+
+ XSync( local->display, False );
+
+ XUnlockDisplay( local->display );
+
+ return DFB_OK;
+}
+
+
+const SurfacePoolBridgeFuncs x11SurfacePoolBridgeFuncs = {
+ .PoolBridgeDataSize = x11PoolBridgeDataSize,
+ .PoolBridgeLocalDataSize = x11PoolBridgeLocalDataSize,
+ .PoolTransferDataSize = x11PoolTransferDataSize,
+
+ .InitPoolBridge = x11InitPoolBridge,
+ .JoinPoolBridge = x11JoinPoolBridge,
+ .DestroyPoolBridge = x11DestroyPoolBridge,
+ .LeavePoolBridge = x11LeavePoolBridge,
+
+ .CheckTransfer = x11CheckTransfer,
+
+ .StartTransfer = x11StartTransfer,
+ .FinishTransfer = x11FinishTransfer,
+};
+
diff --git a/Source/DirectFB/systems/x11/x11_surface_pool_bridge.h b/Source/DirectFB/systems/x11/x11_surface_pool_bridge.h
new file mode 100755
index 0000000..cebb5dc
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11_surface_pool_bridge.h
@@ -0,0 +1,37 @@
+/*
+ (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 __X11SYSTEM__X11_SURFACE_POOL_BRIDGE_H__
+#define __X11SYSTEM__X11_SURFACE_POOL_BRIDGE_H__
+
+#include <core/surface_pool_bridge.h>
+
+extern const SurfacePoolBridgeFuncs x11SurfacePoolBridgeFuncs;
+
+#endif
+
diff --git a/Source/DirectFB/systems/x11/x11image.c b/Source/DirectFB/systems/x11/x11image.c
new file mode 100755
index 0000000..acf36f0
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11image.c
@@ -0,0 +1,231 @@
+/*
+ (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 <stdlib.h>
+#include <stdio.h>
+
+#include "x11.h"
+#include "x11image.h"
+
+/**********************************************************************************************************************/
+
+DFBResult x11ImageInit( DFBX11 *x11,
+ x11Image *image,
+ int width,
+ int height,
+ DFBSurfacePixelFormat format )
+{
+ int ret;
+ Visual *visual;
+ DFBX11Shared *shared = x11->shared;
+
+ if (!x11->use_shm)
+ return DFB_UNSUPPORTED;
+
+ /* Lookup visual. */
+ visual = x11->visuals[DFB_PIXELFORMAT_INDEX(format)];
+ if (!visual)
+ return DFB_UNSUPPORTED;
+
+ /* For probing. */
+ if (!image)
+ return DFB_OK;
+
+ image->width = width;
+ image->height = height;
+ image->format = format;
+ image->depth = DFB_COLOR_BITS_PER_PIXEL( format );
+
+ D_MAGIC_SET( image, x11Image );
+
+ if (fusion_call_execute( &shared->call, FCEF_NONE, X11_IMAGE_INIT, image, &ret )) {
+ D_MAGIC_CLEAR( image );
+ return DFB_FUSION;
+ }
+
+ if (ret) {
+ D_DERROR( ret, "X11/Image: X11_IMAGE_INIT call failed!\n" );
+ D_MAGIC_CLEAR( image );
+ return ret;
+ }
+
+ return DFB_OK;
+}
+
+DFBResult
+x11ImageDestroy( DFBX11 *x11,
+ x11Image *image )
+{
+ int ret;
+ DFBX11Shared *shared = x11->shared;
+
+ D_MAGIC_ASSERT( image, x11Image );
+
+ if (fusion_call_execute( &shared->call, FCEF_NONE, X11_IMAGE_DESTROY, image, &ret ))
+ return DFB_FUSION;
+
+ if (ret) {
+ D_DERROR( ret, "X11/Image: X11_IMAGE_DESTROY call failed!\n" );
+ return ret;
+ }
+
+ D_MAGIC_CLEAR( image );
+
+ return DFB_OK;
+}
+
+DFBResult
+x11ImageAttach( x11Image *image,
+ void **ret_addr )
+{
+ void *addr;
+
+ D_MAGIC_ASSERT( image, x11Image );
+ D_ASSERT( ret_addr != NULL );
+
+ /* FIXME: We also need to DETACH! */
+
+ addr = shmat( image->seginfo.shmid, NULL, 0 );
+ if (!addr) {
+ int erno = errno;
+
+ D_PERROR( "X11/Image: shmat( %d ) failed!\n", image->seginfo.shmid );
+
+ return errno2result( erno );
+ }
+
+ *ret_addr = addr;
+
+ return DFB_OK;
+}
+
+/**********************************************************************************************************************/
+
+DFBResult
+dfb_x11_image_init_handler( DFBX11 *x11, x11Image *image )
+{
+ Visual *visual;
+ XImage *ximage;
+
+ D_MAGIC_ASSERT( image, x11Image );
+
+ if (!x11->use_shm)
+ return DFB_UNSUPPORTED;
+
+ /* Lookup visual. */
+ visual = x11->visuals[DFB_PIXELFORMAT_INDEX(image->format)];
+ if (!visual)
+ return DFB_UNSUPPORTED;
+
+ image->visual = visual;
+
+ XLockDisplay( x11->display );
+
+ ximage = XShmCreateImage( x11->display, image->visual, image->depth,
+ ZPixmap, NULL, &image->seginfo, image->width, image->height );
+ if (!ximage) {
+ D_ERROR( "X11/ShmImage: Error creating shared image (XShmCreateImage)!\n");
+ XUnlockDisplay( x11->display );
+ return DFB_FAILURE;
+ }
+
+ /* we firstly create our shared memory segment with the size we need, and
+ correct permissions for the owner, the group and the world --> 0777 */
+ image->seginfo.shmid = shmget( IPC_PRIVATE,
+ ximage->bytes_per_line * ximage->height,
+ IPC_CREAT | 0777 );
+ if (image->seginfo.shmid < 0)
+ goto error;
+
+ /* Then, we have to attach the segment to our process, and we let the
+ function search the correct memory place --> NULL. It's safest ! */
+ image->seginfo.shmaddr = shmat( image->seginfo.shmid, NULL, 0 );
+ if (!image->seginfo.shmaddr)
+ goto error_shmat;
+
+ ximage->data = image->seginfo.shmaddr;
+
+ /* We set the buffer in Read and Write mode */
+ image->seginfo.readOnly = False;
+
+ if (!XShmAttach( x11->display, &image->seginfo ))
+ goto error_xshmattach;
+
+ image->ximage = ximage;
+ image->pitch = ximage->bytes_per_line;
+
+ image->pixmap = XShmCreatePixmap( x11->display, DefaultRootWindow(x11->display), ximage->data,
+ &image->seginfo, image->width, image->height, image->depth );
+
+ image->gc = XCreateGC( x11->display, image->pixmap, 0, NULL );
+
+ XUnlockDisplay( x11->display );
+
+ return DFB_OK;
+
+
+error_xshmattach:
+ shmdt( image->seginfo.shmaddr );
+
+error_shmat:
+ shmctl( image->seginfo.shmid, IPC_RMID, NULL );
+
+error:
+ XDestroyImage( ximage );
+
+ XUnlockDisplay( x11->display );
+
+ return DFB_FAILURE;
+}
+
+DFBResult
+dfb_x11_image_destroy_handler( DFBX11 *x11, x11Image *image )
+{
+ D_MAGIC_ASSERT( image, x11Image );
+
+ XLockDisplay( x11->display );
+
+ XFreeGC( x11->display, image->gc );
+ XFreePixmap( x11->display, image->pixmap );
+
+ XShmDetach( x11->display, &image->seginfo );
+
+ XDestroyImage( image->ximage );
+
+ XUnlockDisplay( x11->display );
+
+ shmdt( image->seginfo.shmaddr );
+
+ shmctl( image->seginfo.shmid, IPC_RMID, NULL );
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/systems/x11/x11image.h b/Source/DirectFB/systems/x11/x11image.h
new file mode 100755
index 0000000..3872ef7
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11image.h
@@ -0,0 +1,76 @@
+/*
+ (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 __X11SYSTEM__X11IMAGE_H__
+#define __X11SYSTEM__X11IMAGE_H__
+
+#include <X11/Xlib.h> /* fundamentals X datas structures */
+#include <X11/Xutil.h> /* datas definitions for various functions */
+#include <X11/keysym.h> /* for a perfect use of keyboard events */
+
+#include <X11/extensions/XShm.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include "x11types.h"
+
+
+typedef struct {
+ int magic;
+
+ int width;
+ int height;
+ DFBSurfacePixelFormat format;
+
+ int depth;
+ Visual* visual;
+
+ XImage* ximage;
+ int pitch;
+
+ XShmSegmentInfo seginfo;
+
+ Pixmap pixmap;
+ GC gc;
+} x11Image;
+
+
+DFBResult x11ImageInit ( DFBX11 *x11,
+ x11Image *image,
+ int width,
+ int height,
+ DFBSurfacePixelFormat format );
+
+DFBResult x11ImageDestroy( DFBX11 *x11,
+ x11Image *image );
+
+DFBResult x11ImageAttach ( x11Image *image,
+ void **ret_addr );
+
+#endif /* __X11SYSTEM__X11IMAGE_H__ */
+
diff --git a/Source/DirectFB/systems/x11/x11input.c b/Source/DirectFB/systems/x11/x11input.c
new file mode 100755
index 0000000..0b711e0
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11input.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 <fusion/types.h>
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <directfb.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.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_internal.h>
+#include <core/system.h>
+
+#include <direct/mem.h>
+#include <direct/thread.h>
+
+#include "xwindow.h"
+
+#include "primary.h"
+#include "x11.h"
+
+#define DFB_INPUTDRIVER_HAS_SENSITIVITY
+
+#include <core/input_driver.h>
+
+D_DEBUG_DOMAIN( X11_Input, "X11/Input", "X11 Input/Key/Mouse handling" );
+
+DFB_INPUT_DRIVER( x11input )
+
+
+extern DFBX11 *dfb_x11;
+
+/*
+ * declaration of private data
+ */
+typedef struct {
+ CoreInputDevice* device;
+ DirectThread* thread;
+ DFBX11* x11;
+ bool stop;
+} X11InputData;
+
+
+static DFBInputEvent motionX = {
+ .type = DIET_UNKNOWN,
+ .axisabs = 0,
+};
+
+static DFBInputEvent motionY = {
+ .type = DIET_UNKNOWN,
+ .axisabs = 0,
+};
+
+static void
+motion_compress( int x, int y, const XEvent *xEvent )
+{
+ if (motionX.axisabs != x) {
+ motionX.type = DIET_AXISMOTION;
+ motionX.flags = DIEF_AXISABS | DIEF_TIMESTAMP;
+ motionX.axis = DIAI_X;
+ motionX.axisabs = x;
+
+ motionX.timestamp.tv_sec = xEvent->xmotion.time / 1000;
+ motionX.timestamp.tv_usec = (xEvent->xmotion.time % 1000) * 1000;
+ }
+
+ if (motionY.axisabs != y) {
+ motionY.type = DIET_AXISMOTION;
+ motionY.flags = DIEF_AXISABS | DIEF_TIMESTAMP;
+ motionY.axis = DIAI_Y;
+ motionY.axisabs = y;
+
+ motionY.timestamp.tv_sec = xEvent->xmotion.time / 1000;
+ motionY.timestamp.tv_usec = (xEvent->xmotion.time % 1000) * 1000;
+ }
+}
+
+static void
+motion_realize( X11InputData *data )
+{
+ if (motionX.type != DIET_UNKNOWN) {
+ if (motionY.type != DIET_UNKNOWN)
+ motionX.flags |= DIEF_FOLLOW;
+
+ if (dfb_x11->shared->xw) {
+ motionX.flags |= DIEF_MIN | DIEF_MAX;
+ motionX.min = 0;
+ motionX.max = dfb_x11->shared->xw->width - 1;
+ }
+
+ dfb_input_dispatch( data->device, &motionX );
+
+ motionX.type = DIET_UNKNOWN;
+ }
+
+ if (motionY.type != DIET_UNKNOWN) {
+ if (dfb_x11->shared->xw) {
+ motionY.flags |= DIEF_MIN | DIEF_MAX;
+ motionY.min = 0;
+ motionY.max = dfb_x11->shared->xw->height - 1;
+ }
+
+ dfb_input_dispatch( data->device, &motionY );
+
+ motionY.type = DIET_UNKNOWN;
+ }
+}
+
+static DFBInputDeviceKeyIdentifier
+xsymbol_to_id( KeySym xKeySymbol )
+{
+ switch (xKeySymbol) {
+ case XK_a : return DIKI_A;
+ case XK_b : return DIKI_B;
+ case XK_c : return DIKI_C;
+ case XK_d : return DIKI_D;
+ case XK_e : return DIKI_E;
+ case XK_f : return DIKI_F;
+ case XK_g : return DIKI_G;
+ case XK_h : return DIKI_H;
+ case XK_i : return DIKI_I;
+ case XK_j : return DIKI_J;
+ case XK_k : return DIKI_K;
+ case XK_l : return DIKI_L;
+ case XK_m : return DIKI_M;
+ case XK_n : return DIKI_N;
+ case XK_o : return DIKI_O;
+ case XK_p : return DIKI_P;
+ case XK_q : return DIKI_Q;
+ case XK_r : return DIKI_R;
+ case XK_s : return DIKI_S;
+ case XK_t : return DIKI_T;
+ case XK_u : return DIKI_U;
+ case XK_v : return DIKI_V;
+ case XK_w : return DIKI_W;
+ case XK_x : return DIKI_X;
+ case XK_y : return DIKI_Y;
+ case XK_z : return DIKI_Z;
+ case XK_0 : return DIKI_0;
+ case XK_1 : return DIKI_1;
+ case XK_2 : return DIKI_2;
+ case XK_3 : return DIKI_3;
+ case XK_4 : return DIKI_4;
+ case XK_5 : return DIKI_5;
+ case XK_6 : return DIKI_6;
+ case XK_7 : return DIKI_7;
+ case XK_8 : return DIKI_8;
+ case XK_9 : return DIKI_9;
+ case XK_F1 : return DIKI_F1;
+ case XK_F2 : return DIKI_F2;
+ case XK_F3 : return DIKI_F3;
+ case XK_F4 : return DIKI_F4;
+ case XK_F5 : return DIKI_F5;
+ case XK_F6 : return DIKI_F6;
+ case XK_F7 : return DIKI_F7;
+ case XK_F8 : return DIKI_F8;
+ case XK_F9 : return DIKI_F9;
+ case XK_F10 : return DIKI_F10;
+ case XK_F11 : return DIKI_F11;
+ case XK_F12 : return DIKI_F12;
+
+ case XK_Shift_L : return DIKI_SHIFT_L;
+ case XK_Shift_R : return DIKI_SHIFT_R;
+ case XK_Control_L : return DIKI_CONTROL_L;
+ case XK_Control_R : return DIKI_CONTROL_R;
+ case XK_Alt_L : return DIKI_ALT_L;
+ case XK_Alt_R : return DIKI_ALT_R;
+ case XK_Meta_L : return DIKI_META_L;
+ case XK_Meta_R : return DIKI_META_R;
+ case XK_Super_L : return DIKI_SUPER_L;
+ case XK_Super_R : return DIKI_SUPER_R;
+ case XK_Hyper_L : return DIKI_HYPER_L;
+ case XK_Hyper_R : return DIKI_HYPER_R;
+ case XK_Mode_switch : return DIKI_ALT_R;
+
+ case XK_Caps_Lock : return DIKI_CAPS_LOCK;
+ case XK_Num_Lock : return DIKI_NUM_LOCK;
+ case XK_Scroll_Lock : return DIKI_SCROLL_LOCK;
+
+ case XK_Escape : return DIKI_ESCAPE;
+ case XK_Left : return DIKI_LEFT;
+ case XK_Right : return DIKI_RIGHT;
+ case XK_Up : return DIKI_UP;
+ case XK_Down : return DIKI_DOWN;
+
+ case XK_Tab : return DIKI_TAB;
+ case XK_ISO_Left_Tab : return DIKI_TAB;
+ case XK_Return : return DIKI_ENTER;
+ case XK_space : return DIKI_SPACE;
+ case XK_BackSpace : return DIKI_BACKSPACE;
+ case XK_Insert : return DIKI_INSERT;
+ case XK_Delete : return DIKI_DELETE;
+ case XK_Home : return DIKI_HOME;
+ case XK_End : return DIKI_END;
+ case XK_Page_Up : return DIKI_PAGE_UP;
+ case XK_Page_Down : return DIKI_PAGE_DOWN;
+ case XK_Print : return DIKI_PRINT;
+ case XK_Pause : return DIKI_PAUSE;
+
+ /* The labels on these keys depend on the type of keyboard.
+ * We've choosen the names from a US keyboard layout. The
+ * comments refer to the ISO 9995 terminology.
+ */
+ case XK_quoteleft : return DIKI_QUOTE_LEFT; /* TLDE */
+ case XK_minus : return DIKI_MINUS_SIGN; /* AE11 */
+ case XK_equal : return DIKI_EQUALS_SIGN; /* AE12 */
+ case XK_bracketleft : return DIKI_BRACKET_LEFT; /* AD11 */
+ case XK_bracketright : return DIKI_BRACKET_RIGHT;/* AD12 */
+ case XK_backslash : return DIKI_BACKSLASH; /* BKSL */
+ case XK_semicolon : return DIKI_SEMICOLON; /* AC10 */
+ case XK_quoteright : return DIKI_QUOTE_RIGHT; /* AC11 */
+ case XK_comma : return DIKI_COMMA; /* AB08 */
+ case XK_period : return DIKI_PERIOD; /* AB09 */
+ case XK_slash : return DIKI_SLASH; /* AB10 */
+ case XK_less : return DIKI_LESS_SIGN; /* 103rd */
+
+ case XK_KP_Divide : return DIKI_KP_DIV;
+ case XK_KP_Multiply : return DIKI_KP_MULT;
+ case XK_KP_Subtract : return DIKI_KP_MINUS;
+ case XK_KP_Add : return DIKI_KP_PLUS;
+ case XK_KP_Enter : return DIKI_KP_ENTER;
+ case XK_KP_Space : return DIKI_KP_SPACE;
+ case XK_KP_Tab : return DIKI_KP_TAB;
+ case XK_KP_F1 : return DIKI_KP_F1;
+ case XK_KP_F2 : return DIKI_KP_F2;
+ case XK_KP_F3 : return DIKI_KP_F3;
+ case XK_KP_F4 : return DIKI_KP_F4;
+ case XK_KP_Equal : return DIKI_KP_EQUAL;
+ case XK_KP_Separator : return DIKI_KP_SEPARATOR;
+
+ case XK_KP_Delete : return DIKI_KP_DECIMAL;
+ case XK_KP_Insert : return DIKI_KP_0;
+ case XK_KP_End : return DIKI_KP_1;
+ case XK_KP_Down : return DIKI_KP_2;
+ case XK_KP_Page_Down : return DIKI_KP_3;
+ case XK_KP_Left : return DIKI_KP_4;
+ case XK_KP_Begin : return DIKI_KP_5;
+ case XK_KP_Right : return DIKI_KP_6;
+ case XK_KP_Home : return DIKI_KP_7;
+ case XK_KP_Up : return DIKI_KP_8;
+ case XK_KP_Page_Up : return DIKI_KP_9;
+
+ case XK_KP_Decimal : return DIKI_KP_DECIMAL;
+ case XK_KP_0 : return DIKI_KP_0;
+ case XK_KP_1 : return DIKI_KP_1;
+ case XK_KP_2 : return DIKI_KP_2;
+ case XK_KP_3 : return DIKI_KP_3;
+ case XK_KP_4 : return DIKI_KP_4;
+ case XK_KP_5 : return DIKI_KP_5;
+ case XK_KP_6 : return DIKI_KP_6;
+ case XK_KP_7 : return DIKI_KP_7;
+ case XK_KP_8 : return DIKI_KP_8;
+ case XK_KP_9 : return DIKI_KP_9;
+
+ case 0 : break;
+
+ default:
+ D_DEBUG_AT( X11_Input, "Unknown key symbol 0x%lx\n", xKeySymbol);
+ }
+
+ return DIKI_UNKNOWN;
+}
+
+static DFBInputDeviceKeySymbol
+xsymbol_to_symbol( KeySym xKeySymbol )
+{
+ if (xKeySymbol >= 0x20 && xKeySymbol <= 0xff)
+ return xKeySymbol;
+
+ if (xKeySymbol >= XK_F1 && xKeySymbol <= XK_F35)
+ return DFB_FUNCTION_KEY( xKeySymbol - XK_F1 + 1 );
+
+ switch (xKeySymbol) {
+ case XK_Shift_L : return DIKS_SHIFT;
+ case XK_Shift_R : return DIKS_SHIFT;
+ case XK_Control_L : return DIKS_CONTROL;
+ case XK_Control_R : return DIKS_CONTROL;
+ case XK_Alt_L : return DIKS_ALT;
+ case XK_Alt_R : return DIKS_ALT;
+ case XK_Meta_L : return DIKS_META;
+ case XK_Meta_R : return DIKS_META;
+ case XK_Super_L : return DIKS_SUPER;
+ case XK_Super_R : return DIKS_SUPER;
+ case XK_Hyper_L : return DIKS_HYPER;
+ case XK_Hyper_R : return DIKS_HYPER;
+ case XK_Mode_switch : return DIKS_ALTGR;
+
+ case XK_Caps_Lock : return DIKS_CAPS_LOCK;
+ case XK_Num_Lock : return DIKS_NUM_LOCK;
+ case XK_Scroll_Lock : return DIKS_SCROLL_LOCK;
+
+ case XK_Escape : return DIKS_ESCAPE;
+ case XK_Left : return DIKS_CURSOR_LEFT;
+ case XK_Right : return DIKS_CURSOR_RIGHT;
+ case XK_Up : return DIKS_CURSOR_UP;
+ case XK_Down : return DIKS_CURSOR_DOWN;
+
+ case XK_Tab : return DIKS_TAB;
+ case XK_ISO_Left_Tab : return DIKS_TAB;
+ case XK_Return : return DIKS_ENTER;
+ case XK_space : return DIKS_SPACE;
+ case XK_BackSpace : return DIKS_BACKSPACE;
+ case XK_Insert : return DIKS_INSERT;
+ case XK_Delete : return DIKS_DELETE;
+ case XK_Home : return DIKS_HOME;
+ case XK_End : return DIKS_END;
+ case XK_Page_Up : return DIKS_PAGE_UP;
+ case XK_Page_Down : return DIKS_PAGE_DOWN;
+ case XK_Print : return DIKS_PRINT;
+ case XK_Pause : return DIKS_PAUSE;
+
+ case XK_KP_Divide : return DIKS_SLASH;
+ case XK_KP_Multiply : return DIKS_ASTERISK;
+ case XK_KP_Subtract : return DIKS_MINUS_SIGN;
+ case XK_KP_Add : return DIKS_PLUS_SIGN;
+ case XK_KP_Enter : return DIKS_ENTER;
+ case XK_KP_Space : return DIKS_SPACE;
+ case XK_KP_Tab : return DIKS_TAB;
+ case XK_KP_F1 : return DIKS_F1;
+ case XK_KP_F2 : return DIKS_F2;
+ case XK_KP_F3 : return DIKS_F3;
+ case XK_KP_F4 : return DIKS_F4;
+ case XK_KP_Equal : return DIKS_EQUALS_SIGN;
+ case XK_KP_Separator : return DIKS_COLON; /* FIXME: what is a separator */
+
+ case XK_KP_Delete : return DIKS_DELETE;
+ case XK_KP_Insert : return DIKS_INSERT;
+ case XK_KP_End : return DIKS_END;
+ case XK_KP_Down : return DIKS_CURSOR_DOWN;
+ case XK_KP_Page_Down : return DIKS_PAGE_DOWN;
+ case XK_KP_Left : return DIKS_CURSOR_LEFT;
+ case XK_KP_Begin : return DIKS_BEGIN;
+ case XK_KP_Right : return DIKS_CURSOR_RIGHT;
+ case XK_KP_Home : return DIKS_HOME;
+ case XK_KP_Up : return DIKS_CURSOR_UP;
+ case XK_KP_Page_Up : return DIKS_PAGE_UP;
+
+ case XK_KP_Decimal : return DIKS_PERIOD;
+ case XK_KP_0 : return DIKS_0;
+ case XK_KP_1 : return DIKS_1;
+ case XK_KP_2 : return DIKS_2;
+ case XK_KP_3 : return DIKS_3;
+ case XK_KP_4 : return DIKS_4;
+ case XK_KP_5 : return DIKS_5;
+ case XK_KP_6 : return DIKS_6;
+ case XK_KP_7 : return DIKS_7;
+ case XK_KP_8 : return DIKS_8;
+ case XK_KP_9 : return DIKS_9;
+
+ case 0 : break;
+
+ default:
+ D_DEBUG("X11: Unknown key symbol 0x%lx\n", xKeySymbol);
+ }
+
+ return DIKS_NULL;
+}
+
+
+
+static void handleMouseEvent(XEvent* pXEvent, X11InputData* pData)
+{
+ static int iMouseEventCount = 0;
+ DFBInputEvent dfbEvent;
+ if (pXEvent->type == MotionNotify) {
+ motion_compress( pXEvent->xmotion.x, pXEvent->xmotion.y, pXEvent );
+ ++iMouseEventCount;
+ }
+
+ if ( pXEvent->type == ButtonPress || pXEvent->type == ButtonRelease ) {
+ if ( pXEvent->type == ButtonPress )
+ dfbEvent.type = DIET_BUTTONPRESS;
+ else
+ dfbEvent.type = DIET_BUTTONRELEASE;
+
+ dfbEvent.flags = DIEF_TIMESTAMP;
+
+ /* Get pressed button */
+ switch ( pXEvent->xbutton.button ) {
+ case 1:
+ dfbEvent.button = DIBI_LEFT;
+ break;
+ case 2:
+ dfbEvent.button = DIBI_MIDDLE;
+ break;
+ case 3:
+ dfbEvent.button = DIBI_RIGHT;
+ break;
+ //Wheel events
+ case 4: /*up*/
+ case 5: /*down*/
+ case 6: /*left*/
+ case 7: /*right*/
+ if (pXEvent->type == ButtonPress) {
+ dfbEvent.type = DIET_AXISMOTION;
+ dfbEvent.flags = DIEF_AXISREL;
+ dfbEvent.axis = DIAI_Z;
+ /*SCROLL UP*/
+ if ( pXEvent->xbutton.button == 4 ) {
+ dfbEvent.axisrel = -1;
+ }
+ /*SCROLL DOWN */
+ else if (pXEvent->xbutton.button == 5) {
+ dfbEvent.axisrel = 1;
+ }
+ /*SCROLL LEFT*/
+ else if (pXEvent->xbutton.button == 6) {
+ dfbEvent.axis = DIAI_X;
+ dfbEvent.axisrel = -1;
+ }
+ /*SCROLL RIGHT*/
+ else if (pXEvent->xbutton.button == 7 ) {
+ dfbEvent.axis = DIAI_X;
+ dfbEvent.axisrel = 1;
+ }
+ }
+ else
+ return;
+ break;
+ default:
+ break;
+ }
+
+ dfbEvent.timestamp.tv_sec = pXEvent->xbutton.time / 1000;
+ dfbEvent.timestamp.tv_usec = (pXEvent->xbutton.time % 1000) * 1000;
+
+ dfb_input_dispatch( pData->device, &dfbEvent );
+ ++iMouseEventCount;
+ }
+}
+
+static void
+handle_expose( const XExposeEvent *expose )
+{
+ CoreLayer *layer = dfb_layer_at( DLID_PRIMARY );
+ const DisplayLayerFuncs *funcs = layer->funcs;
+ CoreLayerContext *context;
+
+ D_ASSERT( funcs != NULL );
+ D_ASSERT( funcs->UpdateRegion != NULL );
+
+ /* 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)
+ {
+ /* Lock the region to avoid tearing due to concurrent updates. */
+ dfb_layer_region_lock( region );
+
+ /* Get the surface of the region. */
+ if (region->surface && region->surface_lock.buffer) {
+ DFBRegion update = { expose->x, expose->y,
+ expose->x + expose->width - 1,
+ expose->y + expose->height - 1 };
+
+ funcs->UpdateRegion( layer, layer->driver_data, layer->layer_data,
+ region->region_data, region->surface, &update, &region->surface_lock );
+ }
+
+ /* Unlock the region. */
+ dfb_layer_region_unlock( region );
+
+ /* Release the region. */
+ dfb_layer_region_unref( region );
+ }
+
+ /* Release the context. */
+ dfb_layer_context_unref( context );
+ }
+}
+
+/*
+ * Input thread reading from device.
+ * Generates events on incoming data.
+ */
+static void*
+x11EventThread( DirectThread *thread, void *driver_data )
+{
+ X11InputData *data = driver_data;
+ DFBX11 *x11 = data->x11;
+ DFBX11Shared *shared = x11->shared;
+
+ while (!data->stop) {
+ unsigned int pull = 23;
+ XEvent xEvent;
+ DFBInputEvent dfbEvent;
+
+ /* FIXME: Detect key repeats, we're receiving KeyPress, KeyRelease, KeyPress, KeyRelease... !!?? */
+
+ if (!shared->xw || !shared->xw->window) {
+ /* no window, so no event */
+ usleep( 50000 );
+ continue;
+ }
+
+ usleep( 10000 );
+
+ XLockDisplay( x11->display );
+
+ while (!data->stop && pull-- && XPending( x11->display )) {
+ XNextEvent( x11->display, &xEvent );
+
+ XUnlockDisplay( x11->display );
+
+ D_DEBUG_AT( X11_Input, "Event received: %d\n", xEvent.type );
+
+ switch (xEvent.type) {
+ case ButtonPress:
+ case ButtonRelease:
+ motion_realize( data );
+ case MotionNotify:
+ handleMouseEvent( &xEvent, data ); // crash ???
+ break;
+
+ case KeyPress:
+ case KeyRelease: {
+ motion_realize( data );
+
+ dfbEvent.type = (xEvent.type == KeyPress) ? DIET_KEYPRESS : DIET_KEYRELEASE;
+ dfbEvent.flags = DIEF_KEYCODE | DIEF_TIMESTAMP;
+ dfbEvent.key_code = xEvent.xkey.keycode;
+
+ dfbEvent.timestamp.tv_sec = xEvent.xkey.time / 1000;
+ dfbEvent.timestamp.tv_usec = (xEvent.xkey.time % 1000) * 1000;
+
+ dfb_input_dispatch( data->device, &dfbEvent );
+ break;
+ }
+
+ case Expose:
+ handle_expose( &xEvent.xexpose );
+ break;
+
+ case DestroyNotify:
+ /* this event is mainly to unblock XNextEvent. */
+ break;
+
+ default:
+ break;
+ }
+
+ XLockDisplay( x11->display );
+ }
+
+ XUnlockDisplay( x11->display );
+
+ if (!data->stop)
+ motion_realize( data );
+ }
+
+ return NULL;
+}
+
+/* exported symbols */
+
+/*
+ * Return the number of available devices.
+ * Called once during initialization of DirectFB.
+ */
+static int
+driver_get_available( void )
+{
+ return dfb_system_type() == CORE_X11;
+}
+
+/*
+ * Fill out general information about this driver.
+ * Called once during initialization of DirectFB.
+ */
+static void
+driver_get_info( InputDriverInfo *info )
+{
+ /* fill driver info structure */
+ snprintf ( info->name, DFB_INPUT_DRIVER_INFO_NAME_LENGTH, "X11 Input Driver" );
+ snprintf ( info->vendor, DFB_INPUT_DRIVER_INFO_VENDOR_LENGTH, "directfb.org" );
+
+ info->version.major = 0;
+ info->version.minor = 1;
+}
+
+/*
+ * Open the device, fill out information about it,
+ * allocate and fill private data, start input thread.
+ * Called during initialization, resuming or taking over mastership.
+ */
+static DFBResult
+driver_open_device( CoreInputDevice *device,
+ unsigned int number,
+ InputDeviceInfo *info,
+ void **driver_data )
+{
+ X11InputData *data;
+ DFBX11 *x11 = dfb_system_data();
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Input, "%s()\n", __FUNCTION__ );
+
+ fusion_skirmish_prevail( &shared->lock );
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+ /* set device vendor and name */
+ snprintf( info->desc.vendor, DFB_INPUT_DEVICE_DESC_VENDOR_LENGTH, "XServer" );
+ snprintf( info->desc.name, DFB_INPUT_DEVICE_DESC_NAME_LENGTH, "X11 Input" );
+
+ /* set one of the primary input device IDs */
+ info->prefered_id = DIDID_KEYBOARD;
+
+ /* set type flags */
+ info->desc.type = DIDTF_JOYSTICK | DIDTF_KEYBOARD | DIDTF_MOUSE;
+
+ /* set capabilities */
+ info->desc.caps = DICAPS_ALL;
+
+ /* enable translation of fake raw hardware keycodes */
+ info->desc.min_keycode = 8;
+ info->desc.max_keycode = 255;
+
+
+ /* allocate and fill private data */
+ data = D_CALLOC( 1, sizeof(X11InputData) );
+
+ data->device = device;
+ data->x11 = x11;
+
+ /* start input thread */
+ data->thread = direct_thread_create( DTT_INPUT, x11EventThread, data, "X11 Input" );
+
+ /* set private data pointer */
+ *driver_data = data;
+
+ return DFB_OK;
+}
+
+/*
+ * Fetch one entry from the device's keymap if supported.
+ * this does a fake mapping based on the orginal DFB code
+ */
+static DFBResult
+driver_get_keymap_entry( CoreInputDevice *device,
+ void *driver_data,
+ DFBInputDeviceKeymapEntry *entry )
+{
+ int i;
+ X11InputData *data = driver_data;
+ DFBX11 *x11 = data->x11;
+
+ XLockDisplay( x11->display );
+
+ for (i=0; i<4; i++) {
+ KeySym xSymbol = XKeycodeToKeysym( x11->display, entry->code, i );
+
+ if (i == 0)
+ entry->identifier = xsymbol_to_id( xSymbol );
+
+ entry->symbols[i] = xsymbol_to_symbol( xSymbol );
+ }
+
+ XUnlockDisplay( x11->display );
+
+ /* is CapsLock effective? */
+ if (entry->identifier >= DIKI_A && entry->identifier <= DIKI_Z)
+ entry->locks |= DILS_CAPS;
+
+ /* is NumLock effective? */
+ if (entry->identifier >= DIKI_KP_DECIMAL && entry->identifier <= DIKI_KP_9)
+ entry->locks |= DILS_NUM;
+
+ return DFB_OK;
+}
+
+/*
+ * End thread, close device and free private data.
+ */
+static DFBResult
+driver_set_sensitivity( CoreInputDevice *device,
+ void *driver_data,
+ int sensitivity )
+{
+ D_DEBUG_AT( X11_Input, "%s( %d )\n", __FUNCTION__, sensitivity );
+
+ return DFB_OK;
+}
+
+/*
+ * End thread, close device and free private data.
+ */
+static void
+driver_close_device( void *driver_data )
+{
+ X11InputData *data = driver_data;
+ DFBX11 *x11 = data->x11;
+ DFBX11Shared *shared = x11->shared;
+
+ D_DEBUG_AT( X11_Input, "%s()\n", __FUNCTION__ );
+
+ /* stop input thread */
+ data->stop = true;
+
+ XLockDisplay( x11->display );
+
+ if (shared->xw) {
+ XWindow *xw = shared->xw;
+
+ shared->xw = NULL;
+
+ /* the window must generate an event, otherwise the input thread will not end */
+ dfb_x11_close_window( x11, xw );
+ }
+
+ XSync( x11->display, False );
+
+ XUnlockDisplay( x11->display );
+
+ /* it is possible that this "close" function is called from the same
+ * thread that the input device is actually running on.
+ * This happens when you e.g. click the close box with your mouse.
+ * As a fix, we check if we are this thread. */
+ if (data->thread != direct_thread_self()) {
+ direct_thread_join( data->thread );
+ direct_thread_destroy( data->thread );
+ }
+
+ /* free private data */
+ D_FREE ( data );
+}
+
diff --git a/Source/DirectFB/systems/x11/x11types.h b/Source/DirectFB/systems/x11/x11types.h
new file mode 100755
index 0000000..872f9db
--- /dev/null
+++ b/Source/DirectFB/systems/x11/x11types.h
@@ -0,0 +1,35 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __SYSTEMS_X11TYPES_H__
+#define __SYSTEMS_X11TYPES_H__
+
+typedef struct __DFB_X11 DFBX11;
+
+#endif /* __SYSTEMS_X11TYPES_H__ */
+
diff --git a/Source/DirectFB/systems/x11/xwindow.c b/Source/DirectFB/systems/x11/xwindow.c
new file mode 100755
index 0000000..ce5e1fe
--- /dev/null
+++ b/Source/DirectFB/systems/x11/xwindow.c
@@ -0,0 +1,294 @@
+/*
+ (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 <stdlib.h>
+#include <stdio.h>
+
+#include <directfb_util.h>
+
+#include <direct/mem.h>
+
+#include "x11.h"
+
+D_DEBUG_DOMAIN( X11_Window, "X11/Window", "X11 Window handling" );
+
+static bool use_shm = true;
+
+static int
+error_handler_shm( Display *display, XErrorEvent *event )
+{
+ if (use_shm) {
+ D_INFO( "X11/Display: Error! Disabling XShm.\n" );
+
+ use_shm = false;
+ }
+
+ return 0;
+}
+
+
+static int error_code = 0;
+
+static int
+error_handler( Display *display, XErrorEvent *event )
+{
+ char buf[512];
+
+ D_DEBUG_AT( X11_Window, "%s()\n", __FUNCTION__ );
+
+ XGetErrorText( display, event->error_code, buf, sizeof(buf) );
+
+ D_ERROR( "X11/Window: Error! %s\n", buf );
+
+ error_code = event->error_code;
+
+ return 0;
+}
+
+Bool
+dfb_x11_open_window( DFBX11 *x11, XWindow** ppXW, int iXPos, int iYPos, int iWidth, int iHeight, DFBSurfacePixelFormat format )
+{
+ XWindow *xw;
+ XSetWindowAttributes attr = { .background_pixmap = 0 };
+
+ D_DEBUG_AT( X11_Window, "Creating %4dx%4d %s window...\n", iWidth, iHeight, dfb_pixelformat_name(format) );
+
+ xw = D_CALLOC( 1, sizeof(XWindow) );
+ if (!xw)
+ return D_OOM();
+
+ /* We set the structure as needed for our window */
+ xw->width = iWidth;
+ xw->height = iHeight;
+ xw->display = x11->display;
+
+ xw->screenptr = DefaultScreenOfDisplay(xw->display);
+ xw->screennum = DefaultScreen(xw->display);
+ xw->depth = DefaultDepthOfScreen(xw->screenptr);
+ xw->visual = DefaultVisualOfScreen(xw->screenptr);
+
+ attr.event_mask =
+ ButtonPressMask
+ | ButtonReleaseMask
+ | PointerMotionMask
+ | KeyPressMask
+ | KeyReleaseMask
+ | ExposureMask
+ | StructureNotifyMask;
+
+ XLockDisplay( x11->display );
+
+ XSetErrorHandler( error_handler );
+
+ error_code = 0;
+
+ xw->window = XCreateWindow( xw->display,
+ RootWindowOfScreen(xw->screenptr),
+ iXPos, iYPos, iWidth, iHeight, 0, xw->depth, InputOutput,
+ xw->visual, CWEventMask, &attr );
+ XSync( xw->display, False );
+ if (!xw->window || error_code) {
+ D_FREE( xw );
+ XUnlockDisplay( x11->display );
+ return False;
+ }
+
+
+ XSizeHints Hints;
+
+ /*
+ * Here we inform the function of what we are going to change for the
+ * window (there's also PPosition but it's obsolete)
+ */
+ Hints.flags = PSize | PMinSize | PMaxSize;
+
+ /*
+ * Now we set the structure to the values we need for width & height.
+ * For esthetic reasons we set Width=MinWidth=MaxWidth.
+ * The same goes for Height. You can try whith differents values, or
+ * let's use Hints.flags=Psize; and resize your window..
+ */
+ Hints.min_width = Hints.max_width = Hints.base_width = xw->width;
+ Hints.min_height = Hints.max_height = Hints.base_height = xw->height;
+
+ /* Now we can set the size hints for the specified window */
+ XSetWMNormalHints(xw->display,xw->window,&Hints);
+
+ /* We change the title of the window (default:Untitled) */
+ XStoreName(xw->display,xw->window,"DFB X11 system window");
+
+ xw->gc = XCreateGC(xw->display, xw->window, 0, NULL);
+
+ // Create a null cursor
+ XColor fore;
+ XColor back;
+ char zero = 0;
+
+ xw->pixmp1 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 );
+ xw->pixmp2 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 );
+
+ xw->NullCursor = XCreatePixmapCursor( xw->display, xw->pixmp1, xw->pixmp2, &fore, &back, 0, 0 );
+
+ XDefineCursor( xw->display, xw->window, xw->NullCursor );
+
+
+ /* maps the window and raises it to the top of the stack */
+ XMapRaised( xw->display, xw->window );
+
+
+ if (x11->use_shm) {
+ // Shared memory
+ xw->shmseginfo=(XShmSegmentInfo *)D_CALLOC(1, sizeof(XShmSegmentInfo));
+ if (!xw->shmseginfo) {
+ x11->use_shm = false;
+ goto no_shm;
+ }
+
+ xw->ximage=XShmCreateImage(xw->display, xw->visual, xw->depth, ZPixmap,
+ NULL,xw->shmseginfo, xw->width, xw->height * 2);
+ XSync( xw->display, False );
+ if (!xw->ximage || error_code) {
+ D_ERROR("X11: Error creating shared image (XShmCreateImage) \n");
+ x11->use_shm = false;
+ D_FREE(xw->shmseginfo);
+ error_code = 0;
+ goto no_shm;
+ }
+
+ xw->bpp = (xw->ximage->bits_per_pixel + 7) / 8;
+
+ /* we firstly create our shared memory segment with the size we need, and
+ correct permissions for the owner, the group and the world --> 0777 */
+ xw->shmseginfo->shmid=shmget(IPC_PRIVATE,
+ xw->ximage->bytes_per_line * xw->ximage->height * 2,
+ IPC_CREAT|0777);
+
+ if (xw->shmseginfo->shmid<0) {
+ x11->use_shm = false;
+ XDestroyImage(xw->ximage);
+ D_FREE(xw->shmseginfo);
+ goto no_shm;
+ }
+
+ /* Then, we have to attach the segment to our process, and we let the
+ function search the correct memory place --> NULL. It's safest ! */
+ xw->shmseginfo->shmaddr = shmat( xw->shmseginfo->shmid, NULL, 0 );
+ if (!xw->shmseginfo->shmaddr) {
+ x11->use_shm = false;
+ shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL);
+ XDestroyImage(xw->ximage);
+ D_FREE(xw->shmseginfo);
+ goto no_shm;
+ }
+
+ /* We set the buffer in Read and Write mode */
+ xw->shmseginfo->readOnly=False;
+
+ xw->virtualscreen= xw->ximage->data = xw->shmseginfo->shmaddr;
+
+
+ XSetErrorHandler( error_handler_shm );
+
+ XShmAttach(x11->display,xw->shmseginfo);
+
+ XShmPutImage(x11->display, xw->window, xw->gc, xw->ximage,
+ 0, 0, 0, 0, 1, 1, False);
+
+ XSync(x11->display, False);
+
+ XSetErrorHandler( error_handler );
+
+ if (!x11->use_shm) {
+ shmdt(xw->shmseginfo->shmaddr);
+ shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL);
+ XDestroyImage(xw->ximage);
+ D_FREE(xw->shmseginfo);
+ }
+ }
+
+no_shm:
+ if (!x11->use_shm) {
+ int pitch;
+
+ xw->bpp = (xw->depth > 16) ? 4 :
+ (xw->depth > 8) ? 2 : 1;
+
+ pitch = (xw->bpp * xw->width + 3) & ~3;
+
+ /* Use malloc(), not D_MALLOC() here, because XCreateImage()
+ * will call free() on this data.
+ */
+ xw->virtualscreen = malloc ( 2 * xw->height * pitch );
+
+ xw->ximage = XCreateImage( xw->display, xw->visual, xw->depth, ZPixmap, 0,
+ xw->virtualscreen, xw->width, xw->height * 2, 32, pitch );
+ XSync( xw->display, False );
+ if (!xw->ximage || error_code) {
+ D_ERROR( "X11/Window: XCreateImage( Visual %02lu, depth %d, size %dx%d, buffer %p [%d] ) failed!\n",
+ xw->visual->visualid, xw->depth, xw->width, xw->height * 2, xw->virtualscreen, pitch );
+ XFreeGC(xw->display,xw->gc);
+ XDestroyWindow(xw->display,xw->window);
+ XSetErrorHandler( NULL );
+ XUnlockDisplay( x11->display );
+ D_FREE( xw );
+ return False;
+ }
+ }
+
+ XSetErrorHandler( NULL );
+
+ XUnlockDisplay( x11->display );
+
+ D_INFO( "X11/Display: %ssing XShm.\n", x11->use_shm ? "U" : "Not u" );
+
+ (*ppXW) = xw;
+
+ return True;
+}
+
+void
+dfb_x11_close_window( DFBX11 *x11, XWindow* xw )
+{
+ if (x11->use_shm) {
+ XShmDetach(xw->display, xw->shmseginfo);
+ shmdt(xw->shmseginfo->shmaddr);
+ shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL);
+ D_FREE(xw->shmseginfo);
+ }
+
+ XDestroyImage(xw->ximage);
+
+ XFreeGC(xw->display,xw->gc);
+ XDestroyWindow(xw->display,xw->window);
+
+ D_FREE(xw);
+}
+
diff --git a/Source/DirectFB/systems/x11/xwindow.h b/Source/DirectFB/systems/x11/xwindow.h
new file mode 100755
index 0000000..9eddfd7
--- /dev/null
+++ b/Source/DirectFB/systems/x11/xwindow.h
@@ -0,0 +1,77 @@
+/*
+ (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 __SYSTEMS_XWINDOW_H__
+#define __SYSTEMS_XWINDOW_H__
+
+#include <X11/Xlib.h> /* fundamentals X datas structures */
+#include <X11/Xutil.h> /* datas definitions for various functions */
+#include <X11/keysym.h> /* for a perfect use of keyboard events */
+
+#include <X11/extensions/XShm.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include "x11types.h"
+
+
+typedef struct {
+ Display* display;
+ Window window;
+ Screen* screenptr;
+ int screennum;
+ Visual* visual;
+ GC gc;
+ XImage* ximage;
+ int ximage_offset;
+ Colormap colormap;
+
+ XShmSegmentInfo* shmseginfo;
+ unsigned char* videomemory;
+
+ char* virtualscreen;
+ int videoaccesstype;
+
+ int width;
+ int height;
+ int depth;
+ int bpp;
+
+ /* (Null) cursor stuff*/
+ Pixmap pixmp1;
+ Pixmap pixmp2;
+ Cursor NullCursor;
+} XWindow;
+
+Bool dfb_x11_open_window ( DFBX11 *x11, XWindow** ppXW, int iXPos, int iYPos, int iWidth, int iHeight, DFBSurfacePixelFormat format );
+void dfb_x11_close_window( DFBX11 *x11, XWindow* pXW );
+
+
+
+#endif /* __SYSTEMS_XWINDOW_H__ */
+