summaryrefslogtreecommitdiff
path: root/Source/DirectFB/wm
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/wm')
-rwxr-xr-xSource/DirectFB/wm/Makefile.am9
-rwxr-xr-xSource/DirectFB/wm/Makefile.in558
-rwxr-xr-xSource/DirectFB/wm/default/Makefile.am33
-rwxr-xr-xSource/DirectFB/wm/default/Makefile.in595
-rwxr-xr-xSource/DirectFB/wm/default/default.c4073
-rwxr-xr-xSource/DirectFB/wm/unique/Makefile.am150
-rwxr-xr-xSource/DirectFB/wm/unique/Makefile.in979
-rwxr-xr-xSource/DirectFB/wm/unique/classes/Makefile.am22
-rwxr-xr-xSource/DirectFB/wm/unique/classes/Makefile.in527
-rwxr-xr-xSource/DirectFB/wm/unique/classes/foo.c232
-rwxr-xr-xSource/DirectFB/wm/unique/classes/frame.c53
-rwxr-xr-xSource/DirectFB/wm/unique/classes/root.c206
-rwxr-xr-xSource/DirectFB/wm/unique/classes/window.c165
-rwxr-xr-xSource/DirectFB/wm/unique/context.c711
-rwxr-xr-xSource/DirectFB/wm/unique/context.h134
-rwxr-xr-xSource/DirectFB/wm/unique/data/Makefile.am31
-rwxr-xr-xSource/DirectFB/wm/unique/data/Makefile.in420
-rwxr-xr-xSource/DirectFB/wm/unique/data/foo_e.pngbin0 -> 121 bytes
-rwxr-xr-xSource/DirectFB/wm/unique/data/foo_n.pngbin0 -> 173 bytes
-rwxr-xr-xSource/DirectFB/wm/unique/data/foo_ne.pngbin0 -> 697 bytes
-rwxr-xr-xSource/DirectFB/wm/unique/data/foo_nw.pngbin0 -> 530 bytes
-rwxr-xr-xSource/DirectFB/wm/unique/data/foo_s.pngbin0 -> 169 bytes
-rwxr-xr-xSource/DirectFB/wm/unique/data/foo_se.pngbin0 -> 782 bytes
-rwxr-xr-xSource/DirectFB/wm/unique/data/foo_sw.pngbin0 -> 644 bytes
-rwxr-xr-xSource/DirectFB/wm/unique/data/foo_w.pngbin0 -> 101 bytes
-rwxr-xr-xSource/DirectFB/wm/unique/decoration.c190
-rwxr-xr-xSource/DirectFB/wm/unique/decoration.h132
-rwxr-xr-xSource/DirectFB/wm/unique/device.c495
-rwxr-xr-xSource/DirectFB/wm/unique/device.h139
-rwxr-xr-xSource/DirectFB/wm/unique/devices/Makefile.am21
-rwxr-xr-xSource/DirectFB/wm/unique/devices/Makefile.in525
-rwxr-xr-xSource/DirectFB/wm/unique/devices/keyboard.c192
-rwxr-xr-xSource/DirectFB/wm/unique/devices/pointer.c259
-rwxr-xr-xSource/DirectFB/wm/unique/devices/wheel.c182
-rwxr-xr-xSource/DirectFB/wm/unique/input_channel.c206
-rwxr-xr-xSource/DirectFB/wm/unique/input_channel.h74
-rwxr-xr-xSource/DirectFB/wm/unique/input_events.h114
-rwxr-xr-xSource/DirectFB/wm/unique/input_switch.c776
-rwxr-xr-xSource/DirectFB/wm/unique/input_switch.h78
-rwxr-xr-xSource/DirectFB/wm/unique/internal.h378
-rwxr-xr-xSource/DirectFB/wm/unique/stret.c837
-rwxr-xr-xSource/DirectFB/wm/unique/stret.h155
-rwxr-xr-xSource/DirectFB/wm/unique/stret_iteration.c209
-rwxr-xr-xSource/DirectFB/wm/unique/stret_iteration.h68
-rwxr-xr-xSource/DirectFB/wm/unique/stret_test.c153
-rwxr-xr-xSource/DirectFB/wm/unique/test_color.c221
-rwxr-xr-xSource/DirectFB/wm/unique/test_foo.c288
-rwxr-xr-xSource/DirectFB/wm/unique/types.h53
-rwxr-xr-xSource/DirectFB/wm/unique/unique.c1064
-rwxr-xr-xSource/DirectFB/wm/unique/uniquewm.c451
-rwxr-xr-xSource/DirectFB/wm/unique/uniquewm.h48
-rwxr-xr-xSource/DirectFB/wm/unique/uwmdump.c267
-rwxr-xr-xSource/DirectFB/wm/unique/window.c1525
-rwxr-xr-xSource/DirectFB/wm/unique/window.h135
54 files changed, 18133 insertions, 0 deletions
diff --git a/Source/DirectFB/wm/Makefile.am b/Source/DirectFB/wm/Makefile.am
new file mode 100755
index 0000000..1939b28
--- /dev/null
+++ b/Source/DirectFB/wm/Makefile.am
@@ -0,0 +1,9 @@
+## Makefile.am for DirectFB/wm
+
+if ENABLE_UNIQUE
+UNIQUE_DIR = unique
+else
+UNIQUE_DIR =
+endif
+
+SUBDIRS = default $(UNIQUE_DIR)
diff --git a/Source/DirectFB/wm/Makefile.in b/Source/DirectFB/wm/Makefile.in
new file mode 100755
index 0000000..52846e6
--- /dev/null
+++ b/Source/DirectFB/wm/Makefile.in
@@ -0,0 +1,558 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = wm
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = default unique
+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@
+@ENABLE_UNIQUE_FALSE@UNIQUE_DIR =
+@ENABLE_UNIQUE_TRUE@UNIQUE_DIR = unique
+SUBDIRS = default $(UNIQUE_DIR)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu wm/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu wm/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-info: install-info-recursive
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-ps: install-ps-recursive
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
+ install-strip
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ ctags ctags-recursive distclean distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Source/DirectFB/wm/default/Makefile.am b/Source/DirectFB/wm/default/Makefile.am
new file mode 100755
index 0000000..dce61ab
--- /dev/null
+++ b/Source/DirectFB/wm/default/Makefile.am
@@ -0,0 +1,33 @@
+## Makefile.am for DirectFB/wm/default
+
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src
+
+
+wmdir = $(MODULEDIR)/wm
+
+if BUILD_STATIC
+wm_DATA = libdirectfbwm_default.o
+endif
+
+wm_LTLIBRARIES = libdirectfbwm_default.la
+
+
+libdirectfbwm_default_la_LDFLAGS = \
+ -avoid-version \
+ -module
+
+libdirectfbwm_default_la_SOURCES = \
+ default.c
+
+libdirectfbwm_default_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/wm/default/Makefile.in b/Source/DirectFB/wm/default/Makefile.in
new file mode 100755
index 0000000..38ddacf
--- /dev/null
+++ b/Source/DirectFB/wm/default/Makefile.in
@@ -0,0 +1,595 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/rules/libobject.make
+subdir = wm/default
+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)$(wmdir)" "$(DESTDIR)$(wmdir)"
+wmLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(wm_LTLIBRARIES)
+libdirectfbwm_default_la_DEPENDENCIES = \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+am_libdirectfbwm_default_la_OBJECTS = default.lo
+libdirectfbwm_default_la_OBJECTS = \
+ $(am_libdirectfbwm_default_la_OBJECTS)
+libdirectfbwm_default_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libdirectfbwm_default_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 = $(libdirectfbwm_default_la_SOURCES)
+DIST_SOURCES = $(libdirectfbwm_default_la_SOURCES)
+wmDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(wm_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
+
+wmdir = $(MODULEDIR)/wm
+@BUILD_STATIC_TRUE@wm_DATA = libdirectfbwm_default.o
+wm_LTLIBRARIES = libdirectfbwm_default.la
+libdirectfbwm_default_la_LDFLAGS = \
+ -avoid-version \
+ -module
+
+libdirectfbwm_default_la_SOURCES = \
+ default.c
+
+libdirectfbwm_default_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 wm/default/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu wm/default/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-wmLTLIBRARIES: $(wm_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(wmdir)" || $(MKDIR_P) "$(DESTDIR)$(wmdir)"
+ @list='$(wm_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(wmLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(wmdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(wmLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(wmdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-wmLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(wm_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(wmdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(wmdir)/$$p"; \
+ done
+
+clean-wmLTLIBRARIES:
+ -test -z "$(wm_LTLIBRARIES)" || rm -f $(wm_LTLIBRARIES)
+ @list='$(wm_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
+libdirectfbwm_default.la: $(libdirectfbwm_default_la_OBJECTS) $(libdirectfbwm_default_la_DEPENDENCIES)
+ $(libdirectfbwm_default_la_LINK) -rpath $(wmdir) $(libdirectfbwm_default_la_OBJECTS) $(libdirectfbwm_default_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/default.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-wmDATA: $(wm_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(wmdir)" || $(MKDIR_P) "$(DESTDIR)$(wmdir)"
+ @list='$(wm_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(wmDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(wmdir)/$$f'"; \
+ $(wmDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(wmdir)/$$f"; \
+ done
+
+uninstall-wmDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(wm_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(wmdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(wmdir)/$$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)$(wmdir)" "$(DESTDIR)$(wmdir)"; 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-wmLTLIBRARIES \
+ 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-wmDATA install-wmLTLIBRARIES
+
+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-wmDATA uninstall-wmLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-wmLTLIBRARIES 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-wmDATA install-wmLTLIBRARIES \
+ 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-wmDATA \
+ uninstall-wmLTLIBRARIES
+
+%.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/wm/default/default.c b/Source/DirectFB/wm/default/default.c
new file mode 100755
index 0000000..2049c2d
--- /dev/null
+++ b/Source/DirectFB/wm/default/default.c
@@ -0,0 +1,4073 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/trace.h>
+#include <direct/util.h>
+
+#include <fusion/shmalloc.h>
+#include <fusion/vector.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/gfxcard.h>
+#include <core/layer_context.h>
+#include <core/layer_region.h>
+#include <core/layers_internal.h>
+#include <core/surface.h>
+#include <core/palette.h>
+#include <core/windows.h>
+#include <core/windows_internal.h>
+#include <core/windowstack.h>
+#include <core/wm.h>
+
+#include <gfx/util.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+#include <core/wm_module.h>
+
+
+D_DEBUG_DOMAIN( WM_Default, "WM/Default", "Default window manager module" );
+
+
+DFB_WINDOW_MANAGER( default )
+
+
+typedef struct {
+ DirectLink link;
+
+ DFBInputDeviceKeySymbol symbol;
+ DFBInputDeviceModifierMask modifiers;
+
+ CoreWindow *owner;
+} GrabbedKey;
+
+/**************************************************************************************************/
+
+#define MAX_KEYS 16
+#define MAX_UPDATE_REGIONS 8
+
+typedef struct {
+ CoreDFB *core;
+} WMData;
+
+typedef struct {
+ int magic;
+
+ CoreWindowStack *stack;
+
+ DFBUpdates updates;
+ DFBRegion update_regions[MAX_UPDATE_REGIONS];
+
+ DFBInputDeviceButtonMask buttons;
+ DFBInputDeviceModifierMask modifiers;
+ DFBInputDeviceLockState locks;
+
+ bool active;
+
+ int wm_level;
+ int wm_cycle;
+
+ FusionVector windows;
+
+ CoreWindow *pointer_window; /* window grabbing the pointer */
+ CoreWindow *keyboard_window; /* window grabbing the keyboard */
+ CoreWindow *focused_window; /* window having the focus */
+ CoreWindow *entered_window; /* window under the pointer */
+ CoreWindow *unselkeys_window; /* window grabbing unselected keys */
+
+ DirectLink *grabbed_keys; /* List of currently grabbed keys. */
+
+ struct {
+ DFBInputDeviceKeySymbol symbol;
+ DFBInputDeviceKeyIdentifier id;
+ int code;
+ CoreWindow *owner;
+ } keys[MAX_KEYS];
+
+ CoreSurface *cursor_bs; /* backing store for region under cursor */
+ bool cursor_bs_valid;
+ DFBRegion cursor_region;
+ bool cursor_drawn;
+
+ int cursor_dx;
+ int cursor_dy;
+} StackData;
+
+typedef struct {
+ int magic;
+
+ CoreWindow *window;
+
+ StackData *stack_data;
+
+ int priority; /* derived from stacking class */
+
+ CoreLayerRegionConfig config;
+} WindowData;
+
+/**************************************************************************************************/
+
+static DFBResult
+restack_window( CoreWindow *window,
+ WindowData *window_data,
+ CoreWindow *relative,
+ WindowData *relative_data,
+ int relation,
+ DFBWindowStackingClass stacking );
+
+static DFBResult
+update_window( CoreWindow *window,
+ WindowData *window_data,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags,
+ bool force_complete,
+ bool force_invisible,
+ bool scale_region );
+
+/**************************************************************************************************/
+
+static int keys_compare( const void *key1,
+ const void *key2 )
+{
+ return *(const DFBInputDeviceKeySymbol*) key1 - *(const DFBInputDeviceKeySymbol*) key2;
+}
+
+/**************************************************************************************************/
+
+static inline void
+transform_point_in_window( CoreWindow *window,
+ int *x,
+ int *y )
+{
+ int _x = *x, _y = *y;
+
+ switch (window->config.rotation) {
+ default:
+ D_BUG( "invalid rotation %d", window->config.rotation );
+ case 0:
+ break;
+
+ case 90:
+ *x = window->config.bounds.w - _y - 1;
+ *y = _x;
+ break;
+
+ case 180:
+ *x = window->config.bounds.w - _x - 1;
+ *y = window->config.bounds.h - _y - 1;
+ break;
+
+ case 270:
+ *x = _y;
+ *y = window->config.bounds.h - _x - 1;
+ break;
+ }
+}
+
+static void
+post_event( CoreWindow *window,
+ StackData *data,
+ DFBWindowEvent *event )
+{
+ D_ASSERT( window != NULL );
+ D_ASSERT( window->stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( event != NULL );
+
+ event->buttons = data->buttons;
+ event->modifiers = data->modifiers;
+ event->locks = data->locks;
+
+ dfb_window_post_event( window, event );
+}
+
+static void
+send_key_event( CoreWindow *window,
+ StackData *data,
+ const DFBInputEvent *event )
+{
+ DFBWindowEvent we;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( event != NULL );
+
+ we.type = (event->type == DIET_KEYPRESS) ? DWET_KEYDOWN : DWET_KEYUP;
+ we.key_code = event->key_code;
+ we.key_id = event->key_id;
+ we.key_symbol = event->key_symbol;
+
+ post_event( window, data, &we );
+}
+
+static void
+send_button_event( CoreWindow *window,
+ StackData *data,
+ const DFBInputEvent *event )
+{
+ DFBWindowEvent we;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( event != NULL );
+
+ we.type = (event->type == DIET_BUTTONPRESS) ? DWET_BUTTONDOWN : DWET_BUTTONUP;
+ we.x = window->stack->cursor.x - window->config.bounds.x;
+ we.y = window->stack->cursor.y - window->config.bounds.y;
+ we.button = (data->wm_level & 2) ? (event->button + 2) : event->button;
+
+ transform_point_in_window( window, &we.x, &we.y );
+
+ post_event( window, data, &we );
+}
+
+/**************************************************************************************************/
+
+static inline void
+transform_window_to_stack( CoreWindow *window,
+ const DFBRectangle *rect,
+ DFBRectangle *ret_rect )
+{
+ DFB_RECTANGLE_ASSERT( rect );
+
+ ret_rect->x = rect->x;
+ ret_rect->y = rect->y;
+
+ switch (window->config.rotation) {
+ default:
+ D_BUG( "invalid rotation %d", window->config.rotation );
+ case 0:
+ case 180:
+ ret_rect->w = rect->w;
+ ret_rect->h = rect->h;
+ break;
+
+ case 90:
+ case 270:
+ ret_rect->w = rect->h;
+ ret_rect->h = rect->w;
+ break;
+ }
+}
+
+static inline int
+get_priority( const CoreWindow *window )
+{
+ D_ASSERT( window != NULL );
+
+ switch (window->config.stacking) {
+ case DWSC_UPPER:
+ return 1;
+
+ case DWSC_MIDDLE:
+ return 0;
+
+ case DWSC_LOWER:
+ return -1;
+
+ default:
+ D_BUG( "unknown stacking class" );
+ break;
+ }
+
+ return 0;
+}
+
+static inline int
+get_index( const StackData *data,
+ const CoreWindow *window )
+{
+ D_ASSERT( data != NULL );
+ D_ASSERT( window != NULL );
+
+ D_ASSERT( fusion_vector_contains( &data->windows, window ) );
+
+ return fusion_vector_index_of( &data->windows, window );
+}
+
+static CoreWindow *
+get_keyboard_window( CoreWindowStack *stack,
+ StackData *data,
+ const DFBInputEvent *event )
+{
+ DirectLink *l;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( event != NULL );
+ D_ASSERT( event->type == DIET_KEYPRESS || event->type == DIET_KEYRELEASE );
+
+ /* Check explicit key grabs first. */
+ direct_list_foreach (l, data->grabbed_keys) {
+ GrabbedKey *key = (GrabbedKey*) l;
+
+ if (key->symbol == event->key_symbol &&
+ key->modifiers == data->modifiers)
+ return key->owner;
+ }
+
+ /* Don't do implicit grabs on keys without a hardware index. */
+ if (event->key_code == -1)
+ return (data->keyboard_window ?
+ data->keyboard_window : data->focused_window);
+
+ /* Implicitly grab (press) or ungrab (release) key. */
+ if (event->type == DIET_KEYPRESS) {
+ int i;
+ int free_key = -1;
+ CoreWindow *window;
+
+ /* Check active grabs. */
+ for (i=0; i<MAX_KEYS; i++) {
+ /* Key is grabbed, send to owner (NULL if destroyed). */
+ if (data->keys[i].code == event->key_code)
+ return data->keys[i].owner;
+
+ /* Remember first free array item. */
+ if (free_key == -1 && data->keys[i].code == -1)
+ free_key = i;
+ }
+
+ /* Key is not grabbed, check for explicit keyboard grab or focus. */
+ window = data->keyboard_window ?
+ data->keyboard_window : data->focused_window;
+ if (!window)
+ return NULL;
+
+ /* Check key selection. */
+ switch (window->config.key_selection) {
+ case DWKS_ALL:
+ break;
+
+ case DWKS_LIST:
+ D_ASSERT( window->config.keys != NULL );
+ D_ASSERT( window->config.num_keys > 0 );
+
+ if (bsearch( &event->key_symbol,
+ window->config.keys, window->config.num_keys,
+ sizeof(DFBInputDeviceKeySymbol), keys_compare ))
+ break;
+
+ /* fall through */
+
+ case DWKS_NONE:
+ return data->unselkeys_window;
+ }
+
+ /* Check if a free array item was found. */
+ if (free_key == -1) {
+ D_WARN( "maximum number of owned keys reached" );
+ return NULL;
+ }
+
+ /* Implicitly grab the key. */
+ data->keys[free_key].symbol = event->key_symbol;
+ data->keys[free_key].id = event->key_id;
+ data->keys[free_key].code = event->key_code;
+ data->keys[free_key].owner = window;
+
+ return window;
+ }
+ else {
+ int i;
+
+ /* Lookup owner and ungrab the key. */
+ for (i=0; i<MAX_KEYS; i++) {
+ if (data->keys[i].code == event->key_code) {
+ data->keys[i].code = -1;
+
+ /* Return owner (NULL if destroyed). */
+ return data->keys[i].owner;
+ }
+ }
+ }
+
+ /* No owner for release event found, discard it. */
+ return NULL;
+}
+
+static CoreWindow*
+window_at_pointer( CoreWindowStack *stack,
+ StackData *data,
+ WMData *wmdata,
+ int x,
+ int y )
+{
+ int i;
+ CoreWindow *window;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+
+ if (!stack->cursor.enabled) {
+ fusion_vector_foreach_reverse (window, i, data->windows)
+ if (window->config.opacity && !(window->config.options & DWOP_GHOST))
+ return window;
+
+ return NULL;
+ }
+
+ if (x < 0)
+ x = stack->cursor.x;
+ if (y < 0)
+ y = stack->cursor.y;
+
+ fusion_vector_foreach_reverse (window, i, data->windows) {
+ CoreWindowConfig *config = &window->config;
+ DFBWindowOptions options = config->options;
+ DFBRectangle rotated;
+ DFBRectangle *bounds = &rotated;
+
+ transform_window_to_stack( window, &config->bounds, &rotated );
+
+ if (!(options & DWOP_GHOST) && config->opacity &&
+ x >= bounds->x && x < bounds->x + bounds->w &&
+ y >= bounds->y && y < bounds->y + bounds->h)
+ {
+ int wx = x - bounds->x;
+ int wy = y - bounds->y;
+
+ if ( !(options & DWOP_SHAPED) ||
+ !(options &(DWOP_ALPHACHANNEL|DWOP_COLORKEYING))
+ || !window->surface ||
+ ((options & DWOP_OPAQUE_REGION) &&
+ (wx >= config->opaque.x1 && wx <= config->opaque.x2 &&
+ wy >= config->opaque.y1 && wy <= config->opaque.y2)))
+ {
+ return window;
+ }
+ else {
+ u8 buf[8];
+ CoreSurface *surface = window->surface;
+ DFBSurfacePixelFormat format = surface->config.format;
+ DFBRectangle rect = { wx, wy, 1, 1 };
+
+ if (dfb_surface_read_buffer( surface, CSBR_FRONT, buf, 8, &rect ) == DFB_OK) {
+ if (options & DWOP_ALPHACHANNEL) {
+ int alpha = -1;
+
+ D_ASSERT( DFB_PIXELFORMAT_HAS_ALPHA( format ) );
+
+ switch (format) {
+ case DSPF_AiRGB:
+ alpha = 0xff - (*(u32*)(buf) >> 24);
+ break;
+ case DSPF_ARGB:
+ case DSPF_AYUV:
+ alpha = *(u32*)(buf) >> 24;
+ break;
+ case DSPF_ARGB1555:
+ case DSPF_ARGB2554:
+ case DSPF_ARGB4444:
+ alpha = *(u16*)(buf) & 0x8000;
+ alpha = alpha ? 0xff : 0x00;
+ break;
+ case DSPF_RGBA4444:
+ alpha = *(u16*)(buf) & 0x0008;
+ alpha = alpha ? 0xff : 0x00;
+ break;
+ case DSPF_ALUT44:
+ alpha = *(u8*)(buf) & 0xf0;
+ alpha |= alpha >> 4;
+ break;
+ case DSPF_LUT2:
+ case DSPF_LUT8: {
+ CorePalette *palette = surface->palette;
+ u8 pix = *((u8*) buf);
+
+ if (palette && pix < palette->num_entries) {
+ alpha = palette->entries[pix].a;
+ break;
+ }
+
+
+ /* fall through */
+ }
+
+ default:
+ D_ONCE( "unknown format 0x%x", surface->config.format );
+ break;
+ }
+
+ if (alpha) /* alpha == -1 on error */
+ return window;
+ }
+ if (options & DWOP_COLORKEYING) {
+ int pixel = 0;
+ u8 *p;
+ switch (format) {
+ case DSPF_ARGB:
+ case DSPF_AiRGB:
+ case DSPF_RGB32:
+ pixel = *(u32*)(buf) & 0x00ffffff;
+ break;
+
+ case DSPF_RGB24:
+ p = (buf);
+#ifdef WORDS_BIGENDIAN
+ pixel = (p[0] << 16) | (p[1] << 8) | p[2];
+#else
+ pixel = (p[2] << 16) | (p[1] << 8) | p[0];
+#endif
+ break;
+
+ case DSPF_RGB16:
+ pixel = *(u16*)(buf);
+ break;
+
+ case DSPF_ARGB4444:
+ case DSPF_RGB444:
+ pixel = *(u16*)(buf)
+ & 0x0fff;
+ break;
+
+ case DSPF_RGBA4444:
+ pixel = *(u16*)(buf)
+ & 0xfff0;
+ break;
+
+ case DSPF_ARGB1555:
+ case DSPF_RGB555:
+ case DSPF_BGR555:
+ pixel = *(u16*)(buf)
+ & 0x7fff;
+ break;
+
+ case DSPF_RGB332:
+ case DSPF_LUT8:
+ pixel = *(u8*)(buf);
+ break;
+
+ case DSPF_ALUT44:
+ pixel = *(u8*)(buf)
+ & 0x0f;
+ break;
+
+ default:
+ D_ONCE( "unknown format 0x%x", surface->config.format );
+ break;
+ }
+
+ if (pixel != config->color_key)
+ return window;
+ }
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static void
+switch_focus( CoreWindowStack *stack,
+ StackData *data,
+ CoreWindow *to )
+{
+ DFBWindowEvent evt;
+ CoreWindow *from;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+
+ from = data->focused_window;
+
+ if (from == to)
+ return;
+
+ if (to && to->caps & DWCAPS_NOFOCUS)
+ return;
+
+ if (from) {
+ evt.type = DWET_LOSTFOCUS;
+
+ post_event( from, data, &evt );
+ }
+
+ if (to) {
+ if (to->surface && to->surface->palette && !stack->hw_mode) {
+ CoreSurface *surface;
+
+ D_ASSERT( to->primary_region != NULL );
+
+ if (dfb_layer_region_get_surface( to->primary_region, &surface ) == DFB_OK) {
+ if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format ))
+ dfb_surface_set_palette( surface, to->surface->palette );
+
+ dfb_surface_unref( surface );
+ }
+ }
+
+ evt.type = DWET_GOTFOCUS;
+
+ post_event( to, data, &evt );
+ }
+
+ data->focused_window = to;
+}
+
+static bool
+update_focus( CoreWindowStack *stack,
+ StackData *data,
+ WMData *wmdata )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+
+ /* if pointer is not grabbed */
+ if (!data->pointer_window) {
+ CoreWindow *before = data->entered_window;
+ CoreWindow *after = window_at_pointer( stack, data, wmdata, -1, -1 );
+
+ /* and the window under the cursor is another one now */
+ if (before != after) {
+ DFBWindowEvent we;
+
+ /* send leave event */
+ if (before) {
+ we.type = DWET_LEAVE;
+ we.x = stack->cursor.x - before->config.bounds.x;
+ we.y = stack->cursor.y - before->config.bounds.y;
+
+ transform_point_in_window( before, &we.x, &we.y );
+
+ post_event( before, data, &we );
+ }
+
+ /* switch focus and send enter event */
+ switch_focus( stack, data, after );
+
+ if (after) {
+ we.type = DWET_ENTER;
+ we.x = stack->cursor.x - after->config.bounds.x;
+ we.y = stack->cursor.y - after->config.bounds.y;
+
+ transform_point_in_window( after, &we.x, &we.y );
+
+ post_event( after, data, &we );
+ }
+
+ /* update pointer to window under the cursor */
+ data->entered_window = after;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void
+ensure_focus( CoreWindowStack *stack,
+ StackData *data )
+{
+ int i;
+ CoreWindow *window;
+
+ if (data->focused_window)
+ return;
+
+ fusion_vector_foreach_reverse (window, i, data->windows) {
+ if (window->config.opacity && !(window->config.options & DWOP_GHOST)) {
+ switch_focus( stack, data, window );
+ break;
+ }
+ }
+}
+
+/**************************************************************************************************/
+/**************************************************************************************************/
+
+static inline void
+transform_stack_to_dest( CoreWindowStack *stack,
+ const DFBRegion *region,
+ DFBRegion *ret_dest )
+{
+ DFBDimension size = { stack->width, stack->height };
+
+ DFB_REGION_ASSERT( region );
+
+ dfb_region_from_rotated( ret_dest, region, &size, stack->rotation );
+}
+
+static void
+draw_cursor( CoreWindowStack *stack, StackData *data, CardState *state, const DFBRegion *region )
+{
+ DFBRectangle src;
+ DFBRegion dest;
+ DFBSurfaceBlittingFlags flags = DSBLIT_BLEND_ALPHACHANNEL;
+
+ D_ASSERT( stack != NULL );
+ D_MAGIC_ASSERT( data, StackData );
+ D_MAGIC_ASSERT( state, CardState );
+ DFB_REGION_ASSERT( region );
+
+ D_ASSUME( stack->cursor.opacity > 0 );
+
+ /* Initialize destination region. */
+ transform_stack_to_dest( stack, region, &dest );
+
+ /* Initialize source rectangle. */
+ src.x = region->x1 - stack->cursor.x + stack->cursor.hot.x;
+ src.y = region->y1 - stack->cursor.y + stack->cursor.hot.y;
+ src.w = region->x2 - region->x1 + 1;
+ src.h = region->y2 - region->y1 + 1;
+
+ /* Use global alpha blending. */
+ if (stack->cursor.opacity != 0xFF) {
+ flags |= DSBLIT_BLEND_COLORALPHA;
+
+ /* Set opacity as blending factor. */
+ if (state->color.a != stack->cursor.opacity) {
+ state->color.a = stack->cursor.opacity;
+ state->modified |= SMF_COLOR;
+ }
+ }
+
+ /* Different compositing methods depending on destination format. */
+ if (flags & DSBLIT_BLEND_ALPHACHANNEL) {
+ if (DFB_PIXELFORMAT_HAS_ALPHA( state->destination->config.format )) {
+ /*
+ * Always use compliant Porter/Duff SRC_OVER,
+ * if the destination has an alpha channel.
+ *
+ * Cd = destination color (non-premultiplied)
+ * Ad = destination alpha
+ *
+ * Cs = source color (non-premultiplied)
+ * As = source alpha
+ *
+ * Ac = color alpha
+ *
+ * cd = Cd * Ad (premultiply destination)
+ * cs = Cs * As (premultiply source)
+ *
+ * The full equation to calculate resulting color and alpha (premultiplied):
+ *
+ * cx = cd * (1-As*Ac) + cs * Ac
+ * ax = Ad * (1-As*Ac) + As * Ac
+ */
+ dfb_state_set_src_blend( state, DSBF_ONE );
+
+ /* Need to premultiply source with As*Ac or only with Ac? */
+ if (! (stack->cursor.surface->config.caps & DSCAPS_PREMULTIPLIED))
+ flags |= DSBLIT_SRC_PREMULTIPLY;
+ else if (flags & DSBLIT_BLEND_COLORALPHA)
+ flags |= DSBLIT_SRC_PREMULTCOLOR;
+
+ /* Need to premultiply/demultiply destination? */
+// if (! (state->destination->caps & DSCAPS_PREMULTIPLIED))
+// flags |= DSBLIT_DST_PREMULTIPLY | DSBLIT_DEMULTIPLY;
+ }
+ else {
+ /*
+ * We can avoid DSBLIT_SRC_PREMULTIPLY for destinations without an alpha channel
+ * by using another blending function, which is more likely that it's accelerated
+ * than premultiplication at this point in time.
+ *
+ * This way the resulting alpha (ax) doesn't comply with SRC_OVER,
+ * but as the destination doesn't have an alpha channel it's no problem.
+ *
+ * As the destination's alpha value is always 1.0 there's no need for
+ * premultiplication. The resulting alpha value will also be 1.0 without
+ * exceptions, therefore no need for demultiplication.
+ *
+ * cx = Cd * (1-As*Ac) + Cs*As * Ac (still same effect as above)
+ * ax = Ad * (1-As*Ac) + As*As * Ac (wrong, but discarded anyways)
+ */
+ if (stack->cursor.surface->config.caps & DSCAPS_PREMULTIPLIED) {
+ /* Need to premultiply source with Ac? */
+ if (flags & DSBLIT_BLEND_COLORALPHA)
+ flags |= DSBLIT_SRC_PREMULTCOLOR;
+
+ dfb_state_set_src_blend( state, DSBF_ONE );
+ }
+ else
+ dfb_state_set_src_blend( state, DSBF_SRCALPHA );
+ }
+ }
+
+ /* Set blitting flags. */
+ dfb_state_set_blitting_flags( state, flags | stack->rotated_blit );
+
+ /* Set blitting source. */
+ state->source = stack->cursor.surface;
+ state->modified |= SMF_SOURCE;
+
+ /* Blit from the window to the region being updated. */
+ dfb_gfxcard_blit( &src, dest.x1, dest.y1, state );
+
+ /* Reset blitting source. */
+ state->source = NULL;
+ state->modified |= SMF_SOURCE;
+}
+
+static void
+draw_window( CoreWindow *window, CardState *state,
+ const DFBRegion *region, bool alpha_channel )
+{
+ DFBRegion dest;
+ DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
+ CoreWindowStack *stack;
+ CoreWindowConfig *config;
+ CoreSurface *surface;
+ int rotation;
+
+ D_ASSERT( window != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ DFB_REGION_ASSERT( region );
+
+ stack = window->stack;
+ D_MAGIC_ASSERT( stack, CoreWindowStack );
+
+ surface = window->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ config = &window->config;
+
+ /* Initialize destination region. */
+ transform_stack_to_dest( stack, region, &dest );
+
+ /* Use per pixel alpha blending. */
+ if (alpha_channel && (config->options & DWOP_ALPHACHANNEL))
+ flags |= DSBLIT_BLEND_ALPHACHANNEL;
+
+ /* Use global alpha blending. */
+ if (config->opacity != 0xFF) {
+ flags |= DSBLIT_BLEND_COLORALPHA;
+
+ /* Set opacity as blending factor. */
+ if (state->color.a != config->opacity) {
+ state->color.a = config->opacity;
+ state->modified |= SMF_COLOR;
+ }
+ }
+
+ /* Use source color keying. */
+ if (config->options & DWOP_COLORKEYING) {
+ flags |= DSBLIT_SRC_COLORKEY;
+
+ /* Set window color key. */
+ dfb_state_set_src_colorkey( state, config->color_key );
+ }
+
+ /* Use automatic deinterlacing. */
+ if (surface->config.caps & DSCAPS_INTERLACED)
+ flags |= DSBLIT_DEINTERLACE;
+
+ /* Different compositing methods depending on destination format. */
+ if (flags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
+ if (DFB_PIXELFORMAT_HAS_ALPHA( state->destination->config.format )) {
+ /*
+ * Always use compliant Porter/Duff SRC_OVER,
+ * if the destination has an alpha channel.
+ *
+ * Cd = destination color (non-premultiplied)
+ * Ad = destination alpha
+ *
+ * Cs = source color (non-premultiplied)
+ * As = source alpha
+ *
+ * Ac = color alpha
+ *
+ * cd = Cd * Ad (premultiply destination)
+ * cs = Cs * As (premultiply source)
+ *
+ * The full equation to calculate resulting color and alpha (premultiplied):
+ *
+ * cx = cd * (1-As*Ac) + cs * Ac
+ * ax = Ad * (1-As*Ac) + As * Ac
+ */
+ dfb_state_set_src_blend( state, DSBF_ONE );
+
+ /* Need to premultiply source with As*Ac or only with Ac? */
+ if (! (surface->config.caps & DSCAPS_PREMULTIPLIED))
+ flags |= DSBLIT_SRC_PREMULTIPLY;
+ else if (flags & DSBLIT_BLEND_COLORALPHA)
+ flags |= DSBLIT_SRC_PREMULTCOLOR;
+
+ /* Need to premultiply/demultiply destination? */
+// if (! (state->destination->caps & DSCAPS_PREMULTIPLIED))
+// flags |= DSBLIT_DST_PREMULTIPLY | DSBLIT_DEMULTIPLY;
+ }
+ else {
+ /*
+ * We can avoid DSBLIT_SRC_PREMULTIPLY for destinations without an alpha channel
+ * by using another blending function, which is more likely that it's accelerated
+ * than premultiplication at this point in time.
+ *
+ * This way the resulting alpha (ax) doesn't comply with SRC_OVER,
+ * but as the destination doesn't have an alpha channel it's no problem.
+ *
+ * As the destination's alpha value is always 1.0 there's no need for
+ * premultiplication. The resulting alpha value will also be 1.0 without
+ * exceptions, therefore no need for demultiplication.
+ *
+ * cx = Cd * (1-As*Ac) + Cs*As * Ac (still same effect as above)
+ * ax = Ad * (1-As*Ac) + As*As * Ac (wrong, but discarded anyways)
+ */
+ if (surface->config.caps & DSCAPS_PREMULTIPLIED) {
+ /* Need to premultiply source with Ac? */
+ if (flags & DSBLIT_BLEND_COLORALPHA)
+ flags |= DSBLIT_SRC_PREMULTCOLOR;
+
+ dfb_state_set_src_blend( state, DSBF_ONE );
+ }
+ else
+ dfb_state_set_src_blend( state, DSBF_SRCALPHA );
+ }
+ }
+
+ rotation = (window->config.rotation + stack->rotation) % 360;
+ switch (rotation) {
+ default:
+ D_BUG( "invalid rotation %d", rotation );
+ case 0:
+ break;
+
+ case 90:
+ flags |= DSBLIT_ROTATE90;
+ break;
+
+ case 180:
+ flags |= DSBLIT_ROTATE180;
+ break;
+
+ case 270:
+ flags |= DSBLIT_ROTATE270;
+ break;
+ }
+
+ /* Set blitting flags. */
+ dfb_state_set_blitting_flags( state, flags );
+
+ /* Set blitting source. */
+ state->source = surface;
+ state->modified |= SMF_SOURCE;
+
+ if (window->config.options & DWOP_SCALE) {
+ DFBDimension size = { stack->width, stack->height };
+ DFBRegion clip = state->clip;
+ DFBRectangle src = { 0, 0, surface->config.size.w, surface->config.size.h };
+ DFBRectangle dst;
+ DFBRectangle bounds;
+
+ transform_window_to_stack( window, &window->config.bounds, &bounds );
+
+ dfb_rectangle_from_rotated( &dst, &bounds, &size, stack->rotation );
+
+ /* Change clipping region. */
+ dfb_state_set_clip( state, &dest );
+
+ /* Scale window to the screen clipped by the region being updated. */
+ dfb_gfxcard_stretchblit( &src, &dst, state );
+
+ /* Restore clipping region. */
+ dfb_state_set_clip( state, &clip );
+ }
+ else {
+ DFBDimension size = { config->bounds.w, config->bounds.h };
+ DFBRectangle rect, src;
+
+ D_ASSERT( surface->config.size.w == config->bounds.w );
+ D_ASSERT( surface->config.size.h == config->bounds.h );
+
+ /* Initialize source rectangle. */
+ dfb_rectangle_from_region( &rect, region );
+
+ /* Subtract window offset. */
+ rect.x -= config->bounds.x;
+ rect.y -= config->bounds.y;
+
+ /* Rotate back to window surface. */
+ if (window->config.rotation == 90 || window->config.rotation == 270)
+ D_UTIL_SWAP( size.w, size.h );
+
+ dfb_rectangle_from_rotated( &src, &rect, &size, (360 - window->config.rotation) % 360 );
+
+ /* Blit from the window to the region being updated. */
+ dfb_gfxcard_blit( &src, dest.x1, dest.y1, state );
+ }
+
+ /* Reset blitting source. */
+ state->source = NULL;
+ state->modified |= SMF_SOURCE;
+}
+
+static void
+draw_background( CoreWindowStack *stack, CardState *state, const DFBRegion *region )
+{
+ DFBRegion dest;
+
+ D_ASSERT( stack != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ DFB_REGION_ASSERT( region );
+
+ D_ASSERT( stack->bg.image != NULL || (stack->bg.mode != DLBM_IMAGE &&
+ stack->bg.mode != DLBM_TILE) );
+
+ /* Initialize destination region. */
+ transform_stack_to_dest( stack, region, &dest );
+
+ if (!dfb_region_intersect( &dest, 0, 0,
+ state->destination->config.size.w - 1, state->destination->config.size.h - 1 ))
+ return;
+
+ switch (stack->bg.mode) {
+ case DLBM_COLOR: {
+ DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &dest );
+ CoreSurface *dst = state->destination;
+ DFBColor *color = &stack->bg.color;
+
+ D_MAGIC_ASSERT( dst, CoreSurface );
+
+ /* Set the background color. */
+ if (DFB_PIXELFORMAT_IS_INDEXED( dst->config.format ))
+ dfb_state_set_color_index( state, /* FIXME: don't search every time */
+ dfb_palette_search( dst->palette, color->r,
+ color->g, color->b, color->a ) );
+ else
+ dfb_state_set_color( state, color );
+
+ /* Simply fill the background. */
+ dfb_gfxcard_fillrectangles( &rect, 1, state );
+ break;
+ }
+
+ case DLBM_IMAGE: {
+ CoreSurface *bg = stack->bg.image;
+ DFBRegion clip = state->clip;
+ DFBRectangle src = { 0, 0, bg->config.size.w, bg->config.size.h };
+ DFBRectangle dst = { 0, 0, stack->rotated_width, stack->rotated_height };
+
+ D_MAGIC_ASSERT( bg, CoreSurface );
+
+ /* Set blitting source. */
+ state->source = bg;
+ state->modified |= SMF_SOURCE;
+
+ /* Set blitting flags. */
+ dfb_state_set_blitting_flags( state, stack->rotated_blit );
+
+ /* Set clipping region. */
+ dfb_state_set_clip( state, &dest );
+
+ /* Blit background image. */
+ dfb_gfxcard_stretchblit( &src, &dst, state );
+
+ /* Restore clipping region. */
+ dfb_state_set_clip( state, &clip );
+
+ /* Reset blitting source. */
+ state->source = NULL;
+ state->modified |= SMF_SOURCE;
+
+ break;
+ }
+
+ case DLBM_TILE: {
+ CoreSurface *bg = stack->bg.image;
+ DFBRegion clip = state->clip;
+ DFBRectangle src = { 0, 0, bg->config.size.w, bg->config.size.h };
+
+ D_MAGIC_ASSERT( bg, CoreSurface );
+
+ /* Set blitting source. */
+ state->source = bg;
+ state->modified |= SMF_SOURCE;
+
+ /* Set blitting flags. */
+ dfb_state_set_blitting_flags( state, stack->rotated_blit );
+
+ /* Change clipping region. */
+ dfb_state_set_clip( state, &dest );
+
+ /* Tiled blit (aligned). */
+ dfb_gfxcard_tileblit( &src,
+ (region->x1 / src.w) * src.w,
+ (region->y1 / src.h) * src.h,
+ (region->x2 / src.w + 1) * src.w,
+ (region->y2 / src.h + 1) * src.h,
+ state );
+
+ /* Restore clipping region. */
+ dfb_state_set_clip( state, &clip );
+
+ /* Reset blitting source. */
+ state->source = NULL;
+ state->modified |= SMF_SOURCE;
+
+ break;
+ }
+
+ case DLBM_DONTCARE:
+ break;
+
+ default:
+ D_BUG( "unknown background mode" );
+ break;
+ }
+}
+
+static void
+update_region( CoreWindowStack *stack,
+ StackData *data,
+ CardState *state,
+ int start,
+ int x1,
+ int y1,
+ int x2,
+ int y2 )
+{
+ int i = start;
+ DFBRegion region = { x1, y1, x2, y2 };
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_MAGIC_ASSERT( state, CardState );
+ D_ASSERT( start < fusion_vector_size( &data->windows ) );
+ D_ASSERT( x1 <= x2 );
+ D_ASSERT( y1 <= y2 );
+
+ /* Find next intersecting window. */
+ while (i >= 0) {
+ CoreWindow *window = fusion_vector_at( &data->windows, i );
+
+ if (VISIBLE_WINDOW( window )) {
+ DFBRectangle rotated;
+
+ transform_window_to_stack( window, &window->config.bounds, &rotated );
+
+ if (dfb_region_intersect( &region,
+ DFB_REGION_VALS_FROM_RECTANGLE( &rotated )))
+ break;
+ }
+
+ i--;
+ }
+
+ /* Intersecting window found? */
+ if (i >= 0) {
+ CoreWindow *window = fusion_vector_at( &data->windows, i );
+ CoreWindowConfig *config = &window->config;
+
+ if (D_FLAGS_ARE_SET( config->options, DWOP_ALPHACHANNEL | DWOP_OPAQUE_REGION )) {
+ DFBRegion opaque = DFB_REGION_INIT_TRANSLATED( &config->opaque,
+ config->bounds.x,
+ config->bounds.y );
+
+ if (!dfb_region_region_intersect( &opaque, &region )) {
+ update_region( stack, data, state, i-1, x1, y1, x2, y2 );
+
+ draw_window( window, state, &region, true );
+ }
+ else {
+ if ((config->opacity < 0xff) || (config->options & DWOP_COLORKEYING)) {
+ /* draw everything below */
+ update_region( stack, data, state, i-1, x1, y1, x2, y2 );
+ }
+ else {
+ /* left */
+ if (opaque.x1 != x1)
+ update_region( stack, data, state, i-1, x1, opaque.y1, opaque.x1-1, opaque.y2 );
+
+ /* upper */
+ if (opaque.y1 != y1)
+ update_region( stack, data, state, i-1, x1, y1, x2, opaque.y1-1 );
+
+ /* right */
+ if (opaque.x2 != x2)
+ update_region( stack, data, state, i-1, opaque.x2+1, opaque.y1, x2, opaque.y2 );
+
+ /* lower */
+ if (opaque.y2 != y2)
+ update_region( stack, data, state, i-1, x1, opaque.y2+1, x2, y2 );
+ }
+
+ /* left */
+ if (opaque.x1 != region.x1) {
+ DFBRegion r = { region.x1, opaque.y1, opaque.x1 - 1, opaque.y2 };
+ draw_window( window, state, &r, true );
+ }
+
+ /* upper */
+ if (opaque.y1 != region.y1) {
+ DFBRegion r = { region.x1, region.y1, region.x2, opaque.y1 - 1 };
+ draw_window( window, state, &r, true );
+ }
+
+ /* right */
+ if (opaque.x2 != region.x2) {
+ DFBRegion r = { opaque.x2 + 1, opaque.y1, region.x2, opaque.y2 };
+ draw_window( window, state, &r, true );
+ }
+
+ /* lower */
+ if (opaque.y2 != region.y2) {
+ DFBRegion r = { region.x1, opaque.y2 + 1, region.x2, region.y2 };
+ draw_window( window, state, &r, true );
+ }
+
+ /* inner */
+ draw_window( window, state, &opaque, false );
+ }
+ }
+ else {
+ if (TRANSLUCENT_WINDOW( window )) {
+ /* draw everything below */
+ update_region( stack, data, state, i-1, x1, y1, x2, y2 );
+ }
+ else {
+ /* left */
+ if (region.x1 != x1)
+ update_region( stack, data, state, i-1, x1, region.y1, region.x1-1, region.y2 );
+
+ /* upper */
+ if (region.y1 != y1)
+ update_region( stack, data, state, i-1, x1, y1, x2, region.y1-1 );
+
+ /* right */
+ if (region.x2 != x2)
+ update_region( stack, data, state, i-1, region.x2+1, region.y1, x2, region.y2 );
+
+ /* lower */
+ if (region.y2 != y2)
+ update_region( stack, data, state, i-1, x1, region.y2+1, x2, y2 );
+ }
+
+ draw_window( window, state, &region, true );
+ }
+ }
+ else
+ draw_background( stack, state, &region );
+}
+
+/**************************************************************************************************/
+/**************************************************************************************************/
+
+static void
+repaint_stack( CoreWindowStack *stack,
+ StackData *data,
+ CoreLayerRegion *region,
+ const DFBRegion *updates,
+ int num_updates,
+ DFBSurfaceFlipFlags flags )
+{
+ int i;
+ CoreLayer *layer;
+ CardState *state;
+ CoreSurface *surface;
+ DFBRegion flips[num_updates];
+ int num_flips = 0;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( stack->context != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( region != NULL );
+ D_ASSERT( num_updates > 0 );
+
+ layer = dfb_layer_at( stack->context->layer_id );
+ state = &layer->state;
+ surface = region->surface;
+
+ if (!data->active || !surface)
+ return;
+
+ D_DEBUG_AT( WM_Default, "repaint_stack( %d region(s), flags %x )\n", num_updates, flags );
+
+ /* Set destination. */
+ state->destination = surface;
+ state->modified |= SMF_DESTINATION;
+
+ for (i=0; i<num_updates; i++) {
+ DFBRegion dest;
+ const DFBRegion *update = &updates[i];
+
+ DFB_REGION_ASSERT( update );
+
+ D_DEBUG_AT( WM_Default, " -> %d, %d - %dx%d (%d)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( update ), i );
+
+ transform_stack_to_dest( stack, update, &dest );
+
+ if (!dfb_region_intersect( &dest, 0, 0, surface->config.size.w - 1, surface->config.size.h - 1 ))
+ continue;
+
+ /* Set clipping region. */
+ dfb_state_set_clip( state, &dest );
+
+ /* Compose updated region. */
+ update_region( stack, data, state,
+ fusion_vector_size( &data->windows ) - 1,
+ DFB_REGION_VALS( update ) );
+
+ flips[num_flips++] = dest;
+
+ /* Update cursor? */
+ if (data->cursor_drawn) {
+ DFBRegion cursor_rotated;
+
+ D_ASSUME( data->cursor_bs_valid );
+
+ transform_stack_to_dest( stack, &data->cursor_region, &cursor_rotated );
+
+ if (dfb_region_region_intersect( &dest, &cursor_rotated )) {
+ DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &dest );
+
+ dfb_gfx_copy_to( surface, data->cursor_bs, &rect,
+ rect.x - cursor_rotated.x1,
+ rect.y - cursor_rotated.y1, true );
+
+ draw_cursor( stack, data, state, &data->cursor_region );
+ }
+ }
+ }
+
+ /* Reset destination. */
+ state->destination = NULL;
+ state->modified |= SMF_DESTINATION;
+
+ /* Software cursor code relies on a valid back buffer. */
+ if (stack->cursor.enabled)
+ flags |= DSFLIP_BLIT;
+
+ for (i=0; i<num_flips; i++) {
+ const DFBRegion *flip = &flips[i];
+
+ DFB_REGION_ASSERT( flip );
+
+ /* Flip the updated region .*/
+ dfb_layer_region_flip_update( region, flip, flags );
+ }
+}
+
+static DFBResult
+process_updates( StackData *data,
+ WMData *wmdata,
+ CoreWindowStack *stack,
+ CoreLayerRegion *region,
+ DFBSurfaceFlipFlags flags )
+{
+ DFBResult ret;
+ int n, d;
+ int total;
+ int bounding;
+ CoreLayerContext *context;
+ CoreLayerRegion *primary = region;
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( wmdata != NULL );
+ D_ASSERT( stack != NULL );
+
+ context = stack->context;
+ D_ASSERT( context != NULL );
+
+ if (!data->updates.num_regions)
+ return DFB_OK;
+
+ /* Get the primary region. */
+ if (!region) {
+ ret = dfb_layer_context_get_primary_region( stack->context, false, &primary );
+ if (ret)
+ return ret;
+ }
+
+
+ dfb_updates_stat( &data->updates, &total, &bounding );
+
+ n = data->updates.max_regions - data->updates.num_regions + 1;
+ d = n + 1;
+
+ /* FIXME: depend on buffer mode, hw accel etc. */
+ if (total > stack->width * stack->height * 9 / 10) {
+ DFBRegion region = { 0, 0, stack->width - 1, stack->height - 1 };
+
+// direct_log_printf( NULL, "%s() <- %d regions, total %d, bounding %d (%d/%d: %d), FULL UPDATE\n",
+// __FUNCTION__, data->updates.num_regions, total, bounding, n, d, bounding*n/d );
+
+// if (context->config.buffermode == DLBM_FRONTONLY)
+// dfb_region_transpose(&region, context->rotation);
+
+ repaint_stack( stack, data, primary, &region, 1, flags );
+ }
+ else if (data->updates.num_regions < 2 || total < bounding * n / d)
+ repaint_stack( stack, data, primary, data->updates.regions, data->updates.num_regions, flags );
+ else {
+// direct_log_printf( NULL, "%s() <- %d regions, total %d, bounding %d (%d/%d: %d)\n",
+// __FUNCTION__, data->updates.num_regions, total, bounding, n, d, bounding*n/d );
+
+ repaint_stack( stack, data, primary, &data->updates.bounding, 1, flags );
+ }
+
+
+ dfb_updates_reset( &data->updates );
+
+ /* Unref primary region. */
+ if (!region)
+ dfb_layer_region_unref( primary );
+
+ return DFB_OK;
+}
+
+/*
+ skipping opaque windows that are above the window that changed
+*/
+static void
+wind_of_change( CoreWindowStack *stack,
+ StackData *data,
+ CoreLayerRegion *region,
+ DFBRegion *update,
+ DFBSurfaceFlipFlags flags,
+ int current,
+ int changed )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( region != NULL );
+ D_ASSERT( update != NULL );
+
+ /*
+ loop through windows above
+ */
+ for (; current > changed; current--) {
+ CoreWindow *window;
+ CoreWindowConfig *config;
+ DFBRegion opaque;
+ DFBRectangle rotated;
+ DFBRectangle *bounds = &rotated;
+ DFBWindowOptions options;
+
+ D_ASSERT( changed >= 0 );
+ D_ASSERT( current >= changed );
+ D_ASSERT( current < fusion_vector_size( &data->windows ) );
+
+ window = fusion_vector_at( &data->windows, current );
+ config = &window->config;
+ options = config->options;
+
+ transform_window_to_stack( window, &config->bounds, &rotated );
+
+ /*
+ can skip opaque region
+ */
+ if ((
+ //can skip all opaque window?
+ (config->opacity == 0xff) &&
+ !(options & (DWOP_COLORKEYING | DWOP_ALPHACHANNEL)) &&
+ (opaque=*update,dfb_region_intersect( &opaque,
+ bounds->x, bounds->y,
+ bounds->x + bounds->w - 1,
+ bounds->y + bounds->h -1 ) )
+ )||(
+ //can skip opaque region?
+ (options & DWOP_ALPHACHANNEL) &&
+ (options & DWOP_OPAQUE_REGION) &&
+ (config->opacity == 0xff) &&
+ !(options & DWOP_COLORKEYING) &&
+ (opaque=*update,dfb_region_intersect( &opaque,
+ bounds->x + config->opaque.x1,
+ bounds->y + config->opaque.y1,
+ bounds->x + config->opaque.x2,
+ bounds->y + config->opaque.y2 ))
+ ))
+ {
+ /* left */
+ if (opaque.x1 != update->x1) {
+ DFBRegion left = { update->x1, opaque.y1, opaque.x1-1, opaque.y2};
+ wind_of_change( stack, data, region, &left, flags, current-1, changed );
+ }
+ /* upper */
+ if (opaque.y1 != update->y1) {
+ DFBRegion upper = { update->x1, update->y1, update->x2, opaque.y1-1};
+ wind_of_change( stack, data, region, &upper, flags, current-1, changed );
+ }
+ /* right */
+ if (opaque.x2 != update->x2) {
+ DFBRegion right = { opaque.x2+1, opaque.y1, update->x2, opaque.y2};
+ wind_of_change( stack, data, region, &right, flags, current-1, changed );
+ }
+ /* lower */
+ if (opaque.y2 != update->y2) {
+ DFBRegion lower = { update->x1, opaque.y2+1, update->x2, update->y2};
+ wind_of_change( stack, data, region, &lower, flags, current-1, changed );
+ }
+
+ return;
+ }
+ }
+
+ dfb_updates_add( &data->updates, update );
+}
+
+static void
+repaint_stack_for_window( CoreWindowStack *stack,
+ StackData *data,
+ CoreLayerRegion *region,
+ DFBRegion *update,
+ DFBSurfaceFlipFlags flags,
+ int window )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( region != NULL );
+ D_ASSERT( update != NULL );
+ D_ASSERT( window >= 0 );
+ D_ASSERT( window < fusion_vector_size( &data->windows ) );
+
+ if (fusion_vector_has_elements( &data->windows ) && window >= 0) {
+ int num = fusion_vector_size( &data->windows );
+
+ D_ASSERT( window < num );
+
+ wind_of_change( stack, data, region, update, flags, num - 1, window );
+ }
+ else
+ dfb_updates_add( &data->updates, update );
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+update_window( CoreWindow *window,
+ WindowData *window_data,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags,
+ bool force_complete,
+ bool force_invisible,
+ bool scale_region )
+{
+ DFBRegion area;
+ DFBRegion update;
+ StackData *data;
+ CoreWindowStack *stack;
+ DFBRectangle *bounds;
+ DFBDimension size;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( window_data->stack_data != NULL );
+ D_ASSERT( window_data->stack_data->stack != NULL );
+
+ DFB_REGION_ASSERT_IF( region );
+
+ data = window_data->stack_data;
+ stack = data->stack;
+
+ if (!VISIBLE_WINDOW(window) && !force_invisible)
+ return DFB_OK;
+
+ if (stack->hw_mode)
+ return DFB_OK;
+
+ bounds = &window->config.bounds;
+ size.w = bounds->w;
+ size.h = bounds->h;
+
+ if (region) {
+ if (scale_region && (window->config.options & DWOP_SCALE)) {
+ int sw = window->surface->config.size.w;
+ int sh = window->surface->config.size.h;
+
+ /* horizontal */
+ if (bounds->w > sw) {
+ /* upscaling */
+ area.x1 = (region->x1 - 1) * bounds->w / sw;
+ area.x2 = (region->x2 + 1) * bounds->w / sw;
+ }
+ else {
+ /* downscaling */
+ area.x1 = region->x1 * bounds->w / sw - 1;
+ area.x2 = region->x2 * bounds->w / sw + 1;
+ }
+
+ /* vertical */
+ if (bounds->h > sh) {
+ /* upscaling */
+ area.y1 = (region->y1 - 1) * bounds->h / sh;
+ area.y2 = (region->y2 + 1) * bounds->h / sh;
+ }
+ else {
+ /* downscaling */
+ area.y1 = region->y1 * bounds->h / sh - 1;
+ area.y2 = region->y2 * bounds->h / sh + 1;
+ }
+
+ /* limit to window area */
+ dfb_region_clip( &area, 0, 0, bounds->w - 1, bounds->h - 1 );
+ }
+ else
+ area = *region;
+ }
+ else {
+ area.x1 = area.y1 = 0;
+ area.x2 = bounds->w - 1;
+ area.y2 = bounds->h - 1;
+ }
+
+ dfb_region_from_rotated( &update, &area, &size, window->config.rotation );
+
+ /* screen offset */
+ dfb_region_translate( &update, bounds->x, bounds->y );
+
+ if (!dfb_unsafe_region_intersect( &update, 0, 0, stack->width - 1, stack->height - 1 ))
+ return DFB_OK;
+
+ if (force_complete)
+ dfb_updates_add( &data->updates, &update );
+ else
+ repaint_stack_for_window( stack, data, window->primary_region,
+ &update, flags, get_index( data, window ) );
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+/**************************************************************************************************/
+
+static void
+insert_window( CoreWindowStack *stack,
+ StackData *data,
+ CoreWindow *window,
+ WindowData *window_data )
+{
+ int index;
+ CoreWindow *other;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+
+ /*
+ * Iterate from bottom to top,
+ * stopping at the first window with a higher priority.
+ */
+ fusion_vector_foreach (other, index, data->windows) {
+ WindowData *other_data = other->window_data;
+
+ D_ASSERT( other->window_data != NULL );
+
+ if (other_data->priority > window_data->priority)
+ break;
+ }
+
+ /* Insert the window at the acquired position. */
+ fusion_vector_insert( &data->windows, window, index );
+}
+
+static void
+withdraw_window( CoreWindowStack *stack,
+ StackData *data,
+ CoreWindow *window,
+ WindowData *window_data )
+{
+ int i;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+
+ D_ASSERT( window->stack != NULL );
+
+ D_ASSERT( DFB_WINDOW_INITIALIZED( window ) );
+
+ /* No longer be the 'entered window'. */
+ if (data->entered_window == window)
+ data->entered_window = NULL;
+
+ /* Remove focus from window. */
+ if (data->focused_window == window)
+ data->focused_window = NULL;
+
+ /* Release explicit keyboard grab. */
+ if (data->keyboard_window == window)
+ data->keyboard_window = NULL;
+
+ /* Release explicit pointer grab. */
+ if (data->pointer_window == window)
+ data->pointer_window = NULL;
+
+ /* Release all implicit key grabs. */
+ for (i=0; i<MAX_KEYS; i++) {
+ if (data->keys[i].code != -1 && data->keys[i].owner == window) {
+ if (!DFB_WINDOW_DESTROYED( window )) {
+ DFBWindowEvent we;
+
+ we.type = DWET_KEYUP;
+ we.key_code = data->keys[i].code;
+ we.key_id = data->keys[i].id;
+ we.key_symbol = data->keys[i].symbol;
+
+ post_event( window, data, &we );
+ }
+
+ data->keys[i].code = -1;
+ data->keys[i].owner = NULL;
+ }
+ }
+
+ /* Release grab of unselected keys. */
+ if (data->unselkeys_window == window)
+ data->unselkeys_window = NULL;
+}
+
+static void
+remove_window( CoreWindowStack *stack,
+ StackData *data,
+ CoreWindow *window,
+ WindowData *window_data )
+{
+ DirectLink *l, *n;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+
+ D_ASSERT( window->config.opacity == 0 );
+ D_ASSERT( DFB_WINDOW_INITIALIZED( window ) );
+
+ D_ASSERT( fusion_vector_contains( &data->windows, window ) );
+
+ /* Release implicit grabs, focus etc. */
+ withdraw_window( stack, data, window, window_data );
+
+ /* Release all explicit key grabs. */
+ direct_list_foreach_safe (l, n, data->grabbed_keys) {
+ GrabbedKey *key = (GrabbedKey*) l;
+
+ if (key->owner == window) {
+ direct_list_remove( &data->grabbed_keys, &key->link );
+ SHFREE( stack->shmpool, key );
+ }
+ }
+
+ fusion_vector_remove( &data->windows, fusion_vector_index_of( &data->windows, window ) );
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+move_window( CoreWindow *window,
+ WindowData *data,
+ int dx,
+ int dy )
+{
+ DFBResult ret;
+ DFBWindowEvent evt;
+ DFBRectangle *bounds = &window->config.bounds;
+
+ if (window->region) {
+ data->config.dest.x += dx;
+ data->config.dest.y += dy;
+
+ ret = dfb_layer_region_set_configuration( window->region, &data->config, CLRCF_DEST );
+ if (ret) {
+ data->config.dest.x -= dx;
+ data->config.dest.y -= dy;
+
+ return ret;
+ }
+
+ bounds->x += dx;
+ bounds->y += dy;
+ }
+ else {
+ update_window( window, data, NULL, 0, false, false, false );
+
+ bounds->x += dx;
+ bounds->y += dy;
+
+ update_window( window, data, NULL, 0, false, false, false );
+ }
+
+ /* Send new position */
+ evt.type = DWET_POSITION;
+ evt.x = bounds->x;
+ evt.y = bounds->y;
+
+ post_event( window, data->stack_data, &evt );
+
+ return DFB_OK;
+}
+
+static DFBResult
+resize_window( CoreWindow *window,
+ WMData *wm_data,
+ WindowData *data,
+ int width,
+ int height )
+{
+ DFBResult ret;
+ DFBWindowEvent evt;
+ CoreWindowStack *stack = window->stack;
+ DFBRectangle *bounds = &window->config.bounds;
+ int ow = bounds->w;
+ int oh = bounds->h;
+
+ D_DEBUG_AT( WM_Default, "resize_window( %d, %d )\n", width, height );
+
+ D_ASSERT( wm_data != NULL );
+
+ D_MAGIC_ASSERT( data, WindowData );
+
+ D_ASSERT( width > 0 );
+ D_ASSERT( height > 0 );
+
+ if (width > 4096 || height > 4096)
+ return DFB_LIMITEXCEEDED;
+
+ if (window->surface && !(window->config.options & DWOP_SCALE)) {
+ CoreSurfaceConfig config;
+
+ config.flags = CSCONF_SIZE;
+ config.size.w = width;
+ config.size.h = height;
+
+ ret = dfb_surface_reconfig( window->surface, &config );
+ if (ret)
+ return ret;
+ }
+
+ if (window->region) {
+ data->config.dest.w = data->config.source.w = data->config.width = width;
+ data->config.dest.h = data->config.source.h = data->config.height = height;
+
+ ret = dfb_layer_region_set_configuration( window->region, &data->config,
+ CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_SURFACE |
+ CLRCF_DEST | CLRCF_SOURCE );
+ if (ret) {
+ data->config.dest.w = data->config.source.w = data->config.width = bounds->w = ow;
+ data->config.dest.h = data->config.source.h = data->config.height = bounds->h = oh;
+
+ return ret;
+ }
+ }
+ else {
+ dfb_region_intersect( &window->config.opaque, 0, 0, width - 1, height - 1 );
+
+ if (VISIBLE_WINDOW (window)) {
+ if (ow > width) {
+ DFBRegion region = { width, 0, ow - 1, MIN(height, oh) - 1 };
+
+ update_window( window, data, &region, 0, false, false, false );
+ }
+
+ if (oh > height) {
+ DFBRegion region = { 0, height, MAX(width, ow) - 1, oh - 1 };
+
+ update_window( window, data, &region, 0, false, false, false );
+ }
+ }
+ }
+
+ bounds->w = width;
+ bounds->h = height;
+
+ /* Send new size */
+ evt.type = DWET_SIZE;
+ evt.w = bounds->w;
+ evt.h = bounds->h;
+
+ post_event( window, data->stack_data, &evt );
+
+ update_focus( stack, data->stack_data, wm_data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+set_window_bounds( CoreWindow *window,
+ WMData *wm_data,
+ WindowData *data,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ DFBResult ret;
+ DFBWindowEvent evt;
+ CoreWindowStack *stack = window->stack;
+ DFBRegion old_region;
+ DFBRegion new_region;
+
+ D_DEBUG_AT( WM_Default, "%s( %p [%d] %d, %d - %dx%d )\n", __FUNCTION__, window, window->id, x, y, width, height );
+
+ D_ASSERT( wm_data != NULL );
+
+ D_MAGIC_ASSERT( data, WindowData );
+
+ D_ASSERT( width > 0 );
+ D_ASSERT( height > 0 );
+
+ if (width > 4096 || height > 4096)
+ return DFB_LIMITEXCEEDED;
+
+ if (window->surface && !(window->config.options & DWOP_SCALE)) {
+ ret = dfb_surface_reformat( window->surface,
+ width, height, window->surface->config.format );
+ if (ret)
+ return ret;
+ }
+
+ old_region.x1 = window->config.bounds.x - x;
+ old_region.y1 = window->config.bounds.y - y;
+ old_region.x2 = old_region.x1 + window->config.bounds.w - 1;
+ old_region.y2 = old_region.y1 + window->config.bounds.h - 1;
+
+ window->config.bounds.x = x;
+ window->config.bounds.y = y;
+ window->config.bounds.w = width;
+ window->config.bounds.h = height;
+
+ new_region.x1 = 0;
+ new_region.y1 = 0;
+ new_region.x2 = width - 1;
+ new_region.y2 = height - 1;
+
+ if (!dfb_region_region_intersect( &window->config.opaque, &new_region ))
+ window->config.opaque = new_region;
+
+ /* Update exposed area. */
+ if (VISIBLE_WINDOW( window )) {
+ if (dfb_region_region_intersect( &new_region, &old_region )) {
+ /* left */
+ if (new_region.x1 > old_region.x1) {
+ DFBRegion region = { old_region.x1, old_region.y1,
+ new_region.x1 - 1, new_region.y2 };
+
+ update_window( window, data, &region, 0, false, false, false );
+ }
+
+ /* upper */
+ if (new_region.y1 > old_region.y1) {
+ DFBRegion region = { old_region.x1, old_region.y1,
+ old_region.x2, new_region.y1 - 1 };
+
+ update_window( window, data, &region, 0, false, false, false );
+ }
+
+ /* right */
+ if (new_region.x2 < old_region.x2) {
+ DFBRegion region = { new_region.x2 + 1, new_region.y1,
+ old_region.x2, new_region.y2 };
+
+ update_window( window, data, &region, 0, false, false, false );
+ }
+
+ /* lower */
+ if (new_region.y2 < old_region.y2) {
+ DFBRegion region = { old_region.x1, new_region.y2 + 1,
+ old_region.x2, old_region.y2 };
+
+ update_window( window, data, &region, 0, false, false, false );
+ }
+ }
+ else
+ update_window( window, data, &old_region, 0, false, false, false );
+ }
+
+ /* Send new position and size */
+ evt.type = DWET_POSITION_SIZE;
+ evt.x = window->config.bounds.x;
+ evt.y = window->config.bounds.y;
+ evt.w = window->config.bounds.w;
+ evt.h = window->config.bounds.h;
+
+ post_event( window, data->stack_data, &evt );
+
+ update_focus( stack, data->stack_data, wm_data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+restack_window( CoreWindow *window,
+ WindowData *window_data,
+ CoreWindow *relative,
+ WindowData *relative_data,
+ int relation,
+ DFBWindowStackingClass stacking )
+{
+ StackData *data;
+ int old;
+ int index;
+ int priority;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( window_data->stack_data != NULL );
+
+ D_ASSERT( relative == NULL || relative_data != NULL );
+
+ D_ASSERT( relative == NULL || relative == window || relation != 0);
+
+ data = window_data->stack_data;
+
+ /* Change stacking class. */
+ if (stacking != window->config.stacking) {
+ window->config.stacking = stacking;
+
+ window_data->priority = get_priority( window );
+ }
+
+ /* Get the (new) priority. */
+ priority = window_data->priority;
+
+ /* Get the old index. */
+ old = get_index( data, window );
+
+ /* Calculate the desired index. */
+ if (relative) {
+ index = get_index( data, relative );
+
+ if (relation > 0) {
+ if (old < index)
+ index--;
+ }
+ else if (relation < 0) {
+ if (old > index)
+ index++;
+ }
+
+ index += relation;
+
+ if (index < 0)
+ index = 0;
+ else if (index > fusion_vector_size( &data->windows ) - 1)
+ index = fusion_vector_size( &data->windows ) - 1;
+ }
+ else if (relation)
+ index = fusion_vector_size( &data->windows ) - 1;
+ else
+ index = 0;
+
+ /* Assure window won't be above any window with a higher priority. */
+ while (index > 0) {
+ int below = (old < index) ? index : index - 1;
+ CoreWindow *other = fusion_vector_at( &data->windows, below );
+ WindowData *other_data = other->window_data;
+
+ D_ASSERT( other->window_data != NULL );
+
+ if (priority < other_data->priority)
+ index--;
+ else
+ break;
+ }
+
+ /* Assure window won't be below any window with a lower priority. */
+ while (index < fusion_vector_size( &data->windows ) - 1) {
+ int above = (old > index) ? index : index + 1;
+ CoreWindow *other = fusion_vector_at( &data->windows, above );
+ WindowData *other_data = other->window_data;
+
+ D_ASSERT( other->window_data != NULL );
+
+ if (priority > other_data->priority)
+ index++;
+ else
+ break;
+ }
+
+ /* Return if index hasn't changed. */
+ if (index == old)
+ return DFB_OK;
+
+ /* Actually change the stacking order now. */
+ fusion_vector_move( &data->windows, old, index );
+
+ update_window( window, window_data, NULL, DSFLIP_NONE, (index < old), false, false );
+
+ return DFB_OK;
+}
+
+static void
+set_opacity( CoreWindow *window,
+ WindowData *window_data,
+ WMData *wmdata,
+ u8 opacity )
+{
+ u8 old;
+ StackData *data;
+ CoreWindowStack *stack;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( window_data->stack_data != NULL );
+ D_ASSERT( window_data->stack_data->stack != NULL );
+
+ old = window->config.opacity;
+ data = window_data->stack_data;
+ stack = data->stack;
+
+ if (!stack->hw_mode && !dfb_config->translucent_windows && opacity)
+ opacity = 0xFF;
+
+ if (old != opacity) {
+ bool show = !old && opacity;
+ bool hide = old && !opacity;
+
+ window->config.opacity = opacity;
+
+ if (window->region) {
+ window_data->config.opacity = opacity;
+
+ dfb_layer_region_set_configuration( window->region, &window_data->config, CLRCF_OPACITY );
+ }
+ else
+ update_window( window, window_data, NULL, DSFLIP_NONE, false, true, false );
+
+
+ /* Check focus after window appeared or disappeared */
+ if (show || hide)
+ update_focus( stack, data, wmdata );
+
+ /* If window disappeared... */
+ if (hide) {
+ /* Ungrab pointer/keyboard */
+ withdraw_window( stack, data, window, window_data );
+
+ /* Always try to have a focused window */
+ ensure_focus( stack, data );
+ }
+ }
+}
+
+static DFBResult
+grab_keyboard( CoreWindow *window,
+ WindowData *window_data )
+{
+ StackData *data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( window_data->stack_data != NULL );
+
+ data = window_data->stack_data;
+
+ if (data->keyboard_window)
+ return DFB_LOCKED;
+
+ data->keyboard_window = window;
+
+ return DFB_OK;
+}
+
+static DFBResult
+ungrab_keyboard( CoreWindow *window,
+ WindowData *window_data )
+{
+ StackData *data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( window_data->stack_data != NULL );
+
+ data = window_data->stack_data;
+
+ if (data->keyboard_window == window)
+ data->keyboard_window = NULL;
+
+ return DFB_OK;
+}
+
+static DFBResult
+grab_pointer( CoreWindow *window,
+ WindowData *window_data )
+{
+ StackData *data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( window_data->stack_data != NULL );
+
+ data = window_data->stack_data;
+
+ if (data->pointer_window)
+ return DFB_LOCKED;
+
+ data->pointer_window = window;
+
+ return DFB_OK;
+}
+
+static DFBResult
+ungrab_pointer( CoreWindow *window,
+ WindowData *window_data,
+ WMData *wmdata )
+{
+ StackData *data;
+ CoreWindowStack *stack;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( window_data->stack_data != NULL );
+
+ data = window_data->stack_data;
+ stack = data->stack;
+
+ if (data->pointer_window == window) {
+ data->pointer_window = NULL;
+
+ /* Possibly change focus to window that's now under the cursor */
+ update_focus( stack, data, wmdata );
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+grab_key( CoreWindow *window,
+ WindowData *window_data,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers )
+{
+ int i;
+ StackData *data;
+ GrabbedKey *grab;
+ CoreWindowStack *stack;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( window_data->stack_data != NULL );
+ D_ASSERT( window_data->stack_data->stack != NULL );
+
+ data = window_data->stack_data;
+ stack = data->stack;
+
+ /* Reject if already grabbed. */
+ direct_list_foreach (grab, data->grabbed_keys)
+ if (grab->symbol == symbol && grab->modifiers == modifiers)
+ return DFB_LOCKED;
+
+ /* Allocate grab information. */
+ grab = SHCALLOC( stack->shmpool, 1, sizeof(GrabbedKey) );
+
+ /* Fill grab information. */
+ grab->symbol = symbol;
+ grab->modifiers = modifiers;
+ grab->owner = window;
+
+ /* Add to list of key grabs. */
+ direct_list_append( &data->grabbed_keys, &grab->link );
+
+ /* Remove implicit grabs for this key. */
+ for (i=0; i<MAX_KEYS; i++)
+ if (data->keys[i].code != -1 && data->keys[i].symbol == symbol)
+ data->keys[i].code = -1;
+
+ return DFB_OK;
+}
+
+static DFBResult
+ungrab_key( CoreWindow *window,
+ WindowData *window_data,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers )
+{
+ DirectLink *l;
+ StackData *data;
+ CoreWindowStack *stack;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( window_data->stack_data != NULL );
+ D_ASSERT( window_data->stack_data->stack != NULL );
+
+ data = window_data->stack_data;
+ stack = data->stack;
+
+ direct_list_foreach (l, data->grabbed_keys) {
+ GrabbedKey *key = (GrabbedKey*) l;
+
+ if (key->symbol == symbol && key->modifiers == modifiers && key->owner == window) {
+ direct_list_remove( &data->grabbed_keys, &key->link );
+ SHFREE( stack->shmpool, key );
+ return DFB_OK;
+ }
+ }
+
+ return DFB_IDNOTFOUND;
+}
+
+static DFBResult
+request_focus( CoreWindow *window,
+ WindowData *window_data )
+{
+ StackData *data;
+ CoreWindowStack *stack;
+ CoreWindow *entered;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( !(window->config.options & DWOP_GHOST) );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( window_data->stack_data != NULL );
+
+ data = window_data->stack_data;
+ stack = data->stack;
+
+ switch_focus( stack, data, window );
+
+ entered = data->entered_window;
+
+ if (entered && entered != window) {
+ DFBWindowEvent we;
+
+ we.type = DWET_LEAVE;
+ we.x = stack->cursor.x - entered->config.bounds.x;
+ we.y = stack->cursor.y - entered->config.bounds.y;
+
+ transform_point_in_window( entered, &we.x, &we.y );
+
+ post_event( entered, data, &we );
+
+ data->entered_window = NULL;
+ }
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+/**************************************************************************************************/
+
+static bool
+handle_wm_key( CoreWindowStack *stack,
+ StackData *data,
+ WMData *wmdata,
+ const DFBInputEvent *event )
+{
+ int i, num;
+ CoreWindow *entered;
+ CoreWindow *focused;
+ CoreWindow *window;
+ DFBRegion region;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( data->wm_level > 0 );
+ D_ASSERT( event != NULL );
+ D_ASSERT( event->type == DIET_KEYPRESS );
+
+ entered = data->entered_window;
+ focused = data->focused_window;
+
+ switch (DFB_LOWER_CASE(event->key_symbol)) {
+ case DIKS_SMALL_X:
+ num = fusion_vector_size( &data->windows );
+
+ if (data->wm_cycle <= 0)
+ data->wm_cycle = num;
+
+ if (num) {
+ int looped = 0;
+ int index = MIN( num, data->wm_cycle );
+
+ while (index--) {
+ CoreWindow *window = fusion_vector_at( &data->windows, index );
+
+ if ((window->config.options & (DWOP_GHOST | DWOP_KEEP_STACKING)) ||
+ ! VISIBLE_WINDOW(window) || window == data->focused_window)
+ {
+ if (index == 0 && !looped) {
+ looped = 1;
+ index = num - 1;
+ }
+
+ continue;
+ }
+
+ restack_window( window, window->window_data,
+ NULL, NULL, 1, window->config.stacking );
+ request_focus( window, window->window_data );
+
+ break;
+ }
+
+ data->wm_cycle = index;
+ }
+ break;
+
+ case DIKS_SMALL_S:
+ fusion_vector_foreach (window, i, data->windows) {
+ if (VISIBLE_WINDOW(window) && window->config.stacking == DWSC_MIDDLE &&
+ ! (window->config.options & (DWOP_GHOST | DWOP_KEEP_STACKING)))
+ {
+ restack_window( window, window->window_data,
+ NULL, NULL, 1, window->config.stacking );
+ request_focus( window, window->window_data );
+
+ break;
+ }
+ }
+ break;
+
+ case DIKS_SMALL_C:
+ if (entered) {
+ DFBWindowEvent event;
+
+ event.type = DWET_CLOSE;
+
+ post_event( entered, data, &event );
+ }
+ break;
+
+ case DIKS_SMALL_E:
+ update_focus( stack, data, wmdata );
+ break;
+
+ case DIKS_SMALL_A:
+ if (focused && !(focused->config.options & DWOP_KEEP_STACKING)) {
+ restack_window( focused, focused->window_data,
+ NULL, NULL, 0, focused->config.stacking );
+ update_focus( stack, data, wmdata );
+ }
+ break;
+
+ case DIKS_SMALL_W:
+ if (focused && !(focused->config.options & DWOP_KEEP_STACKING))
+ restack_window( focused, focused->window_data,
+ NULL, NULL, 1, focused->config.stacking );
+ break;
+
+ case DIKS_SMALL_D:
+ if (entered && !(entered->config.options & DWOP_INDESTRUCTIBLE))
+ dfb_window_destroy( entered );
+
+ break;
+
+ case DIKS_SMALL_P:
+ /* Enable and show cursor. */
+ if (stack->cursor.set) {
+ dfb_windowstack_cursor_set_opacity( stack, 0xff );
+ dfb_windowstack_cursor_enable( wmdata->core, stack, true );
+ }
+
+ /* Ungrab pointer. */
+ data->pointer_window = NULL;
+
+ /* TODO: set new cursor shape, the current one might be completely transparent */
+ break;
+
+ case DIKS_SMALL_R:
+ if (focused && !(focused->config.options & DWOP_KEEP_POSITION))
+ dfb_window_set_rotation( focused, (focused->config.rotation + 90) % 360 );
+ break;
+
+ case DIKS_PRINT:
+ if (dfb_config->screenshot_dir && focused && focused->surface)
+ dfb_surface_dump_buffer( focused->surface, CSBR_FRONT, dfb_config->screenshot_dir, "dfb_window" );
+ break;
+
+ case DIKS_F12:
+ region.x1 = 0;
+ region.y1 = 0;
+ region.x2 = stack->width;
+ region.y2 = stack->height;
+
+ dfb_updates_reset( &data->updates );
+ dfb_updates_add( &data->updates, &region );
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+is_wm_key( DFBInputDeviceKeySymbol key_symbol )
+{
+ switch (DFB_LOWER_CASE(key_symbol)) {
+ case DIKS_SMALL_X:
+ case DIKS_SMALL_S:
+ case DIKS_SMALL_C:
+ case DIKS_SMALL_E:
+ case DIKS_SMALL_A:
+ case DIKS_SMALL_W:
+ case DIKS_SMALL_D:
+ case DIKS_SMALL_P:
+ case DIKS_SMALL_R:
+ case DIKS_PRINT:
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+
+/**************************************************************************************************/
+
+static DFBResult
+handle_key_press( CoreWindowStack *stack,
+ StackData *data,
+ WMData *wmdata,
+ const DFBInputEvent *event )
+{
+ CoreWindow *window;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( event != NULL );
+ D_ASSERT( event->type == DIET_KEYPRESS );
+
+ if (data->wm_level) {
+ switch (event->key_symbol) {
+ case DIKS_META:
+ data->wm_level |= 1;
+ break;
+
+ case DIKS_CONTROL:
+ data->wm_level |= 2;
+ break;
+
+ case DIKS_ALT:
+ data->wm_level |= 4;
+ break;
+
+ default:
+ if (handle_wm_key( stack, data, wmdata, event ))
+ return DFB_OK;
+
+ break;
+ }
+ }
+ else if (event->key_symbol == DIKS_META) {
+ data->wm_level |= 1;
+ data->wm_cycle = 0;
+ }
+
+ window = get_keyboard_window( stack, data, event );
+ if (window)
+ send_key_event( window, data, event );
+
+ return DFB_OK;
+}
+
+static DFBResult
+handle_key_release( CoreWindowStack *stack,
+ StackData *data,
+ const DFBInputEvent *event )
+{
+ CoreWindow *window;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( event != NULL );
+ D_ASSERT( event->type == DIET_KEYRELEASE );
+
+ if (data->wm_level) {
+ switch (event->key_symbol) {
+ case DIKS_META:
+ data->wm_level &= ~1;
+ break;
+
+ case DIKS_CONTROL:
+ data->wm_level &= ~2;
+ break;
+
+ case DIKS_ALT:
+ data->wm_level &= ~4;
+ break;
+
+ default:
+ if (is_wm_key( event->key_symbol ))
+ return DFB_OK;
+
+ break;
+ }
+ }
+
+ window = get_keyboard_window( stack, data, event );
+ if (window)
+ send_key_event( window, data, event );
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+handle_button_press( CoreWindowStack *stack,
+ StackData *data,
+ const DFBInputEvent *event )
+{
+ CoreWindow *window;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( event != NULL );
+ D_ASSERT( event->type == DIET_BUTTONPRESS );
+
+ if (!stack->cursor.enabled)
+ return DFB_OK;
+
+ switch (data->wm_level) {
+ case 1:
+ window = data->entered_window;
+ if (window && !(window->config.options & DWOP_KEEP_STACKING))
+ dfb_window_raisetotop( data->entered_window );
+
+ break;
+
+ default:
+ window = data->pointer_window ? data->pointer_window : data->entered_window;
+ if (window)
+ send_button_event( window, data, event );
+
+ break;
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+handle_button_release( CoreWindowStack *stack,
+ StackData *data,
+ const DFBInputEvent *event )
+{
+ CoreWindow *window;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( event != NULL );
+ D_ASSERT( event->type == DIET_BUTTONRELEASE );
+
+ if (!stack->cursor.enabled)
+ return DFB_OK;
+
+ switch (data->wm_level) {
+ case 1:
+ break;
+
+ default:
+ window = data->pointer_window ? data->pointer_window : data->entered_window;
+ if (window)
+ send_button_event( window, data, event );
+
+ break;
+ }
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static void
+perform_motion( CoreWindowStack *stack,
+ StackData *data,
+ WMData *wmdata,
+ int dx,
+ int dy )
+{
+ int old_cx, old_cy;
+ DFBWindowEvent we;
+ CoreWindow *entered;
+ CoreWindowConfig *config = NULL;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+
+ if (!stack->cursor.enabled)
+ return;
+
+
+ old_cx = stack->cursor.x;
+ old_cy = stack->cursor.y;
+
+ dfb_windowstack_cursor_warp( stack, old_cx + dx, old_cy + dy );
+
+ dx = stack->cursor.x - old_cx;
+ dy = stack->cursor.y - old_cy;
+
+ if (!dx && !dy)
+ return;
+
+
+ entered = data->entered_window;
+ if (entered)
+ config = &entered->config;
+
+ switch (data->wm_level) {
+ case 7:
+ case 6:
+ case 5:
+ case 4:
+ if (entered) {
+ int opacity = config->opacity + dx;
+
+ if (opacity < 8)
+ opacity = 8;
+ else if (opacity > 255)
+ opacity = 255;
+
+ dfb_window_set_opacity( entered, opacity );
+ }
+
+ break;
+
+ case 3:
+ case 2:
+ if (entered && !(config->options & DWOP_KEEP_SIZE)) {
+ int width = config->bounds.w + dx;
+ int height = config->bounds.h + dy;
+
+ if (width < 48) width = 48;
+ if (height < 48) height = 48;
+ if (width > 2048) width = 2048;
+ if (height > 2048) height = 2048;
+
+ dfb_window_resize( entered, width, height );
+ }
+
+ break;
+
+ case 1:
+ if (entered && !(config->options & DWOP_KEEP_POSITION))
+ dfb_window_move( entered, dx, dy, true );
+
+ break;
+
+ case 0:
+ if (data->pointer_window) {
+ CoreWindow *window = data->pointer_window;
+
+ we.type = DWET_MOTION;
+ we.x = stack->cursor.x - window->config.bounds.x;
+ we.y = stack->cursor.y - window->config.bounds.y;
+
+ transform_point_in_window( window, &we.x, &we.y );
+
+ post_event( window, data, &we );
+ }
+ else if (!update_focus( stack, data, wmdata ) && data->entered_window) {
+ CoreWindow *window = data->entered_window;
+
+ we.type = DWET_MOTION;
+ we.x = stack->cursor.x - window->config.bounds.x;
+ we.y = stack->cursor.y - window->config.bounds.y;
+
+ transform_point_in_window( window, &we.x, &we.y );
+
+ post_event( window, data, &we );
+ }
+
+ break;
+
+ default:
+ ;
+ }
+}
+
+static void
+flush_motion( CoreWindowStack *stack,
+ StackData *data,
+ WMData *wmdata )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( wmdata != NULL );
+
+ if (data->cursor_dx || data->cursor_dy) {
+ perform_motion( stack, data, wmdata, data->cursor_dx, data->cursor_dy );
+
+ data->cursor_dx = 0;
+ data->cursor_dy = 0;
+ }
+}
+
+static void
+handle_wheel( CoreWindowStack *stack,
+ StackData *data,
+ int dz )
+{
+ DFBWindowEvent we;
+ CoreWindow *window = NULL;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+
+ if (!stack->cursor.enabled)
+ return;
+
+ window = data->pointer_window ? data->pointer_window : data->entered_window;
+
+ if (window) {
+ if (data->wm_level) {
+ int opacity = window->config.opacity + dz*7;
+
+ if (opacity < 0x01)
+ opacity = 1;
+ if (opacity > 0xFF)
+ opacity = 0xFF;
+
+ dfb_window_set_opacity( window, opacity );
+ }
+ else {
+ we.type = DWET_WHEEL;
+ we.x = stack->cursor.x - window->config.bounds.x;
+ we.y = stack->cursor.y - window->config.bounds.y;
+ we.step = dz;
+
+ transform_point_in_window( window, &we.x, &we.y );
+
+ post_event( window, data, &we );
+ }
+ }
+}
+
+static DFBResult
+handle_axis_motion( CoreWindowStack *stack,
+ StackData *data,
+ WMData *wmdata,
+ const DFBInputEvent *event )
+{
+ CoreLayerContext *context;
+ DFBInputEvent rotated_event;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( event != NULL );
+ D_ASSERT( event->type == DIET_AXISMOTION );
+
+ context = stack->context;
+ D_MAGIC_ASSERT( context, CoreLayerContext );
+
+ if (event->flags & DIEF_AXISREL) {
+ rotated_event = *event;
+ event = &rotated_event;
+
+ if (event->axis == DIAI_X) {
+ if (context->rotation == 90) {
+ rotated_event.axis = DIAI_Y;
+ }
+ else if (context->rotation == 180) {
+ rotated_event.axisrel = -rotated_event.axisrel;
+ }
+ else if (context->rotation == 270) {
+ rotated_event.axis = DIAI_Y;
+ rotated_event.axisrel = -rotated_event.axisrel;
+ }
+ }
+ else if (event->axis == DIAI_Y) {
+ if (context->rotation == 90) {
+ rotated_event.axis = DIAI_X;
+ rotated_event.axisrel = -rotated_event.axisrel;
+ }
+ else if (context->rotation == 180) {
+ rotated_event.axisrel = -rotated_event.axisrel;
+ }
+ else if (context->rotation == 270) {
+ rotated_event.axis = DIAI_X;
+ }
+ }
+ }
+ else if (event->flags & DIEF_AXISABS) {
+ rotated_event = *event;
+ event = &rotated_event;
+
+ if (event->axis == DIAI_X) {
+ if (context->rotation == 90) {
+ rotated_event.axis = DIAI_Y;
+ }
+ else if (context->rotation == 180) {
+ rotated_event.axisabs = stack->rotated_width - rotated_event.axisabs;
+ }
+ else if (context->rotation == 270) {
+ rotated_event.axis = DIAI_Y;
+ rotated_event.axisabs = stack->rotated_width - rotated_event.axisabs;
+ }
+ }
+ else if (event->axis == DIAI_Y) {
+ if (context->rotation == 90) {
+ rotated_event.axis = DIAI_X;
+ rotated_event.axisabs = stack->rotated_height - rotated_event.axisabs;
+ }
+ else if (context->rotation == 180) {
+ rotated_event.axisabs = stack->rotated_height - rotated_event.axisabs;
+ }
+ else if (context->rotation == 270) {
+ rotated_event.axis = DIAI_X;
+ }
+ }
+ }
+
+ if (event->flags & DIEF_AXISREL) {
+ int rel = event->axisrel;
+
+ /* handle cursor acceleration */
+ if (rel > stack->cursor.threshold)
+ rel += (rel - stack->cursor.threshold)
+ * stack->cursor.numerator
+ / stack->cursor.denominator;
+ else if (rel < -stack->cursor.threshold)
+ rel += (rel + stack->cursor.threshold)
+ * stack->cursor.numerator
+ / stack->cursor.denominator;
+
+ switch (event->axis) {
+ case DIAI_X:
+ data->cursor_dx += rel;
+ break;
+
+ case DIAI_Y:
+ data->cursor_dy += rel;
+ break;
+
+ case DIAI_Z:
+ flush_motion( stack, data, wmdata );
+
+ handle_wheel( stack, data, - event->axisrel );
+ break;
+
+ default:
+ ;
+ }
+ }
+ else if (event->flags & DIEF_AXISABS) {
+ int axismin = 0;
+ int axisabs = event->axisabs;
+
+ if (event->flags & DIEF_MIN) {
+ axismin = event->min;
+
+ axisabs -= axismin;
+ }
+
+ switch (event->axis) {
+ case DIAI_X:
+ if (event->flags & DIEF_MAX)
+ axisabs = axisabs * stack->width / (event->max - axismin + 1);
+
+ data->cursor_dx = axisabs - stack->cursor.x;
+ break;
+
+ case DIAI_Y:
+ if (event->flags & DIEF_MAX)
+ axisabs = axisabs * stack->height / (event->max - axismin + 1);
+
+ data->cursor_dy = axisabs - stack->cursor.y;
+ break;
+
+ default:
+ ;
+ }
+ }
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+/**************************************************************************************************/
+
+static void
+wm_get_info( CoreWMInfo *info )
+{
+ info->version.major = 0;
+ info->version.minor = 3;
+ info->version.binary = 2;
+
+ snprintf( info->name, DFB_CORE_WM_INFO_NAME_LENGTH, "Default" );
+ snprintf( info->vendor, DFB_CORE_WM_INFO_VENDOR_LENGTH, "directfb.org" );
+
+ info->wm_data_size = sizeof(WMData);
+ info->stack_data_size = sizeof(StackData);
+ info->window_data_size = sizeof(WindowData);
+}
+
+static DFBResult
+wm_initialize( CoreDFB *core, void *wm_data, void *shared_data )
+{
+ WMData *data = wm_data;
+
+ data->core = core;
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_join( CoreDFB *core, void *wm_data, void *shared_data )
+{
+ WMData *data = wm_data;
+
+ data->core = core;
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_shutdown( bool emergency, void *wm_data, void *shared_data )
+{
+ return DFB_OK;
+}
+
+static DFBResult
+wm_leave( bool emergency, void *wm_data, void *shared_data )
+{
+ return DFB_OK;
+}
+
+static DFBResult
+wm_suspend( void *wm_data, void *shared_data )
+{
+ return DFB_OK;
+}
+
+static DFBResult
+wm_resume( void *wm_data, void *shared_data )
+{
+ return DFB_OK;
+}
+
+static DFBResult
+wm_post_init( void *wm_data, void *shared_data )
+{
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+wm_init_stack( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data )
+{
+ int i;
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ data->stack = stack;
+
+ /* Initialize update manager. */
+ dfb_updates_init( &data->updates, data->update_regions, MAX_UPDATE_REGIONS );
+
+ fusion_vector_init( &data->windows, 64, stack->shmpool );
+
+ for (i=0; i<MAX_KEYS; i++)
+ data->keys[i].code = -1;
+
+ D_MAGIC_SET( data, StackData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_close_stack( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data )
+{
+ DirectLink *l, *next;
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+ D_MAGIC_CLEAR( data );
+
+ D_ASSUME( fusion_vector_is_empty( &data->windows ) );
+
+ if (fusion_vector_has_elements( &data->windows )) {
+ int i;
+ CoreWindow *window;
+
+ fusion_vector_foreach (window, i, data->windows) {
+ D_WARN( "setting window->stack = NULL" );
+ window->stack = NULL;
+ }
+ }
+
+ fusion_vector_destroy( &data->windows );
+
+ /* Destroy backing store of software cursor. */
+ if (data->cursor_bs)
+ dfb_surface_unlink( &data->cursor_bs );
+
+ /* Free grabbed keys. */
+ direct_list_foreach_safe (l, next, data->grabbed_keys)
+ SHFREE( stack->shmpool, l );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_set_active( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ bool active )
+{
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ D_ASSUME( data->active != active );
+
+ if (data->active == active)
+ return DFB_OK;
+
+ data->active = active;
+
+ if (active)
+ return dfb_windowstack_repaint_all( stack );
+
+ /* Force release of all pressed keys. */
+ return wm_flush_keys( stack, wm_data, stack_data );
+}
+
+static DFBResult
+wm_resize_stack( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ int width,
+ int height )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_process_input( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ const DFBInputEvent *event )
+{
+ DFBResult ret;
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( event != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ D_DEBUG_AT( WM_Default, "Processing input event (device %d, type 0x%08x, flags 0x%08x)...\n",
+ event->device_id, event->type, event->flags );
+
+ /* FIXME: handle multiple devices */
+ if (event->flags & DIEF_BUTTONS)
+ data->buttons = event->buttons;
+
+ if (event->flags & DIEF_MODIFIERS)
+ data->modifiers = event->modifiers;
+
+ if (event->flags & DIEF_LOCKS)
+ data->locks = event->locks;
+
+ if (event->type != DIET_AXISMOTION)
+ flush_motion( stack, data, wm_data );
+
+ switch (event->type) {
+ case DIET_KEYPRESS:
+ ret = handle_key_press( stack, data, wm_data, event );
+ break;
+
+ case DIET_KEYRELEASE:
+ ret = handle_key_release( stack, data, event );
+ break;
+
+ case DIET_BUTTONPRESS:
+ ret = handle_button_press( stack, data, event );
+ break;
+
+ case DIET_BUTTONRELEASE:
+ ret = handle_button_release( stack, data, event );
+ break;
+
+ case DIET_AXISMOTION:
+ ret = handle_axis_motion( stack, data, wm_data, event );
+ break;
+
+ default:
+ D_ONCE( "unknown input event type" );
+ ret = DFB_UNSUPPORTED;
+ break;
+ }
+
+ if (!D_FLAGS_IS_SET( event->flags, DIEF_FOLLOW ))
+ flush_motion( stack, data, wm_data );
+
+ process_updates( data, wm_data, stack, NULL, DSFLIP_NONE );
+
+ return ret;
+}
+
+static DFBResult
+wm_flush_keys( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data )
+{
+ int i;
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ for (i=0; i<MAX_KEYS; i++) {
+ if (data->keys[i].code != -1) {
+ DFBWindowEvent we;
+
+ we.type = DWET_KEYUP;
+ we.key_code = data->keys[i].code;
+ we.key_id = data->keys[i].id;
+ we.key_symbol = data->keys[i].symbol;
+
+ post_event( data->keys[i].owner, data, &we );
+
+ data->keys[i].code = -1;
+ }
+ }
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_window_at( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ int x,
+ int y,
+ CoreWindow **ret_window )
+{
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( ret_window != NULL );
+
+ *ret_window = window_at_pointer( stack, data, wm_data, x, y );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_window_lookup( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ DFBWindowID window_id,
+ CoreWindow **ret_window )
+{
+ int i;
+ CoreWindow *window = NULL;
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( ret_window != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ fusion_vector_foreach_reverse (window, i, data->windows) {
+ if (window->id == window_id) {
+ break;
+ }
+ }
+
+ *ret_window = window;
+ return DFB_OK;
+}
+
+static DFBResult
+wm_enum_windows( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWMWindowCallback callback,
+ void *callback_ctx )
+{
+ int i;
+ CoreWindow *window = NULL;
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( callback != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ fusion_vector_foreach_reverse (window, i, data->windows) {
+ if (callback( window, callback_ctx ) != DFENUM_OK)
+ break;
+ }
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+wm_get_insets( CoreWindowStack *stack,
+ CoreWindow *window,
+ DFBInsets *insets )
+{
+ insets->l = 0;
+ insets->t = 0;
+ insets->r = 0;
+ insets->b = 0;
+
+ return DFB_OK;
+}
+
+
+static DFBResult
+wm_preconfigure_window( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data )
+{
+ if (window->config.association)
+ return DFB_UNIMPLEMENTED;
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_set_window_property( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void *value,
+ void **ret_old_value )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( key != NULL );
+
+ fusion_object_set_property((FusionObject*)window,
+ key,value,ret_old_value);
+ return DFB_OK;
+}
+
+static DFBResult
+wm_get_window_property( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void **ret_value )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( key != NULL );
+ D_ASSERT( ret_value != NULL );
+
+ *ret_value = fusion_object_get_property((FusionObject*)window,key);
+ return DFB_OK;
+}
+
+
+static DFBResult
+wm_remove_window_property( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void **ret_value )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( key != NULL );
+
+ fusion_object_remove_property((FusionObject*)window,key,ret_value);
+ return DFB_OK;
+}
+
+static DFBResult
+wm_add_window( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data )
+{
+ WindowData *data = window_data;
+ StackData *sdata = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+
+ D_MAGIC_ASSERT( sdata, StackData );
+
+ /* Initialize window data. */
+ data->window = window;
+ data->stack_data = stack_data;
+ data->priority = get_priority( window );
+
+ if (window->region)
+ dfb_layer_region_get_configuration( window->region, &data->config );
+
+ D_MAGIC_SET( data, WindowData );
+
+ /* Actually add the window to the stack. */
+ insert_window( stack, sdata, window, data );
+
+ /* Possibly switch focus to the new window. */
+ update_focus( stack, sdata, wm_data );
+
+ process_updates( sdata, wm_data, stack, window->primary_region, DSFLIP_NONE );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_remove_window( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data )
+{
+ WindowData *data = window_data;
+ StackData *sdata = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+
+ D_MAGIC_ASSERT( data, WindowData );
+ D_MAGIC_ASSERT( sdata, StackData );
+
+ remove_window( stack, sdata, window, data );
+
+ /* Free key list. */
+ if (window->config.keys) {
+ SHFREE( stack->shmpool, window->config.keys );
+
+ window->config.keys = NULL;
+ window->config.num_keys = 0;
+ }
+
+ D_MAGIC_CLEAR( data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_set_window_config( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const CoreWindowConfig *config,
+ CoreWindowConfigFlags flags )
+{
+ DFBResult ret;
+ CoreWindowStack *stack;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( window->stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( config != NULL );
+
+ stack = window->stack;
+ D_ASSERT( stack != NULL );
+
+ if (flags & CWCF_OPTIONS) {
+ if ((window->config.options & DWOP_SCALE) && !(config->options & DWOP_SCALE) && window->surface) {
+ if (window->config.bounds.w != window->surface->config.size.w ||
+ window->config.bounds.h != window->surface->config.size.h)
+ {
+ ret = dfb_surface_reformat( window->surface,
+ window->config.bounds.w,
+ window->config.bounds.h,
+ window->surface->config.format );
+ if (ret) {
+ D_DERROR( ret, "WM/Default: Could not resize surface "
+ "(%dx%d -> %dx%d) to remove DWOP_SCALE!\n",
+ window->surface->config.size.w,
+ window->surface->config.size.h,
+ window->config.bounds.w,
+ window->config.bounds.h );
+ return ret;
+ }
+ }
+ }
+
+ window->config.options = config->options;
+ }
+
+ if (flags & CWCF_EVENTS)
+ window->config.events = config->events;
+
+ if (flags & CWCF_COLOR)
+ return DFB_UNSUPPORTED;
+
+ if (flags & CWCF_COLOR_KEY)
+ window->config.color_key = config->color_key;
+
+ if (flags & CWCF_OPAQUE)
+ window->config.opaque = config->opaque;
+
+ if (flags & CWCF_OPACITY && !config->opacity)
+ set_opacity( window, window_data, wm_data, config->opacity );
+
+ if (flags == (CWCF_POSITION | CWCF_SIZE)) {
+ ret = set_window_bounds (window, wm_data, window_data,
+ config->bounds.x, config->bounds.y,
+ config->bounds.w, config->bounds.h);
+ if (ret)
+ return ret;
+ }
+ else {
+ if (flags & CWCF_POSITION) {
+ ret = move_window( window, window_data,
+ config->bounds.x - window->config.bounds.x,
+ config->bounds.y - window->config.bounds.y );
+ if (ret)
+ return ret;
+ }
+
+ if (flags & CWCF_SIZE) {
+ ret = resize_window( window, wm_data, window_data, config->bounds.w, config->bounds.h );
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (flags & CWCF_ROTATION) {
+ update_window( window, window_data, NULL, DSFLIP_NONE, false, false, false );
+
+ window->config.rotation = config->rotation;
+
+ update_window( window, window_data, NULL, DSFLIP_NONE, false, false, false );
+ }
+
+ if (flags & CWCF_STACKING)
+ restack_window( window, window_data, window, window_data, 0, config->stacking );
+
+ if (flags & CWCF_OPACITY && config->opacity)
+ set_opacity( window, window_data, wm_data, config->opacity );
+
+ if (flags & CWCF_KEY_SELECTION) {
+ if (config->key_selection == DWKS_LIST) {
+ unsigned int bytes = sizeof(DFBInputDeviceKeySymbol) * config->num_keys;
+ DFBInputDeviceKeySymbol *keys;
+
+ D_ASSERT( config->keys != NULL );
+ D_ASSERT( config->num_keys > 0 );
+
+ keys = SHMALLOC( window->stack->shmpool, bytes );
+ if (!keys) {
+ D_ERROR( "WM/Default: Could not allocate %d bytes for list "
+ "of selected keys (%d)!\n", bytes, config->num_keys );
+ return D_OOSHM();
+ }
+
+ direct_memcpy( keys, config->keys, bytes );
+
+ qsort( keys, config->num_keys, sizeof(DFBInputDeviceKeySymbol), keys_compare );
+
+ if (window->config.keys)
+ SHFREE( window->stack->shmpool, window->config.keys );
+
+ window->config.keys = keys;
+ window->config.num_keys = config->num_keys;
+ }
+ else if (window->config.keys) {
+ SHFREE( window->stack->shmpool, window->config.keys );
+
+ window->config.keys = NULL;
+ window->config.num_keys = 0;
+ }
+
+ window->config.key_selection = config->key_selection;
+ }
+
+ process_updates( stack->stack_data, wm_data, stack, window->primary_region, DSFLIP_NONE );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_restack_window( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWindow *relative,
+ void *relative_data,
+ int relation )
+{
+ DFBResult ret;
+ WindowData *data = window_data;
+ StackData *sdata;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+
+ D_MAGIC_ASSERT( data, WindowData );
+
+ D_ASSERT( relative == NULL || relative_data != NULL );
+
+ D_ASSERT( relative == NULL || relative == window || relation != 0);
+
+ sdata = data->stack_data;
+ D_ASSERT( sdata != NULL );
+ D_ASSERT( sdata->stack != NULL );
+
+ ret = restack_window( window, window_data, relative,
+ relative_data, relation, window->config.stacking );
+ if (ret)
+ return ret;
+
+ /* Possibly switch focus to window now under the cursor */
+ update_focus( sdata->stack, sdata, wm_data );
+
+ process_updates( sdata, wm_data, window->stack, window->primary_region, DSFLIP_NONE );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_grab( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWMGrab *grab )
+{
+ StackData *sdata;
+ WindowData *wdata = window_data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( grab != NULL );
+ D_ASSERT( wdata->stack_data != NULL );
+
+ sdata = wdata->stack_data;
+
+ switch (grab->target) {
+ case CWMGT_KEYBOARD:
+ return grab_keyboard( window, window_data );
+
+ case CWMGT_POINTER:
+ return grab_pointer( window, window_data );
+
+ case CWMGT_KEY:
+ return grab_key( window, window_data, grab->symbol, grab->modifiers );
+
+ case CWMGT_UNSELECTED_KEYS:
+ if (sdata->unselkeys_window)
+ return DFB_LOCKED;
+
+ sdata->unselkeys_window = window;
+ return DFB_OK;
+
+ default:
+ D_BUG( "unknown grab target" );
+ break;
+ }
+
+ return DFB_BUG;
+}
+
+static DFBResult
+wm_ungrab( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWMGrab *grab )
+{
+ StackData *sdata;
+ WindowData *wdata = window_data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( grab != NULL );
+ D_ASSERT( wdata->stack_data != NULL );
+
+ sdata = wdata->stack_data;
+
+ switch (grab->target) {
+ case CWMGT_KEYBOARD:
+ return ungrab_keyboard( window, window_data );
+
+ case CWMGT_POINTER:
+ return ungrab_pointer( window, window_data, wm_data );
+
+ case CWMGT_KEY:
+ return ungrab_key( window, window_data, grab->symbol, grab->modifiers );
+
+ case CWMGT_UNSELECTED_KEYS:
+ if (sdata->unselkeys_window == window)
+ sdata->unselkeys_window = NULL;
+
+ return DFB_OK;
+
+ default:
+ D_BUG( "unknown grab target" );
+ break;
+ }
+
+ return DFB_BUG;
+}
+
+static DFBResult
+wm_request_focus( CoreWindow *window,
+ void *wm_data,
+ void *window_data )
+{
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+
+ return request_focus( window, window_data );
+}
+
+static DFBResult
+wm_begin_updates( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const DFBRegion *update )
+{
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+wm_update_stack( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ const DFBRegion *region, /* stack coordinates */
+ DFBSurfaceFlipFlags flags )
+{
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( region != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ dfb_updates_add( &data->updates, region );
+
+ process_updates( data, wm_data, stack, NULL, flags );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_update_window( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const DFBRegion *region, /* surface coordinates! */
+ DFBSurfaceFlipFlags flags )
+{
+ CoreWindowStack *stack;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+
+ DFB_REGION_ASSERT_IF( region );
+
+ stack = window->stack;
+ D_ASSERT( stack != NULL );
+
+ update_window( window, window_data, region, flags, false, false, true );
+
+ process_updates( stack->stack_data, wm_data, stack, window->primary_region, flags );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_update_cursor( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreCursorUpdateFlags flags )
+{
+ DFBResult ret;
+ DFBRegion old_dest;
+ DFBRegion old_region;
+ WMData *wmdata = wm_data;
+ StackData *data = stack_data;
+ bool restored = false;
+ CoreLayerContext *context;
+ CoreLayerRegion *primary;
+ CoreSurface *surface;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ old_region = data->cursor_region;
+
+ transform_stack_to_dest( stack, &old_region, &old_dest );
+
+ if (flags & (CCUF_ENABLE | CCUF_POSITION | CCUF_SIZE)) {
+ data->cursor_bs_valid = false;
+
+ data->cursor_region.x1 = stack->cursor.x - stack->cursor.hot.x;
+ data->cursor_region.y1 = stack->cursor.y - stack->cursor.hot.y;
+ data->cursor_region.x2 = data->cursor_region.x1 + stack->cursor.size.w - 1;
+ data->cursor_region.y2 = data->cursor_region.y1 + stack->cursor.size.h - 1;
+
+ if (!dfb_region_intersect( &data->cursor_region, 0, 0, stack->width - 1, stack->height - 1 )) {
+ D_BUG( "invalid cursor region" );
+ return DFB_BUG;
+ }
+ }
+
+ /* Optimize case of invisible cursor moving. */
+ if (!(flags & ~(CCUF_POSITION | CCUF_SHAPE)) && (!stack->cursor.opacity || !stack->cursor.enabled))
+ return DFB_OK;
+
+ context = stack->context;
+ D_ASSERT( context != NULL );
+
+ if (!data->cursor_bs) {
+ CoreSurface *cursor_bs;
+ DFBSurfaceCapabilities caps = DSCAPS_NONE;
+ DFBDimension size = stack->cursor.size;
+
+ D_ASSUME( flags & CCUF_ENABLE );
+
+ dfb_surface_caps_apply_policy( stack->cursor.policy, &caps );
+
+ if (stack->rotation == 90 || stack->rotation == 270)
+ D_UTIL_SWAP( size.w, size.h );
+
+ /* Create the cursor backing store surface. */
+ ret = dfb_surface_create_simple( wmdata->core, size.w, size.h,
+ context->config.pixelformat, caps, CSTF_SHARED | CSTF_CURSOR,
+ 0, /* FIXME: no shared cursor objects, no cursor id */
+ NULL, &cursor_bs );
+ if (ret) {
+ D_ERROR( "WM/Default: Failed creating backing store for cursor!\n" );
+ return ret;
+ }
+
+ ret = dfb_surface_globalize( cursor_bs );
+ D_ASSERT( ret == DFB_OK );
+
+ data->cursor_bs = cursor_bs;
+ }
+
+ D_ASSERT( data->cursor_bs != NULL );
+
+ /* Get the primary region. */
+ ret = dfb_layer_context_get_primary_region( context, false, &primary );
+ if (ret)
+ return ret;
+
+ surface = primary->surface;
+ D_MAGIC_ASSERT( surface, CoreSurface );
+
+ if (flags & CCUF_ENABLE) {
+ /* Ensure valid back buffer. From now on swapping is prevented until cursor is disabled.
+ * FIXME: Keep a flag to know when back/front have been swapped and need a sync.
+ */
+ switch (context->config.buffermode) {
+ case DLBM_BACKVIDEO:
+ case DLBM_TRIPLE:
+ dfb_gfx_copy( surface, surface, NULL );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* restore region under cursor */
+ if (data->cursor_drawn && dfb_region_intersect( &old_dest, 0, 0,
+ surface->config.size.w - 1, surface->config.size.h - 1 ))
+ {
+ DFBRectangle rect = { 0, 0,
+ old_dest.x2 - old_dest.x1 + 1,
+ old_dest.y2 - old_dest.y1 + 1 };
+
+ D_ASSERT( stack->cursor.opacity || (flags & CCUF_OPACITY) );
+
+ dfb_gfx_copy_to( data->cursor_bs, surface, &rect, old_dest.x1, old_dest.y1, false );
+
+ data->cursor_drawn = false;
+
+ restored = true;
+ }
+
+ if (flags & CCUF_SIZE) {
+ DFBDimension size = stack->cursor.size;
+
+ if (stack->rotation == 90 || stack->rotation == 270)
+ D_UTIL_SWAP( size.w, size.h );
+
+ ret = dfb_surface_reformat( data->cursor_bs, size.w, size.h, data->cursor_bs->config.format );
+ if (ret)
+ D_DERROR( ret, "WM/Default: Failed resizing backing store for cursor from %dx%d to %dx%d!\n",
+ data->cursor_bs->config.size.w, data->cursor_bs->config.size.h,
+ stack->cursor.size.w, stack->cursor.size.h );
+ }
+
+ if (flags & CCUF_DISABLE) {
+ dfb_surface_unlink( &data->cursor_bs );
+ }
+ else if (stack->cursor.opacity) {
+ DFBRegion dest;
+ CoreLayer *layer = dfb_layer_at( context->layer_id );
+ CardState *state = &layer->state;
+
+ transform_stack_to_dest( stack, &data->cursor_region, &dest );
+
+ if (!dfb_region_intersect( &dest, 0, 0, surface->config.size.w - 1, surface->config.size.h - 1 )) {
+ if (restored)
+ dfb_layer_region_flip_update( primary, &old_dest, DSFLIP_BLIT );
+ dfb_layer_region_unref( primary );
+ return DFB_OK;
+ }
+
+ /* backup region under cursor */
+ if (!data->cursor_bs_valid) {
+ DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &dest );
+
+ D_ASSERT( !data->cursor_drawn );
+
+ /* FIXME: this requires using blitted flipping all the time,
+ but fixing it seems impossible, for now DSFLIP_BLIT is forced
+ in repaint_stack() when the cursor is enabled. */
+ dfb_gfx_copy_to( surface, data->cursor_bs, &rect, 0, 0, true );
+
+ data->cursor_bs_valid = true;
+ }
+
+ /* Set destination. */
+ state->destination = surface;
+ state->modified |= SMF_DESTINATION;
+
+ /* Set clipping region. */
+ dfb_state_set_clip( state, &dest );
+
+ /* draw cursor */
+ draw_cursor( stack, data, state, &data->cursor_region );
+
+ /* Reset destination. */
+ state->destination = NULL;
+ state->modified |= SMF_DESTINATION;
+
+ data->cursor_drawn = true;
+
+ if (restored) {
+ if (dfb_region_region_intersects( &old_dest, &dest ))
+ dfb_region_region_union( &old_dest, &dest );
+ else
+ dfb_layer_region_flip_update( primary, &dest, DSFLIP_BLIT );
+
+ dfb_layer_region_flip_update( primary, &old_dest, DSFLIP_BLIT );
+ }
+ else
+ dfb_layer_region_flip_update( primary, &dest, DSFLIP_BLIT );
+
+ /* Pan to follow the cursor? */
+ if (primary->config.source.w < surface->config.size.w || primary->config.source.h < surface->config.size.h) {
+ DFBRectangle source = primary->config.source;
+
+ if (stack->rotation)
+ D_UNIMPLEMENTED();
+
+ if (source.x > stack->cursor.x)
+ source.x = stack->cursor.x;
+ else if (source.x + source.w - 1 < stack->cursor.x)
+ source.x = stack->cursor.x - source.w + 1;
+
+ if (source.y > stack->cursor.y)
+ source.y = stack->cursor.y;
+ else if (source.y + source.h - 1 < stack->cursor.y)
+ source.y = stack->cursor.y - source.h + 1;
+
+ dfb_layer_context_set_sourcerectangle( context, &source );
+ }
+ }
+ else if (restored)
+ dfb_layer_region_flip_update( primary, &old_dest, DSFLIP_BLIT );
+
+ /* Unref primary region. */
+ dfb_layer_region_unref( primary );
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/wm/unique/Makefile.am b/Source/DirectFB/wm/unique/Makefile.am
new file mode 100755
index 0000000..3395c2f
--- /dev/null
+++ b/Source/DirectFB/wm/unique/Makefile.am
@@ -0,0 +1,150 @@
+## Makefile.am for DirectFB/wm/unique
+
+SUBDIRS = classes data devices
+
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/wm \
+ -I$(top_builddir)/wm
+
+bin_PROGRAMS = uwmdump
+
+noinst_PROGRAMS = test_color test_foo stret_test
+
+
+uwmdump_SOURCES = uwmdump.c
+
+uwmdump_LDADD = \
+ libuniquewm.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+
+test_color_SOURCES = test_color.c
+
+test_color_LDADD = \
+ libuniquewm.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+
+test_foo_SOURCES = test_foo.c
+
+test_foo_LDADD = \
+ libuniquewm.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+
+stret_test_SOURCES = stret_test.c
+
+stret_test_LDADD = \
+ libuniquewm.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/src/libdirectfb.la
+
+
+# Set module installation directory
+wmdir = $(MODULEDIR)/wm
+
+# Build wm module
+wm_LTLIBRARIES = libdirectfbwm_unique.la
+
+if BUILD_STATIC
+wm_DATA = libdirectfbwm_unique.o
+endif
+
+libdirectfbwm_unique_la_SOURCES = \
+ unique.c
+
+# Link module against uniquewm library
+libdirectfbwm_unique_la_LIBADD = \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la \
+ libuniquewm.la
+
+libdirectfbwm_unique_la_LDFLAGS = \
+ -avoid-version \
+ -module
+
+# Set header installation directory
+includedir = @INCLUDEDIR@/unique
+
+# Install uniquewm's library header files
+include_HEADERS = \
+ context.h \
+ decoration.h \
+ device.h \
+ input_channel.h \
+ input_events.h \
+ input_switch.h \
+ stret.h \
+ stret_iteration.h \
+ types.h \
+ uniquewm.h \
+ window.h
+
+# Build uniquewm library
+lib_LTLIBRARIES = libuniquewm.la
+
+libuniquewm_la_SOURCES = \
+ context.c \
+ decoration.c \
+ device.c \
+ input_channel.c \
+ input_switch.c \
+ internal.h \
+ stret.c \
+ stret_iteration.c \
+ uniquewm.c \
+ window.c
+
+libuniquewm_la_LIBADD = \
+ classes/libunique_classes.la \
+ devices/libunique_devices.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+libuniquewm_la_LDFLAGS = \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -release $(LT_RELEASE) \
+ $(DFB_LDFLAGS)
+
+
+include $(top_srcdir)/rules/libobject.make
+
+#
+## and now rebuild the static version with the *correct* object files
+#
+if BUILD_STATIC
+
+clean-local:
+ rm -f libuniquewm_fixed.a
+
+all-local: libuniquewm_fixed.a
+
+libuniquewm_fixed.a: .libs/libuniquewm.a
+ rm -f libuniquewm_fixed.a
+ ${AR} cru libuniquewm_fixed.a `find . -name "*.o" | grep -v '.libs'`
+ ${RANLIB} libuniquewm_fixed.a
+ cp -pf libuniquewm_fixed.a .libs/libuniquewm.a
+
+.libs/libuniquewm.a: libuniquewm.la
+
+else
+
+clean-local:
+
+all-local:
+
+endif
diff --git a/Source/DirectFB/wm/unique/Makefile.in b/Source/DirectFB/wm/unique/Makefile.in
new file mode 100755
index 0000000..23aeb55
--- /dev/null
+++ b/Source/DirectFB/wm/unique/Makefile.in
@@ -0,0 +1,979 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+bin_PROGRAMS = uwmdump$(EXEEXT)
+noinst_PROGRAMS = test_color$(EXEEXT) test_foo$(EXEEXT) \
+ stret_test$(EXEEXT)
+DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(top_srcdir)/rules/libobject.make
+subdir = wm/unique
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(wmdir)" \
+ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(wmdir)" \
+ "$(DESTDIR)$(includedir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+wmLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES) $(wm_LTLIBRARIES)
+libdirectfbwm_unique_la_DEPENDENCIES = \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la libuniquewm.la
+am_libdirectfbwm_unique_la_OBJECTS = unique.lo
+libdirectfbwm_unique_la_OBJECTS = \
+ $(am_libdirectfbwm_unique_la_OBJECTS)
+libdirectfbwm_unique_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libdirectfbwm_unique_la_LDFLAGS) $(LDFLAGS) -o $@
+libuniquewm_la_DEPENDENCIES = classes/libunique_classes.la \
+ devices/libunique_devices.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+am_libuniquewm_la_OBJECTS = context.lo decoration.lo device.lo \
+ input_channel.lo input_switch.lo stret.lo stret_iteration.lo \
+ uniquewm.lo window.lo
+libuniquewm_la_OBJECTS = $(am_libuniquewm_la_OBJECTS)
+libuniquewm_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libuniquewm_la_LDFLAGS) $(LDFLAGS) -o $@
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+am_stret_test_OBJECTS = stret_test.$(OBJEXT)
+stret_test_OBJECTS = $(am_stret_test_OBJECTS)
+stret_test_DEPENDENCIES = libuniquewm.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/src/libdirectfb.la
+am_test_color_OBJECTS = test_color.$(OBJEXT)
+test_color_OBJECTS = $(am_test_color_OBJECTS)
+test_color_DEPENDENCIES = libuniquewm.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+am_test_foo_OBJECTS = test_foo.$(OBJEXT)
+test_foo_OBJECTS = $(am_test_foo_OBJECTS)
+test_foo_DEPENDENCIES = libuniquewm.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+am_uwmdump_OBJECTS = uwmdump.$(OBJEXT)
+uwmdump_OBJECTS = $(am_uwmdump_OBJECTS)
+uwmdump_DEPENDENCIES = libuniquewm.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+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 = $(libdirectfbwm_unique_la_SOURCES) $(libuniquewm_la_SOURCES) \
+ $(stret_test_SOURCES) $(test_color_SOURCES) \
+ $(test_foo_SOURCES) $(uwmdump_SOURCES)
+DIST_SOURCES = $(libdirectfbwm_unique_la_SOURCES) \
+ $(libuniquewm_la_SOURCES) $(stret_test_SOURCES) \
+ $(test_color_SOURCES) $(test_foo_SOURCES) $(uwmdump_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+wmDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(wm_DATA)
+includeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(include_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+
+# Set header installation directory
+includedir = @INCLUDEDIR@/unique
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = classes data devices
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/wm \
+ -I$(top_builddir)/wm
+
+uwmdump_SOURCES = uwmdump.c
+uwmdump_LDADD = \
+ libuniquewm.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+test_color_SOURCES = test_color.c
+test_color_LDADD = \
+ libuniquewm.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+test_foo_SOURCES = test_foo.c
+test_foo_LDADD = \
+ libuniquewm.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+stret_test_SOURCES = stret_test.c
+stret_test_LDADD = \
+ libuniquewm.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/src/libdirectfb.la
+
+
+# Set module installation directory
+wmdir = $(MODULEDIR)/wm
+
+# Build wm module
+wm_LTLIBRARIES = libdirectfbwm_unique.la
+@BUILD_STATIC_TRUE@wm_DATA = libdirectfbwm_unique.o
+libdirectfbwm_unique_la_SOURCES = \
+ unique.c
+
+
+# Link module against uniquewm library
+libdirectfbwm_unique_la_LIBADD = \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la \
+ libuniquewm.la
+
+libdirectfbwm_unique_la_LDFLAGS = \
+ -avoid-version \
+ -module
+
+
+# Install uniquewm's library header files
+include_HEADERS = \
+ context.h \
+ decoration.h \
+ device.h \
+ input_channel.h \
+ input_events.h \
+ input_switch.h \
+ stret.h \
+ stret_iteration.h \
+ types.h \
+ uniquewm.h \
+ window.h
+
+
+# Build uniquewm library
+lib_LTLIBRARIES = libuniquewm.la
+libuniquewm_la_SOURCES = \
+ context.c \
+ decoration.c \
+ device.c \
+ input_channel.c \
+ input_switch.c \
+ internal.h \
+ stret.c \
+ stret_iteration.c \
+ uniquewm.c \
+ window.c
+
+libuniquewm_la_LIBADD = \
+ classes/libunique_classes.la \
+ devices/libunique_devices.la \
+ $(top_builddir)/lib/direct/libdirect.la \
+ $(top_builddir)/lib/fusion/libfusion.la \
+ $(top_builddir)/src/libdirectfb.la
+
+libuniquewm_la_LDFLAGS = \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -release $(LT_RELEASE) \
+ $(DFB_LDFLAGS)
+
+all: all-recursive
+
+.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 wm/unique/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu wm/unique/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-wmLTLIBRARIES: $(wm_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(wmdir)" || $(MKDIR_P) "$(DESTDIR)$(wmdir)"
+ @list='$(wm_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(wmLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(wmdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(wmLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(wmdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-wmLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(wm_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(wmdir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(wmdir)/$$p"; \
+ done
+
+clean-wmLTLIBRARIES:
+ -test -z "$(wm_LTLIBRARIES)" || rm -f $(wm_LTLIBRARIES)
+ @list='$(wm_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
+libdirectfbwm_unique.la: $(libdirectfbwm_unique_la_OBJECTS) $(libdirectfbwm_unique_la_DEPENDENCIES)
+ $(libdirectfbwm_unique_la_LINK) -rpath $(wmdir) $(libdirectfbwm_unique_la_OBJECTS) $(libdirectfbwm_unique_la_LIBADD) $(LIBS)
+libuniquewm.la: $(libuniquewm_la_OBJECTS) $(libuniquewm_la_DEPENDENCIES)
+ $(libuniquewm_la_LINK) -rpath $(libdir) $(libuniquewm_la_OBJECTS) $(libuniquewm_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+stret_test$(EXEEXT): $(stret_test_OBJECTS) $(stret_test_DEPENDENCIES)
+ @rm -f stret_test$(EXEEXT)
+ $(LINK) $(stret_test_OBJECTS) $(stret_test_LDADD) $(LIBS)
+test_color$(EXEEXT): $(test_color_OBJECTS) $(test_color_DEPENDENCIES)
+ @rm -f test_color$(EXEEXT)
+ $(LINK) $(test_color_OBJECTS) $(test_color_LDADD) $(LIBS)
+test_foo$(EXEEXT): $(test_foo_OBJECTS) $(test_foo_DEPENDENCIES)
+ @rm -f test_foo$(EXEEXT)
+ $(LINK) $(test_foo_OBJECTS) $(test_foo_LDADD) $(LIBS)
+uwmdump$(EXEEXT): $(uwmdump_OBJECTS) $(uwmdump_DEPENDENCIES)
+ @rm -f uwmdump$(EXEEXT)
+ $(LINK) $(uwmdump_OBJECTS) $(uwmdump_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decoration.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/input_channel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/input_switch.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stret.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stret_iteration.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stret_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_color.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_foo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unique.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniquewm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uwmdump.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-wmDATA: $(wm_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(wmdir)" || $(MKDIR_P) "$(DESTDIR)$(wmdir)"
+ @list='$(wm_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(wmDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(wmdir)/$$f'"; \
+ $(wmDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(wmdir)/$$f"; \
+ done
+
+uninstall-wmDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(wm_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(wmdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(wmdir)/$$f"; \
+ done
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
+ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(includedir)/$$f"; \
+ done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS) \
+ all-local
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(wmdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(wmdir)" "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+ clean-libtool clean-local clean-noinstPROGRAMS \
+ clean-wmLTLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-includeHEADERS install-wmDATA \
+ install-wmLTLIBRARIES
+
+install-dvi: install-dvi-recursive
+
+install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
+
+install-html: install-html-recursive
+
+install-info: install-info-recursive
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-ps: install-ps-recursive
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \
+ uninstall-libLTLIBRARIES uninstall-wmDATA \
+ uninstall-wmLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
+ install-strip
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am all-local check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libLTLIBRARIES clean-libtool clean-local \
+ clean-noinstPROGRAMS clean-wmLTLIBRARIES ctags ctags-recursive \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-includeHEADERS install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip install-wmDATA \
+ install-wmLTLIBRARIES installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-includeHEADERS uninstall-libLTLIBRARIES \
+ uninstall-wmDATA uninstall-wmLTLIBRARIES
+
+%.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)
+
+#
+#
+
+@BUILD_STATIC_TRUE@clean-local:
+@BUILD_STATIC_TRUE@ rm -f libuniquewm_fixed.a
+
+@BUILD_STATIC_TRUE@all-local: libuniquewm_fixed.a
+
+@BUILD_STATIC_TRUE@libuniquewm_fixed.a: .libs/libuniquewm.a
+@BUILD_STATIC_TRUE@ rm -f libuniquewm_fixed.a
+@BUILD_STATIC_TRUE@ ${AR} cru libuniquewm_fixed.a `find . -name "*.o" | grep -v '.libs'`
+@BUILD_STATIC_TRUE@ ${RANLIB} libuniquewm_fixed.a
+@BUILD_STATIC_TRUE@ cp -pf libuniquewm_fixed.a .libs/libuniquewm.a
+
+@BUILD_STATIC_TRUE@.libs/libuniquewm.a: libuniquewm.la
+
+@BUILD_STATIC_FALSE@clean-local:
+
+@BUILD_STATIC_FALSE@all-local:
+# 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/wm/unique/classes/Makefile.am b/Source/DirectFB/wm/unique/classes/Makefile.am
new file mode 100755
index 0000000..85b10d2
--- /dev/null
+++ b/Source/DirectFB/wm/unique/classes/Makefile.am
@@ -0,0 +1,22 @@
+## Makefile.am for DirectFB/wm/unique/classes
+
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/wm
+
+AM_CPPFLAGS = \
+ -DMODULEDIR=\"@MODULEDIR@\" \
+ -DSOPATH=\"@SOPATH@\"
+
+
+noinst_LTLIBRARIES = libunique_classes.la
+
+libunique_classes_la_SOURCES = \
+ foo.c \
+ frame.c \
+ root.c \
+ window.c
diff --git a/Source/DirectFB/wm/unique/classes/Makefile.in b/Source/DirectFB/wm/unique/classes/Makefile.in
new file mode 100755
index 0000000..7a43f3e
--- /dev/null
+++ b/Source/DirectFB/wm/unique/classes/Makefile.in
@@ -0,0 +1,527 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = wm/unique/classes
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libunique_classes_la_LIBADD =
+am_libunique_classes_la_OBJECTS = foo.lo frame.lo root.lo window.lo
+libunique_classes_la_OBJECTS = $(am_libunique_classes_la_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libunique_classes_la_SOURCES)
+DIST_SOURCES = $(libunique_classes_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/wm
+
+AM_CPPFLAGS = \
+ -DMODULEDIR=\"@MODULEDIR@\" \
+ -DSOPATH=\"@SOPATH@\"
+
+noinst_LTLIBRARIES = libunique_classes.la
+libunique_classes_la_SOURCES = \
+ foo.c \
+ frame.c \
+ root.c \
+ window.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu wm/unique/classes/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu wm/unique/classes/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libunique_classes.la: $(libunique_classes_la_OBJECTS) $(libunique_classes_la_DEPENDENCIES)
+ $(LINK) $(libunique_classes_la_OBJECTS) $(libunique_classes_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/root.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+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)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-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:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# 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/wm/unique/classes/foo.c b/Source/DirectFB/wm/unique/classes/foo.c
new file mode 100755
index 0000000..3eafdd1
--- /dev/null
+++ b/Source/DirectFB/wm/unique/classes/foo.c
@@ -0,0 +1,232 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <core/gfxcard.h>
+#include <core/state.h>
+
+#include <misc/util.h>
+
+#include <unique/context.h>
+#include <unique/internal.h>
+#include <unique/stret.h>
+#include <unique/window.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_Foo, "UniQuE/Foo", "UniQuE's Foo Region Class" );
+
+static DFBResult
+foo_get_input( StretRegion *region,
+ void *region_data,
+ unsigned long arg,
+ int index,
+ int x,
+ int y,
+ UniqueInputChannel **ret_channel )
+{
+ UniqueContext *context;
+ UniqueWindow *window = region_data;
+
+ D_MAGIC_ASSERT( region, StretRegion );
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( ret_channel != NULL );
+
+ D_DEBUG_AT( UniQuE_Foo, "foo_get_input( region %p, window %p, index %d, x %d, y %d )\n",
+ region, window, index, x, y );
+
+ switch (index) {
+ case UDCI_KEYBOARD:
+ case UDCI_WHEEL:
+ *ret_channel = window->channel;
+ break;
+
+ case UDCI_POINTER:
+// *ret_channel = window->channel;
+ *ret_channel = context->foo_channel;
+ break;
+
+ default:
+ *ret_channel = NULL;
+ break;
+ }
+
+ return DFB_OK;
+}
+
+static void
+foo_update( StretRegion *region,
+ void *region_data,
+ void *update_data,
+ unsigned long arg,
+ int x,
+ int y,
+ const DFBRegion *updates,
+ int num )
+{
+ int i;
+ DFBRegion clip;
+ DFBDimension size;
+ bool visible;
+ WMShared *shared;
+ UniqueContext *context;
+ UniqueWindow *window = region_data;
+ CardState *state = update_data;
+ DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
+
+ D_ASSERT( region != NULL );
+ D_ASSERT( region_data != NULL );
+ D_ASSERT( update_data != NULL );
+ D_ASSERT( updates != NULL );
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+ D_MAGIC_ASSERT( state, CardState );
+
+ shared = window->shared;
+
+ D_MAGIC_ASSERT( shared, WMShared );
+ D_ASSERT( shared->foo_surface != NULL );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ visible = D_FLAGS_IS_SET( window->flags, UWF_VISIBLE );
+
+ D_DEBUG_AT( UniQuE_Foo, "foo_update( region %p, window %p, visible %s, num %d )\n",
+ region, window, visible ? "yes" : "no", num );
+#if D_DEBUG_ENABLED
+ for (i=0; i<num; i++) {
+ D_DEBUG_AT( UniQuE_Foo, " (%d) %4d,%4d - %4dx%4d\n",
+ i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) );
+ }
+#endif
+
+ if (!visible)
+ return;
+
+ stret_region_get_size( region, &size );
+
+ /* Use per pixel alpha blending. */
+ flags |= DSBLIT_BLEND_ALPHACHANNEL;
+
+ /* Use global alpha blending. */
+ if (window->opacity != 0xFF) {
+ flags |= DSBLIT_BLEND_COLORALPHA;
+
+ /* Set opacity as blending factor. */
+ if (state->color.a != window->opacity) {
+ state->color.a = window->opacity;
+ state->modified |= SMF_COLOR;
+ }
+ }
+
+ /* Use colorizing if the color is not white. */
+ if (context->color.r != 0xff || context->color.g != 0xff || context->color.b != 0xff) {
+ flags |= DSBLIT_COLORIZE;
+
+ state->color.r = context->color.r;
+ state->color.g = context->color.g;
+ state->color.b = context->color.b;
+
+ state->modified |= SMF_COLOR;
+ }
+
+ /* Set blitting flags. */
+ dfb_state_set_blitting_flags( state, flags );
+
+ /* Set blitting source. */
+ state->source = shared->foo_surface;
+ state->modified |= SMF_SOURCE;
+
+ switch (arg) {
+ case UFI_N:
+ case UFI_E:
+ case UFI_S:
+ case UFI_W:
+ clip = state->clip;
+
+/* for (i=0; i<num; i++) {
+ DFBRegion update = DFB_REGION_INIT_TRANSLATED( &updates[i], x, y );
+ DFBRectangle source = shared->foo_rects[arg];
+ DFBRectangle dest = { x, y, size.w, size.h };
+
+ dfb_state_set_clip( state, &update );
+
+ dfb_gfxcard_stretchblit( &source, &dest, state );
+ }*/
+ for (i=0; i<num; i++) {
+ DFBRegion update = DFB_REGION_INIT_TRANSLATED( &updates[i], x, y );
+ DFBRectangle source = shared->foo_rects[arg];
+
+ dfb_state_set_clip( state, &update );
+
+ dfb_gfxcard_tileblit( &source, x, y, x + size.w - 1, y + size.h - 1, state );
+ }
+
+ dfb_state_set_clip( state, &clip );
+ break;
+
+ case UFI_NE:
+ case UFI_SE:
+ case UFI_SW:
+ case UFI_NW:
+ for (i=0; i<num; i++) {
+ DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] );
+
+ dfb_rectangle_translate( &rect, shared->foo_rects[arg].x, shared->foo_rects[arg].y );
+
+ dfb_gfxcard_blit( &rect, x + updates[i].x1, y + updates[i].y1, state );
+ }
+ break;
+
+ default:
+ D_BUG( "invalid arg" );
+ }
+
+ /* Reset blitting source. */
+ state->source = NULL;
+ state->modified |= SMF_SOURCE;
+}
+
+const StretRegionClass unique_foo_region_class = {
+ .GetInput = foo_get_input,
+ .Update = foo_update,
+};
+
diff --git a/Source/DirectFB/wm/unique/classes/frame.c b/Source/DirectFB/wm/unique/classes/frame.c
new file mode 100755
index 0000000..a07ad03
--- /dev/null
+++ b/Source/DirectFB/wm/unique/classes/frame.c
@@ -0,0 +1,53 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <core/gfxcard.h>
+#include <core/state.h>
+#include <core/windows_internal.h>
+
+#include <misc/util.h>
+
+#include <unique/context.h>
+#include <unique/stret.h>
+#include <unique/internal.h>
+
+
+//D_DEBUG_DOMAIN( UniQuE_Frame, "UniQuE/Frame", "UniQuE's Frame Region Class" );
+
+const StretRegionClass unique_frame_region_class = {
+ .GetInput = NULL,
+};
+
diff --git a/Source/DirectFB/wm/unique/classes/root.c b/Source/DirectFB/wm/unique/classes/root.c
new file mode 100755
index 0000000..72dcf87
--- /dev/null
+++ b/Source/DirectFB/wm/unique/classes/root.c
@@ -0,0 +1,206 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <core/gfxcard.h>
+#include <core/palette.h>
+#include <core/state.h>
+#include <core/surface.h>
+#include <core/windows_internal.h>
+
+#include <misc/util.h>
+
+#include <unique/context.h>
+#include <unique/internal.h>
+#include <unique/stret.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_Root, "UniQuE/Root", "UniQuE's Root Region Class" );
+
+
+static void
+root_update( StretRegion *region,
+ void *region_data,
+ void *update_data,
+ unsigned long arg,
+ int x,
+ int y,
+ const DFBRegion *updates,
+ int num )
+{
+ int i;
+ CoreWindowStack *stack;
+ UniqueContext *context = region_data;
+ CardState *state = update_data;
+
+ D_ASSERT( region != NULL );
+ D_ASSERT( region_data != NULL );
+ D_ASSERT( update_data != NULL );
+ D_ASSERT( updates != NULL );
+
+ D_ASSERT( x == 0 );
+ D_ASSERT( y == 0 );
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+ D_MAGIC_ASSERT( state, CardState );
+
+ stack = context->stack;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( stack->bg.image != NULL || (stack->bg.mode != DLBM_IMAGE &&
+ stack->bg.mode != DLBM_TILE) );
+
+ D_DEBUG_AT( UniQuE_Root, "root_update( region %p, num %d )\n", region, num );
+#if D_DEBUG_ENABLED
+ for (i=0; i<num; i++) {
+ D_DEBUG_AT( UniQuE_Root, " (%d) %4d,%4d - %4dx%4d\n",
+ i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) );
+ }
+#endif
+
+ switch (stack->bg.mode) {
+ case DLBM_COLOR: {
+ CoreSurface *dest = state->destination;
+ DFBColor *color = &stack->bg.color;
+ DFBRectangle rects[num];
+
+ /* Set the background color. */
+ if (DFB_PIXELFORMAT_IS_INDEXED( dest->config.format ))
+ dfb_state_set_color_index( state,
+ dfb_palette_search( dest->palette, color->r,
+ color->g, color->b, color->a ) );
+ else
+ dfb_state_set_color( state, color );
+
+ for (i=0; i<num; i++)
+ dfb_rectangle_from_region( &rects[i], &updates[i] );
+
+ /* Simply fill the background. */
+ dfb_gfxcard_fillrectangles( rects, num, state );
+
+ break;
+ }
+
+ case DLBM_IMAGE: {
+ CoreSurface *bg = stack->bg.image;
+
+ /* Set blitting source. */
+ state->source = bg;
+ state->modified |= SMF_SOURCE;
+
+ /* Set blitting flags. */
+ dfb_state_set_blitting_flags( state, DSBLIT_NOFX );
+
+ /* Check the size of the background image. */
+ if (bg->config.size.w == stack->width && bg->config.size.h == stack->height) {
+ for (i=0; i<num; i++) {
+ DFBRectangle dst = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] );
+
+ /* Simple blit for 100% fitting background image. */
+ dfb_gfxcard_blit( &dst, dst.x, dst.y, state );
+ }
+ }
+ else {
+ DFBRegion clip = state->clip;
+
+ for (i=0; i<num; i++) {
+ DFBRectangle src = { 0, 0, bg->config.size.w, bg->config.size.h };
+ DFBRectangle dst = { 0, 0, stack->width, stack->height };
+
+ /* Change clipping region. */
+ dfb_state_set_clip( state, &updates[i] );
+
+ /* Stretch blit for non fitting background images. */
+ dfb_gfxcard_stretchblit( &src, &dst, state );
+ }
+
+ /* Restore clipping region. */
+ dfb_state_set_clip( state, &clip );
+ }
+
+ /* Reset blitting source. */
+ state->source = NULL;
+ state->modified |= SMF_SOURCE;
+
+ break;
+ }
+
+ case DLBM_TILE: {
+ CoreSurface *bg = stack->bg.image;
+ DFBRegion clip = state->clip;
+
+ /* Set blitting source. */
+ state->source = bg;
+ state->modified |= SMF_SOURCE;
+
+ /* Set blitting flags. */
+ dfb_state_set_blitting_flags( state, DSBLIT_NOFX );
+
+ for (i=0; i<num; i++) {
+ DFBRectangle src = { 0, 0, bg->config.size.w, bg->config.size.h };
+
+ /* Change clipping region. */
+ dfb_state_set_clip( state, &updates[i] );
+
+ /* Tiled blit (aligned). */
+ dfb_gfxcard_tileblit( &src, 0, 0, stack->width, stack->height, state );
+ }
+
+ /* Restore clipping region. */
+ dfb_state_set_clip( state, &clip );
+
+ /* Reset blitting source. */
+ state->source = NULL;
+ state->modified |= SMF_SOURCE;
+
+ break;
+ }
+
+ case DLBM_DONTCARE:
+ break;
+
+ default:
+ D_BUG( "unknown background mode" );
+ break;
+ }
+}
+
+/*
+ * The root region is the desktop background.
+ */
+const StretRegionClass unique_root_region_class = {
+ .Update = root_update,
+};
+
diff --git a/Source/DirectFB/wm/unique/classes/window.c b/Source/DirectFB/wm/unique/classes/window.c
new file mode 100755
index 0000000..db9cbaf
--- /dev/null
+++ b/Source/DirectFB/wm/unique/classes/window.c
@@ -0,0 +1,165 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <core/gfxcard.h>
+#include <core/state.h>
+#include <core/surface.h>
+#include <core/windows_internal.h>
+
+#include <misc/util.h>
+
+#include <unique/context.h>
+#include <unique/internal.h>
+#include <unique/stret.h>
+#include <unique/window.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_Window, "UniQuE/WindowReg", "UniQuE's Window Region Class" );
+
+static DFBResult
+window_get_input( StretRegion *region,
+ void *region_data,
+ unsigned long arg,
+ int index,
+ int x,
+ int y,
+ UniqueInputChannel **ret_channel )
+{
+ UniqueWindow *window = region_data;
+
+ D_MAGIC_ASSERT( region, StretRegion );
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( ret_channel != NULL );
+
+ D_DEBUG_AT( UniQuE_Window, "window_get_input( region %p, window %p, index %d, x %d, y %d )\n",
+ region, window, index, x, y );
+
+ *ret_channel = window->channel;
+
+ return DFB_OK;
+}
+
+static void
+window_update( StretRegion *region,
+ void *region_data,
+ void *update_data,
+ unsigned long arg,
+ int x,
+ int y,
+ const DFBRegion *updates,
+ int num )
+{
+ int i;
+ DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
+ UniqueWindow *window = region_data;
+ CardState *state = update_data;
+ bool alpha = arg;
+ bool visible;
+
+ D_ASSERT( updates != NULL );
+
+ D_MAGIC_ASSERT( region, StretRegion );
+ D_MAGIC_ASSERT( window, UniqueWindow );
+ D_MAGIC_ASSERT( state, CardState );
+
+ D_ASSERT( window->surface != NULL );
+
+ visible = D_FLAGS_IS_SET( window->flags, UWF_VISIBLE );
+
+ D_DEBUG_AT( UniQuE_Window, "window_update( region %p, window %p, visible %s, num %d )\n",
+ region, window, visible ? "yes" : "no", num );
+#if D_DEBUG_ENABLED
+ for (i=0; i<num; i++) {
+ D_DEBUG_AT( UniQuE_Window, " (%d) %4d,%4d - %4dx%4d\n",
+ i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) );
+ }
+#endif
+
+ if (!visible)
+ return;
+
+ /* Use per pixel alpha blending. */
+ if (alpha && (window->options & DWOP_ALPHACHANNEL))
+ flags |= DSBLIT_BLEND_ALPHACHANNEL;
+
+ /* Use global alpha blending. */
+ if (window->opacity != 0xFF) {
+ flags |= DSBLIT_BLEND_COLORALPHA;
+
+ /* Set opacity as blending factor. */
+ if (state->color.a != window->opacity) {
+ state->color.a = window->opacity;
+ state->modified |= SMF_COLOR;
+ }
+ }
+
+ /* Use source color keying. */
+ if (window->options & DWOP_COLORKEYING) {
+ flags |= DSBLIT_SRC_COLORKEY;
+
+ /* Set window color key. */
+ dfb_state_set_src_colorkey( state, window->color_key );
+ }
+
+ /* Use automatic deinterlacing. */
+ if (window->surface->config.caps & DSCAPS_INTERLACED)
+ flags |= DSBLIT_DEINTERLACE;
+
+ /* Set blitting flags. */
+ dfb_state_set_blitting_flags( state, flags );
+
+ /* Set blitting source. */
+ state->source = window->surface;
+ state->modified |= SMF_SOURCE;
+
+ for (i=0; i<num; i++) {
+ DFBRectangle src = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] );
+
+ /* Blit from the window to the region being updated. */
+ dfb_gfxcard_blit( &src, x + src.x, y + src.y, state );
+ }
+
+ /* Reset blitting source. */
+ state->source = NULL;
+ state->modified |= SMF_SOURCE;
+}
+
+const StretRegionClass unique_window_region_class = {
+ .GetInput = window_get_input,
+ .Update = window_update,
+};
+
diff --git a/Source/DirectFB/wm/unique/context.c b/Source/DirectFB/wm/unique/context.c
new file mode 100755
index 0000000..cb77b39
--- /dev/null
+++ b/Source/DirectFB/wm/unique/context.c
@@ -0,0 +1,711 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <fusion/object.h>
+#include <fusion/shmalloc.h>
+
+#include <core/coretypes.h>
+#include <core/input.h>
+#include <core/layer_context.h>
+#include <core/layer_region.h>
+#include <core/layers.h>
+#include <core/layers_internal.h> /* FIXME */
+#include <core/state.h>
+#include <core/surface.h>
+#include <core/windowstack.h>
+#include <core/windows_internal.h> /* FIXME */
+
+#include <gfx/util.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+#include <unique/context.h>
+#include <unique/device.h>
+#include <unique/input_channel.h>
+#include <unique/input_switch.h>
+#include <unique/internal.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_Context, "UniQuE/Context", "UniQuE's Stack Context" );
+
+
+static const ReactionFunc unique_context_globals[] = {
+ _unique_wm_module_context_listener,
+ NULL
+};
+
+/**************************************************************************************************/
+
+static void
+context_destructor( FusionObject *object, bool zombie, void *ctx )
+{
+ int i;
+ UniqueContext *context = (UniqueContext*) object;
+
+ D_DEBUG_AT( UniQuE_Context, "destroying %p (stack %p)%s\n",
+ context, context->stack, zombie ? " (ZOMBIE)" : "");
+
+ D_ASSUME( fusion_vector_is_empty( &context->windows ) );
+
+ unique_context_notify( context, UCNF_DESTROYED );
+
+ unique_device_detach_global( context->devices[UDCI_POINTER], &context->cursor_reaction );
+
+
+ unique_input_switch_drop( context->input_switch, context->foo_channel );
+
+ unique_input_channel_destroy( context->foo_channel );
+
+ unique_input_switch_destroy( context->input_switch );
+
+
+ for (i=0; i<_UDCI_NUM; i++)
+ unique_device_destroy( context->devices[i] );
+
+
+ while (fusion_vector_has_elements( &context->windows )) {
+ unique_window_destroy( fusion_vector_at( &context->windows, 0 ) );
+ }
+
+ stret_region_destroy( context->root );
+
+
+ fusion_vector_destroy( &context->windows );
+
+ dfb_surface_unlink( &context->surface );
+
+ dfb_layer_region_unlink( &context->region );
+
+ D_MAGIC_CLEAR( context );
+
+ fusion_object_destroy( object );
+}
+
+FusionObjectPool *
+unique_context_pool_create( const FusionWorld *world )
+{
+ return fusion_object_pool_create( "UniQuE Context Pool", sizeof(UniqueContext),
+ sizeof(UniqueContextNotification), context_destructor, NULL, world );
+}
+
+/**************************************************************************************************/
+
+static DFBEnumerationResult
+connect_device( CoreInputDevice *source,
+ void *ctx )
+{
+ UniqueDevice *device = ctx;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ unique_device_connect( device, source );
+
+ return DFENUM_OK;
+}
+
+static DFBResult
+create_devices( CoreDFB *core,
+ UniqueContext *context,
+ WMShared *shared )
+{
+ int i;
+ DFBResult ret;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ for (i=0; i<_UDCI_NUM; i++) {
+ DFBInputDeviceCapabilities caps;
+
+ ret = unique_device_create( core, context, shared->device_classes[i],
+ context, &context->devices[i] );
+ if (ret)
+ goto error;
+
+ ret = unique_input_switch_add( context->input_switch, context->devices[i] );
+ if (ret)
+ goto error_add;
+
+ switch (i) {
+ case UDCI_POINTER:
+ caps = DICAPS_AXES | DICAPS_BUTTONS;
+ break;
+
+ case UDCI_WHEEL:
+ caps = DICAPS_AXES;
+ break;
+
+ case UDCI_KEYBOARD:
+ caps = DICAPS_KEYS;
+ break;
+
+ default:
+ caps = DICAPS_ALL;
+ break;
+ }
+
+ dfb_input_enumerate_devices( connect_device, context->devices[i], caps );
+ }
+
+ return DFB_OK;
+
+
+error_add:
+ unique_device_destroy( context->devices[i] );
+
+error:
+ while (--i >= 0)
+ unique_device_destroy( context->devices[i] );
+
+ return ret;
+}
+
+/**************************************************************************************************/
+
+DFBResult
+unique_context_create( CoreDFB *core,
+ CoreWindowStack *stack,
+ CoreLayerRegion *region,
+ DFBDisplayLayerID layer_id,
+ WMShared *shared,
+ UniqueContext **ret_context )
+{
+ int i;
+ DFBResult ret;
+ UniqueContext *context;
+
+ D_ASSERT( stack != NULL );
+ D_MAGIC_ASSERT( shared, WMShared );
+ D_ASSERT( ret_context != NULL );
+
+ context = unique_wm_create_context();
+ if (!context)
+ return DFB_FUSION;
+
+ context->stack = stack;
+ context->shared = shared;
+ context->layer_id = layer_id;
+ context->color = (DFBColor) { 0xff, 0xa0, 0xd0, 0xf0 };
+ context->shmpool = stack->shmpool;
+
+ fusion_vector_init( &context->windows, 16, context->shmpool );
+
+ /* Create Root Region. */
+ ret = stret_region_create( shared->region_classes[URCI_ROOT], context, 0,
+ SRF_ACTIVE | SRF_OUTPUT, _UNRL_NUM,
+ 0, 0, INT_MAX, INT_MAX,
+ NULL, 0, context->shmpool, &context->root );
+ if (ret)
+ goto error;
+
+ /* Link layer region. */
+ ret = dfb_layer_region_link( &context->region, region );
+ if (ret)
+ goto error;
+
+ /* Get the region's surface. */
+ ret = dfb_layer_region_get_surface( region, &context->surface );
+ if (ret)
+ goto error;
+
+ /* Make it global. */
+ ret = dfb_surface_globalize( context->surface );
+ if (ret) {
+ dfb_surface_unref( context->surface );
+ goto error;
+ }
+
+ D_MAGIC_SET( context, UniqueContext );
+
+ ret = unique_input_switch_create( context, &context->input_switch );
+ if (ret)
+ goto error_switch;
+
+ ret = create_devices( core, context, shared );
+ if (ret)
+ goto error_devices;
+
+ ret = unique_input_channel_create( core, context, &context->foo_channel );
+ if (ret)
+ goto error_foo_channel;
+
+ ret = unique_device_attach_global( context->devices[UDCI_POINTER],
+ UNIQUE_CURSOR_DEVICE_LISTENER,
+ context, &context->cursor_reaction );
+ if (ret)
+ goto error_attach_cursor;
+
+ /* Change global reaction lock. */
+ fusion_object_set_lock( &context->object, &context->stack->context->lock );
+
+ /* Activate Object. */
+ fusion_object_activate( &context->object );
+
+ /* Return new context. */
+ *ret_context = context;
+
+ return DFB_OK;
+
+
+error_attach_cursor:
+ unique_input_channel_destroy( context->foo_channel );
+
+error_foo_channel:
+ for (i=0; i<_UDCI_NUM; i++)
+ unique_device_destroy( context->devices[i] );
+
+error_devices:
+ unique_input_switch_destroy( context->input_switch );
+
+error_switch:
+ D_MAGIC_CLEAR( context );
+
+ dfb_surface_unlink( &context->surface );
+
+error:
+ if (context->region)
+ dfb_layer_region_unlink( &context->region );
+
+ if (context->root)
+ stret_region_destroy( context->root );
+
+ fusion_vector_destroy( &context->windows );
+
+ fusion_object_destroy( &context->object );
+
+ return ret;
+}
+
+DFBResult
+unique_context_notify( UniqueContext *context,
+ UniqueContextNotificationFlags flags )
+{
+ UniqueContextNotification notification;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( flags != UCNF_NONE );
+
+ D_ASSERT( ! (flags & ~UCNF_ALL) );
+
+ notification.flags = flags;
+ notification.context = context;
+
+ return unique_context_dispatch( context, &notification, unique_context_globals );
+}
+
+DFBResult
+unique_context_set_active( UniqueContext *context,
+ bool active )
+{
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSUME( context->active != active );
+
+ if (context->active == active)
+ return DFB_OK;
+
+ context->active = active;
+
+ if (active)
+ return dfb_windowstack_repaint_all( context->stack );
+
+ /* Force release of all pressed keys. */
+ return unique_context_flush_keys( context );
+}
+
+DFBResult
+unique_context_set_color( UniqueContext *context,
+ const DFBColor *color )
+{
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( color != NULL );
+
+ context->color = *color;
+
+ return dfb_windowstack_repaint_all( context->stack );
+}
+
+/* HACK: dumped in here for now, will move into cursor class */
+void
+unique_draw_cursor( CoreWindowStack *stack, UniqueContext *context, CardState *state, DFBRegion *region )
+{
+ DFBRectangle src;
+ DFBSurfaceBlittingFlags flags = DSBLIT_BLEND_ALPHACHANNEL;
+
+ D_ASSERT( stack != NULL );
+ D_MAGIC_ASSERT( context, UniqueContext );
+ D_MAGIC_ASSERT( state, CardState );
+ DFB_REGION_ASSERT( region );
+
+ D_ASSUME( stack->cursor.opacity > 0 );
+
+ /* Initialize source rectangle. */
+ src.x = region->x1 - stack->cursor.x + stack->cursor.hot.x;
+ src.y = region->y1 - stack->cursor.y + stack->cursor.hot.y;
+ src.w = region->x2 - region->x1 + 1;
+ src.h = region->y2 - region->y1 + 1;
+
+ /* Use global alpha blending. */
+ if (stack->cursor.opacity != 0xFF) {
+ flags |= DSBLIT_BLEND_COLORALPHA;
+
+ /* Set opacity as blending factor. */
+ if (state->color.a != stack->cursor.opacity) {
+ state->color.a = stack->cursor.opacity;
+ state->modified |= SMF_COLOR;
+ }
+ }
+
+ /* Different compositing methods depending on destination format. */
+ if (flags & DSBLIT_BLEND_ALPHACHANNEL) {
+ if (DFB_PIXELFORMAT_HAS_ALPHA( state->destination->config.format )) {
+ /*
+ * Always use compliant Porter/Duff SRC_OVER,
+ * if the destination has an alpha channel.
+ *
+ * Cd = destination color (non-premultiplied)
+ * Ad = destination alpha
+ *
+ * Cs = source color (non-premultiplied)
+ * As = source alpha
+ *
+ * Ac = color alpha
+ *
+ * cd = Cd * Ad (premultiply destination)
+ * cs = Cs * As (premultiply source)
+ *
+ * The full equation to calculate resulting color and alpha (premultiplied):
+ *
+ * cx = cd * (1-As*Ac) + cs * Ac
+ * ax = Ad * (1-As*Ac) + As * Ac
+ */
+ dfb_state_set_src_blend( state, DSBF_ONE );
+
+ /* Need to premultiply source with As*Ac or only with Ac? */
+ if (! (stack->cursor.surface->config.caps & DSCAPS_PREMULTIPLIED))
+ flags |= DSBLIT_SRC_PREMULTIPLY;
+ else if (flags & DSBLIT_BLEND_COLORALPHA)
+ flags |= DSBLIT_SRC_PREMULTCOLOR;
+
+ /* Need to premultiply/demultiply destination? */
+// if (! (state->destination->caps & DSCAPS_PREMULTIPLIED))
+// flags |= DSBLIT_DST_PREMULTIPLY | DSBLIT_DEMULTIPLY;
+ }
+ else {
+ /*
+ * We can avoid DSBLIT_SRC_PREMULTIPLY for destinations without an alpha channel
+ * by using another blending function, which is more likely that it's accelerated
+ * than premultiplication at this point in time.
+ *
+ * This way the resulting alpha (ax) doesn't comply with SRC_OVER,
+ * but as the destination doesn't have an alpha channel it's no problem.
+ *
+ * As the destination's alpha value is always 1.0 there's no need for
+ * premultiplication. The resulting alpha value will also be 1.0 without
+ * exceptions, therefore no need for demultiplication.
+ *
+ * cx = Cd * (1-As*Ac) + Cs*As * Ac (still same effect as above)
+ * ax = Ad * (1-As*Ac) + As*As * Ac (wrong, but discarded anyways)
+ */
+ if (stack->cursor.surface->config.caps & DSCAPS_PREMULTIPLIED) {
+ /* Need to premultiply source with Ac? */
+ if (flags & DSBLIT_BLEND_COLORALPHA)
+ flags |= DSBLIT_SRC_PREMULTCOLOR;
+
+ dfb_state_set_src_blend( state, DSBF_ONE );
+ }
+ else
+ dfb_state_set_src_blend( state, DSBF_SRCALPHA );
+ }
+ }
+
+ /* Set blitting flags. */
+ dfb_state_set_blitting_flags( state, flags );
+
+ /* Set blitting source. */
+ state->source = stack->cursor.surface;
+ state->modified |= SMF_SOURCE;
+
+ /* Blit from the window to the region being updated. */
+ dfb_gfxcard_blit( &src, region->x1, region->y1, state );
+
+ /* Reset blitting source. */
+ state->source = NULL;
+ state->modified |= SMF_SOURCE;
+}
+
+DFBResult
+unique_context_update( UniqueContext *context,
+ const DFBRegion *updates,
+ int num,
+ DFBSurfaceFlipFlags flags )
+{
+ int i;
+ CoreLayer *layer;
+ CardState *state;
+ int count = 0;
+ DFBRegion root;
+ DFBRegion regions[num];
+ DFBRegion cursor_inter;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+ D_ASSERT( context->stack != NULL );
+
+ D_ASSERT( updates != NULL );
+ D_ASSERT( num > 0 );
+
+ if (!context->active)
+ return DFB_OK;
+
+ D_DEBUG_AT( UniQuE_Context, "unique_context_update( num %d, flags 0x%08x )\n", num, flags );
+
+ layer = dfb_layer_at( context->layer_id );
+ state = dfb_layer_state( layer );
+
+ root = DFB_REGION_INIT_FROM_RECTANGLE_VALS( 0, 0, context->width, context->height );
+
+ for (i=0; i<num; i++) {
+ const DFBRegion *region = &updates[i];
+
+ if (!dfb_region_region_intersects( region, &root ))
+ continue;
+
+ regions[count++] = DFB_REGION_INIT_INTERSECTED( region, 0, 0, root.x2, root.y2 );
+
+ D_DEBUG_AT( UniQuE_Context, " (%2d) %4d, %4d - %4dx%4d\n", i,
+ DFB_RECTANGLE_VALS_FROM_REGION( &regions[count-1] ) );
+ }
+
+ if (!count) {
+ D_DEBUG_AT( UniQuE_Context, " -> No intersection with root!\n" );
+ return DFB_OK;
+ }
+
+ /* Set destination. */
+ state->destination = context->surface;
+ state->modified |= SMF_DESTINATION;
+
+ for (i=0; i<count; i++) {
+ const DFBRegion *update = &regions[i];
+
+ /* Set clipping region. */
+ dfb_state_set_clip( state, update );
+
+ /* Compose updated region. */
+ stret_region_update( context->root, update, state );
+
+ /* Update cursor? */
+ cursor_inter = context->cursor_region;
+ if (context->cursor_drawn && dfb_region_region_intersect( &cursor_inter, update )) {
+ DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &cursor_inter );
+
+ D_ASSUME( context->cursor_bs_valid );
+
+ dfb_gfx_copy_to( context->surface, context->cursor_bs, &rect,
+ rect.x - context->cursor_region.x1,
+ rect.y - context->cursor_region.y1, true );
+
+ unique_draw_cursor( context->stack, context, state, &cursor_inter );
+ }
+ }
+
+ /* Reset destination. */
+ state->destination = NULL;
+ state->modified |= SMF_DESTINATION;
+
+ /* Software cursor code relies on a valid back buffer. */
+ if (context->stack->cursor.enabled)
+ flags |= DSFLIP_BLIT;
+
+ /* Flip all updated regions. */
+ for (i=0; i<count; i++) {
+ const DFBRegion *update = &regions[i];
+
+ dfb_layer_region_flip_update( context->region, update, flags );
+ }
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_context_resize( UniqueContext *context,
+ int width,
+ int height )
+{
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ context->width = width;
+ context->height = height;
+
+ stret_region_resize( context->root, width, height );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_context_flush_keys( UniqueContext *context )
+{
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_context_window_at( UniqueContext *context,
+ int x,
+ int y,
+ UniqueWindow **ret_window )
+{
+ int i;
+ CoreWindowStack *stack;
+ WMShared *shared;
+ UniqueWindow *window = NULL;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( ret_window != NULL );
+
+ stack = context->stack;
+ shared = context->shared;
+
+ D_ASSERT( stack != NULL );
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ if (stack->cursor.enabled) {
+ StretRegion *region;
+
+ if (x < 0)
+ x = stack->cursor.x;
+ if (y < 0)
+ y = stack->cursor.y;
+
+ region = stret_region_at( context->root, x, y, SRF_INPUT, SRCID_UNKNOWN );
+ if (region && (region->clazz == shared->region_classes[URCI_FOO] ||
+ region->clazz == shared->region_classes[URCI_WINDOW]))
+ {
+ window = stret_region_data( region );
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+ }
+ }
+ else {
+ fusion_vector_foreach_reverse (window, i, context->windows)
+ if (window->opacity && !(window->options & DWOP_GHOST))
+ break;
+
+ if (i < 0)
+ window = NULL;
+ }
+
+ D_MAGIC_ASSERT_IF( window, UniqueWindow );
+
+ *ret_window = window;
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_context_lookup_window( UniqueContext *context,
+ DFBWindowID window_id,
+ UniqueWindow **ret_window )
+{
+ int i;
+ UniqueWindow *window = NULL;
+
+ D_ASSERT( ret_window != NULL );
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ fusion_vector_foreach_reverse (window, i, context->windows) {
+ if (window->window->id == window_id)
+ break;
+ }
+
+ *ret_window = window;
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_context_enum_windows( UniqueContext *context,
+ CoreWMWindowCallback callback,
+ void *callback_ctx )
+{
+ int i;
+ UniqueWindow *window = NULL;
+
+ D_ASSERT( callback != NULL );
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ fusion_vector_foreach_reverse (window, i, context->windows) {
+ if (callback( window->window, callback_ctx ) != DFENUM_OK)
+ break;
+ }
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+ReactionResult
+_unique_cursor_device_listener( const void *msg_data,
+ void *ctx )
+{
+ const UniqueInputEvent *event = msg_data;
+ UniqueContext *context = ctx;
+
+ D_ASSERT( event != NULL );
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_DEBUG_AT( UniQuE_Context, "_unique_cursor_device_listener( %p, %p )\n", event, context );
+
+ switch (event->type) {
+ case UIET_MOTION:
+ dfb_windowstack_cursor_warp( context->stack, event->pointer.x, event->pointer.y );
+ break;
+
+ default:
+ break;
+ }
+
+ return RS_OK;
+}
+
diff --git a/Source/DirectFB/wm/unique/context.h b/Source/DirectFB/wm/unique/context.h
new file mode 100755
index 0000000..5361caf
--- /dev/null
+++ b/Source/DirectFB/wm/unique/context.h
@@ -0,0 +1,134 @@
+/*
+ (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 __UNIQUE__CONTEXT_H__
+#define __UNIQUE__CONTEXT_H__
+
+#include <directfb.h>
+
+#include <fusion/object.h>
+
+#include <core/wm.h>
+
+#include <unique/types.h>
+
+
+typedef enum {
+ UCNF_NONE = 0x00000000,
+
+ UCNF_DESTROYED = 0x00000001,
+
+ UCNF_WINDOW_ADDED = 0x00000010,
+ UCNF_WINDOW_REMOVED = 0x00000020,
+
+ UCNF_ACTIVATE = 0x00000100,
+ UCNF_DEACTIVATE = 0x00000200,
+
+ UCNF_RESIZE = 0x00001000,
+
+ UCNF_WARP_CURSOR = 0x00010000,
+
+ UCNF_ALL = 0x00011331
+} UniqueContextNotificationFlags;
+
+typedef struct {
+ UniqueContextNotificationFlags flags;
+ UniqueContext *context;
+
+ DFBPoint pos; /* New cursor position (UCNF_WARP_CURSOR) */
+ DFBDimension size; /* New root (desktop) size (UCNF_RESIZE) */
+} UniqueContextNotification;
+
+
+
+DFBResult unique_context_create ( CoreDFB *core,
+ CoreWindowStack *stack,
+ CoreLayerRegion *region,
+ DFBDisplayLayerID layer_id,
+ WMShared *shared,
+ UniqueContext **ret_context );
+
+DFBResult unique_context_notify ( UniqueContext *context,
+ UniqueContextNotificationFlags flags );
+
+DFBResult unique_context_set_active ( UniqueContext *context,
+ bool active );
+
+DFBResult unique_context_set_color ( UniqueContext *context,
+ const DFBColor *color );
+
+
+DFBResult unique_context_update ( UniqueContext *context,
+ const DFBRegion *updates,
+ int num,
+ DFBSurfaceFlipFlags flags );
+
+DFBResult unique_context_resize ( UniqueContext *context,
+ int width,
+ int height );
+
+DFBResult unique_context_flush_keys ( UniqueContext *context );
+
+DFBResult unique_context_window_at ( UniqueContext *context,
+ int x,
+ int y,
+ UniqueWindow **ret_window );
+
+DFBResult unique_context_lookup_window( UniqueContext *context,
+ DFBWindowID window_id,
+ UniqueWindow **ret_window );
+
+DFBResult unique_context_enum_windows ( UniqueContext *context,
+ CoreWMWindowCallback callback,
+ void *callback_ctx );
+
+DFBResult unique_context_warp_cursor ( UniqueContext *context,
+ int x,
+ int y );
+
+
+
+/*
+ * Creates a pool of context objects.
+ */
+FusionObjectPool *unique_context_pool_create( const FusionWorld *world );
+
+/*
+ * Generates unique_context_ref(), unique_context_attach() etc.
+ */
+FUSION_OBJECT_METHODS( UniqueContext, unique_context )
+
+
+/* global reactions */
+
+typedef enum {
+ UNIQUE_WM_MODULE_CONTEXT_LISTENER
+} UNIQUE_CONTEXT_GLOBALS;
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/data/Makefile.am b/Source/DirectFB/wm/unique/data/Makefile.am
new file mode 100755
index 0000000..cd63bfb
--- /dev/null
+++ b/Source/DirectFB/wm/unique/data/Makefile.am
@@ -0,0 +1,31 @@
+## Makefile.am for DirectFB/wm/unique/data
+
+uniquedatadir = $(DATADIR)/unique
+
+all-local: foo.h
+
+clean-local:
+ rm -f foo.h
+
+EXTRA_DIST = \
+ foo_n.png \
+ foo_ne.png \
+ foo_e.png \
+ foo_se.png \
+ foo_s.png \
+ foo_sw.png \
+ foo_w.png \
+ foo_nw.png
+
+if CROSS_COMPILING
+ directfb_csource = $(DIRECTFB_CSOURCE)
+else
+if BUILD_TOOLS
+ directfb_csource = $(top_builddir)/tools/directfb-csource
+else
+ directfb_csource = $(DIRECTFB_CSOURCE)
+endif
+endif
+
+foo.h: $(EXTRA_DIST)
+ $(directfb_csource) --name=foo $(EXTRA_DIST:%=$(srcdir)/%) > foo.h
diff --git a/Source/DirectFB/wm/unique/data/Makefile.in b/Source/DirectFB/wm/unique/data/Makefile.in
new file mode 100755
index 0000000..ad17ea8
--- /dev/null
+++ b/Source/DirectFB/wm/unique/data/Makefile.in
@@ -0,0 +1,420 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = wm/unique/data
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+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@
+uniquedatadir = $(DATADIR)/unique
+EXTRA_DIST = \
+ foo_n.png \
+ foo_ne.png \
+ foo_e.png \
+ foo_se.png \
+ foo_s.png \
+ foo_sw.png \
+ foo_w.png \
+ foo_nw.png
+
+@BUILD_TOOLS_FALSE@@CROSS_COMPILING_FALSE@directfb_csource = $(DIRECTFB_CSOURCE)
+@BUILD_TOOLS_TRUE@@CROSS_COMPILING_FALSE@directfb_csource = $(top_builddir)/tools/directfb-csource
+@CROSS_COMPILING_TRUE@directfb_csource = $(DIRECTFB_CSOURCE)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu wm/unique/data/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu wm/unique/data/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+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 all-local
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+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 -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool clean-local distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am
+
+
+all-local: foo.h
+
+clean-local:
+ rm -f foo.h
+
+foo.h: $(EXTRA_DIST)
+ $(directfb_csource) --name=foo $(EXTRA_DIST:%=$(srcdir)/%) > foo.h
+# 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/wm/unique/data/foo_e.png b/Source/DirectFB/wm/unique/data/foo_e.png
new file mode 100755
index 0000000..db1d2d9
--- /dev/null
+++ b/Source/DirectFB/wm/unique/data/foo_e.png
Binary files differ
diff --git a/Source/DirectFB/wm/unique/data/foo_n.png b/Source/DirectFB/wm/unique/data/foo_n.png
new file mode 100755
index 0000000..ed915dc
--- /dev/null
+++ b/Source/DirectFB/wm/unique/data/foo_n.png
Binary files differ
diff --git a/Source/DirectFB/wm/unique/data/foo_ne.png b/Source/DirectFB/wm/unique/data/foo_ne.png
new file mode 100755
index 0000000..0d94587
--- /dev/null
+++ b/Source/DirectFB/wm/unique/data/foo_ne.png
Binary files differ
diff --git a/Source/DirectFB/wm/unique/data/foo_nw.png b/Source/DirectFB/wm/unique/data/foo_nw.png
new file mode 100755
index 0000000..a411202
--- /dev/null
+++ b/Source/DirectFB/wm/unique/data/foo_nw.png
Binary files differ
diff --git a/Source/DirectFB/wm/unique/data/foo_s.png b/Source/DirectFB/wm/unique/data/foo_s.png
new file mode 100755
index 0000000..fe4e9ff
--- /dev/null
+++ b/Source/DirectFB/wm/unique/data/foo_s.png
Binary files differ
diff --git a/Source/DirectFB/wm/unique/data/foo_se.png b/Source/DirectFB/wm/unique/data/foo_se.png
new file mode 100755
index 0000000..4e15605
--- /dev/null
+++ b/Source/DirectFB/wm/unique/data/foo_se.png
Binary files differ
diff --git a/Source/DirectFB/wm/unique/data/foo_sw.png b/Source/DirectFB/wm/unique/data/foo_sw.png
new file mode 100755
index 0000000..8cb7617
--- /dev/null
+++ b/Source/DirectFB/wm/unique/data/foo_sw.png
Binary files differ
diff --git a/Source/DirectFB/wm/unique/data/foo_w.png b/Source/DirectFB/wm/unique/data/foo_w.png
new file mode 100755
index 0000000..6e75788
--- /dev/null
+++ b/Source/DirectFB/wm/unique/data/foo_w.png
Binary files differ
diff --git a/Source/DirectFB/wm/unique/decoration.c b/Source/DirectFB/wm/unique/decoration.c
new file mode 100755
index 0000000..5b98dcd
--- /dev/null
+++ b/Source/DirectFB/wm/unique/decoration.c
@@ -0,0 +1,190 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+
+#include <fusion/object.h>
+
+#include <core/coretypes.h>
+#include <core/layers_internal.h> /* FIXME */
+#include <core/windows_internal.h> /* FIXME */
+
+#include <misc/util.h>
+
+#include <unique/decoration.h>
+#include <unique/internal.h>
+#include <unique/window.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_Decoration, "UniQuE/Decoration", "UniQuE's Decoration Object" );
+
+
+static const ReactionFunc unique_decoration_globals[] = {
+/* _unique_foo_decoration_listener,*/
+ NULL
+};
+
+/**************************************************************************************************/
+
+static void
+decoration_destructor( FusionObject *object, bool zombie, void *ctx )
+{
+ UniqueDecoration *decoration = (UniqueDecoration*) object;
+
+ D_MAGIC_ASSERT( decoration, UniqueDecoration );
+
+ D_DEBUG_AT( UniQuE_Decoration, "destroying %p%s\n", decoration, zombie ? " (ZOMBIE)" : "");
+
+ unique_window_unlink( &decoration->window );
+ unique_context_unlink( &decoration->context );
+
+ D_MAGIC_CLEAR( decoration );
+
+ fusion_object_destroy( object );
+}
+
+FusionObjectPool *
+unique_decoration_pool_create( const FusionWorld *world )
+{
+ return fusion_object_pool_create( "UniQuE Decoration Pool",
+ sizeof(UniqueDecoration),
+ sizeof(UniqueDecorationNotification),
+ decoration_destructor, NULL, world );
+}
+
+/**************************************************************************************************/
+
+DFBResult
+unique_decoration_create( UniqueWindow *window,
+ UniqueDecorationFlags flags,
+ UniqueDecoration **ret_decoration )
+{
+ DFBResult ret;
+ UniqueDecoration *decoration;
+ UniqueContext *context;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( D_FLAGS_ARE_IN( flags, UDF_ALL ) );
+ D_ASSERT( ret_decoration != NULL );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+
+ /* Create a decoration object. */
+ decoration = unique_wm_create_decoration();
+ if (!decoration)
+ return DFB_FUSION;
+
+ /* Initialize deocration data. */
+ decoration->flags = flags;
+
+ ret = unique_window_link( &decoration->window, window );
+ if (ret)
+ goto error;
+
+ ret = unique_context_link( &decoration->context, window->context );
+ if (ret)
+ goto error;
+
+
+ D_MAGIC_SET( decoration, UniqueDecoration );
+
+
+ /* Change global reaction lock. */
+ fusion_object_set_lock( &decoration->object, &context->stack->context->lock );
+
+ /* activate object */
+ fusion_object_activate( &decoration->object );
+
+ /* return the new decoration */
+ *ret_decoration = decoration;
+
+ return DFB_OK;
+
+error:
+ if (decoration->context)
+ unique_context_unlink( &decoration->context );
+
+ if (decoration->window)
+ unique_window_unlink( &decoration->window );
+
+ fusion_object_destroy( &decoration->object );
+
+ return ret;
+}
+
+DFBResult
+unique_decoration_destroy( UniqueDecoration *decoration )
+{
+ D_MAGIC_ASSERT( decoration, UniqueDecoration );
+
+ D_FLAGS_SET( decoration->flags, UDF_DESTROYED );
+
+ unique_decoration_notify( decoration, UDNF_DESTROYED );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_decoration_notify( UniqueDecoration *decoration,
+ UniqueDecorationNotificationFlags flags )
+{
+ UniqueDecorationNotification notification;
+
+ D_MAGIC_ASSERT( decoration, UniqueDecoration );
+
+ D_ASSERT( flags != UDNF_NONE );
+
+ D_ASSERT( ! (flags & ~UDNF_ALL) );
+
+ notification.flags = flags;
+ notification.decoration = decoration;
+
+ return unique_decoration_dispatch( decoration, &notification, unique_decoration_globals );
+}
+
+DFBResult
+unique_decoration_update( UniqueDecoration *decoration,
+ const DFBRegion *region )
+{
+ D_MAGIC_ASSERT( decoration, UniqueDecoration );
+
+ DFB_REGION_ASSERT_IF( region );
+
+ D_UNIMPLEMENTED();
+
+ return DFB_UNIMPLEMENTED;
+}
+
diff --git a/Source/DirectFB/wm/unique/decoration.h b/Source/DirectFB/wm/unique/decoration.h
new file mode 100755
index 0000000..47e9927
--- /dev/null
+++ b/Source/DirectFB/wm/unique/decoration.h
@@ -0,0 +1,132 @@
+/*
+ (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 __UNIQUE__DECORATION_H__
+#define __UNIQUE__DECORATION_H__
+
+#include <unique/types.h>
+
+#include <directfb.h>
+
+typedef enum {
+ UDF_NONE = 0x00000000,
+
+ UDF_DESTROYED = 0x00000001,
+
+ UDF_ALL = 0x00000001
+} UniqueDecorationFlags;
+
+
+typedef enum {
+ UDNF_NONE = 0x00000000,
+
+ UDNF_DESTROYED = 0x00000001,
+
+ UDNF_ALL = 0x00000001
+} UniqueDecorationNotificationFlags;
+
+typedef struct {
+ UniqueDecorationNotificationFlags flags;
+ UniqueDecoration *decoration;
+} UniqueDecorationNotification;
+
+
+typedef enum {
+ UPOR_TOP_LEFT,
+ UPOR_TOP_MIDDLE,
+ UPOR_TOP_RIGHT,
+ UPOR_MIDDLE_LEFT,
+ UPOR_MIDDLE_MIDDLE,
+ UPOR_MIDDLE_RIGHT,
+ UPOR_BOTTOM_LEFT,
+ UPOR_BOTTOM_MIDDLE,
+ UPOR_BOTTOM_RIGHT
+} UniquePointOfReference;
+
+typedef enum {
+ UDSM_BOTH_ABSOLUTE,
+ UDSM_BOTH_RELATIVE,
+ UDSM_ABSOLUTE_WIDTH,
+ UDSM_ABSOLUTE_HEIGHT
+} UniqueDecorationSizeMode;
+
+
+typedef struct {
+ const UniqueLayout *other;
+ UniquePointOfReference first;
+ UniquePointOfReference second;
+ DFBPoint offset;
+} UniqueLayoutRelation;
+
+struct __UniQuE_UniqueLayout {
+ UniqueLayoutRelation origin;
+ UniqueLayoutRelation extent;
+ UniqueLayoutRelation optional;
+};
+
+
+
+DFBResult unique_decoration_create ( UniqueWindow *window,
+ UniqueDecorationFlags flags,
+ UniqueDecoration **ret_decoration );
+
+DFBResult unique_decoration_destroy ( UniqueDecoration *decoration );
+
+
+DFBResult unique_decoration_notify ( UniqueDecoration *decoration,
+ UniqueDecorationNotificationFlags flags );
+
+
+DFBResult unique_decoration_update ( UniqueDecoration *decoration,
+ const DFBRegion *region );
+
+
+DFBResult unique_decoration_add_item( UniqueDecoration *decoration,
+ const UniqueLayout *layout,
+ UniqueDecorationItem **ret_item );
+
+/*
+ * Creates a pool of decoration objects.
+ */
+FusionObjectPool *unique_decoration_pool_create( const FusionWorld *world );
+
+/*
+ * Generates unique_decoration_ref(), unique_decoration_attach() etc.
+ */
+FUSION_OBJECT_METHODS( UniqueDecoration, unique_decoration )
+
+
+/* global reactions */
+
+typedef enum {
+ UNIQUE_FOO_DECORATION_LISTENER
+} UNIQUE_DECORATION_GLOBALS;
+
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/device.c b/Source/DirectFB/wm/unique/device.c
new file mode 100755
index 0000000..d6b5625
--- /dev/null
+++ b/Source/DirectFB/wm/unique/device.c
@@ -0,0 +1,495 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <fusion/shmalloc.h>
+#include <fusion/vector.h>
+
+#include <core/core.h>
+#include <core/input.h>
+#include <core/layers_internal.h>
+#include <core/windows_internal.h>
+
+#include <misc/util.h>
+
+#include <unique/device.h>
+#include <unique/internal.h>
+
+
+#define MAX_CLASSES 16
+
+
+D_DEBUG_DOMAIN( UniQuE_Device, "UniQuE/Device", "UniQuE's Devices" );
+
+
+static const ReactionFunc unique_device_globals[] = {
+ _unique_input_switch_device_listener,
+ _unique_cursor_device_listener,
+ NULL
+};
+
+/**************************************************************************************************/
+
+typedef struct {
+ DirectLink link;
+
+ int magic;
+
+ DFBInputDeviceID source;
+
+ GlobalReaction reaction;
+} DeviceConnection;
+
+/**************************************************************************************************/
+
+static void purge_connection( UniqueDevice *device,
+ DeviceConnection *connection );
+
+/**************************************************************************************************/
+
+static const UniqueDeviceClass *classes[MAX_CLASSES] = { NULL };
+
+static pthread_mutex_t classes_lock = PTHREAD_MUTEX_INITIALIZER;
+static int classes_count = 0;
+
+/**************************************************************************************************/
+
+DFBResult
+unique_device_class_register( const UniqueDeviceClass *clazz,
+ UniqueDeviceClassID *ret_id )
+{
+ int i;
+
+ D_DEBUG_AT( UniQuE_Device, "unique_device_class_register( %p )\n", clazz );
+
+ D_ASSERT( clazz != NULL );
+ D_ASSERT( ret_id != NULL );
+
+ pthread_mutex_lock( &classes_lock );
+
+ if (classes_count == MAX_CLASSES) {
+ D_WARN( "too many classes" );
+ pthread_mutex_unlock( &classes_lock );
+ return DFB_LIMITEXCEEDED;
+ }
+
+ classes_count++;
+
+ for (i=0; i<MAX_CLASSES; i++) {
+ if (!classes[i]) {
+ classes[i] = clazz;
+ break;
+ }
+ }
+
+ D_DEBUG_AT( UniQuE_Device, " -> New class ID is %d.\n", i );
+
+ D_ASSERT( i < MAX_CLASSES );
+
+ *ret_id = i;
+
+ pthread_mutex_unlock( &classes_lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_device_class_unregister( UniqueDeviceClassID id )
+{
+ D_DEBUG_AT( UniQuE_Device, "unique_device_class_unregister( %d )\n", id );
+
+ pthread_mutex_lock( &classes_lock );
+
+ D_ASSERT( id >= 0 );
+ D_ASSERT( id < MAX_CLASSES );
+ D_ASSERT( classes[id] != NULL );
+
+ classes[id] = NULL;
+
+ classes_count--;
+
+ pthread_mutex_unlock( &classes_lock );
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+DFBResult
+unique_device_create( CoreDFB *core,
+ UniqueContext *context,
+ UniqueDeviceClassID class_id,
+ void *ctx,
+ UniqueDevice **ret_device )
+{
+ DFBResult ret;
+ UniqueDevice *device;
+ const UniqueDeviceClass *clazz;
+
+ D_DEBUG_AT( UniQuE_Device, "unique_device_create( class %d )\n", class_id );
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( class_id >= 0 );
+ D_ASSERT( class_id < MAX_CLASSES );
+
+ clazz = classes[class_id];
+
+ D_ASSERT( clazz != NULL );
+ D_ASSERT( ret_device != NULL );
+
+ /* Allocate device data. */
+ device = SHCALLOC( context->shmpool, 1, sizeof(UniqueDevice) );
+ if (!device) {
+ D_WARN( "out of (shared) memory" );
+ return D_OOSHM();
+ }
+
+ /* Initialize device data. */
+ device->context = context;
+ device->clazz = class_id;
+ device->ctx = ctx;
+
+ /* Allocate private device data. */
+ if (clazz->data_size) {
+ device->data = SHCALLOC( context->shmpool, 1, clazz->data_size );
+ if (!device->data) {
+ ret = D_OOSHM();
+ goto error;
+ }
+ }
+
+ /* Create reactor for dispatching generated events. */
+ device->reactor = fusion_reactor_new( sizeof(UniqueInputEvent),
+ "UniQuE Device", dfb_core_world(core) );
+ if (!device->reactor) {
+ ret = DFB_FUSION;
+ goto error;
+ }
+
+ fusion_reactor_set_lock( device->reactor, &context->stack->context->lock );
+
+ D_MAGIC_SET( device, UniqueDevice );
+
+ if (clazz->Initialize) {
+ ret = clazz->Initialize( device, device->data, device->ctx );
+ if (ret) {
+ D_MAGIC_CLEAR( device );
+ goto error;
+ }
+ }
+
+ D_DEBUG_AT( UniQuE_Device, " -> device created (%p)\n", device );
+
+ *ret_device = device;
+
+ return DFB_OK;
+
+
+error:
+ if (device->reactor)
+ fusion_reactor_free( device->reactor );
+
+ if (device->data)
+ SHFREE( context->shmpool, device->data );
+
+ SHFREE( context->shmpool, device );
+
+ return ret;
+}
+
+DFBResult
+unique_device_destroy( UniqueDevice *device )
+{
+ DirectLink *n;
+ DeviceConnection *connection;
+ UniqueContext *context;
+ const UniqueDeviceClass *clazz;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ context = device->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( device->clazz >= 0 );
+ D_ASSERT( device->clazz < MAX_CLASSES );
+
+ clazz = classes[device->clazz];
+
+ D_ASSERT( clazz != NULL );
+
+ D_DEBUG_AT( UniQuE_Device, "unique_device_destroy( %p )\n", device );
+
+ direct_list_foreach_safe (connection, n, device->connections) {
+ D_MAGIC_ASSERT( connection, DeviceConnection );
+
+ purge_connection( device, connection );
+ }
+
+ D_ASSERT( device->connections == NULL );
+
+ if (clazz->Shutdown)
+ clazz->Shutdown( device, device->data, device->ctx );
+
+ fusion_reactor_free( device->reactor );
+
+ if (device->data)
+ SHFREE( context->shmpool, device->data );
+
+ D_MAGIC_CLEAR( device );
+
+ SHFREE( context->shmpool, device );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_device_connect( UniqueDevice *device,
+ CoreInputDevice *source )
+{
+ DFBResult ret;
+ WMShared *shared;
+ UniqueContext *context;
+ DeviceConnection *connection;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ D_ASSERT( source != NULL );
+
+ D_ASSERT( device->clazz >= 0 );
+ D_ASSERT( device->clazz < MAX_CLASSES );
+ D_ASSERT( classes[device->clazz] != NULL );
+
+ context = device->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ shared = context->shared;
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ D_DEBUG_AT( UniQuE_Device, "unique_device_connect( %p, %p, ID %d )\n",
+ device, source, dfb_input_device_id( source ) );
+
+ /* Allocate connection structure. */
+ connection = SHCALLOC( context->shmpool, 1, sizeof(DeviceConnection) );
+ if (!connection)
+ return D_OOSHM();
+
+ /* Initialize connection structure. */
+ connection->source = dfb_input_device_id( source );
+
+ /* Attach global reaction for processing events. */
+ ret = dfb_input_attach_global( source, shared->device_listener,
+ device, &connection->reaction );
+ if (ret) {
+ SHFREE( context->shmpool, connection );
+ return ret;
+ }
+
+ /* Add the new connection to the list. */
+ direct_list_append( &device->connections, &connection->link );
+
+ D_MAGIC_SET( connection, DeviceConnection );
+
+ if (classes[device->clazz]->Connected)
+ classes[device->clazz]->Connected( device, device->data, device->ctx, source );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_device_disconnect( UniqueDevice *device,
+ CoreInputDevice *source )
+{
+ DFBInputDeviceID source_id;
+ DeviceConnection *connection;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ D_ASSERT( source != NULL );
+
+ D_ASSERT( device->clazz >= 0 );
+ D_ASSERT( device->clazz < MAX_CLASSES );
+ D_ASSERT( classes[device->clazz] != NULL );
+
+ source_id = dfb_input_device_id( source );
+
+ direct_list_foreach (connection, device->connections) {
+ D_MAGIC_ASSERT( connection, DeviceConnection );
+
+ if (connection->source == source_id)
+ break;
+ }
+
+ if (!connection) {
+ D_WARN( "source not found amoung connections" );
+ return DFB_ITEMNOTFOUND;
+ }
+
+ purge_connection( device, connection );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_device_attach( UniqueDevice *device,
+ ReactionFunc func,
+ void *ctx,
+ Reaction *reaction )
+{
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ return fusion_reactor_attach( device->reactor, func, ctx, reaction );
+}
+
+DFBResult
+unique_device_detach( UniqueDevice *device,
+ Reaction *reaction )
+{
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ return fusion_reactor_detach( device->reactor, reaction );
+}
+
+DFBResult
+unique_device_attach_global( UniqueDevice *device,
+ int index,
+ void *ctx,
+ GlobalReaction *reaction )
+{
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ return fusion_reactor_attach_global( device->reactor, index, ctx, reaction );
+}
+
+DFBResult
+unique_device_detach_global( UniqueDevice *device,
+ GlobalReaction *reaction )
+{
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ return fusion_reactor_detach_global( device->reactor, reaction );
+}
+
+DFBResult
+unique_device_dispatch( UniqueDevice *device,
+ const UniqueInputEvent *event )
+{
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ return fusion_reactor_dispatch( device->reactor, event, true, unique_device_globals );
+}
+
+bool
+unique_device_filter ( UniqueDeviceClassID class_id,
+ const UniqueInputEvent *event,
+ const UniqueInputEvent *filter )
+{
+ const UniqueDeviceClass *clazz;
+
+ D_ASSERT( class_id >= 0 );
+ D_ASSERT( class_id < MAX_CLASSES );
+
+ D_ASSERT( event != NULL );
+ D_ASSERT( filter != NULL );
+
+ clazz = classes[class_id];
+
+ D_ASSERT( clazz != NULL );
+
+ if (clazz->FilterEvent)
+ return clazz->FilterEvent( event, filter );
+
+ return false;
+}
+
+/**************************************************************************************************/
+
+ReactionResult
+_unique_device_listener( const void *msg_data,
+ void *ctx )
+{
+ const DFBInputEvent *event = msg_data;
+ UniqueDevice *device = ctx;
+
+ D_ASSERT( event != NULL );
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ D_ASSERT( device->clazz >= 0 );
+ D_ASSERT( device->clazz < MAX_CLASSES );
+ D_ASSERT( classes[device->clazz] != NULL );
+ D_ASSERT( classes[device->clazz]->ProcessEvent != NULL );
+
+ classes[device->clazz]->ProcessEvent( device, device->data, device->ctx, event );
+
+ return RS_OK;
+}
+
+/**************************************************************************************************/
+
+static void
+purge_connection( UniqueDevice *device,
+ DeviceConnection *connection )
+{
+ CoreInputDevice *source;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( connection, DeviceConnection );
+
+ context = device->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ source = dfb_input_device_at( connection->source );
+
+ D_ASSERT( source != NULL );
+
+ /* Detach global reaction for processing events. */
+ dfb_input_detach_global( source, &connection->reaction );
+
+ direct_list_remove( &device->connections, &connection->link );
+
+ if (classes[device->clazz]->Disconnected)
+ classes[device->clazz]->Disconnected( device, device->data, device->ctx, source );
+
+ D_MAGIC_CLEAR( connection );
+
+ SHFREE( context->shmpool, connection );
+}
+
diff --git a/Source/DirectFB/wm/unique/device.h b/Source/DirectFB/wm/unique/device.h
new file mode 100755
index 0000000..d03aa82
--- /dev/null
+++ b/Source/DirectFB/wm/unique/device.h
@@ -0,0 +1,139 @@
+/*
+ (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 __UNIQUE__DEVICE_H__
+#define __UNIQUE__DEVICE_H__
+
+#include <directfb.h>
+
+#include <fusion/reactor.h>
+
+#include <core/coretypes.h>
+
+#include <unique/types.h>
+
+
+typedef struct {
+ int data_size;
+
+
+ DFBResult (*Initialize) ( UniqueDevice *device,
+ void *data,
+ void *ctx );
+
+ void (*Shutdown) ( UniqueDevice *device,
+ void *data,
+ void *ctx );
+
+
+ void (*Connected) ( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ CoreInputDevice *source );
+
+ void (*Disconnected)( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ CoreInputDevice *source );
+
+ void (*ProcessEvent)( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ const DFBInputEvent *event );
+
+
+ bool (*FilterEvent) ( const UniqueInputEvent *event,
+ const UniqueInputEvent *filter );
+} UniqueDeviceClass;
+
+typedef unsigned int UniqueDeviceID;
+typedef unsigned int UniqueDeviceClassID;
+
+typedef enum {
+ UDCI_POINTER,
+ UDCI_WHEEL,
+ UDCI_KEYBOARD,
+
+ _UDCI_NUM
+} UniqueDeviceClassIndex;
+
+
+DFBResult unique_device_class_register ( const UniqueDeviceClass *clazz,
+ UniqueDeviceClassID *ret_id );
+
+DFBResult unique_device_class_unregister( UniqueDeviceClassID id );
+
+
+DFBResult unique_device_create ( CoreDFB *core,
+ UniqueContext *context,
+ UniqueDeviceClassID class_id,
+ void *ctx,
+ UniqueDevice **ret_device );
+
+DFBResult unique_device_destroy ( UniqueDevice *device );
+
+
+DFBResult unique_device_connect ( UniqueDevice *device,
+ CoreInputDevice *source );
+
+DFBResult unique_device_disconnect ( UniqueDevice *device,
+ CoreInputDevice *source );
+
+DFBResult unique_device_attach ( UniqueDevice *device,
+ ReactionFunc func,
+ void *ctx,
+ Reaction *reaction );
+
+DFBResult unique_device_detach ( UniqueDevice *device,
+ Reaction *reaction );
+
+DFBResult unique_device_attach_global( UniqueDevice *device,
+ int index,
+ void *ctx,
+ GlobalReaction *reaction );
+
+DFBResult unique_device_detach_global( UniqueDevice *device,
+ GlobalReaction *reaction );
+
+DFBResult unique_device_dispatch ( UniqueDevice *device,
+ const UniqueInputEvent *event );
+
+bool unique_device_filter ( UniqueDeviceClassID class_id,
+ const UniqueInputEvent *event,
+ const UniqueInputEvent *filter );
+
+
+/* global reactions */
+
+typedef enum {
+ UNIQUE_INPUT_SWITCH_DEVICE_LISTENER,
+ UNIQUE_CURSOR_DEVICE_LISTENER
+} UNIQUE_DEVICE_GLOBALS;
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/devices/Makefile.am b/Source/DirectFB/wm/unique/devices/Makefile.am
new file mode 100755
index 0000000..c42f697
--- /dev/null
+++ b/Source/DirectFB/wm/unique/devices/Makefile.am
@@ -0,0 +1,21 @@
+## Makefile.am for DirectFB/wm/unique/devices
+
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/wm
+
+AM_CPPFLAGS = \
+ -DMODULEDIR=\"@MODULEDIR@\" \
+ -DSOPATH=\"@SOPATH@\"
+
+
+noinst_LTLIBRARIES = libunique_devices.la
+
+libunique_devices_la_SOURCES = \
+ pointer.c \
+ wheel.c \
+ keyboard.c
diff --git a/Source/DirectFB/wm/unique/devices/Makefile.in b/Source/DirectFB/wm/unique/devices/Makefile.in
new file mode 100755
index 0000000..baef097
--- /dev/null
+++ b/Source/DirectFB/wm/unique/devices/Makefile.in
@@ -0,0 +1,525 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = wm/unique/devices
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libunique_devices_la_LIBADD =
+am_libunique_devices_la_OBJECTS = pointer.lo wheel.lo keyboard.lo
+libunique_devices_la_OBJECTS = $(am_libunique_devices_la_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libunique_devices_la_SOURCES)
+DIST_SOURCES = $(libunique_devices_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/wm
+
+AM_CPPFLAGS = \
+ -DMODULEDIR=\"@MODULEDIR@\" \
+ -DSOPATH=\"@SOPATH@\"
+
+noinst_LTLIBRARIES = libunique_devices.la
+libunique_devices_la_SOURCES = \
+ pointer.c \
+ wheel.c \
+ keyboard.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu wm/unique/devices/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu wm/unique/devices/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libunique_devices.la: $(libunique_devices_la_OBJECTS) $(libunique_devices_la_DEPENDENCIES)
+ $(LINK) $(libunique_devices_la_OBJECTS) $(libunique_devices_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keyboard.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pointer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wheel.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
+
+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)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-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:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+# 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/wm/unique/devices/keyboard.c b/Source/DirectFB/wm/unique/devices/keyboard.c
new file mode 100755
index 0000000..fa4b94a
--- /dev/null
+++ b/Source/DirectFB/wm/unique/devices/keyboard.c
@@ -0,0 +1,192 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <core/gfxcard.h>
+#include <core/state.h>
+
+#include <misc/util.h>
+
+#include <unique/context.h>
+#include <unique/device.h>
+#include <unique/internal.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_Keyboard, "UniQuE/Keyboard", "UniQuE's Keyboard Device Class" );
+
+
+typedef struct {
+ int magic;
+} KeyboardData;
+
+/**************************************************************************************************/
+
+static DFBResult
+keyboard_initialize( UniqueDevice *device,
+ void *data,
+ void *ctx )
+{
+ KeyboardData *keyboard = data;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ D_DEBUG_AT( UniQuE_Keyboard, "keyboard_initialize( %p, %p, %p )\n", device, data, ctx );
+
+ D_MAGIC_SET( keyboard, KeyboardData );
+
+ return DFB_OK;
+}
+
+static void
+keyboard_shutdown( UniqueDevice *device,
+ void *data,
+ void *ctx )
+{
+ KeyboardData *keyboard = data;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( keyboard, KeyboardData );
+
+ D_DEBUG_AT( UniQuE_Keyboard, "keyboard_shutdown( %p, %p, %p )\n", device, data, ctx );
+
+ D_MAGIC_CLEAR( keyboard );
+}
+
+static void
+keyboard_connected( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ CoreInputDevice *source )
+{
+ KeyboardData *keyboard = data;
+
+ (void) keyboard;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( keyboard, KeyboardData );
+
+ D_ASSERT( source != NULL );
+
+ D_DEBUG_AT( UniQuE_Keyboard, "keyboard_connected( %p, %p, %p, %p )\n",
+ device, data, ctx, source );
+}
+
+static void
+keyboard_disconnected( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ CoreInputDevice *source )
+{
+ KeyboardData *keyboard = data;
+
+ (void) keyboard;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( keyboard, KeyboardData );
+
+ D_ASSERT( source != NULL );
+
+ D_DEBUG_AT( UniQuE_Keyboard, "keyboard_disconnected( %p, %p, %p, %p )\n",
+ device, data, ctx, source );
+}
+
+static void
+keyboard_process_event( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ const DFBInputEvent *event )
+{
+ UniqueInputEvent evt;
+ KeyboardData *keyboard = data;
+
+ (void) keyboard;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( keyboard, KeyboardData );
+
+ D_ASSERT( event != NULL );
+
+ D_DEBUG_AT( UniQuE_Keyboard, "keyboard_process_event( %p, %p, %p, %p ) <- type 0x%08x\n",
+ device, data, ctx, event, event->type );
+
+ switch (event->type) {
+ case DIET_KEYPRESS:
+ case DIET_KEYRELEASE:
+ evt.type = UIET_KEY;
+
+ evt.keyboard.device_id = event->device_id;
+ evt.keyboard.press = (event->type == DIET_KEYPRESS);
+ evt.keyboard.key_code = event->key_code;
+ evt.keyboard.key_id = event->key_id;
+ evt.keyboard.key_symbol = event->key_symbol;
+ evt.keyboard.modifiers = event->modifiers;
+ evt.keyboard.locks = event->locks;
+
+ unique_device_dispatch( device, &evt );
+ break;
+
+ default:
+ break;
+ }
+}
+
+static bool
+keyboard_filter_event( const UniqueInputEvent *event,
+ const UniqueInputEvent *filter )
+{
+ D_ASSERT( event != NULL );
+ D_ASSERT( filter != NULL );
+
+ D_DEBUG_AT( UniQuE_Keyboard, "keyboard_filter_event( %p, %p )\n", event, filter );
+
+ if (filter->keyboard.key_code != -1)
+ return (filter->keyboard.key_code == event->keyboard.key_code);
+
+ return (event->keyboard.modifiers == filter->keyboard.modifiers &&
+ event->keyboard.key_symbol == filter->keyboard.key_symbol);
+}
+
+
+const UniqueDeviceClass unique_keyboard_device_class = {
+ data_size: sizeof(KeyboardData),
+
+ Initialize: keyboard_initialize,
+ Shutdown: keyboard_shutdown,
+ Connected: keyboard_connected,
+ Disconnected: keyboard_disconnected,
+ ProcessEvent: keyboard_process_event,
+ FilterEvent: keyboard_filter_event
+};
+
diff --git a/Source/DirectFB/wm/unique/devices/pointer.c b/Source/DirectFB/wm/unique/devices/pointer.c
new file mode 100755
index 0000000..4434cba
--- /dev/null
+++ b/Source/DirectFB/wm/unique/devices/pointer.c
@@ -0,0 +1,259 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <core/gfxcard.h>
+#include <core/state.h>
+#include <core/windows_internal.h>
+
+#include <misc/util.h>
+
+#include <unique/context.h>
+#include <unique/device.h>
+#include <unique/internal.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_Pointer, "UniQuE/Pointer", "UniQuE's Pointer Device Class" );
+
+
+typedef struct {
+ int magic;
+
+ int x;
+ int y;
+} PointerData;
+
+/**************************************************************************************************/
+
+static DFBResult
+pointer_initialize( UniqueDevice *device,
+ void *data,
+ void *ctx )
+{
+ PointerData *pointer = data;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ D_DEBUG_AT( UniQuE_Pointer, "pointer_initialize( %p, %p, %p )\n", device, data, ctx );
+
+ D_MAGIC_SET( pointer, PointerData );
+
+ return DFB_OK;
+}
+
+static void
+pointer_shutdown( UniqueDevice *device,
+ void *data,
+ void *ctx )
+{
+ PointerData *pointer = data;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( pointer, PointerData );
+
+ D_DEBUG_AT( UniQuE_Pointer, "pointer_shutdown( %p, %p, %p )\n", device, data, ctx );
+
+ D_MAGIC_CLEAR( pointer );
+}
+
+static void
+pointer_connected( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ CoreInputDevice *source )
+{
+ PointerData *pointer = data;
+
+ (void) pointer;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( pointer, PointerData );
+
+ D_ASSERT( source != NULL );
+
+ D_DEBUG_AT( UniQuE_Pointer, "pointer_connected( %p, %p, %p, %p )\n",
+ device, data, ctx, source );
+}
+
+static void
+pointer_disconnected( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ CoreInputDevice *source )
+{
+ PointerData *pointer = data;
+
+ (void) pointer;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( pointer, PointerData );
+
+ D_ASSERT( source != NULL );
+
+ D_DEBUG_AT( UniQuE_Pointer, "pointer_disconnected( %p, %p, %p, %p )\n",
+ device, data, ctx, source );
+}
+
+static void
+pointer_process_event( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ const DFBInputEvent *event )
+{
+ UniqueInputEvent evt;
+ PointerData *pointer = data;
+ UniqueContext *context = ctx;
+ CoreWindowStack *stack;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( pointer, PointerData );
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( event != NULL );
+
+ D_DEBUG_AT( UniQuE_Pointer, "pointer_process_event( %p, %p, %p, %p ) <- type 0x%08x\n",
+ device, data, ctx, event, event->type );
+
+ stack = context->stack;
+
+ D_ASSERT( stack != NULL );
+
+ switch (event->type) {
+ case DIET_AXISMOTION: {
+ /*int x = pointer->x;
+ int y = pointer->y;*/
+ int x = stack->cursor.x;
+ int y = stack->cursor.y;
+
+ if (event->flags & DIEF_AXISREL) {
+ int rel = event->axisrel;
+
+ /* handle cursor acceleration */
+ if (rel > stack->cursor.threshold)
+ rel += (rel - stack->cursor.threshold)
+ * stack->cursor.numerator
+ / stack->cursor.denominator;
+ else if (rel < -stack->cursor.threshold)
+ rel += (rel + stack->cursor.threshold)
+ * stack->cursor.numerator
+ / stack->cursor.denominator;
+
+ switch (event->axis) {
+ case DIAI_X:
+ x += rel;
+ break;
+
+ case DIAI_Y:
+ y += rel;
+ break;
+
+ default:
+ return;
+ }
+ }
+ else if (event->flags & DIEF_AXISABS) {
+ switch (event->axis) {
+ case DIAI_X:
+ x = event->axisabs;
+ break;
+
+ case DIAI_Y:
+ y = event->axisabs;
+ break;
+
+ default:
+ return;
+ }
+ }
+ else
+ return;
+
+ if (x < 0)
+ x = 0;
+ else if (x >= context->width)
+ x = context->width - 1;
+
+ if (y < 0)
+ y = 0;
+ else if (y >= context->height)
+ y = context->height - 1;
+
+ if (x == pointer->x && y == pointer->y)
+ return;
+
+ pointer->x = x;
+ pointer->y = y;
+
+ evt.type = UIET_MOTION;
+
+ evt.pointer.device_id = event->device_id;
+ evt.pointer.x = x;
+ evt.pointer.y = y;
+ evt.pointer.buttons = event->buttons;
+
+ unique_device_dispatch( device, &evt );
+ break;
+ }
+
+ case DIET_BUTTONPRESS:
+ case DIET_BUTTONRELEASE:
+ evt.type = UIET_BUTTON;
+
+ evt.pointer.device_id = event->device_id;
+ evt.pointer.press = (event->type == DIET_BUTTONPRESS);
+ evt.pointer.x = pointer->x;
+ evt.pointer.y = pointer->y;
+ evt.pointer.button = event->button;
+ evt.pointer.buttons = event->buttons;
+
+ unique_device_dispatch( device, &evt );
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+const UniqueDeviceClass unique_pointer_device_class = {
+ data_size: sizeof(PointerData),
+
+ Initialize: pointer_initialize,
+ Shutdown: pointer_shutdown,
+ Connected: pointer_connected,
+ Disconnected: pointer_disconnected,
+ ProcessEvent: pointer_process_event
+};
+
diff --git a/Source/DirectFB/wm/unique/devices/wheel.c b/Source/DirectFB/wm/unique/devices/wheel.c
new file mode 100755
index 0000000..3328d8f
--- /dev/null
+++ b/Source/DirectFB/wm/unique/devices/wheel.c
@@ -0,0 +1,182 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <core/gfxcard.h>
+#include <core/state.h>
+
+#include <misc/util.h>
+
+#include <unique/context.h>
+#include <unique/device.h>
+#include <unique/internal.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_Wheel, "UniQuE/Wheel", "UniQuE's Wheel Device Class" );
+
+
+typedef struct {
+ int magic;
+} WheelData;
+
+/**************************************************************************************************/
+
+static DFBResult
+wheel_initialize( UniqueDevice *device,
+ void *data,
+ void *ctx )
+{
+ WheelData *wheel = data;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ D_DEBUG_AT( UniQuE_Wheel, "wheel_initialize( %p, %p, %p )\n", device, data, ctx );
+
+ D_MAGIC_SET( wheel, WheelData );
+
+ return DFB_OK;
+}
+
+static void
+wheel_shutdown( UniqueDevice *device,
+ void *data,
+ void *ctx )
+{
+ WheelData *wheel = data;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( wheel, WheelData );
+
+ D_DEBUG_AT( UniQuE_Wheel, "wheel_shutdown( %p, %p, %p )\n", device, data, ctx );
+
+ D_MAGIC_CLEAR( wheel );
+}
+
+static void
+wheel_connected( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ CoreInputDevice *source )
+{
+ WheelData *wheel = data;
+
+ (void) wheel;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( wheel, WheelData );
+
+ D_ASSERT( source != NULL );
+
+ D_DEBUG_AT( UniQuE_Wheel, "wheel_connected( %p, %p, %p, %p )\n",
+ device, data, ctx, source );
+}
+
+static void
+wheel_disconnected( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ CoreInputDevice *source )
+{
+ WheelData *wheel = data;
+
+ (void) wheel;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( wheel, WheelData );
+
+ D_ASSERT( source != NULL );
+
+ D_DEBUG_AT( UniQuE_Wheel, "wheel_disconnected( %p, %p, %p, %p )\n",
+ device, data, ctx, source );
+}
+
+static void
+wheel_process_event( UniqueDevice *device,
+ void *data,
+ void *ctx,
+ const DFBInputEvent *event )
+{
+ UniqueInputEvent evt;
+ WheelData *wheel = data;
+
+ (void) wheel;
+
+ D_MAGIC_ASSERT( device, UniqueDevice );
+ D_MAGIC_ASSERT( wheel, WheelData );
+
+ D_ASSERT( event != NULL );
+
+ D_DEBUG_AT( UniQuE_Wheel, "wheel_process_event( %p, %p, %p, %p ) <- type 0x%08x\n",
+ device, data, ctx, event, event->type );
+
+ switch (event->type) {
+ case DIET_AXISMOTION:
+ switch (event->axis) {
+ case DIAI_Z:
+ evt.type = UIET_WHEEL;
+
+ evt.wheel.device_id = event->device_id;
+
+ if (event->flags & DIEF_AXISREL)
+ evt.wheel.value = -event->axisrel;
+ else if (event->flags & DIEF_AXISABS)
+ evt.wheel.value = event->axisabs;
+ else
+ break;
+
+ unique_device_dispatch( device, &evt );
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+const UniqueDeviceClass unique_wheel_device_class = {
+ data_size: sizeof(WheelData),
+
+ Initialize: wheel_initialize,
+ Shutdown: wheel_shutdown,
+ Connected: wheel_connected,
+ Disconnected: wheel_disconnected,
+ ProcessEvent: wheel_process_event
+};
+
diff --git a/Source/DirectFB/wm/unique/input_channel.c b/Source/DirectFB/wm/unique/input_channel.c
new file mode 100755
index 0000000..69dee79
--- /dev/null
+++ b/Source/DirectFB/wm/unique/input_channel.c
@@ -0,0 +1,206 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <fusion/shmalloc.h>
+#include <fusion/vector.h>
+
+#include <core/core.h>
+#include <core/layers_internal.h>
+#include <core/windows_internal.h>
+
+#include <unique/device.h>
+#include <unique/internal.h>
+#include <unique/input_channel.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_InputChan, "UniQuE/InputChan", "UniQuE's Input Channel" );
+
+
+static const ReactionFunc unique_input_channel_globals[] = {
+ _unique_window_input_channel_listener,
+ NULL
+};
+
+/**************************************************************************************************/
+
+DFBResult
+unique_input_channel_create( CoreDFB *core,
+ UniqueContext *context,
+ UniqueInputChannel **ret_channel )
+{
+ UniqueInputChannel *channel;
+
+ D_DEBUG_AT( UniQuE_InputChan, "unique_input_channel_create( context %p )\n", context );
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( ret_channel != NULL );
+
+ /* Allocate channel data. */
+ channel = SHCALLOC( context->shmpool, 1, sizeof(UniqueInputChannel) );
+ if (!channel) {
+ D_WARN( "out of (shared) memory" );
+ return D_OOSHM();
+ }
+
+ /* Initialize channel data. */
+ channel->context = context;
+
+ /* Create reactor for dispatching events. */
+ channel->reactor = fusion_reactor_new( sizeof(UniqueInputEvent),
+ "UniQuE Input Channel", dfb_core_world(core) );
+ if (!channel->reactor) {
+ SHFREE( context->shmpool, channel );
+ return DFB_FUSION;
+ }
+
+ fusion_reactor_set_lock( channel->reactor, &context->stack->context->lock );
+
+ D_MAGIC_SET( channel, UniqueInputChannel );
+
+ D_DEBUG_AT( UniQuE_InputChan, " -> channel created (%p)\n", channel );
+
+ *ret_channel = channel;
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_channel_destroy( UniqueInputChannel *channel )
+{
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ context = channel->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_DEBUG_AT( UniQuE_InputChan, "unique_input_channel_destroy( %p )\n", channel );
+
+ fusion_reactor_free( channel->reactor );
+
+ D_MAGIC_CLEAR( channel );
+
+ SHFREE( context->shmpool, channel );
+
+ return DFB_OK;
+}
+
+
+DFBResult
+unique_input_channel_attach( UniqueInputChannel *channel,
+ ReactionFunc func,
+ void *ctx,
+ Reaction *reaction )
+{
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ return fusion_reactor_attach( channel->reactor, func, ctx, reaction );
+}
+
+DFBResult
+unique_input_channel_detach( UniqueInputChannel *channel,
+ Reaction *reaction )
+{
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ return fusion_reactor_detach( channel->reactor, reaction );
+}
+
+DFBResult
+unique_input_channel_attach_global( UniqueInputChannel *channel,
+ int index,
+ void *ctx,
+ GlobalReaction *reaction )
+{
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ return fusion_reactor_attach_global( channel->reactor, index, ctx, reaction );
+}
+
+DFBResult
+unique_input_channel_detach_global( UniqueInputChannel *channel,
+ GlobalReaction *reaction )
+{
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ return fusion_reactor_detach_global( channel->reactor, reaction );
+}
+
+DFBResult
+unique_input_channel_dispatch( UniqueInputChannel *channel,
+ const UniqueInputEvent *event )
+{
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ D_ASSERT( event != NULL );
+
+ D_DEBUG_AT( UniQuE_InputChan, "unique_input_channel_dispatch( %p, %p ) <- type 0x%08x\n",
+ channel, event, event->type );
+
+ switch (event->type) {
+ case UIET_MOTION:
+ D_DEBUG_AT( UniQuE_InputChan, " -> MOTION %d, %d, buttons 0x%04x\n",
+ event->pointer.x, event->pointer.y, event->pointer.buttons );
+ break;
+ case UIET_BUTTON:
+ D_DEBUG_AT( UniQuE_InputChan, " -> BUTTON %d, %d, buttons 0x%04x, button %d, %s\n",
+ event->pointer.x, event->pointer.y,
+ event->pointer.buttons, event->pointer.button,
+ event->pointer.press ? "pressed" : "released" );
+ break;
+ case UIET_WHEEL:
+ D_DEBUG_AT( UniQuE_InputChan, " -> WHEEL %d\n", event->wheel.value );
+ break;
+ case UIET_KEY:
+ D_DEBUG_AT( UniQuE_InputChan, " -> KEY 0x%08x, modifiers 0x%04x, %s\n",
+ event->keyboard.key_symbol, event->keyboard.modifiers,
+ event->keyboard.press ? "pressed" : "released" );
+ break;
+ case UIET_CHANNEL:
+ D_DEBUG_AT( UniQuE_InputChan, " -> CHANNEL %d, %d, index %d, %s\n",
+ event->channel.x, event->channel.y, event->channel.index,
+ event->channel.selected ? "selected" : "deselected" );
+ break;
+ default:
+ D_DEBUG_AT( UniQuE_InputChan, " -> unknown type 0x%08x\n", event->type );
+ break;
+ }
+
+ return fusion_reactor_dispatch( channel->reactor, event, true, unique_input_channel_globals );
+}
+
diff --git a/Source/DirectFB/wm/unique/input_channel.h b/Source/DirectFB/wm/unique/input_channel.h
new file mode 100755
index 0000000..a61b92e
--- /dev/null
+++ b/Source/DirectFB/wm/unique/input_channel.h
@@ -0,0 +1,74 @@
+/*
+ (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 __UNIQUE__INPUT_CHANNEL_H__
+#define __UNIQUE__INPUT_CHANNEL_H__
+
+#include <directfb.h>
+
+#include <fusion/reactor.h>
+
+#include <unique/input_events.h>
+#include <unique/types.h>
+
+
+DFBResult unique_input_channel_create ( CoreDFB *core,
+ UniqueContext *context,
+ UniqueInputChannel **ret_channel );
+
+DFBResult unique_input_channel_destroy ( UniqueInputChannel *channel );
+
+
+DFBResult unique_input_channel_attach ( UniqueInputChannel *channel,
+ ReactionFunc func,
+ void *ctx,
+ Reaction *reaction );
+
+DFBResult unique_input_channel_detach ( UniqueInputChannel *channel,
+ Reaction *reaction );
+
+DFBResult unique_input_channel_attach_global( UniqueInputChannel *channel,
+ int index,
+ void *ctx,
+ GlobalReaction *reaction );
+
+DFBResult unique_input_channel_detach_global( UniqueInputChannel *channel,
+ GlobalReaction *reaction );
+
+DFBResult unique_input_channel_dispatch ( UniqueInputChannel *channel,
+ const UniqueInputEvent *event );
+
+
+/* global reactions */
+
+typedef enum {
+ UNIQUE_WINDOW_INPUT_CHANNEL_LISTENER
+} UNIQUE_INPUT_CHANNEL_GLOBALS;
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/input_events.h b/Source/DirectFB/wm/unique/input_events.h
new file mode 100755
index 0000000..c0400bb
--- /dev/null
+++ b/Source/DirectFB/wm/unique/input_events.h
@@ -0,0 +1,114 @@
+/*
+ (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 __UNIQUE__INPUT_EVENTS_H__
+#define __UNIQUE__INPUT_EVENTS_H__
+
+#include <directfb.h>
+
+#include <unique/types.h>
+#include <unique/device.h>
+
+typedef enum {
+ UIET_NONE = 0x00000000,
+
+ UIET_MOTION = 0x00000001,
+ UIET_BUTTON = 0x00000002,
+
+ UIET_WHEEL = 0x00000010,
+
+ UIET_KEY = 0x00000100,
+
+ UIET_CHANNEL = 0x00001000,
+
+ UIET_ALL = 0x00001113
+} UniqueInputEventType;
+
+
+typedef struct {
+ UniqueInputEventType type;
+
+ DFBInputDeviceID device_id;
+
+ bool press;
+
+ int x;
+ int y;
+
+ DFBInputDeviceButtonIdentifier button;
+
+ DFBInputDeviceButtonMask buttons;
+} UniqueInputPointerEvent;
+
+typedef struct {
+ UniqueInputEventType type;
+
+ DFBInputDeviceID device_id;
+
+ int value;
+} UniqueInputWheelEvent;
+
+typedef struct {
+ UniqueInputEventType type;
+
+ DFBInputDeviceID device_id;
+
+ bool press;
+
+ int key_code;
+ DFBInputDeviceKeyIdentifier key_id;
+ DFBInputDeviceKeySymbol key_symbol;
+
+ DFBInputDeviceModifierMask modifiers;
+ DFBInputDeviceLockState locks;
+} UniqueInputKeyboardEvent;
+
+typedef struct {
+ UniqueInputEventType type;
+
+ bool selected;
+
+ UniqueDeviceClassIndex index;
+
+ int x;
+ int y;
+} UniqueInputChannelEvent;
+
+
+union __UniQuE_UniqueInputEvent {
+ UniqueInputEventType type;
+
+ UniqueInputPointerEvent pointer;
+ UniqueInputWheelEvent wheel;
+ UniqueInputKeyboardEvent keyboard;
+ UniqueInputChannelEvent channel;
+};
+
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/input_switch.c b/Source/DirectFB/wm/unique/input_switch.c
new file mode 100755
index 0000000..08fa0e2
--- /dev/null
+++ b/Source/DirectFB/wm/unique/input_switch.c
@@ -0,0 +1,776 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <fusion/shmalloc.h>
+#include <fusion/vector.h>
+
+#include <core/input.h>
+#include <core/windowstack.h>
+
+#include <misc/util.h>
+
+#include <unique/device.h>
+#include <unique/input_channel.h>
+#include <unique/input_switch.h>
+#include <unique/internal.h>
+
+
+
+D_DEBUG_DOMAIN( UniQuE_InpSw, "UniQuE/InpSwitch", "UniQuE's Input Switch" );
+
+
+typedef struct {
+ DirectLink link;
+
+ int magic;
+
+ UniqueDevice *device;
+
+ GlobalReaction reaction;
+} SwitchConnection;
+
+/**************************************************************************************************/
+
+static void purge_connection( UniqueInputSwitch *input_switch,
+ SwitchConnection *connection );
+
+static bool target_switch ( UniqueInputSwitch *input_switch,
+ UniqueDeviceClassIndex index,
+ UniqueInputChannel *channel );
+
+static bool update_targets ( UniqueInputSwitch *input_switch );
+
+/**************************************************************************************************/
+
+DFBResult
+unique_input_switch_create( UniqueContext *context,
+ UniqueInputSwitch **ret_switch )
+{
+ int i;
+ WMShared *shared;
+ UniqueInputSwitch *input_switch;
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_create( context %p )\n", context );
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( ret_switch != NULL );
+
+ shared = context->shared;
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ /* Allocate switch data. */
+ input_switch = SHCALLOC( context->shmpool, 1, sizeof(UniqueInputSwitch) );
+ if (!input_switch) {
+ D_WARN( "out of (shared) memory" );
+ return D_OOSHM();
+ }
+
+ /* Initialize input_switch data. */
+ input_switch->context = context;
+
+ /* Set class ID of each target. */
+ for (i=0; i<_UDCI_NUM; i++)
+ input_switch->targets[i].clazz = shared->device_classes[i];
+
+ D_MAGIC_SET( input_switch, UniqueInputSwitch );
+
+ D_DEBUG_AT( UniQuE_InpSw, " -> input_switch created (%p)\n", input_switch );
+
+ *ret_switch = input_switch;
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_switch_destroy( UniqueInputSwitch *input_switch )
+{
+ int i;
+ DirectLink *n;
+ SwitchConnection *connection;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+
+ context = input_switch->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_destroy( %p )\n", input_switch );
+
+ direct_list_foreach_safe (connection, n, input_switch->connections) {
+ D_MAGIC_ASSERT( connection, SwitchConnection );
+
+ purge_connection( input_switch, connection );
+ }
+
+ D_ASSERT( input_switch->connections == NULL );
+
+ for (i=0; i<_UDCI_NUM; i++) {
+ UniqueInputFilter *filter;
+ UniqueInputTarget *target = &input_switch->targets[i];
+
+ direct_list_foreach_safe (filter, n, target->filters) {
+ D_MAGIC_ASSERT( filter, UniqueInputFilter );
+ D_MAGIC_ASSERT( filter->channel, UniqueInputChannel );
+
+ D_DEBUG_AT( UniQuE_InpSw, " -> filter %p, index %d, channel %p\n",
+ filter, filter->index, filter->channel );
+
+ direct_list_remove( &target->filters, &filter->link );
+
+ D_MAGIC_CLEAR( filter );
+
+ SHFREE( context->shmpool, filter );
+ }
+
+ D_ASSERT( target->filters == NULL );
+ }
+
+ D_MAGIC_CLEAR( input_switch );
+
+ SHFREE( context->shmpool, input_switch );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_switch_add( UniqueInputSwitch *input_switch,
+ UniqueDevice *device )
+{
+ DFBResult ret;
+ SwitchConnection *connection;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ context = input_switch->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_add( %p, %p )\n", input_switch, device );
+
+ /* Allocate connection structure. */
+ connection = SHCALLOC( context->shmpool, 1, sizeof(SwitchConnection) );
+ if (!connection) {
+ D_WARN( "out of (shared) memory" );
+ return D_OOSHM();
+ }
+
+ /* Initialize connection structure. */
+ connection->device = device;
+
+ /* Attach global reaction for processing events. */
+ ret = unique_device_attach_global( device, UNIQUE_INPUT_SWITCH_DEVICE_LISTENER,
+ input_switch, &connection->reaction );
+ if (ret) {
+ D_DERROR( ret, "UniQuE/InpSwitch: Could not attach global device reaction!\n" );
+ SHFREE( context->shmpool, connection );
+ return ret;
+ }
+
+ /* Add the new connection to the list. */
+ direct_list_append( &input_switch->connections, &connection->link );
+
+ D_MAGIC_SET( connection, SwitchConnection );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_switch_remove( UniqueInputSwitch *input_switch,
+ UniqueDevice *device )
+{
+ SwitchConnection *connection;
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+ D_MAGIC_ASSERT( device, UniqueDevice );
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_remove( %p, %p )\n", input_switch, device );
+
+ direct_list_foreach (connection, input_switch->connections) {
+ D_MAGIC_ASSERT( connection, SwitchConnection );
+
+ if (connection->device == device)
+ break;
+ }
+
+ if (!connection) {
+ D_WARN( "device not found amoung connections" );
+ return DFB_ITEMNOTFOUND;
+ }
+
+ purge_connection( input_switch, connection );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_switch_select( UniqueInputSwitch *input_switch,
+ UniqueDeviceClassIndex index,
+ UniqueInputChannel *channel )
+{
+ UniqueInputTarget *target;
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_select( %p, %d, %p )\n",
+ input_switch, index, channel );
+
+ D_ASSERT( index >= 0 );
+ D_ASSERT( index < _UDCI_NUM );
+
+ target = &input_switch->targets[index];
+
+ target->normal = channel;
+
+ if (!target->fixed && !target->implicit)
+ target_switch( input_switch, index, channel );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_switch_set( UniqueInputSwitch *input_switch,
+ UniqueDeviceClassIndex index,
+ UniqueInputChannel *channel )
+{
+ UniqueInputTarget *target;
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_set( %p, %d, %p )\n",
+ input_switch, index, channel );
+
+ D_ASSERT( index >= 0 );
+ D_ASSERT( index < _UDCI_NUM );
+
+ target = &input_switch->targets[index];
+
+ if (target->fixed)
+ return DFB_BUSY;
+
+ target->fixed = channel;
+
+ target_switch( input_switch, index, channel );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_switch_unset( UniqueInputSwitch *input_switch,
+ UniqueDeviceClassIndex index,
+ UniqueInputChannel *channel )
+{
+ UniqueInputTarget *target;
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_unset( %p, %d, %p )\n",
+ input_switch, index, channel );
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ D_ASSERT( index >= 0 );
+ D_ASSERT( index < _UDCI_NUM );
+
+ target = &input_switch->targets[index];
+
+ if (target->fixed != channel)
+ return DFB_ACCESSDENIED;
+
+ target->fixed = NULL;
+
+
+ update_targets( input_switch );
+ //target_switch( input_switch, index, target->normal );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_switch_set_filter( UniqueInputSwitch *input_switch,
+ UniqueDeviceClassIndex index,
+ UniqueInputChannel *channel,
+ const UniqueInputEvent *event,
+ UniqueInputFilter **ret_filter )
+{
+ UniqueInputFilter *filter;
+ UniqueInputTarget *target;
+ UniqueContext *context;
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_set_filter( %p, %d, %p, %p )\n",
+ input_switch, index, channel, event );
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ D_ASSERT( index >= 0 );
+ D_ASSERT( index < _UDCI_NUM );
+
+ D_ASSERT( event != NULL );
+ D_ASSERT( ret_filter != NULL );
+
+ context = input_switch->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ target = &input_switch->targets[index];
+
+ direct_list_foreach (filter, target->filters) {
+ D_MAGIC_ASSERT( filter, UniqueInputFilter );
+
+ if (unique_device_filter( target->clazz, event, &filter->filter ))
+ return DFB_BUSY;
+ }
+
+ /* Allocate new filter. */
+ filter = SHCALLOC( context->shmpool, 1, sizeof(UniqueInputFilter) );
+ if (!filter)
+ return D_OOSHM();
+
+ filter->index = index;
+ filter->channel = channel;
+ filter->filter = *event;
+
+ direct_list_append( &target->filters, &filter->link );
+
+ D_MAGIC_SET( filter, UniqueInputFilter );
+
+ *ret_filter = filter;
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_switch_unset_filter( UniqueInputSwitch *input_switch,
+ UniqueInputFilter *filter )
+{
+ UniqueInputTarget *target;
+ UniqueContext *context;
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_unset_filter( %p, %p )\n",
+ input_switch, filter );
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+ D_MAGIC_ASSERT( filter, UniqueInputFilter );
+
+ context = input_switch->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( filter->index >= 0 );
+ D_ASSERT( filter->index < _UDCI_NUM );
+
+ target = &input_switch->targets[filter->index];
+
+ direct_list_remove( &target->filters, &filter->link );
+
+ D_MAGIC_CLEAR( filter );
+
+ SHFREE( context->shmpool, filter );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_switch_drop( UniqueInputSwitch *input_switch,
+ UniqueInputChannel *channel )
+{
+ int i;
+ UniqueContext *context;
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_drop( %p, %p )\n", input_switch, channel );
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ context = input_switch->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ for (i=0; i<_UDCI_NUM; i++) {
+ DirectLink *n;
+ UniqueInputFilter *filter;
+ UniqueInputTarget *target = &input_switch->targets[i];
+
+ if (target->normal == channel)
+ target->normal = NULL;
+
+ if (target->fixed == channel)
+ target->fixed = NULL;
+
+ if (target->implicit == channel)
+ target->implicit = NULL;
+
+ if (target->current == channel)
+ target->current = NULL;
+
+ D_DEBUG_AT( UniQuE_InpSw, " -> index %d, filters %p\n", i, target->filters );
+
+ direct_list_foreach_safe (filter, n, target->filters) {
+ D_MAGIC_ASSERT( filter, UniqueInputFilter );
+ D_MAGIC_ASSERT( filter->channel, UniqueInputChannel );
+
+ D_DEBUG_AT( UniQuE_InpSw,
+ " -> filter %p, channel %p\n", filter, filter->channel );
+
+ D_ASSUME( filter->channel != channel );
+
+ if (filter->channel == channel) {
+ direct_list_remove( &target->filters, &filter->link );
+
+ D_MAGIC_CLEAR( filter );
+
+ SHFREE( context->shmpool, filter );
+ }
+ }
+ }
+
+ if (!input_switch->targets[UDCI_POINTER].fixed)
+ update_targets( input_switch );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_input_switch_update( UniqueInputSwitch *input_switch,
+ UniqueInputChannel *channel )
+{
+ int x, y, i;
+ StretRegion *region;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+
+ x = input_switch->x;
+ y = input_switch->y;
+
+ D_DEBUG_AT( UniQuE_InpSw, "unique_input_switch_update( %d, %d )\n", x, y );
+
+ context = input_switch->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ region = stret_region_at( context->root, x, y, SRF_INPUT, SRCID_UNKNOWN );
+ if (region) {
+ for (i=0; i<_UDCI_NUM; i++) {
+ UniqueInputTarget *target = &input_switch->targets[i];
+
+ if (target->normal == channel)
+ stret_region_get_input( region, i, x, y, &target->normal );
+ }
+ }
+ else {
+ for (i=0; i<_UDCI_NUM; i++) {
+ UniqueInputTarget *target = &input_switch->targets[i];
+
+ if (target->normal == channel)
+ target->normal = NULL;
+ }
+ }
+
+ for (i=0; i<_UDCI_NUM; i++) {
+ UniqueInputTarget *target = &input_switch->targets[i];
+
+ target_switch( input_switch, i, target->fixed ? : target->implicit ? : target->normal );
+ }
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static bool
+target_switch( UniqueInputSwitch *input_switch,
+ UniqueDeviceClassIndex index,
+ UniqueInputChannel *channel )
+{
+ UniqueInputEvent evt;
+ UniqueInputTarget *target;
+ UniqueInputChannel *current;
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+ D_ASSERT( index >= 0 );
+ D_ASSERT( index < _UDCI_NUM );
+
+ target = &input_switch->targets[index];
+
+ current = target->current;
+
+ D_MAGIC_ASSERT_IF( channel, UniqueInputChannel );
+ D_MAGIC_ASSERT_IF( current, UniqueInputChannel );
+
+ if (channel == current)
+ return false;
+
+ D_DEBUG_AT( UniQuE_InpSw, "target_switch( index %d, x %d, y %d, channel %p )\n",
+ index, input_switch->x, input_switch->y, channel );
+
+ evt.type = UIET_CHANNEL;
+
+ evt.channel.index = index;
+ evt.channel.x = input_switch->x;
+ evt.channel.y = input_switch->y;
+
+ if (current) {
+ evt.channel.selected = false;
+
+ unique_input_channel_dispatch( current, &evt );
+ }
+
+ target->current = channel;
+
+ if (channel) {
+ evt.channel.selected = true;
+
+ unique_input_channel_dispatch( channel, &evt );
+ }
+
+ return true;
+}
+
+static void
+target_dispatch( UniqueInputTarget *target,
+ const UniqueInputEvent *event )
+{
+ UniqueInputFilter *filter;
+ UniqueInputChannel *channel;
+
+ D_ASSERT( target != NULL );
+ D_ASSERT( event != NULL );
+
+ channel = target->current;
+
+ D_MAGIC_ASSERT_IF( channel, UniqueInputChannel );
+
+
+ direct_list_foreach (filter, target->filters) {
+ D_MAGIC_ASSERT( filter, UniqueInputFilter );
+
+ if (unique_device_filter( target->clazz, event, &filter->filter )) {
+ channel = filter->channel;
+
+ D_MAGIC_ASSERT( channel, UniqueInputChannel );
+
+ break;
+ }
+ }
+
+ if (channel)
+ unique_input_channel_dispatch( channel, event );
+ else
+ D_DEBUG_AT( UniQuE_InpSw, "target_dispatch( class %d ) "
+ "<- no selected channel, dropping event.\n", target->clazz );
+}
+
+static bool
+update_targets( UniqueInputSwitch *input_switch )
+{
+ int x, y, i;
+ StretRegion *region;
+ UniqueContext *context;
+ bool updated[_UDCI_NUM];
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+
+ x = input_switch->x;
+ y = input_switch->y;
+
+ D_DEBUG_AT( UniQuE_InpSw, "update_targets( %d, %d )\n", x, y );
+
+ context = input_switch->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ region = stret_region_at( context->root, x, y, SRF_INPUT, SRCID_UNKNOWN );
+ if (region) {
+ for (i=0; i<_UDCI_NUM; i++)
+ stret_region_get_input( region, i, x, y, &input_switch->targets[i].normal );
+ }
+ else {
+ for (i=0; i<_UDCI_NUM; i++)
+ input_switch->targets[i].normal = NULL;
+ }
+
+ for (i=0; i<_UDCI_NUM; i++) {
+ UniqueInputTarget *target = &input_switch->targets[i];
+
+ updated[i] = target_switch( input_switch, i,
+ target->fixed ? : target->implicit ? : target->normal );
+ }
+
+ return updated[UDCI_POINTER];
+}
+
+ReactionResult
+_unique_input_switch_device_listener( const void *msg_data,
+ void *ctx )
+{
+ const UniqueInputEvent *event = msg_data;
+ UniqueInputSwitch *inpsw = ctx;
+ UniqueInputTarget *target = NULL;
+ UniqueContext *context;
+
+ (void) event;
+ (void) inpsw;
+
+ D_ASSERT( event != NULL );
+
+ D_MAGIC_ASSERT( inpsw, UniqueInputSwitch );
+
+ context = inpsw->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ if (dfb_windowstack_lock( context->stack ))
+ return RS_OK;
+
+ if (!context->active) {
+ dfb_windowstack_unlock( context->stack );
+ return RS_OK;
+ }
+
+ D_DEBUG_AT( UniQuE_InpSw, "_unique_input_switch_device_listener( %p, %p )\n",
+ event, inpsw );
+
+ switch (event->type) {
+ case UIET_MOTION:
+ target = &inpsw->targets[UDCI_POINTER];
+
+ inpsw->x = event->pointer.x;
+ inpsw->y = event->pointer.y;
+
+ if (!target->fixed && !target->implicit && update_targets( inpsw ))
+ break;
+
+ target_dispatch( target, event );
+ break;
+
+ case UIET_BUTTON:
+ target = &inpsw->targets[UDCI_POINTER];
+
+ if (event->pointer.press && !target->implicit) {
+ D_DEBUG_AT( UniQuE_InpSw, " -> implicit pointer grab, %p\n", target->current );
+
+ target->implicit = target->current;
+ }
+
+ target_dispatch( target, event );
+
+ if (!event->pointer.press && !event->pointer.buttons) {
+ D_ASSUME( target->implicit != NULL );
+
+ if (target->implicit) {
+ D_DEBUG_AT( UniQuE_InpSw, " -> implicit pointer ungrab, %p\n", target->implicit );
+
+ target->implicit = NULL;
+
+ if (!target->fixed)
+ update_targets( inpsw );
+ }
+ }
+ break;
+
+ case UIET_WHEEL:
+ target_dispatch( &inpsw->targets[UDCI_WHEEL], event );
+ break;
+
+ case UIET_KEY:
+ target = &inpsw->targets[UDCI_KEYBOARD];
+
+ if (event->keyboard.press && !target->implicit) {
+ D_DEBUG_AT( UniQuE_InpSw, " -> implicit keyboard grab, %p\n", target->current );
+
+ target->implicit = target->current;
+ }
+
+ target_dispatch( target, event );
+
+ if (!event->keyboard.press && !event->keyboard.modifiers) {
+ //D_ASSUME( target->implicit != NULL );
+
+ if (target->implicit) {
+ D_DEBUG_AT( UniQuE_InpSw, " -> implicit keyboard ungrab, %p\n", target->implicit );
+
+ if (!target->fixed)
+ target_switch( inpsw, UDCI_KEYBOARD, target->normal );
+
+ target->implicit = NULL;
+ }
+ }
+ break;
+
+ default:
+ D_ONCE( "unknown event type" );
+ break;
+ }
+
+ dfb_windowstack_unlock( context->stack );
+
+ return RS_OK;
+}
+
+/**************************************************************************************************/
+
+static void
+purge_connection( UniqueInputSwitch *input_switch,
+ SwitchConnection *connection )
+{
+ UniqueContext *context;
+
+ D_DEBUG_AT( UniQuE_InpSw, "purge_connection( %p, %p )\n", input_switch, connection );
+
+ D_MAGIC_ASSERT( input_switch, UniqueInputSwitch );
+ D_MAGIC_ASSERT( connection, SwitchConnection );
+
+ context = input_switch->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ /* Detach global reaction for receiving events. */
+ unique_device_detach_global( connection->device, &connection->reaction );
+
+ direct_list_remove( &input_switch->connections, &connection->link );
+
+ D_MAGIC_CLEAR( connection );
+
+ SHFREE( context->shmpool, connection );
+}
+
diff --git a/Source/DirectFB/wm/unique/input_switch.h b/Source/DirectFB/wm/unique/input_switch.h
new file mode 100755
index 0000000..cccb8c6
--- /dev/null
+++ b/Source/DirectFB/wm/unique/input_switch.h
@@ -0,0 +1,78 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __UNIQUE__INPUT_SWITCH_H__
+#define __UNIQUE__INPUT_SWITCH_H__
+
+#include <directfb.h>
+
+#include <unique/internal.h>
+#include <unique/types.h>
+
+
+DFBResult unique_input_switch_create ( UniqueContext *context,
+ UniqueInputSwitch **ret_switch );
+
+DFBResult unique_input_switch_destroy ( UniqueInputSwitch *input_switch );
+
+DFBResult unique_input_switch_add ( UniqueInputSwitch *input_switch,
+ UniqueDevice *device );
+
+DFBResult unique_input_switch_remove ( UniqueInputSwitch *input_switch,
+ UniqueDevice *device );
+
+DFBResult unique_input_switch_select ( UniqueInputSwitch *input_switch,
+ UniqueDeviceClassIndex index,
+ UniqueInputChannel *channel );
+
+DFBResult unique_input_switch_set ( UniqueInputSwitch *input_switch,
+ UniqueDeviceClassIndex index,
+ UniqueInputChannel *channel );
+
+DFBResult unique_input_switch_unset ( UniqueInputSwitch *input_switch,
+ UniqueDeviceClassIndex index,
+ UniqueInputChannel *channel );
+
+DFBResult unique_input_switch_set_filter ( UniqueInputSwitch *input_switch,
+ UniqueDeviceClassIndex index,
+ UniqueInputChannel *channel,
+ const UniqueInputEvent *event,
+ UniqueInputFilter **ret_filter );
+
+DFBResult unique_input_switch_unset_filter( UniqueInputSwitch *input_switch,
+ UniqueInputFilter *filter );
+
+DFBResult unique_input_switch_drop ( UniqueInputSwitch *input_switch,
+ UniqueInputChannel *channel );
+
+DFBResult unique_input_switch_update ( UniqueInputSwitch *input_switch,
+ UniqueInputChannel *channel );
+
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/internal.h b/Source/DirectFB/wm/unique/internal.h
new file mode 100755
index 0000000..0dbf9b4
--- /dev/null
+++ b/Source/DirectFB/wm/unique/internal.h
@@ -0,0 +1,378 @@
+/*
+ (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 __UNIQUE__INTERNAL_H__
+#define __UNIQUE__INTERNAL_H__
+
+#include <directfb.h>
+
+#include <direct/list.h>
+
+#include <fusion/object.h>
+#include <fusion/vector.h>
+
+#include <core/coretypes.h>
+#include <core/windows.h>
+
+#include <unique/context.h>
+#include <unique/decoration.h>
+#include <unique/device.h>
+#include <unique/input_events.h>
+#include <unique/stret.h>
+#include <unique/types.h>
+#include <unique/window.h>
+
+
+#define UNIQUE_WM_ABI_VERSION 12
+
+
+extern const StretRegionClass unique_root_region_class;
+extern const StretRegionClass unique_frame_region_class;
+extern const StretRegionClass unique_window_region_class;
+extern const StretRegionClass unique_foo_region_class;
+
+extern const UniqueDeviceClass unique_pointer_device_class;
+extern const UniqueDeviceClass unique_wheel_device_class;
+extern const UniqueDeviceClass unique_keyboard_device_class;
+
+typedef enum {
+ URCI_ROOT,
+ URCI_FRAME,
+ URCI_WINDOW,
+ URCI_FOO,
+
+ _URCI_NUM
+} UniqueRegionClassIndex;
+
+typedef enum {
+ UFI_N,
+ UFI_NE,
+ UFI_E,
+ UFI_SE,
+ UFI_S,
+ UFI_SW,
+ UFI_W,
+ UFI_NW
+} UniqueFooIndex;
+
+typedef ReactionResult (*UniqueWMContextNotify)( WMData *data,
+ const UniqueContextNotification *notification,
+ void *ctx );
+
+typedef ReactionResult (*UniqueWMWindowNotify) ( WMData *data,
+ const UniqueWindowNotification *notification,
+ void *ctx );
+
+
+struct __UniQuE_WMData {
+ int module_abi;
+
+ CoreDFB *core;
+ FusionWorld *world;
+
+ WMShared *shared;
+
+ UniqueWMContextNotify context_notify;
+ UniqueWMWindowNotify window_notify;
+};
+
+struct __UniQuE_WMShared {
+ int magic;
+
+ FusionObjectPool *context_pool;
+ FusionObjectPool *decoration_pool;
+ FusionObjectPool *window_pool;
+
+ StretRegionClassID region_classes[_URCI_NUM];
+ UniqueDeviceClassID device_classes[_UDCI_NUM];
+
+ int device_listener; /* index of the registered global */
+
+ DFBInsets insets;
+
+ DFBRectangle foo_rects[8];
+
+ CoreSurface *foo_surface;
+};
+
+
+typedef enum {
+ UNRL_DESKTOP, /* Icons, redirected fullscreen apps (force-desktop) */
+ UNRL_USER, /* User windows (all currently available stacking classes) */
+ UNRL_SYSTEM, /* Dock/Panel, Glass, Expos?, Clipboard, Virtual Keyboard, IMs */
+ UNRL_CURSOR, /* Cursor shape and attached objects, e.g. Drag'N'Drop */
+ UNRL_SCREEN, /* Display Locking, Screensaver */
+
+ _UNRL_NUM
+} UniqueRootLevel;
+
+typedef enum {
+ UNFL_BACKGROUND, /* Background for blended content, effects, decorations */
+ UNFL_CONTENT, /* The actual DirectFB Window, i.e. its content */
+ UNFL_FOREGROUND, /* Decorations, effects, any other content overlay */
+
+ _UNFL_NUM
+} UniqueFrameLevel;
+
+typedef struct {
+ DirectLink link;
+
+ DFBInputDeviceKeySymbol symbol;
+ DFBInputDeviceModifierMask modifiers;
+
+ UniqueWindow *owner;
+} GrabbedKey;
+
+
+struct __UniQuE_UniqueContext {
+ FusionObject object;
+
+ int magic;
+
+ CoreWindowStack *stack;
+ WMShared *shared;
+
+ CoreLayerRegion *region;
+ CoreSurface *surface;
+
+ DFBDisplayLayerID layer_id;
+
+ bool active;
+
+ DFBColor color;
+
+ int width;
+ int height;
+
+ StretRegion *root;
+
+ FusionVector windows;
+
+
+ UniqueInputSwitch *input_switch;
+
+ UniqueDevice *devices[_UDCI_NUM];
+
+ GlobalReaction cursor_reaction;
+
+ FusionSHMPoolShared *shmpool;
+
+ UniqueInputChannel *foo_channel;
+
+ CoreSurface *cursor_bs; /* backing store for region under cursor */
+ bool cursor_bs_valid;
+ DFBRegion cursor_region;
+ bool cursor_drawn;
+};
+
+struct __UniQuE_UniqueWindow {
+ FusionObject object;
+
+ int magic;
+
+ CoreWindow *window;
+ UniqueContext *context;
+ WMShared *shared;
+
+ CoreSurface *surface;
+
+ UniqueInputChannel *channel;
+ GlobalReaction channel_reaction;
+
+ DirectLink *filters;
+
+ DFBWindowCapabilities caps;
+
+ UniqueWindowFlags flags;
+
+ StretRegion *frame;
+ StretRegion *region;
+ StretRegion *foos[8];
+ DFBPoint foo_motion;
+
+ DFBInsets insets;
+
+ DFBRectangle bounds; /* absolute bounds of the content */
+ DFBRectangle full; /* absolute bounds of the full frame */
+
+ int opacity; /* global alpha factor */
+
+ DFBWindowStackingClass stacking; /* level boundaries */
+ int priority; /* derived from stacking class */
+
+ DFBWindowOptions options; /* flags for appearance/behaviour */
+ DFBWindowEventType events; /* mask of enabled events */
+
+ u32 color_key; /* transparent pixel */
+ DFBRegion opaque; /* region of the window forced to be opaque */
+};
+
+struct __UniQuE_UniqueDecoration {
+ FusionObject object;
+
+ int magic;
+
+ UniqueWindow *window;
+ UniqueContext *context;
+
+ UniqueDecorationFlags flags;
+};
+
+struct __UniQuE_UniqueDecorationItem {
+ const UniqueLayout *layout;
+
+ DFBPoint pos; /* current offset from window origin */
+ DFBDimension size; /* current dimensions */
+};
+
+struct __UniQuE_StretRegion {
+ int magic;
+
+ StretRegion *parent; /* Is NULL for the root region. */
+
+ int level; /* Level within the parent. */
+ int index; /* Index within the level. */
+
+ int levels; /* Number of levels provided. */
+ FusionVector *children; /* Children of each level. */
+
+ StretRegionFlags flags; /* Control appearance and activity. */
+
+ DFBRegion bounds; /* Relative to its parent. */
+
+ StretRegionClassID clazz; /* Region class (implementation) used for rendering etc. */
+
+ void *data; /* Optional private data of region class. */
+ unsigned long arg; /* Optional argument for region class instance. */
+
+ FusionSHMPoolShared *shmpool;
+};
+
+struct __UniQuE_UniqueDevice {
+ int magic;
+
+ UniqueContext *context;
+
+ UniqueDeviceClassID clazz; /* Device class (implementation) used for processing etc. */
+
+ void *data; /* Optional private data of device class. */
+ void *ctx; /* Optional context for device class instance. */
+
+ FusionReactor *reactor; /* UniqueInputEvent deployment */
+
+ DirectLink *connections; /* CoreInputDevice connections */
+};
+
+
+struct __UniQuE_UniqueInputFilter {
+ DirectLink link;
+
+ int magic;
+
+ UniqueDeviceClassIndex index;
+
+ UniqueInputChannel *channel;
+
+ UniqueInputEvent filter;
+};
+
+typedef struct {
+ UniqueDeviceClassID clazz;
+
+ UniqueInputChannel *current;
+
+ UniqueInputChannel *normal;
+ UniqueInputChannel *fixed;
+
+ UniqueInputChannel *implicit;
+
+ DirectLink *filters;
+} UniqueInputTarget;
+
+
+struct __UniQuE_UniqueInputSwitch {
+ int magic;
+
+ UniqueContext *context;
+
+ DirectLink *connections; /* UniqueDevice connections */
+
+ int x;
+ int y;
+
+ UniqueInputTarget targets[_UDCI_NUM];
+};
+
+struct __UniQuE_UniqueInputChannel {
+ int magic;
+
+ UniqueContext *context;
+
+ FusionReactor *reactor; /* UniqueInputEvent arrival */
+};
+
+
+DFBResult unique_wm_module_init ( CoreDFB *core,
+ WMData *data,
+ WMShared *shared,
+ bool master );
+
+void unique_wm_module_deinit( WMData *data,
+ WMShared *shared,
+ bool master,
+ bool emergency );
+
+UniqueContext *unique_wm_create_context( void );
+UniqueDecoration *unique_wm_create_decoration( void );
+UniqueWindow *unique_wm_create_window( void );
+
+/* HACK: temporary, will move into cursor class */
+void unique_draw_cursor( CoreWindowStack *stack, UniqueContext *context, CardState *state, DFBRegion *region );
+
+
+/* global reactions */
+ReactionResult _unique_device_listener ( const void *msg_data,
+ void *ctx );
+
+ReactionResult _unique_wm_module_context_listener ( const void *msg_data,
+ void *ctx );
+
+ReactionResult _unique_wm_module_window_listener ( const void *msg_data,
+ void *ctx );
+
+ReactionResult _unique_cursor_device_listener ( const void *msg_data,
+ void *ctx );
+
+ReactionResult _unique_input_switch_device_listener ( const void *msg_data,
+ void *ctx );
+
+ReactionResult _unique_window_input_channel_listener( const void *msg_data,
+ void *ctx );
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/stret.c b/Source/DirectFB/wm/unique/stret.c
new file mode 100755
index 0000000..0ae2326
--- /dev/null
+++ b/Source/DirectFB/wm/unique/stret.c
@@ -0,0 +1,837 @@
+/*
+ (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/messages.h>
+#include <direct/util.h>
+
+#include <fusion/shmalloc.h>
+#include <fusion/vector.h>
+
+#include <directfb.h>
+
+#include <misc/util.h>
+
+#include <unique/stret.h>
+#include <unique/stret_iteration.h>
+#include <unique/internal.h>
+
+
+#define MAX_CLASSES 16
+
+D_DEBUG_DOMAIN( UniQuE_StReT, "UniQuE/StReT", "UniQuE's Stack Region Tree" );
+
+/**************************************************************************************************/
+
+static void
+default_update( StretRegion *region,
+ void *region_data,
+ void *update_data,
+ unsigned long arg,
+ int x,
+ int y,
+ const DFBRegion *updates,
+ int num )
+{
+ D_DEBUG_AT( UniQuE_StReT, "default_update( %p, %p, %p, %lu, %d, %d, %p, %d )\n",
+ region, region_data, update_data, arg, x, y, updates, num );
+}
+
+static const StretRegionClass default_class = {
+ .Update = default_update,
+};
+
+/**************************************************************************************************/
+
+static const StretRegionClass *classes[MAX_CLASSES] = { &default_class, NULL };
+
+static pthread_mutex_t classes_lock = PTHREAD_MUTEX_INITIALIZER;
+static int classes_count = 1;
+
+/**************************************************************************************************/
+
+DFBResult
+stret_class_register( const StretRegionClass *clazz,
+ StretRegionClassID *ret_id )
+{
+ int i;
+
+ D_DEBUG_AT( UniQuE_StReT, "stret_class_register( %p )\n", clazz );
+
+ D_ASSERT( clazz != NULL );
+ D_ASSERT( ret_id != NULL );
+
+ pthread_mutex_lock( &classes_lock );
+
+ if (classes_count == MAX_CLASSES) {
+ D_WARN( "too many classes" );
+ pthread_mutex_unlock( &classes_lock );
+ return DFB_LIMITEXCEEDED;
+ }
+
+ classes_count++;
+
+ for (i=0; i<MAX_CLASSES; i++) {
+ if (!classes[i]) {
+ classes[i] = clazz;
+ break;
+ }
+ }
+
+ D_DEBUG_AT( UniQuE_StReT, " -> New class ID is %d.\n", i );
+
+ D_ASSERT( i < MAX_CLASSES );
+
+ *ret_id = i;
+
+ pthread_mutex_unlock( &classes_lock );
+
+ return DFB_OK;
+}
+
+DFBResult
+stret_class_unregister( StretRegionClassID id )
+{
+ D_DEBUG_AT( UniQuE_StReT, "stret_class_unregister( %d )\n", id );
+
+ pthread_mutex_lock( &classes_lock );
+
+ D_ASSERT( id >= 0 );
+ D_ASSERT( id < MAX_CLASSES );
+ D_ASSERT( classes[id] != NULL );
+
+ classes[id] = NULL;
+
+ classes_count--;
+
+ pthread_mutex_unlock( &classes_lock );
+
+ return DFB_OK;
+}
+
+
+
+DFBResult
+stret_region_create( StretRegionClassID class_id,
+ void *data,
+ unsigned long arg,
+ StretRegionFlags flags,
+ int levels,
+ int x,
+ int y,
+ int width,
+ int height,
+ StretRegion *parent,
+ int level,
+ FusionSHMPoolShared *pool,
+ StretRegion **ret_region )
+{
+ int i;
+ StretRegion *region;
+
+ D_DEBUG_AT( UniQuE_StReT, "stret_region_create( class %d, flags 0x%08x, %d,%d - %dx%d (%d), "
+ "parent %p [%d/%d] )\n", class_id, flags, x, y, width, height, levels, parent,
+ level, parent ? parent->levels-1 : 0 );
+
+ D_ASSERT( class_id >= 0 );
+ D_ASSERT( class_id < MAX_CLASSES );
+ D_ASSERT( classes[class_id] != NULL );
+
+ D_ASSERT( ! (flags & ~SRF_ALL) );
+
+ D_ASSERT( levels > 0 );
+ D_ASSERT( width > 0 );
+ D_ASSERT( height > 0 );
+
+ D_MAGIC_ASSERT_IF( parent, StretRegion );
+
+ if (parent)
+ D_ASSERT( level < parent->levels );
+
+ D_ASSERT( ret_region != NULL );
+
+ /* Allocate region data. */
+ region = SHCALLOC( pool, 1, sizeof(StretRegion) + sizeof(FusionVector) * levels );
+ if (!region) {
+ D_WARN( "out of (shared) memory" );
+ return D_OOSHM();
+ }
+
+ /* Initialize region data. */
+ region->parent = parent;
+ region->level = level;
+ region->levels = levels;
+ region->children = (FusionVector*)(region + 1);
+ region->flags = flags;
+ region->bounds = (DFBRegion) { x, y, x + width - 1, y + height - 1 };
+ region->clazz = class_id;
+ region->data = data;
+ region->arg = arg;
+ region->shmpool = pool;
+
+ /* Initialize levels. */
+ for (i=0; i<levels; i++)
+ fusion_vector_init( &region->children[i], 4, pool );
+
+
+ /* Add the region to its parent. */
+ if (parent) {
+ FusionVector *children = &parent->children[level];
+
+ region->index = fusion_vector_size( children );
+
+ if (fusion_vector_add( children, region )) {
+ D_WARN( "out of (shared) memory" );
+ SHFREE( pool, region );
+ return D_OOSHM();
+ }
+ }
+
+
+ D_MAGIC_SET( region, StretRegion );
+
+#if D_DEBUG_ENABLED
+{
+ DFBRegion bounds;
+
+ stret_region_get_abs( region, &bounds );
+
+ D_DEBUG_AT( UniQuE_StReT, " -> Index %d, absolute bounds: %d,%d - %dx%d\n",
+ region->index, DFB_RECTANGLE_VALS_FROM_REGION( &bounds ) );
+}
+#endif
+
+ *ret_region = region;
+
+ return DFB_OK;
+}
+
+DFBResult
+stret_region_destroy( StretRegion *region )
+{
+ int i;
+ int index;
+ StretRegion *parent;
+ StretRegion *child;
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ D_DEBUG_AT( UniQuE_StReT,
+ "stret_region_destroy( %d, %d - %dx%d, level %d, index %d )\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region->bounds ), region->level, region->index );
+
+ parent = region->parent;
+ if (parent) {
+ FusionVector *children = &parent->children[region->level];
+
+ D_MAGIC_ASSERT( parent, StretRegion );
+
+ index = region->index;
+
+ D_ASSERT( index >= 0 );
+ D_ASSERT( index == fusion_vector_index_of( children, region ) );
+
+ fusion_vector_remove( children, index );
+
+ for (; index<fusion_vector_size(children); index++) {
+ StretRegion *child = fusion_vector_at( children, index );
+
+ child->index = index;
+ }
+ }
+
+ for (i=0; i<region->levels; i++) {
+ FusionVector *children = &region->children[i];
+
+ D_ASSUME( ! fusion_vector_has_elements( children ) );
+
+ fusion_vector_foreach( child, index, *children ) {
+ D_MAGIC_ASSERT( child, StretRegion );
+ D_ASSERT( child->parent == region );
+
+ child->parent = NULL;
+ }
+
+ fusion_vector_destroy( children );
+ }
+
+ D_MAGIC_CLEAR( region );
+
+ SHFREE( region->shmpool, region );
+
+ return DFB_OK;
+}
+
+
+DFBResult
+stret_region_enable( StretRegion *region,
+ StretRegionFlags flags )
+{
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ region->flags |= flags;
+
+ return DFB_OK;
+}
+
+DFBResult
+stret_region_disable( StretRegion *region,
+ StretRegionFlags flags )
+{
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ region->flags &= ~flags;
+
+ return DFB_OK;
+}
+
+
+DFBResult
+stret_region_move( StretRegion *region,
+ int dx,
+ int dy )
+{
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ dfb_region_translate( &region->bounds, dx, dy );
+
+ return DFB_OK;
+}
+
+DFBResult
+stret_region_resize( StretRegion *region,
+ int width,
+ int height )
+{
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ dfb_region_resize( &region->bounds, width, height );
+
+ return DFB_OK;
+}
+
+DFBResult
+stret_region_restack( StretRegion *region,
+ int index )
+{
+ StretRegion *parent;
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ D_ASSUME( region->parent != NULL );
+
+ parent = region->parent;
+ if (parent) {
+ int old;
+ FusionVector *children = &parent->children[region->level];
+
+ D_MAGIC_ASSERT( parent, StretRegion );
+
+ old = region->index;
+
+ D_ASSERT( old >= 0 );
+ D_ASSERT( old == fusion_vector_index_of( children, region ) );
+
+ fusion_vector_move( children, old, index );
+
+ for (index = MIN(index,old); index<fusion_vector_size(children); index++) {
+ StretRegion *child = fusion_vector_at( children, index );
+
+ child->index = index;
+ }
+ }
+
+ return DFB_OK;
+}
+
+void
+stret_region_get_abs( StretRegion *region,
+ DFBRegion *ret_bounds )
+{
+ DFBRegion bounds;
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ D_ASSERT( ret_bounds != NULL );
+
+ bounds = region->bounds;
+
+ while (region->parent) {
+ StretRegion *parent = region->parent;
+
+ D_MAGIC_ASSERT( parent, StretRegion );
+
+ dfb_region_translate( &bounds, parent->bounds.x1, parent->bounds.y1 );
+
+ region = parent;
+ }
+
+ *ret_bounds = bounds;
+}
+
+void
+stret_region_get_size( StretRegion *region,
+ DFBDimension *ret_size )
+{
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ D_ASSERT( ret_size != NULL );
+
+ ret_size->w = region->bounds.x2 - region->bounds.x1 + 1;
+ ret_size->h = region->bounds.y2 - region->bounds.y1 + 1;
+}
+
+DFBResult
+stret_region_get_input( StretRegion *region,
+ int index,
+ int x,
+ int y,
+ UniqueInputChannel **ret_channel )
+{
+ const StretRegionClass *clazz;
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ D_ASSERT( ret_channel != NULL );
+
+ D_ASSERT( region->clazz >= 0 );
+ D_ASSERT( region->clazz < MAX_CLASSES );
+
+ clazz = classes[region->clazz];
+
+ D_ASSERT( clazz != NULL );
+
+ if (clazz->GetInput)
+ return clazz->GetInput( region, region->data, region->arg, index, x, y, ret_channel );
+
+ return DFB_UNSUPPORTED;
+}
+
+
+typedef struct {
+ int num;
+ int max;
+ DFBRegion *regions;
+ StretRegion *region;
+} ClipOutContext;
+
+static void
+clip_out( StretIteration *iteration,
+ ClipOutContext *context,
+ int x1,
+ int y1,
+ int x2,
+ int y2 )
+{
+ StretRegion *region;
+ DFBRegion cutout;
+ DFBRegion area = { x1, y1, x2, y2 };
+
+ D_DEBUG_AT( UniQuE_StReT, " clip_out( %4d, %4d - %4dx%4d )\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &area ) );
+
+ D_ASSERT( x1 <= x2 );
+ D_ASSERT( y1 <= y2 );
+
+ while (true) {
+ region = stret_iteration_next( iteration, &area );
+ if (!region || region == context->region) {
+ context->num++;
+
+ if (context->num <= context->max) {
+ DFBRegion *region = &context->regions[ context->num - 1 ];
+
+ D_DEBUG_AT( UniQuE_StReT, " (%2d) %4d, %4d - %4dx%4d\n",
+ context->num - 1, x1, y1, x2 - x1 + 1, y2 - y1 + 1 );
+
+ region->x1 = x1;
+ region->y1 = y1;
+ region->x2 = x2;
+ region->y2 = y2;
+ }
+ else
+ D_DEBUG_AT( UniQuE_StReT, " Maximum number of regions exceeded, dropping...\n" );
+
+ if (region)
+ stret_iteration_abort( iteration );
+
+ return;
+ }
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ if (D_FLAGS_ARE_SET( region->flags, SRF_OUTPUT | SRF_OPAQUE ))
+ break;
+ }
+
+ cutout = DFB_REGION_INIT_TRANSLATED( &region->bounds, iteration->x0, iteration->y0 );
+
+ dfb_region_clip( &cutout, x1, y1, x2, y2 );
+
+ /* upper */
+ if (cutout.y1 != y1) {
+ StretIteration fork = *iteration;
+
+ clip_out( &fork, context, x1, y1, x2, cutout.y1 - 1 );
+ }
+
+ /* left */
+ if (cutout.x1 != x1) {
+ StretIteration fork = *iteration;
+
+ clip_out( &fork, context, x1, cutout.y1, cutout.x1 - 1, cutout.y2 );
+ }
+
+ /* right */
+ if (cutout.x2 != x2) {
+ StretIteration fork = *iteration;
+
+ clip_out( &fork, context, cutout.x2 + 1, cutout.y1, x2, cutout.y2 );
+ }
+
+ /* lower */
+ if (cutout.y2 != y2) {
+ StretIteration fork = *iteration;
+
+ clip_out( &fork, context, x1, cutout.y2 + 1, x2, y2 );
+ }
+
+ stret_iteration_abort( iteration );
+}
+
+DFBResult
+stret_region_visible( StretRegion *region,
+ const DFBRegion *base,
+ bool children,
+ DFBRegion *ret_regions,
+ int max_num,
+ int *ret_num )
+{
+ bool visible = true;
+ DFBRegion area;
+ ClipOutContext context;
+ StretIteration iteration;
+ StretRegion *root;
+
+ int x0, y0;
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ DFB_REGION_ASSERT_IF( base );
+
+ D_ASSERT( ret_regions != NULL );
+ D_ASSERT( max_num > 0 );
+ D_ASSERT( ret_num != NULL );
+
+ if (base) {
+ D_DEBUG_AT( UniQuE_StReT,
+ "stret_region_visible( %d, %d - %dx%d of %d, %d - %dx%d )\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( base ),
+ DFB_RECTANGLE_VALS_FROM_REGION( &region->bounds ) );
+
+ area = *base;
+ }
+ else {
+ D_DEBUG_AT( UniQuE_StReT,
+ "stret_region_visible( %d, %d - %dx%d )\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region->bounds ) );
+
+ area.x1 = 0;
+ area.y1 = 0;
+ area.x2 = region->bounds.x2 - region->bounds.x1;
+ area.y2 = region->bounds.y2 - region->bounds.y1;
+ }
+
+
+ if (! D_FLAGS_IS_SET( region->flags, SRF_ACTIVE )) {
+ D_DEBUG_AT( UniQuE_StReT, " -> Region is not active and therefore invisible!\n" );
+
+ *ret_num = 0;
+
+ return DFB_OK;
+ }
+
+
+ context.num = 0;
+ context.max = max_num;
+ context.regions = ret_regions;
+ context.region = region;
+
+ x0 = region->bounds.x1;
+ y0 = region->bounds.y1;
+
+ root = region;
+
+ if (region->parent) {
+ int rx2;
+ int ry2;
+ StretRegion *parent = region->parent;
+
+ do {
+ D_MAGIC_ASSERT( parent, StretRegion );
+
+ if (! D_FLAGS_IS_SET( parent->flags, SRF_ACTIVE )) {
+ D_DEBUG_AT( UniQuE_StReT, " -> At least one parent is not active!\n" );
+
+ *ret_num = 0;
+
+ return DFB_OK;
+ }
+
+ x0 += parent->bounds.x1;
+ y0 += parent->bounds.y1;
+
+ rx2 = parent->bounds.x2;
+ ry2 = parent->bounds.y2;
+
+ root = parent;
+
+ visible = dfb_region_intersect( &area, - x0, - y0, rx2 - x0, ry2 - y0 );
+
+ parent = parent->parent;
+ } while (visible && parent);
+ }
+ else if (base)
+ visible = dfb_region_intersect( &area, 0, 0, region->bounds.x2, region->bounds.y2 );
+
+
+ if (!visible) {
+ D_DEBUG_AT( UniQuE_StReT, " -> Region is fully clipped by ancestors!\n" );
+
+ *ret_num = 0;
+
+ return DFB_OK;
+ }
+
+
+ stret_iteration_init( &iteration, root, children ? region : NULL );
+
+ clip_out( &iteration, &context, x0 + area.x1, y0 + area.y1, x0 + area.x2, y0 + area.y2 );
+
+
+ *ret_num = context.num;
+
+ if (context.num > context.max) {
+ D_DEBUG_AT( UniQuE_StReT, " -> Failed with %d/%d regions!\n",
+ context.num, context.max );
+
+ return DFB_LIMITEXCEEDED;
+ }
+
+ D_DEBUG_AT( UniQuE_StReT, " -> Succeeded with %d/%d regions.\n", context.num, context.max );
+
+ return DFB_OK;
+}
+
+
+typedef struct {
+ StretIteration iteration;
+ void *update_data;
+} UpdateContext;
+
+static void
+region_update( UpdateContext *context,
+ int x1,
+ int y1,
+ int x2,
+ int y2 )
+{
+ int x0, y0;
+ DFBRegion area = { x1, y1, x2, y2 };
+ StretRegion *region;
+
+ D_DEBUG_AT( UniQuE_StReT, " region_update( %4d, %4d - %4dx%4d )\n",
+ x1, y1, x2 - x1 + 1, y2 - y1 + 1 );
+
+ D_ASSERT( x1 <= x2 );
+ D_ASSERT( y1 <= y2 );
+
+ while (true) {
+ region = stret_iteration_next( &context->iteration, &area );
+ if (!region)
+ return;
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ if (D_FLAGS_IS_SET( region->flags, SRF_OUTPUT ))
+ break;
+ }
+
+ x0 = context->iteration.x0;
+ y0 = context->iteration.y0;
+
+ D_DEBUG_AT( UniQuE_StReT, " -> %4d, %4d - %4dx%4d @ %4d, %4d (class %d, index %d)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region->bounds ),
+ x0, y0, region->clazz, region->index );
+
+ dfb_region_clip( &area, DFB_REGION_VALS_TRANSLATED( &region->bounds, x0, y0 ) );
+
+
+
+ if (D_FLAGS_IS_SET( region->flags, SRF_OPAQUE )) {
+ /* upper */
+ if (area.y1 != y1) {
+ UpdateContext fork = *context;
+
+ region_update( &fork, x1, y1, x2, area.y1 - 1 );
+ }
+
+ /* left */
+ if (area.x1 != x1) {
+ UpdateContext fork = *context;
+
+ region_update( &fork, x1, area.y1, area.x1 - 1, area.y2 );
+ }
+
+ /* right */
+ if (area.x2 != x2) {
+ UpdateContext fork = *context;
+
+ region_update( &fork, area.x2 + 1, area.y1, x2, area.y2 );
+ }
+
+ /* lower */
+ if (area.y2 != y2) {
+ UpdateContext fork = *context;
+
+ region_update( &fork, x1, area.y2 + 1, x2, y2 );
+ }
+
+ stret_iteration_abort( &context->iteration );
+ }
+ else
+ region_update( context, x1, y1, x2, y2 );
+
+
+ x0 += region->bounds.x1;
+ y0 += region->bounds.y1;
+
+ dfb_region_translate( &area, - x0, - y0 );
+
+ D_DEBUG_AT( UniQuE_StReT, " => %4d, %4d - %4dx%4d @ %4d, %4d (class %d, index %d)\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &area ),
+ x0, y0, region->clazz, region->index );
+
+ D_ASSERT( classes[region->clazz]->Update );
+
+ classes[region->clazz]->Update( region, region->data, context->update_data,
+ region->arg, x0, y0, &area, 1 );
+}
+
+DFBResult
+stret_region_update( StretRegion *region,
+ const DFBRegion *clip,
+ void *update_data )
+{
+ DFBRegion area;
+ UpdateContext context;
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ DFB_REGION_ASSERT_IF( clip );
+
+ if (clip)
+ D_DEBUG_AT( UniQuE_StReT,
+ "stret_region_update( %d, %d - %dx%d of %d, %d - %dx%d )\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( clip ),
+ DFB_RECTANGLE_VALS_FROM_REGION( &region->bounds ) );
+ else
+ D_DEBUG_AT( UniQuE_StReT,
+ "stret_region_update( %d, %d - %dx%d )\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( &region->bounds ) );
+
+ if (! D_FLAGS_IS_SET( region->flags, SRF_ACTIVE )) {
+ D_DEBUG_AT( UniQuE_StReT, " -> Region is not active and therefore invisible.\n" );
+ return DFB_OK;
+ }
+
+ area.x1 = 0;
+ area.y1 = 0;
+ area.x2 = region->bounds.x2 - region->bounds.x1;
+ area.y2 = region->bounds.y2 - region->bounds.y1;
+
+ if (clip && !dfb_region_region_intersect( &area, clip )) {
+ D_DEBUG_AT( UniQuE_StReT, " -> Region doesn't intersect with clip.\n" );
+ return DFB_OK;
+ }
+
+
+ stret_iteration_init( &context.iteration, region, NULL );
+
+ context.update_data = update_data;
+
+ region_update( &context, area.x1, area.y1, area.x2, area.y2 );
+
+ return DFB_OK;
+}
+
+StretRegion *
+stret_region_at( StretRegion *region,
+ int x,
+ int y,
+ StretRegionFlags flags,
+ StretRegionClassID class_id )
+{
+ StretIteration iteration;
+ DFBRegion area = { x, y, x, y };
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ D_DEBUG_AT( UniQuE_StReT, "stret_region_at( %p, %d, %d, 0x%08x )\n", region, x, y, flags );
+
+ if (! D_FLAGS_IS_SET( region->flags, SRF_ACTIVE )) {
+ D_DEBUG_AT( UniQuE_StReT, " -> Region is not active.\n" );
+ return NULL;
+ }
+
+
+ stret_iteration_init( &iteration, region, NULL );
+
+ while ((region = stret_iteration_next( &iteration, &area )) != NULL) {
+ if (! D_FLAGS_ARE_SET( region->flags, flags ))
+ continue;
+
+ if (class_id != SRCID_UNKNOWN && region->clazz != class_id)
+ continue;
+
+ return region;
+ }
+
+ return NULL;
+}
+
+void *
+stret_region_data( const StretRegion *region )
+{
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ return region->data;
+}
+
diff --git a/Source/DirectFB/wm/unique/stret.h b/Source/DirectFB/wm/unique/stret.h
new file mode 100755
index 0000000..01bcc97
--- /dev/null
+++ b/Source/DirectFB/wm/unique/stret.h
@@ -0,0 +1,155 @@
+/*
+ (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 __UNIQUE__STRET_H__
+#define __UNIQUE__STRET_H__
+
+#include <directfb.h>
+
+#include <unique/types.h>
+
+/*
+ * A 'StReT' is a Stack Region Tree.
+ */
+
+
+typedef enum {
+ SRF_NONE = 0x00000000,
+
+ SRF_INPUT = 0x00000001,
+ SRF_OUTPUT = 0x00000002,
+ SRF_ACTIVE = 0x00000004,
+
+ SRF_OPAQUE = 0x00000010,
+ SRF_SHAPED = 0x00000020,
+
+ SRF_ALL = 0x00000037
+} StretRegionFlags;
+
+
+typedef struct {
+ DFBResult (*GetInput)( StretRegion *region,
+ void *region_data,
+ unsigned long arg,
+ int index,
+ int x,
+ int y,
+ UniqueInputChannel **ret_channel );
+
+ void (*Update) ( StretRegion *region,
+ void *region_data,
+ void *update_data,
+ unsigned long arg,
+ int x,
+ int y,
+ const DFBRegion *updates,
+ int num );
+} StretRegionClass;
+
+typedef int StretRegionClassID;
+
+#define SRCID_UNKNOWN -1
+#define SRCID_DEFAULT 0
+
+
+DFBResult stret_class_register ( const StretRegionClass *clazz,
+ StretRegionClassID *ret_id );
+
+DFBResult stret_class_unregister( StretRegionClassID id );
+
+
+
+DFBResult stret_region_create ( StretRegionClassID class_id,
+ void *data,
+ unsigned long arg,
+ StretRegionFlags flags,
+ int levels,
+ int x,
+ int y,
+ int width,
+ int height,
+ StretRegion *parent,
+ int level,
+ FusionSHMPoolShared *pool,
+ StretRegion **ret_region );
+
+DFBResult stret_region_destroy ( StretRegion *region );
+
+
+DFBResult stret_region_enable ( StretRegion *region,
+ StretRegionFlags flags );
+
+DFBResult stret_region_disable ( StretRegion *region,
+ StretRegionFlags flags );
+
+
+DFBResult stret_region_move ( StretRegion *region,
+ int dx,
+ int dy );
+
+DFBResult stret_region_resize ( StretRegion *region,
+ int width,
+ int height );
+
+DFBResult stret_region_restack ( StretRegion *region,
+ int index );
+
+
+void stret_region_get_abs ( StretRegion *region,
+ DFBRegion *ret_bounds );
+
+void stret_region_get_size ( StretRegion *region,
+ DFBDimension *ret_size );
+
+DFBResult stret_region_get_input( StretRegion *region,
+ int index,
+ int x,
+ int y,
+ UniqueInputChannel **ret_channel );
+
+DFBResult stret_region_visible ( StretRegion *region,
+ const DFBRegion *base,
+ bool children,
+ DFBRegion *ret_regions,
+ int max_num,
+ int *ret_num );
+
+DFBResult stret_region_update ( StretRegion *region,
+ const DFBRegion *update,
+ void *update_data );
+
+StretRegion *stret_region_at ( StretRegion *region,
+ int x,
+ int y,
+ StretRegionFlags flags,
+ StretRegionClassID class_id );
+
+void *stret_region_data ( const StretRegion *region );
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/stret_iteration.c b/Source/DirectFB/wm/unique/stret_iteration.c
new file mode 100755
index 0000000..30c84e6
--- /dev/null
+++ b/Source/DirectFB/wm/unique/stret_iteration.c
@@ -0,0 +1,209 @@
+/*
+ (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/util.h>
+
+#include <misc/util.h>
+
+#include <unique/stret_iteration.h>
+#include <unique/internal.h>
+
+D_DEBUG_DOMAIN( UniQuE_StReT, "UniQuE/StReT", "UniQuE's Stack Region Tree" );
+
+static inline bool
+accept_region( StretRegion *region, int x0, int y0, const DFBRegion *clip )
+{
+ if (!D_FLAGS_IS_SET( region->flags, SRF_ACTIVE ))
+ return false;
+
+ if (!clip)
+ return true;
+
+ return dfb_region_intersects( clip, DFB_REGION_VALS_TRANSLATED( &region->bounds, x0, y0 ) );
+}
+
+static inline bool
+check_depth( int frame )
+{
+ if (frame >= STRET_ITERATION_MAX_DEPTH) {
+ D_WARN( "refusing to exceed depth limit of %d", STRET_ITERATION_MAX_DEPTH );
+ return false;
+ }
+
+ return true;
+}
+
+void
+stret_iteration_init( StretIteration *iteration, StretRegion *region, StretRegion *abort_at )
+{
+ D_ASSERT( iteration != NULL );
+
+ D_MAGIC_ASSERT( region, StretRegion );
+ D_MAGIC_ASSERT_IF( abort_at, StretRegion );
+
+ D_DEBUG_AT( UniQuE_StReT, "stret_iteration_init()\n" );
+
+ iteration->frame = -1;
+ iteration->x0 = 0;
+ iteration->y0 = 0;
+ iteration->abort = abort_at;
+
+ do {
+ int last_level = region->levels - 1;
+ int last_child = fusion_vector_size( &region->children[last_level] ) - 1;
+
+ iteration->frame++;
+
+ iteration->x0 += region->bounds.x1;
+ iteration->y0 += region->bounds.y1;
+
+ iteration->stack[iteration->frame].region = region;
+ iteration->stack[iteration->frame].level = last_level;
+ iteration->stack[iteration->frame].index = last_child - 1;
+
+ D_DEBUG_AT( UniQuE_StReT, " -> (%d) %p, last level %d, last index %d\n",
+ iteration->frame, region, last_level, last_child );
+
+ if (last_child >= 0) {
+ region = fusion_vector_at( &region->children[last_level], last_child );
+
+ D_MAGIC_ASSERT( region, StretRegion );
+ }
+ } while (fusion_vector_size( &region->children[region->levels - 1] ) && check_depth( iteration->frame + 1 ));
+
+ iteration->stack[iteration->frame].index++;
+
+ D_MAGIC_SET( iteration, StretIteration );
+}
+
+StretRegion *
+stret_iteration_next( StretIteration *iteration,
+ const DFBRegion *clip )
+{
+ int index;
+ int level;
+ StretRegion *region;
+
+ D_MAGIC_ASSERT( iteration, StretIteration );
+
+ DFB_REGION_ASSERT_IF( clip );
+
+ if (clip)
+ D_DEBUG_AT( UniQuE_StReT, "stret_iteration_next( %d, %d - %dx%d )\n",
+ DFB_RECTANGLE_VALS_FROM_REGION( clip ) );
+ else
+ D_DEBUG_AT( UniQuE_StReT, "stret_iteration_next()\n" );
+
+ while (iteration->frame >= 0) {
+ StretIterationStackFrame *frame = &iteration->stack[iteration->frame];
+
+ region = frame->region;
+ level = frame->level;
+ index = frame->index--;
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ D_DEBUG_AT( UniQuE_StReT, " -> (%d) %p, level [%d/%d], index %d\n",
+ iteration->frame, region, level, region->levels - 1, index );
+
+ if (iteration->abort && region == iteration->abort) {
+ D_MAGIC_CLEAR( iteration );
+ return NULL;
+ }
+
+ if (index < 0) {
+ level = --frame->level;
+
+ if (level < 0) {
+ iteration->frame--;
+
+ iteration->x0 -= region->bounds.x1;
+ iteration->y0 -= region->bounds.y1;
+
+ if (accept_region( region, iteration->x0, iteration->y0, clip ))
+ return region;
+ }
+ else {
+ frame->index = fusion_vector_size( &region->children[level] ) - 1;
+ }
+ }
+ else {
+ region = fusion_vector_at( &region->children[level], index );
+
+ D_MAGIC_ASSERT( region, StretRegion );
+
+ if (iteration->abort && region == iteration->abort) {
+ D_MAGIC_CLEAR( iteration );
+ return NULL;
+ }
+
+ if (accept_region( region, iteration->x0, iteration->y0, clip )) {
+ level = region->levels - 1;
+
+ while (fusion_vector_is_empty( &region->children[level] )) {
+ if (level)
+ level--;
+ else
+ return region;
+ }
+
+ if (check_depth( iteration->frame + 1 )) {
+ frame = &iteration->stack[++iteration->frame];
+
+ iteration->x0 += region->bounds.x1;
+ iteration->y0 += region->bounds.y1;
+
+ frame->region = region;
+ frame->level = level;
+ frame->index = fusion_vector_size( &region->children[level] ) - 1;
+
+ continue;
+ }
+
+ return region;
+ }
+ }
+ }
+
+ D_ASSUME( iteration->x0 == 0 );
+ D_ASSUME( iteration->y0 == 0 );
+
+ D_MAGIC_CLEAR( iteration );
+
+ return NULL;
+}
+
+void
+stret_iteration_abort( StretIteration *iteration )
+{
+ D_MAGIC_CLEAR( iteration );
+}
+
diff --git a/Source/DirectFB/wm/unique/stret_iteration.h b/Source/DirectFB/wm/unique/stret_iteration.h
new file mode 100755
index 0000000..251280a
--- /dev/null
+++ b/Source/DirectFB/wm/unique/stret_iteration.h
@@ -0,0 +1,68 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __UNIQUE__STRET_ITERATION_H__
+#define __UNIQUE__STRET_ITERATION_H__
+
+#include <directfb.h>
+
+#include <unique/types.h>
+
+
+#define STRET_ITERATION_MAX_DEPTH 4
+
+typedef struct {
+ StretRegion *region;
+ int level;
+ int index;
+} StretIterationStackFrame;
+
+typedef struct {
+ int magic;
+
+ StretIterationStackFrame stack[STRET_ITERATION_MAX_DEPTH];
+ int frame;
+
+ int x0;
+ int y0;
+
+ StretRegion *abort;
+} StretIteration;
+
+
+void stret_iteration_init ( StretIteration *iteration,
+ StretRegion *region,
+ StretRegion *abort_at );
+
+StretRegion *stret_iteration_next ( StretIteration *iteration,
+ const DFBRegion *clip );
+
+void stret_iteration_abort( StretIteration *iteration );
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/stret_test.c b/Source/DirectFB/wm/unique/stret_test.c
new file mode 100755
index 0000000..62839d0
--- /dev/null
+++ b/Source/DirectFB/wm/unique/stret_test.c
@@ -0,0 +1,153 @@
+/*
+ (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 file is subject to the terms and conditions of the MIT License:
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <config.h>
+
+#include <fusion/fusion.h>
+#include <fusion/shm/pool.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <misc/util.h>
+
+#include <unique/stret.h>
+#include <unique/stret_iteration.h>
+#include <unique/internal.h>
+
+
+int
+main( int argc, char *argv[] )
+{
+ DirectResult ret;
+ FusionWorld *world;
+ StretRegion *root;
+ StretRegion *child[16];
+ int child_num = 0;
+ StretIteration iteration;
+ DFBRegion clip;
+ FusionSHMPoolShared *pool;
+
+ ret = fusion_enter( -1, 0, FER_ANY, &world );
+ if (ret)
+ return -1;
+
+ ret = fusion_shm_pool_create( world, "StReT Test Pool", 0x10000, direct_config->debug, &pool );
+ if (ret) {
+ fusion_exit( world, false );
+ return -1;
+ }
+
+ D_INFO( "StReT/Test: Starting...\n" );
+
+
+ ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 2, 0, 0, 1000, 1000, NULL, 0, pool, &root );
+ if (ret) {
+ D_DERROR( ret, "StReT/Test: Could not create root region!\n" );
+ goto error_root;
+ }
+ else {
+ ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 10, 10, 100, 100, root, 1, pool, &child[child_num++] );
+ if (ret) {
+ D_DERROR( ret, "StReT/Test: Could not create child region!\n" );
+ goto error_child;
+ }
+ else {
+ ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 50, 50, 30, 30, child[0], 0, pool, &child[child_num++] );
+ if (ret) {
+ D_DERROR( ret, "StReT/Test: Could not create child region!\n" );
+ goto error_child;
+ }
+
+ ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 20, 20, 30, 30, child[0], 0, pool, &child[child_num++] );
+ if (ret) {
+ D_DERROR( ret, "StReT/Test: Could not create child region!\n" );
+ goto error_child;
+ }
+ else {
+ ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 10, 10, 10, 10, child[2], 0, pool, &child[child_num++] );
+ if (ret) {
+ D_DERROR( ret, "StReT/Test: Could not create child region!\n" );
+ goto error_child;
+ }
+
+ ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 20, 20, 10, 10, child[2], 0, pool, &child[child_num++] );
+ if (ret) {
+ D_DERROR( ret, "StReT/Test: Could not create child region!\n" );
+ goto error_child;
+ }
+ }
+ }
+
+ ret = stret_region_create( 0, NULL, 0, SRF_ACTIVE, 1, 200, 10, 200, 200, root, 0, pool, &child[child_num++] );
+ if (ret) {
+ D_DERROR( ret, "StReT/Test: Could not create child region!\n" );
+ goto error_child;
+ }
+ }
+
+
+
+
+ stret_iteration_init( &iteration, root, NULL );
+
+ clip = (DFBRegion) { 50, 50, 200, 59 };
+
+ D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[4] );
+ //D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[3] );
+ D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[2] );
+ //D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[1] );
+ D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[0] );
+ D_ASSERT( stret_iteration_next( &iteration, &clip ) == child[5] );
+ D_ASSERT( stret_iteration_next( &iteration, &clip ) == root );
+ D_ASSERT( stret_iteration_next( &iteration, &clip ) == NULL );
+
+
+ stret_region_destroy( child[child_num-1] );
+
+error_child:
+ while (--child_num)
+ stret_region_destroy( child[child_num-1] );
+
+ stret_region_destroy( root );
+
+error_root:
+ fusion_shm_pool_destroy( world, pool );
+
+ fusion_exit( world, false );
+
+ return 0;
+}
+
diff --git a/Source/DirectFB/wm/unique/test_color.c b/Source/DirectFB/wm/unique/test_color.c
new file mode 100755
index 0000000..66bedba
--- /dev/null
+++ b/Source/DirectFB/wm/unique/test_color.c
@@ -0,0 +1,221 @@
+/*
+ (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 file is subject to the terms and conditions of the MIT License:
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <directfb.h>
+
+#include <unique/context.h>
+#include <unique/uniquewm.h>
+
+/*****************************************************************************/
+
+static IDirectFB *dfb = NULL;
+
+static const char *filename = NULL;
+static DFBBoolean color = DFB_FALSE;
+
+
+/*****************************************************************************/
+
+static DFBBoolean parse_command_line ( int argc, char *argv[] );
+static void set_color ( void );
+
+/*****************************************************************************/
+
+static UniqueContext *context;
+
+static bool
+context_callback( FusionObjectPool *pool,
+ FusionObject *object,
+ void *ctx )
+{
+ if (object->state != FOS_ACTIVE)
+ return true;
+
+ context = (UniqueContext*) object;
+ if (unique_context_ref( context )) {
+ D_ERROR( "UniQuE/Test: unique_context_ref() failed!\n" );
+ return true;
+ }
+
+ return false;
+}
+
+int
+main( int argc, char *argv[] )
+{
+ DFBResult ret;
+
+ /* Initialize DirectFB including command line parsing. */
+ ret = DirectFBInit( &argc, &argv );
+ if (ret) {
+ DirectFBError( "DirectFBInit() failed", ret );
+ return -1;
+ }
+
+ /* Parse the command line. */
+ if (!parse_command_line( argc, argv ))
+ return -2;
+
+ /* Create the super interface. */
+ ret = DirectFBCreate( &dfb );
+ if (ret) {
+ DirectFBError( "DirectFBCreate() failed", ret );
+ return -3;
+ }
+
+ if (!unique_wm_running()) {
+ D_ERROR( "UniQuE/Test: This session doesn't run UniQuE!\n" );
+ dfb->Release( dfb );
+ return EXIT_FAILURE;
+ }
+
+ unique_wm_enum_contexts( context_callback, NULL );
+
+ if (!context) {
+ D_ERROR( "UniQuE/Test: No context available!\n" );
+ dfb->Release( dfb );
+ return EXIT_FAILURE;
+ }
+
+ /* Set the background according to the users wishes. */
+ if (color)
+ set_color();
+
+ unique_context_unref( context );
+
+ /* Release the super interface. */
+ dfb->Release( dfb );
+
+ return EXIT_SUCCESS;
+}
+
+/*****************************************************************************/
+
+static void
+print_usage( const char *prg_name )
+{
+ fprintf( stderr,
+ "\n"
+ "UniQuE Test Application (version %s)\n"
+ "\n"
+ "Usage: %s [options] <color>\n"
+ "\n"
+ "Options:\n"
+ " -c, --color Set <color> in AARRGGBB format (hexadecimal)\n"
+ " -h, --help Show this help message\n"
+ " -v, --version Print version information\n"
+ "\n",
+ DIRECTFB_VERSION, prg_name );
+}
+
+static DFBBoolean
+parse_command_line( int argc, char *argv[] )
+{
+ int n;
+ const char *prg_name = strrchr( argv[0], '/' );
+
+ if (prg_name)
+ prg_name++;
+ else
+ prg_name = argv[0];
+
+ for (n = 1; n < argc; n++) {
+ const char *a = argv[n];
+
+ if (*a != '-') {
+ if (!filename) {
+ filename = a;
+ continue;
+ }
+ else {
+ print_usage( prg_name );
+ return DFB_FALSE;
+ }
+ }
+ if (strcmp (a, "-h") == 0 || strcmp (a, "--help") == 0) {
+ print_usage( prg_name );
+ return DFB_FALSE;
+ }
+ if (strcmp (a, "-v") == 0 || strcmp (a, "--version") == 0) {
+ fprintf (stderr, "dfbg version %s\n", DIRECTFB_VERSION);
+ return DFB_FALSE;
+ }
+ if (strcmp (a, "-c") == 0 || strcmp (a, "--color") == 0) {
+ color = DFB_TRUE;
+ continue;
+ }
+ }
+
+ if (!filename) {
+ print_usage( prg_name );
+ return DFB_FALSE;
+ }
+
+ return DFB_TRUE;
+}
+
+static void
+set_color( void )
+{
+ DFBResult ret;
+ char *error;
+ u32 argb;
+ DFBColor color;
+
+ if (*filename == '#')
+ filename++;
+
+ argb = strtoul( filename, &error, 16 );
+
+ if (*error) {
+ fprintf( stderr, "Invalid characters in color string: '%s'\n", error );
+ return;
+ }
+
+ color.a = (argb & 0xFF000000) >> 24;
+ color.r = (argb & 0xFF0000) >> 16;
+ color.g = (argb & 0xFF00) >> 8;
+ color.b = (argb & 0xFF);
+
+ ret = unique_context_set_color( context, &color );
+ if (ret)
+ D_DERROR( ret, "UniQuE/Test: unique_context_set_color() failed!\n" );
+}
+
diff --git a/Source/DirectFB/wm/unique/test_foo.c b/Source/DirectFB/wm/unique/test_foo.c
new file mode 100755
index 0000000..02bfc56
--- /dev/null
+++ b/Source/DirectFB/wm/unique/test_foo.c
@@ -0,0 +1,288 @@
+/*
+ (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 file is subject to the terms and conditions of the MIT License:
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+
+#include <core/layer_context.h>
+#include <core/layers_internal.h>
+
+#include <unique/context.h>
+#include <unique/input_channel.h>
+#include <unique/internal.h>
+#include <unique/uniquewm.h>
+
+D_DEBUG_DOMAIN( UniQuE_TestFoo, "UniQuE/TestFoo", "UniQuE's Test Foo Application" );
+
+/*****************************************************************************/
+
+static IDirectFB *dfb = NULL;
+
+/*****************************************************************************/
+
+static DFBBoolean parse_command_line( int argc, char *argv[] );
+
+/*****************************************************************************/
+
+static UniqueContext *context;
+
+static bool
+context_callback( FusionObjectPool *pool,
+ FusionObject *object,
+ void *ctx )
+{
+ if (object->state != FOS_ACTIVE)
+ return true;
+
+ context = (UniqueContext*) object;
+ if (unique_context_ref( context )) {
+ D_ERROR( "UniQuE/Test: unique_context_ref() failed!\n" );
+ return true;
+ }
+
+ return false;
+}
+
+static void
+dispatch_motion( UniqueWindow *window,
+ const UniqueInputPointerEvent *event )
+{
+ D_MAGIC_ASSERT( window, UniqueWindow );
+ D_ASSERT( event != NULL );
+
+ if (event->buttons) {
+ CoreWindowConfig config;
+
+ unique_window_get_config( window, &config );
+
+ config.bounds.x -= window->foo_motion.x - event->x;
+ config.bounds.y -= window->foo_motion.y - event->y;
+
+ unique_window_set_config( window, &config, CWCF_POSITION );
+ }
+
+ window->foo_motion.x = event->x;
+ window->foo_motion.y = event->y;
+}
+
+static void
+dispatch_button( UniqueWindow *window,
+ const UniqueInputPointerEvent *event )
+{
+ D_MAGIC_ASSERT( window, UniqueWindow );
+ D_ASSERT( event != NULL );
+
+ if (event->press)
+ unique_window_restack( window, NULL, 1 );
+}
+
+static ReactionResult
+foo_channel_listener( const void *msg_data,
+ void *ctx )
+{
+ const UniqueInputEvent *event = msg_data;
+ UniqueContext *context = ctx;
+ CoreLayerRegion *region;
+ StretRegion *stret;
+ WMShared *shared;
+ static UniqueWindow *window;
+
+ (void) context;
+
+ D_ASSERT( event != NULL );
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_DEBUG_AT( UniQuE_TestFoo, "foo_channel_listener( %p, %p )\n", event, context );
+
+ region = context->region;
+ D_ASSERT( region != NULL );
+ D_ASSERT( region->context != NULL );
+
+ shared = context->shared;
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ dfb_layer_context_lock( region->context );
+
+ switch (event->type) {
+ case UIET_MOTION:
+ case UIET_BUTTON:
+ /* FIXME: This is a workaround because of the global input channel used for all windows. */
+ stret = stret_region_at( context->root, event->pointer.x, event->pointer.y,
+ SRF_INPUT, shared->region_classes[URCI_FOO] );
+ if (stret)
+ window = stret->data;
+ else if (event->type == UIET_BUTTON && !event->pointer.buttons)
+ window = NULL;
+
+ if (window) {
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ if (event->type == UIET_MOTION)
+ dispatch_motion( window, &event->pointer );
+ else
+ dispatch_button( window, &event->pointer );
+ }
+ break;
+
+ case UIET_WHEEL:
+ break;
+
+ case UIET_KEY:
+ break;
+
+ case UIET_CHANNEL:
+ break;
+
+ default:
+ D_ONCE( "unknown event type" );
+ break;
+ }
+
+ dfb_layer_context_unlock( region->context );
+
+ return RS_OK;
+}
+
+
+int
+main( int argc, char *argv[] )
+{
+ DFBResult ret;
+ Reaction reaction;
+
+ /* Initialize DirectFB including command line parsing. */
+ ret = DirectFBInit( &argc, &argv );
+ if (ret) {
+ DirectFBError( "DirectFBInit() failed", ret );
+ return -1;
+ }
+
+ /* Parse the command line. */
+ if (!parse_command_line( argc, argv ))
+ return -2;
+
+ /* Create the super interface. */
+ ret = DirectFBCreate( &dfb );
+ if (ret) {
+ DirectFBError( "DirectFBCreate() failed", ret );
+ return -3;
+ }
+
+ if (!unique_wm_running()) {
+ D_ERROR( "UniQuE/Test: This session doesn't run UniQuE!\n" );
+ dfb->Release( dfb );
+ return EXIT_FAILURE;
+ }
+
+ unique_wm_enum_contexts( context_callback, NULL );
+
+ if (!context) {
+ D_ERROR( "UniQuE/Test: No context available!\n" );
+ dfb->Release( dfb );
+ return EXIT_FAILURE;
+ }
+
+
+ unique_input_channel_attach( context->foo_channel, foo_channel_listener, context, &reaction );
+
+ pause();
+
+ unique_input_channel_detach( context->foo_channel, &reaction );
+
+ unique_context_unref( context );
+
+ /* Release the super interface. */
+ dfb->Release( dfb );
+
+ return EXIT_SUCCESS;
+}
+
+/*****************************************************************************/
+
+static void
+print_usage( const char *prg_name )
+{
+ fprintf( stderr,
+ "\n"
+ "UniQuE Foo Test (version %s)\n"
+ "\n"
+ "Usage: %s [options]\n"
+ "\n"
+ "Options:\n"
+ " -h, --help Show this help message\n"
+ " -v, --version Print version information\n"
+ "\n",
+ DIRECTFB_VERSION, prg_name );
+}
+
+static DFBBoolean
+parse_command_line( int argc, char *argv[] )
+{
+ int n;
+ const char *prg_name = strrchr( argv[0], '/' );
+
+ if (prg_name)
+ prg_name++;
+ else
+ prg_name = argv[0];
+
+ for (n = 1; n < argc; n++) {
+ const char *a = argv[n];
+
+ if (*a != '-') {
+ print_usage( prg_name );
+ return DFB_FALSE;
+ }
+ if (strcmp (a, "-h") == 0 || strcmp (a, "--help") == 0) {
+ print_usage( prg_name );
+ return DFB_FALSE;
+ }
+ if (strcmp (a, "-v") == 0 || strcmp (a, "--version") == 0) {
+ fprintf (stderr, "dfbg version %s\n", DIRECTFB_VERSION);
+ return DFB_FALSE;
+ }
+ }
+
+ return DFB_TRUE;
+}
+
diff --git a/Source/DirectFB/wm/unique/types.h b/Source/DirectFB/wm/unique/types.h
new file mode 100755
index 0000000..221ae6b
--- /dev/null
+++ b/Source/DirectFB/wm/unique/types.h
@@ -0,0 +1,53 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __UNIQUE__TYPES_H__
+#define __UNIQUE__TYPES_H__
+
+
+typedef struct __UniQuE_UniqueContext UniqueContext;
+typedef struct __UniQuE_UniqueDecoration UniqueDecoration;
+typedef struct __UniQuE_UniqueDecorationItem UniqueDecorationItem;
+typedef struct __UniQuE_UniqueDevice UniqueDevice;
+typedef struct __UniQuE_UniqueLayout UniqueLayout;
+typedef struct __UniQuE_UniqueWindow UniqueWindow;
+
+typedef struct __UniQuE_UniqueInputChannel UniqueInputChannel;
+typedef union __UniQuE_UniqueInputEvent UniqueInputEvent;
+typedef struct __UniQuE_UniqueInputFilter UniqueInputFilter;
+typedef struct __UniQuE_UniqueInputSwitch UniqueInputSwitch;
+
+
+typedef struct __UniQuE_StretRegion StretRegion;
+
+
+typedef struct __UniQuE_WMData WMData;
+typedef struct __UniQuE_WMShared WMShared;
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/unique.c b/Source/DirectFB/wm/unique/unique.c
new file mode 100755
index 0000000..bb0c5ec
--- /dev/null
+++ b/Source/DirectFB/wm/unique/unique.c
@@ -0,0 +1,1064 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/trace.h>
+#include <direct/util.h>
+
+#include <fusion/reactor.h>
+#include <fusion/shmalloc.h>
+#include <fusion/vector.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/gfxcard.h>
+#include <core/layer_context.h>
+#include <core/layer_region.h>
+#include <core/layers_internal.h>
+#include <core/surface.h>
+#include <core/palette.h>
+#include <core/windows.h>
+#include <core/windows_internal.h>
+#include <core/windowstack.h>
+#include <core/wm.h>
+
+#include <gfx/util.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+#include <core/wm_module.h>
+
+#include <unique/context.h>
+#include <unique/stret.h>
+#include <unique/internal.h>
+
+
+D_DEBUG_DOMAIN( WM_Unique, "WM/UniQuE", "UniQuE - Universal Quark Emitter" );
+
+
+DFB_WINDOW_MANAGER( unique );
+
+/**************************************************************************************************/
+
+typedef struct {
+ int magic;
+
+ CoreWindowStack *stack;
+
+ UniqueContext *context;
+
+ GlobalReaction context_reaction;
+} StackData;
+
+typedef struct {
+ int magic;
+
+ UniqueContext *context;
+
+ UniqueWindow *window;
+
+ GlobalReaction window_reaction;
+} WindowData;
+
+/**************************************************************************************************/
+
+static ReactionResult
+context_notify( WMData *data,
+ const UniqueContextNotification *notification,
+ void *ctx )
+{
+ StackData *stack_data = ctx;
+
+ D_ASSERT( data != NULL );
+
+ D_ASSERT( notification != NULL );
+ D_ASSERT( notification->context != NULL );
+
+ D_MAGIC_ASSERT( stack_data, StackData );
+
+ D_ASSERT( notification->context == stack_data->context );
+
+ D_MAGIC_ASSERT( stack_data->context, UniqueContext );
+
+ D_ASSERT( ! D_FLAGS_IS_SET( notification->flags, ~UCNF_ALL ) );
+
+ D_DEBUG_AT( WM_Unique, "context_notify( wm_data %p, stack_data %p )\n", data, stack_data );
+
+ if (notification->flags & UCNF_DESTROYED) {
+ D_DEBUG_AT( WM_Unique, " -> context destroyed.\n" );
+
+ if (notification->context == stack_data->context)
+ stack_data->context = NULL;
+
+ return RS_REMOVE;
+ }
+
+ return RS_OK;
+}
+
+static ReactionResult
+window_notify( WMData *data,
+ const UniqueWindowNotification *notification,
+ void *ctx )
+{
+ WindowData *window_data = ctx;
+
+ D_ASSERT( data != NULL );
+
+ D_ASSERT( notification != NULL );
+ D_ASSERT( notification->window != NULL );
+
+ D_MAGIC_ASSERT( window_data, WindowData );
+
+ D_ASSERT( notification->window == window_data->window );
+
+ D_MAGIC_ASSERT( window_data->window, UniqueWindow );
+
+ D_ASSERT( ! D_FLAGS_IS_SET( notification->flags, ~UWNF_ALL ) );
+
+ D_DEBUG_AT( WM_Unique, "window_notify( wm_data %p, window_data %p )\n", data, window_data );
+
+ if (notification->flags & UWNF_DESTROYED) {
+ D_DEBUG_AT( WM_Unique, " -> window destroyed.\n" );
+
+ window_data->window = NULL;
+
+ return RS_REMOVE;
+ }
+
+ return RS_OK;
+}
+
+/**************************************************************************************************/
+
+static void
+initialize_data( CoreDFB *core, WMData *data, WMShared *shared )
+{
+ D_ASSERT( data != NULL );
+
+ /* Initialize local data. */
+ data->core = core;
+ data->world = dfb_core_world( core );
+ data->shared = shared;
+ data->module_abi = UNIQUE_WM_ABI_VERSION;
+
+ /* Set module callbacks. */
+ data->context_notify = context_notify;
+ data->window_notify = window_notify;
+}
+
+/**************************************************************************************************/
+
+static void
+wm_get_info( CoreWMInfo *info )
+{
+ info->version.major = 0;
+ info->version.minor = 4;
+ info->version.binary = UNIQUE_WM_ABI_VERSION;
+
+ snprintf( info->name, DFB_CORE_WM_INFO_NAME_LENGTH, "UniQuE" );
+ snprintf( info->vendor, DFB_CORE_WM_INFO_VENDOR_LENGTH, "Denis Oliver Kropp" );
+
+ info->wm_data_size = sizeof(WMData);
+ info->wm_shared_size = sizeof(WMShared);
+ info->stack_data_size = sizeof(StackData);
+ info->window_data_size = sizeof(WindowData);
+}
+
+static DFBResult
+wm_initialize( CoreDFB *core, void *wm_data, void *shared_data )
+{
+ WMData *data = wm_data;
+ WMShared *shared = shared_data;
+
+ D_DEBUG_AT( WM_Unique, "wm_initialize()\n" );
+
+ initialize_data( core, data, shared );
+
+ D_MAGIC_SET( shared, WMShared );
+
+ return unique_wm_module_init( core, data, shared, true );
+}
+
+static DFBResult
+wm_join( CoreDFB *core, void *wm_data, void *shared_data )
+{
+ WMData *data = wm_data;
+ WMShared *shared = shared_data;
+
+ D_DEBUG_AT( WM_Unique, "wm_join()\n" );
+
+ initialize_data( core, data, shared );
+
+ return unique_wm_module_init( core, data, shared, false );
+}
+
+static DFBResult
+wm_shutdown( bool emergency, void *wm_data, void *shared_data )
+{
+ WMShared *shared = shared_data;
+
+ (void) shared;
+
+ D_DEBUG_AT( WM_Unique, "wm_shutdown()\n" );
+
+ unique_wm_module_deinit( wm_data, shared_data, true, emergency );
+
+ D_MAGIC_CLEAR( shared );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_leave( bool emergency, void *wm_data, void *shared_data )
+{
+ D_DEBUG_AT( WM_Unique, "wm_leave()\n" );
+
+ unique_wm_module_deinit( wm_data, shared_data, false, emergency );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_suspend( void *wm_data, void *shared_data )
+{
+ D_DEBUG_AT( WM_Unique, "wm_suspend()\n" );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_resume( void *wm_data, void *shared_data )
+{
+ D_DEBUG_AT( WM_Unique, "wm_resume()\n" );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_post_init( void *wm_data, void *shared_data )
+{
+ D_DEBUG_AT( WM_Unique, "wm_post_init()\n" );
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+wm_init_stack( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data )
+{
+ DFBResult ret;
+ StackData *data = stack_data;
+ WMData *wmdata = wm_data;
+ CoreLayerContext *context;
+ CoreLayerRegion *region;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( stack->context != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ context = stack->context;
+
+ D_ASSERT( context != NULL );
+
+ ret = dfb_layer_context_get_primary_region( context, true, &region );
+ if (ret) {
+ D_DERROR( ret, "WM/UniQuE: Could not get the primary region!\n" );
+ return ret;
+ }
+
+ /* Create the unique context. */
+ ret = unique_context_create( wmdata->core, stack, region, context->layer_id,
+ wmdata->shared, &data->context );
+ dfb_layer_region_unref( region );
+ if (ret) {
+ D_DERROR( ret, "WM/UniQuE: Could not create the context!\n" );
+ return ret;
+ }
+
+ /* Attach the global context listener. */
+ ret = unique_context_attach_global( data->context,
+ UNIQUE_WM_MODULE_CONTEXT_LISTENER,
+ data, &data->context_reaction );
+ if (ret) {
+ unique_context_unref( data->context );
+ D_DERROR( ret, "WM/UniQuE: Could not attach global context listener!\n" );
+ return ret;
+ }
+
+ /* Inherit all local references from the layer context. */
+ ret = unique_context_inherit( data->context, context );
+ unique_context_unref( data->context );
+ if (ret) {
+ unique_context_detach_global( data->context, &data->context_reaction );
+ D_DERROR( ret, "WM/UniQuE: Could not inherit from layer context!\n" );
+ return ret;
+ }
+
+
+
+ data->stack = stack;
+
+ D_MAGIC_SET( data, StackData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_close_stack( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data )
+{
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ D_ASSUME( data->context == NULL );
+
+ if (data->context)
+ unique_context_detach_global( data->context, &data->context_reaction );
+
+ D_MAGIC_CLEAR( data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_set_active( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ bool active )
+{
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ D_DEBUG_AT( WM_Unique, "%s( stack %p, wm_data %p, stack_data %p, %sactive )\n",
+ __FUNCTION__, stack, wm_data, stack_data, active ? "" : "in" );
+
+ if (!data->context) {
+ D_ASSERT( !active );
+ return DFB_OK;
+ }
+
+ return unique_context_set_active( data->context, active );
+}
+
+static DFBResult
+wm_resize_stack( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ int width,
+ int height )
+{
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ if (!data->context)
+ return DFB_DESTROYED;
+
+ return unique_context_resize( data->context, width, height );
+}
+
+static DFBResult
+wm_process_input( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ const DFBInputEvent *event )
+{
+ StackData *data = stack_data;
+
+ (void) data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( event != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_flush_keys( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data )
+{
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ if (!data->context)
+ return DFB_DESTROYED;
+
+ return unique_context_flush_keys( data->context );
+}
+
+static DFBResult
+wm_window_at( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ int x,
+ int y,
+ CoreWindow **ret_window )
+{
+ DFBResult ret;
+ UniqueWindow *window;
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( ret_window != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ if (!data->context)
+ return DFB_DESTROYED;
+
+ ret = unique_context_window_at( data->context, x, y, &window );
+ if (ret)
+ return ret;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ *ret_window = window->window;
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_window_lookup( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ DFBWindowID window_id,
+ CoreWindow **ret_window )
+{
+ DFBResult ret;
+ UniqueWindow *window;
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( ret_window != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ if (!data->context)
+ return DFB_DESTROYED;
+
+ ret = unique_context_lookup_window( data->context, window_id, &window );
+ if (ret)
+ return ret;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ *ret_window = window->window;
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_enum_windows( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWMWindowCallback callback,
+ void *callback_ctx )
+{
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( callback != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ if (!data->context)
+ return DFB_DESTROYED;
+
+ return unique_context_enum_windows( data->context, callback, callback_ctx );
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+wm_get_insets( CoreWindowStack *stack,
+ CoreWindow *window,
+ DFBInsets *insets )
+{
+ if( insets ) {
+ insets->l=0;
+ insets->t=0;
+ insets->r=0;
+ insets->b=0;
+ }
+ return DFB_OK;
+}
+
+static DFBResult
+wm_preconfigure_window( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data )
+{
+ return DFB_OK;
+}
+
+static DFBResult
+wm_set_window_property( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void *value,
+ void **ret_old_value )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( key != NULL );
+
+ fusion_object_set_property((FusionObject*)window,
+ key,value,ret_old_value);
+ return DFB_OK;
+}
+
+static DFBResult
+wm_get_window_property( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void **ret_value )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( key != NULL );
+ D_ASSERT( ret_value != NULL );
+
+ *ret_value=fusion_object_get_property((FusionObject*)window,key);
+ return DFB_OK;
+}
+
+
+static DFBResult
+wm_remove_window_property( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data,
+ const char *key,
+ void **ret_value )
+{
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( key != NULL );
+
+ fusion_object_remove_property((FusionObject*)window,key,ret_value);
+ return DFB_OK;
+}
+
+static DFBResult
+wm_add_window( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data )
+{
+ DFBResult ret;
+ StackData *sdata = stack_data;
+ WindowData *data = window_data;
+ WMData *wmdata = wm_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+
+ D_MAGIC_ASSERT( sdata, StackData );
+ D_MAGIC_ASSERT( sdata->context, UniqueContext );
+
+ data->context = sdata->context;
+
+ /* Create the unique window. */
+ ret = unique_window_create( wmdata->core, window, data->context,
+ window->caps, &window->config, &data->window );
+ if (ret) {
+ D_DERROR( ret, "WM/UniQuE: Could not create window!\n" );
+ return ret;
+ }
+
+ /* Attach the global window listener. */
+ ret = unique_window_attach_global( data->window,
+ UNIQUE_WM_MODULE_WINDOW_LISTENER,
+ data, &data->window_reaction );
+ if (ret) {
+ unique_window_unref( data->window );
+ D_DERROR( ret, "WM/UniQuE: Could not attach global window listener!\n" );
+ return ret;
+ }
+
+ /* Inherit all local references from the layer window. */
+ ret = unique_window_inherit( data->window, window );
+ unique_window_unref( data->window );
+ if (ret) {
+ unique_window_detach_global( data->window, &data->window_reaction );
+ D_DERROR( ret, "WM/UniQuE: Could not inherit from core window!\n" );
+ return ret;
+ }
+
+ unique_window_get_config( data->window, &window->config );
+
+
+ D_MAGIC_SET( data, WindowData );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_remove_window( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreWindow *window,
+ void *window_data )
+{
+ WindowData *data = window_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+ D_ASSERT( window != NULL );
+ D_ASSERT( window_data != NULL );
+
+ D_MAGIC_ASSERT( data, WindowData );
+
+// D_ASSUME( data->window == NULL );
+
+ if (data->window)
+ unique_window_detach_global( data->window, &data->window_reaction );
+
+ D_MAGIC_CLEAR( data );
+
+ return DFB_OK;
+}
+
+static DFBResult
+wm_set_window_config( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const CoreWindowConfig *config,
+ CoreWindowConfigFlags flags )
+{
+ DFBResult ret;
+ WindowData *data = window_data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( config != NULL );
+
+ D_MAGIC_ASSERT( data, WindowData );
+
+ if (!data->window)
+ return DFB_DESTROYED;
+
+ ret = unique_window_set_config( data->window, config, flags );
+
+ unique_window_get_config( data->window, &window->config );
+
+ return ret;
+}
+
+static DFBResult
+wm_restack_window( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWindow *relative,
+ void *relative_data,
+ int relation )
+{
+ WindowData *data = window_data;
+ WindowData *rel_data = relative_data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+
+ D_MAGIC_ASSERT( data, WindowData );
+
+ D_ASSERT( relative == NULL || relative_data != NULL );
+
+ D_ASSERT( relative == NULL || relative == window || relation != 0);
+
+ if (!data->window)
+ return DFB_DESTROYED;
+
+ return unique_window_restack( data->window, rel_data ? rel_data->window : NULL, relation );
+}
+
+static DFBResult
+wm_grab( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWMGrab *grab )
+{
+ WindowData *data = window_data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( grab != NULL );
+
+ D_MAGIC_ASSERT( data, WindowData );
+
+ if (!data->window)
+ return DFB_DESTROYED;
+
+ return unique_window_grab( data->window, grab );
+}
+
+static DFBResult
+wm_ungrab( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ CoreWMGrab *grab )
+{
+ WindowData *data = window_data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+ D_ASSERT( grab != NULL );
+
+ D_MAGIC_ASSERT( data, WindowData );
+
+ if (!data->window)
+ return DFB_DESTROYED;
+
+ return unique_window_ungrab( data->window, grab );
+}
+
+static DFBResult
+wm_request_focus( CoreWindow *window,
+ void *wm_data,
+ void *window_data )
+{
+ WindowData *data = window_data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+
+ D_MAGIC_ASSERT( data, WindowData );
+
+ if (!data->window)
+ return DFB_DESTROYED;
+
+ return unique_window_request_focus( data->window );
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+wm_update_stack( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags )
+{
+ StackData *data = stack_data;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ DFB_REGION_ASSERT( region );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ if (!data->context)
+ return DFB_DESTROYED;
+
+ return unique_context_update( data->context, region, 1, flags );
+}
+
+static DFBResult
+wm_update_window( CoreWindow *window,
+ void *wm_data,
+ void *window_data,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags )
+{
+ WindowData *data = window_data;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( window_data != NULL );
+
+ DFB_REGION_ASSERT_IF( region );
+
+ D_MAGIC_ASSERT( data, WindowData );
+
+ if (!data->window)
+ return DFB_DESTROYED;
+
+ return unique_window_update( data->window, region, flags );
+}
+
+/**************************************************************************************************/
+
+/* HACK: implementation dumped in here for now, will move into context */
+static DFBResult
+wm_update_cursor( CoreWindowStack *stack,
+ void *wm_data,
+ void *stack_data,
+ CoreCursorUpdateFlags flags )
+{
+ DFBResult ret;
+ DFBRegion old_region;
+ WMData *wmdata = wm_data;
+ StackData *data = stack_data;
+ bool restored = false;
+ CoreLayer *layer;
+ CoreLayerRegion *region;
+ CardState *state;
+ CoreSurface *surface;
+ UniqueContext *context;
+
+ D_ASSERT( stack != NULL );
+ D_ASSERT( stack->context != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( stack_data != NULL );
+
+ D_MAGIC_ASSERT( data, StackData );
+
+ context = data->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ /* Optimize case of invisible cursor moving. */
+ if (!(flags & ~(CCUF_POSITION | CCUF_SHAPE)) && (!stack->cursor.opacity || !stack->cursor.enabled)) {
+ context->cursor_bs_valid = false;
+ return DFB_OK;
+ }
+
+ layer = dfb_layer_at( context->layer_id );
+ state = &layer->state;
+ region = context->region;
+ surface = context->surface;
+
+ D_ASSERT( region != NULL );
+ D_ASSERT( surface != NULL );
+
+ if (flags & CCUF_ENABLE) {
+ CoreSurface *cursor_bs;
+ DFBSurfaceCapabilities caps = DSCAPS_NONE;
+
+ dfb_surface_caps_apply_policy( stack->cursor.policy, &caps );
+
+ D_ASSERT( context->cursor_bs == NULL );
+
+ /* Create the cursor backing store surface. */
+ ret = dfb_surface_create_simple( wmdata->core, stack->cursor.size.w, stack->cursor.size.h,
+ region->config.format, caps, CSTF_SHARED | CSTF_CURSOR,
+ 0, /* FIXME: no shared cursor objects, no cursor id */
+ NULL, &cursor_bs );
+ if (ret) {
+ D_ERROR( "WM/Default: Failed creating backing store for cursor!\n" );
+ return ret;
+ }
+
+ ret = dfb_surface_globalize( cursor_bs );
+ D_ASSERT( ret == DFB_OK );
+
+ /* Ensure valid back buffer for now.
+ * FIXME: Keep a flag to know when back/front have been swapped and need a sync.
+ */
+ switch (region->config.buffermode) {
+ case DLBM_BACKVIDEO:
+ case DLBM_TRIPLE:
+ dfb_gfx_copy( surface, surface, NULL );
+ break;
+
+ default:
+ break;
+ }
+
+ context->cursor_bs = cursor_bs;
+ }
+ else {
+ D_ASSERT( context->cursor_bs != NULL );
+
+ /* restore region under cursor */
+ if (context->cursor_drawn) {
+ DFBRectangle rect = { 0, 0,
+ context->cursor_region.x2 - context->cursor_region.x1 + 1,
+ context->cursor_region.y2 - context->cursor_region.y1 + 1 };
+
+ D_ASSERT( stack->cursor.opacity || (flags & CCUF_OPACITY) );
+ D_ASSERT( context->cursor_bs_valid );
+
+ dfb_gfx_copy_to( context->cursor_bs, surface, &rect,
+ context->cursor_region.x1, context->cursor_region.y1, false );
+
+ context->cursor_drawn = false;
+
+ old_region = context->cursor_region;
+ restored = true;
+ }
+
+ if (flags & CCUF_SIZE) {
+ ret = dfb_surface_reformat( context->cursor_bs,
+ stack->cursor.size.w, stack->cursor.size.h,
+ context->cursor_bs->config.format );
+ if (ret) {
+ D_ERROR( "WM/Default: Failed resizing backing store for cursor!\n" );
+ return ret;
+ }
+ }
+ }
+
+ if (flags & (CCUF_ENABLE | CCUF_POSITION | CCUF_SIZE | CCUF_OPACITY)) {
+ context->cursor_bs_valid = false;
+
+ context->cursor_region.x1 = stack->cursor.x - stack->cursor.hot.x;
+ context->cursor_region.y1 = stack->cursor.y - stack->cursor.hot.y;
+ context->cursor_region.x2 = context->cursor_region.x1 + stack->cursor.size.w - 1;
+ context->cursor_region.y2 = context->cursor_region.y1 + stack->cursor.size.h - 1;
+
+ if (!dfb_region_intersect( &context->cursor_region, 0, 0, stack->width - 1, stack->height - 1 )) {
+ D_BUG( "invalid cursor region" );
+ return DFB_BUG;
+ }
+ }
+
+ D_ASSERT( context->cursor_bs != NULL );
+
+ if (flags & CCUF_DISABLE) {
+ dfb_surface_unlink( &context->cursor_bs );
+ }
+ else if (stack->cursor.opacity) {
+ /* backup region under cursor */
+ if (!context->cursor_bs_valid) {
+ DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &context->cursor_region );
+
+ D_ASSERT( !context->cursor_drawn );
+
+ /* FIXME: this requires using blitted flipping all the time,
+ but fixing it seems impossible, for now DSFLIP_BLIT is forced
+ in repaint_stack() when the cursor is enabled. */
+ dfb_gfx_copy_to( surface, context->cursor_bs, &rect, 0, 0, true );
+
+ context->cursor_bs_valid = true;
+ }
+
+ /* Set destination. */
+ state->destination = surface;
+ state->modified |= SMF_DESTINATION;
+
+ /* Set clipping region. */
+ dfb_state_set_clip( state, &context->cursor_region );
+
+ /* draw cursor */
+ unique_draw_cursor( stack, context, state, &context->cursor_region );
+
+ /* Reset destination. */
+ state->destination = NULL;
+ state->modified |= SMF_DESTINATION;
+
+ context->cursor_drawn = true;
+
+ if (restored) {
+ if (dfb_region_region_intersects( &old_region, &context->cursor_region ))
+ dfb_region_region_union( &old_region, &context->cursor_region );
+ else
+ dfb_layer_region_flip_update( region, &context->cursor_region, DSFLIP_BLIT );
+
+ dfb_layer_region_flip_update( region, &old_region, DSFLIP_BLIT );
+ }
+ else
+ dfb_layer_region_flip_update( region, &context->cursor_region, DSFLIP_BLIT );
+ }
+ else if (restored)
+ dfb_layer_region_flip_update( region, &old_region, DSFLIP_BLIT );
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/wm/unique/uniquewm.c b/Source/DirectFB/wm/unique/uniquewm.c
new file mode 100755
index 0000000..8247556
--- /dev/null
+++ b/Source/DirectFB/wm/unique/uniquewm.c
@@ -0,0 +1,451 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+
+#include <core/input.h>
+#include <core/surface.h>
+#include <core/surface_buffer.h>
+
+#include <unique/context.h>
+#include <unique/decoration.h>
+#include <unique/internal.h>
+#include <unique/uniquewm.h>
+
+#include <unique/data/foo.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_WM, "UniQuE/WM", "UniQuE - Universal Quark Emitter" );
+
+/**************************************************************************************************/
+
+static CoreDFB *dfb_core;
+static WMData *wm_data;
+static WMShared *wm_shared;
+
+/**************************************************************************************************/
+
+static const StretRegionClass *region_classes[_URCI_NUM] = {
+ &unique_root_region_class,
+ &unique_frame_region_class,
+ &unique_window_region_class,
+ &unique_foo_region_class
+};
+
+static DFBResult register_region_classes ( WMShared *shared,
+ bool master );
+
+static DFBResult unregister_region_classes( WMShared *shared );
+
+/**************************************************************************************************/
+
+static const UniqueDeviceClass *device_classes[_UDCI_NUM] = {
+ &unique_pointer_device_class,
+ &unique_wheel_device_class,
+ &unique_keyboard_device_class
+};
+
+static DFBResult register_device_classes ( WMShared *shared,
+ bool master );
+
+static DFBResult unregister_device_classes( WMShared *shared );
+
+/**************************************************************************************************/
+
+static DFBResult
+load_foo( CoreDFB *core, WMShared *shared )
+{
+ DFBResult ret;
+
+ D_ASSERT( core != NULL );
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ ret = dfb_surface_create_simple( core, foo_desc.width, foo_desc.height, foo_desc.pixelformat,
+ DSCAPS_NONE, CSTF_SHARED, 0, NULL, &shared->foo_surface );
+ if (ret) {
+ D_DERROR( ret, "UniQuE/WM: Could not create %dx%d surface for border tiles!\n",
+ foo_desc.width, foo_desc.height );
+ return ret;
+ }
+
+ ret = dfb_surface_write_buffer( shared->foo_surface, CSBR_BACK,
+ foo_desc.preallocated[0].data, foo_desc.preallocated[0].pitch, NULL );
+ if (ret)
+ D_DERROR( ret, "UniQuE/WM: Could not write to %dx%d surface for border tiles!\n",
+ foo_desc.width, foo_desc.height );
+
+ dfb_surface_globalize( shared->foo_surface );
+
+ return DFB_OK;
+}
+
+static void
+unload_foo( WMShared *shared )
+{
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ dfb_surface_unlink( &shared->foo_surface );
+}
+
+/**************************************************************************************************/
+
+DFBResult
+unique_wm_module_init( CoreDFB *core, WMData *data, WMShared *shared, bool master )
+{
+ DFBResult ret;
+
+ D_DEBUG_AT( UniQuE_WM, "unique_wm_init( core %p, data %p, shared %p, %s )\n",
+ core, data, shared, master ? "master" : "slave" );
+
+ D_ASSERT( core != NULL );
+ D_ASSERT( data != NULL );
+ D_ASSERT( data->context_notify != NULL );
+ D_ASSERT( data->window_notify != NULL );
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ D_ASSERT( dfb_core == NULL );
+ D_ASSERT( wm_data == NULL );
+ D_ASSERT( wm_shared == NULL );
+
+ if (data->module_abi != UNIQUE_WM_ABI_VERSION) {
+ D_ERROR( "UniQuE/WM: Module ABI version (%d) does not match %d!\n",
+ data->module_abi, UNIQUE_WM_ABI_VERSION );
+ return DFB_VERSIONMISMATCH;
+ }
+
+ ret = register_region_classes( shared, master );
+ if (ret)
+ return ret;
+
+ ret = register_device_classes( shared, master );
+ if (ret)
+ goto error_device;
+
+ if (master) {
+ int i;
+
+ ret = load_foo( core, shared );
+ if (ret)
+ goto error_foo;
+
+ ret = dfb_input_add_global( _unique_device_listener, &shared->device_listener );
+ if (ret)
+ goto error_global;
+
+ shared->context_pool = unique_context_pool_create( data->world );
+ shared->decoration_pool = unique_decoration_pool_create( data->world );
+ shared->window_pool = unique_window_pool_create( data->world );
+
+ shared->insets.l = foo[UFI_W].rect.w;
+ shared->insets.t = foo[UFI_N].rect.h;
+ shared->insets.r = foo[UFI_E].rect.w;
+ shared->insets.b = foo[UFI_S].rect.h;
+
+ for (i=0; i<8; i++)
+ shared->foo_rects[i] = foo[i].rect;
+ }
+ else
+ dfb_input_set_global( _unique_device_listener, shared->device_listener );
+
+ dfb_core = core;
+ wm_data = data;
+ wm_shared = shared;
+
+ return DFB_OK;
+
+error_global:
+ unload_foo( shared );
+
+error_foo:
+ unregister_device_classes( shared );
+
+error_device:
+ unregister_region_classes( shared );
+
+ return ret;
+}
+
+void
+unique_wm_module_deinit( WMData *data, WMShared *shared, bool master, bool emergency )
+{
+ D_DEBUG_AT( UniQuE_WM, "unique_wm_deinit( %s%s ) <- core %p, data %p, shared %p\n",
+ master ? "master" : "slave", emergency ? ", emergency" : "",
+ dfb_core, wm_data, wm_shared );
+
+ D_ASSERT( dfb_core != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( wm_data == data );
+
+ D_MAGIC_ASSERT( shared, WMShared );
+ D_ASSERT( wm_shared == shared );
+
+ if (master) {
+ fusion_object_pool_destroy( shared->window_pool, data->world );
+ fusion_object_pool_destroy( shared->decoration_pool, data->world );
+ fusion_object_pool_destroy( shared->context_pool, data->world );
+ }
+
+ unregister_device_classes( shared );
+ unregister_region_classes( shared );
+
+ if (master)
+ unload_foo( wm_shared );
+
+ dfb_core = NULL;
+ wm_data = NULL;
+ wm_shared = NULL;
+}
+
+ReactionResult
+_unique_wm_module_context_listener( const void *msg_data,
+ void *ctx )
+{
+ const UniqueContextNotification *notification = msg_data;
+
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( wm_data->context_notify != NULL );
+
+ D_ASSERT( notification != NULL );
+
+ D_ASSERT( ! D_FLAGS_IS_SET( notification->flags, ~UCNF_ALL ) );
+
+ D_DEBUG_AT( UniQuE_WM, "%s( context %p, flags 0x%08x )\n",
+ __FUNCTION__, notification->context, notification->flags );
+
+ return wm_data->context_notify( wm_data, notification, ctx );
+}
+
+ReactionResult
+_unique_wm_module_window_listener ( const void *msg_data,
+ void *ctx )
+{
+ const UniqueWindowNotification *notification = msg_data;
+
+ D_ASSERT( wm_data != NULL );
+ D_ASSERT( wm_data->window_notify != NULL );
+
+ D_ASSERT( notification != NULL );
+
+ D_ASSERT( ! D_FLAGS_IS_SET( notification->flags, ~UWNF_ALL ) );
+
+ D_DEBUG_AT( UniQuE_WM, "%s( window %p, flags 0x%08x )\n",
+ __FUNCTION__, notification->window, notification->flags );
+
+ return wm_data->window_notify( wm_data, notification, ctx );
+}
+
+UniqueContext *
+unique_wm_create_context( void )
+{
+ D_ASSERT( dfb_core != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_MAGIC_ASSERT( wm_shared, WMShared );
+ D_ASSERT( wm_shared->context_pool != NULL );
+
+ return (UniqueContext*) fusion_object_create( wm_shared->context_pool, wm_data->world );
+}
+
+UniqueDecoration *
+unique_wm_create_decoration( void )
+{
+ D_ASSERT( dfb_core != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_MAGIC_ASSERT( wm_shared, WMShared );
+ D_ASSERT( wm_shared->decoration_pool != NULL );
+
+ return (UniqueDecoration*) fusion_object_create( wm_shared->decoration_pool, wm_data->world );
+}
+
+UniqueWindow *
+unique_wm_create_window( void )
+{
+ D_ASSERT( dfb_core != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_MAGIC_ASSERT( wm_shared, WMShared );
+ D_ASSERT( wm_shared->window_pool != NULL );
+
+ return (UniqueWindow*) fusion_object_create( wm_shared->window_pool, wm_data->world );
+}
+
+/**************************************************************************************************/
+
+bool
+unique_wm_running( void )
+{
+ if (dfb_core) {
+ if (!wm_data || !wm_shared) {
+ D_BUG( "partly initialized module (%p,%p,%p)", dfb_core, wm_data, wm_shared );
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+DirectResult
+unique_wm_enum_contexts( FusionObjectCallback callback,
+ void *ctx )
+{
+ D_ASSERT( dfb_core != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_MAGIC_ASSERT( wm_shared, WMShared );
+ D_ASSERT( wm_shared->context_pool != NULL );
+
+ return fusion_object_pool_enum( wm_shared->context_pool, callback, ctx );
+}
+
+DirectResult
+unique_wm_enum_windows( FusionObjectCallback callback,
+ void *ctx )
+{
+ D_ASSERT( dfb_core != NULL );
+ D_ASSERT( wm_data != NULL );
+ D_MAGIC_ASSERT( wm_shared, WMShared );
+ D_ASSERT( wm_shared->context_pool != NULL );
+
+ return fusion_object_pool_enum( wm_shared->window_pool, callback, ctx );
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+register_region_classes( WMShared *shared,
+ bool master )
+{
+ int i;
+ DFBResult ret;
+ StretRegionClassID class_id;
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ for (i=0; i<_URCI_NUM; i++) {
+ ret = stret_class_register( region_classes[i], &class_id );
+ if (ret) {
+ D_DERROR( ret, "UniQuE/WM: Failed to register region class %d!\n", i );
+
+ goto error;
+ }
+
+ if (master)
+ shared->region_classes[i] = class_id;
+ else if (shared->region_classes[i] != class_id) {
+ D_ERROR( "UniQuE/WM: Class IDs mismatch (%d/%d)!\n",
+ class_id, shared->region_classes[i] );
+
+ stret_class_unregister( class_id );
+
+ ret = DFB_VERSIONMISMATCH;
+ goto error;
+ }
+ }
+
+ return DFB_OK;
+
+error:
+ while (--i >= 0)
+ stret_class_unregister( shared->region_classes[i] );
+
+ return ret;
+}
+
+static DFBResult
+unregister_region_classes( WMShared *shared )
+{
+ int i;
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ for (i=_URCI_NUM-1; i>=0; i--)
+ stret_class_unregister( shared->region_classes[i] );
+
+ return DFB_OK;
+}
+
+static DFBResult
+register_device_classes( WMShared *shared,
+ bool master )
+{
+ int i;
+ DFBResult ret;
+ UniqueDeviceClassID class_id;
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ for (i=0; i<_UDCI_NUM; i++) {
+ ret = unique_device_class_register( device_classes[i], &class_id );
+ if (ret) {
+ D_DERROR( ret, "UniQuE/WM: Failed to register device class %d!\n", i );
+
+ goto error;
+ }
+
+ if (master)
+ shared->device_classes[i] = class_id;
+ else if (shared->device_classes[i] != class_id) {
+ D_ERROR( "UniQuE/WM: Class IDs mismatch (%d/%d)!\n",
+ class_id, shared->device_classes[i] );
+
+ unique_device_class_unregister( class_id );
+
+ ret = DFB_VERSIONMISMATCH;
+ goto error;
+ }
+ }
+
+ return DFB_OK;
+
+error:
+ while (--i >= 0)
+ unique_device_class_unregister( shared->device_classes[i] );
+
+ return ret;
+}
+
+static DFBResult
+unregister_device_classes( WMShared *shared )
+{
+ int i;
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ for (i=_UDCI_NUM-1; i>=0; i--)
+ unique_device_class_unregister( shared->device_classes[i] );
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/wm/unique/uniquewm.h b/Source/DirectFB/wm/unique/uniquewm.h
new file mode 100755
index 0000000..9b1913b
--- /dev/null
+++ b/Source/DirectFB/wm/unique/uniquewm.h
@@ -0,0 +1,48 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __UNIQUE__UNIQUEWM_H__
+#define __UNIQUE__UNIQUEWM_H__
+
+#include <direct/types.h>
+#include <unique/types.h>
+
+#include <fusion/object.h>
+
+
+bool unique_wm_running ( void );
+
+DirectResult unique_wm_enum_contexts( FusionObjectCallback callback,
+ void *ctx );
+
+DirectResult unique_wm_enum_windows ( FusionObjectCallback callback,
+ void *ctx );
+
+
+#endif
+
diff --git a/Source/DirectFB/wm/unique/uwmdump.c b/Source/DirectFB/wm/unique/uwmdump.c
new file mode 100755
index 0000000..811d344
--- /dev/null
+++ b/Source/DirectFB/wm/unique/uwmdump.c
@@ -0,0 +1,267 @@
+/*
+ (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 file is subject to the terms and conditions of the MIT License:
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <directfb.h>
+
+#include <direct/util.h>
+
+#include <fusion/build.h>
+#include <fusion/vector.h>
+
+#include <core/core.h>
+#include <core/windowstack.h>
+
+#include <unique/context.h>
+#include <unique/internal.h>
+#include <unique/uniquewm.h>
+
+
+static void
+print_usage( const char *prg_name )
+{
+ fprintf( stderr,
+ "\n"
+ "UniQuE Dump (version %s)\n"
+ "\n"
+ "Usage: %s [options]\n"
+ "\n"
+ "Options:\n"
+ " -h, --help Show this help message\n"
+ " -v, --version Print version information\n"
+ "\n",
+ DIRECTFB_VERSION, prg_name );
+}
+
+static DFBBoolean
+parse_command_line( int argc, char *argv[] )
+{
+ int n;
+ const char *prg_name = strrchr( argv[0], '/' );
+
+ if (prg_name)
+ prg_name++;
+ else
+ prg_name = argv[0];
+
+ for (n = 1; n < argc; n++) {
+ const char *a = argv[n];
+
+ if (*a != '-') {
+ print_usage( prg_name );
+ return DFB_FALSE;
+ }
+ if (strcmp (a, "-h") == 0 || strcmp (a, "--help") == 0) {
+ print_usage( prg_name );
+ return DFB_FALSE;
+ }
+ if (strcmp (a, "-v") == 0 || strcmp (a, "--version") == 0) {
+ fprintf (stderr, "dfbg version %s\n", DIRECTFB_VERSION);
+ return DFB_FALSE;
+ }
+ }
+
+ return DFB_TRUE;
+}
+
+static bool
+window_callback( UniqueWindow *window )
+{
+ int refs;
+ DirectResult ret;
+ DFBRectangle *bounds = &window->bounds;
+
+ if (window->object.state != FOS_ACTIVE)
+ return true;
+
+ ret = fusion_ref_stat( &window->object.ref, &refs );
+ if (ret) {
+ printf( "Fusion error %d!\n", ret );
+ return false;
+ }
+
+#if FUSION_BUILD_MULTI
+ printf( "0x%08x : ", window->object.ref.multi.id );
+#else
+ printf( "N/A : " );
+#endif
+
+ printf( "%3d ", refs );
+
+
+ printf( "%4d, %4d ", bounds->x, bounds->y );
+
+ printf( "%4d x %4d ", bounds->w, bounds->h );
+
+ printf( "0x%02x ", window->opacity );
+
+ printf( "%5d ", dfb_window_id( window->window ) );
+
+ switch (window->stacking) {
+ case DWSC_UPPER:
+ printf( "^ " );
+ break;
+ case DWSC_MIDDLE:
+ printf( "- " );
+ break;
+ case DWSC_LOWER:
+ printf( "v " );
+ break;
+ default:
+ printf( "? " );
+ break;
+ }
+
+ if (D_FLAGS_IS_SET( window->flags, UWF_VISIBLE ))
+ printf( "VISIBLE " );
+
+ if (D_FLAGS_IS_SET( window->flags, UWF_DECORATED ))
+ printf( "DECORATED " );
+
+ if (D_FLAGS_IS_SET( window->flags, UWF_DESTROYED ))
+ printf( "DESTROYED " );
+
+
+ printf( "\n" );
+
+ return true;
+}
+
+static bool
+context_callback( FusionObjectPool *pool,
+ FusionObject *object,
+ void *ctx )
+{
+ int refs;
+ DirectResult ret;
+ UniqueContext *context = (UniqueContext*) object;
+
+ if (object->state != FOS_ACTIVE)
+ return true;
+
+ ret = fusion_ref_stat( &object->ref, &refs );
+ if (ret) {
+ printf( "Fusion error %d!\n", ret );
+ return false;
+ }
+
+ printf( "\n"
+ "-------[ Contexts ]-------\n"
+ "Reference . Refs Windows\n"
+ "--------------------------\n" );
+
+#if FUSION_BUILD_MULTI
+ printf( "0x%08x : ", object->ref.multi.id );
+#else
+ printf( "N/A : " );
+#endif
+
+ printf( "%3d ", refs );
+
+ printf( "%2d ", fusion_vector_size( &context->windows ) );
+
+ printf( "\n" );
+
+
+ ret = dfb_windowstack_lock( context->stack );
+ if (ret) {
+ D_DERROR( ret, "UniQuE/Dump: Could not lock window stack!\n" );
+ return true;
+ }
+
+ if (fusion_vector_has_elements( &context->windows )) {
+ int index;
+ UniqueWindow *window;
+
+ printf( "\n"
+ "-----------------------------------[ Windows ]------------------------------------\n" );
+ printf( "Reference . Refs X Y Width Height Opacity ID Flags\n" );
+ printf( "----------------------------------------------------------------------------------\n" );
+
+ fusion_vector_foreach_reverse( window, index, context->windows )
+ window_callback( window );
+ }
+
+ dfb_windowstack_unlock( context->stack );
+
+ printf( "\n" );
+
+ return true;
+}
+
+int
+main( int argc, char *argv[] )
+{
+ DFBResult ret;
+ CoreDFB *core;
+
+ /* Initialize DirectFB including command line parsing. */
+ ret = DirectFBInit( &argc, &argv );
+ if (ret) {
+ DirectFBError( "DirectFBInit() failed", ret );
+ return -1;
+ }
+
+ /* Parse the command line. */
+ if (!parse_command_line( argc, argv ))
+ return -2;
+
+ /* Create the super interface. */
+ ret = dfb_core_create( &core );
+ if (ret) {
+ DirectFBError( "dfb_core_create() failed", ret );
+ return -3;
+ }
+
+ if (!unique_wm_running()) {
+ D_ERROR( "UniQuE/Dump: This session doesn't run UniQuE!\n" );
+ dfb_core_destroy( core, false );
+ return EXIT_FAILURE;
+ }
+
+
+ unique_wm_enum_contexts( context_callback, NULL );
+
+
+ /* Release the super interface. */
+ dfb_core_destroy( core, false );
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/Source/DirectFB/wm/unique/window.c b/Source/DirectFB/wm/unique/window.c
new file mode 100755
index 0000000..eed319c
--- /dev/null
+++ b/Source/DirectFB/wm/unique/window.c
@@ -0,0 +1,1525 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+
+#include <fusion/object.h>
+#include <fusion/shmalloc.h>
+
+#include <core/coretypes.h>
+#include <core/layers_internal.h> /* FIXME */
+#include <core/surface.h>
+#include <core/windows.h>
+#include <core/windows_internal.h> /* FIXME */
+#include <core/windowstack.h>
+
+#include <misc/conf.h>
+#include <misc/util.h>
+
+#include <unique/context.h>
+#include <unique/input_channel.h>
+#include <unique/input_switch.h>
+#include <unique/internal.h>
+#include <unique/window.h>
+
+
+D_DEBUG_DOMAIN( UniQuE_Window, "UniQuE/Window", "UniQuE's Window" );
+
+
+static const ReactionFunc unique_window_globals[] = {
+ _unique_wm_module_window_listener,
+ NULL
+};
+
+/**************************************************************************************************/
+
+typedef struct {
+ DirectLink link;
+
+ int magic;
+
+ DFBInputDeviceKeySymbol symbol;
+ DFBInputDeviceModifierMask modifiers;
+
+ UniqueInputFilter *filter;
+} KeyFilter;
+
+/**************************************************************************************************/
+
+static DFBResult add_key_filter ( UniqueWindow *window,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers,
+ UniqueInputFilter *filter );
+
+static DFBResult remove_key_filter ( UniqueWindow *window,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers );
+
+static void remove_all_filters( UniqueWindow *window );
+
+/**************************************************************************************************/
+
+static DFBResult create_regions ( UniqueWindow *window );
+
+static void insert_window ( UniqueContext *context,
+ UniqueWindow *window );
+
+static void remove_window ( UniqueWindow *window );
+
+static void update_foo_frame( UniqueWindow *window,
+ UniqueContext *context,
+ WMShared *shared );
+
+static DFBResult update_window ( UniqueWindow *window,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags,
+ bool complete );
+
+static void update_flags ( UniqueWindow *window );
+
+static void set_opacity ( UniqueWindow *window,
+ u8 opacity );
+
+static DFBResult move_window ( UniqueWindow *window,
+ int dx,
+ int dy );
+
+static DFBResult resize_window ( UniqueWindow *window,
+ int width,
+ int height );
+
+static DFBResult restack_window ( UniqueWindow *window,
+ UniqueWindow *relative,
+ int relation,
+ DFBWindowStackingClass stacking );
+
+/**************************************************************************************************/
+
+static inline int get_priority( DFBWindowCapabilities caps, DFBWindowStackingClass stacking );
+
+/**************************************************************************************************/
+
+static void
+window_destructor( FusionObject *object, bool zombie, void *ctx )
+{
+ int i;
+ UniqueContext *context;
+ UniqueWindow *window = (UniqueWindow*) object;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_DEBUG_AT( UniQuE_Window, "destroying %p (%dx%d - %dx%d)%s\n",
+ window, DFB_RECTANGLE_VALS( &window->bounds ), zombie ? " (ZOMBIE)" : "");
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+
+ D_FLAGS_SET( window->flags, UWF_DESTROYED );
+
+ unique_window_notify( window, UWNF_DESTROYED );
+
+
+ set_opacity( window, 0 );
+
+ remove_window( window );
+
+ for (i=0; i<8; i++) {
+ if (window->foos[i])
+ stret_region_destroy( window->foos[i] );
+ }
+
+ stret_region_destroy( window->region );
+
+ stret_region_destroy( window->frame );
+
+
+ remove_all_filters( window );
+
+ unique_input_switch_drop( context->input_switch, window->channel );
+
+ unique_input_channel_detach_global( window->channel, &window->channel_reaction );
+
+ unique_input_channel_destroy( window->channel );
+
+
+ if (window->surface)
+ dfb_surface_unlink( &window->surface );
+
+ unique_context_unlink( &window->context );
+
+ dfb_window_unlink( &window->window );
+
+ D_MAGIC_CLEAR( window );
+
+ fusion_object_destroy( object );
+}
+
+FusionObjectPool *
+unique_window_pool_create( const FusionWorld *world )
+{
+ return fusion_object_pool_create( "UniQuE Window Pool", sizeof(UniqueWindow),
+ sizeof(UniqueWindowNotification), window_destructor, NULL, world );
+}
+
+/**************************************************************************************************/
+
+DFBResult
+unique_window_create( CoreDFB *core,
+ CoreWindow *window,
+ UniqueContext *context,
+ DFBWindowCapabilities caps,
+ const CoreWindowConfig *config,
+ UniqueWindow **ret_window )
+{
+ DFBResult ret;
+ UniqueWindow *uniwin;
+ WMShared *shared;
+ CoreSurface *surface;
+ DFBRectangle bounds;
+
+ D_ASSERT( window != NULL );
+ D_ASSERT( ret_window != NULL );
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ shared = context->shared;
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ surface = dfb_window_surface( window );
+
+ D_ASSERT( surface != NULL || (caps & DWCAPS_INPUTONLY));
+
+ uniwin = unique_wm_create_window();
+ if (!uniwin)
+ return DFB_FUSION;
+
+ bounds = config->bounds;
+
+ /*if (bounds.x == 0 && bounds.y == 0) {
+ bounds.x = (context->width - bounds.w) / 2;
+ bounds.y = (context->height - bounds.h) / 2;
+ }*/
+
+ /* Initialize window data. */
+ uniwin->shared = context->shared;
+
+ uniwin->caps = caps;
+ uniwin->flags = UWF_NONE;
+
+ uniwin->bounds = bounds;
+ uniwin->opacity = config->opacity;
+ uniwin->stacking = config->stacking;
+ uniwin->priority = get_priority( caps, config->stacking );
+ uniwin->options = config->options;
+ uniwin->events = config->events;
+ uniwin->color_key = config->color_key;
+ uniwin->opaque = config->opaque;
+
+ if (dfb_config->decorations && ! (caps & (DWCAPS_INPUTONLY | DWCAPS_NODECORATION))) {
+ uniwin->flags |= UWF_DECORATED;
+ uniwin->insets = shared->insets;
+ }
+
+ dfb_rectangle_from_rectangle_plus_insets( &uniwin->full, &uniwin->bounds, &uniwin->insets );
+
+ ret = dfb_window_link( &uniwin->window, window );
+ if (ret)
+ goto error;
+
+ ret = unique_context_link( &uniwin->context, context );
+ if (ret)
+ goto error;
+
+ if (surface) {
+ ret = dfb_surface_link( &uniwin->surface, surface );
+ if (ret)
+ goto error;
+ }
+
+
+ ret = unique_input_channel_create( core, context, &uniwin->channel );
+ if (ret)
+ goto error;
+
+ ret = unique_input_channel_attach_global( uniwin->channel,
+ UNIQUE_WINDOW_INPUT_CHANNEL_LISTENER,
+ uniwin, &uniwin->channel_reaction );
+ if (ret)
+ goto error;
+
+
+ D_MAGIC_SET( uniwin, UniqueWindow );
+
+ ret = create_regions( uniwin );
+ if (ret) {
+ D_MAGIC_CLEAR( uniwin );
+ goto error;
+ }
+
+
+ /* Change global reaction lock. */
+ fusion_object_set_lock( &uniwin->object, &context->stack->context->lock );
+
+ /* activate object */
+ fusion_object_activate( &uniwin->object );
+
+ /* Actually add the window to the stack. */
+ insert_window( context, uniwin );
+
+ /* Possibly switch focus to the new window. */
+ //unique_context_update_focus( context );
+
+ /* return the new context */
+ *ret_window = uniwin;
+
+ return DFB_OK;
+
+error:
+ if (uniwin->channel_reaction.attached)
+ unique_input_channel_detach_global( uniwin->channel, &uniwin->channel_reaction );
+
+ if (uniwin->channel)
+ unique_input_channel_destroy( uniwin->channel );
+
+ if (uniwin->surface)
+ dfb_surface_unlink( &uniwin->surface );
+
+ if (uniwin->context)
+ unique_context_unlink( &uniwin->context );
+
+ if (uniwin->window)
+ dfb_window_unlink( &uniwin->window );
+
+ fusion_object_destroy( &uniwin->object );
+
+ return ret;
+}
+
+DFBResult
+unique_window_close( UniqueWindow *window )
+{
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_UNIMPLEMENTED();
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_window_destroy( UniqueWindow *window )
+{
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_UNIMPLEMENTED();
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_window_notify( UniqueWindow *window,
+ UniqueWindowNotificationFlags flags )
+{
+ UniqueWindowNotification notification;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( flags != UWNF_NONE );
+
+ D_ASSERT( ! (flags & ~UWNF_ALL) );
+
+ notification.flags = flags;
+ notification.window = window;
+
+ return unique_window_dispatch( window, &notification, unique_window_globals );
+}
+
+DFBResult
+unique_window_update( UniqueWindow *window,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags )
+{
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ DFB_REGION_ASSERT_IF( region );
+
+ return update_window( window, region, flags, false );
+}
+
+DFBResult
+unique_window_post_event( UniqueWindow *window,
+ DFBWindowEvent *event )
+{
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( event != NULL );
+
+ if (!D_FLAGS_IS_SET( window->events, event->type ))
+ return DFB_OK;
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ dfb_window_post_event( window->window, event );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_window_set_config( UniqueWindow *window,
+ const CoreWindowConfig *config,
+ CoreWindowConfigFlags flags )
+{
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ if (flags & CWCF_OPTIONS) {
+ window->options = config->options;
+ update_flags( window );
+ }
+
+ if (flags & CWCF_EVENTS)
+ window->events = config->events;
+
+ if (flags & CWCF_COLOR)
+ return DFB_UNSUPPORTED;
+
+ if (flags & CWCF_COLOR_KEY)
+ window->color_key = config->color_key;
+
+ if (flags & CWCF_OPAQUE)
+ window->opaque = config->opaque;
+
+ if (flags & CWCF_OPACITY && !config->opacity)
+ set_opacity( window, config->opacity );
+
+ if (flags & CWCF_POSITION)
+ move_window( window,
+ config->bounds.x - window->bounds.x,
+ config->bounds.y - window->bounds.y );
+
+ if (flags & CWCF_STACKING)
+ restack_window( window, window, 0, config->stacking );
+
+ if (flags & CWCF_OPACITY && config->opacity)
+ set_opacity( window, config->opacity );
+
+ if (flags & CWCF_SIZE)
+ return resize_window( window, config->bounds.w, config->bounds.h );
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_window_get_config( UniqueWindow *window,
+ CoreWindowConfig *config )
+{
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( config != NULL );
+
+ config->bounds = window->bounds;
+ config->opacity = window->opacity;
+ config->stacking = window->stacking;
+ config->options = window->options;
+ config->events = window->events;
+ config->color_key = window->color_key;
+ config->opaque = window->opaque;
+
+ return DFB_OK;
+}
+
+
+DFBResult
+unique_window_restack( UniqueWindow *window,
+ UniqueWindow *relative,
+ int relation )
+{
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ return restack_window( window, relative, relation, window->stacking );
+}
+
+
+DFBResult
+unique_window_grab( UniqueWindow *window,
+ const CoreWMGrab *grab )
+{
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ switch (grab->target) {
+ case CWMGT_KEYBOARD:
+ return unique_input_switch_set( context->input_switch,
+ UDCI_KEYBOARD, window->channel );
+
+ case CWMGT_POINTER:
+ return unique_input_switch_set( context->input_switch,
+ UDCI_POINTER, window->channel );
+
+ case CWMGT_KEY: {
+ DFBResult ret;
+ UniqueInputEvent event;
+ UniqueInputFilter *filter;
+
+ event.keyboard.key_code = -1;
+ event.keyboard.key_symbol = grab->symbol;
+ event.keyboard.modifiers = grab->modifiers;
+
+ ret = unique_input_switch_set_filter( context->input_switch, UDCI_KEYBOARD,
+ window->channel, &event, &filter );
+ if (ret) {
+ D_DERROR( ret, "UniQuE/Window: Could not set input filter for key grab!\n" );
+ return ret;
+ }
+
+ ret = add_key_filter( window, grab->symbol, grab->modifiers, filter );
+ if (ret) {
+ unique_input_switch_unset_filter( context->input_switch, filter );
+ return ret;
+ }
+
+ break;
+ }
+
+ default:
+ D_BUG( "unknown grab target" );
+ break;
+ }
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_window_ungrab( UniqueWindow *window,
+ const CoreWMGrab *grab )
+{
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ switch (grab->target) {
+ case CWMGT_KEYBOARD:
+ return unique_input_switch_unset( context->input_switch,
+ UDCI_KEYBOARD, window->channel );
+
+ case CWMGT_POINTER:
+ return unique_input_switch_unset( context->input_switch,
+ UDCI_POINTER, window->channel );
+
+ case CWMGT_KEY:
+ return remove_key_filter( window, grab->symbol, grab->modifiers );
+
+ default:
+ D_BUG( "unknown grab target" );
+ break;
+ }
+
+ return DFB_OK;
+}
+
+DFBResult
+unique_window_request_focus( UniqueWindow *window )
+{
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ return unique_input_switch_select( context->input_switch, UDCI_KEYBOARD, window->channel );
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+add_key_filter( UniqueWindow *window,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers,
+ UniqueInputFilter *filter )
+{
+ KeyFilter *key;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ key = SHCALLOC( context->shmpool, 1, sizeof(KeyFilter) );
+ if (!key)
+ return D_OOSHM();
+
+ key->symbol = symbol;
+ key->modifiers = modifiers;
+ key->filter = filter;
+
+ direct_list_append( &window->filters, &key->link );
+
+ D_MAGIC_SET( key, KeyFilter );
+
+ return DFB_OK;
+}
+
+static DFBResult
+remove_key_filter( UniqueWindow *window,
+ DFBInputDeviceKeySymbol symbol,
+ DFBInputDeviceModifierMask modifiers )
+{
+ KeyFilter *key;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ direct_list_foreach (key, window->filters) {
+ D_MAGIC_ASSERT( key, KeyFilter );
+
+ if (key->symbol == symbol && key->modifiers == modifiers)
+ break;
+ }
+
+ if (!key)
+ return DFB_ITEMNOTFOUND;
+
+ unique_input_switch_unset_filter( context->input_switch, key->filter );
+
+ direct_list_remove( &window->filters, &key->link );
+
+ D_MAGIC_CLEAR( key );
+
+ SHFREE( context->shmpool, key );
+
+ return DFB_OK;
+}
+
+static void
+remove_all_filters( UniqueWindow *window )
+{
+ DirectLink *n;
+ KeyFilter *key;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ direct_list_foreach_safe (key, n, window->filters) {
+ D_MAGIC_ASSERT( key, KeyFilter );
+
+ unique_input_switch_unset_filter( context->input_switch, key->filter );
+
+ D_MAGIC_CLEAR( key );
+
+ SHFREE( context->shmpool, key );
+ }
+
+ window->filters = NULL;
+}
+
+/**************************************************************************************************/
+
+static void
+dispatch_motion( UniqueWindow *window,
+ const UniqueInputEvent *event )
+{
+ DFBWindowEvent evt;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( event != NULL );
+
+ evt.type = DWET_MOTION;
+ evt.cx = event->pointer.x;
+ evt.cy = event->pointer.y;
+ evt.x = event->pointer.x - window->bounds.x;
+ evt.y = event->pointer.y - window->bounds.y;
+ evt.buttons = event->pointer.buttons;
+
+ dfb_window_post_event( window->window, &evt );
+}
+
+static void
+dispatch_button( UniqueWindow *window,
+ const UniqueInputEvent *event )
+{
+ DFBWindowEvent evt;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( event != NULL );
+
+ evt.type = event->pointer.press ? DWET_BUTTONDOWN : DWET_BUTTONUP;
+ evt.cx = event->pointer.x;
+ evt.cy = event->pointer.y;
+ evt.x = event->pointer.x - window->bounds.x;
+ evt.y = event->pointer.y - window->bounds.y;
+ evt.button = event->pointer.button;
+ evt.buttons = event->pointer.buttons;
+
+ dfb_window_post_event( window->window, &evt );
+}
+
+static void
+dispatch_wheel( UniqueWindow *window,
+ const UniqueInputEvent *event )
+{
+ DFBWindowEvent evt;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( event != NULL );
+
+ evt.type = DWET_WHEEL;
+ evt.step = event->wheel.value;
+
+ dfb_window_post_event( window->window, &evt );
+}
+
+static void
+dispatch_key( UniqueWindow *window,
+ const UniqueInputEvent *event )
+{
+ DFBWindowEvent evt;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( event != NULL );
+
+ evt.type = event->keyboard.press ? DWET_KEYDOWN : DWET_KEYUP;
+ evt.key_code = event->keyboard.key_code;
+ evt.key_id = event->keyboard.key_id;
+ evt.key_symbol = event->keyboard.key_symbol;
+ evt.modifiers = event->keyboard.modifiers;
+ evt.locks = event->keyboard.locks;
+
+ dfb_window_post_event( window->window, &evt );
+}
+
+static void
+dispatch_channel( UniqueWindow *window,
+ const UniqueInputEvent *event )
+{
+ DFBWindowEvent evt;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( event != NULL );
+
+ switch (event->channel.index) {
+ case UDCI_POINTER:
+ evt.type = event->channel.selected ? DWET_ENTER : DWET_LEAVE;
+ break;
+
+ case UDCI_KEYBOARD:
+ evt.type = event->channel.selected ? DWET_GOTFOCUS : DWET_LOSTFOCUS;
+ break;
+
+ default:
+ return;
+ }
+
+ evt.cx = event->channel.x;
+ evt.cy = event->channel.y;
+ evt.x = event->channel.x - window->bounds.x;
+ evt.y = event->channel.y - window->bounds.y;
+
+ dfb_window_post_event( window->window, &evt );
+}
+
+ReactionResult
+_unique_window_input_channel_listener( const void *msg_data,
+ void *ctx )
+{
+ const UniqueInputEvent *event = msg_data;
+ UniqueWindow *window = ctx;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( event != NULL );
+
+ D_DEBUG_AT( UniQuE_Window, "_unique_window_input_channel_listener( %p, %p )\n",
+ event, window );
+
+ switch (event->type) {
+ case UIET_MOTION:
+ dispatch_motion( window, event );
+ break;
+
+ case UIET_BUTTON:
+ dispatch_button( window, event );
+ break;
+
+ case UIET_WHEEL:
+ dispatch_wheel( window, event );
+ break;
+
+ case UIET_KEY:
+ dispatch_key( window, event );
+ break;
+
+ case UIET_CHANNEL:
+ dispatch_channel( window, event );
+ break;
+
+ default:
+ D_ONCE( "unknown event type" );
+ break;
+ }
+
+ return RS_OK;
+}
+
+/**************************************************************************************************/
+
+static inline int
+get_priority( DFBWindowCapabilities caps, DFBWindowStackingClass stacking )
+{
+ switch (stacking) {
+ case DWSC_UPPER:
+ return 1;
+
+ case DWSC_MIDDLE:
+ return 0;
+
+ case DWSC_LOWER:
+ return -1;
+
+ default:
+ D_BUG( "unknown stacking class" );
+ break;
+ }
+
+ return 0;
+}
+
+static inline int
+get_index( UniqueWindow *window )
+{
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( fusion_vector_contains( &context->windows, window ) );
+
+ return fusion_vector_index_of( &context->windows, window );
+}
+
+static DFBResult
+update_window( UniqueWindow *window,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags,
+ bool complete )
+{
+ DFBRegion regions[32];
+ int num_regions;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ DFB_REGION_ASSERT_IF( region );
+
+ if (complete || stret_region_visible( window->region, region, true, regions, 32, &num_regions )) {
+ if (region) {
+ DFBRegion area = DFB_REGION_INIT_TRANSLATED( region,
+ window->bounds.x,
+ window->bounds.y );
+
+ unique_context_update( window->context, &area, 1, flags );
+ }
+ else {
+ DFBRegion area = DFB_REGION_INIT_FROM_RECTANGLE( &window->bounds );
+ unique_context_update( window->context, &area, 1, flags );
+ }
+ }
+ else if (num_regions > 0)
+ unique_context_update( window->context, regions, num_regions, flags );
+
+ return DFB_OK;
+}
+
+static DFBResult
+update_frame( UniqueWindow *window,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags,
+ bool complete )
+{
+ DFBRegion regions[32];
+ int num_regions;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ DFB_REGION_ASSERT_IF( region );
+
+ if (complete || stret_region_visible( window->frame, region, true, regions, 32, &num_regions )) {
+ if (region) {
+ DFBRegion area = DFB_REGION_INIT_TRANSLATED( region,
+ window->full.x,
+ window->full.y );
+
+ unique_context_update( window->context, &area, 1, flags );
+ }
+ else {
+ DFBRegion area = DFB_REGION_INIT_FROM_RECTANGLE( &window->full );
+ unique_context_update( window->context, &area, 1, flags );
+ }
+ }
+ else if (num_regions > 0)
+ unique_context_update( window->context, regions, num_regions, flags );
+
+ return DFB_OK;
+}
+
+/**************************************************************************************************/
+/**************************************************************************************************/
+
+static void
+insert_window( UniqueContext *context,
+ UniqueWindow *window )
+{
+ int index;
+ UniqueWindow *other;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ /*
+ * Iterate from bottom to top,
+ * stopping at the first window with a higher priority.
+ */
+ fusion_vector_foreach (other, index, context->windows) {
+ D_MAGIC_ASSERT( other, UniqueWindow );
+
+ if (other->priority > window->priority)
+ break;
+ }
+
+ /* Insert the window at the acquired position. */
+ fusion_vector_insert( &context->windows, window, index );
+
+ stret_region_restack( window->frame, index );
+}
+
+static void
+remove_window( UniqueWindow *window )
+{
+ int index;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_ASSERT( fusion_vector_contains( &context->windows, window ) );
+
+ index = fusion_vector_index_of( &context->windows, window );
+
+ fusion_vector_remove( &context->windows, index );
+}
+
+/**************************************************************************************************/
+
+static DFBResult
+move_window( UniqueWindow *window,
+ int dx,
+ int dy )
+{
+ DFBWindowEvent evt;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ dfb_rectangle_translate( &window->bounds, dx, dy );
+ dfb_rectangle_translate( &window->full, dx, dy );
+
+ stret_region_move( window->frame, dx, dy );
+
+ if (D_FLAGS_IS_SET( window->flags, UWF_VISIBLE )) {
+ DFBRegion region = { 0, 0, window->full.w - 1, window->full.h - 1 };
+
+ if (dx > 0)
+ region.x1 -= dx;
+ else if (dx < 0)
+ region.x2 -= dx;
+
+ if (dy > 0)
+ region.y1 -= dy;
+ else if (dy < 0)
+ region.y2 -= dy;
+
+ update_frame( window, &region, DSFLIP_NONE, false );
+ }
+
+ /* Send new position */
+ evt.type = DWET_POSITION;
+ evt.x = window->bounds.x;
+ evt.y = window->bounds.y;
+
+ unique_window_post_event( window, &evt );
+
+ return DFB_OK;
+}
+
+static DFBResult
+resize_window( UniqueWindow *window,
+ int width,
+ int height )
+{
+ DFBResult ret;
+ DFBWindowEvent evt;
+ int ow;
+ int oh;
+ UniqueContext *context;
+ WMShared *shared;
+ DFBRectangle *sizes;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_ASSERT( width > 0 );
+ D_ASSERT( height > 0 );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ shared = context->shared;
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ sizes = shared->foo_rects;
+
+ if (width > 4096 || height > 4096)
+ return DFB_LIMITEXCEEDED;
+
+ if (window->surface) {
+ ret = dfb_surface_reformat( window->surface, width, height, window->surface->config.format );
+ if (ret)
+ return ret;
+ }
+
+ ow = window->bounds.w;
+ oh = window->bounds.h;
+
+ window->bounds.w = width;
+ window->bounds.h = height;
+
+ window->full.w += width - ow;
+ window->full.h += height - oh;
+
+ stret_region_resize( window->frame, window->full.w, window->full.h );
+ stret_region_resize( window->region, window->bounds.w, window->bounds.h );
+
+ update_foo_frame( window, window->context, window->shared );
+
+ if (D_FLAGS_IS_SET( window->flags, UWF_VISIBLE )) {
+ int dw = ow - width;
+ int dh = oh - height;
+
+ if (D_FLAGS_IS_SET( window->flags, UWF_DECORATED )) {
+ int bw = dw - sizes[UFI_NE].w + sizes[UFI_E].w;
+ int bh = dh - sizes[UFI_SW].h + sizes[UFI_S].h;
+ DFBInsets *in = &window->insets;
+
+ if (bw < 0) {
+ DFBRegion region = { in->l + width + bw, 0, in->l + width - 1, in->t - 1 };
+
+ update_frame( window, &region, 0, false );
+ }
+
+ if (bh < 0) {
+ DFBRegion region = { 0, in->t + height + bh, in->l - 1, in->t + height - 1 };
+
+ update_frame( window, &region, 0, false );
+ }
+
+ if (dw < 0)
+ dw = 0;
+
+ if (dh < 0)
+ dh = 0;
+
+ dw += in->r;
+ dh += in->b;
+
+ if (dw > 0) {
+ DFBRegion region = { in->l + width, 0, in->l + width + dw - 1, in->t + height - 1 };
+
+ update_frame( window, &region, 0, false );
+ }
+
+ if (dh > 0) {
+ DFBRegion region = { 0, in->t + height, in->l + width + dw - 1, in->t + height + dh - 1 };
+
+ update_frame( window, &region, 0, false );
+ }
+ }
+ else {
+ if (dw < 0)
+ dw = 0;
+
+ if (dh < 0)
+ dh = 0;
+
+ if (dw > 0) {
+ DFBRegion region = { width, 0, width + dw - 1, height - 1 };
+
+ update_frame( window, &region, 0, false );
+ }
+
+ if (dh > 0) {
+ DFBRegion region = { 0, height, width + dw - 1, height + dh - 1 };
+
+ update_frame( window, &region, 0, false );
+ }
+ }
+ }
+
+ /* Send new size */
+ evt.type = DWET_SIZE;
+ evt.w = window->bounds.w;
+ evt.h = window->bounds.h;
+
+ unique_window_post_event( window, &evt );
+
+ unique_input_switch_update( context->input_switch, window->channel );
+ //unique_context_update_focus( context );
+
+ return DFB_OK;
+}
+
+static DFBResult
+restack_window( UniqueWindow *window,
+ UniqueWindow *relative,
+ int relation,
+ DFBWindowStackingClass stacking )
+{
+ int old;
+ int index;
+ int priority;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ D_MAGIC_ASSERT_IF( relative, UniqueWindow );
+
+ D_ASSERT( relative == NULL || relative == window || relation != 0);
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ /* Change stacking class. */
+ if (stacking != window->stacking) {
+ window->stacking = stacking;
+ window->priority = get_priority( window->caps, stacking );
+ }
+
+ /* Get the (new) priority. */
+ priority = window->priority;
+
+ /* Get the old index. */
+ old = get_index( window );
+
+ /* Calculate the desired index. */
+ if (relative) {
+ index = get_index( relative );
+
+ if (relation > 0) {
+ if (old < index)
+ index--;
+ }
+ else if (relation < 0) {
+ if (old > index)
+ index++;
+ }
+
+ index += relation;
+
+ if (index < 0)
+ index = 0;
+ else if (index > fusion_vector_size( &context->windows ) - 1)
+ index = fusion_vector_size( &context->windows ) - 1;
+ }
+ else if (relation)
+ index = fusion_vector_size( &context->windows ) - 1;
+ else
+ index = 0;
+
+ /* Assure window won't be above any window with a higher priority. */
+ while (index > 0) {
+ int below = (old < index) ? index : index - 1;
+ UniqueWindow *other = fusion_vector_at( &context->windows, below );
+
+ D_MAGIC_ASSERT( other, UniqueWindow );
+
+ if (priority < other->priority)
+ index--;
+ else
+ break;
+ }
+
+ /* Assure window won't be below any window with a lower priority. */
+ while (index < fusion_vector_size( &context->windows ) - 1) {
+ int above = (old > index) ? index : index + 1;
+ UniqueWindow *other = fusion_vector_at( &context->windows, above );
+
+ D_MAGIC_ASSERT( other, UniqueWindow );
+
+ if (priority > other->priority)
+ index++;
+ else
+ break;
+ }
+
+ /* Return if index hasn't changed. */
+ if (index == old)
+ return DFB_OK;
+
+ /* Actually change the stacking order now. */
+ fusion_vector_move( &context->windows, old, index );
+
+ stret_region_restack( window->frame, index );
+
+ update_frame( window, NULL, DSFLIP_NONE, (index < old) );
+
+ if (index < old)
+ unique_input_switch_update( context->input_switch, window->channel );
+
+ return DFB_OK;
+}
+
+static void
+set_opacity( UniqueWindow *window,
+ u8 opacity )
+{
+ u8 old;
+ UniqueContext *context;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ old = window->opacity;
+
+ if (!dfb_config->translucent_windows && opacity)
+ opacity = 0xFF;
+
+ if (old != opacity) {
+ bool show = !old && opacity;
+ bool hide = old && !opacity;
+
+ window->opacity = opacity;
+
+ if (show) {
+ stret_region_enable( window->frame, SRF_ACTIVE );
+
+ D_FLAGS_SET( window->flags, UWF_VISIBLE );
+ }
+
+ if (hide)
+ D_FLAGS_CLEAR( window->flags, UWF_VISIBLE );
+
+ if (! (window->options & (DWOP_ALPHACHANNEL | DWOP_COLORKEYING))) {
+ if (opacity == 0xff && old != 0xff)
+ stret_region_enable( window->region, SRF_OPAQUE );
+ else if (opacity != 0xff && old == 0xff)
+ stret_region_disable( window->region, SRF_OPAQUE );
+ }
+
+ update_frame( window, NULL, DSFLIP_NONE, false );
+
+
+ /* Check focus after window appeared or disappeared */
+ if (/*show ||*/ hide)
+ unique_input_switch_update( context->input_switch, window->channel );
+// unique_context_update_focus( context );
+
+ /* If window disappeared... */
+ if (hide) {
+ stret_region_disable( window->frame, SRF_ACTIVE );
+
+ /* Ungrab pointer/keyboard, release focus */
+ unique_input_switch_drop( context->input_switch, window->channel );
+ }
+ }
+}
+
+/**************************************************************************************************/
+
+static void
+foo_rects( UniqueWindow *window,
+ UniqueContext *context,
+ WMShared *shared,
+ DFBRectangle *ret_rects )
+{
+ int width;
+ int height;
+ DFBRectangle *sizes;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ D_MAGIC_ASSERT( shared, WMShared );
+ D_ASSERT( ret_rects != NULL );
+
+ width = window->full.w;
+ height = window->full.h;
+
+ sizes = shared->foo_rects;
+
+ if (width <= sizes[UFI_NW].w + sizes[UFI_NE].w)
+ width = sizes[UFI_NW].w + sizes[UFI_NE].w + 1;
+
+ if (width <= sizes[UFI_SW].w + sizes[UFI_SE].w)
+ width = sizes[UFI_SW].w + sizes[UFI_SE].w + 1;
+
+ if (height <= sizes[UFI_NW].h + sizes[UFI_SW].h)
+ height = sizes[UFI_NW].h + sizes[UFI_SW].h + 1;
+
+ if (height <= sizes[UFI_NE].h + sizes[UFI_SE].h)
+ height = sizes[UFI_NE].h + sizes[UFI_SE].h + 1;
+
+ ret_rects[UFI_N].x = sizes[UFI_NW].w;
+ ret_rects[UFI_N].y = 0;
+ ret_rects[UFI_N].w = width - sizes[UFI_NW].w - sizes[UFI_NE].w;
+ ret_rects[UFI_N].h = sizes[UFI_N].h;
+
+ ret_rects[UFI_NE].x = width - sizes[UFI_NE].w;
+ ret_rects[UFI_NE].y = 0;
+ ret_rects[UFI_NE].w = sizes[UFI_NE].w;
+ ret_rects[UFI_NE].h = sizes[UFI_NE].h;
+
+ ret_rects[UFI_E].x = width - sizes[UFI_E].w;
+ ret_rects[UFI_E].y = sizes[UFI_NE].h;
+ ret_rects[UFI_E].w = sizes[UFI_E].w;
+ ret_rects[UFI_E].h = height - sizes[UFI_NE].h - sizes[UFI_SE].h;
+
+ ret_rects[UFI_SE].x = width - sizes[UFI_SE].w;
+ ret_rects[UFI_SE].y = height - sizes[UFI_SE].h;
+ ret_rects[UFI_SE].w = sizes[UFI_SE].w;
+ ret_rects[UFI_SE].h = sizes[UFI_SE].h;
+
+ ret_rects[UFI_S].x = sizes[UFI_SW].w;
+ ret_rects[UFI_S].y = height - sizes[UFI_S].h;
+ ret_rects[UFI_S].w = width - sizes[UFI_SE].w - sizes[UFI_SW].w;
+ ret_rects[UFI_S].h = sizes[UFI_S].h;
+
+ ret_rects[UFI_SW].x = 0;
+ ret_rects[UFI_SW].y = height - sizes[UFI_SW].h;
+ ret_rects[UFI_SW].w = sizes[UFI_SW].w;
+ ret_rects[UFI_SW].h = sizes[UFI_SW].h;
+
+ ret_rects[UFI_W].x = 0;
+ ret_rects[UFI_W].y = sizes[UFI_NW].h;
+ ret_rects[UFI_W].w = sizes[UFI_W].w;
+ ret_rects[UFI_W].h = height - sizes[UFI_NW].h - sizes[UFI_SW].h;
+
+ ret_rects[UFI_NW].x = 0;
+ ret_rects[UFI_NW].y = 0;
+ ret_rects[UFI_NW].w = sizes[UFI_NW].w;
+ ret_rects[UFI_NW].h = sizes[UFI_NW].h;
+}
+
+static void
+update_foo_frame( UniqueWindow *window,
+ UniqueContext *context,
+ WMShared *shared )
+{
+ int i;
+ DFBRectangle rects[8];
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+ D_MAGIC_ASSERT( context, UniqueContext );
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ if (!window->foos[0])
+ return;
+
+ foo_rects( window, context, shared, rects );
+
+ for (i=0; i<8; i++)
+ window->foos[i]->bounds = DFB_REGION_INIT_FROM_RECTANGLE( &rects[i] );
+}
+
+static void
+update_flags( UniqueWindow *window )
+{
+ int i;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ if (! (window->options & DWOP_GHOST)) {
+ if (window->foos[0]) {
+ for (i=0; i<8; i++)
+ window->foos[i]->flags |= SRF_INPUT;
+ }
+
+ window->region->flags |= SRF_INPUT;
+ }
+ else {
+ if (window->foos[0]) {
+ for (i=0; i<8; i++)
+ window->foos[i]->flags &= ~SRF_INPUT;
+ }
+
+ window->region->flags &= ~SRF_INPUT;
+ }
+}
+
+static DFBResult
+create_foos( UniqueWindow *window,
+ UniqueContext *context,
+ WMShared *shared )
+{
+ int i;
+ DFBResult ret;
+ DFBRectangle rects[8];
+ StretRegionFlags flags = SRF_ACTIVE | SRF_OUTPUT;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+ D_MAGIC_ASSERT( context, UniqueContext );
+ D_MAGIC_ASSERT( shared, WMShared );
+
+
+ foo_rects( window, context, shared, rects );
+
+ if (! (window->options & DWOP_GHOST))
+ flags |= SRF_INPUT;
+
+ for (i=0; i<8; i++) {
+ ret = stret_region_create( shared->region_classes[URCI_FOO], window, i, flags, 1,
+ DFB_RECTANGLE_VALS( &rects[i] ),
+ window->frame, UNFL_FOREGROUND,
+ context->shmpool, &window->foos[i] );
+ if (ret)
+ goto error;
+ }
+
+ return DFB_OK;
+
+error:
+ for (--i; i>0; --i)
+ stret_region_destroy( window->foos[i] );
+
+ return ret;
+}
+
+static DFBResult
+create_regions( UniqueWindow *window )
+{
+ DFBResult ret;
+ UniqueContext *context;
+ WMShared *shared;
+ StretRegionFlags flags = SRF_ACTIVE;
+
+ D_MAGIC_ASSERT( window, UniqueWindow );
+
+ context = window->context;
+
+ D_MAGIC_ASSERT( context, UniqueContext );
+
+ shared = context->shared;
+
+ D_MAGIC_ASSERT( shared, WMShared );
+
+ if (! (window->options & DWOP_GHOST))
+ flags |= SRF_INPUT;
+
+ if (! (window->caps & DWCAPS_INPUTONLY))
+ flags |= SRF_OUTPUT;
+
+ if (window->options & DWOP_SHAPED)
+ flags |= SRF_SHAPED;
+
+ /* Frame */
+ ret = stret_region_create( shared->region_classes[URCI_FRAME], window, 0, SRF_NONE, _UNFL_NUM,
+ DFB_RECTANGLE_VALS( &window->full ),
+ context->root, UNRL_USER, context->shmpool, &window->frame );
+ if (ret)
+ return ret;
+
+ /* Content */
+ ret = stret_region_create( shared->region_classes[URCI_WINDOW], window, true, flags, 1,
+ window->insets.l, window->insets.t,
+ window->bounds.w, window->bounds.h,
+ window->frame, UNFL_CONTENT, context->shmpool, &window->region );
+ if (ret) {
+ stret_region_destroy( window->frame );
+ return ret;
+ }
+
+ /* Foos */
+ if (D_FLAGS_IS_SET( window->flags, UWF_DECORATED )) {
+ ret = create_foos( window, context, shared );
+ if (ret) {
+ stret_region_destroy( window->region );
+ stret_region_destroy( window->frame );
+ return ret;
+ }
+ }
+
+ return DFB_OK;
+}
+
diff --git a/Source/DirectFB/wm/unique/window.h b/Source/DirectFB/wm/unique/window.h
new file mode 100755
index 0000000..be75e96
--- /dev/null
+++ b/Source/DirectFB/wm/unique/window.h
@@ -0,0 +1,135 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __UNIQUE__WINDOW_H__
+#define __UNIQUE__WINDOW_H__
+
+#include <core/coretypes.h>
+#include <core/wm.h>
+
+#include <unique/types.h>
+
+
+typedef enum {
+ UWF_NONE = 0x00000000,
+
+ UWF_VISIBLE = 0x00000001,
+ UWF_DECORATED = 0x00000002,
+
+ UWF_DESTROYED = 0x00000010,
+
+ UWF_ALL = 0x00000013
+} UniqueWindowFlags;
+
+
+typedef enum {
+ UWNF_NONE = 0x00000000,
+
+ UWNF_DESTROYED = 0x00000001,
+
+ UWNF_UPDATE = 0x00000010,
+
+ UWNF_ALL = 0x00000011
+} UniqueWindowNotificationFlags;
+
+typedef struct {
+ UniqueWindowNotificationFlags flags;
+ UniqueWindow *window;
+
+ DFBRegion update;
+} UniqueWindowNotification;
+
+
+
+DFBResult unique_window_create ( CoreDFB *core,
+ CoreWindow *window,
+ UniqueContext *context,
+ DFBWindowCapabilities caps,
+ const CoreWindowConfig *config,
+ UniqueWindow **ret_window );
+
+DFBResult unique_window_close ( UniqueWindow *window );
+
+DFBResult unique_window_destroy ( UniqueWindow *window );
+
+
+DFBResult unique_window_notify ( UniqueWindow *window,
+ UniqueWindowNotificationFlags flags );
+
+
+DFBResult unique_window_update ( UniqueWindow *window,
+ const DFBRegion *region,
+ DFBSurfaceFlipFlags flags );
+
+DFBResult unique_window_post_event ( UniqueWindow *window,
+ DFBWindowEvent *event );
+
+DFBResult unique_window_set_config ( UniqueWindow *window,
+ const CoreWindowConfig *config,
+ CoreWindowConfigFlags flags );
+
+DFBResult unique_window_get_config ( UniqueWindow *window,
+ CoreWindowConfig *config );
+
+
+DFBResult unique_window_restack ( UniqueWindow *window,
+ UniqueWindow *relative,
+ int relation );
+
+
+DFBResult unique_window_grab ( UniqueWindow *window,
+ const CoreWMGrab *grab );
+
+DFBResult unique_window_ungrab ( UniqueWindow *window,
+ const CoreWMGrab *grab );
+
+DFBResult unique_window_request_focus( UniqueWindow *window );
+
+
+
+
+/*
+ * Creates a pool of window objects.
+ */
+FusionObjectPool *unique_window_pool_create( const FusionWorld *world );
+
+/*
+ * Generates unique_window_ref(), unique_window_attach() etc.
+ */
+FUSION_OBJECT_METHODS( UniqueWindow, unique_window )
+
+
+/* global reactions */
+
+typedef enum {
+ UNIQUE_WM_MODULE_WINDOW_LISTENER
+} UNIQUE_WINDOW_GLOBALS;
+
+
+#endif
+